ARM: atmel: add sama5d3xek support

Add sama5d3xek support with following feature
  - boot from NAND flash, PMECC support, 4bit ECC @ 512 bytes sector
  - boot from SPI flash support
  - boot from SD card support
  - LCD support
  - EMAC support
  - USB OHCI support

Signed-off-by: Bo Shen <voice.shen@atmel.com>
Signed-off-by: Andreas Bießmann <andreas.devel@googlemail.com>
diff --git a/arch/arm/cpu/armv7/at91/clock.c b/arch/arm/cpu/armv7/at91/clock.c
new file mode 100644
index 0000000..624b52c
--- /dev/null
+++ b/arch/arm/cpu/armv7/at91/clock.c
@@ -0,0 +1,125 @@
+/*
+ * [origin: Linux kernel linux/arch/arm/mach-at91/clock.c]
+ *
+ * Copyright (C) 2005 David Brownell
+ * Copyright (C) 2005 Ivan Kokshaysky
+ * Copyright (C) 2009 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ * Copyright (C) 2013 Bo Shen <voice.shen@atmel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/at91_pmc.h>
+#include <asm/arch/clk.h>
+
+#if !defined(CONFIG_AT91FAMILY)
+# error You need to define CONFIG_AT91FAMILY in your board config!
+#endif
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static unsigned long at91_css_to_rate(unsigned long css)
+{
+	switch (css) {
+	case AT91_PMC_MCKR_CSS_SLOW:
+		return CONFIG_SYS_AT91_SLOW_CLOCK;
+	case AT91_PMC_MCKR_CSS_MAIN:
+		return gd->arch.main_clk_rate_hz;
+	case AT91_PMC_MCKR_CSS_PLLA:
+		return gd->arch.plla_rate_hz;
+	}
+
+	return 0;
+}
+
+static u32 at91_pll_rate(u32 freq, u32 reg)
+{
+	unsigned mul, div;
+
+	div = reg & 0xff;
+	mul = (reg >> 18) & 0x7f;
+	if (div && mul) {
+		freq /= div;
+		freq *= mul + 1;
+	} else {
+		freq = 0;
+	}
+
+	return freq;
+}
+
+int at91_clock_init(unsigned long main_clock)
+{
+	unsigned freq, mckr;
+	struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
+#ifndef CONFIG_SYS_AT91_MAIN_CLOCK
+	unsigned tmp;
+	/*
+	 * When the bootloader initialized the main oscillator correctly,
+	 * there's no problem using the cycle counter.  But if it didn't,
+	 * or when using oscillator bypass mode, we must be told the speed
+	 * of the main clock.
+	 */
+	if (!main_clock) {
+		do {
+			tmp = readl(&pmc->mcfr);
+		} while (!(tmp & AT91_PMC_MCFR_MAINRDY));
+		tmp &= AT91_PMC_MCFR_MAINF_MASK;
+		main_clock = tmp * (CONFIG_SYS_AT91_SLOW_CLOCK / 16);
+	}
+#endif
+	gd->arch.main_clk_rate_hz = main_clock;
+
+	/* report if PLLA is more than mildly overclocked */
+	gd->arch.plla_rate_hz = at91_pll_rate(main_clock, readl(&pmc->pllar));
+
+	/*
+	 * MCK and CPU derive from one of those primary clocks.
+	 * For now, assume this parentage won't change.
+	 */
+	mckr = readl(&pmc->mckr);
+
+	/* plla divisor by 2 */
+	if (mckr & (1 << 12))
+		gd->arch.plla_rate_hz >>= 1;
+
+	gd->arch.mck_rate_hz = at91_css_to_rate(mckr & AT91_PMC_MCKR_CSS_MASK);
+	freq = gd->arch.mck_rate_hz;
+
+	/* prescale */
+	freq >>= mckr & AT91_PMC_MCKR_PRES_MASK;
+
+	switch (mckr & AT91_PMC_MCKR_MDIV_MASK) {
+	case AT91_PMC_MCKR_MDIV_2:
+		gd->arch.mck_rate_hz = freq / 2;
+		break;
+	case AT91_PMC_MCKR_MDIV_3:
+		gd->arch.mck_rate_hz = freq / 3;
+		break;
+	case AT91_PMC_MCKR_MDIV_4:
+		gd->arch.mck_rate_hz = freq / 4;
+		break;
+	default:
+		break;
+	}
+
+	gd->arch.cpu_clk_rate_hz = freq;
+
+	return 0;
+}
+
+void at91_periph_clk_enable(int id)
+{
+	struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
+
+	if (id > 31)
+		writel(1 << (id - 32), &pmc->pcer1);
+	else
+		writel(1 << id, &pmc->pcer);
+}