Message ID | 20240215050524.1425206-12-suraj.kandpal@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | HDCP MST Type1 fixes | expand |
On 2/15/2024 10:35 AM, Suraj Kandpal wrote: > Allocate stream id after HDCP AKE stage and not before so that it > can also be done during link integrity check. > Right now for MST scenarios LIC fails after hdcp enablement for this > reason. > > Signed-off-by: Suraj Kandpal <suraj.kandpal@intel.com> > --- > drivers/gpu/drm/i915/display/intel_hdcp.c | 126 +++++++++++----------- > 1 file changed, 60 insertions(+), 66 deletions(-) > > diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c > index b22dbc6494e0..627b3e24197d 100644 > --- a/drivers/gpu/drm/i915/display/intel_hdcp.c > +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c > @@ -68,19 +68,52 @@ static int intel_conn_to_vcpi(struct intel_atomic_state *state, > * DP MST topology. Though it is not compulsory, security fw should change its > * policy to mark different content_types for different streams. > */ > -static void > -intel_hdcp_required_content_stream(struct intel_digital_port *dig_port) > +static int > +intel_hdcp_required_content_stream(struct intel_atomic_state *state, > + struct intel_hdcp *hdcp, I dont think we are using this in the function, so lets remove this. > + struct intel_digital_port *dig_port) > { > + struct drm_connector_list_iter conn_iter; > + struct intel_digital_port *conn_dig_port; > + struct intel_connector *connector; > + struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); > struct hdcp_port_data *data = &dig_port->hdcp_port_data; > bool enforce_type0 = false; > int k; > > if (dig_port->hdcp_auth_status) > - return; > + return 0; > + > + data->k = 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) > + continue; > + > + if (!intel_encoder_is_mst(intel_attached_encoder(connector))) > + continue; > + > + conn_dig_port = intel_attached_dig_port(connector); > + if (conn_dig_port != dig_port) > + continue; > + > + data->streams[data->k].stream_id = > + intel_conn_to_vcpi(state, connector); > + data->k++; > + > + /* if there is only one active stream */ > + if (dig_port->dp.active_mst_links <= 1) > + break; > + } > + drm_connector_list_iter_end(&conn_iter); > + > + if (drm_WARN_ON(&i915->drm, data->k > INTEL_NUM_PIPES(i915) || data->k == 0)) > + return -EINVAL; > + > /* > * Apply common protection level across all streams in DP MST Topology. > * Use highest supported content type for all streams in DP MST Topology. > @@ -88,18 +121,24 @@ intel_hdcp_required_content_stream(struct intel_digital_port *dig_port) > for (k = 0; k < data->k; k++) > data->streams[k].stream_type = > enforce_type0 ? DRM_MODE_HDCP_CONTENT_TYPE0 : DRM_MODE_HDCP_CONTENT_TYPE1; > + > + return 0; > } > > -static void intel_hdcp_prepare_streams(struct intel_connector *connector) > +static int intel_hdcp_prepare_streams(struct intel_atomic_state *state, > + 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 intel_hdcp *hdcp = &connector->hdcp; > > if (!intel_encoder_is_mst(intel_attached_encoder(connector))) { > + data->k = 1; > + data->streams[0].stream_id = 0; > data->streams[0].stream_type = hdcp->content_type; > + return 0; > } else { > - intel_hdcp_required_content_stream(dig_port); > + return intel_hdcp_required_content_stream(state, hdcp, dig_port); > } We can get rid of else block now, we can just return intel_hdcp_required_content_stream(state, dig_port); I wonder if it would be better to check for mst encoder first: if (intel_encoder_is_mst(intel_attached_encoder(connector))) return intel_hdcp_required_content_stream(state, dig_port); data->k = 1; data->streams[0].stream_id = 0; data->streams[0].stream_type = hdcp->content_type; return 0; Regards, Ankit > } > > @@ -1901,7 +1940,8 @@ hdcp2_propagate_stream_management_info(struct intel_connector *connector) > return ret; > } > > -static int hdcp2_authenticate_and_encrypt(struct intel_connector *connector) > +static int hdcp2_authenticate_and_encrypt(struct intel_atomic_state *state, > + struct intel_connector *connector) > { > struct intel_digital_port *dig_port = intel_attached_dig_port(connector); > struct drm_i915_private *i915 = to_i915(connector->base.dev); > @@ -1910,7 +1950,13 @@ static int hdcp2_authenticate_and_encrypt(struct intel_connector *connector) > for (i = 0; i < tries && !dig_port->hdcp_auth_status; i++) { > ret = hdcp2_authenticate_sink(connector); > if (!ret) { > - intel_hdcp_prepare_streams(connector); > + ret = intel_hdcp_prepare_streams(state, connector); > + if (ret) { > + drm_dbg_kms(&i915->drm, > + "Prepare stream failed.(%d)\n", > + ret); > + break; > + } > > ret = hdcp2_propagate_stream_management_info(connector); > if (ret) { > @@ -1955,7 +2001,8 @@ static int hdcp2_authenticate_and_encrypt(struct intel_connector *connector) > return ret; > } > > -static int _intel_hdcp2_enable(struct intel_connector *connector) > +static int _intel_hdcp2_enable(struct intel_atomic_state *state, > + struct intel_connector *connector) > { > struct drm_i915_private *i915 = to_i915(connector->base.dev); > struct intel_hdcp *hdcp = &connector->hdcp; > @@ -1965,7 +2012,7 @@ static int _intel_hdcp2_enable(struct intel_connector *connector) > connector->base.base.id, connector->base.name, > hdcp->content_type); > > - ret = hdcp2_authenticate_and_encrypt(connector); > + ret = hdcp2_authenticate_and_encrypt(state, connector); > if (ret) { > drm_dbg_kms(&i915->drm, "HDCP2 Type%d Enabling Failed. (%d)\n", > hdcp->content_type, ret); > @@ -2293,52 +2340,6 @@ int intel_hdcp_init(struct intel_connector *connector, > return 0; > } > > -static int > -intel_hdcp_set_streams(struct intel_digital_port *dig_port, > - struct intel_atomic_state *state) > -{ > - struct drm_connector_list_iter conn_iter; > - struct intel_digital_port *conn_dig_port; > - struct intel_connector *connector; > - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); > - struct hdcp_port_data *data = &dig_port->hdcp_port_data; > - > - if (!intel_encoder_is_mst(&dig_port->base)) { > - data->k = 1; > - data->streams[0].stream_id = 0; > - return 0; > - } > - > - data->k = 0; > - > - drm_connector_list_iter_begin(&i915->drm, &conn_iter); > - for_each_intel_connector_iter(connector, &conn_iter) { > - if (connector->base.status == connector_status_disconnected) > - continue; > - > - if (!intel_encoder_is_mst(intel_attached_encoder(connector))) > - continue; > - > - conn_dig_port = intel_attached_dig_port(connector); > - if (conn_dig_port != dig_port) > - continue; > - > - data->streams[data->k].stream_id = > - intel_conn_to_vcpi(state, connector); > - data->k++; > - > - /* if there is only one active stream */ > - if (dig_port->dp.active_mst_links <= 1) > - break; > - } > - drm_connector_list_iter_end(&conn_iter); > - > - if (drm_WARN_ON(&i915->drm, data->k > INTEL_NUM_PIPES(i915) || data->k == 0)) > - return -EINVAL; > - > - return 0; > -} > - > static int _intel_hdcp_enable(struct intel_atomic_state *state, > struct intel_encoder *encoder, > const struct intel_crtc_state *pipe_config, > @@ -2384,17 +2385,10 @@ static int _intel_hdcp_enable(struct intel_atomic_state *state, > * is capable of HDCP2.2, it is preferred to use HDCP2.2. > */ > if (intel_hdcp2_get_capability(connector)) { > - ret = intel_hdcp_set_streams(dig_port, state); > - if (!ret) { > - ret = _intel_hdcp2_enable(connector); > - if (!ret) > - check_link_interval = > - DRM_HDCP2_CHECK_PERIOD_MS; > - } else { > - drm_dbg_kms(&i915->drm, > - "Set content streams failed: (%d)\n", > - ret); > - } > + ret = _intel_hdcp2_enable(state, connector); > + if (!ret) > + check_link_interval = > + DRM_HDCP2_CHECK_PERIOD_MS; > } > > /*
diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c index b22dbc6494e0..627b3e24197d 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -68,19 +68,52 @@ static int intel_conn_to_vcpi(struct intel_atomic_state *state, * DP MST topology. Though it is not compulsory, security fw should change its * policy to mark different content_types for different streams. */ -static void -intel_hdcp_required_content_stream(struct intel_digital_port *dig_port) +static int +intel_hdcp_required_content_stream(struct intel_atomic_state *state, + struct intel_hdcp *hdcp, + struct intel_digital_port *dig_port) { + struct drm_connector_list_iter conn_iter; + struct intel_digital_port *conn_dig_port; + struct intel_connector *connector; + struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); struct hdcp_port_data *data = &dig_port->hdcp_port_data; bool enforce_type0 = false; int k; if (dig_port->hdcp_auth_status) - return; + return 0; + + data->k = 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) + continue; + + if (!intel_encoder_is_mst(intel_attached_encoder(connector))) + continue; + + conn_dig_port = intel_attached_dig_port(connector); + if (conn_dig_port != dig_port) + continue; + + data->streams[data->k].stream_id = + intel_conn_to_vcpi(state, connector); + data->k++; + + /* if there is only one active stream */ + if (dig_port->dp.active_mst_links <= 1) + break; + } + drm_connector_list_iter_end(&conn_iter); + + if (drm_WARN_ON(&i915->drm, data->k > INTEL_NUM_PIPES(i915) || data->k == 0)) + return -EINVAL; + /* * Apply common protection level across all streams in DP MST Topology. * Use highest supported content type for all streams in DP MST Topology. @@ -88,18 +121,24 @@ intel_hdcp_required_content_stream(struct intel_digital_port *dig_port) for (k = 0; k < data->k; k++) data->streams[k].stream_type = enforce_type0 ? DRM_MODE_HDCP_CONTENT_TYPE0 : DRM_MODE_HDCP_CONTENT_TYPE1; + + return 0; } -static void intel_hdcp_prepare_streams(struct intel_connector *connector) +static int intel_hdcp_prepare_streams(struct intel_atomic_state *state, + 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 intel_hdcp *hdcp = &connector->hdcp; if (!intel_encoder_is_mst(intel_attached_encoder(connector))) { + data->k = 1; + data->streams[0].stream_id = 0; data->streams[0].stream_type = hdcp->content_type; + return 0; } else { - intel_hdcp_required_content_stream(dig_port); + return intel_hdcp_required_content_stream(state, hdcp, dig_port); } } @@ -1901,7 +1940,8 @@ hdcp2_propagate_stream_management_info(struct intel_connector *connector) return ret; } -static int hdcp2_authenticate_and_encrypt(struct intel_connector *connector) +static int hdcp2_authenticate_and_encrypt(struct intel_atomic_state *state, + struct intel_connector *connector) { struct intel_digital_port *dig_port = intel_attached_dig_port(connector); struct drm_i915_private *i915 = to_i915(connector->base.dev); @@ -1910,7 +1950,13 @@ static int hdcp2_authenticate_and_encrypt(struct intel_connector *connector) for (i = 0; i < tries && !dig_port->hdcp_auth_status; i++) { ret = hdcp2_authenticate_sink(connector); if (!ret) { - intel_hdcp_prepare_streams(connector); + ret = intel_hdcp_prepare_streams(state, connector); + if (ret) { + drm_dbg_kms(&i915->drm, + "Prepare stream failed.(%d)\n", + ret); + break; + } ret = hdcp2_propagate_stream_management_info(connector); if (ret) { @@ -1955,7 +2001,8 @@ static int hdcp2_authenticate_and_encrypt(struct intel_connector *connector) return ret; } -static int _intel_hdcp2_enable(struct intel_connector *connector) +static int _intel_hdcp2_enable(struct intel_atomic_state *state, + struct intel_connector *connector) { struct drm_i915_private *i915 = to_i915(connector->base.dev); struct intel_hdcp *hdcp = &connector->hdcp; @@ -1965,7 +2012,7 @@ static int _intel_hdcp2_enable(struct intel_connector *connector) connector->base.base.id, connector->base.name, hdcp->content_type); - ret = hdcp2_authenticate_and_encrypt(connector); + ret = hdcp2_authenticate_and_encrypt(state, connector); if (ret) { drm_dbg_kms(&i915->drm, "HDCP2 Type%d Enabling Failed. (%d)\n", hdcp->content_type, ret); @@ -2293,52 +2340,6 @@ int intel_hdcp_init(struct intel_connector *connector, return 0; } -static int -intel_hdcp_set_streams(struct intel_digital_port *dig_port, - struct intel_atomic_state *state) -{ - struct drm_connector_list_iter conn_iter; - struct intel_digital_port *conn_dig_port; - struct intel_connector *connector; - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); - struct hdcp_port_data *data = &dig_port->hdcp_port_data; - - if (!intel_encoder_is_mst(&dig_port->base)) { - data->k = 1; - data->streams[0].stream_id = 0; - return 0; - } - - data->k = 0; - - drm_connector_list_iter_begin(&i915->drm, &conn_iter); - for_each_intel_connector_iter(connector, &conn_iter) { - if (connector->base.status == connector_status_disconnected) - continue; - - if (!intel_encoder_is_mst(intel_attached_encoder(connector))) - continue; - - conn_dig_port = intel_attached_dig_port(connector); - if (conn_dig_port != dig_port) - continue; - - data->streams[data->k].stream_id = - intel_conn_to_vcpi(state, connector); - data->k++; - - /* if there is only one active stream */ - if (dig_port->dp.active_mst_links <= 1) - break; - } - drm_connector_list_iter_end(&conn_iter); - - if (drm_WARN_ON(&i915->drm, data->k > INTEL_NUM_PIPES(i915) || data->k == 0)) - return -EINVAL; - - return 0; -} - static int _intel_hdcp_enable(struct intel_atomic_state *state, struct intel_encoder *encoder, const struct intel_crtc_state *pipe_config, @@ -2384,17 +2385,10 @@ static int _intel_hdcp_enable(struct intel_atomic_state *state, * is capable of HDCP2.2, it is preferred to use HDCP2.2. */ if (intel_hdcp2_get_capability(connector)) { - ret = intel_hdcp_set_streams(dig_port, state); - if (!ret) { - ret = _intel_hdcp2_enable(connector); - if (!ret) - check_link_interval = - DRM_HDCP2_CHECK_PERIOD_MS; - } else { - drm_dbg_kms(&i915->drm, - "Set content streams failed: (%d)\n", - ret); - } + ret = _intel_hdcp2_enable(state, connector); + if (!ret) + check_link_interval = + DRM_HDCP2_CHECK_PERIOD_MS; } /*
Allocate stream id after HDCP AKE stage and not before so that it can also be done during link integrity check. Right now for MST scenarios LIC fails after hdcp enablement for this reason. Signed-off-by: Suraj Kandpal <suraj.kandpal@intel.com> --- drivers/gpu/drm/i915/display/intel_hdcp.c | 126 +++++++++++----------- 1 file changed, 60 insertions(+), 66 deletions(-)