summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/msm/sde_hdcp.h2
-rw-r--r--drivers/gpu/drm/msm/sde_hdcp_1x.c163
-rw-r--r--drivers/gpu/msm/kgsl_iommu.c8
-rw-r--r--drivers/misc/hdcp.c205
-rw-r--r--drivers/pci/host/pci-msm.c25
-rw-r--r--include/linux/hdcp_qseecom.h12
-rw-r--r--sound/soc/codecs/wcd934x/wcd934x.c17
7 files changed, 398 insertions, 34 deletions
diff --git a/drivers/gpu/drm/msm/sde_hdcp.h b/drivers/gpu/drm/msm/sde_hdcp.h
index c414f68a8e0d..415e8467c99f 100644
--- a/drivers/gpu/drm/msm/sde_hdcp.h
+++ b/drivers/gpu/drm/msm/sde_hdcp.h
@@ -33,6 +33,8 @@
#define SDE_HDCP_DEBUG(fmt, args...) SDE_DEBUG(fmt, ##args)
#endif
+#define SDE_HDCP_SRM_FAIL 29
+
enum sde_hdcp_client_id {
HDCP_CLIENT_HDMI,
HDCP_CLIENT_DP,
diff --git a/drivers/gpu/drm/msm/sde_hdcp_1x.c b/drivers/gpu/drm/msm/sde_hdcp_1x.c
index c2d29a084c7f..6c69cd58c0ed 100644
--- a/drivers/gpu/drm/msm/sde_hdcp_1x.c
+++ b/drivers/gpu/drm/msm/sde_hdcp_1x.c
@@ -748,6 +748,107 @@ error:
return rc;
}
+static u8 *sde_hdcp_1x_swap_byte_order(u8 *bksv_in, int num_dev)
+{
+ u8 *bksv_out;
+ u8 *tmp_out;
+ u8 *tmp_in;
+ int i, j;
+
+ /* Dont exceed max downstream devices */
+ if (num_dev > MAX_DEVICES_SUPPORTED) {
+ pr_err("invalid params\n");
+ return NULL;
+ }
+
+ bksv_out = kzalloc(RECV_ID_SIZE * num_dev, GFP_KERNEL);
+
+ if (!bksv_out)
+ return NULL;
+
+ SDE_HDCP_DEBUG("num_dev = %d\n", num_dev);
+
+ /* Store temporarily for return */
+ tmp_out = bksv_out;
+ tmp_in = bksv_in;
+
+ for (i = 0; i < num_dev; i++) {
+ for (j = 0; j < RECV_ID_SIZE; j++)
+ bksv_out[j] = tmp_in[RECV_ID_SIZE - j - 1];
+
+ /* Each KSV is 5 bytes long */
+ bksv_out += RECV_ID_SIZE;
+ tmp_in += RECV_ID_SIZE;
+ }
+
+ return tmp_out;
+}
+
+static int sde_hdcp_1x_revoked_rcv_chk(struct sde_hdcp_1x *hdcp)
+{
+ int rc = 0;
+ u8 *bksv = hdcp->current_tp.bksv;
+ u8 *bksv_out;
+ struct hdcp_srm_device_id_t *bksv_srm;
+
+ bksv_out = sde_hdcp_1x_swap_byte_order(bksv, 1);
+
+ if (!bksv_out) {
+ rc = -ENOMEM;
+ goto exit;
+ }
+
+ SDE_HDCP_DEBUG("bksv_out : 0x%2x%2x%2x%2x%2x\n",
+ bksv_out[4], bksv_out[3], bksv_out[2],
+ bksv_out[1], bksv_out[0]);
+
+ bksv_srm = (struct hdcp_srm_device_id_t *)bksv_out;
+ /* Here we are checking only receiver ID
+ * hence the device count is one
+ */
+ rc = hdcp1_validate_receiver_ids(bksv_srm, 1);
+
+ kfree(bksv_out);
+
+exit:
+ return rc;
+}
+
+static int sde_hdcp_1x_revoked_rpt_chk(struct sde_hdcp_1x *hdcp)
+{
+ int rc = 0;
+ int i;
+ u8 *bksv = hdcp->current_tp.ksv_list;
+ u8 *bksv_out;
+ struct hdcp_srm_device_id_t *bksv_srm;
+
+ for (i = 0; i < hdcp->sink_addr.ksv_fifo.len;
+ i += RECV_ID_SIZE) {
+ SDE_HDCP_DEBUG("bksv : 0x%2x%2x%2x%2x%2x\n",
+ bksv[i + 4],
+ bksv[i + 3], bksv[i + 2],
+ bksv[i + 1], bksv[i]);
+ }
+
+ bksv_out = sde_hdcp_1x_swap_byte_order(bksv,
+ hdcp->current_tp.dev_count);
+
+ if (!bksv_out) {
+ rc = -ENOMEM;
+ goto exit;
+ }
+
+ bksv_srm = (struct hdcp_srm_device_id_t *)bksv_out;
+ /* Here we are checking repeater ksv list */
+ rc = hdcp1_validate_receiver_ids(bksv_srm,
+ hdcp->current_tp.dev_count);
+
+ kfree(bksv_out);
+
+exit:
+ return rc;
+}
+
static void sde_hdcp_1x_enable_sink_irq_hpd(struct sde_hdcp_1x *hdcp)
{
int rc;
@@ -872,6 +973,12 @@ static int sde_hdcp_1x_authentication_part1(struct sde_hdcp_1x *hdcp)
if (rc)
goto error;
+ rc = sde_hdcp_1x_revoked_rcv_chk(hdcp);
+ if (rc) {
+ rc = -SDE_HDCP_SRM_FAIL;
+ goto error;
+ }
+
rc = sde_hdcp_1x_send_an_aksv_to_sink(hdcp);
if (rc)
goto error;
@@ -1196,6 +1303,12 @@ static int sde_hdcp_1x_authentication_part2(struct sde_hdcp_1x *hdcp)
if (rc)
goto error;
+ rc = sde_hdcp_1x_revoked_rpt_chk(hdcp);
+ if (rc) {
+ rc = -SDE_HDCP_SRM_FAIL;
+ goto error;
+ }
+
do {
rc = sde_hdcp_1x_transfer_v_h(hdcp);
if (rc)
@@ -1317,8 +1430,11 @@ static void sde_hdcp_1x_auth_work(struct work_struct *work)
end:
- if (rc && !sde_hdcp_1x_state(HDCP_STATE_INACTIVE))
+ if (rc && !sde_hdcp_1x_state(HDCP_STATE_INACTIVE)) {
hdcp->hdcp_state = HDCP_STATE_AUTH_FAIL;
+ if (rc == -SDE_HDCP_SRM_FAIL)
+ hdcp->hdcp_state = HDCP_STATE_AUTH_FAIL_NOREAUTH;
+ }
/*
* Disabling software DDC before going into part3 to make sure
@@ -1581,6 +1697,7 @@ void sde_hdcp_1x_deinit(void *input)
if (hdcp->workq)
destroy_workqueue(hdcp->workq);
+ hdcp1_client_unregister();
kfree(hdcp);
} /* hdcp_1x_deinit */
@@ -1680,6 +1797,44 @@ irq_not_handled:
return -EINVAL;
}
+static void sde_hdcp_1x_srm_cb(void *input)
+{
+
+ struct sde_hdcp_1x *hdcp = (struct sde_hdcp_1x *)input;
+ int rc = 0;
+
+ if (!hdcp) {
+ pr_err("invalid input\n");
+ return;
+ }
+
+ rc = sde_hdcp_1x_revoked_rcv_chk(hdcp);
+
+ if (rc) {
+ pr_err("receiver failed SRM check\n");
+ goto fail_noreauth;
+ }
+
+ /* If its not a repeater we are done */
+ if (hdcp->current_tp.ds_type != DS_REPEATER)
+ return;
+
+
+ /* Check the repeater KSV against SRM */
+ rc = sde_hdcp_1x_revoked_rpt_chk(hdcp);
+ if (rc) {
+ pr_err("repeater failed SRM check\n");
+ goto fail_noreauth;
+ }
+
+ return;
+
+ fail_noreauth:
+ /* No reauth in case of SRM failure */
+ hdcp->hdcp_state = HDCP_STATE_AUTH_FAIL_NOREAUTH;
+ sde_hdcp_1x_update_auth_status(hdcp);
+}
+
void *sde_hdcp_1x_init(struct sde_hdcp_init_data *init_data)
{
struct sde_hdcp_1x *hdcp = NULL;
@@ -1692,6 +1847,10 @@ void *sde_hdcp_1x_init(struct sde_hdcp_init_data *init_data)
.off = sde_hdcp_1x_off
};
+ static struct hdcp_client_ops client_ops = {
+ .srm_cb = sde_hdcp_1x_srm_cb,
+ };
+
if (!init_data || !init_data->core_io || !init_data->qfprom_io ||
!init_data->mutex || !init_data->notify_status ||
!init_data->workq || !init_data->cb_data) {
@@ -1729,6 +1888,8 @@ void *sde_hdcp_1x_init(struct sde_hdcp_init_data *init_data)
init_completion(&hdcp->r0_checked);
init_completion(&hdcp->sink_r0_available);
+ /* Register client ctx and the srm_cb with hdcp lib */
+ hdcp1_client_register((void *)hdcp, &client_ops);
SDE_HDCP_DEBUG("HDCP module initialized. HDCP_STATE=%s\n",
SDE_HDCP_STATE_NAME);
diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c
index 57d99c451952..1ca8dca68470 100644
--- a/drivers/gpu/msm/kgsl_iommu.c
+++ b/drivers/gpu/msm/kgsl_iommu.c
@@ -118,9 +118,11 @@ void kgsl_print_global_pt_entries(struct seq_file *s)
if (memdesc == NULL)
continue;
- seq_printf(s, "0x%16.16llX-0x%16.16llX %16llu %s\n",
- memdesc->gpuaddr, memdesc->gpuaddr + memdesc->size - 1,
- memdesc->size, global_pt_entries[i].name);
+ seq_printf(s, "0x%pK-0x%pK %16llu %s\n",
+ (uint64_t *)(uintptr_t) memdesc->gpuaddr,
+ (uint64_t *)(uintptr_t) (memdesc->gpuaddr +
+ memdesc->size - 1), memdesc->size,
+ global_pt_entries[i].name);
}
}
diff --git a/drivers/misc/hdcp.c b/drivers/misc/hdcp.c
index 87daee7cf1c6..09c7c1eeca7a 100644
--- a/drivers/misc/hdcp.c
+++ b/drivers/misc/hdcp.c
@@ -93,6 +93,8 @@
#define RXINFO_SIZE 2
#define SEQ_NUM_V_SIZE 3
+#define HDCP_SRM_CMD_CHECK_DEVICE_ID 2
+
#define RCVR_ID_SIZE BITS_40_IN_BYTES
#define MAX_RCVR_IDS_ALLOWED_IN_LIST 31
#define MAX_RCVR_ID_LIST_SIZE \
@@ -437,6 +439,17 @@ struct __attribute__ ((__packed__)) hdcp_update_srm_rsp {
uint32_t commandid;
};
+struct __attribute__ ((__packed__)) hdcp_srm_check_device_ids_req {
+ uint32_t commandid;
+ uint32_t num_device_ids;
+ uint8_t device_ids[1];
+};
+
+struct __attribute__ ((__packed__)) hdcp_srm_check_device_ids_rsp {
+ uint32_t commandid;
+ int32_t retval;
+};
+
struct __attribute__ ((__packed__)) hdcp_get_topology_req {
uint32_t commandid;
uint32_t ctxhandle;
@@ -497,6 +510,20 @@ struct __attribute__ ((__packed__)) hdcp_rcv_id_list_rsp {
};
/*
+ * struct hdcp1_lib_handle - handle for hdcp1 client
+ * @qseecom_handle - for sending commands to hdcp1 TA
+ * @srm_handle - for sending commands to SRM TA
+ * @client_ops - handle to call APIs exposed by hdcp1 client
+ * @client_ctx - client context maintained by hdmi
+ */
+struct hdcp1_lib_handle {
+ struct qseecom_handle *qsee_handle;
+ struct qseecom_handle *srm_handle;
+ struct hdcp_client_ops *client_ops;
+ void *client_ctx;
+};
+
+/*
* struct hdcp_lib_handle - handle for hdcp client
* @qseecom_handle - for sending commands to qseecom
* @listener_buf - buffer containing message shared with the client
@@ -585,9 +612,10 @@ static void hdcp_lib_stream(struct hdcp_lib_handle *handle);
static int hdcp_lib_txmtr_init(struct hdcp_lib_handle *handle);
static int hdcp_lib_txmtr_init_legacy(struct hdcp_lib_handle *handle);
-static struct qseecom_handle *hdcp1_handle;
static struct qseecom_handle *hdcpsrm_handle;
+static struct hdcp1_lib_handle *hdcp1_handle;
+
static bool hdcp1_supported = true;
static bool hdcp1_enc_enabled;
static struct mutex hdcp1_ta_cmd_lock;
@@ -2283,31 +2311,69 @@ static void hdcp_lib_wait_work(struct kthread_work *work)
bool hdcp1_check_if_supported_load_app(void)
{
int rc = 0;
+ bool hdcp1_srm_supported = true;
/* start hdcp1 app */
- if (hdcp1_supported && !hdcp1_handle) {
- rc = qseecom_start_app(&hdcp1_handle, HDCP1_APP_NAME,
- QSEECOM_SBUFF_SIZE);
+ if (hdcp1_supported && !hdcp1_handle->qsee_handle) {
+ rc = qseecom_start_app(&hdcp1_handle->qsee_handle,
+ HDCP1_APP_NAME,
+ QSEECOM_SBUFF_SIZE);
if (rc) {
- pr_err("qseecom_start_app failed %d\n", rc);
+ pr_err("hdcp1 qseecom_start_app failed %d\n", rc);
hdcp1_supported = false;
- } else {
- mutex_init(&hdcp1_ta_cmd_lock);
+ kfree(hdcp1_handle);
+ }
+ }
+
+ /* if hdcp1 app succeeds load SRM TA as well */
+ if (hdcp1_supported && !hdcp1_handle->srm_handle) {
+ mutex_init(&hdcp1_ta_cmd_lock);
+ rc = qseecom_start_app(&hdcp1_handle->srm_handle,
+ SRMAPP_NAME,
+ QSEECOM_SBUFF_SIZE);
+ if (rc) {
+ hdcp1_srm_supported = false;
+ pr_err("hdcp1_srm qseecom_start_app failed %d\n", rc);
}
}
pr_debug("hdcp1 app %s loaded\n",
hdcp1_supported ? "successfully" : "not");
+ pr_debug("hdcp1 srm app %s loaded\n",
+ hdcp1_srm_supported ? "successfully" : "not");
return hdcp1_supported;
}
+void hdcp1_client_register(void *client_ctx, struct hdcp_client_ops *ops)
+{
+ /* initialize the hdcp1 handle */
+ hdcp1_handle = kzalloc(sizeof(*hdcp1_handle), GFP_KERNEL);
+
+ if (hdcp1_handle) {
+ hdcp1_handle->client_ops = ops;
+ hdcp1_handle->client_ctx = client_ctx;
+ }
+}
+
+void hdcp1_client_unregister(void)
+{
+ if (hdcp1_handle && hdcp1_handle->qsee_handle)
+ qseecom_shutdown_app(&hdcp1_handle->qsee_handle);
+
+ if (hdcp1_handle && hdcp1_handle->srm_handle)
+ qseecom_shutdown_app(&hdcp1_handle->srm_handle);
+
+ kfree(hdcp1_handle);
+}
+
/* APIs exposed to all clients */
int hdcp1_set_keys(uint32_t *aksv_msb, uint32_t *aksv_lsb)
{
int rc = 0;
struct hdcp1_key_set_req *key_set_req;
struct hdcp1_key_set_rsp *key_set_rsp;
+ struct qseecom_handle *hdcp1_qsee_handle;
if (aksv_msb == NULL || aksv_lsb == NULL)
return -EINVAL;
@@ -2315,12 +2381,17 @@ int hdcp1_set_keys(uint32_t *aksv_msb, uint32_t *aksv_lsb)
if (!hdcp1_supported || !hdcp1_handle)
return -EINVAL;
+ hdcp1_qsee_handle = hdcp1_handle->qsee_handle;
+
+ if (!hdcp1_qsee_handle)
+ return -EINVAL;
+
/* set keys and request aksv */
- key_set_req = (struct hdcp1_key_set_req *)hdcp1_handle->sbuf;
+ key_set_req = (struct hdcp1_key_set_req *)hdcp1_qsee_handle->sbuf;
key_set_req->commandid = HDCP1_SET_KEY_MESSAGE_ID;
- key_set_rsp = (struct hdcp1_key_set_rsp *)(hdcp1_handle->sbuf +
+ key_set_rsp = (struct hdcp1_key_set_rsp *)(hdcp1_qsee_handle->sbuf +
QSEECOM_ALIGN(sizeof(struct hdcp1_key_set_req)));
- rc = qseecom_send_command(hdcp1_handle, key_set_req,
+ rc = qseecom_send_command(hdcp1_qsee_handle, key_set_req,
QSEECOM_ALIGN(sizeof
(struct hdcp1_key_set_req)),
key_set_rsp,
@@ -2351,6 +2422,85 @@ int hdcp1_set_keys(uint32_t *aksv_msb, uint32_t *aksv_lsb)
return 0;
}
+int hdcp1_validate_receiver_ids(struct hdcp_srm_device_id_t *device_ids,
+ uint32_t device_id_cnt)
+{
+ int rc = 0;
+ struct hdcp_srm_check_device_ids_req *recv_id_req;
+ struct hdcp_srm_check_device_ids_rsp *recv_id_rsp;
+ uint32_t sbuf_len;
+ uint32_t rbuf_len;
+ int i = 0;
+ struct qseecom_handle *hdcp1_srmhandle;
+
+ /* If client has not been registered return */
+ if (!hdcp1_supported || !hdcp1_handle)
+ return -EINVAL;
+
+ /* Start the hdcp srm app if not already started */
+ if (hdcp1_handle && !hdcp1_handle->srm_handle) {
+ rc = qseecom_start_app(&hdcp1_handle->srm_handle,
+ SRMAPP_NAME, QSEECOM_SBUFF_SIZE);
+ if (rc) {
+ pr_err("qseecom_start_app failed for SRM TA %d\n", rc);
+ goto end;
+ }
+ }
+
+ pr_debug("device_id_cnt = %d\n", device_id_cnt);
+
+ hdcp1_srmhandle = hdcp1_handle->srm_handle;
+
+ sbuf_len = sizeof(struct hdcp_srm_check_device_ids_req)
+ + sizeof(struct hdcp_srm_device_id_t) * device_id_cnt
+ - 1;
+
+ rbuf_len = sizeof(struct hdcp_srm_check_device_ids_rsp);
+
+ /* Create a SRM validate receiver ID request */
+ recv_id_req = (struct hdcp_srm_check_device_ids_req *)
+ hdcp1_srmhandle->sbuf;
+ recv_id_req->commandid = HDCP_SRM_CMD_CHECK_DEVICE_ID;
+ recv_id_req->num_device_ids = device_id_cnt;
+ memcpy(recv_id_req->device_ids, device_ids,
+ device_id_cnt * sizeof(struct hdcp_srm_device_id_t));
+
+ for (i = 0; i < device_id_cnt * sizeof(struct hdcp_srm_device_id_t);
+ i++) {
+ pr_debug("recv_id_req->device_ids[%d] = 0x%x\n", i,
+ recv_id_req->device_ids[i]);
+ }
+
+ recv_id_rsp = (struct hdcp_srm_check_device_ids_rsp *)
+ (hdcp1_srmhandle->sbuf +
+ QSEECOM_ALIGN(sbuf_len));
+
+ rc = qseecom_send_command(hdcp1_srmhandle,
+ recv_id_req,
+ QSEECOM_ALIGN(sbuf_len),
+ recv_id_rsp,
+ QSEECOM_ALIGN(rbuf_len));
+
+ if (rc < 0) {
+ pr_err("qseecom cmd failed err=%d\n", rc);
+ goto end;
+ }
+
+ rc = recv_id_rsp->retval;
+ if (rc) {
+ pr_err("enc cmd failed, rsp=%d\n", recv_id_rsp->retval);
+ rc = -EINVAL;
+ goto end;
+ }
+
+ pr_debug("rsp=%d\n", recv_id_rsp->retval);
+ pr_debug("commandid=%d\n", recv_id_rsp->commandid);
+
+end:
+ return rc;
+}
+
+
static int hdcp_validate_recv_id(struct hdcp_lib_handle *handle)
{
int rc = 0;
@@ -2398,6 +2548,7 @@ int hdcp1_set_enc(bool enable)
int rc = 0;
struct hdcp1_set_enc_req *set_enc_req;
struct hdcp1_set_enc_rsp *set_enc_rsp;
+ struct qseecom_handle *hdcp1_qsee_handle;
mutex_lock(&hdcp1_ta_cmd_lock);
@@ -2406,18 +2557,23 @@ int hdcp1_set_enc(bool enable)
goto end;
}
+ hdcp1_qsee_handle = hdcp1_handle->qsee_handle;
+
+ if (!hdcp1_qsee_handle)
+ return -EINVAL;
+
if (hdcp1_enc_enabled == enable) {
pr_info("already %s\n", enable ? "enabled" : "disabled");
goto end;
}
/* set keys and request aksv */
- set_enc_req = (struct hdcp1_set_enc_req *)hdcp1_handle->sbuf;
+ set_enc_req = (struct hdcp1_set_enc_req *)hdcp1_qsee_handle->sbuf;
set_enc_req->commandid = HDCP1_SET_ENC_MESSAGE_ID;
set_enc_req->enable = enable;
- set_enc_rsp = (struct hdcp1_set_enc_rsp *)(hdcp1_handle->sbuf +
+ set_enc_rsp = (struct hdcp1_set_enc_rsp *)(hdcp1_qsee_handle->sbuf +
QSEECOM_ALIGN(sizeof(struct hdcp1_set_enc_req)));
- rc = qseecom_send_command(hdcp1_handle, set_enc_req,
+ rc = qseecom_send_command(hdcp1_qsee_handle, set_enc_req,
QSEECOM_ALIGN(sizeof
(struct hdcp1_set_enc_req)),
set_enc_rsp,
@@ -2679,6 +2835,8 @@ static ssize_t hdmi_hdcp_srm_updated(struct device *dev,
int srm_updated;
struct hdcp_lib_handle *handle;
ssize_t ret = count;
+ struct hdcp_client_ops *client_ops;
+ void *hdcp_client_ctx;
handle = hdcp_drv_mgr->handle;
@@ -2689,12 +2847,21 @@ static ssize_t hdmi_hdcp_srm_updated(struct device *dev,
}
if (srm_updated) {
- if (hdcp_validate_recv_id(handle)) {
- pr_debug("SRM check FAILED\n");
- if (handle && handle->client_ops->srm_cb)
- handle->client_ops->srm_cb(handle->client_ctx);
- } else {
- pr_debug("SRM check PASSED\n");
+ if (handle && handle->qseecom_handle) {
+ client_ops = handle->client_ops;
+ hdcp_client_ctx = handle->client_ctx;
+ if (hdcp_validate_recv_id(handle)) {
+ pr_debug("HDCP 2.2 SRM check FAILED\n");
+ if (handle && client_ops->srm_cb)
+ client_ops->srm_cb(hdcp_client_ctx);
+ } else
+ pr_debug("HDCP 2.2 SRM check PASSED\n");
+ } else if (hdcp1_handle && hdcp1_handle->qsee_handle) {
+ pr_debug("HDCP 1.4 SRM check\n");
+ hdcp_client_ctx = hdcp1_handle->client_ctx;
+ client_ops = hdcp1_handle->client_ops;
+ if (client_ops->srm_cb)
+ client_ops->srm_cb(hdcp_client_ctx);
}
}
diff --git a/drivers/pci/host/pci-msm.c b/drivers/pci/host/pci-msm.c
index a741c9c7d115..0ecf64f4afe9 100644
--- a/drivers/pci/host/pci-msm.c
+++ b/drivers/pci/host/pci-msm.c
@@ -6865,17 +6865,24 @@ static int msm_pcie_pm_resume(struct pci_dev *dev,
dev->bus->number, dev->bus->primary);
if (!(options & MSM_PCIE_CONFIG_NO_CFG_RESTORE)) {
- PCIE_DBG(pcie_dev,
- "RC%d: entry of PCI framework restore state\n",
- pcie_dev->rc_idx);
+ if (pcie_dev->saved_state) {
+ PCIE_DBG(pcie_dev,
+ "RC%d: entry of PCI framework restore state\n",
+ pcie_dev->rc_idx);
- pci_load_and_free_saved_state(dev,
- &pcie_dev->saved_state);
- pci_restore_state(dev);
+ pci_load_and_free_saved_state(dev,
+ &pcie_dev->saved_state);
+ pci_restore_state(dev);
- PCIE_DBG(pcie_dev,
- "RC%d: exit of PCI framework restore state\n",
- pcie_dev->rc_idx);
+ PCIE_DBG(pcie_dev,
+ "RC%d: exit of PCI framework restore state\n",
+ pcie_dev->rc_idx);
+ } else {
+ PCIE_DBG(pcie_dev,
+ "RC%d: restore rc config space using shadow recovery\n",
+ pcie_dev->rc_idx);
+ msm_pcie_cfg_recover(pcie_dev, true);
+ }
}
}
diff --git a/include/linux/hdcp_qseecom.h b/include/linux/hdcp_qseecom.h
index 8e1b853e738e..11c2af725bb1 100644
--- a/include/linux/hdcp_qseecom.h
+++ b/include/linux/hdcp_qseecom.h
@@ -15,6 +15,8 @@
#include <linux/types.h>
#define HDCP_MAX_MESSAGE_PARTS 4
+#define RECV_ID_SIZE 5
+#define MAX_DEVICES_SUPPORTED 127
enum hdcp_lib_wakeup_cmd {
HDCP_LIB_WKUP_CMD_INVALID,
@@ -115,6 +117,10 @@ static inline char *hdcp_lib_cmd_to_str(uint32_t cmd)
}
}
+struct hdcp_srm_device_id_t {
+ uint8_t data[RECV_ID_SIZE];
+};
+
struct hdcp_txmtr_ops {
int (*wakeup)(struct hdcp_lib_wakeup_data *data);
bool (*feature_supported)(void *phdcpcontext);
@@ -148,6 +154,12 @@ void hdcp_library_deregister(void *phdcpcontext);
bool hdcp1_check_if_supported_load_app(void);
int hdcp1_set_keys(uint32_t *aksv_msb, uint32_t *aksv_lsb);
int hdcp1_set_enc(bool enable);
+int hdcp1_validate_receiver_ids(struct hdcp_srm_device_id_t *device_ids,
+uint32_t device_id_cnt);
void hdcp1_cache_repeater_topology(void *hdcp1_cached_tp);
void hdcp1_notify_topology(void);
+void hdcp1_client_register(void *client_ctx,
+struct hdcp_client_ops *ops);
+void hdcp1_client_unregister(void);
+
#endif /* __HDCP_QSEECOM_H */
diff --git a/sound/soc/codecs/wcd934x/wcd934x.c b/sound/soc/codecs/wcd934x/wcd934x.c
index bfe471e73503..c8cc17d4dfd3 100644
--- a/sound/soc/codecs/wcd934x/wcd934x.c
+++ b/sound/soc/codecs/wcd934x/wcd934x.c
@@ -2996,7 +2996,7 @@ static int tavil_codec_enable_asrc(struct snd_soc_codec *codec,
int asrc_in, int event)
{
struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec);
- u16 cfg_reg, ctl_reg, clk_reg, asrc_ctl, mix_ctl_reg;
+ u16 cfg_reg, ctl_reg, clk_reg, asrc_ctl, mix_ctl_reg, paired_reg;
int asrc, ret = 0;
u8 main_sr, mix_sr, asrc_mode = 0;
@@ -3005,6 +3005,7 @@ static int tavil_codec_enable_asrc(struct snd_soc_codec *codec,
cfg_reg = WCD934X_CDC_RX1_RX_PATH_CFG0;
ctl_reg = WCD934X_CDC_RX1_RX_PATH_CTL;
clk_reg = WCD934X_MIXING_ASRC0_CLK_RST_CTL;
+ paired_reg = WCD934X_MIXING_ASRC1_CLK_RST_CTL;
asrc_ctl = WCD934X_MIXING_ASRC0_CTL1;
asrc = ASRC0;
break;
@@ -3012,6 +3013,7 @@ static int tavil_codec_enable_asrc(struct snd_soc_codec *codec,
cfg_reg = WCD934X_CDC_RX3_RX_PATH_CFG0;
ctl_reg = WCD934X_CDC_RX3_RX_PATH_CTL;
clk_reg = WCD934X_MIXING_ASRC0_CLK_RST_CTL;
+ paired_reg = WCD934X_MIXING_ASRC1_CLK_RST_CTL;
asrc_ctl = WCD934X_MIXING_ASRC0_CTL1;
asrc = ASRC0;
break;
@@ -3019,6 +3021,7 @@ static int tavil_codec_enable_asrc(struct snd_soc_codec *codec,
cfg_reg = WCD934X_CDC_RX2_RX_PATH_CFG0;
ctl_reg = WCD934X_CDC_RX2_RX_PATH_CTL;
clk_reg = WCD934X_MIXING_ASRC1_CLK_RST_CTL;
+ paired_reg = WCD934X_MIXING_ASRC0_CLK_RST_CTL;
asrc_ctl = WCD934X_MIXING_ASRC1_CTL1;
asrc = ASRC1;
break;
@@ -3026,6 +3029,7 @@ static int tavil_codec_enable_asrc(struct snd_soc_codec *codec,
cfg_reg = WCD934X_CDC_RX4_RX_PATH_CFG0;
ctl_reg = WCD934X_CDC_RX4_RX_PATH_CTL;
clk_reg = WCD934X_MIXING_ASRC1_CLK_RST_CTL;
+ paired_reg = WCD934X_MIXING_ASRC0_CLK_RST_CTL;
asrc_ctl = WCD934X_MIXING_ASRC1_CTL1;
asrc = ASRC1;
break;
@@ -3033,6 +3037,7 @@ static int tavil_codec_enable_asrc(struct snd_soc_codec *codec,
cfg_reg = WCD934X_CDC_RX7_RX_PATH_CFG0;
ctl_reg = WCD934X_CDC_RX7_RX_PATH_CTL;
clk_reg = WCD934X_MIXING_ASRC2_CLK_RST_CTL;
+ paired_reg = WCD934X_MIXING_ASRC3_CLK_RST_CTL;
asrc_ctl = WCD934X_MIXING_ASRC2_CTL1;
asrc = ASRC2;
break;
@@ -3040,6 +3045,7 @@ static int tavil_codec_enable_asrc(struct snd_soc_codec *codec,
cfg_reg = WCD934X_CDC_RX8_RX_PATH_CFG0;
ctl_reg = WCD934X_CDC_RX8_RX_PATH_CTL;
clk_reg = WCD934X_MIXING_ASRC3_CLK_RST_CTL;
+ paired_reg = WCD934X_MIXING_ASRC2_CLK_RST_CTL;
asrc_ctl = WCD934X_MIXING_ASRC3_CTL1;
asrc = ASRC3;
break;
@@ -3053,6 +3059,13 @@ static int tavil_codec_enable_asrc(struct snd_soc_codec *codec,
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
if (tavil->asrc_users[asrc] == 0) {
+ if ((snd_soc_read(codec, clk_reg) & 0x02) ||
+ (snd_soc_read(codec, paired_reg) & 0x02)) {
+ snd_soc_update_bits(codec, clk_reg,
+ 0x02, 0x00);
+ snd_soc_update_bits(codec, paired_reg,
+ 0x02, 0x00);
+ }
snd_soc_update_bits(codec, cfg_reg, 0x80, 0x80);
snd_soc_update_bits(codec, clk_reg, 0x01, 0x01);
main_sr = snd_soc_read(codec, ctl_reg) & 0x0F;
@@ -3072,7 +3085,7 @@ static int tavil_codec_enable_asrc(struct snd_soc_codec *codec,
tavil->asrc_users[asrc] = 0;
snd_soc_update_bits(codec, asrc_ctl, 0x07, 0x00);
snd_soc_update_bits(codec, cfg_reg, 0x80, 0x00);
- snd_soc_update_bits(codec, clk_reg, 0x01, 0x00);
+ snd_soc_update_bits(codec, clk_reg, 0x03, 0x02);
}
break;
};