diff options
| author | Linux Build Service Account <lnxbuild@localhost> | 2016-11-15 03:22:28 -0700 |
|---|---|---|
| committer | Linux Build Service Account <lnxbuild@localhost> | 2016-11-15 03:22:28 -0700 |
| commit | 06f25a82e3cd17ed9eba423bda7c37a7ee618ca1 (patch) | |
| tree | d67616ca5e112e3fb9673cf46697c4fe51e73aad | |
| parent | 124459b203bf648a97d88f7d9977f6882d7a47ac (diff) | |
| parent | 24d0c1f91eb2850889cb27ef6fdcadc0c8ff2834 (diff) | |
Promotion of kernel.lnx.4.4-161115.
CRs Change ID Subject
--------------------------------------------------------------------------------------------------------------
1087395 Ib43bdbc1ac51334bcd930657c99f7a0aa255255a clk: msm: mdss: fix potential use of un-initialized vari
1085169 1086278 I67e08d3491fbb7c0960c463cc8f979238b89d818 mdss: display-port: add support to configure stream attr
1062506 I36fd45efe1aa9437d5551002fc75a5f37d9cef79 msm: mdss: dp: handle fast attention events
1084634 I932a58fc633918b151959fcbe320668a87dbc49c msm: sde: add buf_finish callback to clear last fd
1085169 I391ee35fa20cfade89773ecb565b220cc6249b8d msm: mdss: hdcp2p2: check for valid keys before authenti
1085169 Ia69987c0e15ec5f15a07ca3a0e44174ab6e5feb9 msm: mdss: dp: select pin assignment D for multi-functio
Change-Id: I9deaf7b62fdf15bd1d6862708ba755abdb51be74
CRs-Fixed: 1062506, 1085169, 1084634, 1087395, 1086278
| -rw-r--r-- | arch/arm/boot/dts/qcom/msmcobalt-mdss.dtsi | 3 | ||||
| -rw-r--r-- | drivers/clk/msm/mdss/mdss-dp-pll-cobalt-util.c | 2 | ||||
| -rw-r--r-- | drivers/clk/msm/mdss/mdss-dsi-pll-cobalt.c | 18 | ||||
| -rw-r--r-- | drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c | 34 | ||||
| -rw-r--r-- | drivers/misc/hdcp.c | 59 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_dp.c | 144 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_dp.h | 5 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_dp_aux.c | 2 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_dp_util.c | 56 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_dp_util.h | 11 |
10 files changed, 279 insertions, 55 deletions
diff --git a/arch/arm/boot/dts/qcom/msmcobalt-mdss.dtsi b/arch/arm/boot/dts/qcom/msmcobalt-mdss.dtsi index 9c72ebf4a0bd..75c985189842 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-mdss.dtsi +++ b/arch/arm/boot/dts/qcom/msmcobalt-mdss.dtsi @@ -468,9 +468,10 @@ reg = <0xc990000 0xa84>, <0xc011000 0x910>, <0x1fcb200 0x050>, + <0xc8c2200 0x1a0>, <0x780000 0x621c>, <0xc9e1000 0x02c>; - reg-names = "dp_ctrl", "dp_phy", "tcsr_regs", + reg-names = "dp_ctrl", "dp_phy", "tcsr_regs", "dp_mmss_cc", "qfprom_physical","hdcp_physical"; clocks = <&clock_mmss clk_mmss_mnoc_ahb_clk>, diff --git a/drivers/clk/msm/mdss/mdss-dp-pll-cobalt-util.c b/drivers/clk/msm/mdss/mdss-dp-pll-cobalt-util.c index a574a9cd2b5a..f23f32f7e37a 100644 --- a/drivers/clk/msm/mdss/mdss-dp-pll-cobalt-util.c +++ b/drivers/clk/msm/mdss/mdss-dp-pll-cobalt-util.c @@ -733,7 +733,7 @@ unsigned long dp_vco_get_rate(struct clk *c) { struct dp_pll_vco_clk *vco = mdss_dp_to_vco_clk(c); int rc; - u32 div, hsclk_div, link2xclk_div; + u32 div, hsclk_div, link2xclk_div = 0; u64 vco_rate; struct mdss_pll_resources *pll = vco->priv; diff --git a/drivers/clk/msm/mdss/mdss-dsi-pll-cobalt.c b/drivers/clk/msm/mdss/mdss-dsi-pll-cobalt.c index 4b2d8bba0940..299934c86d05 100644 --- a/drivers/clk/msm/mdss/mdss-dsi-pll-cobalt.c +++ b/drivers/clk/msm/mdss/mdss-dsi-pll-cobalt.c @@ -205,18 +205,34 @@ static void dsi_pll_calc_dec_frac(struct dsi_pll_cobalt *pll, struct dsi_pll_regs *regs = &pll->reg_setup; u64 target_freq; u64 fref = rsc->vco_ref_clk_rate; - u32 computed_output_div, div_log; + u32 computed_output_div, div_log = 0; u64 pll_freq; u64 divider; u64 dec, dec_multiple; u32 frac; u64 multiplier; + u32 i; target_freq = rsc->vco_current_rate; pr_debug("target_freq = %llu\n", target_freq); if (config->div_override) { computed_output_div = config->output_div; + + /* + * Computed_output_div = 2 ^ div_log + * To get div_log from output div just get the index of the + * 1 bit in the value. + * div_log ranges from 0-3. so check the 4 lsbs + */ + + for (i = 0; i < 4; i++) { + if (computed_output_div & (1 << i)) { + div_log = i; + break; + } + } + } else { if (target_freq < MHZ_375) { computed_output_div = 8; diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c index b88f03ce89ae..08075ae90507 100644 --- a/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c +++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c @@ -305,6 +305,39 @@ static void sde_rotator_buf_queue(struct vb2_buffer *vb) } /* + * sde_rotator_buf_finish - vb2_ops buf_finish to finalize buffer before going + * back to user space + * @vb: Pointer to vb2 buffer struct. + */ +static void sde_rotator_buf_finish(struct vb2_buffer *vb) +{ + struct sde_rotator_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); + int i; + + SDEDEV_DBG(ctx->rot_dev->dev, + "buf_finish t:%d i:%d s:%d m:%u np:%d up:%lu\n", + vb->type, vb->index, vb->state, + vb->vb2_queue->memory, + vb->num_planes, + vb->planes[0].m.userptr); + + if (vb->vb2_queue->memory != VB2_MEMORY_USERPTR) + return; + + /* + * We use userptr to tunnel fd, and fd can be the same across qbuf + * even though the underlying buffer is different. Since vb2 layer + * optimizes memory mapping for userptr by first checking if userptr + * has changed, it will not trigger put_userptr if fd value does + * not change. In order to force buffer release, we need to clear + * userptr when the current buffer is done and ready to go back to + * user mode. Since 0 is a valid fd, reset userptr to -1 instead. + */ + for (i = 0; i < vb->num_planes; i++) + vb->planes[i].m.userptr = ~0; +} + +/* * sde_rotator_return_all_buffers - Return all buffers with the given status. * @q: Pointer to vb2 buffer queue struct. * @state: State of the buffer @@ -460,6 +493,7 @@ static struct vb2_ops sde_rotator_vb2_q_ops = { .stop_streaming = sde_rotator_stop_streaming, .wait_prepare = vb2_ops_wait_prepare, .wait_finish = vb2_ops_wait_finish, + .buf_finish = sde_rotator_buf_finish, }; /* diff --git a/drivers/misc/hdcp.c b/drivers/misc/hdcp.c index 69ec7127102c..56ddf8467d16 100644 --- a/drivers/misc/hdcp.c +++ b/drivers/misc/hdcp.c @@ -255,6 +255,15 @@ struct __attribute__ ((__packed__)) hdcp_version_rsp { uint32_t appversion; }; +struct __attribute__ ((__packed__)) hdcp_verify_key_req { + uint32_t commandid; +}; + +struct __attribute__ ((__packed__)) hdcp_verify_key_rsp { + uint32_t status; + uint32_t commandId; +}; + struct __attribute__ ((__packed__)) hdcp_lib_init_req_v1 { uint32_t commandid; }; @@ -794,6 +803,48 @@ exit: return rc; } +static int hdcp_lib_verify_keys(struct hdcp_lib_handle *handle) +{ + int rc = -EINVAL; + struct hdcp_verify_key_req *req_buf; + struct hdcp_verify_key_rsp *rsp_buf; + + if (!handle) { + pr_err("invalid input\n"); + goto exit; + } + + if (!(handle->hdcp_state & HDCP_STATE_APP_LOADED)) { + pr_err("app not loaded\n"); + goto exit; + } + + req_buf = (struct hdcp_verify_key_req *)handle->qseecom_handle->sbuf; + req_buf->commandid = HDCP_TXMTR_VERIFY_KEY; + + rsp_buf = (struct hdcp_verify_key_rsp *) + (handle->qseecom_handle->sbuf + + QSEECOM_ALIGN(sizeof(struct hdcp_verify_key_req))); + + rc = qseecom_send_command(handle->qseecom_handle, + req_buf, + QSEECOM_ALIGN(sizeof + (struct hdcp_verify_key_req)), + rsp_buf, + QSEECOM_ALIGN(sizeof + (struct hdcp_verify_key_rsp))); + + if (rc < 0) { + pr_err("qseecom cmd failed err = %d\n", rc); + goto exit; + } + + return rsp_buf->status; +exit: + return rc; +} + + static int hdcp_app_init_legacy(struct hdcp_lib_handle *handle) { int rc = 0; @@ -1456,10 +1507,12 @@ static bool hdcp_lib_client_feature_supported(void *phdcpcontext) rc = hdcp_lib_library_load(handle); if (!rc) { - pr_debug("HDCP2p2 supported\n"); - handle->feature_supported = true; + if (!hdcp_lib_verify_keys(handle)) { + pr_debug("HDCP2p2 supported\n"); + handle->feature_supported = true; + supported = true; + } hdcp_lib_library_unload(handle); - supported = true; } exit: return supported; diff --git a/drivers/video/fbdev/msm/mdss_dp.c b/drivers/video/fbdev/msm/mdss_dp.c index 75e42ca8cd88..29fc4e6fd65b 100644 --- a/drivers/video/fbdev/msm/mdss_dp.c +++ b/drivers/video/fbdev/msm/mdss_dp.c @@ -45,6 +45,11 @@ #define VDDA_UA_ON_LOAD 100000 /* uA units */ #define VDDA_UA_OFF_LOAD 100 /* uA units */ +struct mdss_dp_attention_node { + u32 vdo; + struct list_head list; +}; + #define DEFAULT_VIDEO_RESOLUTION HDMI_VFRMT_640x480p60_4_3 static u32 supported_modes[] = { HDMI_VFRMT_640x480p60_4_3, @@ -60,6 +65,7 @@ static u32 supported_modes[] = { static int mdss_dp_off_irq(struct mdss_dp_drv_pdata *dp_drv); static void mdss_dp_mainlink_push_idle(struct mdss_panel_data *pdata); static inline void mdss_dp_link_retraining(struct mdss_dp_drv_pdata *dp); +static void mdss_dp_handle_attention(struct mdss_dp_drv_pdata *dp_drv); static void mdss_dp_put_dt_clk_data(struct device *dev, struct dss_module_power *module_power) @@ -1133,7 +1139,7 @@ static void mdss_dp_configure_source_params(struct mdss_dp_drv_pdata *dp, mdss_dp_fill_link_cfg(dp); mdss_dp_mainlink_ctrl(&dp->ctrl_io, true); mdss_dp_config_ctrl(dp); - mdss_dp_sw_mvid_nvid(&dp->ctrl_io); + mdss_dp_sw_config_msa(&dp->ctrl_io, dp->link_rate, &dp->dp_cc_io); mdss_dp_timing_cfg(&dp->ctrl_io, &dp->panel_data.panel_info); } @@ -1290,7 +1296,6 @@ link_training: dp_drv->cont_splash = 0; dp_drv->power_on = true; - mdss_dp_ack_state(dp_drv, true); pr_debug("End-\n"); exit: @@ -1559,6 +1564,7 @@ static int mdss_dp_host_init(struct mdss_panel_data *pdata) goto edid_error; } + mdss_dp_update_cable_status(dp_drv, true); mdss_dp_notify_clients(dp_drv, true); dp_drv->dp_initialized = true; @@ -1883,8 +1889,13 @@ static void mdss_dp_update_hdcp_info(struct mdss_dp_drv_pdata *dp) } /* update internal data about hdcp */ - dp->hdcp.data = fd; - dp->hdcp.ops = ops; + if (dp->hdcp.hdcp2_present || dp->hdcp.hdcp1_present) { + dp->hdcp.data = fd; + dp->hdcp.ops = ops; + } else { + dp->hdcp.data = NULL; + dp->hdcp.ops = NULL; + } } static inline bool dp_is_hdcp_enabled(struct mdss_dp_drv_pdata *dp_drv) @@ -1920,6 +1931,8 @@ static int mdss_dp_event_handler(struct mdss_panel_data *pdata, if (dp->hdcp.ops && dp->hdcp.ops->authenticate) rc = dp->hdcp.ops->authenticate(dp->hdcp.data); + + mdss_dp_ack_state(dp, true); break; case MDSS_EVENT_PANEL_OFF: rc = mdss_dp_off(pdata); @@ -2041,6 +2054,12 @@ static int mdss_retrieve_dp_ctrl_resources(struct platform_device *pdev, return rc; } + if (msm_dss_ioremap_byname(pdev, &dp_drv->dp_cc_io, "dp_mmss_cc")) { + pr_err("%d unable to remap dp MMSS_CC resources\n", + __LINE__); + return rc; + } + if (msm_dss_ioremap_byname(pdev, &dp_drv->qfprom_io, "qfprom_physical")) pr_warn("unable to remap dp qfprom resources\n"); @@ -2117,6 +2136,9 @@ static void mdss_dp_event_work(struct work_struct *work) case EV_IDLE_PATTERNS_SENT: mdss_dp_idle_patterns_sent(dp); break; + case EV_USBPD_ATTENTION: + mdss_dp_handle_attention(dp); + break; case EV_USBPD_DISCOVER_MODES: usbpd_send_svdm(dp->pd, USB_C_DP_SID, USBPD_SVDM_DISCOVER_MODES, SVDM_CMD_TYPE_INITIATOR, 0x0, 0x0, 0x0); @@ -2225,6 +2247,7 @@ static int mdss_dp_event_setup(struct mdss_dp_drv_pdata *dp) INIT_WORK(&dp->work, mdss_dp_event_work); INIT_DELAYED_WORK(&dp->hdcp_cb_work, mdss_dp_hdcp_cb_work); + INIT_LIST_HEAD(&dp->attention_head); return 0; } @@ -2508,6 +2531,7 @@ static void usbpd_response_callback(struct usbpd_svid_handler *hdlr, u8 cmd, const u32 *vdos, int num_vdos) { struct mdss_dp_drv_pdata *dp_drv; + struct mdss_dp_attention_node *node; dp_drv = container_of(hdlr, struct mdss_dp_drv_pdata, svid_handler); if (!dp_drv->pd) { @@ -2535,45 +2559,14 @@ static void usbpd_response_callback(struct usbpd_svid_handler *hdlr, u8 cmd, dp_send_events(dp_drv, EV_USBPD_DP_STATUS); break; case USBPD_SVDM_ATTENTION: - dp_drv->alt_mode.dp_status.response = *vdos; - mdss_dp_usbpd_ext_dp_status(&dp_drv->alt_mode.dp_status); - - dp_drv->hpd_irq_toggled = dp_drv->hpd_irq_on != - dp_drv->alt_mode.dp_status.hpd_irq; + node = kzalloc(sizeof(*node), GFP_KERNEL); + node->vdo = *vdos; - if (dp_drv->alt_mode.dp_status.hpd_irq) { - pr_debug("Attention: hpd_irq high\n"); - - if (dp_drv->power_on && dp_drv->hdcp.ops && - dp_drv->hdcp.ops->cp_irq) - dp_drv->hdcp.ops->cp_irq(dp_drv->hdcp.data); - - if (!mdss_dp_process_hpd_irq_high(dp_drv)) - break; - } else if (dp_drv->hpd_irq_toggled) { - if (!mdss_dp_process_hpd_irq_low(dp_drv)) - break; - } - - if (!dp_drv->alt_mode.dp_status.hpd_high) { - pr_debug("Attention: HPD low\n"); - mdss_dp_update_cable_status(dp_drv, false); - mdss_dp_notify_clients(dp_drv, false); - pr_debug("Attention: Notified clients\n"); - break; - } - - pr_debug("Attention: HPD high\n"); - - mdss_dp_update_cable_status(dp_drv, true); - - dp_drv->alt_mode.current_state |= DP_STATUS_DONE; - - if (dp_drv->alt_mode.current_state & DP_CONFIGURE_DONE) - mdss_dp_host_init(&dp_drv->panel_data); - else - dp_send_events(dp_drv, EV_USBPD_DP_CONFIGURE); + mutex_lock(&dp_drv->attention_lock); + list_add_tail(&node->list, &dp_drv->attention_head); + mutex_unlock(&dp_drv->attention_lock); + dp_send_events(dp_drv, EV_USBPD_ATTENTION); break; case DP_VDM_STATUS: dp_drv->alt_mode.dp_status.response = *vdos; @@ -2597,6 +2590,74 @@ static void usbpd_response_callback(struct usbpd_svid_handler *hdlr, u8 cmd, } } +static void mdss_dp_process_attention(struct mdss_dp_drv_pdata *dp_drv) +{ + dp_drv->hpd_irq_toggled = dp_drv->hpd_irq_on != + dp_drv->alt_mode.dp_status.hpd_irq; + + if (dp_drv->alt_mode.dp_status.hpd_irq) { + pr_debug("Attention: hpd_irq high\n"); + + if (dp_drv->power_on && dp_drv->hdcp.ops && + dp_drv->hdcp.ops->cp_irq) + dp_drv->hdcp.ops->cp_irq(dp_drv->hdcp.data); + + if (!mdss_dp_process_hpd_irq_high(dp_drv)) + return; + } else if (dp_drv->hpd_irq_toggled) { + if (!mdss_dp_process_hpd_irq_low(dp_drv)) + return; + } + + if (!dp_drv->alt_mode.dp_status.hpd_high) { + pr_debug("Attention: HPD low\n"); + mdss_dp_update_cable_status(dp_drv, false); + mdss_dp_notify_clients(dp_drv, false); + pr_debug("Attention: Notified clients\n"); + return; + } + + pr_debug("Attention: HPD high\n"); + + mdss_dp_update_cable_status(dp_drv, true); + + dp_drv->alt_mode.current_state |= DP_STATUS_DONE; + + if (dp_drv->alt_mode.current_state & DP_CONFIGURE_DONE) + mdss_dp_host_init(&dp_drv->panel_data); + else + dp_send_events(dp_drv, EV_USBPD_DP_CONFIGURE); + + pr_debug("exit\n"); +} + +static void mdss_dp_handle_attention(struct mdss_dp_drv_pdata *dp) +{ + int i = 0; + + while (!list_empty_careful(&dp->attention_head)) { + struct mdss_dp_attention_node *node; + u32 vdo; + + pr_debug("processing item %d in the list\n", ++i); + + mutex_lock(&dp->attention_lock); + node = list_first_entry(&dp->attention_head, + struct mdss_dp_attention_node, list); + + vdo = node->vdo; + list_del(&node->list); + mutex_unlock(&dp->attention_lock); + + kzfree(node); + + dp->alt_mode.dp_status.response = vdo; + mdss_dp_usbpd_ext_dp_status(&dp->alt_mode.dp_status); + mdss_dp_process_attention(dp); + }; + +} + static int mdss_dp_usbpd_setup(struct mdss_dp_drv_pdata *dp_drv) { int ret = 0; @@ -2670,6 +2731,7 @@ static int mdss_dp_probe(struct platform_device *pdev) dp_drv->mask2 = EDP_INTR_MASK2; mutex_init(&dp_drv->emutex); mutex_init(&dp_drv->pd_msg_mutex); + mutex_init(&dp_drv->attention_lock); mutex_init(&dp_drv->hdcp_mutex); spin_lock_init(&dp_drv->lock); diff --git a/drivers/video/fbdev/msm/mdss_dp.h b/drivers/video/fbdev/msm/mdss_dp.h index e801eceeef1b..04abe9221acc 100644 --- a/drivers/video/fbdev/msm/mdss_dp.h +++ b/drivers/video/fbdev/msm/mdss_dp.h @@ -205,6 +205,7 @@ struct dp_alt_mode { #define EV_USBPD_DP_CONFIGURE BIT(10) #define EV_USBPD_CC_PIN_POLARITY BIT(11) #define EV_USBPD_EXIT_MODE BIT(12) +#define EV_USBPD_ATTENTION BIT(13) /* dp state ctrl */ #define ST_TRAIN_PATTERN_1 BIT(0) @@ -406,6 +407,7 @@ struct mdss_dp_drv_pdata { struct dss_io_data ctrl_io; struct dss_io_data phy_io; struct dss_io_data tcsr_reg_io; + struct dss_io_data dp_cc_io; struct dss_io_data qfprom_io; struct dss_io_data hdcp_io; int base_size; @@ -454,6 +456,7 @@ struct mdss_dp_drv_pdata { struct mutex aux_mutex; struct mutex train_mutex; struct mutex pd_msg_mutex; + struct mutex attention_lock; struct mutex hdcp_mutex; bool cable_connected; u32 s3d_mode; @@ -497,6 +500,8 @@ struct mdss_dp_drv_pdata { struct dpcd_test_request test_data; struct dpcd_sink_count sink_count; + + struct list_head attention_head; }; enum dp_lane_count { diff --git a/drivers/video/fbdev/msm/mdss_dp_aux.c b/drivers/video/fbdev/msm/mdss_dp_aux.c index f9dba99a653d..e396dfff60ef 100644 --- a/drivers/video/fbdev/msm/mdss_dp_aux.c +++ b/drivers/video/fbdev/msm/mdss_dp_aux.c @@ -1647,6 +1647,8 @@ int mdss_dp_link_train(struct mdss_dp_drv_pdata *dp) clear: dp_clear_training_pattern(dp); if (ret != -EINVAL) { + mdss_dp_config_misc_settings(&dp->ctrl_io, + &dp->panel_data.panel_info); mdss_dp_setup_tr_unit(&dp->ctrl_io, dp->link_rate, dp->lane_cnt, dp->vic); mdss_dp_state_ctrl(&dp->ctrl_io, ST_SEND_VIDEO); diff --git a/drivers/video/fbdev/msm/mdss_dp_util.c b/drivers/video/fbdev/msm/mdss_dp_util.c index 2d24d8499105..86edc4492599 100644 --- a/drivers/video/fbdev/msm/mdss_dp_util.c +++ b/drivers/video/fbdev/msm/mdss_dp_util.c @@ -253,10 +253,48 @@ void mdss_dp_timing_cfg(struct dss_io_data *ctrl_io, writel_relaxed(data, ctrl_io->base + DP_ACTIVE_HOR_VER); } -void mdss_dp_sw_mvid_nvid(struct dss_io_data *ctrl_io) +void mdss_dp_sw_config_msa(struct dss_io_data *ctrl_io, + char lrate, struct dss_io_data *dp_cc_io) { - writel_relaxed(0x37, ctrl_io->base + DP_SOFTWARE_MVID); - writel_relaxed(0x3c, ctrl_io->base + DP_SOFTWARE_NVID); + u32 pixel_m, pixel_n; + u32 mvid, nvid; + + pixel_m = readl_relaxed(dp_cc_io->base + MMSS_DP_PIXEL_M); + pixel_n = readl_relaxed(dp_cc_io->base + MMSS_DP_PIXEL_N); + pr_debug("pixel_m=0x%x, pixel_n=0x%x\n", + pixel_m, pixel_n); + + mvid = (pixel_m & 0xFFFF) * 5; + nvid = (0xFFFF & (~pixel_n)) + (pixel_m & 0xFFFF); + if (lrate == DP_LINK_RATE_540) + nvid = nvid * 2; + pr_debug("mvid=0x%x, nvid=0x%x\n", mvid, nvid); + writel_relaxed(mvid, ctrl_io->base + DP_SOFTWARE_MVID); + writel_relaxed(nvid, ctrl_io->base + DP_SOFTWARE_NVID); +} + +void mdss_dp_config_misc_settings(struct dss_io_data *ctrl_io, + struct mdss_panel_info *pinfo) +{ + u32 bpp = pinfo->bpp; + u32 misc_val = 0x0; + + switch (bpp) { + case 18: + misc_val |= (0x0 << 5); + break; + case 30: + misc_val |= (0x2 << 5); + break; + case 24: + default: + misc_val |= (0x1 << 5); + } + + misc_val |= BIT(0); /* Configure clock to synchronous mode */ + + pr_debug("Misc settings = 0x%x\n", misc_val); + writel_relaxed(misc_val, ctrl_io->base + DP_MISC1_MISC0); } void mdss_dp_setup_tr_unit(struct dss_io_data *ctrl_io, u8 link_rate, @@ -267,8 +305,6 @@ void mdss_dp_setup_tr_unit(struct dss_io_data *ctrl_io, u8 link_rate, u32 valid_boundary2 = 0x0; struct dp_vc_tu_mapping_table const *tu_entry = tu_table; - writel_relaxed(0x21, ctrl_io->base + DP_MISC1_MISC0); - for (; tu_entry != tu_table + ARRAY_SIZE(tu_table); ++tu_entry) { if ((tu_entry->vic == res) && (tu_entry->lanes == ln_cnt) && @@ -454,8 +490,14 @@ u32 mdss_dp_usbpd_gen_config_pkt(struct mdss_dp_drv_pdata *dp) 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_cfg & BIT(pin)) { + if (dp->alt_mode.dp_status.multi_func) { + if (pin == PIN_ASSIGNMENT_D) + break; + } else { + break; + } + } } if (pin == PIN_ASSIGNMENT_MAX) diff --git a/drivers/video/fbdev/msm/mdss_dp_util.h b/drivers/video/fbdev/msm/mdss_dp_util.h index 334c0071050d..4b28d98177be 100644 --- a/drivers/video/fbdev/msm/mdss_dp_util.h +++ b/drivers/video/fbdev/msm/mdss_dp_util.h @@ -164,6 +164,12 @@ #define TCSR_USB3_DP_PHYMODE 0x48 #define EDID_START_ADDRESS 0x50 +/* DP MMSS_CC registers */ +#define MMSS_DP_LINK_CMD_RCGR 0x0000 +#define MMSS_DP_LINK_CFG_RCGR 0x0004 +#define MMSS_DP_PIXEL_M 0x0048 +#define MMSS_DP_PIXEL_N 0x004C + /* DP HDCP 1.3 registers */ #define DP_HDCP_CTRL (0x0A0) #define DP_HDCP_STATUS (0x0A4) @@ -271,6 +277,8 @@ void mdss_dp_switch_usb3_phy_to_dp_mode(struct dss_io_data *tcsr_reg_io); void mdss_dp_assert_phy_reset(struct dss_io_data *ctrl_io, bool assert); void mdss_dp_setup_tr_unit(struct dss_io_data *ctrl_io, u8 link_rate, u8 ln_cnt, u32 res); +void mdss_dp_config_misc_settings(struct dss_io_data *ctrl_io, + struct mdss_panel_info *pinfo); void mdss_dp_phy_aux_setup(struct dss_io_data *phy_io); void mdss_dp_hpd_configure(struct dss_io_data *ctrl_io, bool enable); void mdss_dp_aux_ctrl(struct dss_io_data *ctrl_io, bool enable); @@ -285,7 +293,8 @@ void mdss_dp_state_ctrl(struct dss_io_data *ctrl_io, u32 data); int mdss_dp_irq_setup(struct mdss_dp_drv_pdata *dp_drv); void mdss_dp_irq_enable(struct mdss_dp_drv_pdata *dp_drv); void mdss_dp_irq_disable(struct mdss_dp_drv_pdata *dp_drv); -void mdss_dp_sw_mvid_nvid(struct dss_io_data *ctrl_io); +void mdss_dp_sw_config_msa(struct dss_io_data *ctrl_io, + char lrate, struct dss_io_data *dp_cc_io); void mdss_dp_usbpd_ext_capabilities(struct usbpd_dp_capabilities *dp_cap); 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); |
