From 41f2f2520983232c8caaf12aafebee994cb88484 Mon Sep 17 00:00:00 2001
From: Koichiro Iwao
Date: Fri, 24 May 2024 09:04:17 +0000
Subject: [PATCH] Raspberry Pi 5 support
---
.raspberrypi2.metadata | 5 +-
SOURCES/.keep | 0
SOURCES/bcm2709_selinux_config.patch | 64 -
SOURCES/bcm2711_selinux_config.patch | 118 -
SOURCES/rpi-6.1.x.patch | 262290 ------------------------
SPECS/raspberrypi2.spec | 135 +-
6 files changed, 46 insertions(+), 262566 deletions(-)
create mode 100644 SOURCES/.keep
delete mode 100644 SOURCES/bcm2709_selinux_config.patch
delete mode 100644 SOURCES/bcm2711_selinux_config.patch
delete mode 100644 SOURCES/rpi-6.1.x.patch
diff --git a/.raspberrypi2.metadata b/.raspberrypi2.metadata
index a2e00f5..988d3ba 100644
--- a/.raspberrypi2.metadata
+++ b/.raspberrypi2.metadata
@@ -1,3 +1,2 @@
-62f4117436e8eaa59e4974300a4481174a4ef1af SOURCES/cb9500d6021e083a182ba168fe4424e3db2494cf.tar.gz
-30996d7c1c59ddbd495bd9eb37c8dfdb1a67c1c3 SOURCES/linux-6.1.tar.xz
-7fb75dae049c3687780b214931dca33820ebddc9 SOURCES/patch-6.1.31.xz
+60c685b1ff49b11454c147944a6f4e9e24cd05db SOURCES/734829e3525e5baea62d1deedbe65eb60f4fb36b.tar.gz
+a975279af2634dd89b7a2d6a30eaab11240a88e8 SOURCES/stable_20240423.tar.gz
diff --git a/SOURCES/.keep b/SOURCES/.keep
new file mode 100644
index 0000000..e69de29
diff --git a/SOURCES/bcm2709_selinux_config.patch b/SOURCES/bcm2709_selinux_config.patch
deleted file mode 100644
index 60ae082..0000000
--- a/SOURCES/bcm2709_selinux_config.patch
+++ /dev/null
@@ -1,64 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Pablo Greco
-Date: Fri, 7 Aug 2020 02:59:05 +0000
-Subject: [PATCH 1/2] configs 2709
-
----
- arch/arm/configs/bcm2709_defconfig | 40 ++++++++++++++++++++++++++++--
- 1 file changed, 38 insertions(+), 2 deletions(-)
-
-diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig
-index 4b1f46c..537c622 100644
---- a/arch/arm/configs/bcm2709_defconfig
-+++ b/arch/arm/configs/bcm2709_defconfig
-@@ -1530,8 +1530,6 @@ CONFIG_NLS_KOI8_R=m
- CONFIG_NLS_KOI8_U=m
- CONFIG_DLM=m
- CONFIG_SECURITY=y
--CONFIG_SECURITY_APPARMOR=y
--CONFIG_LSM=""
- CONFIG_CRYPTO_USER=m
- CONFIG_CRYPTO_CAST5=m
- CONFIG_CRYPTO_DES=y
-@@ -1569,3 +1567,38 @@ CONFIG_IRQSOFF_TRACER=y
- CONFIG_SCHED_TRACER=y
- CONFIG_BLK_DEV_IO_TRACE=y
- # CONFIG_UPROBE_EVENTS is not set
-+
-+# CentOS added
-+CONFIG_AUDIT=y
-+CONFIG_NETLABEL=y
-+CONFIG_NETFILTER_XT_TARGET_AUDIT=m
-+CONFIG_IP_NF_SECURITY=m
-+CONFIG_IP6_NF_SECURITY=m
-+CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
-+CONFIG_NFSD_V4_SECURITY_LABEL=y
-+CONFIG_SECURITY_NETWORK=y
-+CONFIG_SECURITY_PATH=y
-+CONFIG_SECURITY_SELINUX=y
-+CONFIG_SECURITY_SELINUX_BOOTPARAM=y
-+CONFIG_SECURITY_SELINUX_DISABLE=y
-+CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
-+CONFIG_NET_TEAM=m
-+CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m
-+CONFIG_NET_TEAM_MODE_BROADCAST=m
-+CONFIG_NET_TEAM_MODE_LOADBALANCE=m
-+CONFIG_NET_TEAM_MODE_RANDOM=m
-+CONFIG_NET_TEAM_MODE_ROUNDROBIN=m
-+CONFIG_CRYPTO_BLAKE2S=m
-+CONFIG_CRYPTO_CURVE25519=m
-+CONFIG_CRYPTO_CURVE25519_NEON=m
-+CONFIG_CRYPTO_LIB_BLAKE2S=m
-+CONFIG_CRYPTO_LIB_CHACHA20POLY1305=m
-+CONFIG_CRYPTO_LIB_CHACHA=m
-+CONFIG_CRYPTO_LIB_CURVE25519=m
-+CONFIG_CRYPTO_LIB_POLY1305=m
-+CONFIG_CRYPTO_POLY1305_ARM=m
-+# CONFIG_WIREGUARD_DEBUG is not set
-+CONFIG_WIREGUARD=m
-+CONFIG_FW_LOADER_COMPRESS=y
-+CONFIG_FW_LOADER_COMPRESS_XZ=y
-+CONFIG_FW_LOADER_COMPRESS_ZSTD=y
---
-2.39.0
-
diff --git a/SOURCES/bcm2711_selinux_config.patch b/SOURCES/bcm2711_selinux_config.patch
deleted file mode 100644
index cfc88b0..0000000
--- a/SOURCES/bcm2711_selinux_config.patch
+++ /dev/null
@@ -1,118 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Pablo Greco
-Date: Fri, 7 Aug 2020 02:59:05 +0000
-Subject: [PATCH 2/2] configs 2711
-
----
- arch/arm/configs/bcm2711_defconfig | 35 +++++++++++++++++++++++++--
- arch/arm64/configs/bcm2711_defconfig | 36 ++++++++++++++++++++++++++--
- 2 files changed, 67 insertions(+), 4 deletions(-)
-
-diff --git a/arch/arm/configs/bcm2711_defconfig b/arch/arm/configs/bcm2711_defconfig
-index d31636c..28e0bbd 100644
---- a/arch/arm/configs/bcm2711_defconfig
-+++ b/arch/arm/configs/bcm2711_defconfig
-@@ -1556,8 +1556,6 @@ CONFIG_NLS_KOI8_R=m
- CONFIG_NLS_KOI8_U=m
- CONFIG_DLM=m
- CONFIG_SECURITY=y
--CONFIG_SECURITY_APPARMOR=y
--CONFIG_LSM=""
- CONFIG_CRYPTO_USER=m
- CONFIG_CRYPTO_CAST5=m
- CONFIG_CRYPTO_DES=y
-@@ -1595,3 +1593,38 @@ CONFIG_IRQSOFF_TRACER=y
- CONFIG_SCHED_TRACER=y
- CONFIG_BLK_DEV_IO_TRACE=y
- # CONFIG_UPROBE_EVENTS is not set
-+
-+# CentOS added
-+CONFIG_AUDIT=y
-+CONFIG_NETLABEL=y
-+CONFIG_NETFILTER_XT_TARGET_AUDIT=m
-+CONFIG_IP_NF_SECURITY=m
-+CONFIG_IP6_NF_SECURITY=m
-+CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
-+CONFIG_NFSD_V4_SECURITY_LABEL=y
-+CONFIG_SECURITY_NETWORK=y
-+CONFIG_SECURITY_PATH=y
-+CONFIG_SECURITY_SELINUX=y
-+CONFIG_SECURITY_SELINUX_BOOTPARAM=y
-+CONFIG_SECURITY_SELINUX_DISABLE=y
-+CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
-+CONFIG_NET_TEAM=m
-+CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m
-+CONFIG_NET_TEAM_MODE_BROADCAST=m
-+CONFIG_NET_TEAM_MODE_LOADBALANCE=m
-+CONFIG_NET_TEAM_MODE_RANDOM=m
-+CONFIG_NET_TEAM_MODE_ROUNDROBIN=m
-+CONFIG_CRYPTO_BLAKE2S=m
-+CONFIG_CRYPTO_CURVE25519=m
-+CONFIG_CRYPTO_CURVE25519_NEON=m
-+CONFIG_CRYPTO_LIB_BLAKE2S=m
-+CONFIG_CRYPTO_LIB_CHACHA20POLY1305=m
-+CONFIG_CRYPTO_LIB_CHACHA=m
-+CONFIG_CRYPTO_LIB_CURVE25519=m
-+CONFIG_CRYPTO_LIB_POLY1305=m
-+CONFIG_CRYPTO_POLY1305_ARM=m
-+# CONFIG_WIREGUARD_DEBUG is not set
-+CONFIG_WIREGUARD=m
-+CONFIG_FW_LOADER_COMPRESS=y
-+CONFIG_FW_LOADER_COMPRESS_XZ=y
-+CONFIG_FW_LOADER_COMPRESS_ZSTD=y
-diff --git a/arch/arm64/configs/bcm2711_defconfig b/arch/arm64/configs/bcm2711_defconfig
-index 55e6082..b9acdbc 100644
---- a/arch/arm64/configs/bcm2711_defconfig
-+++ b/arch/arm64/configs/bcm2711_defconfig
-@@ -1573,8 +1573,6 @@ CONFIG_NLS_KOI8_R=m
- CONFIG_NLS_KOI8_U=m
- CONFIG_DLM=m
- CONFIG_SECURITY=y
--CONFIG_SECURITY_APPARMOR=y
--CONFIG_LSM=""
- CONFIG_CRYPTO_USER=m
- CONFIG_CRYPTO_CRYPTD=m
- CONFIG_CRYPTO_AES=m
-@@ -1614,3 +1612,39 @@ CONFIG_IRQSOFF_TRACER=y
- CONFIG_SCHED_TRACER=y
- CONFIG_BLK_DEV_IO_TRACE=y
- # CONFIG_UPROBE_EVENTS is not set
-+
-+# CentOS added
-+CONFIG_AUDIT=y
-+CONFIG_NETLABEL=y
-+CONFIG_NETFILTER_XT_TARGET_AUDIT=m
-+CONFIG_IP_NF_SECURITY=m
-+CONFIG_IP6_NF_SECURITY=m
-+CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
-+CONFIG_NFSD_V4_SECURITY_LABEL=y
-+CONFIG_SECURITY_NETWORK=y
-+CONFIG_SECURITY_PATH=y
-+CONFIG_SECURITY_SELINUX=y
-+CONFIG_SECURITY_SELINUX_BOOTPARAM=y
-+CONFIG_SECURITY_SELINUX_DISABLE=y
-+CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
-+CONFIG_NET_TEAM=m
-+CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m
-+CONFIG_NET_TEAM_MODE_BROADCAST=m
-+CONFIG_NET_TEAM_MODE_LOADBALANCE=m
-+CONFIG_NET_TEAM_MODE_RANDOM=m
-+CONFIG_NET_TEAM_MODE_ROUNDROBIN=m
-+CONFIG_CRYPTO_BLAKE2S=m
-+CONFIG_CRYPTO_CURVE25519=m
-+CONFIG_CRYPTO_LIB_BLAKE2S=m
-+CONFIG_CRYPTO_LIB_CHACHA20POLY1305=m
-+CONFIG_CRYPTO_LIB_CHACHA=m
-+CONFIG_CRYPTO_LIB_CURVE25519=m
-+CONFIG_CRYPTO_LIB_POLY1305=m
-+CONFIG_CRYPTO_POLY1305_NEON=m
-+# CONFIG_EFI_CUSTOM_SSDT_OVERLAYS is not set
-+# CONFIG_WIREGUARD_DEBUG is not set
-+CONFIG_WIREGUARD=m
-+CONFIG_BLK_DEV_RBD=m
-+CONFIG_FW_LOADER_COMPRESS=y
-+CONFIG_FW_LOADER_COMPRESS_XZ=y
-+CONFIG_FW_LOADER_COMPRESS_ZSTD=y
---
-2.39.0
-
diff --git a/SOURCES/rpi-6.1.x.patch b/SOURCES/rpi-6.1.x.patch
deleted file mode 100644
index e5f32e8..0000000
--- a/SOURCES/rpi-6.1.x.patch
+++ /dev/null
@@ -1,262290 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Joerg Quinten
-Date: Fri, 18 Jun 2021 13:02:29 +0200
-Subject: [PATCH 001/784] Support RPi DPI interface in mode6 for 18-bit color
-
-A matching media bus format was added and an overlay for using it,
-both with FB and VC4 was added as well.
-
-Signed-off-by: Joerg Quinten
----
- drivers/gpu/drm/vc4/vc4_dpi.c | 6 ++++++
- 1 file changed, 6 insertions(+)
-
-diff --git a/drivers/gpu/drm/vc4/vc4_dpi.c b/drivers/gpu/drm/vc4/vc4_dpi.c
-index 61ef7d232a12..8ba53af107f8 100644
---- a/drivers/gpu/drm/vc4/vc4_dpi.c
-+++ b/drivers/gpu/drm/vc4/vc4_dpi.c
-@@ -170,10 +170,16 @@ static void vc4_dpi_encoder_enable(struct drm_encoder *encoder)
- dpi_c |= VC4_SET_FIELD(DPI_ORDER_BGR,
- DPI_ORDER);
- break;
-+ case MEDIA_BUS_FMT_BGR666_1X24_CPADHI:
-+ dpi_c |= VC4_SET_FIELD(DPI_ORDER_BGR, DPI_ORDER);
-+ fallthrough;
- case MEDIA_BUS_FMT_RGB666_1X24_CPADHI:
- dpi_c |= VC4_SET_FIELD(DPI_FORMAT_18BIT_666_RGB_2,
- DPI_FORMAT);
- break;
-+ case MEDIA_BUS_FMT_BGR666_1X18:
-+ dpi_c |= VC4_SET_FIELD(DPI_ORDER_BGR, DPI_ORDER);
-+ fallthrough;
- case MEDIA_BUS_FMT_RGB666_1X18:
- dpi_c |= VC4_SET_FIELD(DPI_FORMAT_18BIT_666_RGB_1,
- DPI_FORMAT);
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Dave Stevenson
-Date: Tue, 19 May 2020 16:20:30 +0100
-Subject: [PATCH 002/784] drm/vc4: Add FKMS as an acceptable node for dma
- ranges.
-
-Under FKMS, the firmware (via FKMS) also requires the VideoCore cache
-aliases for image planes, as defined by the dma-ranges under /soc.
-
-Add rpi-firmware-kms to the list of acceptable nodes to look for
-to copy dma config from.
-
-Signed-off-by: Dave Stevenson
----
- drivers/gpu/drm/vc4/vc4_drv.c | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
-index 8c329c071c62..5a1c2f3ded30 100644
---- a/drivers/gpu/drm/vc4/vc4_drv.c
-+++ b/drivers/gpu/drm/vc4/vc4_drv.c
-@@ -276,6 +276,7 @@ static void vc4_component_unbind_all(void *ptr)
- static const struct of_device_id vc4_dma_range_matches[] = {
- { .compatible = "brcm,bcm2711-hvs" },
- { .compatible = "brcm,bcm2835-hvs" },
-+ { .compatible = "raspberrypi,rpi-firmware-kms" },
- { .compatible = "brcm,bcm2835-v3d" },
- { .compatible = "brcm,cygnus-v3d" },
- { .compatible = "brcm,vc4-v3d" },
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Dave Stevenson
-Date: Mon, 26 Oct 2020 12:38:27 +0000
-Subject: [PATCH 003/784] drm/vc4: Add the 2711 HVS as a suitable DMA node
-
-With vc4-drv node not being under /soc on Pi4, we need to
-adopt the correct DMA parameters from a suitable sub-component.
-Add "brcm,bcm2711-hvs" to that list of components.
-
-Signed-off-by: Dave Stevenson
----
- drivers/gpu/drm/vc4/vc4_drv.c | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
-index 5a1c2f3ded30..f8053b591317 100644
---- a/drivers/gpu/drm/vc4/vc4_drv.c
-+++ b/drivers/gpu/drm/vc4/vc4_drv.c
-@@ -276,6 +276,7 @@ static void vc4_component_unbind_all(void *ptr)
- static const struct of_device_id vc4_dma_range_matches[] = {
- { .compatible = "brcm,bcm2711-hvs" },
- { .compatible = "brcm,bcm2835-hvs" },
-+ { .compatible = "brcm,bcm2711-hvs" },
- { .compatible = "raspberrypi,rpi-firmware-kms" },
- { .compatible = "brcm,bcm2835-v3d" },
- { .compatible = "brcm,cygnus-v3d" },
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Dave Stevenson
-Date: Fri, 12 Feb 2021 17:31:37 +0000
-Subject: [PATCH 004/784] drm/vc4: Change the default DPI format to being
- 18bpp, not 24.
-
-DPI hasn't really been used up until now, so the default has
-been meaningless.
-In theory we should be able to pass the desired format for the
-adjacent bridge chip through, but framework seems to be missing
-for that.
-
-As the main device to use DPI is the VGA666 or Adafruit Kippah,
-both of which use RGB666, change the default to being RGB666 instead
-of RGB888.
-
-Signed-off-by: Dave Stevenson
----
- drivers/gpu/drm/vc4/vc4_dpi.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/drivers/gpu/drm/vc4/vc4_dpi.c b/drivers/gpu/drm/vc4/vc4_dpi.c
-index 8ba53af107f8..96b5d34f6bd7 100644
---- a/drivers/gpu/drm/vc4/vc4_dpi.c
-+++ b/drivers/gpu/drm/vc4/vc4_dpi.c
-@@ -150,8 +150,8 @@ static void vc4_dpi_encoder_enable(struct drm_encoder *encoder)
- }
- drm_connector_list_iter_end(&conn_iter);
-
-- /* Default to 24bit if no connector or format found. */
-- dpi_c |= VC4_SET_FIELD(DPI_FORMAT_24BIT_888_RGB, DPI_FORMAT);
-+ /* Default to 18bit if no connector or format found. */
-+ dpi_c |= VC4_SET_FIELD(DPI_FORMAT_18BIT_666_RGB_1, DPI_FORMAT);
-
- if (connector) {
- if (connector->display_info.num_bus_formats) {
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Dave Stevenson
-Date: Thu, 7 Jan 2021 16:30:55 +0000
-Subject: [PATCH 005/784] drm/atomic: Don't fixup modes that haven't been reset
-
-Signed-off-by: Dave Stevenson
----
- drivers/gpu/drm/drm_atomic_helper.c | 5 +++++
- 1 file changed, 5 insertions(+)
-
-diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
-index 02b4a7dc92f5..f3e59236a8ee 100644
---- a/drivers/gpu/drm/drm_atomic_helper.c
-+++ b/drivers/gpu/drm/drm_atomic_helper.c
-@@ -438,6 +438,11 @@ mode_fixup(struct drm_atomic_state *state)
- new_crtc_state =
- drm_atomic_get_new_crtc_state(state, new_conn_state->crtc);
-
-+ if (!new_crtc_state->mode_changed &&
-+ !new_crtc_state->connectors_changed) {
-+ continue;
-+ }
-+
- /*
- * Each encoder has at most one connector (since we always steal
- * it away), so we won't call ->mode_fixup twice.
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Mateusz Kwiatkowski
-Date: Thu, 15 Jul 2021 01:07:30 +0200
-Subject: [PATCH 006/784] drm/vc4: Fix timings for VEC modes
-
-This commit fixes vertical timings of the VEC (composite output) modes
-to accurately represent the 525-line ("NTSC") and 625-line ("PAL") ITU-R
-standards.
-
-Previous timings were actually defined as 502 and 601 lines, resulting
-in non-standard 62.69 Hz and 52 Hz signals being generated,
-respectively.
-
-Changes to vc4_crtc.c have also been made, to make the PixelValve
-vertical timings accurately correspond to the DRM modeline in interlaced
-modes. The resulting VERTA/VERTB register values have been verified
-against the reference values set by the Raspberry Pi firmware.
-
-Signed-off-by: Mateusz Kwiatkowski
----
- drivers/gpu/drm/vc4/vc4_crtc.c | 70 +++++++++++++++++++++-------------
- 1 file changed, 43 insertions(+), 27 deletions(-)
-
-diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
-index 7258975331ca..308b0e1c8af4 100644
---- a/drivers/gpu/drm/vc4/vc4_crtc.c
-+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
-@@ -326,8 +326,14 @@ static void vc4_crtc_config_pv(struct drm_crtc *crtc, struct drm_encoder *encode
- bool is_dsi = (vc4_encoder->type == VC4_ENCODER_TYPE_DSI0 ||
- vc4_encoder->type == VC4_ENCODER_TYPE_DSI1);
- bool is_dsi1 = vc4_encoder->type == VC4_ENCODER_TYPE_DSI1;
-+ bool is_vec = vc4_encoder->type == VC4_ENCODER_TYPE_VEC;
- u32 format = is_dsi1 ? PV_CONTROL_FORMAT_DSIV_24 : PV_CONTROL_FORMAT_24;
- u8 ppc = pv_data->pixels_per_clock;
-+
-+ u16 vert_bp = mode->crtc_vtotal - mode->crtc_vsync_end;
-+ u16 vert_sync = mode->crtc_vsync_end - mode->crtc_vsync_start;
-+ u16 vert_fp = mode->crtc_vsync_start - mode->crtc_vdisplay;
-+
- bool debug_dump_regs = false;
- int idx;
-
-@@ -355,49 +361,59 @@ static void vc4_crtc_config_pv(struct drm_crtc *crtc, struct drm_encoder *encode
- VC4_SET_FIELD(mode->hdisplay * pixel_rep / ppc,
- PV_HORZB_HACTIVE));
-
-- CRTC_WRITE(PV_VERTA,
-- VC4_SET_FIELD(mode->crtc_vtotal - mode->crtc_vsync_end +
-- interlace,
-- PV_VERTA_VBP) |
-- VC4_SET_FIELD(mode->crtc_vsync_end - mode->crtc_vsync_start,
-- PV_VERTA_VSYNC));
-- CRTC_WRITE(PV_VERTB,
-- VC4_SET_FIELD(mode->crtc_vsync_start - mode->crtc_vdisplay,
-- PV_VERTB_VFP) |
-- VC4_SET_FIELD(mode->crtc_vdisplay, PV_VERTB_VACTIVE));
--
- if (interlace) {
-+ bool odd_field_first = false;
-+ u32 field_delay = mode->htotal * pixel_rep / (2 * ppc);
-+ u16 vert_bp_even = vert_bp;
-+ u16 vert_fp_even = vert_fp;
-+
-+ if (is_vec) {
-+ /* VEC (composite output) */
-+ ++field_delay;
-+ if (mode->htotal == 858) {
-+ /* 525-line mode (NTSC or PAL-M) */
-+ odd_field_first = true;
-+ }
-+ }
-+
-+ if (odd_field_first)
-+ ++vert_fp_even;
-+ else
-+ ++vert_bp;
-+
- CRTC_WRITE(PV_VERTA_EVEN,
-- VC4_SET_FIELD(mode->crtc_vtotal -
-- mode->crtc_vsync_end,
-- PV_VERTA_VBP) |
-- VC4_SET_FIELD(mode->crtc_vsync_end -
-- mode->crtc_vsync_start,
-- PV_VERTA_VSYNC));
-+ VC4_SET_FIELD(vert_bp_even, PV_VERTA_VBP) |
-+ VC4_SET_FIELD(vert_sync, PV_VERTA_VSYNC));
- CRTC_WRITE(PV_VERTB_EVEN,
-- VC4_SET_FIELD(mode->crtc_vsync_start -
-- mode->crtc_vdisplay,
-- PV_VERTB_VFP) |
-+ VC4_SET_FIELD(vert_fp_even, PV_VERTB_VFP) |
- VC4_SET_FIELD(mode->crtc_vdisplay, PV_VERTB_VACTIVE));
-
-- /* We set up first field even mode for HDMI. VEC's
-- * NTSC mode would want first field odd instead, once
-- * we support it (to do so, set ODD_FIRST and put the
-- * delay in VSYNCD_EVEN instead).
-+ /* We set up first field even mode for HDMI and VEC's PAL.
-+ * For NTSC, we need first field odd.
- */
- CRTC_WRITE(PV_V_CONTROL,
- PV_VCONTROL_CONTINUOUS |
- (is_dsi ? PV_VCONTROL_DSI : 0) |
- PV_VCONTROL_INTERLACE |
-- VC4_SET_FIELD(mode->htotal * pixel_rep / (2 * ppc),
-- PV_VCONTROL_ODD_DELAY));
-- CRTC_WRITE(PV_VSYNCD_EVEN, 0);
-+ (odd_field_first
-+ ? PV_VCONTROL_ODD_FIRST
-+ : VC4_SET_FIELD(field_delay,
-+ PV_VCONTROL_ODD_DELAY)));
-+ CRTC_WRITE(PV_VSYNCD_EVEN,
-+ (odd_field_first ? field_delay : 0));
- } else {
- CRTC_WRITE(PV_V_CONTROL,
- PV_VCONTROL_CONTINUOUS |
- (is_dsi ? PV_VCONTROL_DSI : 0));
- }
-
-+ CRTC_WRITE(PV_VERTA,
-+ VC4_SET_FIELD(vert_bp, PV_VERTA_VBP) |
-+ VC4_SET_FIELD(vert_sync, PV_VERTA_VSYNC));
-+ CRTC_WRITE(PV_VERTB,
-+ VC4_SET_FIELD(vert_fp, PV_VERTB_VFP) |
-+ VC4_SET_FIELD(mode->crtc_vdisplay, PV_VERTB_VACTIVE));
-+
- if (is_dsi)
- CRTC_WRITE(PV_HACT_ACT, mode->hdisplay * pixel_rep);
-
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Mateusz Kwiatkowski
-Date: Thu, 15 Jul 2021 01:07:53 +0200
-Subject: [PATCH 007/784] drm/vc4: Fix definition of PAL-M mode
-
-PAL-M is a Brazilian analog TV standard that uses a PAL-style chroma
-subcarrier at 3.575611[888111] MHz on top of 525-line (480i60) timings.
-This commit makes the driver actually use the proper VEC preset for this
-mode instead of just changing PAL subcarrier frequency.
-
-DRM mode constant names have also been changed, as they no longer
-correspond to the "NTSC" or "PAL" terms.
-
-Signed-off-by: Mateusz Kwiatkowski
----
- drivers/gpu/drm/vc4/vc4_vec.c | 18 +++++++++---------
- 1 file changed, 9 insertions(+), 9 deletions(-)
-
-diff --git a/drivers/gpu/drm/vc4/vc4_vec.c b/drivers/gpu/drm/vc4/vc4_vec.c
-index 0b3333865702..de4dec160e72 100644
---- a/drivers/gpu/drm/vc4/vc4_vec.c
-+++ b/drivers/gpu/drm/vc4/vc4_vec.c
-@@ -69,6 +69,7 @@
- #define VEC_CONFIG0_STD_MASK GENMASK(1, 0)
- #define VEC_CONFIG0_NTSC_STD 0
- #define VEC_CONFIG0_PAL_BDGHI_STD 1
-+#define VEC_CONFIG0_PAL_M_STD 2
- #define VEC_CONFIG0_PAL_N_STD 3
-
- #define VEC_SCHPH 0x108
-@@ -224,14 +225,14 @@ static const struct debugfs_reg32 vec_regs[] = {
- VC4_REG32(VEC_DAC_MISC),
- };
-
--static const struct drm_display_mode ntsc_mode = {
-+static const struct drm_display_mode drm_mode_480i = {
- DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 13500,
- 720, 720 + 14, 720 + 14 + 64, 720 + 14 + 64 + 60, 0,
- 480, 480 + 7, 480 + 7 + 6, 525, 0,
- DRM_MODE_FLAG_INTERLACE)
- };
-
--static const struct drm_display_mode pal_mode = {
-+static const struct drm_display_mode drm_mode_576i = {
- DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 13500,
- 720, 720 + 20, 720 + 20 + 64, 720 + 20 + 64 + 60, 0,
- 576, 576 + 4, 576 + 4 + 6, 625, 0,
-@@ -240,25 +241,24 @@ static const struct drm_display_mode pal_mode = {
-
- static const struct vc4_vec_tv_mode vc4_vec_tv_modes[] = {
- [VC4_VEC_TV_MODE_NTSC] = {
-- .mode = &ntsc_mode,
-+ .mode = &drm_mode_480i,
- .config0 = VEC_CONFIG0_NTSC_STD | VEC_CONFIG0_PDEN,
- .config1 = VEC_CONFIG1_C_CVBS_CVBS,
- },
- [VC4_VEC_TV_MODE_NTSC_J] = {
-- .mode = &ntsc_mode,
-+ .mode = &drm_mode_480i,
- .config0 = VEC_CONFIG0_NTSC_STD,
- .config1 = VEC_CONFIG1_C_CVBS_CVBS,
- },
- [VC4_VEC_TV_MODE_PAL] = {
-- .mode = &pal_mode,
-+ .mode = &drm_mode_576i,
- .config0 = VEC_CONFIG0_PAL_BDGHI_STD,
- .config1 = VEC_CONFIG1_C_CVBS_CVBS,
- },
- [VC4_VEC_TV_MODE_PAL_M] = {
-- .mode = &pal_mode,
-- .config0 = VEC_CONFIG0_PAL_BDGHI_STD,
-- .config1 = VEC_CONFIG1_C_CVBS_CVBS | VEC_CONFIG1_CUSTOM_FREQ,
-- .custom_freq = 0x223b61d1,
-+ .mode = &drm_mode_480i,
-+ .config0 = VEC_CONFIG0_PAL_M_STD,
-+ .config1 = VEC_CONFIG1_C_CVBS_CVBS,
- },
- };
-
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Mateusz Kwiatkowski
-Date: Thu, 15 Jul 2021 01:07:58 +0200
-Subject: [PATCH 008/784] drm/vc4: Add support for more analog TV standards
-
-Add support for the following composite output modes (all of them are
-somewhat more obscure than the previously defined ones):
-
-- NTSC_443 - NTSC-style signal with the chroma subcarrier shifted to
- 4.43361875 MHz (the PAL subcarrier frequency). Never used for
- broadcasting, but sometimes used as a hack to play NTSC content in PAL
- regions (e.g. on VCRs).
-- PAL_N - PAL with alternative chroma subcarrier frequency,
- 3.58205625 MHz. Used as a broadcast standard in Argentina, Paraguay
- and Uruguay to fit 576i50 with colour in 6 MHz channel raster.
-- PAL60 - 480i60 signal with PAL-style color at normal European PAL
- frequency. Another non-standard, non-broadcast mode, used in similar
- contexts as NTSC_443. Some displays support one but not the other.
-- SECAM - French frequency-modulated analog color standard; also have
- been broadcast in Eastern Europe and various parts of Africa and Asia.
- Uses the same 576i50 timings as PAL.
-
-Also added some comments explaining color subcarrier frequency
-registers.
-
-Signed-off-by: Mateusz Kwiatkowski
----
- drivers/gpu/drm/vc4/vc4_vec.c | 63 +++++++++++++++++++++++++++++++++++
- 1 file changed, 63 insertions(+)
-
-diff --git a/drivers/gpu/drm/vc4/vc4_vec.c b/drivers/gpu/drm/vc4/vc4_vec.c
-index de4dec160e72..edf73378bfe6 100644
---- a/drivers/gpu/drm/vc4/vc4_vec.c
-+++ b/drivers/gpu/drm/vc4/vc4_vec.c
-@@ -46,6 +46,7 @@
- #define VEC_CONFIG0_YDEL(x) ((x) << 26)
- #define VEC_CONFIG0_CDEL_MASK GENMASK(25, 24)
- #define VEC_CONFIG0_CDEL(x) ((x) << 24)
-+#define VEC_CONFIG0_SECAM_STD BIT(21)
- #define VEC_CONFIG0_PBPR_FIL BIT(18)
- #define VEC_CONFIG0_CHROMA_GAIN_MASK GENMASK(17, 16)
- #define VEC_CONFIG0_CHROMA_GAIN_UNITY (0 << 16)
-@@ -76,6 +77,27 @@
- #define VEC_SOFT_RESET 0x10c
- #define VEC_CLMP0_START 0x144
- #define VEC_CLMP0_END 0x148
-+
-+/*
-+ * These set the color subcarrier frequency
-+ * if VEC_CONFIG1_CUSTOM_FREQ is enabled.
-+ *
-+ * VEC_FREQ1_0 contains the most significant 16-bit half-word,
-+ * VEC_FREQ3_2 contains the least significant 16-bit half-word.
-+ * 0x80000000 seems to be equivalent to the pixel clock
-+ * (which itself is the VEC clock divided by 8).
-+ *
-+ * Reference values (with the default pixel clock of 13.5 MHz):
-+ *
-+ * NTSC (3579545.[45] Hz) - 0x21F07C1F
-+ * PAL (4433618.75 Hz) - 0x2A098ACB
-+ * PAL-M (3575611.[888111] Hz) - 0x21E6EFE3
-+ * PAL-N (3582056.25 Hz) - 0x21F69446
-+ *
-+ * NOTE: For SECAM, it is used as the Dr center frequency,
-+ * regardless of whether VEC_CONFIG1_CUSTOM_FREQ is enabled or not;
-+ * that is specified as 4406250 Hz, which corresponds to 0x29C71C72.
-+ */
- #define VEC_FREQ3_2 0x180
- #define VEC_FREQ1_0 0x184
-
-@@ -118,6 +140,14 @@
-
- #define VEC_INTERRUPT_CONTROL 0x190
- #define VEC_INTERRUPT_STATUS 0x194
-+
-+/*
-+ * Db center frequency for SECAM; the clock for this is the same as for
-+ * VEC_FREQ3_2/VEC_FREQ1_0, which is used for Dr center frequency.
-+ *
-+ * This is specified as 4250000 Hz, which corresponds to 0x284BDA13.
-+ * That is also the default value, so no need to set it explicitly.
-+ */
- #define VEC_FCW_SECAM_B 0x198
- #define VEC_SECAM_GAIN_VAL 0x19c
-
-@@ -187,8 +217,12 @@ encoder_to_vc4_vec(struct drm_encoder *encoder)
- enum vc4_vec_tv_mode_id {
- VC4_VEC_TV_MODE_NTSC,
- VC4_VEC_TV_MODE_NTSC_J,
-+ VC4_VEC_TV_MODE_NTSC_443,
- VC4_VEC_TV_MODE_PAL,
- VC4_VEC_TV_MODE_PAL_M,
-+ VC4_VEC_TV_MODE_PAL_N,
-+ VC4_VEC_TV_MODE_PAL60,
-+ VC4_VEC_TV_MODE_SECAM,
- };
-
- struct vc4_vec_tv_mode {
-@@ -250,6 +284,13 @@ static const struct vc4_vec_tv_mode vc4_vec_tv_modes[] = {
- .config0 = VEC_CONFIG0_NTSC_STD,
- .config1 = VEC_CONFIG1_C_CVBS_CVBS,
- },
-+ [VC4_VEC_TV_MODE_NTSC_443] = {
-+ /* NTSC with PAL chroma frequency */
-+ .mode = &drm_mode_480i,
-+ .config0 = VEC_CONFIG0_NTSC_STD,
-+ .config1 = VEC_CONFIG1_C_CVBS_CVBS | VEC_CONFIG1_CUSTOM_FREQ,
-+ .custom_freq = 0x2a098acb,
-+ },
- [VC4_VEC_TV_MODE_PAL] = {
- .mode = &drm_mode_576i,
- .config0 = VEC_CONFIG0_PAL_BDGHI_STD,
-@@ -260,6 +301,24 @@ static const struct vc4_vec_tv_mode vc4_vec_tv_modes[] = {
- .config0 = VEC_CONFIG0_PAL_M_STD,
- .config1 = VEC_CONFIG1_C_CVBS_CVBS,
- },
-+ [VC4_VEC_TV_MODE_PAL_N] = {
-+ .mode = &drm_mode_576i,
-+ .config0 = VEC_CONFIG0_PAL_N_STD,
-+ .config1 = VEC_CONFIG1_C_CVBS_CVBS,
-+ },
-+ [VC4_VEC_TV_MODE_PAL60] = {
-+ /* PAL-M with chroma frequency of regular PAL */
-+ .mode = &drm_mode_480i,
-+ .config0 = VEC_CONFIG0_PAL_M_STD,
-+ .config1 = VEC_CONFIG1_C_CVBS_CVBS | VEC_CONFIG1_CUSTOM_FREQ,
-+ .custom_freq = 0x2a098acb,
-+ },
-+ [VC4_VEC_TV_MODE_SECAM] = {
-+ .mode = &drm_mode_576i,
-+ .config0 = VEC_CONFIG0_SECAM_STD,
-+ .config1 = VEC_CONFIG1_C_CVBS_CVBS,
-+ .custom_freq = 0x29c71c72,
-+ },
- };
-
- static enum drm_connector_status
-@@ -503,8 +562,12 @@ static const struct of_device_id vc4_vec_dt_match[] = {
- static const char * const tv_mode_names[] = {
- [VC4_VEC_TV_MODE_NTSC] = "NTSC",
- [VC4_VEC_TV_MODE_NTSC_J] = "NTSC-J",
-+ [VC4_VEC_TV_MODE_NTSC_443] = "NTSC-443",
- [VC4_VEC_TV_MODE_PAL] = "PAL",
- [VC4_VEC_TV_MODE_PAL_M] = "PAL-M",
-+ [VC4_VEC_TV_MODE_PAL_N] = "PAL-N",
-+ [VC4_VEC_TV_MODE_PAL60] = "PAL60",
-+ [VC4_VEC_TV_MODE_SECAM] = "SECAM",
- };
-
- static int vc4_vec_bind(struct device *dev, struct device *master, void *data)
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Mateusz Kwiatkowski
-Date: Thu, 15 Jul 2021 01:08:01 +0200
-Subject: [PATCH 009/784] drm/vc4: Allow setting the TV norm via module
- parameter
-
-Similar to the ch7006 and nouveau drivers, introduce a "tv_mode" module
-parameter that allow setting the TV norm by specifying vc4.tv_norm= on
-the kernel command line.
-
-If that is not specified, try inferring one of the most popular norms
-(PAL or NTSC) from the video mode specified on the command line. On
-Raspberry Pis, this causes the most common cases of the sdtv_mode
-setting in config.txt to be respected.
-
-Signed-off-by: Mateusz Kwiatkowski
----
- drivers/gpu/drm/vc4/vc4_vec.c | 72 ++++++++++++++++++++++++++++-------
- 1 file changed, 58 insertions(+), 14 deletions(-)
-
-diff --git a/drivers/gpu/drm/vc4/vc4_vec.c b/drivers/gpu/drm/vc4/vc4_vec.c
-index edf73378bfe6..369a5e79676b 100644
---- a/drivers/gpu/drm/vc4/vc4_vec.c
-+++ b/drivers/gpu/drm/vc4/vc4_vec.c
-@@ -67,7 +67,7 @@
- #define VEC_CONFIG0_YCDELAY BIT(4)
- #define VEC_CONFIG0_RAMPEN BIT(2)
- #define VEC_CONFIG0_YCDIS BIT(2)
--#define VEC_CONFIG0_STD_MASK GENMASK(1, 0)
-+#define VEC_CONFIG0_STD_MASK (VEC_CONFIG0_SECAM_STD | GENMASK(1, 0))
- #define VEC_CONFIG0_NTSC_STD 0
- #define VEC_CONFIG0_PAL_BDGHI_STD 1
- #define VEC_CONFIG0_PAL_M_STD 2
-@@ -186,6 +186,8 @@
- #define VEC_DAC_MISC_DAC_RST_N BIT(0)
-
-
-+static char *vc4_vec_tv_norm;
-+
- struct vc4_vec_variant {
- u32 dac_config;
- };
-@@ -321,6 +323,44 @@ static const struct vc4_vec_tv_mode vc4_vec_tv_modes[] = {
- },
- };
-
-+static const char * const tv_mode_names[] = {
-+ [VC4_VEC_TV_MODE_NTSC] = "NTSC",
-+ [VC4_VEC_TV_MODE_NTSC_J] = "NTSC-J",
-+ [VC4_VEC_TV_MODE_NTSC_443] = "NTSC-443",
-+ [VC4_VEC_TV_MODE_PAL] = "PAL",
-+ [VC4_VEC_TV_MODE_PAL_M] = "PAL-M",
-+ [VC4_VEC_TV_MODE_PAL_N] = "PAL-N",
-+ [VC4_VEC_TV_MODE_PAL60] = "PAL60",
-+ [VC4_VEC_TV_MODE_SECAM] = "SECAM",
-+};
-+
-+enum vc4_vec_tv_mode_id
-+vc4_vec_get_default_mode(struct drm_connector *connector)
-+{
-+ int i;
-+
-+ if (vc4_vec_tv_norm) {
-+ for (i = 0; i < ARRAY_SIZE(tv_mode_names); i++)
-+ if (strcmp(vc4_vec_tv_norm, tv_mode_names[i]) == 0)
-+ return (enum vc4_vec_tv_mode_id) i;
-+ } else if (connector->cmdline_mode.specified &&
-+ ((connector->cmdline_mode.refresh_specified &&
-+ (connector->cmdline_mode.refresh == 25 ||
-+ connector->cmdline_mode.refresh == 50)) ||
-+ (!connector->cmdline_mode.refresh_specified &&
-+ (connector->cmdline_mode.yres == 288 ||
-+ connector->cmdline_mode.yres == 576)))) {
-+ /*
-+ * no explicitly specified TV norm; use PAL if a mode that
-+ * looks like PAL has been specified on the command line
-+ */
-+ return VC4_VEC_TV_MODE_PAL;
-+ }
-+
-+ /* in all other cases, default to NTSC */
-+ return VC4_VEC_TV_MODE_NTSC;
-+}
-+
- static enum drm_connector_status
- vc4_vec_connector_detect(struct drm_connector *connector, bool force)
- {
-@@ -344,10 +384,18 @@ static int vc4_vec_connector_get_modes(struct drm_connector *connector)
- return 1;
- }
-
-+static void vc4_vec_connector_reset(struct drm_connector *connector)
-+{
-+ drm_atomic_helper_connector_reset(connector);
-+ /* preserve TV standard */
-+ if (connector->state)
-+ connector->state->tv.mode = vc4_vec_get_default_mode(connector);
-+}
-+
- static const struct drm_connector_funcs vc4_vec_connector_funcs = {
- .detect = vc4_vec_connector_detect,
- .fill_modes = drm_helper_probe_single_connector_modes,
-- .reset = drm_atomic_helper_connector_reset,
-+ .reset = vc4_vec_connector_reset,
- .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
- .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
- };
-@@ -372,7 +420,7 @@ static int vc4_vec_connector_init(struct drm_device *dev, struct vc4_vec *vec)
-
- drm_object_attach_property(&connector->base,
- dev->mode_config.tv_mode_property,
-- VC4_VEC_TV_MODE_NTSC);
-+ vc4_vec_get_default_mode(connector));
-
- drm_connector_attach_encoder(connector, &vec->encoder.base);
-
-@@ -559,17 +607,6 @@ static const struct of_device_id vc4_vec_dt_match[] = {
- { /* sentinel */ },
- };
-
--static const char * const tv_mode_names[] = {
-- [VC4_VEC_TV_MODE_NTSC] = "NTSC",
-- [VC4_VEC_TV_MODE_NTSC_J] = "NTSC-J",
-- [VC4_VEC_TV_MODE_NTSC_443] = "NTSC-443",
-- [VC4_VEC_TV_MODE_PAL] = "PAL",
-- [VC4_VEC_TV_MODE_PAL_M] = "PAL-M",
-- [VC4_VEC_TV_MODE_PAL_N] = "PAL-N",
-- [VC4_VEC_TV_MODE_PAL60] = "PAL60",
-- [VC4_VEC_TV_MODE_SECAM] = "SECAM",
--};
--
- static int vc4_vec_bind(struct device *dev, struct device *master, void *data)
- {
- struct platform_device *pdev = to_platform_device(dev);
-@@ -650,3 +687,10 @@ struct platform_driver vc4_vec_driver = {
- .of_match_table = vc4_vec_dt_match,
- },
- };
-+
-+module_param_named(tv_norm, vc4_vec_tv_norm, charp, 0600);
-+MODULE_PARM_DESC(tv_norm, "Default TV norm.\n"
-+ "\t\tSupported: NTSC, NTSC-J, NTSC-443, PAL, PAL-M, PAL-N,\n"
-+ "\t\t\tPAL60, SECAM.\n"
-+ "\t\tDefault: PAL if a 50 Hz mode has been set via video=,\n"
-+ "\t\t\tNTSC otherwise");
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Mateusz Kwiatkowski
-Date: Thu, 15 Jul 2021 01:08:05 +0200
-Subject: [PATCH 010/784] drm/vc4: Refactor mode checking logic
-
-Replace drm_encoder_helper_funcs::atomic_check with
-drm_connector_helper_funcs::atomic_check - the former is not called
-during drm_mode_obj_set_property_ioctl(). Set crtc_state->mode_changed
-if TV norm changes even without explicit mode change. This makes things
-like "xrandr --output Composite-1 --set mode PAL-M" work properly.
-
-Signed-off-by: Mateusz Kwiatkowski
----
- drivers/gpu/drm/vc4/vc4_vec.c | 42 ++++++++++++++++++++++-------------
- 1 file changed, 26 insertions(+), 16 deletions(-)
-
-diff --git a/drivers/gpu/drm/vc4/vc4_vec.c b/drivers/gpu/drm/vc4/vc4_vec.c
-index 369a5e79676b..c613f930f079 100644
---- a/drivers/gpu/drm/vc4/vc4_vec.c
-+++ b/drivers/gpu/drm/vc4/vc4_vec.c
-@@ -392,6 +392,31 @@ static void vc4_vec_connector_reset(struct drm_connector *connector)
- connector->state->tv.mode = vc4_vec_get_default_mode(connector);
- }
-
-+static int vc4_vec_connector_atomic_check(struct drm_connector *conn,
-+ struct drm_atomic_state *state)
-+{
-+ struct drm_connector_state *old_state =
-+ drm_atomic_get_old_connector_state(state, conn);
-+ struct drm_connector_state *new_state =
-+ drm_atomic_get_new_connector_state(state, conn);
-+
-+ const struct vc4_vec_tv_mode *vec_mode =
-+ &vc4_vec_tv_modes[new_state->tv.mode];
-+
-+ if (new_state->crtc) {
-+ struct drm_crtc_state *crtc_state =
-+ drm_atomic_get_new_crtc_state(state, new_state->crtc);
-+
-+ if (!drm_mode_equal(vec_mode->mode, &crtc_state->mode))
-+ return -EINVAL;
-+
-+ if (old_state->tv.mode != new_state->tv.mode)
-+ crtc_state->mode_changed = true;
-+ }
-+
-+ return 0;
-+}
-+
- static const struct drm_connector_funcs vc4_vec_connector_funcs = {
- .detect = vc4_vec_connector_detect,
- .fill_modes = drm_helper_probe_single_connector_modes,
-@@ -402,6 +427,7 @@ static const struct drm_connector_funcs vc4_vec_connector_funcs = {
-
- static const struct drm_connector_helper_funcs vc4_vec_connector_helper_funcs = {
- .get_modes = vc4_vec_connector_get_modes,
-+ .atomic_check = vc4_vec_connector_atomic_check,
- };
-
- static int vc4_vec_connector_init(struct drm_device *dev, struct vc4_vec *vec)
-@@ -550,23 +576,7 @@ static void vc4_vec_encoder_enable(struct drm_encoder *encoder,
- drm_dev_exit(idx);
- }
-
--static int vc4_vec_encoder_atomic_check(struct drm_encoder *encoder,
-- struct drm_crtc_state *crtc_state,
-- struct drm_connector_state *conn_state)
--{
-- const struct vc4_vec_tv_mode *vec_mode;
--
-- vec_mode = &vc4_vec_tv_modes[conn_state->tv.mode];
--
-- if (conn_state->crtc &&
-- !drm_mode_equal(vec_mode->mode, &crtc_state->adjusted_mode))
-- return -EINVAL;
--
-- return 0;
--}
--
- static const struct drm_encoder_helper_funcs vc4_vec_encoder_helper_funcs = {
-- .atomic_check = vc4_vec_encoder_atomic_check,
- .atomic_disable = vc4_vec_encoder_disable,
- .atomic_enable = vc4_vec_encoder_enable,
- };
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Dave Stevenson
-Date: Mon, 7 Sep 2020 17:32:27 +0100
-Subject: [PATCH 011/784] drm/vc4: Add firmware-kms mode
-
-This is a squash of all firmware-kms related patches from previous
-branches, up to and including
-"drm/vc4: Set the possible crtcs mask correctly for planes with FKMS"
-plus a couple of minor fixups for the 5.9 branch.
-Please refer to earlier branches for full history.
-
-This patch includes work by Eric Anholt, James Hughes, Phil Elwell,
-Dave Stevenson, Dom Cobley, and Jonathon Bell.
-
-Signed-off-by: Dave Stevenson
-
-drm/vc4: Fixup firmware-kms after "drm/atomic: Pass the full state to CRTC atomic enable/disable"
-
-Prototype for those calls changed, so amend fkms (which isn't
-upstream) to match.
-
-Signed-off-by: Dave Stevenson
-
-drm/vc4: Fixup fkms for API change
-
-Atomic flush and check changed API, so fix up the downstream-only
-FKMS driver.
-
-Signed-off-by: Dave Stevenson
-
-drm/vc4: Make normalize_zpos conditional on using fkms
-
-Eric's view was that there was no point in having zpos
-support on vc4 as all the planes had the same functionality.
-
-Can be later squashed into (and fixes):
-drm/vc4: Add firmware-kms mode
-
-Signed-off-by: Dom Cobley
-
-drm/vc4: FKMS: Change of Broadcast RGB mode needs a mode change
-
-The Broadcast RGB (aka HDMI limited/full range) property is only
-notified to the firmware on mode change, so this needs to be
-signalled when set.
-
-https://github.com/raspberrypi/firmware/issues/1580
-
-Signed-off-by: Dave Stevenson
-
-vc4/drv: Only notify firmware of display done with kms
-
-fkms driver still wants firmware display to be active
-
-Signed-off-by: Dom Cobley
-
-ydrm/vc4: fkms: Fix margin calculations for the right/bottom edges
-
-The calculations clipped the right/bottom edge of the clipped
-range based on the left/top margins.
-
-https://github.com/raspberrypi/linux/issues/4447
-
-Signed-off-by: Dave Stevenson
-
-drm/vc4: fkms: Use new devm_rpi_firmware_get api
-
-drm/kms: Add allow_fb_modifiers
-
-Signed-off-by: Dom Cobley
----
- drivers/gpu/drm/vc4/Makefile | 1 +
- drivers/gpu/drm/vc4/vc4_debugfs.c | 3 +-
- drivers/gpu/drm/vc4/vc4_drv.c | 29 +-
- drivers/gpu/drm/vc4/vc4_drv.h | 7 +
- drivers/gpu/drm/vc4/vc4_firmware_kms.c | 1997 ++++++++++++++++++++++++
- drivers/gpu/drm/vc4/vc4_kms.c | 35 +-
- drivers/gpu/drm/vc4/vc_image_types.h | 175 +++
- 7 files changed, 2233 insertions(+), 14 deletions(-)
- create mode 100644 drivers/gpu/drm/vc4/vc4_firmware_kms.c
- create mode 100644 drivers/gpu/drm/vc4/vc_image_types.h
-
-diff --git a/drivers/gpu/drm/vc4/Makefile b/drivers/gpu/drm/vc4/Makefile
-index d0163e18e9ca..8281a044834f 100644
---- a/drivers/gpu/drm/vc4/Makefile
-+++ b/drivers/gpu/drm/vc4/Makefile
-@@ -9,6 +9,7 @@ vc4-y := \
- vc4_dpi.o \
- vc4_dsi.o \
- vc4_fence.o \
-+ vc4_firmware_kms.o \
- vc4_kms.o \
- vc4_gem.o \
- vc4_hdmi.o \
-diff --git a/drivers/gpu/drm/vc4/vc4_debugfs.c b/drivers/gpu/drm/vc4/vc4_debugfs.c
-index 19cda4f91a82..9d050c2bc24d 100644
---- a/drivers/gpu/drm/vc4/vc4_debugfs.c
-+++ b/drivers/gpu/drm/vc4/vc4_debugfs.c
-@@ -24,7 +24,8 @@ vc4_debugfs_init(struct drm_minor *minor)
- struct vc4_dev *vc4 = to_vc4_dev(minor->dev);
- struct drm_device *drm = &vc4->base;
-
-- drm_WARN_ON(drm, vc4_hvs_debugfs_init(minor));
-+ if (vc4->hvs)
-+ drm_WARN_ON(drm, vc4_hvs_debugfs_init(minor));
-
- if (vc4->v3d) {
- drm_WARN_ON(drm, vc4_bo_debugfs_init(minor));
-diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
-index f8053b591317..e0ecb3b5b548 100644
---- a/drivers/gpu/drm/vc4/vc4_drv.c
-+++ b/drivers/gpu/drm/vc4/vc4_drv.c
-@@ -284,6 +284,18 @@ static const struct of_device_id vc4_dma_range_matches[] = {
- {}
- };
-
-+/*
-+ * we need this helper function for determining presence of fkms
-+ * before it's been bound
-+ */
-+static bool firmware_kms(void)
-+{
-+ return of_device_is_available(of_find_compatible_node(NULL, NULL,
-+ "raspberrypi,rpi-firmware-kms")) ||
-+ of_device_is_available(of_find_compatible_node(NULL, NULL,
-+ "raspberrypi,rpi-firmware-kms-2711"));
-+}
-+
- static int vc4_drm_bind(struct device *dev)
- {
- struct platform_device *pdev = to_platform_device(dev);
-@@ -357,7 +369,7 @@ static int vc4_drm_bind(struct device *dev)
- if (ret)
- return ret;
-
-- if (firmware) {
-+ if (firmware && !firmware_kms()) {
- ret = rpi_firmware_property(firmware,
- RPI_FIRMWARE_NOTIFY_DISPLAY_DONE,
- NULL, 0);
-@@ -375,16 +387,20 @@ static int vc4_drm_bind(struct device *dev)
- if (ret)
- return ret;
-
-- ret = vc4_plane_create_additional_planes(drm);
-- if (ret)
-- goto unbind_all;
-+ if (!vc4->firmware_kms) {
-+ ret = vc4_plane_create_additional_planes(drm);
-+ if (ret)
-+ return ret;
-+ }
-
- ret = vc4_kms_load(drm);
- if (ret < 0)
- goto unbind_all;
-
-- drm_for_each_crtc(crtc, drm)
-- vc4_crtc_disable_at_boot(crtc);
-+ if (!vc4->firmware_kms) {
-+ drm_for_each_crtc(crtc, drm)
-+ vc4_crtc_disable_at_boot(crtc);
-+ }
-
- ret = drm_dev_register(drm, 0);
- if (ret < 0)
-@@ -428,6 +444,7 @@ static struct platform_driver *const component_drivers[] = {
- &vc4_dsi_driver,
- &vc4_txp_driver,
- &vc4_crtc_driver,
-+ &vc4_firmware_kms_driver,
- &vc4_v3d_driver,
- };
-
-diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
-index 418a8242691f..7da22fe3a6cc 100644
---- a/drivers/gpu/drm/vc4/vc4_drv.h
-+++ b/drivers/gpu/drm/vc4/vc4_drv.h
-@@ -82,8 +82,12 @@ struct vc4_dev {
-
- unsigned int irq;
-
-+ bool firmware_kms;
-+ struct rpi_firmware *firmware;
-+
- struct vc4_hvs *hvs;
- struct vc4_v3d *v3d;
-+ struct vc4_fkms *fkms;
-
- struct vc4_hang_state *hang_state;
-
-@@ -905,6 +909,9 @@ extern struct platform_driver vc4_dsi_driver;
- /* vc4_fence.c */
- extern const struct dma_fence_ops vc4_fence_ops;
-
-+/* vc4_firmware_kms.c */
-+extern struct platform_driver vc4_firmware_kms_driver;
-+
- /* vc4_gem.c */
- int vc4_gem_init(struct drm_device *dev);
- int vc4_submit_cl_ioctl(struct drm_device *dev, void *data,
-diff --git a/drivers/gpu/drm/vc4/vc4_firmware_kms.c b/drivers/gpu/drm/vc4/vc4_firmware_kms.c
-new file mode 100644
-index 000000000000..6856de434928
---- /dev/null
-+++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c
-@@ -0,0 +1,1997 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/*
-+ * Copyright (C) 2016 Broadcom
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+
-+/**
-+ * DOC: VC4 firmware KMS module.
-+ *
-+ * As a hack to get us from the current closed source driver world
-+ * toward a totally open stack, implement KMS on top of the Raspberry
-+ * Pi's firmware display stack.
-+ */
-+
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+
-+#include
-+#include
-+#include
-+#include
-+
-+#include
-+
-+#include "vc4_drv.h"
-+#include "vc4_regs.h"
-+#include "vc_image_types.h"
-+
-+int fkms_max_refresh_rate = 85;
-+module_param(fkms_max_refresh_rate, int, 0644);
-+MODULE_PARM_DESC(fkms_max_refresh_rate, "Max supported refresh rate");
-+
-+struct get_display_cfg {
-+ u32 max_pixel_clock[2]; //Max pixel clock for each display
-+};
-+
-+struct vc4_fkms {
-+ struct get_display_cfg cfg;
-+ bool bcm2711;
-+};
-+
-+#define PLANES_PER_CRTC 8
-+
-+struct set_plane {
-+ u8 display;
-+ u8 plane_id;
-+ u8 vc_image_type;
-+ s8 layer;
-+
-+ u16 width;
-+ u16 height;
-+
-+ u16 pitch;
-+ u16 vpitch;
-+
-+ u32 src_x; /* 16p16 */
-+ u32 src_y; /* 16p16 */
-+
-+ u32 src_w; /* 16p16 */
-+ u32 src_h; /* 16p16 */
-+
-+ s16 dst_x;
-+ s16 dst_y;
-+
-+ u16 dst_w;
-+ u16 dst_h;
-+
-+ u8 alpha;
-+ u8 num_planes;
-+ u8 is_vu;
-+ u8 color_encoding;
-+
-+ u32 planes[4]; /* DMA address of each plane */
-+
-+ u32 transform;
-+};
-+
-+/* Values for the transform field */
-+#define TRANSFORM_NO_ROTATE 0
-+#define TRANSFORM_ROTATE_180 BIT(1)
-+#define TRANSFORM_FLIP_HRIZ BIT(16)
-+#define TRANSFORM_FLIP_VERT BIT(17)
-+
-+struct mailbox_set_plane {
-+ struct rpi_firmware_property_tag_header tag;
-+ struct set_plane plane;
-+};
-+
-+struct mailbox_blank_display {
-+ struct rpi_firmware_property_tag_header tag1;
-+ u32 display;
-+ struct rpi_firmware_property_tag_header tag2;
-+ u32 blank;
-+};
-+
-+struct mailbox_display_pwr {
-+ struct rpi_firmware_property_tag_header tag1;
-+ u32 display;
-+ u32 state;
-+};
-+
-+struct mailbox_get_edid {
-+ struct rpi_firmware_property_tag_header tag1;
-+ u32 block;
-+ u32 display_number;
-+ u8 edid[128];
-+};
-+
-+struct set_timings {
-+ u8 display;
-+ u8 padding;
-+ u16 video_id_code;
-+
-+ u32 clock; /* in kHz */
-+
-+ u16 hdisplay;
-+ u16 hsync_start;
-+
-+ u16 hsync_end;
-+ u16 htotal;
-+
-+ u16 hskew;
-+ u16 vdisplay;
-+
-+ u16 vsync_start;
-+ u16 vsync_end;
-+
-+ u16 vtotal;
-+ u16 vscan;
-+
-+ u16 vrefresh;
-+ u16 padding2;
-+
-+ u32 flags;
-+#define TIMINGS_FLAGS_H_SYNC_POS BIT(0)
-+#define TIMINGS_FLAGS_H_SYNC_NEG 0
-+#define TIMINGS_FLAGS_V_SYNC_POS BIT(1)
-+#define TIMINGS_FLAGS_V_SYNC_NEG 0
-+#define TIMINGS_FLAGS_INTERLACE BIT(2)
-+
-+#define TIMINGS_FLAGS_ASPECT_MASK GENMASK(7, 4)
-+#define TIMINGS_FLAGS_ASPECT_NONE (0 << 4)
-+#define TIMINGS_FLAGS_ASPECT_4_3 (1 << 4)
-+#define TIMINGS_FLAGS_ASPECT_16_9 (2 << 4)
-+#define TIMINGS_FLAGS_ASPECT_64_27 (3 << 4)
-+#define TIMINGS_FLAGS_ASPECT_256_135 (4 << 4)
-+
-+/* Limited range RGB flag. Not set corresponds to full range. */
-+#define TIMINGS_FLAGS_RGB_LIMITED BIT(8)
-+/* DVI monitor, therefore disable infoframes. Not set corresponds to HDMI. */
-+#define TIMINGS_FLAGS_DVI BIT(9)
-+/* Double clock */
-+#define TIMINGS_FLAGS_DBL_CLK BIT(10)
-+};
-+
-+struct mailbox_set_mode {
-+ struct rpi_firmware_property_tag_header tag1;
-+ struct set_timings timings;
-+};
-+
-+static const struct vc_image_format {
-+ u32 drm; /* DRM_FORMAT_* */
-+ u32 vc_image; /* VC_IMAGE_* */
-+ u32 is_vu;
-+} vc_image_formats[] = {
-+ {
-+ .drm = DRM_FORMAT_XRGB8888,
-+ .vc_image = VC_IMAGE_XRGB8888,
-+ },
-+ {
-+ .drm = DRM_FORMAT_ARGB8888,
-+ .vc_image = VC_IMAGE_ARGB8888,
-+ },
-+/*
-+ * FIXME: Need to resolve which DRM format goes to which vc_image format
-+ * for the remaining RGBA and RGBX formats.
-+ * {
-+ * .drm = DRM_FORMAT_ABGR8888,
-+ * .vc_image = VC_IMAGE_RGBA8888,
-+ * },
-+ * {
-+ * .drm = DRM_FORMAT_XBGR8888,
-+ * .vc_image = VC_IMAGE_RGBA8888,
-+ * },
-+ */
-+ {
-+ .drm = DRM_FORMAT_RGB565,
-+ .vc_image = VC_IMAGE_RGB565,
-+ },
-+ {
-+ .drm = DRM_FORMAT_RGB888,
-+ .vc_image = VC_IMAGE_BGR888,
-+ },
-+ {
-+ .drm = DRM_FORMAT_BGR888,
-+ .vc_image = VC_IMAGE_RGB888,
-+ },
-+ {
-+ .drm = DRM_FORMAT_YUV422,
-+ .vc_image = VC_IMAGE_YUV422PLANAR,
-+ },
-+ {
-+ .drm = DRM_FORMAT_YUV420,
-+ .vc_image = VC_IMAGE_YUV420,
-+ },
-+ {
-+ .drm = DRM_FORMAT_YVU420,
-+ .vc_image = VC_IMAGE_YUV420,
-+ .is_vu = 1,
-+ },
-+ {
-+ .drm = DRM_FORMAT_NV12,
-+ .vc_image = VC_IMAGE_YUV420SP,
-+ },
-+ {
-+ .drm = DRM_FORMAT_NV21,
-+ .vc_image = VC_IMAGE_YUV420SP,
-+ .is_vu = 1,
-+ },
-+ {
-+ .drm = DRM_FORMAT_P030,
-+ .vc_image = VC_IMAGE_YUV10COL,
-+ },
-+};
-+
-+static const struct vc_image_format *vc4_get_vc_image_fmt(u32 drm_format)
-+{
-+ unsigned int i;
-+
-+ for (i = 0; i < ARRAY_SIZE(vc_image_formats); i++) {
-+ if (vc_image_formats[i].drm == drm_format)
-+ return &vc_image_formats[i];
-+ }
-+
-+ return NULL;
-+}
-+
-+/* The firmware delivers a vblank interrupt to us through the SMI
-+ * hardware, which has only this one register.
-+ */
-+#define SMICS 0x0
-+#define SMIDSW0 0x14
-+#define SMIDSW1 0x1C
-+#define SMICS_INTERRUPTS (BIT(9) | BIT(10) | BIT(11))
-+
-+/* Flag to denote that the firmware is giving multiple display callbacks */
-+#define SMI_NEW 0xabcd0000
-+
-+#define vc4_crtc vc4_kms_crtc
-+#define to_vc4_crtc to_vc4_kms_crtc
-+struct vc4_crtc {
-+ struct drm_crtc base;
-+ struct drm_encoder *encoder;
-+ struct drm_connector *connector;
-+ void __iomem *regs;
-+
-+ struct drm_pending_vblank_event *event;
-+ bool vblank_enabled;
-+ u32 display_number;
-+ u32 display_type;
-+};
-+
-+static inline struct vc4_crtc *to_vc4_crtc(struct drm_crtc *crtc)
-+{
-+ return container_of(crtc, struct vc4_crtc, base);
-+}
-+
-+struct vc4_fkms_encoder {
-+ struct drm_encoder base;
-+ bool hdmi_monitor;
-+ bool rgb_range_selectable;
-+ int display_num;
-+};
-+
-+static inline struct vc4_fkms_encoder *
-+to_vc4_fkms_encoder(struct drm_encoder *encoder)
-+{
-+ return container_of(encoder, struct vc4_fkms_encoder, base);
-+}
-+
-+/* "Broadcast RGB" property.
-+ * Allows overriding of HDMI full or limited range RGB
-+ */
-+#define VC4_BROADCAST_RGB_AUTO 0
-+#define VC4_BROADCAST_RGB_FULL 1
-+#define VC4_BROADCAST_RGB_LIMITED 2
-+
-+/* VC4 FKMS connector KMS struct */
-+struct vc4_fkms_connector {
-+ struct drm_connector base;
-+
-+ /* Since the connector is attached to just the one encoder,
-+ * this is the reference to it so we can do the best_encoder()
-+ * hook.
-+ */
-+ struct drm_encoder *encoder;
-+ struct vc4_dev *vc4_dev;
-+ u32 display_number;
-+ u32 display_type;
-+
-+ struct drm_property *broadcast_rgb_property;
-+};
-+
-+static inline struct vc4_fkms_connector *
-+to_vc4_fkms_connector(struct drm_connector *connector)
-+{
-+ return container_of(connector, struct vc4_fkms_connector, base);
-+}
-+
-+/* VC4 FKMS connector state */
-+struct vc4_fkms_connector_state {
-+ struct drm_connector_state base;
-+
-+ int broadcast_rgb;
-+};
-+
-+#define to_vc4_fkms_connector_state(x) \
-+ container_of(x, struct vc4_fkms_connector_state, base)
-+
-+static u32 vc4_get_display_type(u32 display_number)
-+{
-+ const u32 display_types[] = {
-+ /* The firmware display (DispmanX) IDs map to specific types in
-+ * a fixed manner.
-+ */
-+ DRM_MODE_ENCODER_DSI, /* MAIN_LCD - DSI or DPI */
-+ DRM_MODE_ENCODER_DSI, /* AUX_LCD */
-+ DRM_MODE_ENCODER_TMDS, /* HDMI0 */
-+ DRM_MODE_ENCODER_TVDAC, /* VEC */
-+ DRM_MODE_ENCODER_NONE, /* FORCE_LCD */
-+ DRM_MODE_ENCODER_NONE, /* FORCE_TV */
-+ DRM_MODE_ENCODER_NONE, /* FORCE_OTHER */
-+ DRM_MODE_ENCODER_TMDS, /* HDMI1 */
-+ DRM_MODE_ENCODER_NONE, /* FORCE_TV2 */
-+ };
-+ return display_number > ARRAY_SIZE(display_types) - 1 ?
-+ DRM_MODE_ENCODER_NONE : display_types[display_number];
-+}
-+
-+/* Firmware's structure for making an FB mbox call. */
-+struct fbinfo_s {
-+ u32 xres, yres, xres_virtual, yres_virtual;
-+ u32 pitch, bpp;
-+ u32 xoffset, yoffset;
-+ u32 base;
-+ u32 screen_size;
-+ u16 cmap[256];
-+};
-+
-+struct vc4_fkms_plane {
-+ struct drm_plane base;
-+ struct fbinfo_s *fbinfo;
-+ dma_addr_t fbinfo_bus_addr;
-+ u32 pitch;
-+ struct mailbox_set_plane mb;
-+};
-+
-+static inline struct vc4_fkms_plane *to_vc4_fkms_plane(struct drm_plane *plane)
-+{
-+ return (struct vc4_fkms_plane *)plane;
-+}
-+
-+static int vc4_plane_set_blank(struct drm_plane *plane, bool blank)
-+{
-+ struct vc4_dev *vc4 = to_vc4_dev(plane->dev);
-+ struct vc4_fkms_plane *vc4_plane = to_vc4_fkms_plane(plane);
-+ struct mailbox_set_plane blank_mb = {
-+ .tag = { RPI_FIRMWARE_SET_PLANE, sizeof(struct set_plane), 0 },
-+ .plane = {
-+ .display = vc4_plane->mb.plane.display,
-+ .plane_id = vc4_plane->mb.plane.plane_id,
-+ }
-+ };
-+ static const char * const plane_types[] = {
-+ "overlay",
-+ "primary",
-+ "cursor"
-+ };
-+ int ret;
-+
-+ DRM_DEBUG_ATOMIC("[PLANE:%d:%s] %s plane %s",
-+ plane->base.id, plane->name, plane_types[plane->type],
-+ blank ? "blank" : "unblank");
-+
-+ if (blank)
-+ ret = rpi_firmware_property_list(vc4->firmware, &blank_mb,
-+ sizeof(blank_mb));
-+ else
-+ ret = rpi_firmware_property_list(vc4->firmware, &vc4_plane->mb,
-+ sizeof(vc4_plane->mb));
-+
-+ WARN_ONCE(ret, "%s: firmware call failed. Please update your firmware",
-+ __func__);
-+ return ret;
-+}
-+
-+static void vc4_fkms_crtc_get_margins(struct drm_crtc_state *state,
-+ unsigned int *left, unsigned int *right,
-+ unsigned int *top, unsigned int *bottom)
-+{
-+ struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(state);
-+ struct drm_connector_state *conn_state;
-+ struct drm_connector *conn;
-+ int i;
-+
-+ *left = vc4_state->margins.left;
-+ *right = vc4_state->margins.right;
-+ *top = vc4_state->margins.top;
-+ *bottom = vc4_state->margins.bottom;
-+
-+ /* We have to interate over all new connector states because
-+ * vc4_fkms_crtc_get_margins() might be called before
-+ * vc4_fkms_crtc_atomic_check() which means margins info in
-+ * vc4_crtc_state might be outdated.
-+ */
-+ for_each_new_connector_in_state(state->state, conn, conn_state, i) {
-+ if (conn_state->crtc != state->crtc)
-+ continue;
-+
-+ *left = conn_state->tv.margins.left;
-+ *right = conn_state->tv.margins.right;
-+ *top = conn_state->tv.margins.top;
-+ *bottom = conn_state->tv.margins.bottom;
-+ break;
-+ }
-+}
-+
-+static int vc4_fkms_margins_adj(struct drm_plane_state *pstate,
-+ struct set_plane *plane)
-+{
-+ unsigned int left, right, top, bottom;
-+ int adjhdisplay, adjvdisplay;
-+ struct drm_crtc_state *crtc_state;
-+
-+ crtc_state = drm_atomic_get_new_crtc_state(pstate->state,
-+ pstate->crtc);
-+
-+ vc4_fkms_crtc_get_margins(crtc_state, &left, &right, &top, &bottom);
-+
-+ if (!left && !right && !top && !bottom)
-+ return 0;
-+
-+ if (left + right >= crtc_state->mode.hdisplay ||
-+ top + bottom >= crtc_state->mode.vdisplay)
-+ return -EINVAL;
-+
-+ adjhdisplay = crtc_state->mode.hdisplay - (left + right);
-+ plane->dst_x = DIV_ROUND_CLOSEST(plane->dst_x * adjhdisplay,
-+ (int)crtc_state->mode.hdisplay);
-+ plane->dst_x += left;
-+ if (plane->dst_x > (int)(crtc_state->mode.hdisplay - right))
-+ plane->dst_x = crtc_state->mode.hdisplay - right;
-+
-+ adjvdisplay = crtc_state->mode.vdisplay - (top + bottom);
-+ plane->dst_y = DIV_ROUND_CLOSEST(plane->dst_y * adjvdisplay,
-+ (int)crtc_state->mode.vdisplay);
-+ plane->dst_y += top;
-+ if (plane->dst_y > (int)(crtc_state->mode.vdisplay - bottom))
-+ plane->dst_y = crtc_state->mode.vdisplay - bottom;
-+
-+ plane->dst_w = DIV_ROUND_CLOSEST(plane->dst_w * adjhdisplay,
-+ crtc_state->mode.hdisplay);
-+ plane->dst_h = DIV_ROUND_CLOSEST(plane->dst_h * adjvdisplay,
-+ crtc_state->mode.vdisplay);
-+
-+ if (!plane->dst_w || !plane->dst_h)
-+ return -EINVAL;
-+
-+ return 0;
-+}
-+
-+static void vc4_plane_atomic_update(struct drm_plane *plane,
-+ struct drm_atomic_state *old_state)
-+{
-+ struct drm_plane_state *state = plane->state;
-+
-+ /*
-+ * Do NOT set now, as we haven't checked if the crtc is active or not.
-+ * Set from vc4_plane_set_blank instead.
-+ *
-+ * If the CRTC is on (or going to be on) and we're enabled,
-+ * then unblank. Otherwise, stay blank until CRTC enable.
-+ */
-+ if (state->crtc->state->active)
-+ vc4_plane_set_blank(plane, false);
-+}
-+
-+static void vc4_plane_atomic_disable(struct drm_plane *plane,
-+ struct drm_atomic_state *old_state)
-+{
-+ struct drm_plane_state *state = plane->state;
-+ struct vc4_fkms_plane *vc4_plane = to_vc4_fkms_plane(plane);
-+
-+ DRM_DEBUG_ATOMIC("[PLANE:%d:%s] plane disable %dx%d@%d +%d,%d\n",
-+ plane->base.id, plane->name,
-+ state->crtc_w,
-+ state->crtc_h,
-+ vc4_plane->mb.plane.vc_image_type,
-+ state->crtc_x,
-+ state->crtc_y);
-+ vc4_plane_set_blank(plane, true);
-+}
-+
-+static bool plane_enabled(struct drm_plane_state *state)
-+{
-+ return state->fb && state->crtc;
-+}
-+
-+static int vc4_plane_to_mb(struct drm_plane *plane,
-+ struct mailbox_set_plane *mb,
-+ struct drm_plane_state *state)
-+{
-+ struct drm_framebuffer *fb = state->fb;
-+ struct drm_gem_dma_object *bo = drm_fb_dma_get_gem_obj(fb, 0);
-+ const struct drm_format_info *drm_fmt = fb->format;
-+ const struct vc_image_format *vc_fmt =
-+ vc4_get_vc_image_fmt(drm_fmt->format);
-+ int num_planes = fb->format->num_planes;
-+ unsigned int rotation;
-+
-+ mb->plane.vc_image_type = vc_fmt->vc_image;
-+ mb->plane.width = fb->width;
-+ mb->plane.height = fb->height;
-+ mb->plane.pitch = fb->pitches[0];
-+ mb->plane.src_w = state->src_w;
-+ mb->plane.src_h = state->src_h;
-+ mb->plane.src_x = state->src_x;
-+ mb->plane.src_y = state->src_y;
-+ mb->plane.dst_w = state->crtc_w;
-+ mb->plane.dst_h = state->crtc_h;
-+ mb->plane.dst_x = state->crtc_x;
-+ mb->plane.dst_y = state->crtc_y;
-+ mb->plane.alpha = state->alpha >> 8;
-+ mb->plane.layer = state->normalized_zpos ?
-+ state->normalized_zpos : -127;
-+ mb->plane.num_planes = num_planes;
-+ mb->plane.is_vu = vc_fmt->is_vu;
-+ mb->plane.planes[0] = bo->dma_addr + fb->offsets[0];
-+
-+ rotation = drm_rotation_simplify(state->rotation,
-+ DRM_MODE_ROTATE_0 |
-+ DRM_MODE_REFLECT_X |
-+ DRM_MODE_REFLECT_Y);
-+
-+ mb->plane.transform = TRANSFORM_NO_ROTATE;
-+ if (rotation & DRM_MODE_REFLECT_X)
-+ mb->plane.transform |= TRANSFORM_FLIP_HRIZ;
-+ if (rotation & DRM_MODE_REFLECT_Y)
-+ mb->plane.transform |= TRANSFORM_FLIP_VERT;
-+
-+ vc4_fkms_margins_adj(state, &mb->plane);
-+
-+ if (num_planes > 1) {
-+ /* Assume this must be YUV */
-+ /* Makes assumptions on the stride for the chroma planes as we
-+ * can't easily plumb in non-standard pitches.
-+ */
-+ mb->plane.planes[1] = bo->dma_addr + fb->offsets[1];
-+ if (num_planes > 2)
-+ mb->plane.planes[2] = bo->dma_addr + fb->offsets[2];
-+ else
-+ mb->plane.planes[2] = 0;
-+
-+ /* Special case the YUV420 with U and V as line interleaved
-+ * planes as we have special handling for that case.
-+ */
-+ if (num_planes == 3 &&
-+ (fb->offsets[2] - fb->offsets[1]) == fb->pitches[1])
-+ mb->plane.vc_image_type = VC_IMAGE_YUV420_S;
-+
-+ switch (state->color_encoding) {
-+ default:
-+ case DRM_COLOR_YCBCR_BT601:
-+ if (state->color_range == DRM_COLOR_YCBCR_LIMITED_RANGE)
-+ mb->plane.color_encoding =
-+ VC_IMAGE_YUVINFO_CSC_ITUR_BT601;
-+ else
-+ mb->plane.color_encoding =
-+ VC_IMAGE_YUVINFO_CSC_JPEG_JFIF;
-+ break;
-+ case DRM_COLOR_YCBCR_BT709:
-+ /* Currently no support for a full range BT709 */
-+ mb->plane.color_encoding =
-+ VC_IMAGE_YUVINFO_CSC_ITUR_BT709;
-+ break;
-+ case DRM_COLOR_YCBCR_BT2020:
-+ /* Currently no support for a full range BT2020 */
-+ mb->plane.color_encoding =
-+ VC_IMAGE_YUVINFO_CSC_REC_2020;
-+ break;
-+ }
-+ } else {
-+ mb->plane.planes[1] = 0;
-+ mb->plane.planes[2] = 0;
-+ }
-+ mb->plane.planes[3] = 0;
-+
-+ switch (fourcc_mod_broadcom_mod(fb->modifier)) {
-+ case DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED:
-+ switch (mb->plane.vc_image_type) {
-+ case VC_IMAGE_XRGB8888:
-+ mb->plane.vc_image_type = VC_IMAGE_TF_RGBX32;
-+ break;
-+ case VC_IMAGE_ARGB8888:
-+ mb->plane.vc_image_type = VC_IMAGE_TF_RGBA32;
-+ break;
-+ case VC_IMAGE_RGB565:
-+ mb->plane.vc_image_type = VC_IMAGE_TF_RGB565;
-+ break;
-+ }
-+ break;
-+ case DRM_FORMAT_MOD_BROADCOM_SAND128:
-+ switch (mb->plane.vc_image_type) {
-+ case VC_IMAGE_YUV420SP:
-+ mb->plane.vc_image_type = VC_IMAGE_YUV_UV;
-+ break;
-+ /* VC_IMAGE_YUV10COL could be included in here, but it is only
-+ * valid as a SAND128 format, so the table at the top will have
-+ * already set the correct format.
-+ */
-+ }
-+ /* Note that the column pitch is passed across in lines, not
-+ * bytes.
-+ */
-+ mb->plane.pitch = fourcc_mod_broadcom_param(fb->modifier);
-+ break;
-+ }
-+
-+ DRM_DEBUG_ATOMIC("[PLANE:%d:%s] plane update %dx%d@%d +dst(%d,%d, %d,%d) +src(%d,%d, %d,%d) 0x%08x/%08x/%08x/%d, alpha %u zpos %u\n",
-+ plane->base.id, plane->name,
-+ mb->plane.width,
-+ mb->plane.height,
-+ mb->plane.vc_image_type,
-+ state->crtc_x,
-+ state->crtc_y,
-+ state->crtc_w,
-+ state->crtc_h,
-+ mb->plane.src_x,
-+ mb->plane.src_y,
-+ mb->plane.src_w,
-+ mb->plane.src_h,
-+ mb->plane.planes[0],
-+ mb->plane.planes[1],
-+ mb->plane.planes[2],
-+ fb->pitches[0],
-+ state->alpha,
-+ state->normalized_zpos);
-+
-+ return 0;
-+}
-+
-+static int vc4_plane_atomic_check(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 vc4_fkms_plane *vc4_plane = to_vc4_fkms_plane(plane);
-+
-+ if (!plane_enabled(new_plane_state))
-+ return 0;
-+
-+ return vc4_plane_to_mb(plane, &vc4_plane->mb, new_plane_state);
-+}
-+
-+/* Called during init to allocate the plane's atomic state. */
-+static void vc4_plane_reset(struct drm_plane *plane)
-+{
-+ struct vc4_plane_state *vc4_state;
-+
-+ WARN_ON(plane->state);
-+
-+ vc4_state = kzalloc(sizeof(*vc4_state), GFP_KERNEL);
-+ if (!vc4_state)
-+ return;
-+
-+ __drm_atomic_helper_plane_reset(plane, &vc4_state->base);
-+}
-+
-+static void vc4_plane_destroy(struct drm_plane *plane)
-+{
-+ drm_plane_cleanup(plane);
-+}
-+
-+static bool vc4_fkms_format_mod_supported(struct drm_plane *plane,
-+ uint32_t format,
-+ uint64_t modifier)
-+{
-+ /* Support T_TILING for RGB formats only. */
-+ switch (format) {
-+ case DRM_FORMAT_XRGB8888:
-+ case DRM_FORMAT_ARGB8888:
-+ case DRM_FORMAT_RGB565:
-+ switch (modifier) {
-+ case DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED:
-+ case DRM_FORMAT_MOD_LINEAR:
-+ return true;
-+ default:
-+ return false;
-+ }
-+ case DRM_FORMAT_NV12:
-+ switch (fourcc_mod_broadcom_mod(modifier)) {
-+ case DRM_FORMAT_MOD_LINEAR:
-+ case DRM_FORMAT_MOD_BROADCOM_SAND128:
-+ return true;
-+ default:
-+ return false;
-+ }
-+ case DRM_FORMAT_P030:
-+ switch (fourcc_mod_broadcom_mod(modifier)) {
-+ case DRM_FORMAT_MOD_BROADCOM_SAND128:
-+ return true;
-+ default:
-+ return false;
-+ }
-+ case DRM_FORMAT_NV21:
-+ case DRM_FORMAT_RGB888:
-+ case DRM_FORMAT_BGR888:
-+ case DRM_FORMAT_YUV422:
-+ case DRM_FORMAT_YUV420:
-+ case DRM_FORMAT_YVU420:
-+ default:
-+ return (modifier == DRM_FORMAT_MOD_LINEAR);
-+ }
-+}
-+
-+static struct drm_plane_state *vc4_plane_duplicate_state(struct drm_plane *plane)
-+{
-+ struct vc4_plane_state *vc4_state;
-+
-+ if (WARN_ON(!plane->state))
-+ return NULL;
-+
-+ vc4_state = kzalloc(sizeof(*vc4_state), GFP_KERNEL);
-+ if (!vc4_state)
-+ return NULL;
-+
-+ __drm_atomic_helper_plane_duplicate_state(plane, &vc4_state->base);
-+
-+ return &vc4_state->base;
-+}
-+
-+static const struct drm_plane_funcs vc4_plane_funcs = {
-+ .update_plane = drm_atomic_helper_update_plane,
-+ .disable_plane = drm_atomic_helper_disable_plane,
-+ .destroy = vc4_plane_destroy,
-+ .set_property = NULL,
-+ .reset = vc4_plane_reset,
-+ .atomic_duplicate_state = vc4_plane_duplicate_state,
-+ .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
-+ .format_mod_supported = vc4_fkms_format_mod_supported,
-+};
-+
-+static const struct drm_plane_helper_funcs vc4_plane_helper_funcs = {
-+ .prepare_fb = drm_gem_plane_helper_prepare_fb,
-+ .cleanup_fb = NULL,
-+ .atomic_check = vc4_plane_atomic_check,
-+ .atomic_update = vc4_plane_atomic_update,
-+ .atomic_disable = vc4_plane_atomic_disable,
-+};
-+
-+static struct drm_plane *vc4_fkms_plane_init(struct drm_device *dev,
-+ enum drm_plane_type type,
-+ u8 display_num,
-+ u8 plane_id)
-+{
-+ struct drm_plane *plane = NULL;
-+ struct vc4_fkms_plane *vc4_plane;
-+ u32 formats[ARRAY_SIZE(vc_image_formats)];
-+ unsigned int default_zpos = 0;
-+ u32 num_formats = 0;
-+ int ret = 0;
-+ static const uint64_t modifiers[] = {
-+ DRM_FORMAT_MOD_LINEAR,
-+ /* VC4_T_TILED should come after linear, because we
-+ * would prefer to scan out linear (less bus traffic).
-+ */
-+ DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED,
-+ DRM_FORMAT_MOD_BROADCOM_SAND128,
-+ DRM_FORMAT_MOD_INVALID,
-+ };
-+ int i;
-+
-+ vc4_plane = devm_kzalloc(dev->dev, sizeof(*vc4_plane),
-+ GFP_KERNEL);
-+ if (!vc4_plane) {
-+ ret = -ENOMEM;
-+ goto fail;
-+ }
-+
-+ for (i = 0; i < ARRAY_SIZE(vc_image_formats); i++)
-+ formats[num_formats++] = vc_image_formats[i].drm;
-+
-+ plane = &vc4_plane->base;
-+ ret = drm_universal_plane_init(dev, plane, 0,
-+ &vc4_plane_funcs,
-+ formats, num_formats, modifiers,
-+ type, NULL);
-+
-+ /* FIXME: Do we need to be checking return values from all these calls?
-+ */
-+ drm_plane_helper_add(plane, &vc4_plane_helper_funcs);
-+
-+ drm_plane_create_alpha_property(plane);
-+ drm_plane_create_rotation_property(plane, DRM_MODE_ROTATE_0,
-+ DRM_MODE_ROTATE_0 |
-+ DRM_MODE_ROTATE_180 |
-+ DRM_MODE_REFLECT_X |
-+ DRM_MODE_REFLECT_Y);
-+ drm_plane_create_color_properties(plane,
-+ BIT(DRM_COLOR_YCBCR_BT601) |
-+ BIT(DRM_COLOR_YCBCR_BT709) |
-+ BIT(DRM_COLOR_YCBCR_BT2020),
-+ BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
-+ BIT(DRM_COLOR_YCBCR_FULL_RANGE),
-+ DRM_COLOR_YCBCR_BT709,
-+ DRM_COLOR_YCBCR_LIMITED_RANGE);
-+
-+ /*
-+ * Default frame buffer setup is with FB on -127, and raspistill etc
-+ * tend to drop overlays on layer 2. Cursor plane was on layer +127.
-+ *
-+ * For F-KMS the mailbox call allows for a s8.
-+ * Remap zpos 0 to -127 for the background layer, but leave all the
-+ * other layers as requested by KMS.
-+ */
-+ switch (type) {
-+ default:
-+ case DRM_PLANE_TYPE_PRIMARY:
-+ default_zpos = 0;
-+ break;
-+ case DRM_PLANE_TYPE_OVERLAY:
-+ default_zpos = 1;
-+ break;
-+ case DRM_PLANE_TYPE_CURSOR:
-+ default_zpos = 2;
-+ break;
-+ }
-+ drm_plane_create_zpos_property(plane, default_zpos, 0, 127);
-+
-+ /* Prepare the static elements of the mailbox structure */
-+ vc4_plane->mb.tag.tag = RPI_FIRMWARE_SET_PLANE;
-+ vc4_plane->mb.tag.buf_size = sizeof(struct set_plane);
-+ vc4_plane->mb.tag.req_resp_size = 0;
-+ vc4_plane->mb.plane.display = display_num;
-+ vc4_plane->mb.plane.plane_id = plane_id;
-+ vc4_plane->mb.plane.layer = default_zpos ? default_zpos : -127;
-+
-+ return plane;
-+fail:
-+ if (plane)
-+ vc4_plane_destroy(plane);
-+
-+ return ERR_PTR(ret);
-+}
-+
-+static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc)
-+{
-+ struct drm_device *dev = crtc->dev;
-+ struct vc4_dev *vc4 = to_vc4_dev(dev);
-+ struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
-+ struct drm_display_mode *mode = &crtc->state->adjusted_mode;
-+ struct vc4_fkms_encoder *vc4_encoder =
-+ to_vc4_fkms_encoder(vc4_crtc->encoder);
-+ struct mailbox_set_mode mb = {
-+ .tag1 = { RPI_FIRMWARE_SET_TIMING,
-+ sizeof(struct set_timings), 0},
-+ };
-+ union hdmi_infoframe frame;
-+ int ret;
-+
-+ ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, vc4_crtc->connector, mode);
-+ if (ret < 0) {
-+ DRM_ERROR("couldn't fill AVI infoframe\n");
-+ return;
-+ }
-+
-+ DRM_DEBUG_KMS("Setting mode for display num %u mode name %s, clk %d, h(disp %d, start %d, end %d, total %d, skew %d) v(disp %d, start %d, end %d, total %d, scan %d), vrefresh %d, par %u, flags 0x%04x\n",
-+ vc4_crtc->display_number, mode->name, mode->clock,
-+ mode->hdisplay, mode->hsync_start, mode->hsync_end,
-+ mode->htotal, mode->hskew, mode->vdisplay,
-+ mode->vsync_start, mode->vsync_end, mode->vtotal,
-+ mode->vscan, drm_mode_vrefresh(mode),
-+ mode->picture_aspect_ratio, mode->flags);
-+ mb.timings.display = vc4_crtc->display_number;
-+
-+ mb.timings.clock = mode->clock;
-+ mb.timings.hdisplay = mode->hdisplay;
-+ mb.timings.hsync_start = mode->hsync_start;
-+ mb.timings.hsync_end = mode->hsync_end;
-+ mb.timings.htotal = mode->htotal;
-+ mb.timings.hskew = mode->hskew;
-+ mb.timings.vdisplay = mode->vdisplay;
-+ mb.timings.vsync_start = mode->vsync_start;
-+ mb.timings.vsync_end = mode->vsync_end;
-+ mb.timings.vtotal = mode->vtotal;
-+ mb.timings.vscan = mode->vscan;
-+ mb.timings.vrefresh = drm_mode_vrefresh(mode);
-+ mb.timings.flags = 0;
-+ if (mode->flags & DRM_MODE_FLAG_PHSYNC)
-+ mb.timings.flags |= TIMINGS_FLAGS_H_SYNC_POS;
-+ if (mode->flags & DRM_MODE_FLAG_PVSYNC)
-+ mb.timings.flags |= TIMINGS_FLAGS_V_SYNC_POS;
-+
-+ switch (frame.avi.picture_aspect) {
-+ default:
-+ case HDMI_PICTURE_ASPECT_NONE:
-+ mb.timings.flags |= TIMINGS_FLAGS_ASPECT_NONE;
-+ break;
-+ case HDMI_PICTURE_ASPECT_4_3:
-+ mb.timings.flags |= TIMINGS_FLAGS_ASPECT_4_3;
-+ break;
-+ case HDMI_PICTURE_ASPECT_16_9:
-+ mb.timings.flags |= TIMINGS_FLAGS_ASPECT_16_9;
-+ break;
-+ case HDMI_PICTURE_ASPECT_64_27:
-+ mb.timings.flags |= TIMINGS_FLAGS_ASPECT_64_27;
-+ break;
-+ case HDMI_PICTURE_ASPECT_256_135:
-+ mb.timings.flags |= TIMINGS_FLAGS_ASPECT_256_135;
-+ break;
-+ }
-+
-+ if (mode->flags & DRM_MODE_FLAG_INTERLACE)
-+ mb.timings.flags |= TIMINGS_FLAGS_INTERLACE;
-+ if (mode->flags & DRM_MODE_FLAG_DBLCLK)
-+ mb.timings.flags |= TIMINGS_FLAGS_DBL_CLK;
-+
-+ mb.timings.video_id_code = frame.avi.video_code;
-+
-+ if (!vc4_encoder->hdmi_monitor) {
-+ mb.timings.flags |= TIMINGS_FLAGS_DVI;
-+ } else {
-+ struct vc4_fkms_connector_state *conn_state =
-+ to_vc4_fkms_connector_state(vc4_crtc->connector->state);
-+
-+ if (conn_state->broadcast_rgb == VC4_BROADCAST_RGB_AUTO) {
-+ /* See CEA-861-E - 5.1 Default Encoding Parameters */
-+ if (drm_default_rgb_quant_range(mode) ==
-+ HDMI_QUANTIZATION_RANGE_LIMITED)
-+ mb.timings.flags |= TIMINGS_FLAGS_RGB_LIMITED;
-+ } else {
-+ if (conn_state->broadcast_rgb ==
-+ VC4_BROADCAST_RGB_LIMITED)
-+ mb.timings.flags |= TIMINGS_FLAGS_RGB_LIMITED;
-+
-+ /* If not using the default range, then do not provide
-+ * a VIC as the HDMI spec requires that we do not
-+ * signal the opposite of the defined range in the AVI
-+ * infoframe.
-+ */
-+ if (!!(mb.timings.flags & TIMINGS_FLAGS_RGB_LIMITED) !=
-+ (drm_default_rgb_quant_range(mode) ==
-+ HDMI_QUANTIZATION_RANGE_LIMITED))
-+ mb.timings.video_id_code = 0;
-+ }
-+ }
-+
-+ /*
-+ * FIXME: To implement
-+ * switch(mode->flag & DRM_MODE_FLAG_3D_MASK) {
-+ * case DRM_MODE_FLAG_3D_NONE:
-+ * case DRM_MODE_FLAG_3D_FRAME_PACKING:
-+ * case DRM_MODE_FLAG_3D_FIELD_ALTERNATIVE:
-+ * case DRM_MODE_FLAG_3D_LINE_ALTERNATIVE:
-+ * case DRM_MODE_FLAG_3D_SIDE_BY_SIDE_FULL:
-+ * case DRM_MODE_FLAG_3D_L_DEPTH:
-+ * case DRM_MODE_FLAG_3D_L_DEPTH_GFX_GFX_DEPTH:
-+ * case DRM_MODE_FLAG_3D_TOP_AND_BOTTOM:
-+ * case DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF:
-+ * }
-+ */
-+
-+ ret = rpi_firmware_property_list(vc4->firmware, &mb, sizeof(mb));
-+}
-+
-+static void vc4_crtc_disable(struct drm_crtc *crtc,
-+ struct drm_atomic_state *state)
-+{
-+ struct drm_device *dev = crtc->dev;
-+ struct drm_plane *plane;
-+
-+ DRM_DEBUG_KMS("[CRTC:%d] vblanks off.\n",
-+ crtc->base.id);
-+ drm_crtc_vblank_off(crtc);
-+
-+ /* Always turn the planes off on CRTC disable. In DRM, planes
-+ * are enabled/disabled through the update/disable hooks
-+ * above, and the CRTC enable/disable independently controls
-+ * whether anything scans out at all, but the firmware doesn't
-+ * give us a CRTC-level control for that.
-+ */
-+
-+ drm_atomic_crtc_for_each_plane(plane, crtc)
-+ vc4_plane_atomic_disable(plane, state);
-+
-+ /*
-+ * Make sure we issue a vblank event after disabling the CRTC if
-+ * someone was waiting it.
-+ */
-+ if (crtc->state->event) {
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&dev->event_lock, flags);
-+ drm_crtc_send_vblank_event(crtc, crtc->state->event);
-+ crtc->state->event = NULL;
-+ spin_unlock_irqrestore(&dev->event_lock, flags);
-+ }
-+}
-+
-+static void vc4_crtc_consume_event(struct drm_crtc *crtc)
-+{
-+ struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
-+ struct drm_device *dev = crtc->dev;
-+ unsigned long flags;
-+
-+ if (!crtc->state->event)
-+ return;
-+
-+ crtc->state->event->pipe = drm_crtc_index(crtc);
-+
-+ WARN_ON(drm_crtc_vblank_get(crtc) != 0);
-+
-+ spin_lock_irqsave(&dev->event_lock, flags);
-+ vc4_crtc->event = crtc->state->event;
-+ crtc->state->event = NULL;
-+ spin_unlock_irqrestore(&dev->event_lock, flags);
-+}
-+
-+static void vc4_crtc_enable(struct drm_crtc *crtc,
-+ struct drm_atomic_state *state)
-+{
-+ struct drm_plane *plane;
-+
-+ DRM_DEBUG_KMS("[CRTC:%d] vblanks on.\n",
-+ crtc->base.id);
-+ drm_crtc_vblank_on(crtc);
-+ vc4_crtc_consume_event(crtc);
-+
-+ /* Unblank the planes (if they're supposed to be displayed). */
-+ drm_atomic_crtc_for_each_plane(plane, crtc)
-+ if (plane->state->fb)
-+ vc4_plane_set_blank(plane, plane->state->visible);
-+}
-+
-+static enum drm_mode_status
-+vc4_crtc_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode *mode)
-+{
-+ struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
-+ struct drm_device *dev = crtc->dev;
-+ struct vc4_dev *vc4 = to_vc4_dev(dev);
-+ struct vc4_fkms *fkms = vc4->fkms;
-+
-+ /* Do not allow doublescan modes from user space */
-+ if (mode->flags & DRM_MODE_FLAG_DBLSCAN) {
-+ DRM_DEBUG_KMS("[CRTC:%d] Doublescan mode rejected.\n",
-+ crtc->base.id);
-+ return MODE_NO_DBLESCAN;
-+ }
-+
-+ /* Disable refresh rates > defined threshold (default 85Hz) as limited
-+ * gain from them
-+ */
-+ if (drm_mode_vrefresh(mode) > fkms_max_refresh_rate)
-+ return MODE_BAD_VVALUE;
-+
-+ /* Limit the pixel clock based on the HDMI clock limits from the
-+ * firmware
-+ */
-+ switch (vc4_crtc->display_number) {
-+ case 2: /* HDMI0 */
-+ if (fkms->cfg.max_pixel_clock[0] &&
-+ mode->clock > fkms->cfg.max_pixel_clock[0])
-+ return MODE_CLOCK_HIGH;
-+ break;
-+ case 7: /* HDMI1 */
-+ if (fkms->cfg.max_pixel_clock[1] &&
-+ mode->clock > fkms->cfg.max_pixel_clock[1])
-+ return MODE_CLOCK_HIGH;
-+ break;
-+ }
-+
-+ /* Pi4 can't generate odd horizontal timings on HDMI, so reject modes
-+ * that would set them.
-+ */
-+ if (fkms->bcm2711 &&
-+ (vc4_crtc->display_number == 2 || vc4_crtc->display_number == 7) &&
-+ !(mode->flags & DRM_MODE_FLAG_DBLCLK) &&
-+ ((mode->hdisplay | /* active */
-+ (mode->hsync_start - mode->hdisplay) | /* front porch */
-+ (mode->hsync_end - mode->hsync_start) | /* sync pulse */
-+ (mode->htotal - mode->hsync_end)) & 1)) /* back porch */ {
-+ DRM_DEBUG_KMS("[CRTC:%d] Odd timing rejected %u %u %u %u.\n",
-+ crtc->base.id, mode->hdisplay, mode->hsync_start,
-+ mode->hsync_end, mode->htotal);
-+ return MODE_H_ILLEGAL;
-+ }
-+
-+ return MODE_OK;
-+}
-+
-+static int vc4_crtc_atomic_check(struct drm_crtc *crtc,
-+ struct drm_atomic_state *state)
-+{
-+ struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state,
-+ crtc);
-+ struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc_state);
-+ struct drm_connector *conn;
-+ struct drm_connector_state *conn_state;
-+ int i;
-+
-+ DRM_DEBUG_KMS("[CRTC:%d] crtc_atomic_check.\n", crtc->base.id);
-+
-+ for_each_new_connector_in_state(crtc_state->state, conn, conn_state, i) {
-+ if (conn_state->crtc != crtc)
-+ continue;
-+
-+ vc4_state->margins.left = conn_state->tv.margins.left;
-+ vc4_state->margins.right = conn_state->tv.margins.right;
-+ vc4_state->margins.top = conn_state->tv.margins.top;
-+ vc4_state->margins.bottom = conn_state->tv.margins.bottom;
-+ break;
-+ }
-+ return 0;
-+}
-+
-+static void vc4_crtc_atomic_flush(struct drm_crtc *crtc,
-+ struct drm_atomic_state *state)
-+{
-+ struct drm_crtc_state *old_state = drm_atomic_get_old_crtc_state(state,
-+ crtc);
-+
-+ DRM_DEBUG_KMS("[CRTC:%d] crtc_atomic_flush.\n",
-+ crtc->base.id);
-+ if (crtc->state->active && old_state->active && crtc->state->event)
-+ vc4_crtc_consume_event(crtc);
-+}
-+
-+static void vc4_crtc_handle_page_flip(struct vc4_crtc *vc4_crtc)
-+{
-+ struct drm_crtc *crtc = &vc4_crtc->base;
-+ struct drm_device *dev = crtc->dev;
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&dev->event_lock, flags);
-+ if (vc4_crtc->event) {
-+ drm_crtc_send_vblank_event(crtc, vc4_crtc->event);
-+ vc4_crtc->event = NULL;
-+ drm_crtc_vblank_put(crtc);
-+ }
-+ spin_unlock_irqrestore(&dev->event_lock, flags);
-+}
-+
-+static irqreturn_t vc4_crtc_irq_handler(int irq, void *data)
-+{
-+ struct vc4_crtc **crtc_list = data;
-+ int i;
-+ u32 stat = readl(crtc_list[0]->regs + SMICS);
-+ irqreturn_t ret = IRQ_NONE;
-+ u32 chan;
-+
-+ if (stat & SMICS_INTERRUPTS) {
-+ writel(0, crtc_list[0]->regs + SMICS);
-+
-+ chan = readl(crtc_list[0]->regs + SMIDSW0);
-+
-+ if ((chan & 0xFFFF0000) != SMI_NEW) {
-+ /* Older firmware. Treat the one interrupt as vblank/
-+ * complete for all crtcs.
-+ */
-+ for (i = 0; crtc_list[i]; i++) {
-+ if (crtc_list[i]->vblank_enabled)
-+ drm_crtc_handle_vblank(&crtc_list[i]->base);
-+ vc4_crtc_handle_page_flip(crtc_list[i]);
-+ }
-+ } else {
-+ if (chan & 1) {
-+ writel(SMI_NEW, crtc_list[0]->regs + SMIDSW0);
-+ if (crtc_list[0]->vblank_enabled)
-+ drm_crtc_handle_vblank(&crtc_list[0]->base);
-+ vc4_crtc_handle_page_flip(crtc_list[0]);
-+ }
-+
-+ if (crtc_list[1]) {
-+ /* Check for the secondary display too */
-+ chan = readl(crtc_list[0]->regs + SMIDSW1);
-+
-+ if (chan & 1) {
-+ writel(SMI_NEW, crtc_list[0]->regs + SMIDSW1);
-+
-+ if (crtc_list[1]->vblank_enabled)
-+ drm_crtc_handle_vblank(&crtc_list[1]->base);
-+ vc4_crtc_handle_page_flip(crtc_list[1]);
-+ }
-+ }
-+ }
-+
-+ ret = IRQ_HANDLED;
-+ }
-+
-+ return ret;
-+}
-+
-+static int vc4_fkms_page_flip(struct drm_crtc *crtc,
-+ struct drm_framebuffer *fb,
-+ struct drm_pending_vblank_event *event,
-+ uint32_t flags,
-+ struct drm_modeset_acquire_ctx *ctx)
-+{
-+ if (flags & DRM_MODE_PAGE_FLIP_ASYNC) {
-+ DRM_ERROR("Async flips aren't allowed\n");
-+ return -EINVAL;
-+ }
-+
-+ return drm_atomic_helper_page_flip(crtc, fb, event, flags, ctx);
-+}
-+
-+static struct drm_crtc_state *
-+vc4_fkms_crtc_duplicate_state(struct drm_crtc *crtc)
-+{
-+ struct vc4_crtc_state *vc4_state, *old_vc4_state;
-+
-+ vc4_state = kzalloc(sizeof(*vc4_state), GFP_KERNEL);
-+ if (!vc4_state)
-+ return NULL;
-+
-+ old_vc4_state = to_vc4_crtc_state(crtc->state);
-+ vc4_state->margins = old_vc4_state->margins;
-+
-+ __drm_atomic_helper_crtc_duplicate_state(crtc, &vc4_state->base);
-+ return &vc4_state->base;
-+}
-+
-+static void
-+vc4_fkms_crtc_reset(struct drm_crtc *crtc)
-+{
-+ if (crtc->state)
-+ __drm_atomic_helper_crtc_destroy_state(crtc->state);
-+
-+ crtc->state = kzalloc(sizeof(*crtc->state), GFP_KERNEL);
-+ if (crtc->state)
-+ crtc->state->crtc = crtc;
-+}
-+
-+static int vc4_fkms_enable_vblank(struct drm_crtc *crtc)
-+{
-+ struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
-+
-+ DRM_DEBUG_KMS("[CRTC:%d] enable_vblank.\n",
-+ crtc->base.id);
-+ vc4_crtc->vblank_enabled = true;
-+
-+ return 0;
-+}
-+
-+static void vc4_fkms_disable_vblank(struct drm_crtc *crtc)
-+{
-+ struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
-+
-+ DRM_DEBUG_KMS("[CRTC:%d] disable_vblank.\n",
-+ crtc->base.id);
-+ vc4_crtc->vblank_enabled = false;
-+}
-+
-+static const struct drm_crtc_funcs vc4_crtc_funcs = {
-+ .set_config = drm_atomic_helper_set_config,
-+ .destroy = drm_crtc_cleanup,
-+ .page_flip = vc4_fkms_page_flip,
-+ .set_property = NULL,
-+ .cursor_set = NULL, /* handled by drm_mode_cursor_universal */
-+ .cursor_move = NULL, /* handled by drm_mode_cursor_universal */
-+ .reset = vc4_fkms_crtc_reset,
-+ .atomic_duplicate_state = vc4_fkms_crtc_duplicate_state,
-+ .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
-+ .enable_vblank = vc4_fkms_enable_vblank,
-+ .disable_vblank = vc4_fkms_disable_vblank,
-+};
-+
-+static const struct drm_crtc_helper_funcs vc4_crtc_helper_funcs = {
-+ .mode_set_nofb = vc4_crtc_mode_set_nofb,
-+ .mode_valid = vc4_crtc_mode_valid,
-+ .atomic_check = vc4_crtc_atomic_check,
-+ .atomic_flush = vc4_crtc_atomic_flush,
-+ .atomic_enable = vc4_crtc_enable,
-+ .atomic_disable = vc4_crtc_disable,
-+};
-+
-+static const struct of_device_id vc4_firmware_kms_dt_match[] = {
-+ { .compatible = "raspberrypi,rpi-firmware-kms" },
-+ { .compatible = "raspberrypi,rpi-firmware-kms-2711",
-+ .data = (void *)1 },
-+ {}
-+};
-+
-+static enum drm_connector_status
-+vc4_fkms_connector_detect(struct drm_connector *connector, bool force)
-+{
-+ DRM_DEBUG_KMS("connector detect.\n");
-+ return connector_status_connected;
-+}
-+
-+/* Queries the firmware to populate a drm_mode structure for this display */
-+static int vc4_fkms_get_fw_mode(struct vc4_fkms_connector *fkms_connector,
-+ struct drm_display_mode *mode)
-+{
-+ struct vc4_dev *vc4 = fkms_connector->vc4_dev;
-+ struct set_timings timings = { 0 };
-+ int ret;
-+
-+ timings.display = fkms_connector->display_number;
-+
-+ ret = rpi_firmware_property(vc4->firmware,
-+ RPI_FIRMWARE_GET_DISPLAY_TIMING, &timings,
-+ sizeof(timings));
-+ if (ret || !timings.clock)
-+ /* No mode returned - abort */
-+ return -1;
-+
-+ /* Equivalent to DRM_MODE macro. */
-+ memset(mode, 0, sizeof(*mode));
-+ strncpy(mode->name, "FIXED_MODE", sizeof(mode->name));
-+ mode->status = 0;
-+ mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
-+ mode->clock = timings.clock;
-+ mode->hdisplay = timings.hdisplay;
-+ mode->hsync_start = timings.hsync_start;
-+ mode->hsync_end = timings.hsync_end;
-+ mode->htotal = timings.htotal;
-+ mode->hskew = 0;
-+ mode->vdisplay = timings.vdisplay;
-+ mode->vsync_start = timings.vsync_start;
-+ mode->vsync_end = timings.vsync_end;
-+ mode->vtotal = timings.vtotal;
-+ mode->vscan = timings.vscan;
-+
-+ if (timings.flags & TIMINGS_FLAGS_H_SYNC_POS)
-+ mode->flags |= DRM_MODE_FLAG_PHSYNC;
-+ else
-+ mode->flags |= DRM_MODE_FLAG_NHSYNC;
-+
-+ if (timings.flags & TIMINGS_FLAGS_V_SYNC_POS)
-+ mode->flags |= DRM_MODE_FLAG_PVSYNC;
-+ else
-+ mode->flags |= DRM_MODE_FLAG_NVSYNC;
-+
-+ if (timings.flags & TIMINGS_FLAGS_INTERLACE)
-+ mode->flags |= DRM_MODE_FLAG_INTERLACE;
-+
-+ return 0;
-+}
-+
-+static int vc4_fkms_get_edid_block(void *data, u8 *buf, unsigned int block,
-+ size_t len)
-+{
-+ struct vc4_fkms_connector *fkms_connector =
-+ (struct vc4_fkms_connector *)data;
-+ struct vc4_dev *vc4 = fkms_connector->vc4_dev;
-+ struct mailbox_get_edid mb = {
-+ .tag1 = { RPI_FIRMWARE_GET_EDID_BLOCK_DISPLAY,
-+ 128 + 8, 0 },
-+ .block = block,
-+ .display_number = fkms_connector->display_number,
-+ };
-+ int ret = 0;
-+
-+ ret = rpi_firmware_property_list(vc4->firmware, &mb, sizeof(mb));
-+
-+ if (!ret)
-+ memcpy(buf, mb.edid, len);
-+
-+ return ret;
-+}
-+
-+static int vc4_fkms_connector_get_modes(struct drm_connector *connector)
-+{
-+ struct vc4_fkms_connector *fkms_connector =
-+ to_vc4_fkms_connector(connector);
-+ struct drm_encoder *encoder = fkms_connector->encoder;
-+ struct vc4_fkms_encoder *vc4_encoder = to_vc4_fkms_encoder(encoder);
-+ struct drm_display_mode fw_mode;
-+ struct drm_display_mode *mode;
-+ struct edid *edid;
-+ int num_modes;
-+
-+ if (!vc4_fkms_get_fw_mode(fkms_connector, &fw_mode)) {
-+ drm_mode_debug_printmodeline(&fw_mode);
-+ mode = drm_mode_duplicate(connector->dev,
-+ &fw_mode);
-+ drm_mode_probed_add(connector, mode);
-+ num_modes = 1; /* 1 mode */
-+ } else {
-+ edid = drm_do_get_edid(connector, vc4_fkms_get_edid_block,
-+ fkms_connector);
-+
-+ /* FIXME: Can we do CEC?
-+ * cec_s_phys_addr_from_edid(vc4->hdmi->cec_adap, edid);
-+ * if (!edid)
-+ * return -ENODEV;
-+ */
-+
-+ vc4_encoder->hdmi_monitor = drm_detect_hdmi_monitor(edid);
-+
-+ drm_connector_update_edid_property(connector, edid);
-+ num_modes = drm_add_edid_modes(connector, edid);
-+ kfree(edid);
-+ }
-+
-+ return num_modes;
-+}
-+
-+/* This is the DSI panel resolution. Use this as a default should the firmware
-+ * not respond to our request for the timings.
-+ */
-+static const struct drm_display_mode lcd_mode = {
-+ DRM_MODE("800x480", DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
-+ 25979400 / 1000,
-+ 800, 800 + 1, 800 + 1 + 2, 800 + 1 + 2 + 46, 0,
-+ 480, 480 + 7, 480 + 7 + 2, 480 + 7 + 2 + 21, 0,
-+ 0)
-+};
-+
-+static int vc4_fkms_lcd_connector_get_modes(struct drm_connector *connector)
-+{
-+ struct vc4_fkms_connector *fkms_connector =
-+ to_vc4_fkms_connector(connector);
-+ struct drm_display_mode *mode;
-+ struct drm_display_mode fw_mode;
-+
-+ if (!vc4_fkms_get_fw_mode(fkms_connector, &fw_mode) && fw_mode.clock)
-+ mode = drm_mode_duplicate(connector->dev,
-+ &fw_mode);
-+ else
-+ mode = drm_mode_duplicate(connector->dev,
-+ &lcd_mode);
-+
-+ if (!mode) {
-+ DRM_ERROR("Failed to create a new display mode\n");
-+ return -ENOMEM;
-+ }
-+
-+ drm_mode_probed_add(connector, mode);
-+
-+ /* We have one mode */
-+ return 1;
-+}
-+
-+static struct drm_encoder *
-+vc4_fkms_connector_best_encoder(struct drm_connector *connector)
-+{
-+ struct vc4_fkms_connector *fkms_connector =
-+ to_vc4_fkms_connector(connector);
-+ DRM_DEBUG_KMS("best_connector.\n");
-+ return fkms_connector->encoder;
-+}
-+
-+static void vc4_fkms_connector_destroy(struct drm_connector *connector)
-+{
-+ DRM_DEBUG_KMS("[CONNECTOR:%d] destroy.\n",
-+ connector->base.id);
-+ drm_connector_unregister(connector);
-+ drm_connector_cleanup(connector);
-+}
-+
-+/**
-+ * vc4_connector_duplicate_state - duplicate connector state
-+ * @connector: digital connector
-+ *
-+ * Allocates and returns a copy of the connector state (both common and
-+ * digital connector specific) for the specified connector.
-+ *
-+ * Returns: The newly allocated connector state, or NULL on failure.
-+ */
-+struct drm_connector_state *
-+vc4_connector_duplicate_state(struct drm_connector *connector)
-+{
-+ struct vc4_fkms_connector_state *state;
-+
-+ state = kmemdup(connector->state, sizeof(*state), GFP_KERNEL);
-+ if (!state)
-+ return NULL;
-+
-+ __drm_atomic_helper_connector_duplicate_state(connector, &state->base);
-+ return &state->base;
-+}
-+
-+/**
-+ * vc4_connector_atomic_get_property - hook for connector->atomic_get_property.
-+ * @connector: Connector to get the property for.
-+ * @state: Connector state to retrieve the property from.
-+ * @property: Property to retrieve.
-+ * @val: Return value for the property.
-+ *
-+ * Returns the atomic property value for a digital connector.
-+ */
-+int vc4_connector_atomic_get_property(struct drm_connector *connector,
-+ const struct drm_connector_state *state,
-+ struct drm_property *property,
-+ uint64_t *val)
-+{
-+ struct vc4_fkms_connector *fkms_connector =
-+ to_vc4_fkms_connector(connector);
-+ struct vc4_fkms_connector_state *vc4_conn_state =
-+ to_vc4_fkms_connector_state(state);
-+
-+ if (property == fkms_connector->broadcast_rgb_property) {
-+ *val = vc4_conn_state->broadcast_rgb;
-+ } else {
-+ DRM_DEBUG_ATOMIC("Unknown property [PROP:%d:%s]\n",
-+ property->base.id, property->name);
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+
-+/**
-+ * vc4_connector_atomic_set_property - hook for connector->atomic_set_property.
-+ * @connector: Connector to set the property for.
-+ * @state: Connector state to set the property on.
-+ * @property: Property to set.
-+ * @val: New value for the property.
-+ *
-+ * Sets the atomic property value for a digital connector.
-+ */
-+int vc4_connector_atomic_set_property(struct drm_connector *connector,
-+ struct drm_connector_state *state,
-+ struct drm_property *property,
-+ uint64_t val)
-+{
-+ struct vc4_fkms_connector *fkms_connector =
-+ to_vc4_fkms_connector(connector);
-+ struct vc4_fkms_connector_state *vc4_conn_state =
-+ to_vc4_fkms_connector_state(state);
-+
-+ if (property == fkms_connector->broadcast_rgb_property) {
-+ vc4_conn_state->broadcast_rgb = val;
-+ return 0;
-+ }
-+
-+ DRM_DEBUG_ATOMIC("Unknown property [PROP:%d:%s]\n",
-+ property->base.id, property->name);
-+ return -EINVAL;
-+}
-+
-+int vc4_connector_atomic_check(struct drm_connector *connector,
-+ struct drm_atomic_state *state)
-+{
-+ struct drm_connector_state *old_state =
-+ drm_atomic_get_old_connector_state(state, connector);
-+ struct vc4_fkms_connector_state *vc4_old_state =
-+ to_vc4_fkms_connector_state(old_state);
-+ struct drm_connector_state *new_state =
-+ drm_atomic_get_new_connector_state(state, connector);
-+ struct vc4_fkms_connector_state *vc4_new_state =
-+ to_vc4_fkms_connector_state(new_state);
-+ struct drm_crtc *crtc = new_state->crtc;
-+
-+ if (!crtc)
-+ return 0;
-+
-+ if (vc4_old_state->broadcast_rgb != vc4_new_state->broadcast_rgb) {
-+ struct drm_crtc_state *crtc_state;
-+
-+ crtc_state = drm_atomic_get_crtc_state(state, crtc);
-+ if (IS_ERR(crtc_state))
-+ return PTR_ERR(crtc_state);
-+
-+ crtc_state->mode_changed = true;
-+ }
-+ return 0;
-+}
-+
-+static void vc4_hdmi_connector_reset(struct drm_connector *connector)
-+{
-+ drm_atomic_helper_connector_reset(connector);
-+ drm_atomic_helper_connector_tv_reset(connector);
-+}
-+
-+static const struct drm_connector_funcs vc4_fkms_connector_funcs = {
-+ .detect = vc4_fkms_connector_detect,
-+ .fill_modes = drm_helper_probe_single_connector_modes,
-+ .destroy = vc4_fkms_connector_destroy,
-+ .reset = vc4_hdmi_connector_reset,
-+ .atomic_duplicate_state = vc4_connector_duplicate_state,
-+ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
-+ .atomic_get_property = vc4_connector_atomic_get_property,
-+ .atomic_set_property = vc4_connector_atomic_set_property,
-+};
-+
-+static const struct drm_connector_helper_funcs vc4_fkms_connector_helper_funcs = {
-+ .get_modes = vc4_fkms_connector_get_modes,
-+ .best_encoder = vc4_fkms_connector_best_encoder,
-+ .atomic_check = vc4_connector_atomic_check,
-+};
-+
-+static const struct drm_connector_helper_funcs vc4_fkms_lcd_conn_helper_funcs = {
-+ .get_modes = vc4_fkms_lcd_connector_get_modes,
-+ .best_encoder = vc4_fkms_connector_best_encoder,
-+};
-+
-+static const struct drm_prop_enum_list broadcast_rgb_names[] = {
-+ { VC4_BROADCAST_RGB_AUTO, "Automatic" },
-+ { VC4_BROADCAST_RGB_FULL, "Full" },
-+ { VC4_BROADCAST_RGB_LIMITED, "Limited 16:235" },
-+};
-+
-+static void
-+vc4_attach_broadcast_rgb_property(struct vc4_fkms_connector *fkms_connector)
-+{
-+ struct drm_device *dev = fkms_connector->base.dev;
-+ struct drm_property *prop;
-+
-+ prop = fkms_connector->broadcast_rgb_property;
-+ if (!prop) {
-+ prop = drm_property_create_enum(dev, DRM_MODE_PROP_ENUM,
-+ "Broadcast RGB",
-+ broadcast_rgb_names,
-+ ARRAY_SIZE(broadcast_rgb_names));
-+ if (!prop)
-+ return;
-+
-+ fkms_connector->broadcast_rgb_property = prop;
-+ }
-+
-+ drm_object_attach_property(&fkms_connector->base.base, prop, 0);
-+}
-+
-+static struct drm_connector *
-+vc4_fkms_connector_init(struct drm_device *dev, struct drm_encoder *encoder,
-+ u32 display_num)
-+{
-+ struct drm_connector *connector = NULL;
-+ struct vc4_fkms_connector *fkms_connector;
-+ struct vc4_fkms_connector_state *conn_state = NULL;
-+ struct vc4_dev *vc4_dev = to_vc4_dev(dev);
-+ int ret = 0;
-+
-+ DRM_DEBUG_KMS("connector_init, display_num %u\n", display_num);
-+
-+ fkms_connector = devm_kzalloc(dev->dev, sizeof(*fkms_connector),
-+ GFP_KERNEL);
-+ if (!fkms_connector)
-+ return ERR_PTR(-ENOMEM);
-+
-+ /*
-+ * Allocate enough memory to hold vc4_fkms_connector_state,
-+ */
-+ conn_state = kzalloc(sizeof(*conn_state), GFP_KERNEL);
-+ if (!conn_state) {
-+ kfree(fkms_connector);
-+ return ERR_PTR(-ENOMEM);
-+ }
-+
-+ connector = &fkms_connector->base;
-+
-+ fkms_connector->encoder = encoder;
-+ fkms_connector->display_number = display_num;
-+ fkms_connector->display_type = vc4_get_display_type(display_num);
-+ fkms_connector->vc4_dev = vc4_dev;
-+
-+ __drm_atomic_helper_connector_reset(connector,
-+ &conn_state->base);
-+
-+ if (fkms_connector->display_type == DRM_MODE_ENCODER_DSI) {
-+ drm_connector_init(dev, connector, &vc4_fkms_connector_funcs,
-+ DRM_MODE_CONNECTOR_DSI);
-+ drm_connector_helper_add(connector,
-+ &vc4_fkms_lcd_conn_helper_funcs);
-+ connector->interlace_allowed = 0;
-+ } else if (fkms_connector->display_type == DRM_MODE_ENCODER_TVDAC) {
-+ drm_connector_init(dev, connector, &vc4_fkms_connector_funcs,
-+ DRM_MODE_CONNECTOR_Composite);
-+ drm_connector_helper_add(connector,
-+ &vc4_fkms_lcd_conn_helper_funcs);
-+ connector->interlace_allowed = 1;
-+ } else {
-+ drm_connector_init(dev, connector, &vc4_fkms_connector_funcs,
-+ DRM_MODE_CONNECTOR_HDMIA);
-+ drm_connector_helper_add(connector,
-+ &vc4_fkms_connector_helper_funcs);
-+ connector->interlace_allowed = 1;
-+ }
-+
-+ ret = drm_mode_create_tv_margin_properties(dev);
-+ if (ret)
-+ goto fail;
-+
-+ drm_connector_attach_tv_margin_properties(connector);
-+
-+ connector->polled = (DRM_CONNECTOR_POLL_CONNECT |
-+ DRM_CONNECTOR_POLL_DISCONNECT);
-+
-+ connector->doublescan_allowed = 0;
-+
-+ vc4_attach_broadcast_rgb_property(fkms_connector);
-+
-+ drm_connector_attach_encoder(connector, encoder);
-+
-+ return connector;
-+
-+ fail:
-+ if (connector)
-+ vc4_fkms_connector_destroy(connector);
-+
-+ return ERR_PTR(ret);
-+}
-+
-+static void vc4_fkms_encoder_destroy(struct drm_encoder *encoder)
-+{
-+ DRM_DEBUG_KMS("Encoder_destroy\n");
-+ drm_encoder_cleanup(encoder);
-+}
-+
-+static const struct drm_encoder_funcs vc4_fkms_encoder_funcs = {
-+ .destroy = vc4_fkms_encoder_destroy,
-+};
-+
-+static void vc4_fkms_display_power(struct drm_encoder *encoder, bool power)
-+{
-+ struct vc4_fkms_encoder *vc4_encoder = to_vc4_fkms_encoder(encoder);
-+ struct vc4_dev *vc4 = to_vc4_dev(encoder->dev);
-+
-+ struct mailbox_display_pwr pwr = {
-+ .tag1 = {RPI_FIRMWARE_SET_DISPLAY_POWER, 8, 0, },
-+ .display = vc4_encoder->display_num,
-+ .state = power ? 1 : 0,
-+ };
-+
-+ rpi_firmware_property_list(vc4->firmware, &pwr, sizeof(pwr));
-+}
-+
-+static void vc4_fkms_encoder_enable(struct drm_encoder *encoder)
-+{
-+ vc4_fkms_display_power(encoder, true);
-+ DRM_DEBUG_KMS("Encoder_enable\n");
-+}
-+
-+static void vc4_fkms_encoder_disable(struct drm_encoder *encoder)
-+{
-+ vc4_fkms_display_power(encoder, false);
-+ DRM_DEBUG_KMS("Encoder_disable\n");
-+}
-+
-+static const struct drm_encoder_helper_funcs vc4_fkms_encoder_helper_funcs = {
-+ .enable = vc4_fkms_encoder_enable,
-+ .disable = vc4_fkms_encoder_disable,
-+};
-+
-+static int vc4_fkms_create_screen(struct device *dev, struct drm_device *drm,
-+ int display_idx, int display_ref,
-+ struct vc4_crtc **ret_crtc)
-+{
-+ struct vc4_dev *vc4 = to_vc4_dev(drm);
-+ struct vc4_crtc *vc4_crtc;
-+ struct vc4_fkms_encoder *vc4_encoder;
-+ struct drm_crtc *crtc;
-+ struct drm_plane *destroy_plane, *temp;
-+ struct mailbox_blank_display blank = {
-+ .tag1 = {RPI_FIRMWARE_FRAMEBUFFER_SET_DISPLAY_NUM, 4, 0, },
-+ .display = display_idx,
-+ .tag2 = { RPI_FIRMWARE_FRAMEBUFFER_BLANK, 4, 0, },
-+ .blank = 1,
-+ };
-+ struct drm_plane *planes[PLANES_PER_CRTC];
-+ int ret, i;
-+
-+ vc4_crtc = devm_kzalloc(dev, sizeof(*vc4_crtc), GFP_KERNEL);
-+ if (!vc4_crtc)
-+ return -ENOMEM;
-+ crtc = &vc4_crtc->base;
-+
-+ vc4_crtc->display_number = display_ref;
-+ vc4_crtc->display_type = vc4_get_display_type(display_ref);
-+
-+ /* Blank the firmware provided framebuffer */
-+ rpi_firmware_property_list(vc4->firmware, &blank, sizeof(blank));
-+
-+ for (i = 0; i < PLANES_PER_CRTC; i++) {
-+ planes[i] = vc4_fkms_plane_init(drm,
-+ (i == 0) ?
-+ DRM_PLANE_TYPE_PRIMARY :
-+ (i == PLANES_PER_CRTC - 1) ?
-+ DRM_PLANE_TYPE_CURSOR :
-+ DRM_PLANE_TYPE_OVERLAY,
-+ display_ref,
-+ i + (display_idx * PLANES_PER_CRTC)
-+ );
-+ if (IS_ERR(planes[i])) {
-+ dev_err(dev, "failed to construct plane %u\n", i);
-+ ret = PTR_ERR(planes[i]);
-+ goto err;
-+ }
-+ }
-+
-+ drm_crtc_init_with_planes(drm, crtc, planes[0],
-+ planes[PLANES_PER_CRTC - 1], &vc4_crtc_funcs,
-+ NULL);
-+ drm_crtc_helper_add(crtc, &vc4_crtc_helper_funcs);
-+
-+ /* Update the possible_crtcs mask for the overlay plane(s) */
-+ for (i = 1; i < (PLANES_PER_CRTC - 1); i++)
-+ planes[i]->possible_crtcs = drm_crtc_mask(crtc);
-+
-+ vc4_encoder = devm_kzalloc(dev, sizeof(*vc4_encoder), GFP_KERNEL);
-+ if (!vc4_encoder)
-+ return -ENOMEM;
-+ vc4_crtc->encoder = &vc4_encoder->base;
-+
-+ vc4_encoder->display_num = display_ref;
-+ vc4_encoder->base.possible_crtcs |= drm_crtc_mask(crtc);
-+
-+ drm_encoder_init(drm, &vc4_encoder->base, &vc4_fkms_encoder_funcs,
-+ vc4_crtc->display_type, NULL);
-+ drm_encoder_helper_add(&vc4_encoder->base,
-+ &vc4_fkms_encoder_helper_funcs);
-+
-+ vc4_crtc->connector = vc4_fkms_connector_init(drm, &vc4_encoder->base,
-+ display_ref);
-+ if (IS_ERR(vc4_crtc->connector)) {
-+ ret = PTR_ERR(vc4_crtc->connector);
-+ goto err_destroy_encoder;
-+ }
-+
-+ *ret_crtc = vc4_crtc;
-+
-+ return 0;
-+
-+err_destroy_encoder:
-+ vc4_fkms_encoder_destroy(vc4_crtc->encoder);
-+ list_for_each_entry_safe(destroy_plane, temp,
-+ &drm->mode_config.plane_list, head) {
-+ if (destroy_plane->possible_crtcs == 1 << drm_crtc_index(crtc))
-+ destroy_plane->funcs->destroy(destroy_plane);
-+ }
-+err:
-+ return ret;
-+}
-+
-+static int vc4_fkms_bind(struct device *dev, struct device *master, void *data)
-+{
-+ struct platform_device *pdev = to_platform_device(dev);
-+ struct drm_device *drm = dev_get_drvdata(master);
-+ struct vc4_dev *vc4 = to_vc4_dev(drm);
-+ struct device_node *firmware_node;
-+ const struct of_device_id *match;
-+ struct vc4_crtc **crtc_list;
-+ u32 num_displays, display_num;
-+ struct vc4_fkms *fkms;
-+ int ret;
-+ u32 display_id;
-+
-+ vc4->firmware_kms = true;
-+
-+ fkms = devm_kzalloc(dev, sizeof(*fkms), GFP_KERNEL);
-+ if (!fkms)
-+ return -ENOMEM;
-+
-+ match = of_match_device(vc4_firmware_kms_dt_match, dev);
-+ if (!match)
-+ return -ENODEV;
-+ if (match->data)
-+ fkms->bcm2711 = true;
-+
-+ firmware_node = of_parse_phandle(dev->of_node, "brcm,firmware", 0);
-+ vc4->firmware = devm_rpi_firmware_get(&pdev->dev, firmware_node);
-+ if (!vc4->firmware) {
-+ DRM_DEBUG("Failed to get Raspberry Pi firmware reference.\n");
-+ return -EPROBE_DEFER;
-+ }
-+ of_node_put(firmware_node);
-+
-+ ret = rpi_firmware_property(vc4->firmware,
-+ RPI_FIRMWARE_FRAMEBUFFER_GET_NUM_DISPLAYS,
-+ &num_displays, sizeof(u32));
-+
-+ /* If we fail to get the number of displays, then
-+ * assume old firmware that doesn't have the mailbox call, so just
-+ * set one display
-+ */
-+ if (ret) {
-+ num_displays = 1;
-+ DRM_WARN("Unable to determine number of displays - assuming 1\n");
-+ ret = 0;
-+ }
-+
-+ ret = rpi_firmware_property(vc4->firmware,
-+ RPI_FIRMWARE_GET_DISPLAY_CFG,
-+ &fkms->cfg, sizeof(fkms->cfg));
-+
-+ if (ret)
-+ return -EINVAL;
-+ /* The firmware works in Hz. This will be compared against kHz, so div
-+ * 1000 now rather than multiple times later.
-+ */
-+ fkms->cfg.max_pixel_clock[0] /= 1000;
-+ fkms->cfg.max_pixel_clock[1] /= 1000;
-+
-+ /* Allocate a list, with space for a NULL on the end */
-+ crtc_list = devm_kzalloc(dev, sizeof(crtc_list) * (num_displays + 1),
-+ GFP_KERNEL);
-+ if (!crtc_list)
-+ return -ENOMEM;
-+
-+ for (display_num = 0; display_num < num_displays; display_num++) {
-+ display_id = display_num;
-+ ret = rpi_firmware_property(vc4->firmware,
-+ RPI_FIRMWARE_FRAMEBUFFER_GET_DISPLAY_ID,
-+ &display_id, sizeof(display_id));
-+ /* FIXME: Determine the correct error handling here.
-+ * Should we fail to create the one "screen" but keep the
-+ * others, or fail the whole thing?
-+ */
-+ if (ret)
-+ DRM_ERROR("Failed to get display id %u\n", display_num);
-+
-+ ret = vc4_fkms_create_screen(dev, drm, display_num, display_id,
-+ &crtc_list[display_num]);
-+ if (ret)
-+ DRM_ERROR("Oh dear, failed to create display %u\n",
-+ display_num);
-+ }
-+
-+ if (num_displays > 0) {
-+ /* Map the SMI interrupt reg */
-+ crtc_list[0]->regs = vc4_ioremap_regs(pdev, 0);
-+ if (IS_ERR(crtc_list[0]->regs))
-+ DRM_ERROR("Oh dear, failed to map registers\n");
-+
-+ writel(0, crtc_list[0]->regs + SMICS);
-+ ret = devm_request_irq(dev, platform_get_irq(pdev, 0),
-+ vc4_crtc_irq_handler, 0,
-+ "vc4 firmware kms", crtc_list);
-+ if (ret)
-+ DRM_ERROR("Oh dear, failed to register IRQ\n");
-+ } else {
-+ DRM_WARN("No displays found. Consider forcing hotplug if HDMI is attached\n");
-+ }
-+
-+ vc4->fkms = fkms;
-+
-+ platform_set_drvdata(pdev, crtc_list);
-+
-+ return 0;
-+}
-+
-+static void vc4_fkms_unbind(struct device *dev, struct device *master,
-+ void *data)
-+{
-+ struct platform_device *pdev = to_platform_device(dev);
-+ struct vc4_crtc **crtc_list = dev_get_drvdata(dev);
-+ int i;
-+
-+ for (i = 0; crtc_list[i]; i++) {
-+ vc4_fkms_connector_destroy(crtc_list[i]->connector);
-+ vc4_fkms_encoder_destroy(crtc_list[i]->encoder);
-+ drm_crtc_cleanup(&crtc_list[i]->base);
-+ }
-+
-+ platform_set_drvdata(pdev, NULL);
-+}
-+
-+static const struct component_ops vc4_fkms_ops = {
-+ .bind = vc4_fkms_bind,
-+ .unbind = vc4_fkms_unbind,
-+};
-+
-+static int vc4_fkms_probe(struct platform_device *pdev)
-+{
-+ return component_add(&pdev->dev, &vc4_fkms_ops);
-+}
-+
-+static int vc4_fkms_remove(struct platform_device *pdev)
-+{
-+ component_del(&pdev->dev, &vc4_fkms_ops);
-+ return 0;
-+}
-+
-+struct platform_driver vc4_firmware_kms_driver = {
-+ .probe = vc4_fkms_probe,
-+ .remove = vc4_fkms_remove,
-+ .driver = {
-+ .name = "vc4_firmware_kms",
-+ .of_match_table = vc4_firmware_kms_dt_match,
-+ },
-+};
-diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c
-index 0a6347c05df4..e52a4cfaebf6 100644
---- a/drivers/gpu/drm/vc4/vc4_kms.c
-+++ b/drivers/gpu/drm/vc4/vc4_kms.c
-@@ -162,6 +162,9 @@ vc4_ctm_commit(struct vc4_dev *vc4, struct drm_atomic_state *state)
- struct vc4_ctm_state *ctm_state = to_vc4_ctm_state(vc4->ctm_manager.state);
- struct drm_color_ctm *ctm = ctm_state->ctm;
-
-+ if (vc4->firmware_kms)
-+ return;
-+
- if (ctm_state->fifo) {
- HVS_WRITE(SCALER_OLEDCOEF2,
- VC4_SET_FIELD(vc4_ctm_s31_32_to_s0_9(ctm->matrix[0]),
-@@ -367,7 +370,7 @@ static void vc4_atomic_commit_tail(struct drm_atomic_state *state)
- for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
- struct vc4_crtc_state *vc4_crtc_state;
-
-- if (!new_crtc_state->commit)
-+ if (!new_crtc_state->commit || vc4->firmware_kms)
- continue;
-
- vc4_crtc_state = to_vc4_crtc_state(new_crtc_state);
-@@ -393,7 +396,7 @@ static void vc4_atomic_commit_tail(struct drm_atomic_state *state)
- old_hvs_state->fifo_state[channel].pending_commit = NULL;
- }
-
-- if (vc4->is_vc5) {
-+ if (vc4->is_vc5 && !vc4->firmware_kms) {
- unsigned long state_rate = max(old_hvs_state->core_clock_rate,
- new_hvs_state->core_clock_rate);
- unsigned long core_rate = max_t(unsigned long,
-@@ -412,10 +415,12 @@ static void vc4_atomic_commit_tail(struct drm_atomic_state *state)
-
- vc4_ctm_commit(vc4, state);
-
-- if (vc4->is_vc5)
-- vc5_hvs_pv_muxing_commit(vc4, state);
-- else
-- vc4_hvs_pv_muxing_commit(vc4, state);
-+ if (!vc4->firmware_kms) {
-+ if (vc4->is_vc5)
-+ vc5_hvs_pv_muxing_commit(vc4, state);
-+ else
-+ vc4_hvs_pv_muxing_commit(vc4, state);
-+ }
-
- drm_atomic_helper_commit_planes(dev, state,
- DRM_PLANE_COMMIT_ACTIVE_ONLY);
-@@ -430,7 +435,7 @@ static void vc4_atomic_commit_tail(struct drm_atomic_state *state)
-
- drm_atomic_helper_cleanup_planes(dev, state);
-
-- if (vc4->is_vc5) {
-+ if (vc4->is_vc5 && !vc4->firmware_kms) {
- drm_dbg(dev, "Running the core clock at %lu Hz\n",
- new_hvs_state->core_clock_rate);
-
-@@ -447,11 +452,21 @@ static void vc4_atomic_commit_tail(struct drm_atomic_state *state)
-
- static int vc4_atomic_commit_setup(struct drm_atomic_state *state)
- {
-+ struct drm_device *dev = state->dev;
-+ struct vc4_dev *vc4 = to_vc4_dev(dev);
- struct drm_crtc_state *crtc_state;
- struct vc4_hvs_state *hvs_state;
- struct drm_crtc *crtc;
- unsigned int i;
-
-+ /* We know for sure we don't want an async update here. Set
-+ * state->legacy_cursor_update to false to prevent
-+ * drm_atomic_helper_setup_commit() from auto-completing
-+ * commit->flip_done.
-+ */
-+ if (!vc4->firmware_kms)
-+ state->legacy_cursor_update = false;
-+
- hvs_state = vc4_hvs_get_new_global_state(state);
- if (WARN_ON(IS_ERR(hvs_state)))
- return PTR_ERR(hvs_state);
-@@ -806,6 +821,7 @@ static int vc4_hvs_channels_obj_init(struct vc4_dev *vc4)
- static int vc4_pv_muxing_atomic_check(struct drm_device *dev,
- struct drm_atomic_state *state)
- {
-+ struct vc4_dev *vc4 = to_vc4_dev(state->dev);
- struct vc4_hvs_state *hvs_new_state;
- struct drm_crtc_state *old_crtc_state, *new_crtc_state;
- struct drm_crtc *crtc;
-@@ -829,6 +845,9 @@ static int vc4_pv_muxing_atomic_check(struct drm_device *dev,
- unsigned int matching_channels;
- unsigned int channel;
-
-+ if (vc4->firmware_kms)
-+ continue;
-+
- drm_dbg(dev, "%s: Trying to find a channel.\n", crtc->name);
-
- /* Nothing to do here, let's skip it */
-@@ -1047,6 +1066,8 @@ int vc4_kms_load(struct drm_device *dev)
- dev->mode_config.helper_private = &vc4_mode_config_helpers;
- dev->mode_config.preferred_depth = 24;
- dev->mode_config.async_page_flip = true;
-+ if (vc4->firmware_kms)
-+ dev->mode_config.normalize_zpos = true;
-
- ret = vc4_ctm_obj_init(vc4);
- if (ret)
-diff --git a/drivers/gpu/drm/vc4/vc_image_types.h b/drivers/gpu/drm/vc4/vc_image_types.h
-new file mode 100644
-index 000000000000..e8d2b4b162f7
---- /dev/null
-+++ b/drivers/gpu/drm/vc4/vc_image_types.h
-@@ -0,0 +1,175 @@
-+
-+/*
-+ * Copyright (c) 2012, Broadcom Europe Ltd
-+ *
-+ * Values taken from vc_image_types.h released by Broadcom at
-+ * https://github.com/raspberrypi/userland/blob/master/interface/vctypes/vc_image_types.h
-+ * and vc_image_structs.h at
-+ * https://github.com/raspberrypi/userland/blob/master/interface/vctypes/vc_image_structs.h
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+
-+enum {
-+ VC_IMAGE_MIN = 0, //bounds for error checking
-+
-+ VC_IMAGE_RGB565 = 1,
-+ VC_IMAGE_1BPP,
-+ VC_IMAGE_YUV420,
-+ VC_IMAGE_48BPP,
-+ VC_IMAGE_RGB888,
-+ VC_IMAGE_8BPP,
-+ /* 4bpp palettised image */
-+ VC_IMAGE_4BPP,
-+ /* A separated format of 16 colour/light shorts followed by 16 z
-+ * values
-+ */
-+ VC_IMAGE_3D32,
-+ /* 16 colours followed by 16 z values */
-+ VC_IMAGE_3D32B,
-+ /* A separated format of 16 material/colour/light shorts followed by
-+ * 16 z values
-+ */
-+ VC_IMAGE_3D32MAT,
-+ /* 32 bit format containing 18 bits of 6.6.6 RGB, 9 bits per short */
-+ VC_IMAGE_RGB2X9,
-+ /* 32-bit format holding 18 bits of 6.6.6 RGB */
-+ VC_IMAGE_RGB666,
-+ /* 4bpp palettised image with embedded palette */
-+ VC_IMAGE_PAL4_OBSOLETE,
-+ /* 8bpp palettised image with embedded palette */
-+ VC_IMAGE_PAL8_OBSOLETE,
-+ /* RGB888 with an alpha byte after each pixel */
-+ VC_IMAGE_RGBA32,
-+ /* a line of Y (32-byte padded), a line of U (16-byte padded), and a
-+ * line of V (16-byte padded)
-+ */
-+ VC_IMAGE_YUV422,
-+ /* RGB565 with a transparent patch */
-+ VC_IMAGE_RGBA565,
-+ /* Compressed (4444) version of RGBA32 */
-+ VC_IMAGE_RGBA16,
-+ /* VCIII codec format */
-+ VC_IMAGE_YUV_UV,
-+ /* VCIII T-format RGBA8888 */
-+ VC_IMAGE_TF_RGBA32,
-+ /* VCIII T-format RGBx8888 */
-+ VC_IMAGE_TF_RGBX32,
-+ /* VCIII T-format float */
-+ VC_IMAGE_TF_FLOAT,
-+ /* VCIII T-format RGBA4444 */
-+ VC_IMAGE_TF_RGBA16,
-+ /* VCIII T-format RGB5551 */
-+ VC_IMAGE_TF_RGBA5551,
-+ /* VCIII T-format RGB565 */
-+ VC_IMAGE_TF_RGB565,
-+ /* VCIII T-format 8-bit luma and 8-bit alpha */
-+ VC_IMAGE_TF_YA88,
-+ /* VCIII T-format 8 bit generic sample */
-+ VC_IMAGE_TF_BYTE,
-+ /* VCIII T-format 8-bit palette */
-+ VC_IMAGE_TF_PAL8,
-+ /* VCIII T-format 4-bit palette */
-+ VC_IMAGE_TF_PAL4,
-+ /* VCIII T-format Ericsson Texture Compressed */
-+ VC_IMAGE_TF_ETC1,
-+ /* RGB888 with R & B swapped */
-+ VC_IMAGE_BGR888,
-+ /* RGB888 with R & B swapped, but with no pitch, i.e. no padding after
-+ * each row of pixels
-+ */
-+ VC_IMAGE_BGR888_NP,
-+ /* Bayer image, extra defines which variant is being used */
-+ VC_IMAGE_BAYER,
-+ /* General wrapper for codec images e.g. JPEG from camera */
-+ VC_IMAGE_CODEC,
-+ /* VCIII codec format */
-+ VC_IMAGE_YUV_UV32,
-+ /* VCIII T-format 8-bit luma */
-+ VC_IMAGE_TF_Y8,
-+ /* VCIII T-format 8-bit alpha */
-+ VC_IMAGE_TF_A8,
-+ /* VCIII T-format 16-bit generic sample */
-+ VC_IMAGE_TF_SHORT,
-+ /* VCIII T-format 1bpp black/white */
-+ VC_IMAGE_TF_1BPP,
-+ VC_IMAGE_OPENGL,
-+ /* VCIII-B0 HVS YUV 4:4:4 interleaved samples */
-+ VC_IMAGE_YUV444I,
-+ /* Y, U, & V planes separately (VC_IMAGE_YUV422 has them interleaved on
-+ * a per line basis)
-+ */
-+ VC_IMAGE_YUV422PLANAR,
-+ /* 32bpp with 8bit alpha at MS byte, with R, G, B (LS byte) */
-+ VC_IMAGE_ARGB8888,
-+ /* 32bpp with 8bit unused at MS byte, with R, G, B (LS byte) */
-+ VC_IMAGE_XRGB8888,
-+
-+ /* interleaved 8 bit samples of Y, U, Y, V (4 flavours) */
-+ VC_IMAGE_YUV422YUYV,
-+ VC_IMAGE_YUV422YVYU,
-+ VC_IMAGE_YUV422UYVY,
-+ VC_IMAGE_YUV422VYUY,
-+
-+ /* 32bpp like RGBA32 but with unused alpha */
-+ VC_IMAGE_RGBX32,
-+ /* 32bpp, corresponding to RGBA with unused alpha */
-+ VC_IMAGE_RGBX8888,
-+ /* 32bpp, corresponding to BGRA with unused alpha */
-+ VC_IMAGE_BGRX8888,
-+
-+ /* Y as a plane, then UV byte interleaved in plane with same pitch,
-+ * half height
-+ */
-+ VC_IMAGE_YUV420SP,
-+
-+ /* Y, U, & V planes separately 4:4:4 */
-+ VC_IMAGE_YUV444PLANAR,
-+
-+ /* T-format 8-bit U - same as TF_Y8 buf from U plane */
-+ VC_IMAGE_TF_U8,
-+ /* T-format 8-bit U - same as TF_Y8 buf from V plane */
-+ VC_IMAGE_TF_V8,
-+
-+ /* YUV4:2:0 planar, 16bit values */
-+ VC_IMAGE_YUV420_16,
-+ /* YUV4:2:0 codec format, 16bit values */
-+ VC_IMAGE_YUV_UV_16,
-+ /* YUV4:2:0 with U,V in side-by-side format */
-+ VC_IMAGE_YUV420_S,
-+ /* 10-bit YUV 420 column image format */
-+ VC_IMAGE_YUV10COL,
-+ /* 32-bpp, 10-bit R/G/B, 2-bit Alpha */
-+ VC_IMAGE_RGBA1010102,
-+
-+ VC_IMAGE_MAX, /* bounds for error checking */
-+ VC_IMAGE_FORCE_ENUM_16BIT = 0xffff,
-+};
-+
-+enum {
-+ /* Unknown or unset - defaults to BT601 interstitial */
-+ VC_IMAGE_YUVINFO_UNSPECIFIED = 0,
-+
-+ /* colour-space conversions data [4 bits] */
-+
-+ /* ITU-R BT.601-5 [SDTV] (compatible with VideoCore-II) */
-+ VC_IMAGE_YUVINFO_CSC_ITUR_BT601 = 1,
-+ /* ITU-R BT.709-3 [HDTV] */
-+ VC_IMAGE_YUVINFO_CSC_ITUR_BT709 = 2,
-+ /* JPEG JFIF */
-+ VC_IMAGE_YUVINFO_CSC_JPEG_JFIF = 3,
-+ /* Title 47 Code of Federal Regulations (2003) 73.682 (a) (20) */
-+ VC_IMAGE_YUVINFO_CSC_FCC = 4,
-+ /* Society of Motion Picture and Television Engineers 240M (1999) */
-+ VC_IMAGE_YUVINFO_CSC_SMPTE_240M = 5,
-+ /* ITU-R BT.470-2 System M */
-+ VC_IMAGE_YUVINFO_CSC_ITUR_BT470_2_M = 6,
-+ /* ITU-R BT.470-2 System B,G */
-+ VC_IMAGE_YUVINFO_CSC_ITUR_BT470_2_BG = 7,
-+ /* JPEG JFIF, but with 16..255 luma */
-+ VC_IMAGE_YUVINFO_CSC_JPEG_JFIF_Y16_255 = 8,
-+ /* Rec 2020 */
-+ VC_IMAGE_YUVINFO_CSC_REC_2020 = 9,
-+};
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Dave Stevenson
-Date: Tue, 27 Apr 2021 14:24:21 +0200
-Subject: [PATCH 012/784] drm/vc4: Add support for gamma on BCM2711
-
-BCM2711 changes from a 256 entry lookup table to a 16 point
-piecewise linear function as the pipeline bitdepth has increased
-to make a LUT unwieldy.
-
-Implement a simple conversion from a 256 entry LUT that userspace
-is likely to expect to 16 evenly spread points in the PWL. This
-could be improved with curve fitting at a later date.
-
-Co-developed-by: Juerg Haefliger
-Signed-off-by: Juerg Haefliger
-Signed-off-by: Dave Stevenson
-Signed-off-by: Maxime Ripard
----
- drivers/gpu/drm/vc4/vc4_crtc.c | 35 ++++++++++---
- drivers/gpu/drm/vc4/vc4_drv.h | 28 +++++++++--
- drivers/gpu/drm/vc4/vc4_hvs.c | 89 ++++++++++++++++++++++++++++++++--
- drivers/gpu/drm/vc4/vc4_regs.h | 22 +++++++++
- 4 files changed, 162 insertions(+), 12 deletions(-)
-
-diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
-index 308b0e1c8af4..1e22d13768a0 100644
---- a/drivers/gpu/drm/vc4/vc4_crtc.c
-+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
-@@ -1326,19 +1326,42 @@ int vc4_crtc_init(struct drm_device *drm, struct vc4_crtc *vc4_crtc,
-
- if (!vc4->is_vc5) {
- drm_mode_crtc_set_gamma_size(crtc, ARRAY_SIZE(vc4_crtc->lut_r));
-+ } else {
-+ /* This is a lie for hvs5 which uses a 16 point PWL, but it
-+ * allows for something smarter than just 16 linearly spaced
-+ * segments. Conversion is done in vc5_hvs_update_gamma_lut.
-+ */
-+ drm_mode_crtc_set_gamma_size(crtc, 256);
-+ }
-
-- drm_crtc_enable_color_mgmt(crtc, 0, false, crtc->gamma_size);
-+ drm_crtc_enable_color_mgmt(crtc, 0, false, crtc->gamma_size);
-
-+ if (!vc4->is_vc5) {
- /* We support CTM, but only for one CRTC at a time. It's therefore
- * implemented as private driver state in vc4_kms, not here.
- */
- drm_crtc_enable_color_mgmt(crtc, 0, true, crtc->gamma_size);
-- }
-
-- for (i = 0; i < crtc->gamma_size; i++) {
-- vc4_crtc->lut_r[i] = i;
-- vc4_crtc->lut_g[i] = i;
-- vc4_crtc->lut_b[i] = i;
-+ /* Initialize the VC4 gamma LUTs */
-+ for (i = 0; i < crtc->gamma_size; i++) {
-+ vc4_crtc->lut_r[i] = i;
-+ vc4_crtc->lut_g[i] = i;
-+ vc4_crtc->lut_b[i] = i;
-+ }
-+ } else {
-+ /* Initialize the VC5 gamma PWL entries. Assume 12-bit pipeline,
-+ * evenly spread over full range.
-+ */
-+ for (i = 0; i < SCALER5_DSPGAMMA_NUM_POINTS; i++) {
-+ vc4_crtc->pwl_r[i] =
-+ VC5_HVS_SET_GAMMA_ENTRY(i << 8, i << 12, 1 << 8);
-+ vc4_crtc->pwl_g[i] =
-+ VC5_HVS_SET_GAMMA_ENTRY(i << 8, i << 12, 1 << 8);
-+ vc4_crtc->pwl_b[i] =
-+ VC5_HVS_SET_GAMMA_ENTRY(i << 8, i << 12, 1 << 8);
-+ vc4_crtc->pwl_a[i] =
-+ VC5_HVS_SET_GAMMA_ENTRY(i << 8, i << 12, 1 << 8);
-+ }
- }
-
- return 0;
-diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
-index 7da22fe3a6cc..71a07c838c35 100644
---- a/drivers/gpu/drm/vc4/vc4_drv.h
-+++ b/drivers/gpu/drm/vc4/vc4_drv.h
-@@ -20,6 +20,7 @@
- #include
-
- #include "uapi/drm/vc4_drm.h"
-+#include "vc4_regs.h"
-
- struct drm_device;
- struct drm_gem_object;
-@@ -481,6 +482,17 @@ struct vc4_pv_data {
- enum vc4_encoder_type encoder_types[4];
- };
-
-+struct vc5_gamma_entry {
-+ u32 x_c_terms;
-+ u32 grad_term;
-+};
-+
-+#define VC5_HVS_SET_GAMMA_ENTRY(x, c, g) (struct vc5_gamma_entry){ \
-+ .x_c_terms = VC4_SET_FIELD((x), SCALER5_DSPGAMMA_OFF_X) | \
-+ VC4_SET_FIELD((c), SCALER5_DSPGAMMA_OFF_C), \
-+ .grad_term = (g) \
-+}
-+
- struct vc4_crtc {
- struct drm_crtc base;
- struct platform_device *pdev;
-@@ -490,9 +502,19 @@ struct vc4_crtc {
- /* Timestamp at start of vblank irq - unaffected by lock delays. */
- ktime_t t_vblank;
-
-- u8 lut_r[256];
-- u8 lut_g[256];
-- u8 lut_b[256];
-+ union {
-+ struct { /* VC4 gamma LUT */
-+ u8 lut_r[256];
-+ u8 lut_g[256];
-+ u8 lut_b[256];
-+ };
-+ struct { /* VC5 gamma PWL entries */
-+ struct vc5_gamma_entry pwl_r[SCALER5_DSPGAMMA_NUM_POINTS];
-+ struct vc5_gamma_entry pwl_g[SCALER5_DSPGAMMA_NUM_POINTS];
-+ struct vc5_gamma_entry pwl_b[SCALER5_DSPGAMMA_NUM_POINTS];
-+ struct vc5_gamma_entry pwl_a[SCALER5_DSPGAMMA_NUM_POINTS];
-+ };
-+ };
-
- struct drm_pending_vblank_event *event;
-
-diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c
-index 47990ecbfc4d..303f1341db46 100644
---- a/drivers/gpu/drm/vc4/vc4_hvs.c
-+++ b/drivers/gpu/drm/vc4/vc4_hvs.c
-@@ -241,7 +241,8 @@ static void vc4_hvs_lut_load(struct vc4_hvs *hvs,
- static void vc4_hvs_update_gamma_lut(struct vc4_hvs *hvs,
- struct vc4_crtc *vc4_crtc)
- {
-- struct drm_crtc_state *crtc_state = vc4_crtc->base.state;
-+ struct drm_crtc *crtc = &vc4_crtc->base;
-+ struct drm_crtc_state *crtc_state = crtc->state;
- struct drm_color_lut *lut = crtc_state->gamma_lut->data;
- u32 length = drm_color_lut_size(crtc_state->gamma_lut);
- u32 i;
-@@ -255,6 +256,81 @@ static void vc4_hvs_update_gamma_lut(struct vc4_hvs *hvs,
- vc4_hvs_lut_load(hvs, vc4_crtc);
- }
-
-+static void vc5_hvs_write_gamma_entry(struct vc4_hvs *hvs,
-+ u32 offset,
-+ struct vc5_gamma_entry *gamma)
-+{
-+ HVS_WRITE(offset, gamma->x_c_terms);
-+ HVS_WRITE(offset + 4, gamma->grad_term);
-+}
-+
-+static void vc5_hvs_lut_load(struct vc4_hvs *hvs,
-+ struct vc4_crtc *vc4_crtc)
-+{
-+ struct drm_crtc *crtc = &vc4_crtc->base;
-+ struct drm_crtc_state *crtc_state = crtc->state;
-+ struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc_state);
-+ u32 i;
-+ u32 offset = SCALER5_DSPGAMMA_START +
-+ vc4_state->assigned_channel * SCALER5_DSPGAMMA_CHAN_OFFSET;
-+
-+ for (i = 0; i < SCALER5_DSPGAMMA_NUM_POINTS; i++, offset += 8)
-+ vc5_hvs_write_gamma_entry(hvs, offset, &vc4_crtc->pwl_r[i]);
-+ for (i = 0; i < SCALER5_DSPGAMMA_NUM_POINTS; i++, offset += 8)
-+ vc5_hvs_write_gamma_entry(hvs, offset, &vc4_crtc->pwl_g[i]);
-+ for (i = 0; i < SCALER5_DSPGAMMA_NUM_POINTS; i++, offset += 8)
-+ vc5_hvs_write_gamma_entry(hvs, offset, &vc4_crtc->pwl_b[i]);
-+
-+ if (vc4_state->assigned_channel == 2) {
-+ /* Alpha only valid on channel 2 */
-+ for (i = 0; i < SCALER5_DSPGAMMA_NUM_POINTS; i++, offset += 8)
-+ vc5_hvs_write_gamma_entry(hvs, offset, &vc4_crtc->pwl_a[i]);
-+ }
-+}
-+
-+static void vc5_hvs_update_gamma_lut(struct vc4_hvs *hvs,
-+ struct vc4_crtc *vc4_crtc)
-+{
-+ struct drm_crtc *crtc = &vc4_crtc->base;
-+ struct drm_color_lut *lut = crtc->state->gamma_lut->data;
-+ unsigned int step, i;
-+ u32 start, end;
-+
-+#define VC5_HVS_UPDATE_GAMMA_ENTRY_FROM_LUT(pwl, chan) \
-+ start = drm_color_lut_extract(lut[i * step].chan, 12); \
-+ end = drm_color_lut_extract(lut[(i + 1) * step - 1].chan, 12); \
-+ \
-+ /* Negative gradients not permitted by the hardware, so \
-+ * flatten such points out. \
-+ */ \
-+ if (end < start) \
-+ end = start; \
-+ \
-+ /* Assume 12bit pipeline. \
-+ * X evenly spread over full range (12 bit). \
-+ * C as U12.4 format. \
-+ * Gradient as U4.8 format. \
-+ */ \
-+ vc4_crtc->pwl[i] = \
-+ VC5_HVS_SET_GAMMA_ENTRY(i << 8, start << 4, \
-+ ((end - start) << 4) / (step - 1))
-+
-+ /* HVS5 has a 16 point piecewise linear function for each colour
-+ * channel (including alpha on channel 2) on each display channel.
-+ *
-+ * Currently take a crude subsample of the gamma LUT, but this could
-+ * be improved to implement curve fitting.
-+ */
-+ step = crtc->gamma_size / SCALER5_DSPGAMMA_NUM_POINTS;
-+ for (i = 0; i < SCALER5_DSPGAMMA_NUM_POINTS; i++) {
-+ VC5_HVS_UPDATE_GAMMA_ENTRY_FROM_LUT(pwl_r, red);
-+ VC5_HVS_UPDATE_GAMMA_ENTRY_FROM_LUT(pwl_g, green);
-+ VC5_HVS_UPDATE_GAMMA_ENTRY_FROM_LUT(pwl_b, blue);
-+ }
-+
-+ vc5_hvs_lut_load(hvs, vc4_crtc);
-+}
-+
- u8 vc4_hvs_get_fifo_frame_count(struct vc4_hvs *hvs, unsigned int fifo)
- {
- struct drm_device *drm = &hvs->vc4->base;
-@@ -398,7 +474,10 @@ static int vc4_hvs_init_channel(struct vc4_hvs *hvs, struct drm_crtc *crtc,
- /* Reload the LUT, since the SRAMs would have been disabled if
- * all CRTCs had SCALER_DISPBKGND_GAMMA unset at once.
- */
-- vc4_hvs_lut_load(hvs, vc4_crtc);
-+ if (!vc4->is_vc5)
-+ vc4_hvs_lut_load(hvs, vc4_crtc);
-+ else
-+ vc5_hvs_lut_load(hvs, vc4_crtc);
-
- drm_dev_exit(idx);
-
-@@ -628,7 +707,11 @@ void vc4_hvs_atomic_flush(struct drm_crtc *crtc,
- u32 dispbkgndx = HVS_READ(SCALER_DISPBKGNDX(channel));
-
- if (crtc->state->gamma_lut) {
-- vc4_hvs_update_gamma_lut(hvs, vc4_crtc);
-+ if (!vc4->is_vc5)
-+ vc4_hvs_update_gamma_lut(hvs, vc4_crtc);
-+ else
-+ vc5_hvs_update_gamma_lut(hvs, vc4_crtc);
-+
- dispbkgndx |= SCALER_DISPBKGND_GAMMA;
- } else {
- /* Unsetting DISPBKGND_GAMMA skips the gamma lut step
-diff --git a/drivers/gpu/drm/vc4/vc4_regs.h b/drivers/gpu/drm/vc4/vc4_regs.h
-index 1256f0877ff6..e162d3f3bd3c 100644
---- a/drivers/gpu/drm/vc4/vc4_regs.h
-+++ b/drivers/gpu/drm/vc4/vc4_regs.h
-@@ -512,6 +512,28 @@
- #define SCALER_DLIST_START 0x00002000
- #define SCALER_DLIST_SIZE 0x00004000
-
-+/* Gamma PWL for each channel. 16 points for each of 4 colour channels (alpha
-+ * only on channel 2). 8 bytes per entry, offsets first, then gradient:
-+ * Y = GRAD * X + C
-+ *
-+ * Values for X and C are left justified, and vary depending on the width of
-+ * the HVS channel:
-+ * 8-bit pipeline: X uses [31:24], C is U8.8 format, and GRAD is U4.8.
-+ * 12-bit pipeline: X uses [31:20], C is U12.4 format, and GRAD is U4.8.
-+ *
-+ * The 3 HVS channels start at 0x400 offsets (ie chan 1 starts at 0x2400, and
-+ * chan 2 at 0x2800).
-+ */
-+#define SCALER5_DSPGAMMA_NUM_POINTS 16
-+#define SCALER5_DSPGAMMA_START 0x00002000
-+#define SCALER5_DSPGAMMA_CHAN_OFFSET 0x400
-+# define SCALER5_DSPGAMMA_OFF_X_MASK VC4_MASK(31, 20)
-+# define SCALER5_DSPGAMMA_OFF_X_SHIFT 20
-+# define SCALER5_DSPGAMMA_OFF_C_MASK VC4_MASK(15, 0)
-+# define SCALER5_DSPGAMMA_OFF_C_SHIFT 0
-+# define SCALER5_DSPGAMMA_GRAD_MASK VC4_MASK(11, 0)
-+# define SCALER5_DSPGAMMA_GRAD_SHIFT 0
-+
- #define SCALER5_DLIST_START 0x00004000
-
- # define VC4_HDMI_SW_RESET_FORMAT_DETECT BIT(1)
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Dave Stevenson
-Date: Wed, 28 Apr 2021 12:32:10 +0200
-Subject: [PATCH 013/784] drm/vc4: Add debugfs node that dumps the vc5 gamma
- PWL entries
-
-This helps with debugging the conversion from a 256 point gamma LUT to
-16 point PWL entries as used by the BCM2711.
-
-Co-developed-by: Juerg Haefliger
-Signed-off-by: Juerg Haefliger
-Signed-off-by: Dave Stevenson
-Signed-off-by: Maxime Ripard
----
- drivers/gpu/drm/vc4/vc4_hvs.c | 85 ++++++++++++++++++++++++++++++++++-
- 1 file changed, 84 insertions(+), 1 deletion(-)
-
-diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c
-index 303f1341db46..5374502bce37 100644
---- a/drivers/gpu/drm/vc4/vc4_hvs.c
-+++ b/drivers/gpu/drm/vc4/vc4_hvs.c
-@@ -141,6 +141,85 @@ static int vc4_hvs_debugfs_dlist(struct seq_file *m, void *data)
- return 0;
- }
-
-+static int vc5_hvs_debugfs_gamma(struct seq_file *m, void *data)
-+{
-+ struct drm_info_node *node = m->private;
-+ struct drm_device *dev = node->minor->dev;
-+ struct vc4_dev *vc4 = to_vc4_dev(dev);
-+ struct vc4_hvs *hvs = vc4->hvs;
-+ struct drm_printer p = drm_seq_file_printer(m);
-+ unsigned int i, chan;
-+ u32 dispstat, dispbkgndx;
-+
-+ for (chan = 0; chan < SCALER_CHANNELS_COUNT; chan++) {
-+ u32 x_c, grad;
-+ u32 offset = SCALER5_DSPGAMMA_START +
-+ chan * SCALER5_DSPGAMMA_CHAN_OFFSET;
-+
-+ dispstat = VC4_GET_FIELD(HVS_READ(SCALER_DISPSTATX(chan)),
-+ SCALER_DISPSTATX_MODE);
-+ if (dispstat == SCALER_DISPSTATX_MODE_DISABLED ||
-+ dispstat == SCALER_DISPSTATX_MODE_EOF) {
-+ drm_printf(&p, "HVS channel %u: Channel disabled\n", chan);
-+ continue;
-+ }
-+
-+ dispbkgndx = HVS_READ(SCALER_DISPBKGNDX(chan));
-+ if (!(dispbkgndx & SCALER_DISPBKGND_GAMMA)) {
-+ drm_printf(&p, "HVS channel %u: Gamma disabled\n", chan);
-+ continue;
-+ }
-+
-+ drm_printf(&p, "HVS channel %u:\n", chan);
-+ drm_printf(&p, " red:\n");
-+ for (i = 0; i < SCALER5_DSPGAMMA_NUM_POINTS; i++, offset += 8) {
-+ x_c = HVS_READ(offset);
-+ grad = HVS_READ(offset + 4);
-+ drm_printf(&p, " %08x %08x - x %u, c %u, grad %u\n",
-+ x_c, grad,
-+ VC4_GET_FIELD(x_c, SCALER5_DSPGAMMA_OFF_X),
-+ VC4_GET_FIELD(x_c, SCALER5_DSPGAMMA_OFF_C),
-+ grad);
-+ }
-+ drm_printf(&p, " green:\n");
-+ for (i = 0; i < SCALER5_DSPGAMMA_NUM_POINTS; i++, offset += 8) {
-+ x_c = HVS_READ(offset);
-+ grad = HVS_READ(offset + 4);
-+ drm_printf(&p, " %08x %08x - x %u, c %u, grad %u\n",
-+ x_c, grad,
-+ VC4_GET_FIELD(x_c, SCALER5_DSPGAMMA_OFF_X),
-+ VC4_GET_FIELD(x_c, SCALER5_DSPGAMMA_OFF_C),
-+ grad);
-+ }
-+ drm_printf(&p, " blue:\n");
-+ for (i = 0; i < SCALER5_DSPGAMMA_NUM_POINTS; i++, offset += 8) {
-+ x_c = HVS_READ(offset);
-+ grad = HVS_READ(offset + 4);
-+ drm_printf(&p, " %08x %08x - x %u, c %u, grad %u\n",
-+ x_c, grad,
-+ VC4_GET_FIELD(x_c, SCALER5_DSPGAMMA_OFF_X),
-+ VC4_GET_FIELD(x_c, SCALER5_DSPGAMMA_OFF_C),
-+ grad);
-+ }
-+
-+ /* Alpha only valid on channel 2 */
-+ if (chan != 2)
-+ continue;
-+
-+ drm_printf(&p, " alpha:\n");
-+ for (i = 0; i < SCALER5_DSPGAMMA_NUM_POINTS; i++, offset += 8) {
-+ x_c = HVS_READ(offset);
-+ grad = HVS_READ(offset + 4);
-+ drm_printf(&p, " %08x %08x - x %u, c %u, grad %u\n",
-+ x_c, grad,
-+ VC4_GET_FIELD(x_c, SCALER5_DSPGAMMA_OFF_X),
-+ VC4_GET_FIELD(x_c, SCALER5_DSPGAMMA_OFF_C),
-+ grad);
-+ }
-+ }
-+ return 0;
-+}
-+
- /* The filter kernel is composed of dwords each containing 3 9-bit
- * signed integers packed next to each other.
- */
-@@ -833,11 +912,15 @@ int vc4_hvs_debugfs_init(struct drm_minor *minor)
- if (!vc4->hvs)
- return -ENODEV;
-
-- if (!vc4->is_vc5)
-+ if (!vc4->is_vc5) {
- debugfs_create_bool("hvs_load_tracker", S_IRUGO | S_IWUSR,
- minor->debugfs_root,
- &vc4->load_tracker_enabled);
-
-+ vc4_debugfs_add_file(minor, "hvs_gamma", vc5_hvs_debugfs_gamma,
-+ NULL);
-+ }
-+
- ret = vc4_debugfs_add_file(minor, "hvs_dlists",
- vc4_hvs_debugfs_dlist, NULL);
- if (ret)
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Maxime Ripard
-Date: Mon, 14 Jun 2021 15:28:30 +0200
-Subject: [PATCH 014/784] drm/vc4: hvs: Force modeset on gamma lut change
-
-The HVS Gamma block can only be updated when idle, so we need to disable
-the HVS channel when the gamma property is set in an atomic commit.
-
-Since the pixelvalve cannot have its assigned channel halted without
-stalling unless it's disabled as well, in our case that means forcing a
-full disable / enable cycle on the pipeline.
-
-Signed-off-by: Maxime Ripard
----
- drivers/gpu/drm/vc4/vc4_crtc.c | 17 +++++++++++++++++
- drivers/gpu/drm/vc4/vc4_drv.h | 3 +++
- drivers/gpu/drm/vc4/vc4_hvs.c | 32 +++++++++++++++++++++++++++++++-
- 3 files changed, 51 insertions(+), 1 deletion(-)
-
-diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
-index 1e22d13768a0..187508545053 100644
---- a/drivers/gpu/drm/vc4/vc4_crtc.c
-+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
-@@ -293,6 +293,23 @@ struct drm_encoder *vc4_get_crtc_encoder(struct drm_crtc *crtc,
- return NULL;
- }
-
-+#define drm_for_each_connector_mask(connector, dev, connector_mask) \
-+ list_for_each_entry((connector), &(dev)->mode_config.connector_list, head) \
-+ for_each_if ((connector_mask) & drm_connector_mask(connector))
-+
-+struct drm_connector *vc4_get_crtc_connector(struct drm_crtc *crtc,
-+ struct drm_crtc_state *state)
-+{
-+ struct drm_connector *connector;
-+
-+ WARN_ON(hweight32(state->connector_mask) > 1);
-+
-+ drm_for_each_connector_mask(connector, crtc->dev, state->connector_mask)
-+ return connector;
-+
-+ return NULL;
-+}
-+
- static void vc4_crtc_pixelvalve_reset(struct drm_crtc *crtc)
- {
- struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
-diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
-index 71a07c838c35..d54182f995ef 100644
---- a/drivers/gpu/drm/vc4/vc4_drv.h
-+++ b/drivers/gpu/drm/vc4/vc4_drv.h
-@@ -568,6 +568,9 @@ vc4_crtc_to_vc4_pv_data(const struct vc4_crtc *crtc)
- return container_of(data, struct vc4_pv_data, base);
- }
-
-+struct drm_connector *vc4_get_crtc_connector(struct drm_crtc *crtc,
-+ struct drm_crtc_state *state);
-+
- struct drm_encoder *vc4_get_crtc_encoder(struct drm_crtc *crtc,
- struct drm_crtc_state *state);
-
-diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c
-index 5374502bce37..950d719a126b 100644
---- a/drivers/gpu/drm/vc4/vc4_hvs.c
-+++ b/drivers/gpu/drm/vc4/vc4_hvs.c
-@@ -594,6 +594,36 @@ void vc4_hvs_stop_channel(struct vc4_hvs *hvs, unsigned int chan)
- drm_dev_exit(idx);
- }
-
-+static int vc4_hvs_gamma_check(struct drm_crtc *crtc,
-+ struct drm_atomic_state *state)
-+{
-+ struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
-+ struct drm_connector_state *conn_state;
-+ struct drm_connector *connector;
-+ struct drm_device *dev = crtc->dev;
-+ struct vc4_dev *vc4 = to_vc4_dev(dev);
-+
-+ if (!vc4->is_vc5)
-+ return 0;
-+
-+ if (!crtc_state->color_mgmt_changed)
-+ return 0;
-+
-+ connector = vc4_get_crtc_connector(crtc, crtc_state);
-+ if (!connector)
-+ return -EINVAL;
-+
-+ if (!(connector->connector_type == DRM_MODE_CONNECTOR_HDMIA))
-+ return 0;
-+
-+ conn_state = drm_atomic_get_connector_state(state, connector);
-+ if (!conn_state)
-+ return -EINVAL;
-+
-+ crtc_state->mode_changed = true;
-+ return 0;
-+}
-+
- int vc4_hvs_atomic_check(struct drm_crtc *crtc, struct drm_atomic_state *state)
- {
- struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
-@@ -624,7 +654,7 @@ int vc4_hvs_atomic_check(struct drm_crtc *crtc, struct drm_atomic_state *state)
- if (ret)
- return ret;
-
-- return 0;
-+ return vc4_hvs_gamma_check(crtc, state);
- }
-
- static void vc4_hvs_install_dlist(struct drm_crtc *crtc)
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Mateusz Kwiatkowski
-Date: Thu, 15 Jul 2021 01:08:08 +0200
-Subject: [PATCH 015/784] drm/vc4: Relax VEC modeline requirements and add
- progressive mode support
-
-Make vc4_vec_encoder_atomic_check() accept arbitrary modelines, as long
-as they result in somewhat sane output from the VEC. The bounds have
-been determined empirically. Additionally, add support for the
-progressive 262-line and 312-line modes.
-
-Signed-off-by: Mateusz Kwiatkowski
----
- drivers/gpu/drm/vc4/vc4_crtc.c | 1 +
- drivers/gpu/drm/vc4/vc4_vec.c | 94 ++++++++++++++++++++++++++++++----
- 2 files changed, 85 insertions(+), 10 deletions(-)
-
-diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
-index 187508545053..fc4e2e658e6d 100644
---- a/drivers/gpu/drm/vc4/vc4_crtc.c
-+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
-@@ -422,6 +422,7 @@ static void vc4_crtc_config_pv(struct drm_crtc *crtc, struct drm_encoder *encode
- CRTC_WRITE(PV_V_CONTROL,
- PV_VCONTROL_CONTINUOUS |
- (is_dsi ? PV_VCONTROL_DSI : 0));
-+ CRTC_WRITE(PV_VSYNCD_EVEN, 0);
- }
-
- CRTC_WRITE(PV_VERTA,
-diff --git a/drivers/gpu/drm/vc4/vc4_vec.c b/drivers/gpu/drm/vc4/vc4_vec.c
-index c613f930f079..e32a7b45b2b9 100644
---- a/drivers/gpu/drm/vc4/vc4_vec.c
-+++ b/drivers/gpu/drm/vc4/vc4_vec.c
-@@ -400,18 +400,11 @@ static int vc4_vec_connector_atomic_check(struct drm_connector *conn,
- struct drm_connector_state *new_state =
- drm_atomic_get_new_connector_state(state, conn);
-
-- const struct vc4_vec_tv_mode *vec_mode =
-- &vc4_vec_tv_modes[new_state->tv.mode];
--
-- if (new_state->crtc) {
-+ if (new_state->crtc && old_state->tv.mode != new_state->tv.mode) {
- struct drm_crtc_state *crtc_state =
- drm_atomic_get_new_crtc_state(state, new_state->crtc);
-
-- if (!drm_mode_equal(vec_mode->mode, &crtc_state->mode))
-- return -EINVAL;
--
-- if (old_state->tv.mode != new_state->tv.mode)
-- crtc_state->mode_changed = true;
-+ crtc_state->mode_changed = true;
- }
-
- return 0;
-@@ -546,7 +539,10 @@ static void vc4_vec_encoder_enable(struct drm_encoder *encoder,
- VEC_WRITE(VEC_CLMP0_START, 0xac);
- VEC_WRITE(VEC_CLMP0_END, 0xec);
- VEC_WRITE(VEC_CONFIG2,
-- VEC_CONFIG2_UV_DIG_DIS | VEC_CONFIG2_RGB_DIG_DIS);
-+ VEC_CONFIG2_UV_DIG_DIS |
-+ VEC_CONFIG2_RGB_DIG_DIS |
-+ ((encoder->crtc->state->adjusted_mode.flags &
-+ DRM_MODE_FLAG_INTERLACE) ? 0 : VEC_CONFIG2_PROG_SCAN));
- VEC_WRITE(VEC_CONFIG3, VEC_CONFIG3_HORIZ_LEN_STD);
- VEC_WRITE(VEC_DAC_CONFIG, vec->variant->dac_config);
-
-@@ -575,8 +571,86 @@ static void vc4_vec_encoder_enable(struct drm_encoder *encoder,
- err_dev_exit:
- drm_dev_exit(idx);
- }
-+static int vc4_vec_encoder_atomic_check(struct drm_encoder *encoder,
-+ struct drm_crtc_state *crtc_state,
-+ struct drm_connector_state *conn_state)
-+{
-+ const struct drm_display_mode *reference_mode =
-+ vc4_vec_tv_modes[conn_state->tv.mode].mode;
-+
-+ if (crtc_state->adjusted_mode.crtc_clock != reference_mode->clock ||
-+ crtc_state->adjusted_mode.crtc_htotal != reference_mode->htotal ||
-+ crtc_state->adjusted_mode.crtc_hdisplay % 4 != 0 ||
-+ crtc_state->adjusted_mode.crtc_hsync_end -
-+ crtc_state->adjusted_mode.crtc_hsync_start < 1)
-+ return -EINVAL;
-+
-+ switch (reference_mode->vtotal) {
-+ case 525:
-+ if (crtc_state->adjusted_mode.crtc_vdisplay < 1 ||
-+ crtc_state->adjusted_mode.crtc_vdisplay > 253 ||
-+ crtc_state->adjusted_mode.crtc_vsync_start -
-+ crtc_state->adjusted_mode.crtc_vdisplay < 1 ||
-+ crtc_state->adjusted_mode.crtc_vsync_end -
-+ crtc_state->adjusted_mode.crtc_vsync_start != 3 ||
-+ crtc_state->adjusted_mode.crtc_vtotal -
-+ crtc_state->adjusted_mode.crtc_vsync_end < 4 ||
-+ crtc_state->adjusted_mode.crtc_vtotal > 262)
-+ return -EINVAL;
-+
-+ if ((crtc_state->adjusted_mode.flags &
-+ DRM_MODE_FLAG_INTERLACE) &&
-+ (crtc_state->adjusted_mode.vdisplay % 2 != 0 ||
-+ crtc_state->adjusted_mode.vsync_start % 2 != 1 ||
-+ crtc_state->adjusted_mode.vsync_end % 2 != 1 ||
-+ crtc_state->adjusted_mode.vtotal % 2 != 1))
-+ return -EINVAL;
-+
-+ /* progressive mode is hard-wired to 262 total lines */
-+ if (!(crtc_state->adjusted_mode.flags &
-+ DRM_MODE_FLAG_INTERLACE) &&
-+ crtc_state->adjusted_mode.crtc_vtotal != 262)
-+ return -EINVAL;
-+
-+ break;
-+
-+ case 625:
-+ if (crtc_state->adjusted_mode.crtc_vdisplay < 1 ||
-+ crtc_state->adjusted_mode.crtc_vdisplay > 305 ||
-+ crtc_state->adjusted_mode.crtc_vsync_start -
-+ crtc_state->adjusted_mode.crtc_vdisplay < 1 ||
-+ crtc_state->adjusted_mode.crtc_vsync_end -
-+ crtc_state->adjusted_mode.crtc_vsync_start != 3 ||
-+ crtc_state->adjusted_mode.crtc_vtotal -
-+ crtc_state->adjusted_mode.crtc_vsync_end < 2 ||
-+ crtc_state->adjusted_mode.crtc_vtotal > 312)
-+ return -EINVAL;
-+
-+ if ((crtc_state->adjusted_mode.flags &
-+ DRM_MODE_FLAG_INTERLACE) &&
-+ (crtc_state->adjusted_mode.vdisplay % 2 != 0 ||
-+ crtc_state->adjusted_mode.vsync_start % 2 != 0 ||
-+ crtc_state->adjusted_mode.vsync_end % 2 != 0 ||
-+ crtc_state->adjusted_mode.vtotal % 2 != 1))
-+ return -EINVAL;
-+
-+ /* progressive mode is hard-wired to 312 total lines */
-+ if (!(crtc_state->adjusted_mode.flags &
-+ DRM_MODE_FLAG_INTERLACE) &&
-+ crtc_state->adjusted_mode.crtc_vtotal != 312)
-+ return -EINVAL;
-+
-+ break;
-+
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-
- static const struct drm_encoder_helper_funcs vc4_vec_encoder_helper_funcs = {
-+ .atomic_check = vc4_vec_encoder_atomic_check,
- .atomic_disable = vc4_vec_encoder_disable,
- .atomic_enable = vc4_vec_encoder_enable,
- };
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Mateusz Kwiatkowski
-Date: Thu, 15 Jul 2021 01:08:11 +0200
-Subject: [PATCH 016/784] drm/vc4: Make VEC progressive modes readily
- accessible
-
-Add predefined modelines for the 240p (NTSC) and 288p (PAL) progressive
-modes, and report them through vc4_vec_connector_get_modes().
-
-Signed-off-by: Mateusz Kwiatkowski
----
- drivers/gpu/drm/vc4/vc4_vec.c | 73 ++++++++++++++++++++++++++---------
- 1 file changed, 55 insertions(+), 18 deletions(-)
-
-diff --git a/drivers/gpu/drm/vc4/vc4_vec.c b/drivers/gpu/drm/vc4/vc4_vec.c
-index e32a7b45b2b9..32ca0b3d1549 100644
---- a/drivers/gpu/drm/vc4/vc4_vec.c
-+++ b/drivers/gpu/drm/vc4/vc4_vec.c
-@@ -228,7 +228,8 @@ enum vc4_vec_tv_mode_id {
- };
-
- struct vc4_vec_tv_mode {
-- const struct drm_display_mode *mode;
-+ const struct drm_display_mode *interlaced_mode;
-+ const struct drm_display_mode *progressive_mode;
- u32 config0;
- u32 config1;
- u32 custom_freq;
-@@ -262,61 +263,81 @@ static const struct debugfs_reg32 vec_regs[] = {
- };
-
- static const struct drm_display_mode drm_mode_480i = {
-- DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 13500,
-+ DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 13500,
- 720, 720 + 14, 720 + 14 + 64, 720 + 14 + 64 + 60, 0,
- 480, 480 + 7, 480 + 7 + 6, 525, 0,
- DRM_MODE_FLAG_INTERLACE)
- };
-
-+static const struct drm_display_mode drm_mode_240p = {
-+ DRM_MODE("720x240", DRM_MODE_TYPE_DRIVER, 13500,
-+ 720, 720 + 14, 720 + 14 + 64, 720 + 14 + 64 + 60, 0,
-+ 240, 240 + 3, 240 + 3 + 3, 262, 0, 0)
-+};
-+
- static const struct drm_display_mode drm_mode_576i = {
-- DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 13500,
-+ DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 13500,
- 720, 720 + 20, 720 + 20 + 64, 720 + 20 + 64 + 60, 0,
- 576, 576 + 4, 576 + 4 + 6, 625, 0,
- DRM_MODE_FLAG_INTERLACE)
- };
-
-+static const struct drm_display_mode drm_mode_288p = {
-+ DRM_MODE("720x288", DRM_MODE_TYPE_DRIVER, 13500,
-+ 720, 720 + 20, 720 + 20 + 64, 720 + 20 + 64 + 60, 0,
-+ 288, 288 + 2, 288 + 2 + 3, 312, 0, 0)
-+};
-+
- static const struct vc4_vec_tv_mode vc4_vec_tv_modes[] = {
- [VC4_VEC_TV_MODE_NTSC] = {
-- .mode = &drm_mode_480i,
-+ .interlaced_mode = &drm_mode_480i,
-+ .progressive_mode = &drm_mode_240p,
- .config0 = VEC_CONFIG0_NTSC_STD | VEC_CONFIG0_PDEN,
- .config1 = VEC_CONFIG1_C_CVBS_CVBS,
- },
- [VC4_VEC_TV_MODE_NTSC_J] = {
-- .mode = &drm_mode_480i,
-+ .interlaced_mode = &drm_mode_480i,
-+ .progressive_mode = &drm_mode_240p,
- .config0 = VEC_CONFIG0_NTSC_STD,
- .config1 = VEC_CONFIG1_C_CVBS_CVBS,
- },
- [VC4_VEC_TV_MODE_NTSC_443] = {
- /* NTSC with PAL chroma frequency */
-- .mode = &drm_mode_480i,
-+ .interlaced_mode = &drm_mode_480i,
-+ .progressive_mode = &drm_mode_240p,
- .config0 = VEC_CONFIG0_NTSC_STD,
- .config1 = VEC_CONFIG1_C_CVBS_CVBS | VEC_CONFIG1_CUSTOM_FREQ,
- .custom_freq = 0x2a098acb,
- },
- [VC4_VEC_TV_MODE_PAL] = {
-- .mode = &drm_mode_576i,
-+ .interlaced_mode = &drm_mode_576i,
-+ .progressive_mode = &drm_mode_288p,
- .config0 = VEC_CONFIG0_PAL_BDGHI_STD,
- .config1 = VEC_CONFIG1_C_CVBS_CVBS,
- },
- [VC4_VEC_TV_MODE_PAL_M] = {
-- .mode = &drm_mode_480i,
-+ .interlaced_mode = &drm_mode_480i,
-+ .progressive_mode = &drm_mode_240p,
- .config0 = VEC_CONFIG0_PAL_M_STD,
- .config1 = VEC_CONFIG1_C_CVBS_CVBS,
- },
- [VC4_VEC_TV_MODE_PAL_N] = {
-- .mode = &drm_mode_576i,
-+ .interlaced_mode = &drm_mode_576i,
-+ .progressive_mode = &drm_mode_288p,
- .config0 = VEC_CONFIG0_PAL_N_STD,
- .config1 = VEC_CONFIG1_C_CVBS_CVBS,
- },
- [VC4_VEC_TV_MODE_PAL60] = {
- /* PAL-M with chroma frequency of regular PAL */
-- .mode = &drm_mode_480i,
-+ .interlaced_mode = &drm_mode_480i,
-+ .progressive_mode = &drm_mode_240p,
- .config0 = VEC_CONFIG0_PAL_M_STD,
- .config1 = VEC_CONFIG1_C_CVBS_CVBS | VEC_CONFIG1_CUSTOM_FREQ,
- .custom_freq = 0x2a098acb,
- },
- [VC4_VEC_TV_MODE_SECAM] = {
-- .mode = &drm_mode_576i,
-+ .interlaced_mode = &drm_mode_576i,
-+ .progressive_mode = &drm_mode_288p,
- .config0 = VEC_CONFIG0_SECAM_STD,
- .config1 = VEC_CONFIG1_C_CVBS_CVBS,
- .custom_freq = 0x29c71c72,
-@@ -370,16 +391,32 @@ vc4_vec_connector_detect(struct drm_connector *connector, bool force)
- static int vc4_vec_connector_get_modes(struct drm_connector *connector)
- {
- struct drm_connector_state *state = connector->state;
-- struct drm_display_mode *mode;
--
-- mode = drm_mode_duplicate(connector->dev,
-- vc4_vec_tv_modes[state->tv.mode].mode);
-- if (!mode) {
-+ struct drm_display_mode *interlaced_mode, *progressive_mode;
-+
-+ interlaced_mode =
-+ drm_mode_duplicate(connector->dev,
-+ vc4_vec_tv_modes[state->tv.mode].interlaced_mode);
-+ progressive_mode =
-+ drm_mode_duplicate(connector->dev,
-+ vc4_vec_tv_modes[state->tv.mode].progressive_mode);
-+ if (!interlaced_mode || !progressive_mode) {
- DRM_ERROR("Failed to create a new display mode\n");
-+ drm_mode_destroy(connector->dev, interlaced_mode);
-+ drm_mode_destroy(connector->dev, progressive_mode);
- return -ENOMEM;
- }
-
-- drm_mode_probed_add(connector, mode);
-+ if (connector->cmdline_mode.specified &&
-+ connector->cmdline_mode.refresh_specified &&
-+ !connector->cmdline_mode.interlace)
-+ /* progressive mode set at boot, let's make it preferred */
-+ progressive_mode->type |= DRM_MODE_TYPE_PREFERRED;
-+ else
-+ /* otherwise, interlaced mode is preferred */
-+ interlaced_mode->type |= DRM_MODE_TYPE_PREFERRED;
-+
-+ drm_mode_probed_add(connector, interlaced_mode);
-+ drm_mode_probed_add(connector, progressive_mode);
-
- return 1;
- }
-@@ -576,7 +613,7 @@ static int vc4_vec_encoder_atomic_check(struct drm_encoder *encoder,
- struct drm_connector_state *conn_state)
- {
- const struct drm_display_mode *reference_mode =
-- vc4_vec_tv_modes[conn_state->tv.mode].mode;
-+ vc4_vec_tv_modes[conn_state->tv.mode].interlaced_mode;
-
- if (crtc_state->adjusted_mode.crtc_clock != reference_mode->clock ||
- crtc_state->adjusted_mode.crtc_htotal != reference_mode->htotal ||
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Dave Stevenson
-Date: Tue, 2 Nov 2021 16:01:36 +0000
-Subject: [PATCH 017/784] drm: Check whether the gamma lut has changed before
- updating
-
-drm_crtc_legacy_gamma_set updates the gamma_lut blob unconditionally,
-which leads to unnecessary reprogramming of hardware.
-
-Check whether the blob contents has actually changed before
-signalling that it has been updated.
-
-Signed-off-by: Dave Stevenson
----
- drivers/gpu/drm/drm_color_mgmt.c | 4 +++-
- 1 file changed, 3 insertions(+), 1 deletion(-)
-
-diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c
-index d021497841b8..996f12438016 100644
---- a/drivers/gpu/drm/drm_color_mgmt.c
-+++ b/drivers/gpu/drm/drm_color_mgmt.c
-@@ -330,7 +330,9 @@ static int drm_crtc_legacy_gamma_set(struct drm_crtc *crtc,
- replaced = drm_property_replace_blob(&crtc_state->degamma_lut,
- use_gamma_lut ? NULL : blob);
- replaced |= drm_property_replace_blob(&crtc_state->ctm, NULL);
-- replaced |= drm_property_replace_blob(&crtc_state->gamma_lut,
-+ if (!crtc_state->gamma_lut || !crtc_state->gamma_lut->data ||
-+ memcmp(crtc_state->gamma_lut->data, blob_data, blob->length))
-+ replaced |= drm_property_replace_blob(&crtc_state->gamma_lut,
- use_gamma_lut ? blob : NULL);
- crtc_state->color_mgmt_changed |= replaced;
-
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Dave Stevenson
-Date: Mon, 8 Nov 2021 17:32:45 +0000
-Subject: [PATCH 018/784] drm/vc4: Enable gamma block only when required.
-
-With HVS5 the gamma block is now only reprogrammed with
-a disable/enable. Loading the table from vc4_hvs_init_channel
-(called from vc4_hvs_atomic_enable) appears to be at an
-invalid point in time and so isn't applied.
-
-Switch to enabling and disabling the gamma table instead. This
-isn't safe if the pipeline is running, but it isn't now.
-For HVS4 it is safe to enable and disable dynamically, so
-adopt that approach there too.
-
-Signed-off-by: Dave Stevenson
----
- drivers/gpu/drm/vc4/vc4_hvs.c | 22 ++++++++++++++++------
- 1 file changed, 16 insertions(+), 6 deletions(-)
-
-diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c
-index 950d719a126b..7ce6b713b020 100644
---- a/drivers/gpu/drm/vc4/vc4_hvs.c
-+++ b/drivers/gpu/drm/vc4/vc4_hvs.c
-@@ -546,8 +546,11 @@ static int vc4_hvs_init_channel(struct vc4_hvs *hvs, struct drm_crtc *crtc,
- dispbkgndx &= ~SCALER_DISPBKGND_GAMMA;
- dispbkgndx &= ~SCALER_DISPBKGND_INTERLACE;
-
-+ if (crtc->state->gamma_lut)
-+ /* Enable gamma on if required */
-+ dispbkgndx |= SCALER_DISPBKGND_GAMMA;
-+
- HVS_WRITE(SCALER_DISPBKGNDX(chan), dispbkgndx |
-- ((!vc4->is_vc5) ? SCALER_DISPBKGND_GAMMA : 0) |
- (interlace ? SCALER_DISPBKGND_INTERLACE : 0));
-
- /* Reload the LUT, since the SRAMs would have been disabled if
-@@ -816,18 +819,25 @@ void vc4_hvs_atomic_flush(struct drm_crtc *crtc,
- u32 dispbkgndx = HVS_READ(SCALER_DISPBKGNDX(channel));
-
- if (crtc->state->gamma_lut) {
-- if (!vc4->is_vc5)
-+ if (!vc4->is_vc5) {
- vc4_hvs_update_gamma_lut(hvs, vc4_crtc);
-- else
-+ dispbkgndx |= SCALER_DISPBKGND_GAMMA;
-+ } else {
- vc5_hvs_update_gamma_lut(hvs, vc4_crtc);
--
-- dispbkgndx |= SCALER_DISPBKGND_GAMMA;
-+ }
- } else {
- /* Unsetting DISPBKGND_GAMMA skips the gamma lut step
- * in hardware, which is the same as a linear lut that
- * DRM expects us to use in absence of a user lut.
-+ *
-+ * Do NOT change state dynamically for hvs5 as it
-+ * inserts a delay in the pipeline that will cause
-+ * stalls if enabled/disabled whilst running. The other
-+ * should already be disabling/enabling the pipeline
-+ * when gamma changes.
- */
-- dispbkgndx &= ~SCALER_DISPBKGND_GAMMA;
-+ if (!vc4->is_vc5)
-+ dispbkgndx &= ~SCALER_DISPBKGND_GAMMA;
- }
- HVS_WRITE(SCALER_DISPBKGNDX(channel), dispbkgndx);
- }
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Dave Stevenson
-Date: Mon, 8 Nov 2021 18:25:49 +0000
-Subject: [PATCH 019/784] drm/vc4: Only add gamma properties once.
-
-Two calls were made to drm_crtc_enable_color_mgmt to add gamma
-and CTM, however they were both set to add the gamma properties,
-so they ended up added twice.
-
-Fixes: 766cc6b1f7fc "drm/vc4: Add CTM support"
-Signed-off-by: Dave Stevenson
----
- drivers/gpu/drm/vc4/vc4_crtc.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
-index fc4e2e658e6d..7c29f67e4f73 100644
---- a/drivers/gpu/drm/vc4/vc4_crtc.c
-+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
-@@ -1358,7 +1358,7 @@ int vc4_crtc_init(struct drm_device *drm, struct vc4_crtc *vc4_crtc,
- /* We support CTM, but only for one CRTC at a time. It's therefore
- * implemented as private driver state in vc4_kms, not here.
- */
-- drm_crtc_enable_color_mgmt(crtc, 0, true, crtc->gamma_size);
-+ drm_crtc_enable_color_mgmt(crtc, 0, true, 0);
-
- /* Initialize the VC4 gamma LUTs */
- for (i = 0; i < crtc->gamma_size; i++) {
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Dave Stevenson
-Date: Wed, 10 Nov 2021 16:36:12 +0000
-Subject: [PATCH 020/784] drm/vc4: Validate the size of the gamma_lut
-
-Add a check to vc4_hvs_gamma_check to ensure a new non-empty
-gamma LUT is of the correct length before accepting it.
-
-Signed-off-by: Dave Stevenson
----
- drivers/gpu/drm/vc4/vc4_hvs.c | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
-diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c
-index 7ce6b713b020..43ba463b6790 100644
---- a/drivers/gpu/drm/vc4/vc4_hvs.c
-+++ b/drivers/gpu/drm/vc4/vc4_hvs.c
-@@ -612,6 +612,16 @@ static int vc4_hvs_gamma_check(struct drm_crtc *crtc,
- if (!crtc_state->color_mgmt_changed)
- return 0;
-
-+ if (crtc_state->gamma_lut) {
-+ unsigned int len = drm_color_lut_size(crtc_state->gamma_lut);
-+
-+ if (len != crtc->gamma_size) {
-+ DRM_DEBUG_KMS("Invalid LUT size; got %u, expected %u\n",
-+ len, crtc->gamma_size);
-+ return -EINVAL;
-+ }
-+ }
-+
- connector = vc4_get_crtc_connector(crtc, crtc_state);
- if (!connector)
- return -EINVAL;
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Dave Stevenson
-Date: Thu, 13 Jan 2022 11:30:42 +0000
-Subject: [PATCH 021/784] drm/vc4: Disable Gamma control on HVS5 due to issues
- writing the table
-
-Still under investigation, but the conditions under which the HVS
-will accept values written to the gamma PWL are not straightforward.
-
-Disable gamma on HVS5 again until it can be resolved to avoid
-gamma being enabled with an incorrect table.
-
-Signed-off-by: Dave Stevenson
----
- drivers/gpu/drm/vc4/vc4_crtc.c | 8 +-------
- 1 file changed, 1 insertion(+), 7 deletions(-)
-
-diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
-index 7c29f67e4f73..0b16fb5acd7d 100644
---- a/drivers/gpu/drm/vc4/vc4_crtc.c
-+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
-@@ -1344,15 +1344,9 @@ int vc4_crtc_init(struct drm_device *drm, struct vc4_crtc *vc4_crtc,
-
- if (!vc4->is_vc5) {
- drm_mode_crtc_set_gamma_size(crtc, ARRAY_SIZE(vc4_crtc->lut_r));
-- } else {
-- /* This is a lie for hvs5 which uses a 16 point PWL, but it
-- * allows for something smarter than just 16 linearly spaced
-- * segments. Conversion is done in vc5_hvs_update_gamma_lut.
-- */
-- drm_mode_crtc_set_gamma_size(crtc, 256);
-+ drm_crtc_enable_color_mgmt(crtc, 0, false, crtc->gamma_size);
- }
-
-- drm_crtc_enable_color_mgmt(crtc, 0, false, crtc->gamma_size);
-
- if (!vc4->is_vc5) {
- /* We support CTM, but only for one CRTC at a time. It's therefore
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Dave Stevenson
-Date: Wed, 8 Apr 2020 16:12:02 +0100
-Subject: [PATCH 022/784] drm/vc4_hdmi: Add Broadcast RGB property to allow
- override of RGB range
-
-Copy Intel's "Broadcast RGB" property semantics to add manual override
-of the HDMI pixel range for monitors that don't abide by the content
-of the AVI Infoframe.
-
-Signed-off-by: Dave Stevenson
----
- drivers/gpu/drm/vc4/vc4_hdmi.c | 104 +++++++++++++++++++++++++++++++++
- drivers/gpu/drm/vc4/vc4_hdmi.h | 15 +++++
- 2 files changed, 119 insertions(+)
-
-diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
-index ea2eaf6032ca..e9cb32d3b0d5 100644
---- a/drivers/gpu/drm/vc4/vc4_hdmi.c
-+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
-@@ -57,6 +57,14 @@
- #include "vc4_hdmi_regs.h"
- #include "vc4_regs.h"
-
-+/*
-+ * "Broadcast RGB" property.
-+ * Allows overriding of HDMI full or limited range RGB
-+ */
-+#define VC4_BROADCAST_RGB_AUTO 0
-+#define VC4_BROADCAST_RGB_FULL 1
-+#define VC4_BROADCAST_RGB_LIMITED 2
-+
- #define VC5_HDMI_HORZA_HFP_SHIFT 16
- #define VC5_HDMI_HORZA_HFP_MASK VC4_MASK(28, 16)
- #define VC5_HDMI_HORZA_VPOS BIT(15)
-@@ -155,6 +163,11 @@ static bool vc4_hdmi_is_full_range_rgb(struct vc4_hdmi *vc4_hdmi,
- {
- struct drm_display_info *display = &vc4_hdmi->connector.display_info;
-
-+ if (vc4_hdmi->broadcast_rgb == VC4_BROADCAST_RGB_LIMITED)
-+ return false;
-+ else if (vc4_hdmi->broadcast_rgb == VC4_BROADCAST_RGB_FULL)
-+ return true;
-+
- return !display->is_hdmi ||
- drm_default_rgb_quant_range(mode) == HDMI_QUANTIZATION_RANGE_FULL;
- }
-@@ -544,6 +557,65 @@ static int vc4_hdmi_connector_atomic_check(struct drm_connector *connector,
- return 0;
- }
-
-+/**
-+ * vc4_hdmi_connector_atomic_get_property - hook for
-+ * connector->atomic_get_property.
-+ * @connector: Connector to get the property for.
-+ * @state: Connector state to retrieve the property from.
-+ * @property: Property to retrieve.
-+ * @val: Return value for the property.
-+ *
-+ * Returns the atomic property value for a digital connector.
-+ */
-+int vc4_hdmi_connector_get_property(struct drm_connector *connector,
-+ const struct drm_connector_state *state,
-+ struct drm_property *property,
-+ uint64_t *val)
-+{
-+ struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector);
-+ const struct vc4_hdmi_connector_state *vc4_conn_state =
-+ const_conn_state_to_vc4_hdmi_conn_state(state);
-+
-+ if (property == vc4_hdmi->broadcast_rgb_property) {
-+ *val = vc4_conn_state->broadcast_rgb;
-+ } else {
-+ DRM_DEBUG_ATOMIC("Unknown property [PROP:%d:%s]\n",
-+ property->base.id, property->name);
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+
-+/**
-+ * vc4_hdmi_connector_atomic_set_property - hook for
-+ * connector->atomic_set_property.
-+ * @connector: Connector to set the property for.
-+ * @state: Connector state to set the property on.
-+ * @property: Property to set.
-+ * @val: New value for the property.
-+ *
-+ * Sets the atomic property value for a digital connector.
-+ */
-+int vc4_hdmi_connector_set_property(struct drm_connector *connector,
-+ struct drm_connector_state *state,
-+ struct drm_property *property,
-+ uint64_t val)
-+{
-+ struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector);
-+ struct vc4_hdmi_connector_state *vc4_conn_state =
-+ conn_state_to_vc4_hdmi_conn_state(state);
-+
-+ if (property == vc4_hdmi->broadcast_rgb_property) {
-+ vc4_conn_state->broadcast_rgb = val;
-+ return 0;
-+ }
-+
-+ DRM_DEBUG_ATOMIC("Unknown property [PROP:%d:%s]\n",
-+ property->base.id, property->name);
-+ return -EINVAL;
-+}
-+
- static void vc4_hdmi_connector_reset(struct drm_connector *connector)
- {
- struct vc4_hdmi_connector_state *old_state =
-@@ -580,6 +652,7 @@ vc4_hdmi_connector_duplicate_state(struct drm_connector *connector)
- new_state->tmds_char_rate = vc4_state->tmds_char_rate;
- new_state->output_bpc = vc4_state->output_bpc;
- new_state->output_format = vc4_state->output_format;
-+ new_state->broadcast_rgb = vc4_state->broadcast_rgb;
- __drm_atomic_helper_connector_duplicate_state(connector, &new_state->base);
-
- return &new_state->base;
-@@ -590,6 +663,8 @@ static const struct drm_connector_funcs vc4_hdmi_connector_funcs = {
- .reset = vc4_hdmi_connector_reset,
- .atomic_duplicate_state = vc4_hdmi_connector_duplicate_state,
- .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
-+ .atomic_get_property = vc4_hdmi_connector_get_property,
-+ .atomic_set_property = vc4_hdmi_connector_set_property,
- };
-
- static const struct drm_connector_helper_funcs vc4_hdmi_connector_helper_funcs = {
-@@ -598,6 +673,32 @@ static const struct drm_connector_helper_funcs vc4_hdmi_connector_helper_funcs =
- .atomic_check = vc4_hdmi_connector_atomic_check,
- };
-
-+static const struct drm_prop_enum_list broadcast_rgb_names[] = {
-+ { VC4_BROADCAST_RGB_AUTO, "Automatic" },
-+ { VC4_BROADCAST_RGB_FULL, "Full" },
-+ { VC4_BROADCAST_RGB_LIMITED, "Limited 16:235" },
-+};
-+
-+static void
-+vc4_hdmi_attach_broadcast_rgb_property(struct drm_device *dev,
-+ struct vc4_hdmi *vc4_hdmi)
-+{
-+ struct drm_property *prop = vc4_hdmi->broadcast_rgb_property;
-+
-+ if (!prop) {
-+ prop = drm_property_create_enum(dev, DRM_MODE_PROP_ENUM,
-+ "Broadcast RGB",
-+ broadcast_rgb_names,
-+ ARRAY_SIZE(broadcast_rgb_names));
-+ if (!prop)
-+ return;
-+
-+ vc4_hdmi->broadcast_rgb_property = prop;
-+ }
-+
-+ drm_object_attach_property(&vc4_hdmi->connector.base, prop, 0);
-+}
-+
- static int vc4_hdmi_connector_init(struct drm_device *dev,
- struct vc4_hdmi *vc4_hdmi)
- {
-@@ -644,6 +745,8 @@ static int vc4_hdmi_connector_init(struct drm_device *dev,
- if (vc4_hdmi->variant->supports_hdr)
- drm_connector_attach_hdr_output_metadata_property(connector);
-
-+ vc4_hdmi_attach_broadcast_rgb_property(dev, vc4_hdmi);
-+
- drm_connector_attach_encoder(connector, encoder);
-
- return 0;
-@@ -1683,6 +1786,7 @@ static void vc4_hdmi_encoder_atomic_mode_set(struct drm_encoder *encoder,
- mutex_lock(&vc4_hdmi->mutex);
- drm_mode_copy(&vc4_hdmi->saved_adjusted_mode,
- &crtc_state->adjusted_mode);
-+ vc4_hdmi->broadcast_rgb = vc4_state->broadcast_rgb;
- vc4_hdmi->output_bpc = vc4_state->output_bpc;
- vc4_hdmi->output_format = vc4_state->output_format;
- mutex_unlock(&vc4_hdmi->mutex);
-diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.h b/drivers/gpu/drm/vc4/vc4_hdmi.h
-index 1ad8e8c377e2..f57bfb13fc41 100644
---- a/drivers/gpu/drm/vc4/vc4_hdmi.h
-+++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
-@@ -129,6 +129,8 @@ struct vc4_hdmi {
-
- struct delayed_work scrambling_work;
-
-+ struct drm_property *broadcast_rgb_property;
-+
- struct i2c_adapter *ddc;
- void __iomem *hdmicore_regs;
- void __iomem *hd_regs;
-@@ -229,6 +231,12 @@ struct vc4_hdmi {
- * for use outside of KMS hooks. Protected by @mutex.
- */
- enum vc4_hdmi_output_format output_format;
-+
-+ /**
-+ * @broadcast_rgb: Copy of @vc4_connector_state.broadcast_rgb
-+ * for use outside of KMS hooks. Protected by @mutex.
-+ */
-+ int broadcast_rgb;
- };
-
- static inline struct vc4_hdmi *
-@@ -249,6 +257,7 @@ struct vc4_hdmi_connector_state {
- unsigned long long tmds_char_rate;
- unsigned int output_bpc;
- enum vc4_hdmi_output_format output_format;
-+ int broadcast_rgb;
- };
-
- static inline struct vc4_hdmi_connector_state *
-@@ -257,6 +266,12 @@ conn_state_to_vc4_hdmi_conn_state(struct drm_connector_state *conn_state)
- return container_of(conn_state, struct vc4_hdmi_connector_state, base);
- }
-
-+static inline const struct vc4_hdmi_connector_state *
-+const_conn_state_to_vc4_hdmi_conn_state(const struct drm_connector_state *conn_state)
-+{
-+ return container_of(conn_state, struct vc4_hdmi_connector_state, base);
-+}
-+
- void vc4_hdmi_phy_init(struct vc4_hdmi *vc4_hdmi,
- struct vc4_hdmi_connector_state *vc4_conn_state);
- void vc4_hdmi_phy_disable(struct vc4_hdmi *vc4_hdmi);
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Dave Stevenson
-Date: Mon, 31 Jan 2022 16:28:43 +0000
-Subject: [PATCH 023/784] drm/vc4: Add DRM 210101010 RGB formats for hvs5.
-
-HVS5 supports the 210101010 RGB[A|X] formats, but they were
-missing from the DRM to HVS mapping list, so weren't available.
-Add them in.
-
-Signed-off-by: Dave Stevenson
----
- drivers/gpu/drm/vc4/vc4_plane.c | 28 ++++++++++++++++++++++++++++
- 1 file changed, 28 insertions(+)
-
-diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
-index eb08020154f3..9ae2feb34461 100644
---- a/drivers/gpu/drm/vc4/vc4_plane.c
-+++ b/drivers/gpu/drm/vc4/vc4_plane.c
-@@ -139,6 +139,34 @@ static const struct hvs_format {
- .pixel_order = HVS_PIXEL_ORDER_XYCBCR,
- .hvs5_only = true,
- },
-+ {
-+ .drm = DRM_FORMAT_XRGB2101010,
-+ .hvs = HVS_PIXEL_FORMAT_RGBA1010102,
-+ .pixel_order = HVS_PIXEL_ORDER_ABGR,
-+ .pixel_order_hvs5 = HVS_PIXEL_ORDER_ARGB,
-+ .hvs5_only = true,
-+ },
-+ {
-+ .drm = DRM_FORMAT_ARGB2101010,
-+ .hvs = HVS_PIXEL_FORMAT_RGBA1010102,
-+ .pixel_order = HVS_PIXEL_ORDER_ABGR,
-+ .pixel_order_hvs5 = HVS_PIXEL_ORDER_ARGB,
-+ .hvs5_only = true,
-+ },
-+ {
-+ .drm = DRM_FORMAT_ABGR2101010,
-+ .hvs = HVS_PIXEL_FORMAT_RGBA1010102,
-+ .pixel_order = HVS_PIXEL_ORDER_ARGB,
-+ .pixel_order_hvs5 = HVS_PIXEL_ORDER_ABGR,
-+ .hvs5_only = true,
-+ },
-+ {
-+ .drm = DRM_FORMAT_XBGR2101010,
-+ .hvs = HVS_PIXEL_FORMAT_RGBA1010102,
-+ .pixel_order = HVS_PIXEL_ORDER_ARGB,
-+ .pixel_order_hvs5 = HVS_PIXEL_ORDER_ABGR,
-+ .hvs5_only = true,
-+ },
- };
-
- static const struct hvs_format *vc4_get_hvs_format(u32 drm_format)
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Chris Morgan
-Date: Fri, 28 Jan 2022 17:39:54 -0600
-Subject: [PATCH 024/784] drm/vc4: dpi: Support DPI interface in mode3 for
- RGB565
-
-Add support for the VC4 DPI driver to utilize DPI mode 3. This is
-defined here as xxxRRRRRxxGGGGGGxxxBBBBB:
-https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#parallel-display-interface-dpi
-
-This mode is required to use the Geekworm MZP280 DPI display.
-
-Signed-off-by: Chris Morgan
-Reviewed-by: Dave Stevenson
----
- drivers/gpu/drm/vc4/vc4_dpi.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
-diff --git a/drivers/gpu/drm/vc4/vc4_dpi.c b/drivers/gpu/drm/vc4/vc4_dpi.c
-index 96b5d34f6bd7..a7bebfa5d5b0 100644
---- a/drivers/gpu/drm/vc4/vc4_dpi.c
-+++ b/drivers/gpu/drm/vc4/vc4_dpi.c
-@@ -188,6 +188,10 @@ static void vc4_dpi_encoder_enable(struct drm_encoder *encoder)
- dpi_c |= VC4_SET_FIELD(DPI_FORMAT_16BIT_565_RGB_1,
- DPI_FORMAT);
- break;
-+ case MEDIA_BUS_FMT_RGB565_1X24_CPADHI:
-+ dpi_c |= VC4_SET_FIELD(DPI_FORMAT_16BIT_565_RGB_2,
-+ DPI_FORMAT);
-+ break;
- default:
- DRM_ERROR("Unknown media bus format %d\n",
- bus_format);
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Dave Stevenson
-Date: Tue, 1 Feb 2022 12:20:20 +0000
-Subject: [PATCH 025/784] drm/panel: Add and initialise an orientation field to
- drm_panel
-
-Current usage of drm_connector_set_panel_orientation is from a panel's
-get_modes call. However if the panel orientation property doesn't
-exist on the connector at this point, then drm_mode_object triggers
-WARNs as the connector is already registered.
-
-Add an orientation variable to struct drm_panel and initialise it from
-drm_panel_init.
-panel_bridge_attach can then create the property before the connector
-is registered.
-
-Signed-off-by: Dave Stevenson
----
- drivers/gpu/drm/bridge/panel.c | 4 ++++
- drivers/gpu/drm/drm_panel.c | 15 ++++++++++-----
- include/drm/drm_panel.h | 8 ++++++++
- 3 files changed, 22 insertions(+), 5 deletions(-)
-
-diff --git a/drivers/gpu/drm/bridge/panel.c b/drivers/gpu/drm/bridge/panel.c
-index 216af76d0042..94ecad089cba 100644
---- a/drivers/gpu/drm/bridge/panel.c
-+++ b/drivers/gpu/drm/bridge/panel.c
-@@ -81,6 +81,10 @@ static int panel_bridge_attach(struct drm_bridge *bridge,
- return ret;
- }
-
-+ /* set up connector's "panel orientation" property */
-+ drm_connector_set_panel_orientation(&panel_bridge->connector,
-+ panel_bridge->panel->orientation);
-+
- drm_connector_attach_encoder(&panel_bridge->connector,
- bridge->encoder);
-
-diff --git a/drivers/gpu/drm/drm_panel.c b/drivers/gpu/drm/drm_panel.c
-index f634371c717a..bee5066e9227 100644
---- a/drivers/gpu/drm/drm_panel.c
-+++ b/drivers/gpu/drm/drm_panel.c
-@@ -61,6 +61,9 @@ void drm_panel_init(struct drm_panel *panel, struct device *dev,
- panel->dev = dev;
- panel->funcs = funcs;
- panel->connector_type = connector_type;
-+
-+ panel->orientation = DRM_MODE_PANEL_ORIENTATION_UNKNOWN;
-+ of_drm_get_panel_orientation(dev->of_node, &panel->orientation);
- }
- EXPORT_SYMBOL(drm_panel_init);
-
-@@ -289,16 +292,18 @@ int of_drm_get_panel_orientation(const struct device_node *np,
- if (ret < 0)
- return ret;
-
-- if (rotation == 0)
-+ if (rotation == 0) {
- *orientation = DRM_MODE_PANEL_ORIENTATION_NORMAL;
-- else if (rotation == 90)
-+ } else if (rotation == 90) {
- *orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP;
-- else if (rotation == 180)
-+ } else if (rotation == 180) {
- *orientation = DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP;
-- else if (rotation == 270)
-+ } else if (rotation == 270) {
- *orientation = DRM_MODE_PANEL_ORIENTATION_LEFT_UP;
-- else
-+ } else {
-+ DRM_ERROR("%pOF: invalid orientation %d\n", np, ret);
- return -EINVAL;
-+ }
-
- return 0;
- }
-diff --git a/include/drm/drm_panel.h b/include/drm/drm_panel.h
-index 994bfcdd84c5..8ea3885cd93f 100644
---- a/include/drm/drm_panel.h
-+++ b/include/drm/drm_panel.h
-@@ -182,6 +182,14 @@ struct drm_panel {
- */
- int connector_type;
-
-+ /**
-+ * @orientation:
-+ *
-+ * Panel orientation at initialisation. This is used to initialise the
-+ * drm_connector property for panel orientation.
-+ */
-+ enum drm_panel_orientation orientation;
-+
- /**
- * @list:
- *
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Dave Stevenson
-Date: Fri, 17 Dec 2021 13:36:52 +0000
-Subject: [PATCH 026/784] drm/dsi: Document the meaning and spec references for
- MIPI_DSI_MODE_*
-
-The MIPI_DSI_MODE_* flags have fairly terse descriptions and no reference
-to the DSI specification as to their exact meaning. Usage has therefore
-been rather fluid.
-
-Extend the descriptions and provide references to the part of the
-MIPI DSI specification regarding what they mean.
-
-Signed-off-by: Dave Stevenson
----
- include/drm/drm_mipi_dsi.h | 38 ++++++++++++++++++++++++++------------
- 1 file changed, 26 insertions(+), 12 deletions(-)
-
-diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
-index 9054a5185e1a..de21b9ff3ac0 100644
---- a/include/drm/drm_mipi_dsi.h
-+++ b/include/drm/drm_mipi_dsi.h
-@@ -113,29 +113,43 @@ struct mipi_dsi_host *of_find_mipi_dsi_host_by_node(struct device_node *node);
-
- /* DSI mode flags */
-
--/* video mode */
-+/* Video mode display.
-+ * Not set denotes a command mode display.
-+ */
- #define MIPI_DSI_MODE_VIDEO BIT(0)
--/* video burst mode */
-+/* Video burst mode.
-+ * Link frequency to be configured via platform configuration.
-+ * This should always be set in conjunction with MIPI_DSI_MODE_VIDEO.
-+ * (DSI spec V1.1 8.11.4)
-+ */
- #define MIPI_DSI_MODE_VIDEO_BURST BIT(1)
--/* video pulse mode */
-+/* Video pulse mode.
-+ * Not set denotes sync event mode. (DSI spec V1.1 8.11.2)
-+ */
- #define MIPI_DSI_MODE_VIDEO_SYNC_PULSE BIT(2)
--/* enable auto vertical count mode */
-+/* Enable auto vertical count mode */
- #define MIPI_DSI_MODE_VIDEO_AUTO_VERT BIT(3)
--/* enable hsync-end packets in vsync-pulse and v-porch area */
-+/* Enable hsync-end packets in vsync-pulse and v-porch area */
- #define MIPI_DSI_MODE_VIDEO_HSE BIT(4)
--/* disable hfront-porch area */
-+/* Transmit NULL packets or LP mode during hfront-porch area.
-+ * Not set denotes sending a blanking packet instead. (DSI spec V1.1 8.11.1)
-+ */
- #define MIPI_DSI_MODE_VIDEO_NO_HFP BIT(5)
--/* disable hback-porch area */
-+/* Transmit NULL packets or LP mode during hback-porch area.
-+ * Not set denotes sending a blanking packet instead. (DSI spec V1.1 8.11.1)
-+ */
- #define MIPI_DSI_MODE_VIDEO_NO_HBP BIT(6)
--/* disable hsync-active area */
-+/* Transmit NULL packets or LP mode during hsync-active area.
-+ * Not set denotes sending a blanking packet instead. (DSI spec V1.1 8.11.1)
-+ */
- #define MIPI_DSI_MODE_VIDEO_NO_HSA BIT(7)
--/* flush display FIFO on vsync pulse */
-+/* Flush display FIFO on vsync pulse */
- #define MIPI_DSI_MODE_VSYNC_FLUSH BIT(8)
--/* disable EoT packets in HS mode */
-+/* Disable EoT packets in HS mode. (DSI spec V1.1 8.1) */
- #define MIPI_DSI_MODE_NO_EOT_PACKET BIT(9)
--/* device supports non-continuous clock behavior (DSI spec 5.6.1) */
-+/* Device supports non-continuous clock behavior (DSI spec V1.1 5.6.1) */
- #define MIPI_DSI_CLOCK_NON_CONTINUOUS BIT(10)
--/* transmit data in low power */
-+/* Transmit data in low power */
- #define MIPI_DSI_MODE_LPM BIT(11)
- /* transmit data ending at the same time for all lanes within one hsync */
- #define MIPI_DSI_HS_PKT_END_ALIGNED BIT(12)
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Dave Stevenson
-Date: Thu, 20 Jan 2022 17:29:36 +0000
-Subject: [PATCH 027/784] drm/bridge: tc358762: Ignore EPROBE_DEFER when
- logging errors
-
-mipi_dsi_attach can fail due to resources not being available
-yet, therefore do not log error messages should they occur.
-
-Signed-off-by: Dave Stevenson
----
- drivers/gpu/drm/bridge/tc358762.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/drivers/gpu/drm/bridge/tc358762.c b/drivers/gpu/drm/bridge/tc358762.c
-index 7f4fce1aa998..0adc4864beea 100644
---- a/drivers/gpu/drm/bridge/tc358762.c
-+++ b/drivers/gpu/drm/bridge/tc358762.c
-@@ -235,7 +235,7 @@ static int tc358762_probe(struct mipi_dsi_device *dsi)
- ret = mipi_dsi_attach(dsi);
- if (ret < 0) {
- drm_bridge_remove(&ctx->bridge);
-- dev_err(dev, "failed to attach dsi\n");
-+ dev_err_probe(dev, ret, "failed to attach dsi\n");
- }
-
- return ret;
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Dave Stevenson
-Date: Thu, 30 Sep 2021 17:51:16 +0100
-Subject: [PATCH 028/784] drm/vc4: Rename bridge to out_bridge
-
-In preparation for converting the encoder to being a bridge,
-rename the variable holding the next bridge in the chain to
-out_bridge, so that our bridge can be called bridge.
-
-Signed-off-by: Dave Stevenson
----
- drivers/gpu/drm/vc4/vc4_dsi.c | 12 ++++++------
- 1 file changed, 6 insertions(+), 6 deletions(-)
-
-diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c
-index 878e05d79e81..d9d951e9ab7c 100644
---- a/drivers/gpu/drm/vc4/vc4_dsi.c
-+++ b/drivers/gpu/drm/vc4/vc4_dsi.c
-@@ -556,7 +556,7 @@ struct vc4_dsi {
-
- struct platform_device *pdev;
-
-- struct drm_bridge *bridge;
-+ struct drm_bridge *out_bridge;
- struct list_head bridge_chain;
-
- void __iomem *regs;
-@@ -800,7 +800,7 @@ static void vc4_dsi_encoder_disable(struct drm_encoder *encoder)
- if (iter->funcs->disable)
- iter->funcs->disable(iter);
-
-- if (iter == dsi->bridge)
-+ if (iter == dsi->out_bridge)
- break;
- }
-
-@@ -1723,9 +1723,9 @@ static int vc4_dsi_bind(struct device *dev, struct device *master, void *data)
- return ret;
- }
-
-- dsi->bridge = drmm_of_get_bridge(drm, dev->of_node, 0, 0);
-- if (IS_ERR(dsi->bridge))
-- return PTR_ERR(dsi->bridge);
-+ dsi->out_bridge = drmm_of_get_bridge(drm, dev->of_node, 0, 0);
-+ if (IS_ERR(dsi->out_bridge))
-+ return PTR_ERR(dsi->out_bridge);
-
- /* The esc clock rate is supposed to always be 100Mhz. */
- ret = clk_set_rate(dsi->escape_clock, 100 * 1000000);
-@@ -1751,7 +1751,7 @@ static int vc4_dsi_bind(struct device *dev, struct device *master, void *data)
- if (ret)
- return ret;
-
-- ret = drm_bridge_attach(encoder, dsi->bridge, NULL, 0);
-+ ret = drm_bridge_attach(encoder, dsi->out_bridge, NULL, 0);
- if (ret)
- return ret;
- /* Disable the atomic helper calls into the bridge. We
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Dave Stevenson
-Date: Mon, 7 Feb 2022 17:14:51 +0000
-Subject: [PATCH 029/784] drm/vc4: Move DSI initialisation to encoder_mode_set.
-
-Breaking the bridge chain does not work for atomic bridges/panels
-and generally causes issues.
-We need to initialise the DSI host before the bridge pre_enables
-are called, so move that to encoder_mode_set in the same way that
-dw-mipi-dsi does.
-
-Signed-off-by: Dave Stevenson
----
- drivers/gpu/drm/vc4/vc4_dsi.c | 17 +++++++++++++----
- 1 file changed, 13 insertions(+), 4 deletions(-)
-
-diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c
-index d9d951e9ab7c..c1bdd903f1ad 100644
---- a/drivers/gpu/drm/vc4/vc4_dsi.c
-+++ b/drivers/gpu/drm/vc4/vc4_dsi.c
-@@ -867,18 +867,18 @@ static bool vc4_dsi_encoder_mode_fixup(struct drm_encoder *encoder,
- return true;
- }
-
--static void vc4_dsi_encoder_enable(struct drm_encoder *encoder)
-+static void vc4_dsi_encoder_mode_set(struct drm_encoder *encoder,
-+ struct drm_display_mode *mode,
-+ struct drm_display_mode *adjusted_mode)
- {
-- struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode;
- struct vc4_dsi *dsi = to_vc4_dsi(encoder);
- struct device *dev = &dsi->pdev->dev;
- bool debug_dump_regs = false;
-- struct drm_bridge *iter;
- unsigned long hs_clock;
- u32 ui_ns;
- /* Minimum LP state duration in escape clock cycles. */
- u32 lpx = dsi_esc_timing(60);
-- unsigned long pixel_clock_hz = mode->clock * 1000;
-+ unsigned long pixel_clock_hz = adjusted_mode->clock * 1000;
- unsigned long dsip_clock;
- unsigned long phy_clock;
- int ret;
-@@ -1105,6 +1105,14 @@ static void vc4_dsi_encoder_enable(struct drm_encoder *encoder)
- ~DSI_PORT_BIT(PHY_AFEC0_RESET));
-
- vc4_dsi_ulps(dsi, false);
-+}
-+
-+static void vc4_dsi_encoder_enable(struct drm_encoder *encoder)
-+{
-+ struct vc4_dsi_encoder *vc4_encoder = to_vc4_dsi_encoder(encoder);
-+ struct vc4_dsi *dsi = vc4_encoder->dsi;
-+ bool debug_dump_regs = false;
-+ struct drm_bridge *iter;
-
- list_for_each_entry_reverse(iter, &dsi->bridge_chain, chain_node) {
- if (iter->funcs->pre_enable)
-@@ -1370,6 +1378,7 @@ static const struct drm_encoder_helper_funcs vc4_dsi_encoder_helper_funcs = {
- .disable = vc4_dsi_encoder_disable,
- .enable = vc4_dsi_encoder_enable,
- .mode_fixup = vc4_dsi_encoder_mode_fixup,
-+ .mode_set = vc4_dsi_encoder_mode_set,
- };
-
- static int vc4_dsi_late_register(struct drm_encoder *encoder)
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Dave Stevenson
-Date: Wed, 15 Dec 2021 17:44:49 +0000
-Subject: [PATCH 030/784] drm/vc4: Remove splitting the bridge chain from the
- driver.
-
-Splitting the bridge chain fails for atomic bridges as the
-framework can't add the relevant state in
-drm_atomic_add_encoder_bridges.
-The chain was split because we needed to power up before
-calling pre_enable, but that is now done in mode_set, and will
-move into the framework.
-
-Signed-off-by: Dave Stevenson
----
- drivers/gpu/drm/vc4/vc4_dsi.c | 47 -----------------------------------
- 1 file changed, 47 deletions(-)
-
-diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c
-index c1bdd903f1ad..9109bee6c7d2 100644
---- a/drivers/gpu/drm/vc4/vc4_dsi.c
-+++ b/drivers/gpu/drm/vc4/vc4_dsi.c
-@@ -557,7 +557,6 @@ struct vc4_dsi {
- struct platform_device *pdev;
-
- struct drm_bridge *out_bridge;
-- struct list_head bridge_chain;
-
- void __iomem *regs;
-
-@@ -794,23 +793,9 @@ static void vc4_dsi_encoder_disable(struct drm_encoder *encoder)
- {
- struct vc4_dsi *dsi = to_vc4_dsi(encoder);
- struct device *dev = &dsi->pdev->dev;
-- struct drm_bridge *iter;
--
-- list_for_each_entry_reverse(iter, &dsi->bridge_chain, chain_node) {
-- if (iter->funcs->disable)
-- iter->funcs->disable(iter);
--
-- if (iter == dsi->out_bridge)
-- break;
-- }
-
- vc4_dsi_ulps(dsi, true);
-
-- list_for_each_entry_from(iter, &dsi->bridge_chain, chain_node) {
-- if (iter->funcs->post_disable)
-- iter->funcs->post_disable(iter);
-- }
--
- clk_disable_unprepare(dsi->pll_phy_clock);
- clk_disable_unprepare(dsi->escape_clock);
- clk_disable_unprepare(dsi->pixel_clock);
-@@ -1112,12 +1097,6 @@ static void vc4_dsi_encoder_enable(struct drm_encoder *encoder)
- struct vc4_dsi_encoder *vc4_encoder = to_vc4_dsi_encoder(encoder);
- struct vc4_dsi *dsi = vc4_encoder->dsi;
- bool debug_dump_regs = false;
-- struct drm_bridge *iter;
--
-- list_for_each_entry_reverse(iter, &dsi->bridge_chain, chain_node) {
-- if (iter->funcs->pre_enable)
-- iter->funcs->pre_enable(iter);
-- }
-
- if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO) {
- DSI_PORT_WRITE(DISP0_CTRL,
-@@ -1134,11 +1113,6 @@ static void vc4_dsi_encoder_enable(struct drm_encoder *encoder)
- DSI_DISP0_ENABLE);
- }
-
-- list_for_each_entry(iter, &dsi->bridge_chain, chain_node) {
-- if (iter->funcs->enable)
-- iter->funcs->enable(iter);
-- }
--
- if (debug_dump_regs) {
- struct drm_printer p = drm_info_printer(&dsi->pdev->dev);
- dev_info(&dsi->pdev->dev, "DSI regs after:\n");
-@@ -1626,7 +1600,6 @@ static int vc4_dsi_bind(struct device *dev, struct device *master, void *data)
-
- dsi->variant = of_device_get_match_data(dev);
-
-- INIT_LIST_HEAD(&dsi->bridge_chain);
- dsi->encoder.type = dsi->variant->port ?
- VC4_ENCODER_TYPE_DSI1 : VC4_ENCODER_TYPE_DSI0;
-
-@@ -1763,32 +1736,12 @@ static int vc4_dsi_bind(struct device *dev, struct device *master, void *data)
- ret = drm_bridge_attach(encoder, dsi->out_bridge, NULL, 0);
- if (ret)
- return ret;
-- /* Disable the atomic helper calls into the bridge. We
-- * manually call the bridge pre_enable / enable / etc. calls
-- * from our driver, since we need to sequence them within the
-- * encoder's enable/disable paths.
-- */
-- list_splice_init(&encoder->bridge_chain, &dsi->bridge_chain);
-
- return 0;
- }
-
--static void vc4_dsi_unbind(struct device *dev, struct device *master,
-- void *data)
--{
-- struct vc4_dsi *dsi = dev_get_drvdata(dev);
-- struct drm_encoder *encoder = &dsi->encoder.base;
--
-- /*
-- * Restore the bridge_chain so the bridge detach procedure can happen
-- * normally.
-- */
-- list_splice_init(&dsi->bridge_chain, &encoder->bridge_chain);
--}
--
- static const struct component_ops vc4_dsi_ops = {
- .bind = vc4_dsi_bind,
-- .unbind = vc4_dsi_unbind,
- };
-
- static int vc4_dsi_dev_probe(struct platform_device *pdev)
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Dave Stevenson
-Date: Wed, 15 Dec 2021 17:47:14 +0000
-Subject: [PATCH 031/784] drm/vc4: Convert vc4_dsi to use atomic
- enable/disable/mode_set.
-
-The atomic calls are preferred as the non-atomic ones
-are deprecated. In preparation for conversion to a bridge,
-switch to the atomic calls.
-
-Signed-off-by: Dave Stevenson
----
- drivers/gpu/drm/vc4/vc4_dsi.c | 23 +++++++++++++++--------
- 1 file changed, 15 insertions(+), 8 deletions(-)
-
-diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c
-index 9109bee6c7d2..4fd4b05d7530 100644
---- a/drivers/gpu/drm/vc4/vc4_dsi.c
-+++ b/drivers/gpu/drm/vc4/vc4_dsi.c
-@@ -789,7 +789,8 @@ dsi_esc_timing(u32 ns)
- return DIV_ROUND_UP(ns, ESC_TIME_NS);
- }
-
--static void vc4_dsi_encoder_disable(struct drm_encoder *encoder)
-+static void vc4_dsi_encoder_disable(struct drm_encoder *encoder,
-+ struct drm_atomic_state *state)
- {
- struct vc4_dsi *dsi = to_vc4_dsi(encoder);
- struct device *dev = &dsi->pdev->dev;
-@@ -853,17 +854,18 @@ static bool vc4_dsi_encoder_mode_fixup(struct drm_encoder *encoder,
- }
-
- static void vc4_dsi_encoder_mode_set(struct drm_encoder *encoder,
-- struct drm_display_mode *mode,
-- struct drm_display_mode *adjusted_mode)
-+ struct drm_crtc_state *crtc_state,
-+ struct drm_connector_state *conn_state)
- {
- struct vc4_dsi *dsi = to_vc4_dsi(encoder);
- struct device *dev = &dsi->pdev->dev;
-+ const struct drm_display_mode *mode;
- bool debug_dump_regs = false;
- unsigned long hs_clock;
- u32 ui_ns;
- /* Minimum LP state duration in escape clock cycles. */
- u32 lpx = dsi_esc_timing(60);
-- unsigned long pixel_clock_hz = adjusted_mode->clock * 1000;
-+ unsigned long pixel_clock_hz;
- unsigned long dsip_clock;
- unsigned long phy_clock;
- int ret;
-@@ -880,6 +882,10 @@ static void vc4_dsi_encoder_mode_set(struct drm_encoder *encoder,
- drm_print_regset32(&p, &dsi->regset);
- }
-
-+ mode = &crtc_state->adjusted_mode;
-+
-+ pixel_clock_hz = mode->clock * 1000;
-+
- /* Round up the clk_set_rate() request slightly, since
- * PLLD_DSI1 is an integer divider and its rate selection will
- * never round up.
-@@ -1092,7 +1098,8 @@ static void vc4_dsi_encoder_mode_set(struct drm_encoder *encoder,
- vc4_dsi_ulps(dsi, false);
- }
-
--static void vc4_dsi_encoder_enable(struct drm_encoder *encoder)
-+static void vc4_dsi_encoder_enable(struct drm_encoder *encoder,
-+ struct drm_atomic_state *state)
- {
- struct vc4_dsi_encoder *vc4_encoder = to_vc4_dsi_encoder(encoder);
- struct vc4_dsi *dsi = vc4_encoder->dsi;
-@@ -1349,10 +1356,10 @@ static const struct mipi_dsi_host_ops vc4_dsi_host_ops = {
- };
-
- static const struct drm_encoder_helper_funcs vc4_dsi_encoder_helper_funcs = {
-- .disable = vc4_dsi_encoder_disable,
-- .enable = vc4_dsi_encoder_enable,
-+ .atomic_disable = vc4_dsi_encoder_disable,
-+ .atomic_enable = vc4_dsi_encoder_enable,
- .mode_fixup = vc4_dsi_encoder_mode_fixup,
-- .mode_set = vc4_dsi_encoder_mode_set,
-+ .atomic_mode_set = vc4_dsi_encoder_mode_set,
- };
-
- static int vc4_dsi_late_register(struct drm_encoder *encoder)
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Dave Stevenson
-Date: Wed, 15 Dec 2021 17:57:45 +0000
-Subject: [PATCH 032/784] drm/vc4: Convert vc4_dsi to using a bridge instead of
- encoder.
-
-Remove the encoder functions, and create a bridge attached to
-this dumb encoder which implements the same functionality.
-
-As a bridge has state which an encoder doesn't, we need to
-add the state management functions as well.
-
-As there is no bridge atomic_mode_set, move the initialisation
-code that was in mode_set into _pre_enable.
-The code to actually enable and disable sending video are split
-from the general control into _enable and _disable.
-
-Signed-off-by: Dave Stevenson
----
- drivers/gpu/drm/vc4/vc4_dsi.c | 122 +++++++++++++++++++++++++---------
- 1 file changed, 90 insertions(+), 32 deletions(-)
-
-diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c
-index 4fd4b05d7530..a7b8ffd995b0 100644
---- a/drivers/gpu/drm/vc4/vc4_dsi.c
-+++ b/drivers/gpu/drm/vc4/vc4_dsi.c
-@@ -557,6 +557,7 @@ struct vc4_dsi {
- struct platform_device *pdev;
-
- struct drm_bridge *out_bridge;
-+ struct drm_bridge bridge;
-
- void __iomem *regs;
-
-@@ -608,6 +609,12 @@ to_vc4_dsi(struct drm_encoder *encoder)
- return container_of(encoder, struct vc4_dsi, encoder.base);
- }
-
-+static inline struct vc4_dsi *
-+bridge_to_vc4_dsi(struct drm_bridge *bridge)
-+{
-+ return container_of(bridge, struct vc4_dsi, bridge);
-+}
-+
- static inline void
- dsi_dma_workaround_write(struct vc4_dsi *dsi, u32 offset, u32 val)
- {
-@@ -789,10 +796,21 @@ dsi_esc_timing(u32 ns)
- return DIV_ROUND_UP(ns, ESC_TIME_NS);
- }
-
--static void vc4_dsi_encoder_disable(struct drm_encoder *encoder,
-- struct drm_atomic_state *state)
-+static void vc4_dsi_bridge_disable(struct drm_bridge *bridge,
-+ struct drm_bridge_state *state)
- {
-- struct vc4_dsi *dsi = to_vc4_dsi(encoder);
-+ struct vc4_dsi *dsi = bridge_to_vc4_dsi(bridge);
-+ u32 disp0_ctrl;
-+
-+ disp0_ctrl = DSI_PORT_READ(DISP0_CTRL);
-+ disp0_ctrl &= ~DSI_DISP0_ENABLE;
-+ DSI_PORT_WRITE(DISP0_CTRL, disp0_ctrl);
-+}
-+
-+static void vc4_dsi_bridge_post_disable(struct drm_bridge *bridge,
-+ struct drm_bridge_state *state)
-+{
-+ struct vc4_dsi *dsi = bridge_to_vc4_dsi(bridge);
- struct device *dev = &dsi->pdev->dev;
-
- vc4_dsi_ulps(dsi, true);
-@@ -817,11 +835,11 @@ static void vc4_dsi_encoder_disable(struct drm_encoder *encoder,
- * higher-than-expected clock rate to the panel, but that's what the
- * firmware does too.
- */
--static bool vc4_dsi_encoder_mode_fixup(struct drm_encoder *encoder,
-- const struct drm_display_mode *mode,
-- struct drm_display_mode *adjusted_mode)
-+static bool vc4_dsi_bridge_mode_fixup(struct drm_bridge *bridge,
-+ const struct drm_display_mode *mode,
-+ struct drm_display_mode *adjusted_mode)
- {
-- struct vc4_dsi *dsi = to_vc4_dsi(encoder);
-+ struct vc4_dsi *dsi = bridge_to_vc4_dsi(bridge);
- struct clk *phy_parent = clk_get_parent(dsi->pll_phy_clock);
- unsigned long parent_rate = clk_get_rate(phy_parent);
- unsigned long pixel_clock_hz = mode->clock * 1000;
-@@ -853,15 +871,18 @@ static bool vc4_dsi_encoder_mode_fixup(struct drm_encoder *encoder,
- return true;
- }
-
--static void vc4_dsi_encoder_mode_set(struct drm_encoder *encoder,
-- struct drm_crtc_state *crtc_state,
-- struct drm_connector_state *conn_state)
-+static void vc4_dsi_bridge_pre_enable(struct drm_bridge *bridge,
-+ struct drm_bridge_state *old_state)
- {
-- struct vc4_dsi *dsi = to_vc4_dsi(encoder);
-+ struct drm_atomic_state *state = old_state->base.state;
-+ struct vc4_dsi *dsi = bridge_to_vc4_dsi(bridge);
-+ const struct drm_crtc_state *crtc_state;
- struct device *dev = &dsi->pdev->dev;
- const struct drm_display_mode *mode;
-+ struct drm_connector *connector;
- bool debug_dump_regs = false;
- unsigned long hs_clock;
-+ struct drm_crtc *crtc;
- u32 ui_ns;
- /* Minimum LP state duration in escape clock cycles. */
- u32 lpx = dsi_esc_timing(60);
-@@ -882,6 +903,14 @@ static void vc4_dsi_encoder_mode_set(struct drm_encoder *encoder,
- drm_print_regset32(&p, &dsi->regset);
- }
-
-+ /*
-+ * Retrieve the CRTC adjusted mode. This requires a little dance to go
-+ * from the bridge to the encoder, to the connector and to the CRTC.
-+ */
-+ connector = drm_atomic_get_new_connector_for_encoder(state,
-+ bridge->encoder);
-+ crtc = drm_atomic_get_new_connector_state(state, connector)->crtc;
-+ crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
- mode = &crtc_state->adjusted_mode;
-
- pixel_clock_hz = mode->clock * 1000;
-@@ -1096,14 +1125,6 @@ static void vc4_dsi_encoder_mode_set(struct drm_encoder *encoder,
- ~DSI_PORT_BIT(PHY_AFEC0_RESET));
-
- vc4_dsi_ulps(dsi, false);
--}
--
--static void vc4_dsi_encoder_enable(struct drm_encoder *encoder,
-- struct drm_atomic_state *state)
--{
-- struct vc4_dsi_encoder *vc4_encoder = to_vc4_dsi_encoder(encoder);
-- struct vc4_dsi *dsi = vc4_encoder->dsi;
-- bool debug_dump_regs = false;
-
- if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO) {
- DSI_PORT_WRITE(DISP0_CTRL,
-@@ -1112,13 +1133,23 @@ static void vc4_dsi_encoder_enable(struct drm_encoder *encoder,
- VC4_SET_FIELD(dsi->format, DSI_DISP0_PFORMAT) |
- VC4_SET_FIELD(DSI_DISP0_LP_STOP_PERFRAME,
- DSI_DISP0_LP_STOP_CTRL) |
-- DSI_DISP0_ST_END |
-- DSI_DISP0_ENABLE);
-+ DSI_DISP0_ST_END);
- } else {
- DSI_PORT_WRITE(DISP0_CTRL,
-- DSI_DISP0_COMMAND_MODE |
-- DSI_DISP0_ENABLE);
-+ DSI_DISP0_COMMAND_MODE);
- }
-+}
-+
-+static void vc4_dsi_bridge_enable(struct drm_bridge *bridge,
-+ struct drm_bridge_state *old_state)
-+{
-+ struct vc4_dsi *dsi = bridge_to_vc4_dsi(bridge);
-+ bool debug_dump_regs = false;
-+ u32 disp0_ctrl;
-+
-+ disp0_ctrl = DSI_PORT_READ(DISP0_CTRL);
-+ disp0_ctrl |= DSI_DISP0_ENABLE;
-+ DSI_PORT_WRITE(DISP0_CTRL, disp0_ctrl);
-
- if (debug_dump_regs) {
- struct drm_printer p = drm_info_printer(&dsi->pdev->dev);
-@@ -1127,6 +1158,16 @@ static void vc4_dsi_encoder_enable(struct drm_encoder *encoder,
- }
- }
-
-+static int vc4_dsi_bridge_attach(struct drm_bridge *bridge,
-+ enum drm_bridge_attach_flags flags)
-+{
-+ struct vc4_dsi *dsi = bridge_to_vc4_dsi(bridge);
-+
-+ /* Attach the panel or bridge to the dsi bridge */
-+ return drm_bridge_attach(bridge->encoder, dsi->out_bridge,
-+ &dsi->bridge, flags);
-+}
-+
- static ssize_t vc4_dsi_host_transfer(struct mipi_dsi_host *host,
- const struct mipi_dsi_msg *msg)
- {
-@@ -1303,6 +1344,7 @@ static int vc4_dsi_host_attach(struct mipi_dsi_host *host,
- struct mipi_dsi_device *device)
- {
- struct vc4_dsi *dsi = host_to_dsi(host);
-+ int ret;
-
- dsi->lanes = device->lanes;
- dsi->channel = device->channel;
-@@ -1337,7 +1379,15 @@ static int vc4_dsi_host_attach(struct mipi_dsi_host *host,
- return 0;
- }
-
-- return component_add(&dsi->pdev->dev, &vc4_dsi_ops);
-+ drm_bridge_add(&dsi->bridge);
-+
-+ ret = component_add(&dsi->pdev->dev, &vc4_dsi_ops);
-+ if (ret) {
-+ drm_bridge_remove(&dsi->bridge);
-+ return ret;
-+ }
-+
-+ return 0;
- }
-
- static int vc4_dsi_host_detach(struct mipi_dsi_host *host,
-@@ -1346,6 +1396,7 @@ static int vc4_dsi_host_detach(struct mipi_dsi_host *host,
- struct vc4_dsi *dsi = host_to_dsi(host);
-
- component_del(&dsi->pdev->dev, &vc4_dsi_ops);
-+ drm_bridge_remove(&dsi->bridge);
- return 0;
- }
-
-@@ -1355,11 +1406,16 @@ static const struct mipi_dsi_host_ops vc4_dsi_host_ops = {
- .transfer = vc4_dsi_host_transfer,
- };
-
--static const struct drm_encoder_helper_funcs vc4_dsi_encoder_helper_funcs = {
-- .atomic_disable = vc4_dsi_encoder_disable,
-- .atomic_enable = vc4_dsi_encoder_enable,
-- .mode_fixup = vc4_dsi_encoder_mode_fixup,
-- .atomic_mode_set = vc4_dsi_encoder_mode_set,
-+static const struct drm_bridge_funcs vc4_dsi_bridge_funcs = {
-+ .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
-+ .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
-+ .atomic_reset = drm_atomic_helper_bridge_reset,
-+ .atomic_pre_enable = vc4_dsi_bridge_pre_enable,
-+ .atomic_enable = vc4_dsi_bridge_enable,
-+ .atomic_disable = vc4_dsi_bridge_disable,
-+ .atomic_post_disable = vc4_dsi_bridge_post_disable,
-+ .attach = vc4_dsi_bridge_attach,
-+ .mode_fixup = vc4_dsi_bridge_mode_fixup,
- };
-
- static int vc4_dsi_late_register(struct drm_encoder *encoder)
-@@ -1734,13 +1790,11 @@ static int vc4_dsi_bind(struct device *dev, struct device *master, void *data)
- if (ret)
- return ret;
-
-- drm_encoder_helper_add(encoder, &vc4_dsi_encoder_helper_funcs);
--
- ret = devm_pm_runtime_enable(dev);
- if (ret)
- return ret;
-
-- ret = drm_bridge_attach(encoder, dsi->out_bridge, NULL, 0);
-+ ret = drm_bridge_attach(encoder, &dsi->bridge, NULL, 0);
- if (ret)
- return ret;
-
-@@ -1762,7 +1816,11 @@ static int vc4_dsi_dev_probe(struct platform_device *pdev)
- dev_set_drvdata(dev, dsi);
-
- kref_init(&dsi->kref);
-+
- dsi->pdev = pdev;
-+ dsi->bridge.funcs = &vc4_dsi_bridge_funcs;
-+ dsi->bridge.of_node = dev->of_node;
-+ dsi->bridge.type = DRM_MODE_CONNECTOR_DSI;
- dsi->dsi_host.ops = &vc4_dsi_host_ops;
- dsi->dsi_host.dev = dev;
- mipi_dsi_host_register(&dsi->dsi_host);
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Dave Stevenson
-Date: Fri, 11 Feb 2022 14:15:26 +0000
-Subject: [PATCH 033/784] drm/vc4: Remove entry to ULPS from vc4_dsi
- post_disable
-
-Post_disable was sending the D-PHY sequence to put any device
-into ULPS suspend mode, and then cutting power to the DSI block.
-The power-on reset state of the DSI block is for DSI to be in
-an operational state, not ULPS, so it then never sent the sequence
-for exiting ULPS. Any attached device that didn't have an external
-reset therefore remained in ULPS / standby, and didn't function.
-
-Use of ULPS isn't well specified in DRM, therefore remove entering
-it to avoid the above situation.
-
-Signed-off-by: Dave Stevenson
----
- drivers/gpu/drm/vc4/vc4_dsi.c | 2 --
- 1 file changed, 2 deletions(-)
-
-diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c
-index a7b8ffd995b0..4f3805528aa1 100644
---- a/drivers/gpu/drm/vc4/vc4_dsi.c
-+++ b/drivers/gpu/drm/vc4/vc4_dsi.c
-@@ -813,8 +813,6 @@ static void vc4_dsi_bridge_post_disable(struct drm_bridge *bridge,
- struct vc4_dsi *dsi = bridge_to_vc4_dsi(bridge);
- struct device *dev = &dsi->pdev->dev;
-
-- vc4_dsi_ulps(dsi, true);
--
- clk_disable_unprepare(dsi->pll_phy_clock);
- clk_disable_unprepare(dsi->escape_clock);
- clk_disable_unprepare(dsi->pixel_clock);
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Dave Stevenson
-Date: Thu, 16 Dec 2021 15:25:35 +0000
-Subject: [PATCH 034/784] drm/bridge: Introduce pre_enable_upstream_first to
- alter bridge init order
-
-DSI sink devices typically want the DSI host powered up and configured
-before they are powered up. pre_enable is the place this would normally
-happen, but they are called in reverse order from panel/connector towards
-the encoder, which is the "wrong" order.
-
-Add a new flag pre_enable_upstream_first that any bridge can set
-to swap the order of pre_enable (and post_disable) for that and the
-immediately upstream bridge.
-Should the immediately upstream bridge also set the
-pre_enable_upstream_first flag, the bridge upstream of that will be called
-before either of those which requested pre_enable_upstream_first.
-
-eg:
-- Panel
-- Bridge 1
-- Bridge 2 pre_enable_upstream_first
-- Bridge 3
-- Bridge 4 pre_enable_upstream_first
-- Bridge 5 pre_enable_upstream_first
-- Bridge 6
-- Encoder
-Would result in pre_enable's being called as Panel, Bridge 1, Bridge 3,
-Bridge 2, Bridge 6, Bridge 5, Bridge 4, Encoder.
-
-Signed-off-by: Dave Stevenson
----
- drivers/gpu/drm/drm_bridge.c | 177 +++++++++++++++++++++++++----------
- include/drm/drm_bridge.h | 8 ++
- 2 files changed, 137 insertions(+), 48 deletions(-)
-
-diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
-index 1545c50fd1c8..441d781c3da1 100644
---- a/drivers/gpu/drm/drm_bridge.c
-+++ b/drivers/gpu/drm/drm_bridge.c
-@@ -547,20 +547,15 @@ EXPORT_SYMBOL(drm_bridge_chain_disable);
- * encoder chain, starting from the first bridge to the last. These are called
- * after completing the encoder's prepare op.
- *
-+ * If a bridge sets @pre_enable_upstream_first, then the @post_disable for that
-+ * bridge will be called before the previous one to reverse the @pre_enable
-+ * calling direction.
-+ *
- * Note: the bridge passed should be the one closest to the encoder
- */
- void drm_bridge_chain_post_disable(struct drm_bridge *bridge)
- {
-- struct drm_encoder *encoder;
--
-- if (!bridge)
-- return;
--
-- encoder = bridge->encoder;
-- list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node) {
-- if (bridge->funcs->post_disable)
-- bridge->funcs->post_disable(bridge);
-- }
-+ drm_atomic_bridge_chain_post_disable(bridge, NULL);
- }
- EXPORT_SYMBOL(drm_bridge_chain_post_disable);
-
-@@ -602,24 +597,14 @@ EXPORT_SYMBOL(drm_bridge_chain_mode_set);
- * chain, starting from the last bridge to the first. These are called
- * before calling the encoder's commit op.
- *
-+ * If a bridge sets @pre_enable_upstream_first, then the @pre_enable for the
-+ * previous bridge will be called before @pre_enable of this bridge.
-+ *
- * Note: the bridge passed should be the one closest to the encoder
- */
- void drm_bridge_chain_pre_enable(struct drm_bridge *bridge)
- {
-- struct drm_encoder *encoder;
-- struct drm_bridge *iter;
--
-- if (!bridge)
-- return;
--
-- encoder = bridge->encoder;
-- list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node) {
-- if (iter->funcs->pre_enable)
-- iter->funcs->pre_enable(iter);
--
-- if (iter == bridge)
-- break;
-- }
-+ drm_atomic_bridge_chain_pre_enable(bridge, NULL);
- }
- EXPORT_SYMBOL(drm_bridge_chain_pre_enable);
-
-@@ -691,6 +676,25 @@ void drm_atomic_bridge_chain_disable(struct drm_bridge *bridge,
- }
- EXPORT_SYMBOL(drm_atomic_bridge_chain_disable);
-
-+static void drm_atomic_bridge_call_post_disable(struct drm_bridge *bridge,
-+ struct drm_atomic_state *old_state)
-+{
-+ if (old_state && bridge->funcs->atomic_post_disable) {
-+ struct drm_bridge_state *old_bridge_state;
-+
-+ old_bridge_state =
-+ drm_atomic_get_old_bridge_state(old_state,
-+ bridge);
-+ if (WARN_ON(!old_bridge_state))
-+ return;
-+
-+ bridge->funcs->atomic_post_disable(bridge,
-+ old_bridge_state);
-+ } else if (bridge->funcs->post_disable) {
-+ bridge->funcs->post_disable(bridge);
-+ }
-+}
-+
- /**
- * drm_atomic_bridge_chain_post_disable - cleans up after disabling all bridges
- * in the encoder chain
-@@ -701,6 +705,9 @@ EXPORT_SYMBOL(drm_atomic_bridge_chain_disable);
- * &drm_bridge_funcs.post_disable) op for all the bridges in the encoder chain,
- * starting from the first bridge to the last. These are called after completing
- * &drm_encoder_helper_funcs.atomic_disable
-+ * If a bridge sets @pre_enable_upstream_first, then the @post_disable for that
-+ * bridge will be called before the previous one to reverse the @pre_enable
-+ * calling direction.
- *
- * Note: the bridge passed should be the one closest to the encoder
- */
-@@ -708,30 +715,75 @@ void drm_atomic_bridge_chain_post_disable(struct drm_bridge *bridge,
- struct drm_atomic_state *old_state)
- {
- struct drm_encoder *encoder;
-+ struct drm_bridge *next, *limit;
-
- if (!bridge)
- return;
-
- encoder = bridge->encoder;
-+
- list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node) {
-- if (bridge->funcs->atomic_post_disable) {
-- struct drm_bridge_state *old_bridge_state;
-+ limit = NULL;
-+
-+ if (!list_is_last(&bridge->chain_node, &encoder->bridge_chain)) {
-+ next = list_next_entry(bridge, chain_node);
-+
-+ if (next->pre_enable_upstream_first) {
-+ /* Downstream bridge had requested that upstream
-+ * was enabled first, so disabled last
-+ */
-+ limit = next;
-+
-+ /* Find the next bridge that has NOT requested
-+ * upstream to be enabled first / disabled last
-+ */
-+ list_for_each_entry_from(next, &encoder->bridge_chain,
-+ chain_node) {
-+ if (next->pre_enable_upstream_first) {
-+ next = list_prev_entry(next, chain_node);
-+ limit = next;
-+ break;
-+ }
-+ }
-+
-+ /* Call these bridges in reverse order */
-+ list_for_each_entry_from_reverse(next, &encoder->bridge_chain,
-+ chain_node) {
-+ if (next == bridge)
-+ break;
-+
-+ drm_atomic_bridge_call_post_disable(next,
-+ old_state);
-+ }
-+ }
-+ }
-
-- old_bridge_state =
-- drm_atomic_get_old_bridge_state(old_state,
-- bridge);
-- if (WARN_ON(!old_bridge_state))
-- return;
-+ drm_atomic_bridge_call_post_disable(bridge, old_state);
-
-- bridge->funcs->atomic_post_disable(bridge,
-- old_bridge_state);
-- } else if (bridge->funcs->post_disable) {
-- bridge->funcs->post_disable(bridge);
-- }
-+ if (limit)
-+ bridge = limit;
- }
- }
- EXPORT_SYMBOL(drm_atomic_bridge_chain_post_disable);
-
-+static void drm_atomic_bridge_call_pre_enable(struct drm_bridge *bridge,
-+ struct drm_atomic_state *old_state)
-+{
-+ if (old_state && bridge->funcs->atomic_pre_enable) {
-+ struct drm_bridge_state *old_bridge_state;
-+
-+ old_bridge_state =
-+ drm_atomic_get_old_bridge_state(old_state,
-+ bridge);
-+ if (WARN_ON(!old_bridge_state))
-+ return;
-+
-+ bridge->funcs->atomic_pre_enable(bridge, old_bridge_state);
-+ } else if (bridge->funcs->pre_enable) {
-+ bridge->funcs->pre_enable(bridge);
-+ }
-+}
-+
- /**
- * drm_atomic_bridge_chain_pre_enable - prepares for enabling all bridges in
- * the encoder chain
-@@ -743,32 +795,61 @@ EXPORT_SYMBOL(drm_atomic_bridge_chain_post_disable);
- * starting from the last bridge to the first. These are called before calling
- * &drm_encoder_helper_funcs.atomic_enable
- *
-+ * If a bridge sets @pre_enable_upstream_first, then the pre_enable for the
-+ * upstream bridge will be called before pre_enable of this bridge.
-+ *
- * Note: the bridge passed should be the one closest to the encoder
- */
- void drm_atomic_bridge_chain_pre_enable(struct drm_bridge *bridge,
- struct drm_atomic_state *old_state)
- {
- struct drm_encoder *encoder;
-- struct drm_bridge *iter;
-+ struct drm_bridge *iter, *next, *limit;
-
- if (!bridge)
- return;
-
- encoder = bridge->encoder;
-+
- list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node) {
-- if (iter->funcs->atomic_pre_enable) {
-- struct drm_bridge_state *old_bridge_state;
-+ if (iter->pre_enable_upstream_first) {
-+ next = iter;
-+ limit = bridge;
-+ list_for_each_entry_from_reverse(next,
-+ &encoder->bridge_chain,
-+ chain_node) {
-+ if (next == bridge)
-+ break;
-+
-+ if (!next->pre_enable_upstream_first) {
-+ /* Found first bridge that does NOT
-+ * request upstream to be enabled first
-+ */
-+ limit = list_prev_entry(next, chain_node);
-+ break;
-+ }
-+ }
-+
-+ list_for_each_entry_from(next, &encoder->bridge_chain, chain_node) {
-+ /* Call requested upstream bridge pre_enable
-+ * in order.
-+ */
-+ if (next == iter)
-+ /* At the first bridgge to request upstream
-+ * bridges called first.
-+ */
-+ break;
-+
-+ drm_atomic_bridge_call_pre_enable(next, old_state);
-+ }
-+ }
-
-- old_bridge_state =
-- drm_atomic_get_old_bridge_state(old_state,
-- iter);
-- if (WARN_ON(!old_bridge_state))
-- return;
-+ drm_atomic_bridge_call_pre_enable(iter, old_state);
-
-- iter->funcs->atomic_pre_enable(iter, old_bridge_state);
-- } else if (iter->funcs->pre_enable) {
-- iter->funcs->pre_enable(iter);
-- }
-+ if (iter->pre_enable_upstream_first)
-+ /* Jump all bridges that we have already pre_enabled
-+ */
-+ iter = limit;
-
- if (iter == bridge)
- break;
-diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
-index 288c6feda5de..eed8394ed055 100644
---- a/include/drm/drm_bridge.h
-+++ b/include/drm/drm_bridge.h
-@@ -768,6 +768,14 @@ struct drm_bridge {
- * modes.
- */
- bool interlace_allowed;
-+ /**
-+ * @pre_enable_upstream_first: The bridge requires that the upstream
-+ * bridge @pre_enable function is called before its @pre_enable,
-+ * and conversely for post_disable. This is most frequently a
-+ * requirement for DSI devices which need the host to be initialised
-+ * before the peripheral.
-+ */
-+ bool pre_enable_upstream_first;
- /**
- * @ddc: Associated I2C adapter for DDC access, if any.
- */
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Dave Stevenson
-Date: Wed, 23 Feb 2022 15:36:56 +0000
-Subject: [PATCH 035/784] drm/panel: Add prepare_upstream_first flag to
- drm_panel
-
-Mapping to the drm_bridge flag pre_enable_upstream_first,
-add a new flag prepare_upstream_first to drm_panel to allow
-the panel driver to request that the upstream bridge should
-be pre_enabled before the panel prepare.
-
-Signed-off-by: Dave Stevenson
----
- drivers/gpu/drm/bridge/panel.c | 3 +++
- include/drm/drm_panel.h | 10 ++++++++++
- 2 files changed, 13 insertions(+)
-
-diff --git a/drivers/gpu/drm/bridge/panel.c b/drivers/gpu/drm/bridge/panel.c
-index 94ecad089cba..0c1dcf85ed13 100644
---- a/drivers/gpu/drm/bridge/panel.c
-+++ b/drivers/gpu/drm/bridge/panel.c
-@@ -258,6 +258,9 @@ struct drm_bridge *drm_panel_bridge_add_typed(struct drm_panel *panel,
- panel_bridge->bridge.ops = DRM_BRIDGE_OP_MODES;
- panel_bridge->bridge.type = connector_type;
-
-+ panel_bridge->bridge.pre_enable_upstream_first =
-+ panel->prepare_upstream_first;
-+
- drm_bridge_add(&panel_bridge->bridge);
-
- return &panel_bridge->bridge;
-diff --git a/include/drm/drm_panel.h b/include/drm/drm_panel.h
-index 8ea3885cd93f..81ea5e5b272e 100644
---- a/include/drm/drm_panel.h
-+++ b/include/drm/drm_panel.h
-@@ -196,6 +196,16 @@ struct drm_panel {
- * Panel entry in registry.
- */
- struct list_head list;
-+
-+ /**
-+ * @prepare_upstream_first:
-+ *
-+ * The upstream controller should be prepared first, before the prepare
-+ * for the panel is called. This is largely required for DSI panels
-+ * where the DSI host controller should be initialised to LP-11 before
-+ * the panel is powered up.
-+ */
-+ bool prepare_upstream_first;
- };
-
- void drm_panel_init(struct drm_panel *panel, struct device *dev,
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Dave Stevenson
-Date: Fri, 11 Mar 2022 17:24:37 +0000
-Subject: [PATCH 036/784] drm: Include drm_connector.h from drm_panel.h
-
-drm_panel.h wants to reference enum drm_panel_orientation which is defined
-in drm_connector.h (despite the name).
-Include drm_connector.h in drm_panel.h to avoid the rare situation where
-drm_panel.h is used with drm_connector.h
-
-https://github.com/raspberrypi/linux/issues/4919
-
-Signed-off-by: Dave Stevenson
----
- include/drm/drm_panel.h | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
-diff --git a/include/drm/drm_panel.h b/include/drm/drm_panel.h
-index 81ea5e5b272e..451f88efcd1c 100644
---- a/include/drm/drm_panel.h
-+++ b/include/drm/drm_panel.h
-@@ -24,6 +24,7 @@
- #ifndef __DRM_PANEL_H__
- #define __DRM_PANEL_H__
-
-+#include
- #include
- #include
- #include
-@@ -36,8 +37,6 @@ struct drm_device;
- struct drm_panel;
- struct display_timing;
-
--enum drm_panel_orientation;
--
- /**
- * struct drm_panel_funcs - perform operations on a given panel
- *
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Dave Stevenson
-Date: Thu, 16 Dec 2021 15:33:43 +0000
-Subject: [PATCH 037/784] drm/tc358762: Set the pre_enable_upstream_first flag
- to configure DSI host
-
-TC358762 wants the DSI host to be prepared before it is powered up, so
-set the flag to request that the upstream bridges have their
-pre_enable called first.
-
-Signed-off-by: Dave Stevenson
----
- drivers/gpu/drm/bridge/tc358762.c | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/drivers/gpu/drm/bridge/tc358762.c b/drivers/gpu/drm/bridge/tc358762.c
-index 0adc4864beea..9914cfb05b11 100644
---- a/drivers/gpu/drm/bridge/tc358762.c
-+++ b/drivers/gpu/drm/bridge/tc358762.c
-@@ -229,6 +229,7 @@ static int tc358762_probe(struct mipi_dsi_device *dsi)
- ctx->bridge.funcs = &tc358762_bridge_funcs;
- ctx->bridge.type = DRM_MODE_CONNECTOR_DPI;
- ctx->bridge.of_node = dev->of_node;
-+ ctx->bridge.pre_enable_upstream_first = true;
-
- drm_bridge_add(&ctx->bridge);
-
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Dave Stevenson
-Date: Tue, 25 Jan 2022 17:28:18 +0000
-Subject: [PATCH 038/784] drm/vc4: Support zpos on all planes
-
-Adds the zpos property to all planes, and creates the dlist
-by placing the fragments in the correct order based on zpos.
-
-Signed-off-by: Dave Stevenson
----
- drivers/gpu/drm/vc4/vc4_hvs.c | 43 +++++++++++++++++++++------------
- drivers/gpu/drm/vc4/vc4_kms.c | 3 +--
- drivers/gpu/drm/vc4/vc4_plane.c | 22 ++++++++++++++---
- 3 files changed, 48 insertions(+), 20 deletions(-)
-
-diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c
-index 43ba463b6790..38669ea71c4a 100644
---- a/drivers/gpu/drm/vc4/vc4_hvs.c
-+++ b/drivers/gpu/drm/vc4/vc4_hvs.c
-@@ -769,6 +769,8 @@ void vc4_hvs_atomic_flush(struct drm_crtc *crtc,
- bool enable_bg_fill = false;
- u32 __iomem *dlist_start = vc4->hvs->dlist + vc4_state->mm.start;
- u32 __iomem *dlist_next = dlist_start;
-+ unsigned int zpos = 0;
-+ bool found = false;
- int idx;
-
- if (!drm_dev_enter(dev, &idx)) {
-@@ -782,23 +784,34 @@ void vc4_hvs_atomic_flush(struct drm_crtc *crtc,
- }
-
- /* Copy all the active planes' dlist contents to the hardware dlist. */
-- drm_atomic_crtc_for_each_plane(plane, crtc) {
-- /* Is this the first active plane? */
-- if (dlist_next == dlist_start) {
-- /* We need to enable background fill when a plane
-- * could be alpha blending from the background, i.e.
-- * where no other plane is underneath. It suffices to
-- * consider the first active plane here since we set
-- * needs_bg_fill such that either the first plane
-- * already needs it or all planes on top blend from
-- * the first or a lower plane.
-- */
-- vc4_plane_state = to_vc4_plane_state(plane->state);
-- enable_bg_fill = vc4_plane_state->needs_bg_fill;
-+ do {
-+ found = false;
-+
-+ drm_atomic_crtc_for_each_plane(plane, crtc) {
-+ if (plane->state->normalized_zpos != zpos)
-+ continue;
-+
-+ /* Is this the first active plane? */
-+ if (dlist_next == dlist_start) {
-+ /* We need to enable background fill when a plane
-+ * could be alpha blending from the background, i.e.
-+ * where no other plane is underneath. It suffices to
-+ * consider the first active plane here since we set
-+ * needs_bg_fill such that either the first plane
-+ * already needs it or all planes on top blend from
-+ * the first or a lower plane.
-+ */
-+ vc4_plane_state = to_vc4_plane_state(plane->state);
-+ enable_bg_fill = vc4_plane_state->needs_bg_fill;
-+ }
-+
-+ dlist_next += vc4_plane_write_dlist(plane, dlist_next);
-+
-+ found = true;
- }
-
-- dlist_next += vc4_plane_write_dlist(plane, dlist_next);
-- }
-+ zpos++;
-+ } while (found);
-
- writel(SCALER_CTL0_END, dlist_next);
- dlist_next++;
-diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c
-index e52a4cfaebf6..d5b16579fd33 100644
---- a/drivers/gpu/drm/vc4/vc4_kms.c
-+++ b/drivers/gpu/drm/vc4/vc4_kms.c
-@@ -1066,8 +1066,7 @@ int vc4_kms_load(struct drm_device *dev)
- dev->mode_config.helper_private = &vc4_mode_config_helpers;
- dev->mode_config.preferred_depth = 24;
- dev->mode_config.async_page_flip = true;
-- if (vc4->firmware_kms)
-- dev->mode_config.normalize_zpos = true;
-+ dev->mode_config.normalize_zpos = true;
-
- ret = vc4_ctm_obj_init(vc4);
- if (ret)
-diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
-index 9ae2feb34461..7c094e9f8218 100644
---- a/drivers/gpu/drm/vc4/vc4_plane.c
-+++ b/drivers/gpu/drm/vc4/vc4_plane.c
-@@ -1600,9 +1600,14 @@ struct drm_plane *vc4_plane_init(struct drm_device *dev,
- DRM_COLOR_YCBCR_BT709,
- DRM_COLOR_YCBCR_LIMITED_RANGE);
-
-+ if (type == DRM_PLANE_TYPE_PRIMARY)
-+ drm_plane_create_zpos_immutable_property(plane, 0);
-+
- return plane;
- }
-
-+#define VC4_NUM_OVERLAY_PLANES 16
-+
- int vc4_plane_create_additional_planes(struct drm_device *drm)
- {
- struct drm_plane *cursor_plane;
-@@ -1618,24 +1623,35 @@ int vc4_plane_create_additional_planes(struct drm_device *drm)
- * modest number of planes to expose, that should hopefully
- * still cover any sane usecase.
- */
-- for (i = 0; i < 16; i++) {
-+ for (i = 0; i < VC4_NUM_OVERLAY_PLANES; i++) {
- struct drm_plane *plane =
- vc4_plane_init(drm, DRM_PLANE_TYPE_OVERLAY,
- GENMASK(drm->mode_config.num_crtc - 1, 0));
-
- if (IS_ERR(plane))
- continue;
-+
-+ /* Create zpos property. Max of all the overlays + 1 primary +
-+ * 1 cursor plane on a crtc.
-+ */
-+ drm_plane_create_zpos_property(plane, i + 1, 1,
-+ VC4_NUM_OVERLAY_PLANES + 1);
- }
-
- drm_for_each_crtc(crtc, drm) {
- /* Set up the legacy cursor after overlay initialization,
-- * since we overlay planes on the CRTC in the order they were
-- * initialized.
-+ * since the zpos fallback is that planes are rendered by plane
-+ * ID order, and that then puts the cursor on top.
- */
- cursor_plane = vc4_plane_init(drm, DRM_PLANE_TYPE_CURSOR,
- drm_crtc_mask(crtc));
- if (!IS_ERR(cursor_plane)) {
- crtc->cursor = cursor_plane;
-+
-+ drm_plane_create_zpos_property(cursor_plane,
-+ VC4_NUM_OVERLAY_PLANES + 1,
-+ 1,
-+ VC4_NUM_OVERLAY_PLANES + 1);
- }
- }
-
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Dave Stevenson
-Date: Mon, 7 Mar 2022 15:19:38 +0000
-Subject: [PATCH 039/784] drm/vc4: hdmi: Add CSC for BT601/709/2020 limited and
- full range output
-
-The HVS always composes in the RGB domain, but there is a colourspace
-conversion block on the output to allow for sending YCbCr over the
-HDMI interface.
-The colourspace on that link is configurable via the "Colorspace"
-property on the connector, and that updates the infoframes. There
-is also selection of limited or full range based on the mode selected
-or an override.
-
-Add code to update the CSC as well so that the metadata matches the
-image data.
-
-Signed-off-by: Dave Stevenson
----
- drivers/gpu/drm/vc4/vc4_hdmi.c | 196 ++++++++++++++++++++++++---------
- 1 file changed, 145 insertions(+), 51 deletions(-)
-
-diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
-index e9cb32d3b0d5..431f901068a0 100644
---- a/drivers/gpu/drm/vc4/vc4_hdmi.c
-+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
-@@ -158,8 +158,8 @@ static bool vc4_hdmi_mode_needs_scrambling(const struct drm_display_mode *mode,
- return clock > HDMI_14_MAX_TMDS_CLK;
- }
-
--static bool vc4_hdmi_is_full_range_rgb(struct vc4_hdmi *vc4_hdmi,
-- const struct drm_display_mode *mode)
-+static bool vc4_hdmi_is_full_range(struct vc4_hdmi *vc4_hdmi,
-+ const struct drm_display_mode *mode)
- {
- struct drm_display_info *display = &vc4_hdmi->connector.display_info;
-
-@@ -901,7 +901,7 @@ static void vc4_hdmi_set_avi_infoframe(struct drm_encoder *encoder)
-
- drm_hdmi_avi_infoframe_quant_range(&frame.avi,
- connector, mode,
-- vc4_hdmi_is_full_range_rgb(vc4_hdmi, mode) ?
-+ vc4_hdmi_is_full_range(vc4_hdmi, mode) ?
- HDMI_QUANTIZATION_RANGE_FULL :
- HDMI_QUANTIZATION_RANGE_LIMITED);
- drm_hdmi_avi_infoframe_colorimetry(&frame.avi, cstate);
-@@ -1154,7 +1154,7 @@ static void vc4_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi,
- csc_ctl = VC4_SET_FIELD(VC4_HD_CSC_CTL_ORDER_BGR,
- VC4_HD_CSC_CTL_ORDER);
-
-- if (!vc4_hdmi_is_full_range_rgb(vc4_hdmi, mode)) {
-+ if (!vc4_hdmi_is_full_range(vc4_hdmi, mode)) {
- /* CEA VICs other than #1 requre limited range RGB
- * output unless overridden by an AVI infoframe.
- * Apply a colorspace conversion to squash 0-255 down
-@@ -1193,15 +1193,6 @@ static void vc4_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi,
- * [ 0 1 0 0]
- * [ 0 0 1 0]
- *
-- * Matrix is signed 2p13 fixed point, with signed 9p6 offsets
-- */
--static const u16 vc5_hdmi_csc_full_rgb_unity[3][4] = {
-- { 0x2000, 0x0000, 0x0000, 0x0000 },
-- { 0x0000, 0x2000, 0x0000, 0x0000 },
-- { 0x0000, 0x0000, 0x2000, 0x0000 },
--};
--
--/*
- * CEA VICs other than #1 require limited range RGB output unless
- * overridden by an AVI infoframe. Apply a colorspace conversion to
- * squash 0-255 down to 16-235. The matrix here is:
-@@ -1212,43 +1203,105 @@ static const u16 vc5_hdmi_csc_full_rgb_unity[3][4] = {
- *
- * Matrix is signed 2p13 fixed point, with signed 9p6 offsets
- */
--static const u16 vc5_hdmi_csc_full_rgb_to_limited_rgb[3][4] = {
-- { 0x1b80, 0x0000, 0x0000, 0x0400 },
-- { 0x0000, 0x1b80, 0x0000, 0x0400 },
-- { 0x0000, 0x0000, 0x1b80, 0x0400 },
-+static const u16 vc5_hdmi_csc_full_rgb_to_rgb[2][3][4] = {
-+ {
-+ /* Full range - unity */
-+ { 0x2000, 0x0000, 0x0000, 0x0000 },
-+ { 0x0000, 0x2000, 0x0000, 0x0000 },
-+ { 0x0000, 0x0000, 0x2000, 0x0000 },
-+ }, {
-+ /* Limited range */
-+ { 0x1b80, 0x0000, 0x0000, 0x0400 },
-+ { 0x0000, 0x1b80, 0x0000, 0x0400 },
-+ { 0x0000, 0x0000, 0x1b80, 0x0400 },
-+ }
- };
-
- /*
-- * Conversion between Full Range RGB and Full Range YUV422 using the
-- * BT.709 Colorspace
-+ * Conversion between Full Range RGB and YUV using the BT.601 Colorspace
- *
-+ * Full range
-+ * [ 0.299000 0.587000 0.114000 0.000000 ]
-+ * [ -0.168736 -0.331264 0.500000 128.000000 ]
-+ * [ 0.500000 -0.418688 -0.081312 128.000000 ]
- *
-- * [ 0.181906 0.611804 0.061758 16 ]
-- * [ -0.100268 -0.337232 0.437500 128 ]
-- * [ 0.437500 -0.397386 -0.040114 128 ]
-+ * Limited range
-+ * [ 0.255785 0.502160 0.097523 16.000000 ]
-+ * [ -0.147644 -0.289856 0.437500 128.000000 ]
-+ * [ 0.437500 -0.366352 -0.071148 128.000000 ]
- *
- * Matrix is signed 2p13 fixed point, with signed 9p6 offsets
- */
--static const u16 vc5_hdmi_csc_full_rgb_to_limited_yuv422_bt709[3][4] = {
-- { 0x05d2, 0x1394, 0x01fa, 0x0400 },
-- { 0xfccc, 0xf536, 0x0e00, 0x2000 },
-- { 0x0e00, 0xf34a, 0xfeb8, 0x2000 },
-+static const u16 vc5_hdmi_csc_full_rgb_to_yuv_bt601[2][3][4] = {
-+ {
-+ /* Full range */
-+ { 0x0991, 0x12c9, 0x03a6, 0x0000 },
-+ { 0xfa9b, 0xf567, 0x1000, 0x2000 },
-+ { 0x1000, 0xf29b, 0xfd67, 0x2000 },
-+ }, {
-+ /* Limited range */
-+ { 0x082f, 0x1012, 0x031f, 0x0400 },
-+ { 0xfb48, 0xf6ba, 0x0e00, 0x2000 },
-+ { 0x0e00, 0xf448, 0xfdba, 0x2000 },
-+ }
- };
-
- /*
-- * Conversion between Full Range RGB and Full Range YUV444 using the
-- * BT.709 Colorspace
-+ * Conversion between Full Range RGB and YUV using the BT.709 Colorspace
-+ *
-+ * Full range
-+ * [ 0.212600 0.715200 0.072200 0.000000 ]
-+ * [ -0.114572 -0.385428 0.500000 128.000000 ]
-+ * [ 0.500000 -0.454153 -0.045847 128.000000 ]
- *
-- * [ -0.100268 -0.337232 0.437500 128 ]
-- * [ 0.437500 -0.397386 -0.040114 128 ]
-- * [ 0.181906 0.611804 0.061758 16 ]
-+ * Limited range
-+ * [ 0.181873 0.611831 0.061765 16.000000 ]
-+ * [ -0.100251 -0.337249 0.437500 128.000000 ]
-+ * [ 0.437500 -0.397384 -0.040116 128.000000 ]
- *
- * Matrix is signed 2p13 fixed point, with signed 9p6 offsets
- */
--static const u16 vc5_hdmi_csc_full_rgb_to_limited_yuv444_bt709[3][4] = {
-- { 0xfccc, 0xf536, 0x0e00, 0x2000 },
-- { 0x0e00, 0xf34a, 0xfeb8, 0x2000 },
-- { 0x05d2, 0x1394, 0x01fa, 0x0400 },
-+static const u16 vc5_hdmi_csc_full_rgb_to_yuv_bt709[2][3][4] = {
-+ {
-+ /* Full range */
-+ { 0x06ce, 0x16e3, 0x024f, 0x0000 },
-+ { 0xfc56, 0xf3ac, 0x1000, 0x2000 },
-+ { 0x1000, 0xf179, 0xfe89, 0x2000 },
-+ }, {
-+ /* Limited range */
-+ { 0x05d2, 0x1394, 0x01fa, 0x0400 },
-+ { 0xfccc, 0xf536, 0x0e00, 0x2000 },
-+ { 0x0e00, 0xf34a, 0xfeb8, 0x2000 },
-+ }
-+};
-+
-+/*
-+ * Conversion between Full Range RGB and YUV using the BT.2020 Colorspace
-+ *
-+ * Full range
-+ * [ 0.262700 0.678000 0.059300 0.000000 ]
-+ * [ -0.139630 -0.360370 0.500000 128.000000 ]
-+ * [ 0.500000 -0.459786 -0.040214 128.000000 ]
-+ *
-+ * Limited range
-+ * [ 0.224732 0.580008 0.050729 16.000000 ]
-+ * [ -0.122176 -0.315324 0.437500 128.000000 ]
-+ * [ 0.437500 -0.402312 -0.035188 128.000000 ]
-+ *
-+ * Matrix is signed 2p13 fixed point, with signed 9p6 offsets
-+ */
-+static const u16 vc5_hdmi_csc_full_rgb_to_yuv_bt2020[2][3][4] = {
-+ {
-+ /* Full range */
-+ { 0x0868, 0x15b2, 0x01e6, 0x0000 },
-+ { 0xfb89, 0xf479, 0x1000, 0x2000 },
-+ { 0x1000, 0xf14a, 0xfeb8, 0x2000 },
-+ }, {
-+ /* Limited range */
-+ { 0x0731, 0x128f, 0x01a0, 0x0400 },
-+ { 0xfc18, 0xf5ea, 0x0e00, 0x2000 },
-+ { 0x0e00, 0xf321, 0xfee1, 0x2000 },
-+ }
- };
-
- static void vc5_hdmi_set_csc_coeffs(struct vc4_hdmi *vc4_hdmi,
-@@ -1264,6 +1317,20 @@ static void vc5_hdmi_set_csc_coeffs(struct vc4_hdmi *vc4_hdmi,
- HDMI_WRITE(HDMI_CSC_34_33, (coeffs[2][3] << 16) | coeffs[2][2]);
- }
-
-+static void vc5_hdmi_set_csc_coeffs_swap(struct vc4_hdmi *vc4_hdmi,
-+ const u16 coeffs[3][4])
-+{
-+ lockdep_assert_held(&vc4_hdmi->hw_lock);
-+
-+ /* YUV444 needs the CSC matrices using the channels in a different order */
-+ HDMI_WRITE(HDMI_CSC_12_11, (coeffs[2][1] << 16) | coeffs[2][0]);
-+ HDMI_WRITE(HDMI_CSC_14_13, (coeffs[2][3] << 16) | coeffs[2][2]);
-+ HDMI_WRITE(HDMI_CSC_22_21, (coeffs[0][1] << 16) | coeffs[0][0]);
-+ HDMI_WRITE(HDMI_CSC_24_23, (coeffs[0][3] << 16) | coeffs[0][2]);
-+ HDMI_WRITE(HDMI_CSC_32_31, (coeffs[1][1] << 16) | coeffs[1][0]);
-+ HDMI_WRITE(HDMI_CSC_34_33, (coeffs[1][3] << 16) | coeffs[1][2]);
-+}
-+
- static void vc5_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi,
- struct drm_connector_state *state,
- const struct drm_display_mode *mode)
-@@ -1271,6 +1338,8 @@ static void vc5_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi,
- struct drm_device *drm = vc4_hdmi->connector.dev;
- struct vc4_hdmi_connector_state *vc4_state =
- conn_state_to_vc4_hdmi_conn_state(state);
-+ unsigned int lim_range = vc4_hdmi_is_full_range(vc4_hdmi, mode) ? 0 : 1;
-+ const u16 (*csc)[4];
- unsigned long flags;
- u32 if_cfg = 0;
- u32 if_xbar = 0x543210;
-@@ -1286,31 +1355,56 @@ static void vc5_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi,
-
- switch (vc4_state->output_format) {
- case VC4_HDMI_OUTPUT_YUV444:
-- vc5_hdmi_set_csc_coeffs(vc4_hdmi, vc5_hdmi_csc_full_rgb_to_limited_yuv444_bt709);
-- break;
--
- case VC4_HDMI_OUTPUT_YUV422:
-- csc_ctl |= VC4_SET_FIELD(VC5_MT_CP_CSC_CTL_FILTER_MODE_444_TO_422_STANDARD,
-- VC5_MT_CP_CSC_CTL_FILTER_MODE_444_TO_422) |
-- VC5_MT_CP_CSC_CTL_USE_444_TO_422 |
-- VC5_MT_CP_CSC_CTL_USE_RNG_SUPPRESSION;
-+ switch (state->colorspace) {
-+ default:
-+ case DRM_MODE_COLORIMETRY_NO_DATA:
-+ case DRM_MODE_COLORIMETRY_BT709_YCC:
-+ case DRM_MODE_COLORIMETRY_XVYCC_709:
-+ case DRM_MODE_COLORIMETRY_RGB_WIDE_FIXED:
-+ case DRM_MODE_COLORIMETRY_RGB_WIDE_FLOAT:
-+ csc = vc5_hdmi_csc_full_rgb_to_yuv_bt709[lim_range];
-+ break;
-+ case DRM_MODE_COLORIMETRY_SMPTE_170M_YCC:
-+ case DRM_MODE_COLORIMETRY_XVYCC_601:
-+ case DRM_MODE_COLORIMETRY_SYCC_601:
-+ case DRM_MODE_COLORIMETRY_OPYCC_601:
-+ case DRM_MODE_COLORIMETRY_BT601_YCC:
-+ csc = vc5_hdmi_csc_full_rgb_to_yuv_bt601[lim_range];
-+ break;
-+ case DRM_MODE_COLORIMETRY_BT2020_CYCC:
-+ case DRM_MODE_COLORIMETRY_BT2020_YCC:
-+ case DRM_MODE_COLORIMETRY_BT2020_RGB:
-+ case DRM_MODE_COLORIMETRY_DCI_P3_RGB_D65:
-+ case DRM_MODE_COLORIMETRY_DCI_P3_RGB_THEATER:
-+ csc = vc5_hdmi_csc_full_rgb_to_yuv_bt2020[lim_range];
-+ break;
-+ }
-
-- csc_chan_ctl |= VC4_SET_FIELD(VC5_MT_CP_CHANNEL_CTL_OUTPUT_REMAP_LEGACY_STYLE,
-- VC5_MT_CP_CHANNEL_CTL_OUTPUT_REMAP);
-+ if (vc4_state->output_format == VC4_HDMI_OUTPUT_YUV422) {
-+ csc_ctl |= VC4_SET_FIELD(VC5_MT_CP_CSC_CTL_FILTER_MODE_444_TO_422_STANDARD,
-+ VC5_MT_CP_CSC_CTL_FILTER_MODE_444_TO_422) |
-+ VC5_MT_CP_CSC_CTL_USE_444_TO_422 |
-+ VC5_MT_CP_CSC_CTL_USE_RNG_SUPPRESSION;
-
-- if_cfg |= VC4_SET_FIELD(VC5_DVP_HT_VEC_INTERFACE_CFG_SEL_422_FORMAT_422_LEGACY,
-- VC5_DVP_HT_VEC_INTERFACE_CFG_SEL_422);
-+ csc_chan_ctl |= VC4_SET_FIELD(VC5_MT_CP_CHANNEL_CTL_OUTPUT_REMAP_LEGACY_STYLE,
-+ VC5_MT_CP_CHANNEL_CTL_OUTPUT_REMAP);
-+
-+ if_cfg |= VC4_SET_FIELD(VC5_DVP_HT_VEC_INTERFACE_CFG_SEL_422_FORMAT_422_LEGACY,
-+ VC5_DVP_HT_VEC_INTERFACE_CFG_SEL_422);
-+
-+ vc5_hdmi_set_csc_coeffs(vc4_hdmi, csc);
-+ } else {
-+ vc5_hdmi_set_csc_coeffs_swap(vc4_hdmi, csc);
-+ }
-
-- vc5_hdmi_set_csc_coeffs(vc4_hdmi, vc5_hdmi_csc_full_rgb_to_limited_yuv422_bt709);
- break;
-
- case VC4_HDMI_OUTPUT_RGB:
- if_xbar = 0x354021;
-
-- if (!vc4_hdmi_is_full_range_rgb(vc4_hdmi, mode))
-- vc5_hdmi_set_csc_coeffs(vc4_hdmi, vc5_hdmi_csc_full_rgb_to_limited_rgb);
-- else
-- vc5_hdmi_set_csc_coeffs(vc4_hdmi, vc5_hdmi_csc_full_rgb_unity);
-+ vc5_hdmi_set_csc_coeffs(vc4_hdmi,
-+ vc5_hdmi_csc_full_rgb_to_rgb[lim_range]);
- break;
-
- default:
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Dom Cobley
-Date: Mon, 14 Mar 2022 17:56:10 +0000
-Subject: [PATCH 040/784] vc4/drm: vc4_plane: Keep fractional source coords
- inside state
-
-Signed-off-by: Dom Cobley
----
- drivers/gpu/drm/vc4/vc4_drv.h | 2 +-
- drivers/gpu/drm/vc4/vc4_plane.c | 68 ++++++++++++++++-----------------
- 2 files changed, 34 insertions(+), 36 deletions(-)
-
-diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
-index d54182f995ef..3be66ba8ecdd 100644
---- a/drivers/gpu/drm/vc4/vc4_drv.h
-+++ b/drivers/gpu/drm/vc4/vc4_drv.h
-@@ -384,7 +384,7 @@ struct vc4_plane_state {
-
- /* Clipped coordinates of the plane on the display. */
- int crtc_x, crtc_y, crtc_w, crtc_h;
-- /* Clipped area being scanned from in the FB. */
-+ /* Clipped area being scanned from in the FB in u16.16 format */
- u32 src_x, src_y;
-
- u32 src_w[2], src_h[2];
-diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
-index 7c094e9f8218..66b2fb65bb29 100644
---- a/drivers/gpu/drm/vc4/vc4_plane.c
-+++ b/drivers/gpu/drm/vc4/vc4_plane.c
-@@ -183,9 +183,9 @@ static const struct hvs_format *vc4_get_hvs_format(u32 drm_format)
-
- static enum vc4_scaling_mode vc4_get_scaling_mode(u32 src, u32 dst)
- {
-- if (dst == src)
-+ if (dst == src >> 16)
- return VC4_SCALING_NONE;
-- if (3 * dst >= 2 * src)
-+ if (3 * dst >= 2 * (src >> 16))
- return VC4_SCALING_PPF;
- else
- return VC4_SCALING_TPZ;
-@@ -394,15 +394,10 @@ static int vc4_plane_setup_clipping_and_scaling(struct drm_plane_state *state)
- vc4_state->offsets[i] = bo->dma_addr + fb->offsets[i];
- }
-
-- /*
-- * We don't support subpixel source positioning for scaling,
-- * but fractional coordinates can be generated by clipping
-- * so just round for now
-- */
-- vc4_state->src_x = DIV_ROUND_CLOSEST(state->src.x1, 1 << 16);
-- vc4_state->src_y = DIV_ROUND_CLOSEST(state->src.y1, 1 << 16);
-- vc4_state->src_w[0] = DIV_ROUND_CLOSEST(state->src.x2, 1 << 16) - vc4_state->src_x;
-- vc4_state->src_h[0] = DIV_ROUND_CLOSEST(state->src.y2, 1 << 16) - vc4_state->src_y;
-+ vc4_state->src_x = state->src.x1;
-+ vc4_state->src_y = state->src.y1;
-+ vc4_state->src_w[0] = state->src.x2 - vc4_state->src_x;
-+ vc4_state->src_h[0] = state->src.y2 - vc4_state->src_y;
-
- vc4_state->crtc_x = state->dst.x1;
- vc4_state->crtc_y = state->dst.y1;
-@@ -455,7 +450,7 @@ static void vc4_write_tpz(struct vc4_plane_state *vc4_state, u32 src, u32 dst)
- {
- u32 scale, recip;
-
-- scale = (1 << 16) * src / dst;
-+ scale = src / dst;
-
- /* The specs note that while the reciprocal would be defined
- * as (1<<32)/scale, ~0 is close enough.
-@@ -501,7 +496,7 @@ static u32 vc4_lbm_size(struct drm_plane_state *state)
- if (vc4_state->x_scaling[0] == VC4_SCALING_TPZ)
- pix_per_line = vc4_state->crtc_w;
- else
-- pix_per_line = vc4_state->src_w[0];
-+ pix_per_line = vc4_state->src_w[0] >> 16;
-
- if (!vc4_state->is_yuv) {
- if (vc4_state->y_scaling[0] == VC4_SCALING_TPZ)
-@@ -592,7 +587,8 @@ static void vc4_plane_calc_load(struct drm_plane_state *state)
- for (i = 0; i < fb->format->num_planes; i++) {
- /* Even if the bandwidth/plane required for a single frame is
- *
-- * vc4_state->src_w[i] * vc4_state->src_h[i] * cpp * vrefresh
-+ * (vc4_state->src_w[i] >> 16) * (vc4_state->src_h[i] >> 16) *
-+ * cpp * vrefresh
- *
- * when downscaling, we have to read more pixels per line in
- * the time frame reserved for a single line, so the bandwidth
-@@ -601,11 +597,11 @@ static void vc4_plane_calc_load(struct drm_plane_state *state)
- * load by this number. We're likely over-estimating the read
- * demand, but that's better than under-estimating it.
- */
-- vscale_factor = DIV_ROUND_UP(vc4_state->src_h[i],
-+ vscale_factor = DIV_ROUND_UP(vc4_state->src_h[i] >> 16,
- vc4_state->crtc_h);
-- vc4_state->membus_load += vc4_state->src_w[i] *
-- vc4_state->src_h[i] * vscale_factor *
-- fb->format->cpp[i];
-+ vc4_state->membus_load += (vc4_state->src_w[i] >> 16) *
-+ (vc4_state->src_h[i] >> 16) *
-+ vscale_factor * fb->format->cpp[i];
- vc4_state->hvs_load += vc4_state->crtc_h * vc4_state->crtc_w;
- }
-
-@@ -758,7 +754,8 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
- bool mix_plane_alpha;
- bool covers_screen;
- u32 scl0, scl1, pitch0;
-- u32 tiling, src_y;
-+ u32 tiling, src_x, src_y;
-+ u32 width, height;
- u32 hvs_format = format->hvs;
- unsigned int rotation;
- int ret, i;
-@@ -770,6 +767,9 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
- if (ret)
- return ret;
-
-+ width = vc4_state->src_w[0] >> 16;
-+ height = vc4_state->src_h[0] >> 16;
-+
- /* SCL1 is used for Cb/Cr scaling of planar formats. For RGB
- * and 4:4:4, scl1 should be set to scl0 so both channels of
- * the scaler do the same thing. For YUV, the Y plane needs
-@@ -790,9 +790,11 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
- DRM_MODE_REFLECT_Y);
-
- /* We must point to the last line when Y reflection is enabled. */
-- src_y = vc4_state->src_y;
-+ src_y = vc4_state->src_y >> 16;
- if (rotation & DRM_MODE_REFLECT_Y)
-- src_y += vc4_state->src_h[0] - 1;
-+ src_y += height - 1;
-+
-+ src_x = vc4_state->src_x >> 16;
-
- switch (base_format_mod) {
- case DRM_FORMAT_MOD_LINEAR:
-@@ -807,7 +809,7 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
- (i ? v_subsample : 1) *
- fb->pitches[i];
-
-- vc4_state->offsets[i] += vc4_state->src_x /
-+ vc4_state->offsets[i] += src_x /
- (i ? h_subsample : 1) *
- fb->format->cpp[i];
- }
-@@ -830,7 +832,7 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
- * pitch * tile_h == tile_size * tiles_per_row
- */
- u32 tiles_w = fb->pitches[0] >> (tile_size_shift - tile_h_shift);
-- u32 tiles_l = vc4_state->src_x >> tile_w_shift;
-+ u32 tiles_l = src_x >> tile_w_shift;
- u32 tiles_r = tiles_w - tiles_l;
- u32 tiles_t = src_y >> tile_h_shift;
- /* Intra-tile offsets, which modify the base address (the
-@@ -840,7 +842,7 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
- u32 tile_y = (src_y >> 4) & 1;
- u32 subtile_y = (src_y >> 2) & 3;
- u32 utile_y = src_y & 3;
-- u32 x_off = vc4_state->src_x & tile_w_mask;
-+ u32 x_off = src_x & tile_w_mask;
- u32 y_off = src_y & tile_h_mask;
-
- /* When Y reflection is requested we must set the
-@@ -936,7 +938,7 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
- * of the 12-pixels in that 128-bit word is the
- * first pixel to be used
- */
-- u32 remaining_pixels = vc4_state->src_x % 96;
-+ u32 remaining_pixels = src_x % 96;
- u32 aligned = remaining_pixels / 12;
- u32 last_bits = remaining_pixels % 12;
-
-@@ -958,12 +960,12 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
- return -EINVAL;
- }
- pix_per_tile = tile_w / fb->format->cpp[0];
-- x_off = (vc4_state->src_x % pix_per_tile) /
-+ x_off = (src_x % pix_per_tile) /
- (i ? h_subsample : 1) *
- fb->format->cpp[i];
- }
-
-- tile = vc4_state->src_x / pix_per_tile;
-+ tile = src_x / pix_per_tile;
-
- vc4_state->offsets[i] += param * tile_w * tile;
- vc4_state->offsets[i] += src_y /
-@@ -1024,10 +1026,8 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
- vc4_dlist_write(vc4_state,
- (mix_plane_alpha ? SCALER_POS2_ALPHA_MIX : 0) |
- vc4_hvs4_get_alpha_blend_mode(state) |
-- VC4_SET_FIELD(vc4_state->src_w[0],
-- SCALER_POS2_WIDTH) |
-- VC4_SET_FIELD(vc4_state->src_h[0],
-- SCALER_POS2_HEIGHT));
-+ VC4_SET_FIELD(width, SCALER_POS2_WIDTH) |
-+ VC4_SET_FIELD(height, SCALER_POS2_HEIGHT));
-
- /* Position Word 3: Context. Written by the HVS. */
- vc4_dlist_write(vc4_state, 0xc0c0c0c0);
-@@ -1085,10 +1085,8 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
- /* Position Word 2: Source Image Size */
- vc4_state->pos2_offset = vc4_state->dlist_count;
- vc4_dlist_write(vc4_state,
-- VC4_SET_FIELD(vc4_state->src_w[0],
-- SCALER5_POS2_WIDTH) |
-- VC4_SET_FIELD(vc4_state->src_h[0],
-- SCALER5_POS2_HEIGHT));
-+ VC4_SET_FIELD(width, SCALER5_POS2_WIDTH) |
-+ VC4_SET_FIELD(height, SCALER5_POS2_HEIGHT));
-
- /* Position Word 3: Context. Written by the HVS. */
- vc4_dlist_write(vc4_state, 0xc0c0c0c0);
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Dom Cobley
-Date: Fri, 9 Apr 2021 15:00:40 +0100
-Subject: [PATCH 041/784] vc4/drm: Handle fractional coordinates using the
- phase field
-
-Signed-off-by: Dom Cobley
----
- drivers/gpu/drm/vc4/vc4_plane.c | 61 ++++++++++++++++++++++++++++++---
- 1 file changed, 56 insertions(+), 5 deletions(-)
-
-diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
-index 66b2fb65bb29..db4267aada46 100644
---- a/drivers/gpu/drm/vc4/vc4_plane.c
-+++ b/drivers/gpu/drm/vc4/vc4_plane.c
-@@ -464,14 +464,47 @@ static void vc4_write_tpz(struct vc4_plane_state *vc4_state, u32 src, u32 dst)
- VC4_SET_FIELD(recip, SCALER_TPZ1_RECIP));
- }
-
--static void vc4_write_ppf(struct vc4_plane_state *vc4_state, u32 src, u32 dst)
-+/* phase magnitude bits */
-+#define PHASE_BITS 6
-+
-+static void vc4_write_ppf(struct vc4_plane_state *vc4_state, u32 src, u32 dst, u32 xy, int channel)
- {
-- u32 scale = (1 << 16) * src / dst;
-+ u32 scale = src / dst;
-+ s32 offset, offset2;
-+ s32 phase;
-+
-+ /* Start the phase at 1/2 pixel from the 1st pixel at src_x.
-+ 1/4 pixel for YUV. */
-+ if (channel) {
-+ /* the phase is relative to scale_src->x, so shift it for display list's x value */
-+ offset = (xy & 0x1ffff) >> (16 - PHASE_BITS) >> 1;
-+ offset += -(1 << PHASE_BITS >> 2);
-+ } else {
-+ /* the phase is relative to scale_src->x, so shift it for display list's x value */
-+ offset = (xy & 0xffff) >> (16 - PHASE_BITS);
-+ offset += -(1 << PHASE_BITS >> 1);
-+
-+ /* This is a kludge to make sure the scaling factors are consitent with YUV's luma scaling.
-+ we lose 1bit precision because of this. */
-+ scale &= ~1;
-+ }
-+
-+ /* There may be a also small error introduced by precision of scale.
-+ Add half of that as a compromise */
-+ offset2 = src - dst * scale;
-+ offset2 >>= 16 - PHASE_BITS;
-+ phase = offset + (offset2 >> 1);
-+
-+ /* Ensure +ve values don't touch the sign bit, then truncate negative values */
-+ if (phase >= 1 << PHASE_BITS)
-+ phase = (1 << PHASE_BITS) - 1;
-+
-+ phase &= SCALER_PPF_IPHASE_MASK;
-
- vc4_dlist_write(vc4_state,
- SCALER_PPF_AGC |
- VC4_SET_FIELD(scale, SCALER_PPF_SCALE) |
-- VC4_SET_FIELD(0, SCALER_PPF_IPHASE));
-+ VC4_SET_FIELD(phase, SCALER_PPF_IPHASE));
- }
-
- static u32 vc4_lbm_size(struct drm_plane_state *state)
-@@ -530,13 +563,13 @@ static void vc4_write_scaling_parameters(struct drm_plane_state *state,
- /* Ch0 H-PPF Word 0: Scaling Parameters */
- if (vc4_state->x_scaling[channel] == VC4_SCALING_PPF) {
- vc4_write_ppf(vc4_state,
-- vc4_state->src_w[channel], vc4_state->crtc_w);
-+ vc4_state->src_w[channel], vc4_state->crtc_w, vc4_state->src_x, channel);
- }
-
- /* Ch0 V-PPF Words 0-1: Scaling Parameters, Context */
- if (vc4_state->y_scaling[channel] == VC4_SCALING_PPF) {
- vc4_write_ppf(vc4_state,
-- vc4_state->src_h[channel], vc4_state->crtc_h);
-+ vc4_state->src_h[channel], vc4_state->crtc_h, vc4_state->src_y, channel);
- vc4_dlist_write(vc4_state, 0xc0c0c0c0);
- }
-
-@@ -984,6 +1017,24 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
- return -EINVAL;
- }
-
-+ /* fetch an extra pixel if we don't actually line up with the left edge. */
-+ if ((vc4_state->src_x & 0xffff) && vc4_state->src_x < (state->fb->width << 16))
-+ width++;
-+
-+ /* same for the right side */
-+ if (((vc4_state->src_x + vc4_state->src_w[0]) & 0xffff) &&
-+ vc4_state->src_x + vc4_state->src_w[0] < (state->fb->width << 16))
-+ width++;
-+
-+ /* now for the top */
-+ if ((vc4_state->src_y & 0xffff) && vc4_state->src_y < (state->fb->height << 16))
-+ height++;
-+
-+ /* and the bottom */
-+ if (((vc4_state->src_y + vc4_state->src_h[0]) & 0xffff) &&
-+ vc4_state->src_y + vc4_state->src_h[0] < (state->fb->height << 16))
-+ height++;
-+
- /* Don't waste cycles mixing with plane alpha if the set alpha
- * is opaque or there is no per-pixel alpha information.
- * In any case we use the alpha property value as the fixed alpha.
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Dom Cobley
-Date: Wed, 26 Jan 2022 15:58:13 +0000
-Subject: [PATCH 042/784] drm: Add chroma siting properties
-
-Signed-off-by: Dom Cobley
----
- drivers/gpu/drm/drm_atomic_state_helper.c | 14 +++++++++
- drivers/gpu/drm/drm_atomic_uapi.c | 8 +++++
- drivers/gpu/drm/drm_color_mgmt.c | 36 +++++++++++++++++++++++
- include/drm/drm_color_mgmt.h | 3 ++
- include/drm/drm_plane.h | 36 +++++++++++++++++++++++
- 5 files changed, 97 insertions(+)
-
-diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
-index bf31b9d92094..b1288aae847a 100644
---- a/drivers/gpu/drm/drm_atomic_state_helper.c
-+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
-@@ -267,6 +267,20 @@ void __drm_atomic_helper_plane_state_reset(struct drm_plane_state *plane_state,
- plane_state->color_range = val;
- }
-
-+ if (plane->chroma_siting_h_property) {
-+ if (!drm_object_property_get_default_value(&plane->base,
-+ plane->chroma_siting_h_property,
-+ &val))
-+ plane_state->chroma_siting_h = val;
-+ }
-+
-+ if (plane->chroma_siting_v_property) {
-+ if (!drm_object_property_get_default_value(&plane->base,
-+ plane->chroma_siting_v_property,
-+ &val))
-+ plane_state->chroma_siting_v = val;
-+ }
-+
- if (plane->zpos_property) {
- if (!drm_object_property_get_default_value(&plane->base,
- plane->zpos_property,
-diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
-index 79730fa1dd8e..4531f7441578 100644
---- a/drivers/gpu/drm/drm_atomic_uapi.c
-+++ b/drivers/gpu/drm/drm_atomic_uapi.c
-@@ -562,6 +562,10 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane,
- state->color_encoding = val;
- } else if (property == plane->color_range_property) {
- state->color_range = val;
-+ } else if (property == plane->chroma_siting_h_property) {
-+ state->chroma_siting_h = val;
-+ } else if (property == plane->chroma_siting_v_property) {
-+ state->chroma_siting_v = val;
- } else if (property == config->prop_fb_damage_clips) {
- ret = drm_atomic_replace_property_blob_from_id(dev,
- &state->fb_damage_clips,
-@@ -628,6 +632,10 @@ drm_atomic_plane_get_property(struct drm_plane *plane,
- *val = state->color_encoding;
- } else if (property == plane->color_range_property) {
- *val = state->color_range;
-+ } else if (property == plane->chroma_siting_h_property) {
-+ *val = state->chroma_siting_h;
-+ } else if (property == plane->chroma_siting_v_property) {
-+ *val = state->chroma_siting_v;
- } else if (property == config->prop_fb_damage_clips) {
- *val = (state->fb_damage_clips) ?
- state->fb_damage_clips->base.id : 0;
-diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c
-index 996f12438016..973c6aeff8a1 100644
---- a/drivers/gpu/drm/drm_color_mgmt.c
-+++ b/drivers/gpu/drm/drm_color_mgmt.c
-@@ -590,6 +590,42 @@ int drm_plane_create_color_properties(struct drm_plane *plane,
- }
- EXPORT_SYMBOL(drm_plane_create_color_properties);
-
-+/**
-+ * drm_plane_create_chroma_siting_properties - chroma siting related plane properties
-+ * @plane: plane object
-+ *
-+ * Create and attach plane specific CHROMA_SITING
-+ * properties to @plane.
-+ */
-+int drm_plane_create_chroma_siting_properties(struct drm_plane *plane,
-+ int32_t default_chroma_siting_h,
-+ int32_t default_chroma_siting_v)
-+{
-+ struct drm_device *dev = plane->dev;
-+ struct drm_property *prop;
-+
-+ prop = drm_property_create_range(dev, 0, "CHROMA_SITING_H",
-+ 0, 1<<16);
-+ if (!prop)
-+ return -ENOMEM;
-+ plane->chroma_siting_h_property = prop;
-+ drm_object_attach_property(&plane->base, prop, default_chroma_siting_h);
-+
-+ prop = drm_property_create_range(dev, 0, "CHROMA_SITING_V",
-+ 0, 1<<16);
-+ if (!prop)
-+ return -ENOMEM;
-+ plane->chroma_siting_v_property = prop;
-+ drm_object_attach_property(&plane->base, prop, default_chroma_siting_v);
-+
-+ if (plane->state) {
-+ plane->state->chroma_siting_h = default_chroma_siting_h;
-+ plane->state->chroma_siting_v = default_chroma_siting_v;
-+ }
-+ return 0;
-+}
-+EXPORT_SYMBOL(drm_plane_create_chroma_siting_properties);
-+
- /**
- * drm_color_lut_check - check validity of lookup table
- * @lut: property blob containing LUT to check
-diff --git a/include/drm/drm_color_mgmt.h b/include/drm/drm_color_mgmt.h
-index 81c298488b0c..e2573d0dfb8c 100644
---- a/include/drm/drm_color_mgmt.h
-+++ b/include/drm/drm_color_mgmt.h
-@@ -93,6 +93,9 @@ int drm_plane_create_color_properties(struct drm_plane *plane,
- enum drm_color_encoding default_encoding,
- enum drm_color_range default_range);
-
-+int drm_plane_create_chroma_siting_properties(struct drm_plane *plane,
-+ int32_t default_chroma_siting_h, int32_t default_chroma_siting_v);
-+
- /**
- * enum drm_color_lut_tests - hw-specific LUT tests to perform
- *
-diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
-index 447e664e49d5..fba2bb6731df 100644
---- a/include/drm/drm_plane.h
-+++ b/include/drm/drm_plane.h
-@@ -177,6 +177,24 @@ struct drm_plane_state {
- */
- enum drm_color_range color_range;
-
-+ /**
-+ * @chroma_siting_h:
-+ *
-+ * Location of chroma samples horizontally compared to luma
-+ * 0 means chroma is sited with left luma
-+ * 0x8000 is interstitial. 0x10000 is sited with right luma
-+ */
-+ int32_t chroma_siting_h;
-+
-+ /**
-+ * @chroma_siting_v:
-+ *
-+ * Location of chroma samples vertically compared to luma
-+ * 0 means chroma is sited with top luma
-+ * 0x8000 is interstitial. 0x10000 is sited with bottom luma
-+ */
-+ int32_t chroma_siting_v;
-+
- /**
- * @fb_damage_clips:
- *
-@@ -748,6 +766,24 @@ struct drm_plane {
- * scaling.
- */
- struct drm_property *scaling_filter_property;
-+
-+ /**
-+ * @chroma_siting_h_property:
-+ *
-+ * Optional "CHROMA_SITING_H" property for specifying
-+ * chroma siting for YUV formats.
-+ * See drm_plane_create_chroma_siting_properties().
-+ */
-+ struct drm_property *chroma_siting_h_property;
-+
-+ /**
-+ * @chroma_siting_v_property:
-+ *
-+ * Optional "CHROMA_SITING_V" property for specifying
-+ * chroma siting for YUV formats.
-+ * See drm_plane_create_chroma_siting_properties().
-+ */
-+ struct drm_property *chroma_siting_v_property;
- };
-
- #define obj_to_plane(x) container_of(x, struct drm_plane, base)
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Dom Cobley
-Date: Thu, 27 Jan 2022 15:32:04 +0000
-Subject: [PATCH 043/784] vc4/drm:plane: Make use of chroma siting parameter
-
-Signed-off-by: Dom Cobley
----
- drivers/gpu/drm/vc4/vc4_plane.c | 13 +++++++++----
- 1 file changed, 9 insertions(+), 4 deletions(-)
-
-diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
-index db4267aada46..646abd145800 100644
---- a/drivers/gpu/drm/vc4/vc4_plane.c
-+++ b/drivers/gpu/drm/vc4/vc4_plane.c
-@@ -467,17 +467,18 @@ static void vc4_write_tpz(struct vc4_plane_state *vc4_state, u32 src, u32 dst)
- /* phase magnitude bits */
- #define PHASE_BITS 6
-
--static void vc4_write_ppf(struct vc4_plane_state *vc4_state, u32 src, u32 dst, u32 xy, int channel)
-+static void vc4_write_ppf(struct vc4_plane_state *vc4_state, u32 src, u32 dst, u32 xy, int channel, int chroma_offset)
- {
- u32 scale = src / dst;
- s32 offset, offset2;
- s32 phase;
-
- /* Start the phase at 1/2 pixel from the 1st pixel at src_x.
-- 1/4 pixel for YUV. */
-+ 1/4 pixel for YUV, plus the offset for chroma siting */
- if (channel) {
- /* the phase is relative to scale_src->x, so shift it for display list's x value */
- offset = (xy & 0x1ffff) >> (16 - PHASE_BITS) >> 1;
-+ offset -= chroma_offset >> (17 - PHASE_BITS);
- offset += -(1 << PHASE_BITS >> 2);
- } else {
- /* the phase is relative to scale_src->x, so shift it for display list's x value */
-@@ -563,13 +564,15 @@ static void vc4_write_scaling_parameters(struct drm_plane_state *state,
- /* Ch0 H-PPF Word 0: Scaling Parameters */
- if (vc4_state->x_scaling[channel] == VC4_SCALING_PPF) {
- vc4_write_ppf(vc4_state,
-- vc4_state->src_w[channel], vc4_state->crtc_w, vc4_state->src_x, channel);
-+ vc4_state->src_w[channel], vc4_state->crtc_w, vc4_state->src_x, channel,
-+ state->chroma_siting_h);
- }
-
- /* Ch0 V-PPF Words 0-1: Scaling Parameters, Context */
- if (vc4_state->y_scaling[channel] == VC4_SCALING_PPF) {
- vc4_write_ppf(vc4_state,
-- vc4_state->src_h[channel], vc4_state->crtc_h, vc4_state->src_y, channel);
-+ vc4_state->src_h[channel], vc4_state->crtc_h, vc4_state->src_y, channel,
-+ state->chroma_siting_v);
- vc4_dlist_write(vc4_state, 0xc0c0c0c0);
- }
-
-@@ -1649,6 +1652,8 @@ struct drm_plane *vc4_plane_init(struct drm_device *dev,
- DRM_COLOR_YCBCR_BT709,
- DRM_COLOR_YCBCR_LIMITED_RANGE);
-
-+ drm_plane_create_chroma_siting_properties(plane, 0, 0);
-+
- if (type == DRM_PLANE_TYPE_PRIMARY)
- drm_plane_create_zpos_immutable_property(plane, 0);
-
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Dave Stevenson
-Date: Fri, 1 Apr 2022 11:31:38 +0100
-Subject: [PATCH 044/784] drm/vc4: Force trigger of dlist update on margins
- change
-
-When the margins are changed, the dlist needs to be regenerated
-with the changed updated dest regions for each of the planes.
-
-Setting the zpos_changed flag is sufficient to trigger that
-without doing a full modeset, therefore set it should the
-margins be changed.
-
-Signed-off-by: Dave Stevenson
----
- drivers/gpu/drm/vc4/vc4_crtc.c | 14 ++++++++++----
- drivers/gpu/drm/vc4/vc4_drv.h | 7 +------
- 2 files changed, 11 insertions(+), 10 deletions(-)
-
-diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
-index 0b16fb5acd7d..97b1107a30bb 100644
---- a/drivers/gpu/drm/vc4/vc4_crtc.c
-+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
-@@ -757,10 +757,16 @@ static int vc4_crtc_atomic_check(struct drm_crtc *crtc,
- if (conn_state->crtc != crtc)
- continue;
-
-- vc4_state->margins.left = conn_state->tv.margins.left;
-- vc4_state->margins.right = conn_state->tv.margins.right;
-- vc4_state->margins.top = conn_state->tv.margins.top;
-- vc4_state->margins.bottom = conn_state->tv.margins.bottom;
-+ if (memcmp(&vc4_state->margins, &conn_state->tv.margins,
-+ sizeof(vc4_state->margins))) {
-+ memcpy(&vc4_state->margins, &conn_state->tv.margins,
-+ sizeof(vc4_state->margins));
-+
-+ /* Need to force the dlist entries for all planes to be
-+ * updated so that the dest rectangles are changed.
-+ */
-+ crtc_state->zpos_changed = true;
-+ }
- break;
- }
-
-diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
-index 3be66ba8ecdd..a3d058d3c788 100644
---- a/drivers/gpu/drm/vc4/vc4_drv.h
-+++ b/drivers/gpu/drm/vc4/vc4_drv.h
-@@ -581,12 +581,7 @@ struct vc4_crtc_state {
- bool txp_armed;
- unsigned int assigned_channel;
-
-- struct {
-- unsigned int left;
-- unsigned int right;
-- unsigned int top;
-- unsigned int bottom;
-- } margins;
-+ struct drm_connector_tv_margins margins;
-
- unsigned long hvs_load;
-
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Daniel Vetter
-Date: Fri, 23 Oct 2020 14:39:23 +0200
-Subject: [PATCH 045/784] drm/atomic-helpers: remove legacy_cursor_update hacks
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The stuff never really worked, and leads to lots of fun because it
-out-of-order frees atomic states. Which upsets KASAN, among other
-things.
-
-For async updates we now have a more solid solution with the
-->atomic_async_check and ->atomic_async_commit hooks. Support for that
-for msm and vc4 landed. nouveau and i915 have their own commit
-routines, doing something similar.
-
-For everyone else it's probably better to remove the use-after-free
-bug, and encourage folks to use the async support instead. The
-affected drivers which register a legacy cursor plane and don't either
-use the new async stuff or their own commit routine are: amdgpu,
-atmel, mediatek, qxl, rockchip, sti, sun4i, tegra, virtio, and vmwgfx.
-
-Inspired by an amdgpu bug report.
-
-v2: Drop RFC, I think with amdgpu converted over to use
-atomic_async_check/commit done in
-
-commit 674e78acae0dfb4beb56132e41cbae5b60f7d662
-Author: Nicholas Kazlauskas
-Date: Wed Dec 5 14:59:07 2018 -0500
-
- drm/amd/display: Add fast path for cursor plane updates
-
-we don't have any driver anymore where we have userspace expecting
-solid legacy cursor support _and_ they are using the atomic helpers in
-their fully glory. So we can retire this.
-
-v3: Paper over msm and i915 regression. The complete_all is the only
-thing missing afaict.
-
-v4: Rebased on recent kernel, added extra link for vc4 bug.
-
-Link: https://bugzilla.kernel.org/show_bug.cgi?id=199425
-Link: https://lore.kernel.org/all/20220221134155.125447-9-maxime@cerno.tech/
-Cc: mikita.lipski@amd.com
-Cc: Michel Dänzer
-Cc: harry.wentland@amd.com
-Cc: Rob Clark
-Cc: "Kazlauskas, Nicholas"
-Tested-by: Maxime Ripard
-Signed-off-by: Daniel Vetter
-Signed-off-by: Maxime Ripard
----
- drivers/gpu/drm/drm_atomic_helper.c | 13 -------------
- drivers/gpu/drm/i915/display/intel_display.c | 13 +++++++++++++
- drivers/gpu/drm/msm/msm_atomic.c | 2 ++
- 3 files changed, 15 insertions(+), 13 deletions(-)
-
-diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
-index f3e59236a8ee..e8d77ab10389 100644
---- a/drivers/gpu/drm/drm_atomic_helper.c
-+++ b/drivers/gpu/drm/drm_atomic_helper.c
-@@ -1608,13 +1608,6 @@ drm_atomic_helper_wait_for_vblanks(struct drm_device *dev,
- int i, ret;
- unsigned int crtc_mask = 0;
-
-- /*
-- * Legacy cursor ioctls are completely unsynced, and userspace
-- * relies on that (by doing tons of cursor updates).
-- */
-- if (old_state->legacy_cursor_update)
-- return;
--
- for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state, new_crtc_state, i) {
- if (!new_crtc_state->active)
- continue;
-@@ -2265,12 +2258,6 @@ int drm_atomic_helper_setup_commit(struct drm_atomic_state *state,
- continue;
- }
-
-- /* Legacy cursor updates are fully unsynced. */
-- if (state->legacy_cursor_update) {
-- complete_all(&commit->flip_done);
-- continue;
-- }
--
- if (!new_crtc_state->event) {
- commit->event = kzalloc(sizeof(*commit->event),
- GFP_KERNEL);
-diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
-index 455d9ae6c41c..0a550989f904 100644
---- a/drivers/gpu/drm/i915/display/intel_display.c
-+++ b/drivers/gpu/drm/i915/display/intel_display.c
-@@ -7766,6 +7766,19 @@ static int intel_atomic_commit(struct drm_device *dev,
- state->base.legacy_cursor_update = false;
- }
-
-+ /*
-+ * FIXME: Cut over to (async) commit helpers instead of hand-rolling
-+ * everything.
-+ */
-+ if (state->base.legacy_cursor_update) {
-+ struct intel_crtc_state *new_crtc_state;
-+ struct intel_crtc *crtc;
-+ int i;
-+
-+ for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i)
-+ complete_all(&new_crtc_state->uapi.commit->flip_done);
-+ }
-+
- ret = intel_atomic_prepare_commit(state);
- if (ret) {
- drm_dbg_atomic(&dev_priv->drm,
-diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c
-index 1686fbb611fd..b3cfabebe5d6 100644
---- a/drivers/gpu/drm/msm/msm_atomic.c
-+++ b/drivers/gpu/drm/msm/msm_atomic.c
-@@ -222,6 +222,8 @@ void msm_atomic_commit_tail(struct drm_atomic_state *state)
- /* async updates are limited to single-crtc updates: */
- WARN_ON(crtc_mask != drm_crtc_mask(async_crtc));
-
-+ complete_all(&async_crtc->state->commit->flip_done);
-+
- /*
- * Start timer if we don't already have an update pending
- * on this crtc:
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Dom Cobley
-Date: Thu, 5 May 2022 18:50:04 +0100
-Subject: [PATCH 046/784] drm/vc4_hdmi: Force a modeset when Broadcast RGB
- setting changes
-
-Without this the change is not visible until the next modeset
-
-Signed-off-by: Dom Cobley
----
- drivers/gpu/drm/vc4/vc4_hdmi.c | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
-index 431f901068a0..3546c7af0329 100644
---- a/drivers/gpu/drm/vc4/vc4_hdmi.c
-+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
-@@ -536,14 +536,17 @@ static int vc4_hdmi_connector_atomic_check(struct drm_connector *connector,
- {
- struct drm_connector_state *old_state =
- drm_atomic_get_old_connector_state(state, connector);
-+ struct vc4_hdmi_connector_state *old_vc4_state = conn_state_to_vc4_hdmi_conn_state(old_state);
- struct drm_connector_state *new_state =
- drm_atomic_get_new_connector_state(state, connector);
-+ struct vc4_hdmi_connector_state *new_vc4_state = conn_state_to_vc4_hdmi_conn_state(new_state);
- struct drm_crtc *crtc = new_state->crtc;
-
- if (!crtc)
- return 0;
-
- if (old_state->colorspace != new_state->colorspace ||
-+ old_vc4_state->broadcast_rgb != new_vc4_state->broadcast_rgb ||
- !drm_connector_atomic_hdr_metadata_equal(old_state, new_state)) {
- struct drm_crtc_state *crtc_state;
-
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Dave Stevenson
-Date: Fri, 1 Apr 2022 17:10:37 +0100
-Subject: [PATCH 047/784] drm/atomic: If margins are updated, update all
- planes.
-
-Margins may be implemented by scaling the planes, but as there
-is no way of intercepting the set_property for a standard property,
-and all planes are checked in drm_atomic_check_only before the
-connectors, there's now way to add the planes into the state
-from the driver.
-
-If the margin properties change, add all corresponding planes to
-the state.
-
-Signed-off-by: Dave Stevenson
----
- drivers/gpu/drm/drm_atomic_uapi.c | 11 +++++++++++
- 1 file changed, 11 insertions(+)
-
-diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
-index 4531f7441578..f6856df35093 100644
---- a/drivers/gpu/drm/drm_atomic_uapi.c
-+++ b/drivers/gpu/drm/drm_atomic_uapi.c
-@@ -679,6 +679,7 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector,
- {
- struct drm_device *dev = connector->dev;
- struct drm_mode_config *config = &dev->mode_config;
-+ bool margins_updated = false;
- bool replaced = false;
- int ret;
-
-@@ -698,12 +699,16 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector,
- state->tv.subconnector = val;
- } else if (property == config->tv_left_margin_property) {
- state->tv.margins.left = val;
-+ margins_updated = true;
- } else if (property == config->tv_right_margin_property) {
- state->tv.margins.right = val;
-+ margins_updated = true;
- } else if (property == config->tv_top_margin_property) {
- state->tv.margins.top = val;
-+ margins_updated = true;
- } else if (property == config->tv_bottom_margin_property) {
- state->tv.margins.bottom = val;
-+ margins_updated = true;
- } else if (property == config->tv_mode_property) {
- state->tv.mode = val;
- } else if (property == config->tv_brightness_property) {
-@@ -784,6 +789,12 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector,
- return -EINVAL;
- }
-
-+ if (margins_updated && state->crtc) {
-+ ret = drm_atomic_add_affected_planes(state->state, state->crtc);
-+
-+ return ret;
-+ }
-+
- return 0;
- }
-
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Maxime Ripard
-Date: Mon, 6 Dec 2021 16:32:10 +0100
-Subject: [PATCH 048/784] drm/vc4: hvs: Ignore atomic_flush if we're disabled
-
-atomic_flush will be called for each CRTC even if they aren't enabled.
-
-The whole code we have there will thus run without a properly affected
-channel, which can then result in all sorts of weird behaviour.
-
-Signed-off-by: Maxime Ripard
----
- drivers/gpu/drm/vc4/vc4_hvs.c | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c
-index 38669ea71c4a..67effc334715 100644
---- a/drivers/gpu/drm/vc4/vc4_hvs.c
-+++ b/drivers/gpu/drm/vc4/vc4_hvs.c
-@@ -778,6 +778,9 @@ void vc4_hvs_atomic_flush(struct drm_crtc *crtc,
- return;
- }
-
-+ if (vc4_state->assigned_channel == VC4_HVS_CHANNEL_DISABLED)
-+ return;
-+
- if (debug_dump_regs) {
- DRM_INFO("CRTC %d HVS before:\n", drm_crtc_index(crtc));
- vc4_hvs_dump_state(hvs);
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Dave Stevenson
-Date: Fri, 3 Jun 2022 16:49:09 +0100
-Subject: [PATCH 049/784] drm: vc4: 0 is a valid value for pixel_order_hvs5, so
- fix conditionals
-
-vc4_plane_mode_set for HVS5 was using pixel_order unless pixel_order_hvs5
-was non-zero, except 0 is a valid value for the pixel_order.
-
-Specify pixel_order_hvs5 for all formats and remove the conditional.
-
-Reported-by: vrazzer
-Signed-off-by: Dave Stevenson
----
- drivers/gpu/drm/vc4/vc4_plane.c | 20 ++++++++++++++------
- 1 file changed, 14 insertions(+), 6 deletions(-)
-
-diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
-index 646abd145800..a21898d885c7 100644
---- a/drivers/gpu/drm/vc4/vc4_plane.c
-+++ b/drivers/gpu/drm/vc4/vc4_plane.c
-@@ -65,11 +65,13 @@ static const struct hvs_format {
- .drm = DRM_FORMAT_RGB565,
- .hvs = HVS_PIXEL_FORMAT_RGB565,
- .pixel_order = HVS_PIXEL_ORDER_XRGB,
-+ .pixel_order_hvs5 = HVS_PIXEL_ORDER_XRGB,
- },
- {
- .drm = DRM_FORMAT_BGR565,
- .hvs = HVS_PIXEL_FORMAT_RGB565,
- .pixel_order = HVS_PIXEL_ORDER_XBGR,
-+ .pixel_order_hvs5 = HVS_PIXEL_ORDER_XBGR,
- },
- {
- .drm = DRM_FORMAT_ARGB1555,
-@@ -87,56 +89,67 @@ static const struct hvs_format {
- .drm = DRM_FORMAT_RGB888,
- .hvs = HVS_PIXEL_FORMAT_RGB888,
- .pixel_order = HVS_PIXEL_ORDER_XRGB,
-+ .pixel_order_hvs5 = HVS_PIXEL_ORDER_XRGB,
- },
- {
- .drm = DRM_FORMAT_BGR888,
- .hvs = HVS_PIXEL_FORMAT_RGB888,
- .pixel_order = HVS_PIXEL_ORDER_XBGR,
-+ .pixel_order_hvs5 = HVS_PIXEL_ORDER_XBGR,
- },
- {
- .drm = DRM_FORMAT_YUV422,
- .hvs = HVS_PIXEL_FORMAT_YCBCR_YUV422_3PLANE,
- .pixel_order = HVS_PIXEL_ORDER_XYCBCR,
-+ .pixel_order_hvs5 = HVS_PIXEL_ORDER_XYCBCR,
- },
- {
- .drm = DRM_FORMAT_YVU422,
- .hvs = HVS_PIXEL_FORMAT_YCBCR_YUV422_3PLANE,
- .pixel_order = HVS_PIXEL_ORDER_XYCRCB,
-+ .pixel_order_hvs5 = HVS_PIXEL_ORDER_XYCRCB,
- },
- {
- .drm = DRM_FORMAT_YUV420,
- .hvs = HVS_PIXEL_FORMAT_YCBCR_YUV420_3PLANE,
- .pixel_order = HVS_PIXEL_ORDER_XYCBCR,
-+ .pixel_order_hvs5 = HVS_PIXEL_ORDER_XYCBCR,
- },
- {
- .drm = DRM_FORMAT_YVU420,
- .hvs = HVS_PIXEL_FORMAT_YCBCR_YUV420_3PLANE,
- .pixel_order = HVS_PIXEL_ORDER_XYCRCB,
-+ .pixel_order_hvs5 = HVS_PIXEL_ORDER_XYCRCB,
- },
- {
- .drm = DRM_FORMAT_NV12,
- .hvs = HVS_PIXEL_FORMAT_YCBCR_YUV420_2PLANE,
- .pixel_order = HVS_PIXEL_ORDER_XYCBCR,
-+ .pixel_order_hvs5 = HVS_PIXEL_ORDER_XYCBCR,
- },
- {
- .drm = DRM_FORMAT_NV21,
- .hvs = HVS_PIXEL_FORMAT_YCBCR_YUV420_2PLANE,
- .pixel_order = HVS_PIXEL_ORDER_XYCRCB,
-+ .pixel_order_hvs5 = HVS_PIXEL_ORDER_XYCRCB,
- },
- {
- .drm = DRM_FORMAT_NV16,
- .hvs = HVS_PIXEL_FORMAT_YCBCR_YUV422_2PLANE,
- .pixel_order = HVS_PIXEL_ORDER_XYCBCR,
-+ .pixel_order_hvs5 = HVS_PIXEL_ORDER_XYCBCR,
- },
- {
- .drm = DRM_FORMAT_NV61,
- .hvs = HVS_PIXEL_FORMAT_YCBCR_YUV422_2PLANE,
- .pixel_order = HVS_PIXEL_ORDER_XYCRCB,
-+ .pixel_order_hvs5 = HVS_PIXEL_ORDER_XYCRCB,
- },
- {
- .drm = DRM_FORMAT_P030,
- .hvs = HVS_PIXEL_FORMAT_YCBCR_10BIT,
- .pixel_order = HVS_PIXEL_ORDER_XYCBCR,
-+ .pixel_order_hvs5 = HVS_PIXEL_ORDER_XYCBCR,
- .hvs5_only = true,
- },
- {
-@@ -1087,15 +1100,10 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
- vc4_dlist_write(vc4_state, 0xc0c0c0c0);
-
- } else {
-- u32 hvs_pixel_order = format->pixel_order;
--
-- if (format->pixel_order_hvs5)
-- hvs_pixel_order = format->pixel_order_hvs5;
--
- /* Control word */
- vc4_dlist_write(vc4_state,
- SCALER_CTL0_VALID |
-- (hvs_pixel_order << SCALER_CTL0_ORDER_SHIFT) |
-+ (format->pixel_order_hvs5 << SCALER_CTL0_ORDER_SHIFT) |
- (hvs_format << SCALER_CTL0_PIXEL_FORMAT_SHIFT) |
- VC4_SET_FIELD(tiling, SCALER_CTL0_TILING) |
- (vc4_state->is_unity ?
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Dave Stevenson
-Date: Mon, 6 Jun 2022 12:23:28 +0100
-Subject: [PATCH 050/784] drm: vc4: Omit pixel_order from the hvs_format for
- hvs5 only formats
-
-pixel_order is used for the earlier versions of the HVS, so is
-redundant on the 10:10:10:2 and 10bit YUV formats that are only
-supported on HVS5.
-Remove the assignment from the table to avoid confusion.
-
-Signed-off-by: Dave Stevenson
----
- drivers/gpu/drm/vc4/vc4_plane.c | 5 -----
- 1 file changed, 5 deletions(-)
-
-diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
-index a21898d885c7..cdd1dd6a7e48 100644
---- a/drivers/gpu/drm/vc4/vc4_plane.c
-+++ b/drivers/gpu/drm/vc4/vc4_plane.c
-@@ -148,35 +148,30 @@ static const struct hvs_format {
- {
- .drm = DRM_FORMAT_P030,
- .hvs = HVS_PIXEL_FORMAT_YCBCR_10BIT,
-- .pixel_order = HVS_PIXEL_ORDER_XYCBCR,
- .pixel_order_hvs5 = HVS_PIXEL_ORDER_XYCBCR,
- .hvs5_only = true,
- },
- {
- .drm = DRM_FORMAT_XRGB2101010,
- .hvs = HVS_PIXEL_FORMAT_RGBA1010102,
-- .pixel_order = HVS_PIXEL_ORDER_ABGR,
- .pixel_order_hvs5 = HVS_PIXEL_ORDER_ARGB,
- .hvs5_only = true,
- },
- {
- .drm = DRM_FORMAT_ARGB2101010,
- .hvs = HVS_PIXEL_FORMAT_RGBA1010102,
-- .pixel_order = HVS_PIXEL_ORDER_ABGR,
- .pixel_order_hvs5 = HVS_PIXEL_ORDER_ARGB,
- .hvs5_only = true,
- },
- {
- .drm = DRM_FORMAT_ABGR2101010,
- .hvs = HVS_PIXEL_FORMAT_RGBA1010102,
-- .pixel_order = HVS_PIXEL_ORDER_ARGB,
- .pixel_order_hvs5 = HVS_PIXEL_ORDER_ABGR,
- .hvs5_only = true,
- },
- {
- .drm = DRM_FORMAT_XBGR2101010,
- .hvs = HVS_PIXEL_FORMAT_RGBA1010102,
-- .pixel_order = HVS_PIXEL_ORDER_ARGB,
- .pixel_order_hvs5 = HVS_PIXEL_ORDER_ABGR,
- .hvs5_only = true,
- },
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Dave Stevenson
-Date: Fri, 3 Jun 2022 16:57:04 +0100
-Subject: [PATCH 051/784] drm: vc4: Add 3:3:2 and 4:4:4:4 RGB/RGBX/RGBA formats
-
-The hardware supports the 332 8bpp and 4:4:4:4 16bpp formats,
-but the table of supported formats didn't include them.
-Add them in.
-
-In theory they are supported for T-format as well as linear,
-but without a way to test them just add them as linear for now.
-
-Suggested-by: vrazzer
-Signed-off-by: Dave Stevenson
----
- drivers/gpu/drm/vc4/vc4_plane.c | 70 +++++++++++++++++++++++++++++++++
- 1 file changed, 70 insertions(+)
-
-diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
-index cdd1dd6a7e48..6432055454ac 100644
---- a/drivers/gpu/drm/vc4/vc4_plane.c
-+++ b/drivers/gpu/drm/vc4/vc4_plane.c
-@@ -175,6 +175,66 @@ static const struct hvs_format {
- .pixel_order_hvs5 = HVS_PIXEL_ORDER_ABGR,
- .hvs5_only = true,
- },
-+ {
-+ .drm = DRM_FORMAT_RGB332,
-+ .hvs = HVS_PIXEL_FORMAT_RGB332,
-+ .pixel_order = HVS_PIXEL_ORDER_ARGB,
-+ .pixel_order_hvs5 = HVS_PIXEL_ORDER_ARGB,
-+ },
-+ {
-+ .drm = DRM_FORMAT_BGR233,
-+ .hvs = HVS_PIXEL_FORMAT_RGB332,
-+ .pixel_order = HVS_PIXEL_ORDER_ABGR,
-+ .pixel_order_hvs5 = HVS_PIXEL_ORDER_ABGR,
-+ },
-+ {
-+ .drm = DRM_FORMAT_XRGB4444,
-+ .hvs = HVS_PIXEL_FORMAT_RGBA4444,
-+ .pixel_order = HVS_PIXEL_ORDER_ABGR,
-+ .pixel_order_hvs5 = HVS_PIXEL_ORDER_ARGB,
-+ },
-+ {
-+ .drm = DRM_FORMAT_ARGB4444,
-+ .hvs = HVS_PIXEL_FORMAT_RGBA4444,
-+ .pixel_order = HVS_PIXEL_ORDER_ABGR,
-+ .pixel_order_hvs5 = HVS_PIXEL_ORDER_ARGB,
-+ },
-+ {
-+ .drm = DRM_FORMAT_XBGR4444,
-+ .hvs = HVS_PIXEL_FORMAT_RGBA4444,
-+ .pixel_order = HVS_PIXEL_ORDER_ARGB,
-+ .pixel_order_hvs5 = HVS_PIXEL_ORDER_ABGR,
-+ },
-+ {
-+ .drm = DRM_FORMAT_ABGR4444,
-+ .hvs = HVS_PIXEL_FORMAT_RGBA4444,
-+ .pixel_order = HVS_PIXEL_ORDER_ARGB,
-+ .pixel_order_hvs5 = HVS_PIXEL_ORDER_ABGR,
-+ },
-+ {
-+ .drm = DRM_FORMAT_BGRX4444,
-+ .hvs = HVS_PIXEL_FORMAT_RGBA4444,
-+ .pixel_order = HVS_PIXEL_ORDER_RGBA,
-+ .pixel_order_hvs5 = HVS_PIXEL_ORDER_BGRA,
-+ },
-+ {
-+ .drm = DRM_FORMAT_BGRA4444,
-+ .hvs = HVS_PIXEL_FORMAT_RGBA4444,
-+ .pixel_order = HVS_PIXEL_ORDER_RGBA,
-+ .pixel_order_hvs5 = HVS_PIXEL_ORDER_BGRA,
-+ },
-+ {
-+ .drm = DRM_FORMAT_RGBX4444,
-+ .hvs = HVS_PIXEL_FORMAT_RGBA4444,
-+ .pixel_order = HVS_PIXEL_ORDER_BGRA,
-+ .pixel_order_hvs5 = HVS_PIXEL_ORDER_RGBA,
-+ },
-+ {
-+ .drm = DRM_FORMAT_RGBA4444,
-+ .hvs = HVS_PIXEL_FORMAT_RGBA4444,
-+ .pixel_order = HVS_PIXEL_ORDER_BGRA,
-+ .pixel_order_hvs5 = HVS_PIXEL_ORDER_RGBA,
-+ },
- };
-
- static const struct hvs_format *vc4_get_hvs_format(u32 drm_format)
-@@ -1575,6 +1635,16 @@ static bool vc4_format_mod_supported(struct drm_plane *plane,
- case DRM_FORMAT_BGRX1010102:
- case DRM_FORMAT_RGBA1010102:
- case DRM_FORMAT_BGRA1010102:
-+ case DRM_FORMAT_XRGB4444:
-+ case DRM_FORMAT_ARGB4444:
-+ case DRM_FORMAT_XBGR4444:
-+ case DRM_FORMAT_ABGR4444:
-+ case DRM_FORMAT_RGBX4444:
-+ case DRM_FORMAT_RGBA4444:
-+ case DRM_FORMAT_BGRX4444:
-+ case DRM_FORMAT_BGRA4444:
-+ case DRM_FORMAT_RGB332:
-+ case DRM_FORMAT_BGR233:
- case DRM_FORMAT_YUV422:
- case DRM_FORMAT_YVU422:
- case DRM_FORMAT_YUV420:
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Dave Stevenson
-Date: Mon, 6 Jun 2022 14:53:56 +0100
-Subject: [PATCH 052/784] drm: vc4: Add comments for which HVS_PIXEL_ORDER_xxx
- defines apply
-
-The HVS_PIXEL_ORDER_xxx defines apply to specific HVS_PIXEL_FORMAT_xxx
-modes, so add comments to make this obvious.
-
-Signed-off-by: Dave Stevenson
----
- drivers/gpu/drm/vc4/vc4_regs.h | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/drivers/gpu/drm/vc4/vc4_regs.h b/drivers/gpu/drm/vc4/vc4_regs.h
-index e162d3f3bd3c..098173290411 100644
---- a/drivers/gpu/drm/vc4/vc4_regs.h
-+++ b/drivers/gpu/drm/vc4/vc4_regs.h
-@@ -870,16 +870,19 @@ enum hvs_pixel_format {
- /* Note: the LSB is the rightmost character shown. Only valid for
- * HVS_PIXEL_FORMAT_RGB8888, not RGB888.
- */
-+/* For modes 332, 4444, 555, 5551, 6666, 8888, 10:10:10:2 */
- #define HVS_PIXEL_ORDER_RGBA 0
- #define HVS_PIXEL_ORDER_BGRA 1
- #define HVS_PIXEL_ORDER_ARGB 2
- #define HVS_PIXEL_ORDER_ABGR 3
-
-+/* For modes 666 and 888 (4 & 5) */
- #define HVS_PIXEL_ORDER_XBRG 0
- #define HVS_PIXEL_ORDER_XRBG 1
- #define HVS_PIXEL_ORDER_XRGB 2
- #define HVS_PIXEL_ORDER_XBGR 3
-
-+/* For YCbCr modes (8-12, and 17) */
- #define HVS_PIXEL_ORDER_XYCBCR 0
- #define HVS_PIXEL_ORDER_XYCRCB 1
- #define HVS_PIXEL_ORDER_YXCBCR 2
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Phil Elwell <8911409+pelwell@users.noreply.github.com>
-Date: Wed, 24 Aug 2022 11:14:40 +0100
-Subject: [PATCH 053/784] drm/vc4: Add async update support for cursor planes
-
-Now that cursors are implemented as regular planes, all cursor
-movements result in atomic updates. As the firmware-kms driver
-doesn't support asynchronous updates, these are synchronous, which
-limits the update rate to the screen refresh rate. Xorg seems unaware
-of this (or at least of the effect of this), because if the mouse is
-configured with a higher update rate than the screen then continuous
-mouse movement results in an increasing backlog of mouse events -
-cue extreme lag.
-
-Add minimal support for asynchronous updates - limited to cursor
-planes - to eliminate the lag.
-
-See: https://github.com/raspberrypi/linux/pull/4971
- https://github.com/raspberrypi/linux/issues/4988
-
-Signed-off-by: Phil Elwell
----
- drivers/gpu/drm/vc4/vc4_firmware_kms.c | 46 ++++++++++++++++++++++++++
- 1 file changed, 46 insertions(+)
-
-diff --git a/drivers/gpu/drm/vc4/vc4_firmware_kms.c b/drivers/gpu/drm/vc4/vc4_firmware_kms.c
-index 6856de434928..e7f56b3eb213 100644
---- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c
-+++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c
-@@ -675,6 +675,50 @@ static int vc4_plane_atomic_check(struct drm_plane *plane,
- return vc4_plane_to_mb(plane, &vc4_plane->mb, new_plane_state);
- }
-
-+static void vc4_plane_atomic_async_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);
-+
-+ swap(plane->state->fb, new_plane_state->fb);
-+ plane->state->crtc_x = new_plane_state->crtc_x;
-+ plane->state->crtc_y = new_plane_state->crtc_y;
-+ plane->state->crtc_w = new_plane_state->crtc_w;
-+ plane->state->crtc_h = new_plane_state->crtc_h;
-+ plane->state->src_x = new_plane_state->src_x;
-+ plane->state->src_y = new_plane_state->src_y;
-+ plane->state->src_w = new_plane_state->src_w;
-+ plane->state->src_h = new_plane_state->src_h;
-+ plane->state->alpha = new_plane_state->alpha;
-+ plane->state->pixel_blend_mode = new_plane_state->pixel_blend_mode;
-+ plane->state->rotation = new_plane_state->rotation;
-+ plane->state->zpos = new_plane_state->zpos;
-+ plane->state->normalized_zpos = new_plane_state->normalized_zpos;
-+ plane->state->color_encoding = new_plane_state->color_encoding;
-+ plane->state->color_range = new_plane_state->color_range;
-+ plane->state->src = new_plane_state->src;
-+ plane->state->dst = new_plane_state->dst;
-+ plane->state->visible = new_plane_state->visible;
-+
-+ vc4_plane_set_blank(plane, false);
-+}
-+
-+static int vc4_plane_atomic_async_check(struct drm_plane *plane,
-+ struct drm_atomic_state *state)
-+{
-+ struct drm_plane_state *new_plane_state =
-+ drm_atomic_get_new_plane_state(state, plane);
-+ int ret = -EINVAL;
-+
-+ if (plane->type == 2 &&
-+ plane->state->fb &&
-+ new_plane_state->crtc->state->active)
-+ ret = 0;
-+
-+ return ret;
-+}
-+
- /* Called during init to allocate the plane's atomic state. */
- static void vc4_plane_reset(struct drm_plane *plane)
- {
-@@ -769,6 +813,8 @@ static const struct drm_plane_helper_funcs vc4_plane_helper_funcs = {
- .atomic_check = vc4_plane_atomic_check,
- .atomic_update = vc4_plane_atomic_update,
- .atomic_disable = vc4_plane_atomic_disable,
-+ .atomic_async_check = vc4_plane_atomic_async_check,
-+ .atomic_async_update = vc4_plane_atomic_async_update,
- };
-
- static struct drm_plane *vc4_fkms_plane_init(struct drm_device *dev,
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Dave Stevenson
-Date: Thu, 11 Aug 2022 13:49:16 +0100
-Subject: [PATCH 054/784] drm/vc4: Configure the HVS COB allocations
-
-The HVS Composite Output Buffer (COB) is the memory used to
-generate the output pixel data.
-Until now the vc4 driver has been relying on the firmware to
-have set these to sensible values.
-
-In testing triple screen support it has been noted that only
-1 line was being assigned to HVS channel 2. Whilst that is fine
-for the transposer (TXP), and indeed needed as only some pixels
-have an alpha channel, it is insufficient to run a live display.
-
-Split the COB more evenly between the 3 HVS channels.
-
-Signed-off-by: Dave Stevenson
-
-Revert vc4_regs change
----
- drivers/gpu/drm/vc4/vc4_hvs.c | 56 ++++++++++++++++++++++++++++++++++-
- 1 file changed, 55 insertions(+), 1 deletion(-)
-
-diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c
-index 67effc334715..23f8da10ea53 100644
---- a/drivers/gpu/drm/vc4/vc4_hvs.c
-+++ b/drivers/gpu/drm/vc4/vc4_hvs.c
-@@ -1013,7 +1013,7 @@ static int vc4_hvs_bind(struct device *dev, struct device *master, void *data)
- struct vc4_hvs *hvs = NULL;
- int ret;
- u32 dispctrl;
-- u32 reg;
-+ u32 reg, top;
-
- hvs = drmm_kzalloc(drm, sizeof(*hvs), GFP_KERNEL);
- if (!hvs)
-@@ -1151,6 +1151,60 @@ static int vc4_hvs_bind(struct device *dev, struct device *master, void *data)
-
- HVS_WRITE(SCALER_DISPCTRL, dispctrl);
-
-+ /* Recompute Composite Output Buffer (COB) allocations for the displays
-+ */
-+ if (!vc4->is_vc5) {
-+ /* The COB is 20736 pixels, or just over 10 lines at 2048 wide.
-+ * The bottom 2048 pixels are full 32bpp RGBA (intended for the
-+ * TXP composing RGBA to memory), whilst the remainder are only
-+ * 24bpp RGB.
-+ *
-+ * Assign 3 lines to channels 1 & 2, and just over 4 lines to
-+ * channel 0.
-+ */
-+ #define VC4_COB_SIZE 20736
-+ #define VC4_COB_LINE_WIDTH 2048
-+ #define VC4_COB_NUM_LINES 3
-+ reg = 0;
-+ top = VC4_COB_LINE_WIDTH * VC4_COB_NUM_LINES;
-+ reg |= (top - 1) << 16;
-+ HVS_WRITE(SCALER_DISPBASE2, reg);
-+ reg = top;
-+ top += VC4_COB_LINE_WIDTH * VC4_COB_NUM_LINES;
-+ reg |= (top - 1) << 16;
-+ HVS_WRITE(SCALER_DISPBASE1, reg);
-+ reg = top;
-+ top = VC4_COB_SIZE;
-+ reg |= (top - 1) << 16;
-+ HVS_WRITE(SCALER_DISPBASE0, reg);
-+ } else {
-+ /* The COB is 44416 pixels, or 10.8 lines at 4096 wide.
-+ * The bottom 4096 pixels are full RGBA (intended for the TXP
-+ * composing RGBA to memory), whilst the remainder are only
-+ * RGB. Addressing is always pixel wide.
-+ *
-+ * Assign 3 lines of 4096 to channels 1 & 2, and just over 4
-+ * lines. to channel 0.
-+ */
-+ #define VC5_COB_SIZE 44416
-+ #define VC5_COB_LINE_WIDTH 4096
-+ #define VC5_COB_NUM_LINES 3
-+ reg = 0;
-+ top = VC5_COB_LINE_WIDTH * VC5_COB_NUM_LINES;
-+ reg |= top << 16;
-+ HVS_WRITE(SCALER_DISPBASE2, reg);
-+ top += 16;
-+ reg = top;
-+ top += VC5_COB_LINE_WIDTH * VC5_COB_NUM_LINES;
-+ reg |= top << 16;
-+ HVS_WRITE(SCALER_DISPBASE1, reg);
-+ top += 16;
-+ reg = top;
-+ top = VC5_COB_SIZE;
-+ reg |= top << 16;
-+ HVS_WRITE(SCALER_DISPBASE0, reg);
-+ }
-+
- ret = devm_request_irq(dev, platform_get_irq(pdev, 0),
- vc4_hvs_irq_handler, 0, "vc4 hvs", drm);
- if (ret)
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Dave Stevenson
-Date: Thu, 11 Aug 2022 13:59:34 +0100
-Subject: [PATCH 055/784] drm/vc4: Set AXI panic modes for the HVS
-
-The HVS can change AXI request mode based on how full the COB
-FIFOs are.
-Until now the vc4 driver has been relying on the firmware to
-have set these to sensible values.
-
-With HVS channel 2 now being used for live video, change the
-panic mode for all channels to be explicitly set by the driver,
-and the same for all channels.
-
-Signed-off-by: Dave Stevenson
----
- drivers/gpu/drm/vc4/vc4_hvs.c | 11 +++++++++++
- 1 file changed, 11 insertions(+)
-
-diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c
-index 23f8da10ea53..97388f9a75bc 100644
---- a/drivers/gpu/drm/vc4/vc4_hvs.c
-+++ b/drivers/gpu/drm/vc4/vc4_hvs.c
-@@ -1138,6 +1138,17 @@ static int vc4_hvs_bind(struct device *dev, struct device *master, void *data)
- SCALER_DISPCTRL_SCLEIRQ);
-
-
-+ /* Set AXI panic mode.
-+ * VC4 panics when < 2 lines in FIFO.
-+ * VC5 panics when less than 1 line in the FIFO.
-+ */
-+ dispctrl &= ~(SCALER_DISPCTRL_PANIC0_MASK |
-+ SCALER_DISPCTRL_PANIC1_MASK |
-+ SCALER_DISPCTRL_PANIC2_MASK);
-+ dispctrl |= VC4_SET_FIELD(2, SCALER_DISPCTRL_PANIC0);
-+ dispctrl |= VC4_SET_FIELD(2, SCALER_DISPCTRL_PANIC1);
-+ dispctrl |= VC4_SET_FIELD(2, SCALER_DISPCTRL_PANIC2);
-+
- /* Set AXI panic mode.
- * VC4 panics when < 2 lines in FIFO.
- * VC5 panics when less than 1 line in the FIFO.
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Maxime Ripard
-Date: Mon, 11 Jul 2022 10:38:25 +0200
-Subject: [PATCH 056/784] drm/vc4: hvs: Skip DebugFS Registration for FKMS
-
-FKMS doesn't have an HVS and it's expected. Return from the debugfs init
-function immediately if we're running with fkms.
-
-Signed-off-by: Maxime Ripard
----
- drivers/gpu/drm/vc4/vc4_hvs.c | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c
-index 97388f9a75bc..094887d4673e 100644
---- a/drivers/gpu/drm/vc4/vc4_hvs.c
-+++ b/drivers/gpu/drm/vc4/vc4_hvs.c
-@@ -975,6 +975,9 @@ int vc4_hvs_debugfs_init(struct drm_minor *minor)
- struct vc4_hvs *hvs = vc4->hvs;
- int ret;
-
-+ if (vc4->firmware_kms)
-+ return 0;
-+
- if (!vc4->hvs)
- return -ENODEV;
-
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Maxime Ripard
-Date: Mon, 15 Aug 2022 13:34:02 +0200
-Subject: [PATCH 057/784] media: uapi: Add some RGB bus formats for VC4 DPI
- output
-
-The VC4 DPI controller can output more RGB formats that aren't described
-through a media bus format yet, so let's add them.
-
-Signed-off-by: Maxime Ripard
----
- include/uapi/linux/media-bus-format.h | 5 ++++-
- 1 file changed, 4 insertions(+), 1 deletion(-)
-
-diff --git a/include/uapi/linux/media-bus-format.h b/include/uapi/linux/media-bus-format.h
-index ec3323dbb927..d4228d038b54 100644
---- a/include/uapi/linux/media-bus-format.h
-+++ b/include/uapi/linux/media-bus-format.h
-@@ -34,19 +34,22 @@
-
- #define MEDIA_BUS_FMT_FIXED 0x0001
-
--/* RGB - next is 0x1022 */
-+/* RGB - next is 0x1025 */
- #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
- #define MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE 0x1003
- #define MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE 0x1004
- #define MEDIA_BUS_FMT_RGB565_1X16 0x1017
-+#define MEDIA_BUS_FMT_RGB565_1X24_CPADHI 0x1022
- #define MEDIA_BUS_FMT_BGR565_2X8_BE 0x1005
- #define MEDIA_BUS_FMT_BGR565_2X8_LE 0x1006
- #define MEDIA_BUS_FMT_RGB565_2X8_BE 0x1007
- #define MEDIA_BUS_FMT_RGB565_2X8_LE 0x1008
-+#define MEDIA_BUS_FMT_BGR666_1X18 0x1023
- #define MEDIA_BUS_FMT_RGB666_1X18 0x1009
- #define MEDIA_BUS_FMT_RBG888_1X24 0x100e
-+#define MEDIA_BUS_FMT_BGR666_1X24_CPADHI 0x1024
- #define MEDIA_BUS_FMT_RGB666_1X24_CPADHI 0x1015
- #define MEDIA_BUS_FMT_RGB666_1X7X3_SPWG 0x1010
- #define MEDIA_BUS_FMT_BGR888_1X24 0x1013
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Dom Cobley
-Date: Thu, 7 Apr 2022 18:23:07 +0100
-Subject: [PATCH 058/784] raspberrypi-firmware: Update mailbox commands
-
-Signed-off-by: Dom Cobley
----
- include/soc/bcm2835/raspberrypi-firmware.h | 28 +++++++++++++++++++++-
- 1 file changed, 27 insertions(+), 1 deletion(-)
-
-diff --git a/include/soc/bcm2835/raspberrypi-firmware.h b/include/soc/bcm2835/raspberrypi-firmware.h
-index 811ea668c4a1..dd3bbc75e531 100644
---- a/include/soc/bcm2835/raspberrypi-firmware.h
-+++ b/include/soc/bcm2835/raspberrypi-firmware.h
-@@ -36,6 +36,8 @@ struct rpi_firmware_property_tag_header {
- enum rpi_firmware_property_tag {
- RPI_FIRMWARE_PROPERTY_END = 0,
- RPI_FIRMWARE_GET_FIRMWARE_REVISION = 0x00000001,
-+ RPI_FIRMWARE_GET_FIRMWARE_VARIANT = 0x00000002,
-+ RPI_FIRMWARE_GET_FIRMWARE_HASH = 0x00000003,
-
- RPI_FIRMWARE_SET_CURSOR_INFO = 0x00008010,
- RPI_FIRMWARE_SET_CURSOR_STATE = 0x00008011,
-@@ -71,6 +73,7 @@ enum rpi_firmware_property_tag {
- RPI_FIRMWARE_GET_DISPMANX_RESOURCE_MEM_HANDLE = 0x00030014,
- RPI_FIRMWARE_GET_EDID_BLOCK = 0x00030020,
- RPI_FIRMWARE_GET_CUSTOMER_OTP = 0x00030021,
-+ RPI_FIRMWARE_GET_EDID_BLOCK_DISPLAY = 0x00030023,
- RPI_FIRMWARE_GET_DOMAIN_STATE = 0x00030030,
- RPI_FIRMWARE_GET_THROTTLED = 0x00030046,
- RPI_FIRMWARE_GET_CLOCK_MEASURED = 0x00030047,
-@@ -89,8 +92,11 @@ enum rpi_firmware_property_tag {
- RPI_FIRMWARE_GET_PERIPH_REG = 0x00030045,
- RPI_FIRMWARE_SET_PERIPH_REG = 0x00038045,
- RPI_FIRMWARE_GET_POE_HAT_VAL = 0x00030049,
-- RPI_FIRMWARE_SET_POE_HAT_VAL = 0x00030050,
-+ RPI_FIRMWARE_SET_POE_HAT_VAL = 0x00038049,
-+ RPI_FIRMWARE_SET_POE_HAT_VAL_OLD = 0x00030050,
- RPI_FIRMWARE_NOTIFY_XHCI_RESET = 0x00030058,
-+ RPI_FIRMWARE_GET_REBOOT_FLAGS = 0x00030064,
-+ RPI_FIRMWARE_SET_REBOOT_FLAGS = 0x00038064,
- RPI_FIRMWARE_NOTIFY_DISPLAY_DONE = 0x00030066,
-
- /* Dispmanx TAGS */
-@@ -105,9 +111,16 @@ enum rpi_firmware_property_tag {
- RPI_FIRMWARE_FRAMEBUFFER_GET_VIRTUAL_OFFSET = 0x00040009,
- RPI_FIRMWARE_FRAMEBUFFER_GET_OVERSCAN = 0x0004000a,
- RPI_FIRMWARE_FRAMEBUFFER_GET_PALETTE = 0x0004000b,
-+ RPI_FIRMWARE_FRAMEBUFFER_GET_LAYER = 0x0004000c,
-+ RPI_FIRMWARE_FRAMEBUFFER_GET_TRANSFORM = 0x0004000d,
-+ RPI_FIRMWARE_FRAMEBUFFER_GET_VSYNC = 0x0004000e,
- RPI_FIRMWARE_FRAMEBUFFER_GET_TOUCHBUF = 0x0004000f,
- RPI_FIRMWARE_FRAMEBUFFER_GET_GPIOVIRTBUF = 0x00040010,
- RPI_FIRMWARE_FRAMEBUFFER_RELEASE = 0x00048001,
-+ RPI_FIRMWARE_FRAMEBUFFER_GET_DISPLAY_ID = 0x00040016,
-+ RPI_FIRMWARE_FRAMEBUFFER_SET_DISPLAY_NUM = 0x00048013,
-+ RPI_FIRMWARE_FRAMEBUFFER_GET_NUM_DISPLAYS = 0x00040013,
-+ RPI_FIRMWARE_FRAMEBUFFER_GET_DISPLAY_SETTINGS = 0x00040014,
- RPI_FIRMWARE_FRAMEBUFFER_TEST_PHYSICAL_WIDTH_HEIGHT = 0x00044003,
- RPI_FIRMWARE_FRAMEBUFFER_TEST_VIRTUAL_WIDTH_HEIGHT = 0x00044004,
- RPI_FIRMWARE_FRAMEBUFFER_TEST_DEPTH = 0x00044005,
-@@ -116,26 +129,39 @@ enum rpi_firmware_property_tag {
- RPI_FIRMWARE_FRAMEBUFFER_TEST_VIRTUAL_OFFSET = 0x00044009,
- RPI_FIRMWARE_FRAMEBUFFER_TEST_OVERSCAN = 0x0004400a,
- RPI_FIRMWARE_FRAMEBUFFER_TEST_PALETTE = 0x0004400b,
-+ RPI_FIRMWARE_FRAMEBUFFER_TEST_LAYER = 0x0004400c,
-+ RPI_FIRMWARE_FRAMEBUFFER_TEST_TRANSFORM = 0x0004400d,
- RPI_FIRMWARE_FRAMEBUFFER_TEST_VSYNC = 0x0004400e,
- RPI_FIRMWARE_FRAMEBUFFER_SET_PHYSICAL_WIDTH_HEIGHT = 0x00048003,
- RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_WIDTH_HEIGHT = 0x00048004,
- RPI_FIRMWARE_FRAMEBUFFER_SET_DEPTH = 0x00048005,
- RPI_FIRMWARE_FRAMEBUFFER_SET_PIXEL_ORDER = 0x00048006,
- RPI_FIRMWARE_FRAMEBUFFER_SET_ALPHA_MODE = 0x00048007,
-+ RPI_FIRMWARE_FRAMEBUFFER_SET_PITCH = 0x00048008,
- RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_OFFSET = 0x00048009,
- RPI_FIRMWARE_FRAMEBUFFER_SET_OVERSCAN = 0x0004800a,
- RPI_FIRMWARE_FRAMEBUFFER_SET_PALETTE = 0x0004800b,
-+
- RPI_FIRMWARE_FRAMEBUFFER_SET_TOUCHBUF = 0x0004801f,
- RPI_FIRMWARE_FRAMEBUFFER_SET_GPIOVIRTBUF = 0x00048020,
- RPI_FIRMWARE_FRAMEBUFFER_SET_VSYNC = 0x0004800e,
-+ RPI_FIRMWARE_FRAMEBUFFER_SET_LAYER = 0x0004800c,
-+ RPI_FIRMWARE_FRAMEBUFFER_SET_TRANSFORM = 0x0004800d,
- RPI_FIRMWARE_FRAMEBUFFER_SET_BACKLIGHT = 0x0004800f,
-
- RPI_FIRMWARE_VCHIQ_INIT = 0x00048010,
-
-+ RPI_FIRMWARE_SET_PLANE = 0x00048015,
-+ RPI_FIRMWARE_GET_DISPLAY_TIMING = 0x00040017,
-+ RPI_FIRMWARE_SET_TIMING = 0x00048017,
-+ RPI_FIRMWARE_GET_DISPLAY_CFG = 0x00040018,
-+ RPI_FIRMWARE_SET_DISPLAY_POWER = 0x00048019,
- RPI_FIRMWARE_GET_COMMAND_LINE = 0x00050001,
- RPI_FIRMWARE_GET_DMA_CHANNELS = 0x00060001,
- };
-
-+#define GET_DISPLAY_SETTINGS_PAYLOAD_SIZE 64
-+
- #if IS_ENABLED(CONFIG_RASPBERRYPI_FIRMWARE)
- int rpi_firmware_property(struct rpi_firmware *fw,
- u32 tag, void *data, size_t len);
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Maxime Ripard
-Date: Mon, 11 Jul 2022 15:58:36 +0200
-Subject: [PATCH 059/784] clk: bcm: rpi: Create helper to retrieve private data
-
-The RaspberryPi firmware clocks driver uses in several instances a
-container_of to retrieve the struct raspberrypi_clk_data from a pointer
-to struct clk_hw. Let's create a small function to avoid duplicating it
-all over the place.
-
-Signed-off-by: Maxime Ripard
----
- drivers/clk/bcm/clk-raspberrypi.c | 18 ++++++++++--------
- 1 file changed, 10 insertions(+), 8 deletions(-)
-
-diff --git a/drivers/clk/bcm/clk-raspberrypi.c b/drivers/clk/bcm/clk-raspberrypi.c
-index 679f4649a7ef..b967c7b714db 100644
---- a/drivers/clk/bcm/clk-raspberrypi.c
-+++ b/drivers/clk/bcm/clk-raspberrypi.c
-@@ -75,6 +75,12 @@ struct raspberrypi_clk_data {
- struct raspberrypi_clk *rpi;
- };
-
-+static inline
-+const struct raspberrypi_clk_data *clk_hw_to_data(const struct clk_hw *hw)
-+{
-+ return container_of(hw, struct raspberrypi_clk_data, hw);
-+}
-+
- struct raspberrypi_clk_variant {
- bool export;
- char *clkdev;
-@@ -187,8 +193,7 @@ static int raspberrypi_clock_property(struct rpi_firmware *firmware,
-
- static int raspberrypi_fw_is_prepared(struct clk_hw *hw)
- {
-- struct raspberrypi_clk_data *data =
-- container_of(hw, struct raspberrypi_clk_data, hw);
-+ const struct raspberrypi_clk_data *data = clk_hw_to_data(hw);
- struct raspberrypi_clk *rpi = data->rpi;
- u32 val = 0;
- int ret;
-@@ -205,8 +210,7 @@ static int raspberrypi_fw_is_prepared(struct clk_hw *hw)
- static unsigned long raspberrypi_fw_get_rate(struct clk_hw *hw,
- unsigned long parent_rate)
- {
-- struct raspberrypi_clk_data *data =
-- container_of(hw, struct raspberrypi_clk_data, hw);
-+ const struct raspberrypi_clk_data *data = clk_hw_to_data(hw);
- struct raspberrypi_clk *rpi = data->rpi;
- u32 val = 0;
- int ret;
-@@ -222,8 +226,7 @@ static unsigned long raspberrypi_fw_get_rate(struct clk_hw *hw,
- static int raspberrypi_fw_set_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long parent_rate)
- {
-- struct raspberrypi_clk_data *data =
-- container_of(hw, struct raspberrypi_clk_data, hw);
-+ const struct raspberrypi_clk_data *data = clk_hw_to_data(hw);
- struct raspberrypi_clk *rpi = data->rpi;
- u32 _rate = rate;
- int ret;
-@@ -240,8 +243,7 @@ static int raspberrypi_fw_set_rate(struct clk_hw *hw, unsigned long rate,
- static int raspberrypi_fw_dumb_determine_rate(struct clk_hw *hw,
- struct clk_rate_request *req)
- {
-- struct raspberrypi_clk_data *data =
-- container_of(hw, struct raspberrypi_clk_data, hw);
-+ const struct raspberrypi_clk_data *data = clk_hw_to_data(hw);
- struct raspberrypi_clk_variant *variant = data->variant;
-
- /*
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Maxime Ripard
-Date: Mon, 6 Jun 2022 11:02:16 +0200
-Subject: [PATCH 060/784] arm64: setup: Fix build warning
-
-Signed-off-by: Maxime Ripard
----
- arch/arm64/kernel/setup.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
-index fea3223704b6..a2dd48655bc4 100644
---- a/arch/arm64/kernel/setup.c
-+++ b/arch/arm64/kernel/setup.c
-@@ -222,9 +222,9 @@ static void __init request_standard_resources(void)
- size_t res_size;
-
- kernel_code.start = __pa_symbol(_stext);
-- kernel_code.end = __pa_symbol(__init_begin - 1);
-+ kernel_code.end = __pa_symbol(__init_begin) - 1;
- kernel_data.start = __pa_symbol(_sdata);
-- kernel_data.end = __pa_symbol(_end - 1);
-+ kernel_data.end = __pa_symbol(_end) - 1;
- insert_resource(&iomem_resource, &kernel_code);
- insert_resource(&iomem_resource, &kernel_data);
-
---
-2.39.1
-
-
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: notro
-Date: Wed, 9 Jul 2014 14:46:08 +0200
-Subject: [PATCH 061/784] BCM2708: Add core Device Tree support
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Add the bare minimum needed to boot BCM2708 from a Device Tree.
-
-Signed-off-by: Noralf Tronnes
-
-BCM2708: DT: change 'axi' nodename to 'soc'
-
-Change DT node named 'axi' to 'soc' so it matches ARCH_BCM2835.
-The VC4 bootloader fills in certain properties in the 'axi' subtree,
-but since this is part of an upstreaming effort, the name is changed.
-
-Signed-off-by: Noralf Tronnes notro@tronnes.org
-
-BCM2708_DT: Correct length of the peripheral space
-
-Use dts-dirs feature for overlays.
-
-The kernel makefiles have a dts-dirs target that is for vendor subdirectories.
-
-Using this fixes the install_dtbs target, which previously did not install the overlays.
-
-BCM270X_DT: configure I2S DMA channels
-
-Signed-off-by: Matthias Reichl
-
-BCM270X_DT: switch to bcm2835-i2s
-
-I2S soundcard drivers with proper devicetree support (i.e. not linking
-to the cpu_dai/platform via name but to cpu/platform via of_node)
-will work out of the box without any modifications.
-
-When the kernel is compiled without devicetree support the platform
-code will instantiate the bcm2708-i2s driver and I2S soundcard drivers
-will link to it via name, as before.
-
-Signed-off-by: Matthias Reichl
-
-SDIO-overlay: add poll_once-boolean parameter
-
-Add paramter to toggle sdio-device-polling
-done every second or once at boot-time.
-
-Signed-off-by: Patrick Boettcher
-
-BCM270X_DT: Make mmc overlay compatible with current firmware
-
-The original DT overlay logic followed a merge-then-patch procedure,
-i.e. parameters are applied to the loaded overlay before the overlay
-is merged into the base DTB. This sequence has been changed to
-patch-then-merge, in order to support parameterised node names, and
-to protect against bad overlays. As a result, overrides (parameters)
-must only target labels in the overlay, but the overlay can obviously target nodes in the base DTB.
-
-mmc-overlay.dts (that switches back to the original mmc sdcard
-driver) is the only overlay violating that rule, and this patch
-fixes it.
-
-bcm270x_dt: Use the sdhost MMC controller by default
-
-The "mmc" overlay reverts to using the other controller.
-
-squash: Add cprman to dt
-
-BCM270X_DT: Use clk_core for I2C interfaces
-
-BCM270X_DT: Use bcm283x.dtsi, bcm2835.dtsi and bcm2836.dtsi
-
-The mainline Device Tree files are quite close to downstream now.
-Let's use bcm283x.dtsi, bcm2835.dtsi and bcm2836.dtsi as base files
-for our dts files.
-
-Mainline dts files are based on these files:
-
- bcm2835-rpi.dtsi
- bcm2835.dtsi bcm2836.dtsi
- bcm283x.dtsi
-
-Current downstream are based on these:
-
- bcm2708.dtsi bcm2709.dtsi bcm2710.dtsi
- bcm2708_common.dtsi
-
-This patch introduces this dependency:
-
- bcm2708.dtsi bcm2709.dtsi
- bcm2708-rpi.dtsi
- bcm270x.dtsi
- bcm2835.dtsi bcm2836.dtsi
- bcm283x.dtsi
-
-And:
- bcm2710.dtsi
- bcm2708-rpi.dtsi
- bcm270x.dtsi
- bcm283x.dtsi
-
-bcm270x.dtsi contains the downstream bcm283x.dtsi diff.
-bcm2708-rpi.dtsi is the downstream version of bcm2835-rpi.dtsi.
-
-Other changes:
-- The led node has moved from /soc/leds to /leds. This is not a problem
- since the label is used to reference it.
-- The clk_osc reg property changes from 6 to 3.
-- The gpu nodes has their interrupt property set in the base file.
-- the clocks label does not point to the /clocks node anymore, but
- points to the cprman node. This is not a problem since the overlays
- that use the clock node refer to it directly: target-path = "/clocks";
-- some nodes now have 2 labels since mainline and downstream differs in
- this respect: cprman/clocks, spi0/spi, gpu/vc4.
-- some nodes doesn't have an explicit status = "okay" since they're not
- disabled in the base file: watchdog and random.
-- gpiomem doesn't need an explicit status = "okay".
-- bcm2708-rpi-cm.dts got the hpd-gpios property from bcm2708_common.dtsi,
- it's now set directly in that file.
-- bcm2709-rpi-2-b.dts has the timer node moved from /soc/timer to /timer.
-- Removed clock-frequency property on the bcm{2709,2710}.dtsi timer nodes.
-
-Signed-off-by: Noralf Trønnes
-
-BCM270X_DT: Use raspberrypi-power to turn on USB power
-
-Use the raspberrypi-power driver to turn on USB power.
-
-Signed-off-by: Noralf Trønnes
-
-BCM270X_DT: Add a .dtbo target, use for overlays
-
-Change the filenames and extensions to keep the pre-DDT style of
-overlay (-overlay.dtb) distinct from new ones that use a
-different style of local fixups (.dtbo), and to match other
-platforms.
-
-The RPi firmware uses the DDTK trailer atom to choose which type of
-overlay to use for each kernel.
-
-Signed-off-by: Phil Elwell
-
-BCM270X_DT: Don't generate "linux,phandle" props
-
-The EPAPR standard says to use "phandle" properties to store phandles,
-rather than the deprecated "linux,phandle" version. By default, dtc
-generates both, but adding "-H epapr" causes it to only generate
-"phandle"s, saving some space and clutter.
-
-Signed-off-by: Phil Elwell
-
-BCM270X_DT: Add overlay for enc28j60 on SPI2
-
-Works on SPI2 for compute module
-
-BCM270X_DT: Add midi-uart0 overlay
-
-MIDI requires 31.25kbaud, a baudrate unsupported by Linux. The
-midi-uart0 overlay configures uart0 (ttyAMA0) to use a fake clock
-so that requesting 38.4kbaud actually gets 31.25kbaud.
-
-Signed-off-by: Phil Elwell
-
-BCM270X_DT: Add i2c-sensor overlay
-
-The i2c-sensor overlay is a container for various pressure and
-temperature sensors, currently bmp085 and bmp280. The standalone
-bmp085_i2c-sensor overlay is now deprecated.
-
-Signed-off-by: Phil Elwell
-
-BCM270X_DT: overlays/*-overlay.dtb -> overlays/*.dtbo (#1752)
-
-We now create overlays as .dtbo files.
-
-build: support for .dtbo files for dtb overlays
-
-Kernel 4.4.6+ on RaspberryPi support .dtbo files for overlays, instead of .dtb.
-Patch the kernel, which has faulty rules to generate .dtbo the way yocto does
-
-Signed-off-by: Herve Jourdain
-Signed-off-by: Khem Raj
-
-BCM270X: Drop position requirement for CMA in VC4 overlay.
-
-No longer necessary since 2aefcd576195a739a7a256099571c9c4a401005f,
-and will probably let peeople that want to choose a larger CMA
-allocation (particularly on pi0/1).
-
-Signed-off-by: Eric Anholt
-
-BCM270X_DT: RPi Device Tree tidy
-
-Use the upstream sdhost node, add thermal-zones, and factor out some
-common elements.
-
-Signed-off-by: Phil Elwell
-
-kbuild: Silence unhelpful DTC warnings
-
-Signed-off-by: Phil Elwell
-
-BCM270X_DT: DT build rules no longer arch-specific
-
-Signed-off-by: Phil Elwell
----
- arch/arm/boot/dts/Makefile | 31 +
- arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 200 +
- arch/arm/boot/dts/bcm2708-rpi-b-rev1.dts | 208 +
- arch/arm/boot/dts/bcm2708-rpi-b.dts | 190 +
- arch/arm/boot/dts/bcm2708-rpi-bt.dtsi | 26 +
- arch/arm/boot/dts/bcm2708-rpi-cm.dts | 171 +
- arch/arm/boot/dts/bcm2708-rpi-cm.dtsi | 22 +
- arch/arm/boot/dts/bcm2708-rpi-zero-w.dts | 246 +
- arch/arm/boot/dts/bcm2708-rpi-zero.dts | 187 +
- arch/arm/boot/dts/bcm2708-rpi.dtsi | 40 +
- arch/arm/boot/dts/bcm2708.dtsi | 18 +
- arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 200 +
- arch/arm/boot/dts/bcm2709-rpi-cm2.dts | 221 +
- arch/arm/boot/dts/bcm2709-rpi.dtsi | 5 +
- arch/arm/boot/dts/bcm2709.dtsi | 24 +
- arch/arm/boot/dts/bcm270x-rpi.dtsi | 177 +
- arch/arm/boot/dts/bcm270x.dtsi | 294 ++
- arch/arm/boot/dts/bcm2710-rpi-2-b.dts | 200 +
- arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts | 289 ++
- arch/arm/boot/dts/bcm2710-rpi-3-b.dts | 291 ++
- arch/arm/boot/dts/bcm2710-rpi-cm3.dts | 220 +
- arch/arm/boot/dts/bcm2710-rpi-zero-2-w.dts | 267 +
- arch/arm/boot/dts/bcm2710-rpi-zero-2.dts | 1 +
- arch/arm/boot/dts/bcm2710.dtsi | 27 +
- arch/arm/boot/dts/bcm2711-rpi-4-b.dts | 320 +-
- arch/arm/boot/dts/bcm2711-rpi-400.dts | 532 +-
- arch/arm/boot/dts/bcm2711-rpi-cm4.dts | 578 +++
- arch/arm/boot/dts/bcm2711-rpi-cm4s.dts | 427 ++
- arch/arm/boot/dts/bcm2711-rpi-ds.dtsi | 292 ++
- arch/arm/boot/dts/bcm2711-rpi.dtsi | 13 +
- arch/arm/boot/dts/bcm271x-rpi-bt.dtsi | 26 +
- arch/arm/boot/dts/bcm283x-rpi-csi0-2lane.dtsi | 4 +
- arch/arm/boot/dts/bcm283x-rpi-csi1-2lane.dtsi | 4 +
- arch/arm/boot/dts/bcm283x-rpi-csi1-4lane.dtsi | 4 +
- .../boot/dts/bcm283x-rpi-i2c0mux_0_28.dtsi | 4 +
- .../boot/dts/bcm283x-rpi-i2c0mux_0_44.dtsi | 4 +
- arch/arm/boot/dts/overlays/Makefile | 287 ++
- arch/arm/boot/dts/overlays/README | 4513 +++++++++++++++++
- .../arm/boot/dts/overlays/act-led-overlay.dts | 27 +
- .../dts/overlays/adafruit-st7735r-overlay.dts | 83 +
- .../boot/dts/overlays/adafruit18-overlay.dts | 55 +
- .../dts/overlays/adau1977-adc-overlay.dts | 40 +
- .../dts/overlays/adau7002-simple-overlay.dts | 52 +
- .../arm/boot/dts/overlays/ads1015-overlay.dts | 98 +
- .../arm/boot/dts/overlays/ads1115-overlay.dts | 103 +
- .../arm/boot/dts/overlays/ads7846-overlay.dts | 89 +
- .../boot/dts/overlays/adv7282m-overlay.dts | 73 +
- .../boot/dts/overlays/adv728x-m-overlay.dts | 37 +
- .../overlays/akkordion-iqdacplus-overlay.dts | 49 +
- .../allo-boss-dac-pcm512x-audio-overlay.dts | 59 +
- .../overlays/allo-boss2-dac-audio-overlay.dts | 57 +
- .../dts/overlays/allo-digione-overlay.dts | 44 +
- .../allo-katana-dac-audio-overlay.dts | 57 +
- .../allo-piano-dac-pcm512x-audio-overlay.dts | 54 +
- ...o-piano-dac-plus-pcm512x-audio-overlay.dts | 57 +
- arch/arm/boot/dts/overlays/anyspi-overlay.dts | 205 +
- .../boot/dts/overlays/apds9960-overlay.dts | 55 +
- .../boot/dts/overlays/applepi-dac-overlay.dts | 57 +
- .../dts/overlays/arducam-64mp-overlay.dts | 94 +
- .../overlays/arducam-pivariety-overlay.dts | 94 +
- .../boot/dts/overlays/at86rf233-overlay.dts | 57 +
- .../overlays/audioinjector-addons-overlay.dts | 60 +
- .../audioinjector-bare-i2s-overlay.dts | 50 +
- ...dioinjector-isolated-soundcard-overlay.dts | 55 +
- .../overlays/audioinjector-ultra-overlay.dts | 71 +
- .../audioinjector-wm8731-audio-overlay.dts | 39 +
- .../dts/overlays/audiosense-pi-overlay.dts | 82 +
- .../boot/dts/overlays/audremap-overlay.dts | 44 +
- .../boot/dts/overlays/balena-fin-overlay.dts | 125 +
- .../dts/overlays/camera-mux-2port-overlay.dts | 409 ++
- .../dts/overlays/camera-mux-4port-overlay.dts | 684 +++
- .../arm/boot/dts/overlays/cap1106-overlay.dts | 52 +
- .../boot/dts/overlays/chipdip-dac-overlay.dts | 46 +
- .../dts/overlays/cirrus-wm5102-overlay.dts | 172 +
- arch/arm/boot/dts/overlays/cma-overlay.dts | 36 +
- .../dts/overlays/cutiepi-panel-overlay.dts | 117 +
- .../boot/dts/overlays/dacberry400-overlay.dts | 71 +
- arch/arm/boot/dts/overlays/dht11-overlay.dts | 48 +
- .../dts/overlays/dionaudio-kiwi-overlay.dts | 39 +
- .../dts/overlays/dionaudio-loco-overlay.dts | 39 +
- .../overlays/dionaudio-loco-v2-overlay.dts | 49 +
- .../boot/dts/overlays/disable-bt-overlay.dts | 64 +
- .../dts/overlays/disable-wifi-overlay.dts | 20 +
- arch/arm/boot/dts/overlays/dpi18-overlay.dts | 39 +
- .../boot/dts/overlays/dpi18cpadhi-overlay.dts | 26 +
- arch/arm/boot/dts/overlays/dpi24-overlay.dts | 39 +
- arch/arm/boot/dts/overlays/draws-overlay.dts | 208 +
- .../arm/boot/dts/overlays/dwc-otg-overlay.dts | 14 +
- arch/arm/boot/dts/overlays/dwc2-overlay.dts | 26 +
- .../boot/dts/overlays/edt-ft5406-overlay.dts | 26 +
- arch/arm/boot/dts/overlays/edt-ft5406.dtsi | 47 +
- .../boot/dts/overlays/enc28j60-overlay.dts | 53 +
- .../dts/overlays/enc28j60-spi2-overlay.dts | 47 +
- .../arm/boot/dts/overlays/exc3000-overlay.dts | 48 +
- arch/arm/boot/dts/overlays/fbtft-overlay.dts | 611 +++
- .../boot/dts/overlays/fe-pi-audio-overlay.dts | 70 +
- .../boot/dts/overlays/fsm-demo-overlay.dts | 104 +
- arch/arm/boot/dts/overlays/gc9a01-overlay.dts | 151 +
- .../boot/dts/overlays/ghost-amp-overlay.dts | 145 +
- arch/arm/boot/dts/overlays/goodix-overlay.dts | 46 +
- .../googlevoicehat-soundcard-overlay.dts | 49 +
- .../boot/dts/overlays/gpio-fan-overlay.dts | 89 +
- .../boot/dts/overlays/gpio-hog-overlay.dts | 27 +
- .../arm/boot/dts/overlays/gpio-ir-overlay.dts | 49 +
- .../boot/dts/overlays/gpio-ir-tx-overlay.dts | 36 +
- .../boot/dts/overlays/gpio-key-overlay.dts | 48 +
- .../boot/dts/overlays/gpio-led-overlay.dts | 97 +
- .../overlays/gpio-no-bank0-irq-overlay.dts | 14 +
- .../boot/dts/overlays/gpio-no-irq-overlay.dts | 14 +
- .../dts/overlays/gpio-poweroff-overlay.dts | 39 +
- .../dts/overlays/gpio-shutdown-overlay.dts | 86 +
- .../boot/dts/overlays/hd44780-lcd-overlay.dts | 46 +
- .../hdmi-backlight-hwhack-gpio-overlay.dts | 47 +
- .../dts/overlays/hifiberry-amp-overlay.dts | 39 +
- .../dts/overlays/hifiberry-amp100-overlay.dts | 64 +
- .../dts/overlays/hifiberry-amp3-overlay.dts | 57 +
- .../dts/overlays/hifiberry-dac-overlay.dts | 34 +
- .../overlays/hifiberry-dacplus-overlay.dts | 65 +
- .../overlays/hifiberry-dacplusadc-overlay.dts | 72 +
- .../hifiberry-dacplusadcpro-overlay.dts | 70 +
- .../overlays/hifiberry-dacplusdsp-overlay.dts | 34 +
- .../overlays/hifiberry-dacplushd-overlay.dts | 94 +
- .../dts/overlays/hifiberry-digi-overlay.dts | 41 +
- .../overlays/hifiberry-digi-pro-overlay.dts | 43 +
- .../boot/dts/overlays/highperi-overlay.dts | 63 +
- arch/arm/boot/dts/overlays/hy28a-overlay.dts | 93 +
- .../boot/dts/overlays/hy28b-2017-overlay.dts | 152 +
- arch/arm/boot/dts/overlays/hy28b-overlay.dts | 148 +
- .../boot/dts/overlays/i-sabre-q2m-overlay.dts | 39 +
- .../boot/dts/overlays/i2c-bcm2708-overlay.dts | 13 +
- .../arm/boot/dts/overlays/i2c-fan-overlay.dts | 108 +
- .../boot/dts/overlays/i2c-gpio-overlay.dts | 47 +
- .../arm/boot/dts/overlays/i2c-mux-overlay.dts | 139 +
- .../dts/overlays/i2c-pwm-pca9685a-overlay.dts | 26 +
- .../arm/boot/dts/overlays/i2c-rtc-common.dtsi | 351 ++
- .../dts/overlays/i2c-rtc-gpio-overlay.dts | 31 +
- .../arm/boot/dts/overlays/i2c-rtc-overlay.dts | 42 +
- .../boot/dts/overlays/i2c-sensor-common.dtsi | 341 ++
- .../boot/dts/overlays/i2c-sensor-overlay.dts | 42 +
- arch/arm/boot/dts/overlays/i2c0-overlay.dts | 83 +
- arch/arm/boot/dts/overlays/i2c1-overlay.dts | 44 +
- arch/arm/boot/dts/overlays/i2c3-overlay.dts | 36 +
- arch/arm/boot/dts/overlays/i2c4-overlay.dts | 36 +
- arch/arm/boot/dts/overlays/i2c5-overlay.dts | 36 +
- arch/arm/boot/dts/overlays/i2c6-overlay.dts | 36 +
- .../arm/boot/dts/overlays/i2s-dac-overlay.dts | 34 +
- .../dts/overlays/i2s-gpio28-31-overlay.dts | 18 +
- .../boot/dts/overlays/ilitek251x-overlay.dts | 45 +
- arch/arm/boot/dts/overlays/imx219-overlay.dts | 89 +
- arch/arm/boot/dts/overlays/imx219.dtsi | 27 +
- arch/arm/boot/dts/overlays/imx258-overlay.dts | 131 +
- arch/arm/boot/dts/overlays/imx258.dtsi | 27 +
- arch/arm/boot/dts/overlays/imx290-overlay.dts | 32 +
- .../boot/dts/overlays/imx290_327-overlay.dtsi | 112 +
- arch/arm/boot/dts/overlays/imx290_327.dtsi | 24 +
- arch/arm/boot/dts/overlays/imx296-overlay.dts | 103 +
- arch/arm/boot/dts/overlays/imx327-overlay.dts | 32 +
- arch/arm/boot/dts/overlays/imx378-overlay.dts | 10 +
- arch/arm/boot/dts/overlays/imx462-overlay.dts | 32 +
- arch/arm/boot/dts/overlays/imx477-overlay.dts | 10 +
- .../boot/dts/overlays/imx477_378-overlay.dtsi | 83 +
- arch/arm/boot/dts/overlays/imx477_378.dtsi | 24 +
- arch/arm/boot/dts/overlays/imx519-overlay.dts | 96 +
- .../dts/overlays/iqaudio-codec-overlay.dts | 42 +
- .../boot/dts/overlays/iqaudio-dac-overlay.dts | 46 +
- .../dts/overlays/iqaudio-dacplus-overlay.dts | 49 +
- .../iqaudio-digi-wm8804-audio-overlay.dts | 47 +
- arch/arm/boot/dts/overlays/iqs550-overlay.dts | 59 +
- .../arm/boot/dts/overlays/irs1125-overlay.dts | 90 +
- .../dts/overlays/jedec-spi-nor-overlay.dts | 309 ++
- .../dts/overlays/justboom-both-overlay.dts | 65 +
- .../dts/overlays/justboom-dac-overlay.dts | 46 +
- .../dts/overlays/justboom-digi-overlay.dts | 41 +
- .../arm/boot/dts/overlays/ltc294x-overlay.dts | 86 +
- .../boot/dts/overlays/max98357a-overlay.dts | 84 +
- .../boot/dts/overlays/maxtherm-overlay.dts | 186 +
- .../boot/dts/overlays/mbed-dac-overlay.dts | 64 +
- .../boot/dts/overlays/mcp23017-overlay.dts | 69 +
- .../boot/dts/overlays/mcp23s17-overlay.dts | 732 +++
- .../dts/overlays/mcp2515-can0-overlay.dts | 73 +
- .../dts/overlays/mcp2515-can1-overlay.dts | 73 +
- .../arm/boot/dts/overlays/mcp2515-overlay.dts | 156 +
- .../boot/dts/overlays/mcp251xfd-overlay.dts | 226 +
- .../arm/boot/dts/overlays/mcp3008-overlay.dts | 205 +
- .../arm/boot/dts/overlays/mcp3202-overlay.dts | 205 +
- .../arm/boot/dts/overlays/mcp342x-overlay.dts | 164 +
- .../dts/overlays/media-center-overlay.dts | 134 +
- .../boot/dts/overlays/merus-amp-overlay.dts | 59 +
- .../boot/dts/overlays/midi-uart0-overlay.dts | 36 +
- .../boot/dts/overlays/midi-uart1-overlay.dts | 43 +
- .../boot/dts/overlays/midi-uart2-overlay.dts | 37 +
- .../boot/dts/overlays/midi-uart3-overlay.dts | 38 +
- .../boot/dts/overlays/midi-uart4-overlay.dts | 38 +
- .../boot/dts/overlays/midi-uart5-overlay.dts | 38 +
- .../boot/dts/overlays/minipitft13-overlay.dts | 70 +
- .../boot/dts/overlays/miniuart-bt-overlay.dts | 93 +
- .../dts/overlays/mipi-dbi-spi-overlay.dts | 175 +
- .../boot/dts/overlays/mlx90640-overlay.dts | 22 +
- arch/arm/boot/dts/overlays/mmc-overlay.dts | 46 +
- .../arm/boot/dts/overlays/mpu6050-overlay.dts | 29 +
- .../arm/boot/dts/overlays/mz61581-overlay.dts | 117 +
- arch/arm/boot/dts/overlays/ov2311-overlay.dts | 77 +
- arch/arm/boot/dts/overlays/ov2311.dtsi | 26 +
- arch/arm/boot/dts/overlays/ov5647-overlay.dts | 92 +
- arch/arm/boot/dts/overlays/ov5647.dtsi | 25 +
- arch/arm/boot/dts/overlays/ov7251-overlay.dts | 77 +
- arch/arm/boot/dts/overlays/ov7251.dtsi | 28 +
- arch/arm/boot/dts/overlays/ov9281-overlay.dts | 78 +
- arch/arm/boot/dts/overlays/ov9281.dtsi | 27 +
- arch/arm/boot/dts/overlays/overlay_map.dts | 211 +
- .../arm/boot/dts/overlays/papirus-overlay.dts | 84 +
- .../arm/boot/dts/overlays/pca953x-overlay.dts | 240 +
- .../dts/overlays/pcie-32bit-dma-overlay.dts | 38 +
- arch/arm/boot/dts/overlays/pibell-overlay.dts | 81 +
- .../dts/overlays/pifacedigital-overlay.dts | 144 +
- .../arm/boot/dts/overlays/pifi-40-overlay.dts | 50 +
- .../boot/dts/overlays/pifi-dac-hd-overlay.dts | 49 +
- .../dts/overlays/pifi-dac-zero-overlay.dts | 49 +
- .../dts/overlays/pifi-mini-210-overlay.dts | 42 +
- arch/arm/boot/dts/overlays/piglow-overlay.dts | 97 +
- .../boot/dts/overlays/piscreen-overlay.dts | 102 +
- .../boot/dts/overlays/piscreen2r-overlay.dts | 106 +
- .../arm/boot/dts/overlays/pisound-overlay.dts | 120 +
- .../arm/boot/dts/overlays/pitft22-overlay.dts | 69 +
- .../overlays/pitft28-capacitive-overlay.dts | 91 +
- .../overlays/pitft28-resistive-overlay.dts | 121 +
- .../overlays/pitft35-resistive-overlay.dts | 122 +
- .../boot/dts/overlays/pps-gpio-overlay.dts | 39 +
- .../boot/dts/overlays/proto-codec-overlay.dts | 39 +
- .../boot/dts/overlays/pwm-2chan-overlay.dts | 49 +
- .../boot/dts/overlays/pwm-ir-tx-overlay.dts | 40 +
- arch/arm/boot/dts/overlays/pwm-overlay.dts | 45 +
- .../arm/boot/dts/overlays/qca7000-overlay.dts | 55 +
- .../dts/overlays/qca7000-uart0-overlay.dts | 46 +
- .../arm/boot/dts/overlays/ramoops-overlay.dts | 25 +
- .../boot/dts/overlays/ramoops-pi4-overlay.dts | 25 +
- .../dts/overlays/rotary-encoder-overlay.dts | 59 +
- .../dts/overlays/rpi-backlight-overlay.dts | 21 +
- .../dts/overlays/rpi-codeczero-overlay.dts | 9 +
- .../boot/dts/overlays/rpi-dacplus-overlay.dts | 17 +
- .../boot/dts/overlays/rpi-dacpro-overlay.dts | 17 +
- .../dts/overlays/rpi-digiampplus-overlay.dts | 17 +
- .../boot/dts/overlays/rpi-ft5406-overlay.dts | 25 +
- .../arm/boot/dts/overlays/rpi-poe-overlay.dts | 154 +
- .../dts/overlays/rpi-poe-plus-overlay.dts | 49 +
- .../boot/dts/overlays/rpi-sense-overlay.dts | 47 +
- .../dts/overlays/rpi-sense-v2-overlay.dts | 47 +
- arch/arm/boot/dts/overlays/rpi-tv-overlay.dts | 34 +
- .../rra-digidac1-wm8741-audio-overlay.dts | 49 +
- .../boot/dts/overlays/sainsmart18-overlay.dts | 52 +
- .../dts/overlays/sc16is750-i2c-overlay.dts | 43 +
- .../dts/overlays/sc16is752-i2c-overlay.dts | 43 +
- .../dts/overlays/sc16is752-spi0-overlay.dts | 49 +
- .../dts/overlays/sc16is752-spi1-overlay.dts | 67 +
- arch/arm/boot/dts/overlays/sdhost-overlay.dts | 38 +
- arch/arm/boot/dts/overlays/sdio-overlay.dts | 77 +
- .../overlays/seeed-can-fd-hat-v1-overlay.dts | 138 +
- .../overlays/seeed-can-fd-hat-v2-overlay.dts | 117 +
- .../boot/dts/overlays/sh1106-spi-overlay.dts | 84 +
- .../boot/dts/overlays/si446x-spi0-overlay.dts | 53 +
- .../arm/boot/dts/overlays/smi-dev-overlay.dts | 20 +
- .../boot/dts/overlays/smi-nand-overlay.dts | 66 +
- arch/arm/boot/dts/overlays/smi-overlay.dts | 37 +
- .../dts/overlays/spi-gpio35-39-overlay.dts | 31 +
- .../dts/overlays/spi-gpio40-45-overlay.dts | 36 +
- .../arm/boot/dts/overlays/spi-rtc-overlay.dts | 75 +
- .../boot/dts/overlays/spi0-0cs-overlay.dts | 39 +
- .../boot/dts/overlays/spi0-1cs-overlay.dts | 42 +
- .../boot/dts/overlays/spi0-2cs-overlay.dts | 37 +
- .../boot/dts/overlays/spi1-1cs-overlay.dts | 57 +
- .../boot/dts/overlays/spi1-2cs-overlay.dts | 69 +
- .../boot/dts/overlays/spi1-3cs-overlay.dts | 81 +
- .../boot/dts/overlays/spi2-1cs-overlay.dts | 57 +
- .../boot/dts/overlays/spi2-2cs-overlay.dts | 69 +
- .../boot/dts/overlays/spi2-3cs-overlay.dts | 81 +
- .../boot/dts/overlays/spi3-1cs-overlay.dts | 44 +
- .../boot/dts/overlays/spi3-2cs-overlay.dts | 56 +
- .../boot/dts/overlays/spi4-1cs-overlay.dts | 44 +
- .../boot/dts/overlays/spi4-2cs-overlay.dts | 56 +
- .../boot/dts/overlays/spi5-1cs-overlay.dts | 44 +
- .../boot/dts/overlays/spi5-2cs-overlay.dts | 56 +
- .../boot/dts/overlays/spi6-1cs-overlay.dts | 44 +
- .../boot/dts/overlays/spi6-2cs-overlay.dts | 56 +
- .../arm/boot/dts/overlays/ssd1306-overlay.dts | 36 +
- .../boot/dts/overlays/ssd1306-spi-overlay.dts | 84 +
- .../boot/dts/overlays/ssd1331-spi-overlay.dts | 83 +
- .../boot/dts/overlays/ssd1351-spi-overlay.dts | 83 +
- .../dts/overlays/superaudioboard-overlay.dts | 73 +
- arch/arm/boot/dts/overlays/sx150x-overlay.dts | 1706 +++++++
- .../dts/overlays/tc358743-audio-overlay.dts | 52 +
- .../boot/dts/overlays/tc358743-overlay.dts | 109 +
- .../boot/dts/overlays/tinylcd35-overlay.dts | 222 +
- .../boot/dts/overlays/tpm-slb9670-overlay.dts | 44 +
- .../boot/dts/overlays/tpm-slb9673-overlay.dts | 50 +
- arch/arm/boot/dts/overlays/uart0-overlay.dts | 32 +
- arch/arm/boot/dts/overlays/uart1-overlay.dts | 38 +
- arch/arm/boot/dts/overlays/uart2-overlay.dts | 27 +
- arch/arm/boot/dts/overlays/uart3-overlay.dts | 27 +
- arch/arm/boot/dts/overlays/uart4-overlay.dts | 27 +
- arch/arm/boot/dts/overlays/uart5-overlay.dts | 27 +
- arch/arm/boot/dts/overlays/udrc-overlay.dts | 128 +
- .../dts/overlays/ugreen-dabboard-overlay.dts | 49 +
- .../boot/dts/overlays/upstream-overlay.dts | 101 +
- .../dts/overlays/upstream-pi4-overlay.dts | 137 +
- .../dts/overlays/vc4-fkms-v3d-overlay.dts | 40 +
- .../dts/overlays/vc4-fkms-v3d-pi4-overlay.dts | 44 +
- .../overlays/vc4-kms-dpi-generic-overlay.dts | 81 +
- .../dts/overlays/vc4-kms-dpi-hyperpixel.dtsi | 94 +
- .../vc4-kms-dpi-hyperpixel2r-overlay.dts | 114 +
- .../vc4-kms-dpi-hyperpixel4-overlay.dts | 57 +
- .../vc4-kms-dpi-hyperpixel4sq-overlay.dts | 36 +
- .../overlays/vc4-kms-dpi-panel-overlay.dts | 69 +
- arch/arm/boot/dts/overlays/vc4-kms-dpi.dtsi | 111 +
- .../overlays/vc4-kms-dsi-7inch-overlay.dts | 118 +
- .../vc4-kms-dsi-lt070me05000-overlay.dts | 69 +
- .../vc4-kms-dsi-lt070me05000-v2-overlay.dts | 64 +
- .../overlays/vc4-kms-kippah-7inch-overlay.dts | 26 +
- .../boot/dts/overlays/vc4-kms-v3d-overlay.dts | 124 +
- .../dts/overlays/vc4-kms-v3d-pi4-overlay.dts | 200 +
- .../dts/overlays/vc4-kms-vga666-overlay.dts | 100 +
- arch/arm/boot/dts/overlays/vga666-overlay.dts | 30 +
- arch/arm/boot/dts/overlays/vl805-overlay.dts | 18 +
- .../arm/boot/dts/overlays/w1-gpio-overlay.dts | 40 +
- .../dts/overlays/w1-gpio-pullup-overlay.dts | 42 +
- arch/arm/boot/dts/overlays/w5500-overlay.dts | 63 +
- .../overlays/watterott-display-overlay.dts | 150 +
- .../waveshare-can-fd-hat-mode-a-overlay.dts | 140 +
- .../waveshare-can-fd-hat-mode-b-overlay.dts | 103 +
- .../arm/boot/dts/overlays/wittypi-overlay.dts | 44 +
- .../dts/overlays/wm8960-soundcard-overlay.dts | 82 +
- arch/arm64/boot/dts/Makefile | 2 +
- arch/arm64/boot/dts/broadcom/Makefile | 14 +
- .../boot/dts/broadcom/bcm2710-rpi-2-b.dts | 1 +
- .../dts/broadcom/bcm2710-rpi-3-b-plus.dts | 1 +
- .../boot/dts/broadcom/bcm2710-rpi-3-b.dts | 1 +
- .../boot/dts/broadcom/bcm2710-rpi-cm3.dts | 1 +
- .../dts/broadcom/bcm2710-rpi-zero-2-w.dts | 1 +
- .../boot/dts/broadcom/bcm2710-rpi-zero-2.dts | 1 +
- .../boot/dts/broadcom/bcm2711-rpi-4-b.dts | 3 +-
- .../boot/dts/broadcom/bcm2711-rpi-400.dts | 3 +-
- .../boot/dts/broadcom/bcm2711-rpi-cm4.dts | 1 +
- .../boot/dts/broadcom/bcm2711-rpi-cm4s.dts | 1 +
- .../dts/broadcom/bcm283x-rpi-csi1-2lane.dtsi | 1 +
- .../dts/broadcom/bcm283x-rpi-lan7515.dtsi | 1 +
- arch/arm64/boot/dts/overlays | 1 +
- include/dt-bindings/gpio/gpio-fsm.h | 21 +
- scripts/Makefile.dtbinst | 3 +-
- scripts/Makefile.lib | 13 +
- 348 files changed, 34772 insertions(+), 16 deletions(-)
- create mode 100644 arch/arm/boot/dts/bcm2708-rpi-b-plus.dts
- create mode 100644 arch/arm/boot/dts/bcm2708-rpi-b-rev1.dts
- create mode 100644 arch/arm/boot/dts/bcm2708-rpi-b.dts
- create mode 100644 arch/arm/boot/dts/bcm2708-rpi-bt.dtsi
- create mode 100644 arch/arm/boot/dts/bcm2708-rpi-cm.dts
- create mode 100644 arch/arm/boot/dts/bcm2708-rpi-cm.dtsi
- create mode 100644 arch/arm/boot/dts/bcm2708-rpi-zero-w.dts
- create mode 100644 arch/arm/boot/dts/bcm2708-rpi-zero.dts
- create mode 100644 arch/arm/boot/dts/bcm2708-rpi.dtsi
- create mode 100644 arch/arm/boot/dts/bcm2708.dtsi
- create mode 100644 arch/arm/boot/dts/bcm2709-rpi-2-b.dts
- create mode 100644 arch/arm/boot/dts/bcm2709-rpi-cm2.dts
- create mode 100644 arch/arm/boot/dts/bcm2709-rpi.dtsi
- create mode 100644 arch/arm/boot/dts/bcm2709.dtsi
- create mode 100644 arch/arm/boot/dts/bcm270x-rpi.dtsi
- create mode 100644 arch/arm/boot/dts/bcm270x.dtsi
- create mode 100644 arch/arm/boot/dts/bcm2710-rpi-2-b.dts
- create mode 100644 arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts
- create mode 100644 arch/arm/boot/dts/bcm2710-rpi-3-b.dts
- create mode 100644 arch/arm/boot/dts/bcm2710-rpi-cm3.dts
- create mode 100644 arch/arm/boot/dts/bcm2710-rpi-zero-2-w.dts
- create mode 100644 arch/arm/boot/dts/bcm2710-rpi-zero-2.dts
- create mode 100644 arch/arm/boot/dts/bcm2710.dtsi
- create mode 100644 arch/arm/boot/dts/bcm2711-rpi-cm4.dts
- create mode 100644 arch/arm/boot/dts/bcm2711-rpi-cm4s.dts
- create mode 100644 arch/arm/boot/dts/bcm2711-rpi-ds.dtsi
- create mode 100644 arch/arm/boot/dts/bcm271x-rpi-bt.dtsi
- create mode 100644 arch/arm/boot/dts/bcm283x-rpi-csi0-2lane.dtsi
- create mode 100644 arch/arm/boot/dts/bcm283x-rpi-csi1-2lane.dtsi
- create mode 100644 arch/arm/boot/dts/bcm283x-rpi-csi1-4lane.dtsi
- create mode 100644 arch/arm/boot/dts/bcm283x-rpi-i2c0mux_0_28.dtsi
- create mode 100644 arch/arm/boot/dts/bcm283x-rpi-i2c0mux_0_44.dtsi
- create mode 100644 arch/arm/boot/dts/overlays/Makefile
- create mode 100644 arch/arm/boot/dts/overlays/README
- create mode 100644 arch/arm/boot/dts/overlays/act-led-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/adafruit-st7735r-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/adafruit18-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/adau1977-adc-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/adau7002-simple-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/ads1015-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/ads1115-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/ads7846-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/adv7282m-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/adv728x-m-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/akkordion-iqdacplus-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/allo-boss-dac-pcm512x-audio-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/allo-boss2-dac-audio-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/allo-digione-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/allo-katana-dac-audio-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/allo-piano-dac-pcm512x-audio-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/allo-piano-dac-plus-pcm512x-audio-overlay.dts
- create mode 100755 arch/arm/boot/dts/overlays/anyspi-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/apds9960-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/applepi-dac-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/arducam-64mp-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/arducam-pivariety-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/at86rf233-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/audioinjector-addons-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/audioinjector-bare-i2s-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/audioinjector-isolated-soundcard-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/audioinjector-ultra-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/audioinjector-wm8731-audio-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/audiosense-pi-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/audremap-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/balena-fin-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/camera-mux-2port-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/camera-mux-4port-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/cap1106-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/chipdip-dac-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/cirrus-wm5102-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/cma-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/cutiepi-panel-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/dacberry400-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/dht11-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/dionaudio-kiwi-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/dionaudio-loco-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/dionaudio-loco-v2-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/disable-bt-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/disable-wifi-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/dpi18-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/dpi18cpadhi-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/dpi24-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/draws-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/dwc-otg-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/dwc2-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/edt-ft5406-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/edt-ft5406.dtsi
- create mode 100644 arch/arm/boot/dts/overlays/enc28j60-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/enc28j60-spi2-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/exc3000-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/fbtft-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/fe-pi-audio-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/fsm-demo-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/gc9a01-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/ghost-amp-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/goodix-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/googlevoicehat-soundcard-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/gpio-fan-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/gpio-hog-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/gpio-ir-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/gpio-ir-tx-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/gpio-key-overlay.dts
- create mode 100755 arch/arm/boot/dts/overlays/gpio-led-overlay.dts
- create mode 100755 arch/arm/boot/dts/overlays/gpio-no-bank0-irq-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/gpio-no-irq-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/gpio-poweroff-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/gpio-shutdown-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/hd44780-lcd-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/hdmi-backlight-hwhack-gpio-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/hifiberry-amp-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/hifiberry-amp100-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/hifiberry-amp3-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/hifiberry-dac-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/hifiberry-dacplusadc-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/hifiberry-dacplusadcpro-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/hifiberry-dacplusdsp-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/hifiberry-dacplushd-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/hifiberry-digi-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/hifiberry-digi-pro-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/highperi-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/hy28a-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/hy28b-2017-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/hy28b-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/i-sabre-q2m-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/i2c-bcm2708-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/i2c-fan-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/i2c-gpio-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/i2c-mux-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/i2c-pwm-pca9685a-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/i2c-rtc-common.dtsi
- create mode 100644 arch/arm/boot/dts/overlays/i2c-rtc-gpio-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts
- create mode 100755 arch/arm/boot/dts/overlays/i2c-sensor-common.dtsi
- create mode 100755 arch/arm/boot/dts/overlays/i2c-sensor-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/i2c0-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/i2c1-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/i2c3-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/i2c4-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/i2c5-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/i2c6-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/i2s-dac-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/i2s-gpio28-31-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/ilitek251x-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/imx219-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/imx219.dtsi
- create mode 100644 arch/arm/boot/dts/overlays/imx258-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/imx258.dtsi
- create mode 100644 arch/arm/boot/dts/overlays/imx290-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/imx290_327-overlay.dtsi
- create mode 100644 arch/arm/boot/dts/overlays/imx290_327.dtsi
- create mode 100644 arch/arm/boot/dts/overlays/imx296-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/imx327-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/imx378-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/imx462-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/imx477-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/imx477_378-overlay.dtsi
- create mode 100644 arch/arm/boot/dts/overlays/imx477_378.dtsi
- create mode 100644 arch/arm/boot/dts/overlays/imx519-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/iqaudio-codec-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/iqaudio-dac-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/iqaudio-dacplus-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/iqaudio-digi-wm8804-audio-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/iqs550-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/irs1125-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/jedec-spi-nor-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/justboom-both-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/justboom-dac-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/justboom-digi-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/ltc294x-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/max98357a-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/maxtherm-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/mbed-dac-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/mcp23017-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/mcp23s17-overlay.dts
- create mode 100755 arch/arm/boot/dts/overlays/mcp2515-can0-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/mcp2515-can1-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/mcp2515-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/mcp251xfd-overlay.dts
- create mode 100755 arch/arm/boot/dts/overlays/mcp3008-overlay.dts
- create mode 100755 arch/arm/boot/dts/overlays/mcp3202-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/mcp342x-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/media-center-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/merus-amp-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/midi-uart0-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/midi-uart1-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/midi-uart2-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/midi-uart3-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/midi-uart4-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/midi-uart5-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/minipitft13-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/miniuart-bt-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/mipi-dbi-spi-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/mlx90640-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/mmc-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/mpu6050-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/mz61581-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/ov2311-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/ov2311.dtsi
- create mode 100644 arch/arm/boot/dts/overlays/ov5647-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/ov5647.dtsi
- create mode 100644 arch/arm/boot/dts/overlays/ov7251-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/ov7251.dtsi
- create mode 100644 arch/arm/boot/dts/overlays/ov9281-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/ov9281.dtsi
- create mode 100644 arch/arm/boot/dts/overlays/overlay_map.dts
- create mode 100644 arch/arm/boot/dts/overlays/papirus-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/pca953x-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/pcie-32bit-dma-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/pibell-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/pifacedigital-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/pifi-40-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/pifi-dac-hd-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/pifi-dac-zero-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/pifi-mini-210-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/piglow-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/piscreen-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/piscreen2r-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/pisound-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/pitft22-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/pitft28-capacitive-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/pitft28-resistive-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/pitft35-resistive-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/pps-gpio-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/proto-codec-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/pwm-2chan-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/pwm-ir-tx-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/pwm-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/qca7000-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/qca7000-uart0-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/ramoops-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/ramoops-pi4-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/rotary-encoder-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/rpi-backlight-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/rpi-codeczero-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/rpi-dacplus-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/rpi-dacpro-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/rpi-digiampplus-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/rpi-poe-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/rpi-poe-plus-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/rpi-sense-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/rpi-sense-v2-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/rpi-tv-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/rra-digidac1-wm8741-audio-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/sainsmart18-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/sc16is750-i2c-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/sc16is752-i2c-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/sc16is752-spi0-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/sc16is752-spi1-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/sdhost-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/sdio-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/seeed-can-fd-hat-v1-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/seeed-can-fd-hat-v2-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/sh1106-spi-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/si446x-spi0-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/smi-dev-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/smi-nand-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/smi-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/spi-gpio35-39-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/spi-gpio40-45-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/spi-rtc-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/spi0-0cs-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/spi0-1cs-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/spi0-2cs-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/spi1-1cs-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/spi1-2cs-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/spi1-3cs-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/spi2-1cs-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/spi2-2cs-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/spi2-3cs-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/spi3-1cs-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/spi3-2cs-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/spi4-1cs-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/spi4-2cs-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/spi5-1cs-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/spi5-2cs-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/spi6-1cs-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/spi6-2cs-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/ssd1306-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/ssd1306-spi-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/ssd1331-spi-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/ssd1351-spi-overlay.dts
- create mode 100755 arch/arm/boot/dts/overlays/superaudioboard-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/sx150x-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/tc358743-audio-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/tc358743-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/tinylcd35-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/tpm-slb9670-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/tpm-slb9673-overlay.dts
- create mode 100755 arch/arm/boot/dts/overlays/uart0-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/uart1-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/uart2-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/uart3-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/uart4-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/uart5-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/udrc-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/ugreen-dabboard-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/upstream-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/upstream-pi4-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/vc4-fkms-v3d-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/vc4-fkms-v3d-pi4-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/vc4-kms-dpi-generic-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/vc4-kms-dpi-hyperpixel.dtsi
- create mode 100644 arch/arm/boot/dts/overlays/vc4-kms-dpi-hyperpixel2r-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/vc4-kms-dpi-hyperpixel4-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/vc4-kms-dpi-hyperpixel4sq-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/vc4-kms-dpi-panel-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/vc4-kms-dpi.dtsi
- create mode 100644 arch/arm/boot/dts/overlays/vc4-kms-dsi-7inch-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/vc4-kms-dsi-lt070me05000-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/vc4-kms-dsi-lt070me05000-v2-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/vc4-kms-kippah-7inch-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/vc4-kms-v3d-pi4-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/vc4-kms-vga666-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/vga666-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/vl805-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/w1-gpio-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/w1-gpio-pullup-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/w5500-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/watterott-display-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/waveshare-can-fd-hat-mode-a-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/waveshare-can-fd-hat-mode-b-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/wittypi-overlay.dts
- create mode 100644 arch/arm/boot/dts/overlays/wm8960-soundcard-overlay.dts
- create mode 100644 arch/arm64/boot/dts/broadcom/bcm2710-rpi-2-b.dts
- create mode 100644 arch/arm64/boot/dts/broadcom/bcm2710-rpi-3-b-plus.dts
- create mode 100644 arch/arm64/boot/dts/broadcom/bcm2710-rpi-3-b.dts
- create mode 100644 arch/arm64/boot/dts/broadcom/bcm2710-rpi-cm3.dts
- create mode 100644 arch/arm64/boot/dts/broadcom/bcm2710-rpi-zero-2-w.dts
- create mode 100644 arch/arm64/boot/dts/broadcom/bcm2710-rpi-zero-2.dts
- create mode 100644 arch/arm64/boot/dts/broadcom/bcm2711-rpi-cm4.dts
- create mode 100644 arch/arm64/boot/dts/broadcom/bcm2711-rpi-cm4s.dts
- create mode 120000 arch/arm64/boot/dts/broadcom/bcm283x-rpi-csi1-2lane.dtsi
- create mode 120000 arch/arm64/boot/dts/broadcom/bcm283x-rpi-lan7515.dtsi
- create mode 120000 arch/arm64/boot/dts/overlays
- create mode 100644 include/dt-bindings/gpio/gpio-fsm.h
-
-diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
-index 6aa7dc4db2fc..f7d8d09c0a16 100644
---- a/arch/arm/boot/dts/Makefile
-+++ b/arch/arm/boot/dts/Makefile
-@@ -1,4 +1,25 @@
- # SPDX-License-Identifier: GPL-2.0
-+
-+dtb-$(CONFIG_ARCH_BCM2835) += \
-+ bcm2708-rpi-b.dtb \
-+ bcm2708-rpi-b-rev1.dtb \
-+ bcm2708-rpi-b-plus.dtb \
-+ bcm2708-rpi-cm.dtb \
-+ bcm2708-rpi-zero.dtb \
-+ bcm2708-rpi-zero-w.dtb \
-+ bcm2710-rpi-zero-2.dtb \
-+ bcm2710-rpi-zero-2-w.dtb \
-+ bcm2709-rpi-2-b.dtb \
-+ bcm2710-rpi-2-b.dtb \
-+ bcm2710-rpi-3-b.dtb \
-+ bcm2710-rpi-3-b-plus.dtb \
-+ bcm2711-rpi-4-b.dtb \
-+ bcm2711-rpi-400.dtb \
-+ bcm2709-rpi-cm2.dtb \
-+ bcm2710-rpi-cm3.dtb \
-+ bcm2711-rpi-cm4.dtb \
-+ bcm2711-rpi-cm4s.dtb
-+
- dtb-$(CONFIG_ARCH_ALPINE) += \
- alpine-db.dtb
- dtb-$(CONFIG_MACH_ARTPEC6) += \
-@@ -1633,3 +1654,13 @@ dtb-$(CONFIG_ARCH_ASPEED) += \
- aspeed-bmc-vegman-n110.dtb \
- aspeed-bmc-vegman-rx20.dtb \
- aspeed-bmc-vegman-sx20.dtb
-+
-+targets += dtbs dtbs_install
-+targets += $(dtb-y)
-+
-+subdir-y := overlays
-+
-+# Enable fixups to support overlays on BCM2835 platforms
-+ifeq ($(CONFIG_ARCH_BCM2835),y)
-+ DTC_FLAGS += -@
-+endif
-diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts
-new file mode 100644
-index 000000000000..b3b18a7b5fe9
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts
-@@ -0,0 +1,200 @@
-+/dts-v1/;
-+
-+#include "bcm2708.dtsi"
-+#include "bcm2708-rpi.dtsi"
-+#include "bcm283x-rpi-smsc9514.dtsi"
-+#include "bcm283x-rpi-csi1-2lane.dtsi"
-+#include "bcm283x-rpi-i2c0mux_0_28.dtsi"
-+
-+/ {
-+ compatible = "raspberrypi,model-b-plus", "brcm,bcm2835";
-+ model = "Raspberry Pi Model B+";
-+};
-+
-+&gpio {
-+ /*
-+ * Taken from Raspberry-Pi-B-Plus-V1.2-Schematics.pdf
-+ * RPI-BPLUS sheet 1
-+ *
-+ * Legend:
-+ * "NC" = not connected (no rail from the SoC)
-+ * "FOO" = GPIO line named "FOO" on the schematic
-+ * "FOO_N" = GPIO line named "FOO" on schematic, active low
-+ */
-+ gpio-line-names = "ID_SDA",
-+ "ID_SCL",
-+ "SDA1",
-+ "SCL1",
-+ "GPIO_GCLK",
-+ "GPIO5",
-+ "GPIO6",
-+ "SPI_CE1_N",
-+ "SPI_CE0_N",
-+ "SPI_MISO",
-+ "SPI_MOSI",
-+ "SPI_SCLK",
-+ "GPIO12",
-+ "GPIO13",
-+ /* Serial port */
-+ "TXD0",
-+ "RXD0",
-+ "GPIO16",
-+ "GPIO17",
-+ "GPIO18",
-+ "GPIO19",
-+ "GPIO20",
-+ "GPIO21",
-+ "GPIO22",
-+ "GPIO23",
-+ "GPIO24",
-+ "GPIO25",
-+ "GPIO26",
-+ "GPIO27",
-+ "SDA0",
-+ "SCL0",
-+ "NC", /* GPIO30 */
-+ "LAN_RUN", /* GPIO31 */
-+ "CAM_GPIO1", /* GPIO32 */
-+ "NC", /* GPIO33 */
-+ "NC", /* GPIO34 */
-+ "PWR_LOW_N", /* GPIO35 */
-+ "NC", /* GPIO36 */
-+ "NC", /* GPIO37 */
-+ "USB_LIMIT", /* GPIO38 */
-+ "NC", /* GPIO39 */
-+ "PWM0_OUT", /* GPIO40 */
-+ "CAM_GPIO0", /* GPIO41 */
-+ "NC", /* GPIO42 */
-+ "NC", /* GPIO43 */
-+ "ETH_CLK", /* GPIO44 */
-+ "PWM1_OUT", /* GPIO45 */
-+ "HDMI_HPD_N",
-+ "STATUS_LED",
-+ /* Used by SD Card */
-+ "SD_CLK_R",
-+ "SD_CMD_R",
-+ "SD_DATA0_R",
-+ "SD_DATA1_R",
-+ "SD_DATA2_R",
-+ "SD_DATA3_R";
-+
-+ spi0_pins: spi0_pins {
-+ brcm,pins = <9 10 11>;
-+ brcm,function = <4>; /* alt0 */
-+ };
-+
-+ spi0_cs_pins: spi0_cs_pins {
-+ brcm,pins = <8 7>;
-+ brcm,function = <1>; /* output */
-+ };
-+
-+ i2c0_pins: i2c0 {
-+ brcm,pins = <0 1>;
-+ brcm,function = <4>;
-+ };
-+
-+ i2c1_pins: i2c1 {
-+ brcm,pins = <2 3>;
-+ brcm,function = <4>;
-+ };
-+
-+ i2s_pins: i2s {
-+ brcm,pins = <18 19 20 21>;
-+ brcm,function = <4>; /* alt0 */
-+ };
-+
-+ audio_pins: audio_pins {
-+ brcm,pins = <40 45>;
-+ brcm,function = <4>;
-+ brcm,pull = <0>;
-+ };
-+};
-+
-+&uart0 {
-+ status = "okay";
-+};
-+
-+&spi0 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&spi0_pins &spi0_cs_pins>;
-+ cs-gpios = <&gpio 8 1>, <&gpio 7 1>;
-+
-+ spidev0: spidev@0{
-+ compatible = "spidev";
-+ reg = <0>; /* CE0 */
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ spi-max-frequency = <125000000>;
-+ };
-+
-+ spidev1: spidev@1{
-+ compatible = "spidev";
-+ reg = <1>; /* CE1 */
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ spi-max-frequency = <125000000>;
-+ };
-+};
-+
-+&i2c0if {
-+ clock-frequency = <100000>;
-+};
-+
-+&i2c1 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&i2c1_pins>;
-+ clock-frequency = <100000>;
-+};
-+
-+&i2c2 {
-+ clock-frequency = <100000>;
-+};
-+
-+&i2s {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&i2s_pins>;
-+};
-+
-+&leds {
-+ act_led: led-act {
-+ label = "led0";
-+ linux,default-trigger = "mmc0";
-+ gpios = <&gpio 47 0>;
-+ };
-+
-+ pwr_led: led-pwr {
-+ label = "led1";
-+ linux,default-trigger = "input";
-+ gpios = <&gpio 35 0>;
-+ };
-+};
-+
-+&hdmi {
-+ hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>;
-+};
-+
-+&vchiq {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&audio_pins>;
-+};
-+
-+&cam1_reg {
-+ gpio = <&gpio 41 GPIO_ACTIVE_HIGH>;
-+};
-+
-+cam0_reg: &cam_dummy_reg {
-+};
-+
-+/ {
-+ __overrides__ {
-+ audio = <&chosen>,"bootargs{on='snd_bcm2835.enable_headphones=1 snd_bcm2835.enable_hdmi=1',off='snd_bcm2835.enable_headphones=0 snd_bcm2835.enable_hdmi=0'}";
-+
-+ act_led_gpio = <&act_led>,"gpios:4";
-+ act_led_activelow = <&act_led>,"gpios:8";
-+ act_led_trigger = <&act_led>,"linux,default-trigger";
-+
-+ pwr_led_gpio = <&pwr_led>,"gpios:4";
-+ pwr_led_activelow = <&pwr_led>,"gpios:8";
-+ pwr_led_trigger = <&pwr_led>,"linux,default-trigger";
-+ };
-+};
-diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-rev1.dts b/arch/arm/boot/dts/bcm2708-rpi-b-rev1.dts
-new file mode 100644
-index 000000000000..50ac75e8d3d9
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm2708-rpi-b-rev1.dts
-@@ -0,0 +1,208 @@
-+/dts-v1/;
-+
-+#include "bcm2708.dtsi"
-+#include "bcm2708-rpi.dtsi"
-+#include "bcm283x-rpi-smsc9512.dtsi"
-+#include "bcm283x-rpi-csi1-2lane.dtsi"
-+
-+/ {
-+ compatible = "raspberrypi,model-b", "brcm,bcm2835";
-+ model = "Raspberry Pi Model B";
-+};
-+
-+&gpio {
-+ /*
-+ * Taken from Raspberry-Pi-Rev-1.0-Model-AB-Schematics.pdf
-+ * RPI00021 sheet 02
-+ *
-+ * Legend:
-+ * "NC" = not connected (no rail from the SoC)
-+ * "FOO" = GPIO line named "FOO" on the schematic
-+ * "FOO_N" = GPIO line named "FOO" on schematic, active low
-+ */
-+ gpio-line-names = "SDA0",
-+ "SCL0",
-+ "SDA1",
-+ "SCL1",
-+ "GPIO_GCLK",
-+ "CAM_GPIO1",
-+ "LAN_RUN",
-+ "SPI_CE1_N",
-+ "SPI_CE0_N",
-+ "SPI_MISO",
-+ "SPI_MOSI",
-+ "SPI_SCLK",
-+ "NC", /* GPIO12 */
-+ "NC", /* GPIO13 */
-+ /* Serial port */
-+ "TXD0",
-+ "RXD0",
-+ "STATUS_LED_N",
-+ "GPIO17",
-+ "GPIO18",
-+ "NC", /* GPIO19 */
-+ "NC", /* GPIO20 */
-+ "GPIO21",
-+ "GPIO22",
-+ "GPIO23",
-+ "GPIO24",
-+ "GPIO25",
-+ "NC", /* GPIO26 */
-+ "CAM_GPIO0",
-+ /* Binary number representing build/revision */
-+ "CONFIG0",
-+ "CONFIG1",
-+ "CONFIG2",
-+ "CONFIG3",
-+ "NC", /* GPIO32 */
-+ "NC", /* GPIO33 */
-+ "NC", /* GPIO34 */
-+ "NC", /* GPIO35 */
-+ "NC", /* GPIO36 */
-+ "NC", /* GPIO37 */
-+ "NC", /* GPIO38 */
-+ "NC", /* GPIO39 */
-+ "PWM0_OUT",
-+ "NC", /* GPIO41 */
-+ "NC", /* GPIO42 */
-+ "NC", /* GPIO43 */
-+ "NC", /* GPIO44 */
-+ "PWM1_OUT",
-+ "HDMI_HPD_P",
-+ "SD_CARD_DET",
-+ /* Used by SD Card */
-+ "SD_CLK_R",
-+ "SD_CMD_R",
-+ "SD_DATA0_R",
-+ "SD_DATA1_R",
-+ "SD_DATA2_R",
-+ "SD_DATA3_R";
-+
-+ spi0_pins: spi0_pins {
-+ brcm,pins = <9 10 11>;
-+ brcm,function = <4>; /* alt0 */
-+ };
-+
-+ spi0_cs_pins: spi0_cs_pins {
-+ brcm,pins = <8 7>;
-+ brcm,function = <1>; /* output */
-+ };
-+
-+ i2c0_pins: i2c0 {
-+ brcm,pins = <0 1>;
-+ brcm,function = <4>;
-+ };
-+
-+ i2c1_pins: i2c1 {
-+ brcm,pins = <2 3>;
-+ brcm,function = <4>;
-+ };
-+
-+ i2s_pins: i2s {
-+ brcm,pins = <28 29 30 31>;
-+ brcm,function = <6>; /* alt2 */
-+ };
-+
-+ audio_pins: audio_pins {
-+ brcm,pins = <40 45>;
-+ brcm,function = <4>;
-+ brcm,pull = <0>;
-+ };
-+};
-+
-+&uart0 {
-+ status = "okay";
-+};
-+
-+&spi0 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&spi0_pins &spi0_cs_pins>;
-+ cs-gpios = <&gpio 8 1>, <&gpio 7 1>;
-+
-+ spidev0: spidev@0{
-+ compatible = "spidev";
-+ reg = <0>; /* CE0 */
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ spi-max-frequency = <125000000>;
-+ };
-+
-+ spidev1: spidev@1{
-+ compatible = "spidev";
-+ reg = <1>; /* CE1 */
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ spi-max-frequency = <125000000>;
-+ };
-+};
-+
-+/delete-node/ &i2c0mux;
-+
-+i2c0: &i2c0if {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&i2c0_pins>;
-+ clock-frequency = <100000>;
-+};
-+
-+i2c_csi_dsi: &i2c1 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&i2c1_pins>;
-+ clock-frequency = <100000>;
-+};
-+
-+/ {
-+ aliases {
-+ i2c0 = &i2c0;
-+ };
-+
-+ /* Provide an i2c0mux label to avoid undefined symbols in overlays */
-+ i2c0mux: i2c0mux {
-+ };
-+
-+ __overrides__ {
-+ i2c0 = <&i2c0>, "status";
-+ };
-+};
-+
-+&i2c2 {
-+ clock-frequency = <100000>;
-+};
-+
-+&i2s {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&i2s_pins>;
-+};
-+
-+&leds {
-+ act_led: led-act {
-+ label = "led0";
-+ linux,default-trigger = "mmc0";
-+ gpios = <&gpio 16 1>;
-+ };
-+};
-+
-+&hdmi {
-+ hpd-gpios = <&gpio 46 GPIO_ACTIVE_HIGH>;
-+};
-+
-+&vchiq {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&audio_pins>;
-+};
-+
-+&cam1_reg {
-+ gpio = <&gpio 27 GPIO_ACTIVE_HIGH>;
-+};
-+
-+cam0_reg: &cam_dummy_reg {
-+};
-+
-+/ {
-+ __overrides__ {
-+ audio = <&chosen>,"bootargs{on='snd_bcm2835.enable_headphones=1 snd_bcm2835.enable_hdmi=1',off='snd_bcm2835.enable_headphones=0 snd_bcm2835.enable_hdmi=0'}";
-+
-+ act_led_gpio = <&act_led>,"gpios:4";
-+ act_led_activelow = <&act_led>,"gpios:8";
-+ act_led_trigger = <&act_led>,"linux,default-trigger";
-+ };
-+};
-diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts
-new file mode 100644
-index 000000000000..4d7444a31bb6
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts
-@@ -0,0 +1,190 @@
-+/dts-v1/;
-+
-+#include "bcm2708.dtsi"
-+#include "bcm2708-rpi.dtsi"
-+#include "bcm283x-rpi-smsc9512.dtsi"
-+#include "bcm283x-rpi-csi1-2lane.dtsi"
-+#include "bcm283x-rpi-i2c0mux_0_28.dtsi"
-+
-+/ {
-+ compatible = "raspberrypi,model-b", "brcm,bcm2835";
-+ model = "Raspberry Pi Model B";
-+};
-+
-+&gpio {
-+ /*
-+ * Taken from Raspberry-Pi-Rev-2.0-Model-AB-Schematics.pdf
-+ * RPI00022 sheet 02
-+ *
-+ * Legend:
-+ * "NC" = not connected (no rail from the SoC)
-+ * "FOO" = GPIO line named "FOO" on the schematic
-+ * "FOO_N" = GPIO line named "FOO" on schematic, active low
-+ */
-+ gpio-line-names = "SDA0",
-+ "SCL0",
-+ "SDA1",
-+ "SCL1",
-+ "GPIO_GCLK",
-+ "CAM_GPIO1",
-+ "LAN_RUN",
-+ "SPI_CE1_N",
-+ "SPI_CE0_N",
-+ "SPI_MISO",
-+ "SPI_MOSI",
-+ "SPI_SCLK",
-+ "NC", /* GPIO12 */
-+ "NC", /* GPIO13 */
-+ /* Serial port */
-+ "TXD0",
-+ "RXD0",
-+ "STATUS_LED_N",
-+ "GPIO17",
-+ "GPIO18",
-+ "NC", /* GPIO19 */
-+ "NC", /* GPIO20 */
-+ "CAM_GPIO0",
-+ "GPIO22",
-+ "GPIO23",
-+ "GPIO24",
-+ "GPIO25",
-+ "NC", /* GPIO26 */
-+ "GPIO27",
-+ "GPIO28",
-+ "GPIO29",
-+ "GPIO30",
-+ "GPIO31",
-+ "NC", /* GPIO32 */
-+ "NC", /* GPIO33 */
-+ "NC", /* GPIO34 */
-+ "NC", /* GPIO35 */
-+ "NC", /* GPIO36 */
-+ "NC", /* GPIO37 */
-+ "NC", /* GPIO38 */
-+ "NC", /* GPIO39 */
-+ "PWM0_OUT",
-+ "NC", /* GPIO41 */
-+ "NC", /* GPIO42 */
-+ "NC", /* GPIO43 */
-+ "NC", /* GPIO44 */
-+ "PWM1_OUT",
-+ "HDMI_HPD_P",
-+ "SD_CARD_DET",
-+ /* Used by SD Card */
-+ "SD_CLK_R",
-+ "SD_CMD_R",
-+ "SD_DATA0_R",
-+ "SD_DATA1_R",
-+ "SD_DATA2_R",
-+ "SD_DATA3_R";
-+
-+ spi0_pins: spi0_pins {
-+ brcm,pins = <9 10 11>;
-+ brcm,function = <4>; /* alt0 */
-+ };
-+
-+ spi0_cs_pins: spi0_cs_pins {
-+ brcm,pins = <8 7>;
-+ brcm,function = <1>; /* output */
-+ };
-+
-+ i2c0_pins: i2c0 {
-+ brcm,pins = <0 1>;
-+ brcm,function = <4>;
-+ };
-+
-+ i2c1_pins: i2c1 {
-+ brcm,pins = <2 3>;
-+ brcm,function = <4>;
-+ };
-+
-+ i2s_pins: i2s {
-+ brcm,pins = <28 29 30 31>;
-+ brcm,function = <6>; /* alt2 */
-+ };
-+
-+ audio_pins: audio_pins {
-+ brcm,pins = <40 45>;
-+ brcm,function = <4>;
-+ brcm,pull = <0>;
-+ };
-+};
-+
-+&uart0 {
-+ status = "okay";
-+};
-+
-+&spi0 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&spi0_pins &spi0_cs_pins>;
-+ cs-gpios = <&gpio 8 1>, <&gpio 7 1>;
-+
-+ spidev0: spidev@0{
-+ compatible = "spidev";
-+ reg = <0>; /* CE0 */
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ spi-max-frequency = <125000000>;
-+ };
-+
-+ spidev1: spidev@1{
-+ compatible = "spidev";
-+ reg = <1>; /* CE1 */
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ spi-max-frequency = <125000000>;
-+ };
-+};
-+
-+&i2c0if {
-+ clock-frequency = <100000>;
-+};
-+
-+&i2c1 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&i2c1_pins>;
-+ clock-frequency = <100000>;
-+};
-+
-+&i2c2 {
-+ clock-frequency = <100000>;
-+};
-+
-+&i2s {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&i2s_pins>;
-+};
-+
-+&leds {
-+ act_led: led-act {
-+ label = "led0";
-+ linux,default-trigger = "mmc0";
-+ gpios = <&gpio 16 1>;
-+ };
-+};
-+
-+&hdmi {
-+ hpd-gpios = <&gpio 46 GPIO_ACTIVE_HIGH>;
-+};
-+
-+&vchiq {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&audio_pins>;
-+};
-+
-+&cam1_reg {
-+ gpio = <&gpio 21 GPIO_ACTIVE_HIGH>;
-+};
-+
-+cam0_reg: &cam_dummy_reg {
-+};
-+
-+/ {
-+ __overrides__ {
-+ audio = <&chosen>,"bootargs{on='snd_bcm2835.enable_headphones=1 snd_bcm2835.enable_hdmi=1',off='snd_bcm2835.enable_headphones=0 snd_bcm2835.enable_hdmi=0'}";
-+
-+ act_led_gpio = <&act_led>,"gpios:4";
-+ act_led_activelow = <&act_led>,"gpios:8";
-+ act_led_trigger = <&act_led>,"linux,default-trigger";
-+ };
-+};
-diff --git a/arch/arm/boot/dts/bcm2708-rpi-bt.dtsi b/arch/arm/boot/dts/bcm2708-rpi-bt.dtsi
-new file mode 100644
-index 000000000000..a18f80af97d3
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm2708-rpi-bt.dtsi
-@@ -0,0 +1,26 @@
-+// SPDX-License-Identifier: GPL-2.0
-+
-+&uart0 {
-+ bt: bluetooth {
-+ compatible = "brcm,bcm43438-bt";
-+ max-speed = <3000000>;
-+ shutdown-gpios = <&gpio 45 GPIO_ACTIVE_HIGH>;
-+ status = "disabled";
-+ };
-+};
-+
-+&uart1 {
-+ minibt: bluetooth {
-+ compatible = "brcm,bcm43438-bt";
-+ max-speed = <460800>;
-+ shutdown-gpios = <&gpio 45 GPIO_ACTIVE_HIGH>;
-+ status = "disabled";
-+ };
-+};
-+
-+/ {
-+ __overrides__ {
-+ krnbt = <&bt>,"status";
-+ krnbt_baudrate = <&bt>,"max-speed:0";
-+ };
-+};
-diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dts b/arch/arm/boot/dts/bcm2708-rpi-cm.dts
-new file mode 100644
-index 000000000000..6a97189afe58
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dts
-@@ -0,0 +1,171 @@
-+/dts-v1/;
-+
-+#include "bcm2708-rpi-cm.dtsi"
-+#include "bcm283x-rpi-csi0-2lane.dtsi"
-+#include "bcm283x-rpi-csi1-4lane.dtsi"
-+#include "bcm283x-rpi-i2c0mux_0_28.dtsi"
-+
-+/ {
-+ compatible = "raspberrypi,compute-module", "brcm,bcm2835";
-+ model = "Raspberry Pi Compute Module";
-+};
-+
-+&cam1_reg {
-+ gpio = <&gpio 2 GPIO_ACTIVE_HIGH>;
-+ status = "disabled";
-+};
-+
-+cam0_reg: &cam0_regulator {
-+ gpio = <&gpio 30 GPIO_ACTIVE_HIGH>;
-+};
-+
-+&uart0 {
-+ status = "okay";
-+};
-+
-+&gpio {
-+ /*
-+ * This is based on the official GPU firmware DT blob.
-+ *
-+ * Legend:
-+ * "NC" = not connected (no rail from the SoC)
-+ * "FOO" = GPIO line named "FOO" on the schematic
-+ * "FOO_N" = GPIO line named "FOO" on schematic, active low
-+ */
-+ gpio-line-names = "GPIO0",
-+ "GPIO1",
-+ "GPIO2",
-+ "GPIO3",
-+ "GPIO4",
-+ "GPIO5",
-+ "GPIO6",
-+ "GPIO7",
-+ "GPIO8",
-+ "GPIO9",
-+ "GPIO10",
-+ "GPIO11",
-+ "GPIO12",
-+ "GPIO13",
-+ "GPIO14",
-+ "GPIO15",
-+ "GPIO16",
-+ "GPIO17",
-+ "GPIO18",
-+ "GPIO19",
-+ "GPIO20",
-+ "GPIO21",
-+ "GPIO22",
-+ "GPIO23",
-+ "GPIO24",
-+ "GPIO25",
-+ "GPIO26",
-+ "GPIO27",
-+ "GPIO28",
-+ "GPIO29",
-+ "GPIO30",
-+ "GPIO31",
-+ "GPIO32",
-+ "GPIO33",
-+ "GPIO34",
-+ "GPIO35",
-+ "GPIO36",
-+ "GPIO37",
-+ "GPIO38",
-+ "GPIO39",
-+ "GPIO40",
-+ "GPIO41",
-+ "GPIO42",
-+ "GPIO43",
-+ "GPIO44",
-+ "GPIO45",
-+ "HDMI_HPD_N",
-+ /* Also used as ACT LED */
-+ "EMMC_EN_N",
-+ /* Used by eMMC */
-+ "SD_CLK_R",
-+ "SD_CMD_R",
-+ "SD_DATA0_R",
-+ "SD_DATA1_R",
-+ "SD_DATA2_R",
-+ "SD_DATA3_R";
-+
-+ spi0_pins: spi0_pins {
-+ brcm,pins = <9 10 11>;
-+ brcm,function = <4>; /* alt0 */
-+ };
-+
-+ spi0_cs_pins: spi0_cs_pins {
-+ brcm,pins = <8 7>;
-+ brcm,function = <1>; /* output */
-+ };
-+
-+ i2c0_pins: i2c0 {
-+ brcm,pins = <0 1>;
-+ brcm,function = <4>;
-+ };
-+
-+ i2c1_pins: i2c1 {
-+ brcm,pins = <2 3>;
-+ brcm,function = <4>;
-+ };
-+
-+ i2s_pins: i2s {
-+ brcm,pins = <18 19 20 21>;
-+ brcm,function = <4>; /* alt0 */
-+ };
-+
-+ audio_pins: audio_pins {
-+ brcm,pins;
-+ brcm,function;
-+ };
-+};
-+
-+&spi0 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&spi0_pins &spi0_cs_pins>;
-+ cs-gpios = <&gpio 8 1>, <&gpio 7 1>;
-+
-+ spidev0: spidev@0{
-+ compatible = "spidev";
-+ reg = <0>; /* CE0 */
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ spi-max-frequency = <125000000>;
-+ };
-+
-+ spidev1: spidev@1{
-+ compatible = "spidev";
-+ reg = <1>; /* CE1 */
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ spi-max-frequency = <125000000>;
-+ };
-+};
-+
-+&i2c0if {
-+ clock-frequency = <100000>;
-+};
-+
-+&i2c1 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&i2c1_pins>;
-+ clock-frequency = <100000>;
-+};
-+
-+&i2c2 {
-+ clock-frequency = <100000>;
-+};
-+
-+&i2s {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&i2s_pins>;
-+};
-+
-+&vchiq {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&audio_pins>;
-+};
-+
-+&hdmi {
-+ hpd-gpios = <&gpio 46 GPIO_ACTIVE_HIGH>;
-+};
-diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi
-new file mode 100644
-index 000000000000..c7845d2ba7ff
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi
-@@ -0,0 +1,22 @@
-+#include "bcm2708.dtsi"
-+#include "bcm2708-rpi.dtsi"
-+
-+&leds {
-+ act_led: led-act {
-+ label = "led0";
-+ linux,default-trigger = "mmc0";
-+ gpios = <&gpio 47 0>;
-+ };
-+};
-+
-+/ {
-+ __overrides__ {
-+ act_led_gpio = <&act_led>,"gpios:4";
-+ act_led_activelow = <&act_led>,"gpios:8";
-+ act_led_trigger = <&act_led>,"linux,default-trigger";
-+ cam0_reg = <&cam0_reg>,"status";
-+ cam0_reg_gpio = <&cam0_reg>,"gpio:4";
-+ cam1_reg = <&cam1_reg>,"status";
-+ cam1_reg_gpio = <&cam1_reg>,"gpio:4";
-+ };
-+};
-diff --git a/arch/arm/boot/dts/bcm2708-rpi-zero-w.dts b/arch/arm/boot/dts/bcm2708-rpi-zero-w.dts
-new file mode 100644
-index 000000000000..323fa2ebf730
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm2708-rpi-zero-w.dts
-@@ -0,0 +1,246 @@
-+/dts-v1/;
-+
-+#include "bcm2708.dtsi"
-+#include "bcm2708-rpi.dtsi"
-+#include "bcm283x-rpi-csi1-2lane.dtsi"
-+#include "bcm283x-rpi-i2c0mux_0_28.dtsi"
-+#include "bcm2708-rpi-bt.dtsi"
-+
-+/ {
-+ compatible = "raspberrypi,model-zero-w", "brcm,bcm2835";
-+ model = "Raspberry Pi Zero W";
-+
-+ chosen {
-+ bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_headphones=0";
-+ };
-+
-+ aliases {
-+ serial0 = &uart1;
-+ serial1 = &uart0;
-+ mmc1 = &mmcnr;
-+ };
-+};
-+
-+&gpio {
-+ /*
-+ * This is based on the official GPU firmware DT blob.
-+ *
-+ * Legend:
-+ * "NC" = not connected (no rail from the SoC)
-+ * "FOO" = GPIO line named "FOO" on the schematic
-+ * "FOO_N" = GPIO line named "FOO" on schematic, active low
-+ */
-+ gpio-line-names = "ID_SDA",
-+ "ID_SCL",
-+ "SDA1",
-+ "SCL1",
-+ "GPIO_GCLK",
-+ "GPIO5",
-+ "GPIO6",
-+ "SPI_CE1_N",
-+ "SPI_CE0_N",
-+ "SPI_MISO",
-+ "SPI_MOSI",
-+ "SPI_SCLK",
-+ "GPIO12",
-+ "GPIO13",
-+ /* Serial port */
-+ "TXD1",
-+ "RXD1",
-+ "GPIO16",
-+ "GPIO17",
-+ "GPIO18",
-+ "GPIO19",
-+ "GPIO20",
-+ "GPIO21",
-+ "GPIO22",
-+ "GPIO23",
-+ "GPIO24",
-+ "GPIO25",
-+ "GPIO26",
-+ "GPIO27",
-+ "SDA0",
-+ "SCL0",
-+ /* Used by BT module */
-+ "CTS0",
-+ "RTS0",
-+ "TXD0",
-+ "RXD0",
-+ /* Used by Wifi */
-+ "SD1_CLK",
-+ "SD1_CMD",
-+ "SD1_DATA0",
-+ "SD1_DATA1",
-+ "SD1_DATA2",
-+ "SD1_DATA3",
-+ "CAM_GPIO1", /* GPIO40 */
-+ "WL_ON", /* GPIO41 */
-+ "NC", /* GPIO42 */
-+ "WIFI_CLK", /* GPIO43 */
-+ "CAM_GPIO0", /* GPIO44 */
-+ "BT_ON", /* GPIO45 */
-+ "HDMI_HPD_N",
-+ "STATUS_LED_N",
-+ /* Used by SD Card */
-+ "SD_CLK_R",
-+ "SD_CMD_R",
-+ "SD_DATA0_R",
-+ "SD_DATA1_R",
-+ "SD_DATA2_R",
-+ "SD_DATA3_R";
-+
-+ spi0_pins: spi0_pins {
-+ brcm,pins = <9 10 11>;
-+ brcm,function = <4>; /* alt0 */
-+ };
-+
-+ spi0_cs_pins: spi0_cs_pins {
-+ brcm,pins = <8 7>;
-+ brcm,function = <1>; /* output */
-+ };
-+
-+ i2c0_pins: i2c0 {
-+ brcm,pins = <0 1>;
-+ brcm,function = <4>;
-+ };
-+
-+ i2c1_pins: i2c1 {
-+ brcm,pins = <2 3>;
-+ brcm,function = <4>;
-+ };
-+
-+ i2s_pins: i2s {
-+ brcm,pins = <18 19 20 21>;
-+ brcm,function = <4>; /* alt0 */
-+ };
-+
-+ sdio_pins: sdio_pins {
-+ brcm,pins = <34 35 36 37 38 39>;
-+ brcm,function = <7>; /* ALT3 = SD1 */
-+ brcm,pull = <0 2 2 2 2 2>;
-+ };
-+
-+ bt_pins: bt_pins {
-+ brcm,pins = <43>;
-+ brcm,function = <4>; /* alt0:GPCLK2 */
-+ brcm,pull = <0>; /* none */
-+ };
-+
-+ uart0_pins: uart0_pins {
-+ brcm,pins = <30 31 32 33>;
-+ brcm,function = <7>; /* alt3=UART0 */
-+ brcm,pull = <2 0 0 2>; /* up none none up */
-+ };
-+
-+ uart1_pins: uart1_pins {
-+ brcm,pins;
-+ brcm,function;
-+ brcm,pull;
-+ };
-+
-+ audio_pins: audio_pins {
-+ brcm,pins = <>;
-+ brcm,function = <>;
-+ };
-+};
-+
-+&mmcnr {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&sdio_pins>;
-+ bus-width = <4>;
-+ status = "okay";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ brcmf: wifi@1 {
-+ reg = <1>;
-+ compatible = "brcm,bcm4329-fmac";
-+ };
-+};
-+
-+&uart0 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&uart0_pins &bt_pins>;
-+ status = "okay";
-+};
-+
-+&uart1 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&uart1_pins>;
-+ status = "okay";
-+};
-+
-+&spi0 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&spi0_pins &spi0_cs_pins>;
-+ cs-gpios = <&gpio 8 1>, <&gpio 7 1>;
-+
-+ spidev0: spidev@0{
-+ compatible = "spidev";
-+ reg = <0>; /* CE0 */
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ spi-max-frequency = <125000000>;
-+ };
-+
-+ spidev1: spidev@1{
-+ compatible = "spidev";
-+ reg = <1>; /* CE1 */
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ spi-max-frequency = <125000000>;
-+ };
-+};
-+
-+&i2c0if {
-+ clock-frequency = <100000>;
-+};
-+
-+&i2c1 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&i2c1_pins>;
-+ clock-frequency = <100000>;
-+};
-+
-+&i2c2 {
-+ clock-frequency = <100000>;
-+};
-+
-+&i2s {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&i2s_pins>;
-+};
-+
-+&leds {
-+ act_led: led-act {
-+ label = "led0";
-+ linux,default-trigger = "actpwr";
-+ gpios = <&gpio 47 GPIO_ACTIVE_LOW>;
-+ };
-+};
-+
-+&hdmi {
-+ hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>;
-+};
-+
-+&vchiq {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&audio_pins>;
-+};
-+
-+&cam1_reg {
-+ gpio = <&gpio 44 GPIO_ACTIVE_HIGH>;
-+};
-+
-+cam0_reg: &cam_dummy_reg {
-+};
-+
-+/ {
-+ __overrides__ {
-+ audio = <&chosen>,"bootargs{on='snd_bcm2835.enable_hdmi=1',off='snd_bcm2835.enable_hdmi=0'}";
-+
-+ act_led_gpio = <&act_led>,"gpios:4";
-+ act_led_activelow = <&act_led>,"gpios:8";
-+ act_led_trigger = <&act_led>,"linux,default-trigger";
-+ };
-+};
-diff --git a/arch/arm/boot/dts/bcm2708-rpi-zero.dts b/arch/arm/boot/dts/bcm2708-rpi-zero.dts
-new file mode 100644
-index 000000000000..406f945d4093
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm2708-rpi-zero.dts
-@@ -0,0 +1,187 @@
-+/dts-v1/;
-+
-+#include "bcm2708.dtsi"
-+#include "bcm2708-rpi.dtsi"
-+#include "bcm283x-rpi-csi1-2lane.dtsi"
-+#include "bcm283x-rpi-i2c0mux_0_28.dtsi"
-+
-+/ {
-+ compatible = "raspberrypi,model-zero", "brcm,bcm2835";
-+ model = "Raspberry Pi Zero";
-+};
-+
-+&gpio {
-+ /*
-+ * This is based on the official GPU firmware DT blob.
-+ *
-+ * Legend:
-+ * "NC" = not connected (no rail from the SoC)
-+ * "FOO" = GPIO line named "FOO" on the schematic
-+ * "FOO_N" = GPIO line named "FOO" on schematic, active low
-+ */
-+ gpio-line-names = "ID_SDA",
-+ "ID_SCL",
-+ "SDA1",
-+ "SCL1",
-+ "GPIO_GCLK",
-+ "GPIO5",
-+ "GPIO6",
-+ "SPI_CE1_N",
-+ "SPI_CE0_N",
-+ "SPI_MISO",
-+ "SPI_MOSI",
-+ "SPI_SCLK",
-+ "GPIO12",
-+ "GPIO13",
-+ /* Serial port */
-+ "TXD0",
-+ "RXD0",
-+ "GPIO16",
-+ "GPIO17",
-+ "GPIO18",
-+ "GPIO19",
-+ "GPIO20",
-+ "GPIO21",
-+ "GPIO22",
-+ "GPIO23",
-+ "GPIO24",
-+ "GPIO25",
-+ "GPIO26",
-+ "GPIO27",
-+ "SDA0",
-+ "SCL0",
-+ "NC", /* GPIO30 */
-+ "NC", /* GPIO31 */
-+ "CAM_GPIO1", /* GPIO32 */
-+ "NC", /* GPIO33 */
-+ "NC", /* GPIO34 */
-+ "NC", /* GPIO35 */
-+ "NC", /* GPIO36 */
-+ "NC", /* GPIO37 */
-+ "NC", /* GPIO38 */
-+ "NC", /* GPIO39 */
-+ "NC", /* GPIO40 */
-+ "CAM_GPIO0", /* GPIO41 */
-+ "NC", /* GPIO42 */
-+ "NC", /* GPIO43 */
-+ "NC", /* GPIO44 */
-+ "NC", /* GPIO45 */
-+ "HDMI_HPD_N",
-+ "STATUS_LED_N",
-+ /* Used by SD Card */
-+ "SD_CLK_R",
-+ "SD_CMD_R",
-+ "SD_DATA0_R",
-+ "SD_DATA1_R",
-+ "SD_DATA2_R",
-+ "SD_DATA3_R";
-+
-+ spi0_pins: spi0_pins {
-+ brcm,pins = <9 10 11>;
-+ brcm,function = <4>; /* alt0 */
-+ };
-+
-+ spi0_cs_pins: spi0_cs_pins {
-+ brcm,pins = <8 7>;
-+ brcm,function = <1>; /* output */
-+ };
-+
-+ i2c0_pins: i2c0 {
-+ brcm,pins = <0 1>;
-+ brcm,function = <4>;
-+ };
-+
-+ i2c1_pins: i2c1 {
-+ brcm,pins = <2 3>;
-+ brcm,function = <4>;
-+ };
-+
-+ i2s_pins: i2s {
-+ brcm,pins = <18 19 20 21>;
-+ brcm,function = <4>; /* alt0 */
-+ };
-+
-+ audio_pins: audio_pins {
-+ brcm,pins = <>;
-+ brcm,function = <>;
-+ };
-+};
-+
-+&uart0 {
-+ status = "okay";
-+};
-+
-+&spi0 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&spi0_pins &spi0_cs_pins>;
-+ cs-gpios = <&gpio 8 1>, <&gpio 7 1>;
-+
-+ spidev0: spidev@0{
-+ compatible = "spidev";
-+ reg = <0>; /* CE0 */
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ spi-max-frequency = <125000000>;
-+ };
-+
-+ spidev1: spidev@1{
-+ compatible = "spidev";
-+ reg = <1>; /* CE1 */
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ spi-max-frequency = <125000000>;
-+ };
-+};
-+
-+&i2c0if {
-+ clock-frequency = <100000>;
-+};
-+
-+&i2c1 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&i2c1_pins>;
-+ clock-frequency = <100000>;
-+};
-+
-+&i2c2 {
-+ clock-frequency = <100000>;
-+};
-+
-+&i2s {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&i2s_pins>;
-+};
-+
-+&leds {
-+ act_led: led-act {
-+ label = "led0";
-+ linux,default-trigger = "actpwr";
-+ gpios = <&gpio 47 GPIO_ACTIVE_LOW>;
-+ };
-+};
-+
-+&hdmi {
-+ hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>;
-+};
-+
-+&vchiq {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&audio_pins>;
-+};
-+
-+&cam1_reg {
-+ gpio = <&gpio 41 GPIO_ACTIVE_HIGH>;
-+};
-+
-+cam0_reg: &cam_dummy_reg {
-+};
-+
-+/ {
-+ __overrides__ {
-+ audio = <&chosen>,"bootargs{on='snd_bcm2835.enable_hdmi=1',off='snd_bcm2835.enable_hdmi=0'}";
-+
-+ act_led_gpio = <&act_led>,"gpios:4";
-+ act_led_activelow = <&act_led>,"gpios:8";
-+ act_led_trigger = <&act_led>,"linux,default-trigger";
-+ };
-+};
-diff --git a/arch/arm/boot/dts/bcm2708-rpi.dtsi b/arch/arm/boot/dts/bcm2708-rpi.dtsi
-new file mode 100644
-index 000000000000..f774eda1ae55
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm2708-rpi.dtsi
-@@ -0,0 +1,40 @@
-+/* Downstream modifications common to bcm2835, bcm2836, bcm2837 */
-+
-+#define i2c0 i2c0mux
-+#include "bcm2835-rpi.dtsi"
-+#undef i2c0
-+#include "bcm270x-rpi.dtsi"
-+
-+/ {
-+ memory@0 {
-+ device_type = "memory";
-+ reg = <0x0 0x0>;
-+ };
-+
-+ aliases {
-+ i2c2 = &i2c2;
-+ };
-+
-+ __overrides__ {
-+ hdmi = <&hdmi>,"status";
-+ i2c2_iknowwhatimdoing = <&i2c2>,"status";
-+ i2c2_baudrate = <&i2c2>,"clock-frequency:0";
-+ sd = <&sdhost>,"status";
-+ sd_poll_once = <&sdhost>,"non-removable?";
-+ };
-+};
-+
-+&sdhost {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&sdhost_gpio48>;
-+ status = "okay";
-+};
-+
-+&hdmi {
-+ power-domains = <&power RPI_POWER_DOMAIN_HDMI>;
-+ status = "disabled";
-+};
-+
-+&i2c2 {
-+ status = "disabled";
-+};
-diff --git a/arch/arm/boot/dts/bcm2708.dtsi b/arch/arm/boot/dts/bcm2708.dtsi
-new file mode 100644
-index 000000000000..b3cf34cdcc0e
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm2708.dtsi
-@@ -0,0 +1,18 @@
-+#define i2c0 i2c0if
-+#include "bcm2835.dtsi"
-+#undef i2c0
-+#include "bcm270x.dtsi"
-+
-+/ {
-+ __overrides__ {
-+ arm_freq;
-+ };
-+};
-+
-+&soc {
-+ dma-ranges = <0x80000000 0x00000000 0x20000000>;
-+};
-+
-+&vc4 {
-+ status = "disabled";
-+};
-diff --git a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts
-new file mode 100644
-index 000000000000..c6220e6d5fbc
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts
-@@ -0,0 +1,200 @@
-+/dts-v1/;
-+
-+#include "bcm2709.dtsi"
-+#include "bcm2709-rpi.dtsi"
-+#include "bcm283x-rpi-smsc9514.dtsi"
-+#include "bcm283x-rpi-csi1-2lane.dtsi"
-+#include "bcm283x-rpi-i2c0mux_0_28.dtsi"
-+
-+/ {
-+ compatible = "raspberrypi,2-model-b", "brcm,bcm2836";
-+ model = "Raspberry Pi 2 Model B";
-+};
-+
-+&gpio {
-+ /*
-+ * Taken from rpi_SCH_2b_1p2_reduced.pdf and
-+ * the official GPU firmware DT blob.
-+ *
-+ * Legend:
-+ * "NC" = not connected (no rail from the SoC)
-+ * "FOO" = GPIO line named "FOO" on the schematic
-+ * "FOO_N" = GPIO line named "FOO" on schematic, active low
-+ */
-+ gpio-line-names = "ID_SDA",
-+ "ID_SCL",
-+ "SDA1",
-+ "SCL1",
-+ "GPIO_GCLK",
-+ "GPIO5",
-+ "GPIO6",
-+ "SPI_CE1_N",
-+ "SPI_CE0_N",
-+ "SPI_MISO",
-+ "SPI_MOSI",
-+ "SPI_SCLK",
-+ "GPIO12",
-+ "GPIO13",
-+ /* Serial port */
-+ "TXD0",
-+ "RXD0",
-+ "GPIO16",
-+ "GPIO17",
-+ "GPIO18",
-+ "GPIO19",
-+ "GPIO20",
-+ "GPIO21",
-+ "GPIO22",
-+ "GPIO23",
-+ "GPIO24",
-+ "GPIO25",
-+ "GPIO26",
-+ "GPIO27",
-+ "SDA0",
-+ "SCL0",
-+ "NC", /* GPIO30 */
-+ "LAN_RUN",
-+ "CAM_GPIO1",
-+ "NC", /* GPIO33 */
-+ "NC", /* GPIO34 */
-+ "PWR_LOW_N",
-+ "NC", /* GPIO36 */
-+ "NC", /* GPIO37 */
-+ "USB_LIMIT",
-+ "NC", /* GPIO39 */
-+ "PWM0_OUT",
-+ "CAM_GPIO0",
-+ "SMPS_SCL",
-+ "SMPS_SDA",
-+ "ETH_CLK",
-+ "PWM1_OUT",
-+ "HDMI_HPD_N",
-+ "STATUS_LED",
-+ /* Used by SD Card */
-+ "SD_CLK_R",
-+ "SD_CMD_R",
-+ "SD_DATA0_R",
-+ "SD_DATA1_R",
-+ "SD_DATA2_R",
-+ "SD_DATA3_R";
-+
-+ spi0_pins: spi0_pins {
-+ brcm,pins = <9 10 11>;
-+ brcm,function = <4>; /* alt0 */
-+ };
-+
-+ spi0_cs_pins: spi0_cs_pins {
-+ brcm,pins = <8 7>;
-+ brcm,function = <1>; /* output */
-+ };
-+
-+ i2c0_pins: i2c0 {
-+ brcm,pins = <0 1>;
-+ brcm,function = <4>;
-+ };
-+
-+ i2c1_pins: i2c1 {
-+ brcm,pins = <2 3>;
-+ brcm,function = <4>;
-+ };
-+
-+ i2s_pins: i2s {
-+ brcm,pins = <18 19 20 21>;
-+ brcm,function = <4>; /* alt0 */
-+ };
-+
-+ audio_pins: audio_pins {
-+ brcm,pins = <40 45>;
-+ brcm,function = <4>;
-+ brcm,pull = <0>;
-+ };
-+};
-+
-+&uart0 {
-+ status = "okay";
-+};
-+
-+&spi0 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&spi0_pins &spi0_cs_pins>;
-+ cs-gpios = <&gpio 8 1>, <&gpio 7 1>;
-+
-+ spidev0: spidev@0{
-+ compatible = "spidev";
-+ reg = <0>; /* CE0 */
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ spi-max-frequency = <125000000>;
-+ };
-+
-+ spidev1: spidev@1{
-+ compatible = "spidev";
-+ reg = <1>; /* CE1 */
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ spi-max-frequency = <125000000>;
-+ };
-+};
-+
-+&i2c0if {
-+ clock-frequency = <100000>;
-+};
-+
-+&i2c1 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&i2c1_pins>;
-+ clock-frequency = <100000>;
-+};
-+
-+&i2c2 {
-+ clock-frequency = <100000>;
-+};
-+
-+&i2s {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&i2s_pins>;
-+};
-+
-+&leds {
-+ act_led: led-act {
-+ label = "led0";
-+ linux,default-trigger = "mmc0";
-+ gpios = <&gpio 47 0>;
-+ };
-+
-+ pwr_led: led-pwr {
-+ label = "led1";
-+ linux,default-trigger = "input";
-+ gpios = <&gpio 35 0>;
-+ };
-+};
-+
-+&hdmi {
-+ hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>;
-+};
-+
-+&vchiq {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&audio_pins>;
-+};
-+
-+&cam1_reg {
-+ gpio = <&gpio 41 GPIO_ACTIVE_HIGH>;
-+};
-+
-+cam0_reg: &cam_dummy_reg {
-+};
-+
-+/ {
-+ __overrides__ {
-+ audio = <&chosen>,"bootargs{on='snd_bcm2835.enable_headphones=1 snd_bcm2835.enable_hdmi=1',off='snd_bcm2835.enable_headphones=0 snd_bcm2835.enable_hdmi=0'}";
-+
-+ act_led_gpio = <&act_led>,"gpios:4";
-+ act_led_activelow = <&act_led>,"gpios:8";
-+ act_led_trigger = <&act_led>,"linux,default-trigger";
-+
-+ pwr_led_gpio = <&pwr_led>,"gpios:4";
-+ pwr_led_activelow = <&pwr_led>,"gpios:8";
-+ pwr_led_trigger = <&pwr_led>,"linux,default-trigger";
-+ };
-+};
-diff --git a/arch/arm/boot/dts/bcm2709-rpi-cm2.dts b/arch/arm/boot/dts/bcm2709-rpi-cm2.dts
-new file mode 100644
-index 000000000000..c9e47c46f4f7
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm2709-rpi-cm2.dts
-@@ -0,0 +1,221 @@
-+/dts-v1/;
-+
-+#include "bcm2709.dtsi"
-+#include "bcm2709-rpi.dtsi"
-+#include "bcm283x-rpi-csi0-2lane.dtsi"
-+#include "bcm283x-rpi-csi1-4lane.dtsi"
-+#include "bcm283x-rpi-i2c0mux_0_28.dtsi"
-+
-+/ {
-+ compatible = "raspberrypi,2-compute-module", "brcm,bcm2836";
-+ model = "Raspberry Pi Compute Module 2";
-+};
-+
-+&cam1_reg {
-+ gpio = <&gpio 2 GPIO_ACTIVE_HIGH>;
-+ status = "disabled";
-+};
-+
-+cam0_reg: &cam0_regulator {
-+ gpio = <&gpio 30 GPIO_ACTIVE_HIGH>;
-+};
-+
-+&uart0 {
-+ status = "okay";
-+};
-+
-+&gpio {
-+ /*
-+ * This is based on the official GPU firmware DT blob.
-+ *
-+ * Legend:
-+ * "NC" = not connected (no rail from the SoC)
-+ * "FOO" = GPIO line named "FOO" on the schematic
-+ * "FOO_N" = GPIO line named "FOO" on schematic, active low
-+ */
-+ gpio-line-names = "GPIO0",
-+ "GPIO1",
-+ "GPIO2",
-+ "GPIO3",
-+ "GPIO4",
-+ "GPIO5",
-+ "GPIO6",
-+ "GPIO7",
-+ "GPIO8",
-+ "GPIO9",
-+ "GPIO10",
-+ "GPIO11",
-+ "GPIO12",
-+ "GPIO13",
-+ "GPIO14",
-+ "GPIO15",
-+ "GPIO16",
-+ "GPIO17",
-+ "GPIO18",
-+ "GPIO19",
-+ "GPIO20",
-+ "GPIO21",
-+ "GPIO22",
-+ "GPIO23",
-+ "GPIO24",
-+ "GPIO25",
-+ "GPIO26",
-+ "GPIO27",
-+ "GPIO28",
-+ "GPIO29",
-+ "GPIO30",
-+ "GPIO31",
-+ "GPIO32",
-+ "GPIO33",
-+ "GPIO34",
-+ "GPIO35",
-+ "GPIO36",
-+ "GPIO37",
-+ "GPIO38",
-+ "GPIO39",
-+ "GPIO40",
-+ "GPIO41",
-+ "GPIO42",
-+ "GPIO43",
-+ "GPIO44",
-+ "GPIO45",
-+ "SMPS_SCL",
-+ "SMPS_SDA",
-+ /* Used by eMMC */
-+ "SD_CLK_R",
-+ "SD_CMD_R",
-+ "SD_DATA0_R",
-+ "SD_DATA1_R",
-+ "SD_DATA2_R",
-+ "SD_DATA3_R";
-+
-+ spi0_pins: spi0_pins {
-+ brcm,pins = <9 10 11>;
-+ brcm,function = <4>; /* alt0 */
-+ };
-+
-+ spi0_cs_pins: spi0_cs_pins {
-+ brcm,pins = <8 7>;
-+ brcm,function = <1>; /* output */
-+ };
-+
-+ i2c0_pins: i2c0 {
-+ brcm,pins = <0 1>;
-+ brcm,function = <4>;
-+ };
-+
-+ i2c1_pins: i2c1 {
-+ brcm,pins = <2 3>;
-+ brcm,function = <4>;
-+ };
-+
-+ i2s_pins: i2s {
-+ brcm,pins = <18 19 20 21>;
-+ brcm,function = <4>; /* alt0 */
-+ };
-+
-+ audio_pins: audio_pins {
-+ brcm,pins;
-+ brcm,function;
-+ };
-+};
-+
-+&soc {
-+ virtgpio: virtgpio {
-+ compatible = "brcm,bcm2835-virtgpio";
-+ gpio-controller;
-+ #gpio-cells = <2>;
-+ firmware = <&firmware>;
-+ status = "okay";
-+ };
-+
-+};
-+
-+&firmware {
-+ expgpio: expgpio {
-+ compatible = "raspberrypi,firmware-gpio";
-+ gpio-controller;
-+ #gpio-cells = <2>;
-+ gpio-line-names = "HDMI_HPD_N",
-+ "EMMC_EN_N",
-+ "NC",
-+ "NC",
-+ "NC",
-+ "NC",
-+ "NC",
-+ "NC";
-+ status = "okay";
-+ };
-+};
-+
-+&spi0 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&spi0_pins &spi0_cs_pins>;
-+ cs-gpios = <&gpio 8 1>, <&gpio 7 1>;
-+
-+ spidev0: spidev@0{
-+ compatible = "spidev";
-+ reg = <0>; /* CE0 */
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ spi-max-frequency = <125000000>;
-+ };
-+
-+ spidev1: spidev@1{
-+ compatible = "spidev";
-+ reg = <1>; /* CE1 */
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ spi-max-frequency = <125000000>;
-+ };
-+};
-+
-+&i2c0if {
-+ clock-frequency = <100000>;
-+};
-+
-+&i2c1 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&i2c1_pins>;
-+ clock-frequency = <100000>;
-+};
-+
-+&i2c2 {
-+ clock-frequency = <100000>;
-+};
-+
-+&i2s {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&i2s_pins>;
-+};
-+
-+&leds {
-+ act_led: led-act {
-+ label = "led0";
-+ linux,default-trigger = "mmc0";
-+ gpios = <&virtgpio 0 0>;
-+ };
-+};
-+
-+&hdmi {
-+ hpd-gpios = <&expgpio 0 GPIO_ACTIVE_LOW>;
-+};
-+
-+&vchiq {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&audio_pins>;
-+};
-+
-+/ {
-+ __overrides__ {
-+ audio = <&chosen>,"bootargs{on='snd_bcm2835.enable_hdmi=1',off='snd_bcm2835.enable_hdmi=0'}";
-+
-+ act_led_gpio = <&act_led>,"gpios:4";
-+ act_led_activelow = <&act_led>,"gpios:8";
-+ act_led_trigger = <&act_led>,"linux,default-trigger";
-+ cam0_reg = <&cam0_reg>,"status";
-+ cam0_reg_gpio = <&cam0_reg>,"gpio:4";
-+ cam1_reg = <&cam1_reg>,"status";
-+ cam1_reg_gpio = <&cam1_reg>,"gpio:4";
-+ };
-+};
-diff --git a/arch/arm/boot/dts/bcm2709-rpi.dtsi b/arch/arm/boot/dts/bcm2709-rpi.dtsi
-new file mode 100644
-index 000000000000..babfa41cd9f7
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm2709-rpi.dtsi
-@@ -0,0 +1,5 @@
-+#include "bcm2708-rpi.dtsi"
-+
-+&vchiq {
-+ compatible = "brcm,bcm2836-vchiq", "brcm,bcm2835-vchiq";
-+};
-diff --git a/arch/arm/boot/dts/bcm2709.dtsi b/arch/arm/boot/dts/bcm2709.dtsi
-new file mode 100644
-index 000000000000..e195f7247813
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm2709.dtsi
-@@ -0,0 +1,24 @@
-+#define i2c0 i2c0if
-+#include "bcm2836.dtsi"
-+#undef i2c0
-+#include "bcm270x.dtsi"
-+
-+/ {
-+ soc {
-+ ranges = <0x7e000000 0x3f000000 0x01000000>,
-+ <0x40000000 0x40000000 0x00040000>;
-+
-+ /delete-node/ timer@7e003000;
-+ };
-+
-+ __overrides__ {
-+ arm_freq = <&v7_cpu0>, "clock-frequency:0",
-+ <&v7_cpu1>, "clock-frequency:0",
-+ <&v7_cpu2>, "clock-frequency:0",
-+ <&v7_cpu3>, "clock-frequency:0";
-+ };
-+};
-+
-+&vc4 {
-+ status = "disabled";
-+};
-diff --git a/arch/arm/boot/dts/bcm270x-rpi.dtsi b/arch/arm/boot/dts/bcm270x-rpi.dtsi
-new file mode 100644
-index 000000000000..1401d7b261f8
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm270x-rpi.dtsi
-@@ -0,0 +1,177 @@
-+/* Downstream modifications to bcm2835-rpi.dtsi */
-+
-+/ {
-+ aliases {
-+ aux = &aux;
-+ sound = &sound;
-+ soc = &soc;
-+ dma = &dma;
-+ intc = &intc;
-+ watchdog = &watchdog;
-+ random = &random;
-+ mailbox = &mailbox;
-+ gpio = &gpio;
-+ uart0 = &uart0;
-+ uart1 = &uart1;
-+ sdhost = &sdhost;
-+ mmc = &mmc;
-+ mmc1 = &mmc;
-+ mmc0 = &sdhost;
-+ i2s = &i2s;
-+ i2c0 = &i2c0;
-+ i2c1 = &i2c1;
-+ i2c10 = &i2c_csi_dsi;
-+ spi0 = &spi0;
-+ spi1 = &spi1;
-+ spi2 = &spi2;
-+ usb = &usb;
-+ leds = &leds;
-+ fb = &fb;
-+ thermal = &thermal;
-+ axiperf = &axiperf;
-+ };
-+
-+ /* Define these notional regulators for use by overlays */
-+ vdd_3v3_reg: fixedregulator_3v3 {
-+ compatible = "regulator-fixed";
-+ regulator-always-on;
-+ regulator-max-microvolt = <3300000>;
-+ regulator-min-microvolt = <3300000>;
-+ regulator-name = "3v3";
-+ };
-+
-+ vdd_5v0_reg: fixedregulator_5v0 {
-+ compatible = "regulator-fixed";
-+ regulator-always-on;
-+ regulator-max-microvolt = <5000000>;
-+ regulator-min-microvolt = <5000000>;
-+ regulator-name = "5v0";
-+ };
-+
-+ leds: leds {
-+ compatible = "gpio-leds";
-+ };
-+
-+ soc {
-+ gpiomem {
-+ compatible = "brcm,bcm2835-gpiomem";
-+ reg = <0x7e200000 0x1000>;
-+ };
-+
-+ fb: fb {
-+ compatible = "brcm,bcm2708-fb";
-+ firmware = <&firmware>;
-+ status = "okay";
-+ };
-+
-+ /* External sound card */
-+ sound: sound {
-+ status = "disabled";
-+ };
-+ };
-+
-+ __overrides__ {
-+ cache_line_size;
-+
-+ uart0 = <&uart0>,"status";
-+ uart1 = <&uart1>,"status";
-+ i2s = <&i2s>,"status";
-+ spi = <&spi0>,"status";
-+ i2c0 = <&i2c0if>,"status",<&i2c0mux>,"status";
-+ i2c1 = <&i2c1>,"status";
-+ i2c0_baudrate = <&i2c0if>,"clock-frequency:0";
-+ i2c1_baudrate = <&i2c1>,"clock-frequency:0";
-+
-+ watchdog = <&watchdog>,"status";
-+ random = <&random>,"status";
-+ sd_overclock = <&sdhost>,"brcm,overclock-50:0";
-+ sd_force_pio = <&sdhost>,"brcm,force-pio?";
-+ sd_pio_limit = <&sdhost>,"brcm,pio-limit:0";
-+ sd_debug = <&sdhost>,"brcm,debug";
-+ sdio_overclock = <&mmc>,"brcm,overclock-50:0",
-+ <&mmcnr>,"brcm,overclock-50:0";
-+ axiperf = <&axiperf>,"status";
-+ };
-+};
-+
-+&uart0 {
-+ skip-init;
-+};
-+
-+&uart1 {
-+ skip-init;
-+};
-+
-+&txp {
-+ status = "disabled";
-+};
-+
-+&i2c0if {
-+ status = "disabled";
-+};
-+
-+&i2c0mux {
-+ pinctrl-names = "i2c0", "i2c_csi_dsi";
-+ /delete-property/ clock-frequency;
-+ status = "disabled";
-+};
-+
-+&i2c1 {
-+ status = "disabled";
-+};
-+
-+&clocks {
-+ firmware = <&firmware>;
-+};
-+
-+&sdhci {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&emmc_gpio48>;
-+ bus-width = <4>;
-+};
-+
-+&cpu_thermal {
-+ // Add some labels
-+ thermal_trips: trips {
-+ cpu-crit {
-+ // Raise upstream limit of 90C
-+ temperature = <110000>;
-+ };
-+ };
-+ cooling_maps: cooling-maps {
-+ };
-+};
-+
-+&vec {
-+ clocks = <&firmware_clocks 15>;
-+ status = "disabled";
-+};
-+
-+&firmware {
-+#ifndef BCM2711
-+ firmware_clocks: clocks {
-+ compatible = "raspberrypi,firmware-clocks";
-+ #clock-cells = <1>;
-+ };
-+#endif
-+
-+ vcio: vcio {
-+ compatible = "raspberrypi,vcio";
-+ };
-+};
-+
-+&vc4 {
-+ raspberrypi,firmware = <&firmware>;
-+};
-+
-+#ifndef BCM2711
-+
-+&hdmi {
-+ reg-names = "hdmi",
-+ "hd";
-+ clocks = <&firmware_clocks 9>,
-+ <&firmware_clocks 13>;
-+ dmas = <&dma (17|(1<<27)|(1<<24))>;
-+};
-+
-+#endif
-diff --git a/arch/arm/boot/dts/bcm270x.dtsi b/arch/arm/boot/dts/bcm270x.dtsi
-new file mode 100644
-index 000000000000..bb8e7a9d1b22
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm270x.dtsi
-@@ -0,0 +1,294 @@
-+/* Downstream bcm283x.dtsi diff */
-+#include
-+
-+/ {
-+ chosen: chosen {
-+ // Disable audio by default
-+ bootargs = "coherent_pool=1M snd_bcm2835.enable_headphones=0";
-+ /delete-property/ stdout-path;
-+ };
-+
-+ soc: soc {
-+ watchdog: watchdog@7e100000 {
-+ /* Add label */
-+ };
-+
-+ random: rng@7e104000 {
-+ /* Add label */
-+ };
-+
-+ spi0: spi@7e204000 {
-+ /* Add label */
-+ };
-+
-+#ifndef BCM2711
-+ pixelvalve0: pixelvalve@7e206000 {
-+ /* Add label */
-+ status = "disabled";
-+ };
-+
-+ pixelvalve1: pixelvalve@7e207000 {
-+ /* Add label */
-+ status = "disabled";
-+ };
-+#endif
-+
-+ /delete-node/ mmc@7e300000;
-+
-+ sdhci: mmc: mmc@7e300000 {
-+ compatible = "brcm,bcm2835-mmc", "brcm,bcm2835-sdhci";
-+ reg = <0x7e300000 0x100>;
-+ interrupts = <2 30>;
-+ clocks = <&clocks BCM2835_CLOCK_EMMC>;
-+ dmas = <&dma 11>;
-+ dma-names = "rx-tx";
-+ brcm,overclock-50 = <0>;
-+ status = "disabled";
-+ };
-+
-+ /* A clone of mmc but with non-removable set */
-+ mmcnr: mmcnr@7e300000 {
-+ compatible = "brcm,bcm2835-mmc", "brcm,bcm2835-sdhci";
-+ reg = <0x7e300000 0x100>;
-+ interrupts = <2 30>;
-+ clocks = <&clocks BCM2835_CLOCK_EMMC>;
-+ dmas = <&dma 11>;
-+ dma-names = "rx-tx";
-+ brcm,overclock-50 = <0>;
-+ non-removable;
-+ status = "disabled";
-+ };
-+
-+ hvs: hvs@7e400000 {
-+ /* Add label */
-+ status = "disabled";
-+ };
-+
-+ firmwarekms: firmwarekms@7e600000 {
-+ compatible = "raspberrypi,rpi-firmware-kms";
-+ /* SMI interrupt reg */
-+ reg = <0x7e600000 0x100>;
-+ interrupts = <2 16>;
-+ brcm,firmware = <&firmware>;
-+ status = "disabled";
-+ };
-+
-+ smi: smi@7e600000 {
-+ compatible = "brcm,bcm2835-smi";
-+ reg = <0x7e600000 0x100>;
-+ interrupts = <2 16>;
-+ clocks = <&clocks BCM2835_CLOCK_SMI>;
-+ assigned-clocks = <&clocks BCM2835_CLOCK_SMI>;
-+ assigned-clock-rates = <125000000>;
-+ dmas = <&dma 4>;
-+ dma-names = "rx-tx";
-+ status = "disabled";
-+ };
-+
-+ csi0: csi@7e800000 {
-+ compatible = "brcm,bcm2835-unicam";
-+ reg = <0x7e800000 0x800>,
-+ <0x7e802000 0x4>;
-+ interrupts = <2 6>;
-+ clocks = <&clocks BCM2835_CLOCK_CAM0>,
-+ <&firmware_clocks 4>;
-+ clock-names = "lp", "vpu";
-+ power-domains = <&power RPI_POWER_DOMAIN_UNICAM0>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ #clock-cells = <1>;
-+ status = "disabled";
-+ };
-+
-+ csi1: csi@7e801000 {
-+ compatible = "brcm,bcm2835-unicam";
-+ reg = <0x7e801000 0x800>,
-+ <0x7e802004 0x4>;
-+ interrupts = <2 7>;
-+ clocks = <&clocks BCM2835_CLOCK_CAM1>,
-+ <&firmware_clocks 4>;
-+ clock-names = "lp", "vpu";
-+ power-domains = <&power RPI_POWER_DOMAIN_UNICAM1>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ #clock-cells = <1>;
-+ status = "disabled";
-+ };
-+
-+#ifndef BCM2711
-+ pixelvalve2: pixelvalve@7e807000 {
-+ /* Add label */
-+ status = "disabled";
-+ };
-+#endif
-+
-+ hdmi@7e902000 { /* hdmi */
-+ status = "disabled";
-+ };
-+
-+ usb@7e980000 { /* usb */
-+ compatible = "brcm,bcm2708-usb";
-+ reg = <0x7e980000 0x10000>,
-+ <0x7e006000 0x1000>;
-+ interrupt-names = "usb",
-+ "soft";
-+ interrupts = <1 9>,
-+ <2 0>;
-+ };
-+
-+#ifndef BCM2711
-+ v3d@7ec00000 { /* vd3 */
-+ compatible = "brcm,vc4-v3d";
-+ power-domains = <&power RPI_POWER_DOMAIN_V3D>;
-+ status = "disabled";
-+ };
-+#endif
-+
-+ axiperf: axiperf {
-+ compatible = "brcm,bcm2835-axiperf";
-+ reg = <0x7e009800 0x100>,
-+ <0x7ee08000 0x100>;
-+ firmware = <&firmware>;
-+ status = "disabled";
-+ };
-+
-+ i2c0mux: i2c0mux {
-+ compatible = "i2c-mux-pinctrl";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ i2c-parent = <&i2c0if>;
-+
-+ status = "disabled";
-+
-+ i2c0: i2c@0 {
-+ reg = <0>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ };
-+
-+ i2c_csi_dsi: i2c@1 {
-+ reg = <1>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ };
-+ };
-+ };
-+
-+ cam1_reg: cam1_regulator {
-+ compatible = "regulator-fixed";
-+ regulator-name = "cam1-reg";
-+ enable-active-high;
-+ /* Needs to be enabled, as removing a regulator is very unsafe */
-+ status = "okay";
-+ };
-+
-+ cam1_clk: cam1_clk {
-+ compatible = "fixed-clock";
-+ #clock-cells = <0>;
-+ status = "disabled";
-+ };
-+
-+ cam0_regulator: cam0_regulator {
-+ compatible = "regulator-fixed";
-+ regulator-name = "cam0-reg";
-+ enable-active-high;
-+ status = "disabled";
-+ };
-+
-+ cam0_clk: cam0_clk {
-+ compatible = "fixed-clock";
-+ #clock-cells = <0>;
-+ status = "disabled";
-+ };
-+
-+ cam_dummy_reg: cam_dummy_reg {
-+ compatible = "regulator-fixed";
-+ regulator-name = "cam-dummy-reg";
-+ status = "okay";
-+ };
-+
-+ __overrides__ {
-+ cam0-pwdn-ctrl;
-+ cam0-pwdn;
-+ cam0-led-ctrl;
-+ cam0-led;
-+ };
-+};
-+
-+&gpio {
-+ interrupts = <2 17>, <2 18>;
-+
-+ dpi_18bit_cpadhi_gpio0: dpi_18bit_cpadhi_gpio0 {
-+ brcm,pins = <0 1 2 3 4 5 6 7 8 9
-+ 12 13 14 15 16 17
-+ 20 21 22 23 24 25>;
-+ brcm,function = ;
-+ brcm,pull = <0>; /* no pull */
-+ };
-+ dpi_18bit_cpadhi_gpio2: dpi_18bit_cpadhi_gpio2 {
-+ brcm,pins = <2 3 4 5 6 7 8 9
-+ 12 13 14 15 16 17
-+ 20 21 22 23 24 25>;
-+ brcm,function = ;
-+ };
-+ dpi_18bit_gpio0: dpi_18bit_gpio0 {
-+ brcm,pins = <0 1 2 3 4 5 6 7 8 9 10 11
-+ 12 13 14 15 16 17 18 19
-+ 20 21>;
-+ brcm,function = ;
-+ };
-+ dpi_18bit_gpio2: dpi_18bit_gpio2 {
-+ brcm,pins = <2 3 4 5 6 7 8 9 10 11
-+ 12 13 14 15 16 17 18 19
-+ 20 21>;
-+ brcm,function = ;
-+ };
-+ dpi_16bit_gpio0: dpi_16bit_gpio0 {
-+ brcm,pins = <0 1 2 3 4 5 6 7 8 9 10 11
-+ 12 13 14 15 16 17 18 19>;
-+ brcm,function = ;
-+ };
-+ dpi_16bit_gpio2: dpi_16bit_gpio2 {
-+ brcm,pins = <2 3 4 5 6 7 8 9 10 11
-+ 12 13 14 15 16 17 18 19>;
-+ brcm,function = ;
-+ };
-+ dpi_16bit_cpadhi_gpio0: dpi_16bit_cpadhi_gpio0 {
-+ brcm,pins = <0 1 2 3 4 5 6 7 8
-+ 12 13 14 15 16 17
-+ 20 21 22 23 24>;
-+ brcm,function = ;
-+ };
-+ dpi_16bit_cpadhi_gpio2: dpi_16bit_cpadhi_gpio2 {
-+ brcm,pins = <2 3 4 5 6 7 8
-+ 12 13 14 15 16 17
-+ 20 21 22 23 24>;
-+ brcm,function = ;
-+ };
-+};
-+
-+&uart0 {
-+ /* Enable CTS bug workaround */
-+ cts-event-workaround;
-+};
-+
-+&i2s {
-+ #sound-dai-cells = <0>;
-+ dmas = <&dma 2>, <&dma 3>;
-+ dma-names = "tx", "rx";
-+};
-+
-+&sdhost {
-+ dmas = <&dma (13|(1<<29))>;
-+ dma-names = "rx-tx";
-+ bus-width = <4>;
-+ brcm,overclock-50 = <0>;
-+ brcm,pio-limit = <1>;
-+ firmware = <&firmware>;
-+};
-+
-+&spi0 {
-+ dmas = <&dma 6>, <&dma 7>;
-+ dma-names = "tx", "rx";
-+};
-diff --git a/arch/arm/boot/dts/bcm2710-rpi-2-b.dts b/arch/arm/boot/dts/bcm2710-rpi-2-b.dts
-new file mode 100644
-index 000000000000..c77ff30aa738
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm2710-rpi-2-b.dts
-@@ -0,0 +1,200 @@
-+/dts-v1/;
-+
-+#include "bcm2710.dtsi"
-+#include "bcm2709-rpi.dtsi"
-+#include "bcm283x-rpi-smsc9514.dtsi"
-+#include "bcm283x-rpi-csi1-2lane.dtsi"
-+#include "bcm283x-rpi-i2c0mux_0_28.dtsi"
-+
-+/ {
-+ compatible = "raspberrypi,2-model-b-rev2", "brcm,bcm2837";
-+ model = "Raspberry Pi 2 Model B rev 1.2";
-+};
-+
-+&gpio {
-+ /*
-+ * Taken from rpi_SCH_2b_1p2_reduced.pdf and
-+ * the official GPU firmware DT blob.
-+ *
-+ * Legend:
-+ * "NC" = not connected (no rail from the SoC)
-+ * "FOO" = GPIO line named "FOO" on the schematic
-+ * "FOO_N" = GPIO line named "FOO" on schematic, active low
-+ */
-+ gpio-line-names = "ID_SDA",
-+ "ID_SCL",
-+ "SDA1",
-+ "SCL1",
-+ "GPIO_GCLK",
-+ "GPIO5",
-+ "GPIO6",
-+ "SPI_CE1_N",
-+ "SPI_CE0_N",
-+ "SPI_MISO",
-+ "SPI_MOSI",
-+ "SPI_SCLK",
-+ "GPIO12",
-+ "GPIO13",
-+ /* Serial port */
-+ "TXD0",
-+ "RXD0",
-+ "GPIO16",
-+ "GPIO17",
-+ "GPIO18",
-+ "GPIO19",
-+ "GPIO20",
-+ "GPIO21",
-+ "GPIO22",
-+ "GPIO23",
-+ "GPIO24",
-+ "GPIO25",
-+ "GPIO26",
-+ "GPIO27",
-+ "SDA0",
-+ "SCL0",
-+ "NC", /* GPIO30 */
-+ "LAN_RUN",
-+ "CAM_GPIO1",
-+ "NC", /* GPIO33 */
-+ "NC", /* GPIO34 */
-+ "PWR_LOW_N",
-+ "NC", /* GPIO36 */
-+ "NC", /* GPIO37 */
-+ "USB_LIMIT",
-+ "NC", /* GPIO39 */
-+ "PWM0_OUT",
-+ "CAM_GPIO0",
-+ "SMPS_SCL",
-+ "SMPS_SDA",
-+ "ETH_CLK",
-+ "PWM1_OUT",
-+ "HDMI_HPD_N",
-+ "STATUS_LED",
-+ /* Used by SD Card */
-+ "SD_CLK_R",
-+ "SD_CMD_R",
-+ "SD_DATA0_R",
-+ "SD_DATA1_R",
-+ "SD_DATA2_R",
-+ "SD_DATA3_R";
-+
-+ spi0_pins: spi0_pins {
-+ brcm,pins = <9 10 11>;
-+ brcm,function = <4>; /* alt0 */
-+ };
-+
-+ spi0_cs_pins: spi0_cs_pins {
-+ brcm,pins = <8 7>;
-+ brcm,function = <1>; /* output */
-+ };
-+
-+ i2c0_pins: i2c0 {
-+ brcm,pins = <0 1>;
-+ brcm,function = <4>;
-+ };
-+
-+ i2c1_pins: i2c1 {
-+ brcm,pins = <2 3>;
-+ brcm,function = <4>;
-+ };
-+
-+ i2s_pins: i2s {
-+ brcm,pins = <18 19 20 21>;
-+ brcm,function = <4>; /* alt0 */
-+ };
-+
-+ audio_pins: audio_pins {
-+ brcm,pins = <40 45>;
-+ brcm,function = <4>;
-+ brcm,pull = <0>;
-+ };
-+};
-+
-+&uart0 {
-+ status = "okay";
-+};
-+
-+&spi0 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&spi0_pins &spi0_cs_pins>;
-+ cs-gpios = <&gpio 8 1>, <&gpio 7 1>;
-+
-+ spidev0: spidev@0{
-+ compatible = "spidev";
-+ reg = <0>; /* CE0 */
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ spi-max-frequency = <125000000>;
-+ };
-+
-+ spidev1: spidev@1{
-+ compatible = "spidev";
-+ reg = <1>; /* CE1 */
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ spi-max-frequency = <125000000>;
-+ };
-+};
-+
-+&i2c0if {
-+ clock-frequency = <100000>;
-+};
-+
-+&i2c1 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&i2c1_pins>;
-+ clock-frequency = <100000>;
-+};
-+
-+&i2c2 {
-+ clock-frequency = <100000>;
-+};
-+
-+&i2s {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&i2s_pins>;
-+};
-+
-+&leds {
-+ act_led: led-act {
-+ label = "led0";
-+ linux,default-trigger = "mmc0";
-+ gpios = <&gpio 47 0>;
-+ };
-+
-+ pwr_led: led-pwr {
-+ label = "led1";
-+ linux,default-trigger = "input";
-+ gpios = <&gpio 35 0>;
-+ };
-+};
-+
-+&hdmi {
-+ hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>;
-+};
-+
-+&vchiq {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&audio_pins>;
-+};
-+
-+&cam1_reg {
-+ gpio = <&gpio 41 GPIO_ACTIVE_HIGH>;
-+};
-+
-+cam0_reg: &cam_dummy_reg {
-+};
-+
-+/ {
-+ __overrides__ {
-+ audio = <&chosen>,"bootargs{on='snd_bcm2835.enable_headphones=1 snd_bcm2835.enable_hdmi=1',off='snd_bcm2835.enable_headphones=0 snd_bcm2835.enable_hdmi=0'}";
-+
-+ act_led_gpio = <&act_led>,"gpios:4";
-+ act_led_activelow = <&act_led>,"gpios:8";
-+ act_led_trigger = <&act_led>,"linux,default-trigger";
-+
-+ pwr_led_gpio = <&pwr_led>,"gpios:4";
-+ pwr_led_activelow = <&pwr_led>,"gpios:8";
-+ pwr_led_trigger = <&pwr_led>,"linux,default-trigger";
-+ };
-+};
-diff --git a/arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts b/arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts
-new file mode 100644
-index 000000000000..04621bd197c3
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts
-@@ -0,0 +1,289 @@
-+/dts-v1/;
-+
-+#include "bcm2710.dtsi"
-+#include "bcm2709-rpi.dtsi"
-+#include "bcm283x-rpi-lan7515.dtsi"
-+#include "bcm283x-rpi-csi1-2lane.dtsi"
-+#include "bcm283x-rpi-i2c0mux_0_44.dtsi"
-+#include "bcm271x-rpi-bt.dtsi"
-+
-+/ {
-+ compatible = "raspberrypi,3-model-b-plus", "brcm,bcm2837";
-+ model = "Raspberry Pi 3 Model B+";
-+
-+ chosen {
-+ bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_headphones=0";
-+ };
-+
-+ aliases {
-+ serial0 = &uart1;
-+ serial1 = &uart0;
-+ mmc1 = &mmcnr;
-+ };
-+};
-+
-+&gpio {
-+ /*
-+ * Taken from rpi_SCH_3bplus_1p0_reduced.pdf and
-+ * the official GPU firmware DT blob.
-+ *
-+ * Legend:
-+ * "NC" = not connected (no rail from the SoC)
-+ * "FOO" = GPIO line named "FOO" on the schematic
-+ * "FOO_N" = GPIO line named "FOO" on schematic, active low
-+ */
-+ gpio-line-names = "ID_SDA",
-+ "ID_SCL",
-+ "SDA1",
-+ "SCL1",
-+ "GPIO_GCLK",
-+ "GPIO5",
-+ "GPIO6",
-+ "SPI_CE1_N",
-+ "SPI_CE0_N",
-+ "SPI_MISO",
-+ "SPI_MOSI",
-+ "SPI_SCLK",
-+ "GPIO12",
-+ "GPIO13",
-+ /* Serial port */
-+ "TXD1",
-+ "RXD1",
-+ "GPIO16",
-+ "GPIO17",
-+ "GPIO18",
-+ "GPIO19",
-+ "GPIO20",
-+ "GPIO21",
-+ "GPIO22",
-+ "GPIO23",
-+ "GPIO24",
-+ "GPIO25",
-+ "GPIO26",
-+ "GPIO27",
-+ "HDMI_HPD_N",
-+ "STATUS_LED_G",
-+ /* Used by BT module */
-+ "CTS0",
-+ "RTS0",
-+ "TXD0",
-+ "RXD0",
-+ /* Used by Wifi */
-+ "SD1_CLK",
-+ "SD1_CMD",
-+ "SD1_DATA0",
-+ "SD1_DATA1",
-+ "SD1_DATA2",
-+ "SD1_DATA3",
-+ "PWM0_OUT",
-+ "PWM1_OUT",
-+ "ETH_CLK",
-+ "WIFI_CLK",
-+ "SDA0",
-+ "SCL0",
-+ "SMPS_SCL",
-+ "SMPS_SDA",
-+ /* Used by SD Card */
-+ "SD_CLK_R",
-+ "SD_CMD_R",
-+ "SD_DATA0_R",
-+ "SD_DATA1_R",
-+ "SD_DATA2_R",
-+ "SD_DATA3_R";
-+
-+ spi0_pins: spi0_pins {
-+ brcm,pins = <9 10 11>;
-+ brcm,function = <4>; /* alt0 */
-+ };
-+
-+ spi0_cs_pins: spi0_cs_pins {
-+ brcm,pins = <8 7>;
-+ brcm,function = <1>; /* output */
-+ };
-+
-+ i2c0_pins: i2c0 {
-+ brcm,pins = <0 1>;
-+ brcm,function = <4>;
-+ };
-+
-+ i2c1_pins: i2c1 {
-+ brcm,pins = <2 3>;
-+ brcm,function = <4>;
-+ };
-+
-+ i2s_pins: i2s {
-+ brcm,pins = <18 19 20 21>;
-+ brcm,function = <4>; /* alt0 */
-+ };
-+
-+ sdio_pins: sdio_pins {
-+ brcm,pins = <34 35 36 37 38 39>;
-+ brcm,function = <7>; // alt3 = SD1
-+ brcm,pull = <0 2 2 2 2 2>;
-+ };
-+
-+ bt_pins: bt_pins {
-+ brcm,pins = <43>;
-+ brcm,function = <4>; /* alt0:GPCLK2 */
-+ brcm,pull = <0>;
-+ };
-+
-+ uart0_pins: uart0_pins {
-+ brcm,pins = <32 33>;
-+ brcm,function = <7>; /* alt3=UART0 */
-+ brcm,pull = <0 2>;
-+ };
-+
-+ uart1_pins: uart1_pins {
-+ brcm,pins;
-+ brcm,function;
-+ brcm,pull;
-+ };
-+
-+ audio_pins: audio_pins {
-+ brcm,pins = <40 41>;
-+ brcm,function = <4>;
-+ brcm,pull = <0>;
-+ };
-+};
-+
-+&mmcnr {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&sdio_pins>;
-+ bus-width = <4>;
-+ status = "okay";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ brcmf: wifi@1 {
-+ reg = <1>;
-+ compatible = "brcm,bcm4329-fmac";
-+ };
-+};
-+
-+&firmware {
-+ expgpio: expgpio {
-+ compatible = "raspberrypi,firmware-gpio";
-+ gpio-controller;
-+ #gpio-cells = <2>;
-+ gpio-line-names = "BT_ON",
-+ "WL_ON",
-+ "PWR_LED_R",
-+ "LAN_RUN",
-+ "NC",
-+ "CAM_GPIO0",
-+ "CAM_GPIO1",
-+ "NC";
-+ status = "okay";
-+ };
-+};
-+
-+&uart0 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&uart0_pins &bt_pins>;
-+ status = "okay";
-+};
-+
-+&uart1 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&uart1_pins>;
-+ status = "okay";
-+};
-+
-+&spi0 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&spi0_pins &spi0_cs_pins>;
-+ cs-gpios = <&gpio 8 1>, <&gpio 7 1>;
-+
-+ spidev0: spidev@0{
-+ compatible = "spidev";
-+ reg = <0>; /* CE0 */
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ spi-max-frequency = <125000000>;
-+ };
-+
-+ spidev1: spidev@1{
-+ compatible = "spidev";
-+ reg = <1>; /* CE1 */
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ spi-max-frequency = <125000000>;
-+ };
-+};
-+
-+&i2c0if {
-+ clock-frequency = <100000>;
-+};
-+
-+&i2c1 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&i2c1_pins>;
-+ clock-frequency = <100000>;
-+};
-+
-+&i2c2 {
-+ clock-frequency = <100000>;
-+};
-+
-+&i2s {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&i2s_pins>;
-+};
-+
-+&leds {
-+ act_led: led-act {
-+ label = "led0";
-+ linux,default-trigger = "mmc0";
-+ gpios = <&gpio 29 0>;
-+ };
-+
-+ pwr_led: led-pwr {
-+ label = "led1";
-+ linux,default-trigger = "default-on";
-+ gpios = <&expgpio 2 GPIO_ACTIVE_LOW>;
-+ };
-+};
-+
-+&hdmi {
-+ hpd-gpios = <&gpio 28 GPIO_ACTIVE_LOW>;
-+};
-+
-+&vchiq {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&audio_pins>;
-+};
-+
-+ð_phy {
-+ microchip,eee-enabled;
-+ microchip,tx-lpi-timer = <600>; /* non-aggressive*/
-+ microchip,downshift-after = <2>;
-+};
-+
-+&cam1_reg {
-+ gpio = <&expgpio 5 GPIO_ACTIVE_HIGH>;
-+};
-+
-+cam0_reg: &cam_dummy_reg {
-+};
-+
-+/ {
-+ __overrides__ {
-+ audio = <&chosen>,"bootargs{on='snd_bcm2835.enable_headphones=1 snd_bcm2835.enable_hdmi=1',off='snd_bcm2835.enable_headphones=0 snd_bcm2835.enable_hdmi=0'}";
-+
-+ act_led_gpio = <&act_led>,"gpios:4";
-+ act_led_activelow = <&act_led>,"gpios:8";
-+ act_led_trigger = <&act_led>,"linux,default-trigger";
-+
-+ pwr_led_gpio = <&pwr_led>,"gpios:4";
-+ pwr_led_activelow = <&pwr_led>,"gpios:8";
-+ pwr_led_trigger = <&pwr_led>,"linux,default-trigger";
-+
-+ eee = <ð_phy>,"microchip,eee-enabled?";
-+ tx_lpi_timer = <ð_phy>,"microchip,tx-lpi-timer:0";
-+ eth_led0 = <ð_phy>,"microchip,led-modes:0";
-+ eth_led1 = <ð_phy>,"microchip,led-modes:4";
-+ eth_downshift_after = <ð_phy>,"microchip,downshift-after:0";
-+ eth_max_speed = <ð_phy>,"max-speed:0";
-+ };
-+};
-diff --git a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts
-new file mode 100644
-index 000000000000..e0b233562c03
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts
-@@ -0,0 +1,291 @@
-+/dts-v1/;
-+
-+#include "bcm2710.dtsi"
-+#include "bcm2709-rpi.dtsi"
-+#include "bcm283x-rpi-smsc9514.dtsi"
-+#include "bcm283x-rpi-csi1-2lane.dtsi"
-+#include "bcm283x-rpi-i2c0mux_0_44.dtsi"
-+#include "bcm271x-rpi-bt.dtsi"
-+
-+/ {
-+ compatible = "raspberrypi,3-model-b", "brcm,bcm2837";
-+ model = "Raspberry Pi 3 Model B";
-+
-+ chosen {
-+ bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_headphones=0";
-+ };
-+
-+ aliases {
-+ serial0 = &uart1;
-+ serial1 = &uart0;
-+ mmc1 = &mmcnr;
-+ };
-+};
-+
-+&gpio {
-+ /*
-+ * Taken from rpi_SCH_3b_1p2_reduced.pdf and
-+ * the official GPU firmware DT blob.
-+ *
-+ * Legend:
-+ * "NC" = not connected (no rail from the SoC)
-+ * "FOO" = GPIO line named "FOO" on the schematic
-+ * "FOO_N" = GPIO line named "FOO" on schematic, active low
-+ */
-+ gpio-line-names = "ID_SDA",
-+ "ID_SCL",
-+ "SDA1",
-+ "SCL1",
-+ "GPIO_GCLK",
-+ "GPIO5",
-+ "GPIO6",
-+ "SPI_CE1_N",
-+ "SPI_CE0_N",
-+ "SPI_MISO",
-+ "SPI_MOSI",
-+ "SPI_SCLK",
-+ "GPIO12",
-+ "GPIO13",
-+ /* Serial port */
-+ "TXD1",
-+ "RXD1",
-+ "GPIO16",
-+ "GPIO17",
-+ "GPIO18",
-+ "GPIO19",
-+ "GPIO20",
-+ "GPIO21",
-+ "GPIO22",
-+ "GPIO23",
-+ "GPIO24",
-+ "GPIO25",
-+ "GPIO26",
-+ "GPIO27",
-+ "NC", /* GPIO 28 */
-+ "LAN_RUN_BOOT",
-+ /* Used by BT module */
-+ "CTS0",
-+ "RTS0",
-+ "TXD0",
-+ "RXD0",
-+ /* Used by Wifi */
-+ "SD1_CLK",
-+ "SD1_CMD",
-+ "SD1_DATA0",
-+ "SD1_DATA1",
-+ "SD1_DATA2",
-+ "SD1_DATA3",
-+ "PWM0_OUT",
-+ "PWM1_OUT",
-+ "ETH_CLK",
-+ "WIFI_CLK",
-+ "SDA0",
-+ "SCL0",
-+ "SMPS_SCL",
-+ "SMPS_SDA",
-+ /* Used by SD Card */
-+ "SD_CLK_R",
-+ "SD_CMD_R",
-+ "SD_DATA0_R",
-+ "SD_DATA1_R",
-+ "SD_DATA2_R",
-+ "SD_DATA3_R";
-+
-+ spi0_pins: spi0_pins {
-+ brcm,pins = <9 10 11>;
-+ brcm,function = <4>; /* alt0 */
-+ };
-+
-+ spi0_cs_pins: spi0_cs_pins {
-+ brcm,pins = <8 7>;
-+ brcm,function = <1>; /* output */
-+ };
-+
-+ i2c0_pins: i2c0 {
-+ brcm,pins = <0 1>;
-+ brcm,function = <4>;
-+ };
-+
-+ i2c1_pins: i2c1 {
-+ brcm,pins = <2 3>;
-+ brcm,function = <4>;
-+ };
-+
-+ i2s_pins: i2s {
-+ brcm,pins = <18 19 20 21>;
-+ brcm,function = <4>; /* alt0 */
-+ };
-+
-+ sdio_pins: sdio_pins {
-+ brcm,pins = <34 35 36 37 38 39>;
-+ brcm,function = <7>; // alt3 = SD1
-+ brcm,pull = <0 2 2 2 2 2>;
-+ };
-+
-+ bt_pins: bt_pins {
-+ brcm,pins = <43>;
-+ brcm,function = <4>; /* alt0:GPCLK2 */
-+ brcm,pull = <0>;
-+ };
-+
-+ uart0_pins: uart0_pins {
-+ brcm,pins = <32 33>;
-+ brcm,function = <7>; /* alt3=UART0 */
-+ brcm,pull = <0 2>;
-+ };
-+
-+ uart1_pins: uart1_pins {
-+ brcm,pins;
-+ brcm,function;
-+ brcm,pull;
-+ };
-+
-+ audio_pins: audio_pins {
-+ brcm,pins = <40 41>;
-+ brcm,function = <4>;
-+ brcm,pull = <0>;
-+ };
-+};
-+
-+&mmcnr {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&sdio_pins>;
-+ bus-width = <4>;
-+ status = "okay";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ brcmf: wifi@1 {
-+ reg = <1>;
-+ compatible = "brcm,bcm4329-fmac";
-+ };
-+};
-+
-+&soc {
-+ virtgpio: virtgpio {
-+ compatible = "brcm,bcm2835-virtgpio";
-+ gpio-controller;
-+ #gpio-cells = <2>;
-+ firmware = <&firmware>;
-+ status = "okay";
-+ };
-+
-+};
-+
-+&firmware {
-+ expgpio: expgpio {
-+ compatible = "raspberrypi,firmware-gpio";
-+ gpio-controller;
-+ #gpio-cells = <2>;
-+ gpio-line-names = "BT_ON",
-+ "WL_ON",
-+ "STATUS_LED",
-+ "LAN_RUN",
-+ "HDMI_HPD_N",
-+ "CAM_GPIO0",
-+ "CAM_GPIO1",
-+ "PWR_LOW_N";
-+ status = "okay";
-+ };
-+};
-+
-+&uart0 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&uart0_pins &bt_pins>;
-+ status = "okay";
-+};
-+
-+&uart1 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&uart1_pins>;
-+ status = "okay";
-+};
-+
-+&bt {
-+ max-speed = <921600>;
-+};
-+
-+&spi0 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&spi0_pins &spi0_cs_pins>;
-+ cs-gpios = <&gpio 8 1>, <&gpio 7 1>;
-+
-+ spidev0: spidev@0{
-+ compatible = "spidev";
-+ reg = <0>; /* CE0 */
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ spi-max-frequency = <125000000>;
-+ };
-+
-+ spidev1: spidev@1{
-+ compatible = "spidev";
-+ reg = <1>; /* CE1 */
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ spi-max-frequency = <125000000>;
-+ };
-+};
-+
-+&i2c0if {
-+ clock-frequency = <100000>;
-+};
-+
-+&i2c1 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&i2c1_pins>;
-+ clock-frequency = <100000>;
-+};
-+
-+&i2c2 {
-+ clock-frequency = <100000>;
-+};
-+
-+&i2s {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&i2s_pins>;
-+};
-+
-+&leds {
-+ act_led: led-act {
-+ label = "led0";
-+ linux,default-trigger = "mmc0";
-+ gpios = <&virtgpio 0 0>;
-+ };
-+
-+ pwr_led: led-pwr {
-+ label = "led1";
-+ linux,default-trigger = "input";
-+ gpios = <&expgpio 7 0>;
-+ };
-+};
-+
-+&hdmi {
-+ hpd-gpios = <&expgpio 4 GPIO_ACTIVE_LOW>;
-+};
-+
-+&vchiq {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&audio_pins>;
-+};
-+
-+&cam1_reg {
-+ gpio = <&expgpio 5 GPIO_ACTIVE_HIGH>;
-+};
-+
-+cam0_reg: &cam_dummy_reg {
-+};
-+
-+/ {
-+ __overrides__ {
-+ audio = <&chosen>,"bootargs{on='snd_bcm2835.enable_headphones=1 snd_bcm2835.enable_hdmi=1',off='snd_bcm2835.enable_headphones=0 snd_bcm2835.enable_hdmi=0'}";
-+
-+ act_led_gpio = <&act_led>,"gpios:4";
-+ act_led_activelow = <&act_led>,"gpios:8";
-+ act_led_trigger = <&act_led>,"linux,default-trigger";
-+
-+ pwr_led_gpio = <&pwr_led>,"gpios:4";
-+ pwr_led_activelow = <&pwr_led>,"gpios:8";
-+ pwr_led_trigger = <&pwr_led>,"linux,default-trigger";
-+ };
-+};
-diff --git a/arch/arm/boot/dts/bcm2710-rpi-cm3.dts b/arch/arm/boot/dts/bcm2710-rpi-cm3.dts
-new file mode 100644
-index 000000000000..5b9b44e0f30e
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm2710-rpi-cm3.dts
-@@ -0,0 +1,220 @@
-+/dts-v1/;
-+
-+#include "bcm2710.dtsi"
-+#include "bcm2709-rpi.dtsi"
-+#include "bcm283x-rpi-csi0-2lane.dtsi"
-+#include "bcm283x-rpi-csi1-4lane.dtsi"
-+#include "bcm283x-rpi-i2c0mux_0_28.dtsi"
-+/ {
-+ compatible = "raspberrypi,3-compute-module", "brcm,bcm2837";
-+ model = "Raspberry Pi Compute Module 3";
-+};
-+
-+&cam1_reg {
-+ gpio = <&gpio 2 GPIO_ACTIVE_HIGH>;
-+ status = "disabled";
-+};
-+
-+cam0_reg: &cam0_regulator {
-+ gpio = <&gpio 30 GPIO_ACTIVE_HIGH>;
-+};
-+
-+&uart0 {
-+ status = "okay";
-+};
-+
-+&gpio {
-+ /*
-+ * This is based on the official GPU firmware DT blob.
-+ *
-+ * Legend:
-+ * "NC" = not connected (no rail from the SoC)
-+ * "FOO" = GPIO line named "FOO" on the schematic
-+ * "FOO_N" = GPIO line named "FOO" on schematic, active low
-+ */
-+ gpio-line-names = "GPIO0",
-+ "GPIO1",
-+ "GPIO2",
-+ "GPIO3",
-+ "GPIO4",
-+ "GPIO5",
-+ "GPIO6",
-+ "GPIO7",
-+ "GPIO8",
-+ "GPIO9",
-+ "GPIO10",
-+ "GPIO11",
-+ "GPIO12",
-+ "GPIO13",
-+ "GPIO14",
-+ "GPIO15",
-+ "GPIO16",
-+ "GPIO17",
-+ "GPIO18",
-+ "GPIO19",
-+ "GPIO20",
-+ "GPIO21",
-+ "GPIO22",
-+ "GPIO23",
-+ "GPIO24",
-+ "GPIO25",
-+ "GPIO26",
-+ "GPIO27",
-+ "GPIO28",
-+ "GPIO29",
-+ "GPIO30",
-+ "GPIO31",
-+ "GPIO32",
-+ "GPIO33",
-+ "GPIO34",
-+ "GPIO35",
-+ "GPIO36",
-+ "GPIO37",
-+ "GPIO38",
-+ "GPIO39",
-+ "GPIO40",
-+ "GPIO41",
-+ "GPIO42",
-+ "GPIO43",
-+ "GPIO44",
-+ "GPIO45",
-+ "SMPS_SCL",
-+ "SMPS_SDA",
-+ /* Used by eMMC */
-+ "SD_CLK_R",
-+ "SD_CMD_R",
-+ "SD_DATA0_R",
-+ "SD_DATA1_R",
-+ "SD_DATA2_R",
-+ "SD_DATA3_R";
-+
-+ spi0_pins: spi0_pins {
-+ brcm,pins = <9 10 11>;
-+ brcm,function = <4>; /* alt0 */
-+ };
-+
-+ spi0_cs_pins: spi0_cs_pins {
-+ brcm,pins = <8 7>;
-+ brcm,function = <1>; /* output */
-+ };
-+
-+ i2c0_pins: i2c0 {
-+ brcm,pins = <0 1>;
-+ brcm,function = <4>;
-+ };
-+
-+ i2c1_pins: i2c1 {
-+ brcm,pins = <2 3>;
-+ brcm,function = <4>;
-+ };
-+
-+ i2s_pins: i2s {
-+ brcm,pins = <18 19 20 21>;
-+ brcm,function = <4>; /* alt0 */
-+ };
-+
-+ audio_pins: audio_pins {
-+ brcm,pins;
-+ brcm,function;
-+ };
-+};
-+
-+&soc {
-+ virtgpio: virtgpio {
-+ compatible = "brcm,bcm2835-virtgpio";
-+ gpio-controller;
-+ #gpio-cells = <2>;
-+ firmware = <&firmware>;
-+ status = "okay";
-+ };
-+
-+};
-+
-+&firmware {
-+ expgpio: expgpio {
-+ compatible = "raspberrypi,firmware-gpio";
-+ gpio-controller;
-+ #gpio-cells = <2>;
-+ gpio-line-names = "HDMI_HPD_N",
-+ "EMMC_EN_N",
-+ "NC",
-+ "NC",
-+ "NC",
-+ "NC",
-+ "NC",
-+ "NC";
-+ status = "okay";
-+ };
-+};
-+
-+&spi0 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&spi0_pins &spi0_cs_pins>;
-+ cs-gpios = <&gpio 8 1>, <&gpio 7 1>;
-+
-+ spidev0: spidev@0{
-+ compatible = "spidev";
-+ reg = <0>; /* CE0 */
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ spi-max-frequency = <125000000>;
-+ };
-+
-+ spidev1: spidev@1{
-+ compatible = "spidev";
-+ reg = <1>; /* CE1 */
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ spi-max-frequency = <125000000>;
-+ };
-+};
-+
-+&i2c0if {
-+ clock-frequency = <100000>;
-+};
-+
-+&i2c1 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&i2c1_pins>;
-+ clock-frequency = <100000>;
-+};
-+
-+&i2c2 {
-+ clock-frequency = <100000>;
-+};
-+
-+&i2s {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&i2s_pins>;
-+};
-+
-+&leds {
-+ act_led: led-act {
-+ label = "led0";
-+ linux,default-trigger = "mmc0";
-+ gpios = <&virtgpio 0 0>;
-+ };
-+};
-+
-+&hdmi {
-+ hpd-gpios = <&expgpio 0 GPIO_ACTIVE_LOW>;
-+};
-+
-+&vchiq {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&audio_pins>;
-+};
-+
-+/ {
-+ __overrides__ {
-+ audio = <&chosen>,"bootargs{on='snd_bcm2835.enable_hdmi=1',off='snd_bcm2835.enable_hdmi=0'}";
-+
-+ act_led_gpio = <&act_led>,"gpios:4";
-+ act_led_activelow = <&act_led>,"gpios:8";
-+ act_led_trigger = <&act_led>,"linux,default-trigger";
-+ cam0_reg = <&cam0_reg>,"status";
-+ cam0_reg_gpio = <&cam0_reg>,"gpio:4";
-+ cam1_reg = <&cam1_reg>,"status";
-+ cam1_reg_gpio = <&cam1_reg>,"gpio:4";
-+ };
-+};
-diff --git a/arch/arm/boot/dts/bcm2710-rpi-zero-2-w.dts b/arch/arm/boot/dts/bcm2710-rpi-zero-2-w.dts
-new file mode 100644
-index 000000000000..6522d2aa3d52
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm2710-rpi-zero-2-w.dts
-@@ -0,0 +1,267 @@
-+/dts-v1/;
-+
-+#include "bcm2710.dtsi"
-+#include "bcm2709-rpi.dtsi"
-+#include "bcm283x-rpi-csi1-2lane.dtsi"
-+#include "bcm283x-rpi-i2c0mux_0_44.dtsi"
-+#include "bcm2708-rpi-bt.dtsi"
-+
-+/ {
-+ compatible = "raspberrypi,model-zero-2-w", "brcm,bcm2837";
-+ model = "Raspberry Pi Zero 2 W";
-+
-+ chosen {
-+ bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_headphones=0";
-+ };
-+
-+ aliases {
-+ serial0 = &uart1;
-+ serial1 = &uart0;
-+ mmc1 = &mmcnr;
-+ };
-+};
-+
-+&gpio {
-+ /*
-+ * This is based on the official GPU firmware DT blob.
-+ *
-+ * Legend:
-+ * "NC" = not connected (no rail from the SoC)
-+ * "FOO" = GPIO line named "FOO" on the schematic
-+ * "FOO_N" = GPIO line named "FOO" on schematic, active low
-+ */
-+ gpio-line-names = "ID_SDA",
-+ "ID_SCL",
-+ "SDA1",
-+ "SCL1",
-+ "GPIO_GCLK",
-+ "GPIO5",
-+ "GPIO6",
-+ "SPI_CE1_N",
-+ "SPI_CE0_N",
-+ "SPI_MISO",
-+ "SPI_MOSI",
-+ "SPI_SCLK",
-+ "GPIO12",
-+ "GPIO13",
-+ /* Serial port */
-+ "TXD1",
-+ "RXD1",
-+ "GPIO16",
-+ "GPIO17",
-+ "GPIO18",
-+ "GPIO19",
-+ "GPIO20",
-+ "GPIO21",
-+ "GPIO22",
-+ "GPIO23",
-+ "GPIO24",
-+ "GPIO25",
-+ "GPIO26",
-+ "GPIO27",
-+ "HDMI_HPD_N",
-+ "STATUS_LED_N",
-+ /* Used by BT module */
-+ "CTS0",
-+ "RTS0",
-+ "TXD0",
-+ "RXD0",
-+ /* Used by Wifi */
-+ "SD1_CLK",
-+ "SD1_CMD",
-+ "SD1_DATA0",
-+ "SD1_DATA1",
-+ "SD1_DATA2",
-+ "SD1_DATA3",
-+ "CAM_GPIO1", /* GPIO40 */
-+ "WL_ON", /* GPIO41 */
-+ "BT_ON", /* GPIO42 */
-+ "WIFI_CLK", /* GPIO43 */
-+ "SDA0", /* GPIO44 */
-+ "SCL0", /* GPIO45 */
-+ "SMPS_SCL", /* GPIO46 */
-+ "SMPS_SDA", /* GPIO47 */
-+ /* Used by SD Card */
-+ "SD_CLK_R",
-+ "SD_CMD_R",
-+ "SD_DATA0_R",
-+ "SD_DATA1_R",
-+ "SD_DATA2_R",
-+ "SD_DATA3_R";
-+
-+ spi0_pins: spi0_pins {
-+ brcm,pins = <9 10 11>;
-+ brcm,function = <4>; /* alt0 */
-+ };
-+
-+ spi0_cs_pins: spi0_cs_pins {
-+ brcm,pins = <8 7>;
-+ brcm,function = <1>; /* output */
-+ };
-+
-+ i2c0_pins: i2c0 {
-+ brcm,pins = <0 1>;
-+ brcm,function = <4>;
-+ };
-+
-+ i2c1_pins: i2c1 {
-+ brcm,pins = <2 3>;
-+ brcm,function = <4>;
-+ };
-+
-+ i2s_pins: i2s {
-+ brcm,pins = <18 19 20 21>;
-+ brcm,function = <4>; /* alt0 */
-+ };
-+
-+ sdio_pins: sdio_pins {
-+ brcm,pins = <34 35 36 37 38 39>;
-+ brcm,function = <7>; // alt3 = SD1
-+ brcm,pull = <0 2 2 2 2 2>;
-+ };
-+
-+ bt_pins: bt_pins {
-+ brcm,pins = <43>;
-+ brcm,function = <4>; /* alt0:GPCLK2 */
-+ brcm,pull = <0>;
-+ };
-+
-+ uart0_pins: uart0_pins {
-+ brcm,pins = <30 31 32 33>;
-+ brcm,function = <7>; /* alt3=UART0 */
-+ brcm,pull = <2 0 0 2>; /* up none none up */
-+ };
-+
-+ uart1_pins: uart1_pins {
-+ brcm,pins;
-+ brcm,function;
-+ brcm,pull;
-+ };
-+
-+ audio_pins: audio_pins {
-+ brcm,pins = <>;
-+ brcm,function = <>;
-+ };
-+};
-+
-+&mmcnr {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&sdio_pins>;
-+ bus-width = <4>;
-+ status = "okay";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ brcmf: wifi@1 {
-+ reg = <1>;
-+ compatible = "brcm,bcm4329-fmac";
-+
-+ firmwares {
-+ fw_43436p {
-+ chipid = <43430>;
-+ revmask = <4>;
-+ fw_base = "brcm/brcmfmac43436-sdio";
-+ };
-+ fw_43436s {
-+ chipid = <43430>;
-+ revmask = <2>;
-+ fw_base = "brcm/brcmfmac43436s-sdio";
-+ };
-+ };
-+ };
-+};
-+
-+&uart0 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&uart0_pins &bt_pins>;
-+ status = "okay";
-+};
-+
-+&uart1 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&uart1_pins>;
-+ status = "okay";
-+};
-+
-+&spi0 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&spi0_pins &spi0_cs_pins>;
-+ cs-gpios = <&gpio 8 1>, <&gpio 7 1>;
-+
-+ spidev0: spidev@0{
-+ compatible = "spidev";
-+ reg = <0>; /* CE0 */
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ spi-max-frequency = <125000000>;
-+ };
-+
-+ spidev1: spidev@1{
-+ compatible = "spidev";
-+ reg = <1>; /* CE1 */
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ spi-max-frequency = <125000000>;
-+ };
-+};
-+
-+&i2c0if {
-+ clock-frequency = <100000>;
-+};
-+
-+&i2c1 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&i2c1_pins>;
-+ clock-frequency = <100000>;
-+};
-+
-+&i2c2 {
-+ clock-frequency = <100000>;
-+};
-+
-+&i2s {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&i2s_pins>;
-+};
-+
-+&leds {
-+ act_led: led-act {
-+ label = "led0";
-+ linux,default-trigger = "actpwr";
-+ gpios = <&gpio 29 GPIO_ACTIVE_LOW>;
-+ };
-+};
-+
-+&hdmi {
-+ hpd-gpios = <&gpio 28 GPIO_ACTIVE_LOW>;
-+};
-+
-+&vchiq {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&audio_pins>;
-+};
-+
-+&bt {
-+ shutdown-gpios = <&gpio 42 GPIO_ACTIVE_HIGH>;
-+};
-+
-+&minibt {
-+ shutdown-gpios = <&gpio 42 GPIO_ACTIVE_HIGH>;
-+};
-+
-+&cam1_reg {
-+ gpio = <&gpio 40 GPIO_ACTIVE_HIGH>;
-+};
-+
-+cam0_reg: &cam_dummy_reg {
-+};
-+
-+/ {
-+ __overrides__ {
-+ audio = <&chosen>,"bootargs{on='snd_bcm2835.enable_hdmi=1',off='snd_bcm2835.enable_hdmi=0'}";
-+
-+ act_led_gpio = <&act_led>,"gpios:4";
-+ act_led_activelow = <&act_led>,"gpios:8";
-+ act_led_trigger = <&act_led>,"linux,default-trigger";
-+ };
-+};
-diff --git a/arch/arm/boot/dts/bcm2710-rpi-zero-2.dts b/arch/arm/boot/dts/bcm2710-rpi-zero-2.dts
-new file mode 100644
-index 000000000000..daa12bd30d6b
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm2710-rpi-zero-2.dts
-@@ -0,0 +1 @@
-+#include "bcm2710-rpi-zero-2-w.dts"
-diff --git a/arch/arm/boot/dts/bcm2710.dtsi b/arch/arm/boot/dts/bcm2710.dtsi
-new file mode 100644
-index 000000000000..31b13b24affb
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm2710.dtsi
-@@ -0,0 +1,27 @@
-+#define i2c0 i2c0if
-+#include "bcm2837.dtsi"
-+#undef i2c0
-+#include "bcm270x.dtsi"
-+
-+/ {
-+ compatible = "brcm,bcm2837", "brcm,bcm2836";
-+
-+ arm-pmu {
-+ compatible = "arm,cortex-a53-pmu", "arm,cortex-a7-pmu";
-+ };
-+
-+ soc {
-+ /delete-node/ timer@7e003000;
-+ };
-+
-+ __overrides__ {
-+ arm_freq = <&cpu0>, "clock-frequency:0",
-+ <&cpu1>, "clock-frequency:0",
-+ <&cpu2>, "clock-frequency:0",
-+ <&cpu3>, "clock-frequency:0";
-+ };
-+};
-+
-+&vc4 {
-+ status = "disabled";
-+};
-diff --git a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts
-index 4432412044de..43a6cdcb7150 100644
---- a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts
-+++ b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts
-@@ -1,9 +1,15 @@
- // SPDX-License-Identifier: GPL-2.0
- /dts-v1/;
-+#define BCM2711
-+#define i2c0 i2c0if
- #include "bcm2711.dtsi"
--#include "bcm2711-rpi.dtsi"
--#include "bcm283x-rpi-usb-peripheral.dtsi"
- #include "bcm283x-rpi-wifi-bt.dtsi"
-+#undef i2c0
-+#include "bcm270x.dtsi"
-+#define i2c0 i2c0mux
-+#include "bcm2711-rpi.dtsi"
-+#undef i2c0
-+//#include "bcm283x-rpi-usb-peripheral.dtsi"
-
- / {
- compatible = "raspberrypi,4-model-b", "brcm,bcm2711";
-@@ -72,7 +78,7 @@ &expgpio {
- "VDD_SD_IO_SEL",
- "CAM_GPIO", /* 5 */
- "SD_PWR_ON",
-- "";
-+ "SD_OC_N";
- };
-
- &gpio {
-@@ -240,3 +246,311 @@ &vec {
- &wifi_pwrseq {
- reset-gpios = <&expgpio 1 GPIO_ACTIVE_LOW>;
- };
-+
-+// =============================================
-+// Downstream rpi- changes
-+
-+#include "bcm271x-rpi-bt.dtsi"
-+
-+/ {
-+ soc {
-+ /delete-node/ pixelvalve@7e807000;
-+ /delete-node/ hdmi@7e902000;
-+ };
-+};
-+
-+#include "bcm2711-rpi-ds.dtsi"
-+#include "bcm283x-rpi-csi1-2lane.dtsi"
-+#include "bcm283x-rpi-i2c0mux_0_44.dtsi"
-+
-+/ {
-+ chosen {
-+ bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_headphones=0";
-+ };
-+
-+ aliases {
-+ serial0 = &uart1;
-+ serial1 = &uart0;
-+ mmc0 = &emmc2;
-+ mmc1 = &mmcnr;
-+ mmc2 = &sdhost;
-+ i2c3 = &i2c3;
-+ i2c4 = &i2c4;
-+ i2c5 = &i2c5;
-+ i2c6 = &i2c6;
-+ i2c20 = &ddc0;
-+ i2c21 = &ddc1;
-+ spi3 = &spi3;
-+ spi4 = &spi4;
-+ spi5 = &spi5;
-+ spi6 = &spi6;
-+ /delete-property/ intc;
-+ };
-+
-+ /delete-node/ wifi-pwrseq;
-+};
-+
-+&mmcnr {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&sdio_pins>;
-+ bus-width = <4>;
-+ status = "okay";
-+};
-+
-+&uart0 {
-+ pinctrl-0 = <&uart0_pins &bt_pins>;
-+ status = "okay";
-+};
-+
-+&uart1 {
-+ pinctrl-0 = <&uart1_pins>;
-+};
-+
-+&spi0 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&spi0_pins &spi0_cs_pins>;
-+ cs-gpios = <&gpio 8 1>, <&gpio 7 1>;
-+
-+ spidev0: spidev@0{
-+ compatible = "spidev";
-+ reg = <0>; /* CE0 */
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ spi-max-frequency = <125000000>;
-+ };
-+
-+ spidev1: spidev@1{
-+ compatible = "spidev";
-+ reg = <1>; /* CE1 */
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ spi-max-frequency = <125000000>;
-+ };
-+};
-+
-+&gpio {
-+ spi0_pins: spi0_pins {
-+ brcm,pins = <9 10 11>;
-+ brcm,function = ;
-+ };
-+
-+ spi0_cs_pins: spi0_cs_pins {
-+ brcm,pins = <8 7>;
-+ brcm,function = ;
-+ };
-+
-+ spi3_pins: spi3_pins {
-+ brcm,pins = <1 2 3>;
-+ brcm,function = ;
-+ };
-+
-+ spi3_cs_pins: spi3_cs_pins {
-+ brcm,pins = <0 24>;
-+ brcm,function = ;
-+ };
-+
-+ spi4_pins: spi4_pins {
-+ brcm,pins = <5 6 7>;
-+ brcm,function = ;
-+ };
-+
-+ spi4_cs_pins: spi4_cs_pins {
-+ brcm,pins = <4 25>;
-+ brcm,function = ;
-+ };
-+
-+ spi5_pins: spi5_pins {
-+ brcm,pins = <13 14 15>;
-+ brcm,function = ;
-+ };
-+
-+ spi5_cs_pins: spi5_cs_pins {
-+ brcm,pins = <12 26>;
-+ brcm,function = ;
-+ };
-+
-+ spi6_pins: spi6_pins {
-+ brcm,pins = <19 20 21>;
-+ brcm,function = ;
-+ };
-+
-+ spi6_cs_pins: spi6_cs_pins {
-+ brcm,pins = <18 27>;
-+ brcm,function = ;
-+ };
-+
-+ i2c0_pins: i2c0 {
-+ brcm,pins = <0 1>;
-+ brcm,function = ;
-+ brcm,pull = ;
-+ };
-+
-+ i2c1_pins: i2c1 {
-+ brcm,pins = <2 3>;
-+ brcm,function = ;
-+ brcm,pull = ;
-+ };
-+
-+ i2c3_pins: i2c3 {
-+ brcm,pins = <4 5>;
-+ brcm,function = ;
-+ brcm,pull = ;
-+ };
-+
-+ i2c4_pins: i2c4 {
-+ brcm,pins = <8 9>;
-+ brcm,function = ;
-+ brcm,pull = ;
-+ };
-+
-+ i2c5_pins: i2c5 {
-+ brcm,pins = <12 13>;
-+ brcm,function = ;
-+ brcm,pull = ;
-+ };
-+
-+ i2c6_pins: i2c6 {
-+ brcm,pins = <22 23>;
-+ brcm,function = ;
-+ brcm,pull = ;
-+ };
-+
-+ i2s_pins: i2s {
-+ brcm,pins = <18 19 20 21>;
-+ brcm,function = ;
-+ };
-+
-+ sdio_pins: sdio_pins {
-+ brcm,pins = <34 35 36 37 38 39>;
-+ brcm,function = ; // alt3 = SD1
-+ brcm,pull = <0 2 2 2 2 2>;
-+ };
-+
-+ bt_pins: bt_pins {
-+ brcm,pins = "-"; // non-empty to keep btuart happy, //4 = 0
-+ // to fool pinctrl
-+ brcm,function = <0>;
-+ brcm,pull = <2>;
-+ };
-+
-+ uart0_pins: uart0_pins {
-+ brcm,pins = <32 33>;
-+ brcm,function = ;
-+ brcm,pull = <0 2>;
-+ };
-+
-+ uart1_pins: uart1_pins {
-+ brcm,pins;
-+ brcm,function;
-+ brcm,pull;
-+ };
-+
-+ uart2_pins: uart2_pins {
-+ brcm,pins = <0 1>;
-+ brcm,function = ;
-+ brcm,pull = <0 2>;
-+ };
-+
-+ uart3_pins: uart3_pins {
-+ brcm,pins = <4 5>;
-+ brcm,function = ;
-+ brcm,pull = <0 2>;
-+ };
-+
-+ uart4_pins: uart4_pins {
-+ brcm,pins = <8 9>;
-+ brcm,function = ;
-+ brcm,pull = <0 2>;
-+ };
-+
-+ uart5_pins: uart5_pins {
-+ brcm,pins = <12 13>;
-+ brcm,function = ;
-+ brcm,pull = <0 2>;
-+ };
-+};
-+
-+&i2c0if {
-+ clock-frequency = <100000>;
-+};
-+
-+&i2c1 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&i2c1_pins>;
-+ clock-frequency = <100000>;
-+};
-+
-+&i2s {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&i2s_pins>;
-+};
-+
-+// =============================================
-+// Board specific stuff here
-+
-+&sdhost {
-+ status = "disabled";
-+};
-+
-+&phy1 {
-+ led-modes = <0x00 0x08>; /* link/activity link */
-+};
-+
-+&gpio {
-+ audio_pins: audio_pins {
-+ brcm,pins = <40 41>;
-+ brcm,function = <4>;
-+ brcm,pull = <0>;
-+ };
-+};
-+
-+&leds {
-+ act_led: led-act {
-+ label = "led0";
-+ linux,default-trigger = "mmc0";
-+ gpios = <&gpio 42 GPIO_ACTIVE_HIGH>;
-+ };
-+
-+ pwr_led: led-pwr {
-+ label = "led1";
-+ linux,default-trigger = "default-on";
-+ gpios = <&expgpio 2 GPIO_ACTIVE_LOW>;
-+ };
-+};
-+
-+&pwm1 {
-+ status = "disabled";
-+};
-+
-+&vchiq {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&audio_pins>;
-+};
-+
-+&cam1_reg {
-+ gpio = <&expgpio 5 GPIO_ACTIVE_HIGH>;
-+};
-+
-+cam0_reg: &cam_dummy_reg {
-+};
-+
-+/ {
-+ __overrides__ {
-+ audio = <&chosen>,"bootargs{on='snd_bcm2835.enable_headphones=1 snd_bcm2835.enable_hdmi=1',off='snd_bcm2835.enable_headphones=0 snd_bcm2835.enable_hdmi=0'}";
-+
-+ act_led_gpio = <&act_led>,"gpios:4";
-+ act_led_activelow = <&act_led>,"gpios:8";
-+ act_led_trigger = <&act_led>,"linux,default-trigger";
-+
-+ pwr_led_gpio = <&pwr_led>,"gpios:4";
-+ pwr_led_activelow = <&pwr_led>,"gpios:8";
-+ pwr_led_trigger = <&pwr_led>,"linux,default-trigger";
-+
-+ eth_led0 = <&phy1>,"led-modes:0";
-+ eth_led1 = <&phy1>,"led-modes:4";
-+
-+ sd_poll_once = <&emmc2>, "non-removable?";
-+ spi_dma4 = <&spi0>, "dmas:0=", <&dma40>,
-+ <&spi0>, "dmas:8=", <&dma40>;
-+ };
-+};
-diff --git a/arch/arm/boot/dts/bcm2711-rpi-400.dts b/arch/arm/boot/dts/bcm2711-rpi-400.dts
-index c53d9eb0b802..67df994170c7 100644
---- a/arch/arm/boot/dts/bcm2711-rpi-400.dts
-+++ b/arch/arm/boot/dts/bcm2711-rpi-400.dts
-@@ -1,6 +1,15 @@
- // SPDX-License-Identifier: GPL-2.0
- /dts-v1/;
--#include "bcm2711-rpi-4-b.dts"
-+#define BCM2711
-+#define i2c0 i2c0if
-+#include "bcm2711.dtsi"
-+#include "bcm283x-rpi-wifi-bt.dtsi"
-+#undef i2c0
-+#include "bcm270x.dtsi"
-+#define i2c0 i2c0mux
-+#include "bcm2711-rpi.dtsi"
-+#undef i2c0
-+//#include "bcm283x-rpi-usb-peripheral.dtsi"
-
- / {
- compatible = "raspberrypi,400", "brcm,bcm2711";
-@@ -12,19 +21,55 @@ chosen {
- };
-
- leds {
-- /delete-node/ led-act;
-+ led-act {
-+ gpios = <&gpio 42 GPIO_ACTIVE_HIGH>;
-+ };
-
- led-pwr {
-- gpios = <&gpio 42 GPIO_ACTIVE_HIGH>;
-+ label = "PWR";
-+ gpios = <&expgpio 2 GPIO_ACTIVE_LOW>;
-+ default-state = "keep";
-+ linux,default-trigger = "default-on";
- };
- };
-
-- gpio-poweroff {
-- compatible = "gpio-poweroff";
-- gpios = <&expgpio 5 GPIO_ACTIVE_HIGH>;
-+ sd_io_1v8_reg: sd_io_1v8_reg {
-+ compatible = "regulator-gpio";
-+ regulator-name = "vdd-sd-io";
-+ regulator-min-microvolt = <1800000>;
-+ regulator-max-microvolt = <3300000>;
-+ regulator-boot-on;
-+ regulator-always-on;
-+ regulator-settling-time-us = <5000>;
-+ gpios = <&expgpio 4 GPIO_ACTIVE_HIGH>;
-+ states = <1800000 0x1>,
-+ <3300000 0x0>;
-+ status = "okay";
-+ };
-+
-+ sd_vcc_reg: sd_vcc_reg {
-+ compatible = "regulator-fixed";
-+ regulator-name = "vcc-sd";
-+ regulator-min-microvolt = <3300000>;
-+ regulator-max-microvolt = <3300000>;
-+ regulator-boot-on;
-+ enable-active-high;
-+ gpio = <&expgpio 6 GPIO_ACTIVE_HIGH>;
- };
- };
-
-+&bt {
-+ shutdown-gpios = <&expgpio 0 GPIO_ACTIVE_HIGH>;
-+};
-+
-+&ddc0 {
-+ status = "okay";
-+};
-+
-+&ddc1 {
-+ status = "okay";
-+};
-+
- &expgpio {
- gpio-line-names = "BT_ON",
- "WL_ON",
-@@ -36,10 +81,481 @@ &expgpio {
- "SHUTDOWN_REQUEST";
- };
-
-+&gpio {
-+ /*
-+ * Parts taken from rpi_SCH_4b_4p0_reduced.pdf and
-+ * the official GPU firmware DT blob.
-+ *
-+ * Legend:
-+ * "FOO" = GPIO line named "FOO" on the schematic
-+ * "FOO_N" = GPIO line named "FOO" on schematic, active low
-+ */
-+ gpio-line-names = "ID_SDA",
-+ "ID_SCL",
-+ "SDA1",
-+ "SCL1",
-+ "GPIO_GCLK",
-+ "GPIO5",
-+ "GPIO6",
-+ "SPI_CE1_N",
-+ "SPI_CE0_N",
-+ "SPI_MISO",
-+ "SPI_MOSI",
-+ "SPI_SCLK",
-+ "GPIO12",
-+ "GPIO13",
-+ /* Serial port */
-+ "TXD1",
-+ "RXD1",
-+ "GPIO16",
-+ "GPIO17",
-+ "GPIO18",
-+ "GPIO19",
-+ "GPIO20",
-+ "GPIO21",
-+ "GPIO22",
-+ "GPIO23",
-+ "GPIO24",
-+ "GPIO25",
-+ "GPIO26",
-+ "GPIO27",
-+ "RGMII_MDIO",
-+ "RGMIO_MDC",
-+ /* Used by BT module */
-+ "CTS0",
-+ "RTS0",
-+ "TXD0",
-+ "RXD0",
-+ /* Used by Wifi */
-+ "SD1_CLK",
-+ "SD1_CMD",
-+ "SD1_DATA0",
-+ "SD1_DATA1",
-+ "SD1_DATA2",
-+ "SD1_DATA3",
-+ /* Shared with SPI flash */
-+ "PWM0_MISO",
-+ "PWM1_MOSI",
-+ "STATUS_LED_G_CLK",
-+ "SPIFLASH_CE_N",
-+ "SDA0",
-+ "SCL0",
-+ "RGMII_RXCLK",
-+ "RGMII_RXCTL",
-+ "RGMII_RXD0",
-+ "RGMII_RXD1",
-+ "RGMII_RXD2",
-+ "RGMII_RXD3",
-+ "RGMII_TXCLK",
-+ "RGMII_TXCTL",
-+ "RGMII_TXD0",
-+ "RGMII_TXD1",
-+ "RGMII_TXD2",
-+ "RGMII_TXD3";
-+};
-+
-+&hdmi0 {
-+ status = "okay";
-+};
-+
-+&hdmi1 {
-+ status = "okay";
-+};
-+
-+&pixelvalve0 {
-+ status = "okay";
-+};
-+
-+&pixelvalve1 {
-+ status = "okay";
-+};
-+
-+&pixelvalve2 {
-+ status = "okay";
-+};
-+
-+&pixelvalve4 {
-+ status = "okay";
-+};
-+
-+&pwm1 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&pwm1_0_gpio40 &pwm1_1_gpio41>;
-+ status = "okay";
-+};
-+
-+/* EMMC2 is used to drive the SD card */
-+&emmc2 {
-+ vqmmc-supply = <&sd_io_1v8_reg>;
-+ vmmc-supply = <&sd_vcc_reg>;
-+ broken-cd;
-+ status = "okay";
-+};
-+
-+&genet {
-+ phy-handle = <&phy1>;
-+ phy-mode = "rgmii-rxid";
-+ status = "okay";
-+};
-+
-+&genet_mdio {
-+ phy1: ethernet-phy@1 {
-+ /* No PHY interrupt */
-+ reg = <0x1>;
-+ };
-+};
-+
-+&pcie0 {
-+ pci@0,0 {
-+ device_type = "pci";
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+ ranges;
-+
-+ reg = <0 0 0 0 0>;
-+
-+ usb@0,0 {
-+ reg = <0 0 0 0 0>;
-+ resets = <&reset RASPBERRYPI_FIRMWARE_RESET_ID_USB>;
-+ };
-+ };
-+};
-+
-+/* uart0 communicates with the BT module */
-+&uart0 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&uart0_ctsrts_gpio30 &uart0_gpio32>;
-+ uart-has-rtscts;
-+};
-+
-+/* uart1 is mapped to the pin header */
-+&uart1 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&uart1_gpio14>;
-+ status = "okay";
-+};
-+
-+&vc4 {
-+ status = "okay";
-+};
-+
-+&vec {
-+ status = "disabled";
-+};
-+
-+&wifi_pwrseq {
-+ reset-gpios = <&expgpio 1 GPIO_ACTIVE_LOW>;
-+};
-+
-+// =============================================
-+// Downstream rpi- changes
-+
-+#include "bcm271x-rpi-bt.dtsi"
-+
-+/ {
-+ soc {
-+ /delete-node/ pixelvalve@7e807000;
-+ /delete-node/ hdmi@7e902000;
-+ };
-+};
-+
-+#include "bcm2711-rpi-ds.dtsi"
-+#include "bcm283x-rpi-csi1-2lane.dtsi"
-+#include "bcm283x-rpi-i2c0mux_0_44.dtsi"
-+
-+/ {
-+ chosen {
-+ bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_headphones=0";
-+ };
-+
-+ aliases {
-+ serial0 = &uart1;
-+ serial1 = &uart0;
-+ mmc0 = &emmc2;
-+ mmc1 = &mmcnr;
-+ mmc2 = &sdhost;
-+ i2c3 = &i2c3;
-+ i2c4 = &i2c4;
-+ i2c5 = &i2c5;
-+ i2c6 = &i2c6;
-+ i2c20 = &ddc0;
-+ i2c21 = &ddc1;
-+ spi3 = &spi3;
-+ spi4 = &spi4;
-+ spi5 = &spi5;
-+ spi6 = &spi6;
-+ /delete-property/ intc;
-+ };
-+
-+ /delete-node/ wifi-pwrseq;
-+};
-+
-+&mmcnr {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&sdio_pins>;
-+ bus-width = <4>;
-+ status = "okay";
-+};
-+
-+&uart0 {
-+ pinctrl-0 = <&uart0_pins &bt_pins>;
-+ status = "okay";
-+};
-+
-+&uart1 {
-+ pinctrl-0 = <&uart1_pins>;
-+};
-+
-+&spi0 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&spi0_pins &spi0_cs_pins>;
-+ cs-gpios = <&gpio 8 1>, <&gpio 7 1>;
-+
-+ spidev0: spidev@0{
-+ compatible = "spidev";
-+ reg = <0>; /* CE0 */
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ spi-max-frequency = <125000000>;
-+ };
-+
-+ spidev1: spidev@1{
-+ compatible = "spidev";
-+ reg = <1>; /* CE1 */
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ spi-max-frequency = <125000000>;
-+ };
-+};
-+
-+&gpio {
-+ spi0_pins: spi0_pins {
-+ brcm,pins = <9 10 11>;
-+ brcm,function = ;
-+ };
-+
-+ spi0_cs_pins: spi0_cs_pins {
-+ brcm,pins = <8 7>;
-+ brcm,function = ;
-+ };
-+
-+ spi3_pins: spi3_pins {
-+ brcm,pins = <1 2 3>;
-+ brcm,function = ;
-+ };
-+
-+ spi3_cs_pins: spi3_cs_pins {
-+ brcm,pins = <0 24>;
-+ brcm,function = ;
-+ };
-+
-+ spi4_pins: spi4_pins {
-+ brcm,pins = <5 6 7>;
-+ brcm,function = ;
-+ };
-+
-+ spi4_cs_pins: spi4_cs_pins {
-+ brcm,pins = <4 25>;
-+ brcm,function = ;
-+ };
-+
-+ spi5_pins: spi5_pins {
-+ brcm,pins = <13 14 15>;
-+ brcm,function = ;
-+ };
-+
-+ spi5_cs_pins: spi5_cs_pins {
-+ brcm,pins = <12 26>;
-+ brcm,function = ;
-+ };
-+
-+ spi6_pins: spi6_pins {
-+ brcm,pins = <19 20 21>;
-+ brcm,function = ;
-+ };
-+
-+ spi6_cs_pins: spi6_cs_pins {
-+ brcm,pins = <18 27>;
-+ brcm,function = ;
-+ };
-+
-+ i2c0_pins: i2c0 {
-+ brcm,pins = <0 1>;
-+ brcm,function = ;
-+ brcm,pull = ;
-+ };
-+
-+ i2c1_pins: i2c1 {
-+ brcm,pins = <2 3>;
-+ brcm,function = ;
-+ brcm,pull = ;
-+ };
-+
-+ i2c3_pins: i2c3 {
-+ brcm,pins = <4 5>;
-+ brcm,function = ;
-+ brcm,pull = ;
-+ };
-+
-+ i2c4_pins: i2c4 {
-+ brcm,pins = <8 9>;
-+ brcm,function = ;
-+ brcm,pull = ;
-+ };
-+
-+ i2c5_pins: i2c5 {
-+ brcm,pins = <12 13>;
-+ brcm,function = ;
-+ brcm,pull = ;
-+ };
-+
-+ i2c6_pins: i2c6 {
-+ brcm,pins = <22 23>;
-+ brcm,function = ;
-+ brcm,pull = ;
-+ };
-+
-+ i2s_pins: i2s {
-+ brcm,pins = <18 19 20 21>;
-+ brcm,function = ;
-+ };
-+
-+ sdio_pins: sdio_pins {
-+ brcm,pins = <34 35 36 37 38 39>;
-+ brcm,function = ; // alt3 = SD1
-+ brcm,pull = <0 2 2 2 2 2>;
-+ };
-+
-+ bt_pins: bt_pins {
-+ brcm,pins = "-"; // non-empty to keep btuart happy, //4 = 0
-+ // to fool pinctrl
-+ brcm,function = <0>;
-+ brcm,pull = <2>;
-+ };
-+
-+ uart0_pins: uart0_pins {
-+ brcm,pins = <32 33>;
-+ brcm,function = ;
-+ brcm,pull = <0 2>;
-+ };
-+
-+ uart1_pins: uart1_pins {
-+ brcm,pins;
-+ brcm,function;
-+ brcm,pull;
-+ };
-+
-+ uart2_pins: uart2_pins {
-+ brcm,pins = <0 1>;
-+ brcm,function = ;
-+ brcm,pull = <0 2>;
-+ };
-+
-+ uart3_pins: uart3_pins {
-+ brcm,pins = <4 5>;
-+ brcm,function = ;
-+ brcm,pull = <0 2>;
-+ };
-+
-+ uart4_pins: uart4_pins {
-+ brcm,pins = <8 9>;
-+ brcm,function = ;
-+ brcm,pull = <0 2>;
-+ };
-+
-+ uart5_pins: uart5_pins {
-+ brcm,pins = <12 13>;
-+ brcm,function = ;
-+ brcm,pull = <0 2>;
-+ };
-+};
-+
-+&i2c0if {
-+ clock-frequency = <100000>;
-+};
-+
-+&i2c1 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&i2c1_pins>;
-+ clock-frequency = <100000>;
-+};
-+
-+&i2s {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&i2s_pins>;
-+};
-+
-+// =============================================
-+// Board specific stuff here
-+
-+/ {
-+ power_ctrl: power_ctrl {
-+ compatible = "gpio-poweroff";
-+ gpios = <&expgpio 5 0>;
-+ force;
-+ };
-+};
-+
-+&sdhost {
-+ status = "disabled";
-+};
-+
-+&phy1 {
-+ led-modes = <0x00 0x08>; /* link/activity link */
-+};
-+
-+&gpio {
-+ audio_pins: audio_pins {
-+ brcm,pins = <>;
-+ brcm,function = <>;
-+ };
-+};
-+
-+&leds {
-+ act_led: led-act {
-+ label = "led0";
-+ linux,default-trigger = "default-on";
-+ default-state = "on";
-+ gpios = <&gpio 42 GPIO_ACTIVE_HIGH>;
-+ };
-+
-+ pwr_led: led-pwr {
-+ label = "led1";
-+ linux,default-trigger = "default-on";
-+ gpios = <&expgpio 2 GPIO_ACTIVE_LOW>;
-+ };
-+};
-+
-+&pwm1 {
-+ status = "disabled";
-+};
-+
-+&vchiq {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&audio_pins>;
-+};
-+
- &genet_mdio {
- clock-frequency = <1950000>;
- };
-
--&pm {
-- /delete-property/ system-power-controller;
-+/ {
-+ __overrides__ {
-+ audio = <&chosen>,"bootargs{on='snd_bcm2835.enable_hdmi=1',off='snd_bcm2835.enable_hdmi=0'}";
-+
-+ act_led_gpio = <&act_led>,"gpios:4";
-+ act_led_activelow = <&act_led>,"gpios:8";
-+ act_led_trigger = <&act_led>,"linux,default-trigger";
-+
-+ pwr_led_gpio = <&pwr_led>,"gpios:4";
-+ pwr_led_activelow = <&pwr_led>,"gpios:8";
-+ pwr_led_trigger = <&pwr_led>,"linux,default-trigger";
-+
-+ eth_led0 = <&phy1>,"led-modes:0";
-+ eth_led1 = <&phy1>,"led-modes:4";
-+
-+ sd_poll_once = <&emmc2>, "non-removable?";
-+ spi_dma4 = <&spi0>, "dmas:0=", <&dma40>,
-+ <&spi0>, "dmas:8=", <&dma40>;
-+ };
- };
-diff --git a/arch/arm/boot/dts/bcm2711-rpi-cm4.dts b/arch/arm/boot/dts/bcm2711-rpi-cm4.dts
-new file mode 100644
-index 000000000000..5510a1b731c1
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm2711-rpi-cm4.dts
-@@ -0,0 +1,578 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/dts-v1/;
-+#define BCM2711
-+#define i2c0 i2c0if
-+#include "bcm2711.dtsi"
-+#include "bcm283x-rpi-wifi-bt.dtsi"
-+#undef i2c0
-+#include "bcm270x.dtsi"
-+#define i2c0 i2c0mux
-+#include "bcm2711-rpi.dtsi"
-+#undef i2c0
-+//#include "bcm283x-rpi-usb-peripheral.dtsi"
-+
-+/ {
-+ compatible = "raspberrypi,4-compute-module", "brcm,bcm2711";
-+ model = "Raspberry Pi Compute Module 4";
-+
-+ chosen {
-+ /* 8250 auxiliary UART instead of pl011 */
-+ stdout-path = "serial1:115200n8";
-+ };
-+
-+ leds {
-+ led-act {
-+ gpios = <&gpio 42 GPIO_ACTIVE_HIGH>;
-+ };
-+
-+ led-pwr {
-+ label = "PWR";
-+ gpios = <&expgpio 2 GPIO_ACTIVE_LOW>;
-+ default-state = "keep";
-+ linux,default-trigger = "default-on";
-+ };
-+ };
-+
-+ sd_io_1v8_reg: sd_io_1v8_reg {
-+ compatible = "regulator-gpio";
-+ regulator-name = "vdd-sd-io";
-+ regulator-min-microvolt = <1800000>;
-+ regulator-max-microvolt = <3300000>;
-+ regulator-boot-on;
-+ regulator-always-on;
-+ regulator-settling-time-us = <5000>;
-+ gpios = <&expgpio 4 GPIO_ACTIVE_HIGH>;
-+ states = <1800000 0x1>,
-+ <3300000 0x0>;
-+ status = "okay";
-+ };
-+
-+ sd_vcc_reg: sd_vcc_reg {
-+ compatible = "regulator-fixed";
-+ regulator-name = "vcc-sd";
-+ regulator-min-microvolt = <3300000>;
-+ regulator-max-microvolt = <3300000>;
-+ regulator-boot-on;
-+ enable-active-high;
-+ gpio = <&expgpio 6 GPIO_ACTIVE_HIGH>;
-+ };
-+};
-+
-+&bt {
-+ shutdown-gpios = <&expgpio 0 GPIO_ACTIVE_HIGH>;
-+};
-+
-+&ddc0 {
-+ status = "okay";
-+};
-+
-+&ddc1 {
-+ status = "okay";
-+};
-+
-+&expgpio {
-+ gpio-line-names = "BT_ON",
-+ "WL_ON",
-+ "PWR_LED_OFF",
-+ "ANT1",
-+ "VDD_SD_IO_SEL",
-+ "CAM_GPIO",
-+ "SD_PWR_ON",
-+ "ANT2";
-+
-+ ant1: ant1 {
-+ gpio-hog;
-+ gpios = <3 GPIO_ACTIVE_HIGH>;
-+ output-high;
-+ };
-+
-+ ant2: ant2 {
-+ gpio-hog;
-+ gpios = <7 GPIO_ACTIVE_HIGH>;
-+ output-low;
-+ };
-+};
-+
-+&gpio {
-+ /*
-+ * Parts taken from rpi_SCH_4b_4p0_reduced.pdf and
-+ * the official GPU firmware DT blob.
-+ *
-+ * Legend:
-+ * "FOO" = GPIO line named "FOO" on the schematic
-+ * "FOO_N" = GPIO line named "FOO" on schematic, active low
-+ */
-+ gpio-line-names = "ID_SDA",
-+ "ID_SCL",
-+ "SDA1",
-+ "SCL1",
-+ "GPIO_GCLK",
-+ "GPIO5",
-+ "GPIO6",
-+ "SPI_CE1_N",
-+ "SPI_CE0_N",
-+ "SPI_MISO",
-+ "SPI_MOSI",
-+ "SPI_SCLK",
-+ "GPIO12",
-+ "GPIO13",
-+ /* Serial port */
-+ "TXD1",
-+ "RXD1",
-+ "GPIO16",
-+ "GPIO17",
-+ "GPIO18",
-+ "GPIO19",
-+ "GPIO20",
-+ "GPIO21",
-+ "GPIO22",
-+ "GPIO23",
-+ "GPIO24",
-+ "GPIO25",
-+ "GPIO26",
-+ "GPIO27",
-+ "RGMII_MDIO",
-+ "RGMIO_MDC",
-+ /* Used by BT module */
-+ "CTS0",
-+ "RTS0",
-+ "TXD0",
-+ "RXD0",
-+ /* Used by Wifi */
-+ "SD1_CLK",
-+ "SD1_CMD",
-+ "SD1_DATA0",
-+ "SD1_DATA1",
-+ "SD1_DATA2",
-+ "SD1_DATA3",
-+ /* Shared with SPI flash */
-+ "PWM0_MISO",
-+ "PWM1_MOSI",
-+ "STATUS_LED_G_CLK",
-+ "SPIFLASH_CE_N",
-+ "SDA0",
-+ "SCL0",
-+ "RGMII_RXCLK",
-+ "RGMII_RXCTL",
-+ "RGMII_RXD0",
-+ "RGMII_RXD1",
-+ "RGMII_RXD2",
-+ "RGMII_RXD3",
-+ "RGMII_TXCLK",
-+ "RGMII_TXCTL",
-+ "RGMII_TXD0",
-+ "RGMII_TXD1",
-+ "RGMII_TXD2",
-+ "RGMII_TXD3";
-+};
-+
-+&hdmi0 {
-+ status = "okay";
-+};
-+
-+&hdmi1 {
-+ status = "okay";
-+};
-+
-+&pixelvalve0 {
-+ status = "okay";
-+};
-+
-+&pixelvalve1 {
-+ status = "okay";
-+};
-+
-+&pixelvalve2 {
-+ status = "okay";
-+};
-+
-+&pixelvalve4 {
-+ status = "okay";
-+};
-+
-+&pwm1 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&pwm1_0_gpio40 &pwm1_1_gpio41>;
-+ status = "okay";
-+};
-+
-+/* EMMC2 is used to drive the EMMC card */
-+&emmc2 {
-+ bus-width = <8>;
-+ vqmmc-supply = <&sd_io_1v8_reg>;
-+ vmmc-supply = <&sd_vcc_reg>;
-+ broken-cd;
-+ status = "okay";
-+};
-+
-+&genet {
-+ phy-handle = <&phy1>;
-+ phy-mode = "rgmii-rxid";
-+ status = "okay";
-+};
-+
-+&genet_mdio {
-+ phy1: ethernet-phy@0 {
-+ /* No PHY interrupt */
-+ reg = <0x0>;
-+ };
-+};
-+
-+&pcie0 {
-+ pci@0,0 {
-+ device_type = "pci";
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+ ranges;
-+
-+ reg = <0 0 0 0 0>;
-+ };
-+};
-+
-+/* uart0 communicates with the BT module */
-+&uart0 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&uart0_ctsrts_gpio30 &uart0_gpio32>;
-+ uart-has-rtscts;
-+};
-+
-+/* uart1 is mapped to the pin header */
-+&uart1 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&uart1_gpio14>;
-+ status = "okay";
-+};
-+
-+&vc4 {
-+ status = "okay";
-+};
-+
-+&vec {
-+ status = "disabled";
-+};
-+
-+&wifi_pwrseq {
-+ reset-gpios = <&expgpio 1 GPIO_ACTIVE_LOW>;
-+};
-+
-+// =============================================
-+// Downstream rpi- changes
-+
-+#include "bcm271x-rpi-bt.dtsi"
-+
-+/ {
-+ soc {
-+ /delete-node/ pixelvalve@7e807000;
-+ /delete-node/ hdmi@7e902000;
-+ };
-+};
-+
-+#include "bcm2711-rpi-ds.dtsi"
-+#include "bcm283x-rpi-csi0-2lane.dtsi"
-+#include "bcm283x-rpi-csi1-4lane.dtsi"
-+#include "bcm283x-rpi-i2c0mux_0_44.dtsi"
-+
-+/ {
-+ chosen {
-+ bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_headphones=0";
-+ };
-+
-+ aliases {
-+ serial0 = &uart1;
-+ serial1 = &uart0;
-+ mmc0 = &emmc2;
-+ mmc1 = &mmcnr;
-+ mmc2 = &sdhost;
-+ i2c3 = &i2c3;
-+ i2c4 = &i2c4;
-+ i2c5 = &i2c5;
-+ i2c6 = &i2c6;
-+ i2c20 = &ddc0;
-+ i2c21 = &ddc1;
-+ spi3 = &spi3;
-+ spi4 = &spi4;
-+ spi5 = &spi5;
-+ spi6 = &spi6;
-+ /delete-property/ intc;
-+ };
-+
-+ /delete-node/ wifi-pwrseq;
-+};
-+
-+&mmcnr {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&sdio_pins>;
-+ bus-width = <4>;
-+ status = "okay";
-+};
-+
-+&uart0 {
-+ pinctrl-0 = <&uart0_pins &bt_pins>;
-+ status = "okay";
-+};
-+
-+&uart1 {
-+ pinctrl-0 = <&uart1_pins>;
-+};
-+
-+&spi0 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&spi0_pins &spi0_cs_pins>;
-+ cs-gpios = <&gpio 8 1>, <&gpio 7 1>;
-+
-+ spidev0: spidev@0{
-+ compatible = "spidev";
-+ reg = <0>; /* CE0 */
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ spi-max-frequency = <125000000>;
-+ };
-+
-+ spidev1: spidev@1{
-+ compatible = "spidev";
-+ reg = <1>; /* CE1 */
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ spi-max-frequency = <125000000>;
-+ };
-+};
-+
-+&gpio {
-+ spi0_pins: spi0_pins {
-+ brcm,pins = <9 10 11>;
-+ brcm,function = ;
-+ };
-+
-+ spi0_cs_pins: spi0_cs_pins {
-+ brcm,pins = <8 7>;
-+ brcm,function = ;
-+ };
-+
-+ spi3_pins: spi3_pins {
-+ brcm,pins = <1 2 3>;
-+ brcm,function = ;
-+ };
-+
-+ spi3_cs_pins: spi3_cs_pins {
-+ brcm,pins = <0 24>;
-+ brcm,function =