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

Commit a7375eee authored by Sankeerth Billakanti's avatar Sankeerth Billakanti
Browse files

drm/msm/dp: minidp hpd through tlmm and dp tx controller



The minidp hpd through the tlmm is not detecting the
HPD_IRQ and disconnect interrupts accurately. This is
causing some of the DP CTS cases to fail.

These changes shall detect the connect pulse through
the tlmm gpio controller interrupt and the HPD_IRQ &
disconnect pulse through the DP tx controller interrupt.

Change-Id: I5d1a77d59bb7d7d8f92ab6a7521063dc5fd34323
Signed-off-by: default avatarSankeerth Billakanti <sbillaka@codeaurora.org>
parent c30fb660
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ msm_drm-y := \
	dp/dp_debug.o \
	dp/dp_hpd.o \
	dp/dp_gpio_hpd.o \
	dp/dp_lphw_hpd.o \
	dp/dp_display.o \
	dp/dp_drm.o \
	dp/dp_hdcp2p2.o \
+66 −32
Original line number Diff line number Diff line
@@ -1311,37 +1311,6 @@ static void dp_catalog_ctrl_enable_irq(struct dp_catalog_ctrl *ctrl,
	}
}

static void dp_catalog_ctrl_hpd_config(struct dp_catalog_ctrl *ctrl, bool en)
{
	struct dp_catalog_private *catalog;
	struct dp_io_data *io_data;

	if (!ctrl) {
		pr_err("invalid input\n");
		return;
	}

	catalog = dp_catalog_get_priv(ctrl);
	io_data = catalog->io.dp_aux;

	if (en) {
		u32 reftimer = dp_read(catalog->exe_mode, io_data,
						DP_DP_HPD_REFTIMER);

		dp_write(catalog->exe_mode, io_data, DP_DP_HPD_INT_ACK, 0xF);
		dp_write(catalog->exe_mode, io_data, DP_DP_HPD_INT_MASK, 0xF);
		/* Enabling REFTIMER */
		reftimer |= BIT(16);
		dp_write(catalog->exe_mode, io_data, DP_DP_HPD_REFTIMER,
				reftimer);
		/* Enable HPD */
		dp_write(catalog->exe_mode, io_data, DP_DP_HPD_CTRL, 0x1);
	} else {
		/*Disable HPD */
		dp_write(catalog->exe_mode, io_data, DP_DP_HPD_CTRL, 0x0);
	}
}

static void dp_catalog_ctrl_get_interrupt(struct dp_catalog_ctrl *ctrl)
{
	u32 ack = 0;
@@ -1954,6 +1923,67 @@ static int dp_catalog_panel_timing_cfg(struct dp_catalog_panel *panel)
	return 0;
}

static void dp_catalog_hpd_config_hpd(struct dp_catalog_hpd *hpd, bool en)
{
	struct dp_catalog_private *catalog;
	struct dp_io_data *io_data;

	if (!hpd) {
		pr_err("invalid input\n");
		return;
	}

	catalog = dp_catalog_get_priv(hpd);
	io_data = catalog->io.dp_aux;

	if (en) {
		u32 reftimer = dp_read(catalog->exe_mode, io_data,
						DP_DP_HPD_REFTIMER);

		/* Arm only the UNPLUG and HPD_IRQ interrupts */
		dp_write(catalog->exe_mode, io_data, DP_DP_HPD_INT_ACK, 0xF);
		dp_write(catalog->exe_mode, io_data, DP_DP_HPD_INT_MASK, 0xA);

		/* Enable REFTIMER to count 1ms */
		reftimer |= BIT(16);
		dp_write(catalog->exe_mode, io_data, DP_DP_HPD_REFTIMER,
				reftimer);

		 /* Connect_time is 250us & disconnect_time is 2ms */
		dp_write(catalog->exe_mode, io_data, DP_DP_HPD_EVENT_TIME_0,
				0x3E800FA);
		dp_write(catalog->exe_mode, io_data, DP_DP_HPD_EVENT_TIME_1,
				0x1F407D0);

		/* Enable HPD */
		dp_write(catalog->exe_mode, io_data, DP_DP_HPD_CTRL, 0x1);

	} else {
		/* Disable HPD */
		dp_write(catalog->exe_mode, io_data, DP_DP_HPD_CTRL, 0x0);
	}
}

static u32 dp_catalog_hpd_get_interrupt(struct dp_catalog_hpd *hpd)
{
	u32 isr = 0;
	struct dp_catalog_private *catalog;
	struct dp_io_data *io_data;

	if (!hpd) {
		pr_err("invalid input\n");
		return isr;
	}

	catalog = dp_catalog_get_priv(hpd);

	io_data = catalog->io.dp_aux;
	isr = dp_read(catalog->exe_mode, io_data, DP_DP_HPD_INT_STATUS);
	dp_write(catalog->exe_mode, io_data, DP_DP_HPD_INT_ACK, (isr & 0xf));

	return isr;
}

