2023-06-22 09:33:07

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH 00/39] drm: renesas: shmobile: Atomic conversion + DT support

Hi all,

It has been 3 years since the last conversion of a DRM driver to atomic
modesetting, so I guess it's time for another one? ;-)

Currently, there are two drivers for the LCD controller on Renesas
SuperH-based and ARM-based SH-Mobile and R-Mobile SoCs:
1. sh_mobile_lcdcfb, using the fbdev framework,
2. shmob_drm, using the DRM framework.
However, only the former driver is used, as all platform support
integrates the former. None of these drivers support DT-based systems.

This patch series is a follow-up to [1] (which is already included in
drm-next). It converts the SH-Mobile DRM driver to atomic modesetting,
and adds DT support, complemented by the customary set of fixes and
improvements.

Overview:
- Patch 1 adds DT bindings for the SH-Mobile LCD controller,
- Patch 2 adds definitions for RGB666 9:9 media bus formats,
- Patches 3-33 contains miscellaneous fixes, improvements, and
cleanups for the SH-Mobile DRM driver,
- Patches 34-38 convert the SH-Mobile DRM driver to atomic
modesetting,
- Patch 39 adds DT support to the SH-Mobile DRM driver.

To reduce strain on the audience, I have CCed the DT and media people
only on the cover letter and the DT resp. media patches. If interested,
the full series should be available through lore.kernel.org.

Some comments and questioned can be found in the individual patches.

This has been tested on the R-Mobile A1-based Atmark Techno
Armadillo-800-EVA development board, using both legacy[2] and
DT-based[3] instantiation, with the fbdev-emulated text console and
modetest, a.o.

modetest -M shmob-drm -s 43:800x480@RG16 -P 33@41:640x320+80+80@RG16
modetest -M shmob-drm -s 43:800x480@RG16

The output of "modetest -M shmob-drm" can be found below[4].

Thanks for your comments!

[1] "[PATCH v3 0/5] drm: shmobile: Fixes and enhancements"
https://lore.kernel.org/r/[email protected]

[2] "[PATCH/RFC] staging: board: armadillo800eva: Add DRM support"
https://lore.kernel.org/r/f7874a9da4bcb20fbc9cd133147b67862ebcf0b9.1687418281.git.geert+renesas@glider.be

[3] "[PATCH 0/2] ARM: dts: r8a7740/armadillo800eva: Add LCD support"
https://lore.kernel.org/r/[email protected]

[4] Encoders:
id crtc type possible crtcs possible clones
42 41 DPI 0x00000001 0x00000001

Connectors:
id encoder status name size (mm) modes encoders
43 42 connected DPI-1 111x67 1 42
modes:
index name refresh (Hz) hdisp hss hse htot vdisp vss vse vtot
#0 800x480 59.99 800 840 968 1056 480 515 517 525 33260 flags: nhsync, nvsync; type: preferred, driver
props:
1 EDID:
flags: immutable blob
blobs:

value:
2 DPMS:
flags: enum
enums: On=0 Standby=1 Suspend=2 Off=3
value: 0
5 link-status:
flags: enum
enums: Good=0 Bad=1
value: 0
6 non-desktop:
flags: immutable range
values: 0 1
value: 0
4 TILE:
flags: immutable blob
blobs:

value:

CRTCs:
id fb pos size
41 44 (0,0) (800x480)
#0 800x480 59.99 800 840 968 1056 480 515 517 525 33260 flags: nhsync, nvsync; type: preferred, driver
props:

Planes:
id crtc fb CRTC x,y x,y gamma size possible crtcs
31 41 44 0,0 0,0 0 0x00000001
formats: RG16 RG24 AR24 XR24 NV12 NV21 NV16 NV61 NV24 NV42
props:
8 type:
flags: immutable enum
enums: Overlay=0 Primary=1 Cursor=2
value: 1
30 IN_FORMATS:
flags: immutable blob
blobs:

value:
01000000000000000a00000018000000
01000000400000005247313652473234
41523234585232344e5631324e563231
4e5631364e5636314e5632344e563432
ff030000000000000000000000000000
0000000000000000
in_formats blob decoded:
RG16: LINEAR
RG24: LINEAR
AR24: LINEAR
XR24: LINEAR
NV12: LINEAR
NV21: LINEAR
NV16: LINEAR
NV61: LINEAR
NV24: LINEAR
NV42: LINEAR
33 0 0 0,0 0,0 0 0x00000001
formats: RG16 RG24 AR24 XR24 NV12 NV21 NV16 NV61 NV24 NV42
props:
8 type:
flags: immutable enum
enums: Overlay=0 Primary=1 Cursor=2
value: 0
30 IN_FORMATS:
flags: immutable blob
blobs:

value:
01000000000000000a00000018000000
01000000400000005247313652473234
41523234585232344e5631324e563231
4e5631364e5636314e5632344e563432
ff030000000000000000000000000000
0000000000000000
in_formats blob decoded:
RG16: LINEAR
RG24: LINEAR
AR24: LINEAR
XR24: LINEAR
NV12: LINEAR
NV21: LINEAR
NV16: LINEAR
NV61: LINEAR
NV24: LINEAR
NV42: LINEAR
35 0 0 0,0 0,0 0 0x00000001
formats: RG16 RG24 AR24 XR24 NV12 NV21 NV16 NV61 NV24 NV42
props:
8 type:
flags: immutable enum
enums: Overlay=0 Primary=1 Cursor=2
value: 0
30 IN_FORMATS:
flags: immutable blob
blobs:

value:
01000000000000000a00000018000000
01000000400000005247313652473234
41523234585232344e5631324e563231
4e5631364e5636314e5632344e563432
ff030000000000000000000000000000
0000000000000000
in_formats blob decoded:
RG16: LINEAR
RG24: LINEAR
AR24: LINEAR
XR24: LINEAR
NV12: LINEAR
NV21: LINEAR
NV16: LINEAR
NV61: LINEAR
NV24: LINEAR
NV42: LINEAR
37 0 0 0,0 0,0 0 0x00000001
formats: RG16 RG24 AR24 XR24 NV12 NV21 NV16 NV61 NV24 NV42
props:
8 type:
flags: immutable enum
enums: Overlay=0 Primary=1 Cursor=2
value: 0
30 IN_FORMATS:
flags: immutable blob
blobs:

value:
01000000000000000a00000018000000
01000000400000005247313652473234
41523234585232344e5631324e563231
4e5631364e5636314e5632344e563432
ff030000000000000000000000000000
0000000000000000
in_formats blob decoded:
RG16: LINEAR
RG24: LINEAR
AR24: LINEAR
XR24: LINEAR
NV12: LINEAR
NV21: LINEAR
NV16: LINEAR
NV61: LINEAR
NV24: LINEAR
NV42: LINEAR
39 0 0 0,0 0,0 0 0x00000001
formats: RG16 RG24 AR24 XR24 NV12 NV21 NV16 NV61 NV24 NV42
props:
8 type:
flags: immutable enum
enums: Overlay=0 Primary=1 Cursor=2
value: 0
30 IN_FORMATS:
flags: immutable blob
blobs:

value:
01000000000000000a00000018000000
01000000400000005247313652473234
41523234585232344e5631324e563231
4e5631364e5636314e5632344e563432
ff030000000000000000000000000000
0000000000000000
in_formats blob decoded:
RG16: LINEAR
RG24: LINEAR
AR24: LINEAR
XR24: LINEAR
NV12: LINEAR
NV21: LINEAR
NV16: LINEAR
NV61: LINEAR
NV24: LINEAR
NV42: LINEAR

Frame buffers:
id size pitch

Geert Uytterhoeven (34):
dt-bindings: display: Add Renesas SH-Mobile LCDC bindings
media: uapi: Add MEDIA_BUS_FMT_RGB666_2X9 variants
drm: renesas: shmobile: Fix overlay plane disable
drm: renesas: shmobile: Fix ARGB32 overlay format typo
drm: renesas: shmobile: Correct encoder/connector types
drm: renesas: shmobile: Add support for Runtime PM
drm: renesas: shmobile: Restore indentation of
shmob_drm_setup_clocks()
drm: renesas: shmobile: Use %p4cc to print fourcc code
drm: renesas: shmobile: Add missing YCbCr formats
drm: renesas: shmobile: Improve shmob_drm_format_info table
drm: renesas: shmobile: Improve error handling
drm: renesas: shmobile: Convert to use devm_request_irq()
drm: renesas: shmobile: Use drmm_universal_plane_alloc()
drm: renesas: shmobile: Embed drm_device in shmob_drm_device
drm: renesas: shmobile: Convert container helpers to static inline
functions
drm: renesas: shmobile: Replace .dev_private with container_of()
drm: renesas: shmobile: Use media bus formats in platform data
drm: renesas: shmobile: Move interface handling to connector setup
drm: renesas: shmobile: Unify plane allocation
drm: renesas: shmobile: Rename shmob_drm_crtc.crtc
drm: renesas: shmobile: Rename shmob_drm_connector.connector
drm: renesas: shmobile: Rename shmob_drm_plane.plane
drm: renesas: shmobile: Use drm_crtc_handle_vblank()
drm: renesas: shmobile: Move shmob_drm_crtc_finish_page_flip()
drm: renesas: shmobile: Wait for page flip when turning CRTC off
drm: renesas: shmobile: Turn vblank on/off when enabling/disabling
CRTC
drm: renesas: shmobile: Shutdown the display on remove
drm: renesas: shmobile: Cleanup encoder
drm: renesas: shmobile: Atomic conversion part 1
drm: renesas: shmobile: Atomic conversion part 2
drm: renesas: shmobile: Use suspend/resume helpers
drm: renesas: shmobile: Remove internal CRTC state tracking
drm: renesas: shmobile: Atomic conversion part 3
drm: renesas: shmobile: Add DT support

Laurent Pinchart (5):
drm: renesas: shmobile: Remove backlight support
drm: renesas: shmobile: Don't set display info width and height twice
drm: renesas: shmobile: Rename input clocks
drm: renesas: shmobile: Remove support for SYS panels
drm: renesas: shmobile: Use struct videomode in platform data

.../display/renesas,shmobile-lcdc.yaml | 108 +++
.../media/v4l/subdev-formats.rst | 144 ++++
MAINTAINERS | 1 +
drivers/gpu/drm/renesas/shmobile/Makefile | 3 +-
.../renesas/shmobile/shmob_drm_backlight.c | 82 ---
.../renesas/shmobile/shmob_drm_backlight.h | 19 -
.../gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 666 +++++++++---------
.../gpu/drm/renesas/shmobile/shmob_drm_crtc.h | 27 +-
.../gpu/drm/renesas/shmobile/shmob_drm_drv.c | 153 ++--
.../gpu/drm/renesas/shmobile/shmob_drm_drv.h | 18 +-
.../gpu/drm/renesas/shmobile/shmob_drm_kms.c | 77 +-
.../gpu/drm/renesas/shmobile/shmob_drm_kms.h | 9 +-
.../drm/renesas/shmobile/shmob_drm_plane.c | 386 +++++-----
.../drm/renesas/shmobile/shmob_drm_plane.h | 4 +-
include/linux/platform_data/shmob_drm.h | 57 +-
include/uapi/linux/media-bus-format.h | 4 +-
16 files changed, 965 insertions(+), 793 deletions(-)
create mode 100644 Documentation/devicetree/bindings/display/renesas,shmobile-lcdc.yaml
delete mode 100644 drivers/gpu/drm/renesas/shmobile/shmob_drm_backlight.c
delete mode 100644 drivers/gpu/drm/renesas/shmobile/shmob_drm_backlight.h

Cc: Rob Herring <[email protected]>"
Cc: Krzysztof Kozlowski <[email protected]>"
Cc: Conor Dooley <[email protected]>"
Cc: Mauro Carvalho Chehab <[email protected]>"
Cc: [email protected]"
Cc: [email protected]"
--
2.34.1

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds


2023-06-22 09:33:13

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH 08/39] drm: renesas: shmobile: Use %p4cc to print fourcc code

Replace the last printing of an hexadecimal fourcc format code by a
pretty-printed format name, using the "%p4cc" format specifier.

Signed-off-by: Geert Uytterhoeven <[email protected]>
---
drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
index 7e49e2873da1bb6f..36fedb2b74c8b7a2 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
@@ -184,8 +184,8 @@ shmob_drm_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,

format = shmob_drm_format_info(fb->format->format);
if (format == NULL) {
- dev_dbg(sdev->dev, "update_plane: unsupported format %08x\n",
- fb->format->format);
+ dev_dbg(sdev->dev, "update_plane: unsupported format %p4cc\n",
+ &fb->format->format);
return -EINVAL;
}

--
2.34.1


2023-06-22 09:33:16

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH 07/39] drm: renesas: shmobile: Restore indentation of shmob_drm_setup_clocks()

Commit 56550d94cbaeaa19 ("Drivers: gpu: remove __dev* attributes.")
forgot to realign the continuation of the parameter section of
shmob_drm_setup_clocks().

Signed-off-by: Geert Uytterhoeven <[email protected]>
---
drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
index 4f01caa119637032..d272e6273c782178 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
@@ -67,7 +67,7 @@ static int shmob_drm_init_interface(struct shmob_drm_device *sdev)
}

static int shmob_drm_setup_clocks(struct shmob_drm_device *sdev,
- enum shmob_drm_clk_source clksrc)
+ enum shmob_drm_clk_source clksrc)
{
struct clk *clk;
char *clkname;
--
2.34.1


2023-06-22 09:33:23

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH 15/39] drm: renesas: shmobile: Improve error handling

Prepare for DT conversion, where panel probe can be deferred, by
streamlining error propagation and handling:
- Use dev_err_probe() to avoid printing error messages in case of
probe deferral,
- Propagate errors where needed.

Signed-off-by: Geert Uytterhoeven <[email protected]>
---
drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c | 3 ++-
drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c | 14 +++++++++++---
2 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
index 9aa9800899976a23..50fca18282c5cb5e 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
@@ -228,7 +228,8 @@ static int shmob_drm_probe(struct platform_device *pdev)

ret = shmob_drm_modeset_init(sdev);
if (ret < 0) {
- dev_err(&pdev->dev, "failed to initialize mode setting\n");
+ dev_err_probe(&pdev->dev, ret,
+ "failed to initialize mode setting\n");
goto err_free_drm_dev;
}

diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c
index 3051318ddc7999bc..1a62e7f8a8a9e6df 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c
@@ -157,9 +157,17 @@ int shmob_drm_modeset_init(struct shmob_drm_device *sdev)
if (ret)
return ret;

- shmob_drm_crtc_create(sdev);
- shmob_drm_encoder_create(sdev);
- shmob_drm_connector_create(sdev, &sdev->encoder);
+ ret = shmob_drm_crtc_create(sdev);
+ if (ret < 0)
+ return ret;
+
+ ret = shmob_drm_encoder_create(sdev);
+ if (ret < 0)
+ return ret;
+
+ ret = shmob_drm_connector_create(sdev, &sdev->encoder);
+ if (ret < 0)
+ return ret;

drm_kms_helper_poll_init(sdev->ddev);

--
2.34.1


2023-06-22 09:33:41

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH 06/39] drm: renesas: shmobile: Add support for Runtime PM

The SH-Mobile LCD Controller is part of a PM Domain on all relevant SoCs
(clock domain on all, power domain on some). Hence it may not be
sufficient to manage the LCDC module clock explicitly (e.g. if the
selected clock source differs from SHMOB_DRM_CLK_BUS).

Fix this by using Runtime PM instead.

Signed-off-by: Geert Uytterhoeven <[email protected]>
---
drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 11 ++++++++++-
drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c | 5 +++++
2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
index fbfd906844da490c..84dbf35025d7be63 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
@@ -9,6 +9,7 @@

#include <linux/backlight.h>
#include <linux/clk.h>
+#include <linux/pm_runtime.h>

#include <drm/drm_crtc.h>
#include <drm/drm_crtc_helper.h>
@@ -170,10 +171,16 @@ static void shmob_drm_crtc_start(struct shmob_drm_crtc *scrtc)
if (WARN_ON(format == NULL))
return;

+ ret = pm_runtime_resume_and_get(sdev->dev);
+ if (ret)
+ return;
+
/* Enable clocks before accessing the hardware. */
ret = shmob_drm_clk_on(sdev);
- if (ret < 0)
+ if (ret < 0) {
+ pm_runtime_put(sdev->dev);
return;
+ }

/* Reset and enable the LCDC. */
lcdc_write(sdev, LDCNT2R, lcdc_read(sdev, LDCNT2R) | LDCNT2R_BR);
@@ -271,6 +278,8 @@ static void shmob_drm_crtc_stop(struct shmob_drm_crtc *scrtc)
/* Stop clocks. */
shmob_drm_clk_off(sdev);

+ pm_runtime_put(sdev->dev);
+
scrtc->started = false;
}

diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
index 30493ce874192e3e..4f01caa119637032 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
@@ -13,6 +13,7 @@
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
+#include <linux/pm_runtime.h>
#include <linux/slab.h>

#include <drm/drm_drv.h>
@@ -216,6 +217,10 @@ static int shmob_drm_probe(struct platform_device *pdev)
if (IS_ERR(sdev->mmio))
return PTR_ERR(sdev->mmio);

+ ret = devm_pm_runtime_enable(&pdev->dev);
+ if (ret)
+ return ret;
+
ret = shmob_drm_setup_clocks(sdev, pdata->clk_source);
if (ret < 0)
return ret;
--
2.34.1


2023-06-22 09:33:42

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH 32/39] drm: renesas: shmobile: Shutdown the display on remove

When the device is unbound from the driver, the display may be active.
Make sure it gets shut down.

Signed-off-by: Geert Uytterhoeven <[email protected]>
---
drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
index a29c0c1093725b6e..636f1888b815579b 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
@@ -16,6 +16,7 @@
#include <linux/pm_runtime.h>
#include <linux/slab.h>

+#include <drm/drm_crtc_helper.h>
#include <drm/drm_drv.h>
#include <drm/drm_fbdev_generic.h>
#include <drm/drm_gem_dma_helper.h>
@@ -145,6 +146,7 @@ static int shmob_drm_remove(struct platform_device *pdev)
struct drm_device *ddev = &sdev->ddev;

drm_dev_unregister(ddev);
+ drm_helper_force_disable_all(ddev);
drm_kms_helper_poll_fini(ddev);
return 0;
}
--
2.34.1


2023-06-22 09:33:43

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH 22/39] drm: renesas: shmobile: Use media bus formats in platform data

Replace the custom shmob_drm_interface enumeration values with standard
media bus formats. This simplifies driver handling of bus formats and
prepares for DT support.

Signed-off-by: Geert Uytterhoeven <[email protected]>
---
.../gpu/drm/renesas/shmobile/shmob_drm_drv.c | 52 +++++++++++++------
include/linux/platform_data/shmob_drm.h | 13 +----
2 files changed, 38 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
index 1a1d66c6e817e227..e5be0ae99bd970be 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
@@ -9,6 +9,7 @@

#include <linux/clk.h>
#include <linux/io.h>
+#include <linux/media-bus-format.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/platform_device.h>
@@ -34,24 +35,45 @@

static int shmob_drm_init_interface(struct shmob_drm_device *sdev)
{
- static const u32 ldmt1r[] = {
- [SHMOB_DRM_IFACE_RGB8] = LDMT1R_MIFTYP_RGB8,
- [SHMOB_DRM_IFACE_RGB9] = LDMT1R_MIFTYP_RGB9,
- [SHMOB_DRM_IFACE_RGB12A] = LDMT1R_MIFTYP_RGB12A,
- [SHMOB_DRM_IFACE_RGB12B] = LDMT1R_MIFTYP_RGB12B,
- [SHMOB_DRM_IFACE_RGB16] = LDMT1R_MIFTYP_RGB16,
- [SHMOB_DRM_IFACE_RGB18] = LDMT1R_MIFTYP_RGB18,
- [SHMOB_DRM_IFACE_RGB24] = LDMT1R_MIFTYP_RGB24,
- [SHMOB_DRM_IFACE_YUV422] = LDMT1R_MIFTYP_YCBCR,
- };
-
- if (sdev->pdata->iface.interface >= ARRAY_SIZE(ldmt1r)) {
- dev_err(sdev->dev, "invalid interface type %u\n",
- sdev->pdata->iface.interface);
+ switch (sdev->pdata->iface.bus_fmt) {
+ case MEDIA_BUS_FMT_RGB888_3X8:
+ sdev->ldmt1r = LDMT1R_MIFTYP_RGB8;
+ break;
+
+ case MEDIA_BUS_FMT_RGB666_2X9_BE:
+ sdev->ldmt1r = LDMT1R_MIFTYP_RGB9;
+ break;
+
+ case MEDIA_BUS_FMT_RGB888_2X12_BE:
+ sdev->ldmt1r = LDMT1R_MIFTYP_RGB12A;
+ break;
+
+ case MEDIA_BUS_FMT_RGB444_1X12:
+ sdev->ldmt1r = LDMT1R_MIFTYP_RGB12B;
+ break;
+
+ case MEDIA_BUS_FMT_RGB565_1X16:
+ sdev->ldmt1r = LDMT1R_MIFTYP_RGB16;
+ break;
+
+ case MEDIA_BUS_FMT_RGB666_1X18:
+ sdev->ldmt1r = LDMT1R_MIFTYP_RGB18;
+ break;
+
+ case MEDIA_BUS_FMT_RGB888_1X24:
+ sdev->ldmt1r = LDMT1R_MIFTYP_RGB24;
+ break;
+
+ case MEDIA_BUS_FMT_UYVY8_1X16:
+ sdev->ldmt1r = LDMT1R_MIFTYP_YCBCR;
+ break;
+
+ default:
+ dev_err(sdev->dev, "invalid bus format 0x%x\n",
+ sdev->pdata->iface.bus_fmt);
return -EINVAL;
}

- sdev->ldmt1r = ldmt1r[sdev->pdata->iface.interface];
return 0;
}

diff --git a/include/linux/platform_data/shmob_drm.h b/include/linux/platform_data/shmob_drm.h
index f3cb19ff9f818aca..5047e66f0a6823ba 100644
--- a/include/linux/platform_data/shmob_drm.h
+++ b/include/linux/platform_data/shmob_drm.h
@@ -18,17 +18,6 @@ enum shmob_drm_clk_source {
SHMOB_DRM_CLK_EXTERNAL,
};

-enum shmob_drm_interface {
- SHMOB_DRM_IFACE_RGB8, /* 24bpp, 8:8:8 */
- SHMOB_DRM_IFACE_RGB9, /* 18bpp, 9:9 */
- SHMOB_DRM_IFACE_RGB12A, /* 24bpp, 12:12 */
- SHMOB_DRM_IFACE_RGB12B, /* 12bpp */
- SHMOB_DRM_IFACE_RGB16, /* 16bpp */
- SHMOB_DRM_IFACE_RGB18, /* 18bpp */
- SHMOB_DRM_IFACE_RGB24, /* 24bpp */
- SHMOB_DRM_IFACE_YUV422, /* 16bpp */
-};
-
struct shmob_drm_panel_data {
unsigned int width_mm; /* Panel width in mm */
unsigned int height_mm; /* Panel height in mm */
@@ -36,7 +25,7 @@ struct shmob_drm_panel_data {
};

struct shmob_drm_interface_data {
- enum shmob_drm_interface interface;
+ unsigned int bus_fmt; /* MEDIA_BUS_FMT_RGB888_* */
unsigned int clk_div;
};

--
2.34.1


2023-06-22 09:33:54

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH 36/39] drm: renesas: shmobile: Use suspend/resume helpers

Replace the custom suspend/resume handling by calls into
drm_mode_config_helper_{suspend,resume}().

Signed-off-by: Geert Uytterhoeven <[email protected]>
---
drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 13 -------------
drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h | 2 --
drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c | 13 +++----------
3 files changed, 3 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
index cf7152d64424e720..b11bb666de3bac46 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
@@ -339,19 +339,6 @@ static void shmob_drm_crtc_stop(struct shmob_drm_crtc *scrtc)
scrtc->started = false;
}

-void shmob_drm_crtc_suspend(struct shmob_drm_crtc *scrtc)
-{
- shmob_drm_crtc_stop(scrtc);
-}
-
-void shmob_drm_crtc_resume(struct shmob_drm_crtc *scrtc)
-{
- if (scrtc->dpms != DRM_MODE_DPMS_ON)
- return;
-
- shmob_drm_crtc_start(scrtc);
-}
-
static inline struct shmob_drm_crtc *to_shmob_crtc(struct drm_crtc *crtc)
{
return container_of(crtc, struct shmob_drm_crtc, base);
diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
index fe41e42d6cc55275..37380c815f1f5a08 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
@@ -40,8 +40,6 @@ struct shmob_drm_connector {

int shmob_drm_crtc_create(struct shmob_drm_device *sdev);
void shmob_drm_crtc_finish_page_flip(struct shmob_drm_crtc *scrtc);
-void shmob_drm_crtc_suspend(struct shmob_drm_crtc *scrtc);
-void shmob_drm_crtc_resume(struct shmob_drm_crtc *scrtc);

int shmob_drm_encoder_create(struct shmob_drm_device *sdev);
int shmob_drm_connector_create(struct shmob_drm_device *sdev,
diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
index 9107f84224602683..c43f408d6b1fcc5b 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
@@ -20,6 +20,7 @@
#include <drm/drm_drv.h>
#include <drm/drm_fbdev_generic.h>
#include <drm/drm_gem_dma_helper.h>
+#include <drm/drm_modeset_helper.h>
#include <drm/drm_module.h>
#include <drm/drm_probe_helper.h>
#include <drm/drm_vblank.h>
@@ -115,22 +116,14 @@ static int shmob_drm_pm_suspend(struct device *dev)
{
struct shmob_drm_device *sdev = dev_get_drvdata(dev);

- drm_kms_helper_poll_disable(&sdev->ddev);
- shmob_drm_crtc_suspend(&sdev->crtc);
-
- return 0;
+ return drm_mode_config_helper_suspend(&sdev->ddev);
}

static int shmob_drm_pm_resume(struct device *dev)
{
struct shmob_drm_device *sdev = dev_get_drvdata(dev);

- drm_modeset_lock_all(&sdev->ddev);
- shmob_drm_crtc_resume(&sdev->crtc);
- drm_modeset_unlock_all(&sdev->ddev);
-
- drm_kms_helper_poll_enable(&sdev->ddev);
- return 0;
+ return drm_mode_config_helper_resume(&sdev->ddev);
}

static DEFINE_SIMPLE_DEV_PM_OPS(shmob_drm_pm_ops,
--
2.34.1


2023-06-22 09:33:54

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH 02/39] media: uapi: Add MEDIA_BUS_FMT_RGB666_2X9 variants

Add the RGB666 9:9 formats MEDIA_BUS_FMT_RGB666_2X9_BE and
MEDIA_BUS_FMT_RGB666_2X9_LE. The former is supported by the SH-Mobile
LCD Controller.

Signed-off-by: Geert Uytterhoeven <[email protected]>
Cc: Mauro Carvalho Chehab <[email protected]>
Cc: [email protected]
---
.../media/v4l/subdev-formats.rst | 144 ++++++++++++++++++
include/uapi/linux/media-bus-format.h | 4 +-
2 files changed, 147 insertions(+), 1 deletion(-)

diff --git a/Documentation/userspace-api/media/v4l/subdev-formats.rst b/Documentation/userspace-api/media/v4l/subdev-formats.rst
index a3a35eeed70846ba..4bbcdec101384cb1 100644
--- a/Documentation/userspace-api/media/v4l/subdev-formats.rst
+++ b/Documentation/userspace-api/media/v4l/subdev-formats.rst
@@ -949,6 +949,150 @@ The following tables list existing packed RGB formats.
- b\ :sub:`2`
- b\ :sub:`1`
- b\ :sub:`0`
+ * .. _MEDIA-BUS-FMT-RGB666-2X9-BE:
+
+ - MEDIA_BUS_FMT_RGB666_2X9_BE
+ - 0x1025
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ - r\ :sub:`5`
+ - r\ :sub:`4`
+ - r\ :sub:`3`
+ - r\ :sub:`2`
+ - r\ :sub:`1`
+ - r\ :sub:`0`
+ - g\ :sub:`5`
+ - g\ :sub:`4`
+ - g\ :sub:`3`
+ * -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ - g\ :sub:`2`
+ - g\ :sub:`1`
+ - g\ :sub:`0`
+ - b\ :sub:`5`
+ - b\ :sub:`4`
+ - b\ :sub:`3`
+ - b\ :sub:`2`
+ - b\ :sub:`1`
+ - b\ :sub:`0`
+ * .. _MEDIA-BUS-FMT-RGB666-2X9-LE:
+
+ - MEDIA_BUS_FMT_RGB666_2X9_LE
+ - 0x1026
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ - g\ :sub:`2`
+ - g\ :sub:`1`
+ - g\ :sub:`0`
+ - b\ :sub:`5`
+ - b\ :sub:`4`
+ - b\ :sub:`3`
+ - b\ :sub:`2`
+ - b\ :sub:`1`
+ - b\ :sub:`0`
+ * -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ - r\ :sub:`5`
+ - r\ :sub:`4`
+ - r\ :sub:`3`
+ - r\ :sub:`2`
+ - r\ :sub:`1`
+ - r\ :sub:`0`
+ - g\ :sub:`5`
+ - g\ :sub:`4`
+ - g\ :sub:`3`
* .. _MEDIA-BUS-FMT-BGR666-1X18:

- MEDIA_BUS_FMT_BGR666_1X18
diff --git a/include/uapi/linux/media-bus-format.h b/include/uapi/linux/media-bus-format.h
index a03c543cb072de30..07105f530400511e 100644
--- a/include/uapi/linux/media-bus-format.h
+++ b/include/uapi/linux/media-bus-format.h
@@ -34,7 +34,7 @@

#define MEDIA_BUS_FMT_FIXED 0x0001

-/* RGB - next is 0x1025 */
+/* RGB - next is 0x1027 */
#define MEDIA_BUS_FMT_RGB444_1X12 0x1016
#define MEDIA_BUS_FMT_RGB444_2X8_PADHI_BE 0x1001
#define MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE 0x1002
@@ -46,6 +46,8 @@
#define MEDIA_BUS_FMT_RGB565_2X8_BE 0x1007
#define MEDIA_BUS_FMT_RGB565_2X8_LE 0x1008
#define MEDIA_BUS_FMT_RGB666_1X18 0x1009
+#define MEDIA_BUS_FMT_RGB666_2X9_BE 0x1025
+#define MEDIA_BUS_FMT_RGB666_2X9_LE 0x1026
#define MEDIA_BUS_FMT_BGR666_1X18 0x1023
#define MEDIA_BUS_FMT_RBG888_1X24 0x100e
#define MEDIA_BUS_FMT_RGB666_1X24_CPADHI 0x1015
--
2.34.1


2023-06-22 09:34:39

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH 33/39] drm: renesas: shmobile: Cleanup encoder

Most unused callbacks can be NULL pointers these days.
Drop a bunch of empty encoder callbacks.

Signed-off-by: Geert Uytterhoeven <[email protected]>
---
.../gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 26 -------------------
1 file changed, 26 deletions(-)

diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
index b184019d8b1ed89c..ef327da39bca415a 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
@@ -586,11 +586,6 @@ int shmob_drm_crtc_create(struct shmob_drm_device *sdev)
* Encoder
*/

-static void shmob_drm_encoder_dpms(struct drm_encoder *encoder, int mode)
-{
- /* No-op, everything is handled in the CRTC code. */
-}
-
static bool shmob_drm_encoder_mode_fixup(struct drm_encoder *encoder,
const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
@@ -613,29 +608,8 @@ static bool shmob_drm_encoder_mode_fixup(struct drm_encoder *encoder,
return true;
}

-static void shmob_drm_encoder_mode_prepare(struct drm_encoder *encoder)
-{
- /* No-op, everything is handled in the CRTC code. */
-}
-
-static void shmob_drm_encoder_mode_set(struct drm_encoder *encoder,
- struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
-{
- /* No-op, everything is handled in the CRTC code. */
-}
-
-static void shmob_drm_encoder_mode_commit(struct drm_encoder *encoder)
-{
- /* No-op, everything is handled in the CRTC code. */
-}
-
static const struct drm_encoder_helper_funcs encoder_helper_funcs = {
- .dpms = shmob_drm_encoder_dpms,
.mode_fixup = shmob_drm_encoder_mode_fixup,
- .prepare = shmob_drm_encoder_mode_prepare,
- .commit = shmob_drm_encoder_mode_commit,
- .mode_set = shmob_drm_encoder_mode_set,
};

int shmob_drm_encoder_create(struct shmob_drm_device *sdev)
--
2.34.1


2023-06-22 09:34:44

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH 14/39] drm: renesas: shmobile: Remove support for SYS panels

From: Laurent Pinchart <[email protected]>

SYS panels are not used, and have no defined DT bindings. Remove their
support to avoid impeding DT support. It can always be added back
later.

Signed-off-by: Laurent Pinchart <[email protected]>
Signed-off-by: Geert Uytterhoeven <[email protected]>
---
Changes compared to Laurent's original:
- Remove "/* TODO: Setup SYS panel */" comment.
---
.../gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 20 ---------------
.../gpu/drm/renesas/shmobile/shmob_drm_drv.c | 11 --------
include/linux/platform_data/shmob_drm.h | 25 -------------------
3 files changed, 56 deletions(-)

diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
index 0eeb1410b662d74b..bcdebbc9f8a7e299 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
@@ -78,24 +78,6 @@ static void shmob_drm_crtc_setup_geometry(struct shmob_drm_crtc *scrtc)
| ((idata->flags & SHMOB_DRM_IFACE_FL_DWCNT) ? LDMT1R_DWCNT : 0);
lcdc_write(sdev, LDMT1R, value);

- if (idata->interface >= SHMOB_DRM_IFACE_SYS8A &&
- idata->interface <= SHMOB_DRM_IFACE_SYS24) {
- /* Setup SYS bus. */
- value = (idata->sys.cs_setup << LDMT2R_CSUP_SHIFT)
- | (idata->sys.vsync_active_high ? LDMT2R_RSV : 0)
- | (idata->sys.vsync_dir_input ? LDMT2R_VSEL : 0)
- | (idata->sys.write_setup << LDMT2R_WCSC_SHIFT)
- | (idata->sys.write_cycle << LDMT2R_WCEC_SHIFT)
- | (idata->sys.write_strobe << LDMT2R_WCLW_SHIFT);
- lcdc_write(sdev, LDMT2R, value);
-
- value = (idata->sys.read_latch << LDMT3R_RDLC_SHIFT)
- | (idata->sys.read_setup << LDMT3R_RCSC_SHIFT)
- | (idata->sys.read_cycle << LDMT3R_RCEC_SHIFT)
- | (idata->sys.read_strobe << LDMT3R_RCLW_SHIFT);
- lcdc_write(sdev, LDMT3R, value);
- }
-
value = ((mode->hdisplay / 8) << 16) /* HDCN */
| (mode->htotal / 8); /* HTCN */
lcdc_write(sdev, LDHCNR, value);
@@ -210,8 +192,6 @@ static void shmob_drm_crtc_start(struct shmob_drm_crtc *scrtc)
lcdc_write(sdev, LDDCKSTPR, 0);
lcdc_wait_bit(sdev, LDDCKSTPR, ~0, 0);

- /* TODO: Setup SYS panel */
-
/* Setup geometry, format, frame buffer memory and operation mode. */
shmob_drm_crtc_setup_geometry(scrtc);

diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
index 007ba97cc7733c82..9aa9800899976a23 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
@@ -43,17 +43,6 @@ static int shmob_drm_init_interface(struct shmob_drm_device *sdev)
[SHMOB_DRM_IFACE_RGB18] = LDMT1R_MIFTYP_RGB18,
[SHMOB_DRM_IFACE_RGB24] = LDMT1R_MIFTYP_RGB24,
[SHMOB_DRM_IFACE_YUV422] = LDMT1R_MIFTYP_YCBCR,
- [SHMOB_DRM_IFACE_SYS8A] = LDMT1R_IFM | LDMT1R_MIFTYP_SYS8A,
- [SHMOB_DRM_IFACE_SYS8B] = LDMT1R_IFM | LDMT1R_MIFTYP_SYS8B,
- [SHMOB_DRM_IFACE_SYS8C] = LDMT1R_IFM | LDMT1R_MIFTYP_SYS8C,
- [SHMOB_DRM_IFACE_SYS8D] = LDMT1R_IFM | LDMT1R_MIFTYP_SYS8D,
- [SHMOB_DRM_IFACE_SYS9] = LDMT1R_IFM | LDMT1R_MIFTYP_SYS9,
- [SHMOB_DRM_IFACE_SYS12] = LDMT1R_IFM | LDMT1R_MIFTYP_SYS12,
- [SHMOB_DRM_IFACE_SYS16A] = LDMT1R_IFM | LDMT1R_MIFTYP_SYS16A,
- [SHMOB_DRM_IFACE_SYS16B] = LDMT1R_IFM | LDMT1R_MIFTYP_SYS16B,
- [SHMOB_DRM_IFACE_SYS16C] = LDMT1R_IFM | LDMT1R_MIFTYP_SYS16C,
- [SHMOB_DRM_IFACE_SYS18] = LDMT1R_IFM | LDMT1R_MIFTYP_SYS18,
- [SHMOB_DRM_IFACE_SYS24] = LDMT1R_IFM | LDMT1R_MIFTYP_SYS24,
};

if (sdev->pdata->iface.interface >= ARRAY_SIZE(ldmt1r)) {
diff --git a/include/linux/platform_data/shmob_drm.h b/include/linux/platform_data/shmob_drm.h
index b6b5b6607fb5e52c..b728e24222d99158 100644
--- a/include/linux/platform_data/shmob_drm.h
+++ b/include/linux/platform_data/shmob_drm.h
@@ -27,17 +27,6 @@ enum shmob_drm_interface {
SHMOB_DRM_IFACE_RGB18, /* 18bpp */
SHMOB_DRM_IFACE_RGB24, /* 24bpp */
SHMOB_DRM_IFACE_YUV422, /* 16bpp */
- SHMOB_DRM_IFACE_SYS8A, /* 24bpp, 8:8:8 */
- SHMOB_DRM_IFACE_SYS8B, /* 18bpp, 8:8:2 */
- SHMOB_DRM_IFACE_SYS8C, /* 18bpp, 2:8:8 */
- SHMOB_DRM_IFACE_SYS8D, /* 16bpp, 8:8 */
- SHMOB_DRM_IFACE_SYS9, /* 18bpp, 9:9 */
- SHMOB_DRM_IFACE_SYS12, /* 24bpp, 12:12 */
- SHMOB_DRM_IFACE_SYS16A, /* 16bpp */
- SHMOB_DRM_IFACE_SYS16B, /* 18bpp, 16:2 */
- SHMOB_DRM_IFACE_SYS16C, /* 18bpp, 2:16 */
- SHMOB_DRM_IFACE_SYS18, /* 18bpp */
- SHMOB_DRM_IFACE_SYS24, /* 24bpp */
};

struct shmob_drm_panel_data {
@@ -46,19 +35,6 @@ struct shmob_drm_panel_data {
struct drm_mode_modeinfo mode;
};

-struct shmob_drm_sys_interface_data {
- unsigned int read_latch:6;
- unsigned int read_setup:8;
- unsigned int read_cycle:8;
- unsigned int read_strobe:8;
- unsigned int write_setup:8;
- unsigned int write_cycle:8;
- unsigned int write_strobe:8;
- unsigned int cs_setup:3;
- unsigned int vsync_active_high:1;
- unsigned int vsync_dir_input:1;
-};
-
#define SHMOB_DRM_IFACE_FL_DWPOL (1 << 0) /* Rising edge dot clock data latch */
#define SHMOB_DRM_IFACE_FL_DIPOL (1 << 1) /* Active low display enable */
#define SHMOB_DRM_IFACE_FL_DAPOL (1 << 2) /* Active low display data */
@@ -67,7 +43,6 @@ struct shmob_drm_sys_interface_data {

struct shmob_drm_interface_data {
enum shmob_drm_interface interface;
- struct shmob_drm_sys_interface_data sys;
unsigned int clk_div;
unsigned int flags;
};
--
2.34.1


2023-06-22 09:48:35

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH 37/39] drm: renesas: shmobile: Remove internal CRTC state tracking

Now the suspend/resume methods no longer need to look at internal driver
state, the dpms and started fields in the shmob_drm_crtc structure can
be removed, as well as the shmob_drm_crtc_dpms() wrapper.

Signed-off-by: Geert Uytterhoeven <[email protected]>
---
.../gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 35 ++++---------------
.../gpu/drm/renesas/shmobile/shmob_drm_crtc.h | 3 --
2 files changed, 6 insertions(+), 32 deletions(-)

diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
index b11bb666de3bac46..f2332bb0fbbd51a1 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
@@ -196,9 +196,6 @@ static void shmob_drm_crtc_start(struct shmob_drm_crtc *scrtc)
u32 value;
int ret;

- if (scrtc->started)
- return;
-
ret = pm_runtime_resume_and_get(dev);
if (ret)
return;
@@ -252,8 +249,6 @@ static void shmob_drm_crtc_start(struct shmob_drm_crtc *scrtc)

/* Turn vertical blank interrupt reporting back on. */
drm_crtc_vblank_on(crtc);
-
- scrtc->started = true;
}

/* -----------------------------------------------------------------------------
@@ -314,9 +309,6 @@ static void shmob_drm_crtc_stop(struct shmob_drm_crtc *scrtc)
struct drm_crtc *crtc = &scrtc->base;
struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);

- if (!scrtc->started)
- return;
-
/*
* Disable vertical blank interrupt reporting. We first need to wait
* for page flip completion before stopping the CRTC as userspace
@@ -335,8 +327,6 @@ static void shmob_drm_crtc_stop(struct shmob_drm_crtc *scrtc)
shmob_drm_clk_off(sdev);

pm_runtime_put(sdev->dev);
-
- scrtc->started = false;
}

static inline struct shmob_drm_crtc *to_shmob_crtc(struct drm_crtc *crtc)
@@ -344,21 +334,6 @@ static inline struct shmob_drm_crtc *to_shmob_crtc(struct drm_crtc *crtc)
return container_of(crtc, struct shmob_drm_crtc, base);
}

-static void shmob_drm_crtc_dpms(struct drm_crtc *crtc, int mode)
-{
- struct shmob_drm_crtc *scrtc = to_shmob_crtc(crtc);
-
- if (scrtc->dpms == mode)
- return;
-
- if (mode == DRM_MODE_DPMS_ON)
- shmob_drm_crtc_start(scrtc);
- else
- shmob_drm_crtc_stop(scrtc);
-
- scrtc->dpms = mode;
-}
-
static void shmob_drm_crtc_atomic_flush(struct drm_crtc *crtc,
struct drm_atomic_state *state)
{
@@ -378,13 +353,17 @@ static void shmob_drm_crtc_atomic_flush(struct drm_crtc *crtc,
static void shmob_drm_crtc_atomic_enable(struct drm_crtc *crtc,
struct drm_atomic_state *state)
{
- shmob_drm_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
+ struct shmob_drm_crtc *scrtc = to_shmob_crtc(crtc);
+
+ shmob_drm_crtc_start(scrtc);
}

static void shmob_drm_crtc_atomic_disable(struct drm_crtc *crtc,
struct drm_atomic_state *state)
{
- shmob_drm_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
+ struct shmob_drm_crtc *scrtc = to_shmob_crtc(crtc);
+
+ shmob_drm_crtc_stop(scrtc);
}

static const struct drm_crtc_helper_funcs crtc_helper_funcs = {
@@ -476,8 +455,6 @@ int shmob_drm_crtc_create(struct shmob_drm_device *sdev)

init_waitqueue_head(&sdev->crtc.flip_wait);

- sdev->crtc.dpms = DRM_MODE_DPMS_OFF;
-
primary = shmob_drm_plane_create(sdev, 0);
if (IS_ERR(primary))
return PTR_ERR(primary);
diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
index 37380c815f1f5a08..89a0746f9a35807d 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
@@ -27,9 +27,6 @@ struct shmob_drm_crtc {

struct drm_pending_vblank_event *event;
wait_queue_head_t flip_wait;
- int dpms;
-
- bool started;
};

struct shmob_drm_connector {
--
2.34.1


2023-06-22 09:48:36

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH 09/39] drm: renesas: shmobile: Add missing YCbCr formats

The primary plane supports various YCbCr formats, and the CRTC code
already knows how to handle them. Enable support for the missing
formats by adding them to the table of supported modes.

Signed-off-by: Geert Uytterhoeven <[email protected]>
---
drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 6 ++++++
1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
index 84dbf35025d7be63..cd492806105e5b5d 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
@@ -493,6 +493,12 @@ static const uint32_t modeset_formats[] = {
DRM_FORMAT_RGB888,
DRM_FORMAT_ARGB8888,
DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_NV12,
+ DRM_FORMAT_NV21,
+ DRM_FORMAT_NV16,
+ DRM_FORMAT_NV61,
+ DRM_FORMAT_NV24,
+ DRM_FORMAT_NV42,
};

static const struct drm_plane_funcs primary_plane_funcs = {
--
2.34.1


2023-06-22 09:48:54

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH 04/39] drm: renesas: shmobile: Fix ARGB32 overlay format typo

When configurating a CHn Source Image Format Register (LDBBSIFR), one
should use the corresponding LDBBSIFR_RPKF_* definition for overlay
planes, not the DDFR_PKF_* definition for the primary plane.

Fortunately both definitions resolve to the same value, so this bug did
not cause any harm.

Signed-off-by: Geert Uytterhoeven <[email protected]>
---
drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
index 0e34573c3cb3d032..7e49e2873da1bb6f 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
@@ -94,10 +94,10 @@ static void __shmob_drm_plane_setup(struct shmob_drm_plane *splane,
format |= LDBBSIFR_AL_1 | LDBBSIFR_RY | LDBBSIFR_RPKF_RGB24;
break;
case DRM_FORMAT_ARGB8888:
- format |= LDBBSIFR_AL_PK | LDBBSIFR_RY | LDDFR_PKF_ARGB32;
+ format |= LDBBSIFR_AL_PK | LDBBSIFR_RY | LDBBSIFR_RPKF_ARGB32;
break;
case DRM_FORMAT_XRGB8888:
- format |= LDBBSIFR_AL_1 | LDBBSIFR_RY | LDDFR_PKF_ARGB32;
+ format |= LDBBSIFR_AL_1 | LDBBSIFR_RY | LDBBSIFR_RPKF_ARGB32;
break;
case DRM_FORMAT_NV12:
case DRM_FORMAT_NV21:
--
2.34.1


2023-06-22 09:49:44

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH 17/39] drm: renesas: shmobile: Use drmm_universal_plane_alloc()

According to the comments for drm_universal_plane_init(), the plane
structure should not be allocated with devm_kzalloc().

Fix lifetime issues by using drmm_universal_plane_alloc() instead.

Signed-off-by: Geert Uytterhoeven <[email protected]>
---
Plane (and connector) structures are still allocated with devm_kzalloc()
in several other drivers...
---
.../drm/renesas/shmobile/shmob_drm_plane.c | 24 ++++++-------------
1 file changed, 7 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
index 0b2ab153e9ae76df..1fb68b5fe915b8dc 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
@@ -176,16 +176,9 @@ static int shmob_drm_plane_disable(struct drm_plane *plane,
return 0;
}

-static void shmob_drm_plane_destroy(struct drm_plane *plane)
-{
- drm_plane_force_disable(plane);
- drm_plane_cleanup(plane);
-}
-
static const struct drm_plane_funcs shmob_drm_plane_funcs = {
.update_plane = shmob_drm_plane_update,
.disable_plane = shmob_drm_plane_disable,
- .destroy = shmob_drm_plane_destroy,
};

static const uint32_t formats[] = {
@@ -204,19 +197,16 @@ static const uint32_t formats[] = {
int shmob_drm_plane_create(struct shmob_drm_device *sdev, unsigned int index)
{
struct shmob_drm_plane *splane;
- int ret;

- splane = devm_kzalloc(sdev->dev, sizeof(*splane), GFP_KERNEL);
- if (splane == NULL)
- return -ENOMEM;
+ splane = drmm_universal_plane_alloc(sdev->ddev, struct shmob_drm_plane,
+ plane, 1, &shmob_drm_plane_funcs,
+ formats, ARRAY_SIZE(formats), NULL,
+ DRM_PLANE_TYPE_OVERLAY, NULL);
+ if (IS_ERR(splane))
+ return PTR_ERR(splane);

splane->index = index;
splane->alpha = 255;

- ret = drm_universal_plane_init(sdev->ddev, &splane->plane, 1,
- &shmob_drm_plane_funcs,
- formats, ARRAY_SIZE(formats), NULL,
- DRM_PLANE_TYPE_OVERLAY, NULL);
-
- return ret;
+ return 0;
}
--
2.34.1


2023-06-22 09:50:07

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH 35/39] drm: renesas: shmobile: Atomic conversion part 2

Implement atomic mode setting for the CRTC, using the existing dpms
callback.

Signed-off-by: Geert Uytterhoeven <[email protected]>
---
This works, but I had expected that crtc_helper_funcs.atomic_check
should point to drm_crtc_helper_atomic_check() instead, as the primary
plane cannot be disabled. However in doing so, when
drm_atomic_helper_check_crtc_primary_plane() fails:

[drm:drm_atomic_helper_check_crtc_primary_plane] [CRTC:41:crtc-0] primary plane missing

the display fails to restore after running "modetest -s", until I run
modetest without -s.

Letting shmob_drm_plane_atomic_check() return -EINVAL if
!new_plane_state->crtc && is_primary would fix that, but causes an ugly
warning:

WARNING: CPU: 0 PID: 21 at drivers/gpu/drm/drm_framebuffer.c:1130 drm_framebuffer_remove+0x374/0x4b0
atomic remove_fb failed with -22
---
.../gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 41 +++++++------------
1 file changed, 15 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
index ea19e802792e24a4..cf7152d64424e720 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
@@ -11,6 +11,7 @@
#include <linux/media-bus-format.h>
#include <linux/pm_runtime.h>

+#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_atomic_state_helper.h>
#include <drm/drm_atomic_uapi.h>
@@ -371,27 +372,6 @@ static void shmob_drm_crtc_dpms(struct drm_crtc *crtc, int mode)
scrtc->dpms = mode;
}

-static void shmob_drm_crtc_mode_prepare(struct drm_crtc *crtc)
-{
- shmob_drm_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
-}
-
-static void shmob_drm_crtc_mode_commit(struct drm_crtc *crtc)
-{
- shmob_drm_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
-}
-
-static int shmob_drm_crtc_atomic_check(struct drm_crtc *crtc,
- struct drm_atomic_state *state)
-{
- return 0;
-}
-
-static void shmob_drm_crtc_atomic_begin(struct drm_crtc *crtc,
- struct drm_atomic_state *state)
-{
-}
-
static void shmob_drm_crtc_atomic_flush(struct drm_crtc *crtc,
struct drm_atomic_state *state)
{
@@ -408,13 +388,22 @@ static void shmob_drm_crtc_atomic_flush(struct drm_crtc *crtc,
}
}

+static void shmob_drm_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_atomic_state *state)
+{
+ shmob_drm_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
+}
+
+static void shmob_drm_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_atomic_state *state)
+{
+ shmob_drm_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
+}
+
static const struct drm_crtc_helper_funcs crtc_helper_funcs = {
- .dpms = shmob_drm_crtc_dpms,
- .prepare = shmob_drm_crtc_mode_prepare,
- .commit = shmob_drm_crtc_mode_commit,
- .atomic_check = shmob_drm_crtc_atomic_check,
- .atomic_begin = shmob_drm_crtc_atomic_begin,
.atomic_flush = shmob_drm_crtc_atomic_flush,
+ .atomic_enable = shmob_drm_crtc_atomic_enable,
+ .atomic_disable = shmob_drm_crtc_atomic_disable,
};

static int shmob_drm_crtc_page_flip(struct drm_crtc *crtc,
--
2.34.1


2023-06-22 09:50:09

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH 18/39] drm: renesas: shmobile: Embed drm_device in shmob_drm_device

Embedding drm_device in shmob_drm_device allows us to use the DRM
managed API to allocate both structures in one go, simplifying error
handling.

Signed-off-by: Geert Uytterhoeven <[email protected]>
---
.../gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 12 +++---
.../gpu/drm/renesas/shmobile/shmob_drm_drv.c | 41 +++++++------------
.../gpu/drm/renesas/shmobile/shmob_drm_drv.h | 2 +-
.../gpu/drm/renesas/shmobile/shmob_drm_kms.c | 16 ++++----
.../drm/renesas/shmobile/shmob_drm_plane.c | 8 ++--
5 files changed, 34 insertions(+), 45 deletions(-)

diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
index bcdebbc9f8a7e299..26611440f7a12715 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
@@ -139,7 +139,7 @@ static void shmob_drm_crtc_start(struct shmob_drm_crtc *scrtc)
struct shmob_drm_device *sdev = crtc->dev->dev_private;
const struct shmob_drm_interface_data *idata = &sdev->pdata->iface;
const struct shmob_drm_format_info *format;
- struct drm_device *dev = sdev->ddev;
+ struct drm_device *dev = &sdev->ddev;
struct drm_plane *plane;
u32 value;
int ret;
@@ -472,7 +472,7 @@ int shmob_drm_crtc_create(struct shmob_drm_device *sdev)

sdev->crtc.dpms = DRM_MODE_DPMS_OFF;

- primary = __drm_universal_plane_alloc(sdev->ddev, sizeof(*primary), 0,
+ primary = __drm_universal_plane_alloc(&sdev->ddev, sizeof(*primary), 0,
0, &primary_plane_funcs,
modeset_formats,
ARRAY_SIZE(modeset_formats),
@@ -481,7 +481,7 @@ int shmob_drm_crtc_create(struct shmob_drm_device *sdev)
if (IS_ERR(primary))
return PTR_ERR(primary);

- ret = drm_crtc_init_with_planes(sdev->ddev, crtc, primary, NULL,
+ ret = drm_crtc_init_with_planes(&sdev->ddev, crtc, primary, NULL,
&crtc_funcs, NULL);
if (ret < 0) {
drm_plane_cleanup(primary);
@@ -557,7 +557,7 @@ int shmob_drm_encoder_create(struct shmob_drm_device *sdev)

encoder->possible_crtcs = 1;

- ret = drm_simple_encoder_init(sdev->ddev, encoder,
+ ret = drm_simple_encoder_init(&sdev->ddev, encoder,
DRM_MODE_ENCODER_DPI);
if (ret < 0)
return ret;
@@ -637,7 +637,7 @@ int shmob_drm_connector_create(struct shmob_drm_device *sdev,
connector->display_info.width_mm = sdev->pdata->panel.width_mm;
connector->display_info.height_mm = sdev->pdata->panel.height_mm;

- ret = drm_connector_init(sdev->ddev, connector, &connector_funcs,
+ ret = drm_connector_init(&sdev->ddev, connector, &connector_funcs,
DRM_MODE_CONNECTOR_DPI);
if (ret < 0)
return ret;
@@ -650,7 +650,7 @@ int shmob_drm_connector_create(struct shmob_drm_device *sdev,

drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
drm_object_property_set_value(&connector->base,
- sdev->ddev->mode_config.dpms_property, DRM_MODE_DPMS_OFF);
+ sdev->ddev.mode_config.dpms_property, DRM_MODE_DPMS_OFF);

return 0;

diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
index ece9aedde9b662d4..2b77af3a8c97ef8c 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
@@ -137,7 +137,7 @@ static int shmob_drm_pm_suspend(struct device *dev)
{
struct shmob_drm_device *sdev = dev_get_drvdata(dev);

- drm_kms_helper_poll_disable(sdev->ddev);
+ drm_kms_helper_poll_disable(&sdev->ddev);
shmob_drm_crtc_suspend(&sdev->crtc);

return 0;
@@ -147,11 +147,11 @@ static int shmob_drm_pm_resume(struct device *dev)
{
struct shmob_drm_device *sdev = dev_get_drvdata(dev);

- drm_modeset_lock_all(sdev->ddev);
+ drm_modeset_lock_all(&sdev->ddev);
shmob_drm_crtc_resume(&sdev->crtc);
- drm_modeset_unlock_all(sdev->ddev);
+ drm_modeset_unlock_all(&sdev->ddev);

- drm_kms_helper_poll_enable(sdev->ddev);
+ drm_kms_helper_poll_enable(&sdev->ddev);
return 0;
}

@@ -165,12 +165,10 @@ static DEFINE_SIMPLE_DEV_PM_OPS(shmob_drm_pm_ops,
static int shmob_drm_remove(struct platform_device *pdev)
{
struct shmob_drm_device *sdev = platform_get_drvdata(pdev);
- struct drm_device *ddev = sdev->ddev;
+ struct drm_device *ddev = &sdev->ddev;

drm_dev_unregister(ddev);
drm_kms_helper_poll_fini(ddev);
- drm_dev_put(ddev);
-
return 0;
}

@@ -188,13 +186,15 @@ static int shmob_drm_probe(struct platform_device *pdev)
}

/*
- * Allocate and initialize the driver private data, I/O resources and
- * clocks.
+ * Allocate and initialize the DRM device, driver private data, I/O
+ * resources and clocks.
*/
- sdev = devm_kzalloc(&pdev->dev, sizeof(*sdev), GFP_KERNEL);
- if (sdev == NULL)
- return -ENOMEM;
+ sdev = devm_drm_dev_alloc(&pdev->dev, &shmob_drm_driver,
+ struct shmob_drm_device, ddev);
+ if (IS_ERR(sdev))
+ return PTR_ERR(sdev);

+ ddev = &sdev->ddev;
sdev->dev = &pdev->dev;
sdev->pdata = pdata;
spin_lock_init(&sdev->irq_lock);
@@ -217,20 +217,12 @@ static int shmob_drm_probe(struct platform_device *pdev)
if (ret < 0)
return ret;

- /* Allocate and initialize the DRM device. */
- ddev = drm_dev_alloc(&shmob_drm_driver, &pdev->dev);
- if (IS_ERR(ddev))
- return PTR_ERR(ddev);
-
- sdev->ddev = ddev;
ddev->dev_private = sdev;

ret = shmob_drm_modeset_init(sdev);
- if (ret < 0) {
- dev_err_probe(&pdev->dev, ret,
- "failed to initialize mode setting\n");
- goto err_free_drm_dev;
- }
+ if (ret < 0)
+ return dev_err_probe(&pdev->dev, ret,
+ "failed to initialize mode setting\n");

for (i = 0; i < 4; ++i) {
ret = shmob_drm_plane_create(sdev, i);
@@ -272,9 +264,6 @@ static int shmob_drm_probe(struct platform_device *pdev)

err_modeset_cleanup:
drm_kms_helper_poll_fini(ddev);
-err_free_drm_dev:
- drm_dev_put(ddev);
-
return ret;
}

diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.h b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.h
index 16d830168b2ada21..77bb0da48f37ace8 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.h
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.h
@@ -32,7 +32,7 @@ struct shmob_drm_device {
unsigned int irq;
spinlock_t irq_lock; /* Protects hardware LDINTR register */

- struct drm_device *ddev;
+ struct drm_device ddev;

struct shmob_drm_crtc crtc;
struct drm_encoder encoder;
diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c
index 1a62e7f8a8a9e6df..20316907030b2789 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c
@@ -153,7 +153,7 @@ int shmob_drm_modeset_init(struct shmob_drm_device *sdev)
{
int ret;

- ret = drmm_mode_config_init(sdev->ddev);
+ ret = drmm_mode_config_init(&sdev->ddev);
if (ret)
return ret;

@@ -169,15 +169,15 @@ int shmob_drm_modeset_init(struct shmob_drm_device *sdev)
if (ret < 0)
return ret;

- drm_kms_helper_poll_init(sdev->ddev);
+ drm_kms_helper_poll_init(&sdev->ddev);

- sdev->ddev->mode_config.min_width = 0;
- sdev->ddev->mode_config.min_height = 0;
- sdev->ddev->mode_config.max_width = 4095;
- sdev->ddev->mode_config.max_height = 4095;
- sdev->ddev->mode_config.funcs = &shmob_drm_mode_config_funcs;
+ sdev->ddev.mode_config.min_width = 0;
+ sdev->ddev.mode_config.min_height = 0;
+ sdev->ddev.mode_config.max_width = 4095;
+ sdev->ddev.mode_config.max_height = 4095;
+ sdev->ddev.mode_config.funcs = &shmob_drm_mode_config_funcs;

- drm_helper_disable_unused_functions(sdev->ddev);
+ drm_helper_disable_unused_functions(&sdev->ddev);

return 0;
}
diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
index 1fb68b5fe915b8dc..17e66a018689f648 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
@@ -68,7 +68,7 @@ static void __shmob_drm_plane_setup(struct shmob_drm_plane *splane,
splane->format->ldbbsifr;

#define plane_reg_dump(sdev, splane, reg) \
- dev_dbg(sdev->ddev->dev, "%s(%u): %s 0x%08x 0x%08x\n", __func__, \
+ dev_dbg(sdev->ddev.dev, "%s(%u): %s 0x%08x 0x%08x\n", __func__, \
splane->index, #reg, \
lcdc_read(sdev, reg(splane->index)), \
lcdc_read(sdev, reg(splane->index) + LCDC_SIDE_B_OFFSET))
@@ -81,7 +81,7 @@ static void __shmob_drm_plane_setup(struct shmob_drm_plane *splane,
plane_reg_dump(sdev, splane, LDBnBSACR);

lcdc_write(sdev, LDBCR, LDBCR_UPC(splane->index));
- dev_dbg(sdev->ddev->dev, "%s(%u): %s 0x%08x\n", __func__, splane->index,
+ dev_dbg(sdev->ddev.dev, "%s(%u): %s 0x%08x\n", __func__, splane->index,
"LDBCR", lcdc_read(sdev, LDBCR));

lcdc_write(sdev, LDBnBSIFR(splane->index), format);
@@ -103,7 +103,7 @@ static void __shmob_drm_plane_setup(struct shmob_drm_plane *splane,

lcdc_write(sdev, LDBCR,
LDBCR_UPF(splane->index) | LDBCR_UPD(splane->index));
- dev_dbg(sdev->ddev->dev, "%s(%u): %s 0x%08x\n", __func__, splane->index,
+ dev_dbg(sdev->ddev.dev, "%s(%u): %s 0x%08x\n", __func__, splane->index,
"LDBCR", lcdc_read(sdev, LDBCR));

plane_reg_dump(sdev, splane, LDBnBSIFR);
@@ -198,7 +198,7 @@ int shmob_drm_plane_create(struct shmob_drm_device *sdev, unsigned int index)
{
struct shmob_drm_plane *splane;

- splane = drmm_universal_plane_alloc(sdev->ddev, struct shmob_drm_plane,
+ splane = drmm_universal_plane_alloc(&sdev->ddev, struct shmob_drm_plane,
plane, 1, &shmob_drm_plane_funcs,
formats, ARRAY_SIZE(formats), NULL,
DRM_PLANE_TYPE_OVERLAY, NULL);
--
2.34.1


2023-06-22 09:50:58

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH 12/39] drm: renesas: shmobile: Don't set display info width and height twice

From: Laurent Pinchart <[email protected]>

The display info width_mm and height_mm fields are set at init time and
never overwritten, don't set them a second time when getting modes.

Signed-off-by: Laurent Pinchart <[email protected]>
Signed-off-by: Geert Uytterhoeven <[email protected]>
---
drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 3 ---
1 file changed, 3 deletions(-)

diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
index c775c1d49f0e1ce9..0eeb1410b662d74b 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
@@ -618,9 +618,6 @@ static int shmob_drm_connector_get_modes(struct drm_connector *connector)
drm_mode_set_name(mode);
drm_mode_probed_add(connector, mode);

- connector->display_info.width_mm = sdev->pdata->panel.width_mm;
- connector->display_info.height_mm = sdev->pdata->panel.height_mm;
-
return 1;
}

--
2.34.1


2023-06-22 09:52:45

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH 30/39] drm: renesas: shmobile: Wait for page flip when turning CRTC off

Turning a CRTC off will prevent a queued page flip from ever completing,
potentially confusing userspace. Wait for queued page flips to complete
before turning the CRTC off to avoid this.

Signed-off-by: Geert Uytterhoeven <[email protected]>
---
.../gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 37 +++++++++++++++++++
.../gpu/drm/renesas/shmobile/shmob_drm_crtc.h | 3 ++
2 files changed, 40 insertions(+)

diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
index 1d7fcf64bf2aab80..d2a0ac5f9368c11c 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
@@ -285,11 +285,40 @@ void shmob_drm_crtc_finish_page_flip(struct shmob_drm_crtc *scrtc)
scrtc->event = NULL;
if (event) {
drm_crtc_send_vblank_event(&scrtc->base, event);
+ wake_up(&scrtc->flip_wait);
drm_crtc_vblank_put(&scrtc->base);
}
spin_unlock_irqrestore(&dev->event_lock, flags);
}

+static bool shmob_drm_crtc_page_flip_pending(struct shmob_drm_crtc *scrtc)
+{
+ struct drm_device *dev = scrtc->base.dev;
+ unsigned long flags;
+ bool pending;
+
+ spin_lock_irqsave(&dev->event_lock, flags);
+ pending = scrtc->event != NULL;
+ spin_unlock_irqrestore(&dev->event_lock, flags);
+
+ return pending;
+}
+
+static void shmob_drm_crtc_wait_page_flip(struct shmob_drm_crtc *scrtc)
+{
+ struct drm_crtc *crtc = &scrtc->base;
+ struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);
+
+ if (wait_event_timeout(scrtc->flip_wait,
+ !shmob_drm_crtc_page_flip_pending(scrtc),
+ msecs_to_jiffies(50)))
+ return;
+
+ dev_warn(sdev->dev, "page flip timeout\n");
+
+ shmob_drm_crtc_finish_page_flip(scrtc);
+}
+
/* -----------------------------------------------------------------------------
* CRTC Functions
*/
@@ -302,6 +331,12 @@ static void shmob_drm_crtc_stop(struct shmob_drm_crtc *scrtc)
if (!scrtc->started)
return;

+ /*
+ * Wait for page flip completion before stopping the CRTC as userspace
+ * expects page flips to eventually complete.
+ */
+ shmob_drm_crtc_wait_page_flip(scrtc);
+
/* Stop the LCDC. */
shmob_drm_crtc_start_stop(scrtc, false);

@@ -515,6 +550,8 @@ int shmob_drm_crtc_create(struct shmob_drm_device *sdev)
unsigned int i;
int ret;

+ init_waitqueue_head(&sdev->crtc.flip_wait);
+
sdev->crtc.dpms = DRM_MODE_DPMS_OFF;

primary = shmob_drm_plane_create(sdev, 0);
diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
index 2c6d7541427581a6..b9863e026e8a9b83 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
@@ -14,6 +14,8 @@
#include <drm/drm_connector.h>
#include <drm/drm_encoder.h>

+#include <linux/wait.h>
+
#include <video/videomode.h>

struct drm_pending_vblank_event;
@@ -24,6 +26,7 @@ struct shmob_drm_crtc {
struct drm_crtc base;

struct drm_pending_vblank_event *event;
+ wait_queue_head_t flip_wait;
int dpms;

const struct shmob_drm_format_info *format;
--
2.34.1


2023-06-22 09:52:57

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH 25/39] drm: renesas: shmobile: Rename shmob_drm_crtc.crtc

Rename the "crtc" member of the shmob_drm_crtc subclass structure to
"base", to improve readability.

Signed-off-by: Geert Uytterhoeven <[email protected]>
---
.../gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 26 +++++++++----------
.../gpu/drm/renesas/shmobile/shmob_drm_crtc.h | 2 +-
2 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
index 3f6af12f45988124..3f0b71253ed929c9 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
@@ -64,7 +64,7 @@ static void shmob_drm_clk_off(struct shmob_drm_device *sdev)

static void shmob_drm_crtc_setup_geometry(struct shmob_drm_crtc *scrtc)
{
- struct drm_crtc *crtc = &scrtc->crtc;
+ struct drm_crtc *crtc = &scrtc->base;
struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);
const struct drm_display_info *info = &sdev->connector->display_info;
const struct drm_display_mode *mode = &crtc->mode;
@@ -152,7 +152,7 @@ static void shmob_drm_crtc_setup_geometry(struct shmob_drm_crtc *scrtc)

static void shmob_drm_crtc_start_stop(struct shmob_drm_crtc *scrtc, bool start)
{
- struct shmob_drm_device *sdev = to_shmob_device(scrtc->crtc.dev);
+ struct shmob_drm_device *sdev = to_shmob_device(scrtc->base.dev);
u32 value;

value = lcdc_read(sdev, LDCNT2R);
@@ -185,7 +185,7 @@ static void shmob_drm_crtc_start_stop(struct shmob_drm_crtc *scrtc, bool start)
*/
static void shmob_drm_crtc_start(struct shmob_drm_crtc *scrtc)
{
- struct drm_crtc *crtc = &scrtc->crtc;
+ struct drm_crtc *crtc = &scrtc->base;
struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);
const struct shmob_drm_interface_data *idata = &sdev->pdata->iface;
const struct shmob_drm_format_info *format;
@@ -272,7 +272,7 @@ static void shmob_drm_crtc_start(struct shmob_drm_crtc *scrtc)

static void shmob_drm_crtc_stop(struct shmob_drm_crtc *scrtc)
{
- struct drm_crtc *crtc = &scrtc->crtc;
+ struct drm_crtc *crtc = &scrtc->base;
struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);

if (!scrtc->started)
@@ -308,7 +308,7 @@ void shmob_drm_crtc_resume(struct shmob_drm_crtc *scrtc)
static void shmob_drm_crtc_compute_base(struct shmob_drm_crtc *scrtc,
int x, int y)
{
- struct drm_crtc *crtc = &scrtc->crtc;
+ struct drm_crtc *crtc = &scrtc->base;
struct drm_framebuffer *fb = crtc->primary->fb;
struct drm_gem_dma_object *gem;
unsigned int bpp;
@@ -329,7 +329,7 @@ static void shmob_drm_crtc_compute_base(struct shmob_drm_crtc *scrtc,

static void shmob_drm_crtc_update_base(struct shmob_drm_crtc *scrtc)
{
- struct drm_crtc *crtc = &scrtc->crtc;
+ struct drm_crtc *crtc = &scrtc->base;
struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);

shmob_drm_crtc_compute_base(scrtc, crtc->x, crtc->y);
@@ -343,7 +343,7 @@ static void shmob_drm_crtc_update_base(struct shmob_drm_crtc *scrtc)

static inline struct shmob_drm_crtc *to_shmob_crtc(struct drm_crtc *crtc)
{
- return container_of(crtc, struct shmob_drm_crtc, crtc);
+ return container_of(crtc, struct shmob_drm_crtc, base);
}

static void shmob_drm_crtc_dpms(struct drm_crtc *crtc, int mode)
@@ -415,15 +415,15 @@ static const struct drm_crtc_helper_funcs crtc_helper_funcs = {
void shmob_drm_crtc_finish_page_flip(struct shmob_drm_crtc *scrtc)
{
struct drm_pending_vblank_event *event;
- struct drm_device *dev = scrtc->crtc.dev;
+ struct drm_device *dev = scrtc->base.dev;
unsigned long flags;

spin_lock_irqsave(&dev->event_lock, flags);
event = scrtc->event;
scrtc->event = NULL;
if (event) {
- drm_crtc_send_vblank_event(&scrtc->crtc, event);
- drm_crtc_vblank_put(&scrtc->crtc);
+ drm_crtc_send_vblank_event(&scrtc->base, event);
+ drm_crtc_vblank_put(&scrtc->base);
}
spin_unlock_irqrestore(&dev->event_lock, flags);
}
@@ -435,7 +435,7 @@ static int shmob_drm_crtc_page_flip(struct drm_crtc *crtc,
struct drm_modeset_acquire_ctx *ctx)
{
struct shmob_drm_crtc *scrtc = to_shmob_crtc(crtc);
- struct drm_device *dev = scrtc->crtc.dev;
+ struct drm_device *dev = scrtc->base.dev;
unsigned long flags;

spin_lock_irqsave(&dev->event_lock, flags);
@@ -450,7 +450,7 @@ static int shmob_drm_crtc_page_flip(struct drm_crtc *crtc,

if (event) {
event->pipe = 0;
- drm_crtc_vblank_get(&scrtc->crtc);
+ drm_crtc_vblank_get(&scrtc->base);
spin_lock_irqsave(&dev->event_lock, flags);
scrtc->event = event;
spin_unlock_irqrestore(&dev->event_lock, flags);
@@ -502,7 +502,7 @@ static const struct drm_crtc_funcs crtc_funcs = {

int shmob_drm_crtc_create(struct shmob_drm_device *sdev)
{
- struct drm_crtc *crtc = &sdev->crtc.crtc;
+ struct drm_crtc *crtc = &sdev->crtc.base;
struct drm_plane *primary, *plane;
unsigned int i;
int ret;
diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
index f507eaf912e16a22..79cce0a0ada4cfce 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
@@ -21,7 +21,7 @@ struct shmob_drm_device;
struct shmob_drm_format_info;

struct shmob_drm_crtc {
- struct drm_crtc crtc;
+ struct drm_crtc base;

struct drm_pending_vblank_event *event;
int dpms;
--
2.34.1


2023-06-22 09:53:08

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH 39/39] drm: renesas: shmobile: Add DT support

Add DT support, by:
1. Creating a panel bridge from DT, and attaching it to the encoder,
2. Replacing the custom connector with a bridge connector,
3. Obtaining clock configuration based on the compatible value.

Note that for now the driver uses a fixed clock configuration selecting
the bus clock, as the current code to select other clock inputs needs
changes to support any other SoCs than SH7724.

Signed-off-by: Geert Uytterhoeven <[email protected]>
Cc: Rob Herring <[email protected]>
Cc: Krzysztof Kozlowski <[email protected]>
Cc: Conor Dooley <[email protected]>
Cc: [email protected]
---
SH-Mobile AG5 (SH73A0) support is untested.

Unbind crashes when drm_encoder_cleanup() calls drm_bridge_detach(), as
the bridge (allocated by devm_drm_panel_bridge_add()) has already been
freed by that time.
Should I allocate my encoder with devm_kzalloc(), instead of embedding
it inside struct shmob_drm_device?
---
.../gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 101 +++++++++++++++---
.../gpu/drm/renesas/shmobile/shmob_drm_crtc.h | 1 +
.../gpu/drm/renesas/shmobile/shmob_drm_drv.c | 27 ++++-
.../gpu/drm/renesas/shmobile/shmob_drm_drv.h | 6 ++
4 files changed, 118 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
index 17456dde57637ab8..1ec87841658de4f0 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
@@ -9,12 +9,16 @@

#include <linux/clk.h>
#include <linux/media-bus-format.h>
+#include <linux/of.h>
+#include <linux/of_graph.h>
#include <linux/pm_runtime.h>

#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_atomic_state_helper.h>
#include <drm/drm_atomic_uapi.h>
+#include <drm/drm_bridge.h>
+#include <drm/drm_bridge_connector.h>
#include <drm/drm_crtc.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_fb_dma_helper.h>
@@ -23,6 +27,7 @@
#include <drm/drm_gem_dma_helper.h>
#include <drm/drm_modeset_helper.h>
#include <drm/drm_modeset_helper_vtables.h>
+#include <drm/drm_panel.h>
#include <drm/drm_probe_helper.h>
#include <drm/drm_simple_kms_helper.h>
#include <drm/drm_vblank.h>
@@ -35,10 +40,6 @@
#include "shmob_drm_plane.h"
#include "shmob_drm_regs.h"

-/*
- * TODO: panel support
- */
-
/* -----------------------------------------------------------------------------
* Clock management
*/
@@ -129,7 +130,6 @@ static void shmob_drm_crtc_setup_geometry(struct shmob_drm_crtc *scrtc)
value |= LDMT1R_VPOL;
if (mode->flags & DRM_MODE_FLAG_NHSYNC)
value |= LDMT1R_HPOL;
-
lcdc_write(sdev, LDMT1R, value);

value = ((mode->hdisplay / 8) << 16) /* HDCN */
@@ -191,7 +191,7 @@ static void shmob_drm_crtc_start(struct shmob_drm_crtc *scrtc)
{
struct drm_crtc *crtc = &scrtc->base;
struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);
- const struct shmob_drm_interface_data *idata = &sdev->pdata->iface;
+ unsigned int clk_div = sdev->config.clk_div;
struct device *dev = sdev->dev;
u32 value;
int ret;
@@ -220,17 +220,17 @@ static void shmob_drm_crtc_start(struct shmob_drm_crtc *scrtc)
lcdc_write(sdev, LDPMR, 0);

value = sdev->lddckr;
- if (idata->clk_div) {
+ if (clk_div) {
/* FIXME: sh7724 can only use 42, 48, 54 and 60 for the divider
* denominator.
*/
lcdc_write(sdev, LDDCKPAT1R, 0);
- lcdc_write(sdev, LDDCKPAT2R, (1 << (idata->clk_div / 2)) - 1);
+ lcdc_write(sdev, LDDCKPAT2R, (1 << (clk_div / 2)) - 1);

- if (idata->clk_div == 1)
+ if (clk_div == 1)
value |= LDDCKR_MOSEL;
else
- value |= idata->clk_div;
+ value |= clk_div;
}

lcdc_write(sdev, LDDCKR, value);
@@ -479,7 +479,7 @@ int shmob_drm_crtc_create(struct shmob_drm_device *sdev)
}

/* -----------------------------------------------------------------------------
- * Encoder
+ * Legacy Encoder
*/

static bool shmob_drm_encoder_mode_fixup(struct drm_encoder *encoder,
@@ -508,9 +508,43 @@ static const struct drm_encoder_helper_funcs encoder_helper_funcs = {
.mode_fixup = shmob_drm_encoder_mode_fixup,
};

+/* -----------------------------------------------------------------------------
+ * Encoder
+ */
+
+static int shmob_drm_encoder_init(struct shmob_drm_device *sdev,
+ struct device_node *enc_node)
+{
+ struct drm_bridge *bridge;
+ struct drm_panel *panel;
+ int ret;
+
+ /* Create a panel bridge */
+ panel = of_drm_find_panel(enc_node);
+ if (IS_ERR(panel))
+ return PTR_ERR(panel);
+
+ bridge = devm_drm_panel_bridge_add(sdev->dev, panel);
+ if (IS_ERR(bridge))
+ return PTR_ERR(bridge);
+
+ /* Attach the bridge to the encoder */
+ ret = drm_bridge_attach(&sdev->encoder, bridge, NULL,
+ DRM_BRIDGE_ATTACH_NO_CONNECTOR);
+ if (ret) {
+ dev_err(sdev->dev, "failed to attach bridge %pOF: %pe\n",
+ bridge->of_node, ERR_PTR(ret));
+ return ret;
+ }
+
+ return 0;
+}
+
int shmob_drm_encoder_create(struct shmob_drm_device *sdev)
{
struct drm_encoder *encoder = &sdev->encoder;
+ struct device_node *np = sdev->dev->of_node;
+ struct device_node *ep_node, *entity;
int ret;

encoder->possible_crtcs = 1;
@@ -520,13 +554,45 @@ int shmob_drm_encoder_create(struct shmob_drm_device *sdev)
if (ret < 0)
return ret;

- drm_encoder_helper_add(encoder, &encoder_helper_funcs);
+ if (sdev->pdata) {
+ drm_encoder_helper_add(encoder, &encoder_helper_funcs);
+ return 0;
+ }
+
+ for_each_endpoint_of_node(np, ep_node) {
+ struct of_endpoint ep;
+
+ ret = of_graph_parse_endpoint(ep_node, &ep);
+ if (ret < 0) {
+ of_node_put(ep_node);
+ return ret;
+ }
+ /* Ignore all but the LCD port */
+ if (ep.port || ep.id)
+ continue;
+
+ entity = of_graph_get_remote_port_parent(ep.local_node);
+ if (!entity)
+ continue;
+
+ if (!of_device_is_available(entity)) {
+ of_node_put(entity);
+ continue;
+ }
+
+ ret = shmob_drm_encoder_init(sdev, entity);
+ if (ret < 0) {
+ of_node_put(entity);
+ of_node_put(ep_node);
+ return ret;
+ }
+ }

return 0;
}

/* -----------------------------------------------------------------------------
- * Connector
+ * Legacy Connector
*/

static inline struct shmob_drm_connector *to_shmob_connector(struct drm_connector *connector)
@@ -626,13 +692,20 @@ shmob_drm_connector_init(struct shmob_drm_device *sdev,
return connector;
}

+/* -----------------------------------------------------------------------------
+ * Connector
+ */
+
int shmob_drm_connector_create(struct shmob_drm_device *sdev,
struct drm_encoder *encoder)
{
struct drm_connector *connector;
int ret;

- connector = shmob_drm_connector_init(sdev, encoder);
+ if (sdev->pdata)
+ connector = shmob_drm_connector_init(sdev, encoder);
+ else
+ connector = drm_bridge_connector_init(&sdev->ddev, encoder);
if (IS_ERR(connector)) {
dev_err(sdev->dev, "failed to created connector: %pe\n",
connector);
diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
index 89a0746f9a35807d..16e1712dd04e0f2b 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
@@ -29,6 +29,7 @@ struct shmob_drm_crtc {
wait_queue_head_t flip_wait;
};

+/* Legacy connector */
struct shmob_drm_connector {
struct drm_connector base;
struct drm_encoder *encoder;
diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
index 576869164479ec6b..db72ca1c8b2f44c9 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
@@ -11,6 +11,7 @@
#include <linux/io.h>
#include <linux/mm.h>
#include <linux/module.h>
+#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
@@ -147,11 +148,13 @@ static int shmob_drm_remove(struct platform_device *pdev)
static int shmob_drm_probe(struct platform_device *pdev)
{
struct shmob_drm_platform_data *pdata = pdev->dev.platform_data;
+ const struct shmob_drm_config *config;
struct shmob_drm_device *sdev;
struct drm_device *ddev;
int ret;

- if (pdata == NULL) {
+ config = of_device_get_match_data(&pdev->dev);
+ if (!config && !pdata) {
dev_err(&pdev->dev, "no platform data\n");
return -EINVAL;
}
@@ -167,7 +170,13 @@ static int shmob_drm_probe(struct platform_device *pdev)

ddev = &sdev->ddev;
sdev->dev = &pdev->dev;
- sdev->pdata = pdata;
+ if (config) {
+ sdev->config = *config;
+ } else {
+ sdev->pdata = pdata;
+ sdev->config.clk_source = pdata->clk_source;
+ sdev->config.clk_div = pdata->iface.clk_div;
+ }
spin_lock_init(&sdev->irq_lock);

platform_set_drvdata(pdev, sdev);
@@ -180,7 +189,7 @@ static int shmob_drm_probe(struct platform_device *pdev)
if (ret)
return ret;

- ret = shmob_drm_setup_clocks(sdev, pdata->clk_source);
+ ret = shmob_drm_setup_clocks(sdev, sdev->config.clk_source);
if (ret < 0)
return ret;

@@ -224,11 +233,23 @@ static int shmob_drm_probe(struct platform_device *pdev)
return ret;
}

+static const struct shmob_drm_config shmob_arm_config = {
+ .clk_source = SHMOB_DRM_CLK_BUS,
+ .clk_div = 5,
+};
+
+static const struct of_device_id shmob_drm_of_table[] __maybe_unused = {
+ { .compatible = "renesas,r8a7740-lcdc", .data = &shmob_arm_config, },
+ { .compatible = "renesas,sh73a0-lcdc", .data = &shmob_arm_config, },
+ { /* sentinel */ }
+};
+
static struct platform_driver shmob_drm_platform_driver = {
.probe = shmob_drm_probe,
.remove = shmob_drm_remove,
.driver = {
.name = "shmob-drm",
+ .of_match_table = of_match_ptr(shmob_drm_of_table),
.pm = pm_sleep_ptr(&shmob_drm_pm_ops),
},
};
diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.h b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.h
index 18907e5ace51c681..088ac5381e91e61a 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.h
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.h
@@ -20,9 +20,15 @@ struct clk;
struct device;
struct drm_device;

+struct shmob_drm_config {
+ enum shmob_drm_clk_source clk_source;
+ unsigned int clk_div;
+};
+
struct shmob_drm_device {
struct device *dev;
const struct shmob_drm_platform_data *pdata;
+ struct shmob_drm_config config;

void __iomem *mmio;
struct clk *clock;
--
2.34.1


2023-06-22 09:53:13

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH 34/39] drm: renesas: shmobile: Atomic conversion part 1

Implement atomic mode setting for both the primary and overlay planes.
This involves:
- Moving the primary plane handling code from CRTC mode setting to
plane handling shared by primary and overlay planes,
- Adding basic CRTC and mode config atomic mode setting ops, which
don't do much yet.

Signed-off-by: Geert Uytterhoeven <[email protected]>
---
.../gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 128 +++------
.../gpu/drm/renesas/shmobile/shmob_drm_crtc.h | 3 -
.../gpu/drm/renesas/shmobile/shmob_drm_drv.c | 4 +-
.../gpu/drm/renesas/shmobile/shmob_drm_kms.c | 13 +-
.../drm/renesas/shmobile/shmob_drm_plane.c | 260 ++++++++++++------
.../drm/renesas/shmobile/shmob_drm_plane.h | 1 -
6 files changed, 222 insertions(+), 187 deletions(-)

diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
index ef327da39bca415a..ea19e802792e24a4 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
@@ -11,6 +11,9 @@
#include <linux/media-bus-format.h>
#include <linux/pm_runtime.h>

+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_atomic_state_helper.h>
+#include <drm/drm_atomic_uapi.h>
#include <drm/drm_crtc.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_fb_dma_helper.h>
@@ -188,27 +191,21 @@ static void shmob_drm_crtc_start(struct shmob_drm_crtc *scrtc)
struct drm_crtc *crtc = &scrtc->base;
struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);
const struct shmob_drm_interface_data *idata = &sdev->pdata->iface;
- const struct shmob_drm_format_info *format;
- struct drm_device *dev = &sdev->ddev;
- struct drm_plane *plane;
+ struct device *dev = sdev->dev;
u32 value;
int ret;

if (scrtc->started)
return;

- format = shmob_drm_format_info(crtc->primary->fb->format->format);
- if (WARN_ON(format == NULL))
- return;
-
- ret = pm_runtime_resume_and_get(sdev->dev);
+ ret = pm_runtime_resume_and_get(dev);
if (ret)
return;

/* Enable clocks before accessing the hardware. */
ret = shmob_drm_clk_on(sdev);
if (ret < 0) {
- pm_runtime_put(sdev->dev);
+ pm_runtime_put(dev);
return;
}

@@ -245,23 +242,8 @@ static void shmob_drm_crtc_start(struct shmob_drm_crtc *scrtc)
/* Setup geometry, format, frame buffer memory and operation mode. */
shmob_drm_crtc_setup_geometry(scrtc);

- /* TODO: Handle YUV colorspaces. Hardcode REC709 for now. */
- lcdc_write(sdev, LDDFR, format->lddfr | LDDFR_CF1);
- lcdc_write(sdev, LDMLSR, scrtc->line_size);
- lcdc_write(sdev, LDSA1R, scrtc->dma[0]);
- if (shmob_drm_format_is_yuv(format))
- lcdc_write(sdev, LDSA2R, scrtc->dma[1]);
lcdc_write(sdev, LDSM1R, 0);

- /* Word and long word swap. */
- lcdc_write(sdev, LDDDSR, format->ldddsr);
-
- /* Setup planes. */
- drm_for_each_legacy_plane(plane, dev) {
- if (plane->crtc == crtc)
- shmob_drm_plane_setup(plane);
- }
-
/* Enable the display output. */
lcdc_write(sdev, LDCNT1R, LDCNT1R_DE);

@@ -369,42 +351,6 @@ void shmob_drm_crtc_resume(struct shmob_drm_crtc *scrtc)
shmob_drm_crtc_start(scrtc);
}

-static void shmob_drm_crtc_compute_base(struct shmob_drm_crtc *scrtc,
- int x, int y)
-{
- struct drm_crtc *crtc = &scrtc->base;
- struct drm_framebuffer *fb = crtc->primary->fb;
- struct drm_gem_dma_object *gem;
- unsigned int bpp;
-
- bpp = shmob_drm_format_is_yuv(scrtc->format) ? 8 : scrtc->format->bpp;
- gem = drm_fb_dma_get_gem_obj(fb, 0);
- scrtc->dma[0] = gem->dma_addr + fb->offsets[0]
- + y * fb->pitches[0] + x * bpp / 8;
-
- if (shmob_drm_format_is_yuv(scrtc->format)) {
- bpp = scrtc->format->bpp - 8;
- gem = drm_fb_dma_get_gem_obj(fb, 1);
- scrtc->dma[1] = gem->dma_addr + fb->offsets[1]
- + y / (bpp == 4 ? 2 : 1) * fb->pitches[1]
- + x * (bpp == 16 ? 2 : 1);
- }
-}
-
-static void shmob_drm_crtc_update_base(struct shmob_drm_crtc *scrtc)
-{
- struct drm_crtc *crtc = &scrtc->base;
- struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);
-
- shmob_drm_crtc_compute_base(scrtc, crtc->x, crtc->y);
-
- lcdc_write_mirror(sdev, LDSA1R, scrtc->dma[0]);
- if (shmob_drm_format_is_yuv(scrtc->format))
- lcdc_write_mirror(sdev, LDSA2R, scrtc->dma[1]);
-
- lcdc_write(sdev, LDRCNTR, lcdc_read(sdev, LDRCNTR) ^ LDRCNTR_MRS);
-}
-
static inline struct shmob_drm_crtc *to_shmob_crtc(struct drm_crtc *crtc)
{
return container_of(crtc, struct shmob_drm_crtc, base);
@@ -430,50 +376,45 @@ static void shmob_drm_crtc_mode_prepare(struct drm_crtc *crtc)
shmob_drm_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
}

-static int shmob_drm_crtc_mode_set(struct drm_crtc *crtc,
- struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode,
- int x, int y,
- struct drm_framebuffer *old_fb)
+static void shmob_drm_crtc_mode_commit(struct drm_crtc *crtc)
{
- struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);
- struct shmob_drm_crtc *scrtc = to_shmob_crtc(crtc);
- const struct shmob_drm_format_info *format;
-
- format = shmob_drm_format_info(crtc->primary->fb->format->format);
- if (format == NULL) {
- dev_dbg(sdev->dev, "mode_set: unsupported format %p4cc\n",
- &crtc->primary->fb->format->format);
- return -EINVAL;
- }
-
- scrtc->format = format;
- scrtc->line_size = crtc->primary->fb->pitches[0];
-
- shmob_drm_crtc_compute_base(scrtc, x, y);
+ shmob_drm_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
+}

+static int shmob_drm_crtc_atomic_check(struct drm_crtc *crtc,
+ struct drm_atomic_state *state)
+{
return 0;
}

-static void shmob_drm_crtc_mode_commit(struct drm_crtc *crtc)
+static void shmob_drm_crtc_atomic_begin(struct drm_crtc *crtc,
+ struct drm_atomic_state *state)
{
- shmob_drm_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
}

-static int shmob_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
- struct drm_framebuffer *old_fb)
+static void shmob_drm_crtc_atomic_flush(struct drm_crtc *crtc,
+ struct drm_atomic_state *state)
{
- shmob_drm_crtc_update_base(to_shmob_crtc(crtc));
+ struct drm_pending_vblank_event *event;
+ struct drm_device *dev = crtc->dev;
+ unsigned long flags;

- return 0;
+ if (crtc->state->event) {
+ spin_lock_irqsave(&dev->event_lock, flags);
+ event = crtc->state->event;
+ crtc->state->event = NULL;
+ drm_crtc_send_vblank_event(crtc, event);
+ spin_unlock_irqrestore(&dev->event_lock, flags);
+ }
}

static const struct drm_crtc_helper_funcs crtc_helper_funcs = {
.dpms = shmob_drm_crtc_dpms,
.prepare = shmob_drm_crtc_mode_prepare,
.commit = shmob_drm_crtc_mode_commit,
- .mode_set = shmob_drm_crtc_mode_set,
- .mode_set_base = shmob_drm_crtc_mode_set_base,
+ .atomic_check = shmob_drm_crtc_atomic_check,
+ .atomic_begin = shmob_drm_crtc_atomic_begin,
+ .atomic_flush = shmob_drm_crtc_atomic_flush,
};

static int shmob_drm_crtc_page_flip(struct drm_crtc *crtc,
@@ -493,8 +434,7 @@ static int shmob_drm_crtc_page_flip(struct drm_crtc *crtc,
}
spin_unlock_irqrestore(&dev->event_lock, flags);

- crtc->primary->fb = fb;
- shmob_drm_crtc_update_base(scrtc);
+ drm_atomic_set_fb_for_plane(crtc->primary->state, fb);

if (event) {
event->pipe = 0;
@@ -541,9 +481,12 @@ static void shmob_drm_disable_vblank(struct drm_crtc *crtc)
}

static const struct drm_crtc_funcs crtc_funcs = {
+ .reset = drm_atomic_helper_crtc_reset,
.destroy = drm_crtc_cleanup,
- .set_config = drm_crtc_helper_set_config,
+ .set_config = drm_atomic_helper_set_config,
.page_flip = shmob_drm_crtc_page_flip,
+ .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
+ .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
.enable_vblank = shmob_drm_enable_vblank,
.disable_vblank = shmob_drm_disable_vblank,
};
@@ -679,8 +622,11 @@ static void shmob_drm_connector_destroy(struct drm_connector *connector)

static const struct drm_connector_funcs connector_funcs = {
.dpms = drm_helper_connector_dpms,
+ .reset = drm_atomic_helper_connector_reset,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = shmob_drm_connector_destroy,
+ .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
};

static struct drm_connector *
diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
index b9863e026e8a9b83..fe41e42d6cc55275 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
@@ -29,9 +29,6 @@ struct shmob_drm_crtc {
wait_queue_head_t flip_wait;
int dpms;

- const struct shmob_drm_format_info *format;
- unsigned long dma[2];
- unsigned int line_size;
bool started;
};

diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
index 636f1888b815579b..9107f84224602683 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
@@ -16,7 +16,7 @@
#include <linux/pm_runtime.h>
#include <linux/slab.h>

-#include <drm/drm_crtc_helper.h>
+#include <drm/drm_atomic_helper.h>
#include <drm/drm_drv.h>
#include <drm/drm_fbdev_generic.h>
#include <drm/drm_gem_dma_helper.h>
@@ -146,7 +146,7 @@ static int shmob_drm_remove(struct platform_device *pdev)
struct drm_device *ddev = &sdev->ddev;

drm_dev_unregister(ddev);
- drm_helper_force_disable_all(ddev);
+ drm_atomic_helper_shutdown(ddev);
drm_kms_helper_poll_fini(ddev);
return 0;
}
diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c
index 20316907030b2789..4202ab00fb0cf487 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c
@@ -7,6 +7,7 @@
* Laurent Pinchart ([email protected])
*/

+#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_fourcc.h>
@@ -17,6 +18,7 @@
#include "shmob_drm_crtc.h"
#include "shmob_drm_drv.h"
#include "shmob_drm_kms.h"
+#include "shmob_drm_plane.h"
#include "shmob_drm_regs.h"

/* -----------------------------------------------------------------------------
@@ -147,13 +149,16 @@ shmob_drm_fb_create(struct drm_device *dev, struct drm_file *file_priv,

static const struct drm_mode_config_funcs shmob_drm_mode_config_funcs = {
.fb_create = shmob_drm_fb_create,
+ .atomic_check = drm_atomic_helper_check,
+ .atomic_commit = drm_atomic_helper_commit,
};

int shmob_drm_modeset_init(struct shmob_drm_device *sdev)
{
+ struct drm_device *dev = &sdev->ddev;
int ret;

- ret = drmm_mode_config_init(&sdev->ddev);
+ ret = drmm_mode_config_init(dev);
if (ret)
return ret;

@@ -169,7 +174,9 @@ int shmob_drm_modeset_init(struct shmob_drm_device *sdev)
if (ret < 0)
return ret;

- drm_kms_helper_poll_init(&sdev->ddev);
+ drm_mode_config_reset(dev);
+
+ drm_kms_helper_poll_init(dev);

sdev->ddev.mode_config.min_width = 0;
sdev->ddev.mode_config.min_height = 0;
@@ -177,7 +184,5 @@ int shmob_drm_modeset_init(struct shmob_drm_device *sdev)
sdev->ddev.mode_config.max_height = 4095;
sdev->ddev.mode_config.funcs = &shmob_drm_mode_config_funcs;

- drm_helper_disable_unused_functions(&sdev->ddev);
-
return 0;
}
diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
index e300e5c0de70a9b1..2a77e93c054bf2e8 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
@@ -7,6 +7,8 @@
* Laurent Pinchart ([email protected])
*/

+#include <drm/drm_atomic.h>
+#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc.h>
#include <drm/drm_fb_dma_helper.h>
#include <drm/drm_fourcc.h>
@@ -22,17 +24,13 @@
struct shmob_drm_plane {
struct drm_plane base;
unsigned int index;
- unsigned int alpha;
+};
+
+struct shmob_drm_plane_state {
+ struct drm_plane_state base;

const struct shmob_drm_format_info *format;
- unsigned long dma[2];
-
- unsigned int src_x;
- unsigned int src_y;
- unsigned int crtc_x;
- unsigned int crtc_y;
- unsigned int crtc_w;
- unsigned int crtc_h;
+ u32 dma[2];
};

static inline struct shmob_drm_plane *to_shmob_plane(struct drm_plane *plane)
@@ -40,37 +38,66 @@ static inline struct shmob_drm_plane *to_shmob_plane(struct drm_plane *plane)
return container_of(plane, struct shmob_drm_plane, base);
}

-static void shmob_drm_plane_compute_base(struct shmob_drm_plane *splane,
- struct drm_framebuffer *fb,
- int x, int y)
+static inline struct shmob_drm_plane_state *to_shmob_plane_state(struct drm_plane_state *state)
+{
+ return container_of(state, struct shmob_drm_plane_state, base);
+}
+
+static void shmob_drm_plane_compute_base(struct shmob_drm_plane_state *sstate)
{
+ struct drm_framebuffer *fb = sstate->base.fb;
+ unsigned int x = sstate->base.src_x >> 16;
+ unsigned int y = sstate->base.src_y >> 16;
struct drm_gem_dma_object *gem;
unsigned int bpp;

- bpp = shmob_drm_format_is_yuv(splane->format) ? 8 : splane->format->bpp;
+ bpp = shmob_drm_format_is_yuv(sstate->format) ? 8 : sstate->format->bpp;
gem = drm_fb_dma_get_gem_obj(fb, 0);
- splane->dma[0] = gem->dma_addr + fb->offsets[0]
+ sstate->dma[0] = gem->dma_addr + fb->offsets[0]
+ y * fb->pitches[0] + x * bpp / 8;

- if (shmob_drm_format_is_yuv(splane->format)) {
- bpp = splane->format->bpp - 8;
+ if (shmob_drm_format_is_yuv(sstate->format)) {
+ bpp = sstate->format->bpp - 8;
gem = drm_fb_dma_get_gem_obj(fb, 1);
- splane->dma[1] = gem->dma_addr + fb->offsets[1]
+ sstate->dma[1] = gem->dma_addr + fb->offsets[1]
+ y / (bpp == 4 ? 2 : 1) * fb->pitches[1]
+ x * (bpp == 16 ? 2 : 1);
}
}

-static void __shmob_drm_plane_setup(struct shmob_drm_plane *splane,
- struct drm_framebuffer *fb)
+static void shmob_drm_primary_plane_setup(struct shmob_drm_plane *splane,
+ struct drm_plane_state *state)
{
+ struct shmob_drm_plane_state *sstate = to_shmob_plane_state(state);
+ struct shmob_drm_device *sdev = to_shmob_device(splane->base.dev);
+ struct drm_framebuffer *fb = state->fb;
+
+ /* TODO: Handle YUV colorspaces. Hardcode REC709 for now. */
+ lcdc_write(sdev, LDDFR, sstate->format->lddfr | LDDFR_CF1);
+ lcdc_write(sdev, LDMLSR, fb->pitches[0]);
+
+ /* Word and long word swap. */
+ lcdc_write(sdev, LDDDSR, sstate->format->ldddsr);
+
+ lcdc_write_mirror(sdev, LDSA1R, sstate->dma[0]);
+ if (shmob_drm_format_is_yuv(sstate->format))
+ lcdc_write_mirror(sdev, LDSA2R, sstate->dma[1]);
+
+ lcdc_write(sdev, LDRCNTR, lcdc_read(sdev, LDRCNTR) ^ LDRCNTR_MRS);
+}
+
+static void shmob_drm_overlay_plane_setup(struct shmob_drm_plane *splane,
+ struct drm_plane_state *state)
+{
+ struct shmob_drm_plane_state *sstate = to_shmob_plane_state(state);
struct shmob_drm_device *sdev = to_shmob_device(splane->base.dev);
unsigned int ovl_idx = splane->index - 1;
+ struct drm_framebuffer *fb = state->fb;
u32 format;

/* TODO: Support ROP3 mode */
- format = LDBBSIFR_EN | (splane->alpha << LDBBSIFR_LAY_SHIFT) |
- splane->format->ldbbsifr;
+ format = LDBBSIFR_EN | ((state->alpha >> 8) << LDBBSIFR_LAY_SHIFT) |
+ sstate->format->ldbbsifr;

#define plane_reg_dump(sdev, ovl_idx, reg) \
dev_dbg(sdev->ddev.dev, "%s(%u): %s 0x%08x 0x%08x\n", __func__, \
@@ -92,22 +119,19 @@ static void __shmob_drm_plane_setup(struct shmob_drm_plane *splane,
lcdc_write(sdev, LDBnBSIFR(ovl_idx), format);

lcdc_write(sdev, LDBnBSSZR(ovl_idx),
- (splane->crtc_h << LDBBSSZR_BVSS_SHIFT) |
- (splane->crtc_w << LDBBSSZR_BHSS_SHIFT));
+ (state->crtc_h << LDBBSSZR_BVSS_SHIFT) |
+ (state->crtc_w << LDBBSSZR_BHSS_SHIFT));
lcdc_write(sdev, LDBnBLOCR(ovl_idx),
- (splane->crtc_y << LDBBLOCR_CVLC_SHIFT) |
- (splane->crtc_x << LDBBLOCR_CHLC_SHIFT));
+ (state->crtc_y << LDBBLOCR_CVLC_SHIFT) |
+ (state->crtc_x << LDBBLOCR_CHLC_SHIFT));
lcdc_write(sdev, LDBnBSMWR(ovl_idx),
fb->pitches[0] << LDBBSMWR_BSMW_SHIFT);

- shmob_drm_plane_compute_base(splane, fb, splane->src_x, splane->src_y);
-
- lcdc_write(sdev, LDBnBSAYR(ovl_idx), splane->dma[0]);
- if (shmob_drm_format_is_yuv(splane->format))
- lcdc_write(sdev, LDBnBSACR(ovl_idx), splane->dma[1]);
+ lcdc_write(sdev, LDBnBSAYR(ovl_idx), sstate->dma[0]);
+ if (shmob_drm_format_is_yuv(sstate->format))
+ lcdc_write(sdev, LDBnBSACR(ovl_idx), sstate->dma[1]);

- lcdc_write(sdev, LDBCR,
- LDBCR_UPF(ovl_idx) | LDBCR_UPD(ovl_idx));
+ lcdc_write(sdev, LDBCR, LDBCR_UPF(ovl_idx) | LDBCR_UPD(ovl_idx));
dev_dbg(sdev->ddev.dev, "%s(%u): %s 0x%08x\n", __func__, ovl_idx,
"LDBCR", lcdc_read(sdev, LDBCR));

@@ -119,77 +143,144 @@ static void __shmob_drm_plane_setup(struct shmob_drm_plane *splane,
plane_reg_dump(sdev, ovl_idx, LDBnBSACR);
}

-void shmob_drm_plane_setup(struct drm_plane *plane)
+static int shmob_drm_plane_atomic_check(struct drm_plane *plane,
+ struct drm_atomic_state *state)
{
- struct shmob_drm_plane *splane = to_shmob_plane(plane);
-
- if (plane->fb == NULL)
- return;
+ struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, plane);
+ struct shmob_drm_plane_state *sstate = to_shmob_plane_state(new_plane_state);
+ struct drm_crtc_state *crtc_state;
+ bool is_primary = plane->type == DRM_PLANE_TYPE_PRIMARY;
+ int ret;
+
+ if (!new_plane_state->crtc) {
+ /*
+ * The visible field is not reset by the DRM core but only
+ * updated by drm_atomic_helper_check_plane_state(), set it
+ * manually.
+ */
+ new_plane_state->visible = false;
+ sstate->format = NULL;
+ return 0;
+ }

- __shmob_drm_plane_setup(splane, plane->fb);
-}
+ crtc_state = drm_atomic_get_crtc_state(state, new_plane_state->crtc);
+ if (IS_ERR(crtc_state))
+ return PTR_ERR(crtc_state);

-static int
-shmob_drm_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
- struct drm_framebuffer *fb, int crtc_x, int crtc_y,
- unsigned int crtc_w, unsigned int crtc_h,
- uint32_t src_x, uint32_t src_y,
- uint32_t src_w, uint32_t src_h,
- struct drm_modeset_acquire_ctx *ctx)
-{
- struct shmob_drm_device *sdev = to_shmob_device(plane->dev);
- struct shmob_drm_plane *splane = to_shmob_plane(plane);
- const struct shmob_drm_format_info *format;
+ ret = drm_atomic_helper_check_plane_state(new_plane_state, crtc_state,
+ DRM_PLANE_NO_SCALING,
+ DRM_PLANE_NO_SCALING,
+ !is_primary, true);
+ if (ret < 0)
+ return ret;

- format = shmob_drm_format_info(fb->format->format);
- if (format == NULL) {
- dev_dbg(sdev->dev, "update_plane: unsupported format %p4cc\n",
- &fb->format->format);
- return -EINVAL;
+ if (!new_plane_state->visible) {
+ sstate->format = NULL;
+ return 0;
}

- if (src_w >> 16 != crtc_w || src_h >> 16 != crtc_h) {
- dev_dbg(sdev->dev, "%s: scaling not supported\n", __func__);
+ sstate->format = shmob_drm_format_info(new_plane_state->fb->format->format);
+ if (!sstate->format) {
+ dev_dbg(plane->dev->dev,
+ "plane_atomic_check: unsupported format %p4cc\n",
+ &new_plane_state->fb->format->format);
return -EINVAL;
}

- splane->format = format;
+ shmob_drm_plane_compute_base(sstate);

- splane->src_x = src_x >> 16;
- splane->src_y = src_y >> 16;
- splane->crtc_x = crtc_x;
- splane->crtc_y = crtc_y;
- splane->crtc_w = crtc_w;
- splane->crtc_h = crtc_h;
-
- __shmob_drm_plane_setup(splane, fb);
return 0;
}

-static int shmob_drm_plane_disable(struct drm_plane *plane,
- struct drm_modeset_acquire_ctx *ctx)
+static void shmob_drm_plane_atomic_update(struct drm_plane *plane,
+ struct drm_atomic_state *state)
{
+ struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, plane);
+ struct shmob_drm_plane *splane = to_shmob_plane(plane);
+
+ if (!new_plane_state->visible)
+ return;
+
+ if (plane->type == DRM_PLANE_TYPE_PRIMARY)
+ shmob_drm_primary_plane_setup(splane, new_plane_state);
+ else
+ shmob_drm_overlay_plane_setup(splane, new_plane_state);
+}
+
+static void shmob_drm_plane_atomic_disable(struct drm_plane *plane,
+ struct drm_atomic_state *state)
+{
+ struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state, plane);
struct shmob_drm_device *sdev = to_shmob_device(plane->dev);
struct shmob_drm_plane *splane = to_shmob_plane(plane);
- unsigned int ovl_idx = splane->index - 1;
+ unsigned int ovl_idx;

- splane->format = NULL;
+ if (!old_state->crtc)
+ return;
+
+ if (plane->type != DRM_PLANE_TYPE_OVERLAY)
+ return;

+ ovl_idx = splane->index - 1;
lcdc_write(sdev, LDBCR, LDBCR_UPC(ovl_idx));
lcdc_write(sdev, LDBnBSIFR(ovl_idx), 0);
- lcdc_write(sdev, LDBCR,
- LDBCR_UPF(ovl_idx) | LDBCR_UPD(ovl_idx));
- return 0;
+ lcdc_write(sdev, LDBCR, LDBCR_UPF(ovl_idx) | LDBCR_UPD(ovl_idx));
+}
+
+static struct drm_plane_state *
+shmob_drm_plane_atomic_duplicate_state(struct drm_plane *plane)
+{
+ struct shmob_drm_plane_state *state;
+ struct shmob_drm_plane_state *copy;
+
+ if (WARN_ON(!plane->state))
+ return NULL;
+
+ state = to_shmob_plane_state(plane->state);
+ copy = kmemdup(state, sizeof(*state), GFP_KERNEL);
+ if (copy == NULL)
+ return NULL;
+
+ __drm_atomic_helper_plane_duplicate_state(plane, &copy->base);
+
+ return &copy->base;
+}
+
+static void shmob_drm_plane_atomic_destroy_state(struct drm_plane *plane,
+ struct drm_plane_state *state)
+{
+ __drm_atomic_helper_plane_destroy_state(state);
+ kfree(to_shmob_plane_state(state));
+}
+
+static void shmob_drm_plane_reset(struct drm_plane *plane)
+{
+ struct shmob_drm_plane_state *state;
+
+ if (plane->state) {
+ shmob_drm_plane_atomic_destroy_state(plane, plane->state);
+ plane->state = NULL;
+ }
+
+ state = kzalloc(sizeof(*state), GFP_KERNEL);
+ if (state == NULL)
+ return;
+
+ __drm_atomic_helper_plane_reset(plane, &state->base);
}

-static const struct drm_plane_funcs primary_plane_funcs = {
- .update_plane = drm_plane_helper_update_primary,
- .disable_plane = drm_plane_helper_disable_primary,
+static const struct drm_plane_helper_funcs shmob_drm_plane_helper_funcs = {
+ .atomic_check = shmob_drm_plane_atomic_check,
+ .atomic_update = shmob_drm_plane_atomic_update,
+ .atomic_disable = shmob_drm_plane_atomic_disable,
};

static const struct drm_plane_funcs shmob_drm_plane_funcs = {
- .update_plane = shmob_drm_plane_update,
- .disable_plane = shmob_drm_plane_disable,
+ .update_plane = drm_atomic_helper_update_plane,
+ .disable_plane = drm_atomic_helper_disable_plane,
+ .reset = shmob_drm_plane_reset,
+ .atomic_duplicate_state = shmob_drm_plane_atomic_duplicate_state,
+ .atomic_destroy_state = shmob_drm_plane_atomic_destroy_state,
};

static const uint32_t formats[] = {
@@ -208,28 +299,25 @@ static const uint32_t formats[] = {
struct drm_plane *shmob_drm_plane_create(struct shmob_drm_device *sdev,
unsigned int index)
{
- const struct drm_plane_funcs *funcs;
struct shmob_drm_plane *splane;
enum drm_plane_type type;

- if (!index) {
+ if (!index)
type = DRM_PLANE_TYPE_PRIMARY;
- funcs = &primary_plane_funcs;
- } else {
+ else
type = DRM_PLANE_TYPE_OVERLAY;
- funcs = &shmob_drm_plane_funcs;
- }

splane = drmm_universal_plane_alloc(&sdev->ddev,
struct shmob_drm_plane, base, 1,
- funcs, formats,
+ &shmob_drm_plane_funcs, formats,
ARRAY_SIZE(formats), NULL, type,
NULL);
if (IS_ERR(splane))
return ERR_CAST(splane);

splane->index = index;
- splane->alpha = 255;
+
+ drm_plane_helper_add(&splane->base, &shmob_drm_plane_helper_funcs);

return &splane->base;
}
diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.h b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.h
index 29cf6732d479a509..c6744859c4941d6c 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.h
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.h
@@ -15,6 +15,5 @@ struct shmob_drm_device;

struct drm_plane *shmob_drm_plane_create(struct shmob_drm_device *sdev,
unsigned int index);
-void shmob_drm_plane_setup(struct drm_plane *plane);

#endif /* __SHMOB_DRM_PLANE_H__ */
--
2.34.1


2023-06-22 09:53:43

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH 13/39] drm: renesas: shmobile: Rename input clocks

From: Laurent Pinchart <[email protected]>

Prepare for DT bindings by using more appropriate names for the input
clocks.

Note that all LDDCKR_ICKSEL_* definitions but the one for the bus clock
are valid only for SH7724, so the clock selection code needs to be
updated when extending clock support to other SoCs.

Signed-off-by: Laurent Pinchart <[email protected]>
[geert: Add note]
Signed-off-by: Geert Uytterhoeven <[email protected]>
---
drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
index d272e6273c782178..007ba97cc7733c82 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
@@ -74,15 +74,15 @@ static int shmob_drm_setup_clocks(struct shmob_drm_device *sdev,

switch (clksrc) {
case SHMOB_DRM_CLK_BUS:
- clkname = "bus_clk";
+ clkname = "fck";
sdev->lddckr = LDDCKR_ICKSEL_BUS;
break;
case SHMOB_DRM_CLK_PERIPHERAL:
- clkname = "peripheral_clk";
+ clkname = "media";
sdev->lddckr = LDDCKR_ICKSEL_MIPI;
break;
case SHMOB_DRM_CLK_EXTERNAL:
- clkname = NULL;
+ clkname = "lclk";
sdev->lddckr = LDDCKR_ICKSEL_HDMI;
break;
default:
--
2.34.1


2023-06-22 09:53:44

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH 23/39] drm: renesas: shmobile: Move interface handling to connector setup

Move legacy interface handling to the connector setup code.
Set up bus_flags and bus_formats in display_info according to the
bus format and panel information from platform data, to make it more
similar with DT-based connector/bridge/panel setup.
This will allows us to use the same LCD interface setup code for both
legacy and DT-based systems.

Signed-off-by: Geert Uytterhoeven <[email protected]>
---
.../gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 123 +++++++++++++++---
.../gpu/drm/renesas/shmobile/shmob_drm_drv.c | 49 -------
.../gpu/drm/renesas/shmobile/shmob_drm_drv.h | 3 +-
3 files changed, 109 insertions(+), 66 deletions(-)

diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
index 5328910ebe09c832..28a70536693f7788 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
@@ -8,6 +8,7 @@
*/

#include <linux/clk.h>
+#include <linux/media-bus-format.h>
#include <linux/pm_runtime.h>

#include <drm/drm_crtc.h>
@@ -66,15 +67,65 @@ static void shmob_drm_crtc_setup_geometry(struct shmob_drm_crtc *scrtc)
{
struct drm_crtc *crtc = &scrtc->crtc;
struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);
- enum display_flags dpy_flags = sdev->connector.mode->flags;
+ const struct drm_display_info *info = &sdev->connector->display_info;
const struct drm_display_mode *mode = &crtc->mode;
u32 value;

- value = sdev->ldmt1r
- | ((mode->flags & DRM_MODE_FLAG_PVSYNC) ? 0 : LDMT1R_VPOL)
- | ((mode->flags & DRM_MODE_FLAG_PHSYNC) ? 0 : LDMT1R_HPOL)
- | ((dpy_flags & DISPLAY_FLAGS_PIXDATA_POSEDGE) ? LDMT1R_DWPOL : 0)
- | ((dpy_flags & DISPLAY_FLAGS_DE_LOW) ? LDMT1R_DIPOL : 0);
+ if (!info->num_bus_formats || !info->bus_formats) {
+ dev_warn(sdev->dev, "No bus format reported, using RGB888\n");
+ value = LDMT1R_MIFTYP_RGB24;
+ } else {
+ switch (info->bus_formats[0]) {
+ case MEDIA_BUS_FMT_RGB888_3X8:
+ value = LDMT1R_MIFTYP_RGB8;
+ break;
+
+ case MEDIA_BUS_FMT_RGB666_2X9_BE:
+ value = LDMT1R_MIFTYP_RGB9;
+ break;
+
+ case MEDIA_BUS_FMT_RGB888_2X12_BE:
+ value = LDMT1R_MIFTYP_RGB12A;
+ break;
+
+ case MEDIA_BUS_FMT_RGB444_1X12:
+ value = LDMT1R_MIFTYP_RGB12B;
+ break;
+
+ case MEDIA_BUS_FMT_RGB565_1X16:
+ value = LDMT1R_MIFTYP_RGB16;
+ break;
+
+ case MEDIA_BUS_FMT_RGB666_1X18:
+ value = LDMT1R_MIFTYP_RGB18;
+ break;
+
+ case MEDIA_BUS_FMT_RGB888_1X24:
+ value = LDMT1R_MIFTYP_RGB24;
+ break;
+
+ case MEDIA_BUS_FMT_UYVY8_1X16:
+ value = LDMT1R_MIFTYP_YCBCR;
+ break;
+
+ default:
+ dev_warn(sdev->dev,
+ "unsupported bus format 0x%x, using RGB888\n",
+ info->bus_formats[0]);
+ value = LDMT1R_MIFTYP_RGB24;
+ break;
+ }
+ }
+
+ if (info->bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE)
+ value |= LDMT1R_DWPOL;
+ if (info->bus_flags & DRM_BUS_FLAG_DE_LOW)
+ value |= LDMT1R_DIPOL;
+
+ if (mode->flags & DRM_MODE_FLAG_NVSYNC)
+ value |= LDMT1R_VPOL;
+ if (mode->flags & DRM_MODE_FLAG_NHSYNC)
+ value |= LDMT1R_HPOL;

lcdc_write(sdev, LDMT1R, value);

@@ -512,7 +563,7 @@ static bool shmob_drm_encoder_mode_fixup(struct drm_encoder *encoder,
{
struct drm_device *dev = encoder->dev;
struct shmob_drm_device *sdev = to_shmob_device(dev);
- struct drm_connector *connector = &sdev->connector.connector;
+ struct drm_connector *connector = sdev->connector;
const struct drm_display_mode *panel_mode;

if (list_empty(&connector->modes)) {
@@ -614,6 +665,8 @@ static void shmob_drm_connector_destroy(struct drm_connector *connector)
{
drm_connector_unregister(connector);
drm_connector_cleanup(connector);
+
+ kfree(connector);
}

static const struct drm_connector_funcs connector_funcs = {
@@ -622,26 +675,64 @@ static const struct drm_connector_funcs connector_funcs = {
.destroy = shmob_drm_connector_destroy,
};

-int shmob_drm_connector_create(struct shmob_drm_device *sdev,
- struct drm_encoder *encoder)
+static struct drm_connector *
+shmob_drm_connector_init(struct shmob_drm_device *sdev,
+ struct drm_encoder *encoder)
{
- struct shmob_drm_connector *scon = &sdev->connector;
- struct drm_connector *connector = &scon->connector;
+ struct shmob_drm_connector *scon;
+ struct drm_connector *connector;
+ struct drm_display_info *info;
int ret;

+ scon = kzalloc(sizeof(*scon), GFP_KERNEL);
+ if (!scon)
+ return ERR_PTR(-ENOMEM);
+
+ connector = &scon->connector;
+ info = &connector->display_info;
+ info->width_mm = sdev->pdata->panel.width_mm;
+ info->height_mm = sdev->pdata->panel.height_mm;
+
scon->encoder = encoder;
scon->mode = &sdev->pdata->panel.mode;

- connector->display_info.width_mm = sdev->pdata->panel.width_mm;
- connector->display_info.height_mm = sdev->pdata->panel.height_mm;
+ if (scon->mode->flags & DISPLAY_FLAGS_PIXDATA_POSEDGE)
+ info->bus_flags |= DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE;
+ if (scon->mode->flags & DISPLAY_FLAGS_DE_LOW)
+ info->bus_flags |= DRM_BUS_FLAG_DE_LOW;
+
+ ret = drm_display_info_set_bus_formats(info,
+ &sdev->pdata->iface.bus_fmt, 1);
+ if (ret < 0) {
+ kfree(scon);
+ return ERR_PTR(ret);
+ }

ret = drm_connector_init(&sdev->ddev, connector, &connector_funcs,
DRM_MODE_CONNECTOR_DPI);
- if (ret < 0)
- return ret;
+ if (ret < 0) {
+ kfree(scon);
+ return ERR_PTR(ret);
+ }

drm_connector_helper_add(connector, &connector_helper_funcs);

+ return connector;
+}
+
+int shmob_drm_connector_create(struct shmob_drm_device *sdev,
+ struct drm_encoder *encoder)
+{
+ struct drm_connector *connector;
+ int ret;
+
+ connector = shmob_drm_connector_init(sdev, encoder);
+ if (IS_ERR(connector)) {
+ dev_err(sdev->dev, "failed to created connector: %pe\n",
+ connector);
+ return PTR_ERR(connector);
+ }
+
ret = drm_connector_attach_encoder(connector, encoder);
if (ret < 0)
goto error;
@@ -650,6 +741,8 @@ int shmob_drm_connector_create(struct shmob_drm_device *sdev,
drm_object_property_set_value(&connector->base,
sdev->ddev.mode_config.dpms_property, DRM_MODE_DPMS_OFF);

+ sdev->connector = connector;
+
return 0;

error:
diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
index e5be0ae99bd970be..c15ebbe74cac501f 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
@@ -9,7 +9,6 @@

#include <linux/clk.h>
#include <linux/io.h>
-#include <linux/media-bus-format.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/platform_device.h>
@@ -33,50 +32,6 @@
* Hardware initialization
*/

-static int shmob_drm_init_interface(struct shmob_drm_device *sdev)
-{
- switch (sdev->pdata->iface.bus_fmt) {
- case MEDIA_BUS_FMT_RGB888_3X8:
- sdev->ldmt1r = LDMT1R_MIFTYP_RGB8;
- break;
-
- case MEDIA_BUS_FMT_RGB666_2X9_BE:
- sdev->ldmt1r = LDMT1R_MIFTYP_RGB9;
- break;
-
- case MEDIA_BUS_FMT_RGB888_2X12_BE:
- sdev->ldmt1r = LDMT1R_MIFTYP_RGB12A;
- break;
-
- case MEDIA_BUS_FMT_RGB444_1X12:
- sdev->ldmt1r = LDMT1R_MIFTYP_RGB12B;
- break;
-
- case MEDIA_BUS_FMT_RGB565_1X16:
- sdev->ldmt1r = LDMT1R_MIFTYP_RGB16;
- break;
-
- case MEDIA_BUS_FMT_RGB666_1X18:
- sdev->ldmt1r = LDMT1R_MIFTYP_RGB18;
- break;
-
- case MEDIA_BUS_FMT_RGB888_1X24:
- sdev->ldmt1r = LDMT1R_MIFTYP_RGB24;
- break;
-
- case MEDIA_BUS_FMT_UYVY8_1X16:
- sdev->ldmt1r = LDMT1R_MIFTYP_YCBCR;
- break;
-
- default:
- dev_err(sdev->dev, "invalid bus format 0x%x\n",
- sdev->pdata->iface.bus_fmt);
- return -EINVAL;
- }
-
- return 0;
-}
-
static int shmob_drm_setup_clocks(struct shmob_drm_device *sdev,
enum shmob_drm_clk_source clksrc)
{
@@ -235,10 +190,6 @@ static int shmob_drm_probe(struct platform_device *pdev)
if (ret < 0)
return ret;

- ret = shmob_drm_init_interface(sdev);
- if (ret < 0)
- return ret;
-
ret = shmob_drm_modeset_init(sdev);
if (ret < 0)
return dev_err_probe(&pdev->dev, ret,
diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.h b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.h
index 5e55ba7a207865bd..18907e5ace51c681 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.h
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.h
@@ -27,7 +27,6 @@ struct shmob_drm_device {
void __iomem *mmio;
struct clk *clock;
u32 lddckr;
- u32 ldmt1r;

unsigned int irq;
spinlock_t irq_lock; /* Protects hardware LDINTR register */
@@ -36,7 +35,7 @@ struct shmob_drm_device {

struct shmob_drm_crtc crtc;
struct drm_encoder encoder;
- struct shmob_drm_connector connector;
+ struct drm_connector *connector;
};

static inline struct shmob_drm_device *to_shmob_device(struct drm_device *dev)
--
2.34.1


2023-06-22 09:55:03

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH 29/39] drm: renesas: shmobile: Move shmob_drm_crtc_finish_page_flip()

Move the shmob_drm_crtc_finish_page_flip() function up, to avoid having
to move it during the modification in the next change.

Signed-off-by: Geert Uytterhoeven <[email protected]>
---
.../gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 40 +++++++++++--------
1 file changed, 24 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
index 2c0ca802d36026f4..1d7fcf64bf2aab80 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
@@ -270,6 +270,30 @@ static void shmob_drm_crtc_start(struct shmob_drm_crtc *scrtc)
scrtc->started = true;
}

+/* -----------------------------------------------------------------------------
+ * Page Flip
+ */
+
+void shmob_drm_crtc_finish_page_flip(struct shmob_drm_crtc *scrtc)
+{
+ struct drm_pending_vblank_event *event;
+ struct drm_device *dev = scrtc->base.dev;
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->event_lock, flags);
+ event = scrtc->event;
+ scrtc->event = NULL;
+ if (event) {
+ drm_crtc_send_vblank_event(&scrtc->base, event);
+ drm_crtc_vblank_put(&scrtc->base);
+ }
+ spin_unlock_irqrestore(&dev->event_lock, flags);
+}
+
+/* -----------------------------------------------------------------------------
+ * CRTC Functions
+ */
+
static void shmob_drm_crtc_stop(struct shmob_drm_crtc *scrtc)
{
struct drm_crtc *crtc = &scrtc->base;
@@ -412,22 +436,6 @@ static const struct drm_crtc_helper_funcs crtc_helper_funcs = {
.mode_set_base = shmob_drm_crtc_mode_set_base,
};

-void shmob_drm_crtc_finish_page_flip(struct shmob_drm_crtc *scrtc)
-{
- struct drm_pending_vblank_event *event;
- struct drm_device *dev = scrtc->base.dev;
- unsigned long flags;
-
- spin_lock_irqsave(&dev->event_lock, flags);
- event = scrtc->event;
- scrtc->event = NULL;
- if (event) {
- drm_crtc_send_vblank_event(&scrtc->base, event);
- drm_crtc_vblank_put(&scrtc->base);
- }
- spin_unlock_irqrestore(&dev->event_lock, flags);
-}
-
static int shmob_drm_crtc_page_flip(struct drm_crtc *crtc,
struct drm_framebuffer *fb,
struct drm_pending_vblank_event *event,
--
2.34.1


2023-06-22 09:55:29

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH 31/39] drm: renesas: shmobile: Turn vblank on/off when enabling/disabling CRTC

The DRM core vblank handling mechanism requires drivers to forcefully
turn vblank reporting off when disabling the CRTC, and to restore the
vblank reporting status when enabling the CRTC.
Implement this using the drm_crtc_vblank_{on,off}() helpers.

Note that drm_crtc_vblank_off() must be called at startup to synchronize
the state of the vblank core code with the hardware, which is initially
disabled. This is performed at CRTC creation time, requiring vertical
blank initialization to be moved before creating CRTCs.

Signed-off-by: Geert Uytterhoeven <[email protected]>
---
drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 10 +++++++++-
drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c | 12 ++++++------
2 files changed, 15 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
index d2a0ac5f9368c11c..b184019d8b1ed89c 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
@@ -267,6 +267,9 @@ static void shmob_drm_crtc_start(struct shmob_drm_crtc *scrtc)

shmob_drm_crtc_start_stop(scrtc, true);

+ /* Turn vertical blank interrupt reporting back on. */
+ drm_crtc_vblank_on(crtc);
+
scrtc->started = true;
}

@@ -332,10 +335,12 @@ static void shmob_drm_crtc_stop(struct shmob_drm_crtc *scrtc)
return;

/*
- * Wait for page flip completion before stopping the CRTC as userspace
+ * Disable vertical blank interrupt reporting. We first need to wait
+ * for page flip completion before stopping the CRTC as userspace
* expects page flips to eventually complete.
*/
shmob_drm_crtc_wait_page_flip(scrtc);
+ drm_crtc_vblank_off(crtc);

/* Stop the LCDC. */
shmob_drm_crtc_start_stop(scrtc, false);
@@ -571,6 +576,9 @@ int shmob_drm_crtc_create(struct shmob_drm_device *sdev)

drm_crtc_helper_add(crtc, &crtc_helper_funcs);

+ /* Start with vertical blank interrupt reporting disabled. */
+ drm_crtc_vblank_off(crtc);
+
return 0;
}

diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
index 6eaf2c5a104f451a..a29c0c1093725b6e 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
@@ -189,17 +189,17 @@ static int shmob_drm_probe(struct platform_device *pdev)
if (ret < 0)
return ret;

- ret = shmob_drm_modeset_init(sdev);
- if (ret < 0)
- return dev_err_probe(&pdev->dev, ret,
- "failed to initialize mode setting\n");
-
ret = drm_vblank_init(ddev, 1);
if (ret < 0) {
dev_err(&pdev->dev, "failed to initialize vblank\n");
- goto err_modeset_cleanup;
+ return ret;
}

+ ret = shmob_drm_modeset_init(sdev);
+ if (ret < 0)
+ return dev_err_probe(&pdev->dev, ret,
+ "failed to initialize mode setting\n");
+
ret = platform_get_irq(pdev, 0);
if (ret < 0)
goto err_modeset_cleanup;
--
2.34.1


2023-06-22 09:55:30

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH 03/39] drm: renesas: shmobile: Fix overlay plane disable

Merely writing zero to the CHn Source Image Format Register is not
sufficient to disable a plane, as the programmed register value is not
propagated immediately to the current side. This can be seen when using
the -P option of modetest: the extra plane is displayed correctly, but
does not disappear after exit.

Fix this by doing the full update dance using the Blend Control
Register, like is done when enabling the plane.

Signed-off-by: Geert Uytterhoeven <[email protected]>
---
drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c | 3 +++
1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
index 850986cee848226a..0e34573c3cb3d032 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
@@ -215,7 +215,10 @@ static int shmob_drm_plane_disable(struct drm_plane *plane,

splane->format = NULL;

+ lcdc_write(sdev, LDBCR, LDBCR_UPC(splane->index));
lcdc_write(sdev, LDBnBSIFR(splane->index), 0);
+ lcdc_write(sdev, LDBCR,
+ LDBCR_UPF(splane->index) | LDBCR_UPD(splane->index));
return 0;
}

--
2.34.1


2023-06-22 09:55:30

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH 11/39] drm: renesas: shmobile: Remove backlight support

From: Laurent Pinchart <[email protected]>

Backlight support should be implemented by panels, not by the LCDC
driver. As the feature is currently unused anyway, remove it.

Signed-off-by: Laurent Pinchart <[email protected]>
[geert: Cleanups]
Signed-off-by: Geert Uytterhoeven <[email protected]>
---
Changes compared to Laurent's original:
- Rebase,
- Remove unused variable ‘scon’,
- Remove now unused to_shmob_encoder() macro,
- Remove now empty shmob_drm_encoder wrapper.
---
drivers/gpu/drm/renesas/shmobile/Makefile | 3 +-
.../renesas/shmobile/shmob_drm_backlight.c | 82 -------------------
.../renesas/shmobile/shmob_drm_backlight.h | 19 -----
.../gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 33 +-------
.../gpu/drm/renesas/shmobile/shmob_drm_crtc.h | 8 --
.../gpu/drm/renesas/shmobile/shmob_drm_drv.h | 2 +-
.../gpu/drm/renesas/shmobile/shmob_drm_kms.c | 2 +-
include/linux/platform_data/shmob_drm.h | 8 --
8 files changed, 7 insertions(+), 150 deletions(-)
delete mode 100644 drivers/gpu/drm/renesas/shmobile/shmob_drm_backlight.c
delete mode 100644 drivers/gpu/drm/renesas/shmobile/shmob_drm_backlight.h

diff --git a/drivers/gpu/drm/renesas/shmobile/Makefile b/drivers/gpu/drm/renesas/shmobile/Makefile
index 861edafed8562c87..2679555d61a70207 100644
--- a/drivers/gpu/drm/renesas/shmobile/Makefile
+++ b/drivers/gpu/drm/renesas/shmobile/Makefile
@@ -1,6 +1,5 @@
# SPDX-License-Identifier: GPL-2.0
-shmob-drm-y := shmob_drm_backlight.o \
- shmob_drm_crtc.o \
+shmob-drm-y := shmob_drm_crtc.o \
shmob_drm_drv.o \
shmob_drm_kms.o \
shmob_drm_plane.o
diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_backlight.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_backlight.c
deleted file mode 100644
index 794573badfe86076..0000000000000000
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_backlight.c
+++ /dev/null
@@ -1,82 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * shmob_drm_backlight.c -- SH Mobile DRM Backlight
- *
- * Copyright (C) 2012 Renesas Electronics Corporation
- *
- * Laurent Pinchart ([email protected])
- */
-
-#include <linux/backlight.h>
-
-#include "shmob_drm_backlight.h"
-#include "shmob_drm_crtc.h"
-#include "shmob_drm_drv.h"
-
-static int shmob_drm_backlight_update(struct backlight_device *bdev)
-{
- struct shmob_drm_connector *scon = bl_get_data(bdev);
- struct shmob_drm_device *sdev = scon->connector.dev->dev_private;
- const struct shmob_drm_backlight_data *bdata = &sdev->pdata->backlight;
- int brightness = backlight_get_brightness(bdev);
-
- return bdata->set_brightness(brightness);
-}
-
-static int shmob_drm_backlight_get_brightness(struct backlight_device *bdev)
-{
- struct shmob_drm_connector *scon = bl_get_data(bdev);
- struct shmob_drm_device *sdev = scon->connector.dev->dev_private;
- const struct shmob_drm_backlight_data *bdata = &sdev->pdata->backlight;
-
- return bdata->get_brightness();
-}
-
-static const struct backlight_ops shmob_drm_backlight_ops = {
- .options = BL_CORE_SUSPENDRESUME,
- .update_status = shmob_drm_backlight_update,
- .get_brightness = shmob_drm_backlight_get_brightness,
-};
-
-void shmob_drm_backlight_dpms(struct shmob_drm_connector *scon, int mode)
-{
- if (scon->backlight == NULL)
- return;
-
- scon->backlight->props.power = mode == DRM_MODE_DPMS_ON
- ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN;
- backlight_update_status(scon->backlight);
-}
-
-int shmob_drm_backlight_init(struct shmob_drm_connector *scon)
-{
- struct shmob_drm_device *sdev = scon->connector.dev->dev_private;
- const struct shmob_drm_backlight_data *bdata = &sdev->pdata->backlight;
- struct drm_connector *connector = &scon->connector;
- struct drm_device *dev = connector->dev;
- struct backlight_device *backlight;
-
- if (!bdata->max_brightness)
- return 0;
-
- backlight = backlight_device_register(bdata->name, dev->dev, scon,
- &shmob_drm_backlight_ops, NULL);
- if (IS_ERR(backlight)) {
- dev_err(dev->dev, "unable to register backlight device: %ld\n",
- PTR_ERR(backlight));
- return PTR_ERR(backlight);
- }
-
- backlight->props.max_brightness = bdata->max_brightness;
- backlight->props.brightness = bdata->max_brightness;
- backlight->props.power = FB_BLANK_POWERDOWN;
- backlight_update_status(backlight);
-
- scon->backlight = backlight;
- return 0;
-}
-
-void shmob_drm_backlight_exit(struct shmob_drm_connector *scon)
-{
- backlight_device_unregister(scon->backlight);
-}
diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_backlight.h b/drivers/gpu/drm/renesas/shmobile/shmob_drm_backlight.h
deleted file mode 100644
index d9abb7a60be5c414..0000000000000000
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_backlight.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * shmob_drm_backlight.h -- SH Mobile DRM Backlight
- *
- * Copyright (C) 2012 Renesas Electronics Corporation
- *
- * Laurent Pinchart ([email protected])
- */
-
-#ifndef __SHMOB_DRM_BACKLIGHT_H__
-#define __SHMOB_DRM_BACKLIGHT_H__
-
-struct shmob_drm_connector;
-
-void shmob_drm_backlight_dpms(struct shmob_drm_connector *scon, int mode);
-int shmob_drm_backlight_init(struct shmob_drm_connector *scon);
-void shmob_drm_backlight_exit(struct shmob_drm_connector *scon);
-
-#endif /* __SHMOB_DRM_BACKLIGHT_H__ */
diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
index 9bfdfa7c6e2b1001..c775c1d49f0e1ce9 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
@@ -7,7 +7,6 @@
* Laurent Pinchart ([email protected])
*/

-#include <linux/backlight.h>
#include <linux/clk.h>
#include <linux/pm_runtime.h>

@@ -24,7 +23,6 @@
#include <drm/drm_simple_kms_helper.h>
#include <drm/drm_vblank.h>

-#include "shmob_drm_backlight.h"
#include "shmob_drm_crtc.h"
#include "shmob_drm_drv.h"
#include "shmob_drm_kms.h"
@@ -520,21 +518,9 @@ int shmob_drm_crtc_create(struct shmob_drm_device *sdev)
* Encoder
*/

-#define to_shmob_encoder(e) \
- container_of(e, struct shmob_drm_encoder, encoder)
-
static void shmob_drm_encoder_dpms(struct drm_encoder *encoder, int mode)
{
- struct shmob_drm_encoder *senc = to_shmob_encoder(encoder);
- struct shmob_drm_device *sdev = encoder->dev->dev_private;
- struct shmob_drm_connector *scon = &sdev->connector;
-
- if (senc->dpms == mode)
- return;
-
- shmob_drm_backlight_dpms(scon, mode);
-
- senc->dpms = mode;
+ /* No-op, everything is handled in the CRTC code. */
}

static bool shmob_drm_encoder_mode_fixup(struct drm_encoder *encoder,
@@ -586,11 +572,9 @@ static const struct drm_encoder_helper_funcs encoder_helper_funcs = {

int shmob_drm_encoder_create(struct shmob_drm_device *sdev)
{
- struct drm_encoder *encoder = &sdev->encoder.encoder;
+ struct drm_encoder *encoder = &sdev->encoder;
int ret;

- sdev->encoder.dpms = DRM_MODE_DPMS_OFF;
-
encoder->possible_crtcs = 1;

ret = drm_simple_encoder_init(sdev->ddev, encoder,
@@ -655,9 +639,6 @@ static const struct drm_connector_helper_funcs connector_helper_funcs = {

static void shmob_drm_connector_destroy(struct drm_connector *connector)
{
- struct shmob_drm_connector *scon = to_shmob_connector(connector);
-
- shmob_drm_backlight_exit(scon);
drm_connector_unregister(connector);
drm_connector_cleanup(connector);
}
@@ -686,13 +667,9 @@ int shmob_drm_connector_create(struct shmob_drm_device *sdev,

drm_connector_helper_add(connector, &connector_helper_funcs);

- ret = shmob_drm_backlight_init(&sdev->connector);
- if (ret < 0)
- goto err_cleanup;
-
ret = drm_connector_attach_encoder(connector, encoder);
if (ret < 0)
- goto err_backlight;
+ goto error;

drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
drm_object_property_set_value(&connector->base,
@@ -700,9 +677,7 @@ int shmob_drm_connector_create(struct shmob_drm_device *sdev,

return 0;

-err_backlight:
- shmob_drm_backlight_exit(&sdev->connector);
-err_cleanup:
+error:
drm_connector_cleanup(connector);
return ret;
}
diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
index 21718843f46d3d19..bce6926269453b77 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
@@ -14,7 +14,6 @@
#include <drm/drm_connector.h>
#include <drm/drm_encoder.h>

-struct backlight_device;
struct drm_pending_vblank_event;
struct shmob_drm_device;
struct shmob_drm_format_info;
@@ -31,16 +30,9 @@ struct shmob_drm_crtc {
bool started;
};

-struct shmob_drm_encoder {
- struct drm_encoder encoder;
- int dpms;
-};
-
struct shmob_drm_connector {
struct drm_connector connector;
struct drm_encoder *encoder;
-
- struct backlight_device *backlight;
};

int shmob_drm_crtc_create(struct shmob_drm_device *sdev);
diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.h b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.h
index 4964ddd5ab7472b0..16d830168b2ada21 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.h
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.h
@@ -35,7 +35,7 @@ struct shmob_drm_device {
struct drm_device *ddev;

struct shmob_drm_crtc crtc;
- struct shmob_drm_encoder encoder;
+ struct drm_encoder encoder;
struct shmob_drm_connector connector;
};

diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c
index 8fd360149743f8e2..3051318ddc7999bc 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c
@@ -159,7 +159,7 @@ int shmob_drm_modeset_init(struct shmob_drm_device *sdev)

shmob_drm_crtc_create(sdev);
shmob_drm_encoder_create(sdev);
- shmob_drm_connector_create(sdev, &sdev->encoder.encoder);
+ shmob_drm_connector_create(sdev, &sdev->encoder);

drm_kms_helper_poll_init(sdev->ddev);

diff --git a/include/linux/platform_data/shmob_drm.h b/include/linux/platform_data/shmob_drm.h
index d661399b217dfc4b..b6b5b6607fb5e52c 100644
--- a/include/linux/platform_data/shmob_drm.h
+++ b/include/linux/platform_data/shmob_drm.h
@@ -40,13 +40,6 @@ enum shmob_drm_interface {
SHMOB_DRM_IFACE_SYS24, /* 24bpp */
};

-struct shmob_drm_backlight_data {
- const char *name;
- int max_brightness;
- int (*get_brightness)(void);
- int (*set_brightness)(int brightness);
-};
-
struct shmob_drm_panel_data {
unsigned int width_mm; /* Panel width in mm */
unsigned int height_mm; /* Panel height in mm */
@@ -83,7 +76,6 @@ struct shmob_drm_platform_data {
enum shmob_drm_clk_source clk_source;
struct shmob_drm_interface_data iface;
struct shmob_drm_panel_data panel;
- struct shmob_drm_backlight_data backlight;
};

#endif /* __SHMOB_DRM_H__ */
--
2.34.1


2023-06-22 09:55:34

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH 26/39] drm: renesas: shmobile: Rename shmob_drm_connector.connector

Rename the "connector" member of the shmob_drm_connector subclass
structure to "base", to improve readability.

Signed-off-by: Geert Uytterhoeven <[email protected]>
---
drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 4 ++--
drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
index 3f0b71253ed929c9..2c0ca802d36026f4 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
@@ -608,7 +608,7 @@ int shmob_drm_encoder_create(struct shmob_drm_device *sdev)

static inline struct shmob_drm_connector *to_shmob_connector(struct drm_connector *connector)
{
- return container_of(connector, struct shmob_drm_connector, connector);
+ return container_of(connector, struct shmob_drm_connector, base);
}

static int shmob_drm_connector_get_modes(struct drm_connector *connector)
@@ -669,7 +669,7 @@ shmob_drm_connector_init(struct shmob_drm_device *sdev,
if (!scon)
return ERR_PTR(-ENOMEM);

- connector = &scon->connector;
+ connector = &scon->base;
info = &connector->display_info;
info->width_mm = sdev->pdata->panel.width_mm;
info->height_mm = sdev->pdata->panel.height_mm;
diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
index 79cce0a0ada4cfce..2c6d7541427581a6 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
@@ -33,7 +33,7 @@ struct shmob_drm_crtc {
};

struct shmob_drm_connector {
- struct drm_connector connector;
+ struct drm_connector base;
struct drm_encoder *encoder;
const struct videomode *mode;
};
--
2.34.1


2023-06-22 09:55:41

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH 10/39] drm: renesas: shmobile: Improve shmob_drm_format_info table

Improve the table containing hardware information related to the
supported plane formats:
1. Move (part of) the overlay format register settings from multiple
switch() statements spread across the code into the table, like is
already done for the primary plane register settings,
2. Remove the .yuv field, as that information can easily be extracted
from the register settings using a new helper macro,
3. Shrink and move the .bpp field to reduce table size.

Signed-off-by: Geert Uytterhoeven <[email protected]>
---
.../gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 29 ++--------
.../gpu/drm/renesas/shmobile/shmob_drm_kms.c | 42 ++++++++++----
.../gpu/drm/renesas/shmobile/shmob_drm_kms.h | 9 ++-
.../drm/renesas/shmobile/shmob_drm_plane.c | 56 ++-----------------
4 files changed, 47 insertions(+), 89 deletions(-)

diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
index cd492806105e5b5d..9bfdfa7c6e2b1001 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
@@ -221,31 +221,12 @@ static void shmob_drm_crtc_start(struct shmob_drm_crtc *scrtc)
lcdc_write(sdev, LDDFR, format->lddfr | LDDFR_CF1);
lcdc_write(sdev, LDMLSR, scrtc->line_size);
lcdc_write(sdev, LDSA1R, scrtc->dma[0]);
- if (format->yuv)
+ if (shmob_drm_format_is_yuv(format))
lcdc_write(sdev, LDSA2R, scrtc->dma[1]);
lcdc_write(sdev, LDSM1R, 0);

/* Word and long word swap. */
- switch (format->fourcc) {
- case DRM_FORMAT_RGB565:
- case DRM_FORMAT_NV21:
- case DRM_FORMAT_NV61:
- case DRM_FORMAT_NV42:
- value = LDDDSR_LS | LDDDSR_WS;
- break;
- case DRM_FORMAT_RGB888:
- case DRM_FORMAT_NV12:
- case DRM_FORMAT_NV16:
- case DRM_FORMAT_NV24:
- value = LDDDSR_LS | LDDDSR_WS | LDDDSR_BS;
- break;
- case DRM_FORMAT_ARGB8888:
- case DRM_FORMAT_XRGB8888:
- default:
- value = LDDDSR_LS;
- break;
- }
- lcdc_write(sdev, LDDDSR, value);
+ lcdc_write(sdev, LDDDSR, format->ldddsr);

/* Setup planes. */
drm_for_each_legacy_plane(plane, dev) {
@@ -304,12 +285,12 @@ static void shmob_drm_crtc_compute_base(struct shmob_drm_crtc *scrtc,
struct drm_gem_dma_object *gem;
unsigned int bpp;

- bpp = scrtc->format->yuv ? 8 : scrtc->format->bpp;
+ bpp = shmob_drm_format_is_yuv(scrtc->format) ? 8 : scrtc->format->bpp;
gem = drm_fb_dma_get_gem_obj(fb, 0);
scrtc->dma[0] = gem->dma_addr + fb->offsets[0]
+ y * fb->pitches[0] + x * bpp / 8;

- if (scrtc->format->yuv) {
+ if (shmob_drm_format_is_yuv(scrtc->format)) {
bpp = scrtc->format->bpp - 8;
gem = drm_fb_dma_get_gem_obj(fb, 1);
scrtc->dma[1] = gem->dma_addr + fb->offsets[1]
@@ -326,7 +307,7 @@ static void shmob_drm_crtc_update_base(struct shmob_drm_crtc *scrtc)
shmob_drm_crtc_compute_base(scrtc, crtc->x, crtc->y);

lcdc_write_mirror(sdev, LDSA1R, scrtc->dma[0]);
- if (scrtc->format->yuv)
+ if (shmob_drm_format_is_yuv(scrtc->format))
lcdc_write_mirror(sdev, LDSA2R, scrtc->dma[1]);

lcdc_write(sdev, LDRCNTR, lcdc_read(sdev, LDRCNTR) ^ LDRCNTR_MRS);
diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c
index 99381cc0abf3ae1f..8fd360149743f8e2 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c
@@ -27,53 +27,73 @@ static const struct shmob_drm_format_info shmob_drm_format_infos[] = {
{
.fourcc = DRM_FORMAT_RGB565,
.bpp = 16,
- .yuv = false,
.lddfr = LDDFR_PKF_RGB16,
+ .ldddsr = LDDDSR_LS | LDDDSR_WS,
+ .ldbbsifr = LDBBSIFR_AL_1 | LDBBSIFR_SWPL | LDBBSIFR_SWPW |
+ LDBBSIFR_RY | LDBBSIFR_RPKF_RGB16,
}, {
.fourcc = DRM_FORMAT_RGB888,
.bpp = 24,
- .yuv = false,
.lddfr = LDDFR_PKF_RGB24,
+ .ldddsr = LDDDSR_LS | LDDDSR_WS | LDDDSR_BS,
+ .ldbbsifr = LDBBSIFR_AL_1 | LDBBSIFR_SWPL | LDBBSIFR_SWPW |
+ LDBBSIFR_SWPB | LDBBSIFR_RY | LDBBSIFR_RPKF_RGB24,
}, {
.fourcc = DRM_FORMAT_ARGB8888,
.bpp = 32,
- .yuv = false,
.lddfr = LDDFR_PKF_ARGB32,
+ .ldddsr = LDDDSR_LS,
+ .ldbbsifr = LDBBSIFR_AL_PK | LDBBSIFR_SWPL | LDBBSIFR_RY |
+ LDBBSIFR_RPKF_ARGB32,
}, {
.fourcc = DRM_FORMAT_XRGB8888,
.bpp = 32,
- .yuv = false,
.lddfr = LDDFR_PKF_ARGB32,
+ .ldddsr = LDDDSR_LS,
+ .ldbbsifr = LDBBSIFR_AL_1 | LDBBSIFR_SWPL | LDBBSIFR_RY |
+ LDBBSIFR_RPKF_ARGB32,
}, {
.fourcc = DRM_FORMAT_NV12,
.bpp = 12,
- .yuv = true,
.lddfr = LDDFR_CC | LDDFR_YF_420,
+ .ldddsr = LDDDSR_LS | LDDDSR_WS | LDDDSR_BS,
+ .ldbbsifr = LDBBSIFR_AL_1 | LDBBSIFR_SWPL | LDBBSIFR_SWPW |
+ LDBBSIFR_SWPB | LDBBSIFR_CHRR_420,
}, {
.fourcc = DRM_FORMAT_NV21,
.bpp = 12,
- .yuv = true,
.lddfr = LDDFR_CC | LDDFR_YF_420,
+ .ldddsr = LDDDSR_LS | LDDDSR_WS,
+ .ldbbsifr = LDBBSIFR_AL_1 | LDBBSIFR_SWPL | LDBBSIFR_SWPW |
+ LDBBSIFR_CHRR_420,
}, {
.fourcc = DRM_FORMAT_NV16,
.bpp = 16,
- .yuv = true,
.lddfr = LDDFR_CC | LDDFR_YF_422,
+ .ldddsr = LDDDSR_LS | LDDDSR_WS | LDDDSR_BS,
+ .ldbbsifr = LDBBSIFR_AL_1 | LDBBSIFR_SWPL | LDBBSIFR_SWPW |
+ LDBBSIFR_SWPB | LDBBSIFR_CHRR_422,
}, {
.fourcc = DRM_FORMAT_NV61,
.bpp = 16,
- .yuv = true,
.lddfr = LDDFR_CC | LDDFR_YF_422,
+ .ldddsr = LDDDSR_LS | LDDDSR_WS,
+ .ldbbsifr = LDBBSIFR_AL_1 | LDBBSIFR_SWPL | LDBBSIFR_SWPW |
+ LDBBSIFR_CHRR_422,
}, {
.fourcc = DRM_FORMAT_NV24,
.bpp = 24,
- .yuv = true,
.lddfr = LDDFR_CC | LDDFR_YF_444,
+ .ldddsr = LDDDSR_LS | LDDDSR_WS | LDDDSR_BS,
+ .ldbbsifr = LDBBSIFR_AL_1 | LDBBSIFR_SWPL | LDBBSIFR_SWPW |
+ LDBBSIFR_SWPB | LDBBSIFR_CHRR_444,
}, {
.fourcc = DRM_FORMAT_NV42,
.bpp = 24,
- .yuv = true,
.lddfr = LDDFR_CC | LDDFR_YF_444,
+ .ldddsr = LDDDSR_LS | LDDDSR_WS,
+ .ldbbsifr = LDBBSIFR_AL_1 | LDBBSIFR_SWPL | LDBBSIFR_SWPW |
+ LDBBSIFR_CHRR_444,
},
};

@@ -112,7 +132,7 @@ shmob_drm_fb_create(struct drm_device *dev, struct drm_file *file_priv,
return ERR_PTR(-EINVAL);
}

- if (format->yuv) {
+ if (shmob_drm_format_is_yuv(format)) {
unsigned int chroma_cpp = format->bpp == 24 ? 2 : 1;

if (mode_cmd->pitches[1] != mode_cmd->pitches[0] * chroma_cpp) {
diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.h b/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.h
index 0347b1fd2338a84d..590162c3db20209d 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.h
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.h
@@ -17,11 +17,14 @@ struct shmob_drm_device;

struct shmob_drm_format_info {
u32 fourcc;
- unsigned int bpp;
- bool yuv;
- u32 lddfr;
+ u32 lddfr; /* LCD Data Format Register */
+ u16 ldbbsifr; /* CHn Source Image Format Register low bits */
+ u8 ldddsr; /* LCDC Input Image Data Swap Register low bits */
+ u8 bpp;
};

+#define shmob_drm_format_is_yuv(format) ((format)->lddfr & LDDFR_CC)
+
const struct shmob_drm_format_info *shmob_drm_format_info(u32 fourcc);

int shmob_drm_modeset_init(struct shmob_drm_device *sdev);
diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
index 36fedb2b74c8b7a2..0b2ab153e9ae76df 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
@@ -43,12 +43,12 @@ static void shmob_drm_plane_compute_base(struct shmob_drm_plane *splane,
struct drm_gem_dma_object *gem;
unsigned int bpp;

- bpp = splane->format->yuv ? 8 : splane->format->bpp;
+ bpp = shmob_drm_format_is_yuv(splane->format) ? 8 : splane->format->bpp;
gem = drm_fb_dma_get_gem_obj(fb, 0);
splane->dma[0] = gem->dma_addr + fb->offsets[0]
+ y * fb->pitches[0] + x * bpp / 8;

- if (splane->format->yuv) {
+ if (shmob_drm_format_is_yuv(splane->format)) {
bpp = splane->format->bpp - 8;
gem = drm_fb_dma_get_gem_obj(fb, 1);
splane->dma[1] = gem->dma_addr + fb->offsets[1]
@@ -64,54 +64,8 @@ static void __shmob_drm_plane_setup(struct shmob_drm_plane *splane,
u32 format;

/* TODO: Support ROP3 mode */
- format = LDBBSIFR_EN | (splane->alpha << LDBBSIFR_LAY_SHIFT);
-
- switch (splane->format->fourcc) {
- case DRM_FORMAT_RGB565:
- case DRM_FORMAT_NV21:
- case DRM_FORMAT_NV61:
- case DRM_FORMAT_NV42:
- format |= LDBBSIFR_SWPL | LDBBSIFR_SWPW;
- break;
- case DRM_FORMAT_RGB888:
- case DRM_FORMAT_NV12:
- case DRM_FORMAT_NV16:
- case DRM_FORMAT_NV24:
- format |= LDBBSIFR_SWPL | LDBBSIFR_SWPW | LDBBSIFR_SWPB;
- break;
- case DRM_FORMAT_ARGB8888:
- case DRM_FORMAT_XRGB8888:
- default:
- format |= LDBBSIFR_SWPL;
- break;
- }
-
- switch (splane->format->fourcc) {
- case DRM_FORMAT_RGB565:
- format |= LDBBSIFR_AL_1 | LDBBSIFR_RY | LDBBSIFR_RPKF_RGB16;
- break;
- case DRM_FORMAT_RGB888:
- format |= LDBBSIFR_AL_1 | LDBBSIFR_RY | LDBBSIFR_RPKF_RGB24;
- break;
- case DRM_FORMAT_ARGB8888:
- format |= LDBBSIFR_AL_PK | LDBBSIFR_RY | LDBBSIFR_RPKF_ARGB32;
- break;
- case DRM_FORMAT_XRGB8888:
- format |= LDBBSIFR_AL_1 | LDBBSIFR_RY | LDBBSIFR_RPKF_ARGB32;
- break;
- case DRM_FORMAT_NV12:
- case DRM_FORMAT_NV21:
- format |= LDBBSIFR_AL_1 | LDBBSIFR_CHRR_420;
- break;
- case DRM_FORMAT_NV16:
- case DRM_FORMAT_NV61:
- format |= LDBBSIFR_AL_1 | LDBBSIFR_CHRR_422;
- break;
- case DRM_FORMAT_NV24:
- case DRM_FORMAT_NV42:
- format |= LDBBSIFR_AL_1 | LDBBSIFR_CHRR_444;
- break;
- }
+ format = LDBBSIFR_EN | (splane->alpha << LDBBSIFR_LAY_SHIFT) |
+ splane->format->ldbbsifr;

#define plane_reg_dump(sdev, splane, reg) \
dev_dbg(sdev->ddev->dev, "%s(%u): %s 0x%08x 0x%08x\n", __func__, \
@@ -144,7 +98,7 @@ static void __shmob_drm_plane_setup(struct shmob_drm_plane *splane,
shmob_drm_plane_compute_base(splane, fb, splane->src_x, splane->src_y);

lcdc_write(sdev, LDBnBSAYR(splane->index), splane->dma[0]);
- if (splane->format->yuv)
+ if (shmob_drm_format_is_yuv(splane->format))
lcdc_write(sdev, LDBnBSACR(splane->index), splane->dma[1]);

lcdc_write(sdev, LDBCR,
--
2.34.1


2023-06-22 09:55:45

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH 28/39] drm: renesas: shmobile: Use drm_crtc_handle_vblank()

Replace the call to the legacy drm_handle_vblank() function with a call
to the new drm_crtc_handle_vblank() helper.

Signed-off-by: Geert Uytterhoeven <[email protected]>
---
drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
index c98e2bdd888c3274..6eaf2c5a104f451a 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
@@ -86,7 +86,7 @@ static irqreturn_t shmob_drm_irq(int irq, void *arg)
spin_unlock_irqrestore(&sdev->irq_lock, flags);

if (status & LDINTR_VES) {
- drm_handle_vblank(dev, 0);
+ drm_crtc_handle_vblank(&sdev->crtc.base);
shmob_drm_crtc_finish_page_flip(&sdev->crtc);
}

--
2.34.1


2023-06-22 09:55:45

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH 38/39] drm: renesas: shmobile: Atomic conversion part 3

Complete the conversion to atomic mode setting by converting the
connector, and setting the DRIVER_ATOMIC flag.

Signed-off-by: Geert Uytterhoeven <[email protected]>
---
drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 5 +----
drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c | 2 +-
2 files changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
index f2332bb0fbbd51a1..17456dde57637ab8 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
@@ -574,7 +574,6 @@ static void shmob_drm_connector_destroy(struct drm_connector *connector)
}

static const struct drm_connector_funcs connector_funcs = {
- .dpms = drm_helper_connector_dpms,
.reset = drm_atomic_helper_connector_reset,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = shmob_drm_connector_destroy,
@@ -644,9 +643,7 @@ int shmob_drm_connector_create(struct shmob_drm_device *sdev,
if (ret < 0)
goto error;

- drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
- drm_object_property_set_value(&connector->base,
- sdev->ddev.mode_config.dpms_property, DRM_MODE_DPMS_OFF);
+ connector->dpms = DRM_MODE_DPMS_OFF;

sdev->connector = connector;

diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
index c43f408d6b1fcc5b..576869164479ec6b 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
@@ -98,7 +98,7 @@ static irqreturn_t shmob_drm_irq(int irq, void *arg)
DEFINE_DRM_GEM_DMA_FOPS(shmob_drm_fops);

static const struct drm_driver shmob_drm_driver = {
- .driver_features = DRIVER_GEM | DRIVER_MODESET,
+ .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
DRM_GEM_DMA_DRIVER_OPS,
.fops = &shmob_drm_fops,
.name = "shmob-drm",
--
2.34.1


2023-06-22 09:56:32

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH 21/39] drm: renesas: shmobile: Use struct videomode in platform data

From: Laurent Pinchart <[email protected]>

Replace the drm_mode_modeinfo field with videomode that includes more
signal polarity flags. This simplifies driver handling of panel modes
and prepares for DT support.

Signed-off-by: Laurent Pinchart <[email protected]>
[geert: Simplify]
Signed-off-by: Geert Uytterhoeven <[email protected]>
---
Changes compared to Laurent's original:
- Rebase,
- Fix build,
- Remove unneeded {width,height}_mm intermediaries from
shmob_drm_connector,
- Replace embedded videomode by a const pointer to pdata.
---
.../gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 35 ++++++++-----------
.../gpu/drm/renesas/shmobile/shmob_drm_crtc.h | 3 ++
include/linux/platform_data/shmob_drm.h | 11 ++----
3 files changed, 19 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
index 291b3a5014c24f08..5328910ebe09c832 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
@@ -23,6 +23,8 @@
#include <drm/drm_simple_kms_helper.h>
#include <drm/drm_vblank.h>

+#include <video/videomode.h>
+
#include "shmob_drm_crtc.h"
#include "shmob_drm_drv.h"
#include "shmob_drm_kms.h"
@@ -64,18 +66,16 @@ static void shmob_drm_crtc_setup_geometry(struct shmob_drm_crtc *scrtc)
{
struct drm_crtc *crtc = &scrtc->crtc;
struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);
- const struct shmob_drm_interface_data *idata = &sdev->pdata->iface;
+ enum display_flags dpy_flags = sdev->connector.mode->flags;
const struct drm_display_mode *mode = &crtc->mode;
u32 value;

value = sdev->ldmt1r
| ((mode->flags & DRM_MODE_FLAG_PVSYNC) ? 0 : LDMT1R_VPOL)
| ((mode->flags & DRM_MODE_FLAG_PHSYNC) ? 0 : LDMT1R_HPOL)
- | ((idata->flags & SHMOB_DRM_IFACE_FL_DWPOL) ? LDMT1R_DWPOL : 0)
- | ((idata->flags & SHMOB_DRM_IFACE_FL_DIPOL) ? LDMT1R_DIPOL : 0)
- | ((idata->flags & SHMOB_DRM_IFACE_FL_DAPOL) ? LDMT1R_DAPOL : 0)
- | ((idata->flags & SHMOB_DRM_IFACE_FL_HSCNT) ? LDMT1R_HSCNT : 0)
- | ((idata->flags & SHMOB_DRM_IFACE_FL_DWCNT) ? LDMT1R_DWCNT : 0);
+ | ((dpy_flags & DISPLAY_FLAGS_PIXDATA_POSEDGE) ? LDMT1R_DWPOL : 0)
+ | ((dpy_flags & DISPLAY_FLAGS_DE_LOW) ? LDMT1R_DIPOL : 0);
+
lcdc_write(sdev, LDMT1R, value);

value = ((mode->hdisplay / 8) << 16) /* HDCN */
@@ -581,7 +581,7 @@ static inline struct shmob_drm_connector *to_shmob_connector(struct drm_connecto

static int shmob_drm_connector_get_modes(struct drm_connector *connector)
{
- struct shmob_drm_device *sdev = to_shmob_device(connector->dev);
+ struct shmob_drm_connector *scon = to_shmob_connector(connector);
struct drm_display_mode *mode;

mode = drm_mode_create(connector->dev);
@@ -589,18 +589,9 @@ static int shmob_drm_connector_get_modes(struct drm_connector *connector)
return 0;

mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER;
- mode->clock = sdev->pdata->panel.mode.clock;
- mode->hdisplay = sdev->pdata->panel.mode.hdisplay;
- mode->hsync_start = sdev->pdata->panel.mode.hsync_start;
- mode->hsync_end = sdev->pdata->panel.mode.hsync_end;
- mode->htotal = sdev->pdata->panel.mode.htotal;
- mode->vdisplay = sdev->pdata->panel.mode.vdisplay;
- mode->vsync_start = sdev->pdata->panel.mode.vsync_start;
- mode->vsync_end = sdev->pdata->panel.mode.vsync_end;
- mode->vtotal = sdev->pdata->panel.mode.vtotal;
- mode->flags = sdev->pdata->panel.mode.flags;
-
- drm_mode_set_name(mode);
+
+ drm_display_mode_from_videomode(scon->mode, mode);
+
drm_mode_probed_add(connector, mode);

return 1;
@@ -634,10 +625,12 @@ static const struct drm_connector_funcs connector_funcs = {
int shmob_drm_connector_create(struct shmob_drm_device *sdev,
struct drm_encoder *encoder)
{
- struct drm_connector *connector = &sdev->connector.connector;
+ struct shmob_drm_connector *scon = &sdev->connector;
+ struct drm_connector *connector = &scon->connector;
int ret;

- sdev->connector.encoder = encoder;
+ scon->encoder = encoder;
+ scon->mode = &sdev->pdata->panel.mode;

connector->display_info.width_mm = sdev->pdata->panel.width_mm;
connector->display_info.height_mm = sdev->pdata->panel.height_mm;
diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
index bce6926269453b77..f507eaf912e16a22 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
@@ -14,6 +14,8 @@
#include <drm/drm_connector.h>
#include <drm/drm_encoder.h>

+#include <video/videomode.h>
+
struct drm_pending_vblank_event;
struct shmob_drm_device;
struct shmob_drm_format_info;
@@ -33,6 +35,7 @@ struct shmob_drm_crtc {
struct shmob_drm_connector {
struct drm_connector connector;
struct drm_encoder *encoder;
+ const struct videomode *mode;
};

int shmob_drm_crtc_create(struct shmob_drm_device *sdev);
diff --git a/include/linux/platform_data/shmob_drm.h b/include/linux/platform_data/shmob_drm.h
index b728e24222d99158..f3cb19ff9f818aca 100644
--- a/include/linux/platform_data/shmob_drm.h
+++ b/include/linux/platform_data/shmob_drm.h
@@ -10,7 +10,7 @@
#ifndef __SHMOB_DRM_H__
#define __SHMOB_DRM_H__

-#include <drm/drm_mode.h>
+#include <video/videomode.h>

enum shmob_drm_clk_source {
SHMOB_DRM_CLK_BUS,
@@ -32,19 +32,12 @@ enum shmob_drm_interface {
struct shmob_drm_panel_data {
unsigned int width_mm; /* Panel width in mm */
unsigned int height_mm; /* Panel height in mm */
- struct drm_mode_modeinfo mode;
+ struct videomode mode;
};

-#define SHMOB_DRM_IFACE_FL_DWPOL (1 << 0) /* Rising edge dot clock data latch */
-#define SHMOB_DRM_IFACE_FL_DIPOL (1 << 1) /* Active low display enable */
-#define SHMOB_DRM_IFACE_FL_DAPOL (1 << 2) /* Active low display data */
-#define SHMOB_DRM_IFACE_FL_HSCNT (1 << 3) /* Disable HSYNC during VBLANK */
-#define SHMOB_DRM_IFACE_FL_DWCNT (1 << 4) /* Disable dotclock during blanking */
-
struct shmob_drm_interface_data {
enum shmob_drm_interface interface;
unsigned int clk_div;
- unsigned int flags;
};

struct shmob_drm_platform_data {
--
2.34.1


2023-06-22 09:56:34

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH 20/39] drm: renesas: shmobile: Replace .dev_private with container_of()

Now that drm_device is embedded in shmob_drm_device, we can use
a container_of()-based helper to get the shmob_drm_device pointer from
the drm_device, instead of using the deprecated drm_device.dev_private
field.

While at it, restore reverse Xmas tree ordering of local variable
declarations.

Signed-off-by: Geert Uytterhoeven <[email protected]>
---
.../gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 20 +++++++++----------
.../gpu/drm/renesas/shmobile/shmob_drm_drv.c | 4 +---
.../gpu/drm/renesas/shmobile/shmob_drm_drv.h | 5 +++++
.../drm/renesas/shmobile/shmob_drm_plane.c | 6 +++---
4 files changed, 19 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
index 40948b56017ff2df..291b3a5014c24f08 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
@@ -63,7 +63,7 @@ static void shmob_drm_clk_off(struct shmob_drm_device *sdev)
static void shmob_drm_crtc_setup_geometry(struct shmob_drm_crtc *scrtc)
{
struct drm_crtc *crtc = &scrtc->crtc;
- struct shmob_drm_device *sdev = crtc->dev->dev_private;
+ struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);
const struct shmob_drm_interface_data *idata = &sdev->pdata->iface;
const struct drm_display_mode *mode = &crtc->mode;
u32 value;
@@ -102,7 +102,7 @@ static void shmob_drm_crtc_setup_geometry(struct shmob_drm_crtc *scrtc)

static void shmob_drm_crtc_start_stop(struct shmob_drm_crtc *scrtc, bool start)
{
- struct shmob_drm_device *sdev = scrtc->crtc.dev->dev_private;
+ struct shmob_drm_device *sdev = to_shmob_device(scrtc->crtc.dev);
u32 value;

value = lcdc_read(sdev, LDCNT2R);
@@ -136,7 +136,7 @@ static void shmob_drm_crtc_start_stop(struct shmob_drm_crtc *scrtc, bool start)
static void shmob_drm_crtc_start(struct shmob_drm_crtc *scrtc)
{
struct drm_crtc *crtc = &scrtc->crtc;
- struct shmob_drm_device *sdev = crtc->dev->dev_private;
+ struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);
const struct shmob_drm_interface_data *idata = &sdev->pdata->iface;
const struct shmob_drm_format_info *format;
struct drm_device *dev = &sdev->ddev;
@@ -223,7 +223,7 @@ static void shmob_drm_crtc_start(struct shmob_drm_crtc *scrtc)
static void shmob_drm_crtc_stop(struct shmob_drm_crtc *scrtc)
{
struct drm_crtc *crtc = &scrtc->crtc;
- struct shmob_drm_device *sdev = crtc->dev->dev_private;
+ struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);

if (!scrtc->started)
return;
@@ -280,7 +280,7 @@ static void shmob_drm_crtc_compute_base(struct shmob_drm_crtc *scrtc,
static void shmob_drm_crtc_update_base(struct shmob_drm_crtc *scrtc)
{
struct drm_crtc *crtc = &scrtc->crtc;
- struct shmob_drm_device *sdev = crtc->dev->dev_private;
+ struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);

shmob_drm_crtc_compute_base(scrtc, crtc->x, crtc->y);

@@ -322,8 +322,8 @@ static int shmob_drm_crtc_mode_set(struct drm_crtc *crtc,
int x, int y,
struct drm_framebuffer *old_fb)
{
+ struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);
struct shmob_drm_crtc *scrtc = to_shmob_crtc(crtc);
- struct shmob_drm_device *sdev = crtc->dev->dev_private;
const struct shmob_drm_format_info *format;

format = shmob_drm_format_info(crtc->primary->fb->format->format);
@@ -428,7 +428,7 @@ static void shmob_drm_crtc_enable_vblank(struct shmob_drm_device *sdev,

static int shmob_drm_enable_vblank(struct drm_crtc *crtc)
{
- struct shmob_drm_device *sdev = crtc->dev->dev_private;
+ struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);

shmob_drm_crtc_enable_vblank(sdev, true);

@@ -437,7 +437,7 @@ static int shmob_drm_enable_vblank(struct drm_crtc *crtc)

static void shmob_drm_disable_vblank(struct drm_crtc *crtc)
{
- struct shmob_drm_device *sdev = crtc->dev->dev_private;
+ struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);

shmob_drm_crtc_enable_vblank(sdev, false);
}
@@ -511,7 +511,7 @@ static bool shmob_drm_encoder_mode_fixup(struct drm_encoder *encoder,
struct drm_display_mode *adjusted_mode)
{
struct drm_device *dev = encoder->dev;
- struct shmob_drm_device *sdev = dev->dev_private;
+ struct shmob_drm_device *sdev = to_shmob_device(dev);
struct drm_connector *connector = &sdev->connector.connector;
const struct drm_display_mode *panel_mode;

@@ -581,7 +581,7 @@ static inline struct shmob_drm_connector *to_shmob_connector(struct drm_connecto

static int shmob_drm_connector_get_modes(struct drm_connector *connector)
{
- struct shmob_drm_device *sdev = connector->dev->dev_private;
+ struct shmob_drm_device *sdev = to_shmob_device(connector->dev);
struct drm_display_mode *mode;

mode = drm_mode_create(connector->dev);
diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
index 2b77af3a8c97ef8c..1a1d66c6e817e227 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
@@ -95,7 +95,7 @@ static int shmob_drm_setup_clocks(struct shmob_drm_device *sdev,
static irqreturn_t shmob_drm_irq(int irq, void *arg)
{
struct drm_device *dev = arg;
- struct shmob_drm_device *sdev = dev->dev_private;
+ struct shmob_drm_device *sdev = to_shmob_device(dev);
unsigned long flags;
u32 status;

@@ -217,8 +217,6 @@ static int shmob_drm_probe(struct platform_device *pdev)
if (ret < 0)
return ret;

- ddev->dev_private = sdev;
-
ret = shmob_drm_modeset_init(sdev);
if (ret < 0)
return dev_err_probe(&pdev->dev, ret,
diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.h b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.h
index 77bb0da48f37ace8..5e55ba7a207865bd 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.h
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.h
@@ -39,4 +39,9 @@ struct shmob_drm_device {
struct shmob_drm_connector connector;
};

+static inline struct shmob_drm_device *to_shmob_device(struct drm_device *dev)
+{
+ return container_of(dev, struct shmob_drm_device, ddev);
+}
+
#endif /* __SHMOB_DRM_DRV_H__ */
diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
index 258288c80756bf16..c58b9dca34736342 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
@@ -63,7 +63,7 @@ static void shmob_drm_plane_compute_base(struct shmob_drm_plane *splane,
static void __shmob_drm_plane_setup(struct shmob_drm_plane *splane,
struct drm_framebuffer *fb)
{
- struct shmob_drm_device *sdev = splane->plane.dev->dev_private;
+ struct shmob_drm_device *sdev = to_shmob_device(splane->plane.dev);
u32 format;

/* TODO: Support ROP3 mode */
@@ -135,8 +135,8 @@ shmob_drm_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
uint32_t src_w, uint32_t src_h,
struct drm_modeset_acquire_ctx *ctx)
{
+ struct shmob_drm_device *sdev = to_shmob_device(plane->dev);
struct shmob_drm_plane *splane = to_shmob_plane(plane);
- struct shmob_drm_device *sdev = plane->dev->dev_private;
const struct shmob_drm_format_info *format;

format = shmob_drm_format_info(fb->format->format);
@@ -167,8 +167,8 @@ shmob_drm_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
static int shmob_drm_plane_disable(struct drm_plane *plane,
struct drm_modeset_acquire_ctx *ctx)
{
+ struct shmob_drm_device *sdev = to_shmob_device(plane->dev);
struct shmob_drm_plane *splane = to_shmob_plane(plane);
- struct shmob_drm_device *sdev = plane->dev->dev_private;

splane->format = NULL;

--
2.34.1


2023-06-22 09:56:58

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH 27/39] drm: renesas: shmobile: Rename shmob_drm_plane.plane

Rename the "plane" member of the shmob_drm_plane subclass structure to
"base", to improve readability.

Signed-off-by: Geert Uytterhoeven <[email protected]>
---
drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
index 63886015baaebfc0..e300e5c0de70a9b1 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
@@ -20,7 +20,7 @@
#include "shmob_drm_regs.h"

struct shmob_drm_plane {
- struct drm_plane plane;
+ struct drm_plane base;
unsigned int index;
unsigned int alpha;

@@ -37,7 +37,7 @@ struct shmob_drm_plane {

static inline struct shmob_drm_plane *to_shmob_plane(struct drm_plane *plane)
{
- return container_of(plane, struct shmob_drm_plane, plane);
+ return container_of(plane, struct shmob_drm_plane, base);
}

static void shmob_drm_plane_compute_base(struct shmob_drm_plane *splane,
@@ -64,7 +64,7 @@ static void shmob_drm_plane_compute_base(struct shmob_drm_plane *splane,
static void __shmob_drm_plane_setup(struct shmob_drm_plane *splane,
struct drm_framebuffer *fb)
{
- struct shmob_drm_device *sdev = to_shmob_device(splane->plane.dev);
+ struct shmob_drm_device *sdev = to_shmob_device(splane->base.dev);
unsigned int ovl_idx = splane->index - 1;
u32 format;

@@ -221,7 +221,7 @@ struct drm_plane *shmob_drm_plane_create(struct shmob_drm_device *sdev,
}

splane = drmm_universal_plane_alloc(&sdev->ddev,
- struct shmob_drm_plane, plane, 1,
+ struct shmob_drm_plane, base, 1,
funcs, formats,
ARRAY_SIZE(formats), NULL, type,
NULL);
@@ -231,5 +231,5 @@ struct drm_plane *shmob_drm_plane_create(struct shmob_drm_device *sdev,
splane->index = index;
splane->alpha = 255;

- return &splane->plane;
+ return &splane->base;
}
--
2.34.1


2023-06-22 09:57:11

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH 19/39] drm: renesas: shmobile: Convert container helpers to static inline functions

Replace to conversion helper macros using container_of() by static
inline functions, to improve type-safety.

Signed-off-by: Geert Uytterhoeven <[email protected]>
---
drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 11 ++++++++---
drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c | 5 ++++-
2 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
index 26611440f7a12715..40948b56017ff2df 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
@@ -291,7 +291,10 @@ static void shmob_drm_crtc_update_base(struct shmob_drm_crtc *scrtc)
lcdc_write(sdev, LDRCNTR, lcdc_read(sdev, LDRCNTR) ^ LDRCNTR_MRS);
}

-#define to_shmob_crtc(c) container_of(c, struct shmob_drm_crtc, crtc)
+static inline struct shmob_drm_crtc *to_shmob_crtc(struct drm_crtc *crtc)
+{
+ return container_of(crtc, struct shmob_drm_crtc, crtc);
+}

static void shmob_drm_crtc_dpms(struct drm_crtc *crtc, int mode)
{
@@ -571,8 +574,10 @@ int shmob_drm_encoder_create(struct shmob_drm_device *sdev)
* Connector
*/

-#define to_shmob_connector(c) \
- container_of(c, struct shmob_drm_connector, connector)
+static inline struct shmob_drm_connector *to_shmob_connector(struct drm_connector *connector)
+{
+ return container_of(connector, struct shmob_drm_connector, connector);
+}

static int shmob_drm_connector_get_modes(struct drm_connector *connector)
{
diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
index 17e66a018689f648..258288c80756bf16 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
@@ -34,7 +34,10 @@ struct shmob_drm_plane {
unsigned int crtc_h;
};

-#define to_shmob_plane(p) container_of(p, struct shmob_drm_plane, plane)
+static inline struct shmob_drm_plane *to_shmob_plane(struct drm_plane *plane)
+{
+ return container_of(plane, struct shmob_drm_plane, plane);
+}

static void shmob_drm_plane_compute_base(struct shmob_drm_plane *splane,
struct drm_framebuffer *fb,
--
2.34.1


2023-06-22 09:57:11

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH 05/39] drm: renesas: shmobile: Correct encoder/connector types

The first encoder output on the SH-Mobile LCD Controller is a DPI
parallel bus. However, at the time of introduction of the driver, no
encoder or connector types were defined yet for the DPI parallel bus,
hence the driver used the ones for LVDS instead.

Adjust the types accordingly.

Signed-off-by: Geert Uytterhoeven <[email protected]>
---
drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
index 11dd2bc803e7cb62..fbfd906844da490c 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
@@ -598,7 +598,7 @@ int shmob_drm_encoder_create(struct shmob_drm_device *sdev)
encoder->possible_crtcs = 1;

ret = drm_simple_encoder_init(sdev->ddev, encoder,
- DRM_MODE_ENCODER_LVDS);
+ DRM_MODE_ENCODER_DPI);
if (ret < 0)
return ret;

@@ -684,7 +684,7 @@ int shmob_drm_connector_create(struct shmob_drm_device *sdev,
connector->display_info.height_mm = sdev->pdata->panel.height_mm;

ret = drm_connector_init(sdev->ddev, connector, &connector_funcs,
- DRM_MODE_CONNECTOR_LVDS);
+ DRM_MODE_CONNECTOR_DPI);
if (ret < 0)
return ret;

--
2.34.1


2023-06-22 09:57:34

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH 24/39] drm: renesas: shmobile: Unify plane allocation

Unify primary and overlay plane allocation:
- Enhance shmob_drm_plane_create() so it can be used to create the
primary plane, too,
- Move overlay plane creation next to primary plane creation.

As overlay plane index zero now means the primary plane, this requires
shifting all overlay plane indices by one.

Signed-off-by: Geert Uytterhoeven <[email protected]>
---
Perhaps it would be better to not use dynamic allocation, but store
"struct drm_plane primary" and "struct shmob_drm_plane planes[5]" in
struct drm_shmob_device instead, like is done for the crtc and encoder?
---
.../gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 39 ++------
.../gpu/drm/renesas/shmobile/shmob_drm_drv.c | 9 --
.../drm/renesas/shmobile/shmob_drm_plane.c | 96 +++++++++++--------
.../drm/renesas/shmobile/shmob_drm_plane.h | 3 +-
4 files changed, 70 insertions(+), 77 deletions(-)

diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
index 28a70536693f7788..3f6af12f45988124 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
@@ -19,7 +19,6 @@
#include <drm/drm_gem_dma_helper.h>
#include <drm/drm_modeset_helper.h>
#include <drm/drm_modeset_helper_vtables.h>
-#include <drm/drm_plane_helper.h>
#include <drm/drm_probe_helper.h>
#include <drm/drm_simple_kms_helper.h>
#include <drm/drm_vblank.h>
@@ -501,47 +500,29 @@ static const struct drm_crtc_funcs crtc_funcs = {
.disable_vblank = shmob_drm_disable_vblank,
};

-static const uint32_t modeset_formats[] = {
- DRM_FORMAT_RGB565,
- DRM_FORMAT_RGB888,
- DRM_FORMAT_ARGB8888,
- DRM_FORMAT_XRGB8888,
- DRM_FORMAT_NV12,
- DRM_FORMAT_NV21,
- DRM_FORMAT_NV16,
- DRM_FORMAT_NV61,
- DRM_FORMAT_NV24,
- DRM_FORMAT_NV42,
-};
-
-static const struct drm_plane_funcs primary_plane_funcs = {
- DRM_PLANE_NON_ATOMIC_FUNCS,
-};
-
int shmob_drm_crtc_create(struct shmob_drm_device *sdev)
{
struct drm_crtc *crtc = &sdev->crtc.crtc;
- struct drm_plane *primary;
+ struct drm_plane *primary, *plane;
+ unsigned int i;
int ret;

sdev->crtc.dpms = DRM_MODE_DPMS_OFF;

- primary = __drm_universal_plane_alloc(&sdev->ddev, sizeof(*primary), 0,
- 0, &primary_plane_funcs,
- modeset_formats,
- ARRAY_SIZE(modeset_formats),
- NULL, DRM_PLANE_TYPE_PRIMARY,
- NULL);
+ primary = shmob_drm_plane_create(sdev, 0);
if (IS_ERR(primary))
return PTR_ERR(primary);

+ for (i = 1; i < 5; ++i) {
+ plane = shmob_drm_plane_create(sdev, i);
+ if (IS_ERR(plane))
+ return PTR_ERR(plane);
+ }
+
ret = drm_crtc_init_with_planes(&sdev->ddev, crtc, primary, NULL,
&crtc_funcs, NULL);
- if (ret < 0) {
- drm_plane_cleanup(primary);
- kfree(primary);
+ if (ret < 0)
return ret;
- }

drm_crtc_helper_add(crtc, &crtc_helper_funcs);

diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
index c15ebbe74cac501f..c98e2bdd888c3274 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
@@ -154,7 +154,6 @@ static int shmob_drm_probe(struct platform_device *pdev)
struct shmob_drm_platform_data *pdata = pdev->dev.platform_data;
struct shmob_drm_device *sdev;
struct drm_device *ddev;
- unsigned int i;
int ret;

if (pdata == NULL) {
@@ -195,14 +194,6 @@ static int shmob_drm_probe(struct platform_device *pdev)
return dev_err_probe(&pdev->dev, ret,
"failed to initialize mode setting\n");

- for (i = 0; i < 4; ++i) {
- ret = shmob_drm_plane_create(sdev, i);
- if (ret < 0) {
- dev_err(&pdev->dev, "failed to create plane %u\n", i);
- goto err_modeset_cleanup;
- }
- }
-
ret = drm_vblank_init(ddev, 1);
if (ret < 0) {
dev_err(&pdev->dev, "failed to initialize vblank\n");
diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
index c58b9dca34736342..63886015baaebfc0 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
@@ -12,6 +12,7 @@
#include <drm/drm_fourcc.h>
#include <drm/drm_framebuffer.h>
#include <drm/drm_gem_dma_helper.h>
+#include <drm/drm_plane_helper.h>

#include "shmob_drm_drv.h"
#include "shmob_drm_kms.h"
@@ -64,57 +65,58 @@ static void __shmob_drm_plane_setup(struct shmob_drm_plane *splane,
struct drm_framebuffer *fb)
{
struct shmob_drm_device *sdev = to_shmob_device(splane->plane.dev);
+ unsigned int ovl_idx = splane->index - 1;
u32 format;

/* TODO: Support ROP3 mode */
format = LDBBSIFR_EN | (splane->alpha << LDBBSIFR_LAY_SHIFT) |
splane->format->ldbbsifr;

-#define plane_reg_dump(sdev, splane, reg) \
+#define plane_reg_dump(sdev, ovl_idx, reg) \
dev_dbg(sdev->ddev.dev, "%s(%u): %s 0x%08x 0x%08x\n", __func__, \
- splane->index, #reg, \
- lcdc_read(sdev, reg(splane->index)), \
- lcdc_read(sdev, reg(splane->index) + LCDC_SIDE_B_OFFSET))
-
- plane_reg_dump(sdev, splane, LDBnBSIFR);
- plane_reg_dump(sdev, splane, LDBnBSSZR);
- plane_reg_dump(sdev, splane, LDBnBLOCR);
- plane_reg_dump(sdev, splane, LDBnBSMWR);
- plane_reg_dump(sdev, splane, LDBnBSAYR);
- plane_reg_dump(sdev, splane, LDBnBSACR);
-
- lcdc_write(sdev, LDBCR, LDBCR_UPC(splane->index));
- dev_dbg(sdev->ddev.dev, "%s(%u): %s 0x%08x\n", __func__, splane->index,
+ ovl_idx, #reg, \
+ lcdc_read(sdev, reg(ovl_idx)), \
+ lcdc_read(sdev, reg(ovl_idx) + LCDC_SIDE_B_OFFSET))
+
+ plane_reg_dump(sdev, ovl_idx, LDBnBSIFR);
+ plane_reg_dump(sdev, ovl_idx, LDBnBSSZR);
+ plane_reg_dump(sdev, ovl_idx, LDBnBLOCR);
+ plane_reg_dump(sdev, ovl_idx, LDBnBSMWR);
+ plane_reg_dump(sdev, ovl_idx, LDBnBSAYR);
+ plane_reg_dump(sdev, ovl_idx, LDBnBSACR);
+
+ lcdc_write(sdev, LDBCR, LDBCR_UPC(ovl_idx));
+ dev_dbg(sdev->ddev.dev, "%s(%u): %s 0x%08x\n", __func__, ovl_idx,
"LDBCR", lcdc_read(sdev, LDBCR));

- lcdc_write(sdev, LDBnBSIFR(splane->index), format);
+ lcdc_write(sdev, LDBnBSIFR(ovl_idx), format);

- lcdc_write(sdev, LDBnBSSZR(splane->index),
+ lcdc_write(sdev, LDBnBSSZR(ovl_idx),
(splane->crtc_h << LDBBSSZR_BVSS_SHIFT) |
(splane->crtc_w << LDBBSSZR_BHSS_SHIFT));
- lcdc_write(sdev, LDBnBLOCR(splane->index),
+ lcdc_write(sdev, LDBnBLOCR(ovl_idx),
(splane->crtc_y << LDBBLOCR_CVLC_SHIFT) |
(splane->crtc_x << LDBBLOCR_CHLC_SHIFT));
- lcdc_write(sdev, LDBnBSMWR(splane->index),
+ lcdc_write(sdev, LDBnBSMWR(ovl_idx),
fb->pitches[0] << LDBBSMWR_BSMW_SHIFT);

shmob_drm_plane_compute_base(splane, fb, splane->src_x, splane->src_y);

- lcdc_write(sdev, LDBnBSAYR(splane->index), splane->dma[0]);
+ lcdc_write(sdev, LDBnBSAYR(ovl_idx), splane->dma[0]);
if (shmob_drm_format_is_yuv(splane->format))
- lcdc_write(sdev, LDBnBSACR(splane->index), splane->dma[1]);
+ lcdc_write(sdev, LDBnBSACR(ovl_idx), splane->dma[1]);

lcdc_write(sdev, LDBCR,
- LDBCR_UPF(splane->index) | LDBCR_UPD(splane->index));
- dev_dbg(sdev->ddev.dev, "%s(%u): %s 0x%08x\n", __func__, splane->index,
+ LDBCR_UPF(ovl_idx) | LDBCR_UPD(ovl_idx));
+ dev_dbg(sdev->ddev.dev, "%s(%u): %s 0x%08x\n", __func__, ovl_idx,
"LDBCR", lcdc_read(sdev, LDBCR));

- plane_reg_dump(sdev, splane, LDBnBSIFR);
- plane_reg_dump(sdev, splane, LDBnBSSZR);
- plane_reg_dump(sdev, splane, LDBnBLOCR);
- plane_reg_dump(sdev, splane, LDBnBSMWR);
- plane_reg_dump(sdev, splane, LDBnBSAYR);
- plane_reg_dump(sdev, splane, LDBnBSACR);
+ plane_reg_dump(sdev, ovl_idx, LDBnBSIFR);
+ plane_reg_dump(sdev, ovl_idx, LDBnBSSZR);
+ plane_reg_dump(sdev, ovl_idx, LDBnBLOCR);
+ plane_reg_dump(sdev, ovl_idx, LDBnBSMWR);
+ plane_reg_dump(sdev, ovl_idx, LDBnBSAYR);
+ plane_reg_dump(sdev, ovl_idx, LDBnBSACR);
}

void shmob_drm_plane_setup(struct drm_plane *plane)
@@ -169,16 +171,22 @@ static int shmob_drm_plane_disable(struct drm_plane *plane,
{
struct shmob_drm_device *sdev = to_shmob_device(plane->dev);
struct shmob_drm_plane *splane = to_shmob_plane(plane);
+ unsigned int ovl_idx = splane->index - 1;

splane->format = NULL;

- lcdc_write(sdev, LDBCR, LDBCR_UPC(splane->index));
- lcdc_write(sdev, LDBnBSIFR(splane->index), 0);
+ lcdc_write(sdev, LDBCR, LDBCR_UPC(ovl_idx));
+ lcdc_write(sdev, LDBnBSIFR(ovl_idx), 0);
lcdc_write(sdev, LDBCR,
- LDBCR_UPF(splane->index) | LDBCR_UPD(splane->index));
+ LDBCR_UPF(ovl_idx) | LDBCR_UPD(ovl_idx));
return 0;
}

+static const struct drm_plane_funcs primary_plane_funcs = {
+ .update_plane = drm_plane_helper_update_primary,
+ .disable_plane = drm_plane_helper_disable_primary,
+};
+
static const struct drm_plane_funcs shmob_drm_plane_funcs = {
.update_plane = shmob_drm_plane_update,
.disable_plane = shmob_drm_plane_disable,
@@ -197,19 +205,31 @@ static const uint32_t formats[] = {
DRM_FORMAT_NV42,
};

-int shmob_drm_plane_create(struct shmob_drm_device *sdev, unsigned int index)
+struct drm_plane *shmob_drm_plane_create(struct shmob_drm_device *sdev,
+ unsigned int index)
{
+ const struct drm_plane_funcs *funcs;
struct shmob_drm_plane *splane;
+ enum drm_plane_type type;
+
+ if (!index) {
+ type = DRM_PLANE_TYPE_PRIMARY;
+ funcs = &primary_plane_funcs;
+ } else {
+ type = DRM_PLANE_TYPE_OVERLAY;
+ funcs = &shmob_drm_plane_funcs;
+ }

- splane = drmm_universal_plane_alloc(&sdev->ddev, struct shmob_drm_plane,
- plane, 1, &shmob_drm_plane_funcs,
- formats, ARRAY_SIZE(formats), NULL,
- DRM_PLANE_TYPE_OVERLAY, NULL);
+ splane = drmm_universal_plane_alloc(&sdev->ddev,
+ struct shmob_drm_plane, plane, 1,
+ funcs, formats,
+ ARRAY_SIZE(formats), NULL, type,
+ NULL);
if (IS_ERR(splane))
- return PTR_ERR(splane);
+ return ERR_CAST(splane);

splane->index = index;
splane->alpha = 255;

- return 0;
+ return &splane->plane;
}
diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.h b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.h
index e72b21a4288fc23f..29cf6732d479a509 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.h
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.h
@@ -13,7 +13,8 @@
struct drm_plane;
struct shmob_drm_device;

-int shmob_drm_plane_create(struct shmob_drm_device *sdev, unsigned int index);
+struct drm_plane *shmob_drm_plane_create(struct shmob_drm_device *sdev,
+ unsigned int index);
void shmob_drm_plane_setup(struct drm_plane *plane);

#endif /* __SHMOB_DRM_PLANE_H__ */
--
2.34.1


2023-06-22 10:19:52

by Sergei Shtylyov

[permalink] [raw]
Subject: Re: [PATCH 04/39] drm: renesas: shmobile: Fix ARGB32 overlay format typo

Hello!

On 6/22/23 12:21 PM, Geert Uytterhoeven wrote:

> When configurating

Configuring? My spellchecker trips. :-)

> a CHn Source Image Format Register (LDBBSIFR), one
> should use the corresponding LDBBSIFR_RPKF_* definition for overlay
> planes, not the DDFR_PKF_* definition for the primary plane.
>
> Fortunately both definitions resolve to the same value, so this bug did
> not cause any harm.
>
> Signed-off-by: Geert Uytterhoeven <[email protected]>
[...]

MBR, Sergey

2023-06-23 15:08:55

by Laurent Pinchart

[permalink] [raw]
Subject: Re: [PATCH 04/39] drm: renesas: shmobile: Fix ARGB32 overlay format typo

Hi Geert,

Thank you for the patch.

On Thu, Jun 22, 2023 at 11:21:16AM +0200, Geert Uytterhoeven wrote:
> When configurating a CHn Source Image Format Register (LDBBSIFR), one
> should use the corresponding LDBBSIFR_RPKF_* definition for overlay
> planes, not the DDFR_PKF_* definition for the primary plane.
>
> Fortunately both definitions resolve to the same value, so this bug did
> not cause any harm.
>
> Signed-off-by: Geert Uytterhoeven <[email protected]>

With the typo in the commit message fixed,

Reviewed-by: Laurent Pinchart <[email protected]>

> ---
> drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
> index 0e34573c3cb3d032..7e49e2873da1bb6f 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
> @@ -94,10 +94,10 @@ static void __shmob_drm_plane_setup(struct shmob_drm_plane *splane,
> format |= LDBBSIFR_AL_1 | LDBBSIFR_RY | LDBBSIFR_RPKF_RGB24;
> break;
> case DRM_FORMAT_ARGB8888:
> - format |= LDBBSIFR_AL_PK | LDBBSIFR_RY | LDDFR_PKF_ARGB32;
> + format |= LDBBSIFR_AL_PK | LDBBSIFR_RY | LDBBSIFR_RPKF_ARGB32;
> break;
> case DRM_FORMAT_XRGB8888:
> - format |= LDBBSIFR_AL_1 | LDBBSIFR_RY | LDDFR_PKF_ARGB32;
> + format |= LDBBSIFR_AL_1 | LDBBSIFR_RY | LDBBSIFR_RPKF_ARGB32;
> break;
> case DRM_FORMAT_NV12:
> case DRM_FORMAT_NV21:

--
Regards,

Laurent Pinchart

2023-06-23 15:21:12

by Laurent Pinchart

[permalink] [raw]
Subject: Re: [PATCH 06/39] drm: renesas: shmobile: Add support for Runtime PM

Hi Geert,

Thank you for the patch.

On Thu, Jun 22, 2023 at 11:21:18AM +0200, Geert Uytterhoeven wrote:
> The SH-Mobile LCD Controller is part of a PM Domain on all relevant SoCs
> (clock domain on all, power domain on some). Hence it may not be
> sufficient to manage the LCDC module clock explicitly (e.g. if the
> selected clock source differs from SHMOB_DRM_CLK_BUS).
>
> Fix this by using Runtime PM instead.
>
> Signed-off-by: Geert Uytterhoeven <[email protected]>
> ---
> drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 11 ++++++++++-
> drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c | 5 +++++
> 2 files changed, 15 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> index fbfd906844da490c..84dbf35025d7be63 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> @@ -9,6 +9,7 @@
>
> #include <linux/backlight.h>
> #include <linux/clk.h>
> +#include <linux/pm_runtime.h>
>
> #include <drm/drm_crtc.h>
> #include <drm/drm_crtc_helper.h>
> @@ -170,10 +171,16 @@ static void shmob_drm_crtc_start(struct shmob_drm_crtc *scrtc)
> if (WARN_ON(format == NULL))
> return;
>
> + ret = pm_runtime_resume_and_get(sdev->dev);
> + if (ret)
> + return;
> +
> /* Enable clocks before accessing the hardware. */
> ret = shmob_drm_clk_on(sdev);

This would be best located in the runtime PM resume handler. Same for
disabling clocks in the runtime PM suspend handler.

> - if (ret < 0)
> + if (ret < 0) {
> + pm_runtime_put(sdev->dev);
> return;
> + }
>
> /* Reset and enable the LCDC. */
> lcdc_write(sdev, LDCNT2R, lcdc_read(sdev, LDCNT2R) | LDCNT2R_BR);
> @@ -271,6 +278,8 @@ static void shmob_drm_crtc_stop(struct shmob_drm_crtc *scrtc)
> /* Stop clocks. */
> shmob_drm_clk_off(sdev);
>
> + pm_runtime_put(sdev->dev);
> +
> scrtc->started = false;
> }
>
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> index 30493ce874192e3e..4f01caa119637032 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> @@ -13,6 +13,7 @@
> #include <linux/module.h>
> #include <linux/platform_device.h>
> #include <linux/pm.h>
> +#include <linux/pm_runtime.h>
> #include <linux/slab.h>
>
> #include <drm/drm_drv.h>
> @@ -216,6 +217,10 @@ static int shmob_drm_probe(struct platform_device *pdev)
> if (IS_ERR(sdev->mmio))
> return PTR_ERR(sdev->mmio);
>
> + ret = devm_pm_runtime_enable(&pdev->dev);
> + if (ret)
> + return ret;
> +

I would move this after shmob_drm_setup_clocks(), to ensure that the
runtime PM suspend and resume handlers will have access to clocks.

> ret = shmob_drm_setup_clocks(sdev, pdata->clk_source);
> if (ret < 0)
> return ret;

--
Regards,

Laurent Pinchart

2023-06-23 15:24:57

by Laurent Pinchart

[permalink] [raw]
Subject: Re: [PATCH 07/39] drm: renesas: shmobile: Restore indentation of shmob_drm_setup_clocks()

Hi Geert,

Thank you for the patch.

On Thu, Jun 22, 2023 at 11:21:19AM +0200, Geert Uytterhoeven wrote:
> Commit 56550d94cbaeaa19 ("Drivers: gpu: remove __dev* attributes.")
> forgot to realign the continuation of the parameter section of
> shmob_drm_setup_clocks().
>
> Signed-off-by: Geert Uytterhoeven <[email protected]>

Reviewed-by: Laurent Pinchart <[email protected]>

> ---
> drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> index 4f01caa119637032..d272e6273c782178 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> @@ -67,7 +67,7 @@ static int shmob_drm_init_interface(struct shmob_drm_device *sdev)
> }
>
> static int shmob_drm_setup_clocks(struct shmob_drm_device *sdev,
> - enum shmob_drm_clk_source clksrc)
> + enum shmob_drm_clk_source clksrc)
> {
> struct clk *clk;
> char *clkname;

--
Regards,

Laurent Pinchart

2023-06-23 15:25:34

by Laurent Pinchart

[permalink] [raw]
Subject: Re: [PATCH 03/39] drm: renesas: shmobile: Fix overlay plane disable

Hi Geert,

Thank you for the patch.

On Thu, Jun 22, 2023 at 11:21:15AM +0200, Geert Uytterhoeven wrote:
> Merely writing zero to the CHn Source Image Format Register is not
> sufficient to disable a plane, as the programmed register value is not
> propagated immediately to the current side. This can be seen when using
> the -P option of modetest: the extra plane is displayed correctly, but
> does not disappear after exit.
>
> Fix this by doing the full update dance using the Blend Control
> Register, like is done when enabling the plane.
>
> Signed-off-by: Geert Uytterhoeven <[email protected]>

Reviewed-by: Laurent Pinchart <[email protected]>

> ---
> drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
> index 850986cee848226a..0e34573c3cb3d032 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
> @@ -215,7 +215,10 @@ static int shmob_drm_plane_disable(struct drm_plane *plane,
>
> splane->format = NULL;
>
> + lcdc_write(sdev, LDBCR, LDBCR_UPC(splane->index));
> lcdc_write(sdev, LDBnBSIFR(splane->index), 0);
> + lcdc_write(sdev, LDBCR,
> + LDBCR_UPF(splane->index) | LDBCR_UPD(splane->index));
> return 0;
> }
>

--
Regards,

Laurent Pinchart

2023-06-23 15:26:25

by Laurent Pinchart

[permalink] [raw]
Subject: Re: [PATCH 02/39] media: uapi: Add MEDIA_BUS_FMT_RGB666_2X9 variants

Hi Geert,

Thank you for the patch.

On Thu, Jun 22, 2023 at 11:21:14AM +0200, Geert Uytterhoeven wrote:
> Add the RGB666 9:9 formats MEDIA_BUS_FMT_RGB666_2X9_BE and
> MEDIA_BUS_FMT_RGB666_2X9_LE. The former is supported by the SH-Mobile
> LCD Controller.

If MEDIA_BUS_FMT_RGB666_2X9_LE isn't supported, I'd leave it out for
now. It can be added later once a driver needs it.

Reviewed-by: Laurent Pinchart <[email protected]>

> Signed-off-by: Geert Uytterhoeven <[email protected]>
> Cc: Mauro Carvalho Chehab <[email protected]>
> Cc: [email protected]
> ---
> .../media/v4l/subdev-formats.rst | 144 ++++++++++++++++++
> include/uapi/linux/media-bus-format.h | 4 +-
> 2 files changed, 147 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/userspace-api/media/v4l/subdev-formats.rst b/Documentation/userspace-api/media/v4l/subdev-formats.rst
> index a3a35eeed70846ba..4bbcdec101384cb1 100644
> --- a/Documentation/userspace-api/media/v4l/subdev-formats.rst
> +++ b/Documentation/userspace-api/media/v4l/subdev-formats.rst
> @@ -949,6 +949,150 @@ The following tables list existing packed RGB formats.
> - b\ :sub:`2`
> - b\ :sub:`1`
> - b\ :sub:`0`
> + * .. _MEDIA-BUS-FMT-RGB666-2X9-BE:
> +
> + - MEDIA_BUS_FMT_RGB666_2X9_BE
> + - 0x1025
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + - r\ :sub:`5`
> + - r\ :sub:`4`
> + - r\ :sub:`3`
> + - r\ :sub:`2`
> + - r\ :sub:`1`
> + - r\ :sub:`0`
> + - g\ :sub:`5`
> + - g\ :sub:`4`
> + - g\ :sub:`3`
> + * -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + - g\ :sub:`2`
> + - g\ :sub:`1`
> + - g\ :sub:`0`
> + - b\ :sub:`5`
> + - b\ :sub:`4`
> + - b\ :sub:`3`
> + - b\ :sub:`2`
> + - b\ :sub:`1`
> + - b\ :sub:`0`
> + * .. _MEDIA-BUS-FMT-RGB666-2X9-LE:
> +
> + - MEDIA_BUS_FMT_RGB666_2X9_LE
> + - 0x1026
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + - g\ :sub:`2`
> + - g\ :sub:`1`
> + - g\ :sub:`0`
> + - b\ :sub:`5`
> + - b\ :sub:`4`
> + - b\ :sub:`3`
> + - b\ :sub:`2`
> + - b\ :sub:`1`
> + - b\ :sub:`0`
> + * -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + -
> + - r\ :sub:`5`
> + - r\ :sub:`4`
> + - r\ :sub:`3`
> + - r\ :sub:`2`
> + - r\ :sub:`1`
> + - r\ :sub:`0`
> + - g\ :sub:`5`
> + - g\ :sub:`4`
> + - g\ :sub:`3`
> * .. _MEDIA-BUS-FMT-BGR666-1X18:
>
> - MEDIA_BUS_FMT_BGR666_1X18
> diff --git a/include/uapi/linux/media-bus-format.h b/include/uapi/linux/media-bus-format.h
> index a03c543cb072de30..07105f530400511e 100644
> --- a/include/uapi/linux/media-bus-format.h
> +++ b/include/uapi/linux/media-bus-format.h
> @@ -34,7 +34,7 @@
>
> #define MEDIA_BUS_FMT_FIXED 0x0001
>
> -/* RGB - next is 0x1025 */
> +/* RGB - next is 0x1027 */
> #define MEDIA_BUS_FMT_RGB444_1X12 0x1016
> #define MEDIA_BUS_FMT_RGB444_2X8_PADHI_BE 0x1001
> #define MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE 0x1002
> @@ -46,6 +46,8 @@
> #define MEDIA_BUS_FMT_RGB565_2X8_BE 0x1007
> #define MEDIA_BUS_FMT_RGB565_2X8_LE 0x1008
> #define MEDIA_BUS_FMT_RGB666_1X18 0x1009
> +#define MEDIA_BUS_FMT_RGB666_2X9_BE 0x1025
> +#define MEDIA_BUS_FMT_RGB666_2X9_LE 0x1026
> #define MEDIA_BUS_FMT_BGR666_1X18 0x1023
> #define MEDIA_BUS_FMT_RBG888_1X24 0x100e
> #define MEDIA_BUS_FMT_RGB666_1X24_CPADHI 0x1015

--
Regards,

Laurent Pinchart

2023-06-23 15:31:15

by Laurent Pinchart

[permalink] [raw]
Subject: Re: [PATCH 05/39] drm: renesas: shmobile: Correct encoder/connector types

Hi Geert,

Thank you for the patch.

On Thu, Jun 22, 2023 at 11:21:17AM +0200, Geert Uytterhoeven wrote:
> The first encoder output on the SH-Mobile LCD Controller is a DPI
> parallel bus. However, at the time of introduction of the driver, no
> encoder or connector types were defined yet for the DPI parallel bus,
> hence the driver used the ones for LVDS instead.
>
> Adjust the types accordingly.
>
> Signed-off-by: Geert Uytterhoeven <[email protected]>
> ---
> drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> index 11dd2bc803e7cb62..fbfd906844da490c 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> @@ -598,7 +598,7 @@ int shmob_drm_encoder_create(struct shmob_drm_device *sdev)
> encoder->possible_crtcs = 1;
>
> ret = drm_simple_encoder_init(sdev->ddev, encoder,
> - DRM_MODE_ENCODER_LVDS);
> + DRM_MODE_ENCODER_DPI);

You can use DRM_MODE_ENCODER_NONE, that will simplify the code when
adding support for additional outputs. The encoder type was exposed to
userspace by mistake, and AFAIU is unused by userspace, so it doesn't
need to be specified.

Reviewed-by: Laurent Pinchart <[email protected]>

> if (ret < 0)
> return ret;
>
> @@ -684,7 +684,7 @@ int shmob_drm_connector_create(struct shmob_drm_device *sdev,
> connector->display_info.height_mm = sdev->pdata->panel.height_mm;
>
> ret = drm_connector_init(sdev->ddev, connector, &connector_funcs,
> - DRM_MODE_CONNECTOR_LVDS);
> + DRM_MODE_CONNECTOR_DPI);
> if (ret < 0)
> return ret;
>

--
Regards,

Laurent Pinchart

2023-06-23 15:34:18

by Laurent Pinchart

[permalink] [raw]
Subject: Re: [PATCH 06/39] drm: renesas: shmobile: Add support for Runtime PM

On Fri, Jun 23, 2023 at 06:07:44PM +0300, Laurent Pinchart wrote:
> Hi Geert,
>
> Thank you for the patch.
>
> On Thu, Jun 22, 2023 at 11:21:18AM +0200, Geert Uytterhoeven wrote:
> > The SH-Mobile LCD Controller is part of a PM Domain on all relevant SoCs
> > (clock domain on all, power domain on some). Hence it may not be
> > sufficient to manage the LCDC module clock explicitly (e.g. if the
> > selected clock source differs from SHMOB_DRM_CLK_BUS).
> >
> > Fix this by using Runtime PM instead.
> >
> > Signed-off-by: Geert Uytterhoeven <[email protected]>
> > ---
> > drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 11 ++++++++++-
> > drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c | 5 +++++
> > 2 files changed, 15 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> > index fbfd906844da490c..84dbf35025d7be63 100644
> > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> > @@ -9,6 +9,7 @@
> >
> > #include <linux/backlight.h>
> > #include <linux/clk.h>
> > +#include <linux/pm_runtime.h>
> >
> > #include <drm/drm_crtc.h>
> > #include <drm/drm_crtc_helper.h>
> > @@ -170,10 +171,16 @@ static void shmob_drm_crtc_start(struct shmob_drm_crtc *scrtc)
> > if (WARN_ON(format == NULL))
> > return;
> >
> > + ret = pm_runtime_resume_and_get(sdev->dev);
> > + if (ret)
> > + return;
> > +
> > /* Enable clocks before accessing the hardware. */
> > ret = shmob_drm_clk_on(sdev);
>
> This would be best located in the runtime PM resume handler. Same for
> disabling clocks in the runtime PM suspend handler.

The driver should then depend on CONFIG_PM. There's no indirect
dependency through CONFIG_DRM as far as I can tell, but there's one
through ARCH_SHMOBILE. This then got me puzzled, as ARCH_SHMOBILE is
defined in arch/sh/Kconfig, and this driver depends on ARM. Am I missing
something ?

> > - if (ret < 0)
> > + if (ret < 0) {
> > + pm_runtime_put(sdev->dev);
> > return;
> > + }
> >
> > /* Reset and enable the LCDC. */
> > lcdc_write(sdev, LDCNT2R, lcdc_read(sdev, LDCNT2R) | LDCNT2R_BR);
> > @@ -271,6 +278,8 @@ static void shmob_drm_crtc_stop(struct shmob_drm_crtc *scrtc)
> > /* Stop clocks. */
> > shmob_drm_clk_off(sdev);
> >
> > + pm_runtime_put(sdev->dev);
> > +
> > scrtc->started = false;
> > }
> >
> > diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> > index 30493ce874192e3e..4f01caa119637032 100644
> > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> > @@ -13,6 +13,7 @@
> > #include <linux/module.h>
> > #include <linux/platform_device.h>
> > #include <linux/pm.h>
> > +#include <linux/pm_runtime.h>
> > #include <linux/slab.h>
> >
> > #include <drm/drm_drv.h>
> > @@ -216,6 +217,10 @@ static int shmob_drm_probe(struct platform_device *pdev)
> > if (IS_ERR(sdev->mmio))
> > return PTR_ERR(sdev->mmio);
> >
> > + ret = devm_pm_runtime_enable(&pdev->dev);
> > + if (ret)
> > + return ret;
> > +
>
> I would move this after shmob_drm_setup_clocks(), to ensure that the
> runtime PM suspend and resume handlers will have access to clocks.
>
> > ret = shmob_drm_setup_clocks(sdev, pdata->clk_source);
> > if (ret < 0)
> > return ret;

--
Regards,

Laurent Pinchart

2023-06-23 15:34:18

by Laurent Pinchart

[permalink] [raw]
Subject: Re: [PATCH 08/39] drm: renesas: shmobile: Use %p4cc to print fourcc code

Hi Geert,

Thank you for the patch.

On Thu, Jun 22, 2023 at 11:21:20AM +0200, Geert Uytterhoeven wrote:
> Replace the last printing of an hexadecimal fourcc format code by a
> pretty-printed format name, using the "%p4cc" format specifier.
>
> Signed-off-by: Geert Uytterhoeven <[email protected]>

Reviewed-by: Laurent Pinchart <[email protected]>

> ---
> drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
> index 7e49e2873da1bb6f..36fedb2b74c8b7a2 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
> @@ -184,8 +184,8 @@ shmob_drm_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
>
> format = shmob_drm_format_info(fb->format->format);
> if (format == NULL) {
> - dev_dbg(sdev->dev, "update_plane: unsupported format %08x\n",
> - fb->format->format);
> + dev_dbg(sdev->dev, "update_plane: unsupported format %p4cc\n",
> + &fb->format->format);
> return -EINVAL;
> }
>

--
Regards,

Laurent Pinchart

2023-06-23 15:40:35

by Laurent Pinchart

[permalink] [raw]
Subject: Re: [PATCH 06/39] drm: renesas: shmobile: Add support for Runtime PM

On Fri, Jun 23, 2023 at 05:22:45PM +0200, Geert Uytterhoeven wrote:
> On Fri, Jun 23, 2023 at 5:11 PM Laurent Pinchart wrote:
> > On Fri, Jun 23, 2023 at 06:07:44PM +0300, Laurent Pinchart wrote:
> > > On Thu, Jun 22, 2023 at 11:21:18AM +0200, Geert Uytterhoeven wrote:
> > > > The SH-Mobile LCD Controller is part of a PM Domain on all relevant SoCs
> > > > (clock domain on all, power domain on some). Hence it may not be
> > > > sufficient to manage the LCDC module clock explicitly (e.g. if the
> > > > selected clock source differs from SHMOB_DRM_CLK_BUS).
> > > >
> > > > Fix this by using Runtime PM instead.
> > > >
> > > > Signed-off-by: Geert Uytterhoeven <[email protected]>
> > > > ---
> > > > drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 11 ++++++++++-
> > > > drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c | 5 +++++
> > > > 2 files changed, 15 insertions(+), 1 deletion(-)
> > > >
> > > > diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> > > > index fbfd906844da490c..84dbf35025d7be63 100644
> > > > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> > > > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> > > > @@ -9,6 +9,7 @@
> > > >
> > > > #include <linux/backlight.h>
> > > > #include <linux/clk.h>
> > > > +#include <linux/pm_runtime.h>
> > > >
> > > > #include <drm/drm_crtc.h>
> > > > #include <drm/drm_crtc_helper.h>
> > > > @@ -170,10 +171,16 @@ static void shmob_drm_crtc_start(struct shmob_drm_crtc *scrtc)
> > > > if (WARN_ON(format == NULL))
> > > > return;
> > > >
> > > > + ret = pm_runtime_resume_and_get(sdev->dev);
> > > > + if (ret)
> > > > + return;
> > > > +
> > > > /* Enable clocks before accessing the hardware. */
> > > > ret = shmob_drm_clk_on(sdev);
> > >
> > > This would be best located in the runtime PM resume handler. Same for
> > > disabling clocks in the runtime PM suspend handler.
> >
> > The driver should then depend on CONFIG_PM. There's no indirect
> > dependency through CONFIG_DRM as far as I can tell, but there's one
> > through ARCH_SHMOBILE. This then got me puzzled, as ARCH_SHMOBILE is
> > defined in arch/sh/Kconfig, and this driver depends on ARM. Am I missing
> > something ?
>
> Vommit 4bd65789ba847f39 ("drm: shmobile: Make DRM_SHMOBILE visible on
> Renesas SoC platforms") in drm-next:
>
> - depends on DRM && ARM
> - depends on ARCH_SHMOBILE || COMPILE_TEST
> + depends on DRM
> + depends on ARCH_RENESAS || ARCH_SHMOBILE || COMPILE_TEST

That's better indeed :-)

A dependency on CONFIG_PM is still needed as ARCH_RENESAS doesn't depend
on it.

--
Regards,

Laurent Pinchart

2023-06-23 15:53:36

by Laurent Pinchart

[permalink] [raw]
Subject: Re: [PATCH 15/39] drm: renesas: shmobile: Improve error handling

Hi Geert,

Thank you for the patch.

On Thu, Jun 22, 2023 at 11:21:27AM +0200, Geert Uytterhoeven wrote:
> Prepare for DT conversion, where panel probe can be deferred, by
> streamlining error propagation and handling:
> - Use dev_err_probe() to avoid printing error messages in case of
> probe deferral,
> - Propagate errors where needed.
>
> Signed-off-by: Geert Uytterhoeven <[email protected]>

Reviewed-by: Laurent Pinchart <[email protected]>

> ---
> drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c | 3 ++-
> drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c | 14 +++++++++++---
> 2 files changed, 13 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> index 9aa9800899976a23..50fca18282c5cb5e 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> @@ -228,7 +228,8 @@ static int shmob_drm_probe(struct platform_device *pdev)
>
> ret = shmob_drm_modeset_init(sdev);
> if (ret < 0) {
> - dev_err(&pdev->dev, "failed to initialize mode setting\n");
> + dev_err_probe(&pdev->dev, ret,
> + "failed to initialize mode setting\n");
> goto err_free_drm_dev;
> }
>
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c
> index 3051318ddc7999bc..1a62e7f8a8a9e6df 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c
> @@ -157,9 +157,17 @@ int shmob_drm_modeset_init(struct shmob_drm_device *sdev)
> if (ret)
> return ret;
>
> - shmob_drm_crtc_create(sdev);
> - shmob_drm_encoder_create(sdev);
> - shmob_drm_connector_create(sdev, &sdev->encoder);
> + ret = shmob_drm_crtc_create(sdev);
> + if (ret < 0)
> + return ret;
> +
> + ret = shmob_drm_encoder_create(sdev);
> + if (ret < 0)
> + return ret;
> +
> + ret = shmob_drm_connector_create(sdev, &sdev->encoder);
> + if (ret < 0)
> + return ret;
>
> drm_kms_helper_poll_init(sdev->ddev);
>

--
Regards,

Laurent Pinchart

2023-06-23 15:58:48

by Laurent Pinchart

[permalink] [raw]
Subject: Re: [PATCH 11/39] drm: renesas: shmobile: Remove backlight support

Hi Geert,

Thank you for the patch.

On Thu, Jun 22, 2023 at 11:21:23AM +0200, Geert Uytterhoeven wrote:
> From: Laurent Pinchart <[email protected]>
>
> Backlight support should be implemented by panels, not by the LCDC
> driver. As the feature is currently unused anyway, remove it.
>
> Signed-off-by: Laurent Pinchart <[email protected]>
> [geert: Cleanups]
> Signed-off-by: Geert Uytterhoeven <[email protected]>

Reviewed-by: Laurent Pinchart <[email protected]>

> ---
> Changes compared to Laurent's original:
> - Rebase,
> - Remove unused variable ‘scon’,
> - Remove now unused to_shmob_encoder() macro,
> - Remove now empty shmob_drm_encoder wrapper.
> ---
> drivers/gpu/drm/renesas/shmobile/Makefile | 3 +-
> .../renesas/shmobile/shmob_drm_backlight.c | 82 -------------------
> .../renesas/shmobile/shmob_drm_backlight.h | 19 -----
> .../gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 33 +-------
> .../gpu/drm/renesas/shmobile/shmob_drm_crtc.h | 8 --
> .../gpu/drm/renesas/shmobile/shmob_drm_drv.h | 2 +-
> .../gpu/drm/renesas/shmobile/shmob_drm_kms.c | 2 +-
> include/linux/platform_data/shmob_drm.h | 8 --
> 8 files changed, 7 insertions(+), 150 deletions(-)
> delete mode 100644 drivers/gpu/drm/renesas/shmobile/shmob_drm_backlight.c
> delete mode 100644 drivers/gpu/drm/renesas/shmobile/shmob_drm_backlight.h
>
> diff --git a/drivers/gpu/drm/renesas/shmobile/Makefile b/drivers/gpu/drm/renesas/shmobile/Makefile
> index 861edafed8562c87..2679555d61a70207 100644
> --- a/drivers/gpu/drm/renesas/shmobile/Makefile
> +++ b/drivers/gpu/drm/renesas/shmobile/Makefile
> @@ -1,6 +1,5 @@
> # SPDX-License-Identifier: GPL-2.0
> -shmob-drm-y := shmob_drm_backlight.o \
> - shmob_drm_crtc.o \
> +shmob-drm-y := shmob_drm_crtc.o \
> shmob_drm_drv.o \
> shmob_drm_kms.o \
> shmob_drm_plane.o
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_backlight.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_backlight.c
> deleted file mode 100644
> index 794573badfe86076..0000000000000000
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_backlight.c
> +++ /dev/null
> @@ -1,82 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0+
> -/*
> - * shmob_drm_backlight.c -- SH Mobile DRM Backlight
> - *
> - * Copyright (C) 2012 Renesas Electronics Corporation
> - *
> - * Laurent Pinchart ([email protected])
> - */
> -
> -#include <linux/backlight.h>
> -
> -#include "shmob_drm_backlight.h"
> -#include "shmob_drm_crtc.h"
> -#include "shmob_drm_drv.h"
> -
> -static int shmob_drm_backlight_update(struct backlight_device *bdev)
> -{
> - struct shmob_drm_connector *scon = bl_get_data(bdev);
> - struct shmob_drm_device *sdev = scon->connector.dev->dev_private;
> - const struct shmob_drm_backlight_data *bdata = &sdev->pdata->backlight;
> - int brightness = backlight_get_brightness(bdev);
> -
> - return bdata->set_brightness(brightness);
> -}
> -
> -static int shmob_drm_backlight_get_brightness(struct backlight_device *bdev)
> -{
> - struct shmob_drm_connector *scon = bl_get_data(bdev);
> - struct shmob_drm_device *sdev = scon->connector.dev->dev_private;
> - const struct shmob_drm_backlight_data *bdata = &sdev->pdata->backlight;
> -
> - return bdata->get_brightness();
> -}
> -
> -static const struct backlight_ops shmob_drm_backlight_ops = {
> - .options = BL_CORE_SUSPENDRESUME,
> - .update_status = shmob_drm_backlight_update,
> - .get_brightness = shmob_drm_backlight_get_brightness,
> -};
> -
> -void shmob_drm_backlight_dpms(struct shmob_drm_connector *scon, int mode)
> -{
> - if (scon->backlight == NULL)
> - return;
> -
> - scon->backlight->props.power = mode == DRM_MODE_DPMS_ON
> - ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN;
> - backlight_update_status(scon->backlight);
> -}
> -
> -int shmob_drm_backlight_init(struct shmob_drm_connector *scon)
> -{
> - struct shmob_drm_device *sdev = scon->connector.dev->dev_private;
> - const struct shmob_drm_backlight_data *bdata = &sdev->pdata->backlight;
> - struct drm_connector *connector = &scon->connector;
> - struct drm_device *dev = connector->dev;
> - struct backlight_device *backlight;
> -
> - if (!bdata->max_brightness)
> - return 0;
> -
> - backlight = backlight_device_register(bdata->name, dev->dev, scon,
> - &shmob_drm_backlight_ops, NULL);
> - if (IS_ERR(backlight)) {
> - dev_err(dev->dev, "unable to register backlight device: %ld\n",
> - PTR_ERR(backlight));
> - return PTR_ERR(backlight);
> - }
> -
> - backlight->props.max_brightness = bdata->max_brightness;
> - backlight->props.brightness = bdata->max_brightness;
> - backlight->props.power = FB_BLANK_POWERDOWN;
> - backlight_update_status(backlight);
> -
> - scon->backlight = backlight;
> - return 0;
> -}
> -
> -void shmob_drm_backlight_exit(struct shmob_drm_connector *scon)
> -{
> - backlight_device_unregister(scon->backlight);
> -}
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_backlight.h b/drivers/gpu/drm/renesas/shmobile/shmob_drm_backlight.h
> deleted file mode 100644
> index d9abb7a60be5c414..0000000000000000
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_backlight.h
> +++ /dev/null
> @@ -1,19 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0+ */
> -/*
> - * shmob_drm_backlight.h -- SH Mobile DRM Backlight
> - *
> - * Copyright (C) 2012 Renesas Electronics Corporation
> - *
> - * Laurent Pinchart ([email protected])
> - */
> -
> -#ifndef __SHMOB_DRM_BACKLIGHT_H__
> -#define __SHMOB_DRM_BACKLIGHT_H__
> -
> -struct shmob_drm_connector;
> -
> -void shmob_drm_backlight_dpms(struct shmob_drm_connector *scon, int mode);
> -int shmob_drm_backlight_init(struct shmob_drm_connector *scon);
> -void shmob_drm_backlight_exit(struct shmob_drm_connector *scon);
> -
> -#endif /* __SHMOB_DRM_BACKLIGHT_H__ */
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> index 9bfdfa7c6e2b1001..c775c1d49f0e1ce9 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> @@ -7,7 +7,6 @@
> * Laurent Pinchart ([email protected])
> */
>
> -#include <linux/backlight.h>
> #include <linux/clk.h>
> #include <linux/pm_runtime.h>
>
> @@ -24,7 +23,6 @@
> #include <drm/drm_simple_kms_helper.h>
> #include <drm/drm_vblank.h>
>
> -#include "shmob_drm_backlight.h"
> #include "shmob_drm_crtc.h"
> #include "shmob_drm_drv.h"
> #include "shmob_drm_kms.h"
> @@ -520,21 +518,9 @@ int shmob_drm_crtc_create(struct shmob_drm_device *sdev)
> * Encoder
> */
>
> -#define to_shmob_encoder(e) \
> - container_of(e, struct shmob_drm_encoder, encoder)
> -
> static void shmob_drm_encoder_dpms(struct drm_encoder *encoder, int mode)
> {
> - struct shmob_drm_encoder *senc = to_shmob_encoder(encoder);
> - struct shmob_drm_device *sdev = encoder->dev->dev_private;
> - struct shmob_drm_connector *scon = &sdev->connector;
> -
> - if (senc->dpms == mode)
> - return;
> -
> - shmob_drm_backlight_dpms(scon, mode);
> -
> - senc->dpms = mode;
> + /* No-op, everything is handled in the CRTC code. */
> }
>
> static bool shmob_drm_encoder_mode_fixup(struct drm_encoder *encoder,
> @@ -586,11 +572,9 @@ static const struct drm_encoder_helper_funcs encoder_helper_funcs = {
>
> int shmob_drm_encoder_create(struct shmob_drm_device *sdev)
> {
> - struct drm_encoder *encoder = &sdev->encoder.encoder;
> + struct drm_encoder *encoder = &sdev->encoder;
> int ret;
>
> - sdev->encoder.dpms = DRM_MODE_DPMS_OFF;
> -
> encoder->possible_crtcs = 1;
>
> ret = drm_simple_encoder_init(sdev->ddev, encoder,
> @@ -655,9 +639,6 @@ static const struct drm_connector_helper_funcs connector_helper_funcs = {
>
> static void shmob_drm_connector_destroy(struct drm_connector *connector)
> {
> - struct shmob_drm_connector *scon = to_shmob_connector(connector);
> -
> - shmob_drm_backlight_exit(scon);
> drm_connector_unregister(connector);
> drm_connector_cleanup(connector);
> }
> @@ -686,13 +667,9 @@ int shmob_drm_connector_create(struct shmob_drm_device *sdev,
>
> drm_connector_helper_add(connector, &connector_helper_funcs);
>
> - ret = shmob_drm_backlight_init(&sdev->connector);
> - if (ret < 0)
> - goto err_cleanup;
> -
> ret = drm_connector_attach_encoder(connector, encoder);
> if (ret < 0)
> - goto err_backlight;
> + goto error;
>
> drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
> drm_object_property_set_value(&connector->base,
> @@ -700,9 +677,7 @@ int shmob_drm_connector_create(struct shmob_drm_device *sdev,
>
> return 0;
>
> -err_backlight:
> - shmob_drm_backlight_exit(&sdev->connector);
> -err_cleanup:
> +error:
> drm_connector_cleanup(connector);
> return ret;
> }
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
> index 21718843f46d3d19..bce6926269453b77 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
> @@ -14,7 +14,6 @@
> #include <drm/drm_connector.h>
> #include <drm/drm_encoder.h>
>
> -struct backlight_device;
> struct drm_pending_vblank_event;
> struct shmob_drm_device;
> struct shmob_drm_format_info;
> @@ -31,16 +30,9 @@ struct shmob_drm_crtc {
> bool started;
> };
>
> -struct shmob_drm_encoder {
> - struct drm_encoder encoder;
> - int dpms;
> -};
> -
> struct shmob_drm_connector {
> struct drm_connector connector;
> struct drm_encoder *encoder;
> -
> - struct backlight_device *backlight;
> };
>
> int shmob_drm_crtc_create(struct shmob_drm_device *sdev);
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.h b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.h
> index 4964ddd5ab7472b0..16d830168b2ada21 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.h
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.h
> @@ -35,7 +35,7 @@ struct shmob_drm_device {
> struct drm_device *ddev;
>
> struct shmob_drm_crtc crtc;
> - struct shmob_drm_encoder encoder;
> + struct drm_encoder encoder;
> struct shmob_drm_connector connector;
> };
>
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c
> index 8fd360149743f8e2..3051318ddc7999bc 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c
> @@ -159,7 +159,7 @@ int shmob_drm_modeset_init(struct shmob_drm_device *sdev)
>
> shmob_drm_crtc_create(sdev);
> shmob_drm_encoder_create(sdev);
> - shmob_drm_connector_create(sdev, &sdev->encoder.encoder);
> + shmob_drm_connector_create(sdev, &sdev->encoder);
>
> drm_kms_helper_poll_init(sdev->ddev);
>
> diff --git a/include/linux/platform_data/shmob_drm.h b/include/linux/platform_data/shmob_drm.h
> index d661399b217dfc4b..b6b5b6607fb5e52c 100644
> --- a/include/linux/platform_data/shmob_drm.h
> +++ b/include/linux/platform_data/shmob_drm.h
> @@ -40,13 +40,6 @@ enum shmob_drm_interface {
> SHMOB_DRM_IFACE_SYS24, /* 24bpp */
> };
>
> -struct shmob_drm_backlight_data {
> - const char *name;
> - int max_brightness;
> - int (*get_brightness)(void);
> - int (*set_brightness)(int brightness);
> -};
> -
> struct shmob_drm_panel_data {
> unsigned int width_mm; /* Panel width in mm */
> unsigned int height_mm; /* Panel height in mm */
> @@ -83,7 +76,6 @@ struct shmob_drm_platform_data {
> enum shmob_drm_clk_source clk_source;
> struct shmob_drm_interface_data iface;
> struct shmob_drm_panel_data panel;
> - struct shmob_drm_backlight_data backlight;
> };
>
> #endif /* __SHMOB_DRM_H__ */

--
Regards,

Laurent Pinchart

2023-06-23 16:02:17

by Laurent Pinchart

[permalink] [raw]
Subject: Re: [PATCH 09/39] drm: renesas: shmobile: Add missing YCbCr formats

On Thu, Jun 22, 2023 at 11:21:21AM +0200, Geert Uytterhoeven wrote:
> The primary plane supports various YCbCr formats, and the CRTC code
> already knows how to handle them. Enable support for the missing
> formats by adding them to the table of supported modes.
>
> Signed-off-by: Geert Uytterhoeven <[email protected]>

Reviewed-by: Laurent Pinchart <[email protected]>

> ---
> drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 6 ++++++
> 1 file changed, 6 insertions(+)
>
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> index 84dbf35025d7be63..cd492806105e5b5d 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> @@ -493,6 +493,12 @@ static const uint32_t modeset_formats[] = {
> DRM_FORMAT_RGB888,
> DRM_FORMAT_ARGB8888,
> DRM_FORMAT_XRGB8888,
> + DRM_FORMAT_NV12,
> + DRM_FORMAT_NV21,
> + DRM_FORMAT_NV16,
> + DRM_FORMAT_NV61,
> + DRM_FORMAT_NV24,
> + DRM_FORMAT_NV42,
> };
>
> static const struct drm_plane_funcs primary_plane_funcs = {

--
Regards,

Laurent Pinchart

2023-06-23 16:03:58

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH 06/39] drm: renesas: shmobile: Add support for Runtime PM

Hi Laurent,

On Fri, Jun 23, 2023 at 5:11 PM Laurent Pinchart
<[email protected]> wrote:
> On Fri, Jun 23, 2023 at 06:07:44PM +0300, Laurent Pinchart wrote:
> > On Thu, Jun 22, 2023 at 11:21:18AM +0200, Geert Uytterhoeven wrote:
> > > The SH-Mobile LCD Controller is part of a PM Domain on all relevant SoCs
> > > (clock domain on all, power domain on some). Hence it may not be
> > > sufficient to manage the LCDC module clock explicitly (e.g. if the
> > > selected clock source differs from SHMOB_DRM_CLK_BUS).
> > >
> > > Fix this by using Runtime PM instead.
> > >
> > > Signed-off-by: Geert Uytterhoeven <[email protected]>
> > > ---
> > > drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 11 ++++++++++-
> > > drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c | 5 +++++
> > > 2 files changed, 15 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> > > index fbfd906844da490c..84dbf35025d7be63 100644
> > > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> > > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> > > @@ -9,6 +9,7 @@
> > >
> > > #include <linux/backlight.h>
> > > #include <linux/clk.h>
> > > +#include <linux/pm_runtime.h>
> > >
> > > #include <drm/drm_crtc.h>
> > > #include <drm/drm_crtc_helper.h>
> > > @@ -170,10 +171,16 @@ static void shmob_drm_crtc_start(struct shmob_drm_crtc *scrtc)
> > > if (WARN_ON(format == NULL))
> > > return;
> > >
> > > + ret = pm_runtime_resume_and_get(sdev->dev);
> > > + if (ret)
> > > + return;
> > > +
> > > /* Enable clocks before accessing the hardware. */
> > > ret = shmob_drm_clk_on(sdev);
> >
> > This would be best located in the runtime PM resume handler. Same for
> > disabling clocks in the runtime PM suspend handler.
>
> The driver should then depend on CONFIG_PM. There's no indirect
> dependency through CONFIG_DRM as far as I can tell, but there's one
> through ARCH_SHMOBILE. This then got me puzzled, as ARCH_SHMOBILE is
> defined in arch/sh/Kconfig, and this driver depends on ARM. Am I missing
> something ?

Vommit 4bd65789ba847f39 ("drm: shmobile: Make DRM_SHMOBILE visible on
Renesas SoC platforms") in drm-next:

- depends on DRM && ARM
- depends on ARCH_SHMOBILE || COMPILE_TEST
+ depends on DRM
+ depends on ARCH_RENESAS || ARCH_SHMOBILE || COMPILE_TEST

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

2023-06-23 16:04:39

by Laurent Pinchart

[permalink] [raw]
Subject: Re: [PATCH 10/39] drm: renesas: shmobile: Improve shmob_drm_format_info table

Hi Geert,

Thank you for the patch.

On Thu, Jun 22, 2023 at 11:21:22AM +0200, Geert Uytterhoeven wrote:
> Improve the table containing hardware information related to the
> supported plane formats:
> 1. Move (part of) the overlay format register settings from multiple
> switch() statements spread across the code into the table, like is
> already done for the primary plane register settings,
> 2. Remove the .yuv field, as that information can easily be extracted
> from the register settings using a new helper macro,
> 3. Shrink and move the .bpp field to reduce table size.
>
> Signed-off-by: Geert Uytterhoeven <[email protected]>
> ---
> .../gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 29 ++--------
> .../gpu/drm/renesas/shmobile/shmob_drm_kms.c | 42 ++++++++++----
> .../gpu/drm/renesas/shmobile/shmob_drm_kms.h | 9 ++-
> .../drm/renesas/shmobile/shmob_drm_plane.c | 56 ++-----------------
> 4 files changed, 47 insertions(+), 89 deletions(-)

I like this :-)

Reviewed-by: Laurent Pinchart <[email protected]>

> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> index cd492806105e5b5d..9bfdfa7c6e2b1001 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> @@ -221,31 +221,12 @@ static void shmob_drm_crtc_start(struct shmob_drm_crtc *scrtc)
> lcdc_write(sdev, LDDFR, format->lddfr | LDDFR_CF1);
> lcdc_write(sdev, LDMLSR, scrtc->line_size);
> lcdc_write(sdev, LDSA1R, scrtc->dma[0]);
> - if (format->yuv)
> + if (shmob_drm_format_is_yuv(format))
> lcdc_write(sdev, LDSA2R, scrtc->dma[1]);
> lcdc_write(sdev, LDSM1R, 0);
>
> /* Word and long word swap. */
> - switch (format->fourcc) {
> - case DRM_FORMAT_RGB565:
> - case DRM_FORMAT_NV21:
> - case DRM_FORMAT_NV61:
> - case DRM_FORMAT_NV42:
> - value = LDDDSR_LS | LDDDSR_WS;
> - break;
> - case DRM_FORMAT_RGB888:
> - case DRM_FORMAT_NV12:
> - case DRM_FORMAT_NV16:
> - case DRM_FORMAT_NV24:
> - value = LDDDSR_LS | LDDDSR_WS | LDDDSR_BS;
> - break;
> - case DRM_FORMAT_ARGB8888:
> - case DRM_FORMAT_XRGB8888:
> - default:
> - value = LDDDSR_LS;
> - break;
> - }
> - lcdc_write(sdev, LDDDSR, value);
> + lcdc_write(sdev, LDDDSR, format->ldddsr);
>
> /* Setup planes. */
> drm_for_each_legacy_plane(plane, dev) {
> @@ -304,12 +285,12 @@ static void shmob_drm_crtc_compute_base(struct shmob_drm_crtc *scrtc,
> struct drm_gem_dma_object *gem;
> unsigned int bpp;
>
> - bpp = scrtc->format->yuv ? 8 : scrtc->format->bpp;
> + bpp = shmob_drm_format_is_yuv(scrtc->format) ? 8 : scrtc->format->bpp;
> gem = drm_fb_dma_get_gem_obj(fb, 0);
> scrtc->dma[0] = gem->dma_addr + fb->offsets[0]
> + y * fb->pitches[0] + x * bpp / 8;
>
> - if (scrtc->format->yuv) {
> + if (shmob_drm_format_is_yuv(scrtc->format)) {
> bpp = scrtc->format->bpp - 8;
> gem = drm_fb_dma_get_gem_obj(fb, 1);
> scrtc->dma[1] = gem->dma_addr + fb->offsets[1]
> @@ -326,7 +307,7 @@ static void shmob_drm_crtc_update_base(struct shmob_drm_crtc *scrtc)
> shmob_drm_crtc_compute_base(scrtc, crtc->x, crtc->y);
>
> lcdc_write_mirror(sdev, LDSA1R, scrtc->dma[0]);
> - if (scrtc->format->yuv)
> + if (shmob_drm_format_is_yuv(scrtc->format))
> lcdc_write_mirror(sdev, LDSA2R, scrtc->dma[1]);
>
> lcdc_write(sdev, LDRCNTR, lcdc_read(sdev, LDRCNTR) ^ LDRCNTR_MRS);
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c
> index 99381cc0abf3ae1f..8fd360149743f8e2 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c
> @@ -27,53 +27,73 @@ static const struct shmob_drm_format_info shmob_drm_format_infos[] = {
> {
> .fourcc = DRM_FORMAT_RGB565,
> .bpp = 16,
> - .yuv = false,
> .lddfr = LDDFR_PKF_RGB16,
> + .ldddsr = LDDDSR_LS | LDDDSR_WS,
> + .ldbbsifr = LDBBSIFR_AL_1 | LDBBSIFR_SWPL | LDBBSIFR_SWPW |
> + LDBBSIFR_RY | LDBBSIFR_RPKF_RGB16,
> }, {
> .fourcc = DRM_FORMAT_RGB888,
> .bpp = 24,
> - .yuv = false,
> .lddfr = LDDFR_PKF_RGB24,
> + .ldddsr = LDDDSR_LS | LDDDSR_WS | LDDDSR_BS,
> + .ldbbsifr = LDBBSIFR_AL_1 | LDBBSIFR_SWPL | LDBBSIFR_SWPW |
> + LDBBSIFR_SWPB | LDBBSIFR_RY | LDBBSIFR_RPKF_RGB24,
> }, {
> .fourcc = DRM_FORMAT_ARGB8888,
> .bpp = 32,
> - .yuv = false,
> .lddfr = LDDFR_PKF_ARGB32,
> + .ldddsr = LDDDSR_LS,
> + .ldbbsifr = LDBBSIFR_AL_PK | LDBBSIFR_SWPL | LDBBSIFR_RY |
> + LDBBSIFR_RPKF_ARGB32,
> }, {
> .fourcc = DRM_FORMAT_XRGB8888,
> .bpp = 32,
> - .yuv = false,
> .lddfr = LDDFR_PKF_ARGB32,
> + .ldddsr = LDDDSR_LS,
> + .ldbbsifr = LDBBSIFR_AL_1 | LDBBSIFR_SWPL | LDBBSIFR_RY |
> + LDBBSIFR_RPKF_ARGB32,
> }, {
> .fourcc = DRM_FORMAT_NV12,
> .bpp = 12,
> - .yuv = true,
> .lddfr = LDDFR_CC | LDDFR_YF_420,
> + .ldddsr = LDDDSR_LS | LDDDSR_WS | LDDDSR_BS,
> + .ldbbsifr = LDBBSIFR_AL_1 | LDBBSIFR_SWPL | LDBBSIFR_SWPW |
> + LDBBSIFR_SWPB | LDBBSIFR_CHRR_420,
> }, {
> .fourcc = DRM_FORMAT_NV21,
> .bpp = 12,
> - .yuv = true,
> .lddfr = LDDFR_CC | LDDFR_YF_420,
> + .ldddsr = LDDDSR_LS | LDDDSR_WS,
> + .ldbbsifr = LDBBSIFR_AL_1 | LDBBSIFR_SWPL | LDBBSIFR_SWPW |
> + LDBBSIFR_CHRR_420,
> }, {
> .fourcc = DRM_FORMAT_NV16,
> .bpp = 16,
> - .yuv = true,
> .lddfr = LDDFR_CC | LDDFR_YF_422,
> + .ldddsr = LDDDSR_LS | LDDDSR_WS | LDDDSR_BS,
> + .ldbbsifr = LDBBSIFR_AL_1 | LDBBSIFR_SWPL | LDBBSIFR_SWPW |
> + LDBBSIFR_SWPB | LDBBSIFR_CHRR_422,
> }, {
> .fourcc = DRM_FORMAT_NV61,
> .bpp = 16,
> - .yuv = true,
> .lddfr = LDDFR_CC | LDDFR_YF_422,
> + .ldddsr = LDDDSR_LS | LDDDSR_WS,
> + .ldbbsifr = LDBBSIFR_AL_1 | LDBBSIFR_SWPL | LDBBSIFR_SWPW |
> + LDBBSIFR_CHRR_422,
> }, {
> .fourcc = DRM_FORMAT_NV24,
> .bpp = 24,
> - .yuv = true,
> .lddfr = LDDFR_CC | LDDFR_YF_444,
> + .ldddsr = LDDDSR_LS | LDDDSR_WS | LDDDSR_BS,
> + .ldbbsifr = LDBBSIFR_AL_1 | LDBBSIFR_SWPL | LDBBSIFR_SWPW |
> + LDBBSIFR_SWPB | LDBBSIFR_CHRR_444,
> }, {
> .fourcc = DRM_FORMAT_NV42,
> .bpp = 24,
> - .yuv = true,
> .lddfr = LDDFR_CC | LDDFR_YF_444,
> + .ldddsr = LDDDSR_LS | LDDDSR_WS,
> + .ldbbsifr = LDBBSIFR_AL_1 | LDBBSIFR_SWPL | LDBBSIFR_SWPW |
> + LDBBSIFR_CHRR_444,
> },
> };
>
> @@ -112,7 +132,7 @@ shmob_drm_fb_create(struct drm_device *dev, struct drm_file *file_priv,
> return ERR_PTR(-EINVAL);
> }
>
> - if (format->yuv) {
> + if (shmob_drm_format_is_yuv(format)) {
> unsigned int chroma_cpp = format->bpp == 24 ? 2 : 1;
>
> if (mode_cmd->pitches[1] != mode_cmd->pitches[0] * chroma_cpp) {
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.h b/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.h
> index 0347b1fd2338a84d..590162c3db20209d 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.h
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.h
> @@ -17,11 +17,14 @@ struct shmob_drm_device;
>
> struct shmob_drm_format_info {
> u32 fourcc;
> - unsigned int bpp;
> - bool yuv;
> - u32 lddfr;
> + u32 lddfr; /* LCD Data Format Register */
> + u16 ldbbsifr; /* CHn Source Image Format Register low bits */
> + u8 ldddsr; /* LCDC Input Image Data Swap Register low bits */
> + u8 bpp;
> };
>
> +#define shmob_drm_format_is_yuv(format) ((format)->lddfr & LDDFR_CC)
> +
> const struct shmob_drm_format_info *shmob_drm_format_info(u32 fourcc);
>
> int shmob_drm_modeset_init(struct shmob_drm_device *sdev);
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
> index 36fedb2b74c8b7a2..0b2ab153e9ae76df 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
> @@ -43,12 +43,12 @@ static void shmob_drm_plane_compute_base(struct shmob_drm_plane *splane,
> struct drm_gem_dma_object *gem;
> unsigned int bpp;
>
> - bpp = splane->format->yuv ? 8 : splane->format->bpp;
> + bpp = shmob_drm_format_is_yuv(splane->format) ? 8 : splane->format->bpp;
> gem = drm_fb_dma_get_gem_obj(fb, 0);
> splane->dma[0] = gem->dma_addr + fb->offsets[0]
> + y * fb->pitches[0] + x * bpp / 8;
>
> - if (splane->format->yuv) {
> + if (shmob_drm_format_is_yuv(splane->format)) {
> bpp = splane->format->bpp - 8;
> gem = drm_fb_dma_get_gem_obj(fb, 1);
> splane->dma[1] = gem->dma_addr + fb->offsets[1]
> @@ -64,54 +64,8 @@ static void __shmob_drm_plane_setup(struct shmob_drm_plane *splane,
> u32 format;
>
> /* TODO: Support ROP3 mode */
> - format = LDBBSIFR_EN | (splane->alpha << LDBBSIFR_LAY_SHIFT);
> -
> - switch (splane->format->fourcc) {
> - case DRM_FORMAT_RGB565:
> - case DRM_FORMAT_NV21:
> - case DRM_FORMAT_NV61:
> - case DRM_FORMAT_NV42:
> - format |= LDBBSIFR_SWPL | LDBBSIFR_SWPW;
> - break;
> - case DRM_FORMAT_RGB888:
> - case DRM_FORMAT_NV12:
> - case DRM_FORMAT_NV16:
> - case DRM_FORMAT_NV24:
> - format |= LDBBSIFR_SWPL | LDBBSIFR_SWPW | LDBBSIFR_SWPB;
> - break;
> - case DRM_FORMAT_ARGB8888:
> - case DRM_FORMAT_XRGB8888:
> - default:
> - format |= LDBBSIFR_SWPL;
> - break;
> - }
> -
> - switch (splane->format->fourcc) {
> - case DRM_FORMAT_RGB565:
> - format |= LDBBSIFR_AL_1 | LDBBSIFR_RY | LDBBSIFR_RPKF_RGB16;
> - break;
> - case DRM_FORMAT_RGB888:
> - format |= LDBBSIFR_AL_1 | LDBBSIFR_RY | LDBBSIFR_RPKF_RGB24;
> - break;
> - case DRM_FORMAT_ARGB8888:
> - format |= LDBBSIFR_AL_PK | LDBBSIFR_RY | LDBBSIFR_RPKF_ARGB32;
> - break;
> - case DRM_FORMAT_XRGB8888:
> - format |= LDBBSIFR_AL_1 | LDBBSIFR_RY | LDBBSIFR_RPKF_ARGB32;
> - break;
> - case DRM_FORMAT_NV12:
> - case DRM_FORMAT_NV21:
> - format |= LDBBSIFR_AL_1 | LDBBSIFR_CHRR_420;
> - break;
> - case DRM_FORMAT_NV16:
> - case DRM_FORMAT_NV61:
> - format |= LDBBSIFR_AL_1 | LDBBSIFR_CHRR_422;
> - break;
> - case DRM_FORMAT_NV24:
> - case DRM_FORMAT_NV42:
> - format |= LDBBSIFR_AL_1 | LDBBSIFR_CHRR_444;
> - break;
> - }
> + format = LDBBSIFR_EN | (splane->alpha << LDBBSIFR_LAY_SHIFT) |
> + splane->format->ldbbsifr;
>
> #define plane_reg_dump(sdev, splane, reg) \
> dev_dbg(sdev->ddev->dev, "%s(%u): %s 0x%08x 0x%08x\n", __func__, \
> @@ -144,7 +98,7 @@ static void __shmob_drm_plane_setup(struct shmob_drm_plane *splane,
> shmob_drm_plane_compute_base(splane, fb, splane->src_x, splane->src_y);
>
> lcdc_write(sdev, LDBnBSAYR(splane->index), splane->dma[0]);
> - if (splane->format->yuv)
> + if (shmob_drm_format_is_yuv(splane->format))
> lcdc_write(sdev, LDBnBSACR(splane->index), splane->dma[1]);
>
> lcdc_write(sdev, LDBCR,

--
Regards,

Laurent Pinchart

2023-06-23 16:14:29

by Laurent Pinchart

[permalink] [raw]
Subject: Re: [PATCH 20/39] drm: renesas: shmobile: Replace .dev_private with container_of()

Hi Geert,

Thank you for the patch.

On Thu, Jun 22, 2023 at 11:21:32AM +0200, Geert Uytterhoeven wrote:
> Now that drm_device is embedded in shmob_drm_device, we can use
> a container_of()-based helper to get the shmob_drm_device pointer from
> the drm_device, instead of using the deprecated drm_device.dev_private
> field.
>
> While at it, restore reverse Xmas tree ordering of local variable
> declarations.
>
> Signed-off-by: Geert Uytterhoeven <[email protected]>

Reviewed-by: Laurent Pinchart <[email protected]>

> ---
> .../gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 20 +++++++++----------
> .../gpu/drm/renesas/shmobile/shmob_drm_drv.c | 4 +---
> .../gpu/drm/renesas/shmobile/shmob_drm_drv.h | 5 +++++
> .../drm/renesas/shmobile/shmob_drm_plane.c | 6 +++---
> 4 files changed, 19 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> index 40948b56017ff2df..291b3a5014c24f08 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> @@ -63,7 +63,7 @@ static void shmob_drm_clk_off(struct shmob_drm_device *sdev)
> static void shmob_drm_crtc_setup_geometry(struct shmob_drm_crtc *scrtc)
> {
> struct drm_crtc *crtc = &scrtc->crtc;
> - struct shmob_drm_device *sdev = crtc->dev->dev_private;
> + struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);
> const struct shmob_drm_interface_data *idata = &sdev->pdata->iface;
> const struct drm_display_mode *mode = &crtc->mode;
> u32 value;
> @@ -102,7 +102,7 @@ static void shmob_drm_crtc_setup_geometry(struct shmob_drm_crtc *scrtc)
>
> static void shmob_drm_crtc_start_stop(struct shmob_drm_crtc *scrtc, bool start)
> {
> - struct shmob_drm_device *sdev = scrtc->crtc.dev->dev_private;
> + struct shmob_drm_device *sdev = to_shmob_device(scrtc->crtc.dev);
> u32 value;
>
> value = lcdc_read(sdev, LDCNT2R);
> @@ -136,7 +136,7 @@ static void shmob_drm_crtc_start_stop(struct shmob_drm_crtc *scrtc, bool start)
> static void shmob_drm_crtc_start(struct shmob_drm_crtc *scrtc)
> {
> struct drm_crtc *crtc = &scrtc->crtc;
> - struct shmob_drm_device *sdev = crtc->dev->dev_private;
> + struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);
> const struct shmob_drm_interface_data *idata = &sdev->pdata->iface;
> const struct shmob_drm_format_info *format;
> struct drm_device *dev = &sdev->ddev;
> @@ -223,7 +223,7 @@ static void shmob_drm_crtc_start(struct shmob_drm_crtc *scrtc)
> static void shmob_drm_crtc_stop(struct shmob_drm_crtc *scrtc)
> {
> struct drm_crtc *crtc = &scrtc->crtc;
> - struct shmob_drm_device *sdev = crtc->dev->dev_private;
> + struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);
>
> if (!scrtc->started)
> return;
> @@ -280,7 +280,7 @@ static void shmob_drm_crtc_compute_base(struct shmob_drm_crtc *scrtc,
> static void shmob_drm_crtc_update_base(struct shmob_drm_crtc *scrtc)
> {
> struct drm_crtc *crtc = &scrtc->crtc;
> - struct shmob_drm_device *sdev = crtc->dev->dev_private;
> + struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);
>
> shmob_drm_crtc_compute_base(scrtc, crtc->x, crtc->y);
>
> @@ -322,8 +322,8 @@ static int shmob_drm_crtc_mode_set(struct drm_crtc *crtc,
> int x, int y,
> struct drm_framebuffer *old_fb)
> {
> + struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);
> struct shmob_drm_crtc *scrtc = to_shmob_crtc(crtc);
> - struct shmob_drm_device *sdev = crtc->dev->dev_private;
> const struct shmob_drm_format_info *format;
>
> format = shmob_drm_format_info(crtc->primary->fb->format->format);
> @@ -428,7 +428,7 @@ static void shmob_drm_crtc_enable_vblank(struct shmob_drm_device *sdev,
>
> static int shmob_drm_enable_vblank(struct drm_crtc *crtc)
> {
> - struct shmob_drm_device *sdev = crtc->dev->dev_private;
> + struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);
>
> shmob_drm_crtc_enable_vblank(sdev, true);
>
> @@ -437,7 +437,7 @@ static int shmob_drm_enable_vblank(struct drm_crtc *crtc)
>
> static void shmob_drm_disable_vblank(struct drm_crtc *crtc)
> {
> - struct shmob_drm_device *sdev = crtc->dev->dev_private;
> + struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);
>
> shmob_drm_crtc_enable_vblank(sdev, false);
> }
> @@ -511,7 +511,7 @@ static bool shmob_drm_encoder_mode_fixup(struct drm_encoder *encoder,
> struct drm_display_mode *adjusted_mode)
> {
> struct drm_device *dev = encoder->dev;
> - struct shmob_drm_device *sdev = dev->dev_private;
> + struct shmob_drm_device *sdev = to_shmob_device(dev);
> struct drm_connector *connector = &sdev->connector.connector;
> const struct drm_display_mode *panel_mode;
>
> @@ -581,7 +581,7 @@ static inline struct shmob_drm_connector *to_shmob_connector(struct drm_connecto
>
> static int shmob_drm_connector_get_modes(struct drm_connector *connector)
> {
> - struct shmob_drm_device *sdev = connector->dev->dev_private;
> + struct shmob_drm_device *sdev = to_shmob_device(connector->dev);
> struct drm_display_mode *mode;
>
> mode = drm_mode_create(connector->dev);
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> index 2b77af3a8c97ef8c..1a1d66c6e817e227 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> @@ -95,7 +95,7 @@ static int shmob_drm_setup_clocks(struct shmob_drm_device *sdev,
> static irqreturn_t shmob_drm_irq(int irq, void *arg)
> {
> struct drm_device *dev = arg;
> - struct shmob_drm_device *sdev = dev->dev_private;
> + struct shmob_drm_device *sdev = to_shmob_device(dev);
> unsigned long flags;
> u32 status;
>
> @@ -217,8 +217,6 @@ static int shmob_drm_probe(struct platform_device *pdev)
> if (ret < 0)
> return ret;
>
> - ddev->dev_private = sdev;
> -
> ret = shmob_drm_modeset_init(sdev);
> if (ret < 0)
> return dev_err_probe(&pdev->dev, ret,
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.h b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.h
> index 77bb0da48f37ace8..5e55ba7a207865bd 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.h
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.h
> @@ -39,4 +39,9 @@ struct shmob_drm_device {
> struct shmob_drm_connector connector;
> };
>
> +static inline struct shmob_drm_device *to_shmob_device(struct drm_device *dev)
> +{
> + return container_of(dev, struct shmob_drm_device, ddev);
> +}
> +
> #endif /* __SHMOB_DRM_DRV_H__ */
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
> index 258288c80756bf16..c58b9dca34736342 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
> @@ -63,7 +63,7 @@ static void shmob_drm_plane_compute_base(struct shmob_drm_plane *splane,
> static void __shmob_drm_plane_setup(struct shmob_drm_plane *splane,
> struct drm_framebuffer *fb)
> {
> - struct shmob_drm_device *sdev = splane->plane.dev->dev_private;
> + struct shmob_drm_device *sdev = to_shmob_device(splane->plane.dev);
> u32 format;
>
> /* TODO: Support ROP3 mode */
> @@ -135,8 +135,8 @@ shmob_drm_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
> uint32_t src_w, uint32_t src_h,
> struct drm_modeset_acquire_ctx *ctx)
> {
> + struct shmob_drm_device *sdev = to_shmob_device(plane->dev);
> struct shmob_drm_plane *splane = to_shmob_plane(plane);
> - struct shmob_drm_device *sdev = plane->dev->dev_private;
> const struct shmob_drm_format_info *format;
>
> format = shmob_drm_format_info(fb->format->format);
> @@ -167,8 +167,8 @@ shmob_drm_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
> static int shmob_drm_plane_disable(struct drm_plane *plane,
> struct drm_modeset_acquire_ctx *ctx)
> {
> + struct shmob_drm_device *sdev = to_shmob_device(plane->dev);
> struct shmob_drm_plane *splane = to_shmob_plane(plane);
> - struct shmob_drm_device *sdev = plane->dev->dev_private;
>
> splane->format = NULL;
>

--
Regards,

Laurent Pinchart

2023-06-23 16:28:38

by Laurent Pinchart

[permalink] [raw]
Subject: Re: [PATCH 19/39] drm: renesas: shmobile: Convert container helpers to static inline functions

Hi Geert,

Thank you for the patch.

On Thu, Jun 22, 2023 at 11:21:31AM +0200, Geert Uytterhoeven wrote:
> Replace to conversion helper macros using container_of() by static
> inline functions, to improve type-safety.
>
> Signed-off-by: Geert Uytterhoeven <[email protected]>

Reviewed-by: Laurent Pinchart <[email protected]>

> ---
> drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 11 ++++++++---
> drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c | 5 ++++-
> 2 files changed, 12 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> index 26611440f7a12715..40948b56017ff2df 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> @@ -291,7 +291,10 @@ static void shmob_drm_crtc_update_base(struct shmob_drm_crtc *scrtc)
> lcdc_write(sdev, LDRCNTR, lcdc_read(sdev, LDRCNTR) ^ LDRCNTR_MRS);
> }
>
> -#define to_shmob_crtc(c) container_of(c, struct shmob_drm_crtc, crtc)
> +static inline struct shmob_drm_crtc *to_shmob_crtc(struct drm_crtc *crtc)
> +{
> + return container_of(crtc, struct shmob_drm_crtc, crtc);
> +}
>
> static void shmob_drm_crtc_dpms(struct drm_crtc *crtc, int mode)
> {
> @@ -571,8 +574,10 @@ int shmob_drm_encoder_create(struct shmob_drm_device *sdev)
> * Connector
> */
>
> -#define to_shmob_connector(c) \
> - container_of(c, struct shmob_drm_connector, connector)
> +static inline struct shmob_drm_connector *to_shmob_connector(struct drm_connector *connector)
> +{
> + return container_of(connector, struct shmob_drm_connector, connector);
> +}
>
> static int shmob_drm_connector_get_modes(struct drm_connector *connector)
> {
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
> index 17e66a018689f648..258288c80756bf16 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
> @@ -34,7 +34,10 @@ struct shmob_drm_plane {
> unsigned int crtc_h;
> };
>
> -#define to_shmob_plane(p) container_of(p, struct shmob_drm_plane, plane)
> +static inline struct shmob_drm_plane *to_shmob_plane(struct drm_plane *plane)
> +{
> + return container_of(plane, struct shmob_drm_plane, plane);
> +}
>
> static void shmob_drm_plane_compute_base(struct shmob_drm_plane *splane,
> struct drm_framebuffer *fb,

--
Regards,

Laurent Pinchart

2023-06-23 16:33:45

by Laurent Pinchart

[permalink] [raw]
Subject: Re: [PATCH 18/39] drm: renesas: shmobile: Embed drm_device in shmob_drm_device

Hi Geert,

Thank you for the patch.

On Thu, Jun 22, 2023 at 11:21:30AM +0200, Geert Uytterhoeven wrote:
> Embedding drm_device in shmob_drm_device allows us to use the DRM
> managed API to allocate both structures in one go, simplifying error
> handling.
>
> Signed-off-by: Geert Uytterhoeven <[email protected]>

Reviewed-by: Laurent Pinchart <[email protected]>

> ---
> .../gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 12 +++---
> .../gpu/drm/renesas/shmobile/shmob_drm_drv.c | 41 +++++++------------
> .../gpu/drm/renesas/shmobile/shmob_drm_drv.h | 2 +-
> .../gpu/drm/renesas/shmobile/shmob_drm_kms.c | 16 ++++----
> .../drm/renesas/shmobile/shmob_drm_plane.c | 8 ++--
> 5 files changed, 34 insertions(+), 45 deletions(-)
>
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> index bcdebbc9f8a7e299..26611440f7a12715 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> @@ -139,7 +139,7 @@ static void shmob_drm_crtc_start(struct shmob_drm_crtc *scrtc)
> struct shmob_drm_device *sdev = crtc->dev->dev_private;
> const struct shmob_drm_interface_data *idata = &sdev->pdata->iface;
> const struct shmob_drm_format_info *format;
> - struct drm_device *dev = sdev->ddev;
> + struct drm_device *dev = &sdev->ddev;
> struct drm_plane *plane;
> u32 value;
> int ret;
> @@ -472,7 +472,7 @@ int shmob_drm_crtc_create(struct shmob_drm_device *sdev)
>
> sdev->crtc.dpms = DRM_MODE_DPMS_OFF;
>
> - primary = __drm_universal_plane_alloc(sdev->ddev, sizeof(*primary), 0,
> + primary = __drm_universal_plane_alloc(&sdev->ddev, sizeof(*primary), 0,
> 0, &primary_plane_funcs,
> modeset_formats,
> ARRAY_SIZE(modeset_formats),
> @@ -481,7 +481,7 @@ int shmob_drm_crtc_create(struct shmob_drm_device *sdev)
> if (IS_ERR(primary))
> return PTR_ERR(primary);
>
> - ret = drm_crtc_init_with_planes(sdev->ddev, crtc, primary, NULL,
> + ret = drm_crtc_init_with_planes(&sdev->ddev, crtc, primary, NULL,
> &crtc_funcs, NULL);
> if (ret < 0) {
> drm_plane_cleanup(primary);
> @@ -557,7 +557,7 @@ int shmob_drm_encoder_create(struct shmob_drm_device *sdev)
>
> encoder->possible_crtcs = 1;
>
> - ret = drm_simple_encoder_init(sdev->ddev, encoder,
> + ret = drm_simple_encoder_init(&sdev->ddev, encoder,
> DRM_MODE_ENCODER_DPI);
> if (ret < 0)
> return ret;
> @@ -637,7 +637,7 @@ int shmob_drm_connector_create(struct shmob_drm_device *sdev,
> connector->display_info.width_mm = sdev->pdata->panel.width_mm;
> connector->display_info.height_mm = sdev->pdata->panel.height_mm;
>
> - ret = drm_connector_init(sdev->ddev, connector, &connector_funcs,
> + ret = drm_connector_init(&sdev->ddev, connector, &connector_funcs,
> DRM_MODE_CONNECTOR_DPI);
> if (ret < 0)
> return ret;
> @@ -650,7 +650,7 @@ int shmob_drm_connector_create(struct shmob_drm_device *sdev,
>
> drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
> drm_object_property_set_value(&connector->base,
> - sdev->ddev->mode_config.dpms_property, DRM_MODE_DPMS_OFF);
> + sdev->ddev.mode_config.dpms_property, DRM_MODE_DPMS_OFF);
>
> return 0;
>
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> index ece9aedde9b662d4..2b77af3a8c97ef8c 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> @@ -137,7 +137,7 @@ static int shmob_drm_pm_suspend(struct device *dev)
> {
> struct shmob_drm_device *sdev = dev_get_drvdata(dev);
>
> - drm_kms_helper_poll_disable(sdev->ddev);
> + drm_kms_helper_poll_disable(&sdev->ddev);
> shmob_drm_crtc_suspend(&sdev->crtc);
>
> return 0;
> @@ -147,11 +147,11 @@ static int shmob_drm_pm_resume(struct device *dev)
> {
> struct shmob_drm_device *sdev = dev_get_drvdata(dev);
>
> - drm_modeset_lock_all(sdev->ddev);
> + drm_modeset_lock_all(&sdev->ddev);
> shmob_drm_crtc_resume(&sdev->crtc);
> - drm_modeset_unlock_all(sdev->ddev);
> + drm_modeset_unlock_all(&sdev->ddev);
>
> - drm_kms_helper_poll_enable(sdev->ddev);
> + drm_kms_helper_poll_enable(&sdev->ddev);
> return 0;
> }
>
> @@ -165,12 +165,10 @@ static DEFINE_SIMPLE_DEV_PM_OPS(shmob_drm_pm_ops,
> static int shmob_drm_remove(struct platform_device *pdev)
> {
> struct shmob_drm_device *sdev = platform_get_drvdata(pdev);
> - struct drm_device *ddev = sdev->ddev;
> + struct drm_device *ddev = &sdev->ddev;
>
> drm_dev_unregister(ddev);
> drm_kms_helper_poll_fini(ddev);
> - drm_dev_put(ddev);
> -
> return 0;
> }
>
> @@ -188,13 +186,15 @@ static int shmob_drm_probe(struct platform_device *pdev)
> }
>
> /*
> - * Allocate and initialize the driver private data, I/O resources and
> - * clocks.
> + * Allocate and initialize the DRM device, driver private data, I/O
> + * resources and clocks.
> */
> - sdev = devm_kzalloc(&pdev->dev, sizeof(*sdev), GFP_KERNEL);
> - if (sdev == NULL)
> - return -ENOMEM;
> + sdev = devm_drm_dev_alloc(&pdev->dev, &shmob_drm_driver,
> + struct shmob_drm_device, ddev);
> + if (IS_ERR(sdev))
> + return PTR_ERR(sdev);
>
> + ddev = &sdev->ddev;
> sdev->dev = &pdev->dev;
> sdev->pdata = pdata;
> spin_lock_init(&sdev->irq_lock);
> @@ -217,20 +217,12 @@ static int shmob_drm_probe(struct platform_device *pdev)
> if (ret < 0)
> return ret;
>
> - /* Allocate and initialize the DRM device. */
> - ddev = drm_dev_alloc(&shmob_drm_driver, &pdev->dev);
> - if (IS_ERR(ddev))
> - return PTR_ERR(ddev);
> -
> - sdev->ddev = ddev;
> ddev->dev_private = sdev;
>
> ret = shmob_drm_modeset_init(sdev);
> - if (ret < 0) {
> - dev_err_probe(&pdev->dev, ret,
> - "failed to initialize mode setting\n");
> - goto err_free_drm_dev;
> - }
> + if (ret < 0)
> + return dev_err_probe(&pdev->dev, ret,
> + "failed to initialize mode setting\n");
>
> for (i = 0; i < 4; ++i) {
> ret = shmob_drm_plane_create(sdev, i);
> @@ -272,9 +264,6 @@ static int shmob_drm_probe(struct platform_device *pdev)
>
> err_modeset_cleanup:
> drm_kms_helper_poll_fini(ddev);
> -err_free_drm_dev:
> - drm_dev_put(ddev);
> -
> return ret;
> }
>
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.h b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.h
> index 16d830168b2ada21..77bb0da48f37ace8 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.h
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.h
> @@ -32,7 +32,7 @@ struct shmob_drm_device {
> unsigned int irq;
> spinlock_t irq_lock; /* Protects hardware LDINTR register */
>
> - struct drm_device *ddev;
> + struct drm_device ddev;
>
> struct shmob_drm_crtc crtc;
> struct drm_encoder encoder;
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c
> index 1a62e7f8a8a9e6df..20316907030b2789 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c
> @@ -153,7 +153,7 @@ int shmob_drm_modeset_init(struct shmob_drm_device *sdev)
> {
> int ret;
>
> - ret = drmm_mode_config_init(sdev->ddev);
> + ret = drmm_mode_config_init(&sdev->ddev);
> if (ret)
> return ret;
>
> @@ -169,15 +169,15 @@ int shmob_drm_modeset_init(struct shmob_drm_device *sdev)
> if (ret < 0)
> return ret;
>
> - drm_kms_helper_poll_init(sdev->ddev);
> + drm_kms_helper_poll_init(&sdev->ddev);
>
> - sdev->ddev->mode_config.min_width = 0;
> - sdev->ddev->mode_config.min_height = 0;
> - sdev->ddev->mode_config.max_width = 4095;
> - sdev->ddev->mode_config.max_height = 4095;
> - sdev->ddev->mode_config.funcs = &shmob_drm_mode_config_funcs;
> + sdev->ddev.mode_config.min_width = 0;
> + sdev->ddev.mode_config.min_height = 0;
> + sdev->ddev.mode_config.max_width = 4095;
> + sdev->ddev.mode_config.max_height = 4095;
> + sdev->ddev.mode_config.funcs = &shmob_drm_mode_config_funcs;
>
> - drm_helper_disable_unused_functions(sdev->ddev);
> + drm_helper_disable_unused_functions(&sdev->ddev);
>
> return 0;
> }
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
> index 1fb68b5fe915b8dc..17e66a018689f648 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
> @@ -68,7 +68,7 @@ static void __shmob_drm_plane_setup(struct shmob_drm_plane *splane,
> splane->format->ldbbsifr;
>
> #define plane_reg_dump(sdev, splane, reg) \
> - dev_dbg(sdev->ddev->dev, "%s(%u): %s 0x%08x 0x%08x\n", __func__, \
> + dev_dbg(sdev->ddev.dev, "%s(%u): %s 0x%08x 0x%08x\n", __func__, \
> splane->index, #reg, \
> lcdc_read(sdev, reg(splane->index)), \
> lcdc_read(sdev, reg(splane->index) + LCDC_SIDE_B_OFFSET))
> @@ -81,7 +81,7 @@ static void __shmob_drm_plane_setup(struct shmob_drm_plane *splane,
> plane_reg_dump(sdev, splane, LDBnBSACR);
>
> lcdc_write(sdev, LDBCR, LDBCR_UPC(splane->index));
> - dev_dbg(sdev->ddev->dev, "%s(%u): %s 0x%08x\n", __func__, splane->index,
> + dev_dbg(sdev->ddev.dev, "%s(%u): %s 0x%08x\n", __func__, splane->index,
> "LDBCR", lcdc_read(sdev, LDBCR));
>
> lcdc_write(sdev, LDBnBSIFR(splane->index), format);
> @@ -103,7 +103,7 @@ static void __shmob_drm_plane_setup(struct shmob_drm_plane *splane,
>
> lcdc_write(sdev, LDBCR,
> LDBCR_UPF(splane->index) | LDBCR_UPD(splane->index));
> - dev_dbg(sdev->ddev->dev, "%s(%u): %s 0x%08x\n", __func__, splane->index,
> + dev_dbg(sdev->ddev.dev, "%s(%u): %s 0x%08x\n", __func__, splane->index,
> "LDBCR", lcdc_read(sdev, LDBCR));
>
> plane_reg_dump(sdev, splane, LDBnBSIFR);
> @@ -198,7 +198,7 @@ int shmob_drm_plane_create(struct shmob_drm_device *sdev, unsigned int index)
> {
> struct shmob_drm_plane *splane;
>
> - splane = drmm_universal_plane_alloc(sdev->ddev, struct shmob_drm_plane,
> + splane = drmm_universal_plane_alloc(&sdev->ddev, struct shmob_drm_plane,
> plane, 1, &shmob_drm_plane_funcs,
> formats, ARRAY_SIZE(formats), NULL,
> DRM_PLANE_TYPE_OVERLAY, NULL);

--
Regards,

Laurent Pinchart

2023-06-23 16:39:45

by Laurent Pinchart

[permalink] [raw]
Subject: Re: [PATCH 17/39] drm: renesas: shmobile: Use drmm_universal_plane_alloc()

Hi Geert,

Thank you for the patch.

On Thu, Jun 22, 2023 at 11:21:29AM +0200, Geert Uytterhoeven wrote:
> According to the comments for drm_universal_plane_init(), the plane
> structure should not be allocated with devm_kzalloc().
>
> Fix lifetime issues by using drmm_universal_plane_alloc() instead.
>
> Signed-off-by: Geert Uytterhoeven <[email protected]>
> ---
> Plane (and connector) structures are still allocated with devm_kzalloc()
> in several other drivers...
> ---
> .../drm/renesas/shmobile/shmob_drm_plane.c | 24 ++++++-------------
> 1 file changed, 7 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
> index 0b2ab153e9ae76df..1fb68b5fe915b8dc 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
> @@ -176,16 +176,9 @@ static int shmob_drm_plane_disable(struct drm_plane *plane,
> return 0;
> }
>
> -static void shmob_drm_plane_destroy(struct drm_plane *plane)
> -{
> - drm_plane_force_disable(plane);
> - drm_plane_cleanup(plane);

drm_plane_cleanup() will still be called from
drmm_universal_plane_alloc_release(), but drm_plane_force_disable()
won't. Is this an issue ? This should be documented in the commit
message.

> -}
> -
> static const struct drm_plane_funcs shmob_drm_plane_funcs = {
> .update_plane = shmob_drm_plane_update,
> .disable_plane = shmob_drm_plane_disable,
> - .destroy = shmob_drm_plane_destroy,
> };
>
> static const uint32_t formats[] = {
> @@ -204,19 +197,16 @@ static const uint32_t formats[] = {
> int shmob_drm_plane_create(struct shmob_drm_device *sdev, unsigned int index)
> {
> struct shmob_drm_plane *splane;
> - int ret;
>
> - splane = devm_kzalloc(sdev->dev, sizeof(*splane), GFP_KERNEL);
> - if (splane == NULL)
> - return -ENOMEM;
> + splane = drmm_universal_plane_alloc(sdev->ddev, struct shmob_drm_plane,
> + plane, 1, &shmob_drm_plane_funcs,
> + formats, ARRAY_SIZE(formats), NULL,
> + DRM_PLANE_TYPE_OVERLAY, NULL);
> + if (IS_ERR(splane))
> + return PTR_ERR(splane);
>
> splane->index = index;
> splane->alpha = 255;
>
> - ret = drm_universal_plane_init(sdev->ddev, &splane->plane, 1,
> - &shmob_drm_plane_funcs,
> - formats, ARRAY_SIZE(formats), NULL,
> - DRM_PLANE_TYPE_OVERLAY, NULL);
> -
> - return ret;
> + return 0;
> }

--
Regards,

Laurent Pinchart

2023-06-23 16:41:08

by Laurent Pinchart

[permalink] [raw]
Subject: Re: [PATCH 21/39] drm: renesas: shmobile: Use struct videomode in platform data

Hi Geert,

Thank you for the patch.

On Thu, Jun 22, 2023 at 11:21:33AM +0200, Geert Uytterhoeven wrote:
> From: Laurent Pinchart <[email protected]>
>
> Replace the drm_mode_modeinfo field with videomode that includes more
> signal polarity flags. This simplifies driver handling of panel modes
> and prepares for DT support.
>
> Signed-off-by: Laurent Pinchart <[email protected]>
> [geert: Simplify]
> Signed-off-by: Geert Uytterhoeven <[email protected]>

Reviewed-by: Laurent Pinchart <[email protected]>

> ---
> Changes compared to Laurent's original:
> - Rebase,
> - Fix build,
> - Remove unneeded {width,height}_mm intermediaries from
> shmob_drm_connector,
> - Replace embedded videomode by a const pointer to pdata.
> ---
> .../gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 35 ++++++++-----------
> .../gpu/drm/renesas/shmobile/shmob_drm_crtc.h | 3 ++
> include/linux/platform_data/shmob_drm.h | 11 ++----
> 3 files changed, 19 insertions(+), 30 deletions(-)
>
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> index 291b3a5014c24f08..5328910ebe09c832 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> @@ -23,6 +23,8 @@
> #include <drm/drm_simple_kms_helper.h>
> #include <drm/drm_vblank.h>
>
> +#include <video/videomode.h>
> +
> #include "shmob_drm_crtc.h"
> #include "shmob_drm_drv.h"
> #include "shmob_drm_kms.h"
> @@ -64,18 +66,16 @@ static void shmob_drm_crtc_setup_geometry(struct shmob_drm_crtc *scrtc)
> {
> struct drm_crtc *crtc = &scrtc->crtc;
> struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);
> - const struct shmob_drm_interface_data *idata = &sdev->pdata->iface;
> + enum display_flags dpy_flags = sdev->connector.mode->flags;
> const struct drm_display_mode *mode = &crtc->mode;
> u32 value;
>
> value = sdev->ldmt1r
> | ((mode->flags & DRM_MODE_FLAG_PVSYNC) ? 0 : LDMT1R_VPOL)
> | ((mode->flags & DRM_MODE_FLAG_PHSYNC) ? 0 : LDMT1R_HPOL)
> - | ((idata->flags & SHMOB_DRM_IFACE_FL_DWPOL) ? LDMT1R_DWPOL : 0)
> - | ((idata->flags & SHMOB_DRM_IFACE_FL_DIPOL) ? LDMT1R_DIPOL : 0)
> - | ((idata->flags & SHMOB_DRM_IFACE_FL_DAPOL) ? LDMT1R_DAPOL : 0)
> - | ((idata->flags & SHMOB_DRM_IFACE_FL_HSCNT) ? LDMT1R_HSCNT : 0)
> - | ((idata->flags & SHMOB_DRM_IFACE_FL_DWCNT) ? LDMT1R_DWCNT : 0);
> + | ((dpy_flags & DISPLAY_FLAGS_PIXDATA_POSEDGE) ? LDMT1R_DWPOL : 0)
> + | ((dpy_flags & DISPLAY_FLAGS_DE_LOW) ? LDMT1R_DIPOL : 0);
> +
> lcdc_write(sdev, LDMT1R, value);
>
> value = ((mode->hdisplay / 8) << 16) /* HDCN */
> @@ -581,7 +581,7 @@ static inline struct shmob_drm_connector *to_shmob_connector(struct drm_connecto
>
> static int shmob_drm_connector_get_modes(struct drm_connector *connector)
> {
> - struct shmob_drm_device *sdev = to_shmob_device(connector->dev);
> + struct shmob_drm_connector *scon = to_shmob_connector(connector);
> struct drm_display_mode *mode;
>
> mode = drm_mode_create(connector->dev);
> @@ -589,18 +589,9 @@ static int shmob_drm_connector_get_modes(struct drm_connector *connector)
> return 0;
>
> mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER;
> - mode->clock = sdev->pdata->panel.mode.clock;
> - mode->hdisplay = sdev->pdata->panel.mode.hdisplay;
> - mode->hsync_start = sdev->pdata->panel.mode.hsync_start;
> - mode->hsync_end = sdev->pdata->panel.mode.hsync_end;
> - mode->htotal = sdev->pdata->panel.mode.htotal;
> - mode->vdisplay = sdev->pdata->panel.mode.vdisplay;
> - mode->vsync_start = sdev->pdata->panel.mode.vsync_start;
> - mode->vsync_end = sdev->pdata->panel.mode.vsync_end;
> - mode->vtotal = sdev->pdata->panel.mode.vtotal;
> - mode->flags = sdev->pdata->panel.mode.flags;
> -
> - drm_mode_set_name(mode);
> +
> + drm_display_mode_from_videomode(scon->mode, mode);
> +
> drm_mode_probed_add(connector, mode);
>
> return 1;
> @@ -634,10 +625,12 @@ static const struct drm_connector_funcs connector_funcs = {
> int shmob_drm_connector_create(struct shmob_drm_device *sdev,
> struct drm_encoder *encoder)
> {
> - struct drm_connector *connector = &sdev->connector.connector;
> + struct shmob_drm_connector *scon = &sdev->connector;
> + struct drm_connector *connector = &scon->connector;
> int ret;
>
> - sdev->connector.encoder = encoder;
> + scon->encoder = encoder;
> + scon->mode = &sdev->pdata->panel.mode;
>
> connector->display_info.width_mm = sdev->pdata->panel.width_mm;
> connector->display_info.height_mm = sdev->pdata->panel.height_mm;
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
> index bce6926269453b77..f507eaf912e16a22 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
> @@ -14,6 +14,8 @@
> #include <drm/drm_connector.h>
> #include <drm/drm_encoder.h>
>
> +#include <video/videomode.h>
> +
> struct drm_pending_vblank_event;
> struct shmob_drm_device;
> struct shmob_drm_format_info;
> @@ -33,6 +35,7 @@ struct shmob_drm_crtc {
> struct shmob_drm_connector {
> struct drm_connector connector;
> struct drm_encoder *encoder;
> + const struct videomode *mode;
> };
>
> int shmob_drm_crtc_create(struct shmob_drm_device *sdev);
> diff --git a/include/linux/platform_data/shmob_drm.h b/include/linux/platform_data/shmob_drm.h
> index b728e24222d99158..f3cb19ff9f818aca 100644
> --- a/include/linux/platform_data/shmob_drm.h
> +++ b/include/linux/platform_data/shmob_drm.h
> @@ -10,7 +10,7 @@
> #ifndef __SHMOB_DRM_H__
> #define __SHMOB_DRM_H__
>
> -#include <drm/drm_mode.h>
> +#include <video/videomode.h>
>
> enum shmob_drm_clk_source {
> SHMOB_DRM_CLK_BUS,
> @@ -32,19 +32,12 @@ enum shmob_drm_interface {
> struct shmob_drm_panel_data {
> unsigned int width_mm; /* Panel width in mm */
> unsigned int height_mm; /* Panel height in mm */
> - struct drm_mode_modeinfo mode;
> + struct videomode mode;
> };
>
> -#define SHMOB_DRM_IFACE_FL_DWPOL (1 << 0) /* Rising edge dot clock data latch */
> -#define SHMOB_DRM_IFACE_FL_DIPOL (1 << 1) /* Active low display enable */
> -#define SHMOB_DRM_IFACE_FL_DAPOL (1 << 2) /* Active low display data */
> -#define SHMOB_DRM_IFACE_FL_HSCNT (1 << 3) /* Disable HSYNC during VBLANK */
> -#define SHMOB_DRM_IFACE_FL_DWCNT (1 << 4) /* Disable dotclock during blanking */
> -
> struct shmob_drm_interface_data {
> enum shmob_drm_interface interface;
> unsigned int clk_div;
> - unsigned int flags;
> };
>
> struct shmob_drm_platform_data {

--
Regards,

Laurent Pinchart

2023-06-23 16:42:34

by Laurent Pinchart

[permalink] [raw]
Subject: Re: [PATCH 22/39] drm: renesas: shmobile: Use media bus formats in platform data

Hi Geert,

Thank you for the patch.


On Thu, Jun 22, 2023 at 11:21:34AM +0200, Geert Uytterhoeven wrote:
> Replace the custom shmob_drm_interface enumeration values with standard
> media bus formats. This simplifies driver handling of bus formats and
> prepares for DT support.
>
> Signed-off-by: Geert Uytterhoeven <[email protected]>

Reviewed-by: Laurent Pinchart <[email protected]>

> ---
> .../gpu/drm/renesas/shmobile/shmob_drm_drv.c | 52 +++++++++++++------
> include/linux/platform_data/shmob_drm.h | 13 +----
> 2 files changed, 38 insertions(+), 27 deletions(-)
>
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> index 1a1d66c6e817e227..e5be0ae99bd970be 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> @@ -9,6 +9,7 @@
>
> #include <linux/clk.h>
> #include <linux/io.h>
> +#include <linux/media-bus-format.h>
> #include <linux/mm.h>
> #include <linux/module.h>
> #include <linux/platform_device.h>
> @@ -34,24 +35,45 @@
>
> static int shmob_drm_init_interface(struct shmob_drm_device *sdev)
> {
> - static const u32 ldmt1r[] = {
> - [SHMOB_DRM_IFACE_RGB8] = LDMT1R_MIFTYP_RGB8,
> - [SHMOB_DRM_IFACE_RGB9] = LDMT1R_MIFTYP_RGB9,
> - [SHMOB_DRM_IFACE_RGB12A] = LDMT1R_MIFTYP_RGB12A,
> - [SHMOB_DRM_IFACE_RGB12B] = LDMT1R_MIFTYP_RGB12B,
> - [SHMOB_DRM_IFACE_RGB16] = LDMT1R_MIFTYP_RGB16,
> - [SHMOB_DRM_IFACE_RGB18] = LDMT1R_MIFTYP_RGB18,
> - [SHMOB_DRM_IFACE_RGB24] = LDMT1R_MIFTYP_RGB24,
> - [SHMOB_DRM_IFACE_YUV422] = LDMT1R_MIFTYP_YCBCR,
> - };
> -
> - if (sdev->pdata->iface.interface >= ARRAY_SIZE(ldmt1r)) {
> - dev_err(sdev->dev, "invalid interface type %u\n",
> - sdev->pdata->iface.interface);
> + switch (sdev->pdata->iface.bus_fmt) {
> + case MEDIA_BUS_FMT_RGB888_3X8:
> + sdev->ldmt1r = LDMT1R_MIFTYP_RGB8;
> + break;
> +
> + case MEDIA_BUS_FMT_RGB666_2X9_BE:
> + sdev->ldmt1r = LDMT1R_MIFTYP_RGB9;
> + break;
> +
> + case MEDIA_BUS_FMT_RGB888_2X12_BE:
> + sdev->ldmt1r = LDMT1R_MIFTYP_RGB12A;
> + break;
> +
> + case MEDIA_BUS_FMT_RGB444_1X12:
> + sdev->ldmt1r = LDMT1R_MIFTYP_RGB12B;
> + break;
> +
> + case MEDIA_BUS_FMT_RGB565_1X16:
> + sdev->ldmt1r = LDMT1R_MIFTYP_RGB16;
> + break;
> +
> + case MEDIA_BUS_FMT_RGB666_1X18:
> + sdev->ldmt1r = LDMT1R_MIFTYP_RGB18;
> + break;
> +
> + case MEDIA_BUS_FMT_RGB888_1X24:
> + sdev->ldmt1r = LDMT1R_MIFTYP_RGB24;
> + break;
> +
> + case MEDIA_BUS_FMT_UYVY8_1X16:
> + sdev->ldmt1r = LDMT1R_MIFTYP_YCBCR;
> + break;
> +
> + default:
> + dev_err(sdev->dev, "invalid bus format 0x%x\n",
> + sdev->pdata->iface.bus_fmt);
> return -EINVAL;
> }
>
> - sdev->ldmt1r = ldmt1r[sdev->pdata->iface.interface];
> return 0;
> }
>
> diff --git a/include/linux/platform_data/shmob_drm.h b/include/linux/platform_data/shmob_drm.h
> index f3cb19ff9f818aca..5047e66f0a6823ba 100644
> --- a/include/linux/platform_data/shmob_drm.h
> +++ b/include/linux/platform_data/shmob_drm.h
> @@ -18,17 +18,6 @@ enum shmob_drm_clk_source {
> SHMOB_DRM_CLK_EXTERNAL,
> };
>
> -enum shmob_drm_interface {
> - SHMOB_DRM_IFACE_RGB8, /* 24bpp, 8:8:8 */
> - SHMOB_DRM_IFACE_RGB9, /* 18bpp, 9:9 */
> - SHMOB_DRM_IFACE_RGB12A, /* 24bpp, 12:12 */
> - SHMOB_DRM_IFACE_RGB12B, /* 12bpp */
> - SHMOB_DRM_IFACE_RGB16, /* 16bpp */
> - SHMOB_DRM_IFACE_RGB18, /* 18bpp */
> - SHMOB_DRM_IFACE_RGB24, /* 24bpp */
> - SHMOB_DRM_IFACE_YUV422, /* 16bpp */
> -};
> -
> struct shmob_drm_panel_data {
> unsigned int width_mm; /* Panel width in mm */
> unsigned int height_mm; /* Panel height in mm */
> @@ -36,7 +25,7 @@ struct shmob_drm_panel_data {
> };
>
> struct shmob_drm_interface_data {
> - enum shmob_drm_interface interface;
> + unsigned int bus_fmt; /* MEDIA_BUS_FMT_RGB888_* */
> unsigned int clk_div;
> };
>

--
Regards,

Laurent Pinchart

2023-06-23 16:53:20

by Laurent Pinchart

[permalink] [raw]
Subject: Re: [PATCH 23/39] drm: renesas: shmobile: Move interface handling to connector setup

Hi Geert,

Thank you for the patch.

On Thu, Jun 22, 2023 at 11:21:35AM +0200, Geert Uytterhoeven wrote:
> Move legacy interface handling to the connector setup code.
> Set up bus_flags and bus_formats in display_info according to the
> bus format and panel information from platform data, to make it more
> similar with DT-based connector/bridge/panel setup.
> This will allows us to use the same LCD interface setup code for both

s/allows/allow/

> legacy and DT-based systems.
>
> Signed-off-by: Geert Uytterhoeven <[email protected]>
> ---
> .../gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 123 +++++++++++++++---
> .../gpu/drm/renesas/shmobile/shmob_drm_drv.c | 49 -------
> .../gpu/drm/renesas/shmobile/shmob_drm_drv.h | 3 +-
> 3 files changed, 109 insertions(+), 66 deletions(-)
>
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> index 5328910ebe09c832..28a70536693f7788 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> @@ -8,6 +8,7 @@
> */
>
> #include <linux/clk.h>
> +#include <linux/media-bus-format.h>
> #include <linux/pm_runtime.h>
>
> #include <drm/drm_crtc.h>
> @@ -66,15 +67,65 @@ static void shmob_drm_crtc_setup_geometry(struct shmob_drm_crtc *scrtc)
> {
> struct drm_crtc *crtc = &scrtc->crtc;
> struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);
> - enum display_flags dpy_flags = sdev->connector.mode->flags;
> + const struct drm_display_info *info = &sdev->connector->display_info;
> const struct drm_display_mode *mode = &crtc->mode;
> u32 value;
>
> - value = sdev->ldmt1r
> - | ((mode->flags & DRM_MODE_FLAG_PVSYNC) ? 0 : LDMT1R_VPOL)
> - | ((mode->flags & DRM_MODE_FLAG_PHSYNC) ? 0 : LDMT1R_HPOL)
> - | ((dpy_flags & DISPLAY_FLAGS_PIXDATA_POSEDGE) ? LDMT1R_DWPOL : 0)
> - | ((dpy_flags & DISPLAY_FLAGS_DE_LOW) ? LDMT1R_DIPOL : 0);
> + if (!info->num_bus_formats || !info->bus_formats) {
> + dev_warn(sdev->dev, "No bus format reported, using RGB888\n");
> + value = LDMT1R_MIFTYP_RGB24;
> + } else {
> + switch (info->bus_formats[0]) {
> + case MEDIA_BUS_FMT_RGB888_3X8:
> + value = LDMT1R_MIFTYP_RGB8;
> + break;
> +
> + case MEDIA_BUS_FMT_RGB666_2X9_BE:
> + value = LDMT1R_MIFTYP_RGB9;
> + break;
> +
> + case MEDIA_BUS_FMT_RGB888_2X12_BE:
> + value = LDMT1R_MIFTYP_RGB12A;
> + break;
> +
> + case MEDIA_BUS_FMT_RGB444_1X12:
> + value = LDMT1R_MIFTYP_RGB12B;
> + break;
> +
> + case MEDIA_BUS_FMT_RGB565_1X16:
> + value = LDMT1R_MIFTYP_RGB16;
> + break;
> +
> + case MEDIA_BUS_FMT_RGB666_1X18:
> + value = LDMT1R_MIFTYP_RGB18;
> + break;
> +
> + case MEDIA_BUS_FMT_RGB888_1X24:
> + value = LDMT1R_MIFTYP_RGB24;
> + break;
> +
> + case MEDIA_BUS_FMT_UYVY8_1X16:
> + value = LDMT1R_MIFTYP_YCBCR;
> + break;
> +
> + default:
> + dev_warn(sdev->dev,
> + "unsupported bus format 0x%x, using RGB888\n",
> + info->bus_formats[0]);
> + value = LDMT1R_MIFTYP_RGB24;
> + break;
> + }

It's a bit annoying to lose the ability to validate the bus format at
probe time. Can it be kept. I'm also OK with restoring it later in the
series if it gets in the way of the conversion, in which case a mention
in the commit message would be nice.

> + }
> +
> + if (info->bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE)
> + value |= LDMT1R_DWPOL;
> + if (info->bus_flags & DRM_BUS_FLAG_DE_LOW)
> + value |= LDMT1R_DIPOL;
> +
> + if (mode->flags & DRM_MODE_FLAG_NVSYNC)
> + value |= LDMT1R_VPOL;
> + if (mode->flags & DRM_MODE_FLAG_NHSYNC)
> + value |= LDMT1R_HPOL;
>
> lcdc_write(sdev, LDMT1R, value);
>
> @@ -512,7 +563,7 @@ static bool shmob_drm_encoder_mode_fixup(struct drm_encoder *encoder,
> {
> struct drm_device *dev = encoder->dev;
> struct shmob_drm_device *sdev = to_shmob_device(dev);
> - struct drm_connector *connector = &sdev->connector.connector;
> + struct drm_connector *connector = sdev->connector;
> const struct drm_display_mode *panel_mode;
>
> if (list_empty(&connector->modes)) {
> @@ -614,6 +665,8 @@ static void shmob_drm_connector_destroy(struct drm_connector *connector)
> {
> drm_connector_unregister(connector);
> drm_connector_cleanup(connector);
> +
> + kfree(connector);
> }
>
> static const struct drm_connector_funcs connector_funcs = {
> @@ -622,26 +675,64 @@ static const struct drm_connector_funcs connector_funcs = {
> .destroy = shmob_drm_connector_destroy,
> };
>
> -int shmob_drm_connector_create(struct shmob_drm_device *sdev,
> - struct drm_encoder *encoder)
> +static struct drm_connector *
> +shmob_drm_connector_init(struct shmob_drm_device *sdev,
> + struct drm_encoder *encoder)
> {
> - struct shmob_drm_connector *scon = &sdev->connector;
> - struct drm_connector *connector = &scon->connector;
> + struct shmob_drm_connector *scon;
> + struct drm_connector *connector;
> + struct drm_display_info *info;
> int ret;
>
> + scon = kzalloc(sizeof(*scon), GFP_KERNEL);
> + if (!scon)
> + return ERR_PTR(-ENOMEM);
> +
> + connector = &scon->connector;
> + info = &connector->display_info;
> + info->width_mm = sdev->pdata->panel.width_mm;
> + info->height_mm = sdev->pdata->panel.height_mm;
> +
> scon->encoder = encoder;
> scon->mode = &sdev->pdata->panel.mode;
>
> - connector->display_info.width_mm = sdev->pdata->panel.width_mm;
> - connector->display_info.height_mm = sdev->pdata->panel.height_mm;
> + if (scon->mode->flags & DISPLAY_FLAGS_PIXDATA_POSEDGE)
> + info->bus_flags |= DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE;
> + if (scon->mode->flags & DISPLAY_FLAGS_DE_LOW)
> + info->bus_flags |= DRM_BUS_FLAG_DE_LOW;

Could you please keep the initialization of the info fields grouped
together ? You can move the initialization of scon->encoder and
scon->mode just after connector.

> +
> + ret = drm_display_info_set_bus_formats(info,
> + &sdev->pdata->iface.bus_fmt, 1);
> + if (ret < 0) {
> + kfree(scon);
> + return ERR_PTR(ret);
> + }
>
> ret = drm_connector_init(&sdev->ddev, connector, &connector_funcs,
> DRM_MODE_CONNECTOR_DPI);
> - if (ret < 0)
> - return ret;
> + if (ret < 0) {
> + kfree(scon);
> + return ERR_PTR(ret);
> + }
>
> drm_connector_helper_add(connector, &connector_helper_funcs);
>
> + return connector;
> +}
> +
> +int shmob_drm_connector_create(struct shmob_drm_device *sdev,
> + struct drm_encoder *encoder)
> +{
> + struct drm_connector *connector;
> + int ret;
> +
> + connector = shmob_drm_connector_init(sdev, encoder);
> + if (IS_ERR(connector)) {
> + dev_err(sdev->dev, "failed to created connector: %pe\n",
> + connector);
> + return PTR_ERR(connector);
> + }
> +
> ret = drm_connector_attach_encoder(connector, encoder);
> if (ret < 0)
> goto error;
> @@ -650,6 +741,8 @@ int shmob_drm_connector_create(struct shmob_drm_device *sdev,
> drm_object_property_set_value(&connector->base,
> sdev->ddev.mode_config.dpms_property, DRM_MODE_DPMS_OFF);
>
> + sdev->connector = connector;
> +
> return 0;
>
> error:
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> index e5be0ae99bd970be..c15ebbe74cac501f 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> @@ -9,7 +9,6 @@
>
> #include <linux/clk.h>
> #include <linux/io.h>
> -#include <linux/media-bus-format.h>
> #include <linux/mm.h>
> #include <linux/module.h>
> #include <linux/platform_device.h>
> @@ -33,50 +32,6 @@
> * Hardware initialization
> */
>
> -static int shmob_drm_init_interface(struct shmob_drm_device *sdev)
> -{
> - switch (sdev->pdata->iface.bus_fmt) {
> - case MEDIA_BUS_FMT_RGB888_3X8:
> - sdev->ldmt1r = LDMT1R_MIFTYP_RGB8;
> - break;
> -
> - case MEDIA_BUS_FMT_RGB666_2X9_BE:
> - sdev->ldmt1r = LDMT1R_MIFTYP_RGB9;
> - break;
> -
> - case MEDIA_BUS_FMT_RGB888_2X12_BE:
> - sdev->ldmt1r = LDMT1R_MIFTYP_RGB12A;
> - break;
> -
> - case MEDIA_BUS_FMT_RGB444_1X12:
> - sdev->ldmt1r = LDMT1R_MIFTYP_RGB12B;
> - break;
> -
> - case MEDIA_BUS_FMT_RGB565_1X16:
> - sdev->ldmt1r = LDMT1R_MIFTYP_RGB16;
> - break;
> -
> - case MEDIA_BUS_FMT_RGB666_1X18:
> - sdev->ldmt1r = LDMT1R_MIFTYP_RGB18;
> - break;
> -
> - case MEDIA_BUS_FMT_RGB888_1X24:
> - sdev->ldmt1r = LDMT1R_MIFTYP_RGB24;
> - break;
> -
> - case MEDIA_BUS_FMT_UYVY8_1X16:
> - sdev->ldmt1r = LDMT1R_MIFTYP_YCBCR;
> - break;
> -
> - default:
> - dev_err(sdev->dev, "invalid bus format 0x%x\n",
> - sdev->pdata->iface.bus_fmt);
> - return -EINVAL;
> - }
> -
> - return 0;
> -}
> -
> static int shmob_drm_setup_clocks(struct shmob_drm_device *sdev,
> enum shmob_drm_clk_source clksrc)
> {
> @@ -235,10 +190,6 @@ static int shmob_drm_probe(struct platform_device *pdev)
> if (ret < 0)
> return ret;
>
> - ret = shmob_drm_init_interface(sdev);
> - if (ret < 0)
> - return ret;
> -
> ret = shmob_drm_modeset_init(sdev);
> if (ret < 0)
> return dev_err_probe(&pdev->dev, ret,
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.h b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.h
> index 5e55ba7a207865bd..18907e5ace51c681 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.h
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.h
> @@ -27,7 +27,6 @@ struct shmob_drm_device {
> void __iomem *mmio;
> struct clk *clock;
> u32 lddckr;
> - u32 ldmt1r;
>
> unsigned int irq;
> spinlock_t irq_lock; /* Protects hardware LDINTR register */
> @@ -36,7 +35,7 @@ struct shmob_drm_device {
>
> struct shmob_drm_crtc crtc;
> struct drm_encoder encoder;
> - struct shmob_drm_connector connector;
> + struct drm_connector *connector;
> };
>
> static inline struct shmob_drm_device *to_shmob_device(struct drm_device *dev)

--
Regards,

Laurent Pinchart

2023-06-23 17:01:57

by Laurent Pinchart

[permalink] [raw]
Subject: Re: [PATCH 24/39] drm: renesas: shmobile: Unify plane allocation

Hi Geert,

Thank you for the patch.

On Thu, Jun 22, 2023 at 11:21:36AM +0200, Geert Uytterhoeven wrote:
> Unify primary and overlay plane allocation:
> - Enhance shmob_drm_plane_create() so it can be used to create the
> primary plane, too,
> - Move overlay plane creation next to primary plane creation.
>
> As overlay plane index zero now means the primary plane, this requires
> shifting all overlay plane indices by one.

Do you use index zero to identify the primary plane just for
shmob_drm_plane_create(), or somewhere else too ? If it's just to create
the plane, you could instead pass the plane type to the function.

> Signed-off-by: Geert Uytterhoeven <[email protected]>
> ---
> Perhaps it would be better to not use dynamic allocation, but store
> "struct drm_plane primary" and "struct shmob_drm_plane planes[5]" in
> struct drm_shmob_device instead, like is done for the crtc and encoder?
> ---
> .../gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 39 ++------
> .../gpu/drm/renesas/shmobile/shmob_drm_drv.c | 9 --
> .../drm/renesas/shmobile/shmob_drm_plane.c | 96 +++++++++++--------
> .../drm/renesas/shmobile/shmob_drm_plane.h | 3 +-
> 4 files changed, 70 insertions(+), 77 deletions(-)
>
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> index 28a70536693f7788..3f6af12f45988124 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> @@ -19,7 +19,6 @@
> #include <drm/drm_gem_dma_helper.h>
> #include <drm/drm_modeset_helper.h>
> #include <drm/drm_modeset_helper_vtables.h>
> -#include <drm/drm_plane_helper.h>
> #include <drm/drm_probe_helper.h>
> #include <drm/drm_simple_kms_helper.h>
> #include <drm/drm_vblank.h>
> @@ -501,47 +500,29 @@ static const struct drm_crtc_funcs crtc_funcs = {
> .disable_vblank = shmob_drm_disable_vblank,
> };
>
> -static const uint32_t modeset_formats[] = {
> - DRM_FORMAT_RGB565,
> - DRM_FORMAT_RGB888,
> - DRM_FORMAT_ARGB8888,
> - DRM_FORMAT_XRGB8888,
> - DRM_FORMAT_NV12,
> - DRM_FORMAT_NV21,
> - DRM_FORMAT_NV16,
> - DRM_FORMAT_NV61,
> - DRM_FORMAT_NV24,
> - DRM_FORMAT_NV42,
> -};
> -
> -static const struct drm_plane_funcs primary_plane_funcs = {
> - DRM_PLANE_NON_ATOMIC_FUNCS,
> -};
> -
> int shmob_drm_crtc_create(struct shmob_drm_device *sdev)
> {
> struct drm_crtc *crtc = &sdev->crtc.crtc;
> - struct drm_plane *primary;
> + struct drm_plane *primary, *plane;
> + unsigned int i;
> int ret;
>
> sdev->crtc.dpms = DRM_MODE_DPMS_OFF;
>
> - primary = __drm_universal_plane_alloc(&sdev->ddev, sizeof(*primary), 0,
> - 0, &primary_plane_funcs,
> - modeset_formats,
> - ARRAY_SIZE(modeset_formats),
> - NULL, DRM_PLANE_TYPE_PRIMARY,
> - NULL);
> + primary = shmob_drm_plane_create(sdev, 0);
> if (IS_ERR(primary))
> return PTR_ERR(primary);
>
> + for (i = 1; i < 5; ++i) {
> + plane = shmob_drm_plane_create(sdev, i);
> + if (IS_ERR(plane))
> + return PTR_ERR(plane);
> + }
> +
> ret = drm_crtc_init_with_planes(&sdev->ddev, crtc, primary, NULL,
> &crtc_funcs, NULL);
> - if (ret < 0) {
> - drm_plane_cleanup(primary);
> - kfree(primary);
> + if (ret < 0)
> return ret;
> - }
>
> drm_crtc_helper_add(crtc, &crtc_helper_funcs);
>
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> index c15ebbe74cac501f..c98e2bdd888c3274 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> @@ -154,7 +154,6 @@ static int shmob_drm_probe(struct platform_device *pdev)
> struct shmob_drm_platform_data *pdata = pdev->dev.platform_data;
> struct shmob_drm_device *sdev;
> struct drm_device *ddev;
> - unsigned int i;
> int ret;
>
> if (pdata == NULL) {
> @@ -195,14 +194,6 @@ static int shmob_drm_probe(struct platform_device *pdev)
> return dev_err_probe(&pdev->dev, ret,
> "failed to initialize mode setting\n");
>
> - for (i = 0; i < 4; ++i) {
> - ret = shmob_drm_plane_create(sdev, i);
> - if (ret < 0) {
> - dev_err(&pdev->dev, "failed to create plane %u\n", i);
> - goto err_modeset_cleanup;
> - }
> - }
> -
> ret = drm_vblank_init(ddev, 1);
> if (ret < 0) {
> dev_err(&pdev->dev, "failed to initialize vblank\n");
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
> index c58b9dca34736342..63886015baaebfc0 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
> @@ -12,6 +12,7 @@
> #include <drm/drm_fourcc.h>
> #include <drm/drm_framebuffer.h>
> #include <drm/drm_gem_dma_helper.h>
> +#include <drm/drm_plane_helper.h>
>
> #include "shmob_drm_drv.h"
> #include "shmob_drm_kms.h"
> @@ -64,57 +65,58 @@ static void __shmob_drm_plane_setup(struct shmob_drm_plane *splane,
> struct drm_framebuffer *fb)
> {
> struct shmob_drm_device *sdev = to_shmob_device(splane->plane.dev);
> + unsigned int ovl_idx = splane->index - 1;
> u32 format;
>
> /* TODO: Support ROP3 mode */
> format = LDBBSIFR_EN | (splane->alpha << LDBBSIFR_LAY_SHIFT) |
> splane->format->ldbbsifr;
>
> -#define plane_reg_dump(sdev, splane, reg) \
> +#define plane_reg_dump(sdev, ovl_idx, reg) \
> dev_dbg(sdev->ddev.dev, "%s(%u): %s 0x%08x 0x%08x\n", __func__, \
> - splane->index, #reg, \
> - lcdc_read(sdev, reg(splane->index)), \
> - lcdc_read(sdev, reg(splane->index) + LCDC_SIDE_B_OFFSET))
> -
> - plane_reg_dump(sdev, splane, LDBnBSIFR);
> - plane_reg_dump(sdev, splane, LDBnBSSZR);
> - plane_reg_dump(sdev, splane, LDBnBLOCR);
> - plane_reg_dump(sdev, splane, LDBnBSMWR);
> - plane_reg_dump(sdev, splane, LDBnBSAYR);
> - plane_reg_dump(sdev, splane, LDBnBSACR);
> -
> - lcdc_write(sdev, LDBCR, LDBCR_UPC(splane->index));
> - dev_dbg(sdev->ddev.dev, "%s(%u): %s 0x%08x\n", __func__, splane->index,
> + ovl_idx, #reg, \
> + lcdc_read(sdev, reg(ovl_idx)), \
> + lcdc_read(sdev, reg(ovl_idx) + LCDC_SIDE_B_OFFSET))
> +
> + plane_reg_dump(sdev, ovl_idx, LDBnBSIFR);
> + plane_reg_dump(sdev, ovl_idx, LDBnBSSZR);
> + plane_reg_dump(sdev, ovl_idx, LDBnBLOCR);
> + plane_reg_dump(sdev, ovl_idx, LDBnBSMWR);
> + plane_reg_dump(sdev, ovl_idx, LDBnBSAYR);
> + plane_reg_dump(sdev, ovl_idx, LDBnBSACR);
> +
> + lcdc_write(sdev, LDBCR, LDBCR_UPC(ovl_idx));
> + dev_dbg(sdev->ddev.dev, "%s(%u): %s 0x%08x\n", __func__, ovl_idx,
> "LDBCR", lcdc_read(sdev, LDBCR));
>
> - lcdc_write(sdev, LDBnBSIFR(splane->index), format);
> + lcdc_write(sdev, LDBnBSIFR(ovl_idx), format);
>
> - lcdc_write(sdev, LDBnBSSZR(splane->index),
> + lcdc_write(sdev, LDBnBSSZR(ovl_idx),
> (splane->crtc_h << LDBBSSZR_BVSS_SHIFT) |
> (splane->crtc_w << LDBBSSZR_BHSS_SHIFT));
> - lcdc_write(sdev, LDBnBLOCR(splane->index),
> + lcdc_write(sdev, LDBnBLOCR(ovl_idx),
> (splane->crtc_y << LDBBLOCR_CVLC_SHIFT) |
> (splane->crtc_x << LDBBLOCR_CHLC_SHIFT));
> - lcdc_write(sdev, LDBnBSMWR(splane->index),
> + lcdc_write(sdev, LDBnBSMWR(ovl_idx),
> fb->pitches[0] << LDBBSMWR_BSMW_SHIFT);
>
> shmob_drm_plane_compute_base(splane, fb, splane->src_x, splane->src_y);
>
> - lcdc_write(sdev, LDBnBSAYR(splane->index), splane->dma[0]);
> + lcdc_write(sdev, LDBnBSAYR(ovl_idx), splane->dma[0]);
> if (shmob_drm_format_is_yuv(splane->format))
> - lcdc_write(sdev, LDBnBSACR(splane->index), splane->dma[1]);
> + lcdc_write(sdev, LDBnBSACR(ovl_idx), splane->dma[1]);
>
> lcdc_write(sdev, LDBCR,
> - LDBCR_UPF(splane->index) | LDBCR_UPD(splane->index));
> - dev_dbg(sdev->ddev.dev, "%s(%u): %s 0x%08x\n", __func__, splane->index,
> + LDBCR_UPF(ovl_idx) | LDBCR_UPD(ovl_idx));
> + dev_dbg(sdev->ddev.dev, "%s(%u): %s 0x%08x\n", __func__, ovl_idx,
> "LDBCR", lcdc_read(sdev, LDBCR));
>
> - plane_reg_dump(sdev, splane, LDBnBSIFR);
> - plane_reg_dump(sdev, splane, LDBnBSSZR);
> - plane_reg_dump(sdev, splane, LDBnBLOCR);
> - plane_reg_dump(sdev, splane, LDBnBSMWR);
> - plane_reg_dump(sdev, splane, LDBnBSAYR);
> - plane_reg_dump(sdev, splane, LDBnBSACR);
> + plane_reg_dump(sdev, ovl_idx, LDBnBSIFR);
> + plane_reg_dump(sdev, ovl_idx, LDBnBSSZR);
> + plane_reg_dump(sdev, ovl_idx, LDBnBLOCR);
> + plane_reg_dump(sdev, ovl_idx, LDBnBSMWR);
> + plane_reg_dump(sdev, ovl_idx, LDBnBSAYR);
> + plane_reg_dump(sdev, ovl_idx, LDBnBSACR);
> }
>
> void shmob_drm_plane_setup(struct drm_plane *plane)
> @@ -169,16 +171,22 @@ static int shmob_drm_plane_disable(struct drm_plane *plane,
> {
> struct shmob_drm_device *sdev = to_shmob_device(plane->dev);
> struct shmob_drm_plane *splane = to_shmob_plane(plane);
> + unsigned int ovl_idx = splane->index - 1;
>
> splane->format = NULL;
>
> - lcdc_write(sdev, LDBCR, LDBCR_UPC(splane->index));
> - lcdc_write(sdev, LDBnBSIFR(splane->index), 0);
> + lcdc_write(sdev, LDBCR, LDBCR_UPC(ovl_idx));
> + lcdc_write(sdev, LDBnBSIFR(ovl_idx), 0);
> lcdc_write(sdev, LDBCR,
> - LDBCR_UPF(splane->index) | LDBCR_UPD(splane->index));
> + LDBCR_UPF(ovl_idx) | LDBCR_UPD(ovl_idx));
> return 0;
> }
>
> +static const struct drm_plane_funcs primary_plane_funcs = {

While at it, you can name this shmob_primary_plane_funcs to avoid
namespace clashes.

> + .update_plane = drm_plane_helper_update_primary,
> + .disable_plane = drm_plane_helper_disable_primary,
> +};
> +
> static const struct drm_plane_funcs shmob_drm_plane_funcs = {

And shmob_overlay_plane_funcs for consistency.

> .update_plane = shmob_drm_plane_update,
> .disable_plane = shmob_drm_plane_disable,
> @@ -197,19 +205,31 @@ static const uint32_t formats[] = {
> DRM_FORMAT_NV42,
> };
>
> -int shmob_drm_plane_create(struct shmob_drm_device *sdev, unsigned int index)
> +struct drm_plane *shmob_drm_plane_create(struct shmob_drm_device *sdev,
> + unsigned int index)
> {
> + const struct drm_plane_funcs *funcs;
> struct shmob_drm_plane *splane;
> + enum drm_plane_type type;
> +
> + if (!index) {
> + type = DRM_PLANE_TYPE_PRIMARY;
> + funcs = &primary_plane_funcs;
> + } else {
> + type = DRM_PLANE_TYPE_OVERLAY;
> + funcs = &shmob_drm_plane_funcs;
> + }
>
> - splane = drmm_universal_plane_alloc(&sdev->ddev, struct shmob_drm_plane,
> - plane, 1, &shmob_drm_plane_funcs,
> - formats, ARRAY_SIZE(formats), NULL,
> - DRM_PLANE_TYPE_OVERLAY, NULL);
> + splane = drmm_universal_plane_alloc(&sdev->ddev,
> + struct shmob_drm_plane, plane, 1,
> + funcs, formats,
> + ARRAY_SIZE(formats), NULL, type,
> + NULL);
> if (IS_ERR(splane))
> - return PTR_ERR(splane);
> + return ERR_CAST(splane);
>
> splane->index = index;
> splane->alpha = 255;
>
> - return 0;
> + return &splane->plane;
> }
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.h b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.h
> index e72b21a4288fc23f..29cf6732d479a509 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.h
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.h
> @@ -13,7 +13,8 @@
> struct drm_plane;
> struct shmob_drm_device;
>
> -int shmob_drm_plane_create(struct shmob_drm_device *sdev, unsigned int index);
> +struct drm_plane *shmob_drm_plane_create(struct shmob_drm_device *sdev,
> + unsigned int index);
> void shmob_drm_plane_setup(struct drm_plane *plane);
>
> #endif /* __SHMOB_DRM_PLANE_H__ */

--
Regards,

Laurent Pinchart

2023-06-23 17:04:38

by Laurent Pinchart

[permalink] [raw]
Subject: Re: [PATCH 26/39] drm: renesas: shmobile: Rename shmob_drm_connector.connector

Hi Geert,

Thank you for the patch.

On Thu, Jun 22, 2023 at 11:21:38AM +0200, Geert Uytterhoeven wrote:
> Rename the "connector" member of the shmob_drm_connector subclass
> structure to "base", to improve readability.
>
> Signed-off-by: Geert Uytterhoeven <[email protected]>

Reviewed-by: Laurent Pinchart <[email protected]>

> ---
> drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 4 ++--
> drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h | 2 +-
> 2 files changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> index 3f0b71253ed929c9..2c0ca802d36026f4 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> @@ -608,7 +608,7 @@ int shmob_drm_encoder_create(struct shmob_drm_device *sdev)
>
> static inline struct shmob_drm_connector *to_shmob_connector(struct drm_connector *connector)
> {
> - return container_of(connector, struct shmob_drm_connector, connector);
> + return container_of(connector, struct shmob_drm_connector, base);
> }
>
> static int shmob_drm_connector_get_modes(struct drm_connector *connector)
> @@ -669,7 +669,7 @@ shmob_drm_connector_init(struct shmob_drm_device *sdev,
> if (!scon)
> return ERR_PTR(-ENOMEM);
>
> - connector = &scon->connector;
> + connector = &scon->base;
> info = &connector->display_info;
> info->width_mm = sdev->pdata->panel.width_mm;
> info->height_mm = sdev->pdata->panel.height_mm;
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
> index 79cce0a0ada4cfce..2c6d7541427581a6 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
> @@ -33,7 +33,7 @@ struct shmob_drm_crtc {
> };
>
> struct shmob_drm_connector {
> - struct drm_connector connector;
> + struct drm_connector base;
> struct drm_encoder *encoder;
> const struct videomode *mode;
> };

--
Regards,

Laurent Pinchart

2023-06-23 17:17:08

by Laurent Pinchart

[permalink] [raw]
Subject: Re: [PATCH 25/39] drm: renesas: shmobile: Rename shmob_drm_crtc.crtc

Hi Geert,

Thank you for the patch.

On Thu, Jun 22, 2023 at 11:21:37AM +0200, Geert Uytterhoeven wrote:
> Rename the "crtc" member of the shmob_drm_crtc subclass structure to
> "base", to improve readability.

I'm not sure that's more readable to me, but I don't mind :-)

Reviewed-by: Laurent Pinchart <[email protected]>

> Signed-off-by: Geert Uytterhoeven <[email protected]>
> ---
> .../gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 26 +++++++++----------
> .../gpu/drm/renesas/shmobile/shmob_drm_crtc.h | 2 +-
> 2 files changed, 14 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> index 3f6af12f45988124..3f0b71253ed929c9 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> @@ -64,7 +64,7 @@ static void shmob_drm_clk_off(struct shmob_drm_device *sdev)
>
> static void shmob_drm_crtc_setup_geometry(struct shmob_drm_crtc *scrtc)
> {
> - struct drm_crtc *crtc = &scrtc->crtc;
> + struct drm_crtc *crtc = &scrtc->base;
> struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);
> const struct drm_display_info *info = &sdev->connector->display_info;
> const struct drm_display_mode *mode = &crtc->mode;
> @@ -152,7 +152,7 @@ static void shmob_drm_crtc_setup_geometry(struct shmob_drm_crtc *scrtc)
>
> static void shmob_drm_crtc_start_stop(struct shmob_drm_crtc *scrtc, bool start)
> {
> - struct shmob_drm_device *sdev = to_shmob_device(scrtc->crtc.dev);
> + struct shmob_drm_device *sdev = to_shmob_device(scrtc->base.dev);
> u32 value;
>
> value = lcdc_read(sdev, LDCNT2R);
> @@ -185,7 +185,7 @@ static void shmob_drm_crtc_start_stop(struct shmob_drm_crtc *scrtc, bool start)
> */
> static void shmob_drm_crtc_start(struct shmob_drm_crtc *scrtc)
> {
> - struct drm_crtc *crtc = &scrtc->crtc;
> + struct drm_crtc *crtc = &scrtc->base;
> struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);
> const struct shmob_drm_interface_data *idata = &sdev->pdata->iface;
> const struct shmob_drm_format_info *format;
> @@ -272,7 +272,7 @@ static void shmob_drm_crtc_start(struct shmob_drm_crtc *scrtc)
>
> static void shmob_drm_crtc_stop(struct shmob_drm_crtc *scrtc)
> {
> - struct drm_crtc *crtc = &scrtc->crtc;
> + struct drm_crtc *crtc = &scrtc->base;
> struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);
>
> if (!scrtc->started)
> @@ -308,7 +308,7 @@ void shmob_drm_crtc_resume(struct shmob_drm_crtc *scrtc)
> static void shmob_drm_crtc_compute_base(struct shmob_drm_crtc *scrtc,
> int x, int y)
> {
> - struct drm_crtc *crtc = &scrtc->crtc;
> + struct drm_crtc *crtc = &scrtc->base;
> struct drm_framebuffer *fb = crtc->primary->fb;
> struct drm_gem_dma_object *gem;
> unsigned int bpp;
> @@ -329,7 +329,7 @@ static void shmob_drm_crtc_compute_base(struct shmob_drm_crtc *scrtc,
>
> static void shmob_drm_crtc_update_base(struct shmob_drm_crtc *scrtc)
> {
> - struct drm_crtc *crtc = &scrtc->crtc;
> + struct drm_crtc *crtc = &scrtc->base;
> struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);
>
> shmob_drm_crtc_compute_base(scrtc, crtc->x, crtc->y);
> @@ -343,7 +343,7 @@ static void shmob_drm_crtc_update_base(struct shmob_drm_crtc *scrtc)
>
> static inline struct shmob_drm_crtc *to_shmob_crtc(struct drm_crtc *crtc)
> {
> - return container_of(crtc, struct shmob_drm_crtc, crtc);
> + return container_of(crtc, struct shmob_drm_crtc, base);
> }
>
> static void shmob_drm_crtc_dpms(struct drm_crtc *crtc, int mode)
> @@ -415,15 +415,15 @@ static const struct drm_crtc_helper_funcs crtc_helper_funcs = {
> void shmob_drm_crtc_finish_page_flip(struct shmob_drm_crtc *scrtc)
> {
> struct drm_pending_vblank_event *event;
> - struct drm_device *dev = scrtc->crtc.dev;
> + struct drm_device *dev = scrtc->base.dev;
> unsigned long flags;
>
> spin_lock_irqsave(&dev->event_lock, flags);
> event = scrtc->event;
> scrtc->event = NULL;
> if (event) {
> - drm_crtc_send_vblank_event(&scrtc->crtc, event);
> - drm_crtc_vblank_put(&scrtc->crtc);
> + drm_crtc_send_vblank_event(&scrtc->base, event);
> + drm_crtc_vblank_put(&scrtc->base);
> }
> spin_unlock_irqrestore(&dev->event_lock, flags);
> }
> @@ -435,7 +435,7 @@ static int shmob_drm_crtc_page_flip(struct drm_crtc *crtc,
> struct drm_modeset_acquire_ctx *ctx)
> {
> struct shmob_drm_crtc *scrtc = to_shmob_crtc(crtc);
> - struct drm_device *dev = scrtc->crtc.dev;
> + struct drm_device *dev = scrtc->base.dev;
> unsigned long flags;
>
> spin_lock_irqsave(&dev->event_lock, flags);
> @@ -450,7 +450,7 @@ static int shmob_drm_crtc_page_flip(struct drm_crtc *crtc,
>
> if (event) {
> event->pipe = 0;
> - drm_crtc_vblank_get(&scrtc->crtc);
> + drm_crtc_vblank_get(&scrtc->base);
> spin_lock_irqsave(&dev->event_lock, flags);
> scrtc->event = event;
> spin_unlock_irqrestore(&dev->event_lock, flags);
> @@ -502,7 +502,7 @@ static const struct drm_crtc_funcs crtc_funcs = {
>
> int shmob_drm_crtc_create(struct shmob_drm_device *sdev)
> {
> - struct drm_crtc *crtc = &sdev->crtc.crtc;
> + struct drm_crtc *crtc = &sdev->crtc.base;
> struct drm_plane *primary, *plane;
> unsigned int i;
> int ret;
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
> index f507eaf912e16a22..79cce0a0ada4cfce 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
> @@ -21,7 +21,7 @@ struct shmob_drm_device;
> struct shmob_drm_format_info;
>
> struct shmob_drm_crtc {
> - struct drm_crtc crtc;
> + struct drm_crtc base;
>
> struct drm_pending_vblank_event *event;
> int dpms;

--
Regards,

Laurent Pinchart

2023-06-23 17:30:56

by Laurent Pinchart

[permalink] [raw]
Subject: Re: [PATCH 32/39] drm: renesas: shmobile: Shutdown the display on remove

Hi Geert,

Thank you for the patch.

On Thu, Jun 22, 2023 at 11:21:44AM +0200, Geert Uytterhoeven wrote:
> When the device is unbound from the driver, the display may be active.
> Make sure it gets shut down.
>
> Signed-off-by: Geert Uytterhoeven <[email protected]>
> ---
> drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> index a29c0c1093725b6e..636f1888b815579b 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> @@ -16,6 +16,7 @@
> #include <linux/pm_runtime.h>
> #include <linux/slab.h>
>
> +#include <drm/drm_crtc_helper.h>
> #include <drm/drm_drv.h>
> #include <drm/drm_fbdev_generic.h>
> #include <drm/drm_gem_dma_helper.h>
> @@ -145,6 +146,7 @@ static int shmob_drm_remove(struct platform_device *pdev)
> struct drm_device *ddev = &sdev->ddev;
>
> drm_dev_unregister(ddev);
> + drm_helper_force_disable_all(ddev);

I assume this will be turned into drm_atomic_helper_shutdown() later.

Reviewed-by: Laurent Pinchart <[email protected]>

> drm_kms_helper_poll_fini(ddev);
> return 0;
> }

--
Regards,

Laurent Pinchart

2023-06-23 17:41:14

by Laurent Pinchart

[permalink] [raw]
Subject: Re: [PATCH 29/39] drm: renesas: shmobile: Move shmob_drm_crtc_finish_page_flip()

Hi Geert,

Thank you for the patch.

On Thu, Jun 22, 2023 at 11:21:41AM +0200, Geert Uytterhoeven wrote:
> Move the shmob_drm_crtc_finish_page_flip() function up, to avoid having
> to move it during the modification in the next change.
>
> Signed-off-by: Geert Uytterhoeven <[email protected]>

Reviewed-by: Laurent Pinchart <[email protected]>

> ---
> .../gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 40 +++++++++++--------
> 1 file changed, 24 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> index 2c0ca802d36026f4..1d7fcf64bf2aab80 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> @@ -270,6 +270,30 @@ static void shmob_drm_crtc_start(struct shmob_drm_crtc *scrtc)
> scrtc->started = true;
> }
>
> +/* -----------------------------------------------------------------------------
> + * Page Flip
> + */
> +
> +void shmob_drm_crtc_finish_page_flip(struct shmob_drm_crtc *scrtc)
> +{
> + struct drm_pending_vblank_event *event;
> + struct drm_device *dev = scrtc->base.dev;
> + unsigned long flags;
> +
> + spin_lock_irqsave(&dev->event_lock, flags);
> + event = scrtc->event;
> + scrtc->event = NULL;
> + if (event) {
> + drm_crtc_send_vblank_event(&scrtc->base, event);
> + drm_crtc_vblank_put(&scrtc->base);
> + }
> + spin_unlock_irqrestore(&dev->event_lock, flags);
> +}
> +
> +/* -----------------------------------------------------------------------------
> + * CRTC Functions
> + */
> +
> static void shmob_drm_crtc_stop(struct shmob_drm_crtc *scrtc)
> {
> struct drm_crtc *crtc = &scrtc->base;
> @@ -412,22 +436,6 @@ static const struct drm_crtc_helper_funcs crtc_helper_funcs = {
> .mode_set_base = shmob_drm_crtc_mode_set_base,
> };
>
> -void shmob_drm_crtc_finish_page_flip(struct shmob_drm_crtc *scrtc)
> -{
> - struct drm_pending_vblank_event *event;
> - struct drm_device *dev = scrtc->base.dev;
> - unsigned long flags;
> -
> - spin_lock_irqsave(&dev->event_lock, flags);
> - event = scrtc->event;
> - scrtc->event = NULL;
> - if (event) {
> - drm_crtc_send_vblank_event(&scrtc->base, event);
> - drm_crtc_vblank_put(&scrtc->base);
> - }
> - spin_unlock_irqrestore(&dev->event_lock, flags);
> -}
> -
> static int shmob_drm_crtc_page_flip(struct drm_crtc *crtc,
> struct drm_framebuffer *fb,
> struct drm_pending_vblank_event *event,

--
Regards,

Laurent Pinchart

2023-06-23 17:42:44

by Laurent Pinchart

[permalink] [raw]
Subject: Re: [PATCH 28/39] drm: renesas: shmobile: Use drm_crtc_handle_vblank()

Hi Geert,

Thank you for the patch.

On Thu, Jun 22, 2023 at 11:21:40AM +0200, Geert Uytterhoeven wrote:
> Replace the call to the legacy drm_handle_vblank() function with a call
> to the new drm_crtc_handle_vblank() helper.
>
> Signed-off-by: Geert Uytterhoeven <[email protected]>

Reviewed-by: Laurent Pinchart <[email protected]>

> ---
> drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> index c98e2bdd888c3274..6eaf2c5a104f451a 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> @@ -86,7 +86,7 @@ static irqreturn_t shmob_drm_irq(int irq, void *arg)
> spin_unlock_irqrestore(&sdev->irq_lock, flags);
>
> if (status & LDINTR_VES) {
> - drm_handle_vblank(dev, 0);
> + drm_crtc_handle_vblank(&sdev->crtc.base);
> shmob_drm_crtc_finish_page_flip(&sdev->crtc);
> }
>

--
Regards,

Laurent Pinchart

2023-06-23 17:43:00

by Laurent Pinchart

[permalink] [raw]
Subject: Re: [PATCH 38/39] drm: renesas: shmobile: Atomic conversion part 3

Hi Geert,

Thank you for the patch.

On Thu, Jun 22, 2023 at 11:21:50AM +0200, Geert Uytterhoeven wrote:
> Complete the conversion to atomic mode setting by converting the
> connector, and setting the DRIVER_ATOMIC flag.
>
> Signed-off-by: Geert Uytterhoeven <[email protected]>

Reviewed-by: Laurent Pinchart <[email protected]>

> ---
> drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 5 +----
> drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c | 2 +-
> 2 files changed, 2 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> index f2332bb0fbbd51a1..17456dde57637ab8 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> @@ -574,7 +574,6 @@ static void shmob_drm_connector_destroy(struct drm_connector *connector)
> }
>
> static const struct drm_connector_funcs connector_funcs = {
> - .dpms = drm_helper_connector_dpms,
> .reset = drm_atomic_helper_connector_reset,
> .fill_modes = drm_helper_probe_single_connector_modes,
> .destroy = shmob_drm_connector_destroy,
> @@ -644,9 +643,7 @@ int shmob_drm_connector_create(struct shmob_drm_device *sdev,
> if (ret < 0)
> goto error;
>
> - drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
> - drm_object_property_set_value(&connector->base,
> - sdev->ddev.mode_config.dpms_property, DRM_MODE_DPMS_OFF);
> + connector->dpms = DRM_MODE_DPMS_OFF;
>
> sdev->connector = connector;
>
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> index c43f408d6b1fcc5b..576869164479ec6b 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> @@ -98,7 +98,7 @@ static irqreturn_t shmob_drm_irq(int irq, void *arg)
> DEFINE_DRM_GEM_DMA_FOPS(shmob_drm_fops);
>
> static const struct drm_driver shmob_drm_driver = {
> - .driver_features = DRIVER_GEM | DRIVER_MODESET,
> + .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
> DRM_GEM_DMA_DRIVER_OPS,
> .fops = &shmob_drm_fops,
> .name = "shmob-drm",

--
Regards,

Laurent Pinchart

2023-06-23 17:45:00

by Laurent Pinchart

[permalink] [raw]
Subject: Re: [PATCH 27/39] drm: renesas: shmobile: Rename shmob_drm_plane.plane

Hi Geert,

Thank you for the patch.

On Thu, Jun 22, 2023 at 11:21:39AM +0200, Geert Uytterhoeven wrote:
> Rename the "plane" member of the shmob_drm_plane subclass structure to
> "base", to improve readability.
>
> Signed-off-by: Geert Uytterhoeven <[email protected]>

Reviewed-by: Laurent Pinchart <[email protected]>

> ---
> drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c | 10 +++++-----
> 1 file changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
> index 63886015baaebfc0..e300e5c0de70a9b1 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
> @@ -20,7 +20,7 @@
> #include "shmob_drm_regs.h"
>
> struct shmob_drm_plane {
> - struct drm_plane plane;
> + struct drm_plane base;
> unsigned int index;
> unsigned int alpha;
>
> @@ -37,7 +37,7 @@ struct shmob_drm_plane {
>
> static inline struct shmob_drm_plane *to_shmob_plane(struct drm_plane *plane)
> {
> - return container_of(plane, struct shmob_drm_plane, plane);
> + return container_of(plane, struct shmob_drm_plane, base);
> }
>
> static void shmob_drm_plane_compute_base(struct shmob_drm_plane *splane,
> @@ -64,7 +64,7 @@ static void shmob_drm_plane_compute_base(struct shmob_drm_plane *splane,
> static void __shmob_drm_plane_setup(struct shmob_drm_plane *splane,
> struct drm_framebuffer *fb)
> {
> - struct shmob_drm_device *sdev = to_shmob_device(splane->plane.dev);
> + struct shmob_drm_device *sdev = to_shmob_device(splane->base.dev);
> unsigned int ovl_idx = splane->index - 1;
> u32 format;
>
> @@ -221,7 +221,7 @@ struct drm_plane *shmob_drm_plane_create(struct shmob_drm_device *sdev,
> }
>
> splane = drmm_universal_plane_alloc(&sdev->ddev,
> - struct shmob_drm_plane, plane, 1,
> + struct shmob_drm_plane, base, 1,
> funcs, formats,
> ARRAY_SIZE(formats), NULL, type,
> NULL);
> @@ -231,5 +231,5 @@ struct drm_plane *shmob_drm_plane_create(struct shmob_drm_device *sdev,
> splane->index = index;
> splane->alpha = 255;
>
> - return &splane->plane;
> + return &splane->base;
> }

--
Regards,

Laurent Pinchart

2023-06-23 17:49:26

by Laurent Pinchart

[permalink] [raw]
Subject: Re: [PATCH 30/39] drm: renesas: shmobile: Wait for page flip when turning CRTC off

Hi Geert,

Thank you for the patch.

On Thu, Jun 22, 2023 at 11:21:42AM +0200, Geert Uytterhoeven wrote:
> Turning a CRTC off will prevent a queued page flip from ever completing,
> potentially confusing userspace. Wait for queued page flips to complete
> before turning the CRTC off to avoid this.
>
> Signed-off-by: Geert Uytterhoeven <[email protected]>

Given that you're duplicating the rcar-du page flip handling code, I
have a feeling core helpers would be handy. It's not a blocker for this
series though, so

Reviewed-by: Laurent Pinchart <[email protected]>

> ---
> .../gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 37 +++++++++++++++++++
> .../gpu/drm/renesas/shmobile/shmob_drm_crtc.h | 3 ++
> 2 files changed, 40 insertions(+)
>
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> index 1d7fcf64bf2aab80..d2a0ac5f9368c11c 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> @@ -285,11 +285,40 @@ void shmob_drm_crtc_finish_page_flip(struct shmob_drm_crtc *scrtc)
> scrtc->event = NULL;
> if (event) {
> drm_crtc_send_vblank_event(&scrtc->base, event);
> + wake_up(&scrtc->flip_wait);
> drm_crtc_vblank_put(&scrtc->base);
> }
> spin_unlock_irqrestore(&dev->event_lock, flags);
> }
>
> +static bool shmob_drm_crtc_page_flip_pending(struct shmob_drm_crtc *scrtc)
> +{
> + struct drm_device *dev = scrtc->base.dev;
> + unsigned long flags;
> + bool pending;
> +
> + spin_lock_irqsave(&dev->event_lock, flags);
> + pending = scrtc->event != NULL;
> + spin_unlock_irqrestore(&dev->event_lock, flags);
> +
> + return pending;
> +}
> +
> +static void shmob_drm_crtc_wait_page_flip(struct shmob_drm_crtc *scrtc)
> +{
> + struct drm_crtc *crtc = &scrtc->base;
> + struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);
> +
> + if (wait_event_timeout(scrtc->flip_wait,
> + !shmob_drm_crtc_page_flip_pending(scrtc),
> + msecs_to_jiffies(50)))
> + return;
> +
> + dev_warn(sdev->dev, "page flip timeout\n");
> +
> + shmob_drm_crtc_finish_page_flip(scrtc);
> +}
> +
> /* -----------------------------------------------------------------------------
> * CRTC Functions
> */
> @@ -302,6 +331,12 @@ static void shmob_drm_crtc_stop(struct shmob_drm_crtc *scrtc)
> if (!scrtc->started)
> return;
>
> + /*
> + * Wait for page flip completion before stopping the CRTC as userspace
> + * expects page flips to eventually complete.
> + */
> + shmob_drm_crtc_wait_page_flip(scrtc);
> +
> /* Stop the LCDC. */
> shmob_drm_crtc_start_stop(scrtc, false);
>
> @@ -515,6 +550,8 @@ int shmob_drm_crtc_create(struct shmob_drm_device *sdev)
> unsigned int i;
> int ret;
>
> + init_waitqueue_head(&sdev->crtc.flip_wait);
> +
> sdev->crtc.dpms = DRM_MODE_DPMS_OFF;
>
> primary = shmob_drm_plane_create(sdev, 0);
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
> index 2c6d7541427581a6..b9863e026e8a9b83 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
> @@ -14,6 +14,8 @@
> #include <drm/drm_connector.h>
> #include <drm/drm_encoder.h>
>
> +#include <linux/wait.h>
> +
> #include <video/videomode.h>
>
> struct drm_pending_vblank_event;
> @@ -24,6 +26,7 @@ struct shmob_drm_crtc {
> struct drm_crtc base;
>
> struct drm_pending_vblank_event *event;
> + wait_queue_head_t flip_wait;
> int dpms;
>
> const struct shmob_drm_format_info *format;

--
Regards,

Laurent Pinchart

2023-06-23 17:51:10

by Laurent Pinchart

[permalink] [raw]
Subject: Re: [PATCH 33/39] drm: renesas: shmobile: Cleanup encoder

Hi Geert,

Thank you for the patch.

On Thu, Jun 22, 2023 at 11:21:45AM +0200, Geert Uytterhoeven wrote:
> Most unused callbacks can be NULL pointers these days.
> Drop a bunch of empty encoder callbacks.
>
> Signed-off-by: Geert Uytterhoeven <[email protected]>

Reviewed-by: Laurent Pinchart <[email protected]>

> ---
> .../gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 26 -------------------
> 1 file changed, 26 deletions(-)
>
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> index b184019d8b1ed89c..ef327da39bca415a 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> @@ -586,11 +586,6 @@ int shmob_drm_crtc_create(struct shmob_drm_device *sdev)
> * Encoder
> */
>
> -static void shmob_drm_encoder_dpms(struct drm_encoder *encoder, int mode)
> -{
> - /* No-op, everything is handled in the CRTC code. */
> -}
> -
> static bool shmob_drm_encoder_mode_fixup(struct drm_encoder *encoder,
> const struct drm_display_mode *mode,
> struct drm_display_mode *adjusted_mode)
> @@ -613,29 +608,8 @@ static bool shmob_drm_encoder_mode_fixup(struct drm_encoder *encoder,
> return true;
> }
>
> -static void shmob_drm_encoder_mode_prepare(struct drm_encoder *encoder)
> -{
> - /* No-op, everything is handled in the CRTC code. */
> -}
> -
> -static void shmob_drm_encoder_mode_set(struct drm_encoder *encoder,
> - struct drm_display_mode *mode,
> - struct drm_display_mode *adjusted_mode)
> -{
> - /* No-op, everything is handled in the CRTC code. */
> -}
> -
> -static void shmob_drm_encoder_mode_commit(struct drm_encoder *encoder)
> -{
> - /* No-op, everything is handled in the CRTC code. */
> -}
> -
> static const struct drm_encoder_helper_funcs encoder_helper_funcs = {
> - .dpms = shmob_drm_encoder_dpms,
> .mode_fixup = shmob_drm_encoder_mode_fixup,
> - .prepare = shmob_drm_encoder_mode_prepare,
> - .commit = shmob_drm_encoder_mode_commit,
> - .mode_set = shmob_drm_encoder_mode_set,
> };
>
> int shmob_drm_encoder_create(struct shmob_drm_device *sdev)

--
Regards,

Laurent Pinchart

2023-06-23 17:52:41

by Laurent Pinchart

[permalink] [raw]
Subject: Re: [PATCH 31/39] drm: renesas: shmobile: Turn vblank on/off when enabling/disabling CRTC

Hi Geert,

Thank you for the patch.

On Thu, Jun 22, 2023 at 11:21:43AM +0200, Geert Uytterhoeven wrote:
> The DRM core vblank handling mechanism requires drivers to forcefully
> turn vblank reporting off when disabling the CRTC, and to restore the
> vblank reporting status when enabling the CRTC.
> Implement this using the drm_crtc_vblank_{on,off}() helpers.
>
> Note that drm_crtc_vblank_off() must be called at startup to synchronize
> the state of the vblank core code with the hardware, which is initially
> disabled. This is performed at CRTC creation time, requiring vertical
> blank initialization to be moved before creating CRTCs.
>
> Signed-off-by: Geert Uytterhoeven <[email protected]>

Reviewed-by: Laurent Pinchart <[email protected]>

> ---
> drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 10 +++++++++-
> drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c | 12 ++++++------
> 2 files changed, 15 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> index d2a0ac5f9368c11c..b184019d8b1ed89c 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> @@ -267,6 +267,9 @@ static void shmob_drm_crtc_start(struct shmob_drm_crtc *scrtc)
>
> shmob_drm_crtc_start_stop(scrtc, true);
>
> + /* Turn vertical blank interrupt reporting back on. */
> + drm_crtc_vblank_on(crtc);
> +
> scrtc->started = true;
> }
>
> @@ -332,10 +335,12 @@ static void shmob_drm_crtc_stop(struct shmob_drm_crtc *scrtc)
> return;
>
> /*
> - * Wait for page flip completion before stopping the CRTC as userspace
> + * Disable vertical blank interrupt reporting. We first need to wait
> + * for page flip completion before stopping the CRTC as userspace
> * expects page flips to eventually complete.
> */
> shmob_drm_crtc_wait_page_flip(scrtc);
> + drm_crtc_vblank_off(crtc);
>
> /* Stop the LCDC. */
> shmob_drm_crtc_start_stop(scrtc, false);
> @@ -571,6 +576,9 @@ int shmob_drm_crtc_create(struct shmob_drm_device *sdev)
>
> drm_crtc_helper_add(crtc, &crtc_helper_funcs);
>
> + /* Start with vertical blank interrupt reporting disabled. */
> + drm_crtc_vblank_off(crtc);
> +
> return 0;
> }
>
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> index 6eaf2c5a104f451a..a29c0c1093725b6e 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> @@ -189,17 +189,17 @@ static int shmob_drm_probe(struct platform_device *pdev)
> if (ret < 0)
> return ret;
>
> - ret = shmob_drm_modeset_init(sdev);
> - if (ret < 0)
> - return dev_err_probe(&pdev->dev, ret,
> - "failed to initialize mode setting\n");
> -
> ret = drm_vblank_init(ddev, 1);
> if (ret < 0) {
> dev_err(&pdev->dev, "failed to initialize vblank\n");
> - goto err_modeset_cleanup;
> + return ret;
> }
>
> + ret = shmob_drm_modeset_init(sdev);
> + if (ret < 0)
> + return dev_err_probe(&pdev->dev, ret,
> + "failed to initialize mode setting\n");
> +
> ret = platform_get_irq(pdev, 0);
> if (ret < 0)
> goto err_modeset_cleanup;

--
Regards,

Laurent Pinchart

2023-06-23 17:54:28

by Laurent Pinchart

[permalink] [raw]
Subject: Re: [PATCH 37/39] drm: renesas: shmobile: Remove internal CRTC state tracking

Hi Geert,

Thank you for the patch.

On Thu, Jun 22, 2023 at 11:21:49AM +0200, Geert Uytterhoeven wrote:
> Now the suspend/resume methods no longer need to look at internal driver
> state, the dpms and started fields in the shmob_drm_crtc structure can
> be removed, as well as the shmob_drm_crtc_dpms() wrapper.
>
> Signed-off-by: Geert Uytterhoeven <[email protected]>
> ---
> .../gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 35 ++++---------------
> .../gpu/drm/renesas/shmobile/shmob_drm_crtc.h | 3 --
> 2 files changed, 6 insertions(+), 32 deletions(-)
>
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> index b11bb666de3bac46..f2332bb0fbbd51a1 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> @@ -196,9 +196,6 @@ static void shmob_drm_crtc_start(struct shmob_drm_crtc *scrtc)
> u32 value;
> int ret;
>
> - if (scrtc->started)
> - return;
> -
> ret = pm_runtime_resume_and_get(dev);
> if (ret)
> return;
> @@ -252,8 +249,6 @@ static void shmob_drm_crtc_start(struct shmob_drm_crtc *scrtc)
>
> /* Turn vertical blank interrupt reporting back on. */
> drm_crtc_vblank_on(crtc);
> -
> - scrtc->started = true;
> }
>
> /* -----------------------------------------------------------------------------
> @@ -314,9 +309,6 @@ static void shmob_drm_crtc_stop(struct shmob_drm_crtc *scrtc)
> struct drm_crtc *crtc = &scrtc->base;
> struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);
>
> - if (!scrtc->started)
> - return;
> -
> /*
> * Disable vertical blank interrupt reporting. We first need to wait
> * for page flip completion before stopping the CRTC as userspace
> @@ -335,8 +327,6 @@ static void shmob_drm_crtc_stop(struct shmob_drm_crtc *scrtc)
> shmob_drm_clk_off(sdev);
>
> pm_runtime_put(sdev->dev);
> -
> - scrtc->started = false;
> }
>
> static inline struct shmob_drm_crtc *to_shmob_crtc(struct drm_crtc *crtc)
> @@ -344,21 +334,6 @@ static inline struct shmob_drm_crtc *to_shmob_crtc(struct drm_crtc *crtc)
> return container_of(crtc, struct shmob_drm_crtc, base);
> }
>
> -static void shmob_drm_crtc_dpms(struct drm_crtc *crtc, int mode)
> -{
> - struct shmob_drm_crtc *scrtc = to_shmob_crtc(crtc);
> -
> - if (scrtc->dpms == mode)
> - return;
> -
> - if (mode == DRM_MODE_DPMS_ON)
> - shmob_drm_crtc_start(scrtc);
> - else
> - shmob_drm_crtc_stop(scrtc);
> -
> - scrtc->dpms = mode;
> -}
> -
> static void shmob_drm_crtc_atomic_flush(struct drm_crtc *crtc,
> struct drm_atomic_state *state)
> {
> @@ -378,13 +353,17 @@ static void shmob_drm_crtc_atomic_flush(struct drm_crtc *crtc,
> static void shmob_drm_crtc_atomic_enable(struct drm_crtc *crtc,
> struct drm_atomic_state *state)
> {
> - shmob_drm_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
> + struct shmob_drm_crtc *scrtc = to_shmob_crtc(crtc);
> +
> + shmob_drm_crtc_start(scrtc);

If this function isn't called from any other location anymore, you may
want to inline it.

> }
>
> static void shmob_drm_crtc_atomic_disable(struct drm_crtc *crtc,
> struct drm_atomic_state *state)
> {
> - shmob_drm_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
> + struct shmob_drm_crtc *scrtc = to_shmob_crtc(crtc);
> +
> + shmob_drm_crtc_stop(scrtc);

Same here.

Reviewed-by: Laurent Pinchart <[email protected]>

> }
>
> static const struct drm_crtc_helper_funcs crtc_helper_funcs = {
> @@ -476,8 +455,6 @@ int shmob_drm_crtc_create(struct shmob_drm_device *sdev)
>
> init_waitqueue_head(&sdev->crtc.flip_wait);
>
> - sdev->crtc.dpms = DRM_MODE_DPMS_OFF;
> -
> primary = shmob_drm_plane_create(sdev, 0);
> if (IS_ERR(primary))
> return PTR_ERR(primary);
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
> index 37380c815f1f5a08..89a0746f9a35807d 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
> @@ -27,9 +27,6 @@ struct shmob_drm_crtc {
>
> struct drm_pending_vblank_event *event;
> wait_queue_head_t flip_wait;
> - int dpms;
> -
> - bool started;
> };
>
> struct shmob_drm_connector {

--
Regards,

Laurent Pinchart

2023-06-23 17:56:05

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH 06/39] drm: renesas: shmobile: Add support for Runtime PM

Hi Laurent,

On Fri, Jun 23, 2023 at 5:34 PM Laurent Pinchart
<[email protected]> wrote:
> On Fri, Jun 23, 2023 at 05:22:45PM +0200, Geert Uytterhoeven wrote:
> > On Fri, Jun 23, 2023 at 5:11 PM Laurent Pinchart wrote:
> > > On Fri, Jun 23, 2023 at 06:07:44PM +0300, Laurent Pinchart wrote:
> > > > On Thu, Jun 22, 2023 at 11:21:18AM +0200, Geert Uytterhoeven wrote:
> > > > > The SH-Mobile LCD Controller is part of a PM Domain on all relevant SoCs
> > > > > (clock domain on all, power domain on some). Hence it may not be
> > > > > sufficient to manage the LCDC module clock explicitly (e.g. if the
> > > > > selected clock source differs from SHMOB_DRM_CLK_BUS).
> > > > >
> > > > > Fix this by using Runtime PM instead.
> > > > >
> > > > > Signed-off-by: Geert Uytterhoeven <[email protected]>
> > > > > ---
> > > > > drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 11 ++++++++++-
> > > > > drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c | 5 +++++
> > > > > 2 files changed, 15 insertions(+), 1 deletion(-)
> > > > >
> > > > > diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> > > > > index fbfd906844da490c..84dbf35025d7be63 100644
> > > > > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> > > > > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> > > > > @@ -9,6 +9,7 @@
> > > > >
> > > > > #include <linux/backlight.h>
> > > > > #include <linux/clk.h>
> > > > > +#include <linux/pm_runtime.h>
> > > > >
> > > > > #include <drm/drm_crtc.h>
> > > > > #include <drm/drm_crtc_helper.h>
> > > > > @@ -170,10 +171,16 @@ static void shmob_drm_crtc_start(struct shmob_drm_crtc *scrtc)
> > > > > if (WARN_ON(format == NULL))
> > > > > return;
> > > > >
> > > > > + ret = pm_runtime_resume_and_get(sdev->dev);
> > > > > + if (ret)
> > > > > + return;
> > > > > +
> > > > > /* Enable clocks before accessing the hardware. */
> > > > > ret = shmob_drm_clk_on(sdev);
> > > >
> > > > This would be best located in the runtime PM resume handler. Same for
> > > > disabling clocks in the runtime PM suspend handler.
> > >
> > > The driver should then depend on CONFIG_PM. There's no indirect
> > > dependency through CONFIG_DRM as far as I can tell, but there's one
> > > through ARCH_SHMOBILE. This then got me puzzled, as ARCH_SHMOBILE is
> > > defined in arch/sh/Kconfig, and this driver depends on ARM. Am I missing
> > > something ?
> >
> > Vommit 4bd65789ba847f39 ("drm: shmobile: Make DRM_SHMOBILE visible on
> > Renesas SoC platforms") in drm-next:
> >
> > - depends on DRM && ARM
> > - depends on ARCH_SHMOBILE || COMPILE_TEST
> > + depends on DRM
> > + depends on ARCH_RENESAS || ARCH_SHMOBILE || COMPILE_TEST
>
> That's better indeed :-)
>
> A dependency on CONFIG_PM is still needed as ARCH_RENESAS doesn't depend
> on it.

ARCH_RMOBILE selects PM, so PM will be enabled on affected platforms.

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

2023-06-23 18:31:35

by Laurent Pinchart

[permalink] [raw]
Subject: Re: [PATCH 36/39] drm: renesas: shmobile: Use suspend/resume helpers

Hi Geert,

Thank you for the patch.

On Thu, Jun 22, 2023 at 11:21:48AM +0200, Geert Uytterhoeven wrote:
> Replace the custom suspend/resume handling by calls into
> drm_mode_config_helper_{suspend,resume}().
>
> Signed-off-by: Geert Uytterhoeven <[email protected]>

Reviewed-by: Laurent Pinchart <[email protected]>

> ---
> drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 13 -------------
> drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h | 2 --
> drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c | 13 +++----------
> 3 files changed, 3 insertions(+), 25 deletions(-)
>
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> index cf7152d64424e720..b11bb666de3bac46 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> @@ -339,19 +339,6 @@ static void shmob_drm_crtc_stop(struct shmob_drm_crtc *scrtc)
> scrtc->started = false;
> }
>
> -void shmob_drm_crtc_suspend(struct shmob_drm_crtc *scrtc)
> -{
> - shmob_drm_crtc_stop(scrtc);
> -}
> -
> -void shmob_drm_crtc_resume(struct shmob_drm_crtc *scrtc)
> -{
> - if (scrtc->dpms != DRM_MODE_DPMS_ON)
> - return;
> -
> - shmob_drm_crtc_start(scrtc);
> -}
> -
> static inline struct shmob_drm_crtc *to_shmob_crtc(struct drm_crtc *crtc)
> {
> return container_of(crtc, struct shmob_drm_crtc, base);
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
> index fe41e42d6cc55275..37380c815f1f5a08 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
> @@ -40,8 +40,6 @@ struct shmob_drm_connector {
>
> int shmob_drm_crtc_create(struct shmob_drm_device *sdev);
> void shmob_drm_crtc_finish_page_flip(struct shmob_drm_crtc *scrtc);
> -void shmob_drm_crtc_suspend(struct shmob_drm_crtc *scrtc);
> -void shmob_drm_crtc_resume(struct shmob_drm_crtc *scrtc);
>
> int shmob_drm_encoder_create(struct shmob_drm_device *sdev);
> int shmob_drm_connector_create(struct shmob_drm_device *sdev,
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> index 9107f84224602683..c43f408d6b1fcc5b 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> @@ -20,6 +20,7 @@
> #include <drm/drm_drv.h>
> #include <drm/drm_fbdev_generic.h>
> #include <drm/drm_gem_dma_helper.h>
> +#include <drm/drm_modeset_helper.h>
> #include <drm/drm_module.h>
> #include <drm/drm_probe_helper.h>
> #include <drm/drm_vblank.h>
> @@ -115,22 +116,14 @@ static int shmob_drm_pm_suspend(struct device *dev)
> {
> struct shmob_drm_device *sdev = dev_get_drvdata(dev);
>
> - drm_kms_helper_poll_disable(&sdev->ddev);
> - shmob_drm_crtc_suspend(&sdev->crtc);
> -
> - return 0;
> + return drm_mode_config_helper_suspend(&sdev->ddev);
> }
>
> static int shmob_drm_pm_resume(struct device *dev)
> {
> struct shmob_drm_device *sdev = dev_get_drvdata(dev);
>
> - drm_modeset_lock_all(&sdev->ddev);
> - shmob_drm_crtc_resume(&sdev->crtc);
> - drm_modeset_unlock_all(&sdev->ddev);
> -
> - drm_kms_helper_poll_enable(&sdev->ddev);
> - return 0;
> + return drm_mode_config_helper_resume(&sdev->ddev);
> }
>
> static DEFINE_SIMPLE_DEV_PM_OPS(shmob_drm_pm_ops,

--
Regards,

Laurent Pinchart

2023-06-23 18:32:40

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH 24/39] drm: renesas: shmobile: Unify plane allocation

Hi Laurent,

On Fri, Jun 23, 2023 at 6:50 PM Laurent Pinchart
<[email protected]> wrote:
> On Thu, Jun 22, 2023 at 11:21:36AM +0200, Geert Uytterhoeven wrote:
> > Unify primary and overlay plane allocation:
> > - Enhance shmob_drm_plane_create() so it can be used to create the
> > primary plane, too,
> > - Move overlay plane creation next to primary plane creation.
> >
> > As overlay plane index zero now means the primary plane, this requires
> > shifting all overlay plane indices by one.
>
> Do you use index zero to identify the primary plane just for
> shmob_drm_plane_create(), or somewhere else too ? If it's just to create
> the plane, you could instead pass the plane type to the function.

Index zero is just used for the creation.
I guess this sort of goes together with my question below...

> > Signed-off-by: Geert Uytterhoeven <[email protected]>
> > ---
> > Perhaps it would be better to not use dynamic allocation, but store
> > "struct drm_plane primary" and "struct shmob_drm_plane planes[5]" in
> > struct drm_shmob_device instead, like is done for the crtc and encoder?

... as embedding separate primary and planes[] would also get rid of
the need to adjust the plane indices when converting from logical to physical
overlay plane indices.

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

2023-06-23 18:33:00

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH 23/39] drm: renesas: shmobile: Move interface handling to connector setup

Hi Laurent,

On Fri, Jun 23, 2023 at 6:39 PM Laurent Pinchart
<[email protected]> wrote:
> On Thu, Jun 22, 2023 at 11:21:35AM +0200, Geert Uytterhoeven wrote:
> > Move legacy interface handling to the connector setup code.
> > Set up bus_flags and bus_formats in display_info according to the
> > bus format and panel information from platform data, to make it more
> > similar with DT-based connector/bridge/panel setup.
> > This will allows us to use the same LCD interface setup code for both
>
> s/allows/allow/
>
> > legacy and DT-based systems.
> >
> > Signed-off-by: Geert Uytterhoeven <[email protected]>

> > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> > @@ -8,6 +8,7 @@
> > */
> >
> > #include <linux/clk.h>
> > +#include <linux/media-bus-format.h>
> > #include <linux/pm_runtime.h>
> >
> > #include <drm/drm_crtc.h>
> > @@ -66,15 +67,65 @@ static void shmob_drm_crtc_setup_geometry(struct shmob_drm_crtc *scrtc)
> > {
> > struct drm_crtc *crtc = &scrtc->crtc;
> > struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);
> > - enum display_flags dpy_flags = sdev->connector.mode->flags;
> > + const struct drm_display_info *info = &sdev->connector->display_info;
> > const struct drm_display_mode *mode = &crtc->mode;
> > u32 value;
> >
> > - value = sdev->ldmt1r
> > - | ((mode->flags & DRM_MODE_FLAG_PVSYNC) ? 0 : LDMT1R_VPOL)
> > - | ((mode->flags & DRM_MODE_FLAG_PHSYNC) ? 0 : LDMT1R_HPOL)
> > - | ((dpy_flags & DISPLAY_FLAGS_PIXDATA_POSEDGE) ? LDMT1R_DWPOL : 0)
> > - | ((dpy_flags & DISPLAY_FLAGS_DE_LOW) ? LDMT1R_DIPOL : 0);
> > + if (!info->num_bus_formats || !info->bus_formats) {
> > + dev_warn(sdev->dev, "No bus format reported, using RGB888\n");
> > + value = LDMT1R_MIFTYP_RGB24;
> > + } else {
> > + switch (info->bus_formats[0]) {
> > + case MEDIA_BUS_FMT_RGB888_3X8:
> > + value = LDMT1R_MIFTYP_RGB8;
> > + break;
> > +
> > + case MEDIA_BUS_FMT_RGB666_2X9_BE:
> > + value = LDMT1R_MIFTYP_RGB9;
> > + break;
> > +
> > + case MEDIA_BUS_FMT_RGB888_2X12_BE:
> > + value = LDMT1R_MIFTYP_RGB12A;
> > + break;
> > +
> > + case MEDIA_BUS_FMT_RGB444_1X12:
> > + value = LDMT1R_MIFTYP_RGB12B;
> > + break;
> > +
> > + case MEDIA_BUS_FMT_RGB565_1X16:
> > + value = LDMT1R_MIFTYP_RGB16;
> > + break;
> > +
> > + case MEDIA_BUS_FMT_RGB666_1X18:
> > + value = LDMT1R_MIFTYP_RGB18;
> > + break;
> > +
> > + case MEDIA_BUS_FMT_RGB888_1X24:
> > + value = LDMT1R_MIFTYP_RGB24;
> > + break;
> > +
> > + case MEDIA_BUS_FMT_UYVY8_1X16:
> > + value = LDMT1R_MIFTYP_YCBCR;
> > + break;
> > +
> > + default:
> > + dev_warn(sdev->dev,
> > + "unsupported bus format 0x%x, using RGB888\n",
> > + info->bus_formats[0]);
> > + value = LDMT1R_MIFTYP_RGB24;
> > + break;
> > + }
>
> It's a bit annoying to lose the ability to validate the bus format at
> probe time. Can it be kept. I'm also OK with restoring it later in the
> series if it gets in the way of the conversion, in which case a mention
> in the commit message would be nice.

I guess I can keep it, somewhere.
Probably it should be validated for the DT case later, too.
BTW, drivers/gpu/drm/renesas/rcar-du/rcar_lvds.s doesn't check this
either, so I copied the bad example from the expert ;-)

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

2023-06-23 18:33:57

by Laurent Pinchart

[permalink] [raw]
Subject: Re: [PATCH 39/39] drm: renesas: shmobile: Add DT support

Hi Geert,

Thank you for the patch.

On Thu, Jun 22, 2023 at 11:21:51AM +0200, Geert Uytterhoeven wrote:
> Add DT support, by:
> 1. Creating a panel bridge from DT, and attaching it to the encoder,
> 2. Replacing the custom connector with a bridge connector,
> 3. Obtaining clock configuration based on the compatible value.
>
> Note that for now the driver uses a fixed clock configuration selecting
> the bus clock, as the current code to select other clock inputs needs
> changes to support any other SoCs than SH7724.
>
> Signed-off-by: Geert Uytterhoeven <[email protected]>
> Cc: Rob Herring <[email protected]>
> Cc: Krzysztof Kozlowski <[email protected]>
> Cc: Conor Dooley <[email protected]>
> Cc: [email protected]
> ---
> SH-Mobile AG5 (SH73A0) support is untested.
>
> Unbind crashes when drm_encoder_cleanup() calls drm_bridge_detach(), as
> the bridge (allocated by devm_drm_panel_bridge_add()) has already been
> freed by that time.
> Should I allocate my encoder with devm_kzalloc(), instead of embedding
> it inside struct shmob_drm_device?

That shouldn't be needed, if you manage the memory for shmob_drm_device
with the DRM managed helpers.

Lifetime management of bridges is currently completely broken, there's
nothing that prevents bridges from being freed while still in use.
That's an issue in DRM, not in your driver.

> ---
> .../gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 101 +++++++++++++++---
> .../gpu/drm/renesas/shmobile/shmob_drm_crtc.h | 1 +
> .../gpu/drm/renesas/shmobile/shmob_drm_drv.c | 27 ++++-
> .../gpu/drm/renesas/shmobile/shmob_drm_drv.h | 6 ++
> 4 files changed, 118 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> index 17456dde57637ab8..1ec87841658de4f0 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> @@ -9,12 +9,16 @@
>
> #include <linux/clk.h>
> #include <linux/media-bus-format.h>
> +#include <linux/of.h>
> +#include <linux/of_graph.h>
> #include <linux/pm_runtime.h>
>
> #include <drm/drm_atomic.h>
> #include <drm/drm_atomic_helper.h>
> #include <drm/drm_atomic_state_helper.h>
> #include <drm/drm_atomic_uapi.h>
> +#include <drm/drm_bridge.h>
> +#include <drm/drm_bridge_connector.h>
> #include <drm/drm_crtc.h>
> #include <drm/drm_crtc_helper.h>
> #include <drm/drm_fb_dma_helper.h>
> @@ -23,6 +27,7 @@
> #include <drm/drm_gem_dma_helper.h>
> #include <drm/drm_modeset_helper.h>
> #include <drm/drm_modeset_helper_vtables.h>
> +#include <drm/drm_panel.h>
> #include <drm/drm_probe_helper.h>
> #include <drm/drm_simple_kms_helper.h>
> #include <drm/drm_vblank.h>
> @@ -35,10 +40,6 @@
> #include "shmob_drm_plane.h"
> #include "shmob_drm_regs.h"
>
> -/*
> - * TODO: panel support
> - */
> -
> /* -----------------------------------------------------------------------------
> * Clock management
> */
> @@ -129,7 +130,6 @@ static void shmob_drm_crtc_setup_geometry(struct shmob_drm_crtc *scrtc)
> value |= LDMT1R_VPOL;
> if (mode->flags & DRM_MODE_FLAG_NHSYNC)
> value |= LDMT1R_HPOL;
> -

This could be moved to one of the patches in the series that touch this
code.

> lcdc_write(sdev, LDMT1R, value);
>
> value = ((mode->hdisplay / 8) << 16) /* HDCN */
> @@ -191,7 +191,7 @@ static void shmob_drm_crtc_start(struct shmob_drm_crtc *scrtc)
> {
> struct drm_crtc *crtc = &scrtc->base;
> struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);
> - const struct shmob_drm_interface_data *idata = &sdev->pdata->iface;
> + unsigned int clk_div = sdev->config.clk_div;
> struct device *dev = sdev->dev;
> u32 value;
> int ret;
> @@ -220,17 +220,17 @@ static void shmob_drm_crtc_start(struct shmob_drm_crtc *scrtc)
> lcdc_write(sdev, LDPMR, 0);
>
> value = sdev->lddckr;
> - if (idata->clk_div) {
> + if (clk_div) {
> /* FIXME: sh7724 can only use 42, 48, 54 and 60 for the divider
> * denominator.
> */
> lcdc_write(sdev, LDDCKPAT1R, 0);
> - lcdc_write(sdev, LDDCKPAT2R, (1 << (idata->clk_div / 2)) - 1);
> + lcdc_write(sdev, LDDCKPAT2R, (1 << (clk_div / 2)) - 1);
>
> - if (idata->clk_div == 1)
> + if (clk_div == 1)
> value |= LDDCKR_MOSEL;
> else
> - value |= idata->clk_div;
> + value |= clk_div;
> }
>
> lcdc_write(sdev, LDDCKR, value);
> @@ -479,7 +479,7 @@ int shmob_drm_crtc_create(struct shmob_drm_device *sdev)
> }
>
> /* -----------------------------------------------------------------------------
> - * Encoder
> + * Legacy Encoder
> */
>
> static bool shmob_drm_encoder_mode_fixup(struct drm_encoder *encoder,
> @@ -508,9 +508,43 @@ static const struct drm_encoder_helper_funcs encoder_helper_funcs = {
> .mode_fixup = shmob_drm_encoder_mode_fixup,
> };
>
> +/* -----------------------------------------------------------------------------
> + * Encoder
> + */
> +
> +static int shmob_drm_encoder_init(struct shmob_drm_device *sdev,
> + struct device_node *enc_node)
> +{
> + struct drm_bridge *bridge;
> + struct drm_panel *panel;
> + int ret;
> +
> + /* Create a panel bridge */
> + panel = of_drm_find_panel(enc_node);

Using drm_of_find_panel_or_bridge() would allow supporting platforms
that connect a non-panel device to the SoC, in additional to the already
supported panels.

> + if (IS_ERR(panel))
> + return PTR_ERR(panel);
> +
> + bridge = devm_drm_panel_bridge_add(sdev->dev, panel);
> + if (IS_ERR(bridge))
> + return PTR_ERR(bridge);
> +
> + /* Attach the bridge to the encoder */
> + ret = drm_bridge_attach(&sdev->encoder, bridge, NULL,
> + DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> + if (ret) {
> + dev_err(sdev->dev, "failed to attach bridge %pOF: %pe\n",
> + bridge->of_node, ERR_PTR(ret));
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> int shmob_drm_encoder_create(struct shmob_drm_device *sdev)
> {
> struct drm_encoder *encoder = &sdev->encoder;
> + struct device_node *np = sdev->dev->of_node;
> + struct device_node *ep_node, *entity;
> int ret;
>
> encoder->possible_crtcs = 1;
> @@ -520,13 +554,45 @@ int shmob_drm_encoder_create(struct shmob_drm_device *sdev)
> if (ret < 0)
> return ret;
>
> - drm_encoder_helper_add(encoder, &encoder_helper_funcs);
> + if (sdev->pdata) {
> + drm_encoder_helper_add(encoder, &encoder_helper_funcs);
> + return 0;
> + }
> +
> + for_each_endpoint_of_node(np, ep_node) {
> + struct of_endpoint ep;
> +
> + ret = of_graph_parse_endpoint(ep_node, &ep);
> + if (ret < 0) {
> + of_node_put(ep_node);
> + return ret;
> + }
> + /* Ignore all but the LCD port */
> + if (ep.port || ep.id)
> + continue;
> +
> + entity = of_graph_get_remote_port_parent(ep.local_node);
> + if (!entity)
> + continue;
> +
> + if (!of_device_is_available(entity)) {
> + of_node_put(entity);
> + continue;
> + }
> +
> + ret = shmob_drm_encoder_init(sdev, entity);
> + if (ret < 0) {
> + of_node_put(entity);
> + of_node_put(ep_node);
> + return ret;
> + }
> + }
>
> return 0;
> }
>
> /* -----------------------------------------------------------------------------
> - * Connector
> + * Legacy Connector
> */
>
> static inline struct shmob_drm_connector *to_shmob_connector(struct drm_connector *connector)
> @@ -626,13 +692,20 @@ shmob_drm_connector_init(struct shmob_drm_device *sdev,
> return connector;
> }
>
> +/* -----------------------------------------------------------------------------
> + * Connector
> + */
> +
> int shmob_drm_connector_create(struct shmob_drm_device *sdev,
> struct drm_encoder *encoder)
> {
> struct drm_connector *connector;
> int ret;
>
> - connector = shmob_drm_connector_init(sdev, encoder);
> + if (sdev->pdata)
> + connector = shmob_drm_connector_init(sdev, encoder);
> + else
> + connector = drm_bridge_connector_init(&sdev->ddev, encoder);
> if (IS_ERR(connector)) {
> dev_err(sdev->dev, "failed to created connector: %pe\n",
> connector);
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
> index 89a0746f9a35807d..16e1712dd04e0f2b 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
> @@ -29,6 +29,7 @@ struct shmob_drm_crtc {
> wait_queue_head_t flip_wait;
> };
>
> +/* Legacy connector */
> struct shmob_drm_connector {
> struct drm_connector base;
> struct drm_encoder *encoder;
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> index 576869164479ec6b..db72ca1c8b2f44c9 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> @@ -11,6 +11,7 @@
> #include <linux/io.h>
> #include <linux/mm.h>
> #include <linux/module.h>
> +#include <linux/of.h>
> #include <linux/platform_device.h>
> #include <linux/pm.h>
> #include <linux/pm_runtime.h>
> @@ -147,11 +148,13 @@ static int shmob_drm_remove(struct platform_device *pdev)
> static int shmob_drm_probe(struct platform_device *pdev)
> {
> struct shmob_drm_platform_data *pdata = pdev->dev.platform_data;

How about dropping non-DT support ? That would simplify the driver.

> + const struct shmob_drm_config *config;
> struct shmob_drm_device *sdev;
> struct drm_device *ddev;
> int ret;
>
> - if (pdata == NULL) {
> + config = of_device_get_match_data(&pdev->dev);
> + if (!config && !pdata) {
> dev_err(&pdev->dev, "no platform data\n");
> return -EINVAL;
> }
> @@ -167,7 +170,13 @@ static int shmob_drm_probe(struct platform_device *pdev)
>
> ddev = &sdev->ddev;
> sdev->dev = &pdev->dev;
> - sdev->pdata = pdata;
> + if (config) {
> + sdev->config = *config;
> + } else {
> + sdev->pdata = pdata;
> + sdev->config.clk_source = pdata->clk_source;
> + sdev->config.clk_div = pdata->iface.clk_div;
> + }
> spin_lock_init(&sdev->irq_lock);
>
> platform_set_drvdata(pdev, sdev);
> @@ -180,7 +189,7 @@ static int shmob_drm_probe(struct platform_device *pdev)
> if (ret)
> return ret;
>
> - ret = shmob_drm_setup_clocks(sdev, pdata->clk_source);
> + ret = shmob_drm_setup_clocks(sdev, sdev->config.clk_source);
> if (ret < 0)
> return ret;
>
> @@ -224,11 +233,23 @@ static int shmob_drm_probe(struct platform_device *pdev)
> return ret;
> }
>
> +static const struct shmob_drm_config shmob_arm_config = {
> + .clk_source = SHMOB_DRM_CLK_BUS,
> + .clk_div = 5,
> +};
> +
> +static const struct of_device_id shmob_drm_of_table[] __maybe_unused = {
> + { .compatible = "renesas,r8a7740-lcdc", .data = &shmob_arm_config, },
> + { .compatible = "renesas,sh73a0-lcdc", .data = &shmob_arm_config, },
> + { /* sentinel */ }
> +};
> +
> static struct platform_driver shmob_drm_platform_driver = {
> .probe = shmob_drm_probe,
> .remove = shmob_drm_remove,
> .driver = {
> .name = "shmob-drm",
> + .of_match_table = of_match_ptr(shmob_drm_of_table),
> .pm = pm_sleep_ptr(&shmob_drm_pm_ops),
> },
> };
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.h b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.h
> index 18907e5ace51c681..088ac5381e91e61a 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.h
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.h
> @@ -20,9 +20,15 @@ struct clk;
> struct device;
> struct drm_device;
>
> +struct shmob_drm_config {
> + enum shmob_drm_clk_source clk_source;
> + unsigned int clk_div;
> +};
> +
> struct shmob_drm_device {
> struct device *dev;
> const struct shmob_drm_platform_data *pdata;
> + struct shmob_drm_config config;
>
> void __iomem *mmio;
> struct clk *clock;

--
Regards,

Laurent Pinchart

2023-06-23 18:34:02

by Laurent Pinchart

[permalink] [raw]
Subject: Re: [PATCH 23/39] drm: renesas: shmobile: Move interface handling to connector setup

On Fri, Jun 23, 2023 at 07:51:07PM +0200, Geert Uytterhoeven wrote:
> Hi Laurent,
>
> On Fri, Jun 23, 2023 at 6:39 PM Laurent Pinchart
> <[email protected]> wrote:
> > On Thu, Jun 22, 2023 at 11:21:35AM +0200, Geert Uytterhoeven wrote:
> > > Move legacy interface handling to the connector setup code.
> > > Set up bus_flags and bus_formats in display_info according to the
> > > bus format and panel information from platform data, to make it more
> > > similar with DT-based connector/bridge/panel setup.
> > > This will allows us to use the same LCD interface setup code for both
> >
> > s/allows/allow/
> >
> > > legacy and DT-based systems.
> > >
> > > Signed-off-by: Geert Uytterhoeven <[email protected]>
>
> > > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> > > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> > > @@ -8,6 +8,7 @@
> > > */
> > >
> > > #include <linux/clk.h>
> > > +#include <linux/media-bus-format.h>
> > > #include <linux/pm_runtime.h>
> > >
> > > #include <drm/drm_crtc.h>
> > > @@ -66,15 +67,65 @@ static void shmob_drm_crtc_setup_geometry(struct shmob_drm_crtc *scrtc)
> > > {
> > > struct drm_crtc *crtc = &scrtc->crtc;
> > > struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);
> > > - enum display_flags dpy_flags = sdev->connector.mode->flags;
> > > + const struct drm_display_info *info = &sdev->connector->display_info;
> > > const struct drm_display_mode *mode = &crtc->mode;
> > > u32 value;
> > >
> > > - value = sdev->ldmt1r
> > > - | ((mode->flags & DRM_MODE_FLAG_PVSYNC) ? 0 : LDMT1R_VPOL)
> > > - | ((mode->flags & DRM_MODE_FLAG_PHSYNC) ? 0 : LDMT1R_HPOL)
> > > - | ((dpy_flags & DISPLAY_FLAGS_PIXDATA_POSEDGE) ? LDMT1R_DWPOL : 0)
> > > - | ((dpy_flags & DISPLAY_FLAGS_DE_LOW) ? LDMT1R_DIPOL : 0);
> > > + if (!info->num_bus_formats || !info->bus_formats) {
> > > + dev_warn(sdev->dev, "No bus format reported, using RGB888\n");
> > > + value = LDMT1R_MIFTYP_RGB24;
> > > + } else {
> > > + switch (info->bus_formats[0]) {
> > > + case MEDIA_BUS_FMT_RGB888_3X8:
> > > + value = LDMT1R_MIFTYP_RGB8;
> > > + break;
> > > +
> > > + case MEDIA_BUS_FMT_RGB666_2X9_BE:
> > > + value = LDMT1R_MIFTYP_RGB9;
> > > + break;
> > > +
> > > + case MEDIA_BUS_FMT_RGB888_2X12_BE:
> > > + value = LDMT1R_MIFTYP_RGB12A;
> > > + break;
> > > +
> > > + case MEDIA_BUS_FMT_RGB444_1X12:
> > > + value = LDMT1R_MIFTYP_RGB12B;
> > > + break;
> > > +
> > > + case MEDIA_BUS_FMT_RGB565_1X16:
> > > + value = LDMT1R_MIFTYP_RGB16;
> > > + break;
> > > +
> > > + case MEDIA_BUS_FMT_RGB666_1X18:
> > > + value = LDMT1R_MIFTYP_RGB18;
> > > + break;
> > > +
> > > + case MEDIA_BUS_FMT_RGB888_1X24:
> > > + value = LDMT1R_MIFTYP_RGB24;
> > > + break;
> > > +
> > > + case MEDIA_BUS_FMT_UYVY8_1X16:
> > > + value = LDMT1R_MIFTYP_YCBCR;
> > > + break;
> > > +
> > > + default:
> > > + dev_warn(sdev->dev,
> > > + "unsupported bus format 0x%x, using RGB888\n",
> > > + info->bus_formats[0]);
> > > + value = LDMT1R_MIFTYP_RGB24;
> > > + break;
> > > + }
> >
> > It's a bit annoying to lose the ability to validate the bus format at
> > probe time. Can it be kept. I'm also OK with restoring it later in the
> > series if it gets in the way of the conversion, in which case a mention
> > in the commit message would be nice.
>
> I guess I can keep it, somewhere.
> Probably it should be validated for the DT case later, too.
> BTW, drivers/gpu/drm/renesas/rcar-du/rcar_lvds.s doesn't check this
> either, so I copied the bad example from the expert ;-)

There's an endless amount of issues to fix. Patches are of course
welcome :-)

--
Regards,

Laurent Pinchart

2023-06-23 18:34:09

by Laurent Pinchart

[permalink] [raw]
Subject: Re: [PATCH 06/39] drm: renesas: shmobile: Add support for Runtime PM

Hi Geert,

On Fri, Jun 23, 2023 at 07:41:36PM +0200, Geert Uytterhoeven wrote:
> On Fri, Jun 23, 2023 at 5:34 PM Laurent Pinchart wrote:
> > On Fri, Jun 23, 2023 at 05:22:45PM +0200, Geert Uytterhoeven wrote:
> > > On Fri, Jun 23, 2023 at 5:11 PM Laurent Pinchart wrote:
> > > > On Fri, Jun 23, 2023 at 06:07:44PM +0300, Laurent Pinchart wrote:
> > > > > On Thu, Jun 22, 2023 at 11:21:18AM +0200, Geert Uytterhoeven wrote:
> > > > > > The SH-Mobile LCD Controller is part of a PM Domain on all relevant SoCs
> > > > > > (clock domain on all, power domain on some). Hence it may not be
> > > > > > sufficient to manage the LCDC module clock explicitly (e.g. if the
> > > > > > selected clock source differs from SHMOB_DRM_CLK_BUS).
> > > > > >
> > > > > > Fix this by using Runtime PM instead.
> > > > > >
> > > > > > Signed-off-by: Geert Uytterhoeven <[email protected]>
> > > > > > ---
> > > > > > drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 11 ++++++++++-
> > > > > > drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c | 5 +++++
> > > > > > 2 files changed, 15 insertions(+), 1 deletion(-)
> > > > > >
> > > > > > diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> > > > > > index fbfd906844da490c..84dbf35025d7be63 100644
> > > > > > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> > > > > > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> > > > > > @@ -9,6 +9,7 @@
> > > > > >
> > > > > > #include <linux/backlight.h>
> > > > > > #include <linux/clk.h>
> > > > > > +#include <linux/pm_runtime.h>
> > > > > >
> > > > > > #include <drm/drm_crtc.h>
> > > > > > #include <drm/drm_crtc_helper.h>
> > > > > > @@ -170,10 +171,16 @@ static void shmob_drm_crtc_start(struct shmob_drm_crtc *scrtc)
> > > > > > if (WARN_ON(format == NULL))
> > > > > > return;
> > > > > >
> > > > > > + ret = pm_runtime_resume_and_get(sdev->dev);
> > > > > > + if (ret)
> > > > > > + return;
> > > > > > +
> > > > > > /* Enable clocks before accessing the hardware. */
> > > > > > ret = shmob_drm_clk_on(sdev);
> > > > >
> > > > > This would be best located in the runtime PM resume handler. Same for
> > > > > disabling clocks in the runtime PM suspend handler.
> > > >
> > > > The driver should then depend on CONFIG_PM. There's no indirect
> > > > dependency through CONFIG_DRM as far as I can tell, but there's one
> > > > through ARCH_SHMOBILE. This then got me puzzled, as ARCH_SHMOBILE is
> > > > defined in arch/sh/Kconfig, and this driver depends on ARM. Am I missing
> > > > something ?
> > >
> > > Vommit 4bd65789ba847f39 ("drm: shmobile: Make DRM_SHMOBILE visible on
> > > Renesas SoC platforms") in drm-next:
> > >
> > > - depends on DRM && ARM
> > > - depends on ARCH_SHMOBILE || COMPILE_TEST
> > > + depends on DRM
> > > + depends on ARCH_RENESAS || ARCH_SHMOBILE || COMPILE_TEST
> >
> > That's better indeed :-)
> >
> > A dependency on CONFIG_PM is still needed as ARCH_RENESAS doesn't depend
> > on it.
>
> ARCH_RMOBILE selects PM, so PM will be enabled on affected platforms.

Which also means that you will never test compilation without CONFIG_PM,
while bots will. There's a risk of introducing compilation warnings.

--
Regards,

Laurent Pinchart

2023-06-23 18:34:34

by Sam Ravnborg

[permalink] [raw]
Subject: Re: [PATCH 39/39] drm: renesas: shmobile: Add DT support

On Fri, Jun 23, 2023 at 08:50:19PM +0300, Laurent Pinchart wrote:
> Hi Geert,
>
> Thank you for the patch.
>
> On Thu, Jun 22, 2023 at 11:21:51AM +0200, Geert Uytterhoeven wrote:
> > Add DT support, by:
> > 1. Creating a panel bridge from DT, and attaching it to the encoder,
> > 2. Replacing the custom connector with a bridge connector,
> > 3. Obtaining clock configuration based on the compatible value.
> >
> > Note that for now the driver uses a fixed clock configuration selecting
> > the bus clock, as the current code to select other clock inputs needs
> > changes to support any other SoCs than SH7724.
> >
> > Signed-off-by: Geert Uytterhoeven <[email protected]>
> > Cc: Rob Herring <[email protected]>
> > Cc: Krzysztof Kozlowski <[email protected]>
> > Cc: Conor Dooley <[email protected]>
> > Cc: [email protected]
> > ---
> > SH-Mobile AG5 (SH73A0) support is untested.
> >
> > Unbind crashes when drm_encoder_cleanup() calls drm_bridge_detach(), as
> > the bridge (allocated by devm_drm_panel_bridge_add()) has already been
> > freed by that time.
> > Should I allocate my encoder with devm_kzalloc(), instead of embedding
> > it inside struct shmob_drm_device?
>
> That shouldn't be needed, if you manage the memory for shmob_drm_device
> with the DRM managed helpers.
>
> Lifetime management of bridges is currently completely broken, there's
> nothing that prevents bridges from being freed while still in use.
> That's an issue in DRM, not in your driver.
>
> > ---
> > .../gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 101 +++++++++++++++---
> > .../gpu/drm/renesas/shmobile/shmob_drm_crtc.h | 1 +
> > .../gpu/drm/renesas/shmobile/shmob_drm_drv.c | 27 ++++-
> > .../gpu/drm/renesas/shmobile/shmob_drm_drv.h | 6 ++
> > 4 files changed, 118 insertions(+), 17 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> > index 17456dde57637ab8..1ec87841658de4f0 100644
> > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> > @@ -9,12 +9,16 @@
> >
> > #include <linux/clk.h>
> > #include <linux/media-bus-format.h>
> > +#include <linux/of.h>
> > +#include <linux/of_graph.h>
> > #include <linux/pm_runtime.h>
> >
> > #include <drm/drm_atomic.h>
> > #include <drm/drm_atomic_helper.h>
> > #include <drm/drm_atomic_state_helper.h>
> > #include <drm/drm_atomic_uapi.h>
> > +#include <drm/drm_bridge.h>
> > +#include <drm/drm_bridge_connector.h>
> > #include <drm/drm_crtc.h>
> > #include <drm/drm_crtc_helper.h>
> > #include <drm/drm_fb_dma_helper.h>
> > @@ -23,6 +27,7 @@
> > #include <drm/drm_gem_dma_helper.h>
> > #include <drm/drm_modeset_helper.h>
> > #include <drm/drm_modeset_helper_vtables.h>
> > +#include <drm/drm_panel.h>
> > #include <drm/drm_probe_helper.h>
> > #include <drm/drm_simple_kms_helper.h>
> > #include <drm/drm_vblank.h>
> > @@ -35,10 +40,6 @@
> > #include "shmob_drm_plane.h"
> > #include "shmob_drm_regs.h"
> >
> > -/*
> > - * TODO: panel support
> > - */
> > -
> > /* -----------------------------------------------------------------------------
> > * Clock management
> > */
> > @@ -129,7 +130,6 @@ static void shmob_drm_crtc_setup_geometry(struct shmob_drm_crtc *scrtc)
> > value |= LDMT1R_VPOL;
> > if (mode->flags & DRM_MODE_FLAG_NHSYNC)
> > value |= LDMT1R_HPOL;
> > -
>
> This could be moved to one of the patches in the series that touch this
> code.
>
> > lcdc_write(sdev, LDMT1R, value);
> >
> > value = ((mode->hdisplay / 8) << 16) /* HDCN */
> > @@ -191,7 +191,7 @@ static void shmob_drm_crtc_start(struct shmob_drm_crtc *scrtc)
> > {
> > struct drm_crtc *crtc = &scrtc->base;
> > struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);
> > - const struct shmob_drm_interface_data *idata = &sdev->pdata->iface;
> > + unsigned int clk_div = sdev->config.clk_div;
> > struct device *dev = sdev->dev;
> > u32 value;
> > int ret;
> > @@ -220,17 +220,17 @@ static void shmob_drm_crtc_start(struct shmob_drm_crtc *scrtc)
> > lcdc_write(sdev, LDPMR, 0);
> >
> > value = sdev->lddckr;
> > - if (idata->clk_div) {
> > + if (clk_div) {
> > /* FIXME: sh7724 can only use 42, 48, 54 and 60 for the divider
> > * denominator.
> > */
> > lcdc_write(sdev, LDDCKPAT1R, 0);
> > - lcdc_write(sdev, LDDCKPAT2R, (1 << (idata->clk_div / 2)) - 1);
> > + lcdc_write(sdev, LDDCKPAT2R, (1 << (clk_div / 2)) - 1);
> >
> > - if (idata->clk_div == 1)
> > + if (clk_div == 1)
> > value |= LDDCKR_MOSEL;
> > else
> > - value |= idata->clk_div;
> > + value |= clk_div;
> > }
> >
> > lcdc_write(sdev, LDDCKR, value);
> > @@ -479,7 +479,7 @@ int shmob_drm_crtc_create(struct shmob_drm_device *sdev)
> > }
> >
> > /* -----------------------------------------------------------------------------
> > - * Encoder
> > + * Legacy Encoder
> > */
> >
> > static bool shmob_drm_encoder_mode_fixup(struct drm_encoder *encoder,
> > @@ -508,9 +508,43 @@ static const struct drm_encoder_helper_funcs encoder_helper_funcs = {
> > .mode_fixup = shmob_drm_encoder_mode_fixup,
> > };
> >
> > +/* -----------------------------------------------------------------------------
> > + * Encoder
> > + */
> > +
> > +static int shmob_drm_encoder_init(struct shmob_drm_device *sdev,
> > + struct device_node *enc_node)
> > +{
> > + struct drm_bridge *bridge;
> > + struct drm_panel *panel;
> > + int ret;
> > +
> > + /* Create a panel bridge */
> > + panel = of_drm_find_panel(enc_node);
>
> Using drm_of_find_panel_or_bridge() would allow supporting platforms
> that connect a non-panel device to the SoC, in additional to the already
> supported panels.

From the documentation of drm_of_find_panel_or_bridge():

* This function is deprecated and should not be used in new drivers. Use
* devm_drm_of_get_bridge() instead.

I suggest to go that route.

> > @@ -147,11 +148,13 @@ static int shmob_drm_remove(struct platform_device *pdev)
> > static int shmob_drm_probe(struct platform_device *pdev)
> > {
> > struct shmob_drm_platform_data *pdata = pdev->dev.platform_data;
>
> How about dropping non-DT support ? That would simplify the driver.
+1 for that, without knowing the implications.

Sam

2023-06-23 18:34:57

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH 39/39] drm: renesas: shmobile: Add DT support

Hi Sam, Laurent,

On Fri, Jun 23, 2023 at 7:54 PM Sam Ravnborg <[email protected]> wrote:
> On Fri, Jun 23, 2023 at 08:50:19PM +0300, Laurent Pinchart wrote:
> > On Thu, Jun 22, 2023 at 11:21:51AM +0200, Geert Uytterhoeven wrote:
> > > Add DT support, by:
> > > 1. Creating a panel bridge from DT, and attaching it to the encoder,
> > > 2. Replacing the custom connector with a bridge connector,
> > > 3. Obtaining clock configuration based on the compatible value.
> > >
> > > Note that for now the driver uses a fixed clock configuration selecting
> > > the bus clock, as the current code to select other clock inputs needs
> > > changes to support any other SoCs than SH7724.
> > >
> > > Signed-off-by: Geert Uytterhoeven <[email protected]>
> > > Cc: Rob Herring <[email protected]>
> > > Cc: Krzysztof Kozlowski <[email protected]>
> > > Cc: Conor Dooley <[email protected]>
> > > Cc: [email protected]
> > > ---
> > > SH-Mobile AG5 (SH73A0) support is untested.
> > >
> > > Unbind crashes when drm_encoder_cleanup() calls drm_bridge_detach(), as
> > > the bridge (allocated by devm_drm_panel_bridge_add()) has already been
> > > freed by that time.
> > > Should I allocate my encoder with devm_kzalloc(), instead of embedding
> > > it inside struct shmob_drm_device?
> >
> > That shouldn't be needed, if you manage the memory for shmob_drm_device
> > with the DRM managed helpers.

Well, Marek said unbind works fine in drivers/gpu/drm/mxsfb/lcdif_drv.c,
where the order is:

bridge = devm_drm_of_get_bridge(...)
encoder = devm_kzalloc(...)
drm_encoder_init(...)

> > Lifetime management of bridges is currently completely broken, there's
> > nothing that prevents bridges from being freed while still in use.
> > That's an issue in DRM, not in your driver.

OK ;-) (or :-(

> > > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> > > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> > > @@ -508,9 +508,43 @@ static const struct drm_encoder_helper_funcs encoder_helper_funcs = {
> > > .mode_fixup = shmob_drm_encoder_mode_fixup,
> > > };
> > >
> > > +/* -----------------------------------------------------------------------------
> > > + * Encoder
> > > + */
> > > +
> > > +static int shmob_drm_encoder_init(struct shmob_drm_device *sdev,
> > > + struct device_node *enc_node)
> > > +{
> > > + struct drm_bridge *bridge;
> > > + struct drm_panel *panel;
> > > + int ret;
> > > +
> > > + /* Create a panel bridge */
> > > + panel = of_drm_find_panel(enc_node);
> >
> > Using drm_of_find_panel_or_bridge() would allow supporting platforms
> > that connect a non-panel device to the SoC, in additional to the already
> > supported panels.
>
> From the documentation of drm_of_find_panel_or_bridge():
>
> * This function is deprecated and should not be used in new drivers. Use
> * devm_drm_of_get_bridge() instead.
>
> I suggest to go that route.

OK (do I have the feeling that these helpers are sometimes deprecated
faster than they are written? ;-)

> > > @@ -147,11 +148,13 @@ static int shmob_drm_remove(struct platform_device *pdev)
> > > static int shmob_drm_probe(struct platform_device *pdev)
> > > {
> > > struct shmob_drm_platform_data *pdata = pdev->dev.platform_data;
> >
> > How about dropping non-DT support ? That would simplify the driver.
>
> +1 for that, without knowing the implications.

That depends on your priorities: do you want to migrate all users of
sh_mobile_lcdc_fb to shmob_drm, or do you want the SuperH users to
stick with sh_mobile_lcdc_fb until they have migrated to DT? ;-)

Regardless of the above, I do not have (visible) access to any of the
affected SH772[234] platforms...

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

2023-06-23 19:27:20

by Laurent Pinchart

[permalink] [raw]
Subject: Re: [PATCH 24/39] drm: renesas: shmobile: Unify plane allocation

On Fri, Jun 23, 2023 at 07:55:22PM +0200, Geert Uytterhoeven wrote:
> On Fri, Jun 23, 2023 at 6:50 PM Laurent Pinchart wrote:
> > On Thu, Jun 22, 2023 at 11:21:36AM +0200, Geert Uytterhoeven wrote:
> > > Unify primary and overlay plane allocation:
> > > - Enhance shmob_drm_plane_create() so it can be used to create the
> > > primary plane, too,
> > > - Move overlay plane creation next to primary plane creation.
> > >
> > > As overlay plane index zero now means the primary plane, this requires
> > > shifting all overlay plane indices by one.
> >
> > Do you use index zero to identify the primary plane just for
> > shmob_drm_plane_create(), or somewhere else too ? If it's just to create
> > the plane, you could instead pass the plane type to the function.
>
> Index zero is just used for the creation.
> I guess this sort of goes together with my question below...
>
> > > Signed-off-by: Geert Uytterhoeven <[email protected]>
> > > ---
> > > Perhaps it would be better to not use dynamic allocation, but store
> > > "struct drm_plane primary" and "struct shmob_drm_plane planes[5]" in
> > > struct drm_shmob_device instead, like is done for the crtc and encoder?
>
> ... as embedding separate primary and planes[] would also get rid of
> the need to adjust the plane indices when converting from logical to physical
> overlay plane indices.

Do they need to be embedded for that, or could you simple keep the index
as it is ?

--
Regards,

Laurent Pinchart

2023-06-23 19:32:54

by Laurent Pinchart

[permalink] [raw]
Subject: Re: [PATCH 39/39] drm: renesas: shmobile: Add DT support

On Fri, Jun 23, 2023 at 08:09:53PM +0200, Geert Uytterhoeven wrote:
> On Fri, Jun 23, 2023 at 7:54 PM Sam Ravnborg <[email protected]> wrote:
> > On Fri, Jun 23, 2023 at 08:50:19PM +0300, Laurent Pinchart wrote:
> > > On Thu, Jun 22, 2023 at 11:21:51AM +0200, Geert Uytterhoeven wrote:
> > > > Add DT support, by:
> > > > 1. Creating a panel bridge from DT, and attaching it to the encoder,
> > > > 2. Replacing the custom connector with a bridge connector,
> > > > 3. Obtaining clock configuration based on the compatible value.
> > > >
> > > > Note that for now the driver uses a fixed clock configuration selecting
> > > > the bus clock, as the current code to select other clock inputs needs
> > > > changes to support any other SoCs than SH7724.
> > > >
> > > > Signed-off-by: Geert Uytterhoeven <[email protected]>
> > > > Cc: Rob Herring <[email protected]>
> > > > Cc: Krzysztof Kozlowski <[email protected]>
> > > > Cc: Conor Dooley <[email protected]>
> > > > Cc: [email protected]
> > > > ---
> > > > SH-Mobile AG5 (SH73A0) support is untested.
> > > >
> > > > Unbind crashes when drm_encoder_cleanup() calls drm_bridge_detach(), as
> > > > the bridge (allocated by devm_drm_panel_bridge_add()) has already been
> > > > freed by that time.
> > > > Should I allocate my encoder with devm_kzalloc(), instead of embedding
> > > > it inside struct shmob_drm_device?
> > >
> > > That shouldn't be needed, if you manage the memory for shmob_drm_device
> > > with the DRM managed helpers.
>
> Well, Marek said unbind works fine in drivers/gpu/drm/mxsfb/lcdif_drv.c,
> where the order is:
>
> bridge = devm_drm_of_get_bridge(...)
> encoder = devm_kzalloc(...)
> drm_encoder_init(...)
>
> > > Lifetime management of bridges is currently completely broken, there's
> > > nothing that prevents bridges from being freed while still in use.
> > > That's an issue in DRM, not in your driver.
>
> OK ;-) (or :-(
>
> > > > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> > > > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> > > > @@ -508,9 +508,43 @@ static const struct drm_encoder_helper_funcs encoder_helper_funcs = {
> > > > .mode_fixup = shmob_drm_encoder_mode_fixup,
> > > > };
> > > >
> > > > +/* -----------------------------------------------------------------------------
> > > > + * Encoder
> > > > + */
> > > > +
> > > > +static int shmob_drm_encoder_init(struct shmob_drm_device *sdev,
> > > > + struct device_node *enc_node)
> > > > +{
> > > > + struct drm_bridge *bridge;
> > > > + struct drm_panel *panel;
> > > > + int ret;
> > > > +
> > > > + /* Create a panel bridge */
> > > > + panel = of_drm_find_panel(enc_node);
> > >
> > > Using drm_of_find_panel_or_bridge() would allow supporting platforms
> > > that connect a non-panel device to the SoC, in additional to the already
> > > supported panels.
> >
> > From the documentation of drm_of_find_panel_or_bridge():
> >
> > * This function is deprecated and should not be used in new drivers. Use
> > * devm_drm_of_get_bridge() instead.

Indeed, my bad/ devm_drm_of_get_bridge() is better.

> > I suggest to go that route.
>
> OK (do I have the feeling that these helpers are sometimes deprecated
> faster than they are written? ;-)
>
> > > > @@ -147,11 +148,13 @@ static int shmob_drm_remove(struct platform_device *pdev)
> > > > static int shmob_drm_probe(struct platform_device *pdev)
> > > > {
> > > > struct shmob_drm_platform_data *pdata = pdev->dev.platform_data;
> > >
> > > How about dropping non-DT support ? That would simplify the driver.
> >
> > +1 for that, without knowing the implications.
>
> That depends on your priorities: do you want to migrate all users of
> sh_mobile_lcdc_fb to shmob_drm, or do you want the SuperH users to
> stick with sh_mobile_lcdc_fb until they have migrated to DT? ;-)

I'd vote for dropping LCDC support from the SH users. Does anyone
*really* need it ? If they do, they should convert the board to DT.

> Regardless of the above, I do not have (visible) access to any of the
> affected SH772[234] platforms...

--
Regards,

Laurent Pinchart

2023-06-24 09:50:53

by Sui Jingfeng

[permalink] [raw]
Subject: Re: [28/39] drm: renesas: shmobile: Use drm_crtc_handle_vblank()

Hi,


I'm fine with this patch but I I don't see the benefit.

This reply is more about my personal question.


On 2023/6/22 17:21, Geert Uytterhoeven wrote:
> Replace the call to the legacy drm_handle_vblank() function with a call
> to the new drm_crtc_handle_vblank() helper.
>
> Signed-off-by: Geert Uytterhoeven <[email protected]>
> Reviewed-by: Laurent Pinchart <[email protected]>
Reviewed-by: Sui Jingfeng <[email protected]>
> ---
> drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> index c98e2bdd888c3274..6eaf2c5a104f451a 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> @@ -86,7 +86,7 @@ static irqreturn_t shmob_drm_irq(int irq, void *arg)
> spin_unlock_irqrestore(&sdev->irq_lock, flags);
>
> if (status & LDINTR_VES) {
> - drm_handle_vblank(dev, 0);
> + drm_crtc_handle_vblank(&sdev->crtc.base);


After switching to drm_crtc_handle_vblank(),

your driver need another deference to the pointer of 'struct drm_crtc'
to get the pointer of 'struct drm_device';

Plus another call to get the index(display pipe) of the CRTC by calling
drm_crtc_index(crtc).


Consider that shmob-drm support only one display pipe,

is it that the switching is less straight forward than the original
implement ?


```

/**
 * drm_crtc_handle_vblank - handle a vblank event
 * @crtc: where this event occurred
 *
 * Drivers should call this routine in their vblank interrupt handlers to
 * update the vblank counter and send any signals that may be pending.
 *
 * This is the native KMS version of drm_handle_vblank().
 *
 * Note that for a given vblank counter value drm_crtc_handle_vblank()
 * and drm_crtc_vblank_count() or drm_crtc_vblank_count_and_time()
 * provide a barrier: Any writes done before calling
 * drm_crtc_handle_vblank() will be visible to callers of the later
 * functions, if the vblank count is the same or a later one.
 *
 * See also &drm_vblank_crtc.count.
 *
 * Returns:
 * True if the event was successfully handled, false on failure.
 */
bool drm_crtc_handle_vblank(struct drm_crtc *crtc)
{
    return drm_handle_vblank(crtc->dev, drm_crtc_index(crtc));
}

```

Is it that drm_crtc_handle_vblank() function is preferred over
drm_handle_vblank() in the future?

I'm fine with this question answered.


> shmob_drm_crtc_finish_page_flip(&sdev->crtc);
> }
>

--
Jingfeng


2023-06-24 10:07:37

by Sui Jingfeng

[permalink] [raw]
Subject: Re: [20/39] drm: renesas: shmobile: Replace .dev_private with container_of()

Hi,

On 2023/6/22 17:21, Geert Uytterhoeven wrote:
> Now that drm_device is embedded in shmob_drm_device, we can use
> a container_of()-based helper to get the shmob_drm_device pointer from
> the drm_device, instead of using the deprecated drm_device.dev_private
> field.
>
> While at it, restore reverse Xmas tree ordering of local variable
> declarations.
>
> Signed-off-by: Geert Uytterhoeven <[email protected]>
> Reviewed-by: Laurent Pinchart <[email protected]>

Reviewed-by: Sui Jingfeng <[email protected]>

> ---
> .../gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 20 +++++++++----------
> .../gpu/drm/renesas/shmobile/shmob_drm_drv.c | 4 +---
> .../gpu/drm/renesas/shmobile/shmob_drm_drv.h | 5 +++++
> .../drm/renesas/shmobile/shmob_drm_plane.c | 6 +++---
> 4 files changed, 19 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> index 40948b56017ff2df..291b3a5014c24f08 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> @@ -63,7 +63,7 @@ static void shmob_drm_clk_off(struct shmob_drm_device *sdev)
> static void shmob_drm_crtc_setup_geometry(struct shmob_drm_crtc *scrtc)
> {
> struct drm_crtc *crtc = &scrtc->crtc;
> - struct shmob_drm_device *sdev = crtc->dev->dev_private;
> + struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);
> const struct shmob_drm_interface_data *idata = &sdev->pdata->iface;
> const struct drm_display_mode *mode = &crtc->mode;
> u32 value;
> @@ -102,7 +102,7 @@ static void shmob_drm_crtc_setup_geometry(struct shmob_drm_crtc *scrtc)
>
> static void shmob_drm_crtc_start_stop(struct shmob_drm_crtc *scrtc, bool start)
> {
> - struct shmob_drm_device *sdev = scrtc->crtc.dev->dev_private;
> + struct shmob_drm_device *sdev = to_shmob_device(scrtc->crtc.dev);
> u32 value;
>
> value = lcdc_read(sdev, LDCNT2R);
> @@ -136,7 +136,7 @@ static void shmob_drm_crtc_start_stop(struct shmob_drm_crtc *scrtc, bool start)
> static void shmob_drm_crtc_start(struct shmob_drm_crtc *scrtc)
> {
> struct drm_crtc *crtc = &scrtc->crtc;
> - struct shmob_drm_device *sdev = crtc->dev->dev_private;
> + struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);
> const struct shmob_drm_interface_data *idata = &sdev->pdata->iface;
> const struct shmob_drm_format_info *format;
> struct drm_device *dev = &sdev->ddev;
> @@ -223,7 +223,7 @@ static void shmob_drm_crtc_start(struct shmob_drm_crtc *scrtc)
> static void shmob_drm_crtc_stop(struct shmob_drm_crtc *scrtc)
> {
> struct drm_crtc *crtc = &scrtc->crtc;
> - struct shmob_drm_device *sdev = crtc->dev->dev_private;
> + struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);
>
> if (!scrtc->started)
> return;
> @@ -280,7 +280,7 @@ static void shmob_drm_crtc_compute_base(struct shmob_drm_crtc *scrtc,
> static void shmob_drm_crtc_update_base(struct shmob_drm_crtc *scrtc)
> {
> struct drm_crtc *crtc = &scrtc->crtc;
> - struct shmob_drm_device *sdev = crtc->dev->dev_private;
> + struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);
>
> shmob_drm_crtc_compute_base(scrtc, crtc->x, crtc->y);
>
> @@ -322,8 +322,8 @@ static int shmob_drm_crtc_mode_set(struct drm_crtc *crtc,
> int x, int y,
> struct drm_framebuffer *old_fb)
> {
> + struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);
> struct shmob_drm_crtc *scrtc = to_shmob_crtc(crtc);
> - struct shmob_drm_device *sdev = crtc->dev->dev_private;
> const struct shmob_drm_format_info *format;
>
> format = shmob_drm_format_info(crtc->primary->fb->format->format);
> @@ -428,7 +428,7 @@ static void shmob_drm_crtc_enable_vblank(struct shmob_drm_device *sdev,
>
> static int shmob_drm_enable_vblank(struct drm_crtc *crtc)
> {
> - struct shmob_drm_device *sdev = crtc->dev->dev_private;
> + struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);
>
> shmob_drm_crtc_enable_vblank(sdev, true);
>
> @@ -437,7 +437,7 @@ static int shmob_drm_enable_vblank(struct drm_crtc *crtc)
>
> static void shmob_drm_disable_vblank(struct drm_crtc *crtc)
> {
> - struct shmob_drm_device *sdev = crtc->dev->dev_private;
> + struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);
>
> shmob_drm_crtc_enable_vblank(sdev, false);
> }
> @@ -511,7 +511,7 @@ static bool shmob_drm_encoder_mode_fixup(struct drm_encoder *encoder,
> struct drm_display_mode *adjusted_mode)
> {
> struct drm_device *dev = encoder->dev;
> - struct shmob_drm_device *sdev = dev->dev_private;
> + struct shmob_drm_device *sdev = to_shmob_device(dev);
> struct drm_connector *connector = &sdev->connector.connector;
> const struct drm_display_mode *panel_mode;
>
> @@ -581,7 +581,7 @@ static inline struct shmob_drm_connector *to_shmob_connector(struct drm_connecto
>
> static int shmob_drm_connector_get_modes(struct drm_connector *connector)
> {
> - struct shmob_drm_device *sdev = connector->dev->dev_private;
> + struct shmob_drm_device *sdev = to_shmob_device(connector->dev);
> struct drm_display_mode *mode;
>
> mode = drm_mode_create(connector->dev);
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> index 2b77af3a8c97ef8c..1a1d66c6e817e227 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> @@ -95,7 +95,7 @@ static int shmob_drm_setup_clocks(struct shmob_drm_device *sdev,
> static irqreturn_t shmob_drm_irq(int irq, void *arg)
> {
> struct drm_device *dev = arg;
> - struct shmob_drm_device *sdev = dev->dev_private;
> + struct shmob_drm_device *sdev = to_shmob_device(dev);
> unsigned long flags;
> u32 status;
>
> @@ -217,8 +217,6 @@ static int shmob_drm_probe(struct platform_device *pdev)
> if (ret < 0)
> return ret;
>
> - ddev->dev_private = sdev;
> -
> ret = shmob_drm_modeset_init(sdev);
> if (ret < 0)
> return dev_err_probe(&pdev->dev, ret,
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.h b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.h
> index 77bb0da48f37ace8..5e55ba7a207865bd 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.h
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.h
> @@ -39,4 +39,9 @@ struct shmob_drm_device {
> struct shmob_drm_connector connector;
> };
>
> +static inline struct shmob_drm_device *to_shmob_device(struct drm_device *dev)
> +{
> + return container_of(dev, struct shmob_drm_device, ddev);
> +}
> +
> #endif /* __SHMOB_DRM_DRV_H__ */
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
> index 258288c80756bf16..c58b9dca34736342 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
> @@ -63,7 +63,7 @@ static void shmob_drm_plane_compute_base(struct shmob_drm_plane *splane,
> static void __shmob_drm_plane_setup(struct shmob_drm_plane *splane,
> struct drm_framebuffer *fb)
> {
> - struct shmob_drm_device *sdev = splane->plane.dev->dev_private;
> + struct shmob_drm_device *sdev = to_shmob_device(splane->plane.dev);
> u32 format;
>
> /* TODO: Support ROP3 mode */
> @@ -135,8 +135,8 @@ shmob_drm_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
> uint32_t src_w, uint32_t src_h,
> struct drm_modeset_acquire_ctx *ctx)
> {
> + struct shmob_drm_device *sdev = to_shmob_device(plane->dev);
> struct shmob_drm_plane *splane = to_shmob_plane(plane);
> - struct shmob_drm_device *sdev = plane->dev->dev_private;
> const struct shmob_drm_format_info *format;
>
> format = shmob_drm_format_info(fb->format->format);
> @@ -167,8 +167,8 @@ shmob_drm_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
> static int shmob_drm_plane_disable(struct drm_plane *plane,
> struct drm_modeset_acquire_ctx *ctx)
> {
> + struct shmob_drm_device *sdev = to_shmob_device(plane->dev);
> struct shmob_drm_plane *splane = to_shmob_plane(plane);
> - struct shmob_drm_device *sdev = plane->dev->dev_private;
>
> splane->format = NULL;
>

--
Jingfeng


2023-06-25 09:55:25

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [28/39] drm: renesas: shmobile: Use drm_crtc_handle_vblank()

Hi Sui,

On Sat, Jun 24, 2023 at 11:33 AM Sui Jingfeng <[email protected]> wrote:
> I'm fine with this patch but I I don't see the benefit.
>
> This reply is more about my personal question.
>
> On 2023/6/22 17:21, Geert Uytterhoeven wrote:
> > Replace the call to the legacy drm_handle_vblank() function with a call
> > to the new drm_crtc_handle_vblank() helper.
> >
> > Signed-off-by: Geert Uytterhoeven <[email protected]>
> > Reviewed-by: Laurent Pinchart <[email protected]>
> Reviewed-by: Sui Jingfeng <[email protected]>
> > ---
> > drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c | 2 +-
> > 1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> > index c98e2bdd888c3274..6eaf2c5a104f451a 100644
> > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> > @@ -86,7 +86,7 @@ static irqreturn_t shmob_drm_irq(int irq, void *arg)
> > spin_unlock_irqrestore(&sdev->irq_lock, flags);
> >
> > if (status & LDINTR_VES) {
> > - drm_handle_vblank(dev, 0);
> > + drm_crtc_handle_vblank(&sdev->crtc.base);
>
>
> After switching to drm_crtc_handle_vblank(),
>
> your driver need another deference to the pointer of 'struct drm_crtc'
> to get the pointer of 'struct drm_device';
>
> Plus another call to get the index(display pipe) of the CRTC by calling
> drm_crtc_index(crtc).

That is correct.

> Consider that shmob-drm support only one display pipe,
>
> is it that the switching is less straight forward than the original
> implement ?
>
>
> ```
>
> /**
> * drm_crtc_handle_vblank - handle a vblank event
> * @crtc: where this event occurred
> *
> * Drivers should call this routine in their vblank interrupt handlers to
> * update the vblank counter and send any signals that may be pending.
> *
> * This is the native KMS version of drm_handle_vblank().
> *
> * Note that for a given vblank counter value drm_crtc_handle_vblank()
> * and drm_crtc_vblank_count() or drm_crtc_vblank_count_and_time()
> * provide a barrier: Any writes done before calling
> * drm_crtc_handle_vblank() will be visible to callers of the later
> * functions, if the vblank count is the same or a later one.
> *
> * See also &drm_vblank_crtc.count.
> *
> * Returns:
> * True if the event was successfully handled, false on failure.
> */
> bool drm_crtc_handle_vblank(struct drm_crtc *crtc)
> {
> return drm_handle_vblank(crtc->dev, drm_crtc_index(crtc));
> }
>
> ```
>
> Is it that drm_crtc_handle_vblank() function is preferred over
> drm_handle_vblank() in the future?
>
> I'm fine with this question answered.

I think the native KMS version is preferred over the legacy version, cfr.

/**
* drm_handle_vblank - handle a vblank event
[...]
* This is the legacy version of drm_crtc_handle_vblank().
*/
bool drm_handle_vblank(struct drm_device *dev, unsigned int pipe)

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

2023-06-25 09:55:31

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH 24/39] drm: renesas: shmobile: Unify plane allocation

Hi Laurent,

On Fri, Jun 23, 2023 at 8:50 PM Laurent Pinchart
<[email protected]> wrote:
> On Fri, Jun 23, 2023 at 07:55:22PM +0200, Geert Uytterhoeven wrote:
> > On Fri, Jun 23, 2023 at 6:50 PM Laurent Pinchart wrote:
> > > On Thu, Jun 22, 2023 at 11:21:36AM +0200, Geert Uytterhoeven wrote:
> > > > Unify primary and overlay plane allocation:
> > > > - Enhance shmob_drm_plane_create() so it can be used to create the
> > > > primary plane, too,
> > > > - Move overlay plane creation next to primary plane creation.
> > > >
> > > > As overlay plane index zero now means the primary plane, this requires
> > > > shifting all overlay plane indices by one.
> > >
> > > Do you use index zero to identify the primary plane just for
> > > shmob_drm_plane_create(), or somewhere else too ? If it's just to create
> > > the plane, you could instead pass the plane type to the function.
> >
> > Index zero is just used for the creation.
> > I guess this sort of goes together with my question below...
> >
> > > > Signed-off-by: Geert Uytterhoeven <[email protected]>
> > > > ---
> > > > Perhaps it would be better to not use dynamic allocation, but store
> > > > "struct drm_plane primary" and "struct shmob_drm_plane planes[5]" in
> > > > struct drm_shmob_device instead, like is done for the crtc and encoder?
> >
> > ... as embedding separate primary and planes[] would also get rid of
> > the need to adjust the plane indices when converting from logical to physical
> > overlay plane indices.
>
> Do they need to be embedded for that, or could you simple keep the index
> as it is ?

If the plane type would be passed explicitly, they would not need to be
embedded for that.

Then the question becomes: does it make sense to unify primary and
overlay plane handling?

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

2023-06-25 17:39:54

by Laurent Pinchart

[permalink] [raw]
Subject: Re: [PATCH 24/39] drm: renesas: shmobile: Unify plane allocation

On Sun, Jun 25, 2023 at 10:58:17AM +0200, Geert Uytterhoeven wrote:
> On Fri, Jun 23, 2023 at 8:50 PM Laurent Pinchart wrote:
> > On Fri, Jun 23, 2023 at 07:55:22PM +0200, Geert Uytterhoeven wrote:
> > > On Fri, Jun 23, 2023 at 6:50 PM Laurent Pinchart wrote:
> > > > On Thu, Jun 22, 2023 at 11:21:36AM +0200, Geert Uytterhoeven wrote:
> > > > > Unify primary and overlay plane allocation:
> > > > > - Enhance shmob_drm_plane_create() so it can be used to create the
> > > > > primary plane, too,
> > > > > - Move overlay plane creation next to primary plane creation.
> > > > >
> > > > > As overlay plane index zero now means the primary plane, this requires
> > > > > shifting all overlay plane indices by one.
> > > >
> > > > Do you use index zero to identify the primary plane just for
> > > > shmob_drm_plane_create(), or somewhere else too ? If it's just to create
> > > > the plane, you could instead pass the plane type to the function.
> > >
> > > Index zero is just used for the creation.
> > > I guess this sort of goes together with my question below...
> > >
> > > > > Signed-off-by: Geert Uytterhoeven <[email protected]>
> > > > > ---
> > > > > Perhaps it would be better to not use dynamic allocation, but store
> > > > > "struct drm_plane primary" and "struct shmob_drm_plane planes[5]" in
> > > > > struct drm_shmob_device instead, like is done for the crtc and encoder?
> > >
> > > ... as embedding separate primary and planes[] would also get rid of
> > > the need to adjust the plane indices when converting from logical to physical
> > > overlay plane indices.
> >
> > Do they need to be embedded for that, or could you simple keep the index
> > as it is ?
>
> If the plane type would be passed explicitly, they would not need to be
> embedded for that.
>
> Then the question becomes: does it make sense to unify primary and
> overlay plane handling?

Good point. I don't mind much either way, it depends on how much code
duplication it would remove I suppose.

--
Regards,

Laurent Pinchart

2023-06-27 15:02:51

by Sui Jingfeng

[permalink] [raw]
Subject: Re: [26/39] drm: renesas: shmobile: Rename shmob_drm_connector.connector


On 2023/6/22 17:21, Geert Uytterhoeven wrote:
> Rename the "connector" member of the shmob_drm_connector subclass
> structure to "base", to improve readability.
>
> Signed-off-by: Geert Uytterhoeven <[email protected]>
> Reviewed-by: Laurent Pinchart <[email protected]>

Reviewed-by: Sui Jingfeng <[email protected]>

> ---
> drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 4 ++--
> drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h | 2 +-
> 2 files changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> index 3f0b71253ed929c9..2c0ca802d36026f4 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> @@ -608,7 +608,7 @@ int shmob_drm_encoder_create(struct shmob_drm_device *sdev)
>
> static inline struct shmob_drm_connector *to_shmob_connector(struct drm_connector *connector)
> {
> - return container_of(connector, struct shmob_drm_connector, connector);
> + return container_of(connector, struct shmob_drm_connector, base);
> }
>
> static int shmob_drm_connector_get_modes(struct drm_connector *connector)
> @@ -669,7 +669,7 @@ shmob_drm_connector_init(struct shmob_drm_device *sdev,
> if (!scon)
> return ERR_PTR(-ENOMEM);
>
> - connector = &scon->connector;
> + connector = &scon->base;
> info = &connector->display_info;
> info->width_mm = sdev->pdata->panel.width_mm;
> info->height_mm = sdev->pdata->panel.height_mm;
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
> index 79cce0a0ada4cfce..2c6d7541427581a6 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
> @@ -33,7 +33,7 @@ struct shmob_drm_crtc {
> };
>
> struct shmob_drm_connector {
> - struct drm_connector connector;
> + struct drm_connector base;
> struct drm_encoder *encoder;
> const struct videomode *mode;
> };

--
Jingfeng


2023-06-27 15:06:34

by Sui Jingfeng

[permalink] [raw]
Subject: Re: [27/39] drm: renesas: shmobile: Rename shmob_drm_plane.plane


On 2023/6/22 17:21, Geert Uytterhoeven wrote:
> Rename the "plane" member of the shmob_drm_plane subclass structure to
> "base", to improve readability.
>
> Signed-off-by: Geert Uytterhoeven <[email protected]>
> Reviewed-by: Laurent Pinchart <[email protected]>

Reviewed-by: Sui Jingfeng <[email protected]>

> ---
> drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c | 10 +++++-----
> 1 file changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
> index 63886015baaebfc0..e300e5c0de70a9b1 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
> @@ -20,7 +20,7 @@
> #include "shmob_drm_regs.h"
>
> struct shmob_drm_plane {
> - struct drm_plane plane;
> + struct drm_plane base;
> unsigned int index;
> unsigned int alpha;
>
> @@ -37,7 +37,7 @@ struct shmob_drm_plane {
>
> static inline struct shmob_drm_plane *to_shmob_plane(struct drm_plane *plane)
> {
> - return container_of(plane, struct shmob_drm_plane, plane);
> + return container_of(plane, struct shmob_drm_plane, base);
> }
>
> static void shmob_drm_plane_compute_base(struct shmob_drm_plane *splane,
> @@ -64,7 +64,7 @@ static void shmob_drm_plane_compute_base(struct shmob_drm_plane *splane,
> static void __shmob_drm_plane_setup(struct shmob_drm_plane *splane,
> struct drm_framebuffer *fb)
> {
> - struct shmob_drm_device *sdev = to_shmob_device(splane->plane.dev);
> + struct shmob_drm_device *sdev = to_shmob_device(splane->base.dev);
> unsigned int ovl_idx = splane->index - 1;
> u32 format;
>
> @@ -221,7 +221,7 @@ struct drm_plane *shmob_drm_plane_create(struct shmob_drm_device *sdev,
> }
>
> splane = drmm_universal_plane_alloc(&sdev->ddev,
> - struct shmob_drm_plane, plane, 1,
> + struct shmob_drm_plane, base, 1,
> funcs, formats,
> ARRAY_SIZE(formats), NULL, type,
> NULL);
> @@ -231,5 +231,5 @@ struct drm_plane *shmob_drm_plane_create(struct shmob_drm_device *sdev,
> splane->index = index;
> splane->alpha = 255;
>
> - return &splane->plane;
> + return &splane->base;
> }

--
Jingfeng


2023-06-27 15:08:44

by Sui Jingfeng

[permalink] [raw]
Subject: Re: [25/39] drm: renesas: shmobile: Rename shmob_drm_crtc.crtc


On 2023/6/22 17:21, Geert Uytterhoeven wrote:
> Rename the "crtc" member of the shmob_drm_crtc subclass structure to
> "base", to improve readability.
>
> Signed-off-by: Geert Uytterhoeven <[email protected]>
> Reviewed-by: Laurent Pinchart <[email protected]>


Reviewed-by: Sui Jingfeng <[email protected]>

> ---
> .../gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 26 +++++++++----------
> .../gpu/drm/renesas/shmobile/shmob_drm_crtc.h | 2 +-
> 2 files changed, 14 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> index 3f6af12f45988124..3f0b71253ed929c9 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> @@ -64,7 +64,7 @@ static void shmob_drm_clk_off(struct shmob_drm_device *sdev)
>
> static void shmob_drm_crtc_setup_geometry(struct shmob_drm_crtc *scrtc)
> {
> - struct drm_crtc *crtc = &scrtc->crtc;
> + struct drm_crtc *crtc = &scrtc->base;
> struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);
> const struct drm_display_info *info = &sdev->connector->display_info;
> const struct drm_display_mode *mode = &crtc->mode;
> @@ -152,7 +152,7 @@ static void shmob_drm_crtc_setup_geometry(struct shmob_drm_crtc *scrtc)
>
> static void shmob_drm_crtc_start_stop(struct shmob_drm_crtc *scrtc, bool start)
> {
> - struct shmob_drm_device *sdev = to_shmob_device(scrtc->crtc.dev);
> + struct shmob_drm_device *sdev = to_shmob_device(scrtc->base.dev);
> u32 value;
>
> value = lcdc_read(sdev, LDCNT2R);
> @@ -185,7 +185,7 @@ static void shmob_drm_crtc_start_stop(struct shmob_drm_crtc *scrtc, bool start)
> */
> static void shmob_drm_crtc_start(struct shmob_drm_crtc *scrtc)
> {
> - struct drm_crtc *crtc = &scrtc->crtc;
> + struct drm_crtc *crtc = &scrtc->base;
> struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);
> const struct shmob_drm_interface_data *idata = &sdev->pdata->iface;
> const struct shmob_drm_format_info *format;
> @@ -272,7 +272,7 @@ static void shmob_drm_crtc_start(struct shmob_drm_crtc *scrtc)
>
> static void shmob_drm_crtc_stop(struct shmob_drm_crtc *scrtc)
> {
> - struct drm_crtc *crtc = &scrtc->crtc;
> + struct drm_crtc *crtc = &scrtc->base;
> struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);
>
> if (!scrtc->started)
> @@ -308,7 +308,7 @@ void shmob_drm_crtc_resume(struct shmob_drm_crtc *scrtc)
> static void shmob_drm_crtc_compute_base(struct shmob_drm_crtc *scrtc,
> int x, int y)
> {
> - struct drm_crtc *crtc = &scrtc->crtc;
> + struct drm_crtc *crtc = &scrtc->base;
> struct drm_framebuffer *fb = crtc->primary->fb;
> struct drm_gem_dma_object *gem;
> unsigned int bpp;
> @@ -329,7 +329,7 @@ static void shmob_drm_crtc_compute_base(struct shmob_drm_crtc *scrtc,
>
> static void shmob_drm_crtc_update_base(struct shmob_drm_crtc *scrtc)
> {
> - struct drm_crtc *crtc = &scrtc->crtc;
> + struct drm_crtc *crtc = &scrtc->base;
> struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);
>
> shmob_drm_crtc_compute_base(scrtc, crtc->x, crtc->y);
> @@ -343,7 +343,7 @@ static void shmob_drm_crtc_update_base(struct shmob_drm_crtc *scrtc)
>
> static inline struct shmob_drm_crtc *to_shmob_crtc(struct drm_crtc *crtc)
> {
> - return container_of(crtc, struct shmob_drm_crtc, crtc);
> + return container_of(crtc, struct shmob_drm_crtc, base);
> }
>
> static void shmob_drm_crtc_dpms(struct drm_crtc *crtc, int mode)
> @@ -415,15 +415,15 @@ static const struct drm_crtc_helper_funcs crtc_helper_funcs = {
> void shmob_drm_crtc_finish_page_flip(struct shmob_drm_crtc *scrtc)
> {
> struct drm_pending_vblank_event *event;
> - struct drm_device *dev = scrtc->crtc.dev;
> + struct drm_device *dev = scrtc->base.dev;
> unsigned long flags;
>
> spin_lock_irqsave(&dev->event_lock, flags);
> event = scrtc->event;
> scrtc->event = NULL;
> if (event) {
> - drm_crtc_send_vblank_event(&scrtc->crtc, event);
> - drm_crtc_vblank_put(&scrtc->crtc);
> + drm_crtc_send_vblank_event(&scrtc->base, event);
> + drm_crtc_vblank_put(&scrtc->base);
> }
> spin_unlock_irqrestore(&dev->event_lock, flags);
> }
> @@ -435,7 +435,7 @@ static int shmob_drm_crtc_page_flip(struct drm_crtc *crtc,
> struct drm_modeset_acquire_ctx *ctx)
> {
> struct shmob_drm_crtc *scrtc = to_shmob_crtc(crtc);
> - struct drm_device *dev = scrtc->crtc.dev;
> + struct drm_device *dev = scrtc->base.dev;
> unsigned long flags;
>
> spin_lock_irqsave(&dev->event_lock, flags);
> @@ -450,7 +450,7 @@ static int shmob_drm_crtc_page_flip(struct drm_crtc *crtc,
>
> if (event) {
> event->pipe = 0;
> - drm_crtc_vblank_get(&scrtc->crtc);
> + drm_crtc_vblank_get(&scrtc->base);
> spin_lock_irqsave(&dev->event_lock, flags);
> scrtc->event = event;
> spin_unlock_irqrestore(&dev->event_lock, flags);
> @@ -502,7 +502,7 @@ static const struct drm_crtc_funcs crtc_funcs = {
>
> int shmob_drm_crtc_create(struct shmob_drm_device *sdev)
> {
> - struct drm_crtc *crtc = &sdev->crtc.crtc;
> + struct drm_crtc *crtc = &sdev->crtc.base;
> struct drm_plane *primary, *plane;
> unsigned int i;
> int ret;
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
> index f507eaf912e16a22..79cce0a0ada4cfce 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
> @@ -21,7 +21,7 @@ struct shmob_drm_device;
> struct shmob_drm_format_info;
>
> struct shmob_drm_crtc {
> - struct drm_crtc crtc;
> + struct drm_crtc base;
>
> struct drm_pending_vblank_event *event;
> int dpms;

--
Jingfeng


2023-06-27 15:16:50

by Sui Jingfeng

[permalink] [raw]
Subject: Re: [32/39] drm: renesas: shmobile: Shutdown the display on remove

Hi

On 2023/6/22 17:21, Geert Uytterhoeven wrote:
> When the device is unbound from the driver, the display may be active.
> Make sure it gets shut down.

would you mind to give a short description why this is necessary.

> Signed-off-by: Geert Uytterhoeven <[email protected]>
> Reviewed-by: Laurent Pinchart <[email protected]>
> ---
> drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> index a29c0c1093725b6e..636f1888b815579b 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> @@ -16,6 +16,7 @@
> #include <linux/pm_runtime.h>
> #include <linux/slab.h>
>
> +#include <drm/drm_crtc_helper.h>
> #include <drm/drm_drv.h>
> #include <drm/drm_fbdev_generic.h>
> #include <drm/drm_gem_dma_helper.h>
> @@ -145,6 +146,7 @@ static int shmob_drm_remove(struct platform_device *pdev)
> struct drm_device *ddev = &sdev->ddev;
>
> drm_dev_unregister(ddev);
> + drm_helper_force_disable_all(ddev);
Is it that the DRM core recommend us to use
drm_atomic_helper_disable_all() ?
> drm_kms_helper_poll_fini(ddev);
> return 0;
> }

--
Jingfeng


2023-06-28 01:57:11

by Sui Jingfeng

[permalink] [raw]
Subject: Re: [13/39] drm: renesas: shmobile: Rename input clocks

Hi,

On 2023/6/22 17:21, Geert Uytterhoeven wrote:
> From: Laurent Pinchart <[email protected]>
>
> Prepare for DT bindings by using more appropriate names for the input
> clocks.
>
> Note that all LDDCKR_ICKSEL_* definitions but the one for the bus clock
> are valid only for SH7724, so the clock selection code needs to be
> updated when extending clock support to other SoCs.
>
> Signed-off-by: Laurent Pinchart <[email protected]>
> [geert: Add note]
> Signed-off-by: Geert Uytterhoeven <[email protected]>
Reviewed-by: Sui Jingfeng <[email protected]>
> ---
> drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c | 6 +++---
> 1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> index d272e6273c782178..007ba97cc7733c82 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> @@ -74,15 +74,15 @@ static int shmob_drm_setup_clocks(struct shmob_drm_device *sdev,
>
> switch (clksrc) {
> case SHMOB_DRM_CLK_BUS:
> - clkname = "bus_clk";
> + clkname = "fck";
> sdev->lddckr = LDDCKR_ICKSEL_BUS;
> break;
> case SHMOB_DRM_CLK_PERIPHERAL:
> - clkname = "peripheral_clk";
> + clkname = "media";
> sdev->lddckr = LDDCKR_ICKSEL_MIPI;
> break;
> case SHMOB_DRM_CLK_EXTERNAL:
> - clkname = NULL;
> + clkname = "lclk";
> sdev->lddckr = LDDCKR_ICKSEL_HDMI;
> break;
> default:

--
Jingfeng


2023-06-28 02:19:26

by Sui Jingfeng

[permalink] [raw]
Subject: Re: [12/39] drm: renesas: shmobile: Don't set display info width and height twice

Hi

On 2023/6/22 17:21, Geert Uytterhoeven wrote:
> From: Laurent Pinchart <[email protected]>
>
> The display info width_mm and height_mm fields are set at init time and
> never overwritten, don't set them a second time when getting modes.
>
> Signed-off-by: Laurent Pinchart <[email protected]>
> Signed-off-by: Geert Uytterhoeven <[email protected]>
Reviewed-by: Sui Jingfeng <[email protected]>
> ---
> drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 3 ---
> 1 file changed, 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> index c775c1d49f0e1ce9..0eeb1410b662d74b 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
> @@ -618,9 +618,6 @@ static int shmob_drm_connector_get_modes(struct drm_connector *connector)
> drm_mode_set_name(mode);
> drm_mode_probed_add(connector, mode);
>
> - connector->display_info.width_mm = sdev->pdata->panel.width_mm;
> - connector->display_info.height_mm = sdev->pdata->panel.height_mm;
> -
> return 1;
> }
>

--
Jingfeng


2023-07-05 10:42:58

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [32/39] drm: renesas: shmobile: Shutdown the display on remove

Hi Sui,

On Tue, Jun 27, 2023 at 4:57 PM Sui Jingfeng <[email protected]> wrote:
> On 2023/6/22 17:21, Geert Uytterhoeven wrote:
> > When the device is unbound from the driver, the display may be active.
> > Make sure it gets shut down.
>
> would you mind to give a short description why this is necessary.

That's a good comment.
It turned out that this is not really necessary here, but to avoid a regression
with "[PATCH 34/39] drm: renesas: shmobile: Atomic conversion part 1", where
it is needed to call drm_atomic_helper_shutdown().
As the comments for drm_atomic_helper_shutdown() says it is the
atomic version of drm_helper_force_disable_all(), I figured I had to
introduce a call to the latter first, before doing the atomic conversion.

Does that make sense?

> > Signed-off-by: Geert Uytterhoeven <[email protected]>
> > Reviewed-by: Laurent Pinchart <[email protected]>

> > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> > @@ -16,6 +16,7 @@
> > #include <linux/pm_runtime.h>
> > #include <linux/slab.h>
> >
> > +#include <drm/drm_crtc_helper.h>
> > #include <drm/drm_drv.h>
> > #include <drm/drm_fbdev_generic.h>
> > #include <drm/drm_gem_dma_helper.h>
> > @@ -145,6 +146,7 @@ static int shmob_drm_remove(struct platform_device *pdev)
> > struct drm_device *ddev = &sdev->ddev;
> >
> > drm_dev_unregister(ddev);
> > + drm_helper_force_disable_all(ddev);
>
> Is it that the DRM core recommend us to use
> drm_atomic_helper_disable_all() ?

Well, drm_atomic_helper_shutdown() is a convenience wrapper
around drm_atomic_helper_disable_all()... But we can't call any
atomic helpers yet, before the conversion to atomic modesetting.

>
> > drm_kms_helper_poll_fini(ddev);
> > return 0;
> > }

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds