msm: mdss: hdmi: propagation of content stream management info
Add support for propagating content stream related information downstream. Send/receive repeater authentication stream manage/ready messages as per hdcp2.2 standard. Change-Id: I8d37f9f6d4cb131b29128222bb43c9c290c78437 Signed-off-by: Ajay Singh Parmar <aparmar@codeaurora.org>
This commit is contained in:
parent
bdb2680679
commit
0057829118
3 changed files with 31 additions and 30 deletions
|
@ -337,6 +337,7 @@ struct hdcp_lib_handle {
|
||||||
void *client_ctx;
|
void *client_ctx;
|
||||||
struct hdcp_client_ops *client_ops;
|
struct hdcp_client_ops *client_ops;
|
||||||
struct mutex hdcp_lock;
|
struct mutex hdcp_lock;
|
||||||
|
struct mutex wakeup_mutex;
|
||||||
enum hdcp_state hdcp_state;
|
enum hdcp_state hdcp_state;
|
||||||
enum hdcp_lib_wakeup_cmd wakeup_cmd;
|
enum hdcp_lib_wakeup_cmd wakeup_cmd;
|
||||||
bool repeater_flag;
|
bool repeater_flag;
|
||||||
|
@ -356,6 +357,7 @@ struct hdcp_lib_handle {
|
||||||
struct kthread_work timeout;
|
struct kthread_work timeout;
|
||||||
struct kthread_work clean;
|
struct kthread_work clean;
|
||||||
struct kthread_work topology;
|
struct kthread_work topology;
|
||||||
|
struct kthread_work stream;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct hdcp_lib_message_map {
|
struct hdcp_lib_message_map {
|
||||||
|
@ -671,30 +673,20 @@ exit:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hdcp_lib_query_stream_type(void *phdcpcontext)
|
static void hdcp_lib_query_stream_type_work(struct kthread_work *work)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
struct hdcp_query_stream_type_req *req_buf;
|
struct hdcp_query_stream_type_req *req_buf;
|
||||||
struct hdcp_query_stream_type_rsp *rsp_buf;
|
struct hdcp_query_stream_type_rsp *rsp_buf;
|
||||||
struct hdcp_lib_handle *handle = phdcpcontext;
|
struct hdcp_lib_handle *handle = container_of(work,
|
||||||
|
struct hdcp_lib_handle, stream);
|
||||||
|
|
||||||
if (!handle) {
|
if (!handle) {
|
||||||
pr_err("invalid input\n");
|
pr_err("invalid handle\n");
|
||||||
return -EINVAL;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(handle->hdcp_state & HDCP_STATE_APP_LOADED)) {
|
mutex_lock(&handle->hdcp_lock);
|
||||||
pr_debug("hdcp library not loaded\n");
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(handle->hdcp_state & HDCP_STATE_TXMTR_INIT)) {
|
|
||||||
pr_err("txmtr is not initialized\n");
|
|
||||||
rc = -EINVAL;
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
flush_kthread_worker(&handle->worker);
|
|
||||||
|
|
||||||
/* send command to TZ */
|
/* send command to TZ */
|
||||||
req_buf = (struct hdcp_query_stream_type_req *)handle->
|
req_buf = (struct hdcp_query_stream_type_req *)handle->
|
||||||
|
@ -718,7 +710,7 @@ static int hdcp_lib_query_stream_type(void *phdcpcontext)
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
pr_debug("message received is %s\n",
|
pr_debug("message received from TZ: %s\n",
|
||||||
hdcp_lib_message_name((int)rsp_buf->msg[0]));
|
hdcp_lib_message_name((int)rsp_buf->msg[0]));
|
||||||
|
|
||||||
memset(handle->listener_buf, 0, MAX_TX_MESSAGE_SIZE);
|
memset(handle->listener_buf, 0, MAX_TX_MESSAGE_SIZE);
|
||||||
|
@ -726,15 +718,11 @@ static int hdcp_lib_query_stream_type(void *phdcpcontext)
|
||||||
rsp_buf->msglen);
|
rsp_buf->msglen);
|
||||||
handle->hdcp_timeout = rsp_buf->timeout;
|
handle->hdcp_timeout = rsp_buf->timeout;
|
||||||
handle->msglen = rsp_buf->msglen;
|
handle->msglen = rsp_buf->msglen;
|
||||||
|
|
||||||
if (!atomic_read(&handle->hdcp_off))
|
|
||||||
hdcp_lib_send_message(handle);
|
|
||||||
else
|
|
||||||
goto exit;
|
|
||||||
|
|
||||||
pr_debug("success\n");
|
|
||||||
exit:
|
exit:
|
||||||
return rc;
|
mutex_unlock(&handle->hdcp_lock);
|
||||||
|
|
||||||
|
if (!rc && !atomic_read(&handle->hdcp_off))
|
||||||
|
hdcp_lib_send_message(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool hdcp_lib_client_feature_supported(void *phdcpcontext)
|
static bool hdcp_lib_client_feature_supported(void *phdcpcontext)
|
||||||
|
@ -776,6 +764,8 @@ static int hdcp_lib_wakeup(struct hdcp_lib_wakeup_data *data)
|
||||||
if (!handle)
|
if (!handle)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
mutex_lock(&handle->wakeup_mutex);
|
||||||
|
|
||||||
handle->wakeup_cmd = data->cmd;
|
handle->wakeup_cmd = data->cmd;
|
||||||
|
|
||||||
pr_debug("cmd: %s\n", hdcp_lib_cmd_to_str(handle->wakeup_cmd));
|
pr_debug("cmd: %s\n", hdcp_lib_cmd_to_str(handle->wakeup_cmd));
|
||||||
|
@ -830,10 +820,15 @@ static int hdcp_lib_wakeup(struct hdcp_lib_wakeup_data *data)
|
||||||
if (!atomic_read(&handle->hdcp_off))
|
if (!atomic_read(&handle->hdcp_off))
|
||||||
queue_kthread_work(&handle->worker, &handle->timeout);
|
queue_kthread_work(&handle->worker, &handle->timeout);
|
||||||
break;
|
break;
|
||||||
|
case HDCP_LIB_WKUP_CMD_QUERY_STREAM_TYPE:
|
||||||
|
if (!atomic_read(&handle->hdcp_off))
|
||||||
|
queue_kthread_work(&handle->worker, &handle->stream);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
pr_err("invalid wakeup command %d\n", handle->wakeup_cmd);
|
pr_err("invalid wakeup command %d\n", handle->wakeup_cmd);
|
||||||
}
|
}
|
||||||
exit:
|
exit:
|
||||||
|
mutex_unlock(&handle->wakeup_mutex);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1256,7 +1251,6 @@ int hdcp_library_register(void **pphdcpcontext,
|
||||||
/* populate ops to be called by client */
|
/* populate ops to be called by client */
|
||||||
txmtr_ops->feature_supported = hdcp_lib_client_feature_supported;
|
txmtr_ops->feature_supported = hdcp_lib_client_feature_supported;
|
||||||
txmtr_ops->wakeup = hdcp_lib_wakeup;
|
txmtr_ops->wakeup = hdcp_lib_wakeup;
|
||||||
txmtr_ops->hdcp_query_stream_type = hdcp_lib_query_stream_type;
|
|
||||||
|
|
||||||
handle = kzalloc(sizeof(*handle), GFP_KERNEL);
|
handle = kzalloc(sizeof(*handle), GFP_KERNEL);
|
||||||
if (!handle) {
|
if (!handle) {
|
||||||
|
@ -1270,6 +1264,7 @@ int hdcp_library_register(void **pphdcpcontext,
|
||||||
atomic_set(&handle->hdcp_off, 0);
|
atomic_set(&handle->hdcp_off, 0);
|
||||||
|
|
||||||
mutex_init(&handle->hdcp_lock);
|
mutex_init(&handle->hdcp_lock);
|
||||||
|
mutex_init(&handle->wakeup_mutex);
|
||||||
|
|
||||||
init_kthread_worker(&handle->worker);
|
init_kthread_worker(&handle->worker);
|
||||||
|
|
||||||
|
@ -1279,6 +1274,7 @@ int hdcp_library_register(void **pphdcpcontext,
|
||||||
init_kthread_work(&handle->timeout, hdcp_lib_manage_timeout_work);
|
init_kthread_work(&handle->timeout, hdcp_lib_manage_timeout_work);
|
||||||
init_kthread_work(&handle->clean, hdcp_lib_cleanup_work);
|
init_kthread_work(&handle->clean, hdcp_lib_cleanup_work);
|
||||||
init_kthread_work(&handle->topology, hdcp_lib_topology_work);
|
init_kthread_work(&handle->topology, hdcp_lib_topology_work);
|
||||||
|
init_kthread_work(&handle->stream, hdcp_lib_query_stream_type_work);
|
||||||
|
|
||||||
init_completion(&handle->topo_wait);
|
init_completion(&handle->topo_wait);
|
||||||
|
|
||||||
|
@ -1322,6 +1318,7 @@ void hdcp_library_deregister(void *phdcpcontext)
|
||||||
kzfree(handle->qseecom_handle);
|
kzfree(handle->qseecom_handle);
|
||||||
|
|
||||||
mutex_destroy(&handle->hdcp_lock);
|
mutex_destroy(&handle->hdcp_lock);
|
||||||
|
mutex_destroy(&handle->wakeup_mutex);
|
||||||
|
|
||||||
kzfree(handle->listener_buf);
|
kzfree(handle->listener_buf);
|
||||||
kzfree(handle);
|
kzfree(handle);
|
||||||
|
|
|
@ -275,7 +275,8 @@ static ssize_t hdmi_hdcp2p2_sysfs_wta_min_level_change(struct device *dev,
|
||||||
{
|
{
|
||||||
struct hdmi_hdcp2p2_ctrl *ctrl =
|
struct hdmi_hdcp2p2_ctrl *ctrl =
|
||||||
hdmi_get_featuredata_from_sysfs_dev(dev, HDMI_TX_FEAT_HDCP2P2);
|
hdmi_get_featuredata_from_sysfs_dev(dev, HDMI_TX_FEAT_HDCP2P2);
|
||||||
int res;
|
struct hdcp_lib_wakeup_data cdata = {
|
||||||
|
HDCP_LIB_WKUP_CMD_QUERY_STREAM_TYPE};
|
||||||
|
|
||||||
if (!ctrl) {
|
if (!ctrl) {
|
||||||
pr_err("invalid input\n");
|
pr_err("invalid input\n");
|
||||||
|
@ -283,8 +284,9 @@ static ssize_t hdmi_hdcp2p2_sysfs_wta_min_level_change(struct device *dev,
|
||||||
}
|
}
|
||||||
|
|
||||||
pr_debug("notification of minimum level change received\n");
|
pr_debug("notification of minimum level change received\n");
|
||||||
res = ctrl->lib->
|
|
||||||
hdcp_query_stream_type(ctrl->lib_ctx);
|
cdata.context = ctrl->lib_ctx;
|
||||||
|
hdmi_hdcp2p2_wakeup_lib(ctrl, &cdata);
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ enum hdcp_lib_wakeup_cmd {
|
||||||
HDCP_LIB_WKUP_CMD_MSG_RECV_SUCCESS,
|
HDCP_LIB_WKUP_CMD_MSG_RECV_SUCCESS,
|
||||||
HDCP_LIB_WKUP_CMD_MSG_RECV_FAILED,
|
HDCP_LIB_WKUP_CMD_MSG_RECV_FAILED,
|
||||||
HDCP_LIB_WKUP_CMD_MSG_RECV_TIMEOUT,
|
HDCP_LIB_WKUP_CMD_MSG_RECV_TIMEOUT,
|
||||||
|
HDCP_LIB_WKUP_CMD_QUERY_STREAM_TYPE,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum hdmi_hdcp_wakeup_cmd {
|
enum hdmi_hdcp_wakeup_cmd {
|
||||||
|
@ -85,6 +86,8 @@ static inline char *hdcp_lib_cmd_to_str(uint32_t cmd)
|
||||||
return "HDCP_LIB_WKUP_CMD_MSG_RECV_FAILED";
|
return "HDCP_LIB_WKUP_CMD_MSG_RECV_FAILED";
|
||||||
case HDCP_LIB_WKUP_CMD_MSG_RECV_TIMEOUT:
|
case HDCP_LIB_WKUP_CMD_MSG_RECV_TIMEOUT:
|
||||||
return "HDCP_LIB_WKUP_CMD_MSG_RECV_TIMEOUT";
|
return "HDCP_LIB_WKUP_CMD_MSG_RECV_TIMEOUT";
|
||||||
|
case HDCP_LIB_WKUP_CMD_QUERY_STREAM_TYPE:
|
||||||
|
return "HDCP_LIB_WKUP_CMD_QUERY_STREAM_TYPE";
|
||||||
default:
|
default:
|
||||||
return "???";
|
return "???";
|
||||||
}
|
}
|
||||||
|
@ -96,7 +99,6 @@ struct hdcp_txmtr_ops {
|
||||||
|
|
||||||
int (*hdcp_txmtr_get_state)(void *phdcpcontext,
|
int (*hdcp_txmtr_get_state)(void *phdcpcontext,
|
||||||
uint32_t *state);
|
uint32_t *state);
|
||||||
int (*hdcp_query_stream_type)(void *phdcpcontext);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct hdcp_client_ops {
|
struct hdcp_client_ops {
|
||||||
|
|
Loading…
Add table
Reference in a new issue