dri-devel.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
* [RFCv1 00/42] drm/omap: Convert DSI code to use drm_mipi_dsi and drm_panel
@ 2019-11-17  2:39 Sebastian Reichel
  2019-11-17  2:39 ` Sebastian Reichel
                   ` (42 more replies)
  0 siblings, 43 replies; 64+ messages in thread
From: Sebastian Reichel @ 2019-11-17  2:39 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Tomi Valkeinen
  Cc: kernel, Tony Lindgren, H. Nikolaus Schaller, Merlijn Wajer,
	Sebastian Reichel, dri-devel, linux-omap

This updates the existing omapdrm DSI code, so that it uses
common drm_mipi_dsi API and drm_panel instead of custom API.
I did not implement support for drm_bridge, since I do not
own any hardware needing this and it does not seem to be a
supported scenario with the old DSS code.

The patchset has been tested with Droid 4 using Linux console,
X.org and Weston. While I found some issues, I could not find
any regressions compared to the current state (*). Combined with
Laurent's effort this will remove all custom panel/connector
drivers from omapdrm and allow more cleanups in the DSS code.

I pushed this patchset into the following branch:

https://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-n900.git/log/?h=omapdrm-dsi-drm-panel

(*) When display is used as console for dmesg one can see an
    ugly deadlock on shutdown. I have not yet found the root
    cause for this problem, but that already exists with
    current mainline implementation.

 -- Sebastian

Sebastian Reichel (42):
  omap/drm: drop unused dsi.configure_pins
  drm/omap: dsi: use MIPI_DSI_FMT_* instead of OMAP_DSS_DSI_FMT_*
  drm/omap: constify write buffers
  drm/omap: dsi: add generic transfer function
  drm/omap: panel-dsi-cm: convert to transfer API
  drm/omap: dsi: unexport specific data transfer functions
  drm/omap: dsi: drop virtual channel logic
  drm/omap: dsi: simplify write function
  drm/omap: dsi: simplify read functions
  drm/omap: dsi: switch dsi_vc_send_long/short to mipi_dsi_msg
  ARM: dts: omap: add channel to DSI panels
  drm/omap: dsi: introduce mipi_dsi_host
  drm/omap: panel-dsi-cm: use DSI helpers
  drm/omap: dsi: request VC via mipi_dsi_attach
  drm/omap: panel-dsi-cm: drop hardcoded VC
  drm/omap: panel-dsi-cm: use common MIPI DCS 1.3 defines
  drm/omap: dsi: drop unused memory_read()
  drm/omap: dsi: drop unused get_te()
  drm/omap: dsi: drop unused enable_te()
  drm/omap: dsi: drop useless sync()
  drm/omap: dsi: use pixel-format and mode from attach
  drm/omap: panel-dsi-cm: use bulk regulator API
  drm/omap: dsi: lp/hs switching support for transfer()
  drm/omap: dsi: move TE GPIO handling into core
  drm/omap: dsi: drop custom enable_te() API
  drm/omap: dsi: do bus locking in host driver
  drm/omap: dsi: untangle ulps ops from enable/disable
  drm/dsi: add MIPI_DSI_MODE_ULPS_IDLE
  drm/omap: dsi: do ULPS in host driver
  drm/omap: dsi: move panel refresh function to host
  drm/omap: dsi: Reverse direction of the DSS device enable/disable
    operations
  drm/omap: dsi: convert to drm_panel
  drm/omap: dsi: use atomic helper for dirtyfb
  drm/omap: dsi: implement check timings
  drm/omap: panel-dsi-cm: use DEVICE_ATTR_RO
  drm/omap: panel-dsi-cm: support unbinding
  drm/omap: panel-dsi-cm: fix remove()
  drm/omap: panel-dsi-cm: do not power on/off twice
  drm/omap: dsi: return proper error code from dsi_update_all()
  drm/omap: dsi: support panel un/re-binding
  ARM: dts: omap4-droid4: add panel compatible
  drm/panel: Move OMAP's DSI command mode panel driver

 .../bindings/display/panel/panel-dsi-cm.txt   |    4 +-
 arch/arm/boot/dts/omap3-n950.dts              |    3 +-
 arch/arm/boot/dts/omap3.dtsi                  |    3 +
 arch/arm/boot/dts/omap4-droid4-xt894.dts      |    5 +-
 arch/arm/boot/dts/omap4-sdp.dts               |    6 +-
 arch/arm/boot/dts/omap4.dtsi                  |    6 +
 arch/arm/boot/dts/omap5.dtsi                  |    6 +
 drivers/gpu/drm/omapdrm/displays/Kconfig      |    6 -
 drivers/gpu/drm/omapdrm/displays/Makefile     |    1 -
 .../gpu/drm/omapdrm/displays/panel-dsi-cm.c   | 1387 -----------------
 drivers/gpu/drm/omapdrm/dss/Kconfig           |    1 +
 drivers/gpu/drm/omapdrm/dss/base.c            |    2 +-
 drivers/gpu/drm/omapdrm/dss/dsi.c             | 1019 ++++++++----
 .../gpu/drm/omapdrm/dss/omapdss-boot-init.c   |    1 -
 drivers/gpu/drm/omapdrm/dss/omapdss.h         |   81 +-
 drivers/gpu/drm/omapdrm/omap_crtc.c           |   37 +-
 drivers/gpu/drm/omapdrm/omap_crtc.h           |    1 -
 drivers/gpu/drm/omapdrm/omap_encoder.c        |   20 +-
 drivers/gpu/drm/omapdrm/omap_fb.c             |   21 +-
 drivers/gpu/drm/panel/Kconfig                 |    9 +
 drivers/gpu/drm/panel/Makefile                |    1 +
 drivers/gpu/drm/panel/panel-dsi-cm.c          |  646 ++++++++
 include/drm/drm_mipi_dsi.h                    |    2 +
 23 files changed, 1385 insertions(+), 1883 deletions(-)
 delete mode 100644 drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
 create mode 100644 drivers/gpu/drm/panel/panel-dsi-cm.c


base-commit: 17cc51390c141662748dbbc2fe98f3ed10f2e13e
-- 
2.24.0

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

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

* [RFCv1 00/42] drm/omap: Convert DSI code to use drm_mipi_dsi and drm_panel
  2019-11-17  2:39 [RFCv1 00/42] drm/omap: Convert DSI code to use drm_mipi_dsi and drm_panel Sebastian Reichel
@ 2019-11-17  2:39 ` Sebastian Reichel
  2019-11-17  2:39 ` [RFCv1 01/42] omap/drm: drop unused dsi.configure_pins Sebastian Reichel
                   ` (41 subsequent siblings)
  42 siblings, 0 replies; 64+ messages in thread
From: Sebastian Reichel @ 2019-11-17  2:39 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Tomi Valkeinen
  Cc: kernel, Tony Lindgren, H. Nikolaus Schaller, Merlijn Wajer,
	Sebastian Reichel, dri-devel, linux-omap

This updates the existing omapdrm DSI code, so that it uses
common drm_mipi_dsi API and drm_panel instead of custom API.
I did not implement support for drm_bridge, since I do not
own any hardware needing this and it does not seem to be a
supported scenario with the old DSS code.

The patchset has been tested with Droid 4 using Linux console,
X.org and Weston. While I found some issues, I could not find
any regressions compared to the current state (*). Combined with
Laurent's effort this will remove all custom panel/connector
drivers from omapdrm and allow more cleanups in the DSS code.

I pushed this patchset into the following branch:

https://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-n900.git/log/?h=omapdrm-dsi-drm-panel

(*) When display is used as console for dmesg one can see an
    ugly deadlock on shutdown. I have not yet found the root
    cause for this problem, but that already exists with
    current mainline implementation.

 -- Sebastian

Sebastian Reichel (42):
  omap/drm: drop unused dsi.configure_pins
  drm/omap: dsi: use MIPI_DSI_FMT_* instead of OMAP_DSS_DSI_FMT_*
  drm/omap: constify write buffers
  drm/omap: dsi: add generic transfer function
  drm/omap: panel-dsi-cm: convert to transfer API
  drm/omap: dsi: unexport specific data transfer functions
  drm/omap: dsi: drop virtual channel logic
  drm/omap: dsi: simplify write function
  drm/omap: dsi: simplify read functions
  drm/omap: dsi: switch dsi_vc_send_long/short to mipi_dsi_msg
  ARM: dts: omap: add channel to DSI panels
  drm/omap: dsi: introduce mipi_dsi_host
  drm/omap: panel-dsi-cm: use DSI helpers
  drm/omap: dsi: request VC via mipi_dsi_attach
  drm/omap: panel-dsi-cm: drop hardcoded VC
  drm/omap: panel-dsi-cm: use common MIPI DCS 1.3 defines
  drm/omap: dsi: drop unused memory_read()
  drm/omap: dsi: drop unused get_te()
  drm/omap: dsi: drop unused enable_te()
  drm/omap: dsi: drop useless sync()
  drm/omap: dsi: use pixel-format and mode from attach
  drm/omap: panel-dsi-cm: use bulk regulator API
  drm/omap: dsi: lp/hs switching support for transfer()
  drm/omap: dsi: move TE GPIO handling into core
  drm/omap: dsi: drop custom enable_te() API
  drm/omap: dsi: do bus locking in host driver
  drm/omap: dsi: untangle ulps ops from enable/disable
  drm/dsi: add MIPI_DSI_MODE_ULPS_IDLE
  drm/omap: dsi: do ULPS in host driver
  drm/omap: dsi: move panel refresh function to host
  drm/omap: dsi: Reverse direction of the DSS device enable/disable
    operations
  drm/omap: dsi: convert to drm_panel
  drm/omap: dsi: use atomic helper for dirtyfb
  drm/omap: dsi: implement check timings
  drm/omap: panel-dsi-cm: use DEVICE_ATTR_RO
  drm/omap: panel-dsi-cm: support unbinding
  drm/omap: panel-dsi-cm: fix remove()
  drm/omap: panel-dsi-cm: do not power on/off twice
  drm/omap: dsi: return proper error code from dsi_update_all()
  drm/omap: dsi: support panel un/re-binding
  ARM: dts: omap4-droid4: add panel compatible
  drm/panel: Move OMAP's DSI command mode panel driver

 .../bindings/display/panel/panel-dsi-cm.txt   |    4 +-
 arch/arm/boot/dts/omap3-n950.dts              |    3 +-
 arch/arm/boot/dts/omap3.dtsi                  |    3 +
 arch/arm/boot/dts/omap4-droid4-xt894.dts      |    5 +-
 arch/arm/boot/dts/omap4-sdp.dts               |    6 +-
 arch/arm/boot/dts/omap4.dtsi                  |    6 +
 arch/arm/boot/dts/omap5.dtsi                  |    6 +
 drivers/gpu/drm/omapdrm/displays/Kconfig      |    6 -
 drivers/gpu/drm/omapdrm/displays/Makefile     |    1 -
 .../gpu/drm/omapdrm/displays/panel-dsi-cm.c   | 1387 -----------------
 drivers/gpu/drm/omapdrm/dss/Kconfig           |    1 +
 drivers/gpu/drm/omapdrm/dss/base.c            |    2 +-
 drivers/gpu/drm/omapdrm/dss/dsi.c             | 1019 ++++++++----
 .../gpu/drm/omapdrm/dss/omapdss-boot-init.c   |    1 -
 drivers/gpu/drm/omapdrm/dss/omapdss.h         |   81 +-
 drivers/gpu/drm/omapdrm/omap_crtc.c           |   37 +-
 drivers/gpu/drm/omapdrm/omap_crtc.h           |    1 -
 drivers/gpu/drm/omapdrm/omap_encoder.c        |   20 +-
 drivers/gpu/drm/omapdrm/omap_fb.c             |   21 +-
 drivers/gpu/drm/panel/Kconfig                 |    9 +
 drivers/gpu/drm/panel/Makefile                |    1 +
 drivers/gpu/drm/panel/panel-dsi-cm.c          |  646 ++++++++
 include/drm/drm_mipi_dsi.h                    |    2 +
 23 files changed, 1385 insertions(+), 1883 deletions(-)
 delete mode 100644 drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
 create mode 100644 drivers/gpu/drm/panel/panel-dsi-cm.c


base-commit: 17cc51390c141662748dbbc2fe98f3ed10f2e13e
-- 
2.24.0

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

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

* [RFCv1 01/42] omap/drm: drop unused dsi.configure_pins
  2019-11-17  2:39 [RFCv1 00/42] drm/omap: Convert DSI code to use drm_mipi_dsi and drm_panel Sebastian Reichel
  2019-11-17  2:39 ` Sebastian Reichel
@ 2019-11-17  2:39 ` Sebastian Reichel
  2019-11-17  2:39 ` [RFCv1 02/42] drm/omap: dsi: use MIPI_DSI_FMT_* instead of OMAP_DSS_DSI_FMT_* Sebastian Reichel
                   ` (40 subsequent siblings)
  42 siblings, 0 replies; 64+ messages in thread
From: Sebastian Reichel @ 2019-11-17  2:39 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Tomi Valkeinen
  Cc: kernel, Tony Lindgren, H. Nikolaus Schaller, Merlijn Wajer,
	Sebastian Reichel, dri-devel, linux-omap

The panel-dsi-cm's ddata->pin_config is always NULL, so this
callback is never called. Instead the DSI encoder gets the pin
configuration directly from DT.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c | 11 -----------
 drivers/gpu/drm/omapdrm/dss/dsi.c               |  1 -
 drivers/gpu/drm/omapdrm/dss/omapdss.h           |  2 --
 3 files changed, 14 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
index 564e3e1a1891..c3ddf98f4ec6 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
@@ -68,8 +68,6 @@ struct panel_drv_data {
 	int width_mm;
 	int height_mm;
 
-	struct omap_dsi_pin_config pin_config;
-
 	/* runtime variables */
 	bool enabled;
 
@@ -623,15 +621,6 @@ static int dsicm_power_on(struct panel_drv_data *ddata)
 		}
 	}
 
-	if (ddata->pin_config.num_pins > 0) {
-		r = src->ops->dsi.configure_pins(src, &ddata->pin_config);
-		if (r) {
-			dev_err(&ddata->pdev->dev,
-				"failed to configure DSI pins\n");
-			goto err_vddi;
-		}
-	}
-
 	r = src->ops->dsi.set_config(src, &dsi_config);
 	if (r) {
 		dev_err(&ddata->pdev->dev, "failed to configure DSI\n");
diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index da16ea095f13..8e3664368c4f 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -4892,7 +4892,6 @@ static const struct omap_dss_device_ops dsi_ops = {
 
 		.enable_hs = dsi_vc_enable_hs,
 
-		.configure_pins = dsi_configure_pins,
 		.set_config = dsi_set_config,
 
 		.enable_video_output = dsi_enable_video_output,
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index 79f6b195c7cf..75e506b88733 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -299,8 +299,6 @@ struct omapdss_dsi_ops {
 	/* bus configuration */
 	int (*set_config)(struct omap_dss_device *dssdev,
 			const struct omap_dss_dsi_config *cfg);
-	int (*configure_pins)(struct omap_dss_device *dssdev,
-			const struct omap_dsi_pin_config *pin_cfg);
 
 	void (*enable_hs)(struct omap_dss_device *dssdev, int channel,
 			bool enable);
-- 
2.24.0

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

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

* [RFCv1 02/42] drm/omap: dsi: use MIPI_DSI_FMT_* instead of OMAP_DSS_DSI_FMT_*
  2019-11-17  2:39 [RFCv1 00/42] drm/omap: Convert DSI code to use drm_mipi_dsi and drm_panel Sebastian Reichel
  2019-11-17  2:39 ` Sebastian Reichel
  2019-11-17  2:39 ` [RFCv1 01/42] omap/drm: drop unused dsi.configure_pins Sebastian Reichel
@ 2019-11-17  2:39 ` Sebastian Reichel
  2019-11-17  2:39 ` [RFCv1 03/42] drm/omap: constify write buffers Sebastian Reichel
                   ` (39 subsequent siblings)
  42 siblings, 0 replies; 64+ messages in thread
From: Sebastian Reichel @ 2019-11-17  2:39 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Tomi Valkeinen
  Cc: kernel, Tony Lindgren, H. Nikolaus Schaller, Merlijn Wajer,
	Sebastian Reichel, dri-devel, linux-omap

This replaces OMAP specific enum for pixel format with
common implementation.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 .../gpu/drm/omapdrm/displays/panel-dsi-cm.c   |  2 +-
 drivers/gpu/drm/omapdrm/dss/dsi.c             | 49 +++++++------------
 drivers/gpu/drm/omapdrm/dss/omapdss.h         | 10 +---
 3 files changed, 20 insertions(+), 41 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
index c3ddf98f4ec6..9214d66cfdc7 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
@@ -595,7 +595,7 @@ static int dsicm_power_on(struct panel_drv_data *ddata)
 	int r;
 	struct omap_dss_dsi_config dsi_config = {
 		.mode = OMAP_DSS_DSI_CMD_MODE,
-		.pixel_format = OMAP_DSS_DSI_FMT_RGB888,
+		.pixel_format = MIPI_DSI_FMT_RGB888,
 		.vm = &ddata->vm,
 		.hs_clk_min = 150000000,
 		.hs_clk_max = 300000000,
diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index 8e3664368c4f..fa81fbf3442e 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -34,6 +34,7 @@
 #include <linux/sys_soc.h>
 
 #include <video/mipi_display.h>
+#include <drm/drm_mipi_dsi.h>
 
 #include "omapdss.h"
 #include "dss.h"
@@ -410,7 +411,7 @@ struct dsi_data {
 
 	struct dss_lcd_mgr_config mgr_config;
 	struct videomode vm;
-	enum omap_dss_dsi_pixel_format pix_fmt;
+	enum mipi_dsi_pixel_format pix_fmt;
 	enum omap_dss_dsi_mode mode;
 	struct omap_dss_dsi_videomode_timings vm_timings;
 
@@ -514,22 +515,6 @@ static inline bool wait_for_bit_change(struct dsi_data *dsi,
 	return false;
 }
 
-static u8 dsi_get_pixel_size(enum omap_dss_dsi_pixel_format fmt)
-{
-	switch (fmt) {
-	case OMAP_DSS_DSI_FMT_RGB888:
-	case OMAP_DSS_DSI_FMT_RGB666:
-		return 24;
-	case OMAP_DSS_DSI_FMT_RGB666_PACKED:
-		return 18;
-	case OMAP_DSS_DSI_FMT_RGB565:
-		return 16;
-	default:
-		BUG();
-		return 0;
-	}
-}
-
 #ifdef DSI_PERF_MEASURE
 static void dsi_perf_mark_setup(struct dsi_data *dsi)
 {
@@ -3239,7 +3224,7 @@ static void dsi_config_vp_num_line_buffers(struct dsi_data *dsi)
 	int num_line_buffers;
 
 	if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) {
-		int bpp = dsi_get_pixel_size(dsi->pix_fmt);
+		int bpp = mipi_dsi_pixel_format_to_bpp(dsi->pix_fmt);
 		const struct videomode *vm = &dsi->vm;
 		/*
 		 * Don't use line buffers if width is greater than the video
@@ -3370,7 +3355,7 @@ static void dsi_config_cmd_mode_interleaving(struct dsi_data *dsi)
 	int tclk_trail, ths_exit, exiths_clk;
 	bool ddr_alwon;
 	const struct videomode *vm = &dsi->vm;
-	int bpp = dsi_get_pixel_size(dsi->pix_fmt);
+	int bpp = mipi_dsi_pixel_format_to_bpp(dsi->pix_fmt);
 	int ndl = dsi->num_lanes_used - 1;
 	int dsi_fclk_hsdiv = dsi->user_dsi_cinfo.mX[HSDIV_DSI] + 1;
 	int hsa_interleave_hs = 0, hsa_interleave_lp = 0;
@@ -3498,7 +3483,7 @@ static int dsi_proto_config(struct dsi_data *dsi)
 	dsi_set_lp_rx_timeout(dsi, 0x1fff, true, true);
 	dsi_set_hs_tx_timeout(dsi, 0x1fff, true, true);
 
-	switch (dsi_get_pixel_size(dsi->pix_fmt)) {
+	switch (mipi_dsi_pixel_format_to_bpp(dsi->pix_fmt)) {
 	case 16:
 		buswidth = 0;
 		break;
@@ -3619,7 +3604,7 @@ static void dsi_proto_timings(struct dsi_data *dsi)
 		int window_sync = dsi->vm_timings.window_sync;
 		bool hsync_end;
 		const struct videomode *vm = &dsi->vm;
-		int bpp = dsi_get_pixel_size(dsi->pix_fmt);
+		int bpp = mipi_dsi_pixel_format_to_bpp(dsi->pix_fmt);
 		int tl, t_he, width_bytes;
 
 		hsync_end = dsi->vm_timings.trans_mode == OMAP_DSS_DSI_PULSE_MODE;
@@ -3726,7 +3711,7 @@ static int dsi_configure_pins(struct omap_dss_device *dssdev,
 static int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
 {
 	struct dsi_data *dsi = to_dsi_data(dssdev);
-	int bpp = dsi_get_pixel_size(dsi->pix_fmt);
+	int bpp = mipi_dsi_pixel_format_to_bpp(dsi->pix_fmt);
 	u8 data_type;
 	u16 word_count;
 	int r;
@@ -3737,16 +3722,16 @@ static int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
 
 	if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) {
 		switch (dsi->pix_fmt) {
-		case OMAP_DSS_DSI_FMT_RGB888:
+		case MIPI_DSI_FMT_RGB888:
 			data_type = MIPI_DSI_PACKED_PIXEL_STREAM_24;
 			break;
-		case OMAP_DSS_DSI_FMT_RGB666:
+		case MIPI_DSI_FMT_RGB666:
 			data_type = MIPI_DSI_PIXEL_STREAM_3BYTE_18;
 			break;
-		case OMAP_DSS_DSI_FMT_RGB666_PACKED:
+		case MIPI_DSI_FMT_RGB666_PACKED:
 			data_type = MIPI_DSI_PACKED_PIXEL_STREAM_18;
 			break;
-		case OMAP_DSS_DSI_FMT_RGB565:
+		case MIPI_DSI_FMT_RGB565:
 			data_type = MIPI_DSI_PACKED_PIXEL_STREAM_16;
 			break;
 		default:
@@ -3824,7 +3809,7 @@ static void dsi_update_screen_dispc(struct dsi_data *dsi)
 
 	dsi_vc_config_source(dsi, channel, DSI_VC_SOURCE_VP);
 
-	bytespp	= dsi_get_pixel_size(dsi->pix_fmt) / 8;
+	bytespp	= mipi_dsi_pixel_format_to_bpp(dsi->pix_fmt) / 8;
 	bytespl = w * bytespp;
 	bytespf = bytespl * h;
 
@@ -3954,7 +3939,7 @@ static int dsi_update(struct omap_dss_device *dssdev, int channel,
 
 #ifdef DSI_PERF_MEASURE
 	dsi->update_bytes = dw * dh *
-		dsi_get_pixel_size(dsi->pix_fmt) / 8;
+		mipi_dsi_pixel_format_to_bpp(dsi->pix_fmt) / 8;
 #endif
 	dsi_update_screen_dispc(dsi);
 
@@ -4015,7 +4000,7 @@ static int dsi_display_init_dispc(struct dsi_data *dsi)
 
 	dsi->mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS;
 	dsi->mgr_config.video_port_width =
-			dsi_get_pixel_size(dsi->pix_fmt);
+			mipi_dsi_pixel_format_to_bpp(dsi->pix_fmt);
 	dsi->mgr_config.lcden_sig_polarity = 0;
 
 	dss_mgr_set_lcd_config(&dsi->output, &dsi->mgr_config);
@@ -4353,7 +4338,7 @@ static bool dsi_cm_calc(struct dsi_data *dsi,
 	unsigned long pck, txbyteclk;
 
 	clkin = clk_get_rate(dsi->pll.clkin);
-	bitspp = dsi_get_pixel_size(cfg->pixel_format);
+	bitspp = mipi_dsi_pixel_format_to_bpp(cfg->pixel_format);
 	ndl = dsi->num_lanes_used - 1;
 
 	/*
@@ -4386,7 +4371,7 @@ static bool dsi_vm_calc_blanking(struct dsi_clk_calc_ctx *ctx)
 {
 	struct dsi_data *dsi = ctx->dsi;
 	const struct omap_dss_dsi_config *cfg = ctx->config;
-	int bitspp = dsi_get_pixel_size(cfg->pixel_format);
+	int bitspp = mipi_dsi_pixel_format_to_bpp(cfg->pixel_format);
 	int ndl = dsi->num_lanes_used - 1;
 	unsigned long hsclk = ctx->dsi_cinfo.clkdco / 4;
 	unsigned long byteclk = hsclk / 4;
@@ -4653,7 +4638,7 @@ static bool dsi_vm_calc(struct dsi_data *dsi,
 	unsigned long pll_min;
 	unsigned long pll_max;
 	int ndl = dsi->num_lanes_used - 1;
-	int bitspp = dsi_get_pixel_size(cfg->pixel_format);
+	int bitspp = mipi_dsi_pixel_format_to_bpp(cfg->pixel_format);
 	unsigned long byteclk_min;
 
 	clkin = clk_get_rate(dsi->pll.clkin);
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index 75e506b88733..6dd08d096eed 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -14,6 +14,7 @@
 #include <linux/platform_data/omapdss.h>
 #include <uapi/drm/drm_mode.h>
 #include <drm/drm_crtc.h>
+#include <drm/drm_mipi_dsi.h>
 
 #define DISPC_IRQ_FRAMEDONE		(1 << 0)
 #define DISPC_IRQ_VSYNC			(1 << 1)
@@ -116,13 +117,6 @@ enum omap_dss_venc_type {
 	OMAP_DSS_VENC_TYPE_SVIDEO,
 };
 
-enum omap_dss_dsi_pixel_format {
-	OMAP_DSS_DSI_FMT_RGB888,
-	OMAP_DSS_DSI_FMT_RGB666,
-	OMAP_DSS_DSI_FMT_RGB666_PACKED,
-	OMAP_DSS_DSI_FMT_RGB565,
-};
-
 enum omap_dss_dsi_mode {
 	OMAP_DSS_DSI_CMD_MODE = 0,
 	OMAP_DSS_DSI_VIDEO_MODE,
@@ -210,7 +204,7 @@ struct omap_dss_dsi_videomode_timings {
 
 struct omap_dss_dsi_config {
 	enum omap_dss_dsi_mode mode;
-	enum omap_dss_dsi_pixel_format pixel_format;
+	enum mipi_dsi_pixel_format pixel_format;
 	const struct videomode *vm;
 
 	unsigned long hs_clk_min, hs_clk_max;
-- 
2.24.0

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

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

* [RFCv1 03/42] drm/omap: constify write buffers
  2019-11-17  2:39 [RFCv1 00/42] drm/omap: Convert DSI code to use drm_mipi_dsi and drm_panel Sebastian Reichel
                   ` (2 preceding siblings ...)
  2019-11-17  2:39 ` [RFCv1 02/42] drm/omap: dsi: use MIPI_DSI_FMT_* instead of OMAP_DSS_DSI_FMT_* Sebastian Reichel
@ 2019-11-17  2:39 ` Sebastian Reichel
  2019-11-17  2:39 ` [RFCv1 04/42] drm/omap: dsi: add generic transfer function Sebastian Reichel
                   ` (38 subsequent siblings)
  42 siblings, 0 replies; 64+ messages in thread
From: Sebastian Reichel @ 2019-11-17  2:39 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Tomi Valkeinen
  Cc: kernel, Tony Lindgren, H. Nikolaus Schaller, Merlijn Wajer,
	Sebastian Reichel, dri-devel, linux-omap

The write buffers are not modified, so they can be constant.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 drivers/gpu/drm/omapdrm/dss/dsi.c     | 24 ++++++++++++------------
 drivers/gpu/drm/omapdrm/dss/omapdss.h | 10 +++++-----
 2 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index fa81fbf3442e..bf6131e5fa14 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -2601,11 +2601,11 @@ static inline void dsi_vc_write_long_payload(struct dsi_data *dsi, int channel,
 }
 
 static int dsi_vc_send_long(struct dsi_data *dsi, int channel, u8 data_type,
-			    u8 *data, u16 len, u8 ecc)
+			    const u8 *data, u16 len, u8 ecc)
 {
 	/*u32 val; */
 	int i;
-	u8 *p;
+	const u8 *p;
 	int r = 0;
 	u8 b1, b2, b3, b4;
 
@@ -2698,7 +2698,7 @@ static int dsi_vc_send_null(struct dsi_data *dsi, int channel)
 }
 
 static int dsi_vc_write_nosync_common(struct dsi_data *dsi, int channel,
-				      u8 *data, int len,
+				      const u8 *data, int len,
 				      enum dss_dsi_content_type type)
 {
 	int r;
@@ -2729,7 +2729,7 @@ static int dsi_vc_write_nosync_common(struct dsi_data *dsi, int channel,
 }
 
 static int dsi_vc_dcs_write_nosync(struct omap_dss_device *dssdev, int channel,
-		u8 *data, int len)
+		const u8 *data, int len)
 {
 	struct dsi_data *dsi = to_dsi_data(dssdev);
 
@@ -2738,7 +2738,7 @@ static int dsi_vc_dcs_write_nosync(struct omap_dss_device *dssdev, int channel,
 }
 
 static int dsi_vc_generic_write_nosync(struct omap_dss_device *dssdev, int channel,
-		u8 *data, int len)
+		const u8 *data, int len)
 {
 	struct dsi_data *dsi = to_dsi_data(dssdev);
 
@@ -2747,7 +2747,7 @@ static int dsi_vc_generic_write_nosync(struct omap_dss_device *dssdev, int chann
 }
 
 static int dsi_vc_write_common(struct omap_dss_device *dssdev,
-			       int channel, u8 *data, int len,
+			       int channel, const u8 *data, int len,
 			       enum dss_dsi_content_type type)
 {
 	struct dsi_data *dsi = to_dsi_data(dssdev);
@@ -2776,15 +2776,15 @@ static int dsi_vc_write_common(struct omap_dss_device *dssdev,
 	return r;
 }
 
-static int dsi_vc_dcs_write(struct omap_dss_device *dssdev, int channel, u8 *data,
-		int len)
+static int dsi_vc_dcs_write(struct omap_dss_device *dssdev, int channel,
+		const u8 *data, int len)
 {
 	return dsi_vc_write_common(dssdev, channel, data, len,
 			DSS_DSI_CONTENT_DCS);
 }
 
-static int dsi_vc_generic_write(struct omap_dss_device *dssdev, int channel, u8 *data,
-		int len)
+static int dsi_vc_generic_write(struct omap_dss_device *dssdev, int channel,
+		const u8 *data, int len)
 {
 	return dsi_vc_write_common(dssdev, channel, data, len,
 			DSS_DSI_CONTENT_GENERIC);
@@ -2810,7 +2810,7 @@ static int dsi_vc_dcs_send_read_request(struct dsi_data *dsi, int channel,
 }
 
 static int dsi_vc_generic_send_read_request(struct dsi_data *dsi, int channel,
-					    u8 *reqdata, int reqlen)
+					    const u8 *reqdata, int reqlen)
 {
 	u16 data;
 	u8 data_type;
@@ -2983,7 +2983,7 @@ static int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_c
 }
 
 static int dsi_vc_generic_read(struct omap_dss_device *dssdev, int channel,
-		u8 *reqdata, int reqlen, u8 *buf, int buflen)
+		const u8 *reqdata, int reqlen, u8 *buf, int buflen)
 {
 	struct dsi_data *dsi = to_dsi_data(dssdev);
 	int r;
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index 6dd08d096eed..ae1a4600dab2 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -315,18 +315,18 @@ struct omapdss_dsi_ops {
 
 	/* data transfer */
 	int (*dcs_write)(struct omap_dss_device *dssdev, int channel,
-			u8 *data, int len);
+			const u8 *data, int len);
 	int (*dcs_write_nosync)(struct omap_dss_device *dssdev, int channel,
-			u8 *data, int len);
+			const u8 *data, int len);
 	int (*dcs_read)(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
 			u8 *data, int len);
 
 	int (*gen_write)(struct omap_dss_device *dssdev, int channel,
-			u8 *data, int len);
+			const u8 *data, int len);
 	int (*gen_write_nosync)(struct omap_dss_device *dssdev, int channel,
-			u8 *data, int len);
+			const u8 *data, int len);
 	int (*gen_read)(struct omap_dss_device *dssdev, int channel,
-			u8 *reqdata, int reqlen,
+			const u8 *reqdata, int reqlen,
 			u8 *data, int len);
 
 	int (*bta_sync)(struct omap_dss_device *dssdev, int channel);
-- 
2.24.0

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

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

* [RFCv1 04/42] drm/omap: dsi: add generic transfer function
  2019-11-17  2:39 [RFCv1 00/42] drm/omap: Convert DSI code to use drm_mipi_dsi and drm_panel Sebastian Reichel
                   ` (3 preceding siblings ...)
  2019-11-17  2:39 ` [RFCv1 03/42] drm/omap: constify write buffers Sebastian Reichel
@ 2019-11-17  2:39 ` Sebastian Reichel
  2019-11-17  2:39 ` [RFCv1 05/42] drm/omap: panel-dsi-cm: convert to transfer API Sebastian Reichel
                   ` (37 subsequent siblings)
  42 siblings, 0 replies; 64+ messages in thread
From: Sebastian Reichel @ 2019-11-17  2:39 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Tomi Valkeinen
  Cc: kernel, Tony Lindgren, H. Nikolaus Schaller, Merlijn Wajer,
	Sebastian Reichel, dri-devel, linux-omap

This prepares the driver for becoming a mipi_dsi_host implementation,
which provides a generic transfer function instead of all kind of
different read/write functions. The implementation will become more
elegant after unexporting the specific functions in the following
patches.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 drivers/gpu/drm/omapdrm/dss/dsi.c     | 52 +++++++++++++++++++++++++++
 drivers/gpu/drm/omapdrm/dss/omapdss.h |  3 ++
 2 files changed, 55 insertions(+)

diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index bf6131e5fa14..7560411f8ed6 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -4836,6 +4836,56 @@ static void dsi_release_vc(struct omap_dss_device *dssdev, int channel)
 	}
 }
 
+static ssize_t omap_dsi_transfer(struct omap_dss_device *dssdev,
+				 const struct mipi_dsi_msg *msg)
+{
+	/*
+	 * no_sync can be used to optimize performance by sending
+	 * e.g. column and page information without syncing in
+	 * between. It's not absolutley required, so postpone this
+	 * feature for now.
+	 */
+	bool no_sync = false;
+	u16 val;
+
+	switch (msg->type) {
+	case MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM:
+	case MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM:
+	case MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM:
+	case MIPI_DSI_GENERIC_LONG_WRITE:
+		if (no_sync)
+			return dsi_vc_generic_write_nosync(dssdev, msg->channel,
+				                      msg->tx_buf, msg->tx_len);
+		else
+			return dsi_vc_generic_write(dssdev, msg->channel,
+						    msg->tx_buf, msg->tx_len);
+	case MIPI_DSI_DCS_SHORT_WRITE:
+	case MIPI_DSI_DCS_SHORT_WRITE_PARAM:
+	case MIPI_DSI_DCS_LONG_WRITE:
+		if (no_sync)
+			return dsi_vc_dcs_write_nosync(dssdev, msg->channel,
+						      msg->tx_buf, msg->tx_len);
+		else
+			return dsi_vc_dcs_write(dssdev, msg->channel,
+						msg->tx_buf, msg->tx_len);
+	case MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM:
+	case MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM:
+	case MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM:
+		return dsi_vc_generic_read(dssdev, msg->channel, msg->tx_buf,
+				msg->tx_len, msg->rx_buf, msg->rx_len);
+	case MIPI_DSI_DCS_READ:
+		return dsi_vc_dcs_read(dssdev, msg->channel,
+				((u8*) msg->tx_buf)[0],
+				msg->rx_buf, msg->rx_len);
+	case MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE:
+		val = le16_to_cpu(*((__le16*) msg->tx_buf));
+		return dsi_vc_set_max_rx_packet_size(dssdev, msg->channel, val);
+	case MIPI_DSI_NULL_PACKET:
+		return dsi_vc_send_null(to_dsi_data(dssdev), msg->channel);
+	}
+
+	return -EINVAL;
+}
 
 static int dsi_get_clocks(struct dsi_data *dsi)
 {
@@ -4890,6 +4940,8 @@ static const struct omap_dss_device_ops dsi_ops = {
 		.set_vc_id = dsi_set_vc_id,
 		.release_vc = dsi_release_vc,
 
+		.transfer = omap_dsi_transfer,
+
 		.dcs_write = dsi_vc_dcs_write,
 		.dcs_write_nosync = dsi_vc_dcs_write_nosync,
 		.dcs_read = dsi_vc_dcs_read,
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index ae1a4600dab2..04952c291537 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -314,6 +314,9 @@ struct omapdss_dsi_ops {
 	void (*release_vc)(struct omap_dss_device *dssdev, int channel);
 
 	/* data transfer */
+	ssize_t (*transfer)(struct omap_dss_device *dssdev,
+			const struct mipi_dsi_msg *msg);
+
 	int (*dcs_write)(struct omap_dss_device *dssdev, int channel,
 			const u8 *data, int len);
 	int (*dcs_write_nosync)(struct omap_dss_device *dssdev, int channel,
-- 
2.24.0

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

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

* [RFCv1 05/42] drm/omap: panel-dsi-cm: convert to transfer API
  2019-11-17  2:39 [RFCv1 00/42] drm/omap: Convert DSI code to use drm_mipi_dsi and drm_panel Sebastian Reichel
                   ` (4 preceding siblings ...)
  2019-11-17  2:39 ` [RFCv1 04/42] drm/omap: dsi: add generic transfer function Sebastian Reichel
@ 2019-11-17  2:39 ` Sebastian Reichel
  2019-11-17  2:39 ` [RFCv1 06/42] drm/omap: dsi: unexport specific data transfer functions Sebastian Reichel
                   ` (36 subsequent siblings)
  42 siblings, 0 replies; 64+ messages in thread
From: Sebastian Reichel @ 2019-11-17  2:39 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Tomi Valkeinen
  Cc: kernel, Tony Lindgren, H. Nikolaus Schaller, Merlijn Wajer,
	Sebastian Reichel, dri-devel, linux-omap

This converts the panel-dsi-cm driver to use the transfer
API instead of specific functions, so that the specific
functions can be unexported and squashed into the generic
transfer function.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 .../gpu/drm/omapdrm/displays/panel-dsi-cm.c   | 133 +++++++++++++-----
 1 file changed, 96 insertions(+), 37 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
index 9214d66cfdc7..05974059f231 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
@@ -140,45 +140,61 @@ static void hw_guard_wait(struct panel_drv_data *ddata)
 static int dsicm_dcs_read_1(struct panel_drv_data *ddata, u8 dcs_cmd, u8 *data)
 {
 	struct omap_dss_device *src = ddata->src;
-	int r;
-	u8 buf[1];
-
-	r = src->ops->dsi.dcs_read(src, ddata->channel, dcs_cmd, buf, 1);
-
-	if (r < 0)
-		return r;
-
-	*data = buf[0];
+	const struct mipi_dsi_msg msg = {
+		.channel = ddata->channel,
+		.type = MIPI_DSI_DCS_READ,
+		.tx_len = 1,
+		.tx_buf = &dcs_cmd,
+		.rx_len = 1,
+		.rx_buf = data
+	};
 
-	return 0;
+	return src->ops->dsi.transfer(src, &msg);
 }
 
 static int dsicm_dcs_write_0(struct panel_drv_data *ddata, u8 dcs_cmd)
 {
 	struct omap_dss_device *src = ddata->src;
+	const struct mipi_dsi_msg msg = {
+		.channel = ddata->channel,
+		.type = MIPI_DSI_DCS_SHORT_WRITE,
+		.tx_buf = &dcs_cmd,
+		.tx_len = 1,
+	};
 
-	return src->ops->dsi.dcs_write(src, ddata->channel, &dcs_cmd, 1);
+	return src->ops->dsi.transfer(src, &msg);
 }
 
 static int dsicm_dcs_write_1(struct panel_drv_data *ddata, u8 dcs_cmd, u8 param)
 {
 	struct omap_dss_device *src = ddata->src;
-	u8 buf[2] = { dcs_cmd, param };
+	const u8 buf[] = { dcs_cmd, param };
+	const struct mipi_dsi_msg msg = {
+		.channel = ddata->channel,
+		.type = MIPI_DSI_DCS_SHORT_WRITE_PARAM,
+		.tx_buf = &buf,
+		.tx_len = 2,
+	};
 
-	return src->ops->dsi.dcs_write(src, ddata->channel, buf, 2);
+	return src->ops->dsi.transfer(src, &msg);
 }
 
 static int dsicm_sleep_in(struct panel_drv_data *ddata)
 
 {
 	struct omap_dss_device *src = ddata->src;
-	u8 cmd;
 	int r;
+	const u8 cmd = MIPI_DCS_ENTER_SLEEP_MODE;
+	const struct mipi_dsi_msg msg = {
+		.channel = ddata->channel,
+		.type = MIPI_DSI_DCS_SHORT_WRITE,
+		.tx_buf = &cmd,
+		.tx_len = 1,
+	};
 
 	hw_guard_wait(ddata);
 
-	cmd = MIPI_DCS_ENTER_SLEEP_MODE;
-	r = src->ops->dsi.dcs_write_nosync(src, ddata->channel, &cmd, 1);
+	r = src->ops->dsi.transfer(src, &msg);
 	if (r)
 		return r;
 
@@ -233,28 +249,44 @@ static int dsicm_set_update_window(struct panel_drv_data *ddata,
 	u16 y1 = y;
 	u16 y2 = y + h - 1;
 
-	u8 buf[5];
-	buf[0] = MIPI_DCS_SET_COLUMN_ADDRESS;
-	buf[1] = (x1 >> 8) & 0xff;
-	buf[2] = (x1 >> 0) & 0xff;
-	buf[3] = (x2 >> 8) & 0xff;
-	buf[4] = (x2 >> 0) & 0xff;
+	const u8 paramX[] = {
+		MIPI_DCS_SET_COLUMN_ADDRESS,
+		(x1 >> 8) & 0xff,
+		(x1 >> 0) & 0xff,
+		(x2 >> 8) & 0xff,
+		(x2 >> 0) & 0xff,
+	};
 
-	r = src->ops->dsi.dcs_write_nosync(src, ddata->channel, buf, sizeof(buf));
-	if (r)
-		return r;
+	const struct mipi_dsi_msg msgX = {
+		.channel = ddata->channel,
+		.type = MIPI_DSI_GENERIC_LONG_WRITE,
+		.tx_buf = paramX,
+		.tx_len = 5,
+	};
 
-	buf[0] = MIPI_DCS_SET_PAGE_ADDRESS;
-	buf[1] = (y1 >> 8) & 0xff;
-	buf[2] = (y1 >> 0) & 0xff;
-	buf[3] = (y2 >> 8) & 0xff;
-	buf[4] = (y2 >> 0) & 0xff;
+	const u8 paramY[] = {
+		MIPI_DCS_SET_PAGE_ADDRESS,
+		(y1 >> 8) & 0xff,
+		(y1 >> 0) & 0xff,
+		(y2 >> 8) & 0xff,
+		(y2 >> 0) & 0xff,
+	};
 
-	r = src->ops->dsi.dcs_write_nosync(src, ddata->channel, buf, sizeof(buf));
+	const struct mipi_dsi_msg msgY = {
+		.channel = ddata->channel,
+		.type = MIPI_DSI_GENERIC_LONG_WRITE,
+		.tx_buf = paramY,
+		.tx_len = 5,
+	};
+
+
+	r = src->ops->dsi.transfer(src, &msgX);
 	if (r)
 		return r;
 
-	src->ops->dsi.bta_sync(src, ddata->channel);
+	r = src->ops->dsi.transfer(src, &msgY);
+	if (r)
+		return r;
 
 	return r;
 }
@@ -991,6 +1023,27 @@ static int dsicm_get_te(struct omap_dss_device *dssdev)
 	return r;
 }
 
+static int dsicm_set_max_rx_packet_size(struct omap_dss_device *dssdev,
+                                        u16 size)
+{
+	struct panel_drv_data *ddata = to_panel_data(dssdev);
+	struct omap_dss_device *src = ddata->src;
+
+	const u8 buf[] = {
+		size & 0xff,
+		size >> 8 & 0xff,
+	};
+
+	const struct mipi_dsi_msg msg = {
+		.channel = ddata->channel,
+		.type = MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE,
+		.tx_buf = buf,
+		.tx_len = 2,
+	};
+
+	return src->ops->dsi.transfer(src, &msg);
+}
+
 static int dsicm_memory_read(struct omap_dss_device *dssdev,
 		void *buf, size_t size,
 		u16 x, u16 y, u16 w, u16 h)
@@ -1031,17 +1084,23 @@ static int dsicm_memory_read(struct omap_dss_device *dssdev,
 
 	dsicm_set_update_window(ddata, x, y, w, h);
 
-	r = src->ops->dsi.set_max_rx_packet_size(src, ddata->channel, plen);
+	r = dsicm_set_max_rx_packet_size(dssdev, plen);
 	if (r)
 		goto err2;
 
 	while (buf_used < size) {
 		u8 dcs_cmd = first ? 0x2e : 0x3e;
+		const struct mipi_dsi_msg msg = {
+			.channel = ddata->channel,
+			.type = MIPI_DSI_DCS_READ,
+			.tx_buf = &dcs_cmd,
+			.tx_len = 1,
+			.rx_buf = buf + buf_used,
+			.rx_len = size - buf_used,
+		};
 		first = 0;
 
-		r = src->ops->dsi.dcs_read(src, ddata->channel, dcs_cmd,
-				buf + buf_used, size - buf_used);
-
+		r = src->ops->dsi.transfer(src, &msg);
 		if (r < 0) {
 			dev_err(dssdev->dev, "read error\n");
 			goto err3;
@@ -1065,7 +1124,7 @@ static int dsicm_memory_read(struct omap_dss_device *dssdev,
 	r = buf_used;
 
 err3:
-	src->ops->dsi.set_max_rx_packet_size(src, ddata->channel, 1);
+	dsicm_set_max_rx_packet_size(dssdev, 1);
 err2:
 	src->ops->dsi.bus_unlock(src);
 err1:
-- 
2.24.0

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

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

* [RFCv1 06/42] drm/omap: dsi: unexport specific data transfer functions
  2019-11-17  2:39 [RFCv1 00/42] drm/omap: Convert DSI code to use drm_mipi_dsi and drm_panel Sebastian Reichel
                   ` (5 preceding siblings ...)
  2019-11-17  2:39 ` [RFCv1 05/42] drm/omap: panel-dsi-cm: convert to transfer API Sebastian Reichel
@ 2019-11-17  2:39 ` Sebastian Reichel
  2019-11-17  2:39 ` [RFCv1 07/42] drm/omap: dsi: drop virtual channel logic Sebastian Reichel
                   ` (35 subsequent siblings)
  42 siblings, 0 replies; 64+ messages in thread
From: Sebastian Reichel @ 2019-11-17  2:39 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Tomi Valkeinen
  Cc: kernel, Tony Lindgren, H. Nikolaus Schaller, Merlijn Wajer,
	Sebastian Reichel, dri-devel, linux-omap

After converting all DSI drivers, unexport the specific transfer
functions.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 drivers/gpu/drm/omapdrm/dss/dsi.c     | 12 ------------
 drivers/gpu/drm/omapdrm/dss/omapdss.h | 20 --------------------
 2 files changed, 32 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index 7560411f8ed6..de4ec6055490 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -4941,18 +4941,6 @@ static const struct omap_dss_device_ops dsi_ops = {
 		.release_vc = dsi_release_vc,
 
 		.transfer = omap_dsi_transfer,
-
-		.dcs_write = dsi_vc_dcs_write,
-		.dcs_write_nosync = dsi_vc_dcs_write_nosync,
-		.dcs_read = dsi_vc_dcs_read,
-
-		.gen_write = dsi_vc_generic_write,
-		.gen_write_nosync = dsi_vc_generic_write_nosync,
-		.gen_read = dsi_vc_generic_read,
-
-		.bta_sync = dsi_vc_send_bta_sync,
-
-		.set_max_rx_packet_size = dsi_vc_set_max_rx_packet_size,
 	},
 };
 
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index 04952c291537..79ae4073c35f 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -316,26 +316,6 @@ struct omapdss_dsi_ops {
 	/* data transfer */
 	ssize_t (*transfer)(struct omap_dss_device *dssdev,
 			const struct mipi_dsi_msg *msg);
-
-	int (*dcs_write)(struct omap_dss_device *dssdev, int channel,
-			const u8 *data, int len);
-	int (*dcs_write_nosync)(struct omap_dss_device *dssdev, int channel,
-			const u8 *data, int len);
-	int (*dcs_read)(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
-			u8 *data, int len);
-
-	int (*gen_write)(struct omap_dss_device *dssdev, int channel,
-			const u8 *data, int len);
-	int (*gen_write_nosync)(struct omap_dss_device *dssdev, int channel,
-			const u8 *data, int len);
-	int (*gen_read)(struct omap_dss_device *dssdev, int channel,
-			const u8 *reqdata, int reqlen,
-			u8 *data, int len);
-
-	int (*bta_sync)(struct omap_dss_device *dssdev, int channel);
-
-	int (*set_max_rx_packet_size)(struct omap_dss_device *dssdev,
-			int channel, u16 plen);
 };
 
 struct omap_dss_device_ops {
-- 
2.24.0

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

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

* [RFCv1 07/42] drm/omap: dsi: drop virtual channel logic
  2019-11-17  2:39 [RFCv1 00/42] drm/omap: Convert DSI code to use drm_mipi_dsi and drm_panel Sebastian Reichel
                   ` (6 preceding siblings ...)
  2019-11-17  2:39 ` [RFCv1 06/42] drm/omap: dsi: unexport specific data transfer functions Sebastian Reichel
@ 2019-11-17  2:39 ` Sebastian Reichel
  2019-11-17  2:39 ` [RFCv1 08/42] drm/omap: dsi: simplify write function Sebastian Reichel
                   ` (34 subsequent siblings)
  42 siblings, 0 replies; 64+ messages in thread
From: Sebastian Reichel @ 2019-11-17  2:39 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Tomi Valkeinen
  Cc: kernel, Tony Lindgren, H. Nikolaus Schaller, Merlijn Wajer,
	Sebastian Reichel, dri-devel, linux-omap

This drops the virtual channel logic. Afterwards DSI clients
request their channel number and get the virtual channel with
the same number or -EBUSY if already in use.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 .../gpu/drm/omapdrm/displays/panel-dsi-cm.c   | 11 ++---
 drivers/gpu/drm/omapdrm/dss/dsi.c             | 46 ++++---------------
 drivers/gpu/drm/omapdrm/dss/omapdss.h         |  4 +-
 3 files changed, 12 insertions(+), 49 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
index 05974059f231..b505bfd221fc 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
@@ -769,19 +769,12 @@ static int dsicm_connect(struct omap_dss_device *src,
 	struct device *dev = &ddata->pdev->dev;
 	int r;
 
-	r = src->ops->dsi.request_vc(src, &ddata->channel);
+	r = src->ops->dsi.request_vc(src, ddata->channel);
 	if (r) {
 		dev_err(dev, "failed to get virtual channel\n");
 		return r;
 	}
 
-	r = src->ops->dsi.set_vc_id(src, ddata->channel, TCH);
-	if (r) {
-		dev_err(dev, "failed to set VC_ID\n");
-		src->ops->dsi.release_vc(src, ddata->channel);
-		return r;
-	}
-
 	ddata->src = src;
 	return 0;
 }
@@ -1216,6 +1209,8 @@ static int dsicm_probe_of(struct platform_device *pdev)
 	struct display_timing timing;
 	int err;
 
+	ddata->channel = TCH;
+
 	ddata->reset_gpio = devm_gpiod_get(&pdev->dev, "reset", GPIOD_OUT_LOW);
 	if (IS_ERR(ddata->reset_gpio)) {
 		err = PTR_ERR(ddata->reset_gpio);
diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index de4ec6055490..4d55e7c9cd65 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -350,7 +350,6 @@ struct dsi_data {
 		struct omap_dss_device *dssdev;
 		enum fifo_size tx_fifo_size;
 		enum fifo_size rx_fifo_size;
-		int vc_id;
 	} vc[4];
 
 	struct mutex lock;
@@ -2579,7 +2578,7 @@ 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 | dsi->vc[channel].vc_id << 6;
+	data_id = data_type | channel << 6;
 
 	val = FLD_VAL(data_id, 7, 0) | FLD_VAL(len, 23, 8) |
 		FLD_VAL(ecc, 31, 24);
@@ -2683,7 +2682,7 @@ static int dsi_vc_send_short(struct dsi_data *dsi, int channel, u8 data_type,
 		return -EINVAL;
 	}
 
-	data_id = data_type | dsi->vc[channel].vc_id << 6;
+	data_id = data_type | channel << 6;
 
 	r = (data_id << 0) | (data << 8) | (ecc << 24);
 
@@ -4783,45 +4782,19 @@ static enum omap_channel dsi_get_channel(struct dsi_data *dsi)
 	}
 }
 
-static int dsi_request_vc(struct omap_dss_device *dssdev, int *channel)
+static int dsi_request_vc(struct omap_dss_device *dssdev, int channel)
 {
 	struct dsi_data *dsi = to_dsi_data(dssdev);
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(dsi->vc); i++) {
-		if (!dsi->vc[i].dssdev) {
-			dsi->vc[i].dssdev = dssdev;
-			*channel = i;
-			return 0;
-		}
-	}
 
-	DSSERR("cannot get VC for display %s", dssdev->name);
-	return -ENOSPC;
-}
-
-static int dsi_set_vc_id(struct omap_dss_device *dssdev, int channel, int vc_id)
-{
-	struct dsi_data *dsi = to_dsi_data(dssdev);
-
-	if (vc_id < 0 || vc_id > 3) {
-		DSSERR("VC ID out of range\n");
-		return -EINVAL;
-	}
-
-	if (channel < 0 || channel > 3) {
-		DSSERR("Virtual Channel out of range\n");
+	if (channel < 0 || channel > 3)
 		return -EINVAL;
-	}
 
-	if (dsi->vc[channel].dssdev != dssdev) {
-		DSSERR("Virtual Channel not allocated to display %s\n",
-			dssdev->name);
-		return -EINVAL;
+	if (dsi->vc[channel].dssdev) {
+		DSSERR("cannot get VC for display %s", dssdev->name);
+		return -EBUSY;
 	}
 
-	dsi->vc[channel].vc_id = vc_id;
-
+	dsi->vc[channel].dssdev = dssdev;
 	return 0;
 }
 
@@ -4832,7 +4805,6 @@ static void dsi_release_vc(struct omap_dss_device *dssdev, int channel)
 	if ((channel >= 0 && channel <= 3) &&
 		dsi->vc[channel].dssdev == dssdev) {
 		dsi->vc[channel].dssdev = NULL;
-		dsi->vc[channel].vc_id = 0;
 	}
 }
 
@@ -4937,7 +4909,6 @@ static const struct omap_dss_device_ops dsi_ops = {
 		.enable_te = dsi_enable_te,
 
 		.request_vc = dsi_request_vc,
-		.set_vc_id = dsi_set_vc_id,
 		.release_vc = dsi_release_vc,
 
 		.transfer = omap_dsi_transfer,
@@ -5393,7 +5364,6 @@ static int dsi_probe(struct platform_device *pdev)
 	for (i = 0; i < ARRAY_SIZE(dsi->vc); i++) {
 		dsi->vc[i].source = DSI_VC_SOURCE_L4;
 		dsi->vc[i].dssdev = NULL;
-		dsi->vc[i].vc_id = 0;
 	}
 
 	r = dsi_get_clocks(dsi);
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index 79ae4073c35f..143ff346c311 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -308,9 +308,7 @@ struct omapdss_dsi_ops {
 	void (*disable_video_output)(struct omap_dss_device *dssdev,
 			int channel);
 
-	int (*request_vc)(struct omap_dss_device *dssdev, int *channel);
-	int (*set_vc_id)(struct omap_dss_device *dssdev, int channel,
-			int vc_id);
+	int (*request_vc)(struct omap_dss_device *dssdev, int channel);
 	void (*release_vc)(struct omap_dss_device *dssdev, int channel);
 
 	/* data transfer */
-- 
2.24.0

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

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

* [RFCv1 08/42] drm/omap: dsi: simplify write function
  2019-11-17  2:39 [RFCv1 00/42] drm/omap: Convert DSI code to use drm_mipi_dsi and drm_panel Sebastian Reichel
                   ` (7 preceding siblings ...)
  2019-11-17  2:39 ` [RFCv1 07/42] drm/omap: dsi: drop virtual channel logic Sebastian Reichel
@ 2019-11-17  2:39 ` Sebastian Reichel
  2019-11-17  2:39 ` [RFCv1 09/42] drm/omap: dsi: simplify read functions Sebastian Reichel
                   ` (33 subsequent siblings)
  42 siblings, 0 replies; 64+ messages in thread
From: Sebastian Reichel @ 2019-11-17  2:39 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Tomi Valkeinen
  Cc: kernel, Tony Lindgren, H. Nikolaus Schaller, Merlijn Wajer,
	Sebastian Reichel, dri-devel, linux-omap

Simplify the write related messages handling by using the functionality
provided by CONFIG_DRM_MIPI_DSI.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 drivers/gpu/drm/omapdrm/dss/Kconfig |   1 +
 drivers/gpu/drm/omapdrm/dss/dsi.c   | 144 +++++++---------------------
 2 files changed, 33 insertions(+), 112 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/Kconfig b/drivers/gpu/drm/omapdrm/dss/Kconfig
index 956f23e1452d..1d7e31824ff3 100644
--- a/drivers/gpu/drm/omapdrm/dss/Kconfig
+++ b/drivers/gpu/drm/omapdrm/dss/Kconfig
@@ -94,6 +94,7 @@ config OMAP2_DSS_SDI
 
 config OMAP2_DSS_DSI
 	bool "DSI support"
+	select DRM_MIPI_DSI
         default n
 	help
 	  MIPI DSI (Display Serial Interface) support.
diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index 4d55e7c9cd65..696727673c6a 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -2696,97 +2696,49 @@ static int dsi_vc_send_null(struct dsi_data *dsi, int channel)
 	return dsi_vc_send_long(dsi, channel, MIPI_DSI_NULL_PACKET, NULL, 0, 0);
 }
 
-static int dsi_vc_write_nosync_common(struct dsi_data *dsi, int channel,
-				      const u8 *data, int len,
-				      enum dss_dsi_content_type type)
+static int dsi_vc_write_common(struct omap_dss_device *dssdev,
+			       const struct mipi_dsi_msg *msg)
 {
+	struct dsi_data *dsi = to_dsi_data(dssdev);
+	struct mipi_dsi_packet packet;
 	int r;
 
-	if (len == 0) {
-		BUG_ON(type == DSS_DSI_CONTENT_DCS);
-		r = dsi_vc_send_short(dsi, channel,
-				MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM, 0, 0);
-	} else if (len == 1) {
-		r = dsi_vc_send_short(dsi, channel,
-				type == DSS_DSI_CONTENT_GENERIC ?
-				MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM :
-				MIPI_DSI_DCS_SHORT_WRITE, data[0], 0);
-	} else if (len == 2) {
-		r = dsi_vc_send_short(dsi, channel,
-				type == DSS_DSI_CONTENT_GENERIC ?
-				MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM :
-				MIPI_DSI_DCS_SHORT_WRITE_PARAM,
-				data[0] | (data[1] << 8), 0);
+	r = mipi_dsi_create_packet(&packet, msg);
+	if (r < 0)
+		return r;
+
+	if (mipi_dsi_packet_format_is_short(msg->type)) {
+		u16 data = packet.header[1] | (packet.header[2] << 8);
+		r = dsi_vc_send_short(dsi, msg->channel, msg->type, data, 0);
 	} else {
-		r = dsi_vc_send_long(dsi, channel,
-				type == DSS_DSI_CONTENT_GENERIC ?
-				MIPI_DSI_GENERIC_LONG_WRITE :
-				MIPI_DSI_DCS_LONG_WRITE, data, len, 0);
+		r = dsi_vc_send_long(dsi, msg->channel, msg->type,
+						   msg->tx_buf, msg->tx_len, 0);
 	}
 
-	return r;
-}
-
-static int dsi_vc_dcs_write_nosync(struct omap_dss_device *dssdev, int channel,
-		const u8 *data, int len)
-{
-	struct dsi_data *dsi = to_dsi_data(dssdev);
-
-	return dsi_vc_write_nosync_common(dsi, channel, data, len,
-			DSS_DSI_CONTENT_DCS);
-}
-
-static int dsi_vc_generic_write_nosync(struct omap_dss_device *dssdev, int channel,
-		const u8 *data, int len)
-{
-	struct dsi_data *dsi = to_dsi_data(dssdev);
-
-	return dsi_vc_write_nosync_common(dsi, channel, data, len,
-			DSS_DSI_CONTENT_GENERIC);
-}
-
-static int dsi_vc_write_common(struct omap_dss_device *dssdev,
-			       int channel, const u8 *data, int len,
-			       enum dss_dsi_content_type type)
-{
-	struct dsi_data *dsi = to_dsi_data(dssdev);
-	int r;
+	if (r < 0)
+		return r;
 
-	r = dsi_vc_write_nosync_common(dsi, channel, data, len, type);
-	if (r)
-		goto err;
+	/*
+	 * we do not always have to do the BTA sync, for example we can
+	 * improve performance by setting the update window information
+	 * without sending BTA sync between the commands. In that case
+	 * we can return earily.
+	 */
 
-	r = dsi_vc_send_bta_sync(dssdev, channel);
-	if (r)
-		goto err;
+	r = dsi_vc_send_bta_sync(dssdev, msg->channel);
+	if (r) {
+		DSSERR("bta sync failed\n");
+		return r;
+	}
 
 	/* RX_FIFO_NOT_EMPTY */
-	if (REG_GET(dsi, DSI_VC_CTRL(channel), 20, 20)) {
+	if (REG_GET(dsi, DSI_VC_CTRL(msg->channel), 20, 20)) {
 		DSSERR("rx fifo not empty after write, dumping data:\n");
-		dsi_vc_flush_receive_data(dsi, channel);
-		r = -EIO;
-		goto err;
+		dsi_vc_flush_receive_data(dsi, msg->channel);
+		return -EIO;
 	}
 
 	return 0;
-err:
-	DSSERR("dsi_vc_write_common(ch %d, cmd 0x%02x, len %d) failed\n",
-			channel, data[0], len);
-	return r;
-}
-
-static int dsi_vc_dcs_write(struct omap_dss_device *dssdev, int channel,
-		const u8 *data, int len)
-{
-	return dsi_vc_write_common(dssdev, channel, data, len,
-			DSS_DSI_CONTENT_DCS);
-}
-
-static int dsi_vc_generic_write(struct omap_dss_device *dssdev, int channel,
-		const u8 *data, int len)
-{
-	return dsi_vc_write_common(dssdev, channel, data, len,
-			DSS_DSI_CONTENT_GENERIC);
 }
 
 static int dsi_vc_dcs_send_read_request(struct dsi_data *dsi, int channel,
@@ -3008,15 +2960,6 @@ static int dsi_vc_generic_read(struct omap_dss_device *dssdev, int channel,
 	return 0;
 }
 
-static int dsi_vc_set_max_rx_packet_size(struct omap_dss_device *dssdev, int channel,
-		u16 len)
-{
-	struct dsi_data *dsi = to_dsi_data(dssdev);
-
-	return dsi_vc_send_short(dsi, channel,
-			MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE, len, 0);
-}
-
 static int dsi_enter_ulps(struct dsi_data *dsi)
 {
 	DECLARE_COMPLETION_ONSTACK(completion);
@@ -4811,35 +4754,17 @@ static void dsi_release_vc(struct omap_dss_device *dssdev, int channel)
 static ssize_t omap_dsi_transfer(struct omap_dss_device *dssdev,
 				 const struct mipi_dsi_msg *msg)
 {
-	/*
-	 * no_sync can be used to optimize performance by sending
-	 * e.g. column and page information without syncing in
-	 * between. It's not absolutley required, so postpone this
-	 * feature for now.
-	 */
-	bool no_sync = false;
-	u16 val;
-
 	switch (msg->type) {
 	case MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM:
 	case MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM:
 	case MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM:
 	case MIPI_DSI_GENERIC_LONG_WRITE:
-		if (no_sync)
-			return dsi_vc_generic_write_nosync(dssdev, msg->channel,
-				                      msg->tx_buf, msg->tx_len);
-		else
-			return dsi_vc_generic_write(dssdev, msg->channel,
-						    msg->tx_buf, msg->tx_len);
 	case MIPI_DSI_DCS_SHORT_WRITE:
 	case MIPI_DSI_DCS_SHORT_WRITE_PARAM:
 	case MIPI_DSI_DCS_LONG_WRITE:
-		if (no_sync)
-			return dsi_vc_dcs_write_nosync(dssdev, msg->channel,
-						      msg->tx_buf, msg->tx_len);
-		else
-			return dsi_vc_dcs_write(dssdev, msg->channel,
-						msg->tx_buf, msg->tx_len);
+	case MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE:
+	case MIPI_DSI_NULL_PACKET:
+		return dsi_vc_write_common(dssdev, msg);
 	case MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM:
 	case MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM:
 	case MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM:
@@ -4849,11 +4774,6 @@ static ssize_t omap_dsi_transfer(struct omap_dss_device *dssdev,
 		return dsi_vc_dcs_read(dssdev, msg->channel,
 				((u8*) msg->tx_buf)[0],
 				msg->rx_buf, msg->rx_len);
-	case MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE:
-		val = le16_to_cpu(*((__le16*) msg->tx_buf));
-		return dsi_vc_set_max_rx_packet_size(dssdev, msg->channel, val);
-	case MIPI_DSI_NULL_PACKET:
-		return dsi_vc_send_null(to_dsi_data(dssdev), msg->channel);
 	}
 
 	return -EINVAL;
-- 
2.24.0

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

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

* [RFCv1 09/42] drm/omap: dsi: simplify read functions
  2019-11-17  2:39 [RFCv1 00/42] drm/omap: Convert DSI code to use drm_mipi_dsi and drm_panel Sebastian Reichel
                   ` (8 preceding siblings ...)
  2019-11-17  2:39 ` [RFCv1 08/42] drm/omap: dsi: simplify write function Sebastian Reichel
@ 2019-11-17  2:39 ` Sebastian Reichel
  2019-11-17  2:39 ` [RFCv1 10/42] drm/omap: dsi: switch dsi_vc_send_long/short to mipi_dsi_msg Sebastian Reichel
                   ` (32 subsequent siblings)
  42 siblings, 0 replies; 64+ messages in thread
From: Sebastian Reichel @ 2019-11-17  2:39 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Tomi Valkeinen
  Cc: kernel, Tony Lindgren, H. Nikolaus Schaller, Merlijn Wajer,
	Sebastian Reichel, dri-devel, linux-omap

Simplify the read related message handling by using the functionality
provided by CONFIG_DRM_MIPI_DSI.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 drivers/gpu/drm/omapdrm/dss/dsi.c | 109 +++++++++---------------------
 1 file changed, 33 insertions(+), 76 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index 696727673c6a..c22d438ae2b5 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -2741,60 +2741,6 @@ static int dsi_vc_write_common(struct omap_dss_device *dssdev,
 	return 0;
 }
 
-static int dsi_vc_dcs_send_read_request(struct dsi_data *dsi, int channel,
-					u8 dcs_cmd)
-{
-	int r;
-
-	if (dsi->debug_read)
-		DSSDBG("dsi_vc_dcs_send_read_request(ch%d, dcs_cmd %x)\n",
-			channel, dcs_cmd);
-
-	r = dsi_vc_send_short(dsi, channel, MIPI_DSI_DCS_READ, dcs_cmd, 0);
-	if (r) {
-		DSSERR("dsi_vc_dcs_send_read_request(ch %d, cmd 0x%02x)"
-			" failed\n", channel, dcs_cmd);
-		return r;
-	}
-
-	return 0;
-}
-
-static int dsi_vc_generic_send_read_request(struct dsi_data *dsi, int channel,
-					    const u8 *reqdata, int reqlen)
-{
-	u16 data;
-	u8 data_type;
-	int r;
-
-	if (dsi->debug_read)
-		DSSDBG("dsi_vc_generic_send_read_request(ch %d, reqlen %d)\n",
-			channel, reqlen);
-
-	if (reqlen == 0) {
-		data_type = MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM;
-		data = 0;
-	} else if (reqlen == 1) {
-		data_type = MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM;
-		data = reqdata[0];
-	} else if (reqlen == 2) {
-		data_type = MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM;
-		data = reqdata[0] | (reqdata[1] << 8);
-	} else {
-		BUG();
-		return -EINVAL;
-	}
-
-	r = dsi_vc_send_short(dsi, channel, data_type, data, 0);
-	if (r) {
-		DSSERR("dsi_vc_generic_send_read_request(ch %d, reqlen %d)"
-			" failed\n", channel, reqlen);
-		return r;
-	}
-
-	return 0;
-}
-
 static int dsi_vc_read_rx_fifo(struct dsi_data *dsi, int channel, u8 *buf,
 			       int buflen, enum dss_dsi_content_type type)
 {
@@ -2903,61 +2849,75 @@ static int dsi_vc_read_rx_fifo(struct dsi_data *dsi, int channel, u8 *buf,
 	return r;
 }
 
-static int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
-		u8 *buf, int buflen)
+static int dsi_vc_dcs_read(struct omap_dss_device *dssdev,
+			   const struct mipi_dsi_msg *msg)
 {
 	struct dsi_data *dsi = to_dsi_data(dssdev);
 	int r;
+	u8 dcs_cmd = ((u8*) msg->tx_buf)[0];
 
-	r = dsi_vc_dcs_send_read_request(dsi, channel, dcs_cmd);
+	r = dsi_vc_send_short(dsi, msg->channel, MIPI_DSI_DCS_READ, dcs_cmd, 0);
 	if (r)
 		goto err;
 
-	r = dsi_vc_send_bta_sync(dssdev, channel);
+	r = dsi_vc_send_bta_sync(dssdev, msg->channel);
 	if (r)
 		goto err;
 
-	r = dsi_vc_read_rx_fifo(dsi, channel, buf, buflen,
+	r = dsi_vc_read_rx_fifo(dsi, msg->channel, msg->rx_buf, msg->rx_len,
 		DSS_DSI_CONTENT_DCS);
 	if (r < 0)
 		goto err;
 
-	if (r != buflen) {
+	if (r != msg->rx_len) {
 		r = -EIO;
 		goto err;
 	}
 
 	return 0;
 err:
-	DSSERR("dsi_vc_dcs_read(ch %d, cmd 0x%02x) failed\n", channel, dcs_cmd);
+	DSSERR("dsi_vc_dcs_read(ch %d, cmd 0x%02x) failed\n",
+		msg->channel, dcs_cmd);
 	return r;
 }
 
-static int dsi_vc_generic_read(struct omap_dss_device *dssdev, int channel,
-		const u8 *reqdata, int reqlen, u8 *buf, int buflen)
+static int dsi_vc_generic_read(struct omap_dss_device *dssdev,
+			       const struct mipi_dsi_msg *msg)
 {
 	struct dsi_data *dsi = to_dsi_data(dssdev);
+	struct mipi_dsi_packet packet;
+	u16 data;
 	int r;
 
-	r = dsi_vc_generic_send_read_request(dsi, channel, reqdata, reqlen);
+	r = mipi_dsi_create_packet(&packet, msg);
+	if (r < 0)
+		goto err;
+
+	data = packet.header[1] | (packet.header[2] << 8);
+
+	r = dsi_vc_send_short(dsi, msg->channel, msg->type, data, 0);
 	if (r)
-		return r;
+		goto err;
 
-	r = dsi_vc_send_bta_sync(dssdev, channel);
+	r = dsi_vc_send_bta_sync(dssdev, msg->channel);
 	if (r)
-		return r;
+		goto err;
 
-	r = dsi_vc_read_rx_fifo(dsi, channel, buf, buflen,
+	r = dsi_vc_read_rx_fifo(dsi, msg->channel, msg->rx_buf, msg->rx_len,
 		DSS_DSI_CONTENT_GENERIC);
 	if (r < 0)
-		return r;
+		goto err;
 
-	if (r != buflen) {
+	if (r != msg->rx_len) {
 		r = -EIO;
-		return r;
+		goto err;
 	}
 
 	return 0;
+err:
+	DSSERR("dsi_vc_generic_read(ch %d, reqlen %d) failed\n",
+		msg->channel, msg->tx_len);
+	return r;
 }
 
 static int dsi_enter_ulps(struct dsi_data *dsi)
@@ -4768,12 +4728,9 @@ static ssize_t omap_dsi_transfer(struct omap_dss_device *dssdev,
 	case MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM:
 	case MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM:
 	case MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM:
-		return dsi_vc_generic_read(dssdev, msg->channel, msg->tx_buf,
-				msg->tx_len, msg->rx_buf, msg->rx_len);
+		return dsi_vc_generic_read(dssdev, msg);
 	case MIPI_DSI_DCS_READ:
-		return dsi_vc_dcs_read(dssdev, msg->channel,
-				((u8*) msg->tx_buf)[0],
-				msg->rx_buf, msg->rx_len);
+		return dsi_vc_dcs_read(dssdev, msg);
 	}
 
 	return -EINVAL;
-- 
2.24.0

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

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

* [RFCv1 10/42] drm/omap: dsi: switch dsi_vc_send_long/short to mipi_dsi_msg
  2019-11-17  2:39 [RFCv1 00/42] drm/omap: Convert DSI code to use drm_mipi_dsi and drm_panel Sebastian Reichel
                   ` (9 preceding siblings ...)
  2019-11-17  2:39 ` [RFCv1 09/42] drm/omap: dsi: simplify read functions Sebastian Reichel
@ 2019-11-17  2:39 ` Sebastian Reichel
  2019-11-17  2:39 ` [RFCv1 11/42] ARM: dts: omap: add channel to DSI panels Sebastian Reichel
                   ` (31 subsequent siblings)
  42 siblings, 0 replies; 64+ messages in thread
From: Sebastian Reichel @ 2019-11-17  2:39 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Tomi Valkeinen
  Cc: kernel, Tony Lindgren, H. Nikolaus Schaller, Merlijn Wajer,
	Sebastian Reichel, dri-devel, linux-omap

Simplify the DSI encoder by using mipi_dsi_msg for
dsi_vc_send_long and dsi_vc_send_short. Further improvements
require cleaning up the channel allocation code first.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 drivers/gpu/drm/omapdrm/dss/dsi.c | 92 +++++++++++++++----------------
 1 file changed, 45 insertions(+), 47 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index c22d438ae2b5..d39b84409656 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -2599,30 +2599,36 @@ static inline void dsi_vc_write_long_payload(struct dsi_data *dsi, int channel,
 	dsi_write_reg(dsi, DSI_VC_LONG_PACKET_PAYLOAD(channel), val);
 }
 
-static int dsi_vc_send_long(struct dsi_data *dsi, int channel, u8 data_type,
-			    const u8 *data, u16 len, u8 ecc)
+static int dsi_vc_send_long(struct dsi_data *dsi,
+			    const struct mipi_dsi_msg *msg)
 {
+	struct mipi_dsi_packet pkg;
 	/*u32 val; */
 	int i;
 	const u8 *p;
 	int r = 0;
 	u8 b1, b2, b3, b4;
 
+	r = mipi_dsi_create_packet(&pkg, msg);
+	if (r < 0)
+		return r;
+
 	if (dsi->debug_write)
-		DSSDBG("dsi_vc_send_long, %d bytes\n", len);
+		DSSDBG("dsi_vc_send_long, %d bytes\n", msg->tx_len);
 
 	/* len + header */
-	if (dsi->vc[channel].tx_fifo_size * 32 * 4 < len + 4) {
+	if (dsi->vc[msg->channel].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, channel, DSI_VC_SOURCE_L4);
+	dsi_vc_config_source(dsi, msg->channel, DSI_VC_SOURCE_L4);
 
-	dsi_vc_write_long_header(dsi, channel, data_type, len, ecc);
+	dsi_vc_write_long_header(dsi, msg->channel, msg->type, msg->tx_len,
+				 pkg.header[3]);
 
-	p = data;
-	for (i = 0; i < len >> 2; i++) {
+	p = msg->tx_buf;
+	for (i = 0; i < msg->tx_len >> 2; i++) {
 		if (dsi->debug_write)
 			DSSDBG("\tsending full packet %d\n", i);
 
@@ -2631,10 +2637,10 @@ static int dsi_vc_send_long(struct dsi_data *dsi, int channel, u8 data_type,
 		b3 = *p++;
 		b4 = *p++;
 
-		dsi_vc_write_long_payload(dsi, channel, b1, b2, b3, b4);
+		dsi_vc_write_long_payload(dsi, msg->channel, b1, b2, b3, b4);
 	}
 
-	i = len % 4;
+	i = msg->tx_len % 4;
 	if (i) {
 		b1 = 0; b2 = 0; b3 = 0;
 
@@ -2656,64 +2662,64 @@ static int dsi_vc_send_long(struct dsi_data *dsi, int channel, u8 data_type,
 			break;
 		}
 
-		dsi_vc_write_long_payload(dsi, channel, b1, b2, b3, 0);
+		dsi_vc_write_long_payload(dsi, msg->channel, b1, b2, b3, 0);
 	}
 
 	return r;
 }
 
-static int dsi_vc_send_short(struct dsi_data *dsi, int channel, u8 data_type,
-			     u16 data, u8 ecc)
+static int dsi_vc_send_short(struct dsi_data *dsi,
+			     const struct mipi_dsi_msg *msg)
 {
+	struct mipi_dsi_packet pkg;
 	u32 r;
-	u8 data_id;
+
+	r = mipi_dsi_create_packet(&pkg, msg);
+	if (r < 0)
+		return r;
 
 	WARN_ON(!dsi_bus_is_locked(dsi));
 
 	if (dsi->debug_write)
 		DSSDBG("dsi_vc_send_short(ch%d, dt %#x, b1 %#x, b2 %#x)\n",
-				channel,
-				data_type, data & 0xff, (data >> 8) & 0xff);
+				msg->channel,
+				msg->type, pkg.header[1], pkg.header[2]);
 
-	dsi_vc_config_source(dsi, channel, DSI_VC_SOURCE_L4);
+	dsi_vc_config_source(dsi, msg->channel, DSI_VC_SOURCE_L4);
 
-	if (FLD_GET(dsi_read_reg(dsi, DSI_VC_CTRL(channel)), 16, 16)) {
+	if (FLD_GET(dsi_read_reg(dsi, DSI_VC_CTRL(msg->channel)), 16, 16)) {
 		DSSERR("ERROR FIFO FULL, aborting transfer\n");
 		return -EINVAL;
 	}
 
-	data_id = data_type | channel << 6;
-
-	r = (data_id << 0) | (data << 8) | (ecc << 24);
+	r = pkg.header[3] << 24 | pkg.header[2] << 16 | pkg.header[1] << 8 |
+	    pkg.header[0];
 
-	dsi_write_reg(dsi, DSI_VC_SHORT_PACKET_HEADER(channel), r);
+	dsi_write_reg(dsi, DSI_VC_SHORT_PACKET_HEADER(msg->channel), r);
 
 	return 0;
 }
 
 static int dsi_vc_send_null(struct dsi_data *dsi, int channel)
 {
-	return dsi_vc_send_long(dsi, channel, MIPI_DSI_NULL_PACKET, NULL, 0, 0);
+	const struct mipi_dsi_msg msg = {
+		.channel = channel,
+		.type = MIPI_DSI_NULL_PACKET,
+	};
+
+	return dsi_vc_send_long(dsi, &msg);
 }
 
 static int dsi_vc_write_common(struct omap_dss_device *dssdev,
 			       const struct mipi_dsi_msg *msg)
 {
 	struct dsi_data *dsi = to_dsi_data(dssdev);
-	struct mipi_dsi_packet packet;
 	int r;
 
-	r = mipi_dsi_create_packet(&packet, msg);
-	if (r < 0)
-		return r;
-
-	if (mipi_dsi_packet_format_is_short(msg->type)) {
-		u16 data = packet.header[1] | (packet.header[2] << 8);
-		r = dsi_vc_send_short(dsi, msg->channel, msg->type, data, 0);
-	} else {
-		r = dsi_vc_send_long(dsi, msg->channel, msg->type,
-						   msg->tx_buf, msg->tx_len, 0);
-	}
+	if (mipi_dsi_packet_format_is_short(msg->type))
+		r = dsi_vc_send_short(dsi, msg);
+	else
+		r = dsi_vc_send_long(dsi, msg);
 
 	if (r < 0)
 		return r;
@@ -2853,10 +2859,10 @@ static int dsi_vc_dcs_read(struct omap_dss_device *dssdev,
 			   const struct mipi_dsi_msg *msg)
 {
 	struct dsi_data *dsi = to_dsi_data(dssdev);
+	u8 cmd = ((u8*) msg->tx_buf)[0];
 	int r;
-	u8 dcs_cmd = ((u8*) msg->tx_buf)[0];
 
-	r = dsi_vc_send_short(dsi, msg->channel, MIPI_DSI_DCS_READ, dcs_cmd, 0);
+	r = dsi_vc_send_short(dsi, msg);
 	if (r)
 		goto err;
 
@@ -2877,7 +2883,7 @@ static int dsi_vc_dcs_read(struct omap_dss_device *dssdev,
 	return 0;
 err:
 	DSSERR("dsi_vc_dcs_read(ch %d, cmd 0x%02x) failed\n",
-		msg->channel, dcs_cmd);
+		msg->channel, cmd);
 	return r;
 }
 
@@ -2885,17 +2891,9 @@ static int dsi_vc_generic_read(struct omap_dss_device *dssdev,
 			       const struct mipi_dsi_msg *msg)
 {
 	struct dsi_data *dsi = to_dsi_data(dssdev);
-	struct mipi_dsi_packet packet;
-	u16 data;
 	int r;
 
-	r = mipi_dsi_create_packet(&packet, msg);
-	if (r < 0)
-		goto err;
-
-	data = packet.header[1] | (packet.header[2] << 8);
-
-	r = dsi_vc_send_short(dsi, msg->channel, msg->type, data, 0);
+	r = dsi_vc_send_short(dsi, msg);
 	if (r)
 		goto err;
 
-- 
2.24.0

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

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

* [RFCv1 11/42] ARM: dts: omap: add channel to DSI panels
  2019-11-17  2:39 [RFCv1 00/42] drm/omap: Convert DSI code to use drm_mipi_dsi and drm_panel Sebastian Reichel
                   ` (10 preceding siblings ...)
  2019-11-17  2:39 ` [RFCv1 10/42] drm/omap: dsi: switch dsi_vc_send_long/short to mipi_dsi_msg Sebastian Reichel
@ 2019-11-17  2:39 ` Sebastian Reichel
  2019-11-18 13:05   ` Tomi Valkeinen
  2019-11-17  2:39 ` [RFCv1 12/42] drm/omap: dsi: introduce mipi_dsi_host Sebastian Reichel
                   ` (30 subsequent siblings)
  42 siblings, 1 reply; 64+ messages in thread
From: Sebastian Reichel @ 2019-11-17  2:39 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Tomi Valkeinen
  Cc: kernel, Tony Lindgren, H. Nikolaus Schaller, Merlijn Wajer,
	Sebastian Reichel, dri-devel, linux-omap

The standard binding for DSI requires, that the channel number
of the panel is encoded in DT. This adds the channel number in
all OMAP3-5 boards, in preparation for using common infrastructure.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 .../devicetree/bindings/display/panel/panel-dsi-cm.txt      | 4 +++-
 arch/arm/boot/dts/omap3-n950.dts                            | 3 ++-
 arch/arm/boot/dts/omap3.dtsi                                | 3 +++
 arch/arm/boot/dts/omap4-droid4-xt894.dts                    | 3 ++-
 arch/arm/boot/dts/omap4-sdp.dts                             | 6 ++++--
 arch/arm/boot/dts/omap4.dtsi                                | 6 ++++++
 arch/arm/boot/dts/omap5.dtsi                                | 6 ++++++
 7 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/panel/panel-dsi-cm.txt b/Documentation/devicetree/bindings/display/panel/panel-dsi-cm.txt
index dce48eb9db57..f92d5c9adfc5 100644
--- a/Documentation/devicetree/bindings/display/panel/panel-dsi-cm.txt
+++ b/Documentation/devicetree/bindings/display/panel/panel-dsi-cm.txt
@@ -3,6 +3,7 @@ Generic MIPI DSI Command Mode Panel
 
 Required properties:
 - compatible: "panel-dsi-cm"
+- reg: DSI channel number
 
 Optional properties:
 - label: a symbolic name for the panel
@@ -15,9 +16,10 @@ Required nodes:
 Example
 -------
 
-lcd0: display {
+lcd0: panel@0 {
 	compatible = "tpo,taal", "panel-dsi-cm";
 	label = "lcd0";
+	reg = <0>;
 
 	reset-gpios = <&gpio4 6 GPIO_ACTIVE_HIGH>;
 
diff --git a/arch/arm/boot/dts/omap3-n950.dts b/arch/arm/boot/dts/omap3-n950.dts
index 9886bf8b90ab..d1dfafde351e 100644
--- a/arch/arm/boot/dts/omap3-n950.dts
+++ b/arch/arm/boot/dts/omap3-n950.dts
@@ -225,8 +225,9 @@
 		};
 	};
 
-	lcd0: display {
+	lcd0: panel@0 {
 		compatible = "nokia,himalaya", "panel-dsi-cm";
+		reg = <0>;
 		label = "lcd0";
 
 		pinctrl-names = "default";
diff --git a/arch/arm/boot/dts/omap3.dtsi b/arch/arm/boot/dts/omap3.dtsi
index 4043ecb38016..b872b933f2cb 100644
--- a/arch/arm/boot/dts/omap3.dtsi
+++ b/arch/arm/boot/dts/omap3.dtsi
@@ -771,6 +771,9 @@
 				ti,hwmods = "dss_dsi1";
 				clocks = <&dss1_alwon_fck>, <&dss2_alwon_fck>;
 				clock-names = "fck", "sys_clk";
+
+				#address-cells = <1>;
+				#size-cells = <0>;
 			};
 
 			rfbi: encoder@48050800 {
diff --git a/arch/arm/boot/dts/omap4-droid4-xt894.dts b/arch/arm/boot/dts/omap4-droid4-xt894.dts
index a40fe8d49da6..6af0a9288940 100644
--- a/arch/arm/boot/dts/omap4-droid4-xt894.dts
+++ b/arch/arm/boot/dts/omap4-droid4-xt894.dts
@@ -202,8 +202,9 @@
 		};
 	};
 
-	lcd0: display {
+	lcd0: panel@0 {
 		compatible = "panel-dsi-cm";
+		reg = <0>;
 		label = "lcd0";
 		vddi-supply = <&lcd_regulator>;
 		reset-gpios = <&gpio4 5 GPIO_ACTIVE_HIGH>;	/* gpio101 */
diff --git a/arch/arm/boot/dts/omap4-sdp.dts b/arch/arm/boot/dts/omap4-sdp.dts
index 91480ac1f328..8a8307517dab 100644
--- a/arch/arm/boot/dts/omap4-sdp.dts
+++ b/arch/arm/boot/dts/omap4-sdp.dts
@@ -662,8 +662,9 @@
 		};
 	};
 
-	lcd0: display {
+	lcd0: panel@0 {
 		compatible = "tpo,taal", "panel-dsi-cm";
+		reg = <0>;
 		label = "lcd0";
 
 		reset-gpios = <&gpio4 6 GPIO_ACTIVE_HIGH>;	/* 102 */
@@ -687,8 +688,9 @@
 		};
 	};
 
-	lcd1: display {
+	lcd1: panel@0 {
 		compatible = "tpo,taal", "panel-dsi-cm";
+		reg = <0>;
 		label = "lcd1";
 
 		reset-gpios = <&gpio4 8 GPIO_ACTIVE_HIGH>;	/* 104 */
diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi
index 7cc95bc1598b..a0807cd90eff 100644
--- a/arch/arm/boot/dts/omap4.dtsi
+++ b/arch/arm/boot/dts/omap4.dtsi
@@ -403,6 +403,9 @@
 				clocks = <&l3_dss_clkctrl OMAP4_DSS_CORE_CLKCTRL 8>,
 					 <&l3_dss_clkctrl OMAP4_DSS_CORE_CLKCTRL 10>;
 				clock-names = "fck", "sys_clk";
+
+				#address-cells = <1>;
+				#size-cells = <0>;
 			};
 
 			dsi2: encoder@58005000 {
@@ -417,6 +420,9 @@
 				clocks = <&l3_dss_clkctrl OMAP4_DSS_CORE_CLKCTRL 8>,
 					 <&l3_dss_clkctrl OMAP4_DSS_CORE_CLKCTRL 10>;
 				clock-names = "fck", "sys_clk";
+
+				#address-cells = <1>;
+				#size-cells = <0>;
 			};
 
 			hdmi: encoder@58006000 {
diff --git a/arch/arm/boot/dts/omap5.dtsi b/arch/arm/boot/dts/omap5.dtsi
index 1fb7937638f0..05fd27a1f42e 100644
--- a/arch/arm/boot/dts/omap5.dtsi
+++ b/arch/arm/boot/dts/omap5.dtsi
@@ -321,6 +321,9 @@
 				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>;
 			};
 
 			dsi2: encoder@58005000 {
@@ -335,6 +338,9 @@
 				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>;
 			};
 
 			hdmi: encoder@58060000 {
-- 
2.24.0

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

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

* [RFCv1 12/42] drm/omap: dsi: introduce mipi_dsi_host
  2019-11-17  2:39 [RFCv1 00/42] drm/omap: Convert DSI code to use drm_mipi_dsi and drm_panel Sebastian Reichel
                   ` (11 preceding siblings ...)
  2019-11-17  2:39 ` [RFCv1 11/42] ARM: dts: omap: add channel to DSI panels Sebastian Reichel
@ 2019-11-17  2:39 ` Sebastian Reichel
  2019-11-17  2:39 ` [RFCv1 13/42] drm/omap: panel-dsi-cm: use DSI helpers Sebastian Reichel
                   ` (29 subsequent siblings)
  42 siblings, 0 replies; 64+ messages in thread
From: Sebastian Reichel @ 2019-11-17  2:39 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Tomi Valkeinen
  Cc: kernel, Tony Lindgren, H. Nikolaus Schaller, Merlijn Wajer,
	Sebastian Reichel, dri-devel, linux-omap

This moves from custom platform driver infrastructure to mipi_dsi_host
and mipi_dsi_device. Note, that this is a graduate step and the driver
only uses the devices types and transfer function, but not yet the new
device binding style or drm_panel.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 .../gpu/drm/omapdrm/displays/panel-dsi-cm.c   | 119 +++++++++---------
 drivers/gpu/drm/omapdrm/dss/dsi.c             |  54 ++++++--
 drivers/gpu/drm/omapdrm/dss/omapdss.h         |   4 -
 3 files changed, 102 insertions(+), 75 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
index b505bfd221fc..e2e56cc1cd61 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
@@ -14,7 +14,6 @@
 #include <linux/interrupt.h>
 #include <linux/jiffies.h>
 #include <linux/module.h>
-#include <linux/platform_device.h>
 #include <linux/sched/signal.h>
 #include <linux/slab.h>
 #include <linux/workqueue.h>
@@ -39,13 +38,13 @@
 #define DCS_GET_ID3		0xdc
 
 struct panel_drv_data {
+	struct mipi_dsi_device *dsi;
+
 	struct omap_dss_device dssdev;
 	struct omap_dss_device *src;
 
 	struct videomode vm;
 
-	struct platform_device *pdev;
-
 	struct mutex lock;
 
 	struct backlight_device *bldev;
@@ -139,7 +138,7 @@ static void hw_guard_wait(struct panel_drv_data *ddata)
 
 static int dsicm_dcs_read_1(struct panel_drv_data *ddata, u8 dcs_cmd, u8 *data)
 {
-	struct omap_dss_device *src = ddata->src;
+	struct mipi_dsi_device *dsi = ddata->dsi;
 	const struct mipi_dsi_msg msg = {
 		.channel = ddata->channel,
 		.type = MIPI_DSI_DCS_READ,
@@ -149,12 +148,12 @@ static int dsicm_dcs_read_1(struct panel_drv_data *ddata, u8 dcs_cmd, u8 *data)
 		.rx_buf = data
 	};
 
-	return src->ops->dsi.transfer(src, &msg);
+	return dsi->host->ops->transfer(dsi->host, &msg);
 }
 
 static int dsicm_dcs_write_0(struct panel_drv_data *ddata, u8 dcs_cmd)
 {
-	struct omap_dss_device *src = ddata->src;
+	struct mipi_dsi_device *dsi = ddata->dsi;
 	const struct mipi_dsi_msg msg = {
 		.channel = ddata->channel,
 		.type = MIPI_DSI_DCS_SHORT_WRITE,
@@ -162,12 +161,12 @@ static int dsicm_dcs_write_0(struct panel_drv_data *ddata, u8 dcs_cmd)
 		.tx_len = 1,
 	};
 
-	return src->ops->dsi.transfer(src, &msg);
+	return dsi->host->ops->transfer(dsi->host, &msg);
 }
 
 static int dsicm_dcs_write_1(struct panel_drv_data *ddata, u8 dcs_cmd, u8 param)
 {
-	struct omap_dss_device *src = ddata->src;
+	struct mipi_dsi_device *dsi = ddata->dsi;
 	const u8 buf[] = { dcs_cmd, param };
 	const struct mipi_dsi_msg msg = {
 		.channel = ddata->channel,
@@ -176,13 +175,13 @@ static int dsicm_dcs_write_1(struct panel_drv_data *ddata, u8 dcs_cmd, u8 param)
 		.tx_len = 2,
 	};
 
-	return src->ops->dsi.transfer(src, &msg);
+	return dsi->host->ops->transfer(dsi->host, &msg);
 }
 
 static int dsicm_sleep_in(struct panel_drv_data *ddata)
 
 {
-	struct omap_dss_device *src = ddata->src;
+	struct mipi_dsi_device *dsi = ddata->dsi;
 	int r;
 	const u8 cmd = MIPI_DCS_ENTER_SLEEP_MODE;
 	const struct mipi_dsi_msg msg = {
@@ -194,7 +193,7 @@ static int dsicm_sleep_in(struct panel_drv_data *ddata)
 
 	hw_guard_wait(ddata);
 
-	r = src->ops->dsi.transfer(src, &msg);
+	r = dsi->host->ops->transfer(dsi->host, &msg);
 	if (r)
 		return r;
 
@@ -242,7 +241,7 @@ static int dsicm_get_id(struct panel_drv_data *ddata, u8 *id1, u8 *id2, u8 *id3)
 static int dsicm_set_update_window(struct panel_drv_data *ddata,
 		u16 x, u16 y, u16 w, u16 h)
 {
-	struct omap_dss_device *src = ddata->src;
+	struct mipi_dsi_device *dsi = ddata->dsi;
 	int r;
 	u16 x1 = x;
 	u16 x2 = x + w - 1;
@@ -280,11 +279,11 @@ static int dsicm_set_update_window(struct panel_drv_data *ddata,
 	};
 
 
-	r = src->ops->dsi.transfer(src, &msgX);
+	r = dsi->host->ops->transfer(dsi->host, &msgX);
 	if (r)
 		return r;
 
-	r = src->ops->dsi.transfer(src, &msgY);
+	r = dsi->host->ops->transfer(dsi->host, &msgY);
 	if (r)
 		return r;
 
@@ -327,7 +326,7 @@ static int dsicm_enter_ulps(struct panel_drv_data *ddata)
 	return 0;
 
 err:
-	dev_err(&ddata->pdev->dev, "enter ULPS failed");
+	dev_err(&ddata->dsi->dev, "enter ULPS failed");
 	dsicm_panel_reset(ddata);
 
 	ddata->ulps_enabled = false;
@@ -350,7 +349,7 @@ static int dsicm_exit_ulps(struct panel_drv_data *ddata)
 
 	r = _dsicm_enable_te(ddata, true);
 	if (r) {
-		dev_err(&ddata->pdev->dev, "failed to re-enable TE");
+		dev_err(&ddata->dsi->dev, "failed to re-enable TE");
 		goto err2;
 	}
 
@@ -364,7 +363,7 @@ static int dsicm_exit_ulps(struct panel_drv_data *ddata)
 	return 0;
 
 err2:
-	dev_err(&ddata->pdev->dev, "failed to exit ULPS");
+	dev_err(&ddata->dsi->dev, "failed to exit ULPS");
 
 	r = dsicm_panel_reset(ddata);
 	if (!r) {
@@ -401,7 +400,7 @@ static int dsicm_bl_update_status(struct backlight_device *dev)
 	else
 		level = 0;
 
-	dev_dbg(&ddata->pdev->dev, "update brightness to %d\n", level);
+	dev_dbg(&ddata->dsi->dev, "update brightness to %d\n", level);
 
 	mutex_lock(&ddata->lock);
 
@@ -638,7 +637,7 @@ static int dsicm_power_on(struct panel_drv_data *ddata)
 	if (ddata->vpnl) {
 		r = regulator_enable(ddata->vpnl);
 		if (r) {
-			dev_err(&ddata->pdev->dev,
+			dev_err(&ddata->dsi->dev,
 				"failed to enable VPNL: %d\n", r);
 			return r;
 		}
@@ -647,7 +646,7 @@ static int dsicm_power_on(struct panel_drv_data *ddata)
 	if (ddata->vddi) {
 		r = regulator_enable(ddata->vddi);
 		if (r) {
-			dev_err(&ddata->pdev->dev,
+			dev_err(&ddata->dsi->dev,
 				"failed to enable VDDI: %d\n", r);
 			goto err_vpnl;
 		}
@@ -655,7 +654,7 @@ static int dsicm_power_on(struct panel_drv_data *ddata)
 
 	r = src->ops->dsi.set_config(src, &dsi_config);
 	if (r) {
-		dev_err(&ddata->pdev->dev, "failed to configure DSI\n");
+		dev_err(&ddata->dsi->dev, "failed to configure DSI\n");
 		goto err_vddi;
 	}
 
@@ -702,7 +701,7 @@ static int dsicm_power_on(struct panel_drv_data *ddata)
 	ddata->enabled = 1;
 
 	if (!ddata->intro_printed) {
-		dev_info(&ddata->pdev->dev, "panel revision %02x.%02x.%02x\n",
+		dev_info(&ddata->dsi->dev, "panel revision %02x.%02x.%02x\n",
 			id1, id2, id3);
 		ddata->intro_printed = true;
 	}
@@ -711,7 +710,7 @@ static int dsicm_power_on(struct panel_drv_data *ddata)
 
 	return 0;
 err:
-	dev_err(&ddata->pdev->dev, "error while enabling panel, issuing HW reset\n");
+	dev_err(&ddata->dsi->dev, "error while enabling panel, issuing HW reset\n");
 
 	dsicm_hw_reset(ddata);
 
@@ -738,7 +737,7 @@ static void dsicm_power_off(struct panel_drv_data *ddata)
 		r = dsicm_sleep_in(ddata);
 
 	if (r) {
-		dev_err(&ddata->pdev->dev,
+		dev_err(&ddata->dsi->dev,
 				"error disabling panel, issuing HW reset\n");
 		dsicm_hw_reset(ddata);
 	}
@@ -755,7 +754,7 @@ static void dsicm_power_off(struct panel_drv_data *ddata)
 
 static int dsicm_panel_reset(struct panel_drv_data *ddata)
 {
-	dev_err(&ddata->pdev->dev, "performing LCD reset\n");
+	dev_err(&ddata->dsi->dev, "performing LCD reset\n");
 
 	dsicm_power_off(ddata);
 	dsicm_hw_reset(ddata);
@@ -766,7 +765,7 @@ static int dsicm_connect(struct omap_dss_device *src,
 			 struct omap_dss_device *dst)
 {
 	struct panel_drv_data *ddata = to_panel_data(dst);
-	struct device *dev = &ddata->pdev->dev;
+	struct device *dev = &ddata->dsi->dev;
 	int r;
 
 	r = src->ops->dsi.request_vc(src, ddata->channel);
@@ -811,7 +810,7 @@ static void dsicm_enable(struct omap_dss_device *dssdev)
 
 	return;
 err:
-	dev_dbg(&ddata->pdev->dev, "enable failed (%d)\n", r);
+	dev_dbg(&ddata->dsi->dev, "enable failed (%d)\n", r);
 	mutex_unlock(&ddata->lock);
 }
 
@@ -843,7 +842,7 @@ static void dsicm_framedone_cb(int err, void *data)
 	struct panel_drv_data *ddata = data;
 	struct omap_dss_device *src = ddata->src;
 
-	dev_dbg(&ddata->pdev->dev, "framedone, err %d\n", err);
+	dev_dbg(&ddata->dsi->dev, "framedone, err %d\n", err);
 	src->ops->dsi.bus_unlock(src);
 }
 
@@ -867,7 +866,7 @@ static irqreturn_t dsicm_te_isr(int irq, void *data)
 
 	return IRQ_HANDLED;
 err:
-	dev_err(&ddata->pdev->dev, "start update failed\n");
+	dev_err(&ddata->dsi->dev, "start update failed\n");
 	src->ops->dsi.bus_unlock(src);
 	return IRQ_HANDLED;
 }
@@ -878,7 +877,7 @@ static void dsicm_te_timeout_work_callback(struct work_struct *work)
 					te_timeout_work.work);
 	struct omap_dss_device *src = ddata->src;
 
-	dev_err(&ddata->pdev->dev, "TE not received for 250ms!\n");
+	dev_err(&ddata->dsi->dev, "TE not received for 250ms!\n");
 
 	atomic_set(&ddata->do_update, 0);
 	src->ops->dsi.bus_unlock(src);
@@ -891,7 +890,7 @@ static int dsicm_update(struct omap_dss_device *dssdev,
 	struct omap_dss_device *src = ddata->src;
 	int r;
 
-	dev_dbg(&ddata->pdev->dev, "update %d, %d, %d x %d\n", x, y, w, h);
+	dev_dbg(&ddata->dsi->dev, "update %d, %d, %d x %d\n", x, y, w, h);
 
 	mutex_lock(&ddata->lock);
 	src->ops->dsi.bus_lock(src);
@@ -936,14 +935,14 @@ static int dsicm_sync(struct omap_dss_device *dssdev)
 	struct panel_drv_data *ddata = to_panel_data(dssdev);
 	struct omap_dss_device *src = ddata->src;
 
-	dev_dbg(&ddata->pdev->dev, "sync\n");
+	dev_dbg(&ddata->dsi->dev, "sync\n");
 
 	mutex_lock(&ddata->lock);
 	src->ops->dsi.bus_lock(src);
 	src->ops->dsi.bus_unlock(src);
 	mutex_unlock(&ddata->lock);
 
-	dev_dbg(&ddata->pdev->dev, "sync done\n");
+	dev_dbg(&ddata->dsi->dev, "sync done\n");
 
 	return 0;
 }
@@ -1020,7 +1019,7 @@ static int dsicm_set_max_rx_packet_size(struct omap_dss_device *dssdev,
                                         u16 size)
 {
 	struct panel_drv_data *ddata = to_panel_data(dssdev);
-	struct omap_dss_device *src = ddata->src;
+	struct mipi_dsi_device *dsi = ddata->dsi;
 
 	const u8 buf[] = {
 		size & 0xff,
@@ -1034,7 +1033,7 @@ static int dsicm_set_max_rx_packet_size(struct omap_dss_device *dssdev,
 		.tx_len = 2,
 	};
 
-	return src->ops->dsi.transfer(src, &msg);
+	return dsi->host->ops->transfer(dsi->host, &msg);
 }
 
 static int dsicm_memory_read(struct omap_dss_device *dssdev,
@@ -1042,6 +1041,7 @@ static int dsicm_memory_read(struct omap_dss_device *dssdev,
 		u16 x, u16 y, u16 w, u16 h)
 {
 	struct panel_drv_data *ddata = to_panel_data(dssdev);
+	struct mipi_dsi_device *dsi = ddata->dsi;
 	struct omap_dss_device *src = ddata->src;
 	int r;
 	int first = 1;
@@ -1093,7 +1093,7 @@ static int dsicm_memory_read(struct omap_dss_device *dssdev,
 		};
 		first = 0;
 
-		r = src->ops->dsi.transfer(src, &msg);
+		r = dsi->host->ops->transfer(dsi->host, &msg);
 		if (r < 0) {
 			dev_err(dssdev->dev, "read error\n");
 			goto err3;
@@ -1102,12 +1102,12 @@ static int dsicm_memory_read(struct omap_dss_device *dssdev,
 		buf_used += r;
 
 		if (r < plen) {
-			dev_err(&ddata->pdev->dev, "short read\n");
+			dev_err(&ddata->dsi->dev, "short read\n");
 			break;
 		}
 
 		if (signal_pending(current)) {
-			dev_err(&ddata->pdev->dev, "signal pending, "
+			dev_err(&ddata->dsi->dev, "signal pending, "
 					"aborting memory read\n");
 			r = -ERESTARTSYS;
 			goto err3;
@@ -1201,28 +1201,28 @@ static const struct omap_dss_driver dsicm_dss_driver = {
 	.memory_read	= dsicm_memory_read,
 };
 
-static int dsicm_probe_of(struct platform_device *pdev)
+static int dsicm_probe_of(struct mipi_dsi_device *dsi)
 {
-	struct device_node *node = pdev->dev.of_node;
+	struct device_node *node = dsi->dev.of_node;
 	struct device_node *backlight;
-	struct panel_drv_data *ddata = platform_get_drvdata(pdev);
+	struct panel_drv_data *ddata = mipi_dsi_get_drvdata(dsi);
 	struct display_timing timing;
 	int err;
 
 	ddata->channel = TCH;
 
-	ddata->reset_gpio = devm_gpiod_get(&pdev->dev, "reset", GPIOD_OUT_LOW);
+	ddata->reset_gpio = devm_gpiod_get(&dsi->dev, "reset", GPIOD_OUT_LOW);
 	if (IS_ERR(ddata->reset_gpio)) {
 		err = PTR_ERR(ddata->reset_gpio);
-		dev_err(&pdev->dev, "reset gpio request failed: %d", err);
+		dev_err(&dsi->dev, "reset gpio request failed: %d", err);
 		return err;
 	}
 
-	ddata->ext_te_gpio = devm_gpiod_get_optional(&pdev->dev, "te",
+	ddata->ext_te_gpio = devm_gpiod_get_optional(&dsi->dev, "te",
 						     GPIOD_IN);
 	if (IS_ERR(ddata->ext_te_gpio)) {
 		err = PTR_ERR(ddata->ext_te_gpio);
-		dev_err(&pdev->dev, "TE gpio request failed: %d", err);
+		dev_err(&dsi->dev, "TE gpio request failed: %d", err);
 		return err;
 	}
 
@@ -1233,7 +1233,7 @@ static int dsicm_probe_of(struct platform_device *pdev)
 			ddata->vm.pixelclock =
 				ddata->vm.hactive * ddata->vm.vactive * 60;
 	} else {
-		dev_warn(&pdev->dev,
+		dev_warn(&dsi->dev,
 			 "failed to get video timing, using defaults\n");
 	}
 
@@ -1243,7 +1243,7 @@ static int dsicm_probe_of(struct platform_device *pdev)
 	ddata->height_mm = 0;
 	of_property_read_u32(node, "height-mm", &ddata->height_mm);
 
-	ddata->vpnl = devm_regulator_get_optional(&pdev->dev, "vpnl");
+	ddata->vpnl = devm_regulator_get_optional(&dsi->dev, "vpnl");
 	if (IS_ERR(ddata->vpnl)) {
 		err = PTR_ERR(ddata->vpnl);
 		if (err == -EPROBE_DEFER)
@@ -1251,7 +1251,7 @@ static int dsicm_probe_of(struct platform_device *pdev)
 		ddata->vpnl = NULL;
 	}
 
-	ddata->vddi = devm_regulator_get_optional(&pdev->dev, "vddi");
+	ddata->vddi = devm_regulator_get_optional(&dsi->dev, "vddi");
 	if (IS_ERR(ddata->vddi)) {
 		err = PTR_ERR(ddata->vddi);
 		if (err == -EPROBE_DEFER)
@@ -1276,11 +1276,11 @@ static int dsicm_probe_of(struct platform_device *pdev)
 	return 0;
 }
 
-static int dsicm_probe(struct platform_device *pdev)
+static int dsicm_probe(struct mipi_dsi_device *dsi)
 {
 	struct panel_drv_data *ddata;
 	struct backlight_device *bldev = NULL;
-	struct device *dev = &pdev->dev;
+	struct device *dev = &dsi->dev;
 	struct omap_dss_device *dssdev;
 	int r;
 
@@ -1290,14 +1290,14 @@ static int dsicm_probe(struct platform_device *pdev)
 	if (!ddata)
 		return -ENOMEM;
 
-	platform_set_drvdata(pdev, ddata);
-	ddata->pdev = pdev;
+	mipi_dsi_set_drvdata(dsi, ddata);
+	ddata->dsi = dsi;
 
 	ddata->vm.hactive = 864;
 	ddata->vm.vactive = 480;
 	ddata->vm.pixelclock = 864 * 480 * 60;
 
-	r = dsicm_probe_of(pdev);
+	r = dsicm_probe_of(dsi);
 	if (r)
 		return r;
 
@@ -1379,12 +1379,12 @@ static int dsicm_probe(struct platform_device *pdev)
 	return r;
 }
 
-static int __exit dsicm_remove(struct platform_device *pdev)
+static int __exit dsicm_remove(struct mipi_dsi_device *dsi)
 {
-	struct panel_drv_data *ddata = platform_get_drvdata(pdev);
+	struct panel_drv_data *ddata = mipi_dsi_get_drvdata(dsi);
 	struct omap_dss_device *dssdev = &ddata->dssdev;
 
-	dev_dbg(&pdev->dev, "remove\n");
+	dev_dbg(&dsi->dev, "remove\n");
 
 	omapdss_device_unregister(dssdev);
 
@@ -1392,7 +1392,7 @@ static int __exit dsicm_remove(struct platform_device *pdev)
 		dsicm_disable(dssdev);
 	omapdss_device_disconnect(ddata->src, dssdev);
 
-	sysfs_remove_group(&pdev->dev.kobj, &dsicm_attr_group);
+	sysfs_remove_group(&dsi->dev.kobj, &dsicm_attr_group);
 
 	if (ddata->extbldev)
 		put_device(&ddata->extbldev->dev);
@@ -1413,7 +1413,7 @@ static const struct of_device_id dsicm_of_match[] = {
 
 MODULE_DEVICE_TABLE(of, dsicm_of_match);
 
-static struct platform_driver dsicm_driver = {
+static struct mipi_dsi_driver dsicm_driver = {
 	.probe = dsicm_probe,
 	.remove = __exit_p(dsicm_remove),
 	.driver = {
@@ -1422,8 +1422,7 @@ static struct platform_driver dsicm_driver = {
 		.suppress_bind_attrs = true,
 	},
 };
-
-module_platform_driver(dsicm_driver);
+module_mipi_dsi_driver(dsicm_driver);
 
 MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@ti.com>");
 MODULE_DESCRIPTION("Generic DSI Command Mode Panel Driver");
diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index d39b84409656..c4107fe5a53d 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -334,6 +334,8 @@ struct dsi_data {
 	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;
 
@@ -432,6 +434,11 @@ static inline struct dsi_data *to_dsi_data(struct omap_dss_device *dssdev)
 	return dev_get_drvdata(dssdev->dev);
 }
 
+static inline struct dsi_data *host_to_omap(struct mipi_dsi_host *host)
+{
+	return container_of(host, struct dsi_data, host);
+}
+
 static inline void dsi_write_reg(struct dsi_data *dsi,
 				 const struct dsi_reg idx, u32 val)
 {
@@ -4709,9 +4716,12 @@ static void dsi_release_vc(struct omap_dss_device *dssdev, int channel)
 	}
 }
 
-static ssize_t omap_dsi_transfer(struct omap_dss_device *dssdev,
-				 const struct mipi_dsi_msg *msg)
+static ssize_t omap_dsi_host_transfer(struct mipi_dsi_host *host,
+				      const struct mipi_dsi_msg *msg)
 {
+	struct dsi_data *dsi = host_to_omap(host);
+	struct omap_dss_device *dssdev = &dsi->output;
+
 	switch (msg->type) {
 	case MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM:
 	case MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM:
@@ -4785,11 +4795,30 @@ static const struct omap_dss_device_ops dsi_ops = {
 
 		.request_vc = dsi_request_vc,
 		.release_vc = dsi_release_vc,
-
-		.transfer = omap_dsi_transfer,
 	},
 };
 
+int omap_dsi_host_attach(struct mipi_dsi_host *host,
+			 struct mipi_dsi_device *dsi)
+{
+	/* TODO: convert driver from custom binding method to this one */
+	return 0;
+}
+
+int omap_dsi_host_detach(struct mipi_dsi_host *host,
+			 struct mipi_dsi_device *dsi)
+{
+	/* TODO: convert driver from custom binding method to this one */
+	return 0;
+}
+
+static const struct mipi_dsi_host_ops omap_dsi_host_ops = {
+	.attach = omap_dsi_host_attach,
+	.detach = omap_dsi_host_detach,
+	.transfer = omap_dsi_host_transfer,
+};
+
+
 /* -----------------------------------------------------------------------------
  * PLL
  */
@@ -5258,15 +5287,18 @@ static int dsi_probe(struct platform_device *pdev)
 		dsi->num_lanes_supported = 3;
 	}
 
-	r = of_platform_populate(dev->of_node, NULL, NULL, dev);
-	if (r) {
-		DSSERR("Failed to populate DSI child devices: %d\n", r);
+	dsi->host.ops = &omap_dsi_host_ops;
+	dsi->host.dev = &pdev->dev;
+
+	r = mipi_dsi_host_register(&dsi->host);
+	if (r < 0) {
+		dev_err(&pdev->dev, "failed to register DSI host: %d\n", r);
 		goto err_pm_disable;
 	}
 
 	r = dsi_init_output(dsi);
 	if (r)
-		goto err_of_depopulate;
+		goto err_dsi_host_unregister;
 
 	r = dsi_probe_of(dsi);
 	if (r) {
@@ -5282,8 +5314,8 @@ static int dsi_probe(struct platform_device *pdev)
 
 err_uninit_output:
 	dsi_uninit_output(dsi);
-err_of_depopulate:
-	of_platform_depopulate(dev);
+err_dsi_host_unregister:
+	mipi_dsi_host_unregister(&dsi->host);
 err_pm_disable:
 	pm_runtime_disable(dev);
 	return r;
@@ -5297,7 +5329,7 @@ static int dsi_remove(struct platform_device *pdev)
 
 	dsi_uninit_output(dsi);
 
-	of_platform_depopulate(&pdev->dev);
+	mipi_dsi_host_unregister(&dsi->host);
 
 	pm_runtime_disable(&pdev->dev);
 
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index 143ff346c311..be37c9eb212c 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -310,10 +310,6 @@ struct omapdss_dsi_ops {
 
 	int (*request_vc)(struct omap_dss_device *dssdev, int channel);
 	void (*release_vc)(struct omap_dss_device *dssdev, int channel);
-
-	/* data transfer */
-	ssize_t (*transfer)(struct omap_dss_device *dssdev,
-			const struct mipi_dsi_msg *msg);
 };
 
 struct omap_dss_device_ops {
-- 
2.24.0

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

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

* [RFCv1 13/42] drm/omap: panel-dsi-cm: use DSI helpers
  2019-11-17  2:39 [RFCv1 00/42] drm/omap: Convert DSI code to use drm_mipi_dsi and drm_panel Sebastian Reichel
                   ` (12 preceding siblings ...)
  2019-11-17  2:39 ` [RFCv1 12/42] drm/omap: dsi: introduce mipi_dsi_host Sebastian Reichel
@ 2019-11-17  2:39 ` Sebastian Reichel
  2019-11-17  2:40 ` [RFCv1 14/42] drm/omap: dsi: request VC via mipi_dsi_attach Sebastian Reichel
                   ` (28 subsequent siblings)
  42 siblings, 0 replies; 64+ messages in thread
From: Sebastian Reichel @ 2019-11-17  2:39 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Tomi Valkeinen
  Cc: kernel, Tony Lindgren, H. Nikolaus Schaller, Merlijn Wajer,
	Sebastian Reichel, dri-devel, linux-omap

After converting the driver to mipi_dsi_device we can use the generic
message helpers to simplify the driver a lot.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 .../gpu/drm/omapdrm/displays/panel-dsi-cm.c   | 126 +++---------------
 1 file changed, 18 insertions(+), 108 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
index e2e56cc1cd61..e6c0a6e5aa1d 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
@@ -138,62 +138,22 @@ static void hw_guard_wait(struct panel_drv_data *ddata)
 
 static int dsicm_dcs_read_1(struct panel_drv_data *ddata, u8 dcs_cmd, u8 *data)
 {
-	struct mipi_dsi_device *dsi = ddata->dsi;
-	const struct mipi_dsi_msg msg = {
-		.channel = ddata->channel,
-		.type = MIPI_DSI_DCS_READ,
-		.tx_len = 1,
-		.tx_buf = &dcs_cmd,
-		.rx_len = 1,
-		.rx_buf = data
-	};
-
-	return dsi->host->ops->transfer(dsi->host, &msg);
-}
-
-static int dsicm_dcs_write_0(struct panel_drv_data *ddata, u8 dcs_cmd)
-{
-	struct mipi_dsi_device *dsi = ddata->dsi;
-	const struct mipi_dsi_msg msg = {
-		.channel = ddata->channel,
-		.type = MIPI_DSI_DCS_SHORT_WRITE,
-		.tx_buf = &dcs_cmd,
-		.tx_len = 1,
-	};
-
-	return dsi->host->ops->transfer(dsi->host, &msg);
+	return mipi_dsi_dcs_read(ddata->dsi, dcs_cmd, data, 1);
 }
 
 static int dsicm_dcs_write_1(struct panel_drv_data *ddata, u8 dcs_cmd, u8 param)
 {
-	struct mipi_dsi_device *dsi = ddata->dsi;
-	const u8 buf[] = { dcs_cmd, param };
-	const struct mipi_dsi_msg msg = {
-		.channel = ddata->channel,
-		.type = MIPI_DSI_DCS_SHORT_WRITE_PARAM,
-		.tx_buf = &buf,
-		.tx_len = 2,
-	};
-
-	return dsi->host->ops->transfer(dsi->host, &msg);
+	return mipi_dsi_dcs_write(ddata->dsi, dcs_cmd, &param, 1);
 }
 
 static int dsicm_sleep_in(struct panel_drv_data *ddata)
 
 {
-	struct mipi_dsi_device *dsi = ddata->dsi;
 	int r;
-	const u8 cmd = MIPI_DCS_ENTER_SLEEP_MODE;
-	const struct mipi_dsi_msg msg = {
-		.channel = ddata->channel,
-		.type = MIPI_DSI_DCS_SHORT_WRITE,
-		.tx_buf = &cmd,
-		.tx_len = 1,
-	};
 
 	hw_guard_wait(ddata);
 
-	r = dsi->host->ops->transfer(dsi->host, &msg);
+	r = mipi_dsi_dcs_enter_sleep_mode(ddata->dsi);
 	if (r)
 		return r;
 
@@ -210,7 +170,7 @@ static int dsicm_sleep_out(struct panel_drv_data *ddata)
 
 	hw_guard_wait(ddata);
 
-	r = dsicm_dcs_write_0(ddata, MIPI_DCS_EXIT_SLEEP_MODE);
+	r = mipi_dsi_dcs_exit_sleep_mode(ddata->dsi);
 	if (r)
 		return r;
 
@@ -248,46 +208,15 @@ static int dsicm_set_update_window(struct panel_drv_data *ddata,
 	u16 y1 = y;
 	u16 y2 = y + h - 1;
 
-	const u8 paramX[] = {
-		MIPI_DCS_SET_COLUMN_ADDRESS,
-		(x1 >> 8) & 0xff,
-		(x1 >> 0) & 0xff,
-		(x2 >> 8) & 0xff,
-		(x2 >> 0) & 0xff,
-	};
-
-	const struct mipi_dsi_msg msgX = {
-		.channel = ddata->channel,
-		.type = MIPI_DSI_GENERIC_LONG_WRITE,
-		.tx_buf = paramX,
-		.tx_len = 5,
-	};
-
-	const u8 paramY[] = {
-		MIPI_DCS_SET_PAGE_ADDRESS,
-		(y1 >> 8) & 0xff,
-		(y1 >> 0) & 0xff,
-		(y2 >> 8) & 0xff,
-		(y2 >> 0) & 0xff,
-	};
-
-	const struct mipi_dsi_msg msgY = {
-		.channel = ddata->channel,
-		.type = MIPI_DSI_GENERIC_LONG_WRITE,
-		.tx_buf = paramY,
-		.tx_len = 5,
-	};
-
-
-	r = dsi->host->ops->transfer(dsi->host, &msgX);
-	if (r)
+	r = mipi_dsi_dcs_set_column_address(dsi, x1, x2);
+	if (r < 0)
 		return r;
 
-	r = dsi->host->ops->transfer(dsi->host, &msgY);
-	if (r)
+	r = mipi_dsi_dcs_set_page_address(dsi, y1, y2);
+	if (r < 0)
 		return r;
 
-	return r;
+	return 0;
 }
 
 static void dsicm_queue_ulps_work(struct panel_drv_data *ddata)
@@ -681,12 +610,11 @@ static int dsicm_power_on(struct panel_drv_data *ddata)
 	if (r)
 		goto err;
 
-	r = dsicm_dcs_write_1(ddata, MIPI_DCS_SET_PIXEL_FORMAT,
-		MIPI_DCS_PIXEL_FMT_24BIT);
+	r = mipi_dsi_dcs_set_pixel_format(ddata->dsi, MIPI_DCS_PIXEL_FMT_24BIT);
 	if (r)
 		goto err;
 
-	r = dsicm_dcs_write_0(ddata, MIPI_DCS_SET_DISPLAY_ON);
+	r = mipi_dsi_dcs_set_display_on(ddata->dsi);
 	if (r)
 		goto err;
 
@@ -732,7 +660,7 @@ static void dsicm_power_off(struct panel_drv_data *ddata)
 
 	src->ops->dsi.disable_video_output(src, ddata->channel);
 
-	r = dsicm_dcs_write_0(ddata, MIPI_DCS_SET_DISPLAY_OFF);
+	r = mipi_dsi_dcs_set_display_off(ddata->dsi);
 	if (!r)
 		r = dsicm_sleep_in(ddata);
 
@@ -950,12 +878,13 @@ static int dsicm_sync(struct omap_dss_device *dssdev)
 static int _dsicm_enable_te(struct panel_drv_data *ddata, bool enable)
 {
 	struct omap_dss_device *src = ddata->src;
+	struct mipi_dsi_device *dsi = ddata->dsi;
 	int r;
 
 	if (enable)
-		r = dsicm_dcs_write_1(ddata, MIPI_DCS_SET_TEAR_ON, 0);
+		r = mipi_dsi_dcs_set_tear_on(dsi, MIPI_DSI_DCS_TEAR_MODE_VBLANK);
 	else
-		r = dsicm_dcs_write_0(ddata, MIPI_DCS_SET_TEAR_OFF);
+		r = mipi_dsi_dcs_set_tear_off(dsi);
 
 	if (!ddata->ext_te_gpio)
 		src->ops->dsi.enable_te(src, enable);
@@ -1021,19 +950,7 @@ static int dsicm_set_max_rx_packet_size(struct omap_dss_device *dssdev,
 	struct panel_drv_data *ddata = to_panel_data(dssdev);
 	struct mipi_dsi_device *dsi = ddata->dsi;
 
-	const u8 buf[] = {
-		size & 0xff,
-		size >> 8 & 0xff,
-	};
-
-	const struct mipi_dsi_msg msg = {
-		.channel = ddata->channel,
-		.type = MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE,
-		.tx_buf = buf,
-		.tx_len = 2,
-	};
-
-	return dsi->host->ops->transfer(dsi->host, &msg);
+	return mipi_dsi_set_maximum_return_packet_size(dsi, size);
 }
 
 static int dsicm_memory_read(struct omap_dss_device *dssdev,
@@ -1083,17 +1000,10 @@ static int dsicm_memory_read(struct omap_dss_device *dssdev,
 
 	while (buf_used < size) {
 		u8 dcs_cmd = first ? 0x2e : 0x3e;
-		const struct mipi_dsi_msg msg = {
-			.channel = ddata->channel,
-			.type = MIPI_DSI_DCS_READ,
-			.tx_buf = &dcs_cmd,
-			.tx_len = 1,
-			.rx_buf = buf + buf_used,
-			.rx_len = size - buf_used,
-		};
 		first = 0;
 
-		r = dsi->host->ops->transfer(dsi->host, &msg);
+		r = mipi_dsi_dcs_read(dsi, dcs_cmd,
+				      buf + buf_used, size - buf_used);
 		if (r < 0) {
 			dev_err(dssdev->dev, "read error\n");
 			goto err3;
-- 
2.24.0

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

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

* [RFCv1 14/42] drm/omap: dsi: request VC via mipi_dsi_attach
  2019-11-17  2:39 [RFCv1 00/42] drm/omap: Convert DSI code to use drm_mipi_dsi and drm_panel Sebastian Reichel
                   ` (13 preceding siblings ...)
  2019-11-17  2:39 ` [RFCv1 13/42] drm/omap: panel-dsi-cm: use DSI helpers Sebastian Reichel
@ 2019-11-17  2:40 ` Sebastian Reichel
  2019-11-17  2:40 ` [RFCv1 15/42] drm/omap: panel-dsi-cm: drop hardcoded VC Sebastian Reichel
                   ` (27 subsequent siblings)
  42 siblings, 0 replies; 64+ messages in thread
From: Sebastian Reichel @ 2019-11-17  2:40 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Tomi Valkeinen
  Cc: kernel, Tony Lindgren, H. Nikolaus Schaller, Merlijn Wajer,
	Sebastian Reichel, dri-devel, linux-omap

Drop custom request_vc/release_vc callbacks by using the
generic mipi_dsi_attach/mipi_dsi_detach functions.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 .../gpu/drm/omapdrm/displays/panel-dsi-cm.c   | 24 +++++---
 drivers/gpu/drm/omapdrm/dss/dsi.c             | 61 ++++++++-----------
 drivers/gpu/drm/omapdrm/dss/omapdss.h         |  3 -
 3 files changed, 41 insertions(+), 47 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
index e6c0a6e5aa1d..ddc6dd671cd0 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
@@ -693,14 +693,6 @@ static int dsicm_connect(struct omap_dss_device *src,
 			 struct omap_dss_device *dst)
 {
 	struct panel_drv_data *ddata = to_panel_data(dst);
-	struct device *dev = &ddata->dsi->dev;
-	int r;
-
-	r = src->ops->dsi.request_vc(src, ddata->channel);
-	if (r) {
-		dev_err(dev, "failed to get virtual channel\n");
-		return r;
-	}
 
 	ddata->src = src;
 	return 0;
@@ -711,7 +703,6 @@ static void dsicm_disconnect(struct omap_dss_device *src,
 {
 	struct panel_drv_data *ddata = to_panel_data(dst);
 
-	src->ops->dsi.release_vc(src, ddata->channel);
 	ddata->src = NULL;
 }
 
@@ -1278,8 +1269,21 @@ static int dsicm_probe(struct mipi_dsi_device *dsi)
 		goto err_bl;
 	}
 
+	dsi->lanes = 3;
+	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;
+
+	r = mipi_dsi_attach(dsi);
+	if (r < 0)
+		goto err_dsi_attach;
+
 	return 0;
 
+err_dsi_attach:
+	sysfs_remove_group(&dsi->dev.kobj, &dsicm_attr_group);
 err_bl:
 	destroy_workqueue(ddata->workqueue);
 err_reg:
@@ -1296,6 +1300,8 @@ static int __exit dsicm_remove(struct mipi_dsi_device *dsi)
 
 	dev_dbg(&dsi->dev, "remove\n");
 
+	mipi_dsi_detach(dsi);
+
 	omapdss_device_unregister(dssdev);
 
 	if (omapdss_device_is_enabled(dssdev))
diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index c4107fe5a53d..3cd749cae15c 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -349,7 +349,7 @@ struct dsi_data {
 
 	struct {
 		enum dsi_vc_source source;
-		struct omap_dss_device *dssdev;
+		struct mipi_dsi_device *dest;
 		enum fifo_size tx_fifo_size;
 		enum fifo_size rx_fifo_size;
 	} vc[4];
@@ -4690,32 +4690,6 @@ static enum omap_channel dsi_get_channel(struct dsi_data *dsi)
 	}
 }
 
-static int dsi_request_vc(struct omap_dss_device *dssdev, int channel)
-{
-	struct dsi_data *dsi = to_dsi_data(dssdev);
-
-	if (channel < 0 || channel > 3)
-		return -EINVAL;
-
-	if (dsi->vc[channel].dssdev) {
-		DSSERR("cannot get VC for display %s", dssdev->name);
-		return -EBUSY;
-	}
-
-	dsi->vc[channel].dssdev = dssdev;
-	return 0;
-}
-
-static void dsi_release_vc(struct omap_dss_device *dssdev, int channel)
-{
-	struct dsi_data *dsi = to_dsi_data(dssdev);
-
-	if ((channel >= 0 && channel <= 3) &&
-		dsi->vc[channel].dssdev == dssdev) {
-		dsi->vc[channel].dssdev = NULL;
-	}
-}
-
 static ssize_t omap_dsi_host_transfer(struct mipi_dsi_host *host,
 				      const struct mipi_dsi_msg *msg)
 {
@@ -4792,23 +4766,40 @@ static const struct omap_dss_device_ops dsi_ops = {
 		.update = dsi_update,
 
 		.enable_te = dsi_enable_te,
-
-		.request_vc = dsi_request_vc,
-		.release_vc = dsi_release_vc,
 	},
 };
 
 int omap_dsi_host_attach(struct mipi_dsi_host *host,
-			 struct mipi_dsi_device *dsi)
+			 struct mipi_dsi_device *client)
 {
-	/* TODO: convert driver from custom binding method to this one */
+	struct dsi_data *dsi = host_to_omap(host);
+	unsigned int channel = client->channel;
+
+	if (channel > 3)
+		return -EINVAL;
+
+	if (dsi->vc[channel].dest) {
+		DSSERR("cannot get VC for display %s", dev_name(&client->dev));
+		return -EBUSY;
+	}
+
+	dsi->vc[channel].dest = client;
 	return 0;
 }
 
 int omap_dsi_host_detach(struct mipi_dsi_host *host,
-			 struct mipi_dsi_device *dsi)
+			 struct mipi_dsi_device *client)
 {
-	/* TODO: convert driver from custom binding method to this one */
+	struct dsi_data *dsi = host_to_omap(host);
+	unsigned int channel = client->channel;
+
+	if (channel > 3)
+		return -EINVAL;
+
+	if (dsi->vc[channel].dest != client)
+		return -EINVAL;
+
+	dsi->vc[channel].dest = NULL;
 	return 0;
 }
 
@@ -5267,7 +5258,7 @@ static int dsi_probe(struct platform_device *pdev)
 	/* DSI VCs initialization */
 	for (i = 0; i < ARRAY_SIZE(dsi->vc); i++) {
 		dsi->vc[i].source = DSI_VC_SOURCE_L4;
-		dsi->vc[i].dssdev = NULL;
+		dsi->vc[i].dest = NULL;
 	}
 
 	r = dsi_get_clocks(dsi);
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index be37c9eb212c..28faacb9636b 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -307,9 +307,6 @@ struct omapdss_dsi_ops {
 	int (*enable_video_output)(struct omap_dss_device *dssdev, int channel);
 	void (*disable_video_output)(struct omap_dss_device *dssdev,
 			int channel);
-
-	int (*request_vc)(struct omap_dss_device *dssdev, int channel);
-	void (*release_vc)(struct omap_dss_device *dssdev, int channel);
 };
 
 struct omap_dss_device_ops {
-- 
2.24.0

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

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

* [RFCv1 15/42] drm/omap: panel-dsi-cm: drop hardcoded VC
  2019-11-17  2:39 [RFCv1 00/42] drm/omap: Convert DSI code to use drm_mipi_dsi and drm_panel Sebastian Reichel
                   ` (14 preceding siblings ...)
  2019-11-17  2:40 ` [RFCv1 14/42] drm/omap: dsi: request VC via mipi_dsi_attach Sebastian Reichel
@ 2019-11-17  2:40 ` Sebastian Reichel
  2019-11-17  2:40 ` [RFCv1 16/42] drm/omap: panel-dsi-cm: use common MIPI DCS 1.3 defines Sebastian Reichel
                   ` (26 subsequent siblings)
  42 siblings, 0 replies; 64+ messages in thread
From: Sebastian Reichel @ 2019-11-17  2:40 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Tomi Valkeinen
  Cc: kernel, Tony Lindgren, H. Nikolaus Schaller, Merlijn Wajer,
	Sebastian Reichel, dri-devel, linux-omap

Use dsi->channel everywhere, which originates from DT.

Signed-off-by: Sebastian Reichel <sre@kernel.org>
---
 .../gpu/drm/omapdrm/displays/panel-dsi-cm.c   | 20 +++++++------------
 1 file changed, 7 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
index ddc6dd671cd0..426c660af264 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
@@ -27,9 +27,6 @@
 
 #include "../dss/omapdss.h"
 
-/* DSI Virtual channel. Hardcoded for now. */
-#define TCH 0
-
 #define DCS_READ_NUM_ERRORS	0x05
 #define DCS_BRIGHTNESS		0x51
 #define DCS_CTRL_DISPLAY	0x53
@@ -73,7 +70,6 @@ struct panel_drv_data {
 	bool te_enabled;
 
 	atomic_t do_update;
-	int channel;
 
 	struct delayed_work te_timeout_work;
 
@@ -274,7 +270,7 @@ static int dsicm_exit_ulps(struct panel_drv_data *ddata)
 		return 0;
 
 	src->ops->enable(src);
-	src->ops->dsi.enable_hs(src, ddata->channel, true);
+	src->ops->dsi.enable_hs(src, ddata->dsi->channel, true);
 
 	r = _dsicm_enable_te(ddata, true);
 	if (r) {
@@ -591,7 +587,7 @@ static int dsicm_power_on(struct panel_drv_data *ddata)
 
 	dsicm_hw_reset(ddata);
 
-	src->ops->dsi.enable_hs(src, ddata->channel, false);
+	src->ops->dsi.enable_hs(src, ddata->dsi->channel, false);
 
 	r = dsicm_sleep_out(ddata);
 	if (r)
@@ -622,7 +618,7 @@ static int dsicm_power_on(struct panel_drv_data *ddata)
 	if (r)
 		goto err;
 
-	r = src->ops->dsi.enable_video_output(src, ddata->channel);
+	r = src->ops->dsi.enable_video_output(src, ddata->dsi->channel);
 	if (r)
 		goto err;
 
@@ -634,7 +630,7 @@ static int dsicm_power_on(struct panel_drv_data *ddata)
 		ddata->intro_printed = true;
 	}
 
-	src->ops->dsi.enable_hs(src, ddata->channel, true);
+	src->ops->dsi.enable_hs(src, ddata->dsi->channel, true);
 
 	return 0;
 err:
@@ -658,7 +654,7 @@ static void dsicm_power_off(struct panel_drv_data *ddata)
 	struct omap_dss_device *src = ddata->src;
 	int r;
 
-	src->ops->dsi.disable_video_output(src, ddata->channel);
+	src->ops->dsi.disable_video_output(src, ddata->dsi->channel);
 
 	r = mipi_dsi_dcs_set_display_off(ddata->dsi);
 	if (!r)
@@ -777,7 +773,7 @@ static irqreturn_t dsicm_te_isr(int irq, void *data)
 	if (old) {
 		cancel_delayed_work(&ddata->te_timeout_work);
 
-		r = src->ops->dsi.update(src, ddata->channel, dsicm_framedone_cb,
+		r = src->ops->dsi.update(src, ddata->dsi->channel, dsicm_framedone_cb,
 				ddata);
 		if (r)
 			goto err;
@@ -834,7 +830,7 @@ static int dsicm_update(struct omap_dss_device *dssdev,
 				msecs_to_jiffies(250));
 		atomic_set(&ddata->do_update, 1);
 	} else {
-		r = src->ops->dsi.update(src, ddata->channel, dsicm_framedone_cb,
+		r = src->ops->dsi.update(src, ddata->dsi->channel, dsicm_framedone_cb,
 				ddata);
 		if (r)
 			goto err;
@@ -1110,8 +1106,6 @@ static int dsicm_probe_of(struct mipi_dsi_device *dsi)
 	struct display_timing timing;
 	int err;
 
-	ddata->channel = TCH;
-
 	ddata->reset_gpio = devm_gpiod_get(&dsi->dev, "reset", GPIOD_OUT_LOW);
 	if (IS_ERR(ddata->reset_gpio)) {
 		err = PTR_ERR(ddata->reset_gpio);
-- 
2.24.0

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

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

* [RFCv1 16/42] drm/omap: panel-dsi-cm: use common MIPI DCS 1.3 defines
  2019-11-17  2:39 [RFCv1 00/42] drm/omap: Convert DSI code to use drm_mipi_dsi and drm_panel Sebastian Reichel
                   ` (15 preceding siblings ...)
  2019-11-17  2:40 ` [RFCv1 15/42] drm/omap: panel-dsi-cm: drop hardcoded VC Sebastian Reichel
@ 2019-11-17  2:40 ` Sebastian Reichel
  2019-11-17  2:40 ` [RFCv1 17/42] drm/omap: dsi: drop unused memory_read() Sebastian Reichel
                   ` (25 subsequent siblings)
  42 siblings, 0 replies; 64+ messages in thread
From: Sebastian Reichel @ 2019-11-17  2:40 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Tomi Valkeinen
  Cc: kernel, Tony Lindgren, H. Nikolaus Schaller, Merlijn Wajer,
	Sebastian Reichel, dri-devel, linux-omap

Drop local definition of common MIPI DCS 1.3 defines.

Signed-off-by: Sebastian Reichel <sre@kernel.org>
---
 drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
index 426c660af264..cc25bd0b501f 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
@@ -28,8 +28,6 @@
 #include "../dss/omapdss.h"
 
 #define DCS_READ_NUM_ERRORS	0x05
-#define DCS_BRIGHTNESS		0x51
-#define DCS_CTRL_DISPLAY	0x53
 #define DCS_GET_ID1		0xda
 #define DCS_GET_ID2		0xdb
 #define DCS_GET_ID3		0xdc
@@ -333,8 +331,10 @@ static int dsicm_bl_update_status(struct backlight_device *dev)
 		src->ops->dsi.bus_lock(src);
 
 		r = dsicm_wake_up(ddata);
-		if (!r)
-			r = dsicm_dcs_write_1(ddata, DCS_BRIGHTNESS, level);
+		if (!r) {
+			r = dsicm_dcs_write_1(ddata,
+				MIPI_DCS_SET_DISPLAY_BRIGHTNESS, level);
+		}
 
 		src->ops->dsi.bus_unlock(src);
 	}
@@ -597,11 +597,11 @@ static int dsicm_power_on(struct panel_drv_data *ddata)
 	if (r)
 		goto err;
 
-	r = dsicm_dcs_write_1(ddata, DCS_BRIGHTNESS, 0xff);
+	r = dsicm_dcs_write_1(ddata, MIPI_DCS_SET_DISPLAY_BRIGHTNESS, 0xff);
 	if (r)
 		goto err;
 
-	r = dsicm_dcs_write_1(ddata, DCS_CTRL_DISPLAY,
+	r = dsicm_dcs_write_1(ddata, MIPI_DCS_WRITE_CONTROL_DISPLAY,
 			(1<<2) | (1<<5));	/* BL | BCTRL */
 	if (r)
 		goto err;
-- 
2.24.0

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

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

* [RFCv1 17/42] drm/omap: dsi: drop unused memory_read()
  2019-11-17  2:39 [RFCv1 00/42] drm/omap: Convert DSI code to use drm_mipi_dsi and drm_panel Sebastian Reichel
                   ` (16 preceding siblings ...)
  2019-11-17  2:40 ` [RFCv1 16/42] drm/omap: panel-dsi-cm: use common MIPI DCS 1.3 defines Sebastian Reichel
@ 2019-11-17  2:40 ` Sebastian Reichel
  2019-11-17  2:40 ` [RFCv1 18/42] drm/omap: dsi: drop unused get_te() Sebastian Reichel
                   ` (24 subsequent siblings)
  42 siblings, 0 replies; 64+ messages in thread
From: Sebastian Reichel @ 2019-11-17  2:40 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Tomi Valkeinen
  Cc: kernel, Tony Lindgren, H. Nikolaus Schaller, Merlijn Wajer,
	Sebastian Reichel, dri-devel, linux-omap

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 .../gpu/drm/omapdrm/displays/panel-dsi-cm.c   | 93 -------------------
 drivers/gpu/drm/omapdrm/dss/omapdss.h         |  4 -
 2 files changed, 97 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
index cc25bd0b501f..e309a556c700 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
@@ -931,97 +931,6 @@ static int dsicm_get_te(struct omap_dss_device *dssdev)
 	return r;
 }
 
-static int dsicm_set_max_rx_packet_size(struct omap_dss_device *dssdev,
-                                        u16 size)
-{
-	struct panel_drv_data *ddata = to_panel_data(dssdev);
-	struct mipi_dsi_device *dsi = ddata->dsi;
-
-	return mipi_dsi_set_maximum_return_packet_size(dsi, size);
-}
-
-static int dsicm_memory_read(struct omap_dss_device *dssdev,
-		void *buf, size_t size,
-		u16 x, u16 y, u16 w, u16 h)
-{
-	struct panel_drv_data *ddata = to_panel_data(dssdev);
-	struct mipi_dsi_device *dsi = ddata->dsi;
-	struct omap_dss_device *src = ddata->src;
-	int r;
-	int first = 1;
-	int plen;
-	unsigned int buf_used = 0;
-
-	if (size < w * h * 3)
-		return -ENOMEM;
-
-	mutex_lock(&ddata->lock);
-
-	if (!ddata->enabled) {
-		r = -ENODEV;
-		goto err1;
-	}
-
-	size = min((u32)w * h * 3,
-		   ddata->vm.hactive * ddata->vm.vactive * 3);
-
-	src->ops->dsi.bus_lock(src);
-
-	r = dsicm_wake_up(ddata);
-	if (r)
-		goto err2;
-
-	/* plen 1 or 2 goes into short packet. until checksum error is fixed,
-	 * use short packets. plen 32 works, but bigger packets seem to cause
-	 * an error. */
-	if (size % 2)
-		plen = 1;
-	else
-		plen = 2;
-
-	dsicm_set_update_window(ddata, x, y, w, h);
-
-	r = dsicm_set_max_rx_packet_size(dssdev, plen);
-	if (r)
-		goto err2;
-
-	while (buf_used < size) {
-		u8 dcs_cmd = first ? 0x2e : 0x3e;
-		first = 0;
-
-		r = mipi_dsi_dcs_read(dsi, dcs_cmd,
-				      buf + buf_used, size - buf_used);
-		if (r < 0) {
-			dev_err(dssdev->dev, "read error\n");
-			goto err3;
-		}
-
-		buf_used += r;
-
-		if (r < plen) {
-			dev_err(&ddata->dsi->dev, "short read\n");
-			break;
-		}
-
-		if (signal_pending(current)) {
-			dev_err(&ddata->dsi->dev, "signal pending, "
-					"aborting memory read\n");
-			r = -ERESTARTSYS;
-			goto err3;
-		}
-	}
-
-	r = buf_used;
-
-err3:
-	dsicm_set_max_rx_packet_size(dssdev, 1);
-err2:
-	src->ops->dsi.bus_unlock(src);
-err1:
-	mutex_unlock(&ddata->lock);
-	return r;
-}
-
 static void dsicm_ulps_work(struct work_struct *work)
 {
 	struct panel_drv_data *ddata = container_of(work, struct panel_drv_data,
@@ -1094,8 +1003,6 @@ static const struct omap_dss_driver dsicm_dss_driver = {
 
 	.enable_te	= dsicm_enable_te,
 	.get_te		= dsicm_get_te,
-
-	.memory_read	= dsicm_memory_read,
 };
 
 static int dsicm_probe_of(struct mipi_dsi_device *dsi)
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index 28faacb9636b..742088b8f570 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -413,10 +413,6 @@ struct omap_dss_driver {
 
 	int (*enable_te)(struct omap_dss_device *dssdev, bool enable);
 	int (*get_te)(struct omap_dss_device *dssdev);
-
-	int (*memory_read)(struct omap_dss_device *dssdev,
-			void *buf, size_t size,
-			u16 x, u16 y, u16 w, u16 h);
 };
 
 struct dss_device *omapdss_get_dss(void);
-- 
2.24.0

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

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

* [RFCv1 18/42] drm/omap: dsi: drop unused get_te()
  2019-11-17  2:39 [RFCv1 00/42] drm/omap: Convert DSI code to use drm_mipi_dsi and drm_panel Sebastian Reichel
                   ` (17 preceding siblings ...)
  2019-11-17  2:40 ` [RFCv1 17/42] drm/omap: dsi: drop unused memory_read() Sebastian Reichel
@ 2019-11-17  2:40 ` Sebastian Reichel
  2019-11-17  2:40 ` [RFCv1 19/42] drm/omap: dsi: drop unused enable_te() Sebastian Reichel
                   ` (23 subsequent siblings)
  42 siblings, 0 replies; 64+ messages in thread
From: Sebastian Reichel @ 2019-11-17  2:40 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Tomi Valkeinen
  Cc: kernel, Tony Lindgren, H. Nikolaus Schaller, Merlijn Wajer,
	Sebastian Reichel, dri-devel, linux-omap

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c | 13 -------------
 drivers/gpu/drm/omapdrm/dss/omapdss.h           |  1 -
 2 files changed, 14 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
index e309a556c700..b2eb834c9eff 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
@@ -919,18 +919,6 @@ static int dsicm_enable_te(struct omap_dss_device *dssdev, bool enable)
 	return r;
 }
 
-static int dsicm_get_te(struct omap_dss_device *dssdev)
-{
-	struct panel_drv_data *ddata = to_panel_data(dssdev);
-	int r;
-
-	mutex_lock(&ddata->lock);
-	r = ddata->te_enabled;
-	mutex_unlock(&ddata->lock);
-
-	return r;
-}
-
 static void dsicm_ulps_work(struct work_struct *work)
 {
 	struct panel_drv_data *ddata = container_of(work, struct panel_drv_data,
@@ -1002,7 +990,6 @@ static const struct omap_dss_driver dsicm_dss_driver = {
 	.sync		= dsicm_sync,
 
 	.enable_te	= dsicm_enable_te,
-	.get_te		= dsicm_get_te,
 };
 
 static int dsicm_probe_of(struct mipi_dsi_device *dsi)
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index 742088b8f570..9be1c659d3a4 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -412,7 +412,6 @@ struct omap_dss_driver {
 	int (*sync)(struct omap_dss_device *dssdev);
 
 	int (*enable_te)(struct omap_dss_device *dssdev, bool enable);
-	int (*get_te)(struct omap_dss_device *dssdev);
 };
 
 struct dss_device *omapdss_get_dss(void);
-- 
2.24.0

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

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

* [RFCv1 19/42] drm/omap: dsi: drop unused enable_te()
  2019-11-17  2:39 [RFCv1 00/42] drm/omap: Convert DSI code to use drm_mipi_dsi and drm_panel Sebastian Reichel
                   ` (18 preceding siblings ...)
  2019-11-17  2:40 ` [RFCv1 18/42] drm/omap: dsi: drop unused get_te() Sebastian Reichel
@ 2019-11-17  2:40 ` Sebastian Reichel
  2019-11-17  2:40 ` [RFCv1 20/42] drm/omap: dsi: drop useless sync() Sebastian Reichel
                   ` (22 subsequent siblings)
  42 siblings, 0 replies; 64+ messages in thread
From: Sebastian Reichel @ 2019-11-17  2:40 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Tomi Valkeinen
  Cc: kernel, Tony Lindgren, H. Nikolaus Schaller, Merlijn Wajer,
	Sebastian Reichel, dri-devel, linux-omap

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 .../gpu/drm/omapdrm/displays/panel-dsi-cm.c   | 39 -------------------
 drivers/gpu/drm/omapdrm/dss/omapdss.h         |  2 -
 2 files changed, 41 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
index b2eb834c9eff..164f3a30d7f2 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
@@ -882,43 +882,6 @@ static int _dsicm_enable_te(struct panel_drv_data *ddata, bool enable)
 	return r;
 }
 
-static int dsicm_enable_te(struct omap_dss_device *dssdev, bool enable)
-{
-	struct panel_drv_data *ddata = to_panel_data(dssdev);
-	struct omap_dss_device *src = ddata->src;
-	int r;
-
-	mutex_lock(&ddata->lock);
-
-	if (ddata->te_enabled == enable)
-		goto end;
-
-	src->ops->dsi.bus_lock(src);
-
-	if (ddata->enabled) {
-		r = dsicm_wake_up(ddata);
-		if (r)
-			goto err;
-
-		r = _dsicm_enable_te(ddata, enable);
-		if (r)
-			goto err;
-	}
-
-	ddata->te_enabled = enable;
-
-	src->ops->dsi.bus_unlock(src);
-end:
-	mutex_unlock(&ddata->lock);
-
-	return 0;
-err:
-	src->ops->dsi.bus_unlock(src);
-	mutex_unlock(&ddata->lock);
-
-	return r;
-}
-
 static void dsicm_ulps_work(struct work_struct *work)
 {
 	struct panel_drv_data *ddata = container_of(work, struct panel_drv_data,
@@ -988,8 +951,6 @@ static const struct omap_dss_device_ops dsicm_ops = {
 static const struct omap_dss_driver dsicm_dss_driver = {
 	.update		= dsicm_update,
 	.sync		= dsicm_sync,
-
-	.enable_te	= dsicm_enable_te,
 };
 
 static int dsicm_probe_of(struct mipi_dsi_device *dsi)
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index 9be1c659d3a4..bc583346af4d 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -410,8 +410,6 @@ struct omap_dss_driver {
 	int (*update)(struct omap_dss_device *dssdev,
 			       u16 x, u16 y, u16 w, u16 h);
 	int (*sync)(struct omap_dss_device *dssdev);
-
-	int (*enable_te)(struct omap_dss_device *dssdev, bool enable);
 };
 
 struct dss_device *omapdss_get_dss(void);
-- 
2.24.0

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

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

* [RFCv1 20/42] drm/omap: dsi: drop useless sync()
  2019-11-17  2:39 [RFCv1 00/42] drm/omap: Convert DSI code to use drm_mipi_dsi and drm_panel Sebastian Reichel
                   ` (19 preceding siblings ...)
  2019-11-17  2:40 ` [RFCv1 19/42] drm/omap: dsi: drop unused enable_te() Sebastian Reichel
@ 2019-11-17  2:40 ` Sebastian Reichel
  2019-11-17  2:40 ` [RFCv1 21/42] drm/omap: dsi: use pixel-format and mode from attach Sebastian Reichel
                   ` (21 subsequent siblings)
  42 siblings, 0 replies; 64+ messages in thread
From: Sebastian Reichel @ 2019-11-17  2:40 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Tomi Valkeinen
  Cc: kernel, Tony Lindgren, H. Nikolaus Schaller, Merlijn Wajer,
	Sebastian Reichel, dri-devel, linux-omap

The DSI sync() function only locks the bus and then releases
it again. Currently the only invocation is directly before
update(), which locks the bus anyways.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 .../gpu/drm/omapdrm/displays/panel-dsi-cm.c    | 18 ------------------
 drivers/gpu/drm/omapdrm/dss/omapdss.h          |  1 -
 drivers/gpu/drm/omapdrm/omap_crtc.c            |  3 ---
 3 files changed, 22 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
index 164f3a30d7f2..994880022d0c 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
@@ -845,23 +845,6 @@ static int dsicm_update(struct omap_dss_device *dssdev,
 	return r;
 }
 
-static int dsicm_sync(struct omap_dss_device *dssdev)
-{
-	struct panel_drv_data *ddata = to_panel_data(dssdev);
-	struct omap_dss_device *src = ddata->src;
-
-	dev_dbg(&ddata->dsi->dev, "sync\n");
-
-	mutex_lock(&ddata->lock);
-	src->ops->dsi.bus_lock(src);
-	src->ops->dsi.bus_unlock(src);
-	mutex_unlock(&ddata->lock);
-
-	dev_dbg(&ddata->dsi->dev, "sync done\n");
-
-	return 0;
-}
-
 static int _dsicm_enable_te(struct panel_drv_data *ddata, bool enable)
 {
 	struct omap_dss_device *src = ddata->src;
@@ -950,7 +933,6 @@ static const struct omap_dss_device_ops dsicm_ops = {
 
 static const struct omap_dss_driver dsicm_dss_driver = {
 	.update		= dsicm_update,
-	.sync		= dsicm_sync,
 };
 
 static int dsicm_probe_of(struct mipi_dsi_device *dsi)
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index bc583346af4d..cd9769711b58 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -409,7 +409,6 @@ struct omap_dss_device {
 struct omap_dss_driver {
 	int (*update)(struct omap_dss_device *dssdev,
 			       u16 x, u16 y, u16 w, u16 h);
-	int (*sync)(struct omap_dss_device *dssdev);
 };
 
 struct dss_device *omapdss_get_dss(void);
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 3c5ddbf30e97..8b469eaa5005 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -379,9 +379,6 @@ static void omap_crtc_manual_display_update(struct work_struct *data)
 		return;
 	}
 
-	if (dssdrv->sync)
-		dssdrv->sync(dssdev);
-
 	ret = dssdrv->update(dssdev, 0, 0, mode->hdisplay, mode->vdisplay);
 	if (ret < 0) {
 		spin_lock_irq(&dev->event_lock);
-- 
2.24.0

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

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

* [RFCv1 21/42] drm/omap: dsi: use pixel-format and mode from attach
  2019-11-17  2:39 [RFCv1 00/42] drm/omap: Convert DSI code to use drm_mipi_dsi and drm_panel Sebastian Reichel
                   ` (20 preceding siblings ...)
  2019-11-17  2:40 ` [RFCv1 20/42] drm/omap: dsi: drop useless sync() Sebastian Reichel
@ 2019-11-17  2:40 ` Sebastian Reichel
  2019-11-17  2:40 ` [RFCv1 22/42] drm/omap: panel-dsi-cm: use bulk regulator API Sebastian Reichel
                   ` (20 subsequent siblings)
  42 siblings, 0 replies; 64+ messages in thread
From: Sebastian Reichel @ 2019-11-17  2:40 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Tomi Valkeinen
  Cc: kernel, Tony Lindgren, H. Nikolaus Schaller, Merlijn Wajer,
	Sebastian Reichel, dri-devel, linux-omap

In order to reduce the amount of custom functionality, this moves
handling of pixel format and DSI mode from set_config() to dsi
attach.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 .../gpu/drm/omapdrm/displays/panel-dsi-cm.c   |  2 --
 drivers/gpu/drm/omapdrm/dss/dsi.c             | 20 +++++++++++++------
 2 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
index 994880022d0c..e4120d484f4c 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
@@ -550,8 +550,6 @@ static int dsicm_power_on(struct panel_drv_data *ddata)
 	u8 id1, id2, id3;
 	int r;
 	struct omap_dss_dsi_config dsi_config = {
-		.mode = OMAP_DSS_DSI_CMD_MODE,
-		.pixel_format = MIPI_DSI_FMT_RGB888,
 		.vm = &ddata->vm,
 		.hs_clk_min = 150000000,
 		.hs_clk_max = 300000000,
diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index 3cd749cae15c..32271870e74c 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -4583,18 +4583,19 @@ static int dsi_set_config(struct omap_dss_device *dssdev,
 {
 	struct dsi_data *dsi = to_dsi_data(dssdev);
 	struct dsi_clk_calc_ctx ctx;
+	struct omap_dss_dsi_config cfg = *config;
 	bool ok;
 	int r;
 
 	mutex_lock(&dsi->lock);
 
-	dsi->pix_fmt = config->pixel_format;
-	dsi->mode = config->mode;
+	cfg.mode = dsi->mode;
+	cfg.pixel_format = dsi->pix_fmt;
 
-	if (config->mode == OMAP_DSS_DSI_VIDEO_MODE)
-		ok = dsi_vm_calc(dsi, config, &ctx);
+	if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE)
+		ok = dsi_vm_calc(dsi, &cfg, &ctx);
 	else
-		ok = dsi_cm_calc(dsi, config, &ctx);
+		ok = dsi_cm_calc(dsi, &cfg, &ctx);
 
 	if (!ok) {
 		DSSERR("failed to find suitable DSI clock settings\n");
@@ -4605,7 +4606,7 @@ static int dsi_set_config(struct omap_dss_device *dssdev,
 	dsi_pll_calc_dsi_fck(dsi, &ctx.dsi_cinfo);
 
 	r = dsi_lp_clock_calc(ctx.dsi_cinfo.clkout[HSDIV_DSI],
-		config->lp_clk_min, config->lp_clk_max, &dsi->user_lp_cinfo);
+		cfg.lp_clk_min, cfg.lp_clk_max, &dsi->user_lp_cinfo);
 	if (r) {
 		DSSERR("failed to find suitable DSI LP clock settings\n");
 		goto err;
@@ -4784,6 +4785,13 @@ int omap_dsi_host_attach(struct mipi_dsi_host *host,
 	}
 
 	dsi->vc[channel].dest = client;
+
+	dsi->pix_fmt = client->format;
+	if (client->mode_flags & MIPI_DSI_MODE_VIDEO)
+		dsi->mode = OMAP_DSS_DSI_VIDEO_MODE;
+	else
+		dsi->mode = OMAP_DSS_DSI_CMD_MODE;
+
 	return 0;
 }
 
-- 
2.24.0

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

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

* [RFCv1 22/42] drm/omap: panel-dsi-cm: use bulk regulator API
  2019-11-17  2:39 [RFCv1 00/42] drm/omap: Convert DSI code to use drm_mipi_dsi and drm_panel Sebastian Reichel
                   ` (21 preceding siblings ...)
  2019-11-17  2:40 ` [RFCv1 21/42] drm/omap: dsi: use pixel-format and mode from attach Sebastian Reichel
@ 2019-11-17  2:40 ` Sebastian Reichel
  2019-11-17  2:40 ` [RFCv1 23/42] drm/omap: dsi: lp/hs switching support for transfer() Sebastian Reichel
                   ` (19 subsequent siblings)
  42 siblings, 0 replies; 64+ messages in thread
From: Sebastian Reichel @ 2019-11-17  2:40 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Tomi Valkeinen
  Cc: kernel, Tony Lindgren, H. Nikolaus Schaller, Merlijn Wajer,
	Sebastian Reichel, dri-devel, linux-omap

Use bulk regulator API to simplify the code. This also switches
from _optional variant to normal variant, which will provide a
dummy regulator (i.e. if some always-enabled regulator is not
described in DT).

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 .../gpu/drm/omapdrm/displays/panel-dsi-cm.c   | 65 ++++++-------------
 1 file changed, 21 insertions(+), 44 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
index e4120d484f4c..170cbc78fbef 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
@@ -32,6 +32,8 @@
 #define DCS_GET_ID2		0xdb
 #define DCS_GET_ID3		0xdc
 
+#define DCS_REGULATOR_SUPPLY_NUM 2
+
 struct panel_drv_data {
 	struct mipi_dsi_device *dsi;
 
@@ -54,8 +56,7 @@ struct panel_drv_data {
 	struct gpio_desc *reset_gpio;
 	struct gpio_desc *ext_te_gpio;
 
-	struct regulator *vpnl;
-	struct regulator *vddi;
+	struct regulator_bulk_data supplies[DCS_REGULATOR_SUPPLY_NUM];
 
 	bool use_dsi_backlight;
 
@@ -557,28 +558,16 @@ static int dsicm_power_on(struct panel_drv_data *ddata)
 		.lp_clk_max = 10000000,
 	};
 
-	if (ddata->vpnl) {
-		r = regulator_enable(ddata->vpnl);
-		if (r) {
-			dev_err(&ddata->dsi->dev,
-				"failed to enable VPNL: %d\n", r);
-			return r;
-		}
-	}
-
-	if (ddata->vddi) {
-		r = regulator_enable(ddata->vddi);
-		if (r) {
-			dev_err(&ddata->dsi->dev,
-				"failed to enable VDDI: %d\n", r);
-			goto err_vpnl;
-		}
+	r = regulator_bulk_enable(DCS_REGULATOR_SUPPLY_NUM, ddata->supplies);
+	if (r) {
+		dev_err(&ddata->dsi->dev, "failed to enable supplies: %d\n", r);
+		return r;
 	}
 
 	r = src->ops->dsi.set_config(src, &dsi_config);
 	if (r) {
 		dev_err(&ddata->dsi->dev, "failed to configure DSI\n");
-		goto err_vddi;
+		goto err_regulators;
 	}
 
 	src->ops->enable(src);
@@ -637,12 +626,10 @@ static int dsicm_power_on(struct panel_drv_data *ddata)
 	dsicm_hw_reset(ddata);
 
 	src->ops->dsi.disable(src, true, false);
-err_vddi:
-	if (ddata->vddi)
-		regulator_disable(ddata->vddi);
-err_vpnl:
-	if (ddata->vpnl)
-		regulator_disable(ddata->vpnl);
+err_regulators:
+	r = regulator_bulk_disable(DCS_REGULATOR_SUPPLY_NUM, ddata->supplies);
+	if (r)
+		dev_err(&ddata->dsi->dev, "failed to disable supplies: %d\n", r);
 
 	return r;
 }
@@ -666,10 +653,9 @@ static void dsicm_power_off(struct panel_drv_data *ddata)
 
 	src->ops->dsi.disable(src, true, false);
 
-	if (ddata->vddi)
-		regulator_disable(ddata->vddi);
-	if (ddata->vpnl)
-		regulator_disable(ddata->vpnl);
+	r = regulator_bulk_disable(DCS_REGULATOR_SUPPLY_NUM, ddata->supplies);
+	if (r)
+		dev_err(&ddata->dsi->dev, "failed to disable supplies: %d\n", r);
 
 	ddata->enabled = 0;
 }
@@ -973,21 +959,12 @@ static int dsicm_probe_of(struct mipi_dsi_device *dsi)
 	ddata->height_mm = 0;
 	of_property_read_u32(node, "height-mm", &ddata->height_mm);
 
-	ddata->vpnl = devm_regulator_get_optional(&dsi->dev, "vpnl");
-	if (IS_ERR(ddata->vpnl)) {
-		err = PTR_ERR(ddata->vpnl);
-		if (err == -EPROBE_DEFER)
-			return err;
-		ddata->vpnl = NULL;
-	}
-
-	ddata->vddi = devm_regulator_get_optional(&dsi->dev, "vddi");
-	if (IS_ERR(ddata->vddi)) {
-		err = PTR_ERR(ddata->vddi);
-		if (err == -EPROBE_DEFER)
-			return err;
-		ddata->vddi = NULL;
-	}
+	ddata->supplies[0].supply = "vpnl";
+	ddata->supplies[1].supply = "vddi";
+	err = devm_regulator_bulk_get(&dsi->dev, DCS_REGULATOR_SUPPLY_NUM,
+				      ddata->supplies);
+	if (err)
+		return err;
 
 	backlight = of_parse_phandle(node, "backlight", 0);
 	if (backlight) {
-- 
2.24.0

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

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

* [RFCv1 23/42] drm/omap: dsi: lp/hs switching support for transfer()
  2019-11-17  2:39 [RFCv1 00/42] drm/omap: Convert DSI code to use drm_mipi_dsi and drm_panel Sebastian Reichel
                   ` (22 preceding siblings ...)
  2019-11-17  2:40 ` [RFCv1 22/42] drm/omap: panel-dsi-cm: use bulk regulator API Sebastian Reichel
@ 2019-11-17  2:40 ` Sebastian Reichel
  2019-11-17  2:40 ` [RFCv1 24/42] drm/omap: dsi: move TE GPIO handling into core Sebastian Reichel
                   ` (18 subsequent siblings)
  42 siblings, 0 replies; 64+ messages in thread
From: Sebastian Reichel @ 2019-11-17  2:40 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Tomi Valkeinen
  Cc: kernel, Tony Lindgren, H. Nikolaus Schaller, Merlijn Wajer,
	Sebastian Reichel, dri-devel, linux-omap

Integrate low-power / high-speed bus switching into transfer
function and drop the omapdrm specific enable_hs() callback.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c |  6 +++---
 drivers/gpu/drm/omapdrm/dss/dsi.c               | 13 +++++++++++--
 drivers/gpu/drm/omapdrm/dss/omapdss.h           |  2 --
 3 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
index 170cbc78fbef..5603dae0fd0f 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
@@ -269,7 +269,7 @@ static int dsicm_exit_ulps(struct panel_drv_data *ddata)
 		return 0;
 
 	src->ops->enable(src);
-	src->ops->dsi.enable_hs(src, ddata->dsi->channel, true);
+	ddata->dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
 
 	r = _dsicm_enable_te(ddata, true);
 	if (r) {
@@ -574,7 +574,7 @@ static int dsicm_power_on(struct panel_drv_data *ddata)
 
 	dsicm_hw_reset(ddata);
 
-	src->ops->dsi.enable_hs(src, ddata->dsi->channel, false);
+	ddata->dsi->mode_flags |= MIPI_DSI_MODE_LPM;
 
 	r = dsicm_sleep_out(ddata);
 	if (r)
@@ -617,7 +617,7 @@ static int dsicm_power_on(struct panel_drv_data *ddata)
 		ddata->intro_printed = true;
 	}
 
-	src->ops->dsi.enable_hs(src, ddata->dsi->channel, true);
+	ddata->dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
 
 	return 0;
 err:
diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index 32271870e74c..8eb323adb30a 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -45,6 +45,9 @@ struct dsi_reg { u16 module; u16 idx; };
 
 #define DSI_REG(mod, idx)		((const struct dsi_reg) { mod, idx })
 
+/* returns true iff both arguments logically differs */
+#define NEQV(a, b) (!(a) ^ !(b))
+
 /* DSI Protocol Engine */
 
 #define DSI_PROTO			0
@@ -329,6 +332,7 @@ struct dsi_data {
 	int irq;
 
 	bool is_enabled;
+	bool in_lp_mode;
 
 	struct clk *dss_clk;
 	struct regmap *syscon;
@@ -2431,6 +2435,8 @@ static void dsi_vc_enable_hs(struct omap_dss_device *dssdev, int channel,
 	/* 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->in_lp_mode = !enable;
 }
 
 static void dsi_vc_flush_long_data(struct dsi_data *dsi, int channel)
@@ -4697,6 +4703,11 @@ static ssize_t omap_dsi_host_transfer(struct mipi_dsi_host *host,
 	struct dsi_data *dsi = host_to_omap(host);
 	struct omap_dss_device *dssdev = &dsi->output;
 
+	if (NEQV(msg->flags & MIPI_DSI_MSG_USE_LPM, dsi->in_lp_mode)) {
+		dsi_vc_enable_hs(dssdev, msg->channel,
+				 !(msg->flags & MIPI_DSI_MSG_USE_LPM));
+	}
+
 	switch (msg->type) {
 	case MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM:
 	case MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM:
@@ -4757,8 +4768,6 @@ static const struct omap_dss_device_ops dsi_ops = {
 
 		.disable = dsi_display_disable,
 
-		.enable_hs = dsi_vc_enable_hs,
-
 		.set_config = dsi_set_config,
 
 		.enable_video_output = dsi_enable_video_output,
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index cd9769711b58..5bcc14d9f737 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -294,8 +294,6 @@ struct omapdss_dsi_ops {
 	int (*set_config)(struct omap_dss_device *dssdev,
 			const struct omap_dss_dsi_config *cfg);
 
-	void (*enable_hs)(struct omap_dss_device *dssdev, int channel,
-			bool enable);
 	int (*enable_te)(struct omap_dss_device *dssdev, bool enable);
 
 	int (*update)(struct omap_dss_device *dssdev, int channel,
-- 
2.24.0

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

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

* [RFCv1 24/42] drm/omap: dsi: move TE GPIO handling into core
  2019-11-17  2:39 [RFCv1 00/42] drm/omap: Convert DSI code to use drm_mipi_dsi and drm_panel Sebastian Reichel
                   ` (23 preceding siblings ...)
  2019-11-17  2:40 ` [RFCv1 23/42] drm/omap: dsi: lp/hs switching support for transfer() Sebastian Reichel
@ 2019-11-17  2:40 ` Sebastian Reichel
  2019-11-17  2:40 ` [RFCv1 25/42] drm/omap: dsi: drop custom enable_te() API Sebastian Reichel
                   ` (17 subsequent siblings)
  42 siblings, 0 replies; 64+ messages in thread
From: Sebastian Reichel @ 2019-11-17  2:40 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Tomi Valkeinen
  Cc: kernel, Tony Lindgren, H. Nikolaus Schaller, Merlijn Wajer,
	Sebastian Reichel, dri-devel, linux-omap

In preparation for removing custom DSS calls from the DSI
panel driver, this moves support for external tearing event
GPIOs into the DSI host driver. This way tearing events are
always handled in the core resulting in simplification of
the panel drivers.

The TE GPIO acquisition follows works in the same way as the
exynos DSI implementation.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 .../gpu/drm/omapdrm/displays/panel-dsi-cm.c   | 101 +------------
 drivers/gpu/drm/omapdrm/dss/dsi.c             | 140 ++++++++++++++++--
 2 files changed, 135 insertions(+), 106 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
index 5603dae0fd0f..9a259e0d9e97 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
@@ -54,7 +54,6 @@ struct panel_drv_data {
 
 	/* panel HW configuration from DT or platform data */
 	struct gpio_desc *reset_gpio;
-	struct gpio_desc *ext_te_gpio;
 
 	struct regulator_bulk_data supplies[DCS_REGULATOR_SUPPLY_NUM];
 
@@ -68,10 +67,6 @@ struct panel_drv_data {
 
 	bool te_enabled;
 
-	atomic_t do_update;
-
-	struct delayed_work te_timeout_work;
-
 	bool intro_printed;
 
 	struct workqueue_struct *workqueue;
@@ -83,8 +78,6 @@ struct panel_drv_data {
 
 #define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev)
 
-static irqreturn_t dsicm_te_isr(int irq, void *data);
-static void dsicm_te_timeout_work_callback(struct work_struct *work);
 static int _dsicm_enable_te(struct panel_drv_data *ddata, bool enable);
 
 static int dsicm_panel_reset(struct panel_drv_data *ddata);
@@ -240,9 +233,6 @@ static int dsicm_enter_ulps(struct panel_drv_data *ddata)
 	if (r)
 		goto err;
 
-	if (ddata->ext_te_gpio)
-		disable_irq(gpiod_to_irq(ddata->ext_te_gpio));
-
 	src->ops->dsi.disable(src, false, true);
 
 	ddata->ulps_enabled = true;
@@ -271,15 +261,12 @@ static int dsicm_exit_ulps(struct panel_drv_data *ddata)
 	src->ops->enable(src);
 	ddata->dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
 
-	r = _dsicm_enable_te(ddata, true);
+	r = _dsicm_enable_te(ddata, ddata->te_enabled);
 	if (r) {
 		dev_err(&ddata->dsi->dev, "failed to re-enable TE");
 		goto err2;
 	}
 
-	if (ddata->ext_te_gpio)
-		enable_irq(gpiod_to_irq(ddata->ext_te_gpio));
-
 	dsicm_queue_ulps_work(ddata);
 
 	ddata->ulps_enabled = false;
@@ -290,11 +277,8 @@ static int dsicm_exit_ulps(struct panel_drv_data *ddata)
 	dev_err(&ddata->dsi->dev, "failed to exit ULPS");
 
 	r = dsicm_panel_reset(ddata);
-	if (!r) {
-		if (ddata->ext_te_gpio)
-			enable_irq(gpiod_to_irq(ddata->ext_te_gpio));
+	if (!r)
 		ddata->ulps_enabled = false;
-	}
 
 	dsicm_queue_ulps_work(ddata);
 
@@ -745,43 +729,6 @@ static void dsicm_framedone_cb(int err, void *data)
 	src->ops->dsi.bus_unlock(src);
 }
 
-static irqreturn_t dsicm_te_isr(int irq, void *data)
-{
-	struct panel_drv_data *ddata = data;
-	struct omap_dss_device *src = ddata->src;
-	int old;
-	int r;
-
-	old = atomic_cmpxchg(&ddata->do_update, 1, 0);
-
-	if (old) {
-		cancel_delayed_work(&ddata->te_timeout_work);
-
-		r = src->ops->dsi.update(src, ddata->dsi->channel, dsicm_framedone_cb,
-				ddata);
-		if (r)
-			goto err;
-	}
-
-	return IRQ_HANDLED;
-err:
-	dev_err(&ddata->dsi->dev, "start update failed\n");
-	src->ops->dsi.bus_unlock(src);
-	return IRQ_HANDLED;
-}
-
-static void dsicm_te_timeout_work_callback(struct work_struct *work)
-{
-	struct panel_drv_data *ddata = container_of(work, struct panel_drv_data,
-					te_timeout_work.work);
-	struct omap_dss_device *src = ddata->src;
-
-	dev_err(&ddata->dsi->dev, "TE not received for 250ms!\n");
-
-	atomic_set(&ddata->do_update, 0);
-	src->ops->dsi.bus_unlock(src);
-}
-
 static int dsicm_update(struct omap_dss_device *dssdev,
 				    u16 x, u16 y, u16 w, u16 h)
 {
@@ -809,16 +756,10 @@ static int dsicm_update(struct omap_dss_device *dssdev,
 	if (r)
 		goto err;
 
-	if (ddata->te_enabled && ddata->ext_te_gpio) {
-		schedule_delayed_work(&ddata->te_timeout_work,
-				msecs_to_jiffies(250));
-		atomic_set(&ddata->do_update, 1);
-	} else {
-		r = src->ops->dsi.update(src, ddata->dsi->channel, dsicm_framedone_cb,
-				ddata);
-		if (r)
-			goto err;
-	}
+	r = src->ops->dsi.update(src, ddata->dsi->channel, dsicm_framedone_cb,
+			ddata);
+	if (r)
+		goto err;
 
 	/* note: no bus_unlock here. unlock is src framedone_cb */
 	mutex_unlock(&ddata->lock);
@@ -840,8 +781,7 @@ static int _dsicm_enable_te(struct panel_drv_data *ddata, bool enable)
 	else
 		r = mipi_dsi_dcs_set_tear_off(dsi);
 
-	if (!ddata->ext_te_gpio)
-		src->ops->dsi.enable_te(src, enable);
+	src->ops->dsi.enable_te(src, enable);
 
 	/* possible panel bug */
 	msleep(100);
@@ -934,14 +874,6 @@ static int dsicm_probe_of(struct mipi_dsi_device *dsi)
 		return err;
 	}
 
-	ddata->ext_te_gpio = devm_gpiod_get_optional(&dsi->dev, "te",
-						     GPIOD_IN);
-	if (IS_ERR(ddata->ext_te_gpio)) {
-		err = PTR_ERR(ddata->ext_te_gpio);
-		dev_err(&dsi->dev, "TE gpio request failed: %d", err);
-		return err;
-	}
-
 	err = of_get_display_timing(node, "panel-timing", &timing);
 	if (!err) {
 		videomode_from_timing(&timing, &ddata->vm);
@@ -1026,25 +958,6 @@ static int dsicm_probe(struct mipi_dsi_device *dsi)
 
 	mutex_init(&ddata->lock);
 
-	atomic_set(&ddata->do_update, 0);
-
-	if (ddata->ext_te_gpio) {
-		r = devm_request_irq(dev, gpiod_to_irq(ddata->ext_te_gpio),
-				dsicm_te_isr,
-				IRQF_TRIGGER_RISING,
-				"taal vsync", ddata);
-
-		if (r) {
-			dev_err(dev, "IRQ request failed\n");
-			goto err_reg;
-		}
-
-		INIT_DEFERRABLE_WORK(&ddata->te_timeout_work,
-					dsicm_te_timeout_work_callback);
-
-		dev_dbg(dev, "Using GPIO TE\n");
-	}
-
 	ddata->workqueue = create_singlethread_workqueue("dsicm_wq");
 	if (!ddata->workqueue) {
 		r = -ENOMEM;
diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index 8eb323adb30a..8f900cf1aed7 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -14,7 +14,9 @@
 #include <linux/device.h>
 #include <linux/err.h>
 #include <linux/interrupt.h>
+#include <linux/irq.h>
 #include <linux/delay.h>
+#include <linux/gpio/consumer.h>
 #include <linux/mutex.h>
 #include <linux/module.h>
 #include <linux/semaphore.h>
@@ -371,6 +373,11 @@ struct dsi_data {
 	unsigned int update_bytes;
 #endif
 
+	/* external TE GPIO */
+	struct gpio_desc *te_gpio;
+	struct delayed_work te_timeout_work;
+	atomic_t do_ext_te_update;
+
 	bool te_enabled;
 	bool ulps_enabled;
 
@@ -3834,19 +3841,12 @@ static void dsi_framedone_irq_callback(void *data)
 	dsi_handle_framedone(dsi, 0);
 }
 
-static int dsi_update(struct omap_dss_device *dssdev, int channel,
-		void (*callback)(int, void *), void *data)
+static int _dsi_update(struct dsi_data *dsi)
 {
-	struct dsi_data *dsi = to_dsi_data(dssdev);
 	u16 dw, dh;
 
 	dsi_perf_mark_setup(dsi);
 
-	dsi->update_channel = channel;
-
-	dsi->framedone_callback = callback;
-	dsi->framedone_data = data;
-
 	dw = dsi->vm.hactive;
 	dh = dsi->vm.vactive;
 
@@ -3859,6 +3859,26 @@ static int dsi_update(struct omap_dss_device *dssdev, int channel,
 	return 0;
 }
 
+static int dsi_update(struct omap_dss_device *dssdev, int channel,
+		void (*callback)(int, void *), void *data)
+{
+	struct dsi_data *dsi = to_dsi_data(dssdev);
+
+	dsi->update_channel = channel;
+	dsi->framedone_callback = callback;
+	dsi->framedone_data = data;
+
+	if (dsi->te_enabled && dsi->te_gpio) {
+		schedule_delayed_work(&dsi->te_timeout_work,
+				      msecs_to_jiffies(250));
+		atomic_set(&dsi->do_ext_te_update, 1);
+	} else {
+		_dsi_update(dsi);
+	}
+
+	return 0;
+}
+
 /* Display funcs */
 
 static int dsi_configure_dispc_clocks(struct dsi_data *dsi)
@@ -4102,6 +4122,14 @@ static int dsi_enable_te(struct omap_dss_device *dssdev, bool enable)
 	struct dsi_data *dsi = to_dsi_data(dssdev);
 
 	dsi->te_enabled = enable;
+
+	if (dsi->te_gpio) {
+		if (enable)
+			enable_irq(gpiod_to_irq(dsi->te_gpio));
+		else
+			disable_irq(gpiod_to_irq(dsi->te_gpio));
+	}
+
 	return 0;
 }
 
@@ -4779,11 +4807,91 @@ static const struct omap_dss_device_ops dsi_ops = {
 	},
 };
 
+static irqreturn_t omap_dsi_te_irq_handler(int irq, void *dev_id)
+{
+	struct dsi_data *dsi = (struct dsi_data*) dev_id;
+	int old;
+
+	old = atomic_cmpxchg(&dsi->do_ext_te_update, 1, 0);
+	if (old) {
+		cancel_delayed_work(&dsi->te_timeout_work);
+		_dsi_update(dsi);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static void omap_dsi_te_timeout_work_callback(struct work_struct *work)
+{
+	struct dsi_data *dsi = container_of(work, struct dsi_data,
+					te_timeout_work.work);
+	int old;
+
+	old = atomic_cmpxchg(&dsi->do_ext_te_update, 1, 0);
+	if (old) {
+		dev_err(dsi->dev, "TE not received for 250ms!\n");
+		_dsi_update(dsi);
+	}
+
+	return;
+}
+
+static int omap_dsi_register_te_irq(struct dsi_data *dsi,
+				    struct mipi_dsi_device *client)
+{
+	int err;
+	int te_irq;
+
+	dsi->te_gpio = gpiod_get_from_of_node(client->dev.of_node,
+					      "te-gpios", 0, GPIOD_IN,
+					      "dsi-tearing-effect");
+	if (IS_ERR(dsi->te_gpio)) {
+		err = PTR_ERR(dsi->te_gpio);
+
+		if (err == -ENOENT) {
+			dsi->te_gpio = NULL;
+			return 0;
+		} else {
+			dev_err(dsi->dev, "Could not get TE gpio: %d\n", err);
+			return err;
+		}
+	}
+
+	te_irq = gpiod_to_irq(dsi->te_gpio);
+	irq_set_status_flags(te_irq, IRQ_NOAUTOEN);
+
+	err = request_threaded_irq(te_irq, omap_dsi_te_irq_handler, NULL,
+				   IRQF_TRIGGER_RISING, "TE", dsi);
+	if (err) {
+		dev_err(dsi->dev, "request irq failed with %d\n", err);
+		gpiod_put(dsi->te_gpio);
+		return err;
+	}
+
+	INIT_DEFERRABLE_WORK(&dsi->te_timeout_work,
+			     omap_dsi_te_timeout_work_callback);
+
+	dev_dbg(dsi->dev, "Using GPIO TE\n");
+
+	return 0;
+}
+
+static void omap_dsi_unregister_te_irq(struct dsi_data *dsi)
+{
+	if (dsi->te_gpio) {
+		free_irq(gpiod_to_irq(dsi->te_gpio), dsi);
+		cancel_delayed_work(&dsi->te_timeout_work);
+		gpiod_put(dsi->te_gpio);
+		dsi->te_gpio = NULL;
+	}
+}
+
 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;
@@ -4793,13 +4901,20 @@ int omap_dsi_host_attach(struct mipi_dsi_host *host,
 		return -EBUSY;
 	}
 
-	dsi->vc[channel].dest = client;
+	atomic_set(&dsi->do_ext_te_update, 0);
 
-	dsi->pix_fmt = client->format;
-	if (client->mode_flags & MIPI_DSI_MODE_VIDEO)
+	if (client->mode_flags & MIPI_DSI_MODE_VIDEO) {
 		dsi->mode = OMAP_DSS_DSI_VIDEO_MODE;
-	else
+	} else {
+		r = omap_dsi_register_te_irq(dsi, client);
+		if (r)
+			return r;
+
 		dsi->mode = OMAP_DSS_DSI_CMD_MODE;
+	}
+
+	dsi->vc[channel].dest = client;
+	dsi->pix_fmt = client->format;
 
 	return 0;
 }
@@ -4816,6 +4931,7 @@ int omap_dsi_host_detach(struct mipi_dsi_host *host,
 	if (dsi->vc[channel].dest != client)
 		return -EINVAL;
 
+	omap_dsi_unregister_te_irq(dsi);
 	dsi->vc[channel].dest = NULL;
 	return 0;
 }
-- 
2.24.0

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

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

* [RFCv1 25/42] drm/omap: dsi: drop custom enable_te() API
  2019-11-17  2:39 [RFCv1 00/42] drm/omap: Convert DSI code to use drm_mipi_dsi and drm_panel Sebastian Reichel
                   ` (24 preceding siblings ...)
  2019-11-17  2:40 ` [RFCv1 24/42] drm/omap: dsi: move TE GPIO handling into core Sebastian Reichel
@ 2019-11-17  2:40 ` Sebastian Reichel
  2019-11-17  2:40 ` [RFCv1 26/42] drm/omap: dsi: do bus locking in host driver Sebastian Reichel
                   ` (16 subsequent siblings)
  42 siblings, 0 replies; 64+ messages in thread
From: Sebastian Reichel @ 2019-11-17  2:40 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Tomi Valkeinen
  Cc: kernel, Tony Lindgren, H. Nikolaus Schaller, Merlijn Wajer,
	Sebastian Reichel, dri-devel, linux-omap

Instead of using the custon enable_te() API, this automatically
enables/disables TE core support when a matching packet is send
to the panel.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 .../gpu/drm/omapdrm/displays/panel-dsi-cm.c   |  3 --
 drivers/gpu/drm/omapdrm/dss/dsi.c             | 33 ++++++++++++++-----
 drivers/gpu/drm/omapdrm/dss/omapdss.h         |  2 --
 3 files changed, 24 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
index 9a259e0d9e97..787f953168ec 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
@@ -772,7 +772,6 @@ static int dsicm_update(struct omap_dss_device *dssdev,
 
 static int _dsicm_enable_te(struct panel_drv_data *ddata, bool enable)
 {
-	struct omap_dss_device *src = ddata->src;
 	struct mipi_dsi_device *dsi = ddata->dsi;
 	int r;
 
@@ -781,8 +780,6 @@ static int _dsicm_enable_te(struct panel_drv_data *ddata, bool enable)
 	else
 		r = mipi_dsi_dcs_set_tear_off(dsi);
 
-	src->ops->dsi.enable_te(src, enable);
-
 	/* possible panel bug */
 	msleep(100);
 
diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index 8f900cf1aed7..8060009fbfb9 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -4117,10 +4117,8 @@ static void dsi_display_disable(struct omap_dss_device *dssdev,
 	mutex_unlock(&dsi->lock);
 }
 
-static int dsi_enable_te(struct omap_dss_device *dssdev, bool enable)
+static int dsi_enable_te(struct dsi_data *dsi, bool enable)
 {
-	struct dsi_data *dsi = to_dsi_data(dssdev);
-
 	dsi->te_enabled = enable;
 
 	if (dsi->te_gpio) {
@@ -4730,6 +4728,7 @@ static ssize_t omap_dsi_host_transfer(struct mipi_dsi_host *host,
 {
 	struct dsi_data *dsi = host_to_omap(host);
 	struct omap_dss_device *dssdev = &dsi->output;
+	int r;
 
 	if (NEQV(msg->flags & MIPI_DSI_MSG_USE_LPM, dsi->in_lp_mode)) {
 		dsi_vc_enable_hs(dssdev, msg->channel,
@@ -4746,16 +4745,34 @@ static ssize_t omap_dsi_host_transfer(struct mipi_dsi_host *host,
 	case MIPI_DSI_DCS_LONG_WRITE:
 	case MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE:
 	case MIPI_DSI_NULL_PACKET:
-		return dsi_vc_write_common(dssdev, msg);
+		r = dsi_vc_write_common(dssdev, 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:
-		return dsi_vc_generic_read(dssdev, msg);
+		r = dsi_vc_generic_read(dssdev, msg);
+		break;
 	case MIPI_DSI_DCS_READ:
-		return dsi_vc_dcs_read(dssdev, msg);
+		r = dsi_vc_dcs_read(dssdev, msg);
+		break;
+	default:
+		r = -EINVAL;
+		break;
 	}
 
-	return -EINVAL;
+	if (r < 0)
+		return r;
+
+	if (msg->type == MIPI_DSI_DCS_SHORT_WRITE ||
+	    msg->type == MIPI_DSI_DCS_SHORT_WRITE_PARAM) {
+		u8 cmd = ((u8*) msg->tx_buf)[0];
+		if (cmd == MIPI_DCS_SET_TEAR_OFF)
+			dsi_enable_te(dsi, false);
+		else if(cmd == MIPI_DCS_SET_TEAR_ON)
+			dsi_enable_te(dsi, true);
+	}
+
+	return 0;
 }
 
 static int dsi_get_clocks(struct dsi_data *dsi)
@@ -4802,8 +4819,6 @@ static const struct omap_dss_device_ops dsi_ops = {
 		.disable_video_output = dsi_disable_video_output,
 
 		.update = dsi_update,
-
-		.enable_te = dsi_enable_te,
 	},
 };
 
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index 5bcc14d9f737..ca52b08c57db 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -294,8 +294,6 @@ struct omapdss_dsi_ops {
 	int (*set_config)(struct omap_dss_device *dssdev,
 			const struct omap_dss_dsi_config *cfg);
 
-	int (*enable_te)(struct omap_dss_device *dssdev, bool enable);
-
 	int (*update)(struct omap_dss_device *dssdev, int channel,
 			void (*callback)(int, void *), void *data);
 
-- 
2.24.0

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

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

* [RFCv1 26/42] drm/omap: dsi: do bus locking in host driver
  2019-11-17  2:39 [RFCv1 00/42] drm/omap: Convert DSI code to use drm_mipi_dsi and drm_panel Sebastian Reichel
                   ` (25 preceding siblings ...)
  2019-11-17  2:40 ` [RFCv1 25/42] drm/omap: dsi: drop custom enable_te() API Sebastian Reichel
@ 2019-11-17  2:40 ` Sebastian Reichel
  2019-11-17  2:40 ` [RFCv1 27/42] drm/omap: dsi: untangle ulps ops from enable/disable Sebastian Reichel
                   ` (15 subsequent siblings)
  42 siblings, 0 replies; 64+ messages in thread
From: Sebastian Reichel @ 2019-11-17  2:40 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Tomi Valkeinen
  Cc: kernel, Tony Lindgren, H. Nikolaus Schaller, Merlijn Wajer,
	Sebastian Reichel, dri-devel, linux-omap

This moves the bus locking into the host driver and unexports
the custom API in preparation for drm_panel support.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 .../gpu/drm/omapdrm/displays/panel-dsi-cm.c   | 46 +------------------
 drivers/gpu/drm/omapdrm/dss/dsi.c             | 33 ++++++++-----
 drivers/gpu/drm/omapdrm/dss/omapdss.h         |  3 --
 3 files changed, 23 insertions(+), 59 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
index 787f953168ec..36101d9ba84d 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
@@ -298,7 +298,6 @@ static int dsicm_wake_up(struct panel_drv_data *ddata)
 static int dsicm_bl_update_status(struct backlight_device *dev)
 {
 	struct panel_drv_data *ddata = dev_get_drvdata(&dev->dev);
-	struct omap_dss_device *src = ddata->src;
 	int r = 0;
 	int level;
 
@@ -313,15 +312,11 @@ static int dsicm_bl_update_status(struct backlight_device *dev)
 	mutex_lock(&ddata->lock);
 
 	if (ddata->enabled) {
-		src->ops->dsi.bus_lock(src);
-
 		r = dsicm_wake_up(ddata);
 		if (!r) {
 			r = dsicm_dcs_write_1(ddata,
 				MIPI_DCS_SET_DISPLAY_BRIGHTNESS, level);
 		}
-
-		src->ops->dsi.bus_unlock(src);
 	}
 
 	mutex_unlock(&ddata->lock);
@@ -347,21 +342,16 @@ static ssize_t dsicm_num_errors_show(struct device *dev,
 		struct device_attribute *attr, char *buf)
 {
 	struct panel_drv_data *ddata = dev_get_drvdata(dev);
-	struct omap_dss_device *src = ddata->src;
 	u8 errors = 0;
 	int r;
 
 	mutex_lock(&ddata->lock);
 
 	if (ddata->enabled) {
-		src->ops->dsi.bus_lock(src);
-
 		r = dsicm_wake_up(ddata);
 		if (!r)
 			r = dsicm_dcs_read_1(ddata, DCS_READ_NUM_ERRORS,
 					&errors);
-
-		src->ops->dsi.bus_unlock(src);
 	} else {
 		r = -ENODEV;
 	}
@@ -378,20 +368,15 @@ static ssize_t dsicm_hw_revision_show(struct device *dev,
 		struct device_attribute *attr, char *buf)
 {
 	struct panel_drv_data *ddata = dev_get_drvdata(dev);
-	struct omap_dss_device *src = ddata->src;
 	u8 id1, id2, id3;
 	int r;
 
 	mutex_lock(&ddata->lock);
 
 	if (ddata->enabled) {
-		src->ops->dsi.bus_lock(src);
-
 		r = dsicm_wake_up(ddata);
 		if (!r)
 			r = dsicm_get_id(ddata, &id1, &id2, &id3);
-
-		src->ops->dsi.bus_unlock(src);
 	} else {
 		r = -ENODEV;
 	}
@@ -409,7 +394,6 @@ static ssize_t dsicm_store_ulps(struct device *dev,
 		const char *buf, size_t count)
 {
 	struct panel_drv_data *ddata = dev_get_drvdata(dev);
-	struct omap_dss_device *src = ddata->src;
 	unsigned long t;
 	int r;
 
@@ -420,14 +404,10 @@ static ssize_t dsicm_store_ulps(struct device *dev,
 	mutex_lock(&ddata->lock);
 
 	if (ddata->enabled) {
-		src->ops->dsi.bus_lock(src);
-
 		if (t)
 			r = dsicm_enter_ulps(ddata);
 		else
 			r = dsicm_wake_up(ddata);
-
-		src->ops->dsi.bus_unlock(src);
 	}
 
 	mutex_unlock(&ddata->lock);
@@ -457,7 +437,6 @@ static ssize_t dsicm_store_ulps_timeout(struct device *dev,
 		const char *buf, size_t count)
 {
 	struct panel_drv_data *ddata = dev_get_drvdata(dev);
-	struct omap_dss_device *src = ddata->src;
 	unsigned long t;
 	int r;
 
@@ -470,9 +449,7 @@ static ssize_t dsicm_store_ulps_timeout(struct device *dev,
 
 	if (ddata->enabled) {
 		/* dsicm_wake_up will restart the timer */
-		src->ops->dsi.bus_lock(src);
 		r = dsicm_wake_up(ddata);
-		src->ops->dsi.bus_unlock(src);
 	}
 
 	mutex_unlock(&ddata->lock);
@@ -673,17 +650,11 @@ static void dsicm_disconnect(struct omap_dss_device *src,
 static void dsicm_enable(struct omap_dss_device *dssdev)
 {
 	struct panel_drv_data *ddata = to_panel_data(dssdev);
-	struct omap_dss_device *src = ddata->src;
 	int r;
 
 	mutex_lock(&ddata->lock);
 
-	src->ops->dsi.bus_lock(src);
-
 	r = dsicm_power_on(ddata);
-
-	src->ops->dsi.bus_unlock(src);
-
 	if (r)
 		goto err;
 
@@ -700,7 +671,6 @@ static void dsicm_enable(struct omap_dss_device *dssdev)
 static void dsicm_disable(struct omap_dss_device *dssdev)
 {
 	struct panel_drv_data *ddata = to_panel_data(dssdev);
-	struct omap_dss_device *src = ddata->src;
 	int r;
 
 	dsicm_bl_power(ddata, false);
@@ -709,24 +679,19 @@ static void dsicm_disable(struct omap_dss_device *dssdev)
 
 	dsicm_cancel_ulps_work(ddata);
 
-	src->ops->dsi.bus_lock(src);
-
 	r = dsicm_wake_up(ddata);
 	if (!r)
 		dsicm_power_off(ddata);
 
-	src->ops->dsi.bus_unlock(src);
-
 	mutex_unlock(&ddata->lock);
 }
 
 static void dsicm_framedone_cb(int err, void *data)
 {
 	struct panel_drv_data *ddata = data;
-	struct omap_dss_device *src = ddata->src;
 
 	dev_dbg(&ddata->dsi->dev, "framedone, err %d\n", err);
-	src->ops->dsi.bus_unlock(src);
+	mutex_unlock(&ddata->lock);
 }
 
 static int dsicm_update(struct omap_dss_device *dssdev,
@@ -739,7 +704,6 @@ static int dsicm_update(struct omap_dss_device *dssdev,
 	dev_dbg(&ddata->dsi->dev, "update %d, %d, %d x %d\n", x, y, w, h);
 
 	mutex_lock(&ddata->lock);
-	src->ops->dsi.bus_lock(src);
 
 	r = dsicm_wake_up(ddata);
 	if (r)
@@ -761,11 +725,9 @@ static int dsicm_update(struct omap_dss_device *dssdev,
 	if (r)
 		goto err;
 
-	/* note: no bus_unlock here. unlock is src framedone_cb */
-	mutex_unlock(&ddata->lock);
+	/* note: no unlock here. unlock is src framedone_cb */
 	return 0;
 err:
-	src->ops->dsi.bus_unlock(src);
 	mutex_unlock(&ddata->lock);
 	return r;
 }
@@ -791,7 +753,6 @@ static void dsicm_ulps_work(struct work_struct *work)
 	struct panel_drv_data *ddata = container_of(work, struct panel_drv_data,
 			ulps_work.work);
 	struct omap_dss_device *dssdev = &ddata->dssdev;
-	struct omap_dss_device *src = ddata->src;
 
 	mutex_lock(&ddata->lock);
 
@@ -800,11 +761,8 @@ static void dsicm_ulps_work(struct work_struct *work)
 		return;
 	}
 
-	src->ops->dsi.bus_lock(src);
-
 	dsicm_enter_ulps(ddata);
 
-	src->ops->dsi.bus_unlock(src);
 	mutex_unlock(&ddata->lock);
 }
 
diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index 8060009fbfb9..8387abea21a5 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -479,17 +479,13 @@ static inline u32 dsi_read_reg(struct dsi_data *dsi, const struct dsi_reg idx)
 	return __raw_readl(base + idx.idx);
 }
 
-static void dsi_bus_lock(struct omap_dss_device *dssdev)
+static void dsi_bus_lock(struct dsi_data *dsi)
 {
-	struct dsi_data *dsi = to_dsi_data(dssdev);
-
 	down(&dsi->bus_lock);
 }
 
-static void dsi_bus_unlock(struct omap_dss_device *dssdev)
+static void dsi_bus_unlock(struct dsi_data *dsi)
 {
-	struct dsi_data *dsi = to_dsi_data(dssdev);
-
 	up(&dsi->bus_lock);
 }
 
@@ -3805,6 +3801,8 @@ static void dsi_handle_framedone(struct dsi_data *dsi, int error)
 		REG_FLD_MOD(dsi, DSI_TIMING2, 1, 15, 15); /* LP_RX_TO */
 	}
 
+	dsi_bus_unlock(dsi);
+
 	dsi->framedone_callback(error, dsi->framedone_data);
 
 	if (!error)
@@ -3864,6 +3862,8 @@ static int dsi_update(struct omap_dss_device *dssdev, int channel,
 {
 	struct dsi_data *dsi = to_dsi_data(dssdev);
 
+	dsi_bus_lock(dsi);
+
 	dsi->update_channel = channel;
 	dsi->framedone_callback = callback;
 	dsi->framedone_data = data;
@@ -4723,10 +4723,9 @@ static enum omap_channel dsi_get_channel(struct dsi_data *dsi)
 	}
 }
 
-static ssize_t omap_dsi_host_transfer(struct mipi_dsi_host *host,
-				      const struct mipi_dsi_msg *msg)
+static ssize_t _omap_dsi_host_transfer(struct dsi_data *dsi,
+				       const struct mipi_dsi_msg *msg)
 {
-	struct dsi_data *dsi = host_to_omap(host);
 	struct omap_dss_device *dssdev = &dsi->output;
 	int r;
 
@@ -4775,6 +4774,19 @@ static ssize_t omap_dsi_host_transfer(struct mipi_dsi_host *host,
 	return 0;
 }
 
+static ssize_t omap_dsi_host_transfer(struct mipi_dsi_host *host,
+				      const struct mipi_dsi_msg *msg)
+{
+	struct dsi_data *dsi = host_to_omap(host);
+	int r;
+
+	dsi_bus_lock(dsi);
+	r = _omap_dsi_host_transfer(dsi, msg);
+	dsi_bus_unlock(dsi);
+
+	return r;
+}
+
 static int dsi_get_clocks(struct dsi_data *dsi)
 {
 	struct clk *clk;
@@ -4808,9 +4820,6 @@ static const struct omap_dss_device_ops dsi_ops = {
 	.enable = dsi_display_enable,
 
 	.dsi = {
-		.bus_lock = dsi_bus_lock,
-		.bus_unlock = dsi_bus_unlock,
-
 		.disable = dsi_display_disable,
 
 		.set_config = dsi_set_config,
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index ca52b08c57db..2d6ab948a6dd 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -297,9 +297,6 @@ struct omapdss_dsi_ops {
 	int (*update)(struct omap_dss_device *dssdev, int channel,
 			void (*callback)(int, void *), void *data);
 
-	void (*bus_lock)(struct omap_dss_device *dssdev);
-	void (*bus_unlock)(struct omap_dss_device *dssdev);
-
 	int (*enable_video_output)(struct omap_dss_device *dssdev, int channel);
 	void (*disable_video_output)(struct omap_dss_device *dssdev,
 			int channel);
-- 
2.24.0

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

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

* [RFCv1 27/42] drm/omap: dsi: untangle ulps ops from enable/disable
  2019-11-17  2:39 [RFCv1 00/42] drm/omap: Convert DSI code to use drm_mipi_dsi and drm_panel Sebastian Reichel
                   ` (26 preceding siblings ...)
  2019-11-17  2:40 ` [RFCv1 26/42] drm/omap: dsi: do bus locking in host driver Sebastian Reichel
@ 2019-11-17  2:40 ` Sebastian Reichel
  2019-11-17  2:40 ` [RFCv1 28/42] drm/dsi: add MIPI_DSI_MODE_ULPS_IDLE Sebastian Reichel
                   ` (14 subsequent siblings)
  42 siblings, 0 replies; 64+ messages in thread
From: Sebastian Reichel @ 2019-11-17  2:40 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Tomi Valkeinen
  Cc: kernel, Tony Lindgren, H. Nikolaus Schaller, Merlijn Wajer,
	Sebastian Reichel, dri-devel, linux-omap

Create a custom function pointer for ULPS and use it instead of
reusing disable/enable functions for ULPS mode switch. This allows
us to use the common disable/enable functions pointers for DSI.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 .../gpu/drm/omapdrm/displays/panel-dsi-cm.c   |  8 ++--
 drivers/gpu/drm/omapdrm/dss/dsi.c             | 38 ++++++++++++++-----
 drivers/gpu/drm/omapdrm/dss/omapdss.h         |  5 +--
 3 files changed, 34 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
index 36101d9ba84d..f73b8f489f82 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
@@ -233,7 +233,7 @@ static int dsicm_enter_ulps(struct panel_drv_data *ddata)
 	if (r)
 		goto err;
 
-	src->ops->dsi.disable(src, false, true);
+	src->ops->dsi.ulps(src, true);
 
 	ddata->ulps_enabled = true;
 
@@ -258,7 +258,7 @@ static int dsicm_exit_ulps(struct panel_drv_data *ddata)
 	if (!ddata->ulps_enabled)
 		return 0;
 
-	src->ops->enable(src);
+	src->ops->dsi.ulps(src, false);
 	ddata->dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
 
 	r = _dsicm_enable_te(ddata, ddata->te_enabled);
@@ -586,7 +586,7 @@ static int dsicm_power_on(struct panel_drv_data *ddata)
 
 	dsicm_hw_reset(ddata);
 
-	src->ops->dsi.disable(src, true, false);
+	src->ops->disable(src);
 err_regulators:
 	r = regulator_bulk_disable(DCS_REGULATOR_SUPPLY_NUM, ddata->supplies);
 	if (r)
@@ -612,7 +612,7 @@ static void dsicm_power_off(struct panel_drv_data *ddata)
 		dsicm_hw_reset(ddata);
 	}
 
-	src->ops->dsi.disable(src, true, false);
+	src->ops->disable(src);
 
 	r = regulator_bulk_disable(DCS_REGULATOR_SUPPLY_NUM, ddata->supplies);
 	if (r)
diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index 8387abea21a5..d200b7a6f93c 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -4062,13 +4062,10 @@ static void dsi_display_uninit_dsi(struct dsi_data *dsi, bool disconnect_lanes,
 	}
 }
 
-static void dsi_display_enable(struct omap_dss_device *dssdev)
+static void dsi_display_ulps_enable(struct dsi_data *dsi)
 {
-	struct dsi_data *dsi = to_dsi_data(dssdev);
 	int r;
 
-	DSSDBG("dsi_display_enable\n");
-
 	WARN_ON(!dsi_bus_is_locked(dsi));
 
 	mutex_lock(&dsi->lock);
@@ -4091,16 +4088,19 @@ static void dsi_display_enable(struct omap_dss_device *dssdev)
 	dsi_runtime_put(dsi);
 err_get_dsi:
 	mutex_unlock(&dsi->lock);
-	DSSDBG("dsi_display_enable FAILED\n");
+	DSSDBG("dsi_display_ulps_enable FAILED\n");
 }
 
-static void dsi_display_disable(struct omap_dss_device *dssdev,
-		bool disconnect_lanes, bool enter_ulps)
+static void dsi_display_enable(struct omap_dss_device *dssdev)
 {
 	struct dsi_data *dsi = to_dsi_data(dssdev);
+	DSSDBG("dsi_display_enable\n");
+	dsi_display_ulps_enable(dsi);
+}
 
-	DSSDBG("dsi_display_disable\n");
-
+static void dsi_display_ulps_disable(struct dsi_data *dsi,
+		bool disconnect_lanes, bool enter_ulps)
+{
 	WARN_ON(!dsi_bus_is_locked(dsi));
 
 	mutex_lock(&dsi->lock);
@@ -4117,6 +4117,23 @@ static void dsi_display_disable(struct omap_dss_device *dssdev,
 	mutex_unlock(&dsi->lock);
 }
 
+static void dsi_display_disable(struct omap_dss_device *dssdev)
+{
+	struct dsi_data *dsi = to_dsi_data(dssdev);
+	DSSDBG("dsi_display_disable\n");
+	dsi_display_ulps_disable(dsi, true, false);
+}
+
+static void dsi_ulps(struct omap_dss_device *dssdev, bool enable)
+{
+	struct dsi_data *dsi = to_dsi_data(dssdev);
+	DSSDBG("dsi_ulps\n");
+	if (enable)
+		dsi_display_ulps_disable(dsi, false, true);
+	else
+		dsi_display_ulps_enable(dsi);
+}
+
 static int dsi_enable_te(struct dsi_data *dsi, bool enable)
 {
 	dsi->te_enabled = enable;
@@ -4818,9 +4835,10 @@ static const struct omap_dss_device_ops dsi_ops = {
 	.connect = dsi_connect,
 	.disconnect = dsi_disconnect,
 	.enable = dsi_display_enable,
+	.disable = dsi_display_disable,
 
 	.dsi = {
-		.disable = dsi_display_disable,
+		.ulps = dsi_ulps,
 
 		.set_config = dsi_set_config,
 
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index 2d6ab948a6dd..ad525cf80ad8 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -287,10 +287,9 @@ struct omapdss_hdmi_ops {
 };
 
 struct omapdss_dsi_ops {
-	void (*disable)(struct omap_dss_device *dssdev, bool disconnect_lanes,
-			bool enter_ulps);
-
 	/* bus configuration */
+	void (*ulps)(struct omap_dss_device *dssdev, bool enable);
+
 	int (*set_config)(struct omap_dss_device *dssdev,
 			const struct omap_dss_dsi_config *cfg);
 
-- 
2.24.0

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

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

* [RFCv1 28/42] drm/dsi: add MIPI_DSI_MODE_ULPS_IDLE
  2019-11-17  2:39 [RFCv1 00/42] drm/omap: Convert DSI code to use drm_mipi_dsi and drm_panel Sebastian Reichel
                   ` (27 preceding siblings ...)
  2019-11-17  2:40 ` [RFCv1 27/42] drm/omap: dsi: untangle ulps ops from enable/disable Sebastian Reichel
@ 2019-11-17  2:40 ` Sebastian Reichel
  2019-11-17  2:40 ` [RFCv1 29/42] drm/omap: dsi: do ULPS in host driver Sebastian Reichel
                   ` (13 subsequent siblings)
  42 siblings, 0 replies; 64+ messages in thread
From: Sebastian Reichel @ 2019-11-17  2:40 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Tomi Valkeinen
  Cc: kernel, Tony Lindgren, H. Nikolaus Schaller, Merlijn Wajer,
	Sebastian Reichel, dri-devel, linux-omap

DSI command mode panels are self-refreshing displays, that
can be updated very rarely for static images. For this kind
of scenario some panels support, that the DSI bus switches
into ULPS mode until the panel needs to be refreshed.

This is problematic on some panels, so introduce a flag to
signal the DSI host implementation that the panel allows
going into ULPS mode.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 include/drm/drm_mipi_dsi.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
index 13cf2ae59f6c..5f2e3e6fb013 100644
--- a/include/drm/drm_mipi_dsi.h
+++ b/include/drm/drm_mipi_dsi.h
@@ -131,6 +131,8 @@ struct mipi_dsi_host *of_find_mipi_dsi_host_by_node(struct device_node *node);
 #define MIPI_DSI_CLOCK_NON_CONTINUOUS	BIT(10)
 /* transmit data in low power */
 #define MIPI_DSI_MODE_LPM		BIT(11)
+/* allow going into ULPS mode while command mode panel is not updated */
+#define MIPI_DSI_MODE_ULPS_IDLE		BIT(12)
 
 enum mipi_dsi_pixel_format {
 	MIPI_DSI_FMT_RGB888,
-- 
2.24.0

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

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

* [RFCv1 29/42] drm/omap: dsi: do ULPS in host driver
  2019-11-17  2:39 [RFCv1 00/42] drm/omap: Convert DSI code to use drm_mipi_dsi and drm_panel Sebastian Reichel
                   ` (28 preceding siblings ...)
  2019-11-17  2:40 ` [RFCv1 28/42] drm/dsi: add MIPI_DSI_MODE_ULPS_IDLE Sebastian Reichel
@ 2019-11-17  2:40 ` Sebastian Reichel
  2019-11-17  2:40 ` [RFCv1 30/42] drm/omap: dsi: move panel refresh function to host Sebastian Reichel
                   ` (12 subsequent siblings)
  42 siblings, 0 replies; 64+ messages in thread
From: Sebastian Reichel @ 2019-11-17  2:40 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Tomi Valkeinen
  Cc: kernel, Tony Lindgren, H. Nikolaus Schaller, Merlijn Wajer,
	Sebastian Reichel, dri-devel, linux-omap

Move ULPS handling into the DSI host controller, so that we
no longer need a custom API for the DSI client.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 .../gpu/drm/omapdrm/displays/panel-dsi-cm.c   | 273 +-----------------
 drivers/gpu/drm/omapdrm/dss/dsi.c             |  61 +++-
 drivers/gpu/drm/omapdrm/dss/omapdss.h         |   2 -
 3 files changed, 62 insertions(+), 274 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
index f73b8f489f82..56398e2aec2d 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
@@ -16,7 +16,6 @@
 #include <linux/module.h>
 #include <linux/sched/signal.h>
 #include <linux/slab.h>
-#include <linux/workqueue.h>
 #include <linux/of_device.h>
 #include <linux/regulator/consumer.h>
 
@@ -69,21 +68,13 @@ struct panel_drv_data {
 
 	bool intro_printed;
 
-	struct workqueue_struct *workqueue;
-
 	bool ulps_enabled;
-	unsigned int ulps_timeout;
-	struct delayed_work ulps_work;
 };
 
 #define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev)
 
 static int _dsicm_enable_te(struct panel_drv_data *ddata, bool enable);
 
-static int dsicm_panel_reset(struct panel_drv_data *ddata);
-
-static void dsicm_ulps_work(struct work_struct *work);
-
 static void dsicm_bl_power(struct panel_drv_data *ddata, bool enable)
 {
 	struct backlight_device *backlight;
@@ -207,94 +198,6 @@ static int dsicm_set_update_window(struct panel_drv_data *ddata,
 	return 0;
 }
 
-static void dsicm_queue_ulps_work(struct panel_drv_data *ddata)
-{
-	if (ddata->ulps_timeout > 0)
-		queue_delayed_work(ddata->workqueue, &ddata->ulps_work,
-				msecs_to_jiffies(ddata->ulps_timeout));
-}
-
-static void dsicm_cancel_ulps_work(struct panel_drv_data *ddata)
-{
-	cancel_delayed_work(&ddata->ulps_work);
-}
-
-static int dsicm_enter_ulps(struct panel_drv_data *ddata)
-{
-	struct omap_dss_device *src = ddata->src;
-	int r;
-
-	if (ddata->ulps_enabled)
-		return 0;
-
-	dsicm_cancel_ulps_work(ddata);
-
-	r = _dsicm_enable_te(ddata, false);
-	if (r)
-		goto err;
-
-	src->ops->dsi.ulps(src, true);
-
-	ddata->ulps_enabled = true;
-
-	return 0;
-
-err:
-	dev_err(&ddata->dsi->dev, "enter ULPS failed");
-	dsicm_panel_reset(ddata);
-
-	ddata->ulps_enabled = false;
-
-	dsicm_queue_ulps_work(ddata);
-
-	return r;
-}
-
-static int dsicm_exit_ulps(struct panel_drv_data *ddata)
-{
-	struct omap_dss_device *src = ddata->src;
-	int r;
-
-	if (!ddata->ulps_enabled)
-		return 0;
-
-	src->ops->dsi.ulps(src, false);
-	ddata->dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
-
-	r = _dsicm_enable_te(ddata, ddata->te_enabled);
-	if (r) {
-		dev_err(&ddata->dsi->dev, "failed to re-enable TE");
-		goto err2;
-	}
-
-	dsicm_queue_ulps_work(ddata);
-
-	ddata->ulps_enabled = false;
-
-	return 0;
-
-err2:
-	dev_err(&ddata->dsi->dev, "failed to exit ULPS");
-
-	r = dsicm_panel_reset(ddata);
-	if (!r)
-		ddata->ulps_enabled = false;
-
-	dsicm_queue_ulps_work(ddata);
-
-	return r;
-}
-
-static int dsicm_wake_up(struct panel_drv_data *ddata)
-{
-	if (ddata->ulps_enabled)
-		return dsicm_exit_ulps(ddata);
-
-	dsicm_cancel_ulps_work(ddata);
-	dsicm_queue_ulps_work(ddata);
-	return 0;
-}
-
 static int dsicm_bl_update_status(struct backlight_device *dev)
 {
 	struct panel_drv_data *ddata = dev_get_drvdata(&dev->dev);
@@ -312,11 +215,8 @@ static int dsicm_bl_update_status(struct backlight_device *dev)
 	mutex_lock(&ddata->lock);
 
 	if (ddata->enabled) {
-		r = dsicm_wake_up(ddata);
-		if (!r) {
-			r = dsicm_dcs_write_1(ddata,
-				MIPI_DCS_SET_DISPLAY_BRIGHTNESS, level);
-		}
+		r = dsicm_dcs_write_1(ddata, MIPI_DCS_SET_DISPLAY_BRIGHTNESS,
+				      level);
 	}
 
 	mutex_unlock(&ddata->lock);
@@ -343,18 +243,12 @@ static ssize_t dsicm_num_errors_show(struct device *dev,
 {
 	struct panel_drv_data *ddata = dev_get_drvdata(dev);
 	u8 errors = 0;
-	int r;
+	int r = -ENODEV;
 
 	mutex_lock(&ddata->lock);
 
-	if (ddata->enabled) {
-		r = dsicm_wake_up(ddata);
-		if (!r)
-			r = dsicm_dcs_read_1(ddata, DCS_READ_NUM_ERRORS,
-					&errors);
-	} else {
-		r = -ENODEV;
-	}
+	if (ddata->enabled)
+		r = dsicm_dcs_read_1(ddata, DCS_READ_NUM_ERRORS, &errors);
 
 	mutex_unlock(&ddata->lock);
 
@@ -369,17 +263,12 @@ static ssize_t dsicm_hw_revision_show(struct device *dev,
 {
 	struct panel_drv_data *ddata = dev_get_drvdata(dev);
 	u8 id1, id2, id3;
-	int r;
+	int r = -ENODEV;
 
 	mutex_lock(&ddata->lock);
 
-	if (ddata->enabled) {
-		r = dsicm_wake_up(ddata);
-		if (!r)
-			r = dsicm_get_id(ddata, &id1, &id2, &id3);
-	} else {
-		r = -ENODEV;
-	}
+	if (ddata->enabled)
+		r = dsicm_get_id(ddata, &id1, &id2, &id3);
 
 	mutex_unlock(&ddata->lock);
 
@@ -389,103 +278,12 @@ static ssize_t dsicm_hw_revision_show(struct device *dev,
 	return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x\n", id1, id2, id3);
 }
 
-static ssize_t dsicm_store_ulps(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf, size_t count)
-{
-	struct panel_drv_data *ddata = dev_get_drvdata(dev);
-	unsigned long t;
-	int r;
-
-	r = kstrtoul(buf, 0, &t);
-	if (r)
-		return r;
-
-	mutex_lock(&ddata->lock);
-
-	if (ddata->enabled) {
-		if (t)
-			r = dsicm_enter_ulps(ddata);
-		else
-			r = dsicm_wake_up(ddata);
-	}
-
-	mutex_unlock(&ddata->lock);
-
-	if (r)
-		return r;
-
-	return count;
-}
-
-static ssize_t dsicm_show_ulps(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct panel_drv_data *ddata = dev_get_drvdata(dev);
-	unsigned int t;
-
-	mutex_lock(&ddata->lock);
-	t = ddata->ulps_enabled;
-	mutex_unlock(&ddata->lock);
-
-	return snprintf(buf, PAGE_SIZE, "%u\n", t);
-}
-
-static ssize_t dsicm_store_ulps_timeout(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf, size_t count)
-{
-	struct panel_drv_data *ddata = dev_get_drvdata(dev);
-	unsigned long t;
-	int r;
-
-	r = kstrtoul(buf, 0, &t);
-	if (r)
-		return r;
-
-	mutex_lock(&ddata->lock);
-	ddata->ulps_timeout = t;
-
-	if (ddata->enabled) {
-		/* dsicm_wake_up will restart the timer */
-		r = dsicm_wake_up(ddata);
-	}
-
-	mutex_unlock(&ddata->lock);
-
-	if (r)
-		return r;
-
-	return count;
-}
-
-static ssize_t dsicm_show_ulps_timeout(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct panel_drv_data *ddata = dev_get_drvdata(dev);
-	unsigned int t;
-
-	mutex_lock(&ddata->lock);
-	t = ddata->ulps_timeout;
-	mutex_unlock(&ddata->lock);
-
-	return snprintf(buf, PAGE_SIZE, "%u\n", t);
-}
-
 static DEVICE_ATTR(num_dsi_errors, S_IRUGO, dsicm_num_errors_show, NULL);
 static DEVICE_ATTR(hw_revision, S_IRUGO, dsicm_hw_revision_show, NULL);
-static DEVICE_ATTR(ulps, S_IRUGO | S_IWUSR,
-		dsicm_show_ulps, dsicm_store_ulps);
-static DEVICE_ATTR(ulps_timeout, S_IRUGO | S_IWUSR,
-		dsicm_show_ulps_timeout, dsicm_store_ulps_timeout);
 
 static struct attribute *dsicm_attrs[] = {
 	&dev_attr_num_dsi_errors.attr,
 	&dev_attr_hw_revision.attr,
-	&dev_attr_ulps.attr,
-	&dev_attr_ulps_timeout.attr,
 	NULL,
 };
 
@@ -621,15 +419,6 @@ static void dsicm_power_off(struct panel_drv_data *ddata)
 	ddata->enabled = 0;
 }
 
-static int dsicm_panel_reset(struct panel_drv_data *ddata)
-{
-	dev_err(&ddata->dsi->dev, "performing LCD reset\n");
-
-	dsicm_power_off(ddata);
-	dsicm_hw_reset(ddata);
-	return dsicm_power_on(ddata);
-}
-
 static int dsicm_connect(struct omap_dss_device *src,
 			 struct omap_dss_device *dst)
 {
@@ -671,17 +460,12 @@ static void dsicm_enable(struct omap_dss_device *dssdev)
 static void dsicm_disable(struct omap_dss_device *dssdev)
 {
 	struct panel_drv_data *ddata = to_panel_data(dssdev);
-	int r;
 
 	dsicm_bl_power(ddata, false);
 
 	mutex_lock(&ddata->lock);
 
-	dsicm_cancel_ulps_work(ddata);
-
-	r = dsicm_wake_up(ddata);
-	if (!r)
-		dsicm_power_off(ddata);
+	dsicm_power_off(ddata);
 
 	mutex_unlock(&ddata->lock);
 }
@@ -705,10 +489,6 @@ static int dsicm_update(struct omap_dss_device *dssdev,
 
 	mutex_lock(&ddata->lock);
 
-	r = dsicm_wake_up(ddata);
-	if (r)
-		goto err;
-
 	if (!ddata->enabled) {
 		r = 0;
 		goto err;
@@ -748,24 +528,6 @@ static int _dsicm_enable_te(struct panel_drv_data *ddata, bool enable)
 	return r;
 }
 
-static void dsicm_ulps_work(struct work_struct *work)
-{
-	struct panel_drv_data *ddata = container_of(work, struct panel_drv_data,
-			ulps_work.work);
-	struct omap_dss_device *dssdev = &ddata->dssdev;
-
-	mutex_lock(&ddata->lock);
-
-	if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE || !ddata->enabled) {
-		mutex_unlock(&ddata->lock);
-		return;
-	}
-
-	dsicm_enter_ulps(ddata);
-
-	mutex_unlock(&ddata->lock);
-}
-
 static int dsicm_get_modes(struct omap_dss_device *dssdev,
 			   struct drm_connector *connector)
 {
@@ -865,7 +627,7 @@ static int dsicm_probe_of(struct mipi_dsi_device *dsi)
 		ddata->use_dsi_backlight = true;
 	}
 
-	/* TODO: ulps */
+	/* TODO: ulps_enabled */
 
 	return 0;
 }
@@ -913,13 +675,6 @@ static int dsicm_probe(struct mipi_dsi_device *dsi)
 
 	mutex_init(&ddata->lock);
 
-	ddata->workqueue = create_singlethread_workqueue("dsicm_wq");
-	if (!ddata->workqueue) {
-		r = -ENOMEM;
-		goto err_reg;
-	}
-	INIT_DELAYED_WORK(&ddata->ulps_work, dsicm_ulps_work);
-
 	dsicm_hw_reset(ddata);
 
 	if (ddata->use_dsi_backlight) {
@@ -950,6 +705,9 @@ static int dsicm_probe(struct mipi_dsi_device *dsi)
 	dsi->hs_rate = 300000000;
 	dsi->lp_rate = 10000000;
 
+	if (ddata->ulps_enabled)
+		dsi->mode_flags |= MIPI_DSI_MODE_ULPS_IDLE;
+
 	r = mipi_dsi_attach(dsi);
 	if (r < 0)
 		goto err_dsi_attach;
@@ -959,8 +717,6 @@ static int dsicm_probe(struct mipi_dsi_device *dsi)
 err_dsi_attach:
 	sysfs_remove_group(&dsi->dev.kobj, &dsicm_attr_group);
 err_bl:
-	destroy_workqueue(ddata->workqueue);
-err_reg:
 	if (ddata->extbldev)
 		put_device(&ddata->extbldev->dev);
 
@@ -987,9 +743,6 @@ static int __exit dsicm_remove(struct mipi_dsi_device *dsi)
 	if (ddata->extbldev)
 		put_device(&ddata->extbldev->dev);
 
-	dsicm_cancel_ulps_work(ddata);
-	destroy_workqueue(ddata->workqueue);
-
 	/* reset, to be sure that the panel is in a valid state */
 	dsicm_hw_reset(ddata);
 
diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index d200b7a6f93c..35c0ce72cd15 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -210,6 +210,8 @@ struct dsi_reg { u16 module; u16 idx; };
 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);
 static void dsi_display_uninit_dispc(struct dsi_data *dsi);
 
@@ -380,6 +382,9 @@ struct dsi_data {
 
 	bool te_enabled;
 	bool ulps_enabled;
+	bool ulps_auto_idle;
+
+	struct delayed_work ulps_work;
 
 	void (*framedone_callback)(int, void *);
 	void *framedone_data;
@@ -3801,6 +3806,7 @@ 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);
 
 	dsi->framedone_callback(error, dsi->framedone_data);
@@ -3863,6 +3869,7 @@ static int dsi_update(struct omap_dss_device *dssdev, int channel,
 	struct dsi_data *dsi = to_dsi_data(dssdev);
 
 	dsi_bus_lock(dsi);
+	dsi_set_ulps_auto(dsi, false);
 
 	dsi->update_channel = channel;
 	dsi->framedone_callback = callback;
@@ -4124,16 +4131,6 @@ static void dsi_display_disable(struct omap_dss_device *dssdev)
 	dsi_display_ulps_disable(dsi, true, false);
 }
 
-static void dsi_ulps(struct omap_dss_device *dssdev, bool enable)
-{
-	struct dsi_data *dsi = to_dsi_data(dssdev);
-	DSSDBG("dsi_ulps\n");
-	if (enable)
-		dsi_display_ulps_disable(dsi, false, true);
-	else
-		dsi_display_ulps_enable(dsi);
-}
-
 static int dsi_enable_te(struct dsi_data *dsi, bool enable)
 {
 	dsi->te_enabled = enable;
@@ -4148,6 +4145,40 @@ 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_display_ulps_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_display_ulps_enable(dsi);
+		dsi_enable_te(dsi, true);
+	}
+}
+
 #ifdef PRINT_VERBOSE_VM_TIMINGS
 static void print_dsi_vm(const char *str,
 		const struct omap_dss_dsi_videomode_timings *t)
@@ -4798,7 +4829,9 @@ static ssize_t omap_dsi_host_transfer(struct mipi_dsi_host *host,
 	int r;
 
 	dsi_bus_lock(dsi);
+	dsi_set_ulps_auto(dsi, false);
 	r = _omap_dsi_host_transfer(dsi, msg);
+	dsi_set_ulps_auto(dsi, true);
 	dsi_bus_unlock(dsi);
 
 	return r;
@@ -4838,8 +4871,6 @@ static const struct omap_dss_device_ops dsi_ops = {
 	.disable = dsi_display_disable,
 
 	.dsi = {
-		.ulps = dsi_ulps,
-
 		.set_config = dsi_set_config,
 
 		.enable_video_output = dsi_enable_video_output,
@@ -4958,6 +4989,12 @@ int omap_dsi_host_attach(struct mipi_dsi_host *host,
 	dsi->vc[channel].dest = client;
 	dsi->pix_fmt = client->format;
 
+	INIT_DEFERRABLE_WORK(&dsi->ulps_work,
+			     omap_dsi_ulps_work_callback);
+
+	dsi->ulps_auto_idle = !!(client->mode_flags & MIPI_DSI_MODE_ULPS_IDLE);
+	dsi_set_ulps_auto(dsi, true);
+
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index ad525cf80ad8..74cf0371b8bb 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -288,8 +288,6 @@ struct omapdss_hdmi_ops {
 
 struct omapdss_dsi_ops {
 	/* bus configuration */
-	void (*ulps)(struct omap_dss_device *dssdev, bool enable);
-
 	int (*set_config)(struct omap_dss_device *dssdev,
 			const struct omap_dss_dsi_config *cfg);
 
-- 
2.24.0

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

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

* [RFCv1 30/42] drm/omap: dsi: move panel refresh function to host
  2019-11-17  2:39 [RFCv1 00/42] drm/omap: Convert DSI code to use drm_mipi_dsi and drm_panel Sebastian Reichel
                   ` (29 preceding siblings ...)
  2019-11-17  2:40 ` [RFCv1 29/42] drm/omap: dsi: do ULPS in host driver Sebastian Reichel
@ 2019-11-17  2:40 ` Sebastian Reichel
  2019-11-17  2:40 ` [RFCv1 31/42] drm/omap: dsi: Reverse direction of the DSS device enable/disable operations Sebastian Reichel
                   ` (11 subsequent siblings)
  42 siblings, 0 replies; 64+ messages in thread
From: Sebastian Reichel @ 2019-11-17  2:40 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Tomi Valkeinen
  Cc: kernel, Tony Lindgren, H. Nikolaus Schaller, Merlijn Wajer,
	Sebastian Reichel, dri-devel, linux-omap

This moves the panel refresh/update function from the panel
driver into the DSI host driver to prepare for common drm_panel
support.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 .../gpu/drm/omapdrm/displays/panel-dsi-cm.c   |  68 ------------
 drivers/gpu/drm/omapdrm/dss/dsi.c             | 101 ++++++++++++++++--
 drivers/gpu/drm/omapdrm/dss/omapdss.h         |   7 +-
 drivers/gpu/drm/omapdrm/omap_crtc.c           |  11 +-
 4 files changed, 97 insertions(+), 90 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
index 56398e2aec2d..9bfc262f5c5a 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
@@ -177,27 +177,6 @@ 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,
-		u16 x, u16 y, u16 w, u16 h)
-{
-	struct mipi_dsi_device *dsi = ddata->dsi;
-	int r;
-	u16 x1 = x;
-	u16 x2 = x + w - 1;
-	u16 y1 = y;
-	u16 y2 = y + h - 1;
-
-	r = mipi_dsi_dcs_set_column_address(dsi, x1, x2);
-	if (r < 0)
-		return r;
-
-	r = mipi_dsi_dcs_set_page_address(dsi, y1, y2);
-	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);
@@ -470,48 +449,6 @@ static void dsicm_disable(struct omap_dss_device *dssdev)
 	mutex_unlock(&ddata->lock);
 }
 
-static void dsicm_framedone_cb(int err, void *data)
-{
-	struct panel_drv_data *ddata = data;
-
-	dev_dbg(&ddata->dsi->dev, "framedone, err %d\n", err);
-	mutex_unlock(&ddata->lock);
-}
-
-static int dsicm_update(struct omap_dss_device *dssdev,
-				    u16 x, u16 y, u16 w, u16 h)
-{
-	struct panel_drv_data *ddata = to_panel_data(dssdev);
-	struct omap_dss_device *src = ddata->src;
-	int r;
-
-	dev_dbg(&ddata->dsi->dev, "update %d, %d, %d x %d\n", x, y, w, h);
-
-	mutex_lock(&ddata->lock);
-
-	if (!ddata->enabled) {
-		r = 0;
-		goto err;
-	}
-
-	/* XXX no need to send this every frame, but dsi break if not done */
-	r = dsicm_set_update_window(ddata, 0, 0, ddata->vm.hactive,
-				    ddata->vm.vactive);
-	if (r)
-		goto err;
-
-	r = src->ops->dsi.update(src, ddata->dsi->channel, dsicm_framedone_cb,
-			ddata);
-	if (r)
-		goto err;
-
-	/* note: no unlock here. unlock is src framedone_cb */
-	return 0;
-err:
-	mutex_unlock(&ddata->lock);
-	return r;
-}
-
 static int _dsicm_enable_te(struct panel_drv_data *ddata, bool enable)
 {
 	struct mipi_dsi_device *dsi = ddata->dsi;
@@ -572,10 +509,6 @@ static const struct omap_dss_device_ops dsicm_ops = {
 	.check_timings	= dsicm_check_timings,
 };
 
-static const struct omap_dss_driver dsicm_dss_driver = {
-	.update		= dsicm_update,
-};
-
 static int dsicm_probe_of(struct mipi_dsi_device *dsi)
 {
 	struct device_node *node = dsi->dev.of_node;
@@ -660,7 +593,6 @@ static int dsicm_probe(struct mipi_dsi_device *dsi)
 	dssdev = &ddata->dssdev;
 	dssdev->dev = dev;
 	dssdev->ops = &dsicm_ops;
-	dssdev->driver = &dsicm_dss_driver;
 	dssdev->type = OMAP_DISPLAY_TYPE_DSI;
 	dssdev->display = true;
 	dssdev->owner = THIS_MODULE;
diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index 35c0ce72cd15..66ad7dbc66a2 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -217,6 +217,9 @@ static void dsi_display_uninit_dispc(struct dsi_data *dsi);
 
 static int dsi_vc_send_null(struct dsi_data *dsi, int channel);
 
+static ssize_t _omap_dsi_host_transfer(struct dsi_data *dsi,
+				       const struct mipi_dsi_msg *msg);
+
 /* DSI PLL HSDIV indices */
 #define HSDIV_DISPC	0
 #define HSDIV_DSI	1
@@ -386,9 +389,6 @@ struct dsi_data {
 
 	struct delayed_work ulps_work;
 
-	void (*framedone_callback)(int, void *);
-	void *framedone_data;
-
 	struct delayed_work framedone_timeout_work;
 
 #ifdef DSI_CATCH_MISSING_TE
@@ -3809,8 +3809,6 @@ static void dsi_handle_framedone(struct dsi_data *dsi, int error)
 	dsi_set_ulps_auto(dsi, true);
 	dsi_bus_unlock(dsi);
 
-	dsi->framedone_callback(error, dsi->framedone_data);
-
 	if (!error)
 		dsi_perf_show(dsi, "DISPC");
 }
@@ -3842,6 +3840,8 @@ static void dsi_framedone_irq_callback(void *data)
 
 	cancel_delayed_work(&dsi->framedone_timeout_work);
 
+	DSSDBG("Framedone received!\n");
+
 	dsi_handle_framedone(dsi, 0);
 }
 
@@ -3863,17 +3863,69 @@ static int _dsi_update(struct dsi_data *dsi)
 	return 0;
 }
 
-static int dsi_update(struct omap_dss_device *dssdev, int channel,
-		void (*callback)(int, void *), void *data)
+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;
+
+	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);
+}
+
+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->vc[channel].dest) {
+		r = -ENODEV;
+		goto err;
+	}
+
+	if (dsi->vm.hactive == 0 || dsi->vm.vactive == 0) {
+		r = -EINVAL;
+		goto err;
+	}
+
+	DSSDBG("dsi_update_channel: %d", channel);
+
 	dsi_set_ulps_auto(dsi, false);
 
+	r = _dsi_update_window(dsi, channel, 0, 0, dsi->vm.hactive,
+			       dsi->vm.vactive);
+	if (r < 0) {
+		DSSWARN("window update error: %d\n", r);
+		goto err;
+	}
+
 	dsi->update_channel = channel;
-	dsi->framedone_callback = callback;
-	dsi->framedone_data = data;
 
 	if (dsi->te_enabled && dsi->te_gpio) {
 		schedule_delayed_work(&dsi->te_timeout_work,
@@ -3883,6 +3935,24 @@ static int dsi_update(struct omap_dss_device *dssdev, int channel,
 		_dsi_update(dsi);
 	}
 
+	return 0;
+
+err:
+	dsi_set_ulps_auto(dsi, true);
+	dsi_bus_unlock(dsi);
+	return r;
+}
+
+static int dsi_update_all(struct omap_dss_device *dssdev)
+{
+	int i, r;
+
+	for (i = 0; i < 4; i++) {
+		r = dsi_update_channel(dssdev, i);
+		if (r != -ENODEV)
+			return r;
+	}
+
 	return 0;
 }
 
@@ -4102,7 +4172,9 @@ static void dsi_display_enable(struct omap_dss_device *dssdev)
 {
 	struct dsi_data *dsi = to_dsi_data(dssdev);
 	DSSDBG("dsi_display_enable\n");
+	dsi_bus_lock(dsi);
 	dsi_display_ulps_enable(dsi);
+	dsi_bus_unlock(dsi);
 }
 
 static void dsi_display_ulps_disable(struct dsi_data *dsi,
@@ -4128,7 +4200,9 @@ static void dsi_display_disable(struct omap_dss_device *dssdev)
 {
 	struct dsi_data *dsi = to_dsi_data(dssdev);
 	DSSDBG("dsi_display_disable\n");
+	dsi_bus_lock(dsi);
 	dsi_display_ulps_disable(dsi, true, false);
+	dsi_bus_unlock(dsi);
 }
 
 static int dsi_enable_te(struct dsi_data *dsi, bool enable)
@@ -4876,7 +4950,7 @@ static const struct omap_dss_device_ops dsi_ops = {
 		.enable_video_output = dsi_enable_video_output,
 		.disable_video_output = dsi_disable_video_output,
 
-		.update = dsi_update,
+		.update = dsi_update_all,
 	},
 };
 
@@ -4974,14 +5048,18 @@ int omap_dsi_host_attach(struct mipi_dsi_host *host,
 		return -EBUSY;
 	}
 
+	dsi_bus_lock(dsi);
+
 	atomic_set(&dsi->do_ext_te_update, 0);
 
 	if (client->mode_flags & MIPI_DSI_MODE_VIDEO) {
 		dsi->mode = OMAP_DSS_DSI_VIDEO_MODE;
 	} else {
 		r = omap_dsi_register_te_irq(dsi, client);
-		if (r)
+		if (r) {
+			dsi_bus_unlock(dsi);
 			return r;
+		}
 
 		dsi->mode = OMAP_DSS_DSI_CMD_MODE;
 	}
@@ -4995,6 +5073,7 @@ int omap_dsi_host_attach(struct mipi_dsi_host *host,
 	dsi->ulps_auto_idle = !!(client->mode_flags & MIPI_DSI_MODE_ULPS_IDLE);
 	dsi_set_ulps_auto(dsi, true);
 
+	dsi_bus_unlock(dsi);
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index 74cf0371b8bb..21601af29ee4 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -287,13 +287,12 @@ struct omapdss_hdmi_ops {
 };
 
 struct omapdss_dsi_ops {
-	/* bus configuration */
+	int (*update)(struct omap_dss_device *dssdev);
+
+	/* legacy API used by omapdss panels */
 	int (*set_config)(struct omap_dss_device *dssdev,
 			const struct omap_dss_dsi_config *cfg);
 
-	int (*update)(struct omap_dss_device *dssdev, int channel,
-			void (*callback)(int, void *), void *data);
-
 	int (*enable_video_output)(struct omap_dss_device *dssdev, int channel);
 	void (*disable_video_output)(struct omap_dss_device *dssdev,
 			int channel);
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 8b469eaa5005..a8d0543d1296 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -362,10 +362,8 @@ static void omap_crtc_manual_display_update(struct work_struct *data)
 {
 	struct omap_crtc *omap_crtc =
 			container_of(data, struct omap_crtc, update_work.work);
-	struct drm_display_mode *mode = &omap_crtc->pipe->crtc->mode;
-	struct omap_dss_device *dssdev = omap_crtc->pipe->output->next;
+	struct omap_dss_device *dssdev = omap_crtc->pipe->output;
 	struct drm_device *dev = omap_crtc->base.dev;
-	const struct omap_dss_driver *dssdrv;
 	int ret;
 
 	if (!dssdev) {
@@ -373,13 +371,12 @@ static void omap_crtc_manual_display_update(struct work_struct *data)
 		return;
 	}
 
-	dssdrv = dssdev->driver;
-	if (!dssdrv || !dssdrv->update) {
-		dev_err_once(dev->dev, "missing or incorrect dssdrv!");
+	if (dssdev->type != OMAP_DISPLAY_TYPE_DSI || !dssdev->ops->dsi.update) {
+		dev_err_once(dev->dev, "no DSI update callback found!");
 		return;
 	}
 
-	ret = dssdrv->update(dssdev, 0, 0, mode->hdisplay, mode->vdisplay);
+	ret = dssdev->ops->dsi.update(dssdev);
 	if (ret < 0) {
 		spin_lock_irq(&dev->event_lock);
 		omap_crtc->pending = false;
-- 
2.24.0

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

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

* [RFCv1 31/42] drm/omap: dsi: Reverse direction of the DSS device enable/disable operations
  2019-11-17  2:39 [RFCv1 00/42] drm/omap: Convert DSI code to use drm_mipi_dsi and drm_panel Sebastian Reichel
                   ` (30 preceding siblings ...)
  2019-11-17  2:40 ` [RFCv1 30/42] drm/omap: dsi: move panel refresh function to host Sebastian Reichel
@ 2019-11-17  2:40 ` Sebastian Reichel
  2019-11-17  2:40 ` [RFCv1 32/42] drm/omap: dsi: convert to drm_panel Sebastian Reichel
                   ` (10 subsequent siblings)
  42 siblings, 0 replies; 64+ messages in thread
From: Sebastian Reichel @ 2019-11-17  2:40 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Tomi Valkeinen
  Cc: kernel, Tony Lindgren, H. Nikolaus Schaller, Merlijn Wajer,
	Sebastian Reichel, dri-devel, linux-omap

Complete the direction reversal of the DSS device enable/disable
operations started by 19b4200d8f4b ("drm/omap: Reverse direction
of the DSS device enable/disable operations").

This effectively drops the requirement of calling DSS specific
code from the DSI panel driver moving it a bit further to a
standard drm_panel driver.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 .../gpu/drm/omapdrm/displays/panel-dsi-cm.c   | 75 ++++++++++---------
 drivers/gpu/drm/omapdrm/omap_encoder.c        | 20 ++---
 2 files changed, 44 insertions(+), 51 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
index 9bfc262f5c5a..18020ac43a83 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
@@ -288,27 +288,6 @@ static int dsicm_power_on(struct panel_drv_data *ddata)
 	struct omap_dss_device *src = ddata->src;
 	u8 id1, id2, id3;
 	int r;
-	struct omap_dss_dsi_config dsi_config = {
-		.vm = &ddata->vm,
-		.hs_clk_min = 150000000,
-		.hs_clk_max = 300000000,
-		.lp_clk_min = 7000000,
-		.lp_clk_max = 10000000,
-	};
-
-	r = regulator_bulk_enable(DCS_REGULATOR_SUPPLY_NUM, ddata->supplies);
-	if (r) {
-		dev_err(&ddata->dsi->dev, "failed to enable supplies: %d\n", r);
-		return r;
-	}
-
-	r = src->ops->dsi.set_config(src, &dsi_config);
-	if (r) {
-		dev_err(&ddata->dsi->dev, "failed to configure DSI\n");
-		goto err_regulators;
-	}
-
-	src->ops->enable(src);
 
 	dsicm_hw_reset(ddata);
 
@@ -363,12 +342,6 @@ static int dsicm_power_on(struct panel_drv_data *ddata)
 
 	dsicm_hw_reset(ddata);
 
-	src->ops->disable(src);
-err_regulators:
-	r = regulator_bulk_disable(DCS_REGULATOR_SUPPLY_NUM, ddata->supplies);
-	if (r)
-		dev_err(&ddata->dsi->dev, "failed to disable supplies: %d\n", r);
-
 	return r;
 }
 
@@ -377,6 +350,8 @@ static void dsicm_power_off(struct panel_drv_data *ddata)
 	struct omap_dss_device *src = ddata->src;
 	int r;
 
+	ddata->enabled = 0;
+
 	src->ops->dsi.disable_video_output(src, ddata->dsi->channel);
 
 	r = mipi_dsi_dcs_set_display_off(ddata->dsi);
@@ -388,14 +363,6 @@ static void dsicm_power_off(struct panel_drv_data *ddata)
 				"error disabling panel, issuing HW reset\n");
 		dsicm_hw_reset(ddata);
 	}
-
-	src->ops->disable(src);
-
-	r = regulator_bulk_disable(DCS_REGULATOR_SUPPLY_NUM, ddata->supplies);
-	if (r)
-		dev_err(&ddata->dsi->dev, "failed to disable supplies: %d\n", r);
-
-	ddata->enabled = 0;
 }
 
 static int dsicm_connect(struct omap_dss_device *src,
@@ -415,6 +382,30 @@ static void dsicm_disconnect(struct omap_dss_device *src,
 	ddata->src = NULL;
 }
 
+static void dsicm_pre_enable(struct omap_dss_device *dssdev)
+{
+	struct panel_drv_data *ddata = to_panel_data(dssdev);
+	struct omap_dss_device *src = ddata->src;
+	int r;
+	struct omap_dss_dsi_config dsi_config = {
+		.vm = &ddata->vm,
+		.hs_clk_min = 150000000,
+		.hs_clk_max = 300000000,
+		.lp_clk_min = 7000000,
+		.lp_clk_max = 10000000,
+	};
+
+	r = regulator_bulk_enable(DCS_REGULATOR_SUPPLY_NUM, ddata->supplies);
+	if (r) {
+		dev_err(&ddata->dsi->dev, "failed to enable supplies: %d\n", r);
+	}
+
+	r = src->ops->dsi.set_config(src, &dsi_config);
+	if (r) {
+		dev_err(&ddata->dsi->dev, "failed to configure DSI\n");
+	}
+}
+
 static void dsicm_enable(struct omap_dss_device *dssdev)
 {
 	struct panel_drv_data *ddata = to_panel_data(dssdev);
@@ -449,6 +440,16 @@ static void dsicm_disable(struct omap_dss_device *dssdev)
 	mutex_unlock(&ddata->lock);
 }
 
+static void dsicm_post_disable(struct omap_dss_device *dssdev)
+{
+	struct panel_drv_data *ddata = to_panel_data(dssdev);
+	int r;
+
+	r = regulator_bulk_disable(DCS_REGULATOR_SUPPLY_NUM, ddata->supplies);
+	if (r)
+		dev_err(&ddata->dsi->dev, "failed to disable supplies: %d\n", r);
+}
+
 static int _dsicm_enable_te(struct panel_drv_data *ddata, bool enable)
 {
 	struct mipi_dsi_device *dsi = ddata->dsi;
@@ -502,8 +503,10 @@ static const struct omap_dss_device_ops dsicm_ops = {
 	.connect	= dsicm_connect,
 	.disconnect	= dsicm_disconnect,
 
+	.pre_enable	= dsicm_pre_enable,
 	.enable		= dsicm_enable,
 	.disable	= dsicm_disable,
+	.post_disable	= dsicm_post_disable,
 
 	.get_modes	= dsicm_get_modes,
 	.check_timings	= dsicm_check_timings,
@@ -666,8 +669,6 @@ static int __exit dsicm_remove(struct mipi_dsi_device *dsi)
 
 	omapdss_device_unregister(dssdev);
 
-	if (omapdss_device_is_enabled(dssdev))
-		dsicm_disable(dssdev);
 	omapdss_device_disconnect(ddata->src, dssdev);
 
 	sysfs_remove_group(&dsi->dev.kobj, &dsicm_attr_group);
diff --git a/drivers/gpu/drm/omapdrm/omap_encoder.c b/drivers/gpu/drm/omapdrm/omap_encoder.c
index 24bbe9f2a32e..98f4df48a1f3 100644
--- a/drivers/gpu/drm/omapdrm/omap_encoder.c
+++ b/drivers/gpu/drm/omapdrm/omap_encoder.c
@@ -171,14 +171,10 @@ static void omap_encoder_disable(struct drm_encoder *encoder)
 	omapdss_device_disable(dssdev->next);
 
 	/*
-	 * Disable the internal encoder. This will disable the DSS output. The
-	 * DSI is treated as an exception as DSI pipelines still use the legacy
-	 * flow where the pipeline output controls the encoder.
+	 * Disable the internal encoder. This will disable the DSS output.
 	 */
-	if (dssdev->type != OMAP_DISPLAY_TYPE_DSI) {
-		dssdev->ops->disable(dssdev);
-		dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
-	}
+	dssdev->ops->disable(dssdev);
+	dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
 
 	/*
 	 * Perform the post-disable operations on the chain of external devices
@@ -199,14 +195,10 @@ static void omap_encoder_enable(struct drm_encoder *encoder)
 	omapdss_device_pre_enable(dssdev->next);
 
 	/*
-	 * Enable the internal encoder. This will enable the DSS output. The
-	 * DSI is treated as an exception as DSI pipelines still use the legacy
-	 * flow where the pipeline output controls the encoder.
+	 * Enable the internal encoder. This will enable the DSS output.
 	 */
-	if (dssdev->type != OMAP_DISPLAY_TYPE_DSI) {
-		dssdev->ops->enable(dssdev);
-		dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
-	}
+	dssdev->ops->enable(dssdev);
+	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
 
 	/*
 	 * Enable the chain of external devices, starting at the one at the
-- 
2.24.0

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

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

* [RFCv1 32/42] drm/omap: dsi: convert to drm_panel
  2019-11-17  2:39 [RFCv1 00/42] drm/omap: Convert DSI code to use drm_mipi_dsi and drm_panel Sebastian Reichel
                   ` (31 preceding siblings ...)
  2019-11-17  2:40 ` [RFCv1 31/42] drm/omap: dsi: Reverse direction of the DSS device enable/disable operations Sebastian Reichel
@ 2019-11-17  2:40 ` Sebastian Reichel
  2019-11-17 19:23   ` H. Nikolaus Schaller
  2019-11-17  2:40 ` [RFCv1 33/42] drm/omap: dsi: use atomic helper for dirtyfb Sebastian Reichel
                   ` (9 subsequent siblings)
  42 siblings, 1 reply; 64+ messages in thread
From: Sebastian Reichel @ 2019-11-17  2:40 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Tomi Valkeinen
  Cc: kernel, Tony Lindgren, H. Nikolaus Schaller, Merlijn Wajer,
	Sebastian Reichel, dri-devel, linux-omap

This converts the DSI module to expect common drm_panel display
drivers instead of dssdev based ones.

This commit is WIP. We somehow need to know the panels resolution
in omap_dsi_host_attach(), so that we can properly configure the
DSI bus clock before enabling the bus. The control bus must be
enabled at this point, so that the panel can use it.

Other drivers run drm_panel_attach() in their dsi host attach,
which makes it possible to call drm_panel_get_modes() afterwards
and the get the correct mode from the connector.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 .../gpu/drm/omapdrm/displays/panel-dsi-cm.c   | 217 +++++++-----------
 drivers/gpu/drm/omapdrm/dss/dsi.c             | 141 ++++++++++--
 .../gpu/drm/omapdrm/dss/omapdss-boot-init.c   |   1 -
 drivers/gpu/drm/omapdrm/dss/omapdss.h         |  22 +-
 drivers/gpu/drm/omapdrm/omap_crtc.c           |  17 +-
 5 files changed, 205 insertions(+), 193 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
index 18020ac43a83..84b0e79c025e 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
@@ -6,8 +6,6 @@
  * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
  */
 
-/* #define DEBUG */
-
 #include <linux/backlight.h>
 #include <linux/delay.h>
 #include <linux/gpio/consumer.h>
@@ -20,11 +18,14 @@
 #include <linux/regulator/consumer.h>
 
 #include <drm/drm_connector.h>
+#include <drm/drm_mipi_dsi.h>
+#include <drm/drm_panel.h>
+#include <drm/drm_modes.h>
 
+#include <video/display_timing.h>
 #include <video/mipi_display.h>
 #include <video/of_display_timing.h>
-
-#include "../dss/omapdss.h"
+#include <video/videomode.h>
 
 #define DCS_READ_NUM_ERRORS	0x05
 #define DCS_GET_ID1		0xda
@@ -35,11 +36,8 @@
 
 struct panel_drv_data {
 	struct mipi_dsi_device *dsi;
-
-	struct omap_dss_device dssdev;
-	struct omap_dss_device *src;
-
-	struct videomode vm;
+	struct drm_panel panel;
+	struct drm_display_mode mode;
 
 	struct mutex lock;
 
@@ -71,7 +69,11 @@ struct panel_drv_data {
 	bool ulps_enabled;
 };
 
-#define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev)
+
+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);
 
@@ -285,10 +287,15 @@ static void dsicm_hw_reset(struct panel_drv_data *ddata)
 
 static int dsicm_power_on(struct panel_drv_data *ddata)
 {
-	struct omap_dss_device *src = ddata->src;
 	u8 id1, id2, id3;
 	int r;
 
+	r = regulator_bulk_enable(DCS_REGULATOR_SUPPLY_NUM, ddata->supplies);
+	if (r) {
+		dev_err(&ddata->dsi->dev, "failed to enable supplies: %d\n", r);
+		return r;
+	}
+
 	dsicm_hw_reset(ddata);
 
 	ddata->dsi->mode_flags |= MIPI_DSI_MODE_LPM;
@@ -322,10 +329,6 @@ static int dsicm_power_on(struct panel_drv_data *ddata)
 	if (r)
 		goto err;
 
-	r = src->ops->dsi.enable_video_output(src, ddata->dsi->channel);
-	if (r)
-		goto err;
-
 	ddata->enabled = 1;
 
 	if (!ddata->intro_printed) {
@@ -342,18 +345,17 @@ static int dsicm_power_on(struct panel_drv_data *ddata)
 
 	dsicm_hw_reset(ddata);
 
+	regulator_bulk_disable(DCS_REGULATOR_SUPPLY_NUM, ddata->supplies);
+
 	return r;
 }
 
-static void dsicm_power_off(struct panel_drv_data *ddata)
+static int dsicm_power_off(struct panel_drv_data *ddata)
 {
-	struct omap_dss_device *src = ddata->src;
 	int r;
 
 	ddata->enabled = 0;
 
-	src->ops->dsi.disable_video_output(src, ddata->dsi->channel);
-
 	r = mipi_dsi_dcs_set_display_off(ddata->dsi);
 	if (!r)
 		r = dsicm_sleep_in(ddata);
@@ -363,52 +365,17 @@ static void dsicm_power_off(struct panel_drv_data *ddata)
 				"error disabling panel, issuing HW reset\n");
 		dsicm_hw_reset(ddata);
 	}
-}
 
-static int dsicm_connect(struct omap_dss_device *src,
-			 struct omap_dss_device *dst)
-{
-	struct panel_drv_data *ddata = to_panel_data(dst);
-
-	ddata->src = src;
-	return 0;
-}
-
-static void dsicm_disconnect(struct omap_dss_device *src,
-			     struct omap_dss_device *dst)
-{
-	struct panel_drv_data *ddata = to_panel_data(dst);
-
-	ddata->src = NULL;
-}
-
-static void dsicm_pre_enable(struct omap_dss_device *dssdev)
-{
-	struct panel_drv_data *ddata = to_panel_data(dssdev);
-	struct omap_dss_device *src = ddata->src;
-	int r;
-	struct omap_dss_dsi_config dsi_config = {
-		.vm = &ddata->vm,
-		.hs_clk_min = 150000000,
-		.hs_clk_max = 300000000,
-		.lp_clk_min = 7000000,
-		.lp_clk_max = 10000000,
-	};
-
-	r = regulator_bulk_enable(DCS_REGULATOR_SUPPLY_NUM, ddata->supplies);
-	if (r) {
-		dev_err(&ddata->dsi->dev, "failed to enable supplies: %d\n", r);
-	}
+	r = regulator_bulk_disable(DCS_REGULATOR_SUPPLY_NUM, ddata->supplies);
+	if (r)
+		dev_err(&ddata->dsi->dev, "failed to disable supplies: %d\n", r);
 
-	r = src->ops->dsi.set_config(src, &dsi_config);
-	if (r) {
-		dev_err(&ddata->dsi->dev, "failed to configure DSI\n");
-	}
+	return r;
 }
 
-static void dsicm_enable(struct omap_dss_device *dssdev)
+static int dsicm_prepare(struct drm_panel *panel)
 {
-	struct panel_drv_data *ddata = to_panel_data(dssdev);
+	struct panel_drv_data *ddata = panel_to_ddata(panel);
 	int r;
 
 	mutex_lock(&ddata->lock);
@@ -421,33 +388,27 @@ static void dsicm_enable(struct omap_dss_device *dssdev)
 
 	dsicm_bl_power(ddata, true);
 
-	return;
+	return 0;
 err:
-	dev_dbg(&ddata->dsi->dev, "enable failed (%d)\n", r);
+	dev_err(&ddata->dsi->dev, "enable failed (%d)\n", r);
 	mutex_unlock(&ddata->lock);
+	return r;
 }
 
-static void dsicm_disable(struct omap_dss_device *dssdev)
+static int dsicm_unprepare(struct drm_panel *panel)
 {
-	struct panel_drv_data *ddata = to_panel_data(dssdev);
+	struct panel_drv_data *ddata = panel_to_ddata(panel);
+	int r;
 
 	dsicm_bl_power(ddata, false);
 
 	mutex_lock(&ddata->lock);
 
-	dsicm_power_off(ddata);
+	r = dsicm_power_off(ddata);
 
 	mutex_unlock(&ddata->lock);
-}
-
-static void dsicm_post_disable(struct omap_dss_device *dssdev)
-{
-	struct panel_drv_data *ddata = to_panel_data(dssdev);
-	int r;
 
-	r = regulator_bulk_disable(DCS_REGULATOR_SUPPLY_NUM, ddata->supplies);
-	if (r)
-		dev_err(&ddata->dsi->dev, "failed to disable supplies: %d\n", r);
+	return r;
 }
 
 static int _dsicm_enable_te(struct panel_drv_data *ddata, bool enable)
@@ -466,50 +427,35 @@ static int _dsicm_enable_te(struct panel_drv_data *ddata, bool enable)
 	return r;
 }
 
-static int dsicm_get_modes(struct omap_dss_device *dssdev,
-			   struct drm_connector *connector)
+static int dsicm_get_modes(struct drm_panel *panel)
 {
-	struct panel_drv_data *ddata = to_panel_data(dssdev);
-
-	connector->display_info.width_mm = ddata->width_mm;
-	connector->display_info.height_mm = ddata->height_mm;
-
-	return omapdss_display_get_modes(connector, &ddata->vm);
-}
-
-static int dsicm_check_timings(struct omap_dss_device *dssdev,
-			       struct drm_display_mode *mode)
-{
-	struct panel_drv_data *ddata = to_panel_data(dssdev);
-	int ret = 0;
+	struct panel_drv_data *ddata = panel_to_ddata(panel);
+	struct drm_connector *connector = panel->connector;
+	struct drm_display_mode *mode;
+
+	mode = drm_mode_duplicate(panel->drm, &ddata->mode);
+	if (!mode) {
+		dev_err(&ddata->dsi->dev, "failed to add mode %ux%ux@%u\n",
+			ddata->mode.hdisplay, ddata->mode.vdisplay,
+			ddata->mode.vrefresh);
+		return -ENOMEM;
+	}
 
-	if (mode->hdisplay != ddata->vm.hactive)
-		ret = -EINVAL;
+	drm_mode_set_name(mode);
 
-	if (mode->vdisplay != ddata->vm.vactive)
-		ret = -EINVAL;
+	mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
+	drm_mode_probed_add(connector, mode);
 
-	if (ret) {
-		dev_warn(dssdev->dev, "wrong resolution: %d x %d",
-			 mode->hdisplay, mode->vdisplay);
-		dev_warn(dssdev->dev, "panel resolution: %d x %d",
-			 ddata->vm.hactive, ddata->vm.vactive);
-	}
+	connector->display_info.width_mm = ddata->width_mm;
+	connector->display_info.height_mm = ddata->height_mm;
 
-	return ret;
+	return 1;
 }
 
-static const struct omap_dss_device_ops dsicm_ops = {
-	.connect	= dsicm_connect,
-	.disconnect	= dsicm_disconnect,
-
-	.pre_enable	= dsicm_pre_enable,
-	.enable		= dsicm_enable,
-	.disable	= dsicm_disable,
-	.post_disable	= dsicm_post_disable,
-
-	.get_modes	= dsicm_get_modes,
-	.check_timings	= dsicm_check_timings,
+static const struct drm_panel_funcs dsicm_panel_funcs = {
+	.unprepare = dsicm_unprepare,
+	.prepare = dsicm_prepare,
+	.get_modes = dsicm_get_modes,
 };
 
 static int dsicm_probe_of(struct mipi_dsi_device *dsi)
@@ -518,8 +464,12 @@ static int dsicm_probe_of(struct mipi_dsi_device *dsi)
 	struct device_node *backlight;
 	struct panel_drv_data *ddata = mipi_dsi_get_drvdata(dsi);
 	struct display_timing timing;
+	struct videomode vm;
 	int err;
 
+	vm.hactive = 864;
+	vm.vactive = 480;
+
 	ddata->reset_gpio = devm_gpiod_get(&dsi->dev, "reset", GPIOD_OUT_LOW);
 	if (IS_ERR(ddata->reset_gpio)) {
 		err = PTR_ERR(ddata->reset_gpio);
@@ -529,15 +479,16 @@ static int dsicm_probe_of(struct mipi_dsi_device *dsi)
 
 	err = of_get_display_timing(node, "panel-timing", &timing);
 	if (!err) {
-		videomode_from_timing(&timing, &ddata->vm);
-		if (!ddata->vm.pixelclock)
-			ddata->vm.pixelclock =
-				ddata->vm.hactive * ddata->vm.vactive * 60;
+		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);
 
@@ -573,7 +524,6 @@ static int dsicm_probe(struct mipi_dsi_device *dsi)
 	struct panel_drv_data *ddata;
 	struct backlight_device *bldev = NULL;
 	struct device *dev = &dsi->dev;
-	struct omap_dss_device *dssdev;
 	int r;
 
 	dev_dbg(dev, "probe\n");
@@ -585,33 +535,17 @@ static int dsicm_probe(struct mipi_dsi_device *dsi)
 	mipi_dsi_set_drvdata(dsi, ddata);
 	ddata->dsi = dsi;
 
-	ddata->vm.hactive = 864;
-	ddata->vm.vactive = 480;
-	ddata->vm.pixelclock = 864 * 480 * 60;
-
 	r = dsicm_probe_of(dsi);
 	if (r)
 		return r;
 
-	dssdev = &ddata->dssdev;
-	dssdev->dev = dev;
-	dssdev->ops = &dsicm_ops;
-	dssdev->type = OMAP_DISPLAY_TYPE_DSI;
-	dssdev->display = true;
-	dssdev->owner = THIS_MODULE;
-	dssdev->of_ports = BIT(0);
-	dssdev->ops_flags = OMAP_DSS_DEVICE_OP_MODES;
-
-	dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE |
-		OMAP_DSS_DISPLAY_CAP_TEAR_ELIM;
-
-	omapdss_display_init(dssdev);
-	omapdss_device_register(dssdev);
-
 	mutex_init(&ddata->lock);
 
 	dsicm_hw_reset(ddata);
 
+	drm_panel_init(&ddata->panel, dev, &dsicm_panel_funcs,
+		       DRM_MODE_CONNECTOR_DSI);
+
 	if (ddata->use_dsi_backlight) {
 		struct backlight_properties props = { 0 };
 		props.max_brightness = 255;
@@ -643,6 +577,10 @@ static int dsicm_probe(struct mipi_dsi_device *dsi)
 	if (ddata->ulps_enabled)
 		dsi->mode_flags |= MIPI_DSI_MODE_ULPS_IDLE;
 
+	r = drm_panel_add(&ddata->panel);
+	if (r < 0)
+		goto err_panel_add;
+
 	r = mipi_dsi_attach(dsi);
 	if (r < 0)
 		goto err_dsi_attach;
@@ -650,6 +588,8 @@ static int dsicm_probe(struct mipi_dsi_device *dsi)
 	return 0;
 
 err_dsi_attach:
+	drm_panel_remove(&ddata->panel);
+err_panel_add:
 	sysfs_remove_group(&dsi->dev.kobj, &dsicm_attr_group);
 err_bl:
 	if (ddata->extbldev)
@@ -661,15 +601,12 @@ static int dsicm_probe(struct mipi_dsi_device *dsi)
 static int __exit dsicm_remove(struct mipi_dsi_device *dsi)
 {
 	struct panel_drv_data *ddata = mipi_dsi_get_drvdata(dsi);
-	struct omap_dss_device *dssdev = &ddata->dssdev;
 
 	dev_dbg(&dsi->dev, "remove\n");
 
 	mipi_dsi_detach(dsi);
 
-	omapdss_device_unregister(dssdev);
-
-	omapdss_device_disconnect(ddata->src, dssdev);
+	drm_panel_remove(&ddata->panel);
 
 	sysfs_remove_group(&dsi->dev.kobj, &dsicm_attr_group);
 
@@ -683,7 +620,7 @@ static int __exit dsicm_remove(struct mipi_dsi_device *dsi)
 }
 
 static const struct of_device_id dsicm_of_match[] = {
-	{ .compatible = "omapdss,panel-dsi-cm", },
+	{ .compatible = "panel-dsi-cm", },
 	{},
 };
 
diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index 66ad7dbc66a2..754815068927 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -37,6 +37,7 @@
 
 #include <video/mipi_display.h>
 #include <drm/drm_mipi_dsi.h>
+#include <drm/drm_panel.h>
 
 #include "omapdss.h"
 #include "dss.h"
@@ -220,6 +221,8 @@ static int dsi_vc_send_null(struct dsi_data *dsi, int channel);
 static ssize_t _omap_dsi_host_transfer(struct dsi_data *dsi,
 				       const struct mipi_dsi_msg *msg);
 
+static void dsi_display_disable(struct omap_dss_device *dssdev);
+
 /* DSI PLL HSDIV indices */
 #define HSDIV_DISPC	0
 #define HSDIV_DSI	1
@@ -386,6 +389,7 @@ struct dsi_data {
 	bool te_enabled;
 	bool ulps_enabled;
 	bool ulps_auto_idle;
+	bool video_enabled;
 
 	struct delayed_work ulps_work;
 
@@ -426,6 +430,8 @@ struct dsi_data {
 
 	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;
@@ -3629,7 +3635,7 @@ static int dsi_configure_pins(struct omap_dss_device *dssdev,
 	return 0;
 }
 
-static int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
+static void dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
 {
 	struct dsi_data *dsi = to_dsi_data(dssdev);
 	int bpp = mipi_dsi_pixel_format_to_bpp(dsi->pix_fmt);
@@ -3638,8 +3644,10 @@ static int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
 	int r;
 
 	r = dsi_display_init_dispc(dsi);
-	if (r)
-		return r;
+	if (r) {
+		dev_err(dsi->dev, "failed to init dispc!\n");
+		return;
+	}
 
 	if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) {
 		switch (dsi->pix_fmt) {
@@ -3679,7 +3687,7 @@ static int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
 	if (r)
 		goto err_mgr_enable;
 
-	return 0;
+	return;
 
 err_mgr_enable:
 	if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) {
@@ -3688,7 +3696,8 @@ static int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
 	}
 err_pix_fmt:
 	dsi_display_uninit_dispc(dsi);
-	return r;
+	dev_err(dsi->dev, "failed to enable DSI encoder!\n");
+	return;
 }
 
 static void dsi_disable_video_output(struct omap_dss_device *dssdev, int channel)
@@ -3711,6 +3720,25 @@ static void dsi_disable_video_output(struct omap_dss_device *dssdev, int channel
 	dsi_display_uninit_dispc(dsi);
 }
 
+static void dsi_disable_video_outputs(struct omap_dss_device *dssdev)
+{
+	struct dsi_data *dsi = to_dsi_data(dssdev);
+	int i;
+
+	dsi_bus_lock(dsi);
+	dsi->video_enabled = false;
+
+	for (i = 0; i < 3; i++) {
+		if (!dsi->vc[i].dest)
+			continue;
+		dsi_disable_video_output(dssdev, i);
+	}
+
+	dsi_display_disable(dssdev);
+
+	dsi_bus_unlock(dsi);
+}
+
 static void dsi_update_screen_dispc(struct dsi_data *dsi)
 {
 	unsigned int bytespp;
@@ -3904,6 +3932,11 @@ static int dsi_update_channel(struct omap_dss_device *dssdev, int channel)
 
 	dsi_bus_lock(dsi);
 
+	if (!dsi->video_enabled) {
+		r = -EIO;
+		goto err;
+	}
+
 	if (!dsi->vc[channel].dest) {
 		r = -ENODEV;
 		goto err;
@@ -3949,7 +3982,7 @@ static int dsi_update_all(struct omap_dss_device *dssdev)
 
 	for (i = 0; i < 4; i++) {
 		r = dsi_update_channel(dssdev, i);
-		if (r != -ENODEV)
+		if (r && r != -ENODEV)
 			return r;
 	}
 
@@ -4172,8 +4205,30 @@ static void dsi_display_enable(struct omap_dss_device *dssdev)
 {
 	struct dsi_data *dsi = to_dsi_data(dssdev);
 	DSSDBG("dsi_display_enable\n");
-	dsi_bus_lock(dsi);
+	WARN_ON(!dsi_bus_is_locked(dsi));
+
 	dsi_display_ulps_enable(dsi);
+}
+
+static void dsi_enable_video_outputs(struct omap_dss_device *dssdev)
+{
+	struct dsi_data *dsi = to_dsi_data(dssdev);
+	int i;
+
+	dsi_bus_lock(dsi);
+
+	dsi_display_enable(dssdev);
+
+	for (i = 0; i < 3; i++) {
+		if (!dsi->vc[i].dest)
+			continue;
+		dsi_enable_video_output(dssdev, i);
+	}
+
+	dsi->video_enabled = true;
+
+	dsi_set_ulps_auto(dsi, true);
+
 	dsi_bus_unlock(dsi);
 }
 
@@ -4199,10 +4254,10 @@ static void dsi_display_ulps_disable(struct dsi_data *dsi,
 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_bus_lock(dsi);
+
 	dsi_display_ulps_disable(dsi, true, false);
-	dsi_bus_unlock(dsi);
 }
 
 static int dsi_enable_te(struct dsi_data *dsi, bool enable)
@@ -4732,15 +4787,26 @@ static bool dsi_vm_calc(struct dsi_data *dsi,
 			dsi_vm_calc_pll_cb, ctx);
 }
 
+static bool dsi_is_video_mode(struct omap_dss_device *dssdev)
+{
+	struct dsi_data *dsi = to_dsi_data(dssdev);
+
+	return (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE);
+}
+
 static int dsi_set_config(struct omap_dss_device *dssdev,
-		const struct omap_dss_dsi_config *config)
+		const struct drm_display_mode *mode)
 {
 	struct dsi_data *dsi = to_dsi_data(dssdev);
 	struct dsi_clk_calc_ctx ctx;
-	struct omap_dss_dsi_config cfg = *config;
+	struct videomode vm;
+	struct omap_dss_dsi_config cfg = dsi->config;
 	bool ok;
 	int r;
 
+	drm_display_mode_to_videomode(mode, &vm);
+	cfg.vm = &vm;
+
 	mutex_lock(&dsi->lock);
 
 	cfg.mode = dsi->mode;
@@ -4903,9 +4969,15 @@ static ssize_t omap_dsi_host_transfer(struct mipi_dsi_host *host,
 	int r;
 
 	dsi_bus_lock(dsi);
-	dsi_set_ulps_auto(dsi, false);
-	r = _omap_dsi_host_transfer(dsi, msg);
-	dsi_set_ulps_auto(dsi, true);
+
+	if (dsi->video_enabled) {
+		dsi_set_ulps_auto(dsi, false);
+		r = _omap_dsi_host_transfer(dsi, msg);
+		dsi_set_ulps_auto(dsi, true);
+	} else {
+		r = -EIO;
+	}
+
 	dsi_bus_unlock(dsi);
 
 	return r;
@@ -4926,6 +4998,23 @@ static int dsi_get_clocks(struct dsi_data *dsi)
 	return 0;
 }
 
+static void dsi_set_timings(struct omap_dss_device *dssdev,
+			    const struct drm_display_mode *mode)
+{
+	DSSDBG("dsi_set_timings\n");
+	dsi_set_config(dssdev, mode);
+}
+
+static int dsi_check_timings(struct omap_dss_device *dssdev,
+			     struct drm_display_mode *mode)
+{
+	DSSDBG("dsi_check_timings\n");
+
+	/* TODO */
+
+	return 0;
+}
+
 static int dsi_connect(struct omap_dss_device *src,
 		       struct omap_dss_device *dst)
 {
@@ -4941,16 +5030,15 @@ static void dsi_disconnect(struct omap_dss_device *src,
 static const struct omap_dss_device_ops dsi_ops = {
 	.connect = dsi_connect,
 	.disconnect = dsi_disconnect,
-	.enable = dsi_display_enable,
-	.disable = dsi_display_disable,
-
-	.dsi = {
-		.set_config = dsi_set_config,
+	.enable = dsi_enable_video_outputs,
+	.disable = dsi_disable_video_outputs,
 
-		.enable_video_output = dsi_enable_video_output,
-		.disable_video_output = dsi_disable_video_output,
+	.check_timings = dsi_check_timings,
+	.set_timings = dsi_set_timings,
 
+	.dsi = {
 		.update = dsi_update_all,
+		.is_video_mode = dsi_is_video_mode,
 	},
 };
 
@@ -5038,6 +5126,7 @@ int omap_dsi_host_attach(struct mipi_dsi_host *host,
 {
 	struct dsi_data *dsi = host_to_omap(host);
 	unsigned int channel = client->channel;
+	struct drm_panel *panel;
 	int r;
 
 	if (channel > 3)
@@ -5050,6 +5139,10 @@ int omap_dsi_host_attach(struct mipi_dsi_host *host,
 
 	dsi_bus_lock(dsi);
 
+	panel = of_drm_find_panel(client->dev.of_node);
+	if (IS_ERR(panel))
+		return PTR_ERR(panel);
+
 	atomic_set(&dsi->do_ext_te_update, 0);
 
 	if (client->mode_flags & MIPI_DSI_MODE_VIDEO) {
@@ -5070,8 +5163,12 @@ int omap_dsi_host_attach(struct mipi_dsi_host *host,
 	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?
+	dsi->config.lp_clk_max = client->lp_rate;
+
 	dsi->ulps_auto_idle = !!(client->mode_flags & MIPI_DSI_MODE_ULPS_IDLE);
-	dsi_set_ulps_auto(dsi, true);
 
 	dsi_bus_unlock(dsi);
 	return 0;
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss-boot-init.c b/drivers/gpu/drm/omapdrm/dss/omapdss-boot-init.c
index 31502857f013..05ac2e1cd77e 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss-boot-init.c
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss-boot-init.c
@@ -176,7 +176,6 @@ static const struct of_device_id omapdss_of_match[] __initconst = {
 static const struct of_device_id omapdss_of_fixups_whitelist[] __initconst = {
 	{ .compatible = "composite-video-connector" },
 	{ .compatible = "hdmi-connector" },
-	{ .compatible = "panel-dsi-cm" },
 	{ .compatible = "svideo-connector" },
 	{ .compatible = "ti,opa362" },
 	{ .compatible = "ti,tpd12s015" },
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index 21601af29ee4..bfb402a88475 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -122,11 +122,6 @@ enum omap_dss_dsi_mode {
 	OMAP_DSS_DSI_VIDEO_MODE,
 };
 
-enum omap_display_caps {
-	OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE	= 1 << 0,
-	OMAP_DSS_DISPLAY_CAP_TEAR_ELIM		= 1 << 1,
-};
-
 enum omap_dss_display_state {
 	OMAP_DSS_DISPLAY_DISABLED = 0,
 	OMAP_DSS_DISPLAY_ACTIVE,
@@ -288,14 +283,7 @@ struct omapdss_hdmi_ops {
 
 struct omapdss_dsi_ops {
 	int (*update)(struct omap_dss_device *dssdev);
-
-	/* legacy API used by omapdss panels */
-	int (*set_config)(struct omap_dss_device *dssdev,
-			const struct omap_dss_dsi_config *cfg);
-
-	int (*enable_video_output)(struct omap_dss_device *dssdev, int channel);
-	void (*disable_video_output)(struct omap_dss_device *dssdev,
-			int channel);
+	bool (*is_video_mode)(struct omap_dss_device *dssdev);
 };
 
 struct omap_dss_device_ops {
@@ -374,13 +362,10 @@ struct omap_dss_device {
 
 	const char *name;
 
-	const struct omap_dss_driver *driver;
 	const struct omap_dss_device_ops *ops;
 	unsigned long ops_flags;
 	u32 bus_flags;
 
-	enum omap_display_caps caps;
-
 	enum omap_dss_display_state state;
 
 	/* OMAP DSS output specific fields */
@@ -395,11 +380,6 @@ struct omap_dss_device {
 	unsigned int of_ports;
 };
 
-struct omap_dss_driver {
-	int (*update)(struct omap_dss_device *dssdev,
-			       u16 x, u16 y, u16 w, u16 h);
-};
-
 struct dss_device *omapdss_get_dss(void);
 void omapdss_set_dss(struct dss_device *dss);
 static inline bool omapdss_is_initialized(void)
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c
index a8d0543d1296..80ed1b15ba49 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -495,8 +495,7 @@ static enum drm_mode_status omap_crtc_mode_valid(struct drm_crtc *crtc,
 	 * valid DISPC mode. DSI will calculate and configure the
 	 * proper DISPC mode later.
 	 */
-	if (omap_crtc->pipe->output->next == NULL ||
-	    omap_crtc->pipe->output->next->type != OMAP_DISPLAY_TYPE_DSI) {
+	if (omap_crtc->pipe->output->type != OMAP_DISPLAY_TYPE_DSI) {
 		r = priv->dispc_ops->mgr_check_timings(priv->dispc,
 						       omap_crtc->channel,
 						       &vm);
@@ -548,17 +547,17 @@ static void omap_crtc_mode_set_nofb(struct drm_crtc *crtc)
 static bool omap_crtc_is_manually_updated(struct drm_crtc *crtc)
 {
 	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
-	struct omap_dss_device *display = omap_crtc->pipe->output->next;
+	struct omap_dss_device *dssdev = omap_crtc->pipe->output;
 
-	if (!display)
+	if (dssdev->type != OMAP_DISPLAY_TYPE_DSI ||
+	    !dssdev->ops->dsi.is_video_mode)
 		return false;
 
-	if (display->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
-		DBG("detected manually updated display!");
-		return true;
-	}
+	if (dssdev->ops->dsi.is_video_mode(dssdev))
+		return false;
 
-	return false;
+	DBG("detected manually updated display!");
+	return true;
 }
 
 static int omap_crtc_atomic_check(struct drm_crtc *crtc,
-- 
2.24.0

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

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

* [RFCv1 33/42] drm/omap: dsi: use atomic helper for dirtyfb
  2019-11-17  2:39 [RFCv1 00/42] drm/omap: Convert DSI code to use drm_mipi_dsi and drm_panel Sebastian Reichel
                   ` (32 preceding siblings ...)
  2019-11-17  2:40 ` [RFCv1 32/42] drm/omap: dsi: convert to drm_panel Sebastian Reichel
@ 2019-11-17  2:40 ` Sebastian Reichel
  2019-11-18 23:05   ` Tony Lindgren
  2019-11-17  2:40 ` [RFCv1 34/42] drm/omap: dsi: implement check timings Sebastian Reichel
                   ` (8 subsequent siblings)
  42 siblings, 1 reply; 64+ messages in thread
From: Sebastian Reichel @ 2019-11-17  2:40 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Tomi Valkeinen
  Cc: kernel, Tony Lindgren, H. Nikolaus Schaller, Merlijn Wajer,
	Sebastian Reichel, dri-devel, linux-omap

We can simply use the atomic helper for
handling the dirtyfb callback.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 drivers/gpu/drm/omapdrm/omap_crtc.c |  6 +-----
 drivers/gpu/drm/omapdrm/omap_crtc.h |  1 -
 drivers/gpu/drm/omapdrm/omap_fb.c   | 21 ++-------------------
 3 files changed, 3 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 80ed1b15ba49..2129cba7f4e2 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -346,13 +346,9 @@ void omap_crtc_framedone_irq(struct drm_crtc *crtc, uint32_t irqstatus)
 	wake_up(&omap_crtc->pending_wait);
 }
 
-void omap_crtc_flush(struct drm_crtc *crtc)
+static void omap_crtc_flush(struct drm_crtc *crtc)
 {
 	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
-	struct omap_crtc_state *omap_state = to_omap_crtc_state(crtc->state);
-
-	if (!omap_state->manually_updated)
-		return;
 
 	if (!delayed_work_pending(&omap_crtc->update_work))
 		schedule_delayed_work(&omap_crtc->update_work, 0);
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.h b/drivers/gpu/drm/omapdrm/omap_crtc.h
index 2fd57751ae2b..fe88f78f9711 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.h
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.h
@@ -31,6 +31,5 @@ int omap_crtc_wait_pending(struct drm_crtc *crtc);
 void omap_crtc_error_irq(struct drm_crtc *crtc, u32 irqstatus);
 void omap_crtc_vblank_irq(struct drm_crtc *crtc);
 void omap_crtc_framedone_irq(struct drm_crtc *crtc, uint32_t irqstatus);
-void omap_crtc_flush(struct drm_crtc *crtc);
 
 #endif /* __OMAPDRM_CRTC_H__ */
diff --git a/drivers/gpu/drm/omapdrm/omap_fb.c b/drivers/gpu/drm/omapdrm/omap_fb.c
index 9aeab81dfb90..b0e972945252 100644
--- a/drivers/gpu/drm/omapdrm/omap_fb.c
+++ b/drivers/gpu/drm/omapdrm/omap_fb.c
@@ -9,6 +9,7 @@
 #include <drm/drm_modeset_helper.h>
 #include <drm/drm_fourcc.h>
 #include <drm/drm_gem_framebuffer_helper.h>
+#include <drm/drm_damage_helper.h>
 
 #include "omap_dmm_tiler.h"
 #include "omap_drv.h"
@@ -55,28 +56,10 @@ struct omap_framebuffer {
 	struct mutex lock;
 };
 
-static int omap_framebuffer_dirty(struct drm_framebuffer *fb,
-				  struct drm_file *file_priv,
-				  unsigned flags, unsigned color,
-				  struct drm_clip_rect *clips,
-				  unsigned num_clips)
-{
-	struct drm_crtc *crtc;
-
-	drm_modeset_lock_all(fb->dev);
-
-	drm_for_each_crtc(crtc, fb->dev)
-		omap_crtc_flush(crtc);
-
-	drm_modeset_unlock_all(fb->dev);
-
-	return 0;
-}
-
 static const struct drm_framebuffer_funcs omap_framebuffer_funcs = {
 	.create_handle = drm_gem_fb_create_handle,
-	.dirty = omap_framebuffer_dirty,
 	.destroy = drm_gem_fb_destroy,
+	.dirty = drm_atomic_helper_dirtyfb,
 };
 
 static u32 get_linear_addr(struct drm_framebuffer *fb,
-- 
2.24.0

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

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

* [RFCv1 34/42] drm/omap: dsi: implement check timings
  2019-11-17  2:39 [RFCv1 00/42] drm/omap: Convert DSI code to use drm_mipi_dsi and drm_panel Sebastian Reichel
                   ` (33 preceding siblings ...)
  2019-11-17  2:40 ` [RFCv1 33/42] drm/omap: dsi: use atomic helper for dirtyfb Sebastian Reichel
@ 2019-11-17  2:40 ` Sebastian Reichel
  2019-11-17  2:40 ` [RFCv1 35/42] drm/omap: panel-dsi-cm: use DEVICE_ATTR_RO Sebastian Reichel
                   ` (7 subsequent siblings)
  42 siblings, 0 replies; 64+ messages in thread
From: Sebastian Reichel @ 2019-11-17  2:40 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Tomi Valkeinen
  Cc: kernel, Tony Lindgren, H. Nikolaus Schaller, Merlijn Wajer,
	Sebastian Reichel, dri-devel, linux-omap

Implement check timings, which will check if its possible to
configure the clocks for the provided mode using the same code
as the set_config() hook.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 drivers/gpu/drm/omapdrm/dss/dsi.c | 70 +++++++++++++++++++------------
 1 file changed, 44 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index 754815068927..1b57f516618a 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -283,6 +283,11 @@ struct dsi_isr_tables {
 	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;
@@ -297,16 +302,12 @@ struct dsi_clk_calc_ctx {
 
 	struct dss_pll_clock_info dsi_cinfo;
 	struct dispc_clock_info dispc_cinfo;
+	struct dsi_lp_clock_info user_lp_cinfo;
 
 	struct videomode vm;
 	struct omap_dss_dsi_videomode_timings dsi_vm;
 };
 
-struct dsi_lp_clock_info {
-	unsigned long lp_clk;
-	u16 lp_clk_div;
-};
-
 struct dsi_module_id_data {
 	u32 address;
 	int id;
@@ -4794,44 +4795,55 @@ static bool dsi_is_video_mode(struct omap_dss_device *dssdev)
 	return (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE);
 }
 
-static int dsi_set_config(struct omap_dss_device *dssdev,
-		const struct drm_display_mode *mode)
+static int __dsi_calc_config(struct dsi_data *dsi,
+		const struct drm_display_mode *mode,
+		struct dsi_clk_calc_ctx *ctx)
 {
-	struct dsi_data *dsi = to_dsi_data(dssdev);
-	struct dsi_clk_calc_ctx ctx;
-	struct videomode vm;
 	struct omap_dss_dsi_config cfg = dsi->config;
+	struct videomode vm;
 	bool ok;
 	int r;
 
 	drm_display_mode_to_videomode(mode, &vm);
-	cfg.vm = &vm;
-
-	mutex_lock(&dsi->lock);
 
+	cfg.vm = &vm;
 	cfg.mode = dsi->mode;
 	cfg.pixel_format = dsi->pix_fmt;
 
 	if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE)
-		ok = dsi_vm_calc(dsi, &cfg, &ctx);
+		ok = dsi_vm_calc(dsi, &cfg, ctx);
 	else
-		ok = dsi_cm_calc(dsi, &cfg, &ctx);
+		ok = dsi_cm_calc(dsi, &cfg, ctx);
 
-	if (!ok) {
-		DSSERR("failed to find suitable DSI clock settings\n");
-		r = -EINVAL;
-		goto err;
-	}
+	if (!ok)
+		return -EINVAL;
+
+	dsi_pll_calc_dsi_fck(dsi, &ctx->dsi_cinfo);
 
-	dsi_pll_calc_dsi_fck(dsi, &ctx.dsi_cinfo);
+	r = dsi_lp_clock_calc(ctx->dsi_cinfo.clkout[HSDIV_DSI],
+		cfg.lp_clk_min, cfg.lp_clk_max, &ctx->user_lp_cinfo);
+	if (r)
+		return r;
+
+	return 0;
+}
 
-	r = dsi_lp_clock_calc(ctx.dsi_cinfo.clkout[HSDIV_DSI],
-		cfg.lp_clk_min, cfg.lp_clk_max, &dsi->user_lp_cinfo);
+static int dsi_set_config(struct omap_dss_device *dssdev,
+		const struct drm_display_mode *mode)
+{
+	struct dsi_data *dsi = to_dsi_data(dssdev);
+	struct dsi_clk_calc_ctx ctx;
+	int r;
+
+	mutex_lock(&dsi->lock);
+
+	r = __dsi_calc_config(dsi, mode, &ctx);
 	if (r) {
-		DSSERR("failed to find suitable DSI LP clock settings\n");
+		DSSERR("failed to find suitable DSI clock settings\n");
 		goto err;
 	}
 
+	dsi->user_lp_cinfo = ctx.user_lp_cinfo;
 	dsi->user_dsi_cinfo = ctx.dsi_cinfo;
 	dsi->user_dispc_cinfo = ctx.dispc_cinfo;
 
@@ -5008,11 +5020,17 @@ static void dsi_set_timings(struct omap_dss_device *dssdev,
 static int dsi_check_timings(struct omap_dss_device *dssdev,
 			     struct drm_display_mode *mode)
 {
+	struct dsi_data *dsi = to_dsi_data(dssdev);
+	struct dsi_clk_calc_ctx ctx;
+	int r;
+
 	DSSDBG("dsi_check_timings\n");
 
-	/* TODO */
+	mutex_lock(&dsi->lock);
+	r = __dsi_calc_config(dsi, mode, &ctx);
+	mutex_unlock(&dsi->lock);
 
-	return 0;
+	return r;
 }
 
 static int dsi_connect(struct omap_dss_device *src,
-- 
2.24.0

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

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

* [RFCv1 35/42] drm/omap: panel-dsi-cm: use DEVICE_ATTR_RO
  2019-11-17  2:39 [RFCv1 00/42] drm/omap: Convert DSI code to use drm_mipi_dsi and drm_panel Sebastian Reichel
                   ` (34 preceding siblings ...)
  2019-11-17  2:40 ` [RFCv1 34/42] drm/omap: dsi: implement check timings Sebastian Reichel
@ 2019-11-17  2:40 ` Sebastian Reichel
  2019-11-17  2:40 ` [RFCv1 36/42] drm/omap: panel-dsi-cm: support unbinding Sebastian Reichel
                   ` (6 subsequent siblings)
  42 siblings, 0 replies; 64+ messages in thread
From: Sebastian Reichel @ 2019-11-17  2:40 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Tomi Valkeinen
  Cc: kernel, Tony Lindgren, H. Nikolaus Schaller, Merlijn Wajer,
	Sebastian Reichel, dri-devel, linux-omap

Use DEVICE_ATTR_RO helper instead of plain DEVICE_ATTR,
which makes the code a bit shorter and easier to read.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
index 84b0e79c025e..0148f40eceb2 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
@@ -219,7 +219,7 @@ static const struct backlight_ops dsicm_bl_ops = {
 	.update_status  = dsicm_bl_update_status,
 };
 
-static ssize_t dsicm_num_errors_show(struct device *dev,
+static ssize_t num_dsi_errors_show(struct device *dev,
 		struct device_attribute *attr, char *buf)
 {
 	struct panel_drv_data *ddata = dev_get_drvdata(dev);
@@ -239,7 +239,7 @@ static ssize_t dsicm_num_errors_show(struct device *dev,
 	return snprintf(buf, PAGE_SIZE, "%d\n", errors);
 }
 
-static ssize_t dsicm_hw_revision_show(struct device *dev,
+static ssize_t hw_revision_show(struct device *dev,
 		struct device_attribute *attr, char *buf)
 {
 	struct panel_drv_data *ddata = dev_get_drvdata(dev);
@@ -259,8 +259,8 @@ static ssize_t dsicm_hw_revision_show(struct device *dev,
 	return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x\n", id1, id2, id3);
 }
 
-static DEVICE_ATTR(num_dsi_errors, S_IRUGO, dsicm_num_errors_show, NULL);
-static DEVICE_ATTR(hw_revision, S_IRUGO, dsicm_hw_revision_show, NULL);
+static DEVICE_ATTR_RO(num_dsi_errors);
+static DEVICE_ATTR_RO(hw_revision);
 
 static struct attribute *dsicm_attrs[] = {
 	&dev_attr_num_dsi_errors.attr,
-- 
2.24.0

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

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

* [RFCv1 36/42] drm/omap: panel-dsi-cm: support unbinding
  2019-11-17  2:39 [RFCv1 00/42] drm/omap: Convert DSI code to use drm_mipi_dsi and drm_panel Sebastian Reichel
                   ` (35 preceding siblings ...)
  2019-11-17  2:40 ` [RFCv1 35/42] drm/omap: panel-dsi-cm: use DEVICE_ATTR_RO Sebastian Reichel
@ 2019-11-17  2:40 ` Sebastian Reichel
  2019-11-17  2:40 ` [RFCv1 37/42] drm/omap: panel-dsi-cm: fix remove() Sebastian Reichel
                   ` (5 subsequent siblings)
  42 siblings, 0 replies; 64+ messages in thread
From: Sebastian Reichel @ 2019-11-17  2:40 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Tomi Valkeinen
  Cc: kernel, Tony Lindgren, H. Nikolaus Schaller, Merlijn Wajer,
	Sebastian Reichel, dri-devel, linux-omap

Now, that the driver implements the common DRM panel API
the unbind no longer needs to be suppressed.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
index 0148f40eceb2..f607b3dfa31f 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
@@ -598,7 +598,7 @@ static int dsicm_probe(struct mipi_dsi_device *dsi)
 	return r;
 }
 
-static int __exit dsicm_remove(struct mipi_dsi_device *dsi)
+static int dsicm_remove(struct mipi_dsi_device *dsi)
 {
 	struct panel_drv_data *ddata = mipi_dsi_get_drvdata(dsi);
 
@@ -628,11 +628,10 @@ MODULE_DEVICE_TABLE(of, dsicm_of_match);
 
 static struct mipi_dsi_driver dsicm_driver = {
 	.probe = dsicm_probe,
-	.remove = __exit_p(dsicm_remove),
+	.remove = dsicm_remove,
 	.driver = {
 		.name = "panel-dsi-cm",
 		.of_match_table = dsicm_of_match,
-		.suppress_bind_attrs = true,
 	},
 };
 module_mipi_dsi_driver(dsicm_driver);
-- 
2.24.0

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

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

* [RFCv1 37/42] drm/omap: panel-dsi-cm: fix remove()
  2019-11-17  2:39 [RFCv1 00/42] drm/omap: Convert DSI code to use drm_mipi_dsi and drm_panel Sebastian Reichel
                   ` (36 preceding siblings ...)
  2019-11-17  2:40 ` [RFCv1 36/42] drm/omap: panel-dsi-cm: support unbinding Sebastian Reichel
@ 2019-11-17  2:40 ` Sebastian Reichel
  2019-11-17  2:40 ` [RFCv1 38/42] drm/omap: panel-dsi-cm: do not power on/off twice Sebastian Reichel
                   ` (4 subsequent siblings)
  42 siblings, 0 replies; 64+ messages in thread
From: Sebastian Reichel @ 2019-11-17  2:40 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Tomi Valkeinen
  Cc: kernel, Tony Lindgren, H. Nikolaus Schaller, Merlijn Wajer,
	Sebastian Reichel, dri-devel, linux-omap

The remove function should disable the panel by
calling the unprepare() function before the panel
is disconnected from MIPI bus instead of trying
to reset it.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
index f607b3dfa31f..90132d1d1f5d 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
@@ -604,6 +604,8 @@ static int dsicm_remove(struct mipi_dsi_device *dsi)
 
 	dev_dbg(&dsi->dev, "remove\n");
 
+	drm_panel_unprepare(&ddata->panel);
+
 	mipi_dsi_detach(dsi);
 
 	drm_panel_remove(&ddata->panel);
@@ -613,9 +615,6 @@ static int dsicm_remove(struct mipi_dsi_device *dsi)
 	if (ddata->extbldev)
 		put_device(&ddata->extbldev->dev);
 
-	/* reset, to be sure that the panel is in a valid state */
-	dsicm_hw_reset(ddata);
-
 	return 0;
 }
 
-- 
2.24.0

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

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

* [RFCv1 38/42] drm/omap: panel-dsi-cm: do not power on/off twice
  2019-11-17  2:39 [RFCv1 00/42] drm/omap: Convert DSI code to use drm_mipi_dsi and drm_panel Sebastian Reichel
                   ` (37 preceding siblings ...)
  2019-11-17  2:40 ` [RFCv1 37/42] drm/omap: panel-dsi-cm: fix remove() Sebastian Reichel
@ 2019-11-17  2:40 ` Sebastian Reichel
  2019-11-17  2:40 ` [RFCv1 39/42] drm/omap: dsi: return proper error code from dsi_update_all() Sebastian Reichel
                   ` (3 subsequent siblings)
  42 siblings, 0 replies; 64+ messages in thread
From: Sebastian Reichel @ 2019-11-17  2:40 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Tomi Valkeinen
  Cc: kernel, Tony Lindgren, H. Nikolaus Schaller, Merlijn Wajer,
	Sebastian Reichel, dri-devel, linux-omap

Make sure, that we only power on/off the device once.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
index 90132d1d1f5d..7f6b1129862a 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
@@ -290,6 +290,9 @@ static int dsicm_power_on(struct panel_drv_data *ddata)
 	u8 id1, id2, id3;
 	int r;
 
+	if (ddata->enabled)
+		return 0;
+
 	r = regulator_bulk_enable(DCS_REGULATOR_SUPPLY_NUM, ddata->supplies);
 	if (r) {
 		dev_err(&ddata->dsi->dev, "failed to enable supplies: %d\n", r);
@@ -354,6 +357,9 @@ static int dsicm_power_off(struct panel_drv_data *ddata)
 {
 	int r;
 
+	if (!ddata->enabled)
+		return 0;
+
 	ddata->enabled = 0;
 
 	r = mipi_dsi_dcs_set_display_off(ddata->dsi);
-- 
2.24.0

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

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

* [RFCv1 39/42] drm/omap: dsi: return proper error code from dsi_update_all()
  2019-11-17  2:39 [RFCv1 00/42] drm/omap: Convert DSI code to use drm_mipi_dsi and drm_panel Sebastian Reichel
                   ` (38 preceding siblings ...)
  2019-11-17  2:40 ` [RFCv1 38/42] drm/omap: panel-dsi-cm: do not power on/off twice Sebastian Reichel
@ 2019-11-17  2:40 ` Sebastian Reichel
  2019-11-17  2:40 ` [RFCv1 40/42] drm/omap: dsi: support panel un/re-binding Sebastian Reichel
                   ` (2 subsequent siblings)
  42 siblings, 0 replies; 64+ messages in thread
From: Sebastian Reichel @ 2019-11-17  2:40 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Tomi Valkeinen
  Cc: kernel, Tony Lindgren, H. Nikolaus Schaller, Merlijn Wajer,
	Sebastian Reichel, dri-devel, linux-omap

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 drivers/gpu/drm/omapdrm/dss/dsi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index 1b57f516618a..bc96f74f1740 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -3987,7 +3987,7 @@ static int dsi_update_all(struct omap_dss_device *dssdev)
 			return r;
 	}
 
-	return 0;
+	return r;
 }
 
 /* Display funcs */
-- 
2.24.0

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

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

* [RFCv1 40/42] drm/omap: dsi: support panel un/re-binding
  2019-11-17  2:39 [RFCv1 00/42] drm/omap: Convert DSI code to use drm_mipi_dsi and drm_panel Sebastian Reichel
                   ` (39 preceding siblings ...)
  2019-11-17  2:40 ` [RFCv1 39/42] drm/omap: dsi: return proper error code from dsi_update_all() Sebastian Reichel
@ 2019-11-17  2:40 ` Sebastian Reichel
  2019-11-17  2:40 ` [RFCv1 41/42] ARM: dts: omap4-droid4: add panel compatible Sebastian Reichel
  2019-11-17  2:40 ` [RFCv1 42/42] drm/panel: Move OMAP's DSI command mode panel driver Sebastian Reichel
  42 siblings, 0 replies; 64+ messages in thread
From: Sebastian Reichel @ 2019-11-17  2:40 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Tomi Valkeinen
  Cc: kernel, Tony Lindgren, H. Nikolaus Schaller, Merlijn Wajer,
	Sebastian Reichel, dri-devel, linux-omap

This adds support for unbinding the panel driver
and have working output again when the panel is
bound again later. This is important, since the
generic panel drivers do not suppress the unbind
properties and the panel module might be unloaded.

Also this adds support for unbinding the DSI encoder
and gets back to running setup when the encoder is
rebound later. Making this possible is just a side-
effect of panel unbinding support.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 drivers/gpu/drm/omapdrm/dss/base.c |  2 +-
 drivers/gpu/drm/omapdrm/dss/dsi.c  | 63 ++++++++++++++++++++++--------
 2 files changed, 47 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/base.c b/drivers/gpu/drm/omapdrm/dss/base.c
index a1970b9db6ab..f85697784e26 100644
--- a/drivers/gpu/drm/omapdrm/dss/base.c
+++ b/drivers/gpu/drm/omapdrm/dss/base.c
@@ -217,7 +217,7 @@ void omapdss_device_disconnect(struct omap_dss_device *src,
 		dst ? dev_name(dst->dev) : "NULL");
 
 	if (!dst) {
-		WARN_ON(!src->bridge && !src->panel);
+		WARN_ON(src->type != OMAP_DISPLAY_TYPE_DSI && !src->bridge && !src->panel);
 		return;
 	}
 
diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index bc96f74f1740..5996e39500c6 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -38,6 +38,7 @@
 #include <video/mipi_display.h>
 #include <drm/drm_mipi_dsi.h>
 #include <drm/drm_panel.h>
+#include <drm/drm_probe_helper.h>
 
 #include "omapdss.h"
 #include "dss.h"
@@ -440,6 +441,9 @@ struct dsi_data {
 	struct omap_dss_dsi_videomode_timings vm_timings;
 
 	struct omap_dss_device output;
+
+	struct drm_device *drm_dev;
+	struct drm_connector *connector;
 };
 
 struct dsi_packet_sent_handler_data {
@@ -5143,6 +5147,7 @@ int omap_dsi_host_attach(struct mipi_dsi_host *host,
 			 struct mipi_dsi_device *client)
 {
 	struct dsi_data *dsi = host_to_omap(host);
+	struct omap_dss_device *dssdev = &dsi->output;
 	unsigned int channel = client->channel;
 	struct drm_panel *panel;
 	int r;
@@ -5188,7 +5193,18 @@ int omap_dsi_host_attach(struct mipi_dsi_host *host,
 
 	dsi->ulps_auto_idle = !!(client->mode_flags & MIPI_DSI_MODE_ULPS_IDLE);
 
+	dssdev->panel = panel;
+
+	if (dsi->connector) {
+		dsi->connector->status = connector_status_connected;
+		drm_panel_attach(panel, dsi->connector);
+	}
+
 	dsi_bus_unlock(dsi);
+
+	if (dsi->drm_dev && dsi->drm_dev->mode_config.poll_enabled)
+		drm_kms_helper_hotplug_event(dsi->drm_dev);
+
 	return 0;
 }
 
@@ -5196,6 +5212,7 @@ int omap_dsi_host_detach(struct mipi_dsi_host *host,
 			 struct mipi_dsi_device *client)
 {
 	struct dsi_data *dsi = host_to_omap(host);
+	struct omap_dss_device *dssdev = &dsi->output;
 	unsigned int channel = client->channel;
 
 	if (channel > 3)
@@ -5204,8 +5221,28 @@ int omap_dsi_host_detach(struct mipi_dsi_host *host,
 	if (dsi->vc[channel].dest != client)
 		return -EINVAL;
 
+	if (!dssdev->panel)
+		return -EINVAL;
+
+	dsi_bus_lock(dsi);
+
+	/* HACK: steal connector and drm_dev from panel */
+	dsi->connector = dssdev->panel->connector;
+	dsi->drm_dev = dssdev->panel->drm;
+
+	if (dsi->connector) {
+		dsi->connector->status = connector_status_disconnected;
+		drm_panel_detach(dssdev->panel);
+		dssdev->panel = NULL;
+	}
+
 	omap_dsi_unregister_te_irq(dsi);
 	dsi->vc[channel].dest = NULL;
+	dsi_bus_unlock(dsi);
+
+	if (dsi->drm_dev && dsi->drm_dev->mode_config.poll_enabled)
+		drm_kms_helper_hotplug_event(dsi->drm_dev);
+
 	return 0;
 }
 
@@ -5373,6 +5410,12 @@ static int dsi_bind(struct device *dev, struct device *master, void *data)
 	dsi->debugfs.clks = dss_debugfs_create_file(dss, name,
 						    dsi_dump_dsi_clocks, dsi);
 
+	r = mipi_dsi_host_register(&dsi->host);
+	if (r < 0) {
+		dev_err(dev, "failed to register DSI host: %d\n", r);
+		return r;
+	}
+
 	return 0;
 }
 
@@ -5380,6 +5423,8 @@ static void dsi_unbind(struct device *dev, struct device *master, void *data)
 {
 	struct dsi_data *dsi = dev_get_drvdata(dev);
 
+	mipi_dsi_host_unregister(&dsi->host);
+
 	dss_debugfs_remove_file(dsi->debugfs.clks);
 	dss_debugfs_remove_file(dsi->debugfs.irqs);
 	dss_debugfs_remove_file(dsi->debugfs.regs);
@@ -5401,7 +5446,6 @@ static const struct component_ops dsi_component_ops = {
 static int dsi_init_output(struct dsi_data *dsi)
 {
 	struct omap_dss_device *out = &dsi->output;
-	int r;
 
 	out->dev = dsi->dev;
 	out->id = dsi->module_id == 0 ?
@@ -5417,10 +5461,6 @@ static int dsi_init_output(struct dsi_data *dsi)
 		       | DRM_BUS_FLAG_DE_HIGH
 		       | DRM_BUS_FLAG_SYNC_DRIVE_NEGEDGE;
 
-	r = omapdss_device_init_output(out);
-	if (r < 0)
-		return r;
-
 	omapdss_device_register(out);
 
 	return 0;
@@ -5687,15 +5727,9 @@ static int dsi_probe(struct platform_device *pdev)
 	dsi->host.ops = &omap_dsi_host_ops;
 	dsi->host.dev = &pdev->dev;
 
-	r = mipi_dsi_host_register(&dsi->host);
-	if (r < 0) {
-		dev_err(&pdev->dev, "failed to register DSI host: %d\n", r);
-		goto err_pm_disable;
-	}
-
 	r = dsi_init_output(dsi);
 	if (r)
-		goto err_dsi_host_unregister;
+		goto err_pm_disable;
 
 	r = dsi_probe_of(dsi);
 	if (r) {
@@ -5711,8 +5745,6 @@ static int dsi_probe(struct platform_device *pdev)
 
 err_uninit_output:
 	dsi_uninit_output(dsi);
-err_dsi_host_unregister:
-	mipi_dsi_host_unregister(&dsi->host);
 err_pm_disable:
 	pm_runtime_disable(dev);
 	return r;
@@ -5726,8 +5758,6 @@ static int dsi_remove(struct platform_device *pdev)
 
 	dsi_uninit_output(dsi);
 
-	mipi_dsi_host_unregister(&dsi->host);
-
 	pm_runtime_disable(&pdev->dev);
 
 	if (dsi->vdds_dsi_reg != NULL && dsi->vdds_dsi_enabled) {
@@ -5774,6 +5804,5 @@ struct platform_driver omap_dsihw_driver = {
 		.name   = "omapdss_dsi",
 		.pm	= &dsi_pm_ops,
 		.of_match_table = dsi_of_match,
-		.suppress_bind_attrs = true,
 	},
 };
-- 
2.24.0

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

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

* [RFCv1 41/42] ARM: dts: omap4-droid4: add panel compatible
  2019-11-17  2:39 [RFCv1 00/42] drm/omap: Convert DSI code to use drm_mipi_dsi and drm_panel Sebastian Reichel
                   ` (40 preceding siblings ...)
  2019-11-17  2:40 ` [RFCv1 40/42] drm/omap: dsi: support panel un/re-binding Sebastian Reichel
@ 2019-11-17  2:40 ` Sebastian Reichel
  2019-11-17  2:40 ` [RFCv1 42/42] drm/panel: Move OMAP's DSI command mode panel driver Sebastian Reichel
  42 siblings, 0 replies; 64+ messages in thread
From: Sebastian Reichel @ 2019-11-17  2:40 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Tomi Valkeinen
  Cc: kernel, Tony Lindgren, H. Nikolaus Schaller, Merlijn Wajer,
	Sebastian Reichel, dri-devel, linux-omap

Add Droid 4 specific compatible value in addition to the
generic one, so that we have the ability to add panel
specific quirks in the future.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 arch/arm/boot/dts/omap4-droid4-xt894.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/omap4-droid4-xt894.dts b/arch/arm/boot/dts/omap4-droid4-xt894.dts
index 6af0a9288940..d5668998aa9d 100644
--- a/arch/arm/boot/dts/omap4-droid4-xt894.dts
+++ b/arch/arm/boot/dts/omap4-droid4-xt894.dts
@@ -203,7 +203,7 @@
 	};
 
 	lcd0: panel@0 {
-		compatible = "panel-dsi-cm";
+		compatible = "motorola,droid4-panel", "panel-dsi-cm";
 		reg = <0>;
 		label = "lcd0";
 		vddi-supply = <&lcd_regulator>;
-- 
2.24.0

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

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

* [RFCv1 42/42] drm/panel: Move OMAP's DSI command mode panel driver
  2019-11-17  2:39 [RFCv1 00/42] drm/omap: Convert DSI code to use drm_mipi_dsi and drm_panel Sebastian Reichel
                   ` (41 preceding siblings ...)
  2019-11-17  2:40 ` [RFCv1 41/42] ARM: dts: omap4-droid4: add panel compatible Sebastian Reichel
@ 2019-11-17  2:40 ` Sebastian Reichel
  42 siblings, 0 replies; 64+ messages in thread
From: Sebastian Reichel @ 2019-11-17  2:40 UTC (permalink / raw)
  To: Sebastian Reichel, Laurent Pinchart, Tomi Valkeinen
  Cc: kernel, Tony Lindgren, H. Nikolaus Schaller, Merlijn Wajer,
	Sebastian Reichel, dri-devel, linux-omap

The panel driver is no longer using any OMAP specific APIs, so
let's move it into the generic panel directory.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 drivers/gpu/drm/omapdrm/displays/Kconfig                 | 6 ------
 drivers/gpu/drm/omapdrm/displays/Makefile                | 1 -
 drivers/gpu/drm/panel/Kconfig                            | 9 +++++++++
 drivers/gpu/drm/panel/Makefile                           | 1 +
 .../gpu/drm/{omapdrm/displays => panel}/panel-dsi-cm.c   | 0
 5 files changed, 10 insertions(+), 7 deletions(-)
 rename drivers/gpu/drm/{omapdrm/displays => panel}/panel-dsi-cm.c (100%)

diff --git a/drivers/gpu/drm/omapdrm/displays/Kconfig b/drivers/gpu/drm/omapdrm/displays/Kconfig
index 240dda102845..1175811a55ac 100644
--- a/drivers/gpu/drm/omapdrm/displays/Kconfig
+++ b/drivers/gpu/drm/omapdrm/displays/Kconfig
@@ -23,10 +23,4 @@ config DRM_OMAP_CONNECTOR_ANALOG_TV
 	help
 	  Driver for a generic analog TV connector.
 
-config DRM_OMAP_PANEL_DSI_CM
-	tristate "Generic DSI Command Mode Panel"
-	depends on BACKLIGHT_CLASS_DEVICE
-	help
-	  Driver for generic DSI command mode panels.
-
 endmenu
diff --git a/drivers/gpu/drm/omapdrm/displays/Makefile b/drivers/gpu/drm/omapdrm/displays/Makefile
index cb76859dc574..68ff8b1d051a 100644
--- a/drivers/gpu/drm/omapdrm/displays/Makefile
+++ b/drivers/gpu/drm/omapdrm/displays/Makefile
@@ -3,4 +3,3 @@ obj-$(CONFIG_DRM_OMAP_ENCODER_OPA362) += encoder-opa362.o
 obj-$(CONFIG_DRM_OMAP_ENCODER_TPD12S015) += encoder-tpd12s015.o
 obj-$(CONFIG_DRM_OMAP_CONNECTOR_HDMI) += connector-hdmi.o
 obj-$(CONFIG_DRM_OMAP_CONNECTOR_ANALOG_TV) += connector-analog-tv.o
-obj-$(CONFIG_DRM_OMAP_PANEL_DSI_CM) += panel-dsi-cm.o
diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index f152bc4eeb53..91520907d3c6 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -39,6 +39,15 @@ config DRM_PANEL_SIMPLE
 	  that it can be automatically turned off when the panel goes into a
 	  low power state.
 
+config DRM_PANEL_DSI_CM
+	tristate "support for generic DSI command mode panel"
+	depends on OF
+	depends on DRM_MIPI_DSI
+	depends on BACKLIGHT_CLASS_DEVICE
+	help
+	  DRM panel driver for DSI command mode panels with support for
+	  embedded and external backlights.
+
 config DRM_PANEL_FEIYANG_FY07024DI26A30D
 	tristate "Feiyang FY07024DI26A30-D MIPI-DSI LCD panel"
 	depends on OF
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index b6cd39fe0f20..2afed2ae171c 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -2,6 +2,7 @@
 obj-$(CONFIG_DRM_PANEL_ARM_VERSATILE) += panel-arm-versatile.o
 obj-$(CONFIG_DRM_PANEL_LVDS) += panel-lvds.o
 obj-$(CONFIG_DRM_PANEL_SIMPLE) += panel-simple.o
+obj-$(CONFIG_DRM_PANEL_DSI_CM) += panel-dsi-cm.o
 obj-$(CONFIG_DRM_PANEL_FEIYANG_FY07024DI26A30D) += panel-feiyang-fy07024di26a30d.o
 obj-$(CONFIG_DRM_PANEL_ILITEK_IL9322) += panel-ilitek-ili9322.o
 obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9881C) += panel-ilitek-ili9881c.o
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c b/drivers/gpu/drm/panel/panel-dsi-cm.c
similarity index 100%
rename from drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
rename to drivers/gpu/drm/panel/panel-dsi-cm.c
-- 
2.24.0

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

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

* Re: [RFCv1 32/42] drm/omap: dsi: convert to drm_panel
  2019-11-17  2:40 ` [RFCv1 32/42] drm/omap: dsi: convert to drm_panel Sebastian Reichel
@ 2019-11-17 19:23   ` H. Nikolaus Schaller
  2019-11-18 14:45     ` Sebastian Reichel
  0 siblings, 1 reply; 64+ messages in thread
From: H. Nikolaus Schaller @ 2019-11-17 19:23 UTC (permalink / raw)
  To: Sebastian Reichel
  Cc: kernel, Tony Lindgren, Merlijn Wajer, Sebastian Reichel,
	dri-devel, Tomi Valkeinen, Laurent Pinchart, linux-omap

Hi,

> Am 17.11.2019 um 03:40 schrieb Sebastian Reichel <sebastian.reichel@collabora.com>:
> 
> This converts the DSI module to expect common drm_panel display
> drivers instead of dssdev based ones.
> 
> This commit is WIP. We somehow need to know the panels resolution
> in omap_dsi_host_attach(), so that we can properly configure the
> DSI bus clock before enabling the bus. The control bus must be
> enabled at this point, so that the panel can use it.
> 
> Other drivers run drm_panel_attach() in their dsi host attach,
> which makes it possible to call drm_panel_get_modes() afterwards
> and the get the correct mode from the connector.
> 
> Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
> ---
> .../gpu/drm/omapdrm/displays/panel-dsi-cm.c   | 217 +++++++-----------
> drivers/gpu/drm/omapdrm/dss/dsi.c             | 141 ++++++++++--
> .../gpu/drm/omapdrm/dss/omapdss-boot-init.c   |   1 -
> drivers/gpu/drm/omapdrm/dss/omapdss.h         |  22 +-
> drivers/gpu/drm/omapdrm/omap_crtc.c           |  17 +-
> 5 files changed, 205 insertions(+), 193 deletions(-)
> 
> diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
> index 18020ac43a83..84b0e79c025e 100644
> --- a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
> +++ b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
> @@ -6,8 +6,6 @@
>  * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
>  */
> 
> -/* #define DEBUG */
> -
> #include <linux/backlight.h>
> #include <linux/delay.h>
> #include <linux/gpio/consumer.h>
> @@ -20,11 +18,14 @@
> #include <linux/regulator/consumer.h>
> 
> #include <drm/drm_connector.h>
> +#include <drm/drm_mipi_dsi.h>
> +#include <drm/drm_panel.h>
> +#include <drm/drm_modes.h>
> 
> +#include <video/display_timing.h>
> #include <video/mipi_display.h>
> #include <video/of_display_timing.h>
> -
> -#include "../dss/omapdss.h"
> +#include <video/videomode.h>
> 
> #define DCS_READ_NUM_ERRORS	0x05
> #define DCS_GET_ID1		0xda
> @@ -35,11 +36,8 @@
> 
> struct panel_drv_data {
> 	struct mipi_dsi_device *dsi;
> -
> -	struct omap_dss_device dssdev;
> -	struct omap_dss_device *src;
> -
> -	struct videomode vm;
> +	struct drm_panel panel;
> +	struct drm_display_mode mode;
> 
> 	struct mutex lock;
> 
> @@ -71,7 +69,11 @@ struct panel_drv_data {
> 	bool ulps_enabled;
> };
> 
> -#define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev)
> +
> +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);
> 
> @@ -285,10 +287,15 @@ static void dsicm_hw_reset(struct panel_drv_data *ddata)
> 
> static int dsicm_power_on(struct panel_drv_data *ddata)
> {
> -	struct omap_dss_device *src = ddata->src;
> 	u8 id1, id2, id3;
> 	int r;
> 
> +	r = regulator_bulk_enable(DCS_REGULATOR_SUPPLY_NUM, ddata->supplies);
> +	if (r) {
> +		dev_err(&ddata->dsi->dev, "failed to enable supplies: %d\n", r);
> +		return r;
> +	}
> +
> 	dsicm_hw_reset(ddata);
> 
> 	ddata->dsi->mode_flags |= MIPI_DSI_MODE_LPM;
> @@ -322,10 +329,6 @@ static int dsicm_power_on(struct panel_drv_data *ddata)
> 	if (r)
> 		goto err;
> 
> -	r = src->ops->dsi.enable_video_output(src, ddata->dsi->channel);
> -	if (r)
> -		goto err;
> -
> 	ddata->enabled = 1;
> 
> 	if (!ddata->intro_printed) {
> @@ -342,18 +345,17 @@ static int dsicm_power_on(struct panel_drv_data *ddata)
> 
> 	dsicm_hw_reset(ddata);
> 
> +	regulator_bulk_disable(DCS_REGULATOR_SUPPLY_NUM, ddata->supplies);
> +
> 	return r;
> }
> 
> -static void dsicm_power_off(struct panel_drv_data *ddata)
> +static int dsicm_power_off(struct panel_drv_data *ddata)
> {
> -	struct omap_dss_device *src = ddata->src;
> 	int r;
> 
> 	ddata->enabled = 0;
> 
> -	src->ops->dsi.disable_video_output(src, ddata->dsi->channel);
> -
> 	r = mipi_dsi_dcs_set_display_off(ddata->dsi);
> 	if (!r)
> 		r = dsicm_sleep_in(ddata);
> @@ -363,52 +365,17 @@ static void dsicm_power_off(struct panel_drv_data *ddata)
> 				"error disabling panel, issuing HW reset\n");
> 		dsicm_hw_reset(ddata);
> 	}
> -}
> 
> -static int dsicm_connect(struct omap_dss_device *src,
> -			 struct omap_dss_device *dst)
> -{
> -	struct panel_drv_data *ddata = to_panel_data(dst);
> -
> -	ddata->src = src;
> -	return 0;
> -}
> -
> -static void dsicm_disconnect(struct omap_dss_device *src,
> -			     struct omap_dss_device *dst)
> -{
> -	struct panel_drv_data *ddata = to_panel_data(dst);
> -
> -	ddata->src = NULL;
> -}
> -
> -static void dsicm_pre_enable(struct omap_dss_device *dssdev)
> -{
> -	struct panel_drv_data *ddata = to_panel_data(dssdev);
> -	struct omap_dss_device *src = ddata->src;
> -	int r;
> -	struct omap_dss_dsi_config dsi_config = {
> -		.vm = &ddata->vm,
> -		.hs_clk_min = 150000000,
> -		.hs_clk_max = 300000000,
> -		.lp_clk_min = 7000000,
> -		.lp_clk_max = 10000000,
> -	};
> -
> -	r = regulator_bulk_enable(DCS_REGULATOR_SUPPLY_NUM, ddata->supplies);
> -	if (r) {
> -		dev_err(&ddata->dsi->dev, "failed to enable supplies: %d\n", r);
> -	}
> +	r = regulator_bulk_disable(DCS_REGULATOR_SUPPLY_NUM, ddata->supplies);
> +	if (r)
> +		dev_err(&ddata->dsi->dev, "failed to disable supplies: %d\n", r);
> 
> -	r = src->ops->dsi.set_config(src, &dsi_config);
> -	if (r) {
> -		dev_err(&ddata->dsi->dev, "failed to configure DSI\n");
> -	}
> +	return r;
> }
> 
> -static void dsicm_enable(struct omap_dss_device *dssdev)
> +static int dsicm_prepare(struct drm_panel *panel)
> {
> -	struct panel_drv_data *ddata = to_panel_data(dssdev);
> +	struct panel_drv_data *ddata = panel_to_ddata(panel);
> 	int r;
> 
> 	mutex_lock(&ddata->lock);
> @@ -421,33 +388,27 @@ static void dsicm_enable(struct omap_dss_device *dssdev)
> 
> 	dsicm_bl_power(ddata, true);
> 
> -	return;
> +	return 0;
> err:
> -	dev_dbg(&ddata->dsi->dev, "enable failed (%d)\n", r);
> +	dev_err(&ddata->dsi->dev, "enable failed (%d)\n", r);
> 	mutex_unlock(&ddata->lock);
> +	return r;
> }
> 
> -static void dsicm_disable(struct omap_dss_device *dssdev)
> +static int dsicm_unprepare(struct drm_panel *panel)
> {
> -	struct panel_drv_data *ddata = to_panel_data(dssdev);
> +	struct panel_drv_data *ddata = panel_to_ddata(panel);
> +	int r;
> 
> 	dsicm_bl_power(ddata, false);
> 
> 	mutex_lock(&ddata->lock);
> 
> -	dsicm_power_off(ddata);
> +	r = dsicm_power_off(ddata);
> 
> 	mutex_unlock(&ddata->lock);
> -}
> -
> -static void dsicm_post_disable(struct omap_dss_device *dssdev)
> -{
> -	struct panel_drv_data *ddata = to_panel_data(dssdev);
> -	int r;
> 
> -	r = regulator_bulk_disable(DCS_REGULATOR_SUPPLY_NUM, ddata->supplies);
> -	if (r)
> -		dev_err(&ddata->dsi->dev, "failed to disable supplies: %d\n", r);
> +	return r;
> }
> 
> static int _dsicm_enable_te(struct panel_drv_data *ddata, bool enable)
> @@ -466,50 +427,35 @@ static int _dsicm_enable_te(struct panel_drv_data *ddata, bool enable)
> 	return r;
> }
> 
> -static int dsicm_get_modes(struct omap_dss_device *dssdev,
> -			   struct drm_connector *connector)
> +static int dsicm_get_modes(struct drm_panel *panel)
> {
> -	struct panel_drv_data *ddata = to_panel_data(dssdev);
> -
> -	connector->display_info.width_mm = ddata->width_mm;
> -	connector->display_info.height_mm = ddata->height_mm;
> -
> -	return omapdss_display_get_modes(connector, &ddata->vm);
> -}
> -
> -static int dsicm_check_timings(struct omap_dss_device *dssdev,
> -			       struct drm_display_mode *mode)
> -{
> -	struct panel_drv_data *ddata = to_panel_data(dssdev);
> -	int ret = 0;
> +	struct panel_drv_data *ddata = panel_to_ddata(panel);
> +	struct drm_connector *connector = panel->connector;
> +	struct drm_display_mode *mode;
> +
> +	mode = drm_mode_duplicate(panel->drm, &ddata->mode);
> +	if (!mode) {
> +		dev_err(&ddata->dsi->dev, "failed to add mode %ux%ux@%u\n",
> +			ddata->mode.hdisplay, ddata->mode.vdisplay,
> +			ddata->mode.vrefresh);
> +		return -ENOMEM;
> +	}
> 
> -	if (mode->hdisplay != ddata->vm.hactive)
> -		ret = -EINVAL;
> +	drm_mode_set_name(mode);
> 
> -	if (mode->vdisplay != ddata->vm.vactive)
> -		ret = -EINVAL;
> +	mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
> +	drm_mode_probed_add(connector, mode);
> 
> -	if (ret) {
> -		dev_warn(dssdev->dev, "wrong resolution: %d x %d",
> -			 mode->hdisplay, mode->vdisplay);
> -		dev_warn(dssdev->dev, "panel resolution: %d x %d",
> -			 ddata->vm.hactive, ddata->vm.vactive);
> -	}
> +	connector->display_info.width_mm = ddata->width_mm;
> +	connector->display_info.height_mm = ddata->height_mm;
> 
> -	return ret;
> +	return 1;
> }
> 
> -static const struct omap_dss_device_ops dsicm_ops = {
> -	.connect	= dsicm_connect,
> -	.disconnect	= dsicm_disconnect,
> -
> -	.pre_enable	= dsicm_pre_enable,
> -	.enable		= dsicm_enable,
> -	.disable	= dsicm_disable,
> -	.post_disable	= dsicm_post_disable,
> -
> -	.get_modes	= dsicm_get_modes,
> -	.check_timings	= dsicm_check_timings,
> +static const struct drm_panel_funcs dsicm_panel_funcs = {
> +	.unprepare = dsicm_unprepare,
> +	.prepare = dsicm_prepare,
> +	.get_modes = dsicm_get_modes,
> };
> 
> static int dsicm_probe_of(struct mipi_dsi_device *dsi)
> @@ -518,8 +464,12 @@ static int dsicm_probe_of(struct mipi_dsi_device *dsi)
> 	struct device_node *backlight;
> 	struct panel_drv_data *ddata = mipi_dsi_get_drvdata(dsi);
> 	struct display_timing timing;
> +	struct videomode vm;
> 	int err;
> 
> +	vm.hactive = 864;
> +	vm.vactive = 480;
> +
> 	ddata->reset_gpio = devm_gpiod_get(&dsi->dev, "reset", GPIOD_OUT_LOW);
> 	if (IS_ERR(ddata->reset_gpio)) {
> 		err = PTR_ERR(ddata->reset_gpio);
> @@ -529,15 +479,16 @@ static int dsicm_probe_of(struct mipi_dsi_device *dsi)
> 
> 	err = of_get_display_timing(node, "panel-timing", &timing);
> 	if (!err) {
> -		videomode_from_timing(&timing, &ddata->vm);
> -		if (!ddata->vm.pixelclock)
> -			ddata->vm.pixelclock =
> -				ddata->vm.hactive * ddata->vm.vactive * 60;
> +		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);
> 
> @@ -573,7 +524,6 @@ static int dsicm_probe(struct mipi_dsi_device *dsi)
> 	struct panel_drv_data *ddata;
> 	struct backlight_device *bldev = NULL;
> 	struct device *dev = &dsi->dev;
> -	struct omap_dss_device *dssdev;
> 	int r;
> 
> 	dev_dbg(dev, "probe\n");
> @@ -585,33 +535,17 @@ static int dsicm_probe(struct mipi_dsi_device *dsi)
> 	mipi_dsi_set_drvdata(dsi, ddata);
> 	ddata->dsi = dsi;
> 
> -	ddata->vm.hactive = 864;
> -	ddata->vm.vactive = 480;
> -	ddata->vm.pixelclock = 864 * 480 * 60;
> -
> 	r = dsicm_probe_of(dsi);
> 	if (r)
> 		return r;
> 
> -	dssdev = &ddata->dssdev;
> -	dssdev->dev = dev;
> -	dssdev->ops = &dsicm_ops;
> -	dssdev->type = OMAP_DISPLAY_TYPE_DSI;
> -	dssdev->display = true;
> -	dssdev->owner = THIS_MODULE;
> -	dssdev->of_ports = BIT(0);
> -	dssdev->ops_flags = OMAP_DSS_DEVICE_OP_MODES;
> -
> -	dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE |
> -		OMAP_DSS_DISPLAY_CAP_TEAR_ELIM;
> -
> -	omapdss_display_init(dssdev);
> -	omapdss_device_register(dssdev);
> -
> 	mutex_init(&ddata->lock);
> 
> 	dsicm_hw_reset(ddata);
> 
> +	drm_panel_init(&ddata->panel, dev, &dsicm_panel_funcs,
> +		       DRM_MODE_CONNECTOR_DSI);
> +

This leads to

drivers/gpu/drm/panel/panel-dsi-cm.c: In function 'dsicm_probe':
drivers/gpu/drm/panel/panel-dsi-cm.c:552:2: error: too many arguments to function 'drm_panel_init'
  drm_panel_init(&ddata->panel, dev, &dsicm_panel_funcs,
  ^
In file included from drivers/gpu/drm/panel/panel-dsi-cm.c:22:0:
./include/drm/drm_panel.h:150:6: note: declared here
 void drm_panel_init(struct drm_panel *panel);
      ^

(when applied to v5.4-rc7)

> 	if (ddata->use_dsi_backlight) {
> 		struct backlight_properties props = { 0 };
> 		props.max_brightness = 255;
> @@ -643,6 +577,10 @@ static int dsicm_probe(struct mipi_dsi_device *dsi)
> 	if (ddata->ulps_enabled)
> 		dsi->mode_flags |= MIPI_DSI_MODE_ULPS_IDLE;
> 
> +	r = drm_panel_add(&ddata->panel);
> +	if (r < 0)
> +		goto err_panel_add;
> +
> 	r = mipi_dsi_attach(dsi);
> 	if (r < 0)
> 		goto err_dsi_attach;
> @@ -650,6 +588,8 @@ static int dsicm_probe(struct mipi_dsi_device *dsi)
> 	return 0;
> 
> err_dsi_attach:
> +	drm_panel_remove(&ddata->panel);
> +err_panel_add:
> 	sysfs_remove_group(&dsi->dev.kobj, &dsicm_attr_group);
> err_bl:
> 	if (ddata->extbldev)
> @@ -661,15 +601,12 @@ static int dsicm_probe(struct mipi_dsi_device *dsi)
> static int __exit dsicm_remove(struct mipi_dsi_device *dsi)
> {
> 	struct panel_drv_data *ddata = mipi_dsi_get_drvdata(dsi);
> -	struct omap_dss_device *dssdev = &ddata->dssdev;
> 
> 	dev_dbg(&dsi->dev, "remove\n");
> 
> 	mipi_dsi_detach(dsi);
> 
> -	omapdss_device_unregister(dssdev);
> -
> -	omapdss_device_disconnect(ddata->src, dssdev);
> +	drm_panel_remove(&ddata->panel);
> 
> 	sysfs_remove_group(&dsi->dev.kobj, &dsicm_attr_group);
> 
> @@ -683,7 +620,7 @@ static int __exit dsicm_remove(struct mipi_dsi_device *dsi)
> }
> 
> static const struct of_device_id dsicm_of_match[] = {
> -	{ .compatible = "omapdss,panel-dsi-cm", },
> +	{ .compatible = "panel-dsi-cm", },
> 	{},
> };
> 
> diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
> index 66ad7dbc66a2..754815068927 100644
> --- a/drivers/gpu/drm/omapdrm/dss/dsi.c
> +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
> @@ -37,6 +37,7 @@
> 
> #include <video/mipi_display.h>
> #include <drm/drm_mipi_dsi.h>
> +#include <drm/drm_panel.h>
> 
> #include "omapdss.h"
> #include "dss.h"
> @@ -220,6 +221,8 @@ static int dsi_vc_send_null(struct dsi_data *dsi, int channel);
> static ssize_t _omap_dsi_host_transfer(struct dsi_data *dsi,
> 				       const struct mipi_dsi_msg *msg);
> 
> +static void dsi_display_disable(struct omap_dss_device *dssdev);
> +
> /* DSI PLL HSDIV indices */
> #define HSDIV_DISPC	0
> #define HSDIV_DSI	1
> @@ -386,6 +389,7 @@ struct dsi_data {
> 	bool te_enabled;
> 	bool ulps_enabled;
> 	bool ulps_auto_idle;
> +	bool video_enabled;
> 
> 	struct delayed_work ulps_work;
> 
> @@ -426,6 +430,8 @@ struct dsi_data {
> 
> 	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;
> @@ -3629,7 +3635,7 @@ static int dsi_configure_pins(struct omap_dss_device *dssdev,
> 	return 0;
> }
> 
> -static int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
> +static void dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
> {
> 	struct dsi_data *dsi = to_dsi_data(dssdev);
> 	int bpp = mipi_dsi_pixel_format_to_bpp(dsi->pix_fmt);
> @@ -3638,8 +3644,10 @@ static int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
> 	int r;
> 
> 	r = dsi_display_init_dispc(dsi);
> -	if (r)
> -		return r;
> +	if (r) {
> +		dev_err(dsi->dev, "failed to init dispc!\n");
> +		return;
> +	}
> 
> 	if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) {
> 		switch (dsi->pix_fmt) {
> @@ -3679,7 +3687,7 @@ static int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
> 	if (r)
> 		goto err_mgr_enable;
> 
> -	return 0;
> +	return;
> 
> err_mgr_enable:
> 	if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) {
> @@ -3688,7 +3696,8 @@ static int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
> 	}
> err_pix_fmt:
> 	dsi_display_uninit_dispc(dsi);
> -	return r;
> +	dev_err(dsi->dev, "failed to enable DSI encoder!\n");
> +	return;
> }
> 
> static void dsi_disable_video_output(struct omap_dss_device *dssdev, int channel)
> @@ -3711,6 +3720,25 @@ static void dsi_disable_video_output(struct omap_dss_device *dssdev, int channel
> 	dsi_display_uninit_dispc(dsi);
> }
> 
> +static void dsi_disable_video_outputs(struct omap_dss_device *dssdev)
> +{
> +	struct dsi_data *dsi = to_dsi_data(dssdev);
> +	int i;
> +
> +	dsi_bus_lock(dsi);
> +	dsi->video_enabled = false;
> +
> +	for (i = 0; i < 3; i++) {
> +		if (!dsi->vc[i].dest)
> +			continue;
> +		dsi_disable_video_output(dssdev, i);
> +	}
> +
> +	dsi_display_disable(dssdev);
> +
> +	dsi_bus_unlock(dsi);
> +}
> +
> static void dsi_update_screen_dispc(struct dsi_data *dsi)
> {
> 	unsigned int bytespp;
> @@ -3904,6 +3932,11 @@ static int dsi_update_channel(struct omap_dss_device *dssdev, int channel)
> 
> 	dsi_bus_lock(dsi);
> 
> +	if (!dsi->video_enabled) {
> +		r = -EIO;
> +		goto err;
> +	}
> +
> 	if (!dsi->vc[channel].dest) {
> 		r = -ENODEV;
> 		goto err;
> @@ -3949,7 +3982,7 @@ static int dsi_update_all(struct omap_dss_device *dssdev)
> 
> 	for (i = 0; i < 4; i++) {
> 		r = dsi_update_channel(dssdev, i);
> -		if (r != -ENODEV)
> +		if (r && r != -ENODEV)
> 			return r;
> 	}
> 
> @@ -4172,8 +4205,30 @@ static void dsi_display_enable(struct omap_dss_device *dssdev)
> {
> 	struct dsi_data *dsi = to_dsi_data(dssdev);
> 	DSSDBG("dsi_display_enable\n");
> -	dsi_bus_lock(dsi);
> +	WARN_ON(!dsi_bus_is_locked(dsi));
> +
> 	dsi_display_ulps_enable(dsi);
> +}
> +
> +static void dsi_enable_video_outputs(struct omap_dss_device *dssdev)
> +{
> +	struct dsi_data *dsi = to_dsi_data(dssdev);
> +	int i;
> +
> +	dsi_bus_lock(dsi);
> +
> +	dsi_display_enable(dssdev);
> +
> +	for (i = 0; i < 3; i++) {
> +		if (!dsi->vc[i].dest)
> +			continue;
> +		dsi_enable_video_output(dssdev, i);
> +	}
> +
> +	dsi->video_enabled = true;
> +
> +	dsi_set_ulps_auto(dsi, true);
> +
> 	dsi_bus_unlock(dsi);
> }
> 
> @@ -4199,10 +4254,10 @@ static void dsi_display_ulps_disable(struct dsi_data *dsi,
> 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_bus_lock(dsi);
> +
> 	dsi_display_ulps_disable(dsi, true, false);
> -	dsi_bus_unlock(dsi);
> }
> 
> static int dsi_enable_te(struct dsi_data *dsi, bool enable)
> @@ -4732,15 +4787,26 @@ static bool dsi_vm_calc(struct dsi_data *dsi,
> 			dsi_vm_calc_pll_cb, ctx);
> }
> 
> +static bool dsi_is_video_mode(struct omap_dss_device *dssdev)
> +{
> +	struct dsi_data *dsi = to_dsi_data(dssdev);
> +
> +	return (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE);
> +}
> +
> static int dsi_set_config(struct omap_dss_device *dssdev,
> -		const struct omap_dss_dsi_config *config)
> +		const struct drm_display_mode *mode)
> {
> 	struct dsi_data *dsi = to_dsi_data(dssdev);
> 	struct dsi_clk_calc_ctx ctx;
> -	struct omap_dss_dsi_config cfg = *config;
> +	struct videomode vm;
> +	struct omap_dss_dsi_config cfg = dsi->config;
> 	bool ok;
> 	int r;
> 
> +	drm_display_mode_to_videomode(mode, &vm);
> +	cfg.vm = &vm;
> +
> 	mutex_lock(&dsi->lock);
> 
> 	cfg.mode = dsi->mode;
> @@ -4903,9 +4969,15 @@ static ssize_t omap_dsi_host_transfer(struct mipi_dsi_host *host,
> 	int r;
> 
> 	dsi_bus_lock(dsi);
> -	dsi_set_ulps_auto(dsi, false);
> -	r = _omap_dsi_host_transfer(dsi, msg);
> -	dsi_set_ulps_auto(dsi, true);
> +
> +	if (dsi->video_enabled) {
> +		dsi_set_ulps_auto(dsi, false);
> +		r = _omap_dsi_host_transfer(dsi, msg);
> +		dsi_set_ulps_auto(dsi, true);
> +	} else {
> +		r = -EIO;
> +	}
> +
> 	dsi_bus_unlock(dsi);
> 
> 	return r;
> @@ -4926,6 +4998,23 @@ static int dsi_get_clocks(struct dsi_data *dsi)
> 	return 0;
> }
> 
> +static void dsi_set_timings(struct omap_dss_device *dssdev,
> +			    const struct drm_display_mode *mode)
> +{
> +	DSSDBG("dsi_set_timings\n");
> +	dsi_set_config(dssdev, mode);
> +}
> +
> +static int dsi_check_timings(struct omap_dss_device *dssdev,
> +			     struct drm_display_mode *mode)
> +{
> +	DSSDBG("dsi_check_timings\n");
> +
> +	/* TODO */
> +
> +	return 0;
> +}
> +
> static int dsi_connect(struct omap_dss_device *src,
> 		       struct omap_dss_device *dst)
> {
> @@ -4941,16 +5030,15 @@ static void dsi_disconnect(struct omap_dss_device *src,
> static const struct omap_dss_device_ops dsi_ops = {
> 	.connect = dsi_connect,
> 	.disconnect = dsi_disconnect,
> -	.enable = dsi_display_enable,
> -	.disable = dsi_display_disable,
> -
> -	.dsi = {
> -		.set_config = dsi_set_config,
> +	.enable = dsi_enable_video_outputs,
> +	.disable = dsi_disable_video_outputs,
> 
> -		.enable_video_output = dsi_enable_video_output,
> -		.disable_video_output = dsi_disable_video_output,
> +	.check_timings = dsi_check_timings,
> +	.set_timings = dsi_set_timings,
> 
> +	.dsi = {
> 		.update = dsi_update_all,
> +		.is_video_mode = dsi_is_video_mode,
> 	},
> };
> 
> @@ -5038,6 +5126,7 @@ int omap_dsi_host_attach(struct mipi_dsi_host *host,
> {
> 	struct dsi_data *dsi = host_to_omap(host);
> 	unsigned int channel = client->channel;
> +	struct drm_panel *panel;
> 	int r;
> 
> 	if (channel > 3)
> @@ -5050,6 +5139,10 @@ int omap_dsi_host_attach(struct mipi_dsi_host *host,
> 
> 	dsi_bus_lock(dsi);
> 
> +	panel = of_drm_find_panel(client->dev.of_node);
> +	if (IS_ERR(panel))
> +		return PTR_ERR(panel);
> +
> 	atomic_set(&dsi->do_ext_te_update, 0);
> 
> 	if (client->mode_flags & MIPI_DSI_MODE_VIDEO) {
> @@ -5070,8 +5163,12 @@ int omap_dsi_host_attach(struct mipi_dsi_host *host,
> 	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?
> +	dsi->config.lp_clk_max = client->lp_rate;
> +
> 	dsi->ulps_auto_idle = !!(client->mode_flags & MIPI_DSI_MODE_ULPS_IDLE);
> -	dsi_set_ulps_auto(dsi, true);
> 
> 	dsi_bus_unlock(dsi);
> 	return 0;
> diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss-boot-init.c b/drivers/gpu/drm/omapdrm/dss/omapdss-boot-init.c
> index 31502857f013..05ac2e1cd77e 100644
> --- a/drivers/gpu/drm/omapdrm/dss/omapdss-boot-init.c
> +++ b/drivers/gpu/drm/omapdrm/dss/omapdss-boot-init.c
> @@ -176,7 +176,6 @@ static const struct of_device_id omapdss_of_match[] __initconst = {
> static const struct of_device_id omapdss_of_fixups_whitelist[] __initconst = {
> 	{ .compatible = "composite-video-connector" },
> 	{ .compatible = "hdmi-connector" },
> -	{ .compatible = "panel-dsi-cm" },
> 	{ .compatible = "svideo-connector" },
> 	{ .compatible = "ti,opa362" },
> 	{ .compatible = "ti,tpd12s015" },
> diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h
> index 21601af29ee4..bfb402a88475 100644
> --- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
> +++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
> @@ -122,11 +122,6 @@ enum omap_dss_dsi_mode {
> 	OMAP_DSS_DSI_VIDEO_MODE,
> };
> 
> -enum omap_display_caps {
> -	OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE	= 1 << 0,
> -	OMAP_DSS_DISPLAY_CAP_TEAR_ELIM		= 1 << 1,
> -};
> -
> enum omap_dss_display_state {
> 	OMAP_DSS_DISPLAY_DISABLED = 0,
> 	OMAP_DSS_DISPLAY_ACTIVE,
> @@ -288,14 +283,7 @@ struct omapdss_hdmi_ops {
> 
> struct omapdss_dsi_ops {
> 	int (*update)(struct omap_dss_device *dssdev);
> -
> -	/* legacy API used by omapdss panels */
> -	int (*set_config)(struct omap_dss_device *dssdev,
> -			const struct omap_dss_dsi_config *cfg);
> -
> -	int (*enable_video_output)(struct omap_dss_device *dssdev, int channel);
> -	void (*disable_video_output)(struct omap_dss_device *dssdev,
> -			int channel);
> +	bool (*is_video_mode)(struct omap_dss_device *dssdev);
> };
> 
> struct omap_dss_device_ops {
> @@ -374,13 +362,10 @@ struct omap_dss_device {
> 
> 	const char *name;
> 
> -	const struct omap_dss_driver *driver;
> 	const struct omap_dss_device_ops *ops;
> 	unsigned long ops_flags;
> 	u32 bus_flags;
> 
> -	enum omap_display_caps caps;
> -
> 	enum omap_dss_display_state state;
> 
> 	/* OMAP DSS output specific fields */
> @@ -395,11 +380,6 @@ struct omap_dss_device {
> 	unsigned int of_ports;
> };
> 
> -struct omap_dss_driver {
> -	int (*update)(struct omap_dss_device *dssdev,
> -			       u16 x, u16 y, u16 w, u16 h);
> -};
> -
> struct dss_device *omapdss_get_dss(void);
> void omapdss_set_dss(struct dss_device *dss);
> static inline bool omapdss_is_initialized(void)
> diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c
> index a8d0543d1296..80ed1b15ba49 100644
> --- a/drivers/gpu/drm/omapdrm/omap_crtc.c
> +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
> @@ -495,8 +495,7 @@ static enum drm_mode_status omap_crtc_mode_valid(struct drm_crtc *crtc,
> 	 * valid DISPC mode. DSI will calculate and configure the
> 	 * proper DISPC mode later.
> 	 */
> -	if (omap_crtc->pipe->output->next == NULL ||
> -	    omap_crtc->pipe->output->next->type != OMAP_DISPLAY_TYPE_DSI) {
> +	if (omap_crtc->pipe->output->type != OMAP_DISPLAY_TYPE_DSI) {
> 		r = priv->dispc_ops->mgr_check_timings(priv->dispc,
> 						       omap_crtc->channel,
> 						       &vm);
> @@ -548,17 +547,17 @@ static void omap_crtc_mode_set_nofb(struct drm_crtc *crtc)
> static bool omap_crtc_is_manually_updated(struct drm_crtc *crtc)
> {
> 	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
> -	struct omap_dss_device *display = omap_crtc->pipe->output->next;
> +	struct omap_dss_device *dssdev = omap_crtc->pipe->output;
> 
> -	if (!display)
> +	if (dssdev->type != OMAP_DISPLAY_TYPE_DSI ||
> +	    !dssdev->ops->dsi.is_video_mode)
> 		return false;
> 
> -	if (display->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
> -		DBG("detected manually updated display!");
> -		return true;
> -	}
> +	if (dssdev->ops->dsi.is_video_mode(dssdev))
> +		return false;
> 
> -	return false;
> +	DBG("detected manually updated display!");
> +	return true;
> }
> 
> static int omap_crtc_atomic_check(struct drm_crtc *crtc,
> -- 
> 2.24.0
> 

Otherwise the patches compile fine and my work-in progress
DSI panel driver is probing, but not initializing.

BR,
Nikolaus

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

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

* Re: [RFCv1 11/42] ARM: dts: omap: add channel to DSI panels
  2019-11-17  2:39 ` [RFCv1 11/42] ARM: dts: omap: add channel to DSI panels Sebastian Reichel
@ 2019-11-18 13:05   ` Tomi Valkeinen
  2019-11-18 14:33     ` Sebastian Reichel
  0 siblings, 1 reply; 64+ messages in thread
From: Tomi Valkeinen @ 2019-11-18 13:05 UTC (permalink / raw)
  To: Sebastian Reichel, Sebastian Reichel, Laurent Pinchart
  Cc: kernel, Tony Lindgren, H. Nikolaus Schaller, Merlijn Wajer,
	dri-devel, linux-omap

On 17/11/2019 04:39, Sebastian Reichel wrote:
> The standard binding for DSI requires, that the channel number
> of the panel is encoded in DT. This adds the channel number in
> all OMAP3-5 boards, in preparation for using common infrastructure.
> 
> Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
> ---
>   .../devicetree/bindings/display/panel/panel-dsi-cm.txt      | 4 +++-
>   arch/arm/boot/dts/omap3-n950.dts                            | 3 ++-
>   arch/arm/boot/dts/omap3.dtsi                                | 3 +++
>   arch/arm/boot/dts/omap4-droid4-xt894.dts                    | 3 ++-
>   arch/arm/boot/dts/omap4-sdp.dts                             | 6 ++++--
>   arch/arm/boot/dts/omap4.dtsi                                | 6 ++++++
>   arch/arm/boot/dts/omap5.dtsi                                | 6 ++++++
>   7 files changed, 26 insertions(+), 5 deletions(-)

Is this required only in the .txt, or also by the driver? This does 
break backward compatibility with the dtbs, and there's always someone 
who won't like it.

  Tomi

-- 
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

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

* Re: [RFCv1 11/42] ARM: dts: omap: add channel to DSI panels
  2019-11-18 13:05   ` Tomi Valkeinen
@ 2019-11-18 14:33     ` Sebastian Reichel
  2019-11-18 14:37       ` H. Nikolaus Schaller
  0 siblings, 1 reply; 64+ messages in thread
From: Sebastian Reichel @ 2019-11-18 14:33 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: kernel, Tony Lindgren, H. Nikolaus Schaller, Merlijn Wajer,
	dri-devel, Laurent Pinchart, linux-omap


[-- Attachment #1.1: Type: text/plain, Size: 2025 bytes --]

Hi,

On Mon, Nov 18, 2019 at 03:05:07PM +0200, Tomi Valkeinen wrote:
> On 17/11/2019 04:39, Sebastian Reichel wrote:
> > The standard binding for DSI requires, that the channel number
> > of the panel is encoded in DT. This adds the channel number in
> > all OMAP3-5 boards, in preparation for using common infrastructure.
> > 
> > Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
> > ---
> >   .../devicetree/bindings/display/panel/panel-dsi-cm.txt      | 4 +++-
> >   arch/arm/boot/dts/omap3-n950.dts                            | 3 ++-
> >   arch/arm/boot/dts/omap3.dtsi                                | 3 +++
> >   arch/arm/boot/dts/omap4-droid4-xt894.dts                    | 3 ++-
> >   arch/arm/boot/dts/omap4-sdp.dts                             | 6 ++++--
> >   arch/arm/boot/dts/omap4.dtsi                                | 6 ++++++
> >   arch/arm/boot/dts/omap5.dtsi                                | 6 ++++++
> >   7 files changed, 26 insertions(+), 5 deletions(-)
> 
> Is this required only in the .txt, or also by the driver? This does break
> backward compatibility with the dtbs, and there's always someone who won't
> like it.

I add a compatible string for the Droid 4 panel in addition to the
generic one, which is not really required and just a precaution in
case we need some quirks in the future.

But I had to add the DSI channel to DT, which is required to follow
the standard DSI bindings. We cannot use the generic infrastructure
without this change. Technically it should have been there all the
time, it is only working because it is currently hardcoded to 0 in
the panel driver.

TLDR: Yes, it is required by the driver and it does break backward
compatibility for N950 (panel does not yet work on mainline, since
the OMAP3 quirks are missing in the omapdrm DSI code), omap4-sdp (
untested, I do not know if its working) and Droid 4 (known to be
working with current mainline code, most likely people update their
DT anyways).

-- Sebastian

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

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

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

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

* Re: [RFCv1 11/42] ARM: dts: omap: add channel to DSI panels
  2019-11-18 14:33     ` Sebastian Reichel
@ 2019-11-18 14:37       ` H. Nikolaus Schaller
  2019-11-18 15:03         ` Sebastian Reichel
  0 siblings, 1 reply; 64+ messages in thread
From: H. Nikolaus Schaller @ 2019-11-18 14:37 UTC (permalink / raw)
  To: Sebastian Reichel
  Cc: kernel, Tony Lindgren, Merlijn Wajer, dri-devel, Tomi Valkeinen,
	Laurent Pinchart, linux-omap


> Am 18.11.2019 um 15:33 schrieb Sebastian Reichel <sebastian.reichel@collabora.com>:
> 
> Hi,
> 
> On Mon, Nov 18, 2019 at 03:05:07PM +0200, Tomi Valkeinen wrote:
>> On 17/11/2019 04:39, Sebastian Reichel wrote:
>>> The standard binding for DSI requires, that the channel number
>>> of the panel is encoded in DT. This adds the channel number in
>>> all OMAP3-5 boards, in preparation for using common infrastructure.
>>> 
>>> Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
>>> ---
>>>  .../devicetree/bindings/display/panel/panel-dsi-cm.txt      | 4 +++-
>>>  arch/arm/boot/dts/omap3-n950.dts                            | 3 ++-
>>>  arch/arm/boot/dts/omap3.dtsi                                | 3 +++
>>>  arch/arm/boot/dts/omap4-droid4-xt894.dts                    | 3 ++-
>>>  arch/arm/boot/dts/omap4-sdp.dts                             | 6 ++++--
>>>  arch/arm/boot/dts/omap4.dtsi                                | 6 ++++++
>>>  arch/arm/boot/dts/omap5.dtsi                                | 6 ++++++
>>>  7 files changed, 26 insertions(+), 5 deletions(-)
>> 
>> Is this required only in the .txt, or also by the driver? This does break
>> backward compatibility with the dtbs, and there's always someone who won't
>> like it.
> 
> I add a compatible string for the Droid 4 panel in addition to the
> generic one, which is not really required and just a precaution in
> case we need some quirks in the future.
> 
> But I had to add the DSI channel to DT, which is required to follow
> the standard DSI bindings. We cannot use the generic infrastructure
> without this change. Technically it should have been there all the
> time, it is only working because it is currently hardcoded to 0 in
> the panel driver.

Is it possible to change it to default to channel <0> if reg is not
specified?

> 
> TLDR: Yes, it is required by the driver and it does break backward
> compatibility for N950 (panel does not yet work on mainline, since
> the OMAP3 quirks are missing in the omapdrm DSI code), omap4-sdp (
> untested, I do not know if its working) and Droid 4 (known to be
> working with current mainline code, most likely people update their
> DT anyways).
> 
> -- Sebastian

BR,
Nikolaus

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

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

* Re: [RFCv1 32/42] drm/omap: dsi: convert to drm_panel
  2019-11-17 19:23   ` H. Nikolaus Schaller
@ 2019-11-18 14:45     ` Sebastian Reichel
  2019-11-18 14:51       ` H. Nikolaus Schaller
  0 siblings, 1 reply; 64+ messages in thread
From: Sebastian Reichel @ 2019-11-18 14:45 UTC (permalink / raw)
  To: H. Nikolaus Schaller
  Cc: kernel, Tony Lindgren, Merlijn Wajer, dri-devel, Tomi Valkeinen,
	Laurent Pinchart, linux-omap


[-- Attachment #1.1: Type: text/plain, Size: 1223 bytes --]

Hi,

On Sun, Nov 17, 2019 at 08:23:05PM +0100, H. Nikolaus Schaller wrote:
> > [...]
>
> > +	drm_panel_init(&ddata->panel, dev, &dsicm_panel_funcs,
> > +		       DRM_MODE_CONNECTOR_DSI);
> > +
> 
> This leads to
> 
> drivers/gpu/drm/panel/panel-dsi-cm.c: In function 'dsicm_probe':
> drivers/gpu/drm/panel/panel-dsi-cm.c:552:2: error: too many arguments to function 'drm_panel_init'
>   drm_panel_init(&ddata->panel, dev, &dsicm_panel_funcs,
>   ^
> In file included from drivers/gpu/drm/panel/panel-dsi-cm.c:22:0:
> ./include/drm/drm_panel.h:150:6: note: declared here
>  void drm_panel_init(struct drm_panel *panel);
>       ^
> 
> (when applied to v5.4-rc7)

The patchset is based on drm-next from
https://anongit.freedesktop.org/git/drm/drm.git

For v5.4-rc7 it needs to look like this:

+	drm_panel_init(&ddata->panel);
+	ddata->panel.dev = dev;
+	ddata->panel.funcs = &dsicm_panel_funcs;

> > [...] 
> 
> Otherwise the patches compile fine and my work-in progress
> DSI panel driver is probing, but not initializing.

Ok, I tried not to break video mode support, but I do not have any
hardware. Make sure to set the MIPI_DSI_MODE_VIDEO flag in the panel
driver.

-- Sebastian

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

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

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

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

* Re: [RFCv1 32/42] drm/omap: dsi: convert to drm_panel
  2019-11-18 14:45     ` Sebastian Reichel
@ 2019-11-18 14:51       ` H. Nikolaus Schaller
  2019-11-19  9:42         ` H. Nikolaus Schaller
  0 siblings, 1 reply; 64+ messages in thread
From: H. Nikolaus Schaller @ 2019-11-18 14:51 UTC (permalink / raw)
  To: Sebastian Reichel
  Cc: kernel, Tony Lindgren, Merlijn Wajer, dri-devel, Tomi Valkeinen,
	Laurent Pinchart, linux-omap


> Am 18.11.2019 um 15:45 schrieb Sebastian Reichel <sebastian.reichel@collabora.com>:
> 
> Hi,
> 
> On Sun, Nov 17, 2019 at 08:23:05PM +0100, H. Nikolaus Schaller wrote:
>>> [...]
>> 
>>> +	drm_panel_init(&ddata->panel, dev, &dsicm_panel_funcs,
>>> +		       DRM_MODE_CONNECTOR_DSI);
>>> +
>> 
>> This leads to
>> 
>> drivers/gpu/drm/panel/panel-dsi-cm.c: In function 'dsicm_probe':
>> drivers/gpu/drm/panel/panel-dsi-cm.c:552:2: error: too many arguments to function 'drm_panel_init'
>>  drm_panel_init(&ddata->panel, dev, &dsicm_panel_funcs,
>>  ^
>> In file included from drivers/gpu/drm/panel/panel-dsi-cm.c:22:0:
>> ./include/drm/drm_panel.h:150:6: note: declared here
>> void drm_panel_init(struct drm_panel *panel);
>>      ^
>> 
>> (when applied to v5.4-rc7)
> 
> The patchset is based on drm-next from
> https://anongit.freedesktop.org/git/drm/drm.git
> 
> For v5.4-rc7 it needs to look like this:
> 
> +	drm_panel_init(&ddata->panel);
> +	ddata->panel.dev = dev;
> +	ddata->panel.funcs = &dsicm_panel_funcs;

Ah, ok. The issue with changed parameters seems
to already be fixed by two patches in linux-next
and therefore soon in v5.5-rc1.

> 
>>> [...] 
>> 
>> Otherwise the patches compile fine and my work-in progress
>> DSI panel driver is probing, but not initializing.
> 
> Ok, I tried not to break video mode support, but I do not have any
> hardware. Make sure to set the MIPI_DSI_MODE_VIDEO flag in the panel
> driver.

Indeed, this may be missing (can't look into the code at the moment)...
Or I did something wrong when refactoring the driver.
We will find out.

BR and thanks for the great work,
Nikolaus


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

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

* Re: [RFCv1 11/42] ARM: dts: omap: add channel to DSI panels
  2019-11-18 14:37       ` H. Nikolaus Schaller
@ 2019-11-18 15:03         ` Sebastian Reichel
  2019-11-18 22:52           ` Tony Lindgren
  0 siblings, 1 reply; 64+ messages in thread
From: Sebastian Reichel @ 2019-11-18 15:03 UTC (permalink / raw)
  To: H. Nikolaus Schaller
  Cc: kernel, Tony Lindgren, Merlijn Wajer, dri-devel, Tomi Valkeinen,
	Laurent Pinchart, linux-omap


[-- Attachment #1.1: Type: text/plain, Size: 2793 bytes --]

Hi,

On Mon, Nov 18, 2019 at 03:37:12PM +0100, H. Nikolaus Schaller wrote:
> > Am 18.11.2019 um 15:33 schrieb Sebastian Reichel <sebastian.reichel@collabora.com>:
> > On Mon, Nov 18, 2019 at 03:05:07PM +0200, Tomi Valkeinen wrote:
> >> On 17/11/2019 04:39, Sebastian Reichel wrote:
> >>> The standard binding for DSI requires, that the channel number
> >>> of the panel is encoded in DT. This adds the channel number in
> >>> all OMAP3-5 boards, in preparation for using common infrastructure.
> >>> 
> >>> Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
> >>> ---
> >>>  .../devicetree/bindings/display/panel/panel-dsi-cm.txt      | 4 +++-
> >>>  arch/arm/boot/dts/omap3-n950.dts                            | 3 ++-
> >>>  arch/arm/boot/dts/omap3.dtsi                                | 3 +++
> >>>  arch/arm/boot/dts/omap4-droid4-xt894.dts                    | 3 ++-
> >>>  arch/arm/boot/dts/omap4-sdp.dts                             | 6 ++++--
> >>>  arch/arm/boot/dts/omap4.dtsi                                | 6 ++++++
> >>>  arch/arm/boot/dts/omap5.dtsi                                | 6 ++++++
> >>>  7 files changed, 26 insertions(+), 5 deletions(-)
> >> 
> >> Is this required only in the .txt, or also by the driver? This does break
> >> backward compatibility with the dtbs, and there's always someone who won't
> >> like it.
> > 
> > I add a compatible string for the Droid 4 panel in addition to the
> > generic one, which is not really required and just a precaution in
> > case we need some quirks in the future.
> > 
> > But I had to add the DSI channel to DT, which is required to follow
> > the standard DSI bindings. We cannot use the generic infrastructure
> > without this change. Technically it should have been there all the
> > time, it is only working because it is currently hardcoded to 0 in
> > the panel driver.
> 
> Is it possible to change it to default to channel <0> if reg is not
> specified?

Currently nodes without reg property are skipped by of_mipi_dsi_device_add()
and of_mipi_dsi_device_add() fails if reg node is missing. Technically
it should be possible to default to channel 0 there. That affects all
platforms, though. Considering the small amount of boards affected, I think
its better to just fix the DT. Also the fixed DT does not make problems
with older kernels and can be backported.

> > TLDR: Yes, it is required by the driver and it does break backward
> > compatibility for N950 (panel does not yet work on mainline, since
> > the OMAP3 quirks are missing in the omapdrm DSI code), omap4-sdp (
> > untested, I do not know if its working) and Droid 4 (known to be
> > working with current mainline code, most likely people update their
> > DT anyways).

-- Sebastian

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

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

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

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

* Re: [RFCv1 11/42] ARM: dts: omap: add channel to DSI panels
  2019-11-18 15:03         ` Sebastian Reichel
@ 2019-11-18 22:52           ` Tony Lindgren
  2019-11-19 21:23             ` Sebastian Reichel
  0 siblings, 1 reply; 64+ messages in thread
From: Tony Lindgren @ 2019-11-18 22:52 UTC (permalink / raw)
  To: Sebastian Reichel
  Cc: kernel, H. Nikolaus Schaller, Merlijn Wajer, dri-devel,
	Tomi Valkeinen, Laurent Pinchart, linux-omap

* Sebastian Reichel <sebastian.reichel@collabora.com> [191118 15:03]:
> On Mon, Nov 18, 2019 at 03:37:12PM +0100, H. Nikolaus Schaller wrote:
> > > Am 18.11.2019 um 15:33 schrieb Sebastian Reichel <sebastian.reichel@collabora.com>:
> > > On Mon, Nov 18, 2019 at 03:05:07PM +0200, Tomi Valkeinen wrote:
> > >> On 17/11/2019 04:39, Sebastian Reichel wrote:
> > >>> The standard binding for DSI requires, that the channel number
> > >>> of the panel is encoded in DT. This adds the channel number in
> > >>> all OMAP3-5 boards, in preparation for using common infrastructure.
> > >>> 
> > >>> Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
> > >>> ---
> > >>>  .../devicetree/bindings/display/panel/panel-dsi-cm.txt      | 4 +++-
> > >>>  arch/arm/boot/dts/omap3-n950.dts                            | 3 ++-
> > >>>  arch/arm/boot/dts/omap3.dtsi                                | 3 +++
> > >>>  arch/arm/boot/dts/omap4-droid4-xt894.dts                    | 3 ++-
> > >>>  arch/arm/boot/dts/omap4-sdp.dts                             | 6 ++++--
> > >>>  arch/arm/boot/dts/omap4.dtsi                                | 6 ++++++
> > >>>  arch/arm/boot/dts/omap5.dtsi                                | 6 ++++++
> > >>>  7 files changed, 26 insertions(+), 5 deletions(-)
> > >> 
> > >> Is this required only in the .txt, or also by the driver? This does break
> > >> backward compatibility with the dtbs, and there's always someone who won't
> > >> like it.
> > > 
> > > I add a compatible string for the Droid 4 panel in addition to the
> > > generic one, which is not really required and just a precaution in
> > > case we need some quirks in the future.
> > > 
> > > But I had to add the DSI channel to DT, which is required to follow
> > > the standard DSI bindings. We cannot use the generic infrastructure
> > > without this change. Technically it should have been there all the
> > > time, it is only working because it is currently hardcoded to 0 in
> > > the panel driver.
> > 
> > Is it possible to change it to default to channel <0> if reg is not
> > specified?
> 
> Currently nodes without reg property are skipped by of_mipi_dsi_device_add()
> and of_mipi_dsi_device_add() fails if reg node is missing. Technically
> it should be possible to default to channel 0 there. That affects all
> platforms, though. Considering the small amount of boards affected, I think
> its better to just fix the DT. Also the fixed DT does not make problems
> with older kernels and can be backported.

You might be able to do a local fixup at driver probe time using
of_add_property(). See for example pcs_quirk_missing_pinctrl_cells()
I added earlier because of similar issues.

Regards,

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

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

* Re: [RFCv1 33/42] drm/omap: dsi: use atomic helper for dirtyfb
  2019-11-17  2:40 ` [RFCv1 33/42] drm/omap: dsi: use atomic helper for dirtyfb Sebastian Reichel
@ 2019-11-18 23:05   ` Tony Lindgren
  2019-11-19  5:42     ` Tomi Valkeinen
  0 siblings, 1 reply; 64+ messages in thread
From: Tony Lindgren @ 2019-11-18 23:05 UTC (permalink / raw)
  To: Sebastian Reichel
  Cc: kernel, H. Nikolaus Schaller, Merlijn Wajer, Sebastian Reichel,
	dri-devel, Tomi Valkeinen, Laurent Pinchart, linux-omap

* Sebastian Reichel <sebastian.reichel@collabora.com> [191117 07:11]:
> We can simply use the atomic helper for
> handling the dirtyfb callback.
...
> --- a/drivers/gpu/drm/omapdrm/omap_crtc.c
> +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
> -void omap_crtc_flush(struct drm_crtc *crtc)
> +static void omap_crtc_flush(struct drm_crtc *crtc)
>  {
>  	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
> -	struct omap_crtc_state *omap_state = to_omap_crtc_state(crtc->state);
> -
> -	if (!omap_state->manually_updated)
> -		return;
>  
>  	if (!delayed_work_pending(&omap_crtc->update_work))
>  		schedule_delayed_work(&omap_crtc->update_work, 0);

It would be nice if omap_crtc_flush() would become just some generic
void function with no need to pass it a crtc. I guess for that it
should know what panels are in manual command mode to refresh them.

The reason I'm bringing this up is because it looks like we need
to also flush DSI command mode panels from omap_gem_op_finish()
for gles and the gem code probably should not need to know anything
about crtc, right?

Or maybe there is some better place to call it?

Regards,

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

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

* Re: [RFCv1 33/42] drm/omap: dsi: use atomic helper for dirtyfb
  2019-11-18 23:05   ` Tony Lindgren
@ 2019-11-19  5:42     ` Tomi Valkeinen
  2019-11-19 14:32       ` Tony Lindgren
  0 siblings, 1 reply; 64+ messages in thread
From: Tomi Valkeinen @ 2019-11-19  5:42 UTC (permalink / raw)
  To: Tony Lindgren, Sebastian Reichel
  Cc: kernel, H. Nikolaus Schaller, Merlijn Wajer, Sebastian Reichel,
	dri-devel, Laurent Pinchart, linux-omap

On 19/11/2019 01:05, Tony Lindgren wrote:
> * Sebastian Reichel <sebastian.reichel@collabora.com> [191117 07:11]:
>> We can simply use the atomic helper for
>> handling the dirtyfb callback.
> ...
>> --- a/drivers/gpu/drm/omapdrm/omap_crtc.c
>> +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
>> -void omap_crtc_flush(struct drm_crtc *crtc)
>> +static void omap_crtc_flush(struct drm_crtc *crtc)
>>   {
>>   	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
>> -	struct omap_crtc_state *omap_state = to_omap_crtc_state(crtc->state);
>> -
>> -	if (!omap_state->manually_updated)
>> -		return;
>>   
>>   	if (!delayed_work_pending(&omap_crtc->update_work))
>>   		schedule_delayed_work(&omap_crtc->update_work, 0);
> 
> It would be nice if omap_crtc_flush() would become just some generic
> void function with no need to pass it a crtc. I guess for that it
> should know what panels are in manual command mode to refresh them.
> 
> The reason I'm bringing this up is because it looks like we need
> to also flush DSI command mode panels from omap_gem_op_finish()
> for gles and the gem code probably should not need to know anything
> about crtc, right?

We haven't had omap_gem_op_finish() in the kernel for some years now...

Shouldn't a normal page flip, or if doing single-buffering, using the 
dirtyfb ioctl, do the job?

  Tomi

-- 
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

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

* Re: [RFCv1 32/42] drm/omap: dsi: convert to drm_panel
  2019-11-18 14:51       ` H. Nikolaus Schaller
@ 2019-11-19  9:42         ` H. Nikolaus Schaller
  2019-11-19 21:21           ` Sebastian Reichel
  0 siblings, 1 reply; 64+ messages in thread
From: H. Nikolaus Schaller @ 2019-11-19  9:42 UTC (permalink / raw)
  To: Sebastian Reichel
  Cc: kernel, Tony Lindgren, Merlijn Wajer, dri-devel, Tomi Valkeinen,
	Laurent Pinchart, linux-omap

Hi Sebastian,

> Am 18.11.2019 um 15:51 schrieb H. Nikolaus Schaller <hns@goldelico.com>:
> 
>> Ok, I tried not to break video mode support, but I do not have any
>> hardware. Make sure to set the MIPI_DSI_MODE_VIDEO flag in the panel
>> driver.
> 
> Indeed, this may be missing (can't look into the code at the moment)...
> Or I did something wrong when refactoring the driver.
> We will find out.

Yes, MIPI_DSI_MODE_VIDEO was indeed missing/wrongly applied and some
more bugs. But I still wasn't able to make it work.

I also tried to fake the panel-orisetech-otm8009a.c DSI driver into
my setup. It should not properly program the panel by DCS command
but it should try to.

Result is the same: I can see it being probed and calling get_modes
but then:

[drm] Cannot find any crtc or sizes

And I don't see calls to .enable or .prepare where DCS commands would
be sent.

BR and thanks,
Nikolaus

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

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

* Re: [RFCv1 33/42] drm/omap: dsi: use atomic helper for dirtyfb
  2019-11-19  5:42     ` Tomi Valkeinen
@ 2019-11-19 14:32       ` Tony Lindgren
  2019-11-19 14:53         ` Tomi Valkeinen
  0 siblings, 1 reply; 64+ messages in thread
From: Tony Lindgren @ 2019-11-19 14:32 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: kernel, H. Nikolaus Schaller, Merlijn Wajer, Sebastian Reichel,
	dri-devel, Sebastian Reichel, Laurent Pinchart, linux-omap

* Tomi Valkeinen <tomi.valkeinen@ti.com> [191119 05:42]:
> On 19/11/2019 01:05, Tony Lindgren wrote:
> > * Sebastian Reichel <sebastian.reichel@collabora.com> [191117 07:11]:
> > > We can simply use the atomic helper for
> > > handling the dirtyfb callback.
> > ...
> > > --- a/drivers/gpu/drm/omapdrm/omap_crtc.c
> > > +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
> > > -void omap_crtc_flush(struct drm_crtc *crtc)
> > > +static void omap_crtc_flush(struct drm_crtc *crtc)
> > >   {
> > >   	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
> > > -	struct omap_crtc_state *omap_state = to_omap_crtc_state(crtc->state);
> > > -
> > > -	if (!omap_state->manually_updated)
> > > -		return;
> > >   	if (!delayed_work_pending(&omap_crtc->update_work))
> > >   		schedule_delayed_work(&omap_crtc->update_work, 0);
> > 
> > It would be nice if omap_crtc_flush() would become just some generic
> > void function with no need to pass it a crtc. I guess for that it
> > should know what panels are in manual command mode to refresh them.

Proably still cannot be a void function, but seems like we need to
call something outside omap_crtc.c.

> > The reason I'm bringing this up is because it looks like we need
> > to also flush DSI command mode panels from omap_gem_op_finish()
> > for gles and the gem code probably should not need to know anything
> > about crtc, right?
> 
> We haven't had omap_gem_op_finish() in the kernel for some years now...
> 
> Shouldn't a normal page flip, or if doing single-buffering, using the
> dirtyfb ioctl, do the job?

It does not seem to happen with the old pvr-omap4 related patches
and whatever gles related tests at least. If you have some idea
where it should get called I can take a look at some point.

Regards,

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

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

* Re: [RFCv1 33/42] drm/omap: dsi: use atomic helper for dirtyfb
  2019-11-19 14:32       ` Tony Lindgren
@ 2019-11-19 14:53         ` Tomi Valkeinen
  2019-11-19 15:06           ` Tony Lindgren
  0 siblings, 1 reply; 64+ messages in thread
From: Tomi Valkeinen @ 2019-11-19 14:53 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: kernel, H. Nikolaus Schaller, Merlijn Wajer, Sebastian Reichel,
	dri-devel, Sebastian Reichel, Laurent Pinchart, linux-omap

On 19/11/2019 16:32, Tony Lindgren wrote:

>> We haven't had omap_gem_op_finish() in the kernel for some years now...
>>
>> Shouldn't a normal page flip, or if doing single-buffering, using the
>> dirtyfb ioctl, do the job?
> 
> It does not seem to happen with the old pvr-omap4 related patches
> and whatever gles related tests at least. If you have some idea
> where it should get called I can take a look at some point.

The userspace apps need to do this. If they're using single-buffering, 
then using the dirtyfb ioctl should do the trick, after the SGX has 
finished drawing.

It's probably somewhat difficult if EGL is controlling the display, as, 
afaik, SGX EGL is closed source, and that's probably where it should be 
done.

But adding back the hacky omap gem sync stuff, and then somehow guessing 
from the sync finish that some display needs to be updated... It just 
does not sound right to me.

  Tomi

-- 
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

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

* Re: [RFCv1 33/42] drm/omap: dsi: use atomic helper for dirtyfb
  2019-11-19 14:53         ` Tomi Valkeinen
@ 2019-11-19 15:06           ` Tony Lindgren
  2019-11-19 15:55             ` Tomi Valkeinen
  0 siblings, 1 reply; 64+ messages in thread
From: Tony Lindgren @ 2019-11-19 15:06 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: kernel, H. Nikolaus Schaller, Merlijn Wajer, Sebastian Reichel,
	dri-devel, Sebastian Reichel, Laurent Pinchart, linux-omap

* Tomi Valkeinen <tomi.valkeinen@ti.com> [191119 14:54]:
> On 19/11/2019 16:32, Tony Lindgren wrote:
> 
> > > We haven't had omap_gem_op_finish() in the kernel for some years now...
> > > 
> > > Shouldn't a normal page flip, or if doing single-buffering, using the
> > > dirtyfb ioctl, do the job?
> > 
> > It does not seem to happen with the old pvr-omap4 related patches
> > and whatever gles related tests at least. If you have some idea
> > where it should get called I can take a look at some point.
> 
> The userspace apps need to do this. If they're using single-buffering, then
> using the dirtyfb ioctl should do the trick, after the SGX has finished
> drawing.

Sounds like that's not happening.

But why would the userspace app need to know this might be needed for
a DSI command mode display and that it's not needed for HDMI?

> It's probably somewhat difficult if EGL is controlling the display, as,
> afaik, SGX EGL is closed source, and that's probably where it should be
> done.
> 
> But adding back the hacky omap gem sync stuff, and then somehow guessing
> from the sync finish that some display needs to be updated... It just does
> not sound right to me.

Right it's ugly. Still sounds like we need something in the kernel
that knows "this is a DSI command mode LCD and needs to be updated".

Regards,

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

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

* Re: [RFCv1 33/42] drm/omap: dsi: use atomic helper for dirtyfb
  2019-11-19 15:06           ` Tony Lindgren
@ 2019-11-19 15:55             ` Tomi Valkeinen
  2019-11-19 18:46               ` Andreas Kemnade
  2019-11-20  3:48               ` Tony Lindgren
  0 siblings, 2 replies; 64+ messages in thread
From: Tomi Valkeinen @ 2019-11-19 15:55 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: kernel, H. Nikolaus Schaller, Merlijn Wajer, Sebastian Reichel,
	dri-devel, Sebastian Reichel, Laurent Pinchart, linux-omap

On 19/11/2019 17:06, Tony Lindgren wrote:

>> The userspace apps need to do this. If they're using single-buffering, then
>> using the dirtyfb ioctl should do the trick, after the SGX has finished
>> drawing.
> 
> Sounds like that's not happening.
> 
> But why would the userspace app need to know this might be needed for
> a DSI command mode display and that it's not needed for HDMI?

When double-buffering, the userspace doesn't need to care, as the 
page-flip ioctl explicitly tells that the buffer is ready.

When single buffering, either the userspace has to tell that the buffer 
is now ready, or the kernel has to guess based on something. But afaics, 
the latter is always a guess, and may not be a good guess.

The kernel could trigger a delayed update based on, say, page fault if 
drawing with CPU. But how much delayed... And with this scenario, we 
would somehow need to find a way to catch the writes from any IP to the 
buffer, and afaik there's no such thing.

>> It's probably somewhat difficult if EGL is controlling the display, as,
>> afaik, SGX EGL is closed source, and that's probably where it should be
>> done.
>>
>> But adding back the hacky omap gem sync stuff, and then somehow guessing
>> from the sync finish that some display needs to be updated... It just does
>> not sound right to me.
> 
> Right it's ugly. Still sounds like we need something in the kernel
> that knows "this is a DSI command mode LCD and needs to be updated".

I think one option is to refresh the command mode display all the time. 
Either using a timer, or trigger updates based on the previous update 
being finished.

Of course, that's kind of against the whole point of manual update 
display, but then it should effectively behave like a conventional 
always-updating display (except your HW is more expensive and consumes 
more power than a conventional display).

There's this Panel Self Refresh feature in DisplayPort (which I think is 
implemented in drm_self_refresh_helper.c), which has some similarities 
to this case. But if I read it right, that also expects some kind of 
trigger from userspace (any DRM commit) to start the refresh.

Afaik, Weston and X both handle page flips and/or dirtying the fb, so 
they should work. Are there applications that do not work, and cannot be 
made to work, except the few SGX test apps?

  Tomi

-- 
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

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

* Re: [RFCv1 33/42] drm/omap: dsi: use atomic helper for dirtyfb
  2019-11-19 15:55             ` Tomi Valkeinen
@ 2019-11-19 18:46               ` Andreas Kemnade
  2019-11-19 21:15                 ` Sebastian Reichel
  2019-11-20  3:48               ` Tony Lindgren
  1 sibling, 1 reply; 64+ messages in thread
From: Andreas Kemnade @ 2019-11-19 18:46 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: kernel, Tony Lindgren, H. Nikolaus Schaller, Merlijn Wajer,
	Sebastian Reichel, dri-devel, Sebastian Reichel,
	Laurent Pinchart, linux-omap

On Tue, 19 Nov 2019 17:55:57 +0200
Tomi Valkeinen <tomi.valkeinen@ti.com> wrote:

> On 19/11/2019 17:06, Tony Lindgren wrote:
> 
> >> The userspace apps need to do this. If they're using single-buffering, then
> >> using the dirtyfb ioctl should do the trick, after the SGX has finished
> >> drawing.  
> > 
> > Sounds like that's not happening.
> > 
> > But why would the userspace app need to know this might be needed for
> > a DSI command mode display and that it's not needed for HDMI?  
> 
> When double-buffering, the userspace doesn't need to care, as the 
> page-flip ioctl explicitly tells that the buffer is ready.
> 
> When single buffering, either the userspace has to tell that the buffer 
> is now ready, or the kernel has to guess based on something. But afaics, 
> the latter is always a guess, and may not be a good guess.
> 
> The kernel could trigger a delayed update based on, say, page fault if 
> drawing with CPU. But how much delayed... And with this scenario, we 
> would somehow need to find a way to catch the writes from any IP to the 
> buffer, and afaik there's no such thing.
> 
> >> It's probably somewhat difficult if EGL is controlling the display, as,
> >> afaik, SGX EGL is closed source, and that's probably where it should be
> >> done.
> >>
> >> But adding back the hacky omap gem sync stuff, and then somehow guessing
> >> from the sync finish that some display needs to be updated... It just does
> >> not sound right to me.  
> > 
> > Right it's ugly. Still sounds like we need something in the kernel
> > that knows "this is a DSI command mode LCD and needs to be updated".  
> 
well, if we look broader around and not only at the remaining displays
to be converted from omapdrm to generic and look at more displays, there
are also EPDs.

> I think one option is to refresh the command mode display all the time. 
> Either using a timer, or trigger updates based on the previous update 
> being finished.
> 
> Of course, that's kind of against the whole point of manual update 
> display, but then it should effectively behave like a conventional 
> always-updating display (except your HW is more expensive and consumes 
> more power than a conventional display).
> 
And again as an extreme example about power consumption: EPDs.
So I guess we need a generic interface for userspace-triggered
refreshes anyways. And in that case that are only partly refreshes.

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

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

* Re: [RFCv1 33/42] drm/omap: dsi: use atomic helper for dirtyfb
  2019-11-19 18:46               ` Andreas Kemnade
@ 2019-11-19 21:15                 ` Sebastian Reichel
  0 siblings, 0 replies; 64+ messages in thread
From: Sebastian Reichel @ 2019-11-19 21:15 UTC (permalink / raw)
  To: Andreas Kemnade
  Cc: kernel, Tony Lindgren, H. Nikolaus Schaller, Merlijn Wajer,
	dri-devel, Tomi Valkeinen, Laurent Pinchart, linux-omap


[-- Attachment #1.1: Type: text/plain, Size: 3203 bytes --]

Hi,

On Tue, Nov 19, 2019 at 07:46:28PM +0100, Andreas Kemnade wrote:
> On Tue, 19 Nov 2019 17:55:57 +0200
> Tomi Valkeinen <tomi.valkeinen@ti.com> wrote:
> 
> > On 19/11/2019 17:06, Tony Lindgren wrote:
> > 
> > >> The userspace apps need to do this. If they're using single-buffering, then
> > >> using the dirtyfb ioctl should do the trick, after the SGX has finished
> > >> drawing.  
> > > 
> > > Sounds like that's not happening.
> > > 
> > > But why would the userspace app need to know this might be needed for
> > > a DSI command mode display and that it's not needed for HDMI?  
> > 
> > When double-buffering, the userspace doesn't need to care, as the 
> > page-flip ioctl explicitly tells that the buffer is ready.
> > 
> > When single buffering, either the userspace has to tell that the buffer 
> > is now ready, or the kernel has to guess based on something. But afaics, 
> > the latter is always a guess, and may not be a good guess.
> > 
> > The kernel could trigger a delayed update based on, say, page fault if 
> > drawing with CPU. But how much delayed... And with this scenario, we 
> > would somehow need to find a way to catch the writes from any IP to the 
> > buffer, and afaik there's no such thing.
> > 
> > >> It's probably somewhat difficult if EGL is controlling the display, as,
> > >> afaik, SGX EGL is closed source, and that's probably where it should be
> > >> done.
> > >>
> > >> But adding back the hacky omap gem sync stuff, and then somehow guessing
> > >> from the sync finish that some display needs to be updated... It just does
> > >> not sound right to me.  
> > > 
> > > Right it's ugly. Still sounds like we need something in the kernel
> > > that knows "this is a DSI command mode LCD and needs to be updated".  
> > 
> well, if we look broader around and not only at the remaining displays
> to be converted from omapdrm to generic and look at more displays, there
> are also EPDs.
> 
> > I think one option is to refresh the command mode display all the time. 
> > Either using a timer, or trigger updates based on the previous update 
> > being finished.
> > 
> > Of course, that's kind of against the whole point of manual update 
> > display, but then it should effectively behave like a conventional 
> > always-updating display (except your HW is more expensive and consumes 
> > more power than a conventional display).
> > 
> And again as an extreme example about power consumption: EPDs.
> So I guess we need a generic interface for userspace-triggered
> refreshes anyways. And in that case that are only partly refreshes.

You can do exactly this using the dirtyfb ioctl, which tells the
kernel, that some parts of the framebuffer are "dirty" and should
be send to the hardware. This is being used by the kernel console
and X.org. For omapdrm this triggers a full refresh of DSI command
mode panels.

The second method (which only supports full framebuffer for obvious
reasons) is double buffering. If you toggle from first to second
framebuffer, the driver will send the framebuffer to hardware. This
is being used by Weston when the DRM backend is selected.

-- Sebastian

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

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

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

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

* Re: [RFCv1 32/42] drm/omap: dsi: convert to drm_panel
  2019-11-19  9:42         ` H. Nikolaus Schaller
@ 2019-11-19 21:21           ` Sebastian Reichel
  0 siblings, 0 replies; 64+ messages in thread
From: Sebastian Reichel @ 2019-11-19 21:21 UTC (permalink / raw)
  To: H. Nikolaus Schaller
  Cc: kernel, Tony Lindgren, Merlijn Wajer, dri-devel, Tomi Valkeinen,
	Laurent Pinchart, linux-omap


[-- Attachment #1.1: Type: text/plain, Size: 1314 bytes --]

Hi Nikolaus,

On Tue, Nov 19, 2019 at 10:42:55AM +0100, H. Nikolaus Schaller wrote:
> > Am 18.11.2019 um 15:51 schrieb H. Nikolaus Schaller <hns@goldelico.com>:
> > 
> >> Ok, I tried not to break video mode support, but I do not have any
> >> hardware. Make sure to set the MIPI_DSI_MODE_VIDEO flag in the panel
> >> driver.
> > 
> > Indeed, this may be missing (can't look into the code at the moment)...
> > Or I did something wrong when refactoring the driver.
> > We will find out.
> 
> Yes, MIPI_DSI_MODE_VIDEO was indeed missing/wrongly applied and some
> more bugs. But I still wasn't able to make it work.
> 
> I also tried to fake the panel-orisetech-otm8009a.c DSI driver into
> my setup. It should not properly program the panel by DCS command
> but it should try to.
> 
> Result is the same: I can see it being probed and calling get_modes
> but then:
> 
> [drm] Cannot find any crtc or sizes
> 
> And I don't see calls to .enable or .prepare where DCS commands would
> be sent.

You probably want to enable all kind of drm debugging to get more
information. I guess, that some timing check fails, e.g.
dsi_check_timings(). If the timing checks fail, the mode will not
be added as valid mode. When no valid mode is found, the panel
will not be enabled.

-- Sebastian

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

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

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

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

* Re: [RFCv1 11/42] ARM: dts: omap: add channel to DSI panels
  2019-11-18 22:52           ` Tony Lindgren
@ 2019-11-19 21:23             ` Sebastian Reichel
  0 siblings, 0 replies; 64+ messages in thread
From: Sebastian Reichel @ 2019-11-19 21:23 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: kernel, H. Nikolaus Schaller, Merlijn Wajer, dri-devel,
	Tomi Valkeinen, Laurent Pinchart, linux-omap


[-- Attachment #1.1: Type: text/plain, Size: 3051 bytes --]

Hi Tony,

On Mon, Nov 18, 2019 at 02:52:09PM -0800, Tony Lindgren wrote:
> * Sebastian Reichel <sebastian.reichel@collabora.com> [191118 15:03]:
> > On Mon, Nov 18, 2019 at 03:37:12PM +0100, H. Nikolaus Schaller wrote:
> > > > Am 18.11.2019 um 15:33 schrieb Sebastian Reichel <sebastian.reichel@collabora.com>:
> > > > On Mon, Nov 18, 2019 at 03:05:07PM +0200, Tomi Valkeinen wrote:
> > > >> On 17/11/2019 04:39, Sebastian Reichel wrote:
> > > >>> The standard binding for DSI requires, that the channel number
> > > >>> of the panel is encoded in DT. This adds the channel number in
> > > >>> all OMAP3-5 boards, in preparation for using common infrastructure.
> > > >>> 
> > > >>> Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
> > > >>> ---
> > > >>>  .../devicetree/bindings/display/panel/panel-dsi-cm.txt      | 4 +++-
> > > >>>  arch/arm/boot/dts/omap3-n950.dts                            | 3 ++-
> > > >>>  arch/arm/boot/dts/omap3.dtsi                                | 3 +++
> > > >>>  arch/arm/boot/dts/omap4-droid4-xt894.dts                    | 3 ++-
> > > >>>  arch/arm/boot/dts/omap4-sdp.dts                             | 6 ++++--
> > > >>>  arch/arm/boot/dts/omap4.dtsi                                | 6 ++++++
> > > >>>  arch/arm/boot/dts/omap5.dtsi                                | 6 ++++++
> > > >>>  7 files changed, 26 insertions(+), 5 deletions(-)
> > > >> 
> > > >> Is this required only in the .txt, or also by the driver? This does break
> > > >> backward compatibility with the dtbs, and there's always someone who won't
> > > >> like it.
> > > > 
> > > > I add a compatible string for the Droid 4 panel in addition to the
> > > > generic one, which is not really required and just a precaution in
> > > > case we need some quirks in the future.
> > > > 
> > > > But I had to add the DSI channel to DT, which is required to follow
> > > > the standard DSI bindings. We cannot use the generic infrastructure
> > > > without this change. Technically it should have been there all the
> > > > time, it is only working because it is currently hardcoded to 0 in
> > > > the panel driver.
> > > 
> > > Is it possible to change it to default to channel <0> if reg is not
> > > specified?
> > 
> > Currently nodes without reg property are skipped by of_mipi_dsi_device_add()
> > and of_mipi_dsi_device_add() fails if reg node is missing. Technically
> > it should be possible to default to channel 0 there. That affects all
> > platforms, though. Considering the small amount of boards affected, I think
> > its better to just fix the DT. Also the fixed DT does not make problems
> > with older kernels and can be backported.
> 
> You might be able to do a local fixup at driver probe time using
> of_add_property(). See for example pcs_quirk_missing_pinctrl_cells()
> I added earlier because of similar issues.

That sounds like a good plan. I suppose it could be added for some
kernel releases with a WARN() asking the user to update their DT.

-- Sebastian

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

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

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

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

* Re: [RFCv1 33/42] drm/omap: dsi: use atomic helper for dirtyfb
  2019-11-19 15:55             ` Tomi Valkeinen
  2019-11-19 18:46               ` Andreas Kemnade
@ 2019-11-20  3:48               ` Tony Lindgren
  1 sibling, 0 replies; 64+ messages in thread
From: Tony Lindgren @ 2019-11-20  3:48 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: kernel, H. Nikolaus Schaller, Merlijn Wajer, Sebastian Reichel,
	dri-devel, Sebastian Reichel, Laurent Pinchart, linux-omap

* Tomi Valkeinen <tomi.valkeinen@ti.com> [191119 15:56]:
> Afaik, Weston and X both handle page flips and/or dirtying the fb, so they
> should work. Are there applications that do not work, and cannot be made to
> work, except the few SGX test apps?

I'm not sure sure yet what all it affects, I'll do some more tests on it.

Regards,

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

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

end of thread, other threads:[~2019-11-20  3:48 UTC | newest]

Thread overview: 64+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-11-17  2:39 [RFCv1 00/42] drm/omap: Convert DSI code to use drm_mipi_dsi and drm_panel Sebastian Reichel
2019-11-17  2:39 ` Sebastian Reichel
2019-11-17  2:39 ` [RFCv1 01/42] omap/drm: drop unused dsi.configure_pins Sebastian Reichel
2019-11-17  2:39 ` [RFCv1 02/42] drm/omap: dsi: use MIPI_DSI_FMT_* instead of OMAP_DSS_DSI_FMT_* Sebastian Reichel
2019-11-17  2:39 ` [RFCv1 03/42] drm/omap: constify write buffers Sebastian Reichel
2019-11-17  2:39 ` [RFCv1 04/42] drm/omap: dsi: add generic transfer function Sebastian Reichel
2019-11-17  2:39 ` [RFCv1 05/42] drm/omap: panel-dsi-cm: convert to transfer API Sebastian Reichel
2019-11-17  2:39 ` [RFCv1 06/42] drm/omap: dsi: unexport specific data transfer functions Sebastian Reichel
2019-11-17  2:39 ` [RFCv1 07/42] drm/omap: dsi: drop virtual channel logic Sebastian Reichel
2019-11-17  2:39 ` [RFCv1 08/42] drm/omap: dsi: simplify write function Sebastian Reichel
2019-11-17  2:39 ` [RFCv1 09/42] drm/omap: dsi: simplify read functions Sebastian Reichel
2019-11-17  2:39 ` [RFCv1 10/42] drm/omap: dsi: switch dsi_vc_send_long/short to mipi_dsi_msg Sebastian Reichel
2019-11-17  2:39 ` [RFCv1 11/42] ARM: dts: omap: add channel to DSI panels Sebastian Reichel
2019-11-18 13:05   ` Tomi Valkeinen
2019-11-18 14:33     ` Sebastian Reichel
2019-11-18 14:37       ` H. Nikolaus Schaller
2019-11-18 15:03         ` Sebastian Reichel
2019-11-18 22:52           ` Tony Lindgren
2019-11-19 21:23             ` Sebastian Reichel
2019-11-17  2:39 ` [RFCv1 12/42] drm/omap: dsi: introduce mipi_dsi_host Sebastian Reichel
2019-11-17  2:39 ` [RFCv1 13/42] drm/omap: panel-dsi-cm: use DSI helpers Sebastian Reichel
2019-11-17  2:40 ` [RFCv1 14/42] drm/omap: dsi: request VC via mipi_dsi_attach Sebastian Reichel
2019-11-17  2:40 ` [RFCv1 15/42] drm/omap: panel-dsi-cm: drop hardcoded VC Sebastian Reichel
2019-11-17  2:40 ` [RFCv1 16/42] drm/omap: panel-dsi-cm: use common MIPI DCS 1.3 defines Sebastian Reichel
2019-11-17  2:40 ` [RFCv1 17/42] drm/omap: dsi: drop unused memory_read() Sebastian Reichel
2019-11-17  2:40 ` [RFCv1 18/42] drm/omap: dsi: drop unused get_te() Sebastian Reichel
2019-11-17  2:40 ` [RFCv1 19/42] drm/omap: dsi: drop unused enable_te() Sebastian Reichel
2019-11-17  2:40 ` [RFCv1 20/42] drm/omap: dsi: drop useless sync() Sebastian Reichel
2019-11-17  2:40 ` [RFCv1 21/42] drm/omap: dsi: use pixel-format and mode from attach Sebastian Reichel
2019-11-17  2:40 ` [RFCv1 22/42] drm/omap: panel-dsi-cm: use bulk regulator API Sebastian Reichel
2019-11-17  2:40 ` [RFCv1 23/42] drm/omap: dsi: lp/hs switching support for transfer() Sebastian Reichel
2019-11-17  2:40 ` [RFCv1 24/42] drm/omap: dsi: move TE GPIO handling into core Sebastian Reichel
2019-11-17  2:40 ` [RFCv1 25/42] drm/omap: dsi: drop custom enable_te() API Sebastian Reichel
2019-11-17  2:40 ` [RFCv1 26/42] drm/omap: dsi: do bus locking in host driver Sebastian Reichel
2019-11-17  2:40 ` [RFCv1 27/42] drm/omap: dsi: untangle ulps ops from enable/disable Sebastian Reichel
2019-11-17  2:40 ` [RFCv1 28/42] drm/dsi: add MIPI_DSI_MODE_ULPS_IDLE Sebastian Reichel
2019-11-17  2:40 ` [RFCv1 29/42] drm/omap: dsi: do ULPS in host driver Sebastian Reichel
2019-11-17  2:40 ` [RFCv1 30/42] drm/omap: dsi: move panel refresh function to host Sebastian Reichel
2019-11-17  2:40 ` [RFCv1 31/42] drm/omap: dsi: Reverse direction of the DSS device enable/disable operations Sebastian Reichel
2019-11-17  2:40 ` [RFCv1 32/42] drm/omap: dsi: convert to drm_panel Sebastian Reichel
2019-11-17 19:23   ` H. Nikolaus Schaller
2019-11-18 14:45     ` Sebastian Reichel
2019-11-18 14:51       ` H. Nikolaus Schaller
2019-11-19  9:42         ` H. Nikolaus Schaller
2019-11-19 21:21           ` Sebastian Reichel
2019-11-17  2:40 ` [RFCv1 33/42] drm/omap: dsi: use atomic helper for dirtyfb Sebastian Reichel
2019-11-18 23:05   ` Tony Lindgren
2019-11-19  5:42     ` Tomi Valkeinen
2019-11-19 14:32       ` Tony Lindgren
2019-11-19 14:53         ` Tomi Valkeinen
2019-11-19 15:06           ` Tony Lindgren
2019-11-19 15:55             ` Tomi Valkeinen
2019-11-19 18:46               ` Andreas Kemnade
2019-11-19 21:15                 ` Sebastian Reichel
2019-11-20  3:48               ` Tony Lindgren
2019-11-17  2:40 ` [RFCv1 34/42] drm/omap: dsi: implement check timings Sebastian Reichel
2019-11-17  2:40 ` [RFCv1 35/42] drm/omap: panel-dsi-cm: use DEVICE_ATTR_RO Sebastian Reichel
2019-11-17  2:40 ` [RFCv1 36/42] drm/omap: panel-dsi-cm: support unbinding Sebastian Reichel
2019-11-17  2:40 ` [RFCv1 37/42] drm/omap: panel-dsi-cm: fix remove() Sebastian Reichel
2019-11-17  2:40 ` [RFCv1 38/42] drm/omap: panel-dsi-cm: do not power on/off twice Sebastian Reichel
2019-11-17  2:40 ` [RFCv1 39/42] drm/omap: dsi: return proper error code from dsi_update_all() Sebastian Reichel
2019-11-17  2:40 ` [RFCv1 40/42] drm/omap: dsi: support panel un/re-binding Sebastian Reichel
2019-11-17  2:40 ` [RFCv1 41/42] ARM: dts: omap4-droid4: add panel compatible Sebastian Reichel
2019-11-17  2:40 ` [RFCv1 42/42] drm/panel: Move OMAP's DSI command mode panel driver Sebastian Reichel

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).