2023-08-16 14:35:52

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH v3 00/41] 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 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 a separate maintainer entry.
- Patch 2 adds DT bindings for the SH-Mobile LCD controller,
- Patch 3 adds definitions for RGB666 9:9 media bus formats,
- Patches 4-35 contains miscellaneous fixes, improvements, and
cleanups for the SH-Mobile DRM driver,
- Patches 36-40 convert the SH-Mobile DRM driver to atomic
modesetting,
- Patch 41 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 questions can be found in the individual patches.

Changes compared to v2[1]:
- Add Reviewed-by.

Changes compared to v1[2]:
- New patches
- "[PATCH v2 01/41] MAINTAINER: Create entry for Renesas SH-Mobile
DRM drivers",
- "[PATCH v2 18/41] drm: renesas: shmobile: Remove custom plane
destroy callback",
- Add myself as co-maintainer,
- Make fck clock required,
- Drop ports description referring to obsolete graph.txt,
- Condition ports to compatible strings,
- Drop label and status from example,
- Add Reviewed-by,
- Drop unused MEDIA_BUS_FMT_RGB666_2X9_LE, as requested by Laurent,
- Move explicit clock handling to Runtime PM callbacks,
- Move devm_pm_runtime_enable() after shmob_drm_setup_clocks(),
- Depend on PM,
- Split off removal of call to drm_plane_force_disable(),
- Select VIDEOMODE_HELPERS,
- Keep table instead of replacing it by a switch() statement,
- Fix shmob_drm_interface_data.bus_fmt comment,
- Drop superfluous blank lines,
- Keep initialization of info fields together,
- Use shmob_drm_bus_fmts[],
- Keep bus format validation at probe time,
- Pass plane type to shmob_drm_plane_create() to avoid having to shift
all overlay plane indices by one,
- Rename primary_plane_funcs to shmob_drm_primary_plane_funcs,
- Rename shmob_drm_plane_funcs to shmob_drm_overlay_plane_funcs,
- Move shmob_drm_crtc_finish_page_flip() further up,
- Inline shmob_drm_crtc_st{art,op}(),
- Use devm_drm_of_get_bridge(),
- Don't print bridge->of_node on failure, as this field depends on
CONFIG_OF.

This has been tested on the R-Mobile A1-based Atmark Techno
Armadillo-800-EVA development board, using both legacy[3] and
DT-based[4] 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[5].

Thanks for your comments!

[1] "[PATCH v2 00/41] drm: renesas: shmobile: Atomic conversion + DT
support"
https://lore.kernel.org/r/[email protected]

[2] "[PATCH 00/39] drm: renesas: shmobile: Atomic conversion + DT
support"
https://lore.kernel.org/r/[email protected]/

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

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

[5] 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:
24 VRR_ENABLED:
flags: range
values: 0 1
value: 0

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 (36):
MAINTAINER: Create entry for Renesas SH-Mobile DRM drivers
dt-bindings: display: Add Renesas SH-Mobile LCDC bindings
media: uapi: Add MEDIA_BUS_FMT_RGB666_2X9_BE format
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: Remove custom plane destroy callback
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 | 130 ++++
.../media/v4l/subdev-formats.rst | 72 ++
MAINTAINERS | 13 +-
drivers/gpu/drm/renesas/shmobile/Kconfig | 3 +-
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 | 650 ++++++++----------
.../gpu/drm/renesas/shmobile/shmob_drm_crtc.h | 27 +-
.../gpu/drm/renesas/shmobile/shmob_drm_drv.c | 180 +++--
.../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 | 326 +++++----
.../drm/renesas/shmobile/shmob_drm_plane.h | 5 +-
include/linux/platform_data/shmob_drm.h | 57 +-
include/uapi/linux/media-bus-format.h | 3 +-
17 files changed, 860 insertions(+), 814 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: Hans Verkuil <[email protected]>
Cc: [email protected]
Cc: [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-08-16 14:52:40

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH v3 10/41] 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]>
Reviewed-by: Laurent Pinchart <[email protected]>
---
v3:
- No changes,

v2:
- Add Reviewed-by.
---
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 2d9ae0c6ab7b18a8..a0e1a49c84d5691a 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
@@ -460,6 +460,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-08-16 16:00:26

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH v3 13/41] 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]>
Reviewed-by: Sui Jingfeng <[email protected]>
---
v3:
- No changes,

v2:
- Add Reviewed-by.
---
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 db9d8d440144db36..2ccb2fbfea26b5bf 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
@@ -585,9 +585,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-08-16 16:28:12

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH v3 28/41] 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]>
Reviewed-by: Laurent Pinchart <[email protected]>
Reviewed-by: Sui Jingfeng <[email protected]>
---
v3:
- No changes,

v2:
- Add Reviewed-by.
---
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 84a773a5363035e0..f55b5263e611c782 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
@@ -560,7 +560,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)
@@ -632,7 +632,7 @@ shmob_drm_connector_init(struct shmob_drm_device *sdev,
if (!scon)
return ERR_PTR(-ENOMEM);

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

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-08-16 16:48:22

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH v3 07/41] 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 for all clock handling. Add an explicit
dependency on CONFIG_PM, which should already be met on all affected
platforms.

Signed-off-by: Geert Uytterhoeven <[email protected]>
---
v3:
- No changes,

v2:
- Move explicit clock handling to Runtime PM callbacks,
- Move devm_pm_runtime_enable() after shmob_drm_setup_clocks(),
- Depend on PM.
---
drivers/gpu/drm/renesas/shmobile/Kconfig | 2 +-
.../gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 32 ++--------------
.../gpu/drm/renesas/shmobile/shmob_drm_drv.c | 38 +++++++++++++++++--
3 files changed, 40 insertions(+), 32 deletions(-)

diff --git a/drivers/gpu/drm/renesas/shmobile/Kconfig b/drivers/gpu/drm/renesas/shmobile/Kconfig
index ad14112999ad8aba..ba941587ca70e08c 100644
--- a/drivers/gpu/drm/renesas/shmobile/Kconfig
+++ b/drivers/gpu/drm/renesas/shmobile/Kconfig
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
config DRM_SHMOBILE
tristate "DRM Support for SH Mobile"
- depends on DRM
+ depends on DRM && PM
depends on ARCH_RENESAS || ARCH_SHMOBILE || COMPILE_TEST
select BACKLIGHT_CLASS_DEVICE
select DRM_KMS_HELPER
diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
index fbfd906844da490c..2d9ae0c6ab7b18a8 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>
@@ -34,29 +35,6 @@
* TODO: panel support
*/

-/* -----------------------------------------------------------------------------
- * Clock management
- */
-
-static int shmob_drm_clk_on(struct shmob_drm_device *sdev)
-{
- int ret;
-
- if (sdev->clock) {
- ret = clk_prepare_enable(sdev->clock);
- if (ret < 0)
- return ret;
- }
-
- return 0;
-}
-
-static void shmob_drm_clk_off(struct shmob_drm_device *sdev)
-{
- if (sdev->clock)
- clk_disable_unprepare(sdev->clock);
-}
-
/* -----------------------------------------------------------------------------
* CRTC
*/
@@ -170,9 +148,8 @@ static void shmob_drm_crtc_start(struct shmob_drm_crtc *scrtc)
if (WARN_ON(format == NULL))
return;

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

/* Reset and enable the LCDC. */
@@ -268,8 +245,7 @@ static void shmob_drm_crtc_stop(struct shmob_drm_crtc *scrtc)
/* Disable the display output. */
lcdc_write(sdev, LDCNT1R, 0);

- /* 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..3fc7d820abdc61d4 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>
@@ -165,8 +166,35 @@ static int shmob_drm_pm_resume(struct device *dev)
return 0;
}

-static DEFINE_SIMPLE_DEV_PM_OPS(shmob_drm_pm_ops,
- shmob_drm_pm_suspend, shmob_drm_pm_resume);
+static int shmob_drm_pm_runtime_suspend(struct device *dev)
+{
+ struct shmob_drm_device *sdev = dev_get_drvdata(dev);
+
+ if (sdev->clock)
+ clk_disable_unprepare(sdev->clock);
+
+ return 0;
+}
+
+static int shmob_drm_pm_runtime_resume(struct device *dev)
+{
+ struct shmob_drm_device *sdev = dev_get_drvdata(dev);
+ int ret;
+
+ if (sdev->clock) {
+ ret = clk_prepare_enable(sdev->clock);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct dev_pm_ops shmob_drm_pm_ops = {
+ SYSTEM_SLEEP_PM_OPS(shmob_drm_pm_suspend, shmob_drm_pm_resume)
+ RUNTIME_PM_OPS(shmob_drm_pm_runtime_suspend,
+ shmob_drm_pm_runtime_resume, NULL)
+};

/* -----------------------------------------------------------------------------
* Platform driver
@@ -220,6 +248,10 @@ static int shmob_drm_probe(struct platform_device *pdev)
if (ret < 0)
return ret;

+ ret = devm_pm_runtime_enable(&pdev->dev);
+ if (ret)
+ return ret;
+
ret = shmob_drm_init_interface(sdev);
if (ret < 0)
return ret;
@@ -291,7 +323,7 @@ static struct platform_driver shmob_drm_platform_driver = {
.remove = shmob_drm_remove,
.driver = {
.name = "shmob-drm",
- .pm = pm_sleep_ptr(&shmob_drm_pm_ops),
+ .pm = &shmob_drm_pm_ops,
},
};

--
2.34.1


2023-08-16 16:50:54

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH v3 29/41] 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]>
Reviewed-by: Laurent Pinchart <[email protected]>
Reviewed-by: Sui Jingfeng <[email protected]>
---
v3:
- No changes,

v2:
- Add Reviewed-by.
---
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 3518f8900c0d1f9e..d0a9299784d4a7cc 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);
u32 format;

/* TODO: Support ROP3 mode */
@@ -216,7 +216,7 @@ struct drm_plane *shmob_drm_plane_create(struct shmob_drm_device *sdev,
funcs = &shmob_drm_overlay_plane_funcs;

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);
@@ -226,5 +226,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-08-16 17:23:09

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH v3 19/41] 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]>
---
v3:
- No changes,

v2:
- Split off removal of call to drm_plane_force_disable().
---
.../gpu/drm/renesas/shmobile/shmob_drm_plane.c | 18 +++++++-----------
1 file changed, 7 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
index 3a5db319bad14218..1fb68b5fe915b8dc 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
@@ -179,7 +179,6 @@ static int shmob_drm_plane_disable(struct drm_plane *plane,
static const struct drm_plane_funcs shmob_drm_plane_funcs = {
.update_plane = shmob_drm_plane_update,
.disable_plane = shmob_drm_plane_disable,
- .destroy = drm_plane_cleanup,
};

static const uint32_t formats[] = {
@@ -198,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-08-16 18:10:30

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH v3 38/41] 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]>
Reviewed-by: Laurent Pinchart <[email protected]>
---
v3:
- No changes,

