diff --git a/Documentation/arm/stm32/stm32h743-overview.txt b/Documentation/arm/stm32/stm32h743-overview.txt new file mode 100644 index 000000000000..3031cbae31a5 --- /dev/null +++ b/Documentation/arm/stm32/stm32h743-overview.txt @@ -0,0 +1,30 @@ + STM32H743 Overview + ================== + + Introduction + ------------ + The STM32H743 is a Cortex-M7 MCU aimed at various applications. + It features: + - Cortex-M7 core running up to @400MHz + - 2MB internal flash, 1MBytes internal RAM + - FMC controller to connect SDRAM, NOR and NAND memories + - Dual mode QSPI + - SD/MMC/SDIO support + - Ethernet controller + - USB OTFG FS & HS controllers + - I2C, SPI, CAN busses support + - Several 16 & 32 bits general purpose timers + - Serial Audio interface + - LCD controller + - HDMI-CEC + - SPDIFRX + - DFSDM + + Resources + --------- + Datasheet and reference manual are publicly available on ST website: + - http://www.st.com/en/microcontrollers/stm32h7x3.html?querycriteria=productId=LN2033 + + Document Author + --------------- + Alexandre Torgue diff --git a/MAINTAINERS b/MAINTAINERS index 0244bbc76e7f..9d58e9f18705 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1056,8 +1056,13 @@ M: Chen-Yu Tsai L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained N: sun[x456789]i -F: arch/arm/boot/dts/ntc-gr8* +N: sun50i +F: arch/arm/mach-sunxi/ F: arch/arm64/boot/dts/allwinner/ +F: drivers/clk/sunxi-ng/ +F: drivers/pinctrl/sunxi/ +F: drivers/soc/sunxi/ +T: git git://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux.git ARM/Allwinner SoC Clock Support M: Emilio López @@ -1110,7 +1115,6 @@ F: drivers/*/*aspeed* ARM/ATMEL AT91RM9200, AT91SAM9 AND SAMA5 SOC SUPPORT M: Nicolas Ferre M: Alexandre Belloni -M: Jean-Christophe Plagniol-Villard L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) W: http://www.linux4sam.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/nferre/linux-at91.git @@ -1122,6 +1126,7 @@ F: arch/arm/boot/dts/at91*.dtsi F: arch/arm/boot/dts/sama*.dts F: arch/arm/boot/dts/sama*.dtsi F: arch/arm/include/debug/at91.S +F: drivers/memory/atmel* ARM/ATMEL AT91 Clock Support M: Boris Brezillon diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 4c6816be23a9..4c1a35f15838 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -359,15 +359,6 @@ config ARM_SINGLE_ARMV7M select SPARSE_IRQ select USE_OF -config ARCH_GEMINI - bool "Cortina Systems Gemini" - select CLKSRC_MMIO - select CPU_FA526 - select GENERIC_CLOCKEVENTS - select GPIOLIB - help - Support for the Cortina Systems Gemini family SoCs - config ARCH_EBSA110 bool "EBSA-110" select ARCH_USES_GETTIMEOFFSET @@ -819,6 +810,8 @@ source "arch/arm/mach-spear/Kconfig" source "arch/arm/mach-sti/Kconfig" +source "arch/arm/mach-stm32/Kconfig" + source "arch/arm/mach-s3c24xx/Kconfig" source "arch/arm/mach-s3c64xx/Kconfig" @@ -877,28 +870,6 @@ config ARCH_LPC18XX Support for NXP's LPC18xx Cortex-M3 and LPC43xx Cortex-M4 high performance microcontrollers. -config ARCH_STM32 - bool "STMicrolectronics STM32" - depends on ARM_SINGLE_ARMV7M - select ARCH_HAS_RESET_CONTROLLER - select ARMV7M_SYSTICK - select CLKSRC_STM32 - select PINCTRL - select RESET_CONTROLLER - select STM32_EXTI - help - Support for STMicroelectronics STM32 processors. - -config MACH_STM32F429 - bool "STMicrolectronics STM32F429" - depends on ARCH_STM32 - default y - -config MACH_STM32F746 - bool "STMicrolectronics STM32F746" - depends on ARCH_STM32 - default y - config ARCH_MPS2 bool "ARM MPS2 platform" depends on ARM_SINGLE_ARMV7M diff --git a/arch/arm/include/debug/brcmstb.S b/arch/arm/include/debug/brcmstb.S index 9113d7b33ae0..52aaed2b936f 100644 --- a/arch/arm/include/debug/brcmstb.S +++ b/arch/arm/include/debug/brcmstb.S @@ -22,7 +22,8 @@ #define UARTA_3390 REG_PHYS_ADDR(0x40a900) #define UARTA_7250 REG_PHYS_ADDR(0x40b400) -#define UARTA_7268 REG_PHYS_ADDR(0x40c000) +#define UARTA_7260 REG_PHYS_ADDR(0x40c000) +#define UARTA_7268 UARTA_7260 #define UARTA_7271 UARTA_7268 #define UARTA_7364 REG_PHYS_ADDR(0x40b000) #define UARTA_7366 UARTA_7364 @@ -62,13 +63,14 @@ /* Chip specific detection starts here */ 20: checkuart(\rp, \rv, 0x33900000, 3390) 21: checkuart(\rp, \rv, 0x72500000, 7250) -22: checkuart(\rp, \rv, 0x72680000, 7268) -23: checkuart(\rp, \rv, 0x72710000, 7271) -24: checkuart(\rp, \rv, 0x73640000, 7364) -25: checkuart(\rp, \rv, 0x73660000, 7366) -26: checkuart(\rp, \rv, 0x07437100, 74371) -27: checkuart(\rp, \rv, 0x74390000, 7439) -28: checkuart(\rp, \rv, 0x74450000, 7445) +22: checkuart(\rp, \rv, 0x72600000, 7260) +23: checkuart(\rp, \rv, 0x72680000, 7268) +24: checkuart(\rp, \rv, 0x72710000, 7271) +25: checkuart(\rp, \rv, 0x73640000, 7364) +26: checkuart(\rp, \rv, 0x73660000, 7366) +27: checkuart(\rp, \rv, 0x07437100, 74371) +28: checkuart(\rp, \rv, 0x74390000, 7439) +29: checkuart(\rp, \rv, 0x74450000, 7445) /* No valid UART found */ 90: mov \rp, #0 diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile index c5bbf8bb8c0f..cfd8f60a9268 100644 --- a/arch/arm/mach-at91/Makefile +++ b/arch/arm/mach-at91/Makefile @@ -1,7 +1,6 @@ # # Makefile for the linux kernel. # -obj-y := soc.o # CPU-specific support obj-$(CONFIG_SOC_AT91RM9200) += at91rm9200.o @@ -18,3 +17,36 @@ endif ifeq ($(CONFIG_PM_DEBUG),y) CFLAGS_pm.o += -DDEBUG endif + +# Default sed regexp - multiline due to syntax constraints +define sed-y + "/^->/{s:->#\(.*\):/* \1 */:; \ + s:^->\([^ ]*\) [\$$#]*\([-0-9]*\) \(.*\):#define \1 \2 /* \3 */:; \ + s:^->\([^ ]*\) [\$$#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:; \ + s:->::; p;}" +endef + +# Use filechk to avoid rebuilds when a header changes, but the resulting file +# does not +define filechk_offsets + (set -e; \ + echo "#ifndef $2"; \ + echo "#define $2"; \ + echo "/*"; \ + echo " * DO NOT MODIFY."; \ + echo " *"; \ + echo " * This file was generated by Kbuild"; \ + echo " */"; \ + echo ""; \ + sed -ne $(sed-y); \ + echo ""; \ + echo "#endif" ) +endef + +arch/arm/mach-at91/pm_data-offsets.s: arch/arm/mach-at91/pm_data-offsets.c + $(call if_changed_dep,cc_s_c) + +include/generated/at91_pm_data-offsets.h: arch/arm/mach-at91/pm_data-offsets.s FORCE + $(call filechk,offsets,__PM_DATA_OFFSETS_H__) + +arch/arm/mach-at91/pm_suspend.o: include/generated/at91_pm_data-offsets.h diff --git a/arch/arm/mach-at91/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c index d068ec3cd1f6..656ad409a253 100644 --- a/arch/arm/mach-at91/at91rm9200.c +++ b/arch/arm/mach-at91/at91rm9200.c @@ -14,23 +14,10 @@ #include #include "generic.h" -#include "soc.h" - -static const struct at91_soc rm9200_socs[] = { - AT91_SOC(AT91RM9200_CIDR_MATCH, 0, "at91rm9200 BGA", "at91rm9200"), - { /* sentinel */ }, -}; static void __init at91rm9200_dt_device_init(void) { - struct soc_device *soc; - struct device *soc_dev = NULL; - - soc = at91_soc_init(rm9200_socs); - if (soc != NULL) - soc_dev = soc_device_to_device(soc); - - of_platform_default_populate(NULL, NULL, soc_dev); + of_platform_default_populate(NULL, NULL, NULL); at91rm9200_pm_init(); } diff --git a/arch/arm/mach-at91/at91sam9.c b/arch/arm/mach-at91/at91sam9.c index ba28e9cc584d..3dbdef4d3cbf 100644 --- a/arch/arm/mach-at91/at91sam9.c +++ b/arch/arm/mach-at91/at91sam9.c @@ -14,60 +14,12 @@ #include #include "generic.h" -#include "soc.h" -static const struct at91_soc at91sam9_socs[] = { - AT91_SOC(AT91SAM9260_CIDR_MATCH, 0, "at91sam9260", NULL), - AT91_SOC(AT91SAM9261_CIDR_MATCH, 0, "at91sam9261", NULL), - AT91_SOC(AT91SAM9263_CIDR_MATCH, 0, "at91sam9263", NULL), - AT91_SOC(AT91SAM9G20_CIDR_MATCH, 0, "at91sam9g20", NULL), - AT91_SOC(AT91SAM9RL64_CIDR_MATCH, 0, "at91sam9rl64", NULL), - AT91_SOC(AT91SAM9G45_CIDR_MATCH, AT91SAM9M11_EXID_MATCH, - "at91sam9m11", "at91sam9g45"), - AT91_SOC(AT91SAM9G45_CIDR_MATCH, AT91SAM9M10_EXID_MATCH, - "at91sam9m10", "at91sam9g45"), - AT91_SOC(AT91SAM9G45_CIDR_MATCH, AT91SAM9G46_EXID_MATCH, - "at91sam9g46", "at91sam9g45"), - AT91_SOC(AT91SAM9G45_CIDR_MATCH, AT91SAM9G45_EXID_MATCH, - "at91sam9g45", "at91sam9g45"), - AT91_SOC(AT91SAM9X5_CIDR_MATCH, AT91SAM9G15_EXID_MATCH, - "at91sam9g15", "at91sam9x5"), - AT91_SOC(AT91SAM9X5_CIDR_MATCH, AT91SAM9G35_EXID_MATCH, - "at91sam9g35", "at91sam9x5"), - AT91_SOC(AT91SAM9X5_CIDR_MATCH, AT91SAM9X35_EXID_MATCH, - "at91sam9x35", "at91sam9x5"), - AT91_SOC(AT91SAM9X5_CIDR_MATCH, AT91SAM9G25_EXID_MATCH, - "at91sam9g25", "at91sam9x5"), - AT91_SOC(AT91SAM9X5_CIDR_MATCH, AT91SAM9X25_EXID_MATCH, - "at91sam9x25", "at91sam9x5"), - AT91_SOC(AT91SAM9N12_CIDR_MATCH, AT91SAM9CN12_EXID_MATCH, - "at91sam9cn12", "at91sam9n12"), - AT91_SOC(AT91SAM9N12_CIDR_MATCH, AT91SAM9N12_EXID_MATCH, - "at91sam9n12", "at91sam9n12"), - AT91_SOC(AT91SAM9N12_CIDR_MATCH, AT91SAM9CN11_EXID_MATCH, - "at91sam9cn11", "at91sam9n12"), - AT91_SOC(AT91SAM9XE128_CIDR_MATCH, 0, "at91sam9xe128", "at91sam9xe128"), - AT91_SOC(AT91SAM9XE256_CIDR_MATCH, 0, "at91sam9xe256", "at91sam9xe256"), - AT91_SOC(AT91SAM9XE512_CIDR_MATCH, 0, "at91sam9xe512", "at91sam9xe512"), - { /* sentinel */ }, -}; - -static void __init at91sam9_common_init(void) +static void __init at91sam9_init(void) { - struct soc_device *soc; - struct device *soc_dev = NULL; + of_platform_default_populate(NULL, NULL, NULL); - soc = at91_soc_init(at91sam9_socs); - if (soc != NULL) - soc_dev = soc_device_to_device(soc); - - of_platform_default_populate(NULL, NULL, soc_dev); -} - -static void __init at91sam9_dt_device_init(void) -{ - at91sam9_common_init(); - at91sam9260_pm_init(); + at91sam9_pm_init(); } static const char *const at91_dt_board_compat[] __initconst = { @@ -77,41 +29,6 @@ static const char *const at91_dt_board_compat[] __initconst = { DT_MACHINE_START(at91sam_dt, "Atmel AT91SAM9") /* Maintainer: Atmel */ - .init_machine = at91sam9_dt_device_init, + .init_machine = at91sam9_init, .dt_compat = at91_dt_board_compat, MACHINE_END - -static void __init at91sam9g45_dt_device_init(void) -{ - at91sam9_common_init(); - at91sam9g45_pm_init(); -} - -static const char *const at91sam9g45_board_compat[] __initconst = { - "atmel,at91sam9g45", - NULL -}; - -DT_MACHINE_START(at91sam9g45_dt, "Atmel AT91SAM9G45") - /* Maintainer: Atmel */ - .init_machine = at91sam9g45_dt_device_init, - .dt_compat = at91sam9g45_board_compat, -MACHINE_END - -static void __init at91sam9x5_dt_device_init(void) -{ - at91sam9_common_init(); - at91sam9x5_pm_init(); -} - -static const char *const at91sam9x5_board_compat[] __initconst = { - "atmel,at91sam9x5", - "atmel,at91sam9n12", - NULL -}; - -DT_MACHINE_START(at91sam9x5_dt, "Atmel AT91SAM9") - /* Maintainer: Atmel */ - .init_machine = at91sam9x5_dt_device_init, - .dt_compat = at91sam9x5_board_compat, -MACHINE_END diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h index 28ca57a2060f..f1ead0f13c19 100644 --- a/arch/arm/mach-at91/generic.h +++ b/arch/arm/mach-at91/generic.h @@ -13,15 +13,11 @@ #ifdef CONFIG_PM extern void __init at91rm9200_pm_init(void); -extern void __init at91sam9260_pm_init(void); -extern void __init at91sam9g45_pm_init(void); -extern void __init at91sam9x5_pm_init(void); +extern void __init at91sam9_pm_init(void); extern void __init sama5_pm_init(void); #else static inline void __init at91rm9200_pm_init(void) { } -static inline void __init at91sam9260_pm_init(void) { } -static inline void __init at91sam9g45_pm_init(void) { } -static inline void __init at91sam9x5_pm_init(void) { } +static inline void __init at91sam9_pm_init(void) { } static inline void __init sama5_pm_init(void) { } #endif diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index a277981f414d..2cd27c830ab6 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c @@ -10,35 +10,22 @@ * (at your option) any later version. */ -#include -#include -#include -#include #include -#include -#include -#include +#include +#include #include #include -#include -#include -#include -#include +#include + #include -#include -#include -#include -#include -#include #include +#include #include #include "generic.h" #include "pm.h" -static void __iomem *pmc; - /* * FIXME: this is needed to communicate between the pinctrl driver and * the PM implementation in the machine. Possibly part of the PM @@ -50,12 +37,13 @@ extern void at91_pinctrl_gpio_suspend(void); extern void at91_pinctrl_gpio_resume(void); #endif -static struct { - unsigned long uhp_udp_mask; - int memctrl; -} at91_pm_data; +static struct at91_pm_data pm_data; -static void __iomem *at91_ramc_base[2]; +#define at91_ramc_read(id, field) \ + __raw_readl(pm_data.ramc[id] + field) + +#define at91_ramc_write(id, field, value) \ + __raw_writel(value, pm_data.ramc[id] + field) static int at91_pm_valid_state(suspend_state_t state) { @@ -91,10 +79,10 @@ static int at91_pm_verify_clocks(void) unsigned long scsr; int i; - scsr = readl(pmc + AT91_PMC_SCSR); + scsr = readl(pm_data.pmc + AT91_PMC_SCSR); /* USB must not be using PLLB */ - if ((scsr & at91_pm_data.uhp_udp_mask) != 0) { + if ((scsr & pm_data.uhp_udp_mask) != 0) { pr_err("AT91: PM - Suspend-to-RAM with USB still active\n"); return 0; } @@ -105,7 +93,7 @@ static int at91_pm_verify_clocks(void) if ((scsr & (AT91_PMC_PCK0 << i)) == 0) continue; - css = readl(pmc + AT91_PMC_PCKR(i)) & AT91_PMC_CSS; + css = readl(pm_data.pmc + AT91_PMC_PCKR(i)) & AT91_PMC_CSS; if (css != AT91_PMC_CSS_SLOW) { pr_err("AT91: PM - Suspend-to-RAM with PCK%d src %d\n", i, css); return 0; @@ -131,25 +119,18 @@ int at91_suspend_entering_slow_clock(void) } EXPORT_SYMBOL(at91_suspend_entering_slow_clock); -static void (*at91_suspend_sram_fn)(void __iomem *pmc, void __iomem *ramc0, - void __iomem *ramc1, int memctrl); - -extern void at91_pm_suspend_in_sram(void __iomem *pmc, void __iomem *ramc0, - void __iomem *ramc1, int memctrl); +static void (*at91_suspend_sram_fn)(struct at91_pm_data *); +extern void at91_pm_suspend_in_sram(struct at91_pm_data *pm_data); extern u32 at91_pm_suspend_in_sram_sz; static void at91_pm_suspend(suspend_state_t state) { - unsigned int pm_data = at91_pm_data.memctrl; - - pm_data |= (state == PM_SUSPEND_MEM) ? - AT91_PM_MODE(AT91_PM_SLOW_CLOCK) : 0; + pm_data.mode = (state == PM_SUSPEND_MEM) ? AT91_PM_SLOW_CLOCK : 0; flush_cache_all(); outer_disable(); - at91_suspend_sram_fn(pmc, at91_ramc_base[0], - at91_ramc_base[1], pm_data); + at91_suspend_sram_fn(&pm_data); outer_resume(); } @@ -224,12 +205,6 @@ static struct platform_device at91_cpuidle_device = { .name = "cpuidle-at91", }; -static void at91_pm_set_standby(void (*at91_standby)(void)) -{ - if (at91_standby) - at91_cpuidle_device.dev.platform_data = at91_standby; -} - /* * The AT91RM9200 goes into self-refresh mode with this command, and will * terminate self-refresh automatically on the next SDRAM access. @@ -241,20 +216,15 @@ static void at91_pm_set_standby(void (*at91_standby)(void)) */ static void at91rm9200_standby(void) { - u32 lpr = at91_ramc_read(0, AT91_MC_SDRAMC_LPR); - asm volatile( "b 1f\n\t" ".align 5\n\t" "1: mcr p15, 0, %0, c7, c10, 4\n\t" - " str %0, [%1, %2]\n\t" - " str %3, [%1, %4]\n\t" + " str %2, [%1, %3]\n\t" " mcr p15, 0, %0, c7, c0, 4\n\t" - " str %5, [%1, %2]" : - : "r" (0), "r" (at91_ramc_base[0]), "r" (AT91_MC_SDRAMC_LPR), - "r" (1), "r" (AT91_MC_SDRAMC_SRR), - "r" (lpr)); + : "r" (0), "r" (pm_data.ramc[0]), + "r" (1), "r" (AT91_MC_SDRAMC_SRR)); } /* We manage both DDRAM/SDRAM controllers, we need more than one value to @@ -265,12 +235,27 @@ static void at91_ddr_standby(void) /* Those two values allow us to delay self-refresh activation * to the maximum. */ u32 lpr0, lpr1 = 0; + u32 mdr, saved_mdr0, saved_mdr1 = 0; u32 saved_lpr0, saved_lpr1 = 0; - if (at91_ramc_base[1]) { + /* LPDDR1 --> force DDR2 mode during self-refresh */ + saved_mdr0 = at91_ramc_read(0, AT91_DDRSDRC_MDR); + if ((saved_mdr0 & AT91_DDRSDRC_MD) == AT91_DDRSDRC_MD_LOW_POWER_DDR) { + mdr = saved_mdr0 & ~AT91_DDRSDRC_MD; + mdr |= AT91_DDRSDRC_MD_DDR2; + at91_ramc_write(0, AT91_DDRSDRC_MDR, mdr); + } + + if (pm_data.ramc[1]) { saved_lpr1 = at91_ramc_read(1, AT91_DDRSDRC_LPR); lpr1 = saved_lpr1 & ~AT91_DDRSDRC_LPCB; lpr1 |= AT91_DDRSDRC_LPCB_SELF_REFRESH; + saved_mdr1 = at91_ramc_read(1, AT91_DDRSDRC_MDR); + if ((saved_mdr1 & AT91_DDRSDRC_MD) == AT91_DDRSDRC_MD_LOW_POWER_DDR) { + mdr = saved_mdr1 & ~AT91_DDRSDRC_MD; + mdr |= AT91_DDRSDRC_MD_DDR2; + at91_ramc_write(1, AT91_DDRSDRC_MDR, mdr); + } } saved_lpr0 = at91_ramc_read(0, AT91_DDRSDRC_LPR); @@ -279,14 +264,17 @@ static void at91_ddr_standby(void) /* self-refresh mode now */ at91_ramc_write(0, AT91_DDRSDRC_LPR, lpr0); - if (at91_ramc_base[1]) + if (pm_data.ramc[1]) at91_ramc_write(1, AT91_DDRSDRC_LPR, lpr1); cpu_do_idle(); + at91_ramc_write(0, AT91_DDRSDRC_MDR, saved_mdr0); at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr0); - if (at91_ramc_base[1]) + if (pm_data.ramc[1]) { + at91_ramc_write(0, AT91_DDRSDRC_MDR, saved_mdr1); at91_ramc_write(1, AT91_DDRSDRC_LPR, saved_lpr1); + } } static void sama5d3_ddr_standby(void) @@ -313,7 +301,7 @@ static void at91sam9_sdram_standby(void) u32 lpr0, lpr1 = 0; u32 saved_lpr0, saved_lpr1 = 0; - if (at91_ramc_base[1]) { + if (pm_data.ramc[1]) { saved_lpr1 = at91_ramc_read(1, AT91_SDRAMC_LPR); lpr1 = saved_lpr1 & ~AT91_SDRAMC_LPCB; lpr1 |= AT91_SDRAMC_LPCB_SELF_REFRESH; @@ -325,21 +313,33 @@ static void at91sam9_sdram_standby(void) /* self-refresh mode now */ at91_ramc_write(0, AT91_SDRAMC_LPR, lpr0); - if (at91_ramc_base[1]) + if (pm_data.ramc[1]) at91_ramc_write(1, AT91_SDRAMC_LPR, lpr1); cpu_do_idle(); at91_ramc_write(0, AT91_SDRAMC_LPR, saved_lpr0); - if (at91_ramc_base[1]) + if (pm_data.ramc[1]) at91_ramc_write(1, AT91_SDRAMC_LPR, saved_lpr1); } +struct ramc_info { + void (*idle)(void); + unsigned int memctrl; +}; + +static const struct ramc_info ramc_infos[] __initconst = { + { .idle = at91rm9200_standby, .memctrl = AT91_MEMCTRL_MC}, + { .idle = at91sam9_sdram_standby, .memctrl = AT91_MEMCTRL_SDRAMC}, + { .idle = at91_ddr_standby, .memctrl = AT91_MEMCTRL_DDRSDR}, + { .idle = sama5d3_ddr_standby, .memctrl = AT91_MEMCTRL_DDRSDR}, +}; + static const struct of_device_id const ramc_ids[] __initconst = { - { .compatible = "atmel,at91rm9200-sdramc", .data = at91rm9200_standby }, - { .compatible = "atmel,at91sam9260-sdramc", .data = at91sam9_sdram_standby }, - { .compatible = "atmel,at91sam9g45-ddramc", .data = at91_ddr_standby }, - { .compatible = "atmel,sama5d3-ddramc", .data = sama5d3_ddr_standby }, + { .compatible = "atmel,at91rm9200-sdramc", .data = &ramc_infos[0] }, + { .compatible = "atmel,at91sam9260-sdramc", .data = &ramc_infos[1] }, + { .compatible = "atmel,at91sam9g45-ddramc", .data = &ramc_infos[2] }, + { .compatible = "atmel,sama5d3-ddramc", .data = &ramc_infos[3] }, { /*sentinel*/ } }; @@ -348,15 +348,18 @@ static __init void at91_dt_ramc(void) struct device_node *np; const struct of_device_id *of_id; int idx = 0; - const void *standby = NULL; + void *standby = NULL; + const struct ramc_info *ramc; for_each_matching_node_and_match(np, ramc_ids, &of_id) { - at91_ramc_base[idx] = of_iomap(np, 0); - if (!at91_ramc_base[idx]) + pm_data.ramc[idx] = of_iomap(np, 0); + if (!pm_data.ramc[idx]) panic(pr_fmt("unable to map ramc[%d] cpu registers\n"), idx); + ramc = of_id->data; if (!standby) - standby = of_id->data; + standby = ramc->idle; + pm_data.memctrl = ramc->memctrl; idx++; } @@ -369,7 +372,7 @@ static __init void at91_dt_ramc(void) return; } - at91_pm_set_standby(standby); + at91_cpuidle_device.dev.platform_data = standby; } static void at91rm9200_idle(void) @@ -378,12 +381,12 @@ static void at91rm9200_idle(void) * Disable the processor clock. The processor will be automatically * re-enabled by an interrupt or by a reset. */ - writel(AT91_PMC_PCK, pmc + AT91_PMC_SCDR); + writel(AT91_PMC_PCK, pm_data.pmc + AT91_PMC_SCDR); } static void at91sam9_idle(void) { - writel(AT91_PMC_PCK, pmc + AT91_PMC_SCDR); + writel(AT91_PMC_PCK, pm_data.pmc + AT91_PMC_SCDR); cpu_do_idle(); } @@ -433,31 +436,46 @@ static void __init at91_pm_sram_init(void) &at91_pm_suspend_in_sram, at91_pm_suspend_in_sram_sz); } +struct pmc_info { + unsigned long uhp_udp_mask; +}; + +static const struct pmc_info pmc_infos[] __initconst = { + { .uhp_udp_mask = AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP }, + { .uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP }, + { .uhp_udp_mask = AT91SAM926x_PMC_UHP }, +}; + static const struct of_device_id atmel_pmc_ids[] __initconst = { - { .compatible = "atmel,at91rm9200-pmc" }, - { .compatible = "atmel,at91sam9260-pmc" }, - { .compatible = "atmel,at91sam9g45-pmc" }, - { .compatible = "atmel,at91sam9n12-pmc" }, - { .compatible = "atmel,at91sam9x5-pmc" }, - { .compatible = "atmel,sama5d3-pmc" }, - { .compatible = "atmel,sama5d2-pmc" }, + { .compatible = "atmel,at91rm9200-pmc", .data = &pmc_infos[0] }, + { .compatible = "atmel,at91sam9260-pmc", .data = &pmc_infos[1] }, + { .compatible = "atmel,at91sam9g45-pmc", .data = &pmc_infos[2] }, + { .compatible = "atmel,at91sam9n12-pmc", .data = &pmc_infos[1] }, + { .compatible = "atmel,at91sam9x5-pmc", .data = &pmc_infos[1] }, + { .compatible = "atmel,sama5d3-pmc", .data = &pmc_infos[1] }, + { .compatible = "atmel,sama5d2-pmc", .data = &pmc_infos[1] }, { /* sentinel */ }, }; static void __init at91_pm_init(void (*pm_idle)(void)) { struct device_node *pmc_np; + const struct of_device_id *of_id; + const struct pmc_info *pmc; if (at91_cpuidle_device.dev.platform_data) platform_device_register(&at91_cpuidle_device); - pmc_np = of_find_matching_node(NULL, atmel_pmc_ids); - pmc = of_iomap(pmc_np, 0); - if (!pmc) { + pmc_np = of_find_matching_node_and_match(NULL, atmel_pmc_ids, &of_id); + pm_data.pmc = of_iomap(pmc_np, 0); + if (!pm_data.pmc) { pr_err("AT91: PM not supported, PMC not found\n"); return; } + pmc = of_id->data; + pm_data.uhp_udp_mask = pmc->uhp_udp_mask; + if (pm_idle) arm_pm_idle = pm_idle; @@ -478,40 +496,17 @@ void __init at91rm9200_pm_init(void) */ at91_ramc_write(0, AT91_MC_SDRAMC_LPR, 0); - at91_pm_data.uhp_udp_mask = AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP; - at91_pm_data.memctrl = AT91_MEMCTRL_MC; - at91_pm_init(at91rm9200_idle); } -void __init at91sam9260_pm_init(void) +void __init at91sam9_pm_init(void) { at91_dt_ramc(); - at91_pm_data.memctrl = AT91_MEMCTRL_SDRAMC; - at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP; - at91_pm_init(at91sam9_idle); -} - -void __init at91sam9g45_pm_init(void) -{ - at91_dt_ramc(); - at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP; - at91_pm_data.memctrl = AT91_MEMCTRL_DDRSDR; - at91_pm_init(at91sam9_idle); -} - -void __init at91sam9x5_pm_init(void) -{ - at91_dt_ramc(); - at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP; - at91_pm_data.memctrl = AT91_MEMCTRL_DDRSDR; at91_pm_init(at91sam9_idle); } void __init sama5_pm_init(void) { at91_dt_ramc(); - at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP; - at91_pm_data.memctrl = AT91_MEMCTRL_DDRSDR; at91_pm_init(NULL); } diff --git a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h index bf980c6ef294..fc0f7d048187 100644 --- a/arch/arm/mach-at91/pm.h +++ b/arch/arm/mach-at91/pm.h @@ -17,24 +17,20 @@ #include #include -#ifndef __ASSEMBLY__ -#define at91_ramc_read(id, field) \ - __raw_readl(at91_ramc_base[id] + field) - -#define at91_ramc_write(id, field, value) \ - __raw_writel(value, at91_ramc_base[id] + field) -#endif - #define AT91_MEMCTRL_MC 0 #define AT91_MEMCTRL_SDRAMC 1 #define AT91_MEMCTRL_DDRSDR 2 -#define AT91_PM_MEMTYPE_MASK 0x0f - -#define AT91_PM_MODE_OFFSET 4 -#define AT91_PM_MODE_MASK 0x01 -#define AT91_PM_MODE(x) (((x) & AT91_PM_MODE_MASK) << AT91_PM_MODE_OFFSET) - #define AT91_PM_SLOW_CLOCK 0x01 +#ifndef __ASSEMBLY__ +struct at91_pm_data { + void __iomem *pmc; + void __iomem *ramc[2]; + unsigned long uhp_udp_mask; + unsigned int memctrl; + unsigned int mode; +}; +#endif + #endif diff --git a/arch/arm/mach-at91/pm_data-offsets.c b/arch/arm/mach-at91/pm_data-offsets.c new file mode 100644 index 000000000000..30302cb16df0 --- /dev/null +++ b/arch/arm/mach-at91/pm_data-offsets.c @@ -0,0 +1,13 @@ +#include +#include +#include "pm.h" + +int main(void) +{ + DEFINE(PM_DATA_PMC, offsetof(struct at91_pm_data, pmc)); + DEFINE(PM_DATA_RAMC0, offsetof(struct at91_pm_data, ramc[0])); + DEFINE(PM_DATA_RAMC1, offsetof(struct at91_pm_data, ramc[1])); + DEFINE(PM_DATA_MEMCTRL, offsetof(struct at91_pm_data, memctrl)); + DEFINE(PM_DATA_MODE, offsetof(struct at91_pm_data, mode)); + return 0; +} diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S index a25defda3d22..96781daa671a 100644 --- a/arch/arm/mach-at91/pm_suspend.S +++ b/arch/arm/mach-at91/pm_suspend.S @@ -4,7 +4,7 @@ * Copyright (C) 2006 Savin Zlobec * * AT91SAM9 support: - * Copyright (C) 2007 Anti Sullin * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -14,6 +14,7 @@ #include #include #include "pm.h" +#include "generated/at91_pm_data-offsets.h" #define SRAMC_SELF_FRESH_ACTIVE 0x01 #define SRAMC_SELF_FRESH_EXIT 0x00 @@ -72,13 +73,9 @@ tmp2 .req r5 .arm /* - * void at91_pm_suspend_in_sram(void __iomem *pmc, void __iomem *sdramc, - * void __iomem *ramc1, int memctrl) + * void at91_suspend_sram_fn(struct at91_pm_data*) * @input param: - * @r0: base address of AT91_PMC - * @r1: base address of SDRAM Controller (SDRAM, DDRSDR, or AT91_SYS) - * @r2: base address of second SDRAM Controller or 0 if not present - * @r3: pm information + * @r0: base address of struct at91_pm_data */ /* at91_pm_suspend_in_sram must be 8-byte aligned per the requirements of fncpy() */ .align 3 @@ -90,16 +87,16 @@ ENTRY(at91_pm_suspend_in_sram) mov tmp1, #0 mcr p15, 0, tmp1, c7, c10, 4 - str r0, .pmc_base - str r1, .sramc_base - str r2, .sramc1_base - - and r0, r3, #AT91_PM_MEMTYPE_MASK - str r0, .memtype - - lsr r0, r3, #AT91_PM_MODE_OFFSET - and r0, r0, #AT91_PM_MODE_MASK - str r0, .pm_mode + ldr tmp1, [r0, #PM_DATA_PMC] + str tmp1, .pmc_base + ldr tmp1, [r0, #PM_DATA_RAMC0] + str tmp1, .sramc_base + ldr tmp1, [r0, #PM_DATA_RAMC1] + str tmp1, .sramc1_base + ldr tmp1, [r0, #PM_DATA_MEMCTRL] + str tmp1, .memtype + ldr tmp1, [r0, #PM_DATA_MODE] + str tmp1, .pm_mode /* Active the self-refresh mode */ mov r0, #SRAMC_SELF_FRESH_ACTIVE diff --git a/arch/arm/mach-at91/sama5.c b/arch/arm/mach-at91/sama5.c index b272c45b400f..6d157d0ead8e 100644 --- a/arch/arm/mach-at91/sama5.c +++ b/arch/arm/mach-at91/sama5.c @@ -15,60 +15,10 @@ #include #include "generic.h" -#include "soc.h" - -static const struct at91_soc sama5_socs[] = { - AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D21CU_EXID_MATCH, - "sama5d21", "sama5d2"), - AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D22CU_EXID_MATCH, - "sama5d22", "sama5d2"), - AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D23CU_EXID_MATCH, - "sama5d23", "sama5d2"), - AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D24CX_EXID_MATCH, - "sama5d24", "sama5d2"), - AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D24CU_EXID_MATCH, - "sama5d24", "sama5d2"), - AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D26CU_EXID_MATCH, - "sama5d26", "sama5d2"), - AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D27CU_EXID_MATCH, - "sama5d27", "sama5d2"), - AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D27CN_EXID_MATCH, - "sama5d27", "sama5d2"), - AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D28CU_EXID_MATCH, - "sama5d28", "sama5d2"), - AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D28CN_EXID_MATCH, - "sama5d28", "sama5d2"), - AT91_SOC(SAMA5D3_CIDR_MATCH, SAMA5D31_EXID_MATCH, - "sama5d31", "sama5d3"), - AT91_SOC(SAMA5D3_CIDR_MATCH, SAMA5D33_EXID_MATCH, - "sama5d33", "sama5d3"), - AT91_SOC(SAMA5D3_CIDR_MATCH, SAMA5D34_EXID_MATCH, - "sama5d34", "sama5d3"), - AT91_SOC(SAMA5D3_CIDR_MATCH, SAMA5D35_EXID_MATCH, - "sama5d35", "sama5d3"), - AT91_SOC(SAMA5D3_CIDR_MATCH, SAMA5D36_EXID_MATCH, - "sama5d36", "sama5d3"), - AT91_SOC(SAMA5D4_CIDR_MATCH, SAMA5D41_EXID_MATCH, - "sama5d41", "sama5d4"), - AT91_SOC(SAMA5D4_CIDR_MATCH, SAMA5D42_EXID_MATCH, - "sama5d42", "sama5d4"), - AT91_SOC(SAMA5D4_CIDR_MATCH, SAMA5D43_EXID_MATCH, - "sama5d43", "sama5d4"), - AT91_SOC(SAMA5D4_CIDR_MATCH, SAMA5D44_EXID_MATCH, - "sama5d44", "sama5d4"), - { /* sentinel */ }, -}; static void __init sama5_dt_device_init(void) { - struct soc_device *soc; - struct device *soc_dev = NULL; - - soc = at91_soc_init(sama5_socs); - if (soc != NULL) - soc_dev = soc_device_to_device(soc); - - of_platform_default_populate(NULL, NULL, soc_dev); + of_platform_default_populate(NULL, NULL, NULL); sama5_pm_init(); } diff --git a/arch/arm/mach-at91/soc.c b/arch/arm/mach-at91/soc.c deleted file mode 100644 index c6fda75ddb89..000000000000 --- a/arch/arm/mach-at91/soc.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (C) 2015 Atmel - * - * Alexandre Belloni -#include -#include -#include -#include -#include - -#include "soc.h" - -#define AT91_DBGU_CIDR 0x40 -#define AT91_DBGU_EXID 0x44 -#define AT91_CHIPID_CIDR 0x00 -#define AT91_CHIPID_EXID 0x04 -#define AT91_CIDR_VERSION(x) ((x) & 0x1f) -#define AT91_CIDR_EXT BIT(31) -#define AT91_CIDR_MATCH_MASK 0x7fffffe0 - -static int __init at91_get_cidr_exid_from_dbgu(u32 *cidr, u32 *exid) -{ - struct device_node *np; - void __iomem *regs; - - np = of_find_compatible_node(NULL, NULL, "atmel,at91rm9200-dbgu"); - if (!np) - np = of_find_compatible_node(NULL, NULL, - "atmel,at91sam9260-dbgu"); - if (!np) - return -ENODEV; - - regs = of_iomap(np, 0); - of_node_put(np); - - if (!regs) { - pr_warn("Could not map DBGU iomem range"); - return -ENXIO; - } - - *cidr = readl(regs + AT91_DBGU_CIDR); - *exid = readl(regs + AT91_DBGU_EXID); - - iounmap(regs); - - return 0; -} - -static int __init at91_get_cidr_exid_from_chipid(u32 *cidr, u32 *exid) -{ - struct device_node *np; - void __iomem *regs; - - np = of_find_compatible_node(NULL, NULL, "atmel,sama5d2-chipid"); - if (!np) - return -ENODEV; - - regs = of_iomap(np, 0); - of_node_put(np); - - if (!regs) { - pr_warn("Could not map DBGU iomem range"); - return -ENXIO; - } - - *cidr = readl(regs + AT91_CHIPID_CIDR); - *exid = readl(regs + AT91_CHIPID_EXID); - - iounmap(regs); - - return 0; -} - -struct soc_device * __init at91_soc_init(const struct at91_soc *socs) -{ - struct soc_device_attribute *soc_dev_attr; - const struct at91_soc *soc; - struct soc_device *soc_dev; - u32 cidr, exid; - int ret; - - /* - * With SAMA5D2 and later SoCs, CIDR and EXID registers are no more - * in the dbgu device but in the chipid device whose purpose is only - * to expose these two registers. - */ - ret = at91_get_cidr_exid_from_dbgu(&cidr, &exid); - if (ret) - ret = at91_get_cidr_exid_from_chipid(&cidr, &exid); - if (ret) { - if (ret == -ENODEV) - pr_warn("Could not find identification node"); - return NULL; - } - - for (soc = socs; soc->name; soc++) { - if (soc->cidr_match != (cidr & AT91_CIDR_MATCH_MASK)) - continue; - - if (!(cidr & AT91_CIDR_EXT) || soc->exid_match == exid) - break; - } - - if (!soc->name) { - pr_warn("Could not find matching SoC description\n"); - return NULL; - } - - soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); - if (!soc_dev_attr) - return NULL; - - soc_dev_attr->family = soc->family; - soc_dev_attr->soc_id = soc->name; - soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%X", - AT91_CIDR_VERSION(cidr)); - soc_dev = soc_device_register(soc_dev_attr); - if (IS_ERR(soc_dev)) { - kfree(soc_dev_attr->revision); - kfree(soc_dev_attr); - pr_warn("Could not register SoC device\n"); - return NULL; - } - - if (soc->family) - pr_info("Detected SoC family: %s\n", soc->family); - pr_info("Detected SoC: %s, revision %X\n", soc->name, - AT91_CIDR_VERSION(cidr)); - - return soc_dev; -} diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig index a0e66d8200c5..f9389c5910e7 100644 --- a/arch/arm/mach-bcm/Kconfig +++ b/arch/arm/mach-bcm/Kconfig @@ -198,7 +198,9 @@ config ARCH_BRCMSTB select HAVE_ARM_ARCH_TIMER select BRCMSTB_L2_IRQ select BCM7120_L2_IRQ + select ARCH_HAS_HOLES_MEMORYMODEL select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE + select ZONE_DMA if ARM_LPAE select SOC_BRCMSTB select SOC_BUS help diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c index 6f1e1299cab9..b5625d009288 100644 --- a/arch/arm/mach-davinci/board-da850-evm.c +++ b/arch/arm/mach-davinci/board-da850-evm.c @@ -828,6 +828,9 @@ static struct regulator_consumer_supply fixed_supplies[] = { /* Baseboard 1.8V: 5V -> TPS73701DCQ -> 1.8V */ REGULATOR_SUPPLY("DVDD", "1-0018"), + + /* UI card 3.3V: 5V -> TPS73701DCQ -> 3.3V */ + REGULATOR_SUPPLY("vcc", "1-0020"), }; /* TPS65070 voltage regulator support */ @@ -1213,6 +1216,7 @@ static struct vpif_subdev_info da850_vpif_capture_sdev_info[] = { static struct vpif_capture_config da850_vpif_capture_config = { .subdev_info = da850_vpif_capture_sdev_info, .subdev_count = ARRAY_SIZE(da850_vpif_capture_sdev_info), + .i2c_adapter_id = 1, .chan_config[0] = { .inputs = da850_ch0_inputs, .input_count = ARRAY_SIZE(da850_ch0_inputs), diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c index 023480b75244..20f1874a5657 100644 --- a/arch/arm/mach-davinci/board-dm644x-evm.c +++ b/arch/arm/mach-davinci/board-dm644x-evm.c @@ -744,7 +744,8 @@ static int davinci_phy_fixup(struct phy_device *phydev) return 0; } -#define HAS_ATA IS_ENABLED(CONFIG_BLK_DEV_PALMCHIP_BK3710) +#define HAS_ATA (IS_ENABLED(CONFIG_BLK_DEV_PALMCHIP_BK3710) || \ + IS_ENABLED(CONFIG_PATA_BK3710)) #define HAS_NOR IS_ENABLED(CONFIG_MTD_PHYSMAP) diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c index f702d4fc8eb8..cb176826d1cb 100644 --- a/arch/arm/mach-davinci/board-dm646x-evm.c +++ b/arch/arm/mach-davinci/board-dm646x-evm.c @@ -119,7 +119,8 @@ static struct platform_device davinci_nand_device = { }, }; -#define HAS_ATA IS_ENABLED(CONFIG_BLK_DEV_PALMCHIP_BK3710) +#define HAS_ATA (IS_ENABLED(CONFIG_BLK_DEV_PALMCHIP_BK3710) || \ + IS_ENABLED(CONFIG_PATA_BK3710)) #ifdef CONFIG_I2C /* CPLD Register 0 bits to control ATA */ diff --git a/arch/arm/mach-davinci/board-neuros-osd2.c b/arch/arm/mach-davinci/board-neuros-osd2.c index 0a7838852649..0c02aaad0539 100644 --- a/arch/arm/mach-davinci/board-neuros-osd2.c +++ b/arch/arm/mach-davinci/board-neuros-osd2.c @@ -163,7 +163,8 @@ static struct davinci_mmc_config davinci_ntosd2_mmc_config = { .wires = 4, }; -#define HAS_ATA IS_ENABLED(CONFIG_BLK_DEV_PALMCHIP_BK3710) +#define HAS_ATA (IS_ENABLED(CONFIG_BLK_DEV_PALMCHIP_BK3710) || \ + IS_ENABLED(CONFIG_PATA_BK3710)) #define HAS_NAND IS_ENABLED(CONFIG_MTD_NAND_DAVINCI) diff --git a/arch/arm/mach-davinci/da830.c b/arch/arm/mach-davinci/da830.c index 073c458d0c67..bd88470f3e5c 100644 --- a/arch/arm/mach-davinci/da830.c +++ b/arch/arm/mach-davinci/da830.c @@ -304,6 +304,11 @@ static struct clk usb20_clk = { .gpsc = 1, }; +static struct clk cppi41_clk = { + .name = "cppi41", + .parent = &usb20_clk, +}; + static struct clk aemif_clk = { .name = "aemif", .parent = &pll0_sysclk3, @@ -413,6 +418,7 @@ static struct clk_lookup da830_clks[] = { CLK("davinci-mcasp.1", NULL, &mcasp1_clk), CLK("davinci-mcasp.2", NULL, &mcasp2_clk), CLK("musb-da8xx", "usb20", &usb20_clk), + CLK("cppi41-dmaengine", NULL, &cppi41_clk), CLK(NULL, "aemif", &aemif_clk), CLK(NULL, "aintc", &aintc_clk), CLK(NULL, "secu_mgr", &secu_mgr_clk), diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index ccad2f99dfc9..07d6f0eb8c82 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -401,6 +401,11 @@ static struct clk usb20_clk = { .gpsc = 1, }; +static struct clk cppi41_clk = { + .name = "cppi41", + .parent = &usb20_clk, +}; + static struct clk spi0_clk = { .name = "spi0", .parent = &pll0_sysclk2, @@ -560,6 +565,7 @@ static struct clk_lookup da850_clks[] = { CLK("davinci-nand.0", "aemif", &aemif_nand_clk), CLK("ohci-da8xx", "usb11", &usb11_clk), CLK("musb-da8xx", "usb20", &usb20_clk), + CLK("cppi41-dmaengine", NULL, &cppi41_clk), CLK("spi_davinci.0", NULL, &spi0_clk), CLK("spi_davinci.1", NULL, &spi1_clk), CLK("vpif", NULL, &vpif_clk), diff --git a/arch/arm/mach-davinci/da8xx-dt.c b/arch/arm/mach-davinci/da8xx-dt.c index e3cef503cd8f..5699ce39e64f 100644 --- a/arch/arm/mach-davinci/da8xx-dt.c +++ b/arch/arm/mach-davinci/da8xx-dt.c @@ -53,6 +53,7 @@ static struct of_dev_auxdata da850_auxdata_lookup[] __initdata = { OF_DEV_AUXDATA("ti,da830-musb", 0x01e00000, "musb-da8xx", NULL), OF_DEV_AUXDATA("ti,da830-usb-phy", 0x01c1417c, "da8xx-usb-phy", NULL), OF_DEV_AUXDATA("ti,da850-ahci", 0x01e18000, "ahci_da850", NULL), + OF_DEV_AUXDATA("ti,da850-vpif", 0x01e17000, "vpif", NULL), {} }; diff --git a/arch/arm/mach-davinci/pdata-quirks.c b/arch/arm/mach-davinci/pdata-quirks.c index 5b57da475065..329f5402ad1d 100644 --- a/arch/arm/mach-davinci/pdata-quirks.c +++ b/arch/arm/mach-davinci/pdata-quirks.c @@ -10,26 +10,202 @@ #include #include +#include +#include + #include +#include struct pdata_init { const char *compatible; void (*fn)(void); }; +#define TVP5147_CH0 "tvp514x-0" +#define TVP5147_CH1 "tvp514x-1" + +/* VPIF capture configuration */ +static struct tvp514x_platform_data tvp5146_pdata = { + .clk_polarity = 0, + .hs_polarity = 1, + .vs_polarity = 1, +}; + +#define TVP514X_STD_ALL (V4L2_STD_NTSC | V4L2_STD_PAL) + +static const struct vpif_input da850_ch0_inputs[] = { + { + .input = { + .index = 0, + .name = "Composite", + .type = V4L2_INPUT_TYPE_CAMERA, + .capabilities = V4L2_IN_CAP_STD, + .std = TVP514X_STD_ALL, + }, + .input_route = INPUT_CVBS_VI2B, + .output_route = OUTPUT_10BIT_422_EMBEDDED_SYNC, + .subdev_name = TVP5147_CH0, + }, +}; + +static const struct vpif_input da850_ch1_inputs[] = { + { + .input = { + .index = 0, + .name = "S-Video", + .type = V4L2_INPUT_TYPE_CAMERA, + .capabilities = V4L2_IN_CAP_STD, + .std = TVP514X_STD_ALL, + }, + .input_route = INPUT_SVIDEO_VI2C_VI1C, + .output_route = OUTPUT_10BIT_422_EMBEDDED_SYNC, + .subdev_name = TVP5147_CH1, + }, +}; + +static struct vpif_subdev_info da850_vpif_capture_sdev_info[] = { + { + .name = TVP5147_CH0, + .board_info = { + I2C_BOARD_INFO("tvp5146", 0x5d), + .platform_data = &tvp5146_pdata, + }, + }, + { + .name = TVP5147_CH1, + .board_info = { + I2C_BOARD_INFO("tvp5146", 0x5c), + .platform_data = &tvp5146_pdata, + }, + }, +}; + +static struct vpif_capture_config da850_vpif_capture_config = { + .subdev_info = da850_vpif_capture_sdev_info, + .subdev_count = ARRAY_SIZE(da850_vpif_capture_sdev_info), + .chan_config[0] = { + .inputs = da850_ch0_inputs, + .input_count = ARRAY_SIZE(da850_ch0_inputs), + .vpif_if = { + .if_type = VPIF_IF_BT656, + .hd_pol = 1, + .vd_pol = 1, + .fid_pol = 0, + }, + }, + .chan_config[1] = { + .inputs = da850_ch1_inputs, + .input_count = ARRAY_SIZE(da850_ch1_inputs), + .vpif_if = { + .if_type = VPIF_IF_BT656, + .hd_pol = 1, + .vd_pol = 1, + .fid_pol = 0, + }, + }, + .card_name = "DA850/OMAP-L138 Video Capture", +}; + +static void __init da850_vpif_legacy_register_capture(void) +{ + int ret; + + ret = da850_register_vpif_capture(&da850_vpif_capture_config); + if (ret) + pr_warn("%s: VPIF capture setup failed: %d\n", + __func__, ret); +} + +static void __init da850_vpif_capture_legacy_init_lcdk(void) +{ + da850_vpif_capture_config.subdev_count = 1; + da850_vpif_legacy_register_capture(); +} + +static void __init da850_vpif_capture_legacy_init_evm(void) +{ + da850_vpif_legacy_register_capture(); +} + +static struct adv7343_platform_data adv7343_pdata = { + .mode_config = { + .dac = { 1, 1, 1 }, + }, + .sd_config = { + .sd_dac_out = { 1 }, + }, +}; + +static struct vpif_subdev_info da850_vpif_subdev[] = { + { + .name = "adv7343", + .board_info = { + I2C_BOARD_INFO("adv7343", 0x2a), + .platform_data = &adv7343_pdata, + }, + }, +}; + +static const struct vpif_output da850_ch0_outputs[] = { + { + .output = { + .index = 0, + .name = "Composite", + .type = V4L2_OUTPUT_TYPE_ANALOG, + .capabilities = V4L2_OUT_CAP_STD, + .std = V4L2_STD_ALL, + }, + .subdev_name = "adv7343", + .output_route = ADV7343_COMPOSITE_ID, + }, + { + .output = { + .index = 1, + .name = "S-Video", + .type = V4L2_OUTPUT_TYPE_ANALOG, + .capabilities = V4L2_OUT_CAP_STD, + .std = V4L2_STD_ALL, + }, + .subdev_name = "adv7343", + .output_route = ADV7343_SVIDEO_ID, + }, +}; + +static struct vpif_display_config da850_vpif_display_config = { + .subdevinfo = da850_vpif_subdev, + .subdev_count = ARRAY_SIZE(da850_vpif_subdev), + .chan_config[0] = { + .outputs = da850_ch0_outputs, + .output_count = ARRAY_SIZE(da850_ch0_outputs), + }, + .card_name = "DA850/OMAP-L138 Video Display", +}; + +static void __init da850_vpif_display_legacy_init_evm(void) +{ + int ret; + + ret = da850_register_vpif_display(&da850_vpif_display_config); + if (ret) + pr_warn("%s: VPIF display setup failed: %d\n", + __func__, ret); +} + static void pdata_quirks_check(struct pdata_init *quirks) { while (quirks->compatible) { if (of_machine_is_compatible(quirks->compatible)) { if (quirks->fn) quirks->fn(); - break; } quirks++; } } static struct pdata_init pdata_quirks[] __initdata = { + { "ti,da850-lcdk", da850_vpif_capture_legacy_init_lcdk, }, + { "ti,da850-evm", da850_vpif_display_legacy_init_evm, }, + { "ti,da850-evm", da850_vpif_capture_legacy_init_evm, }, { /* sentinel */ }, }; diff --git a/arch/arm/mach-davinci/pm.c b/arch/arm/mach-davinci/pm.c index 0afd201ab980..efb80354f303 100644 --- a/arch/arm/mach-davinci/pm.c +++ b/arch/arm/mach-davinci/pm.c @@ -108,7 +108,6 @@ static int davinci_pm_enter(suspend_state_t state) int ret = 0; switch (state) { - case PM_SUSPEND_STANDBY: case PM_SUSPEND_MEM: davinci_pm_suspend(); break; diff --git a/arch/arm/mach-gemini/Kconfig b/arch/arm/mach-gemini/Kconfig index 6f066ee4bf24..06c8b095154c 100644 --- a/arch/arm/mach-gemini/Kconfig +++ b/arch/arm/mach-gemini/Kconfig @@ -1,40 +1,13 @@ -if ARCH_GEMINI - -menu "Cortina Systems Gemini Implementations" - -config MACH_NAS4220B - bool "Raidsonic NAS-4220-B" - select GEMINI_MEM_SWAP +menuconfig ARCH_GEMINI + bool "Cortina Systems Gemini" + depends on ARCH_MULTI_V4 + select ARM_APPENDED_DTB # Old Redboot bootloaders deployed + select FARADAY_FTINTC010 + select FTTMR010_TIMER + select GPIO_FTGPIO010 + select GPIOLIB + select POWER_RESET + select POWER_RESET_GEMINI_POWEROFF + select POWER_RESET_SYSCON help - Say Y here if you intend to run this kernel on a - Raidsonic NAS-4220-B. - -config MACH_RUT100 - bool "Teltonika RUT100" - select GEMINI_MEM_SWAP - help - Say Y here if you intend to run this kernel on a - Teltonika 3G Router RUT100. - -config MACH_WBD111 - bool "Wiliboard WBD-111" - select GEMINI_MEM_SWAP - help - Say Y here if you intend to run this kernel on a - Wiliboard WBD-111. - -config MACH_WBD222 - bool "Wiliboard WBD-222" - select GEMINI_MEM_SWAP - help - Say Y here if you intend to run this kernel on a - Wiliboard WBD-222. - -endmenu - -config GEMINI_MEM_SWAP - bool "Gemini memory is swapped" - help - Say Y here if Gemini memory is swapped by bootloader. - -endif + Support for the Cortina Systems Gemini family SoCs diff --git a/arch/arm/mach-gemini/Makefile b/arch/arm/mach-gemini/Makefile index 7963a77be637..ca0db5477180 100644 --- a/arch/arm/mach-gemini/Makefile +++ b/arch/arm/mach-gemini/Makefile @@ -1,13 +1,2 @@ -# -# Makefile for the linux kernel. -# - -# Object file lists. - -obj-y := irq.o mm.o time.o devices.o gpio.o idle.o reset.o - -# Board-specific support -obj-$(CONFIG_MACH_NAS4220B) += board-nas4220b.o -obj-$(CONFIG_MACH_RUT100) += board-rut1xx.o -obj-$(CONFIG_MACH_WBD111) += board-wbd111.o -obj-$(CONFIG_MACH_WBD222) += board-wbd222.o +# Makefile for Cortina systems Gemini +obj-y := board-dt.o diff --git a/arch/arm/mach-gemini/Makefile.boot b/arch/arm/mach-gemini/Makefile.boot deleted file mode 100644 index 683f52b20e3d..000000000000 --- a/arch/arm/mach-gemini/Makefile.boot +++ /dev/null @@ -1,9 +0,0 @@ -ifeq ($(CONFIG_GEMINI_MEM_SWAP),y) - zreladdr-y += 0x00008000 -params_phys-y := 0x00000100 -initrd_phys-y := 0x00800000 -else - zreladdr-y += 0x10008000 -params_phys-y := 0x10000100 -initrd_phys-y := 0x10800000 -endif diff --git a/arch/arm/mach-gemini/board-dt.c b/arch/arm/mach-gemini/board-dt.c new file mode 100644 index 000000000000..c0c0ebdd551e --- /dev/null +++ b/arch/arm/mach-gemini/board-dt.c @@ -0,0 +1,62 @@ +/* + * Gemini Device Tree boot support + */ +#include +#include +#include + +#include +#include +#include +#include + +#ifdef CONFIG_DEBUG_GEMINI +/* This is needed for LL-debug/earlyprintk/debug-macro.S */ +static struct map_desc gemini_io_desc[] __initdata = { + { + .virtual = CONFIG_DEBUG_UART_VIRT, + .pfn = __phys_to_pfn(CONFIG_DEBUG_UART_PHYS), + .length = SZ_4K, + .type = MT_DEVICE, + }, +}; + +static void __init gemini_map_io(void) +{ + iotable_init(gemini_io_desc, ARRAY_SIZE(gemini_io_desc)); +} +#else +#define gemini_map_io NULL +#endif + +static void gemini_idle(void) +{ + /* + * Because of broken hardware we have to enable interrupts or the CPU + * will never wakeup... Acctualy it is not very good to enable + * interrupts first since scheduler can miss a tick, but there is + * no other way around this. Platforms that needs it for power saving + * should enable it in init code, since by default it is + * disabled. + */ + + /* FIXME: Enabling interrupts here is racy! */ + local_irq_enable(); + cpu_do_idle(); +} + +static void __init gemini_init_machine(void) +{ + arm_pm_idle = gemini_idle; +} + +static const char *gemini_board_compat[] = { + "cortina,gemini", + NULL, +}; + +DT_MACHINE_START(GEMINI_DT, "Gemini (Device Tree)") + .map_io = gemini_map_io, + .init_machine = gemini_init_machine, + .dt_compat = gemini_board_compat, +MACHINE_END diff --git a/arch/arm/mach-gemini/board-nas4220b.c b/arch/arm/mach-gemini/board-nas4220b.c deleted file mode 100644 index 18b12796acf9..000000000000 --- a/arch/arm/mach-gemini/board-nas4220b.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Support for Raidsonic NAS-4220-B - * - * Copyright (C) 2009 Janos Laube - * - * based on rut1xx.c - * Copyright (C) 2008 Paulius Zaleckas - * - * 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 -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include - -#include "common.h" - -static struct gpio_led ib4220b_leds[] = { - { - .name = "nas4220b:orange:hdd", - .default_trigger = "none", - .gpio = 60, - }, - { - .name = "nas4220b:green:os", - .default_trigger = "heartbeat", - .gpio = 62, - }, -}; - -static struct gpio_led_platform_data ib4220b_leds_data = { - .num_leds = ARRAY_SIZE(ib4220b_leds), - .leds = ib4220b_leds, -}; - -static struct platform_device ib4220b_led_device = { - .name = "leds-gpio", - .id = -1, - .dev = { - .platform_data = &ib4220b_leds_data, - }, -}; - -static struct gpio_keys_button ib4220b_keys[] = { - { - .code = KEY_SETUP, - .gpio = 61, - .active_low = 1, - .desc = "Backup Button", - .type = EV_KEY, - }, - { - .code = KEY_RESTART, - .gpio = 63, - .active_low = 1, - .desc = "Softreset Button", - .type = EV_KEY, - }, -}; - -static struct gpio_keys_platform_data ib4220b_keys_data = { - .buttons = ib4220b_keys, - .nbuttons = ARRAY_SIZE(ib4220b_keys), -}; - -static struct platform_device ib4220b_key_device = { - .name = "gpio-keys", - .id = -1, - .dev = { - .platform_data = &ib4220b_keys_data, - }, -}; - -static void __init ib4220b_init(void) -{ - gemini_gpio_init(); - platform_register_uart(); - platform_register_pflash(SZ_16M, NULL, 0); - platform_device_register(&ib4220b_led_device); - platform_device_register(&ib4220b_key_device); - platform_register_rtc(); -} - -MACHINE_START(NAS4220B, "Raidsonic NAS IB-4220-B") - .atag_offset = 0x100, - .map_io = gemini_map_io, - .init_irq = gemini_init_irq, - .init_time = gemini_timer_init, - .init_machine = ib4220b_init, - .restart = gemini_restart, -MACHINE_END diff --git a/arch/arm/mach-gemini/board-rut1xx.c b/arch/arm/mach-gemini/board-rut1xx.c deleted file mode 100644 index 7a675f88ffd6..000000000000 --- a/arch/arm/mach-gemini/board-rut1xx.c +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Support for Teltonika RUT1xx - * - * Copyright (C) 2008-2009 Paulius Zaleckas - * - * 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 -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "common.h" - -static struct gpio_keys_button rut1xx_keys[] = { - { - .code = KEY_SETUP, - .gpio = 60, - .active_low = 1, - .desc = "Reset to defaults", - .type = EV_KEY, - }, -}; - -static struct gpio_keys_platform_data rut1xx_keys_data = { - .buttons = rut1xx_keys, - .nbuttons = ARRAY_SIZE(rut1xx_keys), -}; - -static struct platform_device rut1xx_keys_device = { - .name = "gpio-keys", - .id = -1, - .dev = { - .platform_data = &rut1xx_keys_data, - }, -}; - -static struct gpio_led rut100_leds[] = { - { - .name = "Power", - .default_trigger = "heartbeat", - .gpio = 17, - }, - { - .name = "GSM", - .default_trigger = "default-on", - .gpio = 7, - .active_low = 1, - }, -}; - -static struct gpio_led_platform_data rut100_leds_data = { - .num_leds = ARRAY_SIZE(rut100_leds), - .leds = rut100_leds, -}; - -static struct platform_device rut1xx_leds = { - .name = "leds-gpio", - .id = -1, - .dev = { - .platform_data = &rut100_leds_data, - }, -}; - -static void __init rut1xx_init(void) -{ - gemini_gpio_init(); - platform_register_uart(); - platform_register_pflash(SZ_8M, NULL, 0); - platform_device_register(&rut1xx_leds); - platform_device_register(&rut1xx_keys_device); - platform_register_rtc(); -} - -MACHINE_START(RUT100, "Teltonika RUT100") - .atag_offset = 0x100, - .map_io = gemini_map_io, - .init_irq = gemini_init_irq, - .init_time = gemini_timer_init, - .init_machine = rut1xx_init, - .restart = gemini_restart, -MACHINE_END diff --git a/arch/arm/mach-gemini/board-wbd111.c b/arch/arm/mach-gemini/board-wbd111.c deleted file mode 100644 index 14c56f3f0ec2..000000000000 --- a/arch/arm/mach-gemini/board-wbd111.c +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Support for Wiliboard WBD-111 - * - * Copyright (C) 2009 Imre Kaloz - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#include "common.h" - -static struct gpio_keys_button wbd111_keys[] = { - { - .code = KEY_SETUP, - .gpio = 5, - .active_low = 1, - .desc = "reset", - .type = EV_KEY, - }, -}; - -static struct gpio_keys_platform_data wbd111_keys_data = { - .buttons = wbd111_keys, - .nbuttons = ARRAY_SIZE(wbd111_keys), -}; - -static struct platform_device wbd111_keys_device = { - .name = "gpio-keys", - .id = -1, - .dev = { - .platform_data = &wbd111_keys_data, - }, -}; - -static struct gpio_led wbd111_leds[] = { - { - .name = "L3red", - .gpio = 1, - }, - { - .name = "L4green", - .gpio = 2, - }, - { - .name = "L4red", - .gpio = 3, - }, - { - .name = "L3green", - .gpio = 5, - }, -}; - -static struct gpio_led_platform_data wbd111_leds_data = { - .num_leds = ARRAY_SIZE(wbd111_leds), - .leds = wbd111_leds, -}; - -static struct platform_device wbd111_leds_device = { - .name = "leds-gpio", - .id = -1, - .dev = { - .platform_data = &wbd111_leds_data, - }, -}; - -static struct mtd_partition wbd111_partitions[] = { - { - .name = "RedBoot", - .offset = 0, - .size = 0x020000, - .mask_flags = MTD_WRITEABLE, - } , { - .name = "kernel", - .offset = 0x020000, - .size = 0x100000, - } , { - .name = "rootfs", - .offset = 0x120000, - .size = 0x6a0000, - } , { - .name = "VCTL", - .offset = 0x7c0000, - .size = 0x010000, - .mask_flags = MTD_WRITEABLE, - } , { - .name = "cfg", - .offset = 0x7d0000, - .size = 0x010000, - .mask_flags = MTD_WRITEABLE, - } , { - .name = "FIS", - .offset = 0x7e0000, - .size = 0x010000, - .mask_flags = MTD_WRITEABLE, - } -}; -#define wbd111_num_partitions ARRAY_SIZE(wbd111_partitions) - -static void __init wbd111_init(void) -{ - gemini_gpio_init(); - platform_register_uart(); - platform_register_pflash(SZ_8M, wbd111_partitions, - wbd111_num_partitions); - platform_device_register(&wbd111_leds_device); - platform_device_register(&wbd111_keys_device); - platform_register_rtc(); -} - -MACHINE_START(WBD111, "Wiliboard WBD-111") - .atag_offset = 0x100, - .map_io = gemini_map_io, - .init_irq = gemini_init_irq, - .init_time = gemini_timer_init, - .init_machine = wbd111_init, - .restart = gemini_restart, -MACHINE_END diff --git a/arch/arm/mach-gemini/board-wbd222.c b/arch/arm/mach-gemini/board-wbd222.c deleted file mode 100644 index 6070282ce243..000000000000 --- a/arch/arm/mach-gemini/board-wbd222.c +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Support for Wiliboard WBD-222 - * - * Copyright (C) 2009 Imre Kaloz - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#include "common.h" - -static struct gpio_keys_button wbd222_keys[] = { - { - .code = KEY_SETUP, - .gpio = 5, - .active_low = 1, - .desc = "reset", - .type = EV_KEY, - }, -}; - -static struct gpio_keys_platform_data wbd222_keys_data = { - .buttons = wbd222_keys, - .nbuttons = ARRAY_SIZE(wbd222_keys), -}; - -static struct platform_device wbd222_keys_device = { - .name = "gpio-keys", - .id = -1, - .dev = { - .platform_data = &wbd222_keys_data, - }, -}; - -static struct gpio_led wbd222_leds[] = { - { - .name = "L3red", - .gpio = 1, - }, - { - .name = "L4green", - .gpio = 2, - }, - { - .name = "L4red", - .gpio = 3, - }, - { - .name = "L3green", - .gpio = 5, - }, -}; - -static struct gpio_led_platform_data wbd222_leds_data = { - .num_leds = ARRAY_SIZE(wbd222_leds), - .leds = wbd222_leds, -}; - -static struct platform_device wbd222_leds_device = { - .name = "leds-gpio", - .id = -1, - .dev = { - .platform_data = &wbd222_leds_data, - }, -}; - -static struct mtd_partition wbd222_partitions[] = { - { - .name = "RedBoot", - .offset = 0, - .size = 0x020000, - .mask_flags = MTD_WRITEABLE, - } , { - .name = "kernel", - .offset = 0x020000, - .size = 0x100000, - } , { - .name = "rootfs", - .offset = 0x120000, - .size = 0x6a0000, - } , { - .name = "VCTL", - .offset = 0x7c0000, - .size = 0x010000, - .mask_flags = MTD_WRITEABLE, - } , { - .name = "cfg", - .offset = 0x7d0000, - .size = 0x010000, - .mask_flags = MTD_WRITEABLE, - } , { - .name = "FIS", - .offset = 0x7e0000, - .size = 0x010000, - .mask_flags = MTD_WRITEABLE, - } -}; -#define wbd222_num_partitions ARRAY_SIZE(wbd222_partitions) - -static void __init wbd222_init(void) -{ - gemini_gpio_init(); - platform_register_uart(); - platform_register_pflash(SZ_8M, wbd222_partitions, - wbd222_num_partitions); - platform_device_register(&wbd222_leds_device); - platform_device_register(&wbd222_keys_device); - platform_register_rtc(); -} - -MACHINE_START(WBD222, "Wiliboard WBD-222") - .atag_offset = 0x100, - .map_io = gemini_map_io, - .init_irq = gemini_init_irq, - .init_time = gemini_timer_init, - .init_machine = wbd222_init, - .restart = gemini_restart, -MACHINE_END diff --git a/arch/arm/mach-gemini/common.h b/arch/arm/mach-gemini/common.h deleted file mode 100644 index dd883698ff7e..000000000000 --- a/arch/arm/mach-gemini/common.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Common Gemini architecture functions - * - * Copyright (C) 2008-2009 Paulius Zaleckas - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#ifndef __GEMINI_COMMON_H__ -#define __GEMINI_COMMON_H__ - -#include - -struct mtd_partition; - -extern void gemini_map_io(void); -extern void gemini_init_irq(void); -extern void gemini_timer_init(void); -extern void gemini_gpio_init(void); -extern void platform_register_rtc(void); - -/* Common platform devices registration functions */ -extern int platform_register_uart(void); -extern int platform_register_pflash(unsigned int size, - struct mtd_partition *parts, - unsigned int nr_parts); - -extern void gemini_restart(enum reboot_mode mode, const char *cmd); - -#endif /* __GEMINI_COMMON_H__ */ diff --git a/arch/arm/mach-gemini/devices.c b/arch/arm/mach-gemini/devices.c deleted file mode 100644 index 5cff29818b73..000000000000 --- a/arch/arm/mach-gemini/devices.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Common devices definition for Gemini - * - * Copyright (C) 2008-2009 Paulius Zaleckas - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -static struct plat_serial8250_port serial_platform_data[] = { - { - .membase = (void *)IO_ADDRESS(GEMINI_UART_BASE), - .mapbase = GEMINI_UART_BASE, - .irq = IRQ_UART, - .uartclk = UART_CLK, - .regshift = 2, - .iotype = UPIO_MEM, - .type = PORT_16550A, - .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_FIXED_TYPE, - }, - {}, -}; - -static struct platform_device serial_device = { - .name = "serial8250", - .id = PLAT8250_DEV_PLATFORM, - .dev = { - .platform_data = serial_platform_data, - }, -}; - -int platform_register_uart(void) -{ - return platform_device_register(&serial_device); -} - -static struct resource flash_resource = { - .start = GEMINI_FLASH_BASE, - .flags = IORESOURCE_MEM, -}; - -static struct physmap_flash_data pflash_platform_data = {}; - -static struct platform_device pflash_device = { - .name = "physmap-flash", - .id = 0, - .dev = { - .platform_data = &pflash_platform_data, - }, - .resource = &flash_resource, - .num_resources = 1, -}; - -int platform_register_pflash(unsigned int size, struct mtd_partition *parts, - unsigned int nr_parts) -{ - unsigned int reg; - - reg = __raw_readl(IO_ADDRESS(GEMINI_GLOBAL_BASE) + GLOBAL_STATUS); - - if ((reg & FLASH_TYPE_MASK) != FLASH_TYPE_PARALLEL) - return -ENXIO; - - if (reg & FLASH_WIDTH_16BIT) - pflash_platform_data.width = 2; - else - pflash_platform_data.width = 1; - - /* enable parallel flash pins and disable others */ - reg = __raw_readl(IO_ADDRESS(GEMINI_GLOBAL_BASE) + GLOBAL_MISC_CTRL); - reg &= ~PFLASH_PADS_DISABLE; - reg |= SFLASH_PADS_DISABLE | NAND_PADS_DISABLE; - __raw_writel(reg, IO_ADDRESS(GEMINI_GLOBAL_BASE) + GLOBAL_MISC_CTRL); - - flash_resource.end = flash_resource.start + size - 1; - - pflash_platform_data.parts = parts; - pflash_platform_data.nr_parts = nr_parts; - - return platform_device_register(&pflash_device); -} - -static struct resource gemini_rtc_resources[] = { - [0] = { - .start = GEMINI_RTC_BASE, - .end = GEMINI_RTC_BASE + 0x24, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_RTC, - .end = IRQ_RTC, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device gemini_rtc_device = { - .name = "rtc-gemini", - .id = 0, - .num_resources = ARRAY_SIZE(gemini_rtc_resources), - .resource = gemini_rtc_resources, -}; - -int __init platform_register_rtc(void) -{ - return platform_device_register(&gemini_rtc_device); -} - diff --git a/arch/arm/mach-gemini/gpio.c b/arch/arm/mach-gemini/gpio.c deleted file mode 100644 index 469a76ea0459..000000000000 --- a/arch/arm/mach-gemini/gpio.c +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Gemini gpiochip and interrupt routines - * - * Copyright (C) 2008-2009 Paulius Zaleckas - * - * Based on plat-mxc/gpio.c: - * MXC GPIO support. (c) 2008 Daniel Mack - * Copyright 2008 Juergen Beisert, kernel@pengutronix.de - * - * 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 -#include -#include -#include -#include - -#include -#include - -#define GPIO_BASE(x) IO_ADDRESS(GEMINI_GPIO_BASE(x)) -#define irq_to_gpio(x) ((x) - GPIO_IRQ_BASE) - -/* GPIO registers definition */ -#define GPIO_DATA_OUT 0x0 -#define GPIO_DATA_IN 0x4 -#define GPIO_DIR 0x8 -#define GPIO_DATA_SET 0x10 -#define GPIO_DATA_CLR 0x14 -#define GPIO_PULL_EN 0x18 -#define GPIO_PULL_TYPE 0x1C -#define GPIO_INT_EN 0x20 -#define GPIO_INT_STAT 0x24 -#define GPIO_INT_MASK 0x2C -#define GPIO_INT_CLR 0x30 -#define GPIO_INT_TYPE 0x34 -#define GPIO_INT_BOTH_EDGE 0x38 -#define GPIO_INT_LEVEL 0x3C -#define GPIO_DEBOUNCE_EN 0x40 -#define GPIO_DEBOUNCE_PRESCALE 0x44 - -#define GPIO_PORT_NUM 3 - -static void _set_gpio_irqenable(void __iomem *base, unsigned int index, - int enable) -{ - unsigned int reg; - - reg = __raw_readl(base + GPIO_INT_EN); - reg = (reg & (~(1 << index))) | (!!enable << index); - __raw_writel(reg, base + GPIO_INT_EN); -} - -static void gpio_ack_irq(struct irq_data *d) -{ - unsigned int gpio = irq_to_gpio(d->irq); - void __iomem *base = GPIO_BASE(gpio / 32); - - __raw_writel(1 << (gpio % 32), base + GPIO_INT_CLR); -} - -static void gpio_mask_irq(struct irq_data *d) -{ - unsigned int gpio = irq_to_gpio(d->irq); - void __iomem *base = GPIO_BASE(gpio / 32); - - _set_gpio_irqenable(base, gpio % 32, 0); -} - -static void gpio_unmask_irq(struct irq_data *d) -{ - unsigned int gpio = irq_to_gpio(d->irq); - void __iomem *base = GPIO_BASE(gpio / 32); - - _set_gpio_irqenable(base, gpio % 32, 1); -} - -static int gpio_set_irq_type(struct irq_data *d, unsigned int type) -{ - unsigned int gpio = irq_to_gpio(d->irq); - unsigned int gpio_mask = 1 << (gpio % 32); - void __iomem *base = GPIO_BASE(gpio / 32); - unsigned int reg_both, reg_level, reg_type; - - reg_type = __raw_readl(base + GPIO_INT_TYPE); - reg_level = __raw_readl(base + GPIO_INT_LEVEL); - reg_both = __raw_readl(base + GPIO_INT_BOTH_EDGE); - - switch (type) { - case IRQ_TYPE_EDGE_BOTH: - reg_type &= ~gpio_mask; - reg_both |= gpio_mask; - break; - case IRQ_TYPE_EDGE_RISING: - reg_type &= ~gpio_mask; - reg_both &= ~gpio_mask; - reg_level &= ~gpio_mask; - break; - case IRQ_TYPE_EDGE_FALLING: - reg_type &= ~gpio_mask; - reg_both &= ~gpio_mask; - reg_level |= gpio_mask; - break; - case IRQ_TYPE_LEVEL_HIGH: - reg_type |= gpio_mask; - reg_level &= ~gpio_mask; - break; - case IRQ_TYPE_LEVEL_LOW: - reg_type |= gpio_mask; - reg_level |= gpio_mask; - break; - default: - return -EINVAL; - } - - __raw_writel(reg_type, base + GPIO_INT_TYPE); - __raw_writel(reg_level, base + GPIO_INT_LEVEL); - __raw_writel(reg_both, base + GPIO_INT_BOTH_EDGE); - - gpio_ack_irq(d); - - return 0; -} - -static void gpio_irq_handler(struct irq_desc *desc) -{ - unsigned int port = (unsigned int)irq_desc_get_handler_data(desc); - unsigned int gpio_irq_no, irq_stat; - - irq_stat = __raw_readl(GPIO_BASE(port) + GPIO_INT_STAT); - - gpio_irq_no = GPIO_IRQ_BASE + port * 32; - for (; irq_stat != 0; irq_stat >>= 1, gpio_irq_no++) { - - if ((irq_stat & 1) == 0) - continue; - - generic_handle_irq(gpio_irq_no); - } -} - -static struct irq_chip gpio_irq_chip = { - .name = "GPIO", - .irq_ack = gpio_ack_irq, - .irq_mask = gpio_mask_irq, - .irq_unmask = gpio_unmask_irq, - .irq_set_type = gpio_set_irq_type, -}; - -static void _set_gpio_direction(struct gpio_chip *chip, unsigned offset, - int dir) -{ - void __iomem *base = GPIO_BASE(offset / 32); - unsigned int reg; - - reg = __raw_readl(base + GPIO_DIR); - if (dir) - reg |= 1 << (offset % 32); - else - reg &= ~(1 << (offset % 32)); - __raw_writel(reg, base + GPIO_DIR); -} - -static void gemini_gpio_set(struct gpio_chip *chip, unsigned offset, int value) -{ - void __iomem *base = GPIO_BASE(offset / 32); - - if (value) - __raw_writel(1 << (offset % 32), base + GPIO_DATA_SET); - else - __raw_writel(1 << (offset % 32), base + GPIO_DATA_CLR); -} - -static int gemini_gpio_get(struct gpio_chip *chip, unsigned offset) -{ - void __iomem *base = GPIO_BASE(offset / 32); - - return (__raw_readl(base + GPIO_DATA_IN) >> (offset % 32)) & 1; -} - -static int gemini_gpio_direction_input(struct gpio_chip *chip, unsigned offset) -{ - _set_gpio_direction(chip, offset, 0); - return 0; -} - -static int gemini_gpio_direction_output(struct gpio_chip *chip, unsigned offset, - int value) -{ - _set_gpio_direction(chip, offset, 1); - gemini_gpio_set(chip, offset, value); - return 0; -} - -static struct gpio_chip gemini_gpio_chip = { - .label = "Gemini", - .direction_input = gemini_gpio_direction_input, - .get = gemini_gpio_get, - .direction_output = gemini_gpio_direction_output, - .set = gemini_gpio_set, - .base = 0, - .ngpio = GPIO_PORT_NUM * 32, -}; - -void __init gemini_gpio_init(void) -{ - int i, j; - - for (i = 0; i < GPIO_PORT_NUM; i++) { - /* disable, unmask and clear all interrupts */ - __raw_writel(0x0, GPIO_BASE(i) + GPIO_INT_EN); - __raw_writel(0x0, GPIO_BASE(i) + GPIO_INT_MASK); - __raw_writel(~0x0, GPIO_BASE(i) + GPIO_INT_CLR); - - for (j = GPIO_IRQ_BASE + i * 32; - j < GPIO_IRQ_BASE + (i + 1) * 32; j++) { - irq_set_chip_and_handler(j, &gpio_irq_chip, - handle_edge_irq); - irq_clear_status_flags(j, IRQ_NOREQUEST); - } - - irq_set_chained_handler_and_data(IRQ_GPIO(i), gpio_irq_handler, - (void *)i); - } - - BUG_ON(gpiochip_add_data(&gemini_gpio_chip, NULL)); -} diff --git a/arch/arm/mach-gemini/idle.c b/arch/arm/mach-gemini/idle.c deleted file mode 100644 index ddf8ec9d203b..000000000000 --- a/arch/arm/mach-gemini/idle.c +++ /dev/null @@ -1,31 +0,0 @@ -/* - * arch/arm/mach-gemini/idle.c - */ - -#include -#include -#include - -static void gemini_idle(void) -{ - /* - * Because of broken hardware we have to enable interrupts or the CPU - * will never wakeup... Acctualy it is not very good to enable - * interrupts first since scheduler can miss a tick, but there is - * no other way around this. Platforms that needs it for power saving - * should enable it in init code, since by default it is - * disabled. - */ - - /* FIXME: Enabling interrupts here is racy! */ - local_irq_enable(); - cpu_do_idle(); -} - -static int __init gemini_idle_init(void) -{ - arm_pm_idle = gemini_idle; - return 0; -} - -arch_initcall(gemini_idle_init); diff --git a/arch/arm/mach-gemini/include/mach/entry-macro.S b/arch/arm/mach-gemini/include/mach/entry-macro.S deleted file mode 100644 index f044e430bfa4..000000000000 --- a/arch/arm/mach-gemini/include/mach/entry-macro.S +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Low-level IRQ helper macros for Gemini platform. - * - * Copyright (C) 2001-2006 Storlink, Corp. - * Copyright (C) 2008-2009 Paulius Zaleckas - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ -#include - -#define IRQ_STATUS 0x14 - - .macro get_irqnr_preamble, base, tmp - .endm - - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp - ldr \irqstat, =IO_ADDRESS(GEMINI_INTERRUPT_BASE + IRQ_STATUS) - ldr \irqnr, [\irqstat] - cmp \irqnr, #0 - beq 2313f - mov \tmp, \irqnr - mov \irqnr, #0 -2312: - tst \tmp, #1 - bne 2313f - add \irqnr, \irqnr, #1 - mov \tmp, \tmp, lsr #1 - cmp \irqnr, #31 - bcc 2312b -2313: - .endm diff --git a/arch/arm/mach-gemini/include/mach/global_reg.h b/arch/arm/mach-gemini/include/mach/global_reg.h deleted file mode 100644 index de7ff7e849fc..000000000000 --- a/arch/arm/mach-gemini/include/mach/global_reg.h +++ /dev/null @@ -1,278 +0,0 @@ -/* - * This file contains the hardware definitions for Gemini. - * - * Copyright (C) 2009 Paulius Zaleckas - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ -#ifndef __MACH_GLOBAL_REG_H -#define __MACH_GLOBAL_REG_H - -/* Global Word ID Register*/ -#define GLOBAL_ID 0x00 - -#define CHIP_ID(reg) ((reg) >> 8) -#define CHIP_REVISION(reg) ((reg) & 0xFF) - -/* Global Status Register */ -#define GLOBAL_STATUS 0x04 - -#define CPU_BIG_ENDIAN (1 << 31) -#define PLL_OSC_30M (1 << 30) /* else 60MHz */ - -#define OPERATION_MODE_MASK (0xF << 26) -#define OPM_IDDQ (0xF << 26) -#define OPM_NAND (0xE << 26) -#define OPM_RING (0xD << 26) -#define OPM_DIRECT_BOOT (0xC << 26) -#define OPM_USB1_PHY_TEST (0xB << 26) -#define OPM_USB0_PHY_TEST (0xA << 26) -#define OPM_SATA1_PHY_TEST (0x9 << 26) -#define OPM_SATA0_PHY_TEST (0x8 << 26) -#define OPM_ICE_ARM (0x7 << 26) -#define OPM_ICE_FARADAY (0x6 << 26) -#define OPM_PLL_BYPASS (0x5 << 26) -#define OPM_DEBUG (0x4 << 26) -#define OPM_BURN_IN (0x3 << 26) -#define OPM_MBIST (0x2 << 26) -#define OPM_SCAN (0x1 << 26) -#define OPM_REAL (0x0 << 26) - -#define FLASH_TYPE_MASK (0x3 << 24) -#define FLASH_TYPE_NAND_2K (0x3 << 24) -#define FLASH_TYPE_NAND_512 (0x2 << 24) -#define FLASH_TYPE_PARALLEL (0x1 << 24) -#define FLASH_TYPE_SERIAL (0x0 << 24) -/* if parallel */ -#define FLASH_WIDTH_16BIT (1 << 23) /* else 8 bit */ -/* if serial */ -#define FLASH_ATMEL (1 << 23) /* else STM */ - -#define FLASH_SIZE_MASK (0x3 << 21) -#define NAND_256M (0x3 << 21) /* and more */ -#define NAND_128M (0x2 << 21) -#define NAND_64M (0x1 << 21) -#define NAND_32M (0x0 << 21) -#define ATMEL_16M (0x3 << 21) /* and more */ -#define ATMEL_8M (0x2 << 21) -#define ATMEL_4M_2M (0x1 << 21) -#define ATMEL_1M (0x0 << 21) /* and less */ -#define STM_32M (1 << 22) /* and more */ -#define STM_16M (0 << 22) /* and less */ - -#define FLASH_PARALLEL_HIGH_PIN_CNT (1 << 20) /* else low pin cnt */ - -#define CPU_AHB_RATIO_MASK (0x3 << 18) -#define CPU_AHB_1_1 (0x0 << 18) -#define CPU_AHB_3_2 (0x1 << 18) -#define CPU_AHB_24_13 (0x2 << 18) -#define CPU_AHB_2_1 (0x3 << 18) - -#define REG_TO_AHB_SPEED(reg) ((((reg) >> 15) & 0x7) * 10 + 130) -#define AHB_SPEED_TO_REG(x) ((((x - 130)) / 10) << 15) - -/* it is posible to override some settings, use >> OVERRIDE_xxxx_SHIFT */ -#define OVERRIDE_FLASH_TYPE_SHIFT 16 -#define OVERRIDE_FLASH_WIDTH_SHIFT 16 -#define OVERRIDE_FLASH_SIZE_SHIFT 16 -#define OVERRIDE_CPU_AHB_RATIO_SHIFT 15 -#define OVERRIDE_AHB_SPEED_SHIFT 15 - -/* Global PLL Control Register */ -#define GLOBAL_PLL_CTRL 0x08 - -#define PLL_BYPASS (1 << 31) -#define PLL_POWER_DOWN (1 << 8) -#define PLL_CONTROL_Q (0x1F << 0) - -/* Global Soft Reset Control Register */ -#define GLOBAL_RESET 0x0C - -#define RESET_GLOBAL (1 << 31) -#define RESET_CPU1 (1 << 30) -#define RESET_TVE (1 << 28) -#define RESET_SATA1 (1 << 27) -#define RESET_SATA0 (1 << 26) -#define RESET_CIR (1 << 25) -#define RESET_EXT_DEV (1 << 24) -#define RESET_WD (1 << 23) -#define RESET_GPIO2 (1 << 22) -#define RESET_GPIO1 (1 << 21) -#define RESET_GPIO0 (1 << 20) -#define RESET_SSP (1 << 19) -#define RESET_UART (1 << 18) -#define RESET_TIMER (1 << 17) -#define RESET_RTC (1 << 16) -#define RESET_INT1 (1 << 15) -#define RESET_INT0 (1 << 14) -#define RESET_LCD (1 << 13) -#define RESET_LPC (1 << 12) -#define RESET_APB (1 << 11) -#define RESET_DMA (1 << 10) -#define RESET_USB1 (1 << 9) -#define RESET_USB0 (1 << 8) -#define RESET_PCI (1 << 7) -#define RESET_GMAC1 (1 << 6) -#define RESET_GMAC0 (1 << 5) -#define RESET_SECURITY (1 << 4) -#define RESET_RAID (1 << 3) -#define RESET_IDE (1 << 2) -#define RESET_FLASH (1 << 1) -#define RESET_DRAM (1 << 0) - -/* Global IO Pad Driving Capability Control Register */ -#define GLOBAL_IO_DRIVING_CTRL 0x10 - -#define DRIVING_CURRENT_MASK 0x3 - -/* here 00-4mA, 01-8mA, 10-12mA, 11-16mA */ -#define GPIO1_PADS_31_28_SHIFT 28 -#define GPIO0_PADS_31_16_SHIFT 26 -#define GPIO0_PADS_15_0_SHIFT 24 -#define PCI_AND_EXT_RESET_PADS_SHIFT 22 -#define IDE_PADS_SHIFT 20 -#define GMAC1_PADS_SHIFT 18 -#define GMAC0_PADS_SHIFT 16 -/* DRAM is not in mA and poorly documented */ -#define DRAM_CLOCK_PADS_SHIFT 8 -#define DRAM_DATA_PADS_SHIFT 4 -#define DRAM_CONTROL_PADS_SHIFT 0 - -/* Global IO Pad Slew Rate Control Register */ -#define GLOBAL_IO_SLEW_RATE_CTRL 0x14 - -#define GPIO1_PADS_31_28_SLOW (1 << 10) -#define GPIO0_PADS_31_16_SLOW (1 << 9) -#define GPIO0_PADS_15_0_SLOW (1 << 8) -#define PCI_PADS_SLOW (1 << 7) -#define IDE_PADS_SLOW (1 << 6) -#define GMAC1_PADS_SLOW (1 << 5) -#define GMAC0_PADS_SLOW (1 << 4) -#define DRAM_CLOCK_PADS_SLOW (1 << 1) -#define DRAM_IO_PADS_SLOW (1 << 0) - -/* - * General skew control defines - * 16 steps, each step is around 0.2ns - */ -#define SKEW_MASK 0xF - -/* Global IDE PAD Skew Control Register */ -#define GLOBAL_IDE_SKEW_CTRL 0x18 - -#define IDE1_HOST_STROBE_DELAY_SHIFT 28 -#define IDE1_DEVICE_STROBE_DELAY_SHIFT 24 -#define IDE1_OUTPUT_IO_SKEW_SHIFT 20 -#define IDE1_INPUT_IO_SKEW_SHIFT 16 -#define IDE0_HOST_STROBE_DELAY_SHIFT 12 -#define IDE0_DEVICE_STROBE_DELAY_SHIFT 8 -#define IDE0_OUTPUT_IO_SKEW_SHIFT 4 -#define IDE0_INPUT_IO_SKEW_SHIFT 0 - -/* Global GMAC Control Pad Skew Control Register */ -#define GLOBAL_GMAC_CTRL_SKEW_CTRL 0x1C - -#define GMAC1_TXC_SKEW_SHIFT 28 -#define GMAC1_TXEN_SKEW_SHIFT 24 -#define GMAC1_RXC_SKEW_SHIFT 20 -#define GMAC1_RXDV_SKEW_SHIFT 16 -#define GMAC0_TXC_SKEW_SHIFT 12 -#define GMAC0_TXEN_SKEW_SHIFT 8 -#define GMAC0_RXC_SKEW_SHIFT 4 -#define GMAC0_RXDV_SKEW_SHIFT 0 - -/* Global GMAC0 Data PAD Skew Control Register */ -#define GLOBAL_GMAC0_DATA_SKEW_CTRL 0x20 -/* Global GMAC1 Data PAD Skew Control Register */ -#define GLOBAL_GMAC1_DATA_SKEW_CTRL 0x24 - -#define GMAC_TXD_SKEW_SHIFT(x) (((x) * 4) + 16) -#define GMAC_RXD_SKEW_SHIFT(x) ((x) * 4) - -/* CPU has two AHB busses. */ - -/* Global Arbitration0 Control Register */ -#define GLOBAL_ARBITRATION0_CTRL 0x28 - -#define BOOT_CONTROLLER_HIGH_PRIO (1 << 3) -#define DMA_BUS1_HIGH_PRIO (1 << 2) -#define CPU0_HIGH_PRIO (1 << 0) - -/* Global Arbitration1 Control Register */ -#define GLOBAL_ARBITRATION1_CTRL 0x2C - -#define TVE_HIGH_PRIO (1 << 9) -#define PCI_HIGH_PRIO (1 << 8) -#define USB1_HIGH_PRIO (1 << 7) -#define USB0_HIGH_PRIO (1 << 6) -#define GMAC1_HIGH_PRIO (1 << 5) -#define GMAC0_HIGH_PRIO (1 << 4) -#define SECURITY_HIGH_PRIO (1 << 3) -#define RAID_HIGH_PRIO (1 << 2) -#define IDE_HIGH_PRIO (1 << 1) -#define DMA_BUS2_HIGH_PRIO (1 << 0) - -/* Common bits for both arbitration registers */ -#define BURST_LENGTH_SHIFT 16 -#define BURST_LENGTH_MASK (0x3F << 16) - -/* Miscellaneous Control Register */ -#define GLOBAL_MISC_CTRL 0x30 - -#define MEMORY_SPACE_SWAP (1 << 31) -#define USB1_PLUG_MINIB (1 << 30) /* else plug is mini-A */ -#define USB0_PLUG_MINIB (1 << 29) -#define GMAC_GMII (1 << 28) -#define GMAC_1_ENABLE (1 << 27) -/* TODO: define ATA/SATA bits */ -#define USB1_VBUS_ON (1 << 23) -#define USB0_VBUS_ON (1 << 22) -#define APB_CLKOUT_ENABLE (1 << 21) -#define TVC_CLKOUT_ENABLE (1 << 20) -#define EXT_CLKIN_ENABLE (1 << 19) -#define PCI_66MHZ (1 << 18) /* else 33 MHz */ -#define PCI_CLKOUT_ENABLE (1 << 17) -#define LPC_CLKOUT_ENABLE (1 << 16) -#define USB1_WAKEUP_ON (1 << 15) -#define USB0_WAKEUP_ON (1 << 14) -/* TODO: define PCI idle detect bits */ -#define TVC_PADS_ENABLE (1 << 9) -#define SSP_PADS_ENABLE (1 << 8) -#define LCD_PADS_ENABLE (1 << 7) -#define LPC_PADS_ENABLE (1 << 6) -#define PCI_PADS_ENABLE (1 << 5) -#define IDE_PADS_ENABLE (1 << 4) -#define DRAM_PADS_POWER_DOWN (1 << 3) -#define NAND_PADS_DISABLE (1 << 2) -#define PFLASH_PADS_DISABLE (1 << 1) -#define SFLASH_PADS_DISABLE (1 << 0) - -/* Global Clock Control Register */ -#define GLOBAL_CLOCK_CTRL 0x34 - -#define POWER_STATE_G0 (1 << 31) -#define POWER_STATE_S1 (1 << 30) /* else it is S3/S4 state */ -#define SECURITY_APB_AHB (1 << 29) -/* else Security APB clk will be 0.75xAHB */ -/* TODO: TVC clock divider */ -#define PCI_CLKRUN_ENABLE (1 << 16) -#define BOOT_CLK_DISABLE (1 << 13) -#define TVC_CLK_DISABLE (1 << 12) -#define FLASH_CLK_DISABLE (1 << 11) -#define DDR_CLK_DISABLE (1 << 10) -#define PCI_CLK_DISABLE (1 << 9) -#define IDE_CLK_DISABLE (1 << 8) -#define USB1_CLK_DISABLE (1 << 7) -#define USB0_CLK_DISABLE (1 << 6) -#define SATA1_CLK_DISABLE (1 << 5) -#define SATA0_CLK_DISABLE (1 << 4) -#define GMAC1_CLK_DISABLE (1 << 3) -#define GMAC0_CLK_DISABLE (1 << 2) -#define SECURITY_CLK_DISABLE (1 << 1) - -/* TODO: other registers definitions if needed */ - -#endif /* __MACH_GLOBAL_REG_H */ diff --git a/arch/arm/mach-gemini/include/mach/hardware.h b/arch/arm/mach-gemini/include/mach/hardware.h deleted file mode 100644 index f0390f184742..000000000000 --- a/arch/arm/mach-gemini/include/mach/hardware.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * This file contains the hardware definitions for Gemini. - * - * Copyright (C) 2001-2006 Storlink, Corp. - * Copyright (C) 2008-2009 Paulius Zaleckas - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ -#ifndef __MACH_HARDWARE_H -#define __MACH_HARDWARE_H - -/* - * Memory Map definitions - */ -#ifdef CONFIG_GEMINI_MEM_SWAP -# define GEMINI_DRAM_BASE 0x00000000 -# define GEMINI_SRAM_BASE 0x70000000 -#else -# define GEMINI_SRAM_BASE 0x00000000 -# define GEMINI_DRAM_BASE 0x10000000 -#endif -#define GEMINI_FLASH_BASE 0x30000000 -#define GEMINI_GLOBAL_BASE 0x40000000 -#define GEMINI_WAQTCHDOG_BASE 0x41000000 -#define GEMINI_UART_BASE 0x42000000 -#define GEMINI_TIMER_BASE 0x43000000 -#define GEMINI_LCD_BASE 0x44000000 -#define GEMINI_RTC_BASE 0x45000000 -#define GEMINI_SATA_BASE 0x46000000 -#define GEMINI_LPC_HOST_BASE 0x47000000 -#define GEMINI_LPC_IO_BASE 0x47800000 -#define GEMINI_INTERRUPT_BASE 0x48000000 -/* TODO: Different interrupt controllers when SMP - * #define GEMINI_INTERRUPT0_BASE 0x48000000 - * #define GEMINI_INTERRUPT1_BASE 0x49000000 - */ -#define GEMINI_SSP_CTRL_BASE 0x4A000000 -#define GEMINI_POWER_CTRL_BASE 0x4B000000 -#define GEMINI_CIR_BASE 0x4C000000 -#define GEMINI_GPIO_BASE(x) (0x4D000000 + (x) * 0x1000000) -#define GEMINI_PCI_IO_BASE 0x50000000 -#define GEMINI_PCI_MEM_BASE 0x58000000 -#define GEMINI_TOE_BASE 0x60000000 -#define GEMINI_GMAC0_BASE 0x6000A000 -#define GEMINI_GMAC1_BASE 0x6000E000 -#define GEMINI_SECURITY_BASE 0x62000000 -#define GEMINI_IDE0_BASE 0x63000000 -#define GEMINI_IDE1_BASE 0x63400000 -#define GEMINI_RAID_BASE 0x64000000 -#define GEMINI_FLASH_CTRL_BASE 0x65000000 -#define GEMINI_DRAM_CTRL_BASE 0x66000000 -#define GEMINI_GENERAL_DMA_BASE 0x67000000 -#define GEMINI_USB0_BASE 0x68000000 -#define GEMINI_USB1_BASE 0x69000000 -#define GEMINI_BIG_ENDIAN_BASE 0x80000000 - - -/* - * UART Clock when System clk is 150MHz - */ -#define UART_CLK 48000000 - -/* - * macro to get at IO space when running virtually - */ -#define IO_ADDRESS(x) IOMEM((((x) & 0xFFF00000) >> 4) | ((x) & 0x000FFFFF) | 0xF0000000) - -#endif diff --git a/arch/arm/mach-gemini/include/mach/irqs.h b/arch/arm/mach-gemini/include/mach/irqs.h deleted file mode 100644 index 06bc47e77e8b..000000000000 --- a/arch/arm/mach-gemini/include/mach/irqs.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2001-2006 Storlink, Corp. - * Copyright (C) 2008-2009 Paulius Zaleckas - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#ifndef __MACH_IRQS_H__ -#define __MACH_IRQS_H__ - -#define IRQ_SERIRQ1 31 -#define IRQ_SERIRQ0 30 -#define IRQ_PCID 29 -#define IRQ_PCIC 28 -#define IRQ_PCIB 27 -#define IRQ_PWR 26 -#define IRQ_CIR 25 -#define IRQ_GPIO(x) (22 + (x)) -#define IRQ_SSP 21 -#define IRQ_LPC 20 -#define IRQ_LCD 19 -#define IRQ_UART 18 -#define IRQ_RTC 17 -#define IRQ_TIMER3 16 -#define IRQ_TIMER2 15 -#define IRQ_TIMER1 14 -#define IRQ_FLASH 12 -#define IRQ_USB1 11 -#define IRQ_USB0 10 -#define IRQ_DMA 9 -#define IRQ_PCI 8 -#define IRQ_IPSEC 7 -#define IRQ_RAID 6 -#define IRQ_IDE1 5 -#define IRQ_IDE0 4 -#define IRQ_WATCHDOG 3 -#define IRQ_GMAC1 2 -#define IRQ_GMAC0 1 -#define IRQ_IPI 0 - -#define NORMAL_IRQ_NUM 32 - -#define GPIO_IRQ_BASE NORMAL_IRQ_NUM -#define GPIO_IRQ_NUM (3 * 32) - -#define ARCH_TIMER_IRQ IRQ_TIMER2 - -#define NR_IRQS (NORMAL_IRQ_NUM + GPIO_IRQ_NUM) - -#endif /* __MACH_IRQS_H__ */ diff --git a/arch/arm/mach-gemini/include/mach/uncompress.h b/arch/arm/mach-gemini/include/mach/uncompress.h deleted file mode 100644 index 02e225673acb..000000000000 --- a/arch/arm/mach-gemini/include/mach/uncompress.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2008-2009 Paulius Zaleckas - * - * Based on mach-pxa/include/mach/uncompress.h: - * Copyright: (C) 2001 MontaVista Software Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#ifndef __MACH_UNCOMPRESS_H -#define __MACH_UNCOMPRESS_H - -#include -#include - -static volatile unsigned long * const UART = (unsigned long *)GEMINI_UART_BASE; - -/* - * The following code assumes the serial port has already been - * initialized by the bootloader. If you didn't setup a port in - * your bootloader then nothing will appear (which might be desired). - */ -static inline void putc(char c) -{ - while (!(UART[UART_LSR] & UART_LSR_THRE)) - barrier(); - UART[UART_TX] = c; -} - -static inline void flush(void) -{ -} - -/* - * nothing to do - */ -#define arch_decomp_setup() - -#endif /* __MACH_UNCOMPRESS_H */ diff --git a/arch/arm/mach-gemini/irq.c b/arch/arm/mach-gemini/irq.c deleted file mode 100644 index d929b3ff18fd..000000000000 --- a/arch/arm/mach-gemini/irq.c +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Interrupt routines for Gemini - * - * Copyright (C) 2001-2006 Storlink, Corp. - * Copyright (C) 2008-2009 Paulius Zaleckas - * - * 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 -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#define IRQ_SOURCE(base_addr) (base_addr + 0x00) -#define IRQ_MASK(base_addr) (base_addr + 0x04) -#define IRQ_CLEAR(base_addr) (base_addr + 0x08) -#define IRQ_TMODE(base_addr) (base_addr + 0x0C) -#define IRQ_TLEVEL(base_addr) (base_addr + 0x10) -#define IRQ_STATUS(base_addr) (base_addr + 0x14) -#define FIQ_SOURCE(base_addr) (base_addr + 0x20) -#define FIQ_MASK(base_addr) (base_addr + 0x24) -#define FIQ_CLEAR(base_addr) (base_addr + 0x28) -#define FIQ_TMODE(base_addr) (base_addr + 0x2C) -#define FIQ_LEVEL(base_addr) (base_addr + 0x30) -#define FIQ_STATUS(base_addr) (base_addr + 0x34) - -static void gemini_ack_irq(struct irq_data *d) -{ - __raw_writel(1 << d->irq, IRQ_CLEAR(IO_ADDRESS(GEMINI_INTERRUPT_BASE))); -} - -static void gemini_mask_irq(struct irq_data *d) -{ - unsigned int mask; - - mask = __raw_readl(IRQ_MASK(IO_ADDRESS(GEMINI_INTERRUPT_BASE))); - mask &= ~(1 << d->irq); - __raw_writel(mask, IRQ_MASK(IO_ADDRESS(GEMINI_INTERRUPT_BASE))); -} - -static void gemini_unmask_irq(struct irq_data *d) -{ - unsigned int mask; - - mask = __raw_readl(IRQ_MASK(IO_ADDRESS(GEMINI_INTERRUPT_BASE))); - mask |= (1 << d->irq); - __raw_writel(mask, IRQ_MASK(IO_ADDRESS(GEMINI_INTERRUPT_BASE))); -} - -static struct irq_chip gemini_irq_chip = { - .name = "INTC", - .irq_ack = gemini_ack_irq, - .irq_mask = gemini_mask_irq, - .irq_unmask = gemini_unmask_irq, -}; - -static struct resource irq_resource = { - .name = "irq_handler", - .start = GEMINI_INTERRUPT_BASE, - .end = FIQ_STATUS(GEMINI_INTERRUPT_BASE) + 4, -}; - -void __init gemini_init_irq(void) -{ - unsigned int i, mode = 0, level = 0; - - /* - * Disable the idle handler by default since it is buggy - * For more info see arch/arm/mach-gemini/idle.c - */ - cpu_idle_poll_ctrl(true); - - request_resource(&iomem_resource, &irq_resource); - - for (i = 0; i < NR_IRQS; i++) { - irq_set_chip(i, &gemini_irq_chip); - if((i >= IRQ_TIMER1 && i <= IRQ_TIMER3) || (i >= IRQ_SERIRQ0 && i <= IRQ_SERIRQ1)) { - irq_set_handler(i, handle_edge_irq); - mode |= 1 << i; - level |= 1 << i; - } else { - irq_set_handler(i, handle_level_irq); - } - irq_clear_status_flags(i, IRQ_NOREQUEST | IRQ_NOPROBE); - } - - /* Disable all interrupts */ - __raw_writel(0, IRQ_MASK(IO_ADDRESS(GEMINI_INTERRUPT_BASE))); - __raw_writel(0, FIQ_MASK(IO_ADDRESS(GEMINI_INTERRUPT_BASE))); - - /* Set interrupt mode */ - __raw_writel(mode, IRQ_TMODE(IO_ADDRESS(GEMINI_INTERRUPT_BASE))); - __raw_writel(level, IRQ_TLEVEL(IO_ADDRESS(GEMINI_INTERRUPT_BASE))); -} diff --git a/arch/arm/mach-gemini/mm.c b/arch/arm/mach-gemini/mm.c deleted file mode 100644 index 2c2cd284bb6a..000000000000 --- a/arch/arm/mach-gemini/mm.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Static mappings for Gemini - * - * Copyright (C) 2001-2006 Storlink, Corp. - * Copyright (C) 2008-2009 Paulius Zaleckas - * - * 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 -#include - -#include - -#include - -/* Page table mapping for I/O region */ -static struct map_desc gemini_io_desc[] __initdata = { - { - .virtual = (unsigned long)IO_ADDRESS(GEMINI_GLOBAL_BASE), - .pfn =__phys_to_pfn(GEMINI_GLOBAL_BASE), - .length = SZ_512K, - .type = MT_DEVICE, - }, { - .virtual = (unsigned long)IO_ADDRESS(GEMINI_UART_BASE), - .pfn = __phys_to_pfn(GEMINI_UART_BASE), - .length = SZ_512K, - .type = MT_DEVICE, - }, { - .virtual = (unsigned long)IO_ADDRESS(GEMINI_TIMER_BASE), - .pfn = __phys_to_pfn(GEMINI_TIMER_BASE), - .length = SZ_512K, - .type = MT_DEVICE, - }, { - .virtual = (unsigned long)IO_ADDRESS(GEMINI_INTERRUPT_BASE), - .pfn = __phys_to_pfn(GEMINI_INTERRUPT_BASE), - .length = SZ_512K, - .type = MT_DEVICE, - }, { - .virtual = (unsigned long)IO_ADDRESS(GEMINI_POWER_CTRL_BASE), - .pfn = __phys_to_pfn(GEMINI_POWER_CTRL_BASE), - .length = SZ_512K, - .type = MT_DEVICE, - }, { - .virtual = (unsigned long)IO_ADDRESS(GEMINI_GPIO_BASE(0)), - .pfn = __phys_to_pfn(GEMINI_GPIO_BASE(0)), - .length = SZ_512K, - .type = MT_DEVICE, - }, { - .virtual = (unsigned long)IO_ADDRESS(GEMINI_GPIO_BASE(1)), - .pfn = __phys_to_pfn(GEMINI_GPIO_BASE(1)), - .length = SZ_512K, - .type = MT_DEVICE, - }, { - .virtual = (unsigned long)IO_ADDRESS(GEMINI_GPIO_BASE(2)), - .pfn = __phys_to_pfn(GEMINI_GPIO_BASE(2)), - .length = SZ_512K, - .type = MT_DEVICE, - }, { - .virtual = (unsigned long)IO_ADDRESS(GEMINI_FLASH_CTRL_BASE), - .pfn = __phys_to_pfn(GEMINI_FLASH_CTRL_BASE), - .length = SZ_512K, - .type = MT_DEVICE, - }, { - .virtual = (unsigned long)IO_ADDRESS(GEMINI_DRAM_CTRL_BASE), - .pfn = __phys_to_pfn(GEMINI_DRAM_CTRL_BASE), - .length = SZ_512K, - .type = MT_DEVICE, - }, { - .virtual = (unsigned long)IO_ADDRESS(GEMINI_GENERAL_DMA_BASE), - .pfn = __phys_to_pfn(GEMINI_GENERAL_DMA_BASE), - .length = SZ_512K, - .type = MT_DEVICE, - }, -}; - -void __init gemini_map_io(void) -{ - iotable_init(gemini_io_desc, ARRAY_SIZE(gemini_io_desc)); -} diff --git a/arch/arm/mach-gemini/reset.c b/arch/arm/mach-gemini/reset.c deleted file mode 100644 index 21a6d6d4f9c4..000000000000 --- a/arch/arm/mach-gemini/reset.c +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) 2001-2006 Storlink, Corp. - * Copyright (C) 2008-2009 Paulius Zaleckas - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ -#ifndef __MACH_SYSTEM_H -#define __MACH_SYSTEM_H - -#include -#include -#include - -#include "common.h" - -void gemini_restart(enum reboot_mode mode, const char *cmd) -{ - __raw_writel(RESET_GLOBAL | RESET_CPU1, - IO_ADDRESS(GEMINI_GLOBAL_BASE) + GLOBAL_RESET); -} - -#endif /* __MACH_SYSTEM_H */ diff --git a/arch/arm/mach-gemini/time.c b/arch/arm/mach-gemini/time.c deleted file mode 100644 index f5f18df5aacd..000000000000 --- a/arch/arm/mach-gemini/time.c +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Copyright (C) 2001-2006 Storlink, Corp. - * Copyright (C) 2008-2009 Paulius Zaleckas - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * Register definitions for the timers - */ - -#define TIMER1_BASE GEMINI_TIMER_BASE -#define TIMER2_BASE (GEMINI_TIMER_BASE + 0x10) -#define TIMER3_BASE (GEMINI_TIMER_BASE + 0x20) - -#define TIMER_COUNT(BASE) (IO_ADDRESS(BASE) + 0x00) -#define TIMER_LOAD(BASE) (IO_ADDRESS(BASE) + 0x04) -#define TIMER_MATCH1(BASE) (IO_ADDRESS(BASE) + 0x08) -#define TIMER_MATCH2(BASE) (IO_ADDRESS(BASE) + 0x0C) -#define TIMER_CR (IO_ADDRESS(GEMINI_TIMER_BASE) + 0x30) -#define TIMER_INTR_STATE (IO_ADDRESS(GEMINI_TIMER_BASE) + 0x34) -#define TIMER_INTR_MASK (IO_ADDRESS(GEMINI_TIMER_BASE) + 0x38) - -#define TIMER_1_CR_ENABLE (1 << 0) -#define TIMER_1_CR_CLOCK (1 << 1) -#define TIMER_1_CR_INT (1 << 2) -#define TIMER_2_CR_ENABLE (1 << 3) -#define TIMER_2_CR_CLOCK (1 << 4) -#define TIMER_2_CR_INT (1 << 5) -#define TIMER_3_CR_ENABLE (1 << 6) -#define TIMER_3_CR_CLOCK (1 << 7) -#define TIMER_3_CR_INT (1 << 8) -#define TIMER_1_CR_UPDOWN (1 << 9) -#define TIMER_2_CR_UPDOWN (1 << 10) -#define TIMER_3_CR_UPDOWN (1 << 11) -#define TIMER_DEFAULT_FLAGS (TIMER_1_CR_UPDOWN | \ - TIMER_3_CR_ENABLE | \ - TIMER_3_CR_UPDOWN) - -#define TIMER_1_INT_MATCH1 (1 << 0) -#define TIMER_1_INT_MATCH2 (1 << 1) -#define TIMER_1_INT_OVERFLOW (1 << 2) -#define TIMER_2_INT_MATCH1 (1 << 3) -#define TIMER_2_INT_MATCH2 (1 << 4) -#define TIMER_2_INT_OVERFLOW (1 << 5) -#define TIMER_3_INT_MATCH1 (1 << 6) -#define TIMER_3_INT_MATCH2 (1 << 7) -#define TIMER_3_INT_OVERFLOW (1 << 8) -#define TIMER_INT_ALL_MASK 0x1ff - - -static unsigned int tick_rate; - -static u64 notrace gemini_read_sched_clock(void) -{ - return readl(TIMER_COUNT(TIMER3_BASE)); -} - -static int gemini_timer_set_next_event(unsigned long cycles, - struct clock_event_device *evt) -{ - u32 cr; - - /* Setup the match register */ - cr = readl(TIMER_COUNT(TIMER1_BASE)); - writel(cr + cycles, TIMER_MATCH1(TIMER1_BASE)); - if (readl(TIMER_COUNT(TIMER1_BASE)) - cr > cycles) - return -ETIME; - - return 0; -} - -static int gemini_timer_shutdown(struct clock_event_device *evt) -{ - u32 cr; - - /* - * Disable also for oneshot: the set_next() call will arm the timer - * instead. - */ - /* Stop timer and interrupt. */ - cr = readl(TIMER_CR); - cr &= ~(TIMER_1_CR_ENABLE | TIMER_1_CR_INT); - writel(cr, TIMER_CR); - - /* Setup counter start from 0 */ - writel(0, TIMER_COUNT(TIMER1_BASE)); - writel(0, TIMER_LOAD(TIMER1_BASE)); - - /* enable interrupt */ - cr = readl(TIMER_INTR_MASK); - cr &= ~(TIMER_1_INT_OVERFLOW | TIMER_1_INT_MATCH2); - cr |= TIMER_1_INT_MATCH1; - writel(cr, TIMER_INTR_MASK); - - /* start the timer */ - cr = readl(TIMER_CR); - cr |= TIMER_1_CR_ENABLE; - writel(cr, TIMER_CR); - - return 0; -} - -static int gemini_timer_set_periodic(struct clock_event_device *evt) -{ - u32 period = DIV_ROUND_CLOSEST(tick_rate, HZ); - u32 cr; - - /* Stop timer and interrupt */ - cr = readl(TIMER_CR); - cr &= ~(TIMER_1_CR_ENABLE | TIMER_1_CR_INT); - writel(cr, TIMER_CR); - - /* Setup timer to fire at 1/HT intervals. */ - cr = 0xffffffff - (period - 1); - writel(cr, TIMER_COUNT(TIMER1_BASE)); - writel(cr, TIMER_LOAD(TIMER1_BASE)); - - /* enable interrupt on overflow */ - cr = readl(TIMER_INTR_MASK); - cr &= ~(TIMER_1_INT_MATCH1 | TIMER_1_INT_MATCH2); - cr |= TIMER_1_INT_OVERFLOW; - writel(cr, TIMER_INTR_MASK); - - /* Start the timer */ - cr = readl(TIMER_CR); - cr |= TIMER_1_CR_ENABLE; - cr |= TIMER_1_CR_INT; - writel(cr, TIMER_CR); - - return 0; -} - -/* Use TIMER1 as clock event */ -static struct clock_event_device gemini_clockevent = { - .name = "TIMER1", - /* Reasonably fast and accurate clock event */ - .rating = 300, - .shift = 32, - .features = CLOCK_EVT_FEAT_PERIODIC | - CLOCK_EVT_FEAT_ONESHOT, - .set_next_event = gemini_timer_set_next_event, - .set_state_shutdown = gemini_timer_shutdown, - .set_state_periodic = gemini_timer_set_periodic, - .set_state_oneshot = gemini_timer_shutdown, - .tick_resume = gemini_timer_shutdown, -}; - -/* - * IRQ handler for the timer - */ -static irqreturn_t gemini_timer_interrupt(int irq, void *dev_id) -{ - struct clock_event_device *evt = &gemini_clockevent; - - evt->event_handler(evt); - return IRQ_HANDLED; -} - -static struct irqaction gemini_timer_irq = { - .name = "Gemini Timer Tick", - .flags = IRQF_TIMER, - .handler = gemini_timer_interrupt, -}; - -/* - * Set up timer interrupt, and return the current time in seconds. - */ -void __init gemini_timer_init(void) -{ - u32 reg_v; - - reg_v = readl(IO_ADDRESS(GEMINI_GLOBAL_BASE + GLOBAL_STATUS)); - tick_rate = REG_TO_AHB_SPEED(reg_v) * 1000000; - - printk(KERN_INFO "Bus: %dMHz", tick_rate / 1000000); - - tick_rate /= 6; /* APB bus run AHB*(1/6) */ - - switch(reg_v & CPU_AHB_RATIO_MASK) { - case CPU_AHB_1_1: - printk(KERN_CONT "(1/1)\n"); - break; - case CPU_AHB_3_2: - printk(KERN_CONT "(3/2)\n"); - break; - case CPU_AHB_24_13: - printk(KERN_CONT "(24/13)\n"); - break; - case CPU_AHB_2_1: - printk(KERN_CONT "(2/1)\n"); - break; - } - - /* - * Reset the interrupt mask and status - */ - writel(TIMER_INT_ALL_MASK, TIMER_INTR_MASK); - writel(0, TIMER_INTR_STATE); - writel(TIMER_DEFAULT_FLAGS, TIMER_CR); - - /* - * Setup free-running clocksource timer (interrupts - * disabled.) - */ - writel(0, TIMER_COUNT(TIMER3_BASE)); - writel(0, TIMER_LOAD(TIMER3_BASE)); - writel(0, TIMER_MATCH1(TIMER3_BASE)); - writel(0, TIMER_MATCH2(TIMER3_BASE)); - clocksource_mmio_init(TIMER_COUNT(TIMER3_BASE), - "gemini_clocksource", tick_rate, - 300, 32, clocksource_mmio_readl_up); - sched_clock_register(gemini_read_sched_clock, 32, tick_rate); - - /* - * Setup clockevent timer (interrupt-driven.) - */ - writel(0, TIMER_COUNT(TIMER1_BASE)); - writel(0, TIMER_LOAD(TIMER1_BASE)); - writel(0, TIMER_MATCH1(TIMER1_BASE)); - writel(0, TIMER_MATCH2(TIMER1_BASE)); - setup_irq(IRQ_TIMER1, &gemini_timer_irq); - gemini_clockevent.cpumask = cpumask_of(0); - clockevents_config_and_register(&gemini_clockevent, tick_rate, - 1, 0xffffffff); - -} diff --git a/arch/arm/mach-hisi/platmcpm.c b/arch/arm/mach-hisi/platmcpm.c index a6c117622d67..f66815c3dd07 100644 --- a/arch/arm/mach-hisi/platmcpm.c +++ b/arch/arm/mach-hisi/platmcpm.c @@ -279,6 +279,8 @@ static int __init hip04_smp_init(void) &hip04_boot_method[0], 4); if (ret) goto err; + + ret = -ENODEV; np_sctl = of_find_compatible_node(NULL, NULL, "hisilicon,sysctrl"); if (!np_sctl) goto err; diff --git a/arch/arm/mach-imx/mach-imx25.c b/arch/arm/mach-imx/mach-imx25.c index 32dcb5e99e23..353b86e3808f 100644 --- a/arch/arm/mach-imx/mach-imx25.c +++ b/arch/arm/mach-imx/mach-imx25.c @@ -23,6 +23,11 @@ static void __init imx25_init_early(void) mxc_set_cpu_type(MXC_CPU_MX25); } +static void __init imx25_dt_init(void) +{ + imx_aips_allow_unprivileged_access("fsl,imx25-aips"); +} + static void __init mx25_init_irq(void) { struct device_node *np; @@ -41,6 +46,7 @@ static const char * const imx25_dt_board_compat[] __initconst = { DT_MACHINE_START(IMX25_DT, "Freescale i.MX25 (Device Tree Support)") .init_early = imx25_init_early, + .init_machine = imx25_dt_init, .init_late = imx25_pm_init, .init_irq = mx25_init_irq, .dt_compat = imx25_dt_board_compat, diff --git a/arch/arm/mach-imx/mach-mx31_3ds.c b/arch/arm/mach-imx/mach-mx31_3ds.c index 558e5f8589cb..68c3f0799d5b 100644 --- a/arch/arm/mach-imx/mach-mx31_3ds.c +++ b/arch/arm/mach-imx/mach-mx31_3ds.c @@ -375,6 +375,8 @@ static struct imx_ssi_platform_data mx31_3ds_ssi_pdata = { /* SPI */ static int spi0_internal_chipselect[] = { + MXC_SPI_CS(0), + MXC_SPI_CS(1), MXC_SPI_CS(2), }; @@ -385,6 +387,7 @@ static const struct spi_imx_master spi0_pdata __initconst = { static int spi1_internal_chipselect[] = { MXC_SPI_CS(0), + MXC_SPI_CS(1), MXC_SPI_CS(2), }; @@ -398,7 +401,7 @@ static struct spi_board_info mx31_3ds_spi_devs[] __initdata = { .modalias = "mc13783", .max_speed_hz = 1000000, .bus_num = 1, - .chip_select = 1, /* SS2 */ + .chip_select = 2, /* SS2 */ .platform_data = &mc13783_pdata, /* irq number is run-time assigned */ .mode = SPI_CS_HIGH, @@ -406,7 +409,7 @@ static struct spi_board_info mx31_3ds_spi_devs[] __initdata = { .modalias = "l4f00242t03", .max_speed_hz = 5000000, .bus_num = 0, - .chip_select = 0, /* SS2 */ + .chip_select = 2, /* SS2 */ .platform_data = &mx31_3ds_l4f00242t03_pdata, }, }; diff --git a/arch/arm/mach-imx/mach-mx31moboard.c b/arch/arm/mach-imx/mach-mx31moboard.c index cc867682520e..bde9a9af6714 100644 --- a/arch/arm/mach-imx/mach-mx31moboard.c +++ b/arch/arm/mach-imx/mach-mx31moboard.c @@ -296,14 +296,14 @@ static struct spi_board_info moboard_spi_board_info[] __initdata = { /* irq number is run-time assigned */ .max_speed_hz = 300000, .bus_num = 1, - .chip_select = 0, + .chip_select = 1, .platform_data = &moboard_pmic, .mode = SPI_CS_HIGH, }, }; static int moboard_spi2_cs[] = { - MXC_SPI_CS(1), + MXC_SPI_CS(0), MXC_SPI_CS(1), }; static const struct spi_imx_master moboard_spi2_pdata __initconst = { diff --git a/arch/arm/mach-imx/mach-pcm037_eet.c b/arch/arm/mach-imx/mach-pcm037_eet.c index 8fd8255068ee..95bd97710494 100644 --- a/arch/arm/mach-imx/mach-pcm037_eet.c +++ b/arch/arm/mach-imx/mach-pcm037_eet.c @@ -50,13 +50,13 @@ static struct spi_board_info pcm037_spi_dev[] = { .modalias = "dac124s085", .max_speed_hz = 400000, .bus_num = 0, - .chip_select = 0, /* Index in pcm037_spi1_cs[] */ + .chip_select = 1, /* Index in pcm037_spi1_cs[] */ .mode = SPI_CPHA, }, }; /* Platform Data for MXC CSPI */ -static int pcm037_spi1_cs[] = {MXC_SPI_CS(1), IOMUX_TO_GPIO(MX31_PIN_KEY_COL7)}; +static int pcm037_spi1_cs[] = { MXC_SPI_CS(0), MXC_SPI_CS(1), }; static const struct spi_imx_master pcm037_spi1_pdata __initconst = { .chipselect = pcm037_spi1_cs, diff --git a/arch/arm/mach-imx/mmdc.c b/arch/arm/mach-imx/mmdc.c index c03bf28d8bbc..78262899a590 100644 --- a/arch/arm/mach-imx/mmdc.c +++ b/arch/arm/mach-imx/mmdc.c @@ -1,4 +1,5 @@ /* + * Copyright 2017 NXP * Copyright 2011,2016 Freescale Semiconductor, Inc. * Copyright 2011 Linaro Ltd. * @@ -47,6 +48,7 @@ #define PROFILE_SEL 0x10 #define MMDC_MADPCR0 0x410 +#define MMDC_MADPCR1 0x414 #define MMDC_MADPSR0 0x418 #define MMDC_MADPSR1 0x41C #define MMDC_MADPSR2 0x420 @@ -57,6 +59,7 @@ #define MMDC_NUM_COUNTERS 6 #define MMDC_FLAG_PROFILE_SEL 0x1 +#define MMDC_PRF_AXI_ID_CLEAR 0x0 #define to_mmdc_pmu(p) container_of(p, struct mmdc_pmu, pmu) @@ -87,7 +90,7 @@ static DEFINE_IDA(mmdc_ida); PMU_EVENT_ATTR_STRING(total-cycles, mmdc_pmu_total_cycles, "event=0x00") PMU_EVENT_ATTR_STRING(busy-cycles, mmdc_pmu_busy_cycles, "event=0x01") PMU_EVENT_ATTR_STRING(read-accesses, mmdc_pmu_read_accesses, "event=0x02") -PMU_EVENT_ATTR_STRING(write-accesses, mmdc_pmu_write_accesses, "config=0x03") +PMU_EVENT_ATTR_STRING(write-accesses, mmdc_pmu_write_accesses, "event=0x03") PMU_EVENT_ATTR_STRING(read-bytes, mmdc_pmu_read_bytes, "event=0x04") PMU_EVENT_ATTR_STRING(read-bytes.unit, mmdc_pmu_read_bytes_unit, "MB"); PMU_EVENT_ATTR_STRING(read-bytes.scale, mmdc_pmu_read_bytes_scale, "0.000001"); @@ -161,8 +164,11 @@ static struct attribute_group mmdc_pmu_events_attr_group = { }; PMU_FORMAT_ATTR(event, "config:0-63"); +PMU_FORMAT_ATTR(axi_id, "config1:0-63"); + static struct attribute *mmdc_pmu_format_attrs[] = { &format_attr_event.attr, + &format_attr_axi_id.attr, NULL, }; @@ -345,6 +351,14 @@ static void mmdc_pmu_event_start(struct perf_event *event, int flags) writel(DBG_RST, reg); + /* + * Write the AXI id parameter to MADPCR1. + */ + val = event->attr.config1; + reg = mmdc_base + MMDC_MADPCR1; + writel(val, reg); + + reg = mmdc_base + MMDC_MADPCR0; val = DBG_EN; if (pmu_mmdc->devtype_data->flags & MMDC_FLAG_PROFILE_SEL) val |= PROFILE_SEL; @@ -382,6 +396,10 @@ static void mmdc_pmu_event_stop(struct perf_event *event, int flags) reg = mmdc_base + MMDC_MADPCR0; writel(PRF_FRZ, reg); + + reg = mmdc_base + MMDC_MADPCR1; + writel(MMDC_PRF_AXI_ID_CLEAR, reg); + mmdc_pmu_event_update(event); } diff --git a/arch/arm/mach-mxs/mach-mxs.c b/arch/arm/mach-mxs/mach-mxs.c index e4f21086b42b..1c6062d240c8 100644 --- a/arch/arm/mach-mxs/mach-mxs.c +++ b/arch/arm/mach-mxs/mach-mxs.c @@ -419,7 +419,8 @@ static void __init mxs_machine_init(void) crystalfontz_init(); else if (of_machine_is_compatible("eukrea,mbmx283lc")) eukrea_mbmx283lc_init(); - else if (of_machine_is_compatible("i2se,duckbill")) + else if (of_machine_is_compatible("i2se,duckbill") || + of_machine_is_compatible("i2se,duckbill-2")) duckbill_init(); else if (of_machine_is_compatible("msr,m28cu3")) m28cu3_init(); diff --git a/arch/arm/mach-omap1/pm.c b/arch/arm/mach-omap1/pm.c index ee5460b8ec2e..f1135bf8940e 100644 --- a/arch/arm/mach-omap1/pm.c +++ b/arch/arm/mach-omap1/pm.c @@ -581,7 +581,6 @@ static int omap_pm_enter(suspend_state_t state) { switch (state) { - case PM_SUSPEND_STANDBY: case PM_SUSPEND_MEM: omap1_pm_suspend(); break; diff --git a/arch/arm/mach-omap2/clockdomains81xx_data.c b/arch/arm/mach-omap2/clockdomains81xx_data.c index 3b5fb05ae701..65fbd136b20c 100644 --- a/arch/arm/mach-omap2/clockdomains81xx_data.c +++ b/arch/arm/mach-omap2/clockdomains81xx_data.c @@ -91,6 +91,14 @@ static struct clockdomain default_l3_slow_81xx_clkdm = { .flags = CLKDM_CAN_SWSUP, }; +static struct clockdomain default_sata_81xx_clkdm = { + .name = "default_clkdm", + .pwrdm = { .name = "default_pwrdm" }, + .cm_inst = TI81XX_CM_DEFAULT_MOD, + .clkdm_offs = TI816X_CM_DEFAULT_SATA_CLKDM, + .flags = CLKDM_CAN_SWSUP, +}; + /* 816x only */ static struct clockdomain alwon_mpu_816x_clkdm = { @@ -173,6 +181,7 @@ static struct clockdomain *clockdomains_ti814x[] __initdata = { &mmu_81xx_clkdm, &mmu_cfg_81xx_clkdm, &default_l3_slow_81xx_clkdm, + &default_sata_81xx_clkdm, NULL, }; @@ -200,6 +209,7 @@ static struct clockdomain *clockdomains_ti816x[] __initdata = { &default_ducati_816x_clkdm, &default_pci_816x_clkdm, &default_l3_slow_81xx_clkdm, + &default_sata_81xx_clkdm, NULL, }; diff --git a/arch/arm/mach-omap2/cm81xx.h b/arch/arm/mach-omap2/cm81xx.h index 3a0ccf07c76f..5d73a1057c82 100644 --- a/arch/arm/mach-omap2/cm81xx.h +++ b/arch/arm/mach-omap2/cm81xx.h @@ -57,5 +57,6 @@ #define TI816X_CM_DEFAULT_PCI_CLKDM 0x0010 #define TI816X_CM_DEFAULT_L3_SLOW_CLKDM 0x0014 #define TI816X_CM_DEFAULT_DUCATI_CLKDM 0x0018 +#define TI816X_CM_DEFAULT_SATA_CLKDM 0x0060 #endif diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index 3fdb94599184..473951203104 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c @@ -121,7 +121,7 @@ static inline void omap_init_mcspi(void) {} * * Bind the RNG hwmod to the RNG omap_device. No return value. */ -static void omap_init_rng(void) +static void __init omap_init_rng(void) { struct omap_hwmod *oh; struct platform_device *pdev; diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 0da4f2ea76c4..8bcea0d83fa0 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -138,7 +138,6 @@ #include #include #include -#include #include #include #include @@ -216,48 +215,11 @@ static LIST_HEAD(omap_hwmod_list); /* mpu_oh: used to add/remove MPU initiator from sleepdep list */ static struct omap_hwmod *mpu_oh; -/* - * linkspace: ptr to a buffer that struct omap_hwmod_link records are - * allocated from - used to reduce the number of small memory - * allocations, which has a significant impact on performance - */ -static struct omap_hwmod_link *linkspace; - -/* - * free_ls, max_ls: array indexes into linkspace; representing the - * next free struct omap_hwmod_link index, and the maximum number of - * struct omap_hwmod_link records allocated (respectively) - */ -static unsigned short free_ls, max_ls, ls_supp; - /* inited: set to true once the hwmod code is initialized */ static bool inited; /* Private functions */ -/** - * _fetch_next_ocp_if - return the next OCP interface in a list - * @p: ptr to a ptr to the list_head inside the ocp_if to return - * @i: pointer to the index of the element pointed to by @p in the list - * - * Return a pointer to the struct omap_hwmod_ocp_if record - * containing the struct list_head pointed to by @p, and increment - * @p such that a future call to this routine will return the next - * record. - */ -static struct omap_hwmod_ocp_if *_fetch_next_ocp_if(struct list_head **p, - int *i) -{ - struct omap_hwmod_ocp_if *oi; - - oi = list_entry(*p, struct omap_hwmod_link, node)->ocp_if; - *p = (*p)->next; - - *i = *i + 1; - - return oi; -} - /** * _update_sysc_cache - return the module OCP_SYSCONFIG register, keep copy * @oh: struct omap_hwmod * @@ -794,15 +756,10 @@ static int _init_main_clk(struct omap_hwmod *oh) static int _init_interface_clks(struct omap_hwmod *oh) { struct omap_hwmod_ocp_if *os; - struct list_head *p; struct clk *c; - int i = 0; int ret = 0; - p = oh->slave_ports.next; - - while (i < oh->slaves_cnt) { - os = _fetch_next_ocp_if(&p, &i); + list_for_each_entry(os, &oh->slave_ports, node) { if (!os->clk) continue; @@ -905,19 +862,13 @@ static void _disable_optional_clocks(struct omap_hwmod *oh) static int _enable_clocks(struct omap_hwmod *oh) { struct omap_hwmod_ocp_if *os; - struct list_head *p; - int i = 0; pr_debug("omap_hwmod: %s: enabling clocks\n", oh->name); if (oh->_clk) clk_enable(oh->_clk); - p = oh->slave_ports.next; - - while (i < oh->slaves_cnt) { - os = _fetch_next_ocp_if(&p, &i); - + list_for_each_entry(os, &oh->slave_ports, node) { if (os->_clk && (os->flags & OCPIF_SWSUP_IDLE)) clk_enable(os->_clk); } @@ -939,19 +890,13 @@ static int _enable_clocks(struct omap_hwmod *oh) static int _disable_clocks(struct omap_hwmod *oh) { struct omap_hwmod_ocp_if *os; - struct list_head *p; - int i = 0; pr_debug("omap_hwmod: %s: disabling clocks\n", oh->name); if (oh->_clk) clk_disable(oh->_clk); - p = oh->slave_ports.next; - - while (i < oh->slaves_cnt) { - os = _fetch_next_ocp_if(&p, &i); - + list_for_each_entry(os, &oh->slave_ports, node) { if (os->_clk && (os->flags & OCPIF_SWSUP_IDLE)) clk_disable(os->_clk); } @@ -1190,16 +1135,11 @@ static int _get_sdma_req_by_name(struct omap_hwmod *oh, const char *name, static int _get_addr_space_by_name(struct omap_hwmod *oh, const char *name, u32 *pa_start, u32 *pa_end) { - int i, j; + int j; struct omap_hwmod_ocp_if *os; - struct list_head *p = NULL; bool found = false; - p = oh->slave_ports.next; - - i = 0; - while (i < oh->slaves_cnt) { - os = _fetch_next_ocp_if(&p, &i); + list_for_each_entry(os, &oh->slave_ports, node) { if (!os->addr) return -ENOENT; @@ -1239,18 +1179,13 @@ static int _get_addr_space_by_name(struct omap_hwmod *oh, const char *name, static void __init _save_mpu_port_index(struct omap_hwmod *oh) { struct omap_hwmod_ocp_if *os = NULL; - struct list_head *p; - int i = 0; if (!oh) return; oh->_int_flags |= _HWMOD_NO_MPU_PORT; - p = oh->slave_ports.next; - - while (i < oh->slaves_cnt) { - os = _fetch_next_ocp_if(&p, &i); + list_for_each_entry(os, &oh->slave_ports, node) { if (os->user & OCP_USER_MPU) { oh->_mpu_port = os; oh->_int_flags &= ~_HWMOD_NO_MPU_PORT; @@ -1393,7 +1328,7 @@ static void _enable_sysc(struct omap_hwmod *oh) */ if ((oh->flags & HWMOD_SET_DEFAULT_CLOCKACT) && (sf & SYSC_HAS_CLOCKACTIVITY)) - _set_clockactivity(oh, oh->class->sysc->clockact, &v); + _set_clockactivity(oh, CLOCKACT_TEST_ICLK, &v); _write_sysconfig(v, oh); @@ -2092,7 +2027,7 @@ static int _enable(struct omap_hwmod *oh) r = (soc_ops.wait_target_ready) ? soc_ops.wait_target_ready(oh) : -EINVAL; - if (oh->clkdm) + if (oh->clkdm && !(oh->flags & HWMOD_CLKDM_NOAUTO)) clkdm_allow_idle(oh->clkdm); if (!r) { @@ -2149,7 +2084,12 @@ static int _idle(struct omap_hwmod *oh) _idle_sysc(oh); _del_initiator_dep(oh, mpu_oh); - if (oh->clkdm) + /* + * If HWMOD_CLKDM_NOAUTO is set then we don't + * deny idle the clkdm again since idle was already denied + * in _enable() + */ + if (oh->clkdm && !(oh->flags & HWMOD_CLKDM_NOAUTO)) clkdm_deny_idle(oh->clkdm); if (oh->flags & HWMOD_BLOCK_WFI) @@ -2451,15 +2391,11 @@ static int __init _init(struct omap_hwmod *oh, void *data) static void __init _setup_iclk_autoidle(struct omap_hwmod *oh) { struct omap_hwmod_ocp_if *os; - struct list_head *p; - int i = 0; + if (oh->_state != _HWMOD_STATE_INITIALIZED) return; - p = oh->slave_ports.next; - - while (i < oh->slaves_cnt) { - os = _fetch_next_ocp_if(&p, &i); + list_for_each_entry(os, &oh->slave_ports, node) { if (!os->_clk) continue; @@ -2657,7 +2593,6 @@ static int __init _register(struct omap_hwmod *oh) list_add_tail(&oh->node, &omap_hwmod_list); - INIT_LIST_HEAD(&oh->master_ports); INIT_LIST_HEAD(&oh->slave_ports); spin_lock_init(&oh->_lock); lockdep_set_class(&oh->_lock, &oh->hwmod_key); @@ -2674,50 +2609,11 @@ static int __init _register(struct omap_hwmod *oh) return 0; } -/** - * _alloc_links - return allocated memory for hwmod links - * @ml: pointer to a struct omap_hwmod_link * for the master link - * @sl: pointer to a struct omap_hwmod_link * for the slave link - * - * Return pointers to two struct omap_hwmod_link records, via the - * addresses pointed to by @ml and @sl. Will first attempt to return - * memory allocated as part of a large initial block, but if that has - * been exhausted, will allocate memory itself. Since ideally this - * second allocation path will never occur, the number of these - * 'supplemental' allocations will be logged when debugging is - * enabled. Returns 0. - */ -static int __init _alloc_links(struct omap_hwmod_link **ml, - struct omap_hwmod_link **sl) -{ - unsigned int sz; - - if ((free_ls + LINKS_PER_OCP_IF) <= max_ls) { - *ml = &linkspace[free_ls++]; - *sl = &linkspace[free_ls++]; - return 0; - } - - sz = sizeof(struct omap_hwmod_link) * LINKS_PER_OCP_IF; - - *sl = NULL; - *ml = memblock_virt_alloc(sz, 0); - - *sl = (void *)(*ml) + sizeof(struct omap_hwmod_link); - - ls_supp++; - pr_debug("omap_hwmod: supplemental link allocations needed: %d\n", - ls_supp * LINKS_PER_OCP_IF); - - return 0; -}; - /** * _add_link - add an interconnect between two IP blocks * @oi: pointer to a struct omap_hwmod_ocp_if record * - * Add struct omap_hwmod_link records connecting the master IP block - * specified in @oi->master to @oi, and connecting the slave IP block + * Add struct omap_hwmod_link records connecting the slave IP block * specified in @oi->slave to @oi. This code is assumed to run before * preemption or SMP has been enabled, thus avoiding the need for * locking in this code. Changes to this assumption will require @@ -2725,19 +2621,10 @@ static int __init _alloc_links(struct omap_hwmod_link **ml, */ static int __init _add_link(struct omap_hwmod_ocp_if *oi) { - struct omap_hwmod_link *ml, *sl; - pr_debug("omap_hwmod: %s -> %s: adding link\n", oi->master->name, oi->slave->name); - _alloc_links(&ml, &sl); - - ml->ocp_if = oi; - list_add(&ml->node, &oi->master->master_ports); - oi->master->masters_cnt++; - - sl->ocp_if = oi; - list_add(&sl->node, &oi->slave->slave_ports); + list_add(&oi->node, &oi->slave->slave_ports); oi->slave->slaves_cnt++; return 0; @@ -2784,45 +2671,6 @@ static int __init _register_link(struct omap_hwmod_ocp_if *oi) return 0; } -/** - * _alloc_linkspace - allocate large block of hwmod links - * @ois: pointer to an array of struct omap_hwmod_ocp_if records to count - * - * Allocate a large block of struct omap_hwmod_link records. This - * improves boot time significantly by avoiding the need to allocate - * individual records one by one. If the number of records to - * allocate in the block hasn't been manually specified, this function - * will count the number of struct omap_hwmod_ocp_if records in @ois - * and use that to determine the allocation size. For SoC families - * that require multiple list registrations, such as OMAP3xxx, this - * estimation process isn't optimal, so manual estimation is advised - * in those cases. Returns -EEXIST if the allocation has already occurred - * or 0 upon success. - */ -static int __init _alloc_linkspace(struct omap_hwmod_ocp_if **ois) -{ - unsigned int i = 0; - unsigned int sz; - - if (linkspace) { - WARN(1, "linkspace already allocated\n"); - return -EEXIST; - } - - if (max_ls == 0) - while (ois[i++]) - max_ls += LINKS_PER_OCP_IF; - - sz = sizeof(struct omap_hwmod_link) * max_ls; - - pr_debug("omap_hwmod: %s: allocating %d byte linkspace (%d links)\n", - __func__, sz, max_ls); - - linkspace = memblock_virt_alloc(sz, 0); - - return 0; -} - /* Static functions intended only for use in soc_ops field function pointers */ /** @@ -3180,13 +3028,6 @@ int __init omap_hwmod_register_links(struct omap_hwmod_ocp_if **ois) if (ois[0] == NULL) /* Empty list */ return 0; - if (!linkspace) { - if (_alloc_linkspace(ois)) { - pr_err("omap_hwmod: could not allocate link space\n"); - return -ENOMEM; - } - } - i = 0; do { r = _register_link(ois[i]); @@ -3398,14 +3239,10 @@ int omap_hwmod_count_resources(struct omap_hwmod *oh, unsigned long flags) ret += _count_sdma_reqs(oh); if (flags & IORESOURCE_MEM) { - int i = 0; struct omap_hwmod_ocp_if *os; - struct list_head *p = oh->slave_ports.next; - while (i < oh->slaves_cnt) { - os = _fetch_next_ocp_if(&p, &i); + list_for_each_entry(os, &oh->slave_ports, node) ret += _count_ocp_if_addr_spaces(os); - } } return ret; @@ -3424,7 +3261,6 @@ int omap_hwmod_count_resources(struct omap_hwmod *oh, unsigned long flags) int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res) { struct omap_hwmod_ocp_if *os; - struct list_head *p; int i, j, mpu_irqs_cnt, sdma_reqs_cnt, addr_cnt; int r = 0; @@ -3454,11 +3290,7 @@ int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res) r++; } - p = oh->slave_ports.next; - - i = 0; - while (i < oh->slaves_cnt) { - os = _fetch_next_ocp_if(&p, &i); + list_for_each_entry(os, &oh->slave_ports, node) { addr_cnt = _count_ocp_if_addr_spaces(os); for (j = 0; j < addr_cnt; j++) { diff --git a/arch/arm/mach-omap2/omap_hwmod.h b/arch/arm/mach-omap2/omap_hwmod.h index 78904017f18c..a8f779381fd8 100644 --- a/arch/arm/mach-omap2/omap_hwmod.h +++ b/arch/arm/mach-omap2/omap_hwmod.h @@ -313,6 +313,7 @@ struct omap_hwmod_ocp_if { struct omap_hwmod_addr_space *addr; const char *clk; struct clk *_clk; + struct list_head node; union { struct omap_hwmod_omap2_firewall omap2; } fw; @@ -410,7 +411,6 @@ struct omap_hwmod_class_sysconfig { struct omap_hwmod_sysc_fields *sysc_fields; u8 srst_udelay; u8 idlemodes; - u8 clockact; }; /** @@ -531,6 +531,10 @@ struct omap_hwmod_omap4_prcm { * operate and they need to be handled at the same time as the main_clk. * HWMOD_NO_IDLE: Do not idle the hwmod at all. Useful to handle certain * IPs like CPSW on DRA7, where clocks to this module cannot be disabled. + * HWMOD_CLKDM_NOAUTO: Allows the hwmod's clockdomain to be prevented from + * entering HW_AUTO while hwmod is active. This is needed to workaround + * some modules which don't function correctly with HW_AUTO. For example, + * DCAN on DRA7x SoC needs this to workaround errata i893. */ #define HWMOD_SWSUP_SIDLE (1 << 0) #define HWMOD_SWSUP_MSTANDBY (1 << 1) @@ -548,6 +552,7 @@ struct omap_hwmod_omap4_prcm { #define HWMOD_RECONFIG_IO_CHAIN (1 << 13) #define HWMOD_OPT_CLKS_NEEDED (1 << 14) #define HWMOD_NO_IDLE (1 << 15) +#define HWMOD_CLKDM_NOAUTO (1 << 16) /* * omap_hwmod._int_flags definitions @@ -616,16 +621,6 @@ struct omap_hwmod_class { void (*unlock)(struct omap_hwmod *oh); }; -/** - * struct omap_hwmod_link - internal structure linking hwmods with ocp_ifs - * @ocp_if: OCP interface structure record pointer - * @node: list_head pointing to next struct omap_hwmod_link in a list - */ -struct omap_hwmod_link { - struct omap_hwmod_ocp_if *ocp_if; - struct list_head node; -}; - /** * struct omap_hwmod - integration data for OMAP hardware "modules" (IP blocks) * @name: name of the hwmod @@ -686,9 +681,8 @@ struct omap_hwmod { const char *main_clk; struct clk *_clk; struct omap_hwmod_opt_clk *opt_clks; - char *clkdm_name; + const char *clkdm_name; struct clockdomain *clkdm; - struct list_head master_ports; /* connect to *_IA */ struct list_head slave_ports; /* connect to *_TA */ void *dev_attr; u32 _sysc_cache; @@ -698,12 +692,11 @@ struct omap_hwmod { struct list_head node; struct omap_hwmod_ocp_if *_mpu_port; unsigned int (*xlate_irq)(unsigned int); - u16 flags; + u32 flags; u8 mpu_rt_idx; u8 response_lat; u8 rst_lines_cnt; u8 opt_clks_cnt; - u8 masters_cnt; u8 slaves_cnt; u8 hwmods_cnt; u8 _int_flags; diff --git a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c index e047033caa3e..d190f1ad97b7 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c @@ -55,7 +55,6 @@ static struct omap_hwmod_class_sysconfig omap2xxx_timer_sysc = { SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS), .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), - .clockact = CLOCKACT_TEST_ICLK, .sysc_fields = &omap_hwmod_sysc_type1, }; diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index 1435fee39a89..1c6ca4d5fa2d 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -149,7 +149,6 @@ static struct omap_hwmod_class_sysconfig omap3xxx_timer_sysc = { SYSC_HAS_EMUFREE | SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS), .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), - .clockact = CLOCKACT_TEST_ICLK, .sysc_fields = &omap_hwmod_sysc_type1, }; @@ -424,7 +423,6 @@ static struct omap_hwmod_class_sysconfig i2c_sysc = { SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS), .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), - .clockact = CLOCKACT_TEST_ICLK, .sysc_fields = &omap_hwmod_sysc_type1, }; @@ -1045,7 +1043,6 @@ static struct omap_hwmod_class_sysconfig omap3xxx_mcbsp_sysc = { SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET), .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), .sysc_fields = &omap_hwmod_sysc_type1, - .clockact = 0x2, }; static struct omap_hwmod_class omap3xxx_mcbsp_hwmod_class = { @@ -1210,7 +1207,6 @@ static struct omap_hwmod_sysc_fields omap34xx_sr_sysc_fields = { static struct omap_hwmod_class_sysconfig omap34xx_sr_sysc = { .sysc_offs = 0x24, .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_NO_CACHE), - .clockact = CLOCKACT_TEST_ICLK, .sysc_fields = &omap34xx_sr_sysc_fields, }; diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index dad871a4cd96..94f09c720f29 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -1320,7 +1320,6 @@ static struct omap_hwmod_class_sysconfig omap44xx_i2c_sysc = { SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | SIDLE_SMART_WKUP), - .clockact = CLOCKACT_TEST_ICLK, .sysc_fields = &omap_hwmod_sysc_type1, }; @@ -2548,7 +2547,6 @@ static struct omap_hwmod_class_sysconfig omap44xx_timer_1ms_sysc = { SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), - .clockact = CLOCKACT_TEST_ICLK, .sysc_fields = &omap_hwmod_sysc_type1, }; diff --git a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c index a2d763a4cc57..9a67f013ebad 100644 --- a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c @@ -839,7 +839,6 @@ static struct omap_hwmod_class_sysconfig omap54xx_i2c_sysc = { SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | SIDLE_SMART_WKUP), - .clockact = CLOCKACT_TEST_ICLK, .sysc_fields = &omap_hwmod_sysc_type1, }; @@ -1530,7 +1529,6 @@ static struct omap_hwmod_class_sysconfig omap54xx_timer_1ms_sysc = { .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | SIDLE_SMART_WKUP), .sysc_fields = &omap_hwmod_sysc_type2, - .clockact = CLOCKACT_TEST_ICLK, }; static struct omap_hwmod_class omap54xx_timer_1ms_hwmod_class = { diff --git a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c index d0585293a381..b3abb8d8b2f6 100644 --- a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c @@ -359,6 +359,7 @@ static struct omap_hwmod dra7xx_dcan1_hwmod = { .class = &dra7xx_dcan_hwmod_class, .clkdm_name = "wkupaon_clkdm", .main_clk = "dcan1_sys_clk_mux", + .flags = HWMOD_CLKDM_NOAUTO, .prcm = { .omap4 = { .clkctrl_offs = DRA7XX_CM_WKUPAON_DCAN1_CLKCTRL_OFFSET, @@ -374,6 +375,7 @@ static struct omap_hwmod dra7xx_dcan2_hwmod = { .class = &dra7xx_dcan_hwmod_class, .clkdm_name = "l4per2_clkdm", .main_clk = "sys_clkin1", + .flags = HWMOD_CLKDM_NOAUTO, .prcm = { .omap4 = { .clkctrl_offs = DRA7XX_CM_L4PER2_DCAN2_CLKCTRL_OFFSET, @@ -1098,7 +1100,6 @@ static struct omap_hwmod_class_sysconfig dra7xx_i2c_sysc = { SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | SIDLE_SMART_WKUP), - .clockact = CLOCKACT_TEST_ICLK, .sysc_fields = &omap_hwmod_sysc_type1, }; @@ -2700,6 +2701,7 @@ static struct omap_hwmod dra7xx_usb_otg_ss1_hwmod = { .class = &dra7xx_usb_otg_ss_hwmod_class, .clkdm_name = "l3init_clkdm", .main_clk = "dpll_core_h13x2_ck", + .flags = HWMOD_CLKDM_NOAUTO, .prcm = { .omap4 = { .clkctrl_offs = DRA7XX_CM_L3INIT_USB_OTG_SS1_CLKCTRL_OFFSET, @@ -2721,6 +2723,7 @@ static struct omap_hwmod dra7xx_usb_otg_ss2_hwmod = { .class = &dra7xx_usb_otg_ss_hwmod_class, .clkdm_name = "l3init_clkdm", .main_clk = "dpll_core_h13x2_ck", + .flags = HWMOD_CLKDM_NOAUTO, .prcm = { .omap4 = { .clkctrl_offs = DRA7XX_CM_L3INIT_USB_OTG_SS2_CLKCTRL_OFFSET, diff --git a/arch/arm/mach-omap2/omap_hwmod_81xx_data.c b/arch/arm/mach-omap2/omap_hwmod_81xx_data.c index b82b77cff24c..310afe474ec4 100644 --- a/arch/arm/mach-omap2/omap_hwmod_81xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_81xx_data.c @@ -106,6 +106,7 @@ */ #define DM81XX_CM_DEFAULT_OFFSET 0x500 #define DM81XX_CM_DEFAULT_USB_CLKCTRL (0x558 - DM81XX_CM_DEFAULT_OFFSET) +#define DM81XX_CM_DEFAULT_SATA_CLKCTRL (0x560 - DM81XX_CM_DEFAULT_OFFSET) /* L3 Interconnect entries clocked at 125, 250 and 500MHz */ static struct omap_hwmod dm81xx_alwon_l3_slow_hwmod = { @@ -973,6 +974,38 @@ static struct omap_hwmod_ocp_if dm816x_l4_hs__emac1 = { .user = OCP_USER_MPU, }; +static struct omap_hwmod_class_sysconfig dm81xx_sata_sysc = { + .sysc_offs = 0x1100, + .sysc_flags = SYSC_HAS_SIDLEMODE, + .idlemodes = SIDLE_FORCE, + .sysc_fields = &omap_hwmod_sysc_type3, +}; + +static struct omap_hwmod_class dm81xx_sata_hwmod_class = { + .name = "sata", + .sysc = &dm81xx_sata_sysc, +}; + +static struct omap_hwmod dm81xx_sata_hwmod = { + .name = "sata", + .clkdm_name = "default_sata_clkdm", + .flags = HWMOD_NO_IDLEST, + .prcm = { + .omap4 = { + .clkctrl_offs = DM81XX_CM_DEFAULT_SATA_CLKCTRL, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .class = &dm81xx_sata_hwmod_class, +}; + +static struct omap_hwmod_ocp_if dm81xx_l4_hs__sata = { + .master = &dm81xx_l4_hs_hwmod, + .slave = &dm81xx_sata_hwmod, + .clk = "sysclk5_ck", + .user = OCP_USER_MPU, +}; + static struct omap_hwmod_class_sysconfig dm81xx_mmc_sysc = { .rev_offs = 0x0, .sysc_offs = 0x110, @@ -1474,6 +1507,7 @@ static struct omap_hwmod_ocp_if *dm816x_hwmod_ocp_ifs[] __initdata = { &dm81xx_l4_hs__emac0, &dm81xx_emac0__mdio, &dm816x_l4_hs__emac1, + &dm81xx_l4_hs__sata, &dm81xx_alwon_l3_fast__tpcc, &dm81xx_alwon_l3_fast__tptc0, &dm81xx_alwon_l3_fast__tptc1, diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c index 0598630c1778..63027e60cc20 100644 --- a/arch/arm/mach-omap2/pm.c +++ b/arch/arm/mach-omap2/pm.c @@ -163,7 +163,6 @@ static int omap_pm_enter(suspend_state_t suspend_state) return -ENOENT; /* XXX doublecheck */ switch (suspend_state) { - case PM_SUSPEND_STANDBY: case PM_SUSPEND_MEM: ret = omap_pm_suspend(); break; diff --git a/arch/arm/mach-stm32/Kconfig b/arch/arm/mach-stm32/Kconfig new file mode 100644 index 000000000000..2d1419eb0896 --- /dev/null +++ b/arch/arm/mach-stm32/Kconfig @@ -0,0 +1,26 @@ +config ARCH_STM32 + bool "STMicrolectronics STM32" + depends on ARM_SINGLE_ARMV7M + select ARCH_HAS_RESET_CONTROLLER + select ARMV7M_SYSTICK + select CLKSRC_STM32 + select PINCTRL + select RESET_CONTROLLER + select STM32_EXTI + help + Support for STMicroelectronics STM32 processors. + +config MACH_STM32F429 + bool "STMicrolectronics STM32F429" + depends on ARCH_STM32 + default y + +config MACH_STM32F746 + bool "STMicrolectronics STM32F746" + depends on ARCH_STM32 + default y + +config MACH_STM32H743 + bool "STMicrolectronics STM32H743" + depends on ARCH_STM32 + default y diff --git a/arch/arm/mach-stm32/board-dt.c b/arch/arm/mach-stm32/board-dt.c index c354222a4158..e918686e4191 100644 --- a/arch/arm/mach-stm32/board-dt.c +++ b/arch/arm/mach-stm32/board-dt.c @@ -12,6 +12,7 @@ static const char *const stm32_compat[] __initconst = { "st,stm32f429", "st,stm32f469", "st,stm32f746", + "st,stm32h743", NULL }; diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig index b9863f9a35fa..58153cdf025b 100644 --- a/arch/arm/mach-sunxi/Kconfig +++ b/arch/arm/mach-sunxi/Kconfig @@ -6,6 +6,7 @@ menuconfig ARCH_SUNXI select GENERIC_IRQ_CHIP select GPIOLIB select PINCTRL + select PM_OPP select SUN4I_TIMER select RESET_CONTROLLER diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig index f09023f7ab11..45e5b13a3c02 100644 --- a/drivers/soc/Kconfig +++ b/drivers/soc/Kconfig @@ -1,5 +1,6 @@ menu "SOC (System On Chip) specific Drivers" +source "drivers/soc/atmel/Kconfig" source "drivers/soc/bcm/Kconfig" source "drivers/soc/fsl/Kconfig" source "drivers/soc/mediatek/Kconfig" diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile index 05eae52a30b4..3467de7d3890 100644 --- a/drivers/soc/Makefile +++ b/drivers/soc/Makefile @@ -2,6 +2,7 @@ # Makefile for the Linux Kernel SOC specific device drivers. # +obj-$(CONFIG_ARCH_AT91) += atmel/ obj-y += bcm/ obj-$(CONFIG_ARCH_DOVE) += dove/ obj-$(CONFIG_MACH_DOVE) += dove/ diff --git a/drivers/soc/atmel/Kconfig b/drivers/soc/atmel/Kconfig new file mode 100644 index 000000000000..6242ebb41abb --- /dev/null +++ b/drivers/soc/atmel/Kconfig @@ -0,0 +1,6 @@ +config AT91_SOC_ID + bool "SoC bus for Atmel ARM SoCs" + depends on ARCH_AT91 || COMPILE_TEST + default ARCH_AT91 + help + Include support for the SoC bus on the Atmel ARM SoCs. diff --git a/drivers/soc/atmel/Makefile b/drivers/soc/atmel/Makefile new file mode 100644 index 000000000000..2d92f32e4ea5 --- /dev/null +++ b/drivers/soc/atmel/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_AT91_SOC_ID) += soc.o diff --git a/drivers/soc/atmel/soc.c b/drivers/soc/atmel/soc.c new file mode 100644 index 000000000000..4790094b498e --- /dev/null +++ b/drivers/soc/atmel/soc.c @@ -0,0 +1,231 @@ +/* + * Copyright (C) 2015 Atmel + * + * Alexandre Belloni +#include +#include +#include +#include +#include + +#include "soc.h" + +#define AT91_DBGU_CIDR 0x40 +#define AT91_DBGU_EXID 0x44 +#define AT91_CHIPID_CIDR 0x00 +#define AT91_CHIPID_EXID 0x04 +#define AT91_CIDR_VERSION(x) ((x) & 0x1f) +#define AT91_CIDR_EXT BIT(31) +#define AT91_CIDR_MATCH_MASK 0x7fffffe0 + +static const struct at91_soc __initconst socs[] = { +#ifdef CONFIG_SOC_AT91RM9200 + AT91_SOC(AT91RM9200_CIDR_MATCH, 0, "at91rm9200 BGA", "at91rm9200"), +#endif +#ifdef CONFIG_SOC_AT91SAM9 + AT91_SOC(AT91SAM9260_CIDR_MATCH, 0, "at91sam9260", NULL), + AT91_SOC(AT91SAM9261_CIDR_MATCH, 0, "at91sam9261", NULL), + AT91_SOC(AT91SAM9263_CIDR_MATCH, 0, "at91sam9263", NULL), + AT91_SOC(AT91SAM9G20_CIDR_MATCH, 0, "at91sam9g20", NULL), + AT91_SOC(AT91SAM9RL64_CIDR_MATCH, 0, "at91sam9rl64", NULL), + AT91_SOC(AT91SAM9G45_CIDR_MATCH, AT91SAM9M11_EXID_MATCH, + "at91sam9m11", "at91sam9g45"), + AT91_SOC(AT91SAM9G45_CIDR_MATCH, AT91SAM9M10_EXID_MATCH, + "at91sam9m10", "at91sam9g45"), + AT91_SOC(AT91SAM9G45_CIDR_MATCH, AT91SAM9G46_EXID_MATCH, + "at91sam9g46", "at91sam9g45"), + AT91_SOC(AT91SAM9G45_CIDR_MATCH, AT91SAM9G45_EXID_MATCH, + "at91sam9g45", "at91sam9g45"), + AT91_SOC(AT91SAM9X5_CIDR_MATCH, AT91SAM9G15_EXID_MATCH, + "at91sam9g15", "at91sam9x5"), + AT91_SOC(AT91SAM9X5_CIDR_MATCH, AT91SAM9G35_EXID_MATCH, + "at91sam9g35", "at91sam9x5"), + AT91_SOC(AT91SAM9X5_CIDR_MATCH, AT91SAM9X35_EXID_MATCH, + "at91sam9x35", "at91sam9x5"), + AT91_SOC(AT91SAM9X5_CIDR_MATCH, AT91SAM9G25_EXID_MATCH, + "at91sam9g25", "at91sam9x5"), + AT91_SOC(AT91SAM9X5_CIDR_MATCH, AT91SAM9X25_EXID_MATCH, + "at91sam9x25", "at91sam9x5"), + AT91_SOC(AT91SAM9N12_CIDR_MATCH, AT91SAM9CN12_EXID_MATCH, + "at91sam9cn12", "at91sam9n12"), + AT91_SOC(AT91SAM9N12_CIDR_MATCH, AT91SAM9N12_EXID_MATCH, + "at91sam9n12", "at91sam9n12"), + AT91_SOC(AT91SAM9N12_CIDR_MATCH, AT91SAM9CN11_EXID_MATCH, + "at91sam9cn11", "at91sam9n12"), + AT91_SOC(AT91SAM9XE128_CIDR_MATCH, 0, "at91sam9xe128", "at91sam9xe128"), + AT91_SOC(AT91SAM9XE256_CIDR_MATCH, 0, "at91sam9xe256", "at91sam9xe256"), + AT91_SOC(AT91SAM9XE512_CIDR_MATCH, 0, "at91sam9xe512", "at91sam9xe512"), +#endif +#ifdef CONFIG_SOC_SAMA5 + AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D21CU_EXID_MATCH, + "sama5d21", "sama5d2"), + AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D22CU_EXID_MATCH, + "sama5d22", "sama5d2"), + AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D23CU_EXID_MATCH, + "sama5d23", "sama5d2"), + AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D24CX_EXID_MATCH, + "sama5d24", "sama5d2"), + AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D24CU_EXID_MATCH, + "sama5d24", "sama5d2"), + AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D26CU_EXID_MATCH, + "sama5d26", "sama5d2"), + AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D27CU_EXID_MATCH, + "sama5d27", "sama5d2"), + AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D27CN_EXID_MATCH, + "sama5d27", "sama5d2"), + AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D28CU_EXID_MATCH, + "sama5d28", "sama5d2"), + AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D28CN_EXID_MATCH, + "sama5d28", "sama5d2"), + AT91_SOC(SAMA5D3_CIDR_MATCH, SAMA5D31_EXID_MATCH, + "sama5d31", "sama5d3"), + AT91_SOC(SAMA5D3_CIDR_MATCH, SAMA5D33_EXID_MATCH, + "sama5d33", "sama5d3"), + AT91_SOC(SAMA5D3_CIDR_MATCH, SAMA5D34_EXID_MATCH, + "sama5d34", "sama5d3"), + AT91_SOC(SAMA5D3_CIDR_MATCH, SAMA5D35_EXID_MATCH, + "sama5d35", "sama5d3"), + AT91_SOC(SAMA5D3_CIDR_MATCH, SAMA5D36_EXID_MATCH, + "sama5d36", "sama5d3"), + AT91_SOC(SAMA5D4_CIDR_MATCH, SAMA5D41_EXID_MATCH, + "sama5d41", "sama5d4"), + AT91_SOC(SAMA5D4_CIDR_MATCH, SAMA5D42_EXID_MATCH, + "sama5d42", "sama5d4"), + AT91_SOC(SAMA5D4_CIDR_MATCH, SAMA5D43_EXID_MATCH, + "sama5d43", "sama5d4"), + AT91_SOC(SAMA5D4_CIDR_MATCH, SAMA5D44_EXID_MATCH, + "sama5d44", "sama5d4"), +#endif + { /* sentinel */ }, +}; + +static int __init at91_get_cidr_exid_from_dbgu(u32 *cidr, u32 *exid) +{ + struct device_node *np; + void __iomem *regs; + + np = of_find_compatible_node(NULL, NULL, "atmel,at91rm9200-dbgu"); + if (!np) + np = of_find_compatible_node(NULL, NULL, + "atmel,at91sam9260-dbgu"); + if (!np) + return -ENODEV; + + regs = of_iomap(np, 0); + of_node_put(np); + + if (!regs) { + pr_warn("Could not map DBGU iomem range"); + return -ENXIO; + } + + *cidr = readl(regs + AT91_DBGU_CIDR); + *exid = readl(regs + AT91_DBGU_EXID); + + iounmap(regs); + + return 0; +} + +static int __init at91_get_cidr_exid_from_chipid(u32 *cidr, u32 *exid) +{ + struct device_node *np; + void __iomem *regs; + + np = of_find_compatible_node(NULL, NULL, "atmel,sama5d2-chipid"); + if (!np) + return -ENODEV; + + regs = of_iomap(np, 0); + of_node_put(np); + + if (!regs) { + pr_warn("Could not map DBGU iomem range"); + return -ENXIO; + } + + *cidr = readl(regs + AT91_CHIPID_CIDR); + *exid = readl(regs + AT91_CHIPID_EXID); + + iounmap(regs); + + return 0; +} + +struct soc_device * __init at91_soc_init(const struct at91_soc *socs) +{ + struct soc_device_attribute *soc_dev_attr; + const struct at91_soc *soc; + struct soc_device *soc_dev; + u32 cidr, exid; + int ret; + + /* + * With SAMA5D2 and later SoCs, CIDR and EXID registers are no more + * in the dbgu device but in the chipid device whose purpose is only + * to expose these two registers. + */ + ret = at91_get_cidr_exid_from_dbgu(&cidr, &exid); + if (ret) + ret = at91_get_cidr_exid_from_chipid(&cidr, &exid); + if (ret) { + if (ret == -ENODEV) + pr_warn("Could not find identification node"); + return NULL; + } + + for (soc = socs; soc->name; soc++) { + if (soc->cidr_match != (cidr & AT91_CIDR_MATCH_MASK)) + continue; + + if (!(cidr & AT91_CIDR_EXT) || soc->exid_match == exid) + break; + } + + if (!soc->name) { + pr_warn("Could not find matching SoC description\n"); + return NULL; + } + + soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); + if (!soc_dev_attr) + return NULL; + + soc_dev_attr->family = soc->family; + soc_dev_attr->soc_id = soc->name; + soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%X", + AT91_CIDR_VERSION(cidr)); + soc_dev = soc_device_register(soc_dev_attr); + if (IS_ERR(soc_dev)) { + kfree(soc_dev_attr->revision); + kfree(soc_dev_attr); + pr_warn("Could not register SoC device\n"); + return NULL; + } + + if (soc->family) + pr_info("Detected SoC family: %s\n", soc->family); + pr_info("Detected SoC: %s, revision %X\n", soc->name, + AT91_CIDR_VERSION(cidr)); + + return soc_dev; +} + +static int __init atmel_soc_device_init(void) +{ + at91_soc_init(socs); + + return 0; +} +subsys_initcall(atmel_soc_device_init); diff --git a/arch/arm/mach-at91/soc.h b/drivers/soc/atmel/soc.h similarity index 100% rename from arch/arm/mach-at91/soc.h rename to drivers/soc/atmel/soc.h