HDCP2 Authentication might take more then 5Secs based on the downstream topology. So when atomic property set ioctl requests for HDCP enable, We schedule the HDCP2 enbale as a asynchronous work by not blocking the ioctl call.
The Result of the work will be updated to the DRM Property.
Signed-off-by: Ramalingam C ramalingam.c@intel.com --- drivers/gpu/drm/drm_hdcp.c | 40 +++++++++++++++++++++++++++++++++++++--- include/drm/drm_hdcp.h | 8 ++++++++ 2 files changed, 45 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/drm_hdcp.c b/drivers/gpu/drm/drm_hdcp.c index cb20cc9..9e1b7ae 100644 --- a/drivers/gpu/drm/drm_hdcp.c +++ b/drivers/gpu/drm/drm_hdcp.c @@ -69,6 +69,39 @@ static void drm_hdcp_update_change(struct drm_hdcp *hdcp, bool enabled, } }
+static void hdcp_2_2_enable_work(struct work_struct *work) +{ + struct drm_hdcp *hdcp = container_of(work, struct drm_hdcp, + hdcp2_enable_work); + + mutex_lock(&hdcp->mutex); + + /* Marking it as WIP */ + drm_hdcp_update_change(hdcp, false, DRM_HDCP_WIP, true); + hdcp->spec_ver_used = HDCP_2_2_SUPPORT; + + /* + * TODO: Implement the HDCP2.2 authentication and Encryption Enable + */ + mutex_unlock(&hdcp->mutex); +} + +static int drm_hdcp_2_2_enable(struct drm_hdcp *hdcp, uint8_t stream_type) +{ + mutex_lock(&hdcp->mutex); + + /* Set the stream type */ + hdcp->streams[0].stream_type = stream_type; + + hdcp->req_state &= ~(DRM_HDCP_ENABLE | DRM_HDCP_TYPE_MASK); + hdcp->req_state = DRM_HDCP_ENABLE | + (stream_type << DRM_HDCP_TYPE_SHIFT); + + schedule_work(&hdcp->hdcp2_enable_work); + + mutex_unlock(&hdcp->mutex); + return 0; +}
int drm_hdcp_enable(struct drm_connector *connector, uint8_t stream_type) { @@ -83,9 +116,8 @@ int drm_hdcp_enable(struct drm_connector *connector, uint8_t stream_type) return ret; }
- /* - * TODO: Invoke the Version specific hdcp_enable - */ + if (connector->hdcp_state & DRM_HDCP2_SUPPORTED) + return drm_hdcp_2_2_enable(hdcp, stream_type);
return 0; } @@ -260,6 +292,8 @@ static inline int drm_hdcp2_init(struct drm_connector *connector, /* Setting it to Type 0 by default */ hdcp->streams[0].stream_type = HDCP_STREAM_TYPE0_CODE;
+ INIT_WORK(&hdcp->hdcp2_enable_work, hdcp_2_2_enable_work); + return 0; }
diff --git a/include/drm/drm_hdcp.h b/include/drm/drm_hdcp.h index dac9831..ea18bac 100644 --- a/include/drm/drm_hdcp.h +++ b/include/drm/drm_hdcp.h @@ -366,6 +366,12 @@ struct drm_hdcp { uint32_t ver_support_on_plat; uint32_t ver_support_on_panel;
+ /* + * HDCP ver last used for Enable. Will help to choose the + * corresponding Version's disable. + */ + uint32_t spec_ver_used; + /* HDCP requested state and also the current state */ uint64_t req_state;
@@ -375,6 +381,8 @@ struct drm_hdcp { const struct drm_hdcp_funcs *hdcp_funcs; const struct drm_hdcp2_funcs *hdcp2_funcs;
+ struct work_struct hdcp2_enable_work; + struct mutex mutex; };