mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH 00/28] ARM: at91: add sama5d2 first stage support
@ 2020-07-01  5:23 Ahmad Fatoum
  2020-07-01  5:23 ` [PATCH 01/28] ARM: at91: remove <mach/hardware.h> include from assembly code Ahmad Fatoum
                   ` (27 more replies)
  0 siblings, 28 replies; 30+ messages in thread
From: Ahmad Fatoum @ 2020-07-01  5:23 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

This adapts the sama5d3 first stage patch set I sent around a few times
for use on the sama5d2. Unlike the original patch set, we now do the
chainloading in the PBL, so integrators can still use multi-image and
don't have to build barebox more than once.

With the FAT PBL implementation in place, first stages of the OMAP and
SoCFPGA could also be migrated to multi-image.

Much code has been adapted from at91bootstrap v3.8.12. Key changes:

 - We detect bootsource automatically, so we don't need to hardcode
   which MCI instance to use
 - We pass along the bootsource, so it's available to second stage
   bootloaders
 - We don't reset the SD card, so we can avoid having a complete
   SD/MMC core implementation in PBL
 - We don't disable the watchdog in first stage. We leave the decision
   on how to deal with it to second stage.
 
There's no defconfig for this yet, it will follow along with a generic
at91_multi_defconfig, when support for the sama5d3 is posted.

Cheers,
Ahmad Fatoum (28):
  ARM: at91: remove <mach/hardware.h> include from assembly code
  ARM: at91: sama5d2: cast peripheral base addresses to __iomem pointers
  ARM: at91: import at91bootstrap's at91_ddrsdrc.h
  ARM: at91: migrate at91sam9_ddrsdr.h to use at91bootstrap's
    at91_ddrsdrc.h
  ARM: at91: replace at91sam9_ddrsdr.h with at91bootstrap's
    at91_ddrsdrc.h
  ARM: at91: import early_udelay from at91bootstrap
  ARM: at91: import low level DDRAMC initialization code from
    at91bootstrap
  ARM: at91: watchdog: implement at91_wdt_disable
  watchdog: add support for at91sam9/sama5 watchdog
  ARM: at91: implement sama5d2 lowlevel init
  ARM: at91: sama5d2: add sama5d2 matrix configuration
  ARM: at91: add sama5d2 cache init
  ARM: at91: add necessary Advanced Interrupt Controller configuration
  ARM: at91: extend low level PMC driver for generic clk support
  pbl: add block I/O API
  fs: fat: extend for in-PBL support
  mci: extend atmel-sdhci driver to first stage use
  ARM: at91: add code for sama5 boot source detection
  ARM: at91: add helpers for chain-loading barebox from SD-card
  ARM: at91: sama5d2: reuse stack set-up by first stage
  at91: debug_ll: remove duplicated IS_ENABLED(CONFIG_DEBUG_LL)
    condition
  ARM: at91: sama5d2: reduce UART setup boilerplate with new helpers
  ARM: at91: sama5d27-som1: add additional first stage entry point
  ARM: at91: sama5d2: read back memory size from DDRAM controller
  ARM: at91: sama5d2: populate $bootsource and $bootsource_instance
  ARM: at91: sama5d27-som1-ek: add barebox_update and multi environment
    support
  ARM: at91: sama5d27-giantboard: add additional first stage entry point
  ARM: at91: sama5d27-giantboard: add default environment/bbu

 arch/arm/boards/at91sam9m10g45ek/lowlevel.c   |   2 +-
 arch/arm/boards/at91sam9m10ihd/lowlevel.c     |   2 +-
 arch/arm/boards/at91sam9n12ek/lowlevel.c      |   2 +-
 arch/arm/boards/at91sam9x5ek/lowlevel.c       |   3 +-
 arch/arm/boards/pm9g45/lowlevel.c             |   3 +-
 arch/arm/boards/sama5d27-giantboard/Makefile  |   2 +
 arch/arm/boards/sama5d27-giantboard/board.c   |  17 +
 .../defaultenv-giantboard/nv/boot.default     |   1 +
 .../arm/boards/sama5d27-giantboard/lowlevel.c |  51 +-
 arch/arm/boards/sama5d27-som1/Makefile        |   1 +
 arch/arm/boards/sama5d27-som1/board.c         |  35 ++
 arch/arm/boards/sama5d27-som1/lowlevel.c      |  61 +--
 arch/arm/boards/sama5d3_xplained/lowlevel.c   |   2 +-
 arch/arm/boards/sama5d3xek/lowlevel.c         |   2 +-
 arch/arm/boards/sama5d4_xplained/lowlevel.c   |   2 +-
 arch/arm/boards/sama5d4ek/lowlevel.c          |   2 +-
 arch/arm/dts/at91-sama5d27_giantboard.dts     |  10 +-
 arch/arm/dts/at91-sama5d27_som1_ek.dts        |  19 +-
 arch/arm/dts/sama5d2.dtsi                     |   2 +
 arch/arm/mach-at91/Kconfig                    |  11 +
 arch/arm/mach-at91/Makefile                   |   9 +-
 arch/arm/mach-at91/aic.c                      |  28 +
 arch/arm/mach-at91/at91_pmc_ll.c              | 169 +++++-
 arch/arm/mach-at91/at91sam9_reset.S           |   1 -
 arch/arm/mach-at91/at91sam9g45_devices.c      |   2 +-
 arch/arm/mach-at91/at91sam9g45_reset.S        |   9 +-
 arch/arm/mach-at91/at91sam9n12_devices.c      |   2 +-
 arch/arm/mach-at91/at91sam9x5_devices.c       |   2 +-
 arch/arm/mach-at91/ddramc.c                   |  59 ++
 arch/arm/mach-at91/ddramc_ll.c                | 507 ++++++++++++++++++
 arch/arm/mach-at91/early_udelay.c             |  56 ++
 arch/arm/mach-at91/include/mach/aic.h         |   9 +
 arch/arm/mach-at91/include/mach/at91_dbgu.h   |  34 +-
 .../arm/mach-at91/include/mach/at91_ddrsdrc.h | 373 +++++++++++++
 arch/arm/mach-at91/include/mach/at91_pmc.h    |  22 +
 arch/arm/mach-at91/include/mach/at91_pmc_ll.h |  32 +-
 arch/arm/mach-at91/include/mach/at91_wdt.h    |  16 +
 .../mach-at91/include/mach/at91sam9_ddrsdr.h  | 214 --------
 arch/arm/mach-at91/include/mach/barebox-arm.h |  21 +
 arch/arm/mach-at91/include/mach/ddramc.h      |  37 ++
 arch/arm/mach-at91/include/mach/debug_ll.h    |  17 +-
 .../arm/mach-at91/include/mach/early_udelay.h |  14 +
 arch/arm/mach-at91/include/mach/matrix.h      |  21 +
 .../mach-at91/include/mach/sama5_bootsource.h |  49 ++
 .../include/mach/sama5d2-sip-ddramc.h         |  39 ++
 arch/arm/mach-at91/include/mach/sama5d2.h     | 225 +++++---
 arch/arm/mach-at91/include/mach/sama5d2_ll.h  | 139 +++++
 arch/arm/mach-at91/include/mach/tz_matrix.h   |  95 ++++
 arch/arm/mach-at91/include/mach/xload.h       |  12 +
 arch/arm/mach-at91/matrix.c                   |  45 ++
 arch/arm/mach-at91/sama5d2.c                  |  71 +++
 arch/arm/mach-at91/sama5d2_ll.c               | 220 ++++++++
 arch/arm/mach-at91/sama5d3_devices.c          |   2 +-
 arch/arm/mach-at91/sama5d4_devices.c          |   2 +-
 arch/arm/mach-at91/xload-mmc.c                |  85 +++
 common/Makefile                               |   3 +-
 drivers/mci/Kconfig                           |   4 +
 drivers/mci/Makefile                          |   1 +
 drivers/mci/atmel-sdhci-common.c              |   3 +
 drivers/mci/atmel-sdhci-pbl.c                 | 128 +++++
 drivers/watchdog/Kconfig                      |   6 +
 drivers/watchdog/Makefile                     |   1 +
 drivers/watchdog/at91sam9_wdt.c               | 109 ++++
 fs/Makefile                                   |   2 +-
 fs/fat/Kconfig                                |   7 +
 fs/fat/Makefile                               |   4 +-
 fs/fat/diskio.h                               |   7 +-
 fs/fat/fat-pbl.c                              |  53 ++
 fs/fat/fat.c                                  |  31 --
 fs/fat/ff.c                                   |  89 +--
 fs/fat/ff.h                                   |  22 +-
 images/Makefile.at91                          |  10 +
 include/pbl.h                                 |  15 +
 lib/Makefile                                  |   2 +-
 74 files changed, 2845 insertions(+), 520 deletions(-)
 create mode 100644 arch/arm/boards/sama5d27-giantboard/board.c
 create mode 100644 arch/arm/boards/sama5d27-giantboard/defaultenv-giantboard/nv/boot.default
 create mode 100644 arch/arm/boards/sama5d27-som1/board.c
 create mode 100644 arch/arm/mach-at91/aic.c
 create mode 100644 arch/arm/mach-at91/ddramc.c
 create mode 100644 arch/arm/mach-at91/ddramc_ll.c
 create mode 100644 arch/arm/mach-at91/early_udelay.c
 create mode 100644 arch/arm/mach-at91/include/mach/aic.h
 create mode 100644 arch/arm/mach-at91/include/mach/at91_ddrsdrc.h
 delete mode 100644 arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h
 create mode 100644 arch/arm/mach-at91/include/mach/barebox-arm.h
 create mode 100644 arch/arm/mach-at91/include/mach/ddramc.h
 create mode 100644 arch/arm/mach-at91/include/mach/early_udelay.h
 create mode 100644 arch/arm/mach-at91/include/mach/matrix.h
 create mode 100644 arch/arm/mach-at91/include/mach/sama5_bootsource.h
 create mode 100644 arch/arm/mach-at91/include/mach/sama5d2-sip-ddramc.h
 create mode 100644 arch/arm/mach-at91/include/mach/sama5d2_ll.h
 create mode 100644 arch/arm/mach-at91/include/mach/tz_matrix.h
 create mode 100644 arch/arm/mach-at91/include/mach/xload.h
 create mode 100644 arch/arm/mach-at91/matrix.c
 create mode 100644 arch/arm/mach-at91/sama5d2.c
 create mode 100644 arch/arm/mach-at91/sama5d2_ll.c
 create mode 100644 arch/arm/mach-at91/xload-mmc.c
 create mode 100644 drivers/mci/atmel-sdhci-pbl.c
 create mode 100644 drivers/watchdog/at91sam9_wdt.c
 create mode 100644 fs/fat/fat-pbl.c

-- 
2.27.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 01/28] ARM: at91: remove <mach/hardware.h> include from assembly code
  2020-07-01  5:23 [PATCH 00/28] ARM: at91: add sama5d2 first stage support Ahmad Fatoum
@ 2020-07-01  5:23 ` Ahmad Fatoum
  2020-07-01  5:23 ` [PATCH 02/28] ARM: at91: sama5d2: cast peripheral base addresses to __iomem pointers Ahmad Fatoum
                   ` (26 subsequent siblings)
  27 siblings, 0 replies; 30+ messages in thread
From: Ahmad Fatoum @ 2020-07-01  5:23 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

They are unused and force all headers included by it to have
__ASSEMBLY__ guards for non-preprocessor code. Avoid this.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 arch/arm/mach-at91/at91sam9_reset.S    | 1 -
 arch/arm/mach-at91/at91sam9g45_reset.S | 1 -
 2 files changed, 2 deletions(-)

diff --git a/arch/arm/mach-at91/at91sam9_reset.S b/arch/arm/mach-at91/at91sam9_reset.S
index 65e22f4fe7e3..ba3f76833161 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/at91sam9g45_reset.S b/arch/arm/mach-at91/at91sam9g45_reset.S
index 6a58de618ce0..98db15c0b0fc 100644
--- a/arch/arm/mach-at91/at91sam9g45_reset.S
+++ b/arch/arm/mach-at91/at91sam9g45_reset.S
@@ -11,7 +11,6 @@
  */
 
 #include <linux/linkage.h>
-#include <mach/hardware.h>
 #include <mach/at91sam9_ddrsdr.h>
 #include <mach/at91_rstc.h>
 
-- 
2.27.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 02/28] ARM: at91: sama5d2: cast peripheral base addresses to __iomem pointers
  2020-07-01  5:23 [PATCH 00/28] ARM: at91: add sama5d2 first stage support Ahmad Fatoum
  2020-07-01  5:23 ` [PATCH 01/28] ARM: at91: remove <mach/hardware.h> include from assembly code Ahmad Fatoum
@ 2020-07-01  5:23 ` Ahmad Fatoum
  2020-07-01  5:23 ` [PATCH 03/28] ARM: at91: import at91bootstrap's at91_ddrsdrc.h Ahmad Fatoum
                   ` (25 subsequent siblings)
  27 siblings, 0 replies; 30+ messages in thread
From: Ahmad Fatoum @ 2020-07-01  5:23 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

The peripheral addresses should be always cast with IOMEM() anyway, so do
this directly in the header to make user code less verbose.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 .../arm/boards/sama5d27-giantboard/lowlevel.c |   6 +-
 arch/arm/boards/sama5d27-som1/lowlevel.c      |  14 +-
 arch/arm/mach-at91/include/mach/sama5d2.h     | 169 +++++++++---------
 3 files changed, 96 insertions(+), 93 deletions(-)

diff --git a/arch/arm/boards/sama5d27-giantboard/lowlevel.c b/arch/arm/boards/sama5d27-giantboard/lowlevel.c
index 0236c424c195..50bc2613c652 100644
--- a/arch/arm/boards/sama5d27-giantboard/lowlevel.c
+++ b/arch/arm/boards/sama5d27-giantboard/lowlevel.c
@@ -20,7 +20,7 @@
 
 static inline void sama5d2_pmc_enable_periph_clock(int clk)
 {
-	at91_pmc_sam9x5_enable_periph_clock(IOMEM(SAMA5D2_BASE_PMC), clk);
+	at91_pmc_sam9x5_enable_periph_clock(SAMA5D2_BASE_PMC, clk);
 }
 
 static void dbgu_init(void)
@@ -29,12 +29,12 @@ static void dbgu_init(void)
 
 	sama5d2_pmc_enable_periph_clock(SAMA5D2_ID_PIOD);
 
-	at91_mux_pio4_set_A_periph(IOMEM(SAMA5D2_BASE_PIOD),
+	at91_mux_pio4_set_A_periph(SAMA5D2_BASE_PIOD,
 				   pin_to_mask(AT91_PIN_PD3)); /* DBGU TXD */
 
 	sama5d2_pmc_enable_periph_clock(SAMA5D2_ID_UART1);
 
-	at91_dbgu_setup_ll(IOMEM(SAMA5D2_BASE_UART1), mck, 115200);
+	at91_dbgu_setup_ll(SAMA5D2_BASE_UART1, mck, 115200);
 
 	putc_ll('>');
 }
diff --git a/arch/arm/boards/sama5d27-som1/lowlevel.c b/arch/arm/boards/sama5d27-som1/lowlevel.c
index 62d35be9123d..569960be445d 100644
--- a/arch/arm/boards/sama5d27-som1/lowlevel.c
+++ b/arch/arm/boards/sama5d27-som1/lowlevel.c
@@ -24,13 +24,13 @@
 
 static inline void sama5d2_pmc_enable_periph_clock(int clk)
 {
-	at91_pmc_sam9x5_enable_periph_clock(IOMEM(SAMA5D2_BASE_PMC), clk);
+	at91_pmc_sam9x5_enable_periph_clock(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,9 +41,9 @@ 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);
 	}
 }
 
@@ -53,12 +53,12 @@ static void ek_dbgu_init(void)
 
 	sama5d2_pmc_enable_periph_clock(SAMA5D2_ID_PIOD);
 
-	at91_mux_pio4_set_A_periph(IOMEM(SAMA5D2_BASE_PIOD),
+	at91_mux_pio4_set_A_periph(SAMA5D2_BASE_PIOD,
 				   pin_to_mask(AT91_PIN_PD3)); /* DBGU TXD */
 
 	sama5d2_pmc_enable_periph_clock(SAMA5D2_ID_UART1);
 
-	at91_dbgu_setup_ll(IOMEM(SAMA5D2_BASE_UART1), mck, 115200);
+	at91_dbgu_setup_ll(SAMA5D2_BASE_UART1, mck, 115200);
 
 	putc_ll('>');
 }
diff --git a/arch/arm/mach-at91/include/mach/sama5d2.h b/arch/arm/mach-at91/include/mach/sama5d2.h
index 3dad7d9c9c2c..ada9c59e0370 100644
--- a/arch/arm/mach-at91/include/mach/sama5d2.h
+++ b/arch/arm/mach-at91/include/mach/sama5d2.h
@@ -14,6 +14,9 @@
 #ifndef SAMA5D2_H
 #define SAMA5D2_H
 
+#include <asm/io.h>
+#include <linux/sizes.h>
+
 /*
  * Peripheral identifiers/interrupts. (Table 18-9)
  */
@@ -101,100 +104,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
-- 
2.27.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 03/28] ARM: at91: import at91bootstrap's at91_ddrsdrc.h
  2020-07-01  5:23 [PATCH 00/28] ARM: at91: add sama5d2 first stage support Ahmad Fatoum
  2020-07-01  5:23 ` [PATCH 01/28] ARM: at91: remove <mach/hardware.h> include from assembly code Ahmad Fatoum
  2020-07-01  5:23 ` [PATCH 02/28] ARM: at91: sama5d2: cast peripheral base addresses to __iomem pointers Ahmad Fatoum
@ 2020-07-01  5:23 ` Ahmad Fatoum
  2020-07-01  5:23 ` [PATCH 04/28] ARM: at91: migrate at91sam9_ddrsdr.h to use " Ahmad Fatoum
                   ` (24 subsequent siblings)
  27 siblings, 0 replies; 30+ messages in thread
From: Ahmad Fatoum @ 2020-07-01  5:23 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

Instead of adding missing definitions to the existing at91sam9_ddrsdr.h
and adapting the incoming DDRAM initialization code from at91bootstrap,
just replace the lightly used existing header with:
https://github.com/linux4sam/at91bootstrap/blob/v3.8.12/include/arch/at91_ddrsdrc.h

