summaryrefslogtreecommitdiff
path: root/arch/arm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/dts/Makefile20
-rw-r--r--arch/arm/dts/armada-3720-turris-mox.dts19
-rw-r--r--arch/arm/dts/armada-38x-solidrun-microsom.dtsi1
-rw-r--r--arch/arm/mach-mvebu/Kconfig2
-rw-r--r--arch/arm/mach-mvebu/arm64-common.c51
-rw-r--r--arch/arm/mach-mvebu/armada3700/cpu.c304
-rw-r--r--arch/arm/mach-mvebu/armada8k/Makefile3
-rw-r--r--arch/arm/mach-mvebu/armada8k/dram.c52
-rw-r--r--arch/arm/mach-mvebu/include/mach/cpu.h13
-rw-r--r--arch/arm/mach-mvebu/serdes/a38x/high_speed_env_spec.c6
-rw-r--r--arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.c17
-rw-r--r--arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.h13
-rw-r--r--arch/arm/mach-mvebu/spl.c3
13 files changed, 418 insertions, 86 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 @@
&eth0 {
/* 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.