summaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-at91
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-at91')
-rw-r--r--arch/arm/mach-at91/Kconfig49
-rw-r--r--arch/arm/mach-at91/Kconfig.non_dt18
-rw-r--r--arch/arm/mach-at91/Makefile9
-rw-r--r--arch/arm/mach-at91/at91_rstc.h53
-rw-r--r--arch/arm/mach-at91/at91_shdwc.h50
-rw-r--r--arch/arm/mach-at91/at91sam9260.c51
-rw-r--r--arch/arm/mach-at91/at91sam9261.c51
-rw-r--r--arch/arm/mach-at91/at91sam9263.c51
-rw-r--r--arch/arm/mach-at91/at91sam926x_time.c294
-rw-r--r--arch/arm/mach-at91/at91sam9_alt_reset.S40
-rw-r--r--arch/arm/mach-at91/at91sam9g45.c55
-rw-r--r--arch/arm/mach-at91/at91sam9g45_reset.S45
-rw-r--r--arch/arm/mach-at91/at91sam9rl.c51
-rw-r--r--arch/arm/mach-at91/board-afeb-9260v1.c4
-rw-r--r--arch/arm/mach-at91/board-cam60.c4
-rw-r--r--arch/arm/mach-at91/board-cpu9krea.c4
-rw-r--r--arch/arm/mach-at91/board-dt-rm9200.c13
-rw-r--r--arch/arm/mach-at91/board-dt-sam9.c23
-rw-r--r--arch/arm/mach-at91/board-dt-sama5.c60
-rw-r--r--arch/arm/mach-at91/board-flexibity.c4
-rw-r--r--arch/arm/mach-at91/board-foxg20.c272
-rw-r--r--arch/arm/mach-at91/board-gsia18s.c2
-rw-r--r--arch/arm/mach-at91/board-pcontrol-g20.c2
-rw-r--r--arch/arm/mach-at91/board-rsi-ews.c232
-rw-r--r--arch/arm/mach-at91/board-sam9-l9260.c4
-rw-r--r--arch/arm/mach-at91/board-sam9260ek.c5
-rw-r--r--arch/arm/mach-at91/board-sam9261ek.c7
-rw-r--r--arch/arm/mach-at91/board-sam9263ek.c5
-rw-r--r--arch/arm/mach-at91/board-sam9g20ek.c4
-rw-r--r--arch/arm/mach-at91/board-sam9m10g45ek.c5
-rw-r--r--arch/arm/mach-at91/board-sam9rlek.c5
-rw-r--r--arch/arm/mach-at91/board-snapper9260.c4
-rw-r--r--arch/arm/mach-at91/board-stamp9g20.c4
-rw-r--r--arch/arm/mach-at91/clock.c1
-rw-r--r--arch/arm/mach-at91/generic.h19
-rw-r--r--arch/arm/mach-at91/include/mach/at91_pio.h6
-rw-r--r--arch/arm/mach-at91/include/mach/cpu.h22
-rw-r--r--arch/arm/mach-at91/include/mach/debug-macro.S5
-rw-r--r--arch/arm/mach-at91/include/mach/hardware.h23
-rw-r--r--arch/arm/mach-at91/include/mach/sama5d4.h33
-rw-r--r--arch/arm/mach-at91/include/mach/uncompress.h21
-rw-r--r--arch/arm/mach-at91/irq.c270
-rw-r--r--arch/arm/mach-at91/pm.c104
-rw-r--r--arch/arm/mach-at91/sama5d4.c64
-rw-r--r--arch/arm/mach-at91/setup.c273
-rw-r--r--arch/arm/mach-at91/soc.h7
46 files changed, 671 insertions, 1657 deletions
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 6cc6f7aebdae..0e6d548b70d9 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -12,6 +12,9 @@ config HAVE_AT91_DBGU0
config HAVE_AT91_DBGU1
bool
+config HAVE_AT91_DBGU2
+ bool
+
config AT91_USE_OLD_CLK
bool
@@ -28,36 +31,33 @@ config OLD_CLK_AT91
bool
default AT91_PMC_UNIT && AT91_USE_OLD_CLK
-config AT91_SAM9_ALT_RESET
+config OLD_IRQ_AT91
bool
- default !ARCH_AT91X40
-
-config AT91_SAM9G45_RESET
- bool
- default !ARCH_AT91X40
+ select MULTI_IRQ_HANDLER
+ select SPARSE_IRQ
-config AT91_SAM9_TIME
+config HAVE_AT91_SMD
bool
-config HAVE_AT91_SMD
+config HAVE_AT91_H32MX
bool
config SOC_AT91SAM9
bool
- select AT91_SAM9_TIME
+ select ATMEL_AIC_IRQ if !OLD_IRQ_AT91
select CPU_ARM926T
select GENERIC_CLOCKEVENTS
- select MULTI_IRQ_HANDLER
- select SPARSE_IRQ
+ select MEMORY if USE_OF
+ select ATMEL_SDRAMC if USE_OF
config SOC_SAMA5
bool
- select AT91_SAM9_TIME
+ select ATMEL_AIC5_IRQ
select CPU_V7
select GENERIC_CLOCKEVENTS
- select MULTI_IRQ_HANDLER
- select SPARSE_IRQ
select USE_OF
+ select MEMORY
+ select ATMEL_SDRAMC
menu "Atmel AT91 System-on-Chip"
@@ -70,8 +70,7 @@ config ARCH_AT91X40
depends on !MMU
select CPU_ARM7TDMI
select ARCH_USES_GETTIMEOFFSET
- select MULTI_IRQ_HANDLER
- select SPARSE_IRQ
+ select OLD_IRQ_AT91
help
Select this if you are using one of Atmel's AT91X40 SoC.
@@ -103,16 +102,30 @@ config SOC_SAMA5D3
help
Select this if you are using one of Atmel's SAMA5D3 family SoC.
This support covers SAMA5D31, SAMA5D33, SAMA5D34, SAMA5D35, SAMA5D36.
+
+config SOC_SAMA5D4
+ bool "SAMA5D4 family"
+ select SOC_SAMA5
+ select HAVE_AT91_DBGU2
+ select CLKSRC_MMIO
+ select CACHE_L2X0
+ select CACHE_PL310
+ select HAVE_FB_ATMEL
+ select HAVE_AT91_UTMI
+ select HAVE_AT91_SMD
+ select HAVE_AT91_USB_CLK
+ select HAVE_AT91_H32MX
+ help
+ Select this if you are using one of Atmel's SAMA5D4 family SoC.
endif
if SOC_SAM_V4_V5
config SOC_AT91RM9200
bool "AT91RM9200"
+ select ATMEL_AIC_IRQ if !OLD_IRQ_AT91
select CPU_ARM920T
select GENERIC_CLOCKEVENTS
select HAVE_AT91_DBGU0
- select MULTI_IRQ_HANDLER
- select SPARSE_IRQ
select HAVE_AT91_USB_CLK
config SOC_AT91SAM9260
diff --git a/arch/arm/mach-at91/Kconfig.non_dt b/arch/arm/mach-at91/Kconfig.non_dt
index 44ace320d2e1..d8e88219edb4 100644
--- a/arch/arm/mach-at91/Kconfig.non_dt
+++ b/arch/arm/mach-at91/Kconfig.non_dt
@@ -14,31 +14,37 @@ config ARCH_AT91RM9200
bool "AT91RM9200"
select SOC_AT91RM9200
select AT91_USE_OLD_CLK
+ select OLD_IRQ_AT91
config ARCH_AT91SAM9260
bool "AT91SAM9260 or AT91SAM9XE or AT91SAM9G20"
select SOC_AT91SAM9260
select AT91_USE_OLD_CLK
+ select OLD_IRQ_AT91
config ARCH_AT91SAM9261
bool "AT91SAM9261 or AT91SAM9G10"
select SOC_AT91SAM9261
select AT91_USE_OLD_CLK
+ select OLD_IRQ_AT91
config ARCH_AT91SAM9263
bool "AT91SAM9263"
select SOC_AT91SAM9263
select AT91_USE_OLD_CLK
+ select OLD_IRQ_AT91
config ARCH_AT91SAM9RL
bool "AT91SAM9RL"
select SOC_AT91SAM9RL
select AT91_USE_OLD_CLK
+ select OLD_IRQ_AT91
config ARCH_AT91SAM9G45
bool "AT91SAM9G45"
select SOC_AT91SAM9G45
select AT91_USE_OLD_CLK
+ select OLD_IRQ_AT91
endchoice
@@ -132,12 +138,6 @@ config MACH_ECO920
bool "eco920"
help
Select this if you are using the eco920 board
-
-config MACH_RSI_EWS
- bool "RSI Embedded Webserver"
- depends on ARCH_AT91RM9200
- help
- Select this if you are using RSIs EWS board.
endif
# ----------------------------------------------------------
@@ -212,12 +212,6 @@ config MACH_CPU9G20
Select this if you are using a Eukrea Electromatique's
CPU9G20 Board <http://www.eukrea.com/>
-config MACH_ACMENETUSFOXG20
- bool "Acme Systems srl FOX Board G20"
- help
- Select this if you are using Acme Systems
- FOX Board G20 <http://www.acmesystems.it>
-
config MACH_PORTUXG20
bool "taskit PortuxG20"
help
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
index 78e9cec282f4..ac99d87ffefe 100644
--- a/arch/arm/mach-at91/Makefile
+++ b/arch/arm/mach-at91/Makefile
@@ -2,15 +2,13 @@
# Makefile for the linux kernel.
#
-obj-y := irq.o gpio.o setup.o sysirq_mask.o
+obj-y := gpio.o setup.o sysirq_mask.o
obj-m :=
obj-n :=
obj- :=
+obj-$(CONFIG_OLD_IRQ_AT91) += irq.o
obj-$(CONFIG_OLD_CLK_AT91) += clock.o
-obj-$(CONFIG_AT91_SAM9_ALT_RESET) += at91sam9_alt_reset.o
-obj-$(CONFIG_AT91_SAM9G45_RESET) += at91sam9g45_reset.o
-obj-$(CONFIG_AT91_SAM9_TIME) += at91sam926x_time.o
obj-$(CONFIG_SOC_AT91SAM9) += sam9_smc.o
# CPU-specific support
@@ -23,6 +21,7 @@ obj-$(CONFIG_SOC_AT91SAM9N12) += at91sam9n12.o
obj-$(CONFIG_SOC_AT91SAM9X5) += at91sam9x5.o
obj-$(CONFIG_SOC_AT91SAM9RL) += at91sam9rl.o
obj-$(CONFIG_SOC_SAMA5D3) += sama5d3.o
+obj-$(CONFIG_SOC_SAMA5D4) += sama5d4.o
obj-$(CONFIG_ARCH_AT91RM9200) += at91rm9200_devices.o
obj-$(CONFIG_ARCH_AT91SAM9260) += at91sam9260_devices.o
@@ -46,7 +45,6 @@ obj-$(CONFIG_MACH_ECBAT91) += board-ecbat91.o
obj-$(CONFIG_MACH_YL9200) += board-yl-9200.o
obj-$(CONFIG_MACH_CPUAT91) += board-cpuat91.o
obj-$(CONFIG_MACH_ECO920) += board-eco920.o
-obj-$(CONFIG_MACH_RSI_EWS) += board-rsi-ews.o
# AT91SAM9260 board-specific support
obj-$(CONFIG_MACH_AT91SAM9260EK) += board-sam9260ek.o
@@ -69,7 +67,6 @@ obj-$(CONFIG_MACH_AT91SAM9RLEK) += board-sam9rlek.o
# AT91SAM9G20 board-specific support
obj-$(CONFIG_MACH_AT91SAM9G20EK) += board-sam9g20ek.o
obj-$(CONFIG_MACH_CPU9G20) += board-cpu9krea.o
-obj-$(CONFIG_MACH_ACMENETUSFOXG20) += board-foxg20.o
obj-$(CONFIG_MACH_STAMP9G20) += board-stamp9g20.o
obj-$(CONFIG_MACH_PORTUXG20) += board-stamp9g20.o
obj-$(CONFIG_MACH_PCONTROL_G20) += board-pcontrol-g20.o board-stamp9g20.o
diff --git a/arch/arm/mach-at91/at91_rstc.h b/arch/arm/mach-at91/at91_rstc.h
deleted file mode 100644
index a600e6992920..000000000000
--- a/arch/arm/mach-at91/at91_rstc.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * arch/arm/mach-at91/include/mach/at91_rstc.h
- *
- * Copyright (C) 2007 Andrew Victor
- * Copyright (C) 2007 Atmel Corporation.
- *
- * Reset Controller (RSTC) - System peripherals regsters.
- * Based on AT91SAM9261 datasheet revision D.
- *
- * 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 AT91_RSTC_H
-#define AT91_RSTC_H
-
-#ifndef __ASSEMBLY__
-extern void __iomem *at91_rstc_base;
-
-#define at91_rstc_read(field) \
- __raw_readl(at91_rstc_base + field)
-
-#define at91_rstc_write(field, value) \
- __raw_writel(value, at91_rstc_base + field)
-#else
-.extern at91_rstc_base
-#endif
-
-#define AT91_RSTC_CR 0x00 /* Reset Controller Control Register */
-#define AT91_RSTC_PROCRST (1 << 0) /* Processor Reset */
-#define AT91_RSTC_PERRST (1 << 2) /* Peripheral Reset */
-#define AT91_RSTC_EXTRST (1 << 3) /* External Reset */
-#define AT91_RSTC_KEY (0xa5 << 24) /* KEY Password */
-
-#define AT91_RSTC_SR 0x04 /* Reset Controller Status Register */
-#define AT91_RSTC_URSTS (1 << 0) /* User Reset Status */
-#define AT91_RSTC_RSTTYP (7 << 8) /* Reset Type */
-#define AT91_RSTC_RSTTYP_GENERAL (0 << 8)
-#define AT91_RSTC_RSTTYP_WAKEUP (1 << 8)
-#define AT91_RSTC_RSTTYP_WATCHDOG (2 << 8)
-#define AT91_RSTC_RSTTYP_SOFTWARE (3 << 8)
-#define AT91_RSTC_RSTTYP_USER (4 << 8)
-#define AT91_RSTC_NRSTL (1 << 16) /* NRST Pin Level */
-#define AT91_RSTC_SRCMP (1 << 17) /* Software Reset Command in Progress */
-
-#define AT91_RSTC_MR 0x08 /* Reset Controller Mode Register */
-#define AT91_RSTC_URSTEN (1 << 0) /* User Reset Enable */
-#define AT91_RSTC_URSTIEN (1 << 4) /* User Reset Interrupt Enable */
-#define AT91_RSTC_ERSTL (0xf << 8) /* External Reset Length */
-
-#endif
diff --git a/arch/arm/mach-at91/at91_shdwc.h b/arch/arm/mach-at91/at91_shdwc.h
deleted file mode 100644
index 9e29f31ec9a6..000000000000
--- a/arch/arm/mach-at91/at91_shdwc.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * arch/arm/mach-at91/include/mach/at91_shdwc.h
- *
- * Copyright (C) 2007 Andrew Victor
- * Copyright (C) 2007 Atmel Corporation.
- *
- * Shutdown Controller (SHDWC) - System peripherals regsters.
- * Based on AT91SAM9261 datasheet revision D.
- *
- * 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 AT91_SHDWC_H
-#define AT91_SHDWC_H
-
-#ifndef __ASSEMBLY__
-extern void __iomem *at91_shdwc_base;
-
-#define at91_shdwc_read(field) \
- __raw_readl(at91_shdwc_base + field)
-
-#define at91_shdwc_write(field, value) \
- __raw_writel(value, at91_shdwc_base + field)
-#endif
-
-#define AT91_SHDW_CR 0x00 /* Shut Down Control Register */
-#define AT91_SHDW_SHDW (1 << 0) /* Shut Down command */
-#define AT91_SHDW_KEY (0xa5 << 24) /* KEY Password */
-
-#define AT91_SHDW_MR 0x04 /* Shut Down Mode Register */
-#define AT91_SHDW_WKMODE0 (3 << 0) /* Wake-up 0 Mode Selection */
-#define AT91_SHDW_WKMODE0_NONE 0
-#define AT91_SHDW_WKMODE0_HIGH 1
-#define AT91_SHDW_WKMODE0_LOW 2
-#define AT91_SHDW_WKMODE0_ANYLEVEL 3
-#define AT91_SHDW_CPTWK0_MAX 0xf /* Maximum Counter On Wake Up 0 */
-#define AT91_SHDW_CPTWK0 (AT91_SHDW_CPTWK0_MAX << 4) /* Counter On Wake Up 0 */
-#define AT91_SHDW_CPTWK0_(x) ((x) << 4)
-#define AT91_SHDW_RTTWKEN (1 << 16) /* Real Time Timer Wake-up Enable */
-#define AT91_SHDW_RTCWKEN (1 << 17) /* Real Time Clock Wake-up Enable */
-
-#define AT91_SHDW_SR 0x08 /* Shut Down Status Register */
-#define AT91_SHDW_WAKEUP0 (1 << 0) /* Wake-up 0 Status */
-#define AT91_SHDW_RTTWK (1 << 16) /* Real-time Timer Wake-up */
-#define AT91_SHDW_RTCWK (1 << 17) /* Real-time Clock Wake-up [SAM9RL] */
-
-#endif
diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c
index 3477ba94c4c5..aab1f969a7c3 100644
--- a/arch/arm/mach-at91/at91sam9260.c
+++ b/arch/arm/mach-at91/at91sam9260.c
@@ -11,6 +11,7 @@
*/
#include <linux/module.h>
+#include <linux/platform_device.h>
#include <linux/clk/at91_pmc.h>
#include <asm/proc-fns.h>
@@ -24,7 +25,6 @@
#include <mach/hardware.h>
#include "at91_aic.h"
-#include "at91_rstc.h"
#include "soc.h"
#include "generic.h"
#include "sam9_smc.h"
@@ -342,8 +342,6 @@ static void __init at91sam9260_map_io(void)
static void __init at91sam9260_ioremap_registers(void)
{
- at91_ioremap_shdwc(AT91SAM9260_BASE_SHDWC);
- at91_ioremap_rstc(AT91SAM9260_BASE_RSTC);
at91_ioremap_ramc(0, AT91SAM9260_BASE_SDRAMC, 512);
at91sam926x_ioremap_pit(AT91SAM9260_BASE_PIT);
at91sam9_ioremap_smc(0, AT91SAM9260_BASE_SMC);
@@ -354,7 +352,6 @@ static void __init at91sam9260_ioremap_registers(void)
static void __init at91sam9260_initialize(void)
{
arm_pm_idle = at91sam9_idle;
- arm_pm_restart = at91sam9_alt_restart;
at91_sysirq_mask_rtt(AT91SAM9260_BASE_RTT);
@@ -362,6 +359,45 @@ static void __init at91sam9260_initialize(void)
at91_gpio_init(at91sam9260_gpio, 3);
}
+static struct resource rstc_resources[] = {
+ [0] = {
+ .start = AT91SAM9260_BASE_RSTC,
+ .end = AT91SAM9260_BASE_RSTC + SZ_16 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9260_BASE_SDRAMC,
+ .end = AT91SAM9260_BASE_SDRAMC + SZ_512 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device rstc_device = {
+ .name = "at91-sam9260-reset",
+ .resource = rstc_resources,
+ .num_resources = ARRAY_SIZE(rstc_resources),
+};
+
+static struct resource shdwc_resources[] = {
+ [0] = {
+ .start = AT91SAM9260_BASE_SHDWC,
+ .end = AT91SAM9260_BASE_SHDWC + SZ_16 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device shdwc_device = {
+ .name = "at91-poweroff",
+ .resource = shdwc_resources,
+ .num_resources = ARRAY_SIZE(shdwc_resources),
+};
+
+static void __init at91sam9260_register_devices(void)
+{
+ platform_device_register(&rstc_device);
+ platform_device_register(&shdwc_device);
+}
+
/* --------------------------------------------------------------------
* Interrupt initialization
* -------------------------------------------------------------------- */
@@ -404,6 +440,11 @@ static unsigned int at91sam9260_default_irq_priority[NR_AIC_IRQS] __initdata = {
0, /* Advanced Interrupt Controller */
};
+static void __init at91sam9260_init_time(void)
+{
+ at91sam926x_pit_init(NR_IRQS_LEGACY + AT91_ID_SYS);
+}
+
AT91_SOC_START(at91sam9260)
.map_io = at91sam9260_map_io,
.default_irq_priority = at91sam9260_default_irq_priority,
@@ -411,5 +452,7 @@ AT91_SOC_START(at91sam9260)
| (1 << AT91SAM9260_ID_IRQ2),
.ioremap_registers = at91sam9260_ioremap_registers,
.register_clocks = at91sam9260_register_clocks,
+ .register_devices = at91sam9260_register_devices,
.init = at91sam9260_initialize,
+ .init_time = at91sam9260_init_time,
AT91_SOC_END
diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c
index fb164a5d04a9..a8bd35963332 100644
--- a/arch/arm/mach-at91/at91sam9261.c
+++ b/arch/arm/mach-at91/at91sam9261.c
@@ -11,6 +11,7 @@
*/
#include <linux/module.h>
+#include <linux/platform_device.h>
#include <linux/clk/at91_pmc.h>
#include <asm/proc-fns.h>
@@ -23,7 +24,6 @@
#include <mach/hardware.h>
#include "at91_aic.h"
-#include "at91_rstc.h"
#include "soc.h"
#include "generic.h"
#include "sam9_smc.h"
@@ -301,8 +301,6 @@ static void __init at91sam9261_map_io(void)
static void __init at91sam9261_ioremap_registers(void)
{
- at91_ioremap_shdwc(AT91SAM9261_BASE_SHDWC);
- at91_ioremap_rstc(AT91SAM9261_BASE_RSTC);
at91_ioremap_ramc(0, AT91SAM9261_BASE_SDRAMC, 512);
at91sam926x_ioremap_pit(AT91SAM9261_BASE_PIT);
at91sam9_ioremap_smc(0, AT91SAM9261_BASE_SMC);
@@ -313,7 +311,6 @@ static void __init at91sam9261_ioremap_registers(void)
static void __init at91sam9261_initialize(void)
{
arm_pm_idle = at91sam9_idle;
- arm_pm_restart = at91sam9_alt_restart;
at91_sysirq_mask_rtt(AT91SAM9261_BASE_RTT);
@@ -321,6 +318,45 @@ static void __init at91sam9261_initialize(void)
at91_gpio_init(at91sam9261_gpio, 3);
}
+static struct resource rstc_resources[] = {
+ [0] = {
+ .start = AT91SAM9261_BASE_RSTC,
+ .end = AT91SAM9261_BASE_RSTC + SZ_16 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9261_BASE_SDRAMC,
+ .end = AT91SAM9261_BASE_SDRAMC + SZ_512 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device rstc_device = {
+ .name = "at91-sam9260-reset",
+ .resource = rstc_resources,
+ .num_resources = ARRAY_SIZE(rstc_resources),
+};
+
+static struct resource shdwc_resources[] = {
+ [0] = {
+ .start = AT91SAM9261_BASE_SHDWC,
+ .end = AT91SAM9261_BASE_SHDWC + SZ_16 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device shdwc_device = {
+ .name = "at91-poweroff",
+ .resource = shdwc_resources,
+ .num_resources = ARRAY_SIZE(shdwc_resources),
+};
+
+static void __init at91sam9261_register_devices(void)
+{
+ platform_device_register(&rstc_device);
+ platform_device_register(&shdwc_device);
+}
+
/* --------------------------------------------------------------------
* Interrupt initialization
* -------------------------------------------------------------------- */
@@ -363,6 +399,11 @@ static unsigned int at91sam9261_default_irq_priority[NR_AIC_IRQS] __initdata = {
0, /* Advanced Interrupt Controller */
};
+static void __init at91sam9261_init_time(void)
+{
+ at91sam926x_pit_init(NR_IRQS_LEGACY + AT91_ID_SYS);
+}
+
AT91_SOC_START(at91sam9261)
.map_io = at91sam9261_map_io,
.default_irq_priority = at91sam9261_default_irq_priority,
@@ -370,5 +411,7 @@ AT91_SOC_START(at91sam9261)
| (1 << AT91SAM9261_ID_IRQ2),
.ioremap_registers = at91sam9261_ioremap_registers,
.register_clocks = at91sam9261_register_clocks,
+ .register_devices = at91sam9261_register_devices,
.init = at91sam9261_initialize,
+ .init_time = at91sam9261_init_time,
AT91_SOC_END
diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c
index 810fa5f15a51..fbff228cc63e 100644
--- a/arch/arm/mach-at91/at91sam9263.c
+++ b/arch/arm/mach-at91/at91sam9263.c
@@ -11,6 +11,7 @@
*/
#include <linux/module.h>
+#include <linux/platform_device.h>
#include <linux/clk/at91_pmc.h>
#include <asm/proc-fns.h>
@@ -22,7 +23,6 @@
#include <mach/hardware.h>
#include "at91_aic.h"
-#include "at91_rstc.h"
#include "soc.h"
#include "generic.h"
#include "sam9_smc.h"
@@ -321,8 +321,6 @@ static void __init at91sam9263_map_io(void)
static void __init at91sam9263_ioremap_registers(void)
{
- at91_ioremap_shdwc(AT91SAM9263_BASE_SHDWC);
- at91_ioremap_rstc(AT91SAM9263_BASE_RSTC);
at91_ioremap_ramc(0, AT91SAM9263_BASE_SDRAMC0, 512);
at91_ioremap_ramc(1, AT91SAM9263_BASE_SDRAMC1, 512);
at91sam926x_ioremap_pit(AT91SAM9263_BASE_PIT);
@@ -335,7 +333,6 @@ static void __init at91sam9263_ioremap_registers(void)
static void __init at91sam9263_initialize(void)
{
arm_pm_idle = at91sam9_idle;
- arm_pm_restart = at91sam9_alt_restart;
at91_sysirq_mask_rtt(AT91SAM9263_BASE_RTT0);
at91_sysirq_mask_rtt(AT91SAM9263_BASE_RTT1);
@@ -344,6 +341,45 @@ static void __init at91sam9263_initialize(void)
at91_gpio_init(at91sam9263_gpio, 5);
}
+static struct resource rstc_resources[] = {
+ [0] = {
+ .start = AT91SAM9263_BASE_RSTC,
+ .end = AT91SAM9263_BASE_RSTC + SZ_16 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9263_BASE_SDRAMC0,
+ .end = AT91SAM9263_BASE_SDRAMC0 + SZ_512 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device rstc_device = {
+ .name = "at91-sam9260-reset",
+ .resource = rstc_resources,
+ .num_resources = ARRAY_SIZE(rstc_resources),
+};
+
+static struct resource shdwc_resources[] = {
+ [0] = {
+ .start = AT91SAM9263_BASE_SHDWC,
+ .end = AT91SAM9263_BASE_SHDWC + SZ_16 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device shdwc_device = {
+ .name = "at91-poweroff",
+ .resource = shdwc_resources,
+ .num_resources = ARRAY_SIZE(shdwc_resources),
+};
+
+static void __init at91sam9263_register_devices(void)
+{
+ platform_device_register(&rstc_device);
+ platform_device_register(&shdwc_device);
+}
+
/* --------------------------------------------------------------------
* Interrupt initialization
* -------------------------------------------------------------------- */
@@ -386,11 +422,18 @@ static unsigned int at91sam9263_default_irq_priority[NR_AIC_IRQS] __initdata = {
0, /* Advanced Interrupt Controller (IRQ1) */
};
+static void __init at91sam9263_init_time(void)
+{
+ at91sam926x_pit_init(NR_IRQS_LEGACY + AT91_ID_SYS);
+}
+
AT91_SOC_START(at91sam9263)
.map_io = at91sam9263_map_io,
.default_irq_priority = at91sam9263_default_irq_priority,
.extern_irq = (1 << AT91SAM9263_ID_IRQ0) | (1 << AT91SAM9263_ID_IRQ1),
.ioremap_registers = at91sam9263_ioremap_registers,
.register_clocks = at91sam9263_register_clocks,
+ .register_devices = at91sam9263_register_devices,
.init = at91sam9263_initialize,
+ .init_time = at91sam9263_init_time,
AT91_SOC_END
diff --git a/arch/arm/mach-at91/at91sam926x_time.c b/arch/arm/mach-at91/at91sam926x_time.c
deleted file mode 100644
index 0a9e2fc8f796..000000000000
--- a/arch/arm/mach-at91/at91sam926x_time.c
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- * at91sam926x_time.c - Periodic Interval Timer (PIT) for at91sam926x
- *
- * Copyright (C) 2005-2006 M. Amine SAYA, ATMEL Rousset, France
- * Revision 2005 M. Nicolas Diremdjian, ATMEL Rousset, France
- * Converted to ClockSource/ClockEvents by David Brownell.
- *
- * 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 <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/kernel.h>
-#include <linux/clk.h>
-#include <linux/clockchips.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/of_irq.h>
-
-#include <asm/mach/time.h>
-#include <mach/hardware.h>
-
-#define AT91_PIT_MR 0x00 /* Mode Register */
-#define AT91_PIT_PITIEN (1 << 25) /* Timer Interrupt Enable */
-#define AT91_PIT_PITEN (1 << 24) /* Timer Enabled */
-#define AT91_PIT_PIV (0xfffff) /* Periodic Interval Value */
-
-#define AT91_PIT_SR 0x04 /* Status Register */
-#define AT91_PIT_PITS (1 << 0) /* Timer Status */
-
-#define AT91_PIT_PIVR 0x08 /* Periodic Interval Value Register */
-#define AT91_PIT_PIIR 0x0c /* Periodic Interval Image Register */
-#define AT91_PIT_PICNT (0xfff << 20) /* Interval Counter */
-#define AT91_PIT_CPIV (0xfffff) /* Inverval Value */
-
-#define PIT_CPIV(x) ((x) & AT91_PIT_CPIV)
-#define PIT_PICNT(x) (((x) & AT91_PIT_PICNT) >> 20)
-
-static u32 pit_cycle; /* write-once */
-static u32 pit_cnt; /* access only w/system irq blocked */
-static void __iomem *pit_base_addr __read_mostly;
-static struct clk *mck;
-
-static inline unsigned int pit_read(unsigned int reg_offset)
-{
- return __raw_readl(pit_base_addr + reg_offset);
-}
-
-static inline void pit_write(unsigned int reg_offset, unsigned long value)
-{
- __raw_writel(value, pit_base_addr + reg_offset);
-}
-
-/*
- * Clocksource: just a monotonic counter of MCK/16 cycles.
- * We don't care whether or not PIT irqs are enabled.
- */
-static cycle_t read_pit_clk(struct clocksource *cs)
-{
- unsigned long flags;
- u32 elapsed;
- u32 t;
-
- raw_local_irq_save(flags);
- elapsed = pit_cnt;
- t = pit_read(AT91_PIT_PIIR);
- raw_local_irq_restore(flags);
-
- elapsed += PIT_PICNT(t) * pit_cycle;
- elapsed += PIT_CPIV(t);
- return elapsed;
-}
-
-static struct clocksource pit_clk = {
- .name = "pit",
- .rating = 175,
- .read = read_pit_clk,
- .flags = CLOCK_SOURCE_IS_CONTINUOUS,
-};
-
-
-/*
- * Clockevent device: interrupts every 1/HZ (== pit_cycles * MCK/16)
- */
-static void
-pit_clkevt_mode(enum clock_event_mode mode, struct clock_event_device *dev)
-{
- switch (mode) {
- case CLOCK_EVT_MODE_PERIODIC:
- /* update clocksource counter */
- pit_cnt += pit_cycle * PIT_PICNT(pit_read(AT91_PIT_PIVR));
- pit_write(AT91_PIT_MR, (pit_cycle - 1) | AT91_PIT_PITEN
- | AT91_PIT_PITIEN);
- break;
- case CLOCK_EVT_MODE_ONESHOT:
- BUG();
- /* FALLTHROUGH */
- case CLOCK_EVT_MODE_SHUTDOWN:
- case CLOCK_EVT_MODE_UNUSED:
- /* disable irq, leaving the clocksource active */
- pit_write(AT91_PIT_MR, (pit_cycle - 1) | AT91_PIT_PITEN);
- break;
- case CLOCK_EVT_MODE_RESUME:
- break;
- }
-}
-
-static void at91sam926x_pit_suspend(struct clock_event_device *cedev)
-{
- /* Disable timer */
- pit_write(AT91_PIT_MR, 0);
-}
-
-static void at91sam926x_pit_reset(void)
-{
- /* Disable timer and irqs */
- pit_write(AT91_PIT_MR, 0);
-
- /* Clear any pending interrupts, wait for PIT to stop counting */
- while (PIT_CPIV(pit_read(AT91_PIT_PIVR)) != 0)
- cpu_relax();
-
- /* Start PIT but don't enable IRQ */
- pit_write(AT91_PIT_MR, (pit_cycle - 1) | AT91_PIT_PITEN);
-}
-
-static void at91sam926x_pit_resume(struct clock_event_device *cedev)
-{
- at91sam926x_pit_reset();
-}
-
-static struct clock_event_device pit_clkevt = {
- .name = "pit",
- .features = CLOCK_EVT_FEAT_PERIODIC,
- .shift = 32,
- .rating = 100,
- .set_mode = pit_clkevt_mode,
- .suspend = at91sam926x_pit_suspend,
- .resume = at91sam926x_pit_resume,
-};
-
-
-/*
- * IRQ handler for the timer.
- */
-static irqreturn_t at91sam926x_pit_interrupt(int irq, void *dev_id)
-{
- /*
- * irqs should be disabled here, but as the irq is shared they are only
- * guaranteed to be off if the timer irq is registered first.
- */
- WARN_ON_ONCE(!irqs_disabled());
-
- /* The PIT interrupt may be disabled, and is shared */
- if ((pit_clkevt.mode == CLOCK_EVT_MODE_PERIODIC)
- && (pit_read(AT91_PIT_SR) & AT91_PIT_PITS)) {
- unsigned nr_ticks;
-
- /* Get number of ticks performed before irq, and ack it */
- nr_ticks = PIT_PICNT(pit_read(AT91_PIT_PIVR));
- do {
- pit_cnt += pit_cycle;
- pit_clkevt.event_handler(&pit_clkevt);
- nr_ticks--;
- } while (nr_ticks);
-
- return IRQ_HANDLED;
- }
-
- return IRQ_NONE;
-}
-
-static struct irqaction at91sam926x_pit_irq = {
- .name = "at91_tick",
- .flags = IRQF_SHARED | IRQF_TIMER | IRQF_IRQPOLL,
- .handler = at91sam926x_pit_interrupt,
- .irq = NR_IRQS_LEGACY + AT91_ID_SYS,
-};
-
-#ifdef CONFIG_OF
-static struct of_device_id pit_timer_ids[] = {
- { .compatible = "atmel,at91sam9260-pit" },
- { /* sentinel */ }
-};
-
-static int __init of_at91sam926x_pit_init(void)
-{
- struct device_node *np;
- int ret;
-
- np = of_find_matching_node(NULL, pit_timer_ids);
- if (!np)
- goto err;
-
- pit_base_addr = of_iomap(np, 0);
- if (!pit_base_addr)
- goto node_err;
-
- mck = of_clk_get(np, 0);
-
- /* Get the interrupts property */
- ret = irq_of_parse_and_map(np, 0);
- if (!ret) {
- pr_crit("AT91: PIT: Unable to get IRQ from DT\n");
- if (!IS_ERR(mck))
- clk_put(mck);
- goto ioremap_err;
- }
- at91sam926x_pit_irq.irq = ret;
-
- of_node_put(np);
-
- return 0;
-
-ioremap_err:
- iounmap(pit_base_addr);
-node_err:
- of_node_put(np);
-err:
- return -EINVAL;
-}
-#else
-static int __init of_at91sam926x_pit_init(void)
-{
- return -EINVAL;
-}
-#endif
-
-/*
- * Set up both clocksource and clockevent support.
- */
-void __init at91sam926x_pit_init(void)
-{
- unsigned long pit_rate;
- unsigned bits;
- int ret;
-
- mck = ERR_PTR(-ENOENT);
-
- /* For device tree enabled device: initialize here */
- of_at91sam926x_pit_init();
-
- /*
- * Use our actual MCK to figure out how many MCK/16 ticks per
- * 1/HZ period (instead of a compile-time constant LATCH).
- */
- if (IS_ERR(mck))
- mck = clk_get(NULL, "mck");
-
- if (IS_ERR(mck))
- panic("AT91: PIT: Unable to get mck clk\n");
- pit_rate = clk_get_rate(mck) / 16;
- pit_cycle = (pit_rate + HZ/2) / HZ;
- WARN_ON(((pit_cycle - 1) & ~AT91_PIT_PIV) != 0);
-
- /* Initialize and enable the timer */
- at91sam926x_pit_reset();
-
- /*
- * Register clocksource. The high order bits of PIV are unused,
- * so this isn't a 32-bit counter unless we get clockevent irqs.
- */
- bits = 12 /* PICNT */ + ilog2(pit_cycle) /* PIV */;
- pit_clk.mask = CLOCKSOURCE_MASK(bits);
- clocksource_register_hz(&pit_clk, pit_rate);
-
- /* Set up irq handler */
- ret = setup_irq(at91sam926x_pit_irq.irq, &at91sam926x_pit_irq);
- if (ret)
- pr_crit("AT91: PIT: Unable to setup IRQ\n");
-
- /* Set up and register clockevents */
- pit_clkevt.mult = div_sc(pit_rate, NSEC_PER_SEC, pit_clkevt.shift);
- pit_clkevt.cpumask = cpumask_of(0);
- clockevents_register_device(&pit_clkevt);
-}
-
-void __init at91sam926x_ioremap_pit(u32 addr)
-{
-#if defined(CONFIG_OF)
- struct device_node *np =
- of_find_matching_node(NULL, pit_timer_ids);
-
- if (np) {
- of_node_put(np);
- return;
- }
-#endif
- pit_base_addr = ioremap(addr, 16);
-
- if (!pit_base_addr)
- panic("Impossible to ioremap PIT\n");
-}
diff --git a/arch/arm/mach-at91/at91sam9_alt_reset.S b/arch/arm/mach-at91/at91sam9_alt_reset.S
deleted file mode 100644
index f039538d3bdb..000000000000
--- a/arch/arm/mach-at91/at91sam9_alt_reset.S
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * reset AT91SAM9G20 as per errata
- *
- * (C) BitBox Ltd 2010
- *
- * unless the SDRAM is cleanly shutdown before we hit the
- * reset register it can be left driving the data bus and
- * killing the chance of a subsequent boot from NAND
- *
- * 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 <linux/linkage.h>
-#include <mach/hardware.h>
-#include <mach/at91_ramc.h>
-#include "at91_rstc.h"
-
- .arm
-
- .globl at91sam9_alt_restart
-
-at91sam9_alt_restart: ldr r0, =at91_ramc_base @ preload constants
- ldr r0, [r0]
- ldr r4, =at91_rstc_base
- ldr r1, [r4]
-
- mov r2, #1
- mov r3, #AT91_SDRAMC_LPCB_POWER_DOWN
- ldr r4, =AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST
-
- .balign 32 @ align to cache line
-
- str r2, [r0, #AT91_SDRAMC_TR] @ disable SDRAM access
- str r3, [r0, #AT91_SDRAMC_LPR] @ power down SDRAM
- str r4, [r1, #AT91_RSTC_CR] @ reset processor
-
- b .
diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c
index 9d45496e4932..405427ec05f8 100644
--- a/arch/arm/mach-at91/at91sam9g45.c
+++ b/arch/arm/mach-at91/at91sam9g45.c
@@ -13,6 +13,7 @@
#include <linux/module.h>
#include <linux/dma-mapping.h>
#include <linux/clk/at91_pmc.h>
+#include <linux/platform_device.h>
#include <asm/irq.h>
#include <asm/mach/arch.h>
@@ -371,8 +372,6 @@ static void __init at91sam9g45_map_io(void)
static void __init at91sam9g45_ioremap_registers(void)
{
- at91_ioremap_shdwc(AT91SAM9G45_BASE_SHDWC);
- at91_ioremap_rstc(AT91SAM9G45_BASE_RSTC);
at91_ioremap_ramc(0, AT91SAM9G45_BASE_DDRSDRC1, 512);
at91_ioremap_ramc(1, AT91SAM9G45_BASE_DDRSDRC0, 512);
at91sam926x_ioremap_pit(AT91SAM9G45_BASE_PIT);
@@ -384,7 +383,6 @@ static void __init at91sam9g45_ioremap_registers(void)
static void __init at91sam9g45_initialize(void)
{
arm_pm_idle = at91sam9_idle;
- arm_pm_restart = at91sam9g45_restart;
at91_sysirq_mask_rtc(AT91SAM9G45_BASE_RTC);
at91_sysirq_mask_rtt(AT91SAM9G45_BASE_RTT);
@@ -393,6 +391,50 @@ static void __init at91sam9g45_initialize(void)
at91_gpio_init(at91sam9g45_gpio, 5);
}
+static struct resource rstc_resources[] = {
+ [0] = {
+ .start = AT91SAM9G45_BASE_RSTC,
+ .end = AT91SAM9G45_BASE_RSTC + SZ_16 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9G45_BASE_DDRSDRC1,
+ .end = AT91SAM9G45_BASE_DDRSDRC1 + SZ_512 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = AT91SAM9G45_BASE_DDRSDRC0,
+ .end = AT91SAM9G45_BASE_DDRSDRC0 + SZ_512 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device rstc_device = {
+ .name = "at91-sam9g45-reset",
+ .resource = rstc_resources,
+ .num_resources = ARRAY_SIZE(rstc_resources),
+};
+
+static struct resource shdwc_resources[] = {
+ [0] = {
+ .start = AT91SAM9G45_BASE_SHDWC,
+ .end = AT91SAM9G45_BASE_SHDWC + SZ_16 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device shdwc_device = {
+ .name = "at91-poweroff",
+ .resource = shdwc_resources,
+ .num_resources = ARRAY_SIZE(shdwc_resources),
+};
+
+static void __init at91sam9g45_register_devices(void)
+{
+ platform_device_register(&rstc_device);
+ platform_device_register(&shdwc_device);
+}
+
/* --------------------------------------------------------------------
* Interrupt initialization
* -------------------------------------------------------------------- */
@@ -435,11 +477,18 @@ static unsigned int at91sam9g45_default_irq_priority[NR_AIC_IRQS] __initdata = {
0, /* Advanced Interrupt Controller (IRQ0) */
};
+static void __init at91sam9g45_init_time(void)
+{
+ at91sam926x_pit_init(NR_IRQS_LEGACY + AT91_ID_SYS);
+}
+
AT91_SOC_START(at91sam9g45)
.map_io = at91sam9g45_map_io,
.default_irq_priority = at91sam9g45_default_irq_priority,
.extern_irq = (1 << AT91SAM9G45_ID_IRQ0),
.ioremap_registers = at91sam9g45_ioremap_registers,
.register_clocks = at91sam9g45_register_clocks,
+ .register_devices = at91sam9g45_register_devices,
.init = at91sam9g45_initialize,
+ .init_time = at91sam9g45_init_time,
AT91_SOC_END
diff --git a/arch/arm/mach-at91/at91sam9g45_reset.S b/arch/arm/mach-at91/at91sam9g45_reset.S
deleted file mode 100644
index c40c1e2ef80f..000000000000
--- a/arch/arm/mach-at91/at91sam9g45_reset.S
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * reset AT91SAM9G45 as per errata
- *
- * Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcosoft.com>
- *
- * unless the SDRAM is cleanly shutdown before we hit the
- * reset register it can be left driving the data bus and
- * killing the chance of a subsequent boot from NAND
- *
- * GPLv2 Only
- */
-
-#include <linux/linkage.h>
-#include <mach/hardware.h>
-#include <mach/at91_ramc.h>
-#include "at91_rstc.h"
- .arm
-
-/*
- * at91_ramc_base is an array void*
- * init at NULL if only one DDR controler is present in or DT
- */
- .globl at91sam9g45_restart
-
-at91sam9g45_restart:
- ldr r5, =at91_ramc_base @ preload constants
- ldr r0, [r5]
- ldr r5, [r5, #4] @ ddr1
- cmp r5, #0
- ldr r4, =at91_rstc_base
- ldr r1, [r4]
-
- mov r2, #1
- mov r3, #AT91_DDRSDRC_LPCB_POWER_DOWN
- ldr r4, =AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST
-
- .balign 32 @ align to cache line
-
- strne r2, [r5, #AT91_DDRSDRC_RTR] @ disable DDR1 access
- strne r3, [r5, #AT91_DDRSDRC_LPR] @ power down DDR1
- str r2, [r0, #AT91_DDRSDRC_RTR] @ disable DDR0 access
- str r3, [r0, #AT91_DDRSDRC_LPR] @ power down DDR0
- str r4, [r1, #AT91_RSTC_CR] @ reset processor
-
- b .
diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c
index 878d5015daab..f553e4ea034b 100644
--- a/arch/arm/mach-at91/at91sam9rl.c
+++ b/arch/arm/mach-at91/at91sam9rl.c
@@ -10,6 +10,7 @@
*/
#include <linux/module.h>
+#include <linux/platform_device.h>
#include <linux/clk/at91_pmc.h>
#include <asm/proc-fns.h>
@@ -23,7 +24,6 @@
#include <mach/hardware.h>
#include "at91_aic.h"
-#include "at91_rstc.h"
#include "soc.h"
#include "generic.h"
#include "sam9_smc.h"
@@ -311,8 +311,6 @@ static void __init at91sam9rl_map_io(void)
static void __init at91sam9rl_ioremap_registers(void)
{
- at91_ioremap_shdwc(AT91SAM9RL_BASE_SHDWC);
- at91_ioremap_rstc(AT91SAM9RL_BASE_RSTC);
at91_ioremap_ramc(0, AT91SAM9RL_BASE_SDRAMC, 512);
at91sam926x_ioremap_pit(AT91SAM9RL_BASE_PIT);
at91sam9_ioremap_smc(0, AT91SAM9RL_BASE_SMC);
@@ -323,7 +321,6 @@ static void __init at91sam9rl_ioremap_registers(void)
static void __init at91sam9rl_initialize(void)
{
arm_pm_idle = at91sam9_idle;
- arm_pm_restart = at91sam9_alt_restart;
at91_sysirq_mask_rtc(AT91SAM9RL_BASE_RTC);
at91_sysirq_mask_rtt(AT91SAM9RL_BASE_RTT);
@@ -332,6 +329,45 @@ static void __init at91sam9rl_initialize(void)
at91_gpio_init(at91sam9rl_gpio, 4);
}
+static struct resource rstc_resources[] = {
+ [0] = {
+ .start = AT91SAM9RL_BASE_RSTC,
+ .end = AT91SAM9RL_BASE_RSTC + SZ_16 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9RL_BASE_SDRAMC,
+ .end = AT91SAM9RL_BASE_SDRAMC + SZ_512 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device rstc_device = {
+ .name = "at91-sam9260-reset",
+ .resource = rstc_resources,
+ .num_resources = ARRAY_SIZE(rstc_resources),
+};
+
+static struct resource shdwc_resources[] = {
+ [0] = {
+ .start = AT91SAM9RL_BASE_SHDWC,
+ .end = AT91SAM9RL_BASE_SHDWC + SZ_16 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device shdwc_device = {
+ .name = "at91-poweroff",
+ .resource = shdwc_resources,
+ .num_resources = ARRAY_SIZE(shdwc_resources),
+};
+
+static void __init at91sam9rl_register_devices(void)
+{
+ platform_device_register(&rstc_device);
+ platform_device_register(&shdwc_device);
+}
+
/* --------------------------------------------------------------------
* Interrupt initialization
* -------------------------------------------------------------------- */
@@ -374,6 +410,11 @@ static unsigned int at91sam9rl_default_irq_priority[NR_AIC_IRQS] __initdata = {
0, /* Advanced Interrupt Controller */
};
+static void __init at91sam9rl_init_time(void)
+{
+ at91sam926x_pit_init(NR_IRQS_LEGACY + AT91_ID_SYS);
+}
+
AT91_SOC_START(at91sam9rl)
.map_io = at91sam9rl_map_io,
.default_irq_priority = at91sam9rl_default_irq_priority,
@@ -382,5 +423,7 @@ AT91_SOC_START(at91sam9rl)
#if defined(CONFIG_OLD_CLK_AT91)
.register_clocks = at91sam9rl_register_clocks,
#endif
+ .register_devices = at91sam9rl_register_devices,
.init = at91sam9rl_initialize,
+ .init_time = at91sam9rl_init_time,
AT91_SOC_END
diff --git a/arch/arm/mach-at91/board-afeb-9260v1.c b/arch/arm/mach-at91/board-afeb-9260v1.c
index 597c649170aa..e76e35ce81e7 100644
--- a/arch/arm/mach-at91/board-afeb-9260v1.c
+++ b/arch/arm/mach-at91/board-afeb-9260v1.c
@@ -167,6 +167,8 @@ static struct at91_cf_data afeb9260_cf_data = {
static void __init afeb9260_board_init(void)
{
+ at91_register_devices();
+
/* Serial */
/* DBGU on ttyS0. (Rx & Tx only) */
at91_register_uart(0, 0, 0);
@@ -211,7 +213,7 @@ static void __init afeb9260_board_init(void)
MACHINE_START(AFEB9260, "Custom afeb9260 board")
/* Maintainer: Sergey Lapin <slapin@ossfans.org> */
- .init_time = at91sam926x_pit_init,
+ .init_time = at91_init_time,
.map_io = at91_map_io,
.handle_irq = at91_aic_handle_irq,
.init_early = afeb9260_init_early,
diff --git a/arch/arm/mach-at91/board-cam60.c b/arch/arm/mach-at91/board-cam60.c
index a30502c8d379..ae827dd2d0d2 100644
--- a/arch/arm/mach-at91/board-cam60.c
+++ b/arch/arm/mach-at91/board-cam60.c
@@ -170,6 +170,8 @@ static void __init cam60_add_device_nand(void)
static void __init cam60_board_init(void)
{
+ at91_register_devices();
+
/* Serial */
/* DBGU on ttyS0. (Rx & Tx only) */
at91_register_uart(0, 0, 0);
@@ -188,7 +190,7 @@ static void __init cam60_board_init(void)
MACHINE_START(CAM60, "KwikByte CAM60")
/* Maintainer: KwikByte */
- .init_time = at91sam926x_pit_init,
+ .init_time = at91_init_time,
.map_io = at91_map_io,
.handle_irq = at91_aic_handle_irq,
.init_early = cam60_init_early,
diff --git a/arch/arm/mach-at91/board-cpu9krea.c b/arch/arm/mach-at91/board-cpu9krea.c
index 2037f78c84e7..731c8318f4f5 100644
--- a/arch/arm/mach-at91/board-cpu9krea.c
+++ b/arch/arm/mach-at91/board-cpu9krea.c
@@ -322,6 +322,8 @@ static struct mci_platform_data __initdata cpu9krea_mci0_data = {
static void __init cpu9krea_board_init(void)
{
+ at91_register_devices();
+
/* NOR */
cpu9krea_add_device_nor();
/* Serial */
@@ -375,7 +377,7 @@ MACHINE_START(CPUAT9260, "Eukrea CPU9260")
MACHINE_START(CPUAT9G20, "Eukrea CPU9G20")
#endif
/* Maintainer: Eric Benard - EUKREA Electromatique */
- .init_time = at91sam926x_pit_init,
+ .init_time = at91_init_time,
.map_io = at91_map_io,
.handle_irq = at91_aic_handle_irq,
.init_early = cpu9krea_init_early,
diff --git a/arch/arm/mach-at91/board-dt-rm9200.c b/arch/arm/mach-at91/board-dt-rm9200.c
index f4b6e91843e4..226563f850b8 100644
--- a/arch/arm/mach-at91/board-dt-rm9200.c
+++ b/arch/arm/mach-at91/board-dt-rm9200.c
@@ -25,17 +25,6 @@
#include "at91_aic.h"
#include "generic.h"
-
-static const struct of_device_id irq_of_match[] __initconst = {
- { .compatible = "atmel,at91rm9200-aic", .data = at91_aic_of_init },
- { /*sentinel*/ }
-};
-
-static void __init at91rm9200_dt_init_irq(void)
-{
- of_irq_init(irq_of_match);
-}
-
static void __init at91rm9200_dt_timer_init(void)
{
#if defined(CONFIG_COMMON_CLK)
@@ -52,8 +41,6 @@ static const char *at91rm9200_dt_board_compat[] __initdata = {
DT_MACHINE_START(at91rm9200_dt, "Atmel AT91RM9200 (Device Tree)")
.init_time = at91rm9200_dt_timer_init,
.map_io = at91_map_io,
- .handle_irq = at91_aic_handle_irq,
.init_early = at91rm9200_dt_initialize,
- .init_irq = at91rm9200_dt_init_irq,
.dt_compat = at91rm9200_dt_board_compat,
MACHINE_END
diff --git a/arch/arm/mach-at91/board-dt-sam9.c b/arch/arm/mach-at91/board-dt-sam9.c
index 575b0be66ca8..d3048ccdc41f 100644
--- a/arch/arm/mach-at91/board-dt-sam9.c
+++ b/arch/arm/mach-at91/board-dt-sam9.c
@@ -25,26 +25,6 @@
#include "board.h"
#include "generic.h"
-
-static void __init sam9_dt_timer_init(void)
-{
-#if defined(CONFIG_COMMON_CLK)
- of_clk_init(NULL);
-#endif
- at91sam926x_pit_init();
-}
-
-static const struct of_device_id irq_of_match[] __initconst = {
-
- { .compatible = "atmel,at91rm9200-aic", .data = at91_aic_of_init },
- { /*sentinel*/ }
-};
-
-static void __init at91_dt_init_irq(void)
-{
- of_irq_init(irq_of_match);
-}
-
static const char *at91_dt_board_compat[] __initdata = {
"atmel,at91sam9",
NULL
@@ -52,10 +32,7 @@ static const char *at91_dt_board_compat[] __initdata = {
DT_MACHINE_START(at91sam_dt, "Atmel AT91SAM (Device Tree)")
/* Maintainer: Atmel */
- .init_time = sam9_dt_timer_init,
.map_io = at91_map_io,
- .handle_irq = at91_aic_handle_irq,
.init_early = at91_dt_initialize,
- .init_irq = at91_dt_init_irq,
.dt_compat = at91_dt_board_compat,
MACHINE_END
diff --git a/arch/arm/mach-at91/board-dt-sama5.c b/arch/arm/mach-at91/board-dt-sama5.c
index 075ec0576ada..129e2917506b 100644
--- a/arch/arm/mach-at91/board-dt-sama5.c
+++ b/arch/arm/mach-at91/board-dt-sama5.c
@@ -27,64 +27,34 @@
#include "at91_aic.h"
#include "generic.h"
-static void __init sama5_dt_timer_init(void)
-{
-#if defined(CONFIG_COMMON_CLK)
- of_clk_init(NULL);
-#endif
- at91sam926x_pit_init();
-}
-
-static const struct of_device_id irq_of_match[] __initconst = {
-
- { .compatible = "atmel,sama5d3-aic", .data = at91_aic5_of_init },
- { /*sentinel*/ }
-};
-
-static void __init at91_dt_init_irq(void)
-{
- of_irq_init(irq_of_match);
-}
-
-static int ksz9021rn_phy_fixup(struct phy_device *phy)
-{
- int value;
-
- /* Set delay values */
- value = MICREL_KSZ9021_RGMII_CLK_CTRL_PAD_SCEW | 0x8000;
- phy_write(phy, MICREL_KSZ9021_EXTREG_CTRL, value);
- value = 0xF2F4;
- phy_write(phy, MICREL_KSZ9021_EXTREG_DATA_WRITE, value);
- value = MICREL_KSZ9021_RGMII_RX_DATA_PAD_SCEW | 0x8000;
- phy_write(phy, MICREL_KSZ9021_EXTREG_CTRL, value);
- value = 0x2222;
- phy_write(phy, MICREL_KSZ9021_EXTREG_DATA_WRITE, value);
-
- return 0;
-}
-
static void __init sama5_dt_device_init(void)
{
- if (of_machine_is_compatible("atmel,sama5d3xcm") &&
- IS_ENABLED(CONFIG_PHYLIB))
- phy_register_fixup_for_uid(PHY_ID_KSZ9021, MICREL_PHY_ID_MASK,
- ksz9021rn_phy_fixup);
-
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
}
-static const char *sama5_dt_board_compat[] __initdata = {
+static const char *sama5_dt_board_compat[] __initconst = {
"atmel,sama5",
NULL
};
DT_MACHINE_START(sama5_dt, "Atmel SAMA5 (Device Tree)")
/* Maintainer: Atmel */
- .init_time = sama5_dt_timer_init,
.map_io = at91_map_io,
- .handle_irq = at91_aic5_handle_irq,
.init_early = at91_dt_initialize,
- .init_irq = at91_dt_init_irq,
.init_machine = sama5_dt_device_init,
.dt_compat = sama5_dt_board_compat,
MACHINE_END
+
+static const char *sama5_alt_dt_board_compat[] __initconst = {
+ "atmel,sama5d4",
+ NULL
+};
+
+DT_MACHINE_START(sama5_alt_dt, "Atmel SAMA5 (Device Tree)")
+ /* Maintainer: Atmel */
+ .map_io = at91_alt_map_io,
+ .init_early = at91_dt_initialize,
+ .init_machine = sama5_dt_device_init,
+ .dt_compat = sama5_alt_dt_board_compat,
+ .l2c_aux_mask = ~0UL,
+MACHINE_END
diff --git a/arch/arm/mach-at91/board-flexibity.c b/arch/arm/mach-at91/board-flexibity.c
index 68f1ab6bd08f..a6aa4a2432f2 100644
--- a/arch/arm/mach-at91/board-flexibity.c
+++ b/arch/arm/mach-at91/board-flexibity.c
@@ -138,6 +138,8 @@ static struct gpio_led flexibity_leds[] = {
static void __init flexibity_board_init(void)
{
+ at91_register_devices();
+
/* Serial */
/* DBGU on ttyS0. (Rx & Tx only) */
at91_register_uart(0, 0, 0);
@@ -160,7 +162,7 @@ static void __init flexibity_board_init(void)
MACHINE_START(FLEXIBITY, "Flexibity Connect")
/* Maintainer: Maxim Osipov */
- .init_time = at91sam926x_pit_init,
+ .init_time = at91_init_time,
.map_io = at91_map_io,
.handle_irq = at91_aic_handle_irq,
.init_early = flexibity_init_early,
diff --git a/arch/arm/mach-at91/board-foxg20.c b/arch/arm/mach-at91/board-foxg20.c
deleted file mode 100644
index 8b22c60bb238..000000000000
--- a/arch/arm/mach-at91/board-foxg20.c
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * Copyright (C) 2005 SAN People
- * Copyright (C) 2008 Atmel
- * Copyright (C) 2010 Lee McLoughlin - lee@lmmrtech.com
- * Copyright (C) 2010 Sergio Tanzilli - tanzilli@acmesystems.it
- *
- * 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.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/spi/spi.h>
-#include <linux/spi/at73c213.h>
-#include <linux/gpio.h>
-#include <linux/gpio_keys.h>
-#include <linux/input.h>
-#include <linux/clk.h>
-#include <linux/w1-gpio.h>
-
-#include <mach/hardware.h>
-#include <asm/setup.h>
-#include <asm/mach-types.h>
-#include <asm/irq.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <mach/at91sam9_smc.h>
-
-#include "at91_aic.h"
-#include "board.h"
-#include "sam9_smc.h"
-#include "generic.h"
-#include "gpio.h"
-
-/*
- * The FOX Board G20 hardware comes as the "Netus G20" board with
- * just the cpu, ram, dataflash and two header connectors.
- * This is plugged into the FOX Board which provides the ethernet,
- * usb, rtc, leds, switch, ...
- *
- * For more info visit: http://www.acmesystems.it/foxg20
- */
-
-
-static void __init foxg20_init_early(void)
-{
- /* Initialize processor: 18.432 MHz crystal */
- at91_initialize(18432000);
-}
-
-/*
- * USB Host port
- */
-static struct at91_usbh_data __initdata foxg20_usbh_data = {
- .ports = 2,
- .vbus_pin = {-EINVAL, -EINVAL},
- .overcurrent_pin= {-EINVAL, -EINVAL},
-};
-
-/*
- * USB Device port
- */
-static struct at91_udc_data __initdata foxg20_udc_data = {
- .vbus_pin = AT91_PIN_PC6,
- .pullup_pin = -EINVAL, /* pull-up driven by UDC */
-};
-
-
-/*
- * SPI devices.
- */
-static struct spi_board_info foxg20_spi_devices[] = {
-#if !IS_ENABLED(CONFIG_MMC_ATMELMCI)
- {
- .modalias = "mtd_dataflash",
- .chip_select = 1,
- .max_speed_hz = 15 * 1000 * 1000,
- .bus_num = 0,
- },
-#endif
-};
-
-
-/*
- * MACB Ethernet device
- */
-static struct macb_platform_data __initdata foxg20_macb_data = {
- .phy_irq_pin = AT91_PIN_PA7,
- .is_rmii = 1,
-};
-
-/*
- * MCI (SD/MMC)
- * det_pin, wp_pin and vcc_pin are not connected
- */
-static struct mci_platform_data __initdata foxg20_mci0_data = {
- .slot[1] = {
- .bus_width = 4,
- .detect_pin = -EINVAL,
- .wp_pin = -EINVAL,
- },
-};
-
-
-/*
- * LEDs
- */
-static struct gpio_led foxg20_leds[] = {
- { /* user led, red */
- .name = "user_led",
- .gpio = AT91_PIN_PC7,
- .active_low = 0,
- .default_trigger = "heartbeat",
- },
-};
-
-
-/*
- * GPIO Buttons
- */
-#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
-static struct gpio_keys_button foxg20_buttons[] = {
- {
- .gpio = AT91_PIN_PC4,
- .code = BTN_1,
- .desc = "Button 1",
- .active_low = 1,
- .wakeup = 1,
- },
-};
-
-static struct gpio_keys_platform_data foxg20_button_data = {
- .buttons = foxg20_buttons,
- .nbuttons = ARRAY_SIZE(foxg20_buttons),
-};
-
-static struct platform_device foxg20_button_device = {
- .name = "gpio-keys",
- .id = -1,
- .num_resources = 0,
- .dev = {
- .platform_data = &foxg20_button_data,
- }
-};
-
-static void __init foxg20_add_device_buttons(void)
-{
- at91_set_gpio_input(AT91_PIN_PC4, 1); /* btn1 */
- at91_set_deglitch(AT91_PIN_PC4, 1);
-
- platform_device_register(&foxg20_button_device);
-}
-#else
-static void __init foxg20_add_device_buttons(void) {}
-#endif
-
-
-#if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE)
-static struct w1_gpio_platform_data w1_gpio_pdata = {
- /* If you choose to use a pin other than PB16 it needs to be 3.3V */
- .pin = AT91_PIN_PB16,
- .is_open_drain = 1,
- .ext_pullup_enable_pin = -EINVAL,
-};
-
-static struct platform_device w1_device = {
- .name = "w1-gpio",
- .id = -1,
- .dev.platform_data = &w1_gpio_pdata,
-};
-
-static void __init at91_add_device_w1(void)
-{
- at91_set_GPIO_periph(w1_gpio_pdata.pin, 1);
- at91_set_multi_drive(w1_gpio_pdata.pin, 1);
- platform_device_register(&w1_device);
-}
-
-#endif
-
-
-static struct i2c_board_info __initdata foxg20_i2c_devices[] = {
- {
- I2C_BOARD_INFO("24c512", 0x50),
- },
-};
-
-
-static void __init foxg20_board_init(void)
-{
- /* Serial */
- /* DBGU on ttyS0. (Rx & Tx only) */
- at91_register_uart(0, 0, 0);
-
- /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
- at91_register_uart(AT91SAM9260_ID_US0, 1,
- ATMEL_UART_CTS
- | ATMEL_UART_RTS
- | ATMEL_UART_DTR
- | ATMEL_UART_DSR
- | ATMEL_UART_DCD
- | ATMEL_UART_RI);
-
- /* USART1 on ttyS2. (Rx, Tx, RTS, CTS) */
- at91_register_uart(AT91SAM9260_ID_US1, 2,
- ATMEL_UART_CTS
- | ATMEL_UART_RTS);
-
- /* USART2 on ttyS3. (Rx & Tx only) */
- at91_register_uart(AT91SAM9260_ID_US2, 3, 0);
-
- /* USART3 on ttyS4. (Rx, Tx, RTS, CTS) */
- at91_register_uart(AT91SAM9260_ID_US3, 4,
- ATMEL_UART_CTS
- | ATMEL_UART_RTS);
-
- /* USART4 on ttyS5. (Rx & Tx only) */
- at91_register_uart(AT91SAM9260_ID_US4, 5, 0);
-
- /* USART5 on ttyS6. (Rx & Tx only) */
- at91_register_uart(AT91SAM9260_ID_US5, 6, 0);
-
- /* Set the internal pull-up resistor on DRXD */
- at91_set_A_periph(AT91_PIN_PB14, 1);
- at91_add_device_serial();
- /* USB Host */
- at91_add_device_usbh(&foxg20_usbh_data);
- /* USB Device */
- at91_add_device_udc(&foxg20_udc_data);
- /* SPI */
- at91_add_device_spi(foxg20_spi_devices, ARRAY_SIZE(foxg20_spi_devices));
- /* Ethernet */
- at91_add_device_eth(&foxg20_macb_data);
- /* MMC */
- at91_add_device_mci(0, &foxg20_mci0_data);
- /* I2C */
- at91_add_device_i2c(foxg20_i2c_devices, ARRAY_SIZE(foxg20_i2c_devices));
- /* LEDs */
- at91_gpio_leds(foxg20_leds, ARRAY_SIZE(foxg20_leds));
- /* Push Buttons */
- foxg20_add_device_buttons();
-#if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE)
- at91_add_device_w1();
-#endif
-}
-
-MACHINE_START(ACMENETUSFOXG20, "Acme Systems srl FOX Board G20")
- /* Maintainer: Sergio Tanzilli */
- .init_time = at91sam926x_pit_init,
- .map_io = at91_map_io,
- .handle_irq = at91_aic_handle_irq,
- .init_early = foxg20_init_early,
- .init_irq = at91_init_irq_default,
- .init_machine = foxg20_board_init,
-MACHINE_END
diff --git a/arch/arm/mach-at91/board-gsia18s.c b/arch/arm/mach-at91/board-gsia18s.c
index b729dd1271bf..bf5cc55c7db6 100644
--- a/arch/arm/mach-at91/board-gsia18s.c
+++ b/arch/arm/mach-at91/board-gsia18s.c
@@ -576,7 +576,7 @@ static void __init gsia18s_board_init(void)
}
MACHINE_START(GSIA18S, "GS_IA18_S")
- .init_time = at91sam926x_pit_init,
+ .init_time = at91_init_time,
.map_io = at91_map_io,
.handle_irq = at91_aic_handle_irq,
.init_early = gsia18s_init_early,
diff --git a/arch/arm/mach-at91/board-pcontrol-g20.c b/arch/arm/mach-at91/board-pcontrol-g20.c
index b48d95ec5152..9c26b94ce448 100644
--- a/arch/arm/mach-at91/board-pcontrol-g20.c
+++ b/arch/arm/mach-at91/board-pcontrol-g20.c
@@ -219,7 +219,7 @@ static void __init pcontrol_g20_board_init(void)
MACHINE_START(PCONTROL_G20, "PControl G20")
/* Maintainer: pgsellmann@portner-elektronik.at */
- .init_time = at91sam926x_pit_init,
+ .init_time = at91_init_time,
.map_io = at91_map_io,
.handle_irq = at91_aic_handle_irq,
.init_early = pcontrol_g20_init_early,
diff --git a/arch/arm/mach-at91/board-rsi-ews.c b/arch/arm/mach-at91/board-rsi-ews.c
deleted file mode 100644
index f28e8b74df4b..000000000000
--- a/arch/arm/mach-at91/board-rsi-ews.c
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * board-rsi-ews.c
- *
- * Copyright (C)
- * 2005 SAN People,
- * 2008-2011 R-S-I Elektrotechnik GmbH & Co. KG
- *
- * Licensed under GPLv2 or later.
- */
-
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/spi/spi.h>
-#include <linux/mtd/physmap.h>
-
-#include <asm/setup.h>
-#include <asm/mach-types.h>
-#include <asm/irq.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <mach/hardware.h>
-
-#include <linux/gpio.h>
-
-#include "at91_aic.h"
-#include "board.h"
-#include "generic.h"
-#include "gpio.h"
-
-static void __init rsi_ews_init_early(void)
-{
- /* Initialize processor: 18.432 MHz crystal */
- at91_initialize(18432000);
-}
-
-/*
- * Ethernet
- */
-static struct macb_platform_data rsi_ews_eth_data __initdata = {
- .phy_irq_pin = AT91_PIN_PC4,
- .is_rmii = 1,
-};
-
-/*
- * USB Host
- */
-static struct at91_usbh_data rsi_ews_usbh_data __initdata = {
- .ports = 1,
- .vbus_pin = {-EINVAL, -EINVAL},
- .overcurrent_pin= {-EINVAL, -EINVAL},
-};
-
-/*
- * SD/MC
- */
-static struct mci_platform_data __initdata rsi_ews_mci0_data = {
- .slot[0] = {
- .bus_width = 4,
- .detect_pin = AT91_PIN_PB27,
- .wp_pin = AT91_PIN_PB29,
- },
-};
-
-/*
- * I2C
- */
-static struct i2c_board_info rsi_ews_i2c_devices[] __initdata = {
- {
- I2C_BOARD_INFO("ds1337", 0x68),
- },
- {
- I2C_BOARD_INFO("24c01", 0x50),
- }
-};
-
-/*
- * LEDs
- */
-static struct gpio_led rsi_ews_leds[] = {
- {
- .name = "led0",
- .gpio = AT91_PIN_PB6,
- .active_low = 0,
- },
- {
- .name = "led1",
- .gpio = AT91_PIN_PB7,
- .active_low = 0,
- },
- {
- .name = "led2",
- .gpio = AT91_PIN_PB8,
- .active_low = 0,
- },
- {
- .name = "led3",
- .gpio = AT91_PIN_PB9,
- .active_low = 0,
- },
-};
-
-/*
- * DataFlash
- */
-static struct spi_board_info rsi_ews_spi_devices[] = {
- { /* DataFlash chip 1*/
- .modalias = "mtd_dataflash",
- .chip_select = 0,
- .max_speed_hz = 5 * 1000 * 1000,
- },
- { /* DataFlash chip 2*/
- .modalias = "mtd_dataflash",
- .chip_select = 1,
- .max_speed_hz = 5 * 1000 * 1000,
- },
-};
-
-/*
- * NOR flash
- */
-static struct mtd_partition rsiews_nor_partitions[] = {
- {
- .name = "boot",
- .offset = 0,
- .size = 3 * SZ_128K,
- .mask_flags = MTD_WRITEABLE
- },
- {
- .name = "kernel",
- .offset = MTDPART_OFS_NXTBLK,
- .size = SZ_2M - (3 * SZ_128K)
- },
- {
- .name = "root",
- .offset = MTDPART_OFS_NXTBLK,
- .size = SZ_8M
- },
- {
- .name = "kernelupd",
- .offset = MTDPART_OFS_NXTBLK,
- .size = 3 * SZ_512K,
- .mask_flags = MTD_WRITEABLE
- },
- {
- .name = "rootupd",
- .offset = MTDPART_OFS_NXTBLK,
- .size = 9 * SZ_512K,
- .mask_flags = MTD_WRITEABLE
- },
-};
-
-static struct physmap_flash_data rsiews_nor_data = {
- .width = 2,
- .parts = rsiews_nor_partitions,
- .nr_parts = ARRAY_SIZE(rsiews_nor_partitions),
-};
-
-#define NOR_BASE AT91_CHIPSELECT_0
-#define NOR_SIZE SZ_16M
-
-static struct resource nor_flash_resources[] = {
- {
- .start = NOR_BASE,
- .end = NOR_BASE + NOR_SIZE - 1,
- .flags = IORESOURCE_MEM,
- }
-};
-
-static struct platform_device rsiews_nor_flash = {
- .name = "physmap-flash",
- .id = 0,
- .dev = {
- .platform_data = &rsiews_nor_data,
- },
- .resource = nor_flash_resources,
- .num_resources = ARRAY_SIZE(nor_flash_resources),
-};
-
-/*
- * Init Func
- */
-static void __init rsi_ews_board_init(void)
-{
- /* Serial */
- /* DBGU on ttyS0. (Rx & Tx only) */
- /* This one is for debugging */
- at91_register_uart(0, 0, 0);
-
- /* USART1 on ttyS2. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
- /* Dialin/-out modem interface */
- at91_register_uart(AT91RM9200_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS
- | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD
- | ATMEL_UART_RI);
-
- /* USART3 on ttyS4. (Rx, Tx, RTS) */
- /* RS485 communication */
- at91_register_uart(AT91RM9200_ID_US3, 4, ATMEL_UART_RTS);
- at91_add_device_serial();
- at91_set_gpio_output(AT91_PIN_PA21, 0);
- /* Ethernet */
- at91_add_device_eth(&rsi_ews_eth_data);
- /* USB Host */
- at91_add_device_usbh(&rsi_ews_usbh_data);
- /* I2C */
- at91_add_device_i2c(rsi_ews_i2c_devices,
- ARRAY_SIZE(rsi_ews_i2c_devices));
- /* SPI */
- at91_add_device_spi(rsi_ews_spi_devices,
- ARRAY_SIZE(rsi_ews_spi_devices));
- /* MMC */
- at91_add_device_mci(0, &rsi_ews_mci0_data);
- /* NOR Flash */
- platform_device_register(&rsiews_nor_flash);
- /* LEDs */
- at91_gpio_leds(rsi_ews_leds, ARRAY_SIZE(rsi_ews_leds));
-}
-
-MACHINE_START(RSI_EWS, "RSI EWS")
- /* Maintainer: Josef Holzmayr <holzmayr@rsi-elektrotechnik.de> */
- .init_time = at91rm9200_timer_init,
- .map_io = at91_map_io,
- .handle_irq = at91_aic_handle_irq,
- .init_early = rsi_ews_init_early,
- .init_irq = at91_init_irq_default,
- .init_machine = rsi_ews_board_init,
-MACHINE_END
diff --git a/arch/arm/mach-at91/board-sam9-l9260.c b/arch/arm/mach-at91/board-sam9-l9260.c
index d24dda67e2d3..c2166e3a236c 100644
--- a/arch/arm/mach-at91/board-sam9-l9260.c
+++ b/arch/arm/mach-at91/board-sam9-l9260.c
@@ -187,6 +187,8 @@ static struct gpio_led ek_leds[] = {
static void __init ek_board_init(void)
{
+ at91_register_devices();
+
/* Serial */
/* DBGU on ttyS0. (Rx & Tx only) */
at91_register_uart(0, 0, 0);
@@ -219,7 +221,7 @@ static void __init ek_board_init(void)
MACHINE_START(SAM9_L9260, "Olimex SAM9-L9260")
/* Maintainer: Olimex */
- .init_time = at91sam926x_pit_init,
+ .init_time = at91_init_time,
.map_io = at91_map_io,
.handle_irq = at91_aic_handle_irq,
.init_early = ek_init_early,
diff --git a/arch/arm/mach-at91/board-sam9260ek.c b/arch/arm/mach-at91/board-sam9260ek.c
index 65dea12d685e..bf8a946b4cd0 100644
--- a/arch/arm/mach-at91/board-sam9260ek.c
+++ b/arch/arm/mach-at91/board-sam9260ek.c
@@ -45,7 +45,6 @@
#include <mach/system_rev.h>
#include "at91_aic.h"
-#include "at91_shdwc.h"
#include "board.h"
#include "sam9_smc.h"
#include "generic.h"
@@ -307,6 +306,8 @@ static void __init ek_add_device_buttons(void) {}
static void __init ek_board_init(void)
{
+ at91_register_devices();
+
/* Serial */
/* DBGU on ttyS0. (Rx & Tx only) */
at91_register_uart(0, 0, 0);
@@ -344,7 +345,7 @@ static void __init ek_board_init(void)
MACHINE_START(AT91SAM9260EK, "Atmel AT91SAM9260-EK")
/* Maintainer: Atmel */
- .init_time = at91sam926x_pit_init,
+ .init_time = at91_init_time,
.map_io = at91_map_io,
.handle_irq = at91_aic_handle_irq,
.init_early = ek_init_early,
diff --git a/arch/arm/mach-at91/board-sam9261ek.c b/arch/arm/mach-at91/board-sam9261ek.c
index 4637432de08f..e85ada820bfb 100644
--- a/arch/arm/mach-at91/board-sam9261ek.c
+++ b/arch/arm/mach-at91/board-sam9261ek.c
@@ -49,7 +49,6 @@
#include <mach/system_rev.h>
#include "at91_aic.h"
-#include "at91_shdwc.h"
#include "board.h"
#include "sam9_smc.h"
#include "generic.h"
@@ -561,6 +560,8 @@ static struct gpio_led ek_leds[] = {
static void __init ek_board_init(void)
{
+ at91_register_devices();
+
/* Serial */
/* DBGU on ttyS0. (Rx & Tx only) */
at91_register_uart(0, 0, 0);
@@ -603,7 +604,7 @@ static void __init ek_board_init(void)
MACHINE_START(AT91SAM9261EK, "Atmel AT91SAM9261-EK")
/* Maintainer: Atmel */
- .init_time = at91sam926x_pit_init,
+ .init_time = at91_init_time,
.map_io = at91_map_io,
.handle_irq = at91_aic_handle_irq,
.init_early = ek_init_early,
@@ -613,7 +614,7 @@ MACHINE_END
MACHINE_START(AT91SAM9G10EK, "Atmel AT91SAM9G10-EK")
/* Maintainer: Atmel */
- .init_time = at91sam926x_pit_init,
+ .init_time = at91_init_time,
.map_io = at91_map_io,
.handle_irq = at91_aic_handle_irq,
.init_early = ek_init_early,
diff --git a/arch/arm/mach-at91/board-sam9263ek.c b/arch/arm/mach-at91/board-sam9263ek.c
index fc446097f410..d76680f2a209 100644
--- a/arch/arm/mach-at91/board-sam9263ek.c
+++ b/arch/arm/mach-at91/board-sam9263ek.c
@@ -50,7 +50,6 @@
#include <mach/system_rev.h>
#include "at91_aic.h"
-#include "at91_shdwc.h"
#include "board.h"
#include "sam9_smc.h"
#include "generic.h"
@@ -439,6 +438,8 @@ static struct platform_device *devices[] __initdata = {
static void __init ek_board_init(void)
{
+ at91_register_devices();
+
/* Serial */
/* DBGU on ttyS0. (Rx & Tx only) */
at91_register_uart(0, 0, 0);
@@ -483,7 +484,7 @@ static void __init ek_board_init(void)
MACHINE_START(AT91SAM9263EK, "Atmel AT91SAM9263-EK")
/* Maintainer: Atmel */
- .init_time = at91sam926x_pit_init,
+ .init_time = at91_init_time,
.map_io = at91_map_io,
.handle_irq = at91_aic_handle_irq,
.init_early = ek_init_early,
diff --git a/arch/arm/mach-at91/board-sam9g20ek.c b/arch/arm/mach-at91/board-sam9g20ek.c
index e1be6e25b380..49f075213451 100644
--- a/arch/arm/mach-at91/board-sam9g20ek.c
+++ b/arch/arm/mach-at91/board-sam9g20ek.c
@@ -410,7 +410,7 @@ static void __init ek_board_init(void)
MACHINE_START(AT91SAM9G20EK, "Atmel AT91SAM9G20-EK")
/* Maintainer: Atmel */
- .init_time = at91sam926x_pit_init,
+ .init_time = at91_init_time,
.map_io = at91_map_io,
.handle_irq = at91_aic_handle_irq,
.init_early = ek_init_early,
@@ -420,7 +420,7 @@ MACHINE_END
MACHINE_START(AT91SAM9G20EK_2MMC, "Atmel AT91SAM9G20-EK 2 MMC Slot Mod")
/* Maintainer: Atmel */
- .init_time = at91sam926x_pit_init,
+ .init_time = at91_init_time,
.map_io = at91_map_io,
.handle_irq = at91_aic_handle_irq,
.init_early = ek_init_early,
diff --git a/arch/arm/mach-at91/board-sam9m10g45ek.c b/arch/arm/mach-at91/board-sam9m10g45ek.c
index b227732b0c83..a517c7f7af92 100644
--- a/arch/arm/mach-at91/board-sam9m10g45ek.c
+++ b/arch/arm/mach-at91/board-sam9m10g45ek.c
@@ -48,7 +48,6 @@
#include <mach/system_rev.h>
#include "at91_aic.h"
-#include "at91_shdwc.h"
#include "board.h"
#include "sam9_smc.h"
#include "generic.h"
@@ -471,6 +470,8 @@ static struct platform_device *devices[] __initdata = {
static void __init ek_board_init(void)
{
+ at91_register_devices();
+
/* Serial */
/* DGBU on ttyS0. (Rx & Tx only) */
at91_register_uart(0, 0, 0);
@@ -517,7 +518,7 @@ static void __init ek_board_init(void)
MACHINE_START(AT91SAM9M10G45EK, "Atmel AT91SAM9M10G45-EK")
/* Maintainer: Atmel */
- .init_time = at91sam926x_pit_init,
+ .init_time = at91_init_time,
.map_io = at91_map_io,
.handle_irq = at91_aic_handle_irq,
.init_early = ek_init_early,
diff --git a/arch/arm/mach-at91/board-sam9rlek.c b/arch/arm/mach-at91/board-sam9rlek.c
index b64648b4a1fc..8bca329b0293 100644
--- a/arch/arm/mach-at91/board-sam9rlek.c
+++ b/arch/arm/mach-at91/board-sam9rlek.c
@@ -35,7 +35,6 @@
#include "at91_aic.h"
-#include "at91_shdwc.h"
#include "board.h"
#include "sam9_smc.h"
#include "generic.h"
@@ -292,6 +291,8 @@ static void __init ek_add_device_buttons(void) {}
static void __init ek_board_init(void)
{
+ at91_register_devices();
+
/* Serial */
/* DBGU on ttyS0. (Rx & Tx only) */
at91_register_uart(0, 0, 0);
@@ -323,7 +324,7 @@ static void __init ek_board_init(void)
MACHINE_START(AT91SAM9RLEK, "Atmel AT91SAM9RL-EK")
/* Maintainer: Atmel */
- .init_time = at91sam926x_pit_init,
+ .init_time = at91_init_time,
.map_io = at91_map_io,
.handle_irq = at91_aic_handle_irq,
.init_early = ek_init_early,
diff --git a/arch/arm/mach-at91/board-snapper9260.c b/arch/arm/mach-at91/board-snapper9260.c
index 1b870e6def0c..b4aff840a1a0 100644
--- a/arch/arm/mach-at91/board-snapper9260.c
+++ b/arch/arm/mach-at91/board-snapper9260.c
@@ -154,6 +154,8 @@ static void __init snapper9260_add_device_nand(void)
static void __init snapper9260_board_init(void)
{
+ at91_register_devices();
+
at91_add_device_i2c(snapper9260_i2c_devices,
ARRAY_SIZE(snapper9260_i2c_devices));
@@ -178,7 +180,7 @@ static void __init snapper9260_board_init(void)
}
MACHINE_START(SNAPPER_9260, "Bluewater Systems Snapper 9260/9G20 module")
- .init_time = at91sam926x_pit_init,
+ .init_time = at91_init_time,
.map_io = at91_map_io,
.handle_irq = at91_aic_handle_irq,
.init_early = snapper9260_init_early,
diff --git a/arch/arm/mach-at91/board-stamp9g20.c b/arch/arm/mach-at91/board-stamp9g20.c
index 3b575036ff96..e825641a1dee 100644
--- a/arch/arm/mach-at91/board-stamp9g20.c
+++ b/arch/arm/mach-at91/board-stamp9g20.c
@@ -275,7 +275,7 @@ static void __init stamp9g20evb_board_init(void)
MACHINE_START(PORTUXG20, "taskit PortuxG20")
/* Maintainer: taskit GmbH */
- .init_time = at91sam926x_pit_init,
+ .init_time = at91_init_time,
.map_io = at91_map_io,
.handle_irq = at91_aic_handle_irq,
.init_early = stamp9g20_init_early,
@@ -285,7 +285,7 @@ MACHINE_END
MACHINE_START(STAMP9G20, "taskit Stamp9G20")
/* Maintainer: taskit GmbH */
- .init_time = at91sam926x_pit_init,
+ .init_time = at91_init_time,
.map_io = at91_map_io,
.handle_irq = at91_aic_handle_irq,
.init_early = stamp9g20_init_early,
diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c
index 034529d801b2..d66f102c352a 100644
--- a/arch/arm/mach-at91/clock.c
+++ b/arch/arm/mach-at91/clock.c
@@ -962,6 +962,7 @@ static int __init at91_clock_reset(void)
}
at91_pmc_write(AT91_PMC_SCDR, scdr);
+ at91_pmc_write(AT91_PMC_PCDR, pcdr);
if (cpu_is_sama5d3())
at91_pmc_write(AT91_PMC_PCDR1, pcdr1);
diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h
index 631fa3b8c16d..81959cf4a137 100644
--- a/arch/arm/mach-at91/generic.h
+++ b/arch/arm/mach-at91/generic.h
@@ -8,12 +8,16 @@
* published by the Free Software Foundation.
*/
+#ifndef _AT91_GENERIC_H
+#define _AT91_GENERIC_H
+
#include <linux/clkdev.h>
#include <linux/of.h>
#include <linux/reboot.h>
/* Map io */
extern void __init at91_map_io(void);
+extern void __init at91_alt_map_io(void);
extern void __init at91_init_sram(int bank, unsigned long base,
unsigned int length);
@@ -37,12 +41,15 @@ extern int __init at91_aic5_of_init(struct device_node *node,
extern void __init at91_sysirq_mask_rtc(u32 rtc_base);
extern void __init at91_sysirq_mask_rtt(u32 rtt_base);
+ /* Devices */
+extern void __init at91_register_devices(void);
/* Timer */
+extern void __init at91_init_time(void);
extern void at91rm9200_ioremap_st(u32 addr);
extern void at91rm9200_timer_init(void);
extern void at91sam926x_ioremap_pit(u32 addr);
-extern void at91sam926x_pit_init(void);
+extern void at91sam926x_pit_init(int irq);
extern void at91x40_timer_init(void);
/* Clocks */
@@ -62,14 +69,6 @@ extern void at91_irq_resume(void);
/* idle */
extern void at91sam9_idle(void);
-/* reset */
-extern void at91_ioremap_rstc(u32 base_addr);
-extern void at91sam9_alt_restart(enum reboot_mode, const char *);
-extern void at91sam9g45_restart(enum reboot_mode, const char *);
-
-/* shutdown */
-extern void at91_ioremap_shdwc(u32 base_addr);
-
/* Matrix */
extern void at91_ioremap_matrix(u32 base_addr);
@@ -90,3 +89,5 @@ extern int __init at91_gpio_of_irq_setup(struct device_node *node,
struct device_node *parent);
extern u32 at91_get_extern_irq(void);
+
+#endif /* _AT91_GENERIC_H */
diff --git a/arch/arm/mach-at91/include/mach/at91_pio.h b/arch/arm/mach-at91/include/mach/at91_pio.h
index 732b11c37f1a..7b7366253ceb 100644
--- a/arch/arm/mach-at91/include/mach/at91_pio.h
+++ b/arch/arm/mach-at91/include/mach/at91_pio.h
@@ -71,4 +71,10 @@
#define ABCDSR_PERIPH_C 0x2
#define ABCDSR_PERIPH_D 0x3
+#define SAMA5D3_PIO_DRIVER1 0x118 /*PIO Driver 1 register offset*/
+#define SAMA5D3_PIO_DRIVER2 0x11C /*PIO Driver 2 register offset*/
+
+#define AT91SAM9X5_PIO_DRIVER1 0x114 /*PIO Driver 1 register offset*/
+#define AT91SAM9X5_PIO_DRIVER2 0x118 /*PIO Driver 2 register offset*/
+
#endif
diff --git a/arch/arm/mach-at91/include/mach/cpu.h b/arch/arm/mach-at91/include/mach/cpu.h
index 86c71debab5b..b27e9ca65653 100644
--- a/arch/arm/mach-at91/include/mach/cpu.h
+++ b/arch/arm/mach-at91/include/mach/cpu.h
@@ -36,7 +36,7 @@
#define ARCH_ID_AT91M40807 0x14080745
#define ARCH_ID_AT91R40008 0x44000840
-#define ARCH_ID_SAMA5D3 0x8A5C07C0
+#define ARCH_ID_SAMA5 0x8A5C07C0
#define ARCH_EXID_AT91SAM9M11 0x00000001
#define ARCH_EXID_AT91SAM9M10 0x00000002
@@ -49,12 +49,19 @@
#define ARCH_EXID_AT91SAM9G25 0x00000003
#define ARCH_EXID_AT91SAM9X25 0x00000004
+#define ARCH_EXID_SAMA5D3 0x00004300
#define ARCH_EXID_SAMA5D31 0x00444300
#define ARCH_EXID_SAMA5D33 0x00414300
#define ARCH_EXID_SAMA5D34 0x00414301
#define ARCH_EXID_SAMA5D35 0x00584300
#define ARCH_EXID_SAMA5D36 0x00004301
+#define ARCH_EXID_SAMA5D4 0x00000007
+#define ARCH_EXID_SAMA5D41 0x00000001
+#define ARCH_EXID_SAMA5D42 0x00000002
+#define ARCH_EXID_SAMA5D43 0x00000003
+#define ARCH_EXID_SAMA5D44 0x00000004
+
#define ARCH_FAMILY_AT91X92 0x09200000
#define ARCH_FAMILY_AT91SAM9 0x01900000
#define ARCH_FAMILY_AT91SAM9XE 0x02900000
@@ -86,6 +93,9 @@ enum at91_soc_type {
/* SAMA5D3 */
AT91_SOC_SAMA5D3,
+ /* SAMA5D4 */
+ AT91_SOC_SAMA5D4,
+
/* Unknown type */
AT91_SOC_UNKNOWN,
};
@@ -108,6 +118,10 @@ enum at91_soc_subtype {
AT91_SOC_SAMA5D31, AT91_SOC_SAMA5D33, AT91_SOC_SAMA5D34,
AT91_SOC_SAMA5D35, AT91_SOC_SAMA5D36,
+ /* SAMA5D4 */
+ AT91_SOC_SAMA5D41, AT91_SOC_SAMA5D42, AT91_SOC_SAMA5D43,
+ AT91_SOC_SAMA5D44,
+
/* No subtype for this SoC */
AT91_SOC_SUBTYPE_NONE,
@@ -211,6 +225,12 @@ static inline int at91_soc_is_detected(void)
#define cpu_is_sama5d3() (0)
#endif
+#ifdef CONFIG_SOC_SAMA5D4
+#define cpu_is_sama5d4() (at91_soc_initdata.type == AT91_SOC_SAMA5D4)
+#else
+#define cpu_is_sama5d4() (0)
+#endif
+
/*
* Since this is ARM, we will never run on any AVR32 CPU. But these
* definitions may reduce clutter in common drivers.
diff --git a/arch/arm/mach-at91/include/mach/debug-macro.S b/arch/arm/mach-at91/include/mach/debug-macro.S
index c6bb9e2d9baa..2103a90f2261 100644
--- a/arch/arm/mach-at91/include/mach/debug-macro.S
+++ b/arch/arm/mach-at91/include/mach/debug-macro.S
@@ -16,8 +16,11 @@
#if defined(CONFIG_AT91_DEBUG_LL_DBGU0)
#define AT91_DBGU AT91_BASE_DBGU0
-#else
+#elif defined(CONFIG_AT91_DEBUG_LL_DBGU1)
#define AT91_DBGU AT91_BASE_DBGU1
+#else
+/* On sama5d4, use USART3 as low level serial console */
+#define AT91_DBGU SAMA5D4_BASE_USART3
#endif
.macro addruart, rp, rv, tmp
diff --git a/arch/arm/mach-at91/include/mach/hardware.h b/arch/arm/mach-at91/include/mach/hardware.h
index 56338245653a..c13797352688 100644
--- a/arch/arm/mach-at91/include/mach/hardware.h
+++ b/arch/arm/mach-at91/include/mach/hardware.h
@@ -19,8 +19,10 @@
/* DBGU base */
/* rm9200, 9260/9g20, 9261/9g10, 9rl */
#define AT91_BASE_DBGU0 0xfffff200
-/* 9263, 9g45 */
+/* 9263, 9g45, sama5d3 */
#define AT91_BASE_DBGU1 0xffffee00
+/* sama5d4 */
+#define AT91_BASE_DBGU2 0xfc069000
#if defined(CONFIG_ARCH_AT91X40)
#include <mach/at91x40.h>
@@ -34,6 +36,7 @@
#include <mach/at91sam9x5.h>
#include <mach/at91sam9n12.h>
#include <mach/sama5d3.h>
+#include <mach/sama5d4.h>
/*
* On all at91 except rm9200 and x40 have the System Controller starts
@@ -47,9 +50,15 @@
* and map the same memory space
*/
#define AT91_BASE_SYS 0xffffc000
+
#endif
/*
+ * On sama5d4 there is no system controller, we map some needed peripherals
+ */
+#define AT91_ALT_BASE_SYS 0xfc069000
+
+/*
* On all at91 have the Advanced Interrupt Controller starts at address
* 0xfffff000 and the Power Management Controller starts at 0xfffffc00
*/
@@ -69,23 +78,35 @@
*/
#define AT91_IO_PHYS_BASE 0xFFF78000
#define AT91_IO_VIRT_BASE IOMEM(0xFF000000 - AT91_IO_SIZE)
+
+/*
+ * On sama5d4, remap the peripherals from address 0xFC069000 .. 0xFC06F000
+ * to 0xFB069000 .. 0xFB06F000. (24Kb)
+ */
+#define AT91_ALT_IO_PHYS_BASE AT91_ALT_BASE_SYS
+#define AT91_ALT_IO_VIRT_BASE IOMEM(0xFB069000)
#else
/*
* Identity mapping for the non MMU case.
*/
#define AT91_IO_PHYS_BASE AT91_BASE_SYS
#define AT91_IO_VIRT_BASE IOMEM(AT91_IO_PHYS_BASE)
+
+#define AT91_ALT_IO_PHYS_BASE AT91_ALT_BASE_SYS
+#define AT91_ALT_IO_VIRT_BASE IOMEM(AT91_ALT_BASE_SYS)
#endif
#define AT91_IO_SIZE (0xFFFFFFFF - AT91_IO_PHYS_BASE + 1)
/* Convert a physical IO address to virtual IO address */
#define AT91_IO_P2V(x) ((x) - AT91_IO_PHYS_BASE + AT91_IO_VIRT_BASE)
+#define AT91_ALT_IO_P2V(x) ((x) - AT91_ALT_IO_PHYS_BASE + AT91_ALT_IO_VIRT_BASE)
/*
* Virtual to Physical Address mapping for IO devices.
*/
#define AT91_VA_BASE_SYS AT91_IO_P2V(AT91_BASE_SYS)
+#define AT91_ALT_VA_BASE_SYS AT91_ALT_IO_P2V(AT91_ALT_BASE_SYS)
/* Internal SRAM is mapped below the IO devices */
#define AT91_SRAM_MAX SZ_1M
diff --git a/arch/arm/mach-at91/include/mach/sama5d4.h b/arch/arm/mach-at91/include/mach/sama5d4.h
new file mode 100644
index 000000000000..f256a45d9854
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/sama5d4.h
@@ -0,0 +1,33 @@
+/*
+ * Chip-specific header file for the SAMA5D4 family
+ *
+ * Copyright (C) 2013 Atmel Corporation,
+ * Nicolas Ferre <nicolas.ferre@atmel.com>
+ *
+ * Common definitions.
+ * Based on SAMA5D4 datasheet.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#ifndef SAMA5D4_H
+#define SAMA5D4_H
+
+/*
+ * User Peripheral physical base addresses.
+ */
+#define SAMA5D4_BASE_USART3 0xfc00c000 /* (USART3 non-secure) Base Address */
+#define SAMA5D4_BASE_PMC 0xf0018000 /* (PMC) Base Address */
+#define SAMA5D4_BASE_MPDDRC 0xf0010000 /* (MPDDRC) Base Address */
+#define SAMA5D4_BASE_PIOD 0xfc068000 /* (PIOD) Base Address */
+
+/* Some other peripherals */
+#define SAMA5D4_BASE_SYS2 SAMA5D4_BASE_PIOD
+
+/*
+ * Internal Memory.
+ */
+#define SAMA5D4_NS_SRAM_BASE 0x00210000 /* Internal SRAM base address Non-Secure */
+#define SAMA5D4_NS_SRAM_SIZE (64 * SZ_1K) /* Internal SRAM size Non-Secure part (64Kb) */
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/uncompress.h b/arch/arm/mach-at91/include/mach/uncompress.h
index 4bb644f8e87c..acb2d890ad7e 100644
--- a/arch/arm/mach-at91/include/mach/uncompress.h
+++ b/arch/arm/mach-at91/include/mach/uncompress.h
@@ -94,7 +94,7 @@ static const u32 uarts_sam9x5[] = {
0,
};
-static const u32 uarts_sama5[] = {
+static const u32 uarts_sama5d3[] = {
AT91_BASE_DBGU1,
SAMA5D3_BASE_USART0,
SAMA5D3_BASE_USART1,
@@ -103,6 +103,12 @@ static const u32 uarts_sama5[] = {
0,
};
+static const u32 uarts_sama5d4[] = {
+ AT91_BASE_DBGU2,
+ SAMA5D4_BASE_USART3,
+ 0,
+};
+
static inline const u32* decomp_soc_detect(void __iomem *dbgu_base)
{
u32 cidr, socid;
@@ -134,8 +140,14 @@ static inline const u32* decomp_soc_detect(void __iomem *dbgu_base)
case ARCH_ID_AT91SAM9X5:
return uarts_sam9x5;
- case ARCH_ID_SAMA5D3:
- return uarts_sama5;
+ case ARCH_ID_SAMA5:
+ cidr = __raw_readl(dbgu_base + AT91_DBGU_EXID);
+ if (cidr & ARCH_EXID_SAMA5D3)
+ return uarts_sama5d3;
+ else if (cidr & ARCH_EXID_SAMA5D4)
+ return uarts_sama5d4;
+
+ break;
}
/* at91sam9g10 */
@@ -156,9 +168,10 @@ static inline void arch_decomp_setup(void)
const u32* usarts;
usarts = decomp_soc_detect((void __iomem *)AT91_BASE_DBGU0);
-
if (!usarts)
usarts = decomp_soc_detect((void __iomem *)AT91_BASE_DBGU1);
+ if (!usarts)
+ usarts = decomp_soc_detect((void __iomem *)AT91_BASE_DBGU2);
if (!usarts) {
at91_uart = NULL;
return;
diff --git a/arch/arm/mach-at91/irq.c b/arch/arm/mach-at91/irq.c
index 3d192c5aee66..cdb3ec9efd2b 100644
--- a/arch/arm/mach-at91/irq.c
+++ b/arch/arm/mach-at91/irq.c
@@ -48,11 +48,6 @@ void __iomem *at91_aic_base;
static struct irq_domain *at91_aic_domain;
static struct device_node *at91_aic_np;
static unsigned int n_irqs = NR_AIC_IRQS;
-static unsigned long at91_aic_caps = 0;
-
-/* AIC5 introduces a Source Select Register */
-#define AT91_AIC_CAP_AIC5 (1 << 0)
-#define has_aic5() (at91_aic_caps & AT91_AIC_CAP_AIC5)
#ifdef CONFIG_PM
@@ -92,50 +87,14 @@ static int at91_aic_set_wake(struct irq_data *d, unsigned value)
void at91_irq_suspend(void)
{
- int bit = -1;
-
- if (has_aic5()) {
- /* disable enabled irqs */
- while ((bit = find_next_bit(backups, n_irqs, bit + 1)) < n_irqs) {
- at91_aic_write(AT91_AIC5_SSR,
- bit & AT91_AIC5_INTSEL_MSK);
- at91_aic_write(AT91_AIC5_IDCR, 1);
- }
- /* enable wakeup irqs */
- bit = -1;
- while ((bit = find_next_bit(wakeups, n_irqs, bit + 1)) < n_irqs) {
- at91_aic_write(AT91_AIC5_SSR,
- bit & AT91_AIC5_INTSEL_MSK);
- at91_aic_write(AT91_AIC5_IECR, 1);
- }
- } else {
- at91_aic_write(AT91_AIC_IDCR, *backups);
- at91_aic_write(AT91_AIC_IECR, *wakeups);
- }
+ at91_aic_write(AT91_AIC_IDCR, *backups);
+ at91_aic_write(AT91_AIC_IECR, *wakeups);
}
void at91_irq_resume(void)
{
- int bit = -1;
-
- if (has_aic5()) {
- /* disable wakeup irqs */
- while ((bit = find_next_bit(wakeups, n_irqs, bit + 1)) < n_irqs) {
- at91_aic_write(AT91_AIC5_SSR,
- bit & AT91_AIC5_INTSEL_MSK);
- at91_aic_write(AT91_AIC5_IDCR, 1);
- }
- /* enable irqs disabled for suspend */
- bit = -1;
- while ((bit = find_next_bit(backups, n_irqs, bit + 1)) < n_irqs) {
- at91_aic_write(AT91_AIC5_SSR,
- bit & AT91_AIC5_INTSEL_MSK);
- at91_aic_write(AT91_AIC5_IECR, 1);
- }
- } else {
- at91_aic_write(AT91_AIC_IDCR, *wakeups);
- at91_aic_write(AT91_AIC_IECR, *backups);
- }
+ at91_aic_write(AT91_AIC_IDCR, *wakeups);
+ at91_aic_write(AT91_AIC_IECR, *backups);
}
#else
@@ -169,21 +128,6 @@ at91_aic_handle_irq(struct pt_regs *regs)
handle_IRQ(irqnr, regs);
}
-asmlinkage void __exception_irq_entry
-at91_aic5_handle_irq(struct pt_regs *regs)
-{
- u32 irqnr;
- u32 irqstat;
-
- irqnr = at91_aic_read(AT91_AIC5_IVR);
- irqstat = at91_aic_read(AT91_AIC5_ISR);
-
- if (!irqstat)
- at91_aic_write(AT91_AIC5_EOICR, 0);
- else
- handle_IRQ(irqnr, regs);
-}
-
static void at91_aic_mask_irq(struct irq_data *d)
{
/* Disable interrupt on AIC */
@@ -192,15 +136,6 @@ static void at91_aic_mask_irq(struct irq_data *d)
clear_backup(d->hwirq);
}
-static void __maybe_unused at91_aic5_mask_irq(struct irq_data *d)
-{
- /* Disable interrupt on AIC5 */
- at91_aic_write(AT91_AIC5_SSR, d->hwirq & AT91_AIC5_INTSEL_MSK);
- at91_aic_write(AT91_AIC5_IDCR, 1);
- /* Update ISR cache */
- clear_backup(d->hwirq);
-}
-
static void at91_aic_unmask_irq(struct irq_data *d)
{
/* Enable interrupt on AIC */
@@ -209,15 +144,6 @@ static void at91_aic_unmask_irq(struct irq_data *d)
set_backup(d->hwirq);
}
-static void __maybe_unused at91_aic5_unmask_irq(struct irq_data *d)
-{
- /* Enable interrupt on AIC5 */
- at91_aic_write(AT91_AIC5_SSR, d->hwirq & AT91_AIC5_INTSEL_MSK);
- at91_aic_write(AT91_AIC5_IECR, 1);
- /* Update ISR cache */
- set_backup(d->hwirq);
-}
-
static void at91_aic_eoi(struct irq_data *d)
{
/*
@@ -227,11 +153,6 @@ static void at91_aic_eoi(struct irq_data *d)
at91_aic_write(AT91_AIC_EOICR, 0);
}
-static void __maybe_unused at91_aic5_eoi(struct irq_data *d)
-{
- at91_aic_write(AT91_AIC5_EOICR, 0);
-}
-
static unsigned long *at91_extern_irq;
u32 at91_get_extern_irq(void)
@@ -282,16 +203,8 @@ static int at91_aic_set_type(struct irq_data *d, unsigned type)
if (srctype < 0)
return srctype;
- if (has_aic5()) {
- at91_aic_write(AT91_AIC5_SSR,
- d->hwirq & AT91_AIC5_INTSEL_MSK);
- smr = at91_aic_read(AT91_AIC5_SMR) & ~AT91_AIC_SRCTYPE;
- at91_aic_write(AT91_AIC5_SMR, smr | srctype);
- } else {
- smr = at91_aic_read(AT91_AIC_SMR(d->hwirq))
- & ~AT91_AIC_SRCTYPE;
- at91_aic_write(AT91_AIC_SMR(d->hwirq), smr | srctype);
- }
+ smr = at91_aic_read(AT91_AIC_SMR(d->hwirq)) & ~AT91_AIC_SRCTYPE;
+ at91_aic_write(AT91_AIC_SMR(d->hwirq), smr | srctype);
return 0;
}
@@ -331,177 +244,6 @@ static void __init at91_aic_hw_init(unsigned int spu_vector)
at91_aic_write(AT91_AIC_ICCR, 0xFFFFFFFF);
}
-static void __init __maybe_unused at91_aic5_hw_init(unsigned int spu_vector)
-{
- int i;
-
- /*
- * Perform 8 End Of Interrupt Command to make sure AIC
- * will not Lock out nIRQ
- */
- for (i = 0; i < 8; i++)
- at91_aic_write(AT91_AIC5_EOICR, 0);
-
- /*
- * Spurious Interrupt ID in Spurious Vector Register.
- * When there is no current interrupt, the IRQ Vector Register
- * reads the value stored in AIC_SPU
- */
- at91_aic_write(AT91_AIC5_SPU, spu_vector);
-
- /* No debugging in AIC: Debug (Protect) Control Register */
- at91_aic_write(AT91_AIC5_DCR, 0);
-
- /* Disable and clear all interrupts initially */
- for (i = 0; i < n_irqs; i++) {
- at91_aic_write(AT91_AIC5_SSR, i & AT91_AIC5_INTSEL_MSK);
- at91_aic_write(AT91_AIC5_IDCR, 1);
- at91_aic_write(AT91_AIC5_ICCR, 1);
- }
-}
-
-#if defined(CONFIG_OF)
-static unsigned int *at91_aic_irq_priorities;
-
-static int at91_aic_irq_map(struct irq_domain *h, unsigned int virq,
- irq_hw_number_t hw)
-{
- /* Put virq number in Source Vector Register */
- at91_aic_write(AT91_AIC_SVR(hw), virq);
-
- /* Active Low interrupt, with priority */
- at91_aic_write(AT91_AIC_SMR(hw),
- AT91_AIC_SRCTYPE_LOW | at91_aic_irq_priorities[hw]);
-
- irq_set_chip_and_handler(virq, &at91_aic_chip, handle_fasteoi_irq);
- set_irq_flags(virq, IRQF_VALID | IRQF_PROBE);
-
- return 0;
-}
-
-static int at91_aic5_irq_map(struct irq_domain *h, unsigned int virq,
- irq_hw_number_t hw)
-{
- at91_aic_write(AT91_AIC5_SSR, hw & AT91_AIC5_INTSEL_MSK);
-
- /* Put virq number in Source Vector Register */
- at91_aic_write(AT91_AIC5_SVR, virq);
-
- /* Active Low interrupt, with priority */
- at91_aic_write(AT91_AIC5_SMR,
- AT91_AIC_SRCTYPE_LOW | at91_aic_irq_priorities[hw]);
-
- irq_set_chip_and_handler(virq, &at91_aic_chip, handle_fasteoi_irq);
- set_irq_flags(virq, IRQF_VALID | IRQF_PROBE);
-
- return 0;
-}
-
-static int at91_aic_irq_domain_xlate(struct irq_domain *d, struct device_node *ctrlr,
- const u32 *intspec, unsigned int intsize,
- irq_hw_number_t *out_hwirq, unsigned int *out_type)
-{
- if (WARN_ON(intsize < 3))
- return -EINVAL;
- if (WARN_ON(intspec[0] >= n_irqs))
- return -EINVAL;
- if (WARN_ON((intspec[2] < AT91_AIC_IRQ_MIN_PRIORITY)
- || (intspec[2] > AT91_AIC_IRQ_MAX_PRIORITY)))
- return -EINVAL;
-
- *out_hwirq = intspec[0];
- *out_type = intspec[1] & IRQ_TYPE_SENSE_MASK;
- at91_aic_irq_priorities[*out_hwirq] = intspec[2];
-
- return 0;
-}
-
-static struct irq_domain_ops at91_aic_irq_ops = {
- .map = at91_aic_irq_map,
- .xlate = at91_aic_irq_domain_xlate,
-};
-
-int __init at91_aic_of_common_init(struct device_node *node,
- struct device_node *parent)
-{
- struct property *prop;
- const __be32 *p;
- u32 val;
-
- at91_extern_irq = kzalloc(BITS_TO_LONGS(n_irqs)
- * sizeof(*at91_extern_irq), GFP_KERNEL);
- if (!at91_extern_irq)
- return -ENOMEM;
-
- if (at91_aic_pm_init()) {
- kfree(at91_extern_irq);
- return -ENOMEM;
- }
-
- at91_aic_irq_priorities = kzalloc(n_irqs
- * sizeof(*at91_aic_irq_priorities),
- GFP_KERNEL);
- if (!at91_aic_irq_priorities)
- return -ENOMEM;
-
- at91_aic_base = of_iomap(node, 0);
- at91_aic_np = node;
-
- at91_aic_domain = irq_domain_add_linear(at91_aic_np, n_irqs,
- &at91_aic_irq_ops, NULL);
- if (!at91_aic_domain)
- panic("Unable to add AIC irq domain (DT)\n");
-
- of_property_for_each_u32(node, "atmel,external-irqs", prop, p, val) {
- if (val >= n_irqs)
- pr_warn("AIC: external irq %d >= %d skip it\n",
- val, n_irqs);
- else
- set_bit(val, at91_extern_irq);
- }
-
- irq_set_default_host(at91_aic_domain);
-
- return 0;
-}
-
-int __init at91_aic_of_init(struct device_node *node,
- struct device_node *parent)
-{
- int err;
-
- err = at91_aic_of_common_init(node, parent);
- if (err)
- return err;
-
- at91_aic_hw_init(n_irqs);
-
- return 0;
-}
-
-int __init at91_aic5_of_init(struct device_node *node,
- struct device_node *parent)
-{
- int err;
-
- at91_aic_caps |= AT91_AIC_CAP_AIC5;
- n_irqs = NR_AIC5_IRQS;
- at91_aic_chip.irq_ack = at91_aic5_mask_irq;
- at91_aic_chip.irq_mask = at91_aic5_mask_irq;
- at91_aic_chip.irq_unmask = at91_aic5_unmask_irq;
- at91_aic_chip.irq_eoi = at91_aic5_eoi;
- at91_aic_irq_ops.map = at91_aic5_irq_map;
-
- err = at91_aic_of_common_init(node, parent);
- if (err)
- return err;
-
- at91_aic5_hw_init(n_irqs);
-
- return 0;
-}
-#endif
-
/*
* Initialize the AIC interrupt controller.
*/
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index e95554532987..4073ab7f38f3 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -34,79 +34,8 @@
#include "pm.h"
#include "gpio.h"
-/*
- * Show the reason for the previous system reset.
- */
-
-#include "at91_rstc.h"
-#include "at91_shdwc.h"
-
static void (*at91_pm_standby)(void);
-static void __init show_reset_status(void)
-{
- static char reset[] __initdata = "reset";
-
- static char general[] __initdata = "general";
- static char wakeup[] __initdata = "wakeup";
- static char watchdog[] __initdata = "watchdog";
- static char software[] __initdata = "software";
- static char user[] __initdata = "user";
- static char unknown[] __initdata = "unknown";
-
- static char signal[] __initdata = "signal";
- static char rtc[] __initdata = "rtc";
- static char rtt[] __initdata = "rtt";
- static char restore[] __initdata = "power-restored";
-
- char *reason, *r2 = reset;
- u32 reset_type, wake_type;
-
- if (!at91_shdwc_base || !at91_rstc_base)
- return;
-
- reset_type = at91_rstc_read(AT91_RSTC_SR) & AT91_RSTC_RSTTYP;
- wake_type = at91_shdwc_read(AT91_SHDW_SR);
-
- switch (reset_type) {
- case AT91_RSTC_RSTTYP_GENERAL:
- reason = general;
- break;
- case AT91_RSTC_RSTTYP_WAKEUP:
- /* board-specific code enabled the wakeup sources */
- reason = wakeup;
-
- /* "wakeup signal" */
- if (wake_type & AT91_SHDW_WAKEUP0)
- r2 = signal;
- else {
- r2 = reason;
- if (wake_type & AT91_SHDW_RTTWK) /* rtt wakeup */
- reason = rtt;
- else if (wake_type & AT91_SHDW_RTCWK) /* rtc wakeup */
- reason = rtc;
- else if (wake_type == 0) /* power-restored wakeup */
- reason = restore;
- else /* unknown wakeup */
- reason = unknown;
- }
- break;
- case AT91_RSTC_RSTTYP_WATCHDOG:
- reason = watchdog;
- break;
- case AT91_RSTC_RSTTYP_SOFTWARE:
- reason = software;
- break;
- case AT91_RSTC_RSTTYP_USER:
- reason = user;
- break;
- default:
- reason = unknown;
- break;
- }
- pr_info("AT91: Starting after %s %s\n", reason, r2);
-}
-
static int at91_pm_valid_state(suspend_state_t state)
{
switch (state) {
@@ -206,16 +135,19 @@ static int at91_pm_enter(suspend_state_t state)
at91_pinctrl_gpio_suspend();
else
at91_gpio_suspend();
- at91_irq_suspend();
- pr_debug("AT91: PM - wake mask %08x, pm state %d\n",
- /* remember all the always-wake irqs */
- (at91_pmc_read(AT91_PMC_PCSR)
- | (1 << AT91_ID_FIQ)
- | (1 << AT91_ID_SYS)
- | (at91_get_extern_irq()))
- & at91_aic_read(AT91_AIC_IMR),
- state);
+ if (IS_ENABLED(CONFIG_OLD_IRQ_AT91) && at91_aic_base) {
+ at91_irq_suspend();
+
+ pr_debug("AT91: PM - wake mask %08x, pm state %d\n",
+ /* remember all the always-wake irqs */
+ (at91_pmc_read(AT91_PMC_PCSR)
+ | (1 << AT91_ID_FIQ)
+ | (1 << AT91_ID_SYS)
+ | (at91_get_extern_irq()))
+ & at91_aic_read(AT91_AIC_IMR),
+ state);
+ }
switch (state) {
/*
@@ -280,12 +212,17 @@ static int at91_pm_enter(suspend_state_t state)
goto error;
}
- pr_debug("AT91: PM - wakeup %08x\n",
- at91_aic_read(AT91_AIC_IPR) & at91_aic_read(AT91_AIC_IMR));
+ if (IS_ENABLED(CONFIG_OLD_IRQ_AT91) && at91_aic_base)
+ pr_debug("AT91: PM - wakeup %08x\n",
+ at91_aic_read(AT91_AIC_IPR) &
+ at91_aic_read(AT91_AIC_IMR));
error:
target_state = PM_SUSPEND_ON;
- at91_irq_resume();
+
+ if (IS_ENABLED(CONFIG_OLD_IRQ_AT91) && at91_aic_base)
+ at91_irq_resume();
+
if (of_have_populated_dt())
at91_pinctrl_gpio_resume();
else
@@ -338,7 +275,6 @@ static int __init at91_pm_init(void)
suspend_set_ops(&at91_pm_ops);
- show_reset_status();
return 0;
}
arch_initcall(at91_pm_init);
diff --git a/arch/arm/mach-at91/sama5d4.c b/arch/arm/mach-at91/sama5d4.c
new file mode 100644
index 000000000000..7638509639f4
--- /dev/null
+++ b/arch/arm/mach-at91/sama5d4.c
@@ -0,0 +1,64 @@
+/*
+ * Chip-specific setup code for the SAMA5D4 family
+ *
+ * Copyright (C) 2013 Atmel Corporation,
+ * Nicolas Ferre <nicolas.ferre@atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include <linux/module.h>
+#include <linux/dma-mapping.h>
+#include <linux/clk/at91_pmc.h>
+
+#include <asm/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <mach/sama5d4.h>
+#include <mach/cpu.h>
+#include <mach/hardware.h>
+
+#include "soc.h"
+#include "generic.h"
+#include "sam9_smc.h"
+
+/* --------------------------------------------------------------------
+ * Processor initialization
+ * -------------------------------------------------------------------- */
+static struct map_desc at91_io_desc[] __initdata = {
+ {
+ .virtual = (unsigned long)AT91_ALT_IO_P2V(SAMA5D4_BASE_MPDDRC),
+ .pfn = __phys_to_pfn(SAMA5D4_BASE_MPDDRC),
+ .length = SZ_512,
+ .type = MT_DEVICE,
+ },
+ {
+ .virtual = (unsigned long)AT91_ALT_IO_P2V(SAMA5D4_BASE_PMC),
+ .pfn = __phys_to_pfn(SAMA5D4_BASE_PMC),
+ .length = SZ_512,
+ .type = MT_DEVICE,
+ },
+ { /* On sama5d4, we use USART3 as serial console */
+ .virtual = (unsigned long)AT91_ALT_IO_P2V(SAMA5D4_BASE_USART3),
+ .pfn = __phys_to_pfn(SAMA5D4_BASE_USART3),
+ .length = SZ_256,
+ .type = MT_DEVICE,
+ },
+ { /* A bunch of peripheral with fine grained IO space */
+ .virtual = (unsigned long)AT91_ALT_IO_P2V(SAMA5D4_BASE_SYS2),
+ .pfn = __phys_to_pfn(SAMA5D4_BASE_SYS2),
+ .length = SZ_2K,
+ .type = MT_DEVICE,
+ },
+};
+
+
+static void __init sama5d4_map_io(void)
+{
+ iotable_init(at91_io_desc, ARRAY_SIZE(at91_io_desc));
+ at91_init_sram(0, SAMA5D4_NS_SRAM_BASE, SAMA5D4_NS_SRAM_SIZE);
+}
+
+AT91_SOC_START(sama5d4)
+ .map_io = sama5d4_map_io,
+AT91_SOC_END
diff --git a/arch/arm/mach-at91/setup.c b/arch/arm/mach-at91/setup.c
index f7a07a58ebb6..961079250b83 100644
--- a/arch/arm/mach-at91/setup.c
+++ b/arch/arm/mach-at91/setup.c
@@ -5,6 +5,8 @@
* Under GPLv2
*/
+#define pr_fmt(fmt) "AT91: " fmt
+
#include <linux/module.h>
#include <linux/io.h>
#include <linux/mm.h>
@@ -20,7 +22,6 @@
#include <mach/cpu.h>
#include <mach/at91_dbgu.h>
-#include "at91_shdwc.h"
#include "soc.h"
#include "generic.h"
#include "pm.h"
@@ -37,7 +38,7 @@ void __init at91rm9200_set_type(int type)
else
at91_soc_initdata.subtype = AT91_SOC_RM9200_BGA;
- pr_info("AT91: filled in soc subtype: %s\n",
+ pr_info("filled in soc subtype: %s\n",
at91_get_soc_subtype(&at91_soc_initdata));
}
@@ -49,7 +50,8 @@ void __init at91_init_irq_default(void)
void __init at91_init_interrupts(unsigned int *priority)
{
/* Initialize the AIC interrupt controller */
- at91_aic_init(priority, at91_boot_soc.extern_irq);
+ if (IS_ENABLED(CONFIG_OLD_IRQ_AT91))
+ at91_aic_init(priority, at91_boot_soc.extern_irq);
/* Enable GPIO interrupts */
at91_gpio_irq_setup();
@@ -66,7 +68,7 @@ void __init at91_ioremap_ramc(int id, u32 addr, u32 size)
}
at91_ramc_base[id] = ioremap(addr, size);
if (!at91_ramc_base[id])
- panic("Impossible to ioremap ramc.%d 0x%x\n", id, addr);
+ panic(pr_fmt("Impossible to ioremap ramc.%d 0x%x\n"), id, addr);
}
static struct map_desc sram_desc[2] __initdata;
@@ -83,7 +85,7 @@ void __init at91_init_sram(int bank, unsigned long base, unsigned int length)
desc->length = length;
desc->type = MT_MEMORY_RWX_NONCACHED;
- pr_info("AT91: sram at 0x%lx of 0x%x mapped at 0x%lx\n",
+ pr_info("sram at 0x%lx of 0x%x mapped at 0x%lx\n",
base, length, desc->virtual);
iotable_init(desc, 1);
@@ -96,6 +98,13 @@ static struct map_desc at91_io_desc __initdata __maybe_unused = {
.type = MT_DEVICE,
};
+static struct map_desc at91_alt_io_desc __initdata __maybe_unused = {
+ .virtual = (unsigned long)AT91_ALT_VA_BASE_SYS,
+ .pfn = __phys_to_pfn(AT91_ALT_BASE_SYS),
+ .length = 24 * SZ_1K,
+ .type = MT_DEVICE,
+};
+
static void __init soc_detect(u32 dbgu_base)
{
u32 cidr, socid;
@@ -158,9 +167,12 @@ static void __init soc_detect(u32 dbgu_base)
at91_boot_soc = at91sam9n12_soc;
break;
- case ARCH_ID_SAMA5D3:
- at91_soc_initdata.type = AT91_SOC_SAMA5D3;
- at91_boot_soc = sama5d3_soc;
+ case ARCH_ID_SAMA5:
+ at91_soc_initdata.exid = __raw_readl(AT91_IO_P2V(dbgu_base) + AT91_DBGU_EXID);
+ if (at91_soc_initdata.exid & ARCH_EXID_SAMA5D3) {
+ at91_soc_initdata.type = AT91_SOC_SAMA5D3;
+ at91_boot_soc = sama5d3_soc;
+ }
break;
}
@@ -183,7 +195,8 @@ static void __init soc_detect(u32 dbgu_base)
at91_soc_initdata.cidr = cidr;
/* sub version of soc */
- at91_soc_initdata.exid = __raw_readl(AT91_IO_P2V(dbgu_base) + AT91_DBGU_EXID);
+ if (!at91_soc_initdata.exid)
+ at91_soc_initdata.exid = __raw_readl(AT91_IO_P2V(dbgu_base) + AT91_DBGU_EXID);
if (at91_soc_initdata.type == AT91_SOC_SAM9G45) {
switch (at91_soc_initdata.exid) {
@@ -240,6 +253,54 @@ static void __init soc_detect(u32 dbgu_base)
}
}
+static void __init alt_soc_detect(u32 dbgu_base)
+{
+ u32 cidr, socid;
+
+ /* SoC ID */
+ cidr = __raw_readl(AT91_ALT_IO_P2V(dbgu_base) + AT91_DBGU_CIDR);
+ socid = cidr & ~AT91_CIDR_VERSION;
+
+ switch (socid) {
+ case ARCH_ID_SAMA5:
+ at91_soc_initdata.exid = __raw_readl(AT91_ALT_IO_P2V(dbgu_base) + AT91_DBGU_EXID);
+ if (at91_soc_initdata.exid & ARCH_EXID_SAMA5D3) {
+ at91_soc_initdata.type = AT91_SOC_SAMA5D3;
+ at91_boot_soc = sama5d3_soc;
+ } else if (at91_soc_initdata.exid & ARCH_EXID_SAMA5D4) {
+ at91_soc_initdata.type = AT91_SOC_SAMA5D4;
+ at91_boot_soc = sama5d4_soc;
+ }
+ break;
+ }
+
+ if (!at91_soc_is_detected())
+ return;
+
+ at91_soc_initdata.cidr = cidr;
+
+ /* sub version of soc */
+ if (!at91_soc_initdata.exid)
+ at91_soc_initdata.exid = __raw_readl(AT91_ALT_IO_P2V(dbgu_base) + AT91_DBGU_EXID);
+
+ if (at91_soc_initdata.type == AT91_SOC_SAMA5D4) {
+ switch (at91_soc_initdata.exid) {
+ case ARCH_EXID_SAMA5D41:
+ at91_soc_initdata.subtype = AT91_SOC_SAMA5D41;
+ break;
+ case ARCH_EXID_SAMA5D42:
+ at91_soc_initdata.subtype = AT91_SOC_SAMA5D42;
+ break;
+ case ARCH_EXID_SAMA5D43:
+ at91_soc_initdata.subtype = AT91_SOC_SAMA5D43;
+ break;
+ case ARCH_EXID_SAMA5D44:
+ at91_soc_initdata.subtype = AT91_SOC_SAMA5D44;
+ break;
+ }
+ }
+}
+
static const char *soc_name[] = {
[AT91_SOC_RM9200] = "at91rm9200",
[AT91_SOC_SAM9260] = "at91sam9260",
@@ -252,6 +313,7 @@ static const char *soc_name[] = {
[AT91_SOC_SAM9X5] = "at91sam9x5",
[AT91_SOC_SAM9N12] = "at91sam9n12",
[AT91_SOC_SAMA5D3] = "sama5d3",
+ [AT91_SOC_SAMA5D4] = "sama5d4",
[AT91_SOC_UNKNOWN] = "Unknown",
};
@@ -279,6 +341,10 @@ static const char *soc_subtype_name[] = {
[AT91_SOC_SAMA5D34] = "sama5d34",
[AT91_SOC_SAMA5D35] = "sama5d35",
[AT91_SOC_SAMA5D36] = "sama5d36",
+ [AT91_SOC_SAMA5D41] = "sama5d41",
+ [AT91_SOC_SAMA5D42] = "sama5d42",
+ [AT91_SOC_SAMA5D43] = "sama5d43",
+ [AT91_SOC_SAMA5D44] = "sama5d44",
[AT91_SOC_SUBTYPE_NONE] = "None",
[AT91_SOC_SUBTYPE_UNKNOWN] = "Unknown",
};
@@ -302,43 +368,44 @@ void __init at91_map_io(void)
soc_detect(AT91_BASE_DBGU1);
if (!at91_soc_is_detected())
- panic("AT91: Impossible to detect the SOC type");
+ panic(pr_fmt("Impossible to detect the SOC type"));
- pr_info("AT91: Detected soc type: %s\n",
+ pr_info("Detected soc type: %s\n",
at91_get_soc_type(&at91_soc_initdata));
if (at91_soc_initdata.subtype != AT91_SOC_SUBTYPE_NONE)
- pr_info("AT91: Detected soc subtype: %s\n",
+ pr_info("Detected soc subtype: %s\n",
at91_get_soc_subtype(&at91_soc_initdata));
if (!at91_soc_is_enabled())
- panic("AT91: Soc not enabled");
+ panic(pr_fmt("Soc not enabled"));
if (at91_boot_soc.map_io)
at91_boot_soc.map_io();
}
-void __iomem *at91_shdwc_base = NULL;
-
-static void at91sam9_poweroff(void)
+void __init at91_alt_map_io(void)
{
- at91_shdwc_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW);
-}
+ /* Map peripherals */
+ iotable_init(&at91_alt_io_desc, 1);
-void __init at91_ioremap_shdwc(u32 base_addr)
-{
- at91_shdwc_base = ioremap(base_addr, 16);
- if (!at91_shdwc_base)
- panic("Impossible to ioremap at91_shdwc_base\n");
- pm_power_off = at91sam9_poweroff;
-}
+ at91_soc_initdata.type = AT91_SOC_UNKNOWN;
+ at91_soc_initdata.subtype = AT91_SOC_SUBTYPE_UNKNOWN;
-void __iomem *at91_rstc_base;
+ alt_soc_detect(AT91_BASE_DBGU2);
+ if (!at91_soc_is_detected())
+ panic("AT91: Impossible to detect the SOC type");
-void __init at91_ioremap_rstc(u32 base_addr)
-{
- at91_rstc_base = ioremap(base_addr, 16);
- if (!at91_rstc_base)
- panic("Impossible to ioremap at91_rstc_base\n");
+ pr_info("AT91: Detected soc type: %s\n",
+ at91_get_soc_type(&at91_soc_initdata));
+ if (at91_soc_initdata.subtype != AT91_SOC_SUBTYPE_NONE)
+ pr_info("AT91: Detected soc subtype: %s\n",
+ at91_get_soc_subtype(&at91_soc_initdata));
+
+ if (!at91_soc_is_enabled())
+ panic("AT91: Soc not enabled");
+
+ if (at91_boot_soc.map_io)
+ at91_boot_soc.map_io();
}
void __iomem *at91_matrix_base;
@@ -348,42 +415,15 @@ void __init at91_ioremap_matrix(u32 base_addr)
{
at91_matrix_base = ioremap(base_addr, 512);
if (!at91_matrix_base)
- panic("Impossible to ioremap at91_matrix_base\n");
+ panic(pr_fmt("Impossible to ioremap at91_matrix_base\n"));
}
#if defined(CONFIG_OF) && !defined(CONFIG_ARCH_AT91X40)
-static struct of_device_id rstc_ids[] = {
- { .compatible = "atmel,at91sam9260-rstc", .data = at91sam9_alt_restart },
- { .compatible = "atmel,at91sam9g45-rstc", .data = at91sam9g45_restart },
- { /*sentinel*/ }
-};
-
-static void at91_dt_rstc(void)
-{
- struct device_node *np;
- const struct of_device_id *of_id;
-
- np = of_find_matching_node(NULL, rstc_ids);
- if (!np)
- panic("unable to find compatible rstc node in dtb\n");
-
- at91_rstc_base = of_iomap(np, 0);
- if (!at91_rstc_base)
- panic("unable to map rstc cpu registers\n");
-
- of_id = of_match_node(rstc_ids, np);
- if (!of_id)
- panic("AT91: rtsc no restart function available\n");
-
- arm_pm_restart = of_id->data;
-
- of_node_put(np);
-}
-
static struct of_device_id ramc_ids[] = {
{ .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 = at91_ddr_standby },
{ /*sentinel*/ }
};
@@ -391,100 +431,29 @@ static void at91_dt_ramc(void)
{
struct device_node *np;
const struct of_device_id *of_id;
+ int idx = 0;
+ const void *standby = NULL;
- np = of_find_matching_node(NULL, ramc_ids);
- if (!np)
- panic("unable to find compatible ram controller node in dtb\n");
-
- at91_ramc_base[0] = of_iomap(np, 0);
- if (!at91_ramc_base[0])
- panic("unable to map ramc[0] cpu registers\n");
- /* the controller may have 2 banks */
- at91_ramc_base[1] = of_iomap(np, 1);
+ for_each_matching_node_and_match(np, ramc_ids, &of_id) {
+ at91_ramc_base[idx] = of_iomap(np, 0);
+ if (!at91_ramc_base[idx])
+ panic(pr_fmt("unable to map ramc[%d] cpu registers\n"), idx);
- of_id = of_match_node(ramc_ids, np);
- if (!of_id)
- pr_warn("AT91: ramc no standby function available\n");
- else
- at91_pm_set_standby(of_id->data);
+ if (!standby)
+ standby = of_id->data;
- of_node_put(np);
-}
-
-static struct of_device_id shdwc_ids[] = {
- { .compatible = "atmel,at91sam9260-shdwc", },
- { .compatible = "atmel,at91sam9rl-shdwc", },
- { .compatible = "atmel,at91sam9x5-shdwc", },
- { /*sentinel*/ }
-};
-
-static const char *shdwc_wakeup_modes[] = {
- [AT91_SHDW_WKMODE0_NONE] = "none",
- [AT91_SHDW_WKMODE0_HIGH] = "high",
- [AT91_SHDW_WKMODE0_LOW] = "low",
- [AT91_SHDW_WKMODE0_ANYLEVEL] = "any",
-};
-
-const int at91_dtget_shdwc_wakeup_mode(struct device_node *np)
-{
- const char *pm;
- int err, i;
-
- err = of_property_read_string(np, "atmel,wakeup-mode", &pm);
- if (err < 0)
- return AT91_SHDW_WKMODE0_ANYLEVEL;
-
- for (i = 0; i < ARRAY_SIZE(shdwc_wakeup_modes); i++)
- if (!strcasecmp(pm, shdwc_wakeup_modes[i]))
- return i;
-
- return -ENODEV;
-}
-
-static void at91_dt_shdwc(void)
-{
- struct device_node *np;
- int wakeup_mode;
- u32 reg;
- u32 mode = 0;
-
- np = of_find_matching_node(NULL, shdwc_ids);
- if (!np) {
- pr_debug("AT91: unable to find compatible shutdown (shdwc) controller node in dtb\n");
- return;
+ idx++;
}
- at91_shdwc_base = of_iomap(np, 0);
- if (!at91_shdwc_base)
- panic("AT91: unable to map shdwc cpu registers\n");
-
- wakeup_mode = at91_dtget_shdwc_wakeup_mode(np);
- if (wakeup_mode < 0) {
- pr_warn("AT91: shdwc unknown wakeup mode\n");
- goto end;
- }
+ if (!idx)
+ panic(pr_fmt("unable to find compatible ram controller node in dtb\n"));
- if (!of_property_read_u32(np, "atmel,wakeup-counter", &reg)) {
- if (reg > AT91_SHDW_CPTWK0_MAX) {
- pr_warn("AT91: shdwc wakeup counter 0x%x > 0x%x reduce it to 0x%x\n",
- reg, AT91_SHDW_CPTWK0_MAX, AT91_SHDW_CPTWK0_MAX);
- reg = AT91_SHDW_CPTWK0_MAX;
- }
- mode |= AT91_SHDW_CPTWK0_(reg);
+ if (!standby) {
+ pr_warn("ramc no standby function available\n");
+ return;
}
- if (of_property_read_bool(np, "atmel,wakeup-rtc-timer"))
- mode |= AT91_SHDW_RTCWKEN;
-
- if (of_property_read_bool(np, "atmel,wakeup-rtt-timer"))
- mode |= AT91_SHDW_RTTWKEN;
-
- at91_shdwc_write(AT91_SHDW_MR, wakeup_mode | mode);
-
-end:
- pm_power_off = at91sam9_poweroff;
-
- of_node_put(np);
+ at91_pm_set_standby(standby);
}
void __init at91rm9200_dt_initialize(void)
@@ -503,9 +472,7 @@ void __init at91rm9200_dt_initialize(void)
void __init at91_dt_initialize(void)
{
- at91_dt_rstc();
at91_dt_ramc();
- at91_dt_shdwc();
/* Init clock subsystem */
at91_dt_clock_init();
@@ -533,3 +500,13 @@ void __init at91_initialize(unsigned long main_clock)
pinctrl_provide_dummies();
}
+
+void __init at91_register_devices(void)
+{
+ at91_boot_soc.register_devices();
+}
+
+void __init at91_init_time(void)
+{
+ at91_boot_soc.init_time();
+}
diff --git a/arch/arm/mach-at91/soc.h b/arch/arm/mach-at91/soc.h
index a1e1482c6da8..9a8fd97a8bef 100644
--- a/arch/arm/mach-at91/soc.h
+++ b/arch/arm/mach-at91/soc.h
@@ -11,7 +11,9 @@ struct at91_init_soc {
void (*map_io)(void);
void (*ioremap_registers)(void);
void (*register_clocks)(void);
+ void (*register_devices)(void);
void (*init)(void);
+ void (*init_time)(void);
};
extern struct at91_init_soc at91_boot_soc;
@@ -24,6 +26,7 @@ extern struct at91_init_soc at91sam9rl_soc;
extern struct at91_init_soc at91sam9x5_soc;
extern struct at91_init_soc at91sam9n12_soc;
extern struct at91_init_soc sama5d3_soc;
+extern struct at91_init_soc sama5d4_soc;
#define AT91_SOC_START(_name) \
struct at91_init_soc __initdata _name##_soc \
@@ -74,3 +77,7 @@ static inline int at91_soc_is_enabled(void)
#if !defined(CONFIG_SOC_SAMA5D3)
#define sama5d3_soc at91_boot_soc
#endif
+
+#if !defined(CONFIG_SOC_SAMA5D4)
+#define sama5d4_soc at91_boot_soc
+#endif