v2:
- Add Reviewed-by.
---
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 5c0575eed3ab6833..a176cd3e494ed2fd 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
@@ -287,19 +287,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 e4e88e66de5c3d3b..b7643884b49f0bc8 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 int shmob_drm_pm_runtime_suspend(struct device *dev)
--
2.34.1


2023-08-16 18:40:39

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH v3 09/41] 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]>
Reviewed-by: Laurent Pinchart <[email protected]>
---
v3:
- No changes,

v2:
- Add Reviewed-by.
---
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-08-16 20:59:15

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH v3 04/41] 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]>
Reviewed-by: Laurent Pinchart <[email protected]>
---
v3:
- No changes,

v2:
- Add Reviewed-by.
---
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-08-16 21:23:41

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH v3 25/41] 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 allow us to use the same LCD interface setup code for both
legacy and DT-based systems.

Signed-off-by: Geert Uytterhoeven <[email protected]>
---
v3:
- No changes,

v2:
- Drop superfluous blank lines,
- Keep initialization of info fields together,
- Use shmob_drm_bus_fmts[],
- Keep bus format validation at probe time.
---
.../gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 118 +++++++++++++++---
.../gpu/drm/renesas/shmobile/shmob_drm_drv.c | 34 -----
.../gpu/drm/renesas/shmobile/shmob_drm_drv.h | 3 +-
3 files changed, 104 insertions(+), 51 deletions(-)

diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
index b3ef10b7828de197..caafd04acd3d46d0 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>
@@ -39,20 +40,55 @@
* CRTC
*/

+static const struct {
+ u32 fmt;
+ u32 ldmt1r;
+} shmob_drm_bus_fmts[] = {
+ { MEDIA_BUS_FMT_RGB888_3X8, LDMT1R_MIFTYP_RGB8 },
+ { MEDIA_BUS_FMT_RGB666_2X9_BE, LDMT1R_MIFTYP_RGB9 },
+ { MEDIA_BUS_FMT_RGB888_2X12_BE, LDMT1R_MIFTYP_RGB12A },
+ { MEDIA_BUS_FMT_RGB444_1X12, LDMT1R_MIFTYP_RGB12B },
+ { MEDIA_BUS_FMT_RGB565_1X16, LDMT1R_MIFTYP_RGB16 },
+ { MEDIA_BUS_FMT_RGB666_1X18, LDMT1R_MIFTYP_RGB18 },
+ { MEDIA_BUS_FMT_RGB888_1X24, LDMT1R_MIFTYP_RGB24 },
+ { MEDIA_BUS_FMT_UYVY8_1X16, LDMT1R_MIFTYP_YCBCR },
+};
+
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;
+ unsigned int i;
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 {
+ for (i = 0; i < ARRAY_SIZE(shmob_drm_bus_fmts); i++) {
+ if (shmob_drm_bus_fmts[i].fmt == info->bus_formats[0])
+ break;
+ }
+ if (i < ARRAY_SIZE(shmob_drm_bus_fmts)) {
+ value = shmob_drm_bus_fmts[i].ldmt1r;
+ } else {
+ dev_warn(sdev->dev,
+ "unsupported bus format 0x%x, using RGB888\n",
+ info->bus_formats[0]);
+ value = LDMT1R_MIFTYP_RGB24;
+ }
+ }

+ 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);

value = ((mode->hdisplay / 8) << 16) /* HDCN */
@@ -479,7 +515,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)) {
@@ -581,6 +617,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 = {
@@ -589,26 +627,74 @@ 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;
+ u32 bus_fmt = sdev->pdata->iface.bus_fmt;
+ struct shmob_drm_connector *scon;
+ struct drm_connector *connector;
+ struct drm_display_info *info;
+ unsigned int i;
int ret;

+ for (i = 0; i < ARRAY_SIZE(shmob_drm_bus_fmts); i++) {
+ if (shmob_drm_bus_fmts[i].fmt == bus_fmt)
+ break;
+ }
+ if (i == ARRAY_SIZE(shmob_drm_bus_fmts)) {
+ dev_err(sdev->dev, "unsupported bus format 0x%x\n", bus_fmt);
+ return ERR_PTR(-EINVAL);
+ }
+
+ scon = kzalloc(sizeof(*scon), GFP_KERNEL);
+ if (!scon)
+ return ERR_PTR(-ENOMEM);
+
+ connector = &scon->connector;
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;
+ info = &connector->display_info;
+ info->width_mm = sdev->pdata->panel.width_mm;
+ 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, &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;
@@ -617,6 +703,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 08b254f0f2874786..8da3054f26b2d235 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,35 +32,6 @@
* Hardware initialization
*/

-static int shmob_drm_init_interface(struct shmob_drm_device *sdev)
-{
- static const struct {
- u32 fmt;
- u32 ldmt1r;
- } bus_fmts[] = {
- { MEDIA_BUS_FMT_RGB888_3X8, LDMT1R_MIFTYP_RGB8 },
- { MEDIA_BUS_FMT_RGB666_2X9_BE, LDMT1R_MIFTYP_RGB9 },
- { MEDIA_BUS_FMT_RGB888_2X12_BE, LDMT1R_MIFTYP_RGB12A },
- { MEDIA_BUS_FMT_RGB444_1X12, LDMT1R_MIFTYP_RGB12B },
- { MEDIA_BUS_FMT_RGB565_1X16, LDMT1R_MIFTYP_RGB16 },
- { MEDIA_BUS_FMT_RGB666_1X18, LDMT1R_MIFTYP_RGB18 },
- { MEDIA_BUS_FMT_RGB888_1X24, LDMT1R_MIFTYP_RGB24 },
- { MEDIA_BUS_FMT_UYVY8_1X16, LDMT1R_MIFTYP_YCBCR },
- };
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(bus_fmts); i++) {
- if (bus_fmts[i].fmt == sdev->pdata->iface.bus_fmt) {
- sdev->ldmt1r = bus_fmts[i].ldmt1r;
- return 0;
- }
- }
-
- dev_err(sdev->dev, "unsupported bus format 0x%x\n",
- sdev->pdata->iface.bus_fmt);
- return -EINVAL;
-}
-
static int shmob_drm_setup_clocks(struct shmob_drm_device *sdev,
enum shmob_drm_clk_source clksrc)
{
@@ -247,10 +217,6 @@ static int shmob_drm_probe(struct platform_device *pdev)
if (ret)
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-08-16 22:47:36

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH v3 22/41] 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]>
Reviewed-by: Laurent Pinchart <[email protected]>
Reviewed-by: Sui Jingfeng <[email protected]>
---
v3:
- No changes,

