diff options
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_dp.c | 19 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_dp_aux.c | 20 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_dp_util.c | 44 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_dp_util.h | 56 |
4 files changed, 125 insertions, 14 deletions
diff --git a/drivers/video/fbdev/msm/mdss_dp.c b/drivers/video/fbdev/msm/mdss_dp.c index 42334941f809..72b262e8171a 100644 --- a/drivers/video/fbdev/msm/mdss_dp.c +++ b/drivers/video/fbdev/msm/mdss_dp.c @@ -45,6 +45,18 @@ #define VDDA_UA_ON_LOAD 100000 /* uA units */ #define VDDA_UA_OFF_LOAD 100 /* uA units */ +#define DEFAULT_VIDEO_RESOLUTION HDMI_VFRMT_640x480p60_4_3 +static u32 supported_modes[] = { + HDMI_VFRMT_640x480p60_4_3, + HDMI_VFRMT_720x480p60_4_3, HDMI_VFRMT_720x480p60_16_9, + HDMI_VFRMT_1280x720p60_16_9, + HDMI_VFRMT_1920x1080p60_16_9, + HDMI_VFRMT_3840x2160p24_16_9, HDMI_VFRMT_3840x2160p30_16_9, + HDMI_VFRMT_3840x2160p60_16_9, + HDMI_VFRMT_4096x2160p24_256_135, HDMI_VFRMT_4096x2160p30_256_135, + HDMI_VFRMT_4096x2160p60_256_135, HDMI_EVFRMT_4096x2160p24_16_9 +}; + static void mdss_dp_put_dt_clk_data(struct device *dev, struct dss_module_power *module_power) { @@ -968,8 +980,6 @@ end: return ret; } -#define DEFAULT_VIDEO_RESOLUTION HDMI_VFRMT_640x480p60_4_3 - static int dp_init_panel_info(struct mdss_dp_drv_pdata *dp_drv, u32 vic) { struct mdss_panel_info *pinfo; @@ -981,7 +991,6 @@ static int dp_init_panel_info(struct mdss_dp_drv_pdata *dp_drv, u32 vic) return -EINVAL; } - dp_drv->ds_data.ds_registered = false; ret = hdmi_get_supported_mode(&timing, &dp_drv->ds_data, vic); pinfo = &dp_drv->panel_data.panel_info; @@ -1251,6 +1260,10 @@ static int mdss_dp_edid_init(struct mdss_panel_data *pdata) dp_drv = container_of(pdata, struct mdss_dp_drv_pdata, panel_data); + dp_drv->ds_data.ds_registered = true; + dp_drv->ds_data.modes_num = ARRAY_SIZE(supported_modes); + dp_drv->ds_data.modes = supported_modes; + dp_drv->max_pclk_khz = DP_MAX_PIXEL_CLK_KHZ; edid_init_data.kobj = dp_drv->kobj; edid_init_data.ds_data = dp_drv->ds_data; diff --git a/drivers/video/fbdev/msm/mdss_dp_aux.c b/drivers/video/fbdev/msm/mdss_dp_aux.c index 136dbb13cc62..27e982437961 100644 --- a/drivers/video/fbdev/msm/mdss_dp_aux.c +++ b/drivers/video/fbdev/msm/mdss_dp_aux.c @@ -510,11 +510,20 @@ char mdss_dp_gen_link_clk(struct mdss_panel_info *pinfo, char lane_cnt) pr_debug("clk_rate=%llu, bpp= %d, lane_cnt=%d\n", pinfo->clk_rate, pinfo->bpp, lane_cnt); - min_link_rate = (u32)div_u64((pinfo->clk_rate * 10), - (lane_cnt * encoding_factx10)); - min_link_rate = (min_link_rate * pinfo->bpp) - / (DP_LINK_RATE_MULTIPLIER); + + /* + * The max pixel clock supported is 675Mhz. The + * current calculations below will make sure + * the min_link_rate is within 32 bit limits. + * Any changes in the section of code should + * consider this limitation. + */ + min_link_rate = pinfo->clk_rate + / (lane_cnt * encoding_factx10); min_link_rate /= ln_to_link_ratio; + min_link_rate = (min_link_rate * pinfo->bpp); + min_link_rate = (u32)div_u64(min_link_rate * 10, + DP_LINK_RATE_MULTIPLIER); pr_debug("min_link_rate = %d\n", min_link_rate); @@ -1375,7 +1384,8 @@ train_start: clear: dp_clear_training_pattern(dp); if (ret != -1) { - mdss_dp_setup_tr_unit(&dp->ctrl_io); + 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); pr_debug("State_ctrl set to SEND_VIDEO\n"); } diff --git a/drivers/video/fbdev/msm/mdss_dp_util.c b/drivers/video/fbdev/msm/mdss_dp_util.c index f6f2b54c2d80..f1245a024a88 100644 --- a/drivers/video/fbdev/msm/mdss_dp_util.c +++ b/drivers/video/fbdev/msm/mdss_dp_util.c @@ -296,13 +296,47 @@ void mdss_dp_sw_mvid_nvid(struct dss_io_data *ctrl_io) writel_relaxed(0x3c, ctrl_io->base + DP_SOFTWARE_NVID); } -void mdss_dp_setup_tr_unit(struct dss_io_data *ctrl_io) +void mdss_dp_setup_tr_unit(struct dss_io_data *ctrl_io, u8 link_rate, + u8 ln_cnt, u32 res) { - /* Current Tr unit configuration supports only 1080p */ + u32 dp_tu = 0x0; + u32 valid_boundary = 0x0; + u32 valid_boundary2 = 0x0; + struct dp_vc_tu_mapping_table const *tu_entry = tu_table; + writel_relaxed(0x21, ctrl_io->base + DP_MISC1_MISC0); - writel_relaxed(0x0f0016, ctrl_io->base + DP_VALID_BOUNDARY); - writel_relaxed(0x1f, ctrl_io->base + DP_TU); - writel_relaxed(0x0, ctrl_io->base + DP_VALID_BOUNDARY_2); + + for (; tu_entry != tu_table + ARRAY_SIZE(tu_table); ++tu_entry) { + if ((tu_entry->vic == res) && + (tu_entry->lanes == ln_cnt) && + (tu_entry->lrate == link_rate)) + break; + } + + if (tu_entry == tu_table + ARRAY_SIZE(tu_table)) { + pr_err("requested ln_cnt=%d, lrate=0x%x not supported\n", + ln_cnt, link_rate); + return; + } + + dp_tu |= tu_entry->tu_size_minus1; + valid_boundary |= tu_entry->valid_boundary_link; + valid_boundary |= (tu_entry->delay_start_link << 16); + + valid_boundary2 |= (tu_entry->valid_lower_boundary_link << 1); + valid_boundary2 |= (tu_entry->upper_boundary_count << 16); + valid_boundary2 |= (tu_entry->lower_boundary_count << 20); + + if (tu_entry->boundary_moderation_en) + valid_boundary2 |= BIT(0); + + writel_relaxed(valid_boundary, ctrl_io->base + DP_VALID_BOUNDARY); + writel_relaxed(dp_tu, ctrl_io->base + DP_TU); + writel_relaxed(valid_boundary2, ctrl_io->base + DP_VALID_BOUNDARY_2); + + pr_debug("valid_boundary=0x%x, valid_boundary2=0x%x\n", + valid_boundary, valid_boundary2); + pr_debug("dp_tu=0x%x\n", dp_tu); } void mdss_dp_ctrl_lane_mapping(struct dss_io_data *ctrl_io, diff --git a/drivers/video/fbdev/msm/mdss_dp_util.h b/drivers/video/fbdev/msm/mdss_dp_util.h index 80dedba33ec5..cf2286f9b58a 100644 --- a/drivers/video/fbdev/msm/mdss_dp_util.h +++ b/drivers/video/fbdev/msm/mdss_dp_util.h @@ -202,6 +202,59 @@ struct edp_cmd { char next; /* next command */ }; +struct dp_vc_tu_mapping_table { + u32 vic; + u8 lanes; + u8 lrate; /* DP_LINK_RATE -> 162(6), 270(10), 540(20) */ + u8 bpp; + u8 valid_boundary_link; + u16 delay_start_link; + bool boundary_moderation_en; + u8 valid_lower_boundary_link; + u8 upper_boundary_count; + u8 lower_boundary_count; + u8 tu_size_minus1; +}; + +static const struct dp_vc_tu_mapping_table tu_table[] = { + {HDMI_VFRMT_640x480p60_4_3, 4, 06, 24, + 0x07, 0x0056, false, 0x00, 0x00, 0x00, 0x3b}, + {HDMI_VFRMT_640x480p60_4_3, 2, 06, 24, + 0x0e, 0x004f, false, 0x00, 0x00, 0x00, 0x3b}, + {HDMI_VFRMT_640x480p60_4_3, 1, 06, 24, + 0x15, 0x0039, false, 0x00, 0x00, 0x00, 0x2c}, + {HDMI_VFRMT_720x480p60_4_3, 1, 06, 24, + 0x13, 0x0038, true, 0x12, 0x0c, 0x0b, 0x24}, + {HDMI_VFRMT_720x480p60_16_9, 1, 06, 24, + 0x13, 0x0038, true, 0x12, 0x0c, 0x0b, 0x24}, + {HDMI_VFRMT_1280x720p60_16_9, 4, 06, 24, + 0x0c, 0x0020, false, 0x00, 0x00, 0x00, 0x1f}, + {HDMI_VFRMT_1280x720p60_16_9, 2, 06, 24, + 0x16, 0x0015, false, 0x00, 0x00, 0x00, 0x1f}, + {HDMI_VFRMT_1280x720p60_16_9, 1, 10, 24, + 0x21, 0x001a, false, 0x00, 0x00, 0x00, 0x27}, + {HDMI_VFRMT_1920x1080p60_16_9, 4, 06, 24, + 0x16, 0x000f, false, 0x00, 0x00, 0x00, 0x1f}, + {HDMI_VFRMT_1920x1080p60_16_9, 2, 10, 24, + 0x21, 0x0011, false, 0x00, 0x00, 0x00, 0x27}, + {HDMI_VFRMT_1920x1080p60_16_9, 1, 20, 24, + 0x21, 0x001a, false, 0x00, 0x00, 0x00, 0x27}, + {HDMI_VFRMT_3840x2160p24_16_9, 4, 10, 24, + 0x21, 0x000c, false, 0x00, 0x00, 0x00, 0x27}, + {HDMI_VFRMT_3840x2160p30_16_9, 4, 10, 24, + 0x21, 0x000c, false, 0x00, 0x00, 0x00, 0x27}, + {HDMI_VFRMT_3840x2160p60_16_9, 4, 20, 24, + 0x21, 0x000c, false, 0x00, 0x00, 0x00, 0x27}, + {HDMI_VFRMT_4096x2160p24_256_135, 4, 10, 24, + 0x21, 0x000c, false, 0x00, 0x00, 0x00, 0x27}, + {HDMI_VFRMT_4096x2160p30_256_135, 4, 10, 24, + 0x21, 0x000c, false, 0x00, 0x00, 0x00, 0x27}, + {HDMI_VFRMT_4096x2160p60_256_135, 4, 20, 24, + 0x21, 0x000c, false, 0x00, 0x00, 0x00, 0x27}, + {HDMI_EVFRMT_4096x2160p24_16_9, 4, 10, 24, + 0x21, 0x000c, false, 0x00, 0x00, 0x00, 0x27}, +}; + int dp_aux_read(void *ep, struct edp_cmd *cmds); int dp_aux_write(void *ep, struct edp_cmd *cmd); void mdss_dp_state_ctrl(struct dss_io_data *ctrl_io, u32 data); @@ -213,7 +266,8 @@ void mdss_dp_mainlink_reset(struct dss_io_data *ctrl_io); void mdss_dp_phy_reset(struct dss_io_data *ctrl_io); 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); +void mdss_dp_setup_tr_unit(struct dss_io_data *ctrl_io, u8 link_rate, + u8 ln_cnt, u32 res); 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); |