For easier comprehension, the replacement is done in three steps:
Here the header is imported.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 .../arm/mach-at91/include/mach/at91_ddrsdrc.h | 295 ++++++++++++++++++
 1 file changed, 295 insertions(+)
 create mode 100644 arch/arm/mach-at91/include/mach/at91_ddrsdrc.h

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 000000000000..17e64fcb9a62
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/at91_ddrsdrc.h
@@ -0,0 +1,295 @@
+/* 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)
+
+#endif	/* #ifndef __AT91_DDRSDRC_H__ */
-- 
2.27.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 04/28] ARM: at91: migrate at91sam9_ddrsdr.h to use at91bootstrap's at91_ddrsdrc.h
  2020-07-01  5:23 [PATCH 00/28] ARM: at91: add sama5d2 first stage support Ahmad Fatoum
                   ` (2 preceding siblings ...)
  2020-07-01  5:23 ` [PATCH 03/28] ARM: at91: import at91bootstrap's at91_ddrsdrc.h Ahmad Fatoum
@ 2020-07-01  5:23 ` Ahmad Fatoum
  2020-07-01  5:23 ` [PATCH 05/28] ARM: at91: replace at91sam9_ddrsdr.h with " Ahmad Fatoum
                   ` (23 subsequent siblings)
  27 siblings, 0 replies; 30+ messages in thread
From: Ahmad Fatoum @ 2020-07-01  5:23 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

Instead of adding missing definitions to the existing at91sam9_ddrsdr.h
and adapting the incoming DDRAM initialization code from at91bootstrap,
just replace the lightly used existing header with:
https://github.com/linux4sam/at91bootstrap/blob/v3.8.12/include/arch/at91_ddrsdrc.h

For easier comprehension, the replacement is done in three steps:
Here the existing at91sam9_ddrsdr.h has its now duplicate (in function,
not name) macros removed and existing users are migrated to use the new
header.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 arch/arm/mach-at91/at91sam9g45_reset.S        |   6 +-
 .../mach-at91/include/mach/at91sam9_ddrsdr.h  | 138 ++----------------
 2 files changed, 12 insertions(+), 132 deletions(-)

diff --git a/arch/arm/mach-at91/at91sam9g45_reset.S b/arch/arm/mach-at91/at91sam9g45_reset.S
index 98db15c0b0fc..c3115fd9ca7a 100644
--- a/arch/arm/mach-at91/at91sam9g45_reset.S
+++ b/arch/arm/mach-at91/at91sam9g45_reset.S
@@ -19,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/include/mach/at91sam9_ddrsdr.h b/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h
index 496cf707014e..88ed1fce558f 100644
--- a/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h
+++ b/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h
@@ -12,130 +12,10 @@
 #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 */
+#include <mach/at91_ddrsdrc.h>
 
 #ifndef __ASSEMBLY__
+#include <common.h>
 #include <io.h>
 #include <mach/hardware.h>
 
@@ -146,11 +26,11 @@ static inline u32 at91_get_ddram_size(void __iomem *base, bool is_nb)
 	u32 size;
 	bool is_sdram;
 
-	cr = readl(base + AT91_DDRSDRC_CR);
-	mdr = readl(base + AT91_DDRSDRC_MDR);
+	cr = readl(base + AT91C_HDDRSDRC2_CR);
+	mdr = readl(base + AT91C_HDDRSDRC2_MDR);
 
 	/* will always be false for sama5d2, sama5d3 or sama5d4 */
-	is_sdram = (mdr & AT91_DDRSDRC_MD) <= AT91_DDRSDRC_MD_LOW_POWER_SDR;
+	is_sdram = (mdr & AT91C_DDRC2_MD) <= AT91C_DDRC2_MD_LP_SDR_SDRAM;
 
 	/* Formula:
 	 * size = bank << (col + row + 1);
@@ -159,19 +39,19 @@ static inline u32 at91_get_ddram_size(void __iomem *base, bool is_nb)
 	 */
 	size = 1;
 	/* COL */
-	size += (cr & AT91_DDRSDRC_NC) + 8;
+	size += (cr & AT91C_DDRC2_NC) + 8;
 	if (!is_sdram)
 		size ++;
 	/* ROW */
-	size += ((cr & AT91_DDRSDRC_NR) >> 2) + 11;
+	size += ((cr & AT91C_DDRC2_NR) >> 2) + 11;
 	/* BANK */
 	if (is_nb)
-		size = ((cr & AT91_DDRSDRC_NB) ? 8 : 4) << size;
+		size = ((cr & AT91C_DDRC2_NB_BANKS) ? 8 : 4) << size;
 	else
 		size = 4 << size;
 
 	/* bandwidth */
-	if (!(mdr & AT91_DDRSDRC_DBW))
+	if (!(mdr & AT91C_DDRC2_DBW))
 		size <<= 1;
 
 	return size;
-- 
2.27.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 05/28] ARM: at91: replace at91sam9_ddrsdr.h with at91bootstrap's at91_ddrsdrc.h
  2020-07-01  5:23 [PATCH 00/28] ARM: at91: add sama5d2 first stage support Ahmad Fatoum
                   ` (3 preceding siblings ...)
  2020-07-01  5:23 ` [PATCH 04/28] ARM: at91: migrate at91sam9_ddrsdr.h to use " Ahmad Fatoum
@ 2020-07-01  5:23 ` Ahmad Fatoum
  2020-07-01  5:23 ` [PATCH 06/28] ARM: at91: import early_udelay from at91bootstrap Ahmad Fatoum
                   ` (22 subsequent siblings)
  27 siblings, 0 replies; 30+ messages in thread
From: Ahmad Fatoum @ 2020-07-01  5:23 UTC (permalink / raw)
  To: barebox; +Cc: Sam Ravnborg, Ahmad Fatoum

Instead of adding missing definitions to the existing at91sam9_ddrsdr.h
and adapting the incoming DDRAM initialization code from at91bootstrap,
just replace the lightly used existing header with:
https://github.com/linux4sam/at91bootstrap/blob/v3.8.12/include/arch/at91_ddrsdrc.h

For easier comprehension, the replacement is done in three steps:
This last step copies the memory size querying functions from at91sam9_ddrsdr.h
to at91_ddrsdrc.h, then deletes it and fixes all references.

Reviewed-by: Sam Ravnborg <sam@ravnborg.org>
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 arch/arm/boards/at91sam9m10g45ek/lowlevel.c   |  2 +-
 arch/arm/boards/at91sam9m10ihd/lowlevel.c     |  2 +-
 arch/arm/boards/at91sam9n12ek/lowlevel.c      |  2 +-
 arch/arm/boards/at91sam9x5ek/lowlevel.c       |  3 +-
 arch/arm/boards/pm9g45/lowlevel.c             |  3 +-
 arch/arm/boards/sama5d3_xplained/lowlevel.c   |  2 +-
 arch/arm/boards/sama5d3xek/lowlevel.c         |  2 +-
 arch/arm/boards/sama5d4_xplained/lowlevel.c   |  2 +-
 arch/arm/boards/sama5d4ek/lowlevel.c          |  2 +-
 arch/arm/mach-at91/at91sam9g45_devices.c      |  2 +-
 arch/arm/mach-at91/at91sam9g45_reset.S        |  2 +-
 arch/arm/mach-at91/at91sam9n12_devices.c      |  2 +-
 arch/arm/mach-at91/at91sam9x5_devices.c       |  2 +-
 .../arm/mach-at91/include/mach/at91_ddrsdrc.h | 78 +++++++++++++++
 .../mach-at91/include/mach/at91sam9_ddrsdr.h  | 94 -------------------
 arch/arm/mach-at91/sama5d3_devices.c          |  2 +-
 arch/arm/mach-at91/sama5d4_devices.c          |  2 +-
 17 files changed, 94 insertions(+), 110 deletions(-)
 delete mode 100644 arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h

diff --git a/arch/arm/boards/at91sam9m10g45ek/lowlevel.c b/arch/arm/boards/at91sam9m10g45ek/lowlevel.c
index 0f3a035d1d6f..755e7ec029f9 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 e07ff892cdb0..817c7548c914 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 5bc18f8fcad6..4353555d0dd0 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 c1433c8f7e84..ebd417b19cc0 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 fc0bfe405b0d..5f66b2825480 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/sama5d3_xplained/lowlevel.c b/arch/arm/boards/sama5d3_xplained/lowlevel.c
index 8653c48c6936..28c07d50531e 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 8653c48c6936..28c07d50531e 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 9a6a767e5f5b..3c58a08f3b9d 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 9a6a767e5f5b..3c58a08f3b9d 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/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c
index 43d8d5fbd6a2..389d88c17d4f 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 c3115fd9ca7a..67517bf59114 100644
--- a/arch/arm/mach-at91/at91sam9g45_reset.S
+++ b/arch/arm/mach-at91/at91sam9g45_reset.S
@@ -11,7 +11,7 @@
  */
 
 #include <linux/linkage.h>
-#include <mach/at91sam9_ddrsdr.h>
+#include <mach/at91_ddrsdrc.h>
 #include <mach/at91_rstc.h>
 
 			.arm
diff --git a/arch/arm/mach-at91/at91sam9n12_devices.c b/arch/arm/mach-at91/at91sam9n12_devices.c
index 43cbb79af4a5..91b3e9b2fbc5 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 ab506a1f4236..022e4fb59ab9 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/include/mach/at91_ddrsdrc.h b/arch/arm/mach-at91/include/mach/at91_ddrsdrc.h
index 17e64fcb9a62..7d70fe4cb4d8 100644
--- a/arch/arm/mach-at91/include/mach/at91_ddrsdrc.h
+++ b/arch/arm/mach-at91/include/mach/at91_ddrsdrc.h
@@ -292,4 +292,82 @@
 #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/at91sam9_ddrsdr.h b/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h
deleted file mode 100644
index 88ed1fce558f..000000000000
--- a/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h
+++ /dev/null
@@ -1,94 +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
-
-#include <mach/at91_ddrsdrc.h>
-
-#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 + AT91C_HDDRSDRC2_CR);
-	mdr = readl(base + AT91C_HDDRSDRC2_MDR);
-
-	/* will always be false for sama5d2, sama5d3 or sama5d4 */
-	is_sdram = (mdr & AT91C_DDRC2_MD) <= AT91C_DDRC2_MD_LP_SDR_SDRAM;
-
-	/* Formula:
-	 * size = bank << (col + row + 1);
-	 * if (bandwidth == 32 bits)
-	 *	size <<= 1;
-	 */
-	size = 1;
-	/* COL */
-	size += (cr & AT91C_DDRC2_NC) + 8;
-	if (!is_sdram)
-		size ++;
-	/* ROW */
-	size += ((cr & AT91C_DDRC2_NR) >> 2) + 11;
-	/* BANK */
-	if (is_nb)
-		size = ((cr & AT91C_DDRC2_NB_BANKS) ? 8 : 4) << size;
-	else
-		size = 4 << size;
-
-	/* bandwidth */
-	if (!(mdr & AT91C_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
-
-#endif
diff --git a/arch/arm/mach-at91/sama5d3_devices.c b/arch/arm/mach-at91/sama5d3_devices.c
index bf4a03d40407..e29ed2ba976c 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 5a1109dc0eab..7be9e260d4a6 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>
-- 
2.27.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 06/28] ARM: at91: import early_udelay from at91bootstrap
  2020-07-01  5:23 [PATCH 00/28] ARM: at91: add sama5d2 first stage support Ahmad Fatoum
                   ` (4 preceding siblings ...)
  2020-07-01  5:23 ` [PATCH 05/28] ARM: at91: replace at91sam9_ddrsdr.h with " Ahmad Fatoum
@ 2020-07-01  5:23 ` Ahmad Fatoum
  2020-07-01  5:23 ` [PATCH 07/28] ARM: at91: import low level DDRAMC initialization code " Ahmad Fatoum
                   ` (21 subsequent siblings)
  27 siblings, 0 replies; 30+ messages in thread
From: Ahmad Fatoum @ 2020-07-01  5:23 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

For use by the incoming at91bootstrap DDRAMC initialization code,
this commit provides an early_udelay function usable in PBL imported from
https://github.com/linux4sam/at91bootstrap/blob/v3.8.12/driver/at91_pit.c

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 arch/arm/mach-at91/Makefile                   |  1 +
 arch/arm/mach-at91/early_udelay.c             | 56 +++++++++++++++++++
 arch/arm/mach-at91/include/mach/at91_pmc_ll.h | 13 ++++-
 .../arm/mach-at91/include/mach/early_udelay.h | 14 +++++
 4 files changed, 83 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/mach-at91/early_udelay.c
 create mode 100644 arch/arm/mach-at91/include/mach/early_udelay.h

diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
index 89aff54b8af7..863b62eddcd0 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
+lwl-$(CONFIG_CLOCKSOURCE_ATMEL_PIT) += early_udelay.o
 
 ifeq ($(CONFIG_COMMON_CLK_OF_PROVIDER),)
 obj-y += clock.o
diff --git a/arch/arm/mach-at91/early_udelay.c b/arch/arm/mach-at91/early_udelay.c
new file mode 100644
index 000000000000..632e797bebe9
--- /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/at91_pmc_ll.h b/arch/arm/mach-at91/include/mach/at91_pmc_ll.h
index eda40e8e12e7..e3d3e3ad59db 100644
--- a/arch/arm/mach-at91/include/mach/at91_pmc_ll.h
+++ b/arch/arm/mach-at91/include/mach/at91_pmc_ll.h
@@ -13,6 +13,7 @@
 #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_AT91RM9200	(0)
 #define AT91_PMC_LL_AT91SAM9260	(0)
@@ -27,7 +28,8 @@
 				 AT91_PMC_LL_FLAG_MEASURE_XTAL)
 #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)
+#define AT91_PMC_LL_SAMA5D4	(AT91_PMC_LL_FLAG_SAM9X5_PMC | \
+				 AT91_PMC_LL_FLAG_H32MXDIV)
 
 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);
@@ -75,4 +77,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/early_udelay.h b/arch/arm/mach-at91/include/mach/early_udelay.h
new file mode 100644
index 000000000000..1c1b0123fee8
--- /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
-- 
2.27.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 07/28] ARM: at91: import low level DDRAMC initialization code from at91bootstrap
  2020-07-01  5:23 [PATCH 00/28] ARM: at91: add sama5d2 first stage support Ahmad Fatoum
                   ` (5 preceding siblings ...)
  2020-07-01  5:23 ` [PATCH 06/28] ARM: at91: import early_udelay from at91bootstrap Ahmad Fatoum
@ 2020-07-01  5:23 ` Ahmad Fatoum
  2020-07-01  5:23 ` [PATCH 08/28] ARM: at91: watchdog: implement at91_wdt_disable Ahmad Fatoum
                   ` (20 subsequent siblings)
  27 siblings, 0 replies; 30+ messages in thread
From: Ahmad Fatoum @ 2020-07-01  5:23 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

This commit imports DDRAMC initialization routines for use in PBL from
https://github.com/linux4sam/at91bootstrap/blob/v3.8.12/driver/ddramc.c

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 arch/arm/mach-at91/Makefile              |   2 +-
 arch/arm/mach-at91/ddramc_ll.c           | 507 +++++++++++++++++++++++
 arch/arm/mach-at91/include/mach/ddramc.h |  36 ++
 3 files changed, 544 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/mach-at91/ddramc_ll.c
 create mode 100644 arch/arm/mach-at91/include/mach/ddramc.h

diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
index 863b62eddcd0..a7e9ce5938e8 100644
--- a/arch/arm/mach-at91/Makefile
+++ b/arch/arm/mach-at91/Makefile
@@ -1,5 +1,5 @@
 obj-y += setup.o
-lwl-y += at91_pmc_ll.o
+lwl-y += at91_pmc_ll.o ddramc_ll.o
 lwl-$(CONFIG_CLOCKSOURCE_ATMEL_PIT) += early_udelay.o
 
 ifeq ($(CONFIG_COMMON_CLK_OF_PROVIDER),)
diff --git a/arch/arm/mach-at91/ddramc_ll.c b/arch/arm/mach-at91/ddramc_ll.c
new file mode 100644
index 000000000000..4768fdcd6281
--- /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/include/mach/ddramc.h b/arch/arm/mach-at91/include/mach/ddramc.h
new file mode 100644
index 000000000000..0b33afc21353
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/ddramc.h
@@ -0,0 +1,36 @@
+// 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);
+
+
+#endif /* #ifndef __DDRAMC_H__ */
-- 
2.27.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 08/28] ARM: at91: watchdog: implement at91_wdt_disable
  2020-07-01  5:23 [PATCH 00/28] ARM: at91: add sama5d2 first stage support Ahmad Fatoum
                   ` (6 preceding siblings ...)
  2020-07-01  5:23 ` [PATCH 07/28] ARM: at91: import low level DDRAMC initialization code " Ahmad Fatoum
@ 2020-07-01  5:23 ` Ahmad Fatoum
  2020-07-01  5:23 ` [PATCH 09/28] watchdog: add support for at91sam9/sama5 watchdog Ahmad Fatoum
                   ` (19 subsequent siblings)
  27 siblings, 0 replies; 30+ messages in thread
From: Ahmad Fatoum @ 2020-07-01  5:23 UTC (permalink / raw)
  To: barebox; +Cc: Sam Ravnborg, Ahmad Fatoum

Board code might want to disable the watchdog in PBL and enable it later
prior to boot. Provide a helper to do so.

Reviewed-by: Sam Ravnborg <sam@ravnborg.org>
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 arch/arm/mach-at91/include/mach/at91_wdt.h | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/arch/arm/mach-at91/include/mach/at91_wdt.h b/arch/arm/mach-at91/include/mach/at91_wdt.h
index 36d37b9d2d64..d295d35d1b5c 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
-- 
2.27.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 09/28] watchdog: add support for at91sam9/sama5 watchdog
  2020-07-01  5:23 [PATCH 00/28] ARM: at91: add sama5d2 first stage support Ahmad Fatoum
                   ` (7 preceding siblings ...)
  2020-07-01  5:23 ` [PATCH 08/28] ARM: at91: watchdog: implement at91_wdt_disable Ahmad Fatoum
@ 2020-07-01  5:23 ` Ahmad Fatoum
  2020-07-01  5:23 ` [PATCH 10/28] ARM: at91: implement sama5d2 lowlevel init Ahmad Fatoum
                   ` (18 subsequent siblings)
  27 siblings, 0 replies; 30+ messages in thread