v2:
- Add Reviewed-by.
---
.../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 207fa98fe76d6f88..f62ae047a48f615b 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
@@ -40,7 +40,7 @@
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;
@@ -79,7 +79,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);
@@ -113,7 +113,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;
@@ -193,7 +193,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;
@@ -247,7 +247,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);

@@ -289,8 +289,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);
@@ -395,7 +395,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);

@@ -404,7 +404,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);
}
@@ -478,7 +478,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;

@@ -548,7 +548,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 3f40ebb96747d1e7..c9ac8a86a7c39097 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;

@@ -244,8 +244,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-08-17 01:08:10

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH v3 35/41] 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]>
Reviewed-by: Laurent Pinchart <[email protected]>
---
v3:
- No changes,

v2:
- Add Reviewed-by.
---
.../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 ab42a4999a55c475..365eb3e154130d41 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
@@ -534,11 +534,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)
@@ -561,29 +556,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-08-17 04:07:30

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH v3 24/41] 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]>
---
v3:
- No changes,

v2:
- Keep table instead of replacing it by a switch() statement,
- Fix shmob_drm_interface_data.bus_fmt comment.
---
.../gpu/drm/renesas/shmobile/shmob_drm_drv.c | 37 +++++++++++--------
include/linux/platform_data/shmob_drm.h | 13 +------
2 files changed, 23 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 c9ac8a86a7c39097..08b254f0f2874786 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,25 +35,31 @@

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,
+ static const struct {
+ u32 fmt;
+ u32 ldmt1r;
+ } bus_fmts[] = {
+ { MEDIA_BUS_FMT_RGB888_3X8, LDMT1R_MIFTYP_RGB8 },
+ { MEDIA_BUS_FMT_RGB666_2X9_BE, LDMT1R_MIFTYP_RGB9 },
+ { MEDIA_BUS_FMT_RGB888_2X12_BE, LDMT1R_MIFTYP_RGB12A },
+ { MEDIA_BUS_FMT_RGB444_1X12, LDMT1R_MIFTYP_RGB12B },
+ { MEDIA_BUS_FMT_RGB565_1X16, LDMT1R_MIFTYP_RGB16 },
+ { MEDIA_BUS_FMT_RGB666_1X18, LDMT1R_MIFTYP_RGB18 },
+ { MEDIA_BUS_FMT_RGB888_1X24, LDMT1R_MIFTYP_RGB24 },
+ { MEDIA_BUS_FMT_UYVY8_1X16, LDMT1R_MIFTYP_YCBCR },
};
+ unsigned int i;

- if (sdev->pdata->iface.interface >= ARRAY_SIZE(ldmt1r)) {
- dev_err(sdev->dev, "invalid interface type %u\n",
- sdev->pdata->iface.interface);
- return -EINVAL;
+ for (i = 0; i < ARRAY_SIZE(bus_fmts); i++) {
+ if (bus_fmts[i].fmt == sdev->pdata->iface.bus_fmt) {
+ sdev->ldmt1r = bus_fmts[i].ldmt1r;
+ return 0;
+ }
}

- sdev->ldmt1r = ldmt1r[sdev->pdata->iface.interface];
- return 0;
+ dev_err(sdev->dev, "unsupported bus format 0x%x\n",
+ sdev->pdata->iface.bus_fmt);
+ return -EINVAL;
}

static int shmob_drm_setup_clocks(struct shmob_drm_device *sdev,
diff --git a/include/linux/platform_data/shmob_drm.h b/include/linux/platform_data/shmob_drm.h
index f3cb19ff9f818aca..6c19d4fbbe39586b 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_* */
unsigned int clk_div;
};

--
2.34.1


2023-08-17 06:33:53

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH v3 23/41] 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]>
Reviewed-by: Laurent Pinchart <[email protected]>
---
v3:
- No changes,

v2:
- Add Reviewed-by,
- Select VIDEOMODE_HELPERS.

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.
---
drivers/gpu/drm/renesas/shmobile/Kconfig | 1 +
.../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 ++----
4 files changed, 20 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/renesas/shmobile/Kconfig b/drivers/gpu/drm/renesas/shmobile/Kconfig
index ba941587ca70e08c..027220b8fe1c5fbd 100644
--- a/drivers/gpu/drm/renesas/shmobile/Kconfig
+++ b/drivers/gpu/drm/renesas/shmobile/Kconfig
@@ -6,6 +6,7 @@ config DRM_SHMOBILE
select BACKLIGHT_CLASS_DEVICE
select DRM_KMS_HELPER
select DRM_GEM_DMA_HELPER
+ select VIDEOMODE_HELPERS
help
Choose this option if you have an SH Mobile chipset.
If M is selected the module will be called shmob-drm.
diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
index f62ae047a48f615b..b3ef10b7828de197 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"
@@ -41,18 +43,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 */
@@ -548,7 +548,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);
@@ -556,18 +556,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;
@@ -601,10 +592,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-08-17 08:10:04

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH v3 27/41] 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]>
Reviewed-by: Laurent Pinchart <[email protected]>
Reviewed-by: Sui Jingfeng <[email protected]>
---
v3:
- No changes,

v2:
- Add Reviewed-by.
---
.../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 564051b505ed4ac5..84a773a5363035e0 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
@@ -55,7 +55,7 @@ static const struct {

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;
@@ -114,7 +114,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);
@@ -147,7 +147,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;
@@ -227,7 +227,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)
@@ -260,7 +260,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;
@@ -281,7 +281,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);
@@ -295,7 +295,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)
@@ -367,15 +367,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);
}
@@ -387,7 +387,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);
@@ -402,7 +402,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);
@@ -454,7 +454,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-08-17 10:47:06

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH v3 36/41] 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]>
---
v3:
- No changes,

v2:
- No changes.
---
.../gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 126 +++------
.../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 | 253 ++++++++++++------
.../drm/renesas/shmobile/shmob_drm_plane.h | 1 -
6 files changed, 217 insertions(+), 183 deletions(-)

diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
index 365eb3e154130d41..c277f93668825e1c 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>
@@ -199,20 +202,14 @@ 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;

@@ -249,23 +246,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);

@@ -317,42 +299,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);
@@ -378,50 +324,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,
@@ -441,8 +382,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;
@@ -489,9 +429,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,
};
@@ -627,8 +570,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 51a9a6955d1fb0fb..e4e88e66de5c3d3b 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>
@@ -173,7 +173,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 d0a9299784d4a7cc..8f9a728affde8375 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,36 +38,65 @@ 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);
+ 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, splane, reg) \
dev_dbg(sdev->ddev.dev, "%s(%u): %s 0x%08x 0x%08x\n", __func__, \
@@ -91,19 +118,17 @@ static void __shmob_drm_plane_setup(struct shmob_drm_plane *splane,
lcdc_write(sdev, LDBnBSIFR(splane->index), format);

lcdc_write(sdev, LDBnBSSZR(splane->index),
- (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(splane->index),
- (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(splane->index),
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]);
- if (shmob_drm_format_is_yuv(splane->format))
- lcdc_write(sdev, LDBnBSACR(splane->index), splane->dma[1]);
+ lcdc_write(sdev, LDBnBSAYR(splane->index), sstate->dma[0]);
+ if (shmob_drm_format_is_yuv(sstate->format))
+ lcdc_write(sdev, LDBnBSACR(splane->index), sstate->dma[1]);

lcdc_write(sdev, LDBCR,
LDBCR_UPF(splane->index) | LDBCR_UPD(splane->index));
@@ -118,76 +143,143 @@ static void __shmob_drm_plane_setup(struct shmob_drm_plane *splane,
plane_reg_dump(sdev, splane, 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;
-
- 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_compute_base(sstate);

- __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);

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

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;
+ LDBCR_UPF(splane->index) | LDBCR_UPD(splane->index));
+}
+
+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 const struct drm_plane_funcs shmob_drm_primary_plane_funcs = {
- .update_plane = drm_plane_helper_update_primary,
- .disable_plane = drm_plane_helper_disable_primary,
+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_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_overlay_plane_funcs = {
- .update_plane = shmob_drm_plane_update,
- .disable_plane = shmob_drm_plane_disable,
+static const struct drm_plane_funcs shmob_drm_plane_funcs = {
+ .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[] = {
@@ -207,24 +299,19 @@ struct drm_plane *shmob_drm_plane_create(struct shmob_drm_device *sdev,
enum drm_plane_type type,
unsigned int index)
{
- const struct drm_plane_funcs *funcs;
struct shmob_drm_plane *splane;

- if (type == DRM_PLANE_TYPE_PRIMARY)
- funcs = &shmob_drm_primary_plane_funcs;
- else
- funcs = &shmob_drm_overlay_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 8ad12129014016fa..dcfddd605899b05d 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.h
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.h
@@ -16,6 +16,5 @@ struct shmob_drm_device;
struct drm_plane *shmob_drm_plane_create(struct shmob_drm_device *sdev,
enum drm_plane_type type,
unsigned int index);
-void shmob_drm_plane_setup(struct drm_plane *plane);

#endif /* __SHMOB_DRM_PLANE_H__ */
--
2.34.1


2023-08-17 13:01:31

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH v3 01/41] MAINTAINER: Create entry for Renesas SH-Mobile DRM drivers

Split off DRM drivers for Renesas SH-Mobile into its own entry, and add
Geert Uytterhoeven as a maintainer.

Signed-off-by: Geert Uytterhoeven <[email protected]>
---
Kieran: do you want to join the club, too? ;-)

v3:
- No changes,

v2:
- New.
---
MAINTAINERS | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index c9cf561aca347709..c454b0186fd669dd 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7007,7 +7007,7 @@ F: drivers/gpu/host1x/
F: include/linux/host1x.h
F: include/uapi/drm/tegra_drm.h

-DRM DRIVERS FOR RENESAS
+DRM DRIVERS FOR RENESAS R-CAR
M: Laurent Pinchart <[email protected]>
M: Kieran Bingham <[email protected]>
L: [email protected]
@@ -7018,7 +7018,15 @@ F: Documentation/devicetree/bindings/display/bridge/renesas,dsi-csi2-tx.yaml
F: Documentation/devicetree/bindings/display/bridge/renesas,dw-hdmi.yaml
F: Documentation/devicetree/bindings/display/bridge/renesas,lvds.yaml
F: Documentation/devicetree/bindings/display/renesas,du.yaml
-F: drivers/gpu/drm/renesas/
+F: drivers/gpu/drm/renesas/rcar-du/
+
+DRM DRIVERS FOR RENESAS SHMOBILE
+M: Laurent Pinchart <[email protected]>
+M: Geert Uytterhoeven <[email protected]>
+L: [email protected]
+L: [email protected]
+S: Supported
+F: drivers/gpu/drm/renesas/shmobile/
F: include/linux/platform_data/shmob_drm.h

DRM DRIVERS FOR ROCKCHIP
--
2.34.1


2023-08-17 14:15:24

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH v3 20/41] 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]>
Reviewed-by: Laurent Pinchart <[email protected]>
---
v3:
- No changes,

v2:
- Add Reviewed-by.
---
.../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 015263ac2100c11e..9c66e00ed70ea582 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
@@ -116,7 +116,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;
@@ -439,7 +439,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),
@@ -448,7 +448,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);
@@ -524,7 +524,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;
@@ -604,7 +604,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;
@@ -617,7 +617,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 381e184abf552c4c..3f40ebb96747d1e7 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;
}

@@ -192,12 +192,10 @@ static const struct 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;
}

@@ -215,13 +213,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);
@@ -244,20 +244,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);
@@ -299,9 +291,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-08-17 14:59:38

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH v3 05/41] drm: renesas: shmobile: Fix ARGB32 overlay format typo

When configuring 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]>
Reviewed-by: Laurent Pinchart <[email protected]>
---
v3:
- No changes,

v2:
- s/configurating/configuring/,
- Add Reviewed-by.
---
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-08-17 15:49:15

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH v3 02/41] dt-bindings: display: Add Renesas SH-Mobile LCDC bindings

Add device tree bindings for the LCD Controller (LCDC) found in Renesas
SuperH SH-Mobile and ARM SH/R-Mobile SOCs.

Based on a plain text prototype by Laurent Pinchart.

Signed-off-by: Geert Uytterhoeven <[email protected]>
Reviewed-by: Rob Herring <[email protected]>
---
Cc: Rob Herring <[email protected]>
Cc: Krzysztof Kozlowski <[email protected]>
Cc: Conor Dooley <[email protected]>
Cc: [email protected]

v3:
- Add Reviewed-by,

v2:
- Add myself as co-maintainer,
- Make fck clock required,
- Drop ports description referring to obsolete graph.txt,
- Condition ports to compatible strings,
- Drop label and status from example.

Changes compared to Laurent's original:
- Convert to json-schema,
- Rename compatible values from "renesas,lcdc-<SoC>" to
"renesas,<SoC>-lcdc",
- Add power-domains property,
- Add MIPI-DSI port on SH-Mobile AG5,
- Update example to reflect reality,
- Add to MAINTAINERS.
---
.../display/renesas,shmobile-lcdc.yaml | 130 ++++++++++++++++++
MAINTAINERS | 1 +
2 files changed, 131 insertions(+)
create mode 100644 Documentation/devicetree/bindings/display/renesas,shmobile-lcdc.yaml

diff --git a/Documentation/devicetree/bindings/display/renesas,shmobile-lcdc.yaml b/Documentation/devicetree/bindings/display/renesas,shmobile-lcdc.yaml
new file mode 100644
index 0000000000000000..9816c4cacc7d9a7f
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/renesas,shmobile-lcdc.yaml
@@ -0,0 +1,130 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/renesas,shmobile-lcdc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Renesas SH-Mobile LCD Controller (LCDC)
+
+maintainers:
+ - Laurent Pinchart <[email protected]>
+ - Geert Uytterhoeven <[email protected]>
+
+properties:
+ compatible:
+ enum:
+ - renesas,r8a7740-lcdc # R-Mobile A1
+ - renesas,sh73a0-lcdc # SH-Mobile AG5
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ clocks:
+ minItems: 1
+ maxItems: 5
+ description:
+ Only the functional clock is mandatory.
+ Some of the optional clocks are model-dependent (e.g. "video" (a.k.a.
+ "vou" or "dv_clk") is available on R-Mobile A1 only).
+
+ clock-names:
+ minItems: 1
+ items:
+ - const: fck
+ - enum: [ media, lclk, hdmi, video ]
+ - enum: [ media, lclk, hdmi, video ]
+ - enum: [ media, lclk, hdmi, video ]
+ - enum: [ media, lclk, hdmi, video ]
+
+ power-domains:
+ maxItems: 1
+
+ ports:
+ $ref: /schemas/graph.yaml#/properties/ports
+
+ properties:
+ port@0:
+ $ref: /schemas/graph.yaml#/properties/port
+ description: LCD port (R-Mobile A1 and SH-Mobile AG5)
+ unevaluatedProperties: false
+
+ port@1:
+ $ref: /schemas/graph.yaml#/properties/port
+ description: HDMI port (R-Mobile A1 LCDC1 and SH-Mobile AG5)
+ unevaluatedProperties: false
+
+ port@2:
+ $ref: /schemas/graph.yaml#/properties/port
+ description: MIPI-DSI port (SH-Mobile AG5)
+ unevaluatedProperties: false
+
+ required:
+ - port@0
+
+ unevaluatedProperties: false
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - clocks
+ - clock-names
+ - power-domains
+ - ports
+
+additionalProperties: false
+
+allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: renesas,r8a7740-lcdc
+ then:
+ properties:
+ ports:
+ properties:
+ port@2: false
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: renesas,sh73a0-lcdc
+ then:
+ properties:
+ ports:
+ required:
+ - port@1
+ - port@2
+
+examples:
+ - |
+ #include <dt-bindings/clock/r8a7740-clock.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+ lcd-controller@fe940000 {
+ compatible = "renesas,r8a7740-lcdc";
+ reg = <0xfe940000 0x4000>;
+ interrupts = <GIC_SPI 177 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp1_clks R8A7740_CLK_LCDC0>,
+ <&cpg_clocks R8A7740_CLK_M3>, <&lcdlclk0_clk>,
+ <&vou_clk>;
+ clock-names = "fck", "media", "lclk", "video";
+ power-domains = <&pd_a4lc>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ lcdc0_rgb: endpoint {
+ };
+ };
+ };
+ };
diff --git a/MAINTAINERS b/MAINTAINERS
index c454b0186fd669dd..d3e1b194dfbd129e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7026,6 +7026,7 @@ M: Geert Uytterhoeven <[email protected]>
L: [email protected]
L: [email protected]
S: Supported
+F: Documentation/devicetree/bindings/display/renesas,shmobile-lcdc.yaml
F: drivers/gpu/drm/renesas/shmobile/
F: include/linux/platform_data/shmob_drm.h

--
2.34.1


2023-08-17 15:54:26

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH v3 03/41] media: uapi: Add MEDIA_BUS_FMT_RGB666_2X9_BE format

Add the RGB666 9:9 format MEDIA_BUS_FMT_RGB666_2X9_BE, which is
supported by the SH-Mobile LCD Controller.

Signed-off-by: Geert Uytterhoeven <[email protected]>
Reviewed-by: Laurent Pinchart <[email protected]>
---
Cc: Mauro Carvalho Chehab <[email protected]>
Cc: Hans Verkuil <[email protected]>
Cc: [email protected]

v3:
- No changes,

v2:
- Add Reviewed-by,
- Drop unused MEDIA_BUS_FMT_RGB666_2X9_LE, as requested by Laurent.
---
.../media/v4l/subdev-formats.rst | 72 +++++++++++++++++++
include/uapi/linux/media-bus-format.h | 3 +-
2 files changed, 74 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..eb3cd20b0cf2e3d6 100644
--- a/Documentation/userspace-api/media/v4l/subdev-formats.rst
+++ b/Documentation/userspace-api/media/v4l/subdev-formats.rst
@@ -949,6 +949,78 @@ 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-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..f05f747e444d6686 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 0x1026 */
#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,7 @@
#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_BGR666_1X18 0x1023
#define MEDIA_BUS_FMT_RBG888_1X24 0x100e
#define MEDIA_BUS_FMT_RGB666_1X24_CPADHI 0x1015
--
2.34.1


2023-08-17 19:16:35

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH v3 17/41] drm: renesas: shmobile: Convert to use devm_request_irq()

Convert to managed IRQ handling, to simplify cleanup.

Signed-off-by: Geert Uytterhoeven <[email protected]>
Reviewed-by: Laurent Pinchart <[email protected]>
---
v3:
- No changes,

v2:
- Add Reviewed-by.
---
drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
index 91daab80b0ede058..381e184abf552c4c 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
@@ -196,7 +196,6 @@ static int shmob_drm_remove(struct platform_device *pdev)

drm_dev_unregister(ddev);
drm_kms_helper_poll_fini(ddev);
- free_irq(sdev->irq, ddev);
drm_dev_put(ddev);

return 0;
@@ -279,8 +278,8 @@ static int shmob_drm_probe(struct platform_device *pdev)
goto err_modeset_cleanup;
sdev->irq = ret;

- ret = request_irq(sdev->irq, shmob_drm_irq, 0, ddev->driver->name,
- ddev);
+ ret = devm_request_irq(&pdev->dev, sdev->irq, shmob_drm_irq, 0,
+ ddev->driver->name, ddev);
if (ret < 0) {
dev_err(&pdev->dev, "failed to install IRQ handler\n");
goto err_modeset_cleanup;
@@ -292,14 +291,12 @@ static int shmob_drm_probe(struct platform_device *pdev)
*/
ret = drm_dev_register(ddev, 0);
if (ret < 0)
- goto err_irq_uninstall;
+ goto err_modeset_cleanup;

drm_fbdev_generic_setup(ddev, 16);

return 0;

-err_irq_uninstall:
- free_irq(sdev->irq, ddev);
err_modeset_cleanup:
drm_kms_helper_poll_fini(ddev);
err_free_drm_dev:
--
2.34.1


2023-08-17 19:28:17

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH v3 33/41] 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]>
Reviewed-by: Laurent Pinchart <[email protected]>
---
v3:
- No changes,

v2:
- Add Reviewed-by.
---
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 20adb9d2fa178250..ab42a4999a55c475 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
@@ -271,6 +271,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;
}

@@ -283,10 +286,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);
@@ -519,6 +524,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 44f12bfcb3ce575d..78f9650e3a61365f 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
@@ -216,17 +216,17 @@ static int shmob_drm_probe(struct platform_device *pdev)
if (ret)
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-08-17 19:28:34

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH v3 15/41] 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]>
---
v3:
- No changes,

v2:
- No changes.

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 2ccb2fbfea26b5bf..015263ac2100c11e 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
@@ -55,24 +55,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);
@@ -180,8 +162,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 1157b4894ff319cd..782767fc66d00c4f 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-08-18 05:34:09

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH v3 32/41] 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]>
Reviewed-by: Laurent Pinchart <[email protected]>
---
v3:
- No changes,

v2:
- Add Reviewed-by.
---
.../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 0adf5d33ba31695e..20adb9d2fa178250 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
@@ -50,11 +50,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
*/
@@ -253,6 +282,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);

@@ -463,6 +498,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, DRM_PLANE_TYPE_PRIMARY, 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-08-18 19:42:20

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH v3 31/41] 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]>
Reviewed-by: Laurent Pinchart <[email protected]>
---
v3:
- No changes,

v2:
- Add Reviewed-by,
- Move further up.
---
.../gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 36 ++++++++++---------
1 file changed, 20 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 f55b5263e611c782..0adf5d33ba31695e 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
@@ -35,6 +35,26 @@
* TODO: panel support
*/

+/* -----------------------------------------------------------------------------
+ * 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
*/
@@ -364,22 +384,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-08-19 09:44:47

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH v3 37/41] 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

v3:
- No changes,

v2:
- No changes.
---
.../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 c277f93668825e1c..5c0575eed3ab6833 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>
@@ -319,27 +320,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)
{
@@ -356,13 +336,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-08-19 12:04:02

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH v3 21/41] 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]>
Reviewed-by: Laurent Pinchart <[email protected]>
---
v3:
- No changes,

v2:
- Add Reviewed-by.
---
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 9c66e00ed70ea582..207fa98fe76d6f88 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
@@ -258,7 +258,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)
{
@@ -538,8 +541,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-08-19 13:44:26

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH v3 11/41] 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]>
Reviewed-by: Laurent Pinchart <[email protected]>
---
v3:
- No changes,

v2:
- Add Reviewed-by.
---
.../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 a0e1a49c84d5691a..2cdf8f9b06e5feb8 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
@@ -191,31 +191,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) {
@@ -271,12 +252,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]
@@ -293,7 +274,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-08-19 17:51:31

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH v3 18/41] drm: renesas: shmobile: Remove custom plane destroy callback

There is no need to call drm_plane_force_disable() from the plane's
.destroy() callback, as the plane should have been disabled already
before. See also commit 3c858a33858baa8c ("drm/plane_helper: don't
disable plane in destroy function") for the generic plane helper case.

After removing this call, shmob_drm_plane_destroy() becomes a simple
wrapper around shmob_drm_plane_destroy(), hence replace it by the
latter.

Signed-off-by: Geert Uytterhoeven <[email protected]>
---
v3:
- No changes,

v2:
- New.
---
drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c | 8 +-------
1 file changed, 1 insertion(+), 7 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..3a5db319bad14218 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
@@ -176,16 +176,10 @@ 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,
+ .destroy = drm_plane_cleanup,
};

static const uint32_t formats[] = {
--
2.34.1


2023-08-20 02:11:57

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH v3 16/41] 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]>
Reviewed-by: Laurent Pinchart <[email protected]>
---
v3:
- No changes,

v2:
- Add Reviewed-by.
---
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 782767fc66d00c4f..91daab80b0ede058 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
@@ -255,7 +255,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-08-20 06:50:32

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH v3 40/41] 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]>
Reviewed-by: Laurent Pinchart <[email protected]>
---
v3:
- No changes,

v2:
- Add Reviewed-by.
---
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 e4d176b1f47654a8..729028a15efae00c 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
@@ -501,7 +501,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,
@@ -581,9 +580,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 b7643884b49f0bc8..58a16efde4e3cb4f 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-08-20 19:47:17

by Geert Uytterhoeven

[permalink] [raw]
Subject: [PATCH v3 06/41] 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]>
Reviewed-by: Laurent Pinchart <[email protected]>
---
v3:
- No changes,

v2:
- Add Reviewed-by.
---
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