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