From: Ahmad Fatoum @ 2020-07-01  5:23 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

The watchdog on these SoCs is enabled by default on system boot, so a
driver is especially useful. According to data sheet the mode register
containing the timeout can be configured only once, but I couldn't
verify this on the sama5d2. Regardless, the driver takes care not to
change the mode register unless necessary. Implementation that want to
leave to the OS the decision which timeout to choose, can just keep
pinging with the POR-default of 16 seconds and the OS will be able to
set the final timeout.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 drivers/watchdog/Kconfig        |   6 ++
 drivers/watchdog/Makefile       |   1 +
 drivers/watchdog/at91sam9_wdt.c | 109 ++++++++++++++++++++++++++++++++
 3 files changed, 116 insertions(+)
 create mode 100644 drivers/watchdog/at91sam9_wdt.c

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index d9734ef58895..cf83b6a15bd4 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -22,6 +22,12 @@ config WATCHDOG_AR9344
 	help
 	  Add support for watchdog on the QCA AR9344 SoC.
 
+config WATCHDOG_AT91SAM9
+	bool "Watchdog for AT91SAM9 and SAMA5 SoCs"
+	depends on ARCH_AT91
+	help
+	  Support for the watchdog in AT91SAM9X and SAMA5D{2,3,4} SoCs.
+
 config WATCHDOG_EFI
 	bool "Generic EFI Watchdog Driver"
 	depends on EFI_BOOTUP
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 3af64db3f247..dc9842770a62 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -1,5 +1,6 @@
 obj-$(CONFIG_WATCHDOG) += wd_core.o
 obj-$(CONFIG_WATCHDOG_AR9344) += ar9344_wdt.o
+obj-$(CONFIG_WATCHDOG_AT91SAM9) += at91sam9_wdt.o
 obj-$(CONFIG_WATCHDOG_EFI) += efi_wdt.o
 obj-$(CONFIG_WATCHDOG_DAVINCI) += davinci_wdt.o
 obj-$(CONFIG_WATCHDOG_OMAP) += omap_wdt.o
diff --git a/drivers/watchdog/at91sam9_wdt.c b/drivers/watchdog/at91sam9_wdt.c
new file mode 100644
index 000000000000..3f554bf47b76
--- /dev/null
+++ b/drivers/watchdog/at91sam9_wdt.c
@@ -0,0 +1,109 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019 Pengutronix, Ahmad Fatoum <a.fatoum@pengutronix.de>
+ */
+
+#include <common.h>
+#include <init.h>
+#include <io.h>
+#include <watchdog.h>
+#include <linux/clk.h>
+#include <mach/at91_wdt.h>
+
+#define MIN_WDT_TIMEOUT		1
+#define MAX_WDT_TIMEOUT		16
+#define SECS_TO_WDOG_TICKS(s)	((s) ? (((s) << 8) - 1) : 0)
+
+struct at91sam9x_wdt {
+	struct watchdog wdd;
+	void __iomem *base;
+};
+
+static inline void at91sam9x_wdt_ping(struct at91sam9x_wdt *wdt)
+{
+	writel(AT91_WDT_WDRSTT | AT91_WDT_KEY, wdt->base + AT91_WDT_CR);
+}
+
+static int at91sam9x_wdt_set_timeout(struct watchdog *wdd, unsigned timeout)
+{
+	struct at91sam9x_wdt *wdt = container_of(wdd, struct at91sam9x_wdt, wdd);
+	u32 mr_old, mr_new;
+
+	mr_old = readl(wdt->base + AT91_WDT_MR);
+
+	if (!timeout) {
+		mr_new = mr_old | AT91_WDT_WDDIS;
+		writel(mr_new, wdt->base + AT91_WDT_MR);
+		return 0;
+	}
+
+	mr_new = AT91_WDT_WDRSTEN
+		| AT91_WDT_WDDBGHLT | AT91_WDT_WDIDLEHLT
+		| AT91_WDT_WDD
+		| (SECS_TO_WDOG_TICKS(timeout) & AT91_WDT_WDV);
+
+	if (mr_new != mr_old)
+		writel(mr_new, wdt->base + AT91_WDT_MR);
+
+	at91sam9x_wdt_ping(wdt);
+	return 0;
+}
+
+static inline bool at91sam9x_wdt_is_disabled(struct at91sam9x_wdt *wdt)
+{
+	return readl(wdt->base + AT91_WDT_MR) & AT91_WDT_WDDIS;
+}
+
+static int at91sam9x_wdt_probe(struct device_d *dev)
+{
+	struct at91sam9x_wdt *wdt;
+	struct resource *iores;
+	struct clk *clk;
+	int ret;
+
+	wdt = xzalloc(sizeof(*wdt));
+	iores = dev_request_mem_resource(dev, 0);
+	if (IS_ERR(iores)) {
+		dev_err(dev, "could not get watchdog memory region\n");
+		return PTR_ERR(iores);
+	}
+	wdt->base = IOMEM(iores->start);
+	clk = clk_get(dev, NULL);
+	if (WARN_ON(IS_ERR(clk)))
+		return PTR_ERR(clk);
+
+	clk_enable(clk);
+
+	wdt->wdd.set_timeout = at91sam9x_wdt_set_timeout;
+	wdt->wdd.timeout_max = MAX_WDT_TIMEOUT;
+	wdt->wdd.hwdev = dev;
+
+	if (at91sam9x_wdt_is_disabled(wdt))
+		wdt->wdd.running = WDOG_HW_NOT_RUNNING;
+	else
+		wdt->wdd.running = WDOG_HW_RUNNING;
+
+	ret = watchdog_register(&wdt->wdd);
+	if (ret)
+		free(wdt);
+
+	return ret;
+}
+
+static const __maybe_unused struct of_device_id at91sam9x_wdt_dt_ids[] = {
+	{ .compatible = "atmel,at91sam9260-wdt", },
+	{ .compatible = "atmel,sama5d4-wdt", },
+	{ /* sentinel */ },
+};
+
+static struct driver_d at91sam9x_wdt_driver = {
+	.name		= "at91sam9x-wdt",
+	.of_compatible	= DRV_OF_COMPAT(at91sam9x_wdt_dt_ids),
+	.probe		= at91sam9x_wdt_probe,
+};
+
+static int __init at91sam9x_wdt_init(void)
+{
+	return platform_driver_register(&at91sam9x_wdt_driver);
+}
+device_initcall(at91sam9x_wdt_init);
-- 
2.27.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 10/28] ARM: at91: implement sama5d2 lowlevel init
  2020-07-01  5:23 [PATCH 00/28] ARM: at91: add sama5d2 first stage support Ahmad Fatoum
                   ` (8 preceding siblings ...)
  2020-07-01  5:23 ` [PATCH 09/28] watchdog: add support for at91sam9/sama5 watchdog Ahmad Fatoum
@ 2020-07-01  5:23 ` Ahmad Fatoum
  2020-07-01  5:23 ` [PATCH 11/28] ARM: at91: sama5d2: add sama5d2 matrix configuration Ahmad Fatoum
                   ` (17 subsequent siblings)
  27 siblings, 0 replies; 30+ messages in thread
From: Ahmad Fatoum @ 2020-07-01  5:23 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

Port over the low level initialization for sama5d2 SoCs from
at91bootstrap.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 .../arm/boards/sama5d27-giantboard/lowlevel.c |  9 +--
 arch/arm/boards/sama5d27-som1/lowlevel.c      |  9 +--
 arch/arm/mach-at91/Makefile                   |  1 +
 arch/arm/mach-at91/include/mach/at91_pmc.h    | 22 +++++
 arch/arm/mach-at91/include/mach/sama5d2_ll.h  | 27 +++++++
 arch/arm/mach-at91/sama5d2_ll.c               | 80 +++++++++++++++++++
 6 files changed, 132 insertions(+), 16 deletions(-)
 create mode 100644 arch/arm/mach-at91/include/mach/sama5d2_ll.h
 create mode 100644 arch/arm/mach-at91/sama5d2_ll.c

diff --git a/arch/arm/boards/sama5d27-giantboard/lowlevel.c b/arch/arm/boards/sama5d27-giantboard/lowlevel.c
index 50bc2613c652..e08217105bcc 100644
--- a/arch/arm/boards/sama5d27-giantboard/lowlevel.c
+++ b/arch/arm/boards/sama5d27-giantboard/lowlevel.c
@@ -8,9 +8,7 @@
 
 #include <asm/barebox-arm-head.h>
 #include <asm/barebox-arm.h>
-#include <mach/at91_pmc_ll.h>
-
-#include <mach/hardware.h>
+#include <mach/sama5d2_ll.h>
 #include <mach/iomux.h>
 #include <debug_ll.h>
 #include <mach/at91_dbgu.h>
@@ -18,11 +16,6 @@
 /* PCK = 492MHz, MCK = 164MHz */
 #define MASTER_CLOCK	164000000
 
-static inline void sama5d2_pmc_enable_periph_clock(int clk)
-{
-	at91_pmc_sam9x5_enable_periph_clock(SAMA5D2_BASE_PMC, clk);
-}
-
 static void dbgu_init(void)
 {
 	unsigned mck = MASTER_CLOCK / 2;
diff --git a/arch/arm/boards/sama5d27-som1/lowlevel.c b/arch/arm/boards/sama5d27-som1/lowlevel.c
index 569960be445d..2b39e5abc396 100644
--- a/arch/arm/boards/sama5d27-som1/lowlevel.c
+++ b/arch/arm/boards/sama5d27-som1/lowlevel.c
@@ -8,9 +8,7 @@
 
 #include <asm/barebox-arm-head.h>
 #include <asm/barebox-arm.h>
-#include <mach/at91_pmc_ll.h>
-
-#include <mach/hardware.h>
+#include <mach/sama5d2_ll.h>
 #include <mach/iomux.h>
 #include <debug_ll.h>
 #include <mach/at91_dbgu.h>
@@ -22,11 +20,6 @@
 /* PCK = 492MHz, MCK = 164MHz */
 #define MASTER_CLOCK	164000000
 
-static inline void sama5d2_pmc_enable_periph_clock(int clk)
-{
-	at91_pmc_sam9x5_enable_periph_clock(SAMA5D2_BASE_PMC, clk);
-}
-
 static void ek_turn_led(unsigned color)
 {
 	struct {
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
index a7e9ce5938e8..ea39d7d8c240 100644
--- a/arch/arm/mach-at91/Makefile
+++ b/arch/arm/mach-at91/Makefile
@@ -25,6 +25,7 @@ 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_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/include/mach/at91_pmc.h b/arch/arm/mach-at91/include/mach/at91_pmc.h
index 4d60becefbab..66b4e49286d7 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/sama5d2_ll.h b/arch/arm/mach-at91/include/mach/sama5d2_ll.h
new file mode 100644
index 000000000000..7c38a84f5395
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/sama5d2_ll.h
@@ -0,0 +1,27 @@
+#ifndef __MACH_SAMA5D2_LL__
+#define __MACH_SAMA5D2_LL__
+
+#include <mach/sama5d2.h>
+#include <mach/at91_pmc_ll.h>
+#include <mach/early_udelay.h>
+#include <mach/ddramc.h>
+
+#include <common.h>
+
+static inline void sama5d2_pmc_enable_periph_clock(int clk)
+{
+	at91_pmc_sam9x5_enable_periph_clock(SAMA5D2_BASE_PMC, clk);
+}
+
+void sama5d2_lowlevel_init(void);
+
+/* 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);
+
+#endif
diff --git a/arch/arm/mach-at91/sama5d2_ll.c b/arch/arm/mach-at91/sama5d2_ll.c
new file mode 100644
index 000000000000..a038bf4b86e6
--- /dev/null
+++ b/arch/arm/mach-at91/sama5d2_ll.c
@@ -0,0 +1,80 @@
+// 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/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 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_rstc_init();
+}
-- 
2.27.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 11/28] ARM: at91: sama5d2: add sama5d2 matrix configuration
  2020-07-01  5:23 [PATCH 00/28] ARM: at91: add sama5d2 first stage support Ahmad Fatoum
                   ` (9 preceding siblings ...)
  2020-07-01  5:23 ` [PATCH 10/28] ARM: at91: implement sama5d2 lowlevel init Ahmad Fatoum
@ 2020-07-01  5:23 ` Ahmad Fatoum
  2020-07-01  5:23 ` [PATCH 12/28] ARM: at91: add sama5d2 cache init Ahmad Fatoum
                   ` (16 subsequent siblings)
  27 siblings, 0 replies; 30+ messages in thread
From: Ahmad Fatoum @ 2020-07-01  5:23 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

Different peripherals, including the SDRAM, are unusable without prior
matrix configuration. Port over the necessary at91bootstrap parts for
sama5d2 use.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 arch/arm/mach-at91/Makefile                 |   2 +-
 arch/arm/mach-at91/include/mach/matrix.h    |  21 +++
 arch/arm/mach-at91/include/mach/tz_matrix.h |  95 +++++++++++++
 arch/arm/mach-at91/matrix.c                 |  45 +++++++
 arch/arm/mach-at91/sama5d2_ll.c             | 140 ++++++++++++++++++++
 5 files changed, 302 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/mach-at91/include/mach/matrix.h
 create mode 100644 arch/arm/mach-at91/include/mach/tz_matrix.h
 create mode 100644 arch/arm/mach-at91/matrix.c

diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
index ea39d7d8c240..6aaef7c531da 100644
--- a/arch/arm/mach-at91/Makefile
+++ b/arch/arm/mach-at91/Makefile
@@ -1,5 +1,5 @@
 obj-y += setup.o
-lwl-y += at91_pmc_ll.o ddramc_ll.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),)
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 000000000000..5dbfcfe41439
--- /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/tz_matrix.h b/arch/arm/mach-at91/include/mach/tz_matrix.h
new file mode 100644
index 000000000000..85589bfa65c8
--- /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/matrix.c b/arch/arm/mach-at91/matrix.c
new file mode 100644
index 000000000000..b2e7345ec1d5
--- /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_ll.c b/arch/arm/mach-at91/sama5d2_ll.c
index a038bf4b86e6..c3b50617778a 100644
--- a/arch/arm/mach-at91/sama5d2_ll.c
+++ b/arch/arm/mach-at91/sama5d2_ll.c
@@ -10,6 +10,8 @@
 #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>
 
@@ -66,6 +68,143 @@ static void sama5d2_pmc_init(void)
 			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,
@@ -76,5 +215,6 @@ void sama5d2_lowlevel_init(void)
 {
 	arm_cpu_lowlevel_init();
 	sama5d2_pmc_init();
+	sama5d2_matrix_init();
 	sama5d2_rstc_init();
 }
-- 
2.27.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 12/28] ARM: at91: add sama5d2 cache init
  2020-07-01  5:23 [PATCH 00/28] ARM: at91: add sama5d2 first stage support Ahmad Fatoum
                   ` (10 preceding siblings ...)
  2020-07-01  5:23 ` [PATCH 11/28] ARM: at91: sama5d2: add sama5d2 matrix configuration Ahmad Fatoum
@ 2020-07-01  5:23 ` Ahmad Fatoum
  2020-07-01  5:23 ` [PATCH 13/28] ARM: at91: add necessary Advanced Interrupt Controller configuration Ahmad Fatoum
                   ` (15 subsequent siblings)
  27 siblings, 0 replies; 30+ messages in thread
From: Ahmad Fatoum @ 2020-07-01  5:23 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

The L2 cache controller needs some initialization before use. Same goes
for the CAN SRAM, do so after the MMU setup.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 arch/arm/mach-at91/Makefile  |  1 +
 arch/arm/mach-at91/sama5d2.c | 52 ++++++++++++++++++++++++++++++++++++
 2 files changed, 53 insertions(+)
 create mode 100644 arch/arm/mach-at91/sama5d2.c

diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
index 6aaef7c531da..7c8399ee76f2 100644
--- a/arch/arm/mach-at91/Makefile
+++ b/arch/arm/mach-at91/Makefile
@@ -26,6 +26,7 @@ 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/sama5d2.c b/arch/arm/mach-at91/sama5d2.c
new file mode 100644
index 000000000000..2f74b0b38df1
--- /dev/null
+++ b/arch/arm/mach-at91/sama5d2.c
@@ -0,0 +1,52 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <common.h>
+#include <of.h>
+#include <init.h>
+#include <mach/sama5d2.h>
+#include <asm/cache-l2x0.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;
+
+	sama5d2_can_ram_init();
+	sama5d2_l2x0_init();
+
+	return 0;
+}
+postmmu_initcall(sama5d2_init);
-- 
2.27.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 13/28] ARM: at91: add necessary Advanced Interrupt Controller configuration
  2020-07-01  5:23 [PATCH 00/28] ARM: at91: add sama5d2 first stage support Ahmad Fatoum
                   ` (11 preceding siblings ...)
  2020-07-01  5:23 ` [PATCH 12/28] ARM: at91: add sama5d2 cache init Ahmad Fatoum
@ 2020-07-01  5:23 ` Ahmad Fatoum
  2020-07-01  5:23 ` [PATCH 14/28] ARM: at91: extend low level PMC driver for generic clk support Ahmad Fatoum
                   ` (14 subsequent siblings)
  27 siblings, 0 replies; 30+ messages in thread
From: Ahmad Fatoum @ 2020-07-01  5:23 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

Without reconfiguration of the AIC redirection, the OS interrupt
handling will misbehave later on. Add it to the SoC init.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 arch/arm/mach-at91/Makefile           |  2 +-
 arch/arm/mach-at91/aic.c              | 28 +++++++++++++++++++++++++++
 arch/arm/mach-at91/include/mach/aic.h |  9 +++++++++
 arch/arm/mach-at91/sama5d2.c          |  2 ++
 4 files changed, 40 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/mach-at91/aic.c
 create mode 100644 arch/arm/mach-at91/include/mach/aic.h

diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
index 7c8399ee76f2..254bbeef2773 100644
--- a/arch/arm/mach-at91/Makefile
+++ b/arch/arm/mach-at91/Makefile
@@ -1,4 +1,4 @@
-obj-y += setup.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
 
