diff options
Diffstat (limited to 'arch')
58 files changed, 1679 insertions, 390 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 0f8dd32bdd..ccf2a844be 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -747,6 +747,8 @@ config ARCH_QEMU select OF_CONTROL select PL01X_SERIAL imply CMD_DM + imply DM_RTC + imply RTC_PL031 config ARCH_RMOBILE bool "Renesas ARM SoCs" @@ -861,7 +863,6 @@ config ARCH_VF610 config ARCH_ZYNQ bool "Xilinx Zynq based platform" select BOARD_EARLY_INIT_F if WDT - select BOARD_LATE_INIT select CLK select CLK_ZYNQ select CPU_V7A @@ -881,6 +882,7 @@ config ARCH_ZYNQ select SPL_SEPARATE_BSS if SPL select SUPPORT_SPL imply ARCH_EARLY_INIT_R + imply BOARD_LATE_INIT imply CMD_CLK imply CMD_DM imply CMD_SPL @@ -898,7 +900,6 @@ config ARCH_ZYNQMP_R5 config ARCH_ZYNQMP bool "Xilinx ZynqMP based platform" select ARM64 - select BOARD_LATE_INIT select CLK select DM select DM_SERIAL @@ -907,6 +908,7 @@ config ARCH_ZYNQMP select SPL_BOARD_INIT if SPL select SPL_CLK if SPL select SUPPORT_SPL + imply BOARD_LATE_INIT imply CMD_DM imply FAT_WRITE diff --git a/arch/arm/cpu/arm926ejs/spear/cpu.c b/arch/arm/cpu/arm926ejs/spear/cpu.c index 88a40c6036..51c4a730f4 100644 --- a/arch/arm/cpu/arm926ejs/spear/cpu.c +++ b/arch/arm/cpu/arm926ejs/spear/cpu.c @@ -52,6 +52,9 @@ int arch_cpu_init(void) #if defined(CONFIG_SPEAR_GPIO) periph1_clken |= MISC_GPIO3ENB | MISC_GPIO4ENB; #endif +#if defined(CONFIG_PL022_SPI) + periph1_clken |= MISC_SSP1ENB | MISC_SSP2ENB | MISC_SSP3ENB; +#endif writel(periph1_clken, &misc_p->periph1_clken); diff --git a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c index 052e0708d4..be00bd55ab 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c @@ -835,7 +835,7 @@ int dram_init_banksize(void) return 0; } -#if defined(CONFIG_EFI_LOADER) && !defined(CONFIG_SPL_BUILD) +#if CONFIG_IS_ENABLED(EFI_LOADER) void efi_add_known_memory(void) { int i; diff --git a/arch/arm/cpu/armv8/fsl-layerscape/fdt.c b/arch/arm/cpu/armv8/fsl-layerscape/fdt.c index fc9de73bce..c9c2c3f6d3 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/fdt.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/fdt.c @@ -135,7 +135,7 @@ remove_psci_node: fdt_add_mem_rsv(blob, (uintptr_t)&secondary_boot_code, *boot_code_size); -#if defined(CONFIG_EFI_LOADER) && !defined(CONFIG_SPL_BUILD) +#if CONFIG_IS_ENABLED(EFI_LOADER) efi_add_memory_map((uintptr_t)&secondary_boot_code, ALIGN(*boot_code_size, EFI_PAGE_SIZE) >> EFI_PAGE_SHIFT, EFI_RESERVED_MEMORY_TYPE, false); diff --git a/arch/arm/cpu/armv8/zynqmp/cpu.c b/arch/arm/cpu/armv8/zynqmp/cpu.c index 1279dc8658..43ba739d2f 100644 --- a/arch/arm/cpu/armv8/zynqmp/cpu.c +++ b/arch/arm/cpu/armv8/zynqmp/cpu.c @@ -171,38 +171,28 @@ int __maybe_unused invoke_smc(u32 pm_api_id, u32 arg0, u32 arg1, u32 arg2, return regs.regs[0]; } -#define ZYNQMP_SIP_SVC_GET_API_VERSION 0xC2000001 - -#define ZYNQMP_PM_VERSION_MAJOR 1 -#define ZYNQMP_PM_VERSION_MINOR 0 -#define ZYNQMP_PM_VERSION_MAJOR_SHIFT 16 -#define ZYNQMP_PM_VERSION_MINOR_MASK 0xFFFF - -#define ZYNQMP_PM_VERSION \ - ((ZYNQMP_PM_VERSION_MAJOR << ZYNQMP_PM_VERSION_MAJOR_SHIFT) | \ - ZYNQMP_PM_VERSION_MINOR) - #if defined(CONFIG_CLK_ZYNQMP) -void zynqmp_pmufw_version(void) +unsigned int zynqmp_pmufw_version(void) { int ret; u32 ret_payload[PAYLOAD_ARG_CNT]; - u32 pm_api_version; - - ret = invoke_smc(ZYNQMP_SIP_SVC_GET_API_VERSION, 0, 0, 0, 0, - ret_payload); - pm_api_version = ret_payload[1]; + static u32 pm_api_version = ZYNQMP_PM_VERSION_INVALID; - if (ret) - panic("PMUFW is not found - Please load it!\n"); + /* + * Get PMU version only once and later + * just return stored values instead of + * asking PMUFW again. + */ + if (pm_api_version == ZYNQMP_PM_VERSION_INVALID) { + ret = invoke_smc(ZYNQMP_SIP_SVC_GET_API_VERSION, 0, 0, 0, 0, + ret_payload); + pm_api_version = ret_payload[1]; - printf("PMUFW:\tv%d.%d\n", - pm_api_version >> ZYNQMP_PM_VERSION_MAJOR_SHIFT, - pm_api_version & ZYNQMP_PM_VERSION_MINOR_MASK); + if (ret) + panic("PMUFW is not found - Please load it!\n"); + } - if (pm_api_version < ZYNQMP_PM_VERSION) - panic("PMUFW version error. Expected: v%d.%d\n", - ZYNQMP_PM_VERSION_MAJOR, ZYNQMP_PM_VERSION_MINOR); + return pm_api_version; } #endif diff --git a/arch/arm/dts/am3517-evm-u-boot.dtsi b/arch/arm/dts/am3517-evm-u-boot.dtsi index c02beaad77..59df819f9d 100644 --- a/arch/arm/dts/am3517-evm-u-boot.dtsi +++ b/arch/arm/dts/am3517-evm-u-boot.dtsi @@ -10,10 +10,6 @@ }; }; -&mmc1 { - cd-inverted; -}; - &uart1 { reg-shift = <2>; }; diff --git a/arch/arm/dts/at91-sama5d27_som1_ek.dts b/arch/arm/dts/at91-sama5d27_som1_ek.dts index 5e62d4af71..4cd6db66fe 100644 --- a/arch/arm/dts/at91-sama5d27_som1_ek.dts +++ b/arch/arm/dts/at91-sama5d27_som1_ek.dts @@ -54,6 +54,18 @@ stdout-path = &uart1; }; + onewire_tm: onewire { + gpios = <&pioA 17 0>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_onewire_tm_default>; + status = "okay"; + + w1_eeprom: w1_eeprom@0 { + compatible = "maxim,ds24b33"; + status = "okay"; + }; + }; + ahb { usb1: ohci@00400000 { num-ports = <3>; @@ -208,6 +220,11 @@ pinmux = <PIN_PA31__GPIO>; bias-disable; }; + + pinctrl_onewire_tm_default: onewire_tm_default { + pinmux = <PIN_PA17__GPIO>; + bias-pull-up; + }; }; }; }; diff --git a/arch/arm/dts/at91-sama5d2_ptc_ek.dts b/arch/arm/dts/at91-sama5d2_ptc_ek.dts index ab5ab21895..068a117585 100644 --- a/arch/arm/dts/at91-sama5d2_ptc_ek.dts +++ b/arch/arm/dts/at91-sama5d2_ptc_ek.dts @@ -56,6 +56,18 @@ stdout-path = &uart0; }; + onewire_tm: onewire { + gpios = <&pioA PIN_PB31 0>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_onewire_tm_default>; + status = "okay"; + + w1_eeprom: w1_eeprom@0 { + compatible = "maxim,ds24b33"; + status = "okay"; + }; + }; + ahb { usb0: gadget@00300000 { atmel,vbus-gpio = <&pioA PIN_PA27 GPIO_ACTIVE_HIGH>; @@ -208,6 +220,11 @@ pinmux = <PIN_PB11__GPIO>; bias-disable; }; + + pinctrl_onewire_tm_default: onewire_tm_default { + pinmux = <PIN_PB31__GPIO>; + bias-pull-up; + }; }; }; }; diff --git a/arch/arm/dts/at91-sama5d2_xplained.dts b/arch/arm/dts/at91-sama5d2_xplained.dts index 01326a1ee0..33064b390a 100644 --- a/arch/arm/dts/at91-sama5d2_xplained.dts +++ b/arch/arm/dts/at91-sama5d2_xplained.dts @@ -11,6 +11,18 @@ stdout-path = &uart1; }; + onewire_tm: onewire { + gpios = <&pioA PIN_PB0 0>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_onewire_tm_default>; + status = "okay"; + + w1_eeprom: w1_eeprom@0 { + compatible = "maxim,ds24b33"; + status = "okay"; + }; + }; + ahb { usb1: ohci@00400000 { num-ports = <3>; @@ -270,6 +282,11 @@ pinmux = <PIN_PA31__GPIO>; bias-disable; }; + + pinctrl_onewire_tm_default: onewire_tm_default { + pinmux = <PIN_PB0__GPIO>; + bias-pull-up; + }; }; }; }; diff --git a/arch/arm/dts/at91-sama5d3_xplained.dts b/arch/arm/dts/at91-sama5d3_xplained.dts index 69597102fb..20fba5f067 100644 --- a/arch/arm/dts/at91-sama5d3_xplained.dts +++ b/arch/arm/dts/at91-sama5d3_xplained.dts @@ -36,6 +36,18 @@ }; }; + onewire_tm: onewire { + gpios = <&pioE 23 GPIO_ACTIVE_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_onewire_tm_default>; + status = "okay"; + + w1_eeprom: w1_eeprom@0 { + compatible = "maxim,ds24b33"; + status = "okay"; + }; + }; + ahb { apb { mmc0: mmc@f0000000 { @@ -243,6 +255,11 @@ atmel,pins = <AT91_PIOE 9 AT91_PERIPH_GPIO AT91_PINCTRL_DEGLITCH>; /* PE9, conflicts with A9 */ }; + + pinctrl_onewire_tm_default: onewire_tm_default { + atmel,pins = + <AT91_PIOE 23 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>; + }; }; }; }; diff --git a/arch/arm/dts/at91-sama5d4_xplained.dts b/arch/arm/dts/at91-sama5d4_xplained.dts index ea35dc21b6..58a0e60d18 100644 --- a/arch/arm/dts/at91-sama5d4_xplained.dts +++ b/arch/arm/dts/at91-sama5d4_xplained.dts @@ -58,6 +58,18 @@ stdout-path = &usart3; }; + onewire_tm: onewire { + gpios = <&pioE 15 GPIO_ACTIVE_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_onewire_tm_default>; + status = "okay"; + + w1_eeprom: w1_eeprom@0 { + compatible = "maxim,ds24b33"; + status = "okay"; + }; + }; + memory { reg = <0x20000000 0x20000000>; }; @@ -199,6 +211,10 @@ atmel,pins = <AT91_PIOE 1 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; }; + pinctrl_onewire_tm_default: onewire_tm_default { + atmel,pins = + <AT91_PIOE 15 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP>; + }; }; }; }; diff --git a/arch/arm/dts/omap3-beagle-u-boot.dtsi b/arch/arm/dts/omap3-beagle-u-boot.dtsi index 094f9557b7..41beaf0900 100644 --- a/arch/arm/dts/omap3-beagle-u-boot.dtsi +++ b/arch/arm/dts/omap3-beagle-u-boot.dtsi @@ -11,10 +11,6 @@ }; }; -&mmc1 { - cd-inverted; -}; - &uart1 { reg-shift = <2>; }; diff --git a/arch/arm/dts/omap3-beagle-xm-ab-u-boot.dtsi b/arch/arm/dts/omap3-beagle-xm-ab-u-boot.dtsi index 094f9557b7..41beaf0900 100644 --- a/arch/arm/dts/omap3-beagle-xm-ab-u-boot.dtsi +++ b/arch/arm/dts/omap3-beagle-xm-ab-u-boot.dtsi @@ -11,10 +11,6 @@ }; }; -&mmc1 { - cd-inverted; -}; - &uart1 { reg-shift = <2>; }; diff --git a/arch/arm/dts/omap3-beagle-xm-u-boot.dtsi b/arch/arm/dts/omap3-beagle-xm-u-boot.dtsi index 094f9557b7..41beaf0900 100644 --- a/arch/arm/dts/omap3-beagle-xm-u-boot.dtsi +++ b/arch/arm/dts/omap3-beagle-xm-u-boot.dtsi @@ -11,10 +11,6 @@ }; }; -&mmc1 { - cd-inverted; -}; - &uart1 { reg-shift = <2>; }; diff --git a/arch/arm/dts/omap3-evm-37xx-u-boot.dtsi b/arch/arm/dts/omap3-evm-37xx-u-boot.dtsi index b09ce0efb5..de411316d8 100644 --- a/arch/arm/dts/omap3-evm-37xx-u-boot.dtsi +++ b/arch/arm/dts/omap3-evm-37xx-u-boot.dtsi @@ -11,10 +11,6 @@ }; }; -&mmc1 { - cd-inverted; -}; - &uart1 { reg-shift = <2>; }; diff --git a/arch/arm/dts/omap3-evm-u-boot.dtsi b/arch/arm/dts/omap3-evm-u-boot.dtsi index b09ce0efb5..de411316d8 100644 --- a/arch/arm/dts/omap3-evm-u-boot.dtsi +++ b/arch/arm/dts/omap3-evm-u-boot.dtsi @@ -11,10 +11,6 @@ }; }; -&mmc1 { - cd-inverted; -}; - &uart1 { reg-shift = <2>; }; diff --git a/arch/arm/dts/sama5d2.dtsi b/arch/arm/dts/sama5d2.dtsi index 6645a55364..830251a539 100644 --- a/arch/arm/dts/sama5d2.dtsi +++ b/arch/arm/dts/sama5d2.dtsi @@ -769,4 +769,9 @@ }; }; }; + + onewire_tm: onewire { + compatible = "w1-gpio"; + status = "disabled"; + }; }; diff --git a/arch/arm/dts/sama5d3.dtsi b/arch/arm/dts/sama5d3.dtsi index ba707b0ddf..7db66c5d50 100644 --- a/arch/arm/dts/sama5d3.dtsi +++ b/arch/arm/dts/sama5d3.dtsi @@ -1534,4 +1534,9 @@ }; }; }; + + onewire_tm: onewire { + compatible = "w1-gpio"; + status = "disabled"; + }; }; diff --git a/arch/arm/dts/sama5d4.dtsi b/arch/arm/dts/sama5d4.dtsi index 8072b8a4f2..8875d7ba76 100644 --- a/arch/arm/dts/sama5d4.dtsi +++ b/arch/arm/dts/sama5d4.dtsi @@ -1913,4 +1913,9 @@ }; }; }; + + onewire_tm: onewire { + compatible = "w1-gpio"; + status = "disabled"; + }; }; diff --git a/arch/arm/dts/stm32mp157-pinctrl.dtsi b/arch/arm/dts/stm32mp157-pinctrl.dtsi index c69c397964..85da592655 100644 --- a/arch/arm/dts/stm32mp157-pinctrl.dtsi +++ b/arch/arm/dts/stm32mp157-pinctrl.dtsi @@ -321,6 +321,12 @@ bias-disable; }; }; + + usbotg_hs_pins_a: usbotg_hs-0 { + pins { + pinmux = <STM32_PINMUX('A', 10, ANALOG)>; /* OTG_ID */ + }; + }; }; pinctrl_z: pin-controller-z@54004000 { diff --git a/arch/arm/dts/stm32mp157c-ev1-u-boot.dtsi b/arch/arm/dts/stm32mp157c-ev1-u-boot.dtsi index 2f4de3a066..30b173478c 100644 --- a/arch/arm/dts/stm32mp157c-ev1-u-boot.dtsi +++ b/arch/arm/dts/stm32mp157c-ev1-u-boot.dtsi @@ -25,6 +25,10 @@ regulator-always-on; }; +&usbotg_hs { + g-tx-fifo-size = <576>; +}; + /* SPL part **************************************/ &qspi { u-boot,dm-spl; @@ -60,3 +64,4 @@ &flash0 { u-boot,dm-spl; }; + diff --git a/arch/arm/dts/stm32mp157c-ev1.dts b/arch/arm/dts/stm32mp157c-ev1.dts index d6934f74e0..902a42bee2 100644 --- a/arch/arm/dts/stm32mp157c-ev1.dts +++ b/arch/arm/dts/stm32mp157c-ev1.dts @@ -96,6 +96,21 @@ }; }; +&usbh_ehci { + phys = <&usbphyc_port0>; + phy-names = "usb"; + vbus-supply = <&vbus_sw>; + status = "okay"; +}; + +&usbotg_hs { + pinctrl-names = "default"; + pinctrl-0 = <&usbotg_hs_pins_a>; + phys = <&usbphyc_port1 0>; + phy-names = "usb2-phy"; + status = "okay"; +}; + &usbphyc { status = "okay"; }; diff --git a/arch/arm/dts/stm32mp157c.dtsi b/arch/arm/dts/stm32mp157c.dtsi index cdf2946968..33c5981869 100644 --- a/arch/arm/dts/stm32mp157c.dtsi +++ b/arch/arm/dts/stm32mp157c.dtsi @@ -106,6 +106,26 @@ }; }; + pm_domain { + #address-cells = <1>; + #size-cells = <0>; + compatible = "st,stm32mp157c-pd"; + + pd_core_ret: core-ret-power-domain@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + #power-domain-cells = <0>; + label = "CORE-RETENTION"; + + pd_core: core-power-domain@2 { + reg = <2>; + #power-domain-cells = <0>; + label = "CORE"; + }; + }; + }; + soc { compatible = "simple-bus"; #address-cells = <1>; @@ -654,6 +674,22 @@ status = "disabled"; }; + usbotg_hs: usb-otg@49000000 { + compatible = "st,stm32mp1-hsotg", "snps,dwc2"; + reg = <0x49000000 0x10000>; + clocks = <&rcc USBO_K>; + clock-names = "otg"; + resets = <&rcc USBO_R>; + reset-names = "dwc2"; + interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>; + g-rx-fifo-size = <256>; + g-np-tx-fifo-size = <32>; + g-tx-fifo-size = <128 128 64 64 64 64 32 32>; + dr_mode = "otg"; + power-domains = <&pd_core>; + status = "disabled"; + }; + rcc: rcc@50000000 { compatible = "st,stm32mp1-rcc", "syscon"; reg = <0x50000000 0x1000>; diff --git a/arch/arm/include/asm/arch-omap3/mmc_host_def.h b/arch/arm/include/asm/arch-omap3/mmc_host_def.h index 9f2896c4b9..39a7cba0f6 100644 --- a/arch/arm/include/asm/arch-omap3/mmc_host_def.h +++ b/arch/arm/include/asm/arch-omap3/mmc_host_def.h @@ -51,6 +51,7 @@ typedef struct t2 { #define PBIASLITEPWRDNZ0 (1 << 1) #define PBIASSPEEDCTRL0 (1 << 2) #define PBIASLITEPWRDNZ1 (1 << 9) +#define PBIASLITEVMODE1 (1 << 8) #define PBIASLITEVMODE0 (1 << 0) #define CTLPROGIO1SPEEDCTRL (1 << 20) diff --git a/arch/arm/include/asm/arch-spear/spr_misc.h b/arch/arm/include/asm/arch-spear/spr_misc.h index 65063fca51..0171119351 100644 --- a/arch/arm/include/asm/arch-spear/spr_misc.h +++ b/arch/arm/include/asm/arch-spear/spr_misc.h @@ -146,11 +146,13 @@ struct misc_regs { #define MISC_SMIENB 0x00200000 #define MISC_GPIO3ENB 0x00040000 #define MISC_GPT3ENB 0x00010000 +#define MISC_SSP3ENB 0x00004000 #define MISC_GPIO4ENB 0x00002000 #define MISC_GPT2ENB 0x00000800 #define MISC_FSMCENB 0x00000200 #define MISC_I2CENB 0x00000080 -#define MISC_SSP2ENB 0x00000070 +#define MISC_SSP2ENB 0x00000040 +#define MISC_SSP1ENB 0x00000020 #define MISC_UART0ENB 0x00000008 /* PERIPH_CLK_CFG */ diff --git a/arch/arm/include/asm/arch-zynqmp/sys_proto.h b/arch/arm/include/asm/arch-zynqmp/sys_proto.h index 773b930512..9fa44d084c 100644 --- a/arch/arm/include/asm/arch-zynqmp/sys_proto.h +++ b/arch/arm/include/asm/arch-zynqmp/sys_proto.h @@ -21,6 +21,21 @@ #define ZYNQMP_FPGA_AUTH_DDR 1 +#define ZYNQMP_SIP_SVC_GET_API_VERSION 0xC2000001 + +#define ZYNQMP_PM_VERSION_MAJOR 1 +#define ZYNQMP_PM_VERSION_MINOR 0 +#define ZYNQMP_PM_VERSION_MAJOR_SHIFT 16 +#define ZYNQMP_PM_VERSION_MINOR_MASK 0xFFFF + +#define ZYNQMP_PM_VERSION \ + ((ZYNQMP_PM_VERSION_MAJOR << ZYNQMP_PM_VERSION_MAJOR_SHIFT) | \ + ZYNQMP_PM_VERSION_MINOR) + +#define ZYNQMP_PM_VERSION_INVALID ~0 + +#define PMUFW_V1_0 ((1 << ZYNQMP_PM_VERSION_MAJOR_SHIFT) | 0) + enum { IDCODE, VERSION, @@ -44,7 +59,7 @@ unsigned int zynqmp_get_silicon_version(void); void handoff_setup(void); -void zynqmp_pmufw_version(void); +unsigned int zynqmp_pmufw_version(void); int zynqmp_mmio_write(const u32 address, const u32 mask, const u32 value); int zynqmp_mmio_read(const u32 address, u32 *value); int invoke_smc(u32 pm_api_id, u32 arg0, u32 arg1, u32 arg2, u32 arg3, diff --git a/arch/arm/include/asm/atomic.h b/arch/arm/include/asm/atomic.h index 171f4d9792..5822b0a52c 100644 --- a/arch/arm/include/asm/atomic.h +++ b/arch/arm/include/asm/atomic.h @@ -20,152 +20,8 @@ #error SMP not supported #endif -typedef struct { volatile int counter; } atomic_t; -#if BITS_PER_LONG == 32 -typedef struct { volatile long long counter; } atomic64_t; -#else /* BIT_PER_LONG == 32 */ -typedef struct { volatile long counter; } atomic64_t; -#endif - -#define ATOMIC_INIT(i) { (i) } - -#ifdef __KERNEL__ #include <asm/proc-armv/system.h> - -#define atomic_read(v) ((v)->counter) -#define atomic_set(v, i) (((v)->counter) = (i)) -#define atomic64_read(v) atomic_read(v) -#define atomic64_set(v, i) atomic_set(v, i) - -static inline void atomic_add(int i, volatile atomic_t *v) -{ - unsigned long flags = 0; - - local_irq_save(flags); - v->counter += i; - local_irq_restore(flags); -} - -static inline void atomic_sub(int i, volatile atomic_t *v) -{ - unsigned long flags = 0; - - local_irq_save(flags); - v->counter -= i; - local_irq_restore(flags); -} - -static inline void atomic_inc(volatile atomic_t *v) -{ - unsigned long flags = 0; - - local_irq_save(flags); - v->counter += 1; - local_irq_restore(flags); -} - -static inline void atomic_dec(volatile atomic_t *v) -{ - unsigned long flags = 0; - - local_irq_save(flags); - v->counter -= 1; - local_irq_restore(flags); -} - -static inline int atomic_dec_and_test(volatile atomic_t *v) -{ - unsigned long flags = 0; - int val; - - local_irq_save(flags); - val = v->counter; - v->counter = val -= 1; - local_irq_restore(flags); - - return val == 0; -} - -static inline int atomic_add_negative(int i, volatile atomic_t *v) -{ - unsigned long flags = 0; - int val; - - local_irq_save(flags); - val = v->counter; - v->counter = val += i; - local_irq_restore(flags); - - return val < 0; -} - -static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr) -{ - unsigned long flags = 0; - - local_irq_save(flags); - *addr &= ~mask; - local_irq_restore(flags); -} - -#if BITS_PER_LONG == 32 - -static inline void atomic64_add(long long i, volatile atomic64_t *v) -{ - unsigned long flags = 0; - - local_irq_save(flags); - v->counter += i; - local_irq_restore(flags); -} - -static inline void atomic64_sub(long long i, volatile atomic64_t *v) -{ - unsigned long flags = 0; - - local_irq_save(flags); - v->counter -= i; - local_irq_restore(flags); -} - -#else /* BIT_PER_LONG == 32 */ - -static inline void atomic64_add(long i, volatile atomic64_t *v) -{ - unsigned long flags = 0; - - local_irq_save(flags); - v->counter += i; - local_irq_restore(flags); -} - -static inline void atomic64_sub(long i, volatile atomic64_t *v) -{ - unsigned long flags = 0; - - local_irq_save(flags); - v->counter -= i; - local_irq_restore(flags); -} -#endif - -static inline void atomic64_inc(volatile atomic64_t *v) -{ - unsigned long flags = 0; - - local_irq_save(flags); - v->counter += 1; - local_irq_restore(flags); -} - -static inline void atomic64_dec(volatile atomic64_t *v) -{ - unsigned long flags = 0; - - local_irq_save(flags); - v->counter -= 1; - local_irq_restore(flags); -} +#include <asm-generic/atomic.h> /* Atomic operations are already serializing on ARM */ #define smp_mb__before_atomic_dec() barrier() @@ -174,4 +30,3 @@ static inline void atomic64_dec(volatile atomic64_t *v) #define smp_mb__after_atomic_inc() barrier() #endif -#endif diff --git a/arch/arm/include/asm/omap_mmc.h b/arch/arm/include/asm/omap_mmc.h index 42ce8dcd6d..6d31cc4422 100644 --- a/arch/arm/include/asm/omap_mmc.h +++ b/arch/arm/include/asm/omap_mmc.h @@ -68,7 +68,6 @@ struct omap_hsmmc_plat { struct mmc_config cfg; struct hsmmc *base_addr; struct mmc *mmc; - bool cd_inverted; u32 controller_flags; const char *hw_rev; }; diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index 69856c8942..a6329dc022 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig @@ -151,6 +151,7 @@ config TARGET_SAMA5D2_PTC_EK bool "SAMA5D2 PTC EK board" select BOARD_EARLY_INIT_F select SAMA5D2 + select BOARD_LATE_INIT config TARGET_SAMA5D2_XPLAINED bool "SAMA5D2 Xplained board" @@ -177,6 +178,7 @@ config TARGET_SAMA5D3_XPLAINED select BOARD_EARLY_INIT_F select SAMA5D3 select SUPPORT_SPL + select BOARD_LATE_INIT config TARGET_SAMA5D3XEK bool "SAMA5D3X-EK board" diff --git a/arch/arm/mach-davinci/da850_lowlevel.c b/arch/arm/mach-davinci/da850_lowlevel.c index 95dc93a24f..822e0dc4a1 100644 --- a/arch/arm/mach-davinci/da850_lowlevel.c +++ b/arch/arm/mach-davinci/da850_lowlevel.c @@ -288,10 +288,10 @@ int arch_cpu_init(void) /* GPIO setup */ board_gpio_init(); - +#if !CONFIG_IS_ENABLED(DM_SERIAL) NS16550_init((NS16550_t)(CONFIG_SYS_NS16550_COM1), CONFIG_SYS_NS16550_CLK / 16 / CONFIG_BAUDRATE); - +#endif /* * Fix Power and Emulation Management Register * see sprufw3a.pdf page 37 Table 24 diff --git a/arch/arm/mach-tegra/board2.c b/arch/arm/mach-tegra/board2.c index 421a71b301..12257a42b5 100644 --- a/arch/arm/mach-tegra/board2.c +++ b/arch/arm/mach-tegra/board2.c @@ -6,6 +6,7 @@ #include <common.h> #include <dm.h> +#include <efi_loader.h> #include <errno.h> #include <ns16550.h> #include <usb.h> @@ -210,6 +211,19 @@ int board_early_init_f(void) int board_late_init(void) { +#if CONFIG_IS_ENABLED(EFI_LOADER) + if (gd->bd->bi_dram[1].start) { + /* + * Only bank 0 is below board_get_usable_ram_top(), so all of + * bank 1 is not mapped by the U-Boot MMU configuration, and so + * we must prevent EFI from using it. + */ + efi_add_memory_map(gd->bd->bi_dram[1].start, + gd->bd->bi_dram[1].size >> EFI_PAGE_SHIFT, + EFI_BOOT_SERVICES_DATA, false); + } +#endif + #if defined(CONFIG_TEGRA_SUPPORT_NON_SECURE) if (tegra_cpu_is_non_secure()) { printf("CPU is in NS mode\n"); diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 6e5e0ffe65..071dea04ec 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -28,6 +28,7 @@ config TARGET_MALTA select DM_SERIAL select DYNAMIC_IO_PORT_BASE select MIPS_CM + select MIPS_INSERT_BOOT_CONFIG select MIPS_L1_CACHE_SHIFT_6 select MIPS_L2_CACHE select OF_CONTROL @@ -68,6 +69,22 @@ config ARCH_BMIPS select SYSRESET imply CMD_DM +config ARCH_MT7620 + bool "Support MT7620/7688 SoCs" + imply CMD_DM + select DISPLAY_CPUINFO + select DM + select DM_SERIAL + imply DM_SPI + imply DM_SPI_FLASH + select MIPS_TUNE_24KC + select OF_CONTROL + select ROM_EXCEPTION_VECTORS + select SUPPORTS_CPU_MIPS32_R1 + select SUPPORTS_CPU_MIPS32_R2 + select SUPPORTS_LITTLE_ENDIAN + select SYSRESET + config MACH_PIC32 bool "Support Microchip PIC32" select DM @@ -120,6 +137,7 @@ source "board/qemu-mips/Kconfig" source "arch/mips/mach-ath79/Kconfig" source "arch/mips/mach-bmips/Kconfig" source "arch/mips/mach-pic32/Kconfig" +source "arch/mips/mach-mt7620/Kconfig" if MIPS @@ -218,6 +236,18 @@ config MIPS_CM_BASE the GCRs occupy a region of the physical address space which is otherwise unused, or at minimum that software doesn't need to access. +config MIPS_CACHE_INDEX_BASE + hex "Index base address for cache initialisation" + default 0x80000000 if CPU_MIPS32 + default 0xffffffff80000000 if CPU_MIPS64 + help + This is the base address for a memory block, which is used for + initialising the cache lines. This is also the base address of a memory + block which is used for loading and filling cache lines when + SYS_MIPS_CACHE_INIT_RAM_LOAD is selected. + Normally this is CKSEG0. If the MIPS system needs to move this block + to some SRAM or ScratchPad RAM, adapt this option accordingly. + endmenu menu "OS boot interface" @@ -390,6 +420,28 @@ config MIPS_CM wish U-Boot to configure it or make use of it to retrieve system information such as cache configuration. +config MIPS_INSERT_BOOT_CONFIG + bool + default n + help + Enable this to insert some board-specific boot configuration in + the U-Boot binary at offset 0x10. + +config MIPS_BOOT_CONFIG_WORD0 + hex + depends on MIPS_INSERT_BOOT_CONFIG + default 0x420 if TARGET_MALTA + default 0x0 + help + Value which is inserted as boot config word 0. + +config MIPS_BOOT_CONFIG_WORD1 + hex + depends on MIPS_INSERT_BOOT_CONFIG + default 0x0 + help + Value which is inserted as boot config word 1. + endif endmenu diff --git a/arch/mips/Makefile b/arch/mips/Makefile index a36f5f1fb6..802244a06e 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -14,6 +14,7 @@ libs-y += arch/mips/lib/ machine-$(CONFIG_ARCH_ATH79) += ath79 machine-$(CONFIG_ARCH_BMIPS) += bmips machine-$(CONFIG_MACH_PIC32) += pic32 +machine-$(CONFIG_ARCH_MT7620) += mt7620 machdirs := $(patsubst %,arch/mips/mach-%/,$(machine-y)) libs-y += $(machdirs) diff --git a/arch/mips/cpu/start.S b/arch/mips/cpu/start.S index 6ca0916c06..1d21b2324a 100644 --- a/arch/mips/cpu/start.S +++ b/arch/mips/cpu/start.S @@ -84,25 +84,14 @@ ENTRY(_start) b reset mtc0 zero, CP0_COUNT # clear cp0 count for most accurate boot timing -#if defined(CONFIG_SYS_XWAY_EBU_BOOTCFG) +#if defined(CONFIG_MIPS_INSERT_BOOT_CONFIG) /* - * Almost all Lantiq XWAY SoC devices have an external bus unit (EBU) to - * access external NOR flashes. If the board boots from NOR flash the - * internal BootROM does a blind read at address 0xB0000010 to read the - * initial configuration for that EBU in order to access the flash - * device with correct parameters. This config option is board-specific. + * Store some board-specific boot configuration. This is used by some + * MIPS systems like Malta. */ .org 0x10 - .word CONFIG_SYS_XWAY_EBU_BOOTCFG - .word 0x0 -#endif -#if defined(CONFIG_MALTA) - /* - * Linux expects the Board ID here. - */ - .org 0x10 - .word 0x00000420 # 0x420 (Malta Board with CoreLV) - .word 0x00000000 + .word CONFIG_MIPS_BOOT_CONFIG_WORD0 + .word CONFIG_MIPS_BOOT_CONFIG_WORD1 #endif #if defined(CONFIG_ROM_EXCEPTION_VECTORS) diff --git a/arch/mips/dts/brcm,bcm6838.dtsi b/arch/mips/dts/brcm,bcm6838.dtsi index d365d0f2ce..1018f9ee49 100644 --- a/arch/mips/dts/brcm,bcm6838.dtsi +++ b/arch/mips/dts/brcm,bcm6838.dtsi @@ -55,6 +55,18 @@ u-boot,dm-pre-reloc; }; + gpio_test_port: syscon@14e00294 { + compatible = "syscon"; + reg = <0x14e00294 0x1c>; + }; + + pinctrl: pinctrl { + compatible = "brcm,bcm6838-pinctrl"; + regmap = <&gpio_test_port>; + brcm,pins-count = <74>; + brcm,functions-count = <8>; + }; + uart0: serial@14e00500 { compatible = "brcm,bcm6345-uart"; reg = <0x14e00500 0x18>; diff --git a/arch/mips/dts/gardena-smart-gateway-mt7688.dts b/arch/mips/dts/gardena-smart-gateway-mt7688.dts new file mode 100644 index 0000000000..ee99c3d17c --- /dev/null +++ b/arch/mips/dts/gardena-smart-gateway-mt7688.dts @@ -0,0 +1,54 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2018 Stefan Roese <sr@denx.de> + */ + +/dts-v1/; + +#include "mt7628a.dtsi" + +/ { + compatible = "gardena,smart-gateway-mt7688", "ralink,mt7628a-soc"; + model = "Gardena smart-Gateway-MT7688"; + + aliases { + serial0 = &uart0; + spi0 = &spi0; + }; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x08000000>; + }; + + chosen { + bootargs = "console=ttyS0,57600"; + stdout-path = &uart0; + }; +}; + +&uart0 { + status = "okay"; + clock-frequency = <40000000>; +}; + +&spi0 { + status = "okay"; + num-cs = <2>; + + spi-flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "spi-flash", "jedec,spi-nor"; + spi-max-frequency = <40000000>; + reg = <0>; + }; + + spi-nand@1 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "spi-nand"; + spi-max-frequency = <40000000>; + reg = <1>; + }; +}; diff --git a/arch/mips/dts/linkit-smart-7688.dts b/arch/mips/dts/linkit-smart-7688.dts new file mode 100644 index 0000000000..df4bf907c6 --- /dev/null +++ b/arch/mips/dts/linkit-smart-7688.dts @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2018 Stefan Roese <sr@denx.de> + */ + +/dts-v1/; + +#include "mt7628a.dtsi" + +/ { + compatible = "seeed,linkit-smart-7688", "ralink,mt7628a-soc"; + model = "LinkIt-Smart-7688"; + + aliases { + serial0 = &uart2; + spi0 = &spi0; + }; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x08000000>; + }; + + chosen { + bootargs = "console=ttyS0,57600"; + stdout-path = &uart2; + }; +}; + +&uart2 { + status = "okay"; + clock-frequency = <40000000>; +}; + +&spi0 { + status = "okay"; + num-cs = <2>; + + spi-flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "spi-flash", "jedec,spi-nor"; + spi-max-frequency = <25000000>; + reg = <0>; + }; +}; diff --git a/arch/mips/dts/mt7628a.dtsi b/arch/mips/dts/mt7628a.dtsi new file mode 100644 index 0000000000..c14259b170 --- /dev/null +++ b/arch/mips/dts/mt7628a.dtsi @@ -0,0 +1,144 @@ +// SPDX-License-Identifier: GPL-2.0 + +/ { + #address-cells = <1>; + #size-cells = <1>; + compatible = "ralink,mt7628a-soc"; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + compatible = "mti,mips24KEc"; + device_type = "cpu"; + reg = <0>; + }; + }; + + resetc: reset-controller { + compatible = "ralink,rt2880-reset"; + #reset-cells = <1>; + }; + + cpuintc: interrupt-controller { + #address-cells = <0>; + #interrupt-cells = <1>; + interrupt-controller; + compatible = "mti,cpu-interrupt-controller"; + }; + + palmbus@10000000 { + compatible = "palmbus", "simple-bus"; + reg = <0x10000000 0x200000>; + ranges = <0x0 0x10000000 0x1FFFFF>; + + #address-cells = <1>; + #size-cells = <1>; + + sysc: system-controller@0 { + compatible = "ralink,mt7620a-sysc", "syscon"; + reg = <0x0 0x100>; + }; + + syscon-reboot { + compatible = "syscon-reboot"; + regmap = <&sysc>; + offset = <0x34>; + mask = <0x1>; + }; + + intc: interrupt-controller@200 { + compatible = "ralink,rt2880-intc"; + reg = <0x200 0x100>; + + interrupt-controller; + #interrupt-cells = <1>; + + resets = <&resetc 9>; + reset-names = "intc"; + + interrupt-parent = <&cpuintc>; + interrupts = <2>; + + ralink,intc-registers = <0x9c 0xa0 + 0x6c 0xa4 + 0x80 0x78>; + }; + + memory-controller@300 { + compatible = "ralink,mt7620a-memc"; + reg = <0x300 0x100>; + }; + + spi0: spi@b00 { + compatible = "ralink,mt7621-spi"; + reg = <0xb00 0x40>; + #address-cells = <1>; + #size-cells = <0>; + + clock-frequency = <200000000>; + }; + + uart0: uartlite@c00 { + compatible = "ns16550a"; + reg = <0xc00 0x100>; + + resets = <&resetc 12>; + reset-names = "uart0"; + + interrupt-parent = <&intc>; + interrupts = <20>; + + reg-shift = <2>; + }; + + uart1: uart1@d00 { + compatible = "ns16550a"; + reg = <0xd00 0x100>; + + resets = <&resetc 19>; + reset-names = "uart1"; + + interrupt-parent = <&intc>; + interrupts = <21>; + + reg-shift = <2>; + }; + + uart2: uart2@e00 { + compatible = "ns16550a"; + reg = <0xe00 0x100>; + + resets = <&resetc 20>; + reset-names = "uart2"; + + interrupt-parent = <&intc>; + interrupts = <22>; + + reg-shift = <2>; + }; + }; + + usb_phy: usb-phy@10120000 { + compatible = "mediatek,mt7628-usbphy"; + reg = <0x10120000 0x1000>; + + #phy-cells = <0>; + + ralink,sysctl = <&sysc>; + resets = <&resetc 22 &resetc 25>; + reset-names = "host", "device"; + }; + + ehci@101c0000 { + compatible = "generic-ehci"; + reg = <0x101c0000 0x1000>; + + phys = <&usb_phy>; + phy-names = "usb"; + + interrupt-parent = <&intc>; + interrupts = <18>; + }; +}; diff --git a/arch/mips/include/asm/atomic.h b/arch/mips/include/asm/atomic.h new file mode 100644 index 0000000000..c4f08b7820 --- /dev/null +++ b/arch/mips/include/asm/atomic.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2016 Cadence Design Systems Inc. + */ + +#ifndef _MIPS_ATOMIC_H +#define _MIPS_ATOMIC_H + +#include <asm/system.h> +#include <asm-generic/atomic.h> + +#endif diff --git a/arch/mips/lib/cache.c b/arch/mips/lib/cache.c index 1d14fc487e..d56fd1e0f4 100644 --- a/arch/mips/lib/cache.c +++ b/arch/mips/lib/cache.c @@ -175,3 +175,23 @@ void invalidate_dcache_range(ulong start_addr, ulong stop) /* ensure cache ops complete before any further memory accesses */ sync(); } + +int dcache_status(void) +{ + unsigned int cca = read_c0_config() & CONF_CM_CMASK; + return cca != CONF_CM_UNCACHED; +} + +void dcache_enable(void) +{ + puts("Not supported!\n"); +} + +void dcache_disable(void) +{ + /* change CCA to uncached */ + change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED); + + /* ensure the pipeline doesn't contain now-invalid instructions */ + instruction_hazard_barrier(); +} diff --git a/arch/mips/lib/cache_init.S b/arch/mips/lib/cache_init.S index b209f23f0a..cfad1d9c8a 100644 --- a/arch/mips/lib/cache_init.S +++ b/arch/mips/lib/cache_init.S @@ -14,12 +14,6 @@ #include <asm/cacheops.h> #include <asm/cm.h> -#ifndef CONFIG_SYS_MIPS_CACHE_MODE -#define CONFIG_SYS_MIPS_CACHE_MODE CONF_CM_CACHABLE_NONCOHERENT -#endif - -#define INDEX_BASE CKSEG0 - .macro f_fill64 dst, offset, val LONG_S \val, (\offset + 0 * LONGSIZE)(\dst) LONG_S \val, (\offset + 1 * LONGSIZE)(\dst) @@ -84,6 +78,7 @@ 10: .set pop .endm + /* * mips_cache_reset - low level initialisation of the primary caches * @@ -255,7 +250,7 @@ l2_probe_done: /* * Now clear that much memory starting from zero. */ - PTR_LI a0, CKSEG1 + PTR_LI a0, CKSEG1ADDR(CONFIG_MIPS_CACHE_INDEX_BASE) PTR_ADDU a1, a0, v0 2: PTR_ADDIU a0, 64 f_fill64 a0, -64, zero @@ -271,7 +266,7 @@ l2_probe_done: bnez R_L2_BYPASSED, l1_init l2_init: - PTR_LI t0, INDEX_BASE + PTR_LI t0, CKSEG0ADDR(CONFIG_MIPS_CACHE_INDEX_BASE) PTR_ADDU t1, t0, R_L2_SIZE 1: cache INDEX_STORE_TAG_SD, 0(t0) PTR_ADDU t0, t0, R_L2_LINE @@ -307,48 +302,50 @@ l1_init: * Initialize the I-cache first, */ blez R_IC_SIZE, 1f - PTR_LI t0, INDEX_BASE + PTR_LI t0, CKSEG0ADDR(CONFIG_MIPS_CACHE_INDEX_BASE) PTR_ADDU t1, t0, R_IC_SIZE /* clear tag to invalidate */ cache_loop t0, t1, R_IC_LINE, INDEX_STORE_TAG_I #ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD /* fill once, so data field parity is correct */ - PTR_LI t0, INDEX_BASE + PTR_LI t0, CKSEG0ADDR(CONFIG_MIPS_CACHE_INDEX_BASE) cache_loop t0, t1, R_IC_LINE, FILL /* invalidate again - prudent but not strictly neccessary */ - PTR_LI t0, INDEX_BASE + PTR_LI t0, CKSEG0ADDR(CONFIG_MIPS_CACHE_INDEX_BASE) cache_loop t0, t1, R_IC_LINE, INDEX_STORE_TAG_I #endif - - /* Enable use of the I-cache by setting Config.K0 */ sync - mfc0 t0, CP0_CONFIG - li t1, CONFIG_SYS_MIPS_CACHE_MODE -#if __mips_isa_rev >= 2 - ins t0, t1, 0, 3 -#else - ori t0, t0, CONF_CM_CMASK - xori t0, t0, CONF_CM_CMASK + + /* + * Enable use of the I-cache by setting Config.K0. The code for this + * must be executed from KSEG1. Jump from KSEG0 to KSEG1 to do this. + * Jump back to KSEG0 after caches are enabled and insert an + * instruction hazard barrier. + */ + PTR_LA t0, change_k0_cca + li t1, CPHYSADDR(~0) + and t0, t0, t1 + PTR_LI t1, CKSEG1 or t0, t0, t1 -#endif - mtc0 t0, CP0_CONFIG + li a0, CONF_CM_CACHABLE_NONCOHERENT + jalr.hb t0 /* * then initialize D-cache. */ 1: blez R_DC_SIZE, 3f - PTR_LI t0, INDEX_BASE + PTR_LI t0, CKSEG0ADDR(CONFIG_MIPS_CACHE_INDEX_BASE) PTR_ADDU t1, t0, R_DC_SIZE /* clear all tags */ cache_loop t0, t1, R_DC_LINE, INDEX_STORE_TAG_D #ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD /* load from each line (in cached space) */ - PTR_LI t0, INDEX_BASE + PTR_LI t0, CKSEG0ADDR(CONFIG_MIPS_CACHE_INDEX_BASE) 2: LONG_L zero, 0(t0) PTR_ADDU t0, R_DC_LINE bne t0, t1, 2b /* clear all tags */ - PTR_LI t0, INDEX_BASE + PTR_LI t0, CKSEG0ADDR(CONFIG_MIPS_CACHE_INDEX_BASE) cache_loop t0, t1, R_DC_LINE, INDEX_STORE_TAG_D #endif 3: @@ -391,16 +388,9 @@ l2_unbypass: beqz t0, 2f /* Change Config.K0 to a coherent CCA */ - mfc0 t0, CP0_CONFIG - li t1, CONF_CM_CACHABLE_COW -#if __mips_isa_rev >= 2 - ins t0, t1, 0, 3 -#else - ori t0, t0, CONF_CM_CMASK - xori t0, t0, CONF_CM_CMASK - or t0, t0, t1 -#endif - mtc0 t0, CP0_CONFIG + PTR_LA t0, change_k0_cca + li a0, CONF_CM_CACHABLE_COW + jalr t0 /* * Join the coherent domain such that the caches of this core are kept @@ -421,51 +411,19 @@ l2_unbypass: return: /* Ensure all cache operations complete before returning */ sync - jr ra + jr R_RETURN END(mips_cache_reset) -/* - * dcache_status - get cache status - * - * RETURNS: 0 - cache disabled; 1 - cache enabled - * - */ -LEAF(dcache_status) - mfc0 t0, CP0_CONFIG - li t1, CONF_CM_UNCACHED - andi t0, t0, CONF_CM_CMASK - move v0, zero - beq t0, t1, 2f - li v0, 1 -2: jr ra - END(dcache_status) - -/* - * dcache_disable - disable cache - * - * RETURNS: N/A - * - */ -LEAF(dcache_disable) - mfc0 t0, CP0_CONFIG - li t1, -8 - and t0, t0, t1 - ori t0, t0, CONF_CM_UNCACHED - mtc0 t0, CP0_CONFIG - jr ra - END(dcache_disable) +LEAF(change_k0_cca) + mfc0 t0, CP0_CONFIG +#if __mips_isa_rev >= 2 + ins t0, a0, 0, 3 +#else + xor a0, a0, t0 + andi a0, a0, CONF_CM_CMASK + xor a0, a0, t0 +#endif + mtc0 a0, CP0_CONFIG -/* - * dcache_enable - enable cache - * - * RETURNS: N/A - * - */ -LEAF(dcache_enable) - mfc0 t0, CP0_CONFIG - ori t0, CONF_CM_CMASK - xori t0, CONF_CM_CMASK - ori t0, CONFIG_SYS_MIPS_CACHE_MODE - mtc0 t0, CP0_CONFIG - jr ra - END(dcache_enable) + jr.hb ra + END(change_k0_cca) diff --git a/arch/mips/mach-mt7620/Kconfig b/arch/mips/mach-mt7620/Kconfig new file mode 100644 index 0000000000..13a7bd2cc0 --- /dev/null +++ b/arch/mips/mach-mt7620/Kconfig @@ -0,0 +1,135 @@ +menu "MediaTek MIPS platforms" + depends on ARCH_MT7620 + +config SYS_MALLOC_F_LEN + default 0x1000 + +config SYS_SOC + default "mt7620" if SOC_MT7620 + +choice + prompt "MediaTek MIPS SoC select" + +config SOC_MT7620 + bool "MT7620/8" + select MIPS_L1_CACHE_SHIFT_5 + help + This supports MediaTek MIPS MT7620 family. + +endchoice + +choice + prompt "Board select" + +config BOARD_GARDENA_SMART_GATEWAY_MT7688 + bool "Gardena Smart Gateway" + depends on SOC_MT7620 + select SUPPORTS_BOOT_RAM + help + Gardena Smart Gateway boards have a MT7688 SoC with 128 MiB of RAM + and 8 MiB of flash (SPI NOR) and additional SPI NAND storage. + +config BOARD_LINKIT_SMART_7688 + bool "LinkIt Smart 7688" + depends on SOC_MT7620 + select SUPPORTS_BOOT_RAM + help + Seeed LinkIt Smart 7688 boards have a MT7688 SoC with 128 MiB of RAM + and 32 MiB of flash (SPI). + Between its different peripherals there's an integrated switch with 4 + ethernet ports, 1 USB port, 1 UART, GPIO buttons and LEDs, and + a MT7688 (PCIe). + +endchoice + +choice + prompt "Boot mode" + +config BOOT_RAM + bool "RAM boot" + depends on SUPPORTS_BOOT_RAM + help + This builds an image that is linked to a RAM address. It can be used + for booting from CFE via TFTP using an ELF image, but it can also be + booted from RAM by other bootloaders using a BIN image. + +config BOOT_ROM + bool "ROM boot" + depends on SUPPORTS_BOOT_RAM + help + This builds an image that is linked to a ROM address. It can be + used as main bootloader image which is programmed onto the onboard + flash storage (SPI NOR). + +endchoice + +choice + prompt "DDR2 size" + +config ONBOARD_DDR2_SIZE_256MBIT + bool "256MBit (32MByte) total size" + depends on BOOT_ROM + help + Use 256MBit (32MByte) of DDR total size + +config ONBOARD_DDR2_SIZE_512MBIT + bool "512MBit (64MByte) total size" + depends on BOOT_ROM + help + Use 512MBit (64MByte) of DDR total size + +config ONBOARD_DDR2_SIZE_1024MBIT + bool "1024MBit (128MByte) total size" + depends on BOOT_ROM + help + Use 1024MBit (128MByte) of DDR total size + +config ONBOARD_DDR2_SIZE_2048MBIT + bool "2048MBit (256MByte) total size" + depends on BOOT_ROM + help + Use 2048MBit (256MByte) of DDR total size + +endchoice + +choice + prompt "DDR2 chip width" + +config ONBOARD_DDR2_CHIP_WIDTH_8BIT + bool "8bit DDR chip width" + depends on BOOT_ROM + help + Use DDR chips with 8bit width + +config ONBOARD_DDR2_CHIP_WIDTH_16BIT + bool "16bit DDR chip width" + depends on BOOT_ROM + help + Use DDR chips with 16bit width + +endchoice + +choice + prompt "DDR2 bus width" + +config ONBOARD_DDR2_BUS_WIDTH_16BIT + bool "16bit DDR bus width" + depends on BOOT_ROM + help + Use 16bit DDR bus width + +config ONBOARD_DDR2_BUS_WIDTH_32BIT + bool "32bit DDR bus width" + depends on BOOT_ROM + help + Use 32bit DDR bus width + +endchoice + +config SUPPORTS_BOOT_RAM + bool + +source "board/gardena/smart-gateway-mt7688/Kconfig" +source "board/seeed/linkit-smart-7688/Kconfig" + +endmenu diff --git a/arch/mips/mach-mt7620/Makefile b/arch/mips/mach-mt7620/Makefile new file mode 100644 index 0000000000..1f3e65e8a5 --- /dev/null +++ b/arch/mips/mach-mt7620/Makefile @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: GPL-2.0+ + +obj-y += cpu.o + +ifndef CONFIG_SKIP_LOWLEVEL_INIT +obj-y += ddr_calibrate.o +obj-y += lowlevel_init.o +endif diff --git a/arch/mips/mach-mt7620/cpu.c b/arch/mips/mach-mt7620/cpu.c new file mode 100644 index 0000000000..457f09f32c --- /dev/null +++ b/arch/mips/mach-mt7620/cpu.c @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018 Stefan Roese <sr@denx.de> + */ + +#include <common.h> +#include <dm.h> +#include <ram.h> +#include <asm/io.h> +#include <linux/io.h> +#include <linux/sizes.h> +#include "mt76xx.h" + +#define STR_LEN 6 + +#ifdef CONFIG_BOOT_ROM +int mach_cpu_init(void) +{ + ddr_calibrate(); + + return 0; +} +#endif + +int dram_init(void) +{ + gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE, SZ_256M); + + return 0; +} + +int print_cpuinfo(void) +{ + static const char * const boot_str[] = { "PLL (3-Byte SPI Addr)", + "PLL (4-Byte SPI Addr)", + "XTAL (3-Byte SPI Addr)", + "XTAL (4-Byte SPI Addr)" }; + const void *blob = gd->fdt_blob; + void __iomem *sysc_base; + char buf[STR_LEN + 1]; + fdt_addr_t base; + fdt_size_t size; + char *str; + int node; + u32 val; + + /* Get system controller base address */ + node = fdt_node_offset_by_compatible(blob, -1, "ralink,mt7620a-sysc"); + if (node < 0) + return -FDT_ERR_NOTFOUND; + + base = fdtdec_get_addr_size_auto_noparent(blob, node, "reg", + 0, &size, true); + if (base == FDT_ADDR_T_NONE) + return -EINVAL; + + sysc_base = ioremap_nocache(base, size); + + str = (char *)sysc_base + MT76XX_CHIPID_OFFS; + snprintf(buf, STR_LEN + 1, "%s", str); + val = readl(sysc_base + MT76XX_CHIP_REV_ID_OFFS); + printf("CPU: %-*s Rev %ld.%ld - ", STR_LEN, buf, + (val & GENMASK(11, 8)) >> 8, val & GENMASK(3, 0)); + + val = (readl(sysc_base + MT76XX_SYSCFG0_OFFS) & GENMASK(3, 1)) >> 1; + printf("Boot from %s\n", boot_str[val]); + + return 0; +} diff --git a/arch/mips/mach-mt7620/ddr_calibrate.c b/arch/mips/mach-mt7620/ddr_calibrate.c new file mode 100644 index 0000000000..75763c4528 --- /dev/null +++ b/arch/mips/mach-mt7620/ddr_calibrate.c @@ -0,0 +1,308 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018 Stefan Roese <sr@denx.de> + * + * This code is mostly based on the code extracted from this MediaTek + * github repository: + * + * https://github.com/MediaTek-Labs/linkit-smart-uboot.git + * + * I was not able to find a specific license or other developers + * copyrights here, so I can't add them here. + * + * Most functions in this file are copied from the MediaTek U-Boot + * repository. Without any documentation, it was impossible to really + * implement this differently. So its mostly a cleaned-up version of + * the original code, with only support for the MT7628 / MT7688 SoC. + */ + +#include <common.h> +#include <linux/io.h> +#include <asm/cacheops.h> +#include <asm/io.h> +#include "mt76xx.h" + +#define NUM_OF_CACHELINE 128 +#define MIN_START 6 +#define MIN_FINE_START 0xf +#define MAX_START 7 +#define MAX_FINE_START 0x0 + +#define CPU_FRAC_DIV 1 + +#if defined(CONFIG_ONBOARD_DDR2_SIZE_256MBIT) +#define DRAM_BUTTOM 0x02000000 +#endif +#if defined(CONFIG_ONBOARD_DDR2_SIZE_512MBIT) +#define DRAM_BUTTOM 0x04000000 +#endif +#if defined(CONFIG_ONBOARD_DDR2_SIZE_1024MBIT) +#define DRAM_BUTTOM 0x08000000 +#endif +#if defined(CONFIG_ONBOARD_DDR2_SIZE_2048MBIT) +#define DRAM_BUTTOM 0x10000000 +#endif + +static inline void cal_memcpy(void *src, void *dst, u32 size) +{ + u8 *psrc = (u8 *)src; + u8 *pdst = (u8 *)dst; + int i; + + for (i = 0; i < size; i++, psrc++, pdst++) + *pdst = *psrc; +} + +static inline void cal_memset(void *src, u8 pat, u32 size) +{ + u8 *psrc = (u8 *)src; + int i; + + for (i = 0; i < size; i++, psrc++) + *psrc = pat; +} + +#define pref_op(hint, addr) \ + __asm__ __volatile__( \ + ".set push\n" \ + ".set noreorder\n" \ + "pref %0, %1\n" \ + ".set pop\n" \ + : \ + : "i" (hint), "R" (*(u8 *)(addr))) + +static inline void cal_patgen(u32 start_addr, u32 size, u32 bias) +{ + u32 *addr = (u32 *)start_addr; + int i; + + for (i = 0; i < size; i++) + addr[i] = start_addr + i + bias; +} + +static inline int test_loop(int k, int dqs, u32 test_dqs, u32 *coarse_dqs, + u32 offs, u32 pat, u32 val) +{ + u32 nc_addr; + u32 *c_addr; + int i; + + for (nc_addr = 0xa0000000; + nc_addr < (0xa0000000 + DRAM_BUTTOM - NUM_OF_CACHELINE * 32); + nc_addr += (DRAM_BUTTOM >> 6) + offs) { + writel(0x00007474, (void *)MT76XX_MEMCTRL_BASE + 0x64); + wmb(); /* Make sure store if finished */ + + c_addr = (u32 *)(nc_addr & 0xdfffffff); + cal_memset(((u8 *)c_addr), 0x1F, NUM_OF_CACHELINE * 32); + cal_patgen(nc_addr, NUM_OF_CACHELINE * 8, pat); + + if (dqs > 0) + writel(0x00000074 | + (((k == 1) ? coarse_dqs[dqs] : test_dqs) << 12) | + (((k == 0) ? val : test_dqs) << 8), + (void *)MT76XX_MEMCTRL_BASE + 0x64); + else + writel(0x00007400 | + (((k == 1) ? coarse_dqs[dqs] : test_dqs) << 4) | + (((k == 0) ? val : test_dqs) << 0), + (void *)MT76XX_MEMCTRL_BASE + 0x64); + wmb(); /* Make sure store if finished */ + + invalidate_dcache_range((u32)c_addr, + (u32)c_addr + + NUM_OF_CACHELINE * 32); + wmb(); /* Make sure store if finished */ + + for (i = 0; i < NUM_OF_CACHELINE * 8; i++) { + if (i % 8 == 0) + pref_op(0, &c_addr[i]); + } + + for (i = 0; i < NUM_OF_CACHELINE * 8; i++) { + if (c_addr[i] != nc_addr + i + pat) + return -1; + } + } + + return 0; +} + +void ddr_calibrate(void) +{ + u32 min_coarse_dqs[2]; + u32 max_coarse_dqs[2]; + u32 min_fine_dqs[2]; + u32 max_fine_dqs[2]; + u32 coarse_dqs[2]; + u32 fine_dqs[2]; + int reg = 0, ddr_cfg2_reg; + int flag; + int i, k; + int dqs = 0; + u32 min_coarse_dqs_bnd, min_fine_dqs_bnd, coarse_dqs_dll, fine_dqs_dll; + u32 val; + u32 fdiv = 0, frac = 0; + + /* Setup clock to run at full speed */ + val = readl((void *)MT76XX_DYN_CFG0_REG); + fdiv = (u32)((val >> 8) & 0x0F); + if (CPU_FRAC_DIV < 1 || CPU_FRAC_DIV > 10) + frac = val & 0x0f; + else + frac = CPU_FRAC_DIV; + + while (frac < fdiv) { + val = readl((void *)MT76XX_DYN_CFG0_REG); + fdiv = (val >> 8) & 0x0f; + fdiv--; + val &= ~(0x0f << 8); + val |= (fdiv << 8); + writel(val, (void *)MT76XX_DYN_CFG0_REG); + udelay(500); + val = readl((void *)MT76XX_DYN_CFG0_REG); + fdiv = (val >> 8) & 0x0f; + } + + clrbits_le32((void *)MT76XX_MEMCTRL_BASE + 0x10, BIT(4)); + ddr_cfg2_reg = readl((void *)MT76XX_MEMCTRL_BASE + 0x48); + clrbits_le32((void *)MT76XX_MEMCTRL_BASE + 0x48, + (0x3 << 28) | (0x3 << 26)); + + min_coarse_dqs[0] = MIN_START; + min_coarse_dqs[1] = MIN_START; + min_fine_dqs[0] = MIN_FINE_START; + min_fine_dqs[1] = MIN_FINE_START; + max_coarse_dqs[0] = MAX_START; + max_coarse_dqs[1] = MAX_START; + max_fine_dqs[0] = MAX_FINE_START; + max_fine_dqs[1] = MAX_FINE_START; + dqs = 0; + + /* Add by KP, DQS MIN boundary */ + reg = readl((void *)MT76XX_MEMCTRL_BASE + 0x20); + coarse_dqs_dll = (reg & 0xf00) >> 8; + fine_dqs_dll = (reg & 0xf0) >> 4; + if (coarse_dqs_dll <= 8) + min_coarse_dqs_bnd = 8 - coarse_dqs_dll; + else + min_coarse_dqs_bnd = 0; + + if (fine_dqs_dll <= 8) + min_fine_dqs_bnd = 8 - fine_dqs_dll; + else + min_fine_dqs_bnd = 0; + /* DQS MIN boundary */ + +DQS_CAL: + + for (k = 0; k < 2; k++) { + u32 test_dqs; + + if (k == 0) + test_dqs = MAX_START; + else + test_dqs = MAX_FINE_START; + + do { + flag = test_loop(k, dqs, test_dqs, max_coarse_dqs, + 0x400, 0x3, 0xf); + if (flag == -1) + break; + + test_dqs++; + } while (test_dqs <= 0xf); + + if (k == 0) { + max_coarse_dqs[dqs] = test_dqs; + } else { + test_dqs--; + + if (test_dqs == MAX_FINE_START - 1) { + max_coarse_dqs[dqs]--; + max_fine_dqs[dqs] = 0xf; + } else { + max_fine_dqs[dqs] = test_dqs; + } + } + } + + for (k = 0; k < 2; k++) { + u32 test_dqs; + + if (k == 0) + test_dqs = MIN_START; + else + test_dqs = MIN_FINE_START; + + do { + flag = test_loop(k, dqs, test_dqs, min_coarse_dqs, + 0x480, 0x1, 0x0); + if (k == 0) { + if (flag == -1 || + test_dqs == min_coarse_dqs_bnd) + break; + + test_dqs--; + + if (test_dqs < min_coarse_dqs_bnd) + break; + } else { + if (flag == -1) { + test_dqs++; + break; + } else if (test_dqs == min_fine_dqs_bnd) { + break; + } + + test_dqs--; + + if (test_dqs < min_fine_dqs_bnd) + break; + } + } while (test_dqs >= 0); + + if (k == 0) { + min_coarse_dqs[dqs] = test_dqs; + } else { + if (test_dqs == MIN_FINE_START + 1) { + min_coarse_dqs[dqs]++; + min_fine_dqs[dqs] = 0x0; + } else { + min_fine_dqs[dqs] = test_dqs; + } + } + } + + if (dqs == 0) { + dqs = 1; + goto DQS_CAL; + } + + for (i = 0; i < 2; i++) { + u32 temp; + + coarse_dqs[i] = (max_coarse_dqs[i] + min_coarse_dqs[i]) >> 1; + temp = + (((max_coarse_dqs[i] + min_coarse_dqs[i]) % 2) * 4) + + ((max_fine_dqs[i] + min_fine_dqs[i]) >> 1); + if (temp >= 0x10) { + coarse_dqs[i]++; + fine_dqs[i] = (temp - 0x10) + 0x8; + } else { + fine_dqs[i] = temp; + } + } + reg = (coarse_dqs[1] << 12) | (fine_dqs[1] << 8) | + (coarse_dqs[0] << 4) | fine_dqs[0]; + + clrbits_le32((void *)MT76XX_MEMCTRL_BASE + 0x10, BIT(4)); + writel(reg, (void *)MT76XX_MEMCTRL_BASE + 0x64); + writel(ddr_cfg2_reg, (void *)MT76XX_MEMCTRL_BASE + 0x48); + setbits_le32((void *)MT76XX_MEMCTRL_BASE + 0x10, BIT(4)); + + for (i = 0; i < 2; i++) + debug("[%02X%02X%02X%02X]", min_coarse_dqs[i], + min_fine_dqs[i], max_coarse_dqs[i], max_fine_dqs[i]); + debug("\nDDR Calibration DQS reg = %08X\n", reg); +} diff --git a/arch/mips/mach-mt7620/lowlevel_init.S b/arch/mips/mach-mt7620/lowlevel_init.S new file mode 100644 index 0000000000..1a50f160fe --- /dev/null +++ b/arch/mips/mach-mt7620/lowlevel_init.S @@ -0,0 +1,322 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (c) 2018 Stefan Roese <sr@denx.de> + * + * This code is mostly based on the code extracted from this MediaTek + * github repository: + * + * https://github.com/MediaTek-Labs/linkit-smart-uboot.git + * + * I was not able to find a specific license or other developers + * copyrights here, so I can't add them here. + */ + +#include <config.h> +#include <asm/regdef.h> +#include <asm/mipsregs.h> +#include <asm/addrspace.h> +#include <asm/asm.h> +#include "mt76xx.h" + +#ifndef BIT +#define BIT(nr) (1 << (nr)) +#endif + +#define DELAY_USEC(us) ((us) / 100) + +#define DDR_CFG1_CHIP_WIDTH_MASK (0x3 << 16) +#define DDR_CFG1_BUS_WIDTH_MASK (0x3 << 12) + +#if defined(CONFIG_ONBOARD_DDR2_SIZE_256MBIT) +#define DDR_CFG1_SIZE_VAL 0x222e2323 +#define DDR_CFG4_SIZE_VAL 7 +#endif +#if defined(CONFIG_ONBOARD_DDR2_SIZE_512MBIT) +#define DDR_CFG1_SIZE_VAL 0x22322323 +#define DDR_CFG4_SIZE_VAL 9 +#endif +#if defined(CONFIG_ONBOARD_DDR2_SIZE_1024MBIT) +#define DDR_CFG1_SIZE_VAL 0x22362323 +#define DDR_CFG4_SIZE_VAL 9 +#endif +#if defined(CONFIG_ONBOARD_DDR2_SIZE_2048MBIT) +#define DDR_CFG1_SIZE_VAL 0x223a2323 +#define DDR_CFG4_SIZE_VAL 9 +#endif + +#if defined(CONFIG_ONBOARD_DDR2_CHIP_WIDTH_8BIT) +#define DDR_CFG1_CHIP_WIDTH_VAL (0x1 << 16) +#endif +#if defined(CONFIG_ONBOARD_DDR2_CHIP_WIDTH_16BIT) +#define DDR_CFG1_CHIP_WIDTH_VAL (0x2 << 16) +#endif + +#if defined(CONFIG_ONBOARD_DDR2_BUS_WIDTH_16BIT) +#define DDR_CFG1_BUS_WIDTH_VAL (0x2 << 12) +#endif +#if defined(CONFIG_ONBOARD_DDR2_BUS_WIDTH_32BIT) +#define DDR_CFG1_BUS_WIDTH_VAL (0x3 << 12) +#endif + + .set noreorder + +LEAF(lowlevel_init) + + /* Load base addresses as physical addresses for later usage */ + li s0, CKSEG1ADDR(MT76XX_SYSCTL_BASE) + li s1, CKSEG1ADDR(MT76XX_MEMCTRL_BASE) + li s2, CKSEG1ADDR(MT76XX_RGCTRL_BASE) + + /* polling CPLL is ready */ + li t1, DELAY_USEC(1000000) + la t5, MT76XX_ROM_STATUS_REG +1: + lw t2, 0(t5) + andi t2, t2, 0x1 + bnez t2, CPLL_READY + subu t1, t1, 1 + bgtz t1, 1b + nop + la t0, MT76XX_CLKCFG0_REG + lw t3, 0(t0) + ori t3, t3, 0x1 + sw t3, 0(t0) + b CPLL_DONE + nop +CPLL_READY: + la t0, MT76XX_CLKCFG0_REG + lw t1, 0(t0) + li t2, ~0x0c + and t1, t1, t2 + ori t1, t1, 0xc + sw t1, 0(t0) + la t0, MT76XX_DYN_CFG0_REG + lw t3, 0(t0) + li t5, ~((0x0f << 8) | (0x0f << 0)) + and t3, t3, t5 + li t5, (10 << 8) | (1 << 0) + or t3, t3, t5 + sw t3, 0(t0) + la t0, MT76XX_CLKCFG0_REG + lw t3, 0(t0) + li t4, ~0x0F + and t3, t3, t4 + ori t3, t3, 0xc + sw t3, 0(t0) + lw t3, 0(t0) + ori t3, t3, 0x08 + sw t3, 0(t0) + +CPLL_DONE: + /* + * SDR and DDR initialization: delay 200us + */ + li t0, DELAY_USEC(200 + 40) + li t1, 0x1 +1: + sub t0, t0, t1 + bnez t0, 1b + nop + + /* set DRAM IO PAD for MT7628IC */ + /* DDR LDO Enable */ + lw t4, 0x100(s2) + li t2, BIT(31) + or t4, t4, t2 + sw t4, 0x100(s2) + lw t4, 0x10c(s2) + j LDO_1P8V + nop +LDO_1P8V: + li t2, ~BIT(6) + and t4, t4, t2 + sw t4, 0x10c(s2) + j DDRLDO_SOFT_START +LDO_2P5V: + /* suppose external DDR1 LDO 2.5V */ + li t2, BIT(6) + or t4, t4, t2 + sw t4, 0x10c(s2) + +DDRLDO_SOFT_START: + lw t2, 0x10c(s2) + li t3, BIT(16) + or t2, t2, t3 + sw t2, 0x10c(s2) + li t3, DELAY_USEC(250*50) +LDO_DELAY: + subu t3, t3, 1 + bnez t3, LDO_DELAY + nop + + lw t2, 0x10c(s2) + li t3, BIT(18) + or t2, t2, t3 + sw t2, 0x10c(s2) + +SET_RG_BUCK_FPWM: + lw t2, 0x104(s2) + ori t2, t2, BIT(10) + sw t2, 0x104(s2) + +DDR_PAD_CFG: + /* clean CLK PAD */ + lw t2, 0x704(s2) + li t8, 0xfffff0f0 + and t2, t2, t8 + /* clean CMD PAD */ + lw t3, 0x70c(s2) + li t8, 0xfffff0f0 + and t3, t3, t8 + /* clean DQ IPAD */ + lw t4, 0x710(s2) + li t8, 0xfffff8ff + and t4, t4, t8 + /* clean DQ OPAD */ + lw t5, 0x714(s2) + li t8, 0xfffff0f0 + and t5, t5, t8 + /* clean DQS IPAD */ + lw t6, 0x718(s2) + li t8, 0xfffff8ff + and t6, t6, t8 + /* clean DQS OPAD */ + lw t7, 0x71c(s2) + li t8, 0xfffff0f0 + and t7, t7, t8 + + lw t9, 0xc(s0) + srl t9, t9, 16 + andi t9, t9, 0x1 + bnez t9, MT7628_AN_DDR1_PAD +MT7628_KN_PAD: + li t8, 0x00000303 + or t2, t2, t8 + or t3, t3, t8 + or t5, t5, t8 + or t7, t7, t8 + li t8, 0x00000000 + or t4, t4, t8 + or t6, t6, t8 + j SET_PAD_CFG +MT7628_AN_DDR1_PAD: + lw t1, 0x10(s0) + andi t1, t1, 0x1 + beqz t1, MT7628_AN_DDR2_PAD + li t8, 0x00000c0c + or t2, t2, t8 + li t8, 0x00000202 + or t3, t3, t8 + li t8, 0x00000707 + or t5, t5, t8 + li t8, 0x00000c0c + or t7, t7, t8 + li t8, 0x00000000 + or t4, t4, t8 + or t6, t6, t8 + j SET_PAD_CFG +MT7628_AN_DDR2_PAD: + li t8, 0x00000c0c + or t2, t2, t8 + li t8, 0x00000202 + or t3, t3, t8 + li t8, 0x00000404 + or t5, t5, t8 + li t8, 0x00000c0c + or t7, t7, t8 + li t8, 0x00000000 /* ODT off */ + or t4, t4, t8 + or t6, t6, t8 + +SET_PAD_CFG: + sw t2, 0x704(s2) + sw t3, 0x70c(s2) + sw t4, 0x710(s2) + sw t5, 0x714(s2) + sw t6, 0x718(s2) + sw t7, 0x71c(s2) + + /* + * DDR initialization: reset pin to 0 + */ + lw t2, 0x34(s0) + and t2, ~BIT(10) + sw t2, 0x34(s0) + nop + + /* + * DDR initialization: wait til reg DDR_CFG1 bit 21 equal to 1 (ready) + */ +DDR_READY: + li t1, DDR_CFG1_REG + lw t0, 0(t1) + nop + and t2, t0, BIT(21) + beqz t2, DDR_READY + nop + + /* + * DDR initialization + * + * Only DDR2 supported right now. DDR2 support can be added, once + * boards using it will get added to mainline U-Boot. + */ + li t1, DDR_CFG2_REG + lw t0, 0(t1) + nop + and t0, ~BIT(30) + and t0, ~(7 << 4) + or t0, (4 << 4) + or t0, BIT(30) + or t0, BIT(11) + sw t0, 0(t1) + nop + + li t1, DDR_CFG3_REG + lw t2, 0(t1) + /* Disable ODT; reference board ok, ev board fail */ + and t2, ~BIT(6) + or t2, BIT(2) + li t0, DDR_CFG4_REG + lw t1, 0(t0) + li t2, ~(0x01f | 0x0f0) + and t1, t1, t2 + ori t1, t1, DDR_CFG4_SIZE_VAL + sw t1, 0(t0) + nop + + /* + * DDR initialization: config size and width on reg DDR_CFG1 + */ + li t6, DDR_CFG1_SIZE_VAL + + and t6, ~DDR_CFG1_CHIP_WIDTH_MASK + or t6, DDR_CFG1_CHIP_WIDTH_VAL + + /* CONFIG DDR_CFG1[13:12] about TOTAL WIDTH */ + and t6, ~DDR_CFG1_BUS_WIDTH_MASK + or t6, DDR_CFG1_BUS_WIDTH_VAL + + li t5, DDR_CFG1_REG + sw t6, 0(t5) + nop + + /* + * DDR: enable self auto refresh for power saving + * enable it by default for both RAM and ROM version (for CoC) + */ + lw t1, 0x14(s1) + nop + and t1, 0xff000000 + or t1, 0x01 + sw t1, 0x14(s1) + nop + lw t1, 0x10(s1) + nop + or t1, 0x10 + sw t1, 0x10(s1) + nop + + jr ra + nop + END(lowlevel_init) diff --git a/arch/mips/mach-mt7620/mt76xx.h b/arch/mips/mach-mt7620/mt76xx.h new file mode 100644 index 0000000000..17473ea8f1 --- /dev/null +++ b/arch/mips/mach-mt7620/mt76xx.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2018 Stefan Roese <sr@denx.de> + */ + +#ifndef __MT76XX_H +#define __MT76XX_H + +#define MT76XX_SYSCTL_BASE 0x10000000 + +#define MT76XX_CHIPID_OFFS 0x00 +#define MT76XX_CHIP_REV_ID_OFFS 0x0c +#define MT76XX_SYSCFG0_OFFS 0x10 + +#define MT76XX_MEMCTRL_BASE (MT76XX_SYSCTL_BASE + 0x0300) +#define MT76XX_RGCTRL_BASE (MT76XX_SYSCTL_BASE + 0x1000) + +#define MT76XX_ROM_STATUS_REG (MT76XX_SYSCTL_BASE + 0x0028) +#define MT76XX_CLKCFG0_REG (MT76XX_SYSCTL_BASE + 0x002c) +#define MT76XX_DYN_CFG0_REG (MT76XX_SYSCTL_BASE + 0x0440) + +#define DDR_CFG1_REG (MT76XX_MEMCTRL_BASE + 0x44) +#define DDR_CFG2_REG (MT76XX_MEMCTRL_BASE + 0x48) +#define DDR_CFG3_REG (MT76XX_MEMCTRL_BASE + 0x4c) +#define DDR_CFG4_REG (MT76XX_MEMCTRL_BASE + 0x50) + +#ifndef __ASSEMBLY__ +/* Prototypes */ +void ddr_calibrate(void); +#endif + +#endif diff --git a/arch/nds32/config.mk b/arch/nds32/config.mk index cb3d8b35b5..c5520fd8d8 100644 --- a/arch/nds32/config.mk +++ b/arch/nds32/config.mk @@ -15,7 +15,7 @@ endif CONFIG_STANDALONE_LOAD_ADDR = 0x300000 \ -T $(srctree)/examples/standalone/nds32.lds -PLATFORM_RELFLAGS += -fno-strict-aliasing -fno-common -mrelax +PLATFORM_RELFLAGS += -fno-common -mrelax PLATFORM_RELFLAGS += -gdwarf-2 PLATFORM_CPPFLAGS += -D__nds32__ -G0 -ffixed-10 -fpie diff --git a/arch/riscv/config.mk b/arch/riscv/config.mk index 219e66683d..c0b3858edd 100644 --- a/arch/riscv/config.mk +++ b/arch/riscv/config.mk @@ -31,7 +31,7 @@ CONFIG_STANDALONE_LOAD_ADDR = 0x00000000 \ -T $(srctree)/examples/standalone/riscv.lds PLATFORM_CPPFLAGS += -ffixed-gp -fpic -PLATFORM_RELFLAGS += -fno-strict-aliasing -fno-common -gdwarf-2 -ffunction-sections +PLATFORM_RELFLAGS += -fno-common -gdwarf-2 -ffunction-sections LDFLAGS_u-boot += --gc-sections -static -pie EFI_CRT0 := crt0_riscv_efi.o diff --git a/arch/sandbox/cpu/cpu.c b/arch/sandbox/cpu/cpu.c index cde0b055a6..6098945049 100644 --- a/arch/sandbox/cpu/cpu.c +++ b/arch/sandbox/cpu/cpu.c @@ -57,14 +57,104 @@ int cleanup_before_linux_select(int flags) return 0; } +/** + * is_in_sandbox_mem() - Checks if a pointer is within sandbox's emulated DRAM + * + * This provides a way to check if a pointer is owned by sandbox (and is within + * its RAM) or not. Sometimes pointers come from a test which conceptually runs + * output sandbox, potentially with direct access to the C-library malloc() + * function, or the sandbox stack (which is not actually within the emulated + * DRAM. + * + * Such pointers obviously cannot be mapped into sandbox's DRAM, so we must + * detect them an process them separately, by recording a mapping to a tag, + * which we can use to map back to the pointer later. + * + * @ptr: Pointer to check + * @return true if this is within sandbox emulated DRAM, false if not + */ +static bool is_in_sandbox_mem(const void *ptr) +{ + return (const uint8_t *)ptr >= gd->arch.ram_buf && + (const uint8_t *)ptr < gd->arch.ram_buf + gd->ram_size; +} + +/** + * phys_to_virt() - Converts a sandbox RAM address to a pointer + * + * Sandbox uses U-Boot addresses from 0 to the size of DRAM. These index into + * the emulated DRAM buffer used by sandbox. This function converts such an + * address to a pointer into this buffer, which can be used to access the + * memory. + * + * If the address is outside this range, it is assumed to be a tag + */ void *phys_to_virt(phys_addr_t paddr) { - return (void *)(gd->arch.ram_buf + paddr); + struct sandbox_mapmem_entry *mentry; + struct sandbox_state *state; + + /* If the address is within emulated DRAM, calculate the value */ + if (paddr < gd->ram_size) + return (void *)(gd->arch.ram_buf + paddr); + + /* + * Otherwise search out list of tags for the correct pointer previously + * created by map_to_sysmem() + */ + state = state_get_current(); + list_for_each_entry(mentry, &state->mapmem_head, sibling_node) { + if (mentry->tag == paddr) { + printf("%s: Used map from %lx to %p\n", __func__, + (ulong)paddr, mentry->ptr); + return mentry->ptr; + } + } + + printf("%s: Cannot map sandbox address %lx (SDRAM from 0 to %lx)\n", + __func__, (ulong)paddr, (ulong)gd->ram_size); + os_abort(); + + /* Not reached */ + return NULL; +} + +struct sandbox_mapmem_entry *find_tag(const void *ptr) +{ + struct sandbox_mapmem_entry *mentry; + struct sandbox_state *state = state_get_current(); + + list_for_each_entry(mentry, &state->mapmem_head, sibling_node) { + if (mentry->ptr == ptr) { + debug("%s: Used map from %p to %lx\n", __func__, ptr, + mentry->tag); + return mentry; + } + } + return NULL; } -phys_addr_t virt_to_phys(void *vaddr) +phys_addr_t virt_to_phys(void *ptr) { - return (phys_addr_t)((uint8_t *)vaddr - gd->arch.ram_buf); + struct sandbox_mapmem_entry *mentry; + + /* + * If it is in emulated RAM, don't bother looking for a tag. Just + * calculate the pointer using the provides offset into the RAM buffer. + */ + if (is_in_sandbox_mem(ptr)) + return (phys_addr_t)((uint8_t *)ptr - gd->arch.ram_buf); + + mentry = find_tag(ptr); + if (!mentry) { + /* Abort so that gdb can be used here */ + printf("%s: Cannot map sandbox address %p (SDRAM from 0 to %lx)\n", + __func__, ptr, (ulong)gd->ram_size); + os_abort(); + } + printf("%s: Used map from %p to %lx\n", __func__, ptr, mentry->tag); + + return mentry->tag; } void *map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags) @@ -87,24 +177,57 @@ void *map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags) return phys_to_virt(paddr); } -void unmap_physmem(const void *vaddr, unsigned long flags) +void unmap_physmem(const void *ptr, unsigned long flags) { #ifdef CONFIG_PCI if (map_dev) { - pci_unmap_physmem(vaddr, map_len, map_dev); + pci_unmap_physmem(ptr, map_len, map_dev); map_dev = NULL; } #endif } -void sandbox_set_enable_pci_map(int enable) +phys_addr_t map_to_sysmem(const void *ptr) { - enable_pci_map = enable; + struct sandbox_mapmem_entry *mentry; + + /* + * If it is in emulated RAM, don't bother creating a tag. Just return + * the offset into the RAM buffer. + */ + if (is_in_sandbox_mem(ptr)) + return (u8 *)ptr - gd->arch.ram_buf; + + /* + * See if there is an existing tag with this pointer. If not, set up a + * new one. + */ + mentry = find_tag(ptr); + if (!mentry) { + struct sandbox_state *state = state_get_current(); + + mentry = malloc(sizeof(*mentry)); + if (!mentry) { + printf("%s: Error: Out of memory\n", __func__); + os_exit(ENOMEM); + } + mentry->tag = state->next_tag++; + mentry->ptr = (void *)ptr; + list_add_tail(&mentry->sibling_node, &state->mapmem_head); + debug("%s: Added map from %p to %lx\n", __func__, ptr, + (ulong)mentry->tag); + } + + /* + * Return the tag as the address to use. A later call to map_sysmem() + * will return ptr + */ + return mentry->tag; } -phys_addr_t map_to_sysmem(const void *ptr) +void sandbox_set_enable_pci_map(int enable) { - return (u8 *)ptr - gd->arch.ram_buf; + enable_pci_map = enable; } void flush_dcache_range(unsigned long start, unsigned long stop) @@ -165,15 +288,3 @@ ulong timer_get_boot_us(void) return (count - base_count) / 1000; } - -int setjmp(jmp_buf jmp) -{ - return os_setjmp((ulong *)jmp, sizeof(*jmp)); -} - -void longjmp(jmp_buf jmp, int ret) -{ - os_longjmp((ulong *)jmp, ret); - while (1) - ; -} diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c index 5839932b00..9fbcb9ef92 100644 --- a/arch/sandbox/cpu/os.c +++ b/arch/sandbox/cpu/os.c @@ -143,14 +143,16 @@ void os_tty_raw(int fd, bool allow_sigs) void *os_malloc(size_t length) { struct os_mem_hdr *hdr; + int page_size = getpagesize(); - hdr = mmap(NULL, length + sizeof(*hdr), PROT_READ | PROT_WRITE, + hdr = mmap(NULL, length + page_size, + PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (hdr == MAP_FAILED) return NULL; hdr->length = length; - return hdr + 1; + return (void *)hdr + page_size; } void os_free(void *ptr) @@ -630,24 +632,7 @@ void os_localtime(struct rtc_time *rt) rt->tm_isdst = tm->tm_isdst; } -int os_setjmp(ulong *jmp, int size) +void os_abort(void) { - jmp_buf dummy; - - /* - * We cannot rely on the struct name that jmp_buf uses, so use a - * local variable here - */ - if (size < sizeof(dummy)) { - printf("setjmp: jmpbuf is too small (%d bytes, need %d)\n", - size, sizeof(jmp_buf)); - return -ENOSPC; - } - - return setjmp((struct __jmp_buf_tag *)jmp); -} - -void os_longjmp(ulong *jmp, int ret) -{ - longjmp((struct __jmp_buf_tag *)jmp, ret); + abort(); } diff --git a/arch/sandbox/cpu/state.c b/arch/sandbox/cpu/state.c index cc50819ab9..04a11fed55 100644 --- a/arch/sandbox/cpu/state.c +++ b/arch/sandbox/cpu/state.c @@ -359,6 +359,14 @@ void state_reset_for_test(struct sandbox_state *state) memset(&state->wdt, '\0', sizeof(state->wdt)); memset(state->spi, '\0', sizeof(state->spi)); + + /* + * Set up the memory tag list. Use the top of emulated SDRAM for the + * first tag number, since that address offset is outside the legal + * range, and can be assumed to be a tag. + */ + INIT_LIST_HEAD(&state->mapmem_head); + state->next_tag = state->ram_size; } int state_init(void) diff --git a/arch/sandbox/dts/sandbox.dts b/arch/sandbox/dts/sandbox.dts index 6ac37f1ed7..1aa0f8eef5 100644 --- a/arch/sandbox/dts/sandbox.dts +++ b/arch/sandbox/dts/sandbox.dts @@ -153,6 +153,7 @@ pinctrl { compatible = "sandbox,pinctrl"; + status = "okay"; pinctrl_i2c0: i2c0 { groups = "i2c"; @@ -164,6 +165,12 @@ groups = "serial_a"; function = "serial"; }; + + pinctrl_onewire0: onewire0 { + groups = "w1"; + function = "w1"; + bias-pull-up; + }; }; reset@1 { @@ -322,6 +329,19 @@ reg = <0x0 0x400>; }; }; + + onewire0: onewire { + compatible = "w1-gpio"; + gpios = <&gpio_a 8>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_onewire0>; + status = "okay"; + + sandbox_eeprom0: sandbox_eeprom@0 { + compatible = "sandbox,w1-eeprom"; + status = "okay"; + }; + }; }; #include "cros-ec-keyboard.dtsi" diff --git a/arch/sandbox/include/asm/setjmp.h b/arch/sandbox/include/asm/setjmp.h index 1fe37c91cc..001c7ea322 100644 --- a/arch/sandbox/include/asm/setjmp.h +++ b/arch/sandbox/include/asm/setjmp.h @@ -24,6 +24,11 @@ struct jmp_buf_data { typedef struct jmp_buf_data jmp_buf[1]; +/* + * We have to directly link with the system versions of + * setjmp/longjmp, because setjmp must not return as otherwise + * the stack may become invalid. + */ int setjmp(jmp_buf jmp); __noreturn void longjmp(jmp_buf jmp, int ret); diff --git a/arch/sandbox/include/asm/state.h b/arch/sandbox/include/asm/state.h index 7ed4b512d2..a612ce8944 100644 --- a/arch/sandbox/include/asm/state.h +++ b/arch/sandbox/include/asm/state.h @@ -9,6 +9,7 @@ #include <config.h> #include <sysreset.h> #include <stdbool.h> +#include <linux/list.h> #include <linux/stringify.h> /** @@ -45,6 +46,23 @@ struct sandbox_wdt_info { bool running; }; +/** + * struct sandbox_mapmem_entry - maps pointers to/from U-Boot addresses + * + * When map_to_sysmem() is called with an address outside sandbox's emulated + * RAM, a record is created with a tag that can be used to reference that + * pointer. When map_sysmem() is called later with that tag, the pointer will + * be returned, just as it would for a normal sandbox address. + * + * @tag: Address tag (a value which U-Boot uses to refer to the address) + * @ptr: Associated pointer for that tag + */ +struct sandbox_mapmem_entry { + ulong tag; + void *ptr; + struct list_head sibling_node; +}; + /* The complete state of the test system */ struct sandbox_state { const char *cmd; /* Command to execute */ @@ -78,6 +96,9 @@ struct sandbox_state { /* Information about Watchdog */ struct sandbox_wdt_info wdt; + + ulong next_tag; /* Next address tag to allocate */ + struct list_head mapmem_head; /* struct sandbox_mapmem_entry */ }; /* Minimum space we guarantee in the state FDT when calling read/write*/ diff --git a/arch/x86/config.mk b/arch/x86/config.mk index 5b04febd68..cc940712a8 100644 --- a/arch/x86/config.mk +++ b/arch/x86/config.mk @@ -5,7 +5,6 @@ CONFIG_STANDALONE_LOAD_ADDR ?= 0x40000 -PLATFORM_CPPFLAGS += -fno-strict-aliasing PLATFORM_CPPFLAGS += -fomit-frame-pointer PF_CPPFLAGS_X86 := $(call cc-option, -fno-toplevel-reorder, \ $(call cc-option, -fno-unit-at-a-time)) diff --git a/arch/x86/lib/e820.c b/arch/x86/lib/e820.c index 8b34f677d9..d6ae2c4e9d 100644 --- a/arch/x86/lib/e820.c +++ b/arch/x86/lib/e820.c @@ -36,7 +36,7 @@ __weak unsigned int install_e820_map(unsigned int max_entries, return 4; } -#if defined(CONFIG_EFI_LOADER) && !defined(CONFIG_SPL_BUILD) +#if CONFIG_IS_ENABLED(EFI_LOADER) void efi_add_known_memory(void) { struct e820_entry e820[E820MAX]; @@ -72,4 +72,4 @@ void efi_add_known_memory(void) efi_add_memory_map(start, pages, type, false); } } -#endif /* defined(EFI_LOADER) && !defined(CONFIG_SPL_BUILD) */ +#endif /* CONFIG_IS_ENABLED(EFI_LOADER) */ diff --git a/arch/xtensa/include/asm/atomic.h b/arch/xtensa/include/asm/atomic.h index 42b32f5d3d..4e3ad56472 100644 --- a/arch/xtensa/include/asm/atomic.h +++ b/arch/xtensa/include/asm/atomic.h @@ -7,48 +7,6 @@ #define _XTENSA_ATOMIC_H #include <asm/system.h> - -typedef struct { volatile int counter; } atomic_t; - -#define ATOMIC_INIT(i) { (i) } - -#define atomic_read(v) ((v)->counter) -#define atomic_set(v, i) ((v)->counter = (i)) - -static inline void atomic_add(int i, atomic_t *v) -{ - unsigned long flags; - - local_irq_save(flags); - v->counter += i; - local_irq_restore(flags); -} - -static inline void atomic_sub(int i, atomic_t *v) -{ - unsigned long flags; - - local_irq_save(flags); - v->counter -= i; - local_irq_restore(flags); -} - -static inline void atomic_inc(atomic_t *v) -{ - unsigned long flags; - - local_irq_save(flags); - ++v->counter; - local_irq_restore(flags); -} - -static inline void atomic_dec(atomic_t *v) -{ - unsigned long flags; - - local_irq_save(flags); - --v->counter; - local_irq_restore(flags); -} +#include <asm-generic/atomic.h> #endif |