U-Boot
Threads by month
- ----- 2025 -----
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2000 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
October 2015
- 191 participants
- 624 discussions
The board supports following features:
- Boot media support: SD card/e.MMC/SPI flash,
- Support LCD display (optional, disabled by default),
- Support ethernet,
- Support USB mass storage.
Signed-off-by: Wenyou Yang <wenyou.yang(a)atmel.com>
---
The patch is based on the following patches sent in mailing list.
[PATCH] gpio: atmel: Add the PIO4 driver support
[PATCH] arm: at91: Change the Chip ID registers' addresses
[PATCH v2] mmc: atmel: Add atmel sdhci support
arch/arm/mach-at91/Kconfig | 5 +
arch/arm/mach-at91/armv7/Makefile | 1 +
arch/arm/mach-at91/armv7/sama5d2_devices.c | 59 +++++
arch/arm/mach-at91/include/mach/at91_pmc.h | 7 +-
arch/arm/mach-at91/include/mach/atmel_usba_udc.h | 3 +-
arch/arm/mach-at91/include/mach/hardware.h | 2 +
arch/arm/mach-at91/include/mach/sama5d2.h | 228 +++++++++++++++++
board/atmel/sama5d2_xplained/Kconfig | 15 ++
board/atmel/sama5d2_xplained/MAINTAINERS | 7 +
board/atmel/sama5d2_xplained/Makefile | 8 +
board/atmel/sama5d2_xplained/sama5d2_xplained.c | 294 ++++++++++++++++++++++
configs/sama5d2_xplained_mmc_defconfig | 10 +
configs/sama5d2_xplained_spiflash_defconfig | 10 +
include/configs/sama5d2_xplained.h | 192 ++++++++++++++
14 files changed, 836 insertions(+), 5 deletions(-)
create mode 100644 arch/arm/mach-at91/armv7/sama5d2_devices.c
create mode 100644 arch/arm/mach-at91/include/mach/sama5d2.h
create mode 100644 board/atmel/sama5d2_xplained/Kconfig
create mode 100644 board/atmel/sama5d2_xplained/MAINTAINERS
create mode 100644 board/atmel/sama5d2_xplained/Makefile
create mode 100644 board/atmel/sama5d2_xplained/sama5d2_xplained.c
create mode 100644 configs/sama5d2_xplained_mmc_defconfig
create mode 100644 configs/sama5d2_xplained_spiflash_defconfig
create mode 100644 include/configs/sama5d2_xplained.h
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index fdaf328..c333647 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -71,6 +71,10 @@ config TARGET_AT91SAM9X5EK
select CPU_ARM926EJS
select SUPPORT_SPL
+config TARGET_SAMA5D2_XPLAINED
+ bool "SAMA5D2 Xplained board"
+ select CPU_V7
+
config TARGET_SAMA5D3_XPLAINED
bool "SAMA5D3 Xplained board"
select CPU_V7
@@ -123,6 +127,7 @@ source "board/atmel/at91sam9m10g45ek/Kconfig"
source "board/atmel/at91sam9n12ek/Kconfig"
source "board/atmel/at91sam9rlek/Kconfig"
source "board/atmel/at91sam9x5ek/Kconfig"
+source "board/atmel/sama5d2_xplained/Kconfig"
source "board/atmel/sama5d3_xplained/Kconfig"
source "board/atmel/sama5d3xek/Kconfig"
source "board/atmel/sama5d4_xplained/Kconfig"
diff --git a/arch/arm/mach-at91/armv7/Makefile b/arch/arm/mach-at91/armv7/Makefile
index f4f35a4..de4a1e0 100644
--- a/arch/arm/mach-at91/armv7/Makefile
+++ b/arch/arm/mach-at91/armv7/Makefile
@@ -10,6 +10,7 @@
obj-$(CONFIG_SAMA5D3) += sama5d3_devices.o
obj-$(CONFIG_SAMA5D4) += sama5d4_devices.o
+obj-$(CONFIG_SAMA5D2) += sama5d2_devices.o
obj-y += clock.o
obj-y += cpu.o
obj-y += reset.o
diff --git a/arch/arm/mach-at91/armv7/sama5d2_devices.c b/arch/arm/mach-at91/armv7/sama5d2_devices.c
new file mode 100644
index 0000000..11e0fed
--- /dev/null
+++ b/arch/arm/mach-at91/armv7/sama5d2_devices.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2015 Atmel Corporation
+ * Wenyou Yang <wenyou.yang(a)atmel.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/at91_pmc.h>
+#include <asm/arch/clk.h>
+#include <asm/arch/sama5d2.h>
+
+char *get_cpu_name()
+{
+ unsigned int extension_id = get_extension_chip_id();
+
+ if (cpu_is_sama5d2()) {
+ switch (extension_id) {
+ case ARCH_EXID_SAMA5D21CU:
+ return "SAMA5D21";
+ case ARCH_EXID_SAMA5D22CU:
+ return "SAMA5D22-CU";
+ case ARCH_EXID_SAMA5D22CN:
+ return "SAMA5D22-CN";
+ case ARCH_EXID_SAMA5D23CU:
+ return "SAMA5D23-CU";
+ case ARCH_EXID_SAMA5D24CX:
+ return "SAMA5D24-CX";
+ case ARCH_EXID_SAMA5D24CU:
+ return "SAMA5D24-CU";
+ case ARCH_EXID_SAMA5D26CU:
+ return "SAMA5D26-CU";
+ case ARCH_EXID_SAMA5D27CU:
+ return "SAMA5D27-CU";
+ case ARCH_EXID_SAMA5D27CN:
+ return "SAMA5D27-CN";
+ case ARCH_EXID_SAMA5D28CU:
+ return "SAMA5D28-CU";
+ case ARCH_EXID_SAMA5D28CN:
+ return "SAMA5D28-CN";
+ default:
+ return "Unknown CPU type";
+ }
+ } else {
+ return "Unknown CPU type";
+ }
+}
+
+#ifdef CONFIG_USB_GADGET_ATMEL_USBA
+void at91_udp_hw_init(void)
+{
+ struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
+
+ writel(AT91_PMC_UPLLEN | AT91_PMC_BIASEN, &pmc->uckr);
+
+ at91_periph_clk_enable(ATMEL_ID_UDPHS);
+}
+#endif
diff --git a/arch/arm/mach-at91/include/mach/at91_pmc.h b/arch/arm/mach-at91/include/mach/at91_pmc.h
index 8a3fb94..4b2b1ac 100644
--- a/arch/arm/mach-at91/include/mach/at91_pmc.h
+++ b/arch/arm/mach-at91/include/mach/at91_pmc.h
@@ -78,7 +78,8 @@ typedef struct at91_pmc {
#define AT91_PMC_PLLXR_DIV(x) (x & 0xFF)
#define AT91_PMC_PLLXR_PLLCOUNT(x) ((x & 0x3F) << 8)
#define AT91_PMC_PLLXR_OUT(x) ((x & 0x03) << 14)
-#if defined(CONFIG_SAMA5D3) || defined(CONFIG_SAMA5D4)
+#if defined(CONFIG_SAMA5D3) || defined(CONFIG_SAMA5D4) || \
+ defined(CONFIG_SAMA5D2)
#define AT91_PMC_PLLXR_MUL(x) ((x & 0x7F) << 18)
#else
#define AT91_PMC_PLLXR_MUL(x) ((x & 0x7FF) << 16)
@@ -98,6 +99,7 @@ typedef struct at91_pmc {
#define AT91_PMC_MCKR_CSS_MASK 0x00000003
#if defined(CONFIG_SAMA5D3) || defined(CONFIG_SAMA5D4) || \
+ defined(CONFIG_SAMA5D2) || \
defined(CONFIG_AT91SAM9X5) || defined(CONFIG_AT91SAM9N12)
#define AT91_PMC_MCKR_PRES_1 0x00000000
#define AT91_PMC_MCKR_PRES_2 0x00000010
@@ -127,10 +129,7 @@ typedef struct at91_pmc {
#else
#define AT91_PMC_MCKR_MDIV_1 0x00000000
#define AT91_PMC_MCKR_MDIV_2 0x00000100
-#if defined(CONFIG_SAMA5D3) || defined(CONFIG_SAMA5D4) || \
- defined(CONFIG_AT91SAM9X5) || defined(CONFIG_AT91SAM9N12)
#define AT91_PMC_MCKR_MDIV_3 0x00000300
-#endif
#define AT91_PMC_MCKR_MDIV_4 0x00000200
#define AT91_PMC_MCKR_MDIV_MASK 0x00000300
#endif
diff --git a/arch/arm/mach-at91/include/mach/atmel_usba_udc.h b/arch/arm/mach-at91/include/mach/atmel_usba_udc.h
index 38b5012..ae564fa 100644
--- a/arch/arm/mach-at91/include/mach/atmel_usba_udc.h
+++ b/arch/arm/mach-at91/include/mach/atmel_usba_udc.h
@@ -31,7 +31,8 @@ static struct usba_ep_data usba_udc_ep[] = {
EP("ep5", 5, 1024, 3, 1, 1),
EP("ep6", 6, 1024, 3, 1, 1),
};
-#elif defined(CONFIG_SAMA5D3) || defined(CONFIG_SAMA5D4)
+#elif defined(CONFIG_SAMA5D3) || defined(CONFIG_SAMA5D4) || \
+ defined(CONFIG_SAMA5D2)
static struct usba_ep_data usba_udc_ep[] = {
EP("ep0", 0, 64, 1, 0, 0),
EP("ep1", 1, 1024, 3, 1, 0),
diff --git a/arch/arm/mach-at91/include/mach/hardware.h b/arch/arm/mach-at91/include/mach/hardware.h
index ff6b71b..0c0e8af 100644
--- a/arch/arm/mach-at91/include/mach/hardware.h
+++ b/arch/arm/mach-at91/include/mach/hardware.h
@@ -27,6 +27,8 @@
# include <asm/arch/sama5d3.h>
#elif defined(CONFIG_SAMA5D4)
# include <asm/arch/sama5d4.h>
+#elif defined(CONFIG_SAMA5D2)
+# include <asm/arch/sama5d2.h>
#else
# error "Unsupported AT91 processor"
#endif
diff --git a/arch/arm/mach-at91/include/mach/sama5d2.h b/arch/arm/mach-at91/include/mach/sama5d2.h
new file mode 100644
index 0000000..3dc39df
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/sama5d2.h
@@ -0,0 +1,228 @@
+/*
+ * Chip-specific header file for the SAMA5D2 SoC
+ *
+ * Copyright (C) 2015 Atmel
+ * Wenyou Yang <wenyou.yang(a)atmel.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __SAMA5D2_H
+#define __SAMA5D2_H
+
+/*
+ * defines to be used in other places
+ */
+#define CONFIG_AT91FAMILY /* It's a member of AT91 */
+
+/*
+ * Peripheral identifiers/interrupts.
+ */
+#define ATMEL_ID_FIQ 0 /* FIQ Interrupt ID */
+/* 1 */
+#define ATMEL_ID_ARM 2 /* Performance Monitor Unit */
+#define ATMEL_ID_PIT 3 /* Periodic Interval Timer Interrupt */
+#define ATMEL_ID_WDT 4 /* Watchdog Timer Interrupt */
+#define ATMEL_ID_GMAC 5 /* Ethernet MAC */
+#define ATMEL_ID_XDMAC0 6 /* DMA Controller 0 */
+#define ATMEL_ID_XDMAC1 7 /* DMA Controller 1 */
+#define ATMEL_ID_ICM 8 /* Integrity Check Monitor */
+#define ATMEL_ID_AES 9 /* Advanced Encryption Standard */
+#define ATMEL_ID_AESB 10 /* AES bridge */
+#define ATMEL_ID_TDES 11 /* Triple Data Encryption Standard */
+#define ATMEL_ID_SHA 12 /* SHA Signature */
+#define ATMEL_ID_MPDDRC 13 /* MPDDR Controller */
+#define ATMEL_ID_MATRIX1 14 /* H32MX, 32-bit AHB Matrix */
+#define ATMEL_ID_MATRIX0 15 /* H64MX, 64-bit AHB Matrix */
+#define ATMEL_ID_SECUMOD 16 /* Secure Module */
+#define ATMEL_ID_HSMC 17 /* Multi-bit ECC interrupt */
+#define ATMEL_ID_PIOA 18 /* Parallel I/O Controller A */
+#define ATMEL_ID_FLEXCOM0 19 /* FLEXCOM0 */
+#define ATMEL_ID_FLEXCOM1 20 /* FLEXCOM1 */
+#define ATMEL_ID_FLEXCOM2 21 /* FLEXCOM2 */
+#define ATMEL_ID_FLEXCOM3 22 /* FLEXCOM3 */
+#define ATMEL_ID_FLEXCOM4 23 /* FLEXCOM4 */
+#define ATMEL_ID_UART0 24 /* UART0 */
+#define ATMEL_ID_UART1 25 /* UART1 */
+#define ATMEL_ID_UART2 26 /* UART2 */
+#define ATMEL_ID_UART3 27 /* UART3 */
+#define ATMEL_ID_UART4 28 /* UART4 */
+#define ATMEL_ID_TWIHS0 29 /* Two-wire Interface 0 */
+#define ATMEL_ID_TWIHS1 30 /* Two-wire Interface 1 */
+#define ATMEL_ID_SDHCI0 31 /* SDMMC Controller 0 */
+#define ATMEL_ID_SDHCI1 32 /* SDMCC Controller 1 */
+#define ATMEL_ID_SPI0 33 /* Serial Peripheral Interface 0 */
+#define ATMEL_ID_SPI1 34 /* Serial Peripheral Interface 1 */
+#define ATMEL_ID_TC0 35 /* Timer Counter 0 (ch.0,1,2) */
+#define ATMEL_ID_TC1 36 /* Timer Counter 1 (ch.3,4,5) */
+/* 37 */
+#define ATMEL_ID_PWM 38 /* PWMController0 (ch. 0,1,2,3) */
+/* 39 */
+#define ATMEL_ID_ADC 40 /* Touch Screen ADC Controller */
+#define ATMEL_ID_UHPHS 41 /* USB Host High Speed */
+#define ATMEL_ID_UDPHS 42 /* USB Device High Speed */
+#define ATMEL_ID_SSC0 43 /* Serial Synchronous Controller 0 */
+#define ATMEL_ID_SSC1 44 /* Serial Synchronous Controller 1 */
+#define ATMEL_ID_LCDC 45 /* LCD Controller */
+#define ATMEL_ID_ISI 46 /* Image Sensor Interface */
+#define ATMEL_ID_TRNG 47 /* True Random Number Generator */
+#define ATMEL_ID_PDMIC 48 /* PDM Interface Controller */
+#define ATMEL_ID_IRQ 49 /* IRQ Interrupt ID */
+#define ATMEL_ID_SFC 50 /* Fuse Controller */
+#define ATMEL_ID_SECURAM 51 /* Secure RAM */
+#define ATMEL_ID_QSPI0 52 /* QSPI0 */
+#define ATMEL_ID_QSPI1 53 /* QSPI1 */
+#define ATMEL_ID_I2SC0 54 /* Inter-IC Sound Controller 0 */
+#define ATMEL_ID_I2SC1 55 /* Inter-IC Sound Controller 1 */
+#define ATMEL_ID_CAN0_INT0 56 /* MCAN 0 Interrupt0 */
+#define ATMEL_ID_CAN1_INT0 57 /* MCAN 1 Interrupt0 */
+#define ATMEL_ID_PTC 58 /* Peripheral Touch Controller */
+#define ATMEL_ID_CLASSD 59 /* Audio Class D Amplifier */
+#define ATMEL_ID_SFR 60 /* Special Function Register */
+#define ATMEL_ID_SAIC 61 /* Secured AIC */
+#define ATMEL_ID_AIC 62 /* Advanced Interrupt Controller */
+#define ATMEL_ID_L2CC 63 /* L2 Cache Controller */
+#define ATMEL_ID_CAN0_INT1 64 /* MCAN 0 Interrupt1 */
+#define ATMEL_ID_CAN1_INT1 65 /* MCAN 1 Interrupt1 */
+#define ATMEL_ID_GMAC_Q1 66 /* GMAC Queue 1 Interrupt */
+#define ATMEL_ID_GMAC_Q2 67 /* GMAC Queue 2 Interrupt */
+#define ATMEL_ID_PIOB 68 /* Parallel I/O Controller B */
+#define ATMEL_ID_PIOC 69 /* Parallel I/O Controller C */
+#define ATMEL_ID_PIOD 70 /* Parallel I/O Controller D */
+#define ATMEL_ID_SDHCI0_TIMER 71 /* SDMCC Controller 0 */
+#define ATMEL_ID_SDHCI1_TIMER 72 /* SDMCC Controller 1 */
+/* 73 */
+#define ATMEL_ID_SYS 74 /* System Controller Interrupt */
+#define ATMEL_ID_ACC 75 /* Analog Comparator */
+#define ATMEL_ID_RXLP 76 /* UART Low-Power */
+#define ATMEL_ID_SFRBU 77 /* Special Function Register BackUp */
+#define ATMEL_ID_CHIPID 78 /* Chip ID */
+
+/*
+ * User Peripherals physical base addresses.
+ */
+#define ATMEL_BASE_LCDC 0xf0000000
+#define ATMEL_BASE_XDMAC1 0xf0004000
+#define ATMEL_BASE_MPDDRC 0xf000c000
+#define ATMEL_BASE_XDMAC0 0xf0010000
+#define ATMEL_BASE_PMC 0xf0014000
+#define ATMEL_BASE_QSPI0 0xf0020000
+#define ATMEL_BASE_QSPI1 0xf0024000
+#define ATMEL_BASE_SPI0 0xf8000000
+#define ATMEL_BASE_GMAC 0xf8008000
+#define ATMEL_BASE_TC0 0xf800c000
+#define ATMEL_BASE_TC1 0xf8010000
+#define ATMEL_BASE_UART0 0xf801c000
+#define ATMEL_BASE_UART1 0xf8020000
+#define ATMEL_BASE_UART2 0xf8024000
+#define ATMEL_BASE_TWI0 0xf8028000
+#define ATMEL_BASE_SYSC 0xf8048000
+#define ATMEL_BASE_SPI1 0xfc000000
+#define ATMEL_BASE_UART3 0xfc008000
+#define ATMEL_BASE_UART4 0xfc00c000
+#define ATMEL_BASE_TWI1 0xfc028000
+#define ATMEL_BASE_UDPHS 0xfc02c000
+
+#define ATMEL_BASE_PIOA 0xfc038000
+
+#define ATMEL_CHIPID_CIDR 0xfc069000
+#define ATMEL_CHIPID_EXID 0xfc069004
+
+/*
+ * Address Memory Space
+ */
+#define ATMEL_BASE_DDRCS 0x20000000
+#define ATMEL_BASE_QSPI0_AES_MEM 0x90000000
+#define ATMEL_BASE_QSPI1_AES_MEM 0x98000000
+#define ATMEL_BASE_SDHCI0 0xa0000000
+#define ATMEL_BASE_SDHCI1 0xb0000000
+#define ATMEL_BASE_QSPI0_MEM 0xd0000000
+#define ATMEL_BASE_QSPI1_MEM 0xd8000000
+
+/*
+ * Internal Memories
+ */
+#define ATMEL_BASE_UDPHS_FIFO 0x00300000 /* USB Device HS controller */
+#define ATMEL_BASE_OHCI 0x00400000 /* USB Host controller (OHCI) */
+#define ATMEL_BASE_EHCI 0x00500000 /* USB Host controller (EHCI) */
+
+/* Other misc defines */
+#define ATMEL_BASE_PMECC (ATMEL_BASE_HSMC + 0x70)
+#define ATMEL_BASE_PMERRLOC (ATMEL_BASE_HSMC + 0x500)
+
+#define AT91_PMECC (ATMEL_BASE_PMECC - ATMEL_BASE_SYS)
+#define AT91_PMERRLOC (ATMEL_BASE_PMERRLOC - ATMEL_BASE_SYS)
+
+#define ATMEL_BASE_PIOB (ATMEL_BASE_PIOA + 0x40)
+#define ATMEL_BASE_PIOC (ATMEL_BASE_PIOB + 0x40)
+#define ATMEL_BASE_PIOD (ATMEL_BASE_PIOC + 0x40)
+
+/* SYSC spawns */
+#define ATMEL_BASE_RSTC ATMEL_BASE_SYSC
+#define ATMEL_BASE_SHDC (ATMEL_BASE_SYSC + 0x10)
+#define ATMEL_BASE_PIT (ATMEL_BASE_SYSC + 0x30)
+#define ATMEL_BASE_WDT (ATMEL_BASE_SYSC + 0x40)
+#define ATMEL_SYS_SCKCR (ATMEL_BASE_SYSC + 0x50)
+#define ATMEL_BASE_RTCC (ATMEL_BASE_SYSC + 0xb0)
+
+#define ATMEL_BASE_SMC (ATMEL_BASE_HSMC + 0x600)
+
+/*
+ * Other misc defines
+ */
+#define ATMEL_PIO_PORTS 4
+#define CPU_HAS_PCR
+#define CPU_HAS_H32MXDIV
+
+/* SAMA5D2 series chip id definitions */
+#define ARCH_ID_SAMA5D2 0x8a5c08c0
+#define ARCH_EXID_SAMA5D21CU 0x0000005a
+#define ARCH_EXID_SAMA5D22CU 0x00000059
+#define ARCH_EXID_SAMA5D22CN 0x00000069
+#define ARCH_EXID_SAMA5D23CU 0x00000058
+#define ARCH_EXID_SAMA5D24CX 0x00000004
+#define ARCH_EXID_SAMA5D24CU 0x00000014
+#define ARCH_EXID_SAMA5D26CU 0x00000012
+#define ARCH_EXID_SAMA5D27CU 0x00000011
+#define ARCH_EXID_SAMA5D27CN 0x00000021
+#define ARCH_EXID_SAMA5D28CU 0x00000010
+#define ARCH_EXID_SAMA5D28CN 0x00000020
+
+#define cpu_is_sama5d2() (get_chip_id() == ARCH_ID_SAMA5D2)
+#define cpu_is_sama5d21cu() (cpu_is_sama5d2() && \
+ (get_extension_chip_id() == ARCH_EXID_SAMA5D21CU))
+#define cpu_is_sama5d22cu() (cpu_is_sama5d2() && \
+ (get_extension_chip_id() == ARCH_EXID_SAMA5D22CU))
+#define cpu_is_sama5d22cn() (cpu_is_sama5d2() && \
+ (get_extension_chip_id() == ARCH_EXID_SAMA5D22CN))
+#define cpu_is_sama5d23cu() (cpu_is_sama5d2() && \
+ (get_extension_chip_id() == ARCH_EXID_SAMA5D23CU))
+#define cpu_is_sama5d24cx() (cpu_is_sama5d2() && \
+ (get_extension_chip_id() == ARCH_EXID_SAMA5D24CX))
+#define cpu_is_sama5d24cu() (cpu_is_sama5d2() && \
+ (get_extension_chip_id() == ARCH_EXID_SAMA5D24CU))
+#define cpu_is_sama5d26cu() (cpu_is_sama5d2() && \
+ (get_extension_chip_id() == ARCH_EXID_SAMA5D26CU))
+#define cpu_is_sama5d27cu() (cpu_is_sama5d2() && \
+ (get_extension_chip_id() == ARCH_EXID_SAMA5D27CU))
+#define cpu_is_sama5d27cn() (cpu_is_sama5d2() && \
+ (get_extension_chip_id() == ARCH_EXID_SAMA5D27CN))
+#define cpu_is_sama5d28cu() (cpu_is_sama5d2() && \
+ (get_extension_chip_id() == ARCH_EXID_SAMA5D28CU))
+#define cpu_is_sama5d28cn() (cpu_is_sama5d2() && \
+ (get_extension_chip_id() == ARCH_EXID_SAMA5D28CN))
+
+/* PIT Timer(PIT_PIIR) */
+#define CONFIG_SYS_TIMER_COUNTER 0xf804803c
+
+/* No PMECC Galois table in ROM */
+#define NO_GALOIS_TABLE_IN_ROM
+
+#ifndef __ASSEMBLY__
+unsigned int get_chip_id(void);
+unsigned int get_extension_chip_id(void);
+unsigned int has_lcdc(void);
+char *get_cpu_name(void);
+#endif
+
+#endif
diff --git a/board/atmel/sama5d2_xplained/Kconfig b/board/atmel/sama5d2_xplained/Kconfig
new file mode 100644
index 0000000..55712e9
--- /dev/null
+++ b/board/atmel/sama5d2_xplained/Kconfig
@@ -0,0 +1,15 @@
+if TARGET_SAMA5D2_XPLAINED
+
+config SYS_BOARD
+ default "sama5d2_xplained"
+
+config SYS_VENDOR
+ default "atmel"
+
+config SYS_SOC
+ default "at91"
+
+config SYS_CONFIG_NAME
+ default "sama5d2_xplained"
+
+endif
diff --git a/board/atmel/sama5d2_xplained/MAINTAINERS b/board/atmel/sama5d2_xplained/MAINTAINERS
new file mode 100644
index 0000000..ff9c86f
--- /dev/null
+++ b/board/atmel/sama5d2_xplained/MAINTAINERS
@@ -0,0 +1,7 @@
+SAMA5D2 XPLAINED BOARD
+M: Wenyou Yang <wenyou.yang(a)atmel.com>
+S: Maintained
+F: board/atmel/sama5d2_xplained/
+F: include/configs/sama5d2_xplained.h
+F: configs/sama5d2_xplained_mmc_defconfig
+F: configs/sama5d2_xplained_spiflash_defconfig
diff --git a/board/atmel/sama5d2_xplained/Makefile b/board/atmel/sama5d2_xplained/Makefile
new file mode 100644
index 0000000..420870b
--- /dev/null
+++ b/board/atmel/sama5d2_xplained/Makefile
@@ -0,0 +1,8 @@
+#
+# Copyright (C) 2015 Atmel Corporation
+# Wenyou Yang <wenyou.yang(a)atmel.com>
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-y += sama5d2_xplained.o
diff --git a/board/atmel/sama5d2_xplained/sama5d2_xplained.c b/board/atmel/sama5d2_xplained/sama5d2_xplained.c
new file mode 100644
index 0000000..879c6cc
--- /dev/null
+++ b/board/atmel/sama5d2_xplained/sama5d2_xplained.c
@@ -0,0 +1,294 @@
+/*
+ * Copyright (C) 2015 Atmel Corporation
+ * Wenyou.Yang <wenyou.yang(a)atmel.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <atmel_hlcdc.h>
+#include <lcd.h>
+#include <mmc.h>
+#include <net.h>
+#include <netdev.h>
+#include <spi.h>
+#include <version.h>
+#include <asm/io.h>
+#include <asm/arch/at91_common.h>
+#include <asm/arch/at91_pmc.h>
+#include <asm/arch/atmel_pio4.h>
+#include <asm/arch/atmel_usba_udc.h>
+#include <asm/arch/atmel_sdhci.h>
+#include <asm/arch/clk.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/sama5d2.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifdef CONFIG_ATMEL_SPI
+int spi_cs_is_valid(unsigned int bus, unsigned int cs)
+{
+ return bus == 0 && cs == 0;
+}
+
+void spi_cs_activate(struct spi_slave *slave)
+{
+ atmel_pio4_set_pio_output(AT91_PIO_PORTA, 17, 0);
+}
+
+void spi_cs_deactivate(struct spi_slave *slave)
+{
+ atmel_pio4_set_pio_output(AT91_PIO_PORTA, 17, 1);
+}
+
+static void board_spi0_hw_init(void)
+{
+ atmel_pio4_set_a_periph(AT91_PIO_PORTA, 14, 0);
+ atmel_pio4_set_a_periph(AT91_PIO_PORTA, 15, 0);
+ atmel_pio4_set_a_periph(AT91_PIO_PORTA, 16, 0);
+
+ atmel_pio4_set_pio_output(AT91_PIO_PORTA, 17, 1);
+
+ at91_periph_clk_enable(ATMEL_ID_SPI0);
+}
+#endif
+
+#ifdef CONFIG_CMD_USB
+static void board_usb_hw_init(void)
+{
+ atmel_pio4_set_pio_output(AT91_PIO_PORTB, 9, 1);
+ atmel_pio4_set_pio_output(AT91_PIO_PORTB, 10, 1);
+}
+#endif
+
+#ifdef CONFIG_LCD
+vidinfo_t panel_info = {
+ .vl_col = 480,
+ .vl_row = 272,
+ .vl_clk = 9000000,
+ .vl_bpix = LCD_BPP,
+ .vl_tft = 1,
+ .vl_hsync_len = 41,
+ .vl_left_margin = 2,
+ .vl_right_margin = 2,
+ .vl_vsync_len = 11,
+ .vl_upper_margin = 2,
+ .vl_lower_margin = 2,
+ .mmio = ATMEL_BASE_LCDC,
+};
+
+/* No power up/down pin for the LCD pannel */
+void lcd_enable(void) { /* Empty! */ }
+void lcd_disable(void) { /* Empty! */ }
+
+unsigned int has_lcdc(void)
+{
+ return 1;
+}
+
+static void board_lcd_hw_init(void)
+{
+ atmel_pio4_set_a_periph(AT91_PIO_PORTC, 28, 0); /* LCDPWM */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTC, 29, 0); /* LCDDISP */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTC, 30, 0); /* LCDVSYNC */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTC, 31, 0); /* LCDHSYNC */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTD, 0, 0); /* LCDPCK */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTD, 1, 0); /* LCDDEN */
+
+ /* LCDDAT0 */
+ /* LCDDAT1 */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTC, 10, 0); /* LCDDAT2 */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTC, 11, 0); /* LCDDAT3 */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTC, 12, 0); /* LCDDAT4 */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTC, 13, 0); /* LCDDAT5 */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTC, 14, 0); /* LCDDAT6 */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTC, 15, 0); /* LCDDAT7 */
+
+ /* LCDDAT8 */
+ /* LCDDAT9 */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTC, 16, 0); /* LCDDAT10 */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTC, 17, 0); /* LCDDAT11 */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTC, 18, 0); /* LCDDAT12 */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTC, 19, 0); /* LCDDAT13 */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTC, 20, 0); /* LCDDAT14 */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTC, 21, 0); /* LCDDAT15 */
+
+ /* LCDD16 */
+ /* LCDD17 */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTC, 22, 0); /* LCDDAT18 */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTC, 23, 0); /* LCDDAT19 */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTC, 24, 0); /* LCDDAT20 */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTC, 25, 0); /* LCDDAT21 */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTC, 26, 0); /* LCDDAT22 */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTC, 27, 0); /* LCDDAT23 */
+
+ at91_periph_clk_enable(ATMEL_ID_LCDC);
+}
+
+#ifdef CONFIG_LCD_INFO
+void lcd_show_board_info(void)
+{
+ ulong dram_size;
+ int i;
+ char temp[32];
+
+ lcd_printf("%s\n", U_BOOT_VERSION);
+ lcd_printf("2015 ATMEL Corp\n");
+ lcd_printf("%s CPU at %s MHz\n", get_cpu_name(),
+ strmhz(temp, get_cpu_clk_rate()));
+
+ dram_size = 0;
+ for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++)
+ dram_size += gd->bd->bi_dram[i].size;
+
+ lcd_printf("%ld MB SDRAM\n", dram_size >> 20);
+}
+#endif
+#endif
+
+#ifdef CONFIG_MACB
+static void board_gmac_hw_init(void)
+{
+ atmel_pio4_set_f_periph(AT91_PIO_PORTB, 14, 0); /* GTXCK */
+ atmel_pio4_set_f_periph(AT91_PIO_PORTB, 15, 0); /* GTXEN */
+ atmel_pio4_set_f_periph(AT91_PIO_PORTB, 16, 0); /* GRXDV */
+ atmel_pio4_set_f_periph(AT91_PIO_PORTB, 17, 0); /* GRXER */
+ atmel_pio4_set_f_periph(AT91_PIO_PORTB, 18, 0); /* GRX0 */
+ atmel_pio4_set_f_periph(AT91_PIO_PORTB, 19, 0); /* GRX1 */
+ atmel_pio4_set_f_periph(AT91_PIO_PORTB, 20, 0); /* GTX0 */
+ atmel_pio4_set_f_periph(AT91_PIO_PORTB, 21, 0); /* GTX1 */
+ atmel_pio4_set_f_periph(AT91_PIO_PORTB, 22, 0); /* GMDC */
+ atmel_pio4_set_f_periph(AT91_PIO_PORTB, 23, 0); /* GMDIO */
+
+ at91_periph_clk_enable(ATMEL_ID_GMAC);
+}
+#endif
+
+#ifdef CONFIG_ATMEL_SDHCI
+#ifdef CONFIG_ATMEL_SDHCI0
+static void board_sdhci0_hw_init(void)
+{
+ atmel_pio4_set_a_periph(AT91_PIO_PORTA, 0, 0); /* SDMMC0_CK */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTA, 1, 0); /* SDMMC0_CMD */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTA, 2, 0); /* SDMMC0_DAT0 */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTA, 3, 0); /* SDMMC0_DAT1 */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTA, 4, 0); /* SDMMC0_DAT2 */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTA, 5, 0); /* SDMMC0_DAT3 */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTA, 6, 0); /* SDMMC0_DAT4 */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTA, 7, 0); /* SDMMC0_DAT5 */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTA, 8, 0); /* SDMMC0_DAT6 */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTA, 9, 0); /* SDMMC0_DAT7 */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTA, 10, 0); /* SDMMC0_RSTN */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTA, 11, 0); /* SDMMC0_VDDSEL */
+
+ at91_periph_clk_enable(ATMEL_ID_SDHCI0);
+ at91_enable_periph_generated_clk(ATMEL_ID_SDHCI0);
+}
+#endif
+
+#ifdef CONFIG_ATMEL_SDHCI1
+static void board_sdhci1_hw_init(void)
+{
+ atmel_pio4_set_e_periph(AT91_PIO_PORTA, 18, 0); /* SDMMC1_DAT0 */
+ atmel_pio4_set_e_periph(AT91_PIO_PORTA, 19, 0); /* SDMMC1_DAT1 */
+ atmel_pio4_set_e_periph(AT91_PIO_PORTA, 20, 0); /* SDMMC1_DAT2 */
+ atmel_pio4_set_e_periph(AT91_PIO_PORTA, 21, 0); /* SDMMC1_DAT3 */
+ atmel_pio4_set_e_periph(AT91_PIO_PORTA, 22, 0); /* SDMMC1_CK */
+ atmel_pio4_set_e_periph(AT91_PIO_PORTA, 27, 0); /* SDMMC1_RSTN */
+ atmel_pio4_set_e_periph(AT91_PIO_PORTA, 28, 0); /* SDMMC1_CMD */
+ atmel_pio4_set_e_periph(AT91_PIO_PORTA, 30, 0); /* SDMMC1_CD */
+
+ at91_periph_clk_enable(ATMEL_ID_SDHCI1);
+ at91_enable_periph_generated_clk(ATMEL_ID_SDHCI1);
+}
+#endif
+
+int board_mmc_init(bd_t *bis)
+{
+#ifdef CONFIG_ATMEL_SDHCI0
+ atmel_sdhci_init((void *)ATMEL_BASE_SDHCI0, ATMEL_ID_SDHCI0);
+#endif
+#ifdef CONFIG_ATMEL_SDHCI1
+ atmel_sdhci_init((void *)ATMEL_BASE_SDHCI1, ATMEL_ID_SDHCI1);
+#endif
+
+ return 0;
+}
+#endif
+
+static void board_uart1_hw_init(void)
+{
+ atmel_pio4_set_a_periph(AT91_PIO_PORTD, 2, 1); /* URXD1 */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTD, 3, 0); /* UTXD1 */
+
+ at91_periph_clk_enable(ATMEL_ID_UART1);
+}
+
+int board_early_init_f(void)
+{
+ at91_periph_clk_enable(ATMEL_ID_PIOA);
+ at91_periph_clk_enable(ATMEL_ID_PIOB);
+ at91_periph_clk_enable(ATMEL_ID_PIOC);
+ at91_periph_clk_enable(ATMEL_ID_PIOD);
+
+ board_uart1_hw_init();
+
+ return 0;
+}
+
+int board_init(void)
+{
+ /* adress of boot parameters */
+ gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
+
+#ifdef CONFIG_ATMEL_SPI
+ board_spi0_hw_init();
+#endif
+#ifdef CONFIG_ATMEL_SDHCI
+#ifdef CONFIG_ATMEL_SDHCI0
+ board_sdhci0_hw_init();
+#endif
+#ifdef CONFIG_ATMEL_SDHCI1
+ board_sdhci1_hw_init();
+#endif
+#endif
+#ifdef CONFIG_MACB
+ board_gmac_hw_init();
+#endif
+#ifdef CONFIG_LCD
+ board_lcd_hw_init();
+#endif
+#ifdef CONFIG_CMD_USB
+ board_usb_hw_init();
+#endif
+#ifdef CONFIG_USB_GADGET_ATMEL_USBA
+ at91_udp_hw_init();
+#endif
+
+ return 0;
+}
+
+int dram_init(void)
+{
+ gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE,
+ CONFIG_SYS_SDRAM_SIZE);
+ return 0;
+}
+
+int board_eth_init(bd_t *bis)
+{
+ int rc = 0;
+
+#ifdef CONFIG_MACB
+ rc = macb_eth_initialize(0, (void *)ATMEL_BASE_GMAC, 0x00);
+#endif
+
+#ifdef CONFIG_USB_GADGET_ATMEL_USBA
+ usba_udc_probe(&pdata);
+#ifdef CONFIG_USB_ETH_RNDIS
+ usb_eth_initialize(bis);
+#endif
+#endif
+
+ return rc;
+}
diff --git a/configs/sama5d2_xplained_mmc_defconfig b/configs/sama5d2_xplained_mmc_defconfig
new file mode 100644
index 0000000..f0a0bb0
--- /dev/null
+++ b/configs/sama5d2_xplained_mmc_defconfig
@@ -0,0 +1,10 @@
+CONFIG_ARM=y
+CONFIG_ARCH_AT91=y
+CONFIG_TARGET_SAMA5D2_XPLAINED=y
+CONFIG_SYS_EXTRA_OPTIONS="SAMA5D2,SYS_USE_MMC"
+# CONFIG_CMD_IMI is not set
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_LOADS is not set
+# CONFIG_CMD_FLASH is not set
+# CONFIG_CMD_FPGA is not set
+CONFIG_SPI_FLASH=y
diff --git a/configs/sama5d2_xplained_spiflash_defconfig b/configs/sama5d2_xplained_spiflash_defconfig
new file mode 100644
index 0000000..9d2174c
--- /dev/null
+++ b/configs/sama5d2_xplained_spiflash_defconfig
@@ -0,0 +1,10 @@
+CONFIG_ARM=y
+CONFIG_ARCH_AT91=y
+CONFIG_TARGET_SAMA5D2_XPLAINED=y
+CONFIG_SYS_EXTRA_OPTIONS="SAMA5D2,SYS_USE_SERIALFLASH"
+# CONFIG_CMD_IMI is not set
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_LOADS is not set
+# CONFIG_CMD_FLASH is not set
+# CONFIG_CMD_FPGA is not set
+CONFIG_SPI_FLASH=y
diff --git a/include/configs/sama5d2_xplained.h b/include/configs/sama5d2_xplained.h
new file mode 100644
index 0000000..40b7b77
--- /dev/null
+++ b/include/configs/sama5d2_xplained.h
@@ -0,0 +1,192 @@
+/*
+ * Configuration file for the SAMA5D2 Xplained Board.
+ *
+ * Copyright (C) 2015 Atmel Corporation
+ * Wenyou Yang <wenyou.yang(a)atmel.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/* No NOR flash, this definition should put before common header */
+#define CONFIG_SYS_NO_FLASH
+
+#include "at91-sama5_common.h"
+
+/* serial console */
+#define CONFIG_ATMEL_USART
+#define CONFIG_USART_BASE ATMEL_BASE_UART1
+#define CONFIG_USART_ID ATMEL_ID_UART1
+
+/* SDRAM */
+#define CONFIG_NR_DRAM_BANKS 1
+#define CONFIG_SYS_SDRAM_BASE ATMEL_BASE_DDRCS
+#define CONFIG_SYS_SDRAM_SIZE 0x20000000
+
+#ifdef CONFIG_SPL_BUILD
+#define CONFIG_SYS_INIT_SP_ADDR 0x210000
+#else
+#define CONFIG_SYS_INIT_SP_ADDR \
+ (CONFIG_SYS_SDRAM_BASE + 4 * 1024 - GENERATED_GBL_DATA_SIZE)
+#endif
+
+#define CONFIG_SYS_LOAD_ADDR 0x22000000 /* load address */
+
+#undef CONFIG_AT91_GPIO
+#define CONFIG_ATMEL_PIO4
+
+/* SerialFlash */
+#define CONFIG_CMD_SF
+
+#ifdef CONFIG_CMD_SF
+#define CONFIG_ATMEL_SPI
+#define CONFIG_ATMEL_SPI0
+#define CONFIG_SPI_FLASH_ATMEL
+#define CONFIG_SF_DEFAULT_BUS 0
+#define CONFIG_SF_DEFAULT_CS 0
+#define CONFIG_SF_DEFAULT_SPEED 30000000
+#endif
+
+/* NAND flash */
+#undef CONFIG_CMD_NAND
+
+#ifdef CONFIG_CMD_NAND
+#define CONFIG_NAND_ATMEL
+#define CONFIG_SYS_MAX_NAND_DEVICE 1
+#define CONFIG_SYS_NAND_BASE ATMEL_BASE_CS3
+/* our ALE is AD21 */
+#define CONFIG_SYS_NAND_MASK_ALE (1 << 21)
+/* our CLE is AD22 */
+#define CONFIG_SYS_NAND_MASK_CLE (1 << 22)
+#define CONFIG_SYS_NAND_ONFI_DETECTION
+/* PMECC & PMERRLOC */
+#define CONFIG_ATMEL_NAND_HWECC
+#define CONFIG_ATMEL_NAND_HW_PMECC
+#endif
+
+/* MMC */
+#define CONFIG_CMD_MMC
+
+#ifdef CONFIG_CMD_MMC
+#define CONFIG_MMC
+#define CONFIG_GENERIC_MMC
+#define CONFIG_SDHCI
+#define CONFIG_ATMEL_SDHCI
+#define CONFIG_ATMEL_SDHCI0
+#define CONFIG_ATMEL_SDHCI1
+#define CONFIG_SUPPORT_EMMC_BOOT
+#endif
+
+/* USB */
+#define CONFIG_CMD_USB
+
+#ifdef CONFIG_CMD_USB
+#define CONFIG_USB_EHCI
+#define CONFIG_USB_EHCI_ATMEL
+#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 3
+#define CONFIG_USB_STORAGE
+#endif
+
+/* USB device */
+#define CONFIG_USB_GADGET
+#define CONFIG_USB_GADGET_DUALSPEED
+#define CONFIG_USB_GADGET_ATMEL_USBA
+#define CONFIG_USB_ETHER
+#define CONFIG_USB_ETH_RNDIS
+#define CONFIG_USBNET_MANUFACTURER "Atmel SAMA5D2 XPlained"
+
+#if defined(CONFIG_CMD_USB) || defined(CONFIG_CMD_MMC)
+#define CONFIG_CMD_FAT
+#define CONFIG_DOS_PARTITION
+#endif
+
+/* Ethernet Hardware */
+#define CONFIG_MACB
+#define CONFIG_RMII
+#define CONFIG_NET_RETRY_COUNT 20
+#define CONFIG_MACB_SEARCH_PHY
+
+/* LCD */
+/* #define CONFIG_LCD */
+
+#ifdef CONFIG_LCD
+#define LCD_BPP LCD_COLOR16
+#define LCD_OUTPUT_BPP 24
+#define CONFIG_LCD_LOGO
+#define CONFIG_LCD_INFO
+#define CONFIG_LCD_INFO_BELOW_LOGO
+#define CONFIG_SYS_WHITE_ON_BLACK
+#define CONFIG_ATMEL_HLCD
+#define CONFIG_ATMEL_LCD_RGB565
+#define CONFIG_SYS_CONSOLE_IS_IN_ENV
+#endif
+
+#ifdef CONFIG_SYS_USE_SERIALFLASH
+/* bootstrap + u-boot + env + linux in serial flash */
+#define CONFIG_ENV_IS_IN_SPI_FLASH
+#define CONFIG_ENV_SPI_BUS CONFIG_SF_DEFAULT_BUS
+#define CONFIG_ENV_SPI_CS CONFIG_SF_DEFAULT_CS
+#define CONFIG_ENV_OFFSET 0x4000
+#define CONFIG_ENV_SIZE 0x4000
+#define CONFIG_ENV_SECT_SIZE 0x1000
+#define CONFIG_BOOTCOMMAND "sf probe 0; " \
+ "sf read 0x21000000 0x60000 0xc000; " \
+ "sf read 0x22000000 0x6c000 0x394000; " \
+ "bootz 0x22000000 - 0x21000000"
+
+#elif CONFIG_SYS_USE_NANDFLASH
+/* bootstrap + u-boot + env in nandflash */
+#define CONFIG_ENV_IS_IN_NAND
+#define CONFIG_ENV_OFFSET 0xc0000
+#define CONFIG_ENV_OFFSET_REDUND 0x100000
+#define CONFIG_ENV_SIZE 0x20000
+#define CONFIG_BOOTCOMMAND "nand read 0x21000000 0x180000 0x80000;" \
+ "nand read 0x22000000 0x200000 0x600000;" \
+ "bootz 0x22000000 - 0x21000000"
+
+#elif CONFIG_SYS_USE_MMC
+
+#undef CONFIG_ENV_IS_IN_FAT
+#undef CONFIG_FAT_WRITE
+#undef FAT_ENV_INTERFACE
+#undef FAT_ENV_DEVICE_AND_PART
+#undef FAT_ENV_FILE
+#undef CONFIG_ENV_SIZE
+#undef CONFIG_BOOTCOMMAND
+
+/* bootstrap + u-boot + env in sd card */
+#define CONFIG_ENV_IS_IN_FAT
+#define CONFIG_FAT_WRITE
+#define FAT_ENV_INTERFACE "mmc"
+/*
+ * We don't specify the part number, if device 0 has partition table, it means
+ * the first partition; it no partition table, then take whole device as a
+ * FAT file system.
+ */
+#define FAT_ENV_DEVICE_AND_PART "1"
+#define FAT_ENV_FILE "uboot.env"
+#define CONFIG_ENV_SIZE 0x4000
+#define CONFIG_BOOTCOMMAND "fatload mmc 1:1 0x21000000 at91-sama5d2_xplained.dtb; " \
+ "fatload mmc 1:1 0x22000000 zImage; " \
+ "bootz 0x22000000 - 0x21000000"
+#endif
+
+#ifdef CONFIG_BOOTARGS
+#undef CONFIG_BOOTARGS
+#endif
+
+#ifdef CONFIG_SYS_USE_MMC
+#define CONFIG_BOOTARGS \
+ "console=ttyS0,115200 earlyprintk root=/dev/mmcblk1p2 rw rootwait"
+#else
+#define CONFIG_BOOTARGS \
+ "console=ttyS0,115200 earlyprintk " \
+ "mtdparts=atmel_nand:256k(bootstrap)ro,512k(uboot)ro," \
+ "256K(env),256k(evn_redundent),256k(spare)," \
+ "512k(dtb),6M(kernel)ro,-(rootfs) " \
+ "rootfstype=ubifs ubi.mtd=7 root=ubi0:rootfs"
+#endif
+
+#endif
--
1.7.9.5
3
3
The board supports following features:
- Boot media support: SD card/e.MMC/SPI flash,
- Support LCD display (optional, disabled by default),
- Support ethernet,
- Support USB mass storage.
Signed-off-by: Wenyou Yang <wenyou.yang(a)atmel.com>
---
The patch is based on the following patches sent in mailing list.
[PATCH] gpio: atmel: Add the PIO4 driver support
[PATCH] arm: at91: Change the Chip ID registers' addresses
[PATCH v3] mmc: atmel: Add atmel sdhci support
[PATCH v2] arm: at91: clock: Add the generated clock support
Changes in v3:
1./ change defines-->definitions for more clearly in asm/arch/sama5d2.h.
2./ remove unused cpu_is_sama5d2x() macros.
3./ fix spelling error "adress".
4./ add __weak attribute for has_lcdc().
5./ remove SPL configs.
Changes in v2:
1./ re-order SAMA5D2 statements alphabetically.
2./ remove redundant "Unknown CPU type".
3./ rework sama5d2's macros.
4./ remove some #ifdef before functions.
5./ move CONFIG_CMD_SF to Kconfig.
6./ remove NAND macros from config file.
7./ CONFIG_BOOTCOMMAND for sf uses defines in at91-sama5_common.h.
arch/arm/mach-at91/Kconfig | 5 +
arch/arm/mach-at91/armv7/Makefile | 1 +
arch/arm/mach-at91/armv7/sama5d2_devices.c | 60 +++++
arch/arm/mach-at91/include/mach/at91_pmc.h | 9 +-
arch/arm/mach-at91/include/mach/atmel_usba_udc.h | 3 +-
arch/arm/mach-at91/include/mach/hardware.h | 2 +
arch/arm/mach-at91/include/mach/sama5d2.h | 203 ++++++++++++++++
board/atmel/sama5d2_xplained/Kconfig | 15 ++
board/atmel/sama5d2_xplained/MAINTAINERS | 7 +
board/atmel/sama5d2_xplained/Makefile | 8 +
board/atmel/sama5d2_xplained/sama5d2_xplained.c | 282 ++++++++++++++++++++++
configs/sama5d2_xplained_mmc_defconfig | 11 +
configs/sama5d2_xplained_spiflash_defconfig | 11 +
include/configs/sama5d2_xplained.h | 122 ++++++++++
14 files changed, 733 insertions(+), 6 deletions(-)
create mode 100644 arch/arm/mach-at91/armv7/sama5d2_devices.c
create mode 100644 arch/arm/mach-at91/include/mach/sama5d2.h
create mode 100644 board/atmel/sama5d2_xplained/Kconfig
create mode 100644 board/atmel/sama5d2_xplained/MAINTAINERS
create mode 100644 board/atmel/sama5d2_xplained/Makefile
create mode 100644 board/atmel/sama5d2_xplained/sama5d2_xplained.c
create mode 100644 configs/sama5d2_xplained_mmc_defconfig
create mode 100644 configs/sama5d2_xplained_spiflash_defconfig
create mode 100644 include/configs/sama5d2_xplained.h
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index fdaf328..c333647 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -71,6 +71,10 @@ config TARGET_AT91SAM9X5EK
select CPU_ARM926EJS
select SUPPORT_SPL
+config TARGET_SAMA5D2_XPLAINED
+ bool "SAMA5D2 Xplained board"
+ select CPU_V7
+
config TARGET_SAMA5D3_XPLAINED
bool "SAMA5D3 Xplained board"
select CPU_V7
@@ -123,6 +127,7 @@ source "board/atmel/at91sam9m10g45ek/Kconfig"
source "board/atmel/at91sam9n12ek/Kconfig"
source "board/atmel/at91sam9rlek/Kconfig"
source "board/atmel/at91sam9x5ek/Kconfig"
+source "board/atmel/sama5d2_xplained/Kconfig"
source "board/atmel/sama5d3_xplained/Kconfig"
source "board/atmel/sama5d3xek/Kconfig"
source "board/atmel/sama5d4_xplained/Kconfig"
diff --git a/arch/arm/mach-at91/armv7/Makefile b/arch/arm/mach-at91/armv7/Makefile
index f4f35a4..9538bc1 100644
--- a/arch/arm/mach-at91/armv7/Makefile
+++ b/arch/arm/mach-at91/armv7/Makefile
@@ -8,6 +8,7 @@
# SPDX-License-Identifier: GPL-2.0+
#
+obj-$(CONFIG_SAMA5D2) += sama5d2_devices.o
obj-$(CONFIG_SAMA5D3) += sama5d3_devices.o
obj-$(CONFIG_SAMA5D4) += sama5d4_devices.o
obj-y += clock.o
diff --git a/arch/arm/mach-at91/armv7/sama5d2_devices.c b/arch/arm/mach-at91/armv7/sama5d2_devices.c
new file mode 100644
index 0000000..26883fc
--- /dev/null
+++ b/arch/arm/mach-at91/armv7/sama5d2_devices.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2015 Atmel Corporation
+ * Wenyou Yang <wenyou.yang(a)atmel.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/at91_pmc.h>
+#include <asm/arch/clk.h>
+#include <asm/arch/sama5d2.h>
+
+char *get_cpu_name()
+{
+ unsigned int extension_id = get_extension_chip_id();
+
+ if (cpu_is_sama5d2()) {
+ switch (extension_id) {
+ case ARCH_EXID_SAMA5D21CU:
+ return "SAMA5D21";
+ case ARCH_EXID_SAMA5D22CU:
+ return "SAMA5D22-CU";
+ case ARCH_EXID_SAMA5D22CN:
+ return "SAMA5D22-CN";
+ case ARCH_EXID_SAMA5D23CU:
+ return "SAMA5D23-CU";
+ case ARCH_EXID_SAMA5D24CX:
+ return "SAMA5D24-CX";
+ case ARCH_EXID_SAMA5D24CU:
+ return "SAMA5D24-CU";
+ case ARCH_EXID_SAMA5D26CU:
+ return "SAMA5D26-CU";
+ case ARCH_EXID_SAMA5D27CU:
+ return "SAMA5D27-CU";
+ case ARCH_EXID_SAMA5D27CN:
+ return "SAMA5D27-CN";
+ case ARCH_EXID_SAMA5D28CU:
+ return "SAMA5D28-CU";
+ case ARCH_EXID_SAMA5D28CN:
+ return "SAMA5D28-CN";
+ default:
+ goto err_exit;
+ }
+ }
+
+err_exit:
+ return "Unknown CPU type";
+}
+
+#ifdef CONFIG_USB_GADGET_ATMEL_USBA
+void at91_udp_hw_init(void)
+{
+ struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
+
+ writel(AT91_PMC_UPLLEN | AT91_PMC_BIASEN, &pmc->uckr);
+
+ at91_periph_clk_enable(ATMEL_ID_UDPHS);
+}
+#endif
diff --git a/arch/arm/mach-at91/include/mach/at91_pmc.h b/arch/arm/mach-at91/include/mach/at91_pmc.h
index 8a3fb94..5adaa30 100644
--- a/arch/arm/mach-at91/include/mach/at91_pmc.h
+++ b/arch/arm/mach-at91/include/mach/at91_pmc.h
@@ -78,7 +78,8 @@ typedef struct at91_pmc {
#define AT91_PMC_PLLXR_DIV(x) (x & 0xFF)
#define AT91_PMC_PLLXR_PLLCOUNT(x) ((x & 0x3F) << 8)
#define AT91_PMC_PLLXR_OUT(x) ((x & 0x03) << 14)
-#if defined(CONFIG_SAMA5D3) || defined(CONFIG_SAMA5D4)
+#if defined(CONFIG_SAMA5D2) || defined(CONFIG_SAMA5D3) || \
+ defined(CONFIG_SAMA5D4)
#define AT91_PMC_PLLXR_MUL(x) ((x & 0x7F) << 18)
#else
#define AT91_PMC_PLLXR_MUL(x) ((x & 0x7FF) << 16)
@@ -97,7 +98,8 @@ typedef struct at91_pmc {
#define AT91_PMC_MCKR_CSS_PLLB 0x00000003
#define AT91_PMC_MCKR_CSS_MASK 0x00000003
-#if defined(CONFIG_SAMA5D3) || defined(CONFIG_SAMA5D4) || \
+#if defined(CONFIG_SAMA5D2) || defined(CONFIG_SAMA5D3) || \
+ defined(CONFIG_SAMA5D4) || \
defined(CONFIG_AT91SAM9X5) || defined(CONFIG_AT91SAM9N12)
#define AT91_PMC_MCKR_PRES_1 0x00000000
#define AT91_PMC_MCKR_PRES_2 0x00000010
@@ -127,10 +129,7 @@ typedef struct at91_pmc {
#else
#define AT91_PMC_MCKR_MDIV_1 0x00000000
#define AT91_PMC_MCKR_MDIV_2 0x00000100
-#if defined(CONFIG_SAMA5D3) || defined(CONFIG_SAMA5D4) || \
- defined(CONFIG_AT91SAM9X5) || defined(CONFIG_AT91SAM9N12)
#define AT91_PMC_MCKR_MDIV_3 0x00000300
-#endif
#define AT91_PMC_MCKR_MDIV_4 0x00000200
#define AT91_PMC_MCKR_MDIV_MASK 0x00000300
#endif
diff --git a/arch/arm/mach-at91/include/mach/atmel_usba_udc.h b/arch/arm/mach-at91/include/mach/atmel_usba_udc.h
index 38b5012..46a329b 100644
--- a/arch/arm/mach-at91/include/mach/atmel_usba_udc.h
+++ b/arch/arm/mach-at91/include/mach/atmel_usba_udc.h
@@ -31,7 +31,8 @@ static struct usba_ep_data usba_udc_ep[] = {
EP("ep5", 5, 1024, 3, 1, 1),
EP("ep6", 6, 1024, 3, 1, 1),
};
-#elif defined(CONFIG_SAMA5D3) || defined(CONFIG_SAMA5D4)
+#elif defined(CONFIG_SAMA5D2) || defined(CONFIG_SAMA5D3) || \
+ defined(CONFIG_SAMA5D4)
static struct usba_ep_data usba_udc_ep[] = {
EP("ep0", 0, 64, 1, 0, 0),
EP("ep1", 1, 1024, 3, 1, 0),
diff --git a/arch/arm/mach-at91/include/mach/hardware.h b/arch/arm/mach-at91/include/mach/hardware.h
index ff6b71b..38abfda 100644
--- a/arch/arm/mach-at91/include/mach/hardware.h
+++ b/arch/arm/mach-at91/include/mach/hardware.h
@@ -23,6 +23,8 @@
# include <asm/arch/at91sam9g45.h>
#elif defined(CONFIG_AT91SAM9N12) || defined(CONFIG_AT91SAM9X5)
# include <asm/arch/at91sam9x5.h>
+#elif defined(CONFIG_SAMA5D2)
+# include <asm/arch/sama5d2.h>
#elif defined(CONFIG_SAMA5D3)
# include <asm/arch/sama5d3.h>
#elif defined(CONFIG_SAMA5D4)
diff --git a/arch/arm/mach-at91/include/mach/sama5d2.h b/arch/arm/mach-at91/include/mach/sama5d2.h
new file mode 100644
index 0000000..c85571c
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/sama5d2.h
@@ -0,0 +1,203 @@
+/*
+ * Chip-specific header file for the SAMA5D2 SoC
+ *
+ * Copyright (C) 2015 Atmel
+ * Wenyou Yang <wenyou.yang(a)atmel.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __SAMA5D2_H
+#define __SAMA5D2_H
+
+/*
+ * definitions to be used in other places
+ */
+#define CONFIG_AT91FAMILY /* It's a member of AT91 */
+
+/*
+ * Peripheral identifiers/interrupts.
+ */
+#define ATMEL_ID_FIQ 0 /* FIQ Interrupt ID */
+/* 1 */
+#define ATMEL_ID_ARM 2 /* Performance Monitor Unit */
+#define ATMEL_ID_PIT 3 /* Periodic Interval Timer Interrupt */
+#define ATMEL_ID_WDT 4 /* Watchdog Timer Interrupt */
+#define ATMEL_ID_GMAC 5 /* Ethernet MAC */
+#define ATMEL_ID_XDMAC0 6 /* DMA Controller 0 */
+#define ATMEL_ID_XDMAC1 7 /* DMA Controller 1 */
+#define ATMEL_ID_ICM 8 /* Integrity Check Monitor */
+#define ATMEL_ID_AES 9 /* Advanced Encryption Standard */
+#define ATMEL_ID_AESB 10 /* AES bridge */
+#define ATMEL_ID_TDES 11 /* Triple Data Encryption Standard */
+#define ATMEL_ID_SHA 12 /* SHA Signature */
+#define ATMEL_ID_MPDDRC 13 /* MPDDR Controller */
+#define ATMEL_ID_MATRIX1 14 /* H32MX, 32-bit AHB Matrix */
+#define ATMEL_ID_MATRIX0 15 /* H64MX, 64-bit AHB Matrix */
+#define ATMEL_ID_SECUMOD 16 /* Secure Module */
+#define ATMEL_ID_HSMC 17 /* Multi-bit ECC interrupt */
+#define ATMEL_ID_PIOA 18 /* Parallel I/O Controller A */
+#define ATMEL_ID_FLEXCOM0 19 /* FLEXCOM0 */
+#define ATMEL_ID_FLEXCOM1 20 /* FLEXCOM1 */
+#define ATMEL_ID_FLEXCOM2 21 /* FLEXCOM2 */
+#define ATMEL_ID_FLEXCOM3 22 /* FLEXCOM3 */
+#define ATMEL_ID_FLEXCOM4 23 /* FLEXCOM4 */
+#define ATMEL_ID_UART0 24 /* UART0 */
+#define ATMEL_ID_UART1 25 /* UART1 */
+#define ATMEL_ID_UART2 26 /* UART2 */
+#define ATMEL_ID_UART3 27 /* UART3 */
+#define ATMEL_ID_UART4 28 /* UART4 */
+#define ATMEL_ID_TWIHS0 29 /* Two-wire Interface 0 */
+#define ATMEL_ID_TWIHS1 30 /* Two-wire Interface 1 */
+#define ATMEL_ID_SDMMC0 31 /* Secure Data Memory Card Controller 0 */
+#define ATMEL_ID_SDMMC1 32 /* Secure Data Memory Card Controller 1 */
+#define ATMEL_ID_SPI0 33 /* Serial Peripheral Interface 0 */
+#define ATMEL_ID_SPI1 34 /* Serial Peripheral Interface 1 */
+#define ATMEL_ID_TC0 35 /* Timer Counter 0 (ch.0,1,2) */
+#define ATMEL_ID_TC1 36 /* Timer Counter 1 (ch.3,4,5) */
+/* 37 */
+#define ATMEL_ID_PWM 38 /* PWMController0 (ch. 0,1,2,3) */
+/* 39 */
+#define ATMEL_ID_ADC 40 /* Touch Screen ADC Controller */
+#define ATMEL_ID_UHPHS 41 /* USB Host High Speed */
+#define ATMEL_ID_UDPHS 42 /* USB Device High Speed */
+#define ATMEL_ID_SSC0 43 /* Serial Synchronous Controller 0 */
+#define ATMEL_ID_SSC1 44 /* Serial Synchronous Controller 1 */
+#define ATMEL_ID_LCDC 45 /* LCD Controller */
+#define ATMEL_ID_ISI 46 /* Image Sensor Controller, for A5D2, named after ISC */
+#define ATMEL_ID_TRNG 47 /* True Random Number Generator */
+#define ATMEL_ID_PDMIC 48 /* PDM Interface Controller */
+#define ATMEL_ID_AIC_IRQ 49 /* IRQ Interrupt ID */
+#define ATMEL_ID_SFC 50 /* Fuse Controller */
+#define ATMEL_ID_SECURAM 51 /* Secure RAM */
+#define ATMEL_ID_QSPI0 52 /* QSPI0 */
+#define ATMEL_ID_QSPI1 53 /* QSPI1 */
+#define ATMEL_ID_I2SC0 54 /* Inter-IC Sound Controller 0 */
+#define ATMEL_ID_I2SC1 55 /* Inter-IC Sound Controller 1 */
+#define ATMEL_ID_CAN0_INT0 56 /* MCAN 0 Interrupt0 */
+#define ATMEL_ID_CAN1_INT0 57 /* MCAN 1 Interrupt0 */
+/* 58 */
+#define ATMEL_ID_CLASSD 59 /* Audio Class D Amplifier */
+#define ATMEL_ID_SFR 60 /* Special Function Register */
+#define ATMEL_ID_SAIC 61 /* Secured AIC */
+#define ATMEL_ID_AIC 62 /* Advanced Interrupt Controller */
+#define ATMEL_ID_L2CC 63 /* L2 Cache Controller */
+#define ATMEL_ID_CAN0_INT1 64 /* MCAN 0 Interrupt1 */
+#define ATMEL_ID_CAN1_INT1 65 /* MCAN 1 Interrupt1 */
+#define ATMEL_ID_GMAC_Q1 66 /* GMAC Queue 1 Interrupt */
+#define ATMEL_ID_GMAC_Q2 67 /* GMAC Queue 2 Interrupt */
+#define ATMEL_ID_PIOB 68 /* Parallel I/O Controller B */
+#define ATMEL_ID_PIOC 69 /* Parallel I/O Controller C */
+#define ATMEL_ID_PIOD 70 /* Parallel I/O Controller D */
+#define ATMEL_ID_SDMMC0_TIMER 71 /* Secure Data Memory Card Controller 0 (TIMER) */
+#define ATMEL_ID_SDMMC1_TIMER 72 /* Secure Data Memory Card Controller 1 (TIMER) */
+/* 73 */
+#define ATMEL_ID_SYS 74 /* System Controller Interrupt */
+#define ATMEL_ID_ACC 75 /* Analog Comparator */
+#define ATMEL_ID_RXLP 76 /* UART Low-Power */
+#define ATMEL_ID_SFRBU 77 /* Special Function Register BackUp */
+#define ATMEL_ID_CHIPID 78 /* Chip ID */
+
+/*
+ * User Peripherals physical base addresses.
+ */
+#define ATMEL_BASE_LCDC 0xf0000000
+#define ATMEL_BASE_XDMAC1 0xf0004000
+#define ATMEL_BASE_MPDDRC 0xf000c000
+#define ATMEL_BASE_XDMAC0 0xf0010000
+#define ATMEL_BASE_PMC 0xf0014000
+#define ATMEL_BASE_QSPI0 0xf0020000
+#define ATMEL_BASE_QSPI1 0xf0024000
+#define ATMEL_BASE_SPI0 0xf8000000
+#define ATMEL_BASE_GMAC 0xf8008000
+#define ATMEL_BASE_TC0 0xf800c000
+#define ATMEL_BASE_TC1 0xf8010000
+#define ATMEL_BASE_HSMC 0xf8014000
+#define ATMEL_BASE_UART0 0xf801c000
+#define ATMEL_BASE_UART1 0xf8020000
+#define ATMEL_BASE_UART2 0xf8024000
+#define ATMEL_BASE_TWI0 0xf8028000
+#define ATMEL_BASE_SYSC 0xf8048000
+#define ATMEL_BASE_SPI1 0xfc000000
+#define ATMEL_BASE_UART3 0xfc008000
+#define ATMEL_BASE_UART4 0xfc00c000
+#define ATMEL_BASE_TWI1 0xfc028000
+#define ATMEL_BASE_UDPHS 0xfc02c000
+
+#define ATMEL_BASE_PIOA 0xfc038000
+
+#define ATMEL_CHIPID_CIDR 0xfc069000
+#define ATMEL_CHIPID_EXID 0xfc069004
+
+/*
+ * Address Memory Space
+ */
+#define ATMEL_BASE_DDRCS 0x20000000
+#define ATMEL_BASE_QSPI0_AES_MEM 0x90000000
+#define ATMEL_BASE_QSPI1_AES_MEM 0x98000000
+#define ATMEL_BASE_SDMMC0 0xa0000000
+#define ATMEL_BASE_SDMMC1 0xb0000000
+#define ATMEL_BASE_QSPI0_MEM 0xd0000000
+#define ATMEL_BASE_QSPI1_MEM 0xd8000000
+
+/*
+ * Internal Memories
+ */
+#define ATMEL_BASE_UDPHS_FIFO 0x00300000 /* USB Device HS controller */
+#define ATMEL_BASE_OHCI 0x00400000 /* USB Host controller (OHCI) */
+#define ATMEL_BASE_EHCI 0x00500000 /* USB Host controller (EHCI) */
+
+/*
+ * SYSC Spawns
+ */
+#define ATMEL_BASE_RSTC ATMEL_BASE_SYSC
+#define ATMEL_BASE_SHDWC (ATMEL_BASE_SYSC + 0x10)
+#define ATMEL_BASE_PIT (ATMEL_BASE_SYSC + 0x30)
+#define ATMEL_BASE_WDT (ATMEL_BASE_SYSC + 0x40)
+#define ATMEL_BASE_SCKC (ATMEL_BASE_SYSC + 0x50)
+#define ATMEL_BASE_RTC (ATMEL_BASE_SYSC + 0xb0)
+
+/*
+ * Other misc definitions
+ */
+#define ATMEL_BASE_PMECC (ATMEL_BASE_HSMC + 0x70)
+#define ATMEL_BASE_PMERRLOC (ATMEL_BASE_HSMC + 0x500)
+
+#define ATMEL_BASE_PIOB (ATMEL_BASE_PIOA + 0x40)
+#define ATMEL_BASE_PIOC (ATMEL_BASE_PIOB + 0x40)
+#define ATMEL_BASE_PIOD (ATMEL_BASE_PIOC + 0x40)
+
+#define ATMEL_PIO_PORTS 4
+#define CPU_HAS_PCR
+#define CPU_HAS_H32MXDIV
+
+/* SAMA5D2 series chip id definitions */
+#define ARCH_ID_SAMA5D2 0x8a5c08c0
+#define ARCH_EXID_SAMA5D21CU 0x0000005a
+#define ARCH_EXID_SAMA5D22CU 0x00000059
+#define ARCH_EXID_SAMA5D22CN 0x00000069
+#define ARCH_EXID_SAMA5D23CU 0x00000058
+#define ARCH_EXID_SAMA5D24CX 0x00000004
+#define ARCH_EXID_SAMA5D24CU 0x00000014
+#define ARCH_EXID_SAMA5D26CU 0x00000012
+#define ARCH_EXID_SAMA5D27CU 0x00000011
+#define ARCH_EXID_SAMA5D27CN 0x00000021
+#define ARCH_EXID_SAMA5D28CU 0x00000010
+#define ARCH_EXID_SAMA5D28CN 0x00000020
+
+#define cpu_is_sama5d2() (get_chip_id() == ARCH_ID_SAMA5D2)
+
+/* PIT Timer(PIT_PIIR) */
+#define CONFIG_SYS_TIMER_COUNTER 0xf804803c
+
+/* No PMECC Galois table in ROM */
+#define NO_GALOIS_TABLE_IN_ROM
+
+#ifndef __ASSEMBLY__
+unsigned int get_chip_id(void);
+unsigned int get_extension_chip_id(void);
+unsigned int has_lcdc(void);
+char *get_cpu_name(void);
+#endif
+
+#endif
diff --git a/board/atmel/sama5d2_xplained/Kconfig b/board/atmel/sama5d2_xplained/Kconfig
new file mode 100644
index 0000000..55712e9
--- /dev/null
+++ b/board/atmel/sama5d2_xplained/Kconfig
@@ -0,0 +1,15 @@
+if TARGET_SAMA5D2_XPLAINED
+
+config SYS_BOARD
+ default "sama5d2_xplained"
+
+config SYS_VENDOR
+ default "atmel"
+
+config SYS_SOC
+ default "at91"
+
+config SYS_CONFIG_NAME
+ default "sama5d2_xplained"
+
+endif
diff --git a/board/atmel/sama5d2_xplained/MAINTAINERS b/board/atmel/sama5d2_xplained/MAINTAINERS
new file mode 100644
index 0000000..ff9c86f
--- /dev/null
+++ b/board/atmel/sama5d2_xplained/MAINTAINERS
@@ -0,0 +1,7 @@
+SAMA5D2 XPLAINED BOARD
+M: Wenyou Yang <wenyou.yang(a)atmel.com>
+S: Maintained
+F: board/atmel/sama5d2_xplained/
+F: include/configs/sama5d2_xplained.h
+F: configs/sama5d2_xplained_mmc_defconfig
+F: configs/sama5d2_xplained_spiflash_defconfig
diff --git a/board/atmel/sama5d2_xplained/Makefile b/board/atmel/sama5d2_xplained/Makefile
new file mode 100644
index 0000000..420870b
--- /dev/null
+++ b/board/atmel/sama5d2_xplained/Makefile
@@ -0,0 +1,8 @@
+#
+# Copyright (C) 2015 Atmel Corporation
+# Wenyou Yang <wenyou.yang(a)atmel.com>
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-y += sama5d2_xplained.o
diff --git a/board/atmel/sama5d2_xplained/sama5d2_xplained.c b/board/atmel/sama5d2_xplained/sama5d2_xplained.c
new file mode 100644
index 0000000..03f4b43
--- /dev/null
+++ b/board/atmel/sama5d2_xplained/sama5d2_xplained.c
@@ -0,0 +1,282 @@
+/*
+ * Copyright (C) 2015 Atmel Corporation
+ * Wenyou.Yang <wenyou.yang(a)atmel.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <atmel_hlcdc.h>
+#include <lcd.h>
+#include <mmc.h>
+#include <net.h>
+#include <netdev.h>
+#include <spi.h>
+#include <version.h>
+#include <asm/io.h>
+#include <asm/arch/at91_common.h>
+#include <asm/arch/at91_pmc.h>
+#include <asm/arch/atmel_pio4.h>
+#include <asm/arch/atmel_usba_udc.h>
+#include <asm/arch/atmel_sdhci.h>
+#include <asm/arch/clk.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/sama5d2.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int spi_cs_is_valid(unsigned int bus, unsigned int cs)
+{
+ return bus == 0 && cs == 0;
+}
+
+void spi_cs_activate(struct spi_slave *slave)
+{
+ atmel_pio4_set_pio_output(AT91_PIO_PORTA, 17, 0);
+}
+
+void spi_cs_deactivate(struct spi_slave *slave)
+{
+ atmel_pio4_set_pio_output(AT91_PIO_PORTA, 17, 1);
+}
+
+static void board_spi0_hw_init(void)
+{
+ atmel_pio4_set_a_periph(AT91_PIO_PORTA, 14, 0);
+ atmel_pio4_set_a_periph(AT91_PIO_PORTA, 15, 0);
+ atmel_pio4_set_a_periph(AT91_PIO_PORTA, 16, 0);
+
+ atmel_pio4_set_pio_output(AT91_PIO_PORTA, 17, 1);
+
+ at91_periph_clk_enable(ATMEL_ID_SPI0);
+}
+
+static void board_usb_hw_init(void)
+{
+ atmel_pio4_set_pio_output(AT91_PIO_PORTB, 9, 1);
+ atmel_pio4_set_pio_output(AT91_PIO_PORTB, 10, 1);
+}
+
+#ifdef CONFIG_LCD
+vidinfo_t panel_info = {
+ .vl_col = 480,
+ .vl_row = 272,
+ .vl_clk = 9000000,
+ .vl_bpix = LCD_BPP,
+ .vl_tft = 1,
+ .vl_hsync_len = 41,
+ .vl_left_margin = 2,
+ .vl_right_margin = 2,
+ .vl_vsync_len = 11,
+ .vl_upper_margin = 2,
+ .vl_lower_margin = 2,
+ .mmio = ATMEL_BASE_LCDC,
+};
+
+/* No power up/down pin for the LCD pannel */
+void lcd_enable(void) { /* Empty! */ }
+void lcd_disable(void) { /* Empty! */ }
+
+__weak unsigned int has_lcdc(void)
+{
+ return 1;
+}
+
+static void board_lcd_hw_init(void)
+{
+ atmel_pio4_set_a_periph(AT91_PIO_PORTC, 28, 0); /* LCDPWM */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTC, 29, 0); /* LCDDISP */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTC, 30, 0); /* LCDVSYNC */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTC, 31, 0); /* LCDHSYNC */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTD, 0, 0); /* LCDPCK */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTD, 1, 0); /* LCDDEN */
+
+ /* LCDDAT0 */
+ /* LCDDAT1 */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTC, 10, 0); /* LCDDAT2 */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTC, 11, 0); /* LCDDAT3 */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTC, 12, 0); /* LCDDAT4 */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTC, 13, 0); /* LCDDAT5 */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTC, 14, 0); /* LCDDAT6 */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTC, 15, 0); /* LCDDAT7 */
+
+ /* LCDDAT8 */
+ /* LCDDAT9 */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTC, 16, 0); /* LCDDAT10 */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTC, 17, 0); /* LCDDAT11 */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTC, 18, 0); /* LCDDAT12 */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTC, 19, 0); /* LCDDAT13 */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTC, 20, 0); /* LCDDAT14 */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTC, 21, 0); /* LCDDAT15 */
+
+ /* LCDD16 */
+ /* LCDD17 */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTC, 22, 0); /* LCDDAT18 */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTC, 23, 0); /* LCDDAT19 */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTC, 24, 0); /* LCDDAT20 */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTC, 25, 0); /* LCDDAT21 */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTC, 26, 0); /* LCDDAT22 */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTC, 27, 0); /* LCDDAT23 */
+
+ at91_periph_clk_enable(ATMEL_ID_LCDC);
+}
+
+#ifdef CONFIG_LCD_INFO
+void lcd_show_board_info(void)
+{
+ ulong dram_size;
+ int i;
+ char temp[32];
+
+ lcd_printf("%s\n", U_BOOT_VERSION);
+ lcd_printf("2015 ATMEL Corp\n");
+ lcd_printf("%s CPU at %s MHz\n", get_cpu_name(),
+ strmhz(temp, get_cpu_clk_rate()));
+
+ dram_size = 0;
+ for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++)
+ dram_size += gd->bd->bi_dram[i].size;
+
+ lcd_printf("%ld MB SDRAM\n", dram_size >> 20);
+}
+#endif /* CONFIG_LCD_INFO */
+#endif /* CONFIG_LCD */
+
+static void board_gmac_hw_init(void)
+{
+ atmel_pio4_set_f_periph(AT91_PIO_PORTB, 14, 0); /* GTXCK */
+ atmel_pio4_set_f_periph(AT91_PIO_PORTB, 15, 0); /* GTXEN */
+ atmel_pio4_set_f_periph(AT91_PIO_PORTB, 16, 0); /* GRXDV */
+ atmel_pio4_set_f_periph(AT91_PIO_PORTB, 17, 0); /* GRXER */
+ atmel_pio4_set_f_periph(AT91_PIO_PORTB, 18, 0); /* GRX0 */
+ atmel_pio4_set_f_periph(AT91_PIO_PORTB, 19, 0); /* GRX1 */
+ atmel_pio4_set_f_periph(AT91_PIO_PORTB, 20, 0); /* GTX0 */
+ atmel_pio4_set_f_periph(AT91_PIO_PORTB, 21, 0); /* GTX1 */
+ atmel_pio4_set_f_periph(AT91_PIO_PORTB, 22, 0); /* GMDC */
+ atmel_pio4_set_f_periph(AT91_PIO_PORTB, 23, 0); /* GMDIO */
+
+ at91_periph_clk_enable(ATMEL_ID_GMAC);
+}
+
+static void board_sdhci0_hw_init(void)
+{
+ atmel_pio4_set_a_periph(AT91_PIO_PORTA, 0, 0); /* SDMMC0_CK */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTA, 1, 0); /* SDMMC0_CMD */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTA, 2, 0); /* SDMMC0_DAT0 */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTA, 3, 0); /* SDMMC0_DAT1 */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTA, 4, 0); /* SDMMC0_DAT2 */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTA, 5, 0); /* SDMMC0_DAT3 */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTA, 6, 0); /* SDMMC0_DAT4 */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTA, 7, 0); /* SDMMC0_DAT5 */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTA, 8, 0); /* SDMMC0_DAT6 */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTA, 9, 0); /* SDMMC0_DAT7 */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTA, 10, 0); /* SDMMC0_RSTN */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTA, 11, 0); /* SDMMC0_VDDSEL */
+
+ at91_periph_clk_enable(ATMEL_ID_SDMMC0);
+ at91_enable_periph_generated_clk(ATMEL_ID_SDMMC0);
+}
+
+static void board_sdhci1_hw_init(void)
+{
+ atmel_pio4_set_e_periph(AT91_PIO_PORTA, 18, 0); /* SDMMC1_DAT0 */
+ atmel_pio4_set_e_periph(AT91_PIO_PORTA, 19, 0); /* SDMMC1_DAT1 */
+ atmel_pio4_set_e_periph(AT91_PIO_PORTA, 20, 0); /* SDMMC1_DAT2 */
+ atmel_pio4_set_e_periph(AT91_PIO_PORTA, 21, 0); /* SDMMC1_DAT3 */
+ atmel_pio4_set_e_periph(AT91_PIO_PORTA, 22, 0); /* SDMMC1_CK */
+ atmel_pio4_set_e_periph(AT91_PIO_PORTA, 27, 0); /* SDMMC1_RSTN */
+ atmel_pio4_set_e_periph(AT91_PIO_PORTA, 28, 0); /* SDMMC1_CMD */
+ atmel_pio4_set_e_periph(AT91_PIO_PORTA, 30, 0); /* SDMMC1_CD */
+
+ at91_periph_clk_enable(ATMEL_ID_SDMMC1);
+ at91_enable_periph_generated_clk(ATMEL_ID_SDMMC1);
+}
+
+int board_mmc_init(bd_t *bis)
+{
+#ifdef CONFIG_ATMEL_SDHCI0
+ atmel_sdhci_init((void *)ATMEL_BASE_SDMMC0, ATMEL_ID_SDMMC0);
+#endif
+#ifdef CONFIG_ATMEL_SDHCI1
+ atmel_sdhci_init((void *)ATMEL_BASE_SDMMC1, ATMEL_ID_SDMMC1);
+#endif
+
+ return 0;
+}
+
+static void board_uart1_hw_init(void)
+{
+ atmel_pio4_set_a_periph(AT91_PIO_PORTD, 2, 1); /* URXD1 */
+ atmel_pio4_set_a_periph(AT91_PIO_PORTD, 3, 0); /* UTXD1 */
+
+ at91_periph_clk_enable(ATMEL_ID_UART1);
+}
+
+int board_early_init_f(void)
+{
+ at91_periph_clk_enable(ATMEL_ID_PIOA);
+ at91_periph_clk_enable(ATMEL_ID_PIOB);
+ at91_periph_clk_enable(ATMEL_ID_PIOC);
+ at91_periph_clk_enable(ATMEL_ID_PIOD);
+
+ board_uart1_hw_init();
+
+ return 0;
+}
+
+int board_init(void)
+{
+ /* address of boot parameters */
+ gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
+
+#ifdef CONFIG_ATMEL_SPI
+ board_spi0_hw_init();
+#endif
+#ifdef CONFIG_ATMEL_SDHCI
+#ifdef CONFIG_ATMEL_SDHCI0
+ board_sdhci0_hw_init();
+#endif
+#ifdef CONFIG_ATMEL_SDHCI1
+ board_sdhci1_hw_init();
+#endif
+#endif
+#ifdef CONFIG_MACB
+ board_gmac_hw_init();
+#endif
+#ifdef CONFIG_LCD
+ board_lcd_hw_init();
+#endif
+#ifdef CONFIG_CMD_USB
+ board_usb_hw_init();
+#endif
+#ifdef CONFIG_USB_GADGET_ATMEL_USBA
+ at91_udp_hw_init();
+#endif
+
+ return 0;
+}
+
+int dram_init(void)
+{
+ gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE,
+ CONFIG_SYS_SDRAM_SIZE);
+ return 0;
+}
+
+int board_eth_init(bd_t *bis)
+{
+ int rc = 0;
+
+#ifdef CONFIG_MACB
+ rc = macb_eth_initialize(0, (void *)ATMEL_BASE_GMAC, 0x00);
+#endif
+
+#ifdef CONFIG_USB_GADGET_ATMEL_USBA
+ usba_udc_probe(&pdata);
+#ifdef CONFIG_USB_ETH_RNDIS
+ usb_eth_initialize(bis);
+#endif
+#endif
+
+ return rc;
+}
diff --git a/configs/sama5d2_xplained_mmc_defconfig b/configs/sama5d2_xplained_mmc_defconfig
new file mode 100644
index 0000000..c1dcbef
--- /dev/null
+++ b/configs/sama5d2_xplained_mmc_defconfig
@@ -0,0 +1,11 @@
+CONFIG_ARM=y
+CONFIG_ARCH_AT91=y
+CONFIG_TARGET_SAMA5D2_XPLAINED=y
+CONFIG_SYS_EXTRA_OPTIONS="SAMA5D2,SYS_USE_MMC"
+# CONFIG_CMD_IMI is not set
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_LOADS is not set
+# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_SF=y
+# CONFIG_CMD_FPGA is not set
+CONFIG_SPI_FLASH=y
diff --git a/configs/sama5d2_xplained_spiflash_defconfig b/configs/sama5d2_xplained_spiflash_defconfig
new file mode 100644
index 0000000..0271e8e
--- /dev/null
+++ b/configs/sama5d2_xplained_spiflash_defconfig
@@ -0,0 +1,11 @@
+CONFIG_ARM=y
+CONFIG_ARCH_AT91=y
+CONFIG_TARGET_SAMA5D2_XPLAINED=y
+CONFIG_SYS_EXTRA_OPTIONS="SAMA5D2,SYS_USE_SERIALFLASH"
+# CONFIG_CMD_IMI is not set
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_LOADS is not set
+# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_SF=y
+# CONFIG_CMD_FPGA is not set
+CONFIG_SPI_FLASH=y
diff --git a/include/configs/sama5d2_xplained.h b/include/configs/sama5d2_xplained.h
new file mode 100644
index 0000000..ae5ba3d
--- /dev/null
+++ b/include/configs/sama5d2_xplained.h
@@ -0,0 +1,122 @@
+/*
+ * Configuration file for the SAMA5D2 Xplained Board.
+ *
+ * Copyright (C) 2015 Atmel Corporation
+ * Wenyou Yang <wenyou.yang(a)atmel.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/* No NOR flash, this definition should put before common header */
+#define CONFIG_SYS_NO_FLASH
+
+#include "at91-sama5_common.h"
+
+/* serial console */
+#define CONFIG_ATMEL_USART
+#define CONFIG_USART_BASE ATMEL_BASE_UART1
+#define CONFIG_USART_ID ATMEL_ID_UART1
+
+/* SDRAM */
+#define CONFIG_NR_DRAM_BANKS 1
+#define CONFIG_SYS_SDRAM_BASE ATMEL_BASE_DDRCS
+#define CONFIG_SYS_SDRAM_SIZE 0x20000000
+
+#define CONFIG_SYS_INIT_SP_ADDR \
+ (CONFIG_SYS_SDRAM_BASE + 4 * 1024 - GENERATED_GBL_DATA_SIZE)
+
+#define CONFIG_SYS_LOAD_ADDR 0x22000000 /* load address */
+
+#undef CONFIG_AT91_GPIO
+#define CONFIG_ATMEL_PIO4
+
+/* SerialFlash */
+#ifdef CONFIG_CMD_SF
+#define CONFIG_ATMEL_SPI
+#define CONFIG_ATMEL_SPI0
+#define CONFIG_SPI_FLASH_ATMEL
+#define CONFIG_SF_DEFAULT_BUS 0
+#define CONFIG_SF_DEFAULT_CS 0
+#define CONFIG_SF_DEFAULT_SPEED 30000000
+#endif
+
+/* NAND flash */
+#undef CONFIG_CMD_NAND
+
+/* MMC */
+#define CONFIG_CMD_MMC
+
+#ifdef CONFIG_CMD_MMC
+#define CONFIG_MMC
+#define CONFIG_GENERIC_MMC
+#define CONFIG_SDHCI
+#define CONFIG_ATMEL_SDHCI
+#define CONFIG_ATMEL_SDHCI0
+#define CONFIG_ATMEL_SDHCI1
+#define CONFIG_SUPPORT_EMMC_BOOT
+#endif
+
+/* USB */
+#define CONFIG_CMD_USB
+
+#ifdef CONFIG_CMD_USB
+#define CONFIG_USB_EHCI
+#define CONFIG_USB_EHCI_ATMEL
+#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 3
+#define CONFIG_USB_STORAGE
+#endif
+
+/* USB device */
+#define CONFIG_USB_GADGET
+#define CONFIG_USB_GADGET_DUALSPEED
+#define CONFIG_USB_GADGET_ATMEL_USBA
+#define CONFIG_USB_ETHER
+#define CONFIG_USB_ETH_RNDIS
+#define CONFIG_USBNET_MANUFACTURER "Atmel SAMA5D2 XPlained"
+
+#if defined(CONFIG_CMD_USB) || defined(CONFIG_CMD_MMC)
+#define CONFIG_CMD_FAT
+#define CONFIG_DOS_PARTITION
+#endif
+
+/* Ethernet Hardware */
+#define CONFIG_MACB
+#define CONFIG_RMII
+#define CONFIG_NET_RETRY_COUNT 20
+#define CONFIG_MACB_SEARCH_PHY
+
+/* LCD */
+/* #define CONFIG_LCD */
+
+#ifdef CONFIG_LCD
+#define LCD_BPP LCD_COLOR16
+#define LCD_OUTPUT_BPP 24
+#define CONFIG_LCD_LOGO
+#define CONFIG_LCD_INFO
+#define CONFIG_LCD_INFO_BELOW_LOGO
+#define CONFIG_SYS_WHITE_ON_BLACK
+#define CONFIG_ATMEL_HLCD
+#define CONFIG_ATMEL_LCD_RGB565
+#define CONFIG_SYS_CONSOLE_IS_IN_ENV
+#endif
+
+#ifdef CONFIG_SYS_USE_MMC
+
+/* bootstrap + u-boot + env in sd card */
+#undef FAT_ENV_DEVICE_AND_PART
+#undef CONFIG_BOOTCOMMAND
+
+#define FAT_ENV_DEVICE_AND_PART "1"
+#define CONFIG_BOOTCOMMAND "fatload mmc 1:1 0x21000000 at91-sama5d2_xplained.dtb; " \
+ "fatload mmc 1:1 0x22000000 zImage; " \
+ "bootz 0x22000000 - 0x21000000"
+#undef CONFIG_BOOTARGS
+#define CONFIG_BOOTARGS \
+ "console=ttyS0,115200 earlyprintk root=/dev/mmcblk1p2 rw rootwait"
+
+#endif
+
+#endif
--
1.7.9.5
1
0

