Loading drivers/video/msm/mdss/mdss_hdmi_hdcp2p2.c +22 −37 Original line number Diff line number Diff line Loading @@ -36,9 +36,6 @@ #define HDCP2P2_LINK_CHECK_TIME_MS 900 /* link check within 1 sec */ #define HDCP2P2_SEC_TO_US 1000000 #define HDCP2P2_MS_TO_US 1000 #define HDCP2P2_KHZ_TO_HZ 1000 #define HDCP2P2_DEFAULT_TIMEOUT 500 /* Loading Loading @@ -600,15 +597,12 @@ exit: static void hdmi_hdcp2p2_recv_msg_work(struct kthread_work *work) { int rc = 0; u32 fps, v_total; u32 time_taken_by_one_line_us; u32 lines_needed_for_given_time; int timeout_hsync; char *recvd_msg_buf = NULL; struct hdmi_hdcp2p2_ctrl *ctrl = container_of(work, struct hdmi_hdcp2p2_ctrl, recv_msg); struct hdmi_tx_hdcp2p2_ddc_data *ddc_data; struct hdmi_tx_ddc_ctrl *ddc_ctrl; struct msm_hdmi_mode_timing_info *timing; struct hdcp_lib_wakeup_data cdata = {HDCP_LIB_WKUP_CMD_INVALID}; if (!ctrl) { Loading @@ -635,27 +629,21 @@ static void hdmi_hdcp2p2_recv_msg_work(struct kthread_work *work) memset(ddc_data, 0, sizeof(*ddc_data)); timing = ctrl->init_data.timing; timeout_hsync = hdmi_utils_get_timeout_in_hysnc( ctrl->init_data.timing, ctrl->timeout); fps = timing->refresh_rate / HDCP2P2_KHZ_TO_HZ; v_total = hdmi_tx_get_v_total(timing); /* * pixel clock = h_total * v_total * fps * 1 sec = pixel clock number of pixels are transmitted. * time taken by one line (h_total) = 1 / (v_total * fps). */ time_taken_by_one_line_us = HDCP2P2_SEC_TO_US / (v_total * fps); lines_needed_for_given_time = (ctrl->timeout * HDCP2P2_MS_TO_US) / time_taken_by_one_line_us; if (timeout_hsync <= 0) { pr_err("err in timeout hsync calc\n"); timeout_hsync = HDMI_DEFAULT_TIMEOUT_HSYNC; } pr_debug("timeout for rxstatus %dms, %d hsyncs\n", ctrl->timeout, lines_needed_for_given_time); pr_debug("timeout for rxstatus %dms, %d hsync\n", ctrl->timeout, timeout_hsync); ddc_data->intr_mask = RXSTATUS_MESSAGE_SIZE; ddc_data->timeout_ms = ctrl->timeout; ddc_data->timeout_hsync = lines_needed_for_given_time; ddc_data->periodic_timer_hsync = lines_needed_for_given_time / 20; ddc_data->timeout_hsync = timeout_hsync; ddc_data->periodic_timer_hsync = timeout_hsync / 20; ddc_data->read_method = HDCP2P2_RXSTATUS_HW_DDC_SW_TRIGGER; rc = hdmi_hdcp2p2_ddc_read_rxstatus(ddc_ctrl, true); Loading Loading @@ -704,10 +692,7 @@ static int hdmi_hdcp2p2_link_check(struct hdmi_hdcp2p2_ctrl *ctrl) { struct hdmi_tx_ddc_ctrl *ddc_ctrl; struct hdmi_tx_hdcp2p2_ddc_data *ddc_data; struct msm_hdmi_mode_timing_info *timing; u32 fps, v_total; u32 time_taken_by_one_line_us; u32 lines_needed_for_given_time; int timeout_hsync; ddc_ctrl = ctrl->init_data.ddc_ctrl; if (!ddc_ctrl) Loading @@ -719,20 +704,20 @@ static int hdmi_hdcp2p2_link_check(struct hdmi_hdcp2p2_ctrl *ctrl) memset(ddc_data, 0, sizeof(*ddc_data)); timing = ctrl->init_data.timing; fps = timing->refresh_rate / HDCP2P2_KHZ_TO_HZ; v_total = hdmi_tx_get_v_total(timing); time_taken_by_one_line_us = HDCP2P2_SEC_TO_US / (v_total * fps); lines_needed_for_given_time = (jiffies_to_msecs((HZ / 2) + (HZ / 4)) * HDCP2P2_MS_TO_US) / time_taken_by_one_line_us; timeout_hsync = hdmi_utils_get_timeout_in_hysnc( ctrl->init_data.timing, jiffies_to_msecs((HZ / 2) + (HZ / 4))); pr_debug("timeout for rxstatus %d hsyncs\n", lines_needed_for_given_time); if (timeout_hsync <= 0) { pr_err("err in timeout hsync calc\n"); timeout_hsync = HDMI_DEFAULT_TIMEOUT_HSYNC; } pr_debug("timeout for rxstatus %d hsyncs\n", timeout_hsync); ddc_data->intr_mask = RXSTATUS_READY | RXSTATUS_MESSAGE_SIZE | RXSTATUS_REAUTH_REQ; ddc_data->timeout_hsync = lines_needed_for_given_time; ddc_data->periodic_timer_hsync = lines_needed_for_given_time; ddc_data->timeout_hsync = timeout_hsync; ddc_data->periodic_timer_hsync = timeout_hsync; ddc_data->read_method = HDCP2P2_RXSTATUS_HW_DDC_SW_TRIGGER; return hdmi_hdcp2p2_ddc_read_rxstatus(ddc_ctrl, false); Loading drivers/video/msm/mdss/mdss_hdmi_tx.c +17 −20 Original line number Diff line number Diff line Loading @@ -75,7 +75,7 @@ #define HDMI_TX_RGB_24BPP_PCLK_TMDS_CH_RATE_RATIO 1 #define HDMI_TX_SCRAMBLER_THRESHOLD_RATE_KHZ 340000 #define HDMI_TX_SCRAMBLER_TIMEOUT_USEC 200000 #define HDMI_TX_SCRAMBLER_TIMEOUT_MSEC 200 #define HDMI_TX_KHZ_TO_HZ 1000 #define HDMI_TX_MHZ_TO_HZ 1000000 Loading Loading @@ -3269,6 +3269,7 @@ int hdmi_tx_setup_scrambler(struct hdmi_tx_ctrl *hdmi_ctrl) struct dss_io_data *io = NULL; struct msm_hdmi_mode_timing_info *timing = NULL; void *edid_data = NULL; int timeout_hsync; if (!hdmi_ctrl) { DEV_ERR("%s: Bad input parameters\n", __func__); Loading @@ -3295,9 +3296,6 @@ int hdmi_tx_setup_scrambler(struct hdmi_tx_ctrl *hdmi_ctrl) return 0; } if (!hdmi_edid_get_scdc_support(edid_data)) DEV_WARN("%s: sink didn't provide scdc support\n", __func__); rate = hdmi_tx_setup_tmds_clk_rate(hdmi_ctrl); if (rate > HDMI_TX_SCRAMBLER_THRESHOLD_RATE_KHZ) { Loading @@ -3309,9 +3307,6 @@ int hdmi_tx_setup_scrambler(struct hdmi_tx_ctrl *hdmi_ctrl) } if (scrambler_on) { u64 mult; u64 div; rc = hdmi_scdc_write(&hdmi_ctrl->ddc_ctrl, HDMI_TX_SCDC_TMDS_BIT_CLOCK_RATIO_UPDATE, tmds_clock_ratio); Loading Loading @@ -3341,24 +3336,26 @@ int hdmi_tx_setup_scrambler(struct hdmi_tx_ctrl *hdmi_ctrl) * status bit on the sink. Sink should set this bit * with in 200ms after scrambler is enabled. */ mult = HDMI_TX_SCRAMBLER_TIMEOUT_USEC * ((u64)timing->pixel_freq * HDMI_TX_KHZ_TO_HZ); div = hdmi_tx_get_v_total(timing) * HDMI_TX_MHZ_TO_HZ; if (div) do_div(mult, div); else mult = 0; timeout_hsync = hdmi_utils_get_timeout_in_hysnc( &hdmi_ctrl->vid_cfg.timing, HDMI_TX_SCRAMBLER_TIMEOUT_MSEC); if (timeout_hsync <= 0) { DEV_ERR("%s: err in timeout hsync calc\n", __func__); timeout_hsync = HDMI_DEFAULT_TIMEOUT_HSYNC; } pr_debug("timeout for scrambling en: %d hsyncs\n", timeout_hsync); rc = hdmi_setup_ddc_timers(&hdmi_ctrl->ddc_ctrl, HDMI_TX_DDC_TIMER_SCRAMBLER_STATUS, (u32)mult); HDMI_TX_DDC_TIMER_SCRAMBLER_STATUS, timeout_hsync); } else { if (hdmi_ctrl->scrambler_enabled) { hdmi_scdc_write(&hdmi_ctrl->ddc_ctrl, HDMI_TX_SCDC_SCRAMBLING_ENABLE, 0x0); hdmi_ctrl->scrambler_enabled = false; } } return rc; } Loading drivers/video/msm/mdss/mdss_hdmi_util.c +171 −112 Original line number Diff line number Diff line Loading @@ -19,37 +19,117 @@ #define RESOLUTION_NAME_STR_LEN 30 #define HDMI_SEC_TO_MS 1000 #define HDMI_MS_TO_US 1000 #define HDMI_SEC_TO_US (HDMI_SEC_TO_MS * HDMI_MS_TO_US) #define HDMI_KHZ_TO_HZ 1000 #define HDMI_SCDC_UNKNOWN_REGISTER "Unknown register" static char res_buf[RESOLUTION_NAME_STR_LEN]; int hdmi_utils_get_timeout_in_hysnc(struct msm_hdmi_mode_timing_info *timing, u32 timeout_ms) { u32 fps, v_total; u32 time_taken_by_one_line_us, lines_needed_for_given_time; if (!timing || !timeout_ms) { pr_err("invalid input\n"); return -EINVAL; } fps = timing->refresh_rate / HDMI_KHZ_TO_HZ; v_total = hdmi_tx_get_v_total(timing); /* * pixel clock = h_total * v_total * fps * 1 sec = pixel clock number of pixels are transmitted. * time taken by one line (h_total) = 1 / (v_total * fps). */ time_taken_by_one_line_us = HDMI_SEC_TO_US / (v_total * fps); lines_needed_for_given_time = (timeout_ms * HDMI_MS_TO_US) / time_taken_by_one_line_us; return lines_needed_for_given_time; } static int hdmi_ddc_clear_irq(struct hdmi_tx_ddc_ctrl *ddc_ctrl, char *what) { u32 ddc_int_ctrl, ddc_status, in_use, timeout; u32 sw_done_mask = BIT(2); u32 sw_done_ack = BIT(1); u32 hw_done_mask = BIT(6); u32 hw_done_ack = BIT(5); u32 in_use_by_sw = BIT(0); u32 in_use_by_hw = BIT(1); if (!ddc_ctrl || !ddc_ctrl->io) { pr_err("invalid input\n"); return -EINVAL; } /* clear and enable interrutps */ ddc_int_ctrl = sw_done_mask | sw_done_ack | hw_done_mask | hw_done_ack; DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_INT_CTRL, ddc_int_ctrl); /* wait until DDC HW is free */ timeout = 100; do { ddc_status = DSS_REG_R_ND(ddc_ctrl->io, HDMI_DDC_HW_STATUS); in_use = ddc_status & (in_use_by_sw | in_use_by_hw); if (in_use) { pr_debug("ddc is in use by %s, timeout(%d)\n", ddc_status & in_use_by_sw ? "sw" : "hw", timeout); udelay(100); } } while (in_use && --timeout); if (!timeout) { pr_err("%s: timedout\n", what); return -ETIMEDOUT; } return 0; } static void hdmi_scrambler_status_timer_setup(struct hdmi_tx_ddc_ctrl *ctrl, u32 to_in_num_lines) u32 timeout_hsync) { u32 reg_val; struct dss_io_data *io = NULL; if (!ctrl || !ctrl->io) { pr_err("invalid input\n"); return; } DSS_REG_W(ctrl->io, HDMI_SCRAMBLER_STATUS_DDC_TIMER_CTRL, to_in_num_lines); DSS_REG_W(ctrl->io, HDMI_SCRAMBLER_STATUS_DDC_TIMER_CTRL2, 0xFFFF); reg_val = DSS_REG_R(ctrl->io, HDMI_DDC_INT_CTRL5); io = ctrl->io; hdmi_ddc_clear_irq(ctrl, "scrambler"); DSS_REG_W(io, HDMI_SCRAMBLER_STATUS_DDC_TIMER_CTRL, timeout_hsync); DSS_REG_W(io, HDMI_SCRAMBLER_STATUS_DDC_TIMER_CTRL2, timeout_hsync); reg_val = DSS_REG_R(io, HDMI_DDC_INT_CTRL5); reg_val |= BIT(10); DSS_REG_W(ctrl->io, HDMI_DDC_INT_CTRL5, reg_val); DSS_REG_W(io, HDMI_DDC_INT_CTRL5, reg_val); reg_val = DSS_REG_R(ctrl->io, HDMI_DDC_INT_CTRL2); reg_val = DSS_REG_R(io, HDMI_DDC_INT_CTRL2); /* Trigger interrupt if scrambler status is 0 or DDC failure */ reg_val |= BIT(10); reg_val &= 0x18000; reg_val |= (0x2 << 15); DSS_REG_W(ctrl->io, HDMI_DDC_INT_CTRL2, reg_val); reg_val &= ~(BIT(15) | BIT(16)); reg_val |= BIT(16); DSS_REG_W(io, HDMI_DDC_INT_CTRL2, reg_val); /* Enable DDC access */ reg_val = DSS_REG_R(ctrl->io, HDMI_HW_DDC_CTRL); reg_val = DSS_REG_R(io, HDMI_HW_DDC_CTRL); reg_val &= ~0x300; reg_val |= (0x1 << 8); DSS_REG_W(ctrl->io, HDMI_HW_DDC_CTRL, reg_val); reg_val &= ~(BIT(8) | BIT(9)); reg_val |= BIT(8); DSS_REG_W(io, HDMI_HW_DDC_CTRL, reg_val); } static inline char *hdmi_scdc_reg2string(u32 type) Loading Loading @@ -499,47 +579,6 @@ static void hdmi_ddc_print_data(struct hdmi_tx_ddc_data *ddc_data) ddc_data->retry, ddc_data->what); } /* hdmi_ddc_print_data */ static int hdmi_ddc_clear_irq(struct hdmi_tx_ddc_ctrl *ddc_ctrl, char *what) { u32 ddc_int_ctrl, ddc_status, in_use, timeout; u32 sw_done_mask = BIT(2); u32 sw_done_ack = BIT(1); u32 hw_done_mask = BIT(6); u32 hw_done_ack = BIT(5); u32 in_use_by_sw = BIT(0); u32 in_use_by_hw = BIT(1); if (!ddc_ctrl || !ddc_ctrl->io) { pr_err("invalid input\n"); return -EINVAL; } /* clear and enable interrutps */ ddc_int_ctrl = sw_done_mask | sw_done_ack | hw_done_mask | hw_done_ack; DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_INT_CTRL, ddc_int_ctrl); /* wait until DDC HW is free */ timeout = 100; do { ddc_status = DSS_REG_R_ND(ddc_ctrl->io, HDMI_DDC_HW_STATUS); in_use = ddc_status & (in_use_by_sw | in_use_by_hw); if (in_use) { pr_debug("ddc is in use by %s\n", ddc_status & in_use_by_sw ? "sw" : "hw"); udelay(100); } } while (in_use && --timeout); if (!timeout) { pr_err("%s: timedout\n", what); return -ETIMEDOUT; } return 0; } /*hdmi_ddc_clear_irq */ static int hdmi_ddc_read_retry(struct hdmi_tx_ddc_ctrl *ddc_ctrl) { u32 reg_val, ndx, time_out_count, wait_time; Loading Loading @@ -796,23 +835,19 @@ static int hdmi_ddc_hdcp2p2_isr(struct hdmi_tx_ddc_ctrl *ddc_ctrl) struct hdmi_tx_hdcp2p2_ddc_data *data; u32 intr0, intr2; if (!ddc_ctrl) { if (!ddc_ctrl || !ddc_ctrl->io) { pr_err("invalid input\n"); return -EINVAL; } io = ddc_ctrl->io; if (!io) { pr_err("invalid io data\n"); return -EINVAL; } data = &ddc_ctrl->hdcp2p2_ddc_data; intr2 = DSS_REG_R(io, HDMI_HDCP_INT_CTRL2); intr0 = DSS_REG_R(io, HDMI_DDC_INT_CTRL0); pr_debug("ctl0: 0x%x, ctl1: 0x%x\n", intr0, intr2); pr_debug("intr0: 0x%x, intr2: 0x%x\n", intr0, intr2); /* check for encryption ready interrupt */ if (intr2 & BIT(2)) { Loading Loading @@ -848,7 +883,7 @@ static int hdmi_ddc_hdcp2p2_isr(struct hdmi_tx_ddc_ctrl *ddc_ctrl) } } DSS_REG_W_ND(ddc_ctrl->io, HDMI_HDCP_INT_CTRL2, intr2); DSS_REG_W_ND(io, HDMI_HDCP_INT_CTRL2, intr2); /* check for message size interrupt */ if (intr0 & BIT(31)) { Loading Loading @@ -913,7 +948,7 @@ static int hdmi_ddc_hdcp2p2_isr(struct hdmi_tx_ddc_ctrl *ddc_ctrl) data->ddc_read_req = (intr0 & BIT(0)) ? true : false; } DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_INT_CTRL0, intr0); DSS_REG_W_ND(io, HDMI_DDC_INT_CTRL0, intr0); if (data->message_size || data->ready || data->reauth_req) { if (!completion_done(&ddc_ctrl->rxstatus_completion)) Loading @@ -923,69 +958,97 @@ static int hdmi_ddc_hdcp2p2_isr(struct hdmi_tx_ddc_ctrl *ddc_ctrl) return 0; } int hdmi_ddc_isr(struct hdmi_tx_ddc_ctrl *ddc_ctrl, u32 version) static int hdmi_ddc_scrambling_isr(struct hdmi_tx_ddc_ctrl *ddc_ctrl) { u32 ddc_int_ctrl; u32 ddc_timer_int; struct dss_io_data *io; bool scrambler_timer_off = false; u32 intr2, intr5; if (!ddc_ctrl || !ddc_ctrl->io) { pr_err("invalid input\n"); return -EINVAL; } ddc_int_ctrl = DSS_REG_R_ND(ddc_ctrl->io, HDMI_DDC_INT_CTRL); if ((ddc_int_ctrl & BIT(2)) && (ddc_int_ctrl & BIT(0))) { /* SW_DONE INT occurred, clr it */ DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_INT_CTRL, ddc_int_ctrl | BIT(1)); complete(&ddc_ctrl->ddc_sw_done); io = ddc_ctrl->io; intr2 = DSS_REG_R_ND(ddc_ctrl->io, HDMI_DDC_INT_CTRL2); pr_debug("ddc_int_ctrl2=0x%x\n", intr2); if (intr2 & BIT(12)) { pr_err("SCRAMBLER_STATUS_NOT\n"); intr2 |= BIT(14); scrambler_timer_off = true; } if ((ddc_int_ctrl & BIT(6)) && (ddc_int_ctrl & BIT(4))) { /* HW_DONE INT occurred, clr it */ DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_INT_CTRL, ddc_int_ctrl | BIT(5)); } pr_debug("ddc_int_ctrl=%04x\n", ddc_int_ctrl); if (version < HDMI_TX_SCRAMBLER_MIN_TX_VERSION) goto end; ddc_timer_int = DSS_REG_R_ND(ddc_ctrl->io, HDMI_DDC_INT_CTRL2); if (ddc_timer_int & BIT(12)) { /* DDC_INT_CTRL2.SCRAMBLER_STATUS_NOT is set */ pr_err("Sink cannot descramble the signal\n"); /* Clear interrupt */ ddc_timer_int |= BIT(14); DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_INT_CTRL2, ddc_timer_int); if (intr2 & BIT(8)) { pr_err("SCRAMBLER_STATUS_DDC_FAILED\n"); intr2 |= BIT(9); scrambler_timer_off = true; } DSS_REG_W_ND(io, HDMI_DDC_INT_CTRL2, intr2); intr5 = DSS_REG_R_ND(io, HDMI_DDC_INT_CTRL5); pr_debug("ddc_int_ctrl5=0x%x\n", intr5); if (intr5 & BIT(8)) { pr_err("SCRAMBLER_STATUS_DDC_REQ_TIMEOUT\n"); intr5 |= BIT(9); ddc_timer_int = DSS_REG_R_ND(ddc_ctrl->io, HDMI_DDC_INT_CTRL5); if (ddc_timer_int & BIT(8)) { /* * DDC_INT_CTRL5.SCRAMBLER_STATUS_DDC_REQ_TIMEOUT * is set */ pr_err("DDC timeout while reading SCRAMBLER STATUS\n"); ddc_timer_int |= BIT(13); DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_INT_CTRL5, ddc_timer_int); scrambler_timer_off = true; } DSS_REG_W_ND(io, HDMI_DDC_INT_CTRL5, intr5); /* Disable scrambler status timer if it has been acknowledged */ if (scrambler_timer_off) { u32 regval = DSS_REG_R_ND(ddc_ctrl->io, HDMI_HW_DDC_CTRL); regval &= 0x300; DSS_REG_W_ND(ddc_ctrl->io, HDMI_HW_DDC_CTRL, regval); u32 reg_val = DSS_REG_R_ND(io, HDMI_HW_DDC_CTRL); reg_val &= ~(BIT(8) | BIT(9)); DSS_REG_W_ND(io, HDMI_HW_DDC_CTRL, reg_val); } end: hdmi_ddc_hdcp2p2_isr(ddc_ctrl); return 0; } int hdmi_ddc_isr(struct hdmi_tx_ddc_ctrl *ddc_ctrl, u32 version) { u32 ddc_int_ctrl, ret = 0; if (!ddc_ctrl || !ddc_ctrl->io) { pr_err("invalid input\n"); return -EINVAL; } ddc_int_ctrl = DSS_REG_R_ND(ddc_ctrl->io, HDMI_DDC_INT_CTRL); pr_debug("ddc_int_ctrl=0x%x\n", ddc_int_ctrl); if ((ddc_int_ctrl & BIT(2)) && (ddc_int_ctrl & BIT(0))) { pr_debug("ddc sw done\n"); ddc_int_ctrl |= BIT(1); complete(&ddc_ctrl->ddc_sw_done); } if ((ddc_int_ctrl & BIT(6)) && (ddc_int_ctrl & BIT(4))) { pr_debug("ddc hw done\n"); ddc_int_ctrl |= BIT(5); } DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_INT_CTRL, ddc_int_ctrl); if (version >= HDMI_TX_SCRAMBLER_MIN_TX_VERSION) { ret = hdmi_ddc_scrambling_isr(ddc_ctrl); if (ret) pr_err("err in scrambling isr\n"); } ret = hdmi_ddc_hdcp2p2_isr(ddc_ctrl); if (ret) pr_err("err in hdcp2p2 isr\n"); return ret; } /* hdmi_ddc_isr */ int hdmi_ddc_read(struct hdmi_tx_ddc_ctrl *ddc_ctrl) Loading Loading @@ -1127,8 +1190,6 @@ again: time_out_count = wait_for_completion_timeout( &ddc_ctrl->ddc_sw_done, HZ/2); reg_val = DSS_REG_R(ddc_ctrl->io, HDMI_DDC_INT_CTRL); DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_INT_CTRL, reg_val & (~BIT(2))); if (!time_out_count) { if (ddc_data->retry-- > 0) { pr_debug("failed timout, retry=%d\n", ddc_data->retry); Loading Loading @@ -1305,8 +1366,6 @@ again: pr_debug("DDC write done at %dms\n", jiffies_to_msecs(jiffies)); reg_val = DSS_REG_R(ddc_ctrl->io, HDMI_DDC_INT_CTRL); DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_INT_CTRL, reg_val & (~BIT(2))); if (!time_out_count) { if (retry-- > 0) { pr_debug("%s: failed timout, retry=%d\n", Loading drivers/video/msm/mdss/mdss_hdmi_util.h +5 −0 Original line number Diff line number Diff line Loading @@ -364,6 +364,9 @@ #define HDCP2P2_RXSTATUS_HW_DDC_FORCE_LOOP 2 #define HDCP2P2_RXSTATUS_HW_DDC_SW_TRIGGER 3 /* default hsyncs for 4k@60 for 200ms */ #define HDMI_DEFAULT_TIMEOUT_HSYNC 28571 enum hdmi_tx_feature_type { HDMI_TX_FEAT_EDID, HDMI_TX_FEAT_HDCP, Loading Loading @@ -496,5 +499,7 @@ void hdmi_hdcp2p2_ddc_reset(struct hdmi_tx_ddc_ctrl *ctrl); void hdmi_hdcp2p2_ddc_disable(struct hdmi_tx_ddc_ctrl *ctrl); int hdmi_hdcp2p2_ddc_read_rxstatus(struct hdmi_tx_ddc_ctrl *ctrl, bool wait); int hdmi_ddc_check_status(struct hdmi_tx_ddc_ctrl *ctrl); int hdmi_utils_get_timeout_in_hysnc(struct msm_hdmi_mode_timing_info *timing, u32 timeout_ms); #endif /* __HDMI_UTIL_H__ */ Loading
drivers/video/msm/mdss/mdss_hdmi_hdcp2p2.c +22 −37 Original line number Diff line number Diff line Loading @@ -36,9 +36,6 @@ #define HDCP2P2_LINK_CHECK_TIME_MS 900 /* link check within 1 sec */ #define HDCP2P2_SEC_TO_US 1000000 #define HDCP2P2_MS_TO_US 1000 #define HDCP2P2_KHZ_TO_HZ 1000 #define HDCP2P2_DEFAULT_TIMEOUT 500 /* Loading Loading @@ -600,15 +597,12 @@ exit: static void hdmi_hdcp2p2_recv_msg_work(struct kthread_work *work) { int rc = 0; u32 fps, v_total; u32 time_taken_by_one_line_us; u32 lines_needed_for_given_time; int timeout_hsync; char *recvd_msg_buf = NULL; struct hdmi_hdcp2p2_ctrl *ctrl = container_of(work, struct hdmi_hdcp2p2_ctrl, recv_msg); struct hdmi_tx_hdcp2p2_ddc_data *ddc_data; struct hdmi_tx_ddc_ctrl *ddc_ctrl; struct msm_hdmi_mode_timing_info *timing; struct hdcp_lib_wakeup_data cdata = {HDCP_LIB_WKUP_CMD_INVALID}; if (!ctrl) { Loading @@ -635,27 +629,21 @@ static void hdmi_hdcp2p2_recv_msg_work(struct kthread_work *work) memset(ddc_data, 0, sizeof(*ddc_data)); timing = ctrl->init_data.timing; timeout_hsync = hdmi_utils_get_timeout_in_hysnc( ctrl->init_data.timing, ctrl->timeout); fps = timing->refresh_rate / HDCP2P2_KHZ_TO_HZ; v_total = hdmi_tx_get_v_total(timing); /* * pixel clock = h_total * v_total * fps * 1 sec = pixel clock number of pixels are transmitted. * time taken by one line (h_total) = 1 / (v_total * fps). */ time_taken_by_one_line_us = HDCP2P2_SEC_TO_US / (v_total * fps); lines_needed_for_given_time = (ctrl->timeout * HDCP2P2_MS_TO_US) / time_taken_by_one_line_us; if (timeout_hsync <= 0) { pr_err("err in timeout hsync calc\n"); timeout_hsync = HDMI_DEFAULT_TIMEOUT_HSYNC; } pr_debug("timeout for rxstatus %dms, %d hsyncs\n", ctrl->timeout, lines_needed_for_given_time); pr_debug("timeout for rxstatus %dms, %d hsync\n", ctrl->timeout, timeout_hsync); ddc_data->intr_mask = RXSTATUS_MESSAGE_SIZE; ddc_data->timeout_ms = ctrl->timeout; ddc_data->timeout_hsync = lines_needed_for_given_time; ddc_data->periodic_timer_hsync = lines_needed_for_given_time / 20; ddc_data->timeout_hsync = timeout_hsync; ddc_data->periodic_timer_hsync = timeout_hsync / 20; ddc_data->read_method = HDCP2P2_RXSTATUS_HW_DDC_SW_TRIGGER; rc = hdmi_hdcp2p2_ddc_read_rxstatus(ddc_ctrl, true); Loading Loading @@ -704,10 +692,7 @@ static int hdmi_hdcp2p2_link_check(struct hdmi_hdcp2p2_ctrl *ctrl) { struct hdmi_tx_ddc_ctrl *ddc_ctrl; struct hdmi_tx_hdcp2p2_ddc_data *ddc_data; struct msm_hdmi_mode_timing_info *timing; u32 fps, v_total; u32 time_taken_by_one_line_us; u32 lines_needed_for_given_time; int timeout_hsync; ddc_ctrl = ctrl->init_data.ddc_ctrl; if (!ddc_ctrl) Loading @@ -719,20 +704,20 @@ static int hdmi_hdcp2p2_link_check(struct hdmi_hdcp2p2_ctrl *ctrl) memset(ddc_data, 0, sizeof(*ddc_data)); timing = ctrl->init_data.timing; fps = timing->refresh_rate / HDCP2P2_KHZ_TO_HZ; v_total = hdmi_tx_get_v_total(timing); time_taken_by_one_line_us = HDCP2P2_SEC_TO_US / (v_total * fps); lines_needed_for_given_time = (jiffies_to_msecs((HZ / 2) + (HZ / 4)) * HDCP2P2_MS_TO_US) / time_taken_by_one_line_us; timeout_hsync = hdmi_utils_get_timeout_in_hysnc( ctrl->init_data.timing, jiffies_to_msecs((HZ / 2) + (HZ / 4))); pr_debug("timeout for rxstatus %d hsyncs\n", lines_needed_for_given_time); if (timeout_hsync <= 0) { pr_err("err in timeout hsync calc\n"); timeout_hsync = HDMI_DEFAULT_TIMEOUT_HSYNC; } pr_debug("timeout for rxstatus %d hsyncs\n", timeout_hsync); ddc_data->intr_mask = RXSTATUS_READY | RXSTATUS_MESSAGE_SIZE | RXSTATUS_REAUTH_REQ; ddc_data->timeout_hsync = lines_needed_for_given_time; ddc_data->periodic_timer_hsync = lines_needed_for_given_time; ddc_data->timeout_hsync = timeout_hsync; ddc_data->periodic_timer_hsync = timeout_hsync; ddc_data->read_method = HDCP2P2_RXSTATUS_HW_DDC_SW_TRIGGER; return hdmi_hdcp2p2_ddc_read_rxstatus(ddc_ctrl, false); Loading
drivers/video/msm/mdss/mdss_hdmi_tx.c +17 −20 Original line number Diff line number Diff line Loading @@ -75,7 +75,7 @@ #define HDMI_TX_RGB_24BPP_PCLK_TMDS_CH_RATE_RATIO 1 #define HDMI_TX_SCRAMBLER_THRESHOLD_RATE_KHZ 340000 #define HDMI_TX_SCRAMBLER_TIMEOUT_USEC 200000 #define HDMI_TX_SCRAMBLER_TIMEOUT_MSEC 200 #define HDMI_TX_KHZ_TO_HZ 1000 #define HDMI_TX_MHZ_TO_HZ 1000000 Loading Loading @@ -3269,6 +3269,7 @@ int hdmi_tx_setup_scrambler(struct hdmi_tx_ctrl *hdmi_ctrl) struct dss_io_data *io = NULL; struct msm_hdmi_mode_timing_info *timing = NULL; void *edid_data = NULL; int timeout_hsync; if (!hdmi_ctrl) { DEV_ERR("%s: Bad input parameters\n", __func__); Loading @@ -3295,9 +3296,6 @@ int hdmi_tx_setup_scrambler(struct hdmi_tx_ctrl *hdmi_ctrl) return 0; } if (!hdmi_edid_get_scdc_support(edid_data)) DEV_WARN("%s: sink didn't provide scdc support\n", __func__); rate = hdmi_tx_setup_tmds_clk_rate(hdmi_ctrl); if (rate > HDMI_TX_SCRAMBLER_THRESHOLD_RATE_KHZ) { Loading @@ -3309,9 +3307,6 @@ int hdmi_tx_setup_scrambler(struct hdmi_tx_ctrl *hdmi_ctrl) } if (scrambler_on) { u64 mult; u64 div; rc = hdmi_scdc_write(&hdmi_ctrl->ddc_ctrl, HDMI_TX_SCDC_TMDS_BIT_CLOCK_RATIO_UPDATE, tmds_clock_ratio); Loading Loading @@ -3341,24 +3336,26 @@ int hdmi_tx_setup_scrambler(struct hdmi_tx_ctrl *hdmi_ctrl) * status bit on the sink. Sink should set this bit * with in 200ms after scrambler is enabled. */ mult = HDMI_TX_SCRAMBLER_TIMEOUT_USEC * ((u64)timing->pixel_freq * HDMI_TX_KHZ_TO_HZ); div = hdmi_tx_get_v_total(timing) * HDMI_TX_MHZ_TO_HZ; if (div) do_div(mult, div); else mult = 0; timeout_hsync = hdmi_utils_get_timeout_in_hysnc( &hdmi_ctrl->vid_cfg.timing, HDMI_TX_SCRAMBLER_TIMEOUT_MSEC); if (timeout_hsync <= 0) { DEV_ERR("%s: err in timeout hsync calc\n", __func__); timeout_hsync = HDMI_DEFAULT_TIMEOUT_HSYNC; } pr_debug("timeout for scrambling en: %d hsyncs\n", timeout_hsync); rc = hdmi_setup_ddc_timers(&hdmi_ctrl->ddc_ctrl, HDMI_TX_DDC_TIMER_SCRAMBLER_STATUS, (u32)mult); HDMI_TX_DDC_TIMER_SCRAMBLER_STATUS, timeout_hsync); } else { if (hdmi_ctrl->scrambler_enabled) { hdmi_scdc_write(&hdmi_ctrl->ddc_ctrl, HDMI_TX_SCDC_SCRAMBLING_ENABLE, 0x0); hdmi_ctrl->scrambler_enabled = false; } } return rc; } Loading
drivers/video/msm/mdss/mdss_hdmi_util.c +171 −112 Original line number Diff line number Diff line Loading @@ -19,37 +19,117 @@ #define RESOLUTION_NAME_STR_LEN 30 #define HDMI_SEC_TO_MS 1000 #define HDMI_MS_TO_US 1000 #define HDMI_SEC_TO_US (HDMI_SEC_TO_MS * HDMI_MS_TO_US) #define HDMI_KHZ_TO_HZ 1000 #define HDMI_SCDC_UNKNOWN_REGISTER "Unknown register" static char res_buf[RESOLUTION_NAME_STR_LEN]; int hdmi_utils_get_timeout_in_hysnc(struct msm_hdmi_mode_timing_info *timing, u32 timeout_ms) { u32 fps, v_total; u32 time_taken_by_one_line_us, lines_needed_for_given_time; if (!timing || !timeout_ms) { pr_err("invalid input\n"); return -EINVAL; } fps = timing->refresh_rate / HDMI_KHZ_TO_HZ; v_total = hdmi_tx_get_v_total(timing); /* * pixel clock = h_total * v_total * fps * 1 sec = pixel clock number of pixels are transmitted. * time taken by one line (h_total) = 1 / (v_total * fps). */ time_taken_by_one_line_us = HDMI_SEC_TO_US / (v_total * fps); lines_needed_for_given_time = (timeout_ms * HDMI_MS_TO_US) / time_taken_by_one_line_us; return lines_needed_for_given_time; } static int hdmi_ddc_clear_irq(struct hdmi_tx_ddc_ctrl *ddc_ctrl, char *what) { u32 ddc_int_ctrl, ddc_status, in_use, timeout; u32 sw_done_mask = BIT(2); u32 sw_done_ack = BIT(1); u32 hw_done_mask = BIT(6); u32 hw_done_ack = BIT(5); u32 in_use_by_sw = BIT(0); u32 in_use_by_hw = BIT(1); if (!ddc_ctrl || !ddc_ctrl->io) { pr_err("invalid input\n"); return -EINVAL; } /* clear and enable interrutps */ ddc_int_ctrl = sw_done_mask | sw_done_ack | hw_done_mask | hw_done_ack; DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_INT_CTRL, ddc_int_ctrl); /* wait until DDC HW is free */ timeout = 100; do { ddc_status = DSS_REG_R_ND(ddc_ctrl->io, HDMI_DDC_HW_STATUS); in_use = ddc_status & (in_use_by_sw | in_use_by_hw); if (in_use) { pr_debug("ddc is in use by %s, timeout(%d)\n", ddc_status & in_use_by_sw ? "sw" : "hw", timeout); udelay(100); } } while (in_use && --timeout); if (!timeout) { pr_err("%s: timedout\n", what); return -ETIMEDOUT; } return 0; } static void hdmi_scrambler_status_timer_setup(struct hdmi_tx_ddc_ctrl *ctrl, u32 to_in_num_lines) u32 timeout_hsync) { u32 reg_val; struct dss_io_data *io = NULL; if (!ctrl || !ctrl->io) { pr_err("invalid input\n"); return; } DSS_REG_W(ctrl->io, HDMI_SCRAMBLER_STATUS_DDC_TIMER_CTRL, to_in_num_lines); DSS_REG_W(ctrl->io, HDMI_SCRAMBLER_STATUS_DDC_TIMER_CTRL2, 0xFFFF); reg_val = DSS_REG_R(ctrl->io, HDMI_DDC_INT_CTRL5); io = ctrl->io; hdmi_ddc_clear_irq(ctrl, "scrambler"); DSS_REG_W(io, HDMI_SCRAMBLER_STATUS_DDC_TIMER_CTRL, timeout_hsync); DSS_REG_W(io, HDMI_SCRAMBLER_STATUS_DDC_TIMER_CTRL2, timeout_hsync); reg_val = DSS_REG_R(io, HDMI_DDC_INT_CTRL5); reg_val |= BIT(10); DSS_REG_W(ctrl->io, HDMI_DDC_INT_CTRL5, reg_val); DSS_REG_W(io, HDMI_DDC_INT_CTRL5, reg_val); reg_val = DSS_REG_R(ctrl->io, HDMI_DDC_INT_CTRL2); reg_val = DSS_REG_R(io, HDMI_DDC_INT_CTRL2); /* Trigger interrupt if scrambler status is 0 or DDC failure */ reg_val |= BIT(10); reg_val &= 0x18000; reg_val |= (0x2 << 15); DSS_REG_W(ctrl->io, HDMI_DDC_INT_CTRL2, reg_val); reg_val &= ~(BIT(15) | BIT(16)); reg_val |= BIT(16); DSS_REG_W(io, HDMI_DDC_INT_CTRL2, reg_val); /* Enable DDC access */ reg_val = DSS_REG_R(ctrl->io, HDMI_HW_DDC_CTRL); reg_val = DSS_REG_R(io, HDMI_HW_DDC_CTRL); reg_val &= ~0x300; reg_val |= (0x1 << 8); DSS_REG_W(ctrl->io, HDMI_HW_DDC_CTRL, reg_val); reg_val &= ~(BIT(8) | BIT(9)); reg_val |= BIT(8); DSS_REG_W(io, HDMI_HW_DDC_CTRL, reg_val); } static inline char *hdmi_scdc_reg2string(u32 type) Loading Loading @@ -499,47 +579,6 @@ static void hdmi_ddc_print_data(struct hdmi_tx_ddc_data *ddc_data) ddc_data->retry, ddc_data->what); } /* hdmi_ddc_print_data */ static int hdmi_ddc_clear_irq(struct hdmi_tx_ddc_ctrl *ddc_ctrl, char *what) { u32 ddc_int_ctrl, ddc_status, in_use, timeout; u32 sw_done_mask = BIT(2); u32 sw_done_ack = BIT(1); u32 hw_done_mask = BIT(6); u32 hw_done_ack = BIT(5); u32 in_use_by_sw = BIT(0); u32 in_use_by_hw = BIT(1); if (!ddc_ctrl || !ddc_ctrl->io) { pr_err("invalid input\n"); return -EINVAL; } /* clear and enable interrutps */ ddc_int_ctrl = sw_done_mask | sw_done_ack | hw_done_mask | hw_done_ack; DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_INT_CTRL, ddc_int_ctrl); /* wait until DDC HW is free */ timeout = 100; do { ddc_status = DSS_REG_R_ND(ddc_ctrl->io, HDMI_DDC_HW_STATUS); in_use = ddc_status & (in_use_by_sw | in_use_by_hw); if (in_use) { pr_debug("ddc is in use by %s\n", ddc_status & in_use_by_sw ? "sw" : "hw"); udelay(100); } } while (in_use && --timeout); if (!timeout) { pr_err("%s: timedout\n", what); return -ETIMEDOUT; } return 0; } /*hdmi_ddc_clear_irq */ static int hdmi_ddc_read_retry(struct hdmi_tx_ddc_ctrl *ddc_ctrl) { u32 reg_val, ndx, time_out_count, wait_time; Loading Loading @@ -796,23 +835,19 @@ static int hdmi_ddc_hdcp2p2_isr(struct hdmi_tx_ddc_ctrl *ddc_ctrl) struct hdmi_tx_hdcp2p2_ddc_data *data; u32 intr0, intr2; if (!ddc_ctrl) { if (!ddc_ctrl || !ddc_ctrl->io) { pr_err("invalid input\n"); return -EINVAL; } io = ddc_ctrl->io; if (!io) { pr_err("invalid io data\n"); return -EINVAL; } data = &ddc_ctrl->hdcp2p2_ddc_data; intr2 = DSS_REG_R(io, HDMI_HDCP_INT_CTRL2); intr0 = DSS_REG_R(io, HDMI_DDC_INT_CTRL0); pr_debug("ctl0: 0x%x, ctl1: 0x%x\n", intr0, intr2); pr_debug("intr0: 0x%x, intr2: 0x%x\n", intr0, intr2); /* check for encryption ready interrupt */ if (intr2 & BIT(2)) { Loading Loading @@ -848,7 +883,7 @@ static int hdmi_ddc_hdcp2p2_isr(struct hdmi_tx_ddc_ctrl *ddc_ctrl) } } DSS_REG_W_ND(ddc_ctrl->io, HDMI_HDCP_INT_CTRL2, intr2); DSS_REG_W_ND(io, HDMI_HDCP_INT_CTRL2, intr2); /* check for message size interrupt */ if (intr0 & BIT(31)) { Loading Loading @@ -913,7 +948,7 @@ static int hdmi_ddc_hdcp2p2_isr(struct hdmi_tx_ddc_ctrl *ddc_ctrl) data->ddc_read_req = (intr0 & BIT(0)) ? true : false; } DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_INT_CTRL0, intr0); DSS_REG_W_ND(io, HDMI_DDC_INT_CTRL0, intr0); if (data->message_size || data->ready || data->reauth_req) { if (!completion_done(&ddc_ctrl->rxstatus_completion)) Loading @@ -923,69 +958,97 @@ static int hdmi_ddc_hdcp2p2_isr(struct hdmi_tx_ddc_ctrl *ddc_ctrl) return 0; } int hdmi_ddc_isr(struct hdmi_tx_ddc_ctrl *ddc_ctrl, u32 version) static int hdmi_ddc_scrambling_isr(struct hdmi_tx_ddc_ctrl *ddc_ctrl) { u32 ddc_int_ctrl; u32 ddc_timer_int; struct dss_io_data *io; bool scrambler_timer_off = false; u32 intr2, intr5; if (!ddc_ctrl || !ddc_ctrl->io) { pr_err("invalid input\n"); return -EINVAL; } ddc_int_ctrl = DSS_REG_R_ND(ddc_ctrl->io, HDMI_DDC_INT_CTRL); if ((ddc_int_ctrl & BIT(2)) && (ddc_int_ctrl & BIT(0))) { /* SW_DONE INT occurred, clr it */ DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_INT_CTRL, ddc_int_ctrl | BIT(1)); complete(&ddc_ctrl->ddc_sw_done); io = ddc_ctrl->io; intr2 = DSS_REG_R_ND(ddc_ctrl->io, HDMI_DDC_INT_CTRL2); pr_debug("ddc_int_ctrl2=0x%x\n", intr2); if (intr2 & BIT(12)) { pr_err("SCRAMBLER_STATUS_NOT\n"); intr2 |= BIT(14); scrambler_timer_off = true; } if ((ddc_int_ctrl & BIT(6)) && (ddc_int_ctrl & BIT(4))) { /* HW_DONE INT occurred, clr it */ DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_INT_CTRL, ddc_int_ctrl | BIT(5)); } pr_debug("ddc_int_ctrl=%04x\n", ddc_int_ctrl); if (version < HDMI_TX_SCRAMBLER_MIN_TX_VERSION) goto end; ddc_timer_int = DSS_REG_R_ND(ddc_ctrl->io, HDMI_DDC_INT_CTRL2); if (ddc_timer_int & BIT(12)) { /* DDC_INT_CTRL2.SCRAMBLER_STATUS_NOT is set */ pr_err("Sink cannot descramble the signal\n"); /* Clear interrupt */ ddc_timer_int |= BIT(14); DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_INT_CTRL2, ddc_timer_int); if (intr2 & BIT(8)) { pr_err("SCRAMBLER_STATUS_DDC_FAILED\n"); intr2 |= BIT(9); scrambler_timer_off = true; } DSS_REG_W_ND(io, HDMI_DDC_INT_CTRL2, intr2); intr5 = DSS_REG_R_ND(io, HDMI_DDC_INT_CTRL5); pr_debug("ddc_int_ctrl5=0x%x\n", intr5); if (intr5 & BIT(8)) { pr_err("SCRAMBLER_STATUS_DDC_REQ_TIMEOUT\n"); intr5 |= BIT(9); ddc_timer_int = DSS_REG_R_ND(ddc_ctrl->io, HDMI_DDC_INT_CTRL5); if (ddc_timer_int & BIT(8)) { /* * DDC_INT_CTRL5.SCRAMBLER_STATUS_DDC_REQ_TIMEOUT * is set */ pr_err("DDC timeout while reading SCRAMBLER STATUS\n"); ddc_timer_int |= BIT(13); DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_INT_CTRL5, ddc_timer_int); scrambler_timer_off = true; } DSS_REG_W_ND(io, HDMI_DDC_INT_CTRL5, intr5); /* Disable scrambler status timer if it has been acknowledged */ if (scrambler_timer_off) { u32 regval = DSS_REG_R_ND(ddc_ctrl->io, HDMI_HW_DDC_CTRL); regval &= 0x300; DSS_REG_W_ND(ddc_ctrl->io, HDMI_HW_DDC_CTRL, regval); u32 reg_val = DSS_REG_R_ND(io, HDMI_HW_DDC_CTRL); reg_val &= ~(BIT(8) | BIT(9)); DSS_REG_W_ND(io, HDMI_HW_DDC_CTRL, reg_val); } end: hdmi_ddc_hdcp2p2_isr(ddc_ctrl); return 0; } int hdmi_ddc_isr(struct hdmi_tx_ddc_ctrl *ddc_ctrl, u32 version) { u32 ddc_int_ctrl, ret = 0; if (!ddc_ctrl || !ddc_ctrl->io) { pr_err("invalid input\n"); return -EINVAL; } ddc_int_ctrl = DSS_REG_R_ND(ddc_ctrl->io, HDMI_DDC_INT_CTRL); pr_debug("ddc_int_ctrl=0x%x\n", ddc_int_ctrl); if ((ddc_int_ctrl & BIT(2)) && (ddc_int_ctrl & BIT(0))) { pr_debug("ddc sw done\n"); ddc_int_ctrl |= BIT(1); complete(&ddc_ctrl->ddc_sw_done); } if ((ddc_int_ctrl & BIT(6)) && (ddc_int_ctrl & BIT(4))) { pr_debug("ddc hw done\n"); ddc_int_ctrl |= BIT(5); } DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_INT_CTRL, ddc_int_ctrl); if (version >= HDMI_TX_SCRAMBLER_MIN_TX_VERSION) { ret = hdmi_ddc_scrambling_isr(ddc_ctrl); if (ret) pr_err("err in scrambling isr\n"); } ret = hdmi_ddc_hdcp2p2_isr(ddc_ctrl); if (ret) pr_err("err in hdcp2p2 isr\n"); return ret; } /* hdmi_ddc_isr */ int hdmi_ddc_read(struct hdmi_tx_ddc_ctrl *ddc_ctrl) Loading Loading @@ -1127,8 +1190,6 @@ again: time_out_count = wait_for_completion_timeout( &ddc_ctrl->ddc_sw_done, HZ/2); reg_val = DSS_REG_R(ddc_ctrl->io, HDMI_DDC_INT_CTRL); DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_INT_CTRL, reg_val & (~BIT(2))); if (!time_out_count) { if (ddc_data->retry-- > 0) { pr_debug("failed timout, retry=%d\n", ddc_data->retry); Loading Loading @@ -1305,8 +1366,6 @@ again: pr_debug("DDC write done at %dms\n", jiffies_to_msecs(jiffies)); reg_val = DSS_REG_R(ddc_ctrl->io, HDMI_DDC_INT_CTRL); DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_INT_CTRL, reg_val & (~BIT(2))); if (!time_out_count) { if (retry-- > 0) { pr_debug("%s: failed timout, retry=%d\n", Loading
drivers/video/msm/mdss/mdss_hdmi_util.h +5 −0 Original line number Diff line number Diff line Loading @@ -364,6 +364,9 @@ #define HDCP2P2_RXSTATUS_HW_DDC_FORCE_LOOP 2 #define HDCP2P2_RXSTATUS_HW_DDC_SW_TRIGGER 3 /* default hsyncs for 4k@60 for 200ms */ #define HDMI_DEFAULT_TIMEOUT_HSYNC 28571 enum hdmi_tx_feature_type { HDMI_TX_FEAT_EDID, HDMI_TX_FEAT_HDCP, Loading Loading @@ -496,5 +499,7 @@ void hdmi_hdcp2p2_ddc_reset(struct hdmi_tx_ddc_ctrl *ctrl); void hdmi_hdcp2p2_ddc_disable(struct hdmi_tx_ddc_ctrl *ctrl); int hdmi_hdcp2p2_ddc_read_rxstatus(struct hdmi_tx_ddc_ctrl *ctrl, bool wait); int hdmi_ddc_check_status(struct hdmi_tx_ddc_ctrl *ctrl); int hdmi_utils_get_timeout_in_hysnc(struct msm_hdmi_mode_timing_info *timing, u32 timeout_ms); #endif /* __HDMI_UTIL_H__ */