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: Ludovic Desroches <ludovic.desroches@atmel.com> Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
This commit is contained in:
Родитель
8f0cdcc570
Коммит
8f4b47949f
|
@ -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
|
||||||
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
|
||||||
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
|
||||||
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
|
||||||
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
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
/*
|
||||||
|
* 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);
|
||||||
*/
|
*/
|
||||||
#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);
|
||||||
|| 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);
|
||||||
/* 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 = {
|
||||||
|
|
||||||
static void pmc_periph_mode(struct clk *clk, int is_on)
|
static void pmc_periph_mode(struct clk *clk, int is_on)
|
||||||
{
|
{
|
||||||
|
u32 regval = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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)
|
if (is_on)
|
||||||
at91_pmc_write(AT91_PMC_PCER, clk->pmc_mask);
|
at91_pmc_write(AT91_PMC_PCER, clk->pmc_mask);
|
||||||
else
|
else
|
||||||
at91_pmc_write(AT91_PMC_PCDR, clk->pmc_mask);
|
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)
|
||||||
|
|
||||||
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)
|
||||||
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);
|
||||||
state = (uckr & clk->pmc_mask) ? "on" : "off";
|
|
||||||
else if (clk->pmc_mask)
|
|
||||||
state = (sr & clk->pmc_mask) ? "on" : "off";
|
|
||||||
else if (clk == &clk32k || clk == &main_clk)
|
|
||||||
state = "on";
|
|
||||||
else
|
|
||||||
state = "";
|
|
||||||
|
|
||||||
seq_printf(s, "%-10s users=%2d %-3s %9ld Hz %s\n",
|
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";
|
||||||
|
} else if (clk->pmc_mask) {
|
||||||
|
state = (sr & clk->pmc_mask) ? "on" : "off";
|
||||||
|
} else if (clk == &clk32k || clk == &main_clk) {
|
||||||
|
state = "on";
|
||||||
|
} else {
|
||||||
|
state = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
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)
|
||||||
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)
|
||||||
|
|
||||||
/* 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)
|
||||||
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)
|
||||||
if (clk->users > 0)
|
if (clk->users > 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (clk->mode == pmc_periph_mode)
|
if (clk->mode == pmc_periph_mode) {
|
||||||
|
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;
|
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)
|
||||||
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 {
|
||||||
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;
|
||||||
#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;
|
||||||
#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 @@
|
||||||
#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 @@
|
||||||
#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 {
|
||||||
/* 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 {
|
||||||
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)
|
||||||
#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.
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
/*
|
||||||
|
* 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
|
|
@ -0,0 +1,377 @@
|
||||||
|
/*
|
||||||
|
* 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)
|
||||||
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)
|
||||||
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[] = {
|
||||||
[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[] = {
|
||||||
[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;
|
||||||
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)
|
||||||
#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
|
||||||
|
|
Загрузка…
Ссылка в новой задаче