summaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2020-07-27 21:58:14 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2020-07-27 21:58:14 +0200
commite41d307e072de3642c0ce293ef3786ff1340440b (patch)
tree8bdd95ae53fc5cd6db7dae46058f545131d992b4 /arch/arm
parent3322880d50b964c17021f9a6089d191b6cf1586b (diff)
parent424b33c88b90fe656dbe2c3a9c954ea6d4f7479b (diff)
downloadbarebox-e41d307e072de3642c0ce293ef3786ff1340440b.tar.gz
barebox-e41d307e072de3642c0ce293ef3786ff1340440b.tar.xz
Merge branch 'for-next/at91'
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/boards/at91sam9m10g45ek/lowlevel.c2
-rw-r--r--arch/arm/boards/at91sam9m10ihd/lowlevel.c2
-rw-r--r--arch/arm/boards/at91sam9n12ek/lowlevel.c2
-rw-r--r--arch/arm/boards/at91sam9x5ek/lowlevel.c3
-rw-r--r--arch/arm/boards/pm9g45/lowlevel.c3
-rw-r--r--arch/arm/boards/sama5d27-giantboard/Makefile2
-rw-r--r--arch/arm/boards/sama5d27-giantboard/board.c17
-rw-r--r--arch/arm/boards/sama5d27-giantboard/defaultenv-giantboard/nv/boot.default1
-rw-r--r--arch/arm/boards/sama5d27-giantboard/lowlevel.c51
-rw-r--r--arch/arm/boards/sama5d27-som1/Makefile1
-rw-r--r--arch/arm/boards/sama5d27-som1/board.c35
-rw-r--r--arch/arm/boards/sama5d27-som1/lowlevel.c61
-rw-r--r--arch/arm/boards/sama5d3_xplained/lowlevel.c2
-rw-r--r--arch/arm/boards/sama5d3xek/lowlevel.c2
-rw-r--r--arch/arm/boards/sama5d4_xplained/lowlevel.c2
-rw-r--r--arch/arm/boards/sama5d4ek/lowlevel.c2
-rw-r--r--arch/arm/dts/at91-sama5d27_giantboard.dts10
-rw-r--r--arch/arm/dts/at91-sama5d27_som1_ek.dts47
-rw-r--r--arch/arm/dts/sama5d2.dtsi10
-rw-r--r--arch/arm/mach-at91/Kconfig11
-rw-r--r--arch/arm/mach-at91/Makefile9
-rw-r--r--arch/arm/mach-at91/aic.c28
-rw-r--r--arch/arm/mach-at91/at91_pmc_ll.c169
-rw-r--r--arch/arm/mach-at91/at91sam9_reset.S1
-rw-r--r--arch/arm/mach-at91/at91sam9_rst.c30
-rw-r--r--arch/arm/mach-at91/at91sam9g45_devices.c2
-rw-r--r--arch/arm/mach-at91/at91sam9g45_reset.S9
-rw-r--r--arch/arm/mach-at91/at91sam9n12_devices.c2
-rw-r--r--arch/arm/mach-at91/at91sam9x5_devices.c2
-rw-r--r--arch/arm/mach-at91/ddramc.c59
-rw-r--r--arch/arm/mach-at91/ddramc_ll.c507
-rw-r--r--arch/arm/mach-at91/early_udelay.c56
-rw-r--r--arch/arm/mach-at91/include/mach/aic.h9
-rw-r--r--arch/arm/mach-at91/include/mach/at91_dbgu.h34
-rw-r--r--arch/arm/mach-at91/include/mach/at91_ddrsdrc.h373
-rw-r--r--arch/arm/mach-at91/include/mach/at91_pmc.h22
-rw-r--r--arch/arm/mach-at91/include/mach/at91_pmc_ll.h32
-rw-r--r--arch/arm/mach-at91/include/mach/at91_wdt.h16
-rw-r--r--arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h214
-rw-r--r--arch/arm/mach-at91/include/mach/barebox-arm.h21
-rw-r--r--arch/arm/mach-at91/include/mach/ddramc.h37
-rw-r--r--arch/arm/mach-at91/include/mach/debug_ll.h17
-rw-r--r--arch/arm/mach-at91/include/mach/early_udelay.h14
-rw-r--r--arch/arm/mach-at91/include/mach/matrix.h21
-rw-r--r--arch/arm/mach-at91/include/mach/sama5_bootsource.h49
-rw-r--r--arch/arm/mach-at91/include/mach/sama5d2-sip-ddramc.h39
-rw-r--r--arch/arm/mach-at91/include/mach/sama5d2.h225
-rw-r--r--arch/arm/mach-at91/include/mach/sama5d2_ll.h139
-rw-r--r--arch/arm/mach-at91/include/mach/tz_matrix.h95
-rw-r--r--arch/arm/mach-at91/include/mach/xload.h12
-rw-r--r--arch/arm/mach-at91/matrix.c45
-rw-r--r--arch/arm/mach-at91/sama5d2.c71
-rw-r--r--arch/arm/mach-at91/sama5d2_ll.c220
-rw-r--r--arch/arm/mach-at91/sama5d3_devices.c2
-rw-r--r--arch/arm/mach-at91/sama5d4_devices.c2
-rw-r--r--arch/arm/mach-at91/xload-mmc.c90
56 files changed, 2493 insertions, 446 deletions
diff --git a/arch/arm/boards/at91sam9m10g45ek/lowlevel.c b/arch/arm/boards/at91sam9m10g45ek/lowlevel.c
index 0f3a035d1d..755e7ec029 100644
--- a/arch/arm/boards/at91sam9m10g45ek/lowlevel.c
+++ b/arch/arm/boards/at91sam9m10g45ek/lowlevel.c
@@ -11,7 +11,7 @@
#include <asm/barebox-arm.h>
#include <mach/hardware.h>
-#include <mach/at91sam9_ddrsdr.h>
+#include <mach/at91_ddrsdrc.h>
void __naked __bare_init barebox_arm_reset_vector(uint32_t r0, uint32_t r1, uint32_t r2)
{
diff --git a/arch/arm/boards/at91sam9m10ihd/lowlevel.c b/arch/arm/boards/at91sam9m10ihd/lowlevel.c
index e07ff892cd..817c7548c9 100644
--- a/arch/arm/boards/at91sam9m10ihd/lowlevel.c
+++ b/arch/arm/boards/at91sam9m10ihd/lowlevel.c
@@ -10,7 +10,7 @@
#include <asm/barebox-arm-head.h>
#include <asm/barebox-arm.h>
-#include <mach/at91sam9_ddrsdr.h>
+#include <mach/at91_ddrsdrc.h>
#include <mach/at91sam9g45.h>
#include <mach/hardware.h>
diff --git a/arch/arm/boards/at91sam9n12ek/lowlevel.c b/arch/arm/boards/at91sam9n12ek/lowlevel.c
index 5bc18f8fca..4353555d0d 100644
--- a/arch/arm/boards/at91sam9n12ek/lowlevel.c
+++ b/arch/arm/boards/at91sam9n12ek/lowlevel.c
@@ -10,7 +10,7 @@
#include <asm/barebox-arm-head.h>
#include <asm/barebox-arm.h>
-#include <mach/at91sam9_ddrsdr.h>
+#include <mach/at91_ddrsdrc.h>
#include <mach/hardware.h>
void __naked __bare_init barebox_arm_reset_vector(uint32_t r0, uint32_t r1, uint32_t r2)
diff --git a/arch/arm/boards/at91sam9x5ek/lowlevel.c b/arch/arm/boards/at91sam9x5ek/lowlevel.c
index c1433c8f7e..ebd417b19c 100644
--- a/arch/arm/boards/at91sam9x5ek/lowlevel.c
+++ b/arch/arm/boards/at91sam9x5ek/lowlevel.c
@@ -1,7 +1,6 @@
#include <common.h>
#include <linux/sizes.h>
-#include <mach/at91sam9_ddrsdr.h>
-#include <mach/hardware.h>
+#include <mach/at91_ddrsdrc.h>
#include <asm/barebox-arm-head.h>
#include <asm/barebox-arm.h>
#include <io.h>
diff --git a/arch/arm/boards/pm9g45/lowlevel.c b/arch/arm/boards/pm9g45/lowlevel.c
index fc0bfe405b..5f66b28254 100644
--- a/arch/arm/boards/pm9g45/lowlevel.c
+++ b/arch/arm/boards/pm9g45/lowlevel.c
@@ -10,7 +10,8 @@
#include <asm/barebox-arm-head.h>
#include <asm/barebox-arm.h>
-#include <mach/at91sam9_ddrsdr.h>
+#include <mach/at91_ddrsdrc.h>
+
#include <mach/hardware.h>
void __naked __bare_init barebox_arm_reset_vector(uint32_t r0, uint32_t r1, uint32_t r2)
diff --git a/arch/arm/boards/sama5d27-giantboard/Makefile b/arch/arm/boards/sama5d27-giantboard/Makefile
index b08c4a93ca..f5869c4839 100644
--- a/arch/arm/boards/sama5d27-giantboard/Makefile
+++ b/arch/arm/boards/sama5d27-giantboard/Makefile
@@ -1 +1,3 @@
lwl-y += lowlevel.o
+obj-y += board.o
+bbenv-y += defaultenv-giantboard
diff --git a/arch/arm/boards/sama5d27-giantboard/board.c b/arch/arm/boards/sama5d27-giantboard/board.c
new file mode 100644
index 0000000000..1d4453ede3
--- /dev/null
+++ b/arch/arm/boards/sama5d27-giantboard/board.c
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <init.h>
+#include <envfs.h>
+#include <bbu.h>
+
+static int giantboard_device_init(void)
+{
+ bbu_register_std_file_update("microSD", BBU_HANDLER_FLAG_DEFAULT,
+ "/mnt/mmc1.0/barebox.bin",
+ filetype_arm_barebox);
+
+ defaultenv_append_directory(defaultenv_giantboard);
+
+ return 0;
+}
+device_initcall(giantboard_device_init);
diff --git a/arch/arm/boards/sama5d27-giantboard/defaultenv-giantboard/nv/boot.default b/arch/arm/boards/sama5d27-giantboard/defaultenv-giantboard/nv/boot.default
new file mode 100644
index 0000000000..646f435652
--- /dev/null
+++ b/arch/arm/boards/sama5d27-giantboard/defaultenv-giantboard/nv/boot.default
@@ -0,0 +1 @@
+mmc1
diff --git a/arch/arm/boards/sama5d27-giantboard/lowlevel.c b/arch/arm/boards/sama5d27-giantboard/lowlevel.c
index 0236c424c1..ee8297fa45 100644
--- a/arch/arm/boards/sama5d27-giantboard/lowlevel.c
+++ b/arch/arm/boards/sama5d27-giantboard/lowlevel.c
@@ -5,59 +5,44 @@
#include <common.h>
#include <init.h>
-
-#include <asm/barebox-arm-head.h>
-#include <asm/barebox-arm.h>
-#include <mach/at91_pmc_ll.h>
-
-#include <mach/hardware.h>
+#include <mach/barebox-arm.h>
+#include <mach/sama5d2_ll.h>
+#include <mach/xload.h>
+#include <mach/sama5d2-sip-ddramc.h>
#include <mach/iomux.h>
#include <debug_ll.h>
-#include <mach/at91_dbgu.h>
/* PCK = 492MHz, MCK = 164MHz */
#define MASTER_CLOCK 164000000
-static inline void sama5d2_pmc_enable_periph_clock(int clk)
+SAMA5_ENTRY_FUNCTION(start_sama5d27_giantboard_xload_mmc, r4)
{
- at91_pmc_sam9x5_enable_periph_clock(IOMEM(SAMA5D2_BASE_PMC), clk);
-}
+ void __iomem *dbgu_base;
-static void dbgu_init(void)
-{
- unsigned mck = MASTER_CLOCK / 2;
+ sama5d2_lowlevel_init();
- sama5d2_pmc_enable_periph_clock(SAMA5D2_ID_PIOD);
-
- at91_mux_pio4_set_A_periph(IOMEM(SAMA5D2_BASE_PIOD),
- pin_to_mask(AT91_PIN_PD3)); /* DBGU TXD */
+ dbgu_base = sama5d2_resetup_uart_console(MASTER_CLOCK);
+ putc_ll('>');
- sama5d2_pmc_enable_periph_clock(SAMA5D2_ID_UART1);
+ relocate_to_current_adr();
+ setup_c();
- at91_dbgu_setup_ll(IOMEM(SAMA5D2_BASE_UART1), mck, 115200);
+ pbl_set_putc(at91_dbgu_putc, dbgu_base);
- putc_ll('>');
+ sama5d2_udelay_init(MASTER_CLOCK);
+ sama5d2_d1g_ddrconf();
+ sama5d2_sdhci_start_image(r4);
}
extern char __dtb_z_at91_sama5d27_giantboard_start[];
-static noinline void giantboard_entry(void)
+SAMA5_ENTRY_FUNCTION(start_sama5d27_giantboard, r4)
{
void *fdt;
- if (IS_ENABLED(CONFIG_DEBUG_LL))
- dbgu_init();
+ putc_ll('>');
fdt = __dtb_z_at91_sama5d27_giantboard_start + get_runtime_offset();
- barebox_arm_entry(SAMA5_DDRCS, SZ_128M, fdt);
-}
-
-ENTRY_FUNCTION(start_sama5d27_giantboard, r0, r1, r2)
-{
- arm_cpu_lowlevel_init();
-
- arm_setup_stack(SAMA5D2_SRAM_BASE + SAMA5D2_SRAM_SIZE);
-
- giantboard_entry();
+ sama5d2_barebox_entry(r4, fdt);
}
diff --git a/arch/arm/boards/sama5d27-som1/Makefile b/arch/arm/boards/sama5d27-som1/Makefile
index b08c4a93ca..092c31d6b2 100644
--- a/arch/arm/boards/sama5d27-som1/Makefile
+++ b/arch/arm/boards/sama5d27-som1/Makefile
@@ -1 +1,2 @@
lwl-y += lowlevel.o
+obj-y += board.o
diff --git a/arch/arm/boards/sama5d27-som1/board.c b/arch/arm/boards/sama5d27-som1/board.c
new file mode 100644
index 0000000000..00c0e92a5d
--- /dev/null
+++ b/arch/arm/boards/sama5d27-som1/board.c
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <common.h>
+#include <linux/sizes.h>
+#include <init.h>
+#include <asm/memory.h>
+#include <bbu.h>
+#include <bootsource.h>
+#include <of.h>
+
+static int ek_device_init(void)
+{
+ int flags_sd = 0, flags_usd = 0;
+ if (!of_machine_is_compatible("atmel,sama5d27-som1-ek"))
+ return 0;
+
+ if (bootsource_get() == BOOTSOURCE_MMC) {
+ if (bootsource_get_instance() == 0) {
+ flags_sd = BBU_HANDLER_FLAG_DEFAULT;
+ of_device_enable_path("/chosen/environment-sd");
+ } else {
+ flags_usd = BBU_HANDLER_FLAG_DEFAULT;
+ of_device_enable_path("/chosen/environment-microsd");
+ }
+ } else {
+ of_device_enable_path("/chosen/environment-qspi");
+ }
+
+ bbu_register_std_file_update("SD", flags_sd, "/mnt/mmc0.0/barebox.bin",
+ filetype_arm_barebox);
+ bbu_register_std_file_update("microSD", flags_usd, "/mnt/mmc1.0/barebox.bin",
+ filetype_arm_barebox);
+ return 0;
+}
+device_initcall(ek_device_init);
diff --git a/arch/arm/boards/sama5d27-som1/lowlevel.c b/arch/arm/boards/sama5d27-som1/lowlevel.c
index 62d35be912..b093711918 100644
--- a/arch/arm/boards/sama5d27-som1/lowlevel.c
+++ b/arch/arm/boards/sama5d27-som1/lowlevel.c
@@ -5,15 +5,12 @@
#include <common.h>
#include <init.h>
-
-#include <asm/barebox-arm-head.h>
-#include <asm/barebox-arm.h>
-#include <mach/at91_pmc_ll.h>
-
-#include <mach/hardware.h>
+#include <mach/barebox-arm.h>
+#include <mach/sama5d2_ll.h>
#include <mach/iomux.h>
+#include <mach/xload.h>
#include <debug_ll.h>
-#include <mach/at91_dbgu.h>
+#include <mach/sama5d2-sip-ddramc.h>
#define RGB_LED_GREEN (1 << 0)
#define RGB_LED_RED (1 << 1)
@@ -22,15 +19,10 @@
/* PCK = 492MHz, MCK = 164MHz */
#define MASTER_CLOCK 164000000
-static inline void sama5d2_pmc_enable_periph_clock(int clk)
-{
- at91_pmc_sam9x5_enable_periph_clock(IOMEM(SAMA5D2_BASE_PMC), clk);
-}
-
static void ek_turn_led(unsigned color)
{
struct {
- unsigned long pio;
+ void __iomem *pio;
unsigned bit;
unsigned color;
} *led, leds[] = {
@@ -41,48 +33,41 @@ static void ek_turn_led(unsigned color)
};
for (led = leds; led->pio; led++) {
- at91_mux_gpio4_enable(IOMEM(led->pio), BIT(led->bit));
- at91_mux_gpio4_input(IOMEM(led->pio), BIT(led->bit), false);
- at91_mux_gpio4_set(IOMEM(led->pio), BIT(led->bit), led->color);
+ at91_mux_gpio4_enable(led->pio, BIT(led->bit));
+ at91_mux_gpio4_input(led->pio, BIT(led->bit), false);
+ at91_mux_gpio4_set(led->pio, BIT(led->bit), led->color);
}
}
-static void ek_dbgu_init(void)
+SAMA5_ENTRY_FUNCTION(start_sama5d27_som1_ek_xload_mmc, r4)
{
- unsigned mck = MASTER_CLOCK / 2;
-
- sama5d2_pmc_enable_periph_clock(SAMA5D2_ID_PIOD);
+ void __iomem *dbgu_base;
+ sama5d2_lowlevel_init();
- at91_mux_pio4_set_A_periph(IOMEM(SAMA5D2_BASE_PIOD),
- pin_to_mask(AT91_PIN_PD3)); /* DBGU TXD */
+ dbgu_base = sama5d2_resetup_uart_console(MASTER_CLOCK);
+ putc_ll('>');
- sama5d2_pmc_enable_periph_clock(SAMA5D2_ID_UART1);
+ relocate_to_current_adr();
+ setup_c();
- at91_dbgu_setup_ll(IOMEM(SAMA5D2_BASE_UART1), mck, 115200);
+ pbl_set_putc(at91_dbgu_putc, dbgu_base);
- putc_ll('>');
+ ek_turn_led(RGB_LED_RED | RGB_LED_GREEN); /* Yellow */
+ sama5d2_udelay_init(MASTER_CLOCK);
+ sama5d2_d1g_ddrconf();
+ sama5d2_sdhci_start_image(r4);
}
extern char __dtb_z_at91_sama5d27_som1_ek_start[];
-static noinline void som1_entry(void)
+SAMA5_ENTRY_FUNCTION(start_sama5d27_som1_ek, r4)
{
void *fdt;
- if (IS_ENABLED(CONFIG_DEBUG_LL))
- ek_dbgu_init();
+ putc_ll('>');
fdt = __dtb_z_at91_sama5d27_som1_ek_start + get_runtime_offset();
ek_turn_led(RGB_LED_GREEN);
- barebox_arm_entry(SAMA5_DDRCS, SZ_128M, fdt);
-}
-
-ENTRY_FUNCTION(start_sama5d27_som1_ek, r0, r1, r2)
-{
- arm_cpu_lowlevel_init();
-
- arm_setup_stack(SAMA5D2_SRAM_BASE + SAMA5D2_SRAM_SIZE);
-
- som1_entry();
+ sama5d2_barebox_entry(r4, fdt);
}
diff --git a/arch/arm/boards/sama5d3_xplained/lowlevel.c b/arch/arm/boards/sama5d3_xplained/lowlevel.c
index 8653c48c69..28c07d5053 100644
--- a/arch/arm/boards/sama5d3_xplained/lowlevel.c
+++ b/arch/arm/boards/sama5d3_xplained/lowlevel.c
@@ -10,7 +10,7 @@
#include <asm/barebox-arm-head.h>
#include <asm/barebox-arm.h>
-#include <mach/at91sam9_ddrsdr.h>
+#include <mach/at91_ddrsdrc.h>
#include <mach/hardware.h>
void __naked __bare_init barebox_arm_reset_vector(uint32_t r0, uint32_t r1, uint32_t r2)
diff --git a/arch/arm/boards/sama5d3xek/lowlevel.c b/arch/arm/boards/sama5d3xek/lowlevel.c
index 8653c48c69..28c07d5053 100644
--- a/arch/arm/boards/sama5d3xek/lowlevel.c
+++ b/arch/arm/boards/sama5d3xek/lowlevel.c
@@ -10,7 +10,7 @@
#include <asm/barebox-arm-head.h>
#include <asm/barebox-arm.h>
-#include <mach/at91sam9_ddrsdr.h>
+#include <mach/at91_ddrsdrc.h>
#include <mach/hardware.h>
void __naked __bare_init barebox_arm_reset_vector(uint32_t r0, uint32_t r1, uint32_t r2)
diff --git a/arch/arm/boards/sama5d4_xplained/lowlevel.c b/arch/arm/boards/sama5d4_xplained/lowlevel.c
index 9a6a767e5f..3c58a08f3b 100644
--- a/arch/arm/boards/sama5d4_xplained/lowlevel.c
+++ b/arch/arm/boards/sama5d4_xplained/lowlevel.c
@@ -10,7 +10,7 @@
#include <asm/barebox-arm-head.h>
#include <asm/barebox-arm.h>
-#include <mach/at91sam9_ddrsdr.h>
+#include <mach/at91_ddrsdrc.h>
#include <mach/hardware.h>
void __naked __bare_init barebox_arm_reset_vector(uint32_t r0, uint32_t r1, uint32_t r2)
diff --git a/arch/arm/boards/sama5d4ek/lowlevel.c b/arch/arm/boards/sama5d4ek/lowlevel.c
index 9a6a767e5f..3c58a08f3b 100644
--- a/arch/arm/boards/sama5d4ek/lowlevel.c
+++ b/arch/arm/boards/sama5d4ek/lowlevel.c
@@ -10,7 +10,7 @@
#include <asm/barebox-arm-head.h>
#include <asm/barebox-arm.h>
-#include <mach/at91sam9_ddrsdr.h>
+#include <mach/at91_ddrsdrc.h>
#include <mach/hardware.h>
void __naked __bare_init barebox_arm_reset_vector(uint32_t r0, uint32_t r1, uint32_t r2)
diff --git a/arch/arm/dts/at91-sama5d27_giantboard.dts b/arch/arm/dts/at91-sama5d27_giantboard.dts
index 7e48fa18ae..2ba3ff2171 100644
--- a/arch/arm/dts/at91-sama5d27_giantboard.dts
+++ b/arch/arm/dts/at91-sama5d27_giantboard.dts
@@ -25,6 +25,12 @@
chosen {
stdout-path = &uart1;
+
+ environment {
+ compatible = "barebox,environment";
+ device-path = &sdmmc1;
+ file-path = "barebox.env";
+ };
};
leds {
@@ -38,10 +44,6 @@
linux,default-trigger = "mmc0";
};
};
-
- memory {
- reg = <0x20000000 0x8000000>;
- };
};
&slow_xtal {
diff --git a/arch/arm/dts/at91-sama5d27_som1_ek.dts b/arch/arm/dts/at91-sama5d27_som1_ek.dts
index cd038dc7c1..97a326dd2b 100644
--- a/arch/arm/dts/at91-sama5d27_som1_ek.dts
+++ b/arch/arm/dts/at91-sama5d27_som1_ek.dts
@@ -8,30 +8,51 @@
/ {
chosen {
- environment {
+ environment-qspi {
compatible = "barebox,environment";
device-path = &barebox_env;
+ status = "disabled";
};
- };
- memory {
- reg = <0x20000000 0x8000000>;
+ environment-sd {
+ compatible = "barebox,environment";
+ device-path = &sdmmc0;
+ file-path = "barebox.env";
+ status = "disabled";
+ };
+
+ environment-microsd {
+ compatible = "barebox,environment";
+ device-path = &sdmmc1;
+ file-path = "barebox.env";
+ status = "disabled";
+ };
};
};
&qspi1 {
+ /delete-node/ flash@0;
+
flash@0 {
- #address-cells = <1>;
- #size-cells = <1>;
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <80000000>;
+ m25p,fast-read;
- partition@0 {
- label = "barebox";
- reg = <0x0 0x80000>;
- };
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ barebox@40000 {
+ label = "barebox";
+ reg = <0x40000 0xc0000>;
+ };
- barebox_env: partition@80000 {
- label = "barebox-environment";
- reg = <0x80000 0x80000>;
+ barebox_env: barebox-env@100000 {
+ label = "barebox-environment";
+ reg = <0x100000 0x40000>;
+ };
};
};
};
diff --git a/arch/arm/dts/sama5d2.dtsi b/arch/arm/dts/sama5d2.dtsi
index 51e964fc0f..c9af5f2f7a 100644
--- a/arch/arm/dts/sama5d2.dtsi
+++ b/arch/arm/dts/sama5d2.dtsi
@@ -6,3 +6,13 @@
mmc1 = &sdmmc1;
};
};
+
+/delete-node/ &{/memory};
+
+&sdmmc0 {
+ assigned-clock-parents = <&pmc PMC_TYPE_CORE PMC_UTMI>;
+};
+
+&sdmmc1 {
+ assigned-clock-parents = <&pmc PMC_TYPE_CORE PMC_UTMI>;
+};
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 54fa9b8aa2..52eefc7361 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -40,6 +40,14 @@ config HAVE_AT91_I2S_MUX_CLK
config HAVE_AT91_SAM9X60_PLL
bool
+config HAVE_AT91_DDRAMC
+ bool
+
+config AT91_MCI_PBL
+ bool
+ depends on MCI_ATMEL_SDHCI_PBL
+ default y
+
# Select if board uses the common at91sam926x_board_init
config AT91SAM926X_BOARD_INIT
bool
@@ -82,6 +90,7 @@ config SOC_SAMA5D2
select PINCTRL_AT91PIO4
select HAS_MACB
select HAVE_MACH_ARM_HEAD
+ select HAVE_AT91_DDRAMC
config SOC_SAMA5D3
bool
@@ -598,7 +607,9 @@ config MACH_SAMA5D27_SOM1
bool "Microchip SAMA5D27 SoM-1 Evaluation Kit"
select SOC_SAMA5D2
select OFDEVICE
+ select MCI_ATMEL_SDHCI_PBL
select COMMON_CLK_OF_PROVIDER
+ select FS_FAT_WRITE if MCI_ATMEL_SDHCI && FS_FAT && ENV_HANDLING
help
Select this if you are using Microchip's sama5d27 SoM evaluation kit
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
index 89aff54b8a..3b9f60a95a 100644
--- a/arch/arm/mach-at91/Makefile
+++ b/arch/arm/mach-at91/Makefile
@@ -1,5 +1,6 @@
-obj-y += setup.o
-lwl-y += at91_pmc_ll.o
+obj-y += setup.o aic.o
+lwl-y += at91_pmc_ll.o ddramc_ll.o matrix.o
+lwl-$(CONFIG_CLOCKSOURCE_ATMEL_PIT) += early_udelay.o
ifeq ($(CONFIG_COMMON_CLK_OF_PROVIDER),)
obj-y += clock.o
@@ -11,6 +12,8 @@ obj-$(CONFIG_AT91_BOOTSTRAP) += bootstrap.o
obj-y += at91sam9_reset.o
obj-y += at91sam9g45_reset.o
+obj-pbl-$(CONFIG_HAVE_AT91_DDRAMC) += ddramc.o
+pbl-$(CONFIG_AT91_MCI_PBL) += xload-mmc.o
obj-$(CONFIG_AT91SAM9_SMC) += sam9_smc.o
obj-$(CONFIG_HAVE_AT91SAM9_RST) += at91sam9_rst.o
@@ -24,6 +27,8 @@ ifeq ($(CONFIG_OFDEVICE),)
obj-$(CONFIG_SOC_AT91SAM9263) += at91sam9263.o at91sam9263_devices.o
obj-$(CONFIG_SOC_SAMA5D3) += sama5d3.o sama5d3_devices.o
endif
+lwl-$(CONFIG_SOC_SAMA5D2) += sama5d2_ll.o
+obj-$(CONFIG_SOC_SAMA5D2) += sama5d2.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/aic.c b/arch/arm/mach-at91/aic.c
new file mode 100644
index 0000000000..b40f1d214b
--- /dev/null
+++ b/arch/arm/mach-at91/aic.c
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: BSD-1-Clause
+/*
+ * Copyright (c) 2015, Atmel Corporation
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ */
+
+#include <mach/aic.h>
+#include <io.h>
+
+#define SFR_AICREDIR 0x54
+#define SFR_SN1 0x50 /* Serial Number 1 Register */
+
+void at91_aic_redir(void __iomem *sfr, u32 key)
+{
+ u32 key32;
+
+ if (readl(sfr + SFR_AICREDIR) & 0x01)
+ return;
+
+ key32 = readl(sfr + SFR_SN1) ^ key;
+ writel(key32 | 0x01, sfr + SFR_AICREDIR);
+ /* bits[31:1] = key */
+ /* bit[0] = 1 => all interrupts redirected to AIC */
+ /* bit[0] = 0 => secure interrupts directed to SAIC,
+ others to AIC (default) */
+}
diff --git a/arch/arm/mach-at91/at91_pmc_ll.c b/arch/arm/mach-at91/at91_pmc_ll.c
index 4d39f57909..9205322db9 100644
--- a/arch/arm/mach-at91/at91_pmc_ll.c
+++ b/arch/arm/mach-at91/at91_pmc_ll.c
@@ -1,17 +1,51 @@
// SPDX-License-Identifier: BSD-1-Clause
/*
* Copyright (c) 2006, Atmel Corporation
+ * Copyright (C) 2019 Microchip Technology Inc. and its subsidiaries
*
- * Atmel's name may not be used to endorse or promote products
+ * Atmel/Microchip's name may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*/
+#define pr_fmt(fmt) "at91pmc: " fmt
+
#include <common.h>
+#include <mach/hardware.h>
+#include <mach/at91_pmc.h>
#include <mach/at91_pmc_ll.h>
+#include <mach/early_udelay.h>
+
+#define SFR_UTMICKTRIM 0x30 /* UTMI Clock Trimming Register */
+#define AT91_UTMICKTRIM_FREQ 0x03
+
+#define PMC_GCSR0 0xC0 /* PMCv2 Generic Clock Status Register 0 */
+#define PMC_GCSR1 0xC4 /* PMCv2 Generic Clock Status Register 1 */
#define at91_pmc_write(off, val) writel(val, pmc_base + off)
#define at91_pmc_read(off) readl(pmc_base + off)
+#define MHZ (1000 * 1000UL)
+
+static unsigned long at91_pmc_get_main_xtal(void __iomem *pmc_base)
+{
+ u32 tmp;
+
+ /* Enable a measurement of the Main Crystal Oscillator */
+ tmp = at91_pmc_read(AT91_CKGR_MCFR);
+ tmp |= AT91_PMC_CCSS_XTAL_OSC;
+ tmp |= AT91_PMC_RCMEAS;
+ at91_pmc_write(AT91_CKGR_MCFR, tmp);
+
+ do {
+ tmp = at91_pmc_read(AT91_CKGR_MCFR);
+ } while (!(tmp & AT91_PMC_MAINRDY));
+
+ /* read once more like the datasheet says */
+ tmp = at91_pmc_read(AT91_CKGR_MCFR) & AT91_PMC_MAINF;
+
+ return tmp * (AT91_SLOW_CLOCK / 16);
+}
+
void at91_pmc_init(void __iomem *pmc_base, unsigned int flags)
{
u32 tmp;
@@ -46,16 +80,8 @@ void at91_pmc_init(void __iomem *pmc_base, unsigned int flags)
while (!(at91_pmc_read(AT91_PMC_SR) & AT91_PMC_MOSCS))
;
- if (flags & AT91_PMC_LL_FLAG_MEASURE_XTAL) {
- /* Enable a measurement of the Main Crystal Oscillator */
- tmp = at91_pmc_read(AT91_CKGR_MCFR);
- tmp |= AT91_PMC_CCSS_XTAL_OSC;
- tmp |= AT91_PMC_RCMEAS;
- at91_pmc_write(AT91_CKGR_MCFR, tmp);
-
- while (!(at91_pmc_read(AT91_CKGR_MCFR) & AT91_PMC_MAINRDY))
- ;
- }
+ if (flags & AT91_PMC_LL_FLAG_MEASURE_XTAL)
+ (void)at91_pmc_get_main_xtal(pmc_base);
/* Switch from internal 12MHz RC to the Main Crystal Oscillator */
tmp = at91_pmc_read(AT91_CKGR_MOR);
@@ -184,3 +210,124 @@ void at91_pmc_cfg_mck(void __iomem *pmc_base, u32 pmc_mckr, unsigned int flags)
while (!(at91_pmc_read(AT91_PMC_SR) & AT91_PMC_MCKRDY))
;
}
+
+static void pmc_configure_utmi_ref_clk(void __iomem *pmc_base,
+ void __iomem *sfr_base,
+ unsigned long main_xtal)
+{
+ unsigned int utmi_ref_clk_freq = 0, tmp;
+
+ /*
+ * If mainck rate is different from 12 MHz, we have to configure
+ * the FREQ field of the SFR_UTMICKTRIM register to generate properly
+ * the utmi clock.
+ */
+ if (main_xtal < (16 + 4) * MHZ)
+ utmi_ref_clk_freq++;
+ if (main_xtal < (24 + 10) * MHZ)
+ utmi_ref_clk_freq++;
+ if (main_xtal < (48 + 10) * MHZ)
+ utmi_ref_clk_freq++;
+
+ /*
+ * Not supported on SAMA5D2 but it's not an issue since MAINCK
+ * maximum value is 24 MHz.
+ */
+ tmp = readl(sfr_base + SFR_UTMICKTRIM);
+ tmp &= ~AT91_UTMICKTRIM_FREQ;
+ tmp |= utmi_ref_clk_freq;
+ writel(tmp, sfr_base + SFR_UTMICKTRIM);
+}
+
+static void pmc_uckr_clk(void __iomem *pmc_base,
+ void __iomem *sfr_base,
+ unsigned long main_xtal)
+{
+ unsigned int uckr = at91_pmc_read(AT91_CKGR_UCKR);
+ unsigned int sr;
+
+ if (main_xtal) {
+ pmc_configure_utmi_ref_clk(pmc_base, sfr_base,
+ main_xtal);
+ uckr |= (AT91_PMC_UPLLCOUNT_DEFAULT |
+ AT91_PMC_UPLLEN | AT91_PMC_BIASEN);
+ sr = AT91_PMC_LOCKU;
+ } else {
+ uckr &= ~(AT91_PMC_UPLLEN | AT91_PMC_BIASEN);
+ sr = 0;
+ }
+
+ at91_pmc_write(AT91_CKGR_UCKR, uckr);
+
+ do {
+ early_udelay(1);
+ } while ((at91_pmc_read(AT91_PMC_SR) & AT91_PMC_LOCKU) != sr);
+}
+
+static inline unsigned gck_status(unsigned periph_id,
+ unsigned flags)
+{
+ if (flags & AT91_PMC_LL_FLAG_GCSR)
+ return periph_id < 32 ? PMC_GCSR0 : PMC_GCSR1;
+
+ return AT91_PMC_SR;
+}
+
+static inline unsigned gck_ready(unsigned status,
+ unsigned periph_id,
+ unsigned flags)
+{
+ unsigned mask;
+
+ if (flags & AT91_PMC_LL_FLAG_GCSR)
+ mask = 1 << (periph_id & 0x1f);
+ else
+ mask = AT91_PMC_GCKRDY;
+
+ return status & mask;
+}
+
+int at91_pmc_enable_generic_clock(void __iomem *pmc_base,
+ void __iomem *sfr_base,
+ unsigned int periph_id,
+ unsigned int clk_source, unsigned int div,
+ unsigned int flags)
+{
+ unsigned long main_xtal;
+ unsigned int regval, status;
+ unsigned int timeout = 1000;
+
+ if (periph_id > 0x7f)
+ return -EINVAL;
+
+ if (div > 0xff)
+ return -EINVAL;
+
+ main_xtal = at91_pmc_get_main_xtal(pmc_base);
+
+ if ((flags & AT91_PMC_LL_FLAG_PMC_UTMI) &&
+ !(at91_pmc_read(AT91_PMC_SR) & AT91_PMC_LOCKU))
+ pmc_uckr_clk(pmc_base, sfr_base, main_xtal);
+
+ at91_pmc_write(AT91_PMC_PCR, periph_id);
+ regval = at91_pmc_read(AT91_PMC_PCR);
+ regval &= ~AT91_PMC_GCKCSS;
+ regval &= ~AT91_PMC_GCKDIV;
+
+ regval |= clk_source;
+ regval |= AT91_PMC_PCR_CMD | AT91_PMC_GCKDIV_(div) | AT91_PMC_GCK_EN;
+
+ at91_pmc_write(AT91_PMC_PCR, regval);
+
+ for (timeout = 1000; timeout; timeout--) {
+ early_udelay(1);
+
+ status = at91_pmc_read(gck_status(periph_id, flags));
+ if (gck_ready(status, periph_id, flags))
+ return 0;
+ }
+
+ pr_warn("Timeout waiting for GCK ready!\n");
+
+ return 0;
+}
diff --git a/arch/arm/mach-at91/at91sam9_reset.S b/arch/arm/mach-at91/at91sam9_reset.S
index 65e22f4fe7..ba3f768331 100644
--- a/arch/arm/mach-at91/at91sam9_reset.S
+++ b/arch/arm/mach-at91/at91sam9_reset.S
@@ -14,7 +14,6 @@
*/
#include <linux/linkage.h>
-#include <mach/hardware.h>
#include <mach/at91sam9_sdramc.h>
#include <mach/at91_rstc.h>
diff --git a/arch/arm/mach-at91/at91sam9_rst.c b/arch/arm/mach-at91/at91sam9_rst.c
index 8f03576e69..a61a26936f 100644
--- a/arch/arm/mach-at91/at91sam9_rst.c
+++ b/arch/arm/mach-at91/at91sam9_rst.c
@@ -7,14 +7,42 @@
#include <init.h>
#include <io.h>
#include <restart.h>
+#include <linux/bitfield.h>
#include <linux/clk.h>
#include <mach/at91_rstc.h>
+#include <reset_source.h>
struct at91sam9x_rst {
struct restart_handler restart;
void __iomem *base;
};
+static int reasons[] = {
+ RESET_POR, /* GENERAL Both VDDCORE and VDDBU rising */
+ RESET_WKE, /* WAKEUP VDDCORE rising */
+ RESET_WDG, /* WATCHDOG Watchdog fault occurred */
+ RESET_RST, /* SOFTWARE Reset required by the software */
+ RESET_EXT, /* USER NRST pin detected low */
+};
+
+static void at91sam9x_set_reset_reason(struct device_d *dev,
+ void __iomem *base)
+{
+ enum reset_src_type type = RESET_UKWN;
+ u32 sr, rsttyp;
+
+ sr = readl(base + AT91_RSTC_SR);
+ rsttyp = FIELD_GET(AT91_RSTC_RSTTYP, sr);
+
+ if (rsttyp < ARRAY_SIZE(reasons))
+ type = reasons[rsttyp];
+
+ dev_info(dev, "reset reason %s (RSTC_SR: 0x%05x)\n",
+ reset_source_to_string(type), sr);
+
+ reset_source_set(type);
+}
+
static void __noreturn at91sam9x_restart_soc(struct restart_handler *rst)
{
struct at91sam9x_rst *priv = container_of(rst, struct at91sam9x_rst, restart);
@@ -52,6 +80,8 @@ static int at91sam9x_rst_probe(struct device_d *dev)
clk_enable(clk);
+ at91sam9x_set_reset_reason(dev, priv->base);
+
priv->restart.name = "at91sam9x-rst";
priv->restart.restart = at91sam9x_restart_soc;
diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c
index 43d8d5fbd6..389d88c17d 100644
--- a/arch/arm/mach-at91/at91sam9g45_devices.c
+++ b/arch/arm/mach-at91/at91sam9g45_devices.c
@@ -17,7 +17,7 @@
#include <mach/hardware.h>
#include <mach/at91_pmc.h>
#include <mach/at91sam9g45_matrix.h>
-#include <mach/at91sam9_ddrsdr.h>
+#include <mach/at91_ddrsdrc.h>
#include <mach/at91_rtt.h>
#include <mach/board.h>
#include <mach/iomux.h>
diff --git a/arch/arm/mach-at91/at91sam9g45_reset.S b/arch/arm/mach-at91/at91sam9g45_reset.S
index 6a58de618c..67517bf591 100644
--- a/arch/arm/mach-at91/at91sam9g45_reset.S
+++ b/arch/arm/mach-at91/at91sam9g45_reset.S
@@ -11,8 +11,7 @@
*/
#include <linux/linkage.h>
-#include <mach/hardware.h>
-#include <mach/at91sam9_ddrsdr.h>
+#include <mach/at91_ddrsdrc.h>
#include <mach/at91_rstc.h>
.arm
@@ -20,13 +19,13 @@
.globl at91sam9g45_reset
at91sam9g45_reset: mov r2, #1
- mov r3, #AT91_DDRSDRC_LPCB_POWER_DOWN
+ mov r3, #AT91_DDRC2_LPCB_POWERDOWN
ldr r4, =AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST
.balign 32 @ align to cache line
- str r2, [r0, #AT91_DDRSDRC_RTR] @ disable DDR0 access
- str r3, [r0, #AT91_DDRSDRC_LPR] @ power down DDR0
+ str r2, [r0, #AT91_HDDRSDRC2_RTR] @ disable DDR0 access
+ str r3, [r0, #AT91_HDDRSDRC2_LPR] @ power down DDR0
str r4, [r1] @ reset processor
b .
diff --git a/arch/arm/mach-at91/at91sam9n12_devices.c b/arch/arm/mach-at91/at91sam9n12_devices.c
index 43cbb79af4..91b3e9b2fb 100644
--- a/arch/arm/mach-at91/at91sam9n12_devices.c
+++ b/arch/arm/mach-at91/at91sam9n12_devices.c
@@ -18,7 +18,7 @@
#include <mach/board.h>
#include <mach/at91_pmc.h>
#include <mach/at91sam9n12_matrix.h>
-#include <mach/at91sam9_ddrsdr.h>
+#include <mach/at91_ddrsdrc.h>
#include <mach/iomux.h>
#include <mach/cpu.h>
#include <i2c/i2c-gpio.h>
diff --git a/arch/arm/mach-at91/at91sam9x5_devices.c b/arch/arm/mach-at91/at91sam9x5_devices.c
index ab506a1f42..022e4fb59a 100644
--- a/arch/arm/mach-at91/at91sam9x5_devices.c
+++ b/arch/arm/mach-at91/at91sam9x5_devices.c
@@ -17,7 +17,7 @@
#include <mach/board.h>
#include <mach/at91_pmc.h>
#include <mach/at91sam9x5_matrix.h>
-#include <mach/at91sam9_ddrsdr.h>
+#include <mach/at91_ddrsdrc.h>
#include <mach/iomux.h>
#include <mach/cpu.h>
#include <i2c/i2c-gpio.h>
diff --git a/arch/arm/mach-at91/ddramc.c b/arch/arm/mach-at91/ddramc.c
new file mode 100644
index 0000000000..a241ea9f0a
--- /dev/null
+++ b/arch/arm/mach-at91/ddramc.c
@@ -0,0 +1,59 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2020 Ahmad Fatoum <a.fatoum@pengutronix.de>
+ */
+
+#include <common.h>
+#include <init.h>
+#include <mach/ddramc.h>
+#include <mach/hardware.h>
+#include <asm/barebox-arm.h>
+#include <mach/at91_ddrsdrc.h>
+#include <mach/sama5_bootsource.h>
+#include <asm/memory.h>
+#include <pbl.h>
+#include <io.h>
+
+static unsigned sama5_ramsize(void __iomem *base)
+{
+ return at91_get_ddram_size(base, true);
+}
+
+void __noreturn sama5d2_barebox_entry(unsigned int r4, void *boarddata)
+{
+ __sama5d2_stashed_bootrom_r4 = r4;
+ barebox_arm_entry(SAMA5_DDRCS, sama5_ramsize(SAMA5D2_BASE_MPDDRC),
+ boarddata);
+}
+
+static int sama5_ddr_probe(struct device_d *dev)
+{
+ struct resource *iores;
+ void __iomem *base;
+
+ iores = dev_request_mem_resource(dev, 0);
+ if (IS_ERR(iores))
+ return PTR_ERR(iores);
+ base = IOMEM(iores->start);
+
+ arm_add_mem_device("ram0", SAMA5_DDRCS, sama5_ramsize(base));
+
+ return 0;
+}
+
+static struct of_device_id sama5_ddr_dt_ids[] = {
+ { .compatible = "atmel,sama5d3-ddramc" },
+ { /* sentinel */ }
+};
+
+static struct driver_d sama5_ddr_driver = {
+ .name = "sama5-ddramc",
+ .probe = sama5_ddr_probe,
+ .of_compatible = sama5_ddr_dt_ids,
+};
+
+static int sama5_ddr_init(void)
+{
+ return platform_driver_register(&sama5_ddr_driver);
+}
+mem_initcall(sama5_ddr_init);
diff --git a/arch/arm/mach-at91/ddramc_ll.c b/arch/arm/mach-at91/ddramc_ll.c
new file mode 100644
index 0000000000..4768fdcd62
--- /dev/null
+++ b/arch/arm/mach-at91/ddramc_ll.c
@@ -0,0 +1,507 @@
+// SPDX-License-Identifier: BSD-1-Clause
+/*
+ * Copyright (c) 2007, Stelian Pop <stelian.pop@leadtechdesign.com>
+ * Copyright (c) 2007 Lead Tech Design <www.leadtechdesign.com>
+ */
+
+#include <linux/kconfig.h>
+#include <asm/system.h>
+#include <mach/at91_ddrsdrc.h>
+#include <mach/ddramc.h>
+#include <mach/early_udelay.h>
+
+void at91_ddram_initialize(void __iomem *base_address,
+ void __iomem *ram_address,
+ struct at91_ddramc_register *ddramc_config)
+{
+ unsigned long ba_offset;
+ unsigned long cr = 0;
+
+ /* compute BA[] offset according to CR configuration */
+ ba_offset = (ddramc_config->cr & AT91_DDRC2_NC) + 9;
+ if ((ddramc_config->cr & AT91_DDRC2_DECOD) == AT91_DDRC2_DECOD_SEQUENTIAL)
+ ba_offset += ((ddramc_config->cr & AT91_DDRC2_NR) >> 2) + 11;
+
+ ba_offset += (ddramc_config->mdr & AT91_DDRC2_DBW) ? 1 : 2;
+
+ /*
+ * Step 1: Program the memory device type into the Memory Device Register
+ */
+ writel(ddramc_config->mdr, base_address + AT91_HDDRSDRC2_MDR);
+
+ /*
+ * Step 2: Program the feature of DDR2-SDRAM device into
+ * the Timing Register, and into the Configuration Register
+ */
+ writel(ddramc_config->cr, base_address + AT91_HDDRSDRC2_CR);
+
+ writel(ddramc_config->t0pr, base_address + AT91_HDDRSDRC2_T0PR);
+ writel(ddramc_config->t1pr, base_address + AT91_HDDRSDRC2_T1PR);
+ writel(ddramc_config->t2pr, base_address + AT91_HDDRSDRC2_T2PR);
+
+ /*
+ * Step 3: An NOP command is issued to the DDR2-SDRAM
+ */
+ writel(AT91_DDRC2_MODE_NOP_CMD, base_address + AT91_HDDRSDRC2_MR);
+ writel(0, ram_address);
+ /* Now, clocks which drive the DDR2-SDRAM device are enabled */
+
+ /* A minimum pause wait 200 us is provided to precede any signal toggle.
+ (6 core cycles per iteration, core is at 396MHz: min 13340 loops) */
+ early_udelay(200);
+
+ /*
+ * Step 4: An NOP command is issued to the DDR2-SDRAM
+ */
+ writel(AT91_DDRC2_MODE_NOP_CMD, base_address + AT91_HDDRSDRC2_MR);
+ writel(0, ram_address);
+ /* Now, CKE is driven high */
+ /* wait 400 ns min */
+ early_udelay(1);
+
+ /*
+ * Step 5: An all banks precharge command is issued to the DDR2-SDRAM.
+ */
+ writel(AT91_DDRC2_MODE_PRCGALL_CMD, base_address + AT91_HDDRSDRC2_MR);
+ writel(0, ram_address);
+
+ /* wait 2 cycles min (of tCK) = 15 ns min */
+ early_udelay(1);
+
+ /*
+ * Step 6: An Extended Mode Register set(EMRS2) cycle is issued to chose between commercial or high
+ * temperature operations.
+ * Perform a write access to DDR2-SDRAM to acknowledge this command.
+ * The write address must be chosen so that BA[1] is set to 1 and BA[0] is set to 0.
+ */
+ writel(AT91_DDRC2_MODE_EXT_LMR_CMD, base_address + AT91_HDDRSDRC2_MR);
+ writel(0, ram_address + (0x2 << ba_offset));
+
+ /* wait 2 cycles min (of tCK) = 15 ns min */
+ early_udelay(1);
+
+ /*
+ * Step 7: An Extended Mode Register set(EMRS3) cycle is issued
+ * to set the Extended Mode Register to "0".
+ * Perform a write access to DDR2-SDRAM to acknowledge this command.
+ * The write address must be chosen so that BA[1] is set to 1 and BA[0] is set to 1.
+ */
+ writel(AT91_DDRC2_MODE_EXT_LMR_CMD, base_address + AT91_HDDRSDRC2_MR);
+ writel(0, ram_address + (0x3 << ba_offset));
+
+ /* wait 2 cycles min (of tCK) = 15 ns min */
+ early_udelay(1);
+
+ /*
+ * Step 8: An Extened Mode Register set(EMRS1) cycle is issued to enable DLL,
+ * and to program D.I.C(Output Driver Impedance Control)
+ * Perform a write access to DDR2-SDRAM to acknowledge this command.
+ * The write address must be chosen so that BA[1] is set to 0 and BA[0] is set to 1.
+ */
+ writel(AT91_DDRC2_MODE_EXT_LMR_CMD, base_address + AT91_HDDRSDRC2_MR);
+ writel(0, ram_address + (0x1 << ba_offset));
+
+ /* An additional 200 cycles of clock are required for locking DLL */
+ early_udelay(1);
+
+ /*
+ * Step 9: Program DLL field into the Configuration Register to high(Enable DLL reset)
+ */
+ cr = readl(base_address + AT91_HDDRSDRC2_CR);
+ writel(cr | AT91_DDRC2_ENABLE_RESET_DLL, base_address + AT91_HDDRSDRC2_CR);
+
+ /*
+ * Step 10: A Mode Register set(MRS) cycle is issied to reset DLL.
+ * Perform a write access to DDR2-SDRAM to acknowledge this command.
+ * The write address must be chosen so that BA[1:0] bits are set to 0.
+ */
+ writel(AT91_DDRC2_MODE_LMR_CMD, base_address + AT91_HDDRSDRC2_MR);
+ writel(0, ram_address + (0x0 << ba_offset));
+
+ /* wait 2 cycles min (of tCK) = 15 ns min */
+ early_udelay(1);
+
+ /*
+ * Step 11: An all banks precharge command is issued to the DDR2-SDRAM.
+ */
+ writel(AT91_DDRC2_MODE_PRCGALL_CMD, base_address + AT91_HDDRSDRC2_MR);
+ writel(0, ram_address);
+
+ /* wait 400 ns min (not needed on certain DDR2 devices) */
+ early_udelay(1);
+
+ /*
+ * Step 12: Two auto-refresh (CBR) cycles are provided.
+ * Program the auto refresh command (CBR) into the Mode Register.
+ */
+ writel(AT91_DDRC2_MODE_RFSH_CMD, base_address + AT91_HDDRSDRC2_MR);
+ writel(0, ram_address);
+
+ /* wait TRFC cycles min (135 ns min) extended to 400 ns */
+ early_udelay(1);
+
+ /* Set 2nd CBR */
+ writel(AT91_DDRC2_MODE_RFSH_CMD, base_address + AT91_HDDRSDRC2_MR);
+ writel(0, ram_address);
+
+ /* wait TRFC cycles min (135 ns min) extended to 400 ns */
+ early_udelay(1);
+
+ /*
+ * Step 13: Program DLL field into the Configuration Register to low(Disable DLL reset).
+ */
+ cr = readl(base_address + AT91_HDDRSDRC2_CR);
+ writel(cr & ~AT91_DDRC2_ENABLE_RESET_DLL, base_address + AT91_HDDRSDRC2_CR);
+
+ /*
+ * Step 14: A Mode Register set (MRS) cycle is issued to program
+ * the parameters of the DDR2-SDRAM devices, in particular CAS latency,
+ * burst length and to disable DDL reset.
+ * Perform a write access to DDR2-SDRAM to acknowledge this command.
+ * The write address must be chosen so that BA[1:0] bits are set to 0.
+ */
+ writel(AT91_DDRC2_MODE_LMR_CMD, base_address + AT91_HDDRSDRC2_MR);
+ writel(0, ram_address + (0x0 << ba_offset));
+
+ /* wait 2 cycles min (of tCK) = 15 ns min */
+ early_udelay(1);
+
+ /*
+ * Step 15: Program OCD field into the Configuration Register
+ * to high (OCD calibration default).
+ */
+ cr = readl(base_address + AT91_HDDRSDRC2_CR);
+ writel(cr | AT91_DDRC2_OCD_DEFAULT, base_address + AT91_HDDRSDRC2_CR);
+
+ /* wait 2 cycles min (of tCK) = 15 ns min */
+ early_udelay(1);
+
+ /*
+ * Step 16: An Extended Mode Register set (EMRS1) cycle is issued to OCD default value.
+ * Perform a write access to DDR2-SDRAM to acknowledge this command.
+ * The write address must be chosen so that BA[1] is set to 0 and BA[0] is set to 1.
+ */
+ writel(AT91_DDRC2_MODE_EXT_LMR_CMD, base_address + AT91_HDDRSDRC2_MR);
+ writel(0, ram_address + (0x1 << ba_offset));
+
+ /* wait 2 cycles min (of tCK) = 15 ns min */
+ early_udelay(1);
+
+ /*
+ * Step 17: Program OCD field into the Configuration Register
+ * to low (OCD calibration mode exit).
+ */
+ cr = readl(base_address + AT91_HDDRSDRC2_CR);
+ writel(cr & ~AT91_DDRC2_OCD_DEFAULT, base_address + AT91_HDDRSDRC2_CR);
+
+ /* wait 2 cycles min (of tCK) = 15 ns min */
+ early_udelay(1);
+
+ /*
+ * Step 18: An Extended Mode Register set (EMRS1) cycle is issued to enable OCD exit.
+ * Perform a write access to DDR2-SDRAM to acknowledge this command.
+ * The write address must be chosen so that BA[1] is set to 0 and BA[0] is set to 1.
+ */
+ writel(AT91_DDRC2_MODE_EXT_LMR_CMD, base_address + AT91_HDDRSDRC2_MR);
+ writel(0, ram_address + (0x1 << ba_offset));
+
+ /* wait 2 cycles min (of tCK) = 15 ns min */
+ early_udelay(1);
+
+ /*
+ * Step 19: A Nornal mode command is provided.
+ */
+ writel(AT91_DDRC2_MODE_NORMAL_CMD, base_address + AT91_HDDRSDRC2_MR);
+ writel(0, ram_address);
+
+ /*
+ * Step 20: Perform a write access to any DDR2-SDRAM address
+ */
+ writel(0, ram_address);
+
+ /*
+ * Step 21: Write the refresh rate into the count field in the Refresh Timer register.
+ */
+ writel(ddramc_config->rtr, base_address + AT91_HDDRSDRC2_RTR);
+
+ /*
+ * Now we are ready to work on the DDRSDR
+ * wait for end of calibration
+ */
+ early_udelay(10);
+}
+
+/* This initialization sequence is sama5d3 and sama5d4 LP-DDR2 specific */
+
+void at91_lpddr2_sdram_initialize(void __iomem *base_address,
+ void __iomem *ram_address,
+ struct at91_ddramc_register *ddramc_config)
+{
+ unsigned long reg;
+
+ writel(ddramc_config->lpddr2_lpr, base_address + AT91_MPDDRC_LPDDR2_LPR);
+
+ writel(ddramc_config->tim_calr, base_address + AT91_MPDDRC_LPDDR2_TIM_CAL);
+
+ /*
+ * Step 1: Program the memory device type.
+ */
+ writel(ddramc_config->mdr, base_address + AT91_HDDRSDRC2_MDR);
+
+ /*
+ * Step 2: Program the feature of the low-power DDR2-SDRAM device.
+ */
+ writel(ddramc_config->cr, base_address + AT91_HDDRSDRC2_CR);
+
+ writel(ddramc_config->t0pr, base_address + AT91_HDDRSDRC2_T0PR);
+ writel(ddramc_config->t1pr, base_address + AT91_HDDRSDRC2_T1PR);
+ writel(ddramc_config->t2pr, base_address + AT91_HDDRSDRC2_T2PR);
+
+ /*
+ * Step 3: A NOP command is issued to the low-power DDR2-SDRAM.
+ */
+ writel(AT91_DDRC2_MODE_NOP_CMD, base_address + AT91_HDDRSDRC2_MR);
+
+ /*
+ * Step 3bis: Add memory barrier then Perform a write access to
+ * any low-power DDR2-SDRAM address to acknowledge the command.
+ */
+ dmb();
+ writel(0, ram_address);
+
+ /*
+ * Step 4: A pause of at least 100 ns must be observed before
+ * a single toggle.
+ */
+ early_udelay(1);
+
+ /*
+ * Step 5: A NOP command is issued to the low-power DDR2-SDRAM.
+ */
+ writel(AT91_DDRC2_MODE_NOP_CMD, base_address + AT91_HDDRSDRC2_MR);
+ dmb();
+ writel(0, ram_address);
+
+ /*
+ * Step 6: A pause of at least 200 us must be observed before a Reset
+ * Command.
+ */
+ early_udelay(200);
+
+ /*
+ * Step 7: A Reset command is issued to the low-power DDR2-SDRAM.
+ */
+ writel(AT91_DDRC2_MRS(63) | AT91_DDRC2_MODE_LPDDR2_CMD,
+ base_address + AT91_HDDRSDRC2_MR);
+ dmb();
+ writel(0, ram_address);
+
+ /*
+ * Step 8: A pause of at least tINIT5 must be observed before issuing
+ * any commands.
+ */
+ early_udelay(1);
+
+ /*
+ * Step 9: A Calibration command is issued to the low-power DDR2-SDRAM.
+ */
+ reg = readl(base_address + AT91_HDDRSDRC2_CR);
+ reg &= ~AT91_DDRC2_ZQ;
+ reg |= AT91_DDRC2_ZQ_RESET;
+ writel(reg, base_address + AT91_HDDRSDRC2_CR);
+
+ writel(AT91_DDRC2_MRS(10) | AT91_DDRC2_MODE_LPDDR2_CMD,
+ base_address + AT91_HDDRSDRC2_MR);
+ dmb();
+ writel(0, ram_address);
+
+ /*
+ * Step 9bis: The ZQ Calibration command is now issued.
+ * Program the type of calibration in the MPDDRC_CR: set the
+ * ZQ field to the SHORT value.
+ */
+ reg = readl(base_address + AT91_HDDRSDRC2_CR);
+ reg &= ~AT91_DDRC2_ZQ;
+ reg |= AT91_DDRC2_ZQ_SHORT;
+ writel(reg, base_address + AT91_HDDRSDRC2_CR);
+
+ /*
+ * Step 10: A Mode Register Write command with 1 to the MRS field
+ * is issued to the low-power DDR2-SDRAM.
+ */
+ writel(AT91_DDRC2_MRS(1) | AT91_DDRC2_MODE_LPDDR2_CMD,
+ base_address + AT91_HDDRSDRC2_MR);
+ dmb();
+ writel(0, ram_address);
+
+ /*
+ * Step 11: A Mode Register Write command with 2 to the MRS field
+ * is issued to the low-power DDR2-SDRAM.
+ */
+ writel(AT91_DDRC2_MRS(2) | AT91_DDRC2_MODE_LPDDR2_CMD,
+ base_address + AT91_HDDRSDRC2_MR);
+ dmb();
+ writel(0, ram_address);
+
+ /*
+ * Step 12: A Mode Register Write command with 3 to the MRS field
+ * is issued to the low-power DDR2-SDRAM.
+ */
+ writel(AT91_DDRC2_MRS(3) | AT91_DDRC2_MODE_LPDDR2_CMD,
+ base_address + AT91_HDDRSDRC2_MR);
+ dmb();
+ writel(0, ram_address);
+
+ /*
+ * Step 13: A Mode Register Write command with 16 to the MRS field
+ * is issued to the low-power DDR2-SDRAM.
+ */
+ writel(AT91_DDRC2_MRS(16) | AT91_DDRC2_MODE_LPDDR2_CMD,
+ base_address + AT91_HDDRSDRC2_MR);
+ dmb();
+ writel(0, ram_address);
+
+ /*
+ * Step 14: A Normal Mode command is provided.
+ */
+ writel(AT91_DDRC2_MODE_NORMAL_CMD, base_address + AT91_HDDRSDRC2_MR);
+ dmb();
+ writel(0, ram_address);
+
+ /*
+ * Step 15: close the input buffers: error in documentation: no need.
+ */
+
+ /*
+ * Step 16: Write the refresh rate into the COUNT field in the MPDDRC
+ * Refresh Timer Register.
+ */
+ writel(ddramc_config->rtr, base_address + AT91_HDDRSDRC2_RTR);
+
+ /*
+ * Now configure the CAL MR4 register.
+ */
+ writel(ddramc_config->cal_mr4r, base_address + AT91_MPDDRC_LPDDR2_CAL_MR4);
+}
+
+void at91_lpddr1_sdram_initialize(void __iomem *base_address,
+ void __iomem *ram_address,
+ struct at91_ddramc_register *ddramc_config)
+{
+ unsigned long ba_offset;
+
+ /* Compute BA[] offset according to CR configuration */
+ ba_offset = (ddramc_config->cr & AT91_DDRC2_NC) + 8;
+ if (!(ddramc_config->cr & AT91_DDRC2_DECOD_INTERLEAVED))
+ ba_offset += ((ddramc_config->cr & AT91_DDRC2_NR) >> 2) + 11;
+
+ ba_offset += (ddramc_config->mdr & AT91_DDRC2_DBW) ? 1 : 2;
+
+ /*
+ * Step 1: Program the memory device type in the MPDDRC Memory Device Register
+ */
+ writel(ddramc_config->mdr, base_address + AT91_HDDRSDRC2_MDR);
+
+ /*
+ * Step 2: Program the features of the low-power DDR1-SDRAM device
+ * in the MPDDRC Configuration Register and in the MPDDRC Timing
+ * Parameter 0 Register/MPDDRC Timing Parameter 1 Register.
+ */
+ writel(ddramc_config->cr, base_address + AT91_HDDRSDRC2_CR);
+
+ writel(ddramc_config->t0pr, base_address + AT91_HDDRSDRC2_T0PR);
+ writel(ddramc_config->t1pr, base_address + AT91_HDDRSDRC2_T1PR);
+ writel(ddramc_config->t2pr, base_address + AT91_HDDRSDRC2_T2PR);
+
+ /*
+ * Step 3: Program Temperature Compensated Self-refresh (TCR),
+ * Partial Array Self-refresh (PASR) and Drive Strength (DS) parameters
+ * in the MPDDRC Low-power Register.
+ */
+ writel(ddramc_config->lpr, base_address + AT91_HDDRSDRC2_LPR);
+
+ /*
+ * Step 4: A NOP command is issued to the low-power DDR1-SDRAM.
+ * Program the NOP command in the MPDDRC Mode Register (MPDDRC_MR).
+ * The clocks which drive the low-power DDR1-SDRAM device
+ * are now enabled.
+ */
+ writel(AT91_DDRC2_MODE_NOP_CMD, base_address + AT91_HDDRSDRC2_MR);
+ writel(0, ram_address);
+
+ /*
+ * Step 5: A pause of at least 200 us must be observed before
+ * a signal toggle.
+ */
+ early_udelay(200);
+
+ /*
+ * Step 6: A NOP command is issued to the low-power DDR1-SDRAM.
+ * Program the NOP command in the MPDDRC_MR. calibration request is
+ * now made to the I/O pad.
+ */
+ writel(AT91_DDRC2_MODE_NOP_CMD, base_address + AT91_HDDRSDRC2_MR);
+ writel(0, ram_address);
+
+ /*
+ * Step 7: An All Banks Precharge command is issued
+ * to the low-power DDR1-SDRAM.
+ * Program All Banks Precharge command in the MPDDRC_MR.
+ */
+ writel(AT91_DDRC2_MODE_PRCGALL_CMD, base_address + AT91_HDDRSDRC2_MR);
+ writel(0, ram_address);
+
+ /*
+ * Step 8: Two auto-refresh (CBR) cycles are provided.
+ * Program the Auto Refresh command (CBR) in the MPDDRC_MR.
+ * The application must write a four to the MODE field
+ * in the MPDDRC_MR. Perform a write access to any low-power
+ * DDR1-SDRAM location twice to acknowledge these commands.
+ */
+ writel(AT91_DDRC2_MODE_RFSH_CMD, base_address + AT91_HDDRSDRC2_MR);
+ writel(0, ram_address);
+
+ writel(AT91_DDRC2_MODE_RFSH_CMD, base_address + AT91_HDDRSDRC2_MR);
+ writel(0, ram_address);
+
+ /*
+ * Step 9: An Extended Mode Register Set (EMRS) cycle is issued to
+ * program the low-power DDR1-SDRAM parameters (TCSR, PASR, DS).
+ * The application must write a five to the MODE field in the MPDDRC_MR
+ * and perform a write access to the SDRAM to acknowledge this command.
+ * The write address must be chosen so that signal BA[1] is set to 1
+ * and BA[0] is set to 0.
+ */
+ writel(AT91_DDRC2_MODE_EXT_LMR_CMD, base_address + AT91_HDDRSDRC2_MR);
+ writel(0, ram_address + (0x2 << ba_offset));
+
+ /*
+ * Step 10: A Mode Register Set (MRS) cycle is issued to program
+ * parameters of the low-power DDR1-SDRAM devices, in particular
+ * CAS latency.
+ * The application must write a three to the MODE field in the MPDDRC_MR
+ * and perform a write access to the SDRAM to acknowledge this command.
+ * The write address must be chosen so that signals BA[1:0] are set to 0.
+ */
+ writel(AT91_DDRC2_MODE_LMR_CMD, base_address + AT91_HDDRSDRC2_MR);
+ writel(0, ram_address + (0x0 << ba_offset));
+
+ /*
+ * Step 11: The application must enter Normal mode, write a zero
+ * to the MODE field in the MPDDRC_MR and perform a write access
+ * at any location in the SDRAM to acknowledge this command.
+ */
+ writel(AT91_DDRC2_MODE_NORMAL_CMD, base_address + AT91_HDDRSDRC2_MR);
+ writel(0, ram_address);
+
+ /*
+ * Step 12: Perform a write access to any low-power DDR1-SDRAM address.
+ */
+ writel(0, ram_address);
+
+ /*
+ * Step 14: Write the refresh rate into the COUNT field in the MPDDRC
+ * Refresh Timer Register (MPDDRC_RTR):
+ */
+ writel(ddramc_config->rtr, base_address + AT91_HDDRSDRC2_RTR);
+}
diff --git a/arch/arm/mach-at91/early_udelay.c b/arch/arm/mach-at91/early_udelay.c
new file mode 100644
index 0000000000..632e797beb
--- /dev/null
+++ b/arch/arm/mach-at91/early_udelay.c
@@ -0,0 +1,56 @@
+// SPDX-License-Identifier: BSD-1-Clause
+/*
+ * Copyright (c) 2012, Atmel Corporation
+ */
+
+#include <mach/hardware.h>
+#include <asm/io.h>
+#include <mach/at91_pmc_ll.h>
+#include <mach/at91_pit.h>
+#include <mach/early_udelay.h>
+
+static unsigned int master_clock;
+static void __iomem *pmc, *pit;
+static bool has_h32mxdiv;
+
+/* Because the below statement is used in the function:
+ * ((MASTER_CLOCK >> 10) * usec) is used,
+ * to our 32-bit system. the argu "usec" maximum value is:
+ * supposed "MASTER_CLOCK" is 132M.
+ * 132000000 / 1024 = 128906
+ * (0xffffffff) / 128906 = 33318.
+ * So the maximum delay time is 33318 us.
+ */
+/* requires PIT to be initialized, but not the clocksource framework */
+void early_udelay(unsigned int usec)
+{
+ unsigned int delay;
+ unsigned int current;
+ unsigned int base = readl(pit + AT91_PIT_PIIR);
+
+ if (has_h32mxdiv)
+ master_clock /= 2;
+
+ delay = ((master_clock >> 10) * usec) >> 14;
+
+ do {
+ current = readl(pit + AT91_PIT_PIIR);
+ current -= base;
+ } while (current < delay);
+}
+
+void early_udelay_init(void __iomem *pmc_base,
+ void __iomem *pit_base,
+ unsigned int clock,
+ unsigned int master_clock_rate,
+ unsigned int flags)
+{
+ master_clock = master_clock_rate;
+ pmc = pmc_base;
+ pit = pit_base;
+ has_h32mxdiv = at91_pmc_check_mck_h32mxdiv(pmc, flags);
+
+ writel(AT91_PIT_PIV | AT91_PIT_PITEN, pit + AT91_PIT_MR);
+
+ at91_pmc_enable_periph_clock(pmc_base, clock);
+}
diff --git a/arch/arm/mach-at91/include/mach/aic.h b/arch/arm/mach-at91/include/mach/aic.h
new file mode 100644
index 0000000000..c1f026b60c
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/aic.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: BSD-1-Clause */
+#ifndef __AT91_AIC_H_
+#define __AT91_AIC_H_
+
+#include <linux/compiler.h>
+
+void at91_aic_redir(void __iomem *sfr, u32 key);
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/at91_dbgu.h b/arch/arm/mach-at91/include/mach/at91_dbgu.h
index 0ba9cdae10..29aaa2dfe1 100644
--- a/arch/arm/mach-at91/include/mach/at91_dbgu.h
+++ b/arch/arm/mach-at91/include/mach/at91_dbgu.h
@@ -94,30 +94,28 @@ static inline void at91_dbgu_setup_ll(void __iomem *dbgu_base,
unsigned mck,
unsigned baudrate)
{
- if (IS_ENABLED(CONFIG_DEBUG_LL)) {
- u32 brgr = mck / (baudrate * 16);
+ u32 brgr = mck / (baudrate * 16);
- if ((mck / (baudrate * 16)) % 10 >= 5)
- brgr++;
+ if ((mck / (baudrate * 16)) % 10 >= 5)
+ brgr++;
- writel(~0, dbgu_base + AT91_DBGU_IDR);
+ writel(~0, dbgu_base + AT91_DBGU_IDR);
- writel(AT91_DBGU_RSTRX
- | AT91_DBGU_RSTTX
- | AT91_DBGU_RXDIS
- | AT91_DBGU_TXDIS,
- dbgu_base + AT91_DBGU_CR);
+ writel(AT91_DBGU_RSTRX
+ | AT91_DBGU_RSTTX
+ | AT91_DBGU_RXDIS
+ | AT91_DBGU_TXDIS,
+ dbgu_base + AT91_DBGU_CR);
- writel(brgr, dbgu_base + AT91_DBGU_BRGR);
+ writel(brgr, dbgu_base + AT91_DBGU_BRGR);
- writel(AT91_DBGU_PAR_NONE
- | AT91_DBGU_CHMODE_NORMAL
- | AT91_DBGU_CHRL_8BIT
- | AT91_DBGU_NBSTOP_1BIT,
- dbgu_base + AT91_DBGU_MR);
+ writel(AT91_DBGU_PAR_NONE
+ | AT91_DBGU_CHMODE_NORMAL
+ | AT91_DBGU_CHRL_8BIT
+ | AT91_DBGU_NBSTOP_1BIT,
+ dbgu_base + AT91_DBGU_MR);
- writel(AT91_DBGU_RXEN | AT91_DBGU_TXEN, dbgu_base + AT91_DBGU_CR);
- }
+ writel(AT91_DBGU_RXEN | AT91_DBGU_TXEN, dbgu_base + AT91_DBGU_CR);
}
#endif
diff --git a/arch/arm/mach-at91/include/mach/at91_ddrsdrc.h b/arch/arm/mach-at91/include/mach/at91_ddrsdrc.h
new file mode 100644
index 0000000000..7d70fe4cb4
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/at91_ddrsdrc.h
@@ -0,0 +1,373 @@
+/* SPDX-License-Identifier: BSD-1-Clause */
+/*
+ * Copyright (c) 2006, Atmel Corporation
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ */
+#ifndef __AT91_DDRSDRC_H__
+#define __AT91_DDRSDRC_H__
+
+/**** Register offset in AT91S_HDDRSDRC2 structure ***/
+#define AT91_HDDRSDRC2_MR 0x00 /* Mode Register */
+#define AT91_HDDRSDRC2_RTR 0x04 /* Refresh Timer Register */
+#define AT91_HDDRSDRC2_CR 0x08 /* Configuration Register */
+#define AT91_HDDRSDRC2_T0PR 0x0C /* Timing Parameter 0 Register */
+#define AT91_HDDRSDRC2_T1PR 0x10 /* Timing Parameter 1 Register */
+#define AT91_HDDRSDRC2_T2PR 0x14 /* Timing Parameter 2 Register */
+#define AT91_HDDRSDRC2_T3PR 0x18 /* Timing Parameter 3 Register */
+#define AT91_HDDRSDRC2_LPR 0x1C /* Low-power Register */
+#define AT91_HDDRSDRC2_MDR 0x20 /* Memory Device Register */
+#define AT91_HDDRSDRC2_DLL 0x24 /* DLL Information Register */
+#define AT91_HDDRSDRC2_HS 0x2C /* High Speed Register */
+
+/* below items defined for sama5d3x */
+#define AT91_MPDDRC_LPDDR2_HS 0x24 /* MPDDRC LPDDR2 High Speed Register */
+#define AT91_MPDDRC_LPDDR2_LPR 0x28 /* MPDDRC LPDDR2 Low-power Register */
+#define AT91_MPDDRC_LPDDR2_CAL_MR4 0x2C /* MPDDRC LPDDR2 Calibration and MR4 Register */
+#define AT91_MPDDRC_LPDDR2_TIM_CAL 0x30 /* MPDDRC LPDDR2 Timing Calibration Register */
+#define AT91_MPDDRC_IO_CALIBR 0x34 /* MPDDRC IO Calibration */
+#define AT91_MPDDRC_OCMS 0x38 /* MPDDRC OCMS Register */
+#define AT91_MPDDRC_OCMS_KEY1 0x3C /* MPDDRC OCMS KEY1 Register */
+#define AT91_MPDDRC_OCMS_KEY2 0x40 /* MPDDRC OCMS KEY2 Register */
+/* 0x54 ~ 0x70 Reserved */
+#define AT91_MPDDRC_DLL_MOR 0x74 /* MPDDRC DLL Master Offset Register */
+#define AT91_MPDDRC_DLL_SOR 0x78 /* MPDDRC DLL Slave Offset Register */
+#define AT91_MPDDRC_DLL_MSR 0x7C /* MPDDRC DLL Master Status Register */
+#define AT91_MPDDRC_DLL_S0SR 0x80 /* MPDDRC DLL Slave 0 Status Register */
+#define AT91_MPDDRC_DLL_S1SR 0x84 /* MPDDRC DLL Slave 1 Status Register */
+
+#define AT91_MPDDRC_RD_DATA_PATH 0x5C /* MPDDRC Read Data Path */
+
+/* 0x94 ~ 0xE0 Reserved */
+#define AT91_HDDRSDRC2_WPCR 0xE4 /* Write Protect Mode Register */
+#define AT91_HDDRSDRC2_WPSR 0xE8 /* Write Protect Status Register */
+
+/* -------- HDDRSDRC2_MR : (HDDRSDRC2 Offset: 0x0) Mode Register --------*/
+#define AT91_DDRC2_MODE (0x7UL << 0)
+#define AT91_DDRC2_MODE_NORMAL_CMD (0x0UL)
+#define AT91_DDRC2_MODE_NOP_CMD (0x1UL)
+#define AT91_DDRC2_MODE_PRCGALL_CMD (0x2UL)
+#define AT91_DDRC2_MODE_LMR_CMD (0x3UL)
+#define AT91_DDRC2_MODE_RFSH_CMD (0x4UL)
+#define AT91_DDRC2_MODE_EXT_LMR_CMD (0x5UL)
+#define AT91_DDRC2_MODE_DEEP_CMD (0x6UL)
+#define AT91_DDRC2_MODE_LPDDR2_CMD (0x7UL)
+#define AT91_DDRC2_MRS(value) (value << 8)
+
+/* -------- HDDRSDRC2_RTR : (HDDRSDRC2 Offset: 0x4) Refresh Timer Register -------- */
+#define AT91_DDRC2_COUNT (0xFFFUL << 0)
+#define AT91_DDRC2_ADJ_REF (0x1UL << 16)
+#define AT91_DDRC2_DISABLE_ADJ_REF (0x0UL << 16)
+#define AT91_DDRC2_ENABLE_ADJ_REF (0x1UL << 16)
+
+/* -------- HDDRSDRC2_CR : (HDDRSDRC2 Offset: 0x8) Configuration Register --------*/
+#define AT91_DDRC2_NC (0x3UL << 0)
+#define AT91_DDRC2_NC_DDR9_SDR8 (0x0UL)
+#define AT91_DDRC2_NC_DDR10_SDR9 (0x1UL)
+#define AT91_DDRC2_NC_DDR11_SDR10 (0x2UL)
+#define AT91_DDRC2_NC_DDR12_SDR11 (0x3UL)
+#define AT91_DDRC2_NR (0x3UL << 2)
+#define AT91_DDRC2_NR_11 (0x0UL << 2)
+#define AT91_DDRC2_NR_12 (0x1UL << 2)
+#define AT91_DDRC2_NR_13 (0x2UL << 2)
+#define AT91_DDRC2_NR_14 (0x3UL << 2)
+#define AT91_DDRC2_CAS (0x7UL << 4)
+#define AT91_DDRC2_CAS_2 (0x2UL << 4)
+#define AT91_DDRC2_CAS_3 (0x3UL << 4)
+#define AT91_DDRC2_CAS_4 (0x4UL << 4)
+#define AT91_DDRC2_CAS_5 (0x5UL << 4)
+#define AT91_DDRC2_CAS_6 (0x6UL << 4)
+#define AT91_DDRC2_RESET_DLL (0x1UL << 7)
+#define AT91_DDRC2_DISABLE_RESET_DLL (0x0UL << 7)
+#define AT91_DDRC2_ENABLE_RESET_DLL (0x1UL << 7)
+#define AT91_DDRC2_DIC_DS (0x1UL << 8)
+#define AT91_DDRC2_NORMAL_STRENGTH_RZQ6 (0x0UL << 8)
+#define AT91_DDRC2_WEAK_STRENGTH_RZQ7 (0x1UL << 8)
+#define AT91_DDRC2_DLL (0x1UL << 9)
+#define AT91_DDRC2_ENABLE_DLL (0x0UL << 9)
+#define AT91_DDRC2_DISABLE_DLL (0x1UL << 9)
+#define AT91_DDRC2_ZQ (0x03 << 10)
+#define AT91_DDRC2_ZQ_INIT (0x0 << 10)
+#define AT91_DDRC2_ZQ_LONG (0x1 << 10)
+#define AT91_DDRC2_ZQ_SHORT (0x2 << 10)
+#define AT91_DDRC2_ZQ_RESET (0x3 << 10)
+#define AT91_DDRC2_OCD (0x7UL << 12)
+#define AT91_DDRC2_OCD_EXIT (0x0UL << 12)
+#define AT91_DDRC2_OCD_DEFAULT (0x7UL << 12)
+#define AT91_DDRC2_EBISHARE (0x1UL << 16)
+#define AT91_DDRC2_DQMS (0x1UL << 16)
+#define AT91_DDRC2_DQMS_NOT_SHARED (0x0UL << 16)
+#define AT91_DDRC2_DQMS_SHARED (0x1UL << 16)
+#define AT91_DDRC2_ENRDM (0x1UL << 17)
+#define AT91_DDRC2_ENRDM_DISABLE (0x0UL << 17)
+#define AT91_DDRC2_ENRDM_ENABLE (0x1UL << 17)
+#define AT91_DDRC2_ACTBST (0x1UL << 18)
+#define AT91_DDRC2_NB_BANKS (0x1UL << 20)
+#define AT91_DDRC2_NB_BANKS_4 (0x0UL << 20)
+#define AT91_DDRC2_NB_BANKS_8 (0x1UL << 20)
+#define AT91_DDRC2_NDQS (0x1UL << 21) /* Not DQS(sama5d3x only) */
+#define AT91_DDRC2_NDQS_ENABLED (0x0UL << 21)
+#define AT91_DDRC2_NDQS_DISABLED (0x1UL << 21)
+#define AT91_DDRC2_DECOD (0x1UL << 22)
+#define AT91_DDRC2_DECOD_SEQUENTIAL (0x0UL << 22)
+#define AT91_DDRC2_DECOD_INTERLEAVED (0x1UL << 22)
+#define AT91_DDRC2_UNAL (0x1UL << 23) /* Support Unaligned Access(sama5d3x only) */
+#define AT91_DDRC2_UNAL_UNSUPPORTED (0x0UL << 23)
+#define AT91_DDRC2_UNAL_SUPPORTED (0x1UL << 23)
+
+/* -------- HDDRSDRC2_T0PR : (HDDRSDRC2 Offset: 0xc) Timing0 Register --------*/
+#define AT91_DDRC2_TRAS (0xFUL << 0)
+#define AT91_DDRC2_TRAS_(x) (x & 0x0f)
+#define AT91_DDRC2_TRCD (0xFUL << 4)
+#define AT91_DDRC2_TRCD_(x) ((x & 0x0f) << 4)
+#define AT91_DDRC2_TWR (0xFUL << 8)
+#define AT91_DDRC2_TWR_(x) ((x & 0x0f) << 8)
+#define AT91_DDRC2_TRC (0xFUL << 12)
+#define AT91_DDRC2_TRC_(x) ((x & 0x0f) << 12)
+#define AT91_DDRC2_TRP (0xFUL << 16)
+#define AT91_DDRC2_TRP_(x) ((x & 0x0f) << 16)
+#define AT91_DDRC2_TRRD (0xFUL << 20)
+#define AT91_DDRC2_TRRD_(x) ((x & 0x0f) << 20)
+#define AT91_DDRC2_TWTR (0xFUL << 24)
+#define AT91_DDRC2_TWTR_(x) ((x & 0x0f) << 24)
+#define AT91_DDRC2_TMRD (0xFUL << 28)
+#define AT91_DDRC2_TMRD_(x) ((x & 0x0f) << 28)
+
+/* -------- HDDRSDRC2_T1PR : (HDDRSDRC2 Offset: 0x10) Timing1 Register -------- */
+#define AT91_DDRC2_TRFC (0x7FUL << 0)
+#define AT91_DDRC2_TRFC_(x) (x & 0x7f)
+#define AT91_DDRC2_TXSNR (0xFFUL << 8)
+#define AT91_DDRC2_TXSNR_(x) ((x & 0xff) << 8)
+#define AT91_DDRC2_TXSRD (0xFFUL << 16)
+#define AT91_DDRC2_TXSRD_(x) ((x & 0xff) << 16)
+#define AT91_DDRC2_TXP (0xFUL << 24)
+#define AT91_DDRC2_TXP_(x) ((x & 0x0f) << 24)
+
+/* -------- HDDRSDRC2_T2PR : (HDDRSDRC2 Offset: 0x14) Timing2 Register --------*/
+#define AT91_DDRC2_TXARD (0xFUL << 0)
+#define AT91_DDRC2_TXARD_(x) (x & 0x0f)
+#define AT91_DDRC2_TXARDS (0xFUL << 4)
+#define AT91_DDRC2_TXARDS_(x) ((x & 0x0f) << 4)
+#define AT91_DDRC2_TRPA (0xFUL << 8)
+#define AT91_DDRC2_TRPA_(x) ((x & 0x0f) << 8)
+#define AT91_DDRC2_TRT (0xFUL << 12)
+#define AT91_DDRC2_TRTP_(x) ((x & 0x0f) << 12)
+#define AT91_DDRC2_TFA (0xFUL << 16)
+#define AT91_DDRC2_TFAW_(x) ((x & 0x0f) << 16)
+
+/* -------- HDDRSDRC2_LPR : (HDDRSDRC2 Offset: 0x1c) --------*/
+#define AT91_DDRC2_LPCB (0x3UL << 0)
+#define AT91_DDRC2_LPCB_DISABLED (0x0UL)
+#define AT91_DDRC2_LPCB_SELFREFRESH (0x1UL)
+#define AT91_DDRC2_LPCB_POWERDOWN (0x2UL)
+#define AT91_DDRC2_LPCB_DEEP_PWD (0x3UL)
+#define AT91_DDRC2_CLK_FR (0x1UL << 2)
+#define AT91_DDRC2_PASR (0x7UL << 4)
+#define AT91_DDRC2_PASR_(x) ((x & 0x7) << 4)
+#define AT91_DDRC2_DS (0x7UL << 8)
+#define AT91_DDRC2_DS_(x) ((x & 0x7) << 8)
+#define AT91_DDRC2_TIMEOUT (0x3UL << 12)
+#define AT91_DDRC2_TIMEOUT_0 (0x0UL << 12)
+#define AT91_DDRC2_TIMEOUT_64 (0x1UL << 12)
+#define AT91_DDRC2_TIMEOUT_128 (0x2UL << 12)
+#define AT91_DDRC2_TIMEOUT_Reserved (0x3UL << 12)
+#define AT91_DDRC2_ADPE (0x1UL << 16)
+#define AT91_DDRC2_ADPE_FAST (0x0UL << 16)
+#define AT91_DDRC2_ADPE_SLOW (0x1UL << 16)
+#define AT91_DDRC2_UPD_MR (0x3UL << 20)
+#define AT91_DDRC2_UPD_MR_NO_UPDATE (0x0UL << 20)
+#define AT91_DDRC2_UPD_MR_SHARED_BUS (0x1UL << 20)
+#define AT91_DDRC2_UPD_MR_NO_SHARED_BUS (0x2UL << 20)
+#define AT91_DDRC2_SELF_DONE (0x1UL << 25)
+
+/* -------- HDDRSDRC2_MDR : (HDDRSDRC2 Offset: 0x20) Memory Device Register -------- */
+#define AT91_DDRC2_MD (0x7UL << 0)
+#define AT91_DDRC2_MD_SDR_SDRAM (0x0UL)
+#define AT91_DDRC2_MD_LP_SDR_SDRAM (0x1UL)
+#define AT91_DDRC2_MD_DDR_SDRAM (0x2UL)
+#define AT91_DDRC2_MD_LP_DDR_SDRAM (0x3UL)
+#define AT91_DDRC2_MD_DDR3_SDRAM (0x4UL)
+#define AT91_DDRC2_MD_LPDDR3_SDRAM (0x5UL)
+#define AT91_DDRC2_MD_DDR2_SDRAM (0x6UL)
+#define AT91_DDRC2_MD_LPDDR2_SDRAM (0x7UL)
+#define AT91_DDRC2_DBW (0x1UL << 4)
+#define AT91_DDRC2_DBW_32_BITS (0x0UL << 4)
+#define AT91_DDRC2_DBW_16_BITS (0x1UL << 4)
+
+/* -------- HDDRSDRC2_DLL : (HDDRSDRC2 Offset: 0x24) DLL Information Register --------*/
+#define AT91_DDRC2_MDINC (0x1UL << 0)
+#define AT91_DDRC2_MDDEC (0x1UL << 1)
+#define AT91_DDRC2_MDOVF (0x1UL << 2)
+#define AT91_DDRC2_MDVAL (0xFFUL << 8)
+
+/* ------- MPDDRC_LPDDR2_LPR (offset: 0x28) */
+#define AT91_LPDDRC2_BK_MASK_PASR(value) (value << 0)
+#define AT91_LPDDRC2_SEG_MASK(value) (value << 8)
+#define AT91_LPDDRC2_DS(value) (value << 24)
+
+/* -------- HDDRSDRC2_HS : (HDDRSDRC2 Offset: 0x2c) High Speed Register --------*/
+#define AT91_DDRC2_NO_ANT (0x1UL << 2)
+
+/* -------- MPDDRC_LPDDR2_CAL_MR4: (MPDDRC Offset: 0x2c) Calibration and MR4 Register --------*/
+#define AT91_DDRC2_COUNT_CAL_MASK (0xFFFFUL)
+#define AT91_DDRC2_COUNT_CAL(value) (((value) & AT91_DDRC2_COUNT_CAL_MASK) << 0)
+#define AT91_DDRC2_MR4R(value) (((value) & 0xFFFFUL) << 16)
+
+/* -------- MPDDRC_LPDDR2_TIM_CAL : (MPDDRC Offset: 0x30) */
+#define AT91_DDRC2_ZQCS(value) (value << 0)
+
+/* -------- MPDDRC_IO_CALIBR : (MPDDRC Offset: 0x34) IO Calibration --------*/
+#define AT91_MPDDRC_RDIV (0x7UL << 0)
+#define AT91_MPDDRC_RDIV_LPDDR2_RZQ_34 (0x1UL << 0)
+#define AT91_MPDDRC_RDIV_LPDDR2_RZQ_48 (0x3UL << 0)
+#define AT91_MPDDRC_RDIV_LPDDR2_RZQ_60 (0x4UL << 0)
+#define AT91_MPDDRC_RDIV_LPDDR2_RZQ_120 (0x7UL << 0)
+
+#define AT91_MPDDRC_RDIV_DDR2_RZQ_33_3 (0x2UL << 0)
+#define AT91_MPDDRC_RDIV_DDR2_RZQ_50 (0x4UL << 0)
+#define AT91_MPDDRC_RDIV_DDR2_RZQ_66_7 (0x6UL << 0)
+#define AT91_MPDDRC_RDIV_DDR2_RZQ_100 (0x7UL << 0)
+
+#define AT91_MPDDRC_RDIV_LPDDR3_RZQ_38 (0x02UL << 0)
+#define AT91_MPDDRC_RDIV_LPDDR3_RZQ_46 (0x03UL << 0)
+#define AT91_MPDDRC_RDIV_LPDDR3_RZQ_57 (0x04UL << 0)
+#define AT91_MPDDRC_RDIV_LPDDR3_RZQ_77 (0x06UL << 0)
+#define AT91_MPDDRC_RDIV_LPDDR3_RZQ_115 (0x07UL << 0)
+
+#define AT91_MPDDRC_ENABLE_CALIB (0x01 << 4)
+#define AT91_MPDDRC_DISABLE_CALIB (0x00 << 4)
+#define AT91_MPDDRC_EN_CALIB (0x01 << 4)
+
+#define AT91_MPDDRC_TZQIO (0x7FUL << 8)
+#define AT91_MPDDRC_TZQIO_(x) ((x) << 8)
+#define AT91_MPDDRC_TZQIO_0 (0x0UL << 8)
+#define AT91_MPDDRC_TZQIO_1 (0x1UL << 8)
+#define AT91_MPDDRC_TZQIO_3 (0x3UL << 8)
+#define AT91_MPDDRC_TZQIO_4 (0x4UL << 8)
+#define AT91_MPDDRC_TZQIO_5 (0x5UL << 8)
+#define AT91_MPDDRC_TZQIO_31 (0x1FUL << 8)
+
+#define AT91_MPDDRC_CALCODEP (0xFUL << 16)
+#define AT91_MPDDRC_CALCODEP_(x) ((x) << 16)
+
+#define AT91_MPDDRC_CALCODEN (0xFUL << 20)
+#define AT91_MPDDRC_CALCODEN_(x) ((x) << 20)
+
+/* ---- MPDDRC_RD_DATA_PATH : (MPDDRC Offset: 0x5c) MPDDRC Read Data Path */
+#define AT91_MPDDRC_SHIFT_SAMPLING (0x03 << 0)
+#define AT91_MPDDRC_RD_DATA_PATH_NO_SHIFT (0x00 << 0)
+#define AT91_MPDDRC_RD_DATA_PATH_ONE_CYCLES (0x01 << 0)
+#define AT91_MPDDRC_RD_DATA_PATH_TWO_CYCLES (0x02 << 0)
+#define AT91_MPDDRC_RD_DATA_PATH_THREE_CYCLES (0x03 << 0)
+
+/* -------- MPDDRC_DLL_MOR : (MPDDRC Offset: 0x74) DLL Master Offset Register --------*/
+#define AT91_MPDDRC_MOFF(value) (value << 0)
+#define AT91_MPDDRC_MOFF_1 (0x1UL << 0)
+#define AT91_MPDDRC_MOFF_7 (0x7UL << 0)
+#define AT91_MPDDRC_CLK90OFF(value) (value << 8)
+#define AT91_MPDDRC_CLK90OFF_1 (0x1UL << 8)
+#define AT91_MPDDRC_CLK90OFF_31 (0x1FUL << 8)
+#define AT91_MPDDRC_SELOFF (0x1UL << 16)
+#define AT91_MPDDRC_SELOFF_DISABLED (0x0UL << 16)
+#define AT91_MPDDRC_SELOFF_ENABLED (0x1UL << 16)
+#define AT91_MPDDRC_KEY (0xC5UL << 24)
+
+/* -------- MPDDRC_DLL_SOR : (MPDDRC Offset: 0x78) DLL Slave Offset Register --------*/
+#define AT91_MPDDRC_S0OFF_1 (0x1UL << 0)
+#define AT91_MPDDRC_S1OFF_1 (0x1UL << 8)
+#define AT91_MPDDRC_S2OFF_1 (0x1UL << 16)
+#define AT91_MPDDRC_S3OFF_1 (0x1UL << 24)
+
+#define AT91_MPDDRC_S0OFF(value) (value << 0)
+#define AT91_MPDDRC_S1OFF(value) (value << 8)
+#define AT91_MPDDRC_S2OFF(value) (value << 16)
+#define AT91_MPDDRC_S3OFF(value) (value << 24)
+
+/* -------- HDDRSDRC2_WPCR : (HDDRSDRC2 Offset: 0xe4) Write Protect Control Register --------*/
+#define AT91_DDRC2_WPEN (0x1UL << 0)
+#define AT91_DDRC2_WPKEY (0xFFFFFFUL << 8)
+
+/* -------- HDDRSDRC2_WPSR : (HDDRSDRC2 Offset: 0xe8) Write Protect Status Register --------*/
+#define AT91_DDRC2_WPVS (0x1UL << 0)
+#define AT91_DDRC2_WPSRC (0xFFFFUL << 8)
+
+#ifndef __ASSEMBLY__
+#include <common.h>
+#include <io.h>
+#include <mach/hardware.h>
+
+static inline u32 at91_get_ddram_size(void __iomem *base, bool is_nb)
+{
+ u32 cr;
+ u32 mdr;
+ u32 size;
+ bool is_sdram;
+
+ cr = readl(base + AT91_HDDRSDRC2_CR);
+ mdr = readl(base + AT91_HDDRSDRC2_MDR);
+
+ /* will always be false for sama5d2, sama5d3 or sama5d4 */
+ is_sdram = (mdr & AT91_DDRC2_MD) <= AT91_DDRC2_MD_LP_SDR_SDRAM;
+
+ /* Formula:
+ * size = bank << (col + row + 1);
+ * if (bandwidth == 32 bits)
+ * size <<= 1;
+ */
+ size = 1;
+ /* COL */
+ size += (cr & AT91_DDRC2_NC) + 8;
+ if (!is_sdram)
+ size ++;
+ /* ROW */
+ size += ((cr & AT91_DDRC2_NR) >> 2) + 11;
+ /* BANK */
+ if (is_nb)
+ size = ((cr & AT91_DDRC2_NB_BANKS) ? 8 : 4) << size;
+ else
+ size = 4 << size;
+
+ /* bandwidth */
+ if (!(mdr & AT91_DDRC2_DBW))
+ size <<= 1;
+
+ return size;
+}
+
+static inline u32 at91sam9g45_get_ddram_size(int bank)
+{
+ switch (bank) {
+ case 0:
+ return at91_get_ddram_size(IOMEM(AT91SAM9G45_BASE_DDRSDRC0), false);
+ case 1:
+ return at91_get_ddram_size(IOMEM(AT91SAM9G45_BASE_DDRSDRC1), false);
+ default:
+ return 0;
+ }
+}
+
+static inline u32 at91sam9x5_get_ddram_size(void)
+{
+ return at91_get_ddram_size(IOMEM(AT91SAM9X5_BASE_DDRSDRC0), true);
+}
+
+static inline u32 at91sam9n12_get_ddram_size(void)
+{
+ return at91_get_ddram_size(IOMEM(AT91SAM9N12_BASE_DDRSDRC0), true);
+}
+
+static inline u32 at91sama5d3_get_ddram_size(void)
+{
+ return at91_get_ddram_size(IOMEM(SAMA5D3_BASE_MPDDRC), true);
+}
+
+static inline u32 at91sama5d4_get_ddram_size(void)
+{
+ return at91_get_ddram_size(IOMEM(SAMA5D4_BASE_MPDDRC), true);
+}
+
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* #ifndef __AT91_DDRSDRC_H__ */
diff --git a/arch/arm/mach-at91/include/mach/at91_pmc.h b/arch/arm/mach-at91/include/mach/at91_pmc.h
index 4d60becefb..66b4e49286 100644
--- a/arch/arm/mach-at91/include/mach/at91_pmc.h
+++ b/arch/arm/mach-at91/include/mach/at91_pmc.h
@@ -42,6 +42,7 @@
#define AT91_CKGR_UCKR 0x1C /* UTMI Clock Register [some SAM9] */
#define AT91_PMC_UPLLEN (1 << 16) /* UTMI PLL Enable */
#define AT91_PMC_UPLLCOUNT (0xf << 20) /* UTMI PLL Start-up Time */
+#define AT91_PMC_UPLLCOUNT_DEFAULT (0x1UL << 20)
#define AT91_PMC_BIASEN (1 << 24) /* UTMI BIAS Enable */
#define AT91_PMC_BIASCOUNT (0xf << 28) /* UTMI BIAS Start-up Time */
@@ -66,9 +67,17 @@
#define AT91_CKGR_PLLAR 0x28 /* PLL A Register */
#define AT91_CKGR_PLLBR 0x2c /* PLL B Register */
#define AT91_PMC_DIV (0xff << 0) /* Divider */
+#define AT91_PMC_DIV_BYPASS (1 << 0) /* Divider bypass */
#define AT91_PMC_PLLCOUNT (0x3f << 8) /* PLL Counter */
#define AT91_PMC_OUT (3 << 14) /* PLL Clock Frequency Range */
+#define AT91_PMC_OUT_0 (0 << 14)
+#define AT91_PMC_OUT_1 (1 << 14)
+#define AT91_PMC_OUT_2 (2 << 14)
+#define AT91_PMC_OUT_3 (3 << 14)
#define AT91_PMC_MUL (0x7ff << 16) /* PLL Multiplier */
+#define AT91_PMC_MUL_(n) (((n) << 16) & AT91_PMC_MUL)
+#define AT91_PMC3_MUL (0x7f << 18) /* PLL Multiplier [SAMA5 only]*/
+#define AT91_PMC3_MUL_(n) (((n) << 18) & AT91_PMC3_MUL)
#define AT91_PMC_USBDIV (3 << 28) /* USB Divisor (PLLB only) */
#define AT91_PMC_USBDIV_1 (0 << 28)
#define AT91_PMC_USBDIV_2 (1 << 28)
@@ -153,6 +162,7 @@
#define AT91_PMC_MOSCSELS (1 << 16) /* Main Oscillator Selection [some SAM9] */
#define AT91_PMC_MOSCRCS (1 << 17) /* Main On-Chip RC [some SAM9] */
#define AT91_PMC_CFDEV (1 << 18) /* Clock Failure Detector Event [some SAM9] */
+#define AT91_PMC_GCKRDY (1 << 24)
#define AT91_PMC_IMR 0x6c /* Interrupt Mask Register */
#define AT91_PMC_PLLICPR 0x80 /* PLL Charge Pump Current Register */
#define AT91_PMC_ICPPLLA (0xf << 0)
@@ -179,6 +189,13 @@
#define AT91_PMC_PCR 0x10c /* Peripheral Control Register [some SAM9] */
#define AT91_PMC_PCR_PID (0x3f << 0) /* Peripheral ID */
+#define AT91_PMC_GCKCSS (0x7 << 8)
+#define AT91_PMC_GCKCSS_SLOW_CLK (0x0 << 8)
+#define AT91_PMC_GCKCSS_MAIN_CLK (0x1 << 8)
+#define AT91_PMC_GCKCSS_PLLA_CLK (0x2 << 8)
+#define AT91_PMC_GCKCSS_UPLL_CLK (0x3 << 8)
+#define AT91_PMC_GCKCSS_MCK_CLK (0x4 << 8)
+#define AT91_PMC_GCKCSS_AUDIO_CLK (0x5 << 8)
#define AT91_PMC_PCR_CMD (0x1 << 12) /* Command */
#define AT91_PMC_PCR_DIV_MASK (0x3 << 16)
#define AT91_PMC_PCR_DIV(n) ((n) << 16) /* Divisor value */
@@ -186,7 +203,12 @@
#define AT91_PMC_PCR_DIV2 0x1 /* Peripheral clock is MCK/2 */
#define AT91_PMC_PCR_DIV4 0x2 /* Peripheral clock is MCK/4 */
#define AT91_PMC_PCR_DIV8 0x3 /* Peripheral clock is MCK/8 */
+#define AT91_PMC_GCKDIV (0xff << 20)
+#define AT91_PMC_GCKDIV_MSK 0xff
+#define AT91_PMC_GCKDIV_OFFSET 20
+#define AT91_PMC_GCKDIV_(x) (((x) & AT91_PMC_GCKDIV_MSK) << AT91_PMC_GCKDIV_OFFSET)
#define AT91_PMC_PCR_EN (0x1 << 28) /* Enable */
+#define AT91_PMC_GCK_EN (0x1 << 29)
#define AT91_PMC_PCER1 0x100 /* Peripheral Clock Enable Register 1 */
#define AT91_PMC_PCDR1 0x104 /* Peripheral Clock Disable Register 1 */
diff --git a/arch/arm/mach-at91/include/mach/at91_pmc_ll.h b/arch/arm/mach-at91/include/mach/at91_pmc_ll.h
index eda40e8e12..6ec3ae0852 100644
--- a/arch/arm/mach-at91/include/mach/at91_pmc_ll.h
+++ b/arch/arm/mach-at91/include/mach/at91_pmc_ll.h
@@ -13,26 +13,39 @@
#define AT91_PMC_LL_FLAG_SAM9X5_PMC (1 << 0)
#define AT91_PMC_LL_FLAG_MEASURE_XTAL (1 << 1)
#define AT91_PMC_LL_FLAG_DISABLE_RC (1 << 2)
+#define AT91_PMC_LL_FLAG_H32MXDIV (1 << 3)
+#define AT91_PMC_LL_FLAG_PMC_UTMI (1 << 4)
+#define AT91_PMC_LL_FLAG_GCSR (1 << 5)
#define AT91_PMC_LL_AT91RM9200 (0)
#define AT91_PMC_LL_AT91SAM9260 (0)
#define AT91_PMC_LL_AT91SAM9261 (0)
#define AT91_PMC_LL_AT91SAM9263 (0)
-#define AT91_PMC_LL_AT91SAM9G45 (0)
+#define AT91_PMC_LL_AT91SAM9G45 (AT91_PMC_LL_FLAG_PMC_UTMI)
#define AT91_PMC_LL_AT91SAM9X5 (AT91_PMC_LL_FLAG_SAM9X5_PMC | \
- AT91_PMC_LL_FLAG_DISABLE_RC)
+ AT91_PMC_LL_FLAG_DISABLE_RC | \
+ AT91_PMC_LL_FLAG_PMC_UTMI)
#define AT91_PMC_LL_AT91SAM9N12 (AT91_PMC_LL_FLAG_SAM9X5_PMC | \
AT91_PMC_LL_FLAG_DISABLE_RC)
#define AT91_PMC_LL_SAMA5D2 (AT91_PMC_LL_FLAG_SAM9X5_PMC | \
- AT91_PMC_LL_FLAG_MEASURE_XTAL)
+ AT91_PMC_LL_FLAG_MEASURE_XTAL | \
+ AT91_PMC_LL_FLAG_PMC_UTMI)
#define AT91_PMC_LL_SAMA5D3 (AT91_PMC_LL_FLAG_SAM9X5_PMC | \
- AT91_PMC_LL_FLAG_DISABLE_RC)
-#define AT91_PMC_LL_SAMA5D4 (AT91_PMC_LL_FLAG_SAM9X5_PMC)
+ AT91_PMC_LL_FLAG_DISABLE_RC | \
+ AT91_PMC_LL_FLAG_PMC_UTMI)
+#define AT91_PMC_LL_SAMA5D4 (AT91_PMC_LL_FLAG_SAM9X5_PMC | \
+ AT91_PMC_LL_FLAG_H32MXDIV | \
+ AT91_PMC_LL_FLAG_PMC_UTMI)
void at91_pmc_init(void __iomem *pmc_base, unsigned int flags);
void at91_pmc_cfg_mck(void __iomem *pmc_base, u32 pmc_mckr, unsigned int flags);
void at91_pmc_cfg_plla(void __iomem *pmc_base, u32 pmc_pllar, unsigned int flags);
+int at91_pmc_enable_generic_clock(void __iomem *pmc_base, void __iomem *sfr_base,
+ unsigned int periph_id,
+ unsigned int clk_source, unsigned int div,
+ unsigned int flags);
+
static inline void at91_pmc_init_pll(void __iomem *pmc_base, u32 pmc_pllicpr)
{
writel(pmc_pllicpr, pmc_base + AT91_PMC_PLLICPR);
@@ -75,4 +88,13 @@ static inline int at91_pmc_sam9x5_enable_periph_clock(void __iomem *pmc_base,
return 0;
}
+static inline bool at91_pmc_check_mck_h32mxdiv(void __iomem *pmc_base,
+ unsigned flags)
+{
+ if (flags & AT91_PMC_LL_FLAG_H32MXDIV)
+ return readl(pmc_base + AT91_PMC_MCKR) & AT91_PMC_H32MXDIV;
+
+ return false;
+}
+
#endif
diff --git a/arch/arm/mach-at91/include/mach/at91_wdt.h b/arch/arm/mach-at91/include/mach/at91_wdt.h
index 36d37b9d2d..d295d35d1b 100644
--- a/arch/arm/mach-at91/include/mach/at91_wdt.h
+++ b/arch/arm/mach-at91/include/mach/at91_wdt.h
@@ -35,4 +35,20 @@
#define AT91_WDT_WDUNF (1 << 0) /* Watchdog Underflow */
#define AT91_WDT_WDERR (1 << 1) /* Watchdog Error */
+#ifndef __ASSEMBLY__
+// SPDX-License-Identifier: BSD-1-Clause
+/*
+ * Copyright (c) 2006, Atmel Corporation
+ */
+
+#include <asm-generic/io.h>
+
+static inline void at91_wdt_disable(void __iomem *wdt_base)
+{
+ u32 reg = readl(wdt_base + AT91_WDT_MR);
+ reg |= AT91_WDT_WDDIS;
+ writel(reg, wdt_base + AT91_WDT_MR);
+}
+
+#endif /* __ASSEMBLY__ */
#endif
diff --git a/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h b/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h
deleted file mode 100644
index 496cf70701..0000000000
--- a/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Header file for the Atmel DDR/SDR SDRAM Controller
- *
- * Copyright (C) 2010 Atmel Corporation
- * Nicolas Ferre <nicolas.ferre@atmel.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-#ifndef AT91SAM9_DDRSDR_H
-#define AT91SAM9_DDRSDR_H
-
-#define AT91_DDRSDRC_MR 0x00 /* Mode Register */
-#define AT91_DDRSDRC_MODE (0x7 << 0) /* Command Mode */
-#define AT91_DDRSDRC_MODE_NORMAL 0
-#define AT91_DDRSDRC_MODE_NOP 1
-#define AT91_DDRSDRC_MODE_PRECHARGE 2
-#define AT91_DDRSDRC_MODE_LMR 3
-#define AT91_DDRSDRC_MODE_REFRESH 4
-#define AT91_DDRSDRC_MODE_EXT_LMR 5
-#define AT91_DDRSDRC_MODE_DEEP 6
-
-#define AT91_DDRSDRC_RTR 0x04 /* Refresh Timer Register */
-#define AT91_DDRSDRC_COUNT (0xfff << 0) /* Refresh Timer Counter */
-
-#define AT91_DDRSDRC_CR 0x08 /* Configuration Register */
-#define AT91_DDRSDRC_NC (3 << 0) /* Number of Column Bits */
-#define AT91_DDRSDRC_NC_SDR8 (0 << 0)
-#define AT91_DDRSDRC_NC_SDR9 (1 << 0)
-#define AT91_DDRSDRC_NC_SDR10 (2 << 0)
-#define AT91_DDRSDRC_NC_SDR11 (3 << 0)
-#define AT91_DDRSDRC_NC_DDR9 (0 << 0)
-#define AT91_DDRSDRC_NC_DDR10 (1 << 0)
-#define AT91_DDRSDRC_NC_DDR11 (2 << 0)
-#define AT91_DDRSDRC_NC_DDR12 (3 << 0)
-#define AT91_DDRSDRC_NR (3 << 2) /* Number of Row Bits */
-#define AT91_DDRSDRC_NR_11 (0 << 2)
-#define AT91_DDRSDRC_NR_12 (1 << 2)
-#define AT91_DDRSDRC_NR_13 (2 << 2)
-#define AT91_DDRSDRC_NR_14 (3 << 2)
-#define AT91_DDRSDRC_CAS (7 << 4) /* CAS Latency */
-#define AT91_DDRSDRC_CAS_2 (2 << 4)
-#define AT91_DDRSDRC_CAS_3 (3 << 4)
-#define AT91_DDRSDRC_CAS_25 (6 << 4)
-#define AT91_DDRSDRC_RST_DLL (1 << 7) /* Reset DLL */
-#define AT91_DDRSDRC_DICDS (1 << 8) /* Output impedance control */
-#define AT91_DDRSDRC_DIS_DLL (1 << 9) /* Disable DLL [SAM9 Only] */
-#define AT91_DDRSDRC_OCD (1 << 12) /* Off-Chip Driver [SAM9 Only] */
-#define AT91_DDRSDRC_DQMS (1 << 16) /* Mask Data is Shared [SAM9 Only] */
-#define AT91_DDRSDRC_ACTBST (1 << 18) /* Active Bank X to Burst Stop Read Access Bank Y [SAM9 Only] */
-#define AT91_DDRSDRC_NB (1 << 20) /* Number of
-Banks [not SAM9G45] */
-#define AT91_SDRAMC_NB_4 (0 << 20)
-#define AT91_SDRAMC_NB_8 (1 << 20)
-
-#define AT91_DDRSDRC_T0PR 0x0C /* Timing 0 Register */
-#define AT91_DDRSDRC_TRAS (0xf << 0) /* Active to Precharge delay */
-#define AT91_DDRSDRC_TRCD (0xf << 4) /* Row to Column delay */
-#define AT91_DDRSDRC_TWR (0xf << 8) /* Write recovery delay */
-#define AT91_DDRSDRC_TRC (0xf << 12) /* Row cycle delay */
-#define AT91_DDRSDRC_TRP (0xf << 16) /* Row precharge delay */
-#define AT91_DDRSDRC_TRRD (0xf << 20) /* Active BankA to BankB */
-#define AT91_DDRSDRC_TWTR (0x7 << 24) /* Internal Write to Read delay */
-#define AT91CAP9_DDRSDRC_TWTR (1 << 24) /* Internal Write to Read delay */
-#define AT91_DDRSDRC_RED_WRRD (0x1 << 27) /* Reduce Write to Read Delay [SAM9 Only] */
-#define AT91_DDRSDRC_TMRD (0xf << 28) /* Load mode to active/refresh delay */
-
-#define AT91_DDRSDRC_T1PR 0x10 /* Timing 1 Register */
-#define AT91_DDRSDRC_TRFC (0x1f << 0) /* Row Cycle Delay */
-#define AT91_DDRSDRC_TXSNR (0xff << 8) /* Exit self-refresh to non-read */
-#define AT91_DDRSDRC_TXSRD (0xff << 16) /* Exit self-refresh to read */
-#define AT91_DDRSDRC_TXP (0xf << 24) /* Exit power-down delay */
-
-#define AT91_DDRSDRC_T2PR 0x14 /* Timing 2 Register [SAM9 Only] */
-#define AT91_DDRSDRC_TXARD (0xf << 0) /* Exit active power down delay to read command in mode "Fast Exit" */
-#define AT91_DDRSDRC_TXARDS (0xf << 4) /* Exit active power down delay to read command in mode "Slow Exit" */
-#define AT91_DDRSDRC_TRPA (0xf << 8) /* Row Precharge All delay */
-#define AT91_DDRSDRC_TRTP (0x7 << 12) /* Read to Precharge delay */
-
-#define AT91_DDRSDRC_LPR 0x1C /* Low Power Register */
-#define AT91CAP9_DDRSDRC_LPR 0x18 /* Low Power Register */
-#define AT91_DDRSDRC_LPCB (3 << 0) /* Low-power Configurations */
-#define AT91_DDRSDRC_LPCB_DISABLE 0
-#define AT91_DDRSDRC_LPCB_SELF_REFRESH 1
-#define AT91_DDRSDRC_LPCB_POWER_DOWN 2
-#define AT91_DDRSDRC_LPCB_DEEP_POWER_DOWN 3
-#define AT91_DDRSDRC_CLKFR (1 << 2) /* Clock Frozen */
-#define AT91_DDRSDRC_PASR (7 << 4) /* Partial Array Self Refresh */
-#define AT91_DDRSDRC_TCSR (3 << 8) /* Temperature Compensated Self Refresh */
-#define AT91_DDRSDRC_DS (3 << 10) /* Drive Strength */
-#define AT91_DDRSDRC_TIMEOUT (3 << 12) /* Time to define when Low Power Mode is enabled */
-#define AT91_DDRSDRC_TIMEOUT_0_CLK_CYCLES (0 << 12)
-#define AT91_DDRSDRC_TIMEOUT_64_CLK_CYCLES (1 << 12)
-#define AT91_DDRSDRC_TIMEOUT_128_CLK_CYCLES (2 << 12)
-#define AT91_DDRSDRC_APDE (1 << 16) /* Active power down exit time */
-#define AT91_DDRSDRC_UPD_MR (3 << 20) /* Update load mode register and extended mode register */
-
-#define AT91_DDRSDRC_MDR 0x20 /* Memory Device Register */
-#define AT91CAP9_DDRSDRC_MDR 0x1C /* Memory Device Register */
-#define AT91_DDRSDRC_MD (3 << 0) /* Memory Device Type */
-#define AT91_DDRSDRC_MD_SDR 0
-#define AT91_DDRSDRC_MD_LOW_POWER_SDR 1
-#define AT91CAP9_DDRSDRC_MD_DDR 2
-#define AT91_DDRSDRC_MD_LOW_POWER_DDR 3
-#define AT91_DDRSDRC_MD_DDR2 6 /* [SAM9 Only] */
-#define AT91_DDRSDRC_DBW (1 << 4) /* Data Bus Width */
-#define AT91_DDRSDRC_DBW_32BITS (0 << 4)
-#define AT91_DDRSDRC_DBW_16BITS (1 << 4)
-
-#define AT91_DDRSDRC_DLL 0x24 /* DLL Information Register */
-#define AT91CAP9_DDRSDRC_DLL 0x20 /* DLL Information Register */
-#define AT91_DDRSDRC_MDINC (1 << 0) /* Master Delay increment */
-#define AT91_DDRSDRC_MDDEC (1 << 1) /* Master Delay decrement */
-#define AT91_DDRSDRC_MDOVF (1 << 2) /* Master Delay Overflow */
-#define AT91CAP9_DDRSDRC_SDCOVF (1 << 3) /* Slave Delay Correction Overflow */
-#define AT91CAP9_DDRSDRC_SDCUDF (1 << 4) /* Slave Delay Correction Underflow */
-#define AT91CAP9_DDRSDRC_SDERF (1 << 5) /* Slave Delay Correction error */
-#define AT91_DDRSDRC_MDVAL (0xff << 8) /* Master Delay value */
-#define AT91CAP9_DDRSDRC_SDVAL (0xff << 16) /* Slave Delay value */
-#define AT91CAP9_DDRSDRC_SDCVAL (0xff << 24) /* Slave Delay Correction value */
-
-#define AT91_DDRSDRC_HS 0x2C /* High Speed Register [SAM9 Only] */
-#define AT91_DDRSDRC_DIS_ATCP_RD (1 << 2) /* Anticip read access is disabled */
-
-#define AT91_DDRSDRC_DELAY(n) (0x30 + (0x4 * (n))) /* Delay I/O Register n */
-
-#define AT91_DDRSDRC_WPMR 0xE4 /* Write Protect Mode Register [SAM9 Only] */
-#define AT91_DDRSDRC_WP (1 << 0) /* Write protect enable */
-#define AT91_DDRSDRC_WPKEY (0xffffff << 8) /* Write protect key */
-#define AT91_DDRSDRC_KEY (0x444452 << 8) /* Write protect key = "DDR" */
-
-#define AT91_DDRSDRC_WPSR 0xE8 /* Write Protect Status Register [SAM9 Only] */
-#define AT91_DDRSDRC_WPVS (1 << 0) /* Write protect violation status */
-#define AT91_DDRSDRC_WPVSRC (0xffff << 8) /* Write protect violation source */
-
-#ifndef __ASSEMBLY__
-#include <io.h>
-#include <mach/hardware.h>
-
-static inline u32 at91_get_ddram_size(void __iomem *base, bool is_nb)
-{
- u32 cr;
- u32 mdr;
- u32 size;
- bool is_sdram;
-
- cr = readl(base + AT91_DDRSDRC_CR);
- mdr = readl(base + AT91_DDRSDRC_MDR);
-
- /* will always be false for sama5d2, sama5d3 or sama5d4 */
- is_sdram = (mdr & AT91_DDRSDRC_MD) <= AT91_DDRSDRC_MD_LOW_POWER_SDR;
-
- /* Formula:
- * size = bank << (col + row + 1);
- * if (bandwidth == 32 bits)
- * size <<= 1;
- */
- size = 1;
- /* COL */
- size += (cr & AT91_DDRSDRC_NC) + 8;
- if (!is_sdram)
- size ++;
- /* ROW */
- size += ((cr & AT91_DDRSDRC_NR) >> 2) + 11;
- /* BANK */
- if (is_nb)
- size = ((cr & AT91_DDRSDRC_NB) ? 8 : 4) << size;
- else
- size = 4 << size;
-
- /* bandwidth */
- if (!(mdr & AT91_DDRSDRC_DBW))
- size <<= 1;
-
- return size;
-}
-
-static inline u32 at91sam9g45_get_ddram_size(int bank)
-{
- switch (bank) {
- case 0:
- return at91_get_ddram_size(IOMEM(AT91SAM9G45_BASE_DDRSDRC0), false);
- case 1:
- return at91_get_ddram_size(IOMEM(AT91SAM9G45_BASE_DDRSDRC1), false);
- default:
- return 0;
- }
-}
-
-static inline u32 at91sam9x5_get_ddram_size(void)
-{
- return at91_get_ddram_size(IOMEM(AT91SAM9X5_BASE_DDRSDRC0), true);
-}
-
-static inline u32 at91sam9n12_get_ddram_size(void)
-{
- return at91_get_ddram_size(IOMEM(AT91SAM9N12_BASE_DDRSDRC0), true);
-}
-
-static inline u32 at91sama5d3_get_ddram_size(void)
-{
- return at91_get_ddram_size(IOMEM(SAMA5D3_BASE_MPDDRC), true);
-}
-
-static inline u32 at91sama5d4_get_ddram_size(void)
-{
- return at91_get_ddram_size(IOMEM(SAMA5D4_BASE_MPDDRC), true);
-}
-
-#endif
-
-#endif
diff --git a/arch/arm/mach-at91/include/mach/barebox-arm.h b/arch/arm/mach-at91/include/mach/barebox-arm.h
new file mode 100644
index 0000000000..4a65c6f8fa
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/barebox-arm.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef AT91_BAREBOX_ARM_H_
+#define AT91_BAREBOX_ARM_H_
+
+#include <asm/barebox-arm.h>
+
+#define SAMA5_ENTRY_FUNCTION(name, r4) \
+ void name (u32 r0, u32 r1, u32 r2, u32 r3); \
+ \
+ static void __##name(u32); \
+ \
+ void NAKED __section(.text_head_entry_##name) name \
+ (u32 r0, u32 r1, u32 r2, u32 r3) \
+ { \
+ register u32 r4 asm("r4"); \
+ __barebox_arm_head(); \
+ __##name(r4); \
+ } \
+ static void NAKED noinline __##name \
+ (u32 r4)
+#endif
diff --git a/arch/arm/mach-at91/include/mach/ddramc.h b/arch/arm/mach-at91/include/mach/ddramc.h
new file mode 100644
index 0000000000..b929bf5f58
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/ddramc.h
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: BSD-1-Clause
+/*
+ * Copyright (c) 2006, Atmel Corporation
+ */
+#ifndef __DDRAMC_H__
+#define __DDRAMC_H__
+
+/* Note: reserved bits must always be zeroed */
+struct at91_ddramc_register {
+ unsigned long mdr;
+ unsigned long cr;
+ unsigned long rtr;
+ unsigned long t0pr;
+ unsigned long t1pr;
+ unsigned long t2pr;
+ unsigned long lpr;
+ unsigned long lpddr2_lpr;
+ unsigned long tim_calr;
+ unsigned long cal_mr4r;
+};
+
+void at91_ddram_initialize(void __iomem *base_address,
+ void __iomem *ram_address,
+ struct at91_ddramc_register *ddramc_config);
+
+void at91_lpddr2_sdram_initialize(void __iomem *base_address,
+ void __iomem *ram_address,
+ struct at91_ddramc_register *ddramc_config);
+
+
+void at91_lpddr1_sdram_initialize(void __iomem *base_address,
+ void __iomem *ram_address,
+ struct at91_ddramc_register *ddramc_config);
+
+void __noreturn sama5d2_barebox_entry(unsigned int r4, void *boarddata);
+
+#endif /* #ifndef __DDRAMC_H__ */
diff --git a/arch/arm/mach-at91/include/mach/debug_ll.h b/arch/arm/mach-at91/include/mach/debug_ll.h
index b713930424..b3cbdbc26f 100644
--- a/arch/arm/mach-at91/include/mach/debug_ll.h
+++ b/arch/arm/mach-at91/include/mach/debug_ll.h
@@ -9,6 +9,9 @@
#define __MACH_DEBUG_LL_H__
#include <asm/io.h>
+#include <mach/gpio.h>
+#include <mach/hardware.h>
+#include <mach/at91_dbgu.h>
#define ATMEL_US_CSR 0x0014
#define ATMEL_US_THR 0x001c
@@ -22,13 +25,19 @@
*
* This does not append a newline
*/
-static inline void PUTC_LL(char c)
+static inline void at91_dbgu_putc(void __iomem *base, int c)
{
- while (!(readl(CONFIG_DEBUG_AT91_UART_BASE + ATMEL_US_CSR) & ATMEL_US_TXRDY))
+ while (!(readl(base + ATMEL_US_CSR) & ATMEL_US_TXRDY))
barrier();
- writel(c, CONFIG_DEBUG_AT91_UART_BASE + ATMEL_US_THR);
+ writel(c, base + ATMEL_US_THR);
- while (!(readl(CONFIG_DEBUG_AT91_UART_BASE + ATMEL_US_CSR) & ATMEL_US_TXEMPTY))
+ while (!(readl(base + ATMEL_US_CSR) & ATMEL_US_TXEMPTY))
barrier();
}
+
+static inline void PUTC_LL(char c)
+{
+ at91_dbgu_putc(IOMEM(CONFIG_DEBUG_AT91_UART_BASE), c);
+}
+
#endif
diff --git a/arch/arm/mach-at91/include/mach/early_udelay.h b/arch/arm/mach-at91/include/mach/early_udelay.h
new file mode 100644
index 0000000000..1c1b0123fe
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/early_udelay.h
@@ -0,0 +1,14 @@
+#ifndef __EARLY_UDELAY_H__
+#define __EARLY_UDELAY_H__
+
+#include <linux/compiler.h>
+
+/* requires PIT to be initialized, but not the clocksource framework */
+void early_udelay(unsigned int usec);
+void early_udelay_init(void __iomem *pmc_base,
+ void __iomem *pit_base,
+ unsigned int clock,
+ unsigned int master_clock_rate,
+ unsigned int flags);
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/matrix.h b/arch/arm/mach-at91/include/mach/matrix.h
new file mode 100644
index 0000000000..5dbfcfe414
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/matrix.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: BSD-1-Clause */
+/*
+ * Copyright (c) 2013, Atmel Corporation
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ */
+#ifndef __MATRIX_H__
+#define __MATRIX_H__
+
+#include <linux/compiler.h>
+
+void at91_matrix_write_protect_enable(void __iomem *matrix_base);
+void at91_matrix_write_protect_disable(void __iomem *matrix_base);
+void at91_matrix_configure_slave_security(void __iomem *matrix_base,
+ unsigned int slave,
+ unsigned int srtop_setting,
+ unsigned int srsplit_setting,
+ unsigned int ssr_setting);
+
+#endif /* #ifndef __MATRIX_H__ */
diff --git a/arch/arm/mach-at91/include/mach/sama5_bootsource.h b/arch/arm/mach-at91/include/mach/sama5_bootsource.h
new file mode 100644
index 0000000000..0f90afe902
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/sama5_bootsource.h
@@ -0,0 +1,49 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef AT91_SAMA5_BOOTSOURCE_H_
+#define AT91_SAMA5_BOOTSOURCE_H_
+
+#include <errno.h>
+#include <bootsource.h>
+#include <linux/bitops.h>
+#include <linux/bitfield.h>
+#include <mach/hardware.h>
+
+/* Boot modes stored by BootROM in r4 */
+#define SAMA5_BOOTSOURCE_SPI 0
+#define SAMA5_BOOTSOURCE_MCI 1
+#define SAMA5_BOOTSOURCE_SMC 2
+#define SAMA5_BOOTSOURCE_TWI 3
+#define SAMA5_BOOTSOURCE_QSPI 4
+#define SAMA5_BOOTSOURCE_SAM_BA 7
+
+#define SAMA5_BOOTSOURCE GENMASK(3, 0)
+#define SAMA5_BOOTSOURCE_INSTANCE GENMASK(7, 4)
+
+static inline int sama5_bootsource(u32 reg)
+{
+ u32 dev = FIELD_GET(SAMA5_BOOTSOURCE, reg);
+
+ switch(dev) {
+ case SAMA5_BOOTSOURCE_MCI:
+ return BOOTSOURCE_MMC;
+ case SAMA5_BOOTSOURCE_SPI:
+ return BOOTSOURCE_SPI_NOR;
+ case SAMA5_BOOTSOURCE_QSPI:
+ return BOOTSOURCE_SPI;
+ case SAMA5_BOOTSOURCE_SMC:
+ return BOOTSOURCE_NAND;
+ case SAMA5_BOOTSOURCE_SAM_BA:
+ return BOOTSOURCE_SERIAL;
+ }
+ return BOOTSOURCE_UNKNOWN;
+}
+
+static inline int sama5_bootsource_instance(u32 reg)
+{
+ return FIELD_GET(SAMA5_BOOTSOURCE_INSTANCE, reg);
+}
+
+#define __sama5d2_stashed_bootrom_r4 \
+ (*(volatile u32 *)(SAMA5D2_SRAM_BASE + SAMA5D2_SRAM_SIZE - 0x4))
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/sama5d2-sip-ddramc.h b/arch/arm/mach-at91/include/mach/sama5d2-sip-ddramc.h
new file mode 100644
index 0000000000..35c92c43fc
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/sama5d2-sip-ddramc.h
@@ -0,0 +1,39 @@
+/* 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/sama5d2_ll.h>
+
+static inline void sama5d2_d1g_ddrconf(void) /* DDR2 1Gbit SDRAM */
+{
+ struct at91_ddramc_register conf = {
+ .mdr = AT91_DDRC2_DBW_16_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_WEAK_STRENGTH_RZQ7 | AT91_DDRC2_ENABLE_DLL |
+ AT91_DDRC2_NB_BANKS_8 | AT91_DDRC2_NDQS_ENABLED |
+ AT91_DDRC2_DECOD_INTERLEAVED | AT91_DDRC2_UNAL_SUPPORTED,
+
+ .rtr = 0x511,
+
+ .t0pr = AT91_DDRC2_TRAS_(7) | AT91_DDRC2_TRCD_(3) |
+ AT91_DDRC2_TWR_(3) | AT91_DDRC2_TRC_(9) |
+ AT91_DDRC2_TRP_(3) | AT91_DDRC2_TRRD_(2) |
+ AT91_DDRC2_TWTR_(2) | AT91_DDRC2_TMRD_(2),
+
+ .t1pr = AT91_DDRC2_TRFC_(22) | AT91_DDRC2_TXSNR_(23) |
+ AT91_DDRC2_TXSRD_(200) | AT91_DDRC2_TXP_(2),
+
+ .t2pr = AT91_DDRC2_TXARD_(2) | AT91_DDRC2_TXARDS_(8) |
+ AT91_DDRC2_TRPA_(4) | AT91_DDRC2_TRTP_(2) |
+ AT91_DDRC2_TFAW_(8),
+ };
+
+ sama5d2_ddr2_init(&conf);
+}
diff --git a/arch/arm/mach-at91/include/mach/sama5d2.h b/arch/arm/mach-at91/include/mach/sama5d2.h
index 3dad7d9c9c..90b566ffc4 100644
--- a/arch/arm/mach-at91/include/mach/sama5d2.h
+++ b/arch/arm/mach-at91/include/mach/sama5d2.h
@@ -14,6 +14,11 @@
#ifndef SAMA5D2_H
#define SAMA5D2_H
+#include <asm/io.h>
+#include <linux/sizes.h>
+#include <linux/bitops.h>
+#include <linux/bitfield.h>
+
/*
* Peripheral identifiers/interrupts. (Table 18-9)
*/
@@ -101,100 +106,100 @@
* User Peripheral physical base addresses.
*/
-#define SAMA5D2_BASE_LCDC 0xf0000000
-#define SAMA5D2_BASE_XDMAC1 0xf0004000
-#define SAMA5D2_BASE_HXISI 0xf0008000
-#define SAMA5D2_BASE_MPDDRC 0xf000c000
-#define SAMA5D2_BASE_XDMAC0 0xf0010000
-#define SAMA5D2_BASE_PMC 0xf0014000
-#define SAMA5D2_BASE_MATRIX64 0xf0018000 /* MATRIX0 */
-#define SAMA5D2_BASE_AESB 0xf001c000
-#define SAMA5D2_BASE_QSPI0 0xf0020000
-#define SAMA5D2_BASE_QSPI1 0xf0024000
-#define SAMA5D2_BASE_SHA 0xf0028000
-#define SAMA5D2_BASE_AES 0xf002c000
+#define SAMA5D2_BASE_LCDC IOMEM(0xf0000000)
+#define SAMA5D2_BASE_XDMAC1 IOMEM(0xf0004000)
+#define SAMA5D2_BASE_HXISI IOMEM(0xf0008000)
+#define SAMA5D2_BASE_MPDDRC IOMEM(0xf000c000)
+#define SAMA5D2_BASE_XDMAC0 IOMEM(0xf0010000)
+#define SAMA5D2_BASE_PMC IOMEM(0xf0014000)
+#define SAMA5D2_BASE_MATRIX64 IOMEM(0xf0018000) /* MATRIX0 */
+#define SAMA5D2_BASE_AESB IOMEM(0xf001c000)
+#define SAMA5D2_BASE_QSPI0 IOMEM(0xf0020000)
+#define SAMA5D2_BASE_QSPI1 IOMEM(0xf0024000)
+#define SAMA5D2_BASE_SHA IOMEM(0xf0028000)
+#define SAMA5D2_BASE_AES IOMEM(0xf002c000)
-#define SAMA5D2_BASE_SPI0 0xf8000000
-#define SAMA5D2_BASE_SSC0 0xf8004000
-#define SAMA5D2_BASE_GMAC 0xf8008000
-#define SAMA5D2_BASE_TC0 0xf800c000
-#define SAMA5D2_BASE_TC1 0xf8010000
-#define SAMA5D2_BASE_HSMC 0xf8014000
-#define SAMA5D2_BASE_PDMIC 0xf8018000
-#define SAMA5D2_BASE_UART0 0xf801c000
-#define SAMA5D2_BASE_UART1 0xf8020000
-#define SAMA5D2_BASE_UART2 0xf8024000
-#define SAMA5D2_BASE_TWI0 0xf8028000
-#define SAMA5D2_BASE_PWMC 0xf802c000
-#define SAMA5D2_BASE_SFR 0xf8030000
-#define SAMA5D2_BASE_FLEXCOM0 0xf8034000
-#define SAMA5D2_BASE_FLEXCOM1 0xf8038000
-#define SAMA5D2_BASE_SAIC 0xf803c000
-#define SAMA5D2_BASE_ICM 0xf8040000
-#define SAMA5D2_BASE_SECURAM 0xf8044000
-#define SAMA5D2_BASE_SYSC 0xf8048000
-#define SAMA5D2_BASE_ACC 0xf804a000
-#define SAMA5D2_BASE_SFC 0xf804c000
-#define SAMA5D2_BASE_I2SC0 0xf8050000
-#define SAMA5D2_BASE_CAN0 0xf8054000
+#define SAMA5D2_BASE_SPI0 IOMEM(0xf8000000)
+#define SAMA5D2_BASE_SSC0 IOMEM(0xf8004000)
+#define SAMA5D2_BASE_GMAC IOMEM(0xf8008000)
+#define SAMA5D2_BASE_TC0 IOMEM(0xf800c000)
+#define SAMA5D2_BASE_TC1 IOMEM(0xf8010000)
+#define SAMA5D2_BASE_HSMC IOMEM(0xf8014000)
+#define SAMA5D2_BASE_PDMIC IOMEM(0xf8018000)
+#define SAMA5D2_BASE_UART0 IOMEM(0xf801c000)
+#define SAMA5D2_BASE_UART1 IOMEM(0xf8020000)
+#define SAMA5D2_BASE_UART2 IOMEM(0xf8024000)
+#define SAMA5D2_BASE_TWI0 IOMEM(0xf8028000)
+#define SAMA5D2_BASE_PWMC IOMEM(0xf802c000)
+#define SAMA5D2_BASE_SFR IOMEM(0xf8030000)
+#define SAMA5D2_BASE_FLEXCOM0 IOMEM(0xf8034000)
+#define SAMA5D2_BASE_FLEXCOM1 IOMEM(0xf8038000)
+#define SAMA5D2_BASE_SAIC IOMEM(0xf803c000)
+#define SAMA5D2_BASE_ICM IOMEM(0xf8040000)
+#define SAMA5D2_BASE_SECURAM IOMEM(0xf8044000)
+#define SAMA5D2_BASE_SYSC IOMEM(0xf8048000)
+#define SAMA5D2_BASE_ACC IOMEM(0xf804a000)
+#define SAMA5D2_BASE_SFC IOMEM(0xf804c000)
+#define SAMA5D2_BASE_I2SC0 IOMEM(0xf8050000)
+#define SAMA5D2_BASE_CAN0 IOMEM(0xf8054000)
-#define SAMA5D2_BASE_SPI1 0xfc000000
-#define SAMA5D2_BASE_SSC1 0xfc004000
-#define SAMA5D2_BASE_UART3 0xfc008000
-#define SAMA5D2_BASE_UART4 0xfc00c000
-#define SAMA5D2_BASE_FLEXCOM2 0xfc010000
-#define SAMA5D2_BASE_FLEXCOM3 0xfc014000
-#define SAMA5D2_BASE_FLEXCOM4 0xfc018000
-#define SAMA5D2_BASE_TRNG 0xfc01c000
-#define SAMA5D2_BASE_AIC 0xfc020000
-#define SAMA5D2_BASE_TWI1 0xfc028000
-#define SAMA5D2_BASE_UDPHS 0xfc02c000
-#define SAMA5D2_BASE_ADC 0xfc030000
+#define SAMA5D2_BASE_SPI1 IOMEM(0xfc000000)
+#define SAMA5D2_BASE_SSC1 IOMEM(0xfc004000)
+#define SAMA5D2_BASE_UART3 IOMEM(0xfc008000)
+#define SAMA5D2_BASE_UART4 IOMEM(0xfc00c000)
+#define SAMA5D2_BASE_FLEXCOM2 IOMEM(0xfc010000)
+#define SAMA5D2_BASE_FLEXCOM3 IOMEM(0xfc014000)
+#define SAMA5D2_BASE_FLEXCOM4 IOMEM(0xfc018000)
+#define SAMA5D2_BASE_TRNG IOMEM(0xfc01c000)
+#define SAMA5D2_BASE_AIC IOMEM(0xfc020000)
+#define SAMA5D2_BASE_TWI1 IOMEM(0xfc028000)
+#define SAMA5D2_BASE_UDPHS IOMEM(0xfc02c000)
+#define SAMA5D2_BASE_ADC IOMEM(0xfc030000)
-#define SAMA5D2_BASE_PIOA 0xfc038000
-#define SAMA5D2_BASE_MATRIX32 0xfc03c000 /* MATRIX1 */
-#define SAMA5D2_BASE_SECUMOD 0xfc040000
-#define SAMA5D2_BASE_TDES 0xfc044000
-#define SAMA5D2_BASE_CLASSD 0xfc048000
-#define SAMA5D2_BASE_I2SC1 0xfc04c000
-#define SAMA5D2_BASE_CAN1 0xfc050000
-#define SAMA5D2_BASE_SFRBU 0xfc05c000
-#define SAMA5D2_BASE_CHIPID 0xfc069000
+#define SAMA5D2_BASE_PIOA IOMEM(0xfc038000)
+#define SAMA5D2_BASE_MATRIX32 IOMEM(0xfc03c000) /* MATRIX1 */
+#define SAMA5D2_BASE_SECUMOD IOMEM(0xfc040000)
+#define SAMA5D2_BASE_TDES IOMEM(0xfc044000)
+#define SAMA5D2_BASE_CLASSD IOMEM(0xfc048000)
+#define SAMA5D2_BASE_I2SC1 IOMEM(0xfc04c000)
+#define SAMA5D2_BASE_CAN1 IOMEM(0xfc050000)
+#define SAMA5D2_BASE_SFRBU IOMEM(0xfc05c000)
+#define SAMA5D2_BASE_CHIPID IOMEM(0xfc069000)
/*
* Address Memory Space
*/
-#define SAMA5D2_BASE_INTERNAL_MEM 0x00000000
-#define SAMA5D2_BASE_CS0 0x10000000
-#define SAMA5D2_BASE_DDRCS 0x20000000
-#define SAMA5D2_BASE_DDRCS_AES 0x40000000
-#define SAMA5D2_BASE_CS1 0x60000000
-#define SAMA5D2_BASE_CS2 0x70000000
-#define SAMA5D2_BASE_CS3 0x80000000
-#define SAMA5D2_BASE_QSPI0_AES_MEM 0x90000000
-#define SAMA5D2_BASE_QSPI1_AES_MEM 0x98000000
-#define SAMA5D2_BASE_SDHC0 0xa0000000
-#define SAMA5D2_BASE_SDHC1 0xb0000000
-#define SAMA5D2_BASE_NFC_CMD_REG 0xc0000000
-#define SAMA5D2_BASE_QSPI0_MEM 0xd0000000
-#define SAMA5D2_BASE_QSPI1_MEM 0xd8000000
-#define SAMA5D2_BASE_PERIPH 0xf0000000
+#define SAMA5D2_BASE_INTERNAL_MEM IOMEM(0x00000000)
+#define SAMA5D2_BASE_CS0 IOMEM(0x10000000)
+#define SAMA5D2_BASE_DDRCS IOMEM(0x20000000)
+#define SAMA5D2_BASE_DDRCS_AES IOMEM(0x40000000)
+#define SAMA5D2_BASE_CS1 IOMEM(0x60000000)
+#define SAMA5D2_BASE_CS2 IOMEM(0x70000000)
+#define SAMA5D2_BASE_CS3 IOMEM(0x80000000)
+#define SAMA5D2_BASE_QSPI0_AES_MEM IOMEM(0x90000000)
+#define SAMA5D2_BASE_QSPI1_AES_MEM IOMEM(0x98000000)
+#define SAMA5D2_BASE_SDHC0 IOMEM(0xa0000000)
+#define SAMA5D2_BASE_SDHC1 IOMEM(0xb0000000)
+#define SAMA5D2_BASE_NFC_CMD_REG IOMEM(0xc0000000)
+#define SAMA5D2_BASE_QSPI0_MEM IOMEM(0xd0000000)
+#define SAMA5D2_BASE_QSPI1_MEM IOMEM(0xd8000000)
+#define SAMA5D2_BASE_PERIPH IOMEM(0xf0000000)
/*
* Internal Memories
*/
-#define SAMA5D2_BASE_ROM 0x00000000 /* ROM */
-#define SAMA5D2_BASE_ECC_ROM 0x00060000 /* ECC ROM */
-#define SAMA5D2_BASE_NFC_SRAM 0x00100000 /* NFC SRAM */
-#define SAMA5D2_BASE_SRAM0 0x00200000 /* SRAM0 */
-#define SAMA5D2_BASE_SRAM1 0x00220000 /* SRAM1 */
-#define SAMA5D2_BASE_UDPHS_SRAM 0x00300000 /* UDPHS RAM */
-#define SAMA5D2_BASE_UHP_OHCI 0x00400000 /* UHP OHCI */
-#define SAMA5D2_BASE_UHP_EHCI 0x00500000 /* UHP EHCI */
-#define SAMA5D2_BASE_AXI_MATRIX 0x00600000 /* AXI Maxtrix */
-#define SAMA5D2_BASE_DAP 0x00700000 /* DAP */
-#define SAMA5D2_BASE_PTC 0x00800000 /* PTC */
-#define SAMA5D2_BASE_L2CC 0x00A00000 /* L2CC */
+#define SAMA5D2_BASE_ROM IOMEM(0x00000000) /* ROM */
+#define SAMA5D2_BASE_ECC_ROM IOMEM(0x00060000) /* ECC ROM */
+#define SAMA5D2_BASE_NFC_SRAM 0x00100000 /* NFC SRAM */
+#define SAMA5D2_BASE_SRAM0 0x00200000 /* SRAM0 */
+#define SAMA5D2_BASE_SRAM1 0x00220000 /* SRAM1 */
+#define SAMA5D2_BASE_UDPHS_SRAM 0x00300000 /* UDPHS RAM */
+#define SAMA5D2_BASE_UHP_OHCI IOMEM(0x00400000) /* UHP OHCI */
+#define SAMA5D2_BASE_UHP_EHCI IOMEM(0x00500000) /* UHP EHCI */
+#define SAMA5D2_BASE_AXI_MATRIX IOMEM(0x00600000) /* AXI Maxtrix */
+#define SAMA5D2_BASE_DAP IOMEM(0x00700000) /* DAP */
+#define SAMA5D2_BASE_PTC IOMEM(0x00800000) /* PTC */
+#define SAMA5D2_BASE_L2CC IOMEM(0x00A00000) /* L2CC */
/*
* Other misc defines
@@ -258,4 +263,58 @@
#define SAMA5D2_SRAM_BASE SAMA5D2_BASE_SRAM0
#define SAMA5D2_SRAM_SIZE (128 * SZ_1K)
+static inline void __iomem *sama5d2_pio_map_bank(int bank, unsigned *id)
+{
+ switch(bank + 'A') {
+ case 'A':
+ *id = SAMA5D2_ID_PIOA;
+ return SAMA5D2_BASE_PIOA;
+ case 'B':
+ *id = SAMA5D2_ID_PIOB;
+ return SAMA5D2_BASE_PIOB;
+ case 'C':
+ *id = SAMA5D2_ID_PIOC;
+ return SAMA5D2_BASE_PIOC;
+ case 'D':
+ *id = SAMA5D2_ID_PIOD;
+ return SAMA5D2_BASE_PIOD;
+ }
+
+ return NULL;
+}
+
+#define SAMA5D2_BUREG_INDEX GENMASK(1, 0)
+#define SAMA5D2_BUREG_VALID BIT(2)
+
+#define SAMA5D2_SFC_DR(x) (SAMA5D2_BASE_SFC + 0x20 + 4 * (x))
+
+#define SAMA5D2_BOOTCFG_QSPI_0 GENMASK(1, 0)
+#define SAMA5D2_BOOTCFG_QSPI_1 GENMASK(3, 2)
+#define SAMA5D2_BOOTCFG_SPI_0 GENMASK(5, 4)
+#define SAMA5D2_BOOTCFG_SPI_1 GENMASK(7, 6)
+#define SAMA5D2_BOOTCFG_NFC GENMASK(9, 8)
+#define SAMA5D2_BOOTCFG_SDMMC_0 BIT(10)
+#define SAMA5D2_BOOTCFG_SDMMC_1 BIT(11)
+#define SAMA5D2_BOOTCFG_UART GENMASK(15, 12)
+#define SAMA5D2_BOOTCFG_JTAG GENMASK(17, 16)
+#define SAMA5D2_BOOTCFG_EXT_MEM_BOOT_EN BIT(18)
+#define SAMA5D2_BOOTCFG_QSPI_XIP BIT(21)
+#define SAMA5D2_DISABLE_BSC_CR BIT(22)
+#define SAMA5D2_DISABLE_MONITOR BIT(24)
+#define SAMA5D2_SECURE_MODE BIT(29)
+
+static inline u32 sama5d2_bootcfg(void)
+{
+ u32 __iomem *bureg = SAMA5D2_BASE_SECURAM + 0x1400;
+ u32 bsc_cr = readl(SAMA5D2_BASE_SYSC + 0x54);
+ u32 __iomem *bootcfg;
+
+ if (bsc_cr & SAMA5D2_BUREG_VALID)
+ bootcfg = &bureg[FIELD_GET(SAMA5D2_BUREG_INDEX, bsc_cr)];
+ else
+ bootcfg = SAMA5D2_SFC_DR(512 / 32);
+
+ return readl(bootcfg);
+}
+
#endif
diff --git a/arch/arm/mach-at91/include/mach/sama5d2_ll.h b/arch/arm/mach-at91/include/mach/sama5d2_ll.h
new file mode 100644
index 0000000000..96f3bc5452
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/sama5d2_ll.h
@@ -0,0 +1,139 @@
+#ifndef __MACH_SAMA5D2_LL__
+#define __MACH_SAMA5D2_LL__
+
+#include <mach/sama5d2.h>
+#include <mach/at91_pmc_ll.h>
+#include <mach/iomux.h>
+#include <mach/debug_ll.h>
+#include <mach/early_udelay.h>
+#include <mach/ddramc.h>
+
+#include <common.h>
+
+void sama5d2_lowlevel_init(void);
+
+static inline void sama5d2_pmc_enable_periph_clock(int clk)
+{
+ at91_pmc_sam9x5_enable_periph_clock(SAMA5D2_BASE_PMC, clk);
+}
+
+/* requires relocation */
+static inline void sama5d2_udelay_init(unsigned int msc)
+{
+ early_udelay_init(SAMA5D2_BASE_PMC, SAMA5D2_BASE_PITC,
+ SAMA5D2_ID_PIT, msc, AT91_PMC_LL_SAMA5D2);
+}
+
+
+void sama5d2_ddr2_init(struct at91_ddramc_register *ddramc_reg_config);
+
+static inline int sama5d2_pmc_enable_generic_clock(unsigned int periph_id,
+ unsigned int clk_source,
+ unsigned int div)
+{
+ return at91_pmc_enable_generic_clock(SAMA5D2_BASE_PMC,
+ SAMA5D2_BASE_SFR,
+ periph_id, clk_source, div,
+ AT91_PMC_LL_SAMA5D2);
+}
+
+static inline int sama5d2_dbgu_setup_ll(unsigned dbgu_id,
+ unsigned pin, unsigned periph,
+ unsigned mck)
+{
+ unsigned mask, bank, pio_id;
+ void __iomem *dbgu_base, *pio_base;
+
+ mask = pin_to_mask(pin);
+ bank = pin_to_bank(pin);
+
+ switch (dbgu_id) {
+ case SAMA5D2_ID_UART0:
+ dbgu_base = SAMA5D2_BASE_UART0;
+ break;
+ case SAMA5D2_ID_UART1:
+ dbgu_base = SAMA5D2_BASE_UART1;
+ break;
+ case SAMA5D2_ID_UART2:
+ dbgu_base = SAMA5D2_BASE_UART2;
+ break;
+ case SAMA5D2_ID_UART3:
+ dbgu_base = SAMA5D2_BASE_UART3;
+ break;
+ case SAMA5D2_ID_UART4:
+ dbgu_base = SAMA5D2_BASE_UART4;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ pio_base = sama5d2_pio_map_bank(bank, &pio_id);
+ if (!pio_base)
+ return -EINVAL;
+
+ sama5d2_pmc_enable_periph_clock(pio_id);
+
+ at91_mux_pio4_set_periph(pio_base, mask, periph);
+
+ sama5d2_pmc_enable_periph_clock(dbgu_id);
+
+ at91_dbgu_setup_ll(dbgu_base, mck / 2, CONFIG_BAUDRATE);
+
+ return 0;
+}
+
+struct sama5d2_uart_pinmux {
+ void __iomem *base;
+ u8 id, dtxd, periph;
+};
+
+#define SAMA5D2_UART(idx, pio, periph) (struct sama5d2_uart_pinmux) { \
+ SAMA5D2_BASE_UART##idx, SAMA5D2_ID_UART##idx, \
+ AT91_PIN_##pio, AT91_MUX_PERIPH_##periph }
+
+static inline void __iomem *sama5d2_resetup_uart_console(unsigned mck)
+{
+ struct sama5d2_uart_pinmux pinmux;
+
+ /* Table 48-2 I/O Lines and 16.4.4 Boot Configuration Word */
+
+ switch (FIELD_GET(SAMA5D2_BOOTCFG_UART, sama5d2_bootcfg())) {
+ case 0: /* UART_1_IOSET_1 */
+ pinmux = SAMA5D2_UART(1, PD3, A);
+ break;
+ case 1: /* UART_0_IOSET_1 */
+ pinmux = SAMA5D2_UART(0, PB27, C);
+ break;
+ case 2: /* UART_1_IOSET_2 */
+ pinmux = SAMA5D2_UART(1, PC8, E);
+ break;
+ case 3: /* UART_2_IOSET_1 */
+ pinmux = SAMA5D2_UART(2, PD5, B);
+ break;
+ case 4: /* UART_2_IOSET_2 */
+ pinmux = SAMA5D2_UART(2, PD24, A);
+ break;
+ case 5: /* UART_2_IOSET_3 */
+ pinmux = SAMA5D2_UART(2, PD20, C);
+ break;
+ case 6: /* UART_3_IOSET_1 */
+ pinmux = SAMA5D2_UART(3, PC13, D);
+ break;
+ case 7: /* UART_3_IOSET_2 */
+ pinmux = SAMA5D2_UART(3, PD0, C);
+ break;
+ case 8: /* UART_3_IOSET_3 */
+ pinmux = SAMA5D2_UART(3, PB12, C);
+ break;
+ case 9: /* UART_4_IOSET_1 */
+ pinmux = SAMA5D2_UART(4, PB4, A);
+ break;
+ default:
+ return NULL;
+ }
+
+ sama5d2_dbgu_setup_ll(pinmux.id, pinmux.dtxd, pinmux.periph, mck);
+ return pinmux.base;
+}
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/tz_matrix.h b/arch/arm/mach-at91/include/mach/tz_matrix.h
new file mode 100644
index 0000000000..85589bfa65
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/tz_matrix.h
@@ -0,0 +1,95 @@
+/* SPDX-License-Identifier: BSD-1-Clause */
+/*
+ * Copyright (c) 2013, Atmel Corporation
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ */
+#ifndef __TZ_MATRIX_H__
+#define __TZ_MATRIX_H__
+
+#define MATRIX_MCFG(n) (0x0000 + (n) * 4)/* Master Configuration Register */
+#define MATRIX_SCFG(n) (0x0040 + (n) * 4)/* Slave Configuration Register */
+#define MATRIX_PRAS(n) (0x0080 + (n) * 8)/* Priority Register A for Slave */
+#define MATRIX_PRBS(n) (0x0084 + (n) * 8)/* Priority Register B for Slave */
+
+#define MATRIX_MRCR 0x0100 /* Master Remap Control Register */
+#define MATRIX_MEIER 0x0150 /* Master Error Interrupt Enable Register */
+#define MATRIX_MEIDR 0x0154 /* Master Error Interrupt Disable Register */
+#define MATRIX_MEIMR 0x0158 /* Master Error Interrupt Mask Register */
+#define MATRIX_MESR 0x015c /* Master Error Statue Register */
+
+/* Master n Error Address Register */
+#define MATRIX_MEAR(n) (0x0160 + (n) * 4)
+
+#define MATRIX_WPMR 0x01E4 /* Write Protect Mode Register */
+#define MATRIX_WPSR 0x01E8 /* Write Protect Status Register */
+
+/* Security Slave n Register */
+#define MATRIX_SSR(n) (0x0200 + (n) * 4)
+/* Security Area Split Slave n Register */
+#define MATRIX_SASSR(n) (0x0240 + (n) * 4)
+/* Security Region Top Slave n Register */
+#define MATRIX_SRTSR(n) (0x0280 + (n) * 4)
+
+/* Security Peripheral Select n Register */
+#define MATRIX_SPSELR(n) (0x02c0 + (n) * 4)
+
+/**************************************************************************/
+/* Write Protect Mode Register (MATRIX_WPMR) */
+#define MATRIX_WPMR_WPEN (1 << 0) /* Write Protect Enable */
+#define MATRIX_WPMR_WPEN_DISABLE (0 << 0)
+#define MATRIX_WPMR_WPEN_ENABLE (1 << 0)
+#define MATRIX_WPMR_WPKEY (PASSWD << 8) /* Write Protect KEY */
+#define MATRIX_WPMR_WPKEY_PASSWD (0x4D4154 << 8)
+
+/* Security Slave Registers (MATRIX_SSRx) */
+#define MATRIX_LANSECH(n, bit) ((bit) << n)
+#define MATRIX_LANSECH_S(n) (0x00 << n)
+#define MATRIX_LANSECH_NS(n) (0x01 << n)
+#define MATRIX_RDNSECH(n, bit) ((bit) << (n + 8))
+#define MATRIX_RDNSECH_S(n) (0x00 << (n + 8))
+#define MATRIX_RDNSECH_NS(n) (0x01 << (n + 8))
+#define MATRIX_WRNSECH(n, bit) ((bit) << (n + 16))
+#define MATRIX_WRNSECH_S(n) (0x00 << (n + 16))
+#define MATRIX_WRNSECH_NS(n) (0x01 << (n + 16))
+
+/* Security Areas Split Slave Registers (MATRIX_SASSRx) */
+#define MATRIX_SASPLIT(n, value) ((value) << (4 * n))
+#define MATRIX_SASPLIT_VALUE_4K 0x00
+#define MATRIX_SASPLIT_VALUE_8K 0x01
+#define MATRIX_SASPLIT_VALUE_16K 0x02
+#define MATRIX_SASPLIT_VALUE_32K 0x03
+#define MATRIX_SASPLIT_VALUE_64K 0x04
+#define MATRIX_SASPLIT_VALUE_128K 0x05
+#define MATRIX_SASPLIT_VALUE_256K 0x06
+#define MATRIX_SASPLIT_VALUE_512K 0x07
+#define MATRIX_SASPLIT_VALUE_1M 0x08
+#define MATRIX_SASPLIT_VALUE_2M 0x09
+#define MATRIX_SASPLIT_VALUE_4M 0x0a
+#define MATRIX_SASPLIT_VALUE_8M 0x0b
+#define MATRIX_SASPLIT_VALUE_16M 0x0c
+#define MATRIX_SASPLIT_VALUE_32M 0x0d
+#define MATRIX_SASPLIT_VALUE_64M 0x0e
+#define MATRIX_SASPLIT_VALUE_128M 0x0f
+
+/* Security Region Top Slave Registers (MATRIX_SRTSRx) */
+#define MATRIX_SRTOP(n, value) ((value) << (4 * n))
+#define MATRIX_SRTOP_VALUE_4K 0x00
+#define MATRIX_SRTOP_VALUE_8K 0x01
+#define MATRIX_SRTOP_VALUE_16K 0x02
+#define MATRIX_SRTOP_VALUE_32K 0x03
+#define MATRIX_SRTOP_VALUE_64K 0x04
+#define MATRIX_SRTOP_VALUE_128K 0x05
+#define MATRIX_SRTOP_VALUE_256K 0x06
+#define MATRIX_SRTOP_VALUE_512K 0x07
+#define MATRIX_SRTOP_VALUE_1M 0x08
+#define MATRIX_SRTOP_VALUE_2M 0x09
+#define MATRIX_SRTOP_VALUE_4M 0x0a
+#define MATRIX_SRTOP_VALUE_8M 0x0b
+#define MATRIX_SRTOP_VALUE_16M 0x0c
+#define MATRIX_SRTOP_VALUE_32M 0x0d
+#define MATRIX_SRTOP_VALUE_64M 0x0e
+#define MATRIX_SRTOP_VALUE_128M 0x0f
+
+#endif /* #ifndef __TZ_MATRIX_H__ */
diff --git a/arch/arm/mach-at91/include/mach/xload.h b/arch/arm/mach-at91/include/mach/xload.h
new file mode 100644
index 0000000000..f110236b0b
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/xload.h
@@ -0,0 +1,12 @@
+#ifndef __MACH_XLOAD_H
+#define __MACH_XLOAD_H
+
+#include <linux/compiler.h>
+#include <pbl.h>
+
+void __noreturn sama5d2_sdhci_start_image(u32 r4);
+
+int at91_sdhci_bio_init(struct pbl_bio *bio, void __iomem *base);
+
+#endif /* __MACH_XLOAD_H */
+
diff --git a/arch/arm/mach-at91/matrix.c b/arch/arm/mach-at91/matrix.c
new file mode 100644
index 0000000000..b2e7345ec1
--- /dev/null
+++ b/arch/arm/mach-at91/matrix.c
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: BSD-1-Clause */
+/*
+ * Copyright (c) 2013, Atmel Corporation
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ */
+
+#include <io.h>
+#include <mach/tz_matrix.h>
+#include <mach/matrix.h>
+
+static inline void matrix_write(void __iomem *base,
+ unsigned int offset,
+ const unsigned int value)
+{
+ writel(value, base + offset);
+}
+
+static inline unsigned int matrix_read(void __iomem *base, unsigned int offset)
+{
+ return readl(base + offset);
+}
+
+void at91_matrix_write_protect_enable(void __iomem *matrix_base)
+{
+ matrix_write(matrix_base, MATRIX_WPMR,
+ MATRIX_WPMR_WPKEY_PASSWD | MATRIX_WPMR_WPEN_ENABLE);
+}
+
+void at91_matrix_write_protect_disable(void __iomem *matrix_base)
+{
+ matrix_write(matrix_base, MATRIX_WPMR, MATRIX_WPMR_WPKEY_PASSWD);
+}
+
+void at91_matrix_configure_slave_security(void __iomem *matrix_base,
+ unsigned int slave,
+ unsigned int srtop_setting,
+ unsigned int srsplit_setting,
+ unsigned int ssr_setting)
+{
+ matrix_write(matrix_base, MATRIX_SSR(slave), ssr_setting);
+ matrix_write(matrix_base, MATRIX_SRTSR(slave), srtop_setting);
+ matrix_write(matrix_base, MATRIX_SASSR(slave), srsplit_setting);
+}
diff --git a/arch/arm/mach-at91/sama5d2.c b/arch/arm/mach-at91/sama5d2.c
new file mode 100644
index 0000000000..2ce6d7f36f
--- /dev/null
+++ b/arch/arm/mach-at91/sama5d2.c
@@ -0,0 +1,71 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <common.h>
+#include <of.h>
+#include <init.h>
+#include <mach/aic.h>
+#include <mach/sama5d2.h>
+#include <asm/cache-l2x0.h>
+#include <mach/sama5_bootsource.h>
+#include <asm/mmu.h>
+
+#define SFR_CAN 0x48
+#define SFR_L2CC_HRAMC 0x58
+
+static void sama5d2_can_ram_init(void)
+{
+ writel(0x00210021, SAMA5D2_BASE_SFR + SFR_CAN);
+}
+
+static void sama5d2_l2x0_init(void)
+{
+ void __iomem *l2x0_base = SAMA5D2_BASE_L2CC;
+ u32 cfg;
+
+ writel(0x1, SAMA5D2_BASE_SFR + SFR_L2CC_HRAMC);
+
+ /* Prefetch Control */
+ cfg = readl(l2x0_base + L2X0_PREFETCH_CTRL);
+ /* prefetch offset: TODO find proper values */
+ cfg |= 0x1;
+ cfg |= L2X0_INCR_DOUBLE_LINEFILL_EN | L2X0_PREFETCH_DROP_EN
+ | L2X0_DOUBLE_LINEFILL_EN;
+ cfg |= L2X0_DATA_PREFETCH_EN | L2X0_INSTRUCTION_PREFETCH_EN;
+ writel(cfg, l2x0_base + L2X0_PREFETCH_CTRL);
+
+ /* Power Control */
+ cfg = readl(l2x0_base + L2X0_POWER_CTRL);
+ cfg |= L2X0_STNDBY_MODE_EN | L2X0_DYNAMIC_CLK_GATING_EN;
+ writel(cfg, l2x0_base + L2X0_POWER_CTRL);
+
+ l2x0_init(l2x0_base, 0x0, ~0UL);
+}
+
+static int sama5d2_init(void)
+{
+ if (!of_machine_is_compatible("atmel,sama5d2"))
+ return 0;
+
+ at91_aic_redir(SAMA5D2_BASE_SFR, SAMA5D2_AICREDIR_KEY);
+ sama5d2_can_ram_init();
+ sama5d2_l2x0_init();
+
+ return 0;
+}
+postmmu_initcall(sama5d2_init);
+
+static int sama5d2_bootsource_init(void)
+{
+ u32 r4;
+
+ if (!of_machine_is_compatible("atmel,sama5d2"))
+ return 0;
+
+ r4 = __sama5d2_stashed_bootrom_r4;
+
+ bootsource_set(sama5_bootsource(r4));
+ bootsource_set_instance(sama5_bootsource_instance(r4));
+
+ return 0;
+}
+postcore_initcall(sama5d2_bootsource_init);
diff --git a/arch/arm/mach-at91/sama5d2_ll.c b/arch/arm/mach-at91/sama5d2_ll.c
new file mode 100644
index 0000000000..c3b5061777
--- /dev/null
+++ b/arch/arm/mach-at91/sama5d2_ll.c
@@ -0,0 +1,220 @@
+// SPDX-License-Identifier: BSD-1-Clause
+/*
+ * Copyright (c) 2017, Microchip Corporation
+ *
+ * Microchip's name may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ */
+
+#include <mach/sama5d2_ll.h>
+#include <mach/at91_ddrsdrc.h>
+#include <mach/ddramc.h>
+#include <mach/early_udelay.h>
+#include <mach/tz_matrix.h>
+#include <mach/matrix.h>
+#include <mach/at91_rstc.h>
+#include <asm/barebox-arm.h>
+
+#define sama5d2_pmc_write(off, val) writel(val, SAMA5D2_BASE_PMC + off)
+#define sama5d2_pmc_read(off) readl(SAMA5D2_BASE_PMC + off)
+
+void sama5d2_ddr2_init(struct at91_ddramc_register *ddramc_reg_config)
+{
+ unsigned int reg;
+
+ /* enable ddr2 clock */
+ sama5d2_pmc_enable_periph_clock(SAMA5D2_ID_MPDDRC);
+ sama5d2_pmc_write(AT91_PMC_SCER, AT91CAP9_PMC_DDR);
+
+ reg = AT91_MPDDRC_RD_DATA_PATH_ONE_CYCLES;
+ writel(reg, SAMA5D2_BASE_MPDDRC + AT91_MPDDRC_RD_DATA_PATH);
+
+ reg = readl(SAMA5D2_BASE_MPDDRC + AT91_MPDDRC_IO_CALIBR);
+ reg &= ~AT91_MPDDRC_RDIV;
+ reg &= ~AT91_MPDDRC_TZQIO;
+ reg |= AT91_MPDDRC_RDIV_DDR2_RZQ_50;
+ reg |= AT91_MPDDRC_TZQIO_(101);
+ writel(reg, SAMA5D2_BASE_MPDDRC + AT91_MPDDRC_IO_CALIBR);
+
+ /* DDRAM2 Controller initialize */
+ at91_ddram_initialize(SAMA5D2_BASE_MPDDRC, IOMEM(SAMA5_DDRCS),
+ ddramc_reg_config);
+}
+
+static void sama5d2_pmc_init(void)
+{
+ at91_pmc_init(SAMA5D2_BASE_PMC, AT91_PMC_LL_SAMA5D2);
+
+ /* Configure PLLA = MOSC * (PLL_MULA + 1) / PLL_DIVA */
+ sama5d2_pmc_write(AT91_CKGR_PLLAR, AT91_PMC_PLLA_WR_ERRATA);
+ sama5d2_pmc_write(AT91_CKGR_PLLAR, AT91_PMC_PLLA_WR_ERRATA
+ | AT91_PMC3_MUL_(40) | AT91_PMC_OUT_0
+ | AT91_PMC_PLLCOUNT
+ | AT91_PMC_DIV_BYPASS);
+
+ while (!(sama5d2_pmc_read(AT91_PMC_SR) & AT91_PMC_LOCKA))
+ ;
+
+ /* Initialize PLLA charge pump */
+ /* No need: we keep what is set in ROM code */
+ //sama5d2_pmc_write(AT91_PMC_PLLICPR, AT91_PMC_IPLLA_3);
+
+ /* Switch PCK/MCK on PLLA output */
+ at91_pmc_cfg_mck(SAMA5D2_BASE_PMC,
+ AT91_PMC_H32MXDIV
+ | AT91_PMC_PLLADIV2_ON
+ | AT91SAM9_PMC_MDIV_3
+ | AT91_PMC_CSS_PLLA,
+ AT91_PMC_LL_SAMA5D2);
+}
+
+static void matrix_configure_slave(void)
+{
+ u32 ddr_port;
+ u32 ssr_setting, sasplit_setting, srtop_setting;
+
+ /*
+ * Matrix 0 (H64MX)
+ */
+
+ /*
+ * 0: Bridge from H64MX to AXIMX
+ * (Internal ROM, Crypto Library, PKCC RAM): Always Secured
+ */
+
+ /* 1: H64MX Peripheral Bridge */
+
+ /* 2 ~ 9 DDR2 Port0 ~ 7: Non-Secure */
+ srtop_setting = MATRIX_SRTOP(0, MATRIX_SRTOP_VALUE_128M);
+ sasplit_setting = MATRIX_SASPLIT(0, MATRIX_SASPLIT_VALUE_128M);
+ ssr_setting = MATRIX_LANSECH_NS(0) |
+ MATRIX_RDNSECH_NS(0) |
+ MATRIX_WRNSECH_NS(0);
+ for (ddr_port = 0; ddr_port < 8; ddr_port++) {
+ at91_matrix_configure_slave_security(SAMA5D2_BASE_MATRIX64,
+ SAMA5D2_H64MX_SLAVE_DDR2_PORT_0 + ddr_port,
+ srtop_setting,
+ sasplit_setting,
+ ssr_setting);
+ }
+
+ /*
+ * 10: Internal SRAM 128K
+ * TOP0 is set to 128K
+ * SPLIT0 is set to 64K
+ * LANSECH0 is set to 0, the low area of region 0 is the Securable one
+ * RDNSECH0 is set to 0, region 0 Securable area is secured for reads.
+ * WRNSECH0 is set to 0, region 0 Securable area is secured for writes
+ */
+ srtop_setting = MATRIX_SRTOP(0, MATRIX_SRTOP_VALUE_128K);
+ sasplit_setting = MATRIX_SASPLIT(0, MATRIX_SASPLIT_VALUE_64K);
+ ssr_setting = MATRIX_LANSECH_S(0) |
+ MATRIX_RDNSECH_S(0) |
+ MATRIX_WRNSECH_S(0);
+ at91_matrix_configure_slave_security(SAMA5D2_BASE_MATRIX64,
+ SAMA5D2_H64MX_SLAVE_INTERNAL_SRAM,
+ srtop_setting,
+ sasplit_setting,
+ ssr_setting);
+
+ /* 11: Internal SRAM 128K (Cache L2) */
+ /* 12: QSPI0 */
+ /* 13: QSPI1 */
+ /* 14: AESB */
+
+ /*
+ * Matrix 1 (H32MX)
+ */
+
+ /* 0: Bridge from H32MX to H64MX: Not Secured */
+
+ /* 1: H32MX Peripheral Bridge 0: Not Secured */
+
+ /* 2: H32MX Peripheral Bridge 1: Not Secured */
+
+ /*
+ * 3: External Bus Interface
+ * EBI CS0 Memory(256M) ----> Slave Region 0, 1
+ * EBI CS1 Memory(256M) ----> Slave Region 2, 3
+ * EBI CS2 Memory(256M) ----> Slave Region 4, 5
+ * EBI CS3 Memory(128M) ----> Slave Region 6
+ * NFC Command Registers(128M) -->Slave Region 7
+ *
+ * NANDFlash(EBI CS3) --> Slave Region 6: Non-Secure
+ */
+ srtop_setting = MATRIX_SRTOP(6, MATRIX_SRTOP_VALUE_128M) |
+ MATRIX_SRTOP(7, MATRIX_SRTOP_VALUE_128M);
+ sasplit_setting = MATRIX_SASPLIT(6, MATRIX_SASPLIT_VALUE_128M) |
+ MATRIX_SASPLIT(7, MATRIX_SASPLIT_VALUE_128M);
+ ssr_setting = MATRIX_LANSECH_NS(6) |
+ MATRIX_RDNSECH_NS(6) |
+ MATRIX_WRNSECH_NS(6) |
+ MATRIX_LANSECH_NS(7) |
+ MATRIX_RDNSECH_NS(7) |
+ MATRIX_WRNSECH_NS(7);
+ at91_matrix_configure_slave_security(SAMA5D2_BASE_MATRIX32,
+ SAMA5D2_H32MX_EXTERNAL_EBI,
+ srtop_setting,
+ sasplit_setting,
+ ssr_setting);
+
+ /* 4: NFC SRAM (4K): Non-Secure */
+ srtop_setting = MATRIX_SRTOP(0, MATRIX_SRTOP_VALUE_8K);
+ sasplit_setting = MATRIX_SASPLIT(0, MATRIX_SASPLIT_VALUE_8K);
+ ssr_setting = MATRIX_LANSECH_NS(0) |
+ MATRIX_RDNSECH_NS(0) |
+ MATRIX_WRNSECH_NS(0);
+ at91_matrix_configure_slave_security(SAMA5D2_BASE_MATRIX32,
+ SAMA5D2_H32MX_NFC_SRAM,
+ srtop_setting,
+ sasplit_setting,
+ ssr_setting);
+
+ /* 5:
+ * USB Device High Speed Dual Port RAM (DPR): 1M
+ * USB Host OHCI registers: 1M
+ * USB Host EHCI registers: 1M
+ */
+ srtop_setting = MATRIX_SRTOP(0, MATRIX_SRTOP_VALUE_1M) |
+ MATRIX_SRTOP(1, MATRIX_SRTOP_VALUE_1M) |
+ MATRIX_SRTOP(2, MATRIX_SRTOP_VALUE_1M);
+ sasplit_setting = MATRIX_SASPLIT(0, MATRIX_SASPLIT_VALUE_1M) |
+ MATRIX_SASPLIT(1, MATRIX_SASPLIT_VALUE_1M) |
+ MATRIX_SASPLIT(2, MATRIX_SASPLIT_VALUE_1M);
+ ssr_setting = MATRIX_LANSECH_NS(0) |
+ MATRIX_LANSECH_NS(1) |
+ MATRIX_LANSECH_NS(2) |
+ MATRIX_RDNSECH_NS(0) |
+ MATRIX_RDNSECH_NS(1) |
+ MATRIX_RDNSECH_NS(2) |
+ MATRIX_WRNSECH_NS(0) |
+ MATRIX_WRNSECH_NS(1) |
+ MATRIX_WRNSECH_NS(2);
+ at91_matrix_configure_slave_security(SAMA5D2_BASE_MATRIX32,
+ SAMA5D2_H32MX_USB,
+ srtop_setting,
+ sasplit_setting,
+ ssr_setting);
+}
+
+static void sama5d2_matrix_init(void)
+{
+ at91_matrix_write_protect_disable(SAMA5D2_BASE_MATRIX64);
+ at91_matrix_write_protect_disable(SAMA5D2_BASE_MATRIX32);
+
+ matrix_configure_slave();
+}
+
+static void sama5d2_rstc_init(void)
+{
+ writel(AT91_RSTC_KEY | AT91_RSTC_URSTEN,
+ SAMA5D2_BASE_RSTC + AT91_RSTC_MR);
+}
+
+void sama5d2_lowlevel_init(void)
+{
+ arm_cpu_lowlevel_init();
+ sama5d2_pmc_init();
+ sama5d2_matrix_init();
+ sama5d2_rstc_init();
+}
diff --git a/arch/arm/mach-at91/sama5d3_devices.c b/arch/arm/mach-at91/sama5d3_devices.c
index bf4a03d404..e29ed2ba97 100644
--- a/arch/arm/mach-at91/sama5d3_devices.c
+++ b/arch/arm/mach-at91/sama5d3_devices.c
@@ -18,7 +18,7 @@
#include <mach/board.h>
#include <mach/at91_pmc.h>
#include <mach/at91sam9x5_matrix.h>
-#include <mach/at91sam9_ddrsdr.h>
+#include <mach/at91_ddrsdrc.h>
#include <mach/iomux.h>
#include <mach/cpu.h>
#include <i2c/i2c-gpio.h>
diff --git a/arch/arm/mach-at91/sama5d4_devices.c b/arch/arm/mach-at91/sama5d4_devices.c
index 5a1109dc0e..7be9e260d4 100644
--- a/arch/arm/mach-at91/sama5d4_devices.c
+++ b/arch/arm/mach-at91/sama5d4_devices.c
@@ -19,7 +19,7 @@
#include <mach/board.h>
#include <mach/at91_pmc.h>
#include <mach/at91sam9x5_matrix.h>
-#include <mach/at91sam9_ddrsdr.h>
+#include <mach/at91_ddrsdrc.h>
#include <mach/iomux.h>
#include <mach/cpu.h>
#include <i2c/i2c-gpio.h>
diff --git a/arch/arm/mach-at91/xload-mmc.c b/arch/arm/mach-at91/xload-mmc.c
new file mode 100644
index 0000000000..42341fa54b
--- /dev/null
+++ b/arch/arm/mach-at91/xload-mmc.c
@@ -0,0 +1,90 @@
+#include <common.h>
+#include <mach/xload.h>
+#include <mach/sama5_bootsource.h>
+#include <mach/hardware.h>
+#include <mach/sama5d2_ll.h>
+#include <mach/gpio.h>
+#include <linux/sizes.h>
+#include <asm/cache.h>
+#include <pbl.h>
+
+static void __naked __noreturn xload_bb(void __noreturn (*bb)(void), u32 r4)
+{
+ asm volatile("mov r4, %0" : : "r"(r4) : );
+ asm volatile("bx %0" : : "r"(bb) : );
+}
+
+static void at91_fat_start_image(struct pbl_bio *bio,
+ void *buf, unsigned int len,
+ u32 r4)
+{
+ void __noreturn (*bb)(void);
+ int ret;
+
+ ret = pbl_fat_load(bio, "barebox.bin", buf, len);
+ if (ret < 0) {
+ pr_err("pbl_fat_load: error %d\n", ret);
+ return;
+ }
+
+ bb = buf;
+
+ sync_caches_for_execution();
+
+ xload_bb(bb, r4);
+}
+
+static const struct sdhci_instance {
+ void __iomem *base;
+ unsigned id;
+ u8 periph;
+ s8 pins[15];
+} sdhci_instances[] = {
+ [0] = {
+ .base = SAMA5D2_BASE_SDHC0, .id = SAMA5D2_ID_SDMMC0, .periph = AT91_MUX_PERIPH_A,
+ .pins = { 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 13, 10, 11, 12, -1 }
+ },
+ [1] = {
+ .base = SAMA5D2_BASE_SDHC1, .id = SAMA5D2_ID_SDMMC1, .periph = AT91_MUX_PERIPH_E,
+ .pins = { 18, 19, 20, 21, 22, 28, 30, -1 }
+ },
+};
+
+/**
+ * sama5d2_sdhci_start_image - Load and start an image from FAT-formatted SDHCI
+ * @r4: value of r4 passed by BootROM
+ */
+void __noreturn sama5d2_sdhci_start_image(u32 r4)
+{
+ void *buf = (void *)SAMA5_DDRCS;
+ const struct sdhci_instance *instance;
+ struct pbl_bio bio;
+ const s8 *pin;
+ int ret;
+
+ ret = sama5_bootsource_instance(r4);
+ if (ret > 1)
+ panic("Couldn't determine boot MCI instance\n");
+
+ instance = &sdhci_instances[ret];
+
+ sama5d2_pmc_enable_periph_clock(SAMA5D2_ID_PIOA);
+ for (pin = instance->pins; *pin >= 0; pin++) {
+ at91_mux_pio4_set_periph(SAMA5D2_BASE_PIOA,
+ BIT(*pin), instance->periph);
+ }
+
+ sama5d2_pmc_enable_periph_clock(instance->id);
+ sama5d2_pmc_enable_generic_clock(instance->id, AT91_PMC_GCKCSS_UPLL_CLK, 1);
+
+ ret = at91_sdhci_bio_init(&bio, instance->base);
+ if (ret)
+ goto out_panic;
+
+ /* TODO: eMMC boot partition handling: they are not FAT-formatted */
+
+ at91_fat_start_image(&bio, buf, SZ_16M, r4);
+
+out_panic:
+ panic("FAT chainloading failed\n");
+}