All of lore.kernel.org
 help / color / mirror / Atom feed
From: YT Shen <yt.shen@mediatek.com>
To: <dri-devel@lists.freedesktop.org>,
	Philipp Zabel <p.zabel@pengutronix.de>
Cc: David Airlie <airlied@linux.ie>,
	Matthias Brugger <matthias.bgg@gmail.com>,
	YT Shen <yt.shen@mediatek.com>,
	Daniel Kurtz <djkurtz@chromium.org>,
	Mao Huang <littlecvr@chromium.org>, CK Hu <ck.hu@mediatek.com>,
	Bibby Hsieh <bibby.hsieh@mediatek.com>,
	Daniel Vetter <daniel.vetter@ffwll.ch>,
	Thierry Reding <thierry.reding@gmail.com>,
	Jie Qiu <jie.qiu@mediatek.com>,
	Maxime Ripard <maxime.ripard@free-electrons.com>,
	Chris Wilson <chris@chris-wilson.co.uk>,
	shaoming chen <shaoming.chen@mediatek.com>,
	Jitao Shi <jitao.shi@mediatek.com>,
	Boris Brezillon <boris.brezillon@free-electrons.com>,
	Dan Carpenter <dan.carpenter@oracle.com>,
	<linux-arm-kernel@lists.infradead.org>,
	<linux-mediatek@lists.infradead.org>,
	<linux-kernel@vger.kernel.org>, <srv_heupstream@mediatek.com>,
	Sascha Hauer <kernel@pengutronix.de>, <yingjoe.chen@mediatek.com>,
	<emil.l.velikov@gmail.com>
Subject: [PATCH v10 12/13] drm/mediatek: update DSI sub driver flow for sending commands to panel
Date: Fri, 25 Nov 2016 18:34:35 +0800	[thread overview]
Message-ID: <1480070076-6196-13-git-send-email-yt.shen@mediatek.com> (raw)
In-Reply-To: <1480070076-6196-1-git-send-email-yt.shen@mediatek.com>

This patch update enable/disable flow of DSI module.
Original flow works on there is a bridge chip: DSI -> bridge -> panel.
In this case: DSI -> panel, the DSI sub driver flow should be updated.
We need to initialize DSI first so that we can send commands to panel.

Signed-off-by: shaoming chen <shaoming.chen@mediatek.com>
Signed-off-by: YT Shen <yt.shen@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 101 +++++++++++++++++++++++++++++--------
 1 file changed, 80 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index ded4202..0569f2e 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -126,6 +126,10 @@
 #define CLK_HS_POST			(0xff << 8)
 #define CLK_HS_EXIT			(0xff << 16)
 
+#define DSI_VM_CMD_CON		0x130
+#define VM_CMD_EN			BIT(0)
+#define TS_VFP_EN			BIT(5)
+
 #define DSI_CMDQ0		0x180
 #define CONFIG				(0xff << 0)
 #define SHORT_PACKET			0
@@ -249,7 +253,9 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi)
 	 * mipi_ratio is mipi clk coefficient for balance the pixel clk in mipi.
 	 * we set mipi_ratio is 1.05.
 	 */
-	dsi->data_rate = dsi->vm.pixelclock * 3 * 21 / (1 * 1000 * 10);
+	dsi->data_rate = dsi->vm.pixelclock * 12 * 21;
+	dsi->data_rate /= (dsi->lanes * 1000 * 10);
+	DRM_DEBUG_DRIVER("set mipitx's data rate: %dMHz\n", dsi->data_rate);
 
 	ret = clk_set_rate(dsi->hs_clk, dsi->data_rate * 1000000);
 	if (ret < 0) {
@@ -333,16 +339,23 @@ static void mtk_dsi_set_mode(struct mtk_dsi *dsi)
 	u32 vid_mode = CMD_MODE;
 
 	if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO) {
-		vid_mode = SYNC_PULSE_MODE;
-
-		if ((dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST) &&
-		    !(dsi->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE))
+		if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST)
 			vid_mode = BURST_MODE;
+		else if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)
+			vid_mode = SYNC_PULSE_MODE;
+		else
+			vid_mode = SYNC_EVENT_MODE;
 	}
 
 	writel(vid_mode, dsi->regs + DSI_MODE_CTRL);
 }
 