diff --git a/arch/arm/mach-at91/aic.c b/arch/arm/mach-at91/aic.c
new file mode 100644
index 000000000000..b40f1d214b28
--- /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/include/mach/aic.h b/arch/arm/mach-at91/include/mach/aic.h
new file mode 100644
index 000000000000..c1f026b60c62
--- /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/sama5d2.c b/arch/arm/mach-at91/sama5d2.c
index 2f74b0b38df1..c498b0964534 100644
--- a/arch/arm/mach-at91/sama5d2.c
+++ b/arch/arm/mach-at91/sama5d2.c
@@ -3,6 +3,7 @@
 #include <common.h>
 #include <of.h>
 #include <init.h>
+#include <mach/aic.h>
 #include <mach/sama5d2.h>
 #include <asm/cache-l2x0.h>
 #include <asm/mmu.h>
@@ -44,6 +45,7 @@ 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();
 
-- 
2.27.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 14/28] ARM: at91: extend low level PMC driver for generic clk support
  2020-07-01  5:23 [PATCH 00/28] ARM: at91: add sama5d2 first stage support Ahmad Fatoum
                   ` (12 preceding siblings ...)
  2020-07-01  5:23 ` [PATCH 13/28] ARM: at91: add necessary Advanced Interrupt Controller configuration Ahmad Fatoum
@ 2020-07-01  5:23 ` Ahmad Fatoum
  2020-07-01  5:23 ` [PATCH 15/28] pbl: add block I/O API Ahmad Fatoum
                   ` (13 subsequent siblings)
  27 siblings, 0 replies; 30+ messages in thread
From: Ahmad Fatoum @ 2020-07-01  5:23 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

The SAMA5D2 and SAM9X60 both feature generic clocks, which we already
support in barebox proper, but not in PBL. Add PBL support for setting
the parent and enabling them, so we may use it to enable the SDMMC
peripherals in first stage.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 arch/arm/mach-at91/at91_pmc_ll.c              | 169 ++++++++++++++++--
 arch/arm/mach-at91/include/mach/at91_pmc_ll.h |  21 ++-
 arch/arm/mach-at91/include/mach/sama5d2_ll.h  |  15 +-
 3 files changed, 187 insertions(+), 18 deletions(-)

diff --git a/arch/arm/mach-at91/at91_pmc_ll.c b/arch/arm/mach-at91/at91_pmc_ll.c
index 4d39f579091e..9205322db972 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/include/mach/at91_pmc_ll.h b/arch/arm/mach-at91/include/mach/at91_pmc_ll.h
index e3d3e3ad59db..6ec3ae0852c6 100644
--- a/arch/arm/mach-at91/include/mach/at91_pmc_ll.h
+++ b/arch/arm/mach-at91/include/mach/at91_pmc_ll.h
@@ -14,27 +14,38 @@
 #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)
+				 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_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);
diff --git a/arch/arm/mach-at91/include/mach/sama5d2_ll.h b/arch/arm/mach-at91/include/mach/sama5d2_ll.h
index 7c38a84f5395..e6fa3914250b 100644
--- a/arch/arm/mach-at91/include/mach/sama5d2_ll.h
+++ b/arch/arm/mach-at91/include/mach/sama5d2_ll.h
@@ -8,13 +8,13 @@
 
 #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);
 }
 
-void sama5d2_lowlevel_init(void);
-
 /* requires relocation */
 static inline void sama5d2_udelay_init(unsigned int msc)
 {
@@ -22,6 +22,17 @@ static inline void sama5d2_udelay_init(unsigned int msc)
 			  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);
+}
+
 #endif
-- 
2.27.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 15/28] pbl: add block I/O API
  2020-07-01  5:23 [PATCH 00/28] ARM: at91: add sama5d2 first stage support Ahmad Fatoum
                   ` (13 preceding siblings ...)
  2020-07-01  5:23 ` [PATCH 14/28] ARM: at91: extend low level PMC driver for generic clk support Ahmad Fatoum
@ 2020-07-01  5:23 ` Ahmad Fatoum
  2020-07-01  5:23 ` [PATCH 16/28] fs: fat: extend for in-PBL support Ahmad Fatoum
                   ` (12 subsequent siblings)
  27 siblings, 0 replies; 30+ messages in thread
From: Ahmad Fatoum @ 2020-07-01  5:23 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

We already have some PBL MCI implementations in barebox, but none
are used for chainloading a barebox from a file system.

There are some SoCs that would benefit from this however:
At least the Zynq, AT91, SoCFPGA and TI SoCs.

In preparation for supporting first stage boot on these where it's
customary for both the BootROM and first stage bootloader to load the
follow-up stage from FAT, add a very basic block I/O API that MCI
drivers can implement.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 include/pbl.h | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/include/pbl.h b/include/pbl.h
index f84ed3b7bfcf..83a058075dc6 100644
--- a/include/pbl.h
+++ b/include/pbl.h
@@ -6,6 +6,8 @@
 #ifndef __PBL_H__
 #define __PBL_H__
 
+#include <linux/types.h>
+
 extern unsigned long free_mem_ptr;
 extern unsigned long free_mem_end_ptr;
 
@@ -13,6 +15,18 @@ void pbl_barebox_uncompress(void *dest, void *compressed_start, unsigned int len
 
 #ifdef __PBL__
 #define IN_PBL	1
+
+struct pbl_bio {
+	void *priv;
+	int (*read)(struct pbl_bio *bio, off_t block_off, void *buf, unsigned nblocks);
+};
+
+static inline int pbl_bio_read(struct pbl_bio *bio, off_t block_off,
+			       void *buf, unsigned nblocks)
+{
+	return bio->read(bio, block_off, buf, nblocks);
+}
+
 #else
 #define IN_PBL	0
 #endif
-- 
2.27.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 16/28] fs: fat: extend for in-PBL support
  2020-07-01  5:23 [PATCH 00/28] ARM: at91: add sama5d2 first stage support Ahmad Fatoum
                   ` (14 preceding siblings ...)
  2020-07-01  5:23 ` [PATCH 15/28] pbl: add block I/O API Ahmad Fatoum
@ 2020-07-01  5:23 ` Ahmad Fatoum
  2020-07-01  5:23 ` [PATCH 17/28] mci: extend atmel-sdhci driver to first stage use Ahmad Fatoum
                   ` (11 subsequent siblings)
  27 siblings, 0 replies; 30+ messages in thread
From: Ahmad Fatoum @ 2020-07-01  5:23 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

The AT91 BootROM loads a boot.bin file from the first FAT partition
into SRAM, when booting from MMC. To avoid the need for two barebox
configurations for each of the bootloader stages, add PBL support
for reading from FAT. This way each stage need only have a different
PBL entry point.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 common/Makefile  |  3 +-
 fs/Makefile      |  2 +-
 fs/fat/Kconfig   |  7 ++++
 fs/fat/Makefile  |  4 ++-
 fs/fat/diskio.h  |  7 +++-
 fs/fat/fat-pbl.c | 53 ++++++++++++++++++++++++++++
 fs/fat/fat.c     | 31 -----------------
 fs/fat/ff.c      | 89 ++++++++++++++++++++++++------------------------
 fs/fat/ff.h      | 22 +++++++++---
 include/pbl.h    |  1 +
 lib/Makefile     |  2 +-
 11 files changed, 136 insertions(+), 85 deletions(-)
 create mode 100644 fs/fat/fat-pbl.c

diff --git a/common/Makefile b/common/Makefile
index 53859d8d14f6..ad5146a3011b 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -29,8 +29,9 @@ obj-pbl-$(CONFIG_DDR_SPD)	+= ddr_spd.o
 obj-$(CONFIG_ENV_HANDLING)	+= environment.o envfs-core.o
 obj-$(CONFIG_DEFAULT_ENVIRONMENT) += envfs-core.o
 obj-$(CONFIG_ENVIRONMENT_VARIABLES) += env.o
-obj-$(CONFIG_FILETYPE)		+= filetype.o
+obj-pbl-$(CONFIG_FILETYPE)	+= filetype.o
 CFLAGS_filetype.o = -I$(srctree)/arch/
+CFLAGS_filetype.pbl.o = -I$(srctree)/arch/
 obj-$(CONFIG_FLEXIBLE_BOOTARGS)	+= bootargs.o
 obj-$(CONFIG_GLOBALVAR)		+= globalvar.o
 obj-$(CONFIG_GREGORIAN_CALENDER) += date.o
diff --git a/fs/Makefile b/fs/Makefile
index f13dc97c3201..fa950941de92 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -4,7 +4,7 @@ obj-$(CONFIG_FS_RAMFS)	+= ramfs.o
 obj-y			+= devfs-core.o
 obj-$(CONFIG_FS_LEGACY) += legacy.o
 obj-$(CONFIG_FS_DEVFS)	+= devfs.o
-obj-$(CONFIG_FS_FAT)	+= fat/
+obj-pbl-$(CONFIG_FS_FAT)	+= fat/
 obj-y	+= fs.o libfs.o
 obj-$(CONFIG_FS_JFFS2)	+= jffs2/
 obj-$(CONFIG_FS_UBIFS)	+= ubifs/
diff --git a/fs/fat/Kconfig b/fs/fat/Kconfig
index b1def851cfb8..bc3b4b69e870 100644
--- a/fs/fat/Kconfig
+++ b/fs/fat/Kconfig
@@ -8,9 +8,16 @@ if FS_FAT
 config FS_FAT_WRITE
 	bool
 	prompt "FAT write support"
+	help
+	  Enable support for writing in FAT partitions.
+	  Note: This doesn't apply to FAT usage in barebox PBL.
+
 
 config FS_FAT_LFN
 	bool
 	prompt "Support long filenames"
+	help
+	  Enable support for file names other than 8.3.
+	  Note: This doesn't apply to FAT usage in barebox PBL.
 
 endif
diff --git a/fs/fat/Makefile b/fs/fat/Makefile
index efc89ec67db8..fe47569bda09 100644
--- a/fs/fat/Makefile
+++ b/fs/fat/Makefile
@@ -1 +1,3 @@
-obj-y += ff.o fat.o
+obj-y += fat.o
+pbl-y += fat-pbl.o
+obj-pbl-y += ff.o fat-diskio.o
diff --git a/fs/fat/diskio.h b/fs/fat/diskio.h
index f0d29dc390d5..aee1ce2b0b3b 100644
--- a/fs/fat/diskio.h
+++ b/fs/fat/diskio.h
@@ -4,7 +4,12 @@
 
 #ifndef _DISKIO
 
-#define _READONLY	0	/* 1: Remove write functions */
+#ifdef __PBL__
+#define _READONLY	1	/* 1: Remove write functions */
+#else
+#define _READONLY	0
+#endif
+
 #define _USE_IOCTL	1	/* 1: Use disk_ioctl fucntion */
 
 #include "integer.h"
diff --git a/fs/fat/fat-pbl.c b/fs/fat/fat-pbl.c
new file mode 100644
index 000000000000..93cd6decbcb0
--- /dev/null
+++ b/fs/fat/fat-pbl.c
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * fat-pbl.c - PBL FAT filesystem barebox driver
+ *
+ * Copyright (c) 2019 Ahmad Fatoum, Pengutronix
+ */
+
+#define pr_fmt(fmt) "fat-pbl: " fmt
+
+#include <common.h>
+#include "integer.h"
+#include "ff.h"
+#include "diskio.h"
+#include "pbl.h"
+
+DRESULT disk_read(FATFS *fat, BYTE *buf, DWORD sector, BYTE count)
+{
+	int ret = pbl_bio_read(fat->userdata, sector, buf, count);
+	return ret != count ? ret : 0;
+}
+
+ssize_t pbl_fat_load(struct pbl_bio *bio, const char *filename, void *dest, size_t len)
+{
+	FATFS	fs = {};
+	FIL	file = {};
+	UINT	nread;
+	int	ret;
+
+	fs.userdata = bio;
+
+	/* mount fs */
+	ret = f_mount(&fs);
+	if (ret) {
+		pr_debug("f_mount(%s) failed: %d\n", filename, ret);
+		return ret;
+	}
+
+	ret = f_open(&fs, &file, filename, FA_OPEN_EXISTING | FA_READ);
+	if (ret) {
+		pr_debug("f_open(%s) failed: %d\n", filename, ret);
+		return ret;
+	}
+
+	pr_debug("Reading file %s to 0x%p\n", filename, dest);
+
+	ret = f_read(&file, dest, len, &nread);
+	if (ret) {
+		pr_debug("f_read failed: %d\n", ret);
+		return ret;
+	}
+
+	return f_size(&file) <= len ? nread : -ENOSPC;
+}
diff --git a/fs/fat/fat.c b/fs/fat/fat.c
index c2da0ade4aac..84bfe69089e5 100644
--- a/fs/fat/fat.c
+++ b/fs/fat/fat.c
@@ -65,37 +65,6 @@ DRESULT disk_write(FATFS *fat, const BYTE *buf, DWORD sector, BYTE count)
 	return 0;
 }
 
-DSTATUS disk_status(FATFS *fat)
-{
-	return 0;
-}
-
-DWORD get_fattime(void)
-{
-	return 0;
-}
-
-DRESULT disk_ioctl (FATFS *fat, BYTE command, void *buf)
-{
-	return 0;
-}
-
-WCHAR ff_convert(WCHAR src, UINT dir)
-{
-	if (src <= 0x80)
-		return src;
-	else
-		return '?';
-}
-
-WCHAR ff_wtoupper(WCHAR chr)
-{
-	if (chr <= 0x80)
-		return toupper(chr);
-	else
-		return '?';
-}
-
 /* ---------------------------------------------------------------*/
 
 #ifdef CONFIG_FS_FAT_WRITE
diff --git a/fs/fat/ff.c b/fs/fat/ff.c
index 4d30433e5f03..c8d57ce50054 100644
--- a/fs/fat/ff.c
+++ b/fs/fat/ff.c
@@ -96,6 +96,7 @@
 #include <filetype.h>
 #include "ff.h"			/* FatFs configurations and declarations */
 #include "diskio.h"		/* Declarations of low level disk I/O functions */
+#include <pbl.h>
 
 #if _FATFS != 8237
 #error Wrong include file (ff.h).
@@ -214,7 +215,7 @@
 #define	DDE			0xE5	/* Deleted directory enrty mark in DIR_Name[0] */
 #define	NDDE			0x05	/* Replacement of a character collides with DDE */
 
-#ifndef CONFIG_FS_FAT_LFN
+#ifndef FS_FAT_LFN
 #define	DEF_NAMEBUF		BYTE sfn[12]
 #define INIT_BUF(dobj)		(dobj).fn = sfn
 #define	FREE_BUF()
@@ -250,7 +251,7 @@ int move_window (
 
 	wsect = fs->winsect;
 	if (wsect != sector) {	/* Changed current window */
-#ifdef CONFIG_FS_FAT_WRITE
+#ifdef FS_FAT_WRITE
 		if (fs->wflag) {	/* Write back dirty window if needed */
 			if (disk_write(fs, fs->win, wsect, 1) != RES_OK)
 				return -EIO;
@@ -277,7 +278,7 @@ int move_window (
 /*
  * Clean-up cached data
  */
-#ifdef CONFIG_FS_FAT_WRITE
+#ifdef FS_FAT_WRITE
 static
 int sync (	/* 0: successful, -EIO: failed */
 	FATFS *fs	/* File system object */
@@ -372,7 +373,7 @@ static DWORD get_fat (	/* 0xFFFFFFFF:Disk error, 1:Internal error, Else:Cluster
 /*
  * FAT access - Change value of a FAT entry
  */
-#ifdef CONFIG_FS_FAT_WRITE
+#ifdef FS_FAT_WRITE
 
 static int put_fat (
 	FATFS *fs,	/* File system object */
@@ -431,7 +432,7 @@ static int put_fat (
 
 	return res;
 }
-#endif /* CONFIG_FS_FAT_WRITE */
+#endif /* FS_FAT_WRITE */
 
 
 
@@ -439,7 +440,7 @@ static int put_fat (
 /*
  * FAT handling - Remove a cluster chain
  */
-#ifdef CONFIG_FS_FAT_WRITE
+#ifdef FS_FAT_WRITE
 static
 int remove_chain (
 	FATFS *fs,			/* File system object */
@@ -506,7 +507,7 @@ int remove_chain (
 /*
  * FAT handling - Stretch or Create a cluster chain
  */
-#ifdef CONFIG_FS_FAT_WRITE
+#ifdef FS_FAT_WRITE
 static
 DWORD create_chain (	/* 0:No free cluster, 1:Internal error, 0xFFFFFFFF:Disk error, >=2:New cluster# */
 	FATFS *fs,	/* File system object */
@@ -566,7 +567,7 @@ DWORD create_chain (	/* 0:No free cluster, 1:Internal error, 0xFFFFFFFF:Disk err
 
 	return ncl; /* Return new cluster number or error code */
 }
-#endif /* CONFIG_FS_FAT_WRITE */
+#endif /* FS_FAT_WRITE */
 
 /*
  * Directory handling - Set directory index
@@ -657,7 +658,7 @@ static int dir_next (	/* 0:Succeeded, FR_NO_FILE:End of table, FR_DENIED:EOT and
 					return -EIO;
 
 				if (clst >= dj->fs->n_fatent) {	/* When it reached end of dynamic table */
-#ifdef CONFIG_FS_FAT_WRITE
+#ifdef FS_FAT_WRITE
 					BYTE c;
 
 					if (!stretch)
@@ -708,7 +709,7 @@ static int dir_next (	/* 0:Succeeded, FR_NO_FILE:End of table, FR_DENIED:EOT and
 /*
  * LFN handling - Test/Pick/Fit an LFN segment from/to directory entry
  */
-#ifdef CONFIG_FS_FAT_LFN
+#ifdef FS_FAT_LFN
 
 /* Offset of LFN chars in the directory entry */
 static const BYTE LfnOfs[] = {1,3,5,7,9,14,16,18,20,22,24,28,30};
@@ -784,7 +785,7 @@ int pick_lfn (		/* 1:Succeeded, 0:Buffer overflow */
 }
 
 
-#ifdef CONFIG_FS_FAT_WRITE
+#ifdef FS_FAT_WRITE
 static
 void fit_lfn (
 	const WCHAR *lfnbuf,	/* Pointer to the LFN buffer */
@@ -824,7 +825,7 @@ void fit_lfn (
 /*
  * Create numbered name
  */
-#if defined(CONFIG_FS_FAT_LFN) && defined(CONFIG_FS_FAT_WRITE)
+#if defined(FS_FAT_LFN) && defined(FS_FAT_WRITE)
 static void gen_numname (
 	BYTE *dst,		/* Pointer to generated SFN */
 	const BYTE *src,	/* Pointer to source SFN to be modified */
@@ -874,7 +875,7 @@ static void gen_numname (
 /*
  * Calculate sum of an SFN
  */
-#ifdef CONFIG_FS_FAT_LFN
+#ifdef FS_FAT_LFN
 static BYTE sum_sfn (
 	const BYTE *dir		/* Ptr to directory entry */
 )
@@ -897,7 +898,7 @@ static int dir_find (
 {
 	int res;
 	BYTE c, *dir;
-#ifdef CONFIG_FS_FAT_LFN
+#ifdef FS_FAT_LFN
 	BYTE a, ord, sum;
 #endif
 
@@ -905,7 +906,7 @@ static int dir_find (
 	if (res != 0)
 		return res;
 
-#ifdef CONFIG_FS_FAT_LFN
+#ifdef FS_FAT_LFN
 	ord = sum = 0xFF;
 #endif
 	do {
@@ -919,7 +920,7 @@ static int dir_find (
 			res = -ENOENT;
 			break;
 		}
-#ifdef CONFIG_FS_FAT_LFN	/* LFN configuration */
+#ifdef FS_FAT_LFN	/* LFN configuration */
 		a = dir[DIR_Attr] & AM_MASK;
 		if (c == DDE || ((a & AM_VOL) && a != AM_LFN)) {
 			/* An entry without valid data */
@@ -970,7 +971,7 @@ static int dir_read (
 {
 	int res;
 	BYTE c, *dir;
-#ifdef CONFIG_FS_FAT_LFN
+#ifdef FS_FAT_LFN
 	BYTE a, ord = 0xFF, sum = 0xFF;
 #endif
 
@@ -986,7 +987,7 @@ static int dir_read (
 			res = -ENOENT;
 			break;
 		}
-#ifdef CONFIG_FS_FAT_LFN	/* LFN configuration */
+#ifdef FS_FAT_LFN	/* LFN configuration */
 		a = dir[DIR_Attr] & AM_MASK;
 		if (c == DDE || c == '.' || ((a & AM_VOL) && a != AM_LFN)) {	/* An entry without valid data */
 			ord = 0xFF;
@@ -1025,7 +1026,7 @@ static int dir_read (
 /*
  * Register an object to the directory
  */
-#ifdef CONFIG_FS_FAT_WRITE
+#ifdef FS_FAT_WRITE
 static
 int dir_register (	/* 0:Successful, FR_DENIED:No free entry or too many SFN collision, -EIO:Disk error */
 	FF_DIR *dj	/* Target directory with object name to be created */
@@ -1033,7 +1034,7 @@ int dir_register (	/* 0:Successful, FR_DENIED:No free entry or too many SFN coll
 {
 	int res;
 	BYTE c, *dir;
-#ifdef CONFIG_FS_FAT_LFN	/* LFN configuration */
+#ifdef FS_FAT_LFN	/* LFN configuration */
 	WORD n, ne, is;
 	BYTE sn[12], *fn, sum;
 	WCHAR *lfn;
@@ -1127,7 +1128,7 @@ int dir_register (	/* 0:Successful, FR_DENIED:No free entry or too many SFN coll
 			dir = dj->dir;
 			memset(dir, 0, SZ_DIR);	/* Clean the entry */
 			memcpy(dir, dj->fn, 11);	/* Put SFN */
-#ifdef CONFIG_FS_FAT_LFN
+#ifdef FS_FAT_LFN
 			dir[DIR_NTres] = *(dj->fn+NS) & (NS_BODY | NS_EXT);	/* Put NT flag */
 #endif
 			dj->fs->wflag = 1;
@@ -1136,18 +1137,18 @@ int dir_register (	/* 0:Successful, FR_DENIED:No free entry or too many SFN coll
 
 	return res;
 }
-#endif /* CONFIG_FS_FAT_WRITE */
+#endif /* FS_FAT_WRITE */
 
 /*
  * Remove an object from the directory
  */
-#if defined CONFIG_FS_FAT_WRITE
+#if defined FS_FAT_WRITE
 static int dir_remove (	/* 0: Successful, -EIO: A disk error */
 	FF_DIR *dj				/* Directory object pointing the entry to be removed */
 )
 {
 	int res;
-#ifdef CONFIG_FS_FAT_LFN	/* LFN configuration */
+#ifdef FS_FAT_LFN	/* LFN configuration */
 	WORD i;
 
 	i = dj->index;	/* SFN index */
@@ -1181,7 +1182,7 @@ static int dir_remove (	/* 0: Successful, -EIO: A disk error */
 
 	return res;
 }
-#endif /* CONFIG_FS_FAT_WRITE */
+#endif /* FS_FAT_WRITE */
 
 /*
  * Pick a segment and create the object name in directory form
@@ -1195,7 +1196,7 @@ static int create_name (
 	static const BYTE excvt[] = _EXCVT;	/* Upper conversion table for extended chars */
 #endif
 
-#ifdef CONFIG_FS_FAT_LFN	/* LFN configuration */
+#ifdef FS_FAT_LFN	/* LFN configuration */
 	BYTE b, cf;
 	WCHAR w, *lfn;
 	UINT i, ni, si, di;
@@ -1410,7 +1411,7 @@ static void get_fileinfo (		/* No return code */
 				break;
 			if (c == NDDE)
 				c = (TCHAR)DDE;
-#ifdef CONFIG_FS_FAT_LFN
+#ifdef FS_FAT_LFN
 			if ((nt & NS_BODY) && isupper(c))
 				c += 0x20;
 #endif
@@ -1428,7 +1429,7 @@ static void get_fileinfo (		/* No return code */
 				c = dir[i];
 				if (c == ' ')
 					break;
-#ifdef CONFIG_FS_FAT_LFN
+#ifdef FS_FAT_LFN
 				if ((nt & NS_EXT) && isupper(c))
 					c += 0x20;
 #endif
@@ -1449,7 +1450,7 @@ static void get_fileinfo (		/* No return code */
 	}
 	*p = 0;		/* Terminate SFN str by a \0 */
 
-#ifdef CONFIG_FS_FAT_LFN
+#ifdef FS_FAT_LFN
 	if (fno->lfname && fno->lfsize) {
 		TCHAR *tp = fno->lfname;
 		WCHAR w, *lfn;
@@ -1668,7 +1669,7 @@ static int chk_mounted (	/* 0(0): successful, !=0: any error occurred */
 	if (fs->fsize < (szbfat + (SS(fs) - 1)) / SS(fs))
 		return -EINVAL;
 
-#ifdef CONFIG_FS_FAT_WRITE
+#ifdef FS_FAT_WRITE
 	/* Initialize cluster allocation information */
 	fs->free_clust = 0xFFFFFFFF;
 	fs->last_clust = 0;
@@ -1723,7 +1724,7 @@ int f_open (
 
 	fp->fs = NULL;		/* Clear file object */
 
-#ifdef CONFIG_FS_FAT_WRITE
+#ifdef FS_FAT_WRITE
 	mode &= FA_READ | FA_WRITE | FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW;
 	dj.fs = fatfs;
 #else
@@ -1735,7 +1736,7 @@ int f_open (
 		res = follow_path(&dj, path);	/* Follow the file path */
 	dir = dj.dir;
 
-#ifdef CONFIG_FS_FAT_WRITE	/* R/W configuration */
+#ifdef FS_FAT_WRITE	/* R/W configuration */
 	if (res == 0) {
 		if (!dir)	/* Current dir itself */
 			res = -EISDIR;
@@ -1870,7 +1871,7 @@ int f_read (
 					cc = fp->fs->csize - csect;
 				if (disk_read(fp->fs, rbuff, sect, (BYTE)cc) != RES_OK)
 					ABORT(fp->fs, -EIO);
-#if defined CONFIG_FS_FAT_WRITE
+#if defined FS_FAT_WRITE
 				/* Replace one of the read sectors with cached data if it contains a dirty sector */
 				if ((fp->flag & FA__DIRTY) && fp->dsect - sect < cc)
 					memcpy(rbuff + ((fp->dsect - sect) * SS(fp->fs)), fp->buf, SS(fp->fs));
@@ -1879,7 +1880,7 @@ int f_read (
 				continue;
 			}
 			if (fp->dsect != sect) {	/* Load data sector if not in cache */
-#ifdef CONFIG_FS_FAT_WRITE
+#ifdef FS_FAT_WRITE
 				if (fp->flag & FA__DIRTY) {	/* Write-back dirty sector cache */
 					if (disk_write(fp->fs, fp->buf, fp->dsect, 1) != RES_OK)
 						ABORT(fp->fs, -EIO);
@@ -1903,7 +1904,7 @@ int f_read (
 
 
 
-#ifdef CONFIG_FS_FAT_WRITE
+#ifdef FS_FAT_WRITE
 /*
  * Write File
  */
@@ -2044,7 +2045,7 @@ int f_sync (
 	return res;
 }
 
-#endif /* CONFIG_FS_FAT_WRITE */
+#endif /* FS_FAT_WRITE */
 
 /*
  * Close File
@@ -2053,7 +2054,7 @@ int f_close (
 	FIL *fp		/* Pointer to the file object to be closed */
 )
 {
-#ifndef CONFIG_FS_FAT_WRITE
+#ifndef FS_FAT_WRITE
 	fp->fs = 0;	/* Discard file object */
 	return 0;
 #else
@@ -2082,7 +2083,7 @@ int f_lseek (
 		return -ERESTARTSYS;
 
 	if (ofs > fp->fsize	/* In read-only mode, clip offset with the file size */
-#ifdef CONFIG_FS_FAT_WRITE
+#ifdef FS_FAT_WRITE
 		 && !(fp->flag & FA_WRITE)
 #endif
 		) ofs = fp->fsize;
@@ -2098,7 +2099,7 @@ int f_lseek (
 			clst = fp->clust;
 		} else {					/* When seek to back cluster, */
 			clst = fp->sclust;			/* start from the first cluster */
-#ifdef CONFIG_FS_FAT_WRITE
+#ifdef FS_FAT_WRITE
 			if (clst == 0) {			/* If no cluster chain, create a new chain */
 				clst = create_chain(fp->fs, 0);
 				if (clst == 1)
@@ -2112,7 +2113,7 @@ int f_lseek (
 		}
 		if (clst != 0) {
 			while (ofs > bcs) {	/* Cluster following loop */
-#ifdef CONFIG_FS_FAT_WRITE
+#ifdef FS_FAT_WRITE
 				if (fp->flag & FA_WRITE) {	/* Check if in write mode or not */
 					/* Force stretch if in write mode */
 					clst = create_chain(fp->fs, clst);
@@ -2143,7 +2144,7 @@ int f_lseek (
 		}
 	}
 	if (fp->fptr % SS(fp->fs) && nsect != fp->dsect) {	/* Fill sector cache if needed */
-#ifdef CONFIG_FS_FAT_WRITE
+#ifdef FS_FAT_WRITE
 		if (fp->flag & FA__DIRTY) {	/* Write-back dirty sector cache */
 			if (disk_write(fp->fs, fp->buf, fp->dsect, 1) != RES_OK)
 				ABORT(fp->fs, -EIO);
@@ -2154,7 +2155,7 @@ int f_lseek (
 			ABORT(fp->fs, -EIO);
 		fp->dsect = nsect;
 	}
-#ifdef CONFIG_FS_FAT_WRITE
+#ifdef FS_FAT_WRITE
 	if (fp->fptr > fp->fsize) {	/* Set file change flag if the file size is extended */
 		fp->fsize = fp->fptr;
 		fp->flag |= FA__WRITTEN;
@@ -2269,7 +2270,7 @@ int f_stat (
 	return res;
 }
 
-#ifdef CONFIG_FS_FAT_WRITE
+#ifdef FS_FAT_WRITE
 /*
  * Get Number of Free Clusters
  */
@@ -2706,4 +2707,4 @@ out:
 
 	return res;
 }
-#endif /* CONFIG_FS_FAT_WRITE */
+#endif /* FS_FAT_WRITE */
diff --git a/fs/fat/ff.h b/fs/fat/ff.h
index e86ca3aae063..c961de46e1f4 100644
--- a/fs/fat/ff.h
+++ b/fs/fat/ff.h
@@ -17,6 +17,18 @@
 #ifndef _FATFS
 #define _FATFS	8237	/* Revision ID */
 
+#ifndef __PBL__
+
+#ifdef CONFIG_FS_FAT_LFN
+#define FS_FAT_LFN 1
+#endif
+
+#ifdef CONFIG_FS_FAT_WRITE
+#define FS_FAT_WRITE 1
+#endif
+
+#endif
+
 #include <asm/unaligned.h>
 #include <linux/list.h>
 
@@ -30,7 +42,7 @@
 /* Type of path name strings on FatFs API */
 
 #if _LFN_UNICODE			/* Unicode string */
-#ifndef CONFIG_FS_FAT_LFN
+#ifndef FS_FAT_LFN
 #error _LFN_UNICODE must be 0 in non-LFN cfg.
 #endif
 #ifndef _INC_TCHAR
@@ -63,7 +75,7 @@ typedef struct {
 #if _MAX_SS != 512
 	WORD	ssize;		/* Bytes per sector (512,1024,2048,4096) */
 #endif
-#ifdef CONFIG_FS_FAT_WRITE
+#ifdef FS_FAT_WRITE
 	DWORD	last_clust;	/* Last allocated cluster */
 	DWORD	free_clust;	/* Number of free clusters */
 	DWORD	fsi_sector;	/* fsinfo sector (FAT32) */
@@ -92,7 +104,7 @@ typedef struct {
 	DWORD	sclust;		/* File start cluster (0 when fsize==0) */
 	DWORD	clust;		/* Current cluster */
 	DWORD	dsect;		/* Current data sector */
-#ifdef CONFIG_FS_FAT_WRITE
+#ifdef FS_FAT_WRITE
 	DWORD	dir_sect;	/* Sector containing the directory entry */
 	BYTE*	dir_ptr;	/* Ponter to the directory entry in the window */
 #endif
@@ -119,7 +131,7 @@ typedef struct {
 	DWORD	sect;			/* Current sector */
 	BYTE*	dir;			/* Pointer to the current SFN entry in the win[] */
 	BYTE*	fn;			/* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */
-#ifdef CONFIG_FS_FAT_LFN
+#ifdef FS_FAT_LFN
 	WCHAR*	lfn;			/* Pointer to the LFN working buffer */
 	WORD	lfn_idx;		/* Last matched LFN index number (0xFFFF:No LFN) */
 #endif
@@ -135,7 +147,7 @@ typedef struct {
 	WORD	ftime;			/* Last modified time */
 	BYTE	fattrib;		/* Attribute */
 	TCHAR	fname[13];		/* Short file name (8.3 format) */
-#ifdef CONFIG_FS_FAT_LFN
+#ifdef FS_FAT_LFN
 	TCHAR*	lfname;			/* Pointer to the LFN buffer */
 	UINT 	lfsize;			/* Size of LFN buffer in TCHAR */
 #endif
diff --git a/include/pbl.h b/include/pbl.h
index 83a058075dc6..5e971f865675 100644
--- a/include/pbl.h
+++ b/include/pbl.h
@@ -27,6 +27,7 @@ static inline int pbl_bio_read(struct pbl_bio *bio, off_t block_off,
 	return bio->read(bio, block_off, buf, nblocks);
 }
 
+ssize_t pbl_fat_load(struct pbl_bio *, const char *filename, void *dest, size_t len);
 #else
 #define IN_PBL	0
 #endif
diff --git a/lib/Makefile b/lib/Makefile
index f370d167b708..73399a1bf1b3 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -1,6 +1,6 @@
 obj-y			+= bcd.o
 obj-$(CONFIG_BOOTSTRAP)	+= bootstrap/
-obj-y			+= ctype.o
+obj-pbl-y		+= ctype.o
 obj-y			+= rbtree.o
 obj-y			+= display_options.o
 obj-y			+= string.o
-- 
2.27.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 17/28] mci: extend atmel-sdhci driver to first stage use
  2020-07-01  5:23 [PATCH 00/28] ARM: at91: add sama5d2 first stage support Ahmad Fatoum
                   ` (15 preceding siblings ...)
  2020-07-01  5:23 ` [PATCH 16/28] fs: fat: extend for in-PBL support Ahmad Fatoum
@ 2020-07-01  5:23 ` Ahmad Fatoum
  2020-07-01  5:23 ` [PATCH 18/28] ARM: at91: add code for sama5 boot source detection Ahmad Fatoum
                   ` (10 subsequent siblings)
  27 siblings, 0 replies; 30+ messages in thread
From: Ahmad Fatoum @ 2020-07-01  5:23 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

The BootROM resets both the SD/MMC host controller and the pin controller,
but the card itself remains in transfer mode. If we redo host-side
setup, we can directly read new blocks off the card.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 drivers/mci/Kconfig              |   4 +
 drivers/mci/Makefile             |   1 +
 drivers/mci/atmel-sdhci-common.c |   3 +
 drivers/mci/atmel-sdhci-pbl.c    | 128 +++++++++++++++++++++++++++++++
 4 files changed, 136 insertions(+)
 create mode 100644 drivers/mci/atmel-sdhci-pbl.c

diff --git a/drivers/mci/Kconfig b/drivers/mci/Kconfig
index 6ae1e812528c..3026b25cadc9 100644
--- a/drivers/mci/Kconfig
+++ b/drivers/mci/Kconfig
@@ -187,3 +187,7 @@ endif
 config MCI_IMX_ESDHC_PBL
 	bool
 	select MCI_SDHCI
+
+config MCI_ATMEL_SDHCI_PBL
+	bool
+	select MCI_SDHCI
diff --git a/drivers/mci/Makefile b/drivers/mci/Makefile
index 177483dcfba5..4a5363367476 100644
--- a/drivers/mci/Makefile
+++ b/drivers/mci/Makefile
@@ -5,6 +5,7 @@ obj-$(CONFIG_MCI_ATMEL_SDHCI)	+= atmel-sdhci.o atmel-sdhci-common.o
 obj-$(CONFIG_MCI_BCM283X)	+= mci-bcm2835.o
 obj-$(CONFIG_MCI_BCM283X_SDHOST)	+= bcm2835-sdhost.o
 obj-$(CONFIG_MCI_DOVE)		+= dove-sdhci.o
+pbl-$(CONFIG_MCI_ATMEL_SDHCI_PBL)	+= atmel-sdhci-pbl.o atmel-sdhci-common.o
 obj-$(CONFIG_MCI_IMX)		+= imx.o
 obj-$(CONFIG_MCI_IMX_ESDHC)	+= imx-esdhc.o imx-esdhc-common.o
 pbl-$(CONFIG_MCI_IMX_ESDHC_PBL)	+= imx-esdhc-pbl.o imx-esdhc-common.o
diff --git a/drivers/mci/atmel-sdhci-common.c b/drivers/mci/atmel-sdhci-common.c
index 1884f3836337..a83610c3d090 100644
--- a/drivers/mci/atmel-sdhci-common.c
+++ b/drivers/mci/atmel-sdhci-common.c
@@ -12,7 +12,10 @@
 #include <common.h>
 #include <mci.h>
 
+#include <mach/early_udelay.h>
+
 #ifdef __PBL__
+#define udelay early_udelay
 #undef  dev_err
 #define dev_err(d, ...)		pr_err(__VA_ARGS__)
 #undef  dev_warn
diff --git a/drivers/mci/atmel-sdhci-pbl.c b/drivers/mci/atmel-sdhci-pbl.c
new file mode 100644
index 000000000000..626e4008fe85
--- /dev/null
+++ b/drivers/mci/atmel-sdhci-pbl.c
@@ -0,0 +1,128 @@
+// SPDX-License-Identifier: BSD-1-Clause
+/*
+ * Copyright (c) 2015, Atmel Corporation
+ * Copyright (c) 2019, Ahmad Fatoum, Pengutronix
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ */
+
+#include <common.h>
+#include <pbl.h>
+#include <mci.h>
+#include <debug_ll.h>
+#include <mach/xload.h>
+#include "atmel-sdhci.h"
+
+#include <mach/early_udelay.h>
+
+#ifdef __PBL__
+#define udelay early_udelay
+#endif
+
+#define SECTOR_SIZE			512
+#define SUPPORT_MAX_BLOCKS		16U
+
+struct at91_sdhci_priv {
+	struct at91_sdhci host;
+	bool highcapacity_card;
+};
+
+static int sd_cmd_stop_transmission(struct at91_sdhci_priv *priv)
+{
+	struct mci_cmd cmd = {
+		.cmdidx = MMC_CMD_STOP_TRANSMISSION,
+		.resp_type = MMC_RSP_R1b,
+	};
+
+	return at91_sdhci_send_command(&priv->host, &cmd, NULL);
+}
+
+static int sd_cmd_read_multiple_block(struct at91_sdhci_priv *priv,
+				      void *buf,
+				      unsigned int start,
+				      unsigned int block_count)
+{
+	u16 block_len = SECTOR_SIZE;
+	struct mci_data data;
+	struct mci_cmd cmd = {
+		.cmdidx = MMC_CMD_READ_MULTIPLE_BLOCK,
+		.resp_type = MMC_RSP_R1,
+		.cmdarg = start,
+	};
+
+	if (!priv->highcapacity_card)
+		cmd.cmdarg *= block_len;
+
+	data.dest = buf;
+	data.flags = MMC_DATA_READ;
+	data.blocksize = block_len;
+	data.blocks = block_count;
+
+	return at91_sdhci_send_command(&priv->host, &cmd, &data);
+}
+
+static int at91_sdhci_bio_read(struct pbl_bio *bio, off_t start,
+				void *buf, unsigned int nblocks)
+{
+	struct at91_sdhci_priv *priv = bio->priv;
+	unsigned int blocks_done = 0;
+	unsigned int blocks;
+	unsigned int block_len = SECTOR_SIZE;
+	unsigned int blocks_read;
+	int ret;
+
+	/*
+	 * Refer to the at91sam9g20 datasheet:
+	 * Figure 35-10. Read Function Flow Diagram
+	*/
+
+	while (blocks_done < nblocks) {
+		blocks = min(nblocks - blocks_done, SUPPORT_MAX_BLOCKS);
+
+		blocks_read = sd_cmd_read_multiple_block(priv, buf,
+							 start + blocks_done,
+							 blocks);
+
+		ret = sd_cmd_stop_transmission(priv);
+		if (ret)
+			return ret;
+
+		blocks_done += blocks_read;
+
+		if (blocks_read != blocks)
+			break;
+
+		buf += blocks * block_len;
+	}
+
+	return blocks_done;
+}
+
+static struct at91_sdhci_priv atmel_sdcard;
+
+int at91_sdhci_bio_init(struct pbl_bio *bio, void __iomem *base)
+{
+	struct at91_sdhci_priv *priv = &atmel_sdcard;
+	struct at91_sdhci *host = &priv->host;
+	struct mci_ios ios = { .bus_width = MMC_BUS_WIDTH_1, .clock = 25000000 };
+	int ret;
+
+	bio->priv = priv;
+	bio->read = at91_sdhci_bio_read;
+
+	at91_sdhci_mmio_init(host, base);
+
+	sdhci_reset(&host->sdhci, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
+
+	ret = at91_sdhci_init(host, 240000000, true, true);
+	if (ret)
+		return ret;
+
+	ret = at91_sdhci_set_ios(host, &ios);
+
+	 // FIXME can we determine this without leaving SD transfer mode?
+	priv->highcapacity_card = 1;
+
+	return 0;
+}
-- 
2.27.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 18/28] ARM: at91: add code for sama5 boot source detection
  2020-07-01  5:23 [PATCH 00/28] ARM: at91: add sama5d2 first stage support Ahmad Fatoum
                   ` (16 preceding siblings ...)
  2020-07-01  5:23 ` [PATCH 17/28] mci: extend atmel-sdhci driver to first stage use Ahmad Fatoum
@ 2020-07-01  5:23 ` Ahmad Fatoum
  2020-07-01  5:23 ` [PATCH 19/28] ARM: at91: add helpers for chain-loading barebox from SD-card Ahmad Fatoum
                   ` (9 subsequent siblings)
  27 siblings, 0 replies; 30+ messages in thread
From: Ahmad Fatoum @ 2020-07-01  5:23 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

SAMA5 BootROM passes information about the boot source in the r4
register. Add functions to parse these. To make use of this, entry point
must back up the r4 register, because otherwise it's clobbered by local
variable use.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 .../mach-at91/include/mach/sama5_bootsource.h | 46 +++++++++++++++++++
 1 file changed, 46 insertions(+)
 create mode 100644 arch/arm/mach-at91/include/mach/sama5_bootsource.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 000000000000..29354dcaf34d
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/sama5_bootsource.h
@@ -0,0 +1,46 @@
+/* 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);
+}
+
+#endif
-- 
2.27.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 19/28] ARM: at91: add helpers for chain-loading barebox from SD-card
  2020-07-01  5:23 [PATCH 00/28] ARM: at91: add sama5d2 first stage support Ahmad Fatoum
                   ` (17 preceding siblings ...)
  2020-07-01  5:23 ` [PATCH 18/28] ARM: at91: add code for sama5 boot source detection Ahmad Fatoum
@ 2020-07-01  5:23 ` Ahmad Fatoum
  2020-07-01  5:23 ` [PATCH 20/28] ARM: at91: sama5d2: reuse stack set-up by first stage Ahmad Fatoum
                   ` (8 subsequent siblings)
  27 siblings, 0 replies; 30+ messages in thread
From: Ahmad Fatoum @ 2020-07-01  5:23 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

With PBL FAT support implemented, provide an sama5d2_sdhci_start_image
helper that can be called from the PBL to chainload a barebox.bin file
from the first FAT partition.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 arch/arm/mach-at91/Kconfig              |  5 ++
 arch/arm/mach-at91/Makefile             |  1 +
 arch/arm/mach-at91/include/mach/xload.h | 12 ++++
 arch/arm/mach-at91/xload-mmc.c          | 85 +++++++++++++++++++++++++
 4 files changed, 103 insertions(+)
 create mode 100644 arch/arm/mach-at91/include/mach/xload.h
 create mode 100644 arch/arm/mach-at91/xload-mmc.c

diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 54fa9b8aa28c..25ef854bf0b5 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -40,6 +40,11 @@ config HAVE_AT91_I2S_MUX_CLK
 config HAVE_AT91_SAM9X60_PLL
 	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
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
index 254bbeef2773..31a91b967ef4 100644
--- a/arch/arm/mach-at91/Makefile
+++ b/arch/arm/mach-at91/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_AT91_BOOTSTRAP)	+= bootstrap.o
 
 obj-y += at91sam9_reset.o
 obj-y += at91sam9g45_reset.o
+pbl-$(CONFIG_AT91_MCI_PBL) +=  xload-mmc.o
 
 obj-$(CONFIG_AT91SAM9_SMC) += sam9_smc.o
 obj-$(CONFIG_HAVE_AT91SAM9_RST) += at91sam9_rst.o
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 000000000000..f110236b0b10
--- /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/xload-mmc.c b/arch/arm/mach-at91/xload-mmc.c
new file mode 100644
index 000000000000..bc974b6446c7
--- /dev/null
+++ b/arch/arm/mach-at91/xload-mmc.c
@@ -0,0 +1,85 @@
+#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] = { SAMA5D2_BASE_SDHC0, SAMA5D2_ID_SDMMC0, AT91_MUX_PERIPH_A,
+		{ 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 13, 10, 11, 12, -1 } },
+	[1] = { SAMA5D2_BASE_SDHC1, SAMA5D2_ID_SDMMC1, AT91_MUX_PERIPH_E,
+		{ 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
+ *
+ * Return: If successul, this function does not return. A negative error
+ * code is returned when this function fails.
+ */
+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;
+
+	instance = &sdhci_instances[!!sama5_bootsource_instance(r4)];
+
+	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");
+}
-- 
2.27.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 20/28] ARM: at91: sama5d2: reuse stack set-up by first stage
  2020-07-01  5:23 [PATCH 00/28] ARM: at91: add sama5d2 first stage support Ahmad Fatoum
                   ` (18 preceding siblings ...)
  2020-07-01  5:23 ` [PATCH 19/28] ARM: at91: add helpers for chain-loading barebox from SD-card Ahmad Fatoum
@ 2020-07-01  5:23 ` Ahmad Fatoum
  2020-07-01  5:23 ` [PATCH 21/28] at91: debug_ll: remove duplicated IS_ENABLED(CONFIG_DEBUG_LL) condition Ahmad Fatoum
                   ` (7 subsequent siblings)
  27 siblings, 0 replies; 30+ messages in thread
From: Ahmad Fatoum @ 2020-07-01  5:23 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

Stack is always set up to end of SRAM before PBL, either by ROM code or
by first stage bootloader, be it at91bootstrap or barebox in a later
commit, so no need to change the stack pointer again.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 arch/arm/boards/sama5d27-giantboard/lowlevel.c | 13 +++----------
 arch/arm/boards/sama5d27-som1/lowlevel.c       | 13 +++----------
 2 files changed, 6 insertions(+), 20 deletions(-)

diff --git a/arch/arm/boards/sama5d27-giantboard/lowlevel.c b/arch/arm/boards/sama5d27-giantboard/lowlevel.c
index e08217105bcc..4419e946f1a8 100644
--- a/arch/arm/boards/sama5d27-giantboard/lowlevel.c
+++ b/arch/arm/boards/sama5d27-giantboard/lowlevel.c
@@ -34,10 +34,12 @@ static void dbgu_init(void)
 
 extern char __dtb_z_at91_sama5d27_giantboard_start[];
 
-static noinline void giantboard_entry(void)
+ENTRY_FUNCTION(start_sama5d27_giantboard, r0, r1, r2)
 {
 	void *fdt;
 
+	arm_cpu_lowlevel_init();
+
 	if (IS_ENABLED(CONFIG_DEBUG_LL))
 		dbgu_init();
 
@@ -45,12 +47,3 @@ static noinline void giantboard_entry(void)
 
 	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();
-}
diff --git a/arch/arm/boards/sama5d27-som1/lowlevel.c b/arch/arm/boards/sama5d27-som1/lowlevel.c
index 2b39e5abc396..b7780ec8ae43 100644
--- a/arch/arm/boards/sama5d27-som1/lowlevel.c
+++ b/arch/arm/boards/sama5d27-som1/lowlevel.c
@@ -58,10 +58,12 @@ static void ek_dbgu_init(void)
 
 extern char __dtb_z_at91_sama5d27_som1_ek_start[];
 
-static noinline void som1_entry(void)
+ENTRY_FUNCTION(start_sama5d27_som1_ek, r0, r1, r2)
 {
 	void *fdt;
 
+	arm_cpu_lowlevel_init();
+
 	if (IS_ENABLED(CONFIG_DEBUG_LL))
 		ek_dbgu_init();
 
@@ -70,12 +72,3 @@ static noinline void som1_entry(void)
 	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();
-}
-- 
2.27.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 21/28] at91: debug_ll: remove duplicated IS_ENABLED(CONFIG_DEBUG_LL) condition
  2020-07-01  5:23 [PATCH 00/28] ARM: at91: add sama5d2 first stage support Ahmad Fatoum
                   ` (19 preceding siblings ...)
  2020-07-01  5:23 ` [PATCH 20/28] ARM: at91: sama5d2: reuse stack set-up by first stage Ahmad Fatoum
@ 2020-07-01  5:23 ` Ahmad Fatoum
  2020-07-01  5:23 ` [PATCH 22/28] ARM: at91: sama5d2: reduce UART setup boilerplate with new helpers Ahmad Fatoum
                   ` (6 subsequent siblings)
  27 siblings, 0 replies; 30+ messages in thread
From: Ahmad Fatoum @ 2020-07-01  5:23 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

There are three users of at91_dbgu_setup_ll and all already call this
function only when IS_ENABLED(CONFIG_DEBUG_LL). Remove the duplicated
condition from the function itself. This allows us to use the function
for pbl_set_console use later on, even with DEBUG_LL disabled.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 arch/arm/mach-at91/include/mach/at91_dbgu.h | 34 ++++++++++-----------
 1 file changed, 16 insertions(+), 18 deletions(-)

diff --git a/arch/arm/mach-at91/include/mach/at91_dbgu.h b/arch/arm/mach-at91/include/mach/at91_dbgu.h
index 0ba9cdae10ce..29aaa2dfe154 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
-- 
2.27.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 22/28] ARM: at91: sama5d2: reduce UART setup boilerplate with new helpers
  2020-07-01  5:23 [PATCH 00/28] ARM: at91: add sama5d2 first stage support Ahmad Fatoum
                   ` (20 preceding siblings ...)
  2020-07-01  5:23 ` [PATCH 21/28] at91: debug_ll: remove duplicated IS_ENABLED(CONFIG_DEBUG_LL) condition Ahmad Fatoum
@ 2020-07-01  5:23 ` Ahmad Fatoum
  2020-07-01  5:23 ` [PATCH 23/28] ARM: at91: sama5d27-som1: add additional first stage entry point Ahmad Fatoum
                   ` (5 subsequent siblings)
  27 siblings, 0 replies; 30+ messages in thread
From: Ahmad Fatoum @ 2020-07-01  5:23 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

The sama5d2 can be fused for one of 9 preset UART iosets. This is then
used by the BootROM for printing the `RomBOOT' header and for the XMODEM
protocol implemented by the SAM-BA monitor. Add two new sama5d2 specific
helpers:

- sama5d2_dbgu_setup_ll for setting up the port with only pinmux and
  master clock as arguments
- sama5d2_resetup_uart_console for resetup of the uart console with
  same pinmux used by the ROM code

The default value, when unfused, is UART_1_IOSET_1 (RX@PD2, TX@PD3),
which are the same ones used on the two sama5d2 board supported so far.

With this change, the DEBUG_LL baudrate is also no longer fixed at 115200,
but instead comes from the CONFIG_BAUDRATE symbol.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 .../arm/boards/sama5d27-giantboard/lowlevel.c |  11 +-
 arch/arm/boards/sama5d27-som1/lowlevel.c      |  11 +-
 arch/arm/mach-at91/include/mach/debug_ll.h    |  17 ++-
 arch/arm/mach-at91/include/mach/sama5d2.h     |  56 ++++++++++
 arch/arm/mach-at91/include/mach/sama5d2_ll.h  | 101 ++++++++++++++++++
 5 files changed, 172 insertions(+), 24 deletions(-)

diff --git a/arch/arm/boards/sama5d27-giantboard/lowlevel.c b/arch/arm/boards/sama5d27-giantboard/lowlevel.c
index 4419e946f1a8..a30441d7ccfa 100644
--- a/arch/arm/boards/sama5d27-giantboard/lowlevel.c
+++ b/arch/arm/boards/sama5d27-giantboard/lowlevel.c
@@ -18,16 +18,7 @@
 
 static void dbgu_init(void)
 {
-	unsigned mck = MASTER_CLOCK / 2;
-
-	sama5d2_pmc_enable_periph_clock(SAMA5D2_ID_PIOD);
-
-	at91_mux_pio4_set_A_periph(SAMA5D2_BASE_PIOD,
-				   pin_to_mask(AT91_PIN_PD3)); /* DBGU TXD */
-
-	sama5d2_pmc_enable_periph_clock(SAMA5D2_ID_UART1);
-
-	at91_dbgu_setup_ll(SAMA5D2_BASE_UART1, mck, 115200);
+	sama5d2_resetup_uart_console(MASTER_CLOCK);
 
 	putc_ll('>');
 }
diff --git a/arch/arm/boards/sama5d27-som1/lowlevel.c b/arch/arm/boards/sama5d27-som1/lowlevel.c
index b7780ec8ae43..2e408ce832f7 100644
--- a/arch/arm/boards/sama5d27-som1/lowlevel.c
+++ b/arch/arm/boards/sama5d27-som1/lowlevel.c
@@ -42,16 +42,7 @@ static void ek_turn_led(unsigned color)
 
 static void ek_dbgu_init(void)
 {
-	unsigned mck = MASTER_CLOCK / 2;
-
-	sama5d2_pmc_enable_periph_clock(SAMA5D2_ID_PIOD);
-
-	at91_mux_pio4_set_A_periph(SAMA5D2_BASE_PIOD,
-				   pin_to_mask(AT91_PIN_PD3)); /* DBGU TXD */
-
-	sama5d2_pmc_enable_periph_clock(SAMA5D2_ID_UART1);
-
-	at91_dbgu_setup_ll(SAMA5D2_BASE_UART1, mck, 115200);
+	sama5d2_resetup_uart_console(MASTER_CLOCK);
 
 	putc_ll('>');
 }
