linux-omap.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v5 00/29] Convert DSI code to use drm_mipi_dsi and drm_panel (second half)
@ 2020-12-08 12:28 Tomi Valkeinen
  2020-12-08 12:28 ` [PATCH v5 01/29] drm/panel: panel-dsi-cm: cleanup tear enable Tomi Valkeinen
                   ` (28 more replies)
  0 siblings, 29 replies; 72+ messages in thread
From: Tomi Valkeinen @ 2020-12-08 12:28 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Nikhil Devshatwar, dri-devel
  Cc: linux-omap, Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg,
	Tomi Valkeinen

Hi,

This is version 5 of the series OMAP DSI conversion series. Previous
version can be found from:

https://www.spinics.net/lists/linux-omap/msg157480.html

To lessen the patch spam, I'm sending only patches starting from patch
56/80. There has been no changes to the patches before 56/80.

Diff between v4 and v5 is not much. There are no functional changes at
the end of the series (diff between v4 and v5 shows only cosmetic
changes, except fixing one missing r = 0 initialization).

The biggest change is splitting "drm/omap: dsi: cleanup channel usages"
into three parts. Also, the last patch is new in this version, although
I did send it for v4 as 81/80.

Other changes include minor clarifications and cleanups in the
descriptions, and moving a few changes from one commit to another in
case the change logically belongs to the other commit.

 Tomi

Tomi Valkeinen (29):
  drm/panel: panel-dsi-cm: cleanup tear enable
  ARM: dts: omap5: add address-cells & size-cells to dsi
  drm/omap: pll: fix iteration loop check
  drm/omap: dsi: set trans_mode according to client mode_flags
  drm/panel: panel-dsi-cm: set column & page at setup
  drm/omap: dsi: send nop instead of page & column
  drm/omap: dsi: simplify VC handling
  drm/omap: dsi: drop useless channel checks
  drm/omap: dsi: cleanup dispc channel usage
  drm/omap: dsi: rename 'channel' to 'vc'
  drm/omap: dsi: pass vc to various functions
  drm/omap: dsi: untangle vc & channel
  drm/omap: dsi: skip dsi_vc_enable_hs when already in correct mode
  drm/omap: dsi: enable HS before sending the frame
  drm/omap: dsi: use separate VCs for cmd and video
  drm/panel: panel-dsi-cm: remove extra 'if'
  drm/panel: panel-dsi-cm: add panel database to driver
  drm/panel: panel-dsi-cm: drop unneeded includes
  drm/omap: dsi: move structs & defines to dsi.h
  drm/omap: dsi: move enable/disable to bridge enable/disable
  drm/omap: dsi: display_enable cleanup
  drm/omap: dsi: display_disable cleanup
  drm/omap: dsi: rename dsi_display_* functions
  drm/omap: dsi: cleanup initial vc setup
  drm/omap: dsi: split video mode enable/disable into separate func
  drm/omap: dsi: fix and cleanup ddr_clk_always_on
  drm/omap: dsi: remove ulps support
  drm/omap: dsi: fix DCS_CMD_ENABLE
  drm/omap: dsi: allow DSI commands to be sent early

 arch/arm/boot/dts/omap5.dtsi          |    6 +
 drivers/gpu/drm/omapdrm/dss/dsi.c     | 1375 ++++++-------------------
 drivers/gpu/drm/omapdrm/dss/dsi.h     |  456 ++++++++
 drivers/gpu/drm/omapdrm/dss/omapdss.h |   64 --
 drivers/gpu/drm/omapdrm/dss/pll.c     |    6 +
 drivers/gpu/drm/panel/panel-dsi-cm.c  |  161 +--
 6 files changed, 899 insertions(+), 1169 deletions(-)
 create mode 100644 drivers/gpu/drm/omapdrm/dss/dsi.h

-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki


^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH v5 01/29] drm/panel: panel-dsi-cm: cleanup tear enable
  2020-12-08 12:28 [PATCH v5 00/29] Convert DSI code to use drm_mipi_dsi and drm_panel (second half) Tomi Valkeinen
@ 2020-12-08 12:28 ` Tomi Valkeinen
  2020-12-14 13:09   ` Sebastian Reichel
  2020-12-08 12:28 ` [PATCH v5 02/29] ARM: dts: omap5: add address-cells & size-cells to dsi Tomi Valkeinen
                   ` (27 subsequent siblings)
  28 siblings, 1 reply; 72+ messages in thread
From: Tomi Valkeinen @ 2020-12-08 12:28 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Nikhil Devshatwar, dri-devel
  Cc: linux-omap, Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg,
	Tomi Valkeinen

Simplify the code by moving code from _dsicm_enable_te() into
dsicm_power_on().

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: Sam Ravnborg <sam@ravnborg.org>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/gpu/drm/panel/panel-dsi-cm.c | 23 ++++-------------------
 1 file changed, 4 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-dsi-cm.c b/drivers/gpu/drm/panel/panel-dsi-cm.c
index 729b42b4dabd..38f79dca1fd0 100644
--- a/drivers/gpu/drm/panel/panel-dsi-cm.c
+++ b/drivers/gpu/drm/panel/panel-dsi-cm.c
@@ -68,8 +68,6 @@ static inline struct panel_drv_data *panel_to_ddata(struct drm_panel *panel)
 	return container_of(panel, struct panel_drv_data, panel);
 }
 
-static int _dsicm_enable_te(struct panel_drv_data *ddata, bool enable);
-
 static void dsicm_bl_power(struct panel_drv_data *ddata, bool enable)
 {
 	struct backlight_device *backlight;
@@ -313,10 +311,13 @@ static int dsicm_power_on(struct panel_drv_data *ddata)
 	if (r)
 		goto err;
 
-	r = _dsicm_enable_te(ddata, true);
+	r = mipi_dsi_dcs_set_tear_on(ddata->dsi, MIPI_DSI_DCS_TEAR_MODE_VBLANK);
 	if (r)
 		goto err;
 
+	/* possible panel bug */
+	msleep(100);
+
 	ddata->enabled = true;
 
 	if (!ddata->intro_printed) {
@@ -417,22 +418,6 @@ static int dsicm_disable(struct drm_panel *panel)
 	return r;
 }
 
-static int _dsicm_enable_te(struct panel_drv_data *ddata, bool enable)
-{
-	struct mipi_dsi_device *dsi = ddata->dsi;
-	int r;
-
-	if (enable)
-		r = mipi_dsi_dcs_set_tear_on(dsi, MIPI_DSI_DCS_TEAR_MODE_VBLANK);
-	else
-		r = mipi_dsi_dcs_set_tear_off(dsi);
-
-	/* possible panel bug */
-	msleep(100);
-
-	return r;
-}
-
 static int dsicm_get_modes(struct drm_panel *panel,
 			   struct drm_connector *connector)
 {
-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v5 02/29] ARM: dts: omap5: add address-cells & size-cells to dsi
  2020-12-08 12:28 [PATCH v5 00/29] Convert DSI code to use drm_mipi_dsi and drm_panel (second half) Tomi Valkeinen
  2020-12-08 12:28 ` [PATCH v5 01/29] drm/panel: panel-dsi-cm: cleanup tear enable Tomi Valkeinen
@ 2020-12-08 12:28 ` Tomi Valkeinen
  2020-12-14 13:09   ` Sebastian Reichel
  2020-12-08 12:28 ` [PATCH v5 03/29] drm/omap: pll: fix iteration loop check Tomi Valkeinen
                   ` (26 subsequent siblings)
  28 siblings, 1 reply; 72+ messages in thread
From: Tomi Valkeinen @ 2020-12-08 12:28 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Nikhil Devshatwar, dri-devel
  Cc: linux-omap, Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg,
	Tomi Valkeinen

Add address-cells & size-cells to DSI nodes so that board files do not
need to define them.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Cc: Tony Lindgren <tony@atomide.com>
Acked-by: Tony Lindgren <tony@atomide.com>
---
 arch/arm/boot/dts/omap5.dtsi | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm/boot/dts/omap5.dtsi b/arch/arm/boot/dts/omap5.dtsi
index 2bf2e5839a7f..e6f6947965ef 100644
--- a/arch/arm/boot/dts/omap5.dtsi
+++ b/arch/arm/boot/dts/omap5.dtsi
@@ -517,6 +517,9 @@ dsi1: encoder@0 {
 						clocks = <&dss_clkctrl OMAP5_DSS_CORE_CLKCTRL 8>,
 							 <&dss_clkctrl OMAP5_DSS_CORE_CLKCTRL 10>;
 						clock-names = "fck", "sys_clk";
+
+						#address-cells = <1>;
+						#size-cells = <0>;
 					};
 				};
 
@@ -549,6 +552,9 @@ dsi2: encoder@0 {
 						clocks = <&dss_clkctrl OMAP5_DSS_CORE_CLKCTRL 8>,
 							 <&dss_clkctrl OMAP5_DSS_CORE_CLKCTRL 10>;
 						clock-names = "fck", "sys_clk";
+
+						#address-cells = <1>;
+						#size-cells = <0>;
 					};
 				};
 
-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v5 03/29] drm/omap: pll: fix iteration loop check
  2020-12-08 12:28 [PATCH v5 00/29] Convert DSI code to use drm_mipi_dsi and drm_panel (second half) Tomi Valkeinen
  2020-12-08 12:28 ` [PATCH v5 01/29] drm/panel: panel-dsi-cm: cleanup tear enable Tomi Valkeinen
  2020-12-08 12:28 ` [PATCH v5 02/29] ARM: dts: omap5: add address-cells & size-cells to dsi Tomi Valkeinen
@ 2020-12-08 12:28 ` Tomi Valkeinen
  2020-12-14 13:10   ` Sebastian Reichel
  2020-12-08 12:28 ` [PATCH v5 04/29] drm/omap: dsi: set trans_mode according to client mode_flags Tomi Valkeinen
                   ` (25 subsequent siblings)
  28 siblings, 1 reply; 72+ messages in thread
From: Tomi Valkeinen @ 2020-12-08 12:28 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Nikhil Devshatwar, dri-devel
  Cc: linux-omap, Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg,
	Tomi Valkeinen

If the PLL calc function is given bad parameters, n_start/m_start may be
higher than n_stop/m_stop, which leads to the loops iterating through
the whole u32 number space.

Fix this by failing early on such cases.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/gpu/drm/omapdrm/dss/pll.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/omapdrm/dss/pll.c b/drivers/gpu/drm/omapdrm/dss/pll.c
index 1212f3cc52d1..12926218c436 100644
--- a/drivers/gpu/drm/omapdrm/dss/pll.c
+++ b/drivers/gpu/drm/omapdrm/dss/pll.c
@@ -222,6 +222,9 @@ bool dss_pll_calc_a(const struct dss_pll *pll, unsigned long clkin,
 	n_stop = min((unsigned)(clkin / fint_hw_min), hw->n_max);
 	n_inc = 1;
 
+	if (n_start > n_stop)
+		return false;
+
 	if (hw->errata_i886) {
 		swap(n_start, n_stop);
 		n_inc = -1;
@@ -239,6 +242,9 @@ bool dss_pll_calc_a(const struct dss_pll *pll, unsigned long clkin,
 				hw->m_max);
 		m_inc = 1;
 
+		if (m_start > m_stop)
+			continue;
+
 		if (hw->errata_i886) {
 			swap(m_start, m_stop);
 			m_inc = -1;
-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v5 04/29] drm/omap: dsi: set trans_mode according to client mode_flags
  2020-12-08 12:28 [PATCH v5 00/29] Convert DSI code to use drm_mipi_dsi and drm_panel (second half) Tomi Valkeinen
                   ` (2 preceding siblings ...)
  2020-12-08 12:28 ` [PATCH v5 03/29] drm/omap: pll: fix iteration loop check Tomi Valkeinen
@ 2020-12-08 12:28 ` Tomi Valkeinen
  2020-12-14 13:10   ` Sebastian Reichel
  2020-12-08 12:28 ` [PATCH v5 05/29] drm/panel: panel-dsi-cm: set column & page at setup Tomi Valkeinen
                   ` (24 subsequent siblings)
  28 siblings, 1 reply; 72+ messages in thread
From: Tomi Valkeinen @ 2020-12-08 12:28 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Nikhil Devshatwar, dri-devel
  Cc: linux-omap, Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg,
	Tomi Valkeinen

The DSI host driver currently ignores the video mode flags in
client->mode_flags. Add the code to take the transfer mode from client's
mode_flags.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/gpu/drm/omapdrm/dss/dsi.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index c3592c6db977..7fee9cf8782d 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -5140,6 +5140,13 @@ static int omap_dsi_host_attach(struct mipi_dsi_host *host,
 	dsi->config.lp_clk_min = 7000000; // TODO: get from client?
 	dsi->config.lp_clk_max = client->lp_rate;
 
+	if (client->mode_flags & MIPI_DSI_MODE_VIDEO_BURST)
+		dsi->config.trans_mode = OMAP_DSS_DSI_BURST_MODE;
+	else if (client->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)
+		dsi->config.trans_mode = OMAP_DSS_DSI_PULSE_MODE;
+	else
+		dsi->config.trans_mode = OMAP_DSS_DSI_EVENT_MODE;
+
 	dsi->ulps_auto_idle = false;
 
 	return 0;
-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v5 05/29] drm/panel: panel-dsi-cm: set column & page at setup
  2020-12-08 12:28 [PATCH v5 00/29] Convert DSI code to use drm_mipi_dsi and drm_panel (second half) Tomi Valkeinen
                   ` (3 preceding siblings ...)
  2020-12-08 12:28 ` [PATCH v5 04/29] drm/omap: dsi: set trans_mode according to client mode_flags Tomi Valkeinen
@ 2020-12-08 12:28 ` Tomi Valkeinen
  2020-12-14 13:10   ` Sebastian Reichel
  2020-12-08 12:28 ` [PATCH v5 06/29] drm/omap: dsi: send nop instead of page & column Tomi Valkeinen
                   ` (23 subsequent siblings)
  28 siblings, 1 reply; 72+ messages in thread
From: Tomi Valkeinen @ 2020-12-08 12:28 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Nikhil Devshatwar, dri-devel
  Cc: linux-omap, Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg,
	Tomi Valkeinen

Set the column & page address once during setup, instead of relying the
DSI host driver to set those.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: Sam Ravnborg <sam@ravnborg.org>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/gpu/drm/panel/panel-dsi-cm.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/drivers/gpu/drm/panel/panel-dsi-cm.c b/drivers/gpu/drm/panel/panel-dsi-cm.c
index 38f79dca1fd0..556f9a2c5c0c 100644
--- a/drivers/gpu/drm/panel/panel-dsi-cm.c
+++ b/drivers/gpu/drm/panel/panel-dsi-cm.c
@@ -170,6 +170,22 @@ static int dsicm_get_id(struct panel_drv_data *ddata, u8 *id1, u8 *id2, u8 *id3)
 	return 0;
 }
 
+static int dsicm_set_update_window(struct panel_drv_data *ddata)
+{
+	struct mipi_dsi_device *dsi = ddata->dsi;
+	int r;
+
+	r = mipi_dsi_dcs_set_column_address(dsi, 0, ddata->mode.hdisplay - 1);
+	if (r < 0)
+		return r;
+
+	r = mipi_dsi_dcs_set_page_address(dsi, 0, ddata->mode.vdisplay - 1);
+	if (r < 0)
+		return r;
+
+	return 0;
+}
+
 static int dsicm_bl_update_status(struct backlight_device *dev)
 {
 	struct panel_drv_data *ddata = dev_get_drvdata(&dev->dev);
@@ -307,6 +323,10 @@ static int dsicm_power_on(struct panel_drv_data *ddata)
 	if (r)
 		goto err;
 
+	r = dsicm_set_update_window(ddata);
+	if (r)
+		goto err;
+
 	r = mipi_dsi_dcs_set_display_on(ddata->dsi);
 	if (r)
 		goto err;
-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v5 06/29] drm/omap: dsi: send nop instead of page & column
  2020-12-08 12:28 [PATCH v5 00/29] Convert DSI code to use drm_mipi_dsi and drm_panel (second half) Tomi Valkeinen
                   ` (4 preceding siblings ...)
  2020-12-08 12:28 ` [PATCH v5 05/29] drm/panel: panel-dsi-cm: set column & page at setup Tomi Valkeinen
@ 2020-12-08 12:28 ` Tomi Valkeinen
  2020-12-14 14:22   ` Sebastian Reichel
  2020-12-08 12:28 ` [PATCH v5 07/29] drm/omap: dsi: simplify VC handling Tomi Valkeinen
                   ` (22 subsequent siblings)
  28 siblings, 1 reply; 72+ messages in thread
From: Tomi Valkeinen @ 2020-12-08 12:28 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Nikhil Devshatwar, dri-devel
  Cc: linux-omap, Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg,
	Tomi Valkeinen

The OMAP DSI command mode panel driver used to send page & column
address before each frame update, and this code was moved into the DSI
host driver when converting it to the DRM bridge model.

However, it's not really required to send the page & column address
before each frame. It's also something that doesn't really belong to the
DSI host driver, so we should drop the code.

That said, frame updates break if we don't send _something_ between the
frames. A NOP command does the trick.

It is not clear if this behavior is as expected from a DSI command mode
frame transfer, or is it a feature/issue with OMAP DSI driver, or a
feature/issue in the command mode panel used.

Most likely this is related to the following from the DSI spec:

"To enable PHY synchronization the host processor should periodically
end HS transmission and drive the Data Lanes to the LP state. This
transition should take place at least once per frame."

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/gpu/drm/omapdrm/dss/dsi.c | 46 ++++++++++++-------------------
 1 file changed, 17 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index 7fee9cf8782d..c6e044f8bece 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -3884,35 +3884,19 @@ static int _dsi_update(struct dsi_data *dsi)
 	return 0;
 }
 
-static int _dsi_update_window(struct dsi_data *dsi, int channel,
-			      int x, int y, int w, int h)
-{
-	int x1 = x, x2 = (x + w - 1);
-	int y1 = y, y2 = (y + h - 1);
-	u8 payloadX[5] = { MIPI_DCS_SET_COLUMN_ADDRESS,
-			   x1 >> 8, x1 & 0xff, x2 >> 8, x2 & 0xff };
-	u8 payloadY[5] = { MIPI_DCS_SET_PAGE_ADDRESS,
-			   y1 >> 8, y1 & 0xff, y2 >> 8, y2 & 0xff };
-	struct mipi_dsi_msg msgX = { 0 }, msgY = { 0 };
-	int ret;
+static int _dsi_send_nop(struct dsi_data *dsi, int channel)
+{
+	const u8 payload[] = { MIPI_DCS_NOP };
+	const struct mipi_dsi_msg msg = {
+		.channel = channel,
+		.type = MIPI_DSI_DCS_SHORT_WRITE,
+		.tx_len = 1,
+		.tx_buf = payload,
+	};
 
 	WARN_ON(!dsi_bus_is_locked(dsi));
 
-	msgX.type = MIPI_DSI_DCS_LONG_WRITE;
-	msgX.channel = channel;
-	msgX.tx_buf = payloadX;
-	msgX.tx_len = sizeof(payloadX);
-
-	msgY.type = MIPI_DSI_DCS_LONG_WRITE;
-	msgY.channel = channel;
-	msgY.tx_buf = payloadY;
-	msgY.tx_len = sizeof(payloadY);
-
-	ret = _omap_dsi_host_transfer(dsi, &msgX);
-	if (ret != 0)
-		return ret;
-
-	return _omap_dsi_host_transfer(dsi, &msgY);
+	return _omap_dsi_host_transfer(dsi, &msg);
 }
 
 static int dsi_update_channel(struct omap_dss_device *dssdev, int channel)
@@ -3944,10 +3928,14 @@ static int dsi_update_channel(struct omap_dss_device *dssdev, int channel)
 
 	dsi_set_ulps_auto(dsi, false);
 
-	r = _dsi_update_window(dsi, channel, 0, 0, dsi->vm.hactive,
-			       dsi->vm.vactive);
+	/*
+	 * Send NOP between the frames. If we don't send something here, the
+	 * updates stop working. This is probably related to DSI spec stating
+	 * that the DSI host should transition to LP at least once per frame.
+	 */
+	r = _dsi_send_nop(dsi, channel);
 	if (r < 0) {
-		DSSWARN("window update error: %d\n", r);
+		DSSWARN("failed to send nop between frames: %d\n", r);
 		goto err;
 	}
 
-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v5 07/29] drm/omap: dsi: simplify VC handling
  2020-12-08 12:28 [PATCH v5 00/29] Convert DSI code to use drm_mipi_dsi and drm_panel (second half) Tomi Valkeinen
                   ` (5 preceding siblings ...)
  2020-12-08 12:28 ` [PATCH v5 06/29] drm/omap: dsi: send nop instead of page & column Tomi Valkeinen
@ 2020-12-08 12:28 ` Tomi Valkeinen
  2020-12-14 14:31   ` Sebastian Reichel
  2020-12-08 12:28 ` [PATCH v5 08/29] drm/omap: dsi: drop useless channel checks Tomi Valkeinen
                   ` (21 subsequent siblings)
  28 siblings, 1 reply; 72+ messages in thread
From: Tomi Valkeinen @ 2020-12-08 12:28 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Nikhil Devshatwar, dri-devel
  Cc: linux-omap, Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg,
	Tomi Valkeinen

The VC handling has gotten quite tangled up. As the first step to clean
it up, lets define that we only support a single DSI peripheral (which
was really already the case), and we always use VC0 (define VC_DEFAULT
0) register block to send data to the peripheral.

We can thus have a single mipi_dsi_device pointer and remove the
for-loops which made passes over all the four VCs (just the first one
was ever used).

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/gpu/drm/omapdrm/dss/dsi.c | 49 ++++++++-----------------------
 1 file changed, 13 insertions(+), 36 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index c6e044f8bece..5e13478010db 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -360,9 +360,10 @@ struct dsi_data {
 	bool vdds_dsi_enabled;
 	struct regulator *vdds_dsi_reg;
 
+	struct mipi_dsi_device *dsidev;
+
 	struct {
 		enum dsi_vc_source source;
-		struct mipi_dsi_device *dest;
 		enum fifo_size tx_fifo_size;
 		enum fifo_size rx_fifo_size;
 	} vc[4];
@@ -452,6 +453,8 @@ static bool dsi_perf;
 module_param(dsi_perf, bool, 0644);
 #endif
 
+#define VC_DEFAULT 0
+
 #define drm_bridge_to_dsi(bridge) \
 	container_of(bridge, struct dsi_data, bridge)
 
@@ -3716,16 +3719,11 @@ static void dsi_disable_video_output(struct omap_dss_device *dssdev, int channel
 static void dsi_disable_video_outputs(struct omap_dss_device *dssdev)
 {
 	struct dsi_data *dsi = to_dsi_data(dssdev);
-	unsigned int i;
 
 	dsi_bus_lock(dsi);
 	dsi->video_enabled = false;
 
-	for (i = 0; i < 4; i++) {
-		if (!dsi->vc[i].dest)
-			continue;
-		dsi_disable_video_output(dssdev, i);
-	}
+	dsi_disable_video_output(dssdev, VC_DEFAULT);
 
 	dsi_display_disable(dssdev);
 
@@ -3914,11 +3912,6 @@ static int dsi_update_channel(struct omap_dss_device *dssdev, int channel)
 		goto err;
 	}
 
-	if (!dsi->vc[channel].dest) {
-		r = -ENODEV;
-		goto err;
-	}
-
 	if (dsi->vm.hactive == 0 || dsi->vm.vactive == 0) {
 		r = -EINVAL;
 		goto err;
@@ -3959,16 +3952,7 @@ static int dsi_update_channel(struct omap_dss_device *dssdev, int channel)
 
 static int dsi_update_all(struct omap_dss_device *dssdev)
 {
-	unsigned int i;
-	int r;
-
-	for (i = 0; i < 4; i++) {
-		r = dsi_update_channel(dssdev, i);
-		if (r && r != -ENODEV)
-			return r;
-	}
-
-	return r;
+	return dsi_update_channel(dssdev, VC_DEFAULT);
 }
 
 /* Display funcs */
@@ -4196,17 +4180,12 @@ static void dsi_display_enable(struct omap_dss_device *dssdev)
 static void dsi_enable_video_outputs(struct omap_dss_device *dssdev)
 {
 	struct dsi_data *dsi = to_dsi_data(dssdev);
-	unsigned int i;
 
 	dsi_bus_lock(dsi);
 
 	dsi_display_enable(dssdev);
 
-	for (i = 0; i < 4; i++) {
-		if (!dsi->vc[i].dest)
-			continue;
-		dsi_enable_video_output(dssdev, i);
-	}
+	dsi_enable_video_output(dssdev, VC_DEFAULT);
 
 	dsi->video_enabled = true;
 
@@ -5095,8 +5074,8 @@ static int omap_dsi_host_attach(struct mipi_dsi_host *host,
 	if (channel > 3)
 		return -EINVAL;
 
-	if (dsi->vc[channel].dest) {
-		DSSERR("cannot get VC for display %s", dev_name(&client->dev));
+	if (dsi->dsidev) {
+		DSSERR("dsi client already attached\n");
 		return -EBUSY;
 	}
 
@@ -5117,7 +5096,7 @@ static int omap_dsi_host_attach(struct mipi_dsi_host *host,
 		dsi->mode = OMAP_DSS_DSI_CMD_MODE;
 	}
 
-	dsi->vc[channel].dest = client;
+	dsi->dsidev = client;
 	dsi->pix_fmt = client->format;
 
 	INIT_DEFERRABLE_WORK(&dsi->ulps_work,
@@ -5149,11 +5128,11 @@ static int omap_dsi_host_detach(struct mipi_dsi_host *host,
 	if (channel > 3)
 		return -EINVAL;
 
-	if (dsi->vc[channel].dest != client)
+	if (WARN_ON(dsi->dsidev != client))
 		return -EINVAL;
 
 	omap_dsi_unregister_te_irq(dsi);
-	dsi->vc[channel].dest = NULL;
+	dsi->dsidev = NULL;
 	return 0;
 }
 
@@ -5685,10 +5664,8 @@ static int dsi_probe(struct platform_device *pdev)
 	}
 
 	/* DSI VCs initialization */
-	for (i = 0; i < ARRAY_SIZE(dsi->vc); i++) {
+	for (i = 0; i < ARRAY_SIZE(dsi->vc); i++)
 		dsi->vc[i].source = DSI_VC_SOURCE_L4;
-		dsi->vc[i].dest = NULL;
-	}
 
 	r = dsi_get_clocks(dsi);
 	if (r)
-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v5 08/29] drm/omap: dsi: drop useless channel checks
  2020-12-08 12:28 [PATCH v5 00/29] Convert DSI code to use drm_mipi_dsi and drm_panel (second half) Tomi Valkeinen
                   ` (6 preceding siblings ...)
  2020-12-08 12:28 ` [PATCH v5 07/29] drm/omap: dsi: simplify VC handling Tomi Valkeinen
@ 2020-12-08 12:28 ` Tomi Valkeinen
  2020-12-14 14:32   ` Sebastian Reichel
  2020-12-08 12:28 ` [PATCH v5 09/29] drm/omap: dsi: cleanup dispc channel usage Tomi Valkeinen
                   ` (20 subsequent siblings)
  28 siblings, 1 reply; 72+ messages in thread
From: Tomi Valkeinen @ 2020-12-08 12:28 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Nikhil Devshatwar, dri-devel
  Cc: linux-omap, Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg,
	Tomi Valkeinen

A DSI peripheral can have virtual channel ID of 0-3. This should be
always the case, and there's no need in the driver to validate the
channel.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/gpu/drm/omapdrm/dss/dsi.c | 11 -----------
 1 file changed, 11 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index 5e13478010db..c78ae99c8742 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -3902,9 +3902,6 @@ static int dsi_update_channel(struct omap_dss_device *dssdev, int channel)
 	struct dsi_data *dsi = to_dsi_data(dssdev);
 	int r;
 
-	if (channel > 3)
-		return -EINVAL;
-
 	dsi_bus_lock(dsi);
 
 	if (!dsi->video_enabled) {
@@ -5068,12 +5065,8 @@ static int omap_dsi_host_attach(struct mipi_dsi_host *host,
 				struct mipi_dsi_device *client)
 {
 	struct dsi_data *dsi = host_to_omap(host);
-	unsigned int channel = client->channel;
 	int r;
 
-	if (channel > 3)
-		return -EINVAL;
-
 	if (dsi->dsidev) {
 		DSSERR("dsi client already attached\n");
 		return -EBUSY;
@@ -5123,10 +5116,6 @@ static int omap_dsi_host_detach(struct mipi_dsi_host *host,
 				struct mipi_dsi_device *client)
 {
 	struct dsi_data *dsi = host_to_omap(host);
-	unsigned int channel = client->channel;
-
-	if (channel > 3)
-		return -EINVAL;
 
 	if (WARN_ON(dsi->dsidev != client))
 		return -EINVAL;
-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v5 09/29] drm/omap: dsi: cleanup dispc channel usage
  2020-12-08 12:28 [PATCH v5 00/29] Convert DSI code to use drm_mipi_dsi and drm_panel (second half) Tomi Valkeinen
                   ` (7 preceding siblings ...)
  2020-12-08 12:28 ` [PATCH v5 08/29] drm/omap: dsi: drop useless channel checks Tomi Valkeinen
@ 2020-12-08 12:28 ` Tomi Valkeinen
  2020-12-08 15:17   ` Laurent Pinchart
  2020-12-14 14:35   ` Sebastian Reichel
  2020-12-08 12:28 ` [PATCH v5 10/29] drm/omap: dsi: rename 'channel' to 'vc' Tomi Valkeinen
                   ` (19 subsequent siblings)
  28 siblings, 2 replies; 72+ messages in thread
From: Tomi Valkeinen @ 2020-12-08 12:28 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Nikhil Devshatwar, dri-devel
  Cc: linux-omap, Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg,
	Tomi Valkeinen

The "channel" usage in omap dsi driver is confusing. As the first step,
change "channel" to "dispc_channel" when dealing with the dispc channel.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/gpu/drm/omapdrm/dss/dsi.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index c78ae99c8742..cf0dc4872d14 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -3978,10 +3978,10 @@ static int dsi_configure_dispc_clocks(struct dsi_data *dsi)
 
 static int dsi_display_init_dispc(struct dsi_data *dsi)
 {
-	enum omap_channel channel = dsi->output.dispc_channel;
+	enum omap_channel dispc_channel = dsi->output.dispc_channel;
 	int r;
 
-	dss_select_lcd_clk_source(dsi->dss, channel, dsi->module_id == 0 ?
+	dss_select_lcd_clk_source(dsi->dss, dispc_channel, dsi->module_id == 0 ?
 			DSS_CLK_SRC_PLL1_1 :
 			DSS_CLK_SRC_PLL2_1);
 
@@ -4017,19 +4017,19 @@ static int dsi_display_init_dispc(struct dsi_data *dsi)
 		dss_mgr_unregister_framedone_handler(&dsi->output,
 				dsi_framedone_irq_callback, dsi);
 err:
-	dss_select_lcd_clk_source(dsi->dss, channel, DSS_CLK_SRC_FCK);
+	dss_select_lcd_clk_source(dsi->dss, dispc_channel, DSS_CLK_SRC_FCK);
 	return r;
 }
 
 static void dsi_display_uninit_dispc(struct dsi_data *dsi)
 {
-	enum omap_channel channel = dsi->output.dispc_channel;
+	enum omap_channel dispc_channel = dsi->output.dispc_channel;
 
 	if (dsi->mode == OMAP_DSS_DSI_CMD_MODE)
 		dss_mgr_unregister_framedone_handler(&dsi->output,
 				dsi_framedone_irq_callback, dsi);
 
-	dss_select_lcd_clk_source(dsi->dss, channel, DSS_CLK_SRC_FCK);
+	dss_select_lcd_clk_source(dsi->dss, dispc_channel, DSS_CLK_SRC_FCK);
 }
 
 static int dsi_configure_dsi_clocks(struct dsi_data *dsi)
@@ -4846,12 +4846,12 @@ static int dsi_set_config(struct omap_dss_device *dssdev,
 }
 
 /*
- * Return a hardcoded channel for the DSI output. This should work for
+ * Return a hardcoded dispc channel for the DSI output. This should work for
  * current use cases, but this can be later expanded to either resolve
  * the channel in some more dynamic manner, or get the channel as a user
  * parameter.
  */
-static enum omap_channel dsi_get_channel(struct dsi_data *dsi)
+static enum omap_channel dsi_get_dispc_channel(struct dsi_data *dsi)
 {
 	switch (dsi->data->model) {
 	case DSI_MODEL_OMAP3:
@@ -5403,7 +5403,7 @@ static int dsi_init_output(struct dsi_data *dsi)
 
 	out->type = OMAP_DISPLAY_TYPE_DSI;
 	out->name = dsi->module_id == 0 ? "dsi.0" : "dsi.1";
-	out->dispc_channel = dsi_get_channel(dsi);
+	out->dispc_channel = dsi_get_dispc_channel(dsi);
 	out->dsi_ops = &dsi_ops;
 	out->of_port = 0;
 	out->bus_flags = DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE
-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v5 10/29] drm/omap: dsi: rename 'channel' to 'vc'
  2020-12-08 12:28 [PATCH v5 00/29] Convert DSI code to use drm_mipi_dsi and drm_panel (second half) Tomi Valkeinen
                   ` (8 preceding siblings ...)
  2020-12-08 12:28 ` [PATCH v5 09/29] drm/omap: dsi: cleanup dispc channel usage Tomi Valkeinen
@ 2020-12-08 12:28 ` Tomi Valkeinen
  2020-12-08 15:22   ` Laurent Pinchart
  2020-12-14 15:18   ` Sebastian Reichel
  2020-12-08 12:28 ` [PATCH v5 11/29] drm/omap: dsi: pass vc to various functions Tomi Valkeinen
                   ` (18 subsequent siblings)
  28 siblings, 2 replies; 72+ messages in thread
From: Tomi Valkeinen @ 2020-12-08 12:28 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Nikhil Devshatwar, dri-devel
  Cc: linux-omap, Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg,
	Tomi Valkeinen

The "channel" usage in omap dsi driver is confusing. We have three
different "channels":

1) DSI virtual channel ID. This is a number from 0 to 3, included in the
packet payload.

2) VC. This is a register block in the DSI IP. There are four of those
blocks. A VC is a DSI "pipeline", with defined fifo settings, data
source (cpu or dispc), and some other settings. It has no relation to
the 1).

3) dispc channel. It's the "pipeline" number dispc uses to send pixel
data.

The previous patch handled the third case.

 To start fixing 1) and 2), we first rename all uses of 'channel' to
'vc', as in most of the cases that is the correct thing to use.

However, in some places 1) and 2) have gotten mixed up (i.e. the code
uses msg->channel when it should use vc), which will be fixed in the
following patch.

Note that mixing 1) and 2) currently is "fine", as at the moment we only
support DSI peripherals with DSI virtual channel 0, and we always use
VC0 to send data. So both 1) and 2) are always 0.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/gpu/drm/omapdrm/dss/dsi.c | 220 +++++++++++++++---------------
 1 file changed, 110 insertions(+), 110 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index cf0dc4872d14..273159e8f992 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -214,7 +214,7 @@ static void dsi_set_ulps_auto(struct dsi_data *dsi, bool enable);
 static int dsi_display_init_dispc(struct dsi_data *dsi);
 static void dsi_display_uninit_dispc(struct dsi_data *dsi);
 
-static int dsi_vc_send_null(struct dsi_data *dsi, int channel);
+static int dsi_vc_send_null(struct dsi_data *dsi, int vc);
 
 static ssize_t _omap_dsi_host_transfer(struct dsi_data *dsi,
 				       const struct mipi_dsi_msg *msg);
@@ -376,7 +376,7 @@ struct dsi_data {
 	/* space for a copy used by the interrupt handler */
 	struct dsi_isr_tables isr_tables_copy;
 
-	int update_channel;
+	int update_vc;
 #ifdef DSI_PERF_MEASURE
 	unsigned int update_bytes;
 #endif
@@ -639,7 +639,7 @@ static void print_irq_status(u32 status)
 #undef PIS
 }
 
-static void print_irq_status_vc(int channel, u32 status)
+static void print_irq_status_vc(int vc, u32 status)
 {
 	if (status == 0)
 		return;
@@ -650,7 +650,7 @@ static void print_irq_status_vc(int channel, u32 status)
 #define PIS(x) (status & DSI_VC_IRQ_##x) ? (#x " ") : ""
 
 	pr_debug("DSI VC(%d) IRQ 0x%x: %s%s%s%s%s%s%s%s%s\n",
-		channel,
+		vc,
 		status,
 		PIS(CS),
 		PIS(ECC_CORR),
@@ -1031,7 +1031,7 @@ static int dsi_unregister_isr(struct dsi_data *dsi, omap_dsi_isr_t isr,
 	return r;
 }
 
-static int dsi_register_isr_vc(struct dsi_data *dsi, int channel,
+static int dsi_register_isr_vc(struct dsi_data *dsi, int vc,
 			       omap_dsi_isr_t isr, void *arg, u32 mask)
 {
 	unsigned long flags;
@@ -1040,18 +1040,18 @@ static int dsi_register_isr_vc(struct dsi_data *dsi, int channel,
 	spin_lock_irqsave(&dsi->irq_lock, flags);
 
 	r = _dsi_register_isr(isr, arg, mask,
-			dsi->isr_tables.isr_table_vc[channel],
-			ARRAY_SIZE(dsi->isr_tables.isr_table_vc[channel]));
+			dsi->isr_tables.isr_table_vc[vc],
+			ARRAY_SIZE(dsi->isr_tables.isr_table_vc[vc]));
 
 	if (r == 0)
-		_omap_dsi_set_irqs_vc(dsi, channel);
+		_omap_dsi_set_irqs_vc(dsi, vc);
 
 	spin_unlock_irqrestore(&dsi->irq_lock, flags);
 
 	return r;
 }
 
-static int dsi_unregister_isr_vc(struct dsi_data *dsi, int channel,
+static int dsi_unregister_isr_vc(struct dsi_data *dsi, int vc,
 				 omap_dsi_isr_t isr, void *arg, u32 mask)
 {
 	unsigned long flags;
@@ -1060,11 +1060,11 @@ static int dsi_unregister_isr_vc(struct dsi_data *dsi, int channel,
 	spin_lock_irqsave(&dsi->irq_lock, flags);
 
 	r = _dsi_unregister_isr(isr, arg, mask,
-			dsi->isr_tables.isr_table_vc[channel],
-			ARRAY_SIZE(dsi->isr_tables.isr_table_vc[channel]));
+			dsi->isr_tables.isr_table_vc[vc],
+			ARRAY_SIZE(dsi->isr_tables.isr_table_vc[vc]));
 
 	if (r == 0)
-		_omap_dsi_set_irqs_vc(dsi, channel);
+		_omap_dsi_set_irqs_vc(dsi, vc);
 
 	spin_unlock_irqrestore(&dsi->irq_lock, flags);
 
@@ -2232,9 +2232,9 @@ static int dsi_force_tx_stop_mode_io(struct dsi_data *dsi)
 	return 0;
 }
 
-static bool dsi_vc_is_enabled(struct dsi_data *dsi, int channel)
+static bool dsi_vc_is_enabled(struct dsi_data *dsi, int vc)
 {
-	return REG_GET(dsi, DSI_VC_CTRL(channel), 0, 0);
+	return REG_GET(dsi, DSI_VC_CTRL(vc), 0, 0);
 }
 
 static void dsi_packet_sent_handler_vp(void *data, u32 mask)
@@ -2242,14 +2242,14 @@ static void dsi_packet_sent_handler_vp(void *data, u32 mask)
 	struct dsi_packet_sent_handler_data *vp_data =
 		(struct dsi_packet_sent_handler_data *) data;
 	struct dsi_data *dsi = vp_data->dsi;
-	const int channel = dsi->update_channel;
+	const int vc = dsi->update_vc;
 	u8 bit = dsi->te_enabled ? 30 : 31;
 
-	if (REG_GET(dsi, DSI_VC_TE(channel), bit, bit) == 0)
+	if (REG_GET(dsi, DSI_VC_TE(vc), bit, bit) == 0)
 		complete(vp_data->completion);
 }
 
-static int dsi_sync_vc_vp(struct dsi_data *dsi, int channel)
+static int dsi_sync_vc_vp(struct dsi_data *dsi, int vc)
 {
 	DECLARE_COMPLETION_ONSTACK(completion);
 	struct dsi_packet_sent_handler_data vp_data = {
@@ -2261,13 +2261,13 @@ static int dsi_sync_vc_vp(struct dsi_data *dsi, int channel)
 
 	bit = dsi->te_enabled ? 30 : 31;
 
-	r = dsi_register_isr_vc(dsi, channel, dsi_packet_sent_handler_vp,
+	r = dsi_register_isr_vc(dsi, vc, dsi_packet_sent_handler_vp,
 		&vp_data, DSI_VC_IRQ_PACKET_SENT);
 	if (r)
 		goto err0;
 
 	/* Wait for completion only if TE_EN/TE_START is still set */
-	if (REG_GET(dsi, DSI_VC_TE(channel), bit, bit)) {
+	if (REG_GET(dsi, DSI_VC_TE(vc), bit, bit)) {
 		if (wait_for_completion_timeout(&completion,
 				msecs_to_jiffies(10)) == 0) {
 			DSSERR("Failed to complete previous frame transfer\n");
@@ -2276,12 +2276,12 @@ static int dsi_sync_vc_vp(struct dsi_data *dsi, int channel)
 		}
 	}
 
-	dsi_unregister_isr_vc(dsi, channel, dsi_packet_sent_handler_vp,
+	dsi_unregister_isr_vc(dsi, vc, dsi_packet_sent_handler_vp,
 		&vp_data, DSI_VC_IRQ_PACKET_SENT);
 
 	return 0;
 err1:
-	dsi_unregister_isr_vc(dsi, channel, dsi_packet_sent_handler_vp,
+	dsi_unregister_isr_vc(dsi, vc, dsi_packet_sent_handler_vp,
 		&vp_data, DSI_VC_IRQ_PACKET_SENT);
 err0:
 	return r;
@@ -2292,13 +2292,13 @@ static void dsi_packet_sent_handler_l4(void *data, u32 mask)
 	struct dsi_packet_sent_handler_data *l4_data =
 		(struct dsi_packet_sent_handler_data *) data;
 	struct dsi_data *dsi = l4_data->dsi;
-	const int channel = dsi->update_channel;
+	const int vc = dsi->update_vc;
 
-	if (REG_GET(dsi, DSI_VC_CTRL(channel), 5, 5) == 0)
+	if (REG_GET(dsi, DSI_VC_CTRL(vc), 5, 5) == 0)
 		complete(l4_data->completion);
 }
 
-static int dsi_sync_vc_l4(struct dsi_data *dsi, int channel)
+static int dsi_sync_vc_l4(struct dsi_data *dsi, int vc)
 {
 	DECLARE_COMPLETION_ONSTACK(completion);
 	struct dsi_packet_sent_handler_data l4_data = {
@@ -2307,13 +2307,13 @@ static int dsi_sync_vc_l4(struct dsi_data *dsi, int channel)
 	};
 	int r = 0;
 
-	r = dsi_register_isr_vc(dsi, channel, dsi_packet_sent_handler_l4,
+	r = dsi_register_isr_vc(dsi, vc, dsi_packet_sent_handler_l4,
 		&l4_data, DSI_VC_IRQ_PACKET_SENT);
 	if (r)
 		goto err0;
 
 	/* Wait for completion only if TX_FIFO_NOT_EMPTY is still set */
-	if (REG_GET(dsi, DSI_VC_CTRL(channel), 5, 5)) {
+	if (REG_GET(dsi, DSI_VC_CTRL(vc), 5, 5)) {
 		if (wait_for_completion_timeout(&completion,
 				msecs_to_jiffies(10)) == 0) {
 			DSSERR("Failed to complete previous l4 transfer\n");
@@ -2322,47 +2322,47 @@ static int dsi_sync_vc_l4(struct dsi_data *dsi, int channel)
 		}
 	}
 
-	dsi_unregister_isr_vc(dsi, channel, dsi_packet_sent_handler_l4,
+	dsi_unregister_isr_vc(dsi, vc, dsi_packet_sent_handler_l4,
 		&l4_data, DSI_VC_IRQ_PACKET_SENT);
 
 	return 0;
 err1:
-	dsi_unregister_isr_vc(dsi, channel, dsi_packet_sent_handler_l4,
+	dsi_unregister_isr_vc(dsi, vc, dsi_packet_sent_handler_l4,
 		&l4_data, DSI_VC_IRQ_PACKET_SENT);
 err0:
 	return r;
 }
 
-static int dsi_sync_vc(struct dsi_data *dsi, int channel)
+static int dsi_sync_vc(struct dsi_data *dsi, int vc)
 {
 	WARN_ON(!dsi_bus_is_locked(dsi));
 
 	WARN_ON(in_interrupt());
 
-	if (!dsi_vc_is_enabled(dsi, channel))
+	if (!dsi_vc_is_enabled(dsi, vc))
 		return 0;
 
-	switch (dsi->vc[channel].source) {
+	switch (dsi->vc[vc].source) {
 	case DSI_VC_SOURCE_VP:
-		return dsi_sync_vc_vp(dsi, channel);
+		return dsi_sync_vc_vp(dsi, vc);
 	case DSI_VC_SOURCE_L4:
-		return dsi_sync_vc_l4(dsi, channel);
+		return dsi_sync_vc_l4(dsi, vc);
 	default:
 		BUG();
 		return -EINVAL;
 	}
 }
 
-static int dsi_vc_enable(struct dsi_data *dsi, int channel, bool enable)
+static int dsi_vc_enable(struct dsi_data *dsi, int vc, bool enable)
 {
-	DSSDBG("dsi_vc_enable channel %d, enable %d\n",
-			channel, enable);
+	DSSDBG("dsi_vc_enable vc %d, enable %d\n",
+			vc, enable);
 
 	enable = enable ? 1 : 0;
 
-	REG_FLD_MOD(dsi, DSI_VC_CTRL(channel), enable, 0, 0);
+	REG_FLD_MOD(dsi, DSI_VC_CTRL(vc), enable, 0, 0);
 
-	if (!wait_for_bit_change(dsi, DSI_VC_CTRL(channel), 0, enable)) {
+	if (!wait_for_bit_change(dsi, DSI_VC_CTRL(vc), 0, enable)) {
 		DSSERR("Failed to set dsi_vc_enable to %d\n", enable);
 		return -EIO;
 	}
@@ -2370,17 +2370,17 @@ static int dsi_vc_enable(struct dsi_data *dsi, int channel, bool enable)
 	return 0;
 }
 
-static void dsi_vc_initial_config(struct dsi_data *dsi, int channel)
+static void dsi_vc_initial_config(struct dsi_data *dsi, int vc)
 {
 	u32 r;
 
-	DSSDBG("Initial config of virtual channel %d", channel);
+	DSSDBG("Initial config of VC %d", vc);
 
-	r = dsi_read_reg(dsi, DSI_VC_CTRL(channel));
+	r = dsi_read_reg(dsi, DSI_VC_CTRL(vc));
 
 	if (FLD_GET(r, 15, 15)) /* VC_BUSY */
 		DSSERR("VC(%d) busy when trying to configure it!\n",
-				channel);
+				vc);
 
 	r = FLD_MOD(r, 0, 1, 1); /* SOURCE, 0 = L4 */
 	r = FLD_MOD(r, 0, 2, 2); /* BTA_SHORT_EN  */
@@ -2395,76 +2395,76 @@ static void dsi_vc_initial_config(struct dsi_data *dsi, int channel)
 	r = FLD_MOD(r, 4, 29, 27); /* DMA_RX_REQ_NB = no dma */
 	r = FLD_MOD(r, 4, 23, 21); /* DMA_TX_REQ_NB = no dma */
 
-	dsi_write_reg(dsi, DSI_VC_CTRL(channel), r);
+	dsi_write_reg(dsi, DSI_VC_CTRL(vc), r);
 
-	dsi->vc[channel].source = DSI_VC_SOURCE_L4;
+	dsi->vc[vc].source = DSI_VC_SOURCE_L4;
 }
 
-static int dsi_vc_config_source(struct dsi_data *dsi, int channel,
+static int dsi_vc_config_source(struct dsi_data *dsi, int vc,
 				enum dsi_vc_source source)
 {
-	if (dsi->vc[channel].source == source)
+	if (dsi->vc[vc].source == source)
 		return 0;
 
-	DSSDBG("Source config of virtual channel %d", channel);
+	DSSDBG("Source config of VC %d", vc);
 
-	dsi_sync_vc(dsi, channel);
+	dsi_sync_vc(dsi, vc);
 
-	dsi_vc_enable(dsi, channel, 0);
+	dsi_vc_enable(dsi, vc, 0);
 
 	/* VC_BUSY */
-	if (!wait_for_bit_change(dsi, DSI_VC_CTRL(channel), 15, 0)) {
-		DSSERR("vc(%d) busy when trying to config for VP\n", channel);
+	if (!wait_for_bit_change(dsi, DSI_VC_CTRL(vc), 15, 0)) {
+		DSSERR("vc(%d) busy when trying to config for VP\n", vc);
 		return -EIO;
 	}
 
 	/* SOURCE, 0 = L4, 1 = video port */
-	REG_FLD_MOD(dsi, DSI_VC_CTRL(channel), source, 1, 1);
+	REG_FLD_MOD(dsi, DSI_VC_CTRL(vc), source, 1, 1);
 
 	/* DCS_CMD_ENABLE */
 	if (dsi->data->quirks & DSI_QUIRK_DCS_CMD_CONFIG_VC) {
 		bool enable = source == DSI_VC_SOURCE_VP;
-		REG_FLD_MOD(dsi, DSI_VC_CTRL(channel), enable, 30, 30);
+		REG_FLD_MOD(dsi, DSI_VC_CTRL(vc), enable, 30, 30);
 	}
 
-	dsi_vc_enable(dsi, channel, 1);
+	dsi_vc_enable(dsi, vc, 1);
 
-	dsi->vc[channel].source = source;
+	dsi->vc[vc].source = source;
 
 	return 0;
 }
 
-static void dsi_vc_enable_hs(struct omap_dss_device *dssdev, int channel,
+static void dsi_vc_enable_hs(struct omap_dss_device *dssdev, int vc,
 		bool enable)
 {
 	struct dsi_data *dsi = to_dsi_data(dssdev);
 
-	DSSDBG("dsi_vc_enable_hs(%d, %d)\n", channel, enable);
+	DSSDBG("dsi_vc_enable_hs(%d, %d)\n", vc, enable);
 
 	WARN_ON(!dsi_bus_is_locked(dsi));
 
-	dsi_vc_enable(dsi, channel, 0);
+	dsi_vc_enable(dsi, vc, 0);
 	dsi_if_enable(dsi, 0);
 
-	REG_FLD_MOD(dsi, DSI_VC_CTRL(channel), enable, 9, 9);
+	REG_FLD_MOD(dsi, DSI_VC_CTRL(vc), enable, 9, 9);
 
-	dsi_vc_enable(dsi, channel, 1);
+	dsi_vc_enable(dsi, vc, 1);
 	dsi_if_enable(dsi, 1);
 
 	dsi_force_tx_stop_mode_io(dsi);
 
 	/* start the DDR clock by sending a NULL packet */
 	if (dsi->vm_timings.ddr_clk_always_on && enable)
-		dsi_vc_send_null(dsi, channel);
+		dsi_vc_send_null(dsi, vc);
 
 	dsi->in_lp_mode = !enable;
 }
 
-static void dsi_vc_flush_long_data(struct dsi_data *dsi, int channel)
+static void dsi_vc_flush_long_data(struct dsi_data *dsi, int vc)
 {
-	while (REG_GET(dsi, DSI_VC_CTRL(channel), 20, 20)) {
+	while (REG_GET(dsi, DSI_VC_CTRL(vc), 20, 20)) {
 		u32 val;
-		val = dsi_read_reg(dsi, DSI_VC_SHORT_PACKET_HEADER(channel));
+		val = dsi_read_reg(dsi, DSI_VC_SHORT_PACKET_HEADER(vc));
 		DSSDBG("\t\tb1 %#02x b2 %#02x b3 %#02x b4 %#02x\n",
 				(val >> 0) & 0xff,
 				(val >> 8) & 0xff,
@@ -2510,13 +2510,13 @@ static void dsi_show_rx_ack_with_err(u16 err)
 		DSSERR("\t\tDSI Protocol Violation\n");
 }
 
-static u16 dsi_vc_flush_receive_data(struct dsi_data *dsi, int channel)
+static u16 dsi_vc_flush_receive_data(struct dsi_data *dsi, int vc)
 {
 	/* RX_FIFO_NOT_EMPTY */
-	while (REG_GET(dsi, DSI_VC_CTRL(channel), 20, 20)) {
+	while (REG_GET(dsi, DSI_VC_CTRL(vc), 20, 20)) {
 		u32 val;
 		u8 dt;
-		val = dsi_read_reg(dsi, DSI_VC_SHORT_PACKET_HEADER(channel));
+		val = dsi_read_reg(dsi, DSI_VC_SHORT_PACKET_HEADER(vc));
 		DSSERR("\trawval %#08x\n", val);
 		dt = FLD_GET(val, 5, 0);
 		if (dt == MIPI_DSI_RX_ACKNOWLEDGE_AND_ERROR_REPORT) {
@@ -2531,7 +2531,7 @@ static u16 dsi_vc_flush_receive_data(struct dsi_data *dsi, int channel)
 		} else if (dt == MIPI_DSI_RX_DCS_LONG_READ_RESPONSE) {
 			DSSERR("\tDCS long response, len %d\n",
 					FLD_GET(val, 23, 8));
-			dsi_vc_flush_long_data(dsi, channel);
+			dsi_vc_flush_long_data(dsi, vc);
 		} else {
 			DSSERR("\tunknown datatype 0x%02x\n", dt);
 		}
@@ -2539,35 +2539,35 @@ static u16 dsi_vc_flush_receive_data(struct dsi_data *dsi, int channel)
 	return 0;
 }
 
-static int dsi_vc_send_bta(struct dsi_data *dsi, int channel)
+static int dsi_vc_send_bta(struct dsi_data *dsi, int vc)
 {
 	if (dsi->debug_write || dsi->debug_read)
-		DSSDBG("dsi_vc_send_bta %d\n", channel);
+		DSSDBG("dsi_vc_send_bta %d\n", vc);
 
 	WARN_ON(!dsi_bus_is_locked(dsi));
 
 	/* RX_FIFO_NOT_EMPTY */
-	if (REG_GET(dsi, DSI_VC_CTRL(channel), 20, 20)) {
+	if (REG_GET(dsi, DSI_VC_CTRL(vc), 20, 20)) {
 		DSSERR("rx fifo not empty when sending BTA, dumping data:\n");
-		dsi_vc_flush_receive_data(dsi, channel);
+		dsi_vc_flush_receive_data(dsi, vc);
 	}
 
-	REG_FLD_MOD(dsi, DSI_VC_CTRL(channel), 1, 6, 6); /* BTA_EN */
+	REG_FLD_MOD(dsi, DSI_VC_CTRL(vc), 1, 6, 6); /* BTA_EN */
 
 	/* flush posted write */
-	dsi_read_reg(dsi, DSI_VC_CTRL(channel));
+	dsi_read_reg(dsi, DSI_VC_CTRL(vc));
 
 	return 0;
 }
 
-static int dsi_vc_send_bta_sync(struct omap_dss_device *dssdev, int channel)
+static int dsi_vc_send_bta_sync(struct omap_dss_device *dssdev, int vc)
 {
 	struct dsi_data *dsi = to_dsi_data(dssdev);
 	DECLARE_COMPLETION_ONSTACK(completion);
 	int r = 0;
 	u32 err;
 
-	r = dsi_register_isr_vc(dsi, channel, dsi_completion_handler,
+	r = dsi_register_isr_vc(dsi, vc, dsi_completion_handler,
 			&completion, DSI_VC_IRQ_BTA);
 	if (r)
 		goto err0;
@@ -2577,7 +2577,7 @@ static int dsi_vc_send_bta_sync(struct omap_dss_device *dssdev, int channel)
 	if (r)
 		goto err1;
 
-	r = dsi_vc_send_bta(dsi, channel);
+	r = dsi_vc_send_bta(dsi, vc);
 	if (r)
 		goto err2;
 
@@ -2598,13 +2598,13 @@ static int dsi_vc_send_bta_sync(struct omap_dss_device *dssdev, int channel)
 	dsi_unregister_isr(dsi, dsi_completion_handler, &completion,
 			DSI_IRQ_ERROR_MASK);
 err1:
-	dsi_unregister_isr_vc(dsi, channel, dsi_completion_handler,
+	dsi_unregister_isr_vc(dsi, vc, dsi_completion_handler,
 			&completion, DSI_VC_IRQ_BTA);
 err0:
 	return r;
 }
 
-static inline void dsi_vc_write_long_header(struct dsi_data *dsi, int channel,
+static inline void dsi_vc_write_long_header(struct dsi_data *dsi, int vc,
 					    u8 data_type, u16 len, u8 ecc)
 {
 	u32 val;
@@ -2612,15 +2612,15 @@ static inline void dsi_vc_write_long_header(struct dsi_data *dsi, int channel,
 
 	WARN_ON(!dsi_bus_is_locked(dsi));
 
-	data_id = data_type | channel << 6;
+	data_id = data_type | vc << 6;
 
 	val = FLD_VAL(data_id, 7, 0) | FLD_VAL(len, 23, 8) |
 		FLD_VAL(ecc, 31, 24);
 
-	dsi_write_reg(dsi, DSI_VC_LONG_PACKET_HEADER(channel), val);
+	dsi_write_reg(dsi, DSI_VC_LONG_PACKET_HEADER(vc), val);
 }
 
-static inline void dsi_vc_write_long_payload(struct dsi_data *dsi, int channel,
+static inline void dsi_vc_write_long_payload(struct dsi_data *dsi, int vc,
 					     u8 b1, u8 b2, u8 b3, u8 b4)
 {
 	u32 val;
@@ -2630,7 +2630,7 @@ static inline void dsi_vc_write_long_payload(struct dsi_data *dsi, int channel,
 /*	DSSDBG("\twriting %02x, %02x, %02x, %02x (%#010x)\n",
 			b1, b2, b3, b4, val); */
 
-	dsi_write_reg(dsi, DSI_VC_LONG_PACKET_PAYLOAD(channel), val);
+	dsi_write_reg(dsi, DSI_VC_LONG_PACKET_PAYLOAD(vc), val);
 }
 
 static int dsi_vc_send_long(struct dsi_data *dsi,
@@ -2727,10 +2727,10 @@ static int dsi_vc_send_short(struct dsi_data *dsi,
 	return 0;
 }
 
-static int dsi_vc_send_null(struct dsi_data *dsi, int channel)
+static int dsi_vc_send_null(struct dsi_data *dsi, int vc)
 {
 	const struct mipi_dsi_msg msg = {
-		.channel = channel,
+		.channel = vc,
 		.type = MIPI_DSI_NULL_PACKET,
 	};
 
@@ -2774,7 +2774,7 @@ static int dsi_vc_write_common(struct omap_dss_device *dssdev,
 	return 0;
 }
 
-static int dsi_vc_read_rx_fifo(struct dsi_data *dsi, int channel, u8 *buf,
+static int dsi_vc_read_rx_fifo(struct dsi_data *dsi, int vc, u8 *buf,
 			       int buflen, enum dss_dsi_content_type type)
 {
 	u32 val;
@@ -2782,13 +2782,13 @@ static int dsi_vc_read_rx_fifo(struct dsi_data *dsi, int channel, u8 *buf,
 	int r;
 
 	/* RX_FIFO_NOT_EMPTY */
-	if (REG_GET(dsi, DSI_VC_CTRL(channel), 20, 20) == 0) {
+	if (REG_GET(dsi, DSI_VC_CTRL(vc), 20, 20) == 0) {
 		DSSERR("RX fifo empty when trying to read.\n");
 		r = -EIO;
 		goto err;
 	}
 
-	val = dsi_read_reg(dsi, DSI_VC_SHORT_PACKET_HEADER(channel));
+	val = dsi_read_reg(dsi, DSI_VC_SHORT_PACKET_HEADER(vc));
 	if (dsi->debug_read)
 		DSSDBG("\theader: %08x\n", val);
 	dt = FLD_GET(val, 5, 0);
@@ -2852,7 +2852,7 @@ static int dsi_vc_read_rx_fifo(struct dsi_data *dsi, int channel, u8 *buf,
 		for (w = 0; w < len + 2;) {
 			int b;
 			val = dsi_read_reg(dsi,
-				DSI_VC_SHORT_PACKET_HEADER(channel));
+				DSI_VC_SHORT_PACKET_HEADER(vc));
 			if (dsi->debug_read)
 				DSSDBG("\t\t%02x %02x %02x %02x\n",
 						(val >> 0) & 0xff,
@@ -2876,7 +2876,7 @@ static int dsi_vc_read_rx_fifo(struct dsi_data *dsi, int channel, u8 *buf,
 	}
 
 err:
-	DSSERR("dsi_vc_read_rx_fifo(ch %d type %s) failed\n", channel,
+	DSSERR("dsi_vc_read_rx_fifo(vc %d type %s) failed\n", vc,
 		type == DSS_DSI_CONTENT_GENERIC ? "GENERIC" : "DCS");
 
 	return r;
@@ -3631,7 +3631,7 @@ static int dsi_configure_pins(struct dsi_data *dsi,
 	return 0;
 }
 
-static void dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
+static void dsi_enable_video_output(struct omap_dss_device *dssdev, int vc)
 {
 	struct dsi_data *dsi = to_dsi_data(dssdev);
 	int bpp = mipi_dsi_pixel_format_to_bpp(dsi->pix_fmt);
@@ -3665,17 +3665,17 @@ static void dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
 		}
 
 		dsi_if_enable(dsi, false);
-		dsi_vc_enable(dsi, channel, false);
+		dsi_vc_enable(dsi, vc, false);
 
 		/* MODE, 1 = video mode */
-		REG_FLD_MOD(dsi, DSI_VC_CTRL(channel), 1, 4, 4);
+		REG_FLD_MOD(dsi, DSI_VC_CTRL(vc), 1, 4, 4);
 
 		word_count = DIV_ROUND_UP(dsi->vm.hactive * bpp, 8);
 
-		dsi_vc_write_long_header(dsi, channel, data_type,
+		dsi_vc_write_long_header(dsi, vc, data_type,
 				word_count, 0);
 
-		dsi_vc_enable(dsi, channel, true);
+		dsi_vc_enable(dsi, vc, true);
 		dsi_if_enable(dsi, true);
 	}
 
@@ -3688,7 +3688,7 @@ static void dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
 err_mgr_enable:
 	if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) {
 		dsi_if_enable(dsi, false);
-		dsi_vc_enable(dsi, channel, false);
+		dsi_vc_enable(dsi, vc, false);
 	}
 err_pix_fmt:
 	dsi_display_uninit_dispc(dsi);
@@ -3696,18 +3696,18 @@ static void dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
 	return;
 }
 
-static void dsi_disable_video_output(struct omap_dss_device *dssdev, int channel)
+static void dsi_disable_video_output(struct omap_dss_device *dssdev, int vc)
 {
 	struct dsi_data *dsi = to_dsi_data(dssdev);
 
 	if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) {
 		dsi_if_enable(dsi, false);
-		dsi_vc_enable(dsi, channel, false);
+		dsi_vc_enable(dsi, vc, false);
 
 		/* MODE, 0 = command mode */
-		REG_FLD_MOD(dsi, DSI_VC_CTRL(channel), 0, 4, 4);
+		REG_FLD_MOD(dsi, DSI_VC_CTRL(vc), 0, 4, 4);
 
-		dsi_vc_enable(dsi, channel, true);
+		dsi_vc_enable(dsi, vc, true);
 		dsi_if_enable(dsi, true);
 	}
 
@@ -3740,14 +3740,14 @@ static void dsi_update_screen_dispc(struct dsi_data *dsi)
 	unsigned int packet_len;
 	u32 l;
 	int r;
-	const unsigned channel = dsi->update_channel;
+	const unsigned vc = dsi->update_vc;
 	const unsigned int line_buf_size = dsi->line_buffer_size;
 	u16 w = dsi->vm.hactive;
 	u16 h = dsi->vm.vactive;
 
 	DSSDBG("dsi_update_screen_dispc(%dx%d)\n", w, h);
 
-	dsi_vc_config_source(dsi, channel, DSI_VC_SOURCE_VP);
+	dsi_vc_config_source(dsi, vc, DSI_VC_SOURCE_VP);
 
 	bytespp	= mipi_dsi_pixel_format_to_bpp(dsi->pix_fmt) / 8;
 	bytespl = w * bytespp;
@@ -3768,16 +3768,16 @@ static void dsi_update_screen_dispc(struct dsi_data *dsi)
 		total_len += (bytespf % packet_payload) + 1;
 
 	l = FLD_VAL(total_len, 23, 0); /* TE_SIZE */
-	dsi_write_reg(dsi, DSI_VC_TE(channel), l);
+	dsi_write_reg(dsi, DSI_VC_TE(vc), l);
 
-	dsi_vc_write_long_header(dsi, channel, MIPI_DSI_DCS_LONG_WRITE,
+	dsi_vc_write_long_header(dsi, vc, MIPI_DSI_DCS_LONG_WRITE,
 		packet_len, 0);
 
 	if (dsi->te_enabled)
 		l = FLD_MOD(l, 1, 30, 30); /* TE_EN */
 	else
 		l = FLD_MOD(l, 1, 31, 31); /* TE_START */
-	dsi_write_reg(dsi, DSI_VC_TE(channel), l);
+	dsi_write_reg(dsi, DSI_VC_TE(vc), l);
 
 	/* We put SIDLEMODE to no-idle for the duration of the transfer,
 	 * because DSS interrupts are not capable of waking up the CPU and the
@@ -3800,7 +3800,7 @@ static void dsi_update_screen_dispc(struct dsi_data *dsi)
 		 * for TE is longer than the timer allows */
 		REG_FLD_MOD(dsi, DSI_TIMING2, 0, 15, 15); /* LP_RX_TO */
 
-		dsi_vc_send_bta(dsi, channel);
+		dsi_vc_send_bta(dsi, vc);
 
 #ifdef DSI_CATCH_MISSING_TE
 		mod_timer(&dsi->te_timer, jiffies + msecs_to_jiffies(250));
@@ -3897,7 +3897,7 @@ static int _dsi_send_nop(struct dsi_data *dsi, int channel)
 	return _omap_dsi_host_transfer(dsi, &msg);
 }
 
-static int dsi_update_channel(struct omap_dss_device *dssdev, int channel)
+static int dsi_update_channel(struct omap_dss_device *dssdev, int vc)
 {
 	struct dsi_data *dsi = to_dsi_data(dssdev);
 	int r;
@@ -3914,7 +3914,7 @@ static int dsi_update_channel(struct omap_dss_device *dssdev, int channel)
 		goto err;
 	}
 
-	DSSDBG("dsi_update_channel: %d", channel);
+	DSSDBG("dsi_update_channel: %d", vc);
 
 	dsi_set_ulps_auto(dsi, false);
 
@@ -3923,13 +3923,13 @@ static int dsi_update_channel(struct omap_dss_device *dssdev, int channel)
 	 * updates stop working. This is probably related to DSI spec stating
 	 * that the DSI host should transition to LP at least once per frame.
 	 */
-	r = _dsi_send_nop(dsi, channel);
+	r = _dsi_send_nop(dsi, vc);
 	if (r < 0) {
 		DSSWARN("failed to send nop between frames: %d\n", r);
 		goto err;
 	}
 
-	dsi->update_channel = channel;
+	dsi->update_vc = vc;
 
 	if (dsi->te_enabled && dsi->te_gpio) {
 		schedule_delayed_work(&dsi->te_timeout_work,
-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v5 11/29] drm/omap: dsi: pass vc to various functions
  2020-12-08 12:28 [PATCH v5 00/29] Convert DSI code to use drm_mipi_dsi and drm_panel (second half) Tomi Valkeinen
                   ` (9 preceding siblings ...)
  2020-12-08 12:28 ` [PATCH v5 10/29] drm/omap: dsi: rename 'channel' to 'vc' Tomi Valkeinen
@ 2020-12-08 12:28 ` Tomi Valkeinen
  2020-12-08 15:38   ` Laurent Pinchart
  2020-12-14 15:37   ` Sebastian Reichel
  2020-12-08 12:28 ` [PATCH v5 12/29] drm/omap: dsi: untangle vc & channel Tomi Valkeinen
                   ` (17 subsequent siblings)
  28 siblings, 2 replies; 72+ messages in thread
From: Tomi Valkeinen @ 2020-12-08 12:28 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Nikhil Devshatwar, dri-devel
  Cc: linux-omap, Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg,
	Tomi Valkeinen

To start fixing the issues related to channels and vcs described in the
previous commit, pass vc to various functions which will need it do
properly handle different DSI channels and VCs.

No functional changes.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/gpu/drm/omapdrm/dss/dsi.c | 54 ++++++++++++++++---------------
 1 file changed, 28 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index 273159e8f992..8d8412199693 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -214,9 +214,9 @@ static void dsi_set_ulps_auto(struct dsi_data *dsi, bool enable);
 static int dsi_display_init_dispc(struct dsi_data *dsi);
 static void dsi_display_uninit_dispc(struct dsi_data *dsi);
 
-static int dsi_vc_send_null(struct dsi_data *dsi, int vc);
+static int dsi_vc_send_null(struct dsi_data *dsi, int vc, int channel);
 
-static ssize_t _omap_dsi_host_transfer(struct dsi_data *dsi,
+static ssize_t _omap_dsi_host_transfer(struct dsi_data *dsi, int vc,
 				       const struct mipi_dsi_msg *msg);
 
 static void dsi_display_disable(struct omap_dss_device *dssdev);
@@ -2455,7 +2455,7 @@ static void dsi_vc_enable_hs(struct omap_dss_device *dssdev, int vc,
 
 	/* start the DDR clock by sending a NULL packet */
 	if (dsi->vm_timings.ddr_clk_always_on && enable)
-		dsi_vc_send_null(dsi, vc);
+		dsi_vc_send_null(dsi, vc, dsi->dsidev->channel);
 
 	dsi->in_lp_mode = !enable;
 }
@@ -2605,7 +2605,8 @@ static int dsi_vc_send_bta_sync(struct omap_dss_device *dssdev, int vc)
 }
 
 static inline void dsi_vc_write_long_header(struct dsi_data *dsi, int vc,
-					    u8 data_type, u16 len, u8 ecc)
+					    int channel, u8 data_type, u16 len,
+					    u8 ecc)
 {
 	u32 val;
 	u8 data_id;
@@ -2633,7 +2634,7 @@ static inline void dsi_vc_write_long_payload(struct dsi_data *dsi, int vc,
 	dsi_write_reg(dsi, DSI_VC_LONG_PACKET_PAYLOAD(vc), val);
 }
 
-static int dsi_vc_send_long(struct dsi_data *dsi,
+static int dsi_vc_send_long(struct dsi_data *dsi, int vc,
 			    const struct mipi_dsi_msg *msg)
 {
 	/*u32 val; */
@@ -2653,7 +2654,7 @@ static int dsi_vc_send_long(struct dsi_data *dsi,
 
 	dsi_vc_config_source(dsi, msg->channel, DSI_VC_SOURCE_L4);
 
-	dsi_vc_write_long_header(dsi, msg->channel, msg->type, msg->tx_len, 0);
+	dsi_vc_write_long_header(dsi, vc, msg->channel, msg->type, msg->tx_len, 0);
 
 	p = msg->tx_buf;
 	for (i = 0; i < msg->tx_len >> 2; i++) {
@@ -2696,7 +2697,7 @@ static int dsi_vc_send_long(struct dsi_data *dsi,
 	return r;
 }
 
-static int dsi_vc_send_short(struct dsi_data *dsi,
+static int dsi_vc_send_short(struct dsi_data *dsi, int vc,
 			     const struct mipi_dsi_msg *msg)
 {
 	struct mipi_dsi_packet pkt;
@@ -2727,26 +2728,26 @@ static int dsi_vc_send_short(struct dsi_data *dsi,
 	return 0;
 }
 
-static int dsi_vc_send_null(struct dsi_data *dsi, int vc)
+static int dsi_vc_send_null(struct dsi_data *dsi, int vc, int channel)
 {
 	const struct mipi_dsi_msg msg = {
 		.channel = vc,
 		.type = MIPI_DSI_NULL_PACKET,
 	};
 
-	return dsi_vc_send_long(dsi, &msg);
+	return dsi_vc_send_long(dsi, vc, &msg);
 }
 
-static int dsi_vc_write_common(struct omap_dss_device *dssdev,
+static int dsi_vc_write_common(struct omap_dss_device *dssdev, int vc,
 			       const struct mipi_dsi_msg *msg)
 {
 	struct dsi_data *dsi = to_dsi_data(dssdev);
 	int r;
 
 	if (mipi_dsi_packet_format_is_short(msg->type))
-		r = dsi_vc_send_short(dsi, msg);
+		r = dsi_vc_send_short(dsi, vc, msg);
 	else
-		r = dsi_vc_send_long(dsi, msg);
+		r = dsi_vc_send_long(dsi, vc, msg);
 
 	if (r < 0)
 		return r;
@@ -2882,7 +2883,7 @@ static int dsi_vc_read_rx_fifo(struct dsi_data *dsi, int vc, u8 *buf,
 	return r;
 }
 
-static int dsi_vc_dcs_read(struct omap_dss_device *dssdev,
+static int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int vc,
 			   const struct mipi_dsi_msg *msg)
 {
 	struct dsi_data *dsi = to_dsi_data(dssdev);
@@ -2893,7 +2894,7 @@ static int dsi_vc_dcs_read(struct omap_dss_device *dssdev,
 	if (dsi->debug_read)
 		DSSDBG("%s(ch %d, cmd %x)\n", __func__, channel, cmd);
 
-	r = dsi_vc_send_short(dsi, msg);
+	r = dsi_vc_send_short(dsi, vc, msg);
 	if (r)
 		goto err;
 
@@ -2917,13 +2918,13 @@ static int dsi_vc_dcs_read(struct omap_dss_device *dssdev,
 	return r;
 }
 
-static int dsi_vc_generic_read(struct omap_dss_device *dssdev,
+static int dsi_vc_generic_read(struct omap_dss_device *dssdev, int vc,
 			       const struct mipi_dsi_msg *msg)
 {
 	struct dsi_data *dsi = to_dsi_data(dssdev);
 	int r;
 
-	r = dsi_vc_send_short(dsi, msg);
+	r = dsi_vc_send_short(dsi, vc, msg);
 	if (r)
 		goto err;
 
@@ -3672,7 +3673,7 @@ static void dsi_enable_video_output(struct omap_dss_device *dssdev, int vc)
 
 		word_count = DIV_ROUND_UP(dsi->vm.hactive * bpp, 8);
 
-		dsi_vc_write_long_header(dsi, vc, data_type,
+		dsi_vc_write_long_header(dsi, vc, dsi->dsidev->channel, data_type,
 				word_count, 0);
 
 		dsi_vc_enable(dsi, vc, true);
@@ -3770,7 +3771,7 @@ static void dsi_update_screen_dispc(struct dsi_data *dsi)
 	l = FLD_VAL(total_len, 23, 0); /* TE_SIZE */
 	dsi_write_reg(dsi, DSI_VC_TE(vc), l);
 
-	dsi_vc_write_long_header(dsi, vc, MIPI_DSI_DCS_LONG_WRITE,
+	dsi_vc_write_long_header(dsi, vc, dsi->dsidev->channel, MIPI_DSI_DCS_LONG_WRITE,
 		packet_len, 0);
 
 	if (dsi->te_enabled)
@@ -3882,7 +3883,7 @@ static int _dsi_update(struct dsi_data *dsi)
 	return 0;
 }
 
-static int _dsi_send_nop(struct dsi_data *dsi, int channel)
+static int _dsi_send_nop(struct dsi_data *dsi, int vc, int channel)
 {
 	const u8 payload[] = { MIPI_DCS_NOP };
 	const struct mipi_dsi_msg msg = {
@@ -3894,7 +3895,7 @@ static int _dsi_send_nop(struct dsi_data *dsi, int channel)
 
 	WARN_ON(!dsi_bus_is_locked(dsi));
 
-	return _omap_dsi_host_transfer(dsi, &msg);
+	return _omap_dsi_host_transfer(dsi, vc, &msg);
 }
 
 static int dsi_update_channel(struct omap_dss_device *dssdev, int vc)
@@ -3923,7 +3924,7 @@ static int dsi_update_channel(struct omap_dss_device *dssdev, int vc)
 	 * updates stop working. This is probably related to DSI spec stating
 	 * that the DSI host should transition to LP at least once per frame.
 	 */
-	r = _dsi_send_nop(dsi, vc);
+	r = _dsi_send_nop(dsi, vc, dsi->dsidev->channel);
 	if (r < 0) {
 		DSSWARN("failed to send nop between frames: %d\n", r);
 		goto err;
@@ -4885,7 +4886,7 @@ static enum omap_channel dsi_get_dispc_channel(struct dsi_data *dsi)
 	}
 }
 
-static ssize_t _omap_dsi_host_transfer(struct dsi_data *dsi,
+static ssize_t _omap_dsi_host_transfer(struct dsi_data *dsi, int vc,
 				       const struct mipi_dsi_msg *msg)
 {
 	struct omap_dss_device *dssdev = &dsi->output;
@@ -4905,15 +4906,15 @@ static ssize_t _omap_dsi_host_transfer(struct dsi_data *dsi,
 	case MIPI_DSI_DCS_LONG_WRITE:
 	case MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE:
 	case MIPI_DSI_NULL_PACKET:
-		r = dsi_vc_write_common(dssdev, msg);
+		r = dsi_vc_write_common(dssdev, vc, msg);
 		break;
 	case MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM:
 	case MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM:
 	case MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM:
-		r = dsi_vc_generic_read(dssdev, msg);
+		r = dsi_vc_generic_read(dssdev, vc, msg);
 		break;
 	case MIPI_DSI_DCS_READ:
-		r = dsi_vc_dcs_read(dssdev, msg);
+		r = dsi_vc_dcs_read(dssdev, vc, msg);
 		break;
 	default:
 		r = -EINVAL;
@@ -4941,12 +4942,13 @@ static ssize_t omap_dsi_host_transfer(struct mipi_dsi_host *host,
 {
 	struct dsi_data *dsi = host_to_omap(host);
 	int r;
+	int vc = VC_DEFAULT;
 
 	dsi_bus_lock(dsi);
 
 	if (dsi->video_enabled) {
 		dsi_set_ulps_auto(dsi, false);
-		r = _omap_dsi_host_transfer(dsi, msg);
+		r = _omap_dsi_host_transfer(dsi, vc, msg);
 		dsi_set_ulps_auto(dsi, true);
 	} else {
 		r = -EIO;
-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v5 12/29] drm/omap: dsi: untangle vc & channel
  2020-12-08 12:28 [PATCH v5 00/29] Convert DSI code to use drm_mipi_dsi and drm_panel (second half) Tomi Valkeinen
                   ` (10 preceding siblings ...)
  2020-12-08 12:28 ` [PATCH v5 11/29] drm/omap: dsi: pass vc to various functions Tomi Valkeinen
@ 2020-12-08 12:28 ` Tomi Valkeinen
  2020-12-08 15:41   ` Laurent Pinchart
  2020-12-08 12:28 ` [PATCH v5 13/29] drm/omap: dsi: skip dsi_vc_enable_hs when already in correct mode Tomi Valkeinen
                   ` (16 subsequent siblings)
  28 siblings, 1 reply; 72+ messages in thread
From: Tomi Valkeinen @ 2020-12-08 12:28 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Nikhil Devshatwar, dri-devel
  Cc: linux-omap, Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg,
	Tomi Valkeinen

DSI virtual channel and hardware VC blocks have gotten tangled as
described in the previous commits. This has not caused any issues, as
the value for both is 0, so it happens to work.

To fix the issue, change the code to use the correct one of the two.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/gpu/drm/omapdrm/dss/dsi.c | 43 +++++++++++++++----------------
 1 file changed, 21 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index 8d8412199693..a1f3623f45b1 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -2613,7 +2613,7 @@ static inline void dsi_vc_write_long_header(struct dsi_data *dsi, int vc,
 
 	WARN_ON(!dsi_bus_is_locked(dsi));
 
-	data_id = data_type | vc << 6;
+	data_id = data_type | channel << 6;
 
 	val = FLD_VAL(data_id, 7, 0) | FLD_VAL(len, 23, 8) |
 		FLD_VAL(ecc, 31, 24);
@@ -2647,12 +2647,12 @@ static int dsi_vc_send_long(struct dsi_data *dsi, int vc,
 		DSSDBG("dsi_vc_send_long, %d bytes\n", msg->tx_len);
 
 	/* len + header */
-	if (dsi->vc[msg->channel].tx_fifo_size * 32 * 4 < msg->tx_len + 4) {
+	if (dsi->vc[vc].tx_fifo_size * 32 * 4 < msg->tx_len + 4) {
 		DSSERR("unable to send long packet: packet too long.\n");
 		return -EINVAL;
 	}
 
-	dsi_vc_config_source(dsi, msg->channel, DSI_VC_SOURCE_L4);
+	dsi_vc_config_source(dsi, vc, DSI_VC_SOURCE_L4);
 
 	dsi_vc_write_long_header(dsi, vc, msg->channel, msg->type, msg->tx_len, 0);
 
@@ -2666,7 +2666,7 @@ static int dsi_vc_send_long(struct dsi_data *dsi, int vc,
 		b3 = *p++;
 		b4 = *p++;
 
-		dsi_vc_write_long_payload(dsi, msg->channel, b1, b2, b3, b4);
+		dsi_vc_write_long_payload(dsi, vc, b1, b2, b3, b4);
 	}
 
 	i = msg->tx_len % 4;
@@ -2691,7 +2691,7 @@ static int dsi_vc_send_long(struct dsi_data *dsi, int vc,
 			break;
 		}
 
-		dsi_vc_write_long_payload(dsi, msg->channel, b1, b2, b3, 0);
+		dsi_vc_write_long_payload(dsi, vc, b1, b2, b3, 0);
 	}
 
 	return r;
@@ -2711,11 +2711,11 @@ static int dsi_vc_send_short(struct dsi_data *dsi, int vc,
 
 	if (dsi->debug_write)
 		DSSDBG("dsi_vc_send_short(ch%d, dt %#x, b1 %#x, b2 %#x)\n",
-		       msg->channel, msg->type, pkt.header[1], pkt.header[2]);
+		       vc, msg->type, pkt.header[1], pkt.header[2]);
 
-	dsi_vc_config_source(dsi, msg->channel, DSI_VC_SOURCE_L4);
+	dsi_vc_config_source(dsi, vc, DSI_VC_SOURCE_L4);
 
-	if (FLD_GET(dsi_read_reg(dsi, DSI_VC_CTRL(msg->channel)), 16, 16)) {
+	if (FLD_GET(dsi_read_reg(dsi, DSI_VC_CTRL(vc)), 16, 16)) {
 		DSSERR("ERROR FIFO FULL, aborting transfer\n");
 		return -EINVAL;
 	}
@@ -2723,7 +2723,7 @@ static int dsi_vc_send_short(struct dsi_data *dsi, int vc,
 	r = pkt.header[3] << 24 | pkt.header[2] << 16 | pkt.header[1] << 8 |
 	    pkt.header[0];
 
-	dsi_write_reg(dsi, DSI_VC_SHORT_PACKET_HEADER(msg->channel), r);
+	dsi_write_reg(dsi, DSI_VC_SHORT_PACKET_HEADER(vc), r);
 
 	return 0;
 }
@@ -2731,7 +2731,7 @@ static int dsi_vc_send_short(struct dsi_data *dsi, int vc,
 static int dsi_vc_send_null(struct dsi_data *dsi, int vc, int channel)
 {
 	const struct mipi_dsi_msg msg = {
-		.channel = vc,
+		.channel = channel,
 		.type = MIPI_DSI_NULL_PACKET,
 	};
 
@@ -2759,16 +2759,16 @@ static int dsi_vc_write_common(struct omap_dss_device *dssdev, int vc,
 	 * In that case we can return early.
 	 */
 
-	r = dsi_vc_send_bta_sync(dssdev, msg->channel);
+	r = dsi_vc_send_bta_sync(dssdev, vc);
 	if (r) {
 		DSSERR("bta sync failed\n");
 		return r;
 	}
 
 	/* RX_FIFO_NOT_EMPTY */
-	if (REG_GET(dsi, DSI_VC_CTRL(msg->channel), 20, 20)) {
+	if (REG_GET(dsi, DSI_VC_CTRL(vc), 20, 20)) {
 		DSSERR("rx fifo not empty after write, dumping data:\n");
-		dsi_vc_flush_receive_data(dsi, msg->channel);
+		dsi_vc_flush_receive_data(dsi, vc);
 		return -EIO;
 	}
 
@@ -2888,21 +2888,20 @@ static int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int vc,
 {
 	struct dsi_data *dsi = to_dsi_data(dssdev);
 	u8 cmd = ((u8 *)msg->tx_buf)[0];
-	u8 channel = msg->channel;
 	int r;
 
 	if (dsi->debug_read)
-		DSSDBG("%s(ch %d, cmd %x)\n", __func__, channel, cmd);
+		DSSDBG("%s(ch %d, cmd %x)\n", __func__, vc, cmd);
 
 	r = dsi_vc_send_short(dsi, vc, msg);
 	if (r)
 		goto err;
 
-	r = dsi_vc_send_bta_sync(dssdev, channel);
+	r = dsi_vc_send_bta_sync(dssdev, vc);
 	if (r)
 		goto err;
 
-	r = dsi_vc_read_rx_fifo(dsi, channel, msg->rx_buf, msg->rx_len,
+	r = dsi_vc_read_rx_fifo(dsi, vc, msg->rx_buf, msg->rx_len,
 		DSS_DSI_CONTENT_DCS);
 	if (r < 0)
 		goto err;
@@ -2914,7 +2913,7 @@ static int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int vc,
 
 	return 0;
 err:
-	DSSERR("%s(ch %d, cmd 0x%02x) failed\n", __func__,  msg->channel, cmd);
+	DSSERR("%s(ch %d, cmd 0x%02x) failed\n", __func__,  vc, cmd);
 	return r;
 }
 
@@ -2928,11 +2927,11 @@ static int dsi_vc_generic_read(struct omap_dss_device *dssdev, int vc,
 	if (r)
 		goto err;
 
-	r = dsi_vc_send_bta_sync(dssdev, msg->channel);
+	r = dsi_vc_send_bta_sync(dssdev, vc);
 	if (r)
 		goto err;
 
-	r = dsi_vc_read_rx_fifo(dsi, msg->channel, msg->rx_buf, msg->rx_len,
+	r = dsi_vc_read_rx_fifo(dsi, vc, msg->rx_buf, msg->rx_len,
 		DSS_DSI_CONTENT_GENERIC);
 	if (r < 0)
 		goto err;
@@ -2944,7 +2943,7 @@ static int dsi_vc_generic_read(struct omap_dss_device *dssdev, int vc,
 
 	return 0;
 err:
-	DSSERR("%s(ch %d, reqlen %d) failed\n", __func__,  msg->channel, msg->tx_len);
+	DSSERR("%s(ch %d, reqlen %d) failed\n", __func__,  vc, msg->tx_len);
 	return r;
 }
 
@@ -4893,7 +4892,7 @@ static ssize_t _omap_dsi_host_transfer(struct dsi_data *dsi, int vc,
 	int r;
 
 	if (!!(msg->flags & MIPI_DSI_MSG_USE_LPM) != dsi->in_lp_mode)
-		dsi_vc_enable_hs(dssdev, msg->channel,
+		dsi_vc_enable_hs(dssdev, vc,
 				 !(msg->flags & MIPI_DSI_MSG_USE_LPM));
 
 	switch (msg->type) {
-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v5 13/29] drm/omap: dsi: skip dsi_vc_enable_hs when already in correct mode
  2020-12-08 12:28 [PATCH v5 00/29] Convert DSI code to use drm_mipi_dsi and drm_panel (second half) Tomi Valkeinen
                   ` (11 preceding siblings ...)
  2020-12-08 12:28 ` [PATCH v5 12/29] drm/omap: dsi: untangle vc & channel Tomi Valkeinen
@ 2020-12-08 12:28 ` Tomi Valkeinen
  2020-12-14 15:50   ` Sebastian Reichel
  2020-12-08 12:28 ` [PATCH v5 14/29] drm/omap: dsi: enable HS before sending the frame Tomi Valkeinen
                   ` (15 subsequent siblings)
  28 siblings, 1 reply; 72+ messages in thread
From: Tomi Valkeinen @ 2020-12-08 12:28 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Nikhil Devshatwar, dri-devel
  Cc: linux-omap, Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg,
	Tomi Valkeinen

Simplify and optimize dsi_vc_enable_hs() so that it can be called
without checking the current HS/LP mode. Make dsi_vc_enable_hs() return
if the VC is already in the correct mode.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/gpu/drm/omapdrm/dss/dsi.c | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index a1f3623f45b1..544f5f1eed91 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -341,7 +341,6 @@ struct dsi_data {
 	int irq;
 
 	bool is_enabled;
-	bool in_lp_mode;
 
 	struct clk *dss_clk;
 	struct regmap *syscon;
@@ -2441,6 +2440,9 @@ static void dsi_vc_enable_hs(struct omap_dss_device *dssdev, int vc,
 
 	DSSDBG("dsi_vc_enable_hs(%d, %d)\n", vc, enable);
 
+	if (REG_GET(dsi, DSI_VC_CTRL(vc), 9, 9) == enable)
+		return;
+
 	WARN_ON(!dsi_bus_is_locked(dsi));
 
 	dsi_vc_enable(dsi, vc, 0);
@@ -2456,8 +2458,6 @@ static void dsi_vc_enable_hs(struct omap_dss_device *dssdev, int vc,
 	/* start the DDR clock by sending a NULL packet */
 	if (dsi->vm_timings.ddr_clk_always_on && enable)
 		dsi_vc_send_null(dsi, vc, dsi->dsidev->channel);
-
-	dsi->in_lp_mode = !enable;
 }
 
 static void dsi_vc_flush_long_data(struct dsi_data *dsi, int vc)
@@ -4891,9 +4891,7 @@ static ssize_t _omap_dsi_host_transfer(struct dsi_data *dsi, int vc,
 	struct omap_dss_device *dssdev = &dsi->output;
 	int r;
 
-	if (!!(msg->flags & MIPI_DSI_MSG_USE_LPM) != dsi->in_lp_mode)
-		dsi_vc_enable_hs(dssdev, vc,
-				 !(msg->flags & MIPI_DSI_MSG_USE_LPM));
+	dsi_vc_enable_hs(dssdev, vc, !(msg->flags & MIPI_DSI_MSG_USE_LPM));
 
 	switch (msg->type) {
 	case MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM:
-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v5 14/29] drm/omap: dsi: enable HS before sending the frame
  2020-12-08 12:28 [PATCH v5 00/29] Convert DSI code to use drm_mipi_dsi and drm_panel (second half) Tomi Valkeinen
                   ` (12 preceding siblings ...)
  2020-12-08 12:28 ` [PATCH v5 13/29] drm/omap: dsi: skip dsi_vc_enable_hs when already in correct mode Tomi Valkeinen
@ 2020-12-08 12:28 ` Tomi Valkeinen
  2020-12-08 15:42   ` Laurent Pinchart
  2020-12-14 15:51   ` Sebastian Reichel
  2020-12-08 12:28 ` [PATCH v5 15/29] drm/omap: dsi: use separate VCs for cmd and video Tomi Valkeinen
                   ` (14 subsequent siblings)
  28 siblings, 2 replies; 72+ messages in thread
From: Tomi Valkeinen @ 2020-12-08 12:28 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Nikhil Devshatwar, dri-devel
  Cc: linux-omap, Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg,
	Tomi Valkeinen

We currently use a single VC for sending commands and pixel data. The
LP/HS mode for pixel data is correctly set to HS by accident, as we have
set the VC to HS already earlier.

However, if we use a different VC for video data, the VC is in LP mode.
Fix this by always enabling HS mode before starting a frame update.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/gpu/drm/omapdrm/dss/dsi.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index 544f5f1eed91..9d210a020916 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -3918,6 +3918,8 @@ static int dsi_update_channel(struct omap_dss_device *dssdev, int vc)
 
 	dsi_set_ulps_auto(dsi, false);
 
+	dsi_vc_enable_hs(dssdev, vc, true);
+
 	/*
 	 * Send NOP between the frames. If we don't send something here, the
 	 * updates stop working. This is probably related to DSI spec stating
-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v5 15/29] drm/omap: dsi: use separate VCs for cmd and video
  2020-12-08 12:28 [PATCH v5 00/29] Convert DSI code to use drm_mipi_dsi and drm_panel (second half) Tomi Valkeinen
                   ` (13 preceding siblings ...)
  2020-12-08 12:28 ` [PATCH v5 14/29] drm/omap: dsi: enable HS before sending the frame Tomi Valkeinen
@ 2020-12-08 12:28 ` Tomi Valkeinen
  2020-12-14 15:54   ` Sebastian Reichel
  2020-12-08 12:28 ` [PATCH v5 16/29] drm/panel: panel-dsi-cm: remove extra 'if' Tomi Valkeinen
                   ` (13 subsequent siblings)
  28 siblings, 1 reply; 72+ messages in thread
From: Tomi Valkeinen @ 2020-12-08 12:28 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Nikhil Devshatwar, dri-devel
  Cc: linux-omap, Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg,
	Tomi Valkeinen

For command mode panels we can use a single VC for sending command and
video data, even if we have to change the data source for that VC when
going from command to video or vice versa.

However, with video mode panels we want to keep the pixel data VC
enabled, and use another VC for command data, and the commands will get
interleaved into the pixel data.

This patch makes the driver use VC0 for commands and VC1 for video.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/gpu/drm/omapdrm/dss/dsi.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index 9d210a020916..0795efdd8902 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -452,7 +452,9 @@ static bool dsi_perf;
 module_param(dsi_perf, bool, 0644);
 #endif
 
-#define VC_DEFAULT 0
+/* Note: for some reason video mode seems to work only if VC_VIDEO is 0 */
+#define VC_VIDEO	0
+#define VC_CMD		1
 
 #define drm_bridge_to_dsi(bridge) \
 	container_of(bridge, struct dsi_data, bridge)
@@ -3723,7 +3725,7 @@ static void dsi_disable_video_outputs(struct omap_dss_device *dssdev)
 	dsi_bus_lock(dsi);
 	dsi->video_enabled = false;
 
-	dsi_disable_video_output(dssdev, VC_DEFAULT);
+	dsi_disable_video_output(dssdev, VC_VIDEO);
 
 	dsi_display_disable(dssdev);
 
@@ -3951,7 +3953,7 @@ static int dsi_update_channel(struct omap_dss_device *dssdev, int vc)
 
 static int dsi_update_all(struct omap_dss_device *dssdev)
 {
-	return dsi_update_channel(dssdev, VC_DEFAULT);
+	return dsi_update_channel(dssdev, VC_VIDEO);
 }
 
 /* Display funcs */
@@ -4184,7 +4186,7 @@ static void dsi_enable_video_outputs(struct omap_dss_device *dssdev)
 
 	dsi_display_enable(dssdev);
 
-	dsi_enable_video_output(dssdev, VC_DEFAULT);
+	dsi_enable_video_output(dssdev, VC_VIDEO);
 
 	dsi->video_enabled = true;
 
@@ -4941,7 +4943,7 @@ static ssize_t omap_dsi_host_transfer(struct mipi_dsi_host *host,
 {
 	struct dsi_data *dsi = host_to_omap(host);
 	int r;
-	int vc = VC_DEFAULT;
+	int vc = VC_CMD;
 
 	dsi_bus_lock(dsi);
 
-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v5 16/29] drm/panel: panel-dsi-cm: remove extra 'if'
  2020-12-08 12:28 [PATCH v5 00/29] Convert DSI code to use drm_mipi_dsi and drm_panel (second half) Tomi Valkeinen
                   ` (14 preceding siblings ...)
  2020-12-08 12:28 ` [PATCH v5 15/29] drm/omap: dsi: use separate VCs for cmd and video Tomi Valkeinen
@ 2020-12-08 12:28 ` Tomi Valkeinen
  2020-12-08 15:42   ` Laurent Pinchart
  2020-12-14 15:55   ` Sebastian Reichel
  2020-12-08 12:28 ` [PATCH v5 17/29] drm/panel: panel-dsi-cm: add panel database to driver Tomi Valkeinen
                   ` (12 subsequent siblings)
  28 siblings, 2 replies; 72+ messages in thread
From: Tomi Valkeinen @ 2020-12-08 12:28 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Nikhil Devshatwar, dri-devel
  Cc: linux-omap, Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg,
	Tomi Valkeinen

We have a useless 'if' in the dsicm_bl_update_status(), a left over from
the conversion to DRM model. Drop the if.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: Sam Ravnborg <sam@ravnborg.org>
---
 drivers/gpu/drm/panel/panel-dsi-cm.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-dsi-cm.c b/drivers/gpu/drm/panel/panel-dsi-cm.c
index 556f9a2c5c0c..fa564aad7f25 100644
--- a/drivers/gpu/drm/panel/panel-dsi-cm.c
+++ b/drivers/gpu/drm/panel/panel-dsi-cm.c
@@ -202,11 +202,9 @@ static int dsicm_bl_update_status(struct backlight_device *dev)
 
 	mutex_lock(&ddata->lock);
 
-	if (ddata->enabled) {
-		if (!r)
-			r = dsicm_dcs_write_1(
-				ddata, MIPI_DCS_SET_DISPLAY_BRIGHTNESS, level);
-	}
+	if (ddata->enabled)
+		r = dsicm_dcs_write_1(ddata, MIPI_DCS_SET_DISPLAY_BRIGHTNESS,
+				      level);
 
 	mutex_unlock(&ddata->lock);
 
-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v5 17/29] drm/panel: panel-dsi-cm: add panel database to driver
  2020-12-08 12:28 [PATCH v5 00/29] Convert DSI code to use drm_mipi_dsi and drm_panel (second half) Tomi Valkeinen
                   ` (15 preceding siblings ...)
  2020-12-08 12:28 ` [PATCH v5 16/29] drm/panel: panel-dsi-cm: remove extra 'if' Tomi Valkeinen
@ 2020-12-08 12:28 ` Tomi Valkeinen
  2020-12-14 16:04   ` Sebastian Reichel
  2020-12-08 12:28 ` [PATCH v5 18/29] drm/panel: panel-dsi-cm: drop unneeded includes Tomi Valkeinen
                   ` (11 subsequent siblings)
  28 siblings, 1 reply; 72+ messages in thread
From: Tomi Valkeinen @ 2020-12-08 12:28 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Nikhil Devshatwar, dri-devel
  Cc: linux-omap, Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg,
	Tomi Valkeinen

Add a panel database to the driver instead of reading propertes from DT
data. This is similar to panel-simple, and I believe it's more future
safe way to handle the panels.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: Sam Ravnborg <sam@ravnborg.org>
---
 drivers/gpu/drm/panel/panel-dsi-cm.c | 107 +++++++++++++++++----------
 1 file changed, 69 insertions(+), 38 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-dsi-cm.c b/drivers/gpu/drm/panel/panel-dsi-cm.c
index fa564aad7f25..3fb5b2856283 100644
--- a/drivers/gpu/drm/panel/panel-dsi-cm.c
+++ b/drivers/gpu/drm/panel/panel-dsi-cm.c
@@ -21,10 +21,7 @@
 #include <drm/drm_modes.h>
 #include <drm/drm_panel.h>
 
-#include <video/display_timing.h>
 #include <video/mipi_display.h>
-#include <video/of_display_timing.h>
-#include <video/videomode.h>
 
 #define DCS_GET_ID1		0xda
 #define DCS_GET_ID2		0xdb
@@ -32,6 +29,18 @@
 
 #define DCS_REGULATOR_SUPPLY_NUM 2
 
+static const struct of_device_id dsicm_of_match[];
+
+struct dsic_panel_data {
+	u32 xres;
+	u32 yres;
+	u32 refresh;
+	u32 width_mm;
+	u32 height_mm;
+	u32 max_hs_rate;
+	u32 max_lp_rate;
+};
+
 struct panel_drv_data {
 	struct mipi_dsi_device *dsi;
 	struct drm_panel panel;
@@ -47,16 +56,14 @@ struct panel_drv_data {
 					 */
 	unsigned long	hw_guard_wait;	/* max guard time in jiffies */
 
-	/* panel HW configuration from DT or platform data */
+	const struct dsic_panel_data *panel_data;
+
 	struct gpio_desc *reset_gpio;
 
 	struct regulator_bulk_data supplies[DCS_REGULATOR_SUPPLY_NUM];
 
 	bool use_dsi_backlight;
 
-	int width_mm;
-	int height_mm;
-
 	/* runtime variables */
 	bool enabled;
 
@@ -450,11 +457,8 @@ static int dsicm_get_modes(struct drm_panel *panel,
 		return -ENOMEM;
 	}
 
-	drm_mode_set_name(mode);
-	mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
-
-	connector->display_info.width_mm = ddata->width_mm;
-	connector->display_info.height_mm = ddata->height_mm;
+	connector->display_info.width_mm = ddata->panel_data->width_mm;
+	connector->display_info.height_mm = ddata->panel_data->height_mm;
 
 	drm_mode_probed_add(connector, mode);
 
@@ -471,15 +475,10 @@ static const struct drm_panel_funcs dsicm_panel_funcs = {
 
 static int dsicm_probe_of(struct mipi_dsi_device *dsi)
 {
-	struct device_node *node = dsi->dev.of_node;
 	struct backlight_device *backlight;
 	struct panel_drv_data *ddata = mipi_dsi_get_drvdata(dsi);
-	struct display_timing timing;
-	struct videomode vm = {
-		.hactive = 864,
-		.vactive = 480,
-	};
 	int err;
+	struct drm_display_mode *mode = &ddata->mode;
 
 	ddata->reset_gpio = devm_gpiod_get(&dsi->dev, "reset", GPIOD_OUT_LOW);
 	if (IS_ERR(ddata->reset_gpio)) {
@@ -488,23 +487,16 @@ static int dsicm_probe_of(struct mipi_dsi_device *dsi)
 		return err;
 	}
 
-	err = of_get_display_timing(node, "panel-timing", &timing);
-	if (!err) {
-		videomode_from_timing(&timing, &vm);
-	} else {
-		dev_warn(&dsi->dev,
-			 "failed to get video timing, using defaults\n");
-	}
-
-	if (!vm.pixelclock)
-		vm.pixelclock = vm.hactive * vm.vactive * 60;
-	drm_display_mode_from_videomode(&vm, &ddata->mode);
-
-	ddata->width_mm = 0;
-	of_property_read_u32(node, "width-mm", &ddata->width_mm);
-
-	ddata->height_mm = 0;
-	of_property_read_u32(node, "height-mm", &ddata->height_mm);
+	mode->hdisplay = mode->hsync_start = mode->hsync_end = mode->htotal =
+		ddata->panel_data->xres;
+	mode->vdisplay = mode->vsync_start = mode->vsync_end = mode->vtotal =
+		ddata->panel_data->yres;
+	mode->clock = ddata->panel_data->xres * ddata->panel_data->yres *
+		ddata->panel_data->refresh / 1000;
+	mode->width_mm = ddata->panel_data->width_mm;
+	mode->height_mm = ddata->panel_data->height_mm;
+	mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
+	drm_mode_set_name(mode);
 
 	ddata->supplies[0].supply = "vpnl";
 	ddata->supplies[1].supply = "vddi";
@@ -531,6 +523,7 @@ static int dsicm_probe(struct mipi_dsi_device *dsi)
 	struct panel_drv_data *ddata;
 	struct backlight_device *bldev = NULL;
 	struct device *dev = &dsi->dev;
+	const struct of_device_id *id;
 	int r;
 
 	dev_dbg(dev, "probe\n");
@@ -542,6 +535,12 @@ static int dsicm_probe(struct mipi_dsi_device *dsi)
 	mipi_dsi_set_drvdata(dsi, ddata);
 	ddata->dsi = dsi;
 
+	id = of_match_node(dsicm_of_match, dev->of_node);
+	if (!id)
+		return -ENODEV;
+
+	ddata->panel_data = id->data;
+
 	r = dsicm_probe_of(dsi);
 	if (r)
 		return r;
@@ -578,8 +577,8 @@ static int dsicm_probe(struct mipi_dsi_device *dsi)
 	dsi->format = MIPI_DSI_FMT_RGB888;
 	dsi->mode_flags = MIPI_DSI_CLOCK_NON_CONTINUOUS |
 			  MIPI_DSI_MODE_EOT_PACKET;
-	dsi->hs_rate = 300000000;
-	dsi->lp_rate = 10000000;
+	dsi->hs_rate = ddata->panel_data->max_hs_rate;
+	dsi->lp_rate = ddata->panel_data->max_lp_rate;
 
 	drm_panel_add(&ddata->panel);
 
@@ -617,8 +616,40 @@ static int dsicm_remove(struct mipi_dsi_device *dsi)
 	return 0;
 }
 
+static const struct dsic_panel_data taal_data = {
+	.xres = 864,
+	.yres = 480,
+	.refresh = 60,
+	.width_mm = 0,
+	.height_mm = 0,
+	.max_hs_rate = 300000000,
+	.max_lp_rate = 10000000,
+};
+
+static const struct dsic_panel_data himalaya_data = {
+	.xres = 480,
+	.yres = 864,
+	.refresh = 60,
+	.width_mm = 49,
+	.height_mm = 88,
+	.max_hs_rate = 300000000,
+	.max_lp_rate = 10000000,
+};
+
+static const struct dsic_panel_data droid4_data = {
+	.xres = 540,
+	.yres = 960,
+	.refresh = 60,
+	.width_mm = 50,
+	.height_mm = 89,
+	.max_hs_rate = 300000000,
+	.max_lp_rate = 10000000,
+};
+
 static const struct of_device_id dsicm_of_match[] = {
-	{ .compatible = "panel-dsi-cm", },
+	{ .compatible = "tpo,taal", .data = &taal_data },
+	{ .compatible = "nokia,himalaya", &himalaya_data },
+	{ .compatible = "motorola,droid4-panel", &droid4_data },
 	{},
 };
 
-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v5 18/29] drm/panel: panel-dsi-cm: drop unneeded includes
  2020-12-08 12:28 [PATCH v5 00/29] Convert DSI code to use drm_mipi_dsi and drm_panel (second half) Tomi Valkeinen
                   ` (16 preceding siblings ...)
  2020-12-08 12:28 ` [PATCH v5 17/29] drm/panel: panel-dsi-cm: add panel database to driver Tomi Valkeinen
@ 2020-12-08 12:28 ` Tomi Valkeinen
  2020-12-14 16:06   ` Sebastian Reichel
  2020-12-08 12:28 ` [PATCH v5 19/29] drm/omap: dsi: move structs & defines to dsi.h Tomi Valkeinen
                   ` (10 subsequent siblings)
  28 siblings, 1 reply; 72+ messages in thread
From: Tomi Valkeinen @ 2020-12-08 12:28 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Nikhil Devshatwar, dri-devel
  Cc: linux-omap, Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg,
	Tomi Valkeinen

Drop unneeded includes.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: Sam Ravnborg <sam@ravnborg.org>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/gpu/drm/panel/panel-dsi-cm.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-dsi-cm.c b/drivers/gpu/drm/panel/panel-dsi-cm.c
index 3fb5b2856283..3fe73c4bef6e 100644
--- a/drivers/gpu/drm/panel/panel-dsi-cm.c
+++ b/drivers/gpu/drm/panel/panel-dsi-cm.c
@@ -11,9 +11,6 @@
 #include <linux/gpio/consumer.h>
 #include <linux/jiffies.h>
 #include <linux/module.h>
-#include <linux/sched/signal.h>
-#include <linux/slab.h>
-#include <linux/of_device.h>
 #include <linux/regulator/consumer.h>
 
 #include <drm/drm_connector.h>
-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v5 19/29] drm/omap: dsi: move structs & defines to dsi.h
  2020-12-08 12:28 [PATCH v5 00/29] Convert DSI code to use drm_mipi_dsi and drm_panel (second half) Tomi Valkeinen
                   ` (17 preceding siblings ...)
  2020-12-08 12:28 ` [PATCH v5 18/29] drm/panel: panel-dsi-cm: drop unneeded includes Tomi Valkeinen
@ 2020-12-08 12:28 ` Tomi Valkeinen
  2020-12-14 16:14   ` Sebastian Reichel
  2020-12-08 12:28 ` [PATCH v5 20/29] drm/omap: dsi: move enable/disable to bridge enable/disable Tomi Valkeinen
                   ` (9 subsequent siblings)
  28 siblings, 1 reply; 72+ messages in thread
From: Tomi Valkeinen @ 2020-12-08 12:28 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Nikhil Devshatwar, dri-devel
  Cc: linux-omap, Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg,
	Tomi Valkeinen

Move structs and defines to a private dsi.h header file to make dsi.c a
bit easier to navigate. Also move the (now) private structs and defines
from omapdss.h to dsi.h.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/gpu/drm/omapdrm/dss/dsi.c     | 384 +--------------------
 drivers/gpu/drm/omapdrm/dss/dsi.h     | 459 ++++++++++++++++++++++++++
 drivers/gpu/drm/omapdrm/dss/omapdss.h |  64 ----
 3 files changed, 460 insertions(+), 447 deletions(-)
 create mode 100644 drivers/gpu/drm/omapdrm/dss/dsi.h

diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index 0795efdd8902..da3ff9e236bd 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -45,73 +45,7 @@
 
 #define DSI_CATCH_MISSING_TE
 
-struct dsi_reg { u16 module; u16 idx; };
-
-#define DSI_REG(mod, idx)		((const struct dsi_reg) { mod, idx })
-
-/* DSI Protocol Engine */
-
-#define DSI_PROTO			0
-#define DSI_PROTO_SZ			0x200
-
-#define DSI_REVISION			DSI_REG(DSI_PROTO, 0x0000)
-#define DSI_SYSCONFIG			DSI_REG(DSI_PROTO, 0x0010)
-#define DSI_SYSSTATUS			DSI_REG(DSI_PROTO, 0x0014)
-#define DSI_IRQSTATUS			DSI_REG(DSI_PROTO, 0x0018)
-#define DSI_IRQENABLE			DSI_REG(DSI_PROTO, 0x001C)
-#define DSI_CTRL			DSI_REG(DSI_PROTO, 0x0040)
-#define DSI_GNQ				DSI_REG(DSI_PROTO, 0x0044)
-#define DSI_COMPLEXIO_CFG1		DSI_REG(DSI_PROTO, 0x0048)
-#define DSI_COMPLEXIO_IRQ_STATUS	DSI_REG(DSI_PROTO, 0x004C)
-#define DSI_COMPLEXIO_IRQ_ENABLE	DSI_REG(DSI_PROTO, 0x0050)
-#define DSI_CLK_CTRL			DSI_REG(DSI_PROTO, 0x0054)
-#define DSI_TIMING1			DSI_REG(DSI_PROTO, 0x0058)
-#define DSI_TIMING2			DSI_REG(DSI_PROTO, 0x005C)
-#define DSI_VM_TIMING1			DSI_REG(DSI_PROTO, 0x0060)
-#define DSI_VM_TIMING2			DSI_REG(DSI_PROTO, 0x0064)
-#define DSI_VM_TIMING3			DSI_REG(DSI_PROTO, 0x0068)
-#define DSI_CLK_TIMING			DSI_REG(DSI_PROTO, 0x006C)
-#define DSI_TX_FIFO_VC_SIZE		DSI_REG(DSI_PROTO, 0x0070)
-#define DSI_RX_FIFO_VC_SIZE		DSI_REG(DSI_PROTO, 0x0074)
-#define DSI_COMPLEXIO_CFG2		DSI_REG(DSI_PROTO, 0x0078)
-#define DSI_RX_FIFO_VC_FULLNESS		DSI_REG(DSI_PROTO, 0x007C)
-#define DSI_VM_TIMING4			DSI_REG(DSI_PROTO, 0x0080)
-#define DSI_TX_FIFO_VC_EMPTINESS	DSI_REG(DSI_PROTO, 0x0084)
-#define DSI_VM_TIMING5			DSI_REG(DSI_PROTO, 0x0088)
-#define DSI_VM_TIMING6			DSI_REG(DSI_PROTO, 0x008C)
-#define DSI_VM_TIMING7			DSI_REG(DSI_PROTO, 0x0090)
-#define DSI_STOPCLK_TIMING		DSI_REG(DSI_PROTO, 0x0094)
-#define DSI_VC_CTRL(n)			DSI_REG(DSI_PROTO, 0x0100 + (n * 0x20))
-#define DSI_VC_TE(n)			DSI_REG(DSI_PROTO, 0x0104 + (n * 0x20))
-#define DSI_VC_LONG_PACKET_HEADER(n)	DSI_REG(DSI_PROTO, 0x0108 + (n * 0x20))
-#define DSI_VC_LONG_PACKET_PAYLOAD(n)	DSI_REG(DSI_PROTO, 0x010C + (n * 0x20))
-#define DSI_VC_SHORT_PACKET_HEADER(n)	DSI_REG(DSI_PROTO, 0x0110 + (n * 0x20))
-#define DSI_VC_IRQSTATUS(n)		DSI_REG(DSI_PROTO, 0x0118 + (n * 0x20))
-#define DSI_VC_IRQENABLE(n)		DSI_REG(DSI_PROTO, 0x011C + (n * 0x20))
-
-/* DSIPHY_SCP */
-
-#define DSI_PHY				1
-#define DSI_PHY_OFFSET			0x200
-#define DSI_PHY_SZ			0x40
-
-#define DSI_DSIPHY_CFG0			DSI_REG(DSI_PHY, 0x0000)
-#define DSI_DSIPHY_CFG1			DSI_REG(DSI_PHY, 0x0004)
-#define DSI_DSIPHY_CFG2			DSI_REG(DSI_PHY, 0x0008)
-#define DSI_DSIPHY_CFG5			DSI_REG(DSI_PHY, 0x0014)
-#define DSI_DSIPHY_CFG10		DSI_REG(DSI_PHY, 0x0028)
-
-/* DSI_PLL_CTRL_SCP */
-
-#define DSI_PLL				2
-#define DSI_PLL_OFFSET			0x300
-#define DSI_PLL_SZ			0x20
-
-#define DSI_PLL_CONTROL			DSI_REG(DSI_PLL, 0x0000)
-#define DSI_PLL_STATUS			DSI_REG(DSI_PLL, 0x0004)
-#define DSI_PLL_GO			DSI_REG(DSI_PLL, 0x0008)
-#define DSI_PLL_CONFIGURATION1		DSI_REG(DSI_PLL, 0x000C)
-#define DSI_PLL_CONFIGURATION2		DSI_REG(DSI_PLL, 0x0010)
+#include "dsi.h"
 
 #define REG_GET(dsi, idx, start, end) \
 	FLD_GET(dsi_read_reg(dsi, idx), start, end)
@@ -119,96 +53,6 @@ struct dsi_reg { u16 module; u16 idx; };
 #define REG_FLD_MOD(dsi, idx, val, start, end) \
 	dsi_write_reg(dsi, idx, FLD_MOD(dsi_read_reg(dsi, idx), val, start, end))
 
-/* Global interrupts */
-#define DSI_IRQ_VC0		(1 << 0)
-#define DSI_IRQ_VC1		(1 << 1)
-#define DSI_IRQ_VC2		(1 << 2)
-#define DSI_IRQ_VC3		(1 << 3)
-#define DSI_IRQ_WAKEUP		(1 << 4)
-#define DSI_IRQ_RESYNC		(1 << 5)
-#define DSI_IRQ_PLL_LOCK	(1 << 7)
-#define DSI_IRQ_PLL_UNLOCK	(1 << 8)
-#define DSI_IRQ_PLL_RECALL	(1 << 9)
-#define DSI_IRQ_COMPLEXIO_ERR	(1 << 10)
-#define DSI_IRQ_HS_TX_TIMEOUT	(1 << 14)
-#define DSI_IRQ_LP_RX_TIMEOUT	(1 << 15)
-#define DSI_IRQ_TE_TRIGGER	(1 << 16)
-#define DSI_IRQ_ACK_TRIGGER	(1 << 17)
-#define DSI_IRQ_SYNC_LOST	(1 << 18)
-#define DSI_IRQ_LDO_POWER_GOOD	(1 << 19)
-#define DSI_IRQ_TA_TIMEOUT	(1 << 20)
-#define DSI_IRQ_ERROR_MASK \
-	(DSI_IRQ_HS_TX_TIMEOUT | DSI_IRQ_LP_RX_TIMEOUT | DSI_IRQ_SYNC_LOST | \
-	DSI_IRQ_TA_TIMEOUT)
-#define DSI_IRQ_CHANNEL_MASK	0xf
-
-/* Virtual channel interrupts */
-#define DSI_VC_IRQ_CS		(1 << 0)
-#define DSI_VC_IRQ_ECC_CORR	(1 << 1)
-#define DSI_VC_IRQ_PACKET_SENT	(1 << 2)
-#define DSI_VC_IRQ_FIFO_TX_OVF	(1 << 3)
-#define DSI_VC_IRQ_FIFO_RX_OVF	(1 << 4)
-#define DSI_VC_IRQ_BTA		(1 << 5)
-#define DSI_VC_IRQ_ECC_NO_CORR	(1 << 6)
-#define DSI_VC_IRQ_FIFO_TX_UDF	(1 << 7)
-#define DSI_VC_IRQ_PP_BUSY_CHANGE (1 << 8)
-#define DSI_VC_IRQ_ERROR_MASK \
-	(DSI_VC_IRQ_CS | DSI_VC_IRQ_ECC_CORR | DSI_VC_IRQ_FIFO_TX_OVF | \
-	DSI_VC_IRQ_FIFO_RX_OVF | DSI_VC_IRQ_ECC_NO_CORR | \
-	DSI_VC_IRQ_FIFO_TX_UDF)
-
-/* ComplexIO interrupts */
-#define DSI_CIO_IRQ_ERRSYNCESC1		(1 << 0)
-#define DSI_CIO_IRQ_ERRSYNCESC2		(1 << 1)
-#define DSI_CIO_IRQ_ERRSYNCESC3		(1 << 2)
-#define DSI_CIO_IRQ_ERRSYNCESC4		(1 << 3)
-#define DSI_CIO_IRQ_ERRSYNCESC5		(1 << 4)
-#define DSI_CIO_IRQ_ERRESC1		(1 << 5)
-#define DSI_CIO_IRQ_ERRESC2		(1 << 6)
-#define DSI_CIO_IRQ_ERRESC3		(1 << 7)
-#define DSI_CIO_IRQ_ERRESC4		(1 << 8)
-#define DSI_CIO_IRQ_ERRESC5		(1 << 9)
-#define DSI_CIO_IRQ_ERRCONTROL1		(1 << 10)
-#define DSI_CIO_IRQ_ERRCONTROL2		(1 << 11)
-#define DSI_CIO_IRQ_ERRCONTROL3		(1 << 12)
-#define DSI_CIO_IRQ_ERRCONTROL4		(1 << 13)
-#define DSI_CIO_IRQ_ERRCONTROL5		(1 << 14)
-#define DSI_CIO_IRQ_STATEULPS1		(1 << 15)
-#define DSI_CIO_IRQ_STATEULPS2		(1 << 16)
-#define DSI_CIO_IRQ_STATEULPS3		(1 << 17)
-#define DSI_CIO_IRQ_STATEULPS4		(1 << 18)
-#define DSI_CIO_IRQ_STATEULPS5		(1 << 19)
-#define DSI_CIO_IRQ_ERRCONTENTIONLP0_1	(1 << 20)
-#define DSI_CIO_IRQ_ERRCONTENTIONLP1_1	(1 << 21)
-#define DSI_CIO_IRQ_ERRCONTENTIONLP0_2	(1 << 22)
-#define DSI_CIO_IRQ_ERRCONTENTIONLP1_2	(1 << 23)
-#define DSI_CIO_IRQ_ERRCONTENTIONLP0_3	(1 << 24)
-#define DSI_CIO_IRQ_ERRCONTENTIONLP1_3	(1 << 25)
-#define DSI_CIO_IRQ_ERRCONTENTIONLP0_4	(1 << 26)
-#define DSI_CIO_IRQ_ERRCONTENTIONLP1_4	(1 << 27)
-#define DSI_CIO_IRQ_ERRCONTENTIONLP0_5	(1 << 28)
-#define DSI_CIO_IRQ_ERRCONTENTIONLP1_5	(1 << 29)
-#define DSI_CIO_IRQ_ULPSACTIVENOT_ALL0	(1 << 30)
-#define DSI_CIO_IRQ_ULPSACTIVENOT_ALL1	(1 << 31)
-#define DSI_CIO_IRQ_ERROR_MASK \
-	(DSI_CIO_IRQ_ERRSYNCESC1 | DSI_CIO_IRQ_ERRSYNCESC2 | \
-	 DSI_CIO_IRQ_ERRSYNCESC3 | DSI_CIO_IRQ_ERRSYNCESC4 | \
-	 DSI_CIO_IRQ_ERRSYNCESC5 | \
-	 DSI_CIO_IRQ_ERRESC1 | DSI_CIO_IRQ_ERRESC2 | \
-	 DSI_CIO_IRQ_ERRESC3 | DSI_CIO_IRQ_ERRESC4 | \
-	 DSI_CIO_IRQ_ERRESC5 | \
-	 DSI_CIO_IRQ_ERRCONTROL1 | DSI_CIO_IRQ_ERRCONTROL2 | \
-	 DSI_CIO_IRQ_ERRCONTROL3 | DSI_CIO_IRQ_ERRCONTROL4 | \
-	 DSI_CIO_IRQ_ERRCONTROL5 | \
-	 DSI_CIO_IRQ_ERRCONTENTIONLP0_1 | DSI_CIO_IRQ_ERRCONTENTIONLP1_1 | \
-	 DSI_CIO_IRQ_ERRCONTENTIONLP0_2 | DSI_CIO_IRQ_ERRCONTENTIONLP1_2 | \
-	 DSI_CIO_IRQ_ERRCONTENTIONLP0_3 | DSI_CIO_IRQ_ERRCONTENTIONLP1_3 | \
-	 DSI_CIO_IRQ_ERRCONTENTIONLP0_4 | DSI_CIO_IRQ_ERRCONTENTIONLP1_4 | \
-	 DSI_CIO_IRQ_ERRCONTENTIONLP0_5 | DSI_CIO_IRQ_ERRCONTENTIONLP1_5)
-
-typedef void (*omap_dsi_isr_t) (void *arg, u32 mask);
-struct dsi_data;
-
 static void dsi_set_ulps_auto(struct dsi_data *dsi, bool enable);
 
 static int dsi_display_init_dispc(struct dsi_data *dsi);
@@ -221,232 +65,6 @@ static ssize_t _omap_dsi_host_transfer(struct dsi_data *dsi, int vc,
 
 static void dsi_display_disable(struct omap_dss_device *dssdev);
 
-/* DSI PLL HSDIV indices */
-#define HSDIV_DISPC	0
-#define HSDIV_DSI	1
-
-#define DSI_MAX_NR_ISRS                2
-#define DSI_MAX_NR_LANES	5
-
-enum dsi_model {
-	DSI_MODEL_OMAP3,
-	DSI_MODEL_OMAP4,
-	DSI_MODEL_OMAP5,
-};
-
-enum dsi_lane_function {
-	DSI_LANE_UNUSED	= 0,
-	DSI_LANE_CLK,
-	DSI_LANE_DATA1,
-	DSI_LANE_DATA2,
-	DSI_LANE_DATA3,
-	DSI_LANE_DATA4,
-};
-
-struct dsi_lane_config {
-	enum dsi_lane_function function;
-	u8 polarity;
-};
-
-struct dsi_isr_data {
-	omap_dsi_isr_t	isr;
-	void		*arg;
-	u32		mask;
-};
-
-enum fifo_size {
-	DSI_FIFO_SIZE_0		= 0,
-	DSI_FIFO_SIZE_32	= 1,
-	DSI_FIFO_SIZE_64	= 2,
-	DSI_FIFO_SIZE_96	= 3,
-	DSI_FIFO_SIZE_128	= 4,
-};
-
-enum dsi_vc_source {
-	DSI_VC_SOURCE_L4 = 0,
-	DSI_VC_SOURCE_VP,
-};
-
-struct dsi_irq_stats {
-	unsigned long last_reset;
-	unsigned int irq_count;
-	unsigned int dsi_irqs[32];
-	unsigned int vc_irqs[4][32];
-	unsigned int cio_irqs[32];
-};
-
-struct dsi_isr_tables {
-	struct dsi_isr_data isr_table[DSI_MAX_NR_ISRS];
-	struct dsi_isr_data isr_table_vc[4][DSI_MAX_NR_ISRS];
-	struct dsi_isr_data isr_table_cio[DSI_MAX_NR_ISRS];
-};
-
-struct dsi_lp_clock_info {
-	unsigned long lp_clk;
-	u16 lp_clk_div;
-};
-
-struct dsi_clk_calc_ctx {
-	struct dsi_data *dsi;
-	struct dss_pll *pll;
-
-	/* inputs */
-
-	const struct omap_dss_dsi_config *config;
-
-	unsigned long req_pck_min, req_pck_nom, req_pck_max;
-
-	/* outputs */
-
-	struct dss_pll_clock_info dsi_cinfo;
-	struct dispc_clock_info dispc_cinfo;
-	struct dsi_lp_clock_info lp_cinfo;
-
-	struct videomode vm;
-	struct omap_dss_dsi_videomode_timings dsi_vm;
-};
-
-struct dsi_module_id_data {
-	u32 address;
-	int id;
-};
-
-enum dsi_quirks {
-	DSI_QUIRK_PLL_PWR_BUG = (1 << 0),	/* DSI-PLL power command 0x3 is not working */
-	DSI_QUIRK_DCS_CMD_CONFIG_VC = (1 << 1),
-	DSI_QUIRK_VC_OCP_WIDTH = (1 << 2),
-	DSI_QUIRK_REVERSE_TXCLKESC = (1 << 3),
-	DSI_QUIRK_GNQ = (1 << 4),
-	DSI_QUIRK_PHY_DCC = (1 << 5),
-};
-
-struct dsi_of_data {
-	enum dsi_model model;
-	const struct dss_pll_hw *pll_hw;
-	const struct dsi_module_id_data *modules;
-	unsigned int max_fck_freq;
-	unsigned int max_pll_lpdiv;
-	enum dsi_quirks quirks;
-};
-
-struct dsi_data {
-	struct device *dev;
-	void __iomem *proto_base;
-	void __iomem *phy_base;
-	void __iomem *pll_base;
-
-	const struct dsi_of_data *data;
-	int module_id;
-
-	int irq;
-
-	bool is_enabled;
-
-	struct clk *dss_clk;
-	struct regmap *syscon;
-	struct dss_device *dss;
-
-	struct mipi_dsi_host host;
-
-	struct dispc_clock_info user_dispc_cinfo;
-	struct dss_pll_clock_info user_dsi_cinfo;
-
-	struct dsi_lp_clock_info user_lp_cinfo;
-	struct dsi_lp_clock_info current_lp_cinfo;
-
-	struct dss_pll pll;
-
-	bool vdds_dsi_enabled;
-	struct regulator *vdds_dsi_reg;
-
-	struct mipi_dsi_device *dsidev;
-
-	struct {
-		enum dsi_vc_source source;
-		enum fifo_size tx_fifo_size;
-		enum fifo_size rx_fifo_size;
-	} vc[4];
-
-	struct mutex lock;
-	struct semaphore bus_lock;
-
-	spinlock_t irq_lock;
-	struct dsi_isr_tables isr_tables;
-	/* space for a copy used by the interrupt handler */
-	struct dsi_isr_tables isr_tables_copy;
-
-	int update_vc;
-#ifdef DSI_PERF_MEASURE
-	unsigned int update_bytes;
-#endif
-
-	/* external TE GPIO */
-	struct gpio_desc *te_gpio;
-	int te_irq;
-	struct delayed_work te_timeout_work;
-	atomic_t do_ext_te_update;
-
-	bool te_enabled;
-	bool ulps_enabled;
-	bool ulps_auto_idle;
-	bool video_enabled;
-
-	struct delayed_work ulps_work;
-
-	struct delayed_work framedone_timeout_work;
-
-#ifdef DSI_CATCH_MISSING_TE
-	struct timer_list te_timer;
-#endif
-
-	unsigned long cache_req_pck;
-	unsigned long cache_clk_freq;
-	struct dss_pll_clock_info cache_cinfo;
-
-	u32		errors;
-	spinlock_t	errors_lock;
-#ifdef DSI_PERF_MEASURE
-	ktime_t perf_setup_time;
-	ktime_t perf_start_time;
-#endif
-	int debug_read;
-	int debug_write;
-	struct {
-		struct dss_debugfs_entry *irqs;
-		struct dss_debugfs_entry *regs;
-		struct dss_debugfs_entry *clks;
-	} debugfs;
-
-#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
-	spinlock_t irq_stats_lock;
-	struct dsi_irq_stats irq_stats;
-#endif
-
-	unsigned int num_lanes_supported;
-	unsigned int line_buffer_size;
-
-	struct dsi_lane_config lanes[DSI_MAX_NR_LANES];
-	unsigned int num_lanes_used;
-
-	unsigned int scp_clk_refcount;
-
-	struct omap_dss_dsi_config config;
-
-	struct dss_lcd_mgr_config mgr_config;
-	struct videomode vm;
-	enum mipi_dsi_pixel_format pix_fmt;
-	enum omap_dss_dsi_mode mode;
-	struct omap_dss_dsi_videomode_timings vm_timings;
-
-	struct omap_dss_device output;
-	struct drm_bridge bridge;
-};
-
-struct dsi_packet_sent_handler_data {
-	struct dsi_data *dsi;
-	struct completion *completion;
-};
-
 #ifdef DSI_PERF_MEASURE
 static bool dsi_perf;
 module_param(dsi_perf, bool, 0644);
diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.h b/drivers/gpu/drm/omapdrm/dss/dsi.h
new file mode 100644
index 000000000000..478fc10bd18d
--- /dev/null
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.h
@@ -0,0 +1,459 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2016 Texas Instruments Incorporated - http://www.ti.com/
+ * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
+ */
+
+#ifndef __OMAP_DRM_DSS_DSI_H
+#define __OMAP_DRM_DSS_DSI_H
+
+#include <drm/drm_mipi_dsi.h>
+
+struct dsi_reg {
+	u16 module;
+	u16 idx;
+};
+
+#define DSI_REG(mod, idx)		((const struct dsi_reg) { mod, idx })
+
+/* DSI Protocol Engine */
+
+#define DSI_PROTO			0
+#define DSI_PROTO_SZ			0x200
+
+#define DSI_REVISION			DSI_REG(DSI_PROTO, 0x0000)
+#define DSI_SYSCONFIG			DSI_REG(DSI_PROTO, 0x0010)
+#define DSI_SYSSTATUS			DSI_REG(DSI_PROTO, 0x0014)
+#define DSI_IRQSTATUS			DSI_REG(DSI_PROTO, 0x0018)
+#define DSI_IRQENABLE			DSI_REG(DSI_PROTO, 0x001C)
+#define DSI_CTRL			DSI_REG(DSI_PROTO, 0x0040)
+#define DSI_GNQ				DSI_REG(DSI_PROTO, 0x0044)
+#define DSI_COMPLEXIO_CFG1		DSI_REG(DSI_PROTO, 0x0048)
+#define DSI_COMPLEXIO_IRQ_STATUS	DSI_REG(DSI_PROTO, 0x004C)
+#define DSI_COMPLEXIO_IRQ_ENABLE	DSI_REG(DSI_PROTO, 0x0050)
+#define DSI_CLK_CTRL			DSI_REG(DSI_PROTO, 0x0054)
+#define DSI_TIMING1			DSI_REG(DSI_PROTO, 0x0058)
+#define DSI_TIMING2			DSI_REG(DSI_PROTO, 0x005C)
+#define DSI_VM_TIMING1			DSI_REG(DSI_PROTO, 0x0060)
+#define DSI_VM_TIMING2			DSI_REG(DSI_PROTO, 0x0064)
+#define DSI_VM_TIMING3			DSI_REG(DSI_PROTO, 0x0068)
+#define DSI_CLK_TIMING			DSI_REG(DSI_PROTO, 0x006C)
+#define DSI_TX_FIFO_VC_SIZE		DSI_REG(DSI_PROTO, 0x0070)
+#define DSI_RX_FIFO_VC_SIZE		DSI_REG(DSI_PROTO, 0x0074)
+#define DSI_COMPLEXIO_CFG2		DSI_REG(DSI_PROTO, 0x0078)
+#define DSI_RX_FIFO_VC_FULLNESS		DSI_REG(DSI_PROTO, 0x007C)
+#define DSI_VM_TIMING4			DSI_REG(DSI_PROTO, 0x0080)
+#define DSI_TX_FIFO_VC_EMPTINESS	DSI_REG(DSI_PROTO, 0x0084)
+#define DSI_VM_TIMING5			DSI_REG(DSI_PROTO, 0x0088)
+#define DSI_VM_TIMING6			DSI_REG(DSI_PROTO, 0x008C)
+#define DSI_VM_TIMING7			DSI_REG(DSI_PROTO, 0x0090)
+#define DSI_STOPCLK_TIMING		DSI_REG(DSI_PROTO, 0x0094)
+#define DSI_VC_CTRL(n)			DSI_REG(DSI_PROTO, 0x0100 + (n * 0x20))
+#define DSI_VC_TE(n)			DSI_REG(DSI_PROTO, 0x0104 + (n * 0x20))
+#define DSI_VC_LONG_PACKET_HEADER(n)	DSI_REG(DSI_PROTO, 0x0108 + (n * 0x20))
+#define DSI_VC_LONG_PACKET_PAYLOAD(n)	DSI_REG(DSI_PROTO, 0x010C + (n * 0x20))
+#define DSI_VC_SHORT_PACKET_HEADER(n)	DSI_REG(DSI_PROTO, 0x0110 + (n * 0x20))
+#define DSI_VC_IRQSTATUS(n)		DSI_REG(DSI_PROTO, 0x0118 + (n * 0x20))
+#define DSI_VC_IRQENABLE(n)		DSI_REG(DSI_PROTO, 0x011C + (n * 0x20))
+
+/* DSIPHY_SCP */
+
+#define DSI_PHY				1
+#define DSI_PHY_OFFSET			0x200
+#define DSI_PHY_SZ			0x40
+
+#define DSI_DSIPHY_CFG0			DSI_REG(DSI_PHY, 0x0000)
+#define DSI_DSIPHY_CFG1			DSI_REG(DSI_PHY, 0x0004)
+#define DSI_DSIPHY_CFG2			DSI_REG(DSI_PHY, 0x0008)
+#define DSI_DSIPHY_CFG5			DSI_REG(DSI_PHY, 0x0014)
+#define DSI_DSIPHY_CFG10		DSI_REG(DSI_PHY, 0x0028)
+
+/* DSI_PLL_CTRL_SCP */
+
+#define DSI_PLL				2
+#define DSI_PLL_OFFSET			0x300
+#define DSI_PLL_SZ			0x20
+
+#define DSI_PLL_CONTROL			DSI_REG(DSI_PLL, 0x0000)
+#define DSI_PLL_STATUS			DSI_REG(DSI_PLL, 0x0004)
+#define DSI_PLL_GO			DSI_REG(DSI_PLL, 0x0008)
+#define DSI_PLL_CONFIGURATION1		DSI_REG(DSI_PLL, 0x000C)
+#define DSI_PLL_CONFIGURATION2		DSI_REG(DSI_PLL, 0x0010)
+
+/* Global interrupts */
+#define DSI_IRQ_VC0		(1 << 0)
+#define DSI_IRQ_VC1		(1 << 1)
+#define DSI_IRQ_VC2		(1 << 2)
+#define DSI_IRQ_VC3		(1 << 3)
+#define DSI_IRQ_WAKEUP		(1 << 4)
+#define DSI_IRQ_RESYNC		(1 << 5)
+#define DSI_IRQ_PLL_LOCK	(1 << 7)
+#define DSI_IRQ_PLL_UNLOCK	(1 << 8)
+#define DSI_IRQ_PLL_RECALL	(1 << 9)
+#define DSI_IRQ_COMPLEXIO_ERR	(1 << 10)
+#define DSI_IRQ_HS_TX_TIMEOUT	(1 << 14)
+#define DSI_IRQ_LP_RX_TIMEOUT	(1 << 15)
+#define DSI_IRQ_TE_TRIGGER	(1 << 16)
+#define DSI_IRQ_ACK_TRIGGER	(1 << 17)
+#define DSI_IRQ_SYNC_LOST	(1 << 18)
+#define DSI_IRQ_LDO_POWER_GOOD	(1 << 19)
+#define DSI_IRQ_TA_TIMEOUT	(1 << 20)
+#define DSI_IRQ_ERROR_MASK \
+	(DSI_IRQ_HS_TX_TIMEOUT | DSI_IRQ_LP_RX_TIMEOUT | DSI_IRQ_SYNC_LOST | \
+	DSI_IRQ_TA_TIMEOUT)
+#define DSI_IRQ_CHANNEL_MASK	0xf
+
+/* Virtual channel interrupts */
+#define DSI_VC_IRQ_CS		(1 << 0)
+#define DSI_VC_IRQ_ECC_CORR	(1 << 1)
+#define DSI_VC_IRQ_PACKET_SENT	(1 << 2)
+#define DSI_VC_IRQ_FIFO_TX_OVF	(1 << 3)
+#define DSI_VC_IRQ_FIFO_RX_OVF	(1 << 4)
+#define DSI_VC_IRQ_BTA		(1 << 5)
+#define DSI_VC_IRQ_ECC_NO_CORR	(1 << 6)
+#define DSI_VC_IRQ_FIFO_TX_UDF	(1 << 7)
+#define DSI_VC_IRQ_PP_BUSY_CHANGE (1 << 8)
+#define DSI_VC_IRQ_ERROR_MASK \
+	(DSI_VC_IRQ_CS | DSI_VC_IRQ_ECC_CORR | DSI_VC_IRQ_FIFO_TX_OVF | \
+	DSI_VC_IRQ_FIFO_RX_OVF | DSI_VC_IRQ_ECC_NO_CORR | \
+	DSI_VC_IRQ_FIFO_TX_UDF)
+
+/* ComplexIO interrupts */
+#define DSI_CIO_IRQ_ERRSYNCESC1		(1 << 0)
+#define DSI_CIO_IRQ_ERRSYNCESC2		(1 << 1)
+#define DSI_CIO_IRQ_ERRSYNCESC3		(1 << 2)
+#define DSI_CIO_IRQ_ERRSYNCESC4		(1 << 3)
+#define DSI_CIO_IRQ_ERRSYNCESC5		(1 << 4)
+#define DSI_CIO_IRQ_ERRESC1		(1 << 5)
+#define DSI_CIO_IRQ_ERRESC2		(1 << 6)
+#define DSI_CIO_IRQ_ERRESC3		(1 << 7)
+#define DSI_CIO_IRQ_ERRESC4		(1 << 8)
+#define DSI_CIO_IRQ_ERRESC5		(1 << 9)
+#define DSI_CIO_IRQ_ERRCONTROL1		(1 << 10)
+#define DSI_CIO_IRQ_ERRCONTROL2		(1 << 11)
+#define DSI_CIO_IRQ_ERRCONTROL3		(1 << 12)
+#define DSI_CIO_IRQ_ERRCONTROL4		(1 << 13)
+#define DSI_CIO_IRQ_ERRCONTROL5		(1 << 14)
+#define DSI_CIO_IRQ_STATEULPS1		(1 << 15)
+#define DSI_CIO_IRQ_STATEULPS2		(1 << 16)
+#define DSI_CIO_IRQ_STATEULPS3		(1 << 17)
+#define DSI_CIO_IRQ_STATEULPS4		(1 << 18)
+#define DSI_CIO_IRQ_STATEULPS5		(1 << 19)
+#define DSI_CIO_IRQ_ERRCONTENTIONLP0_1	(1 << 20)
+#define DSI_CIO_IRQ_ERRCONTENTIONLP1_1	(1 << 21)
+#define DSI_CIO_IRQ_ERRCONTENTIONLP0_2	(1 << 22)
+#define DSI_CIO_IRQ_ERRCONTENTIONLP1_2	(1 << 23)
+#define DSI_CIO_IRQ_ERRCONTENTIONLP0_3	(1 << 24)
+#define DSI_CIO_IRQ_ERRCONTENTIONLP1_3	(1 << 25)
+#define DSI_CIO_IRQ_ERRCONTENTIONLP0_4	(1 << 26)
+#define DSI_CIO_IRQ_ERRCONTENTIONLP1_4	(1 << 27)
+#define DSI_CIO_IRQ_ERRCONTENTIONLP0_5	(1 << 28)
+#define DSI_CIO_IRQ_ERRCONTENTIONLP1_5	(1 << 29)
+#define DSI_CIO_IRQ_ULPSACTIVENOT_ALL0	(1 << 30)
+#define DSI_CIO_IRQ_ULPSACTIVENOT_ALL1	(1 << 31)
+#define DSI_CIO_IRQ_ERROR_MASK \
+	(DSI_CIO_IRQ_ERRSYNCESC1 | DSI_CIO_IRQ_ERRSYNCESC2 | \
+	 DSI_CIO_IRQ_ERRSYNCESC3 | DSI_CIO_IRQ_ERRSYNCESC4 | \
+	 DSI_CIO_IRQ_ERRSYNCESC5 | \
+	 DSI_CIO_IRQ_ERRESC1 | DSI_CIO_IRQ_ERRESC2 | \
+	 DSI_CIO_IRQ_ERRESC3 | DSI_CIO_IRQ_ERRESC4 | \
+	 DSI_CIO_IRQ_ERRESC5 | \
+	 DSI_CIO_IRQ_ERRCONTROL1 | DSI_CIO_IRQ_ERRCONTROL2 | \
+	 DSI_CIO_IRQ_ERRCONTROL3 | DSI_CIO_IRQ_ERRCONTROL4 | \
+	 DSI_CIO_IRQ_ERRCONTROL5 | \
+	 DSI_CIO_IRQ_ERRCONTENTIONLP0_1 | DSI_CIO_IRQ_ERRCONTENTIONLP1_1 | \
+	 DSI_CIO_IRQ_ERRCONTENTIONLP0_2 | DSI_CIO_IRQ_ERRCONTENTIONLP1_2 | \
+	 DSI_CIO_IRQ_ERRCONTENTIONLP0_3 | DSI_CIO_IRQ_ERRCONTENTIONLP1_3 | \
+	 DSI_CIO_IRQ_ERRCONTENTIONLP0_4 | DSI_CIO_IRQ_ERRCONTENTIONLP1_4 | \
+	 DSI_CIO_IRQ_ERRCONTENTIONLP0_5 | DSI_CIO_IRQ_ERRCONTENTIONLP1_5)
+
+enum omap_dss_dsi_mode {
+	OMAP_DSS_DSI_CMD_MODE = 0,
+	OMAP_DSS_DSI_VIDEO_MODE,
+};
+
+enum omap_dss_dsi_trans_mode {
+	/* Sync Pulses: both sync start and end packets sent */
+	OMAP_DSS_DSI_PULSE_MODE,
+	/* Sync Events: only sync start packets sent */
+	OMAP_DSS_DSI_EVENT_MODE,
+	/* Burst: only sync start packets sent, pixels are time compressed */
+	OMAP_DSS_DSI_BURST_MODE,
+};
+
+struct omap_dss_dsi_videomode_timings {
+	unsigned long hsclk;
+
+	unsigned int ndl;
+	unsigned int bitspp;
+
+	/* pixels */
+	u16 hact;
+	/* lines */
+	u16 vact;
+
+	/* DSI video mode blanking data */
+	/* Unit: byte clock cycles */
+	u16 hss;
+	u16 hsa;
+	u16 hse;
+	u16 hfp;
+	u16 hbp;
+	/* Unit: line clocks */
+	u16 vsa;
+	u16 vfp;
+	u16 vbp;
+
+	/* DSI blanking modes */
+	int blanking_mode;
+	int hsa_blanking_mode;
+	int hbp_blanking_mode;
+	int hfp_blanking_mode;
+
+	enum omap_dss_dsi_trans_mode trans_mode;
+
+	bool ddr_clk_always_on;
+	int window_sync;
+};
+
+struct omap_dss_dsi_config {
+	enum omap_dss_dsi_mode mode;
+	enum mipi_dsi_pixel_format pixel_format;
+	const struct videomode *vm;
+
+	unsigned long hs_clk_min, hs_clk_max;
+	unsigned long lp_clk_min, lp_clk_max;
+
+	bool ddr_clk_always_on;
+	enum omap_dss_dsi_trans_mode trans_mode;
+};
+
+/* DSI PLL HSDIV indices */
+#define HSDIV_DISPC	0
+#define HSDIV_DSI	1
+
+#define DSI_MAX_NR_ISRS                2
+#define DSI_MAX_NR_LANES	5
+
+enum dsi_model {
+	DSI_MODEL_OMAP3,
+	DSI_MODEL_OMAP4,
+	DSI_MODEL_OMAP5,
+};
+
+enum dsi_lane_function {
+	DSI_LANE_UNUSED	= 0,
+	DSI_LANE_CLK,
+	DSI_LANE_DATA1,
+	DSI_LANE_DATA2,
+	DSI_LANE_DATA3,
+	DSI_LANE_DATA4,
+};
+
+struct dsi_lane_config {
+	enum dsi_lane_function function;
+	u8 polarity;
+};
+
+typedef void (*omap_dsi_isr_t) (void *arg, u32 mask);
+
+struct dsi_isr_data {
+	omap_dsi_isr_t	isr;
+	void		*arg;
+	u32		mask;
+};
+
+enum fifo_size {
+	DSI_FIFO_SIZE_0		= 0,
+	DSI_FIFO_SIZE_32	= 1,
+	DSI_FIFO_SIZE_64	= 2,
+	DSI_FIFO_SIZE_96	= 3,
+	DSI_FIFO_SIZE_128	= 4,
+};
+
+enum dsi_vc_source {
+	DSI_VC_SOURCE_L4 = 0,
+	DSI_VC_SOURCE_VP,
+};
+
+struct dsi_irq_stats {
+	unsigned long last_reset;
+	unsigned int irq_count;
+	unsigned int dsi_irqs[32];
+	unsigned int vc_irqs[4][32];
+	unsigned int cio_irqs[32];
+};
+
+struct dsi_isr_tables {
+	struct dsi_isr_data isr_table[DSI_MAX_NR_ISRS];
+	struct dsi_isr_data isr_table_vc[4][DSI_MAX_NR_ISRS];
+	struct dsi_isr_data isr_table_cio[DSI_MAX_NR_ISRS];
+};
+
+struct dsi_lp_clock_info {
+	unsigned long lp_clk;
+	u16 lp_clk_div;
+};
+
+struct dsi_clk_calc_ctx {
+	struct dsi_data *dsi;
+	struct dss_pll *pll;
+
+	/* inputs */
+
+	const struct omap_dss_dsi_config *config;
+
+	unsigned long req_pck_min, req_pck_nom, req_pck_max;
+
+	/* outputs */
+
+	struct dss_pll_clock_info dsi_cinfo;
+	struct dispc_clock_info dispc_cinfo;
+	struct dsi_lp_clock_info lp_cinfo;
+
+	struct videomode vm;
+	struct omap_dss_dsi_videomode_timings dsi_vm;
+};
+
+struct dsi_module_id_data {
+	u32 address;
+	int id;
+};
+
+enum dsi_quirks {
+	DSI_QUIRK_PLL_PWR_BUG = (1 << 0),	/* DSI-PLL power command 0x3 is not working */
+	DSI_QUIRK_DCS_CMD_CONFIG_VC = (1 << 1),
+	DSI_QUIRK_VC_OCP_WIDTH = (1 << 2),
+	DSI_QUIRK_REVERSE_TXCLKESC = (1 << 3),
+	DSI_QUIRK_GNQ = (1 << 4),
+	DSI_QUIRK_PHY_DCC = (1 << 5),
+};
+
+struct dsi_of_data {
+	enum dsi_model model;
+	const struct dss_pll_hw *pll_hw;
+	const struct dsi_module_id_data *modules;
+	unsigned int max_fck_freq;
+	unsigned int max_pll_lpdiv;
+	enum dsi_quirks quirks;
+};
+
+struct dsi_data {
+	struct device *dev;
+	void __iomem *proto_base;
+	void __iomem *phy_base;
+	void __iomem *pll_base;
+
+	const struct dsi_of_data *data;
+	int module_id;
+
+	int irq;
+
+	bool is_enabled;
+
+	struct clk *dss_clk;
+	struct regmap *syscon;
+	struct dss_device *dss;
+
+	struct mipi_dsi_host host;
+
+	struct dispc_clock_info user_dispc_cinfo;
+	struct dss_pll_clock_info user_dsi_cinfo;
+
+	struct dsi_lp_clock_info user_lp_cinfo;
+	struct dsi_lp_clock_info current_lp_cinfo;
+
+	struct dss_pll pll;
+
+	bool vdds_dsi_enabled;
+	struct regulator *vdds_dsi_reg;
+
+	struct mipi_dsi_device *dsidev;
+
+	struct {
+		enum dsi_vc_source source;
+		enum fifo_size tx_fifo_size;
+		enum fifo_size rx_fifo_size;
+	} vc[4];
+
+	struct mutex lock;
+	struct semaphore bus_lock;
+
+	spinlock_t irq_lock;
+	struct dsi_isr_tables isr_tables;
+	/* space for a copy used by the interrupt handler */
+	struct dsi_isr_tables isr_tables_copy;
+
+	int update_vc;
+#ifdef DSI_PERF_MEASURE
+	unsigned int update_bytes;
+#endif
+
+	/* external TE GPIO */
+	struct gpio_desc *te_gpio;
+	int te_irq;
+	struct delayed_work te_timeout_work;
+	atomic_t do_ext_te_update;
+
+	bool te_enabled;
+	bool ulps_enabled;
+	bool ulps_auto_idle;
+	bool video_enabled;
+
+	struct delayed_work ulps_work;
+
+	struct delayed_work framedone_timeout_work;
+
+#ifdef DSI_CATCH_MISSING_TE
+	struct timer_list te_timer;
+#endif
+
+	unsigned long cache_req_pck;
+	unsigned long cache_clk_freq;
+	struct dss_pll_clock_info cache_cinfo;
+
+	u32		errors;
+	spinlock_t	errors_lock;
+#ifdef DSI_PERF_MEASURE
+	ktime_t perf_setup_time;
+	ktime_t perf_start_time;
+#endif
+	int debug_read;
+	int debug_write;
+	struct {
+		struct dss_debugfs_entry *irqs;
+		struct dss_debugfs_entry *regs;
+		struct dss_debugfs_entry *clks;
+	} debugfs;
+
+#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
+	spinlock_t irq_stats_lock;
+	struct dsi_irq_stats irq_stats;
+#endif
+
+	unsigned int num_lanes_supported;
+	unsigned int line_buffer_size;
+
+	struct dsi_lane_config lanes[DSI_MAX_NR_LANES];
+	unsigned int num_lanes_used;
+
+	unsigned int scp_clk_refcount;
+
+	struct omap_dss_dsi_config config;
+
+	struct dss_lcd_mgr_config mgr_config;
+	struct videomode vm;
+	enum mipi_dsi_pixel_format pix_fmt;
+	enum omap_dss_dsi_mode mode;
+	struct omap_dss_dsi_videomode_timings vm_timings;
+
+	struct omap_dss_device output;
+	struct drm_bridge bridge;
+};
+
+struct dsi_packet_sent_handler_data {
+	struct dsi_data *dsi;
+	struct completion *completion;
+};
+
+#endif /* __OMAP_DRM_DSS_DSI_H */
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index 9df322ca467d..6ecaa060ff4b 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -14,7 +14,6 @@
 #include <linux/platform_data/omapdss.h>
 
 #include <drm/drm_crtc.h>
-#include <drm/drm_mipi_dsi.h>
 #include <drm/drm_mode.h>
 
 #define DISPC_IRQ_FRAMEDONE		(1 << 0)
@@ -118,11 +117,6 @@ enum omap_dss_venc_type {
 	OMAP_DSS_VENC_TYPE_SVIDEO,
 };
 
-enum omap_dss_dsi_mode {
-	OMAP_DSS_DSI_CMD_MODE = 0,
-	OMAP_DSS_DSI_VIDEO_MODE,
-};
-
 enum omap_dss_rotation_type {
 	OMAP_DSS_ROT_NONE	= 0,
 	OMAP_DSS_ROT_TILER	= 1 << 0,
@@ -147,64 +141,6 @@ enum omap_dss_output_id {
 	OMAP_DSS_OUTPUT_HDMI	= 1 << 6,
 };
 
-/* DSI */
-
-enum omap_dss_dsi_trans_mode {
-	/* Sync Pulses: both sync start and end packets sent */
-	OMAP_DSS_DSI_PULSE_MODE,
-	/* Sync Events: only sync start packets sent */
-	OMAP_DSS_DSI_EVENT_MODE,
-	/* Burst: only sync start packets sent, pixels are time compressed */
-	OMAP_DSS_DSI_BURST_MODE,
-};
-
-struct omap_dss_dsi_videomode_timings {
-	unsigned long hsclk;
-
-	unsigned int ndl;
-	unsigned int bitspp;
-
-	/* pixels */
-	u16 hact;
-	/* lines */
-	u16 vact;
-
-	/* DSI video mode blanking data */
-	/* Unit: byte clock cycles */
-	u16 hss;
-	u16 hsa;
-	u16 hse;
-	u16 hfp;
-	u16 hbp;
-	/* Unit: line clocks */
-	u16 vsa;
-	u16 vfp;
-	u16 vbp;
-
-	/* DSI blanking modes */
-	int blanking_mode;
-	int hsa_blanking_mode;
-	int hbp_blanking_mode;
-	int hfp_blanking_mode;
-
-	enum omap_dss_dsi_trans_mode trans_mode;
-
-	bool ddr_clk_always_on;
-	int window_sync;
-};
-
-struct omap_dss_dsi_config {
-	enum omap_dss_dsi_mode mode;
-	enum mipi_dsi_pixel_format pixel_format;
-	const struct videomode *vm;
-
-	unsigned long hs_clk_min, hs_clk_max;
-	unsigned long lp_clk_min, lp_clk_max;
-
-	bool ddr_clk_always_on;
-	enum omap_dss_dsi_trans_mode trans_mode;
-};
-
 struct omap_dss_cpr_coefs {
 	s16 rr, rg, rb;
 	s16 gr, gg, gb;
-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v5 20/29] drm/omap: dsi: move enable/disable to bridge enable/disable
  2020-12-08 12:28 [PATCH v5 00/29] Convert DSI code to use drm_mipi_dsi and drm_panel (second half) Tomi Valkeinen
                   ` (18 preceding siblings ...)
  2020-12-08 12:28 ` [PATCH v5 19/29] drm/omap: dsi: move structs & defines to dsi.h Tomi Valkeinen
@ 2020-12-08 12:28 ` Tomi Valkeinen
  2020-12-14 16:16   ` Sebastian Reichel
  2020-12-08 12:28 ` [PATCH v5 21/29] drm/omap: dsi: display_enable cleanup Tomi Valkeinen
                   ` (8 subsequent siblings)
  28 siblings, 1 reply; 72+ messages in thread
From: Tomi Valkeinen @ 2020-12-08 12:28 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Nikhil Devshatwar, dri-devel
  Cc: linux-omap, Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg,
	Tomi Valkeinen

Clean up the code by inlining dsi_enable_video_outputs and
dsi_disable_video_outputs functions.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/gpu/drm/omapdrm/dss/dsi.c | 55 +++++++++++++------------------
 1 file changed, 22 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index da3ff9e236bd..44b8e42b52ec 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -3336,20 +3336,6 @@ static void dsi_disable_video_output(struct omap_dss_device *dssdev, int vc)
 	dsi_display_uninit_dispc(dsi);
 }
 
-static void dsi_disable_video_outputs(struct omap_dss_device *dssdev)
-{
-	struct dsi_data *dsi = to_dsi_data(dssdev);
-
-	dsi_bus_lock(dsi);
-	dsi->video_enabled = false;
-
-	dsi_disable_video_output(dssdev, VC_VIDEO);
-
-	dsi_display_disable(dssdev);
-
-	dsi_bus_unlock(dsi);
-}
-
 static void dsi_update_screen_dispc(struct dsi_data *dsi)
 {
 	unsigned int bytespp;
@@ -3796,23 +3782,6 @@ static void dsi_display_enable(struct omap_dss_device *dssdev)
 	_dsi_display_enable(dsi);
 }
 
-static void dsi_enable_video_outputs(struct omap_dss_device *dssdev)
-{
-	struct dsi_data *dsi = to_dsi_data(dssdev);
-
-	dsi_bus_lock(dsi);
-
-	dsi_display_enable(dssdev);
-
-	dsi_enable_video_output(dssdev, VC_VIDEO);
-
-	dsi->video_enabled = true;
-
-	dsi_set_ulps_auto(dsi, true);
-
-	dsi_bus_unlock(dsi);
-}
-
 static void _dsi_display_disable(struct dsi_data *dsi,
 		bool disconnect_lanes, bool enter_ulps)
 {
@@ -4974,15 +4943,35 @@ static void dsi_bridge_mode_set(struct drm_bridge *bridge,
 static void dsi_bridge_enable(struct drm_bridge *bridge)
 {
 	struct dsi_data *dsi = drm_bridge_to_dsi(bridge);
+	struct omap_dss_device *dssdev = &dsi->output;
 
-	dsi_enable_video_outputs(&dsi->output);
+	dsi_bus_lock(dsi);
+
+	dsi_display_enable(dssdev);
+
+	dsi_enable_video_output(dssdev, VC_VIDEO);
+
+	dsi->video_enabled = true;
+
+	dsi_set_ulps_auto(dsi, true);
+
+	dsi_bus_unlock(dsi);
 }
 
 static void dsi_bridge_disable(struct drm_bridge *bridge)
 {
 	struct dsi_data *dsi = drm_bridge_to_dsi(bridge);
+	struct omap_dss_device *dssdev = &dsi->output;
+
+	dsi_bus_lock(dsi);
+
+	dsi->video_enabled = false;
+
+	dsi_disable_video_output(dssdev, VC_VIDEO);
 
-	dsi_disable_video_outputs(&dsi->output);
+	dsi_display_disable(dssdev);
+
+	dsi_bus_unlock(dsi);
 }
 
 static const struct drm_bridge_funcs dsi_bridge_funcs = {
-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v5 21/29] drm/omap: dsi: display_enable cleanup
  2020-12-08 12:28 [PATCH v5 00/29] Convert DSI code to use drm_mipi_dsi and drm_panel (second half) Tomi Valkeinen
                   ` (19 preceding siblings ...)
  2020-12-08 12:28 ` [PATCH v5 20/29] drm/omap: dsi: move enable/disable to bridge enable/disable Tomi Valkeinen
@ 2020-12-08 12:28 ` Tomi Valkeinen
  2020-12-14 16:17   ` Sebastian Reichel
  2020-12-08 12:28 ` [PATCH v5 22/29] drm/omap: dsi: display_disable cleanup Tomi Valkeinen
                   ` (7 subsequent siblings)
  28 siblings, 1 reply; 72+ messages in thread
From: Tomi Valkeinen @ 2020-12-08 12:28 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Nikhil Devshatwar, dri-devel
  Cc: linux-omap, Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg,
	Tomi Valkeinen

We can drop dsi_display_enable(), which just calls
_dsi_display_enable(), and rename _dsi_display_enable() to
dsi_display_enable().

The WARN_ON(!dsi_bus_is_locked(dsi)) in dsi_display_enable is extra and
can be dropped, as _dsi_display_enable() has the same WARN_ON().

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/gpu/drm/omapdrm/dss/dsi.c | 16 +++-------------
 1 file changed, 3 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index 44b8e42b52ec..961b991f6498 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -3743,7 +3743,7 @@ static void dsi_display_uninit_dsi(struct dsi_data *dsi, bool disconnect_lanes,
 	}
 }
 
-static void _dsi_display_enable(struct dsi_data *dsi)
+static void dsi_display_enable(struct dsi_data *dsi)
 {
 	int r;
 
@@ -3772,16 +3772,6 @@ static void _dsi_display_enable(struct dsi_data *dsi)
 	DSSDBG("dsi_display_ulps_enable FAILED\n");
 }
 
-static void dsi_display_enable(struct omap_dss_device *dssdev)
-{
-	struct dsi_data *dsi = to_dsi_data(dssdev);
-	DSSDBG("dsi_display_enable\n");
-
-	WARN_ON(!dsi_bus_is_locked(dsi));
-
-	_dsi_display_enable(dsi);
-}
-
 static void _dsi_display_disable(struct dsi_data *dsi,
 		bool disconnect_lanes, bool enter_ulps)
 {
@@ -3856,7 +3846,7 @@ static void dsi_set_ulps_auto(struct dsi_data *dsi, bool enable)
 			return;
 
 		dsi_bus_lock(dsi);
-		_dsi_display_enable(dsi);
+		dsi_display_enable(dsi);
 		dsi_enable_te(dsi, true);
 		dsi_bus_unlock(dsi);
 	}
@@ -4947,7 +4937,7 @@ static void dsi_bridge_enable(struct drm_bridge *bridge)
 
 	dsi_bus_lock(dsi);
 
-	dsi_display_enable(dssdev);
+	dsi_display_enable(dsi);
 
 	dsi_enable_video_output(dssdev, VC_VIDEO);
 
-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v5 22/29] drm/omap: dsi: display_disable cleanup
  2020-12-08 12:28 [PATCH v5 00/29] Convert DSI code to use drm_mipi_dsi and drm_panel (second half) Tomi Valkeinen
                   ` (20 preceding siblings ...)
  2020-12-08 12:28 ` [PATCH v5 21/29] drm/omap: dsi: display_enable cleanup Tomi Valkeinen
@ 2020-12-08 12:28 ` Tomi Valkeinen
  2020-12-14 16:20   ` Sebastian Reichel
  2020-12-08 12:28 ` [PATCH v5 23/29] drm/omap: dsi: rename dsi_display_* functions Tomi Valkeinen
                   ` (6 subsequent siblings)
  28 siblings, 1 reply; 72+ messages in thread
From: Tomi Valkeinen @ 2020-12-08 12:28 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Nikhil Devshatwar, dri-devel
  Cc: linux-omap, Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg,
	Tomi Valkeinen

We can drop dsi_display_disable() which just calls
_dsi_display_disable(), and rename _dsi_display_disable() to
dsi_display_disable().

The WARN_ON(!dsi_bus_is_locked(dsi)) in dsi_display_disable is extra and
can be dropped, as _dsi_display_disable() has the same WARN_ON().

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/gpu/drm/omapdrm/dss/dsi.c | 19 +++----------------
 1 file changed, 3 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index 961b991f6498..d83346812810 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -63,8 +63,6 @@ static int dsi_vc_send_null(struct dsi_data *dsi, int vc, int channel);
 static ssize_t _omap_dsi_host_transfer(struct dsi_data *dsi, int vc,
 				       const struct mipi_dsi_msg *msg);
 
-static void dsi_display_disable(struct omap_dss_device *dssdev);
-
 #ifdef DSI_PERF_MEASURE
 static bool dsi_perf;
 module_param(dsi_perf, bool, 0644);
@@ -3772,7 +3770,7 @@ static void dsi_display_enable(struct dsi_data *dsi)
 	DSSDBG("dsi_display_ulps_enable FAILED\n");
 }
 
-static void _dsi_display_disable(struct dsi_data *dsi,
+static void dsi_display_disable(struct dsi_data *dsi,
 		bool disconnect_lanes, bool enter_ulps)
 {
 	WARN_ON(!dsi_bus_is_locked(dsi));
@@ -3791,17 +3789,6 @@ static void _dsi_display_disable(struct dsi_data *dsi,
 	mutex_unlock(&dsi->lock);
 }
 
-static void dsi_display_disable(struct omap_dss_device *dssdev)
-{
-	struct dsi_data *dsi = to_dsi_data(dssdev);
-
-	WARN_ON(!dsi_bus_is_locked(dsi));
-
-	DSSDBG("dsi_display_disable\n");
-
-	_dsi_display_disable(dsi, true, false);
-}
-
 static int dsi_enable_te(struct dsi_data *dsi, bool enable)
 {
 	dsi->te_enabled = enable;
@@ -3825,7 +3812,7 @@ static void omap_dsi_ulps_work_callback(struct work_struct *work)
 
 	dsi_enable_te(dsi, false);
 
-	_dsi_display_disable(dsi, false, true);
+	dsi_display_disable(dsi, false, true);
 
 	dsi_bus_unlock(dsi);
 }
@@ -4959,7 +4946,7 @@ static void dsi_bridge_disable(struct drm_bridge *bridge)
 
 	dsi_disable_video_output(dssdev, VC_VIDEO);
 
-	dsi_display_disable(dssdev);
+	dsi_display_disable(dsi, true, false);
 
 	dsi_bus_unlock(dsi);
 }
-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v5 23/29] drm/omap: dsi: rename dsi_display_* functions
  2020-12-08 12:28 [PATCH v5 00/29] Convert DSI code to use drm_mipi_dsi and drm_panel (second half) Tomi Valkeinen
                   ` (21 preceding siblings ...)
  2020-12-08 12:28 ` [PATCH v5 22/29] drm/omap: dsi: display_disable cleanup Tomi Valkeinen
@ 2020-12-08 12:28 ` Tomi Valkeinen
  2020-12-14 16:22   ` Sebastian Reichel
  2020-12-08 12:28 ` [PATCH v5 24/29] drm/omap: dsi: cleanup initial vc setup Tomi Valkeinen
                   ` (5 subsequent siblings)
  28 siblings, 1 reply; 72+ messages in thread
From: Tomi Valkeinen @ 2020-12-08 12:28 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Nikhil Devshatwar, dri-devel
  Cc: linux-omap, Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg,
	Tomi Valkeinen

The function names have evolved to be very confusing, and bunch of them
have "display" in them even if the function doesn't deal with display as
such (e.g. dsi_display_enable which just enables the DSI interface).
Rename them by dropping the "display".

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/gpu/drm/omapdrm/dss/dsi.c | 36 +++++++++++++++----------------
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index d83346812810..d9c2cd849328 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -55,8 +55,8 @@
 
 static void dsi_set_ulps_auto(struct dsi_data *dsi, bool enable);
 
-static int dsi_display_init_dispc(struct dsi_data *dsi);
-static void dsi_display_uninit_dispc(struct dsi_data *dsi);
+static int dsi_init_dispc(struct dsi_data *dsi);
+static void dsi_uninit_dispc(struct dsi_data *dsi);
 
 static int dsi_vc_send_null(struct dsi_data *dsi, int vc, int channel);
 
@@ -3257,7 +3257,7 @@ static void dsi_enable_video_output(struct omap_dss_device *dssdev, int vc)
 	u16 word_count;
 	int r;
 
-	r = dsi_display_init_dispc(dsi);
+	r = dsi_init_dispc(dsi);
 	if (r) {
 		dev_err(dsi->dev, "failed to init dispc!\n");
 		return;
@@ -3309,7 +3309,7 @@ static void dsi_enable_video_output(struct omap_dss_device *dssdev, int vc)
 		dsi_vc_enable(dsi, vc, false);
 	}
 err_pix_fmt:
-	dsi_display_uninit_dispc(dsi);
+	dsi_uninit_dispc(dsi);
 	dev_err(dsi->dev, "failed to enable DSI encoder!\n");
 	return;
 }
@@ -3331,7 +3331,7 @@ static void dsi_disable_video_output(struct omap_dss_device *dssdev, int vc)
 
 	dss_mgr_disable(&dsi->output);
 
-	dsi_display_uninit_dispc(dsi);
+	dsi_uninit_dispc(dsi);
 }
 
 static void dsi_update_screen_dispc(struct dsi_data *dsi)
@@ -3582,7 +3582,7 @@ static int dsi_configure_dispc_clocks(struct dsi_data *dsi)
 	return 0;
 }
 
-static int dsi_display_init_dispc(struct dsi_data *dsi)
+static int dsi_init_dispc(struct dsi_data *dsi)
 {
 	enum omap_channel dispc_channel = dsi->output.dispc_channel;
 	int r;
@@ -3627,7 +3627,7 @@ static int dsi_display_init_dispc(struct dsi_data *dsi)
 	return r;
 }
 
-static void dsi_display_uninit_dispc(struct dsi_data *dsi)
+static void dsi_uninit_dispc(struct dsi_data *dsi)
 {
 	enum omap_channel dispc_channel = dsi->output.dispc_channel;
 
@@ -3654,7 +3654,7 @@ static int dsi_configure_dsi_clocks(struct dsi_data *dsi)
 	return 0;
 }
 
-static int dsi_display_init_dsi(struct dsi_data *dsi)
+static int dsi_init_dsi(struct dsi_data *dsi)
 {
 	int r;
 
@@ -3718,7 +3718,7 @@ static int dsi_display_init_dsi(struct dsi_data *dsi)
 	return r;
 }
 
-static void dsi_display_uninit_dsi(struct dsi_data *dsi, bool disconnect_lanes,
+static void dsi_uninit_dsi(struct dsi_data *dsi, bool disconnect_lanes,
 				   bool enter_ulps)
 {
 	if (enter_ulps && !dsi->ulps_enabled)
@@ -3741,7 +3741,7 @@ static void dsi_display_uninit_dsi(struct dsi_data *dsi, bool disconnect_lanes,
 	}
 }
 
-static void dsi_display_enable(struct dsi_data *dsi)
+static void dsi_enable(struct dsi_data *dsi)
 {
 	int r;
 
@@ -3755,7 +3755,7 @@ static void dsi_display_enable(struct dsi_data *dsi)
 
 	_dsi_initialize_irq(dsi);
 
-	r = dsi_display_init_dsi(dsi);
+	r = dsi_init_dsi(dsi);
 	if (r)
 		goto err_init_dsi;
 
@@ -3767,10 +3767,10 @@ static void dsi_display_enable(struct dsi_data *dsi)
 	dsi_runtime_put(dsi);
 err_get_dsi:
 	mutex_unlock(&dsi->lock);
-	DSSDBG("dsi_display_ulps_enable FAILED\n");
+	DSSDBG("dsi_enable FAILED\n");
 }
 
-static void dsi_display_disable(struct dsi_data *dsi,
+static void dsi_disable(struct dsi_data *dsi,
 		bool disconnect_lanes, bool enter_ulps)
 {
 	WARN_ON(!dsi_bus_is_locked(dsi));
@@ -3782,7 +3782,7 @@ static void dsi_display_disable(struct dsi_data *dsi,
 	dsi_sync_vc(dsi, 2);
 	dsi_sync_vc(dsi, 3);
 
-	dsi_display_uninit_dsi(dsi, disconnect_lanes, enter_ulps);
+	dsi_uninit_dsi(dsi, disconnect_lanes, enter_ulps);
 
 	dsi_runtime_put(dsi);
 
@@ -3812,7 +3812,7 @@ static void omap_dsi_ulps_work_callback(struct work_struct *work)
 
 	dsi_enable_te(dsi, false);
 
-	dsi_display_disable(dsi, false, true);
+	dsi_disable(dsi, false, true);
 
 	dsi_bus_unlock(dsi);
 }
@@ -3833,7 +3833,7 @@ static void dsi_set_ulps_auto(struct dsi_data *dsi, bool enable)
 			return;
 
 		dsi_bus_lock(dsi);
-		dsi_display_enable(dsi);
+		dsi_enable(dsi);
 		dsi_enable_te(dsi, true);
 		dsi_bus_unlock(dsi);
 	}
@@ -4924,7 +4924,7 @@ static void dsi_bridge_enable(struct drm_bridge *bridge)
 
 	dsi_bus_lock(dsi);
 
-	dsi_display_enable(dsi);
+	dsi_enable(dsi);
 
 	dsi_enable_video_output(dssdev, VC_VIDEO);
 
@@ -4946,7 +4946,7 @@ static void dsi_bridge_disable(struct drm_bridge *bridge)
 
 	dsi_disable_video_output(dssdev, VC_VIDEO);
 
-	dsi_display_disable(dsi, true, false);
+	dsi_disable(dsi, true, false);
 
 	dsi_bus_unlock(dsi);
 }
-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v5 24/29] drm/omap: dsi: cleanup initial vc setup
  2020-12-08 12:28 [PATCH v5 00/29] Convert DSI code to use drm_mipi_dsi and drm_panel (second half) Tomi Valkeinen
                   ` (22 preceding siblings ...)
  2020-12-08 12:28 ` [PATCH v5 23/29] drm/omap: dsi: rename dsi_display_* functions Tomi Valkeinen
@ 2020-12-08 12:28 ` Tomi Valkeinen
  2020-12-14 16:34   ` Sebastian Reichel
  2020-12-08 12:28 ` [PATCH v5 25/29] drm/omap: dsi: split video mode enable/disable into separate func Tomi Valkeinen
                   ` (4 subsequent siblings)
  28 siblings, 1 reply; 72+ messages in thread
From: Tomi Valkeinen @ 2020-12-08 12:28 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Nikhil Devshatwar, dri-devel
  Cc: linux-omap, Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg,
	Tomi Valkeinen

As we now have a fixed setup for VCs (VC0 for video stream, VC1 for
commands), we can simplify the VC setup.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/gpu/drm/omapdrm/dss/dsi.c | 85 +++++++++++--------------------
 1 file changed, 31 insertions(+), 54 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index d9c2cd849328..c32884f167b8 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -2017,40 +2017,6 @@ static void dsi_vc_initial_config(struct dsi_data *dsi, int vc)
 	dsi->vc[vc].source = DSI_VC_SOURCE_L4;
 }
 
-static int dsi_vc_config_source(struct dsi_data *dsi, int vc,
-				enum dsi_vc_source source)
-{
-	if (dsi->vc[vc].source == source)
-		return 0;
-
-	DSSDBG("Source config of VC %d", vc);
-
-	dsi_sync_vc(dsi, vc);
-
-	dsi_vc_enable(dsi, vc, 0);
-
-	/* VC_BUSY */
-	if (!wait_for_bit_change(dsi, DSI_VC_CTRL(vc), 15, 0)) {
-		DSSERR("vc(%d) busy when trying to config for VP\n", vc);
-		return -EIO;
-	}
-
-	/* SOURCE, 0 = L4, 1 = video port */
-	REG_FLD_MOD(dsi, DSI_VC_CTRL(vc), source, 1, 1);
-
-	/* DCS_CMD_ENABLE */
-	if (dsi->data->quirks & DSI_QUIRK_DCS_CMD_CONFIG_VC) {
-		bool enable = source == DSI_VC_SOURCE_VP;
-		REG_FLD_MOD(dsi, DSI_VC_CTRL(vc), enable, 30, 30);
-	}
-
-	dsi_vc_enable(dsi, vc, 1);
-
-	dsi->vc[vc].source = source;
-
-	return 0;
-}
-
 static void dsi_vc_enable_hs(struct omap_dss_device *dssdev, int vc,
 		bool enable)
 {
@@ -2072,10 +2038,6 @@ static void dsi_vc_enable_hs(struct omap_dss_device *dssdev, int vc,
 	dsi_if_enable(dsi, 1);
 
 	dsi_force_tx_stop_mode_io(dsi);
-
-	/* start the DDR clock by sending a NULL packet */
-	if (dsi->vm_timings.ddr_clk_always_on && enable)
-		dsi_vc_send_null(dsi, vc, dsi->dsidev->channel);
 }
 
 static void dsi_vc_flush_long_data(struct dsi_data *dsi, int vc)
@@ -2270,8 +2232,6 @@ static int dsi_vc_send_long(struct dsi_data *dsi, int vc,
 		return -EINVAL;
 	}
 
-	dsi_vc_config_source(dsi, vc, DSI_VC_SOURCE_L4);
-
 	dsi_vc_write_long_header(dsi, vc, msg->channel, msg->type, msg->tx_len, 0);
 
 	p = msg->tx_buf;
@@ -2331,8 +2291,6 @@ static int dsi_vc_send_short(struct dsi_data *dsi, int vc,
 		DSSDBG("dsi_vc_send_short(ch%d, dt %#x, b1 %#x, b2 %#x)\n",
 		       vc, msg->type, pkt.header[1], pkt.header[2]);
 
-	dsi_vc_config_source(dsi, vc, DSI_VC_SOURCE_L4);
-
 	if (FLD_GET(dsi_read_reg(dsi, DSI_VC_CTRL(vc)), 16, 16)) {
 		DSSERR("ERROR FIFO FULL, aborting transfer\n");
 		return -EINVAL;
@@ -3351,8 +3309,6 @@ static void dsi_update_screen_dispc(struct dsi_data *dsi)
 
 	DSSDBG("dsi_update_screen_dispc(%dx%d)\n", w, h);
 
-	dsi_vc_config_source(dsi, vc, DSI_VC_SOURCE_VP);
-
 	bytespp	= mipi_dsi_pixel_format_to_bpp(dsi->pix_fmt) / 8;
 	bytespl = w * bytespp;
 	bytespf = bytespl * h;
@@ -3522,14 +3478,12 @@ static int dsi_update_channel(struct omap_dss_device *dssdev, int vc)
 
 	dsi_set_ulps_auto(dsi, false);
 
-	dsi_vc_enable_hs(dssdev, vc, true);
-
 	/*
 	 * Send NOP between the frames. If we don't send something here, the
 	 * updates stop working. This is probably related to DSI spec stating
 	 * that the DSI host should transition to LP at least once per frame.
 	 */
-	r = _dsi_send_nop(dsi, vc, dsi->dsidev->channel);
+	r = _dsi_send_nop(dsi, VC_CMD, dsi->dsidev->channel);
 	if (r < 0) {
 		DSSWARN("failed to send nop between frames: %d\n", r);
 		goto err;
@@ -3654,6 +3608,35 @@ static int dsi_configure_dsi_clocks(struct dsi_data *dsi)
 	return 0;
 }
 
+static void dsi_setup_dsi_vcs(struct dsi_data *dsi)
+{
+	/* Setup VC_CMD for LP and cpu transfers */
+	REG_FLD_MOD(dsi, DSI_VC_CTRL(VC_CMD), 0, 9, 9); /* LP */
+
+	REG_FLD_MOD(dsi, DSI_VC_CTRL(VC_CMD), 0, 1, 1); /* SOURCE_L4 */
+	dsi->vc[VC_CMD].source = DSI_VC_SOURCE_L4;
+
+	/* Setup VC_VIDEO for HS and dispc transfers */
+	REG_FLD_MOD(dsi, DSI_VC_CTRL(VC_VIDEO), 1, 9, 9); /* HS */
+
+	REG_FLD_MOD(dsi, DSI_VC_CTRL(VC_VIDEO), 1, 1, 1); /* SOURCE_VP */
+	dsi->vc[VC_VIDEO].source = DSI_VC_SOURCE_VP;
+
+	if (dsi->data->quirks & DSI_QUIRK_DCS_CMD_CONFIG_VC)
+		REG_FLD_MOD(dsi, DSI_VC_CTRL(VC_VIDEO), 1, 30, 30); /* DCS_CMD_ENABLE */
+
+	dsi_vc_enable(dsi, VC_CMD, 1);
+	dsi_vc_enable(dsi, VC_VIDEO, 1);
+
+	dsi_if_enable(dsi, 1);
+
+	dsi_force_tx_stop_mode_io(dsi);
+
+	/* start the DDR clock by sending a NULL packet */
+	if (dsi->vm_timings.ddr_clk_always_on)
+		dsi_vc_send_null(dsi, VC_CMD, dsi->dsidev->channel);
+}
+
 static int dsi_init_dsi(struct dsi_data *dsi)
 {
 	int r;
@@ -3696,13 +3679,7 @@ static int dsi_init_dsi(struct dsi_data *dsi)
 	if (r)
 		goto err3;
 
-	/* enable interface */
-	dsi_vc_enable(dsi, 0, 1);
-	dsi_vc_enable(dsi, 1, 1);
-	dsi_vc_enable(dsi, 2, 1);
-	dsi_vc_enable(dsi, 3, 1);
-	dsi_if_enable(dsi, 1);
-	dsi_force_tx_stop_mode_io(dsi);
+	dsi_setup_dsi_vcs(dsi);
 
 	return 0;
 err3:
-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v5 25/29] drm/omap: dsi: split video mode enable/disable into separate func
  2020-12-08 12:28 [PATCH v5 00/29] Convert DSI code to use drm_mipi_dsi and drm_panel (second half) Tomi Valkeinen
                   ` (23 preceding siblings ...)
  2020-12-08 12:28 ` [PATCH v5 24/29] drm/omap: dsi: cleanup initial vc setup Tomi Valkeinen
@ 2020-12-08 12:28 ` Tomi Valkeinen
  2020-12-14 16:38   ` Sebastian Reichel
  2020-12-08 12:28 ` [PATCH v5 26/29] drm/omap: dsi: fix and cleanup ddr_clk_always_on Tomi Valkeinen
                   ` (3 subsequent siblings)
  28 siblings, 1 reply; 72+ messages in thread
From: Tomi Valkeinen @ 2020-12-08 12:28 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Nikhil Devshatwar, dri-devel
  Cc: linux-omap, Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg,
	Tomi Valkeinen

Clean up the code by separating video-mode enable/disable code into
functions of their own.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/gpu/drm/omapdrm/dss/dsi.c | 101 +++++++++++++++++-------------
 1 file changed, 57 insertions(+), 44 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index c32884f167b8..71de6119d2de 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -3207,12 +3207,61 @@ static int dsi_configure_pins(struct dsi_data *dsi,
 	return 0;
 }
 
-static void dsi_enable_video_output(struct omap_dss_device *dssdev, int vc)
+static int dsi_enable_video_mode(struct dsi_data *dsi, int vc)
 {
-	struct dsi_data *dsi = to_dsi_data(dssdev);
 	int bpp = mipi_dsi_pixel_format_to_bpp(dsi->pix_fmt);
 	u8 data_type;
 	u16 word_count;
+
+	switch (dsi->pix_fmt) {
+	case MIPI_DSI_FMT_RGB888:
+		data_type = MIPI_DSI_PACKED_PIXEL_STREAM_24;
+		break;
+	case MIPI_DSI_FMT_RGB666:
+		data_type = MIPI_DSI_PIXEL_STREAM_3BYTE_18;
+		break;
+	case MIPI_DSI_FMT_RGB666_PACKED:
+		data_type = MIPI_DSI_PACKED_PIXEL_STREAM_18;
+		break;
+	case MIPI_DSI_FMT_RGB565:
+		data_type = MIPI_DSI_PACKED_PIXEL_STREAM_16;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	dsi_if_enable(dsi, false);
+	dsi_vc_enable(dsi, vc, false);
+
+	/* MODE, 1 = video mode */
+	REG_FLD_MOD(dsi, DSI_VC_CTRL(vc), 1, 4, 4);
+
+	word_count = DIV_ROUND_UP(dsi->vm.hactive * bpp, 8);
+
+	dsi_vc_write_long_header(dsi, vc, dsi->dsidev->channel, data_type,
+			word_count, 0);
+
+	dsi_vc_enable(dsi, vc, true);
+	dsi_if_enable(dsi, true);
+
+	return 0;
+}
+
+static void dsi_disable_video_mode(struct dsi_data *dsi, int vc)
+{
+	dsi_if_enable(dsi, false);
+	dsi_vc_enable(dsi, vc, false);
+
+	/* MODE, 0 = command mode */
+	REG_FLD_MOD(dsi, DSI_VC_CTRL(vc), 0, 4, 4);
+
+	dsi_vc_enable(dsi, vc, true);
+	dsi_if_enable(dsi, true);
+}
+
+static void dsi_enable_video_output(struct omap_dss_device *dssdev, int vc)
+{
+	struct dsi_data *dsi = to_dsi_data(dssdev);
 	int r;
 
 	r = dsi_init_dispc(dsi);
@@ -3222,37 +3271,9 @@ static void dsi_enable_video_output(struct omap_dss_device *dssdev, int vc)
 	}
 
 	if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) {
-		switch (dsi->pix_fmt) {
-		case MIPI_DSI_FMT_RGB888:
-			data_type = MIPI_DSI_PACKED_PIXEL_STREAM_24;
-			break;
-		case MIPI_DSI_FMT_RGB666:
-			data_type = MIPI_DSI_PIXEL_STREAM_3BYTE_18;
-			break;
-		case MIPI_DSI_FMT_RGB666_PACKED:
-			data_type = MIPI_DSI_PACKED_PIXEL_STREAM_18;
-			break;
-		case MIPI_DSI_FMT_RGB565:
-			data_type = MIPI_DSI_PACKED_PIXEL_STREAM_16;
-			break;
-		default:
-			r = -EINVAL;
-			goto err_pix_fmt;
-		}
-
-		dsi_if_enable(dsi, false);
-		dsi_vc_enable(dsi, vc, false);
-
-		/* MODE, 1 = video mode */
-		REG_FLD_MOD(dsi, DSI_VC_CTRL(vc), 1, 4, 4);
-
-		word_count = DIV_ROUND_UP(dsi->vm.hactive * bpp, 8);
-
-		dsi_vc_write_long_header(dsi, vc, dsi->dsidev->channel, data_type,
-				word_count, 0);
-
-		dsi_vc_enable(dsi, vc, true);
-		dsi_if_enable(dsi, true);
+		r = dsi_enable_video_mode(dsi, vc);
+		if (r)
+			goto err_video_mode;
 	}
 
 	r = dss_mgr_enable(&dsi->output);
@@ -3266,7 +3287,7 @@ static void dsi_enable_video_output(struct omap_dss_device *dssdev, int vc)
 		dsi_if_enable(dsi, false);
 		dsi_vc_enable(dsi, vc, false);
 	}
-err_pix_fmt:
+err_video_mode:
 	dsi_uninit_dispc(dsi);
 	dev_err(dsi->dev, "failed to enable DSI encoder!\n");
 	return;
@@ -3276,16 +3297,8 @@ static void dsi_disable_video_output(struct omap_dss_device *dssdev, int vc)
 {
 	struct dsi_data *dsi = to_dsi_data(dssdev);
 
-	if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) {
-		dsi_if_enable(dsi, false);
-		dsi_vc_enable(dsi, vc, false);
-
-		/* MODE, 0 = command mode */
-		REG_FLD_MOD(dsi, DSI_VC_CTRL(vc), 0, 4, 4);
-
-		dsi_vc_enable(dsi, vc, true);
-		dsi_if_enable(dsi, true);
-	}
+	if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE)
+		dsi_disable_video_mode(dsi, vc);
 
 	dss_mgr_disable(&dsi->output);
 
-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v5 26/29] drm/omap: dsi: fix and cleanup ddr_clk_always_on
  2020-12-08 12:28 [PATCH v5 00/29] Convert DSI code to use drm_mipi_dsi and drm_panel (second half) Tomi Valkeinen
                   ` (24 preceding siblings ...)
  2020-12-08 12:28 ` [PATCH v5 25/29] drm/omap: dsi: split video mode enable/disable into separate func Tomi Valkeinen
@ 2020-12-08 12:28 ` Tomi Valkeinen
  2020-12-14 16:39   ` Sebastian Reichel
  2020-12-08 12:28 ` [PATCH v5 27/29] drm/omap: dsi: remove ulps support Tomi Valkeinen
                   ` (2 subsequent siblings)
  28 siblings, 1 reply; 72+ messages in thread
From: Tomi Valkeinen @ 2020-12-08 12:28 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Nikhil Devshatwar, dri-devel
  Cc: linux-omap, Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg,
	Tomi Valkeinen

The driver ignores MIPI_DSI_CLOCK_NON_CONTINUOUS, and always uses
non-continuous clock.

Fix this by using MIPI_DSI_CLOCK_NON_CONTINUOUS and at the same time,
drop ddr_clk_always_on field which seems pretty useless.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/gpu/drm/omapdrm/dss/dsi.c | 12 +++++-------
 drivers/gpu/drm/omapdrm/dss/dsi.h |  2 --
 2 files changed, 5 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index 71de6119d2de..cc8b169b2223 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -1734,11 +1734,10 @@ static int dsi_cio_init(struct dsi_data *dsi)
 
 	dsi_cio_timings(dsi);
 
-	if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) {
-		/* DDR_CLK_ALWAYS_ON */
-		REG_FLD_MOD(dsi, DSI_CLK_CTRL,
-			dsi->vm_timings.ddr_clk_always_on, 13, 13);
-	}
+	/* DDR_CLK_ALWAYS_ON */
+	REG_FLD_MOD(dsi, DSI_CLK_CTRL,
+		    !(dsi->dsidev->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS),
+		    13, 13);
 
 	dsi->ulps_enabled = false;
 
@@ -3646,7 +3645,7 @@ static void dsi_setup_dsi_vcs(struct dsi_data *dsi)
 	dsi_force_tx_stop_mode_io(dsi);
 
 	/* start the DDR clock by sending a NULL packet */
-	if (dsi->vm_timings.ddr_clk_always_on)
+	if (!(dsi->dsidev->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS))
 		dsi_vc_send_null(dsi, VC_CMD, dsi->dsidev->channel);
 }
 
@@ -4155,7 +4154,6 @@ static bool dsi_vm_calc_blanking(struct dsi_clk_calc_ctx *ctx)
 	dsi_vm->hfp_blanking_mode = 1;
 	dsi_vm->hbp_blanking_mode = 1;
 
-	dsi_vm->ddr_clk_always_on = cfg->ddr_clk_always_on;
 	dsi_vm->window_sync = 4;
 
 	/* setup DISPC videomode */
diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.h b/drivers/gpu/drm/omapdrm/dss/dsi.h
index 478fc10bd18d..476069fda082 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.h
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.h
@@ -212,7 +212,6 @@ struct omap_dss_dsi_videomode_timings {
 
 	enum omap_dss_dsi_trans_mode trans_mode;
 
-	bool ddr_clk_always_on;
 	int window_sync;
 };
 
@@ -224,7 +223,6 @@ struct omap_dss_dsi_config {
 	unsigned long hs_clk_min, hs_clk_max;
 	unsigned long lp_clk_min, lp_clk_max;
 
-	bool ddr_clk_always_on;
 	enum omap_dss_dsi_trans_mode trans_mode;
 };
 
-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v5 27/29] drm/omap: dsi: remove ulps support
  2020-12-08 12:28 [PATCH v5 00/29] Convert DSI code to use drm_mipi_dsi and drm_panel (second half) Tomi Valkeinen
                   ` (25 preceding siblings ...)
  2020-12-08 12:28 ` [PATCH v5 26/29] drm/omap: dsi: fix and cleanup ddr_clk_always_on Tomi Valkeinen
@ 2020-12-08 12:28 ` Tomi Valkeinen
  2020-12-14 17:39   ` Sebastian Reichel
  2020-12-08 12:28 ` [PATCH v5 28/29] drm/omap: dsi: fix DCS_CMD_ENABLE Tomi Valkeinen
  2020-12-08 12:28 ` [PATCH v5 29/29] drm/omap: dsi: allow DSI commands to be sent early Tomi Valkeinen
  28 siblings, 1 reply; 72+ messages in thread
From: Tomi Valkeinen @ 2020-12-08 12:28 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Nikhil Devshatwar, dri-devel
  Cc: linux-omap, Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg,
	Tomi Valkeinen

ULPS doesn't work, and I have been unable to get it to work. As ULPS is
a minor power-saving feature which requires substantial amount of
non-trivial code, and we have trouble just getting and
keeping DSI working at all, remove ULPS support.

When the DSI driver works reliably for command and video mode displays,
someone interested can add it back.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/gpu/drm/omapdrm/dss/dsi.c | 297 +-----------------------------
 drivers/gpu/drm/omapdrm/dss/dsi.h |   4 -
 2 files changed, 8 insertions(+), 293 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index cc8b169b2223..b2aa07a09dcd 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -53,8 +53,6 @@
 #define REG_FLD_MOD(dsi, idx, val, start, end) \
 	dsi_write_reg(dsi, idx, FLD_MOD(dsi_read_reg(dsi, idx), val, start, end))
 
-static void dsi_set_ulps_auto(struct dsi_data *dsi, bool enable);
-
 static int dsi_init_dispc(struct dsi_data *dsi);
 static void dsi_uninit_dispc(struct dsi_data *dsi);
 
@@ -688,44 +686,6 @@ static int dsi_unregister_isr_vc(struct dsi_data *dsi, int vc,
 	return r;
 }
 
-static int dsi_register_isr_cio(struct dsi_data *dsi, omap_dsi_isr_t isr,
-				void *arg, u32 mask)
-{
-	unsigned long flags;
-	int r;
-
-	spin_lock_irqsave(&dsi->irq_lock, flags);
-
-	r = _dsi_register_isr(isr, arg, mask, dsi->isr_tables.isr_table_cio,
-			ARRAY_SIZE(dsi->isr_tables.isr_table_cio));
-
-	if (r == 0)
-		_omap_dsi_set_irqs_cio(dsi);
-
-	spin_unlock_irqrestore(&dsi->irq_lock, flags);
-
-	return r;
-}
-
-static int dsi_unregister_isr_cio(struct dsi_data *dsi, omap_dsi_isr_t isr,
-				  void *arg, u32 mask)
-{
-	unsigned long flags;
-	int r;
-
-	spin_lock_irqsave(&dsi->irq_lock, flags);
-
-	r = _dsi_unregister_isr(isr, arg, mask, dsi->isr_tables.isr_table_cio,
-			ARRAY_SIZE(dsi->isr_tables.isr_table_cio));
-
-	if (r == 0)
-		_omap_dsi_set_irqs_cio(dsi);
-
-	spin_unlock_irqrestore(&dsi->irq_lock, flags);
-
-	return r;
-}
-
 static u32 dsi_get_errors(struct dsi_data *dsi)
 {
 	unsigned long flags;
@@ -1450,56 +1410,6 @@ static void dsi_cio_timings(struct dsi_data *dsi)
 	dsi_write_reg(dsi, DSI_DSIPHY_CFG2, r);
 }
 
-/* lane masks have lane 0 at lsb. mask_p for positive lines, n for negative */
-static void dsi_cio_enable_lane_override(struct dsi_data *dsi,
-					 unsigned int mask_p,
-					 unsigned int mask_n)
-{
-	int i;
-	u32 l;
-	u8 lptxscp_start = dsi->num_lanes_supported == 3 ? 22 : 26;
-
-	l = 0;
-
-	for (i = 0; i < dsi->num_lanes_supported; ++i) {
-		unsigned int p = dsi->lanes[i].polarity;
-
-		if (mask_p & (1 << i))
-			l |= 1 << (i * 2 + (p ? 0 : 1));
-
-		if (mask_n & (1 << i))
-			l |= 1 << (i * 2 + (p ? 1 : 0));
-	}
-
-	/*
-	 * Bits in REGLPTXSCPDAT4TO0DXDY:
-	 * 17: DY0 18: DX0
-	 * 19: DY1 20: DX1
-	 * 21: DY2 22: DX2
-	 * 23: DY3 24: DX3
-	 * 25: DY4 26: DX4
-	 */
-
-	/* Set the lane override configuration */
-
-	/* REGLPTXSCPDAT4TO0DXDY */
-	REG_FLD_MOD(dsi, DSI_DSIPHY_CFG10, l, lptxscp_start, 17);
-
-	/* Enable lane override */
-
-	/* ENLPTXSCPDAT */
-	REG_FLD_MOD(dsi, DSI_DSIPHY_CFG10, 1, 27, 27);
-}
-
-static void dsi_cio_disable_lane_override(struct dsi_data *dsi)
-{
-	/* Disable lane override */
-	REG_FLD_MOD(dsi, DSI_DSIPHY_CFG10, 0, 27, 27); /* ENLPTXSCPDAT */
-	/* Reset the lane override configuration */
-	/* REGLPTXSCPDAT4TO0DXDY */
-	REG_FLD_MOD(dsi, DSI_DSIPHY_CFG10, 0, 22, 17);
-}
-
 static int dsi_cio_wait_tx_clk_esc_reset(struct dsi_data *dsi)
 {
 	int t, i;
@@ -1674,32 +1584,6 @@ static int dsi_cio_init(struct dsi_data *dsi)
 	l = FLD_MOD(l, 0x1fff, 12, 0);	/* STOP_STATE_COUNTER_IO */
 	dsi_write_reg(dsi, DSI_TIMING1, l);
 
-	if (dsi->ulps_enabled) {
-		unsigned int mask_p;
-		int i;
-
-		DSSDBG("manual ulps exit\n");
-
-		/* ULPS is exited by Mark-1 state for 1ms, followed by
-		 * stop state. DSS HW cannot do this via the normal
-		 * ULPS exit sequence, as after reset the DSS HW thinks
-		 * that we are not in ULPS mode, and refuses to send the
-		 * sequence. So we need to send the ULPS exit sequence
-		 * manually by setting positive lines high and negative lines
-		 * low for 1ms.
-		 */
-
-		mask_p = 0;
-
-		for (i = 0; i < dsi->num_lanes_supported; ++i) {
-			if (dsi->lanes[i].function == DSI_LANE_UNUSED)
-				continue;
-			mask_p |= 1 << i;
-		}
-
-		dsi_cio_enable_lane_override(dsi, mask_p, 0);
-	}
-
 	r = dsi_cio_power(dsi, DSI_COMPLEXIO_POWER_ON);
 	if (r)
 		goto err_cio_pwr;
@@ -1718,17 +1602,6 @@ static int dsi_cio_init(struct dsi_data *dsi)
 	if (r)
 		goto err_tx_clk_esc_rst;
 
-	if (dsi->ulps_enabled) {
-		/* Keep Mark-1 state for 1ms (as per DSI spec) */
-		ktime_t wait = ns_to_ktime(1000 * 1000);
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_hrtimeout(&wait, HRTIMER_MODE_REL);
-
-		/* Disable the override. The lanes should be set to Mark-11
-		 * state by the HW */
-		dsi_cio_disable_lane_override(dsi);
-	}
-
 	/* FORCE_TX_STOP_MODE_IO */
 	REG_FLD_MOD(dsi, DSI_TIMING1, 0, 15, 15);
 
@@ -1739,8 +1612,6 @@ static int dsi_cio_init(struct dsi_data *dsi)
 		    !(dsi->dsidev->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS),
 		    13, 13);
 
-	dsi->ulps_enabled = false;
-
 	DSSDBG("CIO init done\n");
 
 	return 0;
@@ -1750,8 +1621,6 @@ static int dsi_cio_init(struct dsi_data *dsi)
 err_cio_pwr_dom:
 	dsi_cio_power(dsi, DSI_COMPLEXIO_POWER_OFF);
 err_cio_pwr:
-	if (dsi->ulps_enabled)
-		dsi_cio_disable_lane_override(dsi);
 err_scp_clk_dom:
 	dsi_disable_scp_clk(dsi);
 	dsi_disable_pads(dsi);
@@ -2522,99 +2391,6 @@ static int dsi_vc_generic_read(struct omap_dss_device *dssdev, int vc,
 	return r;
 }
 
-static int dsi_enter_ulps(struct dsi_data *dsi)
-{
-	DECLARE_COMPLETION_ONSTACK(completion);
-	int r, i;
-	unsigned int mask;
-
-	DSSDBG("Entering ULPS");
-
-	WARN_ON(!dsi_bus_is_locked(dsi));
-
-	WARN_ON(dsi->ulps_enabled);
-
-	if (dsi->ulps_enabled)
-		return 0;
-
-	/* DDR_CLK_ALWAYS_ON */
-	if (REG_GET(dsi, DSI_CLK_CTRL, 13, 13)) {
-		dsi_if_enable(dsi, 0);
-		REG_FLD_MOD(dsi, DSI_CLK_CTRL, 0, 13, 13);
-		dsi_if_enable(dsi, 1);
-	}
-
-	dsi_sync_vc(dsi, 0);
-	dsi_sync_vc(dsi, 1);
-	dsi_sync_vc(dsi, 2);
-	dsi_sync_vc(dsi, 3);
-
-	dsi_force_tx_stop_mode_io(dsi);
-
-	dsi_vc_enable(dsi, 0, false);
-	dsi_vc_enable(dsi, 1, false);
-	dsi_vc_enable(dsi, 2, false);
-	dsi_vc_enable(dsi, 3, false);
-
-	if (REG_GET(dsi, DSI_COMPLEXIO_CFG2, 16, 16)) {	/* HS_BUSY */
-		DSSERR("HS busy when enabling ULPS\n");
-		return -EIO;
-	}
-
-	if (REG_GET(dsi, DSI_COMPLEXIO_CFG2, 17, 17)) {	/* LP_BUSY */
-		DSSERR("LP busy when enabling ULPS\n");
-		return -EIO;
-	}
-
-	r = dsi_register_isr_cio(dsi, dsi_completion_handler, &completion,
-			DSI_CIO_IRQ_ULPSACTIVENOT_ALL0);
-	if (r)
-		return r;
-
-	mask = 0;
-
-	for (i = 0; i < dsi->num_lanes_supported; ++i) {
-		if (dsi->lanes[i].function == DSI_LANE_UNUSED)
-			continue;
-		mask |= 1 << i;
-	}
-	/* Assert TxRequestEsc for data lanes and TxUlpsClk for clk lane */
-	/* LANEx_ULPS_SIG2 */
-	REG_FLD_MOD(dsi, DSI_COMPLEXIO_CFG2, mask, 9, 5);
-
-	/* flush posted write and wait for SCP interface to finish the write */
-	dsi_read_reg(dsi, DSI_COMPLEXIO_CFG2);
-
-	if (wait_for_completion_timeout(&completion,
-				msecs_to_jiffies(1000)) == 0) {
-		DSSERR("ULPS enable timeout\n");
-		r = -EIO;
-		goto err;
-	}
-
-	dsi_unregister_isr_cio(dsi, dsi_completion_handler, &completion,
-			DSI_CIO_IRQ_ULPSACTIVENOT_ALL0);
-
-	/* Reset LANEx_ULPS_SIG2 */
-	REG_FLD_MOD(dsi, DSI_COMPLEXIO_CFG2, 0, 9, 5);
-
-	/* flush posted write and wait for SCP interface to finish the write */
-	dsi_read_reg(dsi, DSI_COMPLEXIO_CFG2);
-
-	dsi_cio_power(dsi, DSI_COMPLEXIO_POWER_ULPS);
-
-	dsi_if_enable(dsi, false);
-
-	dsi->ulps_enabled = true;
-
-	return 0;
-
-err:
-	dsi_unregister_isr_cio(dsi, dsi_completion_handler, &completion,
-			DSI_CIO_IRQ_ULPSACTIVENOT_ALL0);
-	return r;
-}
-
 static void dsi_set_lp_rx_timeout(struct dsi_data *dsi, unsigned int ticks,
 				  bool x4, bool x16)
 {
@@ -3397,7 +3173,6 @@ static void dsi_handle_framedone(struct dsi_data *dsi, int error)
 		REG_FLD_MOD(dsi, DSI_TIMING2, 1, 15, 15); /* LP_RX_TO */
 	}
 
-	dsi_set_ulps_auto(dsi, true);
 	dsi_bus_unlock(dsi);
 
 	if (!error)
@@ -3488,8 +3263,6 @@ static int dsi_update_channel(struct omap_dss_device *dssdev, int vc)
 
 	DSSDBG("dsi_update_channel: %d", vc);
 
-	dsi_set_ulps_auto(dsi, false);
-
 	/*
 	 * Send NOP between the frames. If we don't send something here, the
 	 * updates stop working. This is probably related to DSI spec stating
@@ -3514,7 +3287,6 @@ static int dsi_update_channel(struct omap_dss_device *dssdev, int vc)
 	return 0;
 
 err:
-	dsi_set_ulps_auto(dsi, true);
 	dsi_bus_unlock(dsi);
 	return r;
 }
@@ -3707,12 +3479,8 @@ static int dsi_init_dsi(struct dsi_data *dsi)
 	return r;
 }
 
-static void dsi_uninit_dsi(struct dsi_data *dsi, bool disconnect_lanes,
-				   bool enter_ulps)
+static void dsi_uninit_dsi(struct dsi_data *dsi)
 {
-	if (enter_ulps && !dsi->ulps_enabled)
-		dsi_enter_ulps(dsi);
-
 	/* disable interface */
 	dsi_if_enable(dsi, 0);
 	dsi_vc_enable(dsi, 0, 0);
@@ -3724,10 +3492,8 @@ static void dsi_uninit_dsi(struct dsi_data *dsi, bool disconnect_lanes,
 	dsi_cio_uninit(dsi);
 	dss_pll_disable(&dsi->pll);
 
-	if (disconnect_lanes) {
-		regulator_disable(dsi->vdds_dsi_reg);
-		dsi->vdds_dsi_enabled = false;
-	}
+	regulator_disable(dsi->vdds_dsi_reg);
+	dsi->vdds_dsi_enabled = false;
 }
 
 static void dsi_enable(struct dsi_data *dsi)
@@ -3759,8 +3525,7 @@ static void dsi_enable(struct dsi_data *dsi)
 	DSSDBG("dsi_enable FAILED\n");
 }
 
-static void dsi_disable(struct dsi_data *dsi,
-		bool disconnect_lanes, bool enter_ulps)
+static void dsi_disable(struct dsi_data *dsi)
 {
 	WARN_ON(!dsi_bus_is_locked(dsi));
 
@@ -3771,7 +3536,7 @@ static void dsi_disable(struct dsi_data *dsi,
 	dsi_sync_vc(dsi, 2);
 	dsi_sync_vc(dsi, 3);
 
-	dsi_uninit_dsi(dsi, disconnect_lanes, enter_ulps);
+	dsi_uninit_dsi(dsi);
 
 	dsi_runtime_put(dsi);
 
@@ -3792,42 +3557,6 @@ static int dsi_enable_te(struct dsi_data *dsi, bool enable)
 	return 0;
 }
 
-static void omap_dsi_ulps_work_callback(struct work_struct *work)
-{
-	struct dsi_data *dsi = container_of(work, struct dsi_data,
-					    ulps_work.work);
-
-	dsi_bus_lock(dsi);
-
-	dsi_enable_te(dsi, false);
-
-	dsi_disable(dsi, false, true);
-
-	dsi_bus_unlock(dsi);
-}
-
-static void dsi_set_ulps_auto(struct dsi_data *dsi, bool enable)
-{
-	WARN_ON(!dsi_bus_is_locked(dsi));
-
-	if (!dsi->ulps_auto_idle)
-		return;
-
-	if (enable) {
-		schedule_delayed_work(&dsi->ulps_work, msecs_to_jiffies(250));
-	} else {
-		cancel_delayed_work_sync(&dsi->ulps_work);
-
-		if (!dsi->ulps_enabled)
-			return;
-
-		dsi_bus_lock(dsi);
-		dsi_enable(dsi);
-		dsi_enable_te(dsi, true);
-		dsi_bus_unlock(dsi);
-	}
-}
-
 #ifdef PRINT_VERBOSE_VM_TIMINGS
 static void print_dsi_vm(const char *str,
 		const struct omap_dss_dsi_videomode_timings *t)
@@ -4499,13 +4228,10 @@ static ssize_t omap_dsi_host_transfer(struct mipi_dsi_host *host,
 
 	dsi_bus_lock(dsi);
 
-	if (dsi->video_enabled) {
-		dsi_set_ulps_auto(dsi, false);
+	if (dsi->video_enabled)
 		r = _omap_dsi_host_transfer(dsi, vc, msg);
-		dsi_set_ulps_auto(dsi, true);
-	} else {
+	else
 		r = -EIO;
-	}
 
 	dsi_bus_unlock(dsi);
 
@@ -4647,9 +4373,6 @@ static int omap_dsi_host_attach(struct mipi_dsi_host *host,
 	dsi->dsidev = client;
 	dsi->pix_fmt = client->format;
 
-	INIT_DEFERRABLE_WORK(&dsi->ulps_work,
-			     omap_dsi_ulps_work_callback);
-
 	dsi->config.hs_clk_min = 150000000; // TODO: get from client?
 	dsi->config.hs_clk_max = client->hs_rate;
 	dsi->config.lp_clk_min = 7000000; // TODO: get from client?
@@ -4662,8 +4385,6 @@ static int omap_dsi_host_attach(struct mipi_dsi_host *host,
 	else
 		dsi->config.trans_mode = OMAP_DSS_DSI_EVENT_MODE;
 
-	dsi->ulps_auto_idle = false;
-
 	return 0;
 }
 
@@ -4918,8 +4639,6 @@ static void dsi_bridge_enable(struct drm_bridge *bridge)
 
 	dsi->video_enabled = true;
 
-	dsi_set_ulps_auto(dsi, true);
-
 	dsi_bus_unlock(dsi);
 }
 
@@ -4934,7 +4653,7 @@ static void dsi_bridge_disable(struct drm_bridge *bridge)
 
 	dsi_disable_video_output(dssdev, VC_VIDEO);
 
-	dsi_disable(dsi, true, false);
+	dsi_disable(dsi);
 
 	dsi_bus_unlock(dsi);
 }
diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.h b/drivers/gpu/drm/omapdrm/dss/dsi.h
index 476069fda082..de9411067ba2 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.h
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.h
@@ -394,12 +394,8 @@ struct dsi_data {
 	atomic_t do_ext_te_update;
 
 	bool te_enabled;
-	bool ulps_enabled;
-	bool ulps_auto_idle;
 	bool video_enabled;
 
-	struct delayed_work ulps_work;
-
 	struct delayed_work framedone_timeout_work;
 
 #ifdef DSI_CATCH_MISSING_TE
-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v5 28/29] drm/omap: dsi: fix DCS_CMD_ENABLE
  2020-12-08 12:28 [PATCH v5 00/29] Convert DSI code to use drm_mipi_dsi and drm_panel (second half) Tomi Valkeinen
                   ` (26 preceding siblings ...)
  2020-12-08 12:28 ` [PATCH v5 27/29] drm/omap: dsi: remove ulps support Tomi Valkeinen
@ 2020-12-08 12:28 ` Tomi Valkeinen
  2020-12-14 16:48   ` Sebastian Reichel
  2020-12-08 12:28 ` [PATCH v5 29/29] drm/omap: dsi: allow DSI commands to be sent early Tomi Valkeinen
  28 siblings, 1 reply; 72+ messages in thread
From: Tomi Valkeinen @ 2020-12-08 12:28 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Nikhil Devshatwar, dri-devel
  Cc: linux-omap, Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg,
	Tomi Valkeinen

We only need to set VC_CTRL:DCS_CMD_ENABLE for command mode panels when
the HW has DSI_QUIRK_DCS_CMD_CONFIG_VC quirk. The old code did this
right by accident, but now we set DCS_CMD_ENABLE for video mode panels
too.

Fix this by skipping the set for video mode.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/gpu/drm/omapdrm/dss/dsi.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index b2aa07a09dcd..53a64bc91867 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -3406,7 +3406,8 @@ static void dsi_setup_dsi_vcs(struct dsi_data *dsi)
 	REG_FLD_MOD(dsi, DSI_VC_CTRL(VC_VIDEO), 1, 1, 1); /* SOURCE_VP */
 	dsi->vc[VC_VIDEO].source = DSI_VC_SOURCE_VP;
 
-	if (dsi->data->quirks & DSI_QUIRK_DCS_CMD_CONFIG_VC)
+	if ((dsi->data->quirks & DSI_QUIRK_DCS_CMD_CONFIG_VC) &&
+	    !(dsi->dsidev->mode_flags & MIPI_DSI_MODE_VIDEO))
 		REG_FLD_MOD(dsi, DSI_VC_CTRL(VC_VIDEO), 1, 30, 30); /* DCS_CMD_ENABLE */
 
 	dsi_vc_enable(dsi, VC_CMD, 1);
-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v5 29/29] drm/omap: dsi: allow DSI commands to be sent early
  2020-12-08 12:28 [PATCH v5 00/29] Convert DSI code to use drm_mipi_dsi and drm_panel (second half) Tomi Valkeinen
                   ` (27 preceding siblings ...)
  2020-12-08 12:28 ` [PATCH v5 28/29] drm/omap: dsi: fix DCS_CMD_ENABLE Tomi Valkeinen
@ 2020-12-08 12:28 ` Tomi Valkeinen
  2020-12-08 15:48   ` Laurent Pinchart
  2020-12-14 17:17   ` Sebastian Reichel
  28 siblings, 2 replies; 72+ messages in thread
From: Tomi Valkeinen @ 2020-12-08 12:28 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Nikhil Devshatwar, dri-devel
  Cc: linux-omap, Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg,
	Tomi Valkeinen

Panel drivers can send DSI commands in panel's prepare(), which happens
before the bridge's enable() is called. The OMAP DSI driver currently
only sets up the DSI interface at bridge's enable(), so prepare() cannot
be used to send DSI commands.

This patch fixes the issue by making it possible to enable the DSI
interface any time a command is about to be sent. Disabling the
interface is be done via delayed work.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/gpu/drm/omapdrm/dss/dsi.c | 49 +++++++++++++++++++++++++++----
 drivers/gpu/drm/omapdrm/dss/dsi.h |  3 ++
 2 files changed, 47 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index 53a64bc91867..34f665aa9a59 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -3503,6 +3503,9 @@ static void dsi_enable(struct dsi_data *dsi)
 
 	WARN_ON(!dsi_bus_is_locked(dsi));
 
+	if (WARN_ON(dsi->iface_enabled))
+		return;
+
 	mutex_lock(&dsi->lock);
 
 	r = dsi_runtime_get(dsi);
@@ -3515,6 +3518,8 @@ static void dsi_enable(struct dsi_data *dsi)
 	if (r)
 		goto err_init_dsi;
 
+	dsi->iface_enabled = true;
+
 	mutex_unlock(&dsi->lock);
 
 	return;
@@ -3530,6 +3535,9 @@ static void dsi_disable(struct dsi_data *dsi)
 {
 	WARN_ON(!dsi_bus_is_locked(dsi));
 
+	if (WARN_ON(!dsi->iface_enabled))
+		return;
+
 	mutex_lock(&dsi->lock);
 
 	dsi_sync_vc(dsi, 0);
@@ -3541,6 +3549,8 @@ static void dsi_disable(struct dsi_data *dsi)
 
 	dsi_runtime_put(dsi);
 
+	dsi->iface_enabled = false;
+
 	mutex_unlock(&dsi->lock);
 }
 
@@ -4229,10 +4239,12 @@ static ssize_t omap_dsi_host_transfer(struct mipi_dsi_host *host,
 
 	dsi_bus_lock(dsi);
 
-	if (dsi->video_enabled)
-		r = _omap_dsi_host_transfer(dsi, vc, msg);
-	else
-		r = -EIO;
+	if (!dsi->iface_enabled) {
+		dsi_enable(dsi);
+		schedule_delayed_work(&dsi->dsi_disable_work, msecs_to_jiffies(2000));
+	}
+
+	r = _omap_dsi_host_transfer(dsi, vc, msg);
 
 	dsi_bus_unlock(dsi);
 
@@ -4397,6 +4409,14 @@ static int omap_dsi_host_detach(struct mipi_dsi_host *host,
 	if (WARN_ON(dsi->dsidev != client))
 		return -EINVAL;
 
+	cancel_delayed_work_sync(&dsi->dsi_disable_work);
+
+	if (dsi->iface_enabled) {
+		dsi_bus_lock(dsi);
+		dsi_disable(dsi);
+		dsi_bus_unlock(dsi);
+	}
+
 	omap_dsi_unregister_te_irq(dsi);
 	dsi->dsidev = NULL;
 	return 0;
@@ -4632,9 +4652,12 @@ static void dsi_bridge_enable(struct drm_bridge *bridge)
 	struct dsi_data *dsi = drm_bridge_to_dsi(bridge);
 	struct omap_dss_device *dssdev = &dsi->output;
 
+	cancel_delayed_work_sync(&dsi->dsi_disable_work);
+
 	dsi_bus_lock(dsi);
 
-	dsi_enable(dsi);
+	if (!dsi->iface_enabled)
+		dsi_enable(dsi);
 
 	dsi_enable_video_output(dssdev, VC_VIDEO);
 
@@ -4648,6 +4671,8 @@ static void dsi_bridge_disable(struct drm_bridge *bridge)
 	struct dsi_data *dsi = drm_bridge_to_dsi(bridge);
 	struct omap_dss_device *dssdev = &dsi->output;
 
+	cancel_delayed_work_sync(&dsi->dsi_disable_work);
+
 	dsi_bus_lock(dsi);
 
 	dsi->video_enabled = false;
@@ -4840,6 +4865,18 @@ static const struct soc_device_attribute dsi_soc_devices[] = {
 	{ /* sentinel */ }
 };
 
+static void omap_dsi_disable_work_callback(struct work_struct *work)
+{
+	struct dsi_data *dsi = container_of(work, struct dsi_data, dsi_disable_work.work);
+
+	dsi_bus_lock(dsi);
+
+	if (dsi->iface_enabled && !dsi->video_enabled)
+		dsi_disable(dsi);
+
+	dsi_bus_unlock(dsi);
+}
+
 static int dsi_probe(struct platform_device *pdev)
 {
 	const struct soc_device_attribute *soc;
@@ -4873,6 +4910,8 @@ static int dsi_probe(struct platform_device *pdev)
 	INIT_DEFERRABLE_WORK(&dsi->framedone_timeout_work,
 			     dsi_framedone_timeout_work_callback);
 
+	INIT_DEFERRABLE_WORK(&dsi->dsi_disable_work, omap_dsi_disable_work_callback);
+
 #ifdef DSI_CATCH_MISSING_TE
 	timer_setup(&dsi->te_timer, dsi_te_timeout, 0);
 #endif
diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.h b/drivers/gpu/drm/omapdrm/dss/dsi.h
index de9411067ba2..601707c0ecc4 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.h
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.h
@@ -394,6 +394,7 @@ struct dsi_data {
 	atomic_t do_ext_te_update;
 
 	bool te_enabled;
+	bool iface_enabled;
 	bool video_enabled;
 
 	struct delayed_work framedone_timeout_work;
@@ -443,6 +444,8 @@ struct dsi_data {
 
 	struct omap_dss_device output;
 	struct drm_bridge bridge;
+
+	struct delayed_work dsi_disable_work;
 };
 
 struct dsi_packet_sent_handler_data {
-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* Re: [PATCH v5 09/29] drm/omap: dsi: cleanup dispc channel usage
  2020-12-08 12:28 ` [PATCH v5 09/29] drm/omap: dsi: cleanup dispc channel usage Tomi Valkeinen
@ 2020-12-08 15:17   ` Laurent Pinchart
  2020-12-14 14:35   ` Sebastian Reichel
  1 sibling, 0 replies; 72+ messages in thread
From: Laurent Pinchart @ 2020-12-08 15:17 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Sebastian Reichel, Nikhil Devshatwar, dri-devel, linux-omap,
	Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg

Hi Tomi,

Thank you for the patch.

On Tue, Dec 08, 2020 at 02:28:35PM +0200, Tomi Valkeinen wrote:
> The "channel" usage in omap dsi driver is confusing. As the first step,
> change "channel" to "dispc_channel" when dealing with the dispc channel.
> 
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

> ---
>  drivers/gpu/drm/omapdrm/dss/dsi.c | 16 ++++++++--------
>  1 file changed, 8 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
> index c78ae99c8742..cf0dc4872d14 100644
> --- a/drivers/gpu/drm/omapdrm/dss/dsi.c
> +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
> @@ -3978,10 +3978,10 @@ static int dsi_configure_dispc_clocks(struct dsi_data *dsi)
>  
>  static int dsi_display_init_dispc(struct dsi_data *dsi)
>  {
> -	enum omap_channel channel = dsi->output.dispc_channel;
> +	enum omap_channel dispc_channel = dsi->output.dispc_channel;
>  	int r;
>  
> -	dss_select_lcd_clk_source(dsi->dss, channel, dsi->module_id == 0 ?
> +	dss_select_lcd_clk_source(dsi->dss, dispc_channel, dsi->module_id == 0 ?
>  			DSS_CLK_SRC_PLL1_1 :
>  			DSS_CLK_SRC_PLL2_1);
>  
> @@ -4017,19 +4017,19 @@ static int dsi_display_init_dispc(struct dsi_data *dsi)
>  		dss_mgr_unregister_framedone_handler(&dsi->output,
>  				dsi_framedone_irq_callback, dsi);
>  err:
> -	dss_select_lcd_clk_source(dsi->dss, channel, DSS_CLK_SRC_FCK);
> +	dss_select_lcd_clk_source(dsi->dss, dispc_channel, DSS_CLK_SRC_FCK);
>  	return r;
>  }
>  
>  static void dsi_display_uninit_dispc(struct dsi_data *dsi)
>  {
> -	enum omap_channel channel = dsi->output.dispc_channel;
> +	enum omap_channel dispc_channel = dsi->output.dispc_channel;
>  
>  	if (dsi->mode == OMAP_DSS_DSI_CMD_MODE)
>  		dss_mgr_unregister_framedone_handler(&dsi->output,
>  				dsi_framedone_irq_callback, dsi);
>  
> -	dss_select_lcd_clk_source(dsi->dss, channel, DSS_CLK_SRC_FCK);
> +	dss_select_lcd_clk_source(dsi->dss, dispc_channel, DSS_CLK_SRC_FCK);
>  }
>  
>  static int dsi_configure_dsi_clocks(struct dsi_data *dsi)
> @@ -4846,12 +4846,12 @@ static int dsi_set_config(struct omap_dss_device *dssdev,
>  }
>  
>  /*
> - * Return a hardcoded channel for the DSI output. This should work for
> + * Return a hardcoded dispc channel for the DSI output. This should work for
>   * current use cases, but this can be later expanded to either resolve
>   * the channel in some more dynamic manner, or get the channel as a user
>   * parameter.
>   */
> -static enum omap_channel dsi_get_channel(struct dsi_data *dsi)
> +static enum omap_channel dsi_get_dispc_channel(struct dsi_data *dsi)
>  {
>  	switch (dsi->data->model) {
>  	case DSI_MODEL_OMAP3:
> @@ -5403,7 +5403,7 @@ static int dsi_init_output(struct dsi_data *dsi)
>  
>  	out->type = OMAP_DISPLAY_TYPE_DSI;
>  	out->name = dsi->module_id == 0 ? "dsi.0" : "dsi.1";
> -	out->dispc_channel = dsi_get_channel(dsi);
> +	out->dispc_channel = dsi_get_dispc_channel(dsi);
>  	out->dsi_ops = &dsi_ops;
>  	out->of_port = 0;
>  	out->bus_flags = DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE

-- 
Regards,

Laurent Pinchart

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v5 10/29] drm/omap: dsi: rename 'channel' to 'vc'
  2020-12-08 12:28 ` [PATCH v5 10/29] drm/omap: dsi: rename 'channel' to 'vc' Tomi Valkeinen
@ 2020-12-08 15:22   ` Laurent Pinchart
  2020-12-14 15:18   ` Sebastian Reichel
  1 sibling, 0 replies; 72+ messages in thread
From: Laurent Pinchart @ 2020-12-08 15:22 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Sebastian Reichel, Nikhil Devshatwar, dri-devel, linux-omap,
	Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg

Hi Tomi,

Thank you for the patch.

On Tue, Dec 08, 2020 at 02:28:36PM +0200, Tomi Valkeinen wrote:
> The "channel" usage in omap dsi driver is confusing. We have three
> different "channels":
> 
> 1) DSI virtual channel ID. This is a number from 0 to 3, included in the
> packet payload.
> 
> 2) VC. This is a register block in the DSI IP. There are four of those
> blocks. A VC is a DSI "pipeline", with defined fifo settings, data
> source (cpu or dispc), and some other settings. It has no relation to
> the 1).
> 
> 3) dispc channel. It's the "pipeline" number dispc uses to send pixel
> data.
> 
> The previous patch handled the third case.
> 
>  To start fixing 1) and 2), we first rename all uses of 'channel' to
> 'vc', as in most of the cases that is the correct thing to use.
> 
> However, in some places 1) and 2) have gotten mixed up (i.e. the code
> uses msg->channel when it should use vc), which will be fixed in the
> following patch.
> 
> Note that mixing 1) and 2) currently is "fine", as at the moment we only
> support DSI peripherals with DSI virtual channel 0, and we always use
> VC0 to send data. So both 1) and 2) are always 0.
> 
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

> ---
>  drivers/gpu/drm/omapdrm/dss/dsi.c | 220 +++++++++++++++---------------
>  1 file changed, 110 insertions(+), 110 deletions(-)
> 
> diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
> index cf0dc4872d14..273159e8f992 100644
> --- a/drivers/gpu/drm/omapdrm/dss/dsi.c
> +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
> @@ -214,7 +214,7 @@ static void dsi_set_ulps_auto(struct dsi_data *dsi, bool enable);
>  static int dsi_display_init_dispc(struct dsi_data *dsi);
>  static void dsi_display_uninit_dispc(struct dsi_data *dsi);
>  
> -static int dsi_vc_send_null(struct dsi_data *dsi, int channel);
> +static int dsi_vc_send_null(struct dsi_data *dsi, int vc);
>  
>  static ssize_t _omap_dsi_host_transfer(struct dsi_data *dsi,
>  				       const struct mipi_dsi_msg *msg);
> @@ -376,7 +376,7 @@ struct dsi_data {
>  	/* space for a copy used by the interrupt handler */
>  	struct dsi_isr_tables isr_tables_copy;
>  
> -	int update_channel;
> +	int update_vc;
>  #ifdef DSI_PERF_MEASURE
>  	unsigned int update_bytes;
>  #endif
> @@ -639,7 +639,7 @@ static void print_irq_status(u32 status)
>  #undef PIS
>  }
>  
> -static void print_irq_status_vc(int channel, u32 status)
> +static void print_irq_status_vc(int vc, u32 status)
>  {
>  	if (status == 0)
>  		return;
> @@ -650,7 +650,7 @@ static void print_irq_status_vc(int channel, u32 status)
>  #define PIS(x) (status & DSI_VC_IRQ_##x) ? (#x " ") : ""
>  
>  	pr_debug("DSI VC(%d) IRQ 0x%x: %s%s%s%s%s%s%s%s%s\n",
> -		channel,
> +		vc,
>  		status,
>  		PIS(CS),
>  		PIS(ECC_CORR),
> @@ -1031,7 +1031,7 @@ static int dsi_unregister_isr(struct dsi_data *dsi, omap_dsi_isr_t isr,
>  	return r;
>  }
>  
> -static int dsi_register_isr_vc(struct dsi_data *dsi, int channel,
> +static int dsi_register_isr_vc(struct dsi_data *dsi, int vc,
>  			       omap_dsi_isr_t isr, void *arg, u32 mask)
>  {
>  	unsigned long flags;
> @@ -1040,18 +1040,18 @@ static int dsi_register_isr_vc(struct dsi_data *dsi, int channel,
>  	spin_lock_irqsave(&dsi->irq_lock, flags);
>  
>  	r = _dsi_register_isr(isr, arg, mask,
> -			dsi->isr_tables.isr_table_vc[channel],
> -			ARRAY_SIZE(dsi->isr_tables.isr_table_vc[channel]));
> +			dsi->isr_tables.isr_table_vc[vc],
> +			ARRAY_SIZE(dsi->isr_tables.isr_table_vc[vc]));
>  
>  	if (r == 0)
> -		_omap_dsi_set_irqs_vc(dsi, channel);
> +		_omap_dsi_set_irqs_vc(dsi, vc);
>  
>  	spin_unlock_irqrestore(&dsi->irq_lock, flags);
>  
>  	return r;
>  }
>  
> -static int dsi_unregister_isr_vc(struct dsi_data *dsi, int channel,
> +static int dsi_unregister_isr_vc(struct dsi_data *dsi, int vc,
>  				 omap_dsi_isr_t isr, void *arg, u32 mask)
>  {
>  	unsigned long flags;
> @@ -1060,11 +1060,11 @@ static int dsi_unregister_isr_vc(struct dsi_data *dsi, int channel,
>  	spin_lock_irqsave(&dsi->irq_lock, flags);
>  
>  	r = _dsi_unregister_isr(isr, arg, mask,
> -			dsi->isr_tables.isr_table_vc[channel],
> -			ARRAY_SIZE(dsi->isr_tables.isr_table_vc[channel]));
> +			dsi->isr_tables.isr_table_vc[vc],
> +			ARRAY_SIZE(dsi->isr_tables.isr_table_vc[vc]));
>  
>  	if (r == 0)
> -		_omap_dsi_set_irqs_vc(dsi, channel);
> +		_omap_dsi_set_irqs_vc(dsi, vc);
>  
>  	spin_unlock_irqrestore(&dsi->irq_lock, flags);
>  
> @@ -2232,9 +2232,9 @@ static int dsi_force_tx_stop_mode_io(struct dsi_data *dsi)
>  	return 0;
>  }
>  
> -static bool dsi_vc_is_enabled(struct dsi_data *dsi, int channel)
> +static bool dsi_vc_is_enabled(struct dsi_data *dsi, int vc)
>  {
> -	return REG_GET(dsi, DSI_VC_CTRL(channel), 0, 0);
> +	return REG_GET(dsi, DSI_VC_CTRL(vc), 0, 0);
>  }
>  
>  static void dsi_packet_sent_handler_vp(void *data, u32 mask)
> @@ -2242,14 +2242,14 @@ static void dsi_packet_sent_handler_vp(void *data, u32 mask)
>  	struct dsi_packet_sent_handler_data *vp_data =
>  		(struct dsi_packet_sent_handler_data *) data;
>  	struct dsi_data *dsi = vp_data->dsi;
> -	const int channel = dsi->update_channel;
> +	const int vc = dsi->update_vc;
>  	u8 bit = dsi->te_enabled ? 30 : 31;
>  
> -	if (REG_GET(dsi, DSI_VC_TE(channel), bit, bit) == 0)
> +	if (REG_GET(dsi, DSI_VC_TE(vc), bit, bit) == 0)
>  		complete(vp_data->completion);
>  }
>  
> -static int dsi_sync_vc_vp(struct dsi_data *dsi, int channel)
> +static int dsi_sync_vc_vp(struct dsi_data *dsi, int vc)
>  {
>  	DECLARE_COMPLETION_ONSTACK(completion);
>  	struct dsi_packet_sent_handler_data vp_data = {
> @@ -2261,13 +2261,13 @@ static int dsi_sync_vc_vp(struct dsi_data *dsi, int channel)
>  
>  	bit = dsi->te_enabled ? 30 : 31;
>  
> -	r = dsi_register_isr_vc(dsi, channel, dsi_packet_sent_handler_vp,
> +	r = dsi_register_isr_vc(dsi, vc, dsi_packet_sent_handler_vp,
>  		&vp_data, DSI_VC_IRQ_PACKET_SENT);
>  	if (r)
>  		goto err0;
>  
>  	/* Wait for completion only if TE_EN/TE_START is still set */
> -	if (REG_GET(dsi, DSI_VC_TE(channel), bit, bit)) {
> +	if (REG_GET(dsi, DSI_VC_TE(vc), bit, bit)) {
>  		if (wait_for_completion_timeout(&completion,
>  				msecs_to_jiffies(10)) == 0) {
>  			DSSERR("Failed to complete previous frame transfer\n");
> @@ -2276,12 +2276,12 @@ static int dsi_sync_vc_vp(struct dsi_data *dsi, int channel)
>  		}
>  	}
>  
> -	dsi_unregister_isr_vc(dsi, channel, dsi_packet_sent_handler_vp,
> +	dsi_unregister_isr_vc(dsi, vc, dsi_packet_sent_handler_vp,
>  		&vp_data, DSI_VC_IRQ_PACKET_SENT);
>  
>  	return 0;
>  err1:
> -	dsi_unregister_isr_vc(dsi, channel, dsi_packet_sent_handler_vp,
> +	dsi_unregister_isr_vc(dsi, vc, dsi_packet_sent_handler_vp,
>  		&vp_data, DSI_VC_IRQ_PACKET_SENT);
>  err0:
>  	return r;
> @@ -2292,13 +2292,13 @@ static void dsi_packet_sent_handler_l4(void *data, u32 mask)
>  	struct dsi_packet_sent_handler_data *l4_data =
>  		(struct dsi_packet_sent_handler_data *) data;
>  	struct dsi_data *dsi = l4_data->dsi;
> -	const int channel = dsi->update_channel;
> +	const int vc = dsi->update_vc;
>  
> -	if (REG_GET(dsi, DSI_VC_CTRL(channel), 5, 5) == 0)
> +	if (REG_GET(dsi, DSI_VC_CTRL(vc), 5, 5) == 0)
>  		complete(l4_data->completion);
>  }
>  
> -static int dsi_sync_vc_l4(struct dsi_data *dsi, int channel)
> +static int dsi_sync_vc_l4(struct dsi_data *dsi, int vc)
>  {
>  	DECLARE_COMPLETION_ONSTACK(completion);
>  	struct dsi_packet_sent_handler_data l4_data = {
> @@ -2307,13 +2307,13 @@ static int dsi_sync_vc_l4(struct dsi_data *dsi, int channel)
>  	};
>  	int r = 0;
>  
> -	r = dsi_register_isr_vc(dsi, channel, dsi_packet_sent_handler_l4,
> +	r = dsi_register_isr_vc(dsi, vc, dsi_packet_sent_handler_l4,
>  		&l4_data, DSI_VC_IRQ_PACKET_SENT);
>  	if (r)
>  		goto err0;
>  
>  	/* Wait for completion only if TX_FIFO_NOT_EMPTY is still set */
> -	if (REG_GET(dsi, DSI_VC_CTRL(channel), 5, 5)) {
> +	if (REG_GET(dsi, DSI_VC_CTRL(vc), 5, 5)) {
>  		if (wait_for_completion_timeout(&completion,
>  				msecs_to_jiffies(10)) == 0) {
>  			DSSERR("Failed to complete previous l4 transfer\n");
> @@ -2322,47 +2322,47 @@ static int dsi_sync_vc_l4(struct dsi_data *dsi, int channel)
>  		}
>  	}
>  
> -	dsi_unregister_isr_vc(dsi, channel, dsi_packet_sent_handler_l4,
> +	dsi_unregister_isr_vc(dsi, vc, dsi_packet_sent_handler_l4,
>  		&l4_data, DSI_VC_IRQ_PACKET_SENT);
>  
>  	return 0;
>  err1:
> -	dsi_unregister_isr_vc(dsi, channel, dsi_packet_sent_handler_l4,
> +	dsi_unregister_isr_vc(dsi, vc, dsi_packet_sent_handler_l4,
>  		&l4_data, DSI_VC_IRQ_PACKET_SENT);
>  err0:
>  	return r;
>  }
>  
> -static int dsi_sync_vc(struct dsi_data *dsi, int channel)
> +static int dsi_sync_vc(struct dsi_data *dsi, int vc)
>  {
>  	WARN_ON(!dsi_bus_is_locked(dsi));
>  
>  	WARN_ON(in_interrupt());
>  
> -	if (!dsi_vc_is_enabled(dsi, channel))
> +	if (!dsi_vc_is_enabled(dsi, vc))
>  		return 0;
>  
> -	switch (dsi->vc[channel].source) {
> +	switch (dsi->vc[vc].source) {
>  	case DSI_VC_SOURCE_VP:
> -		return dsi_sync_vc_vp(dsi, channel);
> +		return dsi_sync_vc_vp(dsi, vc);
>  	case DSI_VC_SOURCE_L4:
> -		return dsi_sync_vc_l4(dsi, channel);
> +		return dsi_sync_vc_l4(dsi, vc);
>  	default:
>  		BUG();
>  		return -EINVAL;
>  	}
>  }
>  
> -static int dsi_vc_enable(struct dsi_data *dsi, int channel, bool enable)
> +static int dsi_vc_enable(struct dsi_data *dsi, int vc, bool enable)
>  {
> -	DSSDBG("dsi_vc_enable channel %d, enable %d\n",
> -			channel, enable);
> +	DSSDBG("dsi_vc_enable vc %d, enable %d\n",
> +			vc, enable);
>  
>  	enable = enable ? 1 : 0;
>  
> -	REG_FLD_MOD(dsi, DSI_VC_CTRL(channel), enable, 0, 0);
> +	REG_FLD_MOD(dsi, DSI_VC_CTRL(vc), enable, 0, 0);
>  
> -	if (!wait_for_bit_change(dsi, DSI_VC_CTRL(channel), 0, enable)) {
> +	if (!wait_for_bit_change(dsi, DSI_VC_CTRL(vc), 0, enable)) {
>  		DSSERR("Failed to set dsi_vc_enable to %d\n", enable);
>  		return -EIO;
>  	}
> @@ -2370,17 +2370,17 @@ static int dsi_vc_enable(struct dsi_data *dsi, int channel, bool enable)
>  	return 0;
>  }
>  
> -static void dsi_vc_initial_config(struct dsi_data *dsi, int channel)
> +static void dsi_vc_initial_config(struct dsi_data *dsi, int vc)
>  {
>  	u32 r;
>  
> -	DSSDBG("Initial config of virtual channel %d", channel);
> +	DSSDBG("Initial config of VC %d", vc);
>  
> -	r = dsi_read_reg(dsi, DSI_VC_CTRL(channel));
> +	r = dsi_read_reg(dsi, DSI_VC_CTRL(vc));
>  
>  	if (FLD_GET(r, 15, 15)) /* VC_BUSY */
>  		DSSERR("VC(%d) busy when trying to configure it!\n",
> -				channel);
> +				vc);
>  
>  	r = FLD_MOD(r, 0, 1, 1); /* SOURCE, 0 = L4 */
>  	r = FLD_MOD(r, 0, 2, 2); /* BTA_SHORT_EN  */
> @@ -2395,76 +2395,76 @@ static void dsi_vc_initial_config(struct dsi_data *dsi, int channel)
>  	r = FLD_MOD(r, 4, 29, 27); /* DMA_RX_REQ_NB = no dma */
>  	r = FLD_MOD(r, 4, 23, 21); /* DMA_TX_REQ_NB = no dma */
>  
> -	dsi_write_reg(dsi, DSI_VC_CTRL(channel), r);
> +	dsi_write_reg(dsi, DSI_VC_CTRL(vc), r);
>  
> -	dsi->vc[channel].source = DSI_VC_SOURCE_L4;
> +	dsi->vc[vc].source = DSI_VC_SOURCE_L4;
>  }
>  
> -static int dsi_vc_config_source(struct dsi_data *dsi, int channel,
> +static int dsi_vc_config_source(struct dsi_data *dsi, int vc,
>  				enum dsi_vc_source source)
>  {
> -	if (dsi->vc[channel].source == source)
> +	if (dsi->vc[vc].source == source)
>  		return 0;
>  
> -	DSSDBG("Source config of virtual channel %d", channel);
> +	DSSDBG("Source config of VC %d", vc);
>  
> -	dsi_sync_vc(dsi, channel);
> +	dsi_sync_vc(dsi, vc);
>  
> -	dsi_vc_enable(dsi, channel, 0);
> +	dsi_vc_enable(dsi, vc, 0);
>  
>  	/* VC_BUSY */
> -	if (!wait_for_bit_change(dsi, DSI_VC_CTRL(channel), 15, 0)) {
> -		DSSERR("vc(%d) busy when trying to config for VP\n", channel);
> +	if (!wait_for_bit_change(dsi, DSI_VC_CTRL(vc), 15, 0)) {
> +		DSSERR("vc(%d) busy when trying to config for VP\n", vc);
>  		return -EIO;
>  	}
>  
>  	/* SOURCE, 0 = L4, 1 = video port */
> -	REG_FLD_MOD(dsi, DSI_VC_CTRL(channel), source, 1, 1);
> +	REG_FLD_MOD(dsi, DSI_VC_CTRL(vc), source, 1, 1);
>  
>  	/* DCS_CMD_ENABLE */
>  	if (dsi->data->quirks & DSI_QUIRK_DCS_CMD_CONFIG_VC) {
>  		bool enable = source == DSI_VC_SOURCE_VP;
> -		REG_FLD_MOD(dsi, DSI_VC_CTRL(channel), enable, 30, 30);
> +		REG_FLD_MOD(dsi, DSI_VC_CTRL(vc), enable, 30, 30);
>  	}
>  
> -	dsi_vc_enable(dsi, channel, 1);
> +	dsi_vc_enable(dsi, vc, 1);
>  
> -	dsi->vc[channel].source = source;
> +	dsi->vc[vc].source = source;
>  
>  	return 0;
>  }
>  
> -static void dsi_vc_enable_hs(struct omap_dss_device *dssdev, int channel,
> +static void dsi_vc_enable_hs(struct omap_dss_device *dssdev, int vc,
>  		bool enable)
>  {
>  	struct dsi_data *dsi = to_dsi_data(dssdev);
>  
> -	DSSDBG("dsi_vc_enable_hs(%d, %d)\n", channel, enable);
> +	DSSDBG("dsi_vc_enable_hs(%d, %d)\n", vc, enable);
>  
>  	WARN_ON(!dsi_bus_is_locked(dsi));
>  
> -	dsi_vc_enable(dsi, channel, 0);
> +	dsi_vc_enable(dsi, vc, 0);
>  	dsi_if_enable(dsi, 0);
>  
> -	REG_FLD_MOD(dsi, DSI_VC_CTRL(channel), enable, 9, 9);
> +	REG_FLD_MOD(dsi, DSI_VC_CTRL(vc), enable, 9, 9);
>  
> -	dsi_vc_enable(dsi, channel, 1);
> +	dsi_vc_enable(dsi, vc, 1);
>  	dsi_if_enable(dsi, 1);
>  
>  	dsi_force_tx_stop_mode_io(dsi);
>  
>  	/* start the DDR clock by sending a NULL packet */
>  	if (dsi->vm_timings.ddr_clk_always_on && enable)
> -		dsi_vc_send_null(dsi, channel);
> +		dsi_vc_send_null(dsi, vc);
>  
>  	dsi->in_lp_mode = !enable;
>  }
>  
> -static void dsi_vc_flush_long_data(struct dsi_data *dsi, int channel)
> +static void dsi_vc_flush_long_data(struct dsi_data *dsi, int vc)
>  {
> -	while (REG_GET(dsi, DSI_VC_CTRL(channel), 20, 20)) {
> +	while (REG_GET(dsi, DSI_VC_CTRL(vc), 20, 20)) {
>  		u32 val;
> -		val = dsi_read_reg(dsi, DSI_VC_SHORT_PACKET_HEADER(channel));
> +		val = dsi_read_reg(dsi, DSI_VC_SHORT_PACKET_HEADER(vc));
>  		DSSDBG("\t\tb1 %#02x b2 %#02x b3 %#02x b4 %#02x\n",
>  				(val >> 0) & 0xff,
>  				(val >> 8) & 0xff,
> @@ -2510,13 +2510,13 @@ static void dsi_show_rx_ack_with_err(u16 err)
>  		DSSERR("\t\tDSI Protocol Violation\n");
>  }
>  
> -static u16 dsi_vc_flush_receive_data(struct dsi_data *dsi, int channel)
> +static u16 dsi_vc_flush_receive_data(struct dsi_data *dsi, int vc)
>  {
>  	/* RX_FIFO_NOT_EMPTY */
> -	while (REG_GET(dsi, DSI_VC_CTRL(channel), 20, 20)) {
> +	while (REG_GET(dsi, DSI_VC_CTRL(vc), 20, 20)) {
>  		u32 val;
>  		u8 dt;
> -		val = dsi_read_reg(dsi, DSI_VC_SHORT_PACKET_HEADER(channel));
> +		val = dsi_read_reg(dsi, DSI_VC_SHORT_PACKET_HEADER(vc));
>  		DSSERR("\trawval %#08x\n", val);
>  		dt = FLD_GET(val, 5, 0);
>  		if (dt == MIPI_DSI_RX_ACKNOWLEDGE_AND_ERROR_REPORT) {
> @@ -2531,7 +2531,7 @@ static u16 dsi_vc_flush_receive_data(struct dsi_data *dsi, int channel)
>  		} else if (dt == MIPI_DSI_RX_DCS_LONG_READ_RESPONSE) {
>  			DSSERR("\tDCS long response, len %d\n",
>  					FLD_GET(val, 23, 8));
> -			dsi_vc_flush_long_data(dsi, channel);
> +			dsi_vc_flush_long_data(dsi, vc);
>  		} else {
>  			DSSERR("\tunknown datatype 0x%02x\n", dt);
>  		}
> @@ -2539,35 +2539,35 @@ static u16 dsi_vc_flush_receive_data(struct dsi_data *dsi, int channel)
>  	return 0;
>  }
>  
> -static int dsi_vc_send_bta(struct dsi_data *dsi, int channel)
> +static int dsi_vc_send_bta(struct dsi_data *dsi, int vc)
>  {
>  	if (dsi->debug_write || dsi->debug_read)
> -		DSSDBG("dsi_vc_send_bta %d\n", channel);
> +		DSSDBG("dsi_vc_send_bta %d\n", vc);
>  
>  	WARN_ON(!dsi_bus_is_locked(dsi));
>  
>  	/* RX_FIFO_NOT_EMPTY */
> -	if (REG_GET(dsi, DSI_VC_CTRL(channel), 20, 20)) {
> +	if (REG_GET(dsi, DSI_VC_CTRL(vc), 20, 20)) {
>  		DSSERR("rx fifo not empty when sending BTA, dumping data:\n");
> -		dsi_vc_flush_receive_data(dsi, channel);
> +		dsi_vc_flush_receive_data(dsi, vc);
>  	}
>  
> -	REG_FLD_MOD(dsi, DSI_VC_CTRL(channel), 1, 6, 6); /* BTA_EN */
> +	REG_FLD_MOD(dsi, DSI_VC_CTRL(vc), 1, 6, 6); /* BTA_EN */
>  
>  	/* flush posted write */
> -	dsi_read_reg(dsi, DSI_VC_CTRL(channel));
> +	dsi_read_reg(dsi, DSI_VC_CTRL(vc));
>  
>  	return 0;
>  }
>  
> -static int dsi_vc_send_bta_sync(struct omap_dss_device *dssdev, int channel)
> +static int dsi_vc_send_bta_sync(struct omap_dss_device *dssdev, int vc)
>  {
>  	struct dsi_data *dsi = to_dsi_data(dssdev);
>  	DECLARE_COMPLETION_ONSTACK(completion);
>  	int r = 0;
>  	u32 err;
>  
> -	r = dsi_register_isr_vc(dsi, channel, dsi_completion_handler,
> +	r = dsi_register_isr_vc(dsi, vc, dsi_completion_handler,
>  			&completion, DSI_VC_IRQ_BTA);
>  	if (r)
>  		goto err0;
> @@ -2577,7 +2577,7 @@ static int dsi_vc_send_bta_sync(struct omap_dss_device *dssdev, int channel)
>  	if (r)
>  		goto err1;
>  
> -	r = dsi_vc_send_bta(dsi, channel);
> +	r = dsi_vc_send_bta(dsi, vc);
>  	if (r)
>  		goto err2;
>  
> @@ -2598,13 +2598,13 @@ static int dsi_vc_send_bta_sync(struct omap_dss_device *dssdev, int channel)
>  	dsi_unregister_isr(dsi, dsi_completion_handler, &completion,
>  			DSI_IRQ_ERROR_MASK);
>  err1:
> -	dsi_unregister_isr_vc(dsi, channel, dsi_completion_handler,
> +	dsi_unregister_isr_vc(dsi, vc, dsi_completion_handler,
>  			&completion, DSI_VC_IRQ_BTA);
>  err0:
>  	return r;
>  }
>  
> -static inline void dsi_vc_write_long_header(struct dsi_data *dsi, int channel,
> +static inline void dsi_vc_write_long_header(struct dsi_data *dsi, int vc,
>  					    u8 data_type, u16 len, u8 ecc)
>  {
>  	u32 val;
> @@ -2612,15 +2612,15 @@ static inline void dsi_vc_write_long_header(struct dsi_data *dsi, int channel,
>  
>  	WARN_ON(!dsi_bus_is_locked(dsi));
>  
> -	data_id = data_type | channel << 6;
> +	data_id = data_type | vc << 6;
>  
>  	val = FLD_VAL(data_id, 7, 0) | FLD_VAL(len, 23, 8) |
>  		FLD_VAL(ecc, 31, 24);
>  
> -	dsi_write_reg(dsi, DSI_VC_LONG_PACKET_HEADER(channel), val);
> +	dsi_write_reg(dsi, DSI_VC_LONG_PACKET_HEADER(vc), val);
>  }
>  
> -static inline void dsi_vc_write_long_payload(struct dsi_data *dsi, int channel,
> +static inline void dsi_vc_write_long_payload(struct dsi_data *dsi, int vc,
>  					     u8 b1, u8 b2, u8 b3, u8 b4)
>  {
>  	u32 val;
> @@ -2630,7 +2630,7 @@ static inline void dsi_vc_write_long_payload(struct dsi_data *dsi, int channel,
>  /*	DSSDBG("\twriting %02x, %02x, %02x, %02x (%#010x)\n",
>  			b1, b2, b3, b4, val); */
>  
> -	dsi_write_reg(dsi, DSI_VC_LONG_PACKET_PAYLOAD(channel), val);
> +	dsi_write_reg(dsi, DSI_VC_LONG_PACKET_PAYLOAD(vc), val);
>  }
>  
>  static int dsi_vc_send_long(struct dsi_data *dsi,
> @@ -2727,10 +2727,10 @@ static int dsi_vc_send_short(struct dsi_data *dsi,
>  	return 0;
>  }
>  
> -static int dsi_vc_send_null(struct dsi_data *dsi, int channel)
> +static int dsi_vc_send_null(struct dsi_data *dsi, int vc)
>  {
>  	const struct mipi_dsi_msg msg = {
> -		.channel = channel,
> +		.channel = vc,
>  		.type = MIPI_DSI_NULL_PACKET,
>  	};
>  
> @@ -2774,7 +2774,7 @@ static int dsi_vc_write_common(struct omap_dss_device *dssdev,
>  	return 0;
>  }
>  
> -static int dsi_vc_read_rx_fifo(struct dsi_data *dsi, int channel, u8 *buf,
> +static int dsi_vc_read_rx_fifo(struct dsi_data *dsi, int vc, u8 *buf,
>  			       int buflen, enum dss_dsi_content_type type)
>  {
>  	u32 val;
> @@ -2782,13 +2782,13 @@ static int dsi_vc_read_rx_fifo(struct dsi_data *dsi, int channel, u8 *buf,
>  	int r;
>  
>  	/* RX_FIFO_NOT_EMPTY */
> -	if (REG_GET(dsi, DSI_VC_CTRL(channel), 20, 20) == 0) {
> +	if (REG_GET(dsi, DSI_VC_CTRL(vc), 20, 20) == 0) {
>  		DSSERR("RX fifo empty when trying to read.\n");
>  		r = -EIO;
>  		goto err;
>  	}
>  
> -	val = dsi_read_reg(dsi, DSI_VC_SHORT_PACKET_HEADER(channel));
> +	val = dsi_read_reg(dsi, DSI_VC_SHORT_PACKET_HEADER(vc));
>  	if (dsi->debug_read)
>  		DSSDBG("\theader: %08x\n", val);
>  	dt = FLD_GET(val, 5, 0);
> @@ -2852,7 +2852,7 @@ static int dsi_vc_read_rx_fifo(struct dsi_data *dsi, int channel, u8 *buf,
>  		for (w = 0; w < len + 2;) {
>  			int b;
>  			val = dsi_read_reg(dsi,
> -				DSI_VC_SHORT_PACKET_HEADER(channel));
> +				DSI_VC_SHORT_PACKET_HEADER(vc));
>  			if (dsi->debug_read)
>  				DSSDBG("\t\t%02x %02x %02x %02x\n",
>  						(val >> 0) & 0xff,
> @@ -2876,7 +2876,7 @@ static int dsi_vc_read_rx_fifo(struct dsi_data *dsi, int channel, u8 *buf,
>  	}
>  
>  err:
> -	DSSERR("dsi_vc_read_rx_fifo(ch %d type %s) failed\n", channel,
> +	DSSERR("dsi_vc_read_rx_fifo(vc %d type %s) failed\n", vc,
>  		type == DSS_DSI_CONTENT_GENERIC ? "GENERIC" : "DCS");
>  
>  	return r;
> @@ -3631,7 +3631,7 @@ static int dsi_configure_pins(struct dsi_data *dsi,
>  	return 0;
>  }
>  
> -static void dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
> +static void dsi_enable_video_output(struct omap_dss_device *dssdev, int vc)
>  {
>  	struct dsi_data *dsi = to_dsi_data(dssdev);
>  	int bpp = mipi_dsi_pixel_format_to_bpp(dsi->pix_fmt);
> @@ -3665,17 +3665,17 @@ static void dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
>  		}
>  
>  		dsi_if_enable(dsi, false);
> -		dsi_vc_enable(dsi, channel, false);
> +		dsi_vc_enable(dsi, vc, false);
>  
>  		/* MODE, 1 = video mode */
> -		REG_FLD_MOD(dsi, DSI_VC_CTRL(channel), 1, 4, 4);
> +		REG_FLD_MOD(dsi, DSI_VC_CTRL(vc), 1, 4, 4);
>  
>  		word_count = DIV_ROUND_UP(dsi->vm.hactive * bpp, 8);
>  
> -		dsi_vc_write_long_header(dsi, channel, data_type,
> +		dsi_vc_write_long_header(dsi, vc, data_type,
>  				word_count, 0);
>  
> -		dsi_vc_enable(dsi, channel, true);
> +		dsi_vc_enable(dsi, vc, true);
>  		dsi_if_enable(dsi, true);
>  	}
>  
> @@ -3688,7 +3688,7 @@ static void dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
>  err_mgr_enable:
>  	if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) {
>  		dsi_if_enable(dsi, false);
> -		dsi_vc_enable(dsi, channel, false);
> +		dsi_vc_enable(dsi, vc, false);
>  	}
>  err_pix_fmt:
>  	dsi_display_uninit_dispc(dsi);
> @@ -3696,18 +3696,18 @@ static void dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
>  	return;
>  }
>  
> -static void dsi_disable_video_output(struct omap_dss_device *dssdev, int channel)
> +static void dsi_disable_video_output(struct omap_dss_device *dssdev, int vc)
>  {
>  	struct dsi_data *dsi = to_dsi_data(dssdev);
>  
>  	if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) {
>  		dsi_if_enable(dsi, false);
> -		dsi_vc_enable(dsi, channel, false);
> +		dsi_vc_enable(dsi, vc, false);
>  
>  		/* MODE, 0 = command mode */
> -		REG_FLD_MOD(dsi, DSI_VC_CTRL(channel), 0, 4, 4);
> +		REG_FLD_MOD(dsi, DSI_VC_CTRL(vc), 0, 4, 4);
>  
> -		dsi_vc_enable(dsi, channel, true);
> +		dsi_vc_enable(dsi, vc, true);
>  		dsi_if_enable(dsi, true);
>  	}
>  
> @@ -3740,14 +3740,14 @@ static void dsi_update_screen_dispc(struct dsi_data *dsi)
>  	unsigned int packet_len;
>  	u32 l;
>  	int r;
> -	const unsigned channel = dsi->update_channel;
> +	const unsigned vc = dsi->update_vc;
>  	const unsigned int line_buf_size = dsi->line_buffer_size;
>  	u16 w = dsi->vm.hactive;
>  	u16 h = dsi->vm.vactive;
>  
>  	DSSDBG("dsi_update_screen_dispc(%dx%d)\n", w, h);
>  
> -	dsi_vc_config_source(dsi, channel, DSI_VC_SOURCE_VP);
> +	dsi_vc_config_source(dsi, vc, DSI_VC_SOURCE_VP);
>  
>  	bytespp	= mipi_dsi_pixel_format_to_bpp(dsi->pix_fmt) / 8;
>  	bytespl = w * bytespp;
> @@ -3768,16 +3768,16 @@ static void dsi_update_screen_dispc(struct dsi_data *dsi)
>  		total_len += (bytespf % packet_payload) + 1;
>  
>  	l = FLD_VAL(total_len, 23, 0); /* TE_SIZE */
> -	dsi_write_reg(dsi, DSI_VC_TE(channel), l);
> +	dsi_write_reg(dsi, DSI_VC_TE(vc), l);
>  
> -	dsi_vc_write_long_header(dsi, channel, MIPI_DSI_DCS_LONG_WRITE,
> +	dsi_vc_write_long_header(dsi, vc, MIPI_DSI_DCS_LONG_WRITE,
>  		packet_len, 0);
>  
>  	if (dsi->te_enabled)
>  		l = FLD_MOD(l, 1, 30, 30); /* TE_EN */
>  	else
>  		l = FLD_MOD(l, 1, 31, 31); /* TE_START */
> -	dsi_write_reg(dsi, DSI_VC_TE(channel), l);
> +	dsi_write_reg(dsi, DSI_VC_TE(vc), l);
>  
>  	/* We put SIDLEMODE to no-idle for the duration of the transfer,
>  	 * because DSS interrupts are not capable of waking up the CPU and the
> @@ -3800,7 +3800,7 @@ static void dsi_update_screen_dispc(struct dsi_data *dsi)
>  		 * for TE is longer than the timer allows */
>  		REG_FLD_MOD(dsi, DSI_TIMING2, 0, 15, 15); /* LP_RX_TO */
>  
> -		dsi_vc_send_bta(dsi, channel);
> +		dsi_vc_send_bta(dsi, vc);
>  
>  #ifdef DSI_CATCH_MISSING_TE
>  		mod_timer(&dsi->te_timer, jiffies + msecs_to_jiffies(250));
> @@ -3897,7 +3897,7 @@ static int _dsi_send_nop(struct dsi_data *dsi, int channel)
>  	return _omap_dsi_host_transfer(dsi, &msg);
>  }
>  
> -static int dsi_update_channel(struct omap_dss_device *dssdev, int channel)
> +static int dsi_update_channel(struct omap_dss_device *dssdev, int vc)
>  {
>  	struct dsi_data *dsi = to_dsi_data(dssdev);
>  	int r;
> @@ -3914,7 +3914,7 @@ static int dsi_update_channel(struct omap_dss_device *dssdev, int channel)
>  		goto err;
>  	}
>  
> -	DSSDBG("dsi_update_channel: %d", channel);
> +	DSSDBG("dsi_update_channel: %d", vc);
>  
>  	dsi_set_ulps_auto(dsi, false);
>  
> @@ -3923,13 +3923,13 @@ static int dsi_update_channel(struct omap_dss_device *dssdev, int channel)
>  	 * updates stop working. This is probably related to DSI spec stating
>  	 * that the DSI host should transition to LP at least once per frame.
>  	 */
> -	r = _dsi_send_nop(dsi, channel);
> +	r = _dsi_send_nop(dsi, vc);
>  	if (r < 0) {
>  		DSSWARN("failed to send nop between frames: %d\n", r);
>  		goto err;
>  	}
>  
> -	dsi->update_channel = channel;
> +	dsi->update_vc = vc;
>  
>  	if (dsi->te_enabled && dsi->te_gpio) {
>  		schedule_delayed_work(&dsi->te_timeout_work,

-- 
Regards,

Laurent Pinchart

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v5 11/29] drm/omap: dsi: pass vc to various functions
  2020-12-08 12:28 ` [PATCH v5 11/29] drm/omap: dsi: pass vc to various functions Tomi Valkeinen
@ 2020-12-08 15:38   ` Laurent Pinchart
  2020-12-08 15:45     ` Tomi Valkeinen
  2020-12-14 15:37   ` Sebastian Reichel
  1 sibling, 1 reply; 72+ messages in thread
From: Laurent Pinchart @ 2020-12-08 15:38 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Sebastian Reichel, Nikhil Devshatwar, dri-devel, linux-omap,
	Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg

Hi Tomi,

Thank you for the patch.

On Tue, Dec 08, 2020 at 02:28:37PM +0200, Tomi Valkeinen wrote:
> To start fixing the issues related to channels and vcs described in the
> previous commit, pass vc to various functions which will need it do
> properly handle different DSI channels and VCs.

This is a bit hard to review as you add the OMAP DSI VC as a parameter
(named vc) to some functions , and the MIPI DSI virtual channel as a
parameter (named channel) to other functions. Only the former matches
the commit message. Splitting this in two would make the changes
clearer. Still, I believe the patch is correct, so

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

> No functional changes.
> 
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> ---
>  drivers/gpu/drm/omapdrm/dss/dsi.c | 54 ++++++++++++++++---------------
>  1 file changed, 28 insertions(+), 26 deletions(-)
> 
> diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
> index 273159e8f992..8d8412199693 100644
> --- a/drivers/gpu/drm/omapdrm/dss/dsi.c
> +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
> @@ -214,9 +214,9 @@ static void dsi_set_ulps_auto(struct dsi_data *dsi, bool enable);
>  static int dsi_display_init_dispc(struct dsi_data *dsi);
>  static void dsi_display_uninit_dispc(struct dsi_data *dsi);
>  
> -static int dsi_vc_send_null(struct dsi_data *dsi, int vc);
> +static int dsi_vc_send_null(struct dsi_data *dsi, int vc, int channel);
>  
> -static ssize_t _omap_dsi_host_transfer(struct dsi_data *dsi,
> +static ssize_t _omap_dsi_host_transfer(struct dsi_data *dsi, int vc,
>  				       const struct mipi_dsi_msg *msg);
>  
>  static void dsi_display_disable(struct omap_dss_device *dssdev);
> @@ -2455,7 +2455,7 @@ static void dsi_vc_enable_hs(struct omap_dss_device *dssdev, int vc,
>  
>  	/* start the DDR clock by sending a NULL packet */
>  	if (dsi->vm_timings.ddr_clk_always_on && enable)
> -		dsi_vc_send_null(dsi, vc);
> +		dsi_vc_send_null(dsi, vc, dsi->dsidev->channel);
>  
>  	dsi->in_lp_mode = !enable;
>  }
> @@ -2605,7 +2605,8 @@ static int dsi_vc_send_bta_sync(struct omap_dss_device *dssdev, int vc)
>  }
>  
>  static inline void dsi_vc_write_long_header(struct dsi_data *dsi, int vc,
> -					    u8 data_type, u16 len, u8 ecc)
> +					    int channel, u8 data_type, u16 len,
> +					    u8 ecc)
>  {
>  	u32 val;
>  	u8 data_id;
> @@ -2633,7 +2634,7 @@ static inline void dsi_vc_write_long_payload(struct dsi_data *dsi, int vc,
>  	dsi_write_reg(dsi, DSI_VC_LONG_PACKET_PAYLOAD(vc), val);
>  }
>  
> -static int dsi_vc_send_long(struct dsi_data *dsi,
> +static int dsi_vc_send_long(struct dsi_data *dsi, int vc,
>  			    const struct mipi_dsi_msg *msg)
>  {
>  	/*u32 val; */
> @@ -2653,7 +2654,7 @@ static int dsi_vc_send_long(struct dsi_data *dsi,
>  
>  	dsi_vc_config_source(dsi, msg->channel, DSI_VC_SOURCE_L4);
>  
> -	dsi_vc_write_long_header(dsi, msg->channel, msg->type, msg->tx_len, 0);
> +	dsi_vc_write_long_header(dsi, vc, msg->channel, msg->type, msg->tx_len, 0);
>  
>  	p = msg->tx_buf;
>  	for (i = 0; i < msg->tx_len >> 2; i++) {
> @@ -2696,7 +2697,7 @@ static int dsi_vc_send_long(struct dsi_data *dsi,
>  	return r;
>  }
>  
> -static int dsi_vc_send_short(struct dsi_data *dsi,
> +static int dsi_vc_send_short(struct dsi_data *dsi, int vc,
>  			     const struct mipi_dsi_msg *msg)
>  {
>  	struct mipi_dsi_packet pkt;
> @@ -2727,26 +2728,26 @@ static int dsi_vc_send_short(struct dsi_data *dsi,
>  	return 0;
>  }
>  
> -static int dsi_vc_send_null(struct dsi_data *dsi, int vc)
> +static int dsi_vc_send_null(struct dsi_data *dsi, int vc, int channel)
>  {
>  	const struct mipi_dsi_msg msg = {
>  		.channel = vc,
>  		.type = MIPI_DSI_NULL_PACKET,
>  	};
>  
> -	return dsi_vc_send_long(dsi, &msg);
> +	return dsi_vc_send_long(dsi, vc, &msg);
>  }
>  
> -static int dsi_vc_write_common(struct omap_dss_device *dssdev,
> +static int dsi_vc_write_common(struct omap_dss_device *dssdev, int vc,
>  			       const struct mipi_dsi_msg *msg)
>  {
>  	struct dsi_data *dsi = to_dsi_data(dssdev);
>  	int r;
>  
>  	if (mipi_dsi_packet_format_is_short(msg->type))
> -		r = dsi_vc_send_short(dsi, msg);
> +		r = dsi_vc_send_short(dsi, vc, msg);
>  	else
> -		r = dsi_vc_send_long(dsi, msg);
> +		r = dsi_vc_send_long(dsi, vc, msg);
>  
>  	if (r < 0)
>  		return r;
> @@ -2882,7 +2883,7 @@ static int dsi_vc_read_rx_fifo(struct dsi_data *dsi, int vc, u8 *buf,
>  	return r;
>  }
>  
> -static int dsi_vc_dcs_read(struct omap_dss_device *dssdev,
> +static int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int vc,
>  			   const struct mipi_dsi_msg *msg)
>  {
>  	struct dsi_data *dsi = to_dsi_data(dssdev);
> @@ -2893,7 +2894,7 @@ static int dsi_vc_dcs_read(struct omap_dss_device *dssdev,
>  	if (dsi->debug_read)
>  		DSSDBG("%s(ch %d, cmd %x)\n", __func__, channel, cmd);
>  
> -	r = dsi_vc_send_short(dsi, msg);
> +	r = dsi_vc_send_short(dsi, vc, msg);
>  	if (r)
>  		goto err;
>  
> @@ -2917,13 +2918,13 @@ static int dsi_vc_dcs_read(struct omap_dss_device *dssdev,
>  	return r;
>  }
>  
> -static int dsi_vc_generic_read(struct omap_dss_device *dssdev,
> +static int dsi_vc_generic_read(struct omap_dss_device *dssdev, int vc,
>  			       const struct mipi_dsi_msg *msg)
>  {
>  	struct dsi_data *dsi = to_dsi_data(dssdev);
>  	int r;
>  
> -	r = dsi_vc_send_short(dsi, msg);
> +	r = dsi_vc_send_short(dsi, vc, msg);
>  	if (r)
>  		goto err;
>  
> @@ -3672,7 +3673,7 @@ static void dsi_enable_video_output(struct omap_dss_device *dssdev, int vc)
>  
>  		word_count = DIV_ROUND_UP(dsi->vm.hactive * bpp, 8);
>  
> -		dsi_vc_write_long_header(dsi, vc, data_type,
> +		dsi_vc_write_long_header(dsi, vc, dsi->dsidev->channel, data_type,
>  				word_count, 0);
>  
>  		dsi_vc_enable(dsi, vc, true);
> @@ -3770,7 +3771,7 @@ static void dsi_update_screen_dispc(struct dsi_data *dsi)
>  	l = FLD_VAL(total_len, 23, 0); /* TE_SIZE */
>  	dsi_write_reg(dsi, DSI_VC_TE(vc), l);
>  
> -	dsi_vc_write_long_header(dsi, vc, MIPI_DSI_DCS_LONG_WRITE,
> +	dsi_vc_write_long_header(dsi, vc, dsi->dsidev->channel, MIPI_DSI_DCS_LONG_WRITE,
>  		packet_len, 0);
>  
>  	if (dsi->te_enabled)
> @@ -3882,7 +3883,7 @@ static int _dsi_update(struct dsi_data *dsi)
>  	return 0;
>  }
>  
> -static int _dsi_send_nop(struct dsi_data *dsi, int channel)
> +static int _dsi_send_nop(struct dsi_data *dsi, int vc, int channel)
>  {
>  	const u8 payload[] = { MIPI_DCS_NOP };
>  	const struct mipi_dsi_msg msg = {
> @@ -3894,7 +3895,7 @@ static int _dsi_send_nop(struct dsi_data *dsi, int channel)
>  
>  	WARN_ON(!dsi_bus_is_locked(dsi));
>  
> -	return _omap_dsi_host_transfer(dsi, &msg);
> +	return _omap_dsi_host_transfer(dsi, vc, &msg);
>  }
>  
>  static int dsi_update_channel(struct omap_dss_device *dssdev, int vc)
> @@ -3923,7 +3924,7 @@ static int dsi_update_channel(struct omap_dss_device *dssdev, int vc)
>  	 * updates stop working. This is probably related to DSI spec stating
>  	 * that the DSI host should transition to LP at least once per frame.
>  	 */
> -	r = _dsi_send_nop(dsi, vc);
> +	r = _dsi_send_nop(dsi, vc, dsi->dsidev->channel);
>  	if (r < 0) {
>  		DSSWARN("failed to send nop between frames: %d\n", r);
>  		goto err;
> @@ -4885,7 +4886,7 @@ static enum omap_channel dsi_get_dispc_channel(struct dsi_data *dsi)
>  	}
>  }
>  
> -static ssize_t _omap_dsi_host_transfer(struct dsi_data *dsi,
> +static ssize_t _omap_dsi_host_transfer(struct dsi_data *dsi, int vc,
>  				       const struct mipi_dsi_msg *msg)
>  {
>  	struct omap_dss_device *dssdev = &dsi->output;
> @@ -4905,15 +4906,15 @@ static ssize_t _omap_dsi_host_transfer(struct dsi_data *dsi,
>  	case MIPI_DSI_DCS_LONG_WRITE:
>  	case MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE:
>  	case MIPI_DSI_NULL_PACKET:
> -		r = dsi_vc_write_common(dssdev, msg);
> +		r = dsi_vc_write_common(dssdev, vc, msg);
>  		break;
>  	case MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM:
>  	case MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM:
>  	case MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM:
> -		r = dsi_vc_generic_read(dssdev, msg);
> +		r = dsi_vc_generic_read(dssdev, vc, msg);
>  		break;
>  	case MIPI_DSI_DCS_READ:
> -		r = dsi_vc_dcs_read(dssdev, msg);
> +		r = dsi_vc_dcs_read(dssdev, vc, msg);
>  		break;
>  	default:
>  		r = -EINVAL;
> @@ -4941,12 +4942,13 @@ static ssize_t omap_dsi_host_transfer(struct mipi_dsi_host *host,
>  {
>  	struct dsi_data *dsi = host_to_omap(host);
>  	int r;
> +	int vc = VC_DEFAULT;
>  
>  	dsi_bus_lock(dsi);
>  
>  	if (dsi->video_enabled) {
>  		dsi_set_ulps_auto(dsi, false);
> -		r = _omap_dsi_host_transfer(dsi, msg);
> +		r = _omap_dsi_host_transfer(dsi, vc, msg);
>  		dsi_set_ulps_auto(dsi, true);
>  	} else {
>  		r = -EIO;

-- 
Regards,

Laurent Pinchart

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v5 12/29] drm/omap: dsi: untangle vc & channel
  2020-12-08 12:28 ` [PATCH v5 12/29] drm/omap: dsi: untangle vc & channel Tomi Valkeinen
@ 2020-12-08 15:41   ` Laurent Pinchart
  2020-12-14 15:47     ` Sebastian Reichel
  0 siblings, 1 reply; 72+ messages in thread
From: Laurent Pinchart @ 2020-12-08 15:41 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Sebastian Reichel, Nikhil Devshatwar, dri-devel, linux-omap,
	Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg

Hi Tomi,

Thank you for the patch.

On Tue, Dec 08, 2020 at 02:28:38PM +0200, Tomi Valkeinen wrote:
> DSI virtual channel and hardware VC blocks have gotten tangled as
> described in the previous commits. This has not caused any issues, as
> the value for both is 0, so it happens to work.
> 
> To fix the issue, change the code to use the correct one of the two.
> 
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> ---
>  drivers/gpu/drm/omapdrm/dss/dsi.c | 43 +++++++++++++++----------------
>  1 file changed, 21 insertions(+), 22 deletions(-)
> 
> diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
> index 8d8412199693..a1f3623f45b1 100644
> --- a/drivers/gpu/drm/omapdrm/dss/dsi.c
> +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
> @@ -2613,7 +2613,7 @@ static inline void dsi_vc_write_long_header(struct dsi_data *dsi, int vc,
>  
>  	WARN_ON(!dsi_bus_is_locked(dsi));
>  
> -	data_id = data_type | vc << 6;
> +	data_id = data_type | channel << 6;
>  
>  	val = FLD_VAL(data_id, 7, 0) | FLD_VAL(len, 23, 8) |
>  		FLD_VAL(ecc, 31, 24);
> @@ -2647,12 +2647,12 @@ static int dsi_vc_send_long(struct dsi_data *dsi, int vc,
>  		DSSDBG("dsi_vc_send_long, %d bytes\n", msg->tx_len);
>  
>  	/* len + header */
> -	if (dsi->vc[msg->channel].tx_fifo_size * 32 * 4 < msg->tx_len + 4) {
> +	if (dsi->vc[vc].tx_fifo_size * 32 * 4 < msg->tx_len + 4) {
>  		DSSERR("unable to send long packet: packet too long.\n");
>  		return -EINVAL;
>  	}
>  
> -	dsi_vc_config_source(dsi, msg->channel, DSI_VC_SOURCE_L4);
> +	dsi_vc_config_source(dsi, vc, DSI_VC_SOURCE_L4);
>  
>  	dsi_vc_write_long_header(dsi, vc, msg->channel, msg->type, msg->tx_len, 0);
>  
> @@ -2666,7 +2666,7 @@ static int dsi_vc_send_long(struct dsi_data *dsi, int vc,
>  		b3 = *p++;
>  		b4 = *p++;
>  
> -		dsi_vc_write_long_payload(dsi, msg->channel, b1, b2, b3, b4);
> +		dsi_vc_write_long_payload(dsi, vc, b1, b2, b3, b4);
>  	}
>  
>  	i = msg->tx_len % 4;
> @@ -2691,7 +2691,7 @@ static int dsi_vc_send_long(struct dsi_data *dsi, int vc,
>  			break;
>  		}
>  
> -		dsi_vc_write_long_payload(dsi, msg->channel, b1, b2, b3, 0);
> +		dsi_vc_write_long_payload(dsi, vc, b1, b2, b3, 0);
>  	}
>  
>  	return r;
> @@ -2711,11 +2711,11 @@ static int dsi_vc_send_short(struct dsi_data *dsi, int vc,
>  
>  	if (dsi->debug_write)
>  		DSSDBG("dsi_vc_send_short(ch%d, dt %#x, b1 %#x, b2 %#x)\n",
> -		       msg->channel, msg->type, pkt.header[1], pkt.header[2]);
> +		       vc, msg->type, pkt.header[1], pkt.header[2]);
>  
> -	dsi_vc_config_source(dsi, msg->channel, DSI_VC_SOURCE_L4);
> +	dsi_vc_config_source(dsi, vc, DSI_VC_SOURCE_L4);
>  
> -	if (FLD_GET(dsi_read_reg(dsi, DSI_VC_CTRL(msg->channel)), 16, 16)) {
> +	if (FLD_GET(dsi_read_reg(dsi, DSI_VC_CTRL(vc)), 16, 16)) {
>  		DSSERR("ERROR FIFO FULL, aborting transfer\n");
>  		return -EINVAL;
>  	}
> @@ -2723,7 +2723,7 @@ static int dsi_vc_send_short(struct dsi_data *dsi, int vc,
>  	r = pkt.header[3] << 24 | pkt.header[2] << 16 | pkt.header[1] << 8 |
>  	    pkt.header[0];
>  
> -	dsi_write_reg(dsi, DSI_VC_SHORT_PACKET_HEADER(msg->channel), r);
> +	dsi_write_reg(dsi, DSI_VC_SHORT_PACKET_HEADER(vc), r);
>  
>  	return 0;
>  }
> @@ -2731,7 +2731,7 @@ static int dsi_vc_send_short(struct dsi_data *dsi, int vc,
>  static int dsi_vc_send_null(struct dsi_data *dsi, int vc, int channel)
>  {
>  	const struct mipi_dsi_msg msg = {
> -		.channel = vc,
> +		.channel = channel,
>  		.type = MIPI_DSI_NULL_PACKET,
>  	};
>  
> @@ -2759,16 +2759,16 @@ static int dsi_vc_write_common(struct omap_dss_device *dssdev, int vc,
>  	 * In that case we can return early.
>  	 */
>  
> -	r = dsi_vc_send_bta_sync(dssdev, msg->channel);
> +	r = dsi_vc_send_bta_sync(dssdev, vc);
>  	if (r) {
>  		DSSERR("bta sync failed\n");
>  		return r;
>  	}
>  
>  	/* RX_FIFO_NOT_EMPTY */
> -	if (REG_GET(dsi, DSI_VC_CTRL(msg->channel), 20, 20)) {
> +	if (REG_GET(dsi, DSI_VC_CTRL(vc), 20, 20)) {
>  		DSSERR("rx fifo not empty after write, dumping data:\n");
> -		dsi_vc_flush_receive_data(dsi, msg->channel);
> +		dsi_vc_flush_receive_data(dsi, vc);
>  		return -EIO;
>  	}
>  
> @@ -2888,21 +2888,20 @@ static int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int vc,
>  {
>  	struct dsi_data *dsi = to_dsi_data(dssdev);
>  	u8 cmd = ((u8 *)msg->tx_buf)[0];
> -	u8 channel = msg->channel;
>  	int r;
>  
>  	if (dsi->debug_read)
> -		DSSDBG("%s(ch %d, cmd %x)\n", __func__, channel, cmd);
> +		DSSDBG("%s(ch %d, cmd %x)\n", __func__, vc, cmd);

How about also renaming ch to vc in the message ?

>  
>  	r = dsi_vc_send_short(dsi, vc, msg);
>  	if (r)
>  		goto err;
>  
> -	r = dsi_vc_send_bta_sync(dssdev, channel);
> +	r = dsi_vc_send_bta_sync(dssdev, vc);
>  	if (r)
>  		goto err;
>  
> -	r = dsi_vc_read_rx_fifo(dsi, channel, msg->rx_buf, msg->rx_len,
> +	r = dsi_vc_read_rx_fifo(dsi, vc, msg->rx_buf, msg->rx_len,
>  		DSS_DSI_CONTENT_DCS);
>  	if (r < 0)
>  		goto err;
> @@ -2914,7 +2913,7 @@ static int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int vc,
>  
>  	return 0;
>  err:
> -	DSSERR("%s(ch %d, cmd 0x%02x) failed\n", __func__,  msg->channel, cmd);
> +	DSSERR("%s(ch %d, cmd 0x%02x) failed\n", __func__,  vc, cmd);

Same here.

>  	return r;
>  }
>  
> @@ -2928,11 +2927,11 @@ static int dsi_vc_generic_read(struct omap_dss_device *dssdev, int vc,
>  	if (r)
>  		goto err;
>  
> -	r = dsi_vc_send_bta_sync(dssdev, msg->channel);
> +	r = dsi_vc_send_bta_sync(dssdev, vc);
>  	if (r)
>  		goto err;
>  
> -	r = dsi_vc_read_rx_fifo(dsi, msg->channel, msg->rx_buf, msg->rx_len,
> +	r = dsi_vc_read_rx_fifo(dsi, vc, msg->rx_buf, msg->rx_len,
>  		DSS_DSI_CONTENT_GENERIC);
>  	if (r < 0)
>  		goto err;
> @@ -2944,7 +2943,7 @@ static int dsi_vc_generic_read(struct omap_dss_device *dssdev, int vc,
>  
>  	return 0;
>  err:
> -	DSSERR("%s(ch %d, reqlen %d) failed\n", __func__,  msg->channel, msg->tx_len);
> +	DSSERR("%s(ch %d, reqlen %d) failed\n", __func__,  vc, msg->tx_len);

And here.

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

>  	return r;
>  }
>  
> @@ -4893,7 +4892,7 @@ static ssize_t _omap_dsi_host_transfer(struct dsi_data *dsi, int vc,
>  	int r;
>  
>  	if (!!(msg->flags & MIPI_DSI_MSG_USE_LPM) != dsi->in_lp_mode)
> -		dsi_vc_enable_hs(dssdev, msg->channel,
> +		dsi_vc_enable_hs(dssdev, vc,
>  				 !(msg->flags & MIPI_DSI_MSG_USE_LPM));
>  
>  	switch (msg->type) {

-- 
Regards,

Laurent Pinchart

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v5 14/29] drm/omap: dsi: enable HS before sending the frame
  2020-12-08 12:28 ` [PATCH v5 14/29] drm/omap: dsi: enable HS before sending the frame Tomi Valkeinen
@ 2020-12-08 15:42   ` Laurent Pinchart
  2020-12-14 15:51   ` Sebastian Reichel
  1 sibling, 0 replies; 72+ messages in thread
From: Laurent Pinchart @ 2020-12-08 15:42 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Sebastian Reichel, Nikhil Devshatwar, dri-devel, linux-omap,
	Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg

Hi Tomi,

Thank you for the patch.

On Tue, Dec 08, 2020 at 02:28:40PM +0200, Tomi Valkeinen wrote:
> We currently use a single VC for sending commands and pixel data. The
> LP/HS mode for pixel data is correctly set to HS by accident, as we have
> set the VC to HS already earlier.
> 
> However, if we use a different VC for video data, the VC is in LP mode.
> Fix this by always enabling HS mode before starting a frame update.
> 
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

> ---
>  drivers/gpu/drm/omapdrm/dss/dsi.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
> index 544f5f1eed91..9d210a020916 100644
> --- a/drivers/gpu/drm/omapdrm/dss/dsi.c
> +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
> @@ -3918,6 +3918,8 @@ static int dsi_update_channel(struct omap_dss_device *dssdev, int vc)
>  
>  	dsi_set_ulps_auto(dsi, false);
>  
> +	dsi_vc_enable_hs(dssdev, vc, true);
> +
>  	/*
>  	 * Send NOP between the frames. If we don't send something here, the
>  	 * updates stop working. This is probably related to DSI spec stating

-- 
Regards,

Laurent Pinchart

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v5 16/29] drm/panel: panel-dsi-cm: remove extra 'if'
  2020-12-08 12:28 ` [PATCH v5 16/29] drm/panel: panel-dsi-cm: remove extra 'if' Tomi Valkeinen
@ 2020-12-08 15:42   ` Laurent Pinchart
  2020-12-14 15:55   ` Sebastian Reichel
  1 sibling, 0 replies; 72+ messages in thread
From: Laurent Pinchart @ 2020-12-08 15:42 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Sebastian Reichel, Nikhil Devshatwar, dri-devel, linux-omap,
	Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg

Hi Tomi,

Thank you for the patch.

On Tue, Dec 08, 2020 at 02:28:42PM +0200, Tomi Valkeinen wrote:
> We have a useless 'if' in the dsicm_bl_update_status(), a left over from
> the conversion to DRM model. Drop the if.
> 
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> Reviewed-by: Sam Ravnborg <sam@ravnborg.org>

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

> ---
>  drivers/gpu/drm/panel/panel-dsi-cm.c | 8 +++-----
>  1 file changed, 3 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/panel/panel-dsi-cm.c b/drivers/gpu/drm/panel/panel-dsi-cm.c
> index 556f9a2c5c0c..fa564aad7f25 100644
> --- a/drivers/gpu/drm/panel/panel-dsi-cm.c
> +++ b/drivers/gpu/drm/panel/panel-dsi-cm.c
> @@ -202,11 +202,9 @@ static int dsicm_bl_update_status(struct backlight_device *dev)
>  
>  	mutex_lock(&ddata->lock);
>  
> -	if (ddata->enabled) {
> -		if (!r)
> -			r = dsicm_dcs_write_1(
> -				ddata, MIPI_DCS_SET_DISPLAY_BRIGHTNESS, level);
> -	}
> +	if (ddata->enabled)
> +		r = dsicm_dcs_write_1(ddata, MIPI_DCS_SET_DISPLAY_BRIGHTNESS,
> +				      level);
>  
>  	mutex_unlock(&ddata->lock);
>  

-- 
Regards,

Laurent Pinchart

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v5 11/29] drm/omap: dsi: pass vc to various functions
  2020-12-08 15:38   ` Laurent Pinchart
@ 2020-12-08 15:45     ` Tomi Valkeinen
  0 siblings, 0 replies; 72+ messages in thread
From: Tomi Valkeinen @ 2020-12-08 15:45 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Sebastian Reichel, Nikhil Devshatwar, dri-devel, linux-omap,
	Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg

On 08/12/2020 17:38, Laurent Pinchart wrote:
> Hi Tomi,
> 
> Thank you for the patch.
> 
> On Tue, Dec 08, 2020 at 02:28:37PM +0200, Tomi Valkeinen wrote:
>> To start fixing the issues related to channels and vcs described in the
>> previous commit, pass vc to various functions which will need it do
>> properly handle different DSI channels and VCs.
> 
> This is a bit hard to review as you add the OMAP DSI VC as a parameter
> (named vc) to some functions , and the MIPI DSI virtual channel as a
> parameter (named channel) to other functions. Only the former matches
> the commit message. Splitting this in two would make the changes

Ah, that's true. I'll update the title and desc to mention channel too.

 Tomi

-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v5 29/29] drm/omap: dsi: allow DSI commands to be sent early
  2020-12-08 12:28 ` [PATCH v5 29/29] drm/omap: dsi: allow DSI commands to be sent early Tomi Valkeinen
@ 2020-12-08 15:48   ` Laurent Pinchart
  2020-12-10  7:34     ` Tomi Valkeinen
  2020-12-14 17:17   ` Sebastian Reichel
  1 sibling, 1 reply; 72+ messages in thread
From: Laurent Pinchart @ 2020-12-08 15:48 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Sebastian Reichel, Nikhil Devshatwar, dri-devel, linux-omap,
	Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg

Hi Tomi,

Thank you for the patch.

On Tue, Dec 08, 2020 at 02:28:55PM +0200, Tomi Valkeinen wrote:
> Panel drivers can send DSI commands in panel's prepare(), which happens
> before the bridge's enable() is called. The OMAP DSI driver currently
> only sets up the DSI interface at bridge's enable(), so prepare() cannot
> be used to send DSI commands.
> 
> This patch fixes the issue by making it possible to enable the DSI
> interface any time a command is about to be sent. Disabling the
> interface is be done via delayed work.
> 
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> ---
>  drivers/gpu/drm/omapdrm/dss/dsi.c | 49 +++++++++++++++++++++++++++----
>  drivers/gpu/drm/omapdrm/dss/dsi.h |  3 ++
>  2 files changed, 47 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
> index 53a64bc91867..34f665aa9a59 100644
> --- a/drivers/gpu/drm/omapdrm/dss/dsi.c
> +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
> @@ -3503,6 +3503,9 @@ static void dsi_enable(struct dsi_data *dsi)
>  
>  	WARN_ON(!dsi_bus_is_locked(dsi));
>  
> +	if (WARN_ON(dsi->iface_enabled))
> +		return;
> +
>  	mutex_lock(&dsi->lock);
>  
>  	r = dsi_runtime_get(dsi);
> @@ -3515,6 +3518,8 @@ static void dsi_enable(struct dsi_data *dsi)
>  	if (r)
>  		goto err_init_dsi;
>  
> +	dsi->iface_enabled = true;
> +
>  	mutex_unlock(&dsi->lock);
>  
>  	return;
> @@ -3530,6 +3535,9 @@ static void dsi_disable(struct dsi_data *dsi)
>  {
>  	WARN_ON(!dsi_bus_is_locked(dsi));
>  
> +	if (WARN_ON(!dsi->iface_enabled))
> +		return;
> +
>  	mutex_lock(&dsi->lock);
>  
>  	dsi_sync_vc(dsi, 0);
> @@ -3541,6 +3549,8 @@ static void dsi_disable(struct dsi_data *dsi)
>  
>  	dsi_runtime_put(dsi);
>  
> +	dsi->iface_enabled = false;
> +
>  	mutex_unlock(&dsi->lock);
>  }
>  
> @@ -4229,10 +4239,12 @@ static ssize_t omap_dsi_host_transfer(struct mipi_dsi_host *host,
>  
>  	dsi_bus_lock(dsi);
>  
> -	if (dsi->video_enabled)
> -		r = _omap_dsi_host_transfer(dsi, vc, msg);
> -	else
> -		r = -EIO;
> +	if (!dsi->iface_enabled) {
> +		dsi_enable(dsi);
> +		schedule_delayed_work(&dsi->dsi_disable_work, msecs_to_jiffies(2000));
> +	}
> +
> +	r = _omap_dsi_host_transfer(dsi, vc, msg);
>  
>  	dsi_bus_unlock(dsi);
>  
> @@ -4397,6 +4409,14 @@ static int omap_dsi_host_detach(struct mipi_dsi_host *host,
>  	if (WARN_ON(dsi->dsidev != client))
>  		return -EINVAL;
>  
> +	cancel_delayed_work_sync(&dsi->dsi_disable_work);
> +
> +	if (dsi->iface_enabled) {
> +		dsi_bus_lock(dsi);
> +		dsi_disable(dsi);
> +		dsi_bus_unlock(dsi);
> +	}
> +
>  	omap_dsi_unregister_te_irq(dsi);
>  	dsi->dsidev = NULL;
>  	return 0;
> @@ -4632,9 +4652,12 @@ static void dsi_bridge_enable(struct drm_bridge *bridge)
>  	struct dsi_data *dsi = drm_bridge_to_dsi(bridge);
>  	struct omap_dss_device *dssdev = &dsi->output;
>  
> +	cancel_delayed_work_sync(&dsi->dsi_disable_work);
> +

Is there a risk of a race condition if omap_dsi_host_transfer() is
called right here, before locking the bus ? Or is there a guarantee that
the two functions can't be executed concurrently ? Same for
dsi_bridge_disable() below.

>  	dsi_bus_lock(dsi);
>  
> -	dsi_enable(dsi);
> +	if (!dsi->iface_enabled)
> +		dsi_enable(dsi);
>  
>  	dsi_enable_video_output(dssdev, VC_VIDEO);
>  
> @@ -4648,6 +4671,8 @@ static void dsi_bridge_disable(struct drm_bridge *bridge)
>  	struct dsi_data *dsi = drm_bridge_to_dsi(bridge);
>  	struct omap_dss_device *dssdev = &dsi->output;
>  
> +	cancel_delayed_work_sync(&dsi->dsi_disable_work);
> +
>  	dsi_bus_lock(dsi);
>  
>  	dsi->video_enabled = false;
> @@ -4840,6 +4865,18 @@ static const struct soc_device_attribute dsi_soc_devices[] = {
>  	{ /* sentinel */ }
>  };
>  
> +static void omap_dsi_disable_work_callback(struct work_struct *work)
> +{
> +	struct dsi_data *dsi = container_of(work, struct dsi_data, dsi_disable_work.work);
> +
> +	dsi_bus_lock(dsi);
> +
> +	if (dsi->iface_enabled && !dsi->video_enabled)
> +		dsi_disable(dsi);
> +
> +	dsi_bus_unlock(dsi);
> +}
> +
>  static int dsi_probe(struct platform_device *pdev)
>  {
>  	const struct soc_device_attribute *soc;
> @@ -4873,6 +4910,8 @@ static int dsi_probe(struct platform_device *pdev)
>  	INIT_DEFERRABLE_WORK(&dsi->framedone_timeout_work,
>  			     dsi_framedone_timeout_work_callback);
>  
> +	INIT_DEFERRABLE_WORK(&dsi->dsi_disable_work, omap_dsi_disable_work_callback);
> +
>  #ifdef DSI_CATCH_MISSING_TE
>  	timer_setup(&dsi->te_timer, dsi_te_timeout, 0);
>  #endif
> diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.h b/drivers/gpu/drm/omapdrm/dss/dsi.h
> index de9411067ba2..601707c0ecc4 100644
> --- a/drivers/gpu/drm/omapdrm/dss/dsi.h
> +++ b/drivers/gpu/drm/omapdrm/dss/dsi.h
> @@ -394,6 +394,7 @@ struct dsi_data {
>  	atomic_t do_ext_te_update;
>  
>  	bool te_enabled;
> +	bool iface_enabled;
>  	bool video_enabled;
>  
>  	struct delayed_work framedone_timeout_work;
> @@ -443,6 +444,8 @@ struct dsi_data {
>  
>  	struct omap_dss_device output;
>  	struct drm_bridge bridge;
> +
> +	struct delayed_work dsi_disable_work;
>  };
>  
>  struct dsi_packet_sent_handler_data {

-- 
Regards,

Laurent Pinchart

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v5 29/29] drm/omap: dsi: allow DSI commands to be sent early
  2020-12-08 15:48   ` Laurent Pinchart
@ 2020-12-10  7:34     ` Tomi Valkeinen
  2020-12-10  8:17       ` Tomi Valkeinen
  0 siblings, 1 reply; 72+ messages in thread
From: Tomi Valkeinen @ 2020-12-10  7:34 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Sebastian Reichel, Nikhil Devshatwar, dri-devel, linux-omap,
	Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg

On 08/12/2020 17:48, Laurent Pinchart wrote:
> Hi Tomi,
> 
> Thank you for the patch.
> 
> On Tue, Dec 08, 2020 at 02:28:55PM +0200, Tomi Valkeinen wrote:
>> Panel drivers can send DSI commands in panel's prepare(), which happens
>> before the bridge's enable() is called. The OMAP DSI driver currently
>> only sets up the DSI interface at bridge's enable(), so prepare() cannot
>> be used to send DSI commands.
>>
>> This patch fixes the issue by making it possible to enable the DSI
>> interface any time a command is about to be sent. Disabling the
>> interface is be done via delayed work.
>>
>> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
>> ---
>>  drivers/gpu/drm/omapdrm/dss/dsi.c | 49 +++++++++++++++++++++++++++----
>>  drivers/gpu/drm/omapdrm/dss/dsi.h |  3 ++
>>  2 files changed, 47 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
>> index 53a64bc91867..34f665aa9a59 100644
>> --- a/drivers/gpu/drm/omapdrm/dss/dsi.c
>> +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
>> @@ -3503,6 +3503,9 @@ static void dsi_enable(struct dsi_data *dsi)
>>  
>>  	WARN_ON(!dsi_bus_is_locked(dsi));
>>  
>> +	if (WARN_ON(dsi->iface_enabled))
>> +		return;
>> +
>>  	mutex_lock(&dsi->lock);
>>  
>>  	r = dsi_runtime_get(dsi);
>> @@ -3515,6 +3518,8 @@ static void dsi_enable(struct dsi_data *dsi)
>>  	if (r)
>>  		goto err_init_dsi;
>>  
>> +	dsi->iface_enabled = true;
>> +
>>  	mutex_unlock(&dsi->lock);
>>  
>>  	return;
>> @@ -3530,6 +3535,9 @@ static void dsi_disable(struct dsi_data *dsi)
>>  {
>>  	WARN_ON(!dsi_bus_is_locked(dsi));
>>  
>> +	if (WARN_ON(!dsi->iface_enabled))
>> +		return;
>> +
>>  	mutex_lock(&dsi->lock);
>>  
>>  	dsi_sync_vc(dsi, 0);
>> @@ -3541,6 +3549,8 @@ static void dsi_disable(struct dsi_data *dsi)
>>  
>>  	dsi_runtime_put(dsi);
>>  
>> +	dsi->iface_enabled = false;
>> +
>>  	mutex_unlock(&dsi->lock);
>>  }
>>  
>> @@ -4229,10 +4239,12 @@ static ssize_t omap_dsi_host_transfer(struct mipi_dsi_host *host,
>>  
>>  	dsi_bus_lock(dsi);
>>  
>> -	if (dsi->video_enabled)
>> -		r = _omap_dsi_host_transfer(dsi, vc, msg);
>> -	else
>> -		r = -EIO;
>> +	if (!dsi->iface_enabled) {
>> +		dsi_enable(dsi);
>> +		schedule_delayed_work(&dsi->dsi_disable_work, msecs_to_jiffies(2000));
>> +	}
>> +
>> +	r = _omap_dsi_host_transfer(dsi, vc, msg);
>>  
>>  	dsi_bus_unlock(dsi);
>>  
>> @@ -4397,6 +4409,14 @@ static int omap_dsi_host_detach(struct mipi_dsi_host *host,
>>  	if (WARN_ON(dsi->dsidev != client))
>>  		return -EINVAL;
>>  
>> +	cancel_delayed_work_sync(&dsi->dsi_disable_work);
>> +
>> +	if (dsi->iface_enabled) {
>> +		dsi_bus_lock(dsi);
>> +		dsi_disable(dsi);
>> +		dsi_bus_unlock(dsi);
>> +	}
>> +
>>  	omap_dsi_unregister_te_irq(dsi);
>>  	dsi->dsidev = NULL;
>>  	return 0;
>> @@ -4632,9 +4652,12 @@ static void dsi_bridge_enable(struct drm_bridge *bridge)
>>  	struct dsi_data *dsi = drm_bridge_to_dsi(bridge);
>>  	struct omap_dss_device *dssdev = &dsi->output;
>>  
>> +	cancel_delayed_work_sync(&dsi->dsi_disable_work);
>> +
> 
> Is there a risk of a race condition if omap_dsi_host_transfer() is
> called right here, before locking the bus ? Or is there a guarantee that
> the two functions can't be executed concurrently ? Same for
> dsi_bridge_disable() below.

Yes, there's a possibility for a race, if the panel driver does dsi command transactions via, say, a
timer, and doesn't take DRM locks that are shared with bridge-enable/disable/detach.

For bridge-enable, it shouldn't matter: If the disable callback is called just before bridge_enable
takes the dsi_bus_lock, no problem, bridge_enable just enables the interface again. If the callback
is ran just after bridge_enable's dsi_bus_unlock, no problem, dsi->video_enabled == true so the
callback does nothing.

Similarly for bridge-disable, the callback won't do anything if video_enabled == true, and after
bridge-disable has turned the video and the interface off, there's nothing to do for the callback.

The detach is a bit more unclear. Is the panel driver allowed to do "stuff" with bridges while
bridge detach is going on? If yes, it's probably broken. We should move the bus_locks to cover the
whole if() so that dsi->iface_enabled is inside the locks. With that change the delayed disable
itself should work fine.

But we don't have anything stopping omap_dsi_host_transfer being called after the whole bridge has
been detached (or called before attach). So, if we have a guarantee that the panels won't be doing
dsi transfers before/during bridge attach or after/during bridge detach, we have no issue. If we
don't have such a guarantee, it's broken.

I'll try to figure out if there's such a guarantee, but maybe it's safer to add a flag to indicate
if the bridge is available, and check that during omap_dsi_host_transfer.

 Tomi

-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v5 29/29] drm/omap: dsi: allow DSI commands to be sent early
  2020-12-10  7:34     ` Tomi Valkeinen
@ 2020-12-10  8:17       ` Tomi Valkeinen
  0 siblings, 0 replies; 72+ messages in thread
From: Tomi Valkeinen @ 2020-12-10  8:17 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Sebastian Reichel, Nikhil Devshatwar, dri-devel, linux-omap,
	Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg

On 10/12/2020 09:34, Tomi Valkeinen wrote:

> But we don't have anything stopping omap_dsi_host_transfer being called after the whole bridge has
> been detached (or called before attach). So, if we have a guarantee that the panels won't be doing
> dsi transfers before/during bridge attach or after/during bridge detach, we have no issue. If we
> don't have such a guarantee, it's broken.
> 
> I'll try to figure out if there's such a guarantee, but maybe it's safer to add a flag to indicate
> if the bridge is available, and check that during omap_dsi_host_transfer.

I don't think this can happen. I mixed up the bridge attach/detach and the dsi host attach/detach.
The cancel_delayed_work_sync happens in omap_dsi_host_detach, and I think it's a sensible
expectation that the panel won't first do mipi_dsi_detach(), and then try to do DSI transfers.

 Tomi

-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v5 01/29] drm/panel: panel-dsi-cm: cleanup tear enable
  2020-12-08 12:28 ` [PATCH v5 01/29] drm/panel: panel-dsi-cm: cleanup tear enable Tomi Valkeinen
@ 2020-12-14 13:09   ` Sebastian Reichel
  0 siblings, 0 replies; 72+ messages in thread
From: Sebastian Reichel @ 2020-12-14 13:09 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Laurent Pinchart, Nikhil Devshatwar, dri-devel, linux-omap,
	Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg

[-- Attachment #1: Type: text/plain, Size: 2261 bytes --]

Hi,

On Tue, Dec 08, 2020 at 02:28:27PM +0200, Tomi Valkeinen wrote:
> Simplify the code by moving code from _dsicm_enable_te() into
> dsicm_power_on().
> 
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> Reviewed-by: Sam Ravnborg <sam@ravnborg.org>
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---

Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>

-- Sebastian

>  drivers/gpu/drm/panel/panel-dsi-cm.c | 23 ++++-------------------
>  1 file changed, 4 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/gpu/drm/panel/panel-dsi-cm.c b/drivers/gpu/drm/panel/panel-dsi-cm.c
> index 729b42b4dabd..38f79dca1fd0 100644
> --- a/drivers/gpu/drm/panel/panel-dsi-cm.c
> +++ b/drivers/gpu/drm/panel/panel-dsi-cm.c
> @@ -68,8 +68,6 @@ static inline struct panel_drv_data *panel_to_ddata(struct drm_panel *panel)
>  	return container_of(panel, struct panel_drv_data, panel);
>  }
>  
> -static int _dsicm_enable_te(struct panel_drv_data *ddata, bool enable);
> -
>  static void dsicm_bl_power(struct panel_drv_data *ddata, bool enable)
>  {
>  	struct backlight_device *backlight;
> @@ -313,10 +311,13 @@ static int dsicm_power_on(struct panel_drv_data *ddata)
>  	if (r)
>  		goto err;
>  
> -	r = _dsicm_enable_te(ddata, true);
> +	r = mipi_dsi_dcs_set_tear_on(ddata->dsi, MIPI_DSI_DCS_TEAR_MODE_VBLANK);
>  	if (r)
>  		goto err;
>  
> +	/* possible panel bug */
> +	msleep(100);
> +
>  	ddata->enabled = true;
>  
>  	if (!ddata->intro_printed) {
> @@ -417,22 +418,6 @@ static int dsicm_disable(struct drm_panel *panel)
>  	return r;
>  }
>  
> -static int _dsicm_enable_te(struct panel_drv_data *ddata, bool enable)
> -{
> -	struct mipi_dsi_device *dsi = ddata->dsi;
> -	int r;
> -
> -	if (enable)
> -		r = mipi_dsi_dcs_set_tear_on(dsi, MIPI_DSI_DCS_TEAR_MODE_VBLANK);
> -	else
> -		r = mipi_dsi_dcs_set_tear_off(dsi);
> -
> -	/* possible panel bug */
> -	msleep(100);
> -
> -	return r;
> -}
> -
>  static int dsicm_get_modes(struct drm_panel *panel,
>  			   struct drm_connector *connector)
>  {
> -- 
> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
> Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v5 02/29] ARM: dts: omap5: add address-cells & size-cells to dsi
  2020-12-08 12:28 ` [PATCH v5 02/29] ARM: dts: omap5: add address-cells & size-cells to dsi Tomi Valkeinen
@ 2020-12-14 13:09   ` Sebastian Reichel
  0 siblings, 0 replies; 72+ messages in thread
From: Sebastian Reichel @ 2020-12-14 13:09 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Laurent Pinchart, Nikhil Devshatwar, dri-devel, linux-omap,
	Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg

[-- Attachment #1: Type: text/plain, Size: 1415 bytes --]

Hi,

On Tue, Dec 08, 2020 at 02:28:28PM +0200, Tomi Valkeinen wrote:
> Add address-cells & size-cells to DSI nodes so that board files do not
> need to define them.
> 
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> Cc: Tony Lindgren <tony@atomide.com>
> Acked-by: Tony Lindgren <tony@atomide.com>
> ---

Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>

-- Sebastian

>  arch/arm/boot/dts/omap5.dtsi | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/omap5.dtsi b/arch/arm/boot/dts/omap5.dtsi
> index 2bf2e5839a7f..e6f6947965ef 100644
> --- a/arch/arm/boot/dts/omap5.dtsi
> +++ b/arch/arm/boot/dts/omap5.dtsi
> @@ -517,6 +517,9 @@ dsi1: encoder@0 {
>  						clocks = <&dss_clkctrl OMAP5_DSS_CORE_CLKCTRL 8>,
>  							 <&dss_clkctrl OMAP5_DSS_CORE_CLKCTRL 10>;
>  						clock-names = "fck", "sys_clk";
> +
> +						#address-cells = <1>;
> +						#size-cells = <0>;
>  					};
>  				};
>  
> @@ -549,6 +552,9 @@ dsi2: encoder@0 {
>  						clocks = <&dss_clkctrl OMAP5_DSS_CORE_CLKCTRL 8>,
>  							 <&dss_clkctrl OMAP5_DSS_CORE_CLKCTRL 10>;
>  						clock-names = "fck", "sys_clk";
> +
> +						#address-cells = <1>;
> +						#size-cells = <0>;
>  					};
>  				};
>  
> -- 
> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
> Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v5 03/29] drm/omap: pll: fix iteration loop check
  2020-12-08 12:28 ` [PATCH v5 03/29] drm/omap: pll: fix iteration loop check Tomi Valkeinen
@ 2020-12-14 13:10   ` Sebastian Reichel
  0 siblings, 0 replies; 72+ messages in thread
From: Sebastian Reichel @ 2020-12-14 13:10 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Laurent Pinchart, Nikhil Devshatwar, dri-devel, linux-omap,
	Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg

[-- Attachment #1: Type: text/plain, Size: 1534 bytes --]

Hi,

On Tue, Dec 08, 2020 at 02:28:29PM +0200, Tomi Valkeinen wrote:
> If the PLL calc function is given bad parameters, n_start/m_start may be
> higher than n_stop/m_stop, which leads to the loops iterating through
> the whole u32 number space.
> 
> Fix this by failing early on such cases.
> 
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---

Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>

-- Sebastian

>  drivers/gpu/drm/omapdrm/dss/pll.c | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/drivers/gpu/drm/omapdrm/dss/pll.c b/drivers/gpu/drm/omapdrm/dss/pll.c
> index 1212f3cc52d1..12926218c436 100644
> --- a/drivers/gpu/drm/omapdrm/dss/pll.c
> +++ b/drivers/gpu/drm/omapdrm/dss/pll.c
> @@ -222,6 +222,9 @@ bool dss_pll_calc_a(const struct dss_pll *pll, unsigned long clkin,
>  	n_stop = min((unsigned)(clkin / fint_hw_min), hw->n_max);
>  	n_inc = 1;
>  
> +	if (n_start > n_stop)
> +		return false;
> +
>  	if (hw->errata_i886) {
>  		swap(n_start, n_stop);
>  		n_inc = -1;
> @@ -239,6 +242,9 @@ bool dss_pll_calc_a(const struct dss_pll *pll, unsigned long clkin,
>  				hw->m_max);
>  		m_inc = 1;
>  
> +		if (m_start > m_stop)
> +			continue;
> +
>  		if (hw->errata_i886) {
>  			swap(m_start, m_stop);
>  			m_inc = -1;
> -- 
> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
> Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v5 04/29] drm/omap: dsi: set trans_mode according to client mode_flags
  2020-12-08 12:28 ` [PATCH v5 04/29] drm/omap: dsi: set trans_mode according to client mode_flags Tomi Valkeinen
@ 2020-12-14 13:10   ` Sebastian Reichel
  0 siblings, 0 replies; 72+ messages in thread
From: Sebastian Reichel @ 2020-12-14 13:10 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Laurent Pinchart, Nikhil Devshatwar, dri-devel, linux-omap,
	Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg

[-- Attachment #1: Type: text/plain, Size: 1464 bytes --]

Hi,

On Tue, Dec 08, 2020 at 02:28:30PM +0200, Tomi Valkeinen wrote:
> The DSI host driver currently ignores the video mode flags in
> client->mode_flags. Add the code to take the transfer mode from client's
> mode_flags.
> 
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---

Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>

-- Sebastian

>  drivers/gpu/drm/omapdrm/dss/dsi.c | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
> index c3592c6db977..7fee9cf8782d 100644
> --- a/drivers/gpu/drm/omapdrm/dss/dsi.c
> +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
> @@ -5140,6 +5140,13 @@ static int omap_dsi_host_attach(struct mipi_dsi_host *host,
>  	dsi->config.lp_clk_min = 7000000; // TODO: get from client?
>  	dsi->config.lp_clk_max = client->lp_rate;
>  
> +	if (client->mode_flags & MIPI_DSI_MODE_VIDEO_BURST)
> +		dsi->config.trans_mode = OMAP_DSS_DSI_BURST_MODE;
> +	else if (client->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)
> +		dsi->config.trans_mode = OMAP_DSS_DSI_PULSE_MODE;
> +	else
> +		dsi->config.trans_mode = OMAP_DSS_DSI_EVENT_MODE;
> +
>  	dsi->ulps_auto_idle = false;
>  
>  	return 0;
> -- 
> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
> Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v5 05/29] drm/panel: panel-dsi-cm: set column & page at setup
  2020-12-08 12:28 ` [PATCH v5 05/29] drm/panel: panel-dsi-cm: set column & page at setup Tomi Valkeinen
@ 2020-12-14 13:10   ` Sebastian Reichel
  0 siblings, 0 replies; 72+ messages in thread
From: Sebastian Reichel @ 2020-12-14 13:10 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Laurent Pinchart, Nikhil Devshatwar, dri-devel, linux-omap,
	Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg

[-- Attachment #1: Type: text/plain, Size: 1853 bytes --]

Hi,

On Tue, Dec 08, 2020 at 02:28:31PM +0200, Tomi Valkeinen wrote:
> Set the column & page address once during setup, instead of relying the
> DSI host driver to set those.
> 
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> Reviewed-by: Sam Ravnborg <sam@ravnborg.org>
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---

Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>

-- Sebastian

>  drivers/gpu/drm/panel/panel-dsi-cm.c | 20 ++++++++++++++++++++
>  1 file changed, 20 insertions(+)
> 
> diff --git a/drivers/gpu/drm/panel/panel-dsi-cm.c b/drivers/gpu/drm/panel/panel-dsi-cm.c
> index 38f79dca1fd0..556f9a2c5c0c 100644
> --- a/drivers/gpu/drm/panel/panel-dsi-cm.c
> +++ b/drivers/gpu/drm/panel/panel-dsi-cm.c
> @@ -170,6 +170,22 @@ static int dsicm_get_id(struct panel_drv_data *ddata, u8 *id1, u8 *id2, u8 *id3)
>  	return 0;
>  }
>  
> +static int dsicm_set_update_window(struct panel_drv_data *ddata)
> +{
> +	struct mipi_dsi_device *dsi = ddata->dsi;
> +	int r;
> +
> +	r = mipi_dsi_dcs_set_column_address(dsi, 0, ddata->mode.hdisplay - 1);
> +	if (r < 0)
> +		return r;
> +
> +	r = mipi_dsi_dcs_set_page_address(dsi, 0, ddata->mode.vdisplay - 1);
> +	if (r < 0)
> +		return r;
> +
> +	return 0;
> +}
> +
>  static int dsicm_bl_update_status(struct backlight_device *dev)
>  {
>  	struct panel_drv_data *ddata = dev_get_drvdata(&dev->dev);
> @@ -307,6 +323,10 @@ static int dsicm_power_on(struct panel_drv_data *ddata)
>  	if (r)
>  		goto err;
>  
> +	r = dsicm_set_update_window(ddata);
> +	if (r)
> +		goto err;
> +
>  	r = mipi_dsi_dcs_set_display_on(ddata->dsi);
>  	if (r)
>  		goto err;
> -- 
> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
> Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v5 06/29] drm/omap: dsi: send nop instead of page & column
  2020-12-08 12:28 ` [PATCH v5 06/29] drm/omap: dsi: send nop instead of page & column Tomi Valkeinen
@ 2020-12-14 14:22   ` Sebastian Reichel
  0 siblings, 0 replies; 72+ messages in thread
From: Sebastian Reichel @ 2020-12-14 14:22 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Laurent Pinchart, Nikhil Devshatwar, dri-devel, linux-omap,
	Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg

[-- Attachment #1: Type: text/plain, Size: 3901 bytes --]

Hi,

On Tue, Dec 08, 2020 at 02:28:32PM +0200, Tomi Valkeinen wrote:
> The OMAP DSI command mode panel driver used to send page & column
> address before each frame update, and this code was moved into the DSI
> host driver when converting it to the DRM bridge model.
> 
> However, it's not really required to send the page & column address
> before each frame. It's also something that doesn't really belong to the
> DSI host driver, so we should drop the code.
> 
> That said, frame updates break if we don't send _something_ between the
> frames. A NOP command does the trick.
> 
> It is not clear if this behavior is as expected from a DSI command mode
> frame transfer, or is it a feature/issue with OMAP DSI driver, or a
> feature/issue in the command mode panel used.
> 
> Most likely this is related to the following from the DSI spec:
> 
> "To enable PHY synchronization the host processor should periodically
> end HS transmission and drive the Data Lanes to the LP state. This
> transition should take place at least once per frame."
> 
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---

Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>

-- Sebastian

>  drivers/gpu/drm/omapdrm/dss/dsi.c | 46 ++++++++++++-------------------
>  1 file changed, 17 insertions(+), 29 deletions(-)
> 
> diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
> index 7fee9cf8782d..c6e044f8bece 100644
> --- a/drivers/gpu/drm/omapdrm/dss/dsi.c
> +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
> @@ -3884,35 +3884,19 @@ static int _dsi_update(struct dsi_data *dsi)
>  	return 0;
>  }
>  
> -static int _dsi_update_window(struct dsi_data *dsi, int channel,
> -			      int x, int y, int w, int h)
> -{
> -	int x1 = x, x2 = (x + w - 1);
> -	int y1 = y, y2 = (y + h - 1);
> -	u8 payloadX[5] = { MIPI_DCS_SET_COLUMN_ADDRESS,
> -			   x1 >> 8, x1 & 0xff, x2 >> 8, x2 & 0xff };
> -	u8 payloadY[5] = { MIPI_DCS_SET_PAGE_ADDRESS,
> -			   y1 >> 8, y1 & 0xff, y2 >> 8, y2 & 0xff };
> -	struct mipi_dsi_msg msgX = { 0 }, msgY = { 0 };
> -	int ret;
> +static int _dsi_send_nop(struct dsi_data *dsi, int channel)
> +{
> +	const u8 payload[] = { MIPI_DCS_NOP };
> +	const struct mipi_dsi_msg msg = {
> +		.channel = channel,
> +		.type = MIPI_DSI_DCS_SHORT_WRITE,
> +		.tx_len = 1,
> +		.tx_buf = payload,
> +	};
>  
>  	WARN_ON(!dsi_bus_is_locked(dsi));
>  
> -	msgX.type = MIPI_DSI_DCS_LONG_WRITE;
> -	msgX.channel = channel;
> -	msgX.tx_buf = payloadX;
> -	msgX.tx_len = sizeof(payloadX);
> -
> -	msgY.type = MIPI_DSI_DCS_LONG_WRITE;
> -	msgY.channel = channel;
> -	msgY.tx_buf = payloadY;
> -	msgY.tx_len = sizeof(payloadY);
> -
> -	ret = _omap_dsi_host_transfer(dsi, &msgX);
> -	if (ret != 0)
> -		return ret;
> -
> -	return _omap_dsi_host_transfer(dsi, &msgY);
> +	return _omap_dsi_host_transfer(dsi, &msg);
>  }
>  
>  static int dsi_update_channel(struct omap_dss_device *dssdev, int channel)
> @@ -3944,10 +3928,14 @@ static int dsi_update_channel(struct omap_dss_device *dssdev, int channel)
>  
>  	dsi_set_ulps_auto(dsi, false);
>  
> -	r = _dsi_update_window(dsi, channel, 0, 0, dsi->vm.hactive,
> -			       dsi->vm.vactive);
> +	/*
> +	 * Send NOP between the frames. If we don't send something here, the
> +	 * updates stop working. This is probably related to DSI spec stating
> +	 * that the DSI host should transition to LP at least once per frame.
> +	 */
> +	r = _dsi_send_nop(dsi, channel);
>  	if (r < 0) {
> -		DSSWARN("window update error: %d\n", r);
> +		DSSWARN("failed to send nop between frames: %d\n", r);
>  		goto err;
>  	}
>  
> -- 
> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
> Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v5 07/29] drm/omap: dsi: simplify VC handling
  2020-12-08 12:28 ` [PATCH v5 07/29] drm/omap: dsi: simplify VC handling Tomi Valkeinen
@ 2020-12-14 14:31   ` Sebastian Reichel
  0 siblings, 0 replies; 72+ messages in thread
From: Sebastian Reichel @ 2020-12-14 14:31 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Laurent Pinchart, Nikhil Devshatwar, dri-devel, linux-omap,
	Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg

[-- Attachment #1: Type: text/plain, Size: 4941 bytes --]

Hi,

On Tue, Dec 08, 2020 at 02:28:33PM +0200, Tomi Valkeinen wrote:
> The VC handling has gotten quite tangled up. As the first step to clean
> it up, lets define that we only support a single DSI peripheral (which
> was really already the case), and we always use VC0 (define VC_DEFAULT
> 0) register block to send data to the peripheral.
> 
> We can thus have a single mipi_dsi_device pointer and remove the
> for-loops which made passes over all the four VCs (just the first one
> was ever used).
> 
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---

Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>

-- Sebastian

>  drivers/gpu/drm/omapdrm/dss/dsi.c | 49 ++++++++-----------------------
>  1 file changed, 13 insertions(+), 36 deletions(-)
> 
> diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
> index c6e044f8bece..5e13478010db 100644
> --- a/drivers/gpu/drm/omapdrm/dss/dsi.c
> +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
> @@ -360,9 +360,10 @@ struct dsi_data {
>  	bool vdds_dsi_enabled;
>  	struct regulator *vdds_dsi_reg;
>  
> +	struct mipi_dsi_device *dsidev;
> +
>  	struct {
>  		enum dsi_vc_source source;
> -		struct mipi_dsi_device *dest;
>  		enum fifo_size tx_fifo_size;
>  		enum fifo_size rx_fifo_size;
>  	} vc[4];
> @@ -452,6 +453,8 @@ static bool dsi_perf;
>  module_param(dsi_perf, bool, 0644);
>  #endif
>  
> +#define VC_DEFAULT 0
> +
>  #define drm_bridge_to_dsi(bridge) \
>  	container_of(bridge, struct dsi_data, bridge)
>  
> @@ -3716,16 +3719,11 @@ static void dsi_disable_video_output(struct omap_dss_device *dssdev, int channel
>  static void dsi_disable_video_outputs(struct omap_dss_device *dssdev)
>  {
>  	struct dsi_data *dsi = to_dsi_data(dssdev);
> -	unsigned int i;
>  
>  	dsi_bus_lock(dsi);
>  	dsi->video_enabled = false;
>  
> -	for (i = 0; i < 4; i++) {
> -		if (!dsi->vc[i].dest)
> -			continue;
> -		dsi_disable_video_output(dssdev, i);
> -	}
> +	dsi_disable_video_output(dssdev, VC_DEFAULT);
>  
>  	dsi_display_disable(dssdev);
>  
> @@ -3914,11 +3912,6 @@ static int dsi_update_channel(struct omap_dss_device *dssdev, int channel)
>  		goto err;
>  	}
>  
> -	if (!dsi->vc[channel].dest) {
> -		r = -ENODEV;
> -		goto err;
> -	}
> -
>  	if (dsi->vm.hactive == 0 || dsi->vm.vactive == 0) {
>  		r = -EINVAL;
>  		goto err;
> @@ -3959,16 +3952,7 @@ static int dsi_update_channel(struct omap_dss_device *dssdev, int channel)
>  
>  static int dsi_update_all(struct omap_dss_device *dssdev)
>  {
> -	unsigned int i;
> -	int r;
> -
> -	for (i = 0; i < 4; i++) {
> -		r = dsi_update_channel(dssdev, i);
> -		if (r && r != -ENODEV)
> -			return r;
> -	}
> -
> -	return r;
> +	return dsi_update_channel(dssdev, VC_DEFAULT);
>  }
>  
>  /* Display funcs */
> @@ -4196,17 +4180,12 @@ static void dsi_display_enable(struct omap_dss_device *dssdev)
>  static void dsi_enable_video_outputs(struct omap_dss_device *dssdev)
>  {
>  	struct dsi_data *dsi = to_dsi_data(dssdev);
> -	unsigned int i;
>  
>  	dsi_bus_lock(dsi);
>  
>  	dsi_display_enable(dssdev);
>  
> -	for (i = 0; i < 4; i++) {
> -		if (!dsi->vc[i].dest)
> -			continue;
> -		dsi_enable_video_output(dssdev, i);
> -	}
> +	dsi_enable_video_output(dssdev, VC_DEFAULT);
>  
>  	dsi->video_enabled = true;
>  
> @@ -5095,8 +5074,8 @@ static int omap_dsi_host_attach(struct mipi_dsi_host *host,
>  	if (channel > 3)
>  		return -EINVAL;
>  
> -	if (dsi->vc[channel].dest) {
> -		DSSERR("cannot get VC for display %s", dev_name(&client->dev));
> +	if (dsi->dsidev) {
> +		DSSERR("dsi client already attached\n");
>  		return -EBUSY;
>  	}
>  
> @@ -5117,7 +5096,7 @@ static int omap_dsi_host_attach(struct mipi_dsi_host *host,
>  		dsi->mode = OMAP_DSS_DSI_CMD_MODE;
>  	}
>  
> -	dsi->vc[channel].dest = client;
> +	dsi->dsidev = client;
>  	dsi->pix_fmt = client->format;
>  
>  	INIT_DEFERRABLE_WORK(&dsi->ulps_work,
> @@ -5149,11 +5128,11 @@ static int omap_dsi_host_detach(struct mipi_dsi_host *host,
>  	if (channel > 3)
>  		return -EINVAL;
>  
> -	if (dsi->vc[channel].dest != client)
> +	if (WARN_ON(dsi->dsidev != client))
>  		return -EINVAL;
>  
>  	omap_dsi_unregister_te_irq(dsi);
> -	dsi->vc[channel].dest = NULL;
> +	dsi->dsidev = NULL;
>  	return 0;
>  }
>  
> @@ -5685,10 +5664,8 @@ static int dsi_probe(struct platform_device *pdev)
>  	}
>  
>  	/* DSI VCs initialization */
> -	for (i = 0; i < ARRAY_SIZE(dsi->vc); i++) {
> +	for (i = 0; i < ARRAY_SIZE(dsi->vc); i++)
>  		dsi->vc[i].source = DSI_VC_SOURCE_L4;
> -		dsi->vc[i].dest = NULL;
> -	}
>  
>  	r = dsi_get_clocks(dsi);
>  	if (r)
> -- 
> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
> Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v5 08/29] drm/omap: dsi: drop useless channel checks
  2020-12-08 12:28 ` [PATCH v5 08/29] drm/omap: dsi: drop useless channel checks Tomi Valkeinen
@ 2020-12-14 14:32   ` Sebastian Reichel
  0 siblings, 0 replies; 72+ messages in thread
From: Sebastian Reichel @ 2020-12-14 14:32 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Laurent Pinchart, Nikhil Devshatwar, dri-devel, linux-omap,
	Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg

[-- Attachment #1: Type: text/plain, Size: 1903 bytes --]

Hi,

On Tue, Dec 08, 2020 at 02:28:34PM +0200, Tomi Valkeinen wrote:
> A DSI peripheral can have virtual channel ID of 0-3. This should be
> always the case, and there's no need in the driver to validate the
> channel.
> 
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---

Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>

-- Sebastian

>  drivers/gpu/drm/omapdrm/dss/dsi.c | 11 -----------
>  1 file changed, 11 deletions(-)
> 
> diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
> index 5e13478010db..c78ae99c8742 100644
> --- a/drivers/gpu/drm/omapdrm/dss/dsi.c
> +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
> @@ -3902,9 +3902,6 @@ static int dsi_update_channel(struct omap_dss_device *dssdev, int channel)
>  	struct dsi_data *dsi = to_dsi_data(dssdev);
>  	int r;
>  
> -	if (channel > 3)
> -		return -EINVAL;
> -
>  	dsi_bus_lock(dsi);
>  
>  	if (!dsi->video_enabled) {
> @@ -5068,12 +5065,8 @@ static int omap_dsi_host_attach(struct mipi_dsi_host *host,
>  				struct mipi_dsi_device *client)
>  {
>  	struct dsi_data *dsi = host_to_omap(host);
> -	unsigned int channel = client->channel;
>  	int r;
>  
> -	if (channel > 3)
> -		return -EINVAL;
> -
>  	if (dsi->dsidev) {
>  		DSSERR("dsi client already attached\n");
>  		return -EBUSY;
> @@ -5123,10 +5116,6 @@ static int omap_dsi_host_detach(struct mipi_dsi_host *host,
>  				struct mipi_dsi_device *client)
>  {
>  	struct dsi_data *dsi = host_to_omap(host);
> -	unsigned int channel = client->channel;
> -
> -	if (channel > 3)
> -		return -EINVAL;
>  
>  	if (WARN_ON(dsi->dsidev != client))
>  		return -EINVAL;
> -- 
> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
> Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v5 09/29] drm/omap: dsi: cleanup dispc channel usage
  2020-12-08 12:28 ` [PATCH v5 09/29] drm/omap: dsi: cleanup dispc channel usage Tomi Valkeinen
  2020-12-08 15:17   ` Laurent Pinchart
@ 2020-12-14 14:35   ` Sebastian Reichel
  1 sibling, 0 replies; 72+ messages in thread
From: Sebastian Reichel @ 2020-12-14 14:35 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Laurent Pinchart, Nikhil Devshatwar, dri-devel, linux-omap,
	Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg

[-- Attachment #1: Type: text/plain, Size: 3319 bytes --]

Hi,

On Tue, Dec 08, 2020 at 02:28:35PM +0200, Tomi Valkeinen wrote:
> The "channel" usage in omap dsi driver is confusing. As the first step,
> change "channel" to "dispc_channel" when dealing with the dispc channel.
> 
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> ---

Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>

-- Sebastian

>  drivers/gpu/drm/omapdrm/dss/dsi.c | 16 ++++++++--------
>  1 file changed, 8 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
> index c78ae99c8742..cf0dc4872d14 100644
> --- a/drivers/gpu/drm/omapdrm/dss/dsi.c
> +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
> @@ -3978,10 +3978,10 @@ static int dsi_configure_dispc_clocks(struct dsi_data *dsi)
>  
>  static int dsi_display_init_dispc(struct dsi_data *dsi)
>  {
> -	enum omap_channel channel = dsi->output.dispc_channel;
> +	enum omap_channel dispc_channel = dsi->output.dispc_channel;
>  	int r;
>  
> -	dss_select_lcd_clk_source(dsi->dss, channel, dsi->module_id == 0 ?
> +	dss_select_lcd_clk_source(dsi->dss, dispc_channel, dsi->module_id == 0 ?
>  			DSS_CLK_SRC_PLL1_1 :
>  			DSS_CLK_SRC_PLL2_1);
>  
> @@ -4017,19 +4017,19 @@ static int dsi_display_init_dispc(struct dsi_data *dsi)
>  		dss_mgr_unregister_framedone_handler(&dsi->output,
>  				dsi_framedone_irq_callback, dsi);
>  err:
> -	dss_select_lcd_clk_source(dsi->dss, channel, DSS_CLK_SRC_FCK);
> +	dss_select_lcd_clk_source(dsi->dss, dispc_channel, DSS_CLK_SRC_FCK);
>  	return r;
>  }
>  
>  static void dsi_display_uninit_dispc(struct dsi_data *dsi)
>  {
> -	enum omap_channel channel = dsi->output.dispc_channel;
> +	enum omap_channel dispc_channel = dsi->output.dispc_channel;
>  
>  	if (dsi->mode == OMAP_DSS_DSI_CMD_MODE)
>  		dss_mgr_unregister_framedone_handler(&dsi->output,
>  				dsi_framedone_irq_callback, dsi);
>  
> -	dss_select_lcd_clk_source(dsi->dss, channel, DSS_CLK_SRC_FCK);
> +	dss_select_lcd_clk_source(dsi->dss, dispc_channel, DSS_CLK_SRC_FCK);
>  }
>  
>  static int dsi_configure_dsi_clocks(struct dsi_data *dsi)
> @@ -4846,12 +4846,12 @@ static int dsi_set_config(struct omap_dss_device *dssdev,
>  }
>  
>  /*
> - * Return a hardcoded channel for the DSI output. This should work for
> + * Return a hardcoded dispc channel for the DSI output. This should work for
>   * current use cases, but this can be later expanded to either resolve
>   * the channel in some more dynamic manner, or get the channel as a user
>   * parameter.
>   */
> -static enum omap_channel dsi_get_channel(struct dsi_data *dsi)
> +static enum omap_channel dsi_get_dispc_channel(struct dsi_data *dsi)
>  {
>  	switch (dsi->data->model) {
>  	case DSI_MODEL_OMAP3:
> @@ -5403,7 +5403,7 @@ static int dsi_init_output(struct dsi_data *dsi)
>  
>  	out->type = OMAP_DISPLAY_TYPE_DSI;
>  	out->name = dsi->module_id == 0 ? "dsi.0" : "dsi.1";
> -	out->dispc_channel = dsi_get_channel(dsi);
> +	out->dispc_channel = dsi_get_dispc_channel(dsi);
>  	out->dsi_ops = &dsi_ops;
>  	out->of_port = 0;
>  	out->bus_flags = DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE
> -- 
> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
> Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v5 10/29] drm/omap: dsi: rename 'channel' to 'vc'
  2020-12-08 12:28 ` [PATCH v5 10/29] drm/omap: dsi: rename 'channel' to 'vc' Tomi Valkeinen
  2020-12-08 15:22   ` Laurent Pinchart
@ 2020-12-14 15:18   ` Sebastian Reichel
  1 sibling, 0 replies; 72+ messages in thread
From: Sebastian Reichel @ 2020-12-14 15:18 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Laurent Pinchart, Nikhil Devshatwar, dri-devel, linux-omap,
	Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg

[-- Attachment #1: Type: text/plain, Size: 26325 bytes --]

Hi,

On Tue, Dec 08, 2020 at 02:28:36PM +0200, Tomi Valkeinen wrote:
> The "channel" usage in omap dsi driver is confusing. We have three
> different "channels":
> 
> 1) DSI virtual channel ID. This is a number from 0 to 3, included in the
> packet payload.
> 
> 2) VC. This is a register block in the DSI IP. There are four of those
> blocks. A VC is a DSI "pipeline", with defined fifo settings, data
> source (cpu or dispc), and some other settings. It has no relation to
> the 1).
> 
> 3) dispc channel. It's the "pipeline" number dispc uses to send pixel
> data.
> 
> The previous patch handled the third case.
> 
>  To start fixing 1) and 2), we first rename all uses of 'channel' to
> 'vc', as in most of the cases that is the correct thing to use.
> 
> However, in some places 1) and 2) have gotten mixed up (i.e. the code
> uses msg->channel when it should use vc), which will be fixed in the
> following patch.
> 
> Note that mixing 1) and 2) currently is "fine", as at the moment we only
> support DSI peripherals with DSI virtual channel 0, and we always use
> VC0 to send data. So both 1) and 2) are always 0.
> 
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> ---

Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>

-- Sebastian

>  drivers/gpu/drm/omapdrm/dss/dsi.c | 220 +++++++++++++++---------------
>  1 file changed, 110 insertions(+), 110 deletions(-)
> 
> diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
> index cf0dc4872d14..273159e8f992 100644
> --- a/drivers/gpu/drm/omapdrm/dss/dsi.c
> +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
> @@ -214,7 +214,7 @@ static void dsi_set_ulps_auto(struct dsi_data *dsi, bool enable);
>  static int dsi_display_init_dispc(struct dsi_data *dsi);
>  static void dsi_display_uninit_dispc(struct dsi_data *dsi);
>  
> -static int dsi_vc_send_null(struct dsi_data *dsi, int channel);
> +static int dsi_vc_send_null(struct dsi_data *dsi, int vc);
>  
>  static ssize_t _omap_dsi_host_transfer(struct dsi_data *dsi,
>  				       const struct mipi_dsi_msg *msg);
> @@ -376,7 +376,7 @@ struct dsi_data {
>  	/* space for a copy used by the interrupt handler */
>  	struct dsi_isr_tables isr_tables_copy;
>  
> -	int update_channel;
> +	int update_vc;
>  #ifdef DSI_PERF_MEASURE
>  	unsigned int update_bytes;
>  #endif
> @@ -639,7 +639,7 @@ static void print_irq_status(u32 status)
>  #undef PIS
>  }
>  
> -static void print_irq_status_vc(int channel, u32 status)
> +static void print_irq_status_vc(int vc, u32 status)
>  {
>  	if (status == 0)
>  		return;
> @@ -650,7 +650,7 @@ static void print_irq_status_vc(int channel, u32 status)
>  #define PIS(x) (status & DSI_VC_IRQ_##x) ? (#x " ") : ""
>  
>  	pr_debug("DSI VC(%d) IRQ 0x%x: %s%s%s%s%s%s%s%s%s\n",
> -		channel,
> +		vc,
>  		status,
>  		PIS(CS),
>  		PIS(ECC_CORR),
> @@ -1031,7 +1031,7 @@ static int dsi_unregister_isr(struct dsi_data *dsi, omap_dsi_isr_t isr,
>  	return r;
>  }
>  
> -static int dsi_register_isr_vc(struct dsi_data *dsi, int channel,
> +static int dsi_register_isr_vc(struct dsi_data *dsi, int vc,
>  			       omap_dsi_isr_t isr, void *arg, u32 mask)
>  {
>  	unsigned long flags;
> @@ -1040,18 +1040,18 @@ static int dsi_register_isr_vc(struct dsi_data *dsi, int channel,
>  	spin_lock_irqsave(&dsi->irq_lock, flags);
>  
>  	r = _dsi_register_isr(isr, arg, mask,
> -			dsi->isr_tables.isr_table_vc[channel],
> -			ARRAY_SIZE(dsi->isr_tables.isr_table_vc[channel]));
> +			dsi->isr_tables.isr_table_vc[vc],
> +			ARRAY_SIZE(dsi->isr_tables.isr_table_vc[vc]));
>  
>  	if (r == 0)
> -		_omap_dsi_set_irqs_vc(dsi, channel);
> +		_omap_dsi_set_irqs_vc(dsi, vc);
>  
>  	spin_unlock_irqrestore(&dsi->irq_lock, flags);
>  
>  	return r;
>  }
>  
> -static int dsi_unregister_isr_vc(struct dsi_data *dsi, int channel,
> +static int dsi_unregister_isr_vc(struct dsi_data *dsi, int vc,
>  				 omap_dsi_isr_t isr, void *arg, u32 mask)
>  {
>  	unsigned long flags;
> @@ -1060,11 +1060,11 @@ static int dsi_unregister_isr_vc(struct dsi_data *dsi, int channel,
>  	spin_lock_irqsave(&dsi->irq_lock, flags);
>  
>  	r = _dsi_unregister_isr(isr, arg, mask,
> -			dsi->isr_tables.isr_table_vc[channel],
> -			ARRAY_SIZE(dsi->isr_tables.isr_table_vc[channel]));
> +			dsi->isr_tables.isr_table_vc[vc],
> +			ARRAY_SIZE(dsi->isr_tables.isr_table_vc[vc]));
>  
>  	if (r == 0)
> -		_omap_dsi_set_irqs_vc(dsi, channel);
> +		_omap_dsi_set_irqs_vc(dsi, vc);
>  
>  	spin_unlock_irqrestore(&dsi->irq_lock, flags);
>  
> @@ -2232,9 +2232,9 @@ static int dsi_force_tx_stop_mode_io(struct dsi_data *dsi)
>  	return 0;
>  }
>  
> -static bool dsi_vc_is_enabled(struct dsi_data *dsi, int channel)
> +static bool dsi_vc_is_enabled(struct dsi_data *dsi, int vc)
>  {
> -	return REG_GET(dsi, DSI_VC_CTRL(channel), 0, 0);
> +	return REG_GET(dsi, DSI_VC_CTRL(vc), 0, 0);
>  }
>  
>  static void dsi_packet_sent_handler_vp(void *data, u32 mask)
> @@ -2242,14 +2242,14 @@ static void dsi_packet_sent_handler_vp(void *data, u32 mask)
>  	struct dsi_packet_sent_handler_data *vp_data =
>  		(struct dsi_packet_sent_handler_data *) data;
>  	struct dsi_data *dsi = vp_data->dsi;
> -	const int channel = dsi->update_channel;
> +	const int vc = dsi->update_vc;
>  	u8 bit = dsi->te_enabled ? 30 : 31;
>  
> -	if (REG_GET(dsi, DSI_VC_TE(channel), bit, bit) == 0)
> +	if (REG_GET(dsi, DSI_VC_TE(vc), bit, bit) == 0)
>  		complete(vp_data->completion);
>  }
>  
> -static int dsi_sync_vc_vp(struct dsi_data *dsi, int channel)
> +static int dsi_sync_vc_vp(struct dsi_data *dsi, int vc)
>  {
>  	DECLARE_COMPLETION_ONSTACK(completion);
>  	struct dsi_packet_sent_handler_data vp_data = {
> @@ -2261,13 +2261,13 @@ static int dsi_sync_vc_vp(struct dsi_data *dsi, int channel)
>  
>  	bit = dsi->te_enabled ? 30 : 31;
>  
> -	r = dsi_register_isr_vc(dsi, channel, dsi_packet_sent_handler_vp,
> +	r = dsi_register_isr_vc(dsi, vc, dsi_packet_sent_handler_vp,
>  		&vp_data, DSI_VC_IRQ_PACKET_SENT);
>  	if (r)
>  		goto err0;
>  
>  	/* Wait for completion only if TE_EN/TE_START is still set */
> -	if (REG_GET(dsi, DSI_VC_TE(channel), bit, bit)) {
> +	if (REG_GET(dsi, DSI_VC_TE(vc), bit, bit)) {
>  		if (wait_for_completion_timeout(&completion,
>  				msecs_to_jiffies(10)) == 0) {
>  			DSSERR("Failed to complete previous frame transfer\n");
> @@ -2276,12 +2276,12 @@ static int dsi_sync_vc_vp(struct dsi_data *dsi, int channel)
>  		}
>  	}
>  
> -	dsi_unregister_isr_vc(dsi, channel, dsi_packet_sent_handler_vp,
> +	dsi_unregister_isr_vc(dsi, vc, dsi_packet_sent_handler_vp,
>  		&vp_data, DSI_VC_IRQ_PACKET_SENT);
>  
>  	return 0;
>  err1:
> -	dsi_unregister_isr_vc(dsi, channel, dsi_packet_sent_handler_vp,
> +	dsi_unregister_isr_vc(dsi, vc, dsi_packet_sent_handler_vp,
>  		&vp_data, DSI_VC_IRQ_PACKET_SENT);
>  err0:
>  	return r;
> @@ -2292,13 +2292,13 @@ static void dsi_packet_sent_handler_l4(void *data, u32 mask)
>  	struct dsi_packet_sent_handler_data *l4_data =
>  		(struct dsi_packet_sent_handler_data *) data;
>  	struct dsi_data *dsi = l4_data->dsi;
> -	const int channel = dsi->update_channel;
> +	const int vc = dsi->update_vc;
>  
> -	if (REG_GET(dsi, DSI_VC_CTRL(channel), 5, 5) == 0)
> +	if (REG_GET(dsi, DSI_VC_CTRL(vc), 5, 5) == 0)
>  		complete(l4_data->completion);
>  }
>  
> -static int dsi_sync_vc_l4(struct dsi_data *dsi, int channel)
> +static int dsi_sync_vc_l4(struct dsi_data *dsi, int vc)
>  {
>  	DECLARE_COMPLETION_ONSTACK(completion);
>  	struct dsi_packet_sent_handler_data l4_data = {
> @@ -2307,13 +2307,13 @@ static int dsi_sync_vc_l4(struct dsi_data *dsi, int channel)
>  	};
>  	int r = 0;
>  
> -	r = dsi_register_isr_vc(dsi, channel, dsi_packet_sent_handler_l4,
> +	r = dsi_register_isr_vc(dsi, vc, dsi_packet_sent_handler_l4,
>  		&l4_data, DSI_VC_IRQ_PACKET_SENT);
>  	if (r)
>  		goto err0;
>  
>  	/* Wait for completion only if TX_FIFO_NOT_EMPTY is still set */
> -	if (REG_GET(dsi, DSI_VC_CTRL(channel), 5, 5)) {
> +	if (REG_GET(dsi, DSI_VC_CTRL(vc), 5, 5)) {
>  		if (wait_for_completion_timeout(&completion,
>  				msecs_to_jiffies(10)) == 0) {
>  			DSSERR("Failed to complete previous l4 transfer\n");
> @@ -2322,47 +2322,47 @@ static int dsi_sync_vc_l4(struct dsi_data *dsi, int channel)
>  		}
>  	}
>  
> -	dsi_unregister_isr_vc(dsi, channel, dsi_packet_sent_handler_l4,
> +	dsi_unregister_isr_vc(dsi, vc, dsi_packet_sent_handler_l4,
>  		&l4_data, DSI_VC_IRQ_PACKET_SENT);
>  
>  	return 0;
>  err1:
> -	dsi_unregister_isr_vc(dsi, channel, dsi_packet_sent_handler_l4,
> +	dsi_unregister_isr_vc(dsi, vc, dsi_packet_sent_handler_l4,
>  		&l4_data, DSI_VC_IRQ_PACKET_SENT);
>  err0:
>  	return r;
>  }
>  
> -static int dsi_sync_vc(struct dsi_data *dsi, int channel)
> +static int dsi_sync_vc(struct dsi_data *dsi, int vc)
>  {
>  	WARN_ON(!dsi_bus_is_locked(dsi));
>  
>  	WARN_ON(in_interrupt());
>  
> -	if (!dsi_vc_is_enabled(dsi, channel))
> +	if (!dsi_vc_is_enabled(dsi, vc))
>  		return 0;
>  
> -	switch (dsi->vc[channel].source) {
> +	switch (dsi->vc[vc].source) {
>  	case DSI_VC_SOURCE_VP:
> -		return dsi_sync_vc_vp(dsi, channel);
> +		return dsi_sync_vc_vp(dsi, vc);
>  	case DSI_VC_SOURCE_L4:
> -		return dsi_sync_vc_l4(dsi, channel);
> +		return dsi_sync_vc_l4(dsi, vc);
>  	default:
>  		BUG();
>  		return -EINVAL;
>  	}
>  }
>  
> -static int dsi_vc_enable(struct dsi_data *dsi, int channel, bool enable)
> +static int dsi_vc_enable(struct dsi_data *dsi, int vc, bool enable)
>  {
> -	DSSDBG("dsi_vc_enable channel %d, enable %d\n",
> -			channel, enable);
> +	DSSDBG("dsi_vc_enable vc %d, enable %d\n",
> +			vc, enable);
>  
>  	enable = enable ? 1 : 0;
>  
> -	REG_FLD_MOD(dsi, DSI_VC_CTRL(channel), enable, 0, 0);
> +	REG_FLD_MOD(dsi, DSI_VC_CTRL(vc), enable, 0, 0);
>  
> -	if (!wait_for_bit_change(dsi, DSI_VC_CTRL(channel), 0, enable)) {
> +	if (!wait_for_bit_change(dsi, DSI_VC_CTRL(vc), 0, enable)) {
>  		DSSERR("Failed to set dsi_vc_enable to %d\n", enable);
>  		return -EIO;
>  	}
> @@ -2370,17 +2370,17 @@ static int dsi_vc_enable(struct dsi_data *dsi, int channel, bool enable)
>  	return 0;
>  }
>  
> -static void dsi_vc_initial_config(struct dsi_data *dsi, int channel)
> +static void dsi_vc_initial_config(struct dsi_data *dsi, int vc)
>  {
>  	u32 r;
>  
> -	DSSDBG("Initial config of virtual channel %d", channel);
> +	DSSDBG("Initial config of VC %d", vc);
>  
> -	r = dsi_read_reg(dsi, DSI_VC_CTRL(channel));
> +	r = dsi_read_reg(dsi, DSI_VC_CTRL(vc));
>  
>  	if (FLD_GET(r, 15, 15)) /* VC_BUSY */
>  		DSSERR("VC(%d) busy when trying to configure it!\n",
> -				channel);
> +				vc);
>  
>  	r = FLD_MOD(r, 0, 1, 1); /* SOURCE, 0 = L4 */
>  	r = FLD_MOD(r, 0, 2, 2); /* BTA_SHORT_EN  */
> @@ -2395,76 +2395,76 @@ static void dsi_vc_initial_config(struct dsi_data *dsi, int channel)
>  	r = FLD_MOD(r, 4, 29, 27); /* DMA_RX_REQ_NB = no dma */
>  	r = FLD_MOD(r, 4, 23, 21); /* DMA_TX_REQ_NB = no dma */
>  
> -	dsi_write_reg(dsi, DSI_VC_CTRL(channel), r);
> +	dsi_write_reg(dsi, DSI_VC_CTRL(vc), r);
>  
> -	dsi->vc[channel].source = DSI_VC_SOURCE_L4;
> +	dsi->vc[vc].source = DSI_VC_SOURCE_L4;
>  }
>  
> -static int dsi_vc_config_source(struct dsi_data *dsi, int channel,
> +static int dsi_vc_config_source(struct dsi_data *dsi, int vc,
>  				enum dsi_vc_source source)
>  {
> -	if (dsi->vc[channel].source == source)
> +	if (dsi->vc[vc].source == source)
>  		return 0;
>  
> -	DSSDBG("Source config of virtual channel %d", channel);
> +	DSSDBG("Source config of VC %d", vc);
>  
> -	dsi_sync_vc(dsi, channel);
> +	dsi_sync_vc(dsi, vc);
>  
> -	dsi_vc_enable(dsi, channel, 0);
> +	dsi_vc_enable(dsi, vc, 0);
>  
>  	/* VC_BUSY */
> -	if (!wait_for_bit_change(dsi, DSI_VC_CTRL(channel), 15, 0)) {
> -		DSSERR("vc(%d) busy when trying to config for VP\n", channel);
> +	if (!wait_for_bit_change(dsi, DSI_VC_CTRL(vc), 15, 0)) {
> +		DSSERR("vc(%d) busy when trying to config for VP\n", vc);
>  		return -EIO;
>  	}
>  
>  	/* SOURCE, 0 = L4, 1 = video port */
> -	REG_FLD_MOD(dsi, DSI_VC_CTRL(channel), source, 1, 1);
> +	REG_FLD_MOD(dsi, DSI_VC_CTRL(vc), source, 1, 1);
>  
>  	/* DCS_CMD_ENABLE */
>  	if (dsi->data->quirks & DSI_QUIRK_DCS_CMD_CONFIG_VC) {
>  		bool enable = source == DSI_VC_SOURCE_VP;
> -		REG_FLD_MOD(dsi, DSI_VC_CTRL(channel), enable, 30, 30);
> +		REG_FLD_MOD(dsi, DSI_VC_CTRL(vc), enable, 30, 30);
>  	}
>  
> -	dsi_vc_enable(dsi, channel, 1);
> +	dsi_vc_enable(dsi, vc, 1);
>  
> -	dsi->vc[channel].source = source;
> +	dsi->vc[vc].source = source;
>  
>  	return 0;
>  }
>  
> -static void dsi_vc_enable_hs(struct omap_dss_device *dssdev, int channel,
> +static void dsi_vc_enable_hs(struct omap_dss_device *dssdev, int vc,
>  		bool enable)
>  {
>  	struct dsi_data *dsi = to_dsi_data(dssdev);
>  
> -	DSSDBG("dsi_vc_enable_hs(%d, %d)\n", channel, enable);
> +	DSSDBG("dsi_vc_enable_hs(%d, %d)\n", vc, enable);
>  
>  	WARN_ON(!dsi_bus_is_locked(dsi));
>  
> -	dsi_vc_enable(dsi, channel, 0);
> +	dsi_vc_enable(dsi, vc, 0);
>  	dsi_if_enable(dsi, 0);
>  
> -	REG_FLD_MOD(dsi, DSI_VC_CTRL(channel), enable, 9, 9);
> +	REG_FLD_MOD(dsi, DSI_VC_CTRL(vc), enable, 9, 9);
>  
> -	dsi_vc_enable(dsi, channel, 1);
> +	dsi_vc_enable(dsi, vc, 1);
>  	dsi_if_enable(dsi, 1);
>  
>  	dsi_force_tx_stop_mode_io(dsi);
>  
>  	/* start the DDR clock by sending a NULL packet */
>  	if (dsi->vm_timings.ddr_clk_always_on && enable)
> -		dsi_vc_send_null(dsi, channel);
> +		dsi_vc_send_null(dsi, vc);
>  
>  	dsi->in_lp_mode = !enable;
>  }
>  
> -static void dsi_vc_flush_long_data(struct dsi_data *dsi, int channel)
> +static void dsi_vc_flush_long_data(struct dsi_data *dsi, int vc)
>  {
> -	while (REG_GET(dsi, DSI_VC_CTRL(channel), 20, 20)) {
> +	while (REG_GET(dsi, DSI_VC_CTRL(vc), 20, 20)) {
>  		u32 val;
> -		val = dsi_read_reg(dsi, DSI_VC_SHORT_PACKET_HEADER(channel));
> +		val = dsi_read_reg(dsi, DSI_VC_SHORT_PACKET_HEADER(vc));
>  		DSSDBG("\t\tb1 %#02x b2 %#02x b3 %#02x b4 %#02x\n",
>  				(val >> 0) & 0xff,
>  				(val >> 8) & 0xff,
> @@ -2510,13 +2510,13 @@ static void dsi_show_rx_ack_with_err(u16 err)
>  		DSSERR("\t\tDSI Protocol Violation\n");
>  }
>  
> -static u16 dsi_vc_flush_receive_data(struct dsi_data *dsi, int channel)
> +static u16 dsi_vc_flush_receive_data(struct dsi_data *dsi, int vc)
>  {
>  	/* RX_FIFO_NOT_EMPTY */
> -	while (REG_GET(dsi, DSI_VC_CTRL(channel), 20, 20)) {
> +	while (REG_GET(dsi, DSI_VC_CTRL(vc), 20, 20)) {
>  		u32 val;
>  		u8 dt;
> -		val = dsi_read_reg(dsi, DSI_VC_SHORT_PACKET_HEADER(channel));
> +		val = dsi_read_reg(dsi, DSI_VC_SHORT_PACKET_HEADER(vc));
>  		DSSERR("\trawval %#08x\n", val);
>  		dt = FLD_GET(val, 5, 0);
>  		if (dt == MIPI_DSI_RX_ACKNOWLEDGE_AND_ERROR_REPORT) {
> @@ -2531,7 +2531,7 @@ static u16 dsi_vc_flush_receive_data(struct dsi_data *dsi, int channel)
>  		} else if (dt == MIPI_DSI_RX_DCS_LONG_READ_RESPONSE) {
>  			DSSERR("\tDCS long response, len %d\n",
>  					FLD_GET(val, 23, 8));
> -			dsi_vc_flush_long_data(dsi, channel);
> +			dsi_vc_flush_long_data(dsi, vc);
>  		} else {
>  			DSSERR("\tunknown datatype 0x%02x\n", dt);
>  		}
> @@ -2539,35 +2539,35 @@ static u16 dsi_vc_flush_receive_data(struct dsi_data *dsi, int channel)
>  	return 0;
>  }
>  
> -static int dsi_vc_send_bta(struct dsi_data *dsi, int channel)
> +static int dsi_vc_send_bta(struct dsi_data *dsi, int vc)
>  {
>  	if (dsi->debug_write || dsi->debug_read)
> -		DSSDBG("dsi_vc_send_bta %d\n", channel);
> +		DSSDBG("dsi_vc_send_bta %d\n", vc);
>  
>  	WARN_ON(!dsi_bus_is_locked(dsi));
>  
>  	/* RX_FIFO_NOT_EMPTY */
> -	if (REG_GET(dsi, DSI_VC_CTRL(channel), 20, 20)) {
> +	if (REG_GET(dsi, DSI_VC_CTRL(vc), 20, 20)) {
>  		DSSERR("rx fifo not empty when sending BTA, dumping data:\n");
> -		dsi_vc_flush_receive_data(dsi, channel);
> +		dsi_vc_flush_receive_data(dsi, vc);
>  	}
>  
> -	REG_FLD_MOD(dsi, DSI_VC_CTRL(channel), 1, 6, 6); /* BTA_EN */
> +	REG_FLD_MOD(dsi, DSI_VC_CTRL(vc), 1, 6, 6); /* BTA_EN */
>  
>  	/* flush posted write */
> -	dsi_read_reg(dsi, DSI_VC_CTRL(channel));
> +	dsi_read_reg(dsi, DSI_VC_CTRL(vc));
>  
>  	return 0;
>  }
>  
> -static int dsi_vc_send_bta_sync(struct omap_dss_device *dssdev, int channel)
> +static int dsi_vc_send_bta_sync(struct omap_dss_device *dssdev, int vc)
>  {
>  	struct dsi_data *dsi = to_dsi_data(dssdev);
>  	DECLARE_COMPLETION_ONSTACK(completion);
>  	int r = 0;
>  	u32 err;
>  
> -	r = dsi_register_isr_vc(dsi, channel, dsi_completion_handler,
> +	r = dsi_register_isr_vc(dsi, vc, dsi_completion_handler,
>  			&completion, DSI_VC_IRQ_BTA);
>  	if (r)
>  		goto err0;
> @@ -2577,7 +2577,7 @@ static int dsi_vc_send_bta_sync(struct omap_dss_device *dssdev, int channel)
>  	if (r)
>  		goto err1;
>  
> -	r = dsi_vc_send_bta(dsi, channel);
> +	r = dsi_vc_send_bta(dsi, vc);
>  	if (r)
>  		goto err2;
>  
> @@ -2598,13 +2598,13 @@ static int dsi_vc_send_bta_sync(struct omap_dss_device *dssdev, int channel)
>  	dsi_unregister_isr(dsi, dsi_completion_handler, &completion,
>  			DSI_IRQ_ERROR_MASK);
>  err1:
> -	dsi_unregister_isr_vc(dsi, channel, dsi_completion_handler,
> +	dsi_unregister_isr_vc(dsi, vc, dsi_completion_handler,
>  			&completion, DSI_VC_IRQ_BTA);
>  err0:
>  	return r;
>  }
>  
> -static inline void dsi_vc_write_long_header(struct dsi_data *dsi, int channel,
> +static inline void dsi_vc_write_long_header(struct dsi_data *dsi, int vc,
>  					    u8 data_type, u16 len, u8 ecc)
>  {
>  	u32 val;
> @@ -2612,15 +2612,15 @@ static inline void dsi_vc_write_long_header(struct dsi_data *dsi, int channel,
>  
>  	WARN_ON(!dsi_bus_is_locked(dsi));
>  
> -	data_id = data_type | channel << 6;
> +	data_id = data_type | vc << 6;
>  
>  	val = FLD_VAL(data_id, 7, 0) | FLD_VAL(len, 23, 8) |
>  		FLD_VAL(ecc, 31, 24);
>  
> -	dsi_write_reg(dsi, DSI_VC_LONG_PACKET_HEADER(channel), val);
> +	dsi_write_reg(dsi, DSI_VC_LONG_PACKET_HEADER(vc), val);
>  }
>  
> -static inline void dsi_vc_write_long_payload(struct dsi_data *dsi, int channel,
> +static inline void dsi_vc_write_long_payload(struct dsi_data *dsi, int vc,
>  					     u8 b1, u8 b2, u8 b3, u8 b4)
>  {
>  	u32 val;
> @@ -2630,7 +2630,7 @@ static inline void dsi_vc_write_long_payload(struct dsi_data *dsi, int channel,
>  /*	DSSDBG("\twriting %02x, %02x, %02x, %02x (%#010x)\n",
>  			b1, b2, b3, b4, val); */
>  
> -	dsi_write_reg(dsi, DSI_VC_LONG_PACKET_PAYLOAD(channel), val);
> +	dsi_write_reg(dsi, DSI_VC_LONG_PACKET_PAYLOAD(vc), val);
>  }
>  
>  static int dsi_vc_send_long(struct dsi_data *dsi,
> @@ -2727,10 +2727,10 @@ static int dsi_vc_send_short(struct dsi_data *dsi,
>  	return 0;
>  }
>  
> -static int dsi_vc_send_null(struct dsi_data *dsi, int channel)
> +static int dsi_vc_send_null(struct dsi_data *dsi, int vc)
>  {
>  	const struct mipi_dsi_msg msg = {
> -		.channel = channel,
> +		.channel = vc,
>  		.type = MIPI_DSI_NULL_PACKET,
>  	};
>  
> @@ -2774,7 +2774,7 @@ static int dsi_vc_write_common(struct omap_dss_device *dssdev,
>  	return 0;
>  }
>  
> -static int dsi_vc_read_rx_fifo(struct dsi_data *dsi, int channel, u8 *buf,
> +static int dsi_vc_read_rx_fifo(struct dsi_data *dsi, int vc, u8 *buf,
>  			       int buflen, enum dss_dsi_content_type type)
>  {
>  	u32 val;
> @@ -2782,13 +2782,13 @@ static int dsi_vc_read_rx_fifo(struct dsi_data *dsi, int channel, u8 *buf,
>  	int r;
>  
>  	/* RX_FIFO_NOT_EMPTY */
> -	if (REG_GET(dsi, DSI_VC_CTRL(channel), 20, 20) == 0) {
> +	if (REG_GET(dsi, DSI_VC_CTRL(vc), 20, 20) == 0) {
>  		DSSERR("RX fifo empty when trying to read.\n");
>  		r = -EIO;
>  		goto err;
>  	}
>  
> -	val = dsi_read_reg(dsi, DSI_VC_SHORT_PACKET_HEADER(channel));
> +	val = dsi_read_reg(dsi, DSI_VC_SHORT_PACKET_HEADER(vc));
>  	if (dsi->debug_read)
>  		DSSDBG("\theader: %08x\n", val);
>  	dt = FLD_GET(val, 5, 0);
> @@ -2852,7 +2852,7 @@ static int dsi_vc_read_rx_fifo(struct dsi_data *dsi, int channel, u8 *buf,
>  		for (w = 0; w < len + 2;) {
>  			int b;
>  			val = dsi_read_reg(dsi,
> -				DSI_VC_SHORT_PACKET_HEADER(channel));
> +				DSI_VC_SHORT_PACKET_HEADER(vc));
>  			if (dsi->debug_read)
>  				DSSDBG("\t\t%02x %02x %02x %02x\n",
>  						(val >> 0) & 0xff,
> @@ -2876,7 +2876,7 @@ static int dsi_vc_read_rx_fifo(struct dsi_data *dsi, int channel, u8 *buf,
>  	}
>  
>  err:
> -	DSSERR("dsi_vc_read_rx_fifo(ch %d type %s) failed\n", channel,
> +	DSSERR("dsi_vc_read_rx_fifo(vc %d type %s) failed\n", vc,
>  		type == DSS_DSI_CONTENT_GENERIC ? "GENERIC" : "DCS");
>  
>  	return r;
> @@ -3631,7 +3631,7 @@ static int dsi_configure_pins(struct dsi_data *dsi,
>  	return 0;
>  }
>  
> -static void dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
> +static void dsi_enable_video_output(struct omap_dss_device *dssdev, int vc)
>  {
>  	struct dsi_data *dsi = to_dsi_data(dssdev);
>  	int bpp = mipi_dsi_pixel_format_to_bpp(dsi->pix_fmt);
> @@ -3665,17 +3665,17 @@ static void dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
>  		}
>  
>  		dsi_if_enable(dsi, false);
> -		dsi_vc_enable(dsi, channel, false);
> +		dsi_vc_enable(dsi, vc, false);
>  
>  		/* MODE, 1 = video mode */
> -		REG_FLD_MOD(dsi, DSI_VC_CTRL(channel), 1, 4, 4);
> +		REG_FLD_MOD(dsi, DSI_VC_CTRL(vc), 1, 4, 4);
>  
>  		word_count = DIV_ROUND_UP(dsi->vm.hactive * bpp, 8);
>  
> -		dsi_vc_write_long_header(dsi, channel, data_type,
> +		dsi_vc_write_long_header(dsi, vc, data_type,
>  				word_count, 0);
>  
> -		dsi_vc_enable(dsi, channel, true);
> +		dsi_vc_enable(dsi, vc, true);
>  		dsi_if_enable(dsi, true);
>  	}
>  
> @@ -3688,7 +3688,7 @@ static void dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
>  err_mgr_enable:
>  	if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) {
>  		dsi_if_enable(dsi, false);
> -		dsi_vc_enable(dsi, channel, false);
> +		dsi_vc_enable(dsi, vc, false);
>  	}
>  err_pix_fmt:
>  	dsi_display_uninit_dispc(dsi);
> @@ -3696,18 +3696,18 @@ static void dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
>  	return;
>  }
>  
> -static void dsi_disable_video_output(struct omap_dss_device *dssdev, int channel)
> +static void dsi_disable_video_output(struct omap_dss_device *dssdev, int vc)
>  {
>  	struct dsi_data *dsi = to_dsi_data(dssdev);
>  
>  	if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) {
>  		dsi_if_enable(dsi, false);
> -		dsi_vc_enable(dsi, channel, false);
> +		dsi_vc_enable(dsi, vc, false);
>  
>  		/* MODE, 0 = command mode */
> -		REG_FLD_MOD(dsi, DSI_VC_CTRL(channel), 0, 4, 4);
> +		REG_FLD_MOD(dsi, DSI_VC_CTRL(vc), 0, 4, 4);
>  
> -		dsi_vc_enable(dsi, channel, true);
> +		dsi_vc_enable(dsi, vc, true);
>  		dsi_if_enable(dsi, true);
>  	}
>  
> @@ -3740,14 +3740,14 @@ static void dsi_update_screen_dispc(struct dsi_data *dsi)
>  	unsigned int packet_len;
>  	u32 l;
>  	int r;
> -	const unsigned channel = dsi->update_channel;
> +	const unsigned vc = dsi->update_vc;
>  	const unsigned int line_buf_size = dsi->line_buffer_size;
>  	u16 w = dsi->vm.hactive;
>  	u16 h = dsi->vm.vactive;
>  
>  	DSSDBG("dsi_update_screen_dispc(%dx%d)\n", w, h);
>  
> -	dsi_vc_config_source(dsi, channel, DSI_VC_SOURCE_VP);
> +	dsi_vc_config_source(dsi, vc, DSI_VC_SOURCE_VP);
>  
>  	bytespp	= mipi_dsi_pixel_format_to_bpp(dsi->pix_fmt) / 8;
>  	bytespl = w * bytespp;
> @@ -3768,16 +3768,16 @@ static void dsi_update_screen_dispc(struct dsi_data *dsi)
>  		total_len += (bytespf % packet_payload) + 1;
>  
>  	l = FLD_VAL(total_len, 23, 0); /* TE_SIZE */
> -	dsi_write_reg(dsi, DSI_VC_TE(channel), l);
> +	dsi_write_reg(dsi, DSI_VC_TE(vc), l);
>  
> -	dsi_vc_write_long_header(dsi, channel, MIPI_DSI_DCS_LONG_WRITE,
> +	dsi_vc_write_long_header(dsi, vc, MIPI_DSI_DCS_LONG_WRITE,
>  		packet_len, 0);
>  
>  	if (dsi->te_enabled)
>  		l = FLD_MOD(l, 1, 30, 30); /* TE_EN */
>  	else
>  		l = FLD_MOD(l, 1, 31, 31); /* TE_START */
> -	dsi_write_reg(dsi, DSI_VC_TE(channel), l);
> +	dsi_write_reg(dsi, DSI_VC_TE(vc), l);
>  
>  	/* We put SIDLEMODE to no-idle for the duration of the transfer,
>  	 * because DSS interrupts are not capable of waking up the CPU and the
> @@ -3800,7 +3800,7 @@ static void dsi_update_screen_dispc(struct dsi_data *dsi)
>  		 * for TE is longer than the timer allows */
>  		REG_FLD_MOD(dsi, DSI_TIMING2, 0, 15, 15); /* LP_RX_TO */
>  
> -		dsi_vc_send_bta(dsi, channel);
> +		dsi_vc_send_bta(dsi, vc);
>  
>  #ifdef DSI_CATCH_MISSING_TE
>  		mod_timer(&dsi->te_timer, jiffies + msecs_to_jiffies(250));
> @@ -3897,7 +3897,7 @@ static int _dsi_send_nop(struct dsi_data *dsi, int channel)
>  	return _omap_dsi_host_transfer(dsi, &msg);
>  }
>  
> -static int dsi_update_channel(struct omap_dss_device *dssdev, int channel)
> +static int dsi_update_channel(struct omap_dss_device *dssdev, int vc)
>  {
>  	struct dsi_data *dsi = to_dsi_data(dssdev);
>  	int r;
> @@ -3914,7 +3914,7 @@ static int dsi_update_channel(struct omap_dss_device *dssdev, int channel)
>  		goto err;
>  	}
>  
> -	DSSDBG("dsi_update_channel: %d", channel);
> +	DSSDBG("dsi_update_channel: %d", vc);
>  
>  	dsi_set_ulps_auto(dsi, false);
>  
> @@ -3923,13 +3923,13 @@ static int dsi_update_channel(struct omap_dss_device *dssdev, int channel)
>  	 * updates stop working. This is probably related to DSI spec stating
>  	 * that the DSI host should transition to LP at least once per frame.
>  	 */
> -	r = _dsi_send_nop(dsi, channel);
> +	r = _dsi_send_nop(dsi, vc);
>  	if (r < 0) {
>  		DSSWARN("failed to send nop between frames: %d\n", r);
>  		goto err;
>  	}
>  
> -	dsi->update_channel = channel;
> +	dsi->update_vc = vc;
>  
>  	if (dsi->te_enabled && dsi->te_gpio) {
>  		schedule_delayed_work(&dsi->te_timeout_work,
> -- 
> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
> Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v5 11/29] drm/omap: dsi: pass vc to various functions
  2020-12-08 12:28 ` [PATCH v5 11/29] drm/omap: dsi: pass vc to various functions Tomi Valkeinen
  2020-12-08 15:38   ` Laurent Pinchart
@ 2020-12-14 15:37   ` Sebastian Reichel
  1 sibling, 0 replies; 72+ messages in thread
From: Sebastian Reichel @ 2020-12-14 15:37 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Laurent Pinchart, Nikhil Devshatwar, dri-devel, linux-omap,
	Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg

[-- Attachment #1: Type: text/plain, Size: 8729 bytes --]

Hi,

On Tue, Dec 08, 2020 at 02:28:37PM +0200, Tomi Valkeinen wrote:
> To start fixing the issues related to channels and vcs described in the
> previous commit, pass vc to various functions which will need it do
> properly handle different DSI channels and VCs.
> 
> No functional changes.
> 
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> ---

Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>

-- Sebastian

>  drivers/gpu/drm/omapdrm/dss/dsi.c | 54 ++++++++++++++++---------------
>  1 file changed, 28 insertions(+), 26 deletions(-)
> 
> diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
> index 273159e8f992..8d8412199693 100644
> --- a/drivers/gpu/drm/omapdrm/dss/dsi.c
> +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
> @@ -214,9 +214,9 @@ static void dsi_set_ulps_auto(struct dsi_data *dsi, bool enable);
>  static int dsi_display_init_dispc(struct dsi_data *dsi);
>  static void dsi_display_uninit_dispc(struct dsi_data *dsi);
>  
> -static int dsi_vc_send_null(struct dsi_data *dsi, int vc);
> +static int dsi_vc_send_null(struct dsi_data *dsi, int vc, int channel);
>  
> -static ssize_t _omap_dsi_host_transfer(struct dsi_data *dsi,
> +static ssize_t _omap_dsi_host_transfer(struct dsi_data *dsi, int vc,
>  				       const struct mipi_dsi_msg *msg);
>  
>  static void dsi_display_disable(struct omap_dss_device *dssdev);
> @@ -2455,7 +2455,7 @@ static void dsi_vc_enable_hs(struct omap_dss_device *dssdev, int vc,
>  
>  	/* start the DDR clock by sending a NULL packet */
>  	if (dsi->vm_timings.ddr_clk_always_on && enable)
> -		dsi_vc_send_null(dsi, vc);
> +		dsi_vc_send_null(dsi, vc, dsi->dsidev->channel);
>  
>  	dsi->in_lp_mode = !enable;
>  }
> @@ -2605,7 +2605,8 @@ static int dsi_vc_send_bta_sync(struct omap_dss_device *dssdev, int vc)
>  }
>  
>  static inline void dsi_vc_write_long_header(struct dsi_data *dsi, int vc,
> -					    u8 data_type, u16 len, u8 ecc)
> +					    int channel, u8 data_type, u16 len,
> +					    u8 ecc)
>  {
>  	u32 val;
>  	u8 data_id;
> @@ -2633,7 +2634,7 @@ static inline void dsi_vc_write_long_payload(struct dsi_data *dsi, int vc,
>  	dsi_write_reg(dsi, DSI_VC_LONG_PACKET_PAYLOAD(vc), val);
>  }
>  
> -static int dsi_vc_send_long(struct dsi_data *dsi,
> +static int dsi_vc_send_long(struct dsi_data *dsi, int vc,
>  			    const struct mipi_dsi_msg *msg)
>  {
>  	/*u32 val; */
> @@ -2653,7 +2654,7 @@ static int dsi_vc_send_long(struct dsi_data *dsi,
>  
>  	dsi_vc_config_source(dsi, msg->channel, DSI_VC_SOURCE_L4);
>  
> -	dsi_vc_write_long_header(dsi, msg->channel, msg->type, msg->tx_len, 0);
> +	dsi_vc_write_long_header(dsi, vc, msg->channel, msg->type, msg->tx_len, 0);
>  
>  	p = msg->tx_buf;
>  	for (i = 0; i < msg->tx_len >> 2; i++) {
> @@ -2696,7 +2697,7 @@ static int dsi_vc_send_long(struct dsi_data *dsi,
>  	return r;
>  }
>  
> -static int dsi_vc_send_short(struct dsi_data *dsi,
> +static int dsi_vc_send_short(struct dsi_data *dsi, int vc,
>  			     const struct mipi_dsi_msg *msg)
>  {
>  	struct mipi_dsi_packet pkt;
> @@ -2727,26 +2728,26 @@ static int dsi_vc_send_short(struct dsi_data *dsi,
>  	return 0;
>  }
>  
> -static int dsi_vc_send_null(struct dsi_data *dsi, int vc)
> +static int dsi_vc_send_null(struct dsi_data *dsi, int vc, int channel)
>  {
>  	const struct mipi_dsi_msg msg = {
>  		.channel = vc,
>  		.type = MIPI_DSI_NULL_PACKET,
>  	};
>  
> -	return dsi_vc_send_long(dsi, &msg);
> +	return dsi_vc_send_long(dsi, vc, &msg);
>  }
>  
> -static int dsi_vc_write_common(struct omap_dss_device *dssdev,
> +static int dsi_vc_write_common(struct omap_dss_device *dssdev, int vc,
>  			       const struct mipi_dsi_msg *msg)
>  {
>  	struct dsi_data *dsi = to_dsi_data(dssdev);
>  	int r;
>  
>  	if (mipi_dsi_packet_format_is_short(msg->type))
> -		r = dsi_vc_send_short(dsi, msg);
> +		r = dsi_vc_send_short(dsi, vc, msg);
>  	else
> -		r = dsi_vc_send_long(dsi, msg);
> +		r = dsi_vc_send_long(dsi, vc, msg);
>  
>  	if (r < 0)
>  		return r;
> @@ -2882,7 +2883,7 @@ static int dsi_vc_read_rx_fifo(struct dsi_data *dsi, int vc, u8 *buf,
>  	return r;
>  }
>  
> -static int dsi_vc_dcs_read(struct omap_dss_device *dssdev,
> +static int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int vc,
>  			   const struct mipi_dsi_msg *msg)
>  {
>  	struct dsi_data *dsi = to_dsi_data(dssdev);
> @@ -2893,7 +2894,7 @@ static int dsi_vc_dcs_read(struct omap_dss_device *dssdev,
>  	if (dsi->debug_read)
>  		DSSDBG("%s(ch %d, cmd %x)\n", __func__, channel, cmd);
>  
> -	r = dsi_vc_send_short(dsi, msg);
> +	r = dsi_vc_send_short(dsi, vc, msg);
>  	if (r)
>  		goto err;
>  
> @@ -2917,13 +2918,13 @@ static int dsi_vc_dcs_read(struct omap_dss_device *dssdev,
>  	return r;
>  }
>  
> -static int dsi_vc_generic_read(struct omap_dss_device *dssdev,
> +static int dsi_vc_generic_read(struct omap_dss_device *dssdev, int vc,
>  			       const struct mipi_dsi_msg *msg)
>  {
>  	struct dsi_data *dsi = to_dsi_data(dssdev);
>  	int r;
>  
> -	r = dsi_vc_send_short(dsi, msg);
> +	r = dsi_vc_send_short(dsi, vc, msg);
>  	if (r)
>  		goto err;
>  
> @@ -3672,7 +3673,7 @@ static void dsi_enable_video_output(struct omap_dss_device *dssdev, int vc)
>  
>  		word_count = DIV_ROUND_UP(dsi->vm.hactive * bpp, 8);
>  
> -		dsi_vc_write_long_header(dsi, vc, data_type,
> +		dsi_vc_write_long_header(dsi, vc, dsi->dsidev->channel, data_type,
>  				word_count, 0);
>  
>  		dsi_vc_enable(dsi, vc, true);
> @@ -3770,7 +3771,7 @@ static void dsi_update_screen_dispc(struct dsi_data *dsi)
>  	l = FLD_VAL(total_len, 23, 0); /* TE_SIZE */
>  	dsi_write_reg(dsi, DSI_VC_TE(vc), l);
>  
> -	dsi_vc_write_long_header(dsi, vc, MIPI_DSI_DCS_LONG_WRITE,
> +	dsi_vc_write_long_header(dsi, vc, dsi->dsidev->channel, MIPI_DSI_DCS_LONG_WRITE,
>  		packet_len, 0);
>  
>  	if (dsi->te_enabled)
> @@ -3882,7 +3883,7 @@ static int _dsi_update(struct dsi_data *dsi)
>  	return 0;
>  }
>  
> -static int _dsi_send_nop(struct dsi_data *dsi, int channel)
> +static int _dsi_send_nop(struct dsi_data *dsi, int vc, int channel)
>  {
>  	const u8 payload[] = { MIPI_DCS_NOP };
>  	const struct mipi_dsi_msg msg = {
> @@ -3894,7 +3895,7 @@ static int _dsi_send_nop(struct dsi_data *dsi, int channel)
>  
>  	WARN_ON(!dsi_bus_is_locked(dsi));
>  
> -	return _omap_dsi_host_transfer(dsi, &msg);
> +	return _omap_dsi_host_transfer(dsi, vc, &msg);
>  }
>  
>  static int dsi_update_channel(struct omap_dss_device *dssdev, int vc)
> @@ -3923,7 +3924,7 @@ static int dsi_update_channel(struct omap_dss_device *dssdev, int vc)
>  	 * updates stop working. This is probably related to DSI spec stating
>  	 * that the DSI host should transition to LP at least once per frame.
>  	 */
> -	r = _dsi_send_nop(dsi, vc);
> +	r = _dsi_send_nop(dsi, vc, dsi->dsidev->channel);
>  	if (r < 0) {
>  		DSSWARN("failed to send nop between frames: %d\n", r);
>  		goto err;
> @@ -4885,7 +4886,7 @@ static enum omap_channel dsi_get_dispc_channel(struct dsi_data *dsi)
>  	}
>  }
>  
> -static ssize_t _omap_dsi_host_transfer(struct dsi_data *dsi,
> +static ssize_t _omap_dsi_host_transfer(struct dsi_data *dsi, int vc,
>  				       const struct mipi_dsi_msg *msg)
>  {
>  	struct omap_dss_device *dssdev = &dsi->output;
> @@ -4905,15 +4906,15 @@ static ssize_t _omap_dsi_host_transfer(struct dsi_data *dsi,
>  	case MIPI_DSI_DCS_LONG_WRITE:
>  	case MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE:
>  	case MIPI_DSI_NULL_PACKET:
> -		r = dsi_vc_write_common(dssdev, msg);
> +		r = dsi_vc_write_common(dssdev, vc, msg);
>  		break;
>  	case MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM:
>  	case MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM:
>  	case MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM:
> -		r = dsi_vc_generic_read(dssdev, msg);
> +		r = dsi_vc_generic_read(dssdev, vc, msg);
>  		break;
>  	case MIPI_DSI_DCS_READ:
> -		r = dsi_vc_dcs_read(dssdev, msg);
> +		r = dsi_vc_dcs_read(dssdev, vc, msg);
>  		break;
>  	default:
>  		r = -EINVAL;
> @@ -4941,12 +4942,13 @@ static ssize_t omap_dsi_host_transfer(struct mipi_dsi_host *host,
>  {
>  	struct dsi_data *dsi = host_to_omap(host);
>  	int r;
> +	int vc = VC_DEFAULT;
>  
>  	dsi_bus_lock(dsi);
>  
>  	if (dsi->video_enabled) {
>  		dsi_set_ulps_auto(dsi, false);
> -		r = _omap_dsi_host_transfer(dsi, msg);
> +		r = _omap_dsi_host_transfer(dsi, vc, msg);
>  		dsi_set_ulps_auto(dsi, true);
>  	} else {
>  		r = -EIO;
> -- 
> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
> Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v5 12/29] drm/omap: dsi: untangle vc & channel
  2020-12-08 15:41   ` Laurent Pinchart
@ 2020-12-14 15:47     ` Sebastian Reichel
  0 siblings, 0 replies; 72+ messages in thread
From: Sebastian Reichel @ 2020-12-14 15:47 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Tomi Valkeinen, Nikhil Devshatwar, dri-devel, linux-omap,
	Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg

[-- Attachment #1: Type: text/plain, Size: 7226 bytes --]

On Tue, Dec 08, 2020 at 05:41:23PM +0200, Laurent Pinchart wrote:
> Hi Tomi,
> 
> Thank you for the patch.
> 
> On Tue, Dec 08, 2020 at 02:28:38PM +0200, Tomi Valkeinen wrote:
> > DSI virtual channel and hardware VC blocks have gotten tangled as
> > described in the previous commits. This has not caused any issues, as
> > the value for both is 0, so it happens to work.
> > 
> > To fix the issue, change the code to use the correct one of the two.
> > 
> > Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> > ---
> >  drivers/gpu/drm/omapdrm/dss/dsi.c | 43 +++++++++++++++----------------
> >  1 file changed, 21 insertions(+), 22 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
> > index 8d8412199693..a1f3623f45b1 100644
> > --- a/drivers/gpu/drm/omapdrm/dss/dsi.c
> > +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
> > @@ -2613,7 +2613,7 @@ static inline void dsi_vc_write_long_header(struct dsi_data *dsi, int vc,
> >  
> >  	WARN_ON(!dsi_bus_is_locked(dsi));
> >  
> > -	data_id = data_type | vc << 6;
> > +	data_id = data_type | channel << 6;
> >  
> >  	val = FLD_VAL(data_id, 7, 0) | FLD_VAL(len, 23, 8) |
> >  		FLD_VAL(ecc, 31, 24);
> > @@ -2647,12 +2647,12 @@ static int dsi_vc_send_long(struct dsi_data *dsi, int vc,
> >  		DSSDBG("dsi_vc_send_long, %d bytes\n", msg->tx_len);
> >  
> >  	/* len + header */
> > -	if (dsi->vc[msg->channel].tx_fifo_size * 32 * 4 < msg->tx_len + 4) {
> > +	if (dsi->vc[vc].tx_fifo_size * 32 * 4 < msg->tx_len + 4) {
> >  		DSSERR("unable to send long packet: packet too long.\n");
> >  		return -EINVAL;
> >  	}
> >  
> > -	dsi_vc_config_source(dsi, msg->channel, DSI_VC_SOURCE_L4);
> > +	dsi_vc_config_source(dsi, vc, DSI_VC_SOURCE_L4);
> >  
> >  	dsi_vc_write_long_header(dsi, vc, msg->channel, msg->type, msg->tx_len, 0);
> >  
> > @@ -2666,7 +2666,7 @@ static int dsi_vc_send_long(struct dsi_data *dsi, int vc,
> >  		b3 = *p++;
> >  		b4 = *p++;
> >  
> > -		dsi_vc_write_long_payload(dsi, msg->channel, b1, b2, b3, b4);
> > +		dsi_vc_write_long_payload(dsi, vc, b1, b2, b3, b4);
> >  	}
> >  
> >  	i = msg->tx_len % 4;
> > @@ -2691,7 +2691,7 @@ static int dsi_vc_send_long(struct dsi_data *dsi, int vc,
> >  			break;
> >  		}
> >  
> > -		dsi_vc_write_long_payload(dsi, msg->channel, b1, b2, b3, 0);
> > +		dsi_vc_write_long_payload(dsi, vc, b1, b2, b3, 0);
> >  	}
> >  
> >  	return r;
> > @@ -2711,11 +2711,11 @@ static int dsi_vc_send_short(struct dsi_data *dsi, int vc,
> >  
> >  	if (dsi->debug_write)
> >  		DSSDBG("dsi_vc_send_short(ch%d, dt %#x, b1 %#x, b2 %#x)\n",
> > -		       msg->channel, msg->type, pkt.header[1], pkt.header[2]);
> > +		       vc, msg->type, pkt.header[1], pkt.header[2]);

There is another "ch%d" filled with vc. With this and Laurent
findings fixed:

Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>

-- Sebastian

> >  
> > -	dsi_vc_config_source(dsi, msg->channel, DSI_VC_SOURCE_L4);
> > +	dsi_vc_config_source(dsi, vc, DSI_VC_SOURCE_L4);
> >  
> > -	if (FLD_GET(dsi_read_reg(dsi, DSI_VC_CTRL(msg->channel)), 16, 16)) {
> > +	if (FLD_GET(dsi_read_reg(dsi, DSI_VC_CTRL(vc)), 16, 16)) {
> >  		DSSERR("ERROR FIFO FULL, aborting transfer\n");
> >  		return -EINVAL;
> >  	}
> > @@ -2723,7 +2723,7 @@ static int dsi_vc_send_short(struct dsi_data *dsi, int vc,
> >  	r = pkt.header[3] << 24 | pkt.header[2] << 16 | pkt.header[1] << 8 |
> >  	    pkt.header[0];
> >  
> > -	dsi_write_reg(dsi, DSI_VC_SHORT_PACKET_HEADER(msg->channel), r);
> > +	dsi_write_reg(dsi, DSI_VC_SHORT_PACKET_HEADER(vc), r);
> >  
> >  	return 0;
> >  }
> > @@ -2731,7 +2731,7 @@ static int dsi_vc_send_short(struct dsi_data *dsi, int vc,
> >  static int dsi_vc_send_null(struct dsi_data *dsi, int vc, int channel)
> >  {
> >  	const struct mipi_dsi_msg msg = {
> > -		.channel = vc,
> > +		.channel = channel,
> >  		.type = MIPI_DSI_NULL_PACKET,
> >  	};
> >  
> > @@ -2759,16 +2759,16 @@ static int dsi_vc_write_common(struct omap_dss_device *dssdev, int vc,
> >  	 * In that case we can return early.
> >  	 */
> >  
> > -	r = dsi_vc_send_bta_sync(dssdev, msg->channel);
> > +	r = dsi_vc_send_bta_sync(dssdev, vc);
> >  	if (r) {
> >  		DSSERR("bta sync failed\n");
> >  		return r;
> >  	}
> >  
> >  	/* RX_FIFO_NOT_EMPTY */
> > -	if (REG_GET(dsi, DSI_VC_CTRL(msg->channel), 20, 20)) {
> > +	if (REG_GET(dsi, DSI_VC_CTRL(vc), 20, 20)) {
> >  		DSSERR("rx fifo not empty after write, dumping data:\n");
> > -		dsi_vc_flush_receive_data(dsi, msg->channel);
> > +		dsi_vc_flush_receive_data(dsi, vc);
> >  		return -EIO;
> >  	}
> >  
> > @@ -2888,21 +2888,20 @@ static int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int vc,
> >  {
> >  	struct dsi_data *dsi = to_dsi_data(dssdev);
> >  	u8 cmd = ((u8 *)msg->tx_buf)[0];
> > -	u8 channel = msg->channel;
> >  	int r;
> >  
> >  	if (dsi->debug_read)
> > -		DSSDBG("%s(ch %d, cmd %x)\n", __func__, channel, cmd);
> > +		DSSDBG("%s(ch %d, cmd %x)\n", __func__, vc, cmd);
> 
> How about also renaming ch to vc in the message ?
> 
> >  
> >  	r = dsi_vc_send_short(dsi, vc, msg);
> >  	if (r)
> >  		goto err;
> >  
> > -	r = dsi_vc_send_bta_sync(dssdev, channel);
> > +	r = dsi_vc_send_bta_sync(dssdev, vc);
> >  	if (r)
> >  		goto err;
> >  
> > -	r = dsi_vc_read_rx_fifo(dsi, channel, msg->rx_buf, msg->rx_len,
> > +	r = dsi_vc_read_rx_fifo(dsi, vc, msg->rx_buf, msg->rx_len,
> >  		DSS_DSI_CONTENT_DCS);
> >  	if (r < 0)
> >  		goto err;
> > @@ -2914,7 +2913,7 @@ static int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int vc,
> >  
> >  	return 0;
> >  err:
> > -	DSSERR("%s(ch %d, cmd 0x%02x) failed\n", __func__,  msg->channel, cmd);
> > +	DSSERR("%s(ch %d, cmd 0x%02x) failed\n", __func__,  vc, cmd);
> 
> Same here.
> 
> >  	return r;
> >  }
> >  
> > @@ -2928,11 +2927,11 @@ static int dsi_vc_generic_read(struct omap_dss_device *dssdev, int vc,
> >  	if (r)
> >  		goto err;
> >  
> > -	r = dsi_vc_send_bta_sync(dssdev, msg->channel);
> > +	r = dsi_vc_send_bta_sync(dssdev, vc);
> >  	if (r)
> >  		goto err;
> >  
> > -	r = dsi_vc_read_rx_fifo(dsi, msg->channel, msg->rx_buf, msg->rx_len,
> > +	r = dsi_vc_read_rx_fifo(dsi, vc, msg->rx_buf, msg->rx_len,
> >  		DSS_DSI_CONTENT_GENERIC);
> >  	if (r < 0)
> >  		goto err;
> > @@ -2944,7 +2943,7 @@ static int dsi_vc_generic_read(struct omap_dss_device *dssdev, int vc,
> >  
> >  	return 0;
> >  err:
> > -	DSSERR("%s(ch %d, reqlen %d) failed\n", __func__,  msg->channel, msg->tx_len);
> > +	DSSERR("%s(ch %d, reqlen %d) failed\n", __func__,  vc, msg->tx_len);
> 
> And here.
> 
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> 
> >  	return r;
> >  }
> >  
> > @@ -4893,7 +4892,7 @@ static ssize_t _omap_dsi_host_transfer(struct dsi_data *dsi, int vc,
> >  	int r;
> >  
> >  	if (!!(msg->flags & MIPI_DSI_MSG_USE_LPM) != dsi->in_lp_mode)
> > -		dsi_vc_enable_hs(dssdev, msg->channel,
> > +		dsi_vc_enable_hs(dssdev, vc,
> >  				 !(msg->flags & MIPI_DSI_MSG_USE_LPM));
> >  
> >  	switch (msg->type) {
> 
> -- 
> Regards,
> 
> Laurent Pinchart

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v5 13/29] drm/omap: dsi: skip dsi_vc_enable_hs when already in correct mode
  2020-12-08 12:28 ` [PATCH v5 13/29] drm/omap: dsi: skip dsi_vc_enable_hs when already in correct mode Tomi Valkeinen
@ 2020-12-14 15:50   ` Sebastian Reichel
  0 siblings, 0 replies; 72+ messages in thread
From: Sebastian Reichel @ 2020-12-14 15:50 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Laurent Pinchart, Nikhil Devshatwar, dri-devel, linux-omap,
	Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg

[-- Attachment #1: Type: text/plain, Size: 2267 bytes --]

Hi,

On Tue, Dec 08, 2020 at 02:28:39PM +0200, Tomi Valkeinen wrote:
> Simplify and optimize dsi_vc_enable_hs() so that it can be called
> without checking the current HS/LP mode. Make dsi_vc_enable_hs() return
> if the VC is already in the correct mode.
> 
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---

Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>

-- Sebastian

>  drivers/gpu/drm/omapdrm/dss/dsi.c | 10 ++++------
>  1 file changed, 4 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
> index a1f3623f45b1..544f5f1eed91 100644
> --- a/drivers/gpu/drm/omapdrm/dss/dsi.c
> +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
> @@ -341,7 +341,6 @@ struct dsi_data {
>  	int irq;
>  
>  	bool is_enabled;
> -	bool in_lp_mode;
>  
>  	struct clk *dss_clk;
>  	struct regmap *syscon;
> @@ -2441,6 +2440,9 @@ static void dsi_vc_enable_hs(struct omap_dss_device *dssdev, int vc,
>  
>  	DSSDBG("dsi_vc_enable_hs(%d, %d)\n", vc, enable);
>  
> +	if (REG_GET(dsi, DSI_VC_CTRL(vc), 9, 9) == enable)
> +		return;
> +
>  	WARN_ON(!dsi_bus_is_locked(dsi));
>  
>  	dsi_vc_enable(dsi, vc, 0);
> @@ -2456,8 +2458,6 @@ static void dsi_vc_enable_hs(struct omap_dss_device *dssdev, int vc,
>  	/* start the DDR clock by sending a NULL packet */
>  	if (dsi->vm_timings.ddr_clk_always_on && enable)
>  		dsi_vc_send_null(dsi, vc, dsi->dsidev->channel);
> -
> -	dsi->in_lp_mode = !enable;
>  }
>  
>  static void dsi_vc_flush_long_data(struct dsi_data *dsi, int vc)
> @@ -4891,9 +4891,7 @@ static ssize_t _omap_dsi_host_transfer(struct dsi_data *dsi, int vc,
>  	struct omap_dss_device *dssdev = &dsi->output;
>  	int r;
>  
> -	if (!!(msg->flags & MIPI_DSI_MSG_USE_LPM) != dsi->in_lp_mode)
> -		dsi_vc_enable_hs(dssdev, vc,
> -				 !(msg->flags & MIPI_DSI_MSG_USE_LPM));
> +	dsi_vc_enable_hs(dssdev, vc, !(msg->flags & MIPI_DSI_MSG_USE_LPM));
>  
>  	switch (msg->type) {
>  	case MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM:
> -- 
> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
> Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v5 14/29] drm/omap: dsi: enable HS before sending the frame
  2020-12-08 12:28 ` [PATCH v5 14/29] drm/omap: dsi: enable HS before sending the frame Tomi Valkeinen
  2020-12-08 15:42   ` Laurent Pinchart
@ 2020-12-14 15:51   ` Sebastian Reichel
  1 sibling, 0 replies; 72+ messages in thread
From: Sebastian Reichel @ 2020-12-14 15:51 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Laurent Pinchart, Nikhil Devshatwar, dri-devel, linux-omap,
	Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg

[-- Attachment #1: Type: text/plain, Size: 1350 bytes --]

Hi,

On Tue, Dec 08, 2020 at 02:28:40PM +0200, Tomi Valkeinen wrote:
> We currently use a single VC for sending commands and pixel data. The
> LP/HS mode for pixel data is correctly set to HS by accident, as we have
> set the VC to HS already earlier.
> 
> However, if we use a different VC for video data, the VC is in LP mode.
> Fix this by always enabling HS mode before starting a frame update.
> 
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> ---

Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>

-- Sebastian

>  drivers/gpu/drm/omapdrm/dss/dsi.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
> index 544f5f1eed91..9d210a020916 100644
> --- a/drivers/gpu/drm/omapdrm/dss/dsi.c
> +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
> @@ -3918,6 +3918,8 @@ static int dsi_update_channel(struct omap_dss_device *dssdev, int vc)
>  
>  	dsi_set_ulps_auto(dsi, false);
>  
> +	dsi_vc_enable_hs(dssdev, vc, true);
> +
>  	/*
>  	 * Send NOP between the frames. If we don't send something here, the
>  	 * updates stop working. This is probably related to DSI spec stating
> -- 
> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
> Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v5 15/29] drm/omap: dsi: use separate VCs for cmd and video
  2020-12-08 12:28 ` [PATCH v5 15/29] drm/omap: dsi: use separate VCs for cmd and video Tomi Valkeinen
@ 2020-12-14 15:54   ` Sebastian Reichel
  0 siblings, 0 replies; 72+ messages in thread
From: Sebastian Reichel @ 2020-12-14 15:54 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Laurent Pinchart, Nikhil Devshatwar, dri-devel, linux-omap,
	Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg

[-- Attachment #1: Type: text/plain, Size: 2687 bytes --]

Hi,

On Tue, Dec 08, 2020 at 02:28:41PM +0200, Tomi Valkeinen wrote:
> For command mode panels we can use a single VC for sending command and
> video data, even if we have to change the data source for that VC when
> going from command to video or vice versa.
> 
> However, with video mode panels we want to keep the pixel data VC
> enabled, and use another VC for command data, and the commands will get
> interleaved into the pixel data.
> 
> This patch makes the driver use VC0 for commands and VC1 for video.
> 
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---

Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>

-- Sebastian

>  drivers/gpu/drm/omapdrm/dss/dsi.c | 12 +++++++-----
>  1 file changed, 7 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
> index 9d210a020916..0795efdd8902 100644
> --- a/drivers/gpu/drm/omapdrm/dss/dsi.c
> +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
> @@ -452,7 +452,9 @@ static bool dsi_perf;
>  module_param(dsi_perf, bool, 0644);
>  #endif
>  
> -#define VC_DEFAULT 0
> +/* Note: for some reason video mode seems to work only if VC_VIDEO is 0 */
> +#define VC_VIDEO	0
> +#define VC_CMD		1
>  
>  #define drm_bridge_to_dsi(bridge) \
>  	container_of(bridge, struct dsi_data, bridge)
> @@ -3723,7 +3725,7 @@ static void dsi_disable_video_outputs(struct omap_dss_device *dssdev)
>  	dsi_bus_lock(dsi);
>  	dsi->video_enabled = false;
>  
> -	dsi_disable_video_output(dssdev, VC_DEFAULT);
> +	dsi_disable_video_output(dssdev, VC_VIDEO);
>  
>  	dsi_display_disable(dssdev);
>  
> @@ -3951,7 +3953,7 @@ static int dsi_update_channel(struct omap_dss_device *dssdev, int vc)
>  
>  static int dsi_update_all(struct omap_dss_device *dssdev)
>  {
> -	return dsi_update_channel(dssdev, VC_DEFAULT);
> +	return dsi_update_channel(dssdev, VC_VIDEO);
>  }
>  
>  /* Display funcs */
> @@ -4184,7 +4186,7 @@ static void dsi_enable_video_outputs(struct omap_dss_device *dssdev)
>  
>  	dsi_display_enable(dssdev);
>  
> -	dsi_enable_video_output(dssdev, VC_DEFAULT);
> +	dsi_enable_video_output(dssdev, VC_VIDEO);
>  
>  	dsi->video_enabled = true;
>  
> @@ -4941,7 +4943,7 @@ static ssize_t omap_dsi_host_transfer(struct mipi_dsi_host *host,
>  {
>  	struct dsi_data *dsi = host_to_omap(host);
>  	int r;
> -	int vc = VC_DEFAULT;
> +	int vc = VC_CMD;
>  
>  	dsi_bus_lock(dsi);
>  
> -- 
> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
> Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v5 16/29] drm/panel: panel-dsi-cm: remove extra 'if'
  2020-12-08 12:28 ` [PATCH v5 16/29] drm/panel: panel-dsi-cm: remove extra 'if' Tomi Valkeinen
  2020-12-08 15:42   ` Laurent Pinchart
@ 2020-12-14 15:55   ` Sebastian Reichel
  1 sibling, 0 replies; 72+ messages in thread
From: Sebastian Reichel @ 2020-12-14 15:55 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Laurent Pinchart, Nikhil Devshatwar, dri-devel, linux-omap,
	Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg

[-- Attachment #1: Type: text/plain, Size: 1297 bytes --]

Hi,

On Tue, Dec 08, 2020 at 02:28:42PM +0200, Tomi Valkeinen wrote:
> We have a useless 'if' in the dsicm_bl_update_status(), a left over from
> the conversion to DRM model. Drop the if.
> 
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> Reviewed-by: Sam Ravnborg <sam@ravnborg.org>
> ---

Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>

-- Sebastian

>  drivers/gpu/drm/panel/panel-dsi-cm.c | 8 +++-----
>  1 file changed, 3 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/panel/panel-dsi-cm.c b/drivers/gpu/drm/panel/panel-dsi-cm.c
> index 556f9a2c5c0c..fa564aad7f25 100644
> --- a/drivers/gpu/drm/panel/panel-dsi-cm.c
> +++ b/drivers/gpu/drm/panel/panel-dsi-cm.c
> @@ -202,11 +202,9 @@ static int dsicm_bl_update_status(struct backlight_device *dev)
>  
>  	mutex_lock(&ddata->lock);
>  
> -	if (ddata->enabled) {
> -		if (!r)
> -			r = dsicm_dcs_write_1(
> -				ddata, MIPI_DCS_SET_DISPLAY_BRIGHTNESS, level);
> -	}
> +	if (ddata->enabled)
> +		r = dsicm_dcs_write_1(ddata, MIPI_DCS_SET_DISPLAY_BRIGHTNESS,
> +				      level);
>  
>  	mutex_unlock(&ddata->lock);
>  
> -- 
> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
> Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v5 17/29] drm/panel: panel-dsi-cm: add panel database to driver
  2020-12-08 12:28 ` [PATCH v5 17/29] drm/panel: panel-dsi-cm: add panel database to driver Tomi Valkeinen
@ 2020-12-14 16:04   ` Sebastian Reichel
  0 siblings, 0 replies; 72+ messages in thread
From: Sebastian Reichel @ 2020-12-14 16:04 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Laurent Pinchart, Nikhil Devshatwar, dri-devel, linux-omap,
	Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg

[-- Attachment #1: Type: text/plain, Size: 6772 bytes --]

On Tue, Dec 08, 2020 at 02:28:43PM +0200, Tomi Valkeinen wrote:
> Add a panel database to the driver instead of reading propertes from DT
> data. This is similar to panel-simple, and I believe it's more future
> safe way to handle the panels.
> 
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> Reviewed-by: Sam Ravnborg <sam@ravnborg.org>
> ---
>  drivers/gpu/drm/panel/panel-dsi-cm.c | 107 +++++++++++++++++----------
>  1 file changed, 69 insertions(+), 38 deletions(-)
> 
> diff --git a/drivers/gpu/drm/panel/panel-dsi-cm.c b/drivers/gpu/drm/panel/panel-dsi-cm.c
> index fa564aad7f25..3fb5b2856283 100644
> --- a/drivers/gpu/drm/panel/panel-dsi-cm.c
> +++ b/drivers/gpu/drm/panel/panel-dsi-cm.c
> @@ -21,10 +21,7 @@
>  #include <drm/drm_modes.h>
>  #include <drm/drm_panel.h>
>  
> -#include <video/display_timing.h>
>  #include <video/mipi_display.h>
> -#include <video/of_display_timing.h>
> -#include <video/videomode.h>
>  
>  #define DCS_GET_ID1		0xda
>  #define DCS_GET_ID2		0xdb
> @@ -32,6 +29,18 @@
>  
>  #define DCS_REGULATOR_SUPPLY_NUM 2
>  
> +static const struct of_device_id dsicm_of_match[];
> +
> +struct dsic_panel_data {
> +	u32 xres;
> +	u32 yres;
> +	u32 refresh;
> +	u32 width_mm;
> +	u32 height_mm;
> +	u32 max_hs_rate;
> +	u32 max_lp_rate;
> +};
> +
>  struct panel_drv_data {
>  	struct mipi_dsi_device *dsi;
>  	struct drm_panel panel;
> @@ -47,16 +56,14 @@ struct panel_drv_data {
>  					 */
>  	unsigned long	hw_guard_wait;	/* max guard time in jiffies */
>  
> -	/* panel HW configuration from DT or platform data */
> +	const struct dsic_panel_data *panel_data;
> +
>  	struct gpio_desc *reset_gpio;
>  
>  	struct regulator_bulk_data supplies[DCS_REGULATOR_SUPPLY_NUM];
>  
>  	bool use_dsi_backlight;
>  
> -	int width_mm;
> -	int height_mm;
> -
>  	/* runtime variables */
>  	bool enabled;
>  
> @@ -450,11 +457,8 @@ static int dsicm_get_modes(struct drm_panel *panel,
>  		return -ENOMEM;
>  	}
>  
> -	drm_mode_set_name(mode);
> -	mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
> -
> -	connector->display_info.width_mm = ddata->width_mm;
> -	connector->display_info.height_mm = ddata->height_mm;
> +	connector->display_info.width_mm = ddata->panel_data->width_mm;
> +	connector->display_info.height_mm = ddata->panel_data->height_mm;
>  
>  	drm_mode_probed_add(connector, mode);
>  
> @@ -471,15 +475,10 @@ static const struct drm_panel_funcs dsicm_panel_funcs = {
>  
>  static int dsicm_probe_of(struct mipi_dsi_device *dsi)
>  {
> -	struct device_node *node = dsi->dev.of_node;
>  	struct backlight_device *backlight;
>  	struct panel_drv_data *ddata = mipi_dsi_get_drvdata(dsi);
> -	struct display_timing timing;
> -	struct videomode vm = {
> -		.hactive = 864,
> -		.vactive = 480,
> -	};
>  	int err;
> +	struct drm_display_mode *mode = &ddata->mode;
>  
>  	ddata->reset_gpio = devm_gpiod_get(&dsi->dev, "reset", GPIOD_OUT_LOW);
>  	if (IS_ERR(ddata->reset_gpio)) {
> @@ -488,23 +487,16 @@ static int dsicm_probe_of(struct mipi_dsi_device *dsi)
>  		return err;
>  	}
>  
> -	err = of_get_display_timing(node, "panel-timing", &timing);
> -	if (!err) {
> -		videomode_from_timing(&timing, &vm);
> -	} else {
> -		dev_warn(&dsi->dev,
> -			 "failed to get video timing, using defaults\n");
> -	}
> -
> -	if (!vm.pixelclock)
> -		vm.pixelclock = vm.hactive * vm.vactive * 60;
> -	drm_display_mode_from_videomode(&vm, &ddata->mode);
> -
> -	ddata->width_mm = 0;
> -	of_property_read_u32(node, "width-mm", &ddata->width_mm);
> -
> -	ddata->height_mm = 0;
> -	of_property_read_u32(node, "height-mm", &ddata->height_mm);
> +	mode->hdisplay = mode->hsync_start = mode->hsync_end = mode->htotal =
> +		ddata->panel_data->xres;
> +	mode->vdisplay = mode->vsync_start = mode->vsync_end = mode->vtotal =
> +		ddata->panel_data->yres;
> +	mode->clock = ddata->panel_data->xres * ddata->panel_data->yres *
> +		ddata->panel_data->refresh / 1000;
> +	mode->width_mm = ddata->panel_data->width_mm;
> +	mode->height_mm = ddata->panel_data->height_mm;
> +	mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
> +	drm_mode_set_name(mode);
>  
>  	ddata->supplies[0].supply = "vpnl";
>  	ddata->supplies[1].supply = "vddi";
> @@ -531,6 +523,7 @@ static int dsicm_probe(struct mipi_dsi_device *dsi)
>  	struct panel_drv_data *ddata;
>  	struct backlight_device *bldev = NULL;
>  	struct device *dev = &dsi->dev;
> +	const struct of_device_id *id;
>  	int r;
>  
>  	dev_dbg(dev, "probe\n");
> @@ -542,6 +535,12 @@ static int dsicm_probe(struct mipi_dsi_device *dsi)
>  	mipi_dsi_set_drvdata(dsi, ddata);
>  	ddata->dsi = dsi;
>  
> +	id = of_match_node(dsicm_of_match, dev->of_node);
> +	if (!id)
> +		return -ENODEV;
> +
> +	ddata->panel_data = id->data;

ddata->panel_data = of_device_get_match_data(dev);
if (!ddata->panel_data)
    return -ENODEV;

Otherwise looks good to me:

Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>

-- Sebastian

>  	r = dsicm_probe_of(dsi);
>  	if (r)
>  		return r;
> @@ -578,8 +577,8 @@ static int dsicm_probe(struct mipi_dsi_device *dsi)
>  	dsi->format = MIPI_DSI_FMT_RGB888;
>  	dsi->mode_flags = MIPI_DSI_CLOCK_NON_CONTINUOUS |
>  			  MIPI_DSI_MODE_EOT_PACKET;
> -	dsi->hs_rate = 300000000;
> -	dsi->lp_rate = 10000000;
> +	dsi->hs_rate = ddata->panel_data->max_hs_rate;
> +	dsi->lp_rate = ddata->panel_data->max_lp_rate;
>  
>  	drm_panel_add(&ddata->panel);
>  
> @@ -617,8 +616,40 @@ static int dsicm_remove(struct mipi_dsi_device *dsi)
>  	return 0;
>  }
>  
> +static const struct dsic_panel_data taal_data = {
> +	.xres = 864,
> +	.yres = 480,
> +	.refresh = 60,
> +	.width_mm = 0,
> +	.height_mm = 0,
> +	.max_hs_rate = 300000000,
> +	.max_lp_rate = 10000000,
> +};
> +
> +static const struct dsic_panel_data himalaya_data = {
> +	.xres = 480,
> +	.yres = 864,
> +	.refresh = 60,
> +	.width_mm = 49,
> +	.height_mm = 88,
> +	.max_hs_rate = 300000000,
> +	.max_lp_rate = 10000000,
> +};
> +
> +static const struct dsic_panel_data droid4_data = {
> +	.xres = 540,
> +	.yres = 960,
> +	.refresh = 60,
> +	.width_mm = 50,
> +	.height_mm = 89,
> +	.max_hs_rate = 300000000,
> +	.max_lp_rate = 10000000,
> +};
> +
>  static const struct of_device_id dsicm_of_match[] = {
> -	{ .compatible = "panel-dsi-cm", },
> +	{ .compatible = "tpo,taal", .data = &taal_data },
> +	{ .compatible = "nokia,himalaya", &himalaya_data },
> +	{ .compatible = "motorola,droid4-panel", &droid4_data },
>  	{},
>  };
>  
> -- 
> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
> Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v5 18/29] drm/panel: panel-dsi-cm: drop unneeded includes
  2020-12-08 12:28 ` [PATCH v5 18/29] drm/panel: panel-dsi-cm: drop unneeded includes Tomi Valkeinen
@ 2020-12-14 16:06   ` Sebastian Reichel
  0 siblings, 0 replies; 72+ messages in thread
From: Sebastian Reichel @ 2020-12-14 16:06 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Laurent Pinchart, Nikhil Devshatwar, dri-devel, linux-omap,
	Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg

[-- Attachment #1: Type: text/plain, Size: 1251 bytes --]

Hi,

On Tue, Dec 08, 2020 at 02:28:44PM +0200, Tomi Valkeinen wrote:
> Drop unneeded includes.
> 
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> Reviewed-by: Sam Ravnborg <sam@ravnborg.org>
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---
>  drivers/gpu/drm/panel/panel-dsi-cm.c | 3 ---
>  1 file changed, 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/panel/panel-dsi-cm.c b/drivers/gpu/drm/panel/panel-dsi-cm.c
> index 3fb5b2856283..3fe73c4bef6e 100644
> --- a/drivers/gpu/drm/panel/panel-dsi-cm.c
> +++ b/drivers/gpu/drm/panel/panel-dsi-cm.c
> @@ -11,9 +11,6 @@
>  #include <linux/gpio/consumer.h>
>  #include <linux/jiffies.h>
>  #include <linux/module.h>
> -#include <linux/sched/signal.h>
> -#include <linux/slab.h>
> -#include <linux/of_device.h>

Note, that 'of_device_get_match_data', which I suggested in
previous patch is defined in <linux/of_device.h>. Otherwise

Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>

-- Sebastian

>  #include <linux/regulator/consumer.h>
>  
>  #include <drm/drm_connector.h>
> -- 
> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
> Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v5 19/29] drm/omap: dsi: move structs & defines to dsi.h
  2020-12-08 12:28 ` [PATCH v5 19/29] drm/omap: dsi: move structs & defines to dsi.h Tomi Valkeinen
@ 2020-12-14 16:14   ` Sebastian Reichel
  0 siblings, 0 replies; 72+ messages in thread
From: Sebastian Reichel @ 2020-12-14 16:14 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Laurent Pinchart, Nikhil Devshatwar, dri-devel, linux-omap,
	Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg

[-- Attachment #1: Type: text/plain, Size: 31074 bytes --]

Hi,

On Tue, Dec 08, 2020 at 02:28:45PM +0200, Tomi Valkeinen wrote:
> Move structs and defines to a private dsi.h header file to make dsi.c a
> bit easier to navigate. Also move the (now) private structs and defines
> from omapdss.h to dsi.h.
> 
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---

Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>

-- Sebastian

>  drivers/gpu/drm/omapdrm/dss/dsi.c     | 384 +--------------------
>  drivers/gpu/drm/omapdrm/dss/dsi.h     | 459 ++++++++++++++++++++++++++
>  drivers/gpu/drm/omapdrm/dss/omapdss.h |  64 ----
>  3 files changed, 460 insertions(+), 447 deletions(-)
>  create mode 100644 drivers/gpu/drm/omapdrm/dss/dsi.h
> 
> diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
> index 0795efdd8902..da3ff9e236bd 100644
> --- a/drivers/gpu/drm/omapdrm/dss/dsi.c
> +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
> @@ -45,73 +45,7 @@
>  
>  #define DSI_CATCH_MISSING_TE
>  
> -struct dsi_reg { u16 module; u16 idx; };
> -
> -#define DSI_REG(mod, idx)		((const struct dsi_reg) { mod, idx })
> -
> -/* DSI Protocol Engine */
> -
> -#define DSI_PROTO			0
> -#define DSI_PROTO_SZ			0x200
> -
> -#define DSI_REVISION			DSI_REG(DSI_PROTO, 0x0000)
> -#define DSI_SYSCONFIG			DSI_REG(DSI_PROTO, 0x0010)
> -#define DSI_SYSSTATUS			DSI_REG(DSI_PROTO, 0x0014)
> -#define DSI_IRQSTATUS			DSI_REG(DSI_PROTO, 0x0018)
> -#define DSI_IRQENABLE			DSI_REG(DSI_PROTO, 0x001C)
> -#define DSI_CTRL			DSI_REG(DSI_PROTO, 0x0040)
> -#define DSI_GNQ				DSI_REG(DSI_PROTO, 0x0044)
> -#define DSI_COMPLEXIO_CFG1		DSI_REG(DSI_PROTO, 0x0048)
> -#define DSI_COMPLEXIO_IRQ_STATUS	DSI_REG(DSI_PROTO, 0x004C)
> -#define DSI_COMPLEXIO_IRQ_ENABLE	DSI_REG(DSI_PROTO, 0x0050)
> -#define DSI_CLK_CTRL			DSI_REG(DSI_PROTO, 0x0054)
> -#define DSI_TIMING1			DSI_REG(DSI_PROTO, 0x0058)
> -#define DSI_TIMING2			DSI_REG(DSI_PROTO, 0x005C)
> -#define DSI_VM_TIMING1			DSI_REG(DSI_PROTO, 0x0060)
> -#define DSI_VM_TIMING2			DSI_REG(DSI_PROTO, 0x0064)
> -#define DSI_VM_TIMING3			DSI_REG(DSI_PROTO, 0x0068)
> -#define DSI_CLK_TIMING			DSI_REG(DSI_PROTO, 0x006C)
> -#define DSI_TX_FIFO_VC_SIZE		DSI_REG(DSI_PROTO, 0x0070)
> -#define DSI_RX_FIFO_VC_SIZE		DSI_REG(DSI_PROTO, 0x0074)
> -#define DSI_COMPLEXIO_CFG2		DSI_REG(DSI_PROTO, 0x0078)
> -#define DSI_RX_FIFO_VC_FULLNESS		DSI_REG(DSI_PROTO, 0x007C)
> -#define DSI_VM_TIMING4			DSI_REG(DSI_PROTO, 0x0080)
> -#define DSI_TX_FIFO_VC_EMPTINESS	DSI_REG(DSI_PROTO, 0x0084)
> -#define DSI_VM_TIMING5			DSI_REG(DSI_PROTO, 0x0088)
> -#define DSI_VM_TIMING6			DSI_REG(DSI_PROTO, 0x008C)
> -#define DSI_VM_TIMING7			DSI_REG(DSI_PROTO, 0x0090)
> -#define DSI_STOPCLK_TIMING		DSI_REG(DSI_PROTO, 0x0094)
> -#define DSI_VC_CTRL(n)			DSI_REG(DSI_PROTO, 0x0100 + (n * 0x20))
> -#define DSI_VC_TE(n)			DSI_REG(DSI_PROTO, 0x0104 + (n * 0x20))
> -#define DSI_VC_LONG_PACKET_HEADER(n)	DSI_REG(DSI_PROTO, 0x0108 + (n * 0x20))
> -#define DSI_VC_LONG_PACKET_PAYLOAD(n)	DSI_REG(DSI_PROTO, 0x010C + (n * 0x20))
> -#define DSI_VC_SHORT_PACKET_HEADER(n)	DSI_REG(DSI_PROTO, 0x0110 + (n * 0x20))
> -#define DSI_VC_IRQSTATUS(n)		DSI_REG(DSI_PROTO, 0x0118 + (n * 0x20))
> -#define DSI_VC_IRQENABLE(n)		DSI_REG(DSI_PROTO, 0x011C + (n * 0x20))
> -
> -/* DSIPHY_SCP */
> -
> -#define DSI_PHY				1
> -#define DSI_PHY_OFFSET			0x200
> -#define DSI_PHY_SZ			0x40
> -
> -#define DSI_DSIPHY_CFG0			DSI_REG(DSI_PHY, 0x0000)
> -#define DSI_DSIPHY_CFG1			DSI_REG(DSI_PHY, 0x0004)
> -#define DSI_DSIPHY_CFG2			DSI_REG(DSI_PHY, 0x0008)
> -#define DSI_DSIPHY_CFG5			DSI_REG(DSI_PHY, 0x0014)
> -#define DSI_DSIPHY_CFG10		DSI_REG(DSI_PHY, 0x0028)
> -
> -/* DSI_PLL_CTRL_SCP */
> -
> -#define DSI_PLL				2
> -#define DSI_PLL_OFFSET			0x300
> -#define DSI_PLL_SZ			0x20
> -
> -#define DSI_PLL_CONTROL			DSI_REG(DSI_PLL, 0x0000)
> -#define DSI_PLL_STATUS			DSI_REG(DSI_PLL, 0x0004)
> -#define DSI_PLL_GO			DSI_REG(DSI_PLL, 0x0008)
> -#define DSI_PLL_CONFIGURATION1		DSI_REG(DSI_PLL, 0x000C)
> -#define DSI_PLL_CONFIGURATION2		DSI_REG(DSI_PLL, 0x0010)
> +#include "dsi.h"
>  
>  #define REG_GET(dsi, idx, start, end) \
>  	FLD_GET(dsi_read_reg(dsi, idx), start, end)
> @@ -119,96 +53,6 @@ struct dsi_reg { u16 module; u16 idx; };
>  #define REG_FLD_MOD(dsi, idx, val, start, end) \
>  	dsi_write_reg(dsi, idx, FLD_MOD(dsi_read_reg(dsi, idx), val, start, end))
>  
> -/* Global interrupts */
> -#define DSI_IRQ_VC0		(1 << 0)
> -#define DSI_IRQ_VC1		(1 << 1)
> -#define DSI_IRQ_VC2		(1 << 2)
> -#define DSI_IRQ_VC3		(1 << 3)
> -#define DSI_IRQ_WAKEUP		(1 << 4)
> -#define DSI_IRQ_RESYNC		(1 << 5)
> -#define DSI_IRQ_PLL_LOCK	(1 << 7)
> -#define DSI_IRQ_PLL_UNLOCK	(1 << 8)
> -#define DSI_IRQ_PLL_RECALL	(1 << 9)
> -#define DSI_IRQ_COMPLEXIO_ERR	(1 << 10)
> -#define DSI_IRQ_HS_TX_TIMEOUT	(1 << 14)
> -#define DSI_IRQ_LP_RX_TIMEOUT	(1 << 15)
> -#define DSI_IRQ_TE_TRIGGER	(1 << 16)
> -#define DSI_IRQ_ACK_TRIGGER	(1 << 17)
> -#define DSI_IRQ_SYNC_LOST	(1 << 18)
> -#define DSI_IRQ_LDO_POWER_GOOD	(1 << 19)
> -#define DSI_IRQ_TA_TIMEOUT	(1 << 20)
> -#define DSI_IRQ_ERROR_MASK \
> -	(DSI_IRQ_HS_TX_TIMEOUT | DSI_IRQ_LP_RX_TIMEOUT | DSI_IRQ_SYNC_LOST | \
> -	DSI_IRQ_TA_TIMEOUT)
> -#define DSI_IRQ_CHANNEL_MASK	0xf
> -
> -/* Virtual channel interrupts */
> -#define DSI_VC_IRQ_CS		(1 << 0)
> -#define DSI_VC_IRQ_ECC_CORR	(1 << 1)
> -#define DSI_VC_IRQ_PACKET_SENT	(1 << 2)
> -#define DSI_VC_IRQ_FIFO_TX_OVF	(1 << 3)
> -#define DSI_VC_IRQ_FIFO_RX_OVF	(1 << 4)
> -#define DSI_VC_IRQ_BTA		(1 << 5)
> -#define DSI_VC_IRQ_ECC_NO_CORR	(1 << 6)
> -#define DSI_VC_IRQ_FIFO_TX_UDF	(1 << 7)
> -#define DSI_VC_IRQ_PP_BUSY_CHANGE (1 << 8)
> -#define DSI_VC_IRQ_ERROR_MASK \
> -	(DSI_VC_IRQ_CS | DSI_VC_IRQ_ECC_CORR | DSI_VC_IRQ_FIFO_TX_OVF | \
> -	DSI_VC_IRQ_FIFO_RX_OVF | DSI_VC_IRQ_ECC_NO_CORR | \
> -	DSI_VC_IRQ_FIFO_TX_UDF)
> -
> -/* ComplexIO interrupts */
> -#define DSI_CIO_IRQ_ERRSYNCESC1		(1 << 0)
> -#define DSI_CIO_IRQ_ERRSYNCESC2		(1 << 1)
> -#define DSI_CIO_IRQ_ERRSYNCESC3		(1 << 2)
> -#define DSI_CIO_IRQ_ERRSYNCESC4		(1 << 3)
> -#define DSI_CIO_IRQ_ERRSYNCESC5		(1 << 4)
> -#define DSI_CIO_IRQ_ERRESC1		(1 << 5)
> -#define DSI_CIO_IRQ_ERRESC2		(1 << 6)
> -#define DSI_CIO_IRQ_ERRESC3		(1 << 7)
> -#define DSI_CIO_IRQ_ERRESC4		(1 << 8)
> -#define DSI_CIO_IRQ_ERRESC5		(1 << 9)
> -#define DSI_CIO_IRQ_ERRCONTROL1		(1 << 10)
> -#define DSI_CIO_IRQ_ERRCONTROL2		(1 << 11)
> -#define DSI_CIO_IRQ_ERRCONTROL3		(1 << 12)
> -#define DSI_CIO_IRQ_ERRCONTROL4		(1 << 13)
> -#define DSI_CIO_IRQ_ERRCONTROL5		(1 << 14)
> -#define DSI_CIO_IRQ_STATEULPS1		(1 << 15)
> -#define DSI_CIO_IRQ_STATEULPS2		(1 << 16)
> -#define DSI_CIO_IRQ_STATEULPS3		(1 << 17)
> -#define DSI_CIO_IRQ_STATEULPS4		(1 << 18)
> -#define DSI_CIO_IRQ_STATEULPS5		(1 << 19)
> -#define DSI_CIO_IRQ_ERRCONTENTIONLP0_1	(1 << 20)
> -#define DSI_CIO_IRQ_ERRCONTENTIONLP1_1	(1 << 21)
> -#define DSI_CIO_IRQ_ERRCONTENTIONLP0_2	(1 << 22)
> -#define DSI_CIO_IRQ_ERRCONTENTIONLP1_2	(1 << 23)
> -#define DSI_CIO_IRQ_ERRCONTENTIONLP0_3	(1 << 24)
> -#define DSI_CIO_IRQ_ERRCONTENTIONLP1_3	(1 << 25)
> -#define DSI_CIO_IRQ_ERRCONTENTIONLP0_4	(1 << 26)
> -#define DSI_CIO_IRQ_ERRCONTENTIONLP1_4	(1 << 27)
> -#define DSI_CIO_IRQ_ERRCONTENTIONLP0_5	(1 << 28)
> -#define DSI_CIO_IRQ_ERRCONTENTIONLP1_5	(1 << 29)
> -#define DSI_CIO_IRQ_ULPSACTIVENOT_ALL0	(1 << 30)
> -#define DSI_CIO_IRQ_ULPSACTIVENOT_ALL1	(1 << 31)
> -#define DSI_CIO_IRQ_ERROR_MASK \
> -	(DSI_CIO_IRQ_ERRSYNCESC1 | DSI_CIO_IRQ_ERRSYNCESC2 | \
> -	 DSI_CIO_IRQ_ERRSYNCESC3 | DSI_CIO_IRQ_ERRSYNCESC4 | \
> -	 DSI_CIO_IRQ_ERRSYNCESC5 | \
> -	 DSI_CIO_IRQ_ERRESC1 | DSI_CIO_IRQ_ERRESC2 | \
> -	 DSI_CIO_IRQ_ERRESC3 | DSI_CIO_IRQ_ERRESC4 | \
> -	 DSI_CIO_IRQ_ERRESC5 | \
> -	 DSI_CIO_IRQ_ERRCONTROL1 | DSI_CIO_IRQ_ERRCONTROL2 | \
> -	 DSI_CIO_IRQ_ERRCONTROL3 | DSI_CIO_IRQ_ERRCONTROL4 | \
> -	 DSI_CIO_IRQ_ERRCONTROL5 | \
> -	 DSI_CIO_IRQ_ERRCONTENTIONLP0_1 | DSI_CIO_IRQ_ERRCONTENTIONLP1_1 | \
> -	 DSI_CIO_IRQ_ERRCONTENTIONLP0_2 | DSI_CIO_IRQ_ERRCONTENTIONLP1_2 | \
> -	 DSI_CIO_IRQ_ERRCONTENTIONLP0_3 | DSI_CIO_IRQ_ERRCONTENTIONLP1_3 | \
> -	 DSI_CIO_IRQ_ERRCONTENTIONLP0_4 | DSI_CIO_IRQ_ERRCONTENTIONLP1_4 | \
> -	 DSI_CIO_IRQ_ERRCONTENTIONLP0_5 | DSI_CIO_IRQ_ERRCONTENTIONLP1_5)
> -
> -typedef void (*omap_dsi_isr_t) (void *arg, u32 mask);
> -struct dsi_data;
> -
>  static void dsi_set_ulps_auto(struct dsi_data *dsi, bool enable);
>  
>  static int dsi_display_init_dispc(struct dsi_data *dsi);
> @@ -221,232 +65,6 @@ static ssize_t _omap_dsi_host_transfer(struct dsi_data *dsi, int vc,
>  
>  static void dsi_display_disable(struct omap_dss_device *dssdev);
>  
> -/* DSI PLL HSDIV indices */
> -#define HSDIV_DISPC	0
> -#define HSDIV_DSI	1
> -
> -#define DSI_MAX_NR_ISRS                2
> -#define DSI_MAX_NR_LANES	5
> -
> -enum dsi_model {
> -	DSI_MODEL_OMAP3,
> -	DSI_MODEL_OMAP4,
> -	DSI_MODEL_OMAP5,
> -};
> -
> -enum dsi_lane_function {
> -	DSI_LANE_UNUSED	= 0,
> -	DSI_LANE_CLK,
> -	DSI_LANE_DATA1,
> -	DSI_LANE_DATA2,
> -	DSI_LANE_DATA3,
> -	DSI_LANE_DATA4,
> -};
> -
> -struct dsi_lane_config {
> -	enum dsi_lane_function function;
> -	u8 polarity;
> -};
> -
> -struct dsi_isr_data {
> -	omap_dsi_isr_t	isr;
> -	void		*arg;
> -	u32		mask;
> -};
> -
> -enum fifo_size {
> -	DSI_FIFO_SIZE_0		= 0,
> -	DSI_FIFO_SIZE_32	= 1,
> -	DSI_FIFO_SIZE_64	= 2,
> -	DSI_FIFO_SIZE_96	= 3,
> -	DSI_FIFO_SIZE_128	= 4,
> -};
> -
> -enum dsi_vc_source {
> -	DSI_VC_SOURCE_L4 = 0,
> -	DSI_VC_SOURCE_VP,
> -};
> -
> -struct dsi_irq_stats {
> -	unsigned long last_reset;
> -	unsigned int irq_count;
> -	unsigned int dsi_irqs[32];
> -	unsigned int vc_irqs[4][32];
> -	unsigned int cio_irqs[32];
> -};
> -
> -struct dsi_isr_tables {
> -	struct dsi_isr_data isr_table[DSI_MAX_NR_ISRS];
> -	struct dsi_isr_data isr_table_vc[4][DSI_MAX_NR_ISRS];
> -	struct dsi_isr_data isr_table_cio[DSI_MAX_NR_ISRS];
> -};
> -
> -struct dsi_lp_clock_info {
> -	unsigned long lp_clk;
> -	u16 lp_clk_div;
> -};
> -
> -struct dsi_clk_calc_ctx {
> -	struct dsi_data *dsi;
> -	struct dss_pll *pll;
> -
> -	/* inputs */
> -
> -	const struct omap_dss_dsi_config *config;
> -
> -	unsigned long req_pck_min, req_pck_nom, req_pck_max;
> -
> -	/* outputs */
> -
> -	struct dss_pll_clock_info dsi_cinfo;
> -	struct dispc_clock_info dispc_cinfo;
> -	struct dsi_lp_clock_info lp_cinfo;
> -
> -	struct videomode vm;
> -	struct omap_dss_dsi_videomode_timings dsi_vm;
> -};
> -
> -struct dsi_module_id_data {
> -	u32 address;
> -	int id;
> -};
> -
> -enum dsi_quirks {
> -	DSI_QUIRK_PLL_PWR_BUG = (1 << 0),	/* DSI-PLL power command 0x3 is not working */
> -	DSI_QUIRK_DCS_CMD_CONFIG_VC = (1 << 1),
> -	DSI_QUIRK_VC_OCP_WIDTH = (1 << 2),
> -	DSI_QUIRK_REVERSE_TXCLKESC = (1 << 3),
> -	DSI_QUIRK_GNQ = (1 << 4),
> -	DSI_QUIRK_PHY_DCC = (1 << 5),
> -};
> -
> -struct dsi_of_data {
> -	enum dsi_model model;
> -	const struct dss_pll_hw *pll_hw;
> -	const struct dsi_module_id_data *modules;
> -	unsigned int max_fck_freq;
> -	unsigned int max_pll_lpdiv;
> -	enum dsi_quirks quirks;
> -};
> -
> -struct dsi_data {
> -	struct device *dev;
> -	void __iomem *proto_base;
> -	void __iomem *phy_base;
> -	void __iomem *pll_base;
> -
> -	const struct dsi_of_data *data;
> -	int module_id;
> -
> -	int irq;
> -
> -	bool is_enabled;
> -
> -	struct clk *dss_clk;
> -	struct regmap *syscon;
> -	struct dss_device *dss;
> -
> -	struct mipi_dsi_host host;
> -
> -	struct dispc_clock_info user_dispc_cinfo;
> -	struct dss_pll_clock_info user_dsi_cinfo;
> -
> -	struct dsi_lp_clock_info user_lp_cinfo;
> -	struct dsi_lp_clock_info current_lp_cinfo;
> -
> -	struct dss_pll pll;
> -
> -	bool vdds_dsi_enabled;
> -	struct regulator *vdds_dsi_reg;
> -
> -	struct mipi_dsi_device *dsidev;
> -
> -	struct {
> -		enum dsi_vc_source source;
> -		enum fifo_size tx_fifo_size;
> -		enum fifo_size rx_fifo_size;
> -	} vc[4];
> -
> -	struct mutex lock;
> -	struct semaphore bus_lock;
> -
> -	spinlock_t irq_lock;
> -	struct dsi_isr_tables isr_tables;
> -	/* space for a copy used by the interrupt handler */
> -	struct dsi_isr_tables isr_tables_copy;
> -
> -	int update_vc;
> -#ifdef DSI_PERF_MEASURE
> -	unsigned int update_bytes;
> -#endif
> -
> -	/* external TE GPIO */
> -	struct gpio_desc *te_gpio;
> -	int te_irq;
> -	struct delayed_work te_timeout_work;
> -	atomic_t do_ext_te_update;
> -
> -	bool te_enabled;
> -	bool ulps_enabled;
> -	bool ulps_auto_idle;
> -	bool video_enabled;
> -
> -	struct delayed_work ulps_work;
> -
> -	struct delayed_work framedone_timeout_work;
> -
> -#ifdef DSI_CATCH_MISSING_TE
> -	struct timer_list te_timer;
> -#endif
> -
> -	unsigned long cache_req_pck;
> -	unsigned long cache_clk_freq;
> -	struct dss_pll_clock_info cache_cinfo;
> -
> -	u32		errors;
> -	spinlock_t	errors_lock;
> -#ifdef DSI_PERF_MEASURE
> -	ktime_t perf_setup_time;
> -	ktime_t perf_start_time;
> -#endif
> -	int debug_read;
> -	int debug_write;
> -	struct {
> -		struct dss_debugfs_entry *irqs;
> -		struct dss_debugfs_entry *regs;
> -		struct dss_debugfs_entry *clks;
> -	} debugfs;
> -
> -#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
> -	spinlock_t irq_stats_lock;
> -	struct dsi_irq_stats irq_stats;
> -#endif
> -
> -	unsigned int num_lanes_supported;
> -	unsigned int line_buffer_size;
> -
> -	struct dsi_lane_config lanes[DSI_MAX_NR_LANES];
> -	unsigned int num_lanes_used;
> -
> -	unsigned int scp_clk_refcount;
> -
> -	struct omap_dss_dsi_config config;
> -
> -	struct dss_lcd_mgr_config mgr_config;
> -	struct videomode vm;
> -	enum mipi_dsi_pixel_format pix_fmt;
> -	enum omap_dss_dsi_mode mode;
> -	struct omap_dss_dsi_videomode_timings vm_timings;
> -
> -	struct omap_dss_device output;
> -	struct drm_bridge bridge;
> -};
> -
> -struct dsi_packet_sent_handler_data {
> -	struct dsi_data *dsi;
> -	struct completion *completion;
> -};
> -
>  #ifdef DSI_PERF_MEASURE
>  static bool dsi_perf;
>  module_param(dsi_perf, bool, 0644);
> diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.h b/drivers/gpu/drm/omapdrm/dss/dsi.h
> new file mode 100644
> index 000000000000..478fc10bd18d
> --- /dev/null
> +++ b/drivers/gpu/drm/omapdrm/dss/dsi.h
> @@ -0,0 +1,459 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Copyright (C) 2016 Texas Instruments Incorporated - http://www.ti.com/
> + * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
> + */
> +
> +#ifndef __OMAP_DRM_DSS_DSI_H
> +#define __OMAP_DRM_DSS_DSI_H
> +
> +#include <drm/drm_mipi_dsi.h>
> +
> +struct dsi_reg {
> +	u16 module;
> +	u16 idx;
> +};
> +
> +#define DSI_REG(mod, idx)		((const struct dsi_reg) { mod, idx })
> +
> +/* DSI Protocol Engine */
> +
> +#define DSI_PROTO			0
> +#define DSI_PROTO_SZ			0x200
> +
> +#define DSI_REVISION			DSI_REG(DSI_PROTO, 0x0000)
> +#define DSI_SYSCONFIG			DSI_REG(DSI_PROTO, 0x0010)
> +#define DSI_SYSSTATUS			DSI_REG(DSI_PROTO, 0x0014)
> +#define DSI_IRQSTATUS			DSI_REG(DSI_PROTO, 0x0018)
> +#define DSI_IRQENABLE			DSI_REG(DSI_PROTO, 0x001C)
> +#define DSI_CTRL			DSI_REG(DSI_PROTO, 0x0040)
> +#define DSI_GNQ				DSI_REG(DSI_PROTO, 0x0044)
> +#define DSI_COMPLEXIO_CFG1		DSI_REG(DSI_PROTO, 0x0048)
> +#define DSI_COMPLEXIO_IRQ_STATUS	DSI_REG(DSI_PROTO, 0x004C)
> +#define DSI_COMPLEXIO_IRQ_ENABLE	DSI_REG(DSI_PROTO, 0x0050)
> +#define DSI_CLK_CTRL			DSI_REG(DSI_PROTO, 0x0054)
> +#define DSI_TIMING1			DSI_REG(DSI_PROTO, 0x0058)
> +#define DSI_TIMING2			DSI_REG(DSI_PROTO, 0x005C)
> +#define DSI_VM_TIMING1			DSI_REG(DSI_PROTO, 0x0060)
> +#define DSI_VM_TIMING2			DSI_REG(DSI_PROTO, 0x0064)
> +#define DSI_VM_TIMING3			DSI_REG(DSI_PROTO, 0x0068)
> +#define DSI_CLK_TIMING			DSI_REG(DSI_PROTO, 0x006C)
> +#define DSI_TX_FIFO_VC_SIZE		DSI_REG(DSI_PROTO, 0x0070)
> +#define DSI_RX_FIFO_VC_SIZE		DSI_REG(DSI_PROTO, 0x0074)
> +#define DSI_COMPLEXIO_CFG2		DSI_REG(DSI_PROTO, 0x0078)
> +#define DSI_RX_FIFO_VC_FULLNESS		DSI_REG(DSI_PROTO, 0x007C)
> +#define DSI_VM_TIMING4			DSI_REG(DSI_PROTO, 0x0080)
> +#define DSI_TX_FIFO_VC_EMPTINESS	DSI_REG(DSI_PROTO, 0x0084)
> +#define DSI_VM_TIMING5			DSI_REG(DSI_PROTO, 0x0088)
> +#define DSI_VM_TIMING6			DSI_REG(DSI_PROTO, 0x008C)
> +#define DSI_VM_TIMING7			DSI_REG(DSI_PROTO, 0x0090)
> +#define DSI_STOPCLK_TIMING		DSI_REG(DSI_PROTO, 0x0094)
> +#define DSI_VC_CTRL(n)			DSI_REG(DSI_PROTO, 0x0100 + (n * 0x20))
> +#define DSI_VC_TE(n)			DSI_REG(DSI_PROTO, 0x0104 + (n * 0x20))
> +#define DSI_VC_LONG_PACKET_HEADER(n)	DSI_REG(DSI_PROTO, 0x0108 + (n * 0x20))
> +#define DSI_VC_LONG_PACKET_PAYLOAD(n)	DSI_REG(DSI_PROTO, 0x010C + (n * 0x20))
> +#define DSI_VC_SHORT_PACKET_HEADER(n)	DSI_REG(DSI_PROTO, 0x0110 + (n * 0x20))
> +#define DSI_VC_IRQSTATUS(n)		DSI_REG(DSI_PROTO, 0x0118 + (n * 0x20))
> +#define DSI_VC_IRQENABLE(n)		DSI_REG(DSI_PROTO, 0x011C + (n * 0x20))
> +
> +/* DSIPHY_SCP */
> +
> +#define DSI_PHY				1
> +#define DSI_PHY_OFFSET			0x200
> +#define DSI_PHY_SZ			0x40
> +
> +#define DSI_DSIPHY_CFG0			DSI_REG(DSI_PHY, 0x0000)
> +#define DSI_DSIPHY_CFG1			DSI_REG(DSI_PHY, 0x0004)
> +#define DSI_DSIPHY_CFG2			DSI_REG(DSI_PHY, 0x0008)
> +#define DSI_DSIPHY_CFG5			DSI_REG(DSI_PHY, 0x0014)
> +#define DSI_DSIPHY_CFG10		DSI_REG(DSI_PHY, 0x0028)
> +
> +/* DSI_PLL_CTRL_SCP */
> +
> +#define DSI_PLL				2
> +#define DSI_PLL_OFFSET			0x300
> +#define DSI_PLL_SZ			0x20
> +
> +#define DSI_PLL_CONTROL			DSI_REG(DSI_PLL, 0x0000)
> +#define DSI_PLL_STATUS			DSI_REG(DSI_PLL, 0x0004)
> +#define DSI_PLL_GO			DSI_REG(DSI_PLL, 0x0008)
> +#define DSI_PLL_CONFIGURATION1		DSI_REG(DSI_PLL, 0x000C)
> +#define DSI_PLL_CONFIGURATION2		DSI_REG(DSI_PLL, 0x0010)
> +
> +/* Global interrupts */
> +#define DSI_IRQ_VC0		(1 << 0)
> +#define DSI_IRQ_VC1		(1 << 1)
> +#define DSI_IRQ_VC2		(1 << 2)
> +#define DSI_IRQ_VC3		(1 << 3)
> +#define DSI_IRQ_WAKEUP		(1 << 4)
> +#define DSI_IRQ_RESYNC		(1 << 5)
> +#define DSI_IRQ_PLL_LOCK	(1 << 7)
> +#define DSI_IRQ_PLL_UNLOCK	(1 << 8)
> +#define DSI_IRQ_PLL_RECALL	(1 << 9)
> +#define DSI_IRQ_COMPLEXIO_ERR	(1 << 10)
> +#define DSI_IRQ_HS_TX_TIMEOUT	(1 << 14)
> +#define DSI_IRQ_LP_RX_TIMEOUT	(1 << 15)
> +#define DSI_IRQ_TE_TRIGGER	(1 << 16)
> +#define DSI_IRQ_ACK_TRIGGER	(1 << 17)
> +#define DSI_IRQ_SYNC_LOST	(1 << 18)
> +#define DSI_IRQ_LDO_POWER_GOOD	(1 << 19)
> +#define DSI_IRQ_TA_TIMEOUT	(1 << 20)
> +#define DSI_IRQ_ERROR_MASK \
> +	(DSI_IRQ_HS_TX_TIMEOUT | DSI_IRQ_LP_RX_TIMEOUT | DSI_IRQ_SYNC_LOST | \
> +	DSI_IRQ_TA_TIMEOUT)
> +#define DSI_IRQ_CHANNEL_MASK	0xf
> +
> +/* Virtual channel interrupts */
> +#define DSI_VC_IRQ_CS		(1 << 0)
> +#define DSI_VC_IRQ_ECC_CORR	(1 << 1)
> +#define DSI_VC_IRQ_PACKET_SENT	(1 << 2)
> +#define DSI_VC_IRQ_FIFO_TX_OVF	(1 << 3)
> +#define DSI_VC_IRQ_FIFO_RX_OVF	(1 << 4)
> +#define DSI_VC_IRQ_BTA		(1 << 5)
> +#define DSI_VC_IRQ_ECC_NO_CORR	(1 << 6)
> +#define DSI_VC_IRQ_FIFO_TX_UDF	(1 << 7)
> +#define DSI_VC_IRQ_PP_BUSY_CHANGE (1 << 8)
> +#define DSI_VC_IRQ_ERROR_MASK \
> +	(DSI_VC_IRQ_CS | DSI_VC_IRQ_ECC_CORR | DSI_VC_IRQ_FIFO_TX_OVF | \
> +	DSI_VC_IRQ_FIFO_RX_OVF | DSI_VC_IRQ_ECC_NO_CORR | \
> +	DSI_VC_IRQ_FIFO_TX_UDF)
> +
> +/* ComplexIO interrupts */
> +#define DSI_CIO_IRQ_ERRSYNCESC1		(1 << 0)
> +#define DSI_CIO_IRQ_ERRSYNCESC2		(1 << 1)
> +#define DSI_CIO_IRQ_ERRSYNCESC3		(1 << 2)
> +#define DSI_CIO_IRQ_ERRSYNCESC4		(1 << 3)
> +#define DSI_CIO_IRQ_ERRSYNCESC5		(1 << 4)
> +#define DSI_CIO_IRQ_ERRESC1		(1 << 5)
> +#define DSI_CIO_IRQ_ERRESC2		(1 << 6)
> +#define DSI_CIO_IRQ_ERRESC3		(1 << 7)
> +#define DSI_CIO_IRQ_ERRESC4		(1 << 8)
> +#define DSI_CIO_IRQ_ERRESC5		(1 << 9)
> +#define DSI_CIO_IRQ_ERRCONTROL1		(1 << 10)
> +#define DSI_CIO_IRQ_ERRCONTROL2		(1 << 11)
> +#define DSI_CIO_IRQ_ERRCONTROL3		(1 << 12)
> +#define DSI_CIO_IRQ_ERRCONTROL4		(1 << 13)
> +#define DSI_CIO_IRQ_ERRCONTROL5		(1 << 14)
> +#define DSI_CIO_IRQ_STATEULPS1		(1 << 15)
> +#define DSI_CIO_IRQ_STATEULPS2		(1 << 16)
> +#define DSI_CIO_IRQ_STATEULPS3		(1 << 17)
> +#define DSI_CIO_IRQ_STATEULPS4		(1 << 18)
> +#define DSI_CIO_IRQ_STATEULPS5		(1 << 19)
> +#define DSI_CIO_IRQ_ERRCONTENTIONLP0_1	(1 << 20)
> +#define DSI_CIO_IRQ_ERRCONTENTIONLP1_1	(1 << 21)
> +#define DSI_CIO_IRQ_ERRCONTENTIONLP0_2	(1 << 22)
> +#define DSI_CIO_IRQ_ERRCONTENTIONLP1_2	(1 << 23)
> +#define DSI_CIO_IRQ_ERRCONTENTIONLP0_3	(1 << 24)
> +#define DSI_CIO_IRQ_ERRCONTENTIONLP1_3	(1 << 25)
> +#define DSI_CIO_IRQ_ERRCONTENTIONLP0_4	(1 << 26)
> +#define DSI_CIO_IRQ_ERRCONTENTIONLP1_4	(1 << 27)
> +#define DSI_CIO_IRQ_ERRCONTENTIONLP0_5	(1 << 28)
> +#define DSI_CIO_IRQ_ERRCONTENTIONLP1_5	(1 << 29)
> +#define DSI_CIO_IRQ_ULPSACTIVENOT_ALL0	(1 << 30)
> +#define DSI_CIO_IRQ_ULPSACTIVENOT_ALL1	(1 << 31)
> +#define DSI_CIO_IRQ_ERROR_MASK \
> +	(DSI_CIO_IRQ_ERRSYNCESC1 | DSI_CIO_IRQ_ERRSYNCESC2 | \
> +	 DSI_CIO_IRQ_ERRSYNCESC3 | DSI_CIO_IRQ_ERRSYNCESC4 | \
> +	 DSI_CIO_IRQ_ERRSYNCESC5 | \
> +	 DSI_CIO_IRQ_ERRESC1 | DSI_CIO_IRQ_ERRESC2 | \
> +	 DSI_CIO_IRQ_ERRESC3 | DSI_CIO_IRQ_ERRESC4 | \
> +	 DSI_CIO_IRQ_ERRESC5 | \
> +	 DSI_CIO_IRQ_ERRCONTROL1 | DSI_CIO_IRQ_ERRCONTROL2 | \
> +	 DSI_CIO_IRQ_ERRCONTROL3 | DSI_CIO_IRQ_ERRCONTROL4 | \
> +	 DSI_CIO_IRQ_ERRCONTROL5 | \
> +	 DSI_CIO_IRQ_ERRCONTENTIONLP0_1 | DSI_CIO_IRQ_ERRCONTENTIONLP1_1 | \
> +	 DSI_CIO_IRQ_ERRCONTENTIONLP0_2 | DSI_CIO_IRQ_ERRCONTENTIONLP1_2 | \
> +	 DSI_CIO_IRQ_ERRCONTENTIONLP0_3 | DSI_CIO_IRQ_ERRCONTENTIONLP1_3 | \
> +	 DSI_CIO_IRQ_ERRCONTENTIONLP0_4 | DSI_CIO_IRQ_ERRCONTENTIONLP1_4 | \
> +	 DSI_CIO_IRQ_ERRCONTENTIONLP0_5 | DSI_CIO_IRQ_ERRCONTENTIONLP1_5)
> +
> +enum omap_dss_dsi_mode {
> +	OMAP_DSS_DSI_CMD_MODE = 0,
> +	OMAP_DSS_DSI_VIDEO_MODE,
> +};
> +
> +enum omap_dss_dsi_trans_mode {
> +	/* Sync Pulses: both sync start and end packets sent */
> +	OMAP_DSS_DSI_PULSE_MODE,
> +	/* Sync Events: only sync start packets sent */
> +	OMAP_DSS_DSI_EVENT_MODE,
> +	/* Burst: only sync start packets sent, pixels are time compressed */
> +	OMAP_DSS_DSI_BURST_MODE,
> +};
> +
> +struct omap_dss_dsi_videomode_timings {
> +	unsigned long hsclk;
> +
> +	unsigned int ndl;
> +	unsigned int bitspp;
> +
> +	/* pixels */
> +	u16 hact;
> +	/* lines */
> +	u16 vact;
> +
> +	/* DSI video mode blanking data */
> +	/* Unit: byte clock cycles */
> +	u16 hss;
> +	u16 hsa;
> +	u16 hse;
> +	u16 hfp;
> +	u16 hbp;
> +	/* Unit: line clocks */
> +	u16 vsa;
> +	u16 vfp;
> +	u16 vbp;
> +
> +	/* DSI blanking modes */
> +	int blanking_mode;
> +	int hsa_blanking_mode;
> +	int hbp_blanking_mode;
> +	int hfp_blanking_mode;
> +
> +	enum omap_dss_dsi_trans_mode trans_mode;
> +
> +	bool ddr_clk_always_on;
> +	int window_sync;
> +};
> +
> +struct omap_dss_dsi_config {
> +	enum omap_dss_dsi_mode mode;
> +	enum mipi_dsi_pixel_format pixel_format;
> +	const struct videomode *vm;
> +
> +	unsigned long hs_clk_min, hs_clk_max;
> +	unsigned long lp_clk_min, lp_clk_max;
> +
> +	bool ddr_clk_always_on;
> +	enum omap_dss_dsi_trans_mode trans_mode;
> +};
> +
> +/* DSI PLL HSDIV indices */
> +#define HSDIV_DISPC	0
> +#define HSDIV_DSI	1
> +
> +#define DSI_MAX_NR_ISRS                2
> +#define DSI_MAX_NR_LANES	5
> +
> +enum dsi_model {
> +	DSI_MODEL_OMAP3,
> +	DSI_MODEL_OMAP4,
> +	DSI_MODEL_OMAP5,
> +};
> +
> +enum dsi_lane_function {
> +	DSI_LANE_UNUSED	= 0,
> +	DSI_LANE_CLK,
> +	DSI_LANE_DATA1,
> +	DSI_LANE_DATA2,
> +	DSI_LANE_DATA3,
> +	DSI_LANE_DATA4,
> +};
> +
> +struct dsi_lane_config {
> +	enum dsi_lane_function function;
> +	u8 polarity;
> +};
> +
> +typedef void (*omap_dsi_isr_t) (void *arg, u32 mask);
> +
> +struct dsi_isr_data {
> +	omap_dsi_isr_t	isr;
> +	void		*arg;
> +	u32		mask;
> +};
> +
> +enum fifo_size {
> +	DSI_FIFO_SIZE_0		= 0,
> +	DSI_FIFO_SIZE_32	= 1,
> +	DSI_FIFO_SIZE_64	= 2,
> +	DSI_FIFO_SIZE_96	= 3,
> +	DSI_FIFO_SIZE_128	= 4,
> +};
> +
> +enum dsi_vc_source {
> +	DSI_VC_SOURCE_L4 = 0,
> +	DSI_VC_SOURCE_VP,
> +};
> +
> +struct dsi_irq_stats {
> +	unsigned long last_reset;
> +	unsigned int irq_count;
> +	unsigned int dsi_irqs[32];
> +	unsigned int vc_irqs[4][32];
> +	unsigned int cio_irqs[32];
> +};
> +
> +struct dsi_isr_tables {
> +	struct dsi_isr_data isr_table[DSI_MAX_NR_ISRS];
> +	struct dsi_isr_data isr_table_vc[4][DSI_MAX_NR_ISRS];
> +	struct dsi_isr_data isr_table_cio[DSI_MAX_NR_ISRS];
> +};
> +
> +struct dsi_lp_clock_info {
> +	unsigned long lp_clk;
> +	u16 lp_clk_div;
> +};
> +
> +struct dsi_clk_calc_ctx {
> +	struct dsi_data *dsi;
> +	struct dss_pll *pll;
> +
> +	/* inputs */
> +
> +	const struct omap_dss_dsi_config *config;
> +
> +	unsigned long req_pck_min, req_pck_nom, req_pck_max;
> +
> +	/* outputs */
> +
> +	struct dss_pll_clock_info dsi_cinfo;
> +	struct dispc_clock_info dispc_cinfo;
> +	struct dsi_lp_clock_info lp_cinfo;
> +
> +	struct videomode vm;
> +	struct omap_dss_dsi_videomode_timings dsi_vm;
> +};
> +
> +struct dsi_module_id_data {
> +	u32 address;
> +	int id;
> +};
> +
> +enum dsi_quirks {
> +	DSI_QUIRK_PLL_PWR_BUG = (1 << 0),	/* DSI-PLL power command 0x3 is not working */
> +	DSI_QUIRK_DCS_CMD_CONFIG_VC = (1 << 1),
> +	DSI_QUIRK_VC_OCP_WIDTH = (1 << 2),
> +	DSI_QUIRK_REVERSE_TXCLKESC = (1 << 3),
> +	DSI_QUIRK_GNQ = (1 << 4),
> +	DSI_QUIRK_PHY_DCC = (1 << 5),
> +};
> +
> +struct dsi_of_data {
> +	enum dsi_model model;
> +	const struct dss_pll_hw *pll_hw;
> +	const struct dsi_module_id_data *modules;
> +	unsigned int max_fck_freq;
> +	unsigned int max_pll_lpdiv;
> +	enum dsi_quirks quirks;
> +};
> +
> +struct dsi_data {
> +	struct device *dev;
> +	void __iomem *proto_base;
> +	void __iomem *phy_base;
> +	void __iomem *pll_base;
> +
> +	const struct dsi_of_data *data;
> +	int module_id;
> +
> +	int irq;
> +
> +	bool is_enabled;
> +
> +	struct clk *dss_clk;
> +	struct regmap *syscon;
> +	struct dss_device *dss;
> +
> +	struct mipi_dsi_host host;
> +
> +	struct dispc_clock_info user_dispc_cinfo;
> +	struct dss_pll_clock_info user_dsi_cinfo;
> +
> +	struct dsi_lp_clock_info user_lp_cinfo;
> +	struct dsi_lp_clock_info current_lp_cinfo;
> +
> +	struct dss_pll pll;
> +
> +	bool vdds_dsi_enabled;
> +	struct regulator *vdds_dsi_reg;
> +
> +	struct mipi_dsi_device *dsidev;
> +
> +	struct {
> +		enum dsi_vc_source source;
> +		enum fifo_size tx_fifo_size;
> +		enum fifo_size rx_fifo_size;
> +	} vc[4];
> +
> +	struct mutex lock;
> +	struct semaphore bus_lock;
> +
> +	spinlock_t irq_lock;
> +	struct dsi_isr_tables isr_tables;
> +	/* space for a copy used by the interrupt handler */
> +	struct dsi_isr_tables isr_tables_copy;
> +
> +	int update_vc;
> +#ifdef DSI_PERF_MEASURE
> +	unsigned int update_bytes;
> +#endif
> +
> +	/* external TE GPIO */
> +	struct gpio_desc *te_gpio;
> +	int te_irq;
> +	struct delayed_work te_timeout_work;
> +	atomic_t do_ext_te_update;
> +
> +	bool te_enabled;
> +	bool ulps_enabled;
> +	bool ulps_auto_idle;
> +	bool video_enabled;
> +
> +	struct delayed_work ulps_work;
> +
> +	struct delayed_work framedone_timeout_work;
> +
> +#ifdef DSI_CATCH_MISSING_TE
> +	struct timer_list te_timer;
> +#endif
> +
> +	unsigned long cache_req_pck;
> +	unsigned long cache_clk_freq;
> +	struct dss_pll_clock_info cache_cinfo;
> +
> +	u32		errors;
> +	spinlock_t	errors_lock;
> +#ifdef DSI_PERF_MEASURE
> +	ktime_t perf_setup_time;
> +	ktime_t perf_start_time;
> +#endif
> +	int debug_read;
> +	int debug_write;
> +	struct {
> +		struct dss_debugfs_entry *irqs;
> +		struct dss_debugfs_entry *regs;
> +		struct dss_debugfs_entry *clks;
> +	} debugfs;
> +
> +#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
> +	spinlock_t irq_stats_lock;
> +	struct dsi_irq_stats irq_stats;
> +#endif
> +
> +	unsigned int num_lanes_supported;
> +	unsigned int line_buffer_size;
> +
> +	struct dsi_lane_config lanes[DSI_MAX_NR_LANES];
> +	unsigned int num_lanes_used;
> +
> +	unsigned int scp_clk_refcount;
> +
> +	struct omap_dss_dsi_config config;
> +
> +	struct dss_lcd_mgr_config mgr_config;
> +	struct videomode vm;
> +	enum mipi_dsi_pixel_format pix_fmt;
> +	enum omap_dss_dsi_mode mode;
> +	struct omap_dss_dsi_videomode_timings vm_timings;
> +
> +	struct omap_dss_device output;
> +	struct drm_bridge bridge;
> +};
> +
> +struct dsi_packet_sent_handler_data {
> +	struct dsi_data *dsi;
> +	struct completion *completion;
> +};
> +
> +#endif /* __OMAP_DRM_DSS_DSI_H */
> diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h
> index 9df322ca467d..6ecaa060ff4b 100644
> --- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
> +++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
> @@ -14,7 +14,6 @@
>  #include <linux/platform_data/omapdss.h>
>  
>  #include <drm/drm_crtc.h>
> -#include <drm/drm_mipi_dsi.h>
>  #include <drm/drm_mode.h>
>  
>  #define DISPC_IRQ_FRAMEDONE		(1 << 0)
> @@ -118,11 +117,6 @@ enum omap_dss_venc_type {
>  	OMAP_DSS_VENC_TYPE_SVIDEO,
>  };
>  
> -enum omap_dss_dsi_mode {
> -	OMAP_DSS_DSI_CMD_MODE = 0,
> -	OMAP_DSS_DSI_VIDEO_MODE,
> -};
> -
>  enum omap_dss_rotation_type {
>  	OMAP_DSS_ROT_NONE	= 0,
>  	OMAP_DSS_ROT_TILER	= 1 << 0,
> @@ -147,64 +141,6 @@ enum omap_dss_output_id {
>  	OMAP_DSS_OUTPUT_HDMI	= 1 << 6,
>  };
>  
> -/* DSI */
> -
> -enum omap_dss_dsi_trans_mode {
> -	/* Sync Pulses: both sync start and end packets sent */
> -	OMAP_DSS_DSI_PULSE_MODE,
> -	/* Sync Events: only sync start packets sent */
> -	OMAP_DSS_DSI_EVENT_MODE,
> -	/* Burst: only sync start packets sent, pixels are time compressed */
> -	OMAP_DSS_DSI_BURST_MODE,
> -};
> -
> -struct omap_dss_dsi_videomode_timings {
> -	unsigned long hsclk;
> -
> -	unsigned int ndl;
> -	unsigned int bitspp;
> -
> -	/* pixels */
> -	u16 hact;
> -	/* lines */
> -	u16 vact;
> -
> -	/* DSI video mode blanking data */
> -	/* Unit: byte clock cycles */
> -	u16 hss;
> -	u16 hsa;
> -	u16 hse;
> -	u16 hfp;
> -	u16 hbp;
> -	/* Unit: line clocks */
> -	u16 vsa;
> -	u16 vfp;
> -	u16 vbp;
> -
> -	/* DSI blanking modes */
> -	int blanking_mode;
> -	int hsa_blanking_mode;
> -	int hbp_blanking_mode;
> -	int hfp_blanking_mode;
> -
> -	enum omap_dss_dsi_trans_mode trans_mode;
> -
> -	bool ddr_clk_always_on;
> -	int window_sync;
> -};
> -
> -struct omap_dss_dsi_config {
> -	enum omap_dss_dsi_mode mode;
> -	enum mipi_dsi_pixel_format pixel_format;
> -	const struct videomode *vm;
> -
> -	unsigned long hs_clk_min, hs_clk_max;
> -	unsigned long lp_clk_min, lp_clk_max;
> -
> -	bool ddr_clk_always_on;
> -	enum omap_dss_dsi_trans_mode trans_mode;
> -};
> -
>  struct omap_dss_cpr_coefs {
>  	s16 rr, rg, rb;
>  	s16 gr, gg, gb;
> -- 
> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
> Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v5 20/29] drm/omap: dsi: move enable/disable to bridge enable/disable
  2020-12-08 12:28 ` [PATCH v5 20/29] drm/omap: dsi: move enable/disable to bridge enable/disable Tomi Valkeinen
@ 2020-12-14 16:16   ` Sebastian Reichel
  0 siblings, 0 replies; 72+ messages in thread
From: Sebastian Reichel @ 2020-12-14 16:16 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Laurent Pinchart, Nikhil Devshatwar, dri-devel, linux-omap,
	Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg

[-- Attachment #1: Type: text/plain, Size: 3098 bytes --]

Hi,

On Tue, Dec 08, 2020 at 02:28:46PM +0200, Tomi Valkeinen wrote:
> Clean up the code by inlining dsi_enable_video_outputs and
> dsi_disable_video_outputs functions.
> 
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---

Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>

-- Sebastian

>  drivers/gpu/drm/omapdrm/dss/dsi.c | 55 +++++++++++++------------------
>  1 file changed, 22 insertions(+), 33 deletions(-)
> 
> diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
> index da3ff9e236bd..44b8e42b52ec 100644
> --- a/drivers/gpu/drm/omapdrm/dss/dsi.c
> +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
> @@ -3336,20 +3336,6 @@ static void dsi_disable_video_output(struct omap_dss_device *dssdev, int vc)
>  	dsi_display_uninit_dispc(dsi);
>  }
>  
> -static void dsi_disable_video_outputs(struct omap_dss_device *dssdev)
> -{
> -	struct dsi_data *dsi = to_dsi_data(dssdev);
> -
> -	dsi_bus_lock(dsi);
> -	dsi->video_enabled = false;
> -
> -	dsi_disable_video_output(dssdev, VC_VIDEO);
> -
> -	dsi_display_disable(dssdev);
> -
> -	dsi_bus_unlock(dsi);
> -}
> -
>  static void dsi_update_screen_dispc(struct dsi_data *dsi)
>  {
>  	unsigned int bytespp;
> @@ -3796,23 +3782,6 @@ static void dsi_display_enable(struct omap_dss_device *dssdev)
>  	_dsi_display_enable(dsi);
>  }
>  
> -static void dsi_enable_video_outputs(struct omap_dss_device *dssdev)
> -{
> -	struct dsi_data *dsi = to_dsi_data(dssdev);
> -
> -	dsi_bus_lock(dsi);
> -
> -	dsi_display_enable(dssdev);
> -
> -	dsi_enable_video_output(dssdev, VC_VIDEO);
> -
> -	dsi->video_enabled = true;
> -
> -	dsi_set_ulps_auto(dsi, true);
> -
> -	dsi_bus_unlock(dsi);
> -}
> -
>  static void _dsi_display_disable(struct dsi_data *dsi,
>  		bool disconnect_lanes, bool enter_ulps)
>  {
> @@ -4974,15 +4943,35 @@ static void dsi_bridge_mode_set(struct drm_bridge *bridge,
>  static void dsi_bridge_enable(struct drm_bridge *bridge)
>  {
>  	struct dsi_data *dsi = drm_bridge_to_dsi(bridge);
> +	struct omap_dss_device *dssdev = &dsi->output;
>  
> -	dsi_enable_video_outputs(&dsi->output);
> +	dsi_bus_lock(dsi);
> +
> +	dsi_display_enable(dssdev);
> +
> +	dsi_enable_video_output(dssdev, VC_VIDEO);
> +
> +	dsi->video_enabled = true;
> +
> +	dsi_set_ulps_auto(dsi, true);
> +
> +	dsi_bus_unlock(dsi);
>  }
>  
>  static void dsi_bridge_disable(struct drm_bridge *bridge)
>  {
>  	struct dsi_data *dsi = drm_bridge_to_dsi(bridge);
> +	struct omap_dss_device *dssdev = &dsi->output;
> +
> +	dsi_bus_lock(dsi);
> +
> +	dsi->video_enabled = false;
> +
> +	dsi_disable_video_output(dssdev, VC_VIDEO);
>  
> -	dsi_disable_video_outputs(&dsi->output);
> +	dsi_display_disable(dssdev);
> +
> +	dsi_bus_unlock(dsi);
>  }
>  
>  static const struct drm_bridge_funcs dsi_bridge_funcs = {
> -- 
> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
> Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v5 21/29] drm/omap: dsi: display_enable cleanup
  2020-12-08 12:28 ` [PATCH v5 21/29] drm/omap: dsi: display_enable cleanup Tomi Valkeinen
@ 2020-12-14 16:17   ` Sebastian Reichel
  0 siblings, 0 replies; 72+ messages in thread
From: Sebastian Reichel @ 2020-12-14 16:17 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Laurent Pinchart, Nikhil Devshatwar, dri-devel, linux-omap,
	Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg

[-- Attachment #1: Type: text/plain, Size: 2322 bytes --]

Hi,

On Tue, Dec 08, 2020 at 02:28:47PM +0200, Tomi Valkeinen wrote:
> We can drop dsi_display_enable(), which just calls
> _dsi_display_enable(), and rename _dsi_display_enable() to
> dsi_display_enable().
> 
> The WARN_ON(!dsi_bus_is_locked(dsi)) in dsi_display_enable is extra and
> can be dropped, as _dsi_display_enable() has the same WARN_ON().
> 
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---

Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>

-- Sebastian

>  drivers/gpu/drm/omapdrm/dss/dsi.c | 16 +++-------------
>  1 file changed, 3 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
> index 44b8e42b52ec..961b991f6498 100644
> --- a/drivers/gpu/drm/omapdrm/dss/dsi.c
> +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
> @@ -3743,7 +3743,7 @@ static void dsi_display_uninit_dsi(struct dsi_data *dsi, bool disconnect_lanes,
>  	}
>  }
>  
> -static void _dsi_display_enable(struct dsi_data *dsi)
> +static void dsi_display_enable(struct dsi_data *dsi)
>  {
>  	int r;
>  
> @@ -3772,16 +3772,6 @@ static void _dsi_display_enable(struct dsi_data *dsi)
>  	DSSDBG("dsi_display_ulps_enable FAILED\n");
>  }
>  
> -static void dsi_display_enable(struct omap_dss_device *dssdev)
> -{
> -	struct dsi_data *dsi = to_dsi_data(dssdev);
> -	DSSDBG("dsi_display_enable\n");
> -
> -	WARN_ON(!dsi_bus_is_locked(dsi));
> -
> -	_dsi_display_enable(dsi);
> -}
> -
>  static void _dsi_display_disable(struct dsi_data *dsi,
>  		bool disconnect_lanes, bool enter_ulps)
>  {
> @@ -3856,7 +3846,7 @@ static void dsi_set_ulps_auto(struct dsi_data *dsi, bool enable)
>  			return;
>  
>  		dsi_bus_lock(dsi);
> -		_dsi_display_enable(dsi);
> +		dsi_display_enable(dsi);
>  		dsi_enable_te(dsi, true);
>  		dsi_bus_unlock(dsi);
>  	}
> @@ -4947,7 +4937,7 @@ static void dsi_bridge_enable(struct drm_bridge *bridge)
>  
>  	dsi_bus_lock(dsi);
>  
> -	dsi_display_enable(dssdev);
> +	dsi_display_enable(dsi);
>  
>  	dsi_enable_video_output(dssdev, VC_VIDEO);
>  
> -- 
> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
> Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v5 22/29] drm/omap: dsi: display_disable cleanup
  2020-12-08 12:28 ` [PATCH v5 22/29] drm/omap: dsi: display_disable cleanup Tomi Valkeinen
@ 2020-12-14 16:20   ` Sebastian Reichel
  0 siblings, 0 replies; 72+ messages in thread
From: Sebastian Reichel @ 2020-12-14 16:20 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Laurent Pinchart, Nikhil Devshatwar, dri-devel, linux-omap,
	Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg

[-- Attachment #1: Type: text/plain, Size: 2811 bytes --]

Hi,

On Tue, Dec 08, 2020 at 02:28:48PM +0200, Tomi Valkeinen wrote:
> We can drop dsi_display_disable() which just calls
> _dsi_display_disable(), and rename _dsi_display_disable() to
> dsi_display_disable().
> 
> The WARN_ON(!dsi_bus_is_locked(dsi)) in dsi_display_disable is extra and
> can be dropped, as _dsi_display_disable() has the same WARN_ON().
> 
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---

Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>

-- Sebastian

>  drivers/gpu/drm/omapdrm/dss/dsi.c | 19 +++----------------
>  1 file changed, 3 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
> index 961b991f6498..d83346812810 100644
> --- a/drivers/gpu/drm/omapdrm/dss/dsi.c
> +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
> @@ -63,8 +63,6 @@ static int dsi_vc_send_null(struct dsi_data *dsi, int vc, int channel);
>  static ssize_t _omap_dsi_host_transfer(struct dsi_data *dsi, int vc,
>  				       const struct mipi_dsi_msg *msg);
>  
> -static void dsi_display_disable(struct omap_dss_device *dssdev);
> -
>  #ifdef DSI_PERF_MEASURE
>  static bool dsi_perf;
>  module_param(dsi_perf, bool, 0644);
> @@ -3772,7 +3770,7 @@ static void dsi_display_enable(struct dsi_data *dsi)
>  	DSSDBG("dsi_display_ulps_enable FAILED\n");
>  }
>  
> -static void _dsi_display_disable(struct dsi_data *dsi,
> +static void dsi_display_disable(struct dsi_data *dsi,
>  		bool disconnect_lanes, bool enter_ulps)
>  {
>  	WARN_ON(!dsi_bus_is_locked(dsi));
> @@ -3791,17 +3789,6 @@ static void _dsi_display_disable(struct dsi_data *dsi,
>  	mutex_unlock(&dsi->lock);
>  }
>  
> -static void dsi_display_disable(struct omap_dss_device *dssdev)
> -{
> -	struct dsi_data *dsi = to_dsi_data(dssdev);
> -
> -	WARN_ON(!dsi_bus_is_locked(dsi));
> -
> -	DSSDBG("dsi_display_disable\n");
> -
> -	_dsi_display_disable(dsi, true, false);
> -}
> -
>  static int dsi_enable_te(struct dsi_data *dsi, bool enable)
>  {
>  	dsi->te_enabled = enable;
> @@ -3825,7 +3812,7 @@ static void omap_dsi_ulps_work_callback(struct work_struct *work)
>  
>  	dsi_enable_te(dsi, false);
>  
> -	_dsi_display_disable(dsi, false, true);
> +	dsi_display_disable(dsi, false, true);
>  
>  	dsi_bus_unlock(dsi);
>  }
> @@ -4959,7 +4946,7 @@ static void dsi_bridge_disable(struct drm_bridge *bridge)
>  
>  	dsi_disable_video_output(dssdev, VC_VIDEO);
>  
> -	dsi_display_disable(dssdev);
> +	dsi_display_disable(dsi, true, false);
>  
>  	dsi_bus_unlock(dsi);
>  }
> -- 
> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
> Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v5 23/29] drm/omap: dsi: rename dsi_display_* functions
  2020-12-08 12:28 ` [PATCH v5 23/29] drm/omap: dsi: rename dsi_display_* functions Tomi Valkeinen
@ 2020-12-14 16:22   ` Sebastian Reichel
  0 siblings, 0 replies; 72+ messages in thread
From: Sebastian Reichel @ 2020-12-14 16:22 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Laurent Pinchart, Nikhil Devshatwar, dri-devel, linux-omap,
	Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg

[-- Attachment #1: Type: text/plain, Size: 5750 bytes --]

Hi,

On Tue, Dec 08, 2020 at 02:28:49PM +0200, Tomi Valkeinen wrote:
> The function names have evolved to be very confusing, and bunch of them
> have "display" in them even if the function doesn't deal with display as
> such (e.g. dsi_display_enable which just enables the DSI interface).
> Rename them by dropping the "display".
> 
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---

Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>

-- Sebastian

>  drivers/gpu/drm/omapdrm/dss/dsi.c | 36 +++++++++++++++----------------
>  1 file changed, 18 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
> index d83346812810..d9c2cd849328 100644
> --- a/drivers/gpu/drm/omapdrm/dss/dsi.c
> +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
> @@ -55,8 +55,8 @@
>  
>  static void dsi_set_ulps_auto(struct dsi_data *dsi, bool enable);
>  
> -static int dsi_display_init_dispc(struct dsi_data *dsi);
> -static void dsi_display_uninit_dispc(struct dsi_data *dsi);
> +static int dsi_init_dispc(struct dsi_data *dsi);
> +static void dsi_uninit_dispc(struct dsi_data *dsi);
>  
>  static int dsi_vc_send_null(struct dsi_data *dsi, int vc, int channel);
>  
> @@ -3257,7 +3257,7 @@ static void dsi_enable_video_output(struct omap_dss_device *dssdev, int vc)
>  	u16 word_count;
>  	int r;
>  
> -	r = dsi_display_init_dispc(dsi);
> +	r = dsi_init_dispc(dsi);
>  	if (r) {
>  		dev_err(dsi->dev, "failed to init dispc!\n");
>  		return;
> @@ -3309,7 +3309,7 @@ static void dsi_enable_video_output(struct omap_dss_device *dssdev, int vc)
>  		dsi_vc_enable(dsi, vc, false);
>  	}
>  err_pix_fmt:
> -	dsi_display_uninit_dispc(dsi);
> +	dsi_uninit_dispc(dsi);
>  	dev_err(dsi->dev, "failed to enable DSI encoder!\n");
>  	return;
>  }
> @@ -3331,7 +3331,7 @@ static void dsi_disable_video_output(struct omap_dss_device *dssdev, int vc)
>  
>  	dss_mgr_disable(&dsi->output);
>  
> -	dsi_display_uninit_dispc(dsi);
> +	dsi_uninit_dispc(dsi);
>  }
>  
>  static void dsi_update_screen_dispc(struct dsi_data *dsi)
> @@ -3582,7 +3582,7 @@ static int dsi_configure_dispc_clocks(struct dsi_data *dsi)
>  	return 0;
>  }
>  
> -static int dsi_display_init_dispc(struct dsi_data *dsi)
> +static int dsi_init_dispc(struct dsi_data *dsi)
>  {
>  	enum omap_channel dispc_channel = dsi->output.dispc_channel;
>  	int r;
> @@ -3627,7 +3627,7 @@ static int dsi_display_init_dispc(struct dsi_data *dsi)
>  	return r;
>  }
>  
> -static void dsi_display_uninit_dispc(struct dsi_data *dsi)
> +static void dsi_uninit_dispc(struct dsi_data *dsi)
>  {
>  	enum omap_channel dispc_channel = dsi->output.dispc_channel;
>  
> @@ -3654,7 +3654,7 @@ static int dsi_configure_dsi_clocks(struct dsi_data *dsi)
>  	return 0;
>  }
>  
> -static int dsi_display_init_dsi(struct dsi_data *dsi)
> +static int dsi_init_dsi(struct dsi_data *dsi)
>  {
>  	int r;
>  
> @@ -3718,7 +3718,7 @@ static int dsi_display_init_dsi(struct dsi_data *dsi)
>  	return r;
>  }
>  
> -static void dsi_display_uninit_dsi(struct dsi_data *dsi, bool disconnect_lanes,
> +static void dsi_uninit_dsi(struct dsi_data *dsi, bool disconnect_lanes,
>  				   bool enter_ulps)
>  {
>  	if (enter_ulps && !dsi->ulps_enabled)
> @@ -3741,7 +3741,7 @@ static void dsi_display_uninit_dsi(struct dsi_data *dsi, bool disconnect_lanes,
>  	}
>  }
>  
> -static void dsi_display_enable(struct dsi_data *dsi)
> +static void dsi_enable(struct dsi_data *dsi)
>  {
>  	int r;
>  
> @@ -3755,7 +3755,7 @@ static void dsi_display_enable(struct dsi_data *dsi)
>  
>  	_dsi_initialize_irq(dsi);
>  
> -	r = dsi_display_init_dsi(dsi);
> +	r = dsi_init_dsi(dsi);
>  	if (r)
>  		goto err_init_dsi;
>  
> @@ -3767,10 +3767,10 @@ static void dsi_display_enable(struct dsi_data *dsi)
>  	dsi_runtime_put(dsi);
>  err_get_dsi:
>  	mutex_unlock(&dsi->lock);
> -	DSSDBG("dsi_display_ulps_enable FAILED\n");
> +	DSSDBG("dsi_enable FAILED\n");
>  }
>  
> -static void dsi_display_disable(struct dsi_data *dsi,
> +static void dsi_disable(struct dsi_data *dsi,
>  		bool disconnect_lanes, bool enter_ulps)
>  {
>  	WARN_ON(!dsi_bus_is_locked(dsi));
> @@ -3782,7 +3782,7 @@ static void dsi_display_disable(struct dsi_data *dsi,
>  	dsi_sync_vc(dsi, 2);
>  	dsi_sync_vc(dsi, 3);
>  
> -	dsi_display_uninit_dsi(dsi, disconnect_lanes, enter_ulps);
> +	dsi_uninit_dsi(dsi, disconnect_lanes, enter_ulps);
>  
>  	dsi_runtime_put(dsi);
>  
> @@ -3812,7 +3812,7 @@ static void omap_dsi_ulps_work_callback(struct work_struct *work)
>  
>  	dsi_enable_te(dsi, false);
>  
> -	dsi_display_disable(dsi, false, true);
> +	dsi_disable(dsi, false, true);
>  
>  	dsi_bus_unlock(dsi);
>  }
> @@ -3833,7 +3833,7 @@ static void dsi_set_ulps_auto(struct dsi_data *dsi, bool enable)
>  			return;
>  
>  		dsi_bus_lock(dsi);
> -		dsi_display_enable(dsi);
> +		dsi_enable(dsi);
>  		dsi_enable_te(dsi, true);
>  		dsi_bus_unlock(dsi);
>  	}
> @@ -4924,7 +4924,7 @@ static void dsi_bridge_enable(struct drm_bridge *bridge)
>  
>  	dsi_bus_lock(dsi);
>  
> -	dsi_display_enable(dsi);
> +	dsi_enable(dsi);
>  
>  	dsi_enable_video_output(dssdev, VC_VIDEO);
>  
> @@ -4946,7 +4946,7 @@ static void dsi_bridge_disable(struct drm_bridge *bridge)
>  
>  	dsi_disable_video_output(dssdev, VC_VIDEO);
>  
> -	dsi_display_disable(dsi, true, false);
> +	dsi_disable(dsi, true, false);
>  
>  	dsi_bus_unlock(dsi);
>  }
> -- 
> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
> Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v5 24/29] drm/omap: dsi: cleanup initial vc setup
  2020-12-08 12:28 ` [PATCH v5 24/29] drm/omap: dsi: cleanup initial vc setup Tomi Valkeinen
@ 2020-12-14 16:34   ` Sebastian Reichel
  0 siblings, 0 replies; 72+ messages in thread
From: Sebastian Reichel @ 2020-12-14 16:34 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Laurent Pinchart, Nikhil Devshatwar, dri-devel, linux-omap,
	Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg

[-- Attachment #1: Type: text/plain, Size: 5593 bytes --]

Hi,

On Tue, Dec 08, 2020 at 02:28:50PM +0200, Tomi Valkeinen wrote:
> As we now have a fixed setup for VCs (VC0 for video stream, VC1 for
> commands), we can simplify the VC setup.
> 
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> ---

Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>

-- Sebastian

>  drivers/gpu/drm/omapdrm/dss/dsi.c | 85 +++++++++++--------------------
>  1 file changed, 31 insertions(+), 54 deletions(-)
> 
> diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
> index d9c2cd849328..c32884f167b8 100644
> --- a/drivers/gpu/drm/omapdrm/dss/dsi.c
> +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
> @@ -2017,40 +2017,6 @@ static void dsi_vc_initial_config(struct dsi_data *dsi, int vc)
>  	dsi->vc[vc].source = DSI_VC_SOURCE_L4;
>  }
>  
> -static int dsi_vc_config_source(struct dsi_data *dsi, int vc,
> -				enum dsi_vc_source source)
> -{
> -	if (dsi->vc[vc].source == source)
> -		return 0;
> -
> -	DSSDBG("Source config of VC %d", vc);
> -
> -	dsi_sync_vc(dsi, vc);
> -
> -	dsi_vc_enable(dsi, vc, 0);
> -
> -	/* VC_BUSY */
> -	if (!wait_for_bit_change(dsi, DSI_VC_CTRL(vc), 15, 0)) {
> -		DSSERR("vc(%d) busy when trying to config for VP\n", vc);
> -		return -EIO;
> -	}
> -
> -	/* SOURCE, 0 = L4, 1 = video port */
> -	REG_FLD_MOD(dsi, DSI_VC_CTRL(vc), source, 1, 1);
> -
> -	/* DCS_CMD_ENABLE */
> -	if (dsi->data->quirks & DSI_QUIRK_DCS_CMD_CONFIG_VC) {
> -		bool enable = source == DSI_VC_SOURCE_VP;
> -		REG_FLD_MOD(dsi, DSI_VC_CTRL(vc), enable, 30, 30);
> -	}
> -
> -	dsi_vc_enable(dsi, vc, 1);
> -
> -	dsi->vc[vc].source = source;
> -
> -	return 0;
> -}
> -
>  static void dsi_vc_enable_hs(struct omap_dss_device *dssdev, int vc,
>  		bool enable)
>  {
> @@ -2072,10 +2038,6 @@ static void dsi_vc_enable_hs(struct omap_dss_device *dssdev, int vc,
>  	dsi_if_enable(dsi, 1);
>  
>  	dsi_force_tx_stop_mode_io(dsi);
> -
> -	/* start the DDR clock by sending a NULL packet */
> -	if (dsi->vm_timings.ddr_clk_always_on && enable)
> -		dsi_vc_send_null(dsi, vc, dsi->dsidev->channel);
>  }
>  
>  static void dsi_vc_flush_long_data(struct dsi_data *dsi, int vc)
> @@ -2270,8 +2232,6 @@ static int dsi_vc_send_long(struct dsi_data *dsi, int vc,
>  		return -EINVAL;
>  	}
>  
> -	dsi_vc_config_source(dsi, vc, DSI_VC_SOURCE_L4);
> -
>  	dsi_vc_write_long_header(dsi, vc, msg->channel, msg->type, msg->tx_len, 0);
>  
>  	p = msg->tx_buf;
> @@ -2331,8 +2291,6 @@ static int dsi_vc_send_short(struct dsi_data *dsi, int vc,
>  		DSSDBG("dsi_vc_send_short(ch%d, dt %#x, b1 %#x, b2 %#x)\n",
>  		       vc, msg->type, pkt.header[1], pkt.header[2]);
>  
> -	dsi_vc_config_source(dsi, vc, DSI_VC_SOURCE_L4);
> -
>  	if (FLD_GET(dsi_read_reg(dsi, DSI_VC_CTRL(vc)), 16, 16)) {
>  		DSSERR("ERROR FIFO FULL, aborting transfer\n");
>  		return -EINVAL;
> @@ -3351,8 +3309,6 @@ static void dsi_update_screen_dispc(struct dsi_data *dsi)
>  
>  	DSSDBG("dsi_update_screen_dispc(%dx%d)\n", w, h);
>  
> -	dsi_vc_config_source(dsi, vc, DSI_VC_SOURCE_VP);
> -
>  	bytespp	= mipi_dsi_pixel_format_to_bpp(dsi->pix_fmt) / 8;
>  	bytespl = w * bytespp;
>  	bytespf = bytespl * h;
> @@ -3522,14 +3478,12 @@ static int dsi_update_channel(struct omap_dss_device *dssdev, int vc)
>  
>  	dsi_set_ulps_auto(dsi, false);
>  
> -	dsi_vc_enable_hs(dssdev, vc, true);
> -
>  	/*
>  	 * Send NOP between the frames. If we don't send something here, the
>  	 * updates stop working. This is probably related to DSI spec stating
>  	 * that the DSI host should transition to LP at least once per frame.
>  	 */
> -	r = _dsi_send_nop(dsi, vc, dsi->dsidev->channel);
> +	r = _dsi_send_nop(dsi, VC_CMD, dsi->dsidev->channel);
>  	if (r < 0) {
>  		DSSWARN("failed to send nop between frames: %d\n", r);
>  		goto err;
> @@ -3654,6 +3608,35 @@ static int dsi_configure_dsi_clocks(struct dsi_data *dsi)
>  	return 0;
>  }
>  
> +static void dsi_setup_dsi_vcs(struct dsi_data *dsi)
> +{
> +	/* Setup VC_CMD for LP and cpu transfers */
> +	REG_FLD_MOD(dsi, DSI_VC_CTRL(VC_CMD), 0, 9, 9); /* LP */
> +
> +	REG_FLD_MOD(dsi, DSI_VC_CTRL(VC_CMD), 0, 1, 1); /* SOURCE_L4 */
> +	dsi->vc[VC_CMD].source = DSI_VC_SOURCE_L4;
> +
> +	/* Setup VC_VIDEO for HS and dispc transfers */
> +	REG_FLD_MOD(dsi, DSI_VC_CTRL(VC_VIDEO), 1, 9, 9); /* HS */
> +
> +	REG_FLD_MOD(dsi, DSI_VC_CTRL(VC_VIDEO), 1, 1, 1); /* SOURCE_VP */
> +	dsi->vc[VC_VIDEO].source = DSI_VC_SOURCE_VP;
> +
> +	if (dsi->data->quirks & DSI_QUIRK_DCS_CMD_CONFIG_VC)
> +		REG_FLD_MOD(dsi, DSI_VC_CTRL(VC_VIDEO), 1, 30, 30); /* DCS_CMD_ENABLE */
> +
> +	dsi_vc_enable(dsi, VC_CMD, 1);
> +	dsi_vc_enable(dsi, VC_VIDEO, 1);
> +
> +	dsi_if_enable(dsi, 1);
> +
> +	dsi_force_tx_stop_mode_io(dsi);
> +
> +	/* start the DDR clock by sending a NULL packet */
> +	if (dsi->vm_timings.ddr_clk_always_on)
> +		dsi_vc_send_null(dsi, VC_CMD, dsi->dsidev->channel);
> +}
> +
>  static int dsi_init_dsi(struct dsi_data *dsi)
>  {
>  	int r;
> @@ -3696,13 +3679,7 @@ static int dsi_init_dsi(struct dsi_data *dsi)
>  	if (r)
>  		goto err3;
>  
> -	/* enable interface */
> -	dsi_vc_enable(dsi, 0, 1);
> -	dsi_vc_enable(dsi, 1, 1);
> -	dsi_vc_enable(dsi, 2, 1);
> -	dsi_vc_enable(dsi, 3, 1);
> -	dsi_if_enable(dsi, 1);
> -	dsi_force_tx_stop_mode_io(dsi);
> +	dsi_setup_dsi_vcs(dsi);
>  
>  	return 0;
>  err3:
> -- 
> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
> Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v5 25/29] drm/omap: dsi: split video mode enable/disable into separate func
  2020-12-08 12:28 ` [PATCH v5 25/29] drm/omap: dsi: split video mode enable/disable into separate func Tomi Valkeinen
@ 2020-12-14 16:38   ` Sebastian Reichel
  0 siblings, 0 replies; 72+ messages in thread
From: Sebastian Reichel @ 2020-12-14 16:38 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Laurent Pinchart, Nikhil Devshatwar, dri-devel, linux-omap,
	Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg

[-- Attachment #1: Type: text/plain, Size: 4767 bytes --]

Hi,

On Tue, Dec 08, 2020 at 02:28:51PM +0200, Tomi Valkeinen wrote:
> Clean up the code by separating video-mode enable/disable code into
> functions of their own.
> 
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---

Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>

-- Sebastian

>  drivers/gpu/drm/omapdrm/dss/dsi.c | 101 +++++++++++++++++-------------
>  1 file changed, 57 insertions(+), 44 deletions(-)
> 
> diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
> index c32884f167b8..71de6119d2de 100644
> --- a/drivers/gpu/drm/omapdrm/dss/dsi.c
> +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
> @@ -3207,12 +3207,61 @@ static int dsi_configure_pins(struct dsi_data *dsi,
>  	return 0;
>  }
>  
> -static void dsi_enable_video_output(struct omap_dss_device *dssdev, int vc)
> +static int dsi_enable_video_mode(struct dsi_data *dsi, int vc)
>  {
> -	struct dsi_data *dsi = to_dsi_data(dssdev);
>  	int bpp = mipi_dsi_pixel_format_to_bpp(dsi->pix_fmt);
>  	u8 data_type;
>  	u16 word_count;
> +
> +	switch (dsi->pix_fmt) {
> +	case MIPI_DSI_FMT_RGB888:
> +		data_type = MIPI_DSI_PACKED_PIXEL_STREAM_24;
> +		break;
> +	case MIPI_DSI_FMT_RGB666:
> +		data_type = MIPI_DSI_PIXEL_STREAM_3BYTE_18;
> +		break;
> +	case MIPI_DSI_FMT_RGB666_PACKED:
> +		data_type = MIPI_DSI_PACKED_PIXEL_STREAM_18;
> +		break;
> +	case MIPI_DSI_FMT_RGB565:
> +		data_type = MIPI_DSI_PACKED_PIXEL_STREAM_16;
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	dsi_if_enable(dsi, false);
> +	dsi_vc_enable(dsi, vc, false);
> +
> +	/* MODE, 1 = video mode */
> +	REG_FLD_MOD(dsi, DSI_VC_CTRL(vc), 1, 4, 4);
> +
> +	word_count = DIV_ROUND_UP(dsi->vm.hactive * bpp, 8);
> +
> +	dsi_vc_write_long_header(dsi, vc, dsi->dsidev->channel, data_type,
> +			word_count, 0);
> +
> +	dsi_vc_enable(dsi, vc, true);
> +	dsi_if_enable(dsi, true);
> +
> +	return 0;
> +}
> +
> +static void dsi_disable_video_mode(struct dsi_data *dsi, int vc)
> +{
> +	dsi_if_enable(dsi, false);
> +	dsi_vc_enable(dsi, vc, false);
> +
> +	/* MODE, 0 = command mode */
> +	REG_FLD_MOD(dsi, DSI_VC_CTRL(vc), 0, 4, 4);
> +
> +	dsi_vc_enable(dsi, vc, true);
> +	dsi_if_enable(dsi, true);
> +}
> +
> +static void dsi_enable_video_output(struct omap_dss_device *dssdev, int vc)
> +{
> +	struct dsi_data *dsi = to_dsi_data(dssdev);
>  	int r;
>  
>  	r = dsi_init_dispc(dsi);
> @@ -3222,37 +3271,9 @@ static void dsi_enable_video_output(struct omap_dss_device *dssdev, int vc)
>  	}
>  
>  	if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) {
> -		switch (dsi->pix_fmt) {
> -		case MIPI_DSI_FMT_RGB888:
> -			data_type = MIPI_DSI_PACKED_PIXEL_STREAM_24;
> -			break;
> -		case MIPI_DSI_FMT_RGB666:
> -			data_type = MIPI_DSI_PIXEL_STREAM_3BYTE_18;
> -			break;
> -		case MIPI_DSI_FMT_RGB666_PACKED:
> -			data_type = MIPI_DSI_PACKED_PIXEL_STREAM_18;
> -			break;
> -		case MIPI_DSI_FMT_RGB565:
> -			data_type = MIPI_DSI_PACKED_PIXEL_STREAM_16;
> -			break;
> -		default:
> -			r = -EINVAL;
> -			goto err_pix_fmt;
> -		}
> -
> -		dsi_if_enable(dsi, false);
> -		dsi_vc_enable(dsi, vc, false);
> -
> -		/* MODE, 1 = video mode */
> -		REG_FLD_MOD(dsi, DSI_VC_CTRL(vc), 1, 4, 4);
> -
> -		word_count = DIV_ROUND_UP(dsi->vm.hactive * bpp, 8);
> -
> -		dsi_vc_write_long_header(dsi, vc, dsi->dsidev->channel, data_type,
> -				word_count, 0);
> -
> -		dsi_vc_enable(dsi, vc, true);
> -		dsi_if_enable(dsi, true);
> +		r = dsi_enable_video_mode(dsi, vc);
> +		if (r)
> +			goto err_video_mode;
>  	}
>  
>  	r = dss_mgr_enable(&dsi->output);
> @@ -3266,7 +3287,7 @@ static void dsi_enable_video_output(struct omap_dss_device *dssdev, int vc)
>  		dsi_if_enable(dsi, false);
>  		dsi_vc_enable(dsi, vc, false);
>  	}
> -err_pix_fmt:
> +err_video_mode:
>  	dsi_uninit_dispc(dsi);
>  	dev_err(dsi->dev, "failed to enable DSI encoder!\n");
>  	return;
> @@ -3276,16 +3297,8 @@ static void dsi_disable_video_output(struct omap_dss_device *dssdev, int vc)
>  {
>  	struct dsi_data *dsi = to_dsi_data(dssdev);
>  
> -	if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) {
> -		dsi_if_enable(dsi, false);
> -		dsi_vc_enable(dsi, vc, false);
> -
> -		/* MODE, 0 = command mode */
> -		REG_FLD_MOD(dsi, DSI_VC_CTRL(vc), 0, 4, 4);
> -
> -		dsi_vc_enable(dsi, vc, true);
> -		dsi_if_enable(dsi, true);
> -	}
> +	if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE)
> +		dsi_disable_video_mode(dsi, vc);
>  
>  	dss_mgr_disable(&dsi->output);
>  
> -- 
> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
> Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v5 26/29] drm/omap: dsi: fix and cleanup ddr_clk_always_on
  2020-12-08 12:28 ` [PATCH v5 26/29] drm/omap: dsi: fix and cleanup ddr_clk_always_on Tomi Valkeinen
@ 2020-12-14 16:39   ` Sebastian Reichel
  0 siblings, 0 replies; 72+ messages in thread
From: Sebastian Reichel @ 2020-12-14 16:39 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Laurent Pinchart, Nikhil Devshatwar, dri-devel, linux-omap,
	Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg

[-- Attachment #1: Type: text/plain, Size: 2799 bytes --]

Hi,

On Tue, Dec 08, 2020 at 02:28:52PM +0200, Tomi Valkeinen wrote:
> The driver ignores MIPI_DSI_CLOCK_NON_CONTINUOUS, and always uses
> non-continuous clock.
> 
> Fix this by using MIPI_DSI_CLOCK_NON_CONTINUOUS and at the same time,
> drop ddr_clk_always_on field which seems pretty useless.
> 
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---

Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>

-- Sebastian

>  drivers/gpu/drm/omapdrm/dss/dsi.c | 12 +++++-------
>  drivers/gpu/drm/omapdrm/dss/dsi.h |  2 --
>  2 files changed, 5 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
> index 71de6119d2de..cc8b169b2223 100644
> --- a/drivers/gpu/drm/omapdrm/dss/dsi.c
> +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
> @@ -1734,11 +1734,10 @@ static int dsi_cio_init(struct dsi_data *dsi)
>  
>  	dsi_cio_timings(dsi);
>  
> -	if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) {
> -		/* DDR_CLK_ALWAYS_ON */
> -		REG_FLD_MOD(dsi, DSI_CLK_CTRL,
> -			dsi->vm_timings.ddr_clk_always_on, 13, 13);
> -	}
> +	/* DDR_CLK_ALWAYS_ON */
> +	REG_FLD_MOD(dsi, DSI_CLK_CTRL,
> +		    !(dsi->dsidev->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS),
> +		    13, 13);
>  
>  	dsi->ulps_enabled = false;
>  
> @@ -3646,7 +3645,7 @@ static void dsi_setup_dsi_vcs(struct dsi_data *dsi)
>  	dsi_force_tx_stop_mode_io(dsi);
>  
>  	/* start the DDR clock by sending a NULL packet */
> -	if (dsi->vm_timings.ddr_clk_always_on)
> +	if (!(dsi->dsidev->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS))
>  		dsi_vc_send_null(dsi, VC_CMD, dsi->dsidev->channel);
>  }
>  
> @@ -4155,7 +4154,6 @@ static bool dsi_vm_calc_blanking(struct dsi_clk_calc_ctx *ctx)
>  	dsi_vm->hfp_blanking_mode = 1;
>  	dsi_vm->hbp_blanking_mode = 1;
>  
> -	dsi_vm->ddr_clk_always_on = cfg->ddr_clk_always_on;
>  	dsi_vm->window_sync = 4;
>  
>  	/* setup DISPC videomode */
> diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.h b/drivers/gpu/drm/omapdrm/dss/dsi.h
> index 478fc10bd18d..476069fda082 100644
> --- a/drivers/gpu/drm/omapdrm/dss/dsi.h
> +++ b/drivers/gpu/drm/omapdrm/dss/dsi.h
> @@ -212,7 +212,6 @@ struct omap_dss_dsi_videomode_timings {
>  
>  	enum omap_dss_dsi_trans_mode trans_mode;
>  
> -	bool ddr_clk_always_on;
>  	int window_sync;
>  };
>  
> @@ -224,7 +223,6 @@ struct omap_dss_dsi_config {
>  	unsigned long hs_clk_min, hs_clk_max;
>  	unsigned long lp_clk_min, lp_clk_max;
>  
> -	bool ddr_clk_always_on;
>  	enum omap_dss_dsi_trans_mode trans_mode;
>  };
>  
> -- 
> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
> Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v5 28/29] drm/omap: dsi: fix DCS_CMD_ENABLE
  2020-12-08 12:28 ` [PATCH v5 28/29] drm/omap: dsi: fix DCS_CMD_ENABLE Tomi Valkeinen
@ 2020-12-14 16:48   ` Sebastian Reichel
  0 siblings, 0 replies; 72+ messages in thread
From: Sebastian Reichel @ 2020-12-14 16:48 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Laurent Pinchart, Nikhil Devshatwar, dri-devel, linux-omap,
	Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg

[-- Attachment #1: Type: text/plain, Size: 1537 bytes --]

Hi,

On Tue, Dec 08, 2020 at 02:28:54PM +0200, Tomi Valkeinen wrote:
> We only need to set VC_CTRL:DCS_CMD_ENABLE for command mode panels when
> the HW has DSI_QUIRK_DCS_CMD_CONFIG_VC quirk. The old code did this
> right by accident, but now we set DCS_CMD_ENABLE for video mode panels
> too.
> 
> Fix this by skipping the set for video mode.
> 
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---

Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>

-- Sebastian

>  drivers/gpu/drm/omapdrm/dss/dsi.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
> index b2aa07a09dcd..53a64bc91867 100644
> --- a/drivers/gpu/drm/omapdrm/dss/dsi.c
> +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
> @@ -3406,7 +3406,8 @@ static void dsi_setup_dsi_vcs(struct dsi_data *dsi)
>  	REG_FLD_MOD(dsi, DSI_VC_CTRL(VC_VIDEO), 1, 1, 1); /* SOURCE_VP */
>  	dsi->vc[VC_VIDEO].source = DSI_VC_SOURCE_VP;
>  
> -	if (dsi->data->quirks & DSI_QUIRK_DCS_CMD_CONFIG_VC)
> +	if ((dsi->data->quirks & DSI_QUIRK_DCS_CMD_CONFIG_VC) &&
> +	    !(dsi->dsidev->mode_flags & MIPI_DSI_MODE_VIDEO))
>  		REG_FLD_MOD(dsi, DSI_VC_CTRL(VC_VIDEO), 1, 30, 30); /* DCS_CMD_ENABLE */
>  
>  	dsi_vc_enable(dsi, VC_CMD, 1);
> -- 
> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
> Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v5 29/29] drm/omap: dsi: allow DSI commands to be sent early
  2020-12-08 12:28 ` [PATCH v5 29/29] drm/omap: dsi: allow DSI commands to be sent early Tomi Valkeinen
  2020-12-08 15:48   ` Laurent Pinchart
@ 2020-12-14 17:17   ` Sebastian Reichel
  2020-12-15 10:05     ` Tomi Valkeinen
  1 sibling, 1 reply; 72+ messages in thread
From: Sebastian Reichel @ 2020-12-14 17:17 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Laurent Pinchart, Nikhil Devshatwar, dri-devel, linux-omap,
	Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg

[-- Attachment #1: Type: text/plain, Size: 5383 bytes --]

Hi,

On Tue, Dec 08, 2020 at 02:28:55PM +0200, Tomi Valkeinen wrote:
> Panel drivers can send DSI commands in panel's prepare(), which happens
> before the bridge's enable() is called. The OMAP DSI driver currently
> only sets up the DSI interface at bridge's enable(), so prepare() cannot
> be used to send DSI commands.
> 
> This patch fixes the issue by making it possible to enable the DSI
> interface any time a command is about to be sent. Disabling the
> interface is be done via delayed work.
> 
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> ---

Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>

Would be nice to include the information why locking is ok from your
reply mails to the patch description. It was helpful for reviewing
the patch :)

-- Sebastian

>  drivers/gpu/drm/omapdrm/dss/dsi.c | 49 +++++++++++++++++++++++++++----
>  drivers/gpu/drm/omapdrm/dss/dsi.h |  3 ++
>  2 files changed, 47 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
> index 53a64bc91867..34f665aa9a59 100644
> --- a/drivers/gpu/drm/omapdrm/dss/dsi.c
> +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
> @@ -3503,6 +3503,9 @@ static void dsi_enable(struct dsi_data *dsi)
>  
>  	WARN_ON(!dsi_bus_is_locked(dsi));
>  
> +	if (WARN_ON(dsi->iface_enabled))
> +		return;
> +
>  	mutex_lock(&dsi->lock);
>  
>  	r = dsi_runtime_get(dsi);
> @@ -3515,6 +3518,8 @@ static void dsi_enable(struct dsi_data *dsi)
>  	if (r)
>  		goto err_init_dsi;
>  
> +	dsi->iface_enabled = true;
> +
>  	mutex_unlock(&dsi->lock);
>  
>  	return;
> @@ -3530,6 +3535,9 @@ static void dsi_disable(struct dsi_data *dsi)
>  {
>  	WARN_ON(!dsi_bus_is_locked(dsi));
>  
> +	if (WARN_ON(!dsi->iface_enabled))
> +		return;
> +
>  	mutex_lock(&dsi->lock);
>  
>  	dsi_sync_vc(dsi, 0);
> @@ -3541,6 +3549,8 @@ static void dsi_disable(struct dsi_data *dsi)
>  
>  	dsi_runtime_put(dsi);
>  
> +	dsi->iface_enabled = false;
> +
>  	mutex_unlock(&dsi->lock);
>  }
>  
> @@ -4229,10 +4239,12 @@ static ssize_t omap_dsi_host_transfer(struct mipi_dsi_host *host,
>  
>  	dsi_bus_lock(dsi);
>  
> -	if (dsi->video_enabled)
> -		r = _omap_dsi_host_transfer(dsi, vc, msg);
> -	else
> -		r = -EIO;
> +	if (!dsi->iface_enabled) {
> +		dsi_enable(dsi);
> +		schedule_delayed_work(&dsi->dsi_disable_work, msecs_to_jiffies(2000));
> +	}
> +
> +	r = _omap_dsi_host_transfer(dsi, vc, msg);
>  
>  	dsi_bus_unlock(dsi);
>  
> @@ -4397,6 +4409,14 @@ static int omap_dsi_host_detach(struct mipi_dsi_host *host,
>  	if (WARN_ON(dsi->dsidev != client))
>  		return -EINVAL;
>  
> +	cancel_delayed_work_sync(&dsi->dsi_disable_work);
> +
> +	if (dsi->iface_enabled) {
> +		dsi_bus_lock(dsi);
> +		dsi_disable(dsi);
> +		dsi_bus_unlock(dsi);
> +	}
> +
>  	omap_dsi_unregister_te_irq(dsi);
>  	dsi->dsidev = NULL;
>  	return 0;
> @@ -4632,9 +4652,12 @@ static void dsi_bridge_enable(struct drm_bridge *bridge)
>  	struct dsi_data *dsi = drm_bridge_to_dsi(bridge);
>  	struct omap_dss_device *dssdev = &dsi->output;
>  
> +	cancel_delayed_work_sync(&dsi->dsi_disable_work);
> +
>  	dsi_bus_lock(dsi);
>  
> -	dsi_enable(dsi);
> +	if (!dsi->iface_enabled)
> +		dsi_enable(dsi);
>  
>  	dsi_enable_video_output(dssdev, VC_VIDEO);
>  
> @@ -4648,6 +4671,8 @@ static void dsi_bridge_disable(struct drm_bridge *bridge)
>  	struct dsi_data *dsi = drm_bridge_to_dsi(bridge);
>  	struct omap_dss_device *dssdev = &dsi->output;
>  
> +	cancel_delayed_work_sync(&dsi->dsi_disable_work);
> +
>  	dsi_bus_lock(dsi);
>  
>  	dsi->video_enabled = false;
> @@ -4840,6 +4865,18 @@ static const struct soc_device_attribute dsi_soc_devices[] = {
>  	{ /* sentinel */ }
>  };
>  
> +static void omap_dsi_disable_work_callback(struct work_struct *work)
> +{
> +	struct dsi_data *dsi = container_of(work, struct dsi_data, dsi_disable_work.work);
> +
> +	dsi_bus_lock(dsi);
> +
> +	if (dsi->iface_enabled && !dsi->video_enabled)
> +		dsi_disable(dsi);
> +
> +	dsi_bus_unlock(dsi);
> +}
> +
>  static int dsi_probe(struct platform_device *pdev)
>  {
>  	const struct soc_device_attribute *soc;
> @@ -4873,6 +4910,8 @@ static int dsi_probe(struct platform_device *pdev)
>  	INIT_DEFERRABLE_WORK(&dsi->framedone_timeout_work,
>  			     dsi_framedone_timeout_work_callback);
>  
> +	INIT_DEFERRABLE_WORK(&dsi->dsi_disable_work, omap_dsi_disable_work_callback);
> +
>  #ifdef DSI_CATCH_MISSING_TE
>  	timer_setup(&dsi->te_timer, dsi_te_timeout, 0);
>  #endif
> diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.h b/drivers/gpu/drm/omapdrm/dss/dsi.h
> index de9411067ba2..601707c0ecc4 100644
> --- a/drivers/gpu/drm/omapdrm/dss/dsi.h
> +++ b/drivers/gpu/drm/omapdrm/dss/dsi.h
> @@ -394,6 +394,7 @@ struct dsi_data {
>  	atomic_t do_ext_te_update;
>  
>  	bool te_enabled;
> +	bool iface_enabled;
>  	bool video_enabled;
>  
>  	struct delayed_work framedone_timeout_work;
> @@ -443,6 +444,8 @@ struct dsi_data {
>  
>  	struct omap_dss_device output;
>  	struct drm_bridge bridge;
> +
> +	struct delayed_work dsi_disable_work;
>  };
>  
>  struct dsi_packet_sent_handler_data {
> -- 
> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
> Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v5 27/29] drm/omap: dsi: remove ulps support
  2020-12-08 12:28 ` [PATCH v5 27/29] drm/omap: dsi: remove ulps support Tomi Valkeinen
@ 2020-12-14 17:39   ` Sebastian Reichel
  2020-12-14 18:55     ` Tomi Valkeinen
  0 siblings, 1 reply; 72+ messages in thread
From: Sebastian Reichel @ 2020-12-14 17:39 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Laurent Pinchart, Nikhil Devshatwar, dri-devel, Tony Lindgren,
	hns, Sekhar Nori, linux-omap, Sam Ravnborg

[-- Attachment #1: Type: text/plain, Size: 15086 bytes --]

Hi,

On Tue, Dec 08, 2020 at 02:28:53PM +0200, Tomi Valkeinen wrote:
> ULPS doesn't work, and I have been unable to get it to work. As ULPS
> is a minor power-saving feature which requires substantial amount of
> non-trivial code, and we have trouble just getting and
> keeping DSI working at all, remove ULPS support.
>
> When the DSI driver works reliably for command and video mode displays,
> someone interested can add it back.
> 
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---

Is it really 'minor power-saving'? If I search for DSI and ULPS among
the first results is a TI datasheet for SN65DSI84, which claims device
active current in the more than 100mA range and ULPS current in the
less than 10mA range.

Considering all known omapdrm DSI users are battery powered devices
caring for saving as much power as possible, it might be good to just
keep this until it is being fixed considering this is very close to
the end of the series anyways?

-- Sebastian

>  drivers/gpu/drm/omapdrm/dss/dsi.c | 297 +-----------------------------
>  drivers/gpu/drm/omapdrm/dss/dsi.h |   4 -
>  2 files changed, 8 insertions(+), 293 deletions(-)
> 
> diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
> index cc8b169b2223..b2aa07a09dcd 100644
> --- a/drivers/gpu/drm/omapdrm/dss/dsi.c
> +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
> @@ -53,8 +53,6 @@
>  #define REG_FLD_MOD(dsi, idx, val, start, end) \
>  	dsi_write_reg(dsi, idx, FLD_MOD(dsi_read_reg(dsi, idx), val, start, end))
>  
> -static void dsi_set_ulps_auto(struct dsi_data *dsi, bool enable);
> -
>  static int dsi_init_dispc(struct dsi_data *dsi);
>  static void dsi_uninit_dispc(struct dsi_data *dsi);
>  
> @@ -688,44 +686,6 @@ static int dsi_unregister_isr_vc(struct dsi_data *dsi, int vc,
>  	return r;
>  }
>  
> -static int dsi_register_isr_cio(struct dsi_data *dsi, omap_dsi_isr_t isr,
> -				void *arg, u32 mask)
> -{
> -	unsigned long flags;
> -	int r;
> -
> -	spin_lock_irqsave(&dsi->irq_lock, flags);
> -
> -	r = _dsi_register_isr(isr, arg, mask, dsi->isr_tables.isr_table_cio,
> -			ARRAY_SIZE(dsi->isr_tables.isr_table_cio));
> -
> -	if (r == 0)
> -		_omap_dsi_set_irqs_cio(dsi);
> -
> -	spin_unlock_irqrestore(&dsi->irq_lock, flags);
> -
> -	return r;
> -}
> -
> -static int dsi_unregister_isr_cio(struct dsi_data *dsi, omap_dsi_isr_t isr,
> -				  void *arg, u32 mask)
> -{
> -	unsigned long flags;
> -	int r;
> -
> -	spin_lock_irqsave(&dsi->irq_lock, flags);
> -
> -	r = _dsi_unregister_isr(isr, arg, mask, dsi->isr_tables.isr_table_cio,
> -			ARRAY_SIZE(dsi->isr_tables.isr_table_cio));
> -
> -	if (r == 0)
> -		_omap_dsi_set_irqs_cio(dsi);
> -
> -	spin_unlock_irqrestore(&dsi->irq_lock, flags);
> -
> -	return r;
> -}
> -
>  static u32 dsi_get_errors(struct dsi_data *dsi)
>  {
>  	unsigned long flags;
> @@ -1450,56 +1410,6 @@ static void dsi_cio_timings(struct dsi_data *dsi)
>  	dsi_write_reg(dsi, DSI_DSIPHY_CFG2, r);
>  }
>  
> -/* lane masks have lane 0 at lsb. mask_p for positive lines, n for negative */
> -static void dsi_cio_enable_lane_override(struct dsi_data *dsi,
> -					 unsigned int mask_p,
> -					 unsigned int mask_n)
> -{
> -	int i;
> -	u32 l;
> -	u8 lptxscp_start = dsi->num_lanes_supported == 3 ? 22 : 26;
> -
> -	l = 0;
> -
> -	for (i = 0; i < dsi->num_lanes_supported; ++i) {
> -		unsigned int p = dsi->lanes[i].polarity;
> -
> -		if (mask_p & (1 << i))
> -			l |= 1 << (i * 2 + (p ? 0 : 1));
> -
> -		if (mask_n & (1 << i))
> -			l |= 1 << (i * 2 + (p ? 1 : 0));
> -	}
> -
> -	/*
> -	 * Bits in REGLPTXSCPDAT4TO0DXDY:
> -	 * 17: DY0 18: DX0
> -	 * 19: DY1 20: DX1
> -	 * 21: DY2 22: DX2
> -	 * 23: DY3 24: DX3
> -	 * 25: DY4 26: DX4
> -	 */
> -
> -	/* Set the lane override configuration */
> -
> -	/* REGLPTXSCPDAT4TO0DXDY */
> -	REG_FLD_MOD(dsi, DSI_DSIPHY_CFG10, l, lptxscp_start, 17);
> -
> -	/* Enable lane override */
> -
> -	/* ENLPTXSCPDAT */
> -	REG_FLD_MOD(dsi, DSI_DSIPHY_CFG10, 1, 27, 27);
> -}
> -
> -static void dsi_cio_disable_lane_override(struct dsi_data *dsi)
> -{
> -	/* Disable lane override */
> -	REG_FLD_MOD(dsi, DSI_DSIPHY_CFG10, 0, 27, 27); /* ENLPTXSCPDAT */
> -	/* Reset the lane override configuration */
> -	/* REGLPTXSCPDAT4TO0DXDY */
> -	REG_FLD_MOD(dsi, DSI_DSIPHY_CFG10, 0, 22, 17);
> -}
> -
>  static int dsi_cio_wait_tx_clk_esc_reset(struct dsi_data *dsi)
>  {
>  	int t, i;
> @@ -1674,32 +1584,6 @@ static int dsi_cio_init(struct dsi_data *dsi)
>  	l = FLD_MOD(l, 0x1fff, 12, 0);	/* STOP_STATE_COUNTER_IO */
>  	dsi_write_reg(dsi, DSI_TIMING1, l);
>  
> -	if (dsi->ulps_enabled) {
> -		unsigned int mask_p;
> -		int i;
> -
> -		DSSDBG("manual ulps exit\n");
> -
> -		/* ULPS is exited by Mark-1 state for 1ms, followed by
> -		 * stop state. DSS HW cannot do this via the normal
> -		 * ULPS exit sequence, as after reset the DSS HW thinks
> -		 * that we are not in ULPS mode, and refuses to send the
> -		 * sequence. So we need to send the ULPS exit sequence
> -		 * manually by setting positive lines high and negative lines
> -		 * low for 1ms.
> -		 */
> -
> -		mask_p = 0;
> -
> -		for (i = 0; i < dsi->num_lanes_supported; ++i) {
> -			if (dsi->lanes[i].function == DSI_LANE_UNUSED)
> -				continue;
> -			mask_p |= 1 << i;
> -		}
> -
> -		dsi_cio_enable_lane_override(dsi, mask_p, 0);
> -	}
> -
>  	r = dsi_cio_power(dsi, DSI_COMPLEXIO_POWER_ON);
>  	if (r)
>  		goto err_cio_pwr;
> @@ -1718,17 +1602,6 @@ static int dsi_cio_init(struct dsi_data *dsi)
>  	if (r)
>  		goto err_tx_clk_esc_rst;
>  
> -	if (dsi->ulps_enabled) {
> -		/* Keep Mark-1 state for 1ms (as per DSI spec) */
> -		ktime_t wait = ns_to_ktime(1000 * 1000);
> -		set_current_state(TASK_UNINTERRUPTIBLE);
> -		schedule_hrtimeout(&wait, HRTIMER_MODE_REL);
> -
> -		/* Disable the override. The lanes should be set to Mark-11
> -		 * state by the HW */
> -		dsi_cio_disable_lane_override(dsi);
> -	}
> -
>  	/* FORCE_TX_STOP_MODE_IO */
>  	REG_FLD_MOD(dsi, DSI_TIMING1, 0, 15, 15);
>  
> @@ -1739,8 +1612,6 @@ static int dsi_cio_init(struct dsi_data *dsi)
>  		    !(dsi->dsidev->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS),
>  		    13, 13);
>  
> -	dsi->ulps_enabled = false;
> -
>  	DSSDBG("CIO init done\n");
>  
>  	return 0;
> @@ -1750,8 +1621,6 @@ static int dsi_cio_init(struct dsi_data *dsi)
>  err_cio_pwr_dom:
>  	dsi_cio_power(dsi, DSI_COMPLEXIO_POWER_OFF);
>  err_cio_pwr:
> -	if (dsi->ulps_enabled)
> -		dsi_cio_disable_lane_override(dsi);
>  err_scp_clk_dom:
>  	dsi_disable_scp_clk(dsi);
>  	dsi_disable_pads(dsi);
> @@ -2522,99 +2391,6 @@ static int dsi_vc_generic_read(struct omap_dss_device *dssdev, int vc,
>  	return r;
>  }
>  
> -static int dsi_enter_ulps(struct dsi_data *dsi)
> -{
> -	DECLARE_COMPLETION_ONSTACK(completion);
> -	int r, i;
> -	unsigned int mask;
> -
> -	DSSDBG("Entering ULPS");
> -
> -	WARN_ON(!dsi_bus_is_locked(dsi));
> -
> -	WARN_ON(dsi->ulps_enabled);
> -
> -	if (dsi->ulps_enabled)
> -		return 0;
> -
> -	/* DDR_CLK_ALWAYS_ON */
> -	if (REG_GET(dsi, DSI_CLK_CTRL, 13, 13)) {
> -		dsi_if_enable(dsi, 0);
> -		REG_FLD_MOD(dsi, DSI_CLK_CTRL, 0, 13, 13);
> -		dsi_if_enable(dsi, 1);
> -	}
> -
> -	dsi_sync_vc(dsi, 0);
> -	dsi_sync_vc(dsi, 1);
> -	dsi_sync_vc(dsi, 2);
> -	dsi_sync_vc(dsi, 3);
> -
> -	dsi_force_tx_stop_mode_io(dsi);
> -
> -	dsi_vc_enable(dsi, 0, false);
> -	dsi_vc_enable(dsi, 1, false);
> -	dsi_vc_enable(dsi, 2, false);
> -	dsi_vc_enable(dsi, 3, false);
> -
> -	if (REG_GET(dsi, DSI_COMPLEXIO_CFG2, 16, 16)) {	/* HS_BUSY */
> -		DSSERR("HS busy when enabling ULPS\n");
> -		return -EIO;
> -	}
> -
> -	if (REG_GET(dsi, DSI_COMPLEXIO_CFG2, 17, 17)) {	/* LP_BUSY */
> -		DSSERR("LP busy when enabling ULPS\n");
> -		return -EIO;
> -	}
> -
> -	r = dsi_register_isr_cio(dsi, dsi_completion_handler, &completion,
> -			DSI_CIO_IRQ_ULPSACTIVENOT_ALL0);
> -	if (r)
> -		return r;
> -
> -	mask = 0;
> -
> -	for (i = 0; i < dsi->num_lanes_supported; ++i) {
> -		if (dsi->lanes[i].function == DSI_LANE_UNUSED)
> -			continue;
> -		mask |= 1 << i;
> -	}
> -	/* Assert TxRequestEsc for data lanes and TxUlpsClk for clk lane */
> -	/* LANEx_ULPS_SIG2 */
> -	REG_FLD_MOD(dsi, DSI_COMPLEXIO_CFG2, mask, 9, 5);
> -
> -	/* flush posted write and wait for SCP interface to finish the write */
> -	dsi_read_reg(dsi, DSI_COMPLEXIO_CFG2);
> -
> -	if (wait_for_completion_timeout(&completion,
> -				msecs_to_jiffies(1000)) == 0) {
> -		DSSERR("ULPS enable timeout\n");
> -		r = -EIO;
> -		goto err;
> -	}
> -
> -	dsi_unregister_isr_cio(dsi, dsi_completion_handler, &completion,
> -			DSI_CIO_IRQ_ULPSACTIVENOT_ALL0);
> -
> -	/* Reset LANEx_ULPS_SIG2 */
> -	REG_FLD_MOD(dsi, DSI_COMPLEXIO_CFG2, 0, 9, 5);
> -
> -	/* flush posted write and wait for SCP interface to finish the write */
> -	dsi_read_reg(dsi, DSI_COMPLEXIO_CFG2);
> -
> -	dsi_cio_power(dsi, DSI_COMPLEXIO_POWER_ULPS);
> -
> -	dsi_if_enable(dsi, false);
> -
> -	dsi->ulps_enabled = true;
> -
> -	return 0;
> -
> -err:
> -	dsi_unregister_isr_cio(dsi, dsi_completion_handler, &completion,
> -			DSI_CIO_IRQ_ULPSACTIVENOT_ALL0);
> -	return r;
> -}
> -
>  static void dsi_set_lp_rx_timeout(struct dsi_data *dsi, unsigned int ticks,
>  				  bool x4, bool x16)
>  {
> @@ -3397,7 +3173,6 @@ static void dsi_handle_framedone(struct dsi_data *dsi, int error)
>  		REG_FLD_MOD(dsi, DSI_TIMING2, 1, 15, 15); /* LP_RX_TO */
>  	}
>  
> -	dsi_set_ulps_auto(dsi, true);
>  	dsi_bus_unlock(dsi);
>  
>  	if (!error)
> @@ -3488,8 +3263,6 @@ static int dsi_update_channel(struct omap_dss_device *dssdev, int vc)
>  
>  	DSSDBG("dsi_update_channel: %d", vc);
>  
> -	dsi_set_ulps_auto(dsi, false);
> -
>  	/*
>  	 * Send NOP between the frames. If we don't send something here, the
>  	 * updates stop working. This is probably related to DSI spec stating
> @@ -3514,7 +3287,6 @@ static int dsi_update_channel(struct omap_dss_device *dssdev, int vc)
>  	return 0;
>  
>  err:
> -	dsi_set_ulps_auto(dsi, true);
>  	dsi_bus_unlock(dsi);
>  	return r;
>  }
> @@ -3707,12 +3479,8 @@ static int dsi_init_dsi(struct dsi_data *dsi)
>  	return r;
>  }
>  
> -static void dsi_uninit_dsi(struct dsi_data *dsi, bool disconnect_lanes,
> -				   bool enter_ulps)
> +static void dsi_uninit_dsi(struct dsi_data *dsi)
>  {
> -	if (enter_ulps && !dsi->ulps_enabled)
> -		dsi_enter_ulps(dsi);
> -
>  	/* disable interface */
>  	dsi_if_enable(dsi, 0);
>  	dsi_vc_enable(dsi, 0, 0);
> @@ -3724,10 +3492,8 @@ static void dsi_uninit_dsi(struct dsi_data *dsi, bool disconnect_lanes,
>  	dsi_cio_uninit(dsi);
>  	dss_pll_disable(&dsi->pll);
>  
> -	if (disconnect_lanes) {
> -		regulator_disable(dsi->vdds_dsi_reg);
> -		dsi->vdds_dsi_enabled = false;
> -	}
> +	regulator_disable(dsi->vdds_dsi_reg);
> +	dsi->vdds_dsi_enabled = false;
>  }
>  
>  static void dsi_enable(struct dsi_data *dsi)
> @@ -3759,8 +3525,7 @@ static void dsi_enable(struct dsi_data *dsi)
>  	DSSDBG("dsi_enable FAILED\n");
>  }
>  
> -static void dsi_disable(struct dsi_data *dsi,
> -		bool disconnect_lanes, bool enter_ulps)
> +static void dsi_disable(struct dsi_data *dsi)
>  {
>  	WARN_ON(!dsi_bus_is_locked(dsi));
>  
> @@ -3771,7 +3536,7 @@ static void dsi_disable(struct dsi_data *dsi,
>  	dsi_sync_vc(dsi, 2);
>  	dsi_sync_vc(dsi, 3);
>  
> -	dsi_uninit_dsi(dsi, disconnect_lanes, enter_ulps);
> +	dsi_uninit_dsi(dsi);
>  
>  	dsi_runtime_put(dsi);
>  
> @@ -3792,42 +3557,6 @@ static int dsi_enable_te(struct dsi_data *dsi, bool enable)
>  	return 0;
>  }
>  
> -static void omap_dsi_ulps_work_callback(struct work_struct *work)
> -{
> -	struct dsi_data *dsi = container_of(work, struct dsi_data,
> -					    ulps_work.work);
> -
> -	dsi_bus_lock(dsi);
> -
> -	dsi_enable_te(dsi, false);
> -
> -	dsi_disable(dsi, false, true);
> -
> -	dsi_bus_unlock(dsi);
> -}
> -
> -static void dsi_set_ulps_auto(struct dsi_data *dsi, bool enable)
> -{
> -	WARN_ON(!dsi_bus_is_locked(dsi));
> -
> -	if (!dsi->ulps_auto_idle)
> -		return;
> -
> -	if (enable) {
> -		schedule_delayed_work(&dsi->ulps_work, msecs_to_jiffies(250));
> -	} else {
> -		cancel_delayed_work_sync(&dsi->ulps_work);
> -
> -		if (!dsi->ulps_enabled)
> -			return;
> -
> -		dsi_bus_lock(dsi);
> -		dsi_enable(dsi);
> -		dsi_enable_te(dsi, true);
> -		dsi_bus_unlock(dsi);
> -	}
> -}
> -
>  #ifdef PRINT_VERBOSE_VM_TIMINGS
>  static void print_dsi_vm(const char *str,
>  		const struct omap_dss_dsi_videomode_timings *t)
> @@ -4499,13 +4228,10 @@ static ssize_t omap_dsi_host_transfer(struct mipi_dsi_host *host,
>  
>  	dsi_bus_lock(dsi);
>  
> -	if (dsi->video_enabled) {
> -		dsi_set_ulps_auto(dsi, false);
> +	if (dsi->video_enabled)
>  		r = _omap_dsi_host_transfer(dsi, vc, msg);
> -		dsi_set_ulps_auto(dsi, true);
> -	} else {
> +	else
>  		r = -EIO;
> -	}
>  
>  	dsi_bus_unlock(dsi);
>  
> @@ -4647,9 +4373,6 @@ static int omap_dsi_host_attach(struct mipi_dsi_host *host,
>  	dsi->dsidev = client;
>  	dsi->pix_fmt = client->format;
>  
> -	INIT_DEFERRABLE_WORK(&dsi->ulps_work,
> -			     omap_dsi_ulps_work_callback);
> -
>  	dsi->config.hs_clk_min = 150000000; // TODO: get from client?
>  	dsi->config.hs_clk_max = client->hs_rate;
>  	dsi->config.lp_clk_min = 7000000; // TODO: get from client?
> @@ -4662,8 +4385,6 @@ static int omap_dsi_host_attach(struct mipi_dsi_host *host,
>  	else
>  		dsi->config.trans_mode = OMAP_DSS_DSI_EVENT_MODE;
>  
> -	dsi->ulps_auto_idle = false;
> -
>  	return 0;
>  }
>  
> @@ -4918,8 +4639,6 @@ static void dsi_bridge_enable(struct drm_bridge *bridge)
>  
>  	dsi->video_enabled = true;
>  
> -	dsi_set_ulps_auto(dsi, true);
> -
>  	dsi_bus_unlock(dsi);
>  }
>  
> @@ -4934,7 +4653,7 @@ static void dsi_bridge_disable(struct drm_bridge *bridge)
>  
>  	dsi_disable_video_output(dssdev, VC_VIDEO);
>  
> -	dsi_disable(dsi, true, false);
> +	dsi_disable(dsi);
>  
>  	dsi_bus_unlock(dsi);
>  }
> diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.h b/drivers/gpu/drm/omapdrm/dss/dsi.h
> index 476069fda082..de9411067ba2 100644
> --- a/drivers/gpu/drm/omapdrm/dss/dsi.h
> +++ b/drivers/gpu/drm/omapdrm/dss/dsi.h
> @@ -394,12 +394,8 @@ struct dsi_data {
>  	atomic_t do_ext_te_update;
>  
>  	bool te_enabled;
> -	bool ulps_enabled;
> -	bool ulps_auto_idle;
>  	bool video_enabled;
>  
> -	struct delayed_work ulps_work;
> -
>  	struct delayed_work framedone_timeout_work;
>  
>  #ifdef DSI_CATCH_MISSING_TE
> -- 
> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
> Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v5 27/29] drm/omap: dsi: remove ulps support
  2020-12-14 17:39   ` Sebastian Reichel
@ 2020-12-14 18:55     ` Tomi Valkeinen
  2020-12-14 22:08       ` Sebastian Reichel
  0 siblings, 1 reply; 72+ messages in thread
From: Tomi Valkeinen @ 2020-12-14 18:55 UTC (permalink / raw)
  To: Sebastian Reichel
  Cc: Laurent Pinchart, Nikhil Devshatwar, dri-devel, Tony Lindgren,
	hns, Sekhar Nori, linux-omap, Sam Ravnborg

On 14/12/2020 19:39, Sebastian Reichel wrote:
> Hi,
> 
> On Tue, Dec 08, 2020 at 02:28:53PM +0200, Tomi Valkeinen wrote:
>> ULPS doesn't work, and I have been unable to get it to work. As ULPS
>> is a minor power-saving feature which requires substantial amount of
>> non-trivial code, and we have trouble just getting and
>> keeping DSI working at all, remove ULPS support.
>>
>> When the DSI driver works reliably for command and video mode displays,
>> someone interested can add it back.
>>
>> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
>> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
>> ---
> 
> Is it really 'minor power-saving'? If I search for DSI and ULPS among
> the first results is a TI datasheet for SN65DSI84, which claims device
> active current in the more than 100mA range and ULPS current in the
> less than 10mA range.

I don't have any numbers, just my guesses. For videomode displays or command mode displays in active
use, I don't think ULPS matters much. The link is mostly not in ULPS. And if the display is blanked,
things are off, so again not in ULPS.

It's only for command mode displays, when updated rarely, where I think ULPS matters. Which, of
course, is probably not unusual use case if you have a cmdmode display. But whether OMAP DSI power
savings matches SN65DSI84, I have no clue.

> Considering all known omapdrm DSI users are battery powered devices
> caring for saving as much power as possible, it might be good to just
> keep this until it is being fixed considering this is very close to
> the end of the series anyways?

I don't like to leave known to be broken code around, unless someone has plans to work on it. I
wouldn't be surprised to see ULPS still broken two years from now =). It should be trivial to add
the relevant bits back later.

But I can leave it here if you think it's better, presuming it doesn't have bigger conflicts with
the 29/29 or break anything. However, I have only a few days left in TI, which is why I'm rushing
here a bit (*). If I hit problems, I either have to drop the whole series, or push it in its current
form.

 Tomi

(*) But I will fix possible issues caused by my push, of course.

-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v5 27/29] drm/omap: dsi: remove ulps support
  2020-12-14 18:55     ` Tomi Valkeinen
@ 2020-12-14 22:08       ` Sebastian Reichel
  0 siblings, 0 replies; 72+ messages in thread
From: Sebastian Reichel @ 2020-12-14 22:08 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Laurent Pinchart, Nikhil Devshatwar, dri-devel, Tony Lindgren,
	hns, Sekhar Nori, linux-omap, Sam Ravnborg

[-- Attachment #1: Type: text/plain, Size: 3190 bytes --]

Hi,

On Mon, Dec 14, 2020 at 08:55:36PM +0200, Tomi Valkeinen wrote:
> On 14/12/2020 19:39, Sebastian Reichel wrote:
> > Hi,
> > 
> > On Tue, Dec 08, 2020 at 02:28:53PM +0200, Tomi Valkeinen wrote:
> >> ULPS doesn't work, and I have been unable to get it to work. As ULPS
> >> is a minor power-saving feature which requires substantial amount of
> >> non-trivial code, and we have trouble just getting and
> >> keeping DSI working at all, remove ULPS support.
> >>
> >> When the DSI driver works reliably for command and video mode displays,
> >> someone interested can add it back.
> >>
> >> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> >> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> >> ---
> > 
> > Is it really 'minor power-saving'? If I search for DSI and ULPS among
> > the first results is a TI datasheet for SN65DSI84, which claims device
> > active current in the more than 100mA range and ULPS current in the
> > less than 10mA range.
> 
> I don't have any numbers, just my guesses. For videomode displays
> or command mode displays in active use, I don't think ULPS matters
> much. The link is mostly not in ULPS. And if the display is
> blanked, things are off, so again not in ULPS.
> 
> It's only for command mode displays, when updated rarely, where I
> think ULPS matters. Which, of course, is probably not unusual use
> case if you have a cmdmode display. But whether OMAP DSI power
> savings matches SN65DSI84, I have no clue.

Right. FWIW I don't expect savings to be as big as this. The
comparision is not "active current", but "idle current" since
we do disable the clocks among other things. Considering the
amount of power-saving is pure guess-work I suggest to rephrase
the commit message to something like this:

ULPS is a niche power-saving optimization feature only
affecting enabled command mode panels showing a static
picture. It never worked with the omapdrm driver and I have
been unable to get it working. Keeping DSI command mode panels
working is hard enough without this, so remove ULPS support.

FWIW I'm fine with this being removed:

Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>

> > Considering all known omapdrm DSI users are battery powered devices
> > caring for saving as much power as possible, it might be good to just
> > keep this until it is being fixed considering this is very close to
> > the end of the series anyways?
> 
> I don't like to leave known to be broken code around, unless
> someone has plans to work on it. I wouldn't be surprised to see
> ULPS still broken two years from now =). It should be trivial to
> add the relevant bits back later.

Ack.

> But I can leave it here if you think it's better, presuming it
> doesn't have bigger conflicts with the 29/29 or break anything.
> However, I have only a few days left in TI, which is why I'm
> rushing here a bit (*). If I hit problems, I either have to drop
> the whole series, or push it in its current form.
> 
>  Tomi
> 
> (*) But I will fix possible issues caused by my push, of course.

Best of luck on whatever you do next!

-- Sebastian

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v5 29/29] drm/omap: dsi: allow DSI commands to be sent early
  2020-12-14 17:17   ` Sebastian Reichel
@ 2020-12-15 10:05     ` Tomi Valkeinen
  0 siblings, 0 replies; 72+ messages in thread
From: Tomi Valkeinen @ 2020-12-15 10:05 UTC (permalink / raw)
  To: Sebastian Reichel
  Cc: Laurent Pinchart, Nikhil Devshatwar, dri-devel, linux-omap,
	Sekhar Nori, Tony Lindgren, hns, Sam Ravnborg

Hi Sebastian,

On 14/12/2020 19:17, Sebastian Reichel wrote:
> Hi,
> 
> On Tue, Dec 08, 2020 at 02:28:55PM +0200, Tomi Valkeinen wrote:
>> Panel drivers can send DSI commands in panel's prepare(), which happens
>> before the bridge's enable() is called. The OMAP DSI driver currently
>> only sets up the DSI interface at bridge's enable(), so prepare() cannot
>> be used to send DSI commands.
>>
>> This patch fixes the issue by making it possible to enable the DSI
>> interface any time a command is about to be sent. Disabling the
>> interface is be done via delayed work.
>>
>> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
>> ---
> 
> Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
> 
> Would be nice to include the information why locking is ok from your
> reply mails to the patch description. It was helpful for reviewing
> the patch :)

Thanks for the reviews! I've made the changes you suggested.

I'll do some testing on top of the latest drm-misc-next, and send the whole series once more, so 
that I'm able to dim apply it.

I'm planning to push this to drm-misc-next tomorrow.

  Tomi

-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

^ permalink raw reply	[flat|nested] 72+ messages in thread

end of thread, other threads:[~2020-12-15 10:07 UTC | newest]

Thread overview: 72+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-12-08 12:28 [PATCH v5 00/29] Convert DSI code to use drm_mipi_dsi and drm_panel (second half) Tomi Valkeinen
2020-12-08 12:28 ` [PATCH v5 01/29] drm/panel: panel-dsi-cm: cleanup tear enable Tomi Valkeinen
2020-12-14 13:09   ` Sebastian Reichel
2020-12-08 12:28 ` [PATCH v5 02/29] ARM: dts: omap5: add address-cells & size-cells to dsi Tomi Valkeinen
2020-12-14 13:09   ` Sebastian Reichel
2020-12-08 12:28 ` [PATCH v5 03/29] drm/omap: pll: fix iteration loop check Tomi Valkeinen
2020-12-14 13:10   ` Sebastian Reichel
2020-12-08 12:28 ` [PATCH v5 04/29] drm/omap: dsi: set trans_mode according to client mode_flags Tomi Valkeinen
2020-12-14 13:10   ` Sebastian Reichel
2020-12-08 12:28 ` [PATCH v5 05/29] drm/panel: panel-dsi-cm: set column & page at setup Tomi Valkeinen
2020-12-14 13:10   ` Sebastian Reichel
2020-12-08 12:28 ` [PATCH v5 06/29] drm/omap: dsi: send nop instead of page & column Tomi Valkeinen
2020-12-14 14:22   ` Sebastian Reichel
2020-12-08 12:28 ` [PATCH v5 07/29] drm/omap: dsi: simplify VC handling Tomi Valkeinen
2020-12-14 14:31   ` Sebastian Reichel
2020-12-08 12:28 ` [PATCH v5 08/29] drm/omap: dsi: drop useless channel checks Tomi Valkeinen
2020-12-14 14:32   ` Sebastian Reichel
2020-12-08 12:28 ` [PATCH v5 09/29] drm/omap: dsi: cleanup dispc channel usage Tomi Valkeinen
2020-12-08 15:17   ` Laurent Pinchart
2020-12-14 14:35   ` Sebastian Reichel
2020-12-08 12:28 ` [PATCH v5 10/29] drm/omap: dsi: rename 'channel' to 'vc' Tomi Valkeinen
2020-12-08 15:22   ` Laurent Pinchart
2020-12-14 15:18   ` Sebastian Reichel
2020-12-08 12:28 ` [PATCH v5 11/29] drm/omap: dsi: pass vc to various functions Tomi Valkeinen
2020-12-08 15:38   ` Laurent Pinchart
2020-12-08 15:45     ` Tomi Valkeinen
2020-12-14 15:37   ` Sebastian Reichel
2020-12-08 12:28 ` [PATCH v5 12/29] drm/omap: dsi: untangle vc & channel Tomi Valkeinen
2020-12-08 15:41   ` Laurent Pinchart
2020-12-14 15:47     ` Sebastian Reichel
2020-12-08 12:28 ` [PATCH v5 13/29] drm/omap: dsi: skip dsi_vc_enable_hs when already in correct mode Tomi Valkeinen
2020-12-14 15:50   ` Sebastian Reichel
2020-12-08 12:28 ` [PATCH v5 14/29] drm/omap: dsi: enable HS before sending the frame Tomi Valkeinen
2020-12-08 15:42   ` Laurent Pinchart
2020-12-14 15:51   ` Sebastian Reichel
2020-12-08 12:28 ` [PATCH v5 15/29] drm/omap: dsi: use separate VCs for cmd and video Tomi Valkeinen
2020-12-14 15:54   ` Sebastian Reichel
2020-12-08 12:28 ` [PATCH v5 16/29] drm/panel: panel-dsi-cm: remove extra 'if' Tomi Valkeinen
2020-12-08 15:42   ` Laurent Pinchart
2020-12-14 15:55   ` Sebastian Reichel
2020-12-08 12:28 ` [PATCH v5 17/29] drm/panel: panel-dsi-cm: add panel database to driver Tomi Valkeinen
2020-12-14 16:04   ` Sebastian Reichel
2020-12-08 12:28 ` [PATCH v5 18/29] drm/panel: panel-dsi-cm: drop unneeded includes Tomi Valkeinen
2020-12-14 16:06   ` Sebastian Reichel
2020-12-08 12:28 ` [PATCH v5 19/29] drm/omap: dsi: move structs & defines to dsi.h Tomi Valkeinen
2020-12-14 16:14   ` Sebastian Reichel
2020-12-08 12:28 ` [PATCH v5 20/29] drm/omap: dsi: move enable/disable to bridge enable/disable Tomi Valkeinen
2020-12-14 16:16   ` Sebastian Reichel
2020-12-08 12:28 ` [PATCH v5 21/29] drm/omap: dsi: display_enable cleanup Tomi Valkeinen
2020-12-14 16:17   ` Sebastian Reichel
2020-12-08 12:28 ` [PATCH v5 22/29] drm/omap: dsi: display_disable cleanup Tomi Valkeinen
2020-12-14 16:20   ` Sebastian Reichel
2020-12-08 12:28 ` [PATCH v5 23/29] drm/omap: dsi: rename dsi_display_* functions Tomi Valkeinen
2020-12-14 16:22   ` Sebastian Reichel
2020-12-08 12:28 ` [PATCH v5 24/29] drm/omap: dsi: cleanup initial vc setup Tomi Valkeinen
2020-12-14 16:34   ` Sebastian Reichel
2020-12-08 12:28 ` [PATCH v5 25/29] drm/omap: dsi: split video mode enable/disable into separate func Tomi Valkeinen
2020-12-14 16:38   ` Sebastian Reichel
2020-12-08 12:28 ` [PATCH v5 26/29] drm/omap: dsi: fix and cleanup ddr_clk_always_on Tomi Valkeinen
2020-12-14 16:39   ` Sebastian Reichel
2020-12-08 12:28 ` [PATCH v5 27/29] drm/omap: dsi: remove ulps support Tomi Valkeinen
2020-12-14 17:39   ` Sebastian Reichel
2020-12-14 18:55     ` Tomi Valkeinen
2020-12-14 22:08       ` Sebastian Reichel
2020-12-08 12:28 ` [PATCH v5 28/29] drm/omap: dsi: fix DCS_CMD_ENABLE Tomi Valkeinen
2020-12-14 16:48   ` Sebastian Reichel
2020-12-08 12:28 ` [PATCH v5 29/29] drm/omap: dsi: allow DSI commands to be sent early Tomi Valkeinen
2020-12-08 15:48   ` Laurent Pinchart
2020-12-10  7:34     ` Tomi Valkeinen
2020-12-10  8:17       ` Tomi Valkeinen
2020-12-14 17:17   ` Sebastian Reichel
2020-12-15 10:05     ` Tomi Valkeinen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).