80,7 → 80,7 |
|
/* |
* Capabilities of the SDVO device returned by |
* i830_sdvo_get_capabilities() |
* intel_sdvo_get_capabilities() |
*/ |
struct intel_sdvo_caps caps; |
|
202,15 → 202,14 |
u32 cur_dot_crawl, max_dot_crawl; |
}; |
|
static struct intel_sdvo *to_intel_sdvo(struct drm_encoder *encoder) |
static struct intel_sdvo *to_sdvo(struct intel_encoder *encoder) |
{ |
return container_of(encoder, struct intel_sdvo, base.base); |
return container_of(encoder, struct intel_sdvo, base); |
} |
|
static struct intel_sdvo *intel_attached_sdvo(struct drm_connector *connector) |
{ |
return container_of(intel_attached_encoder(connector), |
struct intel_sdvo, base); |
return to_sdvo(intel_attached_encoder(connector)); |
} |
|
static struct intel_sdvo_connector *to_intel_sdvo_connector(struct drm_connector *connector) |
539,7 → 538,8 |
&status)) |
goto log_fail; |
|
while (status == SDVO_CMD_STATUS_PENDING && --retry) { |
while ((status == SDVO_CMD_STATUS_PENDING || |
status == SDVO_CMD_STATUS_TARGET_NOT_SPECIFIED) && --retry) { |
if (retry < 10) |
msleep(15); |
else |
712,6 → 712,13 |
intel_sdvo_set_value(intel_sdvo, cmd + 1, &dtd->part2, sizeof(dtd->part2)); |
} |
|
static bool intel_sdvo_get_timing(struct intel_sdvo *intel_sdvo, u8 cmd, |
struct intel_sdvo_dtd *dtd) |
{ |
return intel_sdvo_get_value(intel_sdvo, cmd, &dtd->part1, sizeof(dtd->part1)) && |
intel_sdvo_get_value(intel_sdvo, cmd + 1, &dtd->part2, sizeof(dtd->part2)); |
} |
|
static bool intel_sdvo_set_input_timing(struct intel_sdvo *intel_sdvo, |
struct intel_sdvo_dtd *dtd) |
{ |
726,6 → 733,13 |
SDVO_CMD_SET_OUTPUT_TIMINGS_PART1, dtd); |
} |
|
static bool intel_sdvo_get_input_timing(struct intel_sdvo *intel_sdvo, |
struct intel_sdvo_dtd *dtd) |
{ |
return intel_sdvo_get_timing(intel_sdvo, |
SDVO_CMD_GET_INPUT_TIMINGS_PART1, dtd); |
} |
|
static bool |
intel_sdvo_create_preferred_input_timing(struct intel_sdvo *intel_sdvo, |
uint16_t clock, |
774,6 → 788,8 |
uint16_t h_sync_offset, v_sync_offset; |
int mode_clock; |
|
memset(dtd, 0, sizeof(*dtd)); |
|
width = mode->hdisplay; |
height = mode->vdisplay; |
|
816,44 → 832,51 |
if (mode->flags & DRM_MODE_FLAG_PVSYNC) |
dtd->part2.dtd_flags |= DTD_FLAG_VSYNC_POSITIVE; |
|
dtd->part2.sdvo_flags = 0; |
dtd->part2.v_sync_off_high = v_sync_offset & 0xc0; |
dtd->part2.reserved = 0; |
} |
|
static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode, |
static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode *pmode, |
const struct intel_sdvo_dtd *dtd) |
{ |
mode->hdisplay = dtd->part1.h_active; |
mode->hdisplay += ((dtd->part1.h_high >> 4) & 0x0f) << 8; |
mode->hsync_start = mode->hdisplay + dtd->part2.h_sync_off; |
mode->hsync_start += (dtd->part2.sync_off_width_high & 0xc0) << 2; |
mode->hsync_end = mode->hsync_start + dtd->part2.h_sync_width; |
mode->hsync_end += (dtd->part2.sync_off_width_high & 0x30) << 4; |
mode->htotal = mode->hdisplay + dtd->part1.h_blank; |
mode->htotal += (dtd->part1.h_high & 0xf) << 8; |
struct drm_display_mode mode = {}; |
|
mode->vdisplay = dtd->part1.v_active; |
mode->vdisplay += ((dtd->part1.v_high >> 4) & 0x0f) << 8; |
mode->vsync_start = mode->vdisplay; |
mode->vsync_start += (dtd->part2.v_sync_off_width >> 4) & 0xf; |
mode->vsync_start += (dtd->part2.sync_off_width_high & 0x0c) << 2; |
mode->vsync_start += dtd->part2.v_sync_off_high & 0xc0; |
mode->vsync_end = mode->vsync_start + |
mode.hdisplay = dtd->part1.h_active; |
mode.hdisplay += ((dtd->part1.h_high >> 4) & 0x0f) << 8; |
mode.hsync_start = mode.hdisplay + dtd->part2.h_sync_off; |
mode.hsync_start += (dtd->part2.sync_off_width_high & 0xc0) << 2; |
mode.hsync_end = mode.hsync_start + dtd->part2.h_sync_width; |
mode.hsync_end += (dtd->part2.sync_off_width_high & 0x30) << 4; |
mode.htotal = mode.hdisplay + dtd->part1.h_blank; |
mode.htotal += (dtd->part1.h_high & 0xf) << 8; |
|
mode.vdisplay = dtd->part1.v_active; |
mode.vdisplay += ((dtd->part1.v_high >> 4) & 0x0f) << 8; |
mode.vsync_start = mode.vdisplay; |
mode.vsync_start += (dtd->part2.v_sync_off_width >> 4) & 0xf; |
mode.vsync_start += (dtd->part2.sync_off_width_high & 0x0c) << 2; |
mode.vsync_start += dtd->part2.v_sync_off_high & 0xc0; |
mode.vsync_end = mode.vsync_start + |
(dtd->part2.v_sync_off_width & 0xf); |
mode->vsync_end += (dtd->part2.sync_off_width_high & 0x3) << 4; |
mode->vtotal = mode->vdisplay + dtd->part1.v_blank; |
mode->vtotal += (dtd->part1.v_high & 0xf) << 8; |
mode.vsync_end += (dtd->part2.sync_off_width_high & 0x3) << 4; |
mode.vtotal = mode.vdisplay + dtd->part1.v_blank; |
mode.vtotal += (dtd->part1.v_high & 0xf) << 8; |
|
mode->clock = dtd->part1.clock * 10; |
mode.clock = dtd->part1.clock * 10; |
|
mode->flags &= ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC); |
if (dtd->part2.dtd_flags & DTD_FLAG_INTERLACE) |
mode->flags |= DRM_MODE_FLAG_INTERLACE; |
mode.flags |= DRM_MODE_FLAG_INTERLACE; |
if (dtd->part2.dtd_flags & DTD_FLAG_HSYNC_POSITIVE) |
mode->flags |= DRM_MODE_FLAG_PHSYNC; |
mode.flags |= DRM_MODE_FLAG_PHSYNC; |
else |
mode.flags |= DRM_MODE_FLAG_NHSYNC; |
if (dtd->part2.dtd_flags & DTD_FLAG_VSYNC_POSITIVE) |
mode->flags |= DRM_MODE_FLAG_PVSYNC; |
mode.flags |= DRM_MODE_FLAG_PVSYNC; |
else |
mode.flags |= DRM_MODE_FLAG_NVSYNC; |
|
drm_mode_set_crtcinfo(&mode, 0); |
|
drm_mode_copy(pmode, &mode); |
} |
|
static bool intel_sdvo_check_supp_encode(struct intel_sdvo *intel_sdvo) |
950,31 → 973,33 |
static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo, |
const struct drm_display_mode *adjusted_mode) |
{ |
struct dip_infoframe avi_if = { |
.type = DIP_TYPE_AVI, |
.ver = DIP_VERSION_AVI, |
.len = DIP_LEN_AVI, |
}; |
uint8_t sdvo_data[4 + sizeof(avi_if.body.avi)]; |
struct intel_crtc *intel_crtc = to_intel_crtc(intel_sdvo->base.base.crtc); |
uint8_t sdvo_data[HDMI_INFOFRAME_SIZE(AVI)]; |
struct drm_crtc *crtc = intel_sdvo->base.base.crtc; |
struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
union hdmi_infoframe frame; |
int ret; |
ssize_t len; |
|
ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, |
adjusted_mode); |
if (ret < 0) { |
DRM_ERROR("couldn't fill AVI infoframe\n"); |
return false; |
} |
|
if (intel_sdvo->rgb_quant_range_selectable) { |
if (intel_crtc->config.limited_color_range) |
avi_if.body.avi.ITC_EC_Q_SC |= DIP_AVI_RGB_QUANT_RANGE_LIMITED; |
frame.avi.quantization_range = |
HDMI_QUANTIZATION_RANGE_LIMITED; |
else |
avi_if.body.avi.ITC_EC_Q_SC |= DIP_AVI_RGB_QUANT_RANGE_FULL; |
frame.avi.quantization_range = |
HDMI_QUANTIZATION_RANGE_FULL; |
} |
|
avi_if.body.avi.VIC = drm_match_cea_mode(adjusted_mode); |
len = hdmi_infoframe_pack(&frame, sdvo_data, sizeof(sdvo_data)); |
if (len < 0) |
return false; |
|
intel_dip_infoframe_csum(&avi_if); |
|
/* sdvo spec says that the ecc is handled by the hw, and it looks like |
* we must not send the ecc field, either. */ |
memcpy(sdvo_data, &avi_if, 3); |
sdvo_data[3] = avi_if.checksum; |
memcpy(&sdvo_data[4], &avi_if.body, sizeof(avi_if.body.avi)); |
|
return intel_sdvo_write_infoframe(intel_sdvo, SDVO_HBUF_INDEX_AVI_IF, |
SDVO_HBUF_TX_VSYNC, |
sdvo_data, sizeof(sdvo_data)); |
1041,10 → 1066,36 |
return true; |
} |
|
static void i9xx_adjust_sdvo_tv_clock(struct intel_crtc_config *pipe_config) |
{ |
unsigned dotclock = pipe_config->adjusted_mode.clock; |
struct dpll *clock = &pipe_config->dpll; |
|
/* SDVO TV has fixed PLL values depend on its clock range, |
this mirrors vbios setting. */ |
if (dotclock >= 100000 && dotclock < 140500) { |
clock->p1 = 2; |
clock->p2 = 10; |
clock->n = 3; |
clock->m1 = 16; |
clock->m2 = 8; |
} else if (dotclock >= 140500 && dotclock <= 200000) { |
clock->p1 = 1; |
clock->p2 = 10; |
clock->n = 6; |
clock->m1 = 12; |
clock->m2 = 8; |
} else { |
WARN(1, "SDVO TV clock out of range: %i\n", dotclock); |
} |
|
pipe_config->clock_set = true; |
} |
|
static bool intel_sdvo_compute_config(struct intel_encoder *encoder, |
struct intel_crtc_config *pipe_config) |
{ |
struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base); |
struct intel_sdvo *intel_sdvo = to_sdvo(encoder); |
struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode; |
struct drm_display_mode *mode = &pipe_config->requested_mode; |
|
1066,6 → 1117,7 |
(void) intel_sdvo_get_preferred_input_mode(intel_sdvo, |
mode, |
adjusted_mode); |
pipe_config->sdvo_tv_clock = true; |
} else if (intel_sdvo->is_lvds) { |
if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, |
intel_sdvo->sdvo_lvds_fixed_mode)) |
1097,6 → 1149,10 |
if (intel_sdvo->color_range) |
pipe_config->limited_color_range = true; |
|
/* Clock computation needs to happen after pixel multiplier. */ |
if (intel_sdvo->is_tv) |
i9xx_adjust_sdvo_tv_clock(pipe_config); |
|
return true; |
} |
|
1104,12 → 1160,11 |
{ |
struct drm_device *dev = intel_encoder->base.dev; |
struct drm_i915_private *dev_priv = dev->dev_private; |
struct drm_crtc *crtc = intel_encoder->base.crtc; |
struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
struct intel_crtc *crtc = to_intel_crtc(intel_encoder->base.crtc); |
struct drm_display_mode *adjusted_mode = |
&intel_crtc->config.adjusted_mode; |
struct drm_display_mode *mode = &intel_crtc->config.requested_mode; |
struct intel_sdvo *intel_sdvo = to_intel_sdvo(&intel_encoder->base); |
&crtc->config.adjusted_mode; |
struct drm_display_mode *mode = &crtc->config.requested_mode; |
struct intel_sdvo *intel_sdvo = to_sdvo(intel_encoder); |
u32 sdvox; |
struct intel_sdvo_in_out_map in_out; |
struct intel_sdvo_dtd input_dtd, output_dtd; |
1166,6 → 1221,8 |
* adjusted_mode. |
*/ |
intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); |
input_dtd.part1.clock /= crtc->config.pixel_multiplier; |
|
if (intel_sdvo->is_tv || intel_sdvo->is_lvds) |
input_dtd.part2.sdvo_flags = intel_sdvo->dtd_sdvo_flags; |
if (!intel_sdvo_set_input_timing(intel_sdvo, &input_dtd)) |
1172,8 → 1229,9 |
DRM_INFO("Setting input timings on %s failed\n", |
SDVO_NAME(intel_sdvo)); |
|
switch (intel_crtc->config.pixel_multiplier) { |
switch (crtc->config.pixel_multiplier) { |
default: |
WARN(1, "unknown pixel mutlipler specified\n"); |
case 1: rate = SDVO_CLOCK_RATE_MULT_1X; break; |
case 2: rate = SDVO_CLOCK_RATE_MULT_2X; break; |
case 4: rate = SDVO_CLOCK_RATE_MULT_4X; break; |
1204,9 → 1262,9 |
} |
|
if (INTEL_PCH_TYPE(dev) >= PCH_CPT) |
sdvox |= SDVO_PIPE_SEL_CPT(intel_crtc->pipe); |
sdvox |= SDVO_PIPE_SEL_CPT(crtc->pipe); |
else |
sdvox |= SDVO_PIPE_SEL(intel_crtc->pipe); |
sdvox |= SDVO_PIPE_SEL(crtc->pipe); |
|
if (intel_sdvo->has_hdmi_audio) |
sdvox |= SDVO_AUDIO_ENABLE; |
1216,7 → 1274,7 |
} else if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) { |
/* done in crtc_mode_set as it lives inside the dpll register */ |
} else { |
sdvox |= (intel_crtc->config.pixel_multiplier - 1) |
sdvox |= (crtc->config.pixel_multiplier - 1) |
<< SDVO_PORT_MULTIPLY_SHIFT; |
} |
|
1231,7 → 1289,7 |
struct intel_sdvo_connector *intel_sdvo_connector = |
to_intel_sdvo_connector(&connector->base); |
struct intel_sdvo *intel_sdvo = intel_attached_sdvo(&connector->base); |
u16 active_outputs; |
u16 active_outputs = 0; |
|
intel_sdvo_get_active_outputs(intel_sdvo, &active_outputs); |
|
1246,8 → 1304,8 |
{ |
struct drm_device *dev = encoder->base.dev; |
struct drm_i915_private *dev_priv = dev->dev_private; |
struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base); |
u16 active_outputs; |
struct intel_sdvo *intel_sdvo = to_sdvo(encoder); |
u16 active_outputs = 0; |
u32 tmp; |
|
tmp = I915_READ(intel_sdvo->sdvo_reg); |
1264,10 → 1322,77 |
return true; |
} |
|
static void intel_sdvo_get_config(struct intel_encoder *encoder, |
struct intel_crtc_config *pipe_config) |
{ |
struct drm_device *dev = encoder->base.dev; |
struct drm_i915_private *dev_priv = dev->dev_private; |
struct intel_sdvo *intel_sdvo = to_sdvo(encoder); |
struct intel_sdvo_dtd dtd; |
int encoder_pixel_multiplier = 0; |
u32 flags = 0, sdvox; |
u8 val; |
bool ret; |
|
ret = intel_sdvo_get_input_timing(intel_sdvo, &dtd); |
if (!ret) { |
/* Some sdvo encoders are not spec compliant and don't |
* implement the mandatory get_timings function. */ |
DRM_DEBUG_DRIVER("failed to retrieve SDVO DTD\n"); |
pipe_config->quirks |= PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS; |
} else { |
if (dtd.part2.dtd_flags & DTD_FLAG_HSYNC_POSITIVE) |
flags |= DRM_MODE_FLAG_PHSYNC; |
else |
flags |= DRM_MODE_FLAG_NHSYNC; |
|
if (dtd.part2.dtd_flags & DTD_FLAG_VSYNC_POSITIVE) |
flags |= DRM_MODE_FLAG_PVSYNC; |
else |
flags |= DRM_MODE_FLAG_NVSYNC; |
} |
|
pipe_config->adjusted_mode.flags |= flags; |
|
/* |
* pixel multiplier readout is tricky: Only on i915g/gm it is stored in |
* the sdvo port register, on all other platforms it is part of the dpll |
* state. Since the general pipe state readout happens before the |
* encoder->get_config we so already have a valid pixel multplier on all |
* other platfroms. |
*/ |
if (IS_I915G(dev) || IS_I915GM(dev)) { |
sdvox = I915_READ(intel_sdvo->sdvo_reg); |
pipe_config->pixel_multiplier = |
((sdvox & SDVO_PORT_MULTIPLY_MASK) |
>> SDVO_PORT_MULTIPLY_SHIFT) + 1; |
} |
|
/* Cross check the port pixel multiplier with the sdvo encoder state. */ |
if (intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_CLOCK_RATE_MULT, |
&val, 1)) { |
switch (val) { |
case SDVO_CLOCK_RATE_MULT_1X: |
encoder_pixel_multiplier = 1; |
break; |
case SDVO_CLOCK_RATE_MULT_2X: |
encoder_pixel_multiplier = 2; |
break; |
case SDVO_CLOCK_RATE_MULT_4X: |
encoder_pixel_multiplier = 4; |
break; |
} |
} |
|
WARN(encoder_pixel_multiplier != pipe_config->pixel_multiplier, |
"SDVO pixel multiplier mismatch, port: %i, encoder: %i\n", |
pipe_config->pixel_multiplier, encoder_pixel_multiplier); |
} |
|
static void intel_disable_sdvo(struct intel_encoder *encoder) |
{ |
struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; |
struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base); |
struct intel_sdvo *intel_sdvo = to_sdvo(encoder); |
u32 temp; |
|
intel_sdvo_set_active_outputs(intel_sdvo, 0); |
1309,7 → 1434,7 |
{ |
struct drm_device *dev = encoder->base.dev; |
struct drm_i915_private *dev_priv = dev->dev_private; |
struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base); |
struct intel_sdvo *intel_sdvo = to_sdvo(encoder); |
struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); |
u32 temp; |
bool input1, input2; |
1344,6 → 1469,7 |
intel_sdvo_set_active_outputs(intel_sdvo, intel_sdvo->attached_output); |
} |
|
/* Special dpms function to support cloning between dvo/sdvo/crt. */ |
static void intel_sdvo_dpms(struct drm_connector *connector, int mode) |
{ |
struct drm_crtc *crtc; |
1365,6 → 1491,8 |
return; |
} |
|
/* We set active outputs manually below in case pipe dpms doesn't change |
* due to cloning. */ |
if (mode != DRM_MODE_DPMS_ON) { |
intel_sdvo_set_active_outputs(intel_sdvo, 0); |
if (0) |
1467,7 → 1595,7 |
|
static void intel_sdvo_enable_hotplug(struct intel_encoder *encoder) |
{ |
struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base); |
struct intel_sdvo *intel_sdvo = to_sdvo(encoder); |
|
intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_ACTIVE_HOT_PLUG, |
&intel_sdvo->hotplug_active, 2); |
1495,7 → 1623,7 |
|
return drm_get_edid(connector, |
intel_gmbus_get_adapter(dev_priv, |
dev_priv->crt_ddc_pin)); |
dev_priv->vbt.crt_ddc_pin)); |
} |
|
static enum drm_connector_status |
1580,6 → 1708,9 |
struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); |
enum drm_connector_status ret; |
|
DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", |
connector->base.id, drm_get_connector_name(connector)); |
|
if (!intel_sdvo_get_value(intel_sdvo, |
SDVO_CMD_GET_ATTACHED_DISPLAYS, |
&response, 2)) |
1625,12 → 1756,9 |
if (ret == connector_status_connected) { |
intel_sdvo->is_tv = false; |
intel_sdvo->is_lvds = false; |
intel_sdvo->base.needs_tv_clock = false; |
|
if (response & SDVO_TV_MASK) { |
if (response & SDVO_TV_MASK) |
intel_sdvo->is_tv = true; |
intel_sdvo->base.needs_tv_clock = true; |
} |
if (response & SDVO_LVDS_MASK) |
intel_sdvo->is_lvds = intel_sdvo->sdvo_lvds_fixed_mode != NULL; |
} |
1772,21 → 1900,12 |
struct drm_display_mode *newmode; |
|
/* |
* Attempt to get the mode list from DDC. |
* Assume that the preferred modes are |
* arranged in priority order. |
*/ |
intel_ddc_get_modes(connector, &intel_sdvo->ddc); |
|
/* |
* Fetch modes from VBT. For SDVO prefer the VBT mode since some |
* SDVO->LVDS transcoders can't cope with the EDID mode. Since |
* drm_mode_probed_add adds the mode at the head of the list we add it |
* last. |
* SDVO->LVDS transcoders can't cope with the EDID mode. |
*/ |
if (dev_priv->sdvo_lvds_vbt_mode != NULL) { |
if (dev_priv->vbt.sdvo_lvds_vbt_mode != NULL) { |
newmode = drm_mode_duplicate(connector->dev, |
dev_priv->sdvo_lvds_vbt_mode); |
dev_priv->vbt.sdvo_lvds_vbt_mode); |
if (newmode != NULL) { |
/* Guarantee the mode is preferred */ |
newmode->type = (DRM_MODE_TYPE_PREFERRED | |
1795,6 → 1914,13 |
} |
} |
|
/* |
* Attempt to get the mode list from DDC. |
* Assume that the preferred modes are |
* arranged in priority order. |
*/ |
intel_ddc_get_modes(connector, &intel_sdvo->ddc); |
|
list_for_each_entry(newmode, &connector->probed_modes, head) { |
if (newmode->type & DRM_MODE_TYPE_PREFERRED) { |
intel_sdvo->sdvo_lvds_fixed_mode = |
2076,7 → 2202,7 |
|
static void intel_sdvo_enc_destroy(struct drm_encoder *encoder) |
{ |
struct intel_sdvo *intel_sdvo = to_intel_sdvo(encoder); |
struct intel_sdvo *intel_sdvo = to_sdvo(to_intel_encoder(encoder)); |
|
if (intel_sdvo->sdvo_lvds_fixed_mode != NULL) |
drm_mode_destroy(encoder->dev, |
2329,7 → 2455,6 |
intel_sdvo_connector->output_flag = type; |
|
intel_sdvo->is_tv = true; |
intel_sdvo->base.needs_tv_clock = true; |
|
intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); |
|
2417,7 → 2542,6 |
intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, uint16_t flags) |
{ |
intel_sdvo->is_tv = false; |
intel_sdvo->base.needs_tv_clock = false; |
intel_sdvo->is_lvds = false; |
|
/* SDVO requires XXX1 function may not exist unless it has XXX0 function.*/ |
2751,7 → 2875,6 |
struct drm_i915_private *dev_priv = dev->dev_private; |
struct intel_encoder *intel_encoder; |
struct intel_sdvo *intel_sdvo; |
u32 hotplug_mask; |
int i; |
intel_sdvo = kzalloc(sizeof(struct intel_sdvo), GFP_KERNEL); |
if (!intel_sdvo) |
2780,23 → 2903,12 |
} |
} |
|
hotplug_mask = 0; |
if (IS_G4X(dev)) { |
hotplug_mask = intel_sdvo->is_sdvob ? |
SDVOB_HOTPLUG_INT_STATUS_G4X : SDVOC_HOTPLUG_INT_STATUS_G4X; |
} else if (IS_GEN4(dev)) { |
hotplug_mask = intel_sdvo->is_sdvob ? |
SDVOB_HOTPLUG_INT_STATUS_I965 : SDVOC_HOTPLUG_INT_STATUS_I965; |
} else { |
hotplug_mask = intel_sdvo->is_sdvob ? |
SDVOB_HOTPLUG_INT_STATUS_I915 : SDVOC_HOTPLUG_INT_STATUS_I915; |
} |
|
intel_encoder->compute_config = intel_sdvo_compute_config; |
intel_encoder->disable = intel_disable_sdvo; |
intel_encoder->mode_set = intel_sdvo_mode_set; |
intel_encoder->enable = intel_enable_sdvo; |
intel_encoder->get_hw_state = intel_sdvo_get_hw_state; |
intel_encoder->get_config = intel_sdvo_get_config; |
|
/* In default case sdvo lvds is false */ |
if (!intel_sdvo_get_capabilities(intel_sdvo, &intel_sdvo->caps)) |