27 Oct '15
As sama5 board has 32k sram size, so the at91bootstrap and spl for sama5
boards is bigger than 16k (0x4000). That will overlap the U-Boot
environment. So I move environment to 0x6000. And reduce its size as
well.
Signed-off-by: Josh Wu <josh.wu(a)atmel.com>
---
include/configs/at91-sama5_common.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/configs/at91-sama5_common.h b/include/configs/at91-sama5_common.h
index a5990ce..0b60f0b 100644
--- a/include/configs/at91-sama5_common.h
+++ b/include/configs/at91-sama5_common.h
@@ -98,8 +98,8 @@
#elif CONFIG_SYS_USE_SERIALFLASH
/* u-boot env in serial flash, by default is bus 0 and cs 0 */
#define CONFIG_ENV_IS_IN_SPI_FLASH
-#define CONFIG_ENV_OFFSET 0x4000
-#define CONFIG_ENV_SIZE 0x4000
+#define CONFIG_ENV_OFFSET 0x6000
+#define CONFIG_ENV_SIZE 0x2000
#define CONFIG_ENV_SECT_SIZE 0x1000
#define CONFIG_BOOTCOMMAND "sf probe 0; " \
"sf read 0x21000000 0x60000 0xc000; " \
--
1.9.1
3
5
This series replaces numerical bit shitfts and mask values
with BIT and GENMASK macro's
Changes for v5:
- Dropped exynos_spi BIT changes
- Removed GENMASK for 0XFF on cadence_qspi_qpb
- Split the commit message body
Changes for v4:
- Patch split for individual drivers.
Changes for v3, v2:
- none
Jagan Teki (23):
spi: zynq_[q]spi: Use BIT macro
spi: zynq_[q]spi: Use GENMASK macro
spi: altera_spi: Use BIT macro
spi: atmel_spi: Use BIT macro
spi: bfin_spi6xx: Use BIT macro
spi: cadence_qspi_apb: Use BIT macro
spi: designware_spi: Use BIT macro
spi: fsl: Use BIT macro
spi: ich: Use BIT macro
spi: mpc8xxx_spi: Use BIT macro
spi: omap3_spi: Use BIT macro
spi: sh_qspi: Use BIT macro
spi: tegra: Use BIT macro
spi: ti_qspi: Use BIT macro
spi: xilinx_spi: Use BIT macro
spi: atmel_spi: Use GENMASK
spi: cadence_qspi_apb: Use GENMASK
spi: designware_spi: Use GENMASK
spi: fsl_qspi: Use GENMASK
spi: mxs_spi: Use GENMASK
spi: omap3_spi: Use GENMASK
spi: tegra: Use GENMASK
spi: xilinx_spi: Use GENMASK
drivers/spi/altera_spi.c | 26 +++++++--------
drivers/spi/atmel_spi.h | 54 +++++++++++++++---------------
drivers/spi/bfin_spi6xx.c | 8 ++---
drivers/spi/cadence_qspi_apb.c | 74 ++++++++++++++++++++--------------------
drivers/spi/designware_spi.c | 16 ++++-----
drivers/spi/fsl_dspi.c | 2 +-
drivers/spi/fsl_espi.c | 20 +++++------
drivers/spi/fsl_qspi.c | 6 ++--
drivers/spi/ich.c | 4 +--
drivers/spi/mpc8xxx_spi.c | 2 +-
drivers/spi/mxs_spi.c | 2 +-
drivers/spi/omap3_spi.h | 64 +++++++++++++++++------------------
drivers/spi/sh_qspi.c | 16 ++++-----
drivers/spi/tegra114_spi.c | 76 +++++++++++++++++++++---------------------
drivers/spi/tegra20_sflash.c | 54 +++++++++++++++---------------
drivers/spi/tegra20_slink.c | 62 +++++++++++++++++-----------------
drivers/spi/ti_qspi.c | 10 +++---
drivers/spi/xilinx_spi.c | 46 ++++++++++++-------------
drivers/spi/zynq_qspi.c | 28 ++++++++--------
drivers/spi/zynq_spi.c | 22 ++++++------
20 files changed, 296 insertions(+), 296 deletions(-)
--
1.9.1
8
45
Hi Richard,
Just looked through the slides of your ELCE talk "Current challenges in
UBIFS". I would like to elaborate the issues wrt moster boot. I did not
attend the talk (sorry) and also was not able to find a video of it so
far, hence I don't know what has been said at the talk... So, the last
slide says:
* Don’t boot from UBIFS
* Your boot loader does not have to know UBIFS nor have full UBI support
* Use static volumes, you can read out a static UBI volume with 100 LoC
* Thomas Gleixner sent patches for u-boot
Can you elaborate why you disadvise booting from UBIFS?
Here is my analysis on that:
We switched to "monster boot" approach about one year ago. On the plus
side, U-Boot had already UBIFS read support and it works. Beside that,
it is basically the standard boot mode for distros on PC-like systems
(GRUB is able to read the kernel from a ext2/ext3 formatted /boot
partition, UEFI reads EFI boot loaders or the kernel with the EFI stub
from FAT partitions directly).
I see the obvious pain point: It makes the boot loader much more
complex... After all, we had some issues lately, especially with Fastmap
(e.g. PEB leaks). However, one thing was related to a driver issue, and
after backporting some Fastmap patches from Linux, Fastmap in U-Boot
seems to be stable now. Anyway, since these issues were within the
U-Boot UBI stack (and below), we would probably would have run into them
even when using static volumes (assuming using the full UBI stack of
U-Boot). But likely not if we would have used the minimal static volume
approach of Thomas Gleixner.... On the other hand, we did not had any
problems with the UBIFS part so far...
A fallback boot scheme is possible with UBIFS (just have a spare kernel
ready) but it suffer from the huge stack...
Another disadvantage with monster boot is that we can't replace the
kernel from U-Boot currently since there is no UBIFS write support,
however that is not really a problem.
On the advantage side, we do not loose any space (we would likely have
to create a larger than necessary Kernel volume to reserve some space in
case customers want to load a bigger kernel). And we can use one UBIFS
image for multiple modules (multiple device tree in /boot).
I also did some rough performance measurements, and it seems that the
overhead of mounting the UBIFS is not all that huge:
UBI Attach (without Fastmap): 1.57s
UBI Attach (with Fastmap): 0.25s
UBIFS Mount: 0.06s
Load kernel from FS: 380ms
Load DT from FS: 9ms
However, it seems that reading from UBIFS is somewhat slower compared to
reading from static volumes:
Load kernel from UBI 4.5MB: 316ms
Load kernel from UBI 24kB: 6ms
I used the size argument of the ubi read command to avoid reading the
whole static volume. This is somewhat ugly to handle since the size need
to be stored in environment variables... I am consider implementing a
bootubi command which would read only the effective size for a kernel,
device tree or initramfs by making use of the individual file headers.
I would be glad if you could comment whether I miss anything...
--
Stefan
1
0

