summaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-at91
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2021-05-17 16:23:49 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2021-05-17 16:23:49 +0200
commit82e29d615600621d7aca7d3fb1016feb8762f030 (patch)
tree72c9aae719572fc625b7aa8412a99994d5678d62 /arch/arm/mach-at91
parent605737eceb5af862ddffc8659629c3587de94d1d (diff)
parent5837dcc2e04edfbf1b6fa3ceb5553d60d027cc82 (diff)
downloadbarebox-82e29d615600621d7aca7d3fb1016feb8762f030.tar.gz
barebox-82e29d615600621d7aca7d3fb1016feb8762f030.tar.xz
Merge branch 'for-next/at91'
Diffstat (limited to 'arch/arm/mach-at91')
-rw-r--r--arch/arm/mach-at91/Kconfig2
-rw-r--r--arch/arm/mach-at91/Makefile1
-rw-r--r--arch/arm/mach-at91/ddramc.c8
-rw-r--r--arch/arm/mach-at91/include/mach/ddramc.h1
-rw-r--r--arch/arm/mach-at91/include/mach/sama5_bootsource.h3
-rw-r--r--arch/arm/mach-at91/include/mach/sama5d3-xplained-ddramc.h88
-rw-r--r--arch/arm/mach-at91/include/mach/sama5d3_ll.h24
-rw-r--r--arch/arm/mach-at91/include/mach/xload.h4
-rw-r--r--arch/arm/mach-at91/sama5d3_ll.c34
-rw-r--r--arch/arm/mach-at91/xload-mmc.c51
10 files changed, 216 insertions, 0 deletions
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 810c00d495..28a82c1a93 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -45,6 +45,7 @@ config HAVE_AT91_DDRAMC
config AT91_MCI_PBL
bool
+ depends on MCI_ATMEL_PBL
depends on MCI_ATMEL_SDHCI_PBL
default y
@@ -610,6 +611,7 @@ config MACH_MICROCHIP_KSZ9477_EVB
bool "Microchip EVB-KSZ9477 Evaluation Kit"
select SOC_SAMA5D3
select OFDEVICE
+ select MCI_ATMEL_PBL
select COMMON_CLK_OF_PROVIDER
help
Select this if you are using Microchip's EVB-KSZ9477 Evaluation Kit.
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
index 9cfba28fa0..c895af7a2f 100644
--- a/arch/arm/mach-at91/Makefile
+++ b/arch/arm/mach-at91/Makefile
@@ -30,6 +30,7 @@ obj-$(CONFIG_SOC_SAMA5D3) += sama5d3.o sama5d3_devices.o
endif
lwl-$(CONFIG_SOC_SAMA5D2) += sama5d2_ll.o
obj-$(CONFIG_SOC_SAMA5D2) += sama5d2.o
+lwl-$(CONFIG_SOC_SAMA5D3) += sama5d3_ll.o
obj-$(CONFIG_SOC_AT91SAM9G20) += at91sam9260.o at91sam9260_devices.o
obj-$(CONFIG_SOC_AT91SAM9G45) += at91sam9g45.o at91sam9g45_devices.o
obj-$(CONFIG_SOC_AT91SAM9X5) += at91sam9x5.o at91sam9x5_devices.o
diff --git a/arch/arm/mach-at91/ddramc.c b/arch/arm/mach-at91/ddramc.c
index c3ef6b0090..0aece5345f 100644
--- a/arch/arm/mach-at91/ddramc.c
+++ b/arch/arm/mach-at91/ddramc.c
@@ -26,6 +26,14 @@ void __noreturn sama5d2_barebox_entry(unsigned int r4, void *boarddata)
boarddata);
}
+void __noreturn sama5d3_barebox_entry(unsigned int r4, void *boarddata)
+{
+ __sama5d3_stashed_bootrom_r4 = r4;
+
+ barebox_arm_entry(SAMA5_DDRCS, at91sama5d3_get_ddram_size(),
+ boarddata);
+}
+
static int sama5_ddr_probe(struct device_d *dev)
{
struct resource *iores;
diff --git a/arch/arm/mach-at91/include/mach/ddramc.h b/arch/arm/mach-at91/include/mach/ddramc.h
index 5d6f3a70b7..7daef17636 100644
--- a/arch/arm/mach-at91/include/mach/ddramc.h
+++ b/arch/arm/mach-at91/include/mach/ddramc.h
@@ -33,5 +33,6 @@ void at91_lpddr1_sdram_initialize(void __iomem *base_address,
const struct at91_ddramc_register *ddramc_config);
void __noreturn sama5d2_barebox_entry(unsigned int r4, void *boarddata);
+void __noreturn sama5d3_barebox_entry(unsigned int r4, void *boarddata);
#endif /* #ifndef __DDRAMC_H__ */
diff --git a/arch/arm/mach-at91/include/mach/sama5_bootsource.h b/arch/arm/mach-at91/include/mach/sama5_bootsource.h
index 8355c2eeb6..931e1f29c8 100644
--- a/arch/arm/mach-at91/include/mach/sama5_bootsource.h
+++ b/arch/arm/mach-at91/include/mach/sama5_bootsource.h
@@ -46,6 +46,9 @@ static inline int sama5_bootsource_instance(u32 reg)
#define __sama5d2_stashed_bootrom_r4 \
(*(volatile u32 *)(SAMA5D2_SRAM_BASE + SAMA5D2_SRAM_SIZE - 0x4))
+#define __sama5d3_stashed_bootrom_r4 \
+ (*(volatile u32 *)(SAMA5D3_SRAM_BASE + SAMA5D3_SRAM_SIZE - 0x4))
+
static inline void __noreturn sama5_boot_xload(void __noreturn (*bb)(void), u32 r4)
{
asm volatile("mov r4, %0" : : "r"(r4) : );
diff --git a/arch/arm/mach-at91/include/mach/sama5d3-xplained-ddramc.h b/arch/arm/mach-at91/include/mach/sama5d3-xplained-ddramc.h
new file mode 100644
index 0000000000..6f829282c6
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/sama5d3-xplained-ddramc.h
@@ -0,0 +1,88 @@
+/* SPDX-License-Identifier: BSD-1-Clause
+ *
+ * Copyright (C) 2014, Atmel Corporation
+ *
+ * SAMA5D27 System-in-Package DDRAMC configuration
+ */
+
+#include <mach/at91_ddrsdrc.h>
+#include <mach/ddramc.h>
+#include <mach/sama5d3_ll.h>
+
+static inline void sama5d3_xplained_ddrconf(void)
+{
+ const struct at91_ddramc_register conf = {
+ .mdr = AT91_DDRC2_DBW_32_BITS | AT91_DDRC2_MD_DDR2_SDRAM,
+
+ .cr = AT91_DDRC2_NC_DDR10_SDR9
+ | AT91_DDRC2_NR_13
+ | AT91_DDRC2_CAS_3
+ | AT91_DDRC2_DISABLE_RESET_DLL
+ | AT91_DDRC2_ENABLE_DLL
+ | AT91_DDRC2_ENRDM_ENABLE
+ | AT91_DDRC2_NB_BANKS_8
+ | AT91_DDRC2_NDQS_DISABLED
+ | AT91_DDRC2_DECOD_INTERLEAVED
+ | AT91_DDRC2_UNAL_SUPPORTED,
+
+ /*
+ * The DDR2-SDRAM device requires a refresh every 15.625 us or 7.81 us.
+ * With a 133 MHz frequency, the refresh timer count register must to be
+ * set with (15.625 x 133 MHz) ~ 2084 i.e. 0x824
+ * or (7.81 x 133 MHz) ~ 1039 i.e. 0x40F.
+ */
+ .rtr = 0x40F, /* Refresh timer: 7.812us */
+
+ /* One clock cycle @ 133 MHz = 7.5 ns */
+ .t0pr = AT91_DDRC2_TRAS_(6) /* 6 * 7.5 = 45 ns */
+ | AT91_DDRC2_TRCD_(2) /* 2 * 7.5 = 22.5 ns */
+ | AT91_DDRC2_TWR_(2) /* 2 * 7.5 = 15 ns */
+ | AT91_DDRC2_TRC_(8) /* 8 * 7.5 = 75 ns */
+ | AT91_DDRC2_TRP_(2) /* 2 * 7.5 = 15 ns */
+ | AT91_DDRC2_TRRD_(2) /* 2 * 7.5 = 15 ns */
+ | AT91_DDRC2_TWTR_(2) /* 2 clock cycles min */
+ | AT91_DDRC2_TMRD_(2), /* 2 clock cycles */
+
+ .t1pr = AT91_DDRC2_TXP_(2) /* 2 clock cycles */
+ | AT91_DDRC2_TXSRD_(200) /* 200 clock cycles */
+ | AT91_DDRC2_TXSNR_(19) /* 19 * 7.5 = 142.5 ns */
+ | AT91_DDRC2_TRFC_(17), /* 17 * 7.5 = 127.5 ns */
+
+ .t2pr = AT91_DDRC2_TFAW_(6) /* 6 * 7.5 = 45 ns */
+ | AT91_DDRC2_TRTP_(2) /* 2 clock cycles min */
+ | AT91_DDRC2_TRPA_(2) /* 2 * 7.5 = 15 ns */
+ | AT91_DDRC2_TXARDS_(8) /* = TXARD */
+ | AT91_DDRC2_TXARD_(8), /* MR12 = 1 */
+ };
+ u32 reg;
+
+ /* enable ddr2 clock */
+ sama5d3_pmc_enable_periph_clock(SAMA5D3_ID_MPDDRC);
+ at91_pmc_enable_system_clock(IOMEM(SAMA5D3_BASE_PMC), AT91CAP9_PMC_DDR);
+
+
+ /* Init the special register for sama5d3x */
+ /* MPDDRC DLL Slave Offset Register: DDR2 configuration */
+ reg = AT91_MPDDRC_S0OFF_1
+ | AT91_MPDDRC_S2OFF_1
+ | AT91_MPDDRC_S3OFF_1;
+ writel(reg, SAMA5D3_BASE_MPDDRC + AT91_MPDDRC_DLL_SOR);
+
+ /* MPDDRC DLL Master Offset Register */
+ /* write master + clk90 offset */
+ reg = AT91_MPDDRC_MOFF_7
+ | AT91_MPDDRC_CLK90OFF_31
+ | AT91_MPDDRC_SELOFF_ENABLED | AT91_MPDDRC_KEY;
+ writel(reg, SAMA5D3_BASE_MPDDRC + AT91_MPDDRC_DLL_MOR);
+
+ /* MPDDRC I/O Calibration Register */
+ /* DDR2 RZQ = 50 Ohm */
+ /* TZQIO = 4 */
+ reg = AT91_MPDDRC_RDIV_DDR2_RZQ_50
+ | AT91_MPDDRC_TZQIO_4;
+ writel(reg, SAMA5D3_BASE_MPDDRC + AT91_MPDDRC_IO_CALIBR);
+
+ /* DDRAM2 Controller initialize */
+ at91_ddram_initialize(IOMEM(SAMA5D3_BASE_MPDDRC), IOMEM(SAMA5_DDRCS),
+ &conf);
+}
diff --git a/arch/arm/mach-at91/include/mach/sama5d3_ll.h b/arch/arm/mach-at91/include/mach/sama5d3_ll.h
new file mode 100644
index 0000000000..b5b6b5d820
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/sama5d3_ll.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#ifndef __SAMA5D3_LL_H__
+#define __SAMA5D3_LL_H__
+
+#include <mach/at91_pmc_ll.h>
+#include <mach/debug_ll.h>
+#include <mach/early_udelay.h>
+
+void sama5d3_lowlevel_init(void);
+
+static inline void sama5d3_pmc_enable_periph_clock(int clk)
+{
+ at91_pmc_enable_periph_clock(IOMEM(SAMA5D3_BASE_PMC), clk);
+}
+
+/* requires relocation */
+static inline void sama5d3_udelay_init(unsigned int msc)
+{
+ early_udelay_init(IOMEM(SAMA5D3_BASE_PMC), IOMEM(SAMA5D3_BASE_PIT),
+ SAMA5D3_ID_PIT, msc, AT91_PMC_LL_SAMA5D3);
+}
+
+#endif /* __SAMA5D3_LL_H__ */
diff --git a/arch/arm/mach-at91/include/mach/xload.h b/arch/arm/mach-at91/include/mach/xload.h
index 338577c221..bbc70af210 100644
--- a/arch/arm/mach-at91/include/mach/xload.h
+++ b/arch/arm/mach-at91/include/mach/xload.h
@@ -5,7 +5,11 @@
#include <pbl.h>
void __noreturn sama5d2_sdhci_start_image(u32 r4);
+void __noreturn sama5d3_atmci_start_image(u32 r4, unsigned int clock,
+ unsigned int slot);
int at91_sdhci_bio_init(struct pbl_bio *bio, void __iomem *base);
+int at91_mci_bio_init(struct pbl_bio *bio, void __iomem *base,
+ unsigned int clock, unsigned int slot);
#endif /* __MACH_XLOAD_H */
diff --git a/arch/arm/mach-at91/sama5d3_ll.c b/arch/arm/mach-at91/sama5d3_ll.c
new file mode 100644
index 0000000000..4650593699
--- /dev/null
+++ b/arch/arm/mach-at91/sama5d3_ll.c
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: GPL-2.0-only AND BSD-1-Clause
+// SPDX-FileCopyrightText: 2017, Microchip Corporation
+
+#include <mach/at91_wdt.h>
+#include <mach/barebox-arm.h>
+#include <mach/sama5d3_ll.h>
+
+void sama5d3_lowlevel_init(void)
+{
+ arm_cpu_lowlevel_init();
+
+ at91_wdt_disable(IOMEM(SAMA5D3_BASE_WDT));
+ at91_pmc_init(IOMEM(SAMA5D3_BASE_PMC), AT91_PMC_LL_SAMA5D3);
+
+ /* At this stage the main oscillator
+ * is supposed to be enabled PCK = MCK = MOSC
+ */
+
+ /* Configure PLLA = MOSC * (PLL_MULA + 1) / PLL_DIVA */
+ at91_pmc_cfg_plla(IOMEM(SAMA5D3_BASE_PMC), AT91_PMC3_MUL_(43)
+ | AT91_PMC_OUT_0 | AT91_PMC_PLLCOUNT
+ | AT91_PMC_DIV_BYPASS, AT91_PMC_LL_SAMA5D3);
+
+ /* Initialize PLLA charge pump */
+ at91_pmc_init_pll(IOMEM(SAMA5D3_BASE_PMC), AT91_PMC_IPLLA_3);
+
+ /* Switch PCK/MCK on Main clock output */
+ at91_pmc_cfg_mck(IOMEM(SAMA5D3_BASE_PMC), AT91SAM9_PMC_MDIV_4
+ | AT91_PMC_CSS_MAIN, AT91_PMC_LL_SAMA5D3);
+
+ /* Switch PCK/MCK on PLLA output */
+ at91_pmc_cfg_mck(IOMEM(SAMA5D3_BASE_PMC), AT91SAM9_PMC_MDIV_4
+ | AT91_PMC_CSS_PLLA, AT91_PMC_LL_SAMA5D3);
+}
diff --git a/arch/arm/mach-at91/xload-mmc.c b/arch/arm/mach-at91/xload-mmc.c
index e9edeccb7f..8d4f653d1e 100644
--- a/arch/arm/mach-at91/xload-mmc.c
+++ b/arch/arm/mach-at91/xload-mmc.c
@@ -3,6 +3,7 @@
#include <mach/sama5_bootsource.h>
#include <mach/hardware.h>
#include <mach/sama5d2_ll.h>
+#include <mach/sama5d3_ll.h>
#include <mach/gpio.h>
#include <linux/sizes.h>
#include <asm/cache.h>
@@ -82,3 +83,53 @@ void __noreturn sama5d2_sdhci_start_image(u32 r4)
out_panic:
panic("FAT chainloading failed\n");
}
+
+static const struct atmci_instance {
+ void __iomem *base;
+ unsigned id;
+ u8 periph;
+ s8 pins[15];
+} sama5d3_atmci_instances[] = {
+ [0] = {
+ .base = IOMEM(SAMA5D3_BASE_HSMCI0),
+ .id = SAMA5D3_ID_HSMCI0,
+ .periph = AT91_MUX_PERIPH_A,
+ .pins = {
+ AT91_PIN_PD0, AT91_PIN_PD1, AT91_PIN_PD2, AT91_PIN_PD3,
+ AT91_PIN_PD4, AT91_PIN_PD5, AT91_PIN_PD6, AT91_PIN_PD7,
+ AT91_PIN_PD8, AT91_PIN_PD9, -1 }
+ },
+};
+
+void __noreturn sama5d3_atmci_start_image(u32 boot_src, unsigned int clock,
+ unsigned int slot)
+{
+ void *buf = (void *)SAMA5_DDRCS;
+ const struct atmci_instance *instance;
+ struct pbl_bio bio;
+ const s8 *pin;
+ int ret;
+
+ ret = sama5_bootsource_instance(boot_src);
+ if (ret > ARRAY_SIZE(sama5d3_atmci_instances) - 1)
+ panic("Couldn't determine boot MCI instance\n");
+
+ instance = &sama5d3_atmci_instances[boot_src];
+
+ sama5d3_pmc_enable_periph_clock(SAMA5D2_ID_PIOD);
+ for (pin = instance->pins; *pin >= 0; pin++) {
+ at91_mux_pio3_pin(IOMEM(SAMA5D3_BASE_PIOD),
+ pin_to_mask(*pin), instance->periph, 0);
+ }
+
+ sama5d3_pmc_enable_periph_clock(instance->id);
+
+ ret = at91_mci_bio_init(&bio, instance->base, clock, slot);
+ if (ret)
+ goto out_panic;
+
+ at91_fat_start_image(&bio, buf, SZ_16M, boot_src);
+
+out_panic:
+ panic("FAT chainloading failed\n");
+}