mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-11 07:34:31 +00:00
Merge branch 'master' of git://git.denx.de/u-boot-marvell
- Misc enhancements to Clearfog, including board variant detection (Joel) - Misc enhancements to Turris Mox, including generalization of the ARMADA37xx DDR size detection (Marek)
This commit is contained in:
commit
142a07f2a4
26 changed files with 920 additions and 158 deletions
|
@ -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 \
|
||||
|
|
|
@ -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";
|
||||
};
|
||||
|
||||
|
|
|
@ -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>;
|
||||
|
|
|
@ -280,4 +280,6 @@ config SECURED_MODE_CSK_INDEX
|
|||
default 0
|
||||
depends on SECURED_MODE_IMAGE
|
||||
|
||||
source "board/solidrun/clearfog/Kconfig"
|
||||
|
||||
endif
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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[] = {
|
||||
/* 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] = {
|
||||
{
|
||||
/* RAM */
|
||||
.phys = 0x0UL,
|
||||
.virt = 0x0UL,
|
||||
.size = 0x80000000UL,
|
||||
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
|
||||
PTE_BLOCK_INNER_SHARE
|
||||
},
|
||||
{
|
||||
/* 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
|
||||
.attrs = A3700_PTE_BLOCK_DEVICE
|
||||
},
|
||||
{
|
||||
/* PCI regions */
|
||||
.phys = 0xe8000000UL,
|
||||
.virt = 0xe8000000UL,
|
||||
.size = 0x02000000UL, /* 32MiB master PCI space */
|
||||
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
|
||||
PTE_BLOCK_NON_SHARE
|
||||
},
|
||||
{
|
||||
/* 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)
|
||||
{
|
||||
/*
|
||||
|
|
|
@ -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
|
||||
|
|
52
arch/arm/mach-mvebu/armada8k/dram.c
Normal file
52
arch/arm/mach-mvebu/armada8k/dram.c
Normal file
|
@ -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;
|
||||
}
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
62
board/solidrun/clearfog/Kconfig
Normal file
62
board/solidrun/clearfog/Kconfig
Normal file
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -434,10 +434,6 @@ static u32 ddr3_init_main(void)
|
|||
scrub_size = 0;
|
||||
#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))
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in a new issue