+static void mtk_dsi_set_vm_cmd(struct mtk_dsi *dsi)
+{
+	mtk_dsi_mask(dsi, DSI_VM_CMD_CON, VM_CMD_EN, VM_CMD_EN);
+	mtk_dsi_mask(dsi, DSI_VM_CMD_CON, TS_VFP_EN, TS_VFP_EN);
+}
+
 static void mtk_dsi_ps_control_vact(struct mtk_dsi *dsi)
 {
 	struct videomode *vm = &dsi->vm;
@@ -480,6 +493,16 @@ static void mtk_dsi_start(struct mtk_dsi *dsi)
 	writel(1, dsi->regs + DSI_START);
 }
 
+static void mtk_dsi_stop(struct mtk_dsi *dsi)
+{
+	writel(0, dsi->regs + DSI_START);
+}
+
+static void mtk_dsi_set_cmd_mode(struct mtk_dsi *dsi)
+{
+	writel(CMD_MODE, dsi->regs + DSI_MODE_CTRL);
+}
+
 static void mtk_dsi_set_interrupt_enable(struct mtk_dsi *dsi)
 {
 	u32 inten = LPRX_RD_RDY_INT_FLAG | CMD_DONE_INT_FLAG | VM_DONE_INT_FLAG;
@@ -538,6 +561,19 @@ static irqreturn_t mtk_dsi_irq(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
+static s32 mtk_dsi_switch_to_cmd_mode(struct mtk_dsi *dsi, u8 irq_flag, u32 t)
+{
+	mtk_dsi_irq_data_clear(dsi, irq_flag);
+	mtk_dsi_set_cmd_mode(dsi);
+
+	if (!mtk_dsi_wait_for_irq_done(dsi, irq_flag, t)) {
+		DRM_ERROR("failed to switch cmd mode\n");
+		return -ETIME;
+	} else {
+		return 0;
+	}
+}
+
 static void mtk_dsi_poweroff(struct mtk_dsi *dsi)
 {
 	if (WARN_ON(dsi->refcount == 0))
@@ -546,11 +582,6 @@ static void mtk_dsi_poweroff(struct mtk_dsi *dsi)
 	if (--dsi->refcount != 0)
 		return;
 
-	mtk_dsi_lane0_ulp_mode_enter(dsi);
-	mtk_dsi_clk_ulp_mode_enter(dsi);
-
-	mtk_dsi_disable(dsi);
-
 	clk_disable_unprepare(dsi->engine_clk);
 	clk_disable_unprepare(dsi->digital_clk);
 
@@ -564,13 +595,6 @@ static void mtk_output_dsi_enable(struct mtk_dsi *dsi)
 	if (dsi->enabled)
 		return;
 
-	if (dsi->panel) {
-		if (drm_panel_prepare(dsi->panel)) {
-			DRM_ERROR("failed to setup the panel\n");
-			return;
-		}
-	}
-
 	ret = mtk_dsi_poweron(dsi);
 	if (ret < 0) {
 		DRM_ERROR("failed to power on dsi\n");
@@ -578,21 +602,43 @@ static void mtk_output_dsi_enable(struct mtk_dsi *dsi)
 	}
 
 	mtk_dsi_rxtx_control(dsi);
+	mtk_dsi_ps_control_vact(dsi);
+	mtk_dsi_set_vm_cmd(dsi);
+	mtk_dsi_config_vdo_timing(dsi);
+	mtk_dsi_set_interrupt_enable(dsi);
 
 	mtk_dsi_clk_ulp_mode_leave(dsi);
 	mtk_dsi_lane0_ulp_mode_leave(dsi);
 	mtk_dsi_clk_hs_mode(dsi, 0);
-	mtk_dsi_set_mode(dsi);
 
-	mtk_dsi_ps_control_vact(dsi);
-	mtk_dsi_config_vdo_timing(dsi);
-	mtk_dsi_set_interrupt_enable(dsi);
+	if (dsi->panel) {
+		if (drm_panel_prepare(dsi->panel)) {
+			DRM_ERROR("failed to prepare the panel\n");
+
+			mtk_dsi_stop(dsi);
+			mtk_dsi_poweroff(dsi);
+			return;
+		}
+	}
 
 	mtk_dsi_set_mode(dsi);
 	mtk_dsi_clk_hs_mode(dsi, 1);
 
 	mtk_dsi_start(dsi);
 
+	if (dsi->panel) {
+		if (drm_panel_enable(dsi->panel)) {
+			DRM_ERROR("failed to enable the panel\n");
+
+			if (drm_panel_unprepare(dsi->panel))
+				DRM_ERROR("failed to unprepare the panel\n");
+
+			mtk_dsi_stop(dsi);
+			mtk_dsi_poweroff(dsi);
+			return;
+		}
+	}
+
 	dsi->enabled = true;
 }
 
@@ -608,6 +654,19 @@ static void mtk_output_dsi_disable(struct mtk_dsi *dsi)
 		}
 	}
 
+	mtk_dsi_stop(dsi);
+	if (!mtk_dsi_switch_to_cmd_mode(dsi, VM_DONE_INT_FLAG, 500)) {
+		if (dsi->panel) {
+			if (drm_panel_unprepare(dsi->panel))
+				DRM_ERROR("failed to unprepare the panel\n");
+		}
+	}
+
+	mtk_dsi_reset_engine(dsi);
+	mtk_dsi_lane0_ulp_mode_enter(dsi);
+	mtk_dsi_clk_ulp_mode_enter(dsi);
+	mtk_dsi_disable(dsi);
+
 	mtk_dsi_poweroff(dsi);
 
 	dsi->enabled = false;
-- 
1.9.1

WARNING: multiple messages have this Message-ID (diff)
From: YT Shen <yt.shen@mediatek.com>
To: dri-devel@lists.freedesktop.org, Philipp Zabel <p.zabel@pengutronix.de>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>,
	Jie Qiu <jie.qiu@mediatek.com>,
	Mao Huang <littlecvr@chromium.org>,
	yingjoe.chen@mediatek.com,
	Dan Carpenter <dan.carpenter@oracle.com>,
	Jitao Shi <jitao.shi@mediatek.com>,
	linux-mediatek@lists.infradead.org,
	Matthias Brugger <matthias.bgg@gmail.com>,
	shaoming chen <shaoming.chen@mediatek.com>,
	linux-arm-kernel@lists.infradead.org,
	srv_heupstream@mediatek.com, emil.l.velikov@gmail.com,
	linux-kernel@vger.kernel.org,
	Sascha Hauer <kernel@pengutronix.de>,
	Maxime Ripard <maxime.ripard@free-electrons.com>
Subject: [PATCH v10 12/13] drm/mediatek: update DSI sub driver flow for sending commands to panel
Date: Fri, 25 Nov 2016 18:34:35 +0800	[thread overview]
Message-ID: <1480070076-6196-13-git-send-email-yt.shen@mediatek.com> (raw)
In-Reply-To: <1480070076-6196-1-git-send-email-yt.shen@mediatek.com>

This patch update enable/disable flow of DSI module.
Original flow works on there is a bridge chip: DSI -> bridge -> panel.
In this case: DSI -> panel, the DSI sub driver flow should be updated.
We need to initialize DSI first so that we can send commands to panel.

Signed-off-by: shaoming chen <shaoming.chen@mediatek.com>
Signed-off-by: YT Shen <yt.shen@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 101 +++++++++++++++++++++++++++++--------
 1 file changed, 80 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index ded4202..0569f2e 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -126,6 +126,10 @@
 #define CLK_HS_POST			(0xff << 8)
 #define CLK_HS_EXIT			(0xff << 16)
 
+#define DSI_VM_CMD_CON		0x130
+#define VM_CMD_EN			BIT(0)
+#define TS_VFP_EN			BIT(5)
+
 #define DSI_CMDQ0		0x180
 #define CONFIG				(0xff << 0)
 #define SHORT_PACKET			0
@@ -249,7 +253,9 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi)
 	 * mipi_ratio is mipi clk coefficient for balance the pixel clk in mipi.
 	 * we set mipi_ratio is 1.05.
 	 */
