arm: mvebu: Enable NAND controller on MVEBU SoC's

This patch enables the NAND controller on the Armada XP/38x and provides
a new function that returns the NAND controller input clock. This
function will be used by the MVEBU NAND driver.

As part of this patch, the multiple BIT macro definitions are moved
to a common place in soc.h.

Signed-off-by: Stefan Roese <sr@denx.de>
Cc: Peter Morrow <peter@senient.com>
Cc: Luka Perkov <luka.perkov@sartura.hr>
diff --git a/arch/arm/mach-mvebu/cpu.c b/arch/arm/mach-mvebu/cpu.c
index fa82067..38e15aa 100644
--- a/arch/arm/mach-mvebu/cpu.c
+++ b/arch/arm/mach-mvebu/cpu.c
@@ -241,6 +241,16 @@
 	 */
 	mvebu_mbus_probe(windows, ARRAY_SIZE(windows));
 
+	if (mvebu_soc_family() == MVEBU_SOC_AXP) {
+		/* Enable GBE0, GBE1, LCD and NFC PUP */
+		clrsetbits_le32(ARMADA_XP_PUP_ENABLE, 0,
+				GE0_PUP_EN | GE1_PUP_EN | LCD_PUP_EN |
+				NAND_PUP_EN | SPI_PUP_EN);
+	}
+
+	/* Enable NAND and NAND arbiter */
+	clrsetbits_le32(MVEBU_SOC_DEV_MUX_REG, 0, NAND_EN | NAND_ARBITER_EN);
+
 	/* Disable MBUS error propagation */
 	clrsetbits_le32(SOC_COHERENCY_FABRIC_CTRL_REG, MBUS_ERR_PROP_EN, 0);
 
@@ -248,6 +258,13 @@
 }
 #endif /* CONFIG_ARCH_CPU_INIT */
 
+u32 mvebu_get_nand_clock(void)
+{
+	return CONFIG_SYS_MVEBU_PLL_CLOCK /
+		((readl(MVEBU_CORE_DIV_CLK_CTRL(1)) &
+		  NAND_ECC_DIVCKL_RATIO_MASK) >> NAND_ECC_DIVCKL_RATIO_OFFS);
+}
+
 /*
  * SOC specific misc init
  */
diff --git a/arch/arm/mach-mvebu/include/mach/cpu.h b/arch/arm/mach-mvebu/include/mach/cpu.h
index 674fdaa..6fa4173 100644
--- a/arch/arm/mach-mvebu/include/mach/cpu.h
+++ b/arch/arm/mach-mvebu/include/mach/cpu.h
@@ -117,6 +117,7 @@
 void mvebu_sdram_size_adjust(enum memory_bank bank);
 int mvebu_mbus_probe(struct mbus_win windows[], int count);
 int mvebu_soc_family(void);
+u32 mvebu_get_nand_clock(void);
 
 int mv_sdh_init(unsigned long regbase, u32 max_clk, u32 min_clk, u32 quirks);
 
diff --git a/arch/arm/mach-mvebu/include/mach/soc.h b/arch/arm/mach-mvebu/include/mach/soc.h
index a29e5dc..6115d6e 100644
--- a/arch/arm/mach-mvebu/include/mach/soc.h
+++ b/arch/arm/mach-mvebu/include/mach/soc.h
@@ -11,6 +11,8 @@
 #ifndef _MVEBU_SOC_H
 #define _MVEBU_SOC_H
 
+#define BIT(x)			(1 << (x))
+
 #define SOC_MV78460_ID		0x7846
 #define SOC_88F6810_ID		0x6810
 #define SOC_88F6820_ID		0x6820
@@ -25,6 +27,9 @@
 #define CONFIG_SYS_TCLK		250000000	/* 250MHz */
 #endif
 
+/* Armada XP PLL frequency (used for NAND clock generation) */
+#define CONFIG_SYS_MVEBU_PLL_CLOCK	2000000000
+
 /* SOC specific definations */
 #define INTREG_BASE		0xd0000000
 #define INTREG_BASE_ADDR_REG	(INTREG_BASE + 0x20080)
@@ -53,6 +58,7 @@
 #define MVEBU_GPIO1_BASE	(MVEBU_REGISTER(0x18140))
 #define MVEBU_GPIO2_BASE	(MVEBU_REGISTER(0x18180))
 #define MVEBU_SYSTEM_REG_BASE	(MVEBU_REGISTER(0x18200))
+#define MVEBU_CLOCK_BASE	(MVEBU_REGISTER(0x18700))
 #define MVEBU_CPU_WIN_BASE	(MVEBU_REGISTER(0x20000))
 #define MVEBU_SDRAM_BASE	(MVEBU_REGISTER(0x20180))
 #define MVEBU_TIMER_BASE	(MVEBU_REGISTER(0x20300))
@@ -64,6 +70,7 @@
 #define MVEBU_EGIGA1_BASE	(MVEBU_REGISTER(0x74000))
 #define MVEBU_AXP_SATA_BASE	(MVEBU_REGISTER(0xa0000))
 #define MVEBU_SATA0_BASE	(MVEBU_REGISTER(0xa8000))
+#define MVEBU_NAND_BASE		(MVEBU_REGISTER(0xd0000))
 #define MVEBU_SDIO_BASE		(MVEBU_REGISTER(0xd8000))
 
 #define SOC_COHERENCY_FABRIC_CTRL_REG	(MVEBU_REGISTER(0x20200))
@@ -72,6 +79,21 @@
 #define MBUS_BRIDGE_WIN_CTRL_REG (MVEBU_REGISTER(0x20250))
 #define MBUS_BRIDGE_WIN_BASE_REG (MVEBU_REGISTER(0x20254))
 
+#define MVEBU_SOC_DEV_MUX_REG	(MVEBU_SYSTEM_REG_BASE + 0x08)
+#define NAND_EN			BIT(0)
+#define NAND_ARBITER_EN		BIT(27)
+
+#define ARMADA_XP_PUP_ENABLE	(MVEBU_SYSTEM_REG_BASE + 0x44c)
+#define GE0_PUP_EN		BIT(0)
+#define GE1_PUP_EN		BIT(1)
+#define LCD_PUP_EN		BIT(2)
+#define NAND_PUP_EN		BIT(4)
+#define SPI_PUP_EN		BIT(5)
+
+#define MVEBU_CORE_DIV_CLK_CTRL(i)	(MVEBU_CLOCK_BASE + ((i) * 0x8))
+#define NAND_ECC_DIVCKL_RATIO_OFFS	8
+#define NAND_ECC_DIVCKL_RATIO_MASK	(0x3F << NAND_ECC_DIVCKL_RATIO_OFFS)
+
 #define SDRAM_MAX_CS		4
 #define SDRAM_ADDR_MASK		0xFF000000
 
diff --git a/arch/arm/mach-mvebu/mbus.c b/arch/arm/mach-mvebu/mbus.c
index 71fa693..771cce6 100644
--- a/arch/arm/mach-mvebu/mbus.c
+++ b/arch/arm/mach-mvebu/mbus.c
@@ -55,8 +55,6 @@
 #include <linux/compat.h>
 #include <linux/mbus.h>
 
-#define BIT(nr)			(1UL << (nr))
-
 /* DDR target is the same on all platforms */
 #define TARGET_DDR		0