diff --git a/arch/arm/dts/en7523-evb-u-boot.dtsi b/arch/arm/dts/en7523-evb-u-boot.dtsi new file mode 100644 index 00000000000..c109d6794fb --- /dev/null +++ b/arch/arm/dts/en7523-evb-u-boot.dtsi @@ -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" diff --git a/arch/arm/dts/en7523-u-boot.dtsi b/arch/arm/dts/en7523-u-boot.dtsi new file mode 100644 index 00000000000..90838c00a85 --- /dev/null +++ b/arch/arm/dts/en7523-u-boot.dtsi @@ -0,0 +1,70 @@ +// SPDX-License-Identifier: GPL-2.0+ + +#include + +/ { + 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; +}; diff --git a/arch/arm/include/asm/arch-airoha/scu-regmap.h b/arch/arm/include/asm/arch-airoha/scu-regmap.h new file mode 100644 index 00000000000..31fc23d8c4d --- /dev/null +++ b/arch/arm/include/asm/arch-airoha/scu-regmap.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Author: Mikhail Kshevetskiy + */ +#ifndef __AIROHA_SCU_REGMAP__ +#define __AIROHA_SCU_REGMAP__ + +#include + +struct regmap *airoha_get_scu_regmap(void); +struct regmap *airoha_get_chip_scu_regmap(void); + +#endif diff --git a/arch/arm/include/asm/arch-an7581 b/arch/arm/include/asm/arch-an7581 new file mode 120000 index 00000000000..d2317ed3bc3 --- /dev/null +++ b/arch/arm/include/asm/arch-an7581 @@ -0,0 +1 @@ +arch-airoha \ No newline at end of file diff --git a/arch/arm/include/asm/arch-en7523 b/arch/arm/include/asm/arch-en7523 new file mode 120000 index 00000000000..d2317ed3bc3 --- /dev/null +++ b/arch/arm/include/asm/arch-en7523 @@ -0,0 +1 @@ +arch-airoha \ No newline at end of file diff --git a/arch/arm/mach-airoha/Kconfig b/arch/arm/mach-airoha/Kconfig index be3562ae3ff..b9cd0a413e1 100644 --- a/arch/arm/mach-airoha/Kconfig +++ b/arch/arm/mach-airoha/Kconfig @@ -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 diff --git a/arch/arm/mach-airoha/Makefile b/arch/arm/mach-airoha/Makefile index 215a300373b..91395b8a850 100644 --- a/arch/arm/mach-airoha/Makefile +++ b/arch/arm/mach-airoha/Makefile @@ -2,4 +2,5 @@ obj-y += cpu.o +obj-$(CONFIG_TARGET_EN7523) += en7523/ obj-$(CONFIG_TARGET_AN7581) += an7581/ diff --git a/arch/arm/mach-airoha/an7581/Makefile b/arch/arm/mach-airoha/an7581/Makefile index 886ab7e4eb9..51f978aa101 100644 --- a/arch/arm/mach-airoha/an7581/Makefile +++ b/arch/arm/mach-airoha/an7581/Makefile @@ -1,3 +1,4 @@ # SPDX-License-Identifier: GPL-2.0 obj-y += init.o +obj-y += scu-regmap.o diff --git a/arch/arm/mach-airoha/an7581/scu-regmap.c b/arch/arm/mach-airoha/an7581/scu-regmap.c new file mode 100644 index 00000000000..7beeaecccc1 --- /dev/null +++ b/arch/arm/mach-airoha/an7581/scu-regmap.c @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Author: Mikhail Kshevetskiy + */ + +#include +#include +#include + +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); +} diff --git a/arch/arm/mach-airoha/en7523/Makefile b/arch/arm/mach-airoha/en7523/Makefile new file mode 100644 index 00000000000..51f978aa101 --- /dev/null +++ b/arch/arm/mach-airoha/en7523/Makefile @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-y += init.o +obj-y += scu-regmap.o diff --git a/arch/arm/mach-airoha/en7523/init.c b/arch/arm/mach-airoha/en7523/init.c new file mode 100644 index 00000000000..c1c1eeabdf5 --- /dev/null +++ b/arch/arm/mach-airoha/en7523/init.c @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Author: Mikhail Kshevetskiy + */ +#include +#include +#include +#include +#include + +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 */ + } +} diff --git a/arch/arm/mach-airoha/en7523/scu-regmap.c b/arch/arm/mach-airoha/en7523/scu-regmap.c new file mode 100644 index 00000000000..1e201cb060c --- /dev/null +++ b/arch/arm/mach-airoha/en7523/scu-regmap.c @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Author: Mikhail Kshevetskiy + */ + +#include +#include +#include + +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); +} diff --git a/board/airoha/en7523/MAINTAINERS b/board/airoha/en7523/MAINTAINERS new file mode 100644 index 00000000000..c0d89bb0fe7 --- /dev/null +++ b/board/airoha/en7523/MAINTAINERS @@ -0,0 +1,4 @@ +EN7523 +M: Mikhail Kshevetskiy +S: Maintained +N: en7523 diff --git a/board/airoha/en7523/Makefile b/board/airoha/en7523/Makefile new file mode 100644 index 00000000000..c6629486f21 --- /dev/null +++ b/board/airoha/en7523/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-y += en7523_rfb.o diff --git a/board/airoha/en7523/en7523_rfb.c b/board/airoha/en7523/en7523_rfb.c new file mode 100644 index 00000000000..aa73679d929 --- /dev/null +++ b/board/airoha/en7523/en7523_rfb.c @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Author: Christian Marangi + */ + +#include + +DECLARE_GLOBAL_DATA_PTR; + +int board_init(void) +{ + /* address of boot parameters */ + gd->bd->bi_boot_params = CFG_SYS_SDRAM_BASE + 0x100; + + return 0; +} diff --git a/configs/an7581_evb_defconfig b/configs/an7581_evb_defconfig index baa3fc3f5de..73af30cd693 100644 --- a/configs/an7581_evb_defconfig +++ b/configs/an7581_evb_defconfig @@ -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 diff --git a/configs/en7523_evb_defconfig b/configs/en7523_evb_defconfig new file mode 100644 index 00000000000..76e829a8e99 --- /dev/null +++ b/configs/en7523_evb_defconfig @@ -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 diff --git a/drivers/clk/airoha/clk-airoha.c b/drivers/clk/airoha/clk-airoha.c index 1b2c4c98de5..49dbca82135 100644 --- a/drivers/clk/airoha/clk-airoha.c +++ b/drivers/clk/airoha/clk-airoha.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include @@ -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, }, diff --git a/drivers/net/airoha_eth.c b/drivers/net/airoha_eth.c index 19c3d60044c..3234d875887 100644 --- a/drivers/net/airoha_eth.c +++ b/drivers/net/airoha_eth.c @@ -21,6 +21,7 @@ #include #include #include +#include #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, + }, { } }; diff --git a/drivers/reset/reset-airoha.c b/drivers/reset/reset-airoha.c index e878af6167c..ef8c47a067b 100644 --- a/drivers/reset/reset-airoha.c +++ b/drivers/reset/reset-airoha.c @@ -10,7 +10,10 @@ #include #include #include +#include +#include +#include #include #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, diff --git a/include/configs/en7523.h b/include/configs/en7523.h new file mode 100644 index 00000000000..2d27b3626ae --- /dev/null +++ b/include/configs/en7523.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Configuration for Airoha EN7523 + * + * Author: Mikhail Kshevetskiy + */ + +#ifndef __EN7523_H +#define __EN7523_H + +#include + +#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 diff --git a/include/dt-bindings/reset/airoha,en7523-reset.h b/include/dt-bindings/reset/airoha,en7523-reset.h new file mode 100644 index 00000000000..bb0a28673d6 --- /dev/null +++ b/include/dt-bindings/reset/airoha,en7523-reset.h @@ -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 + * + * based on + * dts/upstream/include/dt-bindings/reset/airoha,en7581-reset.h + * by Lorenzo Bianconi + */ + +#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_ */