drm/i915/hdcp: Remove enforce_type0 check outside loop
[linux-2.6-microblaze.git] / drivers / gpu / drm / i915 / display / intel_hdcp.c
index 2984d28..73b7e7e 100644 (file)
@@ -23,6 +23,7 @@
 #include "intel_display_power_well.h"
 #include "intel_display_types.h"
 #include "intel_hdcp.h"
+#include "intel_hdcp_gsc.h"
 #include "intel_hdcp_regs.h"
 #include "intel_pcode.h"
 
@@ -83,6 +84,9 @@ intel_hdcp_required_content_stream(struct intel_digital_port *dig_port)
        if (dig_port->hdcp_auth_status)
                return 0;
 
+       if (!dig_port->hdcp_mst_type1_capable)
+               enforce_type0 = true;
+
        drm_connector_list_iter_begin(&i915->drm, &conn_iter);
        for_each_intel_connector_iter(connector, &conn_iter) {
                if (connector->base.status == connector_status_disconnected)
@@ -95,9 +99,6 @@ intel_hdcp_required_content_stream(struct intel_digital_port *dig_port)
                if (conn_dig_port != dig_port)
                        continue;
 
-               if (!enforce_type0 && !dig_port->hdcp_mst_type1_capable)
-                       enforce_type0 = true;
-
                data->streams[data->k].stream_id = intel_conn_to_vcpi(connector);
                data->k++;
 
@@ -209,7 +210,16 @@ bool intel_hdcp2_capable(struct intel_connector *connector)
        if (!hdcp->hdcp2_supported)
                return false;
 
-       /* MEI interface is solid */
+       /* If MTL+ make sure gsc is loaded and proxy is setup */
+       if (intel_hdcp_gsc_cs_required(dev_priv)) {
+               struct intel_gt *gt = dev_priv->media_gt;
+               struct intel_gsc_uc *gsc = gt ? &gt->uc.gsc : NULL;
+
+               if (!gsc || !intel_uc_fw_is_running(&gsc->fw))
+                       return false;
+       }
+
+       /* MEI/GSC interface is solid depending on which is used */
        mutex_lock(&dev_priv->display.hdcp.comp_mutex);
        if (!dev_priv->display.hdcp.comp_added ||  !dev_priv->display.hdcp.master) {
                mutex_unlock(&dev_priv->display.hdcp.comp_mutex);
@@ -1142,18 +1152,18 @@ hdcp2_prepare_ake_init(struct intel_connector *connector,
        struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
        struct hdcp_port_data *data = &dig_port->hdcp_port_data;
        struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-       struct i915_hdcp_comp_master *comp;
+       struct i915_hdcp_master *arbiter;
        int ret;
 
        mutex_lock(&dev_priv->display.hdcp.comp_mutex);
-       comp = dev_priv->display.hdcp.master;
+       arbiter = dev_priv->display.hdcp.master;
 
-       if (!comp || !comp->ops) {
+       if (!arbiter || !arbiter->ops) {
                mutex_unlock(&dev_priv->display.hdcp.comp_mutex);
                return -EINVAL;
        }
 
-       ret = comp->ops->initiate_hdcp2_session(comp->mei_dev, data, ake_data);
+       ret = arbiter->ops->initiate_hdcp2_session(arbiter->hdcp_dev, data, ake_data);
        if (ret)
                drm_dbg_kms(&dev_priv->drm, "Prepare_ake_init failed. %d\n",
                            ret);
@@ -1172,18 +1182,18 @@ hdcp2_verify_rx_cert_prepare_km(struct intel_connector *connector,
        struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
        struct hdcp_port_data *data = &dig_port->hdcp_port_data;
        struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-       struct i915_hdcp_comp_master *comp;
+       struct i915_hdcp_master *arbiter;
        int ret;
 
        mutex_lock(&dev_priv->display.hdcp.comp_mutex);
-       comp = dev_priv->display.hdcp.master;
+       arbiter = dev_priv->display.hdcp.master;
 
-       if (!comp || !comp->ops) {
+       if (!arbiter || !arbiter->ops) {
                mutex_unlock(&dev_priv->display.hdcp.comp_mutex);
                return -EINVAL;
        }
 
-       ret = comp->ops->verify_receiver_cert_prepare_km(comp->mei_dev, data,
+       ret = arbiter->ops->verify_receiver_cert_prepare_km(arbiter->hdcp_dev, data,
                                                         rx_cert, paired,
                                                         ek_pub_km, msg_sz);
        if (ret < 0)
@@ -1200,18 +1210,18 @@ static int hdcp2_verify_hprime(struct intel_connector *connector,
        struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
        struct hdcp_port_data *data = &dig_port->hdcp_port_data;
        struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-       struct i915_hdcp_comp_master *comp;
+       struct i915_hdcp_master *arbiter;
        int ret;
 
        mutex_lock(&dev_priv->display.hdcp.comp_mutex);
-       comp = dev_priv->display.hdcp.master;
+       arbiter = dev_priv->display.hdcp.master;
 
-       if (!comp || !comp->ops) {
+       if (!arbiter || !arbiter->ops) {
                mutex_unlock(&dev_priv->display.hdcp.comp_mutex);
                return -EINVAL;
        }
 
-       ret = comp->ops->verify_hprime(comp->mei_dev, data, rx_hprime);
+       ret = arbiter->ops->verify_hprime(arbiter->hdcp_dev, data, rx_hprime);
        if (ret < 0)
                drm_dbg_kms(&dev_priv->drm, "Verify hprime failed. %d\n", ret);
        mutex_unlock(&dev_priv->display.hdcp.comp_mutex);
@@ -1226,18 +1236,18 @@ hdcp2_store_pairing_info(struct intel_connector *connector,
        struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
        struct hdcp_port_data *data = &dig_port->hdcp_port_data;
        struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-       struct i915_hdcp_comp_master *comp;
+       struct i915_hdcp_master *arbiter;
        int ret;
 
        mutex_lock(&dev_priv->display.hdcp.comp_mutex);
-       comp = dev_priv->display.hdcp.master;
+       arbiter = dev_priv->display.hdcp.master;
 
-       if (!comp || !comp->ops) {
+       if (!arbiter || !arbiter->ops) {
                mutex_unlock(&dev_priv->display.hdcp.comp_mutex);
                return -EINVAL;
        }
 
-       ret = comp->ops->store_pairing_info(comp->mei_dev, data, pairing_info);
+       ret = arbiter->ops->store_pairing_info(arbiter->hdcp_dev, data, pairing_info);
        if (ret < 0)
                drm_dbg_kms(&dev_priv->drm, "Store pairing info failed. %d\n",
                            ret);
@@ -1253,18 +1263,18 @@ hdcp2_prepare_lc_init(struct intel_connector *connector,
        struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
        struct hdcp_port_data *data = &dig_port->hdcp_port_data;
        struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-       struct i915_hdcp_comp_master *comp;
+       struct i915_hdcp_master *arbiter;
        int ret;
 
        mutex_lock(&dev_priv->display.hdcp.comp_mutex);
-       comp = dev_priv->display.hdcp.master;
+       arbiter = dev_priv->display.hdcp.master;
 
-       if (!comp || !comp->ops) {
+       if (!arbiter || !arbiter->ops) {
                mutex_unlock(&dev_priv->display.hdcp.comp_mutex);
                return -EINVAL;
        }
 
-       ret = comp->ops->initiate_locality_check(comp->mei_dev, data, lc_init);
+       ret = arbiter->ops->initiate_locality_check(arbiter->hdcp_dev, data, lc_init);
        if (ret < 0)
                drm_dbg_kms(&dev_priv->drm, "Prepare lc_init failed. %d\n",
                            ret);
@@ -1280,18 +1290,18 @@ hdcp2_verify_lprime(struct intel_connector *connector,
        struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
        struct hdcp_port_data *data = &dig_port->hdcp_port_data;
        struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-       struct i915_hdcp_comp_master *comp;
+       struct i915_hdcp_master *arbiter;
        int ret;
 
        mutex_lock(&dev_priv->display.hdcp.comp_mutex);
-       comp = dev_priv->display.hdcp.master;
+       arbiter = dev_priv->display.hdcp.master;
 
-       if (!comp || !comp->ops) {
+       if (!arbiter || !arbiter->ops) {
                mutex_unlock(&dev_priv->display.hdcp.comp_mutex);
                return -EINVAL;
        }
 
-       ret = comp->ops->verify_lprime(comp->mei_dev, data, rx_lprime);
+       ret = arbiter->ops->verify_lprime(arbiter->hdcp_dev, data, rx_lprime);
        if (ret < 0)
                drm_dbg_kms(&dev_priv->drm, "Verify L_Prime failed. %d\n",
                            ret);
@@ -1306,18 +1316,18 @@ static int hdcp2_prepare_skey(struct intel_connector *connector,
        struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
        struct hdcp_port_data *data = &dig_port->hdcp_port_data;
        struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-       struct i915_hdcp_comp_master *comp;
+       struct i915_hdcp_master *arbiter;
        int ret;
 
        mutex_lock(&dev_priv->display.hdcp.comp_mutex);
-       comp = dev_priv->display.hdcp.master;
+       arbiter = dev_priv->display.hdcp.master;
 
-       if (!comp || !comp->ops) {
+       if (!arbiter || !arbiter->ops) {
                mutex_unlock(&dev_priv->display.hdcp.comp_mutex);
                return -EINVAL;
        }
 
-       ret = comp->ops->get_session_key(comp->mei_dev, data, ske_data);
+       ret = arbiter->ops->get_session_key(arbiter->hdcp_dev, data, ske_data);
        if (ret < 0)
                drm_dbg_kms(&dev_priv->drm, "Get session key failed. %d\n",
                            ret);
@@ -1335,20 +1345,21 @@ hdcp2_verify_rep_topology_prepare_ack(struct intel_connector *connector,
        struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
        struct hdcp_port_data *data = &dig_port->hdcp_port_data;
        struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-       struct i915_hdcp_comp_master *comp;
+       struct i915_hdcp_master *arbiter;
        int ret;
 
        mutex_lock(&dev_priv->display.hdcp.comp_mutex);
-       comp = dev_priv->display.hdcp.master;
+       arbiter = dev_priv->display.hdcp.master;
 
-       if (!comp || !comp->ops) {
+       if (!arbiter || !arbiter->ops) {
                mutex_unlock(&dev_priv->display.hdcp.comp_mutex);
                return -EINVAL;
        }
 
-       ret = comp->ops->repeater_check_flow_prepare_ack(comp->mei_dev, data,
-                                                        rep_topology,
-                                                        rep_send_ack);
+       ret = arbiter->ops->repeater_check_flow_prepare_ack(arbiter->hdcp_dev,
+                                                           data,
+                                                           rep_topology,
+                                                           rep_send_ack);
        if (ret < 0)
                drm_dbg_kms(&dev_priv->drm,
                            "Verify rep topology failed. %d\n", ret);
@@ -1364,18 +1375,18 @@ hdcp2_verify_mprime(struct intel_connector *connector,
        struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
        struct hdcp_port_data *data = &dig_port->hdcp_port_data;
        struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-       struct i915_hdcp_comp_master *comp;
+       struct i915_hdcp_master *arbiter;
        int ret;
 
        mutex_lock(&dev_priv->display.hdcp.comp_mutex);
-       comp = dev_priv->display.hdcp.master;
+       arbiter = dev_priv->display.hdcp.master;
 
-       if (!comp || !comp->ops) {
+       if (!arbiter || !arbiter->ops) {
                mutex_unlock(&dev_priv->display.hdcp.comp_mutex);
                return -EINVAL;
        }
 
-       ret = comp->ops->verify_mprime(comp->mei_dev, data, stream_ready);
+       ret = arbiter->ops->verify_mprime(arbiter->hdcp_dev, data, stream_ready);
        if (ret < 0)
                drm_dbg_kms(&dev_priv->drm, "Verify mprime failed. %d\n", ret);
        mutex_unlock(&dev_priv->display.hdcp.comp_mutex);
@@ -1388,18 +1399,18 @@ static int hdcp2_authenticate_port(struct intel_connector *connector)
        struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
        struct hdcp_port_data *data = &dig_port->hdcp_port_data;
        struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-       struct i915_hdcp_comp_master *comp;
+       struct i915_hdcp_master *arbiter;
        int ret;
 
        mutex_lock(&dev_priv->display.hdcp.comp_mutex);
-       comp = dev_priv->display.hdcp.master;
+       arbiter = dev_priv->display.hdcp.master;
 
-       if (!comp || !comp->ops) {
+       if (!arbiter || !arbiter->ops) {
                mutex_unlock(&dev_priv->display.hdcp.comp_mutex);
                return -EINVAL;
        }
 
-       ret = comp->ops->enable_hdcp_authentication(comp->mei_dev, data);
+       ret = arbiter->ops->enable_hdcp_authentication(arbiter->hdcp_dev, data);
        if (ret < 0)
                drm_dbg_kms(&dev_priv->drm, "Enable hdcp auth failed. %d\n",
                            ret);
@@ -1408,22 +1419,22 @@ static int hdcp2_authenticate_port(struct intel_connector *connector)
        return ret;
 }
 
-static int hdcp2_close_mei_session(struct intel_connector *connector)
+static int hdcp2_close_session(struct intel_connector *connector)
 {
        struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
        struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-       struct i915_hdcp_comp_master *comp;
+       struct i915_hdcp_master *arbiter;
        int ret;
 
        mutex_lock(&dev_priv->display.hdcp.comp_mutex);
-       comp = dev_priv->display.hdcp.master;
+       arbiter = dev_priv->display.hdcp.master;
 
-       if (!comp || !comp->ops) {
+       if (!arbiter || !arbiter->ops) {
                mutex_unlock(&dev_priv->display.hdcp.comp_mutex);
                return -EINVAL;
        }
 
-       ret = comp->ops->close_hdcp_session(comp->mei_dev,
+       ret = arbiter->ops->close_hdcp_session(arbiter->hdcp_dev,
                                             &dig_port->hdcp_port_data);
        mutex_unlock(&dev_priv->display.hdcp.comp_mutex);
 
@@ -1432,7 +1443,7 @@ static int hdcp2_close_mei_session(struct intel_connector *connector)
 
 static int hdcp2_deauthenticate_port(struct intel_connector *connector)
 {
-       return hdcp2_close_mei_session(connector);
+       return hdcp2_close_session(connector);
 }
 
 /* Authentication flow starts from here */
@@ -2142,8 +2153,8 @@ static int i915_hdcp_component_bind(struct device *i915_kdev,
 
        drm_dbg(&dev_priv->drm, "I915 HDCP comp bind\n");
        mutex_lock(&dev_priv->display.hdcp.comp_mutex);
-       dev_priv->display.hdcp.master = (struct i915_hdcp_comp_master *)data;
-       dev_priv->display.hdcp.master->mei_dev = mei_kdev;
+       dev_priv->display.hdcp.master = (struct i915_hdcp_master *)data;
+       dev_priv->display.hdcp.master->hdcp_dev = mei_kdev;
        mutex_unlock(&dev_priv->display.hdcp.comp_mutex);
 
        return 0;
@@ -2160,30 +2171,30 @@ static void i915_hdcp_component_unbind(struct device *i915_kdev,
        mutex_unlock(&dev_priv->display.hdcp.comp_mutex);
 }
 
-static const struct component_ops i915_hdcp_component_ops = {
+static const struct component_ops i915_hdcp_ops = {
        .bind   = i915_hdcp_component_bind,
        .unbind = i915_hdcp_component_unbind,
 };
 
-static enum mei_fw_ddi intel_get_mei_fw_ddi_index(enum port port)
+static enum hdcp_ddi intel_get_hdcp_ddi_index(enum port port)
 {
        switch (port) {
        case PORT_A:
-               return MEI_DDI_A;
+               return HDCP_DDI_A;
        case PORT_B ... PORT_F:
-               return (enum mei_fw_ddi)port;
+               return (enum hdcp_ddi)port;
        default:
-               return MEI_DDI_INVALID_PORT;
+               return HDCP_DDI_INVALID_PORT;
        }
 }
 
-static enum mei_fw_tc intel_get_mei_fw_tc(enum transcoder cpu_transcoder)
+static enum hdcp_transcoder intel_get_hdcp_transcoder(enum transcoder cpu_transcoder)
 {
        switch (cpu_transcoder) {
        case TRANSCODER_A ... TRANSCODER_D:
-               return (enum mei_fw_tc)(cpu_transcoder | 0x10);
+               return (enum hdcp_transcoder)(cpu_transcoder | 0x10);
        default: /* eDP, DSI TRANSCODERS are non HDCP capable */
-               return MEI_INVALID_TRANSCODER;
+               return HDCP_INVALID_TRANSCODER;
        }
 }
 
@@ -2197,20 +2208,20 @@ static int initialize_hdcp_port_data(struct intel_connector *connector,
        enum port port = dig_port->base.port;
 
        if (DISPLAY_VER(dev_priv) < 12)
-               data->fw_ddi = intel_get_mei_fw_ddi_index(port);
+               data->hdcp_ddi = intel_get_hdcp_ddi_index(port);
        else
                /*
-                * As per ME FW API expectation, for GEN 12+, fw_ddi is filled
+                * As per ME FW API expectation, for GEN 12+, hdcp_ddi is filled
                 * with zero(INVALID PORT index).
                 */
-               data->fw_ddi = MEI_DDI_INVALID_PORT;
+               data->hdcp_ddi = HDCP_DDI_INVALID_PORT;
 
        /*
-        * As associated transcoder is set and modified at modeset, here fw_tc
+        * As associated transcoder is set and modified at modeset, here hdcp_transcoder
         * is initialized to zero (invalid transcoder index). This will be
         * retained for <Gen12 forever.
         */
-       data->fw_tc = MEI_INVALID_TRANSCODER;
+       data->hdcp_transcoder = HDCP_INVALID_TRANSCODER;
 
        data->port_type = (u8)HDCP_PORT_TYPE_INTEGRATED;
        data->protocol = (u8)shim->protocol;
@@ -2232,6 +2243,9 @@ static int initialize_hdcp_port_data(struct intel_connector *connector,
 
 static bool is_hdcp2_supported(struct drm_i915_private *dev_priv)
 {
+       if (intel_hdcp_gsc_cs_required(dev_priv))
+               return true;
+
        if (!IS_ENABLED(CONFIG_INTEL_MEI_HDCP))
                return false;
 
@@ -2253,10 +2267,14 @@ void intel_hdcp_component_init(struct drm_i915_private *dev_priv)
 
        dev_priv->display.hdcp.comp_added = true;
        mutex_unlock(&dev_priv->display.hdcp.comp_mutex);
-       ret = component_add_typed(dev_priv->drm.dev, &i915_hdcp_component_ops,
-                                 I915_COMPONENT_HDCP);
+       if (intel_hdcp_gsc_cs_required(dev_priv))
+               ret = intel_hdcp_gsc_init(dev_priv);
+       else
+               ret = component_add_typed(dev_priv->drm.dev, &i915_hdcp_ops,
+                                         I915_COMPONENT_HDCP);
+
        if (ret < 0) {
-               drm_dbg_kms(&dev_priv->drm, "Failed at component add(%d)\n",
+               drm_dbg_kms(&dev_priv->drm, "Failed at fw component add(%d)\n",
                            ret);
                mutex_lock(&dev_priv->display.hdcp.comp_mutex);
                dev_priv->display.hdcp.comp_added = false;
@@ -2314,10 +2332,14 @@ int intel_hdcp_init(struct intel_connector *connector,
        return 0;
 }
 
-int intel_hdcp_enable(struct intel_connector *connector,
-                     const struct intel_crtc_state *pipe_config, u8 content_type)
+int intel_hdcp_enable(struct intel_atomic_state *state,
+                     struct intel_encoder *encoder,
+                     const struct intel_crtc_state *pipe_config,
+                     const struct drm_connector_state *conn_state)
 {
-       struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+       struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+       struct intel_connector *connector =
+               to_intel_connector(conn_state->connector);
        struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
        struct intel_hdcp *hdcp = &connector->hdcp;
        unsigned long check_link_interval = DRM_HDCP_CHECK_PERIOD_MS;
@@ -2336,7 +2358,7 @@ int intel_hdcp_enable(struct intel_connector *connector,
        mutex_lock(&dig_port->hdcp_mutex);
        drm_WARN_ON(&dev_priv->drm,
                    hdcp->value == DRM_MODE_CONTENT_PROTECTION_ENABLED);
-       hdcp->content_type = content_type;
+       hdcp->content_type = (u8)conn_state->content_type;
 
        if (intel_crtc_has_type(pipe_config, INTEL_OUTPUT_DP_MST)) {
                hdcp->cpu_transcoder = pipe_config->mst_master_transcoder;
@@ -2347,7 +2369,8 @@ int intel_hdcp_enable(struct intel_connector *connector,
        }
 
        if (DISPLAY_VER(dev_priv) >= 12)
-               dig_port->hdcp_port_data.fw_tc = intel_get_mei_fw_tc(hdcp->cpu_transcoder);
+               dig_port->hdcp_port_data.hdcp_transcoder =
+                       intel_get_hdcp_transcoder(hdcp->cpu_transcoder);
 
        /*
         * Considering that HDCP2.2 is more secure than HDCP1.4, If the setup
@@ -2466,9 +2489,7 @@ void intel_hdcp_update_pipe(struct intel_atomic_state *state,
        }
 
        if (desired_and_not_enabled || content_protection_type_changed)
-               intel_hdcp_enable(connector,
-                                 crtc_state,
-                                 (u8)conn_state->hdcp_content_type);
+               intel_hdcp_enable(state, encoder, crtc_state, conn_state);
 }
 
 void intel_hdcp_component_fini(struct drm_i915_private *dev_priv)
@@ -2482,7 +2503,10 @@ void intel_hdcp_component_fini(struct drm_i915_private *dev_priv)
        dev_priv->display.hdcp.comp_added = false;
        mutex_unlock(&dev_priv->display.hdcp.comp_mutex);
 
-       component_del(dev_priv->drm.dev, &i915_hdcp_component_ops);
+       if (intel_hdcp_gsc_cs_required(dev_priv))
+               intel_hdcp_gsc_fini(dev_priv);
+       else
+               component_del(dev_priv->drm.dev, &i915_hdcp_ops);
 }
 
 void intel_hdcp_cleanup(struct intel_connector *connector)