1153,20 → 1153,21 |
pipe_config->pixel_multiplier = |
intel_sdvo_get_pixel_multiplier(adjusted_mode); |
|
pipe_config->has_hdmi_sink = intel_sdvo->has_hdmi_monitor; |
|
if (intel_sdvo->color_range_auto) { |
/* See CEA-861-E - 5.1 Default Encoding Parameters */ |
/* FIXME: This bit is only valid when using TMDS encoding and 8 |
* bit per color mode. */ |
if (intel_sdvo->has_hdmi_monitor && |
if (pipe_config->has_hdmi_sink && |
drm_match_cea_mode(adjusted_mode) > 1) |
intel_sdvo->color_range = HDMI_COLOR_RANGE_16_235; |
else |
intel_sdvo->color_range = 0; |
pipe_config->limited_color_range = true; |
} else { |
if (pipe_config->has_hdmi_sink && |
intel_sdvo->color_range == HDMI_COLOR_RANGE_16_235) |
pipe_config->limited_color_range = true; |
} |
|
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); |
1174,7 → 1175,7 |
return true; |
} |
|
static void intel_sdvo_mode_set(struct intel_encoder *intel_encoder) |
static void intel_sdvo_pre_enable(struct intel_encoder *intel_encoder) |
{ |
struct drm_device *dev = intel_encoder->base.dev; |
struct drm_i915_private *dev_priv = dev->dev_private; |
1223,7 → 1224,7 |
if (!intel_sdvo_set_target_input(intel_sdvo)) |
return; |
|
if (intel_sdvo->has_hdmi_monitor) { |
if (crtc->config.has_hdmi_sink) { |
intel_sdvo_set_encode(intel_sdvo, SDVO_ENCODE_HDMI); |
intel_sdvo_set_colorimetry(intel_sdvo, |
SDVO_COLORIMETRY_RGB256); |
1258,8 → 1259,8 |
/* The real mode polarity is set by the SDVO commands, using |
* struct intel_sdvo_dtd. */ |
sdvox = SDVO_VSYNC_ACTIVE_HIGH | SDVO_HSYNC_ACTIVE_HIGH; |
if (!HAS_PCH_SPLIT(dev) && intel_sdvo->is_hdmi) |
sdvox |= intel_sdvo->color_range; |
if (!HAS_PCH_SPLIT(dev) && crtc->config.limited_color_range) |
sdvox |= HDMI_COLOR_RANGE_16_235; |
if (INTEL_INFO(dev)->gen < 5) |
sdvox |= SDVO_BORDER_ENABLE; |
} else { |
1349,6 → 1350,8 |
u8 val; |
bool ret; |
|
sdvox = I915_READ(intel_sdvo->sdvo_reg); |
|
ret = intel_sdvo_get_input_timing(intel_sdvo, &dtd); |
if (!ret) { |
/* Some sdvo encoders are not spec compliant and don't |
1377,13 → 1380,14 |
* 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; |
} |
|
dotclock = pipe_config->port_clock / pipe_config->pixel_multiplier; |
dotclock = pipe_config->port_clock; |
if (pipe_config->pixel_multiplier) |
dotclock /= pipe_config->pixel_multiplier; |
|
if (HAS_PCH_SPLIT(dev)) |
ironlake_check_encoder_dotclock(pipe_config, dotclock); |
1406,6 → 1410,15 |
} |
} |
|
if (sdvox & HDMI_COLOR_RANGE_16_235) |
pipe_config->limited_color_range = true; |
|
if (intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_ENCODE, |
&val, 1)) { |
if (val == SDVO_ENCODE_HDMI) |
pipe_config->has_hdmi_sink = true; |
} |
|
WARN(encoder_pixel_multiplier != pipe_config->pixel_multiplier, |
"SDVO pixel multiplier mismatch, port: %i, encoder: %i\n", |
pipe_config->pixel_multiplier, encoder_pixel_multiplier); |
1461,7 → 1474,7 |
u32 temp; |
bool input1, input2; |
int i; |
u8 status; |
bool success; |
|
temp = I915_READ(intel_sdvo->sdvo_reg); |
if ((temp & SDVO_ENABLE) == 0) { |
1475,12 → 1488,12 |
for (i = 0; i < 2; i++) |
intel_wait_for_vblank(dev, intel_crtc->pipe); |
|
status = intel_sdvo_get_trained_inputs(intel_sdvo, &input1, &input2); |
success = intel_sdvo_get_trained_inputs(intel_sdvo, &input1, &input2); |
/* Warn if the device reported failure to sync. |
* A lot of SDVO devices fail to notify of sync, but it's |
* a given it the status is a success, we succeeded. |
*/ |
if (status == SDVO_CMD_STATUS_SUCCESS && !input1) { |
if (success && !input1) { |
DRM_DEBUG_KMS("First %s output reported failure to " |
"sync\n", SDVO_NAME(intel_sdvo)); |
} |
1732,7 → 1745,7 |
enum drm_connector_status ret; |
|
DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", |
connector->base.id, drm_get_connector_name(connector)); |
connector->base.id, connector->name); |
|
if (!intel_sdvo_get_value(intel_sdvo, |
SDVO_CMD_GET_ATTACHED_DISPLAYS, |
1794,7 → 1807,7 |
struct edid *edid; |
|
DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", |
connector->base.id, drm_get_connector_name(connector)); |
connector->base.id, connector->name); |
|
/* set the bus switch and get the modes */ |
edid = intel_sdvo_get_edid(connector); |
1892,7 → 1905,7 |
int i; |
|
DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", |
connector->base.id, drm_get_connector_name(connector)); |
connector->base.id, connector->name); |
|
/* Read the list of supported input resolutions for the selected TV |
* format. |
1929,7 → 1942,7 |
struct drm_display_mode *newmode; |
|
DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", |
connector->base.id, drm_get_connector_name(connector)); |
connector->base.id, connector->name); |
|
/* |
* Fetch modes from VBT. For SDVO prefer the VBT mode since some |
2382,15 → 2395,33 |
} |
|
static void |
intel_sdvo_connector_unregister(struct intel_connector *intel_connector) |
{ |
struct drm_connector *drm_connector; |
struct intel_sdvo *sdvo_encoder; |
|
drm_connector = &intel_connector->base; |
sdvo_encoder = intel_attached_sdvo(&intel_connector->base); |
|
intel_connector_unregister(intel_connector); |
} |
|
static int |
intel_sdvo_connector_init(struct intel_sdvo_connector *connector, |
struct intel_sdvo *encoder) |
{ |
drm_connector_init(encoder->base.base.dev, |
&connector->base.base, |
struct drm_connector *drm_connector; |
int ret; |
|
drm_connector = &connector->base.base; |
ret = drm_connector_init(encoder->base.base.dev, |
drm_connector, |
&intel_sdvo_connector_funcs, |
connector->base.base.connector_type); |
if (ret < 0) |
return ret; |
|
drm_connector_helper_add(&connector->base.base, |
drm_connector_helper_add(drm_connector, |
&intel_sdvo_connector_helper_funcs); |
|
connector->base.base.interlace_allowed = 1; |
2397,9 → 2428,11 |
connector->base.base.doublescan_allowed = 0; |
connector->base.base.display_info.subpixel_order = SubPixelHorizontalRGB; |
connector->base.get_hw_state = intel_sdvo_connector_get_hw_state; |
connector->base.unregister = intel_sdvo_connector_unregister; |
|
intel_connector_attach_encoder(&connector->base, &encoder->base); |
drm_sysfs_connector_add(&connector->base.base); |
|
return ret; |
} |
|
static void |
2459,7 → 2492,11 |
intel_sdvo->is_hdmi = true; |
} |
|
intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); |
if (intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo) < 0) { |
kfree(intel_sdvo_connector); |
return false; |
} |
|
if (intel_sdvo->is_hdmi) |
intel_sdvo_add_hdmi_properties(intel_sdvo, intel_sdvo_connector); |
|
2490,7 → 2527,10 |
|
intel_sdvo->is_tv = true; |
|
intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); |
if (intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo) < 0) { |
kfree(intel_sdvo_connector); |
return false; |
} |
|
if (!intel_sdvo_tv_create_property(intel_sdvo, intel_sdvo_connector, type)) |
goto err; |
2501,7 → 2541,7 |
return true; |
|
err: |
drm_sysfs_connector_remove(connector); |
drm_connector_unregister(connector); |
intel_sdvo_destroy(connector); |
return false; |
} |
2534,8 → 2574,11 |
intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB1; |
} |
|
intel_sdvo_connector_init(intel_sdvo_connector, |
intel_sdvo); |
if (intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo) < 0) { |
kfree(intel_sdvo_connector); |
return false; |
} |
|
return true; |
} |
|
2566,7 → 2609,11 |
intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1; |
} |
|
intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); |
if (intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo) < 0) { |
kfree(intel_sdvo_connector); |
return false; |
} |
|
if (!intel_sdvo_create_enhance_property(intel_sdvo, intel_sdvo_connector)) |
goto err; |
|
2573,7 → 2620,7 |
return true; |
|
err: |
drm_sysfs_connector_remove(connector); |
drm_connector_unregister(connector); |
intel_sdvo_destroy(connector); |
return false; |
} |
2646,7 → 2693,7 |
list_for_each_entry_safe(connector, tmp, |
&dev->mode_config.connector_list, head) { |
if (intel_attached_encoder(connector) == &intel_sdvo->base) { |
drm_sysfs_connector_remove(connector); |
drm_connector_unregister(connector); |
intel_sdvo_destroy(connector); |
} |
} |
2947,7 → 2994,7 |
|
intel_encoder->compute_config = intel_sdvo_compute_config; |
intel_encoder->disable = intel_disable_sdvo; |
intel_encoder->mode_set = intel_sdvo_mode_set; |
intel_encoder->pre_enable = intel_sdvo_pre_enable; |
intel_encoder->enable = intel_enable_sdvo; |
intel_encoder->get_hw_state = intel_sdvo_get_hw_state; |
intel_encoder->get_config = intel_sdvo_get_config; |
2980,7 → 3027,7 |
* simplistic anyway to express such constraints, so just give up on |
* cloning for SDVO encoders. |
*/ |
intel_sdvo->base.cloneable = false; |
intel_sdvo->base.cloneable = 0; |
|
intel_sdvo_select_ddc_bus(dev_priv, intel_sdvo, sdvo_reg); |
|