Merge tag 'drm-misc-next-2019-08-08' of git://anongit.freedesktop.org/drm/drm-misc...
[linux-2.6-microblaze.git] / drivers / gpu / drm / i915 / display / intel_hdcp.c
index a78139f..845eb8f 100644 (file)
@@ -869,7 +869,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);
@@ -879,10 +878,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);
@@ -1754,14 +1752,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)
@@ -1811,12 +1810,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;
@@ -1835,23 +1835,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;
@@ -1862,6 +1867,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
@@ -1873,8 +1879,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);
        }
 
@@ -1956,12 +1966,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);