-	dsi->data_rate = dsi->vm.pixelclock * 3 * 21 / (1 * 1000 * 10);
+	dsi->data_rate = dsi->vm.pixelclock * 12 * 21;
+	dsi->data_rate /= (dsi->lanes * 1000 * 10);
+	DRM_DEBUG_DRIVER("set mipitx's data rate: %dMHz\n", dsi->data_rate);
 
 	ret = clk_set_rate(dsi->hs_clk, dsi->data_rate * 1000000);
 	if (ret < 0) {
@@ -333,16 +339,23 @@ static void mtk_dsi_set_mode(struct mtk_dsi *dsi)
 	u32 vid_mode = CMD_MODE;
 
 	if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO) {
-		vid_mode = SYNC_PULSE_MODE;
-
-		if ((dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST) &&
-		    !(dsi->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE))
+		if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST)
 			vid_mode = BURST_MODE;
+		else if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)
+			vid_mode = SYNC_PULSE_MODE;
+		else
+			vid_mode = SYNC_EVENT_MODE;
 	}
 
 	writel(vid_mode, dsi->regs + DSI_MODE_CTRL);
 }
 
+static void mtk_dsi_set_vm_cmd(struct mtk_dsi *dsi)
+{
+	mtk_dsi_mask(dsi, DSI_VM_CMD_CON, VM_CMD_EN, VM_CMD_EN);
+	mtk_dsi_mask(dsi, DSI_VM_CMD_CON, TS_VFP_EN, TS_VFP_EN);
+}
+
 static void mtk_dsi_ps_control_vact(struct mtk_dsi *dsi)
 {
 	struct videomode *vm = &dsi->vm;
@@ -480,6 +493,16 @@ static void mtk_dsi_start(struct mtk_dsi *dsi)
 	writel(1, dsi->regs + DSI_START);
 }
 
+static void mtk_dsi_stop(struct mtk_dsi *dsi)
+{
+	writel(0, dsi->regs + DSI_START);
+}
+
+static void mtk_dsi_set_cmd_mode(struct mtk_dsi *dsi)
+{
+	writel(CMD_MODE, dsi->regs + DSI_MODE_CTRL);
+}
+
 static void mtk_dsi_set_interrupt_enable(struct mtk_dsi *dsi)
 {
 	u32 inten = LPRX_RD_RDY_INT_FLAG | CMD_DONE_INT_FLAG | VM_DONE_INT_FLAG;
@@ -538,6 +561,19 @@ static irqreturn_t mtk_dsi_irq(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
+static s32 mtk_dsi_switch_to_cmd_mode(struct mtk_dsi *dsi, u8 irq_flag, u32 t)
+{
+	mtk_dsi_irq_data_clear(dsi, irq_flag);
+	mtk_dsi_set_cmd_mode(dsi);
+
+	if (!mtk_dsi_wait_for_irq_done(dsi, irq_flag, t)) {
+		DRM_ERROR("failed to switch cmd mode\n");
+		return -ETIME;
+	} else {
+		return 0;
+	}
+}
+
 static void mtk_dsi_poweroff(struct mtk_dsi *dsi)
 {
 	if (WARN_ON(dsi->refcount == 0))
@@ -546,11 +582,6 @@ static void mtk_dsi_poweroff(struct mtk_dsi *dsi)
 	if (--dsi->refcount != 0)
 		return;
 
-	mtk_dsi_lane0_ulp_mode_enter(dsi);
-	mtk_dsi_clk_ulp_mode_enter(dsi);
-
-	mtk_dsi_disable(dsi);
-
 	clk_disable_unprepare(dsi->engine_clk);
 	clk_disable_unprepare(dsi->digital_clk);
 
@@ -564,13 +595,6 @@ static void mtk_output_dsi_enable(struct mtk_dsi *dsi)
 	if (dsi->enabled)
 		return;
 
-	if (dsi->panel) {
-		if (drm_panel_prepare(dsi->panel)) {
-			DRM_ERROR("failed to setup the panel\n");
-			return;
-		}
-	}
-
 	ret = mtk_dsi_poweron(dsi);
 	if (ret < 0) {
 		DRM_ERROR("failed to power on dsi\n");
@@ -578,21 +602,43 @@ static void mtk_output_dsi_enable(struct mtk_dsi *dsi)
 	}
 
 	mtk_dsi_rxtx_control(dsi);
+	mtk_dsi_ps_control_vact(dsi);
+	mtk_dsi_set_vm_cmd(dsi);
+	mtk_dsi_config_vdo_timing(dsi);
+	mtk_dsi_set_interrupt_enable(dsi);
 
 	mtk_dsi_clk_ulp_mode_leave(dsi);
 	mtk_dsi_lane0_ulp_mode_leave(dsi);
 	mtk_dsi_clk_hs_mode(dsi, 0);
-	mtk_dsi_set_mode(dsi);
 
-	mtk_dsi_ps_control_vact(dsi);
-	mtk_dsi_config_vdo_timing(dsi);
-	mtk_dsi_set_interrupt_enable(dsi);
+	if (dsi->panel) {
+		if (drm_panel_prepare(dsi->panel)) {
+			DRM_ERROR("failed to prepare the panel\n");
+
+			mtk_dsi_stop(dsi);
+			mtk_dsi_poweroff(dsi);
+			return;
+		}
+	}
 
 	mtk_dsi_set_mode(dsi);
 	mtk_dsi_clk_hs_mode(dsi, 1);
 
 	mtk_dsi_start(dsi);
 
+	if (dsi->panel) {
+		if (drm_panel_enable(dsi->panel)) {
+			DRM_ERROR("failed to enable the panel\n");
+
+			if (drm_panel_unprepare(dsi->panel))
+				DRM_ERROR("failed to unprepare the panel\n");
+
+			mtk_dsi_stop(dsi);
+			mtk_dsi_poweroff(dsi);
+			return;
+		}
+	}
+
 	dsi->enabled = true;
 }
 
@@ -608,6 +654,19 @@ static void mtk_output_dsi_disable(struct mtk_dsi *dsi)
 		}
 	}
 
