diff options
Diffstat (limited to 'arch')
84 files changed, 3098 insertions, 250 deletions
diff --git a/arch/Kconfig b/arch/Kconfig index ea33d07c086..7e05e0c2263 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -63,6 +63,13 @@ config SYS_CACHELINE_SIZE default 64 if RISCV default 32 if MIPS +config SYS_DTC_PAD_BYTES + int "Size in bytes to pad device tree blob" + default 32768 if X86 && EFI_APP + default 4096 if ARC || ARM64 || M68K || MICROBLAZE || NIOS2 \ + || RISCV || SANDBOX || X86 + default 0 + config LINKER_LIST_ALIGN int default 32 if SANDBOX @@ -213,6 +220,7 @@ config SANDBOX imply BITREVERSE select BLOBLIST imply LTO + imply CMD_BOOTEFI_SELFTEST imply CMD_DM imply CMD_EXCEPTION imply CMD_GETTIME diff --git a/arch/arc/dts/Makefile b/arch/arc/dts/Makefile index fe6ad7b849a..87c627c01c8 100644 --- a/arch/arc/dts/Makefile +++ b/arch/arc/dts/Makefile @@ -11,4 +11,4 @@ dtb-$(CONFIG_TARGET_IOT_DEVKIT) += iot_devkit.dtb include $(srctree)/scripts/Makefile.dts # Add any required device tree compiler flags here -DTC_FLAGS += -R 4 -p 0x1000 +DTC_FLAGS += -R 4 diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index f6430a5aaf0..1d096ad6554 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -832,6 +832,7 @@ config ARCH_K3 select FIT select REGEX select FIT_SIGNATURE if ARM64 + select LTO imply TI_SECURE_DEVICE config ARCH_OMAP2PLUS @@ -1079,7 +1080,7 @@ config ARCH_OWL select CLK select CLK_OWL select OF_CONTROL - select SYS_RELOC_GD_ENV_ADDR + select ENV_RELOC_GD_ENV_ADDR imply CMD_DM config ARCH_QEMU @@ -1137,6 +1138,7 @@ config ARCH_SNAPDRAGON select LINUX_KERNEL_IMAGE_HEADER if !ENABLE_ARM_SOC_BOOT0_HOOK select SYSRESET select SYSRESET_PSCI + select ANDROID_BOOT_IMAGE_IGNORE_BLOB_ADDR imply OF_UPSTREAM imply CMD_DM imply DM_USB_GADGET @@ -1219,7 +1221,7 @@ config ARCH_SUNXI select USB_STORAGE if DISTRO_DEFAULTS && USB_HOST select SPL_USE_TINY_PRINTF if SPL select USE_PREBOOT - select SYS_RELOC_GD_ENV_ADDR + select ENV_RELOC_GD_ENV_ADDR imply BOARD_LATE_INIT imply CMD_DM imply CMD_GPT diff --git a/arch/arm/cpu/armv8/fel_utils.S b/arch/arm/cpu/armv8/fel_utils.S index 044a7c16cc5..6a7ec9a7ec1 100644 --- a/arch/arm/cpu/armv8/fel_utils.S +++ b/arch/arm/cpu/armv8/fel_utils.S @@ -41,7 +41,7 @@ ENTRY(return_to_fel) str w2, [x1] ldr w0, =0xfa50392f // CPU hotplug magic -#ifdef CONFIG_MACH_SUN50I_H616 +#if defined(CONFIG_MACH_SUN50I_H616) || defined(CONFIG_MACH_SUN50I_A133) ldr w2, =(SUNXI_R_CPUCFG_BASE + 0x1c0) str w0, [x2], #0x4 #elif CONFIG_MACH_SUN50I_H6 diff --git a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c index d2d3e346a36..cfbaa475701 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c @@ -802,7 +802,7 @@ enum boot_src get_boot_src(void) int mmc_get_env_dev(void) { enum boot_src src = get_boot_src(); - int dev = CONFIG_SYS_MMC_ENV_DEV; + int dev = CONFIG_ENV_MMC_DEVICE_INDEX; switch (src) { case BOOT_SOURCE_SD_MMC: diff --git a/arch/arm/dts/at91-sam9x60_curiosity-u-boot.dtsi b/arch/arm/dts/at91-sam9x60_curiosity-u-boot.dtsi index dd4623311c9..9144387861e 100644 --- a/arch/arm/dts/at91-sam9x60_curiosity-u-boot.dtsi +++ b/arch/arm/dts/at91-sam9x60_curiosity-u-boot.dtsi @@ -95,3 +95,7 @@ &slow_xtal { bootph-all; }; + +&watchdog { + timeout-sec = <16>; +}; diff --git a/arch/arm/dts/at91-sam9x60_curiosity.dts b/arch/arm/dts/at91-sam9x60_curiosity.dts index 1c7f0fa6a49..f165fdadb9e 100644 --- a/arch/arm/dts/at91-sam9x60_curiosity.dts +++ b/arch/arm/dts/at91-sam9x60_curiosity.dts @@ -336,3 +336,7 @@ &usb2 { status = "okay"; }; + +&watchdog { + status = "okay"; +}; diff --git a/arch/arm/dts/at91-sam9x75_curiosity-u-boot.dtsi b/arch/arm/dts/at91-sam9x75_curiosity-u-boot.dtsi new file mode 100644 index 00000000000..94585ee0232 --- /dev/null +++ b/arch/arm/dts/at91-sam9x75_curiosity-u-boot.dtsi @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * at91-sam9x75_curiosity-u-boot.dtsi - Device Tree file for SAM9X75 + * CURIOSITY board. + * + * Copyright (C) 2025 Microchip Technology Inc. and its subsidiaries + * + * Author: Manikandan Muralidharan <manikandan.m@microchip.com> + */ + +/ { + cpus { + cpu@0 { + clocks = <&pmc PMC_TYPE_CORE 25>, <&pmc PMC_TYPE_CORE 17>, <&main_xtal>; + clock-names = "cpu", "master", "xtal"; + }; + }; + + clocks { + slow_rc_osc: slow_rc_osc { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <18500>; + }; + }; + + ahb { + bootph-all; + + apb { + bootph-all; + + pinctrl { + bootph-all; + }; + }; + }; + + chosen { + bootph-all; + }; +}; + +&clk32k { + bootph-all; + clocks = <&slow_rc_osc>, <&slow_xtal>; +}; + +&dbgu { + bootph-all; +}; + +&gmac { + compatible = "microchip,sam9x7-gem", "cdns,sama7g5-gem"; +}; + +&main_xtal { + bootph-all; +}; + +&pinctrl_dbgu_default { + bootph-all; +}; + +&pinctrl_sdmmc0_default { + bootph-all; +}; + +&pioA { + bootph-all; +}; + +&pioB { + bootph-all; +}; + +&pit64b0 { + bootph-all; +}; + +&pmc { + bootph-all; +}; + +&sdmmc0 { + bootph-all; +}; + +&slow_xtal { + bootph-all; +}; + +&slow_rc_osc { + bootph-all; +}; diff --git a/arch/arm/dts/ipq5424-rdp466-u-boot.dtsi b/arch/arm/dts/ipq5424-rdp466-u-boot.dtsi new file mode 100644 index 00000000000..9e4af4d9f72 --- /dev/null +++ b/arch/arm/dts/ipq5424-rdp466-u-boot.dtsi @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * IPQ5424 RDP466 board device tree source + * + * Copyright (c) 2025 The Linux Foundation. All rights reserved. + */ + +/ { + /* Will be removed when SMEM parsing is updated */ + memory@80000000 { + device_type = "memory"; + reg = <0x0 0x80000000 0x0 0x20000000>; + }; + +}; + + &sdhc { + sdhci-caps-mask = <0x0 0x04000000>; + sdhci-caps = <0x0 0x04000000>; /* SDHCI_CAN_VDD_180 */ + mmc-ddr-1_8v; + mmc-hs200-1_8v; + max-frequency = <192000000>; + bus-width = <4>; + pinctrl-0 = <&sdc_default_state>; + pinctrl-names = "default"; + non-removable; + + /* + * This reset is needed to clear out the settings done by + * previous boot loader. Without this the SDHCI_RESET_ALL + * reset done sdhci_init() times out. + */ + resets = <&gcc GCC_SDCC_BCR>; + + status = "okay"; + }; + diff --git a/arch/arm/dts/k3-am625-phycore-som-binman.dtsi b/arch/arm/dts/k3-am625-phycore-som-binman.dtsi index 32d8804a395..6deebdadf09 100644 --- a/arch/arm/dts/k3-am625-phycore-som-binman.dtsi +++ b/arch/arm/dts/k3-am625-phycore-som-binman.dtsi @@ -400,11 +400,105 @@ }; &binman { + tifsstub-hs { + filename = "tifsstub.bin_hs"; + ti-secure-rom { + content = <&tifsstub_hs_cert>; + core = "secure"; + load = <0x40000>; + sw-rev = <CONFIG_K3_X509_SWRV>; + keyfile = "custMpk.pem"; + countersign; + tifsstub; + }; + tifsstub_hs_cert: tifsstub-hs-cert.bin { + filename = "ti-sysfw/ti-fs-stub-firmware-am62x-hs-cert.bin"; + type = "blob-ext"; + optional; + }; + tifsstub_hs_enc: tifsstub-hs-enc.bin { + filename = "ti-sysfw/ti-fs-stub-firmware-am62x-hs-enc.bin"; + type = "blob-ext"; + optional; + }; + }; + + tifsstub-fs { + filename = "tifsstub.bin_fs"; + tifsstub_fs_cert: tifsstub-fs-cert.bin { + filename = "ti-sysfw/ti-fs-stub-firmware-am62x-hs-cert.bin"; + type = "blob-ext"; + optional; + }; + tifsstub_fs_enc: tifsstub-fs-enc.bin { + filename = "ti-sysfw/ti-fs-stub-firmware-am62x-hs-enc.bin"; + type = "blob-ext"; + optional; + }; + + }; + + tifsstub-gp { + filename = "tifsstub.bin_gp"; + ti-secure-rom { + content = <&tifsstub_gp>; + core = "secure"; + load = <0x60000>; + sw-rev = <CONFIG_K3_X509_SWRV>; + keyfile = "ti-degenerate-key.pem"; + tifsstub; + }; + tifsstub_gp: tifsstub-gp.bin { + filename = "ti-sysfw/ti-fs-stub-firmware-am62x-gp.bin"; + type = "blob-ext"; + optional; + }; + }; + ti-spl_unsigned { insert-template = <&ti_spl_unsigned_template>; fit { images { + tifsstub-hs { + description = "TIFSSTUB"; + type = "firmware"; + arch = "arm32"; + compression = "none"; + os = "tifsstub-hs"; + load = <0x9dc00000>; + entry = <0x9dc00000>; + blob-ext { + filename = "tifsstub.bin_hs"; + }; + }; + + tifsstub-fs { + description = "TIFSSTUB"; + type = "firmware"; + arch = "arm32"; + compression = "none"; + os = "tifsstub-fs"; + load = <0x9dc00000>; + entry = <0x9dc00000>; + blob-ext { + filename = "tifsstub.bin_fs"; + }; + }; + + tifsstub-gp { + description = "TIFSSTUB"; + type = "firmware"; + arch = "arm32"; + compression = "none"; + os = "tifsstub-gp"; + load = <0x9dc00000>; + entry = <0x9dc00000>; + blob-ext { + filename = "tifsstub.bin_gp"; + }; + }; + dm { ti-dm { filename = "ti-dm/am62xx/ipc_echo_testb_mcu1_0_release_strip.xer5f"; diff --git a/arch/arm/dts/qcs615-ride-u-boot.dtsi b/arch/arm/dts/qcs615-ride-u-boot.dtsi new file mode 100644 index 00000000000..68fffc70fcb --- /dev/null +++ b/arch/arm/dts/qcs615-ride-u-boot.dtsi @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2025, Qualcomm Innovation Center, Inc. All rights reserved. + */ + +/ { + memory@80000000 { + device_type = "memory"; + reg = <0x0 0x80000000 0x0 0x7a00000>, + <0x0 0x89600000 0x0 0x30100000>, + <0x0 0xc0000000 0x0 0xc0000000>, + <0x1 0x80000000 0x1 0x00000000>; + }; +}; diff --git a/arch/arm/dts/qcs8300-ride-u-boot.dtsi b/arch/arm/dts/qcs8300-ride-u-boot.dtsi new file mode 100644 index 00000000000..8c353ace71e --- /dev/null +++ b/arch/arm/dts/qcs8300-ride-u-boot.dtsi @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2025, Qualcomm Innovation Center, Inc. All rights reserved. + */ + +/ { + memory@80000000 { + device_type = "memory"; + reg = <0x0 0x80000000 0x0 0x11a80000>, + <0x0 0xc0000000 0x0 0x10000000>, + <0x0 0xd3100000 0x0 0x26b00000>, + <0xe 0x80000000 0x1 0x00000000>, + <0xa 0x80000000 0x1 0x80000000>, + <0x0 0xb0800000 0x0 0x0f200000>, + <0x0 0xd0100000 0x0 0x01800000>, + <0x0 0x91b00000 0x0 0x1e500000>; + }; +}; + diff --git a/arch/arm/dts/sam9x60.dtsi b/arch/arm/dts/sam9x60.dtsi index 7631dfaa07f..79449042c24 100644 --- a/arch/arm/dts/sam9x60.dtsi +++ b/arch/arm/dts/sam9x60.dtsi @@ -311,6 +311,14 @@ clocks = <&slow_rc_osc>, <&slow_xtal>; #clock-cells = <1>; }; + + watchdog: watchdog@ffffff80 { + compatible = "microchip,sam9x60-wdt"; + reg = <0xffffff80 0x24>; + interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>; + clocks = <&clk32 0>; + status = "disabled"; + }; }; }; 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 ccacc99d018..575dff68804 100644 --- a/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h +++ b/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h @@ -90,6 +90,13 @@ #define CCM_PLL6_DEFAULT 0xe8216300 #define CCM_PSI_AHB1_AHB2_DEFAULT 0x03000002 #define CCM_APB1_DEFAULT 0x03000102 + +#elif CONFIG_MACH_SUN50I_A133 /* A133 */ + +#define CCM_PLL6_DEFAULT 0xb8003100 +#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_sun50i_h6.h b/arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h index 8a3f465545a..2a9b086991c 100644 --- a/arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h +++ b/arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h @@ -29,6 +29,10 @@ #define SUNXI_DRAM_COM_BASE 0x047FA000 #define SUNXI_DRAM_CTL0_BASE 0x047FB000 #define SUNXI_DRAM_PHY0_BASE 0x04800000 +#elif CONFIG_MACH_SUN50I_A133 +#define SUNXI_DRAM_COM_BASE 0x04810000 +#define SUNXI_DRAM_CTL0_BASE 0x04820000 +#define SUNXI_DRAM_PHY0_BASE 0x04830000 #endif #define SUNXI_TWI0_BASE 0x05002000 diff --git a/arch/arm/include/asm/arch-sunxi/dram.h b/arch/arm/include/asm/arch-sunxi/dram.h index 9d21b492418..0708ae3ee3b 100644 --- a/arch/arm/include/asm/arch-sunxi/dram.h +++ b/arch/arm/include/asm/arch-sunxi/dram.h @@ -31,6 +31,8 @@ #include <asm/arch/dram_sun50i_h6.h> #elif defined(CONFIG_MACH_SUN50I_H616) #include <asm/arch/dram_sun50i_h616.h> +#elif defined(CONFIG_DRAM_SUN50I_A133) +#include <asm/arch/dram_sun50i_a133.h> #elif defined(CONFIG_MACH_SUNIV) #include <asm/arch/dram_suniv.h> #else diff --git a/arch/arm/include/asm/arch-sunxi/dram_sun50i_a133.h b/arch/arm/include/asm/arch-sunxi/dram_sun50i_a133.h new file mode 100644 index 00000000000..a5fc6ad3656 --- /dev/null +++ b/arch/arm/include/asm/arch-sunxi/dram_sun50i_a133.h @@ -0,0 +1,230 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * A133 dram controller register and constant defines + * + * (C) Copyright 2024 MasterR3C0RD <masterr3c0rd@epochal.quest> + */ + +#ifndef _SUNXI_DRAM_SUN50I_A133_H +#define _SUNXI_DRAM_SUN50I_A133_H + +#include <linux/bitops.h> + +enum sunxi_dram_type { + SUNXI_DRAM_TYPE_DDR3 = 3, + SUNXI_DRAM_TYPE_DDR4, + SUNXI_DRAM_TYPE_LPDDR3 = 7, + SUNXI_DRAM_TYPE_LPDDR4 +}; + +static inline int ns_to_t(int nanoseconds) +{ + const unsigned int ctrl_freq = CONFIG_DRAM_CLK / 2; + + return DIV_ROUND_UP(ctrl_freq * nanoseconds, 1000); +} + +/* MBUS part is largely the same as in H6, except for one special register */ +#define MCTL_COM_UNK_008 0x008 +/* NOTE: This register has the same importance as mctl_ctl->clken in H616 */ +#define MCTL_COM_MAER0 0x020 + +/* + * Controller registers seems to be the same or at least very similar + * to those in H6. + */ +struct sunxi_mctl_ctl_reg { + u32 mstr; /* 0x000 */ + u32 statr; /* 0x004 unused */ + u32 mstr1; /* 0x008 unused */ + u32 clken; /* 0x00c */ + u32 mrctrl0; /* 0x010 unused */ + u32 mrctrl1; /* 0x014 unused */ + u32 mrstatr; /* 0x018 unused */ + u32 mrctrl2; /* 0x01c unused */ + u32 derateen; /* 0x020 unused */ + u32 derateint; /* 0x024 unused */ + u8 reserved_0x028[8]; /* 0x028 */ + u32 pwrctl; /* 0x030 unused */ + u32 pwrtmg; /* 0x034 unused */ + u32 hwlpctl; /* 0x038 unused */ + u8 reserved_0x03c[20]; /* 0x03c */ + u32 rfshctl0; /* 0x050 unused */ + u32 rfshctl1; /* 0x054 unused */ + u8 reserved_0x058[8]; /* 0x05c */ + u32 rfshctl3; /* 0x060 */ + u32 rfshtmg; /* 0x064 */ + u8 reserved_0x068[104]; /* 0x068 */ + u32 init[8]; /* 0x0d0 */ + u32 dimmctl; /* 0x0f0 unused */ + u32 rankctl; /* 0x0f4 */ + u8 reserved_0x0f8[8]; /* 0x0f8 */ + u32 dramtmg[17]; /* 0x100 */ + u8 reserved_0x144[60]; /* 0x144 */ + u32 zqctl[3]; /* 0x180 */ + u32 zqstat; /* 0x18c unused */ + u32 dfitmg0; /* 0x190 */ + u32 dfitmg1; /* 0x194 */ + u32 dfilpcfg[2]; /* 0x198 unused */ + u32 dfiupd[3]; /* 0x1a0 */ + u32 reserved_0x1ac; /* 0x1ac */ + u32 dfimisc; /* 0x1b0 */ + u32 dfitmg2; /* 0x1b4 unused */ + u32 dfitmg3; /* 0x1b8 unused */ + u32 dfistat; /* 0x1bc */ + u32 dbictl; /* 0x1c0 */ + u8 reserved_0x1c4[60]; /* 0x1c4 */ + u32 addrmap[12]; /* 0x200 */ + u8 reserved_0x230[16]; /* 0x230 */ + u32 odtcfg; /* 0x240 */ + u32 odtmap; /* 0x244 */ + u8 reserved_0x248[8]; /* 0x248 */ + u32 sched[2]; /* 0x250 */ + u8 reserved_0x258[180]; /* 0x258 */ + u32 dbgcmd; /* 0x30c unused */ + u32 dbgstat; /* 0x310 unused */ + u8 reserved_0x314[12]; /* 0x314 */ + u32 swctl; /* 0x320 */ + u32 swstat; /* 0x324 */ + u8 reserved_0x328[7768]; /* 0x328 */ + u32 unk_0x2180; /* 0x2180 */ + u8 reserved_0x2184[188]; /* 0x2184 */ + u32 unk_0x2240; /* 0x2240 */ + u8 reserved_0x2244[3900]; /* 0x2244 */ + u32 unk_0x3180; /* 0x3180 */ + u8 reserved_0x3184[188]; /* 0x3184 */ + u32 unk_0x3240; /* 0x3240 */ + u8 reserved_0x3244[3900]; /* 0x3244 */ + u32 unk_0x4180; /* 0x4180 */ + u8 reserved_0x4184[188]; /* 0x4184 */ + u32 unk_0x4240; /* 0x4240 */ +}; + +check_member(sunxi_mctl_ctl_reg, swstat, 0x324); +check_member(sunxi_mctl_ctl_reg, unk_0x4240, 0x4240); + +#define MSTR_DEVICETYPE_DDR3 BIT(0) +#define MSTR_DEVICETYPE_LPDDR2 BIT(2) +#define MSTR_DEVICETYPE_LPDDR3 BIT(3) +#define MSTR_DEVICETYPE_DDR4 BIT(4) +#define MSTR_DEVICETYPE_LPDDR4 BIT(5) +#define MSTR_DEVICETYPE_MASK GENMASK(5, 0) +#define MSTR_GEARDOWNMODE BIT(0) /* Same as MSTR_DEVICETYPE_DDR3, only used for DDR4 */ +#define MSTR_2TMODE BIT(10) +#define MSTR_BUSWIDTH_FULL (0 << 12) +#define MSTR_BUSWIDTH_HALF (1 << 12) +#define MSTR_ACTIVE_RANKS(x) (((x == 1) ? 3 : 1) << 24) +#define MSTR_BURST_LENGTH(x) (((x) >> 1) << 16) +#define MSTR_DEVICECONFIG_X32 (3 << 30) + +#define TPR10_CA_BIT_DELAY BIT(16) +#define TPR10_DX_BIT_DELAY0 BIT(17) +#define TPR10_DX_BIT_DELAY1 BIT(18) +#define TPR10_WRITE_LEVELING BIT(20) +#define TPR10_READ_CALIBRATION BIT(21) +#define TPR10_READ_TRAINING BIT(22) +#define TPR10_WRITE_TRAINING BIT(23) + +/* MRCTRL constants */ +#define MRCTRL0_MR_RANKS_ALL (3 << 4) +#define MRCTRL0_MR_ADDR(x) (x << 12) +#define MRCTRL0_MR_WR BIT(31) + +#define MRCTRL1_MR_ADDR(x) (x << 8) +#define MRCTRL1_MR_DATA(x) (x) + +/* ADDRMAP constants */ +#define ADDRMAP_DISABLED_3F_B(b) (0x3f + b) +#define ADDRMAP_DISABLED_1F_B(b) (0x1f + b) +#define ADDRMAP_DISABLED_0F_B(b) (0x0f + b) + +#define _ADDRMAP_VALUE(a,x,b) (((a) - b) << (x * 8)) + +/* + * Bx = internal base + * The selected HIF address bit for each address bit is determined + * by adding the internal base to the value of each field + * */ + +#define ADDRMAP0_CS0_B6(v) _ADDRMAP_VALUE(v, 0, 6) + +#define ADDRMAP1_BANK0_B2(v) _ADDRMAP_VALUE(v, 0, 2) +#define ADDRMAP1_BANK1_B3(v) _ADDRMAP_VALUE(v, 1, 3) +#define ADDRMAP1_BANK2_B4(v) _ADDRMAP_VALUE(v, 2, 4) + +#define ADDRMAP2_COL2_B2(v) _ADDRMAP_VALUE(v, 0, 2) +#define ADDRMAP2_COL3_B3(v) _ADDRMAP_VALUE(v, 1, 3) +#define ADDRMAP2_COL4_B4(v) _ADDRMAP_VALUE(v, 2, 4) +#define ADDRMAP2_COL5_B5(v) _ADDRMAP_VALUE(v, 3, 5) + +#define ADDRMAP3_COL6_B6(v) _ADDRMAP_VALUE(v, 0, 6) +#define ADDRMAP3_COL7_B7(v) _ADDRMAP_VALUE(v, 1, 7) +#define ADDRMAP3_COL8_B8(v) _ADDRMAP_VALUE(v, 2, 8) +#define ADDRMAP3_COL9_B9(v) _ADDRMAP_VALUE(v, 3, 9) + +#define ADDRMAP4_COL10_B10(v) _ADDRMAP_VALUE(v, 0, 10) +#define ADDRMAP4_COL11_B11(v) _ADDRMAP_VALUE(v, 1, 11) + +#define ADDRMAP5_ROW0_B6(v) _ADDRMAP_VALUE(v, 0, 6) +#define ADDRMAP5_ROW1_B7(v) _ADDRMAP_VALUE(v, 1, 7) +#define ADDRMAP5_ROW2_10_B8(v) _ADDRMAP_VALUE(v, 2, 8) +#define ADDRMAP5_ROW11_B17(v) _ADDRMAP_VALUE(v, 3, 17) + +#define ADDRMAP6_ROW12_B18(v) _ADDRMAP_VALUE(v, 0, 18) +#define ADDRMAP6_ROW13_B19(v) _ADDRMAP_VALUE(v, 1, 19) +#define ADDRMAP6_ROW14_B20(v) _ADDRMAP_VALUE(v, 2, 20) +#define ADDRMAP6_ROW15_B21(v) _ADDRMAP_VALUE(v, 3, 21) + +#define ADDRMAP7_ROW16_B22(v) _ADDRMAP_VALUE(v, 0, 22) +#define ADDRMAP7_ROW17_B23(v) _ADDRMAP_VALUE(v, 1, 23) + +#define ADDRMAP8_BG0_B2(v) _ADDRMAP_VALUE(v, 0, 2) +#define ADDRMAP8_BG1_B3(v) _ADDRMAP_VALUE(v, 1, 3) + +/* These are only used if ADDRMAP5_ROW_BITS_2_10 = ADDRMAP_DISABLED_0F */ +#define ADDRMAP9_ROW2_B8(v) _ADDRMAP_VALUE(v, 0, 8) +#define ADDRMAP9_ROW3_B9(v) _ADDRMAP_VALUE(v, 1, 9) +#define ADDRMAP9_ROW4_B10(v) _ADDRMAP_VALUE(v, 2, 10) +#define ADDRMAP9_ROW5_B11(v) _ADDRMAP_VALUE(v, 3, 11) + +#define ADDRMAP10_ROW6_B12(v) _ADDRMAP_VALUE(v, 0, 12) +#define ADDRMAP10_ROW7_B13(v) _ADDRMAP_VALUE(v, 1, 13) +#define ADDRMAP10_ROW8_B14(v) _ADDRMAP_VALUE(v, 2, 14) +#define ADDRMAP10_ROW9_B15(v) _ADDRMAP_VALUE(v, 3, 15) + +#define ADDRMAP11_ROW10_B16(v) _ADDRMAP_VALUE(v, 0, 16) + +struct dram_para { + uint32_t clk; + enum sunxi_dram_type type; + uint32_t dx_odt; + uint32_t dx_dri; + uint32_t ca_dri; + uint32_t para0; + uint32_t mr11; + uint32_t mr12; + uint32_t mr13; + uint32_t mr14; + uint32_t tpr1; + uint32_t tpr2; + uint32_t tpr3; + uint32_t tpr6; + uint32_t tpr10; + uint32_t tpr11; + uint32_t tpr12; + uint32_t tpr13; + uint32_t tpr14; +}; + +void mctl_set_timing_params(const struct dram_para *para); + +struct dram_config { + u8 cols; /* Column bits */ + u8 rows; /* Row bits */ + u8 ranks; /* Rank bits (different from H616!) */ + u8 banks; /* Bank bits */ + u8 bankgrps; /* Bank group bits */ + u8 bus_full_width; /* 1 = x32, 0 = x16 */ +}; + +#endif /* _SUNXI_DRAM_SUN50I_A133_H */ diff --git a/arch/arm/lib/crt0.S b/arch/arm/lib/crt0.S index a50dde60e8b..3e11fadafc6 100644 --- a/arch/arm/lib/crt0.S +++ b/arch/arm/lib/crt0.S @@ -145,7 +145,7 @@ ENTRY(_main) ldr r1, =CONFIG_TEXT_BASE sub r1, r0 add lr, r1 -#if defined(CONFIG_SYS_RELOC_GD_ENV_ADDR) +#if defined(CONFIG_ENV_RELOC_GD_ENV_ADDR) ldr r0, [r9, #GD_ENV_ADDR] /* r0 = gd->env_addr */ add r0, r0, r1 str r0, [r9, #GD_ENV_ADDR] diff --git a/arch/arm/lib/crt0_64.S b/arch/arm/lib/crt0_64.S index 30950ddaf9b..f3f279f2c39 100644 --- a/arch/arm/lib/crt0_64.S +++ b/arch/arm/lib/crt0_64.S @@ -119,7 +119,7 @@ ENTRY(_main) ldr x9, _TEXT_BASE /* x9 <- Linked value of _start */ sub x9, x9, x0 /* x9 <- Run-vs-link offset */ add lr, lr, x9 -#if defined(CONFIG_SYS_RELOC_GD_ENV_ADDR) +#if defined(CONFIG_ENV_RELOC_GD_ENV_ADDR) ldr x0, [x18, #GD_ENV_ADDR] /* x0 <- gd->env_addr */ add x0, x0, x9 str x0, [x18, #GD_ENV_ADDR] diff --git a/arch/arm/mach-airoha/an7581/init.c b/arch/arm/mach-airoha/an7581/init.c index cefe9c6db9e..d149e0ee3c8 100644 --- a/arch/arm/mach-airoha/an7581/init.c +++ b/arch/arm/mach-airoha/an7581/init.c @@ -2,6 +2,7 @@ #include <fdtdec.h> #include <init.h> +#include <sysreset.h> #include <asm/armv8/mmu.h> #include <asm/system.h> @@ -21,7 +22,7 @@ int dram_init_banksize(void) return fdtdec_setup_memory_banksize(); } -void reset_cpu(ulong addr) +void reset_cpu(void) { psci_system_reset(); } diff --git a/arch/arm/mach-apple/board.c b/arch/arm/mach-apple/board.c index 2604c5a710e..4cd8979bdc2 100644 --- a/arch/arm/mach-apple/board.c +++ b/arch/arm/mach-apple/board.c @@ -773,22 +773,31 @@ u64 get_page_table_size(void) #define KERNEL_COMP_SIZE SZ_128M +#define lmb_alloc(size, addr) lmb_alloc_mem(LMB_MEM_ALLOC_ANY, SZ_2M, addr, size, LMB_NONE) + int board_late_init(void) { u32 status = 0; + phys_addr_t addr; /* somewhat based on the Linux Kernel boot requirements: * align by 2M and maximal FDT size 2M */ - status |= env_set_hex("loadaddr", lmb_alloc(SZ_1G, SZ_2M)); - status |= env_set_hex("fdt_addr_r", lmb_alloc(SZ_2M, SZ_2M)); - status |= env_set_hex("kernel_addr_r", lmb_alloc(SZ_128M, SZ_2M)); - status |= env_set_hex("ramdisk_addr_r", lmb_alloc(SZ_1G, SZ_2M)); - status |= env_set_hex("kernel_comp_addr_r", - lmb_alloc(KERNEL_COMP_SIZE, SZ_2M)); - status |= env_set_hex("kernel_comp_size", KERNEL_COMP_SIZE); - status |= env_set_hex("scriptaddr", lmb_alloc(SZ_4M, SZ_2M)); - status |= env_set_hex("pxefile_addr_r", lmb_alloc(SZ_4M, SZ_2M)); + status |= !lmb_alloc(SZ_1G, &addr) ? env_set_hex("loadaddr", addr) : 1; + status |= !lmb_alloc(SZ_2M, &addr) ? + env_set_hex("fdt_addr_r", addr) : 1; + status |= !lmb_alloc(SZ_128M, &addr) ? + env_set_hex("kernel_addr_r", addr) : 1; + status |= !lmb_alloc(SZ_1G, &addr) ? + env_set_hex("ramdisk_addr_r", addr) : 1; + status |= !lmb_alloc(KERNEL_COMP_SIZE, &addr) ? + env_set_hex("kernel_comp_addr_r", addr) : 1; + status |= !lmb_alloc(KERNEL_COMP_SIZE, &addr) ? + env_set_hex("kernel_comp_size", addr) : 1; + status |= !lmb_alloc(SZ_4M, &addr) ? + env_set_hex("scriptaddr", addr) : 1; + status |= !lmb_alloc(SZ_4M, &addr) ? + env_set_hex("pxefile_addr_r", addr) : 1; if (status) log_warning("late_init: Failed to set run time variables\n"); diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index 7c4ccc427c8..d21534ce883 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig @@ -43,6 +43,10 @@ config SAM9X60 bool select CPU_ARM926EJS +config SAM9X7 + bool + select CPU_ARM926EJS + config SAMA7G5 bool select CPU_V7A @@ -154,6 +158,13 @@ config TARGET_SAM9X60_CURIOSITY select BOARD_EARLY_INIT_F select BOARD_LATE_INIT +config TARGET_SAM9X75_CURIOSITY + bool "SAM9X75 CURIOSITY board" + select SAM9X7 + select BOARD_EARLY_INIT_F + select BOARD_LATE_INIT + imply OF_UPSTREAM + config TARGET_SAMA5D2_PTC_EK bool "SAMA5D2 PTC EK board" select BOARD_EARLY_INIT_F @@ -351,6 +362,7 @@ source "board/atmel/at91sam9rlek/Kconfig" source "board/atmel/at91sam9x5ek/Kconfig" source "board/atmel/sam9x60ek/Kconfig" source "board/atmel/sam9x60_curiosity/Kconfig" +source "board/atmel/sam9x75_curiosity/Kconfig" source "board/atmel/sama7g5ek/Kconfig" source "board/atmel/sama7g54_curiosity/Kconfig" source "board/atmel/sama5d2_ptc_ek/Kconfig" diff --git a/arch/arm/mach-at91/arm926ejs/Makefile b/arch/arm/mach-at91/arm926ejs/Makefile index 62c44b997e4..8a9464cdfba 100644 --- a/arch/arm/mach-at91/arm926ejs/Makefile +++ b/arch/arm/mach-at91/arm926ejs/Makefile @@ -14,6 +14,7 @@ obj-$(CONFIG_AT91SAM9G45) += at91sam9m10g45_devices.o obj-$(CONFIG_AT91SAM9N12) += at91sam9n12_devices.o obj-$(CONFIG_AT91SAM9X5) += at91sam9x5_devices.o obj-$(CONFIG_SAM9X60) += sam9x60_devices.o +obj-$(CONFIG_SAM9X7) += sam9x7_devices.o obj-y += clock.o obj-y += cpu.o ifndef CONFIG_$(PHASE_)SYSRESET diff --git a/arch/arm/mach-at91/arm926ejs/sam9x7_devices.c b/arch/arm/mach-at91/arm926ejs/sam9x7_devices.c new file mode 100644 index 00000000000..c65764a3de4 --- /dev/null +++ b/arch/arm/mach-at91/arm926ejs/sam9x7_devices.c @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2025 Microchip Technology Inc. and its subsidiaries + */ + +#include <asm/arch/at91_common.h> +#include <asm/arch/clk.h> +#include <asm/arch/gpio.h> +#include <asm/io.h> + +unsigned int get_chip_id(void) +{ + /* The 0x40 is the offset of cidr in DBGU */ + return readl(ATMEL_BASE_DBGU + 0x40); +} + +unsigned int get_extension_chip_id(void) +{ + /* The 0x44 is the offset of exid in DBGU */ + return readl(ATMEL_BASE_DBGU + 0x44); +} + +char *get_cpu_name(void) +{ + unsigned int extension_id = get_extension_chip_id(); + + if (cpu_is_sam9x7()) { + switch (extension_id) { + case ARCH_EXID_SAM9X70: + return "SAM9X70"; + case ARCH_EXID_SAM9X72: + return "SAM9X72"; + case ARCH_EXID_SAM9X75: + return "SAM9X75"; + case ARCH_EXID_SAM9X75_D1M: + return "SAM9X75 16MB DDR2 SiP"; + case ARCH_EXID_SAM9X75_D5M: + return "SAM9X75 64MB DDR2 SiP"; + case ARCH_EXID_SAM9X75_D1G: + return "SAM9X75 125MB DDR3L SiP"; + case ARCH_EXID_SAM9X75_D2G: + return "SAM9X75 250MB DDR3L SiP"; + default: + return "Unknown CPU type"; + } + } else { + return "Unknown CPU type"; + } +} diff --git a/arch/arm/mach-at91/include/mach/at91_wdt.h b/arch/arm/mach-at91/include/mach/at91_wdt.h index 25d95fab1f8..3780f0bfe40 100644 --- a/arch/arm/mach-at91/include/mach/at91_wdt.h +++ b/arch/arm/mach-at91/include/mach/at91_wdt.h @@ -19,15 +19,16 @@ #else -typedef struct at91_wdt { - u32 cr; - u32 mr; - u32 sr; -} at91_wdt_t; +enum { + AT91_WDT_MODE_SAM9260 = 0, + AT91_WDT_MODE_SAM9X60 = 1 +}; struct at91_wdt_priv { void __iomem *regs; - u32 regval; + u32 mr; + u32 wddis; + u8 mode; }; #endif @@ -39,14 +40,22 @@ struct at91_wdt_priv { /* Watchdog Mode Register*/ #define AT91_WDT_MR 0x04 -#define AT91_WDT_MR_WDV(x) (x & 0xfff) +#define AT91_WDT_MR_WDV(x) ((x) & 0xfff) +#define AT91_SAM9X60_MR_PERIODRST 0x00000010 #define AT91_WDT_MR_WDFIEN 0x00001000 +#define AT91_SAM9X60_MR_WDDIS 0x00001000 #define AT91_WDT_MR_WDRSTEN 0x00002000 #define AT91_WDT_MR_WDRPROC 0x00004000 #define AT91_WDT_MR_WDDIS 0x00008000 -#define AT91_WDT_MR_WDD(x) ((x & 0xfff) << 16) +#define AT91_WDT_MR_WDD(x) (((x) & 0xfff) << 16) #define AT91_WDT_MR_WDDBGHLT 0x10000000 +#define AT91_SAM9X60_MR_WDIDLEHLT 0x10000000 #define AT91_WDT_MR_WDIDLEHLT 0x20000000 +#define AT91_SAM9X60_MR_WDDBGHLT 0x20000000 + +/* Watchdog Window Level Register */ +#define AT91_SAM9X60_WLR 0x0c +#define AT91_SAM9X60_WLR_COUNTER(x) ((x) & 0xfff) /* Hardware timeout in seconds */ #define WDT_MAX_TIMEOUT 16 diff --git a/arch/arm/mach-at91/include/mach/hardware.h b/arch/arm/mach-at91/include/mach/hardware.h index 988ef492b62..de89714b097 100644 --- a/arch/arm/mach-at91/include/mach/hardware.h +++ b/arch/arm/mach-at91/include/mach/hardware.h @@ -23,6 +23,8 @@ # include <asm/arch/at91sam9x5.h> #elif defined(CONFIG_SAM9X60) # include <asm/arch/sam9x60.h> +#elif defined(CONFIG_SAM9X7) +# include <asm/arch/sam9x7.h> #elif defined(CONFIG_SAMA7G5) # include <asm/arch/sama7g5.h> #elif defined(CONFIG_SAMA5D2) diff --git a/arch/arm/mach-at91/include/mach/sam9x7.h b/arch/arm/mach-at91/include/mach/sam9x7.h new file mode 100644 index 00000000000..998fa786f90 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/sam9x7.h @@ -0,0 +1,172 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Chip-specific header file for the SAM9X7 SoC. + * + * Copyright (C) 2025 Microchip Technology Inc. and its subsidiaries + */ + +#ifndef __SAM9X7_H__ +#define __SAM9X7_H__ + +/* + * Peripheral identifiers/interrupts. + */ +#define ATMEL_ID_FIQ 0 /* Advanced Interrupt Controller - FIQ */ +#define ATMEL_ID_SYS 1 /* System Controller Interrupt */ +#define ATMEL_ID_PIOA 2 /* Parallel I/O Controller A */ +#define ATMEL_ID_PIOB 3 /* Parallel I/O Controller B */ +#define ATMEL_ID_PIOC 4 /* Parallel I/O Controller C */ +#define ATMEL_ID_FLEXCOM0 5 /* FLEXCOM 0 */ +#define ATMEL_ID_FLEXCOM1 6 /* FLEXCOM 1 */ +#define ATMEL_ID_FLEXCOM2 7 /* FLEXCOM 2 */ +#define ATMEL_ID_FLEXCOM3 8 /* FLEXCOM 3 */ +#define ATMEL_ID_FLEXCOM6 9 /* FLEXCOM 6 */ +#define ATMEL_ID_FLEXCOM7 10 /* FLEXCOM 7 */ +#define ATMEL_ID_FLEXCOM8 11 /* FLEXCOM 8 */ +#define ATMEL_ID_SDMMC0 12 /* SDMMC 0 */ +#define ATMEL_ID_FLEXCOM4 13 /* FLEXCOM 4 */ +#define ATMEL_ID_FLEXCOM5 14 /* FLEXCOM 5 */ +#define ATMEL_ID_FLEXCOM9 15 /* FLEXCOM 9 */ +#define ATMEL_ID_FLEXCOM10 16 /* FLEXCOM 10 */ +#define ATMEL_ID_TC01 17 /* Timer Counter 0, 1, 2, 3, 4 and 5 */ +#define ATMEL_ID_PWM 18 /* Pulse Width Modulation Controller */ +#define ATMEL_ID_ADC 19 /* ADC Controller */ +#define ATMEL_ID_XDMAC0 20 /* XDMA Controller 0 */ +#define ATMEL_ID_MATRIX 21 /* BUS Matrix */ +#define ATMEL_ID_UHPHS 22 /* USB Host High Speed */ +#define ATMEL_ID_UDPHS 23 /* USB Device High Speed */ +#define ATMEL_ID_GMAC 24 /* GMAC */ +#define ATMEL_ID_LCDC 25 /* LCD Controller */ +#define ATMEL_ID_SDMMC1 26 /* SDMMC 1 */ +#define ATMEL_ID_SSC 28 /* Synchronous Serial Controller */ +#define ATMEL_ID_IRQ 31 /* Advanced Interrupt Controller - IRQ */ +#define ATMEL_ID_TRNG 38 /* True Random Number Generator */ +#define ATMEL_ID_PIOD 44 /* Parallel I/O Controller D */ +#define ATMEL_ID_DBGU 47 /* Debug unit */ + +/* + * User Peripheral physical base addresses. + */ +#define ATMEL_BASE_FLEXCOM4 0xf0000000 +#define ATMEL_BASE_FLEXCOM5 0xf0004000 +#define ATMEL_BASE_XDMA0 0xf0008000 +#define ATMEL_BASE_SSC 0xf0010000 +#define ATMEL_BASE_QSPI 0xf0014000 +#define ATMEL_BASE_CAN0 0xf8000000 +#define ATMEL_BASE_CAN1 0xf8004000 +#define ATMEL_BASE_TC0 0xf8008000 +#define ATMEL_BASE_TC1 0xf800c000 +#define ATMEL_BASE_FLEXCOM6 0xf8010000 +#define ATMEL_BASE_FLEXCOM7 0xf8014000 +#define ATMEL_BASE_FLEXCOM8 0xf8018000 +#define ATMEL_BASE_FLEXCOM0 0xf801c000 +#define ATMEL_BASE_FLEXCOM1 0xf8020000 +#define ATMEL_BASE_FLEXCOM2 0xf8024000 +#define ATMEL_BASE_FLEXCOM3 0xf8028000 +#define ATMEL_BASE_GMAC 0xf802c000 +#define ATMEL_BASE_PWM 0xf8034000 +#define ATMEL_BASE_LCDC 0xf8038000 +#define ATMEL_BASE_UDPHS 0xf803c000 +#define ATMEL_BASE_FLEXCOM9 0xf8040000 +#define ATMEL_BASE_FLEXCOM10 0xf8044000 +#define ATMEL_BASE_ISC 0xf8048000 +#define ATMEL_BASE_ADC 0xf804c000 +#define ATMEL_BASE_SFR 0xf8050000 +#define ATMEL_BASE_SYS 0xffffc000 + +/* + * System Peripherals + */ +#define ATMEL_BASE_MATRIX 0xffffde00 +#define ATMEL_BASE_PMECC 0xffffe000 +#define ATMEL_BASE_PMERRLOC 0xffffe600 +#define ATMEL_BASE_MPDDRC 0xffffe800 +#define ATMEL_BASE_SMC 0xffffea00 +#define ATMEL_BASE_SDRAMC 0xffffec00 +#define ATMEL_BASE_AIC 0xfffff100 +#define ATMEL_BASE_DBGU 0xfffff200 +#define ATMEL_BASE_PIOA 0xfffff400 +#define ATMEL_BASE_PIOB 0xfffff600 +#define ATMEL_BASE_PIOC 0xfffff800 +#define ATMEL_BASE_PIOD 0xfffffa00 +#define ATMEL_BASE_PMC 0xfffffc00 +#define ATMEL_BASE_RSTC 0xfffffe00 +#define ATMEL_BASE_SHDWC 0xfffffe10 +#define ATMEL_BASE_PIT 0xfffffe40 +#define ATMEL_BASE_GPBR 0xfffffe60 +#define ATMEL_BASE_RTC 0xfffffea8 +#define ATMEL_BASE_WDT 0xffffff80 + +/* + * Internal Memory. + */ +#define ATMEL_BASE_ROM 0x00100000 /* Internal ROM base address */ +#define ATMEL_BASE_SRAM 0x00300000 /* Internal SRAM base address */ +#define ATMEL_BASE_UDPHS_FIFO 0x00500000 /* USB Device HS controller */ +#define ATMEL_BASE_OHCI 0x00600000 /* USB Host controller (OHCI) */ +#define ATMEL_BASE_EHCI 0x00700000 /* USB Host controller (EHCI) */ + +/* + * External memory + */ +#define ATMEL_BASE_CS0 0x10000000 +#define ATMEL_BASE_CS1 0x20000000 +#define ATMEL_BASE_CS2 0x30000000 +#define ATMEL_BASE_CS3 0x40000000 +#define ATMEL_BASE_CS4 0x50000000 +#define ATMEL_BASE_CS5 0x60000000 +#define ATMEL_BASE_SDMMC0 0x80000000 +#define ATMEL_BASE_SDMMC1 0x90000000 + +/* + * SAM9x7 series chip id definitions + */ +#define ARCH_ID_SAM9X7 0x89750030 +#define ARCH_EXID_SAM9X70 0x00000005 +#define ARCH_EXID_SAM9X72 0x00000004 +#define ARCH_EXID_SAM9X75 0x00000000 +#define ARCH_EXID_SAM9X75_D1G 0x00000018 +#define ARCH_EXID_SAM9X75_D2G 0x00000020 +#define ARCH_EXID_SAM9X75_D1M 0x00000003 +#define ARCH_EXID_SAM9X75_D5M 0x00000010 + +#define cpu_is_sam9x7() (get_chip_id() == ARCH_ID_SAM9X7) + +/* + * Cpu Name + */ +#define ATMEL_CPU_NAME get_cpu_name() + +/* + * Timer + */ +#define CFG_SYS_TIMER_COUNTER 0xf0028000 + +/* + * Other misc defines + */ +#define ATMEL_PIO_PORTS 4 +#define CPU_HAS_PCR +#define CPU_NO_PLLB +#define PLL_ID_PLLA 0 +#define PLL_ID_UPLL 1 +#define PLL_ID_AUDIOPLL 2 +#define PLL_ID_LVDSPLL 3 +#define PLL_ID_PLLA_DIV_2 4 + +/* + * PMECC table in ROM + */ +#define ATMEL_PMECC_INDEX_OFFSET_512 0x0000 +#define ATMEL_PMECC_INDEX_OFFSET_1024 0x8000 + +/* + * SAM9X7 specific prototypes + */ +#ifndef __ASSEMBLY__ +unsigned int get_chip_id(void); +unsigned int get_extension_chip_id(void); +char *get_cpu_name(void); +#endif + +#endif diff --git a/arch/arm/mach-at91/spl.c b/arch/arm/mach-at91/spl.c index 5feb8f73551..a814973242a 100644 --- a/arch/arm/mach-at91/spl.c +++ b/arch/arm/mach-at91/spl.c @@ -14,9 +14,7 @@ #if !defined(CONFIG_WDT_AT91) void at91_disable_wdt(void) { - struct at91_wdt *wdt = (struct at91_wdt *)ATMEL_BASE_WDT; - - writel(AT91_WDT_MR_WDDIS, &wdt->mr); + writel(AT91_WDT_MR_WDDIS, ATMEL_BASE_WDT + AT91_WDT_MR); } #endif diff --git a/arch/arm/mach-imx/imx8/cpu.c b/arch/arm/mach-imx/imx8/cpu.c index 37a5473ac7c..0e112af661c 100644 --- a/arch/arm/mach-imx/imx8/cpu.c +++ b/arch/arm/mach-imx/imx8/cpu.c @@ -451,7 +451,7 @@ void get_board_serial(struct tag_serialnr *serialnr) #ifdef CONFIG_ENV_IS_IN_MMC __weak int board_mmc_get_env_dev(int devno) { - return CONFIG_SYS_MMC_ENV_DEV; + return CONFIG_ENV_MMC_DEVICE_INDEX; } int mmc_get_env_dev(void) @@ -473,7 +473,7 @@ int mmc_get_env_dev(void) break; default: /* If not boot from sd/mmc, use default value */ - return CONFIG_SYS_MMC_ENV_DEV; + return CONFIG_ENV_MMC_DEVICE_INDEX; } return board_mmc_get_env_dev(devno); diff --git a/arch/arm/mach-imx/imx8ulp/soc.c b/arch/arm/mach-imx/imx8ulp/soc.c index 2b042300103..8fe70e2424f 100644 --- a/arch/arm/mach-imx/imx8ulp/soc.c +++ b/arch/arm/mach-imx/imx8ulp/soc.c @@ -56,7 +56,7 @@ int mmc_get_env_dev(void) if (ret != ROM_API_OKAY) { puts("ROMAPI: failure at query_boot_info\n"); - return CONFIG_SYS_MMC_ENV_DEV; + return CONFIG_ENV_MMC_DEVICE_INDEX; } boot_type = boot >> 16; @@ -64,7 +64,7 @@ int mmc_get_env_dev(void) /* If not boot from sd/mmc, use default value */ if (boot_type != BOOT_TYPE_SD && boot_type != BOOT_TYPE_MMC) - return env_get_ulong("mmcdev", 10, CONFIG_SYS_MMC_ENV_DEV); + return env_get_ulong("mmcdev", 10, CONFIG_ENV_MMC_DEVICE_INDEX); return board_mmc_get_env_dev(boot_instance); } diff --git a/arch/arm/mach-imx/imx9/scmi/soc.c b/arch/arm/mach-imx/imx9/scmi/soc.c index d68a1166deb..13f13ca7d10 100644 --- a/arch/arm/mach-imx/imx9/scmi/soc.c +++ b/arch/arm/mach-imx/imx9/scmi/soc.c @@ -84,7 +84,7 @@ int mmc_get_env_dev(void) ret = scmi_get_rom_data(rdata); if (ret != 0) { puts("SCMI: failure at rom_boot_info\n"); - return CONFIG_SYS_MMC_ENV_DEV; + return CONFIG_ENV_MMC_DEVICE_INDEX; } } boot_type = rdata->boot_dev_type; @@ -95,7 +95,7 @@ int mmc_get_env_dev(void) /* If not boot from sd/mmc, use default value */ if (boot_type != BOOT_TYPE_SD && boot_type != BOOT_TYPE_MMC) - return env_get_ulong("mmcdev", 10, CONFIG_SYS_MMC_ENV_DEV); + return env_get_ulong("mmcdev", 10, CONFIG_ENV_MMC_DEVICE_INDEX); return board_mmc_get_env_dev(boot_instance); } diff --git a/arch/arm/mach-imx/imx9/soc.c b/arch/arm/mach-imx/imx9/soc.c index bb13ca742e3..02db7cc97ba 100644 --- a/arch/arm/mach-imx/imx9/soc.c +++ b/arch/arm/mach-imx/imx9/soc.c @@ -48,8 +48,8 @@ __weak int board_mmc_get_env_dev(int devno) return devno; } -#ifdef CONFIG_SYS_MMC_ENV_DEV -#define IMX9_MMC_ENV_DEV CONFIG_SYS_MMC_ENV_DEV +#ifdef CONFIG_ENV_MMC_DEVICE_INDEX +#define IMX9_MMC_ENV_DEV CONFIG_ENV_MMC_DEVICE_INDEX #else #define IMX9_MMC_ENV_DEV 0 #endif diff --git a/arch/arm/mach-imx/mmc_env.c b/arch/arm/mach-imx/mmc_env.c index 34a7d1706f3..2ec8ddf4d59 100644 --- a/arch/arm/mach-imx/mmc_env.c +++ b/arch/arm/mach-imx/mmc_env.c @@ -10,7 +10,7 @@ __weak int board_mmc_get_env_dev(int devno) { - return CONFIG_SYS_MMC_ENV_DEV; + return CONFIG_ENV_MMC_DEVICE_INDEX; } int mmc_get_env_dev(void) @@ -22,7 +22,7 @@ int mmc_get_env_dev(void) /* If not boot from sd/mmc, use default value */ if ((boot_type != BOOT_TYPE_SD) && (boot_type != BOOT_TYPE_MMC)) - return CONFIG_SYS_MMC_ENV_DEV; + return CONFIG_ENV_MMC_DEVICE_INDEX; return board_mmc_get_env_dev(devno); } diff --git a/arch/arm/mach-imx/mx6/soc.c b/arch/arm/mach-imx/mx6/soc.c index d4a61731a67..50521490b35 100644 --- a/arch/arm/mach-imx/mx6/soc.c +++ b/arch/arm/mach-imx/mx6/soc.c @@ -502,7 +502,7 @@ int arch_cpu_init(void) #ifdef CONFIG_ENV_IS_IN_MMC __weak int board_mmc_get_env_dev(int devno) { - return CONFIG_SYS_MMC_ENV_DEV; + return CONFIG_ENV_MMC_DEVICE_INDEX; } static int mmc_get_boot_dev(void) @@ -535,15 +535,15 @@ int mmc_get_env_dev(void) /* If not boot from sd/mmc, use default value */ if (devno < 0) - return CONFIG_SYS_MMC_ENV_DEV; + return CONFIG_ENV_MMC_DEVICE_INDEX; return board_mmc_get_env_dev(devno); } -#ifdef CONFIG_SYS_MMC_ENV_PART +#ifdef CONFIG_ENV_MMC_EMMC_HW_PARTITION __weak int board_mmc_get_env_part(int devno) { - return CONFIG_SYS_MMC_ENV_PART; + return CONFIG_ENV_MMC_EMMC_HW_PARTITION; } uint mmc_get_env_part(struct mmc *mmc) @@ -552,7 +552,7 @@ uint mmc_get_env_part(struct mmc *mmc) /* If not boot from sd/mmc, use default value */ if (devno < 0) - return CONFIG_SYS_MMC_ENV_PART; + return CONFIG_ENV_MMC_EMMC_HW_PARTITION; return board_mmc_get_env_part(devno); } diff --git a/arch/arm/mach-imx/mx7ulp/soc.c b/arch/arm/mach-imx/mx7ulp/soc.c index 61d331e0181..5306e76223f 100644 --- a/arch/arm/mach-imx/mx7ulp/soc.c +++ b/arch/arm/mach-imx/mx7ulp/soc.c @@ -362,7 +362,7 @@ static char *get_reset_cause(char *ret) #ifdef CONFIG_ENV_IS_IN_MMC __weak int board_mmc_get_env_dev(int devno) { - return CONFIG_SYS_MMC_ENV_DEV; + return CONFIG_ENV_MMC_DEVICE_INDEX; } int mmc_get_env_dev(void) @@ -372,7 +372,7 @@ int mmc_get_env_dev(void) /* If not boot from sd/mmc, use default value */ if (get_boot_mode() == LOW_POWER_BOOT) - return CONFIG_SYS_MMC_ENV_DEV; + return CONFIG_ENV_MMC_DEVICE_INDEX; bt1_cfg = readl(CMC1_RBASE + 0x40); devno = (bt1_cfg >> 9) & 0x7; diff --git a/arch/arm/mach-k3/am62ax/am62a7_init.c b/arch/arm/mach-k3/am62ax/am62a7_init.c index edd43a1d78d..00173e6836b 100644 --- a/arch/arm/mach-k3/am62ax/am62a7_init.c +++ b/arch/arm/mach-k3/am62ax/am62a7_init.c @@ -57,7 +57,6 @@ static void ctrl_mmr_unlock(void) mmr_unlock(CTRL_MMR0_BASE, 1); mmr_unlock(CTRL_MMR0_BASE, 2); mmr_unlock(CTRL_MMR0_BASE, 4); - mmr_unlock(CTRL_MMR0_BASE, 5); mmr_unlock(CTRL_MMR0_BASE, 6); /* Unlock all MCU_CTRL_MMR0 module registers */ @@ -172,6 +171,10 @@ void board_init_f(ulong dummy) /* Output System Firmware version info */ k3_sysfw_print_ver(); + /* Output DM Firmware version info */ + if (IS_ENABLED(CONFIG_ARM64)) + k3_dm_print_ver(); + if (IS_ENABLED(CONFIG_ESM_K3)) { /* Probe/configure ESM0 */ ret = uclass_get_device_by_name(UCLASS_MISC, "esm@420000", &dev); diff --git a/arch/arm/mach-k3/am62px/am62p5_init.c b/arch/arm/mach-k3/am62px/am62p5_init.c index 6e3c66e5107..44a2d445d24 100644 --- a/arch/arm/mach-k3/am62px/am62p5_init.c +++ b/arch/arm/mach-k3/am62px/am62p5_init.c @@ -224,6 +224,10 @@ void board_init_f(ulong dummy) /* Output System Firmware version info */ k3_sysfw_print_ver(); + /* Output DM Firmware version info */ + if (IS_ENABLED(CONFIG_ARM64)) + k3_dm_print_ver(); + if (IS_ENABLED(CONFIG_K3_AM62A_DDRSS)) { ret = uclass_get_device(UCLASS_RAM, 0, &dev); if (ret) diff --git a/arch/arm/mach-k3/arm64/arm64-mmu.c b/arch/arm/mach-k3/arm64/arm64-mmu.c index 0e07b1b7ce0..74c855852e9 100644 --- a/arch/arm/mach-k3/arm64/arm64-mmu.c +++ b/arch/arm/mach-k3/arm64/arm64-mmu.c @@ -9,11 +9,19 @@ * */ +#include <linux/sizes.h> #include <asm/system.h> #include <asm/armv8/mmu.h> +#include <mach/k3-ddr.h> +#include <sort.h> -struct mm_region k3_mem_map[] = { +#include "../common_fdt.h" + +DECLARE_GLOBAL_DATA_PTR; + +struct mm_region k3_mem_map[K3_MMU_REGIONS_COUNT] = { { + /* Peripherals */ .virt = 0x0UL, .phys = 0x0UL, .size = 0x80000000UL, @@ -21,24 +29,14 @@ struct mm_region k3_mem_map[] = { PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, { - .virt = 0x80000000UL, - .phys = 0x80000000UL, - .size = 0x1e780000UL, - .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | - PTE_BLOCK_INNER_SHARE - }, { - .virt = 0xa0000000UL, - .phys = 0xa0000000UL, - .size = 0x60000000UL, - .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | - PTE_BLOCK_INNER_SHARE - }, { + /* Higher DDR banks */ .virt = 0x880000000UL, .phys = 0x880000000UL, .size = 0x80000000UL, .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_INNER_SHARE }, { + /* Flash peripherals */ .virt = 0x500000000UL, .phys = 0x500000000UL, .size = 0x380000000UL, @@ -46,9 +44,242 @@ struct mm_region k3_mem_map[] = { PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, { + /* Map SPL load region and the next 128MiB as cacheable */ + .virt = CONFIG_SPL_TEXT_BASE, + .phys = CONFIG_SPL_TEXT_BASE, + .size = SZ_128M, + .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_INNER_SHARE + }, { + /* Framebuffer reserved, size set at runtime */ + .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_INNER_SHARE + }, { /* List terminator */ 0, } }; struct mm_region *mem_map = k3_mem_map; + +int k3_spl_mem_map_init(void) +{ + unsigned int i; + int k3_map_idx = -EINVAL; + + for (i = 0; i < K3_MMU_REGIONS_COUNT; i++) { + if (k3_mem_map[i].virt == 0 && k3_mem_map[i].phys == 0 && + k3_mem_map[i].size == 0) { + k3_map_idx = i; + break; + } + } + + if (k3_map_idx == -EINVAL) { + pr_err("%s: Failed to find fixup region in MMU memory map\n", + __func__); + return -EINVAL; + } + + if (k3_map_idx >= K3_MMU_REGIONS_COUNT - 1) { + pr_err("%s: Not enough space in MMU map for the added entry\n", + __func__); + return -ENOMEM; + } + + if (CONFIG_IS_ENABLED(VIDEO)) { + k3_mem_map[k3_map_idx].virt = gd_video_bottom(); + k3_mem_map[k3_map_idx].phys = gd_video_bottom(); + k3_mem_map[k3_map_idx].size = + gd_video_top() - gd_video_bottom(); + k3_mem_map[k3_map_idx].attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_INNER_SHARE; + k3_map_idx++; + } + + k3_mem_map[k3_map_idx] = (const struct mm_region){ 0 }; + + return 0; +} + +static int dt_reserved_cmp(const void *a, const void *b) +{ + const struct fdt_resource *val_a = a, *val_b = b; + + return (val_a->start - val_b->start); +} + +int k3_mem_map_init(void) +{ + fdt_addr_t mem_base; + fdt_size_t mem_size; + struct fdt_resource dt_reserved[K3_MMU_REGIONS_COUNT], + coalesced[K3_MMU_REGIONS_COUNT]; + int k3_map_idx = -EINVAL, ret, nodeoffset, subnode; + void *blob = (void *)gd->fdt_blob; + unsigned int carveout_len, i, j; + + ret = fdt_fixup_reserved(blob, "tfa", CONFIG_K3_ATF_LOAD_ADDR, 0x80000); + if (ret) { + pr_err("%s: Failed to fixup reserved node for tfa [%d]\n", + __func__, ret); + return ret; + } + + ret = fdt_fixup_reserved(blob, "optee", CONFIG_K3_OPTEE_LOAD_ADDR, + 0x1800000); + if (ret) { + pr_err("%s: Failed to fixup reserved node for optee [%d]\n", + __func__, ret); + return ret; + } + + nodeoffset = fdt_subnode_offset(blob, 0, "memory"); + if (nodeoffset < 0) { + pr_err("%s: Failed to get memory data: %s\n", __func__, + fdt_strerror(nodeoffset)); + return nodeoffset; + } + + mem_base = fdtdec_get_addr_size(blob, nodeoffset, "reg", &mem_size); + if (mem_base != CFG_SYS_SDRAM_BASE) + return -EINVAL; + + for (i = 0; i < K3_MMU_REGIONS_COUNT; i++) { + if (k3_mem_map[i].virt == CONFIG_SPL_TEXT_BASE) { + k3_map_idx = i; + break; + } + } + + if (k3_map_idx == -EINVAL) { + pr_err("%s: Failed to find DDR region in MMU memory map\n", + __func__); + return -EINVAL; + } + + i = 0; + nodeoffset = fdt_subnode_offset(blob, 0, "reserved-memory"); + fdt_for_each_subnode(subnode, blob, nodeoffset) { + const char *name; + fdt_addr_t addr, end_addr; + fdt_size_t size; + + if (i >= K3_MMU_REGIONS_COUNT) { + /* + * This is a recoverable error if the regions can be + * coalesced, the required logic can be implemented once + * requirement arises. + */ + pr_err("%s: Not enough space in MMU map for carveouts\n", + __func__); + return -ENOMEM; + } + + name = fdt_get_name(blob, subnode, NULL); + addr = fdtdec_get_addr_size(blob, subnode, "reg", &size); + + if (addr == FDT_ADDR_T_NONE) + continue; + + if (!fdtdec_get_bool(blob, subnode, "no-map")) + continue; + + if (addr >= mem_base + mem_size) + continue; + + end_addr = addr + size; + + if (end_addr <= mem_base) + continue; + + debug("Added memory carveout at 0x%llx, size: 0x%llx for '%s'\n", + addr, size, name); + + addr = max(addr, mem_base); + end_addr = min(end_addr, mem_base + mem_size); + size = end_addr - addr; + dt_reserved[i].start = addr; + dt_reserved[i].end = end_addr; + i++; + } + carveout_len = i; + + if (!carveout_len) + return 0; + + /* sort carveout regions by address required for creating carveouts */ + qsort(dt_reserved, carveout_len, sizeof(dt_reserved[0]), + dt_reserved_cmp); + + /* coalesce regions */ + struct fdt_resource coalescing_temp = dt_reserved[0]; + + j = 0; + for (i = 1; i < carveout_len; i++) { + struct fdt_resource current = dt_reserved[i]; + + if (coalescing_temp.end >= current.start) { + coalescing_temp.end = current.end; + continue; + } + coalesced[j] = coalescing_temp; + coalescing_temp = current; + j++; + } + + coalesced[j] = coalescing_temp; + carveout_len = j + 1; + + if (coalesced[0].start != mem_base) { + k3_mem_map[k3_map_idx].virt = mem_base; + k3_mem_map[k3_map_idx].phys = mem_base; + k3_mem_map[k3_map_idx].size = coalesced[0].start - mem_base; + k3_mem_map[k3_map_idx].attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_INNER_SHARE; + k3_map_idx++; + } + + for (i = 1; i < carveout_len; i++) { + k3_mem_map[k3_map_idx].virt = coalesced[i - 1].end; + k3_mem_map[k3_map_idx].phys = coalesced[i - 1].end; + k3_mem_map[k3_map_idx].size = + coalesced[i].start - coalesced[i - 1].end; + k3_mem_map[k3_map_idx].attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_INNER_SHARE; + k3_map_idx++; + } + + k3_mem_map[k3_map_idx].virt = coalesced[carveout_len - 1].end; + k3_mem_map[k3_map_idx].phys = coalesced[carveout_len - 1].end; + k3_mem_map[k3_map_idx].size = + mem_base + mem_size - coalesced[carveout_len - 1].end; + k3_mem_map[k3_map_idx].attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_INNER_SHARE; + k3_map_idx++; + + /* map reserved memory as non cachable */ + for (i = 0; i < carveout_len; i++) { + k3_mem_map[k3_map_idx].virt = coalesced[i].start; + k3_mem_map[k3_map_idx].phys = coalesced[i].start; + k3_mem_map[k3_map_idx].size = + coalesced[i].end - coalesced[i].start; + k3_mem_map[k3_map_idx].attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL_NC) | + PTE_BLOCK_INNER_SHARE; + k3_map_idx++; + } + + debug("%s: MMU Table configured as:\n", __func__); + debug(" |virt start\t\t|virt end\t|phys\t\t|size\t\t|attrs:\n"); + for (i = 0; i < k3_map_idx; i++) { + debug("%2d: 0x%-12llx\t0x%-12llx\t0x%-12llx\t0x%-12llx\t0x%llx\n", + i, k3_mem_map[i].virt, + k3_mem_map[i].virt + k3_mem_map[i].size, + k3_mem_map[i].phys, k3_mem_map[i].size, + k3_mem_map[i].attrs); + } + + k3_mem_map[k3_map_idx] = (const struct mm_region){ 0 }; + + return 0; +} diff --git a/arch/arm/mach-k3/common.c b/arch/arm/mach-k3/common.c index 0323001d6d3..723076ee874 100644 --- a/arch/arm/mach-k3/common.c +++ b/arch/arm/mach-k3/common.c @@ -15,6 +15,7 @@ #include <asm/global_data.h> #include <linux/printk.h> #include "common.h" +#include "mach/k3-ddr.h" #include <dm.h> #include <remoteproc.h> #include <asm/cache.h> @@ -31,6 +32,11 @@ #include <dm/uclass-internal.h> #include <dm/device-internal.h> +#define PROC_BOOT_CTRL_FLAG_R5_CORE_HALT 0x00000001 +#define PROC_BOOT_STATUS_FLAG_R5_WFI 0x00000002 +#define PROC_ID_MCU_R5FSS0_CORE1 0x02 +#define PROC_BOOT_CFG_FLAG_R5_LOCKSTEP 0x00000100 + #include <asm/arch/k3-qos.h> struct ti_sci_handle *get_ti_sci_handle(void) @@ -68,6 +74,35 @@ void k3_sysfw_print_ver(void) ti_sci->version.firmware_revision, fw_desc); } +void __maybe_unused k3_dm_print_ver(void) +{ + struct ti_sci_handle *ti_sci = get_ti_sci_handle(); + struct ti_sci_firmware_ops *fw_ops = &ti_sci->ops.fw_ops; + struct ti_sci_dm_version_info dm_info = {0}; + u64 fw_caps; + int ret; + + ret = fw_ops->query_dm_cap(ti_sci, &fw_caps); + if (ret) { + printf("Failed to query DM firmware capability %d\n", ret); + return; + } + + if (!(fw_caps & TI_SCI_MSG_FLAG_FW_CAP_DM)) + return; + + ret = fw_ops->get_dm_version(ti_sci, &dm_info); + if (ret) { + printf("Failed to fetch DM firmware version %d\n", ret); + return; + } + + printf("DM ABI: %d.%d (firmware ver 0x%04x '%s--%s' " + "patch_ver: %d)\n", dm_info.abi_major, dm_info.abi_minor, + dm_info.dm_ver, dm_info.sci_server_version, + dm_info.rm_pm_hal_version, dm_info.patch_ver); +} + void mmr_unlock(uintptr_t base, u32 partition) { /* Translate the base address */ @@ -234,9 +269,6 @@ void spl_enable_cache(void) dram_init(); - /* reserve TLB table */ - gd->arch.tlb_size = PGTABLE_SIZE; - gd->ram_top += get_effective_memsize(); gd->relocaddr = gd->ram_top; @@ -244,6 +276,15 @@ void spl_enable_cache(void) if (ret) panic("Failed to reserve framebuffer memory (%d)\n", ret); + if (IS_ENABLED(CONFIG_ARM64)) { + ret = k3_spl_mem_map_init(); + if (ret) + panic("Failed to perform MMU fixups: %d\n", ret); + } + + /* reserve TLB table */ + gd->arch.tlb_size = PGTABLE_SIZE; + gd->arch.tlb_addr = gd->relocaddr - gd->arch.tlb_size; gd->arch.tlb_addr &= ~(0x10000 - 1); debug("TLB table from %08lx to %08lx\n", gd->arch.tlb_addr, @@ -338,3 +379,67 @@ void setup_qos(void) writel(qos_data[i].val, (uintptr_t)qos_data[i].reg); } #endif + +int __maybe_unused shutdown_mcu_r5_core1(void) +{ + struct ti_sci_handle *ti_sci = get_ti_sci_handle(); + struct ti_sci_dev_ops *dev_ops = &ti_sci->ops.dev_ops; + struct ti_sci_proc_ops *proc_ops = &ti_sci->ops.proc_ops; + u32 dev_id_mcu_r5_core1 = put_core_ids[0]; + u64 boot_vector; + u32 cfg, ctrl, sts, halted; + int cluster_mode_lockstep, ret; + bool r_state = false, c_state = false; + + ret = proc_ops->proc_request(ti_sci, PROC_ID_MCU_R5FSS0_CORE1); + if (ret) { + printf("Unable to request processor control for MCU1_1 core, %d\n", + ret); + return ret; + } + + ret = dev_ops->is_on(ti_sci, dev_id_mcu_r5_core1, &r_state, &c_state); + if (ret) { + printf("Unable to get device status for MCU1_1 core, %d\n", ret); + return ret; + } + + ret = proc_ops->get_proc_boot_status(ti_sci, PROC_ID_MCU_R5FSS0_CORE1, + &boot_vector, &cfg, &ctrl, &sts); + if (ret) { + printf("Unable to get Processor boot status for MCU1_1 core, %d\n", + ret); + goto release_proc_ctrl; + } + + halted = !!(sts & PROC_BOOT_STATUS_FLAG_R5_WFI); + cluster_mode_lockstep = !!(cfg & PROC_BOOT_CFG_FLAG_R5_LOCKSTEP); + + /* + * Shutdown MCU R5F Core 1 only if: + * - cluster is booted in SplitMode + * - core is powered on + * - core is in WFI (halted) + */ + if (cluster_mode_lockstep || !c_state || !halted) { + ret = -EINVAL; + goto release_proc_ctrl; + } + + ret = proc_ops->set_proc_boot_ctrl(ti_sci, PROC_ID_MCU_R5FSS0_CORE1, + PROC_BOOT_CTRL_FLAG_R5_CORE_HALT, 0); + if (ret) { + printf("Unable to Halt MCU1_1 core, %d\n", ret); + goto release_proc_ctrl; + } + + ret = dev_ops->put_device(ti_sci, dev_id_mcu_r5_core1); + if (ret) { + printf("Unable to assert reset on MCU1_1 core, %d\n", ret); + return ret; + } + +release_proc_ctrl: + proc_ops->proc_release(ti_sci, PROC_ID_MCU_R5FSS0_CORE1); + return ret; +} diff --git a/arch/arm/mach-k3/common.h b/arch/arm/mach-k3/common.h index 02c74731fea..52d3faaab5c 100644 --- a/arch/arm/mach-k3/common.h +++ b/arch/arm/mach-k3/common.h @@ -42,6 +42,7 @@ int remove_fwl_region(struct fwl_data *fwl); void remove_fwl_configs(struct fwl_data *fwl_data, size_t fwl_data_size); int load_firmware(char *name_fw, char *name_loadaddr, u32 *loadaddr); void k3_sysfw_print_ver(void); +void k3_dm_print_ver(void); void spl_enable_cache(void); void mmr_unlock(uintptr_t base, u32 partition); bool is_rom_loaded_sysfw(struct rom_extended_boot_data *data); @@ -49,6 +50,7 @@ enum k3_device_type get_device_type(void); struct ti_sci_handle *get_ti_sci_handle(void); void do_board_detect(void); void ti_secure_image_check_binary(void **p_image, size_t *p_size); +int shutdown_mcu_r5_core1(void); #if (IS_ENABLED(CONFIG_K3_QOS)) void setup_qos(void); diff --git a/arch/arm/mach-k3/include/mach/am62_hardware.h b/arch/arm/mach-k3/include/mach/am62_hardware.h index c33362696c4..2f5655bf24a 100644 --- a/arch/arm/mach-k3/include/mach/am62_hardware.h +++ b/arch/arm/mach-k3/include/mach/am62_hardware.h @@ -177,8 +177,8 @@ static inline int k3_has_gpu(void) static const u32 put_device_ids[] = {}; -static const u32 put_core_ids[] = {}; - #endif +static const u32 put_core_ids[] = {}; + #endif /* __ASM_ARCH_AM62_HARDWARE_H */ diff --git a/arch/arm/mach-k3/include/mach/am62a_hardware.h b/arch/arm/mach-k3/include/mach/am62a_hardware.h index cd61abe0185..f3fd736f31b 100644 --- a/arch/arm/mach-k3/include/mach/am62a_hardware.h +++ b/arch/arm/mach-k3/include/mach/am62a_hardware.h @@ -90,8 +90,8 @@ static const u32 put_device_ids[] = {}; -static const u32 put_core_ids[] = {}; - #endif +static const u32 put_core_ids[] = {}; + #endif /* __ASM_ARCH_AM62A_HARDWARE_H */ diff --git a/arch/arm/mach-k3/include/mach/am62p_hardware.h b/arch/arm/mach-k3/include/mach/am62p_hardware.h index 95af5c5c547..a310b52b45d 100644 --- a/arch/arm/mach-k3/include/mach/am62p_hardware.h +++ b/arch/arm/mach-k3/include/mach/am62p_hardware.h @@ -141,8 +141,8 @@ static inline int k3_get_a53_max_frequency(void) static const u32 put_device_ids[] = {}; -static const u32 put_core_ids[] = {}; - #endif +static const u32 put_core_ids[] = {}; + #endif /* __ASM_ARCH_AM62P_HARDWARE_H */ diff --git a/arch/arm/mach-k3/include/mach/am64_hardware.h b/arch/arm/mach-k3/include/mach/am64_hardware.h index 44df887d5df..105b42986de 100644 --- a/arch/arm/mach-k3/include/mach/am64_hardware.h +++ b/arch/arm/mach-k3/include/mach/am64_hardware.h @@ -50,19 +50,20 @@ #define AM64X_DEV_RTI8 127 #define AM64X_DEV_RTI9 128 -#define AM64X_DEV_R5FSS0_CORE0 121 -#define AM64X_DEV_R5FSS0_CORE1 122 static const u32 put_device_ids[] = { AM64X_DEV_RTI9, AM64X_DEV_RTI8, }; +#endif + +#define AM64X_DEV_R5FSS0_CORE0 121 +#define AM64X_DEV_R5FSS0_CORE1 122 + static const u32 put_core_ids[] = { AM64X_DEV_R5FSS0_CORE1, AM64X_DEV_R5FSS0_CORE0, /* Handle CPU0 after CPU1 */ }; -#endif - #endif /* __ASM_ARCH_DRA8_HARDWARE_H */ diff --git a/arch/arm/mach-k3/include/mach/am6_hardware.h b/arch/arm/mach-k3/include/mach/am6_hardware.h index 9913964c46b..8169584a372 100644 --- a/arch/arm/mach-k3/include/mach/am6_hardware.h +++ b/arch/arm/mach-k3/include/mach/am6_hardware.h @@ -43,19 +43,20 @@ #define AM6_DEV_MCU_RTI0 134 #define AM6_DEV_MCU_RTI1 135 -#define AM6_DEV_MCU_ARMSS0_CPU0 159 -#define AM6_DEV_MCU_ARMSS0_CPU1 245 static const u32 put_device_ids[] = { AM6_DEV_MCU_RTI0, AM6_DEV_MCU_RTI1, }; +#endif + +#define AM6_DEV_MCU_ARMSS0_CPU0 159 +#define AM6_DEV_MCU_ARMSS0_CPU1 245 + static const u32 put_core_ids[] = { AM6_DEV_MCU_ARMSS0_CPU1, AM6_DEV_MCU_ARMSS0_CPU0, /* Handle CPU0 after CPU1 */ }; -#endif - #endif /* __ASM_ARCH_AM6_HARDWARE_H */ diff --git a/arch/arm/mach-k3/include/mach/j721e_hardware.h b/arch/arm/mach-k3/include/mach/j721e_hardware.h index 2b5ec771e18..5bef309af0a 100644 --- a/arch/arm/mach-k3/include/mach/j721e_hardware.h +++ b/arch/arm/mach-k3/include/mach/j721e_hardware.h @@ -41,19 +41,20 @@ #define J721E_DEV_MCU_RTI0 262 #define J721E_DEV_MCU_RTI1 263 -#define J721E_DEV_MCU_ARMSS0_CPU0 250 -#define J721E_DEV_MCU_ARMSS0_CPU1 251 static const u32 put_device_ids[] = { J721E_DEV_MCU_RTI0, J721E_DEV_MCU_RTI1, }; +#endif + +#define J721E_DEV_MCU_ARMSS0_CPU0 250 +#define J721E_DEV_MCU_ARMSS0_CPU1 251 + static const u32 put_core_ids[] = { J721E_DEV_MCU_ARMSS0_CPU1, J721E_DEV_MCU_ARMSS0_CPU0, /* Handle CPU0 after CPU1 */ }; -#endif - #endif /* __ASM_ARCH_J721E_HARDWARE_H */ diff --git a/arch/arm/mach-k3/include/mach/j721s2_hardware.h b/arch/arm/mach-k3/include/mach/j721s2_hardware.h index 8daea82a77e..82f076a45e0 100644 --- a/arch/arm/mach-k3/include/mach/j721s2_hardware.h +++ b/arch/arm/mach-k3/include/mach/j721s2_hardware.h @@ -41,19 +41,20 @@ #define J721S2_DEV_MCU_RTI0 295 #define J721S2_DEV_MCU_RTI1 296 -#define J721S2_DEV_MCU_ARMSS0_CPU0 284 -#define J721S2_DEV_MCU_ARMSS0_CPU1 285 static const u32 put_device_ids[] = { J721S2_DEV_MCU_RTI0, J721S2_DEV_MCU_RTI1, }; +#endif + +#define J721S2_DEV_MCU_ARMSS0_CPU0 284 +#define J721S2_DEV_MCU_ARMSS0_CPU1 285 + static const u32 put_core_ids[] = { J721S2_DEV_MCU_ARMSS0_CPU1, J721S2_DEV_MCU_ARMSS0_CPU0, /* Handle CPU0 after CPU1 */ }; -#endif - #endif /* __ASM_ARCH_J721S2_HARDWARE_H */ diff --git a/arch/arm/mach-k3/include/mach/j722s_hardware.h b/arch/arm/mach-k3/include/mach/j722s_hardware.h index 8d0bec22068..0c695134c28 100644 --- a/arch/arm/mach-k3/include/mach/j722s_hardware.h +++ b/arch/arm/mach-k3/include/mach/j722s_hardware.h @@ -76,8 +76,8 @@ static const u32 put_device_ids[] = {}; -static const u32 put_core_ids[] = {}; - #endif +static const u32 put_core_ids[] = {}; + #endif /* __ASM_ARCH_J722S_HARDWARE_H */ diff --git a/arch/arm/mach-k3/include/mach/j784s4_hardware.h b/arch/arm/mach-k3/include/mach/j784s4_hardware.h index 0ffe238cdae..29a894baed3 100644 --- a/arch/arm/mach-k3/include/mach/j784s4_hardware.h +++ b/arch/arm/mach-k3/include/mach/j784s4_hardware.h @@ -41,19 +41,20 @@ #define J784S4_DEV_MCU_RTI0 367 #define J784S4_DEV_MCU_RTI1 368 -#define J784S4_DEV_MCU_ARMSS0_CPU0 346 -#define J784S4_DEV_MCU_ARMSS0_CPU1 347 static const u32 put_device_ids[] = { J784S4_DEV_MCU_RTI0, J784S4_DEV_MCU_RTI1, }; +#endif + +#define J784S4_DEV_MCU_ARMSS0_CPU0 346 +#define J784S4_DEV_MCU_ARMSS0_CPU1 347 + static const u32 put_core_ids[] = { J784S4_DEV_MCU_ARMSS0_CPU1, J784S4_DEV_MCU_ARMSS0_CPU0, /* Handle CPU0 after CPU1 */ }; -#endif - #endif /* __ASM_ARCH_J784S4_HARDWARE_H */ diff --git a/arch/arm/mach-k3/include/mach/k3-ddr.h b/arch/arm/mach-k3/include/mach/k3-ddr.h index 39e6725bb9b..375a1a85945 100644 --- a/arch/arm/mach-k3/include/mach/k3-ddr.h +++ b/arch/arm/mach-k3/include/mach/k3-ddr.h @@ -8,10 +8,22 @@ #include <spl.h> +/* Number of mappable regions in the MMU page table */ +#define K3_MMU_REGIONS_COUNT 32 + int dram_init(void); int dram_init_banksize(void); void fixup_ddr_driver_for_ecc(struct spl_image_info *spl_image); void fixup_memory_node(struct spl_image_info *spl_image); +/* Performs MMU memory map fixups at SPL stage */ +int k3_spl_mem_map_init(void); + +/* + * Modifies the MMU memory map based on DDR size and reserved-memory + * nodes in DT + */ +int k3_mem_map_init(void); + #endif /* _K3_DDR_H_ */ diff --git a/arch/arm/mach-k3/j721e/j721e_init.c b/arch/arm/mach-k3/j721e/j721e_init.c index f31c20f7ed6..f9af0288cf6 100644 --- a/arch/arm/mach-k3/j721e/j721e_init.c +++ b/arch/arm/mach-k3/j721e/j721e_init.c @@ -296,9 +296,9 @@ void do_dt_magic(void) void board_init_f(ulong dummy) { + int ret; #if defined(CONFIG_K3_J721E_DDRSS) || defined(CONFIG_K3_LOAD_SYSFW) struct udevice *dev; - int ret; #endif /* * Cannot delay this further as there is a chance that @@ -371,9 +371,20 @@ void board_init_f(ulong dummy) preloader_console_init(); #endif + /* Shutdown MCU_R5 Core 1 in Split mode at A72 SPL Stage */ + if (IS_ENABLED(CONFIG_ARM64)) { + ret = shutdown_mcu_r5_core1(); + if (ret) + printf("Unable to shutdown MCU R5 core 1, %d\n", ret); + } + /* Output System Firmware version info */ k3_sysfw_print_ver(); + /* Output DM Firmware version info */ + if (IS_ENABLED(CONFIG_ARM64)) + k3_dm_print_ver(); + /* Perform board detection */ do_board_detect(); diff --git a/arch/arm/mach-k3/j721s2/j721s2_init.c b/arch/arm/mach-k3/j721s2/j721s2_init.c index 5941fa26a95..eee3d0440ac 100644 --- a/arch/arm/mach-k3/j721s2/j721s2_init.c +++ b/arch/arm/mach-k3/j721s2/j721s2_init.c @@ -230,8 +230,19 @@ void k3_spl_init(void) remove_fwl_configs(navss_cbass0_fwls, ARRAY_SIZE(navss_cbass0_fwls)); } + /* Shutdown MCU_R5 Core 1 in Split mode at A72 SPL Stage */ + if (IS_ENABLED(CONFIG_ARM64)) { + ret = shutdown_mcu_r5_core1(); + if (ret) + printf("Unable to shutdown MCU R5 core 1, %d\n", ret); + } + /* Output System Firmware version info */ k3_sysfw_print_ver(); + + /* Output DM Firmware version info */ + if (IS_ENABLED(CONFIG_ARM64)) + k3_dm_print_ver(); } bool check_rom_loaded_sysfw(void) diff --git a/arch/arm/mach-k3/j722s/j722s_init.c b/arch/arm/mach-k3/j722s/j722s_init.c index af211377e7c..1180c75f551 100644 --- a/arch/arm/mach-k3/j722s/j722s_init.c +++ b/arch/arm/mach-k3/j722s/j722s_init.c @@ -150,6 +150,10 @@ static void k3_spl_init(void) /* Output System Firmware version info */ k3_sysfw_print_ver(); + + /* Output DM Firmware version info */ + if (IS_ENABLED(CONFIG_ARM64)) + k3_dm_print_ver(); } static void k3_mem_init(void) @@ -162,6 +166,8 @@ static void k3_mem_init(void) if (ret) panic("DRAM init failed: %d\n", ret); } + + spl_enable_cache(); } static __maybe_unused void enable_mcu_esm_reset(void) diff --git a/arch/arm/mach-k3/j784s4/j784s4_init.c b/arch/arm/mach-k3/j784s4/j784s4_init.c index 4e9f823072b..0f11511bda0 100644 --- a/arch/arm/mach-k3/j784s4/j784s4_init.c +++ b/arch/arm/mach-k3/j784s4/j784s4_init.c @@ -206,8 +206,19 @@ void k3_spl_init(void) writel(AUDIO_REFCLK1_DEFAULT, (uintptr_t)CTRL_MMR_CFG0_AUDIO_REFCLK1_CTRL); + /* Shutdown MCU_R5 Core 1 in Split mode at A72 SPL Stage */ + if (IS_ENABLED(CONFIG_ARM64)) { + ret = shutdown_mcu_r5_core1(); + if (ret) + printf("Unable to shutdown MCU R5 core 1, %d\n", ret); + } + /* Output System Firmware version info */ k3_sysfw_print_ver(); + + /* Output DM Firmware version info */ + if (IS_ENABLED(CONFIG_ARM64)) + k3_dm_print_ver(); } void k3_mem_init(void) diff --git a/arch/arm/mach-mediatek/tzcfg.c b/arch/arm/mach-mediatek/tzcfg.c index 71982ba4d20..c8fe8ac0e9b 100644 --- a/arch/arm/mach-mediatek/tzcfg.c +++ b/arch/arm/mach-mediatek/tzcfg.c @@ -173,6 +173,7 @@ phys_addr_t board_get_usable_ram_top(phys_size_t total_size) int arch_misc_init(void) { + phys_addr_t addr; struct arm_smccc_res res; /* @@ -180,11 +181,14 @@ int arch_misc_init(void) * there's no need to check the result */ arm_smccc_smc(MTK_SIP_GET_BL31_REGION, 0, 0, 0, 0, 0, 0, 0, &res); - lmb_reserve(res.a1, res.a2, LMB_NOMAP); + addr = (phys_addr_t)res.a1; + lmb_alloc_mem(LMB_MEM_ALLOC_ADDR, 0, &addr, res.a2, LMB_NOMAP); arm_smccc_smc(MTK_SIP_GET_BL32_REGION, 0, 0, 0, 0, 0, 0, 0, &res); + addr = (phys_addr_t)res.a1; if (!res.a0 && res.a1 && res.a2) - lmb_reserve(res.a1, res.a2, LMB_NOMAP); + lmb_alloc_mem(LMB_MEM_ALLOC_ADDR, 0, &addr, res.a2, + LMB_NOMAP); #if IS_ENABLED(CONFIG_CMD_PSTORE) char cmd[64]; diff --git a/arch/arm/mach-mvebu/armada8k/cpu.c b/arch/arm/mach-mvebu/armada8k/cpu.c index 7908f75809c..3eb93c82387 100644 --- a/arch/arm/mach-mvebu/armada8k/cpu.c +++ b/arch/arm/mach-mvebu/armada8k/cpu.c @@ -109,5 +109,5 @@ int mmc_get_env_dev(void) return 1; } - return CONFIG_SYS_MMC_ENV_DEV; + return CONFIG_ENV_MMC_DEVICE_INDEX; } diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig index d3ed870b169..342933ca509 100644 --- a/arch/arm/mach-rockchip/Kconfig +++ b/arch/arm/mach-rockchip/Kconfig @@ -362,7 +362,7 @@ config ROCKCHIP_RK3528 imply SPL_REGMAP imply SPL_SERIAL imply SPL_SYSCON - imply SYS_RELOC_GD_ENV_ADDR + imply ENV_RELOC_GD_ENV_ADDR imply SYSRESET imply SYSRESET_PSCI if SPL_ATF help @@ -446,7 +446,7 @@ config ROCKCHIP_RK3576 imply SPL_REGMAP imply SPL_SERIAL imply SPL_SYSCON - imply SYS_RELOC_GD_ENV_ADDR + imply ENV_RELOC_GD_ENV_ADDR imply SYSRESET help The Rockchip RK3576 is a ARM-based SoC with quad-core Cortex-A72 and diff --git a/arch/arm/mach-rockchip/board.c b/arch/arm/mach-rockchip/board.c index 75d6693e28a..2e6bb38b923 100644 --- a/arch/arm/mach-rockchip/board.c +++ b/arch/arm/mach-rockchip/board.c @@ -512,8 +512,8 @@ int mmc_get_env_dev(void) const char *boot_device; struct udevice *dev; -#ifdef CONFIG_SYS_MMC_ENV_DEV - devnum = CONFIG_SYS_MMC_ENV_DEV; +#ifdef CONFIG_ENV_MMC_DEVICE_INDEX + devnum = CONFIG_ENV_MMC_DEVICE_INDEX; #else devnum = 0; #endif diff --git a/arch/arm/mach-snapdragon/board.c b/arch/arm/mach-snapdragon/board.c index 5547d6d054f..ec51ebbbe7f 100644 --- a/arch/arm/mach-snapdragon/board.c +++ b/arch/arm/mach-snapdragon/board.c @@ -37,6 +37,8 @@ DECLARE_GLOBAL_DATA_PTR; +enum qcom_boot_source qcom_boot_source __section(".data") = 0; + static struct mm_region rbx_mem_map[CONFIG_NR_DRAM_BANKS + 2] = { { 0 } }; struct mm_region *mem_map = rbx_mem_map; @@ -238,6 +240,12 @@ int board_fdt_blob_setup(void **fdtp) if (ret < 0) panic("No valid memory ranges found!\n"); + /* If we have an external FDT, it can only have come from the Android bootloader. */ + if (external_valid) + qcom_boot_source = QCOM_BOOT_SOURCE_ANDROID; + else + qcom_boot_source = QCOM_BOOT_SOURCE_XBL; + debug("ram_base = %#011lx, ram_size = %#011llx\n", gd->ram_base, gd->ram_size); @@ -481,6 +489,23 @@ static void configure_env(void) qcom_set_serialno(); } +void qcom_show_boot_source(void) +{ + const char *name = "UNKNOWN"; + + switch (qcom_boot_source) { + case QCOM_BOOT_SOURCE_ANDROID: + name = "ABL"; + break; + case QCOM_BOOT_SOURCE_XBL: + name = "XBL"; + break; + } + + log_info("U-Boot loaded from %s\n", name); + env_set("boot_source", name); +} + void __weak qcom_late_init(void) { } @@ -492,38 +517,56 @@ void __weak qcom_late_init(void) #define FASTBOOT_BUF_SIZE 0 #endif -#define addr_alloc(size) lmb_alloc(size, SZ_2M) +#define lmb_alloc(size, addr) lmb_alloc_mem(LMB_MEM_ALLOC_ANY, SZ_2M, addr, size, LMB_NONE) /* Stolen from arch/arm/mach-apple/board.c */ int board_late_init(void) { - u32 status = 0; + u32 status = 0, fdt_status = 0; phys_addr_t addr; struct fdt_header *fdt_blob = (struct fdt_header *)gd->fdt_blob; /* We need to be fairly conservative here as we support boards with just 1G of TOTAL RAM */ - addr = addr_alloc(SZ_128M); + status |= !lmb_alloc(SZ_128M, &addr) ? + env_set_hex("loadaddr", addr) : 1; status |= env_set_hex("kernel_addr_r", addr); - status |= env_set_hex("loadaddr", addr); - status |= env_set_hex("ramdisk_addr_r", addr_alloc(SZ_128M)); - status |= env_set_hex("kernel_comp_addr_r", addr_alloc(KERNEL_COMP_SIZE)); - status |= env_set_hex("kernel_comp_size", KERNEL_COMP_SIZE); - if (IS_ENABLED(CONFIG_FASTBOOT)) - status |= env_set_hex("fastboot_addr_r", addr_alloc(FASTBOOT_BUF_SIZE)); - status |= env_set_hex("scriptaddr", addr_alloc(SZ_4M)); - status |= env_set_hex("pxefile_addr_r", addr_alloc(SZ_4M)); - addr = addr_alloc(SZ_2M); - status |= env_set_hex("fdt_addr_r", addr); - - if (status) + status |= !lmb_alloc(SZ_128M, &addr) ? + env_set_hex("ramdisk_addr_r", addr) : 1; + status |= !lmb_alloc(KERNEL_COMP_SIZE, &addr) ? + env_set_hex("kernel_comp_addr_r", addr) : 1; + status |= !lmb_alloc(KERNEL_COMP_SIZE, &addr) ? + env_set_hex("kernel_comp_size", addr) : 1; + status |= !lmb_alloc(SZ_4M, &addr) ? + env_set_hex("scriptaddr", addr) : 1; + status |= !lmb_alloc(SZ_4M, &addr) ? + env_set_hex("pxefile_addr_r", addr) : 1; + + if (IS_ENABLED(CONFIG_FASTBOOT)) { + status |= !lmb_alloc(FASTBOOT_BUF_SIZE, &addr) ? + env_set_hex("fastboot_addr_r", addr) : 1; + /* override loadaddr for memory rich soc */ + status |= !lmb_alloc(SZ_128M, &addr) ? + env_set_hex("loadaddr", addr) : 1; + } + + fdt_status |= !lmb_alloc(SZ_2M, &addr) ? + env_set_hex("fdt_addr_r", addr) : 1; + + if (status || fdt_status) log_warning("%s: Failed to set run time variables\n", __func__); /* By default copy U-Boots FDT, it will be used as a fallback */ - memcpy((void *)addr, (void *)gd->fdt_blob, fdt32_to_cpu(fdt_blob->totalsize)); + if (fdt_status) + log_warning("%s: Failed to reserve memory for copying FDT\n", + __func__); + else + memcpy((void *)addr, (void *)gd->fdt_blob, + fdt32_to_cpu(fdt_blob->totalsize)); configure_env(); qcom_late_init(); + qcom_show_boot_source(); /* Configure the dfu_string for capsule updates */ qcom_configure_capsule_updates(); diff --git a/arch/arm/mach-snapdragon/capsule_update.c b/arch/arm/mach-snapdragon/capsule_update.c index bf75a9a1b24..4dced4961b6 100644 --- a/arch/arm/mach-snapdragon/capsule_update.c +++ b/arch/arm/mach-snapdragon/capsule_update.c @@ -20,22 +20,19 @@ #include "qcom-priv.h" /* - * NOTE: for now this implementation only supports the rb3gen2. Supporting other - * boards that boot in different ways (e.g. chainloaded from ABL) will require - * additional complexity to properly create the dfu string and fw_images array. - */ - -/* - * To handle different variants like chainloaded U-Boot here we'll need to - * build the fw_images array dynamically at runtime. It looks like - * mach-rockchip is a good example for how to do this. - * Detecting which image types a board uses is TBD, hence for now we only - * support the one new board that runs U-Boot as its primary bootloader. + * To handle different variants like chainloaded U-Boot here we need to + * build the fw_images array dynamically at runtime. These are the possible + * implementations: + * + * - Devices with U-Boot on the uefi_a/b partition + * - Devices with U-Boot on the boot (a/b) partition + * - Devices with U-Boot on the xbl (a/b) partition + * + * Which partition actually has U-Boot on it is determined based on the + * qcom_boot_source variable and additional logic in find_target_partition(). */ struct efi_fw_image fw_images[] = { { - /* U-Boot flashed to the uefi_X partition (e.g. rb3gen2) */ - .fw_name = u"UBOOT_UEFI_PARTITION", .image_index = 1, }, }; @@ -47,6 +44,12 @@ struct efi_capsule_update_info update_info = { .images = fw_images, }; +enum target_part_type { + TARGET_PART_UEFI = 1, + TARGET_PART_XBL, + TARGET_PART_BOOT, +}; + /* LSB first */ struct part_slot_status { u16: 2; @@ -57,35 +60,202 @@ struct part_slot_status { u16 tries_remaining : 4; }; -static int find_boot_partition(const char *partname, struct blk_desc *blk_dev, char *name) +enum ab_slot { + SLOT_NONE, + SLOT_A, + SLOT_B, +}; + +static enum ab_slot get_part_slot(const char *partname) +{ + int len = strlen(partname); + + if (partname[len - 2] != '_') + return SLOT_NONE; + if (partname[len - 1] == 'a') + return SLOT_A; + if (partname[len - 1] == 'b') + return SLOT_B; + + return SLOT_NONE; +} + +/* + * Determine which partition U-Boot is flashed to based on the boot source (ABL/XBL), + * the slot status, and prioritizing the uefi partition over xbl if found. + */ +static int find_target_partition(int *devnum, enum uclass_id *uclass, + enum target_part_type *target_part_type) { int ret; - int partnum; + int partnum, uefi_partnum = -1, xbl_partnum = -1; struct disk_partition info; struct part_slot_status *slot_status; + struct udevice *dev = NULL; + struct blk_desc *desc = NULL, *xbl_desc = NULL; + uchar ptn_name[32] = { 0 }; + bool have_ufs = false; + + /* + * Check to see if we have UFS storage, if so U-Boot MUST be on it and we can skip + * all non-UFS block devices + */ + uclass_foreach_dev_probe(UCLASS_UFS, dev) { + have_ufs = true; + break; + } - for (partnum = 1;; partnum++) { - ret = part_get_info(blk_dev, partnum, &info); - if (ret) - return ret; + uclass_foreach_dev_probe(UCLASS_BLK, dev) { + if (device_get_uclass_id(dev) != UCLASS_BLK) + continue; - slot_status = (struct part_slot_status *)&info.type_flags; - log_io("%16s: Active: %1d, Successful: %1d, Unbootable: %1d, Tries left: %1d\n", - info.name, slot_status->active, - slot_status->successful, slot_status->unbootable, - slot_status->tries_remaining); + /* If we have a UFS then don't look at any other block devices */ + if (have_ufs) { + if (device_get_uclass_id(dev->parent->parent) != UCLASS_UFS) + continue; /* - * FIXME: eventually we'll want to find the active/inactive variant of the partition - * but on the rb3gen2 these values might all be 0 + * If we don't have UFS, then U-Boot must be on the eMMC which is always the first + * MMC device. */ - if (!strncmp(info.name, partname, strlen(partname))) { - log_debug("Found active %s partition: '%s'!\n", partname, info.name); - strlcpy(name, info.name, sizeof(info.name)); - return partnum; + } else if (dev->parent->seq_ > 0) { + continue; } + + desc = dev_get_uclass_plat(dev); + if (!desc || desc->part_type == PART_TYPE_UNKNOWN) + continue; + for (partnum = 1;; partnum++) { + ret = part_get_info(desc, partnum, &info); + if (ret) + break; + + slot_status = (struct part_slot_status *)&info.type_flags; + + /* + * Qualcomm Linux devices have a "uefi" partition, it's A/B but the + * flags might not be set so we assume the A partition unless the B + * partition is active. + */ + if (!strncmp(info.name, "uefi", strlen("uefi"))) { + /* + * If U-Boot was chainloaded somehow we can't be flashed to + * the uefi partition + */ + if (qcom_boot_source != QCOM_BOOT_SOURCE_XBL) + continue; + + *target_part_type = TARGET_PART_UEFI; + /* + * Found an active UEFI partition, this is where U-Boot is + * flashed. + */ + if (slot_status->active) + goto found; + + /* Prefer A slot if it's not marked active */ + if (get_part_slot(info.name) == SLOT_A) { + /* + * If we found the A slot after the B slot (both + * inactive) then we assume U-Boot is on the A slot. + */ + if (uefi_partnum >= 0) + goto found; + + /* Didn't find the B slot yet */ + uefi_partnum = partnum; + strlcpy(ptn_name, info.name, 32); + } else { + /* + * Found inactive B slot after inactive A slot, return + * the A slot + */ + if (uefi_partnum >= 0) { + partnum = uefi_partnum; + goto found; + } + + /* + * Didn't find the A slot yet. Record that we found the + * B slot + */ + uefi_partnum = partnum; + strlcpy(ptn_name, info.name, 32); + } + /* xbl and aboot are effectively the same */ + } else if ((!strncmp(info.name, "xbl", strlen("xbl")) && + strlen(info.name) == 5) || + !strncmp(info.name, "aboot", strlen("aboot"))) { + /* + * If U-Boot was booted via ABL, we can't be flashed to the + * XBL partition + */ + if (qcom_boot_source != QCOM_BOOT_SOURCE_XBL) + continue; + + /* + * ignore xbl partition if we have uefi partitions, U-Boot will + * always be on the UEFI partition in this case. + */ + if (*target_part_type == TARGET_PART_UEFI) + continue; + + /* Either non-A/B or find the active XBL partition */ + if (slot_status->active || !get_part_slot(info.name)) { + /* + * No quick return since we might find a uefi partition + * later + */ + xbl_partnum = partnum; + *target_part_type = TARGET_PART_XBL; + xbl_desc = desc; + strlcpy(ptn_name, info.name, 32); + } + + /* + * No fast return since we might also have a uefi partition which + * will take priority. + */ + } else if (!strncmp(info.name, "boot", strlen("boot"))) { + /* We can only be flashed to boot if we were chainloaded */ + if (qcom_boot_source != QCOM_BOOT_SOURCE_ANDROID) + continue; + + /* + * Either non-A/B or find the active partition. We can return + * immediately here since we've narrowed it down to a single option + */ + if (slot_status->active || !get_part_slot(info.name)) { + *target_part_type = TARGET_PART_BOOT; + goto found; + } + } + } + } + + /* + * Now we've exhausted all options, if we didn't find a uefi partition + * then we are indeed flashed to the xbl partition. + */ + if (*target_part_type == TARGET_PART_XBL) { + partnum = xbl_partnum; + desc = xbl_desc; + goto found; } + /* Found no candidate partitions */ return -1; + +found: + if (desc) { + *devnum = desc->devnum; + *uclass = desc->uclass_id; + } + + /* info won't match for XBL hence the copy. */ + log_info("Capsule update target: %s (disk %d:%d)\n", + *target_part_type == TARGET_PART_BOOT ? info.name : ptn_name, + *devnum, partnum); + return partnum; } /** @@ -101,12 +271,10 @@ static int find_boot_partition(const char *partname, struct blk_desc *blk_dev, c */ void qcom_configure_capsule_updates(void) { - struct blk_desc *desc; int ret = 0, partnum = -1, devnum; static char dfu_string[32] = { 0 }; - char name[32]; /* GPT partition name */ - char *partname = "uefi_a"; - struct udevice *dev = NULL; + enum target_part_type target_part_type = 0; + enum uclass_id dev_uclass; if (IS_ENABLED(CONFIG_SCSI)) { /* Scan for SCSI devices */ @@ -117,26 +285,30 @@ void qcom_configure_capsule_updates(void) } } - uclass_foreach_dev_probe(UCLASS_BLK, dev) { - if (device_get_uclass_id(dev) != UCLASS_BLK) - continue; - - desc = dev_get_uclass_plat(dev); - if (!desc || desc->part_type == PART_TYPE_UNKNOWN) - continue; - devnum = desc->devnum; - partnum = find_boot_partition(partname, desc, - name); - if (partnum >= 0) - break; - } - + partnum = find_target_partition(&devnum, &dev_uclass, &target_part_type); if (partnum < 0) { log_err("Failed to find boot partition\n"); return; } - switch (desc->uclass_id) { + /* + * Set the fw_name based on the partition type. This causes the GUID to be different + * so we will never accidentally flash a U-Boot image intended for XBL to the boot + * partition. + */ + switch (target_part_type) { + case TARGET_PART_UEFI: + fw_images[0].fw_name = u"UBOOT_UEFI_PARTITION"; + break; + case TARGET_PART_XBL: + fw_images[0].fw_name = u"UBOOT_XBL_PARTITION"; + break; + case TARGET_PART_BOOT: + fw_images[0].fw_name = u"UBOOT_BOOT_PARTITION"; + break; + } + + switch (dev_uclass) { case UCLASS_SCSI: snprintf(dfu_string, 32, "scsi %d=u-boot.bin part %d", devnum, partnum); break; @@ -144,10 +316,10 @@ void qcom_configure_capsule_updates(void) snprintf(dfu_string, 32, "mmc 0=u-boot.bin part %d %d", devnum, partnum); break; default: - debug("Unsupported storage uclass: %d\n", desc->uclass_id); + debug("Unsupported storage uclass: %d\n", dev_uclass); return; } - log_debug("boot partition is %s, DFU string: '%s'\n", name, dfu_string); + log_debug("DFU string: '%s'\n", dfu_string); update_info.dfu_string = dfu_string; } diff --git a/arch/arm/mach-snapdragon/of_fixup.c b/arch/arm/mach-snapdragon/of_fixup.c index b398c6b7b9f..328c7812f30 100644 --- a/arch/arm/mach-snapdragon/of_fixup.c +++ b/arch/arm/mach-snapdragon/of_fixup.c @@ -99,19 +99,6 @@ static int fixup_qcom_dwc3(struct device_node *root, struct device_node *glue_np return ret; } - /* - * The RB1/2 boards only have a single USB controller and it's muxed between the type-C port - * and a USB hub. Since we can't do OTG in U-Boot properly we prefer to put it into host mode. - */ - if (of_device_is_compatible(root, "qcom,qrb4210-rb2", NULL, NULL) || - of_device_is_compatible(root, "qcom,qrb2210-rb1", NULL, NULL)) { - ret = of_write_prop(dwc3, "dr_mode", sizeof("host"), "host"); - if (ret) { - log_err("Failed to set 'dr_mode' property: %d\n", ret); - return ret; - } - } - return 0; } diff --git a/arch/arm/mach-snapdragon/qcom-priv.h b/arch/arm/mach-snapdragon/qcom-priv.h index 4f398e2ba37..b8bf574e8bb 100644 --- a/arch/arm/mach-snapdragon/qcom-priv.h +++ b/arch/arm/mach-snapdragon/qcom-priv.h @@ -3,6 +3,20 @@ #ifndef __QCOM_PRIV_H__ #define __QCOM_PRIV_H__ +/** + * enum qcom_boot_source - Track where we got loaded from. + * Used for capsule update logic. + * + * @QCOM_BOOT_SOURCE_ANDROID: chainloaded (typically from ABL) + * @QCOM_BOOT_SOURCE_XBL: flashed to the XBL or UEFI partition + */ +enum qcom_boot_source { + QCOM_BOOT_SOURCE_ANDROID = 1, + QCOM_BOOT_SOURCE_XBL, +}; + +extern enum qcom_boot_source qcom_boot_source; + #if IS_ENABLED(CONFIG_EFI_HAVE_CAPSULE_SUPPORT) void qcom_configure_capsule_updates(void); #else diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig index 17179593913..0a7c029b15a 100644 --- a/arch/arm/mach-sunxi/Kconfig +++ b/arch/arm/mach-sunxi/Kconfig @@ -51,7 +51,13 @@ config DRAM_SUN50I_H616 Select this dram controller driver for some sun50i platforms, like H616. -if DRAM_SUN50I_H616 +config DRAM_SUN50I_A133 + bool + help + Select this dram controller driver for some sun50i platforms, + like A133. + +if DRAM_SUN50I_H616 || DRAM_SUN50I_A133 config DRAM_SUNXI_DX_ODT hex "DRAM DX ODT parameter" help @@ -73,18 +79,64 @@ config DRAM_SUNXI_ODT_EN help ODT EN value from vendor DRAM settings. +config DRAM_SUNXI_PARA0 + hex "DRAM PARA0 parameter" + depends on DRAM_SUN50I_A133 + help + PARA0 value from vendor DRAM settings. + +config DRAM_SUNXI_MR11 + hex "DRAM MR11 parameter" + depends on DRAM_SUN50I_A133 + default 0x0 + help + MR11 value from vendor DRAM settings. + +config DRAM_SUNXI_MR12 + hex "DRAM MR12 parameter" + depends on DRAM_SUN50I_A133 + default 0x0 + help + MR12 value from vendor DRAM settings. + +config DRAM_SUNXI_MR13 + hex "DRAM MR13 parameter" + depends on DRAM_SUN50I_A133 + default 0x0 + help + MR13 value from vendor DRAM settings. + +config DRAM_SUNXI_MR14 + hex "DRAM MR14 parameter" + depends on DRAM_SUN50I_A133 + default 0x0 + help + MR14 value from vendor DRAM settings. + config DRAM_SUNXI_TPR0 hex "DRAM TPR0 parameter" default 0x0 help TPR0 value from vendor DRAM settings. +config DRAM_SUNXI_TPR1 + hex "DRAM TPR1 parameter" + default 0x0 + help + TPR1 value from vendor DRAM settings. + config DRAM_SUNXI_TPR2 hex "DRAM TPR2 parameter" default 0x0 help TPR2 value from vendor DRAM settings. +config DRAM_SUNXI_TPR3 + hex "DRAM TPR3 parameter" + default 0x0 + help + TPR3 value from vendor DRAM settings. + config DRAM_SUNXI_TPR6 hex "DRAM TPR6 parameter" default 0x3300c080 @@ -109,6 +161,20 @@ config DRAM_SUNXI_TPR12 help TPR12 value from vendor DRAM settings. +config DRAM_SUNXI_TPR13 + hex "DRAM TPR13 parameter" + depends on DRAM_SUN50I_A133 + default 0x0 + help + TPR13 value from vendor DRAM settings. + +config DRAM_SUNXI_TPR14 + hex "DRAM TPR14 parameter" + depends on DRAM_SUN50I_A133 + default 0x0 + help + TPR14 value from vendor DRAM settings. + choice prompt "DRAM PHY pin mapping selection" default DRAM_SUNXI_PHY_ADDR_MAP_0 @@ -116,7 +182,8 @@ choice config DRAM_SUNXI_PHY_ADDR_MAP_0 bool "DRAM PHY address map 0" help - This pin mapping selection should be used by the H313, H616, H618. + This pin mapping selection should be used by the H313, H616, H618, + and A133, R818 SoCs. config DRAM_SUNXI_PHY_ADDR_MAP_1 bool "DRAM PHY address map 1" @@ -153,6 +220,7 @@ config SUNXI_SRAM_ADDRESS config SUNXI_RVBAR_ADDRESS hex depends on ARM64 + default 0x08100040 if MACH_SUN50I_A133 default 0x09010040 if SUN50I_GEN_H6 default 0x017000a0 ---help--- @@ -179,8 +247,8 @@ config SUNXI_RVBAR_ALTERNATIVE config SUNXI_BL31_BASE hex default 0x00044000 if MACH_SUN50I || MACH_SUN50I_H5 - default 0x00104000 if MACH_SUN50I_H6 default 0x40000000 if MACH_SUN50I_H616 + default 0x00104000 if SUN50I_GEN_H6 default 0x0 help Address where BL31 (TF-A) is loaded, or zero if BL31 is not used. @@ -262,7 +330,7 @@ config MACH_SUNXI_H3_H5 # TODO: try out A80's 8GiB DRAM space config SUNXI_DRAM_MAX_SIZE hex - default 0x100000000 if MACH_SUN50I_H616 + default 0x100000000 if MACH_SUN50I_H616 || MACH_SUN50I_A133 default 0xC0000000 if MACH_SUN50I || MACH_SUN50I_H5 || MACH_SUN50I_H6 default 0x80000000 @@ -459,6 +527,10 @@ config MACH_SUN50I_H616 config MACH_SUN50I_A133 bool "sun50i (Allwinner A133)" + select ARM64 + select DRAM_SUN50I_A133 + select SUN50I_GEN_H6 + imply OF_UPSTREAM endchoice @@ -497,7 +569,7 @@ config ARM_BOOT_HOOK_RMR This allows both the SPL and the U-Boot proper to be entered in either mode and switch to AArch64 if needed. -if SUNXI_DRAM_DW || DRAM_SUN50I_H6 || DRAM_SUN50I_H616 +if SUNXI_DRAM_DW || DRAM_SUN50I_H6 || DRAM_SUN50I_H616 || DRAM_SUN50I_A133 config SUNXI_DRAM_DDR3 bool @@ -510,6 +582,9 @@ config SUNXI_DRAM_LPDDR3 config SUNXI_DRAM_LPDDR4 bool +config SUNXI_DRAM_DDR4 + bool + choice prompt "DRAM Type and Timing" default SUNXI_DRAM_DDR3_1333 if !MACH_SUN8I_V3S @@ -518,6 +593,7 @@ choice config SUNXI_DRAM_DDR3_1333 bool "DDR3 1333" select SUNXI_DRAM_DDR3 + depends on !DRAM_SUN50I_A133 ---help--- This option is the original only supported memory type, which suits many H3/H5/A64 boards available now. @@ -525,6 +601,7 @@ config SUNXI_DRAM_DDR3_1333 config SUNXI_DRAM_LPDDR3_STOCK bool "LPDDR3 with Allwinner stock configuration" select SUNXI_DRAM_LPDDR3 + depends on !DRAM_SUN50I_A133 ---help--- This option is the LPDDR3 timing used by the stock boot0 by Allwinner. @@ -548,7 +625,7 @@ config SUNXI_DRAM_H6_DDR3_1333 config SUNXI_DRAM_H616_LPDDR3 bool "LPDDR3 DRAM chips on the H616 DRAM controller" select SUNXI_DRAM_LPDDR3 - depends on DRAM_SUN50I_H616 + depends on DRAM_SUN50I_H616 || DRAM_SUN50I_A133 help This option is the LPDDR3 timing used by the stock boot0 by Allwinner. @@ -556,7 +633,7 @@ config SUNXI_DRAM_H616_LPDDR3 config SUNXI_DRAM_H616_LPDDR4 bool "LPDDR4 DRAM chips on the H616 DRAM controller" select SUNXI_DRAM_LPDDR4 - depends on DRAM_SUN50I_H616 + depends on DRAM_SUN50I_H616 || DRAM_SUN50I_A133 help This option is the LPDDR4 timing used by the stock boot0 by Allwinner. @@ -564,11 +641,27 @@ config SUNXI_DRAM_H616_LPDDR4 config SUNXI_DRAM_H616_DDR3_1333 bool "DDR3-1333 boot0 timings on the H616 DRAM controller" select SUNXI_DRAM_DDR3 - depends on DRAM_SUN50I_H616 + depends on DRAM_SUN50I_H616 || DRAM_SUN50I_A133 help This option is the DDR3 timing used by the boot0 on H616 TV boxes which use a DDR3-1333 timing. +config SUNXI_DRAM_A133_DDR4 + bool "DDR4 boot0 timings on the A133 DRAM controller" + select SUNXI_DRAM_DDR4 + depends on DRAM_SUN50I_A133 + help + This option is the DDR4 timing used by the boot0 on A133 devices + which use a DDR4 timing. + +config SUNXI_DRAM_A133_LPDDR4 + bool "LPDDR4 boot0 timings on the A133 DRAM controller" + select SUNXI_DRAM_LPDDR4 + depends on DRAM_SUN50I_A133 + help + This option is the LPDDR4 timing used by the boot0 on A133 devices + which use an LPDDR4 timing. + config SUNXI_DRAM_DDR2_V3S bool "DDR2 found in V3s chip" select SUNXI_DRAM_DDR2 @@ -596,7 +689,7 @@ config DRAM_CLK MACH_SUN8I_V3S default 672 if MACH_SUN50I default 744 if MACH_SUN50I_H6 - default 720 if MACH_SUN50I_H616 + default 720 if MACH_SUN50I_H616 || MACH_SUN50I_A133 ---help--- Set the dram clock speed, valid range 240 - 480 (prior to sun9i), must be a multiple of 24. For the sun9i (A80), the tested values @@ -613,7 +706,7 @@ endif config DRAM_ZQ int "sunxi dram zq value" - depends on !MACH_SUN50I_H616 + depends on !MACH_SUN50I_H616 && !MACH_SUN50I_A133 default 123 if MACH_SUN4I || MACH_SUN5I || MACH_SUN6I || \ MACH_SUN8I_A23 || MACH_SUN8I_A33 || MACH_SUN8I_A83T default 127 if MACH_SUN7I @@ -733,6 +826,7 @@ config SYS_CONFIG_NAME default "sun50i" if MACH_SUN50I default "sun50i" if MACH_SUN50I_H6 default "sun50i" if MACH_SUN50I_H616 + default "sun50i" if MACH_SUN50I_A133 config SYS_BOARD default "sunxi" diff --git a/arch/arm/mach-sunxi/Makefile b/arch/arm/mach-sunxi/Makefile index a33cd5b0f07..8eff20b77bf 100644 --- a/arch/arm/mach-sunxi/Makefile +++ b/arch/arm/mach-sunxi/Makefile @@ -45,4 +45,6 @@ obj-$(CONFIG_DRAM_SUN50I_H6) += dram_sun50i_h6.o dram_dw_helpers.o obj-$(CONFIG_DRAM_SUN50I_H6) += dram_timings/ obj-$(CONFIG_DRAM_SUN50I_H616) += dram_sun50i_h616.o dram_dw_helpers.o obj-$(CONFIG_DRAM_SUN50I_H616) += dram_timings/ +obj-$(CONFIG_DRAM_SUN50I_A133) += dram_sun50i_a133.o +obj-$(CONFIG_DRAM_SUN50I_A133) += dram_timings/ endif diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c index b1bf51f40c5..08d55b3a0e3 100644 --- a/arch/arm/mach-sunxi/board.c +++ b/arch/arm/mach-sunxi/board.c @@ -137,6 +137,10 @@ static int gpio_init(void) sunxi_gpio_set_cfgpin(SUNXI_GPH(0), SUN50I_H616_GPH_UART0); sunxi_gpio_set_cfgpin(SUNXI_GPH(1), SUN50I_H616_GPH_UART0); sunxi_gpio_set_pull(SUNXI_GPH(1), SUNXI_GPIO_PULL_UP); +#elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_MACH_SUN50I_A133) + sunxi_gpio_set_cfgpin(SUNXI_GPB(9), SUN50I_H616_GPH_UART0); + sunxi_gpio_set_cfgpin(SUNXI_GPB(10), SUN50I_H616_GPH_UART0); + sunxi_gpio_set_pull(SUNXI_GPB(10), SUNXI_GPIO_PULL_UP); #elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_MACH_SUN8I_A83T) sunxi_gpio_set_cfgpin(SUNXI_GPB(9), SUN8I_A83T_GPB_UART0); sunxi_gpio_set_cfgpin(SUNXI_GPB(10), SUN8I_A83T_GPB_UART0); diff --git a/arch/arm/mach-sunxi/clock_sun50i_h6.c b/arch/arm/mach-sunxi/clock_sun50i_h6.c index 4c522f60810..3f375a51965 100644 --- a/arch/arm/mach-sunxi/clock_sun50i_h6.c +++ b/arch/arm/mach-sunxi/clock_sun50i_h6.c @@ -87,7 +87,8 @@ void clock_set_pll1(unsigned int clk) /* clk = 24*n/p, p is ignored if clock is >288MHz */ 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)) + if (IS_ENABLED(CONFIG_MACH_SUN50I_H616) || + IS_ENABLED(CONFIG_MACH_SUN50I_A133)) val |= CCM_PLL1_OUT_EN; if (IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2)) val |= CCM_PLL1_OUT_EN | CCM_PLL1_LDO_EN; diff --git a/arch/arm/mach-sunxi/cpu_info.c b/arch/arm/mach-sunxi/cpu_info.c index 310dca06e57..3f4735d4717 100644 --- a/arch/arm/mach-sunxi/cpu_info.c +++ b/arch/arm/mach-sunxi/cpu_info.c @@ -104,6 +104,8 @@ int print_cpuinfo(void) puts("CPU: Allwinner H6 (SUN50I)\n"); #elif defined CONFIG_MACH_SUN50I_H616 puts("CPU: Allwinner H616 (SUN50I)\n"); +#elif defined CONFIG_MACH_SUN50I_A133 + puts("CPU: Allwinner A133 (SUN50I)\n"); #else #warning Please update cpu_info.c with correct CPU information puts("CPU: SUNXI Family\n"); diff --git a/arch/arm/mach-sunxi/dram_sun50i_a133.c b/arch/arm/mach-sunxi/dram_sun50i_a133.c new file mode 100644 index 00000000000..a0fca3738f4 --- /dev/null +++ b/arch/arm/mach-sunxi/dram_sun50i_a133.c @@ -0,0 +1,1204 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * sun50i A133 platform dram controller driver + * + * Controller and PHY appear to be quite similar to that of the H616; + * however certain offsets, timings, and other details are different enough that + * the original code does not work as expected. Some device flags and + * calibrations are not yet implemented, and configuration aside from DDR4 + * have not been tested. + * + * (C) Copyright 2024 MasterR3C0RD <masterr3c0rd@epochal.quest> + * + * Uses code from H616 driver, which is + * (C) Copyright 2020 Jernej Skrabec <jernej.skrabec@siol.net> + * + */ + +//#define DEBUG + +#include <asm/arch/clock.h> +#include <asm/arch/cpu.h> +#include <asm/arch/dram.h> +#include <asm/arch/prcm.h> +#include <asm/io.h> +#include <init.h> +#include <linux/bitops.h> +#include <linux/delay.h> +#include <log.h> + +#ifdef CONFIG_DRAM_SUNXI_PHY_ADDR_MAP_1 +static const u8 phy_init[] = { +#ifdef CONFIG_SUNXI_DRAM_DDR3 + 0x0c, 0x08, 0x19, 0x18, 0x10, 0x06, 0x0a, 0x03, 0x0e, + 0x00, 0x0b, 0x05, 0x09, 0x1a, 0x04, 0x13, 0x16, 0x11, + 0x01, 0x15, 0x0d, 0x07, 0x12, 0x17, 0x14, 0x02, 0x0f +#elif CONFIG_SUNXI_DRAM_DDR4 + 0x19, 0x1a, 0x04, 0x12, 0x09, 0x06, 0x08, 0x0a, 0x16, + 0x17, 0x18, 0x0f, 0x0c, 0x13, 0x02, 0x05, 0x01, 0x11, + 0x0e, 0x00, 0x0b, 0x07, 0x03, 0x14, 0x15, 0x0d, 0x10 +#elif CONFIG_SUNXI_DRAM_LPDDR3 + 0x08, 0x03, 0x02, 0x00, 0x18, 0x19, 0x09, 0x01, 0x06, + 0x17, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, + 0x12, 0x13, 0x14, 0x15, 0x16, 0x04, 0x05, 0x07, 0x1a +#elif CONFIG_SUNXI_DRAM_LPDDR4 + 0x01, 0x05, 0x02, 0x00, 0x19, 0x03, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, + 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x04, 0x1a +#endif +}; +#else +static const u8 phy_init[] = { +#ifdef CONFIG_SUNXI_DRAM_DDR3 + 0x03, 0x19, 0x18, 0x02, 0x10, 0x15, 0x16, 0x07, 0x06, + 0x0e, 0x05, 0x08, 0x0d, 0x04, 0x17, 0x1a, 0x13, 0x11, + 0x12, 0x14, 0x00, 0x01, 0x0c, 0x0a, 0x09, 0x0b, 0x0f +#elif CONFIG_SUNXI_DRAM_DDR4 + 0x13, 0x17, 0x0e, 0x01, 0x06, 0x12, 0x14, 0x07, 0x09, + 0x02, 0x0f, 0x00, 0x0d, 0x05, 0x16, 0x0c, 0x0a, 0x11, + 0x04, 0x03, 0x18, 0x15, 0x08, 0x10, 0x0b, 0x19, 0x1a +#elif CONFIG_SUNXI_DRAM_LPDDR3 + 0x05, 0x06, 0x17, 0x02, 0x19, 0x18, 0x04, 0x07, 0x03, + 0x01, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, + 0x12, 0x13, 0x14, 0x15, 0x16, 0x08, 0x09, 0x00, 0x1a +#elif CONFIG_SUNXI_DRAM_LPDDR4 + 0x01, 0x03, 0x02, 0x19, 0x17, 0x00, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, + 0x12, 0x13, 0x14, 0x15, 0x16, 0x04, 0x18, 0x05, 0x1a +#endif +}; +#endif + +static void mctl_clk_init(u32 clk) +{ + void * const ccm = (void *)SUNXI_CCM_BASE; + + /* Place all DRAM blocks into reset */ + clrbits_le32(ccm + CCU_H6_MBUS_CFG, MBUS_ENABLE); + clrbits_le32(ccm + CCU_H6_MBUS_CFG, MBUS_RESET); + clrbits_le32(ccm + CCU_H6_DRAM_GATE_RESET, BIT(GATE_SHIFT)); + clrbits_le32(ccm + CCU_H6_DRAM_GATE_RESET, BIT(RESET_SHIFT)); + clrbits_le32(ccm + CCU_H6_PLL5_CFG, CCM_PLL5_CTRL_EN); + clrbits_le32(ccm + CCU_H6_DRAM_CLK_CFG, DRAM_MOD_RESET); + udelay(5); + + /* Set up PLL5 clock, used for DRAM */ + clrsetbits_le32(ccm + CCU_H6_PLL5_CFG, 0xff03, + CCM_PLL5_CTRL_N((clk * 2) / 24) | CCM_PLL5_CTRL_EN); + setbits_le32(ccm + CCU_H6_PLL5_CFG, BIT(24)); + clrsetbits_le32(ccm + CCU_H6_PLL5_CFG, 0x3, + CCM_PLL5_LOCK_EN | CCM_PLL5_CTRL_EN | BIT(30)); + clrbits_le32(ccm + CCU_H6_PLL5_CFG, 0x3 | BIT(30)); + mctl_await_completion(ccm + CCU_H6_PLL5_CFG, + CCM_PLL5_LOCK, CCM_PLL5_LOCK); + + /* Enable DRAM clock and gate*/ + clrbits_le32(ccm + CCU_H6_DRAM_CLK_CFG, BIT(24) | BIT(25)); + clrsetbits_le32(ccm + CCU_H6_DRAM_CLK_CFG, 0x1f, BIT(1) | BIT(0)); + setbits_le32(ccm + CCU_H6_DRAM_CLK_CFG, DRAM_CLK_UPDATE); + setbits_le32(ccm + CCU_H6_DRAM_GATE_RESET, BIT(RESET_SHIFT)); + setbits_le32(ccm + CCU_H6_DRAM_GATE_RESET, BIT(GATE_SHIFT)); + + /* Re-enable MBUS and reset the DRAM module */ + setbits_le32(ccm + CCU_H6_MBUS_CFG, MBUS_RESET); + setbits_le32(ccm + CCU_H6_MBUS_CFG, MBUS_ENABLE); + setbits_le32(ccm + CCU_H6_DRAM_CLK_CFG, DRAM_MOD_RESET); + udelay(5); +} + +static void mctl_set_odtmap(const struct dram_para *para, + const struct dram_config *config) +{ + struct sunxi_mctl_ctl_reg *mctl_ctl = + (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE; + + u32 val, temp1, temp2; + + /* Set ODT/rank mappings*/ + if (config->bus_full_width) + writel_relaxed(0x0201, &mctl_ctl->odtmap); + else + writel_relaxed(0x0303, &mctl_ctl->odtmap); + + switch (para->type) { + case SUNXI_DRAM_TYPE_DDR3: + val = 0x06000400; + break; + case SUNXI_DRAM_TYPE_LPDDR3: + /* TODO: What's the purpose of these values? */ + temp1 = para->clk * 7 / 2000; + if (para->clk < 400) + temp2 = 0x3; + else + temp2 = 0x4; + + val = 0x400 | (temp2 - temp1) << 16 | temp1 << 24; + break; + case SUNXI_DRAM_TYPE_DDR4: + /* MR4: CS to CMD / ADDR Latency and write preamble */ + val = 0x400 | (0x000 << 10 & 0x70000) | + (((0x0000 >> 12) & 1) + 6) << 24; + break; + case SUNXI_DRAM_TYPE_LPDDR4: + val = 0x4000400; + break; + } + + writel_relaxed(val, &mctl_ctl->odtcfg); + /* Documented as ODTCFG_SHADOW */ + writel_relaxed(val, &mctl_ctl->unk_0x2240); + /* Offset's interesting; additional undocumented shadows? */ + writel_relaxed(val, &mctl_ctl->unk_0x3240); + writel_relaxed(val, &mctl_ctl->unk_0x4240); +} + +/* + * This function produces address mapping parameters, used internally by the + * controller to map address lines to HIF addresses. HIF addresses are word + * addresses, not byte addresses; + * In other words, DDR address 0x400 maps to HIF address 0x100. + * + * This implementation sets up a reasonable mapping where HIF address + * ordering (LSB->MSB) is as such: + * - Bank Groups + * - Columns + * - Banks + * - Rows + * - Ranks + * + * TODO: Handle 1.5GB + 3GB configurations. Info about these is stored in + * upper bits of TPR13 after autoscan in boot0, and then some extra logic + * happens in the address mapping + */ +#define INITIAL_HIF_OFFSET 3 + +static void mctl_set_addrmap(const struct dram_config *config) +{ + struct sunxi_mctl_ctl_reg *mctl_ctl = + (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE; + + u8 bankgrp_bits = config->bankgrps; + u8 col_bits = config->cols; + u8 bank_bits = config->banks; + u8 row_bits = config->rows; + u8 rank_bits = config->ranks; + + unsigned int i, hif_offset, hif_bits[6]; + + /* + * When the bus is half width, we need to adjust address mapping, + * as COL[0] will be reallocated as part of the byte address, + * offsetting the column address mapping values by 1 + */ + if (!config->bus_full_width) + col_bits--; + + /* Match boot0's DRAM requirements */ + if (bankgrp_bits > 2) + panic("invalid dram configuration (bankgrps_bits = %d)", + bankgrp_bits); + if (col_bits < 8 || col_bits > 12) + panic("invalid dram configuration (col_bits = %d)", col_bits); + + if (bank_bits < 2 || bank_bits > 3) + panic("invalid dram configuration (bank_bits = %d)", bank_bits); + + if (row_bits < 14 || row_bits > 18) + panic("invalid dram configuration (row_bits = %d)", row_bits); + + if (rank_bits > 1) + panic("invalid dram configuration (rank_bits = %d)", rank_bits); + + /* + * Col[0:1] + HIF[0:1] (hardwired), Col[2] = HIF[2] (required) + * Thus, we start allocating from HIF[3] onwards + */ + hif_offset = INITIAL_HIF_OFFSET; + + /* BG[bankgrp_bits:0] = HIF[3 + bankgrp_bits:3]*/ + switch (bankgrp_bits) { + case 0: + writel_relaxed(ADDRMAP8_BG0_B2(ADDRMAP_DISABLED_1F_B(2)) | + ADDRMAP8_BG1_B3(ADDRMAP_DISABLED_1F_B(3)), + &mctl_ctl->addrmap[8]); + break; + case 1: + writel_relaxed(ADDRMAP8_BG0_B2(hif_offset) | + ADDRMAP8_BG1_B3(ADDRMAP_DISABLED_1F_B(3)), + &mctl_ctl->addrmap[8]); + break; + case 2: + writel_relaxed(ADDRMAP8_BG0_B2(hif_offset) | + ADDRMAP8_BG1_B3(hif_offset + 1), + &mctl_ctl->addrmap[8]); + break; + default: + panic("invalid dram configuration (bankgrp_bits = %d)", + bankgrp_bits); + } + + hif_offset += bankgrp_bits; + + /* Col[2] = HIF[2], Col[5:3] = HIF[offset + 2:offset] */ + writel_relaxed(ADDRMAP2_COL2_B2(2) | ADDRMAP2_COL3_B3(hif_offset) | + ADDRMAP2_COL4_B4(hif_offset + 1) | + ADDRMAP2_COL5_B5(hif_offset + 2), + &mctl_ctl->addrmap[2]); + + /* Col[col_bits:6] = HIF[col_bits + offset - 3:offset - 3] */ + for (i = 6; i < 12; i++) { + if (i < col_bits) + hif_bits[i - 6] = hif_offset + (i - INITIAL_HIF_OFFSET); + else + hif_bits[i - 6] = ADDRMAP_DISABLED_1F_B(i); + } + + writel_relaxed(ADDRMAP3_COL6_B6(hif_bits[0]) | + ADDRMAP3_COL7_B7(hif_bits[1]) | + ADDRMAP3_COL8_B8(hif_bits[2]) | + ADDRMAP3_COL9_B9(hif_bits[3]), + &mctl_ctl->addrmap[3]); + + writel_relaxed(ADDRMAP4_COL10_B10(hif_bits[4]) | + ADDRMAP4_COL11_B11(hif_bits[5]), + &mctl_ctl->addrmap[4]); + + hif_offset = bankgrp_bits + col_bits; + + /* Bank[bank_bits:0] = HIF[bank_bits + offset:offset] */ + if (bank_bits == 3) + writel_relaxed(ADDRMAP1_BANK0_B2(hif_offset) | + ADDRMAP1_BANK1_B3(hif_offset + 1) | + ADDRMAP1_BANK2_B4(hif_offset + 2), + &mctl_ctl->addrmap[1]); + else + writel_relaxed(ADDRMAP1_BANK0_B2(hif_offset) | + ADDRMAP1_BANK1_B3(hif_offset + 1) | + ADDRMAP1_BANK2_B4(ADDRMAP_DISABLED_1F_B(4)), + &mctl_ctl->addrmap[1]); + + hif_offset += bank_bits; + + /* Row[11:0] = HIF[11 + offset:offset] */ + writel_relaxed(ADDRMAP5_ROW0_B6(hif_offset) | + ADDRMAP5_ROW1_B7(hif_offset + 1) | + ADDRMAP5_ROW2_10_B8(hif_offset + 2) | + ADDRMAP5_ROW11_B17(hif_offset + 11), + &mctl_ctl->addrmap[5]); + + /* + * There's some complexity here because of a special case + * in boot0 code that appears to work around a hardware bug. + * For (col_bits, row_bits, rank_bits) = (10, 16, 1), we have to + * place CS[0] in the position we would normally place ROW[14], + * and shift ROW[14] and ROW[15] over by one. Using the bit following + * ROW[15], as would be standard here, seems to cause nonsensical + * aliasing patterns. + * + * Aside from this case, mapping is simple: + * Row[row_bits:12] = HIF[offset + row_bits:offset + 12] + */ + for (i = 12; i < 18; i++) { + if (i >= row_bits) + hif_bits[i - 12] = ADDRMAP_DISABLED_0F_B(6 + i); + else if (rank_bits != 1 || col_bits != 10 || row_bits != 16 || + i < 14) + hif_bits[i - 12] = hif_offset + i; + else + hif_bits[i - 12] = hif_offset + i + 1; + } + + writel_relaxed(ADDRMAP6_ROW12_B18(hif_bits[0]) | + ADDRMAP6_ROW13_B19(hif_bits[1]) | + ADDRMAP6_ROW14_B20(hif_bits[2]) | + ADDRMAP6_ROW15_B21(hif_bits[3]), + &mctl_ctl->addrmap[6]); + + writel_relaxed(ADDRMAP7_ROW16_B22(hif_bits[4]) | + ADDRMAP7_ROW17_B23(hif_bits[5]), + &mctl_ctl->addrmap[7]); + + hif_offset += row_bits; + + /* + * Ranks + * Most cases: CS[0] = HIF[offset] + * Special case (see above): CS[0] = HIF[offset - 2] + */ + if (rank_bits == 0) + writel_relaxed(ADDRMAP0_CS0_B6(ADDRMAP_DISABLED_1F_B(6)), + &mctl_ctl->addrmap[0]); + else if (col_bits == 10 && row_bits == 16) + writel_relaxed(ADDRMAP0_CS0_B6(hif_offset - 2), + &mctl_ctl->addrmap[0]); + else + writel_relaxed(ADDRMAP0_CS0_B6(hif_offset), + &mctl_ctl->addrmap[0]); +} + +static void mctl_com_init(const struct dram_para *para, + const struct dram_config *config) +{ + void *const mctl_com = (void *)SUNXI_DRAM_COM_BASE; + struct sunxi_mctl_ctl_reg *mctl_ctl = + (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE; + + /* Might control power/reset of DDR-related blocks */ + clrsetbits_le32(mctl_com + MCTL_COM_UNK_008, BIT(24), BIT(25) | BIT(9)); + + /* Unlock mctl_ctl registers */ + setbits_le32(mctl_com + MCTL_COM_MAER0, BIT(15)); + + if (para->type == SUNXI_DRAM_TYPE_LPDDR4) + setbits_le32(0x03102ea8, BIT(0)); + + clrsetbits_le32(&mctl_ctl->sched[0], 0xff << 8, 0x30 << 8); + if (!(para->tpr13 & BIT(28))) + clrsetbits_le32(&mctl_ctl->sched[0], 0xf, BIT(0)); + + writel_relaxed(0, &mctl_ctl->hwlpctl); + + /* Master settings */ + u32 mstr_value = MSTR_DEVICECONFIG_X32 | + MSTR_ACTIVE_RANKS(config->ranks); + + if (config->bus_full_width) + mstr_value |= MSTR_BUSWIDTH_FULL; + else + mstr_value |= MSTR_BUSWIDTH_HALF; + + /* + * Geardown and 2T mode are always enabled here, but is controlled by a flag in boot0; + * it has not been a problem so far, but may be suspect if a particular board isn't booting. + */ + switch (para->type) { + case SUNXI_DRAM_TYPE_DDR3: + mstr_value |= MSTR_DEVICETYPE_DDR3 | MSTR_BURST_LENGTH(8) | + MSTR_2TMODE; + break; + case SUNXI_DRAM_TYPE_DDR4: + mstr_value |= MSTR_DEVICETYPE_DDR4 | MSTR_BURST_LENGTH(8) | + MSTR_GEARDOWNMODE | MSTR_2TMODE; + break; + case SUNXI_DRAM_TYPE_LPDDR3: + mstr_value |= MSTR_DEVICETYPE_LPDDR3 | MSTR_BURST_LENGTH(8); + break; + case SUNXI_DRAM_TYPE_LPDDR4: + mstr_value |= MSTR_DEVICETYPE_LPDDR4 | MSTR_BURST_LENGTH(16); + break; + } + + writel_relaxed(mstr_value, &mctl_ctl->mstr); + + mctl_set_odtmap(para, config); + mctl_set_addrmap(config); + mctl_set_timing_params(para); + + dsb(); + writel(0, &mctl_ctl->pwrctl); + + /* Disable automatic controller updates + automatic controller update requests */ + setbits_le32(&mctl_ctl->dfiupd[0], BIT(31) | BIT(30)); + setbits_le32(&mctl_ctl->zqctl[0], BIT(31) | BIT(30)); + setbits_le32(&mctl_ctl->unk_0x2180, BIT(31) | BIT(30)); + setbits_le32(&mctl_ctl->unk_0x3180, BIT(31) | BIT(30)); + setbits_le32(&mctl_ctl->unk_0x4180, BIT(31) | BIT(30)); + + /* + * Data bus inversion + * Controlled by a flag in boot0, enabled by default here. + */ + if (para->type == SUNXI_DRAM_TYPE_DDR4 || + para->type == SUNXI_DRAM_TYPE_LPDDR4) + setbits_le32(&mctl_ctl->dbictl, BIT(2)); +} + +static void mctl_drive_odt_config(const struct dram_para *para) +{ + u32 val; + u64 base; + u32 i; + + /* DX drive */ + for (i = 0; i < 4; i++) { + base = SUNXI_DRAM_PHY0_BASE + 0x388 + 0x40 * i; + val = (para->dx_dri >> (i * 8)) & 0x1f; + + writel_relaxed(val, base); + if (para->type == SUNXI_DRAM_TYPE_LPDDR4) { + if (para->tpr3 & 0x1f1f1f1f) + val = (para->tpr3 >> (i * 8)) & 0x1f; + else + val = 4; + } + writel_relaxed(val, base + 4); + } + + /* CA drive */ + for (i = 0; i < 2; i++) { + base = SUNXI_DRAM_PHY0_BASE + 0x340 + 0x8 * i; + val = (para->ca_dri >> (i * 8)) & 0x1f; + + writel_relaxed(val, base); + writel_relaxed(val, base + 4); + } + + /* DX ODT */ + for (i = 0; i < 4; i++) { + base = SUNXI_DRAM_PHY0_BASE + 0x380 + 0x40 * i; + val = (para->dx_odt >> (i * 8)) & 0x1f; + + if (para->type == SUNXI_DRAM_TYPE_DDR4 || + para->type == SUNXI_DRAM_TYPE_LPDDR3) + writel_relaxed(0, base); + else + writel_relaxed(val, base); + + if (para->type == SUNXI_DRAM_TYPE_LPDDR4) + writel_relaxed(0, base + 4); + else + writel_relaxed(val, base + 4); + } + dsb(); +} + +static void mctl_phy_ca_bit_delay_compensation(const struct dram_para *para) +{ + u32 val, i; + u32 *ptr; + + if (para->tpr10 & BIT(31)) { + val = para->tpr2; + } else { + val = ((para->tpr10 << 1) & 0x1e) | + ((para->tpr10 << 5) & 0x1e00) | + ((para->tpr10 << 9) & 0x1e0000) | + ((para->tpr10 << 13) & 0x1e000000); + + if (para->tpr10 >> 29 != 0) + val <<= 1; + } + + ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x780); + for (i = 0; i < 32; i++) + writel_relaxed((val >> 8) & 0x3f, &ptr[i]); + + writel_relaxed(val & 0x3f, SUNXI_DRAM_PHY0_BASE + 0x7dc); + writel_relaxed(val & 0x3f, SUNXI_DRAM_PHY0_BASE + 0x7e0); + + switch (para->type) { + case SUNXI_DRAM_TYPE_DDR3: + writel_relaxed((val >> 16) & 0x3f, + SUNXI_DRAM_PHY0_BASE + 0x7b8); + writel_relaxed((val >> 24) & 0x3f, + SUNXI_DRAM_PHY0_BASE + 0x784); + break; + case SUNXI_DRAM_TYPE_DDR4: + writel_relaxed((val >> 16) & 0x3f, + SUNXI_DRAM_PHY0_BASE + 0x784); + break; + case SUNXI_DRAM_TYPE_LPDDR3: + writel_relaxed((val >> 16) & 0x3f, + SUNXI_DRAM_PHY0_BASE + 0x788); + writel_relaxed((val >> 24) & 0x3f, + SUNXI_DRAM_PHY0_BASE + 0x790); + break; + case SUNXI_DRAM_TYPE_LPDDR4: + writel_relaxed((val >> 16) & 0x3f, + SUNXI_DRAM_PHY0_BASE + 0x790); + writel_relaxed((val >> 24) & 0x3f, + SUNXI_DRAM_PHY0_BASE + 0x78c); + break; + } + + dsb(); +} + +static void mctl_phy_init(const struct dram_para *para, + const struct dram_config *config) +{ + struct sunxi_mctl_ctl_reg *mctl_ctl = + (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE; + void *const prcm = (void *)SUNXI_PRCM_BASE; + void *const mctl_com = (void *)SUNXI_DRAM_COM_BASE; + + u32 val, val2, i; + u32 *ptr; + + /* Disable auto refresh. */ + setbits_le32(&mctl_ctl->rfshctl3, BIT(0)); + + /* Set "phy_dbi_mode" to mark the DFI as implementing DBI functionality */ + writel_relaxed(0, &mctl_ctl->pwrctl); + clrbits_le32(&mctl_ctl->dfimisc, 1); + writel_relaxed(0x20, &mctl_ctl->pwrctl); + + /* PHY cold reset */ + clrsetbits_le32(mctl_com + MCTL_COM_UNK_008, BIT(24), BIT(9)); + udelay(1); + setbits_le32(mctl_com + MCTL_COM_UNK_008, BIT(24)); + + /* Not sure what this gates the power of. */ + clrbits_le32(prcm + CCU_PRCM_SYS_PWROFF_GATING, BIT(4)); + + if (para->type == SUNXI_DRAM_TYPE_LPDDR4) + clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x4, BIT(7)); + + /* Note: Similar enumeration of values is used during read training */ + if (config->bus_full_width) + val = 0xf; + else + val = 0x3; + + clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x3c, 0xf, val); + + switch (para->type) { + case SUNXI_DRAM_TYPE_DDR3: + val = 13; + val2 = 9; + break; + case SUNXI_DRAM_TYPE_DDR4: + val = 13; + val2 = 10; + break; + case SUNXI_DRAM_TYPE_LPDDR3: + val = 14; + val2 = 8; + break; + case SUNXI_DRAM_TYPE_LPDDR4: + if (para->tpr13 & BIT(28)) + val = 22; + else + val = 20; + + val2 = 10; + break; + } + + writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x14); + writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x35c); + writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x368); + writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x374); + writel_relaxed(0, SUNXI_DRAM_PHY0_BASE + 0x18); + writel_relaxed(0, SUNXI_DRAM_PHY0_BASE + 0x360); + writel_relaxed(0, SUNXI_DRAM_PHY0_BASE + 0x36c); + writel_relaxed(0, SUNXI_DRAM_PHY0_BASE + 0x378); + writel_relaxed(val2, SUNXI_DRAM_PHY0_BASE + 0x1c); + writel_relaxed(val2, SUNXI_DRAM_PHY0_BASE + 0x364); + writel_relaxed(val2, SUNXI_DRAM_PHY0_BASE + 0x370); + writel_relaxed(val2, SUNXI_DRAM_PHY0_BASE + 0x37c); + + /* Set up SDQ swizzle */ + ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0xc0); + for (i = 0; i < ARRAY_SIZE(phy_init); i++) + writel_relaxed(phy_init[i], &ptr[i]); + + /* Set VREF */ + val = 0; + switch (para->type) { + case SUNXI_DRAM_TYPE_DDR3: + val = para->tpr6 & 0xff; + if (val == 0) + val = 0x80; + break; + case SUNXI_DRAM_TYPE_DDR4: + val = (para->tpr6 >> 8) & 0xff; + if (val == 0) + val = 0x80; + break; + case SUNXI_DRAM_TYPE_LPDDR3: + val = (para->tpr6 >> 16) & 0xff; + if (val == 0) + val = 0x80; + break; + case SUNXI_DRAM_TYPE_LPDDR4: + val = (para->tpr6 >> 24) & 0xff; + if (val == 0) + val = 0x33; + break; + } + writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x3dc); + writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x45c); + + mctl_drive_odt_config(para); + + if (para->tpr10 & TPR10_CA_BIT_DELAY) + mctl_phy_ca_bit_delay_compensation(para); + + switch (para->type) { + case SUNXI_DRAM_TYPE_DDR3: + val = 2; + break; + case SUNXI_DRAM_TYPE_LPDDR3: + val = 3; + break; + case SUNXI_DRAM_TYPE_DDR4: + val = 4; + break; + case SUNXI_DRAM_TYPE_LPDDR4: + val = 5; + break; + } + + clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x4, 0x7, val | 8); + + if (para->clk <= 672) + writel_relaxed(0xf, SUNXI_DRAM_PHY0_BASE + 0x20); + + if (para->clk > 500) { + val = 0; + val2 = 0; + } else { + val = 0x80; + val2 = 0x20; + } + + clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x144, 0x80, val); + clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x14c, 0xe0, val2); + + dsb(); + clrbits_le32(mctl_com + MCTL_COM_UNK_008, BIT(9)); + udelay(1); + clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x14c, BIT(3)); + + mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x180), BIT(2), + BIT(2)); + + /* + * This delay is controlled by a tpr13 flag in boot0; doesn't hurt + * to always do it though. + */ + udelay(1000); + writel(0x37, SUNXI_DRAM_PHY0_BASE + 0x58); + + setbits_le32(prcm + CCU_PRCM_SYS_PWROFF_GATING, BIT(4)); +} + +/* Helpers for updating mode registers */ +static inline void mctl_mr_write(u32 mrctrl0, u32 mrctrl1) +{ + struct sunxi_mctl_ctl_reg *mctl_ctl = + (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE; + + writel(mrctrl1, &mctl_ctl->mrctrl1); + writel(mrctrl0 | MRCTRL0_MR_WR | MRCTRL0_MR_RANKS_ALL, + &mctl_ctl->mrctrl0); + mctl_await_completion(&mctl_ctl->mrctrl0, MRCTRL0_MR_WR, 0); +} + +static inline void mctl_mr_write_lpddr4(u8 addr, u8 value) +{ + mctl_mr_write(0, MRCTRL1_MR_ADDR(addr) | MRCTRL1_MR_DATA(value)); +} + +static inline void mctl_mr_write_lpddr3(u8 addr, u8 value) +{ + /* Bit [7:6] are set by boot0, but undocumented */ + mctl_mr_write(BIT(6) | BIT(7), + MRCTRL1_MR_ADDR(addr) | MRCTRL1_MR_DATA(value)); +} + +static void mctl_dfi_init(const struct dram_para *para) +{ + void *const mctl_com = (void *)SUNXI_DRAM_COM_BASE; + struct sunxi_mctl_ctl_reg *mctl_ctl = + (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE; + + /* Unlock DFI registers? */ + setbits_le32(mctl_com + MCTL_COM_MAER0, BIT(8)); + + /* Enable dfi_init_complete signal and trigger PHY init start request */ + writel_relaxed(0, &mctl_ctl->swctl); + setbits_le32(&mctl_ctl->dfimisc, BIT(0)); + setbits_le32(&mctl_ctl->dfimisc, BIT(5)); + writel_relaxed(1, &mctl_ctl->swctl); + mctl_await_completion(&mctl_ctl->swstat, BIT(0), BIT(0)); + + /* Stop sending init request and wait for DFI initialization to complete. */ + writel_relaxed(0, &mctl_ctl->swctl); + clrbits_le32(&mctl_ctl->dfimisc, BIT(5)); + writel_relaxed(1, &mctl_ctl->swctl); + mctl_await_completion(&mctl_ctl->swstat, BIT(0), BIT(0)); + mctl_await_completion(&mctl_ctl->dfistat, BIT(0), BIT(0)); + + /* Enter Software Exit from Self Refresh */ + writel_relaxed(0, &mctl_ctl->swctl); + clrbits_le32(&mctl_ctl->pwrctl, BIT(5)); + writel_relaxed(1, &mctl_ctl->swctl); + mctl_await_completion(&mctl_ctl->swstat, BIT(0), BIT(0)); + mctl_await_completion(&mctl_ctl->statr, 0x3, 1); + + udelay(200); + + /* Disable dfi_init_complete signal */ + writel_relaxed(0, &mctl_ctl->swctl); + clrbits_le32(&mctl_ctl->dfimisc, BIT(0)); + writel_relaxed(1, &mctl_ctl->swctl); + mctl_await_completion(&mctl_ctl->swstat, BIT(0), BIT(0)); + + /* Write mode registers, fixed in the JEDEC spec */ + switch (para->type) { + case SUNXI_DRAM_TYPE_DDR3: + mctl_mr_write(MRCTRL0_MR_ADDR(0), 0x1c70); /* MR0 */ + /* + * outbuf en, TDQs dis, write leveling dis, out drv 40 Ohms, + * DLL en, Rtt_nom 120 Ohms + */ + mctl_mr_write(MRCTRL0_MR_ADDR(1), 0x40); /* MR1 */ + /* + * full array self-ref, CAS: 8 cyc, SRT w/ norm temp range, + * dynamic ODT off + */ + mctl_mr_write(MRCTRL0_MR_ADDR(2), 0x18); /* MR2 */ + /* predef MPR pattern */ + mctl_mr_write(MRCTRL0_MR_ADDR(3), 0); /* MR3 */ + break; + case SUNXI_DRAM_TYPE_DDR4: + mctl_mr_write(MRCTRL0_MR_ADDR(0), 0x840); + mctl_mr_write(MRCTRL0_MR_ADDR(1), 0x601); + mctl_mr_write(MRCTRL0_MR_ADDR(2), 0x8); + mctl_mr_write(MRCTRL0_MR_ADDR(3), 0); + mctl_mr_write(MRCTRL0_MR_ADDR(4), 0); + mctl_mr_write(MRCTRL0_MR_ADDR(5), 0x400); + + mctl_mr_write(MRCTRL0_MR_ADDR(6), 0x862 | BIT(7)); + mctl_mr_write(MRCTRL0_MR_ADDR(6), 0x862 | BIT(7)); + mctl_mr_write(MRCTRL0_MR_ADDR(6), 0x862 & (~BIT(7))); + break; + case SUNXI_DRAM_TYPE_LPDDR3: + mctl_mr_write_lpddr3(1, 0xc3); /* MR1: nWR=8, BL8 */ + mctl_mr_write_lpddr3(2, 0xa); /* MR2: RL=12, WL=6 */ + mctl_mr_write_lpddr3(3, 0x2); /* MR3: 40 0hms PD/PU */ + mctl_mr_write_lpddr3(11, para->mr11); + break; + case SUNXI_DRAM_TYPE_LPDDR4: + mctl_mr_write_lpddr4(0, 0); /* MR0 */ + mctl_mr_write_lpddr4(1, 0x34); /* MR1 */ + mctl_mr_write_lpddr4(2, 0x1b); /* MR2 */ + mctl_mr_write_lpddr4(3, 0x33); /* MR3 */ + mctl_mr_write_lpddr4(4, 0x3); /* MR4 */ + mctl_mr_write_lpddr4(11, para->mr11); + mctl_mr_write_lpddr4(12, para->mr12); + mctl_mr_write_lpddr4(13, para->mr13); + mctl_mr_write_lpddr4(14, para->mr14); + mctl_mr_write_lpddr4(22, para->tpr1); + break; + } + + writel(0, SUNXI_DRAM_PHY0_BASE + 0x54); + + /* Re-enable controller refresh */ + writel(0, &mctl_ctl->swctl); + clrbits_le32(&mctl_ctl->rfshctl3, BIT(0)); + writel(1, &mctl_ctl->swctl); +} + +/* Slightly modified from H616 driver */ +static bool mctl_phy_read_calibration(const struct dram_config *config) +{ + bool result = true; + u32 val, tmp; + + clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 0x30, 0x20); + + setbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 1); + + if (config->bus_full_width) + val = 0xf; + else + val = 3; + + while ((readl_relaxed(SUNXI_DRAM_PHY0_BASE + 0x184) & val) != val) { + if (readl_relaxed(SUNXI_DRAM_PHY0_BASE + 0x184) & 0x20) { + result = false; + break; + } + } + + clrbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 1); + + clrbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 0x30); + + if (config->ranks == 1) { + clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 0x30, 0x10); + + setbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 1); + + while ((readl_relaxed(SUNXI_DRAM_PHY0_BASE + 0x184) & val) != + val) { + if (readl_relaxed(SUNXI_DRAM_PHY0_BASE + 0x184) & + 0x20) { + result = false; + break; + } + } + + clrbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 1); + } + + clrbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 0x30); + + val = readl_relaxed(SUNXI_DRAM_PHY0_BASE + 0x274) & 7; + tmp = readl_relaxed(SUNXI_DRAM_PHY0_BASE + 0x26c) & 7; + if (val < tmp) + val = tmp; + tmp = readl_relaxed(SUNXI_DRAM_PHY0_BASE + 0x32c) & 7; + if (val < tmp) + val = tmp; + tmp = readl_relaxed(SUNXI_DRAM_PHY0_BASE + 0x334) & 7; + if (val < tmp) + val = tmp; + clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x38, 0x7, (val + 2) & 7); + + setbits_le32(SUNXI_DRAM_PHY0_BASE + 4, 0x20); + + return result; +} + +static inline void mctl_phy_dx_delay1_inner(u32 *base, u32 val1, u32 val2) +{ + u32 *ptr = base; + + for (int i = 0; i < 9; i++) { + writel_relaxed(val1, ptr); + writel_relaxed(val1, ptr + 0x30); + ptr += 2; + } + + writel_relaxed(val2, ptr + 1); + writel_relaxed(val2, ptr + 49); + writel_relaxed(val2, ptr); + writel_relaxed(val2, ptr + 48); +} + +static inline void mctl_phy_dx_delay0_inner(u32 *base1, u32 *base2, u32 val1, + u32 val2) +{ + u32 *ptr = base1; + + for (int i = 0; i < 9; i++) { + writel_relaxed(val1, ptr); + writel_relaxed(val1, ptr + 0x30); + ptr += 2; + } + + writel_relaxed(val2, base2); + writel_relaxed(val2, base2 + 48); + writel_relaxed(val2, ptr); + writel_relaxed(val2, base2 + 44); +} + +/* + * This might be somewhat transferable to H616; whether or not people like + * the design is another question + */ +static void mctl_phy_dx_delay_compensation(const struct dram_para *para) +{ + if (para->tpr10 & TPR10_DX_BIT_DELAY1) { + clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x60, 1); + setbits_le32(SUNXI_DRAM_PHY0_BASE + 8, BIT(3)); + clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, BIT(4)); + + if (para->type == SUNXI_DRAM_TYPE_DDR4) + clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x4, BIT(7)); + + mctl_phy_dx_delay1_inner((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x484), + para->tpr11 & 0x3f, + para->para0 & 0x3f); + mctl_phy_dx_delay1_inner((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x4d8), + (para->tpr11 >> 8) & 0x3f, + (para->para0 >> 8) & 0x3f); + mctl_phy_dx_delay1_inner((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x604), + (para->tpr11 >> 16) & 0x3f, + (para->para0 >> 16) & 0x3f); + mctl_phy_dx_delay1_inner((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x658), + (para->tpr11 >> 24) & 0x3f, + (para->para0 >> 24) & 0x3f); + + setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x60, 1); + } + + if (para->tpr10 & TPR10_DX_BIT_DELAY0) { + clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x54, BIT(7)); + clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, BIT(2)); + + mctl_phy_dx_delay0_inner((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x480), + (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x528), + para->tpr12 & 0x3f, + para->tpr14 & 0x3f); + + mctl_phy_dx_delay0_inner((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x4d4), + (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x52c), + (para->tpr12 >> 8) & 0x3f, + (para->tpr14 >> 8) & 0x3f); + + mctl_phy_dx_delay0_inner((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x600), + (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x6a8), + (para->tpr12 >> 16) & 0x3f, + (para->tpr14 >> 16) & 0x3f); + + mctl_phy_dx_delay0_inner((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x6ac), + (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x528), + (para->tpr12 >> 24) & 0x3f, + (para->tpr14 >> 24) & 0x3f); + + setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x54, BIT(7)); + } +} + +static bool mctl_calibrate_phy(const struct dram_para *para, + const struct dram_config *config) +{ + struct sunxi_mctl_ctl_reg *mctl_ctl = + (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE; + + int i; + + /* TODO: Implement write levelling */ + if (para->tpr10 & TPR10_READ_CALIBRATION) { + for (i = 0; i < 5; i++) + if (mctl_phy_read_calibration(config)) + break; + if (i == 5) { + debug("read calibration failed\n"); + return false; + } + } + + /* TODO: Implement read training */ + /* TODO: Implement write training */ + + mctl_phy_dx_delay_compensation(para); + /* TODO: Implement DFS */ + clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x60, BIT(0)); + clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x54, 7); + + /* Q: Does self-refresh get disabled by a calibration? */ + writel_relaxed(0, &mctl_ctl->swctl); + clrbits_le32(&mctl_ctl->rfshctl3, BIT(1)); + writel_relaxed(1, &mctl_ctl->swctl); + mctl_await_completion(&mctl_ctl->swstat, BIT(0), BIT(0)); + + return true; +} + +static bool mctl_core_init(const struct dram_para *para, + const struct dram_config *config) +{ + mctl_clk_init(para->clk); + mctl_com_init(para, config); + mctl_phy_init(para, config); + mctl_dfi_init(para); + + return mctl_calibrate_phy(para, config); +} + +/* Heavily inspired from H616 driver. */ +static void auto_detect_ranks(const struct dram_para *para, + struct dram_config *config) +{ + int i; + + config->cols = 9; + config->rows = 14; + config->banks = 2; + config->bankgrps = 0; + + /* Test ranks */ + for (i = 1; i >= 0; i--) { + config->ranks = i; + config->bus_full_width = true; + debug("Testing ranks = %d, 32-bit bus: ", i); + if (mctl_core_init(para, config)) { + debug("OK\n"); + break; + } + + config->bus_full_width = false; + debug("Testing ranks = %d, 16-bit bus: ", i); + if (mctl_core_init(para, config)) { + debug("OK\n"); + break; + } + } + + if (i < 0) + debug("rank testing failed\n"); +} + +static void mctl_write_pattern(void) +{ + unsigned int i; + u32 *ptr, val; + + ptr = (u32 *)CFG_SYS_SDRAM_BASE; + for (i = 0; i < 16; ptr++, i++) { + if (i & 1) + val = ~(ulong)ptr; + else + val = (ulong)ptr; + writel(val, ptr); + } +} + +static bool mctl_check_pattern(ulong offset) +{ + unsigned int i; + u32 *ptr, val; + + ptr = (u32 *)CFG_SYS_SDRAM_BASE; + for (i = 0; i < 16; ptr++, i++) { + if (i & 1) + val = ~(ulong)ptr; + else + val = (ulong)ptr; + if (val != *(ptr + offset / 4)) + return false; + } + + return true; +} + +static void mctl_auto_detect_dram_size(const struct dram_para *para, + struct dram_config *config) +{ + unsigned int shift; + u32 buffer[16]; + + /* max config for bankgrps on DDR4, minimum for everything else */ + config->cols = 8; + config->banks = 2; + config->rows = 14; + + shift = 1 + config->bus_full_width; + if (para->type == SUNXI_DRAM_TYPE_DDR4) { + config->bankgrps = 2; + mctl_core_init(para, config); + + /* store content so it can be restored later. */ + memcpy(buffer, (u32 *)CFG_SYS_SDRAM_BASE, sizeof(buffer)); + mctl_write_pattern(); + + if (mctl_check_pattern(1ULL << (shift + 4))) + config->bankgrps = 1; + + /* restore data */ + memcpy((u32 *)CFG_SYS_SDRAM_BASE, buffer, sizeof(buffer)); + } else { + /* No bank groups in (LP)DDR3/LPDDR4 */ + config->bankgrps = 0; + } + + /* reconfigure to make sure all active columns are accessible */ + config->cols = 12; + mctl_core_init(para, config); + + /* store data again as it might be moved */ + memcpy(buffer, (u32 *)CFG_SYS_SDRAM_BASE, sizeof(buffer)); + mctl_write_pattern(); + + /* + * Detect column address bits. The last number of columns checked + * is 11, if that doesn't match, is must be 12, no more checks needed. + */ + shift = 1 + config->bus_full_width + config->bankgrps; + for (config->cols = 8; config->cols < 12; config->cols++) { + if (mctl_check_pattern(1ULL << (config->cols + shift))) + break; + } + memcpy((u32 *)CFG_SYS_SDRAM_BASE, buffer, sizeof(buffer)); + + /* reconfigure to make sure that all active banks are accessible */ + config->banks = 3; + mctl_core_init(para, config); + + memcpy(buffer, (u32 *)CFG_SYS_SDRAM_BASE, sizeof(buffer)); + mctl_write_pattern(); + + /* detect bank bits */ + shift += config->cols; + for (config->banks = 2; config->banks < 3; config->banks++) { + if (mctl_check_pattern(1ULL << (config->banks + shift))) + break; + } + memcpy((u32 *)CFG_SYS_SDRAM_BASE, buffer, sizeof(buffer)); + + /* reconfigure to make sure that all active rows are accessible */ + config->rows = 18; + mctl_core_init(para, config); + + memcpy(buffer, (u32 *)CFG_SYS_SDRAM_BASE, sizeof(buffer)); + mctl_write_pattern(); + + /* detect row address bits */ + shift += config->banks; + for (config->rows = 14; config->rows < 18; config->rows++) { + if (mctl_check_pattern(1ULL << (config->rows + shift))) + break; + } + memcpy((u32 *)CFG_SYS_SDRAM_BASE, buffer, sizeof(buffer)); +} + +/* Modified from H616 driver to add banks and bank groups */ +static unsigned long calculate_dram_size(const struct dram_config *config) +{ + /* Bootrom only uses x32 or x16 bus widths */ + u8 width = config->bus_full_width ? 4 : 2; + + return (1ULL << (config->cols + config->rows + config->banks + + config->bankgrps)) * + width * (1ULL << config->ranks); +} + +static const struct dram_para para = { + .clk = CONFIG_DRAM_CLK, +#ifdef CONFIG_SUNXI_DRAM_DDR3 + .type = SUNXI_DRAM_TYPE_DDR3, +#elif defined(CONFIG_SUNXI_DRAM_DDR4) + .type = SUNXI_DRAM_TYPE_DDR4, +#elif defined(CONFIG_SUNXI_DRAM_LPDDR3) + .type = SUNXI_DRAM_TYPE_LPDDR3, +#elif defined(CONFIG_SUNXI_DRAM_LPDDR4) + .type = SUNXI_DRAM_TYPE_LPDDR4, +#endif + /* TODO: Populate from config */ + .dx_odt = CONFIG_DRAM_SUNXI_DX_ODT, + .dx_dri = CONFIG_DRAM_SUNXI_DX_DRI, + .ca_dri = CONFIG_DRAM_SUNXI_CA_DRI, + .para0 = CONFIG_DRAM_SUNXI_PARA0, + .mr11 = CONFIG_DRAM_SUNXI_MR11, + .mr12 = CONFIG_DRAM_SUNXI_MR12, + .mr13 = CONFIG_DRAM_SUNXI_MR13, + .mr14 = CONFIG_DRAM_SUNXI_MR14, + .tpr1 = CONFIG_DRAM_SUNXI_TPR1, + .tpr2 = CONFIG_DRAM_SUNXI_TPR2, + .tpr3 = CONFIG_DRAM_SUNXI_TPR3, + .tpr6 = CONFIG_DRAM_SUNXI_TPR6, + .tpr10 = CONFIG_DRAM_SUNXI_TPR10, + .tpr11 = CONFIG_DRAM_SUNXI_TPR11, + .tpr12 = CONFIG_DRAM_SUNXI_TPR12, + .tpr13 = CONFIG_DRAM_SUNXI_TPR13, + .tpr14 = CONFIG_DRAM_SUNXI_TPR14, +}; + +unsigned long sunxi_dram_init(void) +{ + struct dram_config config; + + /* Writing to undocumented SYS_CFG area, according to user manual. */ + setbits_le32(0x03000160, BIT(8)); + clrbits_le32(0x03000168, 0x3f); + + auto_detect_ranks(¶, &config); + mctl_auto_detect_dram_size(¶, &config); + + if (!mctl_core_init(¶, &config)) + return 0; + + debug("cols = 2^%d, rows = 2^%d, banks = %d, bank groups = %d, ranks = %d, width = %d\n", + config.cols, config.rows, 1U << config.banks, + 1U << config.bankgrps, 1U << config.ranks, + 16U << config.bus_full_width); + + return calculate_dram_size(&config); +} diff --git a/arch/arm/mach-sunxi/dram_timings/Makefile b/arch/arm/mach-sunxi/dram_timings/Makefile index 5f203419240..4dc1f29fc08 100644 --- a/arch/arm/mach-sunxi/dram_timings/Makefile +++ b/arch/arm/mach-sunxi/dram_timings/Makefile @@ -6,3 +6,5 @@ obj-$(CONFIG_SUNXI_DRAM_H6_DDR3_1333) += h6_ddr3_1333.o obj-$(CONFIG_SUNXI_DRAM_H616_DDR3_1333) += h616_ddr3_1333.o obj-$(CONFIG_SUNXI_DRAM_H616_LPDDR3) += h616_lpddr3.o obj-$(CONFIG_SUNXI_DRAM_H616_LPDDR4) += h616_lpddr4_2133.o +obj-$(CONFIG_SUNXI_DRAM_A133_DDR4) += a133_ddr4.o +obj-$(CONFIG_SUNXI_DRAM_A133_LPDDR4) += a133_lpddr4.o diff --git a/arch/arm/mach-sunxi/dram_timings/a133_ddr4.c b/arch/arm/mach-sunxi/dram_timings/a133_ddr4.c new file mode 100644 index 00000000000..dec208e22df --- /dev/null +++ b/arch/arm/mach-sunxi/dram_timings/a133_ddr4.c @@ -0,0 +1,80 @@ +#include <asm/arch/cpu.h> +#include <asm/arch/dram.h> + +void mctl_set_timing_params(const struct dram_para *para) +{ + struct sunxi_mctl_ctl_reg *const mctl_ctl = + (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE; + + u8 txsr = 4; + u8 tccd = 3; + u8 rd2wr = 5; + u8 tmrd = 4; + u8 tmrw = 0; + u8 wrlat = 5; + u8 rdlat = 7; + u8 wr2pre = 14; + u8 dfi_tphy_wrlat = 6; + u8 dfi_trddata_en = 10; + + u8 tfaw = ns_to_t(35); + u8 trrd = max(ns_to_t(8), 2); + u8 txp = max(ns_to_t(6), 2); + u8 tmrd_pda = max(ns_to_t(10), 8); + u8 trp = ns_to_t(15); + u8 trc = ns_to_t(49); + u8 wr2rd_s = max(ns_to_t(3), 1) + 7; + u8 tras_min = ns_to_t(34); + u16 trefi_x32 = ns_to_t(7800) / 32; + u16 trfc_min = ns_to_t(350); + u16 txs_x32 = ns_to_t(360) / 32; + u16 tmod = max(ns_to_t(15), 12); + u8 tcke = max(ns_to_t(5), 2); + u8 tcksrx = max(ns_to_t(10), 3); + u8 txs_abort_x32 = ns_to_t(170) / 32; + u8 tras_max = ns_to_t(70200) / 1024; + + u8 rd2pre = (trp < 5 ? 9 - trp : 4); + u8 wr2rd = trrd + 7; + u8 tckesr = tcke + 1; + u8 trcd = trp; + u8 trrd_s = txp; + u8 tcksre = tcksrx; + + writel(tras_min | tras_max << 8 | tfaw << 16 | wr2pre << 24, + &mctl_ctl->dramtmg[0]); + writel(trc | rd2pre << 8 | txp << 16, &mctl_ctl->dramtmg[1]); + writel(wr2rd | rd2wr << 8 | rdlat << 16 | wrlat << 24, + &mctl_ctl->dramtmg[2]); + writel(tmod | tmrd << 12 | tmrw << 20, &mctl_ctl->dramtmg[3]); + writel(trp | trrd << 8 | tccd << 16 | trcd << 24, + &mctl_ctl->dramtmg[4]); + writel(tcke | tckesr << 8 | tcksre << 16 | tcksrx << 24, + &mctl_ctl->dramtmg[5]); + writel((txp + 2) | 0x20 << 16 | 0x20 << 24, + &mctl_ctl->dramtmg[6]); + writel(txs_x32 | 0x10 << 8 | txs_abort_x32 << 16 | txs_abort_x32 << 24, + &mctl_ctl->dramtmg[8]); + writel(wr2rd_s | trrd_s << 8 | 0x2 << 16, &mctl_ctl->dramtmg[9]); + writel(0xe0c05, &mctl_ctl->dramtmg[10]); + writel(0x440c021c, &mctl_ctl->dramtmg[11]); + writel(tmrd_pda, &mctl_ctl->dramtmg[12]); + writel(0xa100002, &mctl_ctl->dramtmg[13]); + writel(txsr, &mctl_ctl->dramtmg[14]); + + clrsetbits_le32(&mctl_ctl->init[0], 0xc0000fff, 1008); + writel(0x1f20000, &mctl_ctl->init[1]); + clrsetbits_le32(&mctl_ctl->init[2], 0xff0f, 0xd05); + writel(0, &mctl_ctl->dfimisc); + + writel(0x840 << 16 | 0x601, &mctl_ctl->init[3]); /* MR0 / MR1 */ + writel(0x8 << 16 | 0x0, &mctl_ctl->init[4]); /* MR2 / MR3 */ + writel(0x0 << 16 | 0x400, &mctl_ctl->init[6]); /* MR4 / MR5 */ + writel(0x826, &mctl_ctl->init[7]); /* MR6 */ + + clrsetbits_le32(&mctl_ctl->rankctl, 0xff0, 0x660); + writel((dfi_tphy_wrlat - 1) | 0x2000000 | (dfi_trddata_en - 1) << 16 | + 0x808000, &mctl_ctl->dfitmg0); + writel(0x100202, &mctl_ctl->dfitmg1); + writel(trfc_min | trefi_x32 << 16, &mctl_ctl->rfshtmg); +} diff --git a/arch/arm/mach-sunxi/dram_timings/a133_lpddr4.c b/arch/arm/mach-sunxi/dram_timings/a133_lpddr4.c new file mode 100644 index 00000000000..1e607381023 --- /dev/null +++ b/arch/arm/mach-sunxi/dram_timings/a133_lpddr4.c @@ -0,0 +1,102 @@ +#include <asm/arch/cpu.h> +#include <asm/arch/dram.h> + +void mctl_set_timing_params(const struct dram_para *para) +{ + struct sunxi_mctl_ctl_reg *const mctl_ctl = + (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE; + + bool tpr13_flag1 = para->tpr13 & BIT(28); + bool tpr13_flag2 = para->tpr13 & BIT(3); + bool tpr13_flag3 = para->tpr13 & BIT(5); + + u8 tccd = 4; + u8 tfaw = ns_to_t(40); + u8 trrd = max(ns_to_t(10), 2); + u8 trcd = max(ns_to_t(18), 2); + u8 trc = ns_to_t(65); + u8 txp = max(ns_to_t(8), 2); + + u8 trp = ns_to_t(21); + u8 tras_min = ns_to_t(42); + u16 trefi_x32 = ns_to_t(3904) / 32; + u16 trfc_min = ns_to_t(180); + u16 txsr = ns_to_t(190); + + u8 tmrw = max(ns_to_t(14), 5); + u8 tmrd = max(ns_to_t(14), 5); + u8 tmod = 12; + u8 tcke = max(ns_to_t(15), 2); + u8 tcksrx = max(ns_to_t(2), 2); + u8 tcksre = max(ns_to_t(5), 2); + u8 tckesr = max(ns_to_t(15), 2); + u8 tras_max = (trefi_x32 * 9) / 32; + u8 txs_x32 = 4; + u8 txsabort_x32 = 4; + + u8 wrlat = 5; + u8 wr2rd_s = 8; + u8 trrd_s = 2; + u8 tmrd_pda = 8; + + u8 wr2pre = 24; + u8 rd2pre = 4; + u8 wr2rd = 14 + max(ns_to_t(tpr13_flag1 ? 10 : 12), 4); + u8 rd2wr = 17 + ns_to_t(4) - ns_to_t(1); + u8 tphy_wrlat = 5; + + u8 rdlat = 10; + u8 trddata_en = 17; + + if (tpr13_flag1) { + rdlat = 11; + trddata_en = 19; + } + + writel(tras_min | tras_max << 8 | tfaw << 16 | wr2pre << 24, + &mctl_ctl->dramtmg[0]); + writel(trc | rd2pre << 8 | txp << 16, &mctl_ctl->dramtmg[1]); + writel(wr2rd | rd2wr << 8 | rdlat << 16 | wrlat << 24, + &mctl_ctl->dramtmg[2]); + writel(tmod | tmrd << 12 | tmrw << 20, &mctl_ctl->dramtmg[3]); + writel(trp | trrd << 8 | tccd << 16 | trcd << 24, + &mctl_ctl->dramtmg[4]); + writel(tcke | tckesr << 8 | tcksre << 16 | tcksrx << 24, + &mctl_ctl->dramtmg[5]); + writel((txp + 2) | 0x20 << 16 | 0x20 << 24, &mctl_ctl->dramtmg[6]); + writel(txs_x32 | 0x10 << 8 | txsabort_x32 << 16 | txsabort_x32 << 24, + &mctl_ctl->dramtmg[8]); + writel(wr2rd_s | trrd_s << 8 | 0x2 << 16, &mctl_ctl->dramtmg[9]); + writel(0xe0c05, &mctl_ctl->dramtmg[10]); + writel(0x440c021c, &mctl_ctl->dramtmg[11]); + writel(tmrd_pda, &mctl_ctl->dramtmg[12]); + writel(0xa100002, &mctl_ctl->dramtmg[13]); + writel(txsr, &mctl_ctl->dramtmg[14]); + + clrsetbits_le32(&mctl_ctl->init[0], 0xc0000fff, 1008); + + if (tpr13_flag2) + writel(0x420000, &mctl_ctl->init[1]); + else + writel(0x1f20000, &mctl_ctl->init[1]); + + clrsetbits_le32(&mctl_ctl->init[2], 0xff0f, 0xd05); + writel(0, &mctl_ctl->dfimisc); + + writel(0x34 << 16 | 0x1b, &mctl_ctl->init[3]); /* MR1/MR2 */ + writel(0x33 << 16, &mctl_ctl->init[4]); /* MR3 */ + writel(para->mr11 << 16 | para->mr12, &mctl_ctl->init[6]); + writel(para->tpr1 << 16 | para->mr14, &mctl_ctl->init[7]); + + clrsetbits_le32(&mctl_ctl->rankctl, 0xff0, 0x660); + if (!tpr13_flag3) { + tphy_wrlat -= 1; + trddata_en -= 1; + } + + writel(tphy_wrlat | trddata_en << 16 | 0x808000 | 0x2000000, + &mctl_ctl->dfitmg0); + writel(0x100202, &mctl_ctl->dfitmg1); + + writel(trfc_min | trefi_x32 << 16, &mctl_ctl->rfshtmg); +} diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index b288c65e7fd..8ade6f7b9d1 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig @@ -155,10 +155,6 @@ config TARGET_M5282EVB bool "Support M5282EVB" select M5282 -config TARGET_ASTRO_MCF5373L - bool "Support astro_mcf5373l" - select M5373 - config TARGET_M53017EVB bool "Support M53017EVB" select M53015 @@ -183,7 +179,6 @@ config TARGET_STMARK2 endchoice source "board/BuS/eb_cpu5282/Kconfig" -source "board/astro/mcf5373l/Kconfig" source "board/cobra5272/Kconfig" source "board/freescale/m5208evbe/Kconfig" source "board/freescale/m5235evb/Kconfig" diff --git a/arch/m68k/dts/Makefile b/arch/m68k/dts/Makefile index 8b354b9c570..c89559be309 100644 --- a/arch/m68k/dts/Makefile +++ b/arch/m68k/dts/Makefile @@ -11,7 +11,6 @@ dtb-$(CONFIG_TARGET_M5253DEMO) += M5253DEMO.dtb dtb-$(CONFIG_TARGET_M5272C3) += M5272C3.dtb dtb-$(CONFIG_TARGET_M5275EVB) += M5275EVB.dtb dtb-$(CONFIG_TARGET_M5282EVB) += M5282EVB.dtb -dtb-$(CONFIG_TARGET_ASTRO_MCF5373L) += astro_mcf5373l.dtb dtb-$(CONFIG_TARGET_M53017EVB) += M53017EVB.dtb dtb-$(CONFIG_TARGET_M5329EVB) += M5329AFEE.dtb M5329BFEE.dtb dtb-$(CONFIG_TARGET_M5373EVB) += M5373EVB.dtb @@ -21,4 +20,4 @@ dtb-$(CONFIG_TARGET_STMARK2) += stmark2.dtb include $(srctree)/scripts/Makefile.dts # Add any required device tree compiler flags here -DTC_FLAGS += -R 4 -p 0x1000 +DTC_FLAGS += -R 4 diff --git a/arch/m68k/dts/astro_mcf5373l.dts b/arch/m68k/dts/astro_mcf5373l.dts deleted file mode 100644 index 40f84dd64b6..00000000000 --- a/arch/m68k/dts/astro_mcf5373l.dts +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it> - */ - -/dts-v1/; -/include/ "mcf537x.dtsi" - -/ { - model = "Astro mcf5373l"; - compatible = "astro,mcf5373l"; - - chosen { - stdout-path = "serial0:115200n8"; - }; -}; - -&uart0 { - bootph-all; - status = "okay"; -}; - -&i2c0 { - clock-frequency = <80000>; - u-boot,i2c-slave-addr = <0x7f>; - status = "okay"; -}; diff --git a/arch/microblaze/dts/Makefile b/arch/microblaze/dts/Makefile index 9be902d3bb1..0f3a7472a67 100644 --- a/arch/microblaze/dts/Makefile +++ b/arch/microblaze/dts/Makefile @@ -5,4 +5,4 @@ dtb-y += $(shell echo $(CONFIG_DEFAULT_DEVICE_TREE)).dtb include $(srctree)/scripts/Makefile.dts # Add any required device tree compiler flags here -DTC_FLAGS += -R 4 -p 0x1000 +DTC_FLAGS += -R 4 diff --git a/arch/mips/include/asm/processor.h b/arch/mips/include/asm/processor.h index 39a4f435a84..4c6322ed1c7 100644 --- a/arch/mips/include/asm/processor.h +++ b/arch/mips/include/asm/processor.h @@ -118,20 +118,4 @@ struct task_struct; */ #define return_address() ({__asm__ __volatile__("":::"$31");__builtin_return_address(0);}) -#ifdef CONFIG_CPU_HAS_PREFETCH - -#define ARCH_HAS_PREFETCH - -static inline void prefetch(const void *addr) -{ - __asm__ __volatile__( - " .set mips4 \n" - " pref %0, (%1) \n" - " .set mips0 \n" - : - : "i" (Pref_Load), "r" (addr)); -} - -#endif - #endif /* _ASM_PROCESSOR_H */ diff --git a/arch/nios2/dts/Makefile b/arch/nios2/dts/Makefile index d77db9762a1..75951164978 100644 --- a/arch/nios2/dts/Makefile +++ b/arch/nios2/dts/Makefile @@ -5,4 +5,4 @@ dtb-y += $(CONFIG_DEFAULT_DEVICE_TREE:"%"=%).dtb include $(srctree)/scripts/Makefile.dts # Add any required device tree compiler flags here -DTC_FLAGS += -R 4 -p 0x1000 +DTC_FLAGS += -R 4 diff --git a/arch/powerpc/cpu/mpc85xx/mp.c b/arch/powerpc/cpu/mpc85xx/mp.c index 8918a401fac..bee6758dc9a 100644 --- a/arch/powerpc/cpu/mpc85xx/mp.c +++ b/arch/powerpc/cpu/mpc85xx/mp.c @@ -410,9 +410,9 @@ static void plat_mp_up(unsigned long bootpg, unsigned int pagesize) void cpu_mp_lmb_reserve(void) { - u32 bootpg = determine_mp_bootpg(NULL); + phys_addr_t bootpg = determine_mp_bootpg(NULL); - lmb_reserve(bootpg, 4096, LMB_NONE); + lmb_alloc_mem(LMB_MEM_ALLOC_ADDR, 0, &bootpg, 4096, LMB_NONE); } void setup_mp(void) diff --git a/arch/powerpc/lib/misc.c b/arch/powerpc/lib/misc.c index 7e303419624..fc10ae50cf8 100644 --- a/arch/powerpc/lib/misc.c +++ b/arch/powerpc/lib/misc.c @@ -36,11 +36,12 @@ int arch_misc_init(void) size = min(size, (ulong)CFG_SYS_LINUX_LOWMEM_MAX_SIZE); if (size < bootm_size) { - ulong base = bootmap_base + size; + phys_addr_t base = bootmap_base + size; printf("WARNING: adjusting available memory from 0x%lx to 0x%llx\n", size, (unsigned long long)bootm_size); - lmb_reserve(base, bootm_size - size, LMB_NONE); + lmb_alloc_mem(LMB_MEM_ALLOC_ADDR, 0, &base, + bootm_size - size, LMB_NONE); } #ifdef CONFIG_MP diff --git a/arch/riscv/dts/Makefile b/arch/riscv/dts/Makefile index cf1872f3fdc..2b10c2d6c01 100644 --- a/arch/riscv/dts/Makefile +++ b/arch/riscv/dts/Makefile @@ -19,4 +19,4 @@ dtb-$(CONFIG_TARGET_ASPEED_AST2700_IBEX) += ast2700-ibex.dtb include $(srctree)/scripts/Makefile.dts # Add any required device tree compiler flags here -DTC_FLAGS += -R 4 -p 0x1000 +DTC_FLAGS += -R 4 diff --git a/arch/sandbox/cpu/state.c b/arch/sandbox/cpu/state.c index 49236db99c2..6a15c8b0a18 100644 --- a/arch/sandbox/cpu/state.c +++ b/arch/sandbox/cpu/state.c @@ -480,7 +480,9 @@ int state_init(void) state = &main_state; state->ram_size = CFG_SYS_SDRAM_SIZE; - state->ram_buf = os_malloc(state->ram_size); + state->mmap_addr = os_malloc(state->ram_size + SB_SDRAM_ALIGN); + state->ram_buf = (uint8_t *)ALIGN((uintptr_t)state->mmap_addr, + SB_SDRAM_ALIGN); if (!state->ram_buf) { printf("Out of memory\n"); os_exit(1); @@ -533,7 +535,7 @@ int state_uninit(void) trace_set_enabled(0); os_free(state->state_fdt); - os_free(state->ram_buf); + os_free(state->mmap_addr); memset(state, '\0', sizeof(*state)); return 0; diff --git a/arch/sandbox/dts/Makefile b/arch/sandbox/dts/Makefile index 1c9fb4a4566..0d7b0b80e21 100644 --- a/arch/sandbox/dts/Makefile +++ b/arch/sandbox/dts/Makefile @@ -11,4 +11,4 @@ dtb-$(CONFIG_CMD_EXTENSION) += overlay0.dtbo overlay1.dtbo include $(srctree)/scripts/Makefile.dts # Add any required device tree compiler flags here -DTC_FLAGS += -R 4 -p 0x1000 +DTC_FLAGS += -R 4 diff --git a/arch/sandbox/include/asm/state.h b/arch/sandbox/include/asm/state.h index dc21a623106..9dea0980bfc 100644 --- a/arch/sandbox/include/asm/state.h +++ b/arch/sandbox/include/asm/state.h @@ -75,6 +75,7 @@ struct sandbox_state { char **argv; /* Command line arguments */ const char *jumped_fname; /* Jumped from previous U-Boot */ const char *prog_fname; /* U-Boot executable filename */ + uint8_t *mmap_addr; /* Memory allocated via mmap */ uint8_t *ram_buf; /* Emulated RAM buffer */ unsigned long ram_size; /* Size of RAM buffer */ const char *ram_buf_fname; /* Filename to use for RAM buffer */ diff --git a/arch/x86/dts/Makefile b/arch/x86/dts/Makefile index 9a46726e026..725991e2629 100644 --- a/arch/x86/dts/Makefile +++ b/arch/x86/dts/Makefile @@ -24,4 +24,4 @@ dtb-y += bayleybay.dtb \ include $(srctree)/scripts/Makefile.dts -DTC_FLAGS += -R 4 -p $(if $(CONFIG_EFI_APP),0x8000,0x1000) +DTC_FLAGS += -R 4 |