Loading drivers/misc/hdcp.c +22 −12 Original line number Diff line number Diff line Loading @@ -365,6 +365,9 @@ struct hdcp_lib_message_map { const char *msg_name; }; static struct qseecom_handle *hdcp1_handle; static bool hdcp1_supported = true; static const char *hdcp_lib_message_name(int msg_id) { /* Loading Loading @@ -1151,16 +1154,12 @@ static void hdcp_lib_topology_work(struct kthread_work *work) u32 timeout; struct hdcp_lib_handle *handle = container_of(work, struct hdcp_lib_handle, topology); struct hdmi_hdcp_wakeup_data cdata = {HDMI_HDCP_WKUP_CMD_INVALID}; if (!handle) { pr_err("invalid input\n"); return; } cdata.context = handle->client_ctx; cdata.cmd = HDMI_HDCP_WKUP_CMD_RECV_MESSAGE; hdcp_lib_wakeup_client(handle, &cdata); reinit_completion(&handle->topo_wait); timeout = wait_for_completion_timeout(&handle->topo_wait, HZ * 3); Loading @@ -1172,24 +1171,35 @@ static void hdcp_lib_topology_work(struct kthread_work *work) } } bool hdcp1_check_if_supported_load_app(void) { int rc = 0; /* start hdcp1 app */ if (hdcp1_supported && !hdcp1_handle) { rc = qseecom_start_app(&hdcp1_handle, HDCP1_APP_NAME, QSEECOM_SBUFF_SIZE); if (rc) { pr_err("qseecom_start_app failed %d\n", rc); hdcp1_supported = false; } } return hdcp1_supported; } /* 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_handle = NULL; if (aksv_msb == NULL || aksv_lsb == NULL) return -EINVAL; /* start hdcp1 app */ rc = qseecom_start_app(&hdcp1_handle, HDCP1_APP_NAME, QSEECOM_SBUFF_SIZE); if (rc) { pr_err("qseecom_start_app failed %d\n", rc); return -ENOSYS; } if (!hdcp1_supported || !hdcp1_handle) return -EINVAL; /* set keys and request aksv */ key_set_req = (struct hdcp1_key_set_req *)hdcp1_handle->sbuf; Loading drivers/video/msm/mdss/mdss_hdmi_hdcp2p2.c +34 −9 Original line number Diff line number Diff line Loading @@ -56,7 +56,6 @@ struct hdmi_hdcp2p2_ctrl { struct hdmi_hdcp_ops *ops; void *lib_ctx; /* Handle to HDCP 2.2 Trustzone library */ struct hdcp_txmtr_ops *lib; /* Ops for driver to call into TZ */ struct completion rxstatus_completion; /* Rx status interrupt */ enum hdmi_hdcp_wakeup_cmd wakeup_cmd; char *send_msg_buf; Loading Loading @@ -356,7 +355,7 @@ static int hdmi_hdcp2p2_ddc_write_message(struct hdmi_hdcp2p2_ctrl *ctrl, rc = hdmi_ddc_write(ctrl->init_data.ddc_ctrl); if (rc) pr_err("Cannot write HDCP message register"); pr_err("Cannot write HDCP message register\n"); return rc; } Loading Loading @@ -625,11 +624,12 @@ static void hdmi_hdcp2p2_link_work(struct kthread_work *work) int rc = 0; struct hdmi_hdcp2p2_ctrl *ctrl = container_of(work, struct hdmi_hdcp2p2_ctrl, link); struct hdcp_lib_wakeup_data cdata = {HDCP_LIB_WKUP_CMD_STOP}; struct hdcp_lib_wakeup_data cdata = {HDCP_LIB_WKUP_CMD_INVALID}; struct hdmi_tx_ddc_ctrl *ddc_ctrl; struct hdmi_tx_hdcp2p2_ddc_data *ddc_data; u64 mult; struct msm_hdmi_mode_timing_info *timing; char *recvd_msg_buf = NULL; if (!ctrl) { pr_err("invalid input\n"); Loading @@ -643,6 +643,7 @@ static void hdmi_hdcp2p2_link_work(struct kthread_work *work) ddc_ctrl = ctrl->init_data.ddc_ctrl; if (!ddc_ctrl) { rc = -EINVAL; cdata.cmd = HDCP_LIB_WKUP_CMD_STOP; goto exit; } Loading @@ -654,27 +655,53 @@ static void hdmi_hdcp2p2_link_work(struct kthread_work *work) timing = ctrl->init_data.timing; mult = hdmi_tx_get_v_total(timing) / 20; ddc_data->intr_mask = RXSTATUS_REAUTH_REQ; ddc_data->intr_mask = RXSTATUS_READY | RXSTATUS_MESSAGE_SIZE | RXSTATUS_REAUTH_REQ; ddc_data->timer_delay_lines = (u32)mult; ddc_data->read_method = HDCP2P2_RXSTATUS_HW_DDC_SW_TRIGGER; rc = hdmi_hdcp2p2_ddc_read_rxstatus(ddc_ctrl); if (rc) { pr_err("error reading rxstatus %d\n", rc); cdata.cmd = HDCP_LIB_WKUP_CMD_STOP; goto exit; } if (ddc_data->reauth_req) { pr_debug("sync reported loss of synchronization, reauth\n"); rc = -ENOLINK; cdata.cmd = HDCP_LIB_WKUP_CMD_STOP; goto exit; } if (ddc_data->ready && ddc_data->message_size) { pr_debug("topology changed. rxstatus msg size %d\n", ddc_data->message_size); recvd_msg_buf = kzalloc(ddc_data->message_size, GFP_KERNEL); if (!recvd_msg_buf) { cdata.cmd = HDCP_LIB_WKUP_CMD_STOP; goto exit; } rc = hdmi_hdcp2p2_ddc_read_message(ctrl, recvd_msg_buf, ddc_data->message_size, ctrl->timeout); if (rc) { cdata.cmd = HDCP_LIB_WKUP_CMD_STOP; pr_err("error reading message %d\n", rc); } else { cdata.cmd = HDCP_LIB_WKUP_CMD_MSG_RECV_SUCCESS; cdata.recvd_msg_buf = recvd_msg_buf; cdata.recvd_msg_len = ddc_data->message_size; } } exit: mutex_unlock(&ctrl->mutex); if (rc) { /* notify hdcp lib to stop auth */ hdmi_hdcp2p2_wakeup_lib(ctrl, &cdata); kfree(recvd_msg_buf); if (rc) { /* notify hdmi tx about auth failure */ hdmi_hdcp2p2_auth_failed(ctrl); Loading Loading @@ -779,8 +806,6 @@ void *hdmi_hdcp2p2_init(struct hdmi_hdcp_init_data *init_data) goto error; } init_completion(&ctrl->rxstatus_completion); ctrl->sink_status = SINK_DISCONNECTED; atomic_set(&ctrl->auth_state, HDCP_STATE_INACTIVE); Loading drivers/video/msm/mdss/mdss_hdmi_tx.c +66 −92 Original line number Diff line number Diff line Loading @@ -397,24 +397,9 @@ static bool hdmi_tx_is_cea_format(int mode) static inline bool hdmi_tx_is_hdcp_enabled(struct hdmi_tx_ctrl *hdmi_ctrl) { bool ret = false; if (hdmi_ctrl->hdcp_feature_on) { if (hdmi_ctrl->hdcp14_present) { /* Check to see if sw keys are available */ if (hdmi_ctrl->hdcp14_sw_keys) { u32 m_aksv, l_aksv; ret = !hdcp1_set_keys(&m_aksv, &l_aksv); } else { ret = true; } } if (hdmi_ctrl->hdcp22_present) ret = true; } return ret; return hdmi_ctrl->hdcp_feature_on && (hdmi_ctrl->hdcp14_present || hdmi_ctrl->hdcp22_present) && hdmi_ctrl->hdcp_ops; } static const char *hdmi_tx_pm_name(enum hdmi_tx_power_module_type module) Loading Loading @@ -1245,7 +1230,7 @@ static void hdmi_tx_hdcp_cb_work(struct work_struct *work) if (hdmi_ctrl->hpd_state && hdmi_ctrl->panel_power_on) { DEV_DBG("%s: Reauthenticating\n", __func__); rc = hdmi_ctrl->hdcp_ops->hdmi_hdcp_reauthenticate( hdmi_ctrl->hdcp_feature_data); hdmi_ctrl->hdcp_data); if (rc) DEV_ERR("%s: HDCP reauth failed. rc=%d\n", __func__, rc); Loading Loading @@ -1421,6 +1406,7 @@ static int hdmi_tx_init_features(struct hdmi_tx_ctrl *hdmi_ctrl, struct hdmi_hdcp_init_data hdcp_init_data; struct hdmi_cec_init_data cec_init_data; struct resource *res = NULL; void *fd = NULL; if (!hdmi_ctrl || !fbi) { DEV_ERR("%s: invalid input\n", __func__); Loading @@ -1432,23 +1418,21 @@ static int hdmi_tx_init_features(struct hdmi_tx_ctrl *hdmi_ctrl, edid_init_data.ds_data = &hdmi_ctrl->ds_data; edid_init_data.max_pclk_khz = hdmi_ctrl->max_pclk_khz; hdmi_ctrl->feature_data[HDMI_TX_FEAT_EDID] = hdmi_edid_init(&edid_init_data); if (!hdmi_ctrl->feature_data[HDMI_TX_FEAT_EDID]) { fd = hdmi_edid_init(&edid_init_data); if (!fd) { DEV_ERR("%s: hdmi_edid_init failed\n", __func__); return -EPERM; } hdmi_ctrl->panel_data.panel_info.edid_data = hdmi_ctrl->feature_data[HDMI_TX_FEAT_EDID]; hdmi_ctrl->panel_data.panel_info.edid_data = fd; /* get edid buffer from edid parser */ hdmi_ctrl->edid_buf = edid_init_data.buf; hdmi_ctrl->edid_buf_size = edid_init_data.buf_size; hdmi_edid_set_video_resolution( hdmi_ctrl->feature_data[HDMI_TX_FEAT_EDID], hdmi_ctrl->vid_cfg.vic, true); hdmi_edid_set_video_resolution(fd, hdmi_ctrl->vid_cfg.vic, true); hdmi_ctrl->feature_data[HDMI_TX_FEAT_EDID] = fd; /* Initialize HDCP features */ res = platform_get_resource_byname(hdmi_ctrl->pdev, Loading @@ -1461,10 +1445,8 @@ static int hdmi_tx_init_features(struct hdmi_tx_ctrl *hdmi_ctrl, hdcp_init_data.phy_addr = res->start; hdcp_init_data.core_io = &hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO]; hdcp_init_data.qfprom_io = &hdmi_ctrl->pdata.io[HDMI_TX_QFPROM_IO]; hdcp_init_data.hdcp_io = &hdmi_ctrl->pdata.io[HDMI_TX_HDCP_IO]; hdcp_init_data.qfprom_io = &hdmi_ctrl->pdata.io[HDMI_TX_QFPROM_IO]; hdcp_init_data.hdcp_io = &hdmi_ctrl->pdata.io[HDMI_TX_HDCP_IO]; hdcp_init_data.mutex = &hdmi_ctrl->mutex; hdcp_init_data.sysfs_kobj = hdmi_ctrl->kobj; hdcp_init_data.ddc_ctrl = &hdmi_ctrl->ddc_ctrl; Loading @@ -1474,47 +1456,36 @@ static int hdmi_tx_init_features(struct hdmi_tx_ctrl *hdmi_ctrl, hdcp_init_data.hdmi_tx_ver = hdmi_ctrl->hdmi_tx_ver; hdcp_init_data.timing = &hdmi_ctrl->vid_cfg.timing; /* * Try to initialize both HDCP 1.4 and 2.2 features, decide which one * to use at HPD time */ if (hdmi_ctrl->hdcp14_present) { fd = hdmi_hdcp_init(&hdcp_init_data); hdmi_ctrl->feature_data[HDMI_TX_FEAT_HDCP] = hdmi_hdcp_init(&hdcp_init_data); if (IS_ERR_OR_NULL( hdmi_ctrl->feature_data[HDMI_TX_FEAT_HDCP])) { DEV_ERR("%s: hdmi_hdcp_init failed\n", __func__); hdmi_edid_deinit(hdmi_ctrl->feature_data[ HDMI_TX_FEAT_EDID]); hdmi_ctrl->feature_data[HDMI_TX_FEAT_EDID] = NULL; return -EPERM; if (IS_ERR_OR_NULL(fd)) { DEV_WARN("%s: hdmi_hdcp_init failed\n", __func__); } else { hdmi_ctrl->feature_data[HDMI_TX_FEAT_HDCP] = fd; DEV_DBG("%s: HDCP 1.4 configured\n", __func__); } DEV_DBG("%s: HDCP 1.4 feature initialized\n", __func__); } hdmi_ctrl->feature_data[HDMI_TX_FEAT_HDCP2P2] = hdmi_hdcp2p2_init(&hdcp_init_data); fd = hdmi_hdcp2p2_init(&hdcp_init_data); if (IS_ERR_OR_NULL( hdmi_ctrl->feature_data[HDMI_TX_FEAT_HDCP2P2])) { if (IS_ERR_OR_NULL(fd)) { DEV_WARN("%s: hdmi_hdcp2p2_init failed\n", __func__); hdmi_ctrl->feature_data[HDMI_TX_FEAT_HDCP2P2] = NULL; } else { DEV_DBG("%s: HDCP 2.2 feature initialized\n", __func__); hdmi_ctrl->feature_data[HDMI_TX_FEAT_HDCP2P2] = fd; DEV_DBG("%s: HDCP 2.2 configured\n", __func__); } /* Initialize CEC feature */ cec_init_data.io = &hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO]; cec_init_data.sysfs_kobj = hdmi_ctrl->kobj; cec_init_data.workq = hdmi_ctrl->workq; hdmi_ctrl->feature_data[HDMI_TX_FEAT_CEC] = hdmi_cec_init(&cec_init_data); if (!hdmi_ctrl->feature_data[HDMI_TX_FEAT_CEC]) fd = hdmi_cec_init(&cec_init_data); if (!fd) DEV_WARN("%s: hdmi_cec_init failed\n", __func__); else hdmi_ctrl->feature_data[HDMI_TX_FEAT_CEC] = fd; return 0; } /* hdmi_tx_init_features */ Loading Loading @@ -1622,13 +1593,19 @@ static void hdmi_tx_update_hdcp_info(struct hdmi_tx_ctrl *hdmi_ctrl) else hdmi_ctrl->hdcp22_present = false; if (!hdmi_ctrl->hdcp22_present && hdmi_ctrl->hdcp14_present) { if (!hdmi_ctrl->hdcp22_present) { if (hdmi_ctrl->hdcp1_use_sw_keys) hdmi_ctrl->hdcp14_present = hdcp1_check_if_supported_load_app(); if (hdmi_ctrl->hdcp14_present) { fd = hdmi_ctrl->feature_data[HDMI_TX_FEAT_HDCP]; ops = hdmi_hdcp_start(fd); } } /* update internal data about hdcp */ hdmi_ctrl->hdcp_feature_data = fd; hdmi_ctrl->hdcp_data = fd; hdmi_ctrl->hdcp_ops = ops; } Loading Loading @@ -1678,20 +1655,23 @@ static void hdmi_tx_hpd_int_work(struct work_struct *work) static int hdmi_tx_check_capability(struct hdmi_tx_ctrl *hdmi_ctrl) { u32 hdmi_disabled, hdcp_disabled, reg_val; bool sw_keys = false; struct dss_io_data *io = NULL; int ret = 0; if (!hdmi_ctrl) { DEV_ERR("%s: invalid input\n", __func__); return -EINVAL; ret = -EINVAL; goto end; } io = &hdmi_ctrl->pdata.io[HDMI_TX_QFPROM_IO]; if (!io->base) { DEV_ERR("%s: QFPROM io is not initialized\n", __func__); return -EINVAL; ret = -EINVAL; goto end; } /* check if hdmi and hdcp are disabled */ if (hdmi_ctrl->hdmi_tx_ver < HDMI_TX_VERSION_4) { hdcp_disabled = DSS_REG_R_ND(io, QFPROM_RAW_FEAT_CONFIG_ROW0_LSB) & BIT(31); Loading @@ -1703,6 +1683,7 @@ static int hdmi_tx_check_capability(struct hdmi_tx_ctrl *hdmi_ctrl) QFPROM_RAW_FEAT_CONFIG_ROW0_LSB + QFPROM_RAW_VERSION_4); hdcp_disabled = reg_val & BIT(12); hdmi_disabled = reg_val & BIT(13); reg_val = DSS_REG_R_ND(io, SEC_CTRL_HW_VERSION); /* * With HDCP enabled on capable hardware, check if HW Loading @@ -1713,7 +1694,7 @@ static int hdmi_tx_check_capability(struct hdmi_tx_ctrl *hdmi_ctrl) QFPROM_RAW_FEAT_CONFIG_ROW0_MSB + QFPROM_RAW_VERSION_4); if (!(reg_val & BIT(23))) sw_keys = true; hdmi_ctrl->hdcp1_use_sw_keys = true; } } Loading @@ -1722,19 +1703,13 @@ static int hdmi_tx_check_capability(struct hdmi_tx_ctrl *hdmi_ctrl) if (hdmi_disabled) { DEV_ERR("%s: HDMI disabled\n", __func__); return -ENODEV; } if (hdcp_disabled) { hdmi_ctrl->hdcp14_present = 0; DEV_WARN("%s: HDCP disabled\n", __func__); } else { hdmi_ctrl->hdcp14_present = 1; hdmi_ctrl->hdcp14_sw_keys = sw_keys; DEV_DBG("%s: Device is HDCP enabled\n", __func__); ret = -ENODEV; goto end; } return 0; hdmi_ctrl->hdcp14_present = !hdcp_disabled; end: return ret; } /* hdmi_tx_check_capability */ static int hdmi_tx_set_video_fmt(struct hdmi_tx_ctrl *hdmi_ctrl, Loading Loading @@ -3329,11 +3304,11 @@ static int hdmi_tx_start(struct hdmi_tx_ctrl *hdmi_ctrl) hdmi_tx_set_spd_infoframe(hdmi_ctrl); } hdmi_tx_set_mode(hdmi_ctrl, true); if (hdmi_tx_setup_scrambler(hdmi_ctrl)) DEV_WARN("%s: Scrambler setup failed\n", __func__); hdmi_tx_set_mode(hdmi_ctrl, true); DEV_INFO("%s: HDMI Core: Initialized\n", __func__); return rc; Loading Loading @@ -3779,10 +3754,10 @@ static irqreturn_t hdmi_tx_isr(int irq, void *data) if (hdmi_cec_isr(hdmi_ctrl->feature_data[HDMI_TX_FEAT_CEC])) DEV_ERR("%s: hdmi_cec_isr failed\n", __func__); if (hdmi_ctrl->hdcp_ops && hdmi_ctrl->hdcp_feature_data) { if (hdmi_ctrl->hdcp_ops && hdmi_ctrl->hdcp_data) { if (hdmi_ctrl->hdcp_ops->hdmi_hdcp_isr) { if (hdmi_ctrl->hdcp_ops->hdmi_hdcp_isr( hdmi_ctrl->hdcp_feature_data)) hdmi_ctrl->hdcp_data)) DEV_ERR("%s: hdmi_hdcp_isr failed\n", __func__); } Loading Loading @@ -3815,7 +3790,7 @@ static void hdmi_tx_dev_deinit(struct hdmi_tx_ctrl *hdmi_ctrl) } hdmi_ctrl->hdcp_ops = NULL; hdmi_ctrl->hdcp_feature_data = NULL; hdmi_ctrl->hdcp_data = NULL; if (hdmi_ctrl->feature_data[HDMI_TX_FEAT_EDID]) { hdmi_edid_deinit(hdmi_ctrl->feature_data[HDMI_TX_FEAT_EDID]); Loading Loading @@ -3940,8 +3915,7 @@ static int hdmi_tx_start_hdcp(struct hdmi_tx_ctrl *hdmi_ctrl) return -ENODEV; } rc = hdmi_ctrl->hdcp_ops->hdmi_hdcp_authenticate( hdmi_ctrl->hdcp_feature_data); rc = hdmi_ctrl->hdcp_ops->hdmi_hdcp_authenticate(hdmi_ctrl->hdcp_data); if (rc) DEV_ERR("%s: hdcp auth failed. rc=%d\n", __func__, rc); Loading Loading @@ -4085,7 +4059,7 @@ static int hdmi_tx_panel_event_handler(struct mdss_panel_data *panel_data, if (hdmi_tx_is_hdcp_enabled(hdmi_ctrl)) { DEV_DBG("%s: Turning off HDCP\n", __func__); hdmi_ctrl->hdcp_ops->hdmi_hdcp_off( hdmi_ctrl->hdcp_feature_data); hdmi_ctrl->hdcp_data); hdmi_ctrl->hdcp_ops = NULL; Loading drivers/video/msm/mdss/mdss_hdmi_tx.h +2 −1 Original line number Diff line number Diff line Loading @@ -174,6 +174,7 @@ struct hdmi_tx_ctrl { bool ds_registered; bool scrambler_enabled; u32 hdcp14_present; bool hdcp1_use_sw_keys; bool audio_ack_enabled; atomic_t audio_ack_pending; bool hdcp14_sw_keys; Loading @@ -188,7 +189,7 @@ struct hdmi_tx_ctrl { void *feature_data[HDMI_TX_FEAT_MAX]; struct hdmi_hdcp_ops *hdcp_ops; void *hdcp_feature_data; void *hdcp_data; bool hdcp22_present; u8 *edid_buf; Loading drivers/video/msm/mdss/mdss_hdmi_util.c +0 −2 Original line number Diff line number Diff line Loading @@ -1672,8 +1672,6 @@ int hdmi_hdcp2p2_ddc_read_rxstatus(struct hdmi_tx_ddc_ctrl *ctrl) /* check for errors and clear status */ reg_val = DSS_REG_R(ctrl->io, HDMI_HDCP2P2_DDC_STATUS); if (reg_val & BIT(0)) pr_debug("ddc busy\n"); if (reg_val & BIT(4)) { pr_err("ddc aborted\n"); Loading Loading
drivers/misc/hdcp.c +22 −12 Original line number Diff line number Diff line Loading @@ -365,6 +365,9 @@ struct hdcp_lib_message_map { const char *msg_name; }; static struct qseecom_handle *hdcp1_handle; static bool hdcp1_supported = true; static const char *hdcp_lib_message_name(int msg_id) { /* Loading Loading @@ -1151,16 +1154,12 @@ static void hdcp_lib_topology_work(struct kthread_work *work) u32 timeout; struct hdcp_lib_handle *handle = container_of(work, struct hdcp_lib_handle, topology); struct hdmi_hdcp_wakeup_data cdata = {HDMI_HDCP_WKUP_CMD_INVALID}; if (!handle) { pr_err("invalid input\n"); return; } cdata.context = handle->client_ctx; cdata.cmd = HDMI_HDCP_WKUP_CMD_RECV_MESSAGE; hdcp_lib_wakeup_client(handle, &cdata); reinit_completion(&handle->topo_wait); timeout = wait_for_completion_timeout(&handle->topo_wait, HZ * 3); Loading @@ -1172,24 +1171,35 @@ static void hdcp_lib_topology_work(struct kthread_work *work) } } bool hdcp1_check_if_supported_load_app(void) { int rc = 0; /* start hdcp1 app */ if (hdcp1_supported && !hdcp1_handle) { rc = qseecom_start_app(&hdcp1_handle, HDCP1_APP_NAME, QSEECOM_SBUFF_SIZE); if (rc) { pr_err("qseecom_start_app failed %d\n", rc); hdcp1_supported = false; } } return hdcp1_supported; } /* 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_handle = NULL; if (aksv_msb == NULL || aksv_lsb == NULL) return -EINVAL; /* start hdcp1 app */ rc = qseecom_start_app(&hdcp1_handle, HDCP1_APP_NAME, QSEECOM_SBUFF_SIZE); if (rc) { pr_err("qseecom_start_app failed %d\n", rc); return -ENOSYS; } if (!hdcp1_supported || !hdcp1_handle) return -EINVAL; /* set keys and request aksv */ key_set_req = (struct hdcp1_key_set_req *)hdcp1_handle->sbuf; Loading
drivers/video/msm/mdss/mdss_hdmi_hdcp2p2.c +34 −9 Original line number Diff line number Diff line Loading @@ -56,7 +56,6 @@ struct hdmi_hdcp2p2_ctrl { struct hdmi_hdcp_ops *ops; void *lib_ctx; /* Handle to HDCP 2.2 Trustzone library */ struct hdcp_txmtr_ops *lib; /* Ops for driver to call into TZ */ struct completion rxstatus_completion; /* Rx status interrupt */ enum hdmi_hdcp_wakeup_cmd wakeup_cmd; char *send_msg_buf; Loading Loading @@ -356,7 +355,7 @@ static int hdmi_hdcp2p2_ddc_write_message(struct hdmi_hdcp2p2_ctrl *ctrl, rc = hdmi_ddc_write(ctrl->init_data.ddc_ctrl); if (rc) pr_err("Cannot write HDCP message register"); pr_err("Cannot write HDCP message register\n"); return rc; } Loading Loading @@ -625,11 +624,12 @@ static void hdmi_hdcp2p2_link_work(struct kthread_work *work) int rc = 0; struct hdmi_hdcp2p2_ctrl *ctrl = container_of(work, struct hdmi_hdcp2p2_ctrl, link); struct hdcp_lib_wakeup_data cdata = {HDCP_LIB_WKUP_CMD_STOP}; struct hdcp_lib_wakeup_data cdata = {HDCP_LIB_WKUP_CMD_INVALID}; struct hdmi_tx_ddc_ctrl *ddc_ctrl; struct hdmi_tx_hdcp2p2_ddc_data *ddc_data; u64 mult; struct msm_hdmi_mode_timing_info *timing; char *recvd_msg_buf = NULL; if (!ctrl) { pr_err("invalid input\n"); Loading @@ -643,6 +643,7 @@ static void hdmi_hdcp2p2_link_work(struct kthread_work *work) ddc_ctrl = ctrl->init_data.ddc_ctrl; if (!ddc_ctrl) { rc = -EINVAL; cdata.cmd = HDCP_LIB_WKUP_CMD_STOP; goto exit; } Loading @@ -654,27 +655,53 @@ static void hdmi_hdcp2p2_link_work(struct kthread_work *work) timing = ctrl->init_data.timing; mult = hdmi_tx_get_v_total(timing) / 20; ddc_data->intr_mask = RXSTATUS_REAUTH_REQ; ddc_data->intr_mask = RXSTATUS_READY | RXSTATUS_MESSAGE_SIZE | RXSTATUS_REAUTH_REQ; ddc_data->timer_delay_lines = (u32)mult; ddc_data->read_method = HDCP2P2_RXSTATUS_HW_DDC_SW_TRIGGER; rc = hdmi_hdcp2p2_ddc_read_rxstatus(ddc_ctrl); if (rc) { pr_err("error reading rxstatus %d\n", rc); cdata.cmd = HDCP_LIB_WKUP_CMD_STOP; goto exit; } if (ddc_data->reauth_req) { pr_debug("sync reported loss of synchronization, reauth\n"); rc = -ENOLINK; cdata.cmd = HDCP_LIB_WKUP_CMD_STOP; goto exit; } if (ddc_data->ready && ddc_data->message_size) { pr_debug("topology changed. rxstatus msg size %d\n", ddc_data->message_size); recvd_msg_buf = kzalloc(ddc_data->message_size, GFP_KERNEL); if (!recvd_msg_buf) { cdata.cmd = HDCP_LIB_WKUP_CMD_STOP; goto exit; } rc = hdmi_hdcp2p2_ddc_read_message(ctrl, recvd_msg_buf, ddc_data->message_size, ctrl->timeout); if (rc) { cdata.cmd = HDCP_LIB_WKUP_CMD_STOP; pr_err("error reading message %d\n", rc); } else { cdata.cmd = HDCP_LIB_WKUP_CMD_MSG_RECV_SUCCESS; cdata.recvd_msg_buf = recvd_msg_buf; cdata.recvd_msg_len = ddc_data->message_size; } } exit: mutex_unlock(&ctrl->mutex); if (rc) { /* notify hdcp lib to stop auth */ hdmi_hdcp2p2_wakeup_lib(ctrl, &cdata); kfree(recvd_msg_buf); if (rc) { /* notify hdmi tx about auth failure */ hdmi_hdcp2p2_auth_failed(ctrl); Loading Loading @@ -779,8 +806,6 @@ void *hdmi_hdcp2p2_init(struct hdmi_hdcp_init_data *init_data) goto error; } init_completion(&ctrl->rxstatus_completion); ctrl->sink_status = SINK_DISCONNECTED; atomic_set(&ctrl->auth_state, HDCP_STATE_INACTIVE); Loading
drivers/video/msm/mdss/mdss_hdmi_tx.c +66 −92 Original line number Diff line number Diff line Loading @@ -397,24 +397,9 @@ static bool hdmi_tx_is_cea_format(int mode) static inline bool hdmi_tx_is_hdcp_enabled(struct hdmi_tx_ctrl *hdmi_ctrl) { bool ret = false; if (hdmi_ctrl->hdcp_feature_on) { if (hdmi_ctrl->hdcp14_present) { /* Check to see if sw keys are available */ if (hdmi_ctrl->hdcp14_sw_keys) { u32 m_aksv, l_aksv; ret = !hdcp1_set_keys(&m_aksv, &l_aksv); } else { ret = true; } } if (hdmi_ctrl->hdcp22_present) ret = true; } return ret; return hdmi_ctrl->hdcp_feature_on && (hdmi_ctrl->hdcp14_present || hdmi_ctrl->hdcp22_present) && hdmi_ctrl->hdcp_ops; } static const char *hdmi_tx_pm_name(enum hdmi_tx_power_module_type module) Loading Loading @@ -1245,7 +1230,7 @@ static void hdmi_tx_hdcp_cb_work(struct work_struct *work) if (hdmi_ctrl->hpd_state && hdmi_ctrl->panel_power_on) { DEV_DBG("%s: Reauthenticating\n", __func__); rc = hdmi_ctrl->hdcp_ops->hdmi_hdcp_reauthenticate( hdmi_ctrl->hdcp_feature_data); hdmi_ctrl->hdcp_data); if (rc) DEV_ERR("%s: HDCP reauth failed. rc=%d\n", __func__, rc); Loading Loading @@ -1421,6 +1406,7 @@ static int hdmi_tx_init_features(struct hdmi_tx_ctrl *hdmi_ctrl, struct hdmi_hdcp_init_data hdcp_init_data; struct hdmi_cec_init_data cec_init_data; struct resource *res = NULL; void *fd = NULL; if (!hdmi_ctrl || !fbi) { DEV_ERR("%s: invalid input\n", __func__); Loading @@ -1432,23 +1418,21 @@ static int hdmi_tx_init_features(struct hdmi_tx_ctrl *hdmi_ctrl, edid_init_data.ds_data = &hdmi_ctrl->ds_data; edid_init_data.max_pclk_khz = hdmi_ctrl->max_pclk_khz; hdmi_ctrl->feature_data[HDMI_TX_FEAT_EDID] = hdmi_edid_init(&edid_init_data); if (!hdmi_ctrl->feature_data[HDMI_TX_FEAT_EDID]) { fd = hdmi_edid_init(&edid_init_data); if (!fd) { DEV_ERR("%s: hdmi_edid_init failed\n", __func__); return -EPERM; } hdmi_ctrl->panel_data.panel_info.edid_data = hdmi_ctrl->feature_data[HDMI_TX_FEAT_EDID]; hdmi_ctrl->panel_data.panel_info.edid_data = fd; /* get edid buffer from edid parser */ hdmi_ctrl->edid_buf = edid_init_data.buf; hdmi_ctrl->edid_buf_size = edid_init_data.buf_size; hdmi_edid_set_video_resolution( hdmi_ctrl->feature_data[HDMI_TX_FEAT_EDID], hdmi_ctrl->vid_cfg.vic, true); hdmi_edid_set_video_resolution(fd, hdmi_ctrl->vid_cfg.vic, true); hdmi_ctrl->feature_data[HDMI_TX_FEAT_EDID] = fd; /* Initialize HDCP features */ res = platform_get_resource_byname(hdmi_ctrl->pdev, Loading @@ -1461,10 +1445,8 @@ static int hdmi_tx_init_features(struct hdmi_tx_ctrl *hdmi_ctrl, hdcp_init_data.phy_addr = res->start; hdcp_init_data.core_io = &hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO]; hdcp_init_data.qfprom_io = &hdmi_ctrl->pdata.io[HDMI_TX_QFPROM_IO]; hdcp_init_data.hdcp_io = &hdmi_ctrl->pdata.io[HDMI_TX_HDCP_IO]; hdcp_init_data.qfprom_io = &hdmi_ctrl->pdata.io[HDMI_TX_QFPROM_IO]; hdcp_init_data.hdcp_io = &hdmi_ctrl->pdata.io[HDMI_TX_HDCP_IO]; hdcp_init_data.mutex = &hdmi_ctrl->mutex; hdcp_init_data.sysfs_kobj = hdmi_ctrl->kobj; hdcp_init_data.ddc_ctrl = &hdmi_ctrl->ddc_ctrl; Loading @@ -1474,47 +1456,36 @@ static int hdmi_tx_init_features(struct hdmi_tx_ctrl *hdmi_ctrl, hdcp_init_data.hdmi_tx_ver = hdmi_ctrl->hdmi_tx_ver; hdcp_init_data.timing = &hdmi_ctrl->vid_cfg.timing; /* * Try to initialize both HDCP 1.4 and 2.2 features, decide which one * to use at HPD time */ if (hdmi_ctrl->hdcp14_present) { fd = hdmi_hdcp_init(&hdcp_init_data); hdmi_ctrl->feature_data[HDMI_TX_FEAT_HDCP] = hdmi_hdcp_init(&hdcp_init_data); if (IS_ERR_OR_NULL( hdmi_ctrl->feature_data[HDMI_TX_FEAT_HDCP])) { DEV_ERR("%s: hdmi_hdcp_init failed\n", __func__); hdmi_edid_deinit(hdmi_ctrl->feature_data[ HDMI_TX_FEAT_EDID]); hdmi_ctrl->feature_data[HDMI_TX_FEAT_EDID] = NULL; return -EPERM; if (IS_ERR_OR_NULL(fd)) { DEV_WARN("%s: hdmi_hdcp_init failed\n", __func__); } else { hdmi_ctrl->feature_data[HDMI_TX_FEAT_HDCP] = fd; DEV_DBG("%s: HDCP 1.4 configured\n", __func__); } DEV_DBG("%s: HDCP 1.4 feature initialized\n", __func__); } hdmi_ctrl->feature_data[HDMI_TX_FEAT_HDCP2P2] = hdmi_hdcp2p2_init(&hdcp_init_data); fd = hdmi_hdcp2p2_init(&hdcp_init_data); if (IS_ERR_OR_NULL( hdmi_ctrl->feature_data[HDMI_TX_FEAT_HDCP2P2])) { if (IS_ERR_OR_NULL(fd)) { DEV_WARN("%s: hdmi_hdcp2p2_init failed\n", __func__); hdmi_ctrl->feature_data[HDMI_TX_FEAT_HDCP2P2] = NULL; } else { DEV_DBG("%s: HDCP 2.2 feature initialized\n", __func__); hdmi_ctrl->feature_data[HDMI_TX_FEAT_HDCP2P2] = fd; DEV_DBG("%s: HDCP 2.2 configured\n", __func__); } /* Initialize CEC feature */ cec_init_data.io = &hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO]; cec_init_data.sysfs_kobj = hdmi_ctrl->kobj; cec_init_data.workq = hdmi_ctrl->workq; hdmi_ctrl->feature_data[HDMI_TX_FEAT_CEC] = hdmi_cec_init(&cec_init_data); if (!hdmi_ctrl->feature_data[HDMI_TX_FEAT_CEC]) fd = hdmi_cec_init(&cec_init_data); if (!fd) DEV_WARN("%s: hdmi_cec_init failed\n", __func__); else hdmi_ctrl->feature_data[HDMI_TX_FEAT_CEC] = fd; return 0; } /* hdmi_tx_init_features */ Loading Loading @@ -1622,13 +1593,19 @@ static void hdmi_tx_update_hdcp_info(struct hdmi_tx_ctrl *hdmi_ctrl) else hdmi_ctrl->hdcp22_present = false; if (!hdmi_ctrl->hdcp22_present && hdmi_ctrl->hdcp14_present) { if (!hdmi_ctrl->hdcp22_present) { if (hdmi_ctrl->hdcp1_use_sw_keys) hdmi_ctrl->hdcp14_present = hdcp1_check_if_supported_load_app(); if (hdmi_ctrl->hdcp14_present) { fd = hdmi_ctrl->feature_data[HDMI_TX_FEAT_HDCP]; ops = hdmi_hdcp_start(fd); } } /* update internal data about hdcp */ hdmi_ctrl->hdcp_feature_data = fd; hdmi_ctrl->hdcp_data = fd; hdmi_ctrl->hdcp_ops = ops; } Loading Loading @@ -1678,20 +1655,23 @@ static void hdmi_tx_hpd_int_work(struct work_struct *work) static int hdmi_tx_check_capability(struct hdmi_tx_ctrl *hdmi_ctrl) { u32 hdmi_disabled, hdcp_disabled, reg_val; bool sw_keys = false; struct dss_io_data *io = NULL; int ret = 0; if (!hdmi_ctrl) { DEV_ERR("%s: invalid input\n", __func__); return -EINVAL; ret = -EINVAL; goto end; } io = &hdmi_ctrl->pdata.io[HDMI_TX_QFPROM_IO]; if (!io->base) { DEV_ERR("%s: QFPROM io is not initialized\n", __func__); return -EINVAL; ret = -EINVAL; goto end; } /* check if hdmi and hdcp are disabled */ if (hdmi_ctrl->hdmi_tx_ver < HDMI_TX_VERSION_4) { hdcp_disabled = DSS_REG_R_ND(io, QFPROM_RAW_FEAT_CONFIG_ROW0_LSB) & BIT(31); Loading @@ -1703,6 +1683,7 @@ static int hdmi_tx_check_capability(struct hdmi_tx_ctrl *hdmi_ctrl) QFPROM_RAW_FEAT_CONFIG_ROW0_LSB + QFPROM_RAW_VERSION_4); hdcp_disabled = reg_val & BIT(12); hdmi_disabled = reg_val & BIT(13); reg_val = DSS_REG_R_ND(io, SEC_CTRL_HW_VERSION); /* * With HDCP enabled on capable hardware, check if HW Loading @@ -1713,7 +1694,7 @@ static int hdmi_tx_check_capability(struct hdmi_tx_ctrl *hdmi_ctrl) QFPROM_RAW_FEAT_CONFIG_ROW0_MSB + QFPROM_RAW_VERSION_4); if (!(reg_val & BIT(23))) sw_keys = true; hdmi_ctrl->hdcp1_use_sw_keys = true; } } Loading @@ -1722,19 +1703,13 @@ static int hdmi_tx_check_capability(struct hdmi_tx_ctrl *hdmi_ctrl) if (hdmi_disabled) { DEV_ERR("%s: HDMI disabled\n", __func__); return -ENODEV; } if (hdcp_disabled) { hdmi_ctrl->hdcp14_present = 0; DEV_WARN("%s: HDCP disabled\n", __func__); } else { hdmi_ctrl->hdcp14_present = 1; hdmi_ctrl->hdcp14_sw_keys = sw_keys; DEV_DBG("%s: Device is HDCP enabled\n", __func__); ret = -ENODEV; goto end; } return 0; hdmi_ctrl->hdcp14_present = !hdcp_disabled; end: return ret; } /* hdmi_tx_check_capability */ static int hdmi_tx_set_video_fmt(struct hdmi_tx_ctrl *hdmi_ctrl, Loading Loading @@ -3329,11 +3304,11 @@ static int hdmi_tx_start(struct hdmi_tx_ctrl *hdmi_ctrl) hdmi_tx_set_spd_infoframe(hdmi_ctrl); } hdmi_tx_set_mode(hdmi_ctrl, true); if (hdmi_tx_setup_scrambler(hdmi_ctrl)) DEV_WARN("%s: Scrambler setup failed\n", __func__); hdmi_tx_set_mode(hdmi_ctrl, true); DEV_INFO("%s: HDMI Core: Initialized\n", __func__); return rc; Loading Loading @@ -3779,10 +3754,10 @@ static irqreturn_t hdmi_tx_isr(int irq, void *data) if (hdmi_cec_isr(hdmi_ctrl->feature_data[HDMI_TX_FEAT_CEC])) DEV_ERR("%s: hdmi_cec_isr failed\n", __func__); if (hdmi_ctrl->hdcp_ops && hdmi_ctrl->hdcp_feature_data) { if (hdmi_ctrl->hdcp_ops && hdmi_ctrl->hdcp_data) { if (hdmi_ctrl->hdcp_ops->hdmi_hdcp_isr) { if (hdmi_ctrl->hdcp_ops->hdmi_hdcp_isr( hdmi_ctrl->hdcp_feature_data)) hdmi_ctrl->hdcp_data)) DEV_ERR("%s: hdmi_hdcp_isr failed\n", __func__); } Loading Loading @@ -3815,7 +3790,7 @@ static void hdmi_tx_dev_deinit(struct hdmi_tx_ctrl *hdmi_ctrl) } hdmi_ctrl->hdcp_ops = NULL; hdmi_ctrl->hdcp_feature_data = NULL; hdmi_ctrl->hdcp_data = NULL; if (hdmi_ctrl->feature_data[HDMI_TX_FEAT_EDID]) { hdmi_edid_deinit(hdmi_ctrl->feature_data[HDMI_TX_FEAT_EDID]); Loading Loading @@ -3940,8 +3915,7 @@ static int hdmi_tx_start_hdcp(struct hdmi_tx_ctrl *hdmi_ctrl) return -ENODEV; } rc = hdmi_ctrl->hdcp_ops->hdmi_hdcp_authenticate( hdmi_ctrl->hdcp_feature_data); rc = hdmi_ctrl->hdcp_ops->hdmi_hdcp_authenticate(hdmi_ctrl->hdcp_data); if (rc) DEV_ERR("%s: hdcp auth failed. rc=%d\n", __func__, rc); Loading Loading @@ -4085,7 +4059,7 @@ static int hdmi_tx_panel_event_handler(struct mdss_panel_data *panel_data, if (hdmi_tx_is_hdcp_enabled(hdmi_ctrl)) { DEV_DBG("%s: Turning off HDCP\n", __func__); hdmi_ctrl->hdcp_ops->hdmi_hdcp_off( hdmi_ctrl->hdcp_feature_data); hdmi_ctrl->hdcp_data); hdmi_ctrl->hdcp_ops = NULL; Loading
drivers/video/msm/mdss/mdss_hdmi_tx.h +2 −1 Original line number Diff line number Diff line Loading @@ -174,6 +174,7 @@ struct hdmi_tx_ctrl { bool ds_registered; bool scrambler_enabled; u32 hdcp14_present; bool hdcp1_use_sw_keys; bool audio_ack_enabled; atomic_t audio_ack_pending; bool hdcp14_sw_keys; Loading @@ -188,7 +189,7 @@ struct hdmi_tx_ctrl { void *feature_data[HDMI_TX_FEAT_MAX]; struct hdmi_hdcp_ops *hdcp_ops; void *hdcp_feature_data; void *hdcp_data; bool hdcp22_present; u8 *edid_buf; Loading
drivers/video/msm/mdss/mdss_hdmi_util.c +0 −2 Original line number Diff line number Diff line Loading @@ -1672,8 +1672,6 @@ int hdmi_hdcp2p2_ddc_read_rxstatus(struct hdmi_tx_ddc_ctrl *ctrl) /* check for errors and clear status */ reg_val = DSS_REG_R(ctrl->io, HDMI_HDCP2P2_DDC_STATUS); if (reg_val & BIT(0)) pr_debug("ddc busy\n"); if (reg_val & BIT(4)) { pr_err("ddc aborted\n"); Loading