+	mtk_dsi_stop(dsi);
+	if (!mtk_dsi_switch_to_cmd_mode(dsi, VM_DONE_INT_FLAG, 500)) {
+		if (dsi->panel) {
+			if (drm_panel_unprepare(dsi->panel))
+				DRM_ERROR("failed to unprepare the panel\n");
+		}
+	}
+
+	mtk_dsi_reset_engine(dsi);
+	mtk_dsi_lane0_ulp_mode_enter(dsi);
+	mtk_dsi_clk_ulp_mode_enter(dsi);
+	mtk_dsi_disable(dsi);
+
 	mtk_dsi_poweroff(dsi);
 
 	dsi->enabled = false;
-- 
1.9.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

WARNING: multiple messages have this Message-ID (diff)
From: yt.shen@mediatek.com (YT Shen)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v10 12/13] drm/mediatek: update DSI sub driver flow for sending commands to panel
Date: Fri, 25 Nov 2016 18:34:35 +0800	[thread overview]
Message-ID: <1480070076-6196-13-git-send-email-yt.shen@mediatek.com> (raw)
In-Reply-To: <1480070076-6196-1-git-send-email-yt.shen@mediatek.com>

This patch update enable/disable flow of DSI module.
Original flow works on there is a bridge chip: DSI -> bridge -> panel.
In this case: DSI -> panel, the DSI sub driver flow should be updated.
We need to initialize DSI first so that we can send commands to panel.

Signed-off-by: shaoming chen <shaoming.chen@mediatek.com>
Signed-off-by: YT Shen <yt.shen@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 101 +++++++++++++++++++++++++++++--------
 1 file changed, 80 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index ded4202..0569f2e 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -126,6 +126,10 @@
 #define CLK_HS_POST			(0xff << 8)
 #define CLK_HS_EXIT			(0xff << 16)
 
+#define DSI_VM_CMD_CON		0x130
+#define VM_CMD_EN			BIT(0)
+#define TS_VFP_EN			BIT(5)
+
 #define DSI_CMDQ0		0x180
 #define CONFIG				(0xff << 0)
 #define SHORT_PACKET			0
@@ -249,7 +253,9 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi)
 	 * mipi_ratio is mipi clk coefficient for balance the pixel clk in mipi.
 	 * we set mipi_ratio is 1.05.
 	 */
-	dsi->data_rate = dsi->vm.pixelclock * 3 * 21 / (1 * 1000 * 10);
+	dsi->data_rate = dsi->vm.pixelclock * 12 * 21;
+	dsi->data_rate /= (dsi->lanes * 1000 * 10);
+	DRM_DEBUG_DRIVER("set mipitx's data rate: %dMHz\n", dsi->data_rate);
 
 	ret = clk_set_rate(dsi->hs_clk, dsi->data_rate * 1000000);
 	if (ret < 0) {
@@ -333,16 +339,23 @@ static void mtk_dsi_set_mode(struct mtk_dsi *dsi)
 	u32 vid_mode = CMD_MODE;
 
 	if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO) {
-		vid_mode = SYNC_PULSE_MODE;
-
-		if ((dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST) &&
-		    !(dsi->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE))
+		if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST)
 			vid_mode = BURST_MODE;
+		else if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)
+			vid_mode = SYNC_PULSE_MODE;
+		else
+			vid_mode = SYNC_EVENT_MODE;
 	}
 
 	writel(vid_mode, dsi->regs + DSI_MODE_CTRL);
 }
 
+static void mtk_dsi_set_vm_cmd(struct mtk_dsi *dsi)
+{
+	mtk_dsi_mask(dsi, DSI_VM_CMD_CON, VM_CMD_EN, VM_CMD_EN);
+	mtk_dsi_mask(dsi, DSI_VM_CMD_CON, TS_VFP_EN, TS_VFP_EN);
+}
+
 static void mtk_dsi_ps_control_vact(struct mtk_dsi *dsi)
 {
 	struct videomode *vm = &dsi->vm;
@@ -480,6 +493,16 @@ static void mtk_dsi_start(struct mtk_dsi *dsi)
 	writel(1, dsi->regs + DSI_START);
 }
 
+static void mtk_dsi_stop(struct mtk_dsi *dsi)
+{
+	writel(0, dsi->regs + DSI_START);
+}
+
+static void mtk_dsi_set_cmd_mode(struct mtk_dsi *dsi)
+{
+	writel(CMD_MODE, dsi->regs + DSI_MODE_CTRL);
+}
+
 static void mtk_dsi_set_interrupt_enable(struct mtk_dsi *dsi)
 {
 	u32 inten = LPRX_RD_RDY_INT_FLAG | CMD_DONE_INT_FLAG | VM_DONE_INT_FLAG;
@@ -538,6 +561,19 @@ static irqreturn_t mtk_dsi_irq(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
+static s32 mtk_dsi_switch_to_cmd_mode(struct mtk_dsi *dsi, u8 irq_flag, u32 t)
+{
+	mtk_dsi_irq_data_clear(dsi, irq_flag);
+	mtk_dsi_set_cmd_mode(dsi);
+
+	if (!mtk_dsi_wait_for_irq_done(dsi, irq_flag, t)) {
+		DRM_ERROR("failed to switch cmd mode\n");
+		return -ETIME;
+	} else {
+		return 0;
+	}
+}
+
 static void mtk_dsi_poweroff(struct mtk_dsi *dsi)
 {
 	if (WARN_ON(dsi->refcount == 0))
@@ -546,11 +582,6 @@ static void mtk_dsi_poweroff(struct mtk_dsi *dsi)
 	if (--dsi->refcount != 0)
 		return;
 
-	mtk_dsi_lane0_ulp_mode_enter(dsi);
-	mtk_dsi_clk_ulp_mode_enter(dsi);
-
-	mtk_dsi_disable(dsi);
-
 	clk_disable_unprepare(dsi->engine_clk);
 	clk_disable_unprepare(dsi->digital_clk);
 
@@ -564,13 +595,6 @@ static void mtk_output_dsi_enable(struct mtk_dsi *dsi)
 	if (dsi->enabled)
 		return;
 
-	if (dsi->panel) {
-		if (drm_panel_prepare(dsi->panel)) {
-			DRM_ERROR("failed to setup the panel\n");
-			return;
-		}
-	}
-
 	ret = mtk_dsi_poweron(dsi);
 	if (ret < 0) {
 		DRM_ERROR("failed to power on dsi\n");
@@ -578,21 +602,43 @@ static void mtk_output_dsi_enable(struct mtk_dsi *dsi)
 	}
 
 	mtk_dsi_rxtx_control(dsi);
+	mtk_dsi_ps_control_vact(dsi);
+	mtk_dsi_set_vm_cmd(dsi);
+	mtk_dsi_config_vdo_timing(dsi);
+	mtk_dsi_set_interrupt_enable(dsi);
 
 	mtk_dsi_clk_ulp_mode_leave(dsi);
 	mtk_dsi_lane0_ulp_mode_leave(dsi);
 	mtk_dsi_clk_hs_mode(dsi, 0);
-	mtk_dsi_set_mode(dsi);
 
-	mtk_dsi_ps_control_vact(dsi);
-	mtk_dsi_config_vdo_timing(dsi);
-	mtk_dsi_set_interrupt_enable(dsi);
+	if (dsi->panel) {
+		if (drm_panel_prepare(dsi->panel)) {
+			DRM_ERROR("failed to prepare the panel\n");
+
+			mtk_dsi_stop(dsi);
+			mtk_dsi_poweroff(dsi);
+			return;
+		}
+	}
 
 	mtk_dsi_set_mode(dsi);
 	mtk_dsi_clk_hs_mode(dsi, 1);
 
 	mtk_dsi_start(dsi);
 
+	if (dsi->panel) {
+		if (drm_panel_enable(dsi->panel)) {
+			DRM_ERROR("failed to enable the panel\n");
+
+			if (drm_panel_unprepare(dsi->panel))
+				DRM_ERROR("failed to unprepare the panel\n");
+
+			mtk_dsi_stop(dsi);
+			mtk_dsi_poweroff(dsi);
+			return;
+		}
+	}
+
 	dsi->enabled = true;
 }
 
@@ -608,6 +654,19 @@ static void mtk_output_dsi_disable(struct mtk_dsi *dsi)
 		}
 	}
 
+	mtk_dsi_stop(dsi);
+	if (!mtk_dsi_switch_to_cmd_mode(dsi, VM_DONE_INT_FLAG, 500)) {
+		if (dsi->panel) {
+			if (drm_panel_unprepare(dsi->panel))
+				DRM_ERROR("failed to unprepare the panel\n");
+		}
+	}
+
+	mtk_dsi_reset_engine(dsi);
+	mtk_dsi_lane0_ulp_mode_enter(dsi);
+	mtk_dsi_clk_ulp_mode_enter(dsi);
+	mtk_dsi_disable(dsi);
+
 	mtk_dsi_poweroff(dsi);
 
 	dsi->enabled = false;
-- 
1.9.1

  parent reply	other threads:[~2016-11-25 10:45 UTC|newest]

Thread overview: 72+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-11-25 10:34 [PATCH v10 00/13] MT2701 DRM support YT Shen
2016-11-25 10:34 ` YT Shen
2016-11-25 10:34 ` YT Shen
2016-11-25 10:34 ` [PATCH v10 01/13] drm/mediatek: add helpers for coverting from the generic components YT Shen
2016-11-25 10:34   ` YT Shen
2016-11-25 10:34   ` YT Shen
2016-11-25 10:34 ` [PATCH v10 02/13] drm/mediatek: add *driver_data for different hardware settings YT Shen
2016-11-25 10:34   ` YT Shen
2016-11-25 10:34   ` YT Shen
2016-11-30  6:42   ` Daniel Kurtz
2016-11-30  6:42     ` Daniel Kurtz
2016-11-30  6:42     ` Daniel Kurtz
2016-12-05 12:50     ` YT Shen
2016-12-05 12:50       ` YT Shen
2016-12-05 12:50       ` YT Shen
2016-11-25 10:34 ` [PATCH v10 03/13] drm/mediatek: add shadow register support YT Shen
2016-11-25 10:34   ` YT Shen
2016-11-25 10:34   ` YT Shen
2016-11-25 10:34 ` [PATCH v10 04/13] drm/mediatek: add BLS component YT Shen
2016-11-25 10:34   ` YT Shen
2016-11-25 10:34   ` YT Shen
2016-11-25 10:34 ` [PATCH v10 05/13] drm/mediatek: update display module connections YT Shen
2016-11-25 10:34   ` YT Shen
2016-11-25 10:34   ` YT Shen
2016-11-25 10:34 ` [PATCH v10 06/13] drm/mediatek: cleaning up and refine YT Shen
2016-11-25 10:34   ` YT Shen
2016-11-25 10:34   ` YT Shen
2016-11-25 10:34 ` [PATCH v10 07/13] drm/mediatek: add dsi interrupt control YT Shen
2016-11-25 10:34   ` YT Shen
2016-11-25 10:34   ` YT Shen
2016-11-25 10:34 ` [PATCH v10 08/13] drm/mediatek: add dsi transfer function YT Shen
2016-11-25 10:34   ` YT Shen
2016-11-25 10:34   ` YT Shen
2016-11-25 10:34 ` [PATCH v10 09/13] drm/mediatek: add mipi_tx data rate check YT Shen
2016-11-25 10:34   ` YT Shen
2016-11-25 10:34   ` YT Shen
2016-11-30 11:05   ` CK Hu
2016-11-30 11:05     ` CK Hu
2016-11-30 11:05     ` CK Hu
2016-11-25 10:34 ` [PATCH v10 10/13] drm/mediatek: add dsi ulp mode control YT Shen
2016-11-25 10:34   ` YT Shen
2016-11-25 10:34   ` YT Shen
2016-12-01  1:10   ` CK Hu
2016-12-01  1:10     ` CK Hu
2016-12-01  1:10     ` CK Hu
2016-11-25 10:34 ` [PATCH v10 11/13] drm/mediatek: add dsi rxtx control YT Shen
2016-11-25 10:34   ` YT Shen
2016-11-25 10:34   ` YT Shen
2016-11-30 10:47   ` CK Hu
2016-11-30 10:47     ` CK Hu
2016-11-30 10:47     ` CK Hu
2016-11-25 10:34 ` YT Shen [this message]
2016-11-25 10:34   ` [PATCH v10 12/13] drm/mediatek: update DSI sub driver flow for sending commands to panel YT Shen
2016-11-25 10:34   ` YT Shen
2016-11-30  7:58   ` CK Hu
2016-11-30  7:58     ` CK Hu
2016-11-30  7:58     ` CK Hu
2016-12-05 12:43     ` YT Shen
2016-12-05 12:43       ` YT Shen
2016-12-05 12:43       ` YT Shen
2016-11-25 10:34 ` [PATCH v10 13/13] drm/mediatek: add support for Mediatek SoC MT2701 YT Shen
2016-11-25 10:34   ` YT Shen
2016-11-25 10:34   ` YT Shen
2016-11-30 14:03   ` Matthias Brugger
2016-11-30 14:03     ` Matthias Brugger
2016-11-30 14:03     ` Matthias Brugger
2016-12-05 13:01     ` YT Shen
2016-12-05 13:01       ` YT Shen
2016-12-05 13:01       ` YT Shen
2016-11-30  8:59 ` [PATCH v10 00/13] MT2701 DRM support CK Hu
2016-11-30  8:59   ` CK Hu
2016-11-30  8:59   ` CK Hu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1480070076-6196-13-git-send-email-yt.shen@mediatek.com \
    --to=yt.shen@mediatek.com \
    --cc=airlied@linux.ie \
    --cc=bibby.hsieh@mediatek.com \
    --cc=boris.brezillon@free-electrons.com \
    --cc=chris@chris-wilson.co.uk \
    --cc=ck.hu@mediatek.com \
    --cc=dan.carpenter@oracle.com \
    --cc=daniel.vetter@ffwll.ch \
    --cc=djkurtz@chromium.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=emil.l.velikov@gmail.com \
    --cc=jie.qiu@mediatek.com \
    --cc=jitao.shi@mediatek.com \
    --cc=kernel@pengutronix.de \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mediatek@lists.infradead.org \
    --cc=littlecvr@chromium.org \
    --cc=matthias.bgg@gmail.com \
    --cc=maxime.ripard@free-electrons.com \
    --cc=p.zabel@pengutronix.de \
    --cc=shaoming.chen@mediatek.com \
    --cc=srv_heupstream@mediatek.com \
    --cc=thierry.reding@gmail.com \
    --cc=yingjoe.chen@mediatek.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.