diff --git a/arch/arm/mach-at91/include/mach/debug_ll.h b/arch/arm/mach-at91/include/mach/debug_ll.h
index b71393042463..b3cbdbc26f1d 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/sama5d2.h b/arch/arm/mach-at91/include/mach/sama5d2.h
index ada9c59e0370..90b566ffc4ab 100644
--- a/arch/arm/mach-at91/include/mach/sama5d2.h
+++ b/arch/arm/mach-at91/include/mach/sama5d2.h
@@ -16,6 +16,8 @@
 
 #include <asm/io.h>
 #include <linux/sizes.h>
+#include <linux/bitops.h>
+#include <linux/bitfield.h>
 
 /*
  * Peripheral identifiers/interrupts. (Table 18-9)
@@ -261,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
index e6fa3914250b..96f3bc545284 100644
--- a/arch/arm/mach-at91/include/mach/sama5d2_ll.h
+++ b/arch/arm/mach-at91/include/mach/sama5d2_ll.h
@@ -3,6 +3,8 @@
 
 #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>
 
@@ -35,4 +37,103 @@ static inline int sama5d2_pmc_enable_generic_clock(unsigned int periph_id,
 					     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
-- 
2.27.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 23/28] ARM: at91: sama5d27-som1: add additional first stage entry point
  2020-07-01  5:23 [PATCH 00/28] ARM: at91: add sama5d2 first stage support Ahmad Fatoum
                   ` (21 preceding siblings ...)
  2020-07-01  5:23 ` [PATCH 22/28] ARM: at91: sama5d2: reduce UART setup boilerplate with new helpers Ahmad Fatoum
@ 2020-07-01  5:23 ` Ahmad Fatoum
  2020-07-01  5:23 ` [PATCH 24/28] ARM: at91: sama5d2: read back memory size from DDRAM controller Ahmad Fatoum
                   ` (4 subsequent siblings)
  27 siblings, 0 replies; 30+ messages in thread
From: Ahmad Fatoum @ 2020-07-01  5:23 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

The BootROM constrains us to a 64K big first stage bootloader. Add a PBL
entry point for a xload barebox that sets up the minimum necessary to
load a FAT32 barebox.bin from the SD-Card.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 arch/arm/boards/sama5d27-som1/lowlevel.c      | 32 +++++++++------
 arch/arm/mach-at91/Kconfig                    |  1 +
 arch/arm/mach-at91/include/mach/barebox-arm.h | 21 ++++++++++
 .../include/mach/sama5d2-sip-ddramc.h         | 39 +++++++++++++++++++
 images/Makefile.at91                          |  5 +++
 5 files changed, 87 insertions(+), 11 deletions(-)
 create mode 100644 arch/arm/mach-at91/include/mach/barebox-arm.h
 create mode 100644 arch/arm/mach-at91/include/mach/sama5d2-sip-ddramc.h

diff --git a/arch/arm/boards/sama5d27-som1/lowlevel.c b/arch/arm/boards/sama5d27-som1/lowlevel.c
index 2e408ce832f7..d52c4ca7465e 100644
--- a/arch/arm/boards/sama5d27-som1/lowlevel.c
+++ b/arch/arm/boards/sama5d27-som1/lowlevel.c
@@ -5,13 +5,12 @@
 
 #include <common.h>
 #include <init.h>
-
-#include <asm/barebox-arm-head.h>
-#include <asm/barebox-arm.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)
@@ -40,23 +39,34 @@ static void ek_turn_led(unsigned color)
 	}
 }
 
-static void ek_dbgu_init(void)
+SAMA5_ENTRY_FUNCTION(start_sama5d27_som1_ek_xload_mmc, r4)
 {
-	sama5d2_resetup_uart_console(MASTER_CLOCK);
+	void __iomem *dbgu_base;
+	sama5d2_lowlevel_init();
+
+	dbgu_base = sama5d2_resetup_uart_console(MASTER_CLOCK);
+	if (IS_ENABLED(CONFIG_DEBUG_LL))
+		putc_ll('>');
 
-	putc_ll('>');
+	relocate_to_current_adr();
+	setup_c();
+
+	pbl_set_putc(at91_dbgu_putc, dbgu_base);
+
+	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[];
 
-ENTRY_FUNCTION(start_sama5d27_som1_ek, r0, r1, r2)
+SAMA5_ENTRY_FUNCTION(start_sama5d27_som1_ek, r4)
 {
 	void *fdt;
 
-	arm_cpu_lowlevel_init();
-
 	if (IS_ENABLED(CONFIG_DEBUG_LL))
-		ek_dbgu_init();
+		putc_ll('>');
 
 	fdt = __dtb_z_at91_sama5d27_som1_ek_start + get_runtime_offset();
 
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 25ef854bf0b5..f388d00b8f47 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -603,6 +603,7 @@ 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
 	help
 	  Select this if you are using Microchip's sama5d27 SoM evaluation kit
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 000000000000..4a65c6f8fa55
--- /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/sama5d2-sip-ddramc.h b/arch/arm/mach-at91/include/mach/sama5d2-sip-ddramc.h
new file mode 100644
index 000000000000..35c92c43fce8
--- /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/images/Makefile.at91 b/images/Makefile.at91
index 448d71fb981d..bc63357c5d19 100644
--- a/images/Makefile.at91
+++ b/images/Makefile.at91
@@ -18,6 +18,11 @@ pblb-$(CONFIG_MACH_SAMA5D27_SOM1) += start_sama5d27_som1_ek
 FILE_barebox-sama5d27-som1-ek.img = start_sama5d27_som1_ek.pblb
 image-$(CONFIG_MACH_SAMA5D27_SOM1) += barebox-sama5d27-som1-ek.img
 
+pblb-$(CONFIG_MACH_SAMA5D27_SOM1) += start_sama5d27_som1_ek_xload_mmc
+MAX_PBL_IMAGE_SIZE_start_sama5d27_som1_ek_xload_mmc = 0xffff
+FILE_barebox-sama5d27-som1-ek-xload-mmc.img = start_sama5d27_som1_ek_xload_mmc.pblb
+image-$(CONFIG_MACH_SAMA5D27_SOM1) += barebox-sama5d27-som1-ek-xload-mmc.img
+
 pblb-$(CONFIG_MACH_SAMA5D27_GIANTBOARD) += start_sama5d27_giantboard
 FILE_barebox-groboards-sama5d27-giantboard.img = start_sama5d27_giantboard.pblb
 image-$(CONFIG_MACH_SAMA5D27_GIANTBOARD) += barebox-groboards-sama5d27-giantboard.img
-- 
2.27.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 24/28] ARM: at91: sama5d2: read back memory size from DDRAM controller
  2020-07-01  5:23 [PATCH 00/28] ARM: at91: add sama5d2 first stage support Ahmad Fatoum
                   ` (22 preceding siblings ...)
  2020-07-01  5:23 ` [PATCH 23/28] ARM: at91: sama5d27-som1: add additional first stage entry point Ahmad Fatoum
@ 2020-07-01  5:23 ` Ahmad Fatoum
  2020-07-01  5:23 ` [PATCH 25/28] ARM: at91: sama5d2: populate $bootsource and $bootsource_instance Ahmad Fatoum
                   ` (3 subsequent siblings)
  27 siblings, 0 replies; 30+ messages in thread
From: Ahmad Fatoum @ 2020-07-01  5:23 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

We hard code memory size at three places:
 - In the configuration we use to initialize the DDRAM controller
 - In the minimal available size passed from PBL to barebox proper
 - In the device tree memory node override

Remove the two latter ones and replace them with code that reads the
size back from controller.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 .../arm/boards/sama5d27-giantboard/lowlevel.c |  2 +-
 arch/arm/boards/sama5d27-som1/lowlevel.c      |  2 +-
 arch/arm/dts/at91-sama5d27_giantboard.dts     |  4 --
 arch/arm/dts/at91-sama5d27_som1_ek.dts        |  4 --
 arch/arm/dts/sama5d2.dtsi                     |  2 +
 arch/arm/mach-at91/Kconfig                    |  4 ++
 arch/arm/mach-at91/Makefile                   |  1 +
 arch/arm/mach-at91/ddramc.c                   | 57 +++++++++++++++++++
 arch/arm/mach-at91/include/mach/ddramc.h      |  2 +
 9 files changed, 68 insertions(+), 10 deletions(-)
 create mode 100644 arch/arm/mach-at91/ddramc.c

diff --git a/arch/arm/boards/sama5d27-giantboard/lowlevel.c b/arch/arm/boards/sama5d27-giantboard/lowlevel.c
index a30441d7ccfa..0bb3a7289c99 100644
--- a/arch/arm/boards/sama5d27-giantboard/lowlevel.c
+++ b/arch/arm/boards/sama5d27-giantboard/lowlevel.c
@@ -36,5 +36,5 @@ ENTRY_FUNCTION(start_sama5d27_giantboard, r0, r1, r2)
 
 	fdt = __dtb_z_at91_sama5d27_giantboard_start + get_runtime_offset();
 
-	barebox_arm_entry(SAMA5_DDRCS, SZ_128M, fdt);
+	sama5d2_barebox_entry(fdt);
 }
diff --git a/arch/arm/boards/sama5d27-som1/lowlevel.c b/arch/arm/boards/sama5d27-som1/lowlevel.c
index d52c4ca7465e..bf01b161e2f4 100644
--- a/arch/arm/boards/sama5d27-som1/lowlevel.c
+++ b/arch/arm/boards/sama5d27-som1/lowlevel.c
@@ -71,5 +71,5 @@ SAMA5_ENTRY_FUNCTION(start_sama5d27_som1_ek, r4)
 	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);
+	sama5d2_barebox_entry(fdt);
 }
diff --git a/arch/arm/dts/at91-sama5d27_giantboard.dts b/arch/arm/dts/at91-sama5d27_giantboard.dts
index 2ef516bd9e95..6ba094c3da1a 100644
--- a/arch/arm/dts/at91-sama5d27_giantboard.dts
+++ b/arch/arm/dts/at91-sama5d27_giantboard.dts
@@ -40,10 +40,6 @@
 	};
 };
 
-&{/memory} {
-	reg = <0x20000000 0x8000000>;
-};
-
 &slow_xtal {
 	clock-frequency = <32768>;
 };
diff --git a/arch/arm/dts/at91-sama5d27_som1_ek.dts b/arch/arm/dts/at91-sama5d27_som1_ek.dts
index cd038dc7c169..b9042d11317a 100644
--- a/arch/arm/dts/at91-sama5d27_som1_ek.dts
+++ b/arch/arm/dts/at91-sama5d27_som1_ek.dts
@@ -13,10 +13,6 @@
 			device-path = &barebox_env;
 		};
 	};
-
-	memory {
-		reg = <0x20000000 0x8000000>;
-	};
 };
 
 &qspi1 {
diff --git a/arch/arm/dts/sama5d2.dtsi b/arch/arm/dts/sama5d2.dtsi
index fadcc8381570..c9af5f2f7ad4 100644
--- a/arch/arm/dts/sama5d2.dtsi
+++ b/arch/arm/dts/sama5d2.dtsi
@@ -7,6 +7,8 @@
 	};
 };
 
+/delete-node/ &{/memory};
+
 &sdmmc0 {
 	assigned-clock-parents = <&pmc PMC_TYPE_CORE PMC_UTMI>;
 };
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index f388d00b8f47..8584dcd97944 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -40,6 +40,9 @@ 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
@@ -87,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
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
index 31a91b967ef4..3b9f60a95af3 100644
--- a/arch/arm/mach-at91/Makefile
+++ b/arch/arm/mach-at91/Makefile
@@ -12,6 +12,7 @@ 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
diff --git a/arch/arm/mach-at91/ddramc.c b/arch/arm/mach-at91/ddramc.c
new file mode 100644
index 000000000000..6dac7946896b
--- /dev/null
+++ b/arch/arm/mach-at91/ddramc.c
@@ -0,0 +1,57 @@
+// 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 <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(void *boarddata)
+{
+	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/include/mach/ddramc.h b/arch/arm/mach-at91/include/mach/ddramc.h
index 0b33afc21353..cd85bb6eab21 100644
--- a/arch/arm/mach-at91/include/mach/ddramc.h
+++ b/arch/arm/mach-at91/include/mach/ddramc.h
@@ -32,5 +32,7 @@ void at91_lpddr1_sdram_initialize(void __iomem *base_address,
 				  void __iomem *ram_address,
 				  struct at91_ddramc_register *ddramc_config);
 
+void __noreturn sama5d2_barebox_entry(void *boarddata);
+
 
 #endif /* #ifndef __DDRAMC_H__ */
-- 
2.27.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 25/28] ARM: at91: sama5d2: populate $bootsource and $bootsource_instance
  2020-07-01  5:23 [PATCH 00/28] ARM: at91: add sama5d2 first stage support Ahmad Fatoum
                   ` (23 preceding siblings ...)
  2020-07-01  5:23 ` [PATCH 24/28] ARM: at91: sama5d2: read back memory size from DDRAM controller Ahmad Fatoum
@ 2020-07-01  5:23 ` Ahmad Fatoum
  2020-07-01  5:23 ` [PATCH 26/28] ARM: at91: sama5d27-som1-ek: add barebox_update and multi environment support Ahmad Fatoum
                   ` (2 subsequent siblings)
  27 siblings, 0 replies; 30+ messages in thread
From: Ahmad Fatoum @ 2020-07-01  5:23 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

The BootROM passes us information about the boot medium in r4 and we
already use that in first stage and pass it along to second stage
PBL already. To make use of it, we need to pass it to barebox proper, do
this by writing it in the last 4 bytes of the SRAM. As second stage
always run in DRAM, this is safe to do.

We could also write to SRAM directly from first stage, but at91bootstrap
passes info in r4 as well for the sama5d3 boards, so we do it likewise
to maintain compatibility.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 arch/arm/boards/sama5d27-giantboard/lowlevel.c  |  6 +++---
 arch/arm/boards/sama5d27-som1/lowlevel.c        |  2 +-
 arch/arm/mach-at91/ddramc.c                     |  4 +++-
 arch/arm/mach-at91/include/mach/ddramc.h        |  3 +--
 .../mach-at91/include/mach/sama5_bootsource.h   |  3 +++
 arch/arm/mach-at91/sama5d2.c                    | 17 +++++++++++++++++
 6 files changed, 28 insertions(+), 7 deletions(-)

diff --git a/arch/arm/boards/sama5d27-giantboard/lowlevel.c b/arch/arm/boards/sama5d27-giantboard/lowlevel.c
index 0bb3a7289c99..3dada9baf23c 100644
--- a/arch/arm/boards/sama5d27-giantboard/lowlevel.c
+++ b/arch/arm/boards/sama5d27-giantboard/lowlevel.c
@@ -7,7 +7,7 @@
 #include <init.h>
 
 #include <asm/barebox-arm-head.h>
-#include <asm/barebox-arm.h>
+#include <mach/barebox-arm.h>
 #include <mach/sama5d2_ll.h>
 #include <mach/iomux.h>
 #include <debug_ll.h>
@@ -25,7 +25,7 @@ static void dbgu_init(void)
 
 extern char __dtb_z_at91_sama5d27_giantboard_start[];
 
-ENTRY_FUNCTION(start_sama5d27_giantboard, r0, r1, r2)
+SAMA5_ENTRY_FUNCTION(start_sama5d27_giantboard, r4)
 {
 	void *fdt;
 
@@ -36,5 +36,5 @@ ENTRY_FUNCTION(start_sama5d27_giantboard, r0, r1, r2)
 
 	fdt = __dtb_z_at91_sama5d27_giantboard_start + get_runtime_offset();
 
-	sama5d2_barebox_entry(fdt);
+	sama5d2_barebox_entry(r4, fdt);
 }
diff --git a/arch/arm/boards/sama5d27-som1/lowlevel.c b/arch/arm/boards/sama5d27-som1/lowlevel.c
index bf01b161e2f4..e9c781297c27 100644
--- a/arch/arm/boards/sama5d27-som1/lowlevel.c
+++ b/arch/arm/boards/sama5d27-som1/lowlevel.c
@@ -71,5 +71,5 @@ SAMA5_ENTRY_FUNCTION(start_sama5d27_som1_ek, r4)
 	fdt = __dtb_z_at91_sama5d27_som1_ek_start + get_runtime_offset();
 
 	ek_turn_led(RGB_LED_GREEN);
-	sama5d2_barebox_entry(fdt);
+	sama5d2_barebox_entry(r4, fdt);
 }
diff --git a/arch/arm/mach-at91/ddramc.c b/arch/arm/mach-at91/ddramc.c
index 6dac7946896b..a241ea9f0a61 100644
--- a/arch/arm/mach-at91/ddramc.c
+++ b/arch/arm/mach-at91/ddramc.c
@@ -9,6 +9,7 @@
 #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>
@@ -18,8 +19,9 @@ static unsigned sama5_ramsize(void __iomem *base)
 	return at91_get_ddram_size(base, true);
 }
 
-void __noreturn sama5d2_barebox_entry(void *boarddata)
+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);
 }
diff --git a/arch/arm/mach-at91/include/mach/ddramc.h b/arch/arm/mach-at91/include/mach/ddramc.h
index cd85bb6eab21..b929bf5f58e8 100644
--- a/arch/arm/mach-at91/include/mach/ddramc.h
+++ b/arch/arm/mach-at91/include/mach/ddramc.h
@@ -32,7 +32,6 @@ void at91_lpddr1_sdram_initialize(void __iomem *base_address,
 				  void __iomem *ram_address,
 				  struct at91_ddramc_register *ddramc_config);
 
-void __noreturn sama5d2_barebox_entry(void *boarddata);
-
+void __noreturn sama5d2_barebox_entry(unsigned int r4, void *boarddata);
 
 #endif /* #ifndef __DDRAMC_H__ */
diff --git a/arch/arm/mach-at91/include/mach/sama5_bootsource.h b/arch/arm/mach-at91/include/mach/sama5_bootsource.h
index 29354dcaf34d..0f90afe90232 100644
--- a/arch/arm/mach-at91/include/mach/sama5_bootsource.h
+++ b/arch/arm/mach-at91/include/mach/sama5_bootsource.h
@@ -43,4 +43,7 @@ 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/sama5d2.c b/arch/arm/mach-at91/sama5d2.c
index c498b0964534..2ce6d7f36f56 100644
--- a/arch/arm/mach-at91/sama5d2.c
+++ b/arch/arm/mach-at91/sama5d2.c
@@ -6,6 +6,7 @@
 #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
@@ -52,3 +53,19 @@ static int sama5d2_init(void)
 	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);
-- 
2.27.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 26/28] ARM: at91: sama5d27-som1-ek: add barebox_update and multi environment support
  2020-07-01  5:23 [PATCH 00/28] ARM: at91: add sama5d2 first stage support Ahmad Fatoum
                   ` (24 preceding siblings ...)
  2020-07-01  5:23 ` [PATCH 25/28] ARM: at91: sama5d2: populate $bootsource and $bootsource_instance Ahmad Fatoum
@ 2020-07-01  5:23 ` Ahmad Fatoum
  2020-07-01  5:23 ` [PATCH 27/28] ARM: at91: sama5d27-giantboard: add additional first stage entry point Ahmad Fatoum
  2020-07-01  5:23 ` [PATCH 28/28] ARM: at91: sama5d27-giantboard: add default environment/bbu Ahmad Fatoum
  27 siblings, 0 replies; 30+ messages in thread