26 Oct '15
This patch adds the device tree binding doc for the Tegra
QSPI controller on Tegra210.
Signed-off-by: Tom Warren <twarren(a)nvidia.com>
---
Changes in v2:
- based it more on kernel's nvidia,tegra114-spi.txt binding
- changes based on prelim review by swarren(a)nvidia.com
Changes in v3:
- renamed to 'nvidia,tegra210-qspi.txt' to match kernel bindings
- more changes based on review from swarren(a)nvidia.com
Documentation/devicetree/bindings/spi/nvidia,tegra210-qspi.txt | 42 ++++++++++++++++++++++++++++++
1 file changed, 42 insertions(+)
create mode 100644 Documentation/devicetree/bindings/spi/nvidia,tegra210-qspi.txt
diff --git a/Documentation/devicetree/bindings/spi/nvidia,tegra210-qspi.txt b/Documentation/devicetree/bindings/spi/nvidia,tegra210-qspi.txt
new file mode 100644
index 0000000..fe1558f
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/nvidia,tegra210-qspi.txt
@@ -0,0 +1,42 @@
+NVIDIA Tegra QSPI controller.
+
+Required properties:
+- compatible : for Tegra210, must contain "nvidia,tegra210-qspi".
+- reg: Should contain QSPI registers location and length.
+- interrupts: Should contain QSPI interrupt.
+- clock-names : Must include the following entries:
+ - qspi
+- resets : Must contain an entry for each entry in reset-names.
+ See ../reset/reset.txt for details.
+- reset-names : Must include the following entries:
+ - qspi
+- clocks : Must contain an entry for each entry in clock-names.
+ See ../clocks/clock-bindings.txt for details.
+
+Optional properties:
+- dmas : Must contain an entry for each entry in clock-names.
+ See ../dma/dma.txt for details.
+- dma-names : Must include the following entries:
+ - rx
+ - tx
+
+Recommended properties:
+- spi-max-frequency: Definition as per spi-bus.txt
+
+Example:
+
+spi@70410000 {
+ compatible = "nvidia,tegra210-qspi";
+ reg = <0x0 0x70410000 0x0 0x1000>;
+ interrupts = <0 10 0x04>;
+ spi-max-frequency = <24000000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car 211>;
+ clock-names = "qspi";
+ resets = <&tegra_car 211>;
+ reset-names = "qspi";
+ dmas = <&apbdma 16>, <&apbdma 16>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+};
--
1.8.2.1.610.g562af5b
3
3
This is the normal Tegra SPI driver modified to work with the
QSPI controller in Tegra210. It does not do 2x/4x transfers
or any other QSPI protocol.
Author: Yen Lin <yelin(a)nvidia.com>
Signed-off-by: Yen Lin <yelin(a)nvidia.com>
Signed-off-by: Tom Warren <twarren(a)nvidia.com>
---
Changes in v2:
- Drop defconfig and pinmux files, this is a driver-only patch.
- If/when pinmux tables have been updated for P2371/P2571, another
- patch will be sent to enable the QSPI driver on those boards.
Changes in v3:
- removed status reg write/clear in claim_bus(), done in xfer()
drivers/spi/Kconfig | 5 +
drivers/spi/Makefile | 1 +
drivers/spi/tegra210_qspi.c | 400 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 406 insertions(+)
create mode 100644 drivers/spi/tegra210_qspi.c
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 8e04fce..168f31d 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -115,6 +115,11 @@ config TEGRA20_SLINK
be used to access the SPI NOR flash on platforms embedding this
nVidia Tegra20/Tegra30 IP cores.
+config TEGRA210_QSPI
+ bool "nVidia Tegra210 QSPI driver"
+ help
+ Enable the Tegra Quad-SPI (QSPI) driver for T210.
+
config XILINX_SPI
bool "Xilinx SPI driver"
help
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index de241be..209a41e 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_SH_QSPI) += sh_qspi.o
obj-$(CONFIG_TEGRA114_SPI) += tegra114_spi.o
obj-$(CONFIG_TEGRA20_SFLASH) += tegra20_sflash.o
obj-$(CONFIG_TEGRA20_SLINK) += tegra20_slink.o
+obj-$(CONFIG_TEGRA210_QSPI) += tegra210_qspi.o
obj-$(CONFIG_TI_QSPI) += ti_qspi.o
obj-$(CONFIG_XILINX_SPI) += xilinx_spi.o
obj-$(CONFIG_ZYNQ_SPI) += zynq_spi.o
diff --git a/drivers/spi/tegra210_qspi.c b/drivers/spi/tegra210_qspi.c
new file mode 100644
index 0000000..6be37f3
--- /dev/null
+++ b/drivers/spi/tegra210_qspi.c
@@ -0,0 +1,400 @@
+/*
+ * NVIDIA Tegra210 QSPI controller driver
+ * (C) Copyright 2015
+ * NVIDIA Corporation <www.nvidia.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch-tegra/clk_rst.h>
+#include <spi.h>
+#include <fdtdec.h>
+#include "tegra_spi.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* COMMAND1 */
+#define QSPI_CMD1_GO (1 << 31)
+#define QSPI_CMD1_M_S (1 << 30)
+#define QSPI_CMD1_MODE_MASK 0x3
+#define QSPI_CMD1_MODE_SHIFT 28
+#define QSPI_CMD1_CS_SEL_MASK 0x3
+#define QSPI_CMD1_CS_SEL_SHIFT 26
+#define QSPI_CMD1_CS_POL_INACTIVE0 (1 << 22)
+#define QSPI_CMD1_CS_SW_HW (1 << 21)
+#define QSPI_CMD1_CS_SW_VAL (1 << 20)
+#define QSPI_CMD1_IDLE_SDA_MASK 0x3
+#define QSPI_CMD1_IDLE_SDA_SHIFT 18
+#define QSPI_CMD1_BIDIR (1 << 17)
+#define QSPI_CMD1_LSBI_FE (1 << 16)
+#define QSPI_CMD1_LSBY_FE (1 << 15)
+#define QSPI_CMD1_BOTH_EN_BIT (1 << 14)
+#define QSPI_CMD1_BOTH_EN_BYTE (1 << 13)
+#define QSPI_CMD1_RX_EN (1 << 12)
+#define QSPI_CMD1_TX_EN (1 << 11)
+#define QSPI_CMD1_PACKED (1 << 5)
+#define QSPI_CMD1_BITLEN_MASK 0x1F
+#define QSPI_CMD1_BITLEN_SHIFT 0
+
+/* COMMAND2 */
+#define QSPI_CMD2_TX_CLK_TAP_DELAY (1 << 6)
+#define QSPI_CMD2_TX_CLK_TAP_DELAY_MASK (0x3F << 6)
+#define QSPI_CMD2_RX_CLK_TAP_DELAY (1 << 0)
+#define QSPI_CMD2_RX_CLK_TAP_DELAY_MASK (0x3F << 0)
+
+/* TRANSFER STATUS */
+#define QSPI_XFER_STS_RDY (1 << 30)
+
+/* FIFO STATUS */
+#define QSPI_FIFO_STS_CS_INACTIVE (1 << 31)
+#define QSPI_FIFO_STS_FRAME_END (1 << 30)
+#define QSPI_FIFO_STS_RX_FIFO_FLUSH (1 << 15)
+#define QSPI_FIFO_STS_TX_FIFO_FLUSH (1 << 14)
+#define QSPI_FIFO_STS_ERR (1 << 8)
+#define QSPI_FIFO_STS_TX_FIFO_OVF (1 << 7)
+#define QSPI_FIFO_STS_TX_FIFO_UNR (1 << 6)
+#define QSPI_FIFO_STS_RX_FIFO_OVF (1 << 5)
+#define QSPI_FIFO_STS_RX_FIFO_UNR (1 << 4)
+#define QSPI_FIFO_STS_TX_FIFO_FULL (1 << 3)
+#define QSPI_FIFO_STS_TX_FIFO_EMPTY (1 << 2)
+#define QSPI_FIFO_STS_RX_FIFO_FULL (1 << 1)
+#define QSPI_FIFO_STS_RX_FIFO_EMPTY (1 << 0)
+
+#define QSPI_TIMEOUT 1000
+
+struct qspi_regs {
+ u32 command1; /* 000:QSPI_COMMAND1 register */
+ u32 command2; /* 004:QSPI_COMMAND2 register */
+ u32 timing1; /* 008:QSPI_CS_TIM1 register */
+ u32 timing2; /* 00c:QSPI_CS_TIM2 register */
+ u32 xfer_status;/* 010:QSPI_TRANS_STATUS register */
+ u32 fifo_status;/* 014:QSPI_FIFO_STATUS register */
+ u32 tx_data; /* 018:QSPI_TX_DATA register */
+ u32 rx_data; /* 01c:QSPI_RX_DATA register */
+ u32 dma_ctl; /* 020:QSPI_DMA_CTL register */
+ u32 dma_blk; /* 024:QSPI_DMA_BLK register */
+ u32 rsvd[56]; /* 028-107 reserved */
+ u32 tx_fifo; /* 108:QSPI_FIFO1 register */
+ u32 rsvd2[31]; /* 10c-187 reserved */
+ u32 rx_fifo; /* 188:QSPI_FIFO2 register */
+ u32 spare_ctl; /* 18c:QSPI_SPARE_CTRL register */
+};
+
+struct tegra210_qspi_priv {
+ struct qspi_regs *regs;
+ unsigned int freq;
+ unsigned int mode;
+ int periph_id;
+ int valid;
+ int last_transaction_us;
+};
+
+static int tegra210_qspi_ofdata_to_platdata(struct udevice *bus)
+{
+ struct tegra_spi_platdata *plat = bus->platdata;
+ const void *blob = gd->fdt_blob;
+ int node = bus->of_offset;
+
+ plat->base = dev_get_addr(bus);
+ plat->periph_id = clock_decode_periph_id(blob, node);
+
+ if (plat->periph_id == PERIPH_ID_NONE) {
+ debug("%s: could not decode periph id %d\n", __func__,
+ plat->periph_id);
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ /* Use 500KHz as a suitable default */
+ plat->frequency = fdtdec_get_int(blob, node, "spi-max-frequency",
+ 500000);
+ plat->deactivate_delay_us = fdtdec_get_int(blob, node,
+ "spi-deactivate-delay", 0);
+ debug("%s: base=%#08lx, periph_id=%d, max-frequency=%d, deactivate_delay=%d\n",
+ __func__, plat->base, plat->periph_id, plat->frequency,
+ plat->deactivate_delay_us);
+
+ return 0;
+}
+
+static int tegra210_qspi_probe(struct udevice *bus)
+{
+ struct tegra_spi_platdata *plat = dev_get_platdata(bus);
+ struct tegra210_qspi_priv *priv = dev_get_priv(bus);
+
+ priv->regs = (struct qspi_regs *)plat->base;
+
+ priv->last_transaction_us = timer_get_us();
+ priv->freq = plat->frequency;
+ priv->periph_id = plat->periph_id;
+
+ return 0;
+}
+
+static int tegra210_qspi_claim_bus(struct udevice *bus)
+{
+ struct tegra210_qspi_priv *priv = dev_get_priv(bus);
+ struct qspi_regs *regs = priv->regs;
+
+ /* Change SPI clock to correct frequency, PLLP_OUT0 source */
+ clock_start_periph_pll(priv->periph_id, CLOCK_ID_PERIPH, priv->freq);
+
+ debug("%s: FIFO STATUS = %08x\n", __func__, readl(®s->fifo_status));
+
+ /* Set master mode and sw controlled CS */
+ setbits_le32(®s->command1, QSPI_CMD1_M_S | QSPI_CMD1_CS_SW_HW |
+ (priv->mode << QSPI_CMD1_MODE_SHIFT));
+ debug("%s: COMMAND1 = %08x\n", __func__, readl(®s->command1));
+
+ return 0;
+}
+
+/**
+ * Activate the CS by driving it LOW
+ *
+ * @param slave Pointer to spi_slave to which controller has to
+ * communicate with
+ */
+static void spi_cs_activate(struct udevice *dev)
+{
+ struct udevice *bus = dev->parent;
+ struct tegra_spi_platdata *pdata = dev_get_platdata(bus);
+ struct tegra210_qspi_priv *priv = dev_get_priv(bus);
+
+ /* If it's too soon to do another transaction, wait */
+ if (pdata->deactivate_delay_us &&
+ priv->last_transaction_us) {
+ ulong delay_us; /* The delay completed so far */
+ delay_us = timer_get_us() - priv->last_transaction_us;
+ if (delay_us < pdata->deactivate_delay_us)
+ udelay(pdata->deactivate_delay_us - delay_us);
+ }
+
+ clrbits_le32(&priv->regs->command1, QSPI_CMD1_CS_SW_VAL);
+}
+
+/**
+ * Deactivate the CS by driving it HIGH
+ *
+ * @param slave Pointer to spi_slave to which controller has to
+ * communicate with
+ */
+static void spi_cs_deactivate(struct udevice *dev)
+{
+ struct udevice *bus = dev->parent;
+ struct tegra_spi_platdata *pdata = dev_get_platdata(bus);
+ struct tegra210_qspi_priv *priv = dev_get_priv(bus);
+
+ setbits_le32(&priv->regs->command1, QSPI_CMD1_CS_SW_VAL);
+
+ /* Remember time of this transaction so we can honour the bus delay */
+ if (pdata->deactivate_delay_us)
+ priv->last_transaction_us = timer_get_us();
+
+ debug("Deactivate CS, bus '%s'\n", bus->name);
+}
+
+static int tegra210_qspi_xfer(struct udevice *dev, unsigned int bitlen,
+ const void *data_out, void *data_in,
+ unsigned long flags)
+{
+ struct udevice *bus = dev->parent;
+ struct tegra210_qspi_priv *priv = dev_get_priv(bus);
+ struct qspi_regs *regs = priv->regs;
+ u32 reg, tmpdout, tmpdin = 0;
+ const u8 *dout = data_out;
+ u8 *din = data_in;
+ int num_bytes;
+ int ret;
+
+ debug("%s: slave %u:%u dout %p din %p bitlen %u\n",
+ __func__, bus->seq, spi_chip_select(dev), dout, din, bitlen);
+ if (bitlen % 8)
+ return -1;
+ num_bytes = bitlen / 8;
+
+ ret = 0;
+
+ /* clear all error status bits */
+ reg = readl(®s->fifo_status);
+ writel(reg, ®s->fifo_status);
+
+ /* flush RX/TX FIFOs */
+ setbits_le32(®s->fifo_status,
+ (QSPI_FIFO_STS_RX_FIFO_FLUSH |
+ QSPI_FIFO_STS_TX_FIFO_FLUSH));
+ while ((readl(®s->fifo_status) &
+ (QSPI_FIFO_STS_RX_FIFO_FLUSH |
+ QSPI_FIFO_STS_TX_FIFO_FLUSH)))
+ ;
+
+ /*
+ * Notes:
+ * 1. don't set LSBY_FE, so no need to swap bytes from/to TX/RX FIFOs;
+ * 2. don't set RX_EN and TX_EN yet.
+ * (SW needs to make sure that while programming the blk_size,
+ * tx_en and rx_en bits must be zero)
+ * [TODO] I (Yen Lin) have problems when both RX/TX EN bits are set
+ * i.e., both dout and din are not NULL.
+ */
+ clrsetbits_le32(®s->command1,
+ (QSPI_CMD1_LSBI_FE | QSPI_CMD1_LSBY_FE |
+ QSPI_CMD1_RX_EN | QSPI_CMD1_TX_EN),
+ (spi_chip_select(dev) << QSPI_CMD1_CS_SEL_SHIFT));
+
+ /* set xfer size to 1 block (32 bits) */
+ writel(0, ®s->dma_blk);
+
+ if (flags & SPI_XFER_BEGIN)
+ spi_cs_activate(dev);
+
+ /* handle data in 32-bit chunks */
+ while (num_bytes > 0) {
+ int bytes;
+ int tm;
+
+ tmpdout = 0;
+ bytes = (num_bytes > 4) ? 4 : num_bytes;
+
+ if (dout != NULL) {
+ memcpy((void *)&tmpdout, (void *)dout, bytes);
+ dout += bytes;
+ num_bytes -= bytes;
+ writel(tmpdout, ®s->tx_fifo);
+ setbits_le32(®s->command1, QSPI_CMD1_TX_EN);
+ }
+
+ if (din != NULL)
+ setbits_le32(®s->command1, QSPI_CMD1_RX_EN);
+
+ /* clear ready bit */
+ setbits_le32(®s->xfer_status, QSPI_XFER_STS_RDY);
+
+ clrsetbits_le32(®s->command1,
+ QSPI_CMD1_BITLEN_MASK << QSPI_CMD1_BITLEN_SHIFT,
+ (bytes * 8 - 1) << QSPI_CMD1_BITLEN_SHIFT);
+ /* Need to stabilize other reg bit before GO bit set */
+ udelay(2);
+ setbits_le32(®s->command1, QSPI_CMD1_GO);
+ udelay(1);
+
+ /*
+ * Wait for SPI transmit FIFO to empty, or to time out.
+ * The RX FIFO status will be read and cleared last
+ */
+ for (tm = 0; tm < QSPI_TIMEOUT; ++tm) {
+ u32 fifo_status, xfer_status;
+
+ xfer_status = readl(®s->xfer_status);
+ if (!(xfer_status & QSPI_XFER_STS_RDY))
+ continue;
+
+ fifo_status = readl(®s->fifo_status);
+ if (fifo_status & QSPI_FIFO_STS_ERR) {
+ debug("%s: got a fifo error: ", __func__);
+ if (fifo_status & QSPI_FIFO_STS_TX_FIFO_OVF)
+ debug("tx FIFO overflow ");
+ if (fifo_status & QSPI_FIFO_STS_TX_FIFO_UNR)
+ debug("tx FIFO underrun ");
+ if (fifo_status & QSPI_FIFO_STS_RX_FIFO_OVF)
+ debug("rx FIFO overflow ");
+ if (fifo_status & QSPI_FIFO_STS_RX_FIFO_UNR)
+ debug("rx FIFO underrun ");
+ if (fifo_status & QSPI_FIFO_STS_TX_FIFO_FULL)
+ debug("tx FIFO full ");
+ if (fifo_status & QSPI_FIFO_STS_TX_FIFO_EMPTY)
+ debug("tx FIFO empty ");
+ if (fifo_status & QSPI_FIFO_STS_RX_FIFO_FULL)
+ debug("rx FIFO full ");
+ if (fifo_status & QSPI_FIFO_STS_RX_FIFO_EMPTY)
+ debug("rx FIFO empty ");
+ debug("\n");
+ break;
+ }
+
+ if (!(fifo_status & QSPI_FIFO_STS_RX_FIFO_EMPTY)) {
+ tmpdin = readl(®s->rx_fifo);
+ if (din != NULL) {
+ memcpy(din, &tmpdin, bytes);
+ din += bytes;
+ num_bytes -= bytes;
+ }
+ }
+ break;
+ }
+
+ if (tm >= QSPI_TIMEOUT)
+ ret = tm;
+
+ /* clear ACK RDY, etc. bits */
+ writel(readl(®s->fifo_status), ®s->fifo_status);
+ }
+
+ if (flags & SPI_XFER_END)
+ spi_cs_deactivate(dev);
+
+ debug("%s: transfer ended. Value=%08x, fifo_status = %08x\n",
+ __func__, tmpdin, readl(®s->fifo_status));
+
+ if (ret) {
+ printf("%s: timeout during SPI transfer, tm %d\n",
+ __func__, ret);
+ return -1;
+ }
+
+ return ret;
+}
+
+static int tegra210_qspi_set_speed(struct udevice *bus, uint speed)
+{
+ struct tegra_spi_platdata *plat = bus->platdata;
+ struct tegra210_qspi_priv *priv = dev_get_priv(bus);
+
+ if (speed > plat->frequency)
+ speed = plat->frequency;
+ priv->freq = speed;
+ debug("%s: regs=%p, speed=%d\n", __func__, priv->regs, priv->freq);
+
+ return 0;
+}
+
+static int tegra210_qspi_set_mode(struct udevice *bus, uint mode)
+{
+ struct tegra210_qspi_priv *priv = dev_get_priv(bus);
+
+ priv->mode = mode;
+ debug("%s: regs=%p, mode=%d\n", __func__, priv->regs, priv->mode);
+
+ return 0;
+}
+
+static const struct dm_spi_ops tegra210_qspi_ops = {
+ .claim_bus = tegra210_qspi_claim_bus,
+ .xfer = tegra210_qspi_xfer,
+ .set_speed = tegra210_qspi_set_speed,
+ .set_mode = tegra210_qspi_set_mode,
+ /*
+ * cs_info is not needed, since we require all chip selects to be
+ * in the device tree explicitly
+ */
+};
+
+static const struct udevice_id tegra210_qspi_ids[] = {
+ { .compatible = "nvidia,tegra210-qspi" },
+ { }
+};
+
+U_BOOT_DRIVER(tegra210_qspi) = {
+ .name = "tegra210-qspi",
+ .id = UCLASS_SPI,
+ .of_match = tegra210_qspi_ids,
+ .ops = &tegra210_qspi_ops,
+ .ofdata_to_platdata = tegra210_qspi_ofdata_to_platdata,
+ .platdata_auto_alloc_size = sizeof(struct tegra_spi_platdata),
+ .priv_auto_alloc_size = sizeof(struct tegra210_qspi_priv),
+ .per_child_auto_alloc_size = sizeof(struct spi_slave),
+ .probe = tegra210_qspi_probe,
+};
--
1.8.2.1.610.g562af5b
5
8

26 Oct '15
This patch adds the device tree binding doc for the Tegra
SPI/QSPI controllers on Tegra114 and Tegra210.
Signed-off-by: Tom Warren <twarren(a)nvidia.com>
---
Changes in v2:
- based it more on kernel's nvidia,tegra114-spi.txt binding
- changes based on prelim review by swarren(a)nvidia.com
doc/device-tree-bindings/spi/spi-tegra.txt | 60 ++++++++++++++++++++++++++++++
1 file changed, 60 insertions(+)
create mode 100644 doc/device-tree-bindings/spi/spi-tegra.txt
diff --git a/doc/device-tree-bindings/spi/spi-tegra.txt b/doc/device-tree-bindings/spi/spi-tegra.txt
new file mode 100644
index 0000000..3664267
--- /dev/null
+++ b/doc/device-tree-bindings/spi/spi-tegra.txt
@@ -0,0 +1,60 @@
+NVIDIA Tegra SPI/QSPI controller.
+
+Required properties:
+- compatible : should be one of the following:
+ "nvidia,tegra114-spi" (for Tegra114)
+ "nvidia,tegra210-qspi" (for Tegra210)
+- reg: Should contain SPI registers location and length.
+- interrupts: Should contain SPI interrupts.
+- clock-names : Must include the following entries:
+ - spi
+- clocks : Must contain an entry for each entry in clock-names.
+ See ../clocks/clock-bindings.txt for details.
+- resets : Must contain an entry for each entry in reset-names.
+ See ../reset/reset.txt for details.
+- reset-names : Must include the following entries:
+ - spi
+
+Optional properties:
+- dmas : Must contain an entry for each entry in clock-names.
+ See ../dma/dma.txt for details.
+- dma-names : Must include the following entries:
+ - rx
+ - tx
+
+Recommended properties:
+- spi-max-frequency: Definition as per spi-bus.txt
+
+Example:
+
+spi@7000d600 {
+ compatible = "nvidia,tegra114-spi";
+ reg = <0x7000d600 0x200>;
+ interrupts = <0 82 0x04>;
+ spi-max-frequency = <25000000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car 44>;
+ clock-names = "spi";
+ resets = <&tegra_car 44>;
+ reset-names = "spi";
+ dmas = <&apbdma 16>, <&apbdma 16>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+};
+
+spi@70410000 {
+ compatible = "nvidia,tegra210-qspi";
+ reg = <0x0 0x70410000 0x0 0x1000>;
+ interrupts = <0 10 0x04>;
+ spi-max-frequency = <24000000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car 211>;
+ clock-names = "spi";
+ resets = <&tegra_car 211>;
+ reset-names = "spi";
+ dmas = <&apbdma 16>, <&apbdma 16>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+};
--
1.8.2.1.610.g562af5b
3
2

26 Oct '15
From: Fabio Estevam <fabio.estevam(a)freescale.com>
Use the log2 header files from the kernel.
Imported from kernel 4.2.3.
Signed-off-by: Fabio Estevam <fabio.estevam(a)freescale.com>
---
include/linux/log2.h | 205 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 205 insertions(+)
create mode 100644 include/linux/log2.h
diff --git a/include/linux/log2.h b/include/linux/log2.h
new file mode 100644
index 0000000..e3ee91e
--- /dev/null
+++ b/include/linux/log2.h
@@ -0,0 +1,205 @@
+/* Integer base 2 logarithm calculation
+ *
+ * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells(a)redhat.com)
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _LINUX_LOG2_H
+#define _LINUX_LOG2_H
+
+#include <linux/types.h>
+#include <linux/bitops.h>
+
+/*
+ * deal with unrepresentable constant logarithms
+ */
+extern __attribute__((const, noreturn))
+int ____ilog2_NaN(void);
+
+/*
+ * non-constant log of base 2 calculators
+ * - the arch may override these in asm/bitops.h if they can be implemented
+ * more efficiently than using fls() and fls64()
+ * - the arch is not required to handle n==0 if implementing the fallback
+ */
+#ifndef CONFIG_ARCH_HAS_ILOG2_U32
+static inline __attribute__((const))
+int __ilog2_u32(u32 n)
+{
+ return fls(n) - 1;
+}
+#endif
+
+#ifndef CONFIG_ARCH_HAS_ILOG2_U64
+static inline __attribute__((const))
+int __ilog2_u64(u64 n)
+{
+ return fls64(n) - 1;
+}
+#endif
+
+/*
+ * Determine whether some value is a power of two, where zero is
+ * *not* considered a power of two.
+ */
+
+static inline __attribute__((const))
+bool is_power_of_2(unsigned long n)
+{
+ return (n != 0 && ((n & (n - 1)) == 0));
+}
+
+/*
+ * round up to nearest power of two
+ */
+static inline __attribute__((const))
+unsigned long __roundup_pow_of_two(unsigned long n)
+{
+ return 1UL << fls_long(n - 1);
+}
+
+/*
+ * round down to nearest power of two
+ */
+static inline __attribute__((const))
+unsigned long __rounddown_pow_of_two(unsigned long n)
+{
+ return 1UL << (fls_long(n) - 1);
+}
+
+/**
+ * ilog2 - log of base 2 of 32-bit or a 64-bit unsigned value
+ * @n - parameter
+ *
+ * constant-capable log of base 2 calculation
+ * - this can be used to initialise global variables from constant data, hence
+ * the massive ternary operator construction
+ *
+ * selects the appropriately-sized optimised version depending on sizeof(n)
+ */
+#define ilog2(n) \
+( \
+ __builtin_constant_p(n) ? ( \
+ (n) < 1 ? ____ilog2_NaN() : \
+ (n) & (1ULL << 63) ? 63 : \
+ (n) & (1ULL << 62) ? 62 : \
+ (n) & (1ULL << 61) ? 61 : \
+ (n) & (1ULL << 60) ? 60 : \
+ (n) & (1ULL << 59) ? 59 : \
+ (n) & (1ULL << 58) ? 58 : \
+ (n) & (1ULL << 57) ? 57 : \
+ (n) & (1ULL << 56) ? 56 : \
+ (n) & (1ULL << 55) ? 55 : \
+ (n) & (1ULL << 54) ? 54 : \
+ (n) & (1ULL << 53) ? 53 : \
+ (n) & (1ULL << 52) ? 52 : \
+ (n) & (1ULL << 51) ? 51 : \
+ (n) & (1ULL << 50) ? 50 : \
+ (n) & (1ULL << 49) ? 49 : \
+ (n) & (1ULL << 48) ? 48 : \
+ (n) & (1ULL << 47) ? 47 : \
+ (n) & (1ULL << 46) ? 46 : \
+ (n) & (1ULL << 45) ? 45 : \
+ (n) & (1ULL << 44) ? 44 : \
+ (n) & (1ULL << 43) ? 43 : \
+ (n) & (1ULL << 42) ? 42 : \
+ (n) & (1ULL << 41) ? 41 : \
+ (n) & (1ULL << 40) ? 40 : \
+ (n) & (1ULL << 39) ? 39 : \
+ (n) & (1ULL << 38) ? 38 : \
+ (n) & (1ULL << 37) ? 37 : \
+ (n) & (1ULL << 36) ? 36 : \
+ (n) & (1ULL << 35) ? 35 : \
+ (n) & (1ULL << 34) ? 34 : \
+ (n) & (1ULL << 33) ? 33 : \
+ (n) & (1ULL << 32) ? 32 : \
+ (n) & (1ULL << 31) ? 31 : \
+ (n) & (1ULL << 30) ? 30 : \
+ (n) & (1ULL << 29) ? 29 : \
+ (n) & (1ULL << 28) ? 28 : \
+ (n) & (1ULL << 27) ? 27 : \
+ (n) & (1ULL << 26) ? 26 : \
+ (n) & (1ULL << 25) ? 25 : \
+ (n) & (1ULL << 24) ? 24 : \
+ (n) & (1ULL << 23) ? 23 : \
+ (n) & (1ULL << 22) ? 22 : \
+ (n) & (1ULL << 21) ? 21 : \
+ (n) & (1ULL << 20) ? 20 : \
+ (n) & (1ULL << 19) ? 19 : \
+ (n) & (1ULL << 18) ? 18 : \
+ (n) & (1ULL << 17) ? 17 : \
+ (n) & (1ULL << 16) ? 16 : \
+ (n) & (1ULL << 15) ? 15 : \
+ (n) & (1ULL << 14) ? 14 : \
+ (n) & (1ULL << 13) ? 13 : \
+ (n) & (1ULL << 12) ? 12 : \
+ (n) & (1ULL << 11) ? 11 : \
+ (n) & (1ULL << 10) ? 10 : \
+ (n) & (1ULL << 9) ? 9 : \
+ (n) & (1ULL << 8) ? 8 : \
+ (n) & (1ULL << 7) ? 7 : \
+ (n) & (1ULL << 6) ? 6 : \
+ (n) & (1ULL << 5) ? 5 : \
+ (n) & (1ULL << 4) ? 4 : \
+ (n) & (1ULL << 3) ? 3 : \
+ (n) & (1ULL << 2) ? 2 : \
+ (n) & (1ULL << 1) ? 1 : \
+ (n) & (1ULL << 0) ? 0 : \
+ ____ilog2_NaN() \
+ ) : \
+ (sizeof(n) <= 4) ? \
+ __ilog2_u32(n) : \
+ __ilog2_u64(n) \
+ )
+
+/**
+ * roundup_pow_of_two - round the given value up to nearest power of two
+ * @n - parameter
+ *
+ * round the given value up to the nearest power of two
+ * - the result is undefined when n == 0
+ * - this can be used to initialise global variables from constant data
+ */
+#define roundup_pow_of_two(n) \
+( \
+ __builtin_constant_p(n) ? ( \
+ (n == 1) ? 1 : \
+ (1UL << (ilog2((n) - 1) + 1)) \
+ ) : \
+ __roundup_pow_of_two(n) \
+ )
+
+/**
+ * rounddown_pow_of_two - round the given value down to nearest power of two
+ * @n - parameter
+ *
+ * round the given value down to the nearest power of two
+ * - the result is undefined when n == 0
+ * - this can be used to initialise global variables from constant data
+ */
+#define rounddown_pow_of_two(n) \
+( \
+ __builtin_constant_p(n) ? ( \
+ (1UL << ilog2(n))) : \
+ __rounddown_pow_of_two(n) \
+ )
+
+/**
+ * order_base_2 - calculate the (rounded up) base 2 order of the argument
+ * @n: parameter
+ *
+ * The first few values calculated by this routine:
+ * ob2(0) = 0
+ * ob2(1) = 0
+ * ob2(2) = 1
+ * ob2(3) = 2
+ * ob2(4) = 2
+ * ob2(5) = 3
+ * ... and so on.
+ */
+
+#define order_base_2(n) ilog2(roundup_pow_of_two(n))
+
+#endif /* _LINUX_LOG2_H */
--
1.9.1
3
25

26 Oct '15
From: Stephen Warren <swarren(a)nvidia.com>
PCI addresses are always represented as 3 cells in DT. (one cell for bus
and device, and two cells for a 64-bit addres). This does not vary based
on either the physical address size of the CPU, nor any #address-cells
property in DT (or more precisely, #address-cells must be set to 3 in any
PCIe controller's node).
Fix fdtdec_get_pci_addr() to use conversion functions that operate on
(fixed) cell-sized data rather than (varying) physical-address-sized
data, so that the function works on 64-bit systems.
Signed-off-by: Stephen Warren <swarren(a)nvidia.com>
---
lib/fdtdec.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index 1fdb4f0d9ce9..275971d40096 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -219,13 +219,13 @@ int fdtdec_get_pci_addr(const void *blob, int node, enum fdt_pci_space type,
for (i = 0; i < num; i++) {
debug("pci address #%d: %08lx %08lx %08lx\n", i,
- (ulong)fdt_addr_to_cpu(cell[0]),
- (ulong)fdt_addr_to_cpu(cell[1]),
- (ulong)fdt_addr_to_cpu(cell[2]));
- if ((fdt_addr_to_cpu(*cell) & type) == type) {
- addr->phys_hi = fdt_addr_to_cpu(cell[0]);
- addr->phys_mid = fdt_addr_to_cpu(cell[1]);
- addr->phys_lo = fdt_addr_to_cpu(cell[2]);
+ (ulong)fdt32_to_cpu(cell[0]),
+ (ulong)fdt32_to_cpu(cell[1]),
+ (ulong)fdt32_to_cpu(cell[2]));
+ if ((fdt32_to_cpu(*cell) & type) == type) {
+ addr->phys_hi = fdt32_to_cpu(cell[0]);
+ addr->phys_mid = fdt32_to_cpu(cell[1]);
+ addr->phys_lo = fdt32_to_cpu(cell[1]);
break;
} else {
cell += (FDT_PCI_ADDR_CELLS +
--
1.9.1
3
5