static void dp_catalog_audio_init(struct dp_catalog_audio *audio)
{
	struct dp_catalog_private *catalog;
@@ -2417,7 +2447,6 @@ struct dp_catalog *dp_catalog_get(struct device *dev, struct dp_parser *parser)
		.usb_reset      = dp_catalog_ctrl_usb_reset,
		.mainlink_ready = dp_catalog_ctrl_mainlink_ready,
		.enable_irq     = dp_catalog_ctrl_enable_irq,
		.hpd_config     = dp_catalog_ctrl_hpd_config,
		.phy_reset      = dp_catalog_ctrl_phy_reset,
		.phy_lane_cfg   = dp_catalog_ctrl_phy_lane_cfg,
		.update_vx_px   = dp_catalog_ctrl_update_vx_px,
@@ -2434,6 +2463,10 @@ struct dp_catalog *dp_catalog_get(struct device *dev, struct dp_parser *parser)
		.fec_config = dp_catalog_ctrl_fec_config,
		.mainlink_levels = dp_catalog_ctrl_mainlink_levels,
	};
	struct dp_catalog_hpd hpd = {
		.config_hpd	= dp_catalog_hpd_config_hpd,
		.get_interrupt	= dp_catalog_hpd_get_interrupt,
	};
	struct dp_catalog_audio audio = {
		.init       = dp_catalog_audio_init,
		.config_acr = dp_catalog_audio_config_acr,
@@ -2479,6 +2512,7 @@ struct dp_catalog *dp_catalog_get(struct device *dev, struct dp_parser *parser)

	dp_catalog->aux   = aux;
	dp_catalog->ctrl  = ctrl;
	dp_catalog->hpd   = hpd;
	dp_catalog->audio = audio;
	dp_catalog->panel = panel;

+6 −1
Original line number Diff line number Diff line
@@ -108,7 +108,6 @@ struct dp_catalog_ctrl {
	void (*usb_reset)(struct dp_catalog_ctrl *ctrl, bool flip);
	bool (*mainlink_ready)(struct dp_catalog_ctrl *ctrl);
	void (*enable_irq)(struct dp_catalog_ctrl *ctrl, bool enable);
	void (*hpd_config)(struct dp_catalog_ctrl *ctrl, bool enable);
	void (*phy_reset)(struct dp_catalog_ctrl *ctrl);
	void (*phy_lane_cfg)(struct dp_catalog_ctrl *ctrl, bool flipped,
				u8 lane_cnt);
@@ -132,6 +131,11 @@ struct dp_catalog_ctrl {
	void (*mainlink_levels)(struct dp_catalog_ctrl *ctrl, u8 lane_cnt);
};

struct dp_catalog_hpd {
	void (*config_hpd)(struct dp_catalog_hpd *hpd, bool en);
	u32 (*get_interrupt)(struct dp_catalog_hpd *hpd);
};

#define HEADER_BYTE_2_BIT	 0
#define PARITY_BYTE_2_BIT	 8
#define HEADER_BYTE_1_BIT	16
@@ -249,6 +253,7 @@ struct dp_catalog {
	struct dp_catalog_audio audio;
	struct dp_catalog_panel panel;
	struct dp_catalog_priv priv;
	struct dp_catalog_hpd hpd;

	void (*set_exe_mode)(struct dp_catalog *dp_catalog, char *mode);
	int (*get_reg_dump)(struct dp_catalog *dp_catalog,
+0 −1
Original line number Diff line number Diff line
@@ -579,7 +579,6 @@ static int dp_ctrl_link_setup(struct dp_ctrl_private *ctrl, bool shallow)
	catalog = ctrl->catalog;
	link_params = &ctrl->link->link_params;

	catalog->hpd_config(catalog, true);
	catalog->phy_lane_cfg(catalog, ctrl->orientation,
				link_params->lane_count);

+7 −1
Original line number Diff line number Diff line
@@ -138,6 +138,10 @@ static irqreturn_t dp_display_irq(int irq, void *dev_id)
		return IRQ_NONE;
	}

	/* DP HPD isr */
	if (dp->hpd->type ==  DP_HPD_LPHW)
		dp->hpd->isr(dp->hpd);

	/* DP controller isr */
	dp->ctrl->isr(dp->ctrl);

@@ -618,6 +622,7 @@ static void dp_display_host_init(struct dp_display_private *dp)
	reset = dp->debug->sim_mode ? false : !dp->hpd->multi_func;

	dp->power->init(dp->power, flip);
	dp->hpd->host_init(dp->hpd, &dp->catalog->hpd);
	dp->ctrl->init(dp->ctrl, flip, reset);
	dp->aux->init(dp->aux, dp->parser->aux_cfg);
	enable_irq(dp->irq);
@@ -639,6 +644,7 @@ static void dp_display_host_deinit(struct dp_display_private *dp)

	dp->aux->deinit(dp->aux);
	dp->ctrl->deinit(dp->ctrl);
	dp->hpd->host_deinit(dp->hpd, &dp->catalog->hpd);
	dp->power->deinit(dp->power);
	disable_irq(dp->irq);
	dp->core_initialized = false;
@@ -1231,7 +1237,7 @@ static int dp_init_sub_modules(struct dp_display_private *dp)
	cb->disconnect = dp_display_usbpd_disconnect_cb;
	cb->attention  = dp_display_usbpd_attention_cb;

	dp->hpd = dp_hpd_get(dev, dp->parser, cb);
	dp->hpd = dp_hpd_get(dev, dp->parser, &dp->catalog->hpd, cb);
	if (IS_ERR(dp->hpd)) {
		rc = PTR_ERR(dp->hpd);
		pr_err("failed to initialize hpd, rc = %d\n", rc);
Loading