diff options
Diffstat (limited to 'drivers/gpu/drm/i915/display')
-rw-r--r-- | drivers/gpu/drm/i915/display/intel_ddi.c | 39 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/display/intel_display.c | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/display/intel_hdcp.c | 53 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/display/intel_hdcp.h | 2 |
4 files changed, 70 insertions, 30 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index b5ee84437f50..8eb2b3ec01ed 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -3575,7 +3575,8 @@ static void intel_enable_ddi(struct intel_encoder *encoder, /* Enable hdcp if it's desired */ if (conn_state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED) - intel_hdcp_enable(to_intel_connector(conn_state->connector)); + intel_hdcp_enable(to_intel_connector(conn_state->connector), + (u8)conn_state->hdcp_content_type); } static void intel_disable_ddi_dp(struct intel_encoder *encoder, @@ -3644,15 +3645,41 @@ static void intel_ddi_update_pipe(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state) { + struct intel_connector *connector = + to_intel_connector(conn_state->connector); + struct intel_hdcp *hdcp = &connector->hdcp; + bool content_protection_type_changed = + (conn_state->hdcp_content_type != hdcp->content_type && + conn_state->content_protection != + DRM_MODE_CONTENT_PROTECTION_UNDESIRED); + if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) intel_ddi_update_pipe_dp(encoder, crtc_state, conn_state); + /* + * During the HDCP encryption session if Type change is requested, + * disable the HDCP and reenable it with new TYPE value. + */ if (conn_state->content_protection == - DRM_MODE_CONTENT_PROTECTION_DESIRED) - intel_hdcp_enable(to_intel_connector(conn_state->connector)); - else if (conn_state->content_protection == - DRM_MODE_CONTENT_PROTECTION_UNDESIRED) - intel_hdcp_disable(to_intel_connector(conn_state->connector)); + DRM_MODE_CONTENT_PROTECTION_UNDESIRED || + content_protection_type_changed) + intel_hdcp_disable(connector); + + /* + * Mark the hdcp state as DESIRED after the hdcp disable of type + * change procedure. + */ + if (content_protection_type_changed) { + mutex_lock(&hdcp->mutex); + hdcp->value = DRM_MODE_CONTENT_PROTECTION_DESIRED; + schedule_work(&hdcp->prop_work); + mutex_unlock(&hdcp->mutex); + } + + if (conn_state->content_protection == + DRM_MODE_CONTENT_PROTECTION_DESIRED || + content_protection_type_changed) + intel_hdcp_enable(connector, (u8)conn_state->hdcp_content_type); } static void diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index fa60e64a15ff..b51d1ceb8739 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -29,7 +29,7 @@ #include <linux/intel-iommu.h> #include <linux/kernel.h> #include <linux/module.h> -#include <linux/reservation.h> +#include <linux/dma-resv.h> #include <linux/slab.h> #include <linux/vgaarb.h> @@ -12185,7 +12185,7 @@ static bool check_digital_port_conflicts(struct intel_atomic_state *state) case INTEL_OUTPUT_DDI: if (WARN_ON(!HAS_DDI(to_i915(dev)))) break; - /* else: fall through */ + /* else, fall through */ case INTEL_OUTPUT_DP: case INTEL_OUTPUT_HDMI: case INTEL_OUTPUT_EDP: @@ -14414,7 +14414,7 @@ intel_prepare_plane_fb(struct drm_plane *plane, if (ret < 0) return ret; - fence = reservation_object_get_excl_rcu(obj->base.resv); + fence = dma_resv_get_excl_rcu(obj->base.resv); if (fence) { add_rps_boost_after_vblank(new_state->crtc, fence); dma_fence_put(fence); diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c index db1db61fea24..6ec5ceeab601 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -867,7 +867,6 @@ static void intel_hdcp_prop_work(struct work_struct *work) prop_work); struct intel_connector *connector = intel_hdcp_to_connector(hdcp); struct drm_device *dev = connector->base.dev; - struct drm_connector_state *state; drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); mutex_lock(&hdcp->mutex); @@ -877,10 +876,9 @@ static void intel_hdcp_prop_work(struct work_struct *work) * those to UNDESIRED is handled by core. If value == UNDESIRED, * we're running just after hdcp has been disabled, so just exit */ - if (hdcp->value != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) { - state = connector->base.state; - state->content_protection = hdcp->value; - } + if (hdcp->value != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) + drm_hdcp_update_content_protection(&connector->base, + hdcp->value); mutex_unlock(&hdcp->mutex); drm_modeset_unlock(&dev->mode_config.connection_mutex); @@ -1751,14 +1749,15 @@ static const struct component_ops i915_hdcp_component_ops = { .unbind = i915_hdcp_component_unbind, }; -static inline int initialize_hdcp_port_data(struct intel_connector *connector) +static inline int initialize_hdcp_port_data(struct intel_connector *connector, + const struct intel_hdcp_shim *shim) { struct intel_hdcp *hdcp = &connector->hdcp; struct hdcp_port_data *data = &hdcp->port_data; data->port = connector->encoder->port; data->port_type = (u8)HDCP_PORT_TYPE_INTEGRATED; - data->protocol = (u8)hdcp->shim->protocol; + data->protocol = (u8)shim->protocol; data->k = 1; if (!data->streams) @@ -1808,12 +1807,13 @@ void intel_hdcp_component_init(struct drm_i915_private *dev_priv) } } -static void intel_hdcp2_init(struct intel_connector *connector) +static void intel_hdcp2_init(struct intel_connector *connector, + const struct intel_hdcp_shim *shim) { struct intel_hdcp *hdcp = &connector->hdcp; int ret; - ret = initialize_hdcp_port_data(connector); + ret = initialize_hdcp_port_data(connector, shim); if (ret) { DRM_DEBUG_KMS("Mei hdcp data init failed\n"); return; @@ -1832,23 +1832,28 @@ int intel_hdcp_init(struct intel_connector *connector, if (!shim) return -EINVAL; - ret = drm_connector_attach_content_protection_property(&connector->base); - if (ret) + if (is_hdcp2_supported(dev_priv)) + intel_hdcp2_init(connector, shim); + + ret = + drm_connector_attach_content_protection_property(&connector->base, + hdcp->hdcp2_supported); + if (ret) { + hdcp->hdcp2_supported = false; + kfree(hdcp->port_data.streams); return ret; + } hdcp->shim = shim; mutex_init(&hdcp->mutex); INIT_DELAYED_WORK(&hdcp->check_work, intel_hdcp_check_work); INIT_WORK(&hdcp->prop_work, intel_hdcp_prop_work); - - if (is_hdcp2_supported(dev_priv)) - intel_hdcp2_init(connector); init_waitqueue_head(&hdcp->cp_irq_queue); return 0; } -int intel_hdcp_enable(struct intel_connector *connector) +int intel_hdcp_enable(struct intel_connector *connector, u8 content_type) { struct intel_hdcp *hdcp = &connector->hdcp; unsigned long check_link_interval = DRM_HDCP_CHECK_PERIOD_MS; @@ -1859,6 +1864,7 @@ int intel_hdcp_enable(struct intel_connector *connector) mutex_lock(&hdcp->mutex); WARN_ON(hdcp->value == DRM_MODE_CONTENT_PROTECTION_ENABLED); + hdcp->content_type = content_type; /* * Considering that HDCP2.2 is more secure than HDCP1.4, If the setup @@ -1870,8 +1876,12 @@ int intel_hdcp_enable(struct intel_connector *connector) check_link_interval = DRM_HDCP2_CHECK_PERIOD_MS; } - /* When HDCP2.2 fails, HDCP1.4 will be attempted */ - if (ret && intel_hdcp_capable(connector)) { + /* + * When HDCP2.2 fails and Content Type is not Type1, HDCP1.4 will + * be attempted. + */ + if (ret && intel_hdcp_capable(connector) && + hdcp->content_type != DRM_MODE_HDCP_CONTENT_TYPE1) { ret = _intel_hdcp_enable(connector); } @@ -1953,12 +1963,15 @@ void intel_hdcp_atomic_check(struct drm_connector *connector, /* * Nothing to do if the state didn't change, or HDCP was activated since - * the last commit + * the last commit. And also no change in hdcp content type. */ if (old_cp == new_cp || (old_cp == DRM_MODE_CONTENT_PROTECTION_DESIRED && - new_cp == DRM_MODE_CONTENT_PROTECTION_ENABLED)) - return; + new_cp == DRM_MODE_CONTENT_PROTECTION_ENABLED)) { + if (old_state->hdcp_content_type == + new_state->hdcp_content_type) + return; + } crtc_state = drm_atomic_get_new_crtc_state(new_state->state, new_state->crtc); diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.h b/drivers/gpu/drm/i915/display/intel_hdcp.h index be8da85c866a..13555b054930 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.h +++ b/drivers/gpu/drm/i915/display/intel_hdcp.h @@ -21,7 +21,7 @@ void intel_hdcp_atomic_check(struct drm_connector *connector, struct drm_connector_state *new_state); int intel_hdcp_init(struct intel_connector *connector, const struct intel_hdcp_shim *hdcp_shim); -int intel_hdcp_enable(struct intel_connector *connector); +int intel_hdcp_enable(struct intel_connector *connector, u8 content_type); int intel_hdcp_disable(struct intel_connector *connector); bool is_hdcp_supported(struct drm_i915_private *dev_priv, enum port port); bool intel_hdcp_capable(struct intel_connector *connector); |