diff options
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_dp.c | 4 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_dp.h | 36 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_dp_aux.c | 25 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_dp_util.c | 57 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_dp_util.h | 3 |
5 files changed, 96 insertions, 29 deletions
diff --git a/drivers/video/fbdev/msm/mdss_dp.c b/drivers/video/fbdev/msm/mdss_dp.c index a74bf6f60774..7d4578b08244 100644 --- a/drivers/video/fbdev/msm/mdss_dp.c +++ b/drivers/video/fbdev/msm/mdss_dp.c @@ -1455,7 +1455,7 @@ static void mdss_dp_configure_source_params(struct mdss_dp_drv_pdata *dp, mdss_dp_config_misc(dp, mdss_dp_bpp_to_test_bit_depth(mdss_dp_get_bpp(dp)), mdss_dp_get_colorimetry_config(dp)); - mdss_dp_sw_config_msa(&dp->ctrl_io, dp->link_rate, &dp->dp_cc_io); + mdss_dp_sw_config_msa(dp); mdss_dp_timing_cfg(&dp->ctrl_io, &dp->panel_data.panel_info); } @@ -1715,7 +1715,7 @@ int mdss_dp_on(struct mdss_panel_data *pdata) static bool mdss_dp_is_ds_bridge(struct mdss_dp_drv_pdata *dp) { - return dp->dpcd.downstream_port.dfp_present; + return dp->dpcd.downstream_port.dsp_present; } static bool mdss_dp_is_ds_bridge_sink_count_zero(struct mdss_dp_drv_pdata *dp) diff --git a/drivers/video/fbdev/msm/mdss_dp.h b/drivers/video/fbdev/msm/mdss_dp.h index f358aad8a667..afa8e3db590f 100644 --- a/drivers/video/fbdev/msm/mdss_dp.h +++ b/drivers/video/fbdev/msm/mdss_dp.h @@ -230,14 +230,38 @@ struct dp_alt_mode { #define DP_LINK_RATE_MULTIPLIER 27000000 #define DP_KHZ_TO_HZ 1000 #define DP_MAX_PIXEL_CLK_KHZ 675000 + +enum downstream_port_type { + DSP_TYPE_DP = 0x00, + DSP_TYPE_VGA, + DSP_TYPE_DVI_HDMI_DPPP, + DSP_TYPE_OTHER, +}; + +static inline char *mdss_dp_dsp_type_to_string(u32 dsp_type) +{ + switch (dsp_type) { + case DSP_TYPE_DP: + return DP_ENUM_STR(DSP_TYPE_DP); + case DSP_TYPE_VGA: + return DP_ENUM_STR(DSP_TYPE_VGA); + case DSP_TYPE_DVI_HDMI_DPPP: + return DP_ENUM_STR(DSP_TYPE_DVI_HDMI_DPPP); + case DSP_TYPE_OTHER: + return DP_ENUM_STR(DSP_TYPE_OTHER); + default: + return "unknown"; + } +} + struct downstream_port_config { /* Byte 02205h */ - bool dfp_present; - u32 dfp_type; + bool dsp_present; + enum downstream_port_type dsp_type; bool format_conversion; bool detailed_cap_info_available; /* Byte 02207h */ - u32 dfp_count; + u32 dsp_count; bool msa_timing_par_ignored; bool oui_support; }; @@ -1139,6 +1163,12 @@ static inline void mdss_dp_reset_frame_crc_data(struct mdss_dp_crc_data *crc) crc->en = false; } +static inline bool mdss_dp_is_dsp_type_vga(struct mdss_dp_drv_pdata *dp) +{ + return (dp->dpcd.downstream_port.dsp_present && + (dp->dpcd.downstream_port.dsp_type == DSP_TYPE_VGA)); +} + void mdss_dp_phy_initialize(struct mdss_dp_drv_pdata *dp); int mdss_dp_dpcd_cap_read(struct mdss_dp_drv_pdata *dp); diff --git a/drivers/video/fbdev/msm/mdss_dp_aux.c b/drivers/video/fbdev/msm/mdss_dp_aux.c index 37209c161366..23a63121b78c 100644 --- a/drivers/video/fbdev/msm/mdss_dp_aux.c +++ b/drivers/video/fbdev/msm/mdss_dp_aux.c @@ -633,7 +633,8 @@ void dp_extract_edid_video_support(struct edp_edid *edid, char *buf) pr_debug("Digital Video intf=%d color_depth=%d\n", edid->video_intf, edid->color_depth); } else { - pr_err("Error, Analog video interface\n"); + pr_debug("Analog video interface, set color depth to 8\n"); + edid->color_depth = DP_TEST_BIT_DEPTH_8; } }; @@ -1140,13 +1141,13 @@ int mdss_dp_dpcd_cap_read(struct mdss_dp_drv_pdata *ep) pr_debug("rx_ports=%d", cap->num_rx_port); data = *bp++; /* Byte 5: DOWN_STREAM_PORT_PRESENT */ - cap->downstream_port.dfp_present = data & BIT(0); - cap->downstream_port.dfp_type = data & 0x6; + cap->downstream_port.dsp_present = data & BIT(0); + cap->downstream_port.dsp_type = (data & 0x6) >> 1; cap->downstream_port.format_conversion = data & BIT(3); cap->downstream_port.detailed_cap_info_available = data & BIT(4); - pr_debug("dfp_present = %d, dfp_type = %d\n", - cap->downstream_port.dfp_present, - cap->downstream_port.dfp_type); + pr_debug("dsp_present = %d, dsp_type = %d\n", + cap->downstream_port.dsp_present, + cap->downstream_port.dsp_type); pr_debug("format_conversion = %d, detailed_cap_info_available = %d\n", cap->downstream_port.format_conversion, cap->downstream_port.detailed_cap_info_available); @@ -1154,16 +1155,16 @@ int mdss_dp_dpcd_cap_read(struct mdss_dp_drv_pdata *ep) bp += 1; /* Skip Byte 6 */ data = *bp++; /* Byte 7: DOWN_STREAM_PORT_COUNT */ - cap->downstream_port.dfp_count = data & 0x7; - if (cap->downstream_port.dfp_count > DP_MAX_DS_PORT_COUNT) { + cap->downstream_port.dsp_count = data & 0x7; + if (cap->downstream_port.dsp_count > DP_MAX_DS_PORT_COUNT) { pr_debug("DS port count %d greater that max (%d) supported\n", - cap->downstream_port.dfp_count, DP_MAX_DS_PORT_COUNT); - cap->downstream_port.dfp_count = DP_MAX_DS_PORT_COUNT; + cap->downstream_port.dsp_count, DP_MAX_DS_PORT_COUNT); + cap->downstream_port.dsp_count = DP_MAX_DS_PORT_COUNT; } cap->downstream_port.msa_timing_par_ignored = data & BIT(6); cap->downstream_port.oui_support = data & BIT(7); - pr_debug("dfp_count = %d, msa_timing_par_ignored = %d\n", - cap->downstream_port.dfp_count, + pr_debug("dsp_count = %d, msa_timing_par_ignored = %d\n", + cap->downstream_port.dsp_count, cap->downstream_port.msa_timing_par_ignored); pr_debug("oui_support = %d\n", cap->downstream_port.oui_support); diff --git a/drivers/video/fbdev/msm/mdss_dp_util.c b/drivers/video/fbdev/msm/mdss_dp_util.c index e8c3fe9f4957..f7b3d4664e86 100644 --- a/drivers/video/fbdev/msm/mdss_dp_util.c +++ b/drivers/video/fbdev/msm/mdss_dp_util.c @@ -786,19 +786,56 @@ 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_config_msa(struct dss_io_data *ctrl_io, - char lrate, struct dss_io_data *dp_cc_io) +static bool use_fixed_nvid(struct mdss_dp_drv_pdata *dp) +{ + /* + * For better interop experience, used a fixed NVID=0x8000 + * whenever connected to a VGA dongle downstream + */ + return mdss_dp_is_dsp_type_vga(dp); +} + +void mdss_dp_sw_config_msa(struct mdss_dp_drv_pdata *dp) { 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); + u64 mvid_calc; + u32 const nvid_fixed = 0x8000; + struct dss_io_data *ctrl_io = &dp->ctrl_io; + struct dss_io_data *dp_cc_io = &dp->dp_cc_io; + u32 lrate_kbps; + u64 stream_rate_khz; + + if (use_fixed_nvid(dp)) { + pr_debug("use fixed NVID=0x%x\n", nvid_fixed); + nvid = nvid_fixed; + + lrate_kbps = dp->link_rate * DP_LINK_RATE_MULTIPLIER / + DP_KHZ_TO_HZ; + stream_rate_khz = div_u64(dp->panel_data.panel_info.clk_rate, + DP_KHZ_TO_HZ); + pr_debug("link rate=%dkbps, stream_rate_khz=%lluKhz", + lrate_kbps, stream_rate_khz); + + /* + * For intermediate results, use 64 bit arithmetic to avoid + * loss of precision. + */ + mvid_calc = stream_rate_khz * nvid; + mvid_calc = div_u64(mvid_calc, lrate_kbps); + + /* + * truncate back to 32 bits as this final divided value will + * always be within the range of a 32 bit unsigned int. + */ + mvid = (u32) mvid_calc; + } else { + 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); + } pr_debug("mvid=0x%x, nvid=0x%x\n", mvid, nvid); writel_relaxed(mvid, ctrl_io->base + DP_SOFTWARE_MVID); diff --git a/drivers/video/fbdev/msm/mdss_dp_util.h b/drivers/video/fbdev/msm/mdss_dp_util.h index 4c93e48e97dc..4970f5bc3a47 100644 --- a/drivers/video/fbdev/msm/mdss_dp_util.h +++ b/drivers/video/fbdev/msm/mdss_dp_util.h @@ -316,8 +316,7 @@ 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_config_msa(struct dss_io_data *ctrl_io, - char lrate, struct dss_io_data *dp_cc_io); +void mdss_dp_sw_config_msa(struct mdss_dp_drv_pdata *dp); 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); |
