From 41e5ee54e3502ca4854f16d69278698075946238 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Wed, 22 Oct 2014 12:13:17 +0200 Subject: arm: armada-xp: Add basic support for Marvell Armada XP SoC This basic support for the Marvell Armada XP is base on the existing kirkwood support. Which has been generatized by moving some common files into common marvell locations. This is in preparation for the upcoming Armada XP MV78460 support. Signed-off-by: Stefan Roese Tested-by: Luka Perkov --- arch/arm/cpu/armv7/armada-xp/Makefile | 7 + arch/arm/cpu/armv7/armada-xp/cpu.c | 193 +++++++++++++++++++++++++++ arch/arm/include/asm/arch-armada-xp/config.h | 82 ++++++++++++ arch/arm/include/asm/arch-armada-xp/cpu.h | 107 +++++++++++++++ arch/arm/include/asm/arch-armada-xp/soc.h | 57 ++++++++ 5 files changed, 446 insertions(+) create mode 100644 arch/arm/cpu/armv7/armada-xp/Makefile create mode 100644 arch/arm/cpu/armv7/armada-xp/cpu.c create mode 100644 arch/arm/include/asm/arch-armada-xp/config.h create mode 100644 arch/arm/include/asm/arch-armada-xp/cpu.h create mode 100644 arch/arm/include/asm/arch-armada-xp/soc.h (limited to 'arch') diff --git a/arch/arm/cpu/armv7/armada-xp/Makefile b/arch/arm/cpu/armv7/armada-xp/Makefile new file mode 100644 index 0000000..885dcee --- /dev/null +++ b/arch/arm/cpu/armv7/armada-xp/Makefile @@ -0,0 +1,7 @@ +# +# Copyright (C) 2014 Stefan Roese +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y = cpu.o diff --git a/arch/arm/cpu/armv7/armada-xp/cpu.c b/arch/arm/cpu/armv7/armada-xp/cpu.c new file mode 100644 index 0000000..1cf70a9 --- /dev/null +++ b/arch/arm/cpu/armv7/armada-xp/cpu.c @@ -0,0 +1,193 @@ +/* + * Copyright (C) 2014 Stefan Roese + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include + +#define DDR_BASE_CS_OFF(n) (0x0000 + ((n) << 3)) +#define DDR_SIZE_CS_OFF(n) (0x0004 + ((n) << 3)) + +static struct mbus_win windows[] = { + /* PCIE MEM address space */ + { DEFADR_PCI_MEM, 256 << 20, CPU_TARGET_PCIE13, CPU_ATTR_PCIE_MEM }, + + /* PCIE IO address space */ + { DEFADR_PCI_IO, 64 << 10, CPU_TARGET_PCIE13, CPU_ATTR_PCIE_IO }, + + /* SPI */ + { DEFADR_SPIF, 8 << 20, CPU_TARGET_DEVICEBUS_BOOTROM_SPI, + CPU_ATTR_SPIFLASH }, + + /* NOR */ + { DEFADR_BOOTROM, 8 << 20, CPU_TARGET_DEVICEBUS_BOOTROM_SPI, + CPU_ATTR_BOOTROM }, +}; + +void reset_cpu(unsigned long ignored) +{ + struct mvebu_system_registers *reg = + (struct mvebu_system_registers *)MVEBU_SYSTEM_REG_BASE; + + writel(readl(®->rstoutn_mask) | 1, ®->rstoutn_mask); + writel(readl(®->sys_soft_rst) | 1, ®->sys_soft_rst); + while (1) + ; +} + +#if defined(CONFIG_DISPLAY_CPUINFO) +int print_cpuinfo(void) +{ + u16 devid = (readl(MVEBU_REG_PCIE_DEVID) >> 16) & 0xffff; + u8 revid = readl(MVEBU_REG_PCIE_REVID) & 0xff; + + puts("SoC: "); + + switch (devid) { + case SOC_MV78460_ID: + puts("MV78460-"); + break; + default: + puts("Unknown-"); + break; + } + + switch (revid) { + case 1: + puts("A0\n"); + break; + case 2: + puts("B0\n"); + break; + default: + puts("??\n"); + break; + } + + return 0; +} +#endif /* CONFIG_DISPLAY_CPUINFO */ + +/* + * This function initialize Controller DRAM Fastpath windows. + * It takes the CS size information from the 0x1500 scratch registers + * and sets the correct windows sizes and base addresses accordingly. + * + * These values are set in the scratch registers by the Marvell + * DDR3 training code, which is executed by the BootROM before the + * main payload (U-Boot) is executed. This training code is currently + * only available in the Marvell U-Boot version. It needs to be + * ported to mainline U-Boot SPL at some point. + */ +static void update_sdram_window_sizes(void) +{ + u64 base = 0; + u32 size, temp; + int i; + + for (i = 0; i < SDRAM_MAX_CS; i++) { + size = readl((MVEBU_SDRAM_SCRATCH + (i * 8))) & SDRAM_ADDR_MASK; + if (size != 0) { + size |= ~(SDRAM_ADDR_MASK); + + /* Set Base Address */ + temp = (base & 0xFF000000ll) | ((base >> 32) & 0xF); + writel(temp, MVEBU_SDRAM_BASE + DDR_BASE_CS_OFF(i)); + + /* + * Check if out of max window size and resize + * the window + */ + temp = (readl(MVEBU_SDRAM_BASE + DDR_SIZE_CS_OFF(i)) & + ~(SDRAM_ADDR_MASK)) | 1; + temp |= (size & SDRAM_ADDR_MASK); + writel(temp, MVEBU_SDRAM_BASE + DDR_SIZE_CS_OFF(i)); + + base += ((u64)size + 1); + } else { + /* + * Disable window if not used, otherwise this + * leads to overlapping enabled windows with + * pretty strange results + */ + clrbits_le32(MVEBU_SDRAM_BASE + DDR_SIZE_CS_OFF(i), 1); + } + } +} + +#ifdef CONFIG_ARCH_CPU_INIT +int arch_cpu_init(void) +{ + /* Linux expects the internal registers to be at 0xf1000000 */ + writel(SOC_REGS_PHY_BASE, INTREG_BASE_ADDR_REG); + + /* + * We need to call mvebu_mbus_probe() before calling + * update_sdram_window_sizes() as it disables all previously + * configured mbus windows and then configures them as + * required for U-Boot. Calling update_sdram_window_sizes() + * without this configuration will not work, as the internal + * registers can't be accessed reliably because of potenial + * double mapping. + * After updating the SDRAM access windows we need to call + * mvebu_mbus_probe() again, as this now correctly configures + * the SDRAM areas that are later used by the MVEBU drivers + * (e.g. USB, NETA). + */ + + /* + * First disable all windows + */ + mvebu_mbus_probe(NULL, 0); + + /* + * Now the SDRAM access windows can be reconfigured using + * the information in the SDRAM scratch pad registers + */ + update_sdram_window_sizes(); + + /* + * Finally the mbus windows can be configured with the + * updated SDRAM sizes + */ + mvebu_mbus_probe(windows, ARRAY_SIZE(windows)); + + return 0; +} +#endif /* CONFIG_ARCH_CPU_INIT */ + +/* + * SOC specific misc init + */ +#if defined(CONFIG_ARCH_MISC_INIT) +int arch_misc_init(void) +{ + /* Nothing yet, perhaps we need something here later */ + return 0; +} +#endif /* CONFIG_ARCH_MISC_INIT */ + +#ifdef CONFIG_MVNETA +int cpu_eth_init(bd_t *bis) +{ + mvneta_initialize(bis, MVEBU_EGIGA0_BASE, 0, CONFIG_PHY_BASE_ADDR + 0); + mvneta_initialize(bis, MVEBU_EGIGA1_BASE, 1, CONFIG_PHY_BASE_ADDR + 1); + mvneta_initialize(bis, MVEBU_EGIGA2_BASE, 2, CONFIG_PHY_BASE_ADDR + 2); + mvneta_initialize(bis, MVEBU_EGIGA3_BASE, 3, CONFIG_PHY_BASE_ADDR + 3); + + return 0; +} +#endif + +#ifndef CONFIG_SYS_DCACHE_OFF +void enable_caches(void) +{ + /* Enable D-cache. I-cache is already enabled in start.S */ + dcache_enable(); +} +#endif diff --git a/arch/arm/include/asm/arch-armada-xp/config.h b/arch/arm/include/asm/arch-armada-xp/config.h new file mode 100644 index 0000000..00ee775 --- /dev/null +++ b/arch/arm/include/asm/arch-armada-xp/config.h @@ -0,0 +1,82 @@ +/* + * (C) Copyright 2011 + * Marvell Semiconductor + * Written-by: Lei Wen + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * This file should be included in board config header file. + * + * It supports common definitions for Armada XP platforms + */ + +#ifndef _ARMADA_XP_CONFIG_H +#define _ARMADA_XP_CONFIG_H + +#include + +#define MV88F78X60 /* for the DDR training bin_hdr code */ + +#define CONFIG_SYS_CACHELINE_SIZE 32 + +/* + * By default kwbimage.cfg from board specific folder is used + * If for some board, different configuration file need to be used, + * CONFIG_SYS_KWD_CONFIG should be defined in board specific header file + */ +#ifndef CONFIG_SYS_KWD_CONFIG +#define CONFIG_SYS_KWD_CONFIG $(CONFIG_BOARDDIR)/kwbimage.cfg +#endif /* CONFIG_SYS_KWD_CONFIG */ + +/* Add target to build it automatically upon "make" */ +#define CONFIG_BUILD_TARGET "u-boot.kwb" + +/* end of 16M scrubbed by training in bootrom */ +#define CONFIG_SYS_INIT_SP_ADDR 0x00FF0000 +#define CONFIG_NR_DRAM_BANKS_MAX 2 + +#define MV_UART_CONSOLE_BASE MVEBU_UART0_BASE + +/* + * SPI Flash configuration + */ +#ifdef CONFIG_CMD_SF +#define CONFIG_HARD_SPI 1 +#define CONFIG_KIRKWOOD_SPI 1 +#ifndef CONFIG_ENV_SPI_BUS +# define CONFIG_ENV_SPI_BUS 0 +#endif +#ifndef CONFIG_ENV_SPI_CS +# define CONFIG_ENV_SPI_CS 0 +#endif +#ifndef CONFIG_ENV_SPI_MAX_HZ +# define CONFIG_ENV_SPI_MAX_HZ 50000000 +#endif +#endif + +/* + * Ethernet Driver configuration + */ +#ifdef CONFIG_CMD_NET +#define CONFIG_CMD_MII +#define CONFIG_MII /* expose smi ove miiphy interface */ +#define CONFIG_MVNETA /* Enable Marvell Gbe Controller Driver */ +#define CONFIG_PHYLIB +#define CONFIG_ENV_OVERWRITE /* ethaddr can be reprogrammed */ +#define CONFIG_PHY_GIGE /* GbE speed/duplex detect */ +#endif /* CONFIG_CMD_NET */ + +/* + * I2C related stuff + */ +#ifdef CONFIG_CMD_I2C +#ifndef CONFIG_SYS_I2C_SOFT +#define CONFIG_I2C_MVTWSI +#endif +#define CONFIG_SYS_I2C_SLAVE 0x0 +#define CONFIG_SYS_I2C_SPEED 100000 +#endif + +#endif /* _ARMADA_XP_CONFIG_H */ diff --git a/arch/arm/include/asm/arch-armada-xp/cpu.h b/arch/arm/include/asm/arch-armada-xp/cpu.h new file mode 100644 index 0000000..6b60c21 --- /dev/null +++ b/arch/arm/include/asm/arch-armada-xp/cpu.h @@ -0,0 +1,107 @@ +/* + * (C) Copyright 2009 + * Marvell Semiconductor + * Written-by: Prafulla Wadaskar + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _ARMADA_XP_CPU_H +#define _ARMADA_XP_CPU_H + +#include + +#ifndef __ASSEMBLY__ + +#define MVEBU_REG_PCIE_DEVID (MVEBU_REG_PCIE_BASE + 0x00) +#define MVEBU_REG_PCIE_REVID (MVEBU_REG_PCIE_BASE + 0x08) + +enum memory_bank { + BANK0, + BANK1, + BANK2, + BANK3 +}; + +enum cpu_winen { + CPU_WIN_DISABLE, + CPU_WIN_ENABLE +}; + +enum cpu_target { + CPU_TARGET_DRAM = 0x0, + CPU_TARGET_DEVICEBUS_BOOTROM_SPI = 0x1, + CPU_TARGET_ETH23 = 0x3, + CPU_TARGET_PCIE02 = 0x4, + CPU_TARGET_ETH01 = 0x7, + CPU_TARGET_PCIE13 = 0x8, + CPU_TARGET_SASRAM = 0x9, + CPU_TARGET_NAND = 0xd, +}; + +enum cpu_attrib { + CPU_ATTR_SASRAM = 0x01, + CPU_ATTR_DRAM_CS0 = 0x0e, + CPU_ATTR_DRAM_CS1 = 0x0d, + CPU_ATTR_DRAM_CS2 = 0x0b, + CPU_ATTR_DRAM_CS3 = 0x07, + CPU_ATTR_NANDFLASH = 0x2f, + CPU_ATTR_SPIFLASH = 0x1e, + CPU_ATTR_BOOTROM = 0x1d, + CPU_ATTR_PCIE_IO = 0xe0, + CPU_ATTR_PCIE_MEM = 0xe8, + CPU_ATTR_DEV_CS0 = 0x3e, + CPU_ATTR_DEV_CS1 = 0x3d, + CPU_ATTR_DEV_CS2 = 0x3b, + CPU_ATTR_DEV_CS3 = 0x37, +}; + +/* + * Default Device Address MAP BAR values + */ +#define DEFADR_PCI_MEM 0x90000000 +#define DEFADR_PCI_IO 0xC0000000 +#define DEFADR_SPIF 0xF4000000 +#define DEFADR_BOOTROM 0xF8000000 + +struct mbus_win { + u32 base; + u32 size; + u8 target; + u8 attr; +}; + +/* + * System registers + * Ref: Datasheet sec:A.28 + */ +struct mvebu_system_registers { + u8 pad1[0x60]; + u32 rstoutn_mask; /* 0x60 */ + u32 sys_soft_rst; /* 0x64 */ +}; + +/* + * GPIO Registers + * Ref: Datasheet sec:A.19 + */ +struct kwgpio_registers { + u32 dout; + u32 oe; + u32 blink_en; + u32 din_pol; + u32 din; + u32 irq_cause; + u32 irq_mask; + u32 irq_level; +}; + +/* + * functions + */ +unsigned int mvebu_sdram_bar(enum memory_bank bank); +unsigned int mvebu_sdram_bs(enum memory_bank bank); +void mvebu_sdram_size_adjust(enum memory_bank bank); +int mvebu_mbus_probe(struct mbus_win windows[], int count); +#endif /* __ASSEMBLY__ */ +#endif /* _ARMADA_XP_CPU_H */ diff --git a/arch/arm/include/asm/arch-armada-xp/soc.h b/arch/arm/include/asm/arch-armada-xp/soc.h new file mode 100644 index 0000000..963e7ac --- /dev/null +++ b/arch/arm/include/asm/arch-armada-xp/soc.h @@ -0,0 +1,57 @@ +/* + * (C) Copyright 2009 + * Marvell Semiconductor + * Written-by: Prafulla Wadaskar + * + * Header file for the Marvell's Feroceon CPU core. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _ASM_ARCH_ARMADA_XP_H +#define _ASM_ARCH_ARMADA_XP_H + +#define SOC_MV78460_ID 0x7846 + +/* TCLK Core Clock definition */ +#ifndef CONFIG_SYS_TCLK +#define CONFIG_SYS_TCLK 250000000 /* 250MHz */ +#endif + +/* SOC specific definations */ +#define INTREG_BASE 0xd0000000 +#define INTREG_BASE_ADDR_REG (INTREG_BASE + 0x20080) +#define SOC_REGS_PHY_BASE 0xf1000000 +#define MVEBU_REGISTER(x) (SOC_REGS_PHY_BASE + x) + +#define MVEBU_SDRAM_SCRATCH (MVEBU_REGISTER(0x01504)) +#define MVEBU_SPI_BASE (MVEBU_REGISTER(0x10600)) +#define MVEBU_TWSI_BASE (MVEBU_REGISTER(0x11000)) +#define MVEBU_UART0_BASE (MVEBU_REGISTER(0x12000)) +#define MVEBU_UART1_BASE (MVEBU_REGISTER(0x12100)) +#define MVEBU_MPP_BASE (MVEBU_REGISTER(0x18000)) +#define MVEBU_GPIO0_BASE (MVEBU_REGISTER(0x18100)) +#define MVEBU_GPIO1_BASE (MVEBU_REGISTER(0x18140)) +#define MVEBU_GPIO2_BASE (MVEBU_REGISTER(0x18180)) +#define MVEBU_SYSTEM_REG_BASE (MVEBU_REGISTER(0x18200)) +#define MVEBU_CPU_WIN_BASE (MVEBU_REGISTER(0x20000)) +#define MVEBU_SDRAM_BASE (MVEBU_REGISTER(0x20180)) +#define MVEBU_TIMER_BASE (MVEBU_REGISTER(0x20300)) +#define MVEBU_EGIGA2_BASE (MVEBU_REGISTER(0x30000)) +#define MVEBU_EGIGA3_BASE (MVEBU_REGISTER(0x34000)) +#define MVEBU_REG_PCIE_BASE (MVEBU_REGISTER(0x40000)) +#define MVEBU_EGIGA0_BASE (MVEBU_REGISTER(0x70000)) +#define MVEBU_EGIGA1_BASE (MVEBU_REGISTER(0x74000)) + +#define SDRAM_MAX_CS 4 +#define SDRAM_ADDR_MASK 0xFF000000 + +/* Armada XP GbE controller has 4 ports */ +#define MAX_MVNETA_DEVS 4 + +/* Kirkwood CPU memory windows */ +#define MVCPU_WIN_CTRL_DATA CPU_WIN_CTRL_DATA +#define MVCPU_WIN_ENABLE CPU_WIN_ENABLE +#define MVCPU_WIN_DISABLE CPU_WIN_DISABLE + +#endif /* _ASM_ARCH_ARMADA_XP_H */ -- cgit v1.1