Merge patch series "arm: airoha: add support for en7523 based boards"
Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu> says: This patch series adds basic support for the boards based on Airoha EN7523/EN7529/EN7562 SoCs. Due to ATF restrictions these boards are able to run 32-bit OS only. This patch series adds support for the following hardware: * console UART * ethernet controller/switch * spinand flash (in non-dma mode) The following issues may be expected: * Extra slow UBI attaching in U-Boot (up to 20 sec with fastmap enabled). This is caused by the lack of DMA support in the U-Boot airoha-snfi driver. * Linux airoha-snfi driver in some cases might damage you flash data (see: https://lore.kernel.org/lkml/20251012121707.2296160-15-mikhail.kshevetskiy@iopsys.eu/) * Latest linux kernel is recommended to properly support flashes with more than one plane per lun (see: https://lore.kernel.org/lkml/20251012121707.2296160-7-mikhail.kshevetskiy@iopsys.eu/) * It's NOT recommended to use flashes working in continuous mode because U-Boot airoha-snfi driver does not support such flashes properly. The patches was tested on the board: - SoC: Airoha EN7562 - RAM: 512 MB - SPI NAND: 4 Gbit, made by Toshiba - Linux boot: was NOT tested The U-Boot was chain-loaded from the running U-Boot. Airoha ATF-2.3 does not allow easily chain-loading of U-Boot from U-Boot, so a special FIT image (mimic linux kernel) was created 1) Create u-boot.its file with the following contents: === cut here === /dts-v1/; / { description = "ARM OpenWrt FIT (Flattened Image Tree)"; #address-cells = <1>; images { u-boot-ram { description = "OpenWrt U-Boot RAM image"; data = /incbin/("u-boot.bin.lzma"); type = "kernel"; arch = "arm"; os = "linux"; compression = "lzma"; load = <0x81e00000>; entry = <0x81e00000>; hash@1 { algo = "crc32"; }; hash@2 { algo = "sha1"; }; }; fdt-1 { description = "OpenWrt device tree blob"; data = /incbin/("dts/upstream/src/arm/airoha/en7523-evb.dtb"); type = "flat_dt"; arch = "arm"; compression = "none"; hash@1 { algo = "crc32"; }; hash@2 { algo = "sha1"; }; }; }; configurations { default = "config-ram-uboot"; config-ram-uboot { description = "OpenWrt RAM U-Boot"; kernel = "u-boot-ram"; fdt = "fdt-1"; }; }; }; ================== 2) Create u-boot.itb image to chain-load new u-boot from the old one lzma_alone e u-boot.bin u-boot.bin.lzma mkimage -f u-boot.its u-boot.itb 3) Load new u-boot from the old one U-Boot> tftpboot u-boot.itb && bootm Link: https://lore.kernel.org/r/20251101004503.2379529-1-mikhail.kshevetskiy@iopsys.eu
This commit is contained in:
11
arch/arm/dts/en7523-evb-u-boot.dtsi
Normal file
11
arch/arm/dts/en7523-evb-u-boot.dtsi
Normal file
@@ -0,0 +1,11 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
|
||||
/ {
|
||||
/* When running as a first-stage bootloader this isn't filled in automatically */
|
||||
memory@80000000 {
|
||||
device_type = "memory";
|
||||
reg = <0x80000000 0x10000000>;
|
||||
};
|
||||
};
|
||||
|
||||
#include "en7523-u-boot.dtsi"
|
||||
70
arch/arm/dts/en7523-u-boot.dtsi
Normal file
70
arch/arm/dts/en7523-u-boot.dtsi
Normal file
@@ -0,0 +1,70 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
|
||||
#include <dt-bindings/reset/airoha,en7523-reset.h>
|
||||
|
||||
/ {
|
||||
reserved-memory {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges;
|
||||
|
||||
atf-reserved-memory@80000000 {
|
||||
no-map;
|
||||
reg = <0x80000000 0x40000>;
|
||||
};
|
||||
};
|
||||
|
||||
scu: system-controller@1fa20000 {
|
||||
compatible = "airoha,en7523-scu";
|
||||
reg = <0x1fa20000 0x400>,
|
||||
<0x1fb00000 0x1000>;
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
};
|
||||
|
||||
eth: ethernet@1fb50000 {
|
||||
compatible = "airoha,en7523-eth";
|
||||
reg = <0x1fb50000 0x2600>,
|
||||
<0x1fb54000 0x2000>,
|
||||
<0x1fb56000 0x2000>;
|
||||
reg-names = "fe", "qdma0", "qdma1";
|
||||
|
||||
resets = <&scu EN7523_FE_RST>,
|
||||
<&scu EN7523_FE_PDMA_RST>,
|
||||
<&scu EN7523_FE_QDMA_RST>,
|
||||
<&scu EN7523_DUAL_HSI0_MAC_RST>,
|
||||
<&scu EN7523_DUAL_HSI1_MAC_RST>,
|
||||
<&scu EN7523_HSI_MAC_RST>;
|
||||
reset-names = "fe", "pdma", "qdma",
|
||||
"hsi0-mac", "hsi1-mac", "hsi-mac";
|
||||
};
|
||||
|
||||
switch: switch@1fb58000 {
|
||||
compatible = "airoha,en7523-switch";
|
||||
reg = <0x1fb58000 0x8000>;
|
||||
};
|
||||
|
||||
snfi: spi@1fa10000 {
|
||||
compatible = "airoha,en7523-snand", "airoha,en7581-snand";
|
||||
reg = <0x1fa10000 0x140>,
|
||||
<0x1fa11000 0x600>;
|
||||
|
||||
clocks = <&scu EN7523_CLK_SPI>;
|
||||
clock-names = "spi";
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
spi_nand: nand@0 {
|
||||
compatible = "spi-nand";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <50000000>;
|
||||
spi-tx-bus-width = <1>;
|
||||
spi-rx-bus-width = <1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&uart1 {
|
||||
bootph-all;
|
||||
};
|
||||
13
arch/arm/include/asm/arch-airoha/scu-regmap.h
Normal file
13
arch/arm/include/asm/arch-airoha/scu-regmap.h
Normal file
@@ -0,0 +1,13 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Author: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
|
||||
*/
|
||||
#ifndef __AIROHA_SCU_REGMAP__
|
||||
#define __AIROHA_SCU_REGMAP__
|
||||
|
||||
#include <regmap.h>
|
||||
|
||||
struct regmap *airoha_get_scu_regmap(void);
|
||||
struct regmap *airoha_get_chip_scu_regmap(void);
|
||||
|
||||
#endif
|
||||
1
arch/arm/include/asm/arch-an7581
Symbolic link
1
arch/arm/include/asm/arch-an7581
Symbolic link
@@ -0,0 +1 @@
|
||||
arch-airoha
|
||||
1
arch/arm/include/asm/arch-en7523
Symbolic link
1
arch/arm/include/asm/arch-en7523
Symbolic link
@@ -0,0 +1 @@
|
||||
arch-airoha
|
||||
@@ -6,6 +6,17 @@ config SYS_VENDOR
|
||||
choice
|
||||
prompt "Airoha board select"
|
||||
|
||||
config TARGET_EN7523
|
||||
bool "Airoha EN7523 SoC"
|
||||
select CPU_V7A
|
||||
select ARMV7_SET_CORTEX_SMPEN
|
||||
help
|
||||
The Airoha EN7523 family (en7523/en7529/en7562) is an ARM-based
|
||||
SoCs with a dual-core CPU. It comes with Wi-Fi 5/6 support and
|
||||
connectivity to Ethernet PHY, DDR, PCIe, USB, UART and VoIP.
|
||||
With advanced hardware design, EN7523 provides high processing
|
||||
performance and low power consumption.
|
||||
|
||||
config TARGET_AN7581
|
||||
bool "Airoha AN7581 SoC"
|
||||
select ARM64
|
||||
@@ -20,12 +31,15 @@ config TARGET_AN7581
|
||||
endchoice
|
||||
|
||||
config SYS_SOC
|
||||
default "en7523" if TARGET_EN7523
|
||||
default "an7581" if TARGET_AN7581
|
||||
|
||||
config SYS_BOARD
|
||||
default "en7523" if TARGET_EN7523
|
||||
default "an7581" if TARGET_AN7581
|
||||
|
||||
config SYS_CONFIG_NAME
|
||||
default "en7523" if TARGET_EN7523
|
||||
default "an7581" if TARGET_AN7581
|
||||
|
||||
endif
|
||||
|
||||
@@ -2,4 +2,5 @@
|
||||
|
||||
obj-y += cpu.o
|
||||
|
||||
obj-$(CONFIG_TARGET_EN7523) += en7523/
|
||||
obj-$(CONFIG_TARGET_AN7581) += an7581/
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
obj-y += init.o
|
||||
obj-y += scu-regmap.o
|
||||
|
||||
30
arch/arm/mach-airoha/an7581/scu-regmap.c
Normal file
30
arch/arm/mach-airoha/an7581/scu-regmap.c
Normal file
@@ -0,0 +1,30 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Author: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
|
||||
*/
|
||||
|
||||
#include <syscon.h>
|
||||
#include <linux/err.h>
|
||||
#include <asm/arch/scu-regmap.h>
|
||||
|
||||
struct regmap *airoha_get_scu_regmap(void)
|
||||
{
|
||||
ofnode node;
|
||||
|
||||
node = ofnode_by_compatible(ofnode_null(), "airoha,en7581-scu");
|
||||
if (!ofnode_valid(node))
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
return syscon_node_to_regmap(node);
|
||||
}
|
||||
|
||||
struct regmap *airoha_get_chip_scu_regmap(void)
|
||||
{
|
||||
ofnode node;
|
||||
|
||||
node = ofnode_by_compatible(ofnode_null(), "airoha,en7581-chip-scu");
|
||||
if (!ofnode_valid(node))
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
return syscon_node_to_regmap(node);
|
||||
}
|
||||
4
arch/arm/mach-airoha/en7523/Makefile
Normal file
4
arch/arm/mach-airoha/en7523/Makefile
Normal file
@@ -0,0 +1,4 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
obj-y += init.o
|
||||
obj-y += scu-regmap.o
|
||||
33
arch/arm/mach-airoha/en7523/init.c
Normal file
33
arch/arm/mach-airoha/en7523/init.c
Normal file
@@ -0,0 +1,33 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Author: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
|
||||
*/
|
||||
#include <fdtdec.h>
|
||||
#include <init.h>
|
||||
#include <sysreset.h>
|
||||
#include <asm/system.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
int print_cpuinfo(void)
|
||||
{
|
||||
printf("CPU: Airoha EN7523/EN7529/EN7562\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dram_init(void)
|
||||
{
|
||||
return fdtdec_setup_mem_size_base();
|
||||
}
|
||||
|
||||
int dram_init_banksize(void)
|
||||
{
|
||||
return fdtdec_setup_memory_banksize();
|
||||
}
|
||||
|
||||
void __noreturn reset_cpu(void)
|
||||
{
|
||||
writel(0x80000000, 0x1FB00040);
|
||||
while (1) {
|
||||
/* loop forever */
|
||||
}
|
||||
}
|
||||
38
arch/arm/mach-airoha/en7523/scu-regmap.c
Normal file
38
arch/arm/mach-airoha/en7523/scu-regmap.c
Normal file
@@ -0,0 +1,38 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Author: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
|
||||
*/
|
||||
|
||||
#include <dm/ofnode.h>
|
||||
#include <linux/err.h>
|
||||
#include <asm/arch/scu-regmap.h>
|
||||
|
||||
static struct regmap *airoha_scu_node_regmap_by_index(unsigned int index)
|
||||
{
|
||||
struct regmap *map;
|
||||
ofnode node;
|
||||
int err;
|
||||
|
||||
node = ofnode_by_compatible(ofnode_null(), "airoha,en7523-scu");
|
||||
if (!ofnode_valid(node))
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
/* CHIP_SCU (index=0), SCU (index=1) */
|
||||
err = regmap_init_mem_index(node, &map, index);
|
||||
if (err)
|
||||
return ERR_PTR(err);
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
struct regmap *airoha_get_scu_regmap(void)
|
||||
{
|
||||
/* CHIP_SCU (index=0), SCU (index=1) */
|
||||
return airoha_scu_node_regmap_by_index(1);
|
||||
}
|
||||
|
||||
struct regmap *airoha_get_chip_scu_regmap(void)
|
||||
{
|
||||
/* CHIP_SCU (index=0), SCU (index=1) */
|
||||
return airoha_scu_node_regmap_by_index(0);
|
||||
}
|
||||
4
board/airoha/en7523/MAINTAINERS
Normal file
4
board/airoha/en7523/MAINTAINERS
Normal file
@@ -0,0 +1,4 @@
|
||||
EN7523
|
||||
M: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
|
||||
S: Maintained
|
||||
N: en7523
|
||||
3
board/airoha/en7523/Makefile
Normal file
3
board/airoha/en7523/Makefile
Normal file
@@ -0,0 +1,3 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
obj-y += en7523_rfb.o
|
||||
16
board/airoha/en7523/en7523_rfb.c
Normal file
16
board/airoha/en7523/en7523_rfb.c
Normal file
@@ -0,0 +1,16 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Author: Christian Marangi <ansuelsmth@gmail.com>
|
||||
*/
|
||||
|
||||
#include <asm/global_data.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
int board_init(void)
|
||||
{
|
||||
/* address of boot parameters */
|
||||
gd->bd->bi_boot_params = CFG_SYS_SDRAM_BASE + 0x100;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
CONFIG_ARM=y
|
||||
CONFIG_ARCH_AIROHA=y
|
||||
CONFIG_TARGET_AN7581=y
|
||||
CONFIG_TEXT_BASE=0x81E00000
|
||||
CONFIG_SYS_MALLOC_F_LEN=0x4000
|
||||
CONFIG_NR_DRAM_BANKS=1
|
||||
|
||||
67
configs/en7523_evb_defconfig
Normal file
67
configs/en7523_evb_defconfig
Normal file
@@ -0,0 +1,67 @@
|
||||
CONFIG_ARM=y
|
||||
CONFIG_SYS_ARCH_TIMER=y
|
||||
CONFIG_ARCH_AIROHA=y
|
||||
CONFIG_TARGET_EN7523=y
|
||||
CONFIG_TEXT_BASE=0x81E00000
|
||||
CONFIG_SYS_MALLOC_F_LEN=0x4000
|
||||
CONFIG_NR_DRAM_BANKS=1
|
||||
CONFIG_ENV_MTD_DEV="spi-nand0"
|
||||
CONFIG_ENV_SIZE=0x4000
|
||||
CONFIG_ENV_OFFSET=0x7c000
|
||||
CONFIG_DM_GPIO=y
|
||||
CONFIG_DEFAULT_DEVICE_TREE="airoha/en7523-evb"
|
||||
CONFIG_SYS_LOAD_ADDR=0x81800000
|
||||
CONFIG_BUILD_TARGET="u-boot.bin"
|
||||
# CONFIG_EFI_LOADER is not set
|
||||
CONFIG_FIT=y
|
||||
CONFIG_FIT_VERBOSE=y
|
||||
CONFIG_BOOTDELAY=3
|
||||
CONFIG_DEFAULT_FDT_FILE="en7523-evb"
|
||||
CONFIG_SYS_PBSIZE=1049
|
||||
CONFIG_SYS_CONSOLE_IS_IN_ENV=y
|
||||
# CONFIG_DISPLAY_BOARDINFO is not set
|
||||
CONFIG_HUSH_PARSER=y
|
||||
CONFIG_SYS_PROMPT="U-Boot> "
|
||||
CONFIG_SYS_MAXARGS=8
|
||||
CONFIG_CMD_BOOTZ=y
|
||||
CONFIG_CMD_BOOTMENU=y
|
||||
# CONFIG_CMD_ELF is not set
|
||||
# CONFIG_CMD_XIMG is not set
|
||||
CONFIG_CMD_BIND=y
|
||||
CONFIG_CMD_GPIO=y
|
||||
CONFIG_CMD_MTD=y
|
||||
# CONFIG_CMD_SETEXPR is not set
|
||||
CONFIG_CMD_PING=y
|
||||
CONFIG_CMD_EXT4=y
|
||||
CONFIG_CMD_FAT=y
|
||||
CONFIG_CMD_FS_GENERIC=y
|
||||
CONFIG_CMD_MTDPARTS=y
|
||||
CONFIG_CMD_LOG=y
|
||||
CONFIG_OF_UPSTREAM=y
|
||||
CONFIG_ENV_OVERWRITE=y
|
||||
CONFIG_ENV_IS_IN_MTD=y
|
||||
CONFIG_ENV_RELOC_GD_ENV_ADDR=y
|
||||
CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
|
||||
CONFIG_NET_RANDOM_ETHADDR=y
|
||||
CONFIG_SYS_RX_ETH_BUFFER=8
|
||||
CONFIG_REGMAP=y
|
||||
CONFIG_CLK=y
|
||||
CONFIG_DM_RESET=y
|
||||
CONFIG_DMA=y
|
||||
CONFIG_LED=y
|
||||
CONFIG_LED_GPIO=y
|
||||
# CONFIG_MMC is not set
|
||||
CONFIG_MTD=y
|
||||
CONFIG_DM_MTD=y
|
||||
CONFIG_MTD_SPI_NAND=y
|
||||
CONFIG_AIROHA_ETH=y
|
||||
CONFIG_PHY=y
|
||||
CONFIG_PINCTRL=y
|
||||
CONFIG_PINCONF=y
|
||||
CONFIG_RAM=y
|
||||
CONFIG_DM_SERIAL=y
|
||||
CONFIG_SYS_NS16550=y
|
||||
CONFIG_SPI=y
|
||||
CONFIG_DM_SPI=y
|
||||
CONFIG_AIROHA_SNFI_SPI=y
|
||||
CONFIG_SHA512=y
|
||||
@@ -16,7 +16,7 @@
|
||||
#include <dm/device_compat.h>
|
||||
#include <dm/lists.h>
|
||||
#include <regmap.h>
|
||||
#include <syscon.h>
|
||||
#include <asm/arch/scu-regmap.h>
|
||||
|
||||
#include <dt-bindings/clock/en7523-clk.h>
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#define REG_SPI_CLK_DIV_SEL 0x1c4
|
||||
#define REG_SPI_CLK_FREQ_SEL 0x1c8
|
||||
#define REG_NPU_CLK_DIV_SEL 0x1fc
|
||||
#define REG_CRYPTO_CLKSRC 0x200
|
||||
|
||||
#define REG_NP_SCU_PCIC 0x88
|
||||
#define REG_NP_SCU_SSTR 0x9c
|
||||
@@ -33,6 +34,7 @@
|
||||
#define REG_PCIE_XSI1_SEL_MASK GENMASK(12, 11)
|
||||
#define REG_CRYPTO_CLKSRC2 0x20c
|
||||
|
||||
#define EN7523_MAX_CLKS 8
|
||||
#define EN7581_MAX_CLKS 9
|
||||
|
||||
struct airoha_clk_desc {
|
||||
@@ -66,14 +68,119 @@ struct airoha_clk_soc_data {
|
||||
};
|
||||
|
||||
static const u32 gsw_base[] = { 400000000, 500000000 };
|
||||
static const u32 emi_base[] = { 333000000, 400000000 };
|
||||
static const u32 bus_base[] = { 500000000, 540000000 };
|
||||
static const u32 slic_base[] = { 100000000, 3125000 };
|
||||
|
||||
static const u32 npu_base[] = { 333000000, 400000000, 500000000 };
|
||||
/* EN7581 */
|
||||
static const u32 emi7581_base[] = { 540000000, 480000000, 400000000, 300000000 };
|
||||
static const u32 bus7581_base[] = { 600000000, 540000000 };
|
||||
static const u32 npu7581_base[] = { 800000000, 750000000, 720000000, 600000000 };
|
||||
static const u32 crypto_base[] = { 540000000, 480000000 };
|
||||
static const u32 emmc7581_base[] = { 200000000, 150000000 };
|
||||
|
||||
static const struct airoha_clk_desc en7523_base_clks[EN7523_MAX_CLKS] = {
|
||||
[EN7523_CLK_GSW] = {
|
||||
.id = EN7523_CLK_GSW,
|
||||
.name = "gsw",
|
||||
|
||||
.base_reg = REG_GSW_CLK_DIV_SEL,
|
||||
.base_bits = 1,
|
||||
.base_shift = 8,
|
||||
.base_values = gsw_base,
|
||||
.n_base_values = ARRAY_SIZE(gsw_base),
|
||||
|
||||
.div_bits = 3,
|
||||
.div_shift = 0,
|
||||
.div_step = 1,
|
||||
.div_offset = 1,
|
||||
},
|
||||
[EN7523_CLK_EMI] = {
|
||||
.id = EN7523_CLK_EMI,
|
||||
.name = "emi",
|
||||
|
||||
.base_reg = REG_EMI_CLK_DIV_SEL,
|
||||
.base_bits = 1,
|
||||
.base_shift = 8,
|
||||
.base_values = emi_base,
|
||||
.n_base_values = ARRAY_SIZE(emi_base),
|
||||
|
||||
.div_bits = 3,
|
||||
.div_shift = 0,
|
||||
.div_step = 1,
|
||||
.div_offset = 1,
|
||||
},
|
||||
[EN7523_CLK_BUS] = {
|
||||
.id = EN7523_CLK_BUS,
|
||||
.name = "bus",
|
||||
|
||||
.base_reg = REG_BUS_CLK_DIV_SEL,
|
||||
.base_bits = 1,
|
||||
.base_shift = 8,
|
||||
.base_values = bus_base,
|
||||
.n_base_values = ARRAY_SIZE(bus_base),
|
||||
|
||||
.div_bits = 3,
|
||||
.div_shift = 0,
|
||||
.div_step = 1,
|
||||
.div_offset = 1,
|
||||
},
|
||||
[EN7523_CLK_SLIC] = {
|
||||
.id = EN7523_CLK_SLIC,
|
||||
.name = "slic",
|
||||
|
||||
.base_reg = REG_SPI_CLK_FREQ_SEL,
|
||||
.base_bits = 1,
|
||||
.base_shift = 0,
|
||||
.base_values = slic_base,
|
||||
.n_base_values = ARRAY_SIZE(slic_base),
|
||||
|
||||
.div_reg = REG_SPI_CLK_DIV_SEL,
|
||||
.div_bits = 5,
|
||||
.div_shift = 24,
|
||||
.div_val0 = 20,
|
||||
.div_step = 2,
|
||||
},
|
||||
[EN7523_CLK_SPI] = {
|
||||
.id = EN7523_CLK_SPI,
|
||||
.name = "spi",
|
||||
|
||||
.base_reg = REG_SPI_CLK_DIV_SEL,
|
||||
|
||||
.base_value = 400000000,
|
||||
|
||||
.div_bits = 5,
|
||||
.div_shift = 8,
|
||||
.div_val0 = 40,
|
||||
.div_step = 2,
|
||||
},
|
||||
[EN7523_CLK_NPU] = {
|
||||
.id = EN7523_CLK_NPU,
|
||||
.name = "npu",
|
||||
|
||||
.base_reg = REG_NPU_CLK_DIV_SEL,
|
||||
.base_bits = 2,
|
||||
.base_shift = 8,
|
||||
.base_values = npu_base,
|
||||
.n_base_values = ARRAY_SIZE(npu_base),
|
||||
|
||||
.div_bits = 3,
|
||||
.div_shift = 0,
|
||||
.div_step = 1,
|
||||
.div_offset = 1,
|
||||
},
|
||||
[EN7523_CLK_CRYPTO] = {
|
||||
.id = EN7523_CLK_CRYPTO,
|
||||
.name = "crypto",
|
||||
|
||||
.base_reg = REG_CRYPTO_CLKSRC,
|
||||
.base_bits = 1,
|
||||
.base_shift = 0,
|
||||
.base_values = emi_base,
|
||||
.n_base_values = ARRAY_SIZE(emi_base),
|
||||
}
|
||||
};
|
||||
|
||||
static const struct airoha_clk_desc en7581_base_clks[EN7581_MAX_CLKS] = {
|
||||
[EN7523_CLK_GSW] = {
|
||||
.id = EN7523_CLK_GSW,
|
||||
@@ -400,14 +507,8 @@ const struct clk_ops airoha_clk_ops = {
|
||||
static int airoha_clk_probe(struct udevice *dev)
|
||||
{
|
||||
struct airoha_clk_priv *priv = dev_get_priv(dev);
|
||||
ofnode chip_scu_node;
|
||||
|
||||
chip_scu_node = ofnode_by_compatible(ofnode_null(),
|
||||
"airoha,en7581-chip-scu");
|
||||
if (!ofnode_valid(chip_scu_node))
|
||||
return -EINVAL;
|
||||
|
||||
priv->chip_scu_map = syscon_node_to_regmap(chip_scu_node);
|
||||
priv->chip_scu_map = airoha_get_chip_scu_regmap();
|
||||
if (IS_ERR(priv->chip_scu_map))
|
||||
return PTR_ERR(priv->chip_scu_map);
|
||||
|
||||
@@ -431,12 +532,20 @@ static int airoha_clk_bind(struct udevice *dev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct airoha_clk_soc_data en7523_data = {
|
||||
.num_clocks = ARRAY_SIZE(en7523_base_clks),
|
||||
.descs = en7523_base_clks,
|
||||
};
|
||||
|
||||
static const struct airoha_clk_soc_data en7581_data = {
|
||||
.num_clocks = ARRAY_SIZE(en7581_base_clks),
|
||||
.descs = en7581_base_clks,
|
||||
};
|
||||
|
||||
static const struct udevice_id airoha_clk_ids[] = {
|
||||
{ .compatible = "airoha,en7523-scu",
|
||||
.data = (ulong)&en7523_data,
|
||||
},
|
||||
{ .compatible = "airoha,en7581-scu",
|
||||
.data = (ulong)&en7581_data,
|
||||
},
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <linux/io.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/time.h>
|
||||
#include <asm/arch/scu-regmap.h>
|
||||
|
||||
#define AIROHA_MAX_NUM_GDM_PORTS 1
|
||||
#define AIROHA_MAX_NUM_QDMA 1
|
||||
@@ -312,6 +313,25 @@ struct airoha_eth {
|
||||
struct airoha_gdm_port *ports[AIROHA_MAX_NUM_GDM_PORTS];
|
||||
};
|
||||
|
||||
struct airoha_eth_soc_data {
|
||||
int num_xsi_rsts;
|
||||
const char * const *xsi_rsts_names;
|
||||
const char *switch_compatible;
|
||||
};
|
||||
|
||||
static const char * const en7523_xsi_rsts_names[] = {
|
||||
"hsi0-mac",
|
||||
"hsi1-mac",
|
||||
"hsi-mac",
|
||||
};
|
||||
|
||||
static const char * const en7581_xsi_rsts_names[] = {
|
||||
"hsi0-mac",
|
||||
"hsi1-mac",
|
||||
"hsi-mac",
|
||||
"xfp-mac",
|
||||
};
|
||||
|
||||
static u32 airoha_rr(void __iomem *base, u32 offset)
|
||||
{
|
||||
return readl(base + offset);
|
||||
@@ -678,10 +698,12 @@ static int airoha_hw_init(struct udevice *dev,
|
||||
|
||||
static int airoha_switch_init(struct udevice *dev, struct airoha_eth *eth)
|
||||
{
|
||||
struct airoha_eth_soc_data *data = (void *)dev_get_driver_data(dev);
|
||||
ofnode switch_node;
|
||||
fdt_addr_t addr;
|
||||
|
||||
switch_node = ofnode_by_compatible(ofnode_null(), "airoha,en7581-switch");
|
||||
switch_node = ofnode_by_compatible(ofnode_null(),
|
||||
data->switch_compatible);
|
||||
if (!ofnode_valid(switch_node))
|
||||
return -EINVAL;
|
||||
|
||||
@@ -718,16 +740,12 @@ static int airoha_switch_init(struct udevice *dev, struct airoha_eth *eth)
|
||||
|
||||
static int airoha_eth_probe(struct udevice *dev)
|
||||
{
|
||||
struct airoha_eth_soc_data *data = (void *)dev_get_driver_data(dev);
|
||||
struct airoha_eth *eth = dev_get_priv(dev);
|
||||
struct regmap *scu_regmap;
|
||||
ofnode scu_node;
|
||||
int ret;
|
||||
int i, ret;
|
||||
|
||||
scu_node = ofnode_by_compatible(ofnode_null(), "airoha,en7581-scu");
|
||||
if (!ofnode_valid(scu_node))
|
||||
return -EINVAL;
|
||||
|
||||
scu_regmap = syscon_node_to_regmap(scu_node);
|
||||
scu_regmap = airoha_get_scu_regmap();
|
||||
if (IS_ERR(scu_regmap))
|
||||
return PTR_ERR(scu_regmap);
|
||||
|
||||
@@ -747,11 +765,11 @@ static int airoha_eth_probe(struct udevice *dev)
|
||||
return -ENOMEM;
|
||||
eth->rsts.count = AIROHA_MAX_NUM_RSTS;
|
||||
|
||||
eth->xsi_rsts.resets = devm_kcalloc(dev, AIROHA_MAX_NUM_XSI_RSTS,
|
||||
eth->xsi_rsts.resets = devm_kcalloc(dev, data->num_xsi_rsts,
|
||||
sizeof(struct reset_ctl), GFP_KERNEL);
|
||||
if (!eth->xsi_rsts.resets)
|
||||
return -ENOMEM;
|
||||
eth->xsi_rsts.count = AIROHA_MAX_NUM_XSI_RSTS;
|
||||
eth->xsi_rsts.count = data->num_xsi_rsts;
|
||||
|
||||
ret = reset_get_by_name(dev, "fe", ð->rsts.resets[0]);
|
||||
if (ret)
|
||||
@@ -765,21 +783,12 @@ static int airoha_eth_probe(struct udevice *dev)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = reset_get_by_name(dev, "hsi0-mac", ð->xsi_rsts.resets[0]);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = reset_get_by_name(dev, "hsi1-mac", ð->xsi_rsts.resets[1]);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = reset_get_by_name(dev, "hsi-mac", ð->xsi_rsts.resets[2]);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = reset_get_by_name(dev, "xfp-mac", ð->xsi_rsts.resets[3]);
|
||||
if (ret)
|
||||
return ret;
|
||||
for (i = 0; i < data->num_xsi_rsts; i++) {
|
||||
ret = reset_get_by_name(dev, data->xsi_rsts_names[i],
|
||||
ð->xsi_rsts.resets[i]);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = airoha_hw_init(dev, eth);
|
||||
if (ret)
|
||||
@@ -973,8 +982,25 @@ static int arht_eth_write_hwaddr(struct udevice *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct airoha_eth_soc_data en7523_data = {
|
||||
.xsi_rsts_names = en7523_xsi_rsts_names,
|
||||
.num_xsi_rsts = ARRAY_SIZE(en7523_xsi_rsts_names),
|
||||
.switch_compatible = "airoha,en7523-switch",
|
||||
};
|
||||
|
||||
static const struct airoha_eth_soc_data en7581_data = {
|
||||
.xsi_rsts_names = en7581_xsi_rsts_names,
|
||||
.num_xsi_rsts = ARRAY_SIZE(en7581_xsi_rsts_names),
|
||||
.switch_compatible = "airoha,en7581-switch",
|
||||
};
|
||||
|
||||
static const struct udevice_id airoha_eth_ids[] = {
|
||||
{ .compatible = "airoha,en7581-eth" },
|
||||
{ .compatible = "airoha,en7523-eth",
|
||||
.data = (ulong)&en7523_data,
|
||||
},
|
||||
{ .compatible = "airoha,en7581-eth",
|
||||
.data = (ulong)&en7581_data,
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
|
||||
@@ -10,7 +10,10 @@
|
||||
#include <dm.h>
|
||||
#include <linux/io.h>
|
||||
#include <reset-uclass.h>
|
||||
#include <regmap.h>
|
||||
#include <asm/arch/scu-regmap.h>
|
||||
|
||||
#include <dt-bindings/reset/airoha,en7523-reset.h>
|
||||
#include <dt-bindings/reset/airoha,en7581-reset.h>
|
||||
|
||||
#define RST_NR_PER_BANK 32
|
||||
@@ -21,7 +24,8 @@
|
||||
struct airoha_reset_priv {
|
||||
const u16 *bank_ofs;
|
||||
const u16 *idx_map;
|
||||
void __iomem *base;
|
||||
int num_rsts;
|
||||
struct regmap *map;
|
||||
};
|
||||
|
||||
static const u16 en7581_rst_ofs[] = {
|
||||
@@ -29,6 +33,53 @@ static const u16 en7581_rst_ofs[] = {
|
||||
REG_RESET_CONTROL1,
|
||||
};
|
||||
|
||||
static const u16 en7523_rst_map[] = {
|
||||
/* RST_CTRL2 */
|
||||
[EN7523_XPON_PHY_RST] = 0,
|
||||
[EN7523_XSI_MAC_RST] = 7,
|
||||
[EN7523_XSI_PHY_RST] = 8,
|
||||
[EN7523_NPU_RST] = 9,
|
||||
[EN7523_I2S_RST] = 10,
|
||||
[EN7523_TRNG_RST] = 11,
|
||||
[EN7523_TRNG_MSTART_RST] = 12,
|
||||
[EN7523_DUAL_HSI0_RST] = 13,
|
||||
[EN7523_DUAL_HSI1_RST] = 14,
|
||||
[EN7523_HSI_RST] = 15,
|
||||
[EN7523_DUAL_HSI0_MAC_RST] = 16,
|
||||
[EN7523_DUAL_HSI1_MAC_RST] = 17,
|
||||
[EN7523_HSI_MAC_RST] = 18,
|
||||
[EN7523_WDMA_RST] = 19,
|
||||
[EN7523_WOE0_RST] = 20,
|
||||
[EN7523_WOE1_RST] = 21,
|
||||
[EN7523_HSDMA_RST] = 22,
|
||||
[EN7523_I2C2RBUS_RST] = 23,
|
||||
[EN7523_TDMA_RST] = 24,
|
||||
/* RST_CTRL1 */
|
||||
[EN7523_PCM1_ZSI_ISI_RST] = RST_NR_PER_BANK + 0,
|
||||
[EN7523_FE_PDMA_RST] = RST_NR_PER_BANK + 1,
|
||||
[EN7523_FE_QDMA_RST] = RST_NR_PER_BANK + 2,
|
||||
[EN7523_PCM_SPIWP_RST] = RST_NR_PER_BANK + 4,
|
||||
[EN7523_CRYPTO_RST] = RST_NR_PER_BANK + 6,
|
||||
[EN7523_TIMER_RST] = RST_NR_PER_BANK + 8,
|
||||
[EN7523_PCM1_RST] = RST_NR_PER_BANK + 11,
|
||||
[EN7523_UART_RST] = RST_NR_PER_BANK + 12,
|
||||
[EN7523_GPIO_RST] = RST_NR_PER_BANK + 13,
|
||||
[EN7523_GDMA_RST] = RST_NR_PER_BANK + 14,
|
||||
[EN7523_I2C_MASTER_RST] = RST_NR_PER_BANK + 16,
|
||||
[EN7523_PCM2_ZSI_ISI_RST] = RST_NR_PER_BANK + 17,
|
||||
[EN7523_SFC_RST] = RST_NR_PER_BANK + 18,
|
||||
[EN7523_UART2_RST] = RST_NR_PER_BANK + 19,
|
||||
[EN7523_GDMP_RST] = RST_NR_PER_BANK + 20,
|
||||
[EN7523_FE_RST] = RST_NR_PER_BANK + 21,
|
||||
[EN7523_USB_HOST_P0_RST] = RST_NR_PER_BANK + 22,
|
||||
[EN7523_GSW_RST] = RST_NR_PER_BANK + 23,
|
||||
[EN7523_SFC2_PCM_RST] = RST_NR_PER_BANK + 25,
|
||||
[EN7523_PCIE0_RST] = RST_NR_PER_BANK + 26,
|
||||
[EN7523_PCIE1_RST] = RST_NR_PER_BANK + 27,
|
||||
[EN7523_PCIE_HB_RST] = RST_NR_PER_BANK + 29,
|
||||
[EN7523_XPON_MAC_RST] = RST_NR_PER_BANK + 31,
|
||||
};
|
||||
|
||||
static const u16 en7581_rst_map[] = {
|
||||
/* RST_CTRL2 */
|
||||
[EN7581_XPON_PHY_RST] = 0,
|
||||
@@ -90,17 +141,11 @@ static const u16 en7581_rst_map[] = {
|
||||
static int airoha_reset_update(struct airoha_reset_priv *priv,
|
||||
unsigned long id, bool assert)
|
||||
{
|
||||
void __iomem *addr = priv->base + priv->bank_ofs[id / RST_NR_PER_BANK];
|
||||
u32 val;
|
||||
u16 offset = priv->bank_ofs[id / RST_NR_PER_BANK];
|
||||
|
||||
val = readl(addr);
|
||||
if (assert)
|
||||
val |= BIT(id % RST_NR_PER_BANK);
|
||||
else
|
||||
val &= ~BIT(id % RST_NR_PER_BANK);
|
||||
writel(val, addr);
|
||||
|
||||
return 0;
|
||||
return regmap_update_bits(priv->map, offset,
|
||||
BIT(id % RST_NR_PER_BANK),
|
||||
assert ? BIT(id % RST_NR_PER_BANK) : 0);
|
||||
}
|
||||
|
||||
static int airoha_reset_assert(struct reset_ctl *reset_ctl)
|
||||
@@ -123,11 +168,16 @@ static int airoha_reset_status(struct reset_ctl *reset_ctl)
|
||||
{
|
||||
struct airoha_reset_priv *priv = dev_get_priv(reset_ctl->dev);
|
||||
int id = reset_ctl->id;
|
||||
void __iomem *addr;
|
||||
u16 offset;
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
addr = priv->base + priv->bank_ofs[id / RST_NR_PER_BANK];
|
||||
offset = priv->bank_ofs[id / RST_NR_PER_BANK];
|
||||
ret = regmap_read(priv->map, offset, &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return !!(readl(addr) & BIT(id % RST_NR_PER_BANK));
|
||||
return !!(val & BIT(id % RST_NR_PER_BANK));
|
||||
}
|
||||
|
||||
static int airoha_reset_xlate(struct reset_ctl *reset_ctl,
|
||||
@@ -135,7 +185,7 @@ static int airoha_reset_xlate(struct reset_ctl *reset_ctl,
|
||||
{
|
||||
struct airoha_reset_priv *priv = dev_get_priv(reset_ctl->dev);
|
||||
|
||||
if (args->args[0] >= ARRAY_SIZE(en7581_rst_map))
|
||||
if (args->args[0] >= priv->num_rsts)
|
||||
return -EINVAL;
|
||||
|
||||
reset_ctl->id = priv->idx_map[args->args[0]];
|
||||
@@ -150,20 +200,36 @@ static struct reset_ops airoha_reset_ops = {
|
||||
.rst_status = airoha_reset_status,
|
||||
};
|
||||
|
||||
static int airoha_reset_probe(struct udevice *dev)
|
||||
static int reset_init(struct udevice *dev, const u16 *rst_map, int num_rsts)
|
||||
{
|
||||
struct airoha_reset_priv *priv = dev_get_priv(dev);
|
||||
|
||||
priv->base = dev_remap_addr(dev);
|
||||
if (!priv->base)
|
||||
return -ENOMEM;
|
||||
priv->map = airoha_get_scu_regmap();
|
||||
if (IS_ERR(priv->map))
|
||||
return PTR_ERR(priv->map);
|
||||
|
||||
priv->bank_ofs = en7581_rst_ofs;
|
||||
priv->idx_map = en7581_rst_map;
|
||||
priv->idx_map = rst_map;
|
||||
priv->num_rsts = num_rsts;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int airoha_reset_probe(struct udevice *dev)
|
||||
{
|
||||
if (ofnode_device_is_compatible(dev_ofnode(dev),
|
||||
"airoha,en7523-scu"))
|
||||
return reset_init(dev, en7523_rst_map,
|
||||
ARRAY_SIZE(en7523_rst_map));
|
||||
|
||||
if (ofnode_device_is_compatible(dev_ofnode(dev),
|
||||
"airoha,en7581-scu"))
|
||||
return reset_init(dev, en7581_rst_map,
|
||||
ARRAY_SIZE(en7581_rst_map));
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
U_BOOT_DRIVER(airoha_reset) = {
|
||||
.name = "airoha-reset",
|
||||
.id = UCLASS_RESET,
|
||||
|
||||
21
include/configs/en7523.h
Normal file
21
include/configs/en7523.h
Normal file
@@ -0,0 +1,21 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Configuration for Airoha EN7523
|
||||
*
|
||||
* Author: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
|
||||
*/
|
||||
|
||||
#ifndef __EN7523_H
|
||||
#define __EN7523_H
|
||||
|
||||
#include <linux/sizes.h>
|
||||
|
||||
#define CFG_SYS_UBOOT_BASE CONFIG_TEXT_BASE
|
||||
|
||||
#define CFG_SYS_INIT_RAM_ADDR CONFIG_TEXT_BASE
|
||||
#define CFG_SYS_INIT_RAM_SIZE SZ_2M
|
||||
|
||||
/* DRAM */
|
||||
#define CFG_SYS_SDRAM_BASE 0x80000000
|
||||
|
||||
#endif
|
||||
61
include/dt-bindings/reset/airoha,en7523-reset.h
Normal file
61
include/dt-bindings/reset/airoha,en7523-reset.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */
|
||||
/*
|
||||
* Copyright (C) 2024 iopsys Software Solutions AB.
|
||||
* Copyright (C) 2025 Genexis AB.
|
||||
*
|
||||
* Author: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
|
||||
*
|
||||
* based on
|
||||
* dts/upstream/include/dt-bindings/reset/airoha,en7581-reset.h
|
||||
* by Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
*/
|
||||
|
||||
#ifndef __DT_BINDINGS_RESET_CONTROLLER_AIROHA_EN7523_H_
|
||||
#define __DT_BINDINGS_RESET_CONTROLLER_AIROHA_EN7523_H_
|
||||
|
||||
/* RST_CTRL2 */
|
||||
#define EN7523_XPON_PHY_RST 0
|
||||
#define EN7523_XSI_MAC_RST 1
|
||||
#define EN7523_XSI_PHY_RST 2
|
||||
#define EN7523_NPU_RST 3
|
||||
#define EN7523_I2S_RST 4
|
||||
#define EN7523_TRNG_RST 5
|
||||
#define EN7523_TRNG_MSTART_RST 6
|
||||
#define EN7523_DUAL_HSI0_RST 7
|
||||
#define EN7523_DUAL_HSI1_RST 8
|
||||
#define EN7523_HSI_RST 9
|
||||
#define EN7523_DUAL_HSI0_MAC_RST 10
|
||||
#define EN7523_DUAL_HSI1_MAC_RST 11
|
||||
#define EN7523_HSI_MAC_RST 12
|
||||
#define EN7523_WDMA_RST 13
|
||||
#define EN7523_WOE0_RST 14
|
||||
#define EN7523_WOE1_RST 15
|
||||
#define EN7523_HSDMA_RST 16
|
||||
#define EN7523_I2C2RBUS_RST 17
|
||||
#define EN7523_TDMA_RST 18
|
||||
/* RST_CTRL1 */
|
||||
#define EN7523_PCM1_ZSI_ISI_RST 19
|
||||
#define EN7523_FE_PDMA_RST 20
|
||||
#define EN7523_FE_QDMA_RST 21
|
||||
#define EN7523_PCM_SPIWP_RST 22
|
||||
#define EN7523_CRYPTO_RST 23
|
||||
#define EN7523_TIMER_RST 24
|
||||
#define EN7523_PCM1_RST 25
|
||||
#define EN7523_UART_RST 26
|
||||
#define EN7523_GPIO_RST 27
|
||||
#define EN7523_GDMA_RST 28
|
||||
#define EN7523_I2C_MASTER_RST 29
|
||||
#define EN7523_PCM2_ZSI_ISI_RST 30
|
||||
#define EN7523_SFC_RST 31
|
||||
#define EN7523_UART2_RST 32
|
||||
#define EN7523_GDMP_RST 33
|
||||
#define EN7523_FE_RST 34
|
||||
#define EN7523_USB_HOST_P0_RST 35
|
||||
#define EN7523_GSW_RST 36
|
||||
#define EN7523_SFC2_PCM_RST 37
|
||||
#define EN7523_PCIE0_RST 38
|
||||
#define EN7523_PCIE1_RST 39
|
||||
#define EN7523_PCIE_HB_RST 40
|
||||
#define EN7523_XPON_MAC_RST 41
|
||||
|
||||
#endif /* __DT_BINDINGS_RESET_CONTROLLER_AIROHA_EN7523_H_ */
|
||||
Reference in New Issue
Block a user