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

Commit fdcee0ef authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "mdss: display-port: add support for edid read"

parents adc801c2 b62bc857
Loading
Loading
Loading
Loading
+19 −50
Original line number Diff line number Diff line
@@ -42,43 +42,6 @@
#define VDDA_UA_ON_LOAD		100000	/* uA units */
#define VDDA_UA_OFF_LOAD	100		/* uA units */

static char edid_buf1[] = {
	0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
	0x22, 0xf0, 0x52, 0x29, 0x01, 0x01, 0x01, 0x01,
	0x16, 0x16, 0x01, 0x03, 0x80, 0x30, 0x1b, 0x78,
	0x2e, 0xee, 0x95, 0xa3, 0x54, 0x4c, 0x99, 0x26,
	0x0f, 0x50, 0x54, 0xa1, 0x08, 0x00, 0xd1, 0xc0,
	0x81, 0xc0, 0xa9, 0xc0, 0xb3, 0x00, 0x95, 0x00,
	0x81, 0x40, 0x81, 0x80, 0x01, 0x01, 0x02, 0x3a,
	0x80, 0x18, 0x71, 0x38, 0x2d, 0x40, 0x58, 0x2c,
	0x45, 0x00, 0xdb, 0x0b, 0x11, 0x00, 0x00, 0x1e,
	0x00, 0x00, 0x00, 0xfd, 0x00, 0x32, 0x4c, 0x18,
	0x5e, 0x11, 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20,
	0x20, 0x20, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x48,
	0x50, 0x20, 0x5a, 0x52, 0x32, 0x32, 0x34, 0x30,
	0x77, 0x0a, 0x20, 0x20, 0x00, 0x00, 0x00, 0xff,
	0x00, 0x43, 0x4e, 0x34, 0x32, 0x32, 0x32, 0x30,
	0x30, 0x33, 0x46, 0x0a, 0x20, 0x20, 0x01, 0xb1,

	0x02, 0x03, 0x17, 0xb1, 0x4c, 0x90, 0x1f, 0x05,
	0x14, 0x04, 0x13, 0x03, 0x02, 0x07, 0x06, 0x12,
	0x01, 0x65, 0x03, 0x0c, 0x00, 0x10, 0x00, 0x02,
	0x3a, 0x80, 0x18, 0x71, 0x38, 0x2d, 0x40, 0x58,
	0x2c, 0x45, 0x00, 0xdb, 0x0b, 0x11, 0x00, 0x00,
	0x1e, 0x02, 0x3a, 0x80, 0xd0, 0x72, 0x38, 0x2d,
	0x40, 0x10, 0x2c, 0x45, 0x80, 0xdb, 0x0b, 0x11,
	0x00, 0x00, 0x1e, 0x01, 0x1d, 0x00, 0x72, 0x51,
	0xd0, 0x1e, 0x20, 0x6e, 0x28, 0x55, 0x00, 0xdb,
	0x0b, 0x11, 0x00, 0x00, 0x1e, 0x01, 0x1d, 0x00,
	0xbc, 0x52, 0xd0, 0x1e, 0x20, 0xb8, 0x28, 0x55,
	0x40, 0xdb, 0x0b, 0x11, 0x00, 0x00, 0x1e, 0x8c,
	0x0a, 0xd0, 0x8a, 0x20, 0xe0, 0x2d, 0x10, 0x10,
	0x3e, 0x96, 0x00, 0xdb, 0x0b, 0x11, 0x00, 0x00,
	0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b
};


static void mdss_dp_put_dt_clk_data(struct device *dev,
	struct dss_module_power *module_power)
{
@@ -945,9 +908,6 @@ int mdss_dp_on(struct mdss_panel_data *pdata)
			pr_err("Unabled to start core clocks\n");
			return ret;
		}
		mdss_dp_phy_reset(&dp_drv->ctrl_io);
		mdss_dp_aux_reset(&dp_drv->ctrl_io);
		mdss_dp_aux_ctrl(&dp_drv->ctrl_io, true);
		mdss_dp_hpd_configure(&dp_drv->ctrl_io, true);

		orientation = usbpd_get_plug_orientation(dp_drv->pd);
@@ -971,11 +931,6 @@ int mdss_dp_on(struct mdss_panel_data *pdata)
		if (dp_drv->new_vic && (dp_drv->new_vic != dp_drv->vic))
			dp_init_panel_info(dp_drv, dp_drv->new_vic);

		mdss_dp_phy_aux_setup(&dp_drv->phy_io);

		mdss_dp_irq_enable(dp_drv);
		pr_debug("irq enabled\n");
		mdss_dp_dpcd_cap_read(dp_drv);
		dp_drv->link_rate =
			mdss_dp_gen_link_clk(&dp_drv->panel_data.panel_info,
						dp_drv->dpcd.max_lane_count);
