diff options
26 files changed, 920 insertions, 158 deletions
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 2a89da2ce9..6d1e8668e7 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -191,25 +191,25 @@ dtb-$(CONFIG_ARCH_MVEBU) += \ armada-3720-turris-mox.dtb \ armada-3720-uDPU.dtb \ armada-375-db.dtb \ + armada-385-atl-x530.dtb \ + armada-385-atl-x530DP.dtb \ + armada-385-db-88f6820-amc.dtb \ + armada-385-turris-omnia.dtb \ armada-388-clearfog.dtb \ armada-388-gp.dtb \ armada-388-helios4.dtb \ - armada-385-db-88f6820-amc.dtb \ - armada-385-turris-omnia.dtb \ - armada-7040-db.dtb \ + armada-38x-controlcenterdc.dtb \ armada-7040-db-nand.dtb \ + armada-7040-db.dtb \ + armada-8040-clearfog-gt-8k.dtb \ armada-8040-db.dtb \ armada-8040-mcbin.dtb \ - armada-8040-clearfog-gt-8k.dtb \ + armada-xp-crs305-1g-4s.dtb \ + armada-xp-db-xc3-24g4xg.dtb \ armada-xp-gp.dtb \ armada-xp-maxbcm.dtb \ armada-xp-synology-ds414.dtb \ - armada-xp-theadorable.dtb \ - armada-38x-controlcenterdc.dtb \ - armada-385-atl-x530.dtb \ - armada-385-atl-x530DP.dtb \ - armada-xp-db-xc3-24g4xg.dtb \ - armada-xp-crs305-1g-4s.dtb + armada-xp-theadorable.dtb dtb-$(CONFIG_ARCH_UNIPHIER_LD11) += \ uniphier-ld11-global.dtb \ diff --git a/arch/arm/dts/armada-3720-turris-mox.dts b/arch/arm/dts/armada-3720-turris-mox.dts index c36a5b8895..a1e0ad5020 100644 --- a/arch/arm/dts/armada-3720-turris-mox.dts +++ b/arch/arm/dts/armada-3720-turris-mox.dts @@ -42,9 +42,24 @@ startup-delay-us = <2000000>; shutdown-delay-us = <1000000>; gpio = <&gpiosb 0 GPIO_ACTIVE_HIGH>; + enable-active-high; regulator-boot-on; }; + vsdc_reg: vsdc-reg { + compatible = "regulator-gpio"; + regulator-name = "vsdc"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + + gpios = <&gpiosb 23 GPIO_ACTIVE_HIGH>; + gpios-states = <0>; + states = <1800000 0x1 + 3300000 0x0>; + enable-active-high; + }; + mdio { #address-cells = <1>; #size-cells = <0>; @@ -93,7 +108,11 @@ }; &sdhci1 { + wp-inverted; bus-width = <4>; + cd-gpios = <&gpionb 10 GPIO_ACTIVE_HIGH>; + vqmmc-supply = <&vsdc_reg>; + marvell,pad-type = "sd"; status = "okay"; }; diff --git a/arch/arm/dts/armada-38x-solidrun-microsom.dtsi b/arch/arm/dts/armada-38x-solidrun-microsom.dtsi index a322a28c21..9bbeafc53b 100644 --- a/arch/arm/dts/armada-38x-solidrun-microsom.dtsi +++ b/arch/arm/dts/armada-38x-solidrun-microsom.dtsi @@ -39,7 +39,6 @@ ð0 { /* ethernet@70000 */ - mac-address = [00 50 43 02 02 01]; pinctrl-0 = <&ge0_rgmii_pins>; pinctrl-names = "default"; phy = <&phy_dedicated>; diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig index bc5eaa5a76..161dee937f 100644 --- a/arch/arm/mach-mvebu/Kconfig +++ b/arch/arm/mach-mvebu/Kconfig @@ -280,4 +280,6 @@ config SECURED_MODE_CSK_INDEX default 0 depends on SECURED_MODE_IMAGE +source "board/solidrun/clearfog/Kconfig" + endif diff --git a/arch/arm/mach-mvebu/arm64-common.c b/arch/arm/mach-mvebu/arm64-common.c index 40b98dbf08..34cc0479a8 100644 --- a/arch/arm/mach-mvebu/arm64-common.c +++ b/arch/arm/mach-mvebu/arm64-common.c @@ -45,54 +45,14 @@ const struct mbus_dram_target_info *mvebu_mbus_dram_info(void) return NULL; } -/* DRAM init code ... */ - -#define MV_SIP_DRAM_SIZE 0x82000010 - -static u64 a8k_dram_scan_ap_sz(void) -{ - struct pt_regs pregs; - - pregs.regs[0] = MV_SIP_DRAM_SIZE; - pregs.regs[1] = SOC_REGS_PHY_BASE; - smc_call(&pregs); - - return pregs.regs[0]; -} - -static void a8k_dram_init_banksize(void) -{ - /* - * The firmware (ATF) leaves a 1G whole above the 3G mark for IO - * devices. Higher RAM is mapped at 4G. - * - * Config 2 DRAM banks: - * Bank 0 - max size 4G - 1G - * Bank 1 - ram size - 4G + 1G - */ - phys_size_t max_bank0_size = SZ_4G - SZ_1G; - - gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE; - if (gd->ram_size <= max_bank0_size) { - gd->bd->bi_dram[0].size = gd->ram_size; - return; - } - - gd->bd->bi_dram[0].size = max_bank0_size; - if (CONFIG_NR_DRAM_BANKS > 1) { - gd->bd->bi_dram[1].start = SZ_4G; - gd->bd->bi_dram[1].size = gd->ram_size - max_bank0_size; - } -} - __weak int dram_init_banksize(void) { if (CONFIG_IS_ENABLED(ARMADA_8K)) - a8k_dram_init_banksize(); + return a8k_dram_init_banksize(); + else if (CONFIG_IS_ENABLED(ARMADA_3700)) + return a3700_dram_init_banksize(); else - fdtdec_setup_memory_banksize(); - - return 0; + return fdtdec_setup_memory_banksize(); } __weak int dram_init(void) @@ -103,6 +63,9 @@ __weak int dram_init(void) return 0; } + if (CONFIG_IS_ENABLED(ARMADA_3700)) + return a3700_dram_init(); + if (fdtdec_setup_mem_size_base() != 0) return -EINVAL; diff --git a/arch/arm/mach-mvebu/armada3700/cpu.c b/arch/arm/mach-mvebu/armada3700/cpu.c index c83268181b..17d2d43bab 100644 --- a/arch/arm/mach-mvebu/armada3700/cpu.c +++ b/arch/arm/mach-mvebu/armada3700/cpu.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) 2016 Stefan Roese <sr@denx.de> + * Copyright (C) 2020 Marek Behun <marek.behun@nic.cz> */ #include <common.h> @@ -13,6 +14,7 @@ #include <asm/arch/cpu.h> #include <asm/arch/soc.h> #include <asm/armv8/mmu.h> +#include <sort.h> /* Armada 3700 */ #define MVEBU_GPIO_NB_REG_BASE (MVEBU_REGISTER(0x13800)) @@ -26,39 +28,289 @@ #define MVEBU_NB_WARM_RST_REG (MVEBU_GPIO_NB_REG_BASE + 0x40) #define MVEBU_NB_WARM_RST_MAGIC_NUM 0x1d1e -static struct mm_region mvebu_mem_map[] = { - { - /* RAM */ - .phys = 0x0UL, - .virt = 0x0UL, - .size = 0x80000000UL, - .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | - PTE_BLOCK_INNER_SHARE - }, +/* Armada 3700 CPU Address Decoder registers */ +#define MVEBU_CPU_DEC_WIN_REG_BASE (size_t)(MVEBU_REGISTER(0xcf00)) +#define MVEBU_CPU_DEC_WIN_CTRL(w) \ + (MVEBU_CPU_DEC_WIN_REG_BASE + ((w) << 4)) +#define MVEBU_CPU_DEC_WIN_CTRL_EN BIT(0) +#define MVEBU_CPU_DEC_WIN_CTRL_TGT_MASK 0xf +#define MVEBU_CPU_DEC_WIN_CTRL_TGT_OFFS 4 +#define MVEBU_CPU_DEC_WIN_CTRL_TGT_DRAM 0 +#define MVEBU_CPU_DEC_WIN_CTRL_TGT_PCIE 2 +#define MVEBU_CPU_DEC_WIN_SIZE(w) (MVEBU_CPU_DEC_WIN_CTRL(w) + 0x4) +#define MVEBU_CPU_DEC_WIN_BASE(w) (MVEBU_CPU_DEC_WIN_CTRL(w) + 0x8) +#define MVEBU_CPU_DEC_WIN_REMAP(w) (MVEBU_CPU_DEC_WIN_CTRL(w) + 0xc) +#define MVEBU_CPU_DEC_WIN_GRANULARITY 16 +#define MVEBU_CPU_DEC_WINS 5 + +#define MAX_MEM_MAP_REGIONS (MVEBU_CPU_DEC_WINS + 2) + +#define A3700_PTE_BLOCK_NORMAL \ + (PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_INNER_SHARE) +#define A3700_PTE_BLOCK_DEVICE \ + (PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE) + +#define PCIE_PATH "/soc/pcie@d0070000" + +DECLARE_GLOBAL_DATA_PTR; + +static struct mm_region mvebu_mem_map[MAX_MEM_MAP_REGIONS] = { { - /* SRAM, MMIO regions */ - .phys = 0xd0000000UL, - .virt = 0xd0000000UL, + /* + * SRAM, MMIO regions + * Don't remove this, a3700_build_mem_map needs it. + */ + .phys = SOC_REGS_PHY_BASE, + .virt = SOC_REGS_PHY_BASE, .size = 0x02000000UL, /* 32MiB internal registers */ - .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | - PTE_BLOCK_NON_SHARE - }, - { - /* PCI regions */ - .phys = 0xe8000000UL, - .virt = 0xe8000000UL, - .size = 0x02000000UL, /* 32MiB master PCI space */ - .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | - PTE_BLOCK_NON_SHARE + .attrs = A3700_PTE_BLOCK_DEVICE }, - { - /* List terminator */ - 0, - } }; struct mm_region *mem_map = mvebu_mem_map; +static int get_cpu_dec_win(int win, u32 *tgt, u32 *base, u32 *size) +{ + u32 reg; + + reg = readl(MVEBU_CPU_DEC_WIN_CTRL(win)); + if (!(reg & MVEBU_CPU_DEC_WIN_CTRL_EN)) + return -1; + + if (tgt) { + reg >>= MVEBU_CPU_DEC_WIN_CTRL_TGT_OFFS; + reg &= MVEBU_CPU_DEC_WIN_CTRL_TGT_MASK; + *tgt = reg; + } + + if (base) { + reg = readl(MVEBU_CPU_DEC_WIN_BASE(win)); + *base = reg << MVEBU_CPU_DEC_WIN_GRANULARITY; + } + + if (size) { + /* + * Window size is encoded as the number of 1s from LSB to MSB, + * followed by 0s. The number of 1s specifies the size in 64 KiB + * granularity. + */ + reg = readl(MVEBU_CPU_DEC_WIN_SIZE(win)); + *size = ((reg + 1) << MVEBU_CPU_DEC_WIN_GRANULARITY); + } + + return 0; +} + +/* + * Builds mem_map according to CPU Address Decoder settings, which were set by + * the TIMH image on the Cortex-M3 secure processor, or by ARM Trusted Firmware + */ +static void build_mem_map(void) +{ + int win, region; + + region = 1; + for (win = 0; win < MVEBU_CPU_DEC_WINS; ++win) { + u32 base, tgt, size; + u64 attrs; + + /* skip disabled windows */ + if (get_cpu_dec_win(win, &tgt, &base, &size)) + continue; + + if (tgt == MVEBU_CPU_DEC_WIN_CTRL_TGT_DRAM) + attrs = A3700_PTE_BLOCK_NORMAL; + else if (tgt == MVEBU_CPU_DEC_WIN_CTRL_TGT_PCIE) + attrs = A3700_PTE_BLOCK_DEVICE; + else + /* skip windows with other targets */ + continue; + + mvebu_mem_map[region].phys = base; + mvebu_mem_map[region].virt = base; + mvebu_mem_map[region].size = size; + mvebu_mem_map[region].attrs = attrs; + ++region; + } + + /* add list terminator */ + mvebu_mem_map[region].size = 0; + mvebu_mem_map[region].attrs = 0; +} + +void enable_caches(void) +{ + build_mem_map(); + + icache_enable(); + dcache_enable(); +} + +int a3700_dram_init(void) +{ + int win; + + gd->ram_size = 0; + for (win = 0; win < MVEBU_CPU_DEC_WINS; ++win) { + u32 base, tgt, size; + + /* skip disabled windows */ + if (get_cpu_dec_win(win, &tgt, &base, &size)) + continue; + + /* skip non-DRAM windows */ + if (tgt != MVEBU_CPU_DEC_WIN_CTRL_TGT_DRAM) + continue; + + /* + * It is possible that one image was built for boards with + * different RAM sizes, for example 512 MiB and 1 GiB. + * We therefore try to determine the actual RAM size in the + * window with get_ram_size. + */ + gd->ram_size += get_ram_size((void *)(size_t)base, size); + } + + return 0; +} + +struct a3700_dram_window { + size_t base, size; +}; + +static int dram_win_cmp(const void *a, const void *b) +{ + size_t ab, bb; + + ab = ((const struct a3700_dram_window *)a)->base; + bb = ((const struct a3700_dram_window *)b)->base; + + if (ab < bb) + return -1; + else if (ab > bb) + return 1; + else + return 0; +} + +int a3700_dram_init_banksize(void) +{ + struct a3700_dram_window dram_wins[MVEBU_CPU_DEC_WINS]; + int bank, win, ndram_wins; + u32 last_end; + size_t size; + + ndram_wins = 0; + for (win = 0; win < MVEBU_CPU_DEC_WINS; ++win) { + u32 base, tgt, size; + + /* skip disabled windows */ + if (get_cpu_dec_win(win, &tgt, &base, &size)) + continue; + + /* skip non-DRAM windows */ + if (tgt != MVEBU_CPU_DEC_WIN_CTRL_TGT_DRAM) + continue; + + dram_wins[win].base = base; + dram_wins[win].size = size; + ++ndram_wins; + } + + qsort(dram_wins, ndram_wins, sizeof(dram_wins[0]), dram_win_cmp); + + bank = 0; + last_end = -1; + + for (win = 0; win < ndram_wins; ++win) { + /* again determining actual RAM size as in a3700_dram_init */ + size = get_ram_size((void *)dram_wins[win].base, + dram_wins[win].size); + + /* + * Check if previous window ends as the current starts. If yes, + * merge these windows into one "bank". This is possible by this + * simple check thanks to mem_map regions being qsorted in + * build_mem_map. + */ + if (last_end == dram_wins[win].base) { + gd->bd->bi_dram[bank - 1].size += size; + last_end += size; + } else { + if (bank == CONFIG_NR_DRAM_BANKS) { + printf("Need more CONFIG_NR_DRAM_BANKS\n"); + return -ENOBUFS; + } + + gd->bd->bi_dram[bank].start = dram_wins[win].base; + gd->bd->bi_dram[bank].size = size; + last_end = dram_wins[win].base + size; + ++bank; + } + } + + /* + * If there is more place for DRAM BANKS definitions than needed, fill + * the rest with zeros. + */ + for (; bank < CONFIG_NR_DRAM_BANKS; ++bank) { + gd->bd->bi_dram[bank].start = 0; + gd->bd->bi_dram[bank].size = 0; + } + + return 0; +} + +static u32 find_pcie_window_base(void) +{ + int win; + + for (win = 0; win < MVEBU_CPU_DEC_WINS; ++win) { + u32 base, tgt; + + /* skip disabled windows */ + if (get_cpu_dec_win(win, &tgt, &base, NULL)) + continue; + + if (tgt == MVEBU_CPU_DEC_WIN_CTRL_TGT_PCIE) + return base; + } + + return -1; +} + +int a3700_fdt_fix_pcie_regions(void *blob) +{ + u32 new_ranges[14], base; + const u32 *ranges; + int node, len; + + node = fdt_path_offset(blob, PCIE_PATH); + if (node < 0) + return node; + + ranges = fdt_getprop(blob, node, "ranges", &len); + if (!ranges) + return -ENOENT; + + if (len != sizeof(new_ranges)) + return -EINVAL; + + memcpy(new_ranges, ranges, len); + + base = find_pcie_window_base(); + if (base == -1) + return -ENOENT; + + new_ranges[2] = cpu_to_fdt32(base); + new_ranges[4] = new_ranges[2]; + + new_ranges[9] = cpu_to_fdt32(base + 0x1000000); + new_ranges[11] = new_ranges[9]; + + return fdt_setprop_inplace(blob, node, "ranges", new_ranges, len); +} + void reset_cpu(ulong ignored) { /* diff --git a/arch/arm/mach-mvebu/armada8k/Makefile b/arch/arm/mach-mvebu/armada8k/Makefile index 82cb25b417..0a4756717a 100644 --- a/arch/arm/mach-mvebu/armada8k/Makefile +++ b/arch/arm/mach-mvebu/armada8k/Makefile @@ -2,5 +2,4 @@ # # Copyright (C) 2016 Stefan Roese <sr@denx.de> -obj-y = cpu.o -obj-y += cache_llc.o +obj-y = cpu.o cache_llc.o dram.o diff --git a/arch/arm/mach-mvebu/armada8k/dram.c b/arch/arm/mach-mvebu/armada8k/dram.c new file mode 100644 index 0000000000..265a8b0ae8 --- /dev/null +++ b/arch/arm/mach-mvebu/armada8k/dram.c @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2016 Stefan Roese <sr@denx.de> + */ + +#include <common.h> +#include <asm/arch/cpu.h> +#include <asm/arch/soc.h> +#include <asm/system.h> +#include <linux/sizes.h> + +DECLARE_GLOBAL_DATA_PTR; + +#define MV_SIP_DRAM_SIZE 0x82000010 + +u64 a8k_dram_scan_ap_sz(void) +{ + struct pt_regs pregs; + + pregs.regs[0] = MV_SIP_DRAM_SIZE; + pregs.regs[1] = SOC_REGS_PHY_BASE; + smc_call(&pregs); + + return pregs.regs[0]; +} + +int a8k_dram_init_banksize(void) +{ + /* + * The firmware (ATF) leaves a 1G whole above the 3G mark for IO + * devices. Higher RAM is mapped at 4G. + * + * Config 2 DRAM banks: + * Bank 0 - max size 4G - 1G + * Bank 1 - ram size - 4G + 1G + */ + phys_size_t max_bank0_size = SZ_4G - SZ_1G; + + gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE; + if (gd->ram_size <= max_bank0_size) { + gd->bd->bi_dram[0].size = gd->ram_size; + return 0; + } + + gd->bd->bi_dram[0].size = max_bank0_size; + if (CONFIG_NR_DRAM_BANKS > 1) { + gd->bd->bi_dram[1].start = SZ_4G; + gd->bd->bi_dram[1].size = gd->ram_size - max_bank0_size; + } + + return 0; +} diff --git a/arch/arm/mach-mvebu/include/mach/cpu.h b/arch/arm/mach-mvebu/include/mach/cpu.h index 2e2d72aac8..c3f8ad8506 100644 --- a/arch/arm/mach-mvebu/include/mach/cpu.h +++ b/arch/arm/mach-mvebu/include/mach/cpu.h @@ -166,10 +166,23 @@ int ddr3_init(void); /* Auto Voltage Scaling */ #if defined(CONFIG_ARMADA_38X) || defined(CONFIG_ARMADA_39X) void mv_avs_init(void); +void mv_rtc_config(void); #else static inline void mv_avs_init(void) {} +static inline void mv_rtc_config(void) {} #endif +/* A8K dram functions */ +u64 a8k_dram_scan_ap_sz(void); +int a8k_dram_init_banksize(void); + +/* A3700 dram functions */ +int a3700_dram_init(void); +int a3700_dram_init_banksize(void); + +/* A3700 PCIe regions fixer for device tree */ +int a3700_fdt_fix_pcie_regions(void *blob); + /* * get_ref_clk * diff --git a/arch/arm/mach-mvebu/serdes/a38x/high_speed_env_spec.c b/arch/arm/mach-mvebu/serdes/a38x/high_speed_env_spec.c index 33e70569bc..66409a50c0 100644 --- a/arch/arm/mach-mvebu/serdes/a38x/high_speed_env_spec.c +++ b/arch/arm/mach-mvebu/serdes/a38x/high_speed_env_spec.c @@ -1366,16 +1366,16 @@ static void print_topology_details(const struct serdes_map *serdes_map, DEBUG_INIT_S("board SerDes lanes topology details:\n"); - DEBUG_INIT_S(" | Lane # | Speed | Type |\n"); + DEBUG_INIT_S(" | Lane # | Speed | Type |\n"); DEBUG_INIT_S(" --------------------------------\n"); for (lane_num = 0; lane_num < count; lane_num++) { if (serdes_map[lane_num].serdes_type == DEFAULT_SERDES) continue; DEBUG_INIT_S(" | "); DEBUG_INIT_D(hws_get_physical_serdes_num(lane_num), 1); - DEBUG_INIT_S(" | "); + DEBUG_INIT_S(" | "); DEBUG_INIT_D(serdes_map[lane_num].serdes_speed, 2); - DEBUG_INIT_S(" | "); + DEBUG_INIT_S(" | "); DEBUG_INIT_S((char *) serdes_type_to_string[serdes_map[lane_num]. serdes_type]); diff --git a/arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.c b/arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.c index e9dd096ad0..3c4c7e01a1 100644 --- a/arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.c +++ b/arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.c @@ -257,6 +257,23 @@ u8 sys_env_device_rev_get(void) return (value & (REVISON_ID_MASK)) >> REVISON_ID_OFFS; } +void mv_rtc_config(void) +{ + u32 i, val; + + if (!(IS_ENABLED(CONFIG_ARMADA_38X) || IS_ENABLED(CONFIG_ARMADA_39X))) + return; + + /* Activate pipe0 for read/write transaction, and set XBAR client number #1 */ + val = 0x1 << DFX_PIPE_SELECT_PIPE0_ACTIVE_OFFS | + 0x1 << DFX_PIPE_SELECT_XBAR_CLIENT_SEL_OFFS; + writel(val, MVEBU_DFX_BASE); + + /* Set new RTC value for all memory wrappers */ + for (i = 0; i < RTC_MEMORY_WRAPPER_COUNT; i++) + reg_write(RTC_MEMORY_WRAPPER_REG(i), RTC_MEMORY_WRAPPER_CTRL_VAL); +} + void mv_avs_init(void) { u32 sar_freq; diff --git a/arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.h b/arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.h index 1774a5b780..17cd811331 100644 --- a/arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.h +++ b/arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.h @@ -150,6 +150,19 @@ #define MPP_UART1_SET_MASK (~(0xff000)) #define MPP_UART1_SET_DATA (0x66000) +#define DFX_PIPE_SELECT_PIPE0_ACTIVE_OFFS 0 +/* DFX_PIPE_SELECT_XBAR_CLIENT_SEL_OFFS: Since address completion in 14bit + * address mode, and given that [14:8] => [19:13], the 2 lower bits [9:8] => + * [14:13] are dismissed. hence field offset is also shifted to 10 + */ +#define DFX_PIPE_SELECT_XBAR_CLIENT_SEL_OFFS 10 + +#define RTC_MEMORY_CTRL_REG_BASE 0xE6000 +#define RTC_MEMORY_WRAPPER_COUNT 8 +#define RTC_MEMORY_WRAPPER_REG(i) (RTC_MEMORY_CTRL_REG_BASE + ((i) * 0x40)) +#define RTC_MEMORY_CTRL_PDLVMC_FIELD_OFFS 6 +#define RTC_MEMORY_WRAPPER_CTRL_VAL (0x1 << RTC_MEMORY_CTRL_PDLVMC_FIELD_OFFS) + #define AVS_DEBUG_CNTR_REG 0xe4124 #define AVS_DEBUG_CNTR_DEFAULT_VALUE 0x08008073 diff --git a/arch/arm/mach-mvebu/spl.c b/arch/arm/mach-mvebu/spl.c index a99bf166fd..70fef3b573 100644 --- a/arch/arm/mach-mvebu/spl.c +++ b/arch/arm/mach-mvebu/spl.c @@ -130,6 +130,9 @@ void board_init_f(ulong dummy) /* Initialize Auto Voltage Scaling */ mv_avs_init(); + /* Update read timing control for PCIe */ + mv_rtc_config(); + /* * Return to the BootROM to continue the Marvell xmodem * UART boot protocol. As initiated by the kwboot tool. diff --git a/board/CZ.NIC/turris_mox/mox_sp.c b/board/CZ.NIC/turris_mox/mox_sp.c index 0b29ffcc67..3c23471e65 100644 --- a/board/CZ.NIC/turris_mox/mox_sp.c +++ b/board/CZ.NIC/turris_mox/mox_sp.c @@ -4,15 +4,17 @@ */ #include <common.h> +#include <asm/arch/soc.h> #include <asm/io.h> -#define RWTM_CMD_PARAM(i) (size_t)(0xd00b0000 + (i) * 4) -#define RWTM_CMD 0xd00b0040 -#define RWTM_CMD_RETSTATUS 0xd00b0080 -#define RWTM_CMD_STATUS(i) (size_t)(0xd00b0084 + (i) * 4) +#define RWTM_BASE (MVEBU_REGISTER(0xb0000)) +#define RWTM_CMD_PARAM(i) (size_t)(RWTM_BASE + (i) * 4) +#define RWTM_CMD (RWTM_BASE + 0x40) +#define RWTM_CMD_RETSTATUS (RWTM_BASE + 0x80) +#define RWTM_CMD_STATUS(i) (size_t)(RWTM_BASE + 0x84 + (i) * 4) -#define RWTM_HOST_INT_RESET 0xd00b00c8 -#define RWTM_HOST_INT_MASK 0xd00b00cc +#define RWTM_HOST_INT_RESET (RWTM_BASE + 0xc8) +#define RWTM_HOST_INT_MASK (RWTM_BASE + 0xcc) #define SP_CMD_COMPLETE BIT(0) #define MBOX_STS_SUCCESS (0x0 << 30) diff --git a/board/CZ.NIC/turris_mox/turris_mox.c b/board/CZ.NIC/turris_mox/turris_mox.c index 377191baef..470ea32f9c 100644 --- a/board/CZ.NIC/turris_mox/turris_mox.c +++ b/board/CZ.NIC/turris_mox/turris_mox.c @@ -4,18 +4,20 @@ */ #include <common.h> -#include <init.h> -#include <asm/gpio.h> +#include <asm/arch/cpu.h> +#include <asm/arch/soc.h> #include <asm/io.h> -#include <dm.h> +#include <asm/gpio.h> #include <clk.h> +#include <dm.h> #include <env.h> -#include <spi.h> -#include <mvebu/comphy.h> -#include <miiphy.h> -#include <linux/string.h> -#include <linux/libfdt.h> #include <fdt_support.h> +#include <init.h> +#include <linux/libfdt.h> +#include <linux/string.h> +#include <miiphy.h> +#include <mvebu/comphy.h> +#include <spi.h> #include "mox_sp.h" @@ -28,32 +30,20 @@ #define MOX_MODULE_USB3 0x5 #define MOX_MODULE_PASSPCI 0x6 -#define ARMADA_37XX_NB_GPIO_SEL 0xd0013830 -#define ARMADA_37XX_SPI_CTRL 0xd0010600 -#define ARMADA_37XX_SPI_CFG 0xd0010604 -#define ARMADA_37XX_SPI_DOUT 0xd0010608 -#define ARMADA_37XX_SPI_DIN 0xd001060c +#define ARMADA_37XX_NB_GPIO_SEL (MVEBU_REGISTER(0x13830)) +#define ARMADA_37XX_SPI_CTRL (MVEBU_REGISTER(0x10600)) +#define ARMADA_37XX_SPI_CFG (MVEBU_REGISTER(0x10604)) +#define ARMADA_37XX_SPI_DOUT (MVEBU_REGISTER(0x10608)) +#define ARMADA_37XX_SPI_DIN (MVEBU_REGISTER(0x1060c)) +#define ETH1_PATH "/soc/internal-regs@d0000000/ethernet@40000" +#define MDIO_PATH "/soc/internal-regs@d0000000/mdio@32004" +#define SFP_GPIO_PATH "/soc/internal-regs@d0000000/spi@10600/moxtet@1/gpio@0" #define PCIE_PATH "/soc/pcie@d0070000" +#define SFP_PATH "/sfp" DECLARE_GLOBAL_DATA_PTR; -int dram_init(void) -{ - gd->ram_base = 0; - gd->ram_size = (phys_size_t)get_ram_size(0, 0x40000000); - - return 0; -} - -int dram_init_banksize(void) -{ - gd->bd->bi_dram[0].start = (phys_addr_t)0; - gd->bd->bi_dram[0].size = gd->ram_size; - - return 0; -} - #if defined(CONFIG_OF_BOARD_FIXUP) int board_fix_fdt(void *blob) { @@ -67,9 +57,11 @@ int board_fix_fdt(void *blob) * to read SPI by reading/writing SPI registers directly */ - writel(0x563fa, ARMADA_37XX_NB_GPIO_SEL); writel(0x10df, ARMADA_37XX_SPI_CFG); - writel(0x2005b, ARMADA_37XX_SPI_CTRL); + /* put pin from GPIO to SPI mode */ + clrbits_le32(ARMADA_37XX_NB_GPIO_SEL, BIT(12)); + /* enable SPI CS1 */ + setbits_le32(ARMADA_37XX_SPI_CTRL, BIT(17)); while (!(readl(ARMADA_37XX_SPI_CTRL) & 0x2)) udelay(1); @@ -89,7 +81,8 @@ int board_fix_fdt(void *blob) size = i; - writel(0x5b, ARMADA_37XX_SPI_CTRL); + /* disable SPI CS1 */ + clrbits_le32(ARMADA_37XX_SPI_CTRL, BIT(17)); if (size > 1 && (topology[1] == MOX_MODULE_PCI || topology[1] == MOX_MODULE_USB3 || @@ -112,6 +105,11 @@ int board_fix_fdt(void *blob) return 0; } + if (a3700_fdt_fix_pcie_regions(blob) < 0) { + printf("Cannot fix PCIe regions in U-Boot's device tree!\n"); + return 0; + } + return 0; } #endif @@ -456,24 +454,22 @@ int last_stage_init(void) } break; case MOX_MODULE_PCI: - if (pci) { + if (pci) printf("Error: Only one Mini-PCIe module is supported!\n"); - } else if (usb) { + else if (usb) printf("Error: Mini-PCIe module cannot come after USB 3.0 module!\n"); - } else if (i && (i != 1 || !passpci)) { + else if (i && (i != 1 || !passpci)) printf("Error: Mini-PCIe module should be the first connected module or come right after Passthrough Mini-PCIe module!\n"); - } else { + else ++pci; - } break; case MOX_MODULE_TOPAZ: - if (topaz) { + if (topaz) printf("Error: Only one Topaz module is supported!\n"); - } else if (peridot >= 3) { + else if (peridot >= 3) printf("Error: At most two Peridot modules can come before Topaz module!\n"); - } else { + else ++topaz; - } break; case MOX_MODULE_PERIDOT: if (sfp || topaz) { @@ -486,24 +482,22 @@ int last_stage_init(void) } break; case MOX_MODULE_USB3: - if (pci) { + if (pci) printf("Error: USB 3.0 module cannot come after Mini-PCIe module!\n"); - } else if (usb) { + else if (usb) printf("Error: Only one USB 3.0 module is supported!\n"); - } else if (i && (i != 1 || !passpci)) { + else if (i && (i != 1 || !passpci)) printf("Error: USB 3.0 module should be the first connected module or come right after Passthrough Mini-PCIe module!\n"); - } else { + else ++usb; - } break; case MOX_MODULE_PASSPCI: - if (passpci) { + if (passpci) printf("Error: Only one Passthrough Mini-PCIe module is supported!\n"); - } else if (i != 0) { + else if (i != 0) printf("Error: Passthrough Mini-PCIe module should be the first connected module!\n"); - } else { + else ++passpci; - } } } @@ -548,3 +542,267 @@ int last_stage_init(void) return 0; } + +#if defined(CONFIG_OF_BOARD_SETUP) + +static int vnode_by_path(void *blob, const char *fmt, va_list ap) +{ + char path[128]; + + vsnprintf(path, 128, fmt, ap); + return fdt_path_offset(blob, path); +} + +static int node_by_path(void *blob, const char *fmt, ...) +{ + va_list ap; + int res; + + va_start(ap, fmt); + res = vnode_by_path(blob, fmt, ap); + va_end(ap); + + return res; +} + +static int phandle_by_path(void *blob, const char *fmt, ...) +{ + va_list ap; + int node, phandle, res; + + va_start(ap, fmt); + node = vnode_by_path(blob, fmt, ap); + va_end(ap); + + if (node < 0) + return node; + + phandle = fdt_get_phandle(blob, node); + if (phandle > 0) + return phandle; + + phandle = fdt_get_max_phandle(blob); + if (phandle < 0) + return phandle; + + phandle += 1; + + res = fdt_setprop_u32(blob, node, "linux,phandle", phandle); + if (res < 0) + return res; + + res = fdt_setprop_u32(blob, node, "phandle", phandle); + if (res < 0) + return res; + + return phandle; +} + +static int enable_by_path(void *blob, const char *fmt, ...) +{ + va_list ap; + int node; + + va_start(ap, fmt); + node = vnode_by_path(blob, fmt, ap); + va_end(ap); + + if (node < 0) + return node; + + return fdt_setprop_string(blob, node, "status", "okay"); +} + +static bool is_topaz(int id) +{ + return topaz && id == peridot + topaz - 1; +} + +static int switch_addr(int id) +{ + return is_topaz(id) ? 0x2 : 0x10 + id; +} + +static int setup_switch(void *blob, int id) +{ + int res, addr, i, node, phandle; + + addr = switch_addr(id); + + /* first enable the switch by setting status = "okay" */ + res = enable_by_path(blob, MDIO_PATH "/switch%i@%x", id, addr); + if (res < 0) + return res; + + /* + * now if there are more switches or a SFP module coming after, + * enable corresponding ports + */ + if (id < peridot + topaz - 1) { + res = enable_by_path(blob, + MDIO_PATH "/switch%i@%x/ports/port@a", + id, addr); + } else if (id == peridot - 1 && !topaz && sfp) { + res = enable_by_path(blob, + MDIO_PATH "/switch%i@%x/ports/port-sfp@a", + id, addr); + } else { + res = 0; + } + if (res < 0) + return res; + + if (id >= peridot + topaz - 1) + return 0; + + /* finally change link property if needed */ + node = node_by_path(blob, MDIO_PATH "/switch%i@%x/ports/port@a", id, + addr); + if (node < 0) + return node; + + for (i = id + 1; i < peridot + topaz; ++i) { + phandle = phandle_by_path(blob, + MDIO_PATH "/switch%i@%x/ports/port@%x", + i, switch_addr(i), + is_topaz(i) ? 5 : 9); + if (phandle < 0) + return phandle; + + if (i == id + 1) + res = fdt_setprop_u32(blob, node, "link", phandle); + else + res = fdt_appendprop_u32(blob, node, "link", phandle); + if (res < 0) + return res; + } + + return 0; +} + +static int remove_disabled_nodes(void *blob) +{ + while (1) { + int res, offset; + + offset = fdt_node_offset_by_prop_value(blob, -1, "status", + "disabled", 9); + if (offset < 0) + break; + + res = fdt_del_node(blob, offset); + if (res < 0) + return res; + } + + return 0; +} + +int ft_board_setup(void *blob, bd_t *bd) +{ + int node, phandle, res; + + /* + * If MOX B (PCI), MOX F (USB) or MOX G (Passthrough PCI) modules are + * connected, enable the PCIe node. + */ + if (pci || usb || passpci) { + node = fdt_path_offset(blob, PCIE_PATH); + if (node < 0) + return node; + + res = fdt_setprop_string(blob, node, "status", "okay"); + if (res < 0) + return res; + + /* Fix PCIe regions for devices with 4 GB RAM */ + res = a3700_fdt_fix_pcie_regions(blob); + if (res < 0) + return res; + } + + /* + * If MOX C (Topaz switch) and/or MOX E (Peridot switch) are connected, + * enable the eth1 node and setup the switches. + */ + if (peridot || topaz) { + int i; + + res = enable_by_path(blob, ETH1_PATH); + if (res < 0) + return res; + + for (i = 0; i < peridot + topaz; ++i) { + res = setup_switch(blob, i); + if (res < 0) + return res; + } + } + + /* + * If MOX D (SFP cage module) is connected, enable the SFP node and eth1 + * node. If there is no Peridot switch between MOX A and MOX D, add link + * to the SFP node to eth1 node. + * Also enable and configure SFP GPIO controller node. + */ + if (sfp) { + res = enable_by_path(blob, SFP_PATH); + if (res < 0) + return res; + + res = enable_by_path(blob, ETH1_PATH); + if (res < 0) + return res; + + if (!peridot) { + phandle = phandle_by_path(blob, SFP_PATH); + if (phandle < 0) + return res; + + node = node_by_path(blob, ETH1_PATH); + if (node < 0) + return node; + + res = fdt_setprop_u32(blob, node, "sfp", phandle); + if (res < 0) + return res; + + res = fdt_setprop_string(blob, node, "phy-mode", + "sgmii"); + if (res < 0) + return res; + } + + res = enable_by_path(blob, SFP_GPIO_PATH); + if (res < 0) + return res; + + if (sfp_pos) { + char newname[16]; + + /* moxtet-sfp is on non-zero position, change default */ + node = node_by_path(blob, SFP_GPIO_PATH); + if (node < 0) + return node; + + res = fdt_setprop_u32(blob, node, "reg", sfp_pos); + if (res < 0) + return res; + + sprintf(newname, "gpio@%x", sfp_pos); + + res = fdt_set_name(blob, node, newname); + if (res < 0) + return res; + } + } + + fdt_fixup_ethernet(blob); + + /* Finally remove disabled nodes, as per Rob Herring's request. */ + remove_disabled_nodes(blob); + + return 0; +} + +#endif diff --git a/board/alliedtelesis/x530/x530.c b/board/alliedtelesis/x530/x530.c index e0fa8067c1..04b053dc20 100644 --- a/board/alliedtelesis/x530/x530.c +++ b/board/alliedtelesis/x530/x530.c @@ -66,7 +66,11 @@ static struct mv_ddr_topology_map board_topology_map = { BUS_MASK_32BIT_ECC, /* subphys mask */ MV_DDR_CFG_DEFAULT, /* ddr configuration data source */ { {0} }, /* raw spd data */ - {0} /* timing parameters */ + {0}, /* timing parameters */ + { {0} }, /* electrical configuration */ + {0}, /* electrical parameters */ + 0, /* Clock enable mask */ + 160 /* Clock delay */ }; struct mv_ddr_topology_map *mv_ddr_topology_map_get(void) diff --git a/board/solidrun/clearfog/Kconfig b/board/solidrun/clearfog/Kconfig new file mode 100644 index 0000000000..e8c3f53d84 --- /dev/null +++ b/board/solidrun/clearfog/Kconfig @@ -0,0 +1,62 @@ +menu "ClearFog configuration" + depends on TARGET_CLEARFOG + +config TARGET_CLEARFOG_BASE + bool "Use ClearFog Base static configuration" + help + Use the ClearFog Base as the static configuration instead of the + default which uses the ClearFog Pro. + + Runtime board detection is always attempted and used if available. The + static configuration is used as a fallback in cases where runtime + detection is disabled, is not available in hardware, or otherwise fails. + + Only newer revisions of the ClearFog product line support runtime + detection via additional EEPROM hardware. This option enables selecting + the Base variant for older hardware revisions. + +config CLEARFOG_CON3_SATA + bool "Use CON3 slot in SATA mode" + help + Use the CON3 port with SATA protocol instead of the default PCIe. + The ClearFog port allows usage of either mSATA or miniPCIe + modules, but the desired protocol must be configured at build + time since it affects the SerDes topology layout. + +config CLEARFOG_CON2_SATA + bool "Use CON2 slot in SATA mode" + depends on !TARGET_CLEARFOG_BASE + help + Use the CON2 port with SATA protocol instead of the default PCIe. + The ClearFog port allows usage of either mSATA or miniPCIe + modules, but the desired protocol must be configured at build + time since it affects the SerDes topology layout. + +config CLEARFOG_SFP_25GB + bool "Enable 2.5 Gbps mode for SFP" + help + Set the SFP module connection to support 2.5 Gbps transfer speed for the + SGMII connection (requires a supporting SFP). By default, transfer speed + of 1.25 Gbps is used, suitable for a more common 1 Gbps SFP module. + +config ENV_SIZE + hex "Environment Size" + default 0x10000 + +config ENV_OFFSET + hex "Environment offset" + default 0xF0000 + +config ENV_SECT_SIZE + hex "Environment Sector-Size" + # Use SPI flash erase block size of 4 KiB + default 0x1000 if MVEBU_SPL_BOOT_DEVICE_SPI + # Use optimistic 64 KiB erase block, will vary between actual media + default 0x10000 if MVEBU_SPL_BOOT_DEVICE_MMC + +config SYS_SPI_U_BOOT_OFFS + hex "address of u-boot payload in SPI flash" + default 0x20000 + depends on MVEBU_SPL_BOOT_DEVICE_SPI + +endmenu diff --git a/board/solidrun/clearfog/clearfog.c b/board/solidrun/clearfog/clearfog.c index e268ef55a2..443751ba8f 100644 --- a/board/solidrun/clearfog/clearfog.c +++ b/board/solidrun/clearfog/clearfog.c @@ -42,6 +42,7 @@ static void cf_read_tlv_data(void) read_tlv_data(&cf_tlv_data); } +/* The starting board_serdes_map reflects original Clearfog Pro usage */ static struct serdes_map board_serdes_map[] = { {SATA0, SERDES_SPEED_3_GBPS, SERDES_DEFAULT_MODE, 0, 0}, {SGMII1, SERDES_SPEED_1_25_GBPS, SERDES_DEFAULT_MODE, 0, 0}, @@ -51,20 +52,60 @@ static struct serdes_map board_serdes_map[] = { {SGMII2, SERDES_SPEED_1_25_GBPS, SERDES_DEFAULT_MODE, 0, 0}, }; +void config_cfbase_serdes_map(void) +{ + board_serdes_map[4].serdes_type = USB3_HOST0; + board_serdes_map[4].serdes_speed = SERDES_SPEED_5_GBPS; + board_serdes_map[4].serdes_mode = SERDES_DEFAULT_MODE; +} + int hws_board_topology_load(struct serdes_map **serdes_map_array, u8 *count) { cf_read_tlv_data(); + /* Apply build configuration options before runtime configuration */ + if (IS_ENABLED(CONFIG_CLEARFOG_SFP_25GB)) + board_serdes_map[5].serdes_speed = SERDES_SPEED_3_125_GBPS; + + if (IS_ENABLED(CONFIG_CLEARFOG_CON2_SATA)) { + board_serdes_map[4].serdes_type = SATA2; + board_serdes_map[4].serdes_speed = SERDES_SPEED_3_GBPS; + board_serdes_map[4].serdes_mode = SERDES_DEFAULT_MODE; + board_serdes_map[4].swap_rx = 1; + } + + if (IS_ENABLED(CONFIG_CLEARFOG_CON3_SATA)) { + board_serdes_map[2].serdes_type = SATA1; + board_serdes_map[2].serdes_speed = SERDES_SPEED_3_GBPS; + board_serdes_map[2].serdes_mode = SERDES_DEFAULT_MODE; + board_serdes_map[2].swap_rx = 1; + } + + /* Apply runtime detection changes */ if (sr_product_is(&cf_tlv_data, "Clearfog GTR")) { board_serdes_map[0].serdes_type = PEX0; board_serdes_map[0].serdes_speed = SERDES_SPEED_5_GBPS; board_serdes_map[0].serdes_mode = PEX_ROOT_COMPLEX_X1; - } - - if (sr_product_is(&cf_tlv_data, "Clearfog Base")) { - board_serdes_map[4].serdes_type = USB3_HOST0; - board_serdes_map[4].serdes_speed = SERDES_SPEED_5_GBPS; - board_serdes_map[4].serdes_mode = SERDES_DEFAULT_MODE; + } else if (sr_product_is(&cf_tlv_data, "Clearfog Pro")) { + /* handle recognized product as noop, no adjustment required */ + } else if (sr_product_is(&cf_tlv_data, "Clearfog Base")) { + config_cfbase_serdes_map(); + } else { + /* + * Fallback to static default. EEPROM TLV support is not + * enabled, runtime detection failed, hardware support is not + * present, EEPROM is corrupt, or an unrecognized product name + * is present. + */ + if (IS_ENABLED(CONFIG_SPL_CMD_TLV_EEPROM)) + puts("EEPROM TLV detection failed: "); + puts("Using static config for "); + if (IS_ENABLED(CONFIG_TARGET_CLEARFOG_BASE)) { + puts("Clearfog Base.\n"); + config_cfbase_serdes_map(); + } else { + puts("Clearfog Pro.\n"); + } } *serdes_map_array = board_serdes_map; @@ -170,7 +211,9 @@ int board_init(void) int checkboard(void) { - char *board = "ClearFog"; + char *board = "Clearfog Pro"; + if (IS_ENABLED(CONFIG_TARGET_CLEARFOG_BASE)) + board = "Clearfog Base"; cf_read_tlv_data(); if (strlen(cf_tlv_data.tlv_product_name[0]) > 0) @@ -200,6 +243,10 @@ int board_late_init(void) env_set("fdtfile", "armada-385-clearfog-gtr-s4.dtb"); else if (sr_product_is(&cf_tlv_data, "Clearfog GTR L8")) env_set("fdtfile", "armada-385-clearfog-gtr-l8.dtb"); + else if (IS_ENABLED(CONFIG_TARGET_CLEARFOG_BASE)) + env_set("fdtfile", "armada-388-clearfog-base.dtb"); + else + env_set("fdtfile", "armada-388-clearfog-pro.dtb"); return 0; } diff --git a/configs/clearfog_defconfig b/configs/clearfog_defconfig index c938448c30..6db8b8acf6 100644 --- a/configs/clearfog_defconfig +++ b/configs/clearfog_defconfig @@ -9,8 +9,6 @@ CONFIG_SPL_LIBGENERIC_SUPPORT=y CONFIG_SYS_MALLOC_F_LEN=0x2000 CONFIG_TARGET_CLEARFOG=y CONFIG_MVEBU_SPL_BOOT_DEVICE_MMC=y -CONFIG_ENV_SIZE=0x10000 -CONFIG_ENV_OFFSET=0xF0000 CONFIG_DM_GPIO=y CONFIG_SPL_MMC_SUPPORT=y CONFIG_SPL_SERIAL_SUPPORT=y diff --git a/configs/turris_mox_defconfig b/configs/turris_mox_defconfig index 2e637044c1..d786255d1d 100644 --- a/configs/turris_mox_defconfig +++ b/configs/turris_mox_defconfig @@ -8,7 +8,7 @@ CONFIG_ENV_SIZE=0x10000 CONFIG_ENV_SECT_SIZE=0x10000 CONFIG_ENV_OFFSET=0x180000 CONFIG_DM_GPIO=y -CONFIG_NR_DRAM_BANKS=1 +CONFIG_NR_DRAM_BANKS=2 CONFIG_DEBUG_UART_BASE=0xd0012000 CONFIG_DEBUG_UART_CLOCK=25804800 CONFIG_DEBUG_UART=y @@ -37,6 +37,7 @@ CONFIG_CMD_BTRFS=y CONFIG_CMD_EXT4_WRITE=y CONFIG_MAC_PARTITION=y CONFIG_OF_BOARD_FIXUP=y +CONFIG_OF_BOARD_SETUP=y CONFIG_DEFAULT_DEVICE_TREE="armada-3720-turris-mox" CONFIG_ENV_IS_IN_SPI_FLASH=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y diff --git a/drivers/ddr/marvell/a38x/ddr3_init.c b/drivers/ddr/marvell/a38x/ddr3_init.c index 22c8f9ca54..a971cc155a 100644 --- a/drivers/ddr/marvell/a38x/ddr3_init.c +++ b/drivers/ddr/marvell/a38x/ddr3_init.c @@ -106,8 +106,10 @@ static int mv_ddr_training_params_set(u8 dev_num) struct tune_train_params params; int status; u32 cs_num; + int ck_delay; cs_num = mv_ddr_cs_num_get(); + ck_delay = mv_ddr_ck_delay_get(); /* NOTE: do not remove any field initilization */ params.ck_delay = TUNE_TRAINING_PARAMS_CK_DELAY; @@ -131,6 +133,9 @@ static int mv_ddr_training_params_set(u8 dev_num) params.g_odt_config = TUNE_TRAINING_PARAMS_ODT_CONFIG_2CS; } + if (ck_delay > 0) + params.ck_delay = ck_delay; + status = ddr3_tip_tune_training_params(dev_num, ¶ms); if (MV_OK != status) { printf("%s Training Sequence - FAILED\n", ddr_type); diff --git a/drivers/ddr/marvell/a38x/ddr_topology_def.h b/drivers/ddr/marvell/a38x/ddr_topology_def.h index 950f296ff9..34196b1662 100644 --- a/drivers/ddr/marvell/a38x/ddr_topology_def.h +++ b/drivers/ddr/marvell/a38x/ddr_topology_def.h @@ -127,6 +127,9 @@ struct mv_ddr_topology_map { /* Clock enable mask */ u32 clk_enable; + + /* Clock delay */ + int ck_delay; }; enum mv_ddr_iface_mode { diff --git a/drivers/ddr/marvell/a38x/mv_ddr_topology.c b/drivers/ddr/marvell/a38x/mv_ddr_topology.c index ef3b658a78..09840b1e70 100644 --- a/drivers/ddr/marvell/a38x/mv_ddr_topology.c +++ b/drivers/ddr/marvell/a38x/mv_ddr_topology.c @@ -229,6 +229,16 @@ int mv_ddr_is_ecc_ena(void) return 0; } +int mv_ddr_ck_delay_get(void) +{ + struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get(); + + if (tm->ck_delay) + return tm->ck_delay; + + return -1; +} + /* translate topology map definition to real memory size in bits */ static unsigned int mem_size[] = { ADDR_SIZE_512MB, diff --git a/drivers/ddr/marvell/a38x/mv_ddr_topology.h b/drivers/ddr/marvell/a38x/mv_ddr_topology.h index 766f25db57..4fca47689f 100644 --- a/drivers/ddr/marvell/a38x/mv_ddr_topology.h +++ b/drivers/ddr/marvell/a38x/mv_ddr_topology.h @@ -319,6 +319,7 @@ unsigned short mv_ddr_bus_bit_mask_get(void); unsigned int mv_ddr_if_bus_width_get(void); unsigned int mv_ddr_cs_num_get(void); int mv_ddr_is_ecc_ena(void); +int mv_ddr_ck_delay_get(void); unsigned long long mv_ddr_mem_sz_per_cs_get(void); unsigned long long mv_ddr_mem_sz_get(void); unsigned int mv_ddr_rtt_nom_get(void); diff --git a/drivers/ddr/marvell/axp/ddr3_init.c b/drivers/ddr/marvell/axp/ddr3_init.c index 13df9126e7..30ad5d4151 100644 --- a/drivers/ddr/marvell/axp/ddr3_init.c +++ b/drivers/ddr/marvell/axp/ddr3_init.c @@ -435,10 +435,6 @@ static u32 ddr3_init_main(void) #endif #if defined(ECC_SUPPORT) && defined(AUTO_DETECTION_SUPPORT) - ecc = DRAM_ECC; -#endif - -#if defined(ECC_SUPPORT) && defined(AUTO_DETECTION_SUPPORT) ecc = 0; if (ddr3_check_config(BUS_WIDTH_ECC_TWSI_ADDR, CONFIG_ECC)) ecc = 1; diff --git a/include/configs/clearfog.h b/include/configs/clearfog.h index 633187d86f..8314956db6 100644 --- a/include/configs/clearfog.h +++ b/include/configs/clearfog.h @@ -104,15 +104,59 @@ #define BOOT_TARGET_DEVICES_MMC(func) #endif +#ifdef CONFIG_SCSI +#define BOOT_TARGET_DEVICES_SCSI(func) func(SCSI, scsi, 0) +#else +#define BOOT_TARGET_DEVICES_SCSI(func) +#endif + #ifdef CONFIG_USB_STORAGE #define BOOT_TARGET_DEVICES_USB(func) func(USB, usb, 0) #else #define BOOT_TARGET_DEVICES_USB(func) #endif +#ifndef CONFIG_SCSI +#define BOOT_TARGET_DEVICES_SCSI_BUS0(func) +#define BOOT_TARGET_DEVICES_SCSI_BUS1(func) +#define BOOT_TARGET_DEVICES_SCSI_BUS2(func) +#else +/* + * With SCSI enabled, M.2 SATA is always located on bus 0 + */ +#define BOOT_TARGET_DEVICES_SCSI_BUS0(func) func(SCSI, scsi, 0) + +/* + * Either one or both mPCIe slots may be configured as mSATA interfaces. The + * SCSI bus ids are assigned based on sequence of hardware present, not always + * tied to hardware slot ids. As such, use second SCSI bus if either slot is + * set for SATA, and only use third SCSI bus if both slots are SATA enabled. + */ +#if defined (CONFIG_CLEARFOG_CON2_SATA) || defined (CONFIG_CLEARFOG_CON3_SATA) +#define BOOT_TARGET_DEVICES_SCSI_BUS1(func) func(SCSI, scsi, 1) +#else +#define BOOT_TARGET_DEVICES_SCSI_BUS1(func) +#endif + +#if defined (CONFIG_CLEARFOG_CON2_SATA) && defined (CONFIG_CLEARFOG_CON3_SATA) +#define BOOT_TARGET_DEVICES_SCSI_BUS2(func) func(SCSI, scsi, 2) +#else +#define BOOT_TARGET_DEVICES_SCSI_BUS2(func) +#endif + +#endif /* CONFIG_SCSI */ + +/* + * The SCSI buses are attempted in increasing bus order, there is no current + * mechanism to alter the default bus priority order for booting. + */ #define BOOT_TARGET_DEVICES(func) \ BOOT_TARGET_DEVICES_MMC(func) \ + BOOT_TARGET_DEVICES_SCSI(func) \ BOOT_TARGET_DEVICES_USB(func) \ + BOOT_TARGET_DEVICES_SCSI_BUS0(func) \ + BOOT_TARGET_DEVICES_SCSI_BUS1(func) \ + BOOT_TARGET_DEVICES_SCSI_BUS2(func) \ func(PXE, pxe, na) \ func(DHCP, dhcp, na) @@ -134,7 +178,6 @@ #define CONFIG_EXTRA_ENV_SETTINGS \ RELOCATION_LIMITS_ENV_SETTINGS \ LOAD_ADDRESS_ENV_SETTINGS \ - "fdtfile=" CONFIG_DEFAULT_DEVICE_TREE ".dtb\0" \ "console=ttyS0,115200\0" \ BOOTENV |