Commit ea5b213a authored by Chris Wilson's avatar Chris Wilson Committed by Eric Anholt

drm/i915: Subclass intel_encoder.

Subclass intel_encoder to reduce the pointer dance through
intel_encoder->dev_priv.

10 files changed, 896 insertions(+), 997 deletions(-)
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: default avatarEric Anholt <eric@anholt.net>
parent 94113cec
......@@ -30,20 +30,17 @@
#include "intel_drv.h"
struct intel_dvo_device {
char *name;
const char *name;
int type;
/* DVOA/B/C output register */
u32 dvo_reg;
/* GPIO register used for i2c bus to control this device */
u32 gpio;
int slave_addr;
struct i2c_adapter *i2c_bus;
const struct intel_dvo_dev_ops *dev_ops;
void *dev_priv;
struct drm_display_mode *panel_fixed_mode;
bool panel_wants_dither;
struct i2c_adapter *i2c_bus;
};
struct intel_dvo_dev_ops {
......
......@@ -508,17 +508,8 @@ static const struct drm_connector_helper_funcs intel_crt_connector_helper_funcs
.best_encoder = intel_attached_encoder,
};
static void intel_crt_enc_destroy(struct drm_encoder *encoder)
{
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
intel_i2c_destroy(intel_encoder->ddc_bus);
drm_encoder_cleanup(encoder);
kfree(intel_encoder);
}
static const struct drm_encoder_funcs intel_crt_enc_funcs = {
.destroy = intel_crt_enc_destroy,
.destroy = intel_encoder_destroy,
};
void intel_crt_init(struct drm_device *dev)
......
......@@ -2537,6 +2537,20 @@ void intel_encoder_commit (struct drm_encoder *encoder)
encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON);
}
void intel_encoder_destroy(struct drm_encoder *encoder)
{
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
if (intel_encoder->ddc_bus)
intel_i2c_destroy(intel_encoder->ddc_bus);
if (intel_encoder->i2c_bus)
intel_i2c_destroy(intel_encoder->i2c_bus);
drm_encoder_cleanup(encoder);
kfree(intel_encoder);
}
static bool intel_crtc_mode_fixup(struct drm_crtc *crtc,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
......
......@@ -42,10 +42,11 @@
#define DP_LINK_CONFIGURATION_SIZE 9
#define IS_eDP(i) ((i)->type == INTEL_OUTPUT_EDP)
#define IS_PCH_eDP(dp_priv) ((dp_priv)->is_pch_edp)
#define IS_eDP(i) ((i)->base.type == INTEL_OUTPUT_EDP)
#define IS_PCH_eDP(i) ((i)->is_pch_edp)
struct intel_dp_priv {
struct intel_dp {
struct intel_encoder base;
uint32_t output_reg;
uint32_t DP;
uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE];
......@@ -54,40 +55,39 @@ struct intel_dp_priv {
uint8_t link_bw;
uint8_t lane_count;
uint8_t dpcd[4];
struct intel_encoder *intel_encoder;
struct i2c_adapter adapter;
struct i2c_algo_dp_aux_data algo;
bool is_pch_edp;
};
static void
intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP,
uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE]);
static struct intel_dp *enc_to_intel_dp(struct drm_encoder *encoder)
{
return container_of(enc_to_intel_encoder(encoder), struct intel_dp, base);
}
static void
intel_dp_link_down(struct intel_encoder *intel_encoder, uint32_t DP);
static void intel_dp_link_train(struct intel_dp *intel_dp);
static void intel_dp_link_down(struct intel_dp *intel_dp);
void
intel_edp_link_config (struct intel_encoder *intel_encoder,
int *lane_num, int *link_bw)
int *lane_num, int *link_bw)
{
struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
struct intel_dp *intel_dp = container_of(intel_encoder, struct intel_dp, base);
*lane_num = dp_priv->lane_count;
if (dp_priv->link_bw == DP_LINK_BW_1_62)
*lane_num = intel_dp->lane_count;
if (intel_dp->link_bw == DP_LINK_BW_1_62)
*link_bw = 162000;
else if (dp_priv->link_bw == DP_LINK_BW_2_7)
else if (intel_dp->link_bw == DP_LINK_BW_2_7)
*link_bw = 270000;
}
static int
intel_dp_max_lane_count(struct intel_encoder *intel_encoder)
intel_dp_max_lane_count(struct intel_dp *intel_dp)
{
struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
int max_lane_count = 4;
if (dp_priv->dpcd[0] >= 0x11) {
max_lane_count = dp_priv->dpcd[2] & 0x1f;
if (intel_dp->dpcd[0] >= 0x11) {
max_lane_count = intel_dp->dpcd[2] & 0x1f;
switch (max_lane_count) {
case 1: case 2: case 4:
break;
......@@ -99,10 +99,9 @@ intel_dp_max_lane_count(struct intel_encoder *intel_encoder)
}
static int
intel_dp_max_link_bw(struct intel_encoder *intel_encoder)
intel_dp_max_link_bw(struct intel_dp *intel_dp)
{
struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
int max_link_bw = dp_priv->dpcd[1];
int max_link_bw = intel_dp->dpcd[1];
switch (max_link_bw) {
case DP_LINK_BW_1_62:
......@@ -126,13 +125,11 @@ intel_dp_link_clock(uint8_t link_bw)
/* I think this is a fiction */
static int
intel_dp_link_required(struct drm_device *dev,
struct intel_encoder *intel_encoder, int pixel_clock)
intel_dp_link_required(struct drm_device *dev, struct intel_dp *intel_dp, int pixel_clock)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
if (IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv))
if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp))
return (pixel_clock * dev_priv->edp_bpp) / 8;
else
return pixel_clock * 3;
......@@ -149,14 +146,13 @@ intel_dp_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
struct drm_encoder *encoder = intel_attached_encoder(connector);
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
struct drm_device *dev = connector->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_encoder));
int max_lanes = intel_dp_max_lane_count(intel_encoder);
int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_dp));
int max_lanes = intel_dp_max_lane_count(intel_dp);
if ((IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) &&
if ((IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) &&
dev_priv->panel_fixed_mode) {
if (mode->hdisplay > dev_priv->panel_fixed_mode->hdisplay)
return MODE_PANEL;
......@@ -167,8 +163,8 @@ intel_dp_mode_valid(struct drm_connector *connector,
/* only refuse the mode on non eDP since we have seen some wierd eDP panels
which are outside spec tolerances but somehow work by magic */
if (!IS_eDP(intel_encoder) &&
(intel_dp_link_required(connector->dev, intel_encoder, mode->clock)
if (!IS_eDP(intel_dp) &&
(intel_dp_link_required(connector->dev, intel_dp, mode->clock)
> intel_dp_max_data_rate(max_link_clock, max_lanes)))
return MODE_CLOCK_HIGH;
......@@ -232,13 +228,12 @@ intel_hrawclk(struct drm_device *dev)
}
static int
intel_dp_aux_ch(struct intel_encoder *intel_encoder,
intel_dp_aux_ch(struct intel_dp *intel_dp,
uint8_t *send, int send_bytes,
uint8_t *recv, int recv_size)
{
struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
uint32_t output_reg = dp_priv->output_reg;
struct drm_device *dev = intel_encoder->enc.dev;
uint32_t output_reg = intel_dp->output_reg;
struct drm_device *dev = intel_dp->base.enc.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
uint32_t ch_ctl = output_reg + 0x10;
uint32_t ch_data = ch_ctl + 4;
......@@ -253,7 +248,7 @@ intel_dp_aux_ch(struct intel_encoder *intel_encoder,
* and would like to run at 2MHz. So, take the
* hrawclk value and divide by 2 and use that
*/
if (IS_eDP(intel_encoder)) {
if (IS_eDP(intel_dp)) {
if (IS_GEN6(dev))
aux_clock_divider = 200; /* SNB eDP input clock at 400Mhz */
else
......@@ -344,7 +339,7 @@ intel_dp_aux_ch(struct intel_encoder *intel_encoder,
/* Write data to the aux channel in native mode */
static int
intel_dp_aux_native_write(struct intel_encoder *intel_encoder,
intel_dp_aux_native_write(struct intel_dp *intel_dp,
uint16_t address, uint8_t *send, int send_bytes)
{
int ret;
......@@ -361,7 +356,7 @@ intel_dp_aux_native_write(struct intel_encoder *intel_encoder,
memcpy(&msg[4], send, send_bytes);
msg_bytes = send_bytes + 4;
for (;;) {
ret = intel_dp_aux_ch(intel_encoder, msg, msg_bytes, &ack, 1);
ret = intel_dp_aux_ch(intel_dp, msg, msg_bytes, &ack, 1);
if (ret < 0)
return ret;
if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK)
......@@ -376,15 +371,15 @@ intel_dp_aux_native_write(struct intel_encoder *intel_encoder,
/* Write a single byte to the aux channel in native mode */
static int
intel_dp_aux_native_write_1(struct intel_encoder *intel_encoder,
intel_dp_aux_native_write_1(struct intel_dp *intel_dp,
uint16_t address, uint8_t byte)
{
return intel_dp_aux_native_write(intel_encoder, address, &byte, 1);
return intel_dp_aux_native_write(intel_dp, address, &byte, 1);
}
/* read bytes from a native aux channel */
static int
intel_dp_aux_native_read(struct intel_encoder *intel_encoder,
intel_dp_aux_native_read(struct intel_dp *intel_dp,
uint16_t address, uint8_t *recv, int recv_bytes)
{
uint8_t msg[4];
......@@ -403,7 +398,7 @@ intel_dp_aux_native_read(struct intel_encoder *intel_encoder,
reply_bytes = recv_bytes + 1;
for (;;) {
ret = intel_dp_aux_ch(intel_encoder, msg, msg_bytes,
ret = intel_dp_aux_ch(intel_dp, msg, msg_bytes,
reply, reply_bytes);
if (ret == 0)
return -EPROTO;
......@@ -426,10 +421,9 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
uint8_t write_byte, uint8_t *read_byte)
{
struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
struct intel_dp_priv *dp_priv = container_of(adapter,
struct intel_dp_priv,
adapter);
struct intel_encoder *intel_encoder = dp_priv->intel_encoder;
struct intel_dp *intel_dp = container_of(adapter,
struct intel_dp,
adapter);
uint16_t address = algo_data->address;
uint8_t msg[5];
uint8_t reply[2];
......@@ -468,7 +462,7 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
}
for (;;) {
ret = intel_dp_aux_ch(intel_encoder,
ret = intel_dp_aux_ch(intel_dp,
msg, msg_bytes,
reply, reply_bytes);
if (ret < 0) {
......@@ -496,41 +490,38 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
}
static int
intel_dp_i2c_init(struct intel_encoder *intel_encoder,
intel_dp_i2c_init(struct intel_dp *intel_dp,
struct intel_connector *intel_connector, const char *name)
{
struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
DRM_DEBUG_KMS("i2c_init %s\n", name);
dp_priv->algo.running = false;
dp_priv->algo.address = 0;
dp_priv->algo.aux_ch = intel_dp_i2c_aux_ch;
memset(&dp_priv->adapter, '\0', sizeof (dp_priv->adapter));
dp_priv->adapter.owner = THIS_MODULE;
dp_priv->adapter.class = I2C_CLASS_DDC;
strncpy (dp_priv->adapter.name, name, sizeof(dp_priv->adapter.name) - 1);
dp_priv->adapter.name[sizeof(dp_priv->adapter.name) - 1] = '\0';
dp_priv->adapter.algo_data = &dp_priv->algo;
dp_priv->adapter.dev.parent = &intel_connector->base.kdev;
return i2c_dp_aux_add_bus(&dp_priv->adapter);
intel_dp->algo.running = false;
intel_dp->algo.address = 0;
intel_dp->algo.aux_ch = intel_dp_i2c_aux_ch;
memset(&intel_dp->adapter, '\0', sizeof (intel_dp->adapter));
intel_dp->adapter.owner = THIS_MODULE;
intel_dp->adapter.class = I2C_CLASS_DDC;
strncpy (intel_dp->adapter.name, name, sizeof(intel_dp->adapter.name) - 1);
intel_dp->adapter.name[sizeof(intel_dp->adapter.name) - 1] = '\0';
intel_dp->adapter.algo_data = &intel_dp->algo;
intel_dp->adapter.dev.parent = &intel_connector->base.kdev;
return i2c_dp_aux_add_bus(&intel_dp->adapter);
}
static bool
intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
int lane_count, clock;
int max_lane_count = intel_dp_max_lane_count(intel_encoder);
int max_clock = intel_dp_max_link_bw(intel_encoder) == DP_LINK_BW_2_7 ? 1 : 0;
int max_lane_count = intel_dp_max_lane_count(intel_dp);
int max_clock = intel_dp_max_link_bw(intel_dp) == DP_LINK_BW_2_7 ? 1 : 0;
static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 };
if ((IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) &&
if ((IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) &&
dev_priv->panel_fixed_mode) {
struct drm_display_mode *fixed_mode = dev_priv->panel_fixed_mode;
......@@ -558,28 +549,28 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
for (clock = 0; clock <= max_clock; clock++) {
int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count);
if (intel_dp_link_required(encoder->dev, intel_encoder, mode->clock)
if (intel_dp_link_required(encoder->dev, intel_dp, mode->clock)
<= link_avail) {
dp_priv->link_bw = bws[clock];
dp_priv->lane_count = lane_count;
adjusted_mode->clock = intel_dp_link_clock(dp_priv->link_bw);
intel_dp->link_bw = bws[clock];
intel_dp->lane_count = lane_count;
adjusted_mode->clock = intel_dp_link_clock(intel_dp->link_bw);
DRM_DEBUG_KMS("Display port link bw %02x lane "
"count %d clock %d\n",
dp_priv->link_bw, dp_priv->lane_count,
intel_dp->link_bw, intel_dp->lane_count,
adjusted_mode->clock);
return true;
}
}
}
if (IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) {
if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) {
/* okay we failed just pick the highest */
dp_priv->lane_count = max_lane_count;
dp_priv->link_bw = bws[max_clock];
adjusted_mode->clock = intel_dp_link_clock(dp_priv->link_bw);
intel_dp->lane_count = max_lane_count;
intel_dp->link_bw = bws[max_clock];
adjusted_mode->clock = intel_dp_link_clock(intel_dp->link_bw);
DRM_DEBUG_KMS("Force picking display port link bw %02x lane "
"count %d clock %d\n",
dp_priv->link_bw, dp_priv->lane_count,
intel_dp->link_bw, intel_dp->lane_count,
adjusted_mode->clock);
return true;
}
......@@ -626,17 +617,14 @@ bool intel_pch_has_edp(struct drm_crtc *crtc)
struct drm_encoder *encoder;
list_for_each_entry(encoder, &mode_config->encoder_list, head) {
struct intel_encoder *intel_encoder;
struct intel_dp_priv *dp_priv;
struct intel_dp *intel_dp;
if (!encoder || encoder->crtc != crtc)
if (encoder->crtc != crtc)
continue;
intel_encoder = enc_to_intel_encoder(encoder);
dp_priv = intel_encoder->dev_priv;
if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT)
return dp_priv->is_pch_edp;
intel_dp = enc_to_intel_dp(encoder);
if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT)
return intel_dp->is_pch_edp;
}
return false;
}
......@@ -657,18 +645,15 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
* Find the lane count in the intel_encoder private
*/
list_for_each_entry(encoder, &mode_config->encoder_list, head) {
struct intel_encoder *intel_encoder;
struct intel_dp_priv *dp_priv;
struct intel_dp *intel_dp;
if (encoder->crtc != crtc)
continue;
intel_encoder = enc_to_intel_encoder(encoder);
dp_priv = intel_encoder->dev_priv;
if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) {
lane_count = dp_priv->lane_count;
if (IS_PCH_eDP(dp_priv))
intel_dp = enc_to_intel_dp(encoder);
if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT) {
lane_count = intel_dp->lane_count;
if (IS_PCH_eDP(intel_dp))
bpp = dev_priv->edp_bpp;
break;
}
......@@ -724,61 +709,60 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
struct drm_device *dev = encoder->dev;
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
struct drm_crtc *crtc = intel_encoder->enc.crtc;
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
struct drm_crtc *crtc = intel_dp->base.enc.crtc;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
dp_priv->DP = (DP_VOLTAGE_0_4 |
intel_dp->DP = (DP_VOLTAGE_0_4 |
DP_PRE_EMPHASIS_0);
if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
dp_priv->DP |= DP_SYNC_HS_HIGH;
intel_dp->DP |= DP_SYNC_HS_HIGH;
if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
dp_priv->DP |= DP_SYNC_VS_HIGH;
intel_dp->DP |= DP_SYNC_VS_HIGH;
if (HAS_PCH_CPT(dev) && !IS_eDP(intel_encoder))
dp_priv->DP |= DP_LINK_TRAIN_OFF_CPT;
if (HAS_PCH_CPT(dev) && !IS_eDP(intel_dp))
intel_dp->DP |= DP_LINK_TRAIN_OFF_CPT;
else
dp_priv->DP |= DP_LINK_TRAIN_OFF;
intel_dp->DP |= DP_LINK_TRAIN_OFF;
switch (dp_priv->lane_count) {
switch (intel_dp->lane_count) {
case 1:
dp_priv->DP |= DP_PORT_WIDTH_1;
intel_dp->DP |= DP_PORT_WIDTH_1;
break;
case 2:
dp_priv->DP |= DP_PORT_WIDTH_2;
intel_dp->DP |= DP_PORT_WIDTH_2;
break;
case 4:
dp_priv->DP |= DP_PORT_WIDTH_4;
intel_dp->DP |= DP_PORT_WIDTH_4;
break;
}
if (dp_priv->has_audio)
dp_priv->DP |= DP_AUDIO_OUTPUT_ENABLE;
if (intel_dp->has_audio)
intel_dp->DP |= DP_AUDIO_OUTPUT_ENABLE;
memset(dp_priv->link_configuration, 0, DP_LINK_CONFIGURATION_SIZE);
dp_priv->link_configuration[0] = dp_priv->link_bw;
dp_priv->link_configuration[1] = dp_priv->lane_count;
memset(intel_dp->link_configuration, 0, DP_LINK_CONFIGURATION_SIZE);
intel_dp->link_configuration[0] = intel_dp->link_bw;
intel_dp->link_configuration[1] = intel_dp->lane_count;
/*
* Check for DPCD version > 1.1 and enhanced framing support
*/
if (dp_priv->dpcd[0] >= 0x11 && (dp_priv->dpcd[2] & DP_ENHANCED_FRAME_CAP)) {
dp_priv->link_configuration[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
dp_priv->DP |= DP_ENHANCED_FRAMING;
if (intel_dp->dpcd[0] >= 0x11 && (intel_dp->dpcd[2] & DP_ENHANCED_FRAME_CAP)) {
intel_dp->link_configuration[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
intel_dp->DP |= DP_ENHANCED_FRAMING;
}
/* CPT DP's pipe select is decided in TRANS_DP_CTL */
if (intel_crtc->pipe == 1 && !HAS_PCH_CPT(dev))
dp_priv->DP |= DP_PIPEB_SELECT;
intel_dp->DP |= DP_PIPEB_SELECT;
if (IS_eDP(intel_encoder)) {
if (IS_eDP(intel_dp)) {
/* don't miss out required setting for eDP */
dp_priv->DP |= DP_PLL_ENABLE;
intel_dp->DP |= DP_PLL_ENABLE;
if (adjusted_mode->clock < 200000)
dp_priv->DP |= DP_PLL_FREQ_160MHZ;
intel_dp->DP |= DP_PLL_FREQ_160MHZ;
else
dp_priv->DP |= DP_PLL_FREQ_270MHZ;
intel_dp->DP |= DP_PLL_FREQ_270MHZ;
}
}
......@@ -852,30 +836,29 @@ static void ironlake_edp_backlight_off (struct drm_device *dev)
static void
intel_dp_dpms(struct drm_encoder *encoder, int mode)
{
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
uint32_t dp_reg = I915_READ(dp_priv->output_reg);
uint32_t dp_reg = I915_READ(intel_dp->output_reg);
if (mode != DRM_MODE_DPMS_ON) {
if (dp_reg & DP_PORT_EN) {
intel_dp_link_down(intel_encoder, dp_priv->DP);
if (IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) {
intel_dp_link_down(intel_dp);
if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) {
ironlake_edp_backlight_off(dev);
ironlake_edp_panel_off(dev);
}
}
} else {
if (!(dp_reg & DP_PORT_EN)) {
intel_dp_link_train(intel_encoder, dp_priv->DP, dp_priv->link_configuration);
if (IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) {
intel_dp_link_train(intel_dp);
if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) {
ironlake_edp_panel_on(dev);
ironlake_edp_backlight_on(dev);
}
}
}
dp_priv->dpms_mode = mode;
intel_dp->dpms_mode = mode;
}
/*
......@@ -883,12 +866,12 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode)
* link status information
*/
static bool
intel_dp_get_link_status(struct intel_encoder *intel_encoder,
intel_dp_get_link_status(struct intel_dp *intel_dp,
uint8_t link_status[DP_LINK_STATUS_SIZE])
{
int ret;
ret = intel_dp_aux_native_read(intel_encoder,
ret = intel_dp_aux_native_read(intel_dp,
DP_LANE0_1_STATUS,
link_status, DP_LINK_STATUS_SIZE);
if (ret != DP_LINK_STATUS_SIZE)
......@@ -965,7 +948,7 @@ intel_dp_pre_emphasis_max(uint8_t voltage_swing)
}
static void
intel_get_adjust_train(struct intel_encoder *intel_encoder,
intel_get_adjust_train(struct intel_dp *intel_dp,
uint8_t link_status[DP_LINK_STATUS_SIZE],
int lane_count,
uint8_t train_set[4])
......@@ -1101,27 +1084,26 @@ intel_channel_eq_ok(uint8_t link_status[DP_LINK_STATUS_SIZE], int lane_count)
}
static bool
intel_dp_set_link_train(struct intel_encoder *intel_encoder,
intel_dp_set_link_train(struct intel_dp *intel_dp,
uint32_t dp_reg_value,
uint8_t dp_train_pat,
uint8_t train_set[4],
bool first)
{
struct drm_device *dev = intel_encoder->enc.dev;
struct drm_device *dev = intel_dp->base.enc.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
int ret;
I915_WRITE(dp_priv->output_reg, dp_reg_value);
POSTING_READ(dp_priv->output_reg);
I915_WRITE(intel_dp->output_reg, dp_reg_value);
POSTING_READ(intel_dp->output_reg);
if (first)
intel_wait_for_vblank(dev);
intel_dp_aux_native_write_1(intel_encoder,
intel_dp_aux_native_write_1(intel_dp,
DP_TRAINING_PATTERN_SET,
dp_train_pat);
ret = intel_dp_aux_native_write(intel_encoder,
ret = intel_dp_aux_native_write(intel_dp,
DP_TRAINING_LANE0_SET, train_set, 4);
if (ret != 4)
return false;
......@@ -1130,12 +1112,10 @@ intel_dp_set_link_train(struct intel_encoder *intel_encoder,
}
static void
intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP,
uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE])
intel_dp_link_train(struct intel_dp *intel_dp)
{
struct drm_device *dev = intel_encoder->enc.dev;
struct drm_device *dev = intel_dp->base.enc.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
uint8_t train_set[4];
uint8_t link_status[DP_LINK_STATUS_SIZE];
int i;
......@@ -1145,13 +1125,15 @@ intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP,
bool first = true;
int tries;
u32 reg;
uint32_t DP = intel_dp->DP;
/* Write the link configuration data */
intel_dp_aux_native_write(intel_encoder, DP_LINK_BW_SET,
link_configuration, DP_LINK_CONFIGURATION_SIZE);
intel_dp_aux_native_write(intel_dp, DP_LINK_BW_SET,
intel_dp->link_configuration,
DP_LINK_CONFIGURATION_SIZE);
DP |= DP_PORT_EN;
if (HAS_PCH_CPT(dev) && !IS_eDP(intel_encoder))
if (HAS_PCH_CPT(dev) && !IS_eDP(intel_dp))
DP &= ~DP_LINK_TRAIN_MASK_CPT;
else
DP &= ~DP_LINK_TRAIN_MASK;
......@@ -1162,39 +1144,39 @@ intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP,
for (;;) {
/* Use train_set[0] to set the voltage and pre emphasis values */
uint32_t signal_levels;
if (IS_GEN6(dev) && IS_eDP(intel_encoder)) {
if (IS_GEN6(dev) && IS_eDP(intel_dp)) {
signal_levels = intel_gen6_edp_signal_levels(train_set[0]);
DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels;
} else {
signal_levels = intel_dp_signal_levels(train_set[0], dp_priv->lane_count);
signal_levels = intel_dp_signal_levels(train_set[0], intel_dp->lane_count);
DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels;
}
if (HAS_PCH_CPT(dev) && !IS_eDP(intel_encoder))
if (HAS_PCH_CPT(dev) && !IS_eDP(intel_dp))
reg = DP | DP_LINK_TRAIN_PAT_1_CPT;
else
reg = DP | DP_LINK_TRAIN_PAT_1;
if (!intel_dp_set_link_train(intel_encoder, reg,
if (!intel_dp_set_link_train(intel_dp, reg,
DP_TRAINING_PATTERN_1, train_set, first))
break;
first = false;
/* Set training pattern 1 */
udelay(100);
if (!intel_dp_get_link_status(intel_encoder, link_status))
if (!intel_dp_get_link_status(intel_dp, link_status))
break;
if (intel_clock_recovery_ok(link_status, dp_priv->lane_count)) {
if (intel_clock_recovery_ok(link_status, intel_dp->lane_count)) {
clock_recovery = true;
break;
}
/* Check to see if we've tried the max voltage */
for (i = 0; i < dp_priv->lane_count; i++)
for (i = 0; i < intel_dp->lane_count; i++)
if ((train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0)
break;
if (i == dp_priv->lane_count)
if (i == intel_dp->lane_count)
break;
/* Check to see if we've tried the same voltage 5 times */
......@@ -1207,7 +1189,7 @@ intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP,
voltage = train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
/* Compute new train_set as requested by target */
intel_get_adjust_train(intel_encoder, link_status, dp_priv->lane_count, train_set);
intel_get_adjust_train(intel_dp, link_status, intel_dp->lane_count, train_set);
}
/* channel equalization */
......@@ -1217,30 +1199,30 @@ intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP,
/* Use train_set[0] to set the voltage and pre emphasis values */
uint32_t signal_levels;
if (IS_GEN6(dev) && IS_eDP(intel_encoder)) {
if (IS_GEN6(dev) && IS_eDP(intel_dp)) {
signal_levels = intel_gen6_edp_signal_levels(train_set[0]);
DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels;
} else {
signal_levels = intel_dp_signal_levels(train_set[0], dp_priv->lane_count);
signal_levels = intel_dp_signal_levels(train_set[0], intel_dp->lane_count);
DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels;
}
if (HAS_PCH_CPT(dev) && !IS_eDP(intel_encoder))
if (HAS_PCH_CPT(dev) && !IS_eDP(intel_dp))
reg = DP | DP_LINK_TRAIN_PAT_2_CPT;
else
reg = DP | DP_LINK_TRAIN_PAT_2;
/* channel eq pattern */
if (!intel_dp_set_link_train(intel_encoder, reg,
if (!intel_dp_set_link_train(intel_dp, reg,
DP_TRAINING_PATTERN_2, train_set,
false))
break;
udelay(400);
if (!intel_dp_get_link_status(intel_encoder, link_status))
if (!intel_dp_get_link_status(intel_dp, link_status))
break;
if (intel_channel_eq_ok(link_status, dp_priv->lane_count)) {
if (intel_channel_eq_ok(link_status, intel_dp->lane_count)) {
channel_eq = true;
break;
}
......@@ -1250,53 +1232,53 @@ intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP,
break;
/* Compute new train_set as requested by target */
intel_get_adjust_train(intel_encoder, link_status, dp_priv->lane_count, train_set);
intel_get_adjust_train(intel_dp, link_status, intel_dp->lane_count, train_set);
++tries;
}
if (HAS_PCH_CPT(dev) && !IS_eDP(intel_encoder))
if (HAS_PCH_CPT(dev) && !IS_eDP(intel_dp))
reg = DP | DP_LINK_TRAIN_OFF_CPT;
else
reg = DP | DP_LINK_TRAIN_OFF;
I915_WRITE(dp_priv->output_reg, reg);
POSTING_READ(dp_priv->output_reg);
intel_dp_aux_native_write_1(intel_encoder,
I915_WRITE(intel_dp->output_reg, reg);
POSTING_READ(intel_dp->output_reg);
intel_dp_aux_native_write_1(intel_dp,
DP_TRAINING_PATTERN_SET, DP_TRAINING_PATTERN_DISABLE);
}
static void
intel_dp_link_down(struct intel_encoder *intel_encoder, uint32_t DP)
intel_dp_link_down(struct intel_dp *intel_dp)
{
struct drm_device *dev = intel_encoder->enc.dev;
struct drm_device *dev = intel_dp->base.enc.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
uint32_t DP = intel_dp->DP;
DRM_DEBUG_KMS("\n");
if (IS_eDP(intel_encoder)) {
if (IS_eDP(intel_dp)) {
DP &= ~DP_PLL_ENABLE;
I915_WRITE(dp_priv->output_reg, DP);
POSTING_READ(dp_priv->output_reg);
I915_WRITE(intel_dp->output_reg, DP);
POSTING_READ(intel_dp->output_reg);
udelay(100);
}
if (HAS_PCH_CPT(dev) && !IS_eDP(intel_encoder)) {
if (HAS_PCH_CPT(dev) && !IS_eDP(intel_dp)) {
DP &= ~DP_LINK_TRAIN_MASK_CPT;
I915_WRITE(dp_priv->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE_CPT);
POSTING_READ(dp_priv->output_reg);
I915_WRITE(intel_dp->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE_CPT);
POSTING_READ(intel_dp->output_reg);
} else {
DP &= ~DP_LINK_TRAIN_MASK;
I915_WRITE(dp_priv->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE);
POSTING_READ(dp_priv->output_reg);
I915_WRITE(intel_dp->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE);
POSTING_READ(intel_dp->output_reg);
}
udelay(17000);
if (IS_eDP(intel_encoder))
if (IS_eDP(intel_dp))
DP |= DP_LINK_TRAIN_OFF;
I915_WRITE(dp_priv->output_reg, DP & ~DP_PORT_EN);
POSTING_READ(dp_priv->output_reg);
I915_WRITE(intel_dp->output_reg, DP & ~DP_PORT_EN);
POSTING_READ(intel_dp->output_reg);
}
/*
......@@ -1309,41 +1291,39 @@ intel_dp_link_down(struct intel_encoder *intel_encoder, uint32_t DP)
*/
static void
intel_dp_check_link_status(struct intel_encoder *intel_encoder)
intel_dp_check_link_status(struct intel_dp *intel_dp)
{
struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
uint8_t link_status[DP_LINK_STATUS_SIZE];
if (!intel_encoder->enc.crtc)
if (!intel_dp->base.enc.crtc)
return;
if (!intel_dp_get_link_status(intel_encoder, link_status)) {
intel_dp_link_down(intel_encoder, dp_priv->DP);
if (!intel_dp_get_link_status(intel_dp, link_status)) {
intel_dp_link_down(intel_dp);
return;
}
if (!intel_channel_eq_ok(link_status, dp_priv->lane_count))
intel_dp_link_train(intel_encoder, dp_priv->DP, dp_priv->link_configuration);
if (!intel_channel_eq_ok(link_status, intel_dp->lane_count))
intel_dp_link_train(intel_dp);
}
static enum drm_connector_status
ironlake_dp_detect(struct drm_connector *connector)
{
struct drm_encoder *encoder = intel_attached_encoder(connector);
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
enum drm_connector_status status;
status = connector_status_disconnected;
if (intel_dp_aux_native_read(intel_encoder,
0x000, dp_priv->dpcd,
sizeof (dp_priv->dpcd)) == sizeof (dp_priv->dpcd))
if (intel_dp_aux_native_read(intel_dp,
0x000, intel_dp->dpcd,
sizeof (intel_dp->dpcd)) == sizeof (intel_dp->dpcd))
{
if (dp_priv->dpcd[0] != 0)
if (intel_dp->dpcd[0] != 0)
status = connector_status_connected;
}
DRM_DEBUG_KMS("DPCD: %hx%hx%hx%hx\n", dp_priv->dpcd[0],
dp_priv->dpcd[1], dp_priv->dpcd[2], dp_priv->dpcd[3]);
DRM_DEBUG_KMS("DPCD: %hx%hx%hx%hx\n", intel_dp->dpcd[0],
intel_dp->dpcd[1], intel_dp->dpcd[2], intel_dp->dpcd[3]);
return status;
}
......@@ -1357,19 +1337,18 @@ static enum drm_connector_status
intel_dp_detect(struct drm_connector *connector)
{
struct drm_encoder *encoder = intel_attached_encoder(connector);
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
struct drm_device *dev = intel_encoder->enc.dev;
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
struct drm_device *dev = intel_dp->base.enc.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
uint32_t temp, bit;
enum drm_connector_status status;
dp_priv->has_audio = false;
intel_dp->has_audio = false;
if (HAS_PCH_SPLIT(dev))
return ironlake_dp_detect(connector);
switch (dp_priv->output_reg) {
switch (intel_dp->output_reg) {
case DP_B:
bit = DPB_HOTPLUG_INT_STATUS;
break;
......@@ -1389,11 +1368,11 @@ intel_dp_detect(struct drm_connector *connector)
return connector_status_disconnected;
status = connector_status_disconnected;
if (intel_dp_aux_native_read(intel_encoder,
0x000, dp_priv->dpcd,
sizeof (dp_priv->dpcd)) == sizeof (dp_priv->dpcd))
if (intel_dp_aux_native_read(intel_dp,
0x000, intel_dp->dpcd,
sizeof (intel_dp->dpcd)) == sizeof (intel_dp->dpcd))
{
if (dp_priv->dpcd[0] != 0)
if (intel_dp->dpcd[0] != 0)
status = connector_status_connected;
}
return status;
......@@ -1402,18 +1381,17 @@ intel_dp_detect(struct drm_connector *connector)
static int intel_dp_get_modes(struct drm_connector *connector)
{
struct drm_encoder *encoder = intel_attached_encoder(connector);
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
struct drm_device *dev = intel_encoder->enc.dev;
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
struct drm_device *dev = intel_dp->base.enc.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
int ret;
/* We should parse the EDID data and find out if it has an audio sink
*/
ret = intel_ddc_get_modes(connector, intel_encoder->ddc_bus);
ret = intel_ddc_get_modes(connector, intel_dp->base.ddc_bus);
if (ret) {
if ((IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) &&
if ((IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) &&
!dev_priv->panel_fixed_mode) {
struct drm_display_mode *newmode;
list_for_each_entry(newmode, &connector->probed_modes,
......@@ -1430,7 +1408,7 @@ static int intel_dp_get_modes(struct drm_connector *connector)
}
/* if eDP has no EDID, try to use fixed panel mode from VBT */
if (IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) {
if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) {
if (dev_priv->panel_fixed_mode != NULL) {
struct drm_display_mode *mode;
mode = drm_mode_duplicate(dev, dev_priv->panel_fixed_mode);
......@@ -1470,27 +1448,17 @@ static const struct drm_connector_helper_funcs intel_dp_connector_helper_funcs =
.best_encoder = intel_attached_encoder,
};
static void intel_dp_enc_destroy(struct drm_encoder *encoder)
{
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
if (intel_encoder->i2c_bus)
intel_i2c_destroy(intel_encoder->i2c_bus);
drm_encoder_cleanup(encoder);
kfree(intel_encoder);
}
static const struct drm_encoder_funcs intel_dp_enc_funcs = {
.destroy = intel_dp_enc_destroy,
.destroy = intel_encoder_destroy,
};
void
intel_dp_hot_plug(struct intel_encoder *intel_encoder)
{
struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
struct intel_dp *intel_dp = container_of(intel_encoder, struct intel_dp, base);
if (dp_priv->dpms_mode == DRM_MODE_DPMS_ON)
intel_dp_check_link_status(intel_encoder);
if (intel_dp->dpms_mode == DRM_MODE_DPMS_ON)
intel_dp_check_link_status(intel_dp);
}
/* Return which DP Port should be selected for Transcoder DP control */
......@@ -1500,18 +1468,18 @@ intel_trans_dp_port_sel (struct drm_crtc *crtc)
struct drm_device *dev = crtc->dev;
struct drm_mode_config *mode_config = &dev->mode_config;
struct drm_encoder *encoder;
struct intel_encoder *intel_encoder = NULL;
list_for_each_entry(encoder, &mode_config->encoder_list, head) {
struct intel_dp *intel_dp;
if (encoder->crtc != crtc)
continue;
intel_encoder = enc_to_intel_encoder(encoder);
if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) {
struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
return dp_priv->output_reg;
}
intel_dp = enc_to_intel_dp(encoder);
if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT)
return intel_dp->output_reg;
}
return -1;
}
......@@ -1540,30 +1508,28 @@ intel_dp_init(struct drm_device *dev, int output_reg)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_connector *connector;
struct intel_dp *intel_dp;
struct intel_encoder *intel_encoder;
struct intel_connector *intel_connector;
struct intel_dp_priv *dp_priv;
const char *name = NULL;
int type;
intel_encoder = kcalloc(sizeof(struct intel_encoder) +
sizeof(struct intel_dp_priv), 1, GFP_KERNEL);
if (!intel_encoder)
intel_dp = kzalloc(sizeof(struct intel_dp), GFP_KERNEL);
if (!intel_dp)
return;
intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL);
if (!intel_connector) {
kfree(intel_encoder);
kfree(intel_dp);
return;
}
intel_encoder = &intel_dp->base;
dp_priv = (struct intel_dp_priv *)(intel_encoder + 1);
if (HAS_PCH_SPLIT(dev) && (output_reg == PCH_DP_D))
if (HAS_PCH_SPLIT(dev) && output_reg == PCH_DP_D)
if (intel_dpd_is_edp(dev))
dp_priv->is_pch_edp = true;
intel_dp->is_pch_edp = true;
if (output_reg == DP_A || IS_PCH_eDP(dp_priv)) {
if (output_reg == DP_A || IS_PCH_eDP(intel_dp)) {
type = DRM_MODE_CONNECTOR_eDP;
intel_encoder->type = INTEL_OUTPUT_EDP;
} else {
......@@ -1584,18 +1550,16 @@ intel_dp_init(struct drm_device *dev, int output_reg)
else if (output_reg == DP_D || output_reg == PCH_DP_D)
intel_encoder->clone_mask = (1 << INTEL_DP_D_CLONE_BIT);
if (IS_eDP(intel_encoder))
if (IS_eDP(intel_dp))
intel_encoder->clone_mask = (1 << INTEL_EDP_CLONE_BIT);
intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
connector->interlace_allowed = true;
connector->doublescan_allowed = 0;
dp_priv->intel_encoder = intel_encoder;
dp_priv->output_reg = output_reg;
dp_priv->has_audio = false;
dp_priv->dpms_mode = DRM_MODE_DPMS_ON;
intel_encoder->dev_priv = dp_priv;
intel_dp->output_reg = output_reg;
intel_dp->has_audio = false;
intel_dp->dpms_mode = DRM_MODE_DPMS_ON;
drm_encoder_init(dev, &intel_encoder->enc, &intel_dp_enc_funcs,
DRM_MODE_ENCODER_TMDS);
......@@ -1630,12 +1594,12 @@ intel_dp_init(struct drm_device *dev, int output_reg)
break;
}
intel_dp_i2c_init(intel_encoder, intel_connector, name);
intel_dp_i2c_init(intel_dp, intel_connector, name);
intel_encoder->ddc_bus = &dp_priv->adapter;
intel_encoder->ddc_bus = &intel_dp->adapter;
intel_encoder->hot_plug = intel_dp_hot_plug;
if (output_reg == DP_A || IS_PCH_eDP(dp_priv)) {
if (output_reg == DP_A || IS_PCH_eDP(intel_dp)) {
/* initialize panel mode from VBT if available for eDP */
if (dev_priv->lfp_lvds_vbt_mode) {
dev_priv->panel_fixed_mode =
......
......@@ -102,7 +102,6 @@ struct intel_encoder {
struct i2c_adapter *ddc_bus;
bool load_detect_temp;
bool needs_tv_clock;
void *dev_priv;
void (*hot_plug)(struct intel_encoder *);
int crtc_mask;
int clone_mask;
......@@ -192,6 +191,7 @@ extern int intel_panel_fitter_pipe (struct drm_device *dev);
extern void intel_crtc_load_lut(struct drm_crtc *crtc);
extern void intel_encoder_prepare (struct drm_encoder *encoder);
extern void intel_encoder_commit (struct drm_encoder *encoder);
extern void intel_encoder_destroy(struct drm_encoder *encoder);
extern struct drm_encoder *intel_attached_encoder(struct drm_connector *connector);
......
......@@ -38,7 +38,7 @@
#define CH7xxx_ADDR 0x76
#define TFP410_ADDR 0x38
static struct intel_dvo_device intel_dvo_devices[] = {
static const struct intel_dvo_device intel_dvo_devices[] = {
{
.type = INTEL_DVO_CHIP_TMDS,
.name = "sil164",
......@@ -77,20 +77,33 @@ static struct intel_dvo_device intel_dvo_devices[] = {
}
};
struct intel_dvo {
struct intel_encoder base;
struct intel_dvo_device dev;
struct drm_display_mode *panel_fixed_mode;
bool panel_wants_dither;
};
static struct intel_dvo *enc_to_intel_dvo(struct drm_encoder *encoder)
{
return container_of(enc_to_intel_encoder(encoder), struct intel_dvo, base);
}
static void intel_dvo_dpms(struct drm_encoder *encoder, int mode)
{
struct drm_i915_private *dev_priv = encoder->dev->dev_private;
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
struct intel_dvo_device *dvo = intel_encoder->dev_priv;
u32 dvo_reg = dvo->dvo_reg;
struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder);
u32 dvo_reg = intel_dvo->dev.dvo_reg;
u32 temp = I915_READ(dvo_reg);
if (mode == DRM_MODE_DPMS_ON) {
I915_WRITE(dvo_reg, temp | DVO_ENABLE);
I915_READ(dvo_reg);
dvo->dev_ops->dpms(dvo, mode);
intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, mode);
} else {
dvo->dev_ops->dpms(dvo, mode);
intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, mode);
I915_WRITE(dvo_reg, temp & ~DVO_ENABLE);
I915_READ(dvo_reg);
}
......@@ -100,38 +113,36 @@ static int intel_dvo_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
struct drm_encoder *encoder = intel_attached_encoder(connector);
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
struct intel_dvo_device *dvo = intel_encoder->dev_priv;
struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder);
if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
return MODE_NO_DBLESCAN;
/* XXX: Validate clock range */
if (dvo->panel_fixed_mode) {
if (mode->hdisplay > dvo->panel_fixed_mode->hdisplay)
if (intel_dvo->panel_fixed_mode) {
if (mode->hdisplay > intel_dvo->panel_fixed_mode->hdisplay)
return MODE_PANEL;
if (mode->vdisplay > dvo->panel_fixed_mode->vdisplay)
if (mode->vdisplay > intel_dvo->panel_fixed_mode->vdisplay)
return MODE_PANEL;
}
return dvo->dev_ops->mode_valid(dvo, mode);
return intel_dvo->dev.dev_ops->mode_valid(&intel_dvo->dev, mode);
}
static bool intel_dvo_mode_fixup(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
struct intel_dvo_device *dvo = intel_encoder->dev_priv;
struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder);
/* If we have timings from the BIOS for the panel, put them in
* to the adjusted mode. The CRTC will be set up for this mode,
* with the panel scaling set up to source from the H/VDisplay
* of the original mode.
*/
if (dvo->panel_fixed_mode != NULL) {
#define C(x) adjusted_mode->x = dvo->panel_fixed_mode->x
if (intel_dvo->panel_fixed_mode != NULL) {
#define C(x) adjusted_mode->x = intel_dvo->panel_fixed_mode->x
C(hdisplay);
C(hsync_start);
C(hsync_end);
......@@ -145,8 +156,8 @@ static bool intel_dvo_mode_fixup(struct drm_encoder *encoder,
#undef C
}
if (dvo->dev_ops->mode_fixup)
return dvo->dev_ops->mode_fixup(dvo, mode, adjusted_mode);
if (intel_dvo->dev.dev_ops->mode_fixup)
return intel_dvo->dev.dev_ops->mode_fixup(&intel_dvo->dev, mode, adjusted_mode);
return true;
}
......@@ -158,11 +169,10 @@ static void intel_dvo_mode_set(struct drm_encoder *encoder,
struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
struct intel_dvo_device *dvo = intel_encoder->dev_priv;
struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder);
int pipe = intel_crtc->pipe;
u32 dvo_val;
u32 dvo_reg = dvo->dvo_reg, dvo_srcdim_reg;
u32 dvo_reg = intel_dvo->dev.dvo_reg, dvo_srcdim_reg;
int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
switch (dvo_reg) {
......@@ -178,7 +188,7 @@ static void intel_dvo_mode_set(struct drm_encoder *encoder,
break;
}
dvo->dev_ops->mode_set(dvo, mode, adjusted_mode);
intel_dvo->dev.dev_ops->mode_set(&intel_dvo->dev, mode, adjusted_mode);
/* Save the data order, since I don't know what it should be set to. */
dvo_val = I915_READ(dvo_reg) &
......@@ -214,40 +224,38 @@ static void intel_dvo_mode_set(struct drm_encoder *encoder,
static enum drm_connector_status intel_dvo_detect(struct drm_connector *connector)
{
struct drm_encoder *encoder = intel_attached_encoder(connector);
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
struct intel_dvo_device *dvo = intel_encoder->dev_priv;
struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder);
return dvo->dev_ops->detect(dvo);
return intel_dvo->dev.dev_ops->detect(&intel_dvo->dev);
}
static int intel_dvo_get_modes(struct drm_connector *connector)
{
struct drm_encoder *encoder = intel_attached_encoder(connector);
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
struct intel_dvo_device *dvo = intel_encoder->dev_priv;
struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder);
/* We should probably have an i2c driver get_modes function for those
* devices which will have a fixed set of modes determined by the chip
* (TV-out, for example), but for now with just TMDS and LVDS,
* that's not the case.
*/
intel_ddc_get_modes(connector, intel_encoder->ddc_bus);
intel_ddc_get_modes(connector, intel_dvo->base.ddc_bus);
if (!list_empty(&connector->probed_modes))
return 1;
if (dvo->panel_fixed_mode != NULL) {
if (intel_dvo->panel_fixed_mode != NULL) {
struct drm_display_mode *mode;
mode = drm_mode_duplicate(connector->dev, dvo->panel_fixed_mode);
mode = drm_mode_duplicate(connector->dev, intel_dvo->panel_fixed_mode);
if (mode) {
drm_mode_probed_add(connector, mode);
return 1;
}
}
return 0;
}
static void intel_dvo_destroy (struct drm_connector *connector)
static void intel_dvo_destroy(struct drm_connector *connector)
{
drm_sysfs_connector_remove(connector);
drm_connector_cleanup(connector);
......@@ -277,28 +285,20 @@ static const struct drm_connector_helper_funcs intel_dvo_connector_helper_funcs
static void intel_dvo_enc_destroy(struct drm_encoder *encoder)
{
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
struct intel_dvo_device *dvo = intel_encoder->dev_priv;
if (dvo) {
if (dvo->dev_ops->destroy)
dvo->dev_ops->destroy(dvo);
if (dvo->panel_fixed_mode)
kfree(dvo->panel_fixed_mode);
}
if (intel_encoder->i2c_bus)
intel_i2c_destroy(intel_encoder->i2c_bus);
if (intel_encoder->ddc_bus)
intel_i2c_destroy(intel_encoder->ddc_bus);
drm_encoder_cleanup(encoder);
kfree(intel_encoder);
struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder);
if (intel_dvo->dev.dev_ops->destroy)
intel_dvo->dev.dev_ops->destroy(&intel_dvo->dev);
kfree(intel_dvo->panel_fixed_mode);
intel_encoder_destroy(encoder);
}
static const struct drm_encoder_funcs intel_dvo_enc_funcs = {
.destroy = intel_dvo_enc_destroy,
};
/**
* Attempts to get a fixed panel timing for LVDS (currently only the i830).
*
......@@ -306,15 +306,13 @@ static const struct drm_encoder_funcs intel_dvo_enc_funcs = {
* chip being on DVOB/C and having multiple pipes.
*/
static struct drm_display_mode *
intel_dvo_get_current_mode (struct drm_connector *connector)
intel_dvo_get_current_mode(struct drm_connector *connector)
{
struct drm_device *dev = connector->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_encoder *encoder = intel_attached_encoder(connector);
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
struct intel_dvo_device *dvo = intel_encoder->dev_priv;
uint32_t dvo_reg = dvo->dvo_reg;
uint32_t dvo_val = I915_READ(dvo_reg);
struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder);
uint32_t dvo_val = I915_READ(intel_dvo->dev.dvo_reg);
struct drm_display_mode *mode = NULL;
/* If the DVO port is active, that'll be the LVDS, so we can pull out
......@@ -327,7 +325,6 @@ intel_dvo_get_current_mode (struct drm_connector *connector)
crtc = intel_get_crtc_from_pipe(dev, pipe);
if (crtc) {
mode = intel_crtc_mode_get(dev, crtc);
if (mode) {
mode->type |= DRM_MODE_TYPE_PREFERRED;
if (dvo_val & DVO_HSYNC_ACTIVE_HIGH)
......@@ -337,28 +334,32 @@ intel_dvo_get_current_mode (struct drm_connector *connector)
}
}
}
return mode;
}
void intel_dvo_init(struct drm_device *dev)
{
struct intel_encoder *intel_encoder;
struct intel_dvo *intel_dvo;
struct intel_connector *intel_connector;
struct intel_dvo_device *dvo;
struct i2c_adapter *i2cbus = NULL;
int ret = 0;
int i;
int encoder_type = DRM_MODE_ENCODER_NONE;
intel_encoder = kzalloc (sizeof(struct intel_encoder), GFP_KERNEL);
if (!intel_encoder)
intel_dvo = kzalloc(sizeof(struct intel_dvo), GFP_KERNEL);
if (!intel_dvo)
return;
intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL);
if (!intel_connector) {
kfree(intel_encoder);
kfree(intel_dvo);
return;
}
intel_encoder = &intel_dvo->base;
/* Set up the DDC bus */
intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOD, "DVODDC_D");
if (!intel_encoder->ddc_bus)
......@@ -367,10 +368,9 @@ void intel_dvo_init(struct drm_device *dev)
/* Now, try to find a controller */
for (i = 0; i < ARRAY_SIZE(intel_dvo_devices); i++) {
struct drm_connector *connector = &intel_connector->base;
const struct intel_dvo_device *dvo = &intel_dvo_devices[i];
int gpio;
dvo = &intel_dvo_devices[i];
/* Allow the I2C driver info to specify the GPIO to be used in
* special cases, but otherwise default to what's defined
* in the spec.
......@@ -393,11 +393,8 @@ void intel_dvo_init(struct drm_device *dev)
continue;
}
if (dvo->dev_ops!= NULL)
ret = dvo->dev_ops->init(dvo, i2cbus);
else
ret = false;
intel_dvo->dev = *dvo;
ret = dvo->dev_ops->init(&intel_dvo->dev, i2cbus);
if (!ret)
continue;
......@@ -429,9 +426,6 @@ void intel_dvo_init(struct drm_device *dev)
connector->interlace_allowed = false;
connector->doublescan_allowed = false;
intel_encoder->dev_priv = dvo;
intel_encoder->i2c_bus = i2cbus;
drm_encoder_init(dev, &intel_encoder->enc,
&intel_dvo_enc_funcs, encoder_type);
drm_encoder_helper_add(&intel_encoder->enc,
......@@ -447,9 +441,9 @@ void intel_dvo_init(struct drm_device *dev)
* headers, likely), so for now, just get the current
* mode being output through DVO.
*/
dvo->panel_fixed_mode =
intel_dvo->panel_fixed_mode =
intel_dvo_get_current_mode(connector);
dvo->panel_wants_dither = true;
intel_dvo->panel_wants_dither = true;
}
drm_sysfs_connector_add(connector);
......@@ -461,6 +455,6 @@ void intel_dvo_init(struct drm_device *dev)
if (i2cbus != NULL)
intel_i2c_destroy(i2cbus);
free_intel:
kfree(intel_encoder);
kfree(intel_dvo);
kfree(intel_connector);
}
......@@ -37,11 +37,17 @@
#include "i915_drm.h"
#include "i915_drv.h"
struct intel_hdmi_priv {
struct intel_hdmi {
struct intel_encoder base;
u32 sdvox_reg;
bool has_hdmi_sink;
};
static struct intel_hdmi *enc_to_intel_hdmi(struct drm_encoder *encoder)
{
return container_of(enc_to_intel_encoder(encoder), struct intel_hdmi, base);
}
static void intel_hdmi_mode_set(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
......@@ -50,8 +56,7 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder,
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_crtc *crtc = encoder->crtc;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv;
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
u32 sdvox;
sdvox = SDVO_ENCODING_HDMI | SDVO_BORDER_ENABLE;
......@@ -60,7 +65,7 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder,
if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
sdvox |= SDVO_HSYNC_ACTIVE_HIGH;
if (hdmi_priv->has_hdmi_sink) {
if (intel_hdmi->has_hdmi_sink) {
sdvox |= SDVO_AUDIO_ENABLE;
if (HAS_PCH_CPT(dev))
sdvox |= HDMI_MODE_SELECT;
......@@ -73,26 +78,25 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder,
sdvox |= SDVO_PIPE_B_SELECT;
}
I915_WRITE(hdmi_priv->sdvox_reg, sdvox);
POSTING_READ(hdmi_priv->sdvox_reg);
I915_WRITE(intel_hdmi->sdvox_reg, sdvox);
POSTING_READ(intel_hdmi->sdvox_reg);
}
static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode)
{
struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv;
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
u32 temp;
temp = I915_READ(hdmi_priv->sdvox_reg);
temp = I915_READ(intel_hdmi->sdvox_reg);
/* HW workaround, need to toggle enable bit off and on for 12bpc, but
* we do this anyway which shows more stable in testing.
*/
if (HAS_PCH_SPLIT(dev)) {
I915_WRITE(hdmi_priv->sdvox_reg, temp & ~SDVO_ENABLE);
POSTING_READ(hdmi_priv->sdvox_reg);
I915_WRITE(intel_hdmi->sdvox_reg, temp & ~SDVO_ENABLE);
POSTING_READ(intel_hdmi->sdvox_reg);
}
if (mode != DRM_MODE_DPMS_ON) {
......@@ -101,15 +105,15 @@ static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode)
temp |= SDVO_ENABLE;
}
I915_WRITE(hdmi_priv->sdvox_reg, temp);
POSTING_READ(hdmi_priv->sdvox_reg);
I915_WRITE(intel_hdmi->sdvox_reg, temp);
POSTING_READ(intel_hdmi->sdvox_reg);
/* HW workaround, need to write this twice for issue that may result
* in first write getting masked.
*/
if (HAS_PCH_SPLIT(dev)) {
I915_WRITE(hdmi_priv->sdvox_reg, temp);
POSTING_READ(hdmi_priv->sdvox_reg);
I915_WRITE(intel_hdmi->sdvox_reg, temp);
POSTING_READ(intel_hdmi->sdvox_reg);
}
}
......@@ -138,19 +142,17 @@ static enum drm_connector_status
intel_hdmi_detect(struct drm_connector *connector)
{
struct drm_encoder *encoder = intel_attached_encoder(connector);
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv;
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
struct edid *edid = NULL;
enum drm_connector_status status = connector_status_disconnected;
hdmi_priv->has_hdmi_sink = false;
edid = drm_get_edid(connector,
intel_encoder->ddc_bus);
intel_hdmi->has_hdmi_sink = false;
edid = drm_get_edid(connector, intel_hdmi->base.ddc_bus);
if (edid) {
if (edid->input & DRM_EDID_INPUT_DIGITAL) {
status = connector_status_connected;
hdmi_priv->has_hdmi_sink = drm_detect_hdmi_monitor(edid);
intel_hdmi->has_hdmi_sink = drm_detect_hdmi_monitor(edid);
}
connector->display_info.raw_edid = NULL;
kfree(edid);
......@@ -162,13 +164,13 @@ intel_hdmi_detect(struct drm_connector *connector)
static int intel_hdmi_get_modes(struct drm_connector *connector)
{
struct drm_encoder *encoder = intel_attached_encoder(connector);
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
/* We should parse the EDID data and find out if it's an HDMI sink so
* we can send audio to it.
*/
return intel_ddc_get_modes(connector, intel_encoder->ddc_bus);
return intel_ddc_get_modes(connector, intel_hdmi->base.ddc_bus);
}
static void intel_hdmi_destroy(struct drm_connector *connector)
......@@ -199,18 +201,8 @@ static const struct drm_connector_helper_funcs intel_hdmi_connector_helper_funcs
.best_encoder = intel_attached_encoder,
};
static void intel_hdmi_enc_destroy(struct drm_encoder *encoder)
{
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
if (intel_encoder->i2c_bus)
intel_i2c_destroy(intel_encoder->i2c_bus);
drm_encoder_cleanup(encoder);
kfree(intel_encoder);
}
static const struct drm_encoder_funcs intel_hdmi_enc_funcs = {
.destroy = intel_hdmi_enc_destroy,
.destroy = intel_encoder_destroy,
};
void intel_hdmi_init(struct drm_device *dev, int sdvox_reg)
......@@ -219,21 +211,19 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg)
struct drm_connector *connector;
struct intel_encoder *intel_encoder;
struct intel_connector *intel_connector;
struct intel_hdmi_priv *hdmi_priv;
struct intel_hdmi *intel_hdmi;
intel_encoder = kcalloc(sizeof(struct intel_encoder) +
sizeof(struct intel_hdmi_priv), 1, GFP_KERNEL);
if (!intel_encoder)
intel_hdmi = kzalloc(sizeof(struct intel_hdmi), GFP_KERNEL);
if (!intel_hdmi)
return;
intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL);
if (!intel_connector) {
kfree(intel_encoder);
kfree(intel_hdmi);
return;
}
hdmi_priv = (struct intel_hdmi_priv *)(intel_encoder + 1);
intel_encoder = &intel_hdmi->base;
connector = &intel_connector->base;
drm_connector_init(dev, connector, &intel_hdmi_connector_funcs,
DRM_MODE_CONNECTOR_HDMIA);
......@@ -274,8 +264,7 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg)
if (!intel_encoder->ddc_bus)
goto err_connector;
hdmi_priv->sdvox_reg = sdvox_reg;
intel_encoder->dev_priv = hdmi_priv;
intel_hdmi->sdvox_reg = sdvox_reg;
drm_encoder_init(dev, &intel_encoder->enc, &intel_hdmi_enc_funcs,
DRM_MODE_ENCODER_TMDS);
......@@ -298,7 +287,7 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg)
err_connector:
drm_connector_cleanup(connector);
kfree(intel_encoder);
kfree(intel_hdmi);
kfree(intel_connector);
return;
......
......@@ -41,12 +41,18 @@
#include <linux/acpi.h>
/* Private structure for the integrated LVDS support */
struct intel_lvds_priv {
struct intel_lvds {
struct intel_encoder base;
int fitting_mode;
u32 pfit_control;
u32 pfit_pgm_ratios;
};
static struct intel_lvds *enc_to_intel_lvds(struct drm_encoder *encoder)
{
return container_of(enc_to_intel_encoder(encoder), struct intel_lvds, base);
}
/**
* Sets the backlight level.
*
......@@ -219,9 +225,8 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
struct intel_lvds *intel_lvds = enc_to_intel_lvds(encoder);
struct drm_encoder *tmp_encoder;
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv;
u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0;
/* Should never happen!! */
......@@ -293,7 +298,7 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
I915_WRITE(BCLRPAT_B, 0);
}
switch (lvds_priv->fitting_mode) {
switch (intel_lvds->fitting_mode) {
case DRM_MODE_SCALE_CENTER:
/*
* For centered modes, we have to calculate border widths &
......@@ -378,8 +383,8 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
}
out:
lvds_priv->pfit_control = pfit_control;
lvds_priv->pfit_pgm_ratios = pfit_pgm_ratios;
intel_lvds->pfit_control = pfit_control;
intel_lvds->pfit_pgm_ratios = pfit_pgm_ratios;
dev_priv->lvds_border_bits = border;
/*
......@@ -427,8 +432,7 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder,
{
struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv;
struct intel_lvds *intel_lvds = enc_to_intel_lvds(encoder);
/*
* The LVDS pin pair will already have been turned on in the
......@@ -444,8 +448,8 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder,
* screen. Should be enabled before the pipe is enabled, according to
* register description and PRM.
*/
I915_WRITE(PFIT_PGM_RATIOS, lvds_priv->pfit_pgm_ratios);
I915_WRITE(PFIT_CONTROL, lvds_priv->pfit_control);
I915_WRITE(PFIT_PGM_RATIOS, intel_lvds->pfit_pgm_ratios);
I915_WRITE(PFIT_CONTROL, intel_lvds->pfit_control);
}
/**
......@@ -600,18 +604,17 @@ static int intel_lvds_set_property(struct drm_connector *connector,
connector->encoder) {
struct drm_crtc *crtc = connector->encoder->crtc;
struct drm_encoder *encoder = connector->encoder;
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv;
struct intel_lvds *intel_lvds = enc_to_intel_lvds(encoder);
if (value == DRM_MODE_SCALE_NONE) {
DRM_DEBUG_KMS("no scaling not supported\n");
return 0;
}
if (lvds_priv->fitting_mode == value) {
if (intel_lvds->fitting_mode == value) {
/* the LVDS scaling property is not changed */
return 0;
}
lvds_priv->fitting_mode = value;
intel_lvds->fitting_mode = value;
if (crtc && crtc->enabled) {
/*
* If the CRTC is enabled, the display will be changed
......@@ -647,19 +650,8 @@ static const struct drm_connector_funcs intel_lvds_connector_funcs = {
.destroy = intel_lvds_destroy,
};
static void intel_lvds_enc_destroy(struct drm_encoder *encoder)
{
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
if (intel_encoder->ddc_bus)
intel_i2c_destroy(intel_encoder->ddc_bus);
drm_encoder_cleanup(encoder);
kfree(intel_encoder);
}
static const struct drm_encoder_funcs intel_lvds_enc_funcs = {
.destroy = intel_lvds_enc_destroy,
.destroy = intel_encoder_destroy,
};
static int __init intel_no_lvds_dmi_callback(const struct dmi_system_id *id)
......@@ -843,13 +835,13 @@ static int lvds_is_present_in_vbt(struct drm_device *dev)
void intel_lvds_init(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_lvds *intel_lvds;
struct intel_encoder *intel_encoder;
struct intel_connector *intel_connector;
struct drm_connector *connector;
struct drm_encoder *encoder;
struct drm_display_mode *scan; /* *modes, *bios_mode; */
struct drm_crtc *crtc;
struct intel_lvds_priv *lvds_priv;
u32 lvds;
int pipe, gpio = GPIOC;
......@@ -872,20 +864,20 @@ void intel_lvds_init(struct drm_device *dev)
gpio = PCH_GPIOC;
}
intel_encoder = kzalloc(sizeof(struct intel_encoder) +
sizeof(struct intel_lvds_priv), GFP_KERNEL);
if (!intel_encoder) {
intel_lvds = kzalloc(sizeof(struct intel_lvds), GFP_KERNEL);
if (!intel_lvds) {
return;
}
intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL);
if (!intel_connector) {
kfree(intel_encoder);
kfree(intel_lvds);
return;
}
connector = &intel_connector->base;
intel_encoder = &intel_lvds->base;
encoder = &intel_encoder->enc;
connector = &intel_connector->base;
drm_connector_init(dev, &intel_connector->base, &intel_lvds_connector_funcs,
DRM_MODE_CONNECTOR_LVDS);
......@@ -905,8 +897,6 @@ void intel_lvds_init(struct drm_device *dev)
connector->interlace_allowed = false;
connector->doublescan_allowed = false;
lvds_priv = (struct intel_lvds_priv *)(intel_encoder + 1);
intel_encoder->dev_priv = lvds_priv;
/* create the scaling mode property */
drm_mode_create_scaling_mode_property(dev);
/*
......@@ -916,7 +906,7 @@ void intel_lvds_init(struct drm_device *dev)
drm_connector_attach_property(&intel_connector->base,
dev->mode_config.scaling_mode_property,
DRM_MODE_SCALE_ASPECT);
lvds_priv->fitting_mode = DRM_MODE_SCALE_ASPECT;
intel_lvds->fitting_mode = DRM_MODE_SCALE_ASPECT;
/*
* LVDS discovery:
* 1) check for EDID on DDC
......@@ -1024,6 +1014,6 @@ void intel_lvds_init(struct drm_device *dev)
intel_i2c_destroy(intel_encoder->ddc_bus);
drm_connector_cleanup(connector);
drm_encoder_cleanup(encoder);
kfree(intel_encoder);
kfree(intel_lvds);
kfree(intel_connector);
}
......@@ -31,8 +31,8 @@
#include "drmP.h"
#include "drm.h"
#include "drm_crtc.h"
#include "intel_drv.h"
#include "drm_edid.h"
#include "intel_drv.h"
#include "i915_drm.h"
#include "i915_drv.h"
#include "intel_sdvo_regs.h"
......@@ -61,7 +61,9 @@ static char *tv_format_names[] = {
#define TV_FORMAT_NUM (sizeof(tv_format_names) / sizeof(*tv_format_names))
struct intel_sdvo_priv {
struct intel_sdvo {
struct intel_encoder base;
u8 slave_addr;
/* Register for the SDVO device: SDVOB or SDVOC */
......@@ -173,9 +175,13 @@ struct intel_sdvo_connector {
u32 cur_hue, max_hue;
};
static struct intel_sdvo *enc_to_intel_sdvo(struct drm_encoder *encoder)
{
return container_of(enc_to_intel_encoder(encoder), struct intel_sdvo, base);
}
static bool
intel_sdvo_output_setup(struct intel_encoder *intel_encoder,
uint16_t flags);
intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, uint16_t flags);
static void
intel_sdvo_tv_create_property(struct drm_connector *connector, int type);
static void
......@@ -186,21 +192,20 @@ intel_sdvo_create_enhance_property(struct drm_connector *connector);
* SDVOB and SDVOC to work around apparent hardware issues (according to
* comments in the BIOS).
*/
static void intel_sdvo_write_sdvox(struct intel_encoder *intel_encoder, u32 val)
static void intel_sdvo_write_sdvox(struct intel_sdvo *intel_sdvo, u32 val)
{
struct drm_device *dev = intel_encoder->enc.dev;
struct drm_device *dev = intel_sdvo->base.enc.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
u32 bval = val, cval = val;
int i;
if (sdvo_priv->sdvo_reg == PCH_SDVOB) {
I915_WRITE(sdvo_priv->sdvo_reg, val);
I915_READ(sdvo_priv->sdvo_reg);
if (intel_sdvo->sdvo_reg == PCH_SDVOB) {
I915_WRITE(intel_sdvo->sdvo_reg, val);
I915_READ(intel_sdvo->sdvo_reg);
return;
}
if (sdvo_priv->sdvo_reg == SDVOB) {
if (intel_sdvo->sdvo_reg == SDVOB) {
cval = I915_READ(SDVOC);
} else {
bval = I915_READ(SDVOB);
......@@ -219,23 +224,22 @@ static void intel_sdvo_write_sdvox(struct intel_encoder *intel_encoder, u32 val)
}
}
static bool intel_sdvo_read_byte(struct intel_encoder *intel_encoder, u8 addr,
static bool intel_sdvo_read_byte(struct intel_sdvo *intel_sdvo, u8 addr,
u8 *ch)
{
struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
u8 out_buf[2];
u8 buf[2];
int ret;
struct i2c_msg msgs[] = {
{
.addr = sdvo_priv->slave_addr >> 1,
.addr = intel_sdvo->slave_addr >> 1,
.flags = 0,
.len = 1,
.buf = out_buf,
},
{
.addr = sdvo_priv->slave_addr >> 1,
.addr = intel_sdvo->slave_addr >> 1,
.flags = I2C_M_RD,
.len = 1,
.buf = buf,
......@@ -245,7 +249,7 @@ static bool intel_sdvo_read_byte(struct intel_encoder *intel_encoder, u8 addr,
out_buf[0] = addr;
out_buf[1] = 0;
if ((ret = i2c_transfer(intel_encoder->i2c_bus, msgs, 2)) == 2)
if ((ret = i2c_transfer(intel_sdvo->base.i2c_bus, msgs, 2)) == 2)
{
*ch = buf[0];
return true;
......@@ -255,14 +259,13 @@ static bool intel_sdvo_read_byte(struct intel_encoder *intel_encoder, u8 addr,
return false;
}
static bool intel_sdvo_write_byte(struct intel_encoder *intel_encoder, int addr,
static bool intel_sdvo_write_byte(struct intel_sdvo *intel_sdvo, int addr,
u8 ch)
{
struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
u8 out_buf[2];
struct i2c_msg msgs[] = {
{
.addr = sdvo_priv->slave_addr >> 1,
.addr = intel_sdvo->slave_addr >> 1,
.flags = 0,
.len = 2,
.buf = out_buf,
......@@ -272,7 +275,7 @@ static bool intel_sdvo_write_byte(struct intel_encoder *intel_encoder, int addr,
out_buf[0] = addr;
out_buf[1] = ch;
if (i2c_transfer(intel_encoder->i2c_bus, msgs, 1) == 1)
if (i2c_transfer(intel_sdvo->base.i2c_bus, msgs, 1) == 1)
{
return true;
}
......@@ -377,17 +380,15 @@ static const struct _sdvo_cmd_name {
};
#define IS_SDVOB(reg) (reg == SDVOB || reg == PCH_SDVOB)
#define SDVO_NAME(dev_priv) (IS_SDVOB((dev_priv)->sdvo_reg) ? "SDVOB" : "SDVOC")
#define SDVO_PRIV(encoder) ((struct intel_sdvo_priv *) (encoder)->dev_priv)
#define SDVO_NAME(svdo) (IS_SDVOB((svdo)->sdvo_reg) ? "SDVOB" : "SDVOC")
static void intel_sdvo_debug_write(struct intel_encoder *intel_encoder, u8 cmd,
static void intel_sdvo_debug_write(struct intel_sdvo *intel_sdvo, u8 cmd,
void *args, int args_len)
{
struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
int i;
DRM_DEBUG_KMS("%s: W: %02X ",
SDVO_NAME(sdvo_priv), cmd);
SDVO_NAME(intel_sdvo), cmd);
for (i = 0; i < args_len; i++)
DRM_LOG_KMS("%02X ", ((u8 *)args)[i]);
for (; i < 8; i++)
......@@ -403,19 +404,19 @@ static void intel_sdvo_debug_write(struct intel_encoder *intel_encoder, u8 cmd,
DRM_LOG_KMS("\n");
}
static void intel_sdvo_write_cmd(struct intel_encoder *intel_encoder, u8 cmd,
static void intel_sdvo_write_cmd(struct intel_sdvo *intel_sdvo, u8 cmd,
void *args, int args_len)
{
int i;
intel_sdvo_debug_write(intel_encoder, cmd, args, args_len);
intel_sdvo_debug_write(intel_sdvo, cmd, args, args_len);
for (i = 0; i < args_len; i++) {
intel_sdvo_write_byte(intel_encoder, SDVO_I2C_ARG_0 - i,
intel_sdvo_write_byte(intel_sdvo, SDVO_I2C_ARG_0 - i,
((u8*)args)[i]);
}
intel_sdvo_write_byte(intel_encoder, SDVO_I2C_OPCODE, cmd);
intel_sdvo_write_byte(intel_sdvo, SDVO_I2C_OPCODE, cmd);
}
static const char *cmd_status_names[] = {
......@@ -428,14 +429,13 @@ static const char *cmd_status_names[] = {
"Scaling not supported"
};
static void intel_sdvo_debug_response(struct intel_encoder *intel_encoder,
static void intel_sdvo_debug_response(struct intel_sdvo *intel_sdvo,
void *response, int response_len,
u8 status)
{
struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
int i;
DRM_DEBUG_KMS("%s: R: ", SDVO_NAME(sdvo_priv));
DRM_DEBUG_KMS("%s: R: ", SDVO_NAME(intel_sdvo));
for (i = 0; i < response_len; i++)
DRM_LOG_KMS("%02X ", ((u8 *)response)[i]);
for (; i < 8; i++)
......@@ -447,7 +447,7 @@ static void intel_sdvo_debug_response(struct intel_encoder *intel_encoder,
DRM_LOG_KMS("\n");
}
static u8 intel_sdvo_read_response(struct intel_encoder *intel_encoder,
static u8 intel_sdvo_read_response(struct intel_sdvo *intel_sdvo,
void *response, int response_len)
{
int i;
......@@ -457,16 +457,16 @@ static u8 intel_sdvo_read_response(struct intel_encoder *intel_encoder,
while (retry--) {
/* Read the command response */
for (i = 0; i < response_len; i++) {
intel_sdvo_read_byte(intel_encoder,
intel_sdvo_read_byte(intel_sdvo,
SDVO_I2C_RETURN_0 + i,
&((u8 *)response)[i]);
}
/* read the return status */
intel_sdvo_read_byte(intel_encoder, SDVO_I2C_CMD_STATUS,
intel_sdvo_read_byte(intel_sdvo, SDVO_I2C_CMD_STATUS,
&status);
intel_sdvo_debug_response(intel_encoder, response, response_len,
intel_sdvo_debug_response(intel_sdvo, response, response_len,
status);
if (status != SDVO_CMD_STATUS_PENDING)
return status;
......@@ -494,37 +494,36 @@ static int intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode)
* another I2C transaction after issuing the DDC bus switch, it will be
* switched to the internal SDVO register.
*/
static void intel_sdvo_set_control_bus_switch(struct intel_encoder *intel_encoder,
static void intel_sdvo_set_control_bus_switch(struct intel_sdvo *intel_sdvo,
u8 target)
{
struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
u8 out_buf[2], cmd_buf[2], ret_value[2], ret;
struct i2c_msg msgs[] = {
{
.addr = sdvo_priv->slave_addr >> 1,
.addr = intel_sdvo->slave_addr >> 1,
.flags = 0,
.len = 2,
.buf = out_buf,
},
/* the following two are to read the response */
{
.addr = sdvo_priv->slave_addr >> 1,
.addr = intel_sdvo->slave_addr >> 1,
.flags = 0,
.len = 1,
.buf = cmd_buf,
},
{
.addr = sdvo_priv->slave_addr >> 1,
.addr = intel_sdvo->slave_addr >> 1,
.flags = I2C_M_RD,
.len = 1,
.buf = ret_value,
},
};
intel_sdvo_debug_write(intel_encoder, SDVO_CMD_SET_CONTROL_BUS_SWITCH,
intel_sdvo_debug_write(intel_sdvo, SDVO_CMD_SET_CONTROL_BUS_SWITCH,
&target, 1);
/* write the DDC switch command argument */
intel_sdvo_write_byte(intel_encoder, SDVO_I2C_ARG_0, target);
intel_sdvo_write_byte(intel_sdvo, SDVO_I2C_ARG_0, target);
out_buf[0] = SDVO_I2C_OPCODE;
out_buf[1] = SDVO_CMD_SET_CONTROL_BUS_SWITCH;
......@@ -533,7 +532,7 @@ static void intel_sdvo_set_control_bus_switch(struct intel_encoder *intel_encode
ret_value[0] = 0;
ret_value[1] = 0;
ret = i2c_transfer(intel_encoder->i2c_bus, msgs, 3);
ret = i2c_transfer(intel_sdvo->base.i2c_bus, msgs, 3);
if (ret != 3) {
/* failure in I2C transfer */
DRM_DEBUG_KMS("I2c transfer returned %d\n", ret);
......@@ -547,7 +546,7 @@ static void intel_sdvo_set_control_bus_switch(struct intel_encoder *intel_encode
return;
}
static bool intel_sdvo_set_target_input(struct intel_encoder *intel_encoder, bool target_0, bool target_1)
static bool intel_sdvo_set_target_input(struct intel_sdvo *intel_sdvo, bool target_0, bool target_1)
{
struct intel_sdvo_set_target_input_args targets = {0};
u8 status;
......@@ -558,10 +557,10 @@ static bool intel_sdvo_set_target_input(struct intel_encoder *intel_encoder, boo
if (target_1)
targets.target_1 = 1;
intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_TARGET_INPUT, &targets,
intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_TARGET_INPUT, &targets,
sizeof(targets));
status = intel_sdvo_read_response(intel_encoder, NULL, 0);
status = intel_sdvo_read_response(intel_sdvo, NULL, 0);
return (status == SDVO_CMD_STATUS_SUCCESS);
}
......@@ -572,13 +571,13 @@ static bool intel_sdvo_set_target_input(struct intel_encoder *intel_encoder, boo
* This function is making an assumption about the layout of the response,
* which should be checked against the docs.
*/
static bool intel_sdvo_get_trained_inputs(struct intel_encoder *intel_encoder, bool *input_1, bool *input_2)
static bool intel_sdvo_get_trained_inputs(struct intel_sdvo *intel_sdvo, bool *input_1, bool *input_2)
{
struct intel_sdvo_get_trained_inputs_response response;
u8 status;
intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_TRAINED_INPUTS, NULL, 0);
status = intel_sdvo_read_response(intel_encoder, &response, sizeof(response));
intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_GET_TRAINED_INPUTS, NULL, 0);
status = intel_sdvo_read_response(intel_sdvo, &response, sizeof(response));
if (status != SDVO_CMD_STATUS_SUCCESS)
return false;
......@@ -587,18 +586,18 @@ static bool intel_sdvo_get_trained_inputs(struct intel_encoder *intel_encoder, b
return true;
}
static bool intel_sdvo_set_active_outputs(struct intel_encoder *intel_encoder,
static bool intel_sdvo_set_active_outputs(struct intel_sdvo *intel_sdvo,
u16 outputs)
{
u8 status;
intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ACTIVE_OUTPUTS, &outputs,
intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_ACTIVE_OUTPUTS, &outputs,
sizeof(outputs));
status = intel_sdvo_read_response(intel_encoder, NULL, 0);
status = intel_sdvo_read_response(intel_sdvo, NULL, 0);
return (status == SDVO_CMD_STATUS_SUCCESS);
}
static bool intel_sdvo_set_encoder_power_state(struct intel_encoder *intel_encoder,
static bool intel_sdvo_set_encoder_power_state(struct intel_sdvo *intel_sdvo,
int mode)
{
u8 status, state = SDVO_ENCODER_STATE_ON;
......@@ -618,24 +617,24 @@ static bool intel_sdvo_set_encoder_power_state(struct intel_encoder *intel_encod
break;
}
intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ENCODER_POWER_STATE, &state,
intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_ENCODER_POWER_STATE, &state,
sizeof(state));
status = intel_sdvo_read_response(intel_encoder, NULL, 0);
status = intel_sdvo_read_response(intel_sdvo, NULL, 0);
return (status == SDVO_CMD_STATUS_SUCCESS);
}
static bool intel_sdvo_get_input_pixel_clock_range(struct intel_encoder *intel_encoder,
static bool intel_sdvo_get_input_pixel_clock_range(struct intel_sdvo *intel_sdvo,
int *clock_min,
int *clock_max)
{
struct intel_sdvo_pixel_clock_range clocks;
u8 status;
intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE,
intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE,
NULL, 0);
status = intel_sdvo_read_response(intel_encoder, &clocks, sizeof(clocks));
status = intel_sdvo_read_response(intel_sdvo, &clocks, sizeof(clocks));
if (status != SDVO_CMD_STATUS_SUCCESS)
return false;
......@@ -647,58 +646,57 @@ static bool intel_sdvo_get_input_pixel_clock_range(struct intel_encoder *intel_e
return true;
}
static bool intel_sdvo_set_target_output(struct intel_encoder *intel_encoder,
static bool intel_sdvo_set_target_output(struct intel_sdvo *intel_sdvo,
u16 outputs)
{
u8 status;
intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_TARGET_OUTPUT, &outputs,
intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_TARGET_OUTPUT, &outputs,
sizeof(outputs));
status = intel_sdvo_read_response(intel_encoder, NULL, 0);
status = intel_sdvo_read_response(intel_sdvo, NULL, 0);
return (status == SDVO_CMD_STATUS_SUCCESS);
}
static bool intel_sdvo_set_timing(struct intel_encoder *intel_encoder, u8 cmd,
static bool intel_sdvo_set_timing(struct intel_sdvo *intel_sdvo, u8 cmd,
struct intel_sdvo_dtd *dtd)
{
u8 status;
intel_sdvo_write_cmd(intel_encoder, cmd, &dtd->part1, sizeof(dtd->part1));
status = intel_sdvo_read_response(intel_encoder, NULL, 0);
intel_sdvo_write_cmd(intel_sdvo, cmd, &dtd->part1, sizeof(dtd->part1));
status = intel_sdvo_read_response(intel_sdvo, NULL, 0);
if (status != SDVO_CMD_STATUS_SUCCESS)
return false;
intel_sdvo_write_cmd(intel_encoder, cmd + 1, &dtd->part2, sizeof(dtd->part2));
status = intel_sdvo_read_response(intel_encoder, NULL, 0);
intel_sdvo_write_cmd(intel_sdvo, cmd + 1, &dtd->part2, sizeof(dtd->part2));
status = intel_sdvo_read_response(intel_sdvo, NULL, 0);
if (status != SDVO_CMD_STATUS_SUCCESS)
return false;
return true;
}
static bool intel_sdvo_set_input_timing(struct intel_encoder *intel_encoder,
static bool intel_sdvo_set_input_timing(struct intel_sdvo *intel_sdvo,
struct intel_sdvo_dtd *dtd)
{
return intel_sdvo_set_timing(intel_encoder,
return intel_sdvo_set_timing(intel_sdvo,
SDVO_CMD_SET_INPUT_TIMINGS_PART1, dtd);
}
static bool intel_sdvo_set_output_timing(struct intel_encoder *intel_encoder,
static bool intel_sdvo_set_output_timing(struct intel_sdvo *intel_sdvo,
struct intel_sdvo_dtd *dtd)
{
return intel_sdvo_set_timing(intel_encoder,
return intel_sdvo_set_timing(intel_sdvo,
SDVO_CMD_SET_OUTPUT_TIMINGS_PART1, dtd);
}
static bool
intel_sdvo_create_preferred_input_timing(struct intel_encoder *intel_encoder,
intel_sdvo_create_preferred_input_timing(struct intel_sdvo *intel_sdvo,
uint16_t clock,
uint16_t width,
uint16_t height)
{
struct intel_sdvo_preferred_input_timing_args args;
struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
uint8_t status;
memset(&args, 0, sizeof(args));
......@@ -707,38 +705,38 @@ intel_sdvo_create_preferred_input_timing(struct intel_encoder *intel_encoder,
args.height = height;
args.interlace = 0;
if (sdvo_priv->is_lvds &&
(sdvo_priv->sdvo_lvds_fixed_mode->hdisplay != width ||
sdvo_priv->sdvo_lvds_fixed_mode->vdisplay != height))
if (intel_sdvo->is_lvds &&
(intel_sdvo->sdvo_lvds_fixed_mode->hdisplay != width ||
intel_sdvo->sdvo_lvds_fixed_mode->vdisplay != height))
args.scaled = 1;
intel_sdvo_write_cmd(intel_encoder,
intel_sdvo_write_cmd(intel_sdvo,
SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING,
&args, sizeof(args));
status = intel_sdvo_read_response(intel_encoder, NULL, 0);
status = intel_sdvo_read_response(intel_sdvo, NULL, 0);
if (status != SDVO_CMD_STATUS_SUCCESS)
return false;
return true;
}
static bool intel_sdvo_get_preferred_input_timing(struct intel_encoder *intel_encoder,
static bool intel_sdvo_get_preferred_input_timing(struct intel_sdvo *intel_sdvo,
struct intel_sdvo_dtd *dtd)
{
bool status;
intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1,
intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1,
NULL, 0);
status = intel_sdvo_read_response(intel_encoder, &dtd->part1,
status = intel_sdvo_read_response(intel_sdvo, &dtd->part1,
sizeof(dtd->part1));
if (status != SDVO_CMD_STATUS_SUCCESS)
return false;
intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2,
intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2,
NULL, 0);
status = intel_sdvo_read_response(intel_encoder, &dtd->part2,
status = intel_sdvo_read_response(intel_sdvo, &dtd->part2,
sizeof(dtd->part2));
if (status != SDVO_CMD_STATUS_SUCCESS)
return false;
......@@ -746,12 +744,12 @@ static bool intel_sdvo_get_preferred_input_timing(struct intel_encoder *intel_en
return false;
}
static bool intel_sdvo_set_clock_rate_mult(struct intel_encoder *intel_encoder, u8 val)
static bool intel_sdvo_set_clock_rate_mult(struct intel_sdvo *intel_sdvo, u8 val)
{
u8 status;
intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_CLOCK_RATE_MULT, &val, 1);
status = intel_sdvo_read_response(intel_encoder, NULL, 0);
intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_CLOCK_RATE_MULT, &val, 1);
status = intel_sdvo_read_response(intel_sdvo, NULL, 0);
if (status != SDVO_CMD_STATUS_SUCCESS)
return false;
......@@ -840,13 +838,13 @@ static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode,
mode->flags |= DRM_MODE_FLAG_PVSYNC;
}
static bool intel_sdvo_get_supp_encode(struct intel_encoder *intel_encoder,
static bool intel_sdvo_get_supp_encode(struct intel_sdvo *intel_sdvo,
struct intel_sdvo_encode *encode)
{
uint8_t status;
intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_SUPP_ENCODE, NULL, 0);
status = intel_sdvo_read_response(intel_encoder, encode, sizeof(*encode));
intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_GET_SUPP_ENCODE, NULL, 0);
status = intel_sdvo_read_response(intel_sdvo, encode, sizeof(*encode));
if (status != SDVO_CMD_STATUS_SUCCESS) { /* non-support means DVI */
memset(encode, 0, sizeof(*encode));
return false;
......@@ -855,30 +853,30 @@ static bool intel_sdvo_get_supp_encode(struct intel_encoder *intel_encoder,
return true;
}
static bool intel_sdvo_set_encode(struct intel_encoder *intel_encoder,
static bool intel_sdvo_set_encode(struct intel_sdvo *intel_sdvo,
uint8_t mode)
{
uint8_t status;
intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ENCODE, &mode, 1);
status = intel_sdvo_read_response(intel_encoder, NULL, 0);
intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_ENCODE, &mode, 1);
status = intel_sdvo_read_response(intel_sdvo, NULL, 0);
return (status == SDVO_CMD_STATUS_SUCCESS);
}
static bool intel_sdvo_set_colorimetry(struct intel_encoder *intel_encoder,
static bool intel_sdvo_set_colorimetry(struct intel_sdvo *intel_sdvo,
uint8_t mode)
{
uint8_t status;
intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_COLORIMETRY, &mode, 1);
status = intel_sdvo_read_response(intel_encoder, NULL, 0);
intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_COLORIMETRY, &mode, 1);
status = intel_sdvo_read_response(intel_sdvo, NULL, 0);
return (status == SDVO_CMD_STATUS_SUCCESS);
}
#if 0
static void intel_sdvo_dump_hdmi_buf(struct intel_encoder *intel_encoder)
static void intel_sdvo_dump_hdmi_buf(struct intel_sdvo *intel_sdvo)
{
int i, j;
uint8_t set_buf_index[2];
......@@ -908,7 +906,7 @@ static void intel_sdvo_dump_hdmi_buf(struct intel_encoder *intel_encoder)
}
#endif
static void intel_sdvo_set_hdmi_buf(struct intel_encoder *intel_encoder,
static void intel_sdvo_set_hdmi_buf(struct intel_sdvo *intel_sdvo,
int index,
uint8_t *data, int8_t size, uint8_t tx_rate)
{
......@@ -917,15 +915,15 @@ static void intel_sdvo_set_hdmi_buf(struct intel_encoder *intel_encoder,
set_buf_index[0] = index;
set_buf_index[1] = 0;
intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_HBUF_INDEX,
intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_HBUF_INDEX,
set_buf_index, 2);
for (; size > 0; size -= 8) {
intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_HBUF_DATA, data, 8);
intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_HBUF_DATA, data, 8);
data += 8;
}
intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_HBUF_TXRATE, &tx_rate, 1);
intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_HBUF_TXRATE, &tx_rate, 1);
}
static uint8_t intel_sdvo_calc_hbuf_csum(uint8_t *data, uint8_t size)
......@@ -1000,7 +998,7 @@ struct dip_infoframe {
} __attribute__ ((packed)) u;
} __attribute__((packed));
static void intel_sdvo_set_avi_infoframe(struct intel_encoder *intel_encoder,
static void intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo,
struct drm_display_mode * mode)
{
struct dip_infoframe avi_if = {
......@@ -1011,21 +1009,20 @@ static void intel_sdvo_set_avi_infoframe(struct intel_encoder *intel_encoder,
avi_if.checksum = intel_sdvo_calc_hbuf_csum((uint8_t *)&avi_if,
4 + avi_if.len);
intel_sdvo_set_hdmi_buf(intel_encoder, 1, (uint8_t *)&avi_if,
intel_sdvo_set_hdmi_buf(intel_sdvo, 1, (uint8_t *)&avi_if,
4 + avi_if.len,
SDVO_HBUF_TX_VSYNC);
}
static void intel_sdvo_set_tv_format(struct intel_encoder *intel_encoder)
static void intel_sdvo_set_tv_format(struct intel_sdvo *intel_sdvo)
{
struct intel_sdvo_tv_format format;
struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
uint32_t format_map, i;
uint8_t status;
for (i = 0; i < TV_FORMAT_NUM; i++)
if (tv_format_names[i] == sdvo_priv->tv_format_name)
if (tv_format_names[i] == intel_sdvo->tv_format_name)
break;
format_map = 1 << i;
......@@ -1033,23 +1030,22 @@ static void intel_sdvo_set_tv_format(struct intel_encoder *intel_encoder)
memcpy(&format, &format_map, sizeof(format_map) > sizeof(format) ?
sizeof(format) : sizeof(format_map));
intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_TV_FORMAT, &format,
intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_TV_FORMAT, &format,
sizeof(format));
status = intel_sdvo_read_response(intel_encoder, NULL, 0);
status = intel_sdvo_read_response(intel_sdvo, NULL, 0);
if (status != SDVO_CMD_STATUS_SUCCESS)
DRM_DEBUG_KMS("%s: Failed to set TV format\n",
SDVO_NAME(sdvo_priv));
SDVO_NAME(intel_sdvo));
}
static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
struct intel_sdvo_priv *dev_priv = intel_encoder->dev_priv;
struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder);
if (dev_priv->is_tv) {
if (intel_sdvo->is_tv) {
struct intel_sdvo_dtd output_dtd;
bool success;
......@@ -1062,25 +1058,25 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
/* Set output timings */
intel_sdvo_get_dtd_from_mode(&output_dtd, mode);
intel_sdvo_set_target_output(intel_encoder,
dev_priv->attached_output);
intel_sdvo_set_output_timing(intel_encoder, &output_dtd);
intel_sdvo_set_target_output(intel_sdvo,
intel_sdvo->attached_output);
intel_sdvo_set_output_timing(intel_sdvo, &output_dtd);
/* Set the input timing to the screen. Assume always input 0. */
intel_sdvo_set_target_input(intel_encoder, true, false);
intel_sdvo_set_target_input(intel_sdvo, true, false);
success = intel_sdvo_create_preferred_input_timing(intel_encoder,
success = intel_sdvo_create_preferred_input_timing(intel_sdvo,
mode->clock / 10,
mode->hdisplay,
mode->vdisplay);
if (success) {
struct intel_sdvo_dtd input_dtd;
intel_sdvo_get_preferred_input_timing(intel_encoder,
intel_sdvo_get_preferred_input_timing(intel_sdvo,
&input_dtd);
intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd);
dev_priv->sdvo_flags = input_dtd.part2.sdvo_flags;
intel_sdvo->sdvo_flags = input_dtd.part2.sdvo_flags;
drm_mode_set_crtcinfo(adjusted_mode, 0);
......@@ -1091,25 +1087,25 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
} else {
return false;
}
} else if (dev_priv->is_lvds) {
} else if (intel_sdvo->is_lvds) {
struct intel_sdvo_dtd output_dtd;
bool success;
drm_mode_set_crtcinfo(dev_priv->sdvo_lvds_fixed_mode, 0);
drm_mode_set_crtcinfo(intel_sdvo->sdvo_lvds_fixed_mode, 0);
/* Set output timings */
intel_sdvo_get_dtd_from_mode(&output_dtd,
dev_priv->sdvo_lvds_fixed_mode);
intel_sdvo->sdvo_lvds_fixed_mode);
intel_sdvo_set_target_output(intel_encoder,
dev_priv->attached_output);
intel_sdvo_set_output_timing(intel_encoder, &output_dtd);
intel_sdvo_set_target_output(intel_sdvo,
intel_sdvo->attached_output);
intel_sdvo_set_output_timing(intel_sdvo, &output_dtd);
/* Set the input timing to the screen. Assume always input 0. */
intel_sdvo_set_target_input(intel_encoder, true, false);
intel_sdvo_set_target_input(intel_sdvo, true, false);
success = intel_sdvo_create_preferred_input_timing(
intel_encoder,
intel_sdvo,
mode->clock / 10,
mode->hdisplay,
mode->vdisplay);
......@@ -1117,10 +1113,10 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
if (success) {
struct intel_sdvo_dtd input_dtd;
intel_sdvo_get_preferred_input_timing(intel_encoder,
intel_sdvo_get_preferred_input_timing(intel_sdvo,
&input_dtd);
intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd);
dev_priv->sdvo_flags = input_dtd.part2.sdvo_flags;
intel_sdvo->sdvo_flags = input_dtd.part2.sdvo_flags;
drm_mode_set_crtcinfo(adjusted_mode, 0);
......@@ -1149,8 +1145,7 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_crtc *crtc = encoder->crtc;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder);
u32 sdvox = 0;
int sdvo_pixel_multiply;
struct intel_sdvo_in_out_map in_out;
......@@ -1166,41 +1161,41 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
* channel on the motherboard. In a two-input device, the first input
* will be SDVOB and the second SDVOC.
*/
in_out.in0 = sdvo_priv->attached_output;
in_out.in0 = intel_sdvo->attached_output;
in_out.in1 = 0;
intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_IN_OUT_MAP,
intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_IN_OUT_MAP,
&in_out, sizeof(in_out));
status = intel_sdvo_read_response(intel_encoder, NULL, 0);
status = intel_sdvo_read_response(intel_sdvo, NULL, 0);
if (sdvo_priv->is_hdmi) {
intel_sdvo_set_avi_infoframe(intel_encoder, mode);
if (intel_sdvo->is_hdmi) {
intel_sdvo_set_avi_infoframe(intel_sdvo, mode);
sdvox |= SDVO_AUDIO_ENABLE;
}
/* We have tried to get input timing in mode_fixup, and filled into
adjusted_mode */
if (sdvo_priv->is_tv || sdvo_priv->is_lvds) {
if (intel_sdvo->is_tv || intel_sdvo->is_lvds) {
intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode);
input_dtd.part2.sdvo_flags = sdvo_priv->sdvo_flags;
input_dtd.part2.sdvo_flags = intel_sdvo->sdvo_flags;
} else
intel_sdvo_get_dtd_from_mode(&input_dtd, mode);
/* If it's a TV, we already set the output timing in mode_fixup.
* Otherwise, the output timing is equal to the input timing.
*/
if (!sdvo_priv->is_tv && !sdvo_priv->is_lvds) {
if (!intel_sdvo->is_tv && !intel_sdvo->is_lvds) {
/* Set the output timing to the screen */
intel_sdvo_set_target_output(intel_encoder,
sdvo_priv->attached_output);
intel_sdvo_set_output_timing(intel_encoder, &input_dtd);
intel_sdvo_set_target_output(intel_sdvo,
intel_sdvo->attached_output);
intel_sdvo_set_output_timing(intel_sdvo, &input_dtd);
}
/* Set the input timing to the screen. Assume always input 0. */
intel_sdvo_set_target_input(intel_encoder, true, false);
intel_sdvo_set_target_input(intel_sdvo, true, false);
if (sdvo_priv->is_tv)
intel_sdvo_set_tv_format(intel_encoder);
if (intel_sdvo->is_tv)
intel_sdvo_set_tv_format(intel_sdvo);
/* We would like to use intel_sdvo_create_preferred_input_timing() to
* provide the device with a timing it can support, if it supports that
......@@ -1217,20 +1212,20 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
intel_sdvo_set_input_timing(encoder, &input_dtd);
}
#else
intel_sdvo_set_input_timing(intel_encoder, &input_dtd);
intel_sdvo_set_input_timing(intel_sdvo, &input_dtd);
#endif
switch (intel_sdvo_get_pixel_multiplier(mode)) {
case 1:
intel_sdvo_set_clock_rate_mult(intel_encoder,
intel_sdvo_set_clock_rate_mult(intel_sdvo,
SDVO_CLOCK_RATE_MULT_1X);
break;
case 2:
intel_sdvo_set_clock_rate_mult(intel_encoder,
intel_sdvo_set_clock_rate_mult(intel_sdvo,
SDVO_CLOCK_RATE_MULT_2X);
break;
case 4:
intel_sdvo_set_clock_rate_mult(intel_encoder,
intel_sdvo_set_clock_rate_mult(intel_sdvo,
SDVO_CLOCK_RATE_MULT_4X);
break;
}
......@@ -1243,8 +1238,8 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
sdvox |= SDVO_HSYNC_ACTIVE_HIGH;
} else {
sdvox |= I915_READ(sdvo_priv->sdvo_reg);
switch (sdvo_priv->sdvo_reg) {
sdvox |= I915_READ(intel_sdvo->sdvo_reg);
switch (intel_sdvo->sdvo_reg) {
case SDVOB:
sdvox &= SDVOB_PRESERVE_MASK;
break;
......@@ -1266,28 +1261,27 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
sdvox |= (sdvo_pixel_multiply - 1) << SDVO_PORT_MULTIPLY_SHIFT;
}
if (sdvo_priv->sdvo_flags & SDVO_NEED_TO_STALL)
if (intel_sdvo->sdvo_flags & SDVO_NEED_TO_STALL)
sdvox |= SDVO_STALL_SELECT;
intel_sdvo_write_sdvox(intel_encoder, sdvox);
intel_sdvo_write_sdvox(intel_sdvo, sdvox);
}
static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode)
{
struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder);
u32 temp;
if (mode != DRM_MODE_DPMS_ON) {
intel_sdvo_set_active_outputs(intel_encoder, 0);
intel_sdvo_set_active_outputs(intel_sdvo, 0);
if (0)
intel_sdvo_set_encoder_power_state(intel_encoder, mode);
intel_sdvo_set_encoder_power_state(intel_sdvo, mode);
if (mode == DRM_MODE_DPMS_OFF) {
temp = I915_READ(sdvo_priv->sdvo_reg);
temp = I915_READ(intel_sdvo->sdvo_reg);
if ((temp & SDVO_ENABLE) != 0) {
intel_sdvo_write_sdvox(intel_encoder, temp & ~SDVO_ENABLE);
intel_sdvo_write_sdvox(intel_sdvo, temp & ~SDVO_ENABLE);
}
}
} else {
......@@ -1295,13 +1289,13 @@ static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode)
int i;
u8 status;
temp = I915_READ(sdvo_priv->sdvo_reg);
temp = I915_READ(intel_sdvo->sdvo_reg);
if ((temp & SDVO_ENABLE) == 0)
intel_sdvo_write_sdvox(intel_encoder, temp | SDVO_ENABLE);
intel_sdvo_write_sdvox(intel_sdvo, temp | SDVO_ENABLE);
for (i = 0; i < 2; i++)
intel_wait_for_vblank(dev);
status = intel_sdvo_get_trained_inputs(intel_encoder, &input1,
status = intel_sdvo_get_trained_inputs(intel_sdvo, &input1,
&input2);
......@@ -1311,12 +1305,12 @@ static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode)
*/
if (status == SDVO_CMD_STATUS_SUCCESS && !input1) {
DRM_DEBUG_KMS("First %s output reported failure to "
"sync\n", SDVO_NAME(sdvo_priv));
"sync\n", SDVO_NAME(intel_sdvo));
}
if (0)
intel_sdvo_set_encoder_power_state(intel_encoder, mode);
intel_sdvo_set_active_outputs(intel_encoder, sdvo_priv->attached_output);
intel_sdvo_set_encoder_power_state(intel_sdvo, mode);
intel_sdvo_set_active_outputs(intel_sdvo, intel_sdvo->attached_output);
}
return;
}
......@@ -1325,38 +1319,37 @@ static int intel_sdvo_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
struct drm_encoder *encoder = intel_attached_encoder(connector);
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder);
if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
return MODE_NO_DBLESCAN;
if (sdvo_priv->pixel_clock_min > mode->clock)
if (intel_sdvo->pixel_clock_min > mode->clock)
return MODE_CLOCK_LOW;
if (sdvo_priv->pixel_clock_max < mode->clock)
if (intel_sdvo->pixel_clock_max < mode->clock)
return MODE_CLOCK_HIGH;
if (sdvo_priv->is_lvds == true) {
if (sdvo_priv->sdvo_lvds_fixed_mode == NULL)
if (intel_sdvo->is_lvds == true) {
if (intel_sdvo->sdvo_lvds_fixed_mode == NULL)
return MODE_PANEL;
if (mode->hdisplay > sdvo_priv->sdvo_lvds_fixed_mode->hdisplay)
if (mode->hdisplay > intel_sdvo->sdvo_lvds_fixed_mode->hdisplay)
return MODE_PANEL;
if (mode->vdisplay > sdvo_priv->sdvo_lvds_fixed_mode->vdisplay)
if (mode->vdisplay > intel_sdvo->sdvo_lvds_fixed_mode->vdisplay)
return MODE_PANEL;
}
return MODE_OK;
}
static bool intel_sdvo_get_capabilities(struct intel_encoder *intel_encoder, struct intel_sdvo_caps *caps)
static bool intel_sdvo_get_capabilities(struct intel_sdvo *intel_sdvo, struct intel_sdvo_caps *caps)
{
u8 status;
intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_DEVICE_CAPS, NULL, 0);
status = intel_sdvo_read_response(intel_encoder, caps, sizeof(*caps));
intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_GET_DEVICE_CAPS, NULL, 0);
status = intel_sdvo_read_response(intel_sdvo, caps, sizeof(*caps));
if (status != SDVO_CMD_STATUS_SUCCESS)
return false;
......@@ -1368,12 +1361,12 @@ static bool intel_sdvo_get_capabilities(struct intel_encoder *intel_encoder, str
struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB)
{
struct drm_connector *connector = NULL;
struct intel_encoder *iout = NULL;
struct intel_sdvo_priv *sdvo;
struct intel_sdvo *iout = NULL;
struct intel_sdvo *sdvo;
/* find the sdvo connector */
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
iout = to_intel_encoder(connector);
iout = to_intel_sdvo(connector);
if (iout->type != INTEL_OUTPUT_SDVO)
continue;
......@@ -1395,16 +1388,16 @@ int intel_sdvo_supports_hotplug(struct drm_connector *connector)
{
u8 response[2];
u8 status;
struct intel_encoder *intel_encoder;
struct intel_sdvo *intel_sdvo;
DRM_DEBUG_KMS("\n");
if (!connector)
return 0;
intel_encoder = to_intel_encoder(connector);
intel_sdvo = to_intel_sdvo(connector);
intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0);
status = intel_sdvo_read_response(intel_encoder, &response, 2);
intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0);
status = intel_sdvo_read_response(intel_sdvo, &response, 2);
if (response[0] !=0)
return 1;
......@@ -1416,54 +1409,53 @@ void intel_sdvo_set_hotplug(struct drm_connector *connector, int on)
{
u8 response[2];
u8 status;
struct intel_encoder *intel_encoder = to_intel_encoder(connector);
struct intel_sdvo *intel_sdvo = to_intel_sdvo(connector);
intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0);
intel_sdvo_read_response(intel_encoder, &response, 2);
intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0);
intel_sdvo_read_response(intel_sdvo, &response, 2);
if (on) {
intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0);
status = intel_sdvo_read_response(intel_encoder, &response, 2);
intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0);
status = intel_sdvo_read_response(intel_sdvo, &response, 2);
intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2);
intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2);
} else {
response[0] = 0;
response[1] = 0;
intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2);
intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2);
}
intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0);
intel_sdvo_read_response(intel_encoder, &response, 2);
intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0);
intel_sdvo_read_response(intel_sdvo, &response, 2);
}
#endif
static bool
intel_sdvo_multifunc_encoder(struct intel_encoder *intel_encoder)
intel_sdvo_multifunc_encoder(struct intel_sdvo *intel_sdvo)
{
struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
int caps = 0;
if (sdvo_priv->caps.output_flags &
if (intel_sdvo->caps.output_flags &
(SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1))
caps++;
if (sdvo_priv->caps.output_flags &
if (intel_sdvo->caps.output_flags &
(SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1))
caps++;
if (sdvo_priv->caps.output_flags &
if (intel_sdvo->caps.output_flags &
(SDVO_OUTPUT_SVID0 | SDVO_OUTPUT_SVID1))
caps++;
if (sdvo_priv->caps.output_flags &
if (intel_sdvo->caps.output_flags &
(SDVO_OUTPUT_CVBS0 | SDVO_OUTPUT_CVBS1))
caps++;
if (sdvo_priv->caps.output_flags &
if (intel_sdvo->caps.output_flags &
(SDVO_OUTPUT_YPRPB0 | SDVO_OUTPUT_YPRPB1))
caps++;
if (sdvo_priv->caps.output_flags &
if (intel_sdvo->caps.output_flags &
(SDVO_OUTPUT_SCART0 | SDVO_OUTPUT_SCART1))
caps++;
if (sdvo_priv->caps.output_flags &
if (intel_sdvo->caps.output_flags &
(SDVO_OUTPUT_LVDS0 | SDVO_OUTPUT_LVDS1))
caps++;
......@@ -1475,11 +1467,11 @@ intel_find_analog_connector(struct drm_device *dev)
{
struct drm_connector *connector;
struct drm_encoder *encoder;
struct intel_encoder *intel_encoder;
struct intel_sdvo *intel_sdvo;
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
intel_encoder = enc_to_intel_encoder(encoder);
if (intel_encoder->type == INTEL_OUTPUT_ANALOG) {
intel_sdvo = enc_to_intel_sdvo(encoder);
if (intel_sdvo->base.type == INTEL_OUTPUT_ANALOG) {
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
if (encoder == intel_attached_encoder(connector))
return connector;
......@@ -1509,46 +1501,45 @@ enum drm_connector_status
intel_sdvo_hdmi_sink_detect(struct drm_connector *connector)
{
struct drm_encoder *encoder = intel_attached_encoder(connector);
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder);
struct intel_connector *intel_connector = to_intel_connector(connector);
struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv;
enum drm_connector_status status = connector_status_connected;
struct edid *edid = NULL;
edid = drm_get_edid(connector, intel_encoder->ddc_bus);
edid = drm_get_edid(connector, intel_sdvo->base.ddc_bus);
/* This is only applied to SDVO cards with multiple outputs */
if (edid == NULL && intel_sdvo_multifunc_encoder(intel_encoder)) {
if (edid == NULL && intel_sdvo_multifunc_encoder(intel_sdvo)) {
uint8_t saved_ddc, temp_ddc;
saved_ddc = sdvo_priv->ddc_bus;
temp_ddc = sdvo_priv->ddc_bus >> 1;
saved_ddc = intel_sdvo->ddc_bus;
temp_ddc = intel_sdvo->ddc_bus >> 1;
/*
* Don't use the 1 as the argument of DDC bus switch to get
* the EDID. It is used for SDVO SPD ROM.
*/
while(temp_ddc > 1) {
sdvo_priv->ddc_bus = temp_ddc;
edid = drm_get_edid(connector, intel_encoder->ddc_bus);
intel_sdvo->ddc_bus = temp_ddc;
edid = drm_get_edid(connector, intel_sdvo->base.ddc_bus);
if (edid) {
/*
* When we can get the EDID, maybe it is the
* correct DDC bus. Update it.
*/
sdvo_priv->ddc_bus = temp_ddc;
intel_sdvo->ddc_bus = temp_ddc;
break;
}
temp_ddc >>= 1;
}
if (edid == NULL)
sdvo_priv->ddc_bus = saved_ddc;
intel_sdvo->ddc_bus = saved_ddc;
}
/* when there is no edid and no monitor is connected with VGA
* port, try to use the CRT ddc to read the EDID for DVI-connector
*/
if (edid == NULL && sdvo_priv->analog_ddc_bus &&
if (edid == NULL && intel_sdvo->analog_ddc_bus &&
!intel_analog_is_connected(connector->dev))
edid = drm_get_edid(connector, sdvo_priv->analog_ddc_bus);
edid = drm_get_edid(connector, intel_sdvo->analog_ddc_bus);
if (edid != NULL) {
bool is_digital = !!(edid->input & DRM_EDID_INPUT_DIGITAL);
......@@ -1556,7 +1547,7 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector)
/* DDC bus is shared, match EDID to connector type */
if (is_digital && need_digital)
sdvo_priv->is_hdmi = drm_detect_hdmi_monitor(edid);
intel_sdvo->is_hdmi = drm_detect_hdmi_monitor(edid);
else if (is_digital != need_digital)
status = connector_status_disconnected;
......@@ -1574,19 +1565,18 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect
uint16_t response;
u8 status;
struct drm_encoder *encoder = intel_attached_encoder(connector);
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder);
struct intel_connector *intel_connector = to_intel_connector(connector);
struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv;
enum drm_connector_status ret;
intel_sdvo_write_cmd(intel_encoder,
intel_sdvo_write_cmd(intel_sdvo,
SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0);
if (sdvo_priv->is_tv) {
if (intel_sdvo->is_tv) {
/* add 30ms delay when the output type is SDVO-TV */
mdelay(30);
}
status = intel_sdvo_read_response(intel_encoder, &response, 2);
status = intel_sdvo_read_response(intel_sdvo, &response, 2);
DRM_DEBUG_KMS("SDVO response %d %d\n", response & 0xff, response >> 8);
......@@ -1596,7 +1586,7 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect
if (response == 0)
return connector_status_disconnected;
sdvo_priv->attached_output = response;
intel_sdvo->attached_output = response;
if ((sdvo_connector->output_flag & response) == 0)
ret = connector_status_disconnected;
......@@ -1607,16 +1597,16 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect
/* May update encoder flag for like clock for SDVO TV, etc.*/
if (ret == connector_status_connected) {
sdvo_priv->is_tv = false;
sdvo_priv->is_lvds = false;
intel_encoder->needs_tv_clock = false;
intel_sdvo->is_tv = false;
intel_sdvo->is_lvds = false;
intel_sdvo->base.needs_tv_clock = false;
if (response & SDVO_TV_MASK) {
sdvo_priv->is_tv = true;
intel_encoder->needs_tv_clock = true;
intel_sdvo->is_tv = true;
intel_sdvo->base.needs_tv_clock = true;
}
if (response & SDVO_LVDS_MASK)
sdvo_priv->is_lvds = true;
intel_sdvo->is_lvds = true;
}
return ret;
......@@ -1625,12 +1615,11 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect
static void intel_sdvo_get_ddc_modes(struct drm_connector *connector)
{
struct drm_encoder *encoder = intel_attached_encoder(connector);
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder);
int num_modes;
/* set the bus switch and get the modes */
num_modes = intel_ddc_get_modes(connector, intel_encoder->ddc_bus);
num_modes = intel_ddc_get_modes(connector, intel_sdvo->base.ddc_bus);
/*
* Mac mini hack. On this device, the DVI-I connector shares one DDC
......@@ -1639,11 +1628,11 @@ static void intel_sdvo_get_ddc_modes(struct drm_connector *connector)
* which case we'll look there for the digital DDC data.
*/
if (num_modes == 0 &&
sdvo_priv->analog_ddc_bus &&
intel_sdvo->analog_ddc_bus &&
!intel_analog_is_connected(connector->dev)) {
/* Switch to the analog ddc bus and try that
*/
(void) intel_ddc_get_modes(connector, sdvo_priv->analog_ddc_bus);
(void) intel_ddc_get_modes(connector, intel_sdvo->analog_ddc_bus);
}
}
......@@ -1715,8 +1704,7 @@ struct drm_display_mode sdvo_tv_modes[] = {
static void intel_sdvo_get_tv_modes(struct drm_connector *connector)
{
struct drm_encoder *encoder = intel_attached_encoder(connector);
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder);
struct intel_sdvo_sdtv_resolution_request tv_res;
uint32_t reply = 0, format_map = 0;
int i;
......@@ -1727,7 +1715,7 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector)
* format.
*/
for (i = 0; i < TV_FORMAT_NUM; i++)
if (tv_format_names[i] == sdvo_priv->tv_format_name)
if (tv_format_names[i] == intel_sdvo->tv_format_name)
break;
format_map = (1 << i);
......@@ -1736,11 +1724,11 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector)
sizeof(format_map) ? sizeof(format_map) :
sizeof(struct intel_sdvo_sdtv_resolution_request));
intel_sdvo_set_target_output(intel_encoder, sdvo_priv->attached_output);
intel_sdvo_set_target_output(intel_sdvo, intel_sdvo->attached_output);
intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT,
intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT,
&tv_res, sizeof(tv_res));
status = intel_sdvo_read_response(intel_encoder, &reply, 3);
status = intel_sdvo_read_response(intel_sdvo, &reply, 3);
if (status != SDVO_CMD_STATUS_SUCCESS)
return;
......@@ -1758,9 +1746,8 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector)
static void intel_sdvo_get_lvds_modes(struct drm_connector *connector)
{
struct drm_encoder *encoder = intel_attached_encoder(connector);
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder);
struct drm_i915_private *dev_priv = connector->dev->dev_private;
struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
struct drm_display_mode *newmode;
/*
......@@ -1768,7 +1755,7 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector)
* Assume that the preferred modes are
* arranged in priority order.
*/
intel_ddc_get_modes(connector, intel_encoder->ddc_bus);
intel_ddc_get_modes(connector, intel_sdvo->base.ddc_bus);
if (list_empty(&connector->probed_modes) == false)
goto end;
......@@ -1787,7 +1774,7 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector)
end:
list_for_each_entry(newmode, &connector->probed_modes, head) {
if (newmode->type & DRM_MODE_TYPE_PREFERRED) {
sdvo_priv->sdvo_lvds_fixed_mode =
intel_sdvo->sdvo_lvds_fixed_mode =
drm_mode_duplicate(connector->dev, newmode);
break;
}
......@@ -1816,35 +1803,35 @@ static
void intel_sdvo_destroy_enhance_property(struct drm_connector *connector)
{
struct intel_connector *intel_connector = to_intel_connector(connector);
struct intel_sdvo_connector *sdvo_priv = intel_connector->dev_priv;
struct intel_sdvo_connector *intel_sdvo = intel_connector->dev_priv;
struct drm_device *dev = connector->dev;
if (IS_TV(sdvo_priv)) {
if (sdvo_priv->left_property)
drm_property_destroy(dev, sdvo_priv->left_property);
if (sdvo_priv->right_property)
drm_property_destroy(dev, sdvo_priv->right_property);
if (sdvo_priv->top_property)
drm_property_destroy(dev, sdvo_priv->top_property);
if (sdvo_priv->bottom_property)
drm_property_destroy(dev, sdvo_priv->bottom_property);
if (sdvo_priv->hpos_property)
drm_property_destroy(dev, sdvo_priv->hpos_property);
if (sdvo_priv->vpos_property)
drm_property_destroy(dev, sdvo_priv->vpos_property);
if (sdvo_priv->saturation_property)
if (IS_TV(intel_sdvo)) {
if (intel_sdvo->left_property)
drm_property_destroy(dev, intel_sdvo->left_property);
if (intel_sdvo->right_property)
drm_property_destroy(dev, intel_sdvo->right_property);
if (intel_sdvo->top_property)
drm_property_destroy(dev, intel_sdvo->top_property);
if (intel_sdvo->bottom_property)
drm_property_destroy(dev, intel_sdvo->bottom_property);
if (intel_sdvo->hpos_property)
drm_property_destroy(dev, intel_sdvo->hpos_property);
if (intel_sdvo->vpos_property)
drm_property_destroy(dev, intel_sdvo->vpos_property);
if (intel_sdvo->saturation_property)
drm_property_destroy(dev,
sdvo_priv->saturation_property);
if (sdvo_priv->contrast_property)
intel_sdvo->saturation_property);
if (intel_sdvo->contrast_property)
drm_property_destroy(dev,
sdvo_priv->contrast_property);
if (sdvo_priv->hue_property)
drm_property_destroy(dev, sdvo_priv->hue_property);
intel_sdvo->contrast_property);
if (intel_sdvo->hue_property)
drm_property_destroy(dev, intel_sdvo->hue_property);
}
if (IS_TV(sdvo_priv) || IS_LVDS(sdvo_priv)) {
if (sdvo_priv->brightness_property)
if (IS_TV(intel_sdvo) || IS_LVDS(intel_sdvo)) {
if (intel_sdvo->brightness_property)
drm_property_destroy(dev,
sdvo_priv->brightness_property);
intel_sdvo->brightness_property);
}
return;
}
......@@ -1870,8 +1857,7 @@ intel_sdvo_set_property(struct drm_connector *connector,
uint64_t val)
{
struct drm_encoder *encoder = intel_attached_encoder(connector);
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder);
struct intel_connector *intel_connector = to_intel_connector(connector);
struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv;
struct drm_crtc *crtc = encoder->crtc;
......@@ -1889,11 +1875,11 @@ intel_sdvo_set_property(struct drm_connector *connector,
ret = -EINVAL;
goto out;
}
if (sdvo_priv->tv_format_name ==
if (intel_sdvo->tv_format_name ==
sdvo_connector->tv_format_supported[val])
goto out;
sdvo_priv->tv_format_name = sdvo_connector->tv_format_supported[val];
intel_sdvo->tv_format_name = sdvo_connector->tv_format_supported[val];
changed = true;
}
......@@ -1981,8 +1967,8 @@ intel_sdvo_set_property(struct drm_connector *connector,
sdvo_connector->cur_brightness = temp_value;
}
if (cmd) {
intel_sdvo_write_cmd(intel_encoder, cmd, &temp_value, 2);
status = intel_sdvo_read_response(intel_encoder,
intel_sdvo_write_cmd(intel_sdvo, cmd, &temp_value, 2);
status = intel_sdvo_read_response(intel_sdvo,
NULL, 0);
if (status != SDVO_CMD_STATUS_SUCCESS) {
DRM_DEBUG_KMS("Incorrect SDVO command \n");
......@@ -2022,22 +2008,16 @@ static const struct drm_connector_helper_funcs intel_sdvo_connector_helper_funcs
static void intel_sdvo_enc_destroy(struct drm_encoder *encoder)
{
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder);
if (intel_encoder->i2c_bus)
intel_i2c_destroy(intel_encoder->i2c_bus);
if (intel_encoder->ddc_bus)
intel_i2c_destroy(intel_encoder->ddc_bus);
if (sdvo_priv->analog_ddc_bus)
intel_i2c_destroy(sdvo_priv->analog_ddc_bus);
if (intel_sdvo->analog_ddc_bus)
intel_i2c_destroy(intel_sdvo->analog_ddc_bus);
if (sdvo_priv->sdvo_lvds_fixed_mode != NULL)
if (intel_sdvo->sdvo_lvds_fixed_mode != NULL)
drm_mode_destroy(encoder->dev,
sdvo_priv->sdvo_lvds_fixed_mode);
intel_sdvo->sdvo_lvds_fixed_mode);
drm_encoder_cleanup(encoder);
kfree(intel_encoder);
intel_encoder_destroy(encoder);
}
static const struct drm_encoder_funcs intel_sdvo_enc_funcs = {
......@@ -2054,7 +2034,7 @@ static const struct drm_encoder_funcs intel_sdvo_enc_funcs = {
*/
static void
intel_sdvo_select_ddc_bus(struct drm_i915_private *dev_priv,
struct intel_sdvo_priv *sdvo, u32 reg)
struct intel_sdvo *sdvo, u32 reg)
{
struct sdvo_device_mapping *mapping;
......@@ -2067,57 +2047,54 @@ intel_sdvo_select_ddc_bus(struct drm_i915_private *dev_priv,
}
static bool
intel_sdvo_get_digital_encoding_mode(struct intel_encoder *output, int device)
intel_sdvo_get_digital_encoding_mode(struct intel_sdvo *intel_sdvo, int device)
{
struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
uint8_t status;
if (device == 0)
intel_sdvo_set_target_output(output, SDVO_OUTPUT_TMDS0);
intel_sdvo_set_target_output(intel_sdvo, SDVO_OUTPUT_TMDS0);
else
intel_sdvo_set_target_output(output, SDVO_OUTPUT_TMDS1);
intel_sdvo_set_target_output(intel_sdvo, SDVO_OUTPUT_TMDS1);
intel_sdvo_write_cmd(output, SDVO_CMD_GET_ENCODE, NULL, 0);
status = intel_sdvo_read_response(output, &sdvo_priv->is_hdmi, 1);
intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_GET_ENCODE, NULL, 0);
status = intel_sdvo_read_response(intel_sdvo, &intel_sdvo->is_hdmi, 1);
if (status != SDVO_CMD_STATUS_SUCCESS)
return false;
return true;
}
static struct intel_encoder *
intel_sdvo_chan_to_intel_encoder(struct intel_i2c_chan *chan)
static struct intel_sdvo *
intel_sdvo_chan_to_intel_sdvo(struct intel_i2c_chan *chan)
{
struct drm_device *dev = chan->drm_dev;
struct drm_encoder *encoder;
struct intel_encoder *intel_encoder = NULL;
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
intel_encoder = enc_to_intel_encoder(encoder);
if (intel_encoder->ddc_bus == &chan->adapter)
break;
struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder);
if (intel_sdvo->base.ddc_bus == &chan->adapter)
return intel_sdvo;
}
return intel_encoder;
return NULL;;
}
static int intel_sdvo_master_xfer(struct i2c_adapter *i2c_adap,
struct i2c_msg msgs[], int num)
{
struct intel_encoder *intel_encoder;
struct intel_sdvo_priv *sdvo_priv;
struct intel_sdvo *intel_sdvo;
struct i2c_algo_bit_data *algo_data;
const struct i2c_algorithm *algo;
algo_data = (struct i2c_algo_bit_data *)i2c_adap->algo_data;
intel_encoder =
intel_sdvo_chan_to_intel_encoder(
(struct intel_i2c_chan *)(algo_data->data));
if (intel_encoder == NULL)
intel_sdvo =
intel_sdvo_chan_to_intel_sdvo((struct intel_i2c_chan *)
(algo_data->data));
if (intel_sdvo == NULL)
return -EINVAL;
sdvo_priv = intel_encoder->dev_priv;
algo = intel_encoder->i2c_bus->algo;
algo = intel_sdvo->base.i2c_bus->algo;
intel_sdvo_set_control_bus_switch(intel_encoder, sdvo_priv->ddc_bus);
intel_sdvo_set_control_bus_switch(intel_sdvo, intel_sdvo->ddc_bus);
return algo->master_xfer(i2c_adap, msgs, num);
}
......@@ -2198,10 +2175,9 @@ intel_sdvo_connector_create (struct drm_encoder *encoder,
}
static bool
intel_sdvo_dvi_init(struct intel_encoder *intel_encoder, int device)
intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
{
struct drm_encoder *encoder = &intel_encoder->enc;
struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
struct drm_encoder *encoder = &intel_sdvo->base.enc;
struct drm_connector *connector;
struct intel_connector *intel_connector;
struct intel_sdvo_connector *sdvo_connector;
......@@ -2212,10 +2188,10 @@ intel_sdvo_dvi_init(struct intel_encoder *intel_encoder, int device)
sdvo_connector = intel_connector->dev_priv;
if (device == 0) {
sdvo_priv->controlled_output |= SDVO_OUTPUT_TMDS0;
intel_sdvo->controlled_output |= SDVO_OUTPUT_TMDS0;
sdvo_connector->output_flag = SDVO_OUTPUT_TMDS0;
} else if (device == 1) {
sdvo_priv->controlled_output |= SDVO_OUTPUT_TMDS1;
intel_sdvo->controlled_output |= SDVO_OUTPUT_TMDS1;
sdvo_connector->output_flag = SDVO_OUTPUT_TMDS1;
}
......@@ -2224,17 +2200,17 @@ intel_sdvo_dvi_init(struct intel_encoder *intel_encoder, int device)
encoder->encoder_type = DRM_MODE_ENCODER_TMDS;
connector->connector_type = DRM_MODE_CONNECTOR_DVID;
if (intel_sdvo_get_supp_encode(intel_encoder, &sdvo_priv->encode)
&& intel_sdvo_get_digital_encoding_mode(intel_encoder, device)
&& sdvo_priv->is_hdmi) {
if (intel_sdvo_get_supp_encode(intel_sdvo, &intel_sdvo->encode)
&& intel_sdvo_get_digital_encoding_mode(intel_sdvo, device)
&& intel_sdvo->is_hdmi) {
/* enable hdmi encoding mode if supported */
intel_sdvo_set_encode(intel_encoder, SDVO_ENCODE_HDMI);
intel_sdvo_set_colorimetry(intel_encoder,
intel_sdvo_set_encode(intel_sdvo, SDVO_ENCODE_HDMI);
intel_sdvo_set_colorimetry(intel_sdvo,
SDVO_COLORIMETRY_RGB256);
connector->connector_type = DRM_MODE_CONNECTOR_HDMIA;
}
intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
(1 << INTEL_ANALOG_CLONE_BIT);
intel_sdvo->base.clone_mask = ((1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
(1 << INTEL_ANALOG_CLONE_BIT));
intel_sdvo_connector_create(encoder, connector);
......@@ -2242,10 +2218,9 @@ intel_sdvo_dvi_init(struct intel_encoder *intel_encoder, int device)
}
static bool
intel_sdvo_tv_init(struct intel_encoder *intel_encoder, int type)
intel_sdvo_tv_init(struct intel_sdvo *intel_sdvo, int type)
{
struct drm_encoder *encoder = &intel_encoder->enc;
struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
struct drm_encoder *encoder = &intel_sdvo->base.enc;
struct drm_connector *connector;
struct intel_connector *intel_connector;
struct intel_sdvo_connector *sdvo_connector;
......@@ -2258,12 +2233,12 @@ intel_sdvo_tv_init(struct intel_encoder *intel_encoder, int type)
connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO;
sdvo_connector = intel_connector->dev_priv;
sdvo_priv->controlled_output |= type;
intel_sdvo->controlled_output |= type;
sdvo_connector->output_flag = type;
sdvo_priv->is_tv = true;
intel_encoder->needs_tv_clock = true;
intel_encoder->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT;
intel_sdvo->is_tv = true;
intel_sdvo->base.needs_tv_clock = true;
intel_sdvo->base.clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT;
intel_sdvo_connector_create(encoder, connector);
......@@ -2275,10 +2250,9 @@ intel_sdvo_tv_init(struct intel_encoder *intel_encoder, int type)
}
static bool
intel_sdvo_analog_init(struct intel_encoder *intel_encoder, int device)
intel_sdvo_analog_init(struct intel_sdvo *intel_sdvo, int device)
{
struct drm_encoder *encoder = &intel_encoder->enc;
struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
struct drm_encoder *encoder = &intel_sdvo->base.enc;
struct drm_connector *connector;
struct intel_connector *intel_connector;
struct intel_sdvo_connector *sdvo_connector;
......@@ -2293,25 +2267,24 @@ intel_sdvo_analog_init(struct intel_encoder *intel_encoder, int device)
sdvo_connector = intel_connector->dev_priv;
if (device == 0) {
sdvo_priv->controlled_output |= SDVO_OUTPUT_RGB0;
intel_sdvo->controlled_output |= SDVO_OUTPUT_RGB0;
sdvo_connector->output_flag = SDVO_OUTPUT_RGB0;
} else if (device == 1) {
sdvo_priv->controlled_output |= SDVO_OUTPUT_RGB1;
intel_sdvo->controlled_output |= SDVO_OUTPUT_RGB1;
sdvo_connector->output_flag = SDVO_OUTPUT_RGB1;
}
intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
(1 << INTEL_ANALOG_CLONE_BIT);
intel_sdvo->base.clone_mask = ((1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
(1 << INTEL_ANALOG_CLONE_BIT));
intel_sdvo_connector_create(encoder, connector);
return true;
}
static bool
intel_sdvo_lvds_init(struct intel_encoder *intel_encoder, int device)
intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device)
{
struct drm_encoder *encoder = &intel_encoder->enc;
struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
struct drm_encoder *encoder = &intel_sdvo->base.enc;
struct drm_connector *connector;
struct intel_connector *intel_connector;
struct intel_sdvo_connector *sdvo_connector;
......@@ -2324,18 +2297,18 @@ intel_sdvo_lvds_init(struct intel_encoder *intel_encoder, int device)
connector->connector_type = DRM_MODE_CONNECTOR_LVDS;
sdvo_connector = intel_connector->dev_priv;
sdvo_priv->is_lvds = true;
intel_sdvo->is_lvds = true;
if (device == 0) {
sdvo_priv->controlled_output |= SDVO_OUTPUT_LVDS0;
intel_sdvo->controlled_output |= SDVO_OUTPUT_LVDS0;
sdvo_connector->output_flag = SDVO_OUTPUT_LVDS0;
} else if (device == 1) {
sdvo_priv->controlled_output |= SDVO_OUTPUT_LVDS1;
intel_sdvo->controlled_output |= SDVO_OUTPUT_LVDS1;
sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1;
}
intel_encoder->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) |
(1 << INTEL_SDVO_LVDS_CLONE_BIT);
intel_sdvo->base.clone_mask = ((1 << INTEL_ANALOG_CLONE_BIT) |
(1 << INTEL_SDVO_LVDS_CLONE_BIT));
intel_sdvo_connector_create(encoder, connector);
intel_sdvo_create_enhance_property(connector);
......@@ -2343,60 +2316,58 @@ intel_sdvo_lvds_init(struct intel_encoder *intel_encoder, int device)
}
static bool
intel_sdvo_output_setup(struct intel_encoder *intel_encoder, uint16_t flags)
intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, uint16_t flags)
{
struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
sdvo_priv->is_tv = false;
intel_encoder->needs_tv_clock = false;
sdvo_priv->is_lvds = false;
intel_sdvo->is_tv = false;
intel_sdvo->base.needs_tv_clock = false;
intel_sdvo->is_lvds = false;
/* SDVO requires XXX1 function may not exist unless it has XXX0 function.*/
if (flags & SDVO_OUTPUT_TMDS0)
if (!intel_sdvo_dvi_init(intel_encoder, 0))
if (!intel_sdvo_dvi_init(intel_sdvo, 0))
return false;
if ((flags & SDVO_TMDS_MASK) == SDVO_TMDS_MASK)
if (!intel_sdvo_dvi_init(intel_encoder, 1))
if (!intel_sdvo_dvi_init(intel_sdvo, 1))
return false;
/* TV has no XXX1 function block */
if (flags & SDVO_OUTPUT_SVID0)
if (!intel_sdvo_tv_init(intel_encoder, SDVO_OUTPUT_SVID0))
if (!intel_sdvo_tv_init(intel_sdvo, SDVO_OUTPUT_SVID0))
return false;
if (flags & SDVO_OUTPUT_CVBS0)
if (!intel_sdvo_tv_init(intel_encoder, SDVO_OUTPUT_CVBS0))
if (!intel_sdvo_tv_init(intel_sdvo, SDVO_OUTPUT_CVBS0))
return false;
if (flags & SDVO_OUTPUT_RGB0)
if (!intel_sdvo_analog_init(intel_encoder, 0))
if (!intel_sdvo_analog_init(intel_sdvo, 0))
return false;
if ((flags & SDVO_RGB_MASK) == SDVO_RGB_MASK)
if (!intel_sdvo_analog_init(intel_encoder, 1))
if (!intel_sdvo_analog_init(intel_sdvo, 1))
return false;
if (flags & SDVO_OUTPUT_LVDS0)
if (!intel_sdvo_lvds_init(intel_encoder, 0))
if (!intel_sdvo_lvds_init(intel_sdvo, 0))
return false;
if ((flags & SDVO_LVDS_MASK) == SDVO_LVDS_MASK)
if (!intel_sdvo_lvds_init(intel_encoder, 1))
if (!intel_sdvo_lvds_init(intel_sdvo, 1))
return false;
if ((flags & SDVO_OUTPUT_MASK) == 0) {
unsigned char bytes[2];
sdvo_priv->controlled_output = 0;
memcpy(bytes, &sdvo_priv->caps.output_flags, 2);
intel_sdvo->controlled_output = 0;
memcpy(bytes, &intel_sdvo->caps.output_flags, 2);
DRM_DEBUG_KMS("%s: Unknown SDVO output type (0x%02x%02x)\n",
SDVO_NAME(sdvo_priv),
SDVO_NAME(intel_sdvo),
bytes[0], bytes[1]);
return false;
}
intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
intel_sdvo->base.crtc_mask = (1 << 0) | (1 << 1);
return true;
}
......@@ -2404,19 +2375,18 @@ intel_sdvo_output_setup(struct intel_encoder *intel_encoder, uint16_t flags)
static void intel_sdvo_tv_create_property(struct drm_connector *connector, int type)
{
struct drm_encoder *encoder = intel_attached_encoder(connector);
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder);
struct intel_connector *intel_connector = to_intel_connector(connector);
struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv;
struct intel_sdvo_tv_format format;
uint32_t format_map, i;
uint8_t status;
intel_sdvo_set_target_output(intel_encoder, type);
intel_sdvo_set_target_output(intel_sdvo, type);
intel_sdvo_write_cmd(intel_encoder,
intel_sdvo_write_cmd(intel_sdvo,
SDVO_CMD_GET_SUPPORTED_TV_FORMATS, NULL, 0);
status = intel_sdvo_read_response(intel_encoder,
status = intel_sdvo_read_response(intel_sdvo,
&format, sizeof(format));
if (status != SDVO_CMD_STATUS_SUCCESS)
return;
......@@ -2446,7 +2416,7 @@ static void intel_sdvo_tv_create_property(struct drm_connector *connector, int t
sdvo_connector->tv_format_property, i,
i, sdvo_connector->tv_format_supported[i]);
sdvo_priv->tv_format_name = sdvo_connector->tv_format_supported[0];
intel_sdvo->tv_format_name = sdvo_connector->tv_format_supported[0];
drm_connector_attach_property(
connector, sdvo_connector->tv_format_property, 0);
......@@ -2455,17 +2425,17 @@ static void intel_sdvo_tv_create_property(struct drm_connector *connector, int t
static void intel_sdvo_create_enhance_property(struct drm_connector *connector)
{
struct drm_encoder *encoder = intel_attached_encoder(connector);
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder);
struct intel_connector *intel_connector = to_intel_connector(connector);
struct intel_sdvo_connector *sdvo_priv = intel_connector->dev_priv;
struct intel_sdvo_connector *intel_sdvo_connector = intel_connector->dev_priv;
struct intel_sdvo_enhancements_reply sdvo_data;
struct drm_device *dev = connector->dev;
uint8_t status;
uint16_t response, data_value[2];
intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS,
intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS,
NULL, 0);
status = intel_sdvo_read_response(intel_encoder, &sdvo_data,
status = intel_sdvo_read_response(intel_sdvo, &sdvo_data,
sizeof(sdvo_data));
if (status != SDVO_CMD_STATUS_SUCCESS) {
DRM_DEBUG_KMS(" incorrect response is returned\n");
......@@ -2476,278 +2446,278 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector)
DRM_DEBUG_KMS("No enhancement is supported\n");
return;
}
if (IS_TV(sdvo_priv)) {
if (IS_TV(intel_sdvo_connector)) {
/* when horizontal overscan is supported, Add the left/right
* property
*/
if (sdvo_data.overscan_h) {
intel_sdvo_write_cmd(intel_encoder,
intel_sdvo_write_cmd(intel_sdvo,
SDVO_CMD_GET_MAX_OVERSCAN_H, NULL, 0);
status = intel_sdvo_read_response(intel_encoder,
status = intel_sdvo_read_response(intel_sdvo,
&data_value, 4);
if (status != SDVO_CMD_STATUS_SUCCESS) {
DRM_DEBUG_KMS("Incorrect SDVO max "
"h_overscan\n");
return;
}
intel_sdvo_write_cmd(intel_encoder,
intel_sdvo_write_cmd(intel_sdvo,
SDVO_CMD_GET_OVERSCAN_H, NULL, 0);
status = intel_sdvo_read_response(intel_encoder,
status = intel_sdvo_read_response(intel_sdvo,
&response, 2);
if (status != SDVO_CMD_STATUS_SUCCESS) {
DRM_DEBUG_KMS("Incorrect SDVO h_overscan\n");
return;
}
sdvo_priv->max_hscan = data_value[0];
sdvo_priv->left_margin = data_value[0] - response;
sdvo_priv->right_margin = sdvo_priv->left_margin;
sdvo_priv->left_property =
intel_sdvo_connector->max_hscan = data_value[0];
intel_sdvo_connector->left_margin = data_value[0] - response;
intel_sdvo_connector->right_margin = intel_sdvo_connector->left_margin;
intel_sdvo_connector->left_property =
drm_property_create(dev, DRM_MODE_PROP_RANGE,
"left_margin", 2);
sdvo_priv->left_property->values[0] = 0;
sdvo_priv->left_property->values[1] = data_value[0];
intel_sdvo_connector->left_property->values[0] = 0;
intel_sdvo_connector->left_property->values[1] = data_value[0];
drm_connector_attach_property(connector,
sdvo_priv->left_property,
sdvo_priv->left_margin);
sdvo_priv->right_property =
intel_sdvo_connector->left_property,
intel_sdvo_connector->left_margin);
intel_sdvo_connector->right_property =
drm_property_create(dev, DRM_MODE_PROP_RANGE,
"right_margin", 2);
sdvo_priv->right_property->values[0] = 0;
sdvo_priv->right_property->values[1] = data_value[0];
intel_sdvo_connector->right_property->values[0] = 0;
intel_sdvo_connector->right_property->values[1] = data_value[0];
drm_connector_attach_property(connector,
sdvo_priv->right_property,
sdvo_priv->right_margin);
intel_sdvo_connector->right_property,
intel_sdvo_connector->right_margin);
DRM_DEBUG_KMS("h_overscan: max %d, "
"default %d, current %d\n",
data_value[0], data_value[1], response);
}
if (sdvo_data.overscan_v) {
intel_sdvo_write_cmd(intel_encoder,
intel_sdvo_write_cmd(intel_sdvo,
SDVO_CMD_GET_MAX_OVERSCAN_V, NULL, 0);
status = intel_sdvo_read_response(intel_encoder,
status = intel_sdvo_read_response(intel_sdvo,
&data_value, 4);
if (status != SDVO_CMD_STATUS_SUCCESS) {
DRM_DEBUG_KMS("Incorrect SDVO max "
"v_overscan\n");
return;
}
intel_sdvo_write_cmd(intel_encoder,
intel_sdvo_write_cmd(intel_sdvo,
SDVO_CMD_GET_OVERSCAN_V, NULL, 0);
status = intel_sdvo_read_response(intel_encoder,
status = intel_sdvo_read_response(intel_sdvo,
&response, 2);
if (status != SDVO_CMD_STATUS_SUCCESS) {
DRM_DEBUG_KMS("Incorrect SDVO v_overscan\n");
return;
}
sdvo_priv->max_vscan = data_value[0];
sdvo_priv->top_margin = data_value[0] - response;
sdvo_priv->bottom_margin = sdvo_priv->top_margin;
sdvo_priv->top_property =
intel_sdvo_connector->max_vscan = data_value[0];
intel_sdvo_connector->top_margin = data_value[0] - response;
intel_sdvo_connector->bottom_margin = intel_sdvo_connector->top_margin;
intel_sdvo_connector->top_property =
drm_property_create(dev, DRM_MODE_PROP_RANGE,
"top_margin", 2);
sdvo_priv->top_property->values[0] = 0;
sdvo_priv->top_property->values[1] = data_value[0];
intel_sdvo_connector->top_property->values[0] = 0;
intel_sdvo_connector->top_property->values[1] = data_value[0];
drm_connector_attach_property(connector,
sdvo_priv->top_property,
sdvo_priv->top_margin);
sdvo_priv->bottom_property =
intel_sdvo_connector->top_property,
intel_sdvo_connector->top_margin);
intel_sdvo_connector->bottom_property =
drm_property_create(dev, DRM_MODE_PROP_RANGE,
"bottom_margin", 2);
sdvo_priv->bottom_property->values[0] = 0;
sdvo_priv->bottom_property->values[1] = data_value[0];
intel_sdvo_connector->bottom_property->values[0] = 0;
intel_sdvo_connector->bottom_property->values[1] = data_value[0];
drm_connector_attach_property(connector,
sdvo_priv->bottom_property,
sdvo_priv->bottom_margin);
intel_sdvo_connector->bottom_property,
intel_sdvo_connector->bottom_margin);
DRM_DEBUG_KMS("v_overscan: max %d, "
"default %d, current %d\n",
data_value[0], data_value[1], response);
}
if (sdvo_data.position_h) {
intel_sdvo_write_cmd(intel_encoder,
intel_sdvo_write_cmd(intel_sdvo,
SDVO_CMD_GET_MAX_POSITION_H, NULL, 0);
status = intel_sdvo_read_response(intel_encoder,
status = intel_sdvo_read_response(intel_sdvo,
&data_value, 4);
if (status != SDVO_CMD_STATUS_SUCCESS) {
DRM_DEBUG_KMS("Incorrect SDVO Max h_pos\n");
return;
}
intel_sdvo_write_cmd(intel_encoder,
intel_sdvo_write_cmd(intel_sdvo,
SDVO_CMD_GET_POSITION_H, NULL, 0);
status = intel_sdvo_read_response(intel_encoder,
status = intel_sdvo_read_response(intel_sdvo,
&response, 2);
if (status != SDVO_CMD_STATUS_SUCCESS) {
DRM_DEBUG_KMS("Incorrect SDVO get h_postion\n");
return;
}
sdvo_priv->max_hpos = data_value[0];
sdvo_priv->cur_hpos = response;
sdvo_priv->hpos_property =
intel_sdvo_connector->max_hpos = data_value[0];
intel_sdvo_connector->cur_hpos = response;
intel_sdvo_connector->hpos_property =
drm_property_create(dev, DRM_MODE_PROP_RANGE,
"hpos", 2);
sdvo_priv->hpos_property->values[0] = 0;
sdvo_priv->hpos_property->values[1] = data_value[0];
intel_sdvo_connector->hpos_property->values[0] = 0;
intel_sdvo_connector->hpos_property->values[1] = data_value[0];
drm_connector_attach_property(connector,
sdvo_priv->hpos_property,
sdvo_priv->cur_hpos);
intel_sdvo_connector->hpos_property,
intel_sdvo_connector->cur_hpos);
DRM_DEBUG_KMS("h_position: max %d, "
"default %d, current %d\n",
data_value[0], data_value[1], response);
}
if (sdvo_data.position_v) {
intel_sdvo_write_cmd(intel_encoder,
intel_sdvo_write_cmd(intel_sdvo,
SDVO_CMD_GET_MAX_POSITION_V, NULL, 0);
status = intel_sdvo_read_response(intel_encoder,
status = intel_sdvo_read_response(intel_sdvo,
&data_value, 4);
if (status != SDVO_CMD_STATUS_SUCCESS) {
DRM_DEBUG_KMS("Incorrect SDVO Max v_pos\n");
return;
}
intel_sdvo_write_cmd(intel_encoder,
intel_sdvo_write_cmd(intel_sdvo,
SDVO_CMD_GET_POSITION_V, NULL, 0);
status = intel_sdvo_read_response(intel_encoder,
status = intel_sdvo_read_response(intel_sdvo,
&response, 2);
if (status != SDVO_CMD_STATUS_SUCCESS) {
DRM_DEBUG_KMS("Incorrect SDVO get v_postion\n");
return;
}
sdvo_priv->max_vpos = data_value[0];
sdvo_priv->cur_vpos = response;
sdvo_priv->vpos_property =
intel_sdvo_connector->max_vpos = data_value[0];
intel_sdvo_connector->cur_vpos = response;
intel_sdvo_connector->vpos_property =
drm_property_create(dev, DRM_MODE_PROP_RANGE,
"vpos", 2);
sdvo_priv->vpos_property->values[0] = 0;
sdvo_priv->vpos_property->values[1] = data_value[0];
intel_sdvo_connector->vpos_property->values[0] = 0;
intel_sdvo_connector->vpos_property->values[1] = data_value[0];
drm_connector_attach_property(connector,
sdvo_priv->vpos_property,
sdvo_priv->cur_vpos);
intel_sdvo_connector->vpos_property,
intel_sdvo_connector->cur_vpos);
DRM_DEBUG_KMS("v_position: max %d, "
"default %d, current %d\n",
data_value[0], data_value[1], response);
}
if (sdvo_data.saturation) {
intel_sdvo_write_cmd(intel_encoder,
intel_sdvo_write_cmd(intel_sdvo,
SDVO_CMD_GET_MAX_SATURATION, NULL, 0);
status = intel_sdvo_read_response(intel_encoder,
status = intel_sdvo_read_response(intel_sdvo,
&data_value, 4);
if (status != SDVO_CMD_STATUS_SUCCESS) {
DRM_DEBUG_KMS("Incorrect SDVO Max sat\n");
return;
}
intel_sdvo_write_cmd(intel_encoder,
intel_sdvo_write_cmd(intel_sdvo,
SDVO_CMD_GET_SATURATION, NULL, 0);
status = intel_sdvo_read_response(intel_encoder,
status = intel_sdvo_read_response(intel_sdvo,
&response, 2);
if (status != SDVO_CMD_STATUS_SUCCESS) {
DRM_DEBUG_KMS("Incorrect SDVO get sat\n");
return;
}
sdvo_priv->max_saturation = data_value[0];
sdvo_priv->cur_saturation = response;
sdvo_priv->saturation_property =
intel_sdvo_connector->max_saturation = data_value[0];
intel_sdvo_connector->cur_saturation = response;
intel_sdvo_connector->saturation_property =
drm_property_create(dev, DRM_MODE_PROP_RANGE,
"saturation", 2);
sdvo_priv->saturation_property->values[0] = 0;
sdvo_priv->saturation_property->values[1] =
intel_sdvo_connector->saturation_property->values[0] = 0;
intel_sdvo_connector->saturation_property->values[1] =
data_value[0];
drm_connector_attach_property(connector,
sdvo_priv->saturation_property,
sdvo_priv->cur_saturation);
intel_sdvo_connector->saturation_property,
intel_sdvo_connector->cur_saturation);
DRM_DEBUG_KMS("saturation: max %d, "
"default %d, current %d\n",
data_value[0], data_value[1], response);
}
if (sdvo_data.contrast) {
intel_sdvo_write_cmd(intel_encoder,
intel_sdvo_write_cmd(intel_sdvo,
SDVO_CMD_GET_MAX_CONTRAST, NULL, 0);
status = intel_sdvo_read_response(intel_encoder,
status = intel_sdvo_read_response(intel_sdvo,
&data_value, 4);
if (status != SDVO_CMD_STATUS_SUCCESS) {
DRM_DEBUG_KMS("Incorrect SDVO Max contrast\n");
return;
}
intel_sdvo_write_cmd(intel_encoder,
intel_sdvo_write_cmd(intel_sdvo,
SDVO_CMD_GET_CONTRAST, NULL, 0);
status = intel_sdvo_read_response(intel_encoder,
status = intel_sdvo_read_response(intel_sdvo,
&response, 2);
if (status != SDVO_CMD_STATUS_SUCCESS) {
DRM_DEBUG_KMS("Incorrect SDVO get contrast\n");
return;
}
sdvo_priv->max_contrast = data_value[0];
sdvo_priv->cur_contrast = response;
sdvo_priv->contrast_property =
intel_sdvo_connector->max_contrast = data_value[0];
intel_sdvo_connector->cur_contrast = response;
intel_sdvo_connector->contrast_property =
drm_property_create(dev, DRM_MODE_PROP_RANGE,
"contrast", 2);
sdvo_priv->contrast_property->values[0] = 0;
sdvo_priv->contrast_property->values[1] = data_value[0];
intel_sdvo_connector->contrast_property->values[0] = 0;
intel_sdvo_connector->contrast_property->values[1] = data_value[0];
drm_connector_attach_property(connector,
sdvo_priv->contrast_property,
sdvo_priv->cur_contrast);
intel_sdvo_connector->contrast_property,
intel_sdvo_connector->cur_contrast);
DRM_DEBUG_KMS("contrast: max %d, "
"default %d, current %d\n",
data_value[0], data_value[1], response);
}
if (sdvo_data.hue) {
intel_sdvo_write_cmd(intel_encoder,
intel_sdvo_write_cmd(intel_sdvo,
SDVO_CMD_GET_MAX_HUE, NULL, 0);
status = intel_sdvo_read_response(intel_encoder,
status = intel_sdvo_read_response(intel_sdvo,
&data_value, 4);
if (status != SDVO_CMD_STATUS_SUCCESS) {
DRM_DEBUG_KMS("Incorrect SDVO Max hue\n");
return;
}
intel_sdvo_write_cmd(intel_encoder,
intel_sdvo_write_cmd(intel_sdvo,
SDVO_CMD_GET_HUE, NULL, 0);
status = intel_sdvo_read_response(intel_encoder,
status = intel_sdvo_read_response(intel_sdvo,
&response, 2);
if (status != SDVO_CMD_STATUS_SUCCESS) {
DRM_DEBUG_KMS("Incorrect SDVO get hue\n");
return;
}
sdvo_priv->max_hue = data_value[0];
sdvo_priv->cur_hue = response;
sdvo_priv->hue_property =
intel_sdvo_connector->max_hue = data_value[0];
intel_sdvo_connector->cur_hue = response;
intel_sdvo_connector->hue_property =
drm_property_create(dev, DRM_MODE_PROP_RANGE,
"hue", 2);
sdvo_priv->hue_property->values[0] = 0;
sdvo_priv->hue_property->values[1] =
intel_sdvo_connector->hue_property->values[0] = 0;
intel_sdvo_connector->hue_property->values[1] =
data_value[0];
drm_connector_attach_property(connector,
sdvo_priv->hue_property,
sdvo_priv->cur_hue);
intel_sdvo_connector->hue_property,
intel_sdvo_connector->cur_hue);
DRM_DEBUG_KMS("hue: max %d, default %d, current %d\n",
data_value[0], data_value[1], response);
}
}
if (IS_TV(sdvo_priv) || IS_LVDS(sdvo_priv)) {
if (IS_TV(intel_sdvo_connector) || IS_LVDS(intel_sdvo_connector)) {
if (sdvo_data.brightness) {
intel_sdvo_write_cmd(intel_encoder,
intel_sdvo_write_cmd(intel_sdvo,
SDVO_CMD_GET_MAX_BRIGHTNESS, NULL, 0);
status = intel_sdvo_read_response(intel_encoder,
status = intel_sdvo_read_response(intel_sdvo,
&data_value, 4);
if (status != SDVO_CMD_STATUS_SUCCESS) {
DRM_DEBUG_KMS("Incorrect SDVO Max bright\n");
return;
}
intel_sdvo_write_cmd(intel_encoder,
intel_sdvo_write_cmd(intel_sdvo,
SDVO_CMD_GET_BRIGHTNESS, NULL, 0);
status = intel_sdvo_read_response(intel_encoder,
status = intel_sdvo_read_response(intel_sdvo,
&response, 2);
if (status != SDVO_CMD_STATUS_SUCCESS) {
DRM_DEBUG_KMS("Incorrect SDVO get brigh\n");
return;
}
sdvo_priv->max_brightness = data_value[0];
sdvo_priv->cur_brightness = response;
sdvo_priv->brightness_property =
intel_sdvo_connector->max_brightness = data_value[0];
intel_sdvo_connector->cur_brightness = response;
intel_sdvo_connector->brightness_property =
drm_property_create(dev, DRM_MODE_PROP_RANGE,
"brightness", 2);
sdvo_priv->brightness_property->values[0] = 0;
sdvo_priv->brightness_property->values[1] =
intel_sdvo_connector->brightness_property->values[0] = 0;
intel_sdvo_connector->brightness_property->values[1] =
data_value[0];
drm_connector_attach_property(connector,
sdvo_priv->brightness_property,
sdvo_priv->cur_brightness);
intel_sdvo_connector->brightness_property,
intel_sdvo_connector->cur_brightness);
DRM_DEBUG_KMS("brightness: max %d, "
"default %d, current %d\n",
data_value[0], data_value[1], response);
......@@ -2760,20 +2730,18 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_encoder *intel_encoder;
struct intel_sdvo_priv *sdvo_priv;
struct intel_sdvo *intel_sdvo;
u8 ch[0x40];
int i;
u32 i2c_reg, ddc_reg, analog_ddc_reg;
intel_encoder = kcalloc(sizeof(struct intel_encoder)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL);
if (!intel_encoder) {
intel_sdvo = kzalloc(sizeof(struct intel_sdvo), GFP_KERNEL);
if (!intel_sdvo)
return false;
}
sdvo_priv = (struct intel_sdvo_priv *)(intel_encoder + 1);
sdvo_priv->sdvo_reg = sdvo_reg;
intel_sdvo->sdvo_reg = sdvo_reg;
intel_encoder->dev_priv = sdvo_priv;
intel_encoder = &intel_sdvo->base;
intel_encoder->type = INTEL_OUTPUT_SDVO;
if (HAS_PCH_SPLIT(dev)) {
......@@ -2795,14 +2763,14 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg)
if (!intel_encoder->i2c_bus)
goto err_inteloutput;
sdvo_priv->slave_addr = intel_sdvo_get_slave_addr(dev, sdvo_reg);
intel_sdvo->slave_addr = intel_sdvo_get_slave_addr(dev, sdvo_reg);
/* Save the bit-banging i2c functionality for use by the DDC wrapper */
intel_sdvo_i2c_bit_algo.functionality = intel_encoder->i2c_bus->algo->functionality;
/* Read the regs to test if we can talk to the device */
for (i = 0; i < 0x40; i++) {
if (!intel_sdvo_read_byte(intel_encoder, i, &ch[i])) {
if (!intel_sdvo_read_byte(intel_sdvo, i, &ch[i])) {
DRM_DEBUG_KMS("No SDVO device found on SDVO%c\n",
IS_SDVOB(sdvo_reg) ? 'B' : 'C');
goto err_i2c;
......@@ -2812,12 +2780,12 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg)
/* setup the DDC bus. */
if (IS_SDVOB(sdvo_reg)) {
intel_encoder->ddc_bus = intel_i2c_create(dev, ddc_reg, "SDVOB DDC BUS");
sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, analog_ddc_reg,
intel_sdvo->analog_ddc_bus = intel_i2c_create(dev, analog_ddc_reg,
"SDVOB/VGA DDC BUS");
dev_priv->hotplug_supported_mask |= SDVOB_HOTPLUG_INT_STATUS;
} else {
intel_encoder->ddc_bus = intel_i2c_create(dev, ddc_reg, "SDVOC DDC BUS");
sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, analog_ddc_reg,
intel_sdvo->analog_ddc_bus = intel_i2c_create(dev, analog_ddc_reg,
"SDVOC/VGA DDC BUS");
dev_priv->hotplug_supported_mask |= SDVOC_HOTPLUG_INT_STATUS;
}
......@@ -2833,53 +2801,53 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg)
drm_encoder_helper_add(&intel_encoder->enc, &intel_sdvo_helper_funcs);
/* In default case sdvo lvds is false */
intel_sdvo_get_capabilities(intel_encoder, &sdvo_priv->caps);
intel_sdvo_get_capabilities(intel_sdvo, &intel_sdvo->caps);
if (intel_sdvo_output_setup(intel_encoder,
sdvo_priv->caps.output_flags) != true) {
if (intel_sdvo_output_setup(intel_sdvo,
intel_sdvo->caps.output_flags) != true) {
DRM_DEBUG_KMS("SDVO output failed to setup on SDVO%c\n",
IS_SDVOB(sdvo_reg) ? 'B' : 'C');
goto err_i2c;
}
intel_sdvo_select_ddc_bus(dev_priv, sdvo_priv, sdvo_reg);
intel_sdvo_select_ddc_bus(dev_priv, intel_sdvo, sdvo_reg);
/* Set the input timing to the screen. Assume always input 0. */
intel_sdvo_set_target_input(intel_encoder, true, false);
intel_sdvo_set_target_input(intel_sdvo, true, false);
intel_sdvo_get_input_pixel_clock_range(intel_encoder,
&sdvo_priv->pixel_clock_min,
&sdvo_priv->pixel_clock_max);
intel_sdvo_get_input_pixel_clock_range(intel_sdvo,
&intel_sdvo->pixel_clock_min,
&intel_sdvo->pixel_clock_max);
DRM_DEBUG_KMS("%s device VID/DID: %02X:%02X.%02X, "
"clock range %dMHz - %dMHz, "
"input 1: %c, input 2: %c, "
"output 1: %c, output 2: %c\n",
SDVO_NAME(sdvo_priv),
sdvo_priv->caps.vendor_id, sdvo_priv->caps.device_id,
sdvo_priv->caps.device_rev_id,
sdvo_priv->pixel_clock_min / 1000,
sdvo_priv->pixel_clock_max / 1000,
(sdvo_priv->caps.sdvo_inputs_mask & 0x1) ? 'Y' : 'N',
(sdvo_priv->caps.sdvo_inputs_mask & 0x2) ? 'Y' : 'N',
SDVO_NAME(intel_sdvo),
intel_sdvo->caps.vendor_id, intel_sdvo->caps.device_id,
intel_sdvo->caps.device_rev_id,
intel_sdvo->pixel_clock_min / 1000,
intel_sdvo->pixel_clock_max / 1000,
(intel_sdvo->caps.sdvo_inputs_mask & 0x1) ? 'Y' : 'N',
(intel_sdvo->caps.sdvo_inputs_mask & 0x2) ? 'Y' : 'N',
/* check currently supported outputs */
sdvo_priv->caps.output_flags &
intel_sdvo->caps.output_flags &
(SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_RGB0) ? 'Y' : 'N',
sdvo_priv->caps.output_flags &
intel_sdvo->caps.output_flags &
(SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N');
return true;
err_i2c:
if (sdvo_priv->analog_ddc_bus != NULL)
intel_i2c_destroy(sdvo_priv->analog_ddc_bus);
if (intel_sdvo->analog_ddc_bus != NULL)
intel_i2c_destroy(intel_sdvo->analog_ddc_bus);
if (intel_encoder->ddc_bus != NULL)
intel_i2c_destroy(intel_encoder->ddc_bus);
if (intel_encoder->i2c_bus != NULL)
intel_i2c_destroy(intel_encoder->i2c_bus);
err_inteloutput:
kfree(intel_encoder);
kfree(intel_sdvo);
return false;
}
......@@ -44,7 +44,9 @@ enum tv_margin {
};
/** Private structure for the integrated TV support */
struct intel_tv_priv {
struct intel_tv {
struct intel_encoder base;
int type;
char *tv_format;
int margin[4];
......@@ -896,6 +898,11 @@ static const struct tv_mode tv_modes[] = {
},
};
static struct intel_tv *enc_to_intel_tv(struct drm_encoder *encoder)
{
return container_of(enc_to_intel_encoder(encoder), struct intel_tv, base);
}
static void
intel_tv_dpms(struct drm_encoder *encoder, int mode)
{
......@@ -929,19 +936,17 @@ intel_tv_mode_lookup (char *tv_format)
}
static const struct tv_mode *
intel_tv_mode_find (struct intel_encoder *intel_encoder)
intel_tv_mode_find (struct intel_tv *intel_tv)
{
struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
return intel_tv_mode_lookup(tv_priv->tv_format);
return intel_tv_mode_lookup(intel_tv->tv_format);
}
static enum drm_mode_status
intel_tv_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode)
{
struct drm_encoder *encoder = intel_attached_encoder(connector);
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder);
struct intel_tv *intel_tv = enc_to_intel_tv(encoder);
const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
/* Ensure TV refresh is close to desired refresh */
if (tv_mode && abs(tv_mode->refresh - drm_mode_vrefresh(mode) * 1000)
......@@ -957,8 +962,8 @@ intel_tv_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
{
struct drm_device *dev = encoder->dev;
struct drm_mode_config *drm_config = &dev->mode_config;
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
const struct tv_mode *tv_mode = intel_tv_mode_find (intel_encoder);
struct intel_tv *intel_tv = enc_to_intel_tv(encoder);
const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
struct drm_encoder *other_encoder;
if (!tv_mode)
......@@ -983,9 +988,8 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_crtc *crtc = encoder->crtc;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder);
struct intel_tv *intel_tv = enc_to_intel_tv(encoder);
const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
u32 tv_ctl;
u32 hctl1, hctl2, hctl3;
u32 vctl1, vctl2, vctl3, vctl4, vctl5, vctl6, vctl7;
......@@ -1001,7 +1005,7 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
tv_ctl = I915_READ(TV_CTL);
tv_ctl &= TV_CTL_SAVE;
switch (tv_priv->type) {
switch (intel_tv->type) {
default:
case DRM_MODE_CONNECTOR_Unknown:
case DRM_MODE_CONNECTOR_Composite:
......@@ -1168,12 +1172,12 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
else
ysize = 2*tv_mode->nbr_end + 1;
xpos += tv_priv->margin[TV_MARGIN_LEFT];
ypos += tv_priv->margin[TV_MARGIN_TOP];
xsize -= (tv_priv->margin[TV_MARGIN_LEFT] +
tv_priv->margin[TV_MARGIN_RIGHT]);
ysize -= (tv_priv->margin[TV_MARGIN_TOP] +
tv_priv->margin[TV_MARGIN_BOTTOM]);
xpos += intel_tv->margin[TV_MARGIN_LEFT];
ypos += intel_tv->margin[TV_MARGIN_TOP];
xsize -= (intel_tv->margin[TV_MARGIN_LEFT] +
intel_tv->margin[TV_MARGIN_RIGHT]);
ysize -= (intel_tv->margin[TV_MARGIN_TOP] +
intel_tv->margin[TV_MARGIN_BOTTOM]);
I915_WRITE(TV_WIN_POS, (xpos<<16)|ypos);
I915_WRITE(TV_WIN_SIZE, (xsize<<16)|ysize);
......@@ -1222,9 +1226,9 @@ static const struct drm_display_mode reported_modes[] = {
* \return false if TV is disconnected.
*/
static int
intel_tv_detect_type (struct drm_crtc *crtc, struct intel_encoder *intel_encoder)
intel_tv_detect_type (struct intel_tv *intel_tv)
{
struct drm_encoder *encoder = &intel_encoder->enc;
struct drm_encoder *encoder = &intel_tv->base.enc;
struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
unsigned long irqflags;
......@@ -1304,12 +1308,11 @@ intel_tv_detect_type (struct drm_crtc *crtc, struct intel_encoder *intel_encoder
static void intel_tv_find_better_format(struct drm_connector *connector)
{
struct drm_encoder *encoder = intel_attached_encoder(connector);
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder);
struct intel_tv *intel_tv = enc_to_intel_tv(encoder);
const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
int i;
if ((tv_priv->type == DRM_MODE_CONNECTOR_Component) ==
if ((intel_tv->type == DRM_MODE_CONNECTOR_Component) ==
tv_mode->component_only)
return;
......@@ -1317,12 +1320,12 @@ static void intel_tv_find_better_format(struct drm_connector *connector)
for (i = 0; i < sizeof(tv_modes) / sizeof(*tv_modes); i++) {
tv_mode = tv_modes + i;
if ((tv_priv->type == DRM_MODE_CONNECTOR_Component) ==
if ((intel_tv->type == DRM_MODE_CONNECTOR_Component) ==
tv_mode->component_only)
break;
}
tv_priv->tv_format = tv_mode->name;
intel_tv->tv_format = tv_mode->name;
drm_connector_property_set_value(connector,
connector->dev->mode_config.tv_mode_property, i);
}
......@@ -1336,31 +1339,31 @@ static void intel_tv_find_better_format(struct drm_connector *connector)
static enum drm_connector_status
intel_tv_detect(struct drm_connector *connector)
{
struct drm_crtc *crtc;
struct drm_display_mode mode;
struct drm_encoder *encoder = intel_attached_encoder(connector);
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
int dpms_mode;
int type = tv_priv->type;
struct intel_tv *intel_tv = enc_to_intel_tv(encoder);
int type;
mode = reported_modes[0];
drm_mode_set_crtcinfo(&mode, CRTC_INTERLACE_HALVE_V);
if (encoder->crtc && encoder->crtc->enabled) {
type = intel_tv_detect_type(encoder->crtc, intel_encoder);
type = intel_tv_detect_type(intel_tv);
} else {
crtc = intel_get_load_detect_pipe(intel_encoder, connector,
struct drm_crtc *crtc;
int dpms_mode;
crtc = intel_get_load_detect_pipe(&intel_tv->base, connector,
&mode, &dpms_mode);
if (crtc) {
type = intel_tv_detect_type(crtc, intel_encoder);
intel_release_load_detect_pipe(intel_encoder, connector,
type = intel_tv_detect_type(intel_tv);
intel_release_load_detect_pipe(&intel_tv->base, connector,
dpms_mode);
} else
type = -1;
}
tv_priv->type = type;
intel_tv->type = type;
if (type < 0)
return connector_status_disconnected;
......@@ -1391,8 +1394,8 @@ intel_tv_chose_preferred_modes(struct drm_connector *connector,
struct drm_display_mode *mode_ptr)
{
struct drm_encoder *encoder = intel_attached_encoder(connector);
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder);
struct intel_tv *intel_tv = enc_to_intel_tv(encoder);
const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
if (tv_mode->nbr_end < 480 && mode_ptr->vdisplay == 480)
mode_ptr->type |= DRM_MODE_TYPE_PREFERRED;
......@@ -1417,8 +1420,8 @@ intel_tv_get_modes(struct drm_connector *connector)
{
struct drm_display_mode *mode_ptr;
struct drm_encoder *encoder = intel_attached_encoder(connector);
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder);
struct intel_tv *intel_tv = enc_to_intel_tv(encoder);
const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
int j, count = 0;
u64 tmp;
......@@ -1483,8 +1486,7 @@ intel_tv_set_property(struct drm_connector *connector, struct drm_property *prop
{
struct drm_device *dev = connector->dev;
struct drm_encoder *encoder = intel_attached_encoder(connector);
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
struct intel_tv *intel_tv = enc_to_intel_tv(encoder);
struct drm_crtc *crtc = encoder->crtc;
int ret = 0;
bool changed = false;
......@@ -1494,30 +1496,30 @@ intel_tv_set_property(struct drm_connector *connector, struct drm_property *prop
goto out;
if (property == dev->mode_config.tv_left_margin_property &&
tv_priv->margin[TV_MARGIN_LEFT] != val) {
tv_priv->margin[TV_MARGIN_LEFT] = val;
intel_tv->margin[TV_MARGIN_LEFT] != val) {
intel_tv->margin[TV_MARGIN_LEFT] = val;
changed = true;
} else if (property == dev->mode_config.tv_right_margin_property &&
tv_priv->margin[TV_MARGIN_RIGHT] != val) {
tv_priv->margin[TV_MARGIN_RIGHT] = val;
intel_tv->margin[TV_MARGIN_RIGHT] != val) {
intel_tv->margin[TV_MARGIN_RIGHT] = val;
changed = true;
} else if (property == dev->mode_config.tv_top_margin_property &&
tv_priv->margin[TV_MARGIN_TOP] != val) {
tv_priv->margin[TV_MARGIN_TOP] = val;
intel_tv->margin[TV_MARGIN_TOP] != val) {
intel_tv->margin[TV_MARGIN_TOP] = val;
changed = true;
} else if (property == dev->mode_config.tv_bottom_margin_property &&
tv_priv->margin[TV_MARGIN_BOTTOM] != val) {
tv_priv->margin[TV_MARGIN_BOTTOM] = val;
intel_tv->margin[TV_MARGIN_BOTTOM] != val) {
intel_tv->margin[TV_MARGIN_BOTTOM] = val;
changed = true;
} else if (property == dev->mode_config.tv_mode_property) {
if (val >= ARRAY_SIZE(tv_modes)) {
ret = -EINVAL;
goto out;
}
if (!strcmp(tv_priv->tv_format, tv_modes[val].name))
if (!strcmp(intel_tv->tv_format, tv_modes[val].name))
goto out;
tv_priv->tv_format = tv_modes[val].name;
intel_tv->tv_format = tv_modes[val].name;
changed = true;
} else {
ret = -EINVAL;
......@@ -1553,16 +1555,8 @@ static const struct drm_connector_helper_funcs intel_tv_connector_helper_funcs =
.best_encoder = intel_attached_encoder,
};
static void intel_tv_enc_destroy(struct drm_encoder *encoder)
{
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
drm_encoder_cleanup(encoder);
kfree(intel_encoder);
}
static const struct drm_encoder_funcs intel_tv_enc_funcs = {
.destroy = intel_tv_enc_destroy,
.destroy = intel_encoder_destroy,
};
/*
......@@ -1606,9 +1600,9 @@ intel_tv_init(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_connector *connector;
struct intel_tv *intel_tv;
struct intel_encoder *intel_encoder;
struct intel_connector *intel_connector;
struct intel_tv_priv *tv_priv;
u32 tv_dac_on, tv_dac_off, save_tv_dac;
char **tv_format_names;
int i, initial_mode = 0;
......@@ -1647,18 +1641,18 @@ intel_tv_init(struct drm_device *dev)
(tv_dac_off & TVDAC_STATE_CHG_EN) != 0)
return;
intel_encoder = kzalloc(sizeof(struct intel_encoder) +
sizeof(struct intel_tv_priv), GFP_KERNEL);
if (!intel_encoder) {
intel_tv = kzalloc(sizeof(struct intel_tv), GFP_KERNEL);
if (!intel_tv) {
return;
}
intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL);
if (!intel_connector) {
kfree(intel_encoder);
kfree(intel_tv);
return;
}
intel_encoder = &intel_tv->base;
connector = &intel_connector->base;
drm_connector_init(dev, connector, &intel_tv_connector_funcs,
......@@ -1668,22 +1662,20 @@ intel_tv_init(struct drm_device *dev)
DRM_MODE_ENCODER_TVDAC);
drm_mode_connector_attach_encoder(&intel_connector->base, &intel_encoder->enc);
tv_priv = (struct intel_tv_priv *)(intel_encoder + 1);
intel_encoder->type = INTEL_OUTPUT_TVOUT;
intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
intel_encoder->clone_mask = (1 << INTEL_TV_CLONE_BIT);
intel_encoder->enc.possible_crtcs = ((1 << 0) | (1 << 1));
intel_encoder->enc.possible_clones = (1 << INTEL_OUTPUT_TVOUT);
intel_encoder->dev_priv = tv_priv;
tv_priv->type = DRM_MODE_CONNECTOR_Unknown;
intel_tv->type = DRM_MODE_CONNECTOR_Unknown;
/* BIOS margin values */
tv_priv->margin[TV_MARGIN_LEFT] = 54;
tv_priv->margin[TV_MARGIN_TOP] = 36;
tv_priv->margin[TV_MARGIN_RIGHT] = 46;
tv_priv->margin[TV_MARGIN_BOTTOM] = 37;
intel_tv->margin[TV_MARGIN_LEFT] = 54;
intel_tv->margin[TV_MARGIN_TOP] = 36;
intel_tv->margin[TV_MARGIN_RIGHT] = 46;
intel_tv->margin[TV_MARGIN_BOTTOM] = 37;
tv_priv->tv_format = kstrdup(tv_modes[initial_mode].name, GFP_KERNEL);
intel_tv->tv_format = kstrdup(tv_modes[initial_mode].name, GFP_KERNEL);
drm_encoder_helper_add(&intel_encoder->enc, &intel_tv_helper_funcs);
drm_connector_helper_add(connector, &intel_tv_connector_helper_funcs);
......@@ -1703,16 +1695,16 @@ intel_tv_init(struct drm_device *dev)
initial_mode);
drm_connector_attach_property(connector,
dev->mode_config.tv_left_margin_property,
tv_priv->margin[TV_MARGIN_LEFT]);
intel_tv->margin[TV_MARGIN_LEFT]);
drm_connector_attach_property(connector,
dev->mode_config.tv_top_margin_property,
tv_priv->margin[TV_MARGIN_TOP]);
intel_tv->margin[TV_MARGIN_TOP]);
drm_connector_attach_property(connector,
dev->mode_config.tv_right_margin_property,
tv_priv->margin[TV_MARGIN_RIGHT]);
intel_tv->margin[TV_MARGIN_RIGHT]);
drm_connector_attach_property(connector,
dev->mode_config.tv_bottom_margin_property,
tv_priv->margin[TV_MARGIN_BOTTOM]);
intel_tv->margin[TV_MARGIN_BOTTOM]);
out:
drm_sysfs_connector_add(connector);
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment