123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338 |
- // SPDX-License-Identifier: GPL-2.0-only
- /*
- * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
- */
- #include "hdcp_main.h"
- #include "hdcp_qseecom.h"
- #include "hdcp_smcinvoke.h"
- struct hdcp_ta_interface ta_interface;
- static DEFINE_MUTEX(hdcp1_mutex_g);
- static DEFINE_MUTEX(hdcp2_mutex_g);
- void select_interface(bool use_smcinvoke)
- {
- if (use_smcinvoke) {
- ta_interface.trusted_app_hdcp1_init = &hdcp1_init_smcinvoke;
- ta_interface.trusted_app_hdcp1_feature_supported = &hdcp1_feature_supported_smcinvoke;
- ta_interface.trusted_app_hdcp1_set_enc = &hdcp1_set_enc_smcinvoke;
- ta_interface.trusted_app_hdcp1_ops_notify = &hdcp1_ops_notify_smcinvoke;
- ta_interface.trusted_app_hdcp1_start = &hdcp1_start_smcinvoke;
- ta_interface.trusted_app_hdcp1_stop = &hdcp1_stop_smcinvoke;
- ta_interface.trusted_app_hdcp2_init = &hdcp2_init_smcinvoke;
- ta_interface.trusted_app_hdcp2_deinit = &hdcp2_deinit_smcinvoke;
- ta_interface.trusted_app_hdcp2_app_start = &hdcp2_app_start_smcinvoke;
- ta_interface.trusted_app_hdcp2_app_start_auth = &hdcp2_app_start_auth_smcinvoke;
- ta_interface.trusted_app_hdcp2_app_process_msg = &hdcp2_app_process_msg_smcinvoke;
- ta_interface.trusted_app_hdcp2_app_enable_encryption = &hdcp2_app_enable_encryption_smcinvoke;
- ta_interface.trusted_app_hdcp2_app_timeout = &hdcp2_app_timeout_smcinvoke;
- ta_interface.trusted_app_hdcp2_app_query_stream = &hdcp2_app_query_stream_smcinvoke;
- ta_interface.trusted_app_hdcp2_app_stop = &hdcp2_app_stop_smcinvoke;
- ta_interface.trusted_app_hdcp2_feature_supported = &hdcp2_feature_supported_smcinvoke;
- ta_interface.trusted_app_hdcp2_force_encryption = &hdcp2_force_encryption_smcinvoke;
- ta_interface.trusted_app_hdcp2_open_stream = &hdcp2_open_stream_smcinvoke;
- ta_interface.trusted_app_hdcp2_close_stream = &hdcp2_close_stream_smcinvoke;
- ta_interface.trusted_app_hdcp2_update_app_data = &hdcp2_update_app_data_smcinvoke;
- } else {
- ta_interface.trusted_app_hdcp1_init = &hdcp1_init_qseecom;
- ta_interface.trusted_app_hdcp1_feature_supported = &hdcp1_feature_supported_qseecom;
- ta_interface.trusted_app_hdcp1_set_enc = &hdcp1_set_enc_qseecom;
- ta_interface.trusted_app_hdcp1_ops_notify = &hdcp1_ops_notify_qseecom;
- ta_interface.trusted_app_hdcp1_start = &hdcp1_start_qseecom;
- ta_interface.trusted_app_hdcp1_stop = &hdcp1_stop_qseecom;
- ta_interface.trusted_app_hdcp2_init = &hdcp2_init_qseecom;
- ta_interface.trusted_app_hdcp2_deinit = &hdcp2_deinit_qseecom;
- ta_interface.trusted_app_hdcp2_app_start = &hdcp2_app_start_qseecom;
- ta_interface.trusted_app_hdcp2_app_start_auth = &hdcp2_app_start_auth_qseecom;
- ta_interface.trusted_app_hdcp2_app_process_msg = &hdcp2_app_process_msg_qseecom;
- ta_interface.trusted_app_hdcp2_app_timeout = &hdcp2_app_timeout_qseecom;
- ta_interface.trusted_app_hdcp2_app_enable_encryption = &hdcp2_app_enable_encryption_qseecom;
- ta_interface.trusted_app_hdcp2_app_query_stream = &hdcp2_app_query_stream_qseecom;
- ta_interface.trusted_app_hdcp2_app_stop = &hdcp2_app_stop_qseecom;
- ta_interface.trusted_app_hdcp2_feature_supported = &hdcp2_feature_supported_qseecom;
- ta_interface.trusted_app_hdcp2_force_encryption = &hdcp2_force_encryption_qseecom;
- ta_interface.trusted_app_hdcp2_open_stream = &hdcp2_open_stream_qseecom;
- ta_interface.trusted_app_hdcp2_close_stream = &hdcp2_close_stream_qseecom;
- ta_interface.trusted_app_hdcp2_update_app_data = &hdcp2_update_app_data_qseecom;
- }
- }
- int hdcp1_count_ones(u8 *array, u8 len)
- {
- int i, j, count = 0;
- for (i = 0; i < len; i++)
- for (j = 0; j < 8; j++)
- count += (((array[i] >> j) & 0x1) ? 1 : 0);
- return count;
- }
- int hdcp1_validate_aksv(u32 aksv_msb, u32 aksv_lsb)
- {
- int const number_of_ones = 20;
- u8 aksv[5] = {0};
- pr_debug("AKSV=%02x%08x\n", aksv_msb, aksv_lsb);
- aksv[0] = aksv_lsb & 0xFF;
- aksv[1] = (aksv_lsb >> 8) & 0xFF;
- aksv[2] = (aksv_lsb >> 16) & 0xFF;
- aksv[3] = (aksv_lsb >> 24) & 0xFF;
- aksv[4] = aksv_msb & 0xFF;
- /* check there are 20 ones in AKSV */
- if (hdcp1_count_ones(aksv, 5) != number_of_ones) {
- pr_err("AKSV bit count failed\n");
- return -EINVAL;
- }
- return 0;
- }
- bool hdcp2_feature_supported(void *data)
- {
- int ret = 0;
- mutex_lock(&hdcp2_mutex_g);
- ret = ta_interface.trusted_app_hdcp2_feature_supported(data);
- mutex_unlock(&hdcp2_mutex_g);
- return ret;
- }
- EXPORT_SYMBOL_GPL(hdcp2_feature_supported);
- int hdcp2_force_encryption(void *ctx, uint32_t enable)
- {
- int ret = 0;
- mutex_lock(&hdcp2_mutex_g);
- ret = ta_interface.trusted_app_hdcp2_force_encryption(ctx, enable);
- mutex_unlock(&hdcp2_mutex_g);
- return ret;
- }
- EXPORT_SYMBOL_GPL(hdcp2_force_encryption);
- int hdcp2_app_comm(void *ctx, enum hdcp2_app_cmd cmd,
- struct hdcp2_app_data *app_data)
- {
- int ret = 0;
- uint32_t req_len = 0;
- if (!ctx || !app_data) {
- pr_err("invalid input\n");
- return -EINVAL;
- }
- req_len = app_data->request.length;
- mutex_lock(&hdcp2_mutex_g);
- switch (cmd) {
- case HDCP2_CMD_START:
- ret = ta_interface.trusted_app_hdcp2_app_start(ctx, req_len);
- break;
- case HDCP2_CMD_START_AUTH:
- ret = ta_interface.trusted_app_hdcp2_app_start_auth(ctx, req_len);
- break;
- case HDCP2_CMD_PROCESS_MSG:
- ret = ta_interface.trusted_app_hdcp2_app_process_msg(ctx, req_len);
- break;
- case HDCP2_CMD_TIMEOUT:
- ret = ta_interface.trusted_app_hdcp2_app_timeout(ctx, req_len);
- break;
- case HDCP2_CMD_EN_ENCRYPTION:
- ret = ta_interface.trusted_app_hdcp2_app_enable_encryption(ctx, req_len);
- break;
- case HDCP2_CMD_QUERY_STREAM:
- ret = ta_interface.trusted_app_hdcp2_app_query_stream(ctx, req_len);
- break;
- case HDCP2_CMD_STOP:
- ret = ta_interface.trusted_app_hdcp2_app_stop(ctx);
- break;
- default:
- goto error;
- }
- if (ret)
- goto error;
- ret = ta_interface.trusted_app_hdcp2_update_app_data(ctx, app_data);
- error:
- mutex_unlock(&hdcp2_mutex_g);
- return ret;
- }
- EXPORT_SYMBOL_GPL(hdcp2_app_comm);
- int hdcp2_open_stream(void *ctx, uint8_t vc_payload_id, uint8_t stream_number,
- uint32_t *stream_id)
- {
- int ret = 0;
- mutex_lock(&hdcp2_mutex_g);
- ret = ta_interface.trusted_app_hdcp2_open_stream(ctx, vc_payload_id, stream_number,
- stream_id);
- mutex_unlock(&hdcp2_mutex_g);
- return ret;
- }
- EXPORT_SYMBOL_GPL(hdcp2_open_stream);
- int hdcp2_close_stream(void *ctx, uint32_t stream_id)
- {
- int ret = 0;
- mutex_lock(&hdcp2_mutex_g);
- ret = ta_interface.trusted_app_hdcp2_close_stream(ctx, stream_id);
- mutex_unlock(&hdcp2_mutex_g);
- return ret;
- }
- EXPORT_SYMBOL_GPL(hdcp2_close_stream);
- void *hdcp2_init(u32 device_type)
- {
- void *data = NULL;
- mutex_lock(&hdcp2_mutex_g);
- data = ta_interface.trusted_app_hdcp2_init(device_type);
- mutex_unlock(&hdcp2_mutex_g);
- return data;
- }
- EXPORT_SYMBOL_GPL(hdcp2_init);
- void hdcp2_set_hdcp_key_verify_retries(void *ctx, u32 max_hdcp_key_verify_retries)
- {
- struct hdcp2_qsee_handle *handle = ctx;
- handle->max_hdcp_key_verify_retries = max_hdcp_key_verify_retries;
- pr_debug("hdcp2 max_hdcp_key_verify_retries %d\n", handle->max_hdcp_key_verify_retries);
- }
- EXPORT_SYMBOL_GPL(hdcp2_set_hdcp_key_verify_retries);
- void hdcp2_deinit(void *ctx)
- {
- ta_interface.trusted_app_hdcp2_deinit(ctx);
- }
- EXPORT_SYMBOL_GPL(hdcp2_deinit);
- void *hdcp1_init(void)
- {
- void *data = NULL;
- mutex_lock(&hdcp1_mutex_g);
- data = ta_interface.trusted_app_hdcp1_init();
- mutex_unlock(&hdcp1_mutex_g);
- return data;
- }
- EXPORT_SYMBOL_GPL(hdcp1_init);
- void hdcp1_set_hdcp_key_verify_retries(void *ctx, u32 max_hdcp_key_verify_retries)
- {
- struct hdcp1_qsee_handle *handle = ctx;
- handle->max_hdcp_key_verify_retries = max_hdcp_key_verify_retries;
- pr_debug("hdcp1 max_hdcp_key_verify_retries %d\n", handle->max_hdcp_key_verify_retries);
- }
- EXPORT_SYMBOL_GPL(hdcp1_set_hdcp_key_verify_retries);
- void hdcp1_deinit(void *data)
- {
- kfree(data);
- }
- EXPORT_SYMBOL_GPL(hdcp1_deinit);
- bool hdcp1_feature_supported(void *data)
- {
- bool supported = false;
- mutex_lock(&hdcp1_mutex_g);
- supported = ta_interface.trusted_app_hdcp1_feature_supported(data);
- mutex_unlock(&hdcp1_mutex_g);
- return supported;
- }
- EXPORT_SYMBOL_GPL(hdcp1_feature_supported);
- int hdcp1_set_enc(void *data, bool enable)
- {
- int ret = 0;
- mutex_lock(&hdcp1_mutex_g);
- ret = ta_interface.trusted_app_hdcp1_set_enc(data, enable);
- mutex_unlock(&hdcp1_mutex_g);
- return ret;
- }
- EXPORT_SYMBOL_GPL(hdcp1_set_enc);
- int hdcp1_ops_notify(void *data, void *topo, bool is_authenticated)
- {
- int ret = 0;
- ret = ta_interface.trusted_app_hdcp1_ops_notify(data, topo, is_authenticated);
- return ret;
- }
- EXPORT_SYMBOL_GPL(hdcp1_ops_notify);
- int hdcp1_start(void *data, u32 *aksv_msb, u32 *aksv_lsb)
- {
- int ret = 0;
- mutex_lock(&hdcp1_mutex_g);
- ret = ta_interface.trusted_app_hdcp1_start(data, aksv_msb, aksv_lsb);
- mutex_unlock(&hdcp1_mutex_g);
- return ret;
- }
- EXPORT_SYMBOL_GPL(hdcp1_start);
- void hdcp1_stop(void *data)
- {
- mutex_lock(&hdcp1_mutex_g);
- ta_interface.trusted_app_hdcp1_stop(data);
- mutex_unlock(&hdcp1_mutex_g);
- }
- EXPORT_SYMBOL_GPL(hdcp1_stop);
- static int __init hdcp_module_init(void)
- {
- struct device_node *np = NULL;
- bool use_smcinvoke = false;
- np = of_find_compatible_node(NULL, NULL, "qcom,hdcp");
- if (!np) {
- /*select qseecom interface as default if hdcp node
- *is not present in dtsi
- */
- select_interface(use_smcinvoke);
- return 0;
- }
- use_smcinvoke = of_property_read_bool(np, "qcom,use-smcinvoke");
- select_interface(use_smcinvoke);
- return 0;
- }
- static void __exit hdcp_module_exit(void)
- {
- }
- MODULE_LICENSE("GPL v2");
- MODULE_DESCRIPTION("HDCP driver");
- module_init(hdcp_module_init);
- module_exit(hdcp_module_exit);
|