Commit 8f4b4794 authored by Ludovic Desroches's avatar Ludovic Desroches Committed by Nicolas Ferre

ARM: at91: introduce SAMA5 support

This patch introduces the SAMA5 support and a generic board file for SAMA5
devices. It also updates the PMC driver to manage clock division which is a
requirement since some peripherals can't work at the bus frequency on SAMA5.
Signed-off-by: default avatarLudovic Desroches <ludovic.desroches@atmel.com>
Signed-off-by: default avatarJean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Signed-off-by: default avatarNicolas Ferre <nicolas.ferre@atmel.com>
parent 8f0cdcc5
...@@ -29,6 +29,14 @@ config SOC_AT91SAM9 ...@@ -29,6 +29,14 @@ config SOC_AT91SAM9
select MULTI_IRQ_HANDLER select MULTI_IRQ_HANDLER
select SPARSE_IRQ select SPARSE_IRQ
config SOC_SAMA5
bool
select AT91_SAM9_TIME
select CPU_V7
select GENERIC_CLOCKEVENTS
select MULTI_IRQ_HANDLER
select SPARSE_IRQ
menu "Atmel AT91 System-on-Chip" menu "Atmel AT91 System-on-Chip"
choice choice
...@@ -41,10 +49,27 @@ config SOC_SAM_V4_V5 ...@@ -41,10 +49,27 @@ config SOC_SAM_V4_V5
Select this if you are using one of Atmel's AT91SAM9, AT91RM9200 Select this if you are using one of Atmel's AT91SAM9, AT91RM9200
or AT91X40 SoC. or AT91X40 SoC.
config SOC_SAM_V7
bool "Cortex A5"
help
Select this if you are using one of Atmel's SAMA5D3 SoC.
endchoice endchoice
comment "Atmel AT91 Processor" comment "Atmel AT91 Processor"
if SOC_SAM_V7
config SOC_SAMA5D3
bool "SAMA5D3 family"
depends on SOC_SAM_V7
select SOC_SAMA5
select HAVE_FB_ATMEL
select HAVE_AT91_DBGU1
help
Select this if you are using one of Atmel's SAMA5D3 family SoC.
This support covers SAMA5D31, SAMA5D33, SAMA5D34, SAMA5D35.
endif
if SOC_SAM_V4_V5 if SOC_SAM_V4_V5
config SOC_AT91RM9200 config SOC_AT91RM9200
bool "AT91RM9200" bool "AT91RM9200"
...@@ -134,6 +159,14 @@ config MACH_AT91SAM9_DT ...@@ -134,6 +159,14 @@ config MACH_AT91SAM9_DT
Select this if you want to experiment device-tree with Select this if you want to experiment device-tree with
an Atmel Evaluation Kit. an Atmel Evaluation Kit.
config MACH_SAMA5_DT
bool "Atmel SAMA5 Evaluation Kits with device-tree support"
depends on SOC_SAMA5
select USE_OF
help
Select this if you want to experiment device-tree with
an Atmel Evaluation Kit.
# ---------------------------------------------------------- # ----------------------------------------------------------
comment "AT91 Feature Selections" comment "AT91 Feature Selections"
......
...@@ -22,6 +22,7 @@ obj-$(CONFIG_SOC_AT91SAM9G45) += at91sam9g45.o ...@@ -22,6 +22,7 @@ obj-$(CONFIG_SOC_AT91SAM9G45) += at91sam9g45.o
obj-$(CONFIG_SOC_AT91SAM9N12) += at91sam9n12.o obj-$(CONFIG_SOC_AT91SAM9N12) += at91sam9n12.o
obj-$(CONFIG_SOC_AT91SAM9X5) += at91sam9x5.o obj-$(CONFIG_SOC_AT91SAM9X5) += at91sam9x5.o
obj-$(CONFIG_SOC_AT91SAM9RL) += at91sam9rl.o obj-$(CONFIG_SOC_AT91SAM9RL) += at91sam9rl.o
obj-$(CONFIG_SOC_SAMA5D3) += sama5d3.o
obj-$(CONFIG_ARCH_AT91RM9200) += at91rm9200_devices.o obj-$(CONFIG_ARCH_AT91RM9200) += at91rm9200_devices.o
obj-$(CONFIG_ARCH_AT91SAM9260) += at91sam9260_devices.o obj-$(CONFIG_ARCH_AT91SAM9260) += at91sam9260_devices.o
...@@ -91,6 +92,9 @@ obj-$(CONFIG_MACH_AT91SAM9M10G45EK) += board-sam9m10g45ek.o ...@@ -91,6 +92,9 @@ obj-$(CONFIG_MACH_AT91SAM9M10G45EK) += board-sam9m10g45ek.o
obj-$(CONFIG_MACH_AT91RM9200_DT) += board-dt-rm9200.o obj-$(CONFIG_MACH_AT91RM9200_DT) += board-dt-rm9200.o
obj-$(CONFIG_MACH_AT91SAM9_DT) += board-dt-sam9.o obj-$(CONFIG_MACH_AT91SAM9_DT) += board-dt-sam9.o
# SAMA5 board with device-tree
obj-$(CONFIG_MACH_SAMA5_DT) += board-dt-sama5.o
# AT91X40 board-specific support # AT91X40 board-specific support
obj-$(CONFIG_MACH_AT91EB01) += board-eb01.o obj-$(CONFIG_MACH_AT91EB01) += board-eb01.o
......
/*
* Setup code for SAMA5 Evaluation Kits with Device Tree support
*
* Copyright (C) 2013 Atmel,
* 2013 Ludovic Desroches <ludovic.desroches@atmel.com>
*
* Licensed under GPLv2 or later.
*/
#include <linux/types.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/gpio.h>
#include <linux/micrel_phy.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/phy.h>
#include <asm/setup.h>
#include <asm/irq.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
#include "at91_aic.h"
#include "generic.h"
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;
#define GMII_RCCPSR 260
#define GMII_RRDPSR 261
#define GMII_ERCR 11
#define GMII_ERDWR 12
/* Set delay values */
value = GMII_RCCPSR | 0x8000;
phy_write(phy, GMII_ERCR, value);
value = 0xF2F4;
phy_write(phy, GMII_ERDWR, value);
value = GMII_RRDPSR | 0x8000;
phy_write(phy, GMII_ERCR, value);
value = 0x2222;
phy_write(phy, GMII_ERDWR, value);
return 0;
}
static void __init sama5_dt_device_init(void)
{
if (of_machine_is_compatible("atmel,sama5d3xcm"))
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 = {
"atmel,sama5",
NULL
};
DT_MACHINE_START(sama5_dt, "Atmel SAMA5 (Device Tree)")
/* Maintainer: Atmel */
.init_time = at91sam926x_pit_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
...@@ -54,7 +54,10 @@ EXPORT_SYMBOL_GPL(at91_pmc_base); ...@@ -54,7 +54,10 @@ EXPORT_SYMBOL_GPL(at91_pmc_base);
*/ */
#define cpu_has_utmi() ( cpu_is_at91sam9rl() \ #define cpu_has_utmi() ( cpu_is_at91sam9rl() \
|| cpu_is_at91sam9g45() \ || cpu_is_at91sam9g45() \
|| cpu_is_at91sam9x5()) || cpu_is_at91sam9x5() \
|| cpu_is_sama5d3())
#define cpu_has_1056M_plla() (cpu_is_sama5d3())
#define cpu_has_800M_plla() ( cpu_is_at91sam9g20() \ #define cpu_has_800M_plla() ( cpu_is_at91sam9g20() \
|| cpu_is_at91sam9g45() \ || cpu_is_at91sam9g45() \
...@@ -75,7 +78,8 @@ EXPORT_SYMBOL_GPL(at91_pmc_base); ...@@ -75,7 +78,8 @@ EXPORT_SYMBOL_GPL(at91_pmc_base);
|| cpu_is_at91sam9n12())) || cpu_is_at91sam9n12()))
#define cpu_has_upll() (cpu_is_at91sam9g45() \ #define cpu_has_upll() (cpu_is_at91sam9g45() \
|| cpu_is_at91sam9x5()) || cpu_is_at91sam9x5() \
|| cpu_is_sama5d3())
/* USB host HS & FS */ /* USB host HS & FS */
#define cpu_has_uhp() (!cpu_is_at91sam9rl()) #define cpu_has_uhp() (!cpu_is_at91sam9rl())
...@@ -83,18 +87,22 @@ EXPORT_SYMBOL_GPL(at91_pmc_base); ...@@ -83,18 +87,22 @@ EXPORT_SYMBOL_GPL(at91_pmc_base);
/* USB device FS only */ /* USB device FS only */
#define cpu_has_udpfs() (!(cpu_is_at91sam9rl() \ #define cpu_has_udpfs() (!(cpu_is_at91sam9rl() \
|| cpu_is_at91sam9g45() \ || cpu_is_at91sam9g45() \
|| cpu_is_at91sam9x5())) || cpu_is_at91sam9x5() \
|| cpu_is_sama5d3()))
#define cpu_has_plladiv2() (cpu_is_at91sam9g45() \ #define cpu_has_plladiv2() (cpu_is_at91sam9g45() \
|| cpu_is_at91sam9x5() \ || cpu_is_at91sam9x5() \
|| cpu_is_at91sam9n12()) || cpu_is_at91sam9n12() \
|| cpu_is_sama5d3())
#define cpu_has_mdiv3() (cpu_is_at91sam9g45() \ #define cpu_has_mdiv3() (cpu_is_at91sam9g45() \
|| cpu_is_at91sam9x5() \ || cpu_is_at91sam9x5() \
|| cpu_is_at91sam9n12()) || cpu_is_at91sam9n12() \
|| cpu_is_sama5d3())
#define cpu_has_alt_prescaler() (cpu_is_at91sam9x5() \ #define cpu_has_alt_prescaler() (cpu_is_at91sam9x5() \
|| cpu_is_at91sam9n12()) || cpu_is_at91sam9n12() \
|| cpu_is_sama5d3())
static LIST_HEAD(clocks); static LIST_HEAD(clocks);
static DEFINE_SPINLOCK(clk_lock); static DEFINE_SPINLOCK(clk_lock);
...@@ -210,10 +218,26 @@ struct clk mck = { ...@@ -210,10 +218,26 @@ struct clk mck = {
static void pmc_periph_mode(struct clk *clk, int is_on) static void pmc_periph_mode(struct clk *clk, int is_on)
{ {
if (is_on) u32 regval = 0;
at91_pmc_write(AT91_PMC_PCER, clk->pmc_mask);
else /*
at91_pmc_write(AT91_PMC_PCDR, clk->pmc_mask); * With sama5d3 devices, we are managing clock division so we have to
* use the Peripheral Control Register introduced from at91sam9x5
* devices.
*/
if (cpu_is_sama5d3()) {
regval |= AT91_PMC_PCR_CMD; /* write command */
regval |= clk->pid & AT91_PMC_PCR_PID; /* peripheral selection */
regval |= AT91_PMC_PCR_DIV(clk->div);
if (is_on)
regval |= AT91_PMC_PCR_EN; /* enable clock */
at91_pmc_write(AT91_PMC_PCR, regval);
} else {
if (is_on)
at91_pmc_write(AT91_PMC_PCER, clk->pmc_mask);
else
at91_pmc_write(AT91_PMC_PCDR, clk->pmc_mask);
}
} }
static struct clk __init *at91_css_to_clk(unsigned long css) static struct clk __init *at91_css_to_clk(unsigned long css)
...@@ -443,14 +467,18 @@ static void __init init_programmable_clock(struct clk *clk) ...@@ -443,14 +467,18 @@ static void __init init_programmable_clock(struct clk *clk)
static int at91_clk_show(struct seq_file *s, void *unused) static int at91_clk_show(struct seq_file *s, void *unused)
{ {
u32 scsr, pcsr, uckr = 0, sr; u32 scsr, pcsr, pcsr1 = 0, uckr = 0, sr;
struct clk *clk; struct clk *clk;
scsr = at91_pmc_read(AT91_PMC_SCSR); scsr = at91_pmc_read(AT91_PMC_SCSR);
pcsr = at91_pmc_read(AT91_PMC_PCSR); pcsr = at91_pmc_read(AT91_PMC_PCSR);
if (cpu_is_sama5d3())
pcsr1 = at91_pmc_read(AT91_PMC_PCSR1);
sr = at91_pmc_read(AT91_PMC_SR); sr = at91_pmc_read(AT91_PMC_SR);
seq_printf(s, "SCSR = %8x\n", scsr); seq_printf(s, "SCSR = %8x\n", scsr);
seq_printf(s, "PCSR = %8x\n", pcsr); seq_printf(s, "PCSR = %8x\n", pcsr);
if (cpu_is_sama5d3())
seq_printf(s, "PCSR1 = %8x\n", pcsr1);
seq_printf(s, "MOR = %8x\n", at91_pmc_read(AT91_CKGR_MOR)); seq_printf(s, "MOR = %8x\n", at91_pmc_read(AT91_CKGR_MOR));
seq_printf(s, "MCFR = %8x\n", at91_pmc_read(AT91_CKGR_MCFR)); seq_printf(s, "MCFR = %8x\n", at91_pmc_read(AT91_CKGR_MCFR));
seq_printf(s, "PLLA = %8x\n", at91_pmc_read(AT91_CKGR_PLLAR)); seq_printf(s, "PLLA = %8x\n", at91_pmc_read(AT91_CKGR_PLLAR));
...@@ -470,20 +498,30 @@ static int at91_clk_show(struct seq_file *s, void *unused) ...@@ -470,20 +498,30 @@ static int at91_clk_show(struct seq_file *s, void *unused)
list_for_each_entry(clk, &clocks, node) { list_for_each_entry(clk, &clocks, node) {
char *state; char *state;
if (clk->mode == pmc_sys_mode) if (clk->mode == pmc_sys_mode) {
state = (scsr & clk->pmc_mask) ? "on" : "off"; state = (scsr & clk->pmc_mask) ? "on" : "off";
else if (clk->mode == pmc_periph_mode) } else if (clk->mode == pmc_periph_mode) {
state = (pcsr & clk->pmc_mask) ? "on" : "off"; if (cpu_is_sama5d3()) {
else if (clk->mode == pmc_uckr_mode) u32 pmc_mask = 1 << (clk->pid % 32);
if (clk->pid > 31)
state = (pcsr1 & pmc_mask) ? "on" : "off";
else
state = (pcsr & pmc_mask) ? "on" : "off";
} else {
state = (pcsr & clk->pmc_mask) ? "on" : "off";
}
} else if (clk->mode == pmc_uckr_mode) {
state = (uckr & clk->pmc_mask) ? "on" : "off"; state = (uckr & clk->pmc_mask) ? "on" : "off";
else if (clk->pmc_mask) } else if (clk->pmc_mask) {
state = (sr & clk->pmc_mask) ? "on" : "off"; state = (sr & clk->pmc_mask) ? "on" : "off";
else if (clk == &clk32k || clk == &main_clk) } else if (clk == &clk32k || clk == &main_clk) {
state = "on"; state = "on";
else } else {
state = ""; state = "";
}
seq_printf(s, "%-10s users=%2d %-3s %9ld Hz %s\n", seq_printf(s, "%-10s users=%2d %-3s %9lu Hz %s\n",
clk->name, clk->users, state, clk_get_rate(clk), clk->name, clk->users, state, clk_get_rate(clk),
clk->parent ? clk->parent->name : ""); clk->parent ? clk->parent->name : "");
} }
...@@ -530,6 +568,9 @@ int __init clk_register(struct clk *clk) ...@@ -530,6 +568,9 @@ int __init clk_register(struct clk *clk)
if (clk_is_peripheral(clk)) { if (clk_is_peripheral(clk)) {
if (!clk->parent) if (!clk->parent)
clk->parent = &mck; clk->parent = &mck;
if (cpu_is_sama5d3())
clk->rate_hz = DIV_ROUND_UP(clk->parent->rate_hz,
1 << clk->div);
clk->mode = pmc_periph_mode; clk->mode = pmc_periph_mode;
} }
else if (clk_is_sys(clk)) { else if (clk_is_sys(clk)) {
...@@ -555,7 +596,11 @@ static u32 __init at91_pll_rate(struct clk *pll, u32 freq, u32 reg) ...@@ -555,7 +596,11 @@ static u32 __init at91_pll_rate(struct clk *pll, u32 freq, u32 reg)
unsigned mul, div; unsigned mul, div;
div = reg & 0xff; div = reg & 0xff;
mul = (reg >> 16) & 0x7ff; if (cpu_is_sama5d3())
mul = AT91_PMC3_MUL_GET(reg);
else
mul = AT91_PMC_MUL_GET(reg);
if (div && mul) { if (div && mul) {
freq /= div; freq /= div;
freq *= mul + 1; freq *= mul + 1;
...@@ -706,12 +751,15 @@ static int __init at91_pmc_init(unsigned long main_clock) ...@@ -706,12 +751,15 @@ static int __init at91_pmc_init(unsigned long main_clock)
/* report if PLLA is more than mildly overclocked */ /* report if PLLA is more than mildly overclocked */
plla.rate_hz = at91_pll_rate(&plla, main_clock, at91_pmc_read(AT91_CKGR_PLLAR)); plla.rate_hz = at91_pll_rate(&plla, main_clock, at91_pmc_read(AT91_CKGR_PLLAR));
if (cpu_has_300M_plla()) { if (cpu_has_1056M_plla()) {
if (plla.rate_hz > 300000000) if (plla.rate_hz > 1056000000)
pll_overclock = true; pll_overclock = true;
} else if (cpu_has_800M_plla()) { } else if (cpu_has_800M_plla()) {
if (plla.rate_hz > 800000000) if (plla.rate_hz > 800000000)
pll_overclock = true; pll_overclock = true;
} else if (cpu_has_300M_plla()) {
if (plla.rate_hz > 300000000)
pll_overclock = true;
} else if (cpu_has_240M_plla()) { } else if (cpu_has_240M_plla()) {
if (plla.rate_hz > 240000000) if (plla.rate_hz > 240000000)
pll_overclock = true; pll_overclock = true;
...@@ -872,6 +920,7 @@ int __init at91_clock_init(unsigned long main_clock) ...@@ -872,6 +920,7 @@ int __init at91_clock_init(unsigned long main_clock)
static int __init at91_clock_reset(void) static int __init at91_clock_reset(void)
{ {
unsigned long pcdr = 0; unsigned long pcdr = 0;
unsigned long pcdr1 = 0;
unsigned long scdr = 0; unsigned long scdr = 0;
struct clk *clk; struct clk *clk;
...@@ -879,8 +928,17 @@ static int __init at91_clock_reset(void) ...@@ -879,8 +928,17 @@ static int __init at91_clock_reset(void)
if (clk->users > 0) if (clk->users > 0)
continue; continue;
if (clk->mode == pmc_periph_mode) if (clk->mode == pmc_periph_mode) {
pcdr |= clk->pmc_mask; if (cpu_is_sama5d3()) {
u32 pmc_mask = 1 << (clk->pid % 32);
if (clk->pid > 31)
pcdr1 |= pmc_mask;
else
pcdr |= pmc_mask;
} else
pcdr |= clk->pmc_mask;
}
if (clk->mode == pmc_sys_mode) if (clk->mode == pmc_sys_mode)
scdr |= clk->pmc_mask; scdr |= clk->pmc_mask;
...@@ -888,8 +946,9 @@ static int __init at91_clock_reset(void) ...@@ -888,8 +946,9 @@ static int __init at91_clock_reset(void)
pr_debug("Clocks: disable unused %s\n", clk->name); pr_debug("Clocks: disable unused %s\n", clk->name);
} }
at91_pmc_write(AT91_PMC_PCDR, pcdr);
at91_pmc_write(AT91_PMC_SCDR, scdr); at91_pmc_write(AT91_PMC_SCDR, scdr);
if (cpu_is_sama5d3())
at91_pmc_write(AT91_PMC_PCDR1, pcdr1);
return 0; return 0;
} }
......
...@@ -20,7 +20,9 @@ struct clk { ...@@ -20,7 +20,9 @@ struct clk {
const char *name; /* unique clock name */ const char *name; /* unique clock name */
struct clk_lookup cl; struct clk_lookup cl;
unsigned long rate_hz; unsigned long rate_hz;
unsigned div; /* parent clock divider */
struct clk *parent; struct clk *parent;
unsigned pid; /* peripheral ID */
u32 pmc_mask; u32 pmc_mask;
void (*mode)(struct clk *, int); void (*mode)(struct clk *, int);
unsigned id:3; /* PCK0..4, or 32k/main/a/b */ unsigned id:3; /* PCK0..4, or 32k/main/a/b */
......
...@@ -75,6 +75,9 @@ extern void __iomem *at91_pmc_base; ...@@ -75,6 +75,9 @@ extern void __iomem *at91_pmc_base;
#define AT91_PMC_PLLCOUNT (0x3f << 8) /* PLL Counter */ #define AT91_PMC_PLLCOUNT (0x3f << 8) /* PLL Counter */
#define AT91_PMC_OUT (3 << 14) /* PLL Clock Frequency Range */ #define AT91_PMC_OUT (3 << 14) /* PLL Clock Frequency Range */
#define AT91_PMC_MUL (0x7ff << 16) /* PLL Multiplier */ #define AT91_PMC_MUL (0x7ff << 16) /* PLL Multiplier */
#define AT91_PMC_MUL_GET(n) ((n) >> 16 & 0x7ff)
#define AT91_PMC3_MUL (0x7f << 18) /* PLL Multiplier [SAMA5 only] */
#define AT91_PMC3_MUL_GET(n) ((n) >> 18 & 0x7f)
#define AT91_PMC_USBDIV (3 << 28) /* USB Divisor (PLLB only) */ #define AT91_PMC_USBDIV (3 << 28) /* USB Divisor (PLLB only) */
#define AT91_PMC_USBDIV_1 (0 << 28) #define AT91_PMC_USBDIV_1 (0 << 28)
#define AT91_PMC_USBDIV_2 (1 << 28) #define AT91_PMC_USBDIV_2 (1 << 28)
...@@ -167,11 +170,18 @@ extern void __iomem *at91_pmc_base; ...@@ -167,11 +170,18 @@ extern void __iomem *at91_pmc_base;
#define AT91_PMC_WPVS (0x1 << 0) /* Write Protect Violation Status */ #define AT91_PMC_WPVS (0x1 << 0) /* Write Protect Violation Status */
#define AT91_PMC_WPVSRC (0xffff << 8) /* Write Protect Violation Source */ #define AT91_PMC_WPVSRC (0xffff << 8) /* Write Protect Violation Source */
#define AT91_PMC_PCR 0x10c /* Peripheral Control Register [some SAM9] */ #define AT91_PMC_PCER1 0x100 /* Peripheral Clock Enable Register 1 [SAMA5 only]*/
#define AT91_PMC_PCDR1 0x104 /* Peripheral Clock Enable Register 1 */
#define AT91_PMC_PCSR1 0x108 /* Peripheral Clock Enable Register 1 */
#define AT91_PMC_PCR 0x10c /* Peripheral Control Register [some SAM9 and SAMA5] */
#define AT91_PMC_PCR_PID (0x3f << 0) /* Peripheral ID */ #define AT91_PMC_PCR_PID (0x3f << 0) /* Peripheral ID */
#define AT91_PMC_PCR_CMD (0x1 << 12) /* Command */ #define AT91_PMC_PCR_CMD (0x1 << 12) /* Command (read=0, write=1) */
#define AT91_PMC_PCR_DIV (0x3 << 16) /* Divisor Value */ #define AT91_PMC_PCR_DIV(n) ((n) << 16) /* Divisor Value */
#define AT91_PMC_PCRDIV(n) (((n) << 16) & AT91_PMC_PCR_DIV) #define AT91_PMC_PCR_DIV0 0x0 /* Peripheral clock is MCK */
#define AT91_PMC_PCR_DIV2 0x2 /* Peripheral clock is MCK/2 */
#define AT91_PMC_PCR_DIV4 0x4 /* Peripheral clock is MCK/4 */
#define AT91_PMC_PCR_DIV8 0x8 /* Peripheral clock is MCK/8 */
#define AT91_PMC_PCR_EN (0x1 << 28) /* Enable */ #define AT91_PMC_PCR_EN (0x1 << 28) /* Enable */
#endif #endif
...@@ -36,6 +36,8 @@ ...@@ -36,6 +36,8 @@
#define ARCH_ID_AT91M40807 0x14080745 #define ARCH_ID_AT91M40807 0x14080745
#define ARCH_ID_AT91R40008 0x44000840 #define ARCH_ID_AT91R40008 0x44000840
#define ARCH_ID_SAMA5D3 0x8A5C07C0
#define ARCH_EXID_AT91SAM9M11 0x00000001 #define ARCH_EXID_AT91SAM9M11 0x00000001
#define ARCH_EXID_AT91SAM9M10 0x00000002 #define ARCH_EXID_AT91SAM9M10 0x00000002
#define ARCH_EXID_AT91SAM9G46 0x00000003 #define ARCH_EXID_AT91SAM9G46 0x00000003
...@@ -47,6 +49,11 @@ ...@@ -47,6 +49,11 @@
#define ARCH_EXID_AT91SAM9G25 0x00000003 #define ARCH_EXID_AT91SAM9G25 0x00000003
#define ARCH_EXID_AT91SAM9X25 0x00000004 #define ARCH_EXID_AT91SAM9X25 0x00000004
#define ARCH_EXID_SAMA5D31 0x00444300
#define ARCH_EXID_SAMA5D33 0x00414300
#define ARCH_EXID_SAMA5D34 0x00414301
#define ARCH_EXID_SAMA5D35 0x00584300
#define ARCH_FAMILY_AT91X92 0x09200000 #define ARCH_FAMILY_AT91X92 0x09200000
#define ARCH_FAMILY_AT91SAM9 0x01900000 #define ARCH_FAMILY_AT91SAM9 0x01900000
#define ARCH_FAMILY_AT91SAM9XE 0x02900000 #define ARCH_FAMILY_AT91SAM9XE 0x02900000
...@@ -75,6 +82,9 @@ enum at91_soc_type { ...@@ -75,6 +82,9 @@ enum at91_soc_type {
/* SAM9N12 */ /* SAM9N12 */
AT91_SOC_SAM9N12, AT91_SOC_SAM9N12,
/* SAMA5D3 */
AT91_SOC_SAMA5D3,
/* Unknown type */ /* Unknown type */
AT91_SOC_NONE AT91_SOC_NONE
}; };
...@@ -93,6 +103,10 @@ enum at91_soc_subtype { ...@@ -93,6 +103,10 @@ enum at91_soc_subtype {
AT91_SOC_SAM9G15, AT91_SOC_SAM9G35, AT91_SOC_SAM9X35, AT91_SOC_SAM9G15, AT91_SOC_SAM9G35, AT91_SOC_SAM9X35,
AT91_SOC_SAM9G25, AT91_SOC_SAM9X25, AT91_SOC_SAM9G25, AT91_SOC_SAM9X25,
/* SAMA5D3 */
AT91_SOC_SAMA5D31, AT91_SOC_SAMA5D33, AT91_SOC_SAMA5D34,
AT91_SOC_SAMA5D35,
/* Unknown subtype */ /* Unknown subtype */
AT91_SOC_SUBTYPE_NONE AT91_SOC_SUBTYPE_NONE
}; };
...@@ -187,6 +201,12 @@ static inline int at91_soc_is_detected(void) ...@@ -187,6 +201,12 @@ static inline int at91_soc_is_detected(void)
#define cpu_is_at91sam9n12() (0) #define cpu_is_at91sam9n12() (0)
#endif #endif
#ifdef CONFIG_SOC_SAMA5D3
#define cpu_is_sama5d3() (at91_soc_initdata.type == AT91_SOC_SAMA5D3)
#else
#define cpu_is_sama5d3() (0)
#endif
/* /*
* Since this is ARM, we will never run on any AVR32 CPU. But these * Since this is ARM, we will never run on any AVR32 CPU. But these
* definitions may reduce clutter in common drivers. * definitions may reduce clutter in common drivers.
......
/*
* Chip-specific header file for the SAMA5D3 family
*
* Copyright (C) 2013 Atmel,
* 2013 Ludovic Desroches <ludovic.desroches@atmel.com>
*
* Common definitions.
* Based on SAMA5D3 datasheet.
*
* Licensed under GPLv2 or later.
*/
#ifndef SAMA5D3_H
#define SAMA5D3_H
/*
* Peripheral identifiers/interrupts.
*/
#define AT91_ID_FIQ 0 /* Advanced Interrupt Controller (FIQ) */
#define AT91_ID_SYS 1 /* System Peripherals */
#define SAMA5D3_ID_DBGU 2 /* debug Unit (usually no special interrupt line) */
#define AT91_ID_PIT 3 /* PIT */
#define SAMA5D3_ID_WDT 4 /* Watchdog Timer Interrupt */
#define SAMA5D3_ID_HSMC 5 /* Static Memory Controller */
#define SAMA5D3_ID_PIOA 6 /* PIOA */
#define SAMA5D3_ID_PIOB 7 /* PIOB */
#define SAMA5D3_ID_PIOC 8 /* PIOC */
#define SAMA5D3_ID_PIOD 9 /* PIOD */
#define SAMA5D3_ID_PIOE 10 /* PIOE */
#define SAMA5D3_ID_SMD 11 /* SMD Soft Modem */
#define SAMA5D3_ID_USART0 12 /* USART0 */
#define SAMA5D3_ID_USART1 13 /* USART1 */
#define SAMA5D3_ID_USART2 14 /* USART2 */
#define SAMA5D3_ID_USART3 15 /* USART3 */
#define SAMA5D3_ID_UART0 16 /* UART 0 */
#define SAMA5D3_ID_UART1 17 /* UART 1 */
#define SAMA5D3_ID_TWI0 18 /* Two-Wire Interface 0 */
#define SAMA5D3_ID_TWI1 19 /* Two-Wire Interface 1 */
#define SAMA5D3_ID_TWI2 20 /* Two-Wire Interface 2 */
#define SAMA5D3_ID_HSMCI0 21 /* MCI */
#define SAMA5D3_ID_HSMCI1 22 /* MCI */
#define SAMA5D3_ID_HSMCI2 23 /* MCI */
#define SAMA5D3_ID_SPI0 24 /* Serial Peripheral Interface 0 */
#define SAMA5D3_ID_SPI1 25 /* Serial Peripheral Interface 1 */
#define SAMA5D3_ID_TC0 26 /* Timer Counter 0 */
#define SAMA5D3_ID_TC1 27 /* Timer Counter 2 */
#define SAMA5D3_ID_PWM 28 /* Pulse Width Modulation Controller */
#define SAMA5D3_ID_ADC 29 /* Touch Screen ADC Controller */
#define SAMA5D3_ID_DMA0 30 /* DMA Controller 0 */
#define SAMA5D3_ID_DMA1 31 /* DMA Controller 1 */
#define SAMA5D3_ID_UHPHS 32 /* USB Host High Speed */
#define SAMA5D3_ID_UDPHS 33 /* USB Device High Speed */
#define SAMA5D3_ID_GMAC 34 /* Gigabit Ethernet MAC */
#define SAMA5D3_ID_EMAC 35 /* Ethernet MAC */
#define SAMA5D3_ID_LCDC 36 /* LCD Controller */
#define SAMA5D3_ID_ISI 37 /* Image Sensor Interface */
#define SAMA5D3_ID_SSC0 38 /* Synchronous Serial Controller 0 */
#define SAMA5D3_ID_SSC1 39 /* Synchronous Serial Controller 1 */
#define SAMA5D3_ID_CAN0 40 /* CAN Controller 0 */
#define SAMA5D3_ID_CAN1 41 /* CAN Controller 1 */
#define SAMA5D3_ID_SHA 42 /* Secure Hash Algorithm */
#define SAMA5D3_ID_AES 43 /* Advanced Encryption Standard */
#define SAMA5D3_ID_TDES 44 /* Triple Data Encryption Standard */
#define SAMA5D3_ID_TRNG 45 /* True Random Generator Number */
#define SAMA5D3_ID_IRQ0 47 /* Advanced Interrupt Controller (IRQ0) */
/*
* Internal Memory
*/
#define SAMA5D3_SRAM_BASE 0x00300000 /* Internal SRAM base address */
#define SAMA5D3_SRAM_SIZE (128 * SZ_1K) /* Internal SRAM size (128Kb) */
#endif
/*
* Chip-specific setup code for the SAMA5D3 family
*
* Copyright (C) 2013 Atmel,
* 2013 Ludovic Desroches <ludovic.desroches@atmel.com>
*
* Licensed under GPLv2 or later.
*/
#include <linux/module.h>
#include <linux/dma-mapping.h>
#include <asm/irq.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <mach/sama5d3.h>
#include <mach/at91_pmc.h>
#include <mach/cpu.h>
#include "soc.h"
#include "generic.h"
#include "clock.h"
#include "sam9_smc.h"
/* --------------------------------------------------------------------
* Clocks
* -------------------------------------------------------------------- */
/*
* The peripheral clocks.
*/
static struct clk pioA_clk = {
.name = "pioA_clk",
.pid = SAMA5D3_ID_PIOA,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk pioB_clk = {
.name = "pioB_clk",
.pid = SAMA5D3_ID_PIOB,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk pioC_clk = {
.name = "pioC_clk",
.pid = SAMA5D3_ID_PIOC,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk pioD_clk = {
.name = "pioD_clk",
.pid = SAMA5D3_ID_PIOD,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk pioE_clk = {
.name = "pioE_clk",
.pid = SAMA5D3_ID_PIOE,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk usart0_clk = {
.name = "usart0_clk",
.pid = SAMA5D3_ID_USART0,
.type = CLK_TYPE_PERIPHERAL,
.div = AT91_PMC_PCR_DIV2,
};
static struct clk usart1_clk = {
.name = "usart1_clk",
.pid = SAMA5D3_ID_USART1,
.type = CLK_TYPE_PERIPHERAL,
.div = AT91_PMC_PCR_DIV2,
};
static struct clk usart2_clk = {
.name = "usart2_clk",
.pid = SAMA5D3_ID_USART2,
.type = CLK_TYPE_PERIPHERAL,
.div = AT91_PMC_PCR_DIV2,
};
static struct clk usart3_clk = {
.name = "usart3_clk",
.pid = SAMA5D3_ID_USART3,
.type = CLK_TYPE_PERIPHERAL,
.div = AT91_PMC_PCR_DIV2,
};
static struct clk uart0_clk = {
.name = "uart0_clk",
.pid = SAMA5D3_ID_UART0,
.type = CLK_TYPE_PERIPHERAL,
.div = AT91_PMC_PCR_DIV2,
};
static struct clk uart1_clk = {
.name = "uart1_clk",
.pid = SAMA5D3_ID_UART1,
.type = CLK_TYPE_PERIPHERAL,
.div = AT91_PMC_PCR_DIV2,
};
static struct clk twi0_clk = {
.name = "twi0_clk",
.pid = SAMA5D3_ID_TWI0,
.type = CLK_TYPE_PERIPHERAL,
.div = AT91_PMC_PCR_DIV2,
};
static struct clk twi1_clk = {
.name = "twi1_clk",
.pid = SAMA5D3_ID_TWI1,
.type = CLK_TYPE_PERIPHERAL,
.div = AT91_PMC_PCR_DIV2,
};
static struct clk twi2_clk = {
.name = "twi2_clk",
.pid = SAMA5D3_ID_TWI2,
.type = CLK_TYPE_PERIPHERAL,
.div = AT91_PMC_PCR_DIV2,
};
static struct clk mmc0_clk = {
.name = "mci0_clk",
.pid = SAMA5D3_ID_HSMCI0,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk mmc1_clk = {
.name = "mci1_clk",
.pid = SAMA5D3_ID_HSMCI1,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk mmc2_clk = {
.name = "mci2_clk",
.pid = SAMA5D3_ID_HSMCI2,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk spi0_clk = {
.name = "spi0_clk",
.pid = SAMA5D3_ID_SPI0,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk spi1_clk = {
.name = "spi1_clk",
.pid = SAMA5D3_ID_SPI1,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk tcb0_clk = {
.name = "tcb0_clk",
.pid = SAMA5D3_ID_TC0,
.type = CLK_TYPE_PERIPHERAL,
.div = AT91_PMC_PCR_DIV2,
};
static struct clk tcb1_clk = {
.name = "tcb1_clk",
.pid = SAMA5D3_ID_TC1,
.type = CLK_TYPE_PERIPHERAL,
.div = AT91_PMC_PCR_DIV2,
};
static struct clk adc_clk = {
.name = "adc_clk",
.pid = SAMA5D3_ID_ADC,
.type = CLK_TYPE_PERIPHERAL,
.div = AT91_PMC_PCR_DIV2,
};
static struct clk adc_op_clk = {
.name = "adc_op_clk",
.type = CLK_TYPE_PERIPHERAL,
.rate_hz = 5000000,
};
static struct clk dma0_clk = {
.name = "dma0_clk",
.pid = SAMA5D3_ID_DMA0,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk dma1_clk = {
.name = "dma1_clk",
.pid = SAMA5D3_ID_DMA1,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk uhphs_clk = {
.name = "uhphs",
.pid = SAMA5D3_ID_UHPHS,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk udphs_clk = {
.name = "udphs_clk",
.pid = SAMA5D3_ID_UDPHS,
.type = CLK_TYPE_PERIPHERAL,
};
/* gmac only for sama5d33, sama5d34, sama5d35 */
static struct clk macb0_clk = {
.name = "macb0_clk",
.pid = SAMA5D3_ID_GMAC,
.type = CLK_TYPE_PERIPHERAL,
};
/* emac only for sama5d31, sama5d35 */
static struct clk macb1_clk = {
.name = "macb1_clk",
.pid = SAMA5D3_ID_EMAC,
.type = CLK_TYPE_PERIPHERAL,
};
/* lcd only for sama5d31, sama5d33, sama5d34 */
static struct clk lcdc_clk = {
.name = "lcdc_clk",
.pid = SAMA5D3_ID_LCDC,
.type = CLK_TYPE_PERIPHERAL,
};
/* isi only for sama5d33, sama5d35 */
static struct clk isi_clk = {
.name = "isi_clk",
.pid = SAMA5D3_ID_ISI,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk can0_clk = {
.name = "can0_clk",
.pid = SAMA5D3_ID_CAN0,
.type = CLK_TYPE_PERIPHERAL,
.div = AT91_PMC_PCR_DIV2,
};
static struct clk can1_clk = {
.name = "can1_clk",
.pid = SAMA5D3_ID_CAN1,
.type = CLK_TYPE_PERIPHERAL,
.div = AT91_PMC_PCR_DIV2,
};
static struct clk ssc0_clk = {
.name = "ssc0_clk",
.pid = SAMA5D3_ID_SSC0,
.type = CLK_TYPE_PERIPHERAL,
.div = AT91_PMC_PCR_DIV2,
};
static struct clk ssc1_clk = {
.name = "ssc1_clk",
.pid = SAMA5D3_ID_SSC1,
.type = CLK_TYPE_PERIPHERAL,
.div = AT91_PMC_PCR_DIV2,
};
static struct clk sha_clk = {
.name = "sha_clk",
.pid = SAMA5D3_ID_SHA,
.type = CLK_TYPE_PERIPHERAL,
.div = AT91_PMC_PCR_DIV8,
};
static struct clk aes_clk = {
.name = "aes_clk",
.pid = SAMA5D3_ID_AES,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk tdes_clk = {
.name = "tdes_clk",
.pid = SAMA5D3_ID_TDES,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk *periph_clocks[] __initdata = {
&pioA_clk,
&pioB_clk,
&pioC_clk,
&pioD_clk,
&pioE_clk,
&usart0_clk,
&usart1_clk,
&usart2_clk,
&usart3_clk,
&uart0_clk,
&uart1_clk,
&twi0_clk,
&twi1_clk,
&twi2_clk,
&mmc0_clk,
&mmc1_clk,
&mmc2_clk,
&spi0_clk,
&spi1_clk,
&tcb0_clk,
&tcb1_clk,
&adc_clk,
&adc_op_clk,
&dma0_clk,
&dma1_clk,
&uhphs_clk,
&udphs_clk,
&macb0_clk,
&macb1_clk,
&lcdc_clk,
&isi_clk,
&can0_clk,
&can1_clk,
&ssc0_clk,
&ssc1_clk,
&sha_clk,
&aes_clk,
&tdes_clk,
};
static struct clk pck0 = {
.name = "pck0",
.pmc_mask = AT91_PMC_PCK0,
.type = CLK_TYPE_PROGRAMMABLE,
.id = 0,
};
static struct clk pck1 = {
.name = "pck1",
.pmc_mask = AT91_PMC_PCK1,
.type = CLK_TYPE_PROGRAMMABLE,
.id = 1,
};
static struct clk pck2 = {
.name = "pck2",
.pmc_mask = AT91_PMC_PCK2,
.type = CLK_TYPE_PROGRAMMABLE,
.id = 2,
};
static struct clk_lookup periph_clocks_lookups[] = {
/* lookup table for DT entries */
CLKDEV_CON_DEV_ID("usart", "ffffee00.serial", &mck),
CLKDEV_CON_DEV_ID(NULL, "fffff200.gpio", &pioA_clk),
CLKDEV_CON_DEV_ID(NULL, "fffff400.gpio", &pioB_clk),
CLKDEV_CON_DEV_ID(NULL, "fffff600.gpio", &pioC_clk),
CLKDEV_CON_DEV_ID(NULL, "fffff800.gpio", &pioD_clk),
CLKDEV_CON_DEV_ID(NULL, "fffffa00.gpio", &pioE_clk),
CLKDEV_CON_DEV_ID("usart", "f001c000.serial", &usart0_clk),
CLKDEV_CON_DEV_ID("usart", "f0020000.serial", &usart1_clk),
CLKDEV_CON_DEV_ID("usart", "f8020000.serial", &usart2_clk),
CLKDEV_CON_DEV_ID("usart", "f8024000.serial", &usart3_clk),
CLKDEV_CON_DEV_ID(NULL, "f0014000.i2c", &twi0_clk),
CLKDEV_CON_DEV_ID(NULL, "f0018000.i2c", &twi1_clk),
CLKDEV_CON_DEV_ID(NULL, "f801c000.i2c", &twi2_clk),
CLKDEV_CON_DEV_ID("mci_clk", "f0000000.mmc", &mmc0_clk),
CLKDEV_CON_DEV_ID("mci_clk", "f8000000.mmc", &mmc1_clk),
CLKDEV_CON_DEV_ID("mci_clk", "f8004000.mmc", &mmc2_clk),
CLKDEV_CON_DEV_ID("spi_clk", "f0004000.spi", &spi0_clk),
CLKDEV_CON_DEV_ID("spi_clk", "f8008000.spi", &spi1_clk),
CLKDEV_CON_DEV_ID("t0_clk", "f0010000.timer", &tcb0_clk),
CLKDEV_CON_DEV_ID("t0_clk", "f8014000.timer", &tcb1_clk),
CLKDEV_CON_DEV_ID("tsc_clk", "f8018000.tsadcc", &adc_clk),
CLKDEV_CON_DEV_ID("dma_clk", "ffffe600.dma-controller", &dma0_clk),
CLKDEV_CON_DEV_ID("dma_clk", "ffffe800.dma-controller", &dma1_clk),
CLKDEV_CON_DEV_ID("hclk", "600000.ohci", &uhphs_clk),
CLKDEV_CON_DEV_ID("ohci_clk", "600000.ohci", &uhphs_clk),
CLKDEV_CON_DEV_ID("ehci_clk", "700000.ehci", &uhphs_clk),
CLKDEV_CON_DEV_ID("pclk", "500000.gadget", &udphs_clk),
CLKDEV_CON_DEV_ID("hclk", "500000.gadget", &utmi_clk),
CLKDEV_CON_DEV_ID("hclk", "f0028000.ethernet", &macb0_clk),
CLKDEV_CON_DEV_ID("pclk", "f0028000.ethernet", &macb0_clk),
CLKDEV_CON_DEV_ID("hclk", "f802c000.ethernet", &macb1_clk),
CLKDEV_CON_DEV_ID("pclk", "f802c000.ethernet", &macb1_clk),
CLKDEV_CON_DEV_ID("pclk", "f0008000.ssc", &ssc0_clk),
CLKDEV_CON_DEV_ID("pclk", "f000c000.ssc", &ssc1_clk),
CLKDEV_CON_DEV_ID("can_clk", "f000c000.can", &can0_clk),
CLKDEV_CON_DEV_ID("can_clk", "f8010000.can", &can1_clk),
CLKDEV_CON_DEV_ID("sha_clk", "f8034000.sha", &sha_clk),
CLKDEV_CON_DEV_ID("aes_clk", "f8038000.aes", &aes_clk),
CLKDEV_CON_DEV_ID("tdes_clk", "f803c000.tdes", &tdes_clk),
};
static void __init sama5d3_register_clocks(void)
{
int i;
for (i = 0; i < ARRAY_SIZE(periph_clocks); i++)
clk_register(periph_clocks[i]);
clkdev_add_table(periph_clocks_lookups,
ARRAY_SIZE(periph_clocks_lookups));
clk_register(&pck0);
clk_register(&pck1);
clk_register(&pck2);
}
/* --------------------------------------------------------------------
* AT91SAM9x5 processor initialization
* -------------------------------------------------------------------- */
static void __init sama5d3_map_io(void)
{
at91_init_sram(0, SAMA5D3_SRAM_BASE, SAMA5D3_SRAM_SIZE);
}
AT91_SOC_START(sama5d3)
.map_io = sama5d3_map_io,
.register_clocks = sama5d3_register_clocks,
AT91_SOC_END
...@@ -151,6 +151,11 @@ static void __init soc_detect(u32 dbgu_base) ...@@ -151,6 +151,11 @@ static void __init soc_detect(u32 dbgu_base)
at91_soc_initdata.type = AT91_SOC_SAM9N12; at91_soc_initdata.type = AT91_SOC_SAM9N12;
at91_boot_soc = at91sam9n12_soc; at91_boot_soc = at91sam9n12_soc;
break; break;
case ARCH_ID_SAMA5D3:
at91_soc_initdata.type = AT91_SOC_SAMA5D3;
at91_boot_soc = sama5d3_soc;
break;
} }
/* at91sam9g10 */ /* at91sam9g10 */
...@@ -206,6 +211,23 @@ static void __init soc_detect(u32 dbgu_base) ...@@ -206,6 +211,23 @@ static void __init soc_detect(u32 dbgu_base)
break; break;
} }
} }
if (at91_soc_initdata.type == AT91_SOC_SAMA5D3) {
switch (at91_soc_initdata.exid) {
case ARCH_EXID_SAMA5D31:
at91_soc_initdata.subtype = AT91_SOC_SAMA5D31;
break;
case ARCH_EXID_SAMA5D33:
at91_soc_initdata.subtype = AT91_SOC_SAMA5D33;
break;
case ARCH_EXID_SAMA5D34:
at91_soc_initdata.subtype = AT91_SOC_SAMA5D34;
break;
case ARCH_EXID_SAMA5D35:
at91_soc_initdata.subtype = AT91_SOC_SAMA5D35;
break;
}
}
} }
static const char *soc_name[] = { static const char *soc_name[] = {
...@@ -219,6 +241,7 @@ static const char *soc_name[] = { ...@@ -219,6 +241,7 @@ static const char *soc_name[] = {
[AT91_SOC_SAM9RL] = "at91sam9rl", [AT91_SOC_SAM9RL] = "at91sam9rl",
[AT91_SOC_SAM9X5] = "at91sam9x5", [AT91_SOC_SAM9X5] = "at91sam9x5",
[AT91_SOC_SAM9N12] = "at91sam9n12", [AT91_SOC_SAM9N12] = "at91sam9n12",
[AT91_SOC_SAMA5D3] = "sama5d3",
[AT91_SOC_NONE] = "Unknown" [AT91_SOC_NONE] = "Unknown"
}; };
...@@ -241,6 +264,10 @@ static const char *soc_subtype_name[] = { ...@@ -241,6 +264,10 @@ static const char *soc_subtype_name[] = {
[AT91_SOC_SAM9X35] = "at91sam9x35", [AT91_SOC_SAM9X35] = "at91sam9x35",
[AT91_SOC_SAM9G25] = "at91sam9g25", [AT91_SOC_SAM9G25] = "at91sam9g25",
[AT91_SOC_SAM9X25] = "at91sam9x25", [AT91_SOC_SAM9X25] = "at91sam9x25",
[AT91_SOC_SAMA5D31] = "sama5d31",
[AT91_SOC_SAMA5D33] = "sama5d33",
[AT91_SOC_SAMA5D34] = "sama5d34",
[AT91_SOC_SAMA5D35] = "sama5d35",
[AT91_SOC_SUBTYPE_NONE] = "Unknown" [AT91_SOC_SUBTYPE_NONE] = "Unknown"
}; };
......
...@@ -22,6 +22,7 @@ extern struct at91_init_soc at91sam9g45_soc; ...@@ -22,6 +22,7 @@ extern struct at91_init_soc at91sam9g45_soc;
extern struct at91_init_soc at91sam9rl_soc; extern struct at91_init_soc at91sam9rl_soc;
extern struct at91_init_soc at91sam9x5_soc; extern struct at91_init_soc at91sam9x5_soc;
extern struct at91_init_soc at91sam9n12_soc; extern struct at91_init_soc at91sam9n12_soc;
extern struct at91_init_soc sama5d3_soc;
#define AT91_SOC_START(_name) \ #define AT91_SOC_START(_name) \
struct at91_init_soc __initdata _name##_soc \ struct at91_init_soc __initdata _name##_soc \
...@@ -68,3 +69,7 @@ static inline int at91_soc_is_enabled(void) ...@@ -68,3 +69,7 @@ static inline int at91_soc_is_enabled(void)
#if !defined(CONFIG_SOC_AT91SAM9N12) #if !defined(CONFIG_SOC_AT91SAM9N12)
#define at91sam9n12_soc at91_boot_soc #define at91sam9n12_soc at91_boot_soc
#endif #endif
#if !defined(CONFIG_SOC_SAMA5D3)
#define sama5d3_soc at91_boot_soc
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment