diff options
Diffstat (limited to 'arch')
81 files changed, 2966 insertions, 952 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 531b081de9..d812685c98 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1135,7 +1135,6 @@ config ARCH_SUNXI select DM_MMC if MMC select DM_SCSI if SCSI select DM_SERIAL - select GPIO_EXTRA_HEADER select OF_BOARD_SETUP select OF_CONTROL select OF_SEPARATE @@ -1159,6 +1158,8 @@ config ARCH_SUNXI imply CMD_GPT imply CMD_UBI if MTD_RAW_NAND imply DISTRO_DEFAULTS + imply DM_REGULATOR + imply DM_REGULATOR_FIXED imply FAT_WRITE imply FIT imply OF_LIBFDT_OVERLAY diff --git a/arch/arm/cpu/armv7/Kconfig b/arch/arm/cpu/armv7/Kconfig index f015d133cb..4eb34b7b44 100644 --- a/arch/arm/cpu/armv7/Kconfig +++ b/arch/arm/cpu/armv7/Kconfig @@ -61,8 +61,9 @@ config ARMV7_SECURE_MAX_SIZE config ARM_GIC_BASE_ADDRESS hex depends on ARMV7_NONSEC - depends on ARCH_EXYNOS5 + depends on ARCH_EXYNOS5 || MACH_SUN8I_R528 default 0x10480000 if ARCH_EXYNOS5 + default 0x03020000 if MACH_SUN8I_R528 help Override the GIC base address if the Arm Cortex defined CBAR/PERIPHBASE system register holds the wrong value. diff --git a/arch/arm/cpu/armv7/sunxi/psci.c b/arch/arm/cpu/armv7/sunxi/psci.c index e1d3638b5c..5cb8cfa6cf 100644 --- a/arch/arm/cpu/armv7/sunxi/psci.c +++ b/arch/arm/cpu/armv7/sunxi/psci.c @@ -11,8 +11,6 @@ #include <asm/cache.h> #include <asm/arch/cpu.h> -#include <asm/arch/cpucfg.h> -#include <asm/arch/prcm.h> #include <asm/armv7.h> #include <asm/gic.h> #include <asm/io.h> @@ -28,6 +26,17 @@ #define GICC_BASE (SUNXI_GIC400_BASE + GIC_CPU_OFFSET_A15) /* + * Offsets into the CPUCFG block applicable to most SUNXIs. + */ +#define SUNXI_CPU_RST(cpu) (0x40 + (cpu) * 0x40 + 0x0) +#define SUNXI_CPU_STATUS(cpu) (0x40 + (cpu) * 0x40 + 0x8) +#define SUNXI_GEN_CTRL (0x184) +#define SUNXI_PRIV0 (0x1a4) +#define SUN7I_CPU1_PWR_CLAMP (0x1b0) +#define SUN7I_CPU1_PWROFF (0x1b4) +#define SUNXI_DBG_CTRL1 (0x1e4) + +/* * R40 is different from other single cluster SoCs. * * The power clamps are located in the unused space after the per-core @@ -38,6 +47,24 @@ #define SUN8I_R40_PWR_CLAMP(cpu) (0x120 + (cpu) * 0x4) #define SUN8I_R40_SRAMC_SOFT_ENTRY_REG0 (0xbc) +/* + * R528 is also different, as it has both cores powered up (but held in reset + * state) after the SoC is reset. Like the R40, it uses a "soft" entry point + * address register, but unlike the R40, it uses a newer "CPUX" block to manage + * CPU state, rather than the older CPUCFG system. + */ +#define SUN8I_R528_SOFT_ENTRY (0x1c8) +#define SUN8I_R528_C0_RST_CTRL (0x0000) +#define SUN8I_R528_C0_CTRL_REG0 (0x0010) +#define SUN8I_R528_C0_CPU_STATUS (0x0080) + +#define SUN8I_R528_C0_STATUS_STANDBYWFI (16) + +/* Only newer cores have this additional IP block. */ +#ifndef SUNXI_R_CPUCFG_BASE +#define SUNXI_R_CPUCFG_BASE 0 +#endif + static void __secure cp15_write_cntp_tval(u32 tval) { asm volatile ("mcr p15, 0, %0, c14, c2, 0" : : "r" (tval)); @@ -76,11 +103,8 @@ static void __secure __mdelay(u32 ms) isb(); } -static void __secure clamp_release(u32 __maybe_unused *clamp) +static void __secure clamp_release(u32 *clamp) { -#if defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN7I) || \ - defined(CONFIG_MACH_SUN8I_H3) || \ - defined(CONFIG_MACH_SUN8I_R40) u32 tmp = 0x1ff; do { tmp >>= 1; @@ -88,24 +112,54 @@ static void __secure clamp_release(u32 __maybe_unused *clamp) } while (tmp); __mdelay(10); -#endif } -static void __secure clamp_set(u32 __maybe_unused *clamp) +static void __secure clamp_set(u32 *clamp) { -#if defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN7I) || \ - defined(CONFIG_MACH_SUN8I_H3) || \ - defined(CONFIG_MACH_SUN8I_R40) writel(0xff, clamp); -#endif } -static void __secure sunxi_power_switch(u32 *clamp, u32 *pwroff, bool on, - int cpu) +static void __secure sunxi_cpu_set_entry(int __always_unused cpu, void *entry) +{ + if (IS_ENABLED(CONFIG_MACH_SUN8I_R40)) { + writel((u32)entry, + SUNXI_SRAMC_BASE + SUN8I_R40_SRAMC_SOFT_ENTRY_REG0); + } else if (IS_ENABLED(CONFIG_MACH_SUN8I_R528)) { + writel((u32)entry, + SUNXI_R_CPUCFG_BASE + SUN8I_R528_SOFT_ENTRY); + } else { + writel((u32)entry, SUNXI_CPUCFG_BASE + SUNXI_PRIV0); + } +} + +static void __secure sunxi_cpu_set_power(int cpu, bool on) { + u32 *clamp = NULL; + u32 *pwroff; + + /* sun7i (A20) is different from other single cluster SoCs */ + if (IS_ENABLED(CONFIG_MACH_SUN7I)) { + clamp = (void *)SUNXI_CPUCFG_BASE + SUN7I_CPU1_PWR_CLAMP; + pwroff = (void *)SUNXI_CPUCFG_BASE + SUN7I_CPU1_PWROFF; + cpu = 0; + } else if (IS_ENABLED(CONFIG_MACH_SUN8I_R40)) { + clamp = (void *)SUNXI_CPUCFG_BASE + SUN8I_R40_PWR_CLAMP(cpu); + pwroff = (void *)SUNXI_CPUCFG_BASE + SUN8I_R40_PWROFF; + } else if (IS_ENABLED(CONFIG_MACH_SUN8I_R528)) { + /* R528 leaves both cores powered up, manages them via reset */ + return; + } else { + if (IS_ENABLED(CONFIG_MACH_SUN6I) || + IS_ENABLED(CONFIG_MACH_SUN8I_H3)) + clamp = (void *)SUNXI_PRCM_BASE + 0x140 + cpu * 0x4; + + pwroff = (void *)SUNXI_PRCM_BASE + 0x100; + } + if (on) { /* Release power clamp */ - clamp_release(clamp); + if (clamp) + clamp_release(clamp); /* Clear power gating */ clrbits_le32(pwroff, BIT(cpu)); @@ -114,82 +168,80 @@ static void __secure sunxi_power_switch(u32 *clamp, u32 *pwroff, bool on, setbits_le32(pwroff, BIT(cpu)); /* Activate power clamp */ - clamp_set(clamp); + if (clamp) + clamp_set(clamp); } } -#ifdef CONFIG_MACH_SUN8I_R40 -/* secondary core entry address is programmed differently on R40 */ -static void __secure sunxi_set_entry_address(void *entry) +static void __secure sunxi_cpu_set_reset(int cpu, bool reset) { - writel((u32)entry, - SUNXI_SRAMC_BASE + SUN8I_R40_SRAMC_SOFT_ENTRY_REG0); -} -#else -static void __secure sunxi_set_entry_address(void *entry) -{ - struct sunxi_cpucfg_reg *cpucfg = - (struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE; + if (IS_ENABLED(CONFIG_MACH_SUN8I_R528)) { + if (reset) + clrbits_le32(SUNXI_CPUCFG_BASE + SUN8I_R528_C0_RST_CTRL, + BIT(cpu)); + else + setbits_le32(SUNXI_CPUCFG_BASE + SUN8I_R528_C0_RST_CTRL, + BIT(cpu)); + + return; + } - writel((u32)entry, &cpucfg->priv0); + writel(reset ? 0b00 : 0b11, SUNXI_CPUCFG_BASE + SUNXI_CPU_RST(cpu)); } -#endif -#ifdef CONFIG_MACH_SUN7I -/* sun7i (A20) is different from other single cluster SoCs */ -static void __secure sunxi_cpu_set_power(int __always_unused cpu, bool on) +static void __secure sunxi_cpu_set_locking(int cpu, bool lock) { - struct sunxi_cpucfg_reg *cpucfg = - (struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE; + if (IS_ENABLED(CONFIG_MACH_SUN8I_R528)) { + /* Not required on R528 */ + return; + } - sunxi_power_switch(&cpucfg->cpu1_pwr_clamp, &cpucfg->cpu1_pwroff, - on, 0); + if (lock) + clrbits_le32(SUNXI_CPUCFG_BASE + SUNXI_DBG_CTRL1, BIT(cpu)); + else + setbits_le32(SUNXI_CPUCFG_BASE + SUNXI_DBG_CTRL1, BIT(cpu)); } -#elif defined CONFIG_MACH_SUN8I_R40 -static void __secure sunxi_cpu_set_power(int cpu, bool on) + +static bool __secure sunxi_cpu_poll_wfi(int cpu) { - struct sunxi_cpucfg_reg *cpucfg = - (struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE; + if (IS_ENABLED(CONFIG_MACH_SUN8I_R528)) { + return !!(readl(SUNXI_CPUCFG_BASE + SUN8I_R528_C0_CPU_STATUS) & + BIT(SUN8I_R528_C0_STATUS_STANDBYWFI + cpu)); + } - sunxi_power_switch((void *)cpucfg + SUN8I_R40_PWR_CLAMP(cpu), - (void *)cpucfg + SUN8I_R40_PWROFF, - on, cpu); + return !!(readl(SUNXI_CPUCFG_BASE + SUNXI_CPU_STATUS(cpu)) & BIT(2)); } -#else /* ! CONFIG_MACH_SUN7I && ! CONFIG_MACH_SUN8I_R40 */ -static void __secure sunxi_cpu_set_power(int cpu, bool on) + +static void __secure sunxi_cpu_invalidate_cache(int cpu) { - struct sunxi_prcm_reg *prcm = - (struct sunxi_prcm_reg *)SUNXI_PRCM_BASE; + if (IS_ENABLED(CONFIG_MACH_SUN8I_R528)) { + clrbits_le32(SUNXI_CPUCFG_BASE + SUN8I_R528_C0_CTRL_REG0, + BIT(cpu)); + return; + } - sunxi_power_switch(&prcm->cpu_pwr_clamp[cpu], &prcm->cpu_pwroff, - on, cpu); + clrbits_le32(SUNXI_CPUCFG_BASE + SUNXI_GEN_CTRL, BIT(cpu)); } -#endif /* CONFIG_MACH_SUN7I */ -void __secure sunxi_cpu_power_off(u32 cpuid) +static void __secure sunxi_cpu_power_off(u32 cpuid) { - struct sunxi_cpucfg_reg *cpucfg = - (struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE; u32 cpu = cpuid & 0x3; /* Wait for the core to enter WFI */ - while (1) { - if (readl(&cpucfg->cpu[cpu].status) & BIT(2)) - break; + while (!sunxi_cpu_poll_wfi(cpu)) __mdelay(1); - } /* Assert reset on target CPU */ - writel(0, &cpucfg->cpu[cpu].rst); + sunxi_cpu_set_reset(cpu, true); /* Lock CPU (Disable external debug access) */ - clrbits_le32(&cpucfg->dbg_ctrl1, BIT(cpu)); + sunxi_cpu_set_locking(cpu, true); /* Power down CPU */ sunxi_cpu_set_power(cpuid, false); - /* Unlock CPU (Disable external debug access) */ - setbits_le32(&cpucfg->dbg_ctrl1, BIT(cpu)); + /* Unlock CPU (Reenable external debug access) */ + sunxi_cpu_set_locking(cpu, false); } static u32 __secure cp15_read_scr(void) @@ -246,33 +298,31 @@ out: int __secure psci_cpu_on(u32 __always_unused unused, u32 mpidr, u32 pc, u32 context_id) { - struct sunxi_cpucfg_reg *cpucfg = - (struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE; u32 cpu = (mpidr & 0x3); /* store target PC and context id */ psci_save(cpu, pc, context_id); /* Set secondary core power on PC */ - sunxi_set_entry_address(&psci_cpu_entry); + sunxi_cpu_set_entry(cpu, &psci_cpu_entry); /* Assert reset on target CPU */ - writel(0, &cpucfg->cpu[cpu].rst); + sunxi_cpu_set_reset(cpu, true); /* Invalidate L1 cache */ - clrbits_le32(&cpucfg->gen_ctrl, BIT(cpu)); + sunxi_cpu_invalidate_cache(cpu); /* Lock CPU (Disable external debug access) */ - clrbits_le32(&cpucfg->dbg_ctrl1, BIT(cpu)); + sunxi_cpu_set_locking(cpu, true); /* Power up target CPU */ sunxi_cpu_set_power(cpu, true); /* De-assert reset on target CPU */ - writel(BIT(1) | BIT(0), &cpucfg->cpu[cpu].rst); + sunxi_cpu_set_reset(cpu, false); - /* Unlock CPU (Disable external debug access) */ - setbits_le32(&cpucfg->dbg_ctrl1, BIT(cpu)); + /* Unlock CPU (Reenable external debug access) */ + sunxi_cpu_set_locking(cpu, false); return ARM_PSCI_RET_SUCCESS; } diff --git a/arch/arm/cpu/armv7/sunxi/sram.c b/arch/arm/cpu/armv7/sunxi/sram.c index 28564c2846..28ff6a1b7c 100644 --- a/arch/arm/cpu/armv7/sunxi/sram.c +++ b/arch/arm/cpu/armv7/sunxi/sram.c @@ -12,6 +12,7 @@ #include <common.h> #include <init.h> #include <asm/io.h> +#include <asm/arch/cpu.h> void sunxi_sram_init(void) { diff --git a/arch/arm/cpu/armv8/fel_utils.S b/arch/arm/cpu/armv8/fel_utils.S index 2fe38a1a04..939869b9ff 100644 --- a/arch/arm/cpu/armv8/fel_utils.S +++ b/arch/arm/cpu/armv8/fel_utils.S @@ -10,6 +10,7 @@ #include <config.h> #include <asm/system.h> #include <linux/linkage.h> +#include <asm/arch/cpu.h> /* * We don't overwrite save_boot_params() here, to save the FEL state upon diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 4569483d5f..96066a2b6b 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -776,6 +776,8 @@ dtb-$(CONFIG_MACH_SUN8I_V3S) += \ sun8i-s3-pinecube.dtb \ sun8i-v3-sl631-imx179.dtb \ sun8i-v3s-licheepi-zero.dtb +dtb-$(CONFIG_MACH_SUN8I_R528) += \ + sun8i-t113s-mangopi-mq-r-t113.dtb dtb-$(CONFIG_MACH_SUN50I_H5) += \ sun50i-h5-bananapi-m2-plus.dtb \ sun50i-h5-emlid-neutis-n5-devboard.dtb \ @@ -1232,6 +1234,9 @@ dtb-$(CONFIG_TARGET_SAMA5D27_SOM1_EK) += \ dtb-$(CONFIG_TARGET_SAMA5D27_WLSOM1_EK) += \ at91-sama5d27_wlsom1_ek.dtb +dtb-$(CONFIG_TARGET_KSTR_SAMA5D27) += \ + at91-kstr-sama5d27.dtb + dtb-$(CONFIG_TARGET_SAMA5D2_ICP) += \ at91-sama5d2_icp.dtb diff --git a/arch/arm/dts/at91-kstr-sama5d27-u-boot.dtsi b/arch/arm/dts/at91-kstr-sama5d27-u-boot.dtsi new file mode 100644 index 0000000000..cec35ab621 --- /dev/null +++ b/arch/arm/dts/at91-kstr-sama5d27-u-boot.dtsi @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: GPL-2.0+ OR X11 +/* + * at91-kstr-sama5d27-u-boot.dtsi - Device Tree Include file w/ U-Boot specific + * properties for Conclusive KSTR-SAMA5D27 board + * + * Copyright (C) 2023 Conclusive Engineering Sp. z o. o. + * + */ + +/ { + chosen { + bootph-all; + }; +}; + +&sdmmc0 { + bootph-all; +}; + +&uart1 { + bootph-all; +}; + +&pinctrl_uart1_default { + bootph-all; +}; + +&pinctrl_macb0_phy_irq { + bootph-all; +}; + +&pinctrl_macb0_rmii { + bootph-all; +}; + +&pinctrl_sdmmc0_cmd_dat_default { + bootph-all; +}; + +&pinctrl_sdmmc0_ck_cd_default { + bootph-all; +}; diff --git a/arch/arm/dts/at91-kstr-sama5d27.dts b/arch/arm/dts/at91-kstr-sama5d27.dts new file mode 100644 index 0000000000..c226a214a5 --- /dev/null +++ b/arch/arm/dts/at91-kstr-sama5d27.dts @@ -0,0 +1,127 @@ +// SPDX-License-Identifier: GPL-2.0+ OR X11 +/* + * at91-kstr-sama5d27.dts - Device Tree file for Conclusive KSTR-SAMA5D27 board + * + * Copyright (C) 2019-2023 Conclusive Engineering Sp. z o. o. + * + */ +/dts-v1/; + +#include "sama5d2.dtsi" +#include "sama5d2-pinfunc.h" +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/interrupt-controller/irq.h> +#include <dt-bindings/mfd/atmel-flexcom.h> + +/ { + model = "Conclusive KSTR-SAMA5D27"; + compatible = "conclusive,kstr-sama5d27", "atmel,sama5d2", "atmel,sama5"; + + chosen { + stdout-path = &uart1; + }; + + aliases { + i2c2 = &i2c6; + }; +}; + +&main_xtal { + clock-frequency = <12000000>; +}; + +&sdmmc0 { + bus-width = <4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sdmmc0_cmd_dat_default &pinctrl_sdmmc0_ck_cd_default>; + status = "okay"; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1_default>; + status = "okay"; +}; + +&macb0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_macb0_rmii &pinctrl_macb0_phy_irq>; + phy-mode = "rmii"; + status = "okay"; + + ethernet-phy@0 { + reg = <0x0>; + reset-gpios = <&pioA 44 GPIO_ACTIVE_LOW>; + }; +}; + +&flx4 { + atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_TWI>; + status = "okay"; +}; + +&i2c6 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_flx4_i2c>; + status = "okay"; + + eeprom: eeprom@50 { + compatible = "microchip,24c32", "atmel,24c32"; + reg = <0x50>; + read-only; + pagesize = <32>; + status = "okay"; + }; +}; + +&pioA { + pinctrl { + pinctrl_uart1_default: uart1_default { + pinmux = <PIN_PD2__URXD1>, + <PIN_PD3__UTXD1>; + bias-disable; + }; + + pinctrl_macb0_phy_irq: macb0_phy_irq { + pinmux = <PIN_PB13__GPIO>; + bias-disable; + }; + + pinctrl_macb0_rmii: macb0_rmii { + pinmux = <PIN_PB14__GTXCK>, + <PIN_PB15__GTXEN>, + <PIN_PB16__GRXDV>, + <PIN_PB17__GRXER>, + <PIN_PB18__GRX0>, + <PIN_PB19__GRX1>, + <PIN_PB20__GTX0>, + <PIN_PB21__GTX1>, + <PIN_PB22__GMDC>, + <PIN_PB23__GMDIO>; + bias-disable; + }; + + pinctrl_sdmmc0_cmd_dat_default: sdmmc0_cmd_dat_default { + pinmux = <PIN_PA1__SDMMC0_CMD>, + <PIN_PA2__SDMMC0_DAT0>, + <PIN_PA3__SDMMC0_DAT1>, + <PIN_PA4__SDMMC0_DAT2>, + <PIN_PA5__SDMMC0_DAT3>; + bias-pull-up; + }; + + pinctrl_sdmmc0_ck_cd_default: sdmmc0_ck_cd_default { + pinmux = <PIN_PA0__SDMMC0_CK>, + <PIN_PA11__SDMMC0_VDDSEL>, + <PIN_PA13__SDMMC0_CD>; + bias-disable; + }; + + pinctrl_flx4_i2c: flx4_i2c { + pinmux = <PIN_PC28__FLEXCOM4_IO0>, + <PIN_PC29__FLEXCOM4_IO1>; + bias-disable; + }; + }; +}; diff --git a/arch/arm/dts/axp209.dtsi b/arch/arm/dts/axp209.dtsi index ca240cd6f6..469d0f7d51 100644 --- a/arch/arm/dts/axp209.dtsi +++ b/arch/arm/dts/axp209.dtsi @@ -48,6 +48,13 @@ * http://dl.linux-sunxi.org/AXP/AXP209%20Datasheet%20v1.0_cn.pdf */ +/ { + pmic-temp { + compatible = "iio-hwmon"; + io-channels = <&axp_adc 4>; /* Internal temperature */ + }; +}; + &axp209 { compatible = "x-powers,axp209"; interrupt-controller; diff --git a/arch/arm/dts/meson-a1.dtsi b/arch/arm/dts/meson-a1.dtsi index e3a42c5b24..648e7f4942 100644 --- a/arch/arm/dts/meson-a1.dtsi +++ b/arch/arm/dts/meson-a1.dtsi @@ -3,9 +3,13 @@ * Copyright (c) 2019 Amlogic, Inc. All rights reserved. */ -#include <dt-bindings/interrupt-controller/irq.h> -#include <dt-bindings/interrupt-controller/arm-gic.h> +#include <dt-bindings/clock/amlogic,a1-pll-clkc.h> +#include <dt-bindings/clock/amlogic,a1-peripherals-clkc.h> #include <dt-bindings/gpio/meson-a1-gpio.h> +#include <dt-bindings/interrupt-controller/arm-gic.h> +#include <dt-bindings/interrupt-controller/irq.h> +#include <dt-bindings/power/meson-a1-power.h> +#include <dt-bindings/reset/amlogic,meson-a1-reset.h> / { compatible = "amlogic,a1"; @@ -37,9 +41,19 @@ l2: l2-cache0 { compatible = "cache"; cache-level = <2>; + cache-unified; }; }; + efuse: efuse { + compatible = "amlogic,meson-gxbb-efuse"; + clocks = <&clkc_periphs CLKID_OTP>; + #address-cells = <1>; + #size-cells = <1>; + secure-monitor = <&sm>; + power-domains = <&pwrc PWRC_OTP_ID>; + }; + psci { compatible = "arm,psci-1.0"; method = "smc"; @@ -65,7 +79,6 @@ pwrc: power-controller { compatible = "amlogic,meson-a1-pwrc"; #power-domain-cells = <1>; - status = "okay"; }; }; @@ -75,6 +88,16 @@ #size-cells = <2>; ranges; + spifc: spi@fd000400 { + compatible = "amlogic,a1-spifc"; + reg = <0x0 0xfd000400 0x0 0x290>; + clocks = <&clkc_periphs CLKID_SPIFC>; + #address-cells = <1>; + #size-cells = <0>; + power-domains = <&pwrc PWRC_SPIFC_ID>; + status = "disabled"; + }; + apb: bus@fe000000 { compatible = "simple-bus"; reg = <0x0 0xfe000000 0x0 0x1000000>; @@ -103,10 +126,200 @@ gpio-ranges = <&periphs_pinctrl 0 0 62>; }; + i2c0_f11_pins: i2c0-f11 { + mux { + groups = "i2c0_sck_f11", + "i2c0_sda_f12"; + function = "i2c0"; + bias-pull-up; + drive-strength-microamp = <3000>; + }; + }; + + i2c0_f9_pins: i2c0-f9 { + mux { + groups = "i2c0_sck_f9", + "i2c0_sda_f10"; + function = "i2c0"; + bias-pull-up; + drive-strength-microamp = <3000>; + }; + }; + + i2c1_x_pins: i2c1-x { + mux { + groups = "i2c1_sck_x", + "i2c1_sda_x"; + function = "i2c1"; + bias-pull-up; + drive-strength-microamp = <3000>; + }; + }; + + i2c1_a_pins: i2c1-a { + mux { + groups = "i2c1_sck_a", + "i2c1_sda_a"; + function = "i2c1"; + bias-pull-up; + drive-strength-microamp = <3000>; + }; + }; + + i2c2_x0_pins: i2c2-x0 { + mux { + groups = "i2c2_sck_x0", + "i2c2_sda_x1"; + function = "i2c2"; + bias-pull-up; + drive-strength-microamp = <3000>; + }; + }; + + i2c2_x15_pins: i2c2-x15 { + mux { + groups = "i2c2_sck_x15", + "i2c2_sda_x16"; + function = "i2c2"; + bias-pull-up; + drive-strength-microamp = <3000>; + }; + }; + + i2c2_a4_pins: i2c2-a4 { + mux { + groups = "i2c2_sck_a4", + "i2c2_sda_a5"; + function = "i2c2"; + bias-pull-up; + drive-strength-microamp = <3000>; + }; + }; + + i2c2_a8_pins: i2c2-a8 { + mux { + groups = "i2c2_sck_a8", + "i2c2_sda_a9"; + function = "i2c2"; + bias-pull-up; + drive-strength-microamp = <3000>; + }; + }; + + i2c3_x_pins: i2c3-x { + mux { + groups = "i2c3_sck_x", + "i2c3_sda_x"; + function = "i2c3"; + bias-pull-up; + drive-strength-microamp = <3000>; + }; + }; + + i2c3_f_pins: i2c3-f { + mux { + groups = "i2c3_sck_f", + "i2c3_sda_f"; + function = "i2c3"; + bias-pull-up; + drive-strength-microamp = <3000>; + }; + }; + + uart_a_pins: uart-a { + mux { + groups = "uart_a_tx", + "uart_a_rx"; + function = "uart_a"; + }; + }; + + uart_a_cts_rts_pins: uart-a-cts-rts { + mux { + groups = "uart_a_cts", + "uart_a_rts"; + function = "uart_a"; + bias-pull-down; + }; + }; + + sdio_pins: sdio { + mux0 { + groups = "sdcard_d0_x", + "sdcard_d1_x", + "sdcard_d2_x", + "sdcard_d3_x", + "sdcard_cmd_x"; + function = "sdcard"; + bias-pull-up; + }; + + mux1 { + groups = "sdcard_clk_x"; + function = "sdcard"; + bias-disable; + }; + }; + + sdio_clk_gate_pins: sdio-clk-gate { + mux { + groups = "sdcard_clk_x"; + function = "sdcard"; + bias-pull-down; + }; + }; + + spifc_pins: spifc { + mux { + groups = "spif_mo", + "spif_mi", + "spif_clk", + "spif_cs", + "spif_hold_n", + "spif_wp_n"; + function = "spif"; + }; + }; + }; + + gpio_intc: interrupt-controller@440 { + compatible = "amlogic,meson-a1-gpio-intc", + "amlogic,meson-gpio-intc"; + reg = <0x0 0x0440 0x0 0x14>; + interrupt-controller; + #interrupt-cells = <2>; + amlogic,channel-interrupts = + <49 50 51 52 53 54 55 56>; + }; + + clkc_periphs: clock-controller@800 { + compatible = "amlogic,a1-peripherals-clkc"; + reg = <0 0x800 0 0x104>; + #clock-cells = <1>; + clocks = <&clkc_pll CLKID_FCLK_DIV2>, + <&clkc_pll CLKID_FCLK_DIV3>, + <&clkc_pll CLKID_FCLK_DIV5>, + <&clkc_pll CLKID_FCLK_DIV7>, + <&clkc_pll CLKID_HIFI_PLL>, + <&xtal>; + clock-names = "fclk_div2", "fclk_div3", + "fclk_div5", "fclk_div7", + "hifi_pll", "xtal"; + }; + + i2c0: i2c@1400 { + compatible = "amlogic,meson-axg-i2c"; + status = "disabled"; + reg = <0x0 0x1400 0x0 0x20>; + interrupts = <GIC_SPI 32 IRQ_TYPE_EDGE_RISING>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clkc_periphs CLKID_I2C_M_A>; + power-domains = <&pwrc PWRC_I2C_ID>; }; uart_AO: serial@1c00 { - compatible = "amlogic,meson-gx-uart", + compatible = "amlogic,meson-a1-uart", "amlogic,meson-ao-uart"; reg = <0x0 0x1c00 0x0 0x18>; interrupts = <GIC_SPI 25 IRQ_TYPE_EDGE_RISING>; @@ -116,7 +329,7 @@ }; uart_AO_B: serial@2000 { - compatible = "amlogic,meson-gx-uart", + compatible = "amlogic,meson-a1-uart", "amlogic,meson-ao-uart"; reg = <0x0 0x2000 0x0 0x18>; interrupts = <GIC_SPI 26 IRQ_TYPE_EDGE_RISING>; @@ -125,9 +338,70 @@ status = "disabled"; }; + saradc: adc@2c00 { + compatible = "amlogic,meson-g12a-saradc", + "amlogic,meson-saradc"; + reg = <0x0 0x2c00 0x0 0x48>; + #io-channel-cells = <1>; + power-domains = <&pwrc PWRC_I2C_ID>; + interrupts = <GIC_SPI 35 IRQ_TYPE_EDGE_RISING>; + clocks = <&xtal>, + <&clkc_periphs CLKID_SARADC_EN>, + <&clkc_periphs CLKID_SARADC>, + <&clkc_periphs CLKID_SARADC_SEL>; + clock-names = "clkin", "core", + "adc_clk", "adc_sel"; + status = "disabled"; + }; + + i2c1: i2c@5c00 { + compatible = "amlogic,meson-axg-i2c"; + status = "disabled"; + reg = <0x0 0x5c00 0x0 0x20>; + interrupts = <GIC_SPI 68 IRQ_TYPE_EDGE_RISING>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clkc_periphs CLKID_I2C_M_B>; + power-domains = <&pwrc PWRC_I2C_ID>; + }; + + i2c2: i2c@6800 { + compatible = "amlogic,meson-axg-i2c"; + status = "disabled"; + reg = <0x0 0x6800 0x0 0x20>; + interrupts = <GIC_SPI 76 IRQ_TYPE_EDGE_RISING>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clkc_periphs CLKID_I2C_M_C>; + power-domains = <&pwrc PWRC_I2C_ID>; + }; + + i2c3: i2c@6c00 { + compatible = "amlogic,meson-axg-i2c"; + status = "disabled"; + reg = <0x0 0x6c00 0x0 0x20>; + interrupts = <GIC_SPI 78 IRQ_TYPE_EDGE_RISING>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clkc_periphs CLKID_I2C_M_D>; + power-domains = <&pwrc PWRC_I2C_ID>; + }; + + usb2_phy1: phy@4000 { + compatible = "amlogic,a1-usb2-phy"; + clocks = <&clkc_periphs CLKID_USB_PHY_IN>; + clock-names = "xtal"; + reg = <0x0 0x4000 0x0 0x60>; + resets = <&reset RESET_USBPHY>; + reset-names = "phy"; + #phy-cells = <0>; + power-domains = <&pwrc PWRC_USB_ID>; + }; + hwrng: rng@5118 { compatible = "amlogic,meson-rng"; reg = <0x0 0x5118 0x0 0x4>; + power-domains = <&pwrc PWRC_OTP_ID>; }; sec_AO: ao-secure@5a20 { @@ -135,6 +409,78 @@ reg = <0x0 0x5a20 0x0 0x140>; amlogic,has-chip-id; }; + + clkc_pll: pll-clock-controller@7c80 { + compatible = "amlogic,a1-pll-clkc"; + reg = <0 0x7c80 0 0x18c>; + #clock-cells = <1>; + clocks = <&clkc_periphs CLKID_FIXPLL_IN>, + <&clkc_periphs CLKID_HIFIPLL_IN>; + clock-names = "fixpll_in", "hifipll_in"; + }; + + sd_emmc: sd@10000 { + compatible = "amlogic,meson-axg-mmc"; + reg = <0x0 0x10000 0x0 0x800>; + interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clkc_periphs CLKID_SD_EMMC_A>, + <&clkc_periphs CLKID_SD_EMMC>, + <&clkc_pll CLKID_FCLK_DIV2>; + clock-names = "core", + "clkin0", + "clkin1"; + assigned-clocks = <&clkc_periphs CLKID_SD_EMMC_SEL2>; + assigned-clock-parents = <&xtal>; + resets = <&reset RESET_SD_EMMC_A>; + power-domains = <&pwrc PWRC_SD_EMMC_ID>; + status = "disabled"; + }; + }; + + usb: usb@fe004400 { + status = "disabled"; + compatible = "amlogic,meson-a1-usb-ctrl"; + reg = <0x0 0xfe004400 0x0 0xa0>; + interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <2>; + #size-cells = <2>; + ranges; + + clocks = <&clkc_periphs CLKID_USB_CTRL>, + <&clkc_periphs CLKID_USB_BUS>, + <&clkc_periphs CLKID_USB_CTRL_IN>; + clock-names = "usb_ctrl", "usb_bus", "xtal_usb_ctrl"; + resets = <&reset RESET_USBCTRL>; + reset-name = "usb_ctrl"; + + dr_mode = "otg"; + + phys = <&usb2_phy1>; + phy-names = "usb2-phy1"; + + dwc3: usb@ff400000 { + compatible = "snps,dwc3"; + reg = <0x0 0xff400000 0x0 0x100000>; + interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>; + dr_mode = "host"; + snps,dis_u2_susphy_quirk; + snps,quirk-frame-length-adjustment = <0x20>; + snps,parkmode-disable-ss-quirk; + }; + + dwc2: usb@ff500000 { + compatible = "amlogic,meson-a1-usb", "snps,dwc2"; + reg = <0x0 0xff500000 0x0 0x40000>; + interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>; + phys = <&usb2_phy1>; + phy-names = "usb2-phy"; + clocks = <&clkc_periphs CLKID_USB_PHY>; + clock-names = "otg"; + dr_mode = "peripheral"; + g-rx-fifo-size = <192>; + g-np-tx-fifo-size = <128>; + g-tx-fifo-size = <128 128 16 16 16>; + }; }; gic: interrupt-controller@ff901000 { diff --git a/arch/arm/dts/sama5d2.dtsi b/arch/arm/dts/sama5d2.dtsi index dd6468ed96..819564fdd5 100644 --- a/arch/arm/dts/sama5d2.dtsi +++ b/arch/arm/dts/sama5d2.dtsi @@ -781,6 +781,26 @@ status = "disabled"; }; + flx4: flexcom@fc018000 { + compatible = "atmel,sama5d2-flexcom"; + reg = <0xfc018000 0x200>; + clocks = <&flx4_clk>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0xfc018000 0x800>; + status = "disabled"; + + i2c6: i2c@600 { + compatible = "atmel,sama5d2-i2c"; + reg = <0x600 0x200>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&flx4_clk>; + clock-names = "i2c6_clk"; + status = "disabled"; + }; + }; + aic: interrupt-controller@fc020000 { #interrupt-cells = <3>; compatible = "atmel,sama5d2-aic"; diff --git a/arch/arm/dts/sun50i-a64.dtsi b/arch/arm/dts/sun50i-a64.dtsi index 135762b34f..2240eaec5d 100644 --- a/arch/arm/dts/sun50i-a64.dtsi +++ b/arch/arm/dts/sun50i-a64.dtsi @@ -93,6 +93,7 @@ L2: l2-cache { compatible = "cache"; cache-level = <2>; + cache-unified; }; }; @@ -407,7 +408,7 @@ interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>; clocks = <&ccu CLK_BUS_TCON0>, <&ccu CLK_TCON0>; clock-names = "ahb", "tcon-ch0"; - clock-output-names = "tcon-pixel-clock"; + clock-output-names = "tcon-data-clock"; #clock-cells = <0>; resets = <&ccu RST_BUS_TCON0>, <&ccu RST_BUS_LVDS>; reset-names = "lcd", "lvds"; diff --git a/arch/arm/dts/sun50i-h6-pine-h64-model-b.dts b/arch/arm/dts/sun50i-h6-pine-h64-model-b.dts index 686f58e770..b710f1a0f5 100644 --- a/arch/arm/dts/sun50i-h6-pine-h64-model-b.dts +++ b/arch/arm/dts/sun50i-h6-pine-h64-model-b.dts @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: (GPL-2.0+ or MIT) +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) /* * Copyright (C) 2019 Corentin LABBE <clabbe@baylibre.com> */ diff --git a/arch/arm/dts/sun50i-h616-orangepi-zero.dtsi b/arch/arm/dts/sun50i-h616-orangepi-zero.dtsi new file mode 100644 index 0000000000..15290e6892 --- /dev/null +++ b/arch/arm/dts/sun50i-h616-orangepi-zero.dtsi @@ -0,0 +1,134 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (C) 2020 Arm Ltd. + * + * DT nodes common between Orange Pi Zero 2 and Orange Pi Zero 3. + * Excludes PMIC nodes and properties, since they are different between the two. + */ + +#include "sun50i-h616.dtsi" + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/interrupt-controller/arm-gic.h> +#include <dt-bindings/leds/common.h> + +/ { + aliases { + ethernet0 = &emac0; + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + leds { + compatible = "gpio-leds"; + + led-0 { + function = LED_FUNCTION_POWER; + color = <LED_COLOR_ID_RED>; + gpios = <&pio 2 12 GPIO_ACTIVE_HIGH>; /* PC12 */ + default-state = "on"; + }; + + led-1 { + function = LED_FUNCTION_STATUS; + color = <LED_COLOR_ID_GREEN>; + gpios = <&pio 2 13 GPIO_ACTIVE_HIGH>; /* PC13 */ + }; + }; + + reg_vcc5v: vcc5v { + /* board wide 5V supply directly from the USB-C socket */ + compatible = "regulator-fixed"; + regulator-name = "vcc-5v"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + }; + + reg_usb1_vbus: regulator-usb1-vbus { + compatible = "regulator-fixed"; + regulator-name = "usb1-vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <®_vcc5v>; + enable-active-high; + gpio = <&pio 2 16 GPIO_ACTIVE_HIGH>; /* PC16 */ + }; +}; + +&ehci1 { + status = "okay"; +}; + +/* USB 2 & 3 are on headers only. */ + +&emac0 { + pinctrl-names = "default"; + pinctrl-0 = <&ext_rgmii_pins>; + phy-mode = "rgmii"; + phy-handle = <&ext_rgmii_phy>; + allwinner,rx-delay-ps = <3100>; + allwinner,tx-delay-ps = <700>; + status = "okay"; +}; + +&mdio0 { + ext_rgmii_phy: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <1>; + }; +}; + +&mmc0 { + cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */ + bus-width = <4>; + status = "okay"; +}; + +&ohci1 { + status = "okay"; +}; + +&spi0 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&spi0_pins>, <&spi0_cs0_pin>; + + flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <40000000>; + }; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_ph_pins>; + status = "okay"; +}; + +&usbotg { + /* + * PHY0 pins are connected to a USB-C socket, but a role switch + * is not implemented: both CC pins are pulled to GND. + * The VBUS pins power the device, so a fixed peripheral mode + * is the best choice. + * The board can be powered via GPIOs, in this case port0 *can* + * act as a host (with a cable/adapter ignoring CC), as VBUS is + * then provided by the GPIOs. Any user of this setup would + * need to adjust the DT accordingly: dr_mode set to "host", + * enabling OHCI0 and EHCI0. + */ + dr_mode = "peripheral"; + status = "okay"; +}; + +&usbphy { + usb1_vbus-supply = <®_usb1_vbus>; + status = "okay"; +}; diff --git a/arch/arm/dts/sun50i-h616-orangepi-zero2.dts b/arch/arm/dts/sun50i-h616-orangepi-zero2.dts index cb8600d0ea..d83852e72f 100644 --- a/arch/arm/dts/sun50i-h616-orangepi-zero2.dts +++ b/arch/arm/dts/sun50i-h616-orangepi-zero2.dts @@ -1,99 +1,23 @@ -// SPDX-License-Identifier: (GPL-2.0+ or MIT) +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) /* * Copyright (C) 2020 Arm Ltd. */ /dts-v1/; -#include "sun50i-h616.dtsi" - -#include <dt-bindings/gpio/gpio.h> -#include <dt-bindings/interrupt-controller/arm-gic.h> -#include <dt-bindings/leds/common.h> +#include "sun50i-h616-orangepi-zero.dtsi" / { model = "OrangePi Zero2"; compatible = "xunlong,orangepi-zero2", "allwinner,sun50i-h616"; - - aliases { - ethernet0 = &emac0; - serial0 = &uart0; - }; - - chosen { - stdout-path = "serial0:115200n8"; - }; - - leds { - compatible = "gpio-leds"; - - led-0 { - function = LED_FUNCTION_POWER; - color = <LED_COLOR_ID_RED>; - gpios = <&pio 2 12 GPIO_ACTIVE_HIGH>; /* PC12 */ - default-state = "on"; - }; - - led-1 { - function = LED_FUNCTION_STATUS; - color = <LED_COLOR_ID_GREEN>; - gpios = <&pio 2 13 GPIO_ACTIVE_HIGH>; /* PC13 */ - }; - }; - - reg_vcc5v: vcc5v { - /* board wide 5V supply directly from the USB-C socket */ - compatible = "regulator-fixed"; - regulator-name = "vcc-5v"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - regulator-always-on; - }; - - reg_usb1_vbus: regulator-usb1-vbus { - compatible = "regulator-fixed"; - regulator-name = "usb1-vbus"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - vin-supply = <®_vcc5v>; - enable-active-high; - gpio = <&pio 2 16 GPIO_ACTIVE_HIGH>; /* PC16 */ - }; }; -&ehci1 { - status = "okay"; -}; - -/* USB 2 & 3 are on headers only. */ - &emac0 { - pinctrl-names = "default"; - pinctrl-0 = <&ext_rgmii_pins>; - phy-mode = "rgmii"; - phy-handle = <&ext_rgmii_phy>; phy-supply = <®_dcdce>; - allwinner,rx-delay-ps = <3100>; - allwinner,tx-delay-ps = <700>; - status = "okay"; -}; - -&mdio0 { - ext_rgmii_phy: ethernet-phy@1 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <1>; - }; }; &mmc0 { vmmc-supply = <®_dcdce>; - cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */ - bus-width = <4>; - status = "okay"; -}; - -&ohci1 { - status = "okay"; }; &r_rsb { @@ -211,44 +135,3 @@ vcc-ph-supply = <®_aldo1>; vcc-pi-supply = <®_aldo1>; }; - -&spi0 { - status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <&spi0_pins>, <&spi0_cs0_pin>; - - flash@0 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "jedec,spi-nor"; - reg = <0>; - spi-max-frequency = <40000000>; - }; -}; - -&uart0 { - pinctrl-names = "default"; - pinctrl-0 = <&uart0_ph_pins>; - status = "okay"; -}; - -&usbotg { - /* - * PHY0 pins are connected to a USB-C socket, but a role switch - * is not implemented: both CC pins are pulled to GND. - * The VBUS pins power the device, so a fixed peripheral mode - * is the best choice. - * The board can be powered via GPIOs, in this case port0 *can* - * act as a host (with a cable/adapter ignoring CC), as VBUS is - * then provided by the GPIOs. Any user of this setup would - * need to adjust the DT accordingly: dr_mode set to "host", - * enabling OHCI0 and EHCI0. - */ - dr_mode = "peripheral"; - status = "okay"; -}; - -&usbphy { - usb1_vbus-supply = <®_usb1_vbus>; - status = "okay"; -}; diff --git a/arch/arm/dts/sun50i-h616-x96-mate.dts b/arch/arm/dts/sun50i-h616-x96-mate.dts index 07424c28b6..959b6fd184 100644 --- a/arch/arm/dts/sun50i-h616-x96-mate.dts +++ b/arch/arm/dts/sun50i-h616-x96-mate.dts @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: (GPL-2.0+ or MIT) +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) /* * Copyright (C) 2021 Arm Ltd. */ diff --git a/arch/arm/dts/sun50i-h618-orangepi-zero3.dts b/arch/arm/dts/sun50i-h618-orangepi-zero3.dts new file mode 100644 index 0000000000..00fe28caac --- /dev/null +++ b/arch/arm/dts/sun50i-h618-orangepi-zero3.dts @@ -0,0 +1,94 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (C) 2023 Arm Ltd. + */ + +/dts-v1/; + +#include "sun50i-h616-orangepi-zero.dtsi" + +/ { + model = "OrangePi Zero3"; + compatible = "xunlong,orangepi-zero3", "allwinner,sun50i-h618"; +}; + +&emac0 { + phy-supply = <®_dldo1>; +}; + +&ext_rgmii_phy { + motorcomm,clk-out-frequency-hz = <125000000>; +}; + +&mmc0 { + /* + * The schematic shows the card detect pin wired up to PF6, via an + * inverter, but it just doesn't work. + */ + broken-cd; + vmmc-supply = <®_dldo1>; +}; + +&r_i2c { + status = "okay"; + + axp313: pmic@36 { + compatible = "x-powers,axp313a"; + reg = <0x36>; + #interrupt-cells = <1>; + interrupt-controller; + interrupt-parent = <&pio>; + interrupts = <2 9 IRQ_TYPE_LEVEL_LOW>; /* PC9 */ + + vin1-supply = <®_vcc5v>; + vin2-supply = <®_vcc5v>; + vin3-supply = <®_vcc5v>; + + regulators { + /* Supplies VCC-PLL, so needs to be always on. */ + reg_aldo1: aldo1 { + regulator-always-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc1v8"; + }; + + /* Supplies VCC-IO, so needs to be always on. */ + reg_dldo1: dldo1 { + regulator-always-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc3v3"; + }; + + reg_dcdc1: dcdc1 { + regulator-always-on; + regulator-min-microvolt = <810000>; + regulator-max-microvolt = <990000>; + regulator-name = "vdd-gpu-sys"; + }; + + reg_dcdc2: dcdc2 { + regulator-always-on; + regulator-min-microvolt = <810000>; + regulator-max-microvolt = <1100000>; + regulator-name = "vdd-cpu"; + }; + + reg_dcdc3: dcdc3 { + regulator-always-on; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + regulator-name = "vdd-dram"; + }; + }; + }; +}; + +&pio { + vcc-pc-supply = <®_dldo1>; + vcc-pf-supply = <®_dldo1>; + vcc-pg-supply = <®_aldo1>; + vcc-ph-supply = <®_dldo1>; + vcc-pi-supply = <®_dldo1>; +}; diff --git a/arch/arm/dts/sun5i-r8-chip.dts b/arch/arm/dts/sun5i-r8-chip.dts index fd37bd1f39..4192c23848 100644 --- a/arch/arm/dts/sun5i-r8-chip.dts +++ b/arch/arm/dts/sun5i-r8-chip.dts @@ -255,6 +255,12 @@ pinctrl-0 = <&uart3_pg_pins>, <&uart3_cts_rts_pg_pins>; status = "okay"; + + bluetooth { + compatible = "realtek,rtl8723bs-bt"; + device-wake-gpios = <&axp_gpio 3 GPIO_ACTIVE_HIGH>; + host-wake-gpios = <&pio 1 3 GPIO_ACTIVE_HIGH>; /* PB3 */ + }; }; &usb_otg { diff --git a/arch/arm/dts/sun5i.dtsi b/arch/arm/dts/sun5i.dtsi index 250d6b87ab..d7c7b454a1 100644 --- a/arch/arm/dts/sun5i.dtsi +++ b/arch/arm/dts/sun5i.dtsi @@ -286,7 +286,7 @@ clock-names = "ahb", "tcon-ch0", "tcon-ch1"; - clock-output-names = "tcon-pixel-clock"; + clock-output-names = "tcon-data-clock"; #clock-cells = <0>; status = "disabled"; @@ -517,6 +517,15 @@ bias-pull-up; }; + /omit-if-no-ref/ + mmc2_4bit_pe_pins: mmc2-4bit-pe-pins { + pins = "PE4", "PE5", "PE6", "PE7", + "PE8", "PE9"; + function = "mmc2"; + drive-strength = <30>; + bias-pull-up; + }; + mmc2_8bit_pins: mmc2-8bit-pins { pins = "PC6", "PC7", "PC8", "PC9", "PC10", "PC11", "PC12", "PC13", diff --git a/arch/arm/dts/sun7i-a20-icnova-a20-adb4006.dts b/arch/arm/dts/sun7i-a20-icnova-a20-adb4006.dts new file mode 100644 index 0000000000..577ead1d02 --- /dev/null +++ b/arch/arm/dts/sun7i-a20-icnova-a20-adb4006.dts @@ -0,0 +1,137 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +// Copyright (C) 2023 In-Circuit GmbH + +/dts-v1/; + +#include "sun7i-a20-icnova-a20.dtsi" + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/leds/common.h> + +/ { + model = "In-Circuit ICnova A20 ADB4006"; + compatible = "incircuit,icnova-a20-adb4006", "incircuit,icnova-a20", + "allwinner,sun7i-a20"; + + aliases { + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + hdmi-connector { + compatible = "hdmi-connector"; + type = "a"; + + port { + hdmi_con_in: endpoint { + remote-endpoint = <&hdmi_out_con>; + }; + }; + }; + + leds { + compatible = "gpio-leds"; + + led-0 { + function = LED_FUNCTION_POWER; + color = <LED_COLOR_ID_YELLOW>; + gpios = <&pio 7 21 GPIO_ACTIVE_HIGH>; /* PH21 */ + default-state = "on"; + }; + + led-1 { + function = LED_FUNCTION_HEARTBEAT; + color = <LED_COLOR_ID_RED>; + gpios = <&pio 7 20 GPIO_ACTIVE_HIGH>; /* PH20 */ + linux,default-trigger = "heartbeat"; + }; + }; +}; + +&ahci { + target-supply = <®_ahci_5v>; + status = "okay"; +}; + +&codec { + status = "okay"; +}; + +&de { + status = "okay"; +}; + +&ehci0 { + status = "okay"; +}; + +&ehci1 { + status = "okay"; +}; + +&hdmi { + status = "okay"; +}; + +&hdmi_out { + hdmi_out_con: endpoint { + remote-endpoint = <&hdmi_con_in>; + }; +}; + +&mmc0 { + vmmc-supply = <®_vcc3v3>; + bus-width = <4>; + cd-gpios = <&pio 7 1 GPIO_ACTIVE_LOW>; /* PH1 */ + status = "okay"; +}; + +&ohci0 { + status = "okay"; +}; + +&ohci1 { + status = "okay"; +}; + +&otg_sram { + status = "okay"; +}; + +®_ahci_5v { + status = "okay"; +}; + +&ac_power_supply { + status = "okay"; +}; + +®_usb1_vbus { + status = "okay"; +}; + +®_usb2_vbus { + status = "okay"; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pb_pins>; + status = "okay"; +}; + +&usb_otg { + dr_mode = "otg"; + status = "okay"; +}; + +&usbphy { + usb0_id_det-gpios = <&pio 7 4 GPIO_ACTIVE_HIGH>; /* PH4 */ + usb0_vbus_det-gpios = <&pio 7 5 GPIO_ACTIVE_HIGH>; /* PH5 */ + usb1_vbus-supply = <®_usb1_vbus>; + usb2_vbus-supply = <®_usb2_vbus>; + status = "okay"; +}; diff --git a/arch/arm/dts/sun7i-a20-icnova-a20.dtsi b/arch/arm/dts/sun7i-a20-icnova-a20.dtsi new file mode 100644 index 0000000000..46616c6bc8 --- /dev/null +++ b/arch/arm/dts/sun7i-a20-icnova-a20.dtsi @@ -0,0 +1,62 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +// Copyright (C) 2023 In-Circuit GmbH + +#include "sun7i-a20.dtsi" +#include "sunxi-common-regulators.dtsi" + +#include <dt-bindings/interrupt-controller/irq.h> + +&cpu0 { + cpu-supply = <®_dcdc2>; +}; + +&gmac { + pinctrl-names = "default"; + pinctrl-0 = <&gmac_mii_pins>; + phy-handle = <&phy1>; + phy-mode = "mii"; + status = "okay"; +}; + +&i2c0 { + status = "okay"; + + axp209: pmic@34 { + reg = <0x34>; + interrupt-parent = <&nmi_intc>; + interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + }; +}; + +&gmac_mdio { + phy1: ethernet-phy@1 { + reg = <1>; + }; +}; + +#include "axp209.dtsi" + +®_dcdc2 { + regulator-always-on; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1400000>; + regulator-name = "vdd-cpu"; +}; + +®_dcdc3 { + regulator-always-on; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1400000>; + regulator-name = "vdd-int-dll"; +}; + +®_ldo1 { + regulator-name = "vdd-rtc"; +}; + +®_ldo2 { + regulator-always-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-name = "avcc"; +}; diff --git a/arch/arm/dts/sun8i-a23-a33.dtsi b/arch/arm/dts/sun8i-a23-a33.dtsi index 84c6d9379a..a0cac966af 100644 --- a/arch/arm/dts/sun8i-a23-a33.dtsi +++ b/arch/arm/dts/sun8i-a23-a33.dtsi @@ -190,7 +190,7 @@ clock-names = "ahb", "tcon-ch0", "lvds-alt"; - clock-output-names = "tcon-pixel-clock"; + clock-output-names = "tcon-data-clock"; #clock-cells = <0>; resets = <&ccu RST_BUS_LCD>, <&ccu RST_BUS_LVDS>; diff --git a/arch/arm/dts/sun8i-a83t.dtsi b/arch/arm/dts/sun8i-a83t.dtsi index 9c07660080..cc40622466 100644 --- a/arch/arm/dts/sun8i-a83t.dtsi +++ b/arch/arm/dts/sun8i-a83t.dtsi @@ -456,7 +456,7 @@ interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>; clocks = <&ccu CLK_BUS_TCON0>, <&ccu CLK_TCON0>; clock-names = "ahb", "tcon-ch0"; - clock-output-names = "tcon-pixel-clock"; + clock-output-names = "tcon-data-clock"; #clock-cells = <0>; resets = <&ccu RST_BUS_TCON0>, <&ccu RST_BUS_LVDS>; reset-names = "lcd", "lvds"; diff --git a/arch/arm/dts/sun8i-t113s-mangopi-mq-r-t113.dts b/arch/arm/dts/sun8i-t113s-mangopi-mq-r-t113.dts new file mode 100644 index 0000000000..8b3a753838 --- /dev/null +++ b/arch/arm/dts/sun8i-t113s-mangopi-mq-r-t113.dts @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +// Copyright (C) 2022 Arm Ltd. + +#include <dt-bindings/interrupt-controller/irq.h> + +/dts-v1/; + +#include "sun8i-t113s.dtsi" +#include "sunxi-d1s-t113-mangopi-mq-r.dtsi" + +/ { + model = "MangoPi MQ-R-T113"; + compatible = "widora,mangopi-mq-r-t113", "allwinner,sun8i-t113s"; + + aliases { + ethernet0 = &rtl8189ftv; + }; +}; + +&cpu0 { + cpu-supply = <®_vcc_core>; +}; + +&cpu1 { + cpu-supply = <®_vcc_core>; +}; + +&mmc1 { + rtl8189ftv: wifi@1 { + reg = <1>; + interrupt-parent = <&pio>; + interrupts = <6 10 IRQ_TYPE_LEVEL_LOW>; /* PG10 = WL_WAKE_AP */ + interrupt-names = "host-wake"; + }; +}; diff --git a/arch/arm/dts/sun8i-t113s.dtsi b/arch/arm/dts/sun8i-t113s.dtsi new file mode 100644 index 0000000000..b94b69142a --- /dev/null +++ b/arch/arm/dts/sun8i-t113s.dtsi @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +// Copyright (C) 2022 Arm Ltd. + +#define SOC_PERIPHERAL_IRQ(nr) GIC_SPI nr + +#include <dt-bindings/interrupt-controller/arm-gic.h> +#include <../../riscv/dts/sunxi-d1s-t113.dtsi> +#include <../../riscv/dts/sunxi-d1-t113.dtsi> + +/ { + interrupt-parent = <&gic>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + compatible = "arm,cortex-a7"; + device_type = "cpu"; + reg = <0>; + clocks = <&ccu CLK_CPUX>; + clock-names = "cpu"; + }; + + cpu1: cpu@1 { + compatible = "arm,cortex-a7"; + device_type = "cpu"; + reg = <1>; + clocks = <&ccu CLK_CPUX>; + clock-names = "cpu"; + }; + }; + + gic: interrupt-controller@1c81000 { + compatible = "arm,gic-400"; + reg = <0x03021000 0x1000>, + <0x03022000 0x2000>, + <0x03024000 0x2000>, + <0x03026000 0x2000>; + interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; + interrupt-controller; + #interrupt-cells = <3>; + }; + + timer { + compatible = "arm,armv7-timer"; + interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>; + }; + + pmu { + compatible = "arm,cortex-a7-pmu"; + interrupts = <GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>; + interrupt-affinity = <&cpu0>, <&cpu1>; + }; +}; diff --git a/arch/arm/dts/sun8i-v3s.dtsi b/arch/arm/dts/sun8i-v3s.dtsi index b001251644..3b9a282c27 100644 --- a/arch/arm/dts/sun8i-v3s.dtsi +++ b/arch/arm/dts/sun8i-v3s.dtsi @@ -191,7 +191,7 @@ <&ccu CLK_TCON0>; clock-names = "ahb", "tcon-ch0"; - clock-output-names = "tcon-pixel-clock"; + clock-output-names = "tcon-data-clock"; #clock-cells = <0>; resets = <&ccu RST_BUS_TCON0>; reset-names = "lcd"; diff --git a/arch/arm/dts/sunxi-d1s-t113-mangopi-mq-r.dtsi b/arch/arm/dts/sunxi-d1s-t113-mangopi-mq-r.dtsi new file mode 100644 index 0000000000..a415c4a78a --- /dev/null +++ b/arch/arm/dts/sunxi-d1s-t113-mangopi-mq-r.dtsi @@ -0,0 +1,126 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +// Copyright (C) 2022 Arm Ltd. +/* + * Common peripherals and configurations for MangoPi MQ-R boards. + */ + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/leds/common.h> + +/ { + aliases { + serial3 = &uart3; + }; + + chosen { + stdout-path = "serial3:115200n8"; + }; + + leds { + compatible = "gpio-leds"; + + led-0 { + color = <LED_COLOR_ID_BLUE>; + function = LED_FUNCTION_STATUS; + gpios = <&pio 3 22 GPIO_ACTIVE_LOW>; /* PD22 */ + }; + }; + + /* board wide 5V supply directly from the USB-C socket */ + reg_vcc5v: regulator-5v { + compatible = "regulator-fixed"; + regulator-name = "vcc-5v"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + }; + + /* SY8008 DC/DC regulator on the board */ + reg_3v3: regulator-3v3 { + compatible = "regulator-fixed"; + regulator-name = "vcc-3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <®_vcc5v>; + }; + + /* SY8008 DC/DC regulator on the board, also supplying VDD-SYS */ + reg_vcc_core: regulator-core { + compatible = "regulator-fixed"; + regulator-name = "vcc-core"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <880000>; + vin-supply = <®_vcc5v>; + }; + + /* XC6206 LDO on the board */ + reg_avdd2v8: regulator-avdd { + compatible = "regulator-fixed"; + regulator-name = "avdd2v8"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + vin-supply = <®_3v3>; + }; + + wifi_pwrseq: wifi-pwrseq { + compatible = "mmc-pwrseq-simple"; + reset-gpios = <&pio 6 12 GPIO_ACTIVE_LOW>; /* PG12 */ + }; +}; + +&dcxo { + clock-frequency = <24000000>; +}; + +&ehci1 { + status = "okay"; +}; + +&mmc0 { + pinctrl-0 = <&mmc0_pins>; + pinctrl-names = "default"; + vmmc-supply = <®_3v3>; + cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; + disable-wp; + bus-width = <4>; + status = "okay"; +}; + +&mmc1 { + pinctrl-0 = <&mmc1_pins>; + pinctrl-names = "default"; + vmmc-supply = <®_3v3>; + non-removable; + bus-width = <4>; + mmc-pwrseq = <&wifi_pwrseq>; + status = "okay"; +}; + +&ohci1 { + status = "okay"; +}; + +&pio { + vcc-pb-supply = <®_3v3>; + vcc-pd-supply = <®_3v3>; + vcc-pe-supply = <®_avdd2v8>; + vcc-pf-supply = <®_3v3>; + vcc-pg-supply = <®_3v3>; +}; + +&uart3 { + pinctrl-names = "default"; + pinctrl-0 = <&uart3_pb_pins>; + status = "okay"; +}; + +/* The USB-C socket has its CC pins pulled to GND, so is hardwired as a UFP. */ +&usb_otg { + dr_mode = "peripheral"; + status = "okay"; +}; + +&usbphy { + usb1_vbus-supply = <®_vcc5v>; + status = "okay"; +}; diff --git a/arch/arm/dts/sunxi-u-boot.dtsi b/arch/arm/dts/sunxi-u-boot.dtsi index af419c7e59..a0c8abb703 100644 --- a/arch/arm/dts/sunxi-u-boot.dtsi +++ b/arch/arm/dts/sunxi-u-boot.dtsi @@ -23,6 +23,13 @@ }; }; +/* Let U-Boot be the firmware layer that controls the watchdog. */ +#ifdef CONFIG_MACH_SUN8I_R528 +&wdt { + status = "okay"; +}; +#endif + &binman { u-boot-sunxi-with-spl { filename = "u-boot-sunxi-with-spl.bin"; diff --git a/arch/arm/include/asm/arch-sunxi/boot0.h b/arch/arm/include/asm/arch-sunxi/boot0.h index 30f5680757..cad25c50bc 100644 --- a/arch/arm/include/asm/arch-sunxi/boot0.h +++ b/arch/arm/include/asm/arch-sunxi/boot0.h @@ -3,6 +3,8 @@ * Configuration settings for the Allwinner A64 (sun50i) CPU */ +#include <asm/arch/cpu.h> + #if defined(CONFIG_RESERVE_ALLWINNER_BOOT0_HEADER) && !defined(CONFIG_SPL_BUILD) /* reserve space for BOOT0 header information */ b reset diff --git a/arch/arm/include/asm/arch-sunxi/clock.h b/arch/arm/include/asm/arch-sunxi/clock.h index 2cfd540742..fcc8966cb0 100644 --- a/arch/arm/include/asm/arch-sunxi/clock.h +++ b/arch/arm/include/asm/arch-sunxi/clock.h @@ -9,6 +9,7 @@ #define _SUNXI_CLOCK_H #include <linux/types.h> +#include <asm/arch/cpu.h> #define CLK_GATE_OPEN 0x1 #define CLK_GATE_CLOSE 0x0 @@ -16,7 +17,7 @@ /* clock control module regs definition */ #if defined(CONFIG_MACH_SUN8I_A83T) #include <asm/arch/clock_sun8i_a83t.h> -#elif defined(CONFIG_SUN50I_GEN_H6) +#elif defined(CONFIG_SUN50I_GEN_H6) || defined(CONFIG_SUNXI_GEN_NCAT2) #include <asm/arch/clock_sun50i_h6.h> #elif defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN8I) || \ defined(CONFIG_MACH_SUN50I) || defined(CONFIG_MACH_SUNIV) diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h b/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h index 37df4410ea..a84a57e5b4 100644 --- a/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h +++ b/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h @@ -228,6 +228,7 @@ struct sunxi_ccm_reg { /* pll1 bit field */ #define CCM_PLL1_CTRL_EN BIT(31) +#define CCM_PLL1_LDO_EN BIT(30) #define CCM_PLL1_LOCK_EN BIT(29) #define CCM_PLL1_LOCK BIT(28) #define CCM_PLL1_OUT_EN BIT(27) @@ -248,6 +249,8 @@ struct sunxi_ccm_reg { #define CCM_PLL6_CTRL_EN BIT(31) #define CCM_PLL6_LOCK_EN BIT(29) #define CCM_PLL6_LOCK BIT(28) +#define CCM_PLL6_CTRL_P0_SHIFT 16 +#define CCM_PLL6_CTRL_P0_MASK (0x7 << CCM_PLL6_CTRL_P0_SHIFT) #define CCM_PLL6_CTRL_N_SHIFT 8 #define CCM_PLL6_CTRL_N_MASK (0xff << CCM_PLL6_CTRL_N_SHIFT) #define CCM_PLL6_CTRL_DIV1_SHIFT 0 @@ -263,7 +266,7 @@ struct sunxi_ccm_reg { #define CCM_CPU_AXI_AXI_MASK 0x3 #define CCM_CPU_AXI_DEFAULT_FACTORS 0x301 -#ifdef CONFIG_MACH_SUN50I_H6 +#ifdef CONFIG_MACH_SUN50I_H6 /* H6 */ #define CCM_PLL6_DEFAULT 0xa0006300 /* psi_ahb1_ahb2 bit field */ @@ -274,7 +277,7 @@ struct sunxi_ccm_reg { /* apb1 bit field */ #define CCM_APB1_DEFAULT 0x03000102 -#elif CONFIG_MACH_SUN50I_H616 +#elif CONFIG_MACH_SUN50I_H616 /* H616 */ #define CCM_PLL6_DEFAULT 0xa8003100 /* psi_ahb1_ahb2 bit field */ @@ -285,6 +288,11 @@ struct sunxi_ccm_reg { /* apb1 bit field */ #define CCM_APB1_DEFAULT 0x03000102 +#elif CONFIG_MACH_SUN8I_R528 /* R528 */ +#define CCM_PLL6_DEFAULT 0xe8216300 +#define CCM_PSI_AHB1_AHB2_DEFAULT 0x03000002 +//#define CCM_AHB3_DEFAULT 0x03000002 +#define CCM_APB1_DEFAULT 0x03000102 #endif /* apb2 bit field */ diff --git a/arch/arm/include/asm/arch-sunxi/cpu.h b/arch/arm/include/asm/arch-sunxi/cpu.h index b08f202374..768c6572d6 100644 --- a/arch/arm/include/asm/arch-sunxi/cpu.h +++ b/arch/arm/include/asm/arch-sunxi/cpu.h @@ -10,6 +10,8 @@ #include <asm/arch/cpu_sun9i.h> #elif defined(CONFIG_SUN50I_GEN_H6) #include <asm/arch/cpu_sun50i_h6.h> +#elif defined(CONFIG_SUNXI_GEN_NCAT2) +#include <asm/arch/cpu_sunxi_ncat2.h> #else #include <asm/arch/cpu_sun4i.h> #endif diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h index f7ecc790db..3daee2f574 100644 --- a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h +++ b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h @@ -91,7 +91,6 @@ #define SUNXI_CCM_BASE 0x01c20000 #define SUNXI_INTC_BASE 0x01c20400 -#define SUNXI_PIO_BASE 0x01c20800 #define SUNXI_TIMER_BASE 0x01c20c00 #ifndef CONFIG_SUNXI_GEN_SUN6I #define SUNXI_PWM_BASE 0x01c20e00 @@ -129,20 +128,6 @@ defined(CONFIG_MACH_SUN50I) #define SUNXI_CPUCFG_BASE 0x01c25c00 #endif -#ifdef CONFIG_MACH_SUNIV -#define SUNXI_UART0_BASE 0x01c25000 -#define SUNXI_UART1_BASE 0x01c25400 -#define SUNXI_UART2_BASE 0x01c25800 -#else -#define SUNXI_UART0_BASE 0x01c28000 -#define SUNXI_UART1_BASE 0x01c28400 -#define SUNXI_UART2_BASE 0x01c28800 -#endif -#define SUNXI_UART3_BASE 0x01c28c00 -#define SUNXI_UART4_BASE 0x01c29000 -#define SUNXI_UART5_BASE 0x01c29400 -#define SUNXI_UART6_BASE 0x01c29800 -#define SUNXI_UART7_BASE 0x01c29c00 #define SUNXI_PS2_0_BASE 0x01c2a000 #define SUNXI_PS2_1_BASE 0x01c2a400 @@ -209,8 +194,6 @@ defined(CONFIG_MACH_SUN50I) #endif #define SUNXI_R_TWI_BASE 0x01f02400 -#define SUNXI_R_UART_BASE 0x01f02800 -#define SUNXI_R_PIO_BASE 0x01f02c00 #define SUN6I_P2WI_BASE 0x01f03400 #define SUNXI_RSB_BASE 0x01f03400 diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h b/arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h index d9cf8ae042..15ee092d35 100644 --- a/arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h +++ b/arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h @@ -22,7 +22,6 @@ #define SUNXI_SIDC_BASE 0x03006000 #define SUNXI_SID_BASE 0x03006200 #define SUNXI_TIMER_BASE 0x03009000 -#define SUNXI_PIO_BASE 0x0300B000 #define SUNXI_PSI_BASE 0x0300C000 #define SUNXI_GIC400_BASE 0x03020000 @@ -43,10 +42,6 @@ #define SUNXI_DRAM_PHY0_BASE 0x04800000 #endif -#define SUNXI_UART0_BASE 0x05000000 -#define SUNXI_UART1_BASE 0x05000400 -#define SUNXI_UART2_BASE 0x05000800 -#define SUNXI_UART3_BASE 0x05000C00 #define SUNXI_TWI0_BASE 0x05002000 #define SUNXI_TWI1_BASE 0x05002400 #define SUNXI_TWI2_BASE 0x05002800 @@ -68,8 +63,6 @@ #define SUNXI_R_CPUCFG_BASE 0x07000400 #define SUNXI_PRCM_BASE 0x07010000 #define SUNXI_R_WDOG_BASE 0x07020400 -#define SUNXI_R_PIO_BASE 0x07022000 -#define SUNXI_R_UART_BASE 0x07080000 #define SUNXI_R_TWI_BASE 0x07081400 #ifndef __ASSEMBLY__ diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun9i.h b/arch/arm/include/asm/arch-sunxi/cpu_sun9i.h index 9c2d11b590..2bf2675d5c 100644 --- a/arch/arm/include/asm/arch-sunxi/cpu_sun9i.h +++ b/arch/arm/include/asm/arch-sunxi/cpu_sun9i.h @@ -81,18 +81,11 @@ /* APB0 Module */ #define SUNXI_CCM_BASE (REGS_APB0_BASE + 0x0000) #define SUNXI_CCMMODULE_BASE (REGS_APB0_BASE + 0x0400) -#define SUNXI_PIO_BASE (REGS_APB0_BASE + 0x0800) #define SUNXI_TIMER_BASE (REGS_APB0_BASE + 0x0C00) #define SUNXI_PWM_BASE (REGS_APB0_BASE + 0x1400) #define SUNXI_LRADC_BASE (REGS_APB0_BASE + 0x1800) /* APB1 Module */ -#define SUNXI_UART0_BASE (REGS_APB1_BASE + 0x0000) -#define SUNXI_UART1_BASE (REGS_APB1_BASE + 0x0400) -#define SUNXI_UART2_BASE (REGS_APB1_BASE + 0x0800) -#define SUNXI_UART3_BASE (REGS_APB1_BASE + 0x0C00) -#define SUNXI_UART4_BASE (REGS_APB1_BASE + 0x1000) -#define SUNXI_UART5_BASE (REGS_APB1_BASE + 0x1400) #define SUNXI_TWI0_BASE (REGS_APB1_BASE + 0x2800) #define SUNXI_TWI1_BASE (REGS_APB1_BASE + 0x2C00) #define SUNXI_TWI2_BASE (REGS_APB1_BASE + 0x3000) @@ -101,8 +94,6 @@ /* RCPUS Module */ #define SUNXI_PRCM_BASE (REGS_RCPUS_BASE + 0x1400) -#define SUNXI_R_UART_BASE (REGS_RCPUS_BASE + 0x2800) -#define SUNXI_R_PIO_BASE (REGS_RCPUS_BASE + 0x2c00) #define SUNXI_RSB_BASE (REGS_RCPUS_BASE + 0x3400) /* Misc. */ diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sunxi_ncat2.h b/arch/arm/include/asm/arch-sunxi/cpu_sunxi_ncat2.h new file mode 100644 index 0000000000..908a582ae0 --- /dev/null +++ b/arch/arm/include/asm/arch-sunxi/cpu_sunxi_ncat2.h @@ -0,0 +1,39 @@ +/* + * (C) Copyright 2022 Arm Limited + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _SUNXI_CPU_SUNXI_NCAT2_H +#define _SUNXI_CPU_SUNXI_NCAT2_H + +#define SUNXI_CCM_BASE 0x02001000 +#define SUNXI_TIMER_BASE 0x02050000 + +#define SUNXI_TWI0_BASE 0x02502000 +#define SUNXI_TWI1_BASE 0x02502400 +#define SUNXI_TWI2_BASE 0x02502800 +#define SUNXI_TWI3_BASE 0x02502C00 + +#define SUNXI_SRAMC_BASE 0x03000000 +/* SID address space starts at 0x03006000, but e-fuse is at offset 0x200 */ +#define SUNXI_SIDC_BASE 0x03006000 +#define SUNXI_SID_BASE 0x03006200 +#define SUNXI_GIC400_BASE 0x03020000 + +#define SUNXI_MMC0_BASE 0x04020000 +#define SUNXI_MMC1_BASE 0x04021000 +#define SUNXI_MMC2_BASE 0x04022000 + +#define SUNXI_R_CPUCFG_BASE 0x07000400 +#define SUNXI_PRCM_BASE 0x07010000 + +#define SUNXI_CPUCFG_BASE 0x09010000 + +#ifndef __ASSEMBLY__ +void sunxi_board_init(void); +void sunxi_reset(void); +int sunxi_get_sid(unsigned int *sid); +#endif + +#endif /* _SUNXI_CPU_SUNXI_NCAT2_H */ diff --git a/arch/arm/include/asm/arch-sunxi/cpucfg.h b/arch/arm/include/asm/arch-sunxi/cpucfg.h deleted file mode 100644 index 4aaebe0a97..0000000000 --- a/arch/arm/include/asm/arch-sunxi/cpucfg.h +++ /dev/null @@ -1,67 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Sunxi A31 CPUCFG register definition. - * - * (C) Copyright 2014 Hans de Goede <hdegoede@redhat.com - */ - -#ifndef _SUNXI_CPUCFG_H -#define _SUNXI_CPUCFG_H - -#include <linux/compiler.h> -#include <linux/types.h> - -#ifndef __ASSEMBLY__ - -struct __packed sunxi_cpucfg_cpu { - u32 rst; /* base + 0x0 */ - u32 ctrl; /* base + 0x4 */ - u32 status; /* base + 0x8 */ - u8 res[0x34]; /* base + 0xc */ -}; - -struct __packed sunxi_cpucfg_reg { - u8 res0[0x40]; /* 0x000 */ - struct sunxi_cpucfg_cpu cpu[4]; /* 0x040 */ - u8 res1[0x44]; /* 0x140 */ - u32 gen_ctrl; /* 0x184 */ - u32 l2_status; /* 0x188 */ - u8 res2[0x4]; /* 0x18c */ - u32 event_in; /* 0x190 */ - u8 res3[0xc]; /* 0x194 */ - u32 super_standy_flag; /* 0x1a0 */ - u32 priv0; /* 0x1a4 */ - u32 priv1; /* 0x1a8 */ - u8 res4[0x4]; /* 0x1ac */ - u32 cpu1_pwr_clamp; /* 0x1b0 sun7i only */ - u32 cpu1_pwroff; /* 0x1b4 sun7i only */ - u8 res5[0x2c]; /* 0x1b8 */ - u32 dbg_ctrl1; /* 0x1e4 */ - u8 res6[0x18]; /* 0x1e8 */ - u32 idle_cnt0_low; /* 0x200 */ - u32 idle_cnt0_high; /* 0x204 */ - u32 idle_cnt0_ctrl; /* 0x208 */ - u8 res8[0x4]; /* 0x20c */ - u32 idle_cnt1_low; /* 0x210 */ - u32 idle_cnt1_high; /* 0x214 */ - u32 idle_cnt1_ctrl; /* 0x218 */ - u8 res9[0x4]; /* 0x21c */ - u32 idle_cnt2_low; /* 0x220 */ - u32 idle_cnt2_high; /* 0x224 */ - u32 idle_cnt2_ctrl; /* 0x228 */ - u8 res10[0x4]; /* 0x22c */ - u32 idle_cnt3_low; /* 0x230 */ - u32 idle_cnt3_high; /* 0x234 */ - u32 idle_cnt3_ctrl; /* 0x238 */ - u8 res11[0x4]; /* 0x23c */ - u32 idle_cnt4_low; /* 0x240 */ - u32 idle_cnt4_high; /* 0x244 */ - u32 idle_cnt4_ctrl; /* 0x248 */ - u8 res12[0x34]; /* 0x24c */ - u32 cnt64_ctrl; /* 0x280 */ - u32 cnt64_low; /* 0x284 */ - u32 cnt64_high; /* 0x288 */ -}; - -#endif /* __ASSEMBLY__ */ -#endif /* _SUNXI_CPUCFG_H */ diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h deleted file mode 100644 index 6eaeece4e2..0000000000 --- a/arch/arm/include/asm/arch-sunxi/gpio.h +++ /dev/null @@ -1,236 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * (C) Copyright 2007-2012 - * Allwinner Technology Co., Ltd. <www.allwinnertech.com> - * Tom Cubie <tangliang@allwinnertech.com> - */ - -#ifndef _SUNXI_GPIO_H -#define _SUNXI_GPIO_H - -#include <linux/types.h> -#include <asm/arch/cpu.h> - -/* - * sunxi has 9 banks of gpio, they are: - * PA0 - PA17 | PB0 - PB23 | PC0 - PC24 - * PD0 - PD27 | PE0 - PE31 | PF0 - PF5 - * PG0 - PG9 | PH0 - PH27 | PI0 - PI12 - */ - -#define SUNXI_GPIO_A 0 -#define SUNXI_GPIO_B 1 -#define SUNXI_GPIO_C 2 -#define SUNXI_GPIO_D 3 -#define SUNXI_GPIO_E 4 -#define SUNXI_GPIO_F 5 -#define SUNXI_GPIO_G 6 -#define SUNXI_GPIO_H 7 -#define SUNXI_GPIO_I 8 - -/* - * This defines the number of GPIO banks for the _main_ GPIO controller. - * You should fix up the padding in struct sunxi_gpio_reg below if you - * change this. - */ -#define SUNXI_GPIO_BANKS 9 - -/* - * sun6i/sun8i and later SoCs have an additional GPIO controller (R_PIO) - * at a different register offset. - * - * sun6i has 2 banks: - * PL0 - PL8 | PM0 - PM7 - * - * sun8i has 1 bank: - * PL0 - PL11 - * - * sun9i has 3 banks: - * PL0 - PL9 | PM0 - PM15 | PN0 - PN1 - */ -#define SUNXI_GPIO_L 11 -#define SUNXI_GPIO_M 12 -#define SUNXI_GPIO_N 13 - -struct sunxi_gpio { - u32 cfg[4]; - u32 dat; - u32 drv[2]; - u32 pull[2]; -}; - -/* gpio interrupt control */ -struct sunxi_gpio_int { - u32 cfg[3]; - u32 ctl; - u32 sta; - u32 deb; /* interrupt debounce */ -}; - -struct sunxi_gpio_reg { - struct sunxi_gpio gpio_bank[SUNXI_GPIO_BANKS]; - u8 res[0xbc]; - struct sunxi_gpio_int gpio_int; -}; - -#define SUN50I_H6_GPIO_POW_MOD_SEL 0x340 -#define SUN50I_H6_GPIO_POW_MOD_VAL 0x348 - -#define BANK_TO_GPIO(bank) (((bank) < SUNXI_GPIO_L) ? \ - &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[bank] : \ - &((struct sunxi_gpio_reg *)SUNXI_R_PIO_BASE)->gpio_bank[(bank) - SUNXI_GPIO_L]) - -#define GPIO_BANK(pin) ((pin) >> 5) -#define GPIO_NUM(pin) ((pin) & 0x1f) - -#define GPIO_CFG_INDEX(pin) (((pin) & 0x1f) >> 3) -#define GPIO_CFG_OFFSET(pin) ((((pin) & 0x1f) & 0x7) << 2) - -#define GPIO_DRV_INDEX(pin) (((pin) & 0x1f) >> 4) -#define GPIO_DRV_OFFSET(pin) ((((pin) & 0x1f) & 0xf) << 1) - -#define GPIO_PULL_INDEX(pin) (((pin) & 0x1f) >> 4) -#define GPIO_PULL_OFFSET(pin) ((((pin) & 0x1f) & 0xf) << 1) - -/* GPIO bank sizes */ -#define SUNXI_GPIOS_PER_BANK 32 - -#define SUNXI_GPIO_NEXT(__gpio) \ - ((__gpio##_START) + SUNXI_GPIOS_PER_BANK) - -enum sunxi_gpio_number { - SUNXI_GPIO_A_START = 0, - SUNXI_GPIO_B_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_A), - SUNXI_GPIO_C_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_B), - SUNXI_GPIO_D_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_C), - SUNXI_GPIO_E_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_D), - SUNXI_GPIO_F_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_E), - SUNXI_GPIO_G_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_F), - SUNXI_GPIO_H_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_G), - SUNXI_GPIO_I_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_H), - SUNXI_GPIO_L_START = 352, - SUNXI_GPIO_M_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_L), - SUNXI_GPIO_N_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_M), - SUNXI_GPIO_AXP0_START = 1024, -}; - -/* SUNXI GPIO number definitions */ -#define SUNXI_GPA(_nr) (SUNXI_GPIO_A_START + (_nr)) -#define SUNXI_GPB(_nr) (SUNXI_GPIO_B_START + (_nr)) -#define SUNXI_GPC(_nr) (SUNXI_GPIO_C_START + (_nr)) -#define SUNXI_GPD(_nr) (SUNXI_GPIO_D_START + (_nr)) -#define SUNXI_GPE(_nr) (SUNXI_GPIO_E_START + (_nr)) -#define SUNXI_GPF(_nr) (SUNXI_GPIO_F_START + (_nr)) -#define SUNXI_GPG(_nr) (SUNXI_GPIO_G_START + (_nr)) -#define SUNXI_GPH(_nr) (SUNXI_GPIO_H_START + (_nr)) -#define SUNXI_GPI(_nr) (SUNXI_GPIO_I_START + (_nr)) -#define SUNXI_GPL(_nr) (SUNXI_GPIO_L_START + (_nr)) -#define SUNXI_GPM(_nr) (SUNXI_GPIO_M_START + (_nr)) -#define SUNXI_GPN(_nr) (SUNXI_GPIO_N_START + (_nr)) - -#define SUNXI_GPAXP0(_nr) (SUNXI_GPIO_AXP0_START + (_nr)) - -/* GPIO pin function config */ -#define SUNXI_GPIO_INPUT 0 -#define SUNXI_GPIO_OUTPUT 1 -#define SUNXI_GPIO_DISABLE 7 - -#define SUN8I_H3_GPA_UART0 2 -#define SUN8I_H3_GPA_UART2 2 - -#define SUN4I_GPB_PWM 2 -#define SUN4I_GPB_TWI0 2 -#define SUN4I_GPB_TWI1 2 -#define SUN5I_GPB_TWI1 2 -#define SUN8I_V3S_GPB_TWI0 2 -#define SUN4I_GPB_UART0 2 -#define SUN5I_GPB_UART0 2 -#define SUN8I_GPB_UART2 2 -#define SUN8I_A33_GPB_UART0 3 -#define SUN8I_A83T_GPB_UART0 2 -#define SUN8I_V3S_GPB_UART0 3 -#define SUN50I_GPB_UART0 4 - -#define SUNXI_GPC_NAND 2 -#define SUNXI_GPC_SPI0 3 -#define SUNXI_GPC_SDC2 3 -#define SUN6I_GPC_SDC3 4 -#define SUN50I_GPC_SPI0 4 -#define SUNIV_GPC_SPI0 2 - -#define SUNXI_GPD_LCD0 2 -#define SUNXI_GPD_LVDS0 3 - -#define SUNIV_GPE_UART0 5 - -#define SUNXI_GPF_SDC0 2 -#define SUNXI_GPF_UART0 4 -#define SUN8I_GPF_UART0 3 - -#define SUN4I_GPG_SDC1 4 -#define SUN5I_GPG_SDC1 2 -#define SUN6I_GPG_SDC1 2 -#define SUN8I_GPG_SDC1 2 -#define SUN8I_GPG_UART1 2 -#define SUN5I_GPG_UART1 4 - -#define SUN6I_GPH_PWM 2 -#define SUN8I_GPH_PWM 2 -#define SUN4I_GPH_SDC1 5 -#define SUN6I_GPH_TWI0 2 -#define SUN8I_GPH_TWI0 2 -#define SUN50I_GPH_TWI0 2 -#define SUN6I_GPH_TWI1 2 -#define SUN8I_GPH_TWI1 2 -#define SUN50I_GPH_TWI1 2 -#define SUN6I_GPH_UART0 2 -#define SUN9I_GPH_UART0 2 -#define SUN50I_H6_GPH_UART0 2 -#define SUN50I_H616_GPH_UART0 2 - -#define SUNXI_GPI_SDC3 2 - -#define SUN6I_GPL0_R_P2WI_SCK 3 -#define SUN6I_GPL1_R_P2WI_SDA 3 - -#define SUN8I_GPL_R_RSB 2 -#define SUN8I_H3_GPL_R_TWI 2 -#define SUN8I_A23_GPL_R_TWI 3 -#define SUN8I_GPL_R_UART 2 -#define SUN50I_GPL_R_TWI 2 -#define SUN50I_H616_GPL_R_TWI 3 - -#define SUN9I_GPN_R_RSB 3 - -/* GPIO pin pull-up/down config */ -#define SUNXI_GPIO_PULL_DISABLE 0 -#define SUNXI_GPIO_PULL_UP 1 -#define SUNXI_GPIO_PULL_DOWN 2 - -/* Virtual AXP0 GPIOs */ -#define SUNXI_GPIO_AXP0_PREFIX "AXP0-" -#define SUNXI_GPIO_AXP0_VBUS_ENABLE 5 -#define SUNXI_GPIO_AXP0_GPIO_COUNT 6 - -struct sunxi_gpio_plat { - struct sunxi_gpio *regs; - char bank_name[3]; -}; - -void sunxi_gpio_set_cfgbank(struct sunxi_gpio *pio, int bank_offset, u32 val); -void sunxi_gpio_set_cfgpin(u32 pin, u32 val); -int sunxi_gpio_get_cfgbank(struct sunxi_gpio *pio, int bank_offset); -int sunxi_gpio_get_cfgpin(u32 pin); -void sunxi_gpio_set_drv(u32 pin, u32 val); -void sunxi_gpio_set_drv_bank(struct sunxi_gpio *pio, u32 bank_offset, u32 val); -void sunxi_gpio_set_pull(u32 pin, u32 val); -void sunxi_gpio_set_pull_bank(struct sunxi_gpio *pio, int bank_offset, u32 val); -int sunxi_name_to_gpio(const char *name); - -#if !defined CONFIG_SPL_BUILD && defined CONFIG_AXP_GPIO -int axp_gpio_init(void); -#else -static inline int axp_gpio_init(void) { return 0; } -#endif - -#endif /* _SUNXI_GPIO_H */ diff --git a/arch/arm/include/asm/arch-sunxi/mmc.h b/arch/arm/include/asm/arch-sunxi/mmc.h index 5daacf10eb..8ed3e0459c 100644 --- a/arch/arm/include/asm/arch-sunxi/mmc.h +++ b/arch/arm/include/asm/arch-sunxi/mmc.h @@ -45,7 +45,7 @@ struct sunxi_mmc { u32 chda; /* 0x90 */ u32 cbda; /* 0x94 */ u32 res2[26]; -#if defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6) +#if defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6) || defined(CONFIG_SUNXI_GEN_NCAT2) u32 res3[17]; u32 samp_dl; u32 res4[46]; diff --git a/arch/arm/include/asm/arch-sunxi/prcm.h b/arch/arm/include/asm/arch-sunxi/prcm.h index 5106076f5e..c5418cfd28 100644 --- a/arch/arm/include/asm/arch-sunxi/prcm.h +++ b/arch/arm/include/asm/arch-sunxi/prcm.h @@ -9,7 +9,7 @@ #define _SUNXI_PRCM_H /* prcm regs definition */ -#if defined(CONFIG_SUN50I_GEN_H6) +#if defined(CONFIG_SUN50I_GEN_H6) || defined(CONFIG_SUNXI_GEN_NCAT2) #include <asm/arch/prcm_sun50i.h> #else #include <asm/arch/prcm_sun6i.h> diff --git a/arch/arm/include/asm/arch-sunxi/serial.h b/arch/arm/include/asm/arch-sunxi/serial.h new file mode 100644 index 0000000000..9386287b65 --- /dev/null +++ b/arch/arm/include/asm/arch-sunxi/serial.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * hardcoded UART base addresses for early SPL use + * + * Copyright (c) 2022 Arm Ltd. + */ + +#ifndef SUNXI_SERIAL_MEMMAP_H +#define SUNXI_SERIAL_MEMMAP_H + +#if defined(CONFIG_MACH_SUN9I) +#define SUNXI_UART0_BASE 0x07000000 +#define SUNXI_R_UART_BASE 0x08002800 +#elif defined(CONFIG_SUN50I_GEN_H6) +#define SUNXI_UART0_BASE 0x05000000 +#define SUNXI_R_UART_BASE 0x07080000 +#elif defined(CONFIG_MACH_SUNIV) +#define SUNXI_UART0_BASE 0x01c25000 +#define SUNXI_R_UART_BASE 0 +#elif defined(CONFIG_SUNXI_GEN_NCAT2) +#define SUNXI_UART0_BASE 0x02500000 +#define SUNXI_R_UART_BASE 0 // 0x07080000 (?> +#else +#define SUNXI_UART0_BASE 0x01c28000 +#define SUNXI_R_UART_BASE 0x01f02800 +#endif + +#define SUNXI_UART1_BASE (SUNXI_UART0_BASE + 0x400) +#define SUNXI_UART2_BASE (SUNXI_UART0_BASE + 0x800) +#define SUNXI_UART3_BASE (SUNXI_UART0_BASE + 0xc00) + +#endif /* SUNXI_SERIAL_MEMMAP_H */ diff --git a/arch/arm/include/asm/arch-sunxi/timer.h b/arch/arm/include/asm/arch-sunxi/timer.h index bb5626d893..e17db8588e 100644 --- a/arch/arm/include/asm/arch-sunxi/timer.h +++ b/arch/arm/include/asm/arch-sunxi/timer.h @@ -76,7 +76,7 @@ struct sunxi_timer_reg { struct sunxi_tgp tgp[4]; u8 res5[8]; u32 cpu_cfg; -#elif defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6) +#elif defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6) || defined(CONFIG_SUNXI_GEN_NCAT2) u8 res3[16]; struct sunxi_wdog wdog[5]; /* We have 5 watchdogs */ #endif diff --git a/arch/arm/include/asm/mach-imx/ahab.h b/arch/arm/include/asm/mach-imx/ahab.h index 4222e3db27..4884f05625 100644 --- a/arch/arm/include/asm/mach-imx/ahab.h +++ b/arch/arm/include/asm/mach-imx/ahab.h @@ -6,7 +6,7 @@ #ifndef __IMX_AHAB_H__ #define __IMX_AHAB_H__ -#include <asm/mach-imx/image.h> +#include <imx_container.h> int ahab_auth_cntr_hdr(struct container_hdr *container, u16 length); int ahab_auth_release(void); diff --git a/arch/arm/include/asm/mach-imx/image.h b/arch/arm/include/asm/mach-imx/image.h deleted file mode 100644 index ee67ca96f4..0000000000 --- a/arch/arm/include/asm/mach-imx/image.h +++ /dev/null @@ -1,69 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright 2018-2019 NXP - */ - -#ifndef __CONTAINER_HEADER_H_ -#define __CONTAINER_HEADER_H_ - -#include <linux/sizes.h> -#include <linux/types.h> - -#define IV_MAX_LEN 32 -#define HASH_MAX_LEN 64 - -#define CONTAINER_HDR_ALIGNMENT 0x400 -#define CONTAINER_HDR_EMMC_OFFSET 0 -#define CONTAINER_HDR_MMCSD_OFFSET SZ_32K -#define CONTAINER_HDR_QSPI_OFFSET SZ_4K -#define CONTAINER_HDR_NAND_OFFSET SZ_128M - -struct container_hdr { - u8 version; - u8 length_lsb; - u8 length_msb; - u8 tag; - u32 flags; - u16 sw_version; - u8 fuse_version; - u8 num_images; - u16 sig_blk_offset; - u16 reserved; -} __packed; - -struct boot_img_t { - u32 offset; - u32 size; - u64 dst; - u64 entry; - u32 hab_flags; - u32 meta; - u8 hash[HASH_MAX_LEN]; - u8 iv[IV_MAX_LEN]; -} __packed; - -struct signature_block_hdr { - u8 version; - u8 length_lsb; - u8 length_msb; - u8 tag; - u16 srk_table_offset; - u16 cert_offset; - u16 blob_offset; - u16 signature_offset; - u32 reserved; -} __packed; - -struct generate_key_blob_hdr { - u8 version; - u8 length_lsb; - u8 length_msb; - u8 tag; - u8 flags; - u8 size; - u8 algorithm; - u8 mode; -} __packed; - -int get_container_size(ulong addr, u16 *header_length); -#endif diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index 4c65fc0dbd..37ef2d691d 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig @@ -204,6 +204,17 @@ config TARGET_SAMA5D27_WLSOM1_EK processor-based SAMA5D2 MPU with 2 Gbit LPDDR2-SDRAM in a single package. +config TARGET_KSTR_SAMA5D27 + bool "Conclusive KSTR-SAMA5D27 board" + select BOARD_EARLY_INIT_F + select SAMA5D2 + help + The KSTR-SAMA5D27 embeds SAMA5D27 SoC, together with + 256 MiB SDRAM, 10/100 Mbit/s Ethernet, 96 Mbit/s Wi-Fi b/g/n, + Bluetooth 4.1 LE, USB OTG controller w/ type-C USB connector + and stackable GPIO headers in an all-in-one SBC form factor: + https://conclusive.pl/products/kstr-sama5d27-sbc/ + config TARGET_SAMA5D2_ICP bool "SAMA5D2 Industrial Connectivity Platform (ICP)" select SAMA5D2 @@ -364,6 +375,7 @@ source "board/atmel/sama5d4_xplained/Kconfig" source "board/atmel/sama5d4ek/Kconfig" source "board/bluewater/gurnard/Kconfig" source "board/calao/usb_a9263/Kconfig" +source "board/conclusive/kstr-sama5d27/Kconfig" source "board/egnite/ethernut5/Kconfig" source "board/esd/meesc/Kconfig" source "board/gardena/smart-gateway-at91sam/Kconfig" diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 44e1e1628b..abd48d4258 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -194,19 +194,6 @@ config IMX_DCD_ADDR This information is shared with the user via mkimage -l just so the image can be signed. -config SPL_LOAD_IMX_CONTAINER - bool "Enable SPL loading U-Boot as a i.MX Container image" - depends on SPL - help - This is to let SPL could load i.MX Container image - -config IMX_CONTAINER_CFG - string "i.MX Container config file" - depends on SPL - help - This is to specific the cfg file for generating container - image which will be loaded by SPL. - config IOMUX_LPSR bool diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index 6904cf3880..a3b44c93e3 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -79,7 +79,7 @@ obj-$(CONFIG_CMD_NANDBCB) += cmd_nandbcb.o endif ifeq ($(CONFIG_SPL_BUILD),y) -obj-$(CONFIG_SPL_LOAD_IMX_CONTAINER) += image-container.o parse-container.o +obj-$(CONFIG_SPL_LOAD_IMX_CONTAINER) += image-container.o endif ifeq ($(SOC),$(filter $(SOC),imx8ulp imx9)) diff --git a/arch/arm/mach-imx/cmd_dek.c b/arch/arm/mach-imx/cmd_dek.c index 6fa5b41fcd..2f389dbe8d 100644 --- a/arch/arm/mach-imx/cmd_dek.c +++ b/arch/arm/mach-imx/cmd_dek.c @@ -18,12 +18,12 @@ #include <mapmem.h> #include <tee.h> #ifdef CONFIG_IMX_SECO_DEK_ENCAP +#include <imx_container.h> #include <firmware/imx/sci/sci.h> -#include <asm/mach-imx/image.h> #endif #ifdef CONFIG_IMX_ELE_DEK_ENCAP +#include <imx_container.h> #include <asm/mach-imx/ele_api.h> -#include <asm/mach-imx/image.h> #endif #include <cpu_func.h> diff --git a/arch/arm/mach-imx/ele_ahab.c b/arch/arm/mach-imx/ele_ahab.c index 785b0d6ec3..295c055ad0 100644 --- a/arch/arm/mach-imx/ele_ahab.c +++ b/arch/arm/mach-imx/ele_ahab.c @@ -6,12 +6,12 @@ #include <common.h> #include <command.h> #include <errno.h> +#include <imx_container.h> #include <asm/io.h> #include <asm/mach-imx/ele_api.h> #include <asm/mach-imx/sys_proto.h> #include <asm/arch-imx/cpu.h> #include <asm/arch/sys_proto.h> -#include <asm/mach-imx/image.h> #include <console.h> #include <cpu_func.h> #include <asm/global_data.h> @@ -343,7 +343,7 @@ int authenticate_os_container(ulong addr) } phdr = (struct container_hdr *)addr; - if (phdr->tag != 0x87 || phdr->version != 0x0) { + if (!valid_container_hdr(phdr)) { printf("Error: Wrong container header\n"); return -EFAULT; } diff --git a/arch/arm/mach-imx/image-container.c b/arch/arm/mach-imx/image-container.c index 0285bbdaf2..c9455fe222 100644 --- a/arch/arm/mach-imx/image-container.c +++ b/arch/arm/mach-imx/image-container.c @@ -5,6 +5,7 @@ #include <common.h> #include <errno.h> +#include <imx_container.h> #include <log.h> #include <malloc.h> #include <asm/io.h> @@ -12,7 +13,6 @@ #include <spi_flash.h> #include <spl.h> #include <nand.h> -#include <asm/mach-imx/image.h> #include <asm/arch/sys_proto.h> #include <asm/mach-imx/boot_mode.h> @@ -50,7 +50,7 @@ int get_container_size(ulong addr, u16 *header_length) u32 max_offset = 0, img_end; phdr = (struct container_hdr *)addr; - if (phdr->tag != 0x87 || phdr->version != 0x0) { + if (!valid_container_hdr(phdr)) { debug("Wrong container header\n"); return -EFAULT; } diff --git a/arch/arm/mach-imx/imx8/ahab.c b/arch/arm/mach-imx/imx8/ahab.c index b58b14ca9b..994becccef 100644 --- a/arch/arm/mach-imx/imx8/ahab.c +++ b/arch/arm/mach-imx/imx8/ahab.c @@ -6,6 +6,7 @@ #include <common.h> #include <command.h> #include <errno.h> +#include <imx_container.h> #include <log.h> #include <asm/global_data.h> #include <asm/io.h> @@ -13,7 +14,6 @@ #include <asm/mach-imx/sys_proto.h> #include <asm/arch-imx/cpu.h> #include <asm/arch/sys_proto.h> -#include <asm/mach-imx/image.h> #include <console.h> #include <cpu_func.h> #include "u-boot/sha256.h" @@ -146,7 +146,7 @@ int authenticate_os_container(ulong addr) } phdr = (struct container_hdr *)addr; - if (phdr->tag != 0x87 && phdr->version != 0x0) { + if (!valid_container_hdr(phdr)) { printf("Error: Wrong container header\n"); return -EFAULT; } diff --git a/arch/arm/mach-imx/parse-container.c b/arch/arm/mach-imx/parse-container.c deleted file mode 100644 index e2a9e2b273..0000000000 --- a/arch/arm/mach-imx/parse-container.c +++ /dev/null @@ -1,157 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright 2018-2021 NXP - */ - -#include <common.h> -#include <stdlib.h> -#include <errno.h> -#include <log.h> -#include <spl.h> -#include <asm/mach-imx/image.h> -#ifdef CONFIG_AHAB_BOOT -#include <asm/mach-imx/ahab.h> -#endif - -static struct boot_img_t *read_auth_image(struct spl_image_info *spl_image, - struct spl_load_info *info, - struct container_hdr *container, - int image_index, - u32 container_sector) -{ - struct boot_img_t *images; - ulong sector; - u32 sectors; - - if (image_index > container->num_images) { - debug("Invalid image number\n"); - return NULL; - } - - images = (struct boot_img_t *)((u8 *)container + - sizeof(struct container_hdr)); - - if (images[image_index].offset % info->bl_len) { - printf("%s: image%d offset not aligned to %u\n", - __func__, image_index, info->bl_len); - return NULL; - } - - sectors = roundup(images[image_index].size, info->bl_len) / - info->bl_len; - sector = images[image_index].offset / info->bl_len + - container_sector; - - debug("%s: container: %p sector: %lu sectors: %u\n", __func__, - container, sector, sectors); - if (info->read(info, sector, sectors, - (void *)images[image_index].entry) != sectors) { - printf("%s wrong\n", __func__); - return NULL; - } - -#ifdef CONFIG_AHAB_BOOT - if (ahab_verify_cntr_image(&images[image_index], image_index)) - return NULL; -#endif - - return &images[image_index]; -} - -static int read_auth_container(struct spl_image_info *spl_image, - struct spl_load_info *info, ulong sector) -{ - struct container_hdr *container = NULL; - u16 length; - u32 sectors; - int i, size, ret = 0; - - size = roundup(CONTAINER_HDR_ALIGNMENT, info->bl_len); - sectors = size / info->bl_len; - - /* - * It will not override the ATF code, so safe to use it here, - * no need malloc - */ - container = malloc(size); - if (!container) - return -ENOMEM; - - debug("%s: container: %p sector: %lu sectors: %u\n", __func__, - container, sector, sectors); - if (info->read(info, sector, sectors, container) != sectors) { - ret = -EIO; - goto end; - } - - if (container->tag != 0x87 && container->version != 0x0) { - printf("Wrong container header"); - ret = -ENOENT; - goto end; - } - - if (!container->num_images) { - printf("Wrong container, no image found"); - ret = -ENOENT; - goto end; - } - - length = container->length_lsb + (container->length_msb << 8); - debug("Container length %u\n", length); - - if (length > CONTAINER_HDR_ALIGNMENT) { - size = roundup(length, info->bl_len); - sectors = size / info->bl_len; - - free(container); - container = malloc(size); - if (!container) - return -ENOMEM; - - debug("%s: container: %p sector: %lu sectors: %u\n", - __func__, container, sector, sectors); - if (info->read(info, sector, sectors, container) != - sectors) { - ret = -EIO; - goto end; - } - } - -#ifdef CONFIG_AHAB_BOOT - ret = ahab_auth_cntr_hdr(container, length); - if (ret) - goto end_auth; -#endif - - for (i = 0; i < container->num_images; i++) { - struct boot_img_t *image = read_auth_image(spl_image, info, - container, i, - sector); - - if (!image) { - ret = -EINVAL; - goto end_auth; - } - - if (i == 0) { - spl_image->load_addr = image->dst; - spl_image->entry_point = image->entry; - } - } - -end_auth: -#ifdef CONFIG_AHAB_BOOT - ahab_auth_release(); -#endif - -end: - free(container); - - return ret; -} - -int spl_load_imx_container(struct spl_image_info *spl_image, - struct spl_load_info *info, ulong sector) -{ - return read_auth_container(spl_image, info, sector); -} diff --git a/arch/arm/mach-imx/spl_imx_romapi.c b/arch/arm/mach-imx/spl_imx_romapi.c index c4a4185eed..93d48e56ac 100644 --- a/arch/arm/mach-imx/spl_imx_romapi.c +++ b/arch/arm/mach-imx/spl_imx_romapi.c @@ -6,11 +6,11 @@ #include <common.h> #include <errno.h> #include <image.h> +#include <imx_container.h> #include <log.h> #include <asm/global_data.h> #include <linux/libfdt.h> #include <spl.h> -#include <asm/mach-imx/image.h> #include <asm/arch/sys_proto.h> DECLARE_GLOBAL_DATA_PTR; @@ -111,7 +111,8 @@ static int spl_romapi_load_image_seekable(struct spl_image_info *spl_image, load.read = spl_romapi_read_seekable; load.priv = &pagesize; return spl_load_simple_fit(spl_image, &load, offset / pagesize, header); - } else if (IS_ENABLED(CONFIG_SPL_LOAD_IMX_CONTAINER)) { + } else if (IS_ENABLED(CONFIG_SPL_LOAD_IMX_CONTAINER) && + valid_container_hdr((void *)header)) { struct spl_load_info load; memset(&load, 0, sizeof(load)); @@ -202,7 +203,8 @@ static u8 *search_container_header(u8 *p, int size) for (i = 0; i < size; i += 4) { hdr = p + i; - if (*(hdr + 3) == 0x87 && *hdr == 0 && (*(hdr + 1) != 0 || *(hdr + 2) != 0)) + if (valid_container_hdr((void *)hdr) && + (*(hdr + 1) != 0 || *(hdr + 2) != 0)) return p + i; } diff --git a/arch/arm/mach-rmobile/Kconfig b/arch/arm/mach-rmobile/Kconfig index 714eb4405b..2bb96749fc 100644 --- a/arch/arm/mach-rmobile/Kconfig +++ b/arch/arm/mach-rmobile/Kconfig @@ -77,6 +77,7 @@ config RZG2L imply PINCTRL_RZG2L imply RENESAS_SDHI imply RZG2L_GPIO + imply SCIF_CONSOLE imply SYS_MALLOC_F help Enable support for the Renesas RZ/G2L family of SoCs. Currently diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig index 9d5df2c102..40ca7d7b3a 100644 --- a/arch/arm/mach-sunxi/Kconfig +++ b/arch/arm/mach-sunxi/Kconfig @@ -121,7 +121,7 @@ config AXP_PMIC_BUS config SUNXI_SRAM_ADDRESS hex default 0x10000 if MACH_SUN9I || MACH_SUN50I || MACH_SUN50I_H5 - default 0x20000 if SUN50I_GEN_H6 + default 0x20000 if SUN50I_GEN_H6 || SUNXI_GEN_NCAT2 default 0x0 ---help--- Older Allwinner SoCs have their mask boot ROM mapped just below 4GB, @@ -183,6 +183,14 @@ config SUN50I_GEN_H6 Select this for sunxi SoCs which have H6 like peripherals, clocks and memory map. +config SUNXI_GEN_NCAT2 + bool + select MMC_SUNXI_HAS_NEW_MODE + select SUPPORT_SPL + ---help--- + Select this for sunxi SoCs which have D1 like peripherals, clocks + and memory map. + config SUNXI_DRAM_DW bool ---help--- @@ -338,6 +346,19 @@ config MACH_SUN8I_R40 select SUNXI_DRAM_DW_32BIT imply SPL_SYS_I2C_LEGACY +config MACH_SUN8I_R528 + bool "sun8i (Allwinner R528)" + select CPU_V7A + select CPU_V7_HAS_NONSEC + select CPU_V7_HAS_VIRT + select ARCH_SUPPORT_PSCI + select SPL_ARMV7_SET_CORTEX_SMPEN + select SUNXI_GEN_NCAT2 + select SUNXI_NEW_PINCTRL + select MMC_SUNXI_HAS_NEW_MODE + select SUPPORT_SPL + select DRAM_SUN20I_D1 + config MACH_SUN8I_V3S bool "sun8i (Allwinner V3/V3s/S3/S3L)" select CPU_V7A @@ -648,6 +669,7 @@ config SYS_CLK_FREQ default 1008000000 if MACH_SUN9I default 888000000 if MACH_SUN50I_H6 default 1008000000 if MACH_SUN50I_H616 + default 1008000000 if MACH_SUN8I_R528 config SYS_CONFIG_NAME default "suniv" if MACH_SUNIV @@ -656,6 +678,7 @@ config SYS_CONFIG_NAME default "sun6i" if MACH_SUN6I default "sun7i" if MACH_SUN7I default "sun8i" if MACH_SUN8I + default "sun8i" if MACH_SUN8I_R528 default "sun9i" if MACH_SUN9I default "sun50i" if MACH_SUN50I default "sun50i" if MACH_SUN50I_H6 @@ -695,13 +718,6 @@ config OLD_SUNXI_KERNEL_COMPAT Set this to enable various workarounds for old kernels, this results in sub-optimal settings for newer kernels, only enable if needed. -config MACPWR - string "MAC power pin" - default "" - help - Set the pin used to power the MAC. This takes a string in the format - understood by sunxi_name_to_gpio, e.g. PH1 for pin 1 of port H. - config MMC1_PINS_PH bool "Pins for mmc1 are on Port H" depends on MACH_SUN4I || MACH_SUN7I || MACH_SUN8I_R40 @@ -811,6 +827,7 @@ config VIDEO_SUNXI depends on !MACH_SUN9I depends on !MACH_SUN50I depends on !SUN50I_GEN_H6 + depends on !SUNXI_GEN_NCAT2 select VIDEO select DISPLAY imply VIDEO_DT_SIMPLEFB @@ -1008,14 +1025,6 @@ config VIDEO_LCD_TL059WV5C0 endchoice -config SATAPWR - string "SATA power pin" - default "" - help - Set the pins used to power the SATA. This takes a string in the - format understood by sunxi_name_to_gpio, e.g. PH1 for pin 1 of - port H. - config GMAC_TX_DELAY int "GMAC Transmit Clock Delay Chain" default 0 @@ -1032,6 +1041,7 @@ config SPL_STACK_R_ADDR default 0x2fe00000 if MACH_SUN9I default 0x4fe00000 if MACH_SUN50I default 0x4fe00000 if SUN50I_GEN_H6 + default 0x4fe00000 if SUNXI_GEN_NCAT2 config SPL_SPI_SUNXI bool "Support for SPI Flash on Allwinner SoCs in SPL" diff --git a/arch/arm/mach-sunxi/Makefile b/arch/arm/mach-sunxi/Makefile index 58f807cb82..1d4c70ec35 100644 --- a/arch/arm/mach-sunxi/Makefile +++ b/arch/arm/mach-sunxi/Makefile @@ -10,7 +10,6 @@ obj-y += board.o obj-y += clock.o obj-y += cpu_info.o obj-y += dram_helpers.o -obj-y += pinmux.o obj-$(CONFIG_SUN6I_PRCM) += prcm.o obj-$(CONFIG_AXP_PMIC_BUS) += pmic_bus.o obj-$(CONFIG_MACH_SUNIV) += clock_sun6i.o @@ -26,6 +25,7 @@ obj-$(CONFIG_MACH_SUN8I) += clock_sun6i.o endif obj-$(CONFIG_MACH_SUN9I) += clock_sun9i.o gtbus_sun9i.o obj-$(CONFIG_SUN50I_GEN_H6) += clock_sun50i_h6.o +obj-$(CONFIG_SUNXI_GEN_NCAT2) += clock_sun50i_h6.o ifndef CONFIG_ARM64 obj-y += timer.o endif diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c index 61a4245c49..11a4941822 100644 --- a/arch/arm/mach-sunxi/board.c +++ b/arch/arm/mach-sunxi/board.c @@ -17,6 +17,7 @@ #include <i2c.h> #include <serial.h> #include <spl.h> +#include <sunxi_gpio.h> #include <asm/cache.h> #include <asm/gpio.h> #include <asm/io.h> @@ -146,6 +147,10 @@ static int gpio_init(void) sunxi_gpio_set_cfgpin(SUNXI_GPH(12), SUN9I_GPH_UART0); sunxi_gpio_set_cfgpin(SUNXI_GPH(13), SUN9I_GPH_UART0); sunxi_gpio_set_pull(SUNXI_GPH(13), SUNXI_GPIO_PULL_UP); +#elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_MACH_SUN8I_R528) + sunxi_gpio_set_cfgpin(SUNXI_GPE(2), 6); + sunxi_gpio_set_cfgpin(SUNXI_GPE(3), 6); + sunxi_gpio_set_pull(SUNXI_GPE(3), SUNXI_GPIO_PULL_UP); #elif CONFIG_CONS_INDEX == 2 && defined(CONFIG_MACH_SUNIV) sunxi_gpio_set_cfgpin(SUNXI_GPA(2), SUNIV_GPE_UART0); sunxi_gpio_set_cfgpin(SUNXI_GPA(3), SUNIV_GPE_UART0); @@ -162,6 +167,10 @@ static int gpio_init(void) sunxi_gpio_set_cfgpin(SUNXI_GPB(0), SUN8I_GPB_UART2); sunxi_gpio_set_cfgpin(SUNXI_GPB(1), SUN8I_GPB_UART2); sunxi_gpio_set_pull(SUNXI_GPB(1), SUNXI_GPIO_PULL_UP); +#elif CONFIG_CONS_INDEX == 4 && defined(CONFIG_MACH_SUN8I_R528) + sunxi_gpio_set_cfgpin(SUNXI_GPB(6), 7); + sunxi_gpio_set_cfgpin(SUNXI_GPB(7), 7); + sunxi_gpio_set_pull(SUNXI_GPB(7), SUNXI_GPIO_PULL_UP); #elif CONFIG_CONS_INDEX == 5 && defined(CONFIG_MACH_SUN8I) sunxi_gpio_set_cfgpin(SUNXI_GPL(2), SUN8I_GPL_R_UART); sunxi_gpio_set_cfgpin(SUNXI_GPL(3), SUN8I_GPL_R_UART); @@ -175,13 +184,19 @@ static int gpio_init(void) #error Unsupported console port number. Please fix pin mux settings in board.c #endif -#ifdef CONFIG_SUN50I_GEN_H6 - /* Update PIO power bias configuration by copy hardware detected value */ - val = readl(SUNXI_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_VAL); - writel(val, SUNXI_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_SEL); - val = readl(SUNXI_R_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_VAL); - writel(val, SUNXI_R_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_SEL); -#endif + /* + * Update PIO power bias configuration by copying the hardware + * detected value. + */ + if (IS_ENABLED(CONFIG_SUN50I_GEN_H6) || + IS_ENABLED(CONFIG_SUN50I_GEN_NCAT2)) { + val = readl(SUNXI_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_VAL); + writel(val, SUNXI_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_SEL); + } + if (IS_ENABLED(CONFIG_SUN50I_GEN_H6)) { + val = readl(SUNXI_R_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_VAL); + writel(val, SUNXI_R_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_SEL); + } return 0; } @@ -480,7 +495,7 @@ void reset_cpu(void) /* sun5i sometimes gets stuck without this */ writel(WDT_MODE_RESET_EN | WDT_MODE_EN, &wdog->mode); } -#elif defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6) +#elif defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6) || defined(CONFIG_SUNXI_GEN_NCAT2) #if defined(CONFIG_MACH_SUN50I_H6) /* WDOG is broken for some H6 rev. use the R_WDOG instead */ static const struct sunxi_wdog *wdog = diff --git a/arch/arm/mach-sunxi/clock_sun50i_h6.c b/arch/arm/mach-sunxi/clock_sun50i_h6.c index 7926394cf7..bea91c78bc 100644 --- a/arch/arm/mach-sunxi/clock_sun50i_h6.c +++ b/arch/arm/mach-sunxi/clock_sun50i_h6.c @@ -18,8 +18,11 @@ void clock_init_safe(void) setbits_le32(&prcm->res_cal_ctrl, 2); } - clrbits_le32(&prcm->res_cal_ctrl, 1); - setbits_le32(&prcm->res_cal_ctrl, 1); + if (IS_ENABLED(CONFIG_MACH_SUN50I_H616) || + IS_ENABLED(CONFIG_MACH_SUN50I_H6)) { + clrbits_le32(&prcm->res_cal_ctrl, 1); + setbits_le32(&prcm->res_cal_ctrl, 1); + } if (IS_ENABLED(CONFIG_MACH_SUN50I_H6)) { /* set key field for ldo enable */ @@ -38,7 +41,9 @@ void clock_init_safe(void) CCM_CPU_AXI_DEFAULT_FACTORS); writel(CCM_PSI_AHB1_AHB2_DEFAULT, &ccm->psi_ahb1_ahb2_cfg); +#ifdef CCM_AHB3_DEFAULT writel(CCM_AHB3_DEFAULT, &ccm->ahb3_cfg); +#endif writel(CCM_APB1_DEFAULT, &ccm->apb1_cfg); /* @@ -86,11 +91,13 @@ void clock_set_pll1(unsigned int clk) writel(val, &ccm->cpu_axi_cfg); /* clk = 24*n/p, p is ignored if clock is >288MHz */ - writel(CCM_PLL1_CTRL_EN | CCM_PLL1_LOCK_EN | CCM_PLL1_CLOCK_TIME_2 | -#ifdef CONFIG_MACH_SUN50I_H616 - CCM_PLL1_OUT_EN | -#endif - CCM_PLL1_CTRL_N(clk / 24000000), &ccm->pll1_cfg); + val = CCM_PLL1_CTRL_EN | CCM_PLL1_LOCK_EN | CCM_PLL1_CLOCK_TIME_2; + val |= CCM_PLL1_CTRL_N(clk / 24000000); + if (IS_ENABLED(CONFIG_MACH_SUN50I_H616)) + val |= CCM_PLL1_OUT_EN; + if (IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2)) + val |= CCM_PLL1_OUT_EN | CCM_PLL1_LDO_EN; + writel(val, &ccm->pll1_cfg); while (!(readl(&ccm->pll1_cfg) & CCM_PLL1_LOCK)) {} /* Switch CPU to PLL1 */ @@ -105,16 +112,26 @@ unsigned int clock_get_pll6(void) { struct sunxi_ccm_reg *const ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; - int m = IS_ENABLED(CONFIG_MACH_SUN50I_H6) ? 4 : 2; - uint32_t rval = readl(&ccm->pll6_cfg); int n = ((rval & CCM_PLL6_CTRL_N_MASK) >> CCM_PLL6_CTRL_N_SHIFT) + 1; - int div1 = ((rval & CCM_PLL6_CTRL_DIV1_MASK) >> - CCM_PLL6_CTRL_DIV1_SHIFT) + 1; int div2 = ((rval & CCM_PLL6_CTRL_DIV2_MASK) >> - CCM_PLL6_CTRL_DIV2_SHIFT) + 1; - /* The register defines PLL6-2X or PLL6-4X, not plain PLL6 */ - return 24000000 / m * n / div1 / div2; + CCM_PLL6_CTRL_DIV2_SHIFT) + 1; + int div1, m; + + if (IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2)) { + div1 = ((rval & CCM_PLL6_CTRL_P0_MASK) >> + CCM_PLL6_CTRL_P0_SHIFT) + 1; + m = 1; + } else { + div1 = ((rval & CCM_PLL6_CTRL_DIV1_MASK) >> + CCM_PLL6_CTRL_DIV1_SHIFT) + 1; + if (IS_ENABLED(CONFIG_MACH_SUN50I_H6)) + m = 4; + else + m = 2; + } + + return 24000000U * n / m / div1 / div2; } int clock_twi_onoff(int port, int state) diff --git a/arch/arm/mach-sunxi/cpu_info.c b/arch/arm/mach-sunxi/cpu_info.c index 7eef178859..7fecc3b88d 100644 --- a/arch/arm/mach-sunxi/cpu_info.c +++ b/arch/arm/mach-sunxi/cpu_info.c @@ -93,6 +93,8 @@ int print_cpuinfo(void) printf("CPU: Allwinner R40 (SUN8I %04x)\n", sunxi_get_sram_id()); #elif defined CONFIG_MACH_SUN8I_V3S printf("CPU: Allwinner V3s (SUN8I %04x)\n", sunxi_get_sram_id()); +#elif defined CONFIG_MACH_SUN8I_R528 + puts("CPU: Allwinner R528 (SUN8I)\n"); #elif defined CONFIG_MACH_SUN9I puts("CPU: Allwinner A80 (SUN9I)\n"); #elif defined CONFIG_MACH_SUN50I diff --git a/arch/arm/mach-sunxi/dram_suniv.c b/arch/arm/mach-sunxi/dram_suniv.c index 3aa3ce7627..9e583e1855 100644 --- a/arch/arm/mach-sunxi/dram_suniv.c +++ b/arch/arm/mach-sunxi/dram_suniv.c @@ -13,10 +13,10 @@ #include <asm/io.h> #include <asm/arch/clock.h> #include <asm/arch/dram.h> -#include <asm/arch/gpio.h> #include <linux/bitops.h> #include <linux/delay.h> #include <hang.h> +#include <sunxi_gpio.h> #define SDR_T_CAS (0x2) #define SDR_T_RAS (0x8) diff --git a/arch/arm/mach-sunxi/gtbus_sun9i.c b/arch/arm/mach-sunxi/gtbus_sun9i.c index cf011c4cfa..5624621b50 100644 --- a/arch/arm/mach-sunxi/gtbus_sun9i.c +++ b/arch/arm/mach-sunxi/gtbus_sun9i.c @@ -8,6 +8,7 @@ #include <common.h> #include <asm/io.h> +#include <asm/arch/cpu.h> #include <asm/arch/gtbus_sun9i.h> #include <asm/arch/sys_proto.h> diff --git a/arch/arm/mach-sunxi/pinmux.c b/arch/arm/mach-sunxi/pinmux.c deleted file mode 100644 index c95fcee9f6..0000000000 --- a/arch/arm/mach-sunxi/pinmux.c +++ /dev/null @@ -1,78 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * (C) Copyright 2007-2011 - * Allwinner Technology Co., Ltd. <www.allwinnertech.com> - * Tom Cubie <tangliang@allwinnertech.com> - */ - -#include <common.h> -#include <asm/io.h> -#include <asm/arch/gpio.h> - -void sunxi_gpio_set_cfgbank(struct sunxi_gpio *pio, int bank_offset, u32 val) -{ - u32 index = GPIO_CFG_INDEX(bank_offset); - u32 offset = GPIO_CFG_OFFSET(bank_offset); - - clrsetbits_le32(&pio->cfg[index], 0xf << offset, val << offset); -} - -void sunxi_gpio_set_cfgpin(u32 pin, u32 val) -{ - u32 bank = GPIO_BANK(pin); - struct sunxi_gpio *pio = BANK_TO_GPIO(bank); - - sunxi_gpio_set_cfgbank(pio, pin, val); -} - -int sunxi_gpio_get_cfgbank(struct sunxi_gpio *pio, int bank_offset) -{ - u32 index = GPIO_CFG_INDEX(bank_offset); - u32 offset = GPIO_CFG_OFFSET(bank_offset); - u32 cfg; - - cfg = readl(&pio->cfg[index]); - cfg >>= offset; - - return cfg & 0xf; -} - -int sunxi_gpio_get_cfgpin(u32 pin) -{ - u32 bank = GPIO_BANK(pin); - struct sunxi_gpio *pio = BANK_TO_GPIO(bank); - - return sunxi_gpio_get_cfgbank(pio, pin); -} - -void sunxi_gpio_set_drv(u32 pin, u32 val) -{ - u32 bank = GPIO_BANK(pin); - struct sunxi_gpio *pio = BANK_TO_GPIO(bank); - - sunxi_gpio_set_drv_bank(pio, pin, val); -} - -void sunxi_gpio_set_drv_bank(struct sunxi_gpio *pio, u32 bank_offset, u32 val) -{ - u32 index = GPIO_DRV_INDEX(bank_offset); - u32 offset = GPIO_DRV_OFFSET(bank_offset); - - clrsetbits_le32(&pio->drv[index], 0x3 << offset, val << offset); -} - -void sunxi_gpio_set_pull(u32 pin, u32 val) -{ - u32 bank = GPIO_BANK(pin); - struct sunxi_gpio *pio = BANK_TO_GPIO(bank); - - sunxi_gpio_set_pull_bank(pio, pin, val); -} - -void sunxi_gpio_set_pull_bank(struct sunxi_gpio *pio, int bank_offset, u32 val) -{ - u32 index = GPIO_PULL_INDEX(bank_offset); - u32 offset = GPIO_PULL_OFFSET(bank_offset); - - clrsetbits_le32(&pio->pull[index], 0x3 << offset, val << offset); -} diff --git a/arch/arm/mach-sunxi/spl_spi_sunxi.c b/arch/arm/mach-sunxi/spl_spi_sunxi.c index 81159cfee6..c2410dd7bb 100644 --- a/arch/arm/mach-sunxi/spl_spi_sunxi.c +++ b/arch/arm/mach-sunxi/spl_spi_sunxi.c @@ -13,6 +13,7 @@ #include <linux/bitops.h> #include <linux/delay.h> #include <linux/libfdt.h> +#include <sunxi_gpio.h> #ifdef CONFIG_SPL_OS_BOOT #error CONFIG_SPL_OS_BOOT is not supported yet diff --git a/arch/arm/mach-sunxi/timer.c b/arch/arm/mach-sunxi/timer.c index fc9d419a25..9a6f6c06d8 100644 --- a/arch/arm/mach-sunxi/timer.c +++ b/arch/arm/mach-sunxi/timer.c @@ -10,6 +10,7 @@ #include <time.h> #include <asm/global_data.h> #include <asm/io.h> +#include <asm/arch/cpu.h> #include <asm/arch/timer.h> #include <linux/delay.h> diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 183885ebe7..e291456530 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -187,6 +187,97 @@ config RISCV_ISA_D riscv32 ABI from ilp32 to ilp32d and the riscv64 ABI from lp64 to lp64d. +config RISCV_ISA_ZBB + bool "Zbb extension support for bit manipulation instructions" + help + Adds ZBB extension (basic bit manipulation) to the ISA subsets + that the toolchain is allowed to emit when building U-Boot. + The Zbb extension provides instructions to accelerate a number + of bit-specific operations (count bit population, sign extending, + bitrotation, etc) and enables optimized string routines. + +menu "Use assembly optimized implementation of string routines" + +config USE_ARCH_STRLEN + bool "Use an assembly optimized implementation of strlen" + default y + depends on RISCV_ISA_ZBB + help + Enable the generation of an optimized version of strlen using + Zbb extension. + +config SPL_USE_ARCH_STRLEN + bool "Use an assembly optimized implementation of strlen for SPL" + default y if USE_ARCH_STRLEN + depends on RISCV_ISA_ZBB + depends on SPL + help + Enable the generation of an optimized version of strlen using + Zbb extension. + +config TPL_USE_ARCH_STRLEN + bool "Use an assembly optimized implementation of strlen for TPL" + default y if USE_ARCH_STRLEN + depends on RISCV_ISA_ZBB + depends on TPL + help + Enable the generation of an optimized version of strlen using + Zbb extension. + +config USE_ARCH_STRCMP + bool "Use an assembly optimized implementation of strcmp" + default y + depends on RISCV_ISA_ZBB + help + Enable the generation of an optimized version of strcmp using + Zbb extension. + +config SPL_USE_ARCH_STRCMP + bool "Use an assembly optimized implementation of strcmp for SPL" + default y if USE_ARCH_STRCMP + depends on RISCV_ISA_ZBB + depends on SPL + help + Enable the generation of an optimized version of strcmp using + Zbb extension. + +config TPL_USE_ARCH_STRCMP + bool "Use an assembly optimized implementation of strcmp for TPL" + default y if USE_ARCH_STRCMP + depends on RISCV_ISA_ZBB + depends on TPL + help + Enable the generation of an optimized version of strcmp using + Zbb extension. + +config USE_ARCH_STRNCMP + bool "Use an assembly optimized implementation of strncmp" + default y + depends on RISCV_ISA_ZBB + help + Enable the generation of an optimized version of strncmp using + Zbb extension. + +config SPL_USE_ARCH_STRNCMP + bool "Use an assembly optimized implementation of strncmp for SPL" + default y if USE_ARCH_STRNCMP + depends on RISCV_ISA_ZBB + depends on SPL + help + Enable the generation of an optimized version of strncmp using + Zbb extension. + +config TPL_USE_ARCH_STRNCMP + bool "Use an assembly optimized implementation of strncmp for TPL" + default y if USE_ARCH_STRNCMP + depends on RISCV_ISA_ZBB + depends on TPL + help + Enable the generation of an optimized version of strncmp using + Zbb extension. + +endmenu + config RISCV_ISA_A def_bool y @@ -424,4 +515,12 @@ config TPL_USE_ARCH_MEMSET endmenu +config SPL_LOAD_FIT_OPENSBI_OS_BOOT + bool "Enable SPL (OpenSBI OS boot mode) applying linux from FIT" + depends on SPL_LOAD_FIT + help + Use fw_dynamic from the FIT image, and u-boot SPL will invoke it directly. + This is a shortcut boot flow, from u-boot SPL -> OpenSBI -> u-boot proper + -> linux to u-boot SPL -> OpenSBI -> linux. + endmenu diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile index 4963b5109b..b3ef87078b 100644 --- a/arch/riscv/Makefile +++ b/arch/riscv/Makefile @@ -24,6 +24,9 @@ endif ifeq ($(CONFIG_RISCV_ISA_C),y) ARCH_C = c endif +ifeq ($(CONFIG_RISCV_ISA_ZBB),y) + ARCH_ZBB = _zbb +endif ifeq ($(CONFIG_CMODEL_MEDLOW),y) CMODEL = medlow endif @@ -32,7 +35,7 @@ ifeq ($(CONFIG_CMODEL_MEDANY),y) endif -RISCV_MARCH = $(ARCH_BASE)$(ARCH_A)$(ARCH_F)$(ARCH_D)$(ARCH_C) +RISCV_MARCH = $(ARCH_BASE)$(ARCH_A)$(ARCH_F)$(ARCH_D)$(ARCH_C)$(ARCH_ZBB) ABI = $(ABI_BASE)$(ABI_D) # Newer binutils versions default to ISA spec version 20191213 which moves some diff --git a/arch/riscv/cpu/generic/dram.c b/arch/riscv/cpu/generic/dram.c index 94d8018407..1b51bae9b6 100644 --- a/arch/riscv/cpu/generic/dram.c +++ b/arch/riscv/cpu/generic/dram.c @@ -20,19 +20,3 @@ int dram_init_banksize(void) { return fdtdec_setup_memory_banksize(); } - -phys_addr_t board_get_usable_ram_top(phys_size_t total_size) -{ - /* - * Ensure that we run from first 4GB so that all - * addresses used by U-Boot are 32bit addresses. - * - * This in-turn ensures that 32bit DMA capable - * devices work fine because DMA mapping APIs will - * provide 32bit DMA addresses only. - */ - if (gd->ram_top >= SZ_4G) - return SZ_4G - 1; - - return gd->ram_top; -} diff --git a/arch/riscv/dts/binman.dtsi b/arch/riscv/dts/binman.dtsi index 156cb00971..6b4eb8dc7b 100644 --- a/arch/riscv/dts/binman.dtsi +++ b/arch/riscv/dts/binman.dtsi @@ -5,6 +5,9 @@ #include <config.h> +#define U64_TO_U32_H(addr) (((addr) >> 32) & 0xffffffff) +#define U64_TO_U32_L(addr) ((addr) & 0xffffffff) + / { binman: binman { multiple-images; @@ -13,26 +16,47 @@ &binman { itb { + +#ifndef CONFIG_SPL_LOAD_FIT_OPENSBI_OS_BOOT filename = "u-boot.itb"; +#else + filename = "linux.itb"; +#endif fit { description = "Configuration to load OpenSBI before U-Boot"; - #address-cells = <1>; + #address-cells = <2>; fit,fdt-list = "of-list"; images { +#ifndef CONFIG_SPL_LOAD_FIT_OPENSBI_OS_BOOT uboot { description = "U-Boot"; type = "standalone"; os = "U-Boot"; arch = "riscv"; compression = "none"; - load = <CONFIG_TEXT_BASE>; + load = <U64_TO_U32_H(CONFIG_TEXT_BASE) + U64_TO_U32_L(CONFIG_TEXT_BASE)>; uboot_blob: blob-ext { filename = "u-boot-nodtb.bin"; }; }; +#else + linux { + description = "Linux"; + type = "standalone"; + os = "Linux"; + arch = "riscv"; + compression = "none"; + load = <CONFIG_TEXT_BASE>; + + linux_blob: blob-ext { + filename = "Image"; + }; + }; +#endif opensbi { description = "OpenSBI fw_dynamic Firmware"; @@ -40,8 +64,10 @@ os = "opensbi"; arch = "riscv"; compression = "none"; - load = <CONFIG_SPL_OPENSBI_LOAD_ADDR>; - entry = <CONFIG_SPL_OPENSBI_LOAD_ADDR>; + load = <U64_TO_U32_H(CONFIG_SPL_OPENSBI_LOAD_ADDR) + U64_TO_U32_L(CONFIG_SPL_OPENSBI_LOAD_ADDR)>; + entry = <U64_TO_U32_H(CONFIG_SPL_OPENSBI_LOAD_ADDR) + U64_TO_U32_L(CONFIG_SPL_OPENSBI_LOAD_ADDR)>; opensbi_blob: opensbi { filename = "fw_dynamic.bin"; @@ -68,7 +94,11 @@ #endif description = "NAME"; firmware = "opensbi"; +#ifndef CONFIG_SPL_LOAD_FIT_OPENSBI_OS_BOOT loadables = "uboot"; +#else + loadables = "linux"; +#endif #ifndef CONFIG_OF_BOARD fdt = "fdt-SEQ"; #endif diff --git a/arch/riscv/dts/sunxi-d1-t113.dtsi b/arch/riscv/dts/sunxi-d1-t113.dtsi new file mode 100644 index 0000000000..b7156123df --- /dev/null +++ b/arch/riscv/dts/sunxi-d1-t113.dtsi @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: (GPL-2.0+ or MIT) +// Copyright (C) 2021-2022 Samuel Holland <samuel@sholland.org> + +/ { + soc { + dsp_wdt: watchdog@1700400 { + compatible = "allwinner,sun20i-d1-wdt"; + reg = <0x1700400 0x20>; + interrupts = <SOC_PERIPHERAL_IRQ(122) IRQ_TYPE_LEVEL_HIGH>; + clocks = <&dcxo>, <&rtc CLK_OSC32K>; + clock-names = "hosc", "losc"; + status = "reserved"; + }; + }; +}; diff --git a/arch/riscv/dts/sunxi-d1s-t113.dtsi b/arch/riscv/dts/sunxi-d1s-t113.dtsi new file mode 100644 index 0000000000..822f022eec --- /dev/null +++ b/arch/riscv/dts/sunxi-d1s-t113.dtsi @@ -0,0 +1,927 @@ +// SPDX-License-Identifier: (GPL-2.0+ or MIT) +// Copyright (C) 2021-2022 Samuel Holland <samuel@sholland.org> + +#include <dt-bindings/clock/sun6i-rtc.h> +#include <dt-bindings/clock/sun8i-de2.h> +#include <dt-bindings/clock/sun8i-tcon-top.h> +#include <dt-bindings/clock/sun20i-d1-ccu.h> +#include <dt-bindings/clock/sun20i-d1-r-ccu.h> +#include <dt-bindings/interrupt-controller/irq.h> +#include <dt-bindings/reset/sun8i-de2.h> +#include <dt-bindings/reset/sun20i-d1-ccu.h> +#include <dt-bindings/reset/sun20i-d1-r-ccu.h> + +/ { + #address-cells = <1>; + #size-cells = <1>; + + dcxo: dcxo-clk { + compatible = "fixed-clock"; + clock-output-names = "dcxo"; + #clock-cells = <0>; + }; + + de: display-engine { + compatible = "allwinner,sun20i-d1-display-engine"; + allwinner,pipelines = <&mixer0>, <&mixer1>; + status = "disabled"; + }; + + soc { + compatible = "simple-bus"; + ranges; + dma-noncoherent; + #address-cells = <1>; + #size-cells = <1>; + + pio: pinctrl@2000000 { + compatible = "allwinner,sun20i-d1-pinctrl"; + reg = <0x2000000 0x800>; + interrupts = <SOC_PERIPHERAL_IRQ(69) IRQ_TYPE_LEVEL_HIGH>, + <SOC_PERIPHERAL_IRQ(71) IRQ_TYPE_LEVEL_HIGH>, + <SOC_PERIPHERAL_IRQ(73) IRQ_TYPE_LEVEL_HIGH>, + <SOC_PERIPHERAL_IRQ(75) IRQ_TYPE_LEVEL_HIGH>, + <SOC_PERIPHERAL_IRQ(77) IRQ_TYPE_LEVEL_HIGH>, + <SOC_PERIPHERAL_IRQ(79) IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_APB0>, + <&dcxo>, + <&rtc CLK_OSC32K>; + clock-names = "apb", "hosc", "losc"; + gpio-controller; + interrupt-controller; + #gpio-cells = <3>; + #interrupt-cells = <3>; + + /omit-if-no-ref/ + can0_pins: can0-pins { + pins = "PB2", "PB3"; + function = "can0"; + }; + + /omit-if-no-ref/ + can1_pins: can1-pins { + pins = "PB4", "PB5"; + function = "can1"; + }; + + /omit-if-no-ref/ + clk_pg11_pin: clk-pg11-pin { + pins = "PG11"; + function = "clk"; + }; + + /omit-if-no-ref/ + dsi_4lane_pins: dsi-4lane-pins { + pins = "PD0", "PD1", "PD2", "PD3", "PD4", "PD5", + "PD6", "PD7", "PD8", "PD9"; + drive-strength = <30>; + function = "dsi"; + }; + + /omit-if-no-ref/ + lcd_rgb666_pins: lcd-rgb666-pins { + pins = "PD0", "PD1", "PD2", "PD3", "PD4", "PD5", + "PD6", "PD7", "PD8", "PD9", "PD10", "PD11", + "PD12", "PD13", "PD14", "PD15", "PD16", "PD17", + "PD18", "PD19", "PD20", "PD21"; + function = "lcd0"; + }; + + /omit-if-no-ref/ + mmc0_pins: mmc0-pins { + pins = "PF0", "PF1", "PF2", "PF3", "PF4", "PF5"; + function = "mmc0"; + }; + + /omit-if-no-ref/ + mmc1_pins: mmc1-pins { + pins = "PG0", "PG1", "PG2", "PG3", "PG4", "PG5"; + function = "mmc1"; + }; + + /omit-if-no-ref/ + mmc2_pins: mmc2-pins { + pins = "PC2", "PC3", "PC4", "PC5", "PC6", "PC7"; + function = "mmc2"; + }; + + /omit-if-no-ref/ + rgmii_pe_pins: rgmii-pe-pins { + pins = "PE0", "PE1", "PE2", "PE3", "PE4", + "PE5", "PE6", "PE7", "PE8", "PE9", + "PE11", "PE12", "PE13", "PE14", "PE15"; + function = "emac"; + }; + + /omit-if-no-ref/ + rmii_pe_pins: rmii-pe-pins { + pins = "PE0", "PE1", "PE2", "PE3", "PE4", + "PE5", "PE6", "PE7", "PE8", "PE9"; + function = "emac"; + }; + + /omit-if-no-ref/ + spi0_pins: spi0-pins { + pins = "PC2", "PC3", "PC4", "PC5"; + function = "spi0"; + }; + + /omit-if-no-ref/ + uart1_pg6_pins: uart1-pg6-pins { + pins = "PG6", "PG7"; + function = "uart1"; + }; + + /omit-if-no-ref/ + uart1_pg8_rts_cts_pins: uart1-pg8-rts-cts-pins { + pins = "PG8", "PG9"; + function = "uart1"; + }; + + /omit-if-no-ref/ + uart3_pb_pins: uart3-pb-pins { + pins = "PB6", "PB7"; + function = "uart3"; + }; + }; + + ccu: clock-controller@2001000 { + compatible = "allwinner,sun20i-d1-ccu"; + reg = <0x2001000 0x1000>; + clocks = <&dcxo>, + <&rtc CLK_OSC32K>, + <&rtc CLK_IOSC>; + clock-names = "hosc", "losc", "iosc"; + #clock-cells = <1>; + #reset-cells = <1>; + }; + + gpadc: adc@2009000 { + compatible = "allwinner,sun20i-d1-gpadc"; + reg = <0x2009000 0x400>; + clocks = <&ccu CLK_BUS_GPADC>; + resets = <&ccu RST_BUS_GPADC>; + interrupts = <SOC_PERIPHERAL_IRQ(57) IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + #io-channel-cells = <1>; + }; + + dmic: dmic@2031000 { + compatible = "allwinner,sun20i-d1-dmic", + "allwinner,sun50i-h6-dmic"; + reg = <0x2031000 0x400>; + interrupts = <SOC_PERIPHERAL_IRQ(24) IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_BUS_DMIC>, + <&ccu CLK_DMIC>; + clock-names = "bus", "mod"; + resets = <&ccu RST_BUS_DMIC>; + dmas = <&dma 8>; + dma-names = "rx"; + status = "disabled"; + #sound-dai-cells = <0>; + }; + + i2s1: i2s@2033000 { + compatible = "allwinner,sun20i-d1-i2s", + "allwinner,sun50i-r329-i2s"; + reg = <0x2033000 0x1000>; + interrupts = <SOC_PERIPHERAL_IRQ(27) IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_BUS_I2S1>, + <&ccu CLK_I2S1>; + clock-names = "apb", "mod"; + resets = <&ccu RST_BUS_I2S1>; + dmas = <&dma 4>, <&dma 4>; + dma-names = "rx", "tx"; + status = "disabled"; + #sound-dai-cells = <0>; + }; + + i2s2: i2s@2034000 { + compatible = "allwinner,sun20i-d1-i2s", + "allwinner,sun50i-r329-i2s"; + reg = <0x2034000 0x1000>; + interrupts = <SOC_PERIPHERAL_IRQ(28) IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_BUS_I2S2>, + <&ccu CLK_I2S2>; + clock-names = "apb", "mod"; + resets = <&ccu RST_BUS_I2S2>; + dmas = <&dma 5>, <&dma 5>; + dma-names = "rx", "tx"; + status = "disabled"; + #sound-dai-cells = <0>; + }; + + timer: timer@2050000 { + compatible = "allwinner,sun20i-d1-timer", + "allwinner,sun8i-a23-timer"; + reg = <0x2050000 0xa0>; + interrupts = <SOC_PERIPHERAL_IRQ(59) IRQ_TYPE_LEVEL_HIGH>, + <SOC_PERIPHERAL_IRQ(60) IRQ_TYPE_LEVEL_HIGH>; + clocks = <&dcxo>; + }; + + wdt: watchdog@20500a0 { + compatible = "allwinner,sun20i-d1-wdt-reset", + "allwinner,sun20i-d1-wdt"; + reg = <0x20500a0 0x20>; + interrupts = <SOC_PERIPHERAL_IRQ(63) IRQ_TYPE_LEVEL_HIGH>; + clocks = <&dcxo>, <&rtc CLK_OSC32K>; + clock-names = "hosc", "losc"; + status = "reserved"; + }; + + uart0: serial@2500000 { + compatible = "snps,dw-apb-uart"; + reg = <0x2500000 0x400>; + reg-io-width = <4>; + reg-shift = <2>; + interrupts = <SOC_PERIPHERAL_IRQ(2) IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_BUS_UART0>; + resets = <&ccu RST_BUS_UART0>; + dmas = <&dma 14>, <&dma 14>; + dma-names = "tx", "rx"; + status = "disabled"; + }; + + uart1: serial@2500400 { + compatible = "snps,dw-apb-uart"; + reg = <0x2500400 0x400>; + reg-io-width = <4>; + reg-shift = <2>; + interrupts = <SOC_PERIPHERAL_IRQ(3) IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_BUS_UART1>; + resets = <&ccu RST_BUS_UART1>; + dmas = <&dma 15>, <&dma 15>; + dma-names = "tx", "rx"; + status = "disabled"; + }; + + uart2: serial@2500800 { + compatible = "snps,dw-apb-uart"; + reg = <0x2500800 0x400>; + reg-io-width = <4>; + reg-shift = <2>; + interrupts = <SOC_PERIPHERAL_IRQ(4) IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_BUS_UART2>; + resets = <&ccu RST_BUS_UART2>; + dmas = <&dma 16>, <&dma 16>; + dma-names = "tx", "rx"; + status = "disabled"; + }; + + uart3: serial@2500c00 { + compatible = "snps,dw-apb-uart"; + reg = <0x2500c00 0x400>; + reg-io-width = <4>; + reg-shift = <2>; + interrupts = <SOC_PERIPHERAL_IRQ(5) IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_BUS_UART3>; + resets = <&ccu RST_BUS_UART3>; + dmas = <&dma 17>, <&dma 17>; + dma-names = "tx", "rx"; + status = "disabled"; + }; + + uart4: serial@2501000 { + compatible = "snps,dw-apb-uart"; + reg = <0x2501000 0x400>; + reg-io-width = <4>; + reg-shift = <2>; + interrupts = <SOC_PERIPHERAL_IRQ(6) IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_BUS_UART4>; + resets = <&ccu RST_BUS_UART4>; + dmas = <&dma 18>, <&dma 18>; + dma-names = "tx", "rx"; + status = "disabled"; + }; + + uart5: serial@2501400 { + compatible = "snps,dw-apb-uart"; + reg = <0x2501400 0x400>; + reg-io-width = <4>; + reg-shift = <2>; + interrupts = <SOC_PERIPHERAL_IRQ(7) IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_BUS_UART5>; + resets = <&ccu RST_BUS_UART5>; + dmas = <&dma 19>, <&dma 19>; + dma-names = "tx", "rx"; + status = "disabled"; + }; + + i2c0: i2c@2502000 { + compatible = "allwinner,sun20i-d1-i2c", + "allwinner,sun8i-v536-i2c", + "allwinner,sun6i-a31-i2c"; + reg = <0x2502000 0x400>; + interrupts = <SOC_PERIPHERAL_IRQ(9) IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_BUS_I2C0>; + resets = <&ccu RST_BUS_I2C0>; + dmas = <&dma 43>, <&dma 43>; + dma-names = "rx", "tx"; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + i2c1: i2c@2502400 { + compatible = "allwinner,sun20i-d1-i2c", + "allwinner,sun8i-v536-i2c", + "allwinner,sun6i-a31-i2c"; + reg = <0x2502400 0x400>; + interrupts = <SOC_PERIPHERAL_IRQ(10) IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_BUS_I2C1>; + resets = <&ccu RST_BUS_I2C1>; + dmas = <&dma 44>, <&dma 44>; + dma-names = "rx", "tx"; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + i2c2: i2c@2502800 { + compatible = "allwinner,sun20i-d1-i2c", + "allwinner,sun8i-v536-i2c", + "allwinner,sun6i-a31-i2c"; + reg = <0x2502800 0x400>; + interrupts = <SOC_PERIPHERAL_IRQ(11) IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_BUS_I2C2>; + resets = <&ccu RST_BUS_I2C2>; + dmas = <&dma 45>, <&dma 45>; + dma-names = "rx", "tx"; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + i2c3: i2c@2502c00 { + compatible = "allwinner,sun20i-d1-i2c", + "allwinner,sun8i-v536-i2c", + "allwinner,sun6i-a31-i2c"; + reg = <0x2502c00 0x400>; + interrupts = <SOC_PERIPHERAL_IRQ(12) IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_BUS_I2C3>; + resets = <&ccu RST_BUS_I2C3>; + dmas = <&dma 46>, <&dma 46>; + dma-names = "rx", "tx"; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + can0: can@2504000 { + compatible = "allwinner,sun20i-d1-can"; + reg = <0x02504000 0x400>; + interrupts = <SOC_PERIPHERAL_IRQ(21) IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_BUS_CAN0>; + resets = <&ccu RST_BUS_CAN0>; + pinctrl-names = "default"; + pinctrl-0 = <&can0_pins>; + status = "disabled"; + }; + + can1: can@2504400 { + compatible = "allwinner,sun20i-d1-can"; + reg = <0x02504400 0x400>; + interrupts = <SOC_PERIPHERAL_IRQ(22) IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_BUS_CAN1>; + resets = <&ccu RST_BUS_CAN1>; + pinctrl-names = "default"; + pinctrl-0 = <&can1_pins>; + status = "disabled"; + }; + + syscon: syscon@3000000 { + compatible = "allwinner,sun20i-d1-system-control"; + reg = <0x3000000 0x1000>; + ranges; + #address-cells = <1>; + #size-cells = <1>; + }; + + dma: dma-controller@3002000 { + compatible = "allwinner,sun20i-d1-dma"; + reg = <0x3002000 0x1000>; + interrupts = <SOC_PERIPHERAL_IRQ(50) IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_BUS_DMA>, <&ccu CLK_MBUS_DMA>; + clock-names = "bus", "mbus"; + resets = <&ccu RST_BUS_DMA>; + dma-channels = <16>; + dma-requests = <48>; + #dma-cells = <1>; + }; + + sid: efuse@3006000 { + compatible = "allwinner,sun20i-d1-sid"; + reg = <0x3006000 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + }; + + crypto: crypto@3040000 { + compatible = "allwinner,sun20i-d1-crypto"; + reg = <0x3040000 0x800>; + interrupts = <SOC_PERIPHERAL_IRQ(52) IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_BUS_CE>, + <&ccu CLK_CE>, + <&ccu CLK_MBUS_CE>, + <&rtc CLK_IOSC>; + clock-names = "bus", "mod", "ram", "trng"; + resets = <&ccu RST_BUS_CE>; + }; + + mbus: dram-controller@3102000 { + compatible = "allwinner,sun20i-d1-mbus"; + reg = <0x3102000 0x1000>, + <0x3103000 0x1000>; + reg-names = "mbus", "dram"; + interrupts = <SOC_PERIPHERAL_IRQ(43) IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_MBUS>, + <&ccu CLK_DRAM>, + <&ccu CLK_BUS_DRAM>; + clock-names = "mbus", "dram", "bus"; + dma-ranges = <0 0x40000000 0x80000000>; + #address-cells = <1>; + #size-cells = <1>; + #interconnect-cells = <1>; + }; + + mmc0: mmc@4020000 { + compatible = "allwinner,sun20i-d1-mmc"; + reg = <0x4020000 0x1000>; + interrupts = <SOC_PERIPHERAL_IRQ(40) IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_BUS_MMC0>, <&ccu CLK_MMC0>; + clock-names = "ahb", "mmc"; + resets = <&ccu RST_BUS_MMC0>; + reset-names = "ahb"; + cap-sd-highspeed; + max-frequency = <150000000>; + no-mmc; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + mmc1: mmc@4021000 { + compatible = "allwinner,sun20i-d1-mmc"; + reg = <0x4021000 0x1000>; + interrupts = <SOC_PERIPHERAL_IRQ(41) IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_BUS_MMC1>, <&ccu CLK_MMC1>; + clock-names = "ahb", "mmc"; + resets = <&ccu RST_BUS_MMC1>; + reset-names = "ahb"; + cap-sd-highspeed; + max-frequency = <150000000>; + no-mmc; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + mmc2: mmc@4022000 { + compatible = "allwinner,sun20i-d1-emmc", + "allwinner,sun50i-a100-emmc"; + reg = <0x4022000 0x1000>; + interrupts = <SOC_PERIPHERAL_IRQ(42) IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_BUS_MMC2>, <&ccu CLK_MMC2>; + clock-names = "ahb", "mmc"; + resets = <&ccu RST_BUS_MMC2>; + reset-names = "ahb"; + cap-mmc-highspeed; + max-frequency = <150000000>; + mmc-ddr-1_8v; + mmc-ddr-3_3v; + no-sd; + no-sdio; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + spi0: spi@4025000 { + compatible = "allwinner,sun20i-d1-spi", + "allwinner,sun50i-r329-spi"; + reg = <0x04025000 0x1000>; + interrupts = <SOC_PERIPHERAL_IRQ(15) IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_BUS_SPI0>, <&ccu CLK_SPI0>; + clock-names = "ahb", "mod"; + dmas = <&dma 22>, <&dma 22>; + dma-names = "rx", "tx"; + resets = <&ccu RST_BUS_SPI0>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + spi1: spi@4026000 { + compatible = "allwinner,sun20i-d1-spi-dbi", + "allwinner,sun50i-r329-spi-dbi", + "allwinner,sun50i-r329-spi"; + reg = <0x04026000 0x1000>; + interrupts = <SOC_PERIPHERAL_IRQ(16) IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_BUS_SPI1>, <&ccu CLK_SPI1>; + clock-names = "ahb", "mod"; + dmas = <&dma 23>, <&dma 23>; + dma-names = "rx", "tx"; + resets = <&ccu RST_BUS_SPI1>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + usb_otg: usb@4100000 { + compatible = "allwinner,sun20i-d1-musb", + "allwinner,sun8i-a33-musb"; + reg = <0x4100000 0x400>; + interrupts = <SOC_PERIPHERAL_IRQ(29) IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "mc"; + clocks = <&ccu CLK_BUS_OTG>; + resets = <&ccu RST_BUS_OTG>; + extcon = <&usbphy 0>; + phys = <&usbphy 0>; + phy-names = "usb"; + status = "disabled"; + }; + + usbphy: phy@4100400 { + compatible = "allwinner,sun20i-d1-usb-phy"; + reg = <0x4100400 0x100>, + <0x4101800 0x100>, + <0x4200800 0x100>; + reg-names = "phy_ctrl", + "pmu0", + "pmu1"; + clocks = <&dcxo>, + <&dcxo>; + clock-names = "usb0_phy", + "usb1_phy"; + resets = <&ccu RST_USB_PHY0>, + <&ccu RST_USB_PHY1>; + reset-names = "usb0_reset", + "usb1_reset"; + status = "disabled"; + #phy-cells = <1>; + }; + + ehci0: usb@4101000 { + compatible = "allwinner,sun20i-d1-ehci", + "generic-ehci"; + reg = <0x4101000 0x100>; + interrupts = <SOC_PERIPHERAL_IRQ(30) IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_BUS_OHCI0>, + <&ccu CLK_BUS_EHCI0>, + <&ccu CLK_USB_OHCI0>; + resets = <&ccu RST_BUS_OHCI0>, + <&ccu RST_BUS_EHCI0>; + phys = <&usbphy 0>; + phy-names = "usb"; + status = "disabled"; + }; + + ohci0: usb@4101400 { + compatible = "allwinner,sun20i-d1-ohci", + "generic-ohci"; + reg = <0x4101400 0x100>; + interrupts = <SOC_PERIPHERAL_IRQ(31) IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_BUS_OHCI0>, + <&ccu CLK_USB_OHCI0>; + resets = <&ccu RST_BUS_OHCI0>; + phys = <&usbphy 0>; + phy-names = "usb"; + status = "disabled"; + }; + + ehci1: usb@4200000 { + compatible = "allwinner,sun20i-d1-ehci", + "generic-ehci"; + reg = <0x4200000 0x100>; + interrupts = <SOC_PERIPHERAL_IRQ(33) IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_BUS_OHCI1>, + <&ccu CLK_BUS_EHCI1>, + <&ccu CLK_USB_OHCI1>; + resets = <&ccu RST_BUS_OHCI1>, + <&ccu RST_BUS_EHCI1>; + phys = <&usbphy 1>; + phy-names = "usb"; + status = "disabled"; + }; + + ohci1: usb@4200400 { + compatible = "allwinner,sun20i-d1-ohci", + "generic-ohci"; + reg = <0x4200400 0x100>; + interrupts = <SOC_PERIPHERAL_IRQ(34) IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_BUS_OHCI1>, + <&ccu CLK_USB_OHCI1>; + resets = <&ccu RST_BUS_OHCI1>; + phys = <&usbphy 1>; + phy-names = "usb"; + status = "disabled"; + }; + + emac: ethernet@4500000 { + compatible = "allwinner,sun20i-d1-emac", + "allwinner,sun50i-a64-emac"; + reg = <0x4500000 0x10000>; + interrupts = <SOC_PERIPHERAL_IRQ(46) IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "macirq"; + clocks = <&ccu CLK_BUS_EMAC>; + clock-names = "stmmaceth"; + resets = <&ccu RST_BUS_EMAC>; + reset-names = "stmmaceth"; + syscon = <&syscon>; + status = "disabled"; + + mdio: mdio { + compatible = "snps,dwmac-mdio"; + #address-cells = <1>; + #size-cells = <0>; + }; + }; + + display_clocks: clock-controller@5000000 { + compatible = "allwinner,sun20i-d1-de2-clk", + "allwinner,sun50i-h5-de2-clk"; + reg = <0x5000000 0x10000>; + clocks = <&ccu CLK_BUS_DE>, <&ccu CLK_DE>; + clock-names = "bus", "mod"; + resets = <&ccu RST_BUS_DE>; + #clock-cells = <1>; + #reset-cells = <1>; + }; + + mixer0: mixer@5100000 { + compatible = "allwinner,sun20i-d1-de2-mixer-0"; + reg = <0x5100000 0x100000>; + clocks = <&display_clocks CLK_BUS_MIXER0>, + <&display_clocks CLK_MIXER0>; + clock-names = "bus", "mod"; + resets = <&display_clocks RST_MIXER0>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + mixer0_out: port@1 { + reg = <1>; + + mixer0_out_tcon_top_mixer0: endpoint { + remote-endpoint = <&tcon_top_mixer0_in_mixer0>; + }; + }; + }; + }; + + mixer1: mixer@5200000 { + compatible = "allwinner,sun20i-d1-de2-mixer-1"; + reg = <0x5200000 0x100000>; + clocks = <&display_clocks CLK_BUS_MIXER1>, + <&display_clocks CLK_MIXER1>; + clock-names = "bus", "mod"; + resets = <&display_clocks RST_MIXER1>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + mixer1_out: port@1 { + reg = <1>; + + mixer1_out_tcon_top_mixer1: endpoint { + remote-endpoint = <&tcon_top_mixer1_in_mixer1>; + }; + }; + }; + }; + + dsi: dsi@5450000 { + compatible = "allwinner,sun20i-d1-mipi-dsi", + "allwinner,sun50i-a100-mipi-dsi"; + reg = <0x5450000 0x1000>; + interrupts = <SOC_PERIPHERAL_IRQ(92) IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_BUS_MIPI_DSI>, + <&tcon_top CLK_TCON_TOP_DSI>; + clock-names = "bus", "mod"; + resets = <&ccu RST_BUS_MIPI_DSI>; + phys = <&dphy>; + phy-names = "dphy"; + status = "disabled"; + + port { + dsi_in_tcon_lcd0: endpoint { + remote-endpoint = <&tcon_lcd0_out_dsi>; + }; + }; + }; + + dphy: phy@5451000 { + compatible = "allwinner,sun20i-d1-mipi-dphy", + "allwinner,sun50i-a100-mipi-dphy"; + reg = <0x5451000 0x1000>; + interrupts = <SOC_PERIPHERAL_IRQ(92) IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_BUS_MIPI_DSI>, + <&ccu CLK_MIPI_DSI>; + clock-names = "bus", "mod"; + resets = <&ccu RST_BUS_MIPI_DSI>; + #phy-cells = <0>; + }; + + tcon_top: tcon-top@5460000 { + compatible = "allwinner,sun20i-d1-tcon-top"; + reg = <0x5460000 0x1000>; + clocks = <&ccu CLK_BUS_DPSS_TOP>, + <&ccu CLK_TCON_TV>, + <&ccu CLK_TVE>, + <&ccu CLK_TCON_LCD0>; + clock-names = "bus", "tcon-tv0", "tve0", "dsi"; + clock-output-names = "tcon-top-tv0", "tcon-top-dsi"; + resets = <&ccu RST_BUS_DPSS_TOP>; + #clock-cells = <1>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + tcon_top_mixer0_in: port@0 { + reg = <0>; + + tcon_top_mixer0_in_mixer0: endpoint { + remote-endpoint = <&mixer0_out_tcon_top_mixer0>; + }; + }; + + tcon_top_mixer0_out: port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + + tcon_top_mixer0_out_tcon_lcd0: endpoint@0 { + reg = <0>; + remote-endpoint = <&tcon_lcd0_in_tcon_top_mixer0>; + }; + + tcon_top_mixer0_out_tcon_tv0: endpoint@2 { + reg = <2>; + remote-endpoint = <&tcon_tv0_in_tcon_top_mixer0>; + }; + }; + + tcon_top_mixer1_in: port@2 { + reg = <2>; + #address-cells = <1>; + #size-cells = <0>; + + tcon_top_mixer1_in_mixer1: endpoint@1 { + reg = <1>; + remote-endpoint = <&mixer1_out_tcon_top_mixer1>; + }; + }; + + tcon_top_mixer1_out: port@3 { + reg = <3>; + #address-cells = <1>; + #size-cells = <0>; + + tcon_top_mixer1_out_tcon_lcd0: endpoint@0 { + reg = <0>; + remote-endpoint = <&tcon_lcd0_in_tcon_top_mixer1>; + }; + + tcon_top_mixer1_out_tcon_tv0: endpoint@2 { + reg = <2>; + remote-endpoint = <&tcon_tv0_in_tcon_top_mixer1>; + }; + }; + + tcon_top_hdmi_in: port@4 { + reg = <4>; + + tcon_top_hdmi_in_tcon_tv0: endpoint { + remote-endpoint = <&tcon_tv0_out_tcon_top_hdmi>; + }; + }; + + tcon_top_hdmi_out: port@5 { + reg = <5>; + }; + }; + }; + + tcon_lcd0: lcd-controller@5461000 { + compatible = "allwinner,sun20i-d1-tcon-lcd"; + reg = <0x5461000 0x1000>; + interrupts = <SOC_PERIPHERAL_IRQ(90) IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_BUS_TCON_LCD0>, + <&ccu CLK_TCON_LCD0>; + clock-names = "ahb", "tcon-ch0"; + clock-output-names = "tcon-pixel-clock"; + resets = <&ccu RST_BUS_TCON_LCD0>, + <&ccu RST_BUS_LVDS0>; + reset-names = "lcd", "lvds"; + #clock-cells = <0>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + tcon_lcd0_in: port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + + tcon_lcd0_in_tcon_top_mixer0: endpoint@0 { + reg = <0>; + remote-endpoint = <&tcon_top_mixer0_out_tcon_lcd0>; + }; + + tcon_lcd0_in_tcon_top_mixer1: endpoint@1 { + reg = <1>; + remote-endpoint = <&tcon_top_mixer1_out_tcon_lcd0>; + }; + }; + + tcon_lcd0_out: port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + + tcon_lcd0_out_dsi: endpoint@1 { + reg = <1>; + remote-endpoint = <&dsi_in_tcon_lcd0>; + }; + }; + }; + }; + + tcon_tv0: lcd-controller@5470000 { + compatible = "allwinner,sun20i-d1-tcon-tv"; + reg = <0x5470000 0x1000>; + interrupts = <SOC_PERIPHERAL_IRQ(91) IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_BUS_TCON_TV>, + <&tcon_top CLK_TCON_TOP_TV0>; + clock-names = "ahb", "tcon-ch1"; + resets = <&ccu RST_BUS_TCON_TV>; + reset-names = "lcd"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + tcon_tv0_in: port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + + tcon_tv0_in_tcon_top_mixer0: endpoint@0 { + reg = <0>; + remote-endpoint = <&tcon_top_mixer0_out_tcon_tv0>; + }; + + tcon_tv0_in_tcon_top_mixer1: endpoint@1 { + reg = <1>; + remote-endpoint = <&tcon_top_mixer1_out_tcon_tv0>; + }; + }; + + tcon_tv0_out: port@1 { + reg = <1>; + + tcon_tv0_out_tcon_top_hdmi: endpoint { + remote-endpoint = <&tcon_top_hdmi_in_tcon_tv0>; + }; + }; + }; + }; + + ppu: power-controller@7001000 { + compatible = "allwinner,sun20i-d1-ppu"; + reg = <0x7001000 0x1000>; + clocks = <&r_ccu CLK_BUS_R_PPU>; + resets = <&r_ccu RST_BUS_R_PPU>; + #power-domain-cells = <1>; + }; + + r_ccu: clock-controller@7010000 { + compatible = "allwinner,sun20i-d1-r-ccu"; + reg = <0x7010000 0x400>; + clocks = <&dcxo>, + <&rtc CLK_OSC32K>, + <&rtc CLK_IOSC>, + <&ccu CLK_PLL_PERIPH0_DIV3>; + clock-names = "hosc", "losc", "iosc", "pll-periph"; + #clock-cells = <1>; + #reset-cells = <1>; + }; + + rtc: rtc@7090000 { + compatible = "allwinner,sun20i-d1-rtc", + "allwinner,sun50i-r329-rtc"; + reg = <0x7090000 0x400>; + interrupts = <SOC_PERIPHERAL_IRQ(144) IRQ_TYPE_LEVEL_HIGH>; + clocks = <&r_ccu CLK_BUS_R_RTC>, + <&dcxo>, + <&r_ccu CLK_R_AHB>; + clock-names = "bus", "hosc", "ahb"; + #clock-cells = <1>; + }; + }; +}; diff --git a/arch/riscv/include/asm/string.h b/arch/riscv/include/asm/string.h index 7dee3e4c9f..38ad85fe3b 100644 --- a/arch/riscv/include/asm/string.h +++ b/arch/riscv/include/asm/string.h @@ -40,4 +40,22 @@ extern void *memmove(void *, const void *, __kernel_size_t); #endif extern void *memset(void *, int, __kernel_size_t); +#undef __HAVE_ARCH_STRLEN +#if CONFIG_IS_ENABLED(USE_ARCH_STRLEN) +#define __HAVE_ARCH_STRLEN +#endif +extern __kernel_size_t strlen(const char *); + +#undef __HAVE_ARCH_STRCMP +#if CONFIG_IS_ENABLED(USE_ARCH_STRCMP) +#define __HAVE_ARCH_STRCMP +#endif +extern int strcmp(const char *, const char *); + +#undef __HAVE_ARCH_STRNCMP +#if CONFIG_IS_ENABLED(USE_ARCH_STRNCMP) +#define __HAVE_ARCH_STRNCMP +#endif +extern int strncmp(const char *, const char *, size_t __kernel_size_t); + #endif /* __ASM_RISCV_STRING_H */ diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile index 02c4d8fcc6..9a05b662fd 100644 --- a/arch/riscv/lib/Makefile +++ b/arch/riscv/lib/Makefile @@ -42,5 +42,8 @@ extra-$(CONFIG_EFI) += $(EFI_CRT0) $(EFI_RELOC) obj-$(CONFIG_$(SPL_TPL_)USE_ARCH_MEMSET) += memset.o obj-$(CONFIG_$(SPL_TPL_)USE_ARCH_MEMMOVE) += memmove.o obj-$(CONFIG_$(SPL_TPL_)USE_ARCH_MEMCPY) += memcpy.o +obj-$(CONFIG_$(SPL_TPL_)USE_ARCH_STRLEN) += strlen_zbb.o +obj-$(CONFIG_$(SPL_TPL_)USE_ARCH_STRCMP) += strcmp_zbb.o +obj-$(CONFIG_$(SPL_TPL_)USE_ARCH_STRNCMP) += strncmp_zbb.o obj-$(CONFIG_$(SPL_TPL_)SEMIHOSTING) += semihosting.o diff --git a/arch/riscv/lib/andes_plicsw.c b/arch/riscv/lib/andes_plicsw.c index 7518408089..6fd49e873b 100644 --- a/arch/riscv/lib/andes_plicsw.c +++ b/arch/riscv/lib/andes_plicsw.c @@ -22,7 +22,7 @@ #include <linux/err.h> /* pending register */ -#define PENDING_REG(base, hart) ((ulong)(base) + 0x1000 + ((hart) / 4) * 4) +#define PENDING_REG(base) ((ulong)(base) + 0x1000) /* enable register */ #define ENABLE_REG(base, hart) ((ulong)(base) + 0x2000 + (hart) * 0x80) /* claim register */ @@ -30,10 +30,11 @@ /* priority register */ #define PRIORITY_REG(base) ((ulong)(base) + PLICSW_PRIORITY_BASE) -#define ENABLE_HART_IPI (0x01010101) -#define SEND_IPI_TO_HART(hart) (0x1 << (hart)) +/* Bit 0 of PLIC-SW pending array is hardwired to zero, so we start from bit 1 */ +#define FIRST_AVAILABLE_BIT 0x2 +#define SEND_IPI_TO_HART(hart) (FIRST_AVAILABLE_BIT << (hart)) #define PLICSW_PRIORITY_BASE 0x4 -#define PLICSW_INTERRUPT_PER_HART 0x8 +#define PLICSW_INTERRUPT_PER_HART 0x1 DECLARE_GLOBAL_DATA_PTR; @@ -41,9 +42,8 @@ static int enable_ipi(int hart) { unsigned int en; - en = ENABLE_HART_IPI << hart; + en = FIRST_AVAILABLE_BIT << hart; writel(en, (void __iomem *)ENABLE_REG(gd->arch.plicsw, hart)); - writel(en, (void __iomem *)ENABLE_REG(gd->arch.plicsw + 0x4, hart)); return 0; } @@ -75,7 +75,7 @@ int riscv_init_ipi(void) ret = uclass_find_first_device(UCLASS_CPU, &dev); if (ret) return ret; - else if (!dev) + if (!dev) return -ENODEV; ofnode_for_each_subnode(node, dev_ofnode(dev->parent)) { @@ -105,10 +105,9 @@ int riscv_init_ipi(void) int riscv_send_ipi(int hart) { - unsigned int ipi = (SEND_IPI_TO_HART(hart) << (8 * gd->arch.boot_hart)); + unsigned int ipi = SEND_IPI_TO_HART(hart); - writel(ipi, (void __iomem *)PENDING_REG(gd->arch.plicsw, - gd->arch.boot_hart)); + writel(ipi, (void __iomem *)PENDING_REG(gd->arch.plicsw)); return 0; } @@ -125,10 +124,9 @@ int riscv_clear_ipi(int hart) int riscv_get_ipi(int hart, int *pending) { - unsigned int ipi = (SEND_IPI_TO_HART(hart) << (8 * gd->arch.boot_hart)); + unsigned int ipi = SEND_IPI_TO_HART(hart); - *pending = readl((void __iomem *)PENDING_REG(gd->arch.plicsw, - gd->arch.boot_hart)); + *pending = readl((void __iomem *)PENDING_REG(gd->arch.plicsw)); *pending = !!(*pending & ipi); return 0; diff --git a/arch/riscv/lib/strcmp_zbb.S b/arch/riscv/lib/strcmp_zbb.S new file mode 100644 index 0000000000..e5a367c0e5 --- /dev/null +++ b/arch/riscv/lib/strcmp_zbb.S @@ -0,0 +1,81 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Taken from Linux arch/riscv/lib/strcmp.S + */ + +#include <linux/linkage.h> +#include <asm/asm.h> + +ENTRY(__strcmp) +WEAK(strcmp) +.option push +.option arch,+zbb + /* + * Returns + * a0 - comparison result, value like strcmp + * + * Parameters + * a0 - string1 + * a1 - string2 + * + * Clobbers + * t0, t1, t2, t3, t4 + */ + + or t2, a0, a1 + li t4, -1 + and t2, t2, SZREG-1 + bnez t2, 3f + + /* Main loop for aligned string. */ + .p2align 3 +1: + REG_L t0, 0(a0) + REG_L t1, 0(a1) + orc.b t3, t0 + bne t3, t4, 2f + addi a0, a0, SZREG + addi a1, a1, SZREG + beq t0, t1, 1b + + /* + * Words don't match, and no null byte in the first + * word. Get bytes in big-endian order and compare. + */ +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + rev8 t0, t0 + rev8 t1, t1 +#endif + + /* Synthesize (t0 >= t1) ? 1 : -1 in a branchless sequence. */ + sltu a0, t0, t1 + neg a0, a0 + ori a0, a0, 1 + ret + +2: + /* + * Found a null byte. + * If words don't match, fall back to simple loop. + */ + bne t0, t1, 3f + + /* Otherwise, strings are equal. */ + li a0, 0 + ret + + /* Simple loop for misaligned strings. */ + .p2align 3 +3: + lbu t0, 0(a0) + lbu t1, 0(a1) + addi a0, a0, 1 + addi a1, a1, 1 + bne t0, t1, 4f + bnez t0, 3b + +4: + sub a0, t0, t1 + ret +.option pop +END(__strcmp) diff --git a/arch/riscv/lib/strlen_zbb.S b/arch/riscv/lib/strlen_zbb.S new file mode 100644 index 0000000000..bd8fa4c0bd --- /dev/null +++ b/arch/riscv/lib/strlen_zbb.S @@ -0,0 +1,101 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Taken from Linux arch/riscv/lib/strlen.S + */ + +#include <linux/linkage.h> +#include <asm/asm.h> + +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +# define CZ ctz +# define SHIFT srl +#else +# define CZ clz +# define SHIFT sll +#endif + +ENTRY(__strlen) +WEAK(strlen) +.option push +.option arch,+zbb + /* + * Returns + * a0 - string length + * + * Parameters + * a0 - String to measure + * + * Clobbers + * t0, t1, t2, t3 + */ + + /* Number of irrelevant bytes in the first word. */ + andi t2, a0, SZREG-1 + + /* Align pointer. */ + andi t0, a0, -SZREG + + li t3, SZREG + sub t3, t3, t2 + slli t2, t2, 3 + + /* Get the first word. */ + REG_L t1, 0(t0) + + /* + * Shift away the partial data we loaded to remove the irrelevant bytes + * preceding the string with the effect of adding NUL bytes at the + * end of the string's first word. + */ + SHIFT t1, t1, t2 + + /* Convert non-NUL into 0xff and NUL into 0x00. */ + orc.b t1, t1 + + /* Convert non-NUL into 0x00 and NUL into 0xff. */ + not t1, t1 + + /* + * Search for the first set bit (corresponding to a NUL byte in the + * original chunk). + */ + CZ t1, t1 + + /* + * The first chunk is special: compare against the number + * of valid bytes in this chunk. + */ + srli a0, t1, 3 + bgtu t3, a0, 2f + + /* Prepare for the word comparison loop. */ + addi t2, t0, SZREG + li t3, -1 + + /* + * Our critical loop is 4 instructions and processes data in + * 4 byte or 8 byte chunks. + */ + .p2align 3 +1: + REG_L t1, SZREG(t0) + addi t0, t0, SZREG + orc.b t1, t1 + beq t1, t3, 1b + + not t1, t1 + CZ t1, t1 + srli t1, t1, 3 + + /* Get number of processed bytes. */ + sub t2, t0, t2 + + /* Add number of characters in the first word. */ + add a0, a0, t2 + + /* Add number of characters in the last word. */ + add a0, a0, t1 +2: + ret +.option pop +END(__strlen) diff --git a/arch/riscv/lib/strncmp_zbb.S b/arch/riscv/lib/strncmp_zbb.S new file mode 100644 index 0000000000..00e0fec3a6 --- /dev/null +++ b/arch/riscv/lib/strncmp_zbb.S @@ -0,0 +1,94 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Taken from Linux arch/riscv/lib/strncmp.S + */ + +#include <linux/linkage.h> +#include <asm/asm.h> + +ENTRY(__strncmp) +WEAK(strncmp) +.option push +.option arch,+zbb + /* + * Returns + * a0 - comparison result, like strncmp + * + * Parameters + * a0 - string1 + * a1 - string2 + * a2 - number of characters to compare + * + * Clobbers + * t0, t1, t2, t3, t4, t5, t6 + */ + + or t2, a0, a1 + li t5, -1 + and t2, t2, SZREG-1 + add t4, a0, a2 + bnez t2, 3f + + /* Adjust limit for fast-path. */ + andi t6, t4, -SZREG + + /* Main loop for aligned string. */ + .p2align 3 +1: + bge a0, t6, 3f + REG_L t0, 0(a0) + REG_L t1, 0(a1) + orc.b t3, t0 + bne t3, t5, 2f + orc.b t3, t1 + bne t3, t5, 2f + addi a0, a0, SZREG + addi a1, a1, SZREG + beq t0, t1, 1b + + /* + * Words don't match, and no null byte in the first + * word. Get bytes in big-endian order and compare. + */ +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + rev8 t0, t0 + rev8 t1, t1 +#endif + + /* Synthesize (t0 >= t1) ? 1 : -1 in a branchless sequence. */ + sltu a0, t0, t1 + neg a0, a0 + ori a0, a0, 1 + ret + +2: + /* + * Found a null byte. + * If words don't match, fall back to simple loop. + */ + bne t0, t1, 3f + + /* Otherwise, strings are equal. */ + li a0, 0 + ret + + /* Simple loop for misaligned strings. */ + .p2align 3 +3: + bge a0, t4, 5f + lbu t0, 0(a0) + lbu t1, 0(a1) + addi a0, a0, 1 + addi a1, a1, 1 + bne t0, t1, 4f + bnez t0, 3b + +4: + sub a0, t0, t1 + ret + +5: + li a0, 0 + ret +.option pop +END(__strncmp) diff --git a/arch/sandbox/cpu/spl.c b/arch/sandbox/cpu/spl.c index 7590f1b80a..16b7662798 100644 --- a/arch/sandbox/cpu/spl.c +++ b/arch/sandbox/cpu/spl.c @@ -129,6 +129,10 @@ void spl_board_init(void) if (!CONFIG_IS_ENABLED(UNIT_TEST)) return; + /* These are necessary so TFTP can use LMBs to check its load address */ + gd->bd->bi_dram[0].start = gd->ram_base; + gd->bd->bi_dram[0].size = get_effective_memsize(); + if (state->run_unittests) { struct unit_test *tests = UNIT_TEST_ALL_START(); const int count = UNIT_TEST_ALL_COUNT(); diff --git a/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c index 2c8a72590b..2589c2eba7 100644 --- a/arch/sandbox/cpu/start.c +++ b/arch/sandbox/cpu/start.c @@ -13,6 +13,7 @@ #include <log.h> #include <os.h> #include <sort.h> +#include <spl.h> #include <asm/getopt.h> #include <asm/global_data.h> #include <asm/io.h> @@ -202,10 +203,14 @@ static int sandbox_cmdline_cb_test_fdt(struct sandbox_state *state, { char buf[256]; char *fname; + char *relname; int len; - len = state_get_rel_filename("arch/sandbox/dts/test.dtb", buf, - sizeof(buf)); + if (spl_phase() <= PHASE_SPL) + relname = "../arch/sandbox/dts/test.dtb"; + else + relname = "arch/sandbox/dts/test.dtb"; + len = state_get_rel_filename(relname, buf, sizeof(buf)); if (len < 0) return len; diff --git a/arch/sandbox/cpu/u-boot-spl.lds b/arch/sandbox/cpu/u-boot-spl.lds index ef885fd0cb..a81d66a6f2 100644 --- a/arch/sandbox/cpu/u-boot-spl.lds +++ b/arch/sandbox/cpu/u-boot-spl.lds @@ -26,6 +26,8 @@ SECTIONS KEEP(*(_u_boot_sandbox_getopt)) *(_u_boot_sandbox_getopt_end) } + + _image_binary_end = .; } INSERT AFTER .data; diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index e88c267620..e430347356 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -975,7 +975,7 @@ }; wdt-gpio-toggle { - gpios = <&gpio_a 7 0>; + gpios = <&gpio_a 8 0>; compatible = "linux,wdt-gpio"; hw_margin_ms = <100>; hw_algo = "toggle"; diff --git a/arch/sandbox/include/asm/spl.h b/arch/sandbox/include/asm/spl.h index 2f8b5fcfcf..f349ea1997 100644 --- a/arch/sandbox/include/asm/spl.h +++ b/arch/sandbox/include/asm/spl.h @@ -12,6 +12,9 @@ enum { BOOT_DEVICE_MMC2_2, BOOT_DEVICE_BOARD, BOOT_DEVICE_VBE, + BOOT_DEVICE_CPGMAC, + BOOT_DEVICE_NOR, + BOOT_DEVICE_SPI, }; /** |