Loading drivers/video/fbdev/msm/mdss_dp.c +10 −12 Original line number Diff line number Diff line Loading @@ -1022,6 +1022,8 @@ static int dp_init_panel_info(struct mdss_dp_drv_pdata *dp_drv, u32 vic) pinfo->lcdc.hsync_skew = 0; pinfo->is_pluggable = true; dp_drv->bpp = pinfo->bpp; pr_debug("update res. vic= %d, pclk_rate = %llu\n", dp_drv->vic, pinfo->clk_rate); Loading Loading @@ -1786,16 +1788,15 @@ static void mdss_dp_do_link_train(struct mdss_dp_drv_pdata *dp) static void mdss_dp_event_work(struct work_struct *work) { struct mdss_dp_drv_pdata *dp = NULL; struct delayed_work *dw = to_delayed_work(work); unsigned long flag; u32 todo = 0, dp_config_pkt[2]; u32 todo = 0, config; if (!dw) { if (!work) { pr_err("invalid work structure\n"); return; } dp = container_of(dw, struct mdss_dp_drv_pdata, dwork); dp = container_of(work, struct mdss_dp_drv_pdata, work); spin_lock_irqsave(&dp->event_lock, flag); todo = dp->current_event; Loading Loading @@ -1840,11 +1841,9 @@ static void mdss_dp_event_work(struct work_struct *work) SVDM_CMD_TYPE_INITIATOR, 0x1, 0x0, 0x0); break; case EV_USBPD_DP_CONFIGURE: dp_config_pkt[0] = SVDM_HDR(USB_C_DP_SID, VDM_VERSION, 0x1, SVDM_CMD_TYPE_INITIATOR, DP_VDM_CONFIGURE); dp_config_pkt[1] = mdss_dp_usbpd_gen_config_pkt(dp); config = mdss_dp_usbpd_gen_config_pkt(dp); usbpd_send_svdm(dp->pd, USB_C_DP_SID, DP_VDM_CONFIGURE, SVDM_CMD_TYPE_INITIATOR, 0x1, dp_config_pkt, 0x2); SVDM_CMD_TYPE_INITIATOR, 0x1, &config, 0x1); break; default: pr_err("Unknown event:%d\n", todo); Loading @@ -1855,7 +1854,7 @@ static void dp_send_events(struct mdss_dp_drv_pdata *dp, u32 events) { spin_lock(&dp->event_lock); dp->current_event = events; queue_delayed_work(dp->workq, &dp->dwork, HZ / 100); queue_work(dp->workq, &dp->work); spin_unlock(&dp->event_lock); } Loading Loading @@ -1931,7 +1930,7 @@ static int mdss_dp_event_setup(struct mdss_dp_drv_pdata *dp) return -EPERM; } INIT_DELAYED_WORK(&dp->dwork, mdss_dp_event_work); INIT_WORK(&dp->work, mdss_dp_event_work); return 0; } Loading Loading @@ -2050,8 +2049,7 @@ static void usbpd_response_callback(struct usbpd_svid_handler *hdlr, u8 cmd, } break; case DP_VDM_CONFIGURE: if ((dp_drv->cable_connected == true) || (cmd_type == SVDM_CMD_TYPE_RESP_ACK)) { if (cmd_type == SVDM_CMD_TYPE_RESP_ACK) { dp_drv->alt_mode.current_state = DP_CONFIGURE_DONE; pr_debug("config USBPD to DP done\n"); mdss_dp_host_init(&dp_drv->panel_data); Loading drivers/video/fbdev/msm/mdss_dp.h +1 −1 Original line number Diff line number Diff line Loading @@ -428,7 +428,7 @@ struct mdss_dp_drv_pdata { /* event */ struct workqueue_struct *workq; struct delayed_work dwork; struct work_struct work; u32 current_event; spinlock_t event_lock; spinlock_t lock; Loading drivers/video/fbdev/msm/mdss_dp_aux.c +56 −62 Original line number Diff line number Diff line Loading @@ -374,7 +374,19 @@ static int dp_aux_read_buf(struct mdss_dp_drv_pdata *ep, u32 addr, /* * edid standard header bytes */ static char edid_hdr[8] = {0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00}; static u8 edid_hdr[8] = {0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00}; static bool dp_edid_is_valid_header(u8 *buf) { int i; for (i = 0; i < ARRAY_SIZE(edid_hdr); i++) { if (buf[i] != edid_hdr[i]) return false; } return true; } int dp_edid_buf_error(char *buf, int len) { Loading @@ -396,11 +408,6 @@ int dp_edid_buf_error(char *buf, int len) return -EINVAL; } if (strncmp(buf, edid_hdr, strlen(edid_hdr))) { pr_err("Error: header\n"); return -EINVAL; } return 0; } Loading Loading @@ -708,10 +715,11 @@ static int dp_aux_chan_ready(struct mdss_dp_drv_pdata *ep) int mdss_dp_edid_read(struct mdss_dp_drv_pdata *dp) { struct edp_buf *rp; int cnt, rlen; int ret = 0; int blk_num = 0; struct edp_buf *rp = &dp->rxp; int rlen, ret = 0; int edid_blk = 0, blk_num = 0, retries = 10; bool edid_parsing_done = false; const u8 cea_tag = 0x02; ret = dp_aux_chan_ready(dp); if (ret) { Loading @@ -719,25 +727,25 @@ int mdss_dp_edid_read(struct mdss_dp_drv_pdata *dp) return ret; } for (cnt = 5; cnt; cnt--) { rlen = dp_aux_read_buf (dp, EDID_START_ADDRESS, EDID_BLOCK_SIZE, 1); if (rlen > 0) { pr_debug("cnt=%d, block=%d, rlen=%d\n", cnt, blk_num, rlen); rp = &dp->rxp; if (!dp_edid_buf_error(rp->data, rp->len)) break; } } if ((cnt <= 0) && (rlen != EDID_BLOCK_SIZE)) { do { rlen = dp_aux_read_buf(dp, EDID_START_ADDRESS + (blk_num * EDID_BLOCK_SIZE), EDID_BLOCK_SIZE, 1); if (rlen != EDID_BLOCK_SIZE) { pr_err("Read failed. rlen=%d\n", rlen); return -EINVAL; continue; } rp = &dp->rxp; pr_debug("blk_num=%d, rlen=%d\n", blk_num, rlen); if (dp_edid_is_valid_header(rp->data)) { if (dp_edid_buf_error(rp->data, rp->len)) continue; if (edid_parsing_done) { blk_num++; continue; } dp_extract_edid_manufacturer(&dp->edid, rp->data); dp_extract_edid_product(&dp->edid, rp->data); Loading @@ -745,44 +753,30 @@ int mdss_dp_edid_read(struct mdss_dp_drv_pdata *dp) dp_extract_edid_ext_block_cnt(&dp->edid, rp->data); dp_extract_edid_video_support(&dp->edid, rp->data); dp_extract_edid_feature(&dp->edid, rp->data); dp_extract_edid_detailed_timing_description(&dp->edid, rp->data); /* for the first block initialize the edid buffer size */ dp->edid_buf_size = 0; pr_debug("edid extension = %d\n", dp->edid.ext_block_cnt); dp_extract_edid_detailed_timing_description(&dp->edid, rp->data); memcpy(dp->edid_buf, rp->data, EDID_BLOCK_SIZE); dp->edid_buf_size += EDID_BLOCK_SIZE; edid_parsing_done = true; } else { edid_blk++; blk_num++; if (!dp->edid.ext_block_cnt) return 0; /* fix dongle byte shift issue */ if (edid_blk == 1 && rp->data[0] != cea_tag) { u8 tmp[EDID_BLOCK_SIZE - 1]; for (blk_num = 1; blk_num <= dp->edid.ext_block_cnt; blk_num++) { for (cnt = 5; cnt; cnt--) { rlen = dp_aux_read_buf (dp, EDID_START_ADDRESS + (blk_num * EDID_BLOCK_SIZE), EDID_BLOCK_SIZE, 1); if (rlen > 0) { pr_debug("cnt=%d, blk_num=%d, rlen=%d\n", cnt, blk_num, rlen); rp = &dp->rxp; if (!dp_edid_buf_error(rp->data, rp->len)) break; memcpy(tmp, rp->data, EDID_BLOCK_SIZE - 1); rp->data[0] = cea_tag; memcpy(rp->data + 1, tmp, EDID_BLOCK_SIZE - 1); } } if ((cnt <= 0) && (rlen != EDID_BLOCK_SIZE)) { pr_err("Read failed. rlen=%d\n", rlen); return -EINVAL; } memcpy(dp->edid_buf + (blk_num * EDID_BLOCK_SIZE), memcpy(dp->edid_buf + (edid_blk * EDID_BLOCK_SIZE), rp->data, EDID_BLOCK_SIZE); dp->edid_buf_size += EDID_BLOCK_SIZE; } if (edid_blk == dp->edid.ext_block_cnt) return 0; } while (retries--); return 0; } Loading drivers/video/fbdev/msm/mdss_dp_util.c +38 −1 Original line number Diff line number Diff line Loading @@ -32,6 +32,29 @@ #define AUDIO_FREQ_48 48000 #define DP_AUDIO_FREQ_COUNT 3 enum mdss_dp_pin_assignment { PIN_ASSIGNMENT_A, PIN_ASSIGNMENT_B, PIN_ASSIGNMENT_C, PIN_ASSIGNMENT_D, PIN_ASSIGNMENT_E, PIN_ASSIGNMENT_F, PIN_ASSIGNMENT_MAX, }; static const char *mdss_dp_pin_name(u8 pin) { switch (pin) { case PIN_ASSIGNMENT_A: return "PIN_ASSIGNMENT_A"; case PIN_ASSIGNMENT_B: return "PIN_ASSIGNMENT_B"; case PIN_ASSIGNMENT_C: return "PIN_ASSIGNMENT_C"; case PIN_ASSIGNMENT_D: return "PIN_ASSIGNMENT_D"; case PIN_ASSIGNMENT_E: return "PIN_ASSIGNMENT_E"; case PIN_ASSIGNMENT_F: return "PIN_ASSIGNMENT_F"; default: return "UNKNOWN"; } } static const uint32_t naud_value[DP_AUDIO_FREQ_COUNT][DP_AUDIO_FREQ_COUNT] = { { 10125, 16875, 33750 }, { 5625, 9375, 18750 }, Loading Loading @@ -477,9 +500,23 @@ void mdss_dp_usbpd_ext_dp_status(struct usbpd_dp_status *dp_status) u32 mdss_dp_usbpd_gen_config_pkt(struct mdss_dp_drv_pdata *dp) { u8 pin_cfg, pin; u32 config = 0; config |= (dp->alt_mode.dp_cap.dlink_pin_config << 8); pin_cfg = dp->alt_mode.dp_cap.dlink_pin_config; for (pin = PIN_ASSIGNMENT_A; pin < PIN_ASSIGNMENT_MAX; pin++) { if (pin_cfg & BIT(pin)) break; } if (pin == PIN_ASSIGNMENT_MAX) pin = PIN_ASSIGNMENT_C; pr_debug("pin assignment: %s\n", mdss_dp_pin_name(pin)); config |= BIT(pin) << 8; config |= (0x1 << 2); /* configure for DPv1.3 */ config |= 0x2; /* Configuring for UFP_D */ Loading Loading
drivers/video/fbdev/msm/mdss_dp.c +10 −12 Original line number Diff line number Diff line Loading @@ -1022,6 +1022,8 @@ static int dp_init_panel_info(struct mdss_dp_drv_pdata *dp_drv, u32 vic) pinfo->lcdc.hsync_skew = 0; pinfo->is_pluggable = true; dp_drv->bpp = pinfo->bpp; pr_debug("update res. vic= %d, pclk_rate = %llu\n", dp_drv->vic, pinfo->clk_rate); Loading Loading @@ -1786,16 +1788,15 @@ static void mdss_dp_do_link_train(struct mdss_dp_drv_pdata *dp) static void mdss_dp_event_work(struct work_struct *work) { struct mdss_dp_drv_pdata *dp = NULL; struct delayed_work *dw = to_delayed_work(work); unsigned long flag; u32 todo = 0, dp_config_pkt[2]; u32 todo = 0, config; if (!dw) { if (!work) { pr_err("invalid work structure\n"); return; } dp = container_of(dw, struct mdss_dp_drv_pdata, dwork); dp = container_of(work, struct mdss_dp_drv_pdata, work); spin_lock_irqsave(&dp->event_lock, flag); todo = dp->current_event; Loading Loading @@ -1840,11 +1841,9 @@ static void mdss_dp_event_work(struct work_struct *work) SVDM_CMD_TYPE_INITIATOR, 0x1, 0x0, 0x0); break; case EV_USBPD_DP_CONFIGURE: dp_config_pkt[0] = SVDM_HDR(USB_C_DP_SID, VDM_VERSION, 0x1, SVDM_CMD_TYPE_INITIATOR, DP_VDM_CONFIGURE); dp_config_pkt[1] = mdss_dp_usbpd_gen_config_pkt(dp); config = mdss_dp_usbpd_gen_config_pkt(dp); usbpd_send_svdm(dp->pd, USB_C_DP_SID, DP_VDM_CONFIGURE, SVDM_CMD_TYPE_INITIATOR, 0x1, dp_config_pkt, 0x2); SVDM_CMD_TYPE_INITIATOR, 0x1, &config, 0x1); break; default: pr_err("Unknown event:%d\n", todo); Loading @@ -1855,7 +1854,7 @@ static void dp_send_events(struct mdss_dp_drv_pdata *dp, u32 events) { spin_lock(&dp->event_lock); dp->current_event = events; queue_delayed_work(dp->workq, &dp->dwork, HZ / 100); queue_work(dp->workq, &dp->work); spin_unlock(&dp->event_lock); } Loading Loading @@ -1931,7 +1930,7 @@ static int mdss_dp_event_setup(struct mdss_dp_drv_pdata *dp) return -EPERM; } INIT_DELAYED_WORK(&dp->dwork, mdss_dp_event_work); INIT_WORK(&dp->work, mdss_dp_event_work); return 0; } Loading Loading @@ -2050,8 +2049,7 @@ static void usbpd_response_callback(struct usbpd_svid_handler *hdlr, u8 cmd, } break; case DP_VDM_CONFIGURE: if ((dp_drv->cable_connected == true) || (cmd_type == SVDM_CMD_TYPE_RESP_ACK)) { if (cmd_type == SVDM_CMD_TYPE_RESP_ACK) { dp_drv->alt_mode.current_state = DP_CONFIGURE_DONE; pr_debug("config USBPD to DP done\n"); mdss_dp_host_init(&dp_drv->panel_data); Loading
drivers/video/fbdev/msm/mdss_dp.h +1 −1 Original line number Diff line number Diff line Loading @@ -428,7 +428,7 @@ struct mdss_dp_drv_pdata { /* event */ struct workqueue_struct *workq; struct delayed_work dwork; struct work_struct work; u32 current_event; spinlock_t event_lock; spinlock_t lock; Loading
drivers/video/fbdev/msm/mdss_dp_aux.c +56 −62 Original line number Diff line number Diff line Loading @@ -374,7 +374,19 @@ static int dp_aux_read_buf(struct mdss_dp_drv_pdata *ep, u32 addr, /* * edid standard header bytes */ static char edid_hdr[8] = {0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00}; static u8 edid_hdr[8] = {0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00}; static bool dp_edid_is_valid_header(u8 *buf) { int i; for (i = 0; i < ARRAY_SIZE(edid_hdr); i++) { if (buf[i] != edid_hdr[i]) return false; } return true; } int dp_edid_buf_error(char *buf, int len) { Loading @@ -396,11 +408,6 @@ int dp_edid_buf_error(char *buf, int len) return -EINVAL; } if (strncmp(buf, edid_hdr, strlen(edid_hdr))) { pr_err("Error: header\n"); return -EINVAL; } return 0; } Loading Loading @@ -708,10 +715,11 @@ static int dp_aux_chan_ready(struct mdss_dp_drv_pdata *ep) int mdss_dp_edid_read(struct mdss_dp_drv_pdata *dp) { struct edp_buf *rp; int cnt, rlen; int ret = 0; int blk_num = 0; struct edp_buf *rp = &dp->rxp; int rlen, ret = 0; int edid_blk = 0, blk_num = 0, retries = 10; bool edid_parsing_done = false; const u8 cea_tag = 0x02; ret = dp_aux_chan_ready(dp); if (ret) { Loading @@ -719,25 +727,25 @@ int mdss_dp_edid_read(struct mdss_dp_drv_pdata *dp) return ret; } for (cnt = 5; cnt; cnt--) { rlen = dp_aux_read_buf (dp, EDID_START_ADDRESS, EDID_BLOCK_SIZE, 1); if (rlen > 0) { pr_debug("cnt=%d, block=%d, rlen=%d\n", cnt, blk_num, rlen); rp = &dp->rxp; if (!dp_edid_buf_error(rp->data, rp->len)) break; } } if ((cnt <= 0) && (rlen != EDID_BLOCK_SIZE)) { do { rlen = dp_aux_read_buf(dp, EDID_START_ADDRESS + (blk_num * EDID_BLOCK_SIZE), EDID_BLOCK_SIZE, 1); if (rlen != EDID_BLOCK_SIZE) { pr_err("Read failed. rlen=%d\n", rlen); return -EINVAL; continue; } rp = &dp->rxp; pr_debug("blk_num=%d, rlen=%d\n", blk_num, rlen); if (dp_edid_is_valid_header(rp->data)) { if (dp_edid_buf_error(rp->data, rp->len)) continue; if (edid_parsing_done) { blk_num++; continue; } dp_extract_edid_manufacturer(&dp->edid, rp->data); dp_extract_edid_product(&dp->edid, rp->data); Loading @@ -745,44 +753,30 @@ int mdss_dp_edid_read(struct mdss_dp_drv_pdata *dp) dp_extract_edid_ext_block_cnt(&dp->edid, rp->data); dp_extract_edid_video_support(&dp->edid, rp->data); dp_extract_edid_feature(&dp->edid, rp->data); dp_extract_edid_detailed_timing_description(&dp->edid, rp->data); /* for the first block initialize the edid buffer size */ dp->edid_buf_size = 0; pr_debug("edid extension = %d\n", dp->edid.ext_block_cnt); dp_extract_edid_detailed_timing_description(&dp->edid, rp->data); memcpy(dp->edid_buf, rp->data, EDID_BLOCK_SIZE); dp->edid_buf_size += EDID_BLOCK_SIZE; edid_parsing_done = true; } else { edid_blk++; blk_num++; if (!dp->edid.ext_block_cnt) return 0; /* fix dongle byte shift issue */ if (edid_blk == 1 && rp->data[0] != cea_tag) { u8 tmp[EDID_BLOCK_SIZE - 1]; for (blk_num = 1; blk_num <= dp->edid.ext_block_cnt; blk_num++) { for (cnt = 5; cnt; cnt--) { rlen = dp_aux_read_buf (dp, EDID_START_ADDRESS + (blk_num * EDID_BLOCK_SIZE), EDID_BLOCK_SIZE, 1); if (rlen > 0) { pr_debug("cnt=%d, blk_num=%d, rlen=%d\n", cnt, blk_num, rlen); rp = &dp->rxp; if (!dp_edid_buf_error(rp->data, rp->len)) break; memcpy(tmp, rp->data, EDID_BLOCK_SIZE - 1); rp->data[0] = cea_tag; memcpy(rp->data + 1, tmp, EDID_BLOCK_SIZE - 1); } } if ((cnt <= 0) && (rlen != EDID_BLOCK_SIZE)) { pr_err("Read failed. rlen=%d\n", rlen); return -EINVAL; } memcpy(dp->edid_buf + (blk_num * EDID_BLOCK_SIZE), memcpy(dp->edid_buf + (edid_blk * EDID_BLOCK_SIZE), rp->data, EDID_BLOCK_SIZE); dp->edid_buf_size += EDID_BLOCK_SIZE; } if (edid_blk == dp->edid.ext_block_cnt) return 0; } while (retries--); return 0; } Loading
drivers/video/fbdev/msm/mdss_dp_util.c +38 −1 Original line number Diff line number Diff line Loading @@ -32,6 +32,29 @@ #define AUDIO_FREQ_48 48000 #define DP_AUDIO_FREQ_COUNT 3 enum mdss_dp_pin_assignment { PIN_ASSIGNMENT_A, PIN_ASSIGNMENT_B, PIN_ASSIGNMENT_C, PIN_ASSIGNMENT_D, PIN_ASSIGNMENT_E, PIN_ASSIGNMENT_F, PIN_ASSIGNMENT_MAX, }; static const char *mdss_dp_pin_name(u8 pin) { switch (pin) { case PIN_ASSIGNMENT_A: return "PIN_ASSIGNMENT_A"; case PIN_ASSIGNMENT_B: return "PIN_ASSIGNMENT_B"; case PIN_ASSIGNMENT_C: return "PIN_ASSIGNMENT_C"; case PIN_ASSIGNMENT_D: return "PIN_ASSIGNMENT_D"; case PIN_ASSIGNMENT_E: return "PIN_ASSIGNMENT_E"; case PIN_ASSIGNMENT_F: return "PIN_ASSIGNMENT_F"; default: return "UNKNOWN"; } } static const uint32_t naud_value[DP_AUDIO_FREQ_COUNT][DP_AUDIO_FREQ_COUNT] = { { 10125, 16875, 33750 }, { 5625, 9375, 18750 }, Loading Loading @@ -477,9 +500,23 @@ void mdss_dp_usbpd_ext_dp_status(struct usbpd_dp_status *dp_status) u32 mdss_dp_usbpd_gen_config_pkt(struct mdss_dp_drv_pdata *dp) { u8 pin_cfg, pin; u32 config = 0; config |= (dp->alt_mode.dp_cap.dlink_pin_config << 8); pin_cfg = dp->alt_mode.dp_cap.dlink_pin_config; for (pin = PIN_ASSIGNMENT_A; pin < PIN_ASSIGNMENT_MAX; pin++) { if (pin_cfg & BIT(pin)) break; } if (pin == PIN_ASSIGNMENT_MAX) pin = PIN_ASSIGNMENT_C; pr_debug("pin assignment: %s\n", mdss_dp_pin_name(pin)); config |= BIT(pin) << 8; config |= (0x1 << 2); /* configure for DPv1.3 */ config |= 0x2; /* Configuring for UFP_D */ Loading