summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/video/fbdev/msm/mdss_dp.c19
-rw-r--r--drivers/video/fbdev/msm/mdss_dp_aux.c20
-rw-r--r--drivers/video/fbdev/msm/mdss_dp_util.c44
-rw-r--r--drivers/video/fbdev/msm/mdss_dp_util.h56
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);