Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 6937 → Rev 7144

/drivers/video/drm/i915/intel_hdmi.c
836,6 → 836,22
intel_hdmi_set_hdmi_infoframe(encoder, adjusted_mode);
}
 
void intel_dp_dual_mode_set_tmds_output(struct intel_hdmi *hdmi, bool enable)
{
struct drm_i915_private *dev_priv = to_i915(intel_hdmi_to_dev(hdmi));
struct i2c_adapter *adapter =
intel_gmbus_get_adapter(dev_priv, hdmi->ddc_bus);
 
if (hdmi->dp_dual_mode.type < DRM_DP_DUAL_MODE_TYPE2_DVI)
return;
 
DRM_DEBUG_KMS("%s DP dual mode adaptor TMDS output\n",
enable ? "Enabling" : "Disabling");
 
drm_dp_dual_mode_set_tmds_output(hdmi->dp_dual_mode.type,
adapter, enable);
}
 
static void intel_hdmi_prepare(struct intel_encoder *encoder)
{
struct drm_device *dev = encoder->base.dev;
845,6 → 861,8
const struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode;
u32 hdmi_val;
 
intel_dp_dual_mode_set_tmds_output(intel_hdmi, true);
 
hdmi_val = SDVO_ENCODING_HDMI;
if (!HAS_PCH_SPLIT(dev) && crtc->config->limited_color_range)
hdmi_val |= HDMI_COLOR_RANGE_16_235;
1143,6 → 1161,8
}
 
intel_hdmi->set_infoframes(&encoder->base, false, NULL);
 
intel_dp_dual_mode_set_tmds_output(intel_hdmi, false);
}
 
static void g4x_disable_hdmi(struct intel_encoder *encoder)
1168,27 → 1188,42
intel_disable_hdmi(encoder);
}
 
static int hdmi_port_clock_limit(struct intel_hdmi *hdmi, bool respect_dvi_limit)
static int intel_hdmi_source_max_tmds_clock(struct drm_i915_private *dev_priv)
{
struct drm_device *dev = intel_hdmi_to_dev(hdmi);
 
if ((respect_dvi_limit && !hdmi->has_hdmi_sink) || IS_G4X(dev))
if (IS_G4X(dev_priv))
return 165000;
else if (IS_HASWELL(dev) || INTEL_INFO(dev)->gen >= 8)
else if (IS_HASWELL(dev_priv) || INTEL_INFO(dev_priv)->gen >= 8)
return 300000;
else
return 225000;
}
 
static int hdmi_port_clock_limit(struct intel_hdmi *hdmi,
bool respect_downstream_limits)
{
struct drm_device *dev = intel_hdmi_to_dev(hdmi);
int max_tmds_clock = intel_hdmi_source_max_tmds_clock(to_i915(dev));
 
if (respect_downstream_limits) {
if (hdmi->dp_dual_mode.max_tmds_clock)
max_tmds_clock = min(max_tmds_clock,
hdmi->dp_dual_mode.max_tmds_clock);
if (!hdmi->has_hdmi_sink)
max_tmds_clock = min(max_tmds_clock, 165000);
}
 
return max_tmds_clock;
}
 
static enum drm_mode_status
hdmi_port_clock_valid(struct intel_hdmi *hdmi,
int clock, bool respect_dvi_limit)
int clock, bool respect_downstream_limits)
{
struct drm_device *dev = intel_hdmi_to_dev(hdmi);
 
if (clock < 25000)
return MODE_CLOCK_LOW;
if (clock > hdmi_port_clock_limit(hdmi, respect_dvi_limit))
if (clock > hdmi_port_clock_limit(hdmi, respect_downstream_limits))
return MODE_CLOCK_HIGH;
 
/* BXT DPLL can't generate 223-240 MHz */
1210,11 → 1245,19
struct drm_device *dev = intel_hdmi_to_dev(hdmi);
enum drm_mode_status status;
int clock;
int max_dotclk = to_i915(connector->dev)->max_dotclk_freq;
 
if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
return MODE_NO_DBLESCAN;
 
clock = mode->clock;
 
if ((mode->flags & DRM_MODE_FLAG_3D_MASK) == DRM_MODE_FLAG_3D_FRAME_PACKING)
clock *= 2;
 
if (clock > max_dotclk)
return MODE_CLOCK_HIGH;
 
if (mode->flags & DRM_MODE_FLAG_DBLCLK)
clock *= 2;
 
1304,7 → 1347,7
* within limits.
*/
if (pipe_config->pipe_bpp > 8*3 && pipe_config->has_hdmi_sink &&
hdmi_port_clock_valid(intel_hdmi, clock_12bpc, false) == MODE_OK &&
hdmi_port_clock_valid(intel_hdmi, clock_12bpc, true) == MODE_OK &&
hdmi_12bpc_possible(pipe_config)) {
DRM_DEBUG_KMS("picking bpc to 12 for HDMI output\n");
desired_bpp = 12*3;
1344,10 → 1387,35
intel_hdmi->has_audio = false;
intel_hdmi->rgb_quant_range_selectable = false;
 
intel_hdmi->dp_dual_mode.type = DRM_DP_DUAL_MODE_NONE;
intel_hdmi->dp_dual_mode.max_tmds_clock = 0;
 
kfree(to_intel_connector(connector)->detect_edid);
to_intel_connector(connector)->detect_edid = NULL;
}
 
static void
intel_hdmi_dp_dual_mode_detect(struct drm_connector *connector)
{
struct drm_i915_private *dev_priv = to_i915(connector->dev);
struct intel_hdmi *hdmi = intel_attached_hdmi(connector);
struct i2c_adapter *adapter =
intel_gmbus_get_adapter(dev_priv, hdmi->ddc_bus);
enum drm_dp_dual_mode_type type = drm_dp_dual_mode_detect(adapter);
 
if (type == DRM_DP_DUAL_MODE_NONE ||
type == DRM_DP_DUAL_MODE_UNKNOWN)
return;
 
hdmi->dp_dual_mode.type = type;
hdmi->dp_dual_mode.max_tmds_clock =
drm_dp_dual_mode_max_tmds_clock(type, adapter);
 
DRM_DEBUG_KMS("DP dual mode adaptor (%s) detected (max TMDS clock: %d kHz)\n",
drm_dp_get_dual_mode_type_name(type),
hdmi->dp_dual_mode.max_tmds_clock);
}
 
static bool
intel_hdmi_set_edid(struct drm_connector *connector, bool force)
{
1363,6 → 1431,8
intel_gmbus_get_adapter(dev_priv,
intel_hdmi->ddc_bus));
 
intel_hdmi_dp_dual_mode_detect(connector);
 
intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS);
}
 
2049,6 → 2119,11
enum port port = intel_dig_port->port;
uint8_t alternate_ddc_pin;
 
if (WARN(intel_dig_port->max_lanes < 4,
"Not enough lanes (%d) for HDMI on port %c\n",
intel_dig_port->max_lanes, port_name(port)))
return;
 
drm_connector_init(dev, connector, &intel_hdmi_connector_funcs,
DRM_MODE_CONNECTOR_HDMIA);
drm_connector_helper_add(connector, &intel_hdmi_connector_helper_funcs);
2232,6 → 2307,7
intel_dig_port->port = port;
intel_dig_port->hdmi.hdmi_reg = hdmi_reg;
intel_dig_port->dp.output_reg = INVALID_MMIO_REG;
intel_dig_port->max_lanes = 4;
 
intel_hdmi_init_connector(intel_dig_port, intel_connector);
}