Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 76f4f7c5 authored by Chandan Uddaraju's avatar Chandan Uddaraju
Browse files

mdss: DisplayPort: add support for multiple resolutions



Add table to store transfer unit settings for different
resolutions. The table is used for mapping the resolution
with the lane count and Display-port link rate.

Change-Id: I93cc489cdbde21680f8c05311be60ecba053c1db
Signed-off-by: default avatarChandan Uddaraju <chandanu@codeaurora.org>
parent 36d28227
Loading
Loading
Loading
Loading
+16 −3
Original line number Diff line number Diff line
@@ -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;
+15 −5
Original line number Diff line number Diff line
@@ -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");
	}
+39 −5
Original line number Diff line number Diff line
@@ -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,
+55 −1
Original line number Diff line number Diff line
@@ -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);