diff options
| author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2023-03-24 20:22:02 +0100 | 
|---|---|---|
| committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2023-03-24 20:22:03 +0100 | 
| commit | 7ed34927254ae9eac0f6b0ad7e7c2bceb96fcdfc (patch) | |
| tree | c3a49534fe3c663aa130463caab7e2160fd96488 /drivers/gpu/drm/i915/display/intel_hdcp.c | |
| parent | 9578a10d4a2b4bcbbebefb4156c16c82ee725b3a (diff) | |
| parent | 883631771038d1b0c10c0929e31bbd5ffb5e682c (diff) | |
Merge tag 'drm-intel-next-2023-03-23' of git://anongit.freedesktop.org/drm/drm-intel into drm-next
Core Changes:
- drm: Add SDP Error Detection Configuration Register (Arun)
Driver Changes:
- Meteor Lake enabling and fixes (RK, Jose, Madhumitha)
- Lock the fbdev obj before vma pin (Tejas)
- DSC fixes (Stanislav)
- Fixes and clean-up on opregion code (Imre)
- More wm/vblank stuff (Ville)
- More general display code organization (Jani)
- DP Fixes (Stanislav, Ville)
- Introduce flags to ignore long HPD and link training issues \
  for handling spurious issues on CI (Vinod)
- Plane cleanups and extra registers (Ville)
- Update audio keepalive clock values (Clint)
- Rename find_section to bdb_find_section (Maarten)
- DP SDP CRC16 for 128b132b link layer (Arun)
- Fix various issues with noarm register writes (Ville)
- Fix a few TypeC / MST issues (Imre)
- Create GSC submission targeting HDCP and PXP usages on MTL+ (Suraj)
- Enable HDCP2.x via GSC CS (Suraj)
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
From: Rodrigo Vivi <rodrigo.vivi@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/ZBy56qc9C00tCLOY@intel.com
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_hdcp.c')
| -rw-r--r-- | drivers/gpu/drm/i915/display/intel_hdcp.c | 158 | 
1 files changed, 89 insertions, 69 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c index 2984d2810e42..650232c4892b 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -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" @@ -203,13 +204,20 @@ bool intel_hdcp2_capable(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 intel_hdcp *hdcp = &connector->hdcp; +	struct intel_gt *gt = dev_priv->media_gt; +	struct intel_gsc_uc *gsc = >->uc.gsc;  	bool capable = false;  	/* I915 support for HDCP2.2 */  	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)) +		if (!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 +1150,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 +1180,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 +1208,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 +1234,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 +1261,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 +1288,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 +1314,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 +1343,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 +1373,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 +1397,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 +1417,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 +1441,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 +2151,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 +2169,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 +2206,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 +2241,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 +2265,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; @@ -2347,7 +2363,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 @@ -2482,7 +2499,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)  | 
