mirror of
https://github.com/kernelkit/infix.git
synced 2026-07-22 01:13:00 +02:00
Merge pull request #1470 from kernelkit/bpi-r4-support
Add support for Banana Pi BPI-R4
This commit is contained in:
@@ -19,6 +19,8 @@ jobs:
|
||||
- aarch64_qemu_boot
|
||||
- bpi_r3_sd_boot
|
||||
- bpi_r3_emmc_boot
|
||||
- bpi_r4_sd_boot
|
||||
- bpi_r4_emmc_boot
|
||||
- bpi_r64_sd_boot
|
||||
- bpi_r64_emmc_boot
|
||||
- cn9130_crb_boot
|
||||
|
||||
@@ -11,6 +11,7 @@ on:
|
||||
- raspberrypi-rpi2
|
||||
- raspberrypi-rpi64
|
||||
- bananapi-bpi-r3
|
||||
- bananapi-bpi-r4
|
||||
- bananapi-bpi-r64
|
||||
- friendlyarm-nanopi-r2s
|
||||
- microchip-sama7g54-ek
|
||||
@@ -68,6 +69,12 @@ jobs:
|
||||
echo "ARCH=aarch64" >> $GITHUB_ENV
|
||||
echo "BUILD_EMMC=true" >> $GITHUB_ENV
|
||||
;;
|
||||
bananapi-bpi-r4)
|
||||
echo "BOOTLOADER_SD=bpi-r4-sd-boot" >> $GITHUB_ENV
|
||||
echo "BOOTLOADER_EMMC=bpi-r4-emmc-boot" >> $GITHUB_ENV
|
||||
echo "ARCH=aarch64" >> $GITHUB_ENV
|
||||
echo "BUILD_EMMC=true" >> $GITHUB_ENV
|
||||
;;
|
||||
bananapi-bpi-r64)
|
||||
echo "BOOTLOADER_SD=bpi-r64-sd-boot" >> $GITHUB_ENV
|
||||
echo "BOOTLOADER_EMMC=bpi-r64-emmc-boot" >> $GITHUB_ENV
|
||||
|
||||
@@ -2,6 +2,7 @@ if BR2_aarch64
|
||||
|
||||
source "$BR2_EXTERNAL_INFIX_PATH/board/aarch64/alder-alder/Config.in"
|
||||
source "$BR2_EXTERNAL_INFIX_PATH/board/aarch64/bananapi-bpi-r3/Config.in"
|
||||
source "$BR2_EXTERNAL_INFIX_PATH/board/aarch64/bananapi-bpi-r4/Config.in"
|
||||
source "$BR2_EXTERNAL_INFIX_PATH/board/aarch64/bananapi-bpi-r64/Config.in"
|
||||
source "$BR2_EXTERNAL_INFIX_PATH/board/aarch64/freescale-imx8mp-evk/Config.in"
|
||||
source "$BR2_EXTERNAL_INFIX_PATH/board/aarch64/friendlyarm-nanopi-r2s/Config.in"
|
||||
|
||||
@@ -4,9 +4,10 @@ aarch64
|
||||
Board Specific Documentation
|
||||
----------------------------
|
||||
|
||||
- [Banana Pi BPi-R3](banana-pi-r3/)
|
||||
- [Banana Pi BPi-R64](banana-pi-r64/)
|
||||
- [Marvell CN9130-CRB](cn9130-crb/)
|
||||
- [Microchip SparX-5i PCB135 (eMMC)](sparx5-pcb135/)
|
||||
- [NanoPi R2S](r2s/)
|
||||
- [Raspberry Pi 64-bit](raspberry-pi64/)
|
||||
- [Banana Pi BPi-R3](bananapi-bpi-r3/)
|
||||
- [Banana Pi BPi-R4](bananapi-bpi-r4/)
|
||||
- [Banana Pi BPi-R64](bananapi-bpi-r64/)
|
||||
- [Marvell CN9130-CRB](marvell-cn9130-crb/)
|
||||
- [Microchip SparX-5i PCB135 (eMMC)](microchip-sparx5-pcb135/)
|
||||
- [NanoPi R2S](friendlyarm-nanopi-r2s/)
|
||||
- [Raspberry Pi 64-bit](raspberrypi-rpi64/)
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
# Locally calculated
|
||||
sha256 d2f96418893ac66156d0e691cda189b0d85ae1d814065d1d9aa1845383100f46 LICENSE
|
||||
@@ -0,0 +1,2 @@
|
||||
# Locally calculated
|
||||
sha256 dbe4eae8debbba8135297e15f24aeefef0b4c03781f3f9328db4398d58a728b3 LICENSE
|
||||
@@ -0,0 +1,11 @@
|
||||
config BR2_PACKAGE_BANANAPI_BPI_R4
|
||||
bool "Banana Pi R4"
|
||||
depends on BR2_aarch64
|
||||
select BR2_PACKAGE_FEATURE_WIFI
|
||||
select BR2_PACKAGE_LINUX_FIRMWARE
|
||||
select BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK
|
||||
select BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7988
|
||||
select BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7996
|
||||
select SDCARD_AUX
|
||||
help
|
||||
Build Banana PI R4 support
|
||||
@@ -0,0 +1,13 @@
|
||||
Copyright (c) 2026 The KernelKit Authors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
@@ -0,0 +1,360 @@
|
||||
# Banana Pi BPI-R4 / BPI-R4-2g5 / BPI-R4P
|
||||
|
||||
<img src="banana_pi_bpi-r4_poe.jpg" alt="The board" width=800 padding=10>
|
||||
|
||||
## Overview
|
||||
|
||||
The Banana Pi BPI-R4 is a high-performance networking board built around the
|
||||
MediaTek MT7988A SoC (Filogic 880). It is a successor to the BPI-R3 and
|
||||
represents a significant step up: the CPU switches from in-order Cortex-A53
|
||||
cores to out-of-order Cortex-A73 cores, and the MT7531 switch is now part of
|
||||
the SOC. The base model comes with two SFP+ cages supporting 1.25/2.5/5/10
|
||||
Gbps, and the R4P model comes with one SFP+ cage and one 2.5 Gbps RJ45 jack,
|
||||
which with an optional PoE board means the board can act as PD. Unlike the
|
||||
BPi-R3, however, there is no on-board WiFi support, that requires an external
|
||||
tri-band WiFi 7 (IEEE 802.11be) card.
|
||||
|
||||
### Variants
|
||||
|
||||
| **Feature** | **BPI-R4** | **BPI-R4-2g5** | **BPI-R4P** |
|
||||
|------------------|------------------|-------------------|---------------------------|
|
||||
| 1G switch ports | wan, lan1–lan3 | lan0–lan3 | lan0–lan3 |
|
||||
| 2.5G RJ45 (WAN) | — | wan | wan (PoE input) |
|
||||
| SFP+ port(s) | sfp1, sfp2 (10G) | sfp1 (10G) | sfp1 (10G) |
|
||||
| Linux DT | bpi-r4 | bpi-r4-2g5 | bpi-r4-2g5 (same) |
|
||||
|
||||
On the standard BPI-R4 the four 1G switch ports are labeled `wan`, `lan1`, `lan2`,
|
||||
and `lan3`. On the R4-2g5 and R4P, the port that would otherwise be `wan` on the
|
||||
switch is relabeled `lan0` via a device tree overlay, since the actual WAN port on
|
||||
those variants is the dedicated 2.5G internal PHY on the separate RJ45 jack.
|
||||
|
||||
The BPI-R4P is mechanically and electrically identical to the BPI-R4-2g5
|
||||
with an additional PoE daughterboard header. From a Linux kernel and
|
||||
Infix perspective the two boards are treated identically.
|
||||
|
||||
### SoC: MediaTek MT7988A vs MT7986 (BPI-R3)
|
||||
|
||||
The MT7988A (Filogic 880) and MT7986 (Filogic 820) may look similar from
|
||||
their part numbers, but they are built on entirely different silicon with
|
||||
distinct system architectures:
|
||||
|
||||
| **Aspect** | **MT7988A (BPI-R4)** | **MT7986 (BPI-R3)** |
|
||||
|------------------|--------------------------|---------------------------|
|
||||
| CPU cores | 4x Cortex-A73 @ 1.8 GHz | 4x Cortex-A53 @ 2.0 GHz |
|
||||
| CPU architecture | ARMv8-A, out-of-order | ARMv8-A, in-order |
|
||||
| Internal switch | 1 Gbps per port | 1 Gbps per port |
|
||||
| Uplinks | USXGMII (native 10 Gbps) | USXGMII (native 2.5 Gbps) |
|
||||
| WiFi | MT7996E PCIe module | MT7915E (built-in) |
|
||||
| WiFi standard | WiFi 7 (802.11be) | WiFi 6 (802.11ax) |
|
||||
| WiFi bands | 2.4 / 5 / 6 GHz | 2.4 / 5 GHz |
|
||||
| Hardware crypto | EIP-197 NPU | EIP-93 |
|
||||
| PCIe slots | 4 (2x mPCIe, 2x M.2) | 1 mPCIe |
|
||||
| Boot ROM offset | Sector 1024 (0x80000) | Sector 1024 (0x80000) |
|
||||
|
||||
### Hardware Features
|
||||
|
||||
- **SoC:** MediaTek MT7988A (Filogic 880)
|
||||
- **CPU:** Quad-core ARM Cortex-A73, up to 1.8 GHz
|
||||
- **RAM:** 4 GB DDR4
|
||||
- **Storage:** 8 GB eMMC, microSD card slot, SPI NAND flash
|
||||
- **Ethernet switch:** 4-port 1 GbE (10/100/1000) internal DSA switch
|
||||
- **SFP+ ports:** 2x 10 Gbps USXGMII (standard R4) or 1x SFP+ (R4-2g5/R4P)
|
||||
- **WiFi:** optional MediaTek MT7996E PCIe module — tri-band WiFi 7 (2.4/5/6 GHz)
|
||||
- **USB:** 1x USB 3.0 (xHCI)
|
||||
- **PCIe:** 2x mPCIe (SIM2/SIM3), 1x M.2 Key-B (SIM1), 1x M.2 Key-M (SSD)
|
||||
- **RTC:** PCF8563 on I2C
|
||||
- **Fan:** PWM-controlled cooling with thermal management
|
||||
- **Console:** UART at 115200 8N1 (3.3 V, USB-to-serial adapter required)
|
||||
|
||||
### Default Network Configuration
|
||||
|
||||
Infix ships with the following factory defaults.
|
||||
|
||||
**Standard BPI-R4:**
|
||||
|
||||
- **LAN bridge** (`br0`, 192.168.0.1/24): `lan1`, `lan2`, `lan3` (1G switch ports)
|
||||
- **WAN port** (`wan`): DHCP client, used for internet uplink (1G switch port)
|
||||
- **SFP+ ports** (`sfp1`, `sfp2`): Present but unconfigured
|
||||
|
||||
**BPI-R4-2g5 and BPI-R4P:**
|
||||
|
||||
- **LAN bridge** (`br0`, 192.168.0.1/24): `lan0`, `lan1`, `lan2`, `lan3` (1G switch ports)
|
||||
- **WAN port** (`wan`): DHCP client, used for internet uplink (2.5G internal PHY)
|
||||
- **SFP+ port** (`sfp1`): Present but unconfigured
|
||||
|
||||
> [!NOTE]
|
||||
> If an optional WiFi 7 (MT7996E) PCIe card is installed, the radio interfaces
|
||||
> are bridged into the LAN as access points. WiFi is not included with the board
|
||||
> and is not part of the factory default configuration.
|
||||
|
||||
|
||||
## Getting Started
|
||||
|
||||
<img align="right" src="console-header.png" alt="Console header pins" width=200 padding=10>
|
||||
|
||||
### Quick Start with SD Card
|
||||
|
||||
1. **Download the SD card image:** [infix-bpi-r4-sdcard.img][2]
|
||||
2. **Flash the image to an SD card:** see [this guide][0]
|
||||
3. **Set boot switches to SD card mode** (see Boot Switch Reference below)
|
||||
4. **Insert the SD card, connect power and a serial console (115200 8N1)**
|
||||
5. Default login: `admin` / `admin`
|
||||
|
||||
### Boot Switch Reference
|
||||
|
||||
<img align="right" src="bootstrap-sw3.png" alt="DIP switches" width=140 padding=10>
|
||||
|
||||
The BPI-R4 has a 2-position DIP switch (SW3) that selects the boot media.
|
||||
Switch positions are printed on the board near the SD card slot.
|
||||
|
||||
| A | B | Boot media (SW3) |
|
||||
|-----|-----|------------------|
|
||||
| OFF | ON | SPI NAND |
|
||||
| ON | OFF | eMMC |
|
||||
| ON | ON | SD card |
|
||||
|
||||
> [!NOTE]
|
||||
> "OFF" = switch in the UP position = logical 0.
|
||||
|
||||
## Installing to eMMC
|
||||
|
||||
For production use or better reliability, install Infix to the internal
|
||||
eMMC storage.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> The MT7988A has a single MMC controller that can only operate in one mode
|
||||
> (SD or eMMC) per boot session. The SD card U-Boot cannot switch to eMMC
|
||||
> mode mid-session, so an intermediate NAND bootloader step is required to
|
||||
> write the eMMC — the same approach as BPi-R3.
|
||||
>
|
||||
> The MT7988A boot chain is: **BROM → BL2 → FIP (BL31 + U-Boot)**. The FIP
|
||||
> (Firmware Image Package) bundles ARM Trusted Firmware (BL31) and U-Boot
|
||||
> together; it is not just a U-Boot binary. When BL2 runs, it loads the FIP
|
||||
> from a fixed offset and hands off to BL31, which then jumps into U-Boot.
|
||||
>
|
||||
> The factory SPI NAND contains a minimal recovery U-Boot that only supports
|
||||
> TFTP — it has no USB command. You cannot use it to load files from a USB
|
||||
> drive. Similarly, the factory eMMC ships with a basic OpenWRT image.
|
||||
> You must first flash a full-featured U-Boot (from Frank-W) to SPI NAND via
|
||||
> the SD card U-Boot before you can write the eMMC.
|
||||
>
|
||||
> This process involves three boot mode changes and multiple flash operations.
|
||||
> Take your time and verify each step carefully.
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- USB-to-serial adapter (3.3 V) for console access
|
||||
- USB flash drive (FAT32 formatted)
|
||||
- microSD card with Infix SD image, for initial boot
|
||||
- Downloaded files (see below)
|
||||
|
||||
### Required Files
|
||||
|
||||
Place these files on a FAT32-formatted USB drive:
|
||||
|
||||
1. **Infix eMMC image:** [infix-bpi-r4-emmc.img][3]
|
||||
2. **eMMC bootloader** (from): [bpi-r4-emmc-boot-2026.01-latest.tar.gz][4]
|
||||
- Extract `bl2.img` from the tarball to your USB drive
|
||||
3. **Intermediate NAND bootloader** from Frank-W's U-Boot (for BPI-R4, SPI NAND):
|
||||
- [bpi-r4_spim-nand_bl2.img][13] — BL2 first-stage loader
|
||||
- [bpi-r4_spim-nand_fip.bin][14] — FIP image (BL31 + U-Boot)
|
||||
|
||||
### Step 1: Boot from SD card
|
||||
|
||||
1. Set boot switches to **SD card mode** (SW3: A=ON, B=ON)
|
||||
2. Insert the SD card with the Infix image
|
||||
3. Power on and break into U-Boot (press Ctrl-C during countdown)
|
||||
|
||||
### Step 2: Flash intermediate NAND bootloader
|
||||
|
||||
This installs a full-featured U-Boot to SPI NAND so the board can load files
|
||||
from USB in the next step. From the SD card U-Boot prompt:
|
||||
|
||||
```
|
||||
usb start
|
||||
mtd erase spi-nand0
|
||||
fatload usb 0:1 0x50000000 bpi-r4_spim-nand_bl2.img
|
||||
mtd write spi-nand0 0x50000000 0x0 0x100000
|
||||
fatload usb 0:1 0x50000000 bpi-r4_spim-nand_fip.bin
|
||||
mtd write spi-nand0 0x50000000 0x580000 0x200000
|
||||
```
|
||||
|
||||
### Step 3: Boot from NAND
|
||||
|
||||
1. Power off the board
|
||||
2. Set boot switches to **SPI NAND mode** (SW3: A=OFF, B=ON)
|
||||
3. Power on — you should boot into U-Boot again
|
||||
|
||||
### Step 4: Write Infix image to eMMC
|
||||
|
||||
From the U-Boot prompt:
|
||||
|
||||
```
|
||||
usb start
|
||||
fatload usb 0:1 0x50000000 infix-bpi-r4-emmc.img
|
||||
setexpr blocks ${filesize} / 0x200
|
||||
mmc write 0x50000000 0x0 ${blocks}
|
||||
```
|
||||
|
||||
### Step 5: Configure eMMC boot partition
|
||||
|
||||
Write the BL2 bootloader to the eMMC boot partition:
|
||||
|
||||
```
|
||||
mmc partconf 0 1 1 1
|
||||
mmc erase 0x0 0x400
|
||||
fatload usb 0:1 0x50000000 bl2.img
|
||||
mmc write 0x50000000 0x0 0x400
|
||||
mmc partconf 0 1 1 0
|
||||
```
|
||||
|
||||
### Step 6: Boot from eMMC
|
||||
|
||||
1. Power off the board
|
||||
2. Set boot switches to **eMMC mode** (SW3: A=ON, B=OFF)
|
||||
3. Remove the SD card (optional, recommended to verify eMMC boot)
|
||||
4. Power on
|
||||
|
||||
Your BPI-R4 should now boot Infix from internal eMMC storage.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Board won't boot
|
||||
|
||||
- Verify boot switch positions — double-check against the wiki
|
||||
- Ensure the power supply provides adequate current (12 V / 3 A recommended)
|
||||
- Check the serial console output at 115200 8N1
|
||||
|
||||
### Can't break into U-Boot
|
||||
|
||||
- Connect the serial console before powering on
|
||||
- Press Ctrl-C immediately when boot messages appear
|
||||
- Try power cycling and pressing Ctrl-C repeatedly during the countdown
|
||||
|
||||
### eMMC boot fails after installation
|
||||
|
||||
- Boot from NAND (SW3=ON) and verify the eMMC write completed without errors
|
||||
- Re-run the `mmc partconf` sequence — a missed step is the most common
|
||||
cause of failure
|
||||
- Use `mmc info` to confirm the eMMC is detected
|
||||
|
||||
### No network connectivity
|
||||
|
||||
The interface names on BPI-R4 differ from BPI-R3. Confirm what Linux
|
||||
has created with `ip link` and compare with the factory configuration:
|
||||
|
||||
- `wan`, `lan1`–`lan3`: 1G switch ports (standard R4)
|
||||
- `wan`, `lan0`–`lan3`: on R4-2g5/R4P, `wan` is the 2.5G internal PHY; `lan0`–`lan3` are 1G switch ports
|
||||
- `sfp1` (and `sfp2` on standard R4): 10G SFP+ cage(s)
|
||||
|
||||
If interface renames look wrong, check `dmesg | grep renamed` and if
|
||||
you spot any errors, please report as an issue to the Infix tracker
|
||||
on GitHub.
|
||||
|
||||
## Board Variants
|
||||
|
||||
### BPI-R4
|
||||
|
||||
The base model BPi-R4 ports look like this, the `wan` port is the same physical
|
||||
switch port as `lan0` on the R4-2g5/R4P, but here it serves as the WAN port in
|
||||
the factory default configuration.
|
||||
|
||||
```
|
||||
.-.
|
||||
| | .-----.-----.-----.-----.
|
||||
| | _______ _______ | | | | | .---.
|
||||
| | | | | | | | | | | | | .-----.
|
||||
'-' '-------' '-------' '-----'-----'-----'-----' '---' '-----'
|
||||
USB1 sfp1 sfp2 wan lan1 lan2 lan3 DC12V PD20V
|
||||
```
|
||||
|
||||
### BPI-R4-2g5 and BPI-R4P
|
||||
|
||||
These variants substitute one SFP+ cage for an internal 2.5 Gbps PHY
|
||||
connected to a standard RJ45 jack. From a kernel perspective they use
|
||||
the `mt7988a-bananapi-bpi-r4-2g5` device tree.
|
||||
|
||||
The BPI-R4P additionally supports an optional PoE input daughterboard on
|
||||
the 2.5 Gbps RJ45 port. The PoE circuitry is passive with respect to
|
||||
Linux — no special kernel driver is required for basic operation.
|
||||
|
||||
For these board variants, the WAN role moves to the dedicated 2.5G internal PHY,
|
||||
so all four switch ports become LAN ports (`lan0`–`lan3`) instead of three:
|
||||
|
||||
```
|
||||
.-.
|
||||
| | .-----. .-----.-----.-----.-----.
|
||||
| | _______ | | | | | | | .---.
|
||||
| | | | | | | | | | | | | .-----.
|
||||
'-' '-------' '-----' '-----'-----'-----'-----' '---' '-----'
|
||||
USB1 sfp1 wan lan0 lan1 lan2 lan3 DC12V PD20V
|
||||
```
|
||||
|
||||
### Selecting the Board Variant
|
||||
|
||||
U-Boot cannot automatically distinguish the standard R4 from the R4-2g5/R4P at
|
||||
boot time (the on-board EEPROM is not programmed from factory). Instead, the
|
||||
variant is read from the persistent U-Boot environment on the `aux` partition,
|
||||
and you have to set it manually using `fw_setenv` from a UNIX shell:
|
||||
|
||||
```bash
|
||||
# For BPI-R4-2g5 or BPI-R4P (1x SFP+ + 1x 2.5 Gbps RJ45):
|
||||
sudo fw_setenv BOARD_VARIANT 2g5
|
||||
|
||||
# To revert to the standard BPI-R4 (2x SFP+) clear the setting:
|
||||
sudo fw_setenv BOARD_VARIANT
|
||||
```
|
||||
|
||||
> [!IMPORTANT]
|
||||
> The change takes effect on the next reboot. No re-flashing is required, but
|
||||
> you may want to do a factory reset to activate the changes in your system
|
||||
> `startup-config`: `sudo factory -y` from shell, or the CLI.
|
||||
|
||||
`fw_setenv` writes to the `uboot.env` file on the aux partition. U-Boot
|
||||
reads this at every boot (before loading the kernel) and selects the
|
||||
matching device tree:
|
||||
|
||||
| `BOARD_VARIANT` | Device tree loaded |
|
||||
|-----------------|-----------------------------------|
|
||||
| *(unset)* | `mt7988a-bananapi-bpi-r4.dtb` |
|
||||
| `2g5` | `mt7988a-bananapi-bpi-r4-2g5.dtb` |
|
||||
|
||||
## Additional Resources
|
||||
|
||||
- [Infix Documentation][1]
|
||||
- [Official BPI-R4 Page][7]
|
||||
- [BPI-R4 Forum][8]
|
||||
- [Frank-W's site][9]
|
||||
- [Release Downloads][10]
|
||||
- [Bootloader Builds][11]
|
||||
|
||||
## Building Custom Images
|
||||
|
||||
```bash
|
||||
# Build bootloaders for SD and eMMC
|
||||
make x-bpi-r4-sd-boot
|
||||
make x-bpi-r4-emmc-boot
|
||||
|
||||
# Build main system
|
||||
make aarch64
|
||||
|
||||
# Create SD card image
|
||||
./utils/mkimage.sh -od bananapi-bpi-r4
|
||||
|
||||
# Create eMMC image
|
||||
./utils/mkimage.sh -odt emmc bananapi-bpi-r4
|
||||
```
|
||||
|
||||
[0]: https://www.kernelkit.org/posts/flashing-sdcard/
|
||||
[1]: https://www.kernelkit.org/infix/latest/
|
||||
[2]: https://github.com/kernelkit/infix/releases/download/latest-boot/infix-bpi-r4-sdcard.img
|
||||
[3]: https://github.com/kernelkit/infix/releases/download/latest-boot/infix-bpi-r4-emmc.img
|
||||
[4]: https://github.com/kernelkit/infix/releases/download/latest-boot/bpi-r4-emmc-boot-2026.01-latest.tar.gz
|
||||
[7]: https://docs.banana-pi.org/en/BPI-R4/BananaPi_BPI-R4
|
||||
[8]: https://forum.banana-pi.org/
|
||||
[9]: https://wiki.fw-web.de/doku.php?id=en:bpi-r4:start
|
||||
[10]: https://github.com/kernelkit/infix/releases/tag/latest
|
||||
[11]: https://github.com/kernelkit/infix/releases/tag/latest-boot
|
||||
[12]: https://github.com/frank-w/u-boot/releases
|
||||
[13]: https://github.com/frank-w/u-boot/releases/download/CI-BUILD-2026-01-bpi-2026.01-2026-01-15_2013/bpi-r4_spim-nand_bl2.img
|
||||
[14]: https://github.com/frank-w/u-boot/releases/download/CI-BUILD-2026-01-bpi-2026.01-2026-01-15_2013/bpi-r4_spim-nand_fip.bin
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 92 KiB |
@@ -0,0 +1,2 @@
|
||||
# Locally calculated
|
||||
sha256 d48246c717b505cc11df95171f2fd548b389e1a463f1af4c68d0b69fe0d1009b LICENSE
|
||||
@@ -0,0 +1,49 @@
|
||||
define BANANAPI_BPI_R4_LINUX_CONFIG_FIXUPS
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_ARCH_MEDIATEK)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_MACH_MT7988)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_PINCTRL_MT7988)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_SERIAL_8250_MT6577)
|
||||
$(call KCONFIG_SET_OPT,CONFIG_I2C_GPIO,y)
|
||||
$(call KCONFIG_SET_OPT,CONFIG_MTK_THERMAL,m)
|
||||
$(call KCONFIG_SET_OPT,CONFIG_MTK_LVTS_THERMAL,m)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_MTK_UART)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_MEDIATEK_WATCHDOG)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_MEDIATEK_GE_PHY)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_MEDIATEK_GE_SOC_PHY)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_NET_VENDOR_MEDIATEK)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_NET_MEDIATEK_SOC)
|
||||
$(call KCONFIG_SET_OPT,CONFIG_NET_DSA_MT7530,m)
|
||||
$(call KCONFIG_SET_OPT,CONFIG_MT7996E,m)
|
||||
$(call KCONFIG_SET_OPT,CONFIG_PCIE_MEDIATEK_GEN3,m)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_MTK_SCPSYS)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_MMC_MTK)
|
||||
$(call KCONFIG_SET_OPT,CONFIG_I2C_MT65XX,m)
|
||||
$(call KCONFIG_SET_OPT,CONFIG_USB_XHCI_MTK,m)
|
||||
$(call KCONFIG_SET_OPT,CONFIG_PHY_MTK_TPHY,m)
|
||||
$(call KCONFIG_SET_OPT,CONFIG_PHY_MTK_XSPHY,m)
|
||||
$(call KCONFIG_SET_OPT,CONFIG_PHY_MTK_XFI_TPHY,m)
|
||||
$(call KCONFIG_SET_OPT,CONFIG_PCS_STANDALONE,y)
|
||||
$(call KCONFIG_SET_OPT,CONFIG_PCS_MTK_USXGMII,y)
|
||||
$(call KCONFIG_SET_OPT,CONFIG_PWM_MEDIATEK,m)
|
||||
$(call KCONFIG_SET_OPT,CONFIG_SENSORS_PWM_FAN,m)
|
||||
$(call KCONFIG_SET_OPT,CONFIG_NVMEM_MTK_EFUSE,m)
|
||||
$(call KCONFIG_SET_OPT,CONFIG_MEDIATEK_2P5GE_PHY,m)
|
||||
$(call KCONFIG_SET_OPT,CONFIG_CRYPTO_DEV_SAFEXCEL,m)
|
||||
endef
|
||||
|
||||
LINUX_DTS_MT7988 = $(LINUX_DIR)/arch/arm64/boot/dts/mediatek
|
||||
|
||||
define BANANAPI_BPI_R4_KERNEL_DTBS_INSTALL_TARGET
|
||||
@$(call MESSAGE,"Installing kernel DTBs and DTBOs for BPI-R4")
|
||||
$(foreach f, \
|
||||
mt7988a-bananapi-bpi-r4.dtb \
|
||||
mt7988a-bananapi-bpi-r4-2g5.dtb \
|
||||
mt7988a-bananapi-bpi-r4-sd.dtbo \
|
||||
mt7988a-bananapi-bpi-r4-emmc.dtbo, \
|
||||
$(INSTALL) -D $(LINUX_DTS_MT7988)/$(f) \
|
||||
$(TARGET_DIR)/boot/mediatek/$(f)$(sep))
|
||||
endef
|
||||
BANANAPI_BPI_R4_POST_INSTALL_TARGET_HOOKS += BANANAPI_BPI_R4_KERNEL_DTBS_INSTALL_TARGET
|
||||
|
||||
$(eval $(ix-board))
|
||||
$(eval $(generic-package))
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 348 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 6.1 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 282 KiB |
@@ -0,0 +1,2 @@
|
||||
dtb-y += infix/bananapi,bpi-r4.dtbo
|
||||
dtb-y += infix/bananapi,bpi-r4-2g5.dtbo
|
||||
@@ -0,0 +1,32 @@
|
||||
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
|
||||
/dts-v1/;
|
||||
/plugin/;
|
||||
|
||||
/ {
|
||||
compatible = "bananapi,bpi-r4-2g5";
|
||||
};
|
||||
|
||||
/*
|
||||
* On the 2g5 variant, GMAC1 uses the internal 2.5G PHY (eth1 renamed to
|
||||
* "wan" by udev). The switch's port0, which is labeled "wan" in the base
|
||||
* DTS, would cause a name collision when the switch driver registers it.
|
||||
* Rename it to "lan0" here so the kernel names it correctly from the start.
|
||||
*/
|
||||
&gsw_port0 {
|
||||
label = "lan0";
|
||||
};
|
||||
|
||||
/*
|
||||
* The upstream mt7988a.dtsi sets compatible = "ethernet-phy-ieee802.3-c45"
|
||||
* on the internal 2.5G PHY node. That gives genphy_c45 (built-in) OF-match
|
||||
* priority over the PHY-ID-based mtk-2p5ge driver, leaving the PHY powered
|
||||
* down and unclaimed. Replace it with the standard ethernet-phy-idXXXX.XXXX
|
||||
* form so of_get_phy_id() registers the PHY as C22 with explicit ID 0x00339c11.
|
||||
* mtk-2p5ge then matches via PHY_ID_MATCH_VENDOR(0x00339c00) instead of
|
||||
* genphy_c45 winning via OF-match.
|
||||
* Note: /delete-property/ is not used because U-Boot fdt apply does not
|
||||
* implement property deletion in overlays.
|
||||
*/
|
||||
&int_2p5g_phy {
|
||||
compatible = "ethernet-phy-id0033.9c11";
|
||||
};
|
||||
@@ -0,0 +1,28 @@
|
||||
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
|
||||
/dts-v1/;
|
||||
/plugin/;
|
||||
|
||||
/ {
|
||||
compatible = "bananapi,bpi-r4", "mediatek,mt7988a";
|
||||
};
|
||||
|
||||
/*
|
||||
* The upstream mt7988a-bananapi-bpi-r4.dtsi sets stdout-path = "serial0:..."
|
||||
* but the aliases node there only has ethernet entries. Linux resolves
|
||||
* stdout-path by looking in /aliases, so we must add serial0 here.
|
||||
* Path references in overlay aliases cannot use &label, so use the full path.
|
||||
*/
|
||||
&{/} {
|
||||
aliases {
|
||||
serial0 = "/soc/serial@11000000";
|
||||
};
|
||||
|
||||
chosen {
|
||||
infix {
|
||||
/* Default admin user password: 'admin' */
|
||||
factory-password-hash = "$5$mI/zpOAqZYKLC2WU$i7iPzZiIjOjrBF3NyftS9CCq8dfYwHwrmUK097Jca9A";
|
||||
usb-ports = <&ssusb1>;
|
||||
usb-port-names = "USB";
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,81 @@
|
||||
image cfg.ext4 {
|
||||
empty = true
|
||||
temporary = true
|
||||
size = 128M
|
||||
ext4 {
|
||||
label = "cfg"
|
||||
use-mke2fs = true
|
||||
features = "uninit_bg"
|
||||
extraargs = "-m 0 -i 4096"
|
||||
}
|
||||
}
|
||||
|
||||
# The /var partition will be expanded automatically at first boot
|
||||
# to use the full size of the SD-card or eMMC media.
|
||||
image var.ext4 {
|
||||
empty = true
|
||||
temporary = true
|
||||
size = 128M
|
||||
ext4 {
|
||||
label = "var"
|
||||
use-mke2fs = true
|
||||
features = "uninit_bg"
|
||||
extraargs = "-m 0 -i 4096"
|
||||
}
|
||||
}
|
||||
|
||||
image #INFIX_ID##VERSION#-bpi-r4-#TARGET#.img {
|
||||
hdimage {
|
||||
partition-table-type = "gpt"
|
||||
gpt-no-backup = true
|
||||
}
|
||||
# BL2 bootloader partition (MediaTek official location)
|
||||
partition bl2 {
|
||||
image = "bl2.img"
|
||||
offset = 1024s # 0x80000 = sector 1024
|
||||
size = 4M # 0x400000
|
||||
bootable = true
|
||||
}
|
||||
|
||||
# Factory/calibration data (sectors 9216-13311)
|
||||
partition factory {
|
||||
offset = 4608K # 0x480000
|
||||
size = 2M # 0x200000
|
||||
}
|
||||
|
||||
# FIP partition - BL31 + U-Boot (sectors 13312-17407)
|
||||
partition fip {
|
||||
image = "fip.bin"
|
||||
offset = 13312s
|
||||
size = 4096s
|
||||
}
|
||||
|
||||
partition aux {
|
||||
partition-uuid = D4EF35A0-0652-45A1-B3DE-D63339C82035
|
||||
image = "aux.ext4"
|
||||
}
|
||||
|
||||
partition primary {
|
||||
partition-type-uuid = 0FC63DAF-8483-4772-8E79-3D69D8477DE4
|
||||
bootable = true
|
||||
size = 250M
|
||||
image = "rootfs.squashfs"
|
||||
}
|
||||
|
||||
partition secondary {
|
||||
partition-type-uuid = 0FC63DAF-8483-4772-8E79-3D69D8477DE4
|
||||
bootable = true
|
||||
size = 250M
|
||||
image = "rootfs.squashfs"
|
||||
}
|
||||
|
||||
partition cfg {
|
||||
partition-uuid = 7aa497f0-73b5-47e5-b2ab-8752d8a48105
|
||||
image = "cfg.ext4"
|
||||
}
|
||||
|
||||
partition var {
|
||||
partition-uuid = 8046A06A-E45A-4A14-A6AD-6684704A393F
|
||||
image = "var.ext4"
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
label Infix (aarch64)
|
||||
kernel /boot/Image
|
||||
fdtdir /boot
|
||||
fdtoverlays /boot/mediatek/mt7988a-bananapi-bpi-r4-emmc.dtbo /boot/infix/bananapi,bpi-r4.dtbo /boot/infix/bananapi,bpi-r4-2g5.dtbo
|
||||
append ${bootargs_root} ${bootargs_log} usbcore.authorized_default=2 -- ${bootargs_user}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
label Infix (aarch64)
|
||||
kernel /boot/Image
|
||||
fdtdir /boot
|
||||
fdtoverlays /boot/mediatek/mt7988a-bananapi-bpi-r4-sd.dtbo /boot/infix/bananapi,bpi-r4.dtbo /boot/infix/bananapi,bpi-r4-2g5.dtbo
|
||||
append ${bootargs_root} ${bootargs_log} usbcore.authorized_default=2 -- ${bootargs_user}
|
||||
@@ -0,0 +1,5 @@
|
||||
label Infix (aarch64)
|
||||
kernel /boot/Image
|
||||
fdtdir /boot
|
||||
fdtoverlays /boot/mediatek/mt7988a-bananapi-bpi-r4-emmc.dtbo /boot/infix/bananapi,bpi-r4.dtbo
|
||||
append ${bootargs_root} ${bootargs_log} usbcore.authorized_default=2 -- ${bootargs_user}
|
||||
@@ -0,0 +1,5 @@
|
||||
label Infix (aarch64)
|
||||
kernel /boot/Image
|
||||
fdtdir /boot
|
||||
fdtoverlays /boot/mediatek/mt7988a-bananapi-bpi-r4-sd.dtbo /boot/infix/bananapi,bpi-r4.dtbo
|
||||
append ${bootargs_root} ${bootargs_log} usbcore.authorized_default=2 -- ${bootargs_user}
|
||||
+404
@@ -0,0 +1,404 @@
|
||||
{
|
||||
"ieee802-dot1ab-lldp:lldp": {
|
||||
"infix-lldp:enabled": true
|
||||
},
|
||||
"ietf-hardware:hardware": {
|
||||
"component": [
|
||||
{
|
||||
"name": "USB",
|
||||
"class": "infix-hardware:usb",
|
||||
"state": {
|
||||
"admin-state": "unlocked"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"ietf-interfaces:interfaces": {
|
||||
"interface": [
|
||||
{
|
||||
"name": "br0",
|
||||
"type": "infix-if-type:bridge",
|
||||
"ietf-ip:ipv4": {
|
||||
"address": [
|
||||
{
|
||||
"ip": "192.168.0.1",
|
||||
"prefix-length": 24
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "lan0",
|
||||
"type": "infix-if-type:ethernet",
|
||||
"ietf-ip:ipv6": {},
|
||||
"infix-interfaces:bridge-port": {
|
||||
"bridge": "br0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "lan1",
|
||||
"type": "infix-if-type:ethernet",
|
||||
"ietf-ip:ipv6": {},
|
||||
"infix-interfaces:bridge-port": {
|
||||
"bridge": "br0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "lan2",
|
||||
"type": "infix-if-type:ethernet",
|
||||
"ietf-ip:ipv6": {},
|
||||
"infix-interfaces:bridge-port": {
|
||||
"bridge": "br0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "lan3",
|
||||
"type": "infix-if-type:ethernet",
|
||||
"ietf-ip:ipv6": {},
|
||||
"infix-interfaces:bridge-port": {
|
||||
"bridge": "br0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "lo",
|
||||
"type": "infix-if-type:loopback",
|
||||
"ietf-ip:ipv4": {
|
||||
"address": [
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"prefix-length": 8
|
||||
}
|
||||
]
|
||||
},
|
||||
"ietf-ip:ipv6": {
|
||||
"address": [
|
||||
{
|
||||
"ip": "::1",
|
||||
"prefix-length": 128
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "wan",
|
||||
"type": "infix-if-type:ethernet",
|
||||
"ietf-ip:ipv4": {
|
||||
"infix-dhcp-client:dhcp": {
|
||||
"option": [
|
||||
{
|
||||
"id": "ntp-server"
|
||||
},
|
||||
{
|
||||
"id": "broadcast"
|
||||
},
|
||||
{
|
||||
"id": "domain"
|
||||
},
|
||||
{
|
||||
"id": "hostname",
|
||||
"value": "auto"
|
||||
},
|
||||
{
|
||||
"id": "dns-server"
|
||||
},
|
||||
{
|
||||
"id": "router"
|
||||
},
|
||||
{
|
||||
"id": "netmask"
|
||||
},
|
||||
{
|
||||
"id": "vendor-class",
|
||||
"value": "Banana Pi BPI-R4"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"ietf-ip:ipv6": {
|
||||
"infix-dhcpv6-client:dhcp": {
|
||||
"option": [
|
||||
{
|
||||
"id": "ntp-server"
|
||||
},
|
||||
{
|
||||
"id": "client-fqdn"
|
||||
},
|
||||
{
|
||||
"id": "domain-search"
|
||||
},
|
||||
{
|
||||
"id": "dns-server"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"ietf-keystore:keystore": {
|
||||
"asymmetric-keys": {
|
||||
"asymmetric-key": [
|
||||
{
|
||||
"name": "genkey",
|
||||
"public-key-format": "infix-crypto-types:ssh-public-key-format",
|
||||
"public-key": "",
|
||||
"private-key-format": "infix-crypto-types:rsa-private-key-format",
|
||||
"cleartext-private-key": "",
|
||||
"certificates": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"ietf-netconf-acm:nacm": {
|
||||
"enable-nacm": true,
|
||||
"read-default": "permit",
|
||||
"write-default": "permit",
|
||||
"exec-default": "permit",
|
||||
"groups": {
|
||||
"group": [
|
||||
{
|
||||
"name": "admin",
|
||||
"user-name": [
|
||||
"admin"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "operator",
|
||||
"user-name": []
|
||||
},
|
||||
{
|
||||
"name": "guest",
|
||||
"user-name": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"rule-list": [
|
||||
{
|
||||
"name": "admin-acl",
|
||||
"group": [
|
||||
"admin"
|
||||
],
|
||||
"rule": [
|
||||
{
|
||||
"name": "permit-all",
|
||||
"module-name": "*",
|
||||
"access-operations": "*",
|
||||
"action": "permit",
|
||||
"comment": "Allow 'admin' group complete access to all operations and data."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "operator-acl",
|
||||
"group": [
|
||||
"operator"
|
||||
],
|
||||
"rule": [
|
||||
{
|
||||
"name": "permit-system-rpcs",
|
||||
"module-name": "ietf-system",
|
||||
"rpc-name": "*",
|
||||
"access-operations": "exec",
|
||||
"action": "permit",
|
||||
"comment": "Operators can reboot, shutdown, and set system time."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "guest-acl",
|
||||
"group": [
|
||||
"guest"
|
||||
],
|
||||
"rule": [
|
||||
{
|
||||
"name": "deny-all-write+exec",
|
||||
"module-name": "*",
|
||||
"access-operations": "create update delete exec",
|
||||
"action": "deny",
|
||||
"comment": "Guests cannot change anything or exec rpcs."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "default-deny-all",
|
||||
"group": [
|
||||
"*"
|
||||
],
|
||||
"rule": [
|
||||
{
|
||||
"name": "deny-password-access",
|
||||
"path": "/ietf-system:system/authentication/user/password",
|
||||
"access-operations": "*",
|
||||
"action": "deny",
|
||||
"comment": "No user except admins can access password hashes."
|
||||
},
|
||||
{
|
||||
"name": "deny-keystore-access",
|
||||
"module-name": "ietf-keystore",
|
||||
"access-operations": "*",
|
||||
"action": "deny",
|
||||
"comment": "No user except admins can access cryptographic keys."
|
||||
},
|
||||
{
|
||||
"name": "deny-truststore-access",
|
||||
"module-name": "ietf-truststore",
|
||||
"access-operations": "*",
|
||||
"action": "deny",
|
||||
"comment": "No user except admins can access trust store."
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"ietf-netconf-server:netconf-server": {
|
||||
"listen": {
|
||||
"endpoints": {
|
||||
"endpoint": [
|
||||
{
|
||||
"name": "default-ssh",
|
||||
"ssh": {
|
||||
"tcp-server-parameters": {
|
||||
"local-bind": [
|
||||
{
|
||||
"local-address": "::"
|
||||
}
|
||||
]
|
||||
},
|
||||
"ssh-server-parameters": {
|
||||
"server-identity": {
|
||||
"host-key": [
|
||||
{
|
||||
"name": "default-key",
|
||||
"public-key": {
|
||||
"central-keystore-reference": "genkey"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"ietf-system:system": {
|
||||
"hostname": "bpi-%m",
|
||||
"ntp": {
|
||||
"server": [
|
||||
{
|
||||
"name": "default",
|
||||
"udp": {
|
||||
"address": "pool.ntp.org"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"authentication": {
|
||||
"user": [
|
||||
{
|
||||
"name": "admin",
|
||||
"password": "$factory$",
|
||||
"infix-system:shell": "bash"
|
||||
}
|
||||
]
|
||||
},
|
||||
"infix-system:motd-banner": "Li0tLS0tLS0uCnwgIC4gLiAgfCBJbmZpeCBPUyDigJQgSW1tdXRhYmxlLkZyaWVuZGx5LlNlY3VyZQp8LS4gdiAuLXwgaHR0cHM6Ly9rZXJuZWxraXQub3JnCictJy0tLSctJwo="
|
||||
},
|
||||
"infix-dhcp-server:dhcp-server": {
|
||||
"option": [
|
||||
{
|
||||
"id": "ntp-server",
|
||||
"address": "auto"
|
||||
},
|
||||
{
|
||||
"id": "dns-server",
|
||||
"address": "auto"
|
||||
},
|
||||
{
|
||||
"id": "router",
|
||||
"address": "auto"
|
||||
}
|
||||
],
|
||||
"subnet": [
|
||||
{
|
||||
"subnet": "192.168.0.0/24",
|
||||
"pool": {
|
||||
"start-address": "192.168.0.100",
|
||||
"end-address": "192.168.0.250"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"infix-firewall:firewall": {
|
||||
"default": "wan",
|
||||
"zone": [
|
||||
{
|
||||
"name": "lan",
|
||||
"action": "accept",
|
||||
"interface": [
|
||||
"br0"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "wan",
|
||||
"action": "drop",
|
||||
"interface": [
|
||||
"wan"
|
||||
],
|
||||
"service": [
|
||||
"dhcpv6-client"
|
||||
]
|
||||
}
|
||||
],
|
||||
"policy": [
|
||||
{
|
||||
"name": "lan-to-wan",
|
||||
"action": "accept",
|
||||
"ingress": [
|
||||
"lan"
|
||||
],
|
||||
"egress": [
|
||||
"wan"
|
||||
],
|
||||
"masquerade": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"infix-meta:meta": {
|
||||
"version": "1.7"
|
||||
},
|
||||
"infix-services:mdns": {
|
||||
"enabled": true
|
||||
},
|
||||
"infix-services:ssh": {
|
||||
"enabled": true,
|
||||
"hostkey": [
|
||||
"genkey"
|
||||
],
|
||||
"listen": [
|
||||
{
|
||||
"name": "ipv4",
|
||||
"address": "0.0.0.0",
|
||||
"port": 22
|
||||
},
|
||||
{
|
||||
"name": "ipv6",
|
||||
"address": "::",
|
||||
"port": 22
|
||||
}
|
||||
]
|
||||
},
|
||||
"infix-services:web": {
|
||||
"enabled": true,
|
||||
"console": {
|
||||
"enabled": true
|
||||
},
|
||||
"netbrowse": {
|
||||
"enabled": true
|
||||
},
|
||||
"restconf": {
|
||||
"enabled": true
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
# The mtk-2p5ge PHY driver uses MDIO PHY ID matching, not OF compatible
|
||||
# matching. udev auto-loading is based on MODALIAS, which for DT-described
|
||||
# devices is "of:N...C<compatible>" — a format that never matches the driver's
|
||||
# "mdio:..." module alias. Match on OF_COMPATIBLE_0 explicitly instead.
|
||||
ACTION=="add", SUBSYSTEM=="mdio_bus", ENV{OF_COMPATIBLE_0}=="ethernet-phy-id0033.9c11", RUN+="/sbin/modprobe -b mtk-2p5ge"
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
ACTION=="add", SUBSYSTEM=="net", DEVPATH=="/devices/platform/soc/15100000.ethernet/net/eth1", NAME="wan"
|
||||
ACTION=="add", SUBSYSTEM=="net", DEVPATH=="/devices/platform/soc/15100000.ethernet/net/eth2", NAME="sfp1"
|
||||
+396
@@ -0,0 +1,396 @@
|
||||
{
|
||||
"ieee802-dot1ab-lldp:lldp": {
|
||||
"infix-lldp:enabled": true
|
||||
},
|
||||
"ietf-hardware:hardware": {
|
||||
"component": [
|
||||
{
|
||||
"name": "USB",
|
||||
"class": "infix-hardware:usb",
|
||||
"state": {
|
||||
"admin-state": "unlocked"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"ietf-interfaces:interfaces": {
|
||||
"interface": [
|
||||
{
|
||||
"name": "br0",
|
||||
"type": "infix-if-type:bridge",
|
||||
"ietf-ip:ipv4": {
|
||||
"address": [
|
||||
{
|
||||
"ip": "192.168.0.1",
|
||||
"prefix-length": 24
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "lan1",
|
||||
"type": "infix-if-type:ethernet",
|
||||
"ietf-ip:ipv6": {},
|
||||
"infix-interfaces:bridge-port": {
|
||||
"bridge": "br0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "lan2",
|
||||
"type": "infix-if-type:ethernet",
|
||||
"ietf-ip:ipv6": {},
|
||||
"infix-interfaces:bridge-port": {
|
||||
"bridge": "br0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "lan3",
|
||||
"type": "infix-if-type:ethernet",
|
||||
"ietf-ip:ipv6": {},
|
||||
"infix-interfaces:bridge-port": {
|
||||
"bridge": "br0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "lo",
|
||||
"type": "infix-if-type:loopback",
|
||||
"ietf-ip:ipv4": {
|
||||
"address": [
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"prefix-length": 8
|
||||
}
|
||||
]
|
||||
},
|
||||
"ietf-ip:ipv6": {
|
||||
"address": [
|
||||
{
|
||||
"ip": "::1",
|
||||
"prefix-length": 128
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "wan",
|
||||
"type": "infix-if-type:ethernet",
|
||||
"ietf-ip:ipv4": {
|
||||
"infix-dhcp-client:dhcp": {
|
||||
"option": [
|
||||
{
|
||||
"id": "ntp-server"
|
||||
},
|
||||
{
|
||||
"id": "broadcast"
|
||||
},
|
||||
{
|
||||
"id": "domain"
|
||||
},
|
||||
{
|
||||
"id": "hostname",
|
||||
"value": "auto"
|
||||
},
|
||||
{
|
||||
"id": "dns-server"
|
||||
},
|
||||
{
|
||||
"id": "router"
|
||||
},
|
||||
{
|
||||
"id": "netmask"
|
||||
},
|
||||
{
|
||||
"id": "vendor-class",
|
||||
"value": "Banana Pi BPI-R4"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"ietf-ip:ipv6": {
|
||||
"infix-dhcpv6-client:dhcp": {
|
||||
"option": [
|
||||
{
|
||||
"id": "ntp-server"
|
||||
},
|
||||
{
|
||||
"id": "client-fqdn"
|
||||
},
|
||||
{
|
||||
"id": "domain-search"
|
||||
},
|
||||
{
|
||||
"id": "dns-server"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"ietf-keystore:keystore": {
|
||||
"asymmetric-keys": {
|
||||
"asymmetric-key": [
|
||||
{
|
||||
"name": "genkey",
|
||||
"public-key-format": "infix-crypto-types:ssh-public-key-format",
|
||||
"public-key": "",
|
||||
"private-key-format": "infix-crypto-types:rsa-private-key-format",
|
||||
"cleartext-private-key": "",
|
||||
"certificates": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"ietf-netconf-acm:nacm": {
|
||||
"enable-nacm": true,
|
||||
"read-default": "permit",
|
||||
"write-default": "permit",
|
||||
"exec-default": "permit",
|
||||
"groups": {
|
||||
"group": [
|
||||
{
|
||||
"name": "admin",
|
||||
"user-name": [
|
||||
"admin"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "operator",
|
||||
"user-name": []
|
||||
},
|
||||
{
|
||||
"name": "guest",
|
||||
"user-name": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"rule-list": [
|
||||
{
|
||||
"name": "admin-acl",
|
||||
"group": [
|
||||
"admin"
|
||||
],
|
||||
"rule": [
|
||||
{
|
||||
"name": "permit-all",
|
||||
"module-name": "*",
|
||||
"access-operations": "*",
|
||||
"action": "permit",
|
||||
"comment": "Allow 'admin' group complete access to all operations and data."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "operator-acl",
|
||||
"group": [
|
||||
"operator"
|
||||
],
|
||||
"rule": [
|
||||
{
|
||||
"name": "permit-system-rpcs",
|
||||
"module-name": "ietf-system",
|
||||
"rpc-name": "*",
|
||||
"access-operations": "exec",
|
||||
"action": "permit",
|
||||
"comment": "Operators can reboot, shutdown, and set system time."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "guest-acl",
|
||||
"group": [
|
||||
"guest"
|
||||
],
|
||||
"rule": [
|
||||
{
|
||||
"name": "deny-all-write+exec",
|
||||
"module-name": "*",
|
||||
"access-operations": "create update delete exec",
|
||||
"action": "deny",
|
||||
"comment": "Guests cannot change anything or exec rpcs."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "default-deny-all",
|
||||
"group": [
|
||||
"*"
|
||||
],
|
||||
"rule": [
|
||||
{
|
||||
"name": "deny-password-access",
|
||||
"path": "/ietf-system:system/authentication/user/password",
|
||||
"access-operations": "*",
|
||||
"action": "deny",
|
||||
"comment": "No user except admins can access password hashes."
|
||||
},
|
||||
{
|
||||
"name": "deny-keystore-access",
|
||||
"module-name": "ietf-keystore",
|
||||
"access-operations": "*",
|
||||
"action": "deny",
|
||||
"comment": "No user except admins can access cryptographic keys."
|
||||
},
|
||||
{
|
||||
"name": "deny-truststore-access",
|
||||
"module-name": "ietf-truststore",
|
||||
"access-operations": "*",
|
||||
"action": "deny",
|
||||
"comment": "No user except admins can access trust store."
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"ietf-netconf-server:netconf-server": {
|
||||
"listen": {
|
||||
"endpoints": {
|
||||
"endpoint": [
|
||||
{
|
||||
"name": "default-ssh",
|
||||
"ssh": {
|
||||
"tcp-server-parameters": {
|
||||
"local-bind": [
|
||||
{
|
||||
"local-address": "::"
|
||||
}
|
||||
]
|
||||
},
|
||||
"ssh-server-parameters": {
|
||||
"server-identity": {
|
||||
"host-key": [
|
||||
{
|
||||
"name": "default-key",
|
||||
"public-key": {
|
||||
"central-keystore-reference": "genkey"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"ietf-system:system": {
|
||||
"hostname": "bpi-%m",
|
||||
"ntp": {
|
||||
"server": [
|
||||
{
|
||||
"name": "default",
|
||||
"udp": {
|
||||
"address": "pool.ntp.org"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"authentication": {
|
||||
"user": [
|
||||
{
|
||||
"name": "admin",
|
||||
"password": "$factory$",
|
||||
"infix-system:shell": "bash"
|
||||
}
|
||||
]
|
||||
},
|
||||
"infix-system:motd-banner": "Li0tLS0tLS0uCnwgIC4gLiAgfCBJbmZpeCBPUyDigJQgSW1tdXRhYmxlLkZyaWVuZGx5LlNlY3VyZQp8LS4gdiAuLXwgaHR0cHM6Ly9rZXJuZWxraXQub3JnCictJy0tLSctJwo="
|
||||
},
|
||||
"infix-dhcp-server:dhcp-server": {
|
||||
"option": [
|
||||
{
|
||||
"id": "ntp-server",
|
||||
"address": "auto"
|
||||
},
|
||||
{
|
||||
"id": "dns-server",
|
||||
"address": "auto"
|
||||
},
|
||||
{
|
||||
"id": "router",
|
||||
"address": "auto"
|
||||
}
|
||||
],
|
||||
"subnet": [
|
||||
{
|
||||
"subnet": "192.168.0.0/24",
|
||||
"pool": {
|
||||
"start-address": "192.168.0.100",
|
||||
"end-address": "192.168.0.250"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"infix-firewall:firewall": {
|
||||
"default": "wan",
|
||||
"zone": [
|
||||
{
|
||||
"name": "lan",
|
||||
"action": "accept",
|
||||
"interface": [
|
||||
"br0"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "wan",
|
||||
"action": "drop",
|
||||
"interface": [
|
||||
"wan"
|
||||
],
|
||||
"service": [
|
||||
"dhcpv6-client"
|
||||
]
|
||||
}
|
||||
],
|
||||
"policy": [
|
||||
{
|
||||
"name": "lan-to-wan",
|
||||
"action": "accept",
|
||||
"ingress": [
|
||||
"lan"
|
||||
],
|
||||
"egress": [
|
||||
"wan"
|
||||
],
|
||||
"masquerade": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"infix-meta:meta": {
|
||||
"version": "1.7"
|
||||
},
|
||||
"infix-services:mdns": {
|
||||
"enabled": true
|
||||
},
|
||||
"infix-services:ssh": {
|
||||
"enabled": true,
|
||||
"hostkey": [
|
||||
"genkey"
|
||||
],
|
||||
"listen": [
|
||||
{
|
||||
"name": "ipv4",
|
||||
"address": "0.0.0.0",
|
||||
"port": 22
|
||||
},
|
||||
{
|
||||
"name": "ipv6",
|
||||
"address": "::",
|
||||
"port": 22
|
||||
}
|
||||
]
|
||||
},
|
||||
"infix-services:web": {
|
||||
"enabled": true,
|
||||
"console": {
|
||||
"enabled": true
|
||||
},
|
||||
"netbrowse": {
|
||||
"enabled": true
|
||||
},
|
||||
"restconf": {
|
||||
"enabled": true
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
ACTION=="add", SUBSYSTEM=="net", DEVPATH=="/devices/platform/soc/15100000.ethernet/net/eth1", NAME="sfp2"
|
||||
ACTION=="add", SUBSYSTEM=="net", DEVPATH=="/devices/platform/soc/15100000.ethernet/net/eth2", NAME="sfp1"
|
||||
@@ -0,0 +1 @@
|
||||
CONFIG_DEVICE_TREE_INCLUDES="infix-env.dtsi infix-key.dtsi mt7988-emmc-env.dtsi"
|
||||
@@ -0,0 +1,40 @@
|
||||
CONFIG_AUTOBOOT=y
|
||||
CONFIG_BOOTDELAY=2
|
||||
# CONFIG_MMC_PCI is not set
|
||||
CONFIG_ENV_IS_NOWHERE=y
|
||||
# CONFIG_ENV_IS_IN_MMC is not set
|
||||
CONFIG_MULTI_DTB_FIT=y
|
||||
CONFIG_OF_LIST="mt7988a-bananapi-bpi-r4 mt7988a-bananapi-bpi-r4-2g5"
|
||||
|
||||
CONFIG_USB=y
|
||||
CONFIG_USB_XHCI_HCD=y
|
||||
CONFIG_USB_XHCI_MTK=y
|
||||
CONFIG_USB_MTU3=y
|
||||
CONFIG_PHY=y
|
||||
CONFIG_PHY_MTK_TPHY=y
|
||||
|
||||
CONFIG_MTK_SPIM=y
|
||||
CONFIG_SPI=y
|
||||
CONFIG_DM_SPI=y
|
||||
CONFIG_SPI_FLASH=y
|
||||
CONFIG_DM_SPI_FLASH=y
|
||||
CONFIG_SPI_FLASH_MTD=y
|
||||
CONFIG_SPI_FLASH_MACRONIX=y
|
||||
CONFIG_SPI_FLASH_WINBOND=y
|
||||
CONFIG_SPI_FLASH_GIGADEVICE=y
|
||||
CONFIG_MTD=y
|
||||
CONFIG_DM_MTD=y
|
||||
CONFIG_MTD_PARTITIONS=y
|
||||
CONFIG_MTD_SPI_NAND=y
|
||||
CONFIG_MTK_SPIM=y
|
||||
CONFIG_MTK_SNOR=y
|
||||
|
||||
CONFIG_BUTTON=y
|
||||
CONFIG_BUTTON_CMD=y
|
||||
CONFIG_BUTTON_GPIO=y
|
||||
|
||||
CONFIG_CMD_SF=y
|
||||
CONFIG_CMD_USB=y
|
||||
CONFIG_CMD_MTD=y
|
||||
CONFIG_CMD_MTDPARTS=y
|
||||
CONFIG_CMD_DM=y
|
||||
@@ -0,0 +1,7 @@
|
||||
#include <mt7988-env.dtsi>
|
||||
|
||||
&env {
|
||||
fdtfile = "mediatek/mt7988a-bananapi-bpi-r4.dtb";
|
||||
board = "bananapi,bpi-r4-emmc";
|
||||
ixvariant = "if test \"${BOARD_VARIANT}\" = \"2g5\"; then setenv fdtfile mediatek/mt7988a-bananapi-bpi-r4-2g5.dtb; setenv board bananapi,bpi-r4-2g5-emmc; fi";
|
||||
};
|
||||
@@ -0,0 +1,27 @@
|
||||
/ {
|
||||
config {
|
||||
env: environment {
|
||||
bootcmd = "run ixboot";
|
||||
boot_targets = "mmc0";
|
||||
ethprime = "eth0";
|
||||
fdt_addr_r = "0x43f00000";
|
||||
kernel_addr_r = "0x44000000";
|
||||
fdtoverlay_addr_r = "0x47f00000";
|
||||
scriptaddr = "0x48000000";
|
||||
ramdisk_addr_r = "0x4A000000";
|
||||
|
||||
/*
|
||||
* Apply BOARD_VARIANT from aux uboot.env.
|
||||
* Infix writes BOARD_VARIANT=2g5 via fw_setenv on
|
||||
* BPI-R4-2g5 / BPI-R4P boards to select the correct
|
||||
* device tree. Unset = standard R4 (2x SFP+).
|
||||
*/
|
||||
ixvariant = "if test \"${BOARD_VARIANT}\" = \"2g5\"; then setenv fdtfile mediatek/mt7988a-bananapi-bpi-r4-2g5.dtb; fi";
|
||||
|
||||
/* This is a development platform, keep
|
||||
* developer mode statically enabled.
|
||||
*/
|
||||
ixbtn-devmode = "setenv dev_mode yes; echo Enabled";
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,7 @@
|
||||
#include <mt7988-env.dtsi>
|
||||
|
||||
&env {
|
||||
fdtfile = "mediatek/mt7988a-bananapi-bpi-r4.dtb";
|
||||
board = "bananapi,bpi-r4-sdmmc";
|
||||
ixvariant = "if test \"${BOARD_VARIANT}\" = \"2g5\"; then setenv fdtfile mediatek/mt7988a-bananapi-bpi-r4-2g5.dtb; setenv board bananapi,bpi-r4-2g5-sdmmc; fi";
|
||||
};
|
||||
@@ -0,0 +1,2 @@
|
||||
CONFIG_DEVICE_TREE_INCLUDES="infix-env.dtsi infix-key.dtsi mt7988-sd-env.dtsi"
|
||||
CONFIG_OF_LIST="mt7988a-bananapi-bpi-r4-sd"
|
||||
@@ -30,20 +30,15 @@ Infix comes preconfigured with:
|
||||
|
||||
<img align="right" src="bpi-r64-sw1.png" alt="SW1 Boot Switch" width=90 padding=10>
|
||||
|
||||
The BPI-R64 uses a 2-position DIP switch (SW1) to select the boot device
|
||||
order. The MT7622 Boot ROM tries devices in the order listed and falls
|
||||
back to the next if no valid BL2 is found at the expected location.
|
||||
The BPI-R64 has a 2-position DIP switch (SW1) for selecting the boot device.
|
||||
The MT7622 Boot ROM always tries SD first if a card is present, so you can
|
||||
leave SW1 in the OFF (eMMC) position and simply insert or remove an SD card
|
||||
to control boot device selection.
|
||||
|
||||
| SW1 | Boot device | Use case |
|
||||
|-----|-------------|----------------------------|
|
||||
| OFF | eMMC | Production eMMC boot |
|
||||
| ON | SD card | SD card boot / development |
|
||||
|
||||
> [!NOTE]
|
||||
> SinoVoip has exposed only one bit of the MT7622's two-bit `BOOT_SEL[1:0]`
|
||||
> strapping field via SW1, with `BOOT_SEL[1]` hardwired high. This limits the
|
||||
> board to eMMC (`10b`) and SD (`11b`) boot; the SPI-NOR and SPI-NAND modes
|
||||
> available on the MT7622 reference board (`00b`, `01b`) are not selectable.
|
||||
| SW1 | Boot device |
|
||||
|-----|-------------|
|
||||
| OFF | eMMC |
|
||||
| ON | SD card |
|
||||
|
||||
## Getting Started
|
||||
|
||||
@@ -58,11 +53,10 @@ back to the next if no valid BL2 is found at the expected location.
|
||||
dd if=infix-*-bpi-r64-sdcard.img of=/dev/sdX bs=4M status=progress
|
||||
```
|
||||
|
||||
2. **Set boot switch:** SW1 ON (SD card boot)
|
||||
3. **Insert SD card and power on**
|
||||
4. **Connect console:** 115200 8N1 — use the dedicated Debug UART header
|
||||
2. **Insert SD card and power on**
|
||||
3. **Connect console:** 115200 8N1 — use the dedicated Debug UART header
|
||||
just below the 40-pin GPIO header; pins are labeled GND, RX, TX on the board
|
||||
5. **Default login:** `admin` / `admin`
|
||||
4. **Default login:** `admin` / `admin`
|
||||
|
||||
## Installing to eMMC
|
||||
|
||||
@@ -84,9 +78,8 @@ drive.
|
||||
|
||||
#### Step 1: Boot from SD card
|
||||
|
||||
1. Set SW1 to ON (SD boot)
|
||||
2. Insert SD card with Infix
|
||||
3. Power on and break into U-Boot (press Ctrl-C during boot)
|
||||
1. Insert SD card with Infix
|
||||
2. Power on and break into U-Boot (press Ctrl-C during boot)
|
||||
|
||||
#### Step 2: Write the eMMC image from U-Boot
|
||||
|
||||
@@ -115,9 +108,8 @@ mmc partconf 0 1 1 0
|
||||
#### Step 4: Boot from eMMC
|
||||
|
||||
1. Power off the board
|
||||
2. Set SW1 to OFF (eMMC boot)
|
||||
3. Remove SD card and USB drive
|
||||
4. Power on
|
||||
2. Remove SD card and USB drive
|
||||
3. Power on
|
||||
|
||||
## Platform Notes
|
||||
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
# Locally calculated
|
||||
sha256 d48246c717b505cc11df95171f2fd548b389e1a463f1af4c68d0b69fe0d1009b LICENSE
|
||||
@@ -1,2 +1,3 @@
|
||||
CONFIG_DEVICE_TREE_INCLUDES="infix-env.dtsi infix-key.dtsi mt7622-emmc-env.dtsi"
|
||||
CONFIG_SUPPORT_EMMC_BOOT=y
|
||||
CONFIG_CMD_MMC_PARTCONF=y
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
CONFIG_DEVICE_TREE_INCLUDES="infix-env.dtsi infix-key.dtsi mt7622-sd-env.dtsi"
|
||||
CONFIG_SUPPORT_EMMC_BOOT=y
|
||||
CONFIG_CMD_MMC_PARTCONF=y
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
# Locally calculated
|
||||
sha256 d2f96418893ac66156d0e691cda189b0d85ae1d814065d1d9aa1845383100f46 LICENSE
|
||||
@@ -0,0 +1,2 @@
|
||||
# Locally calculated
|
||||
sha256 dbe4eae8debbba8135297e15f24aeefef0b4c03781f3f9328db4398d58a728b3 LICENSE
|
||||
@@ -0,0 +1,2 @@
|
||||
# Locally calculated
|
||||
sha256 d2f96418893ac66156d0e691cda189b0d85ae1d814065d1d9aa1845383100f46 LICENSE
|
||||
@@ -0,0 +1,2 @@
|
||||
# Locally calculated
|
||||
sha256 d2f96418893ac66156d0e691cda189b0d85ae1d814065d1d9aa1845383100f46 LICENSE
|
||||
@@ -0,0 +1,2 @@
|
||||
# Locally calculated
|
||||
sha256 d2f96418893ac66156d0e691cda189b0d85ae1d814065d1d9aa1845383100f46 LICENSE
|
||||
@@ -0,0 +1,2 @@
|
||||
# Locally calculated
|
||||
sha256 dbe4eae8debbba8135297e15f24aeefef0b4c03781f3f9328db4398d58a728b3 LICENSE
|
||||
@@ -0,0 +1,2 @@
|
||||
# Locally calculated
|
||||
sha256 d2f96418893ac66156d0e691cda189b0d85ae1d814065d1d9aa1845383100f46 LICENSE
|
||||
@@ -0,0 +1,2 @@
|
||||
# Locally calculated
|
||||
sha256 d48246c717b505cc11df95171f2fd548b389e1a463f1af4c68d0b69fe0d1009b LICENSE
|
||||
@@ -0,0 +1,2 @@
|
||||
# Locally calculated
|
||||
sha256 dbe4eae8debbba8135297e15f24aeefef0b4c03781f3f9328db4398d58a728b3 LICENSE
|
||||
@@ -14,6 +14,7 @@
|
||||
boot_targets = "virtio mmc";
|
||||
bootcmd = "run ixboot";
|
||||
|
||||
ixvariant = "";
|
||||
ixpreboot = /incbin/("scripts/ixpreboot.sh");
|
||||
ixbtn-devmode = /incbin/("scripts/ixbtn-devmode.sh");
|
||||
ixbtn-factory = /incbin/("scripts/ixbtn-factory.sh");
|
||||
|
||||
@@ -33,7 +33,8 @@ for tgt in "${boot_targets}"; do
|
||||
setexpr ixmenu_n ${ixmenu_n} + 1
|
||||
|
||||
if load ${devtype} ${devnum}:${auxpart} ${loadaddr} /uboot.env; then
|
||||
env import -b ${loadaddr} ${filesize} BOOT_ORDER DEBUG ethact
|
||||
env import -b ${loadaddr} ${filesize} BOOT_ORDER DEBUG ethact BOARD_VARIANT
|
||||
run ixvariant
|
||||
fi
|
||||
|
||||
if test -n "${DEBUG}"; then
|
||||
|
||||
@@ -6,4 +6,8 @@ $(DESTDIR)/boot/%.dtb: %.dtb
|
||||
@echo " DTB-INSTALL $<"
|
||||
@install -D $< $@
|
||||
|
||||
$(DESTDIR)/boot/%.dtbo: %.dtbo
|
||||
@echo " DTBO-INSTALL $<"
|
||||
@install -D $< $@
|
||||
|
||||
.PHONY: install
|
||||
|
||||
+1
-1
Submodule buildroot updated: 79bfb2231d...362f1511ba
@@ -134,6 +134,7 @@ BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y
|
||||
BR2_PACKAGE_HOST_UBOOT_TOOLS_FDT_ADD_PUBKEY=y
|
||||
BR2_PACKAGE_ALDER_ALDER=y
|
||||
BR2_PACKAGE_BANANAPI_BPI_R3=y
|
||||
BR2_PACKAGE_BANANAPI_BPI_R4=y
|
||||
BR2_PACKAGE_BANANAPI_BPI_R64=y
|
||||
BR2_PACKAGE_FRIENDLYARM_NANOPI_R2S=y
|
||||
BR2_PACKAGE_MARVELL_CN9130_CRB=y
|
||||
|
||||
@@ -113,6 +113,7 @@ BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y
|
||||
BR2_PACKAGE_HOST_UBOOT_TOOLS_FDT_ADD_PUBKEY=y
|
||||
BR2_PACKAGE_ALDER_ALDER=y
|
||||
BR2_PACKAGE_BANANAPI_BPI_R3=y
|
||||
BR2_PACKAGE_BANANAPI_BPI_R4=y
|
||||
BR2_PACKAGE_BANANAPI_BPI_R64=y
|
||||
BR2_PACKAGE_FRIENDLYARM_NANOPI_R2S=y
|
||||
BR2_PACKAGE_MARVELL_CN9130_CRB=y
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
BR2_aarch64=y
|
||||
BR2_TOOLCHAIN_EXTERNAL=y
|
||||
BR2_TOOLCHAIN_EXTERNAL_BOOTLIN=y
|
||||
BR2_DL_DIR="$(BR2_EXTERNAL_INFIX_PATH)/dl"
|
||||
BR2_CCACHE=y
|
||||
BR2_CCACHE_DIR="$(BR2_EXTERNAL_INFIX_PATH)/.ccache"
|
||||
BR2_ENABLE_DEBUG=y
|
||||
BR2_PACKAGE_OVERRIDE_FILE="$(BR2_EXTERNAL_INFIX_PATH)/local.mk"
|
||||
BR2_GLOBAL_PATCH_DIR="$(BR2_EXTERNAL_INFIX_PATH)/patches"
|
||||
BR2_SSP_NONE=y
|
||||
BR2_INIT_NONE=y
|
||||
BR2_SYSTEM_BIN_SH_NONE=y
|
||||
# BR2_PACKAGE_BUSYBOX is not set
|
||||
# BR2_PACKAGE_IFUPDOWN_SCRIPTS is not set
|
||||
# BR2_TARGET_ROOTFS_TAR is not set
|
||||
BR2_TARGET_ARM_TRUSTED_FIRMWARE=y
|
||||
BR2_TARGET_ARM_TRUSTED_FIRMWARE_CUSTOM_GIT=y
|
||||
BR2_TARGET_ARM_TRUSTED_FIRMWARE_CUSTOM_REPO_URL="https://github.com/mtk-openwrt/arm-trusted-firmware-mtk.git"
|
||||
BR2_TARGET_ARM_TRUSTED_FIRMWARE_CUSTOM_REPO_VERSION="e06f258664198a901ff1c7c0c87802a115179451"
|
||||
BR2_TARGET_ARM_TRUSTED_FIRMWARE_PLATFORM="mt7988"
|
||||
BR2_TARGET_ARM_TRUSTED_FIRMWARE_FIP=y
|
||||
BR2_TARGET_ARM_TRUSTED_FIRMWARE_UBOOT_AS_BL33=y
|
||||
BR2_TARGET_ARM_TRUSTED_FIRMWARE_ADDITIONAL_VARIABLES="BOOT_DEVICE=emmc DRAM_USE_COMB=1 DDR4_4BG_MODE=1 BOARD_BGA=1 HAVE_DRAM_OBJ_FILE=yes USE_MKIMAGE=1 MKIMAGE=$(HOST_DIR)/bin/mkimage"
|
||||
BR2_TARGET_ARM_TRUSTED_FIRMWARE_IMAGES="*.img *.bin"
|
||||
BR2_TARGET_UBOOT=y
|
||||
BR2_TARGET_UBOOT_BUILD_SYSTEM_KCONFIG=y
|
||||
BR2_TARGET_UBOOT_CUSTOM_VERSION=y
|
||||
BR2_TARGET_UBOOT_CUSTOM_VERSION_VALUE="2026.01"
|
||||
BR2_TARGET_UBOOT_BOARD_DEFCONFIG="mt7988a_bpir4"
|
||||
BR2_TARGET_UBOOT_CONFIG_FRAGMENT_FILES="${BR2_EXTERNAL_INFIX_PATH}/board/common/uboot/extras.config ${BR2_EXTERNAL_INFIX_PATH}/board/aarch64/bananapi-bpi-r4/uboot/extras.config ${BR2_EXTERNAL_INFIX_PATH}/board/aarch64/bananapi-bpi-r4/uboot/emmc-extras.config"
|
||||
BR2_TARGET_UBOOT_NEEDS_DTC=y
|
||||
BR2_TARGET_UBOOT_FORMAT_DTB=y
|
||||
BR2_TARGET_UBOOT_CUSTOM_DTS_PATH="${BR2_EXTERNAL_INFIX_PATH}/board/aarch64/bananapi-bpi-r4/uboot/*.dtsi"
|
||||
BR2_PACKAGE_HOST_BMAP_TOOLS=y
|
||||
BR2_PACKAGE_HOST_GENIMAGE=y
|
||||
BR2_PACKAGE_HOST_RAUC=y
|
||||
BR2_PACKAGE_HOST_UBOOT_TOOLS=y
|
||||
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SUPPORT=y
|
||||
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y
|
||||
BR2_PACKAGE_HOST_UBOOT_TOOLS_FDT_ADD_PUBKEY=y
|
||||
TRUSTED_KEYS=y
|
||||
TRUSTED_KEYS_DEVELOPMENT=y
|
||||
@@ -0,0 +1,42 @@
|
||||
BR2_aarch64=y
|
||||
BR2_TOOLCHAIN_EXTERNAL=y
|
||||
BR2_TOOLCHAIN_EXTERNAL_BOOTLIN=y
|
||||
BR2_DL_DIR="$(BR2_EXTERNAL_INFIX_PATH)/dl"
|
||||
BR2_CCACHE=y
|
||||
BR2_CCACHE_DIR="$(BR2_EXTERNAL_INFIX_PATH)/.ccache"
|
||||
BR2_ENABLE_DEBUG=y
|
||||
BR2_PACKAGE_OVERRIDE_FILE="$(BR2_EXTERNAL_INFIX_PATH)/local.mk"
|
||||
BR2_GLOBAL_PATCH_DIR="$(BR2_EXTERNAL_INFIX_PATH)/patches"
|
||||
BR2_SSP_NONE=y
|
||||
BR2_INIT_NONE=y
|
||||
BR2_SYSTEM_BIN_SH_NONE=y
|
||||
# BR2_PACKAGE_BUSYBOX is not set
|
||||
# BR2_PACKAGE_IFUPDOWN_SCRIPTS is not set
|
||||
# BR2_TARGET_ROOTFS_TAR is not set
|
||||
BR2_TARGET_ARM_TRUSTED_FIRMWARE=y
|
||||
BR2_TARGET_ARM_TRUSTED_FIRMWARE_CUSTOM_GIT=y
|
||||
BR2_TARGET_ARM_TRUSTED_FIRMWARE_CUSTOM_REPO_URL="https://github.com/mtk-openwrt/arm-trusted-firmware-mtk.git"
|
||||
BR2_TARGET_ARM_TRUSTED_FIRMWARE_CUSTOM_REPO_VERSION="e06f258664198a901ff1c7c0c87802a115179451"
|
||||
BR2_TARGET_ARM_TRUSTED_FIRMWARE_PLATFORM="mt7988"
|
||||
BR2_TARGET_ARM_TRUSTED_FIRMWARE_FIP=y
|
||||
BR2_TARGET_ARM_TRUSTED_FIRMWARE_UBOOT_AS_BL33=y
|
||||
BR2_TARGET_ARM_TRUSTED_FIRMWARE_ADDITIONAL_VARIABLES="BOOT_DEVICE=sdmmc DRAM_USE_COMB=1 DDR4_4BG_MODE=1 BOARD_BGA=1 HAVE_DRAM_OBJ_FILE=yes USE_MKIMAGE=1 MKIMAGE=$(HOST_DIR)/bin/mkimage"
|
||||
BR2_TARGET_ARM_TRUSTED_FIRMWARE_IMAGES="*.img *.bin"
|
||||
BR2_TARGET_UBOOT=y
|
||||
BR2_TARGET_UBOOT_BUILD_SYSTEM_KCONFIG=y
|
||||
BR2_TARGET_UBOOT_CUSTOM_VERSION=y
|
||||
BR2_TARGET_UBOOT_CUSTOM_VERSION_VALUE="2026.01"
|
||||
BR2_TARGET_UBOOT_BOARD_DEFCONFIG="mt7988a_bpir4_sd"
|
||||
BR2_TARGET_UBOOT_CONFIG_FRAGMENT_FILES="${BR2_EXTERNAL_INFIX_PATH}/board/common/uboot/extras.config ${BR2_EXTERNAL_INFIX_PATH}/board/aarch64/bananapi-bpi-r4/uboot/extras.config ${BR2_EXTERNAL_INFIX_PATH}/board/aarch64/bananapi-bpi-r4/uboot/sd-extras.config"
|
||||
BR2_TARGET_UBOOT_NEEDS_DTC=y
|
||||
BR2_TARGET_UBOOT_FORMAT_DTB=y
|
||||
BR2_TARGET_UBOOT_CUSTOM_DTS_PATH="${BR2_EXTERNAL_INFIX_PATH}/board/aarch64/bananapi-bpi-r4/uboot/*.dtsi"
|
||||
BR2_PACKAGE_HOST_BMAP_TOOLS=y
|
||||
BR2_PACKAGE_HOST_GENIMAGE=y
|
||||
BR2_PACKAGE_HOST_RAUC=y
|
||||
BR2_PACKAGE_HOST_UBOOT_TOOLS=y
|
||||
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SUPPORT=y
|
||||
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y
|
||||
BR2_PACKAGE_HOST_UBOOT_TOOLS_FDT_ADD_PUBKEY=y
|
||||
TRUSTED_KEYS=y
|
||||
TRUSTED_KEYS_DEVELOPMENT=y
|
||||
@@ -20,6 +20,7 @@ BR2_TARGET_AT91BOOTSTRAP3_CUSTOM_TARBALL=y
|
||||
BR2_TARGET_AT91BOOTSTRAP3_CUSTOM_TARBALL_LOCATION="$(call github,linux4sam,at91bootstrap,v4.0.9)/at91bootstrap-v4.0.9.tar.gz"
|
||||
BR2_TARGET_AT91BOOTSTRAP3_DEFCONFIG="sama7g5ekemmc_uboot"
|
||||
BR2_TARGET_UBOOT=y
|
||||
BR2_TARGET_UBOOT_BUILD_SYSTEM_KCONFIG=y
|
||||
BR2_TARGET_UBOOT_CUSTOM_VERSION=y
|
||||
BR2_TARGET_UBOOT_CUSTOM_VERSION_VALUE="2025.01"
|
||||
BR2_TARGET_UBOOT_BOARD_DEFCONFIG="sama7g5ek_mmc"
|
||||
|
||||
@@ -20,6 +20,7 @@ BR2_TARGET_AT91BOOTSTRAP3_CUSTOM_TARBALL=y
|
||||
BR2_TARGET_AT91BOOTSTRAP3_CUSTOM_TARBALL_LOCATION="$(call github,linux4sam,at91bootstrap,v4.0.9)/at91bootstrap-v4.0.9.tar.gz"
|
||||
BR2_TARGET_AT91BOOTSTRAP3_DEFCONFIG="sama7g5eksd_uboot"
|
||||
BR2_TARGET_UBOOT=y
|
||||
BR2_TARGET_UBOOT_BUILD_SYSTEM_KCONFIG=y
|
||||
BR2_TARGET_UBOOT_CUSTOM_VERSION=y
|
||||
BR2_TARGET_UBOOT_CUSTOM_VERSION_VALUE="2025.01"
|
||||
BR2_TARGET_UBOOT_BOARD_DEFCONFIG="sama7g5ek_mmc1"
|
||||
|
||||
@@ -9,9 +9,15 @@ All notable changes to the project are documented in this file.
|
||||
### Changes
|
||||
|
||||
- Upgrade Linux kernel to 6.18.21 (LTS)
|
||||
- Add support for [Banana Pi BPI-R4][BPI-R4], quad-core Cortex-A73 router with
|
||||
4x 2.5 GbE switching, dual 10 GbE SFP+. Variants BPI-R4-2g5 and BPI-R4P have
|
||||
one SFP+ replaced by a 2.5 GbE RJ45, with optional PoE on the R4P
|
||||
|
||||
### Fixes
|
||||
|
||||
- N/A
|
||||
|
||||
[BPI-R4]: https://docs.banana-pi.org/en/BPI-R4/BananaPi_BPI-R4
|
||||
|
||||
[v26.03.0][] - 2026-03-31
|
||||
-------------------------
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
# Locally calculated
|
||||
sha256 360336cbf0f228b12b7ca0996b33e442d97f496edcf2ec31b655e63631e7f96f LICENSE
|
||||
@@ -1,4 +1,5 @@
|
||||
DATE_CPP_VERSION = 3.0.1
|
||||
DATE_CPP_SOURCE = date-$(DATE_CPP_VERSION).tar.gz
|
||||
DATE_CPP_SITE = $(call github,HowardHinnant,date,v$(DATE_CPP_VERSION))
|
||||
DATE_CPP_INSTALL_STAGING = YES
|
||||
DATE_CPP_LICENSE = MIT
|
||||
@@ -0,0 +1,2 @@
|
||||
# Locally calculated
|
||||
sha256 2f44058572d6e56953b0928a24dc7f816f35d33fb16097e97dfcd5b000bcc140 LICENSE
|
||||
@@ -0,0 +1,2 @@
|
||||
# Locally calculated
|
||||
sha256 ab15fd526bd8dd18a9e77ebc139656bf4d33e97fc7238cd11bf60e2b9b8666c6 COPYING
|
||||
+189
@@ -0,0 +1,189 @@
|
||||
From 8d2aec5525d60e643f85d68d62186cae530f17fc Mon Sep 17 00:00:00 2001
|
||||
From: Joachim Wiberg <troglobit@gmail.com>
|
||||
Date: Sun, 5 Apr 2026 11:33:00 +0200
|
||||
Subject: [PATCH 42/47] net/pcs: add standalone PCS registration infrastructure
|
||||
Organization: Wires
|
||||
|
||||
Add a simple registration mechanism that allows platform PCS drivers to
|
||||
register their phylink_pcs instances, and consumers (e.g. Ethernet MAC
|
||||
drivers) to look them up via a DT phandle using devm_of_pcs_get().
|
||||
|
||||
When the pcs-handle property is present but the PCS device is not yet
|
||||
registered, devm_of_pcs_get() returns -ENODEV to trigger deferred probe
|
||||
in the consumer driver.
|
||||
|
||||
Based on work by Daniel Golle <daniel@makrotopia.org>.
|
||||
|
||||
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
|
||||
---
|
||||
drivers/net/pcs/Kconfig | 4 ++
|
||||
drivers/net/pcs/Makefile | 1 +
|
||||
drivers/net/pcs/pcs-standalone.c | 95 ++++++++++++++++++++++++++++++
|
||||
include/linux/pcs/pcs-standalone.h | 26 ++++++++
|
||||
4 files changed, 126 insertions(+)
|
||||
create mode 100644 drivers/net/pcs/pcs-standalone.c
|
||||
create mode 100644 include/linux/pcs/pcs-standalone.h
|
||||
|
||||
diff --git a/drivers/net/pcs/Kconfig b/drivers/net/pcs/Kconfig
|
||||
index ecbc3530e780..f6b4de7f972c 100644
|
||||
--- a/drivers/net/pcs/Kconfig
|
||||
+++ b/drivers/net/pcs/Kconfig
|
||||
@@ -5,6 +5,10 @@
|
||||
|
||||
menu "PCS device drivers"
|
||||
|
||||
+config PCS_STANDALONE
|
||||
+ tristate
|
||||
+ select PHYLINK
|
||||
+
|
||||
config PCS_XPCS
|
||||
tristate "Synopsys DesignWare Ethernet XPCS"
|
||||
select PHYLINK
|
||||
diff --git a/drivers/net/pcs/Makefile b/drivers/net/pcs/Makefile
|
||||
index 4f7920618b90..0cb0057f2b8e 100644
|
||||
--- a/drivers/net/pcs/Makefile
|
||||
+++ b/drivers/net/pcs/Makefile
|
||||
@@ -4,6 +4,7 @@
|
||||
pcs_xpcs-$(CONFIG_PCS_XPCS) := pcs-xpcs.o pcs-xpcs-plat.o \
|
||||
pcs-xpcs-nxp.o pcs-xpcs-wx.o
|
||||
|
||||
+obj-$(CONFIG_PCS_STANDALONE) += pcs-standalone.o
|
||||
obj-$(CONFIG_PCS_XPCS) += pcs_xpcs.o
|
||||
obj-$(CONFIG_PCS_LYNX) += pcs-lynx.o
|
||||
obj-$(CONFIG_PCS_MTK_LYNXI) += pcs-mtk-lynxi.o
|
||||
diff --git a/drivers/net/pcs/pcs-standalone.c b/drivers/net/pcs/pcs-standalone.c
|
||||
new file mode 100644
|
||||
index 000000000000..f7b46de59636
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/pcs/pcs-standalone.c
|
||||
@@ -0,0 +1,95 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
+/*
|
||||
+ * Helpers for standalone PCS drivers
|
||||
+ *
|
||||
+ * Copyright (C) 2024 Daniel Golle <daniel@makrotopia.org>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/pcs/pcs-standalone.h>
|
||||
+#include <linux/phylink.h>
|
||||
+
|
||||
+static LIST_HEAD(pcs_list);
|
||||
+static DEFINE_MUTEX(pcs_mutex);
|
||||
+
|
||||
+struct pcs_standalone {
|
||||
+ struct device *dev;
|
||||
+ struct phylink_pcs *pcs;
|
||||
+ struct list_head list;
|
||||
+};
|
||||
+
|
||||
+static void devm_pcs_provider_release(struct device *dev, void *res)
|
||||
+{
|
||||
+ struct pcs_standalone *pcssa = (struct pcs_standalone *)res;
|
||||
+
|
||||
+ mutex_lock(&pcs_mutex);
|
||||
+ list_del(&pcssa->list);
|
||||
+ mutex_unlock(&pcs_mutex);
|
||||
+}
|
||||
+
|
||||
+int devm_pcs_register(struct device *dev, struct phylink_pcs *pcs)
|
||||
+{
|
||||
+ struct pcs_standalone *pcssa;
|
||||
+
|
||||
+ pcssa = devres_alloc(devm_pcs_provider_release, sizeof(*pcssa),
|
||||
+ GFP_KERNEL);
|
||||
+ if (!pcssa)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ devres_add(dev, pcssa);
|
||||
+ pcssa->pcs = pcs;
|
||||
+ pcssa->dev = dev;
|
||||
+
|
||||
+ mutex_lock(&pcs_mutex);
|
||||
+ list_add_tail(&pcssa->list, &pcs_list);
|
||||
+ mutex_unlock(&pcs_mutex);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(devm_pcs_register);
|
||||
+
|
||||
+static struct pcs_standalone *of_pcs_locate(const struct device_node *_np, u32 index)
|
||||
+{
|
||||
+ struct device_node *np;
|
||||
+ struct pcs_standalone *iter, *pcssa = NULL;
|
||||
+
|
||||
+ if (!_np)
|
||||
+ return NULL;
|
||||
+
|
||||
+ np = of_parse_phandle(_np, "pcs-handle", index);
|
||||
+ if (!np)
|
||||
+ return NULL;
|
||||
+
|
||||
+ mutex_lock(&pcs_mutex);
|
||||
+ list_for_each_entry(iter, &pcs_list, list) {
|
||||
+ if (iter->dev->of_node != np)
|
||||
+ continue;
|
||||
+
|
||||
+ pcssa = iter;
|
||||
+ break;
|
||||
+ }
|
||||
+ mutex_unlock(&pcs_mutex);
|
||||
+
|
||||
+ of_node_put(np);
|
||||
+
|
||||
+ return pcssa ?: ERR_PTR(-ENODEV);
|
||||
+}
|
||||
+
|
||||
+struct phylink_pcs *devm_of_pcs_get(struct device *dev,
|
||||
+ const struct device_node *np,
|
||||
+ unsigned int index)
|
||||
+{
|
||||
+ struct pcs_standalone *pcssa;
|
||||
+
|
||||
+ pcssa = of_pcs_locate(np ?: dev->of_node, index);
|
||||
+ if (IS_ERR_OR_NULL(pcssa))
|
||||
+ return ERR_PTR(PTR_ERR(pcssa));
|
||||
+
|
||||
+ device_link_add(dev, pcssa->dev, DL_FLAG_AUTOREMOVE_CONSUMER);
|
||||
+
|
||||
+ return pcssa->pcs;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(devm_of_pcs_get);
|
||||
+
|
||||
+MODULE_DESCRIPTION("Helper for standalone PCS drivers");
|
||||
+MODULE_AUTHOR("Daniel Golle <daniel@makrotopia.org>");
|
||||
+MODULE_LICENSE("GPL");
|
||||
diff --git a/include/linux/pcs/pcs-standalone.h b/include/linux/pcs/pcs-standalone.h
|
||||
new file mode 100644
|
||||
index 000000000000..520835cdeee8
|
||||
--- /dev/null
|
||||
+++ b/include/linux/pcs/pcs-standalone.h
|
||||
@@ -0,0 +1,26 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0 */
|
||||
+#ifndef __LINUX_PCS_STANDALONE_H
|
||||
+#define __LINUX_PCS_STANDALONE_H
|
||||
+
|
||||
+#include <linux/device.h>
|
||||
+#include <linux/phylink.h>
|
||||
+#include <linux/phy/phy.h>
|
||||
+#include <linux/of.h>
|
||||
+
|
||||
+#if IS_ENABLED(CONFIG_PCS_STANDALONE)
|
||||
+int devm_pcs_register(struct device *dev, struct phylink_pcs *pcs);
|
||||
+struct phylink_pcs *devm_of_pcs_get(struct device *dev,
|
||||
+ const struct device_node *np, unsigned int index);
|
||||
+#else
|
||||
+static inline int devm_pcs_register(struct device *dev, struct phylink_pcs *pcs)
|
||||
+{
|
||||
+ return -ENOTSUPP;
|
||||
+}
|
||||
+static inline struct phylink_pcs *devm_of_pcs_get(struct device *dev,
|
||||
+ const struct device_node *np,
|
||||
+ unsigned int index)
|
||||
+{
|
||||
+ return ERR_PTR(-ENOTSUPP);
|
||||
+}
|
||||
+#endif /* CONFIG_PCS_STANDALONE */
|
||||
+#endif /* __LINUX_PCS_STANDALONE_H */
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -0,0 +1,465 @@
|
||||
From a11a254420cf8777497b7c027208b382c49964e7 Mon Sep 17 00:00:00 2001
|
||||
From: Joachim Wiberg <troglobit@gmail.com>
|
||||
Date: Mon, 6 Apr 2026 14:14:23 +0200
|
||||
Subject: [PATCH 43/47] net/pcs: add MediaTek MT7988 USXGMII PCS driver
|
||||
Organization: Wires
|
||||
|
||||
Add a PCS driver for the USXGMII subsystem found in the MediaTek MT7988
|
||||
SoC (usxgmiisys0 at 0x10080000, usxgmiisys1 at 0x10081000). The hardware
|
||||
supports USXGMII (10G with in-band AN), 10GBase-R and 5GBase-R interface
|
||||
modes.
|
||||
|
||||
The driver:
|
||||
- Registers via devm_pcs_register() so the Ethernet MAC driver can find
|
||||
it through a DT pcs-handle phandle
|
||||
- Delegates SerDes initialisation to the xfi_tphy PHY driver
|
||||
- Sets up PCS speed/AN control registers and handles link state polling
|
||||
- Reports link state from pcs_get_state without re-running pcs_config;
|
||||
the 10G SerDes needs several seconds to complete CDR lock after a reset
|
||||
and must not be restarted on every poll cycle before it can lock
|
||||
|
||||
Based on work by Henry Yen <henry.yen@mediatek.com> and
|
||||
Daniel Golle <daniel@makrotopia.org>.
|
||||
|
||||
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
|
||||
---
|
||||
drivers/net/pcs/Kconfig | 10 +
|
||||
drivers/net/pcs/Makefile | 1 +
|
||||
drivers/net/pcs/pcs-mtk-usxgmii.c | 394 ++++++++++++++++++++++++++++++
|
||||
3 files changed, 405 insertions(+)
|
||||
create mode 100644 drivers/net/pcs/pcs-mtk-usxgmii.c
|
||||
|
||||
diff --git a/drivers/net/pcs/Kconfig b/drivers/net/pcs/Kconfig
|
||||
index f6b4de7f972c..563c12d6aa9c 100644
|
||||
--- a/drivers/net/pcs/Kconfig
|
||||
+++ b/drivers/net/pcs/Kconfig
|
||||
@@ -29,6 +29,16 @@ config PCS_MTK_LYNXI
|
||||
This module provides helpers to phylink for managing the LynxI PCS
|
||||
which is part of MediaTek's SoC and Ethernet switch ICs.
|
||||
|
||||
+config PCS_MTK_USXGMII
|
||||
+ tristate "MediaTek USXGMII PCS"
|
||||
+ select PCS_STANDALONE
|
||||
+ select PHY_MTK_XFI_TPHY
|
||||
+ select PHYLINK
|
||||
+ help
|
||||
+ This module provides a driver for MediaTek's USXGMII PCS found in
|
||||
+ the MT7988 SoC, supporting USXGMII, 10GBase-R and 5GBase-R interface
|
||||
+ modes.
|
||||
+
|
||||
config PCS_RZN1_MIIC
|
||||
tristate "Renesas RZ/N1, RZ/N2H, RZ/T2H MII converter"
|
||||
depends on OF
|
||||
diff --git a/drivers/net/pcs/Makefile b/drivers/net/pcs/Makefile
|
||||
index 0cb0057f2b8e..b876cb2157b1 100644
|
||||
--- a/drivers/net/pcs/Makefile
|
||||
+++ b/drivers/net/pcs/Makefile
|
||||
@@ -8,4 +8,5 @@ obj-$(CONFIG_PCS_STANDALONE) += pcs-standalone.o
|
||||
obj-$(CONFIG_PCS_XPCS) += pcs_xpcs.o
|
||||
obj-$(CONFIG_PCS_LYNX) += pcs-lynx.o
|
||||
obj-$(CONFIG_PCS_MTK_LYNXI) += pcs-mtk-lynxi.o
|
||||
+obj-$(CONFIG_PCS_MTK_USXGMII) += pcs-mtk-usxgmii.o
|
||||
obj-$(CONFIG_PCS_RZN1_MIIC) += pcs-rzn1-miic.o
|
||||
diff --git a/drivers/net/pcs/pcs-mtk-usxgmii.c b/drivers/net/pcs/pcs-mtk-usxgmii.c
|
||||
new file mode 100644
|
||||
index 000000000000..f0e7d418db38
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/pcs/pcs-mtk-usxgmii.c
|
||||
@@ -0,0 +1,394 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0
|
||||
+/*
|
||||
+ * Copyright (c) 2023 MediaTek Inc.
|
||||
+ * Author: Henry Yen <henry.yen@mediatek.com>
|
||||
+ * Daniel Golle <daniel@makrotopia.org>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/mfd/syscon.h>
|
||||
+#include <linux/mdio.h>
|
||||
+#include <linux/mutex.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/of_platform.h>
|
||||
+#include <linux/reset.h>
|
||||
+#include <linux/pcs/pcs-standalone.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+
|
||||
+/* USXGMII subsystem config registers */
|
||||
+/* Register to control speed */
|
||||
+#define RG_PHY_TOP_SPEED_CTRL1 0x80c
|
||||
+#define USXGMII_RATE_UPDATE_MODE BIT(31)
|
||||
+#define USXGMII_MAC_CK_GATED BIT(29)
|
||||
+#define USXGMII_IF_FORCE_EN BIT(28)
|
||||
+#define USXGMII_RATE_ADAPT_MODE GENMASK(10, 8)
|
||||
+#define USXGMII_RATE_ADAPT_MODE_X1 0
|
||||
+#define USXGMII_RATE_ADAPT_MODE_X2 1
|
||||
+#define USXGMII_RATE_ADAPT_MODE_X4 2
|
||||
+#define USXGMII_RATE_ADAPT_MODE_X10 3
|
||||
+#define USXGMII_RATE_ADAPT_MODE_X100 4
|
||||
+#define USXGMII_RATE_ADAPT_MODE_X5 5
|
||||
+#define USXGMII_RATE_ADAPT_MODE_X50 6
|
||||
+#define USXGMII_XFI_RX_MODE GENMASK(6, 4)
|
||||
+#define USXGMII_XFI_TX_MODE GENMASK(2, 0)
|
||||
+#define USXGMII_XFI_MODE_10G 0
|
||||
+#define USXGMII_XFI_MODE_5G 1
|
||||
+#define USXGMII_XFI_MODE_2P5G 3
|
||||
+
|
||||
+/* Register to control PCS AN */
|
||||
+#define RG_PCS_AN_CTRL0 0x810
|
||||
+#define USXGMII_AN_RESTART BIT(31)
|
||||
+#define USXGMII_AN_SYNC_CNT GENMASK(30, 11)
|
||||
+#define USXGMII_AN_ENABLE BIT(0)
|
||||
+
|
||||
+#define RG_PCS_AN_CTRL2 0x818
|
||||
+#define USXGMII_LINK_TIMER_IDLE_DETECT GENMASK(29, 20)
|
||||
+#define USXGMII_LINK_TIMER_COMP_ACK_DETECT GENMASK(19, 10)
|
||||
+#define USXGMII_LINK_TIMER_AN_RESTART GENMASK(9, 0)
|
||||
+
|
||||
+/* Register to read PCS AN status */
|
||||
+#define RG_PCS_AN_STS0 0x81c
|
||||
+#define USXGMII_LPA GENMASK(15, 0)
|
||||
+#define USXGMII_LPA_LATCH BIT(31)
|
||||
+
|
||||
+/* Register to read PCS link status */
|
||||
+#define RG_PCS_RX_STATUS0 0x904
|
||||
+#define RG_PCS_RX_STATUS_UPDATE BIT(16)
|
||||
+#define RG_PCS_RX_LINK_STATUS BIT(2)
|
||||
+
|
||||
+/* struct mtk_usxgmii_pcs - This structure holds each usxgmii PCS
|
||||
+ * @pcs: Phylink PCS structure
|
||||
+ * @dev: Pointer to device structure
|
||||
+ * @base: IO memory to access PCS hardware
|
||||
+ * @clk: Pointer to USXGMII clk
|
||||
+ * @reset: Pointer to USXGMII reset control
|
||||
+ * @xfi_tphy: Pointer to XFI transceiver PHY
|
||||
+ * @interface: Currently selected interface mode
|
||||
+ * @node: List node
|
||||
+ */
|
||||
+struct mtk_usxgmii_pcs {
|
||||
+ struct phylink_pcs pcs;
|
||||
+ struct device *dev;
|
||||
+ void __iomem *base;
|
||||
+ struct clk *clk;
|
||||
+ struct reset_control *reset;
|
||||
+ struct phy *xfi_tphy;
|
||||
+ phy_interface_t interface;
|
||||
+ struct list_head node;
|
||||
+};
|
||||
+
|
||||
+static u32 mtk_r32(struct mtk_usxgmii_pcs *mpcs, unsigned int reg)
|
||||
+{
|
||||
+ return ioread32(mpcs->base + reg);
|
||||
+}
|
||||
+
|
||||
+static void mtk_m32(struct mtk_usxgmii_pcs *mpcs, unsigned int reg, u32 mask, u32 set)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ val = ioread32(mpcs->base + reg);
|
||||
+ val &= ~mask;
|
||||
+ val |= set;
|
||||
+ iowrite32(val, mpcs->base + reg);
|
||||
+}
|
||||
+
|
||||
+static struct mtk_usxgmii_pcs *pcs_to_mtk_usxgmii_pcs(struct phylink_pcs *pcs)
|
||||
+{
|
||||
+ return container_of(pcs, struct mtk_usxgmii_pcs, pcs);
|
||||
+}
|
||||
+
|
||||
+static void mtk_usxgmii_reset(struct mtk_usxgmii_pcs *mpcs)
|
||||
+{
|
||||
+ reset_control_assert(mpcs->reset);
|
||||
+ udelay(100);
|
||||
+ reset_control_deassert(mpcs->reset);
|
||||
+
|
||||
+ mdelay(10);
|
||||
+}
|
||||
+
|
||||
+static int mtk_usxgmii_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode,
|
||||
+ phy_interface_t interface,
|
||||
+ const unsigned long *advertising,
|
||||
+ bool permit_pause_to_mac)
|
||||
+{
|
||||
+ struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs);
|
||||
+ unsigned int an_ctrl = 0, link_timer = 0, xfi_mode = 0, adapt_mode = 0;
|
||||
+ bool mode_changed = false;
|
||||
+
|
||||
+ if (interface == PHY_INTERFACE_MODE_USXGMII) {
|
||||
+ an_ctrl = FIELD_PREP(USXGMII_AN_SYNC_CNT, 0x1FF) | USXGMII_AN_ENABLE;
|
||||
+ link_timer = FIELD_PREP(USXGMII_LINK_TIMER_IDLE_DETECT, 0x7B) |
|
||||
+ FIELD_PREP(USXGMII_LINK_TIMER_COMP_ACK_DETECT, 0x7B) |
|
||||
+ FIELD_PREP(USXGMII_LINK_TIMER_AN_RESTART, 0x7B);
|
||||
+ xfi_mode = FIELD_PREP(USXGMII_XFI_RX_MODE, USXGMII_XFI_MODE_10G) |
|
||||
+ FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_MODE_10G);
|
||||
+ } else if (interface == PHY_INTERFACE_MODE_10GBASER) {
|
||||
+ an_ctrl = FIELD_PREP(USXGMII_AN_SYNC_CNT, 0x1FF);
|
||||
+ link_timer = FIELD_PREP(USXGMII_LINK_TIMER_IDLE_DETECT, 0x7B) |
|
||||
+ FIELD_PREP(USXGMII_LINK_TIMER_COMP_ACK_DETECT, 0x7B) |
|
||||
+ FIELD_PREP(USXGMII_LINK_TIMER_AN_RESTART, 0x7B);
|
||||
+ xfi_mode = FIELD_PREP(USXGMII_XFI_RX_MODE, USXGMII_XFI_MODE_10G) |
|
||||
+ FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_MODE_10G);
|
||||
+ adapt_mode = USXGMII_RATE_UPDATE_MODE;
|
||||
+ } else if (interface == PHY_INTERFACE_MODE_5GBASER) {
|
||||
+ an_ctrl = FIELD_PREP(USXGMII_AN_SYNC_CNT, 0xFF);
|
||||
+ link_timer = FIELD_PREP(USXGMII_LINK_TIMER_IDLE_DETECT, 0x3D) |
|
||||
+ FIELD_PREP(USXGMII_LINK_TIMER_COMP_ACK_DETECT, 0x3D) |
|
||||
+ FIELD_PREP(USXGMII_LINK_TIMER_AN_RESTART, 0x3D);
|
||||
+ xfi_mode = FIELD_PREP(USXGMII_XFI_RX_MODE, USXGMII_XFI_MODE_5G) |
|
||||
+ FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_MODE_5G);
|
||||
+ adapt_mode = USXGMII_RATE_UPDATE_MODE;
|
||||
+ } else {
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ adapt_mode |= FIELD_PREP(USXGMII_RATE_ADAPT_MODE, USXGMII_RATE_ADAPT_MODE_X1);
|
||||
+
|
||||
+ if (mpcs->interface != interface) {
|
||||
+ mpcs->interface = interface;
|
||||
+ mode_changed = true;
|
||||
+ }
|
||||
+
|
||||
+ phy_reset(mpcs->xfi_tphy);
|
||||
+ mtk_usxgmii_reset(mpcs);
|
||||
+
|
||||
+ /* Setup USXGMII AN ctrl */
|
||||
+ mtk_m32(mpcs, RG_PCS_AN_CTRL0,
|
||||
+ USXGMII_AN_SYNC_CNT | USXGMII_AN_ENABLE,
|
||||
+ an_ctrl);
|
||||
+
|
||||
+ mtk_m32(mpcs, RG_PCS_AN_CTRL2,
|
||||
+ USXGMII_LINK_TIMER_IDLE_DETECT |
|
||||
+ USXGMII_LINK_TIMER_COMP_ACK_DETECT |
|
||||
+ USXGMII_LINK_TIMER_AN_RESTART,
|
||||
+ link_timer);
|
||||
+
|
||||
+ /* Gated MAC CK */
|
||||
+ mtk_m32(mpcs, RG_PHY_TOP_SPEED_CTRL1,
|
||||
+ USXGMII_MAC_CK_GATED, USXGMII_MAC_CK_GATED);
|
||||
+
|
||||
+ /* Enable interface force mode */
|
||||
+ mtk_m32(mpcs, RG_PHY_TOP_SPEED_CTRL1,
|
||||
+ USXGMII_IF_FORCE_EN, USXGMII_IF_FORCE_EN);
|
||||
+
|
||||
+ /* Setup USXGMII adapt mode */
|
||||
+ mtk_m32(mpcs, RG_PHY_TOP_SPEED_CTRL1,
|
||||
+ USXGMII_RATE_UPDATE_MODE | USXGMII_RATE_ADAPT_MODE,
|
||||
+ adapt_mode);
|
||||
+
|
||||
+ /* Setup USXGMII speed */
|
||||
+ mtk_m32(mpcs, RG_PHY_TOP_SPEED_CTRL1,
|
||||
+ USXGMII_XFI_RX_MODE | USXGMII_XFI_TX_MODE,
|
||||
+ xfi_mode);
|
||||
+
|
||||
+ usleep_range(1, 10);
|
||||
+
|
||||
+ /* Un-gated MAC CK */
|
||||
+ mtk_m32(mpcs, RG_PHY_TOP_SPEED_CTRL1, USXGMII_MAC_CK_GATED, 0);
|
||||
+
|
||||
+ usleep_range(1, 10);
|
||||
+
|
||||
+ /* Disable interface force mode for the AN mode */
|
||||
+ if (an_ctrl & USXGMII_AN_ENABLE)
|
||||
+ mtk_m32(mpcs, RG_PHY_TOP_SPEED_CTRL1, USXGMII_IF_FORCE_EN, 0);
|
||||
+
|
||||
+ /* Setup PMA/PMD */
|
||||
+ phy_set_mode_ext(mpcs->xfi_tphy, PHY_MODE_ETHERNET, interface);
|
||||
+
|
||||
+ return mode_changed;
|
||||
+}
|
||||
+
|
||||
+static void mtk_usxgmii_pcs_get_fixed_speed(struct mtk_usxgmii_pcs *mpcs,
|
||||
+ struct phylink_link_state *state)
|
||||
+{
|
||||
+ u32 val = mtk_r32(mpcs, RG_PHY_TOP_SPEED_CTRL1);
|
||||
+ int speed;
|
||||
+
|
||||
+ /* Calculate speed from interface speed and rate adapt mode */
|
||||
+ switch (FIELD_GET(USXGMII_XFI_RX_MODE, val)) {
|
||||
+ case USXGMII_XFI_MODE_10G:
|
||||
+ speed = 10000;
|
||||
+ break;
|
||||
+ case USXGMII_XFI_MODE_5G:
|
||||
+ speed = 5000;
|
||||
+ break;
|
||||
+ case USXGMII_XFI_MODE_2P5G:
|
||||
+ speed = 2500;
|
||||
+ break;
|
||||
+ default:
|
||||
+ state->speed = SPEED_UNKNOWN;
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ switch (FIELD_GET(USXGMII_RATE_ADAPT_MODE, val)) {
|
||||
+ case USXGMII_RATE_ADAPT_MODE_X100:
|
||||
+ speed /= 100;
|
||||
+ break;
|
||||
+ case USXGMII_RATE_ADAPT_MODE_X50:
|
||||
+ speed /= 50;
|
||||
+ break;
|
||||
+ case USXGMII_RATE_ADAPT_MODE_X10:
|
||||
+ speed /= 10;
|
||||
+ break;
|
||||
+ case USXGMII_RATE_ADAPT_MODE_X5:
|
||||
+ speed /= 5;
|
||||
+ break;
|
||||
+ case USXGMII_RATE_ADAPT_MODE_X4:
|
||||
+ speed /= 4;
|
||||
+ break;
|
||||
+ case USXGMII_RATE_ADAPT_MODE_X2:
|
||||
+ speed /= 2;
|
||||
+ break;
|
||||
+ case USXGMII_RATE_ADAPT_MODE_X1:
|
||||
+ break;
|
||||
+ default:
|
||||
+ state->speed = SPEED_UNKNOWN;
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ state->speed = speed;
|
||||
+ state->duplex = DUPLEX_FULL;
|
||||
+}
|
||||
+
|
||||
+static void mtk_usxgmii_pcs_get_an_state(struct mtk_usxgmii_pcs *mpcs,
|
||||
+ struct phylink_link_state *state)
|
||||
+{
|
||||
+ u16 lpa;
|
||||
+
|
||||
+ /* Refresh LPA by toggling LPA_LATCH */
|
||||
+ mtk_m32(mpcs, RG_PCS_AN_STS0, USXGMII_LPA_LATCH, USXGMII_LPA_LATCH);
|
||||
+ ndelay(1020);
|
||||
+ mtk_m32(mpcs, RG_PCS_AN_STS0, USXGMII_LPA_LATCH, 0);
|
||||
+ ndelay(1020);
|
||||
+ lpa = FIELD_GET(USXGMII_LPA, mtk_r32(mpcs, RG_PCS_AN_STS0));
|
||||
+
|
||||
+ phylink_decode_usxgmii_word(state, lpa);
|
||||
+}
|
||||
+
|
||||
+static void mtk_usxgmii_pcs_get_state(struct phylink_pcs *pcs,
|
||||
+ unsigned int neg_mode,
|
||||
+ struct phylink_link_state *state)
|
||||
+{
|
||||
+ struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs);
|
||||
+
|
||||
+ /* Refresh USXGMII link status by toggling RG_PCS_AN_STATUS_UPDATE */
|
||||
+ mtk_m32(mpcs, RG_PCS_RX_STATUS0, RG_PCS_RX_STATUS_UPDATE,
|
||||
+ RG_PCS_RX_STATUS_UPDATE);
|
||||
+ ndelay(1020);
|
||||
+ mtk_m32(mpcs, RG_PCS_RX_STATUS0, RG_PCS_RX_STATUS_UPDATE, 0);
|
||||
+ ndelay(1020);
|
||||
+
|
||||
+ /* Read USXGMII link status */
|
||||
+ state->link = FIELD_GET(RG_PCS_RX_LINK_STATUS,
|
||||
+ mtk_r32(mpcs, RG_PCS_RX_STATUS0));
|
||||
+
|
||||
+ if (!state->link)
|
||||
+ return;
|
||||
+
|
||||
+ if (FIELD_GET(USXGMII_AN_ENABLE, mtk_r32(mpcs, RG_PCS_AN_CTRL0)))
|
||||
+ mtk_usxgmii_pcs_get_an_state(mpcs, state);
|
||||
+ else
|
||||
+ mtk_usxgmii_pcs_get_fixed_speed(mpcs, state);
|
||||
+}
|
||||
+
|
||||
+static void mtk_usxgmii_pcs_restart_an(struct phylink_pcs *pcs)
|
||||
+{
|
||||
+ struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs);
|
||||
+
|
||||
+ mtk_m32(mpcs, RG_PCS_AN_CTRL0, USXGMII_AN_RESTART, USXGMII_AN_RESTART);
|
||||
+}
|
||||
+
|
||||
+static void mtk_usxgmii_pcs_link_up(struct phylink_pcs *pcs, unsigned int neg_mode,
|
||||
+ phy_interface_t interface,
|
||||
+ int speed, int duplex)
|
||||
+{
|
||||
+ /* Reconfiguring USXGMII to ensure the quality of the RX signal
|
||||
+ * after the line side link up.
|
||||
+ */
|
||||
+ mtk_usxgmii_pcs_config(pcs, neg_mode, interface, NULL, false);
|
||||
+}
|
||||
+
|
||||
+static int mtk_usxgmii_pcs_enable(struct phylink_pcs *pcs)
|
||||
+{
|
||||
+ struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs);
|
||||
+
|
||||
+ phy_power_on(mpcs->xfi_tphy);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void mtk_usxgmii_pcs_disable(struct phylink_pcs *pcs)
|
||||
+{
|
||||
+ struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs);
|
||||
+
|
||||
+ mpcs->interface = PHY_INTERFACE_MODE_NA;
|
||||
+
|
||||
+ phy_power_off(mpcs->xfi_tphy);
|
||||
+}
|
||||
+
|
||||
+static const struct phylink_pcs_ops mtk_usxgmii_pcs_ops = {
|
||||
+ .pcs_config = mtk_usxgmii_pcs_config,
|
||||
+ .pcs_get_state = mtk_usxgmii_pcs_get_state,
|
||||
+ .pcs_an_restart = mtk_usxgmii_pcs_restart_an,
|
||||
+ .pcs_link_up = mtk_usxgmii_pcs_link_up,
|
||||
+ .pcs_enable = mtk_usxgmii_pcs_enable,
|
||||
+ .pcs_disable = mtk_usxgmii_pcs_disable,
|
||||
+};
|
||||
+
|
||||
+static int mtk_usxgmii_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct device *dev = &pdev->dev;
|
||||
+ struct mtk_usxgmii_pcs *mpcs;
|
||||
+
|
||||
+ mpcs = devm_kzalloc(dev, sizeof(*mpcs), GFP_KERNEL);
|
||||
+ if (!mpcs)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ mpcs->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
+ if (IS_ERR(mpcs->base))
|
||||
+ return PTR_ERR(mpcs->base);
|
||||
+
|
||||
+ mpcs->dev = dev;
|
||||
+ mpcs->pcs.ops = &mtk_usxgmii_pcs_ops;
|
||||
+ mpcs->pcs.poll = true;
|
||||
+ mpcs->interface = PHY_INTERFACE_MODE_NA;
|
||||
+
|
||||
+ mpcs->clk = devm_clk_get_enabled(mpcs->dev, NULL);
|
||||
+ if (IS_ERR(mpcs->clk))
|
||||
+ return PTR_ERR(mpcs->clk);
|
||||
+
|
||||
+ mpcs->xfi_tphy = devm_of_phy_get(mpcs->dev, dev->of_node, NULL);
|
||||
+ if (IS_ERR(mpcs->xfi_tphy))
|
||||
+ return PTR_ERR(mpcs->xfi_tphy);
|
||||
+
|
||||
+ mpcs->reset = devm_reset_control_get_shared(dev, NULL);
|
||||
+ if (IS_ERR(mpcs->reset))
|
||||
+ return PTR_ERR(mpcs->reset);
|
||||
+
|
||||
+ reset_control_deassert(mpcs->reset);
|
||||
+
|
||||
+ platform_set_drvdata(pdev, mpcs);
|
||||
+
|
||||
+ return devm_pcs_register(dev, &mpcs->pcs);
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id mtk_usxgmii_of_mtable[] = {
|
||||
+ { .compatible = "mediatek,mt7988-usxgmiisys" },
|
||||
+ { /* sentinel */ },
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, mtk_usxgmii_of_mtable);
|
||||
+
|
||||
+static struct platform_driver mtk_usxgmii_driver = {
|
||||
+ .driver = {
|
||||
+ .name = "mtk_usxgmii",
|
||||
+ .suppress_bind_attrs = true,
|
||||
+ .of_match_table = mtk_usxgmii_of_mtable,
|
||||
+ },
|
||||
+ .probe = mtk_usxgmii_probe,
|
||||
+};
|
||||
+module_platform_driver(mtk_usxgmii_driver);
|
||||
+
|
||||
+MODULE_LICENSE("GPL");
|
||||
+MODULE_DESCRIPTION("MediaTek USXGMII PCS driver");
|
||||
+MODULE_AUTHOR("Daniel Golle <daniel@makrotopia.org>");
|
||||
--
|
||||
2.43.0
|
||||
|
||||
+296
@@ -0,0 +1,296 @@
|
||||
From 8917bfe8fac3e16e2c5958cdbf0b8258a7797539 Mon Sep 17 00:00:00 2001
|
||||
From: Joachim Wiberg <troglobit@gmail.com>
|
||||
Date: Mon, 6 Apr 2026 14:15:43 +0200
|
||||
Subject: [PATCH 44/47] net: ethernet: mediatek: add USXGMII support for MT7988
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Wires
|
||||
|
||||
Add support for the USXGMII path used by gmac1 and gmac2 on the MT7988
|
||||
SoC (BananaPi BPI-R4). Changes:
|
||||
|
||||
- mtk_eth_soc.h: add MTK_USXGMII capability bit, path bits for all
|
||||
three GMACs, SYSCFG0_SGMII_GMAC3_V2 mask, usxgmii_pcs pointer in
|
||||
struct mtk_mac, and update MT7988_CAPS to include the USXGMII paths
|
||||
and mux
|
||||
|
||||
- mtk_eth_path.c: add set_mux_gmac123_to_usxgmii() which clears the
|
||||
SGMII SYSCFG0 bits and for GMAC2 sets MUX_G2_USXGMII_SEL in
|
||||
TOP_MISC_NETSYS_PCS_MUX; add mtk_gmac_usxgmii_path_setup()
|
||||
|
||||
- mtk_eth_soc.c: wire up the USXGMII PCS — look up the pcs-handle DT
|
||||
property via devm_of_pcs_get() during MAC probe and store in
|
||||
mac->usxgmii_pcs; return it from mtk_mac_select_pcs() for USXGMII,
|
||||
10GBase-R and 5GBase-R modes; call mtk_gmac_usxgmii_path_setup() in
|
||||
mtk_mac_config(); allow in-band autoneg for XGMII interfaces
|
||||
|
||||
Based on work by Henry Yen <henry.yen@mediatek.com> and
|
||||
Daniel Golle <daniel@makrotopia.org>.
|
||||
|
||||
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/mtk_eth_path.c | 64 ++++++++++++++++++++
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 46 +++++++++++++-
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 32 +++++++++-
|
||||
3 files changed, 139 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_path.c b/drivers/net/ethernet/mediatek/mtk_eth_path.c
|
||||
index b4c01e2878f6..57380776032a 100644
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_path.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_path.c
|
||||
@@ -37,6 +37,12 @@ static const char *mtk_eth_path_name(u64 path)
|
||||
return "gmac2_gephy";
|
||||
case MTK_ETH_PATH_GDM1_ESW:
|
||||
return "gdm1_esw";
|
||||
+ case MTK_ETH_PATH_GMAC1_USXGMII:
|
||||
+ return "gmac1_usxgmii";
|
||||
+ case MTK_ETH_PATH_GMAC2_USXGMII:
|
||||
+ return "gmac2_usxgmii";
|
||||
+ case MTK_ETH_PATH_GMAC3_USXGMII:
|
||||
+ return "gmac3_usxgmii";
|
||||
default:
|
||||
return "unknown path";
|
||||
}
|
||||
@@ -221,6 +227,48 @@ static int set_mux_gmac12_to_gephy_sgmii(struct mtk_eth *eth, u64 path)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int set_mux_gmac123_to_usxgmii(struct mtk_eth *eth, u64 path)
|
||||
+{
|
||||
+ unsigned int val = 0;
|
||||
+ bool updated = true;
|
||||
+ int mac_id = 0;
|
||||
+
|
||||
+ /* Disable SYSCFG1 SGMII */
|
||||
+ regmap_read(eth->ethsys, ETHSYS_SYSCFG0, &val);
|
||||
+
|
||||
+ switch (path) {
|
||||
+ case MTK_ETH_PATH_GMAC1_USXGMII:
|
||||
+ val &= ~(u32)SYSCFG0_SGMII_GMAC1_V2;
|
||||
+ mac_id = MTK_GMAC1_ID;
|
||||
+ break;
|
||||
+ case MTK_ETH_PATH_GMAC2_USXGMII:
|
||||
+ val &= ~(u32)SYSCFG0_SGMII_GMAC2_V2;
|
||||
+ mac_id = MTK_GMAC2_ID;
|
||||
+ break;
|
||||
+ case MTK_ETH_PATH_GMAC3_USXGMII:
|
||||
+ val &= ~(u32)SYSCFG0_SGMII_GMAC3_V2;
|
||||
+ mac_id = MTK_GMAC3_ID;
|
||||
+ break;
|
||||
+ default:
|
||||
+ updated = false;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (updated) {
|
||||
+ regmap_update_bits(eth->ethsys, ETHSYS_SYSCFG0,
|
||||
+ SYSCFG0_SGMII_MASK, val);
|
||||
+
|
||||
+ if (mac_id == MTK_GMAC2_ID)
|
||||
+ regmap_set_bits(eth->infra, TOP_MISC_NETSYS_PCS_MUX,
|
||||
+ MUX_G2_USXGMII_SEL);
|
||||
+ }
|
||||
+
|
||||
+ dev_dbg(eth->dev, "path %s in %s updated = %d\n",
|
||||
+ mtk_eth_path_name(path), __func__, updated);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static const struct mtk_eth_muxc mtk_eth_muxc[] = {
|
||||
{
|
||||
.name = "mux_gdm1_to_gmac1_esw",
|
||||
@@ -246,6 +294,10 @@ static const struct mtk_eth_muxc mtk_eth_muxc[] = {
|
||||
.name = "mux_gmac12_to_gephy_sgmii",
|
||||
.cap_bit = MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII,
|
||||
.set_path = set_mux_gmac12_to_gephy_sgmii,
|
||||
+ }, {
|
||||
+ .name = "mux_gmac123_to_usxgmii",
|
||||
+ .cap_bit = MTK_ETH_MUX_GMAC123_TO_USXGMII,
|
||||
+ .set_path = set_mux_gmac123_to_usxgmii,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -328,3 +380,15 @@ int mtk_gmac_rgmii_path_setup(struct mtk_eth *eth, int mac_id)
|
||||
return mtk_eth_mux_setup(eth, path);
|
||||
}
|
||||
|
||||
+int mtk_gmac_usxgmii_path_setup(struct mtk_eth *eth, int mac_id)
|
||||
+{
|
||||
+ u64 path;
|
||||
+
|
||||
+ path = (mac_id == MTK_GMAC1_ID) ? MTK_ETH_PATH_GMAC1_USXGMII :
|
||||
+ (mac_id == MTK_GMAC2_ID) ? MTK_ETH_PATH_GMAC2_USXGMII :
|
||||
+ MTK_ETH_PATH_GMAC3_USXGMII;
|
||||
+
|
||||
+ /* Setup proper MUXes along the path */
|
||||
+ return mtk_eth_mux_setup(eth, path);
|
||||
+}
|
||||
+
|
||||
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
index 8d3e15bc867d..e6347b08648a 100644
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <linux/pinctrl/devinfo.h>
|
||||
#include <linux/phylink.h>
|
||||
#include <linux/pcs/pcs-mtk-lynxi.h>
|
||||
+#include <linux/pcs/pcs-standalone.h>
|
||||
#include <linux/jhash.h>
|
||||
#include <linux/bitfield.h>
|
||||
#include <net/dsa.h>
|
||||
@@ -522,6 +523,17 @@ static struct phylink_pcs *mtk_mac_select_pcs(struct phylink_config *config,
|
||||
struct mtk_eth *eth = mac->hw;
|
||||
unsigned int sid;
|
||||
|
||||
+ if (mtk_is_netsys_v3_or_greater(eth)) {
|
||||
+ switch (interface) {
|
||||
+ case PHY_INTERFACE_MODE_USXGMII:
|
||||
+ case PHY_INTERFACE_MODE_10GBASER:
|
||||
+ case PHY_INTERFACE_MODE_5GBASER:
|
||||
+ return mac->usxgmii_pcs;
|
||||
+ default:
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (interface == PHY_INTERFACE_MODE_SGMII ||
|
||||
phy_interface_mode_is_8023z(interface)) {
|
||||
sid = (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII)) ?
|
||||
@@ -601,6 +613,15 @@ static void mtk_mac_config(struct phylink_config *config, unsigned int mode,
|
||||
goto init_err;
|
||||
}
|
||||
break;
|
||||
+ case PHY_INTERFACE_MODE_USXGMII:
|
||||
+ case PHY_INTERFACE_MODE_10GBASER:
|
||||
+ case PHY_INTERFACE_MODE_5GBASER:
|
||||
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_USXGMII)) {
|
||||
+ err = mtk_gmac_usxgmii_path_setup(eth, mac->id);
|
||||
+ if (err)
|
||||
+ goto init_err;
|
||||
+ }
|
||||
+ break;
|
||||
default:
|
||||
goto err_phy;
|
||||
}
|
||||
@@ -664,7 +685,8 @@ static void mtk_mac_config(struct phylink_config *config, unsigned int mode,
|
||||
|
||||
/* Save the syscfg0 value for mac_finish */
|
||||
mac->syscfg0 = val;
|
||||
- } else if (phylink_autoneg_inband(mode)) {
|
||||
+ } else if (phylink_autoneg_inband(mode) &&
|
||||
+ !mtk_interface_mode_is_xgmii(eth, state->interface)) {
|
||||
dev_err(eth->dev,
|
||||
"In-band mode not supported in non SGMII mode!\n");
|
||||
return;
|
||||
@@ -4912,6 +4934,28 @@ static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np)
|
||||
mac->phylink_config.supported_interfaces);
|
||||
}
|
||||
|
||||
+ if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_USXGMII)) {
|
||||
+ struct phylink_pcs *pcs;
|
||||
+
|
||||
+ pcs = devm_of_pcs_get(eth->dev, np, 0);
|
||||
+ if (IS_ERR(pcs)) {
|
||||
+ if (PTR_ERR(pcs) == -ENODEV)
|
||||
+ return dev_err_probe(eth->dev, -EPROBE_DEFER,
|
||||
+ "waiting for USXGMII PCS\n");
|
||||
+ /* No pcs-handle property — USXGMII not wired for this MAC */
|
||||
+ } else if (pcs) {
|
||||
+ mac->usxgmii_pcs = pcs;
|
||||
+ mac->phylink_config.mac_capabilities |= MAC_5000FD |
|
||||
+ MAC_10000FD;
|
||||
+ __set_bit(PHY_INTERFACE_MODE_USXGMII,
|
||||
+ mac->phylink_config.supported_interfaces);
|
||||
+ __set_bit(PHY_INTERFACE_MODE_10GBASER,
|
||||
+ mac->phylink_config.supported_interfaces);
|
||||
+ __set_bit(PHY_INTERFACE_MODE_5GBASER,
|
||||
+ mac->phylink_config.supported_interfaces);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
phylink = phylink_create(&mac->phylink_config,
|
||||
of_fwnode_handle(mac->of_node),
|
||||
phy_mode, &mtk_phylink_ops);
|
||||
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
index 0168e2fbc619..2b27ef392b76 100644
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
@@ -567,6 +567,7 @@
|
||||
#define SYSCFG0_SGMII_GMAC2 ((3 << 8) & SYSCFG0_SGMII_MASK)
|
||||
#define SYSCFG0_SGMII_GMAC1_V2 BIT(9)
|
||||
#define SYSCFG0_SGMII_GMAC2_V2 BIT(8)
|
||||
+#define SYSCFG0_SGMII_GMAC3_V2 BIT(7)
|
||||
|
||||
|
||||
/* ethernet subsystem clock register */
|
||||
@@ -1012,6 +1013,13 @@ enum mkt_eth_capabilities {
|
||||
MTK_ETH_PATH_GMAC2_2P5GPHY_BIT,
|
||||
MTK_ETH_PATH_GMAC2_GEPHY_BIT,
|
||||
MTK_ETH_PATH_GDM1_ESW_BIT,
|
||||
+
|
||||
+ /* USXGMII capability and path bits */
|
||||
+ MTK_USXGMII_BIT,
|
||||
+ MTK_ETH_MUX_GMAC123_TO_USXGMII_BIT,
|
||||
+ MTK_ETH_PATH_GMAC1_USXGMII_BIT,
|
||||
+ MTK_ETH_PATH_GMAC2_USXGMII_BIT,
|
||||
+ MTK_ETH_PATH_GMAC3_USXGMII_BIT,
|
||||
};
|
||||
|
||||
/* Supported hardware group on SoCs */
|
||||
@@ -1092,6 +1100,23 @@ enum mkt_eth_capabilities {
|
||||
#define MTK_MUX_GMAC12_TO_GEPHY_SGMII \
|
||||
(MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII | MTK_MUX)
|
||||
|
||||
+/* USXGMII support */
|
||||
+#define MTK_USXGMII BIT_ULL(MTK_USXGMII_BIT)
|
||||
+
|
||||
+#define MTK_ETH_MUX_GMAC123_TO_USXGMII \
|
||||
+ BIT_ULL(MTK_ETH_MUX_GMAC123_TO_USXGMII_BIT)
|
||||
+
|
||||
+#define MTK_ETH_PATH_GMAC1_USXGMII BIT_ULL(MTK_ETH_PATH_GMAC1_USXGMII_BIT)
|
||||
+#define MTK_ETH_PATH_GMAC2_USXGMII BIT_ULL(MTK_ETH_PATH_GMAC2_USXGMII_BIT)
|
||||
+#define MTK_ETH_PATH_GMAC3_USXGMII BIT_ULL(MTK_ETH_PATH_GMAC3_USXGMII_BIT)
|
||||
+
|
||||
+#define MTK_GMAC1_USXGMII (MTK_ETH_PATH_GMAC1_USXGMII | MTK_USXGMII)
|
||||
+#define MTK_GMAC2_USXGMII (MTK_ETH_PATH_GMAC2_USXGMII | MTK_USXGMII)
|
||||
+#define MTK_GMAC3_USXGMII (MTK_ETH_PATH_GMAC3_USXGMII | MTK_USXGMII)
|
||||
+
|
||||
+#define MTK_MUX_GMAC123_TO_USXGMII \
|
||||
+ (MTK_ETH_MUX_GMAC123_TO_USXGMII | MTK_MUX | MTK_INFRA)
|
||||
+
|
||||
#define MTK_HAS_CAPS(caps, _x) (((caps) & (_x)) == (_x))
|
||||
|
||||
#define MT7621_CAPS (MTK_GMAC1_RGMII | MTK_GMAC1_TRGMII | \
|
||||
@@ -1124,8 +1149,9 @@ enum mkt_eth_capabilities {
|
||||
MTK_RSTCTRL_PPE1 | MTK_SRAM)
|
||||
|
||||
#define MT7988_CAPS (MTK_36BIT_DMA | MTK_GDM1_ESW | MTK_GMAC2_2P5GPHY | \
|
||||
- MTK_MUX_GMAC2_TO_2P5GPHY | MTK_QDMA | MTK_RSTCTRL_PPE1 | \
|
||||
- MTK_RSTCTRL_PPE2 | MTK_SRAM)
|
||||
+ MTK_GMAC2_USXGMII | MTK_GMAC3_USXGMII | \
|
||||
+ MTK_MUX_GMAC2_TO_2P5GPHY | MTK_MUX_GMAC123_TO_USXGMII | \
|
||||
+ MTK_QDMA | MTK_RSTCTRL_PPE1 | MTK_RSTCTRL_PPE2 | MTK_SRAM)
|
||||
|
||||
struct mtk_tx_dma_desc_info {
|
||||
dma_addr_t addr;
|
||||
@@ -1372,6 +1398,7 @@ struct mtk_mac {
|
||||
struct device_node *of_node;
|
||||
struct phylink *phylink;
|
||||
struct phylink_config phylink_config;
|
||||
+ struct phylink_pcs *usxgmii_pcs;
|
||||
struct mtk_eth *hw;
|
||||
struct mtk_hw_stats *hw_stats;
|
||||
__be32 hwlro_ip[MTK_MAX_LRO_IP_CNT];
|
||||
@@ -1506,6 +1533,7 @@ int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id);
|
||||
int mtk_gmac_2p5gphy_path_setup(struct mtk_eth *eth, int mac_id);
|
||||
int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id);
|
||||
int mtk_gmac_rgmii_path_setup(struct mtk_eth *eth, int mac_id);
|
||||
+int mtk_gmac_usxgmii_path_setup(struct mtk_eth *eth, int mac_id);
|
||||
|
||||
int mtk_eth_offload_init(struct mtk_eth *eth, u8 id);
|
||||
int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type,
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
From c62809d597945068569a95b7ccc0398d99db098f Mon Sep 17 00:00:00 2001
|
||||
From: Joachim Wiberg <troglobit@gmail.com>
|
||||
Date: Mon, 6 Apr 2026 14:15:56 +0200
|
||||
Subject: [PATCH 45/47] arm64: dts: mediatek: mt7988a: add USXGMII PCS nodes
|
||||
Organization: Wires
|
||||
|
||||
Add device nodes for the two USXGMII subsystem blocks (usxgmiisys0 at
|
||||
0x10080000 and usxgmiisys1 at 0x10081000), each referencing its clock,
|
||||
reset, and xfi_tphy SerDes PHY.
|
||||
|
||||
Wire gmac1 to usxgmiisys1 and gmac2 to usxgmiisys0 via the pcs-handle
|
||||
property, so the Ethernet driver can discover the PCS at probe time.
|
||||
|
||||
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
|
||||
---
|
||||
arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 20 ++++++++++++++++++++
|
||||
1 file changed, 20 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
|
||||
index 366203a72d6d..5ae43390f6c2 100644
|
||||
--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
|
||||
+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
|
||||
@@ -708,6 +708,24 @@ xfi_pll: clock-controller@11f40000 {
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
+ usxgmiisys0: pcs@10080000 {
|
||||
+ compatible = "mediatek,mt7988-usxgmiisys";
|
||||
+ reg = <0 0x10080000 0 0x1000>;
|
||||
+ resets = <&watchdog 12>;
|
||||
+ clocks = <&topckgen CLK_TOP_USXGMII_SBUS_0_SEL>;
|
||||
+ phys = <&xfi_tphy0>;
|
||||
+ #pcs-cells = <0>;
|
||||
+ };
|
||||
+
|
||||
+ usxgmiisys1: pcs@10081000 {
|
||||
+ compatible = "mediatek,mt7988-usxgmiisys";
|
||||
+ reg = <0 0x10081000 0 0x1000>;
|
||||
+ resets = <&watchdog 13>;
|
||||
+ clocks = <&topckgen CLK_TOP_USXGMII_SBUS_1_SEL>;
|
||||
+ phys = <&xfi_tphy1>;
|
||||
+ #pcs-cells = <0>;
|
||||
+ };
|
||||
+
|
||||
efuse@11f50000 {
|
||||
compatible = "mediatek,mt7988-efuse", "mediatek,efuse";
|
||||
reg = <0 0x11f50000 0 0x1000>;
|
||||
@@ -979,12 +997,14 @@ gmac1: mac@1 {
|
||||
compatible = "mediatek,eth-mac";
|
||||
reg = <1>;
|
||||
status = "disabled";
|
||||
+ pcs-handle = <&usxgmiisys1>;
|
||||
};
|
||||
|
||||
gmac2: mac@2 {
|
||||
compatible = "mediatek,eth-mac";
|
||||
reg = <2>;
|
||||
status = "disabled";
|
||||
+ pcs-handle = <&usxgmiisys0>;
|
||||
};
|
||||
|
||||
mdio_bus: mdio-bus {
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
From 12d076e64f65326cf9e453899b6ac5adb31374c3 Mon Sep 17 00:00:00 2001
|
||||
From: Joachim Wiberg <troglobit@gmail.com>
|
||||
Date: Mon, 6 Apr 2026 14:16:11 +0200
|
||||
Subject: [PATCH] arm64: dts: mediatek: bananapi-bpi-r4: enable SFP+ ports and
|
||||
WPS button
|
||||
Organization: Wires
|
||||
|
||||
Enable the SFP+ cages wired to gmac1 and gmac2. The USXGMII PCS nodes
|
||||
and xfi_tphy SerDes are wired up in mt7988a.dtsi; only status = "okay"
|
||||
was missing.
|
||||
|
||||
gmac2 (sfp1, WAN cage) is common to all R4 variants and is enabled in
|
||||
mt7988a-bananapi-bpi-r4.dtsi. gmac1 (sfp2, LAN cage) is present only
|
||||
on the standard R4 (2x SFP+) and is enabled here in the variant .dts.
|
||||
The 2g5 variant uses gmac1 for the internal 2.5G PHY instead.
|
||||
|
||||
Also add a gpio-keys node for the WPS/factory button on GPIO14 (active-low)
|
||||
reporting KEY_WPS_BUTTON. This is the physical button labeled WPS/Factory
|
||||
on the board silkscreen; GPIO14 is connected to it in the final hardware
|
||||
revision of the BPI-R4.
|
||||
|
||||
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
|
||||
---
|
||||
.../boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts | 1 +
|
||||
.../boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi | 13 ++++++++++++-
|
||||
2 files changed, 13 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
|
||||
index 4b3796ba82e3..499f0c91c213 100644
|
||||
--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
|
||||
+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
|
||||
@@ -27,6 +27,7 @@ &gmac1 {
|
||||
managed = "in-band-status";
|
||||
phy-mode = "usxgmii";
|
||||
sfp = <&sfp2>;
|
||||
+ status = "okay";
|
||||
};
|
||||
|
||||
&pca9545 {
|
||||
diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi
|
||||
index 0ff69dae45d3..2a904a76f3fe 100644
|
||||
--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi
|
||||
+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi
|
||||
@@ -3,9 +3,9 @@
|
||||
/dts-v1/;
|
||||
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
+#include <dt-bindings/input/input.h>
|
||||
#include <dt-bindings/leds/common.h>
|
||||
#include <dt-bindings/regulator/richtek,rt5190a-regulator.h>
|
||||
-#include <dt-bindings/leds/common.h>
|
||||
|
||||
#include "mt7988a.dtsi"
|
||||
|
||||
@@ -29,6 +29,16 @@ fan: pwm-fan {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
+ gpio-keys {
|
||||
+ compatible = "gpio-keys";
|
||||
+
|
||||
+ wps {
|
||||
+ label = "wps";
|
||||
+ gpios = <&pio 14 GPIO_ACTIVE_LOW>;
|
||||
+ linux,code = <KEY_WPS_BUTTON>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
gpio-leds {
|
||||
compatible = "gpio-leds";
|
||||
|
||||
@@ -152,6 +162,7 @@ &gmac2 {
|
||||
managed = "in-band-status";
|
||||
phy-mode = "usxgmii";
|
||||
sfp = <&sfp1>;
|
||||
+ status = "okay";
|
||||
};
|
||||
|
||||
&gsw_phy0 {
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
From 4b267c1be4141e0213b49d6d511051b8e6673f7c Mon Sep 17 00:00:00 2001
|
||||
From: Joachim Wiberg <troglobit@gmail.com>
|
||||
Date: Mon, 6 Apr 2026 14:16:16 +0200
|
||||
Subject: [PATCH 47/47] net: phy: sfp: add OEM SFP-10G-T-I quirk
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Wires
|
||||
|
||||
The industrial-temperature variant of the OEM SFP-10G-T copper module
|
||||
reports vendor PN "SFP-10G-T-I". Unlike the base "SFP-10G-T" which is a
|
||||
genuine RollBall module, the -I variant uses a plain XFI (10GBASER) host
|
||||
interface and does not implement the RollBall MDIO protocol.
|
||||
|
||||
Both variants zero the extended_cc field in EEPROM, which causes
|
||||
sfp_module_parse_support() to hit SFF8024_ECC_UNSPEC and set no interface
|
||||
modes, making phylink reject the module with "no common interface modes".
|
||||
|
||||
For the -I variant, add sfp_fixup_xfi_cc which only corrects the extended
|
||||
compliance code to SFF8024_ECC_10GBASE_T_SFI so the driver picks 10GBASER.
|
||||
Skipping the RollBall PHY probe avoids a ~7-minute boot-time delay
|
||||
(sfp_poll_timeout * retries ≈ 440 s) when no RollBall PHY is found.
|
||||
|
||||
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
|
||||
---
|
||||
drivers/net/phy/sfp.c | 11 +++++++++++
|
||||
1 file changed, 11 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c
|
||||
index ca0992533572..53aafabeefd4 100644
|
||||
--- a/drivers/net/phy/sfp.c
|
||||
+++ b/drivers/net/phy/sfp.c
|
||||
@@ -451,6 +451,16 @@ static void sfp_fixup_rollball_cc(struct sfp *sfp)
|
||||
sfp->id.base.extended_cc = SFF8024_ECC_10GBASE_T_SFI;
|
||||
}
|
||||
|
||||
+static void sfp_fixup_xfi_cc(struct sfp *sfp)
|
||||
+{
|
||||
+ /* Module has zeroed extended compliance code but uses a plain XFI
|
||||
+ * (10GBASER) host interface and does not support the Rollball MDIO
|
||||
+ * protocol. Only fix the compliance code so the driver picks 10GBASER;
|
||||
+ * skipping Rollball avoids a ~7 minute PHY probe retry delay on boot.
|
||||
+ */
|
||||
+ sfp->id.base.extended_cc = SFF8024_ECC_10GBASE_T_SFI;
|
||||
+}
|
||||
+
|
||||
static void sfp_quirk_2500basex(const struct sfp_eeprom_id *id,
|
||||
struct sfp_module_caps *caps)
|
||||
{
|
||||
@@ -559,6 +569,7 @@ static const struct sfp_quirk sfp_quirks[] = {
|
||||
SFP_QUIRK_F("OEM", "SFP-GE-T", sfp_fixup_ignore_tx_fault),
|
||||
|
||||
SFP_QUIRK_F("OEM", "SFP-10G-T", sfp_fixup_rollball_cc),
|
||||
+ SFP_QUIRK_F("OEM", "SFP-10G-T-I", sfp_fixup_xfi_cc),
|
||||
SFP_QUIRK_S("OEM", "SFP-2.5G-T", sfp_quirk_oem_2_5g),
|
||||
SFP_QUIRK_S("OEM", "SFP-2.5G-BX10-D", sfp_quirk_2500basex),
|
||||
SFP_QUIRK_S("OEM", "SFP-2.5G-BX10-U", sfp_quirk_2500basex),
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
From cde9fed496833b88094ed6e9fea11969a1be8e25 Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Mon, 10 Jun 2024 13:25:31 +0200
|
||||
Subject: [PATCH 01/10] hush: Remove Ctrl-C detection in loops
|
||||
Organization: Wires
|
||||
|
||||
Assume that the original intent was to emulate SIGINT to a shell. This
|
||||
only works as expected if the loop in question is the ouermost, and
|
||||
last, statement. In all other cases, it completely breaks the expected
|
||||
execution flow. It more or less resurrects Visual Basic's "On Error
|
||||
Resume Next".
|
||||
|
||||
Disable this behavior and delegate the problem of loop termination to
|
||||
the writer of the script instead.
|
||||
|
||||
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
|
||||
---
|
||||
common/cli_hush.c | 7 -------
|
||||
1 file changed, 7 deletions(-)
|
||||
|
||||
diff --git a/common/cli_hush.c b/common/cli_hush.c
|
||||
index 7bd6943d3ed..a58a2d24572 100644
|
||||
--- a/common/cli_hush.c
|
||||
+++ b/common/cli_hush.c
|
||||
@@ -1794,13 +1794,6 @@ static int run_list_real(struct pipe *pi)
|
||||
for (; pi; pi = (flag_restore != 0) ? rpipe : pi->next) {
|
||||
if (pi->r_mode == RES_WHILE || pi->r_mode == RES_UNTIL ||
|
||||
pi->r_mode == RES_FOR) {
|
||||
-#ifdef __U_BOOT__
|
||||
- /* check Ctrl-C */
|
||||
- ctrlc();
|
||||
- if ((had_ctrlc())) {
|
||||
- return 1;
|
||||
- }
|
||||
-#endif
|
||||
flag_restore = 0;
|
||||
if (!rpipe) {
|
||||
flag_rep = 0;
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
From 020c9a036f2916afdce9d18aacc9e8c09a5dfca7 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Mattias=20Walstr=C3=B6m?= <lazzer@gmail.com>
|
||||
Date: Sat, 6 Sep 2025 22:18:27 +0200
|
||||
Subject: [PATCH 02/10] cmd: new command rpidisplay
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Wires
|
||||
|
||||
Signed-off-by: Mattias Walström <lazzer@gmail.com>
|
||||
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
|
||||
---
|
||||
cmd/Kconfig | 14 ++++++++
|
||||
cmd/Makefile | 2 +-
|
||||
cmd/rpi_display.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 96 insertions(+), 1 deletion(-)
|
||||
create mode 100644 cmd/rpi_display.c
|
||||
|
||||
diff --git a/cmd/Kconfig b/cmd/Kconfig
|
||||
index 5c611fb3016..5b69cd3a439 100644
|
||||
--- a/cmd/Kconfig
|
||||
+++ b/cmd/Kconfig
|
||||
@@ -183,6 +183,20 @@ config CMD_UFETCH
|
||||
Fetch utility for U-Boot (akin to neofetch). Prints information
|
||||
about U-Boot and the board it is running on in a pleasing format.
|
||||
|
||||
+config CMD_RPI_DISPLAY
|
||||
+ bool "rpidisplay"
|
||||
+ depends on ARCH_BCM283X
|
||||
+ help
|
||||
+ Enable commands to detect Raspberry Pi 7" DSI display connection.
|
||||
+
|
||||
+ This provides two commands:
|
||||
+ - rpidisplay: Shows detailed detection information
|
||||
+ - testrpidisplay: Silent test for use in boot scripts
|
||||
+
|
||||
+ Detection is performed by querying the VideoCore GPU for the
|
||||
+ active display resolution. The official Raspberry Pi 7" DSI
|
||||
+ display uses 800x480 resolution.
|
||||
+
|
||||
config CMD_FWU_METADATA
|
||||
bool "fwu metadata read"
|
||||
depends on FWU_MULTI_BANK_UPDATE
|
||||
diff --git a/cmd/Makefile b/cmd/Makefile
|
||||
index 25479907797..94b6890df0e 100644
|
||||
--- a/cmd/Makefile
|
||||
+++ b/cmd/Makefile
|
||||
@@ -50,6 +50,7 @@ obj-$(CONFIG_CMD_CLK) += clk.o
|
||||
obj-$(CONFIG_CMD_CLS) += cls.o
|
||||
obj-$(CONFIG_CMD_CONFIG) += config.o
|
||||
obj-$(CONFIG_CMD_CONITRACE) += conitrace.o
|
||||
+obj-$(CONFIG_CMD_RPI_DISPLAY) += rpi_display.o
|
||||
obj-$(CONFIG_CMD_CONSOLE) += console.o
|
||||
obj-$(CONFIG_CMD_CPU) += cpu.o
|
||||
obj-$(CONFIG_CMD_DATE) += date.o
|
||||
@@ -204,7 +205,6 @@ obj-$(CONFIG_CMD_LZMADEC) += lzmadec.o
|
||||
obj-$(CONFIG_CMD_UFS) += ufs.o
|
||||
obj-$(CONFIG_CMD_USB) += usb.o disk.o
|
||||
obj-$(CONFIG_CMD_VIDCONSOLE) += video.o
|
||||
-
|
||||
obj-$(CONFIG_CMD_FASTBOOT) += fastboot.o
|
||||
obj-$(CONFIG_CMD_FS_UUID) += fs_uuid.o
|
||||
|
||||
diff --git a/cmd/rpi_display.c b/cmd/rpi_display.c
|
||||
new file mode 100644
|
||||
index 00000000000..07abdc08552
|
||||
--- /dev/null
|
||||
+++ b/cmd/rpi_display.c
|
||||
@@ -0,0 +1,81 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0+
|
||||
+/*
|
||||
+ * Raspberry Pi 7" DSI Display Detection Command
|
||||
+ * Detects if the official Raspberry Pi 7" DSI display is connected
|
||||
+ */
|
||||
+
|
||||
+#include <command.h>
|
||||
+#include <asm/arch/msg.h>
|
||||
+
|
||||
+static int do_rpi_display(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
|
||||
+{
|
||||
+ int width, height;
|
||||
+ int ret;
|
||||
+
|
||||
+ printf("=== Raspberry Pi 7\" DSI Display Detection ===\n");
|
||||
+
|
||||
+ /* Use official VideoCore mailbox interface to get display resolution */
|
||||
+ ret = bcm2835_get_video_size(&width, &height);
|
||||
+ if (ret) {
|
||||
+ printf("Failed to query VideoCore display size (ret=%d)\n", ret);
|
||||
+ printf("Display Status: NOT DETECTED\n");
|
||||
+ return 2;
|
||||
+ }
|
||||
+
|
||||
+ printf("VideoCore reports display: %dx%d", width, height);
|
||||
+
|
||||
+ /* Official Raspberry Pi 7" DSI display is 800x480 */
|
||||
+ if (width == 800 && height == 480) {
|
||||
+ printf(" - RASPBERRY PI 7\" DSI DISPLAY DETECTED!\n");
|
||||
+ printf("Display Status: CONNECTED\n");
|
||||
+ return 0;
|
||||
+ }
|
||||
+ /* No resolution could indicate no display */
|
||||
+ else if (width == 0 || height == 0) {
|
||||
+ printf(" - No active display\n");
|
||||
+ printf("Display Status: NOT DETECTED\n");
|
||||
+ return 1;
|
||||
+ }
|
||||
+ else {
|
||||
+ printf(" - Not Raspberry Pi DSI display (resolution %dx%d)\n", width, height);
|
||||
+ printf("Display Status: NOT DETECTED\n");
|
||||
+ return 1;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int do_test_rpi_display(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
|
||||
+{
|
||||
+ int width, height;
|
||||
+ int ret;
|
||||
+
|
||||
+ /* Silent test using VideoCore mailbox interface */
|
||||
+ ret = bcm2835_get_video_size(&width, &height);
|
||||
+ if (ret) {
|
||||
+ return 2; /* Failed to query VideoCore */
|
||||
+ }
|
||||
+
|
||||
+ /* Check for Raspberry Pi DSI display resolutions */
|
||||
+ if ((width == 800 && height == 480)) {
|
||||
+ return 0; /* DSI display found */
|
||||
+ }
|
||||
+
|
||||
+ return 1; /* DSI display not found */
|
||||
+}
|
||||
+
|
||||
+U_BOOT_CMD(
|
||||
+ rpidisplay, 1, 1, do_rpi_display,
|
||||
+ "detect Raspberry Pi DSI display",
|
||||
+ "\n"
|
||||
+ "Detects Raspberry Pi 7\" DSI display by checking resolution:\n"
|
||||
+ " - 800x480 = Official Raspberry Pi 7\" DSI display\n"
|
||||
+ "Returns: 0=connected, 1=not detected, 2=no video"
|
||||
+);
|
||||
+
|
||||
+U_BOOT_CMD(
|
||||
+ testrpidisplay, 1, 1, do_test_rpi_display,
|
||||
+ "silent test for Raspberry Pi DSI display",
|
||||
+ "\n"
|
||||
+ "Silent test for Raspberry Pi DSI display (for use in scripts):\n"
|
||||
+ "Returns: 0=connected, 1=not detected, 2=no video\n"
|
||||
+ "Usage: if testrpidisplay; then echo DSI found; fi"
|
||||
+);
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
From 1a861c65011f636e464ca557804dfb6853a3871c Mon Sep 17 00:00:00 2001
|
||||
From: Joachim Wiberg <troglobit@gmail.com>
|
||||
Date: Thu, 12 Feb 2026 10:00:02 +0100
|
||||
Subject: [PATCH 03/10] arm: dts: at91: sama7g5ek supports high-speed on mmc0
|
||||
(eMMC)
|
||||
Organization: Wires
|
||||
|
||||
- eMMC high-speed timing is supported
|
||||
- eMMC hardware reset is supported
|
||||
|
||||
Tested on sama7g5ek rev 5.
|
||||
|
||||
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
|
||||
---
|
||||
arch/arm/dts/at91-sama7g5ek.dts | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/dts/at91-sama7g5ek.dts b/arch/arm/dts/at91-sama7g5ek.dts
|
||||
index 9b247fcaf66..45fe6a7f6cd 100644
|
||||
--- a/arch/arm/dts/at91-sama7g5ek.dts
|
||||
+++ b/arch/arm/dts/at91-sama7g5ek.dts
|
||||
@@ -776,8 +776,8 @@
|
||||
&sdmmc0 {
|
||||
bus-width = <8>;
|
||||
non-removable;
|
||||
- no-1-8-v;
|
||||
- sdhci-caps-mask = <0x0 0x00200000>;
|
||||
+ cap-mmc-highspeed;
|
||||
+ cap-mmc-hw-reset;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_sdmmc0_default>;
|
||||
status = "okay";
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
From 3fadc90e8c1017aa3d8c165e54a13d8f75536b99 Mon Sep 17 00:00:00 2001
|
||||
From: Mihai Sain <mihai.sain@microchip.com>
|
||||
Date: Fri, 5 May 2023 13:28:31 +0300
|
||||
Subject: [PATCH 04/10] arm: dts: at91: sama7g5ek: increase clock for sdmmc
|
||||
from 25 MHz to 50 MHz
|
||||
Organization: Wires
|
||||
|
||||
Current clock for sdmmc0 and sdmmc1 is 25 MHz because of the caps forced
|
||||
by the mainline kernel.
|
||||
|
||||
Remove the caps in order to increase the clock to 50 MHz. This will
|
||||
improve the boot time when reading the kernel binary. Tested on
|
||||
sama7g5ek rev 5 using mmcinfo command.
|
||||
|
||||
Signed-off-by: Mihai Sain <mihai.sain@microchip.com>
|
||||
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
|
||||
---
|
||||
arch/arm/dts/at91-sama7g5ek.dts | 2 --
|
||||
1 file changed, 2 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/dts/at91-sama7g5ek.dts b/arch/arm/dts/at91-sama7g5ek.dts
|
||||
index 45fe6a7f6cd..d2d16bd5f1f 100644
|
||||
--- a/arch/arm/dts/at91-sama7g5ek.dts
|
||||
+++ b/arch/arm/dts/at91-sama7g5ek.dts
|
||||
@@ -785,8 +785,6 @@
|
||||
|
||||
&sdmmc1 {
|
||||
bus-width = <4>;
|
||||
- no-1-8-v;
|
||||
- sdhci-caps-mask = <0x0 0x00200000>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_sdmmc1_default>;
|
||||
status = "okay";
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -0,0 +1,977 @@
|
||||
From b8b781fd58eb8f0934edde8db45744d0a417cda8 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Mattias=20Walstr=C3=B6m?= <lazzer@gmail.com>
|
||||
Date: Wed, 18 Feb 2026 17:00:09 +0100
|
||||
Subject: [PATCH 05/10] net: phy: Add the Airoha EN8811H PHY driver
|
||||
Organization: Wires
|
||||
|
||||
Add the driver for the Airoha EN8811H 2.5 Gigabit PHY. The PHY supports
|
||||
100/1000/2500 Mbps with auto negotiation only.
|
||||
|
||||
The driver uses two firmware files, for which updated versions are added to
|
||||
linux-firmware already.
|
||||
|
||||
Locating the AIROHA FW within the filesystem at the designated partition
|
||||
and path will trigger its automatic loading and writing to the PHY via MDIO.
|
||||
If need board specific loading override,
|
||||
please override the en8811h_read_fw function on board or architecture level.
|
||||
|
||||
Linux upstream AIROHA EN8811H driver commit:
|
||||
71e79430117d56c409c5ea485a263bc0d8083390
|
||||
|
||||
Based on the Linux upstream AIROHA EN8811H driver code(air_en8811h.c),
|
||||
I have modified the relevant process to align with the U-Boot boot sequence.
|
||||
and have validated this on Banana Pi BPI-R3 Mini.
|
||||
|
||||
Signed-off-by: Lucien.Jheng <lucienzx159@gmail.com>
|
||||
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
|
||||
---
|
||||
drivers/net/phy/Kconfig | 25 +
|
||||
drivers/net/phy/Makefile | 1 +
|
||||
drivers/net/phy/air_en8811h.c | 887 ++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 913 insertions(+)
|
||||
create mode 100644 drivers/net/phy/air_en8811h.c
|
||||
|
||||
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
|
||||
index 018be98705a..bc5b9d8a8c4 100644
|
||||
--- a/drivers/net/phy/Kconfig
|
||||
+++ b/drivers/net/phy/Kconfig
|
||||
@@ -83,6 +83,31 @@ config PHY_ADIN
|
||||
help
|
||||
Add support for configuring RGMII on Analog Devices ADIN PHYs.
|
||||
|
||||
+menuconfig PHY_AIROHA
|
||||
+ bool "Airoha Ethernet PHYs support"
|
||||
+
|
||||
+config PHY_AIROHA_EN8811H
|
||||
+ bool "Airoha Ethernet EN8811H support"
|
||||
+ depends on PHY_AIROHA
|
||||
+ help
|
||||
+ AIROHA EN8811H supported.
|
||||
+
|
||||
+choice
|
||||
+ prompt "Location of the Airoha PHY firmware"
|
||||
+ default PHY_AIROHA_FW_IN_MMC
|
||||
+ depends on PHY_AIROHA_EN8811H
|
||||
+
|
||||
+config PHY_AIROHA_FW_IN_MMC
|
||||
+ bool "Airoha firmware in MMC partition"
|
||||
+ help
|
||||
+ Airoha PHYs use firmware which can be loaded automatically
|
||||
+ from storage directly attached to the PHY, and then loaded
|
||||
+ via MDIO commands by the boot loader. The firmware is loaded
|
||||
+ from a file specified by the U-Boot environment variables
|
||||
+ en8811h_fw_part, en8811h_fw_dm_dir, and en8811h_fw_dsp_dir.
|
||||
+
|
||||
+endchoice
|
||||
+
|
||||
menuconfig PHY_AQUANTIA
|
||||
bool "Aquantia Ethernet PHYs support"
|
||||
select PHY_GIGE
|
||||
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
|
||||
index a339b8ac29d..431d1eef083 100644
|
||||
--- a/drivers/net/phy/Makefile
|
||||
+++ b/drivers/net/phy/Makefile
|
||||
@@ -11,6 +11,7 @@ obj-$(CONFIG_MV88E6352_SWITCH) += mv88e6352.o
|
||||
obj-$(CONFIG_PHYLIB) += phy.o
|
||||
obj-$(CONFIG_PHYLIB_10G) += generic_10g.o
|
||||
obj-$(CONFIG_PHY_ADIN) += adin.o
|
||||
+obj-$(CONFIG_PHY_AIROHA_EN8811H) += air_en8811h.o
|
||||
obj-$(CONFIG_PHY_AQUANTIA) += aquantia.o
|
||||
obj-$(CONFIG_PHY_ATHEROS) += atheros.o
|
||||
obj-$(CONFIG_PHY_BROADCOM) += broadcom.o
|
||||
diff --git a/drivers/net/phy/air_en8811h.c b/drivers/net/phy/air_en8811h.c
|
||||
new file mode 100644
|
||||
index 00000000000..d856d48b4a5
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/phy/air_en8811h.c
|
||||
@@ -0,0 +1,887 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0+
|
||||
+/*
|
||||
+ * Driver for the Airoha EN8811H 2.5 Gigabit PHY.
|
||||
+ *
|
||||
+ * Limitations of the EN8811H:
|
||||
+ * - Only full duplex supported
|
||||
+ * - Forced speed (AN off) is not supported by hardware (100Mbps)
|
||||
+ *
|
||||
+ * Source originated from linux air_en8811h.c
|
||||
+ *
|
||||
+ * Copyright (C) 2025 Airoha Technology Corp.
|
||||
+ */
|
||||
+#include <phy.h>
|
||||
+#include <errno.h>
|
||||
+#include <log.h>
|
||||
+#include <env.h>
|
||||
+#include <malloc.h>
|
||||
+#include <fs.h>
|
||||
+#include <asm/unaligned.h>
|
||||
+#include <linux/iopoll.h>
|
||||
+#include <linux/bitops.h>
|
||||
+#include <linux/compat.h>
|
||||
+#include <dm/device_compat.h>
|
||||
+#include <u-boot/crc.h>
|
||||
+
|
||||
+#define EN8811H_PHY_ID 0x03a2a411
|
||||
+
|
||||
+#define AIR_FW_ADDR_DM 0x00000000
|
||||
+#define AIR_FW_ADDR_DSP 0x00100000
|
||||
+
|
||||
+#define EN8811H_MD32_DM_SIZE 0x4000
|
||||
+#define EN8811H_MD32_DSP_SIZE 0x20000
|
||||
+
|
||||
+ #define EN8811H_FW_CTRL_1 0x0f0018
|
||||
+ #define EN8811H_FW_CTRL_1_START 0x0
|
||||
+ #define EN8811H_FW_CTRL_1_FINISH 0x1
|
||||
+ #define EN8811H_FW_CTRL_2 0x800000
|
||||
+ #define EN8811H_FW_CTRL_2_LOADING BIT(11)
|
||||
+
|
||||
+ /* MII Registers */
|
||||
+ #define AIR_AUX_CTRL_STATUS 0x1d
|
||||
+ #define AIR_AUX_CTRL_STATUS_SPEED_MASK GENMASK(4, 2)
|
||||
+ #define AIR_AUX_CTRL_STATUS_SPEED_100 0x4
|
||||
+ #define AIR_AUX_CTRL_STATUS_SPEED_1000 0x8
|
||||
+ #define AIR_AUX_CTRL_STATUS_SPEED_2500 0xc
|
||||
+
|
||||
+#define AIR_EXT_PAGE_ACCESS 0x1f
|
||||
+#define AIR_PHY_PAGE_STANDARD 0x0000
|
||||
+#define AIR_PHY_PAGE_EXTENDED_4 0x0004
|
||||
+
|
||||
+/* MII Registers Page 4*/
|
||||
+#define AIR_BPBUS_MODE 0x10
|
||||
+#define AIR_BPBUS_MODE_ADDR_FIXED 0x0000
|
||||
+#define AIR_BPBUS_MODE_ADDR_INCR BIT(15)
|
||||
+#define AIR_BPBUS_WR_ADDR_HIGH 0x11
|
||||
+#define AIR_BPBUS_WR_ADDR_LOW 0x12
|
||||
+#define AIR_BPBUS_WR_DATA_HIGH 0x13
|
||||
+#define AIR_BPBUS_WR_DATA_LOW 0x14
|
||||
+#define AIR_BPBUS_RD_ADDR_HIGH 0x15
|
||||
+#define AIR_BPBUS_RD_ADDR_LOW 0x16
|
||||
+#define AIR_BPBUS_RD_DATA_HIGH 0x17
|
||||
+#define AIR_BPBUS_RD_DATA_LOW 0x18
|
||||
+
|
||||
+/* Registers on MDIO_MMD_VEND1 */
|
||||
+#define EN8811H_PHY_FW_STATUS 0x8009
|
||||
+#define EN8811H_PHY_READY 0x02
|
||||
+
|
||||
+/* Registers on MDIO_MMD_VEND2 */
|
||||
+#define AIR_PHY_LED_BCR 0x021
|
||||
+#define AIR_PHY_LED_BCR_MODE_MASK GENMASK(1, 0)
|
||||
+#define AIR_PHY_LED_BCR_TIME_TEST BIT(2)
|
||||
+#define AIR_PHY_LED_BCR_CLK_EN BIT(3)
|
||||
+#define AIR_PHY_LED_BCR_EXT_CTRL BIT(15)
|
||||
+
|
||||
+#define AIR_PHY_LED_DUR_ON 0x022
|
||||
+
|
||||
+#define AIR_PHY_LED_DUR_BLINK 0x023
|
||||
+
|
||||
+#define AIR_PHY_LED_ON(i) (0x024 + ((i) * 2))
|
||||
+#define AIR_PHY_LED_ON_MASK (GENMASK(6, 0) | BIT(8))
|
||||
+#define AIR_PHY_LED_ON_LINK1000 BIT(0)
|
||||
+#define AIR_PHY_LED_ON_LINK100 BIT(1)
|
||||
+#define AIR_PHY_LED_ON_LINK10 BIT(2)
|
||||
+#define AIR_PHY_LED_ON_LINKDOWN BIT(3)
|
||||
+#define AIR_PHY_LED_ON_FDX BIT(4) /* Full duplex */
|
||||
+#define AIR_PHY_LED_ON_HDX BIT(5) /* Half duplex */
|
||||
+#define AIR_PHY_LED_ON_FORCE_ON BIT(6)
|
||||
+#define AIR_PHY_LED_ON_LINK2500 BIT(8)
|
||||
+#define AIR_PHY_LED_ON_POLARITY BIT(14)
|
||||
+#define AIR_PHY_LED_ON_ENABLE BIT(15)
|
||||
+
|
||||
+#define AIR_PHY_LED_BLINK(i) (0x025 + ((i) * 2))
|
||||
+#define AIR_PHY_LED_BLINK_1000TX BIT(0)
|
||||
+#define AIR_PHY_LED_BLINK_1000RX BIT(1)
|
||||
+#define AIR_PHY_LED_BLINK_100TX BIT(2)
|
||||
+#define AIR_PHY_LED_BLINK_100RX BIT(3)
|
||||
+#define AIR_PHY_LED_BLINK_10TX BIT(4)
|
||||
+#define AIR_PHY_LED_BLINK_10RX BIT(5)
|
||||
+#define AIR_PHY_LED_BLINK_COLLISION BIT(6)
|
||||
+#define AIR_PHY_LED_BLINK_RX_CRC_ERR BIT(7)
|
||||
+#define AIR_PHY_LED_BLINK_RX_IDLE_ERR BIT(8)
|
||||
+#define AIR_PHY_LED_BLINK_FORCE_BLINK BIT(9)
|
||||
+#define AIR_PHY_LED_BLINK_2500TX BIT(10)
|
||||
+#define AIR_PHY_LED_BLINK_2500RX BIT(11)
|
||||
+
|
||||
+#define EN8811H_FW_VERSION 0x3b3c
|
||||
+
|
||||
+#define EN8811H_POLARITY 0xca0f8
|
||||
+#define EN8811H_POLARITY_TX_NORMAL BIT(0)
|
||||
+#define EN8811H_POLARITY_RX_REVERSE BIT(1)
|
||||
+
|
||||
+#define EN8811H_CLK_CGM 0xcf958
|
||||
+#define EN8811H_CLK_CGM_CKO BIT(26)
|
||||
+#define EN8811H_HWTRAP1 0xcf914
|
||||
+#define EN8811H_HWTRAP1_CKO BIT(12)
|
||||
+
|
||||
+#define air_upper_16_bits(n) ((u16)((n) >> 16))
|
||||
+#define air_lower_16_bits(n) ((u16)((n) & 0xffff))
|
||||
+#define clear_bit(bit, bitmap) __clear_bit(bit, bitmap)
|
||||
+
|
||||
+/* Led definitions */
|
||||
+#define EN8811H_LED_COUNT 3
|
||||
+
|
||||
+struct led {
|
||||
+ unsigned long rules;
|
||||
+ unsigned long state;
|
||||
+};
|
||||
+
|
||||
+enum {
|
||||
+ AIR_PHY_LED_STATE_FORCE_ON,
|
||||
+ AIR_PHY_LED_STATE_FORCE_BLINK,
|
||||
+};
|
||||
+
|
||||
+enum {
|
||||
+ AIR_PHY_LED_DUR_BLINK_32MS,
|
||||
+ AIR_PHY_LED_DUR_BLINK_64MS,
|
||||
+ AIR_PHY_LED_DUR_BLINK_128MS,
|
||||
+ AIR_PHY_LED_DUR_BLINK_256MS,
|
||||
+ AIR_PHY_LED_DUR_BLINK_512MS,
|
||||
+ AIR_PHY_LED_DUR_BLINK_1024MS,
|
||||
+};
|
||||
+
|
||||
+enum {
|
||||
+ AIR_LED_DISABLE,
|
||||
+ AIR_LED_ENABLE,
|
||||
+};
|
||||
+
|
||||
+enum {
|
||||
+ AIR_ACTIVE_LOW,
|
||||
+ AIR_ACTIVE_HIGH,
|
||||
+};
|
||||
+
|
||||
+enum {
|
||||
+ AIR_LED_MODE_DISABLE,
|
||||
+ AIR_LED_MODE_USER_DEFINE,
|
||||
+};
|
||||
+
|
||||
+/* Trigger specific enum */
|
||||
+enum air_led_trigger_netdev_modes {
|
||||
+ AIR_TRIGGER_NETDEV_LINK = 0,
|
||||
+ AIR_TRIGGER_NETDEV_LINK_10,
|
||||
+ AIR_TRIGGER_NETDEV_LINK_100,
|
||||
+ AIR_TRIGGER_NETDEV_LINK_1000,
|
||||
+ AIR_TRIGGER_NETDEV_LINK_2500,
|
||||
+ AIR_TRIGGER_NETDEV_LINK_5000,
|
||||
+ AIR_TRIGGER_NETDEV_LINK_10000,
|
||||
+ AIR_TRIGGER_NETDEV_HALF_DUPLEX,
|
||||
+ AIR_TRIGGER_NETDEV_FULL_DUPLEX,
|
||||
+ AIR_TRIGGER_NETDEV_TX,
|
||||
+ AIR_TRIGGER_NETDEV_RX,
|
||||
+ AIR_TRIGGER_NETDEV_TX_ERR,
|
||||
+ AIR_TRIGGER_NETDEV_RX_ERR,
|
||||
+
|
||||
+ /* Keep last */
|
||||
+ __AIR_TRIGGER_NETDEV_MAX,
|
||||
+};
|
||||
+
|
||||
+/* Default LED setup:
|
||||
+ * GPIO5 <-> LED0 On: Link detected, blink Rx/Tx
|
||||
+ * GPIO4 <-> LED1 On: Link detected at 2500 and 1000 Mbps
|
||||
+ * GPIO3 <-> LED2 On: Link detected at 2500 and 100 Mbps
|
||||
+ */
|
||||
+#define AIR_DEFAULT_TRIGGER_LED0 (BIT(AIR_TRIGGER_NETDEV_LINK) | \
|
||||
+ BIT(AIR_TRIGGER_NETDEV_RX) | \
|
||||
+ BIT(AIR_TRIGGER_NETDEV_TX))
|
||||
+#define AIR_DEFAULT_TRIGGER_LED1 (BIT(AIR_TRIGGER_NETDEV_LINK_2500) | \
|
||||
+ BIT(AIR_TRIGGER_NETDEV_LINK_1000))
|
||||
+#define AIR_DEFAULT_TRIGGER_LED2 (BIT(AIR_TRIGGER_NETDEV_LINK_2500) | \
|
||||
+ BIT(AIR_TRIGGER_NETDEV_LINK_100))
|
||||
+
|
||||
+#define AIR_PHY_LED_DUR_UNIT 781
|
||||
+#define AIR_PHY_LED_DUR (AIR_PHY_LED_DUR_UNIT << AIR_PHY_LED_DUR_BLINK_64MS)
|
||||
+
|
||||
+struct en8811h_priv {
|
||||
+ int firmware_version;
|
||||
+ bool mcu_needs_restart;
|
||||
+ struct led led[EN8811H_LED_COUNT];
|
||||
+};
|
||||
+
|
||||
+static int air_phy_read_page(struct phy_device *phydev)
|
||||
+{
|
||||
+ return phy_read(phydev, MDIO_DEVAD_NONE, AIR_EXT_PAGE_ACCESS);
|
||||
+}
|
||||
+
|
||||
+static int air_phy_write_page(struct phy_device *phydev, int page)
|
||||
+{
|
||||
+ return phy_write(phydev, MDIO_DEVAD_NONE, AIR_EXT_PAGE_ACCESS, page);
|
||||
+}
|
||||
+
|
||||
+int air_phy_select_page(struct phy_device *phydev, int page)
|
||||
+{
|
||||
+ int ret, oldpage;
|
||||
+
|
||||
+ oldpage = air_phy_read_page(phydev);
|
||||
+ if (oldpage < 0)
|
||||
+ return oldpage;
|
||||
+
|
||||
+ if (oldpage != page) {
|
||||
+ ret = air_phy_write_page(phydev, page);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return oldpage;
|
||||
+}
|
||||
+
|
||||
+int air_phy_restore_page(struct phy_device *phydev, int oldpage, int ret)
|
||||
+{
|
||||
+ int r;
|
||||
+
|
||||
+ if (oldpage < 0)
|
||||
+ return oldpage;
|
||||
+
|
||||
+ r = air_phy_write_page(phydev, oldpage);
|
||||
+ if (ret >= 0 && r < 0)
|
||||
+ ret = r;
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int air_buckpbus_reg_write(struct phy_device *phydev,
|
||||
+ u32 pbus_address, u32 pbus_data)
|
||||
+{
|
||||
+ int ret, saved_page;
|
||||
+
|
||||
+ saved_page = air_phy_select_page(phydev, AIR_PHY_PAGE_EXTENDED_4);
|
||||
+ if (saved_page < 0)
|
||||
+ return saved_page;
|
||||
+
|
||||
+ ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_MODE,
|
||||
+ AIR_BPBUS_MODE_ADDR_FIXED);
|
||||
+ if (ret < 0)
|
||||
+ goto restore_page;
|
||||
+
|
||||
+ ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_ADDR_HIGH,
|
||||
+ air_upper_16_bits(pbus_address));
|
||||
+ if (ret < 0)
|
||||
+ goto restore_page;
|
||||
+
|
||||
+ ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_ADDR_LOW,
|
||||
+ air_lower_16_bits(pbus_address));
|
||||
+ if (ret < 0)
|
||||
+ goto restore_page;
|
||||
+
|
||||
+ ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_DATA_HIGH,
|
||||
+ air_upper_16_bits(pbus_data));
|
||||
+ if (ret < 0)
|
||||
+ goto restore_page;
|
||||
+
|
||||
+ ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_DATA_LOW,
|
||||
+ air_lower_16_bits(pbus_data));
|
||||
+ if (ret < 0)
|
||||
+ goto restore_page;
|
||||
+
|
||||
+restore_page:
|
||||
+ if (ret < 0)
|
||||
+ printf("%s 0x%08x failed: %d\n", __func__,
|
||||
+ pbus_address, ret);
|
||||
+
|
||||
+ return air_phy_restore_page(phydev, saved_page, ret);
|
||||
+}
|
||||
+
|
||||
+static int air_buckpbus_reg_read(struct phy_device *phydev,
|
||||
+ u32 pbus_address, u32 *pbus_data)
|
||||
+{
|
||||
+ int pbus_data_low, pbus_data_high;
|
||||
+ int ret = 0, saved_page;
|
||||
+
|
||||
+ saved_page = air_phy_select_page(phydev, AIR_PHY_PAGE_EXTENDED_4);
|
||||
+ if (saved_page < 0)
|
||||
+ return saved_page;
|
||||
+
|
||||
+ ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_MODE,
|
||||
+ AIR_BPBUS_MODE_ADDR_FIXED);
|
||||
+ if (ret < 0)
|
||||
+ goto restore_page;
|
||||
+
|
||||
+ ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_RD_ADDR_HIGH,
|
||||
+ air_upper_16_bits(pbus_address));
|
||||
+ if (ret < 0)
|
||||
+ goto restore_page;
|
||||
+
|
||||
+ ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_RD_ADDR_LOW,
|
||||
+ air_lower_16_bits(pbus_address));
|
||||
+ if (ret < 0)
|
||||
+ goto restore_page;
|
||||
+
|
||||
+ pbus_data_high = phy_read(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_RD_DATA_HIGH);
|
||||
+ if (pbus_data_high < 0) {
|
||||
+ ret = pbus_data_high;
|
||||
+ goto restore_page;
|
||||
+ }
|
||||
+
|
||||
+ pbus_data_low = phy_read(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_RD_DATA_LOW);
|
||||
+ if (pbus_data_low < 0) {
|
||||
+ ret = pbus_data_low;
|
||||
+ goto restore_page;
|
||||
+ }
|
||||
+
|
||||
+ *pbus_data = pbus_data_low | (pbus_data_high << 16);
|
||||
+
|
||||
+restore_page:
|
||||
+ if (ret < 0)
|
||||
+ printf("%s 0x%08x failed: %d\n", __func__,
|
||||
+ pbus_address, ret);
|
||||
+
|
||||
+ return air_phy_restore_page(phydev, saved_page, ret);
|
||||
+}
|
||||
+
|
||||
+static int air_buckpbus_reg_modify(struct phy_device *phydev,
|
||||
+ u32 pbus_address, u32 mask, u32 set)
|
||||
+{
|
||||
+ int pbus_data_low, pbus_data_high;
|
||||
+ u32 pbus_data_old, pbus_data_new;
|
||||
+ int ret = 0, saved_page;
|
||||
+
|
||||
+ saved_page = air_phy_select_page(phydev, AIR_PHY_PAGE_EXTENDED_4);
|
||||
+ if (saved_page < 0)
|
||||
+ return saved_page;
|
||||
+
|
||||
+ ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_MODE,
|
||||
+ AIR_BPBUS_MODE_ADDR_FIXED);
|
||||
+ if (ret < 0)
|
||||
+ goto restore_page;
|
||||
+
|
||||
+ ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_RD_ADDR_HIGH,
|
||||
+ air_upper_16_bits(pbus_address));
|
||||
+ if (ret < 0)
|
||||
+ goto restore_page;
|
||||
+
|
||||
+ ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_RD_ADDR_LOW,
|
||||
+ air_lower_16_bits(pbus_address));
|
||||
+ if (ret < 0)
|
||||
+ goto restore_page;
|
||||
+
|
||||
+ pbus_data_high = phy_read(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_RD_DATA_HIGH);
|
||||
+ if (pbus_data_high < 0)
|
||||
+ return pbus_data_high;
|
||||
+
|
||||
+ pbus_data_low = phy_read(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_RD_DATA_LOW);
|
||||
+ if (pbus_data_low < 0)
|
||||
+ return pbus_data_low;
|
||||
+
|
||||
+ pbus_data_old = pbus_data_low | (pbus_data_high << 16);
|
||||
+ pbus_data_new = (pbus_data_old & ~mask) | set;
|
||||
+ if (pbus_data_new == pbus_data_old)
|
||||
+ return 0;
|
||||
+
|
||||
+ ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_ADDR_HIGH,
|
||||
+ air_upper_16_bits(pbus_address));
|
||||
+ if (ret < 0)
|
||||
+ goto restore_page;
|
||||
+
|
||||
+ ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_ADDR_LOW,
|
||||
+ air_lower_16_bits(pbus_address));
|
||||
+ if (ret < 0)
|
||||
+ goto restore_page;
|
||||
+
|
||||
+ ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_DATA_HIGH,
|
||||
+ air_upper_16_bits(pbus_data_new));
|
||||
+ if (ret < 0)
|
||||
+ goto restore_page;
|
||||
+
|
||||
+ ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_DATA_LOW,
|
||||
+ air_lower_16_bits(pbus_data_new));
|
||||
+ if (ret < 0)
|
||||
+ goto restore_page;
|
||||
+
|
||||
+restore_page:
|
||||
+ if (ret < 0)
|
||||
+ printf("%s 0x%08x failed: %d\n", __func__,
|
||||
+ pbus_address, ret);
|
||||
+
|
||||
+ return air_phy_restore_page(phydev, saved_page, ret);
|
||||
+}
|
||||
+
|
||||
+static int air_write_buf(struct phy_device *phydev, unsigned long address,
|
||||
+ unsigned long array_size, const unsigned char *buffer)
|
||||
+{
|
||||
+ unsigned int offset;
|
||||
+ int ret, saved_page;
|
||||
+ u16 val;
|
||||
+
|
||||
+ saved_page = air_phy_select_page(phydev, AIR_PHY_PAGE_EXTENDED_4);
|
||||
+ if (saved_page < 0)
|
||||
+ return saved_page;
|
||||
+
|
||||
+ ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_MODE,
|
||||
+ AIR_BPBUS_MODE_ADDR_INCR);
|
||||
+ if (ret < 0)
|
||||
+ goto restore_page;
|
||||
+
|
||||
+ ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_ADDR_HIGH,
|
||||
+ air_upper_16_bits(address));
|
||||
+ if (ret < 0)
|
||||
+ goto restore_page;
|
||||
+
|
||||
+ ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_ADDR_LOW,
|
||||
+ air_lower_16_bits(address));
|
||||
+ if (ret < 0)
|
||||
+ goto restore_page;
|
||||
+
|
||||
+ for (offset = 0; offset < array_size; offset += 4) {
|
||||
+ val = get_unaligned_le16(&buffer[offset + 2]);
|
||||
+ ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_DATA_HIGH, val);
|
||||
+ if (ret < 0)
|
||||
+ goto restore_page;
|
||||
+
|
||||
+ val = get_unaligned_le16(&buffer[offset]);
|
||||
+ ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_DATA_LOW, val);
|
||||
+ if (ret < 0)
|
||||
+ goto restore_page;
|
||||
+ }
|
||||
+
|
||||
+restore_page:
|
||||
+ if (ret < 0)
|
||||
+ printf("%s 0x%08lx failed: %d\n", __func__,
|
||||
+ address, ret);
|
||||
+
|
||||
+ return air_phy_restore_page(phydev, saved_page, ret);
|
||||
+}
|
||||
+
|
||||
+static int en8811h_wait_mcu_ready(struct phy_device *phydev)
|
||||
+{
|
||||
+ int ret, reg_value;
|
||||
+
|
||||
+ /* Because of mdio-lock, may have to wait for multiple loads */
|
||||
+ ret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,
|
||||
+ EN8811H_PHY_FW_STATUS, reg_value,
|
||||
+ reg_value == EN8811H_PHY_READY,
|
||||
+ 20000, 7500000, true);
|
||||
+ if (ret) {
|
||||
+ printf("MCU not ready: 0x%x\n", reg_value);
|
||||
+ return -ENODEV;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+__weak int en8811h_read_fw(void **addr)
|
||||
+{
|
||||
+ const char *fw_dm, *fw_dsp, *fw_part;
|
||||
+ u32 ca_crc32;
|
||||
+ void *buffer;
|
||||
+ loff_t read;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (!IS_ENABLED(CONFIG_PHY_AIROHA_FW_IN_MMC))
|
||||
+ return -EOPNOTSUPP;
|
||||
+
|
||||
+ /* Allocate memory to store both DM and DSP firmware */
|
||||
+ buffer = malloc(EN8811H_MD32_DM_SIZE + EN8811H_MD32_DSP_SIZE);
|
||||
+ if (!buffer) {
|
||||
+ printf("Failed to allocate memory for firmware\n");
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ /* Get the partition name where the firmware is stored */
|
||||
+ fw_part = env_get("en8811h_fw_part");
|
||||
+ if (!fw_part) {
|
||||
+ printf("Error: env var en8811h_fw_part not set.\n");
|
||||
+ ret = -EINVAL;
|
||||
+ goto err_free;
|
||||
+ }
|
||||
+
|
||||
+ /* Get the DM firmware file path */
|
||||
+ fw_dm = env_get("en8811h_fw_dm_dir");
|
||||
+ if (!fw_dm) {
|
||||
+ printf("Error: env var en8811h_fw_dm_dir not set.\n");
|
||||
+ ret = -EINVAL;
|
||||
+ goto err_free;
|
||||
+ }
|
||||
+
|
||||
+ /* Get the DSP firmware file path */
|
||||
+ fw_dsp = env_get("en8811h_fw_dsp_dir");
|
||||
+ if (!fw_dsp) {
|
||||
+ printf("Error: env var en8811h_fw_dsp_dir not set.\n");
|
||||
+ ret = -EINVAL;
|
||||
+ goto err_free;
|
||||
+ }
|
||||
+
|
||||
+ /* Load DM firmware */
|
||||
+ ret = fs_set_blk_dev("mmc", fw_part, FS_TYPE_ANY);
|
||||
+ if (ret < 0)
|
||||
+ goto err_free;
|
||||
+
|
||||
+ /* Read DM firmware file into the start of buffer */
|
||||
+ ret = fs_read(fw_dm, (ulong)buffer, 0, EN8811H_MD32_DM_SIZE, &read);
|
||||
+ if (ret < 0) {
|
||||
+ printf("Failed to read DM firmware: %s\n", fw_dm);
|
||||
+ goto err_free;
|
||||
+ }
|
||||
+
|
||||
+ /* Calculate CRC32 of DM firmware for verification */
|
||||
+ ca_crc32 = crc32(0, (unsigned char *)buffer, EN8811H_MD32_DM_SIZE);
|
||||
+ debug("DM crc32: 0x%x\n", ca_crc32);
|
||||
+
|
||||
+ /* Load DSP firmware */
|
||||
+ ret = fs_set_blk_dev("mmc", fw_part, FS_TYPE_ANY);
|
||||
+ if (ret < 0)
|
||||
+ goto err_free;
|
||||
+
|
||||
+ /* Read DSP firmware file into buffer after DM section */
|
||||
+ ret = fs_read(fw_dsp, (ulong)buffer + EN8811H_MD32_DM_SIZE, 0,
|
||||
+ EN8811H_MD32_DSP_SIZE, &read);
|
||||
+ if (ret < 0) {
|
||||
+ printf("Failed to read DSP firmware: %s\n", fw_dsp);
|
||||
+ goto err_free;
|
||||
+ }
|
||||
+
|
||||
+ /* Calculate CRC32 of DSP firmware for verification */
|
||||
+ ca_crc32 = crc32(0, (unsigned char *)buffer + EN8811H_MD32_DM_SIZE,
|
||||
+ EN8811H_MD32_DSP_SIZE);
|
||||
+ debug("DSP crc32: 0x%x\n", ca_crc32);
|
||||
+
|
||||
+ *addr = buffer;
|
||||
+ debug("Found Airoha Firmware.\n");
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+err_free:
|
||||
+ free(buffer);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int en8811h_load_firmware(struct phy_device *phydev)
|
||||
+{
|
||||
+ struct en8811h_priv *priv = phydev->priv;
|
||||
+ void *buffer = NULL;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (!IS_ENABLED(CONFIG_PHY_AIROHA_FW_IN_MMC)) {
|
||||
+ printf("Airoha EN8811H firmware loading not implemented\n");
|
||||
+ return -EOPNOTSUPP;
|
||||
+ }
|
||||
+
|
||||
+ ret = en8811h_read_fw(&buffer);
|
||||
+ if (ret < 0)
|
||||
+ goto en8811h_load_firmware_out;
|
||||
+
|
||||
+ ret = air_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_1,
|
||||
+ EN8811H_FW_CTRL_1_START);
|
||||
+ if (ret < 0)
|
||||
+ goto en8811h_load_firmware_out;
|
||||
+
|
||||
+ ret = air_buckpbus_reg_modify(phydev, EN8811H_FW_CTRL_2,
|
||||
+ EN8811H_FW_CTRL_2_LOADING,
|
||||
+ EN8811H_FW_CTRL_2_LOADING);
|
||||
+ if (ret < 0)
|
||||
+ goto en8811h_load_firmware_out;
|
||||
+
|
||||
+ ret = air_write_buf(phydev, AIR_FW_ADDR_DM, EN8811H_MD32_DM_SIZE,
|
||||
+ (unsigned char *)buffer);
|
||||
+ if (ret < 0)
|
||||
+ goto en8811h_load_firmware_out;
|
||||
+
|
||||
+ ret = air_write_buf(phydev, AIR_FW_ADDR_DSP, EN8811H_MD32_DSP_SIZE,
|
||||
+ (unsigned char *)buffer + EN8811H_MD32_DM_SIZE);
|
||||
+ if (ret < 0)
|
||||
+ goto en8811h_load_firmware_out;
|
||||
+
|
||||
+ ret = air_buckpbus_reg_modify(phydev, EN8811H_FW_CTRL_2,
|
||||
+ EN8811H_FW_CTRL_2_LOADING, 0);
|
||||
+ if (ret < 0)
|
||||
+ goto en8811h_load_firmware_out;
|
||||
+
|
||||
+ ret = air_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_1,
|
||||
+ EN8811H_FW_CTRL_1_FINISH);
|
||||
+ if (ret < 0)
|
||||
+ goto en8811h_load_firmware_out;
|
||||
+
|
||||
+ ret = en8811h_wait_mcu_ready(phydev);
|
||||
+
|
||||
+ air_buckpbus_reg_read(phydev, EN8811H_FW_VERSION,
|
||||
+ &priv->firmware_version);
|
||||
+ printf("MD32 firmware version: %08x\n",
|
||||
+ priv->firmware_version);
|
||||
+
|
||||
+en8811h_load_firmware_out:
|
||||
+ free(buffer);
|
||||
+ if (ret < 0)
|
||||
+ printf("Firmware loading failed: %d\n", ret);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int en8811h_restart_mcu(struct phy_device *phydev)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = phy_write_mmd(phydev, 0x1e, 0x8009, 0x0);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = air_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_1,
|
||||
+ EN8811H_FW_CTRL_1_START);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ return air_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_1,
|
||||
+ EN8811H_FW_CTRL_1_FINISH);
|
||||
+}
|
||||
+
|
||||
+static int air_led_hw_control_set(struct phy_device *phydev, u8 index,
|
||||
+ unsigned long rules)
|
||||
+{
|
||||
+ struct en8811h_priv *priv = phydev->priv;
|
||||
+ u16 on = 0, blink = 0;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (index >= EN8811H_LED_COUNT)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ priv->led[index].rules = rules;
|
||||
+
|
||||
+ if (rules & BIT(AIR_TRIGGER_NETDEV_FULL_DUPLEX))
|
||||
+ on |= AIR_PHY_LED_ON_FDX;
|
||||
+
|
||||
+ if (rules & (BIT(AIR_TRIGGER_NETDEV_LINK_10) | BIT(AIR_TRIGGER_NETDEV_LINK)))
|
||||
+ on |= AIR_PHY_LED_ON_LINK10;
|
||||
+
|
||||
+ if (rules & (BIT(AIR_TRIGGER_NETDEV_LINK_100) | BIT(AIR_TRIGGER_NETDEV_LINK)))
|
||||
+ on |= AIR_PHY_LED_ON_LINK100;
|
||||
+
|
||||
+ if (rules & (BIT(AIR_TRIGGER_NETDEV_LINK_1000) | BIT(AIR_TRIGGER_NETDEV_LINK)))
|
||||
+ on |= AIR_PHY_LED_ON_LINK1000;
|
||||
+
|
||||
+ if (rules & (BIT(AIR_TRIGGER_NETDEV_LINK_2500) | BIT(AIR_TRIGGER_NETDEV_LINK)))
|
||||
+ on |= AIR_PHY_LED_ON_LINK2500;
|
||||
+
|
||||
+ if (rules & BIT(AIR_TRIGGER_NETDEV_RX)) {
|
||||
+ blink |= AIR_PHY_LED_BLINK_10RX |
|
||||
+ AIR_PHY_LED_BLINK_100RX |
|
||||
+ AIR_PHY_LED_BLINK_1000RX |
|
||||
+ AIR_PHY_LED_BLINK_2500RX;
|
||||
+ }
|
||||
+
|
||||
+ if (rules & BIT(AIR_TRIGGER_NETDEV_TX)) {
|
||||
+ blink |= AIR_PHY_LED_BLINK_10TX |
|
||||
+ AIR_PHY_LED_BLINK_100TX |
|
||||
+ AIR_PHY_LED_BLINK_1000TX |
|
||||
+ AIR_PHY_LED_BLINK_2500TX;
|
||||
+ }
|
||||
+
|
||||
+ if (blink || on) {
|
||||
+ /* switch hw-control on, so led-on and led-blink are off */
|
||||
+ clear_bit(AIR_PHY_LED_STATE_FORCE_ON,
|
||||
+ &priv->led[index].state);
|
||||
+ clear_bit(AIR_PHY_LED_STATE_FORCE_BLINK,
|
||||
+ &priv->led[index].state);
|
||||
+ } else {
|
||||
+ priv->led[index].rules = 0;
|
||||
+ }
|
||||
+
|
||||
+ ret = phy_modify_mmd(phydev, MDIO_MMD_VEND2, AIR_PHY_LED_ON(index),
|
||||
+ AIR_PHY_LED_ON_MASK, on);
|
||||
+
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ return phy_write_mmd(phydev, MDIO_MMD_VEND2, AIR_PHY_LED_BLINK(index),
|
||||
+ blink);
|
||||
+};
|
||||
+
|
||||
+static int air_led_init(struct phy_device *phydev, u8 index, u8 state, u8 pol)
|
||||
+{
|
||||
+ int val = 0;
|
||||
+ int err;
|
||||
+
|
||||
+ if (index >= EN8811H_LED_COUNT)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (state == AIR_LED_ENABLE)
|
||||
+ val |= AIR_PHY_LED_ON_ENABLE;
|
||||
+ else
|
||||
+ val &= ~AIR_PHY_LED_ON_ENABLE;
|
||||
+
|
||||
+ if (pol == AIR_ACTIVE_HIGH)
|
||||
+ val |= AIR_PHY_LED_ON_POLARITY;
|
||||
+ else
|
||||
+ val &= ~AIR_PHY_LED_ON_POLARITY;
|
||||
+
|
||||
+ err = phy_write_mmd(phydev, 0x1f, AIR_PHY_LED_ON(index), val);
|
||||
+ if (err < 0)
|
||||
+ return err;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int air_leds_init(struct phy_device *phydev, int num, u16 dur, int mode)
|
||||
+{
|
||||
+ struct en8811h_priv *priv = phydev->priv;
|
||||
+ int ret, i;
|
||||
+
|
||||
+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, AIR_PHY_LED_DUR_BLINK,
|
||||
+ dur);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, AIR_PHY_LED_DUR_ON,
|
||||
+ dur >> 1);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ switch (mode) {
|
||||
+ case AIR_LED_MODE_DISABLE:
|
||||
+ ret = phy_modify_mmd(phydev, MDIO_MMD_VEND2, AIR_PHY_LED_BCR,
|
||||
+ AIR_PHY_LED_BCR_EXT_CTRL |
|
||||
+ AIR_PHY_LED_BCR_MODE_MASK, 0);
|
||||
+ break;
|
||||
+ case AIR_LED_MODE_USER_DEFINE:
|
||||
+ ret = phy_modify_mmd(phydev, MDIO_MMD_VEND2, AIR_PHY_LED_BCR,
|
||||
+ AIR_PHY_LED_BCR_EXT_CTRL |
|
||||
+ AIR_PHY_LED_BCR_CLK_EN,
|
||||
+ AIR_PHY_LED_BCR_EXT_CTRL |
|
||||
+ AIR_PHY_LED_BCR_CLK_EN);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+ break;
|
||||
+ default:
|
||||
+ printf("LED mode %d is not supported\n", mode);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < num; ++i) {
|
||||
+ ret = air_led_init(phydev, i, AIR_LED_ENABLE, AIR_ACTIVE_HIGH);
|
||||
+ if (ret < 0) {
|
||||
+ printf("LED%d init failed: %d\n", i, ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+ air_led_hw_control_set(phydev, i, priv->led[i].rules);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int en8811h_config(struct phy_device *phydev)
|
||||
+{
|
||||
+ struct en8811h_priv *priv = phydev->priv;
|
||||
+ ofnode node = phy_get_ofnode(phydev);
|
||||
+ u32 pbus_value = 0;
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ /* If restart happened in .probe(), no need to restart now */
|
||||
+ if (priv->mcu_needs_restart) {
|
||||
+ ret = en8811h_restart_mcu(phydev);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+ } else {
|
||||
+ ret = en8811h_load_firmware(phydev);
|
||||
+ if (ret) {
|
||||
+ printf("Load firmware fail.\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+ /* Next calls to .config() mcu needs to restart */
|
||||
+ priv->mcu_needs_restart = true;
|
||||
+ }
|
||||
+
|
||||
+ ret = phy_write_mmd(phydev, 0x1e, 0x800c, 0x0);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+ ret = phy_write_mmd(phydev, 0x1e, 0x800d, 0x0);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+ ret = phy_write_mmd(phydev, 0x1e, 0x800e, 0x1101);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+ ret = phy_write_mmd(phydev, 0x1e, 0x800f, 0x0002);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* Serdes polarity */
|
||||
+ pbus_value = 0;
|
||||
+ if (ofnode_read_bool(node, "airoha,pnswap-rx"))
|
||||
+ pbus_value |= EN8811H_POLARITY_RX_REVERSE;
|
||||
+ else
|
||||
+ pbus_value &= ~EN8811H_POLARITY_RX_REVERSE;
|
||||
+ if (ofnode_read_bool(node, "airoha,pnswap-tx"))
|
||||
+ pbus_value &= ~EN8811H_POLARITY_TX_NORMAL;
|
||||
+ else
|
||||
+ pbus_value |= EN8811H_POLARITY_TX_NORMAL;
|
||||
+ ret = air_buckpbus_reg_modify(phydev, EN8811H_POLARITY,
|
||||
+ EN8811H_POLARITY_RX_REVERSE |
|
||||
+ EN8811H_POLARITY_TX_NORMAL, pbus_value);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = air_leds_init(phydev, EN8811H_LED_COUNT, AIR_PHY_LED_DUR,
|
||||
+ AIR_LED_MODE_USER_DEFINE);
|
||||
+ if (ret < 0) {
|
||||
+ printf("Failed to disable leds: %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int en8811h_parse_status(struct phy_device *phydev)
|
||||
+{
|
||||
+ int ret = 0, reg_value;
|
||||
+
|
||||
+ phydev->duplex = DUPLEX_FULL;
|
||||
+
|
||||
+ reg_value = phy_read(phydev, MDIO_DEVAD_NONE, AIR_AUX_CTRL_STATUS);
|
||||
+ if (reg_value < 0)
|
||||
+ return reg_value;
|
||||
+
|
||||
+ switch (reg_value & AIR_AUX_CTRL_STATUS_SPEED_MASK) {
|
||||
+ case AIR_AUX_CTRL_STATUS_SPEED_2500:
|
||||
+ phydev->speed = SPEED_2500;
|
||||
+ break;
|
||||
+ case AIR_AUX_CTRL_STATUS_SPEED_1000:
|
||||
+ phydev->speed = SPEED_1000;
|
||||
+ break;
|
||||
+ case AIR_AUX_CTRL_STATUS_SPEED_100:
|
||||
+ phydev->speed = SPEED_100;
|
||||
+ break;
|
||||
+ default:
|
||||
+ printf("Auto-neg error, defaulting to 100M/FD\n");
|
||||
+ phydev->speed = SPEED_100;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int en8811h_startup(struct phy_device *phydev)
|
||||
+{
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ ret = genphy_update_link(phydev);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ return en8811h_parse_status(phydev);
|
||||
+}
|
||||
+
|
||||
+static int en8811h_probe(struct phy_device *phydev)
|
||||
+{
|
||||
+ struct en8811h_priv *priv;
|
||||
+
|
||||
+ priv = malloc(sizeof(*priv));
|
||||
+ if (!priv)
|
||||
+ return -ENOMEM;
|
||||
+ memset(priv, 0, sizeof(*priv));
|
||||
+
|
||||
+ priv->led[0].rules = AIR_DEFAULT_TRIGGER_LED0;
|
||||
+ priv->led[1].rules = AIR_DEFAULT_TRIGGER_LED1;
|
||||
+ priv->led[2].rules = AIR_DEFAULT_TRIGGER_LED2;
|
||||
+
|
||||
+ /* mcu has just restarted after firmware load */
|
||||
+ priv->mcu_needs_restart = false;
|
||||
+
|
||||
+ phydev->priv = priv;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+U_BOOT_PHY_DRIVER(en8811h) = {
|
||||
+ .name = "Airoha EN8811H",
|
||||
+ .uid = EN8811H_PHY_ID,
|
||||
+ .mask = 0x0ffffff0,
|
||||
+ .config = &en8811h_config,
|
||||
+ .probe = &en8811h_probe,
|
||||
+ .startup = &en8811h_startup,
|
||||
+ .shutdown = &genphy_shutdown,
|
||||
+};
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -0,0 +1,272 @@
|
||||
From 3ba908cf4b16d729f611f64c20568baa47cf0a31 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Mattias=20Walstr=C3=B6m?= <lazzer@gmail.com>
|
||||
Date: Wed, 18 Feb 2026 17:00:42 +0100
|
||||
Subject: [PATCH 06/10] Add bpi-r3-mini device tree
|
||||
Organization: Wires
|
||||
|
||||
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
|
||||
---
|
||||
arch/arm/dts/Makefile | 1 +
|
||||
arch/arm/dts/mt7986a-bpi-r3-mini.dts | 238 +++++++++++++++++++++++++++
|
||||
2 files changed, 239 insertions(+)
|
||||
create mode 100644 arch/arm/dts/mt7986a-bpi-r3-mini.dts
|
||||
|
||||
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
|
||||
index fcad6fb2fc7..d4255f95702 100644
|
||||
--- a/arch/arm/dts/Makefile
|
||||
+++ b/arch/arm/dts/Makefile
|
||||
@@ -1125,6 +1125,7 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \
|
||||
mt7981-sd-rfb.dtb \
|
||||
mt7986a-bpi-r3-sd.dtb \
|
||||
mt7986a-bpi-r3-emmc.dtb \
|
||||
+ mt7986a-bpi-r3-mini.dtb \
|
||||
mt7986a-rfb.dtb \
|
||||
mt7986b-rfb.dtb \
|
||||
mt7986a-sd-rfb.dtb \
|
||||
diff --git a/arch/arm/dts/mt7986a-bpi-r3-mini.dts b/arch/arm/dts/mt7986a-bpi-r3-mini.dts
|
||||
new file mode 100644
|
||||
index 00000000000..469b087fb0c
|
||||
--- /dev/null
|
||||
+++ b/arch/arm/dts/mt7986a-bpi-r3-mini.dts
|
||||
@@ -0,0 +1,238 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
+
|
||||
+/dts-v1/;
|
||||
+#include "mt7986.dtsi"
|
||||
+#include <dt-bindings/gpio/gpio.h>
|
||||
+#include <dt-bindings/input/linux-event-codes.h>
|
||||
+
|
||||
+/ {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <1>;
|
||||
+ model = "Bananapi BPi-R3 Mini";
|
||||
+ compatible = "mediatek,mt7986", "mediatek,mt7986-rfb";
|
||||
+
|
||||
+ chosen {
|
||||
+ stdout-path = &uart0;
|
||||
+ tick-timer = &timer0;
|
||||
+ };
|
||||
+
|
||||
+ memory@40000000 {
|
||||
+ device_type = "memory";
|
||||
+ reg = <0x40000000 0x80000000>;
|
||||
+ };
|
||||
+
|
||||
+ gpio-keys {
|
||||
+ compatible = "gpio-keys";
|
||||
+
|
||||
+ button-reset {
|
||||
+ label = "reset";
|
||||
+ linux,code = <KEY_RESTART>;
|
||||
+ gpios = <&pio 7 GPIO_ACTIVE_LOW>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ leds {
|
||||
+ compatible = "gpio-leds";
|
||||
+
|
||||
+ status_led: led-0 {
|
||||
+ label = "green:status";
|
||||
+ gpios = <&pio 19 GPIO_ACTIVE_HIGH>;
|
||||
+ };
|
||||
+
|
||||
+ led-1 {
|
||||
+ label = "blue:wlan2g";
|
||||
+ gpios = <&pio 1 GPIO_ACTIVE_HIGH>;
|
||||
+ };
|
||||
+
|
||||
+ led-2 {
|
||||
+ label = "blue:wlan5g";
|
||||
+ gpios = <&pio 2 GPIO_ACTIVE_HIGH>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ reg_1p8v: regulator-1p8v {
|
||||
+ compatible = "regulator-fixed";
|
||||
+ regulator-name = "fixed-1.8V";
|
||||
+ regulator-min-microvolt = <1800000>;
|
||||
+ regulator-max-microvolt = <1800000>;
|
||||
+ regulator-boot-on;
|
||||
+ regulator-always-on;
|
||||
+ };
|
||||
+
|
||||
+ reg_3p3v: regulator-3p3v {
|
||||
+ compatible = "regulator-fixed";
|
||||
+ regulator-name = "fixed-3.3V";
|
||||
+ regulator-min-microvolt = <3300000>;
|
||||
+ regulator-max-microvolt = <3300000>;
|
||||
+ regulator-boot-on;
|
||||
+ regulator-always-on;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+ð {
|
||||
+ status = "okay";
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&mdio_pins>;
|
||||
+
|
||||
+ mediatek,gmac-id = <0>;
|
||||
+ phy-mode = "2500base-x";
|
||||
+ phy-handle = <&phy14>;
|
||||
+
|
||||
+ phy14: eth-phy@e {
|
||||
+ compatible = "ethernet-phy-id03a2.a411";
|
||||
+ reg = <14>;
|
||||
+
|
||||
+ airoha,pnswap-rx;
|
||||
+
|
||||
+ reset-gpios = <&pio 49 GPIO_ACTIVE_LOW>;
|
||||
+ reset-assert-us = <10000>;
|
||||
+ reset-deassert-us = <20000>;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&mmc0 {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&mmc0_pins_default>;
|
||||
+ bus-width = <8>;
|
||||
+ max-frequency = <200000000>;
|
||||
+ cap-mmc-highspeed;
|
||||
+ cap-mmc-hw-reset;
|
||||
+ vmmc-supply = <®_3p3v>;
|
||||
+ vqmmc-supply = <®_1p8v>;
|
||||
+ non-removable;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&pio {
|
||||
+ mdio_pins: mdio-pins {
|
||||
+ mux {
|
||||
+ function = "eth";
|
||||
+ groups = "mdc_mdio";
|
||||
+ };
|
||||
+
|
||||
+ conf-en8811-pwr-a {
|
||||
+ pins = "GPIO_11";
|
||||
+ drive-strength = <MTK_DRIVE_8mA>;
|
||||
+ bias-pull-down = <MTK_PUPD_SET_R1R0_11>;
|
||||
+ output-low;
|
||||
+ };
|
||||
+
|
||||
+ conf-en8811-pwr-b {
|
||||
+ pins = "GPIO_12";
|
||||
+ drive-strength = <MTK_DRIVE_8mA>;
|
||||
+ bias-pull-down = <MTK_PUPD_SET_R1R0_11>;
|
||||
+ output-low;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ mmc0_pins_default: mmc0default {
|
||||
+ mux {
|
||||
+ function = "flash";
|
||||
+ groups = "emmc_51";
|
||||
+ };
|
||||
+
|
||||
+ conf-cmd-dat {
|
||||
+ pins = "EMMC_DATA_0", "EMMC_DATA_1", "EMMC_DATA_2",
|
||||
+ "EMMC_DATA_3", "EMMC_DATA_4", "EMMC_DATA_5",
|
||||
+ "EMMC_DATA_6", "EMMC_DATA_7", "EMMC_CMD";
|
||||
+ input-enable;
|
||||
+ drive-strength = <MTK_DRIVE_4mA>;
|
||||
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
|
||||
+ };
|
||||
+
|
||||
+ conf-clk {
|
||||
+ pins = "EMMC_CK";
|
||||
+ drive-strength = <MTK_DRIVE_6mA>;
|
||||
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
|
||||
+ };
|
||||
+
|
||||
+ conf-dsl {
|
||||
+ pins = "EMMC_DSL";
|
||||
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
|
||||
+ };
|
||||
+
|
||||
+ conf-rst {
|
||||
+ pins = "EMMC_RSTB";
|
||||
+ drive-strength = <MTK_DRIVE_4mA>;
|
||||
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ spi_flash_pins: spi0-pins-func-1 {
|
||||
+ mux {
|
||||
+ function = "flash";
|
||||
+ groups = "spi0", "spi0_wp_hold";
|
||||
+ };
|
||||
+
|
||||
+ conf-pu {
|
||||
+ pins = "SPI2_CS", "SPI2_HOLD", "SPI2_WP";
|
||||
+ drive-strength = <MTK_DRIVE_8mA>;
|
||||
+ bias-pull-up = <MTK_PUPD_SET_R1R0_11>;
|
||||
+ };
|
||||
+
|
||||
+ conf-pd {
|
||||
+ pins = "SPI2_CLK", "SPI2_MOSI", "SPI2_MISO";
|
||||
+ drive-strength = <MTK_DRIVE_8mA>;
|
||||
+ bias-pull-down = <MTK_PUPD_SET_R1R0_11>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ pwm_pins: pwm0-pins-func-1 {
|
||||
+ mux {
|
||||
+ function = "pwm";
|
||||
+ groups = "pwm0";
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&pwm {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&pwm_pins>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&spi0 {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&spi_flash_pins>;
|
||||
+ status = "okay";
|
||||
+ must_tx;
|
||||
+ enhance_timing;
|
||||
+ dma_ext;
|
||||
+ ipm_design;
|
||||
+ support_quad;
|
||||
+ tick_dly = <1>;
|
||||
+ sample_sel = <0>;
|
||||
+
|
||||
+ spi_nand@0 {
|
||||
+ compatible = "spi-nand";
|
||||
+ reg = <0>;
|
||||
+ spi-max-frequency = <20000000>;
|
||||
+
|
||||
+ partitions {
|
||||
+ compatible = "fixed-partitions";
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <1>;
|
||||
+
|
||||
+ partition@0 {
|
||||
+ label = "bl2";
|
||||
+ reg = <0x0 0x200000>;
|
||||
+ };
|
||||
+
|
||||
+ partition@200000 {
|
||||
+ label = "ubi";
|
||||
+ reg = <0x200000 0x7e00000>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+};
|
||||
+
|
||||
+&uart0 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&watchdog {
|
||||
+ status = "disabled";
|
||||
+};
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -0,0 +1,559 @@
|
||||
From a1ac4c9c4e35782afcf66ab031b4d426d81120a2 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Mattias=20Walstr=C3=B6m?= <lazzer@gmail.com>
|
||||
Date: Wed, 18 Feb 2026 17:02:23 +0100
|
||||
Subject: [PATCH 07/10] bpi-r3/r4: Add probe for specific model
|
||||
Organization: Wires
|
||||
|
||||
Probe for bpi-r3 and bpi-r3-mini and select correct device tree,
|
||||
prepare for bpi-r4 (not supported yet, but soon), for bpi-r3,
|
||||
look if there are phys connected, if so it is a mini, else it is
|
||||
regular bpi-r3.
|
||||
|
||||
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
|
||||
---
|
||||
arch/arm/mach-mediatek/Kconfig | 3 +
|
||||
board/mediatek/mt7986/Kconfig | 10 ++
|
||||
board/mediatek/mt7986/Makefile | 1 +
|
||||
board/mediatek/mt7986/bpir3.c | 229 +++++++++++++++++++++++++++
|
||||
board/mediatek/mt7988/Kconfig | 9 ++
|
||||
board/mediatek/mt7988/Makefile | 1 +
|
||||
board/mediatek/mt7988/bpir4.c | 33 ++++
|
||||
configs/mt7986a_bpir3_emmc_defconfig | 2 +
|
||||
configs/mt7986a_bpir3_mini_defconfig | 66 ++++++++
|
||||
configs/mt7986a_bpir3_sd_defconfig | 2 +
|
||||
configs/mt7988a_bpir4_defconfig | 85 ++++++++++
|
||||
11 files changed, 441 insertions(+)
|
||||
create mode 100644 board/mediatek/mt7986/Kconfig
|
||||
create mode 100644 board/mediatek/mt7986/bpir3.c
|
||||
create mode 100644 board/mediatek/mt7988/Kconfig
|
||||
create mode 100644 board/mediatek/mt7988/bpir4.c
|
||||
create mode 100644 configs/mt7986a_bpir3_mini_defconfig
|
||||
create mode 100644 configs/mt7988a_bpir4_defconfig
|
||||
|
||||
diff --git a/arch/arm/mach-mediatek/Kconfig b/arch/arm/mach-mediatek/Kconfig
|
||||
index e54c456aec0..ca593cceb43 100644
|
||||
--- a/arch/arm/mach-mediatek/Kconfig
|
||||
+++ b/arch/arm/mach-mediatek/Kconfig
|
||||
@@ -165,4 +165,7 @@ config MTK_TZ_MOVABLE
|
||||
select OF_SYSTEM_SETUP
|
||||
bool
|
||||
|
||||
+source "board/mediatek/mt7986/Kconfig"
|
||||
+source "board/mediatek/mt7988/Kconfig"
|
||||
+
|
||||
endif
|
||||
diff --git a/board/mediatek/mt7986/Kconfig b/board/mediatek/mt7986/Kconfig
|
||||
new file mode 100644
|
||||
index 00000000000..cea150b52d8
|
||||
--- /dev/null
|
||||
+++ b/board/mediatek/mt7986/Kconfig
|
||||
@@ -0,0 +1,10 @@
|
||||
+if TARGET_MT7986
|
||||
+
|
||||
+config BOARD_BPI_R3
|
||||
+ bool "BananaPi BPI-R3 / BPI-R3-mini board support"
|
||||
+ select BOARD_LATE_INIT
|
||||
+ help
|
||||
+ Enable runtime variant detection for BananaPi BPI-R3 and BPI-R3-mini,
|
||||
+ selecting the correct device tree from a FIT image.
|
||||
+
|
||||
+endif
|
||||
diff --git a/board/mediatek/mt7986/Makefile b/board/mediatek/mt7986/Makefile
|
||||
index 7bb84fa2f4e..b006ee150bd 100644
|
||||
--- a/board/mediatek/mt7986/Makefile
|
||||
+++ b/board/mediatek/mt7986/Makefile
|
||||
@@ -1,3 +1,4 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
obj-y += mt7986_rfb.o
|
||||
+obj-$(CONFIG_BOARD_BPI_R3) += bpir3.o
|
||||
diff --git a/board/mediatek/mt7986/bpir3.c b/board/mediatek/mt7986/bpir3.c
|
||||
new file mode 100644
|
||||
index 00000000000..01eef55bb74
|
||||
--- /dev/null
|
||||
+++ b/board/mediatek/mt7986/bpir3.c
|
||||
@@ -0,0 +1,229 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0
|
||||
+/*
|
||||
+ * BPI-R3 / BPI-R3-mini board variant detection
|
||||
+ */
|
||||
+
|
||||
+#include <env.h>
|
||||
+#include <fdt_support.h>
|
||||
+#include <image.h>
|
||||
+#include <asm/global_data.h>
|
||||
+#include <asm/io.h>
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/string.h>
|
||||
+
|
||||
+DECLARE_GLOBAL_DATA_PTR;
|
||||
+
|
||||
+enum bpir3_variant {
|
||||
+ BPIR3,
|
||||
+ BPIR3_MINI,
|
||||
+};
|
||||
+
|
||||
+/*
|
||||
+ * Detect BPI-R3 vs BPI-R3-mini by probing for the Airoha EN8811H PHY.
|
||||
+ *
|
||||
+ * BPI-R3-mini: EN8811H is directly on the MDIO bus at addr 14.
|
||||
+ * GPIO49 (active-low) is its reset; PHYSID1 = 0x03a2.
|
||||
+ * BPI-R3: MT7531AE switch via SGMII; nothing at MDIO addr 14 → 0xffff.
|
||||
+ *
|
||||
+ * NOTE: I2C 0x50 is NOT usable — BPI-R3 SFP cage EEPROMs occupy 0x50–0x5b.
|
||||
+ */
|
||||
+
|
||||
+/*
|
||||
+ * MT7986 GPIO — gpio_base = 0x1001f000
|
||||
+ *
|
||||
+ * DIR register: base + 0x000 + (pin/32)*0x10, 1 bit/pin (1=output)
|
||||
+ * DOUT register: base + 0x100 + (pin/32)*0x10, 1 bit/pin
|
||||
+ * MODE register: base + 0x300 + (pin*4/32)*0x10, 4 bits/pin (0=GPIO, 1=eth…)
|
||||
+ */
|
||||
+#define MT7986_GPIO_BASE 0x1001f000UL
|
||||
+#define GPIO_DIR_REG(p) (MT7986_GPIO_BASE + 0x000 + ((p) / 32) * 0x10)
|
||||
+#define GPIO_DOUT_REG(p) (MT7986_GPIO_BASE + 0x100 + ((p) / 32) * 0x10)
|
||||
+#define GPIO_MODE_REG(p) (MT7986_GPIO_BASE + 0x300 + (((p) * 4) / 32) * 0x10)
|
||||
+#define GPIO_MODE_SHIFT(p) (((p) * 4) % 32)
|
||||
+
|
||||
+/* EN8811H PHY reset: GPIO49, active-low */
|
||||
+#define EN8811H_RST_GPIO 49
|
||||
+/* EN8811H power control lines: active-low enables on some BPI-R3-mini dts */
|
||||
+#define EN8811H_PWR_A_GPIO 11
|
||||
+#define EN8811H_PWR_B_GPIO 12
|
||||
+/* Alternative EN8811H power control lines used by other mini trees */
|
||||
+#define EN8811H_PWR2_A_GPIO 16
|
||||
+#define EN8811H_PWR2_B_GPIO 17
|
||||
+
|
||||
+/* MDC/MDIO pins: GPIO67 = MDC, GPIO68 = MDIO, both on function 1 ("eth") */
|
||||
+#define MDC_GPIO 67
|
||||
+#define MDIO_GPIO 68
|
||||
+
|
||||
+/*
|
||||
+ * MT7986 Frame Engine: ethernet@15100000, GMAC at +0x10000
|
||||
+ *
|
||||
+ * PPSC (+0x0000): MDC clock config — bits[29:24] = divider, bit[4] = turbo
|
||||
+ * PIAC (+0x0004): PHY indirect access — write then poll PHY_ACS_ST clear
|
||||
+ */
|
||||
+#define GMAC_BASE 0x15110000UL
|
||||
+#define GMAC_PPSC (GMAC_BASE + 0x0000)
|
||||
+#define GMAC_PIAC (GMAC_BASE + 0x0004)
|
||||
+
|
||||
+#define PPSC_MDC_CFG_MASK GENMASK(29, 24)
|
||||
+#define PPSC_MDC_CFG(d) (((d) & 0x3f) << 24)
|
||||
+#define PPSC_MDC_TURBO BIT(4)
|
||||
+/* divider = 10 → MDC ≈ 2.5 MHz from 25 MHz reference */
|
||||
+#define MDC_DIVIDER 10
|
||||
+
|
||||
+#define PIAC_ACS_ST BIT(31)
|
||||
+#define PIAC_REG_S 25
|
||||
+#define PIAC_PHY_S 20
|
||||
+#define PIAC_CMD_S 18
|
||||
+#define PIAC_ST_S 16
|
||||
+#define PIAC_DATA_MASK 0xffffU
|
||||
+#define PIAC_CMD_READ 2
|
||||
+#define PIAC_ST_C22 1
|
||||
+
|
||||
+/* EN8811H PHY ID register values */
|
||||
+#define EN8811H_PHYSID1 0x03a2
|
||||
+#define EN8811H_PHYSID2_MASK 0xfff0
|
||||
+#define EN8811H_PHYSID2 0xa410
|
||||
+#define MII_PHYSID1 0x02 /* IEEE MII register 2 */
|
||||
+#define MII_PHYSID2 0x03 /* IEEE MII register 3 */
|
||||
+
|
||||
+/* Set a GPIO pin's mode field (0 = GPIO, 1 = eth function, …) */
|
||||
+static void gpio_set_mode(unsigned int pin, unsigned int func)
|
||||
+{
|
||||
+ clrsetbits_le32(GPIO_MODE_REG(pin),
|
||||
+ 0xf << GPIO_MODE_SHIFT(pin),
|
||||
+ (func & 0xf) << GPIO_MODE_SHIFT(pin));
|
||||
+}
|
||||
+
|
||||
+/* Configure a GPIO pin as output and drive it high or low */
|
||||
+static void gpio_out(unsigned int pin, int val)
|
||||
+{
|
||||
+ setbits_le32(GPIO_DIR_REG(pin), BIT(pin % 32));
|
||||
+ if (val)
|
||||
+ setbits_le32(GPIO_DOUT_REG(pin), BIT(pin % 32));
|
||||
+ else
|
||||
+ clrbits_le32(GPIO_DOUT_REG(pin), BIT(pin % 32));
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Clause-22 MDIO read via the MT7986 GMAC PHY indirect access register.
|
||||
+ * Returns the 16-bit register value, or -1 on timeout.
|
||||
+ */
|
||||
+static int mdio_read_c22(unsigned int phy, unsigned int reg)
|
||||
+{
|
||||
+ u32 val;
|
||||
+ int i;
|
||||
+
|
||||
+ val = (PIAC_ST_C22 << PIAC_ST_S) |
|
||||
+ (PIAC_CMD_READ << PIAC_CMD_S) |
|
||||
+ (phy << PIAC_PHY_S) |
|
||||
+ (reg << PIAC_REG_S);
|
||||
+ writel(val | PIAC_ACS_ST, GMAC_PIAC);
|
||||
+
|
||||
+ for (i = 0; i < 5000; i++) {
|
||||
+ val = readl(GMAC_PIAC);
|
||||
+ if (!(val & PIAC_ACS_ST))
|
||||
+ return (int)(val & PIAC_DATA_MASK);
|
||||
+ udelay(1);
|
||||
+ }
|
||||
+
|
||||
+ return -1; /* timeout */
|
||||
+}
|
||||
+
|
||||
+static void enable_mini_power_lines(unsigned int gpio_a, unsigned int gpio_b)
|
||||
+{
|
||||
+ gpio_set_mode(gpio_a, 0); /* mode 0 = GPIO */
|
||||
+ gpio_set_mode(gpio_b, 0); /* mode 0 = GPIO */
|
||||
+ gpio_out(gpio_a, 0); /* active-low enable */
|
||||
+ gpio_out(gpio_b, 0); /* active-low enable */
|
||||
+}
|
||||
+
|
||||
+static void pulse_mini_phy_reset(void)
|
||||
+{
|
||||
+ gpio_set_mode(EN8811H_RST_GPIO, 0); /* mode 0 = GPIO */
|
||||
+ gpio_out(EN8811H_RST_GPIO, 0); /* assert reset */
|
||||
+ mdelay(10);
|
||||
+ gpio_out(EN8811H_RST_GPIO, 1); /* deassert reset */
|
||||
+ mdelay(20);
|
||||
+}
|
||||
+
|
||||
+static bool is_en8811_id(int id1, int id2)
|
||||
+{
|
||||
+ return id1 == EN8811H_PHYSID1 &&
|
||||
+ (id2 & EN8811H_PHYSID2_MASK) == EN8811H_PHYSID2;
|
||||
+}
|
||||
+
|
||||
+static int probe_en8811_addr(unsigned int phy_addr)
|
||||
+{
|
||||
+ int id1, id2;
|
||||
+
|
||||
+ id1 = mdio_read_c22(phy_addr, MII_PHYSID1);
|
||||
+ id2 = mdio_read_c22(phy_addr, MII_PHYSID2);
|
||||
+
|
||||
+ if (id1 < 0 || id2 < 0)
|
||||
+ return 0;
|
||||
+
|
||||
+ return is_en8811_id(id1, id2);
|
||||
+}
|
||||
+
|
||||
+static enum bpir3_variant detect_bpir3_variant(void)
|
||||
+{
|
||||
+ unsigned int pwr_a[] = { EN8811H_PWR_A_GPIO, EN8811H_PWR2_A_GPIO };
|
||||
+ unsigned int pwr_b[] = { EN8811H_PWR_B_GPIO, EN8811H_PWR2_B_GPIO };
|
||||
+ unsigned int i;
|
||||
+
|
||||
+ /* Switch GPIO67 (MDC) and GPIO68 (MDIO) to eth function */
|
||||
+ gpio_set_mode(MDC_GPIO, 1);
|
||||
+ gpio_set_mode(MDIO_GPIO, 1);
|
||||
+
|
||||
+ /* Configure MDC clock: enable turbo + set safe divider (~2.5 MHz) */
|
||||
+ setbits_le32(GMAC_PPSC, PPSC_MDC_TURBO);
|
||||
+ clrsetbits_le32(GMAC_PPSC, PPSC_MDC_CFG_MASK, PPSC_MDC_CFG(MDC_DIVIDER));
|
||||
+
|
||||
+ /*
|
||||
+ * Enable EN8811H power rails and probe; some mini boards use
|
||||
+ * GPIO11/12, others GPIO16/17.
|
||||
+ */
|
||||
+ for (i = 0; i < ARRAY_SIZE(pwr_a); i++) {
|
||||
+ enable_mini_power_lines(pwr_a[i], pwr_b[i]);
|
||||
+ pulse_mini_phy_reset();
|
||||
+
|
||||
+ if (probe_en8811_addr(14) || probe_en8811_addr(15)) {
|
||||
+ /* Assert reset; DM eth-phy will deassert with proper delays */
|
||||
+ gpio_out(EN8811H_RST_GPIO, 0);
|
||||
+ return BPIR3_MINI;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return BPIR3;
|
||||
+}
|
||||
+
|
||||
+int board_fit_config_name_match(const char *name)
|
||||
+{
|
||||
+ static int variant = -1;
|
||||
+
|
||||
+ if (variant < 0)
|
||||
+ variant = detect_bpir3_variant();
|
||||
+
|
||||
+ switch (variant) {
|
||||
+ case BPIR3_MINI:
|
||||
+ return strcmp(name, "mt7986a-bpi-r3-mini") ? -1 : 0;
|
||||
+ case BPIR3:
|
||||
+ default:
|
||||
+ /*
|
||||
+ * Accept both sd and emmc variants of BPI-R3;
|
||||
+ * storage type is determined by spl_boot_device(), not here.
|
||||
+ */
|
||||
+ return (strcmp(name, "mt7986a-bpi-r3-sd") == 0 ||
|
||||
+ strcmp(name, "mt7986a-bpi-r3-emmc") == 0) ? 0 : -1;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+int board_late_init(void)
|
||||
+{
|
||||
+ const char *model = fdt_getprop(gd->fdt_blob, 0, "model", NULL);
|
||||
+
|
||||
+ if (model && strstr(model, "Mini"))
|
||||
+ env_set("fdtfile", "mediatek/mt7986a-bananapi-bpi-r3-mini.dtb");
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
diff --git a/board/mediatek/mt7988/Kconfig b/board/mediatek/mt7988/Kconfig
|
||||
new file mode 100644
|
||||
index 00000000000..24c70417ec5
|
||||
--- /dev/null
|
||||
+++ b/board/mediatek/mt7988/Kconfig
|
||||
@@ -0,0 +1,9 @@
|
||||
+if TARGET_MT7988
|
||||
+
|
||||
+config BOARD_BPI_R4
|
||||
+ bool "BananaPi BPI-R4 / BPI-R4-2g5 board support"
|
||||
+ help
|
||||
+ Enable runtime variant detection for BananaPi BPI-R4 and BPI-R4-2g5,
|
||||
+ selecting the correct device tree from a FIT image.
|
||||
+
|
||||
+endif
|
||||
diff --git a/board/mediatek/mt7988/Makefile b/board/mediatek/mt7988/Makefile
|
||||
index f1249ab3715..157ee371eae 100644
|
||||
--- a/board/mediatek/mt7988/Makefile
|
||||
+++ b/board/mediatek/mt7988/Makefile
|
||||
@@ -1,3 +1,4 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
obj-y += mt7988_rfb.o
|
||||
+obj-$(CONFIG_BOARD_BPI_R4) += bpir4.o
|
||||
diff --git a/board/mediatek/mt7988/bpir4.c b/board/mediatek/mt7988/bpir4.c
|
||||
new file mode 100644
|
||||
index 00000000000..46e22d38135
|
||||
--- /dev/null
|
||||
+++ b/board/mediatek/mt7988/bpir4.c
|
||||
@@ -0,0 +1,33 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0
|
||||
+/*
|
||||
+ * BPI-R4 / BPI-R4-2g5 board variant detection
|
||||
+ */
|
||||
+
|
||||
+#include <image.h>
|
||||
+#include <linux/string.h>
|
||||
+
|
||||
+enum bpir4_variant {
|
||||
+ BPIR4,
|
||||
+ BPIR4_2G5,
|
||||
+};
|
||||
+
|
||||
+/*
|
||||
+ * Detect which BPI-R4 variant this board is.
|
||||
+ * TODO: implement real hardware detection
|
||||
+ */
|
||||
+static enum bpir4_variant detect_bpir4_variant(void)
|
||||
+{
|
||||
+ /* Stub: always report BPI-R4 */
|
||||
+ return BPIR4;
|
||||
+}
|
||||
+
|
||||
+int board_fit_config_name_match(const char *name)
|
||||
+{
|
||||
+ switch (detect_bpir4_variant()) {
|
||||
+ case BPIR4_2G5:
|
||||
+ return strcmp(name, "mt7988a-bananapi-bpi-r4-2g5") ? -1 : 0;
|
||||
+ case BPIR4:
|
||||
+ default:
|
||||
+ return strcmp(name, "mt7988a-bananapi-bpi-r4") ? -1 : 0;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/configs/mt7986a_bpir3_emmc_defconfig b/configs/mt7986a_bpir3_emmc_defconfig
|
||||
index 153c1934bd0..2f9baa723ff 100644
|
||||
--- a/configs/mt7986a_bpir3_emmc_defconfig
|
||||
+++ b/configs/mt7986a_bpir3_emmc_defconfig
|
||||
@@ -9,6 +9,8 @@ CONFIG_ENV_SIZE=0x80000
|
||||
CONFIG_ENV_OFFSET=0x300000
|
||||
CONFIG_DEFAULT_DEVICE_TREE="mt7986a-bpi-r3-emmc"
|
||||
CONFIG_TARGET_MT7986=y
|
||||
+CONFIG_BOARD_BPI_R3=y
|
||||
+CONFIG_SPL_LOAD_FIT=y
|
||||
CONFIG_SYS_LOAD_ADDR=0x46000000
|
||||
CONFIG_DEBUG_UART_BASE=0x11002000
|
||||
CONFIG_DEBUG_UART_CLOCK=40000000
|
||||
diff --git a/configs/mt7986a_bpir3_mini_defconfig b/configs/mt7986a_bpir3_mini_defconfig
|
||||
new file mode 100644
|
||||
index 00000000000..39e44555c55
|
||||
--- /dev/null
|
||||
+++ b/configs/mt7986a_bpir3_mini_defconfig
|
||||
@@ -0,0 +1,66 @@
|
||||
+CONFIG_ARM=y
|
||||
+CONFIG_SYS_HAS_NONCACHED_MEMORY=y
|
||||
+CONFIG_POSITION_INDEPENDENT=y
|
||||
+CONFIG_ARCH_MEDIATEK=y
|
||||
+CONFIG_TEXT_BASE=0x41e00000
|
||||
+CONFIG_SYS_MALLOC_F_LEN=0x4000
|
||||
+CONFIG_NR_DRAM_BANKS=1
|
||||
+CONFIG_ENV_SIZE=0x80000
|
||||
+CONFIG_ENV_OFFSET=0x300000
|
||||
+CONFIG_DEFAULT_DEVICE_TREE="mt7986a-bpi-r3-mini"
|
||||
+CONFIG_TARGET_MT7986=y
|
||||
+CONFIG_BOARD_BPI_R3=y
|
||||
+CONFIG_SPL_LOAD_FIT=y
|
||||
+CONFIG_SYS_LOAD_ADDR=0x46000000
|
||||
+CONFIG_DEBUG_UART_BASE=0x11002000
|
||||
+CONFIG_DEBUG_UART_CLOCK=40000000
|
||||
+CONFIG_DEBUG_UART=y
|
||||
+# CONFIG_EFI_LOADER is not set
|
||||
+# CONFIG_AUTOBOOT is not set
|
||||
+CONFIG_DEFAULT_FDT_FILE="mt7986a-bpi-r3-mini"
|
||||
+CONFIG_SYS_CBSIZE=512
|
||||
+CONFIG_SYS_PBSIZE=1049
|
||||
+CONFIG_LOGLEVEL=7
|
||||
+CONFIG_LOG=y
|
||||
+CONFIG_SYS_PROMPT="BPI-R3> "
|
||||
+# CONFIG_BOOTM_NETBSD is not set
|
||||
+# CONFIG_BOOTM_PLAN9 is not set
|
||||
+# CONFIG_BOOTM_RTEMS is not set
|
||||
+# CONFIG_BOOTM_VXWORKS is not set
|
||||
+# CONFIG_CMD_ELF is not set
|
||||
+# CONFIG_CMD_UNLZ4 is not set
|
||||
+# CONFIG_CMD_UNZIP is not set
|
||||
+CONFIG_CMD_GPIO=y
|
||||
+CONFIG_CMD_GPT=y
|
||||
+CONFIG_CMD_GPT_RENAME=y
|
||||
+CONFIG_CMD_LSBLK=y
|
||||
+CONFIG_CMD_MMC=y
|
||||
+CONFIG_CMD_PART=y
|
||||
+CONFIG_CMD_READ=y
|
||||
+CONFIG_CMD_PING=y
|
||||
+CONFIG_CMD_SMC=y
|
||||
+CONFIG_CMD_FAT=y
|
||||
+CONFIG_CMD_FS_GENERIC=y
|
||||
+CONFIG_PARTITION_TYPE_GUID=y
|
||||
+CONFIG_ENV_OVERWRITE=y
|
||||
+CONFIG_ENV_IS_IN_MMC=y
|
||||
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
|
||||
+CONFIG_NET_RANDOM_ETHADDR=y
|
||||
+CONFIG_REGMAP=y
|
||||
+CONFIG_SYSCON=y
|
||||
+CONFIG_CLK=y
|
||||
+CONFIG_MMC_HS200_SUPPORT=y
|
||||
+CONFIG_MMC_MTK=y
|
||||
+CONFIG_PHY_FIXED=y
|
||||
+CONFIG_MEDIATEK_ETH=y
|
||||
+CONFIG_PINCTRL=y
|
||||
+CONFIG_PINCONF=y
|
||||
+CONFIG_PINCTRL_MT7986=y
|
||||
+CONFIG_POWER_DOMAIN=y
|
||||
+CONFIG_MTK_POWER_DOMAIN=y
|
||||
+CONFIG_DM_REGULATOR=y
|
||||
+CONFIG_DM_REGULATOR_FIXED=y
|
||||
+CONFIG_DM_SERIAL=y
|
||||
+CONFIG_MTK_SERIAL=y
|
||||
+CONFIG_FAT_WRITE=y
|
||||
+CONFIG_HEXDUMP=y
|
||||
diff --git a/configs/mt7986a_bpir3_sd_defconfig b/configs/mt7986a_bpir3_sd_defconfig
|
||||
index ad9711da614..fc4d5d91fbc 100644
|
||||
--- a/configs/mt7986a_bpir3_sd_defconfig
|
||||
+++ b/configs/mt7986a_bpir3_sd_defconfig
|
||||
@@ -9,6 +9,8 @@ CONFIG_ENV_SIZE=0x80000
|
||||
CONFIG_ENV_OFFSET=0x300000
|
||||
CONFIG_DEFAULT_DEVICE_TREE="mt7986a-bpi-r3-sd"
|
||||
CONFIG_TARGET_MT7986=y
|
||||
+CONFIG_BOARD_BPI_R3=y
|
||||
+CONFIG_SPL_LOAD_FIT=y
|
||||
CONFIG_SYS_LOAD_ADDR=0x46000000
|
||||
CONFIG_DEBUG_UART_BASE=0x11002000
|
||||
CONFIG_DEBUG_UART_CLOCK=40000000
|
||||
diff --git a/configs/mt7988a_bpir4_defconfig b/configs/mt7988a_bpir4_defconfig
|
||||
new file mode 100644
|
||||
index 00000000000..e2e128ec29d
|
||||
--- /dev/null
|
||||
+++ b/configs/mt7988a_bpir4_defconfig
|
||||
@@ -0,0 +1,85 @@
|
||||
+CONFIG_ARM=y
|
||||
+CONFIG_SYS_HAS_NONCACHED_MEMORY=y
|
||||
+CONFIG_POSITION_INDEPENDENT=y
|
||||
+CONFIG_ARCH_MEDIATEK=y
|
||||
+CONFIG_TEXT_BASE=0x41e00000
|
||||
+CONFIG_SYS_MALLOC_F_LEN=0x4000
|
||||
+CONFIG_NR_DRAM_BANKS=1
|
||||
+CONFIG_DEFAULT_DEVICE_TREE="mt7988a-bananapi-bpi-r4"
|
||||
+CONFIG_TARGET_MT7988=y
|
||||
+CONFIG_BOARD_BPI_R4=y
|
||||
+CONFIG_SPL_LOAD_FIT=y
|
||||
+CONFIG_SYS_LOAD_ADDR=0x46000000
|
||||
+CONFIG_DEBUG_UART_BASE=0x11000000
|
||||
+CONFIG_DEBUG_UART_CLOCK=40000000
|
||||
+CONFIG_DEBUG_UART=y
|
||||
+# CONFIG_EFI_LOADER is not set
|
||||
+# CONFIG_AUTOBOOT is not set
|
||||
+CONFIG_DEFAULT_FDT_FILE="mt7988a-bananapi-bpi-r4"
|
||||
+CONFIG_SYS_CBSIZE=512
|
||||
+CONFIG_SYS_PBSIZE=1049
|
||||
+CONFIG_LOGLEVEL=7
|
||||
+CONFIG_LOG=y
|
||||
+CONFIG_SYS_PROMPT="BPI-R4> "
|
||||
+# CONFIG_BOOTM_NETBSD is not set
|
||||
+# CONFIG_BOOTM_PLAN9 is not set
|
||||
+# CONFIG_BOOTM_RTEMS is not set
|
||||
+# CONFIG_BOOTM_VXWORKS is not set
|
||||
+# CONFIG_CMD_ELF is not set
|
||||
+CONFIG_CMD_CLK=y
|
||||
+CONFIG_CMD_DM=y
|
||||
+CONFIG_CMD_GPIO=y
|
||||
+CONFIG_CMD_PWM=y
|
||||
+CONFIG_CMD_MMC=y
|
||||
+CONFIG_CMD_MTD=y
|
||||
+CONFIG_CMD_PING=y
|
||||
+CONFIG_CMD_SMC=y
|
||||
+CONFIG_DOS_PARTITION=y
|
||||
+CONFIG_EFI_PARTITION=y
|
||||
+CONFIG_PARTITION_TYPE_GUID=y
|
||||
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
|
||||
+CONFIG_USE_IPADDR=y
|
||||
+CONFIG_IPADDR="192.168.1.1"
|
||||
+CONFIG_USE_NETMASK=y
|
||||
+CONFIG_NETMASK="255.255.255.0"
|
||||
+CONFIG_USE_SERVERIP=y
|
||||
+CONFIG_SERVERIP="192.168.1.2"
|
||||
+CONFIG_PROT_TCP=y
|
||||
+CONFIG_NET_RANDOM_ETHADDR=y
|
||||
+CONFIG_REGMAP=y
|
||||
+CONFIG_SYSCON=y
|
||||
+CONFIG_CLK=y
|
||||
+CONFIG_MMC_HS200_SUPPORT=y
|
||||
+CONFIG_MMC_MTK=y
|
||||
+CONFIG_MTD=y
|
||||
+CONFIG_DM_MTD=y
|
||||
+CONFIG_MTD_SPI_NAND=y
|
||||
+CONFIG_DM_SPI_FLASH=y
|
||||
+CONFIG_SPI_FLASH_SFDP_SUPPORT=y
|
||||
+CONFIG_SPI_FLASH_EON=y
|
||||
+CONFIG_SPI_FLASH_GIGADEVICE=y
|
||||
+CONFIG_SPI_FLASH_ISSI=y
|
||||
+CONFIG_SPI_FLASH_MACRONIX=y
|
||||
+CONFIG_SPI_FLASH_SPANSION=y
|
||||
+CONFIG_SPI_FLASH_STMICRO=y
|
||||
+CONFIG_SPI_FLASH_WINBOND=y
|
||||
+CONFIG_SPI_FLASH_XMC=y
|
||||
+CONFIG_SPI_FLASH_XTX=y
|
||||
+CONFIG_SPI_FLASH_MTD=y
|
||||
+CONFIG_PHY_FIXED=y
|
||||
+CONFIG_MEDIATEK_ETH=y
|
||||
+CONFIG_PINCTRL=y
|
||||
+CONFIG_PINCONF=y
|
||||
+CONFIG_PINCTRL_MT7988=y
|
||||
+CONFIG_POWER_DOMAIN=y
|
||||
+CONFIG_MTK_POWER_DOMAIN=y
|
||||
+CONFIG_DM_PWM=y
|
||||
+CONFIG_PWM_MTK=y
|
||||
+CONFIG_RAM=y
|
||||
+CONFIG_DM_SERIAL=y
|
||||
+CONFIG_MTK_SERIAL=y
|
||||
+CONFIG_SPI=y
|
||||
+CONFIG_DM_SPI=y
|
||||
+CONFIG_MTK_SPIM=y
|
||||
+CONFIG_LZO=y
|
||||
+CONFIG_HEXDUMP=y
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
From e09f64e56b1f10dd4ad6f066b6c05a604daf80e5 Mon Sep 17 00:00:00 2001
|
||||
From: Joachim Wiberg <troglobit@gmail.com>
|
||||
Date: Thu, 26 Feb 2026 11:22:28 +0100
|
||||
Subject: [PATCH 08/10] arm: mediatek: fix MT7622 BROM image header type
|
||||
Organization: Wires
|
||||
|
||||
The LK image header for MT7622 was inadvertently changed to "media=nor"
|
||||
when board Kconfigs were merged into mach-mediatek/Kconfig. MT7622 uses
|
||||
the same ATF/LK-based boot flow as MT7623 and requires "lk=1" so that
|
||||
mkimage generates the correct header for the BROM to accept.
|
||||
|
||||
Reported-by: Shiji Yang <yangshiji66@outlook.com>
|
||||
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
|
||||
---
|
||||
arch/arm/mach-mediatek/Kconfig | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/arch/arm/mach-mediatek/Kconfig b/arch/arm/mach-mediatek/Kconfig
|
||||
index ca593cceb43..59d678b7a08 100644
|
||||
--- a/arch/arm/mach-mediatek/Kconfig
|
||||
+++ b/arch/arm/mach-mediatek/Kconfig
|
||||
@@ -158,7 +158,8 @@ config MTK_BROM_HEADER_INFO
|
||||
string
|
||||
default "media=nor" if TARGET_MT8518 || TARGET_MT8512 || TARGET_MT7629
|
||||
default "media=emmc" if TARGET_MT8516 || TARGET_MT8365 || TARGET_MT8183
|
||||
- default "lk=1" if TARGET_MT7623
|
||||
+ default "media=snand;nandinfo=2k+64" if TARGET_MT7981 || TARGET_MT7986 || TARGET_MT7988
|
||||
+ default "lk=1" if TARGET_MT7622 || TARGET_MT7623
|
||||
|
||||
config MTK_TZ_MOVABLE
|
||||
select ARCH_MISC_INIT
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -0,0 +1,710 @@
|
||||
From 92ed8c8fbbacab3c2e98c65008b3c314f609fd00 Mon Sep 17 00:00:00 2001
|
||||
From: Joachim Wiberg <troglobit@gmail.com>
|
||||
Date: Thu, 26 Feb 2026 11:23:28 +0100
|
||||
Subject: [PATCH 09/10] arm: mediatek: add BananaPi BPI-R64 (MT7622) defconfigs
|
||||
Organization: Wires
|
||||
|
||||
Add U-Boot support for the BananaPi BPI-R64 router board, based on the
|
||||
MediaTek MT7622 SoC (dual-core ARM Cortex-A53, 64-bit). Three defconfigs
|
||||
are provided, following the BPI-R3 pattern:
|
||||
|
||||
mt7622_bpir64_emmc_defconfig - eMMC (mmc0), env at 4 MiB
|
||||
mt7622_bpir64_sd_defconfig - SD card (mmc1), env at 4 MiB
|
||||
mt7622_bpir64_snand_defconfig - SPI NAND via SNFI, env in UBI
|
||||
|
||||
All variants include PCIe, USB3 (xHCI + T-PHY), Ethernet (MT7531 switch
|
||||
via SGMII/2500base-x), GPIO-LEDs, and push-button support.
|
||||
|
||||
The SNAND variant uses the upstream CONFIG_MTK_SNFI_SPI + MTD_SPI_NAND
|
||||
path with a spi-nand child under &snfi, adapting OpenWRT patch 403 to
|
||||
the upstream driver model (which has no separate &snand node or
|
||||
CONFIG_MTK_SPI_NAND). NAND layout: bl2 at 0x0 (512 KiB), ubi for the
|
||||
remainder of the flash.
|
||||
|
||||
Also, add hardware description missing from the original device tree:
|
||||
- ethernet0 alias for the MT7531 switch
|
||||
- gpio-keys nodes for the reset (GPIO0) and WPS (GPIO102) buttons
|
||||
- gpio-leds nodes for the green (GPIO89) and blue (GPIO85) LEDs
|
||||
- Fix cap-sd-highspeed -> cap-mmc-highspeed on mmc0 (eMMC requires
|
||||
the MMC-specific capability flag, not the SD one)
|
||||
- Reduce mmc1 (SD card) max-frequency to 25 MHz for stability
|
||||
|
||||
Sources:
|
||||
OpenWRT patches 402-404/408 for package/boot/uboot-mediatek
|
||||
https://git.infobricfleet.com/gtu/openwrt/-/tree/master/package/boot/uboot-mediatek/patches
|
||||
Frank Wunderlich's initial MT7622/BPI-R64 U-Boot port (2019)
|
||||
https://github.com/frank-w/u-boot/commit/c451ad3950e63d54b074f71e930459281dd3f594
|
||||
|
||||
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
|
||||
---
|
||||
arch/arm/dts/mt7622-bananapi-bpi-r64-nand.dts | 290 ++++++++++++++++++
|
||||
arch/arm/dts/mt7622-bananapi-bpi-r64.dts | 38 ++-
|
||||
board/mediatek/mt7622/MAINTAINERS | 5 +
|
||||
configs/mt7622_bpir64_emmc_defconfig | 82 +++++
|
||||
configs/mt7622_bpir64_sd_defconfig | 82 +++++
|
||||
configs/mt7622_bpir64_snand_defconfig | 88 ++++++
|
||||
6 files changed, 583 insertions(+), 2 deletions(-)
|
||||
create mode 100644 arch/arm/dts/mt7622-bananapi-bpi-r64-nand.dts
|
||||
create mode 100644 configs/mt7622_bpir64_emmc_defconfig
|
||||
create mode 100644 configs/mt7622_bpir64_sd_defconfig
|
||||
create mode 100644 configs/mt7622_bpir64_snand_defconfig
|
||||
|
||||
diff --git a/arch/arm/dts/mt7622-bananapi-bpi-r64-nand.dts b/arch/arm/dts/mt7622-bananapi-bpi-r64-nand.dts
|
||||
new file mode 100644
|
||||
index 00000000000..afdcb646f69
|
||||
--- /dev/null
|
||||
+++ b/arch/arm/dts/mt7622-bananapi-bpi-r64-nand.dts
|
||||
@@ -0,0 +1,290 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0
|
||||
+/*
|
||||
+ * Copyright (c) 2019 MediaTek Inc.
|
||||
+ * Author: Sam Shih <sam.shih@mediatek.com>
|
||||
+ *
|
||||
+ * BananaPi BPI-R64 - SPI NAND flash variant
|
||||
+ */
|
||||
+
|
||||
+/dts-v1/;
|
||||
+#include <dt-bindings/input/linux-event-codes.h>
|
||||
+#include "mt7622.dtsi"
|
||||
+#include "mt7622-u-boot.dtsi"
|
||||
+
|
||||
+/ {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <1>;
|
||||
+ model = "mt7622-bpi-r64";
|
||||
+ compatible = "mediatek,mt7622", "mediatek,mt7622-rfb";
|
||||
+ chosen {
|
||||
+ stdout-path = &uart0;
|
||||
+ tick-timer = &timer0;
|
||||
+ };
|
||||
+
|
||||
+ aliases {
|
||||
+ spi0 = &snfi;
|
||||
+ ethernet0 = ð
|
||||
+ };
|
||||
+
|
||||
+ memory@40000000 {
|
||||
+ device_type = "memory";
|
||||
+ reg = <0x40000000 0x40000000>;
|
||||
+ };
|
||||
+
|
||||
+ gpio-keys {
|
||||
+ compatible = "gpio-keys";
|
||||
+
|
||||
+ factory-reset {
|
||||
+ label = "factory-reset";
|
||||
+ gpios = <&gpio 0 GPIO_ACTIVE_LOW>;
|
||||
+ linux,code = <KEY_RESTART>;
|
||||
+ };
|
||||
+
|
||||
+ wps {
|
||||
+ label = "wps";
|
||||
+ gpios = <&gpio 102 GPIO_ACTIVE_LOW>;
|
||||
+ linux,code = <KEY_WPS_BUTTON>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ leds {
|
||||
+ compatible = "gpio-leds";
|
||||
+
|
||||
+ green {
|
||||
+ label = "bpi-r64:pio:green";
|
||||
+ gpios = <&gpio 89 GPIO_ACTIVE_HIGH>;
|
||||
+ default-state = "off";
|
||||
+ };
|
||||
+
|
||||
+ blue {
|
||||
+ label = "bpi-r64:pio:blue";
|
||||
+ gpios = <&gpio 85 GPIO_ACTIVE_LOW>;
|
||||
+ default-state = "off";
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ reg_1p8v: regulator-1p8v {
|
||||
+ compatible = "regulator-fixed";
|
||||
+ regulator-name = "fixed-1.8V";
|
||||
+ regulator-min-microvolt = <1800000>;
|
||||
+ regulator-max-microvolt = <1800000>;
|
||||
+ regulator-boot-on;
|
||||
+ regulator-always-on;
|
||||
+ };
|
||||
+
|
||||
+ reg_3p3v: regulator-3p3v {
|
||||
+ compatible = "regulator-fixed";
|
||||
+ regulator-name = "fixed-3.3V";
|
||||
+ regulator-min-microvolt = <3300000>;
|
||||
+ regulator-max-microvolt = <3300000>;
|
||||
+ regulator-boot-on;
|
||||
+ regulator-always-on;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&pcie {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&pcie0_pins>, <&pcie1_pins>;
|
||||
+ status = "okay";
|
||||
+
|
||||
+ pcie@0,0 {
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+
|
||||
+ pcie@1,0 {
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&pinctrl {
|
||||
+ pcie0_pins: pcie0-pins {
|
||||
+ mux {
|
||||
+ function = "pcie";
|
||||
+ groups = "pcie0_pad_perst",
|
||||
+ "pcie0_1_waken",
|
||||
+ "pcie0_1_clkreq";
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ pcie1_pins: pcie1-pins {
|
||||
+ mux {
|
||||
+ function = "pcie";
|
||||
+ groups = "pcie1_pad_perst",
|
||||
+ "pcie1_0_waken",
|
||||
+ "pcie1_0_clkreq";
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ snfi_pins: snfi-pins {
|
||||
+ mux {
|
||||
+ function = "flash";
|
||||
+ groups = "snfi";
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ uart0_pins: uart0 {
|
||||
+ mux {
|
||||
+ function = "uart";
|
||||
+ groups = "uart0_0_tx_rx" ;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ pwm_pins: pwm1 {
|
||||
+ mux {
|
||||
+ function = "pwm";
|
||||
+ groups = "pwm_ch1_0" ;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ watchdog_pins: watchdog-default {
|
||||
+ mux {
|
||||
+ function = "watchdog";
|
||||
+ groups = "watchdog";
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ mmc0_pins_default: mmc0default {
|
||||
+ mux {
|
||||
+ function = "emmc";
|
||||
+ groups = "emmc";
|
||||
+ };
|
||||
+
|
||||
+ conf-cmd-dat {
|
||||
+ pins = "NDL0", "NDL1", "NDL2",
|
||||
+ "NDL3", "NDL4", "NDL5",
|
||||
+ "NDL6", "NDL7", "NRB";
|
||||
+ input-enable;
|
||||
+ bias-pull-up;
|
||||
+ };
|
||||
+
|
||||
+ conf-clk {
|
||||
+ pins = "NCLE";
|
||||
+ bias-pull-down;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ mmc1_pins_default: mmc1default {
|
||||
+ mux {
|
||||
+ function = "sd";
|
||||
+ groups = "sd_0";
|
||||
+ };
|
||||
+
|
||||
+ conf-cmd-data {
|
||||
+ pins = "I2S2_OUT", "I2S4_IN", "I2S3_IN",
|
||||
+ "I2S2_IN","I2S4_OUT";
|
||||
+ input-enable;
|
||||
+ drive-strength = <8>;
|
||||
+ bias-pull-up;
|
||||
+ };
|
||||
+
|
||||
+ conf-clk {
|
||||
+ pins = "I2S3_OUT";
|
||||
+ drive-strength = <12>;
|
||||
+ bias-pull-down;
|
||||
+ };
|
||||
+
|
||||
+ conf-cd {
|
||||
+ pins = "TXD3";
|
||||
+ bias-pull-up;
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&snfi {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&snfi_pins>;
|
||||
+ status = "okay";
|
||||
+
|
||||
+ spi-nand@0 {
|
||||
+ compatible = "spi-nand";
|
||||
+ reg = <0>;
|
||||
+ spi-tx-bus-width = <4>;
|
||||
+ spi-rx-bus-width = <4>;
|
||||
+
|
||||
+ partitions {
|
||||
+ compatible = "fixed-partitions";
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <1>;
|
||||
+
|
||||
+ partition@0 {
|
||||
+ label = "bl2";
|
||||
+ reg = <0x0 0x80000>;
|
||||
+ };
|
||||
+
|
||||
+ partition@80000 {
|
||||
+ label = "ubi";
|
||||
+ reg = <0x80000 0x7f80000>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&uart0 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&pwm {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&pwm_pins>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&mmc0 {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&mmc0_pins_default>;
|
||||
+ status = "okay";
|
||||
+ bus-width = <8>;
|
||||
+ max-frequency = <50000000>;
|
||||
+ cap-mmc-highspeed;
|
||||
+ vmmc-supply = <®_3p3v>;
|
||||
+ vqmmc-supply = <®_3p3v>;
|
||||
+ non-removable;
|
||||
+};
|
||||
+
|
||||
+&mmc1 {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&mmc1_pins_default>;
|
||||
+ status = "okay";
|
||||
+ bus-width = <4>;
|
||||
+ max-frequency = <25000000>;
|
||||
+ cap-sd-highspeed;
|
||||
+ r_smpl = <1>;
|
||||
+ vmmc-supply = <®_3p3v>;
|
||||
+ vqmmc-supply = <®_3p3v>;
|
||||
+};
|
||||
+
|
||||
+&watchdog {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&watchdog_pins>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+ð {
|
||||
+ status = "okay";
|
||||
+ mediatek,gmac-id = <0>;
|
||||
+ phy-mode = "2500base-x";
|
||||
+ mediatek,switch = "mt7531";
|
||||
+ reset-gpios = <&gpio 54 GPIO_ACTIVE_HIGH>;
|
||||
+
|
||||
+ fixed-link {
|
||||
+ speed = <2500>;
|
||||
+ full-duplex;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&gpio {
|
||||
+ /*gpio 90 for setting mode to sata*/
|
||||
+ asm_sel {
|
||||
+ gpio-hog;
|
||||
+ gpios = <90 GPIO_ACTIVE_HIGH>;
|
||||
+ output-low;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&ssusb {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&u3phy {
|
||||
+ status = "okay";
|
||||
+};
|
||||
diff --git a/arch/arm/dts/mt7622-bananapi-bpi-r64.dts b/arch/arm/dts/mt7622-bananapi-bpi-r64.dts
|
||||
index 717baf26d3f..f25257be63d 100644
|
||||
--- a/arch/arm/dts/mt7622-bananapi-bpi-r64.dts
|
||||
+++ b/arch/arm/dts/mt7622-bananapi-bpi-r64.dts
|
||||
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
+#include <dt-bindings/input/linux-event-codes.h>
|
||||
#include "mt7622.dtsi"
|
||||
#include "mt7622-u-boot.dtsi"
|
||||
|
||||
@@ -20,6 +21,7 @@
|
||||
|
||||
aliases {
|
||||
spi0 = &snfi;
|
||||
+ ethernet0 = ð
|
||||
};
|
||||
|
||||
memory@40000000 {
|
||||
@@ -27,6 +29,38 @@
|
||||
reg = <0x40000000 0x40000000>;
|
||||
};
|
||||
|
||||
+ gpio-keys {
|
||||
+ compatible = "gpio-keys";
|
||||
+
|
||||
+ factory-reset {
|
||||
+ label = "factory-reset";
|
||||
+ gpios = <&gpio 0 GPIO_ACTIVE_LOW>;
|
||||
+ linux,code = <KEY_RESTART>;
|
||||
+ };
|
||||
+
|
||||
+ wps {
|
||||
+ label = "wps";
|
||||
+ gpios = <&gpio 102 GPIO_ACTIVE_LOW>;
|
||||
+ linux,code = <KEY_WPS_BUTTON>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ leds {
|
||||
+ compatible = "gpio-leds";
|
||||
+
|
||||
+ green {
|
||||
+ label = "bpi-r64:pio:green";
|
||||
+ gpios = <&gpio 89 GPIO_ACTIVE_HIGH>;
|
||||
+ default-state = "off";
|
||||
+ };
|
||||
+
|
||||
+ blue {
|
||||
+ label = "bpi-r64:pio:blue";
|
||||
+ gpios = <&gpio 85 GPIO_ACTIVE_LOW>;
|
||||
+ default-state = "off";
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
reg_1p8v: regulator-1p8v {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "fixed-1.8V";
|
||||
@@ -197,7 +231,7 @@
|
||||
status = "okay";
|
||||
bus-width = <8>;
|
||||
max-frequency = <50000000>;
|
||||
- cap-sd-highspeed;
|
||||
+ cap-mmc-highspeed;
|
||||
vmmc-supply = <®_3p3v>;
|
||||
vqmmc-supply = <®_3p3v>;
|
||||
non-removable;
|
||||
@@ -208,7 +242,7 @@
|
||||
pinctrl-0 = <&mmc1_pins_default>;
|
||||
status = "okay";
|
||||
bus-width = <4>;
|
||||
- max-frequency = <50000000>;
|
||||
+ max-frequency = <25000000>;
|
||||
cap-sd-highspeed;
|
||||
r_smpl = <1>;
|
||||
vmmc-supply = <®_3p3v>;
|
||||
diff --git a/board/mediatek/mt7622/MAINTAINERS b/board/mediatek/mt7622/MAINTAINERS
|
||||
index a3e0e75ca07..a7da7948a65 100644
|
||||
--- a/board/mediatek/mt7622/MAINTAINERS
|
||||
+++ b/board/mediatek/mt7622/MAINTAINERS
|
||||
@@ -4,3 +4,8 @@ S: Maintained
|
||||
F: board/mediatek/mt7622
|
||||
F: include/configs/mt7622.h
|
||||
F: configs/mt7622_rfb_defconfig
|
||||
+F: configs/mt7622_bpir64_emmc_defconfig
|
||||
+F: configs/mt7622_bpir64_sd_defconfig
|
||||
+F: configs/mt7622_bpir64_snand_defconfig
|
||||
+F: arch/arm/dts/mt7622-bananapi-bpi-r64.dts
|
||||
+F: arch/arm/dts/mt7622-bananapi-bpi-r64-nand.dts
|
||||
diff --git a/configs/mt7622_bpir64_emmc_defconfig b/configs/mt7622_bpir64_emmc_defconfig
|
||||
new file mode 100644
|
||||
index 00000000000..9af7b280c93
|
||||
--- /dev/null
|
||||
+++ b/configs/mt7622_bpir64_emmc_defconfig
|
||||
@@ -0,0 +1,82 @@
|
||||
+CONFIG_ARM=y
|
||||
+CONFIG_SYS_HAS_NONCACHED_MEMORY=y
|
||||
+CONFIG_POSITION_INDEPENDENT=y
|
||||
+CONFIG_ARCH_MEDIATEK=y
|
||||
+CONFIG_TARGET_MT7622=y
|
||||
+CONFIG_TEXT_BASE=0x41e00000
|
||||
+CONFIG_SYS_MALLOC_F_LEN=0x4000
|
||||
+CONFIG_NR_DRAM_BANKS=1
|
||||
+CONFIG_ENV_SIZE=0x80000
|
||||
+CONFIG_ENV_OFFSET=0x400000
|
||||
+CONFIG_DEFAULT_DEVICE_TREE="mt7622-bananapi-bpi-r64"
|
||||
+CONFIG_SYS_LOAD_ADDR=0x40080000
|
||||
+CONFIG_DEBUG_UART_BASE=0x11002000
|
||||
+CONFIG_DEBUG_UART_CLOCK=25000000
|
||||
+CONFIG_PCI=y
|
||||
+CONFIG_DEBUG_UART=y
|
||||
+CONFIG_FIT=y
|
||||
+# CONFIG_EFI_LOADER is not set
|
||||
+# CONFIG_AUTOBOOT is not set
|
||||
+CONFIG_DEFAULT_FDT_FILE="mt7622-bananapi-bpi-r64"
|
||||
+CONFIG_SYS_CBSIZE=512
|
||||
+CONFIG_SYS_PBSIZE=1049
|
||||
+CONFIG_LOGLEVEL=7
|
||||
+CONFIG_LOG=y
|
||||
+CONFIG_SYS_PROMPT="BPI-R64> "
|
||||
+# CONFIG_BOOTM_NETBSD is not set
|
||||
+# CONFIG_BOOTM_PLAN9 is not set
|
||||
+# CONFIG_BOOTM_RTEMS is not set
|
||||
+# CONFIG_BOOTM_VXWORKS is not set
|
||||
+# CONFIG_CMD_ELF is not set
|
||||
+# CONFIG_CMD_UNLZ4 is not set
|
||||
+# CONFIG_CMD_UNZIP is not set
|
||||
+CONFIG_CMD_GPIO=y
|
||||
+CONFIG_CMD_GPT=y
|
||||
+CONFIG_CMD_GPT_RENAME=y
|
||||
+CONFIG_CMD_LSBLK=y
|
||||
+CONFIG_CMD_MMC=y
|
||||
+CONFIG_CMD_PART=y
|
||||
+CONFIG_CMD_READ=y
|
||||
+CONFIG_CMD_PCI=y
|
||||
+CONFIG_CMD_USB=y
|
||||
+CONFIG_CMD_PING=y
|
||||
+CONFIG_CMD_SMC=y
|
||||
+CONFIG_CMD_FAT=y
|
||||
+CONFIG_CMD_FS_GENERIC=y
|
||||
+CONFIG_PARTITION_TYPE_GUID=y
|
||||
+CONFIG_ENV_OVERWRITE=y
|
||||
+CONFIG_ENV_IS_IN_MMC=y
|
||||
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
|
||||
+CONFIG_NET_RANDOM_ETHADDR=y
|
||||
+CONFIG_REGMAP=y
|
||||
+CONFIG_SYSCON=y
|
||||
+CONFIG_BUTTON=y
|
||||
+CONFIG_BUTTON_GPIO=y
|
||||
+CONFIG_CLK=y
|
||||
+CONFIG_GPIO_HOG=y
|
||||
+CONFIG_LED=y
|
||||
+CONFIG_LED_GPIO=y
|
||||
+CONFIG_SUPPORT_EMMC_BOOT=y
|
||||
+CONFIG_MMC_HS200_SUPPORT=y
|
||||
+CONFIG_MMC_MTK=y
|
||||
+CONFIG_PHY_FIXED=y
|
||||
+CONFIG_MEDIATEK_ETH=y
|
||||
+CONFIG_PCIE_MEDIATEK=y
|
||||
+CONFIG_PHY=y
|
||||
+CONFIG_PHY_MTK_TPHY=y
|
||||
+CONFIG_PINCTRL=y
|
||||
+CONFIG_PINCONF=y
|
||||
+CONFIG_PINCTRL_MT7622=y
|
||||
+CONFIG_POWER_DOMAIN=y
|
||||
+CONFIG_MTK_POWER_DOMAIN=y
|
||||
+CONFIG_DM_REGULATOR=y
|
||||
+CONFIG_DM_REGULATOR_FIXED=y
|
||||
+CONFIG_RAM=y
|
||||
+CONFIG_DM_SERIAL=y
|
||||
+CONFIG_MTK_SERIAL=y
|
||||
+CONFIG_USB=y
|
||||
+CONFIG_USB_XHCI_HCD=y
|
||||
+CONFIG_USB_XHCI_MTK=y
|
||||
+CONFIG_USB_STORAGE=y
|
||||
+CONFIG_FAT_WRITE=y
|
||||
+CONFIG_HEXDUMP=y
|
||||
diff --git a/configs/mt7622_bpir64_sd_defconfig b/configs/mt7622_bpir64_sd_defconfig
|
||||
new file mode 100644
|
||||
index 00000000000..5e9340a09a6
|
||||
--- /dev/null
|
||||
+++ b/configs/mt7622_bpir64_sd_defconfig
|
||||
@@ -0,0 +1,82 @@
|
||||
+CONFIG_ARM=y
|
||||
+CONFIG_SYS_HAS_NONCACHED_MEMORY=y
|
||||
+CONFIG_POSITION_INDEPENDENT=y
|
||||
+CONFIG_ARCH_MEDIATEK=y
|
||||
+CONFIG_TARGET_MT7622=y
|
||||
+CONFIG_TEXT_BASE=0x41e00000
|
||||
+CONFIG_SYS_MALLOC_F_LEN=0x4000
|
||||
+CONFIG_NR_DRAM_BANKS=1
|
||||
+CONFIG_ENV_SIZE=0x80000
|
||||
+CONFIG_ENV_OFFSET=0x400000
|
||||
+CONFIG_DEFAULT_DEVICE_TREE="mt7622-bananapi-bpi-r64"
|
||||
+CONFIG_SYS_LOAD_ADDR=0x40080000
|
||||
+CONFIG_DEBUG_UART_BASE=0x11002000
|
||||
+CONFIG_DEBUG_UART_CLOCK=25000000
|
||||
+CONFIG_PCI=y
|
||||
+CONFIG_DEBUG_UART=y
|
||||
+CONFIG_FIT=y
|
||||
+# CONFIG_EFI_LOADER is not set
|
||||
+# CONFIG_AUTOBOOT is not set
|
||||
+CONFIG_DEFAULT_FDT_FILE="mt7622-bananapi-bpi-r64"
|
||||
+CONFIG_SYS_CBSIZE=512
|
||||
+CONFIG_SYS_PBSIZE=1049
|
||||
+CONFIG_LOGLEVEL=7
|
||||
+CONFIG_LOG=y
|
||||
+CONFIG_SYS_PROMPT="BPI-R64> "
|
||||
+# CONFIG_BOOTM_NETBSD is not set
|
||||
+# CONFIG_BOOTM_PLAN9 is not set
|
||||
+# CONFIG_BOOTM_RTEMS is not set
|
||||
+# CONFIG_BOOTM_VXWORKS is not set
|
||||
+# CONFIG_CMD_ELF is not set
|
||||
+# CONFIG_CMD_UNLZ4 is not set
|
||||
+# CONFIG_CMD_UNZIP is not set
|
||||
+CONFIG_CMD_GPIO=y
|
||||
+CONFIG_CMD_GPT=y
|
||||
+CONFIG_CMD_GPT_RENAME=y
|
||||
+CONFIG_CMD_LSBLK=y
|
||||
+CONFIG_CMD_MMC=y
|
||||
+CONFIG_CMD_PART=y
|
||||
+CONFIG_CMD_READ=y
|
||||
+CONFIG_CMD_PCI=y
|
||||
+CONFIG_CMD_USB=y
|
||||
+CONFIG_CMD_PING=y
|
||||
+CONFIG_CMD_SMC=y
|
||||
+CONFIG_CMD_FAT=y
|
||||
+CONFIG_CMD_FS_GENERIC=y
|
||||
+CONFIG_PARTITION_TYPE_GUID=y
|
||||
+CONFIG_ENV_OVERWRITE=y
|
||||
+CONFIG_ENV_IS_IN_MMC=y
|
||||
+CONFIG_SYS_MMC_ENV_DEV=1
|
||||
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
|
||||
+CONFIG_NET_RANDOM_ETHADDR=y
|
||||
+CONFIG_REGMAP=y
|
||||
+CONFIG_SYSCON=y
|
||||
+CONFIG_BUTTON=y
|
||||
+CONFIG_BUTTON_GPIO=y
|
||||
+CONFIG_CLK=y
|
||||
+CONFIG_GPIO_HOG=y
|
||||
+CONFIG_LED=y
|
||||
+CONFIG_LED_GPIO=y
|
||||
+CONFIG_MMC_HS200_SUPPORT=y
|
||||
+CONFIG_MMC_MTK=y
|
||||
+CONFIG_PHY_FIXED=y
|
||||
+CONFIG_MEDIATEK_ETH=y
|
||||
+CONFIG_PCIE_MEDIATEK=y
|
||||
+CONFIG_PHY=y
|
||||
+CONFIG_PHY_MTK_TPHY=y
|
||||
+CONFIG_PINCTRL=y
|
||||
+CONFIG_PINCONF=y
|
||||
+CONFIG_PINCTRL_MT7622=y
|
||||
+CONFIG_POWER_DOMAIN=y
|
||||
+CONFIG_MTK_POWER_DOMAIN=y
|
||||
+CONFIG_DM_REGULATOR=y
|
||||
+CONFIG_DM_REGULATOR_FIXED=y
|
||||
+CONFIG_RAM=y
|
||||
+CONFIG_DM_SERIAL=y
|
||||
+CONFIG_MTK_SERIAL=y
|
||||
+CONFIG_USB=y
|
||||
+CONFIG_USB_XHCI_HCD=y
|
||||
+CONFIG_USB_XHCI_MTK=y
|
||||
+CONFIG_USB_STORAGE=y
|
||||
+CONFIG_FAT_WRITE=y
|
||||
+CONFIG_HEXDUMP=y
|
||||
diff --git a/configs/mt7622_bpir64_snand_defconfig b/configs/mt7622_bpir64_snand_defconfig
|
||||
new file mode 100644
|
||||
index 00000000000..9be13d26fd9
|
||||
--- /dev/null
|
||||
+++ b/configs/mt7622_bpir64_snand_defconfig
|
||||
@@ -0,0 +1,88 @@
|
||||
+CONFIG_ARM=y
|
||||
+CONFIG_SYS_HAS_NONCACHED_MEMORY=y
|
||||
+CONFIG_POSITION_INDEPENDENT=y
|
||||
+CONFIG_ARCH_MEDIATEK=y
|
||||
+CONFIG_TARGET_MT7622=y
|
||||
+CONFIG_TEXT_BASE=0x41e00000
|
||||
+CONFIG_SYS_MALLOC_F_LEN=0x4000
|
||||
+CONFIG_NR_DRAM_BANKS=1
|
||||
+CONFIG_DEFAULT_DEVICE_TREE="mt7622-bananapi-bpi-r64-nand"
|
||||
+CONFIG_SYS_LOAD_ADDR=0x40080000
|
||||
+CONFIG_DEBUG_UART_BASE=0x11002000
|
||||
+CONFIG_DEBUG_UART_CLOCK=25000000
|
||||
+CONFIG_PCI=y
|
||||
+CONFIG_DEBUG_UART=y
|
||||
+CONFIG_FIT=y
|
||||
+# CONFIG_EFI_LOADER is not set
|
||||
+# CONFIG_AUTOBOOT is not set
|
||||
+CONFIG_DEFAULT_FDT_FILE="mt7622-bananapi-bpi-r64-nand"
|
||||
+CONFIG_SYS_CBSIZE=512
|
||||
+CONFIG_SYS_PBSIZE=1049
|
||||
+CONFIG_LOGLEVEL=7
|
||||
+CONFIG_LOG=y
|
||||
+CONFIG_SYS_PROMPT="BPI-R64> "
|
||||
+# CONFIG_BOOTM_NETBSD is not set
|
||||
+# CONFIG_BOOTM_PLAN9 is not set
|
||||
+# CONFIG_BOOTM_RTEMS is not set
|
||||
+# CONFIG_BOOTM_VXWORKS is not set
|
||||
+# CONFIG_CMD_ELF is not set
|
||||
+# CONFIG_CMD_UNLZ4 is not set
|
||||
+# CONFIG_CMD_UNZIP is not set
|
||||
+CONFIG_CMD_GPIO=y
|
||||
+CONFIG_CMD_MMC=y
|
||||
+CONFIG_CMD_MTD=y
|
||||
+CONFIG_CMD_PART=y
|
||||
+CONFIG_CMD_READ=y
|
||||
+CONFIG_CMD_PCI=y
|
||||
+CONFIG_CMD_USB=y
|
||||
+CONFIG_CMD_PING=y
|
||||
+CONFIG_CMD_SMC=y
|
||||
+CONFIG_CMD_FAT=y
|
||||
+CONFIG_CMD_FS_GENERIC=y
|
||||
+CONFIG_CMD_UBI=y
|
||||
+CONFIG_PARTITION_TYPE_GUID=y
|
||||
+CONFIG_ENV_OVERWRITE=y
|
||||
+CONFIG_ENV_IS_IN_UBI=y
|
||||
+CONFIG_ENV_REDUNDANT=y
|
||||
+CONFIG_ENV_UBI_PART="ubi"
|
||||
+CONFIG_ENV_UBI_VOLUME="ubootenv"
|
||||
+CONFIG_ENV_UBI_VOLUME_REDUND="ubootenv2"
|
||||
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
|
||||
+CONFIG_NET_RANDOM_ETHADDR=y
|
||||
+CONFIG_REGMAP=y
|
||||
+CONFIG_SYSCON=y
|
||||
+CONFIG_BUTTON=y
|
||||
+CONFIG_BUTTON_GPIO=y
|
||||
+CONFIG_CLK=y
|
||||
+CONFIG_GPIO_HOG=y
|
||||
+CONFIG_LED=y
|
||||
+CONFIG_LED_GPIO=y
|
||||
+CONFIG_MMC_HS200_SUPPORT=y
|
||||
+CONFIG_MMC_MTK=y
|
||||
+CONFIG_MTD=y
|
||||
+CONFIG_DM_MTD=y
|
||||
+CONFIG_MTD_SPI_NAND=y
|
||||
+CONFIG_PHY_FIXED=y
|
||||
+CONFIG_MEDIATEK_ETH=y
|
||||
+CONFIG_PCIE_MEDIATEK=y
|
||||
+CONFIG_PHY=y
|
||||
+CONFIG_PHY_MTK_TPHY=y
|
||||
+CONFIG_PINCTRL=y
|
||||
+CONFIG_PINCONF=y
|
||||
+CONFIG_PINCTRL_MT7622=y
|
||||
+CONFIG_POWER_DOMAIN=y
|
||||
+CONFIG_MTK_POWER_DOMAIN=y
|
||||
+CONFIG_DM_REGULATOR=y
|
||||
+CONFIG_DM_REGULATOR_FIXED=y
|
||||
+CONFIG_RAM=y
|
||||
+CONFIG_DM_SERIAL=y
|
||||
+CONFIG_MTK_SERIAL=y
|
||||
+CONFIG_SPI=y
|
||||
+CONFIG_DM_SPI=y
|
||||
+CONFIG_MTK_SNFI_SPI=y
|
||||
+CONFIG_USB=y
|
||||
+CONFIG_USB_XHCI_HCD=y
|
||||
+CONFIG_USB_XHCI_MTK=y
|
||||
+CONFIG_USB_STORAGE=y
|
||||
+CONFIG_FAT_WRITE=y
|
||||
+CONFIG_HEXDUMP=y
|
||||
--
|
||||
2.43.0
|
||||
|
||||
+784
@@ -0,0 +1,784 @@
|
||||
From 8b3d206ff8c398de5290a1c4237c841389655505 Mon Sep 17 00:00:00 2001
|
||||
From: Joachim Wiberg <troglobit@gmail.com>
|
||||
Date: Sun, 15 Mar 2026 12:51:39 +0100
|
||||
Subject: [PATCH] arm: mediatek: add BananaPi BPI-R4 (MT7988A) board support
|
||||
Organization: Wires
|
||||
|
||||
Add complete U-Boot support for the BananaPi BPI-R4 router board,
|
||||
based on MediaTek MT7988A (Filogic 880, quad-core Cortex-A73).
|
||||
|
||||
Device tree (mt7988a-bananapi-bpi-r4.dts):
|
||||
- UART0 (console)
|
||||
- eMMC (8-bit, non-removable, 52 MHz, high-speed)
|
||||
- SPI NAND via SPI0
|
||||
- Gigabit/10G Ethernet via MT7988 internal switch (usxgmii)
|
||||
- PCIe x4 (pcie0-3)
|
||||
- USB 3.0 (xhci1)
|
||||
- PWM (fan control)
|
||||
- I2C0: RT5190A PMIC
|
||||
- I2C2: PCA9545 mux with PCF8563 RTC and 24C02 EEPROM on channel 0
|
||||
- gpio-keys: factory-reset / WPS button on GPIO14 (active-low);
|
||||
U-Boot uses it for factory reset detection via the 'button' command,
|
||||
Linux uses the same GPIO as KEY_WPS_BUTTON at runtime
|
||||
|
||||
SD card variant (mt7988a-bananapi-bpi-r4-sd.dts + mt7988a_bpir4_sd_defconfig):
|
||||
- MT7988A eMMC (pins 38-49) and SD card (pins 32-37) use separate
|
||||
physical pads so both are electrically independent; only one can be
|
||||
active per boot session via the single MMC controller (mmc@11230000)
|
||||
- SD variant enables cap-sd-highspeed (50 MHz) vs legacy 25 MHz;
|
||||
GPIO12 used as card-detect
|
||||
- pinctrl-mt7988.c: add 'sdcard' pin group (pins 32-37, function 5)
|
||||
to match the Linux kernel driver
|
||||
|
||||
Board support (mt7988_rfb.c, Kconfig, defconfig):
|
||||
- detect_boot_media(): reads BOOT_DEVICE register (0x1001f6f0 bits
|
||||
10-11) to set $bootmedia env var (nor/spim-nand/emmc/snand)
|
||||
- detect_ram_size(): sets $ram_gb (4 or 8) based on detected DRAM
|
||||
- board_late_init(): calls both detectors at late init
|
||||
- ft_system_setup(): patches /chosen/rootdisk phandle in kernel DT
|
||||
to point at the detected boot device node
|
||||
- BOARD_BPI_R4 now selects BOARD_LATE_INIT and OF_SYSTEM_SETUP
|
||||
|
||||
Defconfig gaps vs upstream filled in (FIT, eMMC, USB, PCIe/NVMe, I2C).
|
||||
CONFIG_CMD_BUTTON=y added to both defconfigs for factory-reset button.
|
||||
|
||||
The bpir4.c board file (from commit 57b3cd86) provides
|
||||
board_fit_config_name_match() for BPI-R4 / BPI-R4-2g5 variant
|
||||
selection via FIT image.
|
||||
|
||||
Based on Frank Wunderlich's porting work:
|
||||
https://github.com/frank-w/u-boot/tree/2026-01-bpi
|
||||
|
||||
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
|
||||
---
|
||||
arch/arm/dts/Makefile | 3 +
|
||||
arch/arm/dts/mt7988a-bananapi-bpi-r4-2g5.dts | 16 ++
|
||||
arch/arm/dts/mt7988a-bananapi-bpi-r4-sd.dts | 33 +++
|
||||
arch/arm/dts/mt7988a-bananapi-bpi-r4.dts | 227 +++++++++++++++++++
|
||||
board/mediatek/mt7988/Kconfig | 2 +
|
||||
board/mediatek/mt7988/bpir4.c | 23 +-
|
||||
board/mediatek/mt7988/mt7988_rfb.c | 96 ++++++++
|
||||
configs/mt7988a_bpir4_defconfig | 33 ++-
|
||||
configs/mt7988a_bpir4_sd_defconfig | 114 ++++++++++
|
||||
drivers/pinctrl/mediatek/pinctrl-mt7988.c | 6 +-
|
||||
10 files changed, 547 insertions(+), 6 deletions(-)
|
||||
create mode 100644 arch/arm/dts/mt7988a-bananapi-bpi-r4-2g5.dts
|
||||
create mode 100644 arch/arm/dts/mt7988a-bananapi-bpi-r4-sd.dts
|
||||
create mode 100644 arch/arm/dts/mt7988a-bananapi-bpi-r4.dts
|
||||
create mode 100644 configs/mt7988a_bpir4_sd_defconfig
|
||||
|
||||
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
|
||||
index d4255f95702..697d3383b01 100644
|
||||
--- a/arch/arm/dts/Makefile
|
||||
+++ b/arch/arm/dts/Makefile
|
||||
@@ -1134,6 +1134,9 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \
|
||||
mt7986b-emmc-rfb.dtb \
|
||||
mt7988-rfb.dtb \
|
||||
mt7988-sd-rfb.dtb \
|
||||
+ mt7988a-bananapi-bpi-r4.dtb \
|
||||
+ mt7988a-bananapi-bpi-r4-2g5.dtb \
|
||||
+ mt7988a-bananapi-bpi-r4-sd.dtb \
|
||||
mt8183-pumpkin.dtb \
|
||||
mt8512-bm1-emmc.dtb \
|
||||
mt8516-pumpkin.dtb \
|
||||
diff --git a/arch/arm/dts/mt7988a-bananapi-bpi-r4-2g5.dts b/arch/arm/dts/mt7988a-bananapi-bpi-r4-2g5.dts
|
||||
new file mode 100644
|
||||
index 00000000000..0dd82cdc9fd
|
||||
--- /dev/null
|
||||
+++ b/arch/arm/dts/mt7988a-bananapi-bpi-r4-2g5.dts
|
||||
@@ -0,0 +1,16 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0
|
||||
+/*
|
||||
+ * Copyright (c) 2024 BananaPi
|
||||
+ * Copyright (c) 2026 KernelKit
|
||||
+ *
|
||||
+ * U-Boot device tree for BananaPi BPI-R4-2g5 (MediaTek MT7988A)
|
||||
+ * Variant with internal 2.5G PHY on GMAC1 instead of SFP+/USXGMII
|
||||
+ */
|
||||
+
|
||||
+#include "mt7988a-bananapi-bpi-r4.dts"
|
||||
+
|
||||
+/ {
|
||||
+ model = "BananaPi BPI-R4-2g5";
|
||||
+ compatible = "bananapi,bpi-r4-2g5", "bananapi,bpi-r4",
|
||||
+ "mediatek,mt7988a", "mediatek,mt7988";
|
||||
+};
|
||||
diff --git a/arch/arm/dts/mt7988a-bananapi-bpi-r4-sd.dts b/arch/arm/dts/mt7988a-bananapi-bpi-r4-sd.dts
|
||||
new file mode 100644
|
||||
index 00000000000..4fb411bad4d
|
||||
--- /dev/null
|
||||
+++ b/arch/arm/dts/mt7988a-bananapi-bpi-r4-sd.dts
|
||||
@@ -0,0 +1,33 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0
|
||||
+/*
|
||||
+ * SD card boot variant of the BananaPi BPI-R4 U-Boot device tree.
|
||||
+ * eMMC and SD use separate physical pins on MT7988, so both are
|
||||
+ * accessible simultaneously — boot from SD, flash eMMC.
|
||||
+ */
|
||||
+
|
||||
+/dts-v1/;
|
||||
+#include "mt7988a-bananapi-bpi-r4.dts"
|
||||
+
|
||||
+/* Override mmc0 for SD card: swap pinctrl, enable high-speed, add CD */
|
||||
+&mmc0 {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&mmc0_pins_sdcard>;
|
||||
+ bus-width = <4>;
|
||||
+ max-frequency = <52000000>;
|
||||
+ cap-sd-highspeed;
|
||||
+ cd-gpios = <&pio 12 GPIO_ACTIVE_LOW>;
|
||||
+ vmmc-supply = <®_3p3v>;
|
||||
+ vqmmc-supply = <®_3p3v>;
|
||||
+ /delete-property/ cap-mmc-highspeed;
|
||||
+ /delete-property/ cap-mmc-hw-reset;
|
||||
+ /delete-property/ non-removable;
|
||||
+};
|
||||
+
|
||||
+&pio {
|
||||
+ mmc0_pins_sdcard: mmc0-sdcard-pins {
|
||||
+ mux {
|
||||
+ function = "flash";
|
||||
+ groups = "sdcard";
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
diff --git a/arch/arm/dts/mt7988a-bananapi-bpi-r4.dts b/arch/arm/dts/mt7988a-bananapi-bpi-r4.dts
|
||||
new file mode 100644
|
||||
index 00000000000..d959d778716
|
||||
--- /dev/null
|
||||
+++ b/arch/arm/dts/mt7988a-bananapi-bpi-r4.dts
|
||||
@@ -0,0 +1,227 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0
|
||||
+/*
|
||||
+ * Copyright (c) 2024 BananaPi
|
||||
+ * Copyright (c) 2026 KernelKit
|
||||
+ *
|
||||
+ * U-Boot device tree for BananaPi BPI-R4 (MediaTek MT7988A)
|
||||
+ * Based on Frank Wunderlich's work: https://github.com/frank-w/u-boot
|
||||
+ */
|
||||
+
|
||||
+/dts-v1/;
|
||||
+#include "mt7988.dtsi"
|
||||
+#include <dt-bindings/gpio/gpio.h>
|
||||
+#include <dt-bindings/input/linux-event-codes.h>
|
||||
+
|
||||
+/ {
|
||||
+ model = "BananaPi BPI-R4";
|
||||
+ compatible = "bananapi,bpi-r4", "mediatek,mt7988a", "mediatek,mt7988";
|
||||
+
|
||||
+ chosen {
|
||||
+ stdout-path = &uart0;
|
||||
+ };
|
||||
+
|
||||
+ memory@40000000 {
|
||||
+ device_type = "memory";
|
||||
+ reg = <0 0x40000000 1 0x00000000>; /* 4 GiB */
|
||||
+ };
|
||||
+
|
||||
+ gpio-keys {
|
||||
+ compatible = "gpio-keys";
|
||||
+
|
||||
+ factory-reset {
|
||||
+ label = "factory-reset";
|
||||
+ gpios = <&pio 14 GPIO_ACTIVE_LOW>;
|
||||
+ linux,code = <KEY_RESTART>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ reg_1p8v: regulator-1p8v {
|
||||
+ compatible = "regulator-fixed";
|
||||
+ regulator-name = "fixed-1.8V";
|
||||
+ regulator-min-microvolt = <1800000>;
|
||||
+ regulator-max-microvolt = <1800000>;
|
||||
+ regulator-boot-on;
|
||||
+ regulator-always-on;
|
||||
+ };
|
||||
+
|
||||
+ reg_3p3v: regulator-3p3v {
|
||||
+ compatible = "regulator-fixed";
|
||||
+ regulator-name = "fixed-3.3V";
|
||||
+ regulator-min-microvolt = <3300000>;
|
||||
+ regulator-max-microvolt = <3300000>;
|
||||
+ regulator-boot-on;
|
||||
+ regulator-always-on;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&uart0 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+/* RT5190A PMIC */
|
||||
+&i2c0 {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&i2c0_pins>;
|
||||
+ status = "okay";
|
||||
+
|
||||
+ rt5190a: pmic@64 {
|
||||
+ compatible = "richtek,rt5190a";
|
||||
+ reg = <0x64>;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+/* I2C mux: PCA9545 at 0x70, with RTC and board EEPROM on channel 0 */
|
||||
+&i2c2 {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&i2c2_1_pins>;
|
||||
+ status = "okay";
|
||||
+
|
||||
+ i2c_mux: i2c-mux@70 {
|
||||
+ compatible = "nxp,pca9545";
|
||||
+ reg = <0x70>;
|
||||
+ reset-gpios = <&pio 5 GPIO_ACTIVE_LOW>;
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ i2c_ch0: i2c@0 {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ reg = <0>;
|
||||
+
|
||||
+ rtc@51 {
|
||||
+ compatible = "nxp,pcf8563";
|
||||
+ reg = <0x51>;
|
||||
+ };
|
||||
+
|
||||
+ eeprom@57 {
|
||||
+ compatible = "atmel,24c02";
|
||||
+ reg = <0x57>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+ð0 {
|
||||
+ status = "okay";
|
||||
+ phy-mode = "usxgmii";
|
||||
+ mediatek,switch = "mt7988";
|
||||
+
|
||||
+ fixed-link {
|
||||
+ speed = <10000>;
|
||||
+ full-duplex;
|
||||
+ pause;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&pcie0 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&pcie1 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&pcie2 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&pcie3 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&pio {
|
||||
+ i2c0_pins: i2c0-g0-pins {
|
||||
+ mux {
|
||||
+ function = "i2c";
|
||||
+ groups = "i2c0_1";
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ i2c2_1_pins: i2c2-g1-pins {
|
||||
+ mux {
|
||||
+ function = "i2c";
|
||||
+ groups = "i2c2_1";
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ mmc0_pins_emmc: mmc0-emmc-pins {
|
||||
+ mux {
|
||||
+ function = "flash";
|
||||
+ groups = "emmc_51";
|
||||
+ };
|
||||
+
|
||||
+ conf-cmd-dat {
|
||||
+ pins = "EMMC_DATA_0", "EMMC_DATA_1", "EMMC_DATA_2",
|
||||
+ "EMMC_DATA_3", "EMMC_DATA_4", "EMMC_DATA_5",
|
||||
+ "EMMC_DATA_6", "EMMC_DATA_7", "EMMC_CMD";
|
||||
+ input-enable;
|
||||
+ drive-strength = <MTK_DRIVE_4mA>;
|
||||
+ mediatek,pull-up-adv = <1>;
|
||||
+ };
|
||||
+
|
||||
+ conf-clk {
|
||||
+ pins = "EMMC_CK";
|
||||
+ drive-strength = <MTK_DRIVE_6mA>;
|
||||
+ mediatek,pull-down-adv = <2>;
|
||||
+ };
|
||||
+
|
||||
+ conf-dsl {
|
||||
+ pins = "EMMC_DSL";
|
||||
+ mediatek,pull-down-adv = <2>;
|
||||
+ };
|
||||
+
|
||||
+ conf-rst {
|
||||
+ pins = "EMMC_RSTB";
|
||||
+ drive-strength = <MTK_DRIVE_4mA>;
|
||||
+ mediatek,pull-up-adv = <1>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ spi0_flash_pins: spi0-flash-pins {
|
||||
+ mux {
|
||||
+ function = "spi";
|
||||
+ groups = "spi0", "spi0_wp_hold";
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&pwm {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+/* SPI NAND */
|
||||
+&spi0 {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&spi0_flash_pins>;
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ status = "okay";
|
||||
+ enhance_timing;
|
||||
+ dma_ext;
|
||||
+ ipm_design;
|
||||
+ support_quad;
|
||||
+ tick_dly = <2>;
|
||||
+ sample_sel = <0>;
|
||||
+
|
||||
+ spi_nand: flash@0 {
|
||||
+ compatible = "spi-nand";
|
||||
+ reg = <0>;
|
||||
+ spi-max-frequency = <52000000>;
|
||||
+ spi-tx-bus-width = <4>;
|
||||
+ spi-rx-bus-width = <4>;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+/* eMMC */
|
||||
+&mmc0 {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&mmc0_pins_emmc>;
|
||||
+ max-frequency = <52000000>;
|
||||
+ bus-width = <8>;
|
||||
+ cap-mmc-highspeed;
|
||||
+ cap-mmc-hw-reset;
|
||||
+ vmmc-supply = <®_3p3v>;
|
||||
+ vqmmc-supply = <®_1p8v>;
|
||||
+ non-removable;
|
||||
+ status = "okay";
|
||||
+};
|
||||
diff --git a/board/mediatek/mt7988/Kconfig b/board/mediatek/mt7988/Kconfig
|
||||
index 24c70417ec5..9bcad9ecefd 100644
|
||||
--- a/board/mediatek/mt7988/Kconfig
|
||||
+++ b/board/mediatek/mt7988/Kconfig
|
||||
@@ -2,6 +2,8 @@ if TARGET_MT7988
|
||||
|
||||
config BOARD_BPI_R4
|
||||
bool "BananaPi BPI-R4 / BPI-R4-2g5 board support"
|
||||
+ select BOARD_LATE_INIT
|
||||
+ select OF_SYSTEM_SETUP
|
||||
help
|
||||
Enable runtime variant detection for BananaPi BPI-R4 and BPI-R4-2g5,
|
||||
selecting the correct device tree from a FIT image.
|
||||
diff --git a/board/mediatek/mt7988/bpir4.c b/board/mediatek/mt7988/bpir4.c
|
||||
index 46e22d38135..cfc05c607fc 100644
|
||||
--- a/board/mediatek/mt7988/bpir4.c
|
||||
+++ b/board/mediatek/mt7988/bpir4.c
|
||||
@@ -13,21 +13,36 @@ enum bpir4_variant {
|
||||
|
||||
/*
|
||||
* Detect which BPI-R4 variant this board is.
|
||||
- * TODO: implement real hardware detection
|
||||
+ *
|
||||
+ * Unlike BPI-R3 vs R3-Mini, the R4-2g5 uses the MT7988A's internal 2.5G
|
||||
+ * PHY (always present in SoC silicon at MDIO addr 15) rather than an
|
||||
+ * external EN8811H, so MDIO probing cannot distinguish the variants.
|
||||
+ *
|
||||
+ * TODO: read variant ID from the 24C02 EEPROM on I2C2/PCA9545 ch0 (addr
|
||||
+ * 0x57) once BananaPi's board-ID byte offset/format is known.
|
||||
*/
|
||||
static enum bpir4_variant detect_bpir4_variant(void)
|
||||
{
|
||||
- /* Stub: always report BPI-R4 */
|
||||
+ /* Stub: always report standard BPI-R4 */
|
||||
return BPIR4;
|
||||
}
|
||||
|
||||
int board_fit_config_name_match(const char *name)
|
||||
{
|
||||
- switch (detect_bpir4_variant()) {
|
||||
+ static int variant = -1;
|
||||
+
|
||||
+ if (variant < 0)
|
||||
+ variant = detect_bpir4_variant();
|
||||
+
|
||||
+ switch (variant) {
|
||||
case BPIR4_2G5:
|
||||
return strcmp(name, "mt7988a-bananapi-bpi-r4-2g5") ? -1 : 0;
|
||||
case BPIR4:
|
||||
default:
|
||||
- return strcmp(name, "mt7988a-bananapi-bpi-r4") ? -1 : 0;
|
||||
+ if (!strcmp(name, "mt7988a-bananapi-bpi-r4") ||
|
||||
+ !strcmp(name, "mt7988a-bananapi-bpi-r4-sd"))
|
||||
+ return 0;
|
||||
+ return -1;
|
||||
}
|
||||
}
|
||||
+
|
||||
diff --git a/board/mediatek/mt7988/mt7988_rfb.c b/board/mediatek/mt7988/mt7988_rfb.c
|
||||
index 0ca87a88aed..ed184574b50 100644
|
||||
--- a/board/mediatek/mt7988/mt7988_rfb.c
|
||||
+++ b/board/mediatek/mt7988/mt7988_rfb.c
|
||||
@@ -4,3 +4,99 @@
|
||||
* Author: Sam Shih <sam.shih@mediatek.com>
|
||||
*/
|
||||
|
||||
+#include <env.h>
|
||||
+#include <asm/io.h>
|
||||
+#include <linux/libfdt.h>
|
||||
+#include <linux/string.h>
|
||||
+#include <fdt_support.h>
|
||||
+#include <asm/global_data.h>
|
||||
+
|
||||
+#define MT7988_BOOT_NOR 0
|
||||
+#define MT7988_BOOT_SPIM_NAND 1
|
||||
+#define MT7988_BOOT_EMMC 2
|
||||
+#define MT7988_BOOT_SNFI_NAND 3
|
||||
+
|
||||
+DECLARE_GLOBAL_DATA_PTR;
|
||||
+
|
||||
+int board_init(void)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void detect_boot_media(void)
|
||||
+{
|
||||
+ const char *media;
|
||||
+
|
||||
+ switch ((readl(0x1001f6f0) & 0xc00) >> 10) {
|
||||
+ case MT7988_BOOT_NOR:
|
||||
+ media = "nor";
|
||||
+ break;
|
||||
+ case MT7988_BOOT_SPIM_NAND:
|
||||
+ media = "spim-nand";
|
||||
+ break;
|
||||
+ case MT7988_BOOT_EMMC:
|
||||
+ media = "emmc";
|
||||
+ break;
|
||||
+ case MT7988_BOOT_SNFI_NAND:
|
||||
+ media = "snand";
|
||||
+ break;
|
||||
+ default:
|
||||
+ media = "unknown";
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ env_set("bootmedia", media);
|
||||
+}
|
||||
+
|
||||
+static void detect_ram_size(void)
|
||||
+{
|
||||
+ env_set("ram_gb", gd->ram_size > (6ULL << 30) ? "8" : "4");
|
||||
+}
|
||||
+
|
||||
+int board_late_init(void)
|
||||
+{
|
||||
+ const char *model;
|
||||
+
|
||||
+ detect_boot_media();
|
||||
+ detect_ram_size();
|
||||
+
|
||||
+ model = fdt_getprop(gd->fdt_blob, 0, "model", NULL);
|
||||
+ if (model && strstr(model, "2g5"))
|
||||
+ env_set("fdtfile", "mediatek/mt7988a-bananapi-bpi-r4-2g5.dtb");
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int ft_system_setup(void *blob, struct bd_info *bd)
|
||||
+{
|
||||
+ const u32 *media_handle_p;
|
||||
+ int chosen, len, ret;
|
||||
+ char media[32];
|
||||
+ const char *bootdev;
|
||||
+ u32 media_handle;
|
||||
+
|
||||
+ if (!env_get("bootmedia"))
|
||||
+ detect_boot_media();
|
||||
+
|
||||
+ bootdev = env_get("bootmedia");
|
||||
+ snprintf(media, sizeof(media), "rootdisk-%s", bootdev);
|
||||
+
|
||||
+ chosen = fdt_path_offset(blob, "/chosen");
|
||||
+ if (chosen <= 0)
|
||||
+ return 0;
|
||||
+
|
||||
+ media_handle_p = fdt_getprop(blob, chosen, media, &len);
|
||||
+ if (!media_handle_p || len != 4)
|
||||
+ return 0;
|
||||
+
|
||||
+ media_handle = *media_handle_p;
|
||||
+ ret = fdt_setprop(blob, chosen, "rootdisk", &media_handle, sizeof(media_handle));
|
||||
+ if (ret) {
|
||||
+ printf("cannot set media phandle %s as rootdisk in /chosen\n", media);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ printf("set /chosen/rootdisk to boot media: %s (phandle 0x%08x)\n",
|
||||
+ media, fdt32_to_cpu(media_handle));
|
||||
+ return 0;
|
||||
+}
|
||||
diff --git a/configs/mt7988a_bpir4_defconfig b/configs/mt7988a_bpir4_defconfig
|
||||
index e2e128ec29d..9d4a2f6e75e 100644
|
||||
--- a/configs/mt7988a_bpir4_defconfig
|
||||
+++ b/configs/mt7988a_bpir4_defconfig
|
||||
@@ -9,6 +9,7 @@ CONFIG_DEFAULT_DEVICE_TREE="mt7988a-bananapi-bpi-r4"
|
||||
CONFIG_TARGET_MT7988=y
|
||||
CONFIG_BOARD_BPI_R4=y
|
||||
CONFIG_SPL_LOAD_FIT=y
|
||||
+CONFIG_FIT=y
|
||||
CONFIG_SYS_LOAD_ADDR=0x46000000
|
||||
CONFIG_DEBUG_UART_BASE=0x11000000
|
||||
CONFIG_DEBUG_UART_CLOCK=40000000
|
||||
@@ -16,6 +17,8 @@ CONFIG_DEBUG_UART=y
|
||||
# CONFIG_EFI_LOADER is not set
|
||||
# CONFIG_AUTOBOOT is not set
|
||||
CONFIG_DEFAULT_FDT_FILE="mt7988a-bananapi-bpi-r4"
|
||||
+CONFIG_MULTI_DTB_FIT=y
|
||||
+CONFIG_OF_LIST="mt7988a-bananapi-bpi-r4 mt7988a-bananapi-bpi-r4-2g5"
|
||||
CONFIG_SYS_CBSIZE=512
|
||||
CONFIG_SYS_PBSIZE=1049
|
||||
CONFIG_LOGLEVEL=7
|
||||
@@ -26,14 +29,19 @@ CONFIG_SYS_PROMPT="BPI-R4> "
|
||||
# CONFIG_BOOTM_RTEMS is not set
|
||||
# CONFIG_BOOTM_VXWORKS is not set
|
||||
# CONFIG_CMD_ELF is not set
|
||||
+CONFIG_CMD_BUTTON=y
|
||||
CONFIG_CMD_CLK=y
|
||||
CONFIG_CMD_DM=y
|
||||
CONFIG_CMD_GPIO=y
|
||||
-CONFIG_CMD_PWM=y
|
||||
+CONFIG_CMD_I2C=y
|
||||
CONFIG_CMD_MMC=y
|
||||
CONFIG_CMD_MTD=y
|
||||
+CONFIG_CMD_MDIO=y
|
||||
+CONFIG_CMD_PCI=y
|
||||
CONFIG_CMD_PING=y
|
||||
+CONFIG_CMD_PWM=y
|
||||
CONFIG_CMD_SMC=y
|
||||
+CONFIG_CMD_USB=y
|
||||
CONFIG_DOS_PARTITION=y
|
||||
CONFIG_EFI_PARTITION=y
|
||||
CONFIG_PARTITION_TYPE_GUID=y
|
||||
@@ -49,8 +57,15 @@ CONFIG_NET_RANDOM_ETHADDR=y
|
||||
CONFIG_REGMAP=y
|
||||
CONFIG_SYSCON=y
|
||||
CONFIG_CLK=y
|
||||
+CONFIG_I2C=y
|
||||
+CONFIG_DM_I2C=y
|
||||
+CONFIG_SYS_I2C_MTK=y
|
||||
+CONFIG_I2C_MUX=y
|
||||
+CONFIG_I2C_MUX_PCA954x=y
|
||||
CONFIG_MMC_HS200_SUPPORT=y
|
||||
+CONFIG_MMC_WRITE=y
|
||||
CONFIG_MMC_MTK=y
|
||||
+CONFIG_SUPPORT_EMMC_BOOT=y
|
||||
CONFIG_MTD=y
|
||||
CONFIG_DM_MTD=y
|
||||
CONFIG_MTD_SPI_NAND=y
|
||||
@@ -67,7 +82,14 @@ CONFIG_SPI_FLASH_XMC=y
|
||||
CONFIG_SPI_FLASH_XTX=y
|
||||
CONFIG_SPI_FLASH_MTD=y
|
||||
CONFIG_PHY_FIXED=y
|
||||
+CONFIG_DM_MDIO=y
|
||||
+CONFIG_DM_ETH_PHY=y
|
||||
+CONFIG_PHY_ETHERNET_ID=y
|
||||
CONFIG_MEDIATEK_ETH=y
|
||||
+CONFIG_PCI=y
|
||||
+CONFIG_PCIE_MEDIATEK_GEN3=y
|
||||
+CONFIG_NVME_PCI=y
|
||||
+CONFIG_NVME=y
|
||||
CONFIG_PINCTRL=y
|
||||
CONFIG_PINCONF=y
|
||||
CONFIG_PINCTRL_MT7988=y
|
||||
@@ -78,8 +100,17 @@ CONFIG_PWM_MTK=y
|
||||
CONFIG_RAM=y
|
||||
CONFIG_DM_SERIAL=y
|
||||
CONFIG_MTK_SERIAL=y
|
||||
+CONFIG_PHY=y
|
||||
+CONFIG_PHY_MTK_TPHY=y
|
||||
+CONFIG_USB=y
|
||||
+CONFIG_USB_XHCI_HCD=y
|
||||
+CONFIG_USB_XHCI_MTK=y
|
||||
+CONFIG_USB_STORAGE=y
|
||||
CONFIG_SPI=y
|
||||
CONFIG_DM_SPI=y
|
||||
CONFIG_MTK_SPIM=y
|
||||
+CONFIG_OF_LIBFDT_OVERLAY=y
|
||||
+CONFIG_OF_SYSTEM_SETUP=y
|
||||
+CONFIG_BOARD_LATE_INIT=y
|
||||
CONFIG_LZO=y
|
||||
CONFIG_HEXDUMP=y
|
||||
diff --git a/configs/mt7988a_bpir4_sd_defconfig b/configs/mt7988a_bpir4_sd_defconfig
|
||||
new file mode 100644
|
||||
index 00000000000..7e78dc17e54
|
||||
--- /dev/null
|
||||
+++ b/configs/mt7988a_bpir4_sd_defconfig
|
||||
@@ -0,0 +1,114 @@
|
||||
+CONFIG_ARM=y
|
||||
+CONFIG_SYS_HAS_NONCACHED_MEMORY=y
|
||||
+CONFIG_POSITION_INDEPENDENT=y
|
||||
+CONFIG_ARCH_MEDIATEK=y
|
||||
+CONFIG_TEXT_BASE=0x41e00000
|
||||
+CONFIG_SYS_MALLOC_F_LEN=0x4000
|
||||
+CONFIG_NR_DRAM_BANKS=1
|
||||
+CONFIG_DEFAULT_DEVICE_TREE="mt7988a-bananapi-bpi-r4-sd"
|
||||
+CONFIG_TARGET_MT7988=y
|
||||
+CONFIG_BOARD_BPI_R4=y
|
||||
+CONFIG_SPL_LOAD_FIT=y
|
||||
+CONFIG_FIT=y
|
||||
+CONFIG_SYS_LOAD_ADDR=0x46000000
|
||||
+CONFIG_DEBUG_UART_BASE=0x11000000
|
||||
+CONFIG_DEBUG_UART_CLOCK=40000000
|
||||
+CONFIG_DEBUG_UART=y
|
||||
+# CONFIG_EFI_LOADER is not set
|
||||
+# CONFIG_AUTOBOOT is not set
|
||||
+CONFIG_DEFAULT_FDT_FILE="mt7988a-bananapi-bpi-r4-sd"
|
||||
+CONFIG_MULTI_DTB_FIT=y
|
||||
+CONFIG_OF_LIST="mt7988a-bananapi-bpi-r4-sd"
|
||||
+CONFIG_SYS_CBSIZE=512
|
||||
+CONFIG_SYS_PBSIZE=1049
|
||||
+CONFIG_LOGLEVEL=7
|
||||
+CONFIG_LOG=y
|
||||
+CONFIG_SYS_PROMPT="BPI-R4> "
|
||||
+# CONFIG_BOOTM_NETBSD is not set
|
||||
+# CONFIG_BOOTM_PLAN9 is not set
|
||||
+# CONFIG_BOOTM_RTEMS is not set
|
||||
+# CONFIG_BOOTM_VXWORKS is not set
|
||||
+# CONFIG_CMD_ELF is not set
|
||||
+CONFIG_CMD_BUTTON=y
|
||||
+CONFIG_CMD_CLK=y
|
||||
+CONFIG_CMD_DM=y
|
||||
+CONFIG_CMD_GPIO=y
|
||||
+CONFIG_CMD_I2C=y
|
||||
+CONFIG_CMD_MMC=y
|
||||
+CONFIG_CMD_MTD=y
|
||||
+CONFIG_CMD_MDIO=y
|
||||
+CONFIG_CMD_PCI=y
|
||||
+CONFIG_CMD_PING=y
|
||||
+CONFIG_CMD_PWM=y
|
||||
+CONFIG_CMD_SMC=y
|
||||
+CONFIG_CMD_USB=y
|
||||
+CONFIG_DOS_PARTITION=y
|
||||
+CONFIG_EFI_PARTITION=y
|
||||
+CONFIG_PARTITION_TYPE_GUID=y
|
||||
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
|
||||
+CONFIG_USE_IPADDR=y
|
||||
+CONFIG_IPADDR="192.168.1.1"
|
||||
+CONFIG_USE_NETMASK=y
|
||||
+CONFIG_NETMASK="255.255.255.0"
|
||||
+CONFIG_USE_SERVERIP=y
|
||||
+CONFIG_SERVERIP="192.168.1.2"
|
||||
+CONFIG_PROT_TCP=y
|
||||
+CONFIG_NET_RANDOM_ETHADDR=y
|
||||
+CONFIG_REGMAP=y
|
||||
+CONFIG_SYSCON=y
|
||||
+CONFIG_CLK=y
|
||||
+CONFIG_I2C=y
|
||||
+CONFIG_DM_I2C=y
|
||||
+CONFIG_SYS_I2C_MTK=y
|
||||
+CONFIG_I2C_MUX=y
|
||||
+CONFIG_I2C_MUX_PCA954x=y
|
||||
+CONFIG_MMC_WRITE=y
|
||||
+CONFIG_MMC_MTK=y
|
||||
+CONFIG_MTD=y
|
||||
+CONFIG_DM_MTD=y
|
||||
+CONFIG_MTD_SPI_NAND=y
|
||||
+CONFIG_DM_SPI_FLASH=y
|
||||
+CONFIG_SPI_FLASH_SFDP_SUPPORT=y
|
||||
+CONFIG_SPI_FLASH_EON=y
|
||||
+CONFIG_SPI_FLASH_GIGADEVICE=y
|
||||
+CONFIG_SPI_FLASH_ISSI=y
|
||||
+CONFIG_SPI_FLASH_MACRONIX=y
|
||||
+CONFIG_SPI_FLASH_SPANSION=y
|
||||
+CONFIG_SPI_FLASH_STMICRO=y
|
||||
+CONFIG_SPI_FLASH_WINBOND=y
|
||||
+CONFIG_SPI_FLASH_XMC=y
|
||||
+CONFIG_SPI_FLASH_XTX=y
|
||||
+CONFIG_SPI_FLASH_MTD=y
|
||||
+CONFIG_PHY_FIXED=y
|
||||
+CONFIG_DM_MDIO=y
|
||||
+CONFIG_DM_ETH_PHY=y
|
||||
+CONFIG_PHY_ETHERNET_ID=y
|
||||
+CONFIG_MEDIATEK_ETH=y
|
||||
+CONFIG_PCI=y
|
||||
+CONFIG_PCIE_MEDIATEK_GEN3=y
|
||||
+CONFIG_NVME_PCI=y
|
||||
+CONFIG_NVME=y
|
||||
+CONFIG_PINCTRL=y
|
||||
+CONFIG_PINCONF=y
|
||||
+CONFIG_PINCTRL_MT7988=y
|
||||
+CONFIG_POWER_DOMAIN=y
|
||||
+CONFIG_MTK_POWER_DOMAIN=y
|
||||
+CONFIG_DM_PWM=y
|
||||
+CONFIG_PWM_MTK=y
|
||||
+CONFIG_RAM=y
|
||||
+CONFIG_DM_SERIAL=y
|
||||
+CONFIG_MTK_SERIAL=y
|
||||
+CONFIG_PHY=y
|
||||
+CONFIG_PHY_MTK_TPHY=y
|
||||
+CONFIG_USB=y
|
||||
+CONFIG_USB_XHCI_HCD=y
|
||||
+CONFIG_USB_XHCI_MTK=y
|
||||
+CONFIG_USB_STORAGE=y
|
||||
+CONFIG_SPI=y
|
||||
+CONFIG_DM_SPI=y
|
||||
+CONFIG_MTK_SPIM=y
|
||||
+CONFIG_OF_LIBFDT_OVERLAY=y
|
||||
+CONFIG_OF_SYSTEM_SETUP=y
|
||||
+CONFIG_BOARD_LATE_INIT=y
|
||||
+CONFIG_LZO=y
|
||||
+CONFIG_HEXDUMP=y
|
||||
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt7988.c b/drivers/pinctrl/mediatek/pinctrl-mt7988.c
|
||||
index 639e2415c63..317a325d8c6 100644
|
||||
--- a/drivers/pinctrl/mediatek/pinctrl-mt7988.c
|
||||
+++ b/drivers/pinctrl/mediatek/pinctrl-mt7988.c
|
||||
@@ -942,6 +942,9 @@ static const int mt7988_emmc_45_pins[] = {
|
||||
21, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37 };
|
||||
static const int mt7988_emmc_45_funcs[] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 };
|
||||
|
||||
+static const int mt7988_sdcard_pins[] = { 32, 33, 34, 35, 36, 37 };
|
||||
+static const int mt7988_sdcard_funcs[] = { 5, 5, 5, 5, 5, 5 };
|
||||
+
|
||||
static const int mt7988_emmc_51_pins[] = {
|
||||
38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49 };
|
||||
static const int mt7988_emmc_51_funcs[] = {
|
||||
@@ -1101,6 +1104,7 @@ static const struct mtk_group_desc mt7988_groups[] = {
|
||||
PINCTRL_PIN_GROUP("udi", mt7988_udi),
|
||||
PINCTRL_PIN_GROUP("emmc_45", mt7988_emmc_45),
|
||||
PINCTRL_PIN_GROUP("emmc_51", mt7988_emmc_51),
|
||||
+ PINCTRL_PIN_GROUP("sdcard", mt7988_sdcard),
|
||||
PINCTRL_PIN_GROUP("2p5g_ext_mdio", mt7988_2p5g_ext_mdio),
|
||||
PINCTRL_PIN_GROUP("gbe_ext_mdio", mt7988_gbe_ext_mdio),
|
||||
PINCTRL_PIN_GROUP("pcm", mt7988_pcm),
|
||||
@@ -1197,7 +1201,7 @@ static const char *const mt7988_pmic_groups[] = { "pmic", };
|
||||
static const char *const mt7988_wdt_groups[] = { "watchdog", };
|
||||
static const char *const mt7988_spi_groups[] = { "spi0", "spi0_wp_hold",
|
||||
"spi1", "spi2", "spi2_wp_hold", };
|
||||
-static const char *const mt7988_flash_groups[] = { "emmc_45", "snfi",
|
||||
+static const char *const mt7988_flash_groups[] = { "emmc_45", "sdcard", "snfi",
|
||||
"emmc_51" };
|
||||
static const char *const mt7988_uart_groups[] = { "uart2", "tops_uart0_0",
|
||||
"uart2_0", "uart1_0", "uart2_1",
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -186,6 +186,13 @@ get_bootloader_name()
|
||||
echo "bpi_r3_sd_boot"
|
||||
fi
|
||||
;;
|
||||
bananapi-bpi-r4)
|
||||
if [ "$target" = "emmc" ]; then
|
||||
echo "bpi_r4_emmc_boot"
|
||||
else
|
||||
echo "bpi_r4_sd_boot"
|
||||
fi
|
||||
;;
|
||||
bananapi-bpi-r64)
|
||||
if [ "$target" = "emmc" ]; then
|
||||
echo "bpi_r64_emmc_boot"
|
||||
|
||||
Reference in New Issue
Block a user