From 64df6fed3749d2b8c4de2712813df8f1dd049986 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Wed, 8 Mar 2023 15:28:19 +0000 Subject: [PATCH 001/688] workflows: We all love checkpatch, so add it to the CI workflows This is currently running on defaults, so the --strict desired for media drivers and similar won't be observed. That may be possible to add later. Signed-off-by: Dave Stevenson .github: Add Github Workflow for KUnit Now that we have some KUnit coverage, let's add a github actions file to run them on each push or pull request. Signed-off-by: Maxime Ripard .github/workflows: Add dtoverlaycheck workflow Signed-off-by: Dave Stevenson .github/workflows: Create workflow to CI kernel builds Builds the bcmrpi, bcm2709, bcm2711, and bcm2835 32 bit kernels, and defconfig and bcm2711 64bit kernels, saving the artifacts for 7 days. Signed-off-by: Dave Stevenson .github: Skip broken Generic DRM/KMS Unit Tests Signed-off-by: Phil Elwell .github/workflows: Set warnings-as-errors for builds To avoid code with build warnings being introduced into the tree, force CONFIG_WERROR=y in the build workflow. Signed-off-by: Phil Elwell .github/workflows: Correct kernel builds artifacts Modify the kernel build workflow to create artifacts with the correct names and structure, both as an example of what we expect and in case anyone wants to use the output. Signed-off-by: Phil Elwell .github/workflows: Switch to a matrix build Remove the per-build duplication by putting build parameters in a matrix. Signed-off-by: Phil Elwell .github/workflows: Retain artifacts for 90 days Signed-off-by: Phil Elwell .github/workflows: Add a bcm2712 build configuration Signed-off-by: Phil Elwell Update kernel-build.yml to use node.js 20 Upgrade the actions to v4 to get rid of the warning about migrating from node.js 16. Update kunit.yml to use node.js 20 Bump actions/checkout to v4. Update dtoverlaycheck.yml to node.js 20 .github/workflows: More jobs for kernel builds Using the "cores * 1.5" heuristic, configure the kernel builds for the 4-core GitHub-hosted runners. Signed-off-by: Phil Elwell --- .github/workflows/checkpatch.yml | 18 +++++ .github/workflows/ci_checkpatch.conf | 4 + .github/workflows/dtoverlaycheck.yml | 48 ++++++++++++ .github/workflows/kernel-build.yml | 108 +++++++++++++++++++++++++++ .github/workflows/kunit.yml | 57 ++++++++++++++ 5 files changed, 235 insertions(+) create mode 100644 .github/workflows/checkpatch.yml create mode 100644 .github/workflows/ci_checkpatch.conf create mode 100644 .github/workflows/dtoverlaycheck.yml create mode 100644 .github/workflows/kernel-build.yml create mode 100644 .github/workflows/kunit.yml diff --git a/.github/workflows/checkpatch.yml b/.github/workflows/checkpatch.yml new file mode 100644 index 00000000000000..c214226654dc1b --- /dev/null +++ b/.github/workflows/checkpatch.yml @@ -0,0 +1,18 @@ +name: Advisory checkpatch review +on: [pull_request] + +jobs: + review: + name: checkpatch review + runs-on: ubuntu-latest + steps: + - name: 'Calculate PR commits + 1' + run: echo "PR_FETCH_DEPTH=$(( ${{ github.event.pull_request.commits }} + 1 ))" >> $GITHUB_ENV + - uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha }} + fetch-depth: ${{ env.PR_FETCH_DEPTH }} + - name: Copy checkpatch.conf + run: cp ${{github.workspace}}/.github/workflows/ci_checkpatch.conf ${{github.workspace}}/.checkpatch.conf + - name: Run checkpatch review + uses: webispy/checkpatch-action@v9 diff --git a/.github/workflows/ci_checkpatch.conf b/.github/workflows/ci_checkpatch.conf new file mode 100644 index 00000000000000..5d79c37b1d8c40 --- /dev/null +++ b/.github/workflows/ci_checkpatch.conf @@ -0,0 +1,4 @@ +--no-tree +--ignore FILE_PATH_CHANGES +--ignore GIT_COMMIT_ID +--ignore SPDX_LICENSE_TAG diff --git a/.github/workflows/dtoverlaycheck.yml b/.github/workflows/dtoverlaycheck.yml new file mode 100644 index 00000000000000..3d96814fe19f21 --- /dev/null +++ b/.github/workflows/dtoverlaycheck.yml @@ -0,0 +1,48 @@ +name: Pi dtoverlay checks + +on: + pull_request: + paths-ignore: + - '.github/**' + branches: [ "rpi-*" ] + push: + paths-ignore: + - '.github/**' + branches: [ "rpi-*" ] + workflow_dispatch: + +env: + UTILS_DIR: "${{github.workspace}}/utils" + +jobs: + dtoverlaycheck: + runs-on: ubuntu-latest + + steps: + - name: Install toolchain + run: | + sudo apt update + sudo apt-get install gcc-arm-linux-gnueabihf libfdt-dev device-tree-compiler + timeout-minutes: 10 + + - uses: actions/checkout@v4 + with: + fetch-depth: 1 + clean: true + + - name: overlaycheck + run: | + git clone https://github.com/raspberrypi/utils ${{env.UTILS_DIR}} + cd ${{env.UTILS_DIR}} + pwd + mkdir build + cd build + pwd + cmake .. + make -j4 + sudo make install + cd ${{github.workspace}} + pwd + make ARCH=arm KERNEL=kernel CROSS_COMPILE=arm-linux-gnueabihf- bcm2711_defconfig + make ARCH=arm KERNEL=kernel CROSS_COMPILE=arm-linux-gnueabihf- dtbs + ${{env.UTILS_DIR}}/overlaycheck/overlaycheck diff --git a/.github/workflows/kernel-build.yml b/.github/workflows/kernel-build.yml new file mode 100644 index 00000000000000..bc16fb8420f9db --- /dev/null +++ b/.github/workflows/kernel-build.yml @@ -0,0 +1,108 @@ +name: Pi kernel build tests + +on: + pull_request: + paths-ignore: + - '.github/**' + branches: [ "rpi-*" ] + push: + paths-ignore: + - '.github/**' + branches: [ "rpi-*" ] + workflow_dispatch: + +env: + NUM_JOBS: 6 + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + include: + - name: bcm2835 + arch: arm + defconfig: bcm2835_defconfig + kernel: kernel + + - name: arm64 + arch: arm64 + defconfig: defconfig + kernel: kernel8 + + - name: bcmrpi + arch: arm + defconfig: bcmrpi_defconfig + kernel: kernel + + - name: bcm2709 + arch: arm + defconfig: bcm2709_defconfig + kernel: kernel7 + + - name: bcm2711 + arch: arm + defconfig: bcm2711_defconfig + kernel: kernel7l + + - name: bcm2711_arm64 + arch: arm64 + defconfig: bcm2711_defconfig + kernel: kernel8 + + - name: bcm2712 + arch: arm64 + defconfig: bcm2712_defconfig + kernel: kernel_2712 + + steps: + - name: Update install + run: + sudo apt-get update + + - name: Install toolchain + run: + if [[ "${{matrix.arch}}" == "arm64" ]]; then + sudo apt-get install gcc-aarch64-linux-gnu; + else + sudo apt-get install gcc-arm-linux-gnueabihf; + fi + timeout-minutes: 5 + + - uses: actions/checkout@v4 + with: + fetch-depth: 1 + clean: true + + - name: Build kernel ${{matrix.name}} + run: | + mkdir ${{github.workspace}}/build + export ARCH=${{matrix.arch}} + if [[ "$ARCH" == "arm64" ]]; then + export CROSS_COMPILE=aarch64-linux-gnu- + export DTS_SUBDIR=broadcom + export IMAGE=Image.gz + else + export CROSS_COMPILE=arm-linux-gnueabihf- + export DTS_SUBDIR=broadcom + export IMAGE=zImage + fi + make O=${{github.workspace}}/build ${{matrix.defconfig}} + scripts/config --file ${{github.workspace}}/build/.config --set-val CONFIG_WERROR y + make O=${{github.workspace}}/build -j ${{env.NUM_JOBS}} $IMAGE modules dtbs + mkdir -p ${{github.workspace}}/install/boot/overlays + make O=${{github.workspace}}/build INSTALL_MOD_PATH=${{github.workspace}}/install modules_install + cp ${{github.workspace}}/build/arch/${ARCH}/boot/dts/${DTS_SUBDIR}/*.dtb ${{github.workspace}}/install/boot/ + cp ${{github.workspace}}/build/arch/${ARCH}/boot/dts/overlays/*.dtb* ${{github.workspace}}/install/boot/overlays/ + cp ${{github.workspace}}/arch/${ARCH}/boot/dts/overlays/README ${{github.workspace}}/install/boot/overlays/ + cp ${{github.workspace}}/build/arch/${ARCH}/boot/$IMAGE ${{github.workspace}}/install/boot/${{matrix.kernel}}.img + + - name: Tar build + run: tar -cvf ${{matrix.name}}_build.tar -C ${{github.workspace}}/install . + + - name: Upload results + uses: actions/upload-artifact@v4 + with: + name: ${{matrix.name}}_build + path: ${{matrix.name}}_build.tar + retention-days: 90 diff --git a/.github/workflows/kunit.yml b/.github/workflows/kunit.yml new file mode 100644 index 00000000000000..5713297d757141 --- /dev/null +++ b/.github/workflows/kunit.yml @@ -0,0 +1,57 @@ +name: KUnit Tests + +on: + pull_request: + branches: [ "rpi-*"] + + push: + branches: [ "rpi-*"] + +jobs: + core: + name: Generic DRM/KMS Unit Tests + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Run Generic DRM Tests + run: | + echo Skipping ./tools/testing/kunit/kunit.py run \ + --kunitconfig=drivers/gpu/drm/tests + + vc4-arm: + name: VC4 Unit Tests on ARM + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Install Dependencies + run: | + sudo apt-get update + sudo apt-get install -y gcc-arm-linux-gnueabihf qemu-system-arm + + - name: Run VC4 Tests + run: | + ./tools/testing/kunit/kunit.py run \ + --kunitconfig=drivers/gpu/drm/vc4/tests \ + --cross_compile=arm-linux-gnueabihf- --arch=arm + + vc4-arm64: + name: VC4 Unit Tests on ARM64 + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Install Dependencies + run: | + sudo apt-get update + sudo apt-get install -y gcc-aarch64-linux-gnu qemu-system-arm + + - name: Run VC4 Tests + run: | + ./tools/testing/kunit/kunit.py run \ + --kunitconfig=drivers/gpu/drm/vc4/tests \ + --cross_compile=aarch64-linux-gnu- --arch=arm64 From e098f7b6cbe79917e8164fda1c83d4c6e5494703 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Mon, 14 Nov 2022 17:14:15 +0000 Subject: [PATCH 002/688] README: Add README.md with CI kernel build status tags This is a copy of README with the tags added. You can not delete the file README as then checkpatch complains you aren't in a kernel tree. Signed-off-by: Dave Stevenson README: Show rpi-6.5.y build status Signed-off-by: Phil Elwell README: show rpi-6.6.y build status Replace rpi-6.5.y with rpi-6.6.y in the build status list. --- README.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000000000..e33ba1b6c9501f --- /dev/null +++ b/README.md @@ -0,0 +1,30 @@ +Linux kernel +============ + +There are several guides for kernel developers and users. These guides can +be rendered in a number of formats, like HTML and PDF. Please read +Documentation/admin-guide/README.rst first. + +In order to build the documentation, use ``make htmldocs`` or +``make pdfdocs``. The formatted documentation can also be read online at: + + https://www.kernel.org/doc/html/latest/ + +There are various text files in the Documentation/ subdirectory, +several of them using the Restructured Text markup notation. + +Please read the Documentation/process/changes.rst file, as it contains the +requirements for building and running the kernel, and information about +the problems which may result by upgrading your kernel. + +Build status for rpi-5.15.y: +[![Pi kernel build tests](https://github.com/raspberrypi/linux/actions/workflows/kernel-build.yml/badge.svg?branch=rpi-5.15.y)](https://github.com/raspberrypi/linux/actions/workflows/kernel-build.yml) +[![dtoverlaycheck](https://github.com/raspberrypi/linux/actions/workflows/dtoverlaycheck.yml/badge.svg?branch=rpi-5.15.y)](https://github.com/raspberrypi/linux/actions/workflows/dtoverlaycheck.yml) + +Build status for rpi-6.1.y: +[![Pi kernel build tests](https://github.com/raspberrypi/linux/actions/workflows/kernel-build.yml/badge.svg?branch=rpi-6.1.y)](https://github.com/raspberrypi/linux/actions/workflows/kernel-build.yml) +[![dtoverlaycheck](https://github.com/raspberrypi/linux/actions/workflows/dtoverlaycheck.yml/badge.svg?branch=rpi-6.1.y)](https://github.com/raspberrypi/linux/actions/workflows/dtoverlaycheck.yml) + +Build status for rpi-6.6.y: +[![Pi kernel build tests](https://github.com/raspberrypi/linux/actions/workflows/kernel-build.yml/badge.svg?branch=rpi-6.6.y)](https://github.com/raspberrypi/linux/actions/workflows/kernel-build.yml) +[![dtoverlaycheck](https://github.com/raspberrypi/linux/actions/workflows/dtoverlaycheck.yml/badge.svg?branch=rpi-6.6.y)](https://github.com/raspberrypi/linux/actions/workflows/dtoverlaycheck.yml) From d687212c4ac3ce63ba8e74b2893fd137ed74a0af Mon Sep 17 00:00:00 2001 From: Andreas Blaesius Date: Wed, 5 Jan 2022 20:38:39 +0100 Subject: [PATCH 003/688] Use GitHubs issue form for bug reports Use GitHubs issue form for bug reports. - modern look - user don't need to mess with given markdown parts while filling the issue template Setup config.yml for general questions and problems with the Raspbian distribution packages. Update issue templates (#2736) Adding Pi 5 as a device to bug_report.yml --- .github/ISSUE_TEMPLATE/bug_report.yml | 92 +++++++++++++++++++++++++++ .github/ISSUE_TEMPLATE/config.yml | 9 +++ 2 files changed, 101 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.yml create mode 100644 .github/ISSUE_TEMPLATE/config.yml diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 00000000000000..54e6d5380d7fb1 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,92 @@ +name: "Bug report" +description: Create a report to help us fix your issue +body: +- type: markdown + attributes: + value: | + **Is this the right place for my bug report?** + This repository contains the Linux kernel used on the Raspberry Pi. + If you believe that the issue you are seeing is kernel-related, this is the right place. + If not, we have other repositories for the GPU firmware at [github.com/raspberrypi/firmware](https://github.com/raspberrypi/firmware) and Raspberry Pi userland applications at [github.com/raspberrypi/userland](https://github.com/raspberrypi/userland). + + If you have problems with the Raspbian distribution packages, report them in the [github.com/RPi-Distro/repo](https://github.com/RPi-Distro/repo). + If you simply have a question, then [the Raspberry Pi forums](https://www.raspberrypi.org/forums) are the best place to ask it. + +- type: textarea + id: description + attributes: + label: Describe the bug + description: | + Add a clear and concise description of what you think the bug is. + validations: + required: true + +- type: textarea + id: reproduce + attributes: + label: Steps to reproduce the behaviour + description: | + List the steps required to reproduce the issue. + validations: + required: true + +- type: dropdown + id: model + attributes: + label: Device (s) + description: On which device you are facing the bug? + multiple: true + options: + - Raspberry Pi Zero + - Raspberry Pi Zero W / WH + - Raspberry Pi Zero 2 W + - Raspberry Pi 1 Mod. A + - Raspberry Pi 1 Mod. A+ + - Raspberry Pi 1 Mod. B + - Raspberry Pi 1 Mod. B+ + - Raspberry Pi 2 Mod. B + - Raspberry Pi 2 Mod. B v1.2 + - Raspberry Pi 3 Mod. A+ + - Raspberry Pi 3 Mod. B + - Raspberry Pi 3 Mod. B+ + - Raspberry Pi 4 Mod. B + - Raspberry Pi 400 + - Raspberry Pi 5 + - Raspberry Pi CM1 + - Raspberry Pi CM3 + - Raspberry Pi CM3 Lite + - Raspberry Pi CM3+ + - Raspberry Pi CM3+ Lite + - Raspberry Pi CM4 + - Raspberry Pi CM4 Lite + - Other + validations: + required: true + +- type: textarea + id: system + attributes: + label: System + description: | + Copy and paste the results of the raspinfo command in to this section. + Alternatively, copy and paste a pastebin link, or add answers to the following questions: + * Which OS and version (`cat /etc/rpi-issue`)? + * Which firmware version (`vcgencmd version`)? + * Which kernel version (`uname -a`)? + validations: + required: true + +- type: textarea + id: logs + attributes: + label: Logs + description: | + If applicable, add the relevant output from `dmesg` or similar. + +- type: textarea + id: additional + attributes: + label: Additional context + description: | + Add any other relevant context for the problem. + diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 00000000000000..338282d8eb4620 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,9 @@ +blank_issues_enabled: false +contact_links: + - name: "⛔ Question" + url: https://www.raspberrypi.org/forums + about: "Please do not use GitHub for asking questions. If you simply have a question, then the Raspberry Pi forums are the best place to ask it. Thanks in advance for helping us keep the issue tracker clean!" + - name: "⛔ Problems with the Raspbian distribution packages" + url: https://github.com/RPi-Distro/repo + about: "If you have problems with the Raspbian distribution packages, please report them in the github.com/RPi-Distro/repo." + From 078e1e53e4bddbfa02cd87823d5754b8cc5027c5 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 20 Apr 2020 13:41:10 +0100 Subject: [PATCH 004/688] Revert "spi: spidev: Fix CS polarity if GPIO descriptors are used" This reverts commit 83b2a8fe43bda0c11981ad6afa5dd0104d78be28. --- drivers/spi/spidev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c index 653f82984216c3..45dfec4d5a174a 100644 --- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c @@ -428,7 +428,7 @@ spidev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) } if (ctlr->use_gpio_descriptors && spi_get_csgpiod(spi, 0)) - tmp |= SPI_CS_HIGH; + { /*tmp |= SPI_CS_HIGH;*/ } tmp |= spi->mode & ~SPI_MODE_MASK; spi->mode = tmp & SPI_MODE_USER_MASK; From 64bc802c5ec5487bfe61a863c3a4f69c9f7cdd0d Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 7 Mar 2022 16:18:55 +0000 Subject: [PATCH 005/688] Revert "net: bcmgenet: Request APD, DLL disable and IDDQ-SR" This reverts commit c3a4c69360ab43560f212eed326c9d8bde35b14c, which broke rebooting when network booting. See: https://github.com/raspberrypi/rpi-eeprom/issues/417 Signed-off-by: Phil Elwell --- drivers/net/ethernet/broadcom/genet/bcmmii.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/net/ethernet/broadcom/genet/bcmmii.c b/drivers/net/ethernet/broadcom/genet/bcmmii.c index c4a3698cef66f6..ca00c657a9f362 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmmii.c +++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c @@ -304,9 +304,7 @@ int bcmgenet_mii_probe(struct net_device *dev) struct device_node *dn = kdev->of_node; phy_interface_t phy_iface = priv->phy_interface; struct phy_device *phydev; - u32 phy_flags = PHY_BRCM_AUTO_PWRDWN_ENABLE | - PHY_BRCM_DIS_TXCRXC_NOENRGY | - PHY_BRCM_IDDQ_SUSPEND; + u32 phy_flags = 0; int ret; /* Communicate the integrated PHY revision */ From 3eb776e33d09e5d23a366b7c9420da1ddb762c04 Mon Sep 17 00:00:00 2001 From: Dom Cobley Date: Mon, 31 Jul 2023 13:47:10 +0100 Subject: [PATCH 006/688] Revert "Revert "xhci: add quirk for host controllers that don't update endpoint DCS"" This reverts commit 5bef4b3cb95a5b883dfec8b3ffc0d671323d55bb. We don't agree with upstream revert so undo it. --- drivers/usb/host/xhci-pci.c | 4 +++- drivers/usb/host/xhci-ring.c | 23 ++++++++++++++++++++++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index cb07cee9ed0c75..f0ec8022c3be71 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -426,8 +426,10 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) pdev->device == 0x3432) xhci->quirks |= XHCI_BROKEN_STREAMS; - if (pdev->vendor == PCI_VENDOR_ID_VIA && pdev->device == 0x3483) + if (pdev->vendor == PCI_VENDOR_ID_VIA && pdev->device == 0x3483) { xhci->quirks |= XHCI_LPM_SUPPORT; + xhci->quirks |= XHCI_EP_CTX_BROKEN_DCS; + } if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA && pdev->device == PCI_DEVICE_ID_ASMEDIA_1042_XHCI) { diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 928b93ad1ee866..040356d64cabf8 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -636,8 +636,11 @@ static int xhci_move_dequeue_past_td(struct xhci_hcd *xhci, struct xhci_ring *ep_ring; struct xhci_command *cmd; struct xhci_segment *new_seg; + struct xhci_segment *halted_seg = NULL; union xhci_trb *new_deq; int new_cycle; + union xhci_trb *halted_trb; + int index = 0; dma_addr_t addr; u64 hw_dequeue; bool cycle_found = false; @@ -656,7 +659,25 @@ static int xhci_move_dequeue_past_td(struct xhci_hcd *xhci, hw_dequeue = xhci_get_hw_deq(xhci, dev, ep_index, stream_id); new_seg = ep_ring->deq_seg; new_deq = ep_ring->dequeue; - new_cycle = hw_dequeue & 0x1; + + /* + * Quirk: xHC write-back of the DCS field in the hardware dequeue + * pointer is wrong - use the cycle state of the TRB pointed to by + * the dequeue pointer. + */ + if (xhci->quirks & XHCI_EP_CTX_BROKEN_DCS && + !(ep->ep_state & EP_HAS_STREAMS)) + halted_seg = trb_in_td(xhci, td, hw_dequeue & ~0xf, false); + if (halted_seg) { + index = ((dma_addr_t)(hw_dequeue & ~0xf) - halted_seg->dma) / + sizeof(*halted_trb); + halted_trb = &halted_seg->trbs[index]; + new_cycle = halted_trb->generic.field[3] & 0x1; + xhci_dbg(xhci, "Endpoint DCS = %d TRB index = %d cycle = %d\n", + (u8)(hw_dequeue & 0x1), index, new_cycle); + } else { + new_cycle = hw_dequeue & 0x1; + } /* * We want to find the pointer, segment and cycle state of the new trb From 33653958b62317cec0bd02496a37720d1af879ac Mon Sep 17 00:00:00 2001 From: Dom Cobley Date: Fri, 2 Feb 2024 13:04:00 +0000 Subject: [PATCH 007/688] Revert "PCI: brcmstb: Configure HW CLKREQ# mode appropriate for downstream device" This reverts commit e2596dcf1e9dfd5904d50f796c19b03c94a3b8b4. --- drivers/pci/controller/pcie-brcmstb.c | 100 +++----------------------- 1 file changed, 10 insertions(+), 90 deletions(-) diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c index 9321280f6edbab..40145a4d7a7e13 100644 --- a/drivers/pci/controller/pcie-brcmstb.c +++ b/drivers/pci/controller/pcie-brcmstb.c @@ -48,9 +48,6 @@ #define PCIE_RC_CFG_PRIV1_LINK_CAPABILITY 0x04dc #define PCIE_RC_CFG_PRIV1_LINK_CAPABILITY_ASPM_SUPPORT_MASK 0xc00 -#define PCIE_RC_CFG_PRIV1_ROOT_CAP 0x4f8 -#define PCIE_RC_CFG_PRIV1_ROOT_CAP_L1SS_MODE_MASK 0xf8 - #define PCIE_RC_DL_MDIO_ADDR 0x1100 #define PCIE_RC_DL_MDIO_WR_DATA 0x1104 #define PCIE_RC_DL_MDIO_RD_DATA 0x1108 @@ -127,12 +124,9 @@ PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI + ((win) * 8) #define PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_MASK 0x2 -#define PCIE_MISC_HARD_PCIE_HARD_DEBUG_L1SS_ENABLE_MASK 0x200000 #define PCIE_MISC_HARD_PCIE_HARD_DEBUG_SERDES_IDDQ_MASK 0x08000000 #define PCIE_BMIPS_MISC_HARD_PCIE_HARD_DEBUG_SERDES_IDDQ_MASK 0x00800000 -#define PCIE_CLKREQ_MASK \ - (PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_MASK | \ - PCIE_MISC_HARD_PCIE_HARD_DEBUG_L1SS_ENABLE_MASK) + #define PCIE_MISC_UBUS_BAR1_CONFIG_REMAP 0x40ac #define PCIE_MISC_UBUS_BAR1_CONFIG_REMAP_ACCESS_EN_MASK BIT(0) @@ -1187,93 +1181,13 @@ static int brcm_pcie_setup(struct brcm_pcie *pcie) return 0; } -/* - * This extends the timeout period for an access to an internal bus. This - * access timeout may occur during L1SS sleep periods, even without the - * presence of a PCIe access. - */ -static void brcm_extend_rbus_timeout(struct brcm_pcie *pcie) -{ - /* TIMEOUT register is two registers before RGR1_SW_INIT_1 */ - const unsigned int REG_OFFSET = PCIE_RGR1_SW_INIT_1(pcie) - 8; - u32 timeout_us = 4000000; /* 4 seconds, our setting for L1SS */ - - /* 7712 does not have this (RGR1) timer */ - if (pcie->soc_base == BCM7712) - return; - - /* Each unit in timeout register is 1/216,000,000 seconds */ - writel(216 * timeout_us, pcie->base + REG_OFFSET); -} - -static void brcm_config_clkreq(struct brcm_pcie *pcie) -{ - static const char err_msg[] = "invalid 'brcm,clkreq-mode' DT string\n"; - const char *mode = "default"; - u32 clkreq_cntl; - int ret, tmp; - - ret = of_property_read_string(pcie->np, "brcm,clkreq-mode", &mode); - if (ret && ret != -EINVAL) { - dev_err(pcie->dev, err_msg); - mode = "safe"; - } - - /* Start out assuming safe mode (both mode bits cleared) */ - clkreq_cntl = readl(pcie->base + HARD_DEBUG(pcie)); - clkreq_cntl &= ~PCIE_CLKREQ_MASK; - - if (strcmp(mode, "no-l1ss") == 0) { - /* - * "no-l1ss" -- Provides Clock Power Management, L0s, and - * L1, but cannot provide L1 substate (L1SS) power - * savings. If the downstream device connected to the RC is - * L1SS capable AND the OS enables L1SS, all PCIe traffic - * may abruptly halt, potentially hanging the system. - */ - clkreq_cntl |= PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_MASK; - /* - * We want to un-advertise L1 substates because if the OS - * tries to configure the controller into using L1 substate - * power savings it may fail or hang when the RC HW is in - * "no-l1ss" mode. - */ - tmp = readl(pcie->base + PCIE_RC_CFG_PRIV1_ROOT_CAP); - u32p_replace_bits(&tmp, 2, PCIE_RC_CFG_PRIV1_ROOT_CAP_L1SS_MODE_MASK); - writel(tmp, pcie->base + PCIE_RC_CFG_PRIV1_ROOT_CAP); - - } else if (strcmp(mode, "default") == 0) { - /* - * "default" -- Provides L0s, L1, and L1SS, but not - * compliant to provide Clock Power Management; - * specifically, may not be able to meet the Tclron max - * timing of 400ns as specified in "Dynamic Clock Control", - * section 3.2.5.2.2 of the PCIe spec. This situation is - * atypical and should happen only with older devices. - */ - clkreq_cntl |= PCIE_MISC_HARD_PCIE_HARD_DEBUG_L1SS_ENABLE_MASK; - brcm_extend_rbus_timeout(pcie); - - } else { - /* - * "safe" -- No power savings; refclk is driven by RC - * unconditionally. - */ - if (strcmp(mode, "safe") != 0) - dev_err(pcie->dev, err_msg); - mode = "safe"; - } - writel(clkreq_cntl, pcie->base + HARD_DEBUG(pcie)); - - dev_info(pcie->dev, "clkreq-mode set to %s\n", mode); -} - static int brcm_pcie_start_link(struct brcm_pcie *pcie) { struct device *dev = pcie->dev; void __iomem *base = pcie->base; u16 nlw, cls, lnksta; bool ssc_good = false; + u32 tmp; int ret, i; /* Unassert the fundamental reset */ @@ -1300,8 +1214,6 @@ static int brcm_pcie_start_link(struct brcm_pcie *pcie) return -ENODEV; } - brcm_config_clkreq(pcie); - if (pcie->gen) brcm_pcie_set_gen(pcie, pcie->gen); @@ -1320,6 +1232,14 @@ static int brcm_pcie_start_link(struct brcm_pcie *pcie) pci_speed_string(pcie_link_speed[cls]), nlw, ssc_good ? "(SSC)" : "(!SSC)"); + /* + * Refclk from RC should be gated with CLKREQ# input when ASPM L0s,L1 + * is enabled => setting the CLKREQ_DEBUG_ENABLE field to 1. + */ + tmp = readl(base + PCIE_MISC_HARD_PCIE_HARD_DEBUG); + tmp |= PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_MASK; + writel(tmp, base + PCIE_MISC_HARD_PCIE_HARD_DEBUG); + return 0; } From e461662e3a2310ca6ca739de063b58d04f1baa51 Mon Sep 17 00:00:00 2001 From: Dom Cobley Date: Wed, 31 Jan 2024 19:47:39 +0000 Subject: [PATCH 008/688] Revert "ARM: dts: bcm2711: Add BCM2711 xHCI support" This reverts commit 522c35e08b53f157ad3e51848caa861b258001e4. --- arch/arm/boot/dts/broadcom/bcm2711-rpi.dtsi | 5 ----- arch/arm/boot/dts/broadcom/bcm2711.dtsi | 14 -------------- 2 files changed, 19 deletions(-) diff --git a/arch/arm/boot/dts/broadcom/bcm2711-rpi.dtsi b/arch/arm/boot/dts/broadcom/bcm2711-rpi.dtsi index 6bf4241fe3b737..c78ed064d1667d 100644 --- a/arch/arm/boot/dts/broadcom/bcm2711-rpi.dtsi +++ b/arch/arm/boot/dts/broadcom/bcm2711-rpi.dtsi @@ -1,7 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #include "bcm2835-rpi.dtsi" -#include #include / { @@ -101,7 +100,3 @@ &vchiq { interrupts = ; }; - -&xhci { - power-domains = <&power RPI_POWER_DOMAIN_USB>; -}; diff --git a/arch/arm/boot/dts/broadcom/bcm2711.dtsi b/arch/arm/boot/dts/broadcom/bcm2711.dtsi index e4e42af21ef3a4..93174b596373b2 100644 --- a/arch/arm/boot/dts/broadcom/bcm2711.dtsi +++ b/arch/arm/boot/dts/broadcom/bcm2711.dtsi @@ -604,20 +604,6 @@ }; }; - xhci: usb@7e9c0000 { - compatible = "brcm,bcm2711-xhci", "brcm,xhci-brcm-v2"; - reg = <0x0 0x7e9c0000 0x100000>; - #address-cells = <1>; - #size-cells = <0>; - interrupts = ; - /* DWC2 and this IP block share the same USB PHY, - * enabling both at the same time results in lockups. - * So keep this node disabled and let the bootloader - * decide which interface should be enabled. - */ - status = "disabled"; - }; - v3d: gpu@7ec00000 { compatible = "brcm,2711-v3d"; reg = <0x0 0x7ec00000 0x4000>, From 4f3cb404df3711df1e88f2227beb866db9f3d225 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Thu, 28 Mar 2024 16:16:37 +0000 Subject: [PATCH 009/688] Revert "usb: phy: generic: Get the vbus supply" This reverts commit 03e607cbb2931374db1825f371e9c7f28526d3f4. --- drivers/usb/phy/phy-generic.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/usb/phy/phy-generic.c b/drivers/usb/phy/phy-generic.c index e7d50e0a161238..aeced547e0e723 100644 --- a/drivers/usb/phy/phy-generic.c +++ b/drivers/usb/phy/phy-generic.c @@ -256,13 +256,6 @@ int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_generic *nop) return dev_err_probe(dev, PTR_ERR(nop->vcc), "could not get vcc regulator\n"); - nop->vbus_draw = devm_regulator_get_exclusive(dev, "vbus"); - if (PTR_ERR(nop->vbus_draw) == -ENODEV) - nop->vbus_draw = NULL; - if (IS_ERR(nop->vbus_draw)) - return dev_err_probe(dev, PTR_ERR(nop->vbus_draw), - "could not get vbus regulator\n"); - nop->dev = dev; nop->phy.dev = nop->dev; nop->phy.label = "nop-xceiv"; From 172ab5fefb9148c361f338e4cb064eeb0ed9e93a Mon Sep 17 00:00:00 2001 From: Dom Cobley Date: Thu, 7 Apr 2022 18:23:07 +0100 Subject: [PATCH 010/688] 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 73cac8d0287e89..c93c98e092990d 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,22 +129,33 @@ 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, }; @@ -155,6 +179,8 @@ enum rpi_firmware_clk_id { RPI_FIRMWARE_NUM_CLK_ID, }; +#define GET_DISPLAY_SETTINGS_PAYLOAD_SIZE 64 + /** * struct rpi_firmware_clk_rate_request - Firmware Request for a rate * @id: ID of the clock being queried From 531b7bd4a4c92e74f8529ebdb2f68389f6b2dfd7 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Tue, 19 May 2020 16:20:30 +0100 Subject: [PATCH 011/688] 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 c133e96b8aca25..7ecef93cb10ddd 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" }, From 057e8ee1fb9f3c9549986710d6475ed5b49b9fe9 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Thu, 7 Jan 2021 16:30:55 +0000 Subject: [PATCH 012/688] 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 43cdf39019a445..04a4e66588f271 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -444,6 +444,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. From f11cc580a654df4cf35d687385303ec01fac9908 Mon Sep 17 00:00:00 2001 From: Mateusz Kwiatkowski Date: Thu, 15 Jul 2021 01:08:01 +0200 Subject: [PATCH 013/688] 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 drm/vc4: Do not reset tv mode as this is already handled by framework In vc4_vec_connector_reset, the tv mode is already reset to the property default by drm_atomic_helper_connector_tv_reset, so there is no need for a local fixup to potentially some other default. Fixes: 96922af14473 ("drm/vc4: Allow setting the TV norm via module parameter") Signed-off-by: Dave Stevenson --- drivers/gpu/drm/vc4/vc4_vec.c | 107 +++++++++++++++++++++++++--------- 1 file changed, 78 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_vec.c b/drivers/gpu/drm/vc4/vc4_vec.c index eb64e881051e6d..677e022967fb34 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; }; @@ -371,6 +373,33 @@ static const struct drm_prop_enum_list legacy_tv_mode_names[] = { { VC4_VEC_TV_MODE_MONOCHROME, "Mono", }, }; +static enum drm_connector_tv_mode +vc4_vec_get_default_mode(struct drm_connector *connector) +{ + if (vc4_vec_tv_norm) { + int ret; + + ret = drm_get_tv_mode_from_name(vc4_vec_tv_norm, strlen(vc4_vec_tv_norm)); + if (ret >= 0) + return ret; + } 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 DRM_MODE_TV_MODE_PAL; + } + + /* in all other cases, default to NTSC */ + return DRM_MODE_TV_MODE_NTSC; +} + static enum drm_connector_status vc4_vec_connector_detect(struct drm_connector *connector, bool force) { @@ -436,52 +465,55 @@ vc4_vec_connector_set_property(struct drm_connector *connector, } static int -vc4_vec_connector_get_property(struct drm_connector *connector, - const struct drm_connector_state *state, - struct drm_property *property, - uint64_t *val) +vc4_vec_generic_tv_mode_to_legacy(enum drm_connector_tv_mode tv_mode) { - struct vc4_vec *vec = connector_to_vc4_vec(connector); - - if (property != vec->legacy_tv_mode_property) - return -EINVAL; - - switch (state->tv.mode) { + switch (tv_mode) { case DRM_MODE_TV_MODE_NTSC: - *val = VC4_VEC_TV_MODE_NTSC; - break; + return VC4_VEC_TV_MODE_NTSC; case DRM_MODE_TV_MODE_NTSC_443: - *val = VC4_VEC_TV_MODE_NTSC_443; - break; + return VC4_VEC_TV_MODE_NTSC_443; case DRM_MODE_TV_MODE_NTSC_J: - *val = VC4_VEC_TV_MODE_NTSC_J; - break; + return VC4_VEC_TV_MODE_NTSC_J; case DRM_MODE_TV_MODE_PAL: - *val = VC4_VEC_TV_MODE_PAL; - break; + return VC4_VEC_TV_MODE_PAL; case DRM_MODE_TV_MODE_PAL_M: - *val = VC4_VEC_TV_MODE_PAL_M; - break; + return VC4_VEC_TV_MODE_PAL_M; case DRM_MODE_TV_MODE_PAL_N: - *val = VC4_VEC_TV_MODE_PAL_N; - break; + return VC4_VEC_TV_MODE_PAL_N; case DRM_MODE_TV_MODE_SECAM: - *val = VC4_VEC_TV_MODE_SECAM; - break; + return VC4_VEC_TV_MODE_SECAM; case DRM_MODE_TV_MODE_MONOCHROME: - *val = VC4_VEC_TV_MODE_MONOCHROME; - break; + return VC4_VEC_TV_MODE_MONOCHROME; default: return -EINVAL; } +} + +static int +vc4_vec_connector_get_property(struct drm_connector *connector, + const struct drm_connector_state *state, + struct drm_property *property, + uint64_t *val) +{ + struct vc4_vec *vec = connector_to_vc4_vec(connector); + enum vc4_vec_tv_mode_id legacy_mode; + + if (property != vec->legacy_tv_mode_property) + return -EINVAL; + + legacy_mode = vc4_vec_generic_tv_mode_to_legacy(state->tv.mode); + if (legacy_mode < 0) + return legacy_mode; + + *val = legacy_mode; return 0; } @@ -504,6 +536,8 @@ static const struct drm_connector_helper_funcs vc4_vec_connector_helper_funcs = static int vc4_vec_connector_init(struct drm_device *dev, struct vc4_vec *vec) { struct drm_connector *connector = &vec->connector; + enum vc4_vec_tv_mode_id legacy_default_mode; + enum drm_connector_tv_mode default_mode; struct drm_property *prop; int ret; @@ -516,9 +550,17 @@ static int vc4_vec_connector_init(struct drm_device *dev, struct vc4_vec *vec) drm_connector_helper_add(connector, &vc4_vec_connector_helper_funcs); + default_mode = vc4_vec_get_default_mode(connector); + if (default_mode < 0) + return default_mode; + drm_object_attach_property(&connector->base, dev->mode_config.tv_mode_property, - DRM_MODE_TV_MODE_NTSC); + default_mode); + + legacy_default_mode = vc4_vec_generic_tv_mode_to_legacy(default_mode); + if (legacy_default_mode < 0) + return legacy_default_mode; prop = drm_property_create_enum(dev, 0, "mode", legacy_tv_mode_names, @@ -527,7 +569,7 @@ static int vc4_vec_connector_init(struct drm_device *dev, struct vc4_vec *vec) return -ENOMEM; vec->legacy_tv_mode_property = prop; - drm_object_attach_property(&connector->base, prop, VC4_VEC_TV_MODE_NTSC); + drm_object_attach_property(&connector->base, prop, legacy_default_mode); drm_connector_attach_tv_margin_properties(connector); @@ -854,3 +896,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"); From 6a1c0b0f37724755c59dc771848a5e4b0a52fbd8 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Mon, 7 Sep 2020 17:32:27 +0100 Subject: [PATCH 014/688] drm/vc4: fkms: 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 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: Add missing 32-bit RGB formats The missing 32-bit per pixel ABGR and various "RGB with an X value" formats are added. Change sent by Dave Stevenson. Signed-off-by: David Plowman drm: vc4: Fixup duplicated macro definition in vc4_firmware_kms Both vc4_drv.h and vc4_firmware_kms.c had definitions for to_vc4_crtc. Rename the fkms one to make it unique, and drop the magic define vc4_crtc vc4_kms_crtc define to_vc4_crtc to_vc4_kms_crtc that renamed half the variable and function names in a slightly unexpected way. Signed-off-by: Dave Stevenson drm/vc4: Fix FKMS for when the YUV chroma planes are different buffers The code was assuming that it was a single buffer with offsets, when kmstest uses separate buffers and 0 offsets for each plane. Signed-off-by: Dave Stevenson drm/vc4: fkms: Rename plane related functions The name collide with the Full KMS functions that are going to be made public. Signed-off-by: Maxime Ripard drm/vc4_fkms: Fix up interrupt handler for both 2835/2711 and 2712 2712 has switched from using the SMI peripheral to another interrupt source for the vsync interrupt, so handle both sources cleanly. Signed-off-by: Dave Stevenson --- 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 | 2079 ++++++++++++++++++++++++ drivers/gpu/drm/vc4/vc4_kms.c | 33 +- drivers/gpu/drm/vc4/vc_image_types.h | 175 ++ 7 files changed, 2313 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 c41f89a15a5504..1c0ce156b0aa79 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 fac624a663ea07..8144dedf2248e1 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 7ecef93cb10ddd..813ebdb8e064ce 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.c +++ b/drivers/gpu/drm/vc4/vc4_drv.c @@ -283,6 +283,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) goto err; - 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) goto err; - ret = vc4_plane_create_additional_planes(drm); - if (ret) - goto err; + if (!vc4->firmware_kms) { + ret = vc4_plane_create_additional_planes(drm); + if (ret) + goto err; + } ret = vc4_kms_load(drm); if (ret < 0) goto err; - 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) @@ -430,6 +446,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 08e29fa825635d..0428b236f315e5 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -88,8 +88,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; @@ -964,6 +968,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 00000000000000..844c41991af0a4 --- /dev/null +++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c @@ -0,0 +1,2079 @@ +// 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 + +#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 +}; + +enum vc4_fkms_revision { + BCM2835_6_7, + BCM2711, + BCM2712, +}; + +struct vc4_fkms { + struct get_display_cfg cfg; + enum vc4_fkms_revision revision; +}; + +#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, + }, + { + .drm = DRM_FORMAT_XBGR8888, + .vc_image = VC_IMAGE_RGBX32, + }, + { + .drm = DRM_FORMAT_ABGR8888, + .vc_image = VC_IMAGE_RGBA32, + }, + { + .drm = DRM_FORMAT_RGBX8888, + .vc_image = VC_IMAGE_BGRX8888, + }, + { + .drm = DRM_FORMAT_BGRX8888, + .vc_image = VC_IMAGE_RGBX8888, + }, + { + .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 + +struct vc4_fkms_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_fkms_crtc *to_vc4_fkms_crtc(struct drm_crtc *crtc) +{ + return container_of(crtc, struct vc4_fkms_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; + 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; + bo = drm_fb_dma_get_gem_obj(fb, 0); + 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. + */ + bo = drm_fb_dma_get_gem_obj(fb, 1); + mb->plane.planes[1] = bo->dma_addr + fb->offsets[1]; + if (num_planes > 2) { + bo = drm_fb_dma_get_gem_obj(fb, 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_fkms_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); +} + +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_fkms_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_fkms_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_fkms_plane_reset, + .atomic_duplicate_state = vc4_fkms_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_fkms_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, + 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_fkms_crtc *vc4_fkms_crtc = to_vc4_fkms_crtc(crtc); + struct drm_display_mode *mode = &crtc->state->adjusted_mode; + struct vc4_fkms_encoder *vc4_encoder = + to_vc4_fkms_encoder(vc4_fkms_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_fkms_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_fkms_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_fkms_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_fkms_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_fkms_crtc *vc4_fkms_crtc = to_vc4_fkms_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_fkms_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_fkms_crtc *vc4_fkms_crtc = to_vc4_fkms_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_fkms_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->revision >= BCM2711 && + (vc4_fkms_crtc->display_number == 2 || vc4_fkms_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_fkms_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_fkms_crtc *vc4_fkms_crtc) +{ + struct drm_crtc *crtc = &vc4_fkms_crtc->base; + struct drm_device *dev = crtc->dev; + unsigned long flags; + + spin_lock_irqsave(&dev->event_lock, flags); + if (vc4_fkms_crtc->event) { + drm_crtc_send_vblank_event(crtc, vc4_fkms_crtc->event); + vc4_fkms_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_fkms_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 irqreturn_t vc4_crtc2712_irq_handler(int irq, void *data) +{ + struct vc4_fkms_crtc **crtc_list = data; + int i; + + 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]); + } + + return IRQ_HANDLED; +} + +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_fkms_crtc *vc4_fkms_crtc = to_vc4_fkms_crtc(crtc); + + DRM_DEBUG_KMS("[CRTC:%d] enable_vblank.\n", + crtc->base.id); + vc4_fkms_crtc->vblank_enabled = true; + + return 0; +} + +static void vc4_fkms_disable_vblank(struct drm_crtc *crtc) +{ + struct vc4_fkms_crtc *vc4_fkms_crtc = to_vc4_fkms_crtc(crtc); + + DRM_DEBUG_KMS("[CRTC:%d] disable_vblank.\n", + crtc->base.id); + vc4_fkms_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_fkms_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", + .data = (void *)BCM2835_6_7 }, + { .compatible = "raspberrypi,rpi-firmware-kms-2711", + .data = (void *)BCM2711 }, + { .compatible = "raspberrypi,rpi-firmware-kms-2712", + .data = (void *)BCM2712 }, + {} +}; + +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; + const struct drm_edid *drm_edid; + const 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 { + drm_edid = drm_edid_read_custom(connector, vc4_fkms_get_edid_block, + fkms_connector); + edid = drm_edid_raw(drm_edid); + + /* 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, (struct edid *)edid); + kfree(drm_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. + */ +static 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. + */ +static 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. + */ +static 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; +} + +static 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_margins_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_fkms_crtc **ret_crtc) +{ + struct vc4_dev *vc4 = to_vc4_dev(drm); + struct vc4_fkms_crtc *vc4_fkms_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_fkms_crtc = devm_kzalloc(dev, sizeof(*vc4_fkms_crtc), GFP_KERNEL); + if (!vc4_fkms_crtc) + return -ENOMEM; + crtc = &vc4_fkms_crtc->base; + + vc4_fkms_crtc->display_number = display_ref; + vc4_fkms_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_fkms_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_fkms_crtc->display_type, NULL); + drm_encoder_helper_add(&vc4_encoder->base, + &vc4_fkms_encoder_helper_funcs); + + vc4_fkms_crtc->connector = vc4_fkms_connector_init(drm, &vc4_encoder->base, + display_ref); + if (IS_ERR(vc4_fkms_crtc->connector)) { + ret = PTR_ERR(vc4_fkms_crtc->connector); + goto err_destroy_encoder; + } + + *ret_crtc = vc4_fkms_crtc; + + return 0; + +err_destroy_encoder: + vc4_fkms_encoder_destroy(vc4_fkms_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_fkms_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; + fkms->revision = (enum vc4_fkms_revision)match->data; + + 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"); + + if (fkms->revision >= BCM2712) { + ret = devm_request_irq(dev, platform_get_irq(pdev, 0), + vc4_crtc2712_irq_handler, 0, + "vc4 firmware kms", crtc_list); + } else { + 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_fkms_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 void vc4_fkms_remove(struct platform_device *pdev) +{ + component_del(&pdev->dev, &vc4_fkms_ops); +} + +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 5495f2a94fa926..dd767a53247946 100644 --- a/drivers/gpu/drm/vc4/vc4_kms.c +++ b/drivers/gpu/drm/vc4/vc4_kms.c @@ -138,6 +138,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]), @@ -343,7 +346,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); @@ -369,7 +372,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 = clamp_t(unsigned long, state_rate, @@ -388,10 +391,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); @@ -406,7 +411,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) { unsigned long core_rate = min_t(unsigned long, hvs->max_core_rate, new_hvs_state->core_clock_rate); @@ -426,11 +431,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); @@ -799,6 +814,7 @@ static int cmp_vc4_crtc_hvs_output(const void *a, const void *b) 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 **sorted_crtcs; struct drm_crtc *crtc; @@ -806,6 +822,9 @@ static int vc4_pv_muxing_atomic_check(struct drm_device *dev, unsigned int i; int ret; + if (vc4->firmware_kms) + return 0; + hvs_new_state = vc4_hvs_get_global_state(state); if (IS_ERR(hvs_new_state)) return PTR_ERR(hvs_new_state); 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 00000000000000..e8d2b4b162f7cd --- /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, +}; From 7f4f374f09fd6f9b7e12ff817e30db53fb6cf6b8 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Tue, 27 Apr 2021 14:24:21 +0200 Subject: [PATCH 015/688] 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 8b5a7e5eb1466c..8be9502d3b53d0 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -1340,19 +1340,42 @@ int __vc4_crtc_init(struct drm_device *drm, 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 0428b236f315e5..c4586b87f443ff 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -23,6 +23,7 @@ #include #include "uapi/drm/vc4_drm.h" +#include "vc4_regs.h" struct drm_device; struct drm_gem_object; @@ -495,6 +496,17 @@ struct drm_encoder *vc4_find_encoder_by_type(struct drm_device *drm, return NULL; } +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_data { const char *name; @@ -539,9 +551,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 2a835a5cff9dd1..ef0c571b22ff2e 100644 --- a/drivers/gpu/drm/vc4/vc4_hvs.c +++ b/drivers/gpu/drm/vc4/vc4_hvs.c @@ -243,7 +243,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; @@ -257,6 +258,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; @@ -400,7 +476,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); @@ -646,7 +725,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 8ac9515554f8a0..b96f49a17c1ce3 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) From 016c4dfdc110334655f7cf109dd564ce4c862680 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Wed, 28 Apr 2021 12:32:10 +0200 Subject: [PATCH 016/688] 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 ef0c571b22ff2e..b6d6e6cea17197 100644 --- a/drivers/gpu/drm/vc4/vc4_hvs.c +++ b/drivers/gpu/drm/vc4/vc4_hvs.c @@ -143,6 +143,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. */ @@ -850,11 +929,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); + drm_debugfs_add_file(drm, "hvs_gamma", vc5_hvs_debugfs_gamma, + NULL); + } + drm_debugfs_add_file(drm, "hvs_dlists", vc4_hvs_debugfs_dlist, NULL); drm_debugfs_add_file(drm, "hvs_underrun", vc4_hvs_debugfs_underrun, NULL); From 15ac053e6fd5a36b5b2267d1eebd8fd0e3bc594a Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Mon, 14 Jun 2021 15:28:30 +0200 Subject: [PATCH 017/688] 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 8be9502d3b53d0..f35187ef32322f 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -303,6 +303,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 c4586b87f443ff..f852d07db3cec5 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -614,6 +614,9 @@ vc4_crtc_to_vc4_pv_data(const struct vc4_crtc *crtc) return container_of_const(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 b6d6e6cea17197..971d5ed3f0b71b 100644 --- a/drivers/gpu/drm/vc4/vc4_hvs.c +++ b/drivers/gpu/drm/vc4/vc4_hvs.c @@ -596,6 +596,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); @@ -626,7 +656,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) From c223964f9f41c57d631446636b18e0c5ab2a5de0 Mon Sep 17 00:00:00 2001 From: Mateusz Kwiatkowski Date: Thu, 15 Jul 2021 01:08:11 +0200 Subject: [PATCH 018/688] 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 | 36 ++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/vc4/vc4_vec.c b/drivers/gpu/drm/vc4/vc4_vec.c index 677e022967fb34..cc3d200c31ee11 100644 --- a/drivers/gpu/drm/vc4/vc4_vec.c +++ b/drivers/gpu/drm/vc4/vc4_vec.c @@ -274,6 +274,18 @@ static const struct debugfs_reg32 vec_regs[] = { VC4_REG32(VEC_DAC_MISC), }; +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_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[] = { { .mode = DRM_MODE_TV_MODE_NTSC, @@ -528,9 +540,31 @@ static const struct drm_connector_funcs vc4_vec_connector_funcs = { .atomic_set_property = vc4_vec_connector_set_property, }; +static int vc4_vec_connector_get_modes(struct drm_connector *connector) +{ + struct drm_display_mode *mode; + int count = drm_connector_helper_tv_get_modes(connector); + + mode = drm_mode_duplicate(connector->dev, &drm_mode_240p); + if (!mode) + return -ENOMEM; + + drm_mode_probed_add(connector, mode); + count++; + + mode = drm_mode_duplicate(connector->dev, &drm_mode_288p); + if (!mode) + return -ENOMEM; + + drm_mode_probed_add(connector, mode); + count++; + + return count; +} + static const struct drm_connector_helper_funcs vc4_vec_connector_helper_funcs = { .atomic_check = drm_atomic_helper_connector_tv_check, - .get_modes = drm_connector_helper_tv_get_modes, + .get_modes = vc4_vec_connector_get_modes, }; static int vc4_vec_connector_init(struct drm_device *dev, struct vc4_vec *vec) From 3ab842925c332d63018cb25d1bcab9bade28bdaa Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Tue, 2 Nov 2021 16:01:36 +0000 Subject: [PATCH 019/688] 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 3969dc548cff60..accda00238ee70 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; From a229e2e7c87ffc03bbad75608c937a4e5ac26010 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Mon, 8 Nov 2021 17:32:45 +0000 Subject: [PATCH 020/688] 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 971d5ed3f0b71b..d50a18a476a590 100644 --- a/drivers/gpu/drm/vc4/vc4_hvs.c +++ b/drivers/gpu/drm/vc4/vc4_hvs.c @@ -548,8 +548,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 @@ -834,18 +837,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); } From 5a5da853cb724e689ae5a2afaaab3d74e5f968fe Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Mon, 8 Nov 2021 18:25:49 +0000 Subject: [PATCH 021/688] 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 f35187ef32322f..250f3f63697229 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -1371,7 +1371,7 @@ int __vc4_crtc_init(struct drm_device *drm, /* 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++) { From acb49527743a8f9ad5849a5fe10aa0785bd7bb21 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Wed, 10 Nov 2021 16:36:12 +0000 Subject: [PATCH 022/688] 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 d50a18a476a590..e5046842148ac1 100644 --- a/drivers/gpu/drm/vc4/vc4_hvs.c +++ b/drivers/gpu/drm/vc4/vc4_hvs.c @@ -614,6 +614,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; From 83829c31443a1a5a539fd9e12479287a25e7ddd2 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Thu, 13 Jan 2022 11:30:42 +0000 Subject: [PATCH 023/688] 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 250f3f63697229..8f5ac282b45081 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -1357,15 +1357,9 @@ int __vc4_crtc_init(struct drm_device *drm, 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 From 50e58bbba13f88e636d92079bfb09643c2e43b87 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Fri, 17 Dec 2021 13:36:52 +0000 Subject: [PATCH 024/688] 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 f725f865461147..2836d25b42202d 100644 --- a/include/drm/drm_mipi_dsi.h +++ b/include/drm/drm_mipi_dsi.h @@ -114,29 +114,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) From 57a727ef07e082cb40fa4476378b6cf034f7e746 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Thu, 20 Jan 2022 17:29:36 +0000 Subject: [PATCH 025/688] 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 46198af9eebbf8..8b856bc2ed5b25 100644 --- a/drivers/gpu/drm/bridge/tc358762.c +++ b/drivers/gpu/drm/bridge/tc358762.c @@ -294,7 +294,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; From 403d5411a7ca276f697ae5cb5952ff354c5e6dc4 Mon Sep 17 00:00:00 2001 From: Dom Cobley Date: Mon, 14 Mar 2022 17:56:10 +0000 Subject: [PATCH 026/688] 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 f852d07db3cec5..0ea9d37d5bc7c5 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -409,7 +409,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 07caf2a47c6cef..e0df210bedcbdc 100644 --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c @@ -251,9 +251,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; @@ -462,15 +462,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; @@ -523,7 +518,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. @@ -569,7 +564,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) @@ -660,7 +655,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 @@ -669,11 +665,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; } @@ -826,7 +822,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; @@ -838,6 +835,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 @@ -858,9 +858,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: @@ -875,7 +877,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]; } @@ -898,7 +900,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 @@ -908,7 +910,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 @@ -1004,7 +1006,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; @@ -1026,12 +1028,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 / @@ -1092,10 +1094,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); @@ -1148,10 +1148,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); From 0053c359bc5c0ea09bb6f9af7f5e7bce88d2b0bd Mon Sep 17 00:00:00 2001 From: Dom Cobley Date: Fri, 9 Apr 2021 15:00:40 +0100 Subject: [PATCH 027/688] 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 e0df210bedcbdc..2a1b1fdf819c86 100644 --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c @@ -532,14 +532,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) @@ -598,13 +631,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); } @@ -1052,6 +1085,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. From 6e3639428d27a5bb3637979f2d61d528a382fe5d Mon Sep 17 00:00:00 2001 From: Dom Cobley Date: Wed, 26 Jan 2022 15:58:13 +0000 Subject: [PATCH 028/688] 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 | 35 ++++++++++++++++++++-- 5 files changed, 94 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c index 519228eb109533..c7ff2123780650 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 370dc676e3aa54..d0117fc8b725b2 100644 --- a/drivers/gpu/drm/drm_atomic_uapi.c +++ b/drivers/gpu/drm/drm_atomic_uapi.c @@ -538,6 +538,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_property_replace_blob_from_id(dev, &state->fb_damage_clips, @@ -620,6 +624,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 accda00238ee70..c183da01b8fbcc 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 ed81741036d766..00359830a4be7e 100644 --- a/include/drm/drm_color_mgmt.h +++ b/include/drm/drm_color_mgmt.h @@ -91,6 +91,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 dd718c62ac31bf..6c512550dfbb7f 100644 --- a/include/drm/drm_plane.h +++ b/include/drm/drm_plane.h @@ -183,6 +183,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: * @@ -783,9 +801,22 @@ struct drm_plane { struct drm_property *hotspot_y_property; /** - * @kmsg_panic: Used to register a panic notifier for this plane + * @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 kmsg_dumper kmsg_panic; + struct drm_property *chroma_siting_v_property; }; #define obj_to_plane(x) container_of(x, struct drm_plane, base) From ae3fe7119d3412a132f0e57d4772a325959274fe Mon Sep 17 00:00:00 2001 From: Dom Cobley Date: Thu, 27 Jan 2022 15:32:04 +0000 Subject: [PATCH 029/688] 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 2a1b1fdf819c86..dbb8acfe48ea88 100644 --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c @@ -535,17 +535,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 */ @@ -631,13 +632,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); } @@ -1721,6 +1724,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); From 0ced7196d4326fdd31dae4255b0d4006f9f0cfe4 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Fri, 1 Apr 2022 11:31:38 +0100 Subject: [PATCH 030/688] 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 8f5ac282b45081..0b0c2bdfe3d024 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -752,10 +752,16 @@ 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 0ea9d37d5bc7c5..99500b4bf0c451 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -627,12 +627,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; From 41d95cb33d2792b553fcbf42faa5d3f56bbef5cf Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 23 Oct 2020 14:39:23 +0200 Subject: [PATCH 031/688] 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 04a4e66588f271..5934a16e278b77 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -1656,13 +1656,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; @@ -2312,12 +2305,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 b4ef4d59da1ace..15541e37a3e354 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -7648,6 +7648,19 @@ int intel_atomic_commit(struct drm_device *dev, struct drm_atomic_state *_state, 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 9c45d641b5212c..5c8e5611304fbd 100644 --- a/drivers/gpu/drm/msm/msm_atomic.c +++ b/drivers/gpu/drm/msm/msm_atomic.c @@ -242,6 +242,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: From 0a4a0e9269aa039cb2153fe06c8179ec37741c15 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Fri, 1 Apr 2022 17:10:37 +0100 Subject: [PATCH 032/688] 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 d0117fc8b725b2..e5c1adfe73205a 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; @@ -707,12 +708,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->legacy_tv_mode_property) { state->tv.legacy_mode = val; } else if (property == config->tv_mode_property) { @@ -797,6 +802,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; } From 19021718c379ef34e2a52a8f7520847642dcb5eb Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Mon, 11 Jul 2022 10:38:25 +0200 Subject: [PATCH 033/688] 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 e5046842148ac1..a2500e3e9f9f43 100644 --- a/drivers/gpu/drm/vc4/vc4_hvs.c +++ b/drivers/gpu/drm/vc4/vc4_hvs.c @@ -976,6 +976,9 @@ int vc4_hvs_debugfs_init(struct drm_minor *minor) struct vc4_dev *vc4 = to_vc4_dev(drm); struct vc4_hvs *hvs = vc4->hvs; + if (vc4->firmware_kms) + return 0; + if (!vc4->hvs) return -ENODEV; From 7f52495823491e73ca99dbe3df4ce7ac53bddd8f Mon Sep 17 00:00:00 2001 From: Dom Cobley Date: Wed, 1 Jun 2022 15:43:51 +0100 Subject: [PATCH 034/688] drm/vc4_hdmi: Allow hotplug detect to be forced See: https://forum.libreelec.tv/thread/24783-tv-avr-turns-back-on-right-after-turning-them-off While the kernel provides a :D flag for assuming device is connected, it doesn't stop this function from being called and generating a cec_phys_addr_invalidate message when hotplug is deasserted. That message provokes a flurry of CEC messages which for many users results in the TV switching back on again and it's very hard to get it to stay switched off. It seems to only occur with an AVR and TV connected but has been observed across a number of manufacturers. The issue started with https://github.com/raspberrypi/linux/pull/4371 and this provides an optional way of getting back the old behaviour Signed-off-by: Dom Cobley --- drivers/gpu/drm/vc4/vc4_hdmi.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index 6611ab7c26a63c..a916dfbdc1bf3e 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -43,6 +43,8 @@ #include #include #include +#include +#include #include #include #include @@ -111,6 +113,10 @@ #define HDMI_14_MAX_TMDS_CLK (340 * 1000 * 1000) +/* bit field to force hotplug detection. bit0 = HDMI0 */ +static int force_hotplug = 0; +module_param(force_hotplug, int, 0644); + static bool vc4_hdmi_supports_scrambling(struct vc4_hdmi *vc4_hdmi) { struct drm_display_info *display = &vc4_hdmi->connector.display_info; @@ -449,7 +455,9 @@ static int vc4_hdmi_connector_detect_ctx(struct drm_connector *connector, return connector_status_unknown; } - if (vc4_hdmi->hpd_gpio) { + if (force_hotplug & BIT(vc4_hdmi->encoder.type - VC4_ENCODER_TYPE_HDMI0)) + status = connector_status_connected; + else if (vc4_hdmi->hpd_gpio) { if (gpiod_get_value_cansleep(vc4_hdmi->hpd_gpio)) status = connector_status_connected; } else { From 21284e3e104c0153fead647026e73da3f98e4092 Mon Sep 17 00:00:00 2001 From: Dom Cobley Date: Tue, 6 Dec 2022 15:05:56 +0000 Subject: [PATCH 035/688] vc4_hdmi: Avoid log spam for audio start failure We regularly get dmesg error reports of: [ 18.184066] hdmi-audio-codec hdmi-audio-codec.3.auto: ASoC: error at snd_soc_dai_startup on i2s-hifi: -19 [ 18.184098] MAI: soc_pcm_open() failed (-19) Currently I get 30 of these when booting to desktop. We always say, ignore they are harmless, but removing them would be good. A bit of investigation shows, for me, the errors are all generated by second, unused hdmi interface. It shows as an alsa device, and pulseaudio attempts to open it (numerous times), generating a kernel error message each time. systemctl --user restart pulseaudio.service generates 6 additional error messages. The error messages all come through: https://github.com/raspberrypi/linux/blob/a009a9c0d79dfec114ee5102ec3d3325a172c952/sound/soc/soc-pcm.c#L39 which suggests returning ENOTSUPP, rather that ENODEV will be quiet. And indeed it is. Note: earlier kernels do not have the quiet ENOTSUPP, so additional cherry-picks will be needed to backport Signed-off-by: Dom Cobley --- drivers/gpu/drm/vc4/vc4_hdmi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index a916dfbdc1bf3e..cfd043a5309a40 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -1928,7 +1928,7 @@ static int vc4_hdmi_audio_startup(struct device *dev, void *data) } if (!vc4_hdmi_audio_can_stream(vc4_hdmi)) { - ret = -ENODEV; + ret = -ENOTSUPP; goto out_dev_exit; } From 61e3d0d7d5d085a168842b5c1840f9d7af43c6cc Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Thu, 16 Dec 2021 14:54:54 +0100 Subject: [PATCH 036/688] drm/vc4: hvs: Defer dlist slots deallocation During normal operations, the cursor position update is done through an asynchronous plane update, which on the vc4 driver basically just modifies the right dlist word to move the plane to the new coordinates. However, when we have the overscan margins setup, we fall back to a regular commit when we are next to the edges. And since that commit happens to be on a cursor plane, it's considered a legacy cursor update by KMS. The main difference it makes is that it won't wait for its completion (ie, next vblank) before returning. This means if we have multiple commits happening in rapid succession, we can have several of them happening before the next vblank. In parallel, our dlist allocation is tied to a CRTC state, and each time we do a commit we end up with a new CRTC state, with the previous one being freed. This means that we free our previous dlist entry (but don't clear it though) every time a new one is being committed. Now, if we were to have two commits happening before the next vblank, we could end up freeing reusing the same dlist entries before the next vblank. Indeed, we would start from an initial state taking, for example, the dlist entries 10 to 20, then start a commit taking the entries 20 to 30 and setting the dlist pointer to 20, and freeing the dlist entries 10 to 20. However, since we haven't reach vblank yet, the HVS is still using the entries 10 to 20. If we were to make a new commit now, chances are the allocator are going to give the 10 to 20 entries back, and we would change their content to match the new state. If vblank hasn't happened yet, we just corrupted the active dlist entries. A first attempt to solve this was made by creating an intermediate dlist buffer to store the current (ie, as of the last commit) dlist content, that we would update each time the HVS is done with a frame. However, if the interrupt handler missed the vblank window, we would end up copying our intermediate dlist to the hardware one during the composition, essentially creating the same issue. Since making sure that our interrupt handler runs within a fixed, constrained, time window would require to make Linux a real-time kernel, this seems a bit out of scope. Instead, we can work around our original issue by keeping the dlist slots allocation longer. That way, we won't reuse a dlist slot while it's still in flight. In order to achieve this, instead of freeing the dlist slot when its associated CRTC state is destroyed, we'll queue it in a list. A naive implementation would free the buffers in that queue when we get our end of frame interrupt. However, there's still a race since, just like in the shadow dlist case, we don't control when the handler for that interrupt is going to run. Thus, we can end up with a commit adding an old dlist allocation to our queue during the window between our actual interrupt and when our handler will run. And since that buffer is still being used for the composition of the current frame, we can't free it right away, exposing us to the original bug. Fortunately for us, the hardware provides a frame counter that is increased each time the first line of a frame is being generated. Associating the frame counter the image is supposed to go away to the allocation, and then only deallocate buffers that have a counter below or equal to the one we see when the deallocation code should prevent the above race from occuring. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/vc4/vc4_crtc.c | 10 +- drivers/gpu/drm/vc4/vc4_drv.h | 15 ++- drivers/gpu/drm/vc4/vc4_hvs.c | 184 ++++++++++++++++++++++++++++++--- 3 files changed, 186 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index 0b0c2bdfe3d024..44965359190505 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -1097,14 +1097,8 @@ void vc4_crtc_destroy_state(struct drm_crtc *crtc, struct vc4_dev *vc4 = to_vc4_dev(crtc->dev); struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(state); - if (drm_mm_node_allocated(&vc4_state->mm)) { - unsigned long flags; - - spin_lock_irqsave(&vc4->hvs->mm_lock, flags); - drm_mm_remove_node(&vc4_state->mm); - spin_unlock_irqrestore(&vc4->hvs->mm_lock, flags); - - } + vc4_hvs_mark_dlist_entry_stale(vc4->hvs, vc4_state->mm); + vc4_state->mm = NULL; drm_atomic_helper_crtc_destroy_state(crtc, state); } diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index 99500b4bf0c451..9e88f1c767e03c 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -333,6 +333,9 @@ struct vc4_hvs { struct drm_mm lbm_mm; spinlock_t mm_lock; + struct list_head stale_dlist_entries; + struct work_struct free_dlist_work; + struct drm_mm_node mitchell_netravali_filter; struct debugfs_regset32 regset; @@ -620,10 +623,16 @@ struct drm_connector *vc4_get_crtc_connector(struct drm_crtc *crtc, struct drm_encoder *vc4_get_crtc_encoder(struct drm_crtc *crtc, struct drm_crtc_state *state); +struct vc4_hvs_dlist_allocation { + struct list_head node; + struct drm_mm_node mm_node; + unsigned int channel; + u8 target_frame_count; +}; + struct vc4_crtc_state { struct drm_crtc_state base; - /* Dlist area for this CRTC configuration. */ - struct drm_mm_node mm; + struct vc4_hvs_dlist_allocation *mm; bool txp_armed; unsigned int assigned_channel; @@ -1033,6 +1042,8 @@ struct vc4_hvs *__vc4_hvs_alloc(struct vc4_dev *vc4, struct platform_device *pde void vc4_hvs_stop_channel(struct vc4_hvs *hvs, unsigned int output); int vc4_hvs_get_fifo_from_output(struct vc4_hvs *hvs, unsigned int output); u8 vc4_hvs_get_fifo_frame_count(struct vc4_hvs *hvs, unsigned int fifo); +void vc4_hvs_mark_dlist_entry_stale(struct vc4_hvs *hvs, + struct vc4_hvs_dlist_allocation *alloc); int vc4_hvs_atomic_check(struct drm_crtc *crtc, struct drm_atomic_state *state); void vc4_hvs_atomic_begin(struct drm_crtc *crtc, struct drm_atomic_state *state); void vc4_hvs_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_state *state); diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c index a2500e3e9f9f43..ea0aaff485bf2f 100644 --- a/drivers/gpu/drm/vc4/vc4_hvs.c +++ b/drivers/gpu/drm/vc4/vc4_hvs.c @@ -412,6 +412,152 @@ static void vc5_hvs_update_gamma_lut(struct vc4_hvs *hvs, vc5_hvs_lut_load(hvs, vc4_crtc); } +static void vc4_hvs_irq_enable_eof(const struct vc4_hvs *hvs, + unsigned int channel) +{ + struct vc4_dev *vc4 = hvs->vc4; + u32 irq_mask = vc4->is_vc5 ? + SCALER5_DISPCTRL_DSPEIEOF(channel) : + SCALER_DISPCTRL_DSPEIEOF(channel); + + HVS_WRITE(SCALER_DISPCTRL, + HVS_READ(SCALER_DISPCTRL) | irq_mask); +} + +static void vc4_hvs_irq_clear_eof(const struct vc4_hvs *hvs, + unsigned int channel) +{ + struct vc4_dev *vc4 = hvs->vc4; + u32 irq_mask = vc4->is_vc5 ? + SCALER5_DISPCTRL_DSPEIEOF(channel) : + SCALER_DISPCTRL_DSPEIEOF(channel); + + HVS_WRITE(SCALER_DISPCTRL, + HVS_READ(SCALER_DISPCTRL) & ~irq_mask); +} + +static struct vc4_hvs_dlist_allocation * +vc4_hvs_alloc_dlist_entry(struct vc4_hvs *hvs, + unsigned int channel, + size_t dlist_count) +{ + struct vc4_hvs_dlist_allocation *alloc; + unsigned long flags; + int ret; + + if (channel == VC4_HVS_CHANNEL_DISABLED) + return NULL; + + alloc = kzalloc(sizeof(*alloc), GFP_KERNEL); + if (!alloc) + return ERR_PTR(-ENOMEM); + + spin_lock_irqsave(&hvs->mm_lock, flags); + ret = drm_mm_insert_node(&hvs->dlist_mm, &alloc->mm_node, + dlist_count); + spin_unlock_irqrestore(&hvs->mm_lock, flags); + if (ret) + return ERR_PTR(ret); + + alloc->channel = channel; + + return alloc; +} + +void vc4_hvs_mark_dlist_entry_stale(struct vc4_hvs *hvs, + struct vc4_hvs_dlist_allocation *alloc) +{ + unsigned long flags; + u8 frcnt; + + if (!alloc) + return; + + if (!drm_mm_node_allocated(&alloc->mm_node)) + return; + + frcnt = vc4_hvs_get_fifo_frame_count(hvs, alloc->channel); + alloc->target_frame_count = (frcnt + 1) & ((1 << 6) - 1); + + spin_lock_irqsave(&hvs->mm_lock, flags); + + list_add_tail(&alloc->node, &hvs->stale_dlist_entries); + + HVS_WRITE(SCALER_DISPSTAT, SCALER_DISPSTAT_EOF(alloc->channel)); + vc4_hvs_irq_enable_eof(hvs, alloc->channel); + + spin_unlock_irqrestore(&hvs->mm_lock, flags); +} + +static void vc4_hvs_schedule_dlist_sweep(struct vc4_hvs *hvs, + unsigned int channel) +{ + unsigned long flags; + + spin_lock_irqsave(&hvs->mm_lock, flags); + + if (!list_empty(&hvs->stale_dlist_entries)) + queue_work(system_unbound_wq, &hvs->free_dlist_work); + + vc4_hvs_irq_clear_eof(hvs, channel); + + spin_unlock_irqrestore(&hvs->mm_lock, flags); +} + +/* + * Frame counts are essentially sequence numbers over 6 bits, and we + * thus can use sequence number arithmetic and follow the RFC1982 to + * implement proper comparison between them. + */ +static bool vc4_hvs_frcnt_lte(u8 cnt1, u8 cnt2) +{ + return (s8)((cnt1 << 2) - (cnt2 << 2)) <= 0; +} + +/* + * Some atomic commits (legacy cursor updates, mostly) will not wait for + * the next vblank and will just return once the commit has been pushed + * to the hardware. + * + * On the hardware side, our HVS stores the planes parameters in its + * context RAM, and will use part of the RAM to store data during the + * frame rendering. + * + * This interacts badly if we get multiple commits before the next + * vblank since we could end up overwriting the DLIST entries used by + * previous commits if our dlist allocation reuses that entry. In such a + * case, we would overwrite the data currently being used by the + * hardware, resulting in a corrupted frame. + * + * In order to work around this, we'll queue the dlist entries in a list + * once the associated CRTC state is destroyed. The HVS only allows us + * to know which entry is being active, but not which one are no longer + * being used, so in order to avoid freeing entries that are still used + * by the hardware we add a guesstimate of the frame count where our + * entry will no longer be used, and thus will only free those entries + * when we will have reached that frame count. + */ +static void vc4_hvs_dlist_free_work(struct work_struct *work) +{ + struct vc4_hvs *hvs = container_of(work, struct vc4_hvs, free_dlist_work); + struct vc4_hvs_dlist_allocation *cur, *next; + unsigned long flags; + + spin_lock_irqsave(&hvs->mm_lock, flags); + list_for_each_entry_safe(cur, next, &hvs->stale_dlist_entries, node) { + u8 frcnt; + + frcnt = vc4_hvs_get_fifo_frame_count(hvs, cur->channel); + if (!vc4_hvs_frcnt_lte(cur->target_frame_count, frcnt)) + continue; + + list_del(&cur->node); + drm_mm_remove_node(&cur->mm_node); + kfree(cur); + } + spin_unlock_irqrestore(&hvs->mm_lock, flags); +} + u8 vc4_hvs_get_fifo_frame_count(struct vc4_hvs *hvs, unsigned int fifo) { struct drm_device *drm = &hvs->vc4->base; @@ -643,13 +789,12 @@ 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); struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc_state); + struct vc4_hvs_dlist_allocation *alloc; struct drm_device *dev = crtc->dev; struct vc4_dev *vc4 = to_vc4_dev(dev); struct drm_plane *plane; - unsigned long flags; const struct drm_plane_state *plane_state; u32 dlist_count = 0; - int ret; /* The pixelvalve can only feed one encoder (and encoders are * 1:1 with connectors.) @@ -662,12 +807,11 @@ int vc4_hvs_atomic_check(struct drm_crtc *crtc, struct drm_atomic_state *state) dlist_count++; /* Account for SCALER_CTL0_END. */ - spin_lock_irqsave(&vc4->hvs->mm_lock, flags); - ret = drm_mm_insert_node(&vc4->hvs->dlist_mm, &vc4_state->mm, - dlist_count); - spin_unlock_irqrestore(&vc4->hvs->mm_lock, flags); - if (ret) - return ret; + alloc = vc4_hvs_alloc_dlist_entry(vc4->hvs, vc4_state->assigned_channel, dlist_count); + if (IS_ERR(alloc)) + return PTR_ERR(alloc); + + vc4_state->mm = alloc; return vc4_hvs_gamma_check(crtc, state); } @@ -683,8 +827,9 @@ static void vc4_hvs_install_dlist(struct drm_crtc *crtc) if (!drm_dev_enter(dev, &idx)) return; + WARN_ON(!vc4_state->mm); HVS_WRITE(SCALER_DISPLISTX(vc4_state->assigned_channel), - vc4_state->mm.start); + vc4_state->mm->mm_node.start); drm_dev_exit(idx); } @@ -711,8 +856,10 @@ static void vc4_hvs_update_dlist(struct drm_crtc *crtc) spin_unlock_irqrestore(&dev->event_lock, flags); } + WARN_ON(!vc4_state->mm); + spin_lock_irqsave(&vc4_crtc->irq_lock, flags); - vc4_crtc->current_dlist = vc4_state->mm.start; + vc4_crtc->current_dlist = vc4_state->mm->mm_node.start; spin_unlock_irqrestore(&vc4_crtc->irq_lock, flags); } @@ -769,8 +916,7 @@ void vc4_hvs_atomic_flush(struct drm_crtc *crtc, struct vc4_plane_state *vc4_plane_state; bool debug_dump_regs = false; bool enable_bg_fill = false; - u32 __iomem *dlist_start = vc4->hvs->dlist + vc4_state->mm.start; - u32 __iomem *dlist_next = dlist_start; + u32 __iomem *dlist_start, *dlist_next; unsigned int zpos = 0; bool found = false; int idx; @@ -788,6 +934,9 @@ void vc4_hvs_atomic_flush(struct drm_crtc *crtc, vc4_hvs_dump_state(hvs); } + dlist_start = vc4->hvs->dlist + vc4_state->mm->mm_node.start; + dlist_next = dlist_start; + /* Copy all the active planes' dlist contents to the hardware dlist. */ do { found = false; @@ -821,7 +970,8 @@ void vc4_hvs_atomic_flush(struct drm_crtc *crtc, writel(SCALER_CTL0_END, dlist_next); dlist_next++; - WARN_ON_ONCE(dlist_next - dlist_start != vc4_state->mm.size); + WARN_ON(!vc4_state->mm); + WARN_ON_ONCE(dlist_next - dlist_start != vc4_state->mm->mm_node.size); if (enable_bg_fill) /* This sets a black background color fill, as is the case @@ -960,6 +1110,11 @@ static irqreturn_t vc4_hvs_irq_handler(int irq, void *data) irqret = IRQ_HANDLED; } + + if (status & SCALER_DISPSTAT_EOF(channel)) { + vc4_hvs_schedule_dlist_sweep(hvs, channel); + irqret = IRQ_HANDLED; + } } /* Clear every per-channel interrupt flag. */ @@ -1014,6 +1169,9 @@ struct vc4_hvs *__vc4_hvs_alloc(struct vc4_dev *vc4, struct platform_device *pde spin_lock_init(&hvs->mm_lock); + INIT_LIST_HEAD(&hvs->stale_dlist_entries); + INIT_WORK(&hvs->free_dlist_work, vc4_hvs_dlist_free_work); + /* Set up the HVS display list memory manager. We never * overwrite the setup from the bootloader (just 128b out of * our 16K), since we don't want to scramble the screen when From 6ed2c65334538c3dda5983470e58c3da7db3424a Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Wed, 25 Jan 2023 12:38:37 +0100 Subject: [PATCH 037/688] drm/vc4: hvs: Initialize the dlist allocation list entry The vc4_hvs_dlist_allocation structure has a list that we don't initialize when we allocate a new instance. This makes any call reading the list structure (such as list_empty) fail with a NULL pointer dereference. Let's make sure our list is always initialized. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/vc4/vc4_hvs.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c index ea0aaff485bf2f..1a133e22bd99d4 100644 --- a/drivers/gpu/drm/vc4/vc4_hvs.c +++ b/drivers/gpu/drm/vc4/vc4_hvs.c @@ -452,6 +452,8 @@ vc4_hvs_alloc_dlist_entry(struct vc4_hvs *hvs, if (!alloc) return ERR_PTR(-ENOMEM); + INIT_LIST_HEAD(&alloc->node); + spin_lock_irqsave(&hvs->mm_lock, flags); ret = drm_mm_insert_node(&hvs->dlist_mm, &alloc->mm_node, dlist_count); From 030b9e41a03f15a76e29f300490c1ea5eae1769e Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Wed, 25 Jan 2023 12:54:36 +0100 Subject: [PATCH 038/688] drm/vc4: hvs: Move the dlist allocation destruction to a function We'll need to destroy a dlist allocation in multiple code paths, so let's move it to a separate function. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/vc4/vc4_hvs.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c index 1a133e22bd99d4..d77f39f5e8ecd5 100644 --- a/drivers/gpu/drm/vc4/vc4_hvs.c +++ b/drivers/gpu/drm/vc4/vc4_hvs.c @@ -466,6 +466,18 @@ vc4_hvs_alloc_dlist_entry(struct vc4_hvs *hvs, return alloc; } +static void vc4_hvs_free_dlist_entry_locked(struct vc4_hvs *hvs, + struct vc4_hvs_dlist_allocation *alloc) +{ + lockdep_assert_held(&hvs->mm_lock); + + if (!list_empty(&alloc->node)) + list_del(&alloc->node); + + drm_mm_remove_node(&alloc->mm_node); + kfree(alloc); +} + void vc4_hvs_mark_dlist_entry_stale(struct vc4_hvs *hvs, struct vc4_hvs_dlist_allocation *alloc) { @@ -553,9 +565,7 @@ static void vc4_hvs_dlist_free_work(struct work_struct *work) if (!vc4_hvs_frcnt_lte(cur->target_frame_count, frcnt)) continue; - list_del(&cur->node); - drm_mm_remove_node(&cur->mm_node); - kfree(cur); + vc4_hvs_free_dlist_entry_locked(hvs, cur); } spin_unlock_irqrestore(&hvs->mm_lock, flags); } From 4d26c1c06e7f4195147231dae7c93805346377e2 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Wed, 25 Jan 2023 13:05:26 +0100 Subject: [PATCH 039/688] drm/vc4: hvs: Destroy dlist allocations immediately when running a test When running a kunit test, the driver runs with a mock device. As such, any attempt to read or write to a hardware register will fail the current test immediately. The dlist allocation management recently introduced will read the current frame count from the HVS to defer its destruction until a subsequent frame has been output. This obviously involves a register read that fails the Kunit tests. Change the destruction deferral function to destroy the allocation immediately if we run under kunit. This is essentially harmless since the main reason for that deferall is to prevent any access to the hardware dlist while a frame described by that list is rendered. On our mock driver, we have neither a hardware dlist nor a rendering, so it doesn't matter. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/vc4/vc4_hvs.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c index d77f39f5e8ecd5..a0dd4738189af1 100644 --- a/drivers/gpu/drm/vc4/vc4_hvs.c +++ b/drivers/gpu/drm/vc4/vc4_hvs.c @@ -490,6 +490,18 @@ void vc4_hvs_mark_dlist_entry_stale(struct vc4_hvs *hvs, if (!drm_mm_node_allocated(&alloc->mm_node)) return; + /* + * Kunit tests run with a mock device and we consider any hardware + * access a test failure. Let's free the dlist allocation right away if + * we're running under kunit, we won't risk a dlist corruption anyway. + */ + if (kunit_get_current_test()) { + spin_lock_irqsave(&hvs->mm_lock, flags); + vc4_hvs_free_dlist_entry_locked(hvs, alloc); + spin_unlock_irqrestore(&hvs->mm_lock, flags); + return; + } + frcnt = vc4_hvs_get_fifo_frame_count(hvs, alloc->channel); alloc->target_frame_count = (frcnt + 1) & ((1 << 6) - 1); From 87677eb2dd7331e06ad4ad8a2a4c33470342206c Mon Sep 17 00:00:00 2001 From: Dom Cobley Date: Tue, 31 Jan 2023 15:14:32 +0000 Subject: [PATCH 040/688] drm/vc4_plane: Add support for YUV444 formats Support displaying DRM_FORMAT_YUV444 and DRM_FORMAT_YVU444 formats. Tested with kmstest and kodi. e.g. kmstest -r 1920x1080@60 -f 400x300-YU24 Note: without the shift of width, only half the chroma is fetched, resulting in correct left half of image and corrupt colours on right half. The increase in width shouldn't affect fetching of Y data, as the hardware will clamp at dest width. Signed-off-by: Dom Cobley --- drivers/gpu/drm/vc4/vc4_plane.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c index dbb8acfe48ea88..5c30d71272e6e8 100644 --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c @@ -109,6 +109,18 @@ static const struct hvs_format { .pixel_order = HVS_PIXEL_ORDER_XYCRCB, .pixel_order_hvs5 = HVS_PIXEL_ORDER_XYCRCB, }, + { + .drm = DRM_FORMAT_YUV444, + .hvs = HVS_PIXEL_FORMAT_YCBCR_YUV422_3PLANE, + .pixel_order = HVS_PIXEL_ORDER_XYCBCR, + .pixel_order_hvs5 = HVS_PIXEL_ORDER_XYCBCR, + }, + { + .drm = DRM_FORMAT_YVU444, + .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, @@ -1106,6 +1118,10 @@ static int vc4_plane_mode_set(struct drm_plane *plane, vc4_state->src_y + vc4_state->src_h[0] < (state->fb->height << 16)) height++; + /* for YUV444 hardware wants double the width, otherwise it doesn't fetch full width of chroma */ + if (format->drm == DRM_FORMAT_YUV444 || format->drm == DRM_FORMAT_YVU444) + width <<= 1; + /* 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. From d77103a2c9d47ee3fc07fd7e8b0d7b3897fa70e2 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Thu, 11 Aug 2022 13:59:34 +0100 Subject: [PATCH 041/688] 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 a0dd4738189af1..8198ddb89046a2 100644 --- a/drivers/gpu/drm/vc4/vc4_hvs.c +++ b/drivers/gpu/drm/vc4/vc4_hvs.c @@ -1352,6 +1352,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. From 68c109044558cc5a98b470032298e0f8b31a5704 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Mon, 6 Jun 2022 11:02:16 +0200 Subject: [PATCH 042/688] 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 b22d28ec80284b..e8751a40eef9cc 100644 --- a/arch/arm64/kernel/setup.c +++ b/arch/arm64/kernel/setup.c @@ -210,9 +210,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); From 59484b40dc00b1309a229c225e5484cebdaee9d9 Mon Sep 17 00:00:00 2001 From: Dom Cobley Date: Mon, 30 Sep 2024 16:40:14 +0100 Subject: [PATCH 043/688] 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 kbuild: Silence unavoidable dtc overlay warnings Much effort has been put into finding ways to avoid warnings from dtc about overlays, usually to do with the presence of #address-cells and size-cells, but not exclusively so. Since the issues being warned about are harmless, suppress the warnings to declutter the build output and to avoid alarming users. Signed-off-by: Phil Elwell overlays: Suppress another dtc warning I'm sure the dtc warnings mean well, but overlays don't have enough context for the checkers to give meaningful results. Signed-off-by: Phil Elwell overlays: Use dtbs-list for overlay installation Update the overlay build rules to use the dtbs-list mechanism. Also include the README, and don't set the executable bits. Signed-off-by: Phil Elwell --- arch/arm/boot/dts/Makefile | 5 + arch/arm/boot/dts/broadcom/Makefile | 35 + .../boot/dts/broadcom/bcm2708-rpi-b-plus.dts | 210 + .../boot/dts/broadcom/bcm2708-rpi-b-rev1.dts | 223 + arch/arm/boot/dts/broadcom/bcm2708-rpi-b.dts | 198 + .../arm/boot/dts/broadcom/bcm2708-rpi-bt.dtsi | 38 + arch/arm/boot/dts/broadcom/bcm2708-rpi-cm.dts | 174 + .../arm/boot/dts/broadcom/bcm2708-rpi-cm.dtsi | 23 + .../boot/dts/broadcom/bcm2708-rpi-zero-w.dts | 254 + .../boot/dts/broadcom/bcm2708-rpi-zero.dts | 189 + arch/arm/boot/dts/broadcom/bcm2708-rpi.dtsi | 63 + arch/arm/boot/dts/broadcom/bcm2708.dtsi | 19 + .../arm/boot/dts/broadcom/bcm2709-rpi-2-b.dts | 204 + .../arm/boot/dts/broadcom/bcm2709-rpi-cm2.dts | 215 + arch/arm/boot/dts/broadcom/bcm2709-rpi.dtsi | 8 + arch/arm/boot/dts/broadcom/bcm2709.dtsi | 29 + arch/arm/boot/dts/broadcom/bcm270x-rpi.dtsi | 201 + arch/arm/boot/dts/broadcom/bcm270x.dtsi | 264 + .../arm/boot/dts/broadcom/bcm2710-rpi-2-b.dts | 204 + .../dts/broadcom/bcm2710-rpi-3-b-plus.dts | 299 + .../arm/boot/dts/broadcom/bcm2710-rpi-3-b.dts | 297 + .../arm/boot/dts/broadcom/bcm2710-rpi-cm3.dts | 215 + .../dts/broadcom/bcm2710-rpi-zero-2-w.dts | 261 + .../boot/dts/broadcom/bcm2710-rpi-zero-2.dts | 1 + arch/arm/boot/dts/broadcom/bcm2710.dtsi | 32 + .../arm/boot/dts/broadcom/bcm2711-rpi-4-b.dts | 270 +- .../arm/boot/dts/broadcom/bcm2711-rpi-400.dts | 49 +- .../arm/boot/dts/broadcom/bcm2711-rpi-cm4.dts | 503 ++ .../boot/dts/broadcom/bcm2711-rpi-cm4s.dts | 293 + .../arm/boot/dts/broadcom/bcm2711-rpi-ds.dtsi | 561 ++ arch/arm/boot/dts/broadcom/bcm2711-rpi.dtsi | 13 + arch/arm/boot/dts/broadcom/bcm2711.dtsi | 2 +- .../arm/boot/dts/broadcom/bcm271x-rpi-bt.dtsi | 38 + .../dts/broadcom/bcm283x-rpi-csi0-2lane.dtsi | 4 + .../dts/broadcom/bcm283x-rpi-csi1-2lane.dtsi | 4 + .../dts/broadcom/bcm283x-rpi-csi1-4lane.dtsi | 4 + .../broadcom/bcm283x-rpi-i2c0mux_0_28.dtsi | 4 + .../broadcom/bcm283x-rpi-i2c0mux_0_44.dtsi | 4 + arch/arm/boot/dts/broadcom/bcm283x.dtsi | 8 +- arch/arm/boot/dts/overlays/Makefile | 347 ++ arch/arm/boot/dts/overlays/README | 5535 +++++++++++++++++ .../arm/boot/dts/overlays/act-led-overlay.dts | 28 + .../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 | 135 + .../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 | 61 + .../overlays/allo-boss2-dac-audio-overlay.dts | 57 + .../dts/overlays/allo-digione-overlay.dts | 44 + .../allo-katana-dac-audio-overlay.dts | 58 + .../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 | 97 + arch/arm/boot/dts/overlays/arducam-64mp.dtsi | 34 + .../overlays/arducam-pivariety-overlay.dts | 100 + .../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 | 38 + .../boot/dts/overlays/balena-fin-overlay.dts | 125 + .../boot/dts/overlays/bcm2712d0-overlay.dts | 75 + .../dts/overlays/camera-mux-2port-overlay.dts | 545 ++ .../dts/overlays/camera-mux-4port-overlay.dts | 954 +++ .../arm/boot/dts/overlays/cap1106-overlay.dts | 52 + .../boot/dts/overlays/chipcap2-overlay.dts | 66 + .../boot/dts/overlays/chipdip-dac-overlay.dts | 46 + .../dts/overlays/cirrus-wm5102-overlay.dts | 172 + .../dts/overlays/cm-swap-i2c0-overlay.dts | 27 + arch/arm/boot/dts/overlays/cma-overlay.dts | 36 + .../crystalfontz-cfa050_pi_m-overlay.dts | 124 + .../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 | 59 + .../dts/overlays/disable-bt-pi5-overlay.dts | 17 + .../dts/overlays/disable-emmc2-overlay.dts | 13 + .../dts/overlays/disable-wifi-overlay.dts | 20 + .../dts/overlays/disable-wifi-pi5-overlay.dts | 13 + 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 | 46 + arch/arm/boot/dts/overlays/edt-ft5406.dtsi | 49 + .../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 + .../dts/overlays/gpio-charger-overlay.dts | 42 + .../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 + arch/arm/boot/dts/overlays/hat_map.dts | 124 + .../dts/overlays/hd44780-i2c-lcd-overlay.dts | 57 + .../boot/dts/overlays/hd44780-lcd-overlay.dts | 46 + .../hdmi-backlight-hwhack-gpio-overlay.dts | 47 + .../dts/overlays/hifiberry-adc-overlay.dts | 45 + .../dts/overlays/hifiberry-adc8x-overlay.dts | 50 + .../dts/overlays/hifiberry-amp-overlay.dts | 39 + .../dts/overlays/hifiberry-amp100-overlay.dts | 67 + .../dts/overlays/hifiberry-amp3-overlay.dts | 57 + .../overlays/hifiberry-amp4pro-overlay.dts | 63 + .../dts/overlays/hifiberry-dac-overlay.dts | 34 + .../dts/overlays/hifiberry-dac8x-overlay.dts | 50 + .../overlays/hifiberry-dacplus-overlay.dts | 68 + .../hifiberry-dacplus-pro-overlay.dts | 64 + .../hifiberry-dacplus-std-overlay.dts | 65 + .../overlays/hifiberry-dacplusadc-overlay.dts | 72 + .../hifiberry-dacplusadcpro-overlay.dts | 72 + .../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 | 183 + .../dts/overlays/i2c-pwm-pca9685a-overlay.dts | 61 + .../arm/boot/dts/overlays/i2c-rtc-common.dtsi | 367 ++ .../dts/overlays/i2c-rtc-gpio-overlay.dts | 31 + .../arm/boot/dts/overlays/i2c-rtc-overlay.dts | 42 + .../boot/dts/overlays/i2c-sensor-common.dtsi | 696 +++ .../boot/dts/overlays/i2c-sensor-overlay.dts | 42 + arch/arm/boot/dts/overlays/i2c0-overlay.dts | 83 + .../boot/dts/overlays/i2c0-pi5-overlay.dts | 34 + arch/arm/boot/dts/overlays/i2c1-overlay.dts | 44 + .../boot/dts/overlays/i2c1-pi5-overlay.dts | 34 + .../boot/dts/overlays/i2c2-pi5-overlay.dts | 21 + arch/arm/boot/dts/overlays/i2c3-overlay.dts | 34 + .../boot/dts/overlays/i2c3-pi5-overlay.dts | 22 + arch/arm/boot/dts/overlays/i2c4-overlay.dts | 34 + arch/arm/boot/dts/overlays/i2c5-overlay.dts | 34 + arch/arm/boot/dts/overlays/i2c6-overlay.dts | 34 + .../arm/boot/dts/overlays/i2s-dac-overlay.dts | 34 + .../dts/overlays/i2s-gpio28-31-overlay.dts | 18 + .../dts/overlays/i2s-master-dac-overlay.dts | 50 + .../boot/dts/overlays/ilitek251x-overlay.dts | 45 + arch/arm/boot/dts/overlays/imx219-overlay.dts | 95 + arch/arm/boot/dts/overlays/imx219.dtsi | 27 + arch/arm/boot/dts/overlays/imx258-overlay.dts | 137 + arch/arm/boot/dts/overlays/imx258.dtsi | 27 + arch/arm/boot/dts/overlays/imx290-overlay.dts | 32 + .../boot/dts/overlays/imx290_327-overlay.dtsi | 118 + arch/arm/boot/dts/overlays/imx290_327.dtsi | 24 + arch/arm/boot/dts/overlays/imx296-overlay.dts | 120 + arch/arm/boot/dts/overlays/imx327-overlay.dts | 33 + arch/arm/boot/dts/overlays/imx378-overlay.dts | 17 + arch/arm/boot/dts/overlays/imx462-overlay.dts | 39 + arch/arm/boot/dts/overlays/imx477-overlay.dts | 17 + .../boot/dts/overlays/imx477_378-overlay.dtsi | 98 + arch/arm/boot/dts/overlays/imx477_378.dtsi | 24 + arch/arm/boot/dts/overlays/imx500-overlay.dts | 120 + .../boot/dts/overlays/imx500-pi5-overlay.dts | 125 + arch/arm/boot/dts/overlays/imx500.dtsi | 28 + arch/arm/boot/dts/overlays/imx519-overlay.dts | 99 + arch/arm/boot/dts/overlays/imx519.dtsi | 34 + arch/arm/boot/dts/overlays/imx708-overlay.dts | 111 + arch/arm/boot/dts/overlays/imx708.dtsi | 35 + .../interludeaudio-analog-overlay.dts | 73 + .../interludeaudio-digital-overlay.dts | 49 + .../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 | 97 + .../dts/overlays/jedec-spi-nor-overlay.dts | 136 + .../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 | 103 + .../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 | 86 + .../boot/dts/overlays/merus-amp-overlay.dts | 59 + .../boot/dts/overlays/midi-uart0-overlay.dts | 36 + .../dts/overlays/midi-uart0-pi5-overlay.dts | 35 + .../boot/dts/overlays/midi-uart1-overlay.dts | 43 + .../dts/overlays/midi-uart1-pi5-overlay.dts | 35 + .../boot/dts/overlays/midi-uart2-overlay.dts | 37 + .../dts/overlays/midi-uart2-pi5-overlay.dts | 35 + .../boot/dts/overlays/midi-uart3-overlay.dts | 38 + .../dts/overlays/midi-uart3-pi5-overlay.dts | 35 + .../boot/dts/overlays/midi-uart4-overlay.dts | 38 + .../dts/overlays/midi-uart4-pi5-overlay.dts | 35 + .../boot/dts/overlays/midi-uart5-overlay.dts | 38 + .../boot/dts/overlays/minipitft13-overlay.dts | 70 + .../boot/dts/overlays/miniuart-bt-overlay.dts | 83 + .../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/mz61581-overlay.dts | 117 + arch/arm/boot/dts/overlays/ov2311-overlay.dts | 83 + arch/arm/boot/dts/overlays/ov2311.dtsi | 26 + arch/arm/boot/dts/overlays/ov5647-overlay.dts | 100 + arch/arm/boot/dts/overlays/ov5647.dtsi | 25 + .../arm/boot/dts/overlays/ov64a40-overlay.dts | 97 + arch/arm/boot/dts/overlays/ov64a40.dtsi | 34 + arch/arm/boot/dts/overlays/ov7251-overlay.dts | 83 + arch/arm/boot/dts/overlays/ov7251.dtsi | 28 + arch/arm/boot/dts/overlays/ov9281-overlay.dts | 84 + arch/arm/boot/dts/overlays/ov9281.dtsi | 27 + arch/arm/boot/dts/overlays/overlay_map.dts | 514 ++ .../arm/boot/dts/overlays/papirus-overlay.dts | 84 + .../arm/boot/dts/overlays/pca953x-overlay.dts | 240 + .../arm/boot/dts/overlays/pcf857x-overlay.dts | 32 + .../dts/overlays/pcie-32bit-dma-overlay.dts | 38 + .../overlays/pcie-32bit-dma-pi5-overlay.dts | 26 + .../overlays/pciex1-compat-pi5-overlay.dts | 60 + 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 + .../overlays/pineboards-hat-ai-overlay.dts | 18 + .../pineboards-hatdrive-poe-plus-overlay.dts | 19 + .../boot/dts/overlays/piscreen-overlay.dts | 110 + .../boot/dts/overlays/piscreen2r-overlay.dts | 106 + .../arm/boot/dts/overlays/pisound-overlay.dts | 118 + .../boot/dts/overlays/pisound-pi5-overlay.dts | 31 + .../arm/boot/dts/overlays/pitft22-overlay.dts | 71 + .../overlays/pitft28-capacitive-overlay.dts | 93 + .../overlays/pitft28-resistive-overlay.dts | 126 + .../overlays/pitft35-resistive-overlay.dts | 127 + .../boot/dts/overlays/pps-gpio-overlay.dts | 39 + .../boot/dts/overlays/proto-codec-overlay.dts | 39 + .../boot/dts/overlays/pwm-2chan-overlay.dts | 48 + .../boot/dts/overlays/pwm-ir-tx-overlay.dts | 40 + arch/arm/boot/dts/overlays/pwm-overlay.dts | 44 + arch/arm/boot/dts/overlays/pwm1-overlay.dts | 59 + .../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 + .../dts/overlays/rpi-rp2040-gpio-bridge.dtsi | 21 + .../boot/dts/overlays/rpi-sense-overlay.dts | 69 + .../dts/overlays/rpi-sense-v2-overlay.dts | 69 + 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 | 57 + .../dts/overlays/sc16is750-spi0-overlay.dts | 63 + .../dts/overlays/sc16is752-i2c-overlay.dts | 57 + .../dts/overlays/sc16is752-spi0-overlay.dts | 63 + .../dts/overlays/sc16is752-spi1-overlay.dts | 76 + arch/arm/boot/dts/overlays/sdhost-overlay.dts | 38 + arch/arm/boot/dts/overlays/sdio-overlay.dts | 77 + .../boot/dts/overlays/sdio-pi5-overlay.dts | 24 + .../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 + .../dts/overlays/spi2-1cs-pi5-overlay.dts | 33 + .../boot/dts/overlays/spi2-2cs-overlay.dts | 69 + .../dts/overlays/spi2-2cs-pi5-overlay.dts | 44 + .../boot/dts/overlays/spi2-3cs-overlay.dts | 81 + .../boot/dts/overlays/spi3-1cs-overlay.dts | 42 + .../dts/overlays/spi3-1cs-pi5-overlay.dts | 33 + .../boot/dts/overlays/spi3-2cs-overlay.dts | 54 + .../dts/overlays/spi3-2cs-pi5-overlay.dts | 44 + .../boot/dts/overlays/spi4-1cs-overlay.dts | 42 + .../boot/dts/overlays/spi4-2cs-overlay.dts | 54 + .../boot/dts/overlays/spi5-1cs-overlay.dts | 42 + .../dts/overlays/spi5-1cs-pi5-overlay.dts | 33 + .../boot/dts/overlays/spi5-2cs-overlay.dts | 54 + .../dts/overlays/spi5-2cs-pi5-overlay.dts | 44 + .../boot/dts/overlays/spi6-1cs-overlay.dts | 42 + .../boot/dts/overlays/spi6-2cs-overlay.dts | 54 + .../arm/boot/dts/overlays/ssd1306-overlay.dts | 36 + .../boot/dts/overlays/ssd1306-spi-overlay.dts | 85 + .../boot/dts/overlays/ssd1327-spi-overlay.dts | 70 + .../boot/dts/overlays/ssd1331-spi-overlay.dts | 83 + .../boot/dts/overlays/ssd1351-spi-overlay.dts | 83 + .../overlays/sunfounder-pipower3-overlay.dts | 44 + .../overlays/sunfounder-pironman5-overlay.dts | 55 + .../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 | 116 + .../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 + .../boot/dts/overlays/uart0-pi5-overlay.dts | 18 + arch/arm/boot/dts/overlays/uart1-overlay.dts | 38 + .../boot/dts/overlays/uart1-pi5-overlay.dts | 18 + arch/arm/boot/dts/overlays/uart2-overlay.dts | 25 + .../boot/dts/overlays/uart2-pi5-overlay.dts | 18 + arch/arm/boot/dts/overlays/uart3-overlay.dts | 25 + .../boot/dts/overlays/uart3-pi5-overlay.dts | 18 + arch/arm/boot/dts/overlays/uart4-overlay.dts | 25 + .../boot/dts/overlays/uart4-pi5-overlay.dts | 18 + arch/arm/boot/dts/overlays/uart5-overlay.dts | 25 + 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 | 46 + .../dts/overlays/vc4-fkms-v3d-pi4-overlay.dts | 50 + .../overlays/vc4-kms-dpi-generic-overlay.dts | 82 + .../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 | 124 + .../overlays/vc4-kms-dsi-generic-overlay.dts | 106 + .../vc4-kms-dsi-ili9881-5inch-overlay.dts | 122 + .../vc4-kms-dsi-ili9881-7inch-overlay.dts | 122 + .../vc4-kms-dsi-lt070me05000-overlay.dts | 69 + .../vc4-kms-dsi-lt070me05000-v2-overlay.dts | 64 + .../vc4-kms-dsi-waveshare-panel-overlay.dts | 133 + .../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-v3d-pi5-overlay.dts | 147 + .../dts/overlays/vc4-kms-vga666-overlay.dts | 107 + 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 + .../boot/dts/overlays/w1-gpio-pi5-overlay.dts | 15 + .../dts/overlays/w1-gpio-pullup-overlay.dts | 42 + .../overlays/w1-gpio-pullup-pi5-overlay.dts | 15 + 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 | 21 + .../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-cm4.dts | 1 + .../boot/dts/broadcom/bcm2711-rpi-cm4s.dts | 1 + arch/arm64/boot/dts/broadcom/bcm2712-ds.dtsi | 808 +++ .../boot/dts/broadcom/bcm2712-rpi-5-b.dts | 685 +- .../boot/dts/broadcom/bcm2712-rpi-500.dts | 142 + .../dts/broadcom/bcm2712-rpi-cm5-cm4io.dts | 20 + .../dts/broadcom/bcm2712-rpi-cm5-cm5io.dts | 10 + .../boot/dts/broadcom/bcm2712-rpi-cm5.dtsi | 728 +++ .../dts/broadcom/bcm2712-rpi-cm5l-cm4io.dts | 20 + .../dts/broadcom/bcm2712-rpi-cm5l-cm5io.dts | 10 + .../boot/dts/broadcom/bcm2712-rpi-cm5l.dtsi | 26 + arch/arm64/boot/dts/broadcom/bcm2712-rpi.dtsi | 462 ++ .../boot/dts/broadcom/bcm2712d0-rpi-5-b.dts | 107 + arch/arm64/boot/dts/broadcom/rp1.dtsi | 1289 ++++ arch/arm64/boot/dts/overlays | 1 + include/dt-bindings/gpio/gpio-fsm.h | 21 + scripts/Makefile.build | 67 +- scripts/Makefile.dtbinst | 9 +- scripts/Makefile.lib | 156 +- 427 files changed, 44658 insertions(+), 83 deletions(-) create mode 100644 arch/arm/boot/dts/broadcom/bcm2708-rpi-b-plus.dts create mode 100644 arch/arm/boot/dts/broadcom/bcm2708-rpi-b-rev1.dts create mode 100644 arch/arm/boot/dts/broadcom/bcm2708-rpi-b.dts create mode 100644 arch/arm/boot/dts/broadcom/bcm2708-rpi-bt.dtsi create mode 100644 arch/arm/boot/dts/broadcom/bcm2708-rpi-cm.dts create mode 100644 arch/arm/boot/dts/broadcom/bcm2708-rpi-cm.dtsi create mode 100644 arch/arm/boot/dts/broadcom/bcm2708-rpi-zero-w.dts create mode 100644 arch/arm/boot/dts/broadcom/bcm2708-rpi-zero.dts create mode 100644 arch/arm/boot/dts/broadcom/bcm2708-rpi.dtsi create mode 100644 arch/arm/boot/dts/broadcom/bcm2708.dtsi create mode 100644 arch/arm/boot/dts/broadcom/bcm2709-rpi-2-b.dts create mode 100644 arch/arm/boot/dts/broadcom/bcm2709-rpi-cm2.dts create mode 100644 arch/arm/boot/dts/broadcom/bcm2709-rpi.dtsi create mode 100644 arch/arm/boot/dts/broadcom/bcm2709.dtsi create mode 100644 arch/arm/boot/dts/broadcom/bcm270x-rpi.dtsi create mode 100644 arch/arm/boot/dts/broadcom/bcm270x.dtsi create mode 100644 arch/arm/boot/dts/broadcom/bcm2710-rpi-2-b.dts create mode 100644 arch/arm/boot/dts/broadcom/bcm2710-rpi-3-b-plus.dts create mode 100644 arch/arm/boot/dts/broadcom/bcm2710-rpi-3-b.dts create mode 100644 arch/arm/boot/dts/broadcom/bcm2710-rpi-cm3.dts create mode 100644 arch/arm/boot/dts/broadcom/bcm2710-rpi-zero-2-w.dts create mode 100644 arch/arm/boot/dts/broadcom/bcm2710-rpi-zero-2.dts create mode 100644 arch/arm/boot/dts/broadcom/bcm2710.dtsi create mode 100644 arch/arm/boot/dts/broadcom/bcm2711-rpi-cm4.dts create mode 100644 arch/arm/boot/dts/broadcom/bcm2711-rpi-cm4s.dts create mode 100644 arch/arm/boot/dts/broadcom/bcm2711-rpi-ds.dtsi create mode 100644 arch/arm/boot/dts/broadcom/bcm271x-rpi-bt.dtsi create mode 100644 arch/arm/boot/dts/broadcom/bcm283x-rpi-csi0-2lane.dtsi create mode 100644 arch/arm/boot/dts/broadcom/bcm283x-rpi-csi1-2lane.dtsi create mode 100644 arch/arm/boot/dts/broadcom/bcm283x-rpi-csi1-4lane.dtsi create mode 100644 arch/arm/boot/dts/broadcom/bcm283x-rpi-i2c0mux_0_28.dtsi create mode 100644 arch/arm/boot/dts/broadcom/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-64mp.dtsi 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/bcm2712d0-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/chipcap2-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/cm-swap-i2c0-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/cma-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/crystalfontz-cfa050_pi_m-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-bt-pi5-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/disable-emmc2-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/disable-wifi-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/disable-wifi-pi5-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-charger-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/hat_map.dts create mode 100644 arch/arm/boot/dts/overlays/hd44780-i2c-lcd-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-adc-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/hifiberry-adc8x-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-amp4pro-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/hifiberry-dac-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/hifiberry-dac8x-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/hifiberry-dacplus-pro-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/hifiberry-dacplus-std-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/i2c0-pi5-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/i2c1-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/i2c1-pi5-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/i2c2-pi5-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/i2c3-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/i2c3-pi5-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/i2s-master-dac-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/imx500-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/imx500-pi5-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/imx500.dtsi create mode 100644 arch/arm/boot/dts/overlays/imx519-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/imx519.dtsi create mode 100644 arch/arm/boot/dts/overlays/imx708-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/imx708.dtsi create mode 100644 arch/arm/boot/dts/overlays/interludeaudio-analog-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/interludeaudio-digital-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-uart0-pi5-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/midi-uart1-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/midi-uart1-pi5-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/midi-uart2-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/midi-uart2-pi5-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/midi-uart3-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/midi-uart3-pi5-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/midi-uart4-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/midi-uart4-pi5-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/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/ov64a40-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/ov64a40.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/pcf857x-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/pcie-32bit-dma-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/pcie-32bit-dma-pi5-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/pciex1-compat-pi5-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/pineboards-hat-ai-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/pineboards-hatdrive-poe-plus-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/pisound-pi5-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/pwm1-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-rp2040-gpio-bridge.dtsi 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/sc16is750-spi0-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/sdio-pi5-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-1cs-pi5-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/spi2-2cs-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/spi2-2cs-pi5-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-1cs-pi5-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/spi3-2cs-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/spi3-2cs-pi5-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-1cs-pi5-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/spi5-2cs-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/spi5-2cs-pi5-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/ssd1327-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 100644 arch/arm/boot/dts/overlays/sunfounder-pipower3-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/sunfounder-pironman5-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 100755 arch/arm/boot/dts/overlays/uart0-pi5-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/uart1-overlay.dts create mode 100755 arch/arm/boot/dts/overlays/uart1-pi5-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/uart2-overlay.dts create mode 100755 arch/arm/boot/dts/overlays/uart2-pi5-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/uart3-overlay.dts create mode 100755 arch/arm/boot/dts/overlays/uart3-pi5-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/uart4-overlay.dts create mode 100755 arch/arm/boot/dts/overlays/uart4-pi5-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-generic-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/vc4-kms-dsi-ili9881-5inch-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/vc4-kms-dsi-ili9881-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-dsi-waveshare-panel-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-v3d-pi5-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-pi5-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/w1-gpio-pullup-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/w1-gpio-pullup-pi5-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 100644 arch/arm64/boot/dts/broadcom/bcm2712-ds.dtsi create mode 100644 arch/arm64/boot/dts/broadcom/bcm2712-rpi-500.dts create mode 100644 arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5-cm4io.dts create mode 100644 arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5-cm5io.dts create mode 100644 arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5.dtsi create mode 100644 arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5l-cm4io.dts create mode 100644 arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5l-cm5io.dts create mode 100644 arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5l.dtsi create mode 100644 arch/arm64/boot/dts/broadcom/bcm2712-rpi.dtsi create mode 100644 arch/arm64/boot/dts/broadcom/bcm2712d0-rpi-5-b.dts create mode 100644 arch/arm64/boot/dts/broadcom/rp1.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 efe38eb2530164..a2a407fb5b281c 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -39,3 +39,8 @@ subdir-y += unisoc subdir-y += vt8500 subdir-y += xen subdir-y += xilinx + +targets += dtbs dtbs_install +targets += $(dtb-y) + +subdir-y += overlays diff --git a/arch/arm/boot/dts/broadcom/Makefile b/arch/arm/boot/dts/broadcom/Makefile index 5881bcc95eba6b..79d83e8a214df4 100644 --- a/arch/arm/boot/dts/broadcom/Makefile +++ b/arch/arm/boot/dts/broadcom/Makefile @@ -35,6 +35,41 @@ dtb-$(CONFIG_ARCH_BCM2835) += \ bcm2711-rpi-cm4-io.dtb \ bcm2835-rpi-zero.dtb \ bcm2835-rpi-zero-w.dtb + +DTC_FLAGS_bcm2708-rpi-b := -@ +DTC_FLAGS_bcm2708-rpi-b-rev1 := -@ +DTC_FLAGS_bcm2708-rpi-b-plus := -@ +DTC_FLAGS_bcm2708-rpi-cm := -@ +DTC_FLAGS_bcm2708-rpi-zero := -@ +DTC_FLAGS_bcm2708-rpi-zero-w := -@ +DTC_FLAGS_bcm2710-rpi-zero-2 := -@ +DTC_FLAGS_bcm2710-rpi-zero-2-w := -@ +DTC_FLAGS_bcm2709-rpi-2-b := -@ +DTC_FLAGS_bcm2710-rpi-2-b := -@ +DTC_FLAGS_bcm2710-rpi-3-b := -@ +DTC_FLAGS_bcm2710-rpi-3-b-plus := -@ +DTC_FLAGS_bcm2709-rpi-cm2 := -@ +DTC_FLAGS_bcm2710-rpi-cm3 := -@ +DTC_FLAGS_bcm2711-rpi-cm4 := -@ +DTC_FLAGS_bcm2711-rpi-cm4s := -@ +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 \ + bcm2709-rpi-cm2.dtb \ + bcm2710-rpi-cm3.dtb \ + bcm2711-rpi-cm4.dtb \ + bcm2711-rpi-cm4s.dtb + dtb-$(CONFIG_ARCH_BCMBCA) += \ bcm947622.dtb \ bcm963138.dtb \ diff --git a/arch/arm/boot/dts/broadcom/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/broadcom/bcm2708-rpi-b-plus.dts new file mode 100644 index 00000000000000..ee72fdac666368 --- /dev/null +++ b/arch/arm/boot/dts/broadcom/bcm2708-rpi-b-plus.dts @@ -0,0 +1,210 @@ +/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" +#include "bcm283x-rpi-led-deprecated.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", + "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", + "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>; +}; + +&led_act { + gpios = <&gpio 47 GPIO_ACTIVE_HIGH>; + default-state = "off"; + linux,default-trigger = "mmc0"; +}; + +&leds { + led_pwr: led-pwr { + label = "PWR"; + gpios = <&gpio 35 GPIO_ACTIVE_HIGH>; + default-state = "off"; + linux,default-trigger = "input"; + }; +}; + +&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 { +}; + +i2c_arm: &i2c1 { +}; + +i2c_vc: &i2c0 { +}; + +i2c_csi_dsi0: &i2c0 { +}; + +/ { + __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 = <&led_act>,"gpios:4"; + act_led_activelow = <&led_act>,"gpios:8"; + act_led_trigger = <&led_act>,"linux,default-trigger"; + + pwr_led_gpio = <&led_pwr>,"gpios:4"; + pwr_led_activelow = <&led_pwr>,"gpios:8"; + pwr_led_trigger = <&led_pwr>,"linux,default-trigger"; + }; +}; diff --git a/arch/arm/boot/dts/broadcom/bcm2708-rpi-b-rev1.dts b/arch/arm/boot/dts/broadcom/bcm2708-rpi-b-rev1.dts new file mode 100644 index 00000000000000..9301e345aea222 --- /dev/null +++ b/arch/arm/boot/dts/broadcom/bcm2708-rpi-b-rev1.dts @@ -0,0 +1,223 @@ +/dts-v1/; + +#include "bcm2708.dtsi" +#include "bcm2708-rpi.dtsi" +#include "bcm283x-rpi-smsc9512.dtsi" +#include "bcm283x-rpi-csi1-2lane.dtsi" +#include "bcm283x-rpi-led-deprecated.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>; +}; + +&led_act { + gpios = <&gpio 16 GPIO_ACTIVE_LOW>; + default-state = "off"; + linux,default-trigger = "mmc0"; +}; + +&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 { +}; + +i2c_arm: &i2c0 { +}; + +i2c_vc: &i2c1 { +}; + +i2c_csi_dsi0: &i2c0 { +}; + +/ { + __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 = <&led_act>,"gpios:4"; + act_led_activelow = <&led_act>,"gpios:8"; + act_led_trigger = <&led_act>,"linux,default-trigger"; + + i2c = <&i2c0>,"status"; + i2c_arm = <&i2c0>,"status"; + i2c_vc = <&i2c1>,"status"; + i2c_baudrate = <&i2c0>,"clock-frequency:0"; + i2c_arm_baudrate = <&i2c0>,"clock-frequency:0"; + i2c_vc_baudrate = <&i2c1>,"clock-frequency:0"; + }; +}; diff --git a/arch/arm/boot/dts/broadcom/bcm2708-rpi-b.dts b/arch/arm/boot/dts/broadcom/bcm2708-rpi-b.dts new file mode 100644 index 00000000000000..b8459fd0f49703 --- /dev/null +++ b/arch/arm/boot/dts/broadcom/bcm2708-rpi-b.dts @@ -0,0 +1,198 @@ +/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" +#include "bcm283x-rpi-led-deprecated.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>; +}; + +&led_act { + gpios = <&gpio 16 GPIO_ACTIVE_LOW>; + default-state = "off"; + linux,default-trigger = "mmc0"; +}; + +&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 { +}; + +i2c_arm: &i2c1 { +}; + +i2c_vc: &i2c0 { +}; + +i2c_csi_dsi0: &i2c0 { +}; + +/ { + __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 = <&led_act>,"gpios:4"; + act_led_activelow = <&led_act>,"gpios:8"; + act_led_trigger = <&led_act>,"linux,default-trigger"; + }; +}; diff --git a/arch/arm/boot/dts/broadcom/bcm2708-rpi-bt.dtsi b/arch/arm/boot/dts/broadcom/bcm2708-rpi-bt.dtsi new file mode 100644 index 00000000000000..98555528adaedf --- /dev/null +++ b/arch/arm/boot/dts/broadcom/bcm2708-rpi-bt.dtsi @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: GPL-2.0 + +&uart0 { + bt: bluetooth { + compatible = "brcm,bcm43438-bt"; + max-speed = <3000000>; + shutdown-gpios = <&gpio 45 GPIO_ACTIVE_HIGH>; + local-bd-address = [ 00 00 00 00 00 00 ]; + fallback-bd-address; // Don't override a valid address + status = "okay"; + }; +}; + +&uart1 { + minibt: bluetooth { + compatible = "brcm,bcm43438-bt"; + max-speed = <230400>; + shutdown-gpios = <&gpio 45 GPIO_ACTIVE_HIGH>; + local-bd-address = [ 00 00 00 00 00 00 ]; + fallback-bd-address; // Don't override a valid address + status = "disabled"; + }; +}; + +/ { + aliases { + bluetooth = &bt; + }; + + __overrides__ { + bdaddr = <&bt>,"local-bd-address[", + <&bt>,"fallback-bd-address?=0", + <&minibt>,"local-bd-address[", + <&minibt>,"fallback-bd-address?=0"; + krnbt = <&bt>,"status"; + krnbt_baudrate = <&bt>,"max-speed:0", <&minibt>,"max-speed:0"; + }; +}; diff --git a/arch/arm/boot/dts/broadcom/bcm2708-rpi-cm.dts b/arch/arm/boot/dts/broadcom/bcm2708-rpi-cm.dts new file mode 100644 index 00000000000000..fde85c8c7dca22 --- /dev/null +++ b/arch/arm/boot/dts/broadcom/bcm2708-rpi-cm.dts @@ -0,0 +1,174 @@ +/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 3 GPIO_ACTIVE_HIGH>; + status = "disabled"; +}; + +cam0_reg: &cam0_regulator { + gpio = <&gpio 31 GPIO_ACTIVE_HIGH>; +}; + +i2c_csi_dsi0: &i2c0 { +}; + +&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/broadcom/bcm2708-rpi-cm.dtsi b/arch/arm/boot/dts/broadcom/bcm2708-rpi-cm.dtsi new file mode 100644 index 00000000000000..8d3e42bfe4f08e --- /dev/null +++ b/arch/arm/boot/dts/broadcom/bcm2708-rpi-cm.dtsi @@ -0,0 +1,23 @@ +#include "bcm2708.dtsi" +#include "bcm2708-rpi.dtsi" +#include "bcm283x-rpi-led-deprecated.dtsi" + +&led_act { + gpios = <&gpio 47 GPIO_ACTIVE_HIGH>; + default-state = "off"; + linux,default-trigger = "mmc0"; +}; + +i2c_arm: &i2c1 { +}; + +i2c_vc: &i2c0 { +}; + +/ { + __overrides__ { + act_led_gpio = <&led_act>,"gpios:4"; + act_led_activelow = <&led_act>,"gpios:8"; + act_led_trigger = <&led_act>,"linux,default-trigger"; + }; +}; diff --git a/arch/arm/boot/dts/broadcom/bcm2708-rpi-zero-w.dts b/arch/arm/boot/dts/broadcom/bcm2708-rpi-zero-w.dts new file mode 100644 index 00000000000000..011d0fa4c9c0de --- /dev/null +++ b/arch/arm/boot/dts/broadcom/bcm2708-rpi-zero-w.dts @@ -0,0 +1,254 @@ +/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" +#include "bcm283x-rpi-led-deprecated.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", + "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", + "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; + }; + + uart1_bt_pins: uart1_bt_pins { + brcm,pins = <32 33 30 31>; + brcm,function = ; /* alt5=UART1 */ + brcm,pull = <0 2 2 0>; + }; + + 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>; +}; + +&led_act { + gpios = <&gpio 47 GPIO_ACTIVE_LOW>; + default-state = "off"; + linux,default-trigger = "actpwr"; +}; + +&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 { +}; + +i2c_arm: &i2c1 {}; +i2c_vc: &i2c0 {}; +i2c_csi_dsi0: &i2c0 {}; + +/ { + __overrides__ { + audio = <&chosen>,"bootargs{on='snd_bcm2835.enable_hdmi=1',off='snd_bcm2835.enable_hdmi=0'}"; + + act_led_gpio = <&led_act>,"gpios:4"; + act_led_activelow = <&led_act>,"gpios:8"; + act_led_trigger = <&led_act>,"linux,default-trigger"; + }; +}; diff --git a/arch/arm/boot/dts/broadcom/bcm2708-rpi-zero.dts b/arch/arm/boot/dts/broadcom/bcm2708-rpi-zero.dts new file mode 100644 index 00000000000000..1721be8dbe20a6 --- /dev/null +++ b/arch/arm/boot/dts/broadcom/bcm2708-rpi-zero.dts @@ -0,0 +1,189 @@ +/dts-v1/; + +#include "bcm2708.dtsi" +#include "bcm2708-rpi.dtsi" +#include "bcm283x-rpi-csi1-2lane.dtsi" +#include "bcm283x-rpi-i2c0mux_0_28.dtsi" +#include "bcm283x-rpi-led-deprecated.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", + "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", + "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>; +}; + +&led_act { + gpios = <&gpio 47 GPIO_ACTIVE_LOW>; + default-state = "off"; + linux,default-trigger = "actpwr"; +}; + +&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 { +}; + +i2c_arm: &i2c1 {}; +i2c_vc: &i2c0 {}; +i2c_csi_dsi0: &i2c0 {}; + +/ { + __overrides__ { + audio = <&chosen>,"bootargs{on='snd_bcm2835.enable_hdmi=1',off='snd_bcm2835.enable_hdmi=0'}"; + + act_led_gpio = <&led_act>,"gpios:4"; + act_led_activelow = <&led_act>,"gpios:8"; + act_led_trigger = <&led_act>,"linux,default-trigger"; + }; +}; diff --git a/arch/arm/boot/dts/broadcom/bcm2708-rpi.dtsi b/arch/arm/boot/dts/broadcom/bcm2708-rpi.dtsi new file mode 100644 index 00000000000000..f4aedb5c532b51 --- /dev/null +++ b/arch/arm/boot/dts/broadcom/bcm2708-rpi.dtsi @@ -0,0 +1,63 @@ +/* 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"; + nvmem_cust_rw = <&nvmem_cust>,"rw?"; + sd = <&sdhost>,"status"; + sd_poll_once = <&sdhost>,"non-removable?"; + }; +}; + +&soc { + nvmem { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + + nvmem_otp: nvmem_otp { + compatible = "raspberrypi,rpi-otp"; + firmware = <&firmware>; + reg = <0 192>; + status = "okay"; + }; + + nvmem_cust: nvmem_cust { + compatible = "raspberrypi,rpi-otp"; + firmware = <&firmware>; + reg = <1 8>; + status = "okay"; + }; + }; +}; + +&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/broadcom/bcm2708.dtsi b/arch/arm/boot/dts/broadcom/bcm2708.dtsi new file mode 100644 index 00000000000000..fdc7f2423bbe62 --- /dev/null +++ b/arch/arm/boot/dts/broadcom/bcm2708.dtsi @@ -0,0 +1,19 @@ +#define i2c0 i2c0if +#include "bcm2835.dtsi" +#undef i2c0 +#include "bcm270x.dtsi" + +/ { + __overrides__ { + arm_freq; + }; +}; + +&soc { + dma-ranges = <0x80000000 0x00000000 0x20000000>, + <0x7e000000 0x20000000 0x02000000>; +}; + +&vc4 { + status = "disabled"; +}; diff --git a/arch/arm/boot/dts/broadcom/bcm2709-rpi-2-b.dts b/arch/arm/boot/dts/broadcom/bcm2709-rpi-2-b.dts new file mode 100644 index 00000000000000..7796e545da43fb --- /dev/null +++ b/arch/arm/boot/dts/broadcom/bcm2709-rpi-2-b.dts @@ -0,0 +1,204 @@ +/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" +#include "bcm283x-rpi-led-deprecated.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", + "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", + "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>; +}; + +&led_act { + gpios = <&gpio 47 GPIO_ACTIVE_HIGH>; + default-state = "off"; + linux,default-trigger = "mmc0"; +}; + +&leds { + led_pwr: led-pwr { + label = "PWR"; + gpios = <&gpio 35 GPIO_ACTIVE_HIGH>; + default-state = "off"; + linux,default-trigger = "input"; + }; +}; + +&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 { +}; + +i2c_csi_dsi0: &i2c0 { +}; + +/ { + __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 = <&led_act>,"gpios:4"; + act_led_activelow = <&led_act>,"gpios:8"; + act_led_trigger = <&led_act>,"linux,default-trigger"; + + pwr_led_gpio = <&led_pwr>,"gpios:4"; + pwr_led_activelow = <&led_pwr>,"gpios:8"; + pwr_led_trigger = <&led_pwr>,"linux,default-trigger"; + }; +}; diff --git a/arch/arm/boot/dts/broadcom/bcm2709-rpi-cm2.dts b/arch/arm/boot/dts/broadcom/bcm2709-rpi-cm2.dts new file mode 100644 index 00000000000000..36d00aa889a39a --- /dev/null +++ b/arch/arm/boot/dts/broadcom/bcm2709-rpi-cm2.dts @@ -0,0 +1,215 @@ +/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" +#include "bcm283x-rpi-led-deprecated.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>; +}; + +i2c_csi_dsi0: &i2c0 { +}; + +&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; + }; +}; + +&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"; + }; + + virtgpio: virtgpio { + compatible = "brcm,bcm2835-virtgpio"; + gpio-controller; + #gpio-cells = <2>; + 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>; +}; + +&led_act { + gpios = <&virtgpio 0 GPIO_ACTIVE_HIGH>; + default-state = "off"; + linux,default-trigger = "mmc0"; +}; + +&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 = <&led_act>,"gpios:4"; + act_led_activelow = <&led_act>,"gpios:8"; + act_led_trigger = <&led_act>,"linux,default-trigger"; + }; +}; diff --git a/arch/arm/boot/dts/broadcom/bcm2709-rpi.dtsi b/arch/arm/boot/dts/broadcom/bcm2709-rpi.dtsi new file mode 100644 index 00000000000000..7335e7fbcb7144 --- /dev/null +++ b/arch/arm/boot/dts/broadcom/bcm2709-rpi.dtsi @@ -0,0 +1,8 @@ +#include "bcm2708-rpi.dtsi" + +&vchiq { + compatible = "brcm,bcm2836-vchiq", "brcm,bcm2835-vchiq"; +}; + +i2c_arm: &i2c1 {}; +i2c_vc: &i2c0 {}; diff --git a/arch/arm/boot/dts/broadcom/bcm2709.dtsi b/arch/arm/boot/dts/broadcom/bcm2709.dtsi new file mode 100644 index 00000000000000..868f65f922ff4d --- /dev/null +++ b/arch/arm/boot/dts/broadcom/bcm2709.dtsi @@ -0,0 +1,29 @@ +#define i2c0 i2c0if +#include "bcm2836.dtsi" +#undef i2c0 +#include "bcm270x.dtsi" + +/ { + soc { + ranges = <0x7e000000 0x3f000000 0x01000000>, + <0x40000000 0x40000000 0x00040000>; + + dma-ranges = <0xc0000000 0x00000000 0x3f000000>, + <0x7e000000 0x3f000000 0x01000000>; + }; + + __overrides__ { + arm_freq = <&v7_cpu0>, "clock-frequency:0", + <&v7_cpu1>, "clock-frequency:0", + <&v7_cpu2>, "clock-frequency:0", + <&v7_cpu3>, "clock-frequency:0"; + }; +}; + +&system_timer { + status = "disabled"; +}; + +&vc4 { + status = "disabled"; +}; diff --git a/arch/arm/boot/dts/broadcom/bcm270x-rpi.dtsi b/arch/arm/boot/dts/broadcom/bcm270x-rpi.dtsi new file mode 100644 index 00000000000000..eeef9788d64929 --- /dev/null +++ b/arch/arm/boot/dts/broadcom/bcm270x-rpi.dtsi @@ -0,0 +1,201 @@ +/* Downstream modifications to bcm2835-rpi.dtsi */ + +/ { + aliases: 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; + i2c = &i2c_arm; + 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"; + }; + + 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"; + i2c = <&i2c1>,"status"; + i2c_arm = <&i2c1>,"status"; + i2c_vc = <&i2c0if>,"status",<&i2c0mux>,"status"; + i2c0_baudrate = <&i2c0if>,"clock-frequency:0"; + i2c1_baudrate = <&i2c1>,"clock-frequency:0"; + i2c_baudrate = <&i2c1>,"clock-frequency:0"; + i2c_arm_baudrate = <&i2c1>,"clock-frequency:0"; + i2c_vc_baudrate = <&i2c0if>,"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"; + drm_fb0_vc4 = <&aliases>, "drm-fb0=",&vc4; + drm_fb1_vc4 = <&aliases>, "drm-fb1=",&vc4; + drm_fb2_vc4 = <&aliases>, "drm-fb2=",&vc4; + + cam1_sync = <&csi1>, "sync-gpios:0=", <&gpio>, + <&csi1>, "sync-gpios:4", + <&csi1>, "sync-gpios:8=", ; + cam1_sync_inverted = <&csi1>, "sync-gpios:0=", <&gpio>, + <&csi1>, "sync-gpios:4", + <&csi1>, "sync-gpios:8=", ; + cam0_sync = <&csi0>, "sync-gpios:0=", <&gpio>, + <&csi0>, "sync-gpios:4", + <&csi0>, "sync-gpios:8=", ; + cam0_sync_inverted = <&csi0>, "sync-gpios:0=", <&gpio>, + <&csi0>, "sync-gpios:4", + <&csi0>, "sync-gpios:8=", ; + + cam0_reg = <&cam0_reg>,"status"; + cam0_reg_gpio = <&cam0_reg>,"gpio:4", + <&cam0_reg>,"gpio:0=", <&gpio>; + cam1_reg = <&cam1_reg>,"status"; + cam1_reg_gpio = <&cam1_reg>,"gpio:4", + <&cam1_reg>,"gpio:0=", <&gpio>; + + strict_gpiod = <&chosen>, "bootargs=pinctrl_bcm2835.persist_gpio_outputs=n"; + }; +}; + +&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"; +}; + +i2s_clk_producer: &i2s {}; +i2s_clk_consumer: &i2s {}; + +&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 { + 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/broadcom/bcm270x.dtsi b/arch/arm/boot/dts/broadcom/bcm270x.dtsi new file mode 100644 index 00000000000000..187f95f93a203e --- /dev/null +++ b/arch/arm/boot/dts/broadcom/bcm270x.dtsi @@ -0,0 +1,264 @@ +/* Downstream bcm283x.dtsi diff */ +#include + +/ { + chosen: chosen { + // Disable audio by default + bootargs = "coherent_pool=1M snd_bcm2835.enable_headphones=0"; + stdout-path = "serial0:115200n8"; + }; + + 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"; + }; + +#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/broadcom/bcm2710-rpi-2-b.dts b/arch/arm/boot/dts/broadcom/bcm2710-rpi-2-b.dts new file mode 100644 index 00000000000000..ce48eb6073f0cd --- /dev/null +++ b/arch/arm/boot/dts/broadcom/bcm2710-rpi-2-b.dts @@ -0,0 +1,204 @@ +/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" +#include "bcm283x-rpi-led-deprecated.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", + "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", + "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>; +}; + +&led_act { + gpios = <&gpio 47 GPIO_ACTIVE_HIGH>; + default-state = "off"; + linux,default-trigger = "mmc0"; +}; + +&leds { + led_pwr: led-pwr { + label = "PWR"; + gpios = <&gpio 35 GPIO_ACTIVE_HIGH>; + default-state = "off"; + linux,default-trigger = "input"; + }; +}; + +&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 { +}; + +i2c_csi_dsi0: &i2c0 { +}; + +/ { + __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 = <&led_act>,"gpios:4"; + act_led_activelow = <&led_act>,"gpios:8"; + act_led_trigger = <&led_act>,"linux,default-trigger"; + + pwr_led_gpio = <&led_pwr>,"gpios:4"; + pwr_led_activelow = <&led_pwr>,"gpios:8"; + pwr_led_trigger = <&led_pwr>,"linux,default-trigger"; + }; +}; diff --git a/arch/arm/boot/dts/broadcom/bcm2710-rpi-3-b-plus.dts b/arch/arm/boot/dts/broadcom/bcm2710-rpi-3-b-plus.dts new file mode 100644 index 00000000000000..1afbb90117025b --- /dev/null +++ b/arch/arm/boot/dts/broadcom/bcm2710-rpi-3-b-plus.dts @@ -0,0 +1,299 @@ +/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" +#include "bcm283x-rpi-led-deprecated.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", + "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", + "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; + }; + + uart1_bt_pins: uart1_bt_pins { + brcm,pins = <32 33 30 31>; + brcm,function = ; /* alt5=UART1 */ + brcm,pull = <0 2 2 0>; + }; + + 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>; +}; + +&led_act { + gpios = <&gpio 29 GPIO_ACTIVE_HIGH>; + default-state = "off"; + linux,default-trigger = "mmc0"; +}; + +&leds { + led_pwr: led-pwr { + label = "PWR"; + gpios = <&expgpio 2 GPIO_ACTIVE_LOW>; + default-state = "off"; + linux,default-trigger = "default-on"; + }; +}; + +&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 { +}; + +i2c_csi_dsi0: &i2c0 { +}; + +/ { + __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 = <&led_act>,"gpios:4"; + act_led_activelow = <&led_act>,"gpios:8"; + act_led_trigger = <&led_act>,"linux,default-trigger"; + + pwr_led_gpio = <&led_pwr>,"gpios:4"; + pwr_led_activelow = <&led_pwr>,"gpios:8"; + pwr_led_trigger = <&led_pwr>,"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/broadcom/bcm2710-rpi-3-b.dts b/arch/arm/boot/dts/broadcom/bcm2710-rpi-3-b.dts new file mode 100644 index 00000000000000..b893affe69974c --- /dev/null +++ b/arch/arm/boot/dts/broadcom/bcm2710-rpi-3-b.dts @@ -0,0 +1,297 @@ +/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" +#include "bcm283x-rpi-led-deprecated.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", + "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", + "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; + }; + + uart1_bt_pins: uart1_bt_pins { + brcm,pins = <32 33>; + brcm,function = ; /* alt5=UART1 */ + brcm,pull = <0 2>; + }; + + 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", + "STATUS_LED", + "LAN_RUN", + "HDMI_HPD_N", + "CAM_GPIO0", + "CAM_GPIO1", + "PWR_LOW_N"; + status = "okay"; + }; + + virtgpio: virtgpio { + compatible = "brcm,bcm2835-virtgpio"; + gpio-controller; + #gpio-cells = <2>; + 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>; +}; + +&led_act { + gpios = <&virtgpio 0 GPIO_ACTIVE_HIGH>; + default-state = "off"; + linux,default-trigger = "mmc0"; +}; + +&leds { + led_pwr: led-pwr { + label = "PWR"; + gpios = <&expgpio 7 GPIO_ACTIVE_HIGH>; + default-state = "off"; + linux,default-trigger = "input"; + }; +}; + +&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 { +}; + +i2c_csi_dsi0: &i2c0 { +}; + +/ { + __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 = <&led_act>,"gpios:4"; + act_led_activelow = <&led_act>,"gpios:8"; + act_led_trigger = <&led_act>,"linux,default-trigger"; + + pwr_led_gpio = <&led_pwr>,"gpios:4"; + pwr_led_activelow = <&led_pwr>,"gpios:8"; + pwr_led_trigger = <&led_pwr>,"linux,default-trigger"; + }; +}; diff --git a/arch/arm/boot/dts/broadcom/bcm2710-rpi-cm3.dts b/arch/arm/boot/dts/broadcom/bcm2710-rpi-cm3.dts new file mode 100644 index 00000000000000..0d6e9e61f87751 --- /dev/null +++ b/arch/arm/boot/dts/broadcom/bcm2710-rpi-cm3.dts @@ -0,0 +1,215 @@ +/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" +#include "bcm283x-rpi-led-deprecated.dtsi" + +/ { + compatible = "raspberrypi,3-compute-module", "brcm,bcm2837"; + model = "Raspberry Pi Compute Module 3"; +}; + +&cam1_reg { + gpio = <&gpio 3 GPIO_ACTIVE_HIGH>; + status = "disabled"; +}; + +cam0_reg: &cam0_regulator { + gpio = <&gpio 31 GPIO_ACTIVE_HIGH>; +}; + +i2c_csi_dsi0: &i2c0 { +}; + +&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; + }; +}; + +&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"; + }; + + virtgpio: virtgpio { + compatible = "brcm,bcm2835-virtgpio"; + gpio-controller; + #gpio-cells = <2>; + 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>; +}; + +&led_act { + gpios = <&virtgpio 0 GPIO_ACTIVE_HIGH>; + default-state = "off"; + linux,default-trigger = "mmc0"; +}; + +&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 = <&led_act>,"gpios:4"; + act_led_activelow = <&led_act>,"gpios:8"; + act_led_trigger = <&led_act>,"linux,default-trigger"; + }; +}; diff --git a/arch/arm/boot/dts/broadcom/bcm2710-rpi-zero-2-w.dts b/arch/arm/boot/dts/broadcom/bcm2710-rpi-zero-2-w.dts new file mode 100644 index 00000000000000..25182d73f24411 --- /dev/null +++ b/arch/arm/boot/dts/broadcom/bcm2710-rpi-zero-2-w.dts @@ -0,0 +1,261 @@ +/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" +#include "bcm283x-rpi-led-deprecated.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", + "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", + "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; + }; + + uart1_bt_pins: uart1_bt_pins { + brcm,pins = <32 33 30 31>; + brcm,function = ; /* alt5=UART1 */ + brcm,pull = <0 2 2 0>; + }; + + 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>; +}; + +&led_act { + gpios = <&gpio 29 GPIO_ACTIVE_LOW>; + default-state = "off"; + linux,default-trigger = "actpwr"; +}; + +&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 { +}; + +i2c_csi_dsi0: &i2c0 { +}; + +/ { + __overrides__ { + audio = <&chosen>,"bootargs{on='snd_bcm2835.enable_hdmi=1',off='snd_bcm2835.enable_hdmi=0'}"; + + act_led_gpio = <&led_act>,"gpios:4"; + act_led_activelow = <&led_act>,"gpios:8"; + act_led_trigger = <&led_act>,"linux,default-trigger"; + }; +}; diff --git a/arch/arm/boot/dts/broadcom/bcm2710-rpi-zero-2.dts b/arch/arm/boot/dts/broadcom/bcm2710-rpi-zero-2.dts new file mode 100644 index 00000000000000..daa12bd30d6b6e --- /dev/null +++ b/arch/arm/boot/dts/broadcom/bcm2710-rpi-zero-2.dts @@ -0,0 +1 @@ +#include "bcm2710-rpi-zero-2-w.dts" diff --git a/arch/arm/boot/dts/broadcom/bcm2710.dtsi b/arch/arm/boot/dts/broadcom/bcm2710.dtsi new file mode 100644 index 00000000000000..bdcdbb51fab834 --- /dev/null +++ b/arch/arm/boot/dts/broadcom/bcm2710.dtsi @@ -0,0 +1,32 @@ +#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 { + dma-ranges = <0xc0000000 0x00000000 0x3f000000>, + <0x7e000000 0x3f000000 0x01000000>; + }; + + __overrides__ { + arm_freq = <&cpu0>, "clock-frequency:0", + <&cpu1>, "clock-frequency:0", + <&cpu2>, "clock-frequency:0", + <&cpu3>, "clock-frequency:0"; + }; +}; + +&system_timer { + status = "disabled"; +}; + +&vc4 { + status = "disabled"; +}; diff --git a/arch/arm/boot/dts/broadcom/bcm2711-rpi-4-b.dts b/arch/arm/boot/dts/broadcom/bcm2711-rpi-4-b.dts index 353bb50ce5425c..3906f7cc25af78 100644 --- a/arch/arm/boot/dts/broadcom/bcm2711-rpi-4-b.dts +++ b/arch/arm/boot/dts/broadcom/bcm2711-rpi-4-b.dts @@ -1,11 +1,19 @@ // SPDX-License-Identifier: GPL-2.0 /dts-v1/; +#define BCM2711 +#define i2c0 i2c0if #include "bcm2711.dtsi" #include "bcm2711-rpi.dtsi" +/delete-node/&i2c0mux; #include "bcm283x-rpi-led-deprecated.dtsi" -#include "bcm283x-rpi-usb-peripheral.dtsi" #include "bcm283x-rpi-wifi-bt.dtsi" #include +#undef i2c0 +#include "bcm270x.dtsi" +#define i2c0 i2c0mux +#undef i2c0 + +/delete-node/ &cam1_reg; / { compatible = "raspberrypi,4-model-b", "brcm,bcm2711"; @@ -68,7 +76,7 @@ "VDD_SD_IO_SEL", "CAM_GPIO", /* 5 */ "SD_PWR_ON", - ""; + "SD_OC_N"; }; &gpio { @@ -82,21 +90,21 @@ */ gpio-line-names = "ID_SDA", /* 0 */ "ID_SCL", - "SDA1", - "SCL1", - "GPIO_GCLK", + "GPIO2", + "GPIO3", + "GPIO4", "GPIO5", /* 5 */ "GPIO6", - "SPI_CE1_N", - "SPI_CE0_N", - "SPI_MISO", - "SPI_MOSI", /* 10 */ - "SPI_SCLK", + "GPIO7", + "GPIO8", + "GPIO9", + "GPIO10", /* 10 */ + "GPIO11", "GPIO12", "GPIO13", /* Serial port */ - "TXD1", - "RXD1", /* 15 */ + "GPIO14", + "GPIO15", /* 15 */ "GPIO16", "GPIO17", "GPIO18", @@ -214,7 +222,7 @@ led@0 { reg = <0>; color = ; - function = LED_FUNCTION_LAN; + function = "lan";//LED_FUNCTION_LAN; default-state = "keep"; }; @@ -222,7 +230,7 @@ led@1 { reg = <1>; color = ; - function = LED_FUNCTION_LAN; + function = "lan";//LED_FUNCTION_LAN; default-state = "keep"; }; }; @@ -270,3 +278,237 @@ &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; + }; +}; + +&phy1 { + /delete-node/ leds; +}; + +#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"; + }; + + /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 { + gpio-line-names = "ID_SDA", + "ID_SCL", + "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", + "RGMII_MDIO", + "RGMIO_MDC", + /* Used by BT module */ + "CTS0", /* 30 */ + "RTS0", + "TXD0", + "RXD0", + /* Used by Wifi */ + "SD1_CLK", + "SD1_CMD", /* 35 */ + "SD1_DATA0", + "SD1_DATA1", + "SD1_DATA2", + "SD1_DATA3", + /* Shared with SPI flash */ + "PWM0_MISO", /* 40 */ + "PWM1_MOSI", + "STATUS_LED_G_CLK", + "SPIFLASH_CE_N", + "SDA0", + "SCL0", /* 45 */ + "RGMII_RXCLK", + "RGMII_RXCTL", + "RGMII_RXD0", + "RGMII_RXD1", + "RGMII_RXD2", /* 50 */ + "RGMII_RXD3", + "RGMII_TXCLK", + "RGMII_TXCTL", + "RGMII_TXD0", + "RGMII_TXD1", /* 55 */ + "RGMII_TXD2", + "RGMII_TXD3"; + + 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; + }; + + uart1_bt_pins: uart1_bt_pins { + brcm,pins = <32 33 30 31>; + brcm,function = ; /* alt5=UART1 */ + brcm,pull = <0 2 2 0>; + }; +}; + +&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>; + }; +}; + +&led_act { + default-state = "off"; + linux,default-trigger = "mmc0"; +}; + +&led_pwr { + default-state = "off"; +}; + +&pwm1 { + status = "disabled"; +}; + +&vchiq { + pinctrl-names = "default"; + pinctrl-0 = <&audio_pins>; +}; + +&cam1_reg { + gpio = <&expgpio 5 GPIO_ACTIVE_HIGH>; +}; + +cam0_reg: &cam_dummy_reg { +}; + +i2c_csi_dsi0: &i2c0 { +}; + +/ { + __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 = <&led_act>,"gpios:4"; + act_led_activelow = <&led_act>,"gpios:8"; + act_led_trigger = <&led_act>,"linux,default-trigger"; + + pwr_led_gpio = <&led_pwr>,"gpios:4"; + pwr_led_activelow = <&led_pwr>,"gpios:8"; + pwr_led_trigger = <&led_pwr>,"linux,default-trigger"; + + eth_led0 = <&phy1>,"led-modes:0"; + eth_led1 = <&phy1>,"led-modes:4"; + }; +}; diff --git a/arch/arm/boot/dts/broadcom/bcm2711-rpi-400.dts b/arch/arm/boot/dts/broadcom/bcm2711-rpi-400.dts index ca9be91b4f3654..553fb0e2469647 100644 --- a/arch/arm/boot/dts/broadcom/bcm2711-rpi-400.dts +++ b/arch/arm/boot/dts/broadcom/bcm2711-rpi-400.dts @@ -37,8 +37,53 @@ gpios = <&gpio 42 GPIO_ACTIVE_HIGH>; }; -/delete-node/ &led_act; - &pm { /delete-property/ system-power-controller; }; + +// ============================================= +// Downstream rpi- changes + +/ { + chosen { + stdout-path = "serial0:115200n8"; + }; +}; + +&audio_pins { + brcm,pins = <>; + brcm,function = <>; +}; + +// Declare the LED but leave it disabled, in case a user wants to map it +// to a GPIO on the header +&led_act { + default-state = "off"; + gpios = <&gpio 0 GPIO_ACTIVE_HIGH>; + status = "disabled"; +}; + +&led_pwr { + default-state = "off"; +}; + +&cam1_reg { + /delete-property/ gpio; +}; + +cam0_reg: &cam_dummy_reg { +}; + +/ { + __overrides__ { + audio = <&chosen>,"bootargs{on='snd_bcm2835.enable_hdmi=1',off='snd_bcm2835.enable_hdmi=0'}"; + + act_led_gpio = <&led_act>,"gpios:4", + <&led_act>,"status=okay"; + act_led_activelow = <&led_act>,"gpios:8"; + act_led_trigger = <&led_act>,"linux,default-trigger"; + pwr_led_gpio = <&led_pwr>,"gpios:4"; + pwr_led_activelow = <&led_pwr>,"gpios:8"; + pwr_led_trigger = <&led_pwr>,"linux,default-trigger"; + }; +}; diff --git a/arch/arm/boot/dts/broadcom/bcm2711-rpi-cm4.dts b/arch/arm/boot/dts/broadcom/bcm2711-rpi-cm4.dts new file mode 100644 index 00000000000000..d876f3d8f0bd9b --- /dev/null +++ b/arch/arm/boot/dts/broadcom/bcm2711-rpi-cm4.dts @@ -0,0 +1,503 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; +#define BCM2711 +#define i2c0 i2c0if +#include "bcm2711.dtsi" +#include "bcm2711-rpi.dtsi" +/delete-node/&i2c0mux; +#include "bcm283x-rpi-led-deprecated.dtsi" +#include "bcm283x-rpi-wifi-bt.dtsi" +#undef i2c0 +#include "bcm270x.dtsi" +#define i2c0 i2c0mux +#undef i2c0 + +/ { + compatible = "raspberrypi,4-compute-module", "brcm,bcm2711"; + model = "Raspberry Pi Compute Module 4"; + + chosen { + /* 8250 auxiliary UART instead of pl011 */ + stdout-path = "serial1:115200n8"; + }; + + 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"; +}; + +&led_act { + gpios = <&gpio 42 GPIO_ACTIVE_HIGH>; +}; + +&leds { + led_pwr: led-pwr { + label = "PWR"; + gpios = <&expgpio 2 GPIO_ACTIVE_LOW>; + default-state = "keep"; + linux,default-trigger = "default-on"; + }; +}; + +&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"; + }; + + /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 { + gpio-line-names = "ID_SDA", + "ID_SCL", + "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", + "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"; + + 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; + }; + + uart1_bt_pins: uart1_bt_pins { + brcm,pins = <32 33 30 31>; + brcm,function = ; /* alt5=UART1 */ + brcm,pull = <0 2 2 0>; + }; +}; + +&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 = <>; + }; +}; + +&led_act { + default-state = "off"; + linux,default-trigger = "mmc0"; +}; + +&led_pwr { + default-state = "off"; +}; + +&pwm1 { + status = "disabled"; +}; + +&vchiq { + pinctrl-names = "default"; + pinctrl-0 = <&audio_pins>; +}; + +cam0_reg: &cam1_reg { + gpio = <&expgpio 5 GPIO_ACTIVE_HIGH>; +}; + +i2c_csi_dsi0: &i2c0 { +}; + +/ { + __overrides__ { + audio = <&chosen>,"bootargs{on='snd_bcm2835.enable_hdmi=1',off='snd_bcm2835.enable_hdmi=0'}"; + + act_led_gpio = <&led_act>,"gpios:4"; + act_led_activelow = <&led_act>,"gpios:8"; + act_led_trigger = <&led_act>,"linux,default-trigger"; + + pwr_led_gpio = <&led_pwr>,"gpios:4"; + pwr_led_activelow = <&led_pwr>,"gpios:8"; + pwr_led_trigger = <&led_pwr>,"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"; + + pcie_tperst_clk_ms = <&pcie0>,"brcm,tperst-clk-ms:0"; + }; +}; diff --git a/arch/arm/boot/dts/broadcom/bcm2711-rpi-cm4s.dts b/arch/arm/boot/dts/broadcom/bcm2711-rpi-cm4s.dts new file mode 100644 index 00000000000000..0a0dfcb733ec57 --- /dev/null +++ b/arch/arm/boot/dts/broadcom/bcm2711-rpi-cm4s.dts @@ -0,0 +1,293 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; +#define BCM2711 +#define i2c0 i2c0if +#include "bcm2711.dtsi" +#include "bcm2711-rpi.dtsi" +/delete-node/&i2c0mux; +#include "bcm283x-rpi-led-deprecated.dtsi" +#undef i2c0 +#include "bcm270x.dtsi" +#define i2c0 i2c0mux +#undef i2c0 + +/ { + compatible = "raspberrypi,4-compute-module-s", "brcm,bcm2711"; + model = "Raspberry Pi Compute Module 4S"; +}; + +&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", + "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", + "PWM0_MISO", + "PWM1_MOSI", + "GPIO42", + "GPIO43", + "GPIO44", + "GPIO45"; +}; + +&hdmi0 { + status = "okay"; +}; + +&led_act { + gpios = <&virtgpio 0 GPIO_ACTIVE_HIGH>; +}; + +&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; + }; +}; + +#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; + serial1 = &uart1; + /delete-property/ i2c20; + /delete-property/ i2c21; + }; + + /delete-node/ wifi-pwrseq; +}; + +&firmware { + virtgpio: virtgpio { + compatible = "brcm,bcm2835-virtgpio"; + gpio-controller; + #gpio-cells = <2>; + status = "okay"; + }; +}; + +&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 { + uart0_pins: uart0_pins { + brcm,pins; + brcm,function; + brcm,pull; + }; +}; + +&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"; +}; + +&led_act { + default-state = "off"; + linux,default-trigger = "mmc0"; +}; + +&pwm1 { + status = "disabled"; +}; + +&vchiq { + pinctrl-names = "default"; + pinctrl-0 = <&audio_pins>; +}; + +&cam1_reg { + gpio = <&gpio 3 GPIO_ACTIVE_HIGH>; + status = "disabled"; +}; + +cam0_reg: &cam0_regulator { + gpio = <&gpio 31 GPIO_ACTIVE_HIGH>; + status = "disabled"; +}; + +i2c_csi_dsi0: &i2c0 { +}; + +/ { + __overrides__ { + audio = <&chosen>,"bootargs{on='snd_bcm2835.enable_hdmi=1',off='snd_bcm2835.enable_hdmi=0'}"; + + act_led_gpio = <&led_act>,"gpios:4"; + act_led_activelow = <&led_act>,"gpios:8"; + act_led_trigger = <&led_act>,"linux,default-trigger"; + }; +}; diff --git a/arch/arm/boot/dts/broadcom/bcm2711-rpi-ds.dtsi b/arch/arm/boot/dts/broadcom/bcm2711-rpi-ds.dtsi new file mode 100644 index 00000000000000..d44bf7bcc7777f --- /dev/null +++ b/arch/arm/boot/dts/broadcom/bcm2711-rpi-ds.dtsi @@ -0,0 +1,561 @@ +// SPDX-License-Identifier: GPL-2.0 +#include "bcm270x-rpi.dtsi" + +/ { + chosen: chosen { + }; + + __overrides__ { + arm_freq; + eee = <&chosen>,"bootargs{on='',off='genet.eee=N'}"; + hdmi = <&hdmi0>,"status", + <&hdmi1>,"status"; + nvmem_cust_rw = <&nvmem_cust>,"rw?"; + nvmem_priv_rw = <&nvmem_priv>,"rw?"; + pcie = <&pcie0>,"status"; + sd = <&emmc2>,"status"; + + sd_poll_once = <&emmc2>, "non-removable?"; + spi_dma4 = <&spi0>, "dmas:0=", <&dma40>, + <&spi0>, "dmas:8=", <&dma40>; + i2s_dma4 = <&i2s>, "dmas:0=", <&dma40>, + <&i2s>, "dmas:8=", <&dma40>; + }; + + scb: scb { + /* Add a label */ + }; + + soc: soc { + /* Add a label */ + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + aliases { + uart2 = &uart2; + uart3 = &uart3; + uart4 = &uart4; + uart5 = &uart5; + serial0 = &uart1; + serial1 = &uart0; + serial2 = &uart2; + serial3 = &uart3; + serial4 = &uart4; + serial5 = &uart5; + 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; + }; + + /* + * Add a node with a dma-ranges value that exists only to be found + * by of_dma_get_max_cpu_address, and hence limit the DMA zone. + */ + zone_dma { + #address-cells = <1>; + #size-cells = <1>; + dma-ranges = <0x0 0x0 0x0 0x40000000>; + }; +}; + +&vc4 { + raspberrypi,firmware = <&firmware>; +}; + +&cma { + /* Limit cma to the lower 768MB to allow room for HIGHMEM on 32-bit */ + alloc-ranges = <0x0 0x00000000 0x30000000>; +}; + +&soc { + /* Add the physical <-> DMA mapping for the I/O space */ + dma-ranges = <0xc0000000 0x0 0x00000000 0x40000000>, + <0x7c000000 0x0 0xfc000000 0x03800000>; + nvmem { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + + nvmem_otp: nvmem_otp { + compatible = "raspberrypi,rpi-otp"; + firmware = <&firmware>; + reg = <0 166>; + status = "okay"; + }; + + nvmem_cust: nvmem_cust { + compatible = "raspberrypi,rpi-otp"; + firmware = <&firmware>; + reg = <1 8>; + status = "okay"; + }; + + nvmem_priv: nvmem_priv { + compatible = "raspberrypi,rpi-otp"; + firmware = <&firmware>; + reg = <3 8>; + status = "okay"; + }; + }; +}; + +&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 = <0x4 0x7c000000 0x0 0xfc000000 0x0 0x03800000>, + <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 = , + ; + + 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>; + }; + + 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>; + }; +}; + +&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 = <&dma40 (10|(1<<30)|(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 = <&dma40 (17|(1<<30)|(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 = ; +}; + +i2c_arm: &i2c1 {}; +i2c_vc: &i2c0 {}; + +&i2c3 { + pinctrl-0 = <&i2c3_pins>; + pinctrl-names = "default"; +}; + +&i2c4 { + pinctrl-0 = <&i2c4_pins>; + pinctrl-names = "default"; +}; + +&i2c5 { + pinctrl-0 = <&i2c5_pins>; + pinctrl-names = "default"; +}; + +&i2c6 { + pinctrl-0 = <&i2c6_pins>; + pinctrl-names = "default"; +}; + +&spi3 { + pinctrl-0 = <&spi3_pins &spi3_cs_pins>; + pinctrl-names = "default"; +}; + +&spi4 { + pinctrl-0 = <&spi4_pins &spi4_cs_pins>; + pinctrl-names = "default"; +}; + +&spi5 { + pinctrl-0 = <&spi5_pins &spi5_cs_pins>; + pinctrl-names = "default"; +}; + +&spi6 { + pinctrl-0 = <&spi6_pins &spi6_cs_pins>; + pinctrl-names = "default"; +}; + +&uart2 { + pinctrl-0 = <&uart2_pins>; + pinctrl-names = "default"; +}; + +&uart3 { + pinctrl-0 = <&uart3_pins>; + pinctrl-names = "default"; +}; + +&uart4 { + pinctrl-0 = <&uart4_pins>; + pinctrl-names = "default"; +}; + +&uart5 { + pinctrl-0 = <&uart5_pins>; + pinctrl-names = "default"; +}; + +&axiperf { + compatible = "brcm,bcm2711-axiperf"; +}; + +/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/broadcom/bcm2711-rpi.dtsi b/arch/arm/boot/dts/broadcom/bcm2711-rpi.dtsi index c78ed064d1667d..da5f54e7dd2447 100644 --- a/arch/arm/boot/dts/broadcom/bcm2711-rpi.dtsi +++ b/arch/arm/boot/dts/broadcom/bcm2711-rpi.dtsi @@ -15,6 +15,7 @@ ethernet0 = &genet; pcie0 = &pcie0; blconfig = &blconfig; + blpubkey = &blpubkey; }; i2c0mux: i2c-mux0 { @@ -91,6 +92,18 @@ 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/broadcom/bcm2711.dtsi b/arch/arm/boot/dts/broadcom/bcm2711.dtsi index 93174b596373b2..f24b518772dd68 100644 --- a/arch/arm/boot/dts/broadcom/bcm2711.dtsi +++ b/arch/arm/boot/dts/broadcom/bcm2711.dtsi @@ -277,7 +277,7 @@ reg = <0x7e20c800 0x28>; clocks = <&clocks BCM2835_CLOCK_PWM>; assigned-clocks = <&clocks BCM2835_CLOCK_PWM>; - assigned-clock-rates = <10000000>; + assigned-clock-rates = <50000000>; #pwm-cells = <3>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/broadcom/bcm271x-rpi-bt.dtsi b/arch/arm/boot/dts/broadcom/bcm271x-rpi-bt.dtsi new file mode 100644 index 00000000000000..400efdc5f03cbd --- /dev/null +++ b/arch/arm/boot/dts/broadcom/bcm271x-rpi-bt.dtsi @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: GPL-2.0 + +&uart0 { + bt: bluetooth { + compatible = "brcm,bcm43438-bt"; + max-speed = <3000000>; + shutdown-gpios = <&expgpio 0 GPIO_ACTIVE_HIGH>; + local-bd-address = [ 00 00 00 00 00 00 ]; + fallback-bd-address; // Don't override a valid address + status = "okay"; + }; +}; + +&uart1 { + minibt: bluetooth { + compatible = "brcm,bcm43438-bt"; + max-speed = <230400>; + shutdown-gpios = <&expgpio 0 GPIO_ACTIVE_HIGH>; + local-bd-address = [ 00 00 00 00 00 00 ]; + fallback-bd-address; // Don't override a valid address + status = "disabled"; + }; +}; + +/ { + aliases { + bluetooth = &bt; + }; + + __overrides__ { + bdaddr = <&bt>,"local-bd-address[", + <&bt>,"fallback-bd-address?=0", + <&minibt>,"local-bd-address[", + <&minibt>,"fallback-bd-address?=0"; + krnbt = <&bt>,"status"; + krnbt_baudrate = <&bt>,"max-speed:0", <&minibt>,"max-speed:0"; + }; +}; diff --git a/arch/arm/boot/dts/broadcom/bcm283x-rpi-csi0-2lane.dtsi b/arch/arm/boot/dts/broadcom/bcm283x-rpi-csi0-2lane.dtsi new file mode 100644 index 00000000000000..6e4ce8622b4774 --- /dev/null +++ b/arch/arm/boot/dts/broadcom/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/broadcom/bcm283x-rpi-csi1-2lane.dtsi b/arch/arm/boot/dts/broadcom/bcm283x-rpi-csi1-2lane.dtsi new file mode 100644 index 00000000000000..6938f4daacdc20 --- /dev/null +++ b/arch/arm/boot/dts/broadcom/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/broadcom/bcm283x-rpi-csi1-4lane.dtsi b/arch/arm/boot/dts/broadcom/bcm283x-rpi-csi1-4lane.dtsi new file mode 100644 index 00000000000000..b37037437beed2 --- /dev/null +++ b/arch/arm/boot/dts/broadcom/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/broadcom/bcm283x-rpi-i2c0mux_0_28.dtsi b/arch/arm/boot/dts/broadcom/bcm283x-rpi-i2c0mux_0_28.dtsi new file mode 100644 index 00000000000000..38f0074bce3ff9 --- /dev/null +++ b/arch/arm/boot/dts/broadcom/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/broadcom/bcm283x-rpi-i2c0mux_0_44.dtsi b/arch/arm/boot/dts/broadcom/bcm283x-rpi-i2c0mux_0_44.dtsi new file mode 100644 index 00000000000000..119946d878dbf2 --- /dev/null +++ b/arch/arm/boot/dts/broadcom/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/broadcom/bcm283x.dtsi b/arch/arm/boot/dts/broadcom/bcm283x.dtsi index 69b0919f1324ab..562c4e9d08cc0a 100644 --- a/arch/arm/boot/dts/broadcom/bcm283x.dtsi +++ b/arch/arm/boot/dts/broadcom/bcm283x.dtsi @@ -363,7 +363,7 @@ #size-cells = <0>; #clock-cells = <1>; - clocks = <&clocks BCM2835_PLLA_DSI0>, + clocks = <&clocks BCM2835_PLLD_DSI0>, <&clocks BCM2835_CLOCK_DSI0E>, <&clocks BCM2835_CLOCK_DSI0P>; clock-names = "phy", "escape", "pixel"; @@ -415,7 +415,7 @@ reg = <0x7e20c000 0x28>; clocks = <&clocks BCM2835_CLOCK_PWM>; assigned-clocks = <&clocks BCM2835_CLOCK_PWM>; - assigned-clock-rates = <10000000>; + assigned-clock-rates = <50000000>; #pwm-cells = <3>; status = "disabled"; }; @@ -502,6 +502,10 @@ }; clocks { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + /* The oscillator is the root of the clock tree. */ clk_osc: clk-osc { compatible = "fixed-clock"; diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile new file mode 100644 index 00000000000000..e14dc0857327a8 --- /dev/null +++ b/arch/arm/boot/dts/overlays/Makefile @@ -0,0 +1,347 @@ +# Overlays for the Raspberry Pi platform + +dtb-$(CONFIG_ARCH_BCM2835) += overlay_map.dtb hat_map.dtb README + +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 \ + bcm2712d0.dtbo \ + camera-mux-2port.dtbo \ + camera-mux-4port.dtbo \ + cap1106.dtbo \ + chipcap2.dtbo \ + chipdip-dac.dtbo \ + cirrus-wm5102.dtbo \ + cm-swap-i2c0.dtbo \ + cma.dtbo \ + crystalfontz-cfa050_pi_m.dtbo \ + cutiepi-panel.dtbo \ + dacberry400.dtbo \ + dht11.dtbo \ + dionaudio-kiwi.dtbo \ + dionaudio-loco.dtbo \ + dionaudio-loco-v2.dtbo \ + disable-bt.dtbo \ + disable-bt-pi5.dtbo \ + disable-emmc2.dtbo \ + disable-wifi.dtbo \ + disable-wifi-pi5.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-charger.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-i2c-lcd.dtbo \ + hd44780-lcd.dtbo \ + hdmi-backlight-hwhack-gpio.dtbo \ + hifiberry-adc.dtbo \ + hifiberry-adc8x.dtbo \ + hifiberry-amp.dtbo \ + hifiberry-amp100.dtbo \ + hifiberry-amp3.dtbo \ + hifiberry-amp4pro.dtbo \ + hifiberry-dac.dtbo \ + hifiberry-dac8x.dtbo \ + hifiberry-dacplus.dtbo \ + hifiberry-dacplus-pro.dtbo \ + hifiberry-dacplus-std.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 \ + i2c0-pi5.dtbo \ + i2c1.dtbo \ + i2c1-pi5.dtbo \ + i2c2-pi5.dtbo \ + i2c3.dtbo \ + i2c3-pi5.dtbo \ + i2c4.dtbo \ + i2c5.dtbo \ + i2c6.dtbo \ + i2s-dac.dtbo \ + i2s-gpio28-31.dtbo \ + i2s-master-dac.dtbo \ + ilitek251x.dtbo \ + imx219.dtbo \ + imx258.dtbo \ + imx290.dtbo \ + imx296.dtbo \ + imx327.dtbo \ + imx378.dtbo \ + imx462.dtbo \ + imx477.dtbo \ + imx500.dtbo \ + imx500-pi5.dtbo \ + imx519.dtbo \ + imx708.dtbo \ + interludeaudio-analog.dtbo \ + interludeaudio-digital.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-uart0-pi5.dtbo \ + midi-uart1.dtbo \ + midi-uart1-pi5.dtbo \ + midi-uart2.dtbo \ + midi-uart2-pi5.dtbo \ + midi-uart3.dtbo \ + midi-uart3-pi5.dtbo \ + midi-uart4.dtbo \ + midi-uart4-pi5.dtbo \ + midi-uart5.dtbo \ + minipitft13.dtbo \ + miniuart-bt.dtbo \ + mipi-dbi-spi.dtbo \ + mlx90640.dtbo \ + mmc.dtbo \ + mz61581.dtbo \ + ov2311.dtbo \ + ov5647.dtbo \ + ov64a40.dtbo \ + ov7251.dtbo \ + ov9281.dtbo \ + papirus.dtbo \ + pca953x.dtbo \ + pcf857x.dtbo \ + pcie-32bit-dma.dtbo \ + pcie-32bit-dma-pi5.dtbo \ + pciex1-compat-pi5.dtbo \ + pibell.dtbo \ + pifacedigital.dtbo \ + pifi-40.dtbo \ + pifi-dac-hd.dtbo \ + pifi-dac-zero.dtbo \ + pifi-mini-210.dtbo \ + piglow.dtbo \ + pineboards-hat-ai.dtbo \ + pineboards-hatdrive-poe-plus.dtbo \ + piscreen.dtbo \ + piscreen2r.dtbo \ + pisound.dtbo \ + pisound-pi5.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 \ + pwm1.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 \ + sc16is750-spi0.dtbo \ + sc16is752-i2c.dtbo \ + sc16is752-spi0.dtbo \ + sc16is752-spi1.dtbo \ + sdhost.dtbo \ + sdio.dtbo \ + sdio-pi5.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-1cs-pi5.dtbo \ + spi2-2cs.dtbo \ + spi2-2cs-pi5.dtbo \ + spi2-3cs.dtbo \ + spi3-1cs.dtbo \ + spi3-1cs-pi5.dtbo \ + spi3-2cs.dtbo \ + spi3-2cs-pi5.dtbo \ + spi4-1cs.dtbo \ + spi4-2cs.dtbo \ + spi5-1cs.dtbo \ + spi5-1cs-pi5.dtbo \ + spi5-2cs.dtbo \ + spi5-2cs-pi5.dtbo \ + spi6-1cs.dtbo \ + spi6-2cs.dtbo \ + ssd1306.dtbo \ + ssd1306-spi.dtbo \ + ssd1327-spi.dtbo \ + ssd1331-spi.dtbo \ + ssd1351-spi.dtbo \ + sunfounder-pipower3.dtbo \ + sunfounder-pironman5.dtbo \ + superaudioboard.dtbo \ + sx150x.dtbo \ + tc358743.dtbo \ + tc358743-audio.dtbo \ + tinylcd35.dtbo \ + tpm-slb9670.dtbo \ + tpm-slb9673.dtbo \ + uart0.dtbo \ + uart0-pi5.dtbo \ + uart1.dtbo \ + uart1-pi5.dtbo \ + uart2.dtbo \ + uart2-pi5.dtbo \ + uart3.dtbo \ + uart3-pi5.dtbo \ + uart4.dtbo \ + uart4-pi5.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-generic.dtbo \ + vc4-kms-dsi-ili9881-5inch.dtbo \ + vc4-kms-dsi-ili9881-7inch.dtbo \ + vc4-kms-dsi-lt070me05000.dtbo \ + vc4-kms-dsi-lt070me05000-v2.dtbo \ + vc4-kms-dsi-waveshare-panel.dtbo \ + vc4-kms-kippah-7inch.dtbo \ + vc4-kms-v3d.dtbo \ + vc4-kms-v3d-pi4.dtbo \ + vc4-kms-v3d-pi5.dtbo \ + vc4-kms-vga666.dtbo \ + vga666.dtbo \ + vl805.dtbo \ + w1-gpio.dtbo \ + w1-gpio-pi5.dtbo \ + w1-gpio-pullup.dtbo \ + w1-gpio-pullup-pi5.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 00000000000000..1e17ca035c771b --- /dev/null +++ b/arch/arm/boot/dts/overlays/README @@ -0,0 +1,5535 @@ +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: + 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. + + ant1 Select antenna 1 (default). CM4/5 only. + + ant2 Select antenna 2. CM4/5 only. + + noant Disable both antennas. CM4/5 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. + + bdaddr Set an alternative Bluetooth address (BDADDR). + The value should be a 6-byte hexadecimal value, + with or without colon separators, written least- + significant-byte first. For example, + bdaddr=06:05:04:03:02:01 + will set the BDADDR to 01:02:03:04:05:06. + + button_debounce Set the debounce delay (in ms) on the power/ + shutdown button (default 50ms) + + cam0_reg Controls CAM 0 regulator. + Disabled by default on CM1 & 3. + Enabled by default on all other boards. + + cam0_reg_gpio Set GPIO for CAM 0 regulator. + NB override switches to the normal GPIO driver, + even if the original was on the GPIO expander. + + cam1_reg Controls CAM 1 regulator. + Disabled by default on CM1 & 3. + Enabled by default on all other boards. + + cam1_reg_gpio Set GPIO for CAM 1 regulator. + NB override switches to the normal GPIO driver, + even if the original was on the GPIO expander. + + cam0_sync Enable a GPIO to reflect frame sync from CSI0, + going high on frame start, and low on frame end. + + cam0_sync_inverted Enable a GPIO to reflect frame sync from CSI0 + going low on frame start, and high on frame end. + + cam1_sync Enable a GPIO to reflect frame sync from CSI1, + going high on frame start, and low on frame end. + + cam1_sync_inverted Enable a GPIO to reflect frame sync from CSI1 + going low on frame start, and high on frame end. + + cooling_fan Enables the Pi 5 cooling fan (enabled + automatically by the firmware) + + drm_fb0_rp1_dpi Assign /dev/fb0 to the RP1 DPI output + + drm_fb0_rp1_dsi0 Assign /dev/fb0 to the RP1 DSI0 output + + drm_fb0_rp1_dsi1 Assign /dev/fb0 to the RP1 DSI1 output + + drm_fb0_vc4 Assign /dev/fb0 to the vc4 outputs + + drm_fb1_rp1_dpi Assign /dev/fb1 to the RP1 DPI output + + drm_fb1_rp1_dsi0 Assign /dev/fb1 to the RP1 DSI0 output + + drm_fb1_rp1_dsi1 Assign /dev/fb1 to the RP1 DSI1 output + + drm_fb1_vc4 Assign /dev/fb1 to the vc4 outputs + + drm_fb2_rp1_dpi Assign /dev/fb2 to the RP1 DPI output + + drm_fb2_rp1_dsi0 Assign /dev/fb2 to the RP1 DSI0 output + + drm_fb2_rp1_dsi1 Assign /dev/fb2 to the RP1 DSI1 output + + drm_fb2_vc4 Assign /dev/fb2 to the vc4 outputs + + 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/5 (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/5 + + 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/5 (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. + + fan_temp0 Temperature threshold (in millicelcius) for + 1st cooling level (default 50000). Pi5 only. + fan_temp0_hyst Temperature hysteresis (in millicelcius) for + 1st cooling level (default 5000). Pi5 only. + fan_temp0_speed Fan PWM setting for 1st cooling level (0-255, + default 75). Pi5 only. + fan_temp1 Temperature threshold (in millicelcius) for + 2nd cooling level (default 60000). Pi5 only. + fan_temp1_hyst Temperature hysteresis (in millicelcius) for + 2nd cooling level (default 5000). Pi5 only. + fan_temp1_speed Fan PWM setting for 2nd cooling level (0-255, + default 125). Pi5 only. + fan_temp2 Temperature threshold (in millicelcius) for + 3rd cooling level (default 67500). Pi5 only. + fan_temp2_hyst Temperature hysteresis (in millicelcius) for + 3rd cooling level (default 5000). Pi5 only. + fan_temp2_speed Fan PWM setting for 3rd cooling level (0-255, + default 175). Pi5 only. + fan_temp3 Temperature threshold (in millicelcius) for + 4th cooling level (default 75000). Pi5 only. + fan_temp3_hyst Temperature hysteresis (in millicelcius) for + 4th cooling level (default 5000). Pi5 only. + fan_temp3_speed Fan PWM setting for 4th cooling level (0-255, + default 250). Pi5 only. + + hdmi Set to "off" to disable the HDMI interface + (default "on") + + i2c An alias for i2c_arm + + i2c_arm Set to "on" to enable the ARM's i2c interface + (default "off") + + i2c_arm_baudrate Set the baudrate of the ARM's i2c interface + (default "100000") + + i2c_baudrate An alias for i2c_arm_baudrate + + i2c_csi_dsi Set to "on" to enable the i2c_csi_dsi interface + + i2c_csi_dsi0 Set to "on" to enable the i2c_csi_dsi0 interface + + i2c_csi_dsi1 Set to "on" to enable the i2c_csi_dsi1 interface + + i2c_vc Set to "on" to enable the i2c interface + usually reserved for the VideoCore processor + (default "off") + + i2c_vc_baudrate Set the baudrate of the VideoCore i2c interface + (default "100000") + + i2s Set to "on" to enable the i2s interface + (default "off") + + i2s_dma4 Use to enable 40-bit DMA on the i2s interface + (the assigned value doesn't matter) + (2711 only) + + krnbt Set to "off" to disable autoprobing of Bluetooth + driver without need of hciattach/btattach + (default "on") + + krnbt_baudrate Set the baudrate of the PL011 UART when used + with krnbt=on + + nvme Alias for "pciex1" (2712 only) + + nvmem_cust_rw Allow read/write access to customer otp + + nvmem_mac_rw Allow read/write access to mac addresses otp + + nvmem_priv_rw Allow read/write access to customer private otp + + 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 + + pcie_tperst_clk_ms Add N milliseconds between PCIe reference clock + activation and PERST# deassertion + (CM4 and 2712, default "0") + + pciex1 Set to "on" to enable the external PCIe link + (2712 only, default "off") + + pciex1_gen Sets the PCIe "GEN"/speed for the external PCIe + link (2712 only, default "2") + + pciex1_no_l0s Set to "on" to disable ASPM L0s on the external + PCIe link for devices that have broken + implementations (2712 only, default "off") + + pciex1_tperst_clk_ms Alias for pcie_tperst_clk_ms + (2712 only, default "0") + + 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. + + random Set to "on" to enable the hardware random + number generator (default "on") + + rtc Set to "off" to disable the onboard Real Time + Clock (2712 only, default "on") + + rtc_bbat_vchg Set the RTC backup battery charging voltage in + microvolts. If set to 0 or not specified, the + trickle charger is disabled. + (2712 only, default "0") + + sd Set to "off" to disable the SD card (or eMMC on + non-lite SKU of CM4). + (default "on") + + sd_cqe Set to "off" to disable Command Queueing if you + have an incompatible Class A2 SD card + (Pi 5 only, 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. + + 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) + + strict_gpiod Return GPIOs to inputs when they are released. + If using the gpiod utilities, it is necessary + to keep a gpioset running (e.g. with + --mode=wait) in order for an output value to + persist. + + suspend Make the power button trigger a suspend rather + than a power-off (2712 only, default "off") + + 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") + + uart0_console Move the kernel boot console to UART0 on pins + 6, 8 and 10 of the 40-way header (2712 only, + default "off") + + uart1 Set to "on" or "off" to enable or disable uart1 + (default varies) + + watchdog Set to "on" to enable the hardware watchdog + (default "off") + + wifiaddr Set an alternative WiFi MAC address. + The value should be a 6-byte hexadecimal value, + with or without colon separators, written in the + natural (big-endian) order. + + 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) + i2c0 Choose the I2C0 bus on GPIOs 0&1 + i2c_csi_dsi Choose the I2C0 bus on GPIOs 44&45 + i2c3 Choose the I2C3 bus (configure with the i2c3 + overlay - BCM2711 only) + i2c4 Choose the I2C4 bus (configure with the i2c4 + overlay - BCM2711 only) + i2c5 Choose the I2C5 bus (configure with the i2c5 + overlay - BCM2711 only) + i2c6 Choose the I2C6 bus (configure with the i2c6 + overlay - BCM2711 only) + + 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). + vcm Select lens driver state. Default is enabled, + but vcm=off will disable. + + +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. Does + nothing on BCM2711 (default off) + pins_12_13 Select GPIOs 12 & 13 (default) + pins_18_19 Select GPIOs 18 & 19 + pins_40_41 Select GPIOs 40 & 41 (not available on CM4, used + for other purposes) + pins_40_45 Select GPIOs 40 & 45 (don't use on BCM2711 - the + pins are on different controllers) + + +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: bcm2712d0 +Info: Overlay encapsulating the BCM2712 C0->D0 differences +Load: dtoverlay=bcm2712d0 +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-arducam-64mp Select Arducam64MP for camera on port 0 + 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-imx519 Select IMX519 for camera on port 0 + cam0-imx708 Select IMX708 for camera on port 0 + cam0-ov2311 Select OV2311 for camera on port 0 + cam0-ov5647 Select OV5647 for camera on port 0 + cam0-ov64a40 Select OV64A40 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-arducam-64mp Select Arducam64MP for camera on port 1 + 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-imx519 Select IMX519 for camera on port 1 + cam1-imx708 Select IMX708 for camera on port 1 + cam1-ov2311 Select OV2311 for camera on port 1 + cam1-ov5647 Select OV5647 for camera on port 1 + cam1-ov64a40 Select OV64A40 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 + cam0-sync-source Set camera on port 0 as vsync source + cam0-sync-sink Set camera on port 0 as vsync sink + cam1-sync-source Set camera on port 1 as vsync source + cam1-sync-sink Set camera on port 1 as vsync sink + + cam0 Connect the mux to CAM0 port (default is CAM1) + + +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-arducam-64mp Select Arducam64MP for camera on port 0 + 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-imx519 Select IMX519 for camera on port 0 + cam0-imx708 Select IMX708 for camera on port 0 + cam0-ov2311 Select OV2311 for camera on port 0 + cam0-ov5647 Select OV5647 for camera on port 0 + cam0-ov64a40 Select OV64A40 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-arducam-64mp Select Arducam64MP for camera on port 1 + 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-imx519 Select IMX519 for camera on port 1 + cam1-imx708 Select IMX708 for camera on port 1 + cam1-ov2311 Select OV2311 for camera on port 1 + cam1-ov5647 Select OV5647 for camera on port 1 + cam1-ov64a40 Select OV64A40 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-arducam-64mp Select Arducam64MP for camera on port 2 + 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-imx519 Select IMX519 for camera on port 2 + cam2-imx708 Select IMX708 for camera on port 2 + cam2-ov2311 Select OV2311 for camera on port 2 + cam2-ov5647 Select OV5647 for camera on port 2 + cam2-ov64a40 Select OV64A40 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-arducam-64mp Select Arducam64MP for camera on port 3 + 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-imx519 Select IMX519 for camera on port 3 + cam3-imx708 Select IMX708 for camera on port 3 + cam3-ov2311 Select OV2311 for camera on port 3 + cam3-ov5647 Select OV5647 for camera on port 3 + cam3-ov64a40 Select OV64A40 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 + cam0-sync-source Set camera on port 0 as vsync source + cam0-sync-sink Set camera on port 0 as vsync sink + cam1-sync-source Set camera on port 1 as vsync source + cam1-sync-sink Set camera on port 1 as vsync sink + cam2-sync-source Set camera on port 2 as vsync source + cam2-sync-sink Set camera on port 2 as vsync sink + cam3-sync-source Set camera on port 3 as vsync source + cam3-sync-sink Set camera on port 3 as vsync sink + + cam0 Connect the mux to CAM0 port (default is CAM1) + + +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: chipcap2 +Info: Enables the Chipcap 2 humidity and temperature sensor. This device + provides low and high humidity alarms and requires a 3V3 dedicated + regulator to operate. +Load: dtoverlay=chipcap2,= +Params: ready_pin GPIO pin for ready signal (default 4) + + low_pin GPIO pin for low humidity signal (default 5) + + high_pin GPIO pin for high humidity signal (default 6) + + reg_pin GPIO pin to control the dedicated regulator + that powers the device (default 26) + + +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: cm-swap-i2c0 +Info: Largely for Compute Modules 1&3 where the original instructions for + adding a camera used GPIOs 0&1 for CAM1 and 28&29 for CAM0, whilst all + other platforms use 28&29 (or 44&45) for CAM1. + The default assignment through using this overlay is for + i2c0 to use 28&29, and i2c10 (aka i2c_csi_dsi) to use 28&29, but the + overrides allow this to be changed. +Load: dtoverlay=cm-swap-i2c0,= +Params: i2c0-gpio0 Use GPIOs 0&1 for i2c0 + i2c0-gpio28 Use GPIOs 28&29 for i2c0 (default) + i2c0-gpio44 Use GPIOs 44&45 for i2c0 + i2c10-gpio0 Use GPIOs 0&1 for i2c0 (default) + i2c10-gpio28 Use GPIOs 28&29 for i2c0 + i2c10-gpio44 Use GPIOs 44&45 for i2c0 + + +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: crystalfontz-cfa050_pi_m +Info: Configures the Crystalfontz CFA050-PI-M series of Raspberry Pi CM4 + based modules using the CFA7201280A0_050Tx 7" TFT LCD displays, + with or without capacitive touch screen. + Requires use of vc4-kms-v3d. +Load: dtoverlay=crystalfontz-cfa050_pi_m,= +Params: captouch Enable capacitive touch display + + +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 Bluetooth-capable Raspberry Pis. On Pis + prior to Pi 5 this restores UART0/ttyAMA0 over GPIOs 14 & 15. +Load: dtoverlay=disable-bt +Params: + + +Name: disable-bt-pi5 +Info: See disable-bt + + +Name: disable-emmc2 +Info: Disable EMMC2 controller on BCM2711. + The allows the onboard EMMC storage on Compute Module 4 to be disabled + e.g. if a fault has occurred. +Load: dtoverlay=disable-emmc2 +Params: + + +Name: disable-wifi +Info: Disable onboard WLAN on WiFi-capable Raspberry Pis. +Load: dtoverlay=disable-wifi +Params: + + +Name: disable-wifi-pi5 +Info: See disable-wifi + + +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. + This works with the Raspberry Pi 7" touchscreen when not being polled + by the firmware. + By default the overlay uses the i2c_csi_dsi I2C interface, but this + can be overridden + 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 + i2c0 Choose the I2C0 bus on GPIOs 0&1 + i2c1 Choose the I2C1 bus on GPIOs 2&3 + i2c3 Choose the I2C3 bus (configure with the i2c3 + overlay - BCM2711 only) + i2c4 Choose the I2C4 bus (configure with the i2c4 + overlay - BCM2711 only) + i2c5 Choose the I2C5 bus (configure with the i2c5 + overlay - BCM2711 only) + i2c6 Choose the I2C6 bus (configure with the i2c6 + overlay - BCM2711 only) + addr Sets the address for the touch controller. Note + that the device must be configured to use the + specified address. + + +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-charger +Info: This is a generic overlay for detecting charger with GPIO. +Load: dtoverlay=gpio-charger,= +Params: gpio GPIO pin to trigger on (default 4) + active_low When this is 1 (active low), a falling + edge generates a charging event and a + rising edge generates a discharging event. + When this is 0 (active high), this is + reversed. The default is 0 (active high) + gpio_pull Desired pull-up/down state (off, down, up) + Default is "down". + type Set a charger type for the pin. (Default: mains) + + +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/