mirror of
https://github.com/kernelkit/infix.git
synced 2026-07-22 01:13:00 +02:00
boards: Add new board bpi-r3-mini
This is a simple two port router board, with the same WiFi chips as BPI-r3. The bootloader shall be the same as the BPI-r3, the bootloader now probes which of the two is booting by checking for the PHYS that only exist on BPI-r3-mini.
This commit is contained in:
@@ -5,6 +5,7 @@ config BR2_PACKAGE_BANANAPI_BPI_R3
|
||||
select BR2_PACKAGE_LINUX_FIRMWARE
|
||||
select BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK
|
||||
select BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7986
|
||||
select BR2_PACKAGE_LINUX_FIRMWARE_AIROHA_EN8811H
|
||||
select SDCARD_AUX
|
||||
help
|
||||
Build Banana PI R3 support
|
||||
|
||||
@@ -9,6 +9,7 @@ define BANANAPI_BPI_R3_LINUX_CONFIG_FIXUPS
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_MEDIATEK_WATCHDOG)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_MEDIATEK_GE_PHY)
|
||||
$(call KCONFIG_ENABLE_OPT,CONFIG_REALTEK_PHY)
|
||||
$(call KCONFIG_SET_OPT,CONFIG_AIR_EN8811H_PHY,m)
|
||||
$(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)
|
||||
|
||||
@@ -1 +1 @@
|
||||
dtb-y += mediatek/mt7986a-bananapi-bpi-r3-sd.dtb mediatek/mt7986a-bananapi-bpi-r3-emmc.dtb
|
||||
dtb-y += mediatek/mt7986a-bananapi-bpi-r3-sd.dtb mediatek/mt7986a-bananapi-bpi-r3-emmc.dtb mediatek/mt7986a-bananapi-bpi-r3-mini.dtb
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
#include <arm64/mediatek/mt7986a-bananapi-bpi-r3.dts>
|
||||
|
||||
#include "mt7986a-bananapi-bpi-r3.dtsi"
|
||||
#include "mt7986a-bananapi-bpi-r3-emmc.dtsi"
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
#include <arm64/mediatek/mt7986a-bananapi-bpi-r3-mini.dts>
|
||||
|
||||
#include "mt7986a-bananapi-bpi-r3.dtsi"
|
||||
#include "mt7986a-bananapi-bpi-r3-emmc.dtsi"
|
||||
|
||||
&phy0 {
|
||||
compatible = "ethernet-phy-id03a2.a411";
|
||||
};
|
||||
&phy1 {
|
||||
compatible = "ethernet-phy-id03a2.a411";
|
||||
};
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
#include "mt7986a-bananapi-bpi-r3.dtsi"
|
||||
#include "mt7986a-bananapi-bpi-r3-emmc.dtsi"
|
||||
@@ -1,2 +1,4 @@
|
||||
#include <arm64/mediatek/mt7986a-bananapi-bpi-r3.dts>
|
||||
|
||||
#include "mt7986a-bananapi-bpi-r3.dtsi"
|
||||
#include "mt7986a-bananapi-bpi-r3-sd.dtsi"
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
#include <arm64/mediatek/mt7986a-bananapi-bpi-r3.dts>
|
||||
|
||||
/ {
|
||||
chosen {
|
||||
infix {
|
||||
|
||||
@@ -51,6 +51,11 @@ image #INFIX_ID##VERSION#-bpi-r3-#TARGET#.img {
|
||||
size = 4096s
|
||||
}
|
||||
|
||||
partition en8811h_fw {
|
||||
size = 10M
|
||||
image = "en8811h-fw.bin"
|
||||
}
|
||||
|
||||
partition aux {
|
||||
partition-uuid = D4EF35A0-0652-45A1-B3DE-D63339C82035
|
||||
image = "aux.ext4"
|
||||
|
||||
+445
@@ -0,0 +1,445 @@
|
||||
{
|
||||
"ieee802-dot1ab-lldp:lldp": {
|
||||
"infix-lldp:enabled": true
|
||||
},
|
||||
"ietf-hardware:hardware": {
|
||||
"component": [
|
||||
{
|
||||
"name": "USB",
|
||||
"class": "infix-hardware:usb",
|
||||
"state": {
|
||||
"admin-state": "unlocked"
|
||||
}
|
||||
},
|
||||
{
|
||||
"class": "infix-hardware:usb",
|
||||
"name": "USB2",
|
||||
"state": {
|
||||
"admin-state": "unlocked"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "radio0",
|
||||
"class": "infix-hardware:wifi",
|
||||
"infix-hardware:wifi-radio": {
|
||||
"country-code": "DE",
|
||||
"band": "2.4GHz",
|
||||
"channel": "auto"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "radio1",
|
||||
"class": "infix-hardware:wifi",
|
||||
"infix-hardware:wifi-radio": {
|
||||
"country-code": "DE",
|
||||
"band": "5GHz",
|
||||
"channel": "auto"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"ietf-interfaces:interfaces": {
|
||||
"interface": [
|
||||
{
|
||||
"name": "br0",
|
||||
"type": "infix-if-type:bridge",
|
||||
"ietf-ip:ipv4": {
|
||||
"address": [
|
||||
{
|
||||
"ip": "192.168.0.1",
|
||||
"prefix-length": 24
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "lan",
|
||||
"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"
|
||||
},
|
||||
{
|
||||
"id": "dns-server"
|
||||
},
|
||||
{
|
||||
"id": "router"
|
||||
},
|
||||
{
|
||||
"id": "netmask"
|
||||
},
|
||||
{
|
||||
"id": "vendor-class",
|
||||
"value": "Banana Pi BPI-R3"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"ietf-ip:ipv6": {
|
||||
"infix-dhcpv6-client:dhcp": {
|
||||
"option": [
|
||||
{
|
||||
"id": "ntp-server"
|
||||
},
|
||||
{
|
||||
"id": "client-fqdn"
|
||||
},
|
||||
{
|
||||
"id": "domain-search"
|
||||
},
|
||||
{
|
||||
"id": "dns-server"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "wifi0-ap",
|
||||
"type": "infix-if-type:wifi",
|
||||
"infix-interfaces:wifi": {
|
||||
"radio": "radio0",
|
||||
"access-point": {
|
||||
"ssid": "Infix",
|
||||
"security": {
|
||||
"secret": "wifi"
|
||||
}
|
||||
}
|
||||
},
|
||||
"infix-interfaces:bridge-port": {
|
||||
"bridge": "br0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "wifi1-ap",
|
||||
"type": "infix-if-type:wifi",
|
||||
"infix-interfaces:wifi": {
|
||||
"radio": "radio1",
|
||||
"access-point": {
|
||||
"ssid": "Infix5Ghz",
|
||||
"security": {
|
||||
"secret": "wifi"
|
||||
}
|
||||
}
|
||||
},
|
||||
"infix-interfaces:bridge-port": {
|
||||
"bridge": "br0"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"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": {}
|
||||
}
|
||||
]
|
||||
},
|
||||
"symmetric-keys": {
|
||||
"symmetric-key": [
|
||||
{
|
||||
"name": "wifi",
|
||||
"cleartext-symmetric-key": "aW5maXhpbmZpeA==",
|
||||
"key-format": "infix-crypto-types:passphrase-key-format"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"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/eth0", NAME="lan"
|
||||
ACTION=="add", SUBSYSTEM=="net", DEVPATH=="/devices/platform/soc/15100000.ethernet/net/eth1", NAME="wan"
|
||||
@@ -3,6 +3,9 @@ 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="mt7986a-bpi-r3-sd mt7986a-bpi-r3-emmc mt7986a-bpi-r3-mini"
|
||||
|
||||
CONFIG_USB=y
|
||||
CONFIG_USB_XHCI_HCD=y
|
||||
CONFIG_USB_XHCI_MTK=y
|
||||
@@ -26,8 +29,17 @@ CONFIG_MTD_SPI_NAND=y
|
||||
CONFIG_MTK_SPIM=y
|
||||
CONFIG_MTK_SNOR=y
|
||||
|
||||
CONFIG_DM_MDIO=y
|
||||
CONFIG_DM_ETH_PHY=y
|
||||
CONFIG_PHY_ETHERNET_ID=y
|
||||
|
||||
CONFIG_PHY_AIROHA=y
|
||||
CONFIG_PHY_AIROHA_EN8811H=y
|
||||
CONFIG_PHY_AIROHA_FW_IN_MMC=y
|
||||
|
||||
CONFIG_CMD_SF=y
|
||||
CONFIG_CMD_USB=y
|
||||
CONFIG_CMD_MTD=y
|
||||
CONFIG_CMD_MDIO=y
|
||||
CONFIG_CMD_MTDPARTS=y
|
||||
CONFIG_CMD_DM=y
|
||||
|
||||
@@ -15,6 +15,10 @@
|
||||
scriptaddr = "0x48000000";
|
||||
ramdisk_addr_r = "0x4A000000";
|
||||
|
||||
en8811h_fw_part = "0#en8811h_fw";
|
||||
en8811h_fw_dm_dir = "EthMD32.dm.bin";
|
||||
en8811h_fw_dsp_dir = "EthMD32.DSP.bin";
|
||||
|
||||
/* This is a development platform, keep
|
||||
* developer mode statically enabled.
|
||||
*/
|
||||
|
||||
@@ -11,6 +11,8 @@ BR2_SSP_NONE=y
|
||||
BR2_INIT_NONE=y
|
||||
BR2_SYSTEM_BIN_SH_NONE=y
|
||||
# BR2_PACKAGE_BUSYBOX is not set
|
||||
BR2_PACKAGE_LINUX_FIRMWARE=y
|
||||
BR2_PACKAGE_LINUX_FIRMWARE_AIROHA_EN8811H=y
|
||||
# BR2_PACKAGE_IFUPDOWN_SCRIPTS is not set
|
||||
# BR2_TARGET_ROOTFS_TAR is not set
|
||||
BR2_TARGET_ARM_TRUSTED_FIRMWARE=y
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
From 989ef8436df2ee48d308981098c44b1b8257c23b Mon Sep 17 00:00:00 2001
|
||||
From 9a9885324c70d607c9c79814441dbc829e212e41 Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Mon, 10 Jun 2024 13:25:31 +0200
|
||||
Subject: [PATCH 8/8] hush: Remove Ctrl-C detection in loops
|
||||
Organization: Addiva Elektronik
|
||||
Subject: [PATCH 1/7] hush: Remove Ctrl-C detection in loops
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
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
|
||||
@@ -14,15 +17,16 @@ 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: Mattias Walström <lazzer@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 171069f5f4..d6d487893f 100644
|
||||
index a6a8edce1f4..0711e05a779 100644
|
||||
--- a/common/cli_hush.c
|
||||
+++ b/common/cli_hush.c
|
||||
@@ -1796,13 +1796,6 @@ static int run_list_real(struct pipe *pi)
|
||||
@@ -1792,13 +1792,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) {
|
||||
@@ -37,5 +41,5 @@ index 171069f5f4..d6d487893f 100644
|
||||
if (!rpipe) {
|
||||
flag_rep = 0;
|
||||
--
|
||||
2.34.1
|
||||
2.43.0
|
||||
|
||||
|
||||
+20
@@ -1,3 +1,20 @@
|
||||
From 7efc3aa61fbc84b2c0c959e737257d2de2e8020c 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 2/7] 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>
|
||||
---
|
||||
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 1d7ddb4ed36..8572dc4353e 100644
|
||||
--- a/cmd/Kconfig
|
||||
@@ -130,3 +147,6 @@ index 00000000000..07abdc08552
|
||||
+ "Returns: 0=connected, 1=not detected, 2=no video\n"
|
||||
+ "Usage: if testrpidisplay; then echo DSI found; fi"
|
||||
+);
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
From c646eef3ee304ae49ad7e3f998ed08bfa0efb7b9 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 3/7] arm: dts: at91: sama7g5ek: increase clock for sdmmc from
|
||||
25 MHz to 50 MHz
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
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: Mattias Walström <lazzer@gmail.com>
|
||||
---
|
||||
arch/arm/dts/at91-sama7g5ek.dts | 4 ----
|
||||
1 file changed, 4 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/dts/at91-sama7g5ek.dts b/arch/arm/dts/at91-sama7g5ek.dts
|
||||
index 9b247fcaf66..5bbbdd8ed76 100644
|
||||
--- a/arch/arm/dts/at91-sama7g5ek.dts
|
||||
+++ b/arch/arm/dts/at91-sama7g5ek.dts
|
||||
@@ -776,8 +776,6 @@
|
||||
&sdmmc0 {
|
||||
bus-width = <8>;
|
||||
non-removable;
|
||||
- no-1-8-v;
|
||||
- sdhci-caps-mask = <0x0 0x00200000>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_sdmmc0_default>;
|
||||
status = "okay";
|
||||
@@ -785,8 +783,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,37 @@
|
||||
From 5a530e4eebf64887fd6b449dd45df04eccd07cad Mon Sep 17 00:00:00 2001
|
||||
From: Joachim Wiberg <troglobit@gmail.com>
|
||||
Date: Thu, 12 Feb 2026 10:00:02 +0100
|
||||
Subject: [PATCH 4/7] arm: dts: at91: sama7g5ek supports high-speed on mmc0
|
||||
(eMMC)
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
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>
|
||||
Signed-off-by: Mattias Walström <lazzer@gmail.com>
|
||||
---
|
||||
arch/arm/dts/at91-sama7g5ek.dts | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/arch/arm/dts/at91-sama7g5ek.dts b/arch/arm/dts/at91-sama7g5ek.dts
|
||||
index 5bbbdd8ed76..d2d16bd5f1f 100644
|
||||
--- a/arch/arm/dts/at91-sama7g5ek.dts
|
||||
+++ b/arch/arm/dts/at91-sama7g5ek.dts
|
||||
@@ -776,6 +776,8 @@
|
||||
&sdmmc0 {
|
||||
bus-width = <8>;
|
||||
non-removable;
|
||||
+ cap-mmc-highspeed;
|
||||
+ cap-mmc-hw-reset;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_sdmmc0_default>;
|
||||
status = "okay";
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -0,0 +1,980 @@
|
||||
From be250151366460ee318ca47bb15ec23e5e322a84 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 5/7] net: phy: Add the Airoha EN8811H PHY driver
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
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: Mattias Walström <lazzer@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 13e73810ad6..4f7451bf0c1 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 2487f366e1c..87dee3c15b9 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,275 @@
|
||||
From a987f92a768291669eec1a8c5d413190bd9241ec 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 6/7] Add bpi-r3-mini device tree
|
||||
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>
|
||||
---
|
||||
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 6ad59aeed5f..3561e4c3651 100644
|
||||
--- a/arch/arm/dts/Makefile
|
||||
+++ b/arch/arm/dts/Makefile
|
||||
@@ -1199,6 +1199,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..b8d0a01c9ed
|
||||
--- /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 = <&gpio 7 GPIO_ACTIVE_LOW>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ leds {
|
||||
+ compatible = "gpio-leds";
|
||||
+
|
||||
+ status_led: led-0 {
|
||||
+ label = "green:status";
|
||||
+ gpios = <&gpio 19 GPIO_ACTIVE_HIGH>;
|
||||
+ };
|
||||
+
|
||||
+ led-1 {
|
||||
+ label = "blue:wlan2g";
|
||||
+ gpios = <&gpio 1 GPIO_ACTIVE_HIGH>;
|
||||
+ };
|
||||
+
|
||||
+ led-2 {
|
||||
+ label = "blue:wlan5g";
|
||||
+ gpios = <&gpio 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 = <&gpio 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";
|
||||
+};
|
||||
+
|
||||
+&pinctrl {
|
||||
+ 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,562 @@
|
||||
From 57b3cd8612a8da852f0796d97e6a7526cc4742cc 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 7/7] bpi-r3/r4: Add probe for specific model
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
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: Mattias Walström <lazzer@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 ff1fdee5c8d..def8a564d90 100644
|
||||
--- a/arch/arm/mach-mediatek/Kconfig
|
||||
+++ b/arch/arm/mach-mediatek/Kconfig
|
||||
@@ -153,4 +153,7 @@ config MTK_BROM_HEADER_INFO
|
||||
default "media=snand;nandinfo=2k+64" if TARGET_MT7981 || TARGET_MT7986 || TARGET_MT7988
|
||||
default "lk=1" if TARGET_MT7623
|
||||
|
||||
+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 ef6a4822c18..193acb4a9b4 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 3d971f5c313..e498b58a4a5 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
|
||||
|
||||
@@ -259,6 +259,50 @@ download_bootloader()
|
||||
log "Bootloader ready in temporary directory"
|
||||
}
|
||||
|
||||
# Build EN8811H firmware partition image as an ext4 filesystem containing
|
||||
# EthMD32.dm.bin and EthMD32.DSP.bin. Returns 0 when created, 1 when source
|
||||
# files are missing.
|
||||
prepare_en8811h_fw_image()
|
||||
{
|
||||
src_dir="$1"
|
||||
out_img="$2"
|
||||
dm_fw="${src_dir}/EthMD32.dm.bin"
|
||||
dsp_fw="${src_dir}/EthMD32.DSP.bin"
|
||||
fw_staging=""
|
||||
|
||||
[ -f "$dm_fw" ] && [ -f "$dsp_fw" ] || return 1
|
||||
|
||||
fw_staging=$(mktemp -d)
|
||||
cp "$dm_fw" "$fw_staging/EthMD32.dm.bin"
|
||||
cp "$dsp_fw" "$fw_staging/EthMD32.DSP.bin"
|
||||
|
||||
rm -f "$out_img"
|
||||
truncate -s 2M "$out_img"
|
||||
|
||||
if command -v mke2fs >/dev/null 2>&1; then
|
||||
mke2fs -q -t ext4 -L en8811h_fw -d "$fw_staging" "$out_img"
|
||||
elif command -v mkfs.ext4 >/dev/null 2>&1; then
|
||||
mkfs.ext4 -q -L en8811h_fw -d "$fw_staging" "$out_img"
|
||||
else
|
||||
rm -rf "$fw_staging"
|
||||
die "mke2fs/mkfs.ext4 not found, cannot create en8811h-fw.bin"
|
||||
fi
|
||||
|
||||
rm -rf "$fw_staging"
|
||||
return 0
|
||||
}
|
||||
|
||||
maybe_prepare_en8811h_fw_image()
|
||||
{
|
||||
out_img="${BINARIES_DIR}/en8811h-fw.bin"
|
||||
|
||||
[ -f "$out_img" ] && return 0
|
||||
|
||||
prepare_en8811h_fw_image "${ROOT_DIR}/images/airoha" "$out_img" || \
|
||||
prepare_en8811h_fw_image "${ROOT_DIR}/airoha" "$out_img" || \
|
||||
prepare_en8811h_fw_image "${BINARIES_DIR}/airoha" "$out_img" || return 0
|
||||
}
|
||||
|
||||
# Discover boot files for Raspberry Pi boot partition
|
||||
# Scans rpi-firmware directory and builds file list for genimage
|
||||
discover_rpi_boot_files()
|
||||
@@ -519,6 +563,11 @@ if [ -n "$DOWNLOAD_BOOT" ]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$BOARD" = "bananapi-bpi-r3" ]; then
|
||||
maybe_prepare_en8811h_fw_image
|
||||
[ -f "${BINARIES_DIR}/en8811h-fw.bin" ] || die "Missing EN8811H firmware image: ${BINARIES_DIR}/en8811h-fw.bin"
|
||||
fi
|
||||
|
||||
# Template expansion
|
||||
log "Generating genimage configuration for $BOARD..."
|
||||
|
||||
|
||||
Reference in New Issue
Block a user