From: Ahmad Fatoum @ 2020-07-01  5:23 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

We now have second stage support for running from sdmmc0 and sdmmc1.
Add a barebox environment and update handler for the two SD cards.

As fall back, we use the environment in the QSPI flash as before as this
is soldered to the SoM and is always available.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 arch/arm/boards/sama5d27-som1/Makefile |  1 +
 arch/arm/boards/sama5d27-som1/board.c  | 35 ++++++++++++++++++++++++++
 arch/arm/dts/at91-sama5d27_som1_ek.dts | 17 ++++++++++++-
 arch/arm/mach-at91/Kconfig             |  1 +
 4 files changed, 53 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/boards/sama5d27-som1/board.c

diff --git a/arch/arm/boards/sama5d27-som1/Makefile b/arch/arm/boards/sama5d27-som1/Makefile
index b08c4a93ca27..092c31d6b28d 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 000000000000..00c0e92a5da3
--- /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/dts/at91-sama5d27_som1_ek.dts b/arch/arm/dts/at91-sama5d27_som1_ek.dts
index b9042d11317a..befee89ad78a 100644
--- a/arch/arm/dts/at91-sama5d27_som1_ek.dts
+++ b/arch/arm/dts/at91-sama5d27_som1_ek.dts
@@ -8,9 +8,24 @@
 
 / {
 	chosen {
-		environment {
+		environment-qspi {
 			compatible = "barebox,environment";
 			device-path = &barebox_env;
+			status = "disabled";
+		};
+
+		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";
 		};
 	};
 };
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 8584dcd97944..52eefc736138 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -609,6 +609,7 @@ config MACH_SAMA5D27_SOM1
 	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
 
-- 
2.27.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 27/28] ARM: at91: sama5d27-giantboard: add additional first stage entry point
  2020-07-01  5:23 [PATCH 00/28] ARM: at91: add sama5d2 first stage support Ahmad Fatoum
                   ` (25 preceding siblings ...)
  2020-07-01  5:23 ` [PATCH 26/28] ARM: at91: sama5d27-som1-ek: add barebox_update and multi environment support Ahmad Fatoum
@ 2020-07-01  5:23 ` Ahmad Fatoum
  2020-07-01  5:23 ` [PATCH 28/28] ARM: at91: sama5d27-giantboard: add default environment/bbu Ahmad Fatoum
  27 siblings, 0 replies; 30+ messages in thread
From: Ahmad Fatoum @ 2020-07-01  5:23 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

The BootROM constrains us to a 64K big first stage bootloader. Add a PBL
entry point for a xload barebox that sets up the minimum necessary to
load a FAT32 barebox.bin from the SD-Card.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 .../arm/boards/sama5d27-giantboard/lowlevel.c | 28 +++++++++++++------
 images/Makefile.at91                          |  5 ++++
 2 files changed, 24 insertions(+), 9 deletions(-)

diff --git a/arch/arm/boards/sama5d27-giantboard/lowlevel.c b/arch/arm/boards/sama5d27-giantboard/lowlevel.c
index 3dada9baf23c..dc678e5d83ce 100644
--- a/arch/arm/boards/sama5d27-giantboard/lowlevel.c
+++ b/arch/arm/boards/sama5d27-giantboard/lowlevel.c
@@ -5,22 +5,34 @@
 
 #include <common.h>
 #include <init.h>
-
-#include <asm/barebox-arm-head.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 void dbgu_init(void)
+SAMA5_ENTRY_FUNCTION(start_sama5d27_giantboard_xload_mmc, r4)
 {
-	sama5d2_resetup_uart_console(MASTER_CLOCK);
+	void __iomem *dbgu_base;
+
+	sama5d2_lowlevel_init();
+
+	dbgu_base = sama5d2_resetup_uart_console(MASTER_CLOCK);
+	if (IS_ENABLED(CONFIG_DEBUG_LL))
+		putc_ll('>');
 
-	putc_ll('>');
+	relocate_to_current_adr();
+	setup_c();
+
+	pbl_set_putc(at91_dbgu_putc, dbgu_base);
+
+	sama5d2_udelay_init(MASTER_CLOCK);
+	sama5d2_d1g_ddrconf();
+	sama5d2_sdhci_start_image(r4);
 }
 
 extern char __dtb_z_at91_sama5d27_giantboard_start[];
@@ -29,10 +41,8 @@ SAMA5_ENTRY_FUNCTION(start_sama5d27_giantboard, r4)
 {
 	void *fdt;
 
-	arm_cpu_lowlevel_init();
-
 	if (IS_ENABLED(CONFIG_DEBUG_LL))
-		dbgu_init();
+		putc_ll('>');
 
 	fdt = __dtb_z_at91_sama5d27_giantboard_start + get_runtime_offset();
 
diff --git a/images/Makefile.at91 b/images/Makefile.at91
index bc63357c5d19..00fa4cab27ea 100644
--- a/images/Makefile.at91
+++ b/images/Makefile.at91
@@ -26,3 +26,8 @@ image-$(CONFIG_MACH_SAMA5D27_SOM1) += barebox-sama5d27-som1-ek-xload-mmc.img
 pblb-$(CONFIG_MACH_SAMA5D27_GIANTBOARD) += start_sama5d27_giantboard
 FILE_barebox-groboards-sama5d27-giantboard.img = start_sama5d27_giantboard.pblb
 image-$(CONFIG_MACH_SAMA5D27_GIANTBOARD) += barebox-groboards-sama5d27-giantboard.img
+
+pblb-$(CONFIG_MACH_SAMA5D27_GIANTBOARD) += start_sama5d27_giantboard_xload_mmc
+FILE_barebox-groboards-sama5d27-giantboard-xload-mmc.img = start_sama5d27_giantboard_xload_mmc.pblb
+MAX_PBL_IMAGE_SIZE_start_sama5d27_giantboard_xload_mmc = 0xffff
+image-$(CONFIG_MACH_SAMA5D27_GIANTBOARD) += barebox-groboards-sama5d27-giantboard-xload-mmc.img
-- 
2.27.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 28/28] ARM: at91: sama5d27-giantboard: add default environment/bbu
  2020-07-01  5:23 [PATCH 00/28] ARM: at91: add sama5d2 first stage support Ahmad Fatoum
                   ` (26 preceding siblings ...)
  2020-07-01  5:23 ` [PATCH 27/28] ARM: at91: sama5d27-giantboard: add additional first stage entry point Ahmad Fatoum
@ 2020-07-01  5:23 ` Ahmad Fatoum
  27 siblings, 0 replies; 30+ messages in thread
From: Ahmad Fatoum @ 2020-07-01  5:23 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

The board only has SD-Card as storage. Add a barebox update handler to
flash barebox to it, as well as an nv.boot.default=mmc1 to boot from it.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 arch/arm/boards/sama5d27-giantboard/Makefile    |  2 ++
 arch/arm/boards/sama5d27-giantboard/board.c     | 17 +++++++++++++++++
 .../defaultenv-giantboard/nv/boot.default       |  1 +
 arch/arm/dts/at91-sama5d27_giantboard.dts       |  6 ++++++
 4 files changed, 26 insertions(+)
 create mode 100644 arch/arm/boards/sama5d27-giantboard/board.c
 create mode 100644 arch/arm/boards/sama5d27-giantboard/defaultenv-giantboard/nv/boot.default

diff --git a/arch/arm/boards/sama5d27-giantboard/Makefile b/arch/arm/boards/sama5d27-giantboard/Makefile
index b08c4a93ca27..f5869c483978 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 000000000000..1d4453ede35b
--- /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 000000000000..646f435652ef
--- /dev/null
+++ b/arch/arm/boards/sama5d27-giantboard/defaultenv-giantboard/nv/boot.default
@@ -0,0 +1 @@
+mmc1
diff --git a/arch/arm/dts/at91-sama5d27_giantboard.dts b/arch/arm/dts/at91-sama5d27_giantboard.dts
index 6ba094c3da1a..2ba3ff217101 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 {
-- 
2.27.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 22/28] ARM: at91: sama5d2: reduce UART setup boilerplate with new helpers
  2020-07-01  9:10 [PATCH RESEND 00/28] ARM: at91: add sama5d2 first stage support Ahmad Fatoum
@ 2020-07-01  9:11 ` Ahmad Fatoum
  0 siblings, 0 replies; 30+ messages in thread
From: Ahmad Fatoum @ 2020-07-01  9:11 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

The sama5d2 can be fused for one of 9 preset UART iosets. This is then
used by the BootROM for printing the `RomBOOT' header and for the XMODEM
protocol implemented by the SAM-BA monitor. Add two new sama5d2 specific
helpers:

- sama5d2_dbgu_setup_ll for setting up the port with only pinmux and
  master clock as arguments
- sama5d2_resetup_uart_console for resetup of the uart console with
  same pinmux used by the ROM code

The default value, when unfused, is UART_1_IOSET_1 (RX@PD2, TX@PD3),
which are the same ones used on the two sama5d2 board supported so far.

With this change, the DEBUG_LL baudrate is also no longer fixed at 115200,
but instead comes from the CONFIG_BAUDRATE symbol.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 .../arm/boards/sama5d27-giantboard/lowlevel.c |  11 +-
 arch/arm/boards/sama5d27-som1/lowlevel.c      |  11 +-
 arch/arm/mach-at91/include/mach/debug_ll.h    |  17 ++-
 arch/arm/mach-at91/include/mach/sama5d2.h     |  56 ++++++++++
 arch/arm/mach-at91/include/mach/sama5d2_ll.h  | 101 ++++++++++++++++++
 5 files changed, 172 insertions(+), 24 deletions(-)

diff --git a/arch/arm/boards/sama5d27-giantboard/lowlevel.c b/arch/arm/boards/sama5d27-giantboard/lowlevel.c
index 4419e946f1a8..a30441d7ccfa 100644
--- a/arch/arm/boards/sama5d27-giantboard/lowlevel.c
+++ b/arch/arm/boards/sama5d27-giantboard/lowlevel.c
@@ -18,16 +18,7 @@
 
 static void dbgu_init(void)
 {
-	unsigned mck = MASTER_CLOCK / 2;
-
-	sama5d2_pmc_enable_periph_clock(SAMA5D2_ID_PIOD);
-
-	at91_mux_pio4_set_A_periph(SAMA5D2_BASE_PIOD,
-				   pin_to_mask(AT91_PIN_PD3)); /* DBGU TXD */
-
-	sama5d2_pmc_enable_periph_clock(SAMA5D2_ID_UART1);
-
-	at91_dbgu_setup_ll(SAMA5D2_BASE_UART1, mck, 115200);
+	sama5d2_resetup_uart_console(MASTER_CLOCK);
 
 	putc_ll('>');
 }
diff --git a/arch/arm/boards/sama5d27-som1/lowlevel.c b/arch/arm/boards/sama5d27-som1/lowlevel.c
index b7780ec8ae43..2e408ce832f7 100644
--- a/arch/arm/boards/sama5d27-som1/lowlevel.c
+++ b/arch/arm/boards/sama5d27-som1/lowlevel.c
@@ -42,16 +42,7 @@ static void ek_turn_led(unsigned color)
 
 static void ek_dbgu_init(void)
 {
-	unsigned mck = MASTER_CLOCK / 2;
-
-	sama5d2_pmc_enable_periph_clock(SAMA5D2_ID_PIOD);
-
-	at91_mux_pio4_set_A_periph(SAMA5D2_BASE_PIOD,
-				   pin_to_mask(AT91_PIN_PD3)); /* DBGU TXD */
-
-	sama5d2_pmc_enable_periph_clock(SAMA5D2_ID_UART1);
-
-	at91_dbgu_setup_ll(SAMA5D2_BASE_UART1, mck, 115200);
+	sama5d2_resetup_uart_console(MASTER_CLOCK);
 
 	putc_ll('>');
 }
diff --git a/arch/arm/mach-at91/include/mach/debug_ll.h b/arch/arm/mach-at91/include/mach/debug_ll.h
index b71393042463..b3cbdbc26f1d 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/sama5d2.h b/arch/arm/mach-at91/include/mach/sama5d2.h
index ada9c59e0370..90b566ffc4ab 100644
--- a/arch/arm/mach-at91/include/mach/sama5d2.h
+++ b/arch/arm/mach-at91/include/mach/sama5d2.h
@@ -16,6 +16,8 @@
 
 #include <asm/io.h>
 #include <linux/sizes.h>
+#include <linux/bitops.h>
+#include <linux/bitfield.h>
 
 /*
  * Peripheral identifiers/interrupts. (Table 18-9)
@@ -261,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
index e6fa3914250b..96f3bc545284 100644
--- a/arch/arm/mach-at91/include/mach/sama5d2_ll.h
+++ b/arch/arm/mach-at91/include/mach/sama5d2_ll.h
@@ -3,6 +3,8 @@
 
 #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>
 
@@ -35,4 +37,103 @@ static inline int sama5d2_pmc_enable_generic_clock(unsigned int periph_id,
 					     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
-- 
2.27.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 30+ messages in thread

end of thread, other threads:[~2020-07-01  9:11 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-01  5:23 [PATCH 00/28] ARM: at91: add sama5d2 first stage support Ahmad Fatoum
2020-07-01  5:23 ` [PATCH 01/28] ARM: at91: remove <mach/hardware.h> include from assembly code Ahmad Fatoum
2020-07-01  5:23 ` [PATCH 02/28] ARM: at91: sama5d2: cast peripheral base addresses to __iomem pointers Ahmad Fatoum
2020-07-01  5:23 ` [PATCH 03/28] ARM: at91: import at91bootstrap's at91_ddrsdrc.h Ahmad Fatoum
2020-07-01  5:23 ` [PATCH 04/28] ARM: at91: migrate at91sam9_ddrsdr.h to use " Ahmad Fatoum
2020-07-01  5:23 ` [PATCH 05/28] ARM: at91: replace at91sam9_ddrsdr.h with " Ahmad Fatoum
2020-07-01  5:23 ` [PATCH 06/28] ARM: at91: import early_udelay from at91bootstrap Ahmad Fatoum
2020-07-01  5:23 ` [PATCH 07/28] ARM: at91: import low level DDRAMC initialization code " Ahmad Fatoum
2020-07-01  5:23 ` [PATCH 08/28] ARM: at91: watchdog: implement at91_wdt_disable Ahmad Fatoum
2020-07-01  5:23 ` [PATCH 09/28] watchdog: add support for at91sam9/sama5 watchdog Ahmad Fatoum
2020-07-01  5:23 ` [PATCH 10/28] ARM: at91: implement sama5d2 lowlevel init Ahmad Fatoum
2020-07-01  5:23 ` [PATCH 11/28] ARM: at91: sama5d2: add sama5d2 matrix configuration Ahmad Fatoum
2020-07-01  5:23 ` [PATCH 12/28] ARM: at91: add sama5d2 cache init Ahmad Fatoum
2020-07-01  5:23 ` [PATCH 13/28] ARM: at91: add necessary Advanced Interrupt Controller configuration Ahmad Fatoum
2020-07-01  5:23 ` [PATCH 14/28] ARM: at91: extend low level PMC driver for generic clk support Ahmad Fatoum
2020-07-01  5:23 ` [PATCH 15/28] pbl: add block I/O API Ahmad Fatoum
2020-07-01  5:23 ` [PATCH 16/28] fs: fat: extend for in-PBL support Ahmad Fatoum
2020-07-01  5:23 ` [PATCH 17/28] mci: extend atmel-sdhci driver to first stage use Ahmad Fatoum
2020-07-01  5:23 ` [PATCH 18/28] ARM: at91: add code for sama5 boot source detection Ahmad Fatoum
2020-07-01  5:23 ` [PATCH 19/28] ARM: at91: add helpers for chain-loading barebox from SD-card Ahmad Fatoum
2020-07-01  5:23 ` [PATCH 20/28] ARM: at91: sama5d2: reuse stack set-up by first stage Ahmad Fatoum
2020-07-01  5:23 ` [PATCH 21/28] at91: debug_ll: remove duplicated IS_ENABLED(CONFIG_DEBUG_LL) condition Ahmad Fatoum
2020-07-01  5:23 ` [PATCH 22/28] ARM: at91: sama5d2: reduce UART setup boilerplate with new helpers Ahmad Fatoum
2020-07-01  5:23 ` [PATCH 23/28] ARM: at91: sama5d27-som1: add additional first stage entry point Ahmad Fatoum
2020-07-01  5:23 ` [PATCH 24/28] ARM: at91: sama5d2: read back memory size from DDRAM controller Ahmad Fatoum
2020-07-01  5:23 ` [PATCH 25/28] ARM: at91: sama5d2: populate $bootsource and $bootsource_instance Ahmad Fatoum
2020-07-01  5:23 ` [PATCH 26/28] ARM: at91: sama5d27-som1-ek: add barebox_update and multi environment support Ahmad Fatoum
2020-07-01  5:23 ` [PATCH 27/28] ARM: at91: sama5d27-giantboard: add additional first stage entry point Ahmad Fatoum
2020-07-01  5:23 ` [PATCH 28/28] ARM: at91: sama5d27-giantboard: add default environment/bbu Ahmad Fatoum
2020-07-01  9:10 [PATCH RESEND 00/28] ARM: at91: add sama5d2 first stage support Ahmad Fatoum
2020-07-01  9:11 ` [PATCH 22/28] ARM: at91: sama5d2: reduce UART setup boilerplate with new helpers Ahmad Fatoum

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox