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 = ; -+ }; -+ -+ 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 -+ -+&pcie0 { -+ brcm,enable-l1ss; -+}; -+ -+&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 = "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>; -+}; -+ -+cam0_reg: &cam1_reg { -+ gpio = <&expgpio 5 GPIO_ACTIVE_HIGH>; -+}; -+ -+/ { -+ __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"; -+ -+ ant1 = <&ant1>,"output-high?=on", -+ <&ant1>, "output-low?=off", -+ <&ant2>, "output-high?=off", -+ <&ant2>, "output-low?=on"; -+ ant2 = <&ant1>,"output-high?=off", -+ <&ant1>, "output-low?=on", -+ <&ant2>, "output-high?=on", -+ <&ant2>, "output-low?=off"; -+ noant = <&ant1>,"output-high?=off", -+ <&ant1>, "output-low?=on", -+ <&ant2>, "output-high?=off", -+ <&ant2>, "output-low?=on"; -+ -+ 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-cm4s.dts b/arch/arm/boot/dts/bcm2711-rpi-cm4s.dts -new file mode 100644 -index 000000000000..1a1d7af1d148 ---- /dev/null -+++ b/arch/arm/boot/dts/bcm2711-rpi-cm4s.dts -@@ -0,0 +1,427 @@ -+// 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 -+ -+/ { -+ compatible = "raspberrypi,4-compute-module-s", "brcm,bcm2711"; -+ model = "Raspberry Pi Compute Module 4S"; -+ -+ leds { -+ led-act { -+ gpios = <&virtgpio 0 0>; -+ }; -+ }; -+}; -+ -+&ddc0 { -+ status = "okay"; -+}; -+ -+&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", -+ "GPIO28", -+ "GPIO29", -+ "GPIO30", -+ "GPIO31", -+ "GPIO32", -+ "GPIO33", -+ "GPIO34", -+ "GPIO35", -+ "GPIO36", -+ "GPIO37", -+ "GPIO38", -+ "GPIO39", -+ "PWM0_MISO", -+ "PWM1_MOSI", -+ "GPIO42", -+ "GPIO43", -+ "GPIO44", -+ "GPIO45"; -+}; -+ -+&hdmi0 { -+ 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>; -+ broken-cd; -+ status = "okay"; -+}; -+ -+&pcie0 { -+ status = "disabled"; -+}; -+ -+&vchiq { -+ interrupts = ; -+}; -+ -+&vc4 { -+ status = "okay"; -+}; -+ -+&vec { -+ status = "disabled"; -+}; -+ -+// ============================================= -+// Downstream rpi- changes -+ -+#include "bcm2711-rpi-ds.dtsi" -+ -+/ { -+ soc { -+ /delete-node/ pixelvalve@7e807000; -+ /delete-node/ hdmi@7e902000; -+ -+ virtgpio: virtgpio { -+ compatible = "brcm,bcm2835-virtgpio"; -+ gpio-controller; -+ #gpio-cells = <2>; -+ firmware = <&firmware>; -+ status = "okay"; -+ }; -+ }; -+}; -+ -+#include "bcm283x-rpi-csi0-2lane.dtsi" -+#include "bcm283x-rpi-csi1-4lane.dtsi" -+#include "bcm283x-rpi-i2c0mux_0_28.dtsi" -+ -+/ { -+ chosen { -+ bootargs = "coherent_pool=1M snd_bcm2835.enable_headphones=0"; -+ }; -+ -+ aliases { -+ serial0 = &uart0; -+ mmc0 = &emmc2; -+ mmc1 = &mmcnr; -+ mmc2 = &sdhost; -+ i2c3 = &i2c3; -+ i2c4 = &i2c4; -+ i2c5 = &i2c5; -+ i2c6 = &i2c6; -+ spi3 = &spi3; -+ spi4 = &spi4; -+ spi5 = &spi5; -+ spi6 = &spi6; -+ /delete-property/ intc; -+ }; -+ -+ /delete-node/ wifi-pwrseq; -+}; -+ -+&uart0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart0_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>; -+ }; -+}; -+ -+&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>; -+ }; -+ -+ uart0_pins: uart0_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 -+ -+/* Enable USB in OTG-aware mode */ -+&usb { -+ compatible = "brcm,bcm2835-usb"; -+ dr_mode = "otg"; -+ g-np-tx-fifo-size = <32>; -+ g-rx-fifo-size = <558>; -+ g-tx-fifo-size = <512 512 512 512 512 256 256>; -+ status = "okay"; -+}; -+ -+&sdhost { -+ status = "disabled"; -+}; -+ -+&gpio { -+ audio_pins: audio_pins { -+ brcm,pins = <>; -+ brcm,function = <>; -+ }; -+}; -+ -+/* Permanently disable HDMI1 */ -+&hdmi1 { -+ compatible = "disabled"; -+}; -+ -+/* Permanently disable DDC1 */ -+&ddc1 { -+ compatible = "disabled"; -+}; -+ -+&leds { -+ act_led: led-act { -+ label = "led0"; -+ linux,default-trigger = "mmc0"; -+ }; -+}; -+ -+&pwm1 { -+ status = "disabled"; -+}; -+ -+&vchiq { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&audio_pins>; -+}; -+ -+&cam1_reg { -+ gpio = <&gpio 2 GPIO_ACTIVE_HIGH>; -+ status = "disabled"; -+}; -+ -+cam0_reg: &cam0_regulator { -+ gpio = <&gpio 30 GPIO_ACTIVE_HIGH>; -+ status = "disabled"; -+}; -+ -+/ { -+ __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"; -+ -+ 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-ds.dtsi b/arch/arm/boot/dts/bcm2711-rpi-ds.dtsi -new file mode 100644 -index 000000000000..5f9a5bad98ad ---- /dev/null -+++ b/arch/arm/boot/dts/bcm2711-rpi-ds.dtsi -@@ -0,0 +1,292 @@ -+// SPDX-License-Identifier: GPL-2.0 -+#include "bcm270x-rpi.dtsi" -+ -+/ { -+ __overrides__ { -+ arm_freq; -+ hdmi = <&hdmi0>,"status", -+ <&hdmi1>,"status"; -+ pcie = <&pcie0>,"status"; -+ sd = <&emmc2>,"status"; -+ }; -+ -+ scb: scb { -+ /* Add a label */ -+ }; -+ -+ arm-pmu { -+ compatible = "arm,cortex-a72-pmu", "arm,armv8-pmuv3", "arm,cortex-a7-pmu"; -+ -+ }; -+ -+ chosen { -+ /delete-property/ stdout-path; -+ }; -+}; -+ -+&vc4 { -+ raspberrypi,firmware = <&firmware>; -+}; -+ -+&cma { -+ /* Limit cma to the lower 768MB to allow room for HIGHMEM on 32-bit */ -+ alloc-ranges = <0x0 0x00000000 0x30000000>; -+}; -+ -+&scb { -+ #size-cells = <2>; -+ -+ ranges = <0x0 0x7c000000 0x0 0xfc000000 0x0 0x03800000>, -+ <0x0 0x40000000 0x0 0xff800000 0x0 0x00800000>, -+ <0x6 0x00000000 0x6 0x00000000 0x0 0x40000000>, -+ <0x0 0x00000000 0x0 0x00000000 0x0 0xfc000000>; -+ dma-ranges = <0x0 0x00000000 0x0 0x00000000 0x4 0x00000000>; -+ -+ dma40: dma@7e007b00 { -+ compatible = "brcm,bcm2711-dma"; -+ reg = <0x0 0x7e007b00 0x0 0x400>; -+ interrupts = -+ , /* dma4 11 */ -+ , /* dma4 12 */ -+ , /* dma4 13 */ -+ ; /* dma4 14 */ -+ interrupt-names = "dma11", -+ "dma12", -+ "dma13", -+ "dma14"; -+ #dma-cells = <1>; -+ brcm,dma-channel-mask = <0x7800>; -+ }; -+ -+ xhci: xhci@7e9c0000 { -+ compatible = "generic-xhci"; -+ status = "disabled"; -+ reg = <0x0 0x7e9c0000 0x0 0x100000>; -+ interrupts = ; -+ power-domains = <&power RPI_POWER_DOMAIN_USB>; -+ }; -+ -+ codec@7eb10000 { -+ compatible = "raspberrypi,rpivid-vid-decoder"; -+ reg = <0x0 0x7eb10000 0x0 0x1000>, /* INTC */ -+ <0x0 0x7eb00000 0x0 0x10000>; /* HEVC */ -+ reg-names = "intc", -+ "hevc"; -+ interrupts = ; -+ -+ clocks = <&firmware_clocks 11>; -+ clock-names = "hevc"; -+ }; -+}; -+ -+&pcie0 { -+ reg = <0x0 0x7d500000 0x0 0x9310>; -+ ranges = <0x02000000 0x0 0xc0000000 0x6 0x00000000 -+ 0x0 0x40000000>; -+}; -+ -+&genet { -+ reg = <0x0 0x7d580000 0x0 0x10000>; -+}; -+ -+&dma40 { -+ /* The VPU firmware uses DMA channel 11 for VCHIQ */ -+ brcm,dma-channel-mask = <0x7000>; -+}; -+ -+&vchiq { -+ compatible = "brcm,bcm2711-vchiq"; -+}; -+ -+&firmwarekms { -+ compatible = "raspberrypi,rpi-firmware-kms-2711"; -+ interrupts = ; -+}; -+ -+&smi { -+ interrupts = ; -+}; -+ -+&mmc { -+ interrupts = ; -+}; -+ -+&mmcnr { -+ interrupts = ; -+}; -+ -+&csi0 { -+ interrupts = ; -+}; -+ -+&csi1 { -+ interrupts = ; -+}; -+ -+&random { -+ compatible = "brcm,bcm2711-rng200"; -+ status = "okay"; -+}; -+ -+&usb { -+ /* Enable the FIQ support */ -+ reg = <0x7e980000 0x10000>, -+ <0x7e00b200 0x200>; -+ interrupts = , -+ ; -+ status = "disabled"; -+}; -+ -+&gpio { -+ interrupts = , -+ ; -+}; -+ -+&emmc2 { -+ mmc-ddr-3_3v; -+}; -+ -+&vc4 { -+ status = "disabled"; -+}; -+ -+&pixelvalve0 { -+ status = "disabled"; -+}; -+ -+&pixelvalve1 { -+ status = "disabled"; -+}; -+ -+&pixelvalve2 { -+ status = "disabled"; -+}; -+ -+&pixelvalve3 { -+ status = "disabled"; -+}; -+ -+&pixelvalve4 { -+ status = "disabled"; -+}; -+ -+&hdmi0 { -+ reg = <0x7ef00700 0x300>, -+ <0x7ef00300 0x200>, -+ <0x7ef00f00 0x80>, -+ <0x7ef00f80 0x80>, -+ <0x7ef01b00 0x200>, -+ <0x7ef01f00 0x400>, -+ <0x7ef00200 0x80>, -+ <0x7ef04300 0x100>, -+ <0x7ef20000 0x100>, -+ <0x7ef00100 0x30>; -+ reg-names = "hdmi", -+ "dvp", -+ "phy", -+ "rm", -+ "packet", -+ "metadata", -+ "csc", -+ "cec", -+ "hd", -+ "intr2"; -+ clocks = <&firmware_clocks 13>, -+ <&firmware_clocks 14>, -+ <&dvp 0>, -+ <&clk_27MHz>; -+ dmas = <&dma (10|(1<<27)|(1<<24)|(10<<16)|(15<<20))>; -+ status = "disabled"; -+}; -+ -+&ddc0 { -+ status = "disabled"; -+}; -+ -+&hdmi1 { -+ reg = <0x7ef05700 0x300>, -+ <0x7ef05300 0x200>, -+ <0x7ef05f00 0x80>, -+ <0x7ef05f80 0x80>, -+ <0x7ef06b00 0x200>, -+ <0x7ef06f00 0x400>, -+ <0x7ef00280 0x80>, -+ <0x7ef09300 0x100>, -+ <0x7ef20000 0x100>, -+ <0x7ef00100 0x30>; -+ reg-names = "hdmi", -+ "dvp", -+ "phy", -+ "rm", -+ "packet", -+ "metadata", -+ "csc", -+ "cec", -+ "hd", -+ "intr2"; -+ clocks = <&firmware_clocks 13>, -+ <&firmware_clocks 14>, -+ <&dvp 1>, -+ <&clk_27MHz>; -+ dmas = <&dma (17|(1<<27)|(1<<24)|(10<<16)|(15<<20))>; -+ status = "disabled"; -+}; -+ -+&ddc1 { -+ status = "disabled"; -+}; -+ -+&dvp { -+ status = "disabled"; -+}; -+ -+&vec { -+ clocks = <&firmware_clocks 15>; -+}; -+ -+&aon_intr { -+ interrupts = ; -+ status = "disabled"; -+}; -+ -+&system_timer { -+ status = "disabled"; -+}; -+ -+&i2c0 { -+ /delete-property/ compatible; -+ /delete-property/ interrupts; -+}; -+ -+&i2c0if { -+ compatible = "brcm,bcm2711-i2c", "brcm,bcm2835-i2c"; -+ interrupts = ; -+}; -+ -+/delete-node/ &v3d; -+ -+/ { -+ v3dbus: v3dbus { -+ compatible = "simple-bus"; -+ #address-cells = <1>; -+ #size-cells = <2>; -+ ranges = <0x7c500000 0x0 0xfc500000 0x0 0x03300000>, -+ <0x40000000 0x0 0xff800000 0x0 0x00800000>; -+ dma-ranges = <0x00000000 0x0 0x00000000 0x4 0x00000000>; -+ -+ v3d: v3d@7ec04000 { -+ compatible = "brcm,2711-v3d"; -+ reg = -+ <0x7ec00000 0x0 0x4000>, -+ <0x7ec04000 0x0 0x4000>; -+ reg-names = "hub", "core0"; -+ -+ power-domains = <&pm BCM2835_POWER_DOMAIN_GRAFX_V3D>; -+ resets = <&pm BCM2835_RESET_V3D>; -+ clocks = <&firmware_clocks 5>; -+ clocks-names = "v3d"; -+ interrupts = ; -+ status = "disabled"; -+ }; -+ }; -+}; -diff --git a/arch/arm/boot/dts/bcm2711-rpi.dtsi b/arch/arm/boot/dts/bcm2711-rpi.dtsi -index 98817a6675b9..7b9e946db985 100644 ---- a/arch/arm/boot/dts/bcm2711-rpi.dtsi -+++ b/arch/arm/boot/dts/bcm2711-rpi.dtsi -@@ -15,6 +15,7 @@ aliases { - ethernet0 = &genet; - pcie0 = &pcie0; - blconfig = &blconfig; -+ blpubkey = &blpubkey; - }; - }; - -@@ -67,6 +68,18 @@ blconfig: nvram@0 { - no-map; - status = "disabled"; - }; -+ /* -+ * RPi4 will copy the binary public key blob (if present) from the bootloader -+ * into memory for use by the OS. -+ */ -+ blpubkey: nvram@1 { -+ compatible = "raspberrypi,bootloader-public-key", "nvmem-rmem"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ reg = <0x0 0x0 0x0>; -+ no-map; -+ status = "disabled"; -+ }; - }; - - &v3d { -diff --git a/arch/arm/boot/dts/bcm271x-rpi-bt.dtsi b/arch/arm/boot/dts/bcm271x-rpi-bt.dtsi -new file mode 100644 -index 000000000000..6b9b79f74cf3 ---- /dev/null -+++ b/arch/arm/boot/dts/bcm271x-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 = <&expgpio 0 GPIO_ACTIVE_HIGH>; -+ status = "disabled"; -+ }; -+}; -+ -+&uart1 { -+ minibt: bluetooth { -+ compatible = "brcm,bcm43438-bt"; -+ max-speed = <460800>; -+ shutdown-gpios = <&expgpio 0 GPIO_ACTIVE_HIGH>; -+ status = "disabled"; -+ }; -+}; -+ -+/ { -+ __overrides__ { -+ krnbt = <&bt>,"status"; -+ krnbt_baudrate = <&bt>,"max-speed:0"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/bcm283x-rpi-csi0-2lane.dtsi b/arch/arm/boot/dts/bcm283x-rpi-csi0-2lane.dtsi -new file mode 100644 -index 000000000000..6e4ce8622b47 ---- /dev/null -+++ b/arch/arm/boot/dts/bcm283x-rpi-csi0-2lane.dtsi -@@ -0,0 +1,4 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+&csi0 { -+ brcm,num-data-lanes = <2>; -+}; -diff --git a/arch/arm/boot/dts/bcm283x-rpi-csi1-2lane.dtsi b/arch/arm/boot/dts/bcm283x-rpi-csi1-2lane.dtsi -new file mode 100644 -index 000000000000..6938f4daacdc ---- /dev/null -+++ b/arch/arm/boot/dts/bcm283x-rpi-csi1-2lane.dtsi -@@ -0,0 +1,4 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+&csi1 { -+ brcm,num-data-lanes = <2>; -+}; -diff --git a/arch/arm/boot/dts/bcm283x-rpi-csi1-4lane.dtsi b/arch/arm/boot/dts/bcm283x-rpi-csi1-4lane.dtsi -new file mode 100644 -index 000000000000..b37037437bee ---- /dev/null -+++ b/arch/arm/boot/dts/bcm283x-rpi-csi1-4lane.dtsi -@@ -0,0 +1,4 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+&csi1 { -+ brcm,num-data-lanes = <4>; -+}; -diff --git a/arch/arm/boot/dts/bcm283x-rpi-i2c0mux_0_28.dtsi b/arch/arm/boot/dts/bcm283x-rpi-i2c0mux_0_28.dtsi -new file mode 100644 -index 000000000000..38f0074bce3f ---- /dev/null -+++ b/arch/arm/boot/dts/bcm283x-rpi-i2c0mux_0_28.dtsi -@@ -0,0 +1,4 @@ -+&i2c0mux { -+ pinctrl-0 = <&i2c0_gpio0>; -+ pinctrl-1 = <&i2c0_gpio28>; -+}; -diff --git a/arch/arm/boot/dts/bcm283x-rpi-i2c0mux_0_44.dtsi b/arch/arm/boot/dts/bcm283x-rpi-i2c0mux_0_44.dtsi -new file mode 100644 -index 000000000000..119946d878db ---- /dev/null -+++ b/arch/arm/boot/dts/bcm283x-rpi-i2c0mux_0_44.dtsi -@@ -0,0 +1,4 @@ -+&i2c0mux { -+ pinctrl-0 = <&i2c0_gpio0>; -+ pinctrl-1 = <&i2c0_gpio44>; -+}; -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -new file mode 100644 -index 000000000000..37254235b641 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -0,0 +1,287 @@ -+# Overlays for the Raspberry Pi platform -+ -+dtb-$(CONFIG_ARCH_BCM2835) += overlay_map.dtb -+ -+dtbo-$(CONFIG_ARCH_BCM2835) += \ -+ act-led.dtbo \ -+ adafruit-st7735r.dtbo \ -+ adafruit18.dtbo \ -+ adau1977-adc.dtbo \ -+ adau7002-simple.dtbo \ -+ ads1015.dtbo \ -+ ads1115.dtbo \ -+ ads7846.dtbo \ -+ adv7282m.dtbo \ -+ adv728x-m.dtbo \ -+ akkordion-iqdacplus.dtbo \ -+ allo-boss-dac-pcm512x-audio.dtbo \ -+ allo-boss2-dac-audio.dtbo \ -+ allo-digione.dtbo \ -+ allo-katana-dac-audio.dtbo \ -+ allo-piano-dac-pcm512x-audio.dtbo \ -+ allo-piano-dac-plus-pcm512x-audio.dtbo \ -+ anyspi.dtbo \ -+ apds9960.dtbo \ -+ applepi-dac.dtbo \ -+ arducam-64mp.dtbo \ -+ arducam-pivariety.dtbo \ -+ at86rf233.dtbo \ -+ audioinjector-addons.dtbo \ -+ audioinjector-bare-i2s.dtbo \ -+ audioinjector-isolated-soundcard.dtbo \ -+ audioinjector-ultra.dtbo \ -+ audioinjector-wm8731-audio.dtbo \ -+ audiosense-pi.dtbo \ -+ audremap.dtbo \ -+ balena-fin.dtbo \ -+ camera-mux-2port.dtbo \ -+ camera-mux-4port.dtbo \ -+ cap1106.dtbo \ -+ chipdip-dac.dtbo \ -+ cirrus-wm5102.dtbo \ -+ cma.dtbo \ -+ cutiepi-panel.dtbo \ -+ dacberry400.dtbo \ -+ dht11.dtbo \ -+ dionaudio-kiwi.dtbo \ -+ dionaudio-loco.dtbo \ -+ dionaudio-loco-v2.dtbo \ -+ disable-bt.dtbo \ -+ disable-wifi.dtbo \ -+ dpi18.dtbo \ -+ dpi18cpadhi.dtbo \ -+ dpi24.dtbo \ -+ draws.dtbo \ -+ dwc-otg.dtbo \ -+ dwc2.dtbo \ -+ edt-ft5406.dtbo \ -+ enc28j60.dtbo \ -+ enc28j60-spi2.dtbo \ -+ exc3000.dtbo \ -+ fbtft.dtbo \ -+ fe-pi-audio.dtbo \ -+ fsm-demo.dtbo \ -+ gc9a01.dtbo \ -+ ghost-amp.dtbo \ -+ goodix.dtbo \ -+ googlevoicehat-soundcard.dtbo \ -+ gpio-fan.dtbo \ -+ gpio-hog.dtbo \ -+ gpio-ir.dtbo \ -+ gpio-ir-tx.dtbo \ -+ gpio-key.dtbo \ -+ gpio-led.dtbo \ -+ gpio-no-bank0-irq.dtbo \ -+ gpio-no-irq.dtbo \ -+ gpio-poweroff.dtbo \ -+ gpio-shutdown.dtbo \ -+ hd44780-lcd.dtbo \ -+ hdmi-backlight-hwhack-gpio.dtbo \ -+ hifiberry-amp.dtbo \ -+ hifiberry-amp100.dtbo \ -+ hifiberry-amp3.dtbo \ -+ hifiberry-dac.dtbo \ -+ hifiberry-dacplus.dtbo \ -+ hifiberry-dacplusadc.dtbo \ -+ hifiberry-dacplusadcpro.dtbo \ -+ hifiberry-dacplusdsp.dtbo \ -+ hifiberry-dacplushd.dtbo \ -+ hifiberry-digi.dtbo \ -+ hifiberry-digi-pro.dtbo \ -+ highperi.dtbo \ -+ hy28a.dtbo \ -+ hy28b.dtbo \ -+ hy28b-2017.dtbo \ -+ i-sabre-q2m.dtbo \ -+ i2c-bcm2708.dtbo \ -+ i2c-fan.dtbo \ -+ i2c-gpio.dtbo \ -+ i2c-mux.dtbo \ -+ i2c-pwm-pca9685a.dtbo \ -+ i2c-rtc.dtbo \ -+ i2c-rtc-gpio.dtbo \ -+ i2c-sensor.dtbo \ -+ i2c0.dtbo \ -+ i2c1.dtbo \ -+ i2c3.dtbo \ -+ i2c4.dtbo \ -+ i2c5.dtbo \ -+ i2c6.dtbo \ -+ i2s-dac.dtbo \ -+ i2s-gpio28-31.dtbo \ -+ ilitek251x.dtbo \ -+ imx219.dtbo \ -+ imx258.dtbo \ -+ imx290.dtbo \ -+ imx296.dtbo \ -+ imx327.dtbo \ -+ imx378.dtbo \ -+ imx462.dtbo \ -+ imx477.dtbo \ -+ imx519.dtbo \ -+ iqaudio-codec.dtbo \ -+ iqaudio-dac.dtbo \ -+ iqaudio-dacplus.dtbo \ -+ iqaudio-digi-wm8804-audio.dtbo \ -+ iqs550.dtbo \ -+ irs1125.dtbo \ -+ jedec-spi-nor.dtbo \ -+ justboom-both.dtbo \ -+ justboom-dac.dtbo \ -+ justboom-digi.dtbo \ -+ ltc294x.dtbo \ -+ max98357a.dtbo \ -+ maxtherm.dtbo \ -+ mbed-dac.dtbo \ -+ mcp23017.dtbo \ -+ mcp23s17.dtbo \ -+ mcp2515.dtbo \ -+ mcp2515-can0.dtbo \ -+ mcp2515-can1.dtbo \ -+ mcp251xfd.dtbo \ -+ mcp3008.dtbo \ -+ mcp3202.dtbo \ -+ mcp342x.dtbo \ -+ media-center.dtbo \ -+ merus-amp.dtbo \ -+ midi-uart0.dtbo \ -+ midi-uart1.dtbo \ -+ midi-uart2.dtbo \ -+ midi-uart3.dtbo \ -+ midi-uart4.dtbo \ -+ midi-uart5.dtbo \ -+ minipitft13.dtbo \ -+ miniuart-bt.dtbo \ -+ mipi-dbi-spi.dtbo \ -+ mlx90640.dtbo \ -+ mmc.dtbo \ -+ mpu6050.dtbo \ -+ mz61581.dtbo \ -+ ov2311.dtbo \ -+ ov5647.dtbo \ -+ ov7251.dtbo \ -+ ov9281.dtbo \ -+ papirus.dtbo \ -+ pca953x.dtbo \ -+ pcie-32bit-dma.dtbo \ -+ pibell.dtbo \ -+ pifacedigital.dtbo \ -+ pifi-40.dtbo \ -+ pifi-dac-hd.dtbo \ -+ pifi-dac-zero.dtbo \ -+ pifi-mini-210.dtbo \ -+ piglow.dtbo \ -+ piscreen.dtbo \ -+ piscreen2r.dtbo \ -+ pisound.dtbo \ -+ pitft22.dtbo \ -+ pitft28-capacitive.dtbo \ -+ pitft28-resistive.dtbo \ -+ pitft35-resistive.dtbo \ -+ pps-gpio.dtbo \ -+ proto-codec.dtbo \ -+ pwm.dtbo \ -+ pwm-2chan.dtbo \ -+ pwm-ir-tx.dtbo \ -+ qca7000.dtbo \ -+ qca7000-uart0.dtbo \ -+ ramoops.dtbo \ -+ ramoops-pi4.dtbo \ -+ rotary-encoder.dtbo \ -+ rpi-backlight.dtbo \ -+ rpi-codeczero.dtbo \ -+ rpi-dacplus.dtbo \ -+ rpi-dacpro.dtbo \ -+ rpi-digiampplus.dtbo \ -+ rpi-ft5406.dtbo \ -+ rpi-poe.dtbo \ -+ rpi-poe-plus.dtbo \ -+ rpi-sense.dtbo \ -+ rpi-sense-v2.dtbo \ -+ rpi-tv.dtbo \ -+ rra-digidac1-wm8741-audio.dtbo \ -+ sainsmart18.dtbo \ -+ sc16is750-i2c.dtbo \ -+ sc16is752-i2c.dtbo \ -+ sc16is752-spi0.dtbo \ -+ sc16is752-spi1.dtbo \ -+ sdhost.dtbo \ -+ sdio.dtbo \ -+ seeed-can-fd-hat-v1.dtbo \ -+ seeed-can-fd-hat-v2.dtbo \ -+ sh1106-spi.dtbo \ -+ si446x-spi0.dtbo \ -+ smi.dtbo \ -+ smi-dev.dtbo \ -+ smi-nand.dtbo \ -+ spi-gpio35-39.dtbo \ -+ spi-gpio40-45.dtbo \ -+ spi-rtc.dtbo \ -+ spi0-0cs.dtbo \ -+ spi0-1cs.dtbo \ -+ spi0-2cs.dtbo \ -+ spi1-1cs.dtbo \ -+ spi1-2cs.dtbo \ -+ spi1-3cs.dtbo \ -+ spi2-1cs.dtbo \ -+ spi2-2cs.dtbo \ -+ spi2-3cs.dtbo \ -+ spi3-1cs.dtbo \ -+ spi3-2cs.dtbo \ -+ spi4-1cs.dtbo \ -+ spi4-2cs.dtbo \ -+ spi5-1cs.dtbo \ -+ spi5-2cs.dtbo \ -+ spi6-1cs.dtbo \ -+ spi6-2cs.dtbo \ -+ ssd1306.dtbo \ -+ ssd1306-spi.dtbo \ -+ ssd1331-spi.dtbo \ -+ ssd1351-spi.dtbo \ -+ superaudioboard.dtbo \ -+ sx150x.dtbo \ -+ tc358743.dtbo \ -+ tc358743-audio.dtbo \ -+ tinylcd35.dtbo \ -+ tpm-slb9670.dtbo \ -+ tpm-slb9673.dtbo \ -+ uart0.dtbo \ -+ uart1.dtbo \ -+ uart2.dtbo \ -+ uart3.dtbo \ -+ uart4.dtbo \ -+ uart5.dtbo \ -+ udrc.dtbo \ -+ ugreen-dabboard.dtbo \ -+ upstream.dtbo \ -+ upstream-pi4.dtbo \ -+ vc4-fkms-v3d.dtbo \ -+ vc4-fkms-v3d-pi4.dtbo \ -+ vc4-kms-dpi-generic.dtbo \ -+ vc4-kms-dpi-hyperpixel2r.dtbo \ -+ vc4-kms-dpi-hyperpixel4.dtbo \ -+ vc4-kms-dpi-hyperpixel4sq.dtbo \ -+ vc4-kms-dpi-panel.dtbo \ -+ vc4-kms-dsi-7inch.dtbo \ -+ vc4-kms-dsi-lt070me05000.dtbo \ -+ vc4-kms-dsi-lt070me05000-v2.dtbo \ -+ vc4-kms-kippah-7inch.dtbo \ -+ vc4-kms-v3d.dtbo \ -+ vc4-kms-v3d-pi4.dtbo \ -+ vc4-kms-vga666.dtbo \ -+ vga666.dtbo \ -+ vl805.dtbo \ -+ w1-gpio.dtbo \ -+ w1-gpio-pullup.dtbo \ -+ w5500.dtbo \ -+ watterott-display.dtbo \ -+ waveshare-can-fd-hat-mode-a.dtbo \ -+ waveshare-can-fd-hat-mode-b.dtbo \ -+ wittypi.dtbo \ -+ wm8960-soundcard.dtbo -+ -+targets += dtbs dtbs_install -+targets += $(dtbo-y) -+ -+always-y := $(dtbo-y) -+clean-files := *.dtbo -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -new file mode 100644 -index 000000000000..90d861b85c9e ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/README -@@ -0,0 +1,4513 @@ -+Introduction -+============ -+ -+This directory contains Device Tree overlays. Device Tree makes it possible -+to support many hardware configurations with a single kernel and without the -+need to explicitly load or blacklist kernel modules. Note that this isn't a -+"pure" Device Tree configuration (c.f. MACH_BCM2835) - some on-board devices -+are still configured by the board support code, but the intention is to -+eventually reach that goal. -+ -+On Raspberry Pi, Device Tree usage is controlled from /boot/config.txt. By -+default, the Raspberry Pi kernel boots with device tree enabled. You can -+completely disable DT usage (for now) by adding: -+ -+ device_tree= -+ -+to your config.txt, which should cause your Pi to revert to the old way of -+doing things after a reboot. -+ -+In /boot you will find a .dtb for each base platform. This describes the -+hardware that is part of the Raspberry Pi board. The loader (start.elf and its -+siblings) selects the .dtb file appropriate for the platform by name, and reads -+it into memory. At this point, all of the optional interfaces (i2c, i2s, spi) -+are disabled, but they can be enabled using Device Tree parameters: -+ -+ dtparam=i2c=on,i2s=on,spi=on -+ -+However, this shouldn't be necessary in many use cases because loading an -+overlay that requires one of those interfaces will cause it to be enabled -+automatically, and it is advisable to only enable interfaces if they are -+needed. -+ -+Configuring additional, optional hardware is done using Device Tree overlays -+(see below). -+ -+GPIO numbering uses the hardware pin numbering scheme (aka BCM scheme) and -+not the physical pin numbers. -+ -+raspi-config -+============ -+ -+The Advanced Options section of the raspi-config utility can enable and disable -+Device Tree use, as well as toggling the I2C and SPI interfaces. Note that it -+is possible to both enable an interface and blacklist the driver, if for some -+reason you should want to defer the loading. -+ -+Modules -+======= -+ -+As well as describing the hardware, Device Tree also gives enough information -+to allow suitable driver modules to be located and loaded, with the corollary -+that unneeded modules are not loaded. As a result it should be possible to -+remove lines from /etc/modules, and /etc/modprobe.d/raspi-blacklist.conf can -+have its contents deleted (or commented out). -+ -+Using Overlays -+============== -+ -+Overlays are loaded using the "dtoverlay" config.txt setting. As an example, -+consider I2C Real Time Clock drivers. In the pre-DT world these would be loaded -+by writing a magic string comprising a device identifier and an I2C address to -+a special file in /sys/class/i2c-adapter, having first loaded the driver for -+the I2C interface and the RTC device - something like this: -+ -+ modprobe i2c-bcm2835 -+ modprobe rtc-ds1307 -+ echo ds1307 0x68 > /sys/class/i2c-adapter/i2c-1/new_device -+ -+With DT enabled, this becomes a line in config.txt: -+ -+ dtoverlay=i2c-rtc,ds1307 -+ -+This causes the file /boot/overlays/i2c-rtc.dtbo to be loaded and a "node" -+describing the DS1307 I2C device to be added to the Device Tree for the Pi. By -+default it usees address 0x68, but this can be modified with an additional DT -+parameter: -+ -+ dtoverlay=i2c-rtc,ds1307,addr=0x68 -+ -+Parameters usually have default values, although certain parameters are -+mandatory. See the list of overlays below for a description of the parameters -+and their defaults. -+ -+Making new Overlays based on existing Overlays -+============================================== -+ -+Recent overlays have been designed in a more general way, so that they can be -+adapted to hardware by changing their parameters. When you have additional -+hardware with more than one device of a kind, you end up using the same overlay -+multiple times with other parameters, e.g. -+ -+ # 2 CAN FD interfaces on spi but with different pins -+ dtoverlay=mcp251xfd,spi0-0,interrupt=25 -+ dtoverlay=mcp251xfd,spi0-1,interrupt=24 -+ -+ # a realtime clock on i2c -+ dtoverlay=i2c-rtc,pcf85063 -+ -+While this approach does work, it requires knowledge about the hardware design. -+It is more feasible to simplify things for the end user by providing a single -+overlay as it is done the traditional way. -+ -+A new overlay can be generated by using ovmerge utility. -+https://github.com/raspberrypi/utils/blob/master/ovmerge/ovmerge -+ -+To generate an overlay for the above configuration we pass the configuration -+to ovmerge and add the -c flag. -+ -+ ovmerge -c mcp251xfd-overlay.dts,spi0-0,interrupt=25 \ -+ mcp251xfd-overlay.dts,spi0-1,interrupt=24 \ -+ i2c-rtc-overlay.dts,pcf85063 \ -+ >> merged-overlay.dts -+ -+The -c option writes the command above as a comment into the overlay as -+a marker that this overlay is generated and how it was generated. -+After compiling the overlay it can be loaded in a single line. -+ -+ dtoverlay=merged -+ -+It does the same as the original configuration but without parameters. -+ -+The Overlay and Parameter Reference -+=================================== -+ -+N.B. When editing this file, please preserve the indentation levels to make it -+simple to parse programmatically. NO HARD TABS. -+ -+ -+Name: -+Info: Configures the base Raspberry Pi hardware -+Load: -+Params: -+ ant1 Select antenna 1 (default). CM4 only. -+ -+ ant2 Select antenna 2. CM4 only. -+ -+ noant Disable both antennas. CM4 only. -+ -+ audio Set to "on" to enable the onboard ALSA audio -+ interface (default "off") -+ -+ axiperf Set to "on" to enable the AXI bus performance -+ monitors. -+ See /sys/kernel/debug/raspberrypi_axi_monitor -+ for the results. -+ -+ cam0_reg Enables CAM 0 regulator. CM1 & 3 only. -+ -+ cam0_reg_gpio Set GPIO for CAM 0 regulator. Default 30. -+ CM1 & 3 only. -+ -+ cam1_reg Enables CAM 1 regulator. CM1 & 3 only. -+ -+ cam1_reg_gpio Set GPIO for CAM 1 regulator. Default 2. -+ CM1 & 3 only. -+ -+ eee Enable Energy Efficient Ethernet support for -+ compatible devices (default "on"). See also -+ "tx_lpi_timer". Pi3B+ only. -+ -+ eth_downshift_after Set the number of auto-negotiation failures -+ after which the 1000Mbps modes are disabled. -+ Legal values are 2, 3, 4, 5 and 0, where -+ 0 means never downshift (default 2). Pi3B+ only. -+ -+ eth_led0 Set mode of LED0 - amber on Pi3B+ (default "1"), -+ green on Pi4 (default "0"). -+ The legal values are: -+ -+ Pi3B+ -+ -+ 0=link/activity 1=link1000/activity -+ 2=link100/activity 3=link10/activity -+ 4=link100/1000/activity 5=link10/1000/activity -+ 6=link10/100/activity 14=off 15=on -+ -+ Pi4 -+ -+ 0=Speed/Activity 1=Speed -+ 2=Flash activity 3=FDX -+ 4=Off 5=On -+ 6=Alt 7=Speed/Flash -+ 8=Link 9=Activity -+ -+ eth_led1 Set mode of LED1 - green on Pi3B+ (default "6"), -+ amber on Pi4 (default "8"). See eth_led0 for -+ legal values. -+ -+ eth_max_speed Set the maximum speed a link is allowed -+ to negotiate. Legal values are 10, 100 and -+ 1000 (default 1000). Pi3B+ only. -+ -+ hdmi Set to "off" to disable the HDMI interface -+ (default "on") -+ -+ i2c_arm Set to "on" to enable the ARM's i2c interface -+ (default "off") -+ -+ i2c_vc Set to "on" to enable the i2c interface -+ usually reserved for the VideoCore processor -+ (default "off") -+ -+ i2c An alias for i2c_arm -+ -+ i2c_arm_baudrate Set the baudrate of the ARM's i2c interface -+ (default "100000") -+ -+ i2c_vc_baudrate Set the baudrate of the VideoCore i2c interface -+ (default "100000") -+ -+ i2c_baudrate An alias for i2c_arm_baudrate -+ -+ i2s Set to "on" to enable the i2s interface -+ (default "off") -+ -+ krnbt Set to "on" to enable autoprobing of Bluetooth -+ driver without need of hciattach/btattach -+ (default "off") -+ -+ krnbt_baudrate Set the baudrate of the PL011 UART when used -+ with krnbt=on -+ -+ pcie Set to "off" to disable the PCIe interface -+ (default "on") -+ (2711 only, but not applicable on CM4S) -+ N.B. USB-A ports on 4B are subsequently disabled -+ -+ spi Set to "on" to enable the spi interfaces -+ (default "off") -+ -+ spi_dma4 Use to enable 40-bit DMA on spi interfaces -+ (the assigned value doesn't matter) -+ (2711 only) -+ -+ random Set to "on" to enable the hardware random -+ number generator (default "on") -+ -+ sd Set to "off" to disable the SD card (or eMMC on -+ non-lite SKU of CM4). -+ (default "on") -+ -+ sd_overclock Clock (in MHz) to use when the MMC framework -+ requests 50MHz -+ -+ sd_poll_once Looks for a card once after booting. Useful -+ for network booting scenarios to avoid the -+ overhead of continuous polling. N.B. Using -+ this option restricts the system to using a -+ single card per boot (or none at all). -+ (default off) -+ -+ sd_force_pio Disable DMA support for SD driver (default off) -+ -+ sd_pio_limit Number of blocks above which to use DMA for -+ SD card (default 1) -+ -+ sd_debug Enable debug output from SD driver (default off) -+ -+ sdio_overclock Clock (in MHz) to use when the MMC framework -+ requests 50MHz for the SDIO/WLAN interface. -+ -+ tx_lpi_timer Set the delay in microseconds between going idle -+ and entering the low power state (default 600). -+ Requires EEE to be enabled - see "eee". -+ -+ uart0 Set to "off" to disable uart0 (default "on") -+ -+ uart1 Set to "on" or "off" to enable or disable uart1 -+ (default varies) -+ -+ watchdog Set to "on" to enable the hardware watchdog -+ (default "off") -+ -+ act_led_trigger Choose which activity the LED tracks. -+ Use "heartbeat" for a nice load indicator. -+ (default "mmc") -+ -+ act_led_activelow Set to "on" to invert the sense of the LED -+ (default "off") -+ N.B. For Pi 3B, 3B+, 3A+ and 4B, use the act-led -+ overlay. -+ -+ act_led_gpio Set which GPIO to use for the activity LED -+ (in case you want to connect it to an external -+ device) -+ (default "16" on a non-Plus board, "47" on a -+ Plus or Pi 2) -+ N.B. For Pi 3B, 3B+, 3A+ and 4B, use the act-led -+ overlay. -+ -+ pwr_led_trigger -+ pwr_led_activelow -+ pwr_led_gpio -+ As for act_led_*, but using the PWR LED. -+ Not available on Model A/B boards. -+ -+ N.B. It is recommended to only enable those interfaces that are needed. -+ Leaving all interfaces enabled can lead to unwanted behaviour (i2c_vc -+ interfering with Pi Camera, I2S and SPI hogging GPIO pins, etc.) -+ Note also that i2c, i2c_arm and i2c_vc are aliases for the physical -+ interfaces i2c0 and i2c1. Use of the numeric variants is still possible -+ but deprecated because the ARM/VC assignments differ between board -+ revisions. The same board-specific mapping applies to i2c_baudrate, -+ and the other i2c baudrate parameters. -+ -+ -+Name: act-led -+Info: Pi 3B, 3B+, 3A+ and 4B use a GPIO expander to drive the LEDs which can -+ only be accessed from the VPU. There is a special driver for this with a -+ separate DT node, which has the unfortunate consequence of breaking the -+ act_led_gpio and act_led_activelow dtparams. -+ This overlay changes the GPIO controller back to the standard one and -+ restores the dtparams. -+Load: dtoverlay=act-led,= -+Params: activelow Set to "on" to invert the sense of the LED -+ (default "off") -+ -+ gpio Set which GPIO to use for the activity LED -+ (in case you want to connect it to an external -+ device) -+ REQUIRED -+ -+ -+Name: adafruit-st7735r -+Info: Overlay for the SPI-connected Adafruit 1.8" 160x128 or 128x128 displays, -+ based on the ST7735R chip. -+ This overlay uses the newer DRM/KMS "Tiny" driver. -+Load: dtoverlay=adafruit-st7735r,= -+Params: 128x128 Select the 128x128 driver (default 160x128) -+ rotate Display rotation {0,90,180,270} (default 90) -+ speed SPI bus speed in Hz (default 4000000) -+ dc_pin GPIO pin for D/C (default 24) -+ reset_pin GPIO pin for RESET (default 25) -+ led_pin GPIO used to control backlight (default 18) -+ -+ -+Name: adafruit18 -+Info: Overlay for the SPI-connected Adafruit 1.8" display (based on the -+ ST7735R chip). It includes support for the "green tab" version. -+ This overlay uses the older fbtft driver. -+Load: dtoverlay=adafruit18,= -+Params: green Use the adafruit18_green variant. -+ rotate Display rotation {0,90,180,270} -+ speed SPI bus speed in Hz (default 4000000) -+ fps Display frame rate in Hz -+ bgr Enable BGR mode (default off) -+ debug Debug output level {0-7} -+ dc_pin GPIO pin for D/C (default 24) -+ reset_pin GPIO pin for RESET (default 25) -+ led_pin GPIO used to control backlight (default 18) -+ -+ -+Name: adau1977-adc -+Info: Overlay for activation of ADAU1977 ADC codec over I2C for control -+ and I2S for data. -+Load: dtoverlay=adau1977-adc -+Params: -+ -+ -+Name: adau7002-simple -+Info: Overlay for the activation of ADAU7002 stereo PDM to I2S converter. -+Load: dtoverlay=adau7002-simple,= -+Params: card-name Override the default, "adau7002", card name. -+ -+ -+Name: ads1015 -+Info: Overlay for activation of Texas Instruments ADS1015 ADC over I2C -+Load: dtoverlay=ads1015,= -+Params: addr I2C bus address of device. Set based on how the -+ addr pin is wired. (default=0x48 assumes addr -+ is pulled to GND) -+ cha_enable Enable virtual channel a. (default=true) -+ cha_cfg Set the configuration for virtual channel a. -+ (default=4 configures this channel for the -+ voltage at A0 with respect to GND) -+ cha_datarate Set the datarate (samples/sec) for this channel. -+ (default=4 sets 1600 sps) -+ cha_gain Set the gain of the Programmable Gain -+ Amplifier for this channel. (default=2 sets the -+ full scale of the channel to 2.048 Volts) -+ -+ Channel (ch) parameters can be set for each enabled channel. -+ A maximum of 4 channels can be enabled (letters a thru d). -+ For more information refer to the device datasheet at: -+ http://www.ti.com/lit/ds/symlink/ads1015.pdf -+ -+ -+Name: ads1115 -+Info: Texas Instruments ADS1115 ADC -+Load: dtoverlay=ads1115,[=] -+Params: addr I2C bus address of device. Set based on how the -+ addr pin is wired. (default=0x48 assumes addr -+ is pulled to GND) -+ cha_enable Enable virtual channel a. -+ cha_cfg Set the configuration for virtual channel a. -+ (default=4 configures this channel for the -+ voltage at A0 with respect to GND) -+ cha_datarate Set the datarate (samples/sec) for this channel. -+ (default=7 sets 860 sps) -+ cha_gain Set the gain of the Programmable Gain -+ Amplifier for this channel. (Default 1 sets the -+ full scale of the channel to 4.096 Volts) -+ -+ Channel parameters can be set for each enabled channel. -+ A maximum of 4 channels can be enabled (letters a thru d). -+ For more information refer to the device datasheet at: -+ http://www.ti.com/lit/ds/symlink/ads1115.pdf -+ -+ -+Name: ads7846 -+Info: ADS7846 Touch controller -+Load: dtoverlay=ads7846,= -+Params: cs SPI bus Chip Select (default 1) -+ speed SPI bus speed (default 2MHz, max 3.25MHz) -+ penirq GPIO used for PENIRQ. REQUIRED -+ penirq_pull Set GPIO pull (default 0=none, 2=pullup) -+ swapxy Swap x and y axis -+ xmin Minimum value on the X axis (default 0) -+ ymin Minimum value on the Y axis (default 0) -+ xmax Maximum value on the X axis (default 4095) -+ ymax Maximum value on the Y axis (default 4095) -+ pmin Minimum reported pressure value (default 0) -+ pmax Maximum reported pressure value (default 65535) -+ xohms Touchpanel sensitivity (X-plate resistance) -+ (default 400) -+ -+ penirq is required and usually xohms (60-100) has to be set as well. -+ Apart from that, pmax (255) and swapxy are also common. -+ The rest of the calibration can be done with xinput-calibrator. -+ See: github.com/notro/fbtft/wiki/FBTFT-on-Raspian -+ Device Tree binding document: -+ www.kernel.org/doc/Documentation/devicetree/bindings/input/ads7846.txt -+ -+ -+Name: adv7282m -+Info: Analog Devices ADV7282M analogue video to CSI2 bridge. -+ Uses Unicam1, which is the standard camera connector on most Pi -+ variants. -+Load: dtoverlay=adv7282m,= -+Params: addr Overrides the I2C address (default 0x21) -+ media-controller Configure use of Media Controller API for -+ configuring the sensor (default off) -+ -+ -+Name: adv728x-m -+Info: Analog Devices ADV728[0|1|2]-M analogue video to CSI2 bridges. -+ This is a wrapper for adv7282m, and defaults to ADV7282M. -+Load: dtoverlay=adv728x-m,= -+Params: addr Overrides the I2C address (default 0x21) -+ adv7280m Select ADV7280-M. -+ adv7281m Select ADV7281-M. -+ adv7281ma Select ADV7281-MA. -+ media-controller Configure use of Media Controller API for -+ configuring the sensor (default off) -+ -+ -+Name: akkordion-iqdacplus -+Info: Configures the Digital Dreamtime Akkordion Music Player (based on the -+ OEM IQAudIO DAC+ or DAC Zero module). -+Load: dtoverlay=akkordion-iqdacplus,= -+Params: 24db_digital_gain Allow gain to be applied via the PCM512x codec -+ Digital volume control. Enable with -+ dtoverlay=akkordion-iqdacplus,24db_digital_gain -+ (The default behaviour is that the Digital -+ volume control is limited to a maximum of -+ 0dB. ie. it can attenuate but not provide -+ gain. For most users, this will be desired -+ as it will prevent clipping. By appending -+ the 24db_digital_gain parameter, the Digital -+ volume control will allow up to 24dB of -+ gain. If this parameter is enabled, it is the -+ responsibility of the user to ensure that -+ the Digital volume control is set to a value -+ that does not result in clipping/distortion!) -+ -+ -+Name: allo-boss-dac-pcm512x-audio -+Info: Configures the Allo Boss DAC audio cards. -+Load: dtoverlay=allo-boss-dac-pcm512x-audio, -+Params: 24db_digital_gain Allow gain to be applied via the PCM512x codec -+ Digital volume control. Enable with -+ "dtoverlay=allo-boss-dac-pcm512x-audio, -+ 24db_digital_gain" -+ (The default behaviour is that the Digital -+ volume control is limited to a maximum of -+ 0dB. ie. it can attenuate but not provide -+ gain. For most users, this will be desired -+ as it will prevent clipping. By appending -+ the 24db_digital_gain parameter, the Digital -+ volume control will allow up to 24dB of -+ gain. If this parameter is enabled, it is the -+ responsibility of the user to ensure that -+ the Digital volume control is set to a value -+ that does not result in clipping/distortion!) -+ slave Force Boss DAC into slave mode, using Pi a -+ master for bit clock and frame clock. Enable -+ with "dtoverlay=allo-boss-dac-pcm512x-audio, -+ slave" -+ -+ -+Name: allo-boss2-dac-audio -+Info: Configures the Allo Boss2 DAC audio card -+Load: dtoverlay=allo-boss2-dac-audio -+Params: -+ -+ -+Name: allo-digione -+Info: Configures the Allo Digione audio card -+Load: dtoverlay=allo-digione -+Params: -+ -+ -+Name: allo-katana-dac-audio -+Info: Configures the Allo Katana DAC audio card -+Load: dtoverlay=allo-katana-dac-audio -+Params: -+ -+ -+Name: allo-piano-dac-pcm512x-audio -+Info: Configures the Allo Piano DAC (2.0/2.1) audio cards. -+ (NB. This initial support is for 2.0 channel audio ONLY! ie. stereo. -+ The subwoofer outputs on the Piano 2.1 are not currently supported!) -+Load: dtoverlay=allo-piano-dac-pcm512x-audio, -+Params: 24db_digital_gain Allow gain to be applied via the PCM512x codec -+ Digital volume control. -+ (The default behaviour is that the Digital -+ volume control is limited to a maximum of -+ 0dB. ie. it can attenuate but not provide -+ gain. For most users, this will be desired -+ as it will prevent clipping. By appending -+ the 24db_digital_gain parameter, the Digital -+ volume control will allow up to 24dB of -+ gain. If this parameter is enabled, it is the -+ responsibility of the user to ensure that -+ the Digital volume control is set to a value -+ that does not result in clipping/distortion!) -+ -+ -+Name: allo-piano-dac-plus-pcm512x-audio -+Info: Configures the Allo Piano DAC (2.1) audio cards. -+Load: dtoverlay=allo-piano-dac-plus-pcm512x-audio, -+Params: 24db_digital_gain Allow gain to be applied via the PCM512x codec -+ Digital volume control. -+ (The default behaviour is that the Digital -+ volume control is limited to a maximum of -+ 0dB. ie. it can attenuate but not provide -+ gain. For most users, this will be desired -+ as it will prevent clipping. By appending -+ the 24db_digital_gain parameter, the Digital -+ volume control will allow up to 24dB of -+ gain. If this parameter is enabled, it is the -+ responsibility of the user to ensure that -+ the Digital volume control is set to a value -+ that does not result in clipping/distortion!) -+ glb_mclk This option is only with Kali board. If enabled, -+ MCLK for Kali is used and PLL is disabled for -+ better voice quality. (default Off) -+ -+ -+Name: anyspi -+Info: Universal device tree overlay for SPI devices -+ -+ Just specify the SPI address and device name ("compatible" property). -+ This overlay lacks any device-specific parameter support! -+ -+ For devices on spi1 or spi2, the interfaces should be enabled -+ with one of the spi1-1/2/3cs and/or spi2-1/2/3cs overlays. -+ -+ Examples: -+ 1. SPI NOR flash on spi0.1, maximum SPI clock frequency 45MHz: -+ dtoverlay=anyspi:spi0-1,dev="jedec,spi-nor",speed=45000000 -+ 2. MCP3204 ADC on spi1.2, maximum SPI clock frequency 500kHz: -+ dtoverlay=anyspi:spi1-2,dev="microchip,mcp3204" -+Load: dtoverlay=anyspi,= -+Params: spi- Configure device at spi, cs -+ (boolean, required) -+ dev Set device name to search compatible module -+ (string, required) -+ speed Set SPI clock frequency in Hz -+ (integer, optional, default 500000) -+ -+ -+Name: apds9960 -+Info: Configures the AVAGO APDS9960 digital proximity, ambient light, RGB and -+ gesture sensor -+Load: dtoverlay=apds9960,= -+Params: gpiopin GPIO used for INT (default 4) -+ noints Disable the interrupt GPIO line. -+ -+ -+Name: applepi-dac -+Info: Configures the Orchard Audio ApplePi-DAC audio card -+Load: dtoverlay=applepi-dac -+Params: -+ -+ -+Name: arducam-64mp -+Info: Arducam 64MP camera module. -+ Uses Unicam 1, which is the standard camera connector on most Pi -+ variants. -+Load: dtoverlay=arducam-64mp,= -+Params: rotation Mounting rotation of the camera sensor (0 or -+ 180, default 0) -+ orientation Sensor orientation (0 = front, 1 = rear, -+ 2 = external, default external) -+ media-controller Configure use of Media Controller API for -+ configuring the sensor (default on) -+ cam0 Adopt the default configuration for CAM0 on a -+ Compute Module (CSI0, i2c_vc, and cam0_reg). -+ -+ -+Name: arducam-pivariety -+Info: Arducam Pivariety camera module. -+ Uses Unicam 1, which is the standard camera connector on most Pi -+ variants. -+Load: dtoverlay=arducam-pivariety,= -+Params: rotation Mounting rotation of the camera sensor (0 or -+ 180, default 0) -+ orientation Sensor orientation (0 = front, 1 = rear, -+ 2 = external, default external) -+ media-controller Configure use of Media Controller API for -+ configuring the sensor (default on) -+ cam0 Adopt the default configuration for CAM0 on a -+ Compute Module (CSI0, i2c_vc, and cam0_reg). -+ -+ -+Name: at86rf233 -+Info: Configures the Atmel AT86RF233 802.15.4 low-power WPAN transceiver, -+ connected to spi0.0 -+Load: dtoverlay=at86rf233,= -+Params: interrupt GPIO used for INT (default 23) -+ reset GPIO used for Reset (default 24) -+ sleep GPIO used for Sleep (default 25) -+ speed SPI bus speed in Hz (default 3000000) -+ trim Fine tuning of the internal capacitance -+ arrays (0=+0pF, 15=+4.5pF, default 15) -+ -+ -+Name: audioinjector-addons -+Info: Configures the audioinjector.net audio add on soundcards -+Load: dtoverlay=audioinjector-addons,= -+Params: non-stop-clocks Keeps the clocks running even when the stream -+ is paused or stopped (default off) -+ -+ -+Name: audioinjector-bare-i2s -+Info: Configures the audioinjector.net audio bare i2s soundcard -+Load: dtoverlay=audioinjector-bare-i2s -+Params: -+ -+ -+Name: audioinjector-isolated-soundcard -+Info: Configures the audioinjector.net isolated soundcard -+Load: dtoverlay=audioinjector-isolated-soundcard -+Params: -+ -+ -+Name: audioinjector-ultra -+Info: Configures the audioinjector.net ultra soundcard -+Load: dtoverlay=audioinjector-ultra -+Params: -+ -+ -+Name: audioinjector-wm8731-audio -+Info: Configures the audioinjector.net audio add on soundcard -+Load: dtoverlay=audioinjector-wm8731-audio -+Params: -+ -+ -+Name: audiosense-pi -+Info: Configures the audiosense-pi add on soundcard -+ For more information refer to -+ https://gitlab.com/kakar0t/audiosense-pi -+Load: dtoverlay=audiosense-pi -+Params: -+ -+ -+Name: audremap -+Info: Switches PWM sound output to GPIOs on the 40-pin header -+Load: dtoverlay=audremap,= -+Params: swap_lr Reverse the channel allocation, which will also -+ swap the audio jack outputs (default off) -+ enable_jack Don't switch off the audio jack output -+ (default off) -+ pins_12_13 Select GPIOs 12 & 13 (default) -+ pins_18_19 Select GPIOs 18 & 19 -+ -+ -+Name: balena-fin -+Info: Overlay that enables WLAN, Bluetooth and the GPIO expander on the -+ balenaFin carrier board for the Raspberry Pi Compute Module 3/3+ Lite. -+Load: dtoverlay=balena-fin -+Params: -+ -+ -+Name: bmp085_i2c-sensor -+Info: This overlay is now deprecated - see i2c-sensor -+Load: -+ -+ -+Name: camera-mux-2port -+Info: Configures a 2 port camera multiplexer -+ Note that currently ALL IMX290 modules share a common clock, therefore -+ all modules will need to have the same clock frequency. -+Load: dtoverlay=camera-mux-2port,= -+Params: cam0-imx219 Select IMX219 for camera on port 0 -+ cam0-imx258 Select IMX258 for camera on port 0 -+ cam0-imx290 Select IMX290 for camera on port 0 -+ cam0-imx477 Select IMX477 for camera on port 0 -+ cam0-ov2311 Select OV2311 for camera on port 0 -+ cam0-ov5647 Select OV5647 for camera on port 0 -+ cam0-ov7251 Select OV7251 for camera on port 0 -+ cam0-ov9281 Select OV9281 for camera on port 0 -+ cam0-imx290-clk-freq Set clock frequency for an IMX290 on port 0 -+ cam1-imx219 Select IMX219 for camera on port 1 -+ cam1-imx258 Select IMX258 for camera on port 1 -+ cam1-imx290 Select IMX290 for camera on port 1 -+ cam1-imx477 Select IMX477 for camera on port 1 -+ cam1-ov2311 Select OV2311 for camera on port 1 -+ cam1-ov5647 Select OV5647 for camera on port 1 -+ cam1-ov7251 Select OV7251 for camera on port 1 -+ cam1-ov9281 Select OV9281 for camera on port 1 -+ cam1-imx290-clk-freq Set clock frequency for an IMX290 on port 1 -+ -+ -+Name: camera-mux-4port -+Info: Configures a 4 port camera multiplexer -+ Note that currently ALL IMX290 modules share a common clock, therefore -+ all modules will need to have the same clock frequency. -+Load: dtoverlay=camera-mux-4port,= -+Params: cam0-imx219 Select IMX219 for camera on port 0 -+ cam0-imx258 Select IMX258 for camera on port 0 -+ cam0-imx290 Select IMX290 for camera on port 0 -+ cam0-imx477 Select IMX477 for camera on port 0 -+ cam0-ov2311 Select OV2311 for camera on port 0 -+ cam0-ov5647 Select OV5647 for camera on port 0 -+ cam0-ov7251 Select OV7251 for camera on port 0 -+ cam0-ov9281 Select OV9281 for camera on port 0 -+ cam0-imx290-clk-freq Set clock frequency for an IMX290 on port 0 -+ cam1-imx219 Select IMX219 for camera on port 1 -+ cam1-imx258 Select IMX258 for camera on port 1 -+ cam1-imx290 Select IMX290 for camera on port 1 -+ cam1-imx477 Select IMX477 for camera on port 1 -+ cam1-ov2311 Select OV2311 for camera on port 1 -+ cam1-ov5647 Select OV5647 for camera on port 1 -+ cam1-ov7251 Select OV7251 for camera on port 1 -+ cam1-ov9281 Select OV9281 for camera on port 1 -+ cam1-imx290-clk-freq Set clock frequency for an IMX290 on port 1 -+ cam2-imx219 Select IMX219 for camera on port 2 -+ cam2-imx258 Select IMX258 for camera on port 2 -+ cam2-imx290 Select IMX290 for camera on port 2 -+ cam2-imx477 Select IMX477 for camera on port 2 -+ cam2-ov2311 Select OV2311 for camera on port 2 -+ cam2-ov5647 Select OV5647 for camera on port 2 -+ cam2-ov7251 Select OV7251 for camera on port 2 -+ cam2-ov9281 Select OV9281 for camera on port 2 -+ cam2-imx290-clk-freq Set clock frequency for an IMX290 on port 2 -+ cam3-imx219 Select IMX219 for camera on port 3 -+ cam3-imx258 Select IMX258 for camera on port 3 -+ cam3-imx290 Select IMX290 for camera on port 3 -+ cam3-imx477 Select IMX477 for camera on port 3 -+ cam3-ov2311 Select OV2311 for camera on port 3 -+ cam3-ov5647 Select OV5647 for camera on port 3 -+ cam3-ov7251 Select OV7251 for camera on port 3 -+ cam3-ov9281 Select OV9281 for camera on port 3 -+ cam3-imx290-clk-freq Set clock frequency for an IMX290 on port 3 -+ -+ -+Name: cap1106 -+Info: Enables the ability to use the cap1106 touch sensor as a keyboard -+Load: dtoverlay=cap1106,= -+Params: int_pin GPIO pin for interrupt signal (default 23) -+ -+ -+Name: chipdip-dac -+Info: Configures Chip Dip audio cards. -+Load: dtoverlay=chipdip-dac -+Params: -+ -+ -+Name: cirrus-wm5102 -+Info: Configures the Cirrus Logic Audio Card -+Load: dtoverlay=cirrus-wm5102 -+Params: -+ -+ -+Name: cma -+Info: Set custom CMA sizes, only use if you know what you are doing, might -+ clash with other overlays like vc4-fkms-v3d and vc4-kms-v3d. -+Load: dtoverlay=cma,= -+Params: cma-512 CMA is 512MB (needs 1GB) -+ cma-448 CMA is 448MB (needs 1GB) -+ cma-384 CMA is 384MB (needs 1GB) -+ cma-320 CMA is 320MB (needs 1GB) -+ cma-256 CMA is 256MB (needs 1GB) -+ cma-192 CMA is 192MB (needs 1GB) -+ cma-128 CMA is 128MB -+ cma-96 CMA is 96MB -+ cma-64 CMA is 64MB -+ cma-size CMA size in bytes, 4MB aligned -+ cma-default Use upstream's default value -+ -+ -+Name: cutiepi-panel -+Info: 8" TFT LCD display and touch panel used by cutiepi.io -+Load: dtoverlay=cutiepi-panel -+Params: -+ -+ -+Name: dacberry400 -+Info: Configures the dacberry400 add on soundcard -+Load: dtoverlay=dacberry400 -+Params: -+ -+ -+Name: dht11 -+Info: Overlay for the DHT11/DHT21/DHT22 humidity/temperature sensors -+ Also sometimes found with the part number(s) AM230x. -+Load: dtoverlay=dht11,= -+Params: gpiopin GPIO connected to the sensor's DATA output. -+ (default 4) -+ -+ -+Name: dionaudio-kiwi -+Info: Configures the Dion Audio KIWI STREAMER -+Load: dtoverlay=dionaudio-kiwi -+Params: -+ -+ -+Name: dionaudio-loco -+Info: Configures the Dion Audio LOCO DAC-AMP -+Load: dtoverlay=dionaudio-loco -+Params: -+ -+ -+Name: dionaudio-loco-v2 -+Info: Configures the Dion Audio LOCO-V2 DAC-AMP -+Load: dtoverlay=dionaudio-loco-v2,= -+Params: 24db_digital_gain Allow gain to be applied via the PCM512x codec -+ Digital volume control. Enable with -+ "dtoverlay=hifiberry-dacplus,24db_digital_gain" -+ (The default behaviour is that the Digital -+ volume control is limited to a maximum of -+ 0dB. ie. it can attenuate but not provide -+ gain. For most users, this will be desired -+ as it will prevent clipping. By appending -+ the 24dB_digital_gain parameter, the Digital -+ volume control will allow up to 24dB of -+ gain. If this parameter is enabled, it is the -+ responsibility of the user to ensure that -+ the Digital volume control is set to a value -+ that does not result in clipping/distortion!) -+ -+ -+Name: disable-bt -+Info: Disable onboard Bluetooth on Pi 3B, 3B+, 3A+, 4B and Zero W, restoring -+ UART0/ttyAMA0 over GPIOs 14 & 15. -+ N.B. To disable the systemd service that initialises the modem so it -+ doesn't use the UART, use 'sudo systemctl disable hciuart'. -+Load: dtoverlay=disable-bt -+Params: -+ -+ -+Name: disable-wifi -+Info: Disable onboard WLAN on Pi 3B, 3B+, 3A+, 4B and Zero W. -+Load: dtoverlay=disable-wifi -+Params: -+ -+ -+Name: dpi18 -+Info: Overlay for a generic 18-bit DPI display -+ This uses GPIOs 0-21 (so no I2C, uart etc.), and activates the output -+ 2-3 seconds after the kernel has started. -+Load: dtoverlay=dpi18 -+Params: -+ -+ -+Name: dpi18cpadhi -+Info: Overlay for a generic 18-bit DPI display (in 'mode 6' connection scheme) -+ This uses GPIOs 0-9,12-17,20-25 (so no I2C, uart etc.), and activates -+ the output 3-3 seconds after the kernel has started. -+Load: dtoverlay=dpi18cpadhi -+Params: -+ -+ -+Name: dpi24 -+Info: Overlay for a generic 24-bit DPI display -+ This uses GPIOs 0-27 (so no I2C, uart etc.), and activates the output -+ 2-3 seconds after the kernel has started. -+Load: dtoverlay=dpi24 -+Params: -+ -+ -+Name: draws -+Info: Configures the NW Digital Radio DRAWS Hat -+ -+ The board includes an ADC to measure various board values and also -+ provides two analog user inputs on the expansion header. The ADC -+ can be configured for various sample rates and gain values to adjust -+ the input range. Tables describing the two parameters follow. -+ -+ ADC Gain Values: -+ 0 = +/- 6.144V -+ 1 = +/- 4.096V -+ 2 = +/- 2.048V -+ 3 = +/- 1.024V -+ 4 = +/- 0.512V -+ 5 = +/- 0.256V -+ 6 = +/- 0.256V -+ 7 = +/- 0.256V -+ -+ ADC Datarate Values: -+ 0 = 128sps -+ 1 = 250sps -+ 2 = 490sps -+ 3 = 920sps -+ 4 = 1600sps (default) -+ 5 = 2400sps -+ 6 = 3300sps -+ 7 = 3300sps -+Load: dtoverlay=draws,= -+Params: draws_adc_ch4_gain Sets the full scale resolution of the ADCs -+ input voltage sensor (default 1) -+ -+ draws_adc_ch4_datarate Sets the datarate of the ADCs input voltage -+ sensor -+ -+ draws_adc_ch5_gain Sets the full scale resolution of the ADCs -+ 5V rail voltage sensor (default 1) -+ -+ draws_adc_ch5_datarate Sets the datarate of the ADCs 4V rail voltage -+ sensor -+ -+ draws_adc_ch6_gain Sets the full scale resolution of the ADCs -+ AIN2 input (default 2) -+ -+ draws_adc_ch6_datarate Sets the datarate of the ADCs AIN2 input -+ -+ draws_adc_ch7_gain Sets the full scale resolution of the ADCs -+ AIN3 input (default 2) -+ -+ draws_adc_ch7_datarate Sets the datarate of the ADCs AIN3 input -+ -+ alsaname Name of the ALSA audio device (default "draws") -+ -+ -+Name: dwc-otg -+Info: Selects the dwc_otg USB controller driver which has fiq support. This -+ is the default on all except the Pi Zero which defaults to dwc2. -+Load: dtoverlay=dwc-otg -+Params: -+ -+ -+Name: dwc2 -+Info: Selects the dwc2 USB controller driver -+Load: dtoverlay=dwc2,= -+Params: dr_mode Dual role mode: "host", "peripheral" or "otg" -+ -+ g-rx-fifo-size Size of rx fifo size in gadget mode -+ -+ g-np-tx-fifo-size Size of non-periodic tx fifo size in gadget -+ mode -+ -+ -+[ The ds1307-rtc overlay has been deleted. See i2c-rtc. ] -+ -+ -+Name: edt-ft5406 -+Info: Overlay for the EDT FT5406 touchscreen on the CSI/DSI I2C interface. -+ This works with the Raspberry Pi 7" touchscreen when not being polled -+ by the firmware. -+ You MUST use either "disable_touchscreen=1" or "ignore_lcd=1" in -+ config.txt to stop the firmware polling the touchscreen. -+Load: dtoverlay=edt-ft5406,= -+Params: sizex Touchscreen size x (default 800) -+ sizey Touchscreen size y (default 480) -+ invx Touchscreen inverted x axis -+ invy Touchscreen inverted y axis -+ swapxy Touchscreen swapped x y axis -+ -+ -+Name: enc28j60 -+Info: Overlay for the Microchip ENC28J60 Ethernet Controller on SPI0 -+Load: dtoverlay=enc28j60,= -+Params: int_pin GPIO used for INT (default 25) -+ -+ speed SPI bus speed (default 12000000) -+ -+ -+Name: enc28j60-spi2 -+Info: Overlay for the Microchip ENC28J60 Ethernet Controller on SPI2 -+Load: dtoverlay=enc28j60-spi2,= -+Params: int_pin GPIO used for INT (default 39) -+ -+ speed SPI bus speed (default 12000000) -+ -+ -+Name: exc3000 -+Info: Enables I2C connected EETI EXC3000 multiple touch controller using -+ GPIO 4 (pin 7 on GPIO header) for interrupt. -+Load: dtoverlay=exc3000,= -+Params: interrupt GPIO used for interrupt (default 4) -+ sizex Touchscreen size x (default 4096) -+ sizey Touchscreen size y (default 4096) -+ invx Touchscreen inverted x axis -+ invy Touchscreen inverted y axis -+ swapxy Touchscreen swapped x y axis -+ -+ -+Name: fbtft -+Info: Overlay for SPI-connected displays using the fbtft drivers. -+ -+ This overlay seeks to replace the functionality provided by fbtft_device -+ which is now gone from the kernel. -+ -+ Most displays from fbtft_device have been ported over. -+ Example: -+ dtoverlay=fbtft,spi0-0,rpi-display,reset_pin=23,dc_pin=24,led_pin=18,rotate=270 -+ -+ It is also possible to specify the controller (this will use the default -+ init sequence in the driver). -+ Example: -+ dtoverlay=fbtft,spi0-0,ili9341,bgr,reset_pin=23,dc_pin=24,led_pin=18,rotate=270 -+ -+ For devices on spi1 or spi2, the interfaces should be enabled -+ with one of the spi1-1/2/3cs and/or spi2-1/2/3cs overlays. -+ -+ The following features of fbtft_device have not been ported over: -+ - parallel bus is not supported -+ - the init property which overrides the controller initialization -+ sequence is not supported as a parameter due to memory limitations in -+ the bootloader responsible for applying the overlay. -+ -+ See https://github.com/notro/fbtft/wiki/FBTFT-RPI-overlays for how to -+ create an overlay. -+ -+Load: dtoverlay=fbtft,= -+Params: -+ spi- Configure device at spi, cs -+ (boolean, required) -+ speed SPI bus speed in Hz (default 32000000) -+ cpha Shifted clock phase (CPHA) mode -+ cpol Inverse clock polarity (CPOL) mode -+ -+ adafruit18 Adafruit 1.8 -+ adafruit22 Adafruit 2.2 (old) -+ adafruit22a Adafruit 2.2 -+ adafruit28 Adafruit 2.8 -+ adafruit13m Adafruit 1.3 OLED -+ admatec_c-berry28 C-Berry28 -+ dogs102 EA DOGS102 -+ er_tftm050_2 ER-TFTM070-2 -+ er_tftm070_5 ER-TFTM070-5 -+ ew24ha0 EW24HA0 -+ ew24ha0_9bit EW24HA0 in 9-bit mode -+ freetronicsoled128 Freetronics OLED128 -+ hy28a HY28A -+ hy28b HY28B -+ itdb28_spi ITDB02-2.8 with SPI interface circuit -+ mi0283qt-2 Watterott MI0283QT-2 -+ mi0283qt-9a Watterott MI0283QT-9A -+ nokia3310 Nokia 3310 -+ nokia3310a Nokia 3310a -+ nokia5110 Nokia 5110 -+ piscreen PiScreen -+ pitft Adafruit PiTFT 2.8 -+ pioled ILSoft OLED -+ rpi-display Watterott rpi-display -+ sainsmart18 Sainsmart 1.8 -+ sainsmart32_spi Sainsmart 3.2 with SPI interfce circuit -+ tinylcd35 TinyLCD 3.5 -+ tm022hdh26 Tianma TM022HDH26 -+ tontec35_9481 Tontect 3.5 with ILI9481 controller -+ tontec35_9486 Tontect 3.5 with ILI9486 controller -+ waveshare32b Waveshare 3.2 -+ waveshare22 Waveshare 2.2 -+ -+ bd663474 BD663474 display controller -+ hx8340bn HX8340BN display controller -+ hx8347d HX8347D display controller -+ hx8353d HX8353D display controller -+ hx8357d HX8357D display controller -+ ili9163 ILI9163 display controller -+ ili9320 ILI9320 display controller -+ ili9325 ILI9325 display controller -+ ili9340 ILI9340 display controller -+ ili9341 ILI9341 display controller -+ ili9481 ILI9481 display controller -+ ili9486 ILI9486 display controller -+ pcd8544 PCD8544 display controller -+ ra8875 RA8875 display controller -+ s6d02a1 S6D02A1 display controller -+ s6d1121 S6D1121 display controller -+ seps525 SEPS525 display controller -+ sh1106 SH1106 display controller -+ ssd1289 SSD1289 display controller -+ ssd1305 SSD1305 display controller -+ ssd1306 SSD1306 display controller -+ ssd1325 SSD1325 display controller -+ ssd1331 SSD1331 display controller -+ ssd1351 SSD1351 display controller -+ st7735r ST7735R display controller -+ st7789v ST7789V display controller -+ tls8204 TLS8204 display controller -+ uc1611 UC1611 display controller -+ uc1701 UC1701 display controller -+ upd161704 UPD161704 display controller -+ -+ width Display width in pixels -+ height Display height in pixels -+ regwidth Display controller register width (default is -+ driver specific) -+ buswidth Display bus interface width (default 8) -+ debug Debug output level {0-7} -+ rotate Display rotation {0, 90, 180, 270} (counter -+ clockwise). Not supported by all drivers. -+ bgr Enable BGR mode (default off). Use if Red and -+ Blue are swapped. Not supported by all drivers. -+ fps Frames per second (default 30). In effect this -+ states how long the driver will wait after video -+ memory has been changed until display update -+ transfer is started. -+ txbuflen Length of the FBTFT transmit buffer -+ (default 4096) -+ startbyte Sets the Start byte used by fb_ili9320, -+ fb_ili9325 and fb_hx8347d. Common value is 0x70. -+ gamma String representation of Gamma Curve(s). Driver -+ specific. Not supported by all drivers. -+ reset_pin GPIO pin for RESET -+ dc_pin GPIO pin for D/C -+ led_pin GPIO pin for LED backlight -+ -+ -+Name: fe-pi-audio -+Info: Configures the Fe-Pi Audio Sound Card -+Load: dtoverlay=fe-pi-audio -+Params: -+ -+ -+Name: fsm-demo -+Info: A demonstration of the gpio-fsm driver. The GPIOs are chosen to work -+ nicely with a "traffic-light" display of red, amber and green LEDs on -+ GPIOs 7, 8 and 25 respectively. -+Load: dtoverlay=fsm-demo,= -+Params: fsm_debug Enable debug logging (default off) -+ -+ -+Name: gc9a01 -+Info: Enables GalaxyCore's GC9A01 single chip driver based displays on -+ SPI0 as fb1, using GPIOs DC=25, RST=27 and BL=18 (physical -+ GPIO header pins 22, 13 and 12 respectively) in addition to the -+ SPI0 pins DIN=10, CLK=11 and CS=8 (physical GPIO header pins 19, -+ 23 and 24 respectively). -+Load: dtoverlay=gc9a01,= -+Params: speed Display SPI bus speed -+ -+ rotate Display rotation {0,90,180,270} -+ -+ width Width of the display -+ -+ height Height of the display -+ -+ fps Delay between frame updates -+ -+ debug Debug output level {0-7} -+ -+ -+Name: ghost-amp -+Info: An overlay for the Ghost amplifier. -+Load: dtoverlay=ghost-amp,= -+Params: fsm_debug Enable debug logging of the GPIO FSM (default -+ off) -+ -+ -+Name: goodix -+Info: Enables I2C connected Goodix gt9271 multiple touch controller using -+ GPIOs 4 and 17 (pins 7 and 11 on GPIO header) for interrupt and reset. -+Load: dtoverlay=goodix,= -+Params: interrupt GPIO used for interrupt (default 4) -+ reset GPIO used for reset (default 17) -+ -+ -+Name: googlevoicehat-soundcard -+Info: Configures the Google voiceHAT soundcard -+Load: dtoverlay=googlevoicehat-soundcard -+Params: -+ -+ -+Name: gpio-fan -+Info: Configure a GPIO pin to control a cooling fan. -+Load: dtoverlay=gpio-fan,= -+Params: gpiopin GPIO used to control the fan (default 12) -+ temp Temperature at which the fan switches on, in -+ millicelcius (default 55000) -+ hyst Temperature delta (in millicelcius) below -+ temp at which the fan will drop to minrpm -+ (default 10000) -+ -+ -+Name: gpio-hog -+Info: Activate a "hog" for a GPIO - request that the kernel configures it as -+ an output, driven low or high as indicated by the presence or absence -+ of the active_low parameter. Note that a hogged GPIO is not available -+ to other drivers or for gpioset/gpioget. -+Load: dtoverlay=gpio-hog,= -+Params: gpio GPIO pin to hog (default 26) -+ active_low If set, the hog drives the GPIO low (defaults -+ to off - the GPIO is driven high) -+ -+ -+Name: gpio-ir -+Info: Use GPIO pin as rc-core style infrared receiver input. The rc-core- -+ based gpio_ir_recv driver maps received keys directly to a -+ /dev/input/event* device, all decoding is done by the kernel - LIRC is -+ not required! The key mapping and other decoding parameters can be -+ configured by "ir-keytable" tool. -+Load: dtoverlay=gpio-ir,= -+Params: gpio_pin Input pin number. Default is 18. -+ -+ gpio_pull Desired pull-up/down state (off, down, up) -+ Default is "up". -+ -+ invert "1" = invert the input (active-low signalling). -+ "0" = non-inverted input (active-high -+ signalling). Default is "1". -+ -+ rc-map-name Default rc keymap (can also be changed by -+ ir-keytable), defaults to "rc-rc6-mce" -+ -+ -+Name: gpio-ir-tx -+Info: Use GPIO pin as bit-banged infrared transmitter output. -+ This is an alternative to "pwm-ir-tx". gpio-ir-tx doesn't require -+ a PWM so it can be used together with onboard analog audio. -+Load: dtoverlay=gpio-ir-tx,= -+Params: gpio_pin Output GPIO (default 18) -+ -+ invert "1" = invert the output (make it active-low). -+ Default is "0" (active-high). -+ -+ -+Name: gpio-key -+Info: This is a generic overlay for activating GPIO keypresses using -+ the gpio-keys library and this dtoverlay. Multiple keys can be -+ set up using multiple calls to the overlay for configuring -+ additional buttons or joysticks. You can see available keycodes -+ at https://github.com/torvalds/linux/blob/v4.12/include/uapi/ -+ linux/input-event-codes.h#L64 -+Load: dtoverlay=gpio-key,= -+Params: gpio GPIO pin to trigger on (default 3) -+ active_low When this is 1 (active low), a falling -+ edge generates a key down event and a -+ rising edge generates a key up event. -+ When this is 0 (active high), this is -+ reversed. The default is 1 (active low) -+ gpio_pull Desired pull-up/down state (off, down, up) -+ Default is "up". Note that the default pin -+ (GPIO3) has an external pullup -+ label Set a label for the key -+ keycode Set the key code for the button -+ -+ -+ -+Name: gpio-led -+Info: This is a generic overlay for activating LEDs (or any other component) -+ by a GPIO pin. Multiple LEDs can be set up using multiple calls to the -+ overlay. While there are many existing methods to activate LEDs on the -+ RPi, this method offers some advantages: -+ 1) Does not require any userspace programs. -+ 2) LEDs can be connected to the kernel's led-trigger framework, -+ and drive the LED based on triggers such as cpu load, heartbeat, -+ kernel panic, key input, timers and others. -+ 3) LED can be tied to the input state of another GPIO pin. -+ 4) The LED is setup early during the kernel boot process (useful -+ for cpu/heartbeat/panic triggers). -+ -+ Typical electrical connection is: -+ RPI-GPIO.19 -> LED -> 300ohm resister -> RPI-GND -+ The GPIO pin number can be changed with the 'gpio=' parameter. -+ -+ To control an LED from userspace, write a 0 or 1 value: -+ echo 1 > /sys/class/leds/myled1/brightness -+ The 'myled1' name can be changed with the 'label=' parameter. -+ -+ To connect the LED to a kernel trigger from userspace: -+ echo cpu > /sys/class/leds/myled1/trigger -+ echo heartbeat > /sys/class/leds/myled1/trigger -+ echo none > /sys/class/leds/myled1/trigger -+ To connect the LED to GPIO.26 pin (physical pin 37): -+ echo gpio > /sys/class/leds/myled1/trigger -+ echo 26 > /sys/class/leds/myled1/gpio -+ Available triggers: -+ cat /sys/class/leds/myled1/trigger -+ -+ More information about the Linux kernel LED/Trigger system: -+ https://www.kernel.org/doc/Documentation/leds/leds-class.rst -+ https://www.kernel.org/doc/Documentation/leds/ledtrig-oneshot.rst -+Load: dtoverlay=gpio-led,= -+Params: gpio GPIO pin connected to the LED (default 19) -+ label The label for this LED. It will appear under -+ /sys/class/leds/