@@ -1143,9 +1098,10 @@ static int mdss_dp_edid_init(struct mdss_panel_data *pdata)
		return -ENODEV;
	}

	/* Use the existing EDID buffer for 1080p */
	memcpy(edid_init_data.buf, edid_buf1, sizeof(edid_buf1));
	dp_drv->panel_data.panel_info.edid_data = edid_data;
	/* initialize EDID buffer pointers */
	dp_drv->edid_buf = edid_init_data.buf;
	dp_drv->edid_buf_size = edid_init_data.buf_size;

	return 0;
}
@@ -1189,17 +1145,30 @@ static int mdss_dp_host_init(struct mdss_panel_data *pdata)
	       mdss_dp_get_ctrl_hw_version(&dp_drv->ctrl_io),
	       mdss_dp_get_phy_hw_version(&dp_drv->phy_io));

	mdss_dp_phy_aux_setup(&dp_drv->phy_io);

	mdss_dp_irq_enable(dp_drv);
	pr_debug("irq enabled\n");
	mdss_dp_dpcd_cap_read(dp_drv);

	ret = mdss_dp_edid_read(dp_drv);
	if (ret)
		goto edid_error;

	pr_debug("edid_read success. buf_size=%d\n",
				dp_drv->edid_buf_size);

	ret = hdmi_edid_parser(dp_drv->panel_data.panel_info.edid_data);
	if (ret) {
		DEV_ERR("%s: edid parse failed\n", __func__);
		goto edid_parser_error;
		goto edid_error;
	}

	mdss_dp_send_cable_notification(dp_drv, true);

	return ret;

edid_parser_error:
edid_error:
	mdss_dp_clk_ctrl(dp_drv, DP_CORE_PM, false);
clk_error:
	mdss_dp_regulator_ctrl(dp_drv, false);
@@ -1422,7 +1391,7 @@ static void mdss_dp_event_work(struct work_struct *work)

	switch (todo) {
	case EV_EDID_READ:
		mdss_dp_edid_read(dp, 0);
		mdss_dp_edid_read(dp);
		break;
	case EV_DPCD_CAP_READ:
		mdss_dp_dpcd_cap_read(dp);
+3 −1
Original line number Diff line number Diff line
@@ -378,6 +378,8 @@ struct mdss_dp_drv_pdata {
	char train_link_rate;	/* X 27000000 for real rate */
	char train_lane_cnt;

	u8 *edid_buf;
	u32 edid_buf_size;
	struct edp_edid edid;
	struct dpcd_cap dpcd;

@@ -464,7 +466,7 @@ void mdss_dp_phy_initialize(struct mdss_dp_drv_pdata *dp);

void mdss_dp_dpcd_cap_read(struct mdss_dp_drv_pdata *dp);
int mdss_dp_dpcd_status_read(struct mdss_dp_drv_pdata *dp);
void mdss_dp_edid_read(struct mdss_dp_drv_pdata *dp, int block);
int mdss_dp_edid_read(struct mdss_dp_drv_pdata *dp);
int mdss_dp_link_train(struct mdss_dp_drv_pdata *dp);
void dp_aux_i2c_handler(struct mdss_dp_drv_pdata *dp, u32 isr);
void dp_aux_native_handler(struct mdss_dp_drv_pdata *dp, u32 isr);
+58 −21
Original line number Diff line number Diff line
@@ -665,7 +665,7 @@ static int dp_aux_chan_ready(struct mdss_dp_drv_pdata *ep)
	char data = 0;

	for (cnt = 5; cnt; cnt--) {
		ret = dp_aux_write_buf(ep, 0x50, &data, 1, 1);
		ret = dp_aux_write_buf(ep, EDID_START_ADDRESS, &data, 1, 1);
		pr_debug("ret=%d\n", ret);
		if (ret >= 0)
			break;
@@ -680,43 +680,85 @@ static int dp_aux_chan_ready(struct mdss_dp_drv_pdata *ep)
	return 0;
}

static int dp_sink_edid_read(struct mdss_dp_drv_pdata *ep, int block)
int mdss_dp_edid_read(struct mdss_dp_drv_pdata *dp)
{
	struct edp_buf *rp;
	int cnt, rlen;
	int ret = 0;
	int blk_num = 0;

	ret = dp_aux_chan_ready(ep);
	ret = dp_aux_chan_ready(dp);
	if (ret) {
		pr_err("aux chan NOT ready\n");
		return ret;
	}

	for (cnt = 5; cnt; cnt--) {
		rlen = dp_aux_read_buf(ep, 0x50, 128, 1);
		rlen = dp_aux_read_buf
			(dp, EDID_START_ADDRESS, EDID_BLOCK_SIZE, 1);
		if (rlen > 0) {
			pr_debug("rlen=%d\n", rlen);
			pr_debug("cnt=%d, block=%d, rlen=%d\n",
					cnt, blk_num, rlen);

			rp = &ep->rxp;
			rp = &dp->rxp;
			if (!dp_edid_buf_error(rp->data, rp->len))
				break;
		}
	}

	if (cnt <= 0) {
		pr_err("Failed\n");
	if ((cnt <= 0) && (rlen != EDID_BLOCK_SIZE)) {
		pr_err("Read failed. rlen=%d\n", rlen);
		return -EINVAL;
	}

	dp_extract_edid_manufacturer(&ep->edid, rp->data);
	dp_extract_edid_product(&ep->edid, rp->data);
	dp_extract_edid_version(&ep->edid, rp->data);
	dp_extract_edid_ext_block_cnt(&ep->edid, rp->data);
	dp_extract_edid_video_support(&ep->edid, rp->data);
	dp_extract_edid_feature(&ep->edid, rp->data);
	dp_extract_edid_detailed_timing_description(&ep->edid, rp->data);
	rp = &dp->rxp;

	dp_extract_edid_manufacturer(&dp->edid, rp->data);
	dp_extract_edid_product(&dp->edid, rp->data);
	dp_extract_edid_version(&dp->edid, rp->data);
	dp_extract_edid_ext_block_cnt(&dp->edid, rp->data);
	dp_extract_edid_video_support(&dp->edid, rp->data);
	dp_extract_edid_feature(&dp->edid, rp->data);
	dp_extract_edid_detailed_timing_description(&dp->edid, rp->data);
	/* for the first block initialize the edid buffer size */
	dp->edid_buf_size = 0;

	pr_debug("edid extension = %d\n",
			dp->edid.ext_block_cnt);

	memcpy(dp->edid_buf, rp->data, EDID_BLOCK_SIZE);
	dp->edid_buf_size += EDID_BLOCK_SIZE;

	return 128;
	if (!dp->edid.ext_block_cnt)
		return 0;

	for (blk_num = 1; blk_num <= dp->edid.ext_block_cnt;
			blk_num++) {
		for (cnt = 5; cnt; cnt--) {
			rlen = dp_aux_read_buf
				(dp, EDID_START_ADDRESS +
				 (blk_num * EDID_BLOCK_SIZE),
				 EDID_BLOCK_SIZE, 1);
			if (rlen > 0) {
				pr_debug("cnt=%d, blk_num=%d, rlen=%d\n",
						cnt, blk_num, rlen);
				rp = &dp->rxp;
				if (!dp_edid_buf_error(rp->data, rp->len))
					break;
			}
		}

		if ((cnt <= 0) && (rlen != EDID_BLOCK_SIZE)) {
			pr_err("Read failed. rlen=%d\n", rlen);
			return -EINVAL;
		}

		memcpy(dp->edid_buf + (blk_num * EDID_BLOCK_SIZE),
					rp->data, EDID_BLOCK_SIZE);
		dp->edid_buf_size += EDID_BLOCK_SIZE;
	}

	return 0;
}

static void dp_sink_capability_read(struct mdss_dp_drv_pdata *ep,
@@ -1357,11 +1399,6 @@ void mdss_dp_fill_link_cfg(struct mdss_dp_drv_pdata *ep)

}

void mdss_dp_edid_read(struct mdss_dp_drv_pdata *ep, int block)
{
	dp_sink_edid_read(ep, block);
}

int mdss_dp_link_train(struct mdss_dp_drv_pdata *ep)
{
	int ret;
+1 −0
Original line number Diff line number Diff line
@@ -86,6 +86,7 @@
#define TXn_TX_DRV_LVL				0x001C

#define TCSR_USB3_DP_PHYMODE			0x48
#define EDID_START_ADDRESS			0x50

struct lane_mapping {
	char lane0;
+15 −9
Original line number Diff line number Diff line
@@ -360,10 +360,13 @@ static int msm_ext_disp_hpd(struct platform_device *pdev,
		ext_disp->current_disp = data->type;
	} else if ((state == EXT_DISPLAY_CABLE_DISCONNECT) &&
			!ext_disp->ack_enabled) {
		if (ext_disp->ops) {
			ext_disp->ops->audio_info_setup = NULL;
			ext_disp->ops->get_audio_edid_blk = NULL;
			ext_disp->ops->cable_status = NULL;
			ext_disp->ops->get_intf_id = NULL;
		}

		ext_disp->current_disp = EXT_DISPLAY_TYPE_MAX;
	}

@@ -451,7 +454,7 @@ static int msm_ext_disp_notify(struct platform_device *pdev,
	if (ret)
		goto end;

	if (new_state == EXT_DISPLAY_CABLE_CONNECT) {
	if (new_state == EXT_DISPLAY_CABLE_CONNECT && ext_disp->ops) {
		ext_disp->ops->audio_info_setup =
			data->codec_ops.audio_info_setup;
		ext_disp->ops->get_audio_edid_blk =
@@ -524,10 +527,13 @@ static int msm_ext_disp_audio_ack(struct platform_device *pdev, u32 ack)
	 * empty.
	 */
	if (!ack_hpd) {
		if (ext_disp->ops) {
			ext_disp->ops->audio_info_setup = NULL;
			ext_disp->ops->get_audio_edid_blk = NULL;
			ext_disp->ops->cable_status = NULL;
			ext_disp->ops->get_intf_id = NULL;
		}

		ext_disp->current_disp = EXT_DISPLAY_TYPE_MAX;
	}