From 85c675d0d09a45a135bddd15d7b385f8758c32fb Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 18 May 2024 19:35:05 +0200 Subject: Adding upstream version 6.7.7. Signed-off-by: Daniel Baumann --- drivers/gpu/drm/i915/display/intel_hdmi.c | 123 ++++++++++-------------------- 1 file changed, 40 insertions(+), 83 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_hdmi.c') diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c index bc975918e0..bfa456fa7d 100644 --- a/drivers/gpu/drm/i915/display/intel_hdmi.c +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c @@ -1240,26 +1240,23 @@ static void hsw_set_infoframes(struct intel_encoder *encoder, void intel_dp_dual_mode_set_tmds_output(struct intel_hdmi *hdmi, bool enable) { struct drm_i915_private *dev_priv = intel_hdmi_to_i915(hdmi); - struct i2c_adapter *adapter; + struct i2c_adapter *ddc = hdmi->attached_connector->base.ddc; if (hdmi->dp_dual_mode.type < DRM_DP_DUAL_MODE_TYPE2_DVI) return; - adapter = intel_gmbus_get_adapter(dev_priv, hdmi->ddc_bus); - drm_dbg_kms(&dev_priv->drm, "%s DP dual mode adaptor TMDS output\n", enable ? "Enabling" : "Disabling"); - drm_dp_dual_mode_set_tmds_output(&dev_priv->drm, hdmi->dp_dual_mode.type, adapter, enable); + drm_dp_dual_mode_set_tmds_output(&dev_priv->drm, + hdmi->dp_dual_mode.type, ddc, enable); } static int intel_hdmi_hdcp_read(struct intel_digital_port *dig_port, unsigned int offset, void *buffer, size_t size) { - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); struct intel_hdmi *hdmi = &dig_port->hdmi; - struct i2c_adapter *adapter = intel_gmbus_get_adapter(i915, - hdmi->ddc_bus); + struct i2c_adapter *ddc = hdmi->attached_connector->base.ddc; int ret; u8 start = offset & 0xff; struct i2c_msg msgs[] = { @@ -1276,7 +1273,7 @@ static int intel_hdmi_hdcp_read(struct intel_digital_port *dig_port, .buf = buffer } }; - ret = i2c_transfer(adapter, msgs, ARRAY_SIZE(msgs)); + ret = i2c_transfer(ddc, msgs, ARRAY_SIZE(msgs)); if (ret == ARRAY_SIZE(msgs)) return 0; return ret >= 0 ? -EIO : ret; @@ -1285,10 +1282,8 @@ static int intel_hdmi_hdcp_read(struct intel_digital_port *dig_port, static int intel_hdmi_hdcp_write(struct intel_digital_port *dig_port, unsigned int offset, void *buffer, size_t size) { - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); struct intel_hdmi *hdmi = &dig_port->hdmi; - struct i2c_adapter *adapter = intel_gmbus_get_adapter(i915, - hdmi->ddc_bus); + struct i2c_adapter *ddc = hdmi->attached_connector->base.ddc; int ret; u8 *write_buf; struct i2c_msg msg; @@ -1305,7 +1300,7 @@ static int intel_hdmi_hdcp_write(struct intel_digital_port *dig_port, msg.len = size + 1, msg.buf = write_buf; - ret = i2c_transfer(adapter, &msg, 1); + ret = i2c_transfer(ddc, &msg, 1); if (ret == 1) ret = 0; else if (ret >= 0) @@ -1321,8 +1316,7 @@ int intel_hdmi_hdcp_write_an_aksv(struct intel_digital_port *dig_port, { struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); struct intel_hdmi *hdmi = &dig_port->hdmi; - struct i2c_adapter *adapter = intel_gmbus_get_adapter(i915, - hdmi->ddc_bus); + struct i2c_adapter *ddc = hdmi->attached_connector->base.ddc; int ret; ret = intel_hdmi_hdcp_write(dig_port, DRM_HDCP_DDC_AN, an, @@ -1333,7 +1327,7 @@ int intel_hdmi_hdcp_write_an_aksv(struct intel_digital_port *dig_port, return ret; } - ret = intel_gmbus_output_aksv(adapter); + ret = intel_gmbus_output_aksv(ddc); if (ret < 0) { drm_dbg_kms(&i915->drm, "Failed to output aksv (%d)\n", ret); return ret; @@ -1665,9 +1659,10 @@ intel_hdmi_hdcp2_wait_for_msg(struct intel_digital_port *dig_port, } static -int intel_hdmi_hdcp2_write_msg(struct intel_digital_port *dig_port, +int intel_hdmi_hdcp2_write_msg(struct intel_connector *connector, void *buf, size_t size) { + struct intel_digital_port *dig_port = intel_attached_dig_port(connector); unsigned int offset; offset = HDCP_2_2_HDMI_REG_WR_MSG_OFFSET; @@ -1675,9 +1670,10 @@ int intel_hdmi_hdcp2_write_msg(struct intel_digital_port *dig_port, } static -int intel_hdmi_hdcp2_read_msg(struct intel_digital_port *dig_port, +int intel_hdmi_hdcp2_read_msg(struct intel_connector *connector, u8 msg_id, void *buf, size_t size) { + struct intel_digital_port *dig_port = intel_attached_dig_port(connector); struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); struct intel_hdmi *hdmi = &dig_port->hdmi; struct intel_hdcp *hdcp = &hdmi->attached_connector->hdcp; @@ -1733,9 +1729,10 @@ int intel_hdmi_hdcp2_check_link(struct intel_digital_port *dig_port, } static -int intel_hdmi_hdcp2_capable(struct intel_digital_port *dig_port, +int intel_hdmi_hdcp2_capable(struct intel_connector *connector, bool *capable) { + struct intel_digital_port *dig_port = intel_attached_dig_port(connector); u8 hdcp2_version; int ret; @@ -2404,9 +2401,10 @@ 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(to_intel_connector(connector)); struct intel_encoder *encoder = &hdmi_to_dig_port(hdmi)->base; - 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(&dev_priv->drm, adapter); + struct i2c_adapter *ddc = connector->ddc; + enum drm_dp_dual_mode_type type; + + type = drm_dp_dual_mode_detect(&dev_priv->drm, ddc); /* * Type 1 DVI adaptors are not required to implement any @@ -2433,7 +2431,7 @@ intel_hdmi_dp_dual_mode_detect(struct drm_connector *connector) hdmi->dp_dual_mode.type = type; hdmi->dp_dual_mode.max_tmds_clock = - drm_dp_dual_mode_max_tmds_clock(&dev_priv->drm, type, adapter); + drm_dp_dual_mode_max_tmds_clock(&dev_priv->drm, type, ddc); drm_dbg_kms(&dev_priv->drm, "DP dual mode adaptor (%s) detected (max TMDS clock: %d kHz)\n", @@ -2454,24 +2452,21 @@ intel_hdmi_set_edid(struct drm_connector *connector) { struct drm_i915_private *dev_priv = to_i915(connector->dev); struct intel_hdmi *intel_hdmi = intel_attached_hdmi(to_intel_connector(connector)); + struct i2c_adapter *ddc = connector->ddc; intel_wakeref_t wakeref; const struct drm_edid *drm_edid; - const struct edid *edid; bool connected = false; - struct i2c_adapter *i2c; wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS); - i2c = intel_gmbus_get_adapter(dev_priv, intel_hdmi->ddc_bus); + drm_edid = drm_edid_read_ddc(connector, ddc); - drm_edid = drm_edid_read_ddc(connector, i2c); - - if (!drm_edid && !intel_gmbus_is_forced_bit(i2c)) { + if (!drm_edid && !intel_gmbus_is_forced_bit(ddc)) { drm_dbg_kms(&dev_priv->drm, "HDMI GMBUS EDID read failed, retry using GPIO bit-banging\n"); - intel_gmbus_force_bit(i2c, true); - drm_edid = drm_edid_read_ddc(connector, i2c); - intel_gmbus_force_bit(i2c, false); + intel_gmbus_force_bit(ddc, true); + drm_edid = drm_edid_read_ddc(connector, ddc); + intel_gmbus_force_bit(ddc, false); } /* Below we depend on display info having been updated */ @@ -2479,9 +2474,7 @@ intel_hdmi_set_edid(struct drm_connector *connector) to_intel_connector(connector)->detect_edid = drm_edid; - /* FIXME: Get rid of drm_edid_raw() */ - edid = drm_edid_raw(drm_edid); - if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) { + if (drm_edid_is_digital(drm_edid)) { intel_hdmi_dp_dual_mode_detect(connector); connected = true; @@ -2489,7 +2482,8 @@ intel_hdmi_set_edid(struct drm_connector *connector) intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS, wakeref); - cec_notifier_set_phys_addr_from_edid(intel_hdmi->cec_notifier, edid); + cec_notifier_set_phys_addr(intel_hdmi->cec_notifier, + connector->display_info.source_physical_address); return connected; } @@ -2506,7 +2500,7 @@ intel_hdmi_detect(struct drm_connector *connector, bool force) drm_dbg_kms(&dev_priv->drm, "[CONNECTOR:%d:%s]\n", connector->base.id, connector->name); - if (!INTEL_DISPLAY_ENABLED(dev_priv)) + if (!intel_display_device_enabled(dev_priv)) return connector_status_disconnected; wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS); @@ -2526,12 +2520,6 @@ out: if (status != connector_status_connected) cec_notifier_phys_addr_invalidate(intel_hdmi->cec_notifier); - /* - * Make sure the refs for power wells enabled during detect are - * dropped to avoid a new detect cycle triggered by HPD polling. - */ - intel_display_power_flush_work(dev_priv); - return status; } @@ -2557,37 +2545,6 @@ static int intel_hdmi_get_modes(struct drm_connector *connector) return drm_edid_connector_add_modes(connector); } -static struct i2c_adapter * -intel_hdmi_get_i2c_adapter(struct drm_connector *connector) -{ - struct drm_i915_private *dev_priv = to_i915(connector->dev); - struct intel_hdmi *intel_hdmi = intel_attached_hdmi(to_intel_connector(connector)); - - return intel_gmbus_get_adapter(dev_priv, intel_hdmi->ddc_bus); -} - -static void intel_hdmi_create_i2c_symlink(struct drm_connector *connector) -{ - struct drm_i915_private *i915 = to_i915(connector->dev); - struct i2c_adapter *adapter = intel_hdmi_get_i2c_adapter(connector); - struct kobject *i2c_kobj = &adapter->dev.kobj; - struct kobject *connector_kobj = &connector->kdev->kobj; - int ret; - - ret = sysfs_create_link(connector_kobj, i2c_kobj, i2c_kobj->name); - if (ret) - drm_err(&i915->drm, "Failed to create i2c symlink (%d)\n", ret); -} - -static void intel_hdmi_remove_i2c_symlink(struct drm_connector *connector) -{ - struct i2c_adapter *adapter = intel_hdmi_get_i2c_adapter(connector); - struct kobject *i2c_kobj = &adapter->dev.kobj; - struct kobject *connector_kobj = &connector->kdev->kobj; - - sysfs_remove_link(connector_kobj, i2c_kobj->name); -} - static int intel_hdmi_connector_register(struct drm_connector *connector) { @@ -2597,8 +2554,6 @@ intel_hdmi_connector_register(struct drm_connector *connector) if (ret) return ret; - intel_hdmi_create_i2c_symlink(connector); - return ret; } @@ -2608,7 +2563,6 @@ static void intel_hdmi_connector_unregister(struct drm_connector *connector) cec_notifier_conn_unregister(n); - intel_hdmi_remove_i2c_symlink(connector); intel_connector_unregister(connector); } @@ -2922,13 +2876,17 @@ get_encoder_by_ddc_pin(struct intel_encoder *encoder, u8 ddc_pin) struct intel_encoder *other; for_each_intel_encoder(&i915->drm, other) { + struct intel_connector *connector; + if (other == encoder) continue; if (!intel_encoder_is_dig_port(other)) continue; - if (enc_to_dig_port(other)->hdmi.ddc_bus == ddc_pin) + connector = enc_to_dig_port(other)->hdmi.attached_connector; + + if (connector && connector->base.ddc == intel_gmbus_get_adapter(i915, ddc_pin)) return other; } @@ -3020,9 +2978,9 @@ void intel_hdmi_init_connector(struct intel_digital_port *dig_port, struct intel_encoder *intel_encoder = &dig_port->base; struct drm_device *dev = intel_encoder->base.dev; struct drm_i915_private *dev_priv = to_i915(dev); - struct i2c_adapter *ddc; enum port port = intel_encoder->port; struct cec_connector_info conn_info; + u8 ddc_pin; drm_dbg_kms(&dev_priv->drm, "Adding HDMI connector on [ENCODER:%d:%s]\n", @@ -3037,16 +2995,15 @@ void intel_hdmi_init_connector(struct intel_digital_port *dig_port, intel_encoder->base.name)) return; - intel_hdmi->ddc_bus = intel_hdmi_ddc_pin(intel_encoder); - if (!intel_hdmi->ddc_bus) + ddc_pin = intel_hdmi_ddc_pin(intel_encoder); + if (!ddc_pin) return; - ddc = intel_gmbus_get_adapter(dev_priv, intel_hdmi->ddc_bus); - drm_connector_init_with_ddc(dev, connector, &intel_hdmi_connector_funcs, DRM_MODE_CONNECTOR_HDMIA, - ddc); + intel_gmbus_get_adapter(dev_priv, ddc_pin)); + drm_connector_helper_add(connector, &intel_hdmi_connector_helper_funcs); if (DISPLAY_VER(dev_priv) < 12) -- cgit v1.2.3