Atomic ioctl request is pruned based on the platform and panel's HDCP capabilities along with current state of HDCP protection on the connector. Valid enable and disable requests are passed on to the HDCP stack. get_property also updated with current state of the HDCP on connector. Signed-off-by: Ramalingam C <ramalingam.c@xxxxxxxxx> --- drivers/gpu/drm/drm_atomic.c | 5 +++++ drivers/gpu/drm/drm_hdcp.c | 53 ++++++++++++++++++++++++++++++++++++++++++++ include/drm/drm_hdcp.h | 1 + 3 files changed, 59 insertions(+) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 09ca662..9d4af3b 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -30,6 +30,7 @@ #include <drm/drm_atomic.h> #include <drm/drm_mode.h> #include <drm/drm_print.h> +#include <drm/drm_hdcp.h> #include <linux/sync_file.h> #include "drm_crtc_internal.h" @@ -1188,6 +1189,8 @@ int drm_atomic_connector_set_property(struct drm_connector *connector, */ if (state->link_status != DRM_LINK_STATUS_GOOD) state->link_status = val; + } else if (property == config->hdcp_property) { + return drm_hdcp_set_property(connector, val); } else if (property == config->aspect_ratio_property) { state->picture_aspect_ratio = val; } else if (property == connector->scaling_mode_property) { @@ -1268,6 +1271,8 @@ drm_atomic_connector_get_property(struct drm_connector *connector, *val = state->tv.hue; } else if (property == config->link_status_property) { *val = state->link_status; + } else if (property == config->hdcp_property) { + *val = connector->hdcp_state; } else if (property == config->aspect_ratio_property) { *val = state->picture_aspect_ratio; } else if (property == connector->scaling_mode_property) { diff --git a/drivers/gpu/drm/drm_hdcp.c b/drivers/gpu/drm/drm_hdcp.c index 89c7c5e..9b3bf92 100644 --- a/drivers/gpu/drm/drm_hdcp.c +++ b/drivers/gpu/drm/drm_hdcp.c @@ -69,6 +69,59 @@ int drm_hdcp_disable(struct drm_connector *connector) return 0; } + +/** + * @drm_hdcp_set_property: + * + * Entry function for hdcp_enable and hdcp_disable. + */ +int drm_hdcp_set_property(struct drm_connector *connector, + uint64_t req_state) +{ + struct drm_hdcp *hdcp = connector->hdcp; + uint64_t cur_state = connector->hdcp_state; + uint8_t stream_type; + + if (connector->status != connector_status_connected) + return -EINVAL; + + if (!hdcp) + return -EINVAL; + + DRM_DEBUG("Prop_val: Current : 0x%llx, Request: 0x%llx\n", + cur_state, req_state); + + if (!(cur_state & DRM_HDCP_VER_SUPPORT_MASK)) { + DRM_ERROR("None of the HDCP Ver is supported\n"); + return -EINVAL; + } + + if ((cur_state & DRM_HDCP_ENABLE) == + (req_state & DRM_HDCP_ENABLE)) { + DRM_DEBUG("Req for current state is redundant\n"); + return -EINVAL; + } + + if (!(cur_state & DRM_HDCP2_SUPPORTED) && + req_state & DRM_HDCP_TYPE_BIT0) { + DRM_ERROR("Type 1 HDCP is not available\n"); + return -EINVAL; + } + + if (cur_state & DRM_HDCP_WIP) + return -EBUSY; + + if (req_state & DRM_HDCP_ENABLE) { + stream_type = (req_state & DRM_HDCP_TYPE_MASK) >> + DRM_HDCP_TYPE_SHIFT; + return drm_hdcp_enable(connector, stream_type); + } else { + drm_hdcp_disable(connector); + } + + return 0; +} + void drm_hdcp_late_init(struct drm_connector *connector) { struct drm_hdcp *hdcp = connector->hdcp; diff --git a/include/drm/drm_hdcp.h b/include/drm/drm_hdcp.h index 89879ff..eb7149b 100644 --- a/include/drm/drm_hdcp.h +++ b/include/drm/drm_hdcp.h @@ -169,5 +169,6 @@ extern int drm_hdcp_init(struct drm_connector *connector, uint8_t spec_supported); extern void drm_hdcp_connector_state_change_handler( struct drm_connector *connector); +int drm_hdcp_set_property(struct drm_connector *connector, uint64_t val); #endif /* __DRM_HDCP_H__ */ -- 2.7.4 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel