diff options
author | Ludovic Desroches <ludovic.desroches@atmel.com> | 2013-03-22 09:24:12 -0400 |
---|---|---|
committer | Nicolas Ferre <nicolas.ferre@atmel.com> | 2013-03-26 07:18:04 -0400 |
commit | 8f4b47949f61eb7f68f458d56a661a7842e67c44 (patch) | |
tree | eebf2f59a252a6dc8dc200e23cd81521d936b386 /arch/arm/mach-at91 | |
parent | 8f0cdcc5700d9f9508385f41f6047fca82334eba (diff) |
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>
Diffstat (limited to 'arch/arm/mach-at91')
-rw-r--r-- | arch/arm/mach-at91/Kconfig | 33 | ||||
-rw-r--r-- | arch/arm/mach-at91/Makefile | 4 | ||||
-rw-r--r-- | arch/arm/mach-at91/board-dt-sama5.c | 86 | ||||
-rw-r--r-- | arch/arm/mach-at91/clock.c | 109 | ||||
-rw-r--r-- | arch/arm/mach-at91/clock.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-at91/include/mach/at91_pmc.h | 18 | ||||
-rw-r--r-- | arch/arm/mach-at91/include/mach/cpu.h | 20 | ||||
-rw-r--r-- | arch/arm/mach-at91/include/mach/sama5d3.h | 73 | ||||
-rw-r--r-- | arch/arm/mach-at91/sama5d3.c | 377 | ||||
-rw-r--r-- | arch/arm/mach-at91/setup.c | 27 | ||||
-rw-r--r-- | arch/arm/mach-at91/soc.h | 5 |
11 files changed, 725 insertions, 29 deletions
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index 8b35c7f1634f..02802386b894 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig | |||
@@ -29,6 +29,14 @@ config SOC_AT91SAM9 | |||
29 | select MULTI_IRQ_HANDLER | 29 | select MULTI_IRQ_HANDLER |
30 | select SPARSE_IRQ | 30 | select SPARSE_IRQ |
31 | 31 | ||
32 | config SOC_SAMA5 | ||
33 | bool | ||
34 | select AT91_SAM9_TIME | ||
35 | select CPU_V7 | ||
36 | select GENERIC_CLOCKEVENTS | ||
37 | select MULTI_IRQ_HANDLER | ||
38 | select SPARSE_IRQ | ||
39 | |||
32 | menu "Atmel AT91 System-on-Chip" | 40 | menu "Atmel AT91 System-on-Chip" |
33 | 41 | ||
34 | choice | 42 | choice |
@@ -41,10 +49,27 @@ config SOC_SAM_V4_V5 | |||
41 | Select this if you are using one of Atmel's AT91SAM9, AT91RM9200 | 49 | Select this if you are using one of Atmel's AT91SAM9, AT91RM9200 |
42 | or AT91X40 SoC. | 50 | or AT91X40 SoC. |
43 | 51 | ||
52 | config SOC_SAM_V7 | ||
53 | bool "Cortex A5" | ||
54 | help | ||
55 | Select this if you are using one of Atmel's SAMA5D3 SoC. | ||
56 | |||
44 | endchoice | 57 | endchoice |
45 | 58 | ||
46 | comment "Atmel AT91 Processor" | 59 | comment "Atmel AT91 Processor" |
47 | 60 | ||
61 | if SOC_SAM_V7 | ||
62 | config SOC_SAMA5D3 | ||
63 | bool "SAMA5D3 family" | ||
64 | depends on SOC_SAM_V7 | ||
65 | select SOC_SAMA5 | ||
66 | select HAVE_FB_ATMEL | ||
67 | select HAVE_AT91_DBGU1 | ||
68 | help | ||
69 | Select this if you are using one of Atmel's SAMA5D3 family SoC. | ||
70 | This support covers SAMA5D31, SAMA5D33, SAMA5D34, SAMA5D35. | ||
71 | endif | ||
72 | |||
48 | if SOC_SAM_V4_V5 | 73 | if SOC_SAM_V4_V5 |
49 | config SOC_AT91RM9200 | 74 | config SOC_AT91RM9200 |
50 | bool "AT91RM9200" | 75 | bool "AT91RM9200" |
@@ -134,6 +159,14 @@ config MACH_AT91SAM9_DT | |||
134 | Select this if you want to experiment device-tree with | 159 | Select this if you want to experiment device-tree with |
135 | an Atmel Evaluation Kit. | 160 | an Atmel Evaluation Kit. |
136 | 161 | ||
162 | config MACH_SAMA5_DT | ||
163 | bool "Atmel SAMA5 Evaluation Kits with device-tree support" | ||
164 | depends on SOC_SAMA5 | ||
165 | select USE_OF | ||
166 | help | ||
167 | Select this if you want to experiment device-tree with | ||
168 | an Atmel Evaluation Kit. | ||
169 | |||
137 | # ---------------------------------------------------------- | 170 | # ---------------------------------------------------------- |
138 | 171 | ||
139 | comment "AT91 Feature Selections" | 172 | comment "AT91 Feature Selections" |
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile index 74e9b5b637bf..788562dccb43 100644 --- a/arch/arm/mach-at91/Makefile +++ b/arch/arm/mach-at91/Makefile | |||
@@ -22,6 +22,7 @@ obj-$(CONFIG_SOC_AT91SAM9G45) += at91sam9g45.o | |||
22 | obj-$(CONFIG_SOC_AT91SAM9N12) += at91sam9n12.o | 22 | obj-$(CONFIG_SOC_AT91SAM9N12) += at91sam9n12.o |
23 | obj-$(CONFIG_SOC_AT91SAM9X5) += at91sam9x5.o | 23 | obj-$(CONFIG_SOC_AT91SAM9X5) += at91sam9x5.o |
24 | obj-$(CONFIG_SOC_AT91SAM9RL) += at91sam9rl.o | 24 | obj-$(CONFIG_SOC_AT91SAM9RL) += at91sam9rl.o |
25 | obj-$(CONFIG_SOC_SAMA5D3) += sama5d3.o | ||
25 | 26 | ||
26 | obj-$(CONFIG_ARCH_AT91RM9200) += at91rm9200_devices.o | 27 | obj-$(CONFIG_ARCH_AT91RM9200) += at91rm9200_devices.o |
27 | obj-$(CONFIG_ARCH_AT91SAM9260) += at91sam9260_devices.o | 28 | obj-$(CONFIG_ARCH_AT91SAM9260) += at91sam9260_devices.o |
@@ -91,6 +92,9 @@ obj-$(CONFIG_MACH_AT91SAM9M10G45EK) += board-sam9m10g45ek.o | |||
91 | obj-$(CONFIG_MACH_AT91RM9200_DT) += board-dt-rm9200.o | 92 | obj-$(CONFIG_MACH_AT91RM9200_DT) += board-dt-rm9200.o |
92 | obj-$(CONFIG_MACH_AT91SAM9_DT) += board-dt-sam9.o | 93 | obj-$(CONFIG_MACH_AT91SAM9_DT) += board-dt-sam9.o |
93 | 94 | ||
95 | # SAMA5 board with device-tree | ||
96 | obj-$(CONFIG_MACH_SAMA5_DT) += board-dt-sama5.o | ||
97 | |||
94 | # AT91X40 board-specific support | 98 | # AT91X40 board-specific support |
95 | obj-$(CONFIG_MACH_AT91EB01) += board-eb01.o | 99 | obj-$(CONFIG_MACH_AT91EB01) += board-eb01.o |
96 | 100 | ||
diff --git a/arch/arm/mach-at91/board-dt-sama5.c b/arch/arm/mach-at91/board-dt-sama5.c new file mode 100644 index 000000000000..705305e62bbc --- /dev/null +++ b/arch/arm/mach-at91/board-dt-sama5.c | |||
@@ -0,0 +1,86 @@ | |||
1 | /* | ||
2 | * Setup code for SAMA5 Evaluation Kits with Device Tree support | ||
3 | * | ||
4 | * Copyright (C) 2013 Atmel, | ||
5 | * 2013 Ludovic Desroches <ludovic.desroches@atmel.com> | ||
6 | * | ||
7 | * Licensed under GPLv2 or later. | ||
8 | */ | ||
9 | |||
10 | #include <linux/types.h> | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/module.h> | ||
13 | #include <linux/gpio.h> | ||
14 | #include <linux/micrel_phy.h> | ||
15 | #include <linux/of.h> | ||
16 | #include <linux/of_irq.h> | ||
17 | #include <linux/of_platform.h> | ||
18 | #include <linux/phy.h> | ||
19 | |||
20 | #include <asm/setup.h> | ||
21 | #include <asm/irq.h> | ||
22 | #include <asm/mach/arch.h> | ||
23 | #include <asm/mach/map.h> | ||
24 | #include <asm/mach/irq.h> | ||
25 | |||
26 | #include "at91_aic.h" | ||
27 | #include "generic.h" | ||
28 | |||
29 | |||
30 | static const struct of_device_id irq_of_match[] __initconst = { | ||
31 | |||
32 | { .compatible = "atmel,sama5d3-aic", .data = at91_aic5_of_init }, | ||
33 | { /*sentinel*/ } | ||
34 | }; | ||
35 | |||
36 | static void __init at91_dt_init_irq(void) | ||
37 | { | ||
38 | of_irq_init(irq_of_match); | ||
39 | } | ||
40 | |||
41 | static int ksz9021rn_phy_fixup(struct phy_device *phy) | ||
42 | { | ||
43 | int value; | ||
44 | |||
45 | #define GMII_RCCPSR 260 | ||
46 | #define GMII_RRDPSR 261 | ||
47 | #define GMII_ERCR 11 | ||
48 | #define GMII_ERDWR 12 | ||
49 | |||
50 | /* Set delay values */ | ||
51 | value = GMII_RCCPSR | 0x8000; | ||
52 | phy_write(phy, GMII_ERCR, value); | ||
53 | value = 0xF2F4; | ||
54 | phy_write(phy, GMII_ERDWR, value); | ||
55 | value = GMII_RRDPSR | 0x8000; | ||
56 | phy_write(phy, GMII_ERCR, value); | ||
57 | value = 0x2222; | ||
58 | phy_write(phy, GMII_ERDWR, value); | ||
59 | |||
60 | return 0; | ||
61 | } | ||
62 | |||
63 | static void __init sama5_dt_device_init(void) | ||
64 | { | ||
65 | if (of_machine_is_compatible("atmel,sama5d3xcm")) | ||
66 | phy_register_fixup_for_uid(PHY_ID_KSZ9021, MICREL_PHY_ID_MASK, | ||
67 | ksz9021rn_phy_fixup); | ||
68 | |||
69 | of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); | ||
70 | } | ||
71 | |||
72 | static const char *sama5_dt_board_compat[] __initdata = { | ||
73 | "atmel,sama5", | ||
74 | NULL | ||
75 | }; | ||
76 | |||
77 | DT_MACHINE_START(sama5_dt, "Atmel SAMA5 (Device Tree)") | ||
78 | /* Maintainer: Atmel */ | ||
79 | .init_time = at91sam926x_pit_init, | ||
80 | .map_io = at91_map_io, | ||
81 | .handle_irq = at91_aic5_handle_irq, | ||
82 | .init_early = at91_dt_initialize, | ||
83 | .init_irq = at91_dt_init_irq, | ||
84 | .init_machine = sama5_dt_device_init, | ||
85 | .dt_compat = sama5_dt_board_compat, | ||
86 | MACHINE_END | ||
diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c index 33361505c0cd..da841885d01c 100644 --- a/arch/arm/mach-at91/clock.c +++ b/arch/arm/mach-at91/clock.c | |||
@@ -54,7 +54,10 @@ EXPORT_SYMBOL_GPL(at91_pmc_base); | |||
54 | */ | 54 | */ |
55 | #define cpu_has_utmi() ( cpu_is_at91sam9rl() \ | 55 | #define cpu_has_utmi() ( cpu_is_at91sam9rl() \ |
56 | || cpu_is_at91sam9g45() \ | 56 | || cpu_is_at91sam9g45() \ |
57 | || cpu_is_at91sam9x5()) | 57 | || cpu_is_at91sam9x5() \ |
58 | || cpu_is_sama5d3()) | ||
59 | |||
60 | #define cpu_has_1056M_plla() (cpu_is_sama5d3()) | ||
58 | 61 | ||
59 | #define cpu_has_800M_plla() ( cpu_is_at91sam9g20() \ | 62 | #define cpu_has_800M_plla() ( cpu_is_at91sam9g20() \ |
60 | || cpu_is_at91sam9g45() \ | 63 | || cpu_is_at91sam9g45() \ |
@@ -75,7 +78,8 @@ EXPORT_SYMBOL_GPL(at91_pmc_base); | |||
75 | || cpu_is_at91sam9n12())) | 78 | || cpu_is_at91sam9n12())) |
76 | 79 | ||
77 | #define cpu_has_upll() (cpu_is_at91sam9g45() \ | 80 | #define cpu_has_upll() (cpu_is_at91sam9g45() \ |
78 | || cpu_is_at91sam9x5()) | 81 | || cpu_is_at91sam9x5() \ |
82 | || cpu_is_sama5d3()) | ||
79 | 83 | ||
80 | /* USB host HS & FS */ | 84 | /* USB host HS & FS */ |
81 | #define cpu_has_uhp() (!cpu_is_at91sam9rl()) | 85 | #define cpu_has_uhp() (!cpu_is_at91sam9rl()) |
@@ -83,18 +87,22 @@ EXPORT_SYMBOL_GPL(at91_pmc_base); | |||
83 | /* USB device FS only */ | 87 | /* USB device FS only */ |
84 | #define cpu_has_udpfs() (!(cpu_is_at91sam9rl() \ | 88 | #define cpu_has_udpfs() (!(cpu_is_at91sam9rl() \ |
85 | || cpu_is_at91sam9g45() \ | 89 | || cpu_is_at91sam9g45() \ |
86 | || cpu_is_at91sam9x5())) | 90 | || cpu_is_at91sam9x5() \ |
91 | || cpu_is_sama5d3())) | ||
87 | 92 | ||
88 | #define cpu_has_plladiv2() (cpu_is_at91sam9g45() \ | 93 | #define cpu_has_plladiv2() (cpu_is_at91sam9g45() \ |
89 | || cpu_is_at91sam9x5() \ | 94 | || cpu_is_at91sam9x5() \ |
90 | || cpu_is_at91sam9n12()) | 95 | || cpu_is_at91sam9n12() \ |
96 | || cpu_is_sama5d3()) | ||
91 | 97 | ||
92 | #define cpu_has_mdiv3() (cpu_is_at91sam9g45() \ | 98 | #define cpu_has_mdiv3() (cpu_is_at91sam9g45() \ |
93 | || cpu_is_at91sam9x5() \ | 99 | || cpu_is_at91sam9x5() \ |
94 | || cpu_is_at91sam9n12()) | 100 | || cpu_is_at91sam9n12() \ |
101 | || cpu_is_sama5d3()) | ||
95 | 102 | ||
96 | #define cpu_has_alt_prescaler() (cpu_is_at91sam9x5() \ | 103 | #define cpu_has_alt_prescaler() (cpu_is_at91sam9x5() \ |
97 | || cpu_is_at91sam9n12()) | 104 | || cpu_is_at91sam9n12() \ |
105 | || cpu_is_sama5d3()) | ||
98 | 106 | ||
99 | static LIST_HEAD(clocks); | 107 | static LIST_HEAD(clocks); |
100 | static DEFINE_SPINLOCK(clk_lock); | 108 | static DEFINE_SPINLOCK(clk_lock); |
@@ -210,10 +218,26 @@ struct clk mck = { | |||
210 | 218 | ||
211 | static void pmc_periph_mode(struct clk *clk, int is_on) | 219 | static void pmc_periph_mode(struct clk *clk, int is_on) |
212 | { | 220 | { |
213 | if (is_on) | 221 | u32 regval = 0; |
214 | at91_pmc_write(AT91_PMC_PCER, clk->pmc_mask); | 222 | |
215 | else | 223 | /* |
216 | at91_pmc_write(AT91_PMC_PCDR, clk->pmc_mask); | 224 | * With sama5d3 devices, we are managing clock division so we have to |
225 | * use the Peripheral Control Register introduced from at91sam9x5 | ||
226 | * devices. | ||
227 | */ | ||
228 | if (cpu_is_sama5d3()) { | ||
229 | regval |= AT91_PMC_PCR_CMD; /* write command */ | ||
230 | regval |= clk->pid & AT91_PMC_PCR_PID; /* peripheral selection */ | ||
231 | regval |= AT91_PMC_PCR_DIV(clk->div); | ||
232 | if (is_on) | ||
233 | regval |= AT91_PMC_PCR_EN; /* enable clock */ | ||
234 | at91_pmc_write(AT91_PMC_PCR, regval); | ||
235 | } else { | ||
236 | if (is_on) | ||
237 | at91_pmc_write(AT91_PMC_PCER, clk->pmc_mask); | ||
238 | else | ||
239 | at91_pmc_write(AT91_PMC_PCDR, clk->pmc_mask); | ||
240 | } | ||
217 | } | 241 | } |
218 | 242 | ||
219 | static struct clk __init *at91_css_to_clk(unsigned long css) | 243 | 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 | 467 | ||
444 | static int at91_clk_show(struct seq_file *s, void *unused) | 468 | static int at91_clk_show(struct seq_file *s, void *unused) |
445 | { | 469 | { |
446 | u32 scsr, pcsr, uckr = 0, sr; | 470 | u32 scsr, pcsr, pcsr1 = 0, uckr = 0, sr; |
447 | struct clk *clk; | 471 | struct clk *clk; |
448 | 472 | ||
449 | scsr = at91_pmc_read(AT91_PMC_SCSR); | 473 | scsr = at91_pmc_read(AT91_PMC_SCSR); |
450 | pcsr = at91_pmc_read(AT91_PMC_PCSR); | 474 | pcsr = at91_pmc_read(AT91_PMC_PCSR); |
475 | if (cpu_is_sama5d3()) | ||
476 | pcsr1 = at91_pmc_read(AT91_PMC_PCSR1); | ||
451 | sr = at91_pmc_read(AT91_PMC_SR); | 477 | sr = at91_pmc_read(AT91_PMC_SR); |
452 | seq_printf(s, "SCSR = %8x\n", scsr); | 478 | seq_printf(s, "SCSR = %8x\n", scsr); |
453 | seq_printf(s, "PCSR = %8x\n", pcsr); | 479 | seq_printf(s, "PCSR = %8x\n", pcsr); |
480 | if (cpu_is_sama5d3()) | ||
481 | seq_printf(s, "PCSR1 = %8x\n", pcsr1); | ||
454 | seq_printf(s, "MOR = %8x\n", at91_pmc_read(AT91_CKGR_MOR)); | 482 | seq_printf(s, "MOR = %8x\n", at91_pmc_read(AT91_CKGR_MOR)); |
455 | seq_printf(s, "MCFR = %8x\n", at91_pmc_read(AT91_CKGR_MCFR)); | 483 | seq_printf(s, "MCFR = %8x\n", at91_pmc_read(AT91_CKGR_MCFR)); |
456 | seq_printf(s, "PLLA = %8x\n", at91_pmc_read(AT91_CKGR_PLLAR)); | 484 | 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 | list_for_each_entry(clk, &clocks, node) { | 498 | list_for_each_entry(clk, &clocks, node) { |
471 | char *state; | 499 | char *state; |
472 | 500 | ||
473 | if (clk->mode == pmc_sys_mode) | 501 | if (clk->mode == pmc_sys_mode) { |
474 | state = (scsr & clk->pmc_mask) ? "on" : "off"; | 502 | state = (scsr & clk->pmc_mask) ? "on" : "off"; |
475 | else if (clk->mode == pmc_periph_mode) | 503 | } else if (clk->mode == pmc_periph_mode) { |
476 | state = (pcsr & clk->pmc_mask) ? "on" : "off"; | 504 | if (cpu_is_sama5d3()) { |
477 | else if (clk->mode == pmc_uckr_mode) | 505 | u32 pmc_mask = 1 << (clk->pid % 32); |
506 | |||
507 | if (clk->pid > 31) | ||
508 | state = (pcsr1 & pmc_mask) ? "on" : "off"; | ||
509 | else | ||
510 | state = (pcsr & pmc_mask) ? "on" : "off"; | ||
511 | } else { | ||
512 | state = (pcsr & clk->pmc_mask) ? "on" : "off"; | ||
513 | } | ||
514 | } else if (clk->mode == pmc_uckr_mode) { | ||
478 | state = (uckr & clk->pmc_mask) ? "on" : "off"; | 515 | state = (uckr & clk->pmc_mask) ? "on" : "off"; |
479 | else if (clk->pmc_mask) | 516 | } else if (clk->pmc_mask) { |
480 | state = (sr & clk->pmc_mask) ? "on" : "off"; | 517 | state = (sr & clk->pmc_mask) ? "on" : "off"; |
481 | else if (clk == &clk32k || clk == &main_clk) | 518 | } else if (clk == &clk32k || clk == &main_clk) { |
482 | state = "on"; | 519 | state = "on"; |
483 | else | 520 | } else { |
484 | state = ""; | 521 | state = ""; |
522 | } | ||
485 | 523 | ||
486 | seq_printf(s, "%-10s users=%2d %-3s %9ld Hz %s\n", | 524 | seq_printf(s, "%-10s users=%2d %-3s %9lu Hz %s\n", |
487 | clk->name, clk->users, state, clk_get_rate(clk), | 525 | clk->name, clk->users, state, clk_get_rate(clk), |
488 | clk->parent ? clk->parent->name : ""); | 526 | clk->parent ? clk->parent->name : ""); |
489 | } | 527 | } |
@@ -530,6 +568,9 @@ int __init clk_register(struct clk *clk) | |||
530 | if (clk_is_peripheral(clk)) { | 568 | if (clk_is_peripheral(clk)) { |
531 | if (!clk->parent) | 569 | if (!clk->parent) |
532 | clk->parent = &mck; | 570 | clk->parent = &mck; |
571 | if (cpu_is_sama5d3()) | ||
572 | clk->rate_hz = DIV_ROUND_UP(clk->parent->rate_hz, | ||
573 | 1 << clk->div); | ||
533 | clk->mode = pmc_periph_mode; | 574 | clk->mode = pmc_periph_mode; |
534 | } | 575 | } |
535 | else if (clk_is_sys(clk)) { | 576 | else if (clk_is_sys(clk)) { |
@@ -555,7 +596,11 @@ static u32 __init at91_pll_rate(struct clk *pll, u32 freq, u32 reg) | |||
555 | unsigned mul, div; | 596 | unsigned mul, div; |
556 | 597 | ||
557 | div = reg & 0xff; | 598 | div = reg & 0xff; |
558 | mul = (reg >> 16) & 0x7ff; | 599 | if (cpu_is_sama5d3()) |
600 | mul = AT91_PMC3_MUL_GET(reg); | ||
601 | else | ||
602 | mul = AT91_PMC_MUL_GET(reg); | ||
603 | |||
559 | if (div && mul) { | 604 | if (div && mul) { |
560 | freq /= div; | 605 | freq /= div; |
561 | freq *= mul + 1; | 606 | freq *= mul + 1; |
@@ -706,12 +751,15 @@ static int __init at91_pmc_init(unsigned long main_clock) | |||
706 | 751 | ||
707 | /* report if PLLA is more than mildly overclocked */ | 752 | /* report if PLLA is more than mildly overclocked */ |
708 | plla.rate_hz = at91_pll_rate(&plla, main_clock, at91_pmc_read(AT91_CKGR_PLLAR)); | 753 | plla.rate_hz = at91_pll_rate(&plla, main_clock, at91_pmc_read(AT91_CKGR_PLLAR)); |
709 | if (cpu_has_300M_plla()) { | 754 | if (cpu_has_1056M_plla()) { |
710 | if (plla.rate_hz > 300000000) | 755 | if (plla.rate_hz > 1056000000) |
711 | pll_overclock = true; | 756 | pll_overclock = true; |
712 | } else if (cpu_has_800M_plla()) { | 757 | } else if (cpu_has_800M_plla()) { |
713 | if (plla.rate_hz > 800000000) | 758 | if (plla.rate_hz > 800000000) |
714 | pll_overclock = true; | 759 | pll_overclock = true; |
760 | } else if (cpu_has_300M_plla()) { | ||
761 | if (plla.rate_hz > 300000000) | ||
762 | pll_overclock = true; | ||
715 | } else if (cpu_has_240M_plla()) { | 763 | } else if (cpu_has_240M_plla()) { |
716 | if (plla.rate_hz > 240000000) | 764 | if (plla.rate_hz > 240000000) |
717 | pll_overclock = true; | 765 | pll_overclock = true; |
@@ -872,6 +920,7 @@ int __init at91_clock_init(unsigned long main_clock) | |||
872 | static int __init at91_clock_reset(void) | 920 | static int __init at91_clock_reset(void) |
873 | { | 921 | { |
874 | unsigned long pcdr = 0; | 922 | unsigned long pcdr = 0; |
923 | unsigned long pcdr1 = 0; | ||
875 | unsigned long scdr = 0; | 924 | unsigned long scdr = 0; |
876 | struct clk *clk; | 925 | struct clk *clk; |
877 | 926 | ||
@@ -879,8 +928,17 @@ static int __init at91_clock_reset(void) | |||
879 | if (clk->users > 0) | 928 | if (clk->users > 0) |
880 | continue; | 929 | continue; |
881 | 930 | ||
882 | if (clk->mode == pmc_periph_mode) | 931 | if (clk->mode == pmc_periph_mode) { |
883 | pcdr |= clk->pmc_mask; | 932 | if (cpu_is_sama5d3()) { |
933 | u32 pmc_mask = 1 << (clk->pid % 32); | ||
934 | |||
935 | if (clk->pid > 31) | ||
936 | pcdr1 |= pmc_mask; | ||
937 | else | ||
938 | pcdr |= pmc_mask; | ||
939 | } else | ||
940 | pcdr |= clk->pmc_mask; | ||
941 | } | ||
884 | 942 | ||
885 | if (clk->mode == pmc_sys_mode) | 943 | if (clk->mode == pmc_sys_mode) |
886 | scdr |= clk->pmc_mask; | 944 | scdr |= clk->pmc_mask; |
@@ -888,8 +946,9 @@ static int __init at91_clock_reset(void) | |||
888 | pr_debug("Clocks: disable unused %s\n", clk->name); | 946 | pr_debug("Clocks: disable unused %s\n", clk->name); |
889 | } | 947 | } |
890 | 948 | ||
891 | at91_pmc_write(AT91_PMC_PCDR, pcdr); | ||
892 | at91_pmc_write(AT91_PMC_SCDR, scdr); | 949 | at91_pmc_write(AT91_PMC_SCDR, scdr); |
950 | if (cpu_is_sama5d3()) | ||
951 | at91_pmc_write(AT91_PMC_PCDR1, pcdr1); | ||
893 | 952 | ||
894 | return 0; | 953 | return 0; |
895 | } | 954 | } |
diff --git a/arch/arm/mach-at91/clock.h b/arch/arm/mach-at91/clock.h index c2e63e47dcbe..a98a39bbd883 100644 --- a/arch/arm/mach-at91/clock.h +++ b/arch/arm/mach-at91/clock.h | |||
@@ -20,7 +20,9 @@ struct clk { | |||
20 | const char *name; /* unique clock name */ | 20 | const char *name; /* unique clock name */ |
21 | struct clk_lookup cl; | 21 | struct clk_lookup cl; |
22 | unsigned long rate_hz; | 22 | unsigned long rate_hz; |
23 | unsigned div; /* parent clock divider */ | ||
23 | struct clk *parent; | 24 | struct clk *parent; |
25 | unsigned pid; /* peripheral ID */ | ||
24 | u32 pmc_mask; | 26 | u32 pmc_mask; |
25 | void (*mode)(struct clk *, int); | 27 | void (*mode)(struct clk *, int); |
26 | unsigned id:3; /* PCK0..4, or 32k/main/a/b */ | 28 | unsigned id:3; /* PCK0..4, or 32k/main/a/b */ |
diff --git a/arch/arm/mach-at91/include/mach/at91_pmc.h b/arch/arm/mach-at91/include/mach/at91_pmc.h index ea2c57a86ca6..31df12029c4e 100644 --- a/arch/arm/mach-at91/include/mach/at91_pmc.h +++ b/arch/arm/mach-at91/include/mach/at91_pmc.h | |||
@@ -75,6 +75,9 @@ extern void __iomem *at91_pmc_base; | |||
75 | #define AT91_PMC_PLLCOUNT (0x3f << 8) /* PLL Counter */ | 75 | #define AT91_PMC_PLLCOUNT (0x3f << 8) /* PLL Counter */ |
76 | #define AT91_PMC_OUT (3 << 14) /* PLL Clock Frequency Range */ | 76 | #define AT91_PMC_OUT (3 << 14) /* PLL Clock Frequency Range */ |
77 | #define AT91_PMC_MUL (0x7ff << 16) /* PLL Multiplier */ | 77 | #define AT91_PMC_MUL (0x7ff << 16) /* PLL Multiplier */ |
78 | #define AT91_PMC_MUL_GET(n) ((n) >> 16 & 0x7ff) | ||
79 | #define AT91_PMC3_MUL (0x7f << 18) /* PLL Multiplier [SAMA5 only] */ | ||
80 | #define AT91_PMC3_MUL_GET(n) ((n) >> 18 & 0x7f) | ||
78 | #define AT91_PMC_USBDIV (3 << 28) /* USB Divisor (PLLB only) */ | 81 | #define AT91_PMC_USBDIV (3 << 28) /* USB Divisor (PLLB only) */ |
79 | #define AT91_PMC_USBDIV_1 (0 << 28) | 82 | #define AT91_PMC_USBDIV_1 (0 << 28) |
80 | #define AT91_PMC_USBDIV_2 (1 << 28) | 83 | #define AT91_PMC_USBDIV_2 (1 << 28) |
@@ -167,11 +170,18 @@ extern void __iomem *at91_pmc_base; | |||
167 | #define AT91_PMC_WPVS (0x1 << 0) /* Write Protect Violation Status */ | 170 | #define AT91_PMC_WPVS (0x1 << 0) /* Write Protect Violation Status */ |
168 | #define AT91_PMC_WPVSRC (0xffff << 8) /* Write Protect Violation Source */ | 171 | #define AT91_PMC_WPVSRC (0xffff << 8) /* Write Protect Violation Source */ |
169 | 172 | ||
170 | #define AT91_PMC_PCR 0x10c /* Peripheral Control Register [some SAM9] */ | 173 | #define AT91_PMC_PCER1 0x100 /* Peripheral Clock Enable Register 1 [SAMA5 only]*/ |
174 | #define AT91_PMC_PCDR1 0x104 /* Peripheral Clock Enable Register 1 */ | ||
175 | #define AT91_PMC_PCSR1 0x108 /* Peripheral Clock Enable Register 1 */ | ||
176 | |||
177 | #define AT91_PMC_PCR 0x10c /* Peripheral Control Register [some SAM9 and SAMA5] */ | ||
171 | #define AT91_PMC_PCR_PID (0x3f << 0) /* Peripheral ID */ | 178 | #define AT91_PMC_PCR_PID (0x3f << 0) /* Peripheral ID */ |
172 | #define AT91_PMC_PCR_CMD (0x1 << 12) /* Command */ | 179 | #define AT91_PMC_PCR_CMD (0x1 << 12) /* Command (read=0, write=1) */ |
173 | #define AT91_PMC_PCR_DIV (0x3 << 16) /* Divisor Value */ | 180 | #define AT91_PMC_PCR_DIV(n) ((n) << 16) /* Divisor Value */ |
174 | #define AT91_PMC_PCRDIV(n) (((n) << 16) & AT91_PMC_PCR_DIV) | 181 | #define AT91_PMC_PCR_DIV0 0x0 /* Peripheral clock is MCK */ |
182 | #define AT91_PMC_PCR_DIV2 0x2 /* Peripheral clock is MCK/2 */ | ||
183 | #define AT91_PMC_PCR_DIV4 0x4 /* Peripheral clock is MCK/4 */ | ||
184 | #define AT91_PMC_PCR_DIV8 0x8 /* Peripheral clock is MCK/8 */ | ||
175 | #define AT91_PMC_PCR_EN (0x1 << 28) /* Enable */ | 185 | #define AT91_PMC_PCR_EN (0x1 << 28) /* Enable */ |
176 | 186 | ||
177 | #endif | 187 | #endif |
diff --git a/arch/arm/mach-at91/include/mach/cpu.h b/arch/arm/mach-at91/include/mach/cpu.h index b6504c19d55c..0f3379fe645f 100644 --- a/arch/arm/mach-at91/include/mach/cpu.h +++ b/arch/arm/mach-at91/include/mach/cpu.h | |||
@@ -36,6 +36,8 @@ | |||
36 | #define ARCH_ID_AT91M40807 0x14080745 | 36 | #define ARCH_ID_AT91M40807 0x14080745 |
37 | #define ARCH_ID_AT91R40008 0x44000840 | 37 | #define ARCH_ID_AT91R40008 0x44000840 |
38 | 38 | ||
39 | #define ARCH_ID_SAMA5D3 0x8A5C07C0 | ||
40 | |||
39 | #define ARCH_EXID_AT91SAM9M11 0x00000001 | 41 | #define ARCH_EXID_AT91SAM9M11 0x00000001 |
40 | #define ARCH_EXID_AT91SAM9M10 0x00000002 | 42 | #define ARCH_EXID_AT91SAM9M10 0x00000002 |
41 | #define ARCH_EXID_AT91SAM9G46 0x00000003 | 43 | #define ARCH_EXID_AT91SAM9G46 0x00000003 |
@@ -47,6 +49,11 @@ | |||
47 | #define ARCH_EXID_AT91SAM9G25 0x00000003 | 49 | #define ARCH_EXID_AT91SAM9G25 0x00000003 |
48 | #define ARCH_EXID_AT91SAM9X25 0x00000004 | 50 | #define ARCH_EXID_AT91SAM9X25 0x00000004 |
49 | 51 | ||
52 | #define ARCH_EXID_SAMA5D31 0x00444300 | ||
53 | #define ARCH_EXID_SAMA5D33 0x00414300 | ||
54 | #define ARCH_EXID_SAMA5D34 0x00414301 | ||
55 | #define ARCH_EXID_SAMA5D35 0x00584300 | ||
56 | |||
50 | #define ARCH_FAMILY_AT91X92 0x09200000 | 57 | #define ARCH_FAMILY_AT91X92 0x09200000 |
51 | #define ARCH_FAMILY_AT91SAM9 0x01900000 | 58 | #define ARCH_FAMILY_AT91SAM9 0x01900000 |
52 | #define ARCH_FAMILY_AT91SAM9XE 0x02900000 | 59 | #define ARCH_FAMILY_AT91SAM9XE 0x02900000 |
@@ -75,6 +82,9 @@ enum at91_soc_type { | |||
75 | /* SAM9N12 */ | 82 | /* SAM9N12 */ |
76 | AT91_SOC_SAM9N12, | 83 | AT91_SOC_SAM9N12, |
77 | 84 | ||
85 | /* SAMA5D3 */ | ||
86 | AT91_SOC_SAMA5D3, | ||
87 | |||
78 | /* Unknown type */ | 88 | /* Unknown type */ |
79 | AT91_SOC_NONE | 89 | AT91_SOC_NONE |
80 | }; | 90 | }; |
@@ -93,6 +103,10 @@ enum at91_soc_subtype { | |||
93 | AT91_SOC_SAM9G15, AT91_SOC_SAM9G35, AT91_SOC_SAM9X35, | 103 | AT91_SOC_SAM9G15, AT91_SOC_SAM9G35, AT91_SOC_SAM9X35, |
94 | AT91_SOC_SAM9G25, AT91_SOC_SAM9X25, | 104 | AT91_SOC_SAM9G25, AT91_SOC_SAM9X25, |
95 | 105 | ||
106 | /* SAMA5D3 */ | ||
107 | AT91_SOC_SAMA5D31, AT91_SOC_SAMA5D33, AT91_SOC_SAMA5D34, | ||
108 | AT91_SOC_SAMA5D35, | ||
109 | |||
96 | /* Unknown subtype */ | 110 | /* Unknown subtype */ |
97 | AT91_SOC_SUBTYPE_NONE | 111 | AT91_SOC_SUBTYPE_NONE |
98 | }; | 112 | }; |
@@ -187,6 +201,12 @@ static inline int at91_soc_is_detected(void) | |||
187 | #define cpu_is_at91sam9n12() (0) | 201 | #define cpu_is_at91sam9n12() (0) |
188 | #endif | 202 | #endif |
189 | 203 | ||
204 | #ifdef CONFIG_SOC_SAMA5D3 | ||
205 | #define cpu_is_sama5d3() (at91_soc_initdata.type == AT91_SOC_SAMA5D3) | ||
206 | #else | ||
207 | #define cpu_is_sama5d3() (0) | ||
208 | #endif | ||
209 | |||
190 | /* | 210 | /* |
191 | * Since this is ARM, we will never run on any AVR32 CPU. But these | 211 | * Since this is ARM, we will never run on any AVR32 CPU. But these |
192 | * definitions may reduce clutter in common drivers. | 212 | * definitions may reduce clutter in common drivers. |
diff --git a/arch/arm/mach-at91/include/mach/sama5d3.h b/arch/arm/mach-at91/include/mach/sama5d3.h new file mode 100644 index 000000000000..6dc81ee38048 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/sama5d3.h | |||
@@ -0,0 +1,73 @@ | |||
1 | /* | ||
2 | * Chip-specific header file for the SAMA5D3 family | ||
3 | * | ||
4 | * Copyright (C) 2013 Atmel, | ||
5 | * 2013 Ludovic Desroches <ludovic.desroches@atmel.com> | ||
6 | * | ||
7 | * Common definitions. | ||
8 | * Based on SAMA5D3 datasheet. | ||
9 | * | ||
10 | * Licensed under GPLv2 or later. | ||
11 | */ | ||
12 | |||
13 | #ifndef SAMA5D3_H | ||
14 | #define SAMA5D3_H | ||
15 | |||
16 | /* | ||
17 | * Peripheral identifiers/interrupts. | ||
18 | */ | ||
19 | #define AT91_ID_FIQ 0 /* Advanced Interrupt Controller (FIQ) */ | ||
20 | #define AT91_ID_SYS 1 /* System Peripherals */ | ||
21 | #define SAMA5D3_ID_DBGU 2 /* debug Unit (usually no special interrupt line) */ | ||
22 | #define AT91_ID_PIT 3 /* PIT */ | ||
23 | #define SAMA5D3_ID_WDT 4 /* Watchdog Timer Interrupt */ | ||
24 | #define SAMA5D3_ID_HSMC 5 /* Static Memory Controller */ | ||
25 | #define SAMA5D3_ID_PIOA 6 /* PIOA */ | ||
26 | #define SAMA5D3_ID_PIOB 7 /* PIOB */ | ||
27 | #define SAMA5D3_ID_PIOC 8 /* PIOC */ | ||
28 | #define SAMA5D3_ID_PIOD 9 /* PIOD */ | ||
29 | #define SAMA5D3_ID_PIOE 10 /* PIOE */ | ||
30 | #define SAMA5D3_ID_SMD 11 /* SMD Soft Modem */ | ||
31 | #define SAMA5D3_ID_USART0 12 /* USART0 */ | ||
32 | #define SAMA5D3_ID_USART1 13 /* USART1 */ | ||
33 | #define SAMA5D3_ID_USART2 14 /* USART2 */ | ||
34 | #define SAMA5D3_ID_USART3 15 /* USART3 */ | ||
35 | #define SAMA5D3_ID_UART0 16 /* UART 0 */ | ||
36 | #define SAMA5D3_ID_UART1 17 /* UART 1 */ | ||
37 | #define SAMA5D3_ID_TWI0 18 /* Two-Wire Interface 0 */ | ||
38 | #define SAMA5D3_ID_TWI1 19 /* Two-Wire Interface 1 */ | ||
39 | #define SAMA5D3_ID_TWI2 20 /* Two-Wire Interface 2 */ | ||
40 | #define SAMA5D3_ID_HSMCI0 21 /* MCI */ | ||
41 | #define SAMA5D3_ID_HSMCI1 22 /* MCI */ | ||
42 | #define SAMA5D3_ID_HSMCI2 23 /* MCI */ | ||
43 | #define SAMA5D3_ID_SPI0 24 /* Serial Peripheral Interface 0 */ | ||
44 | #define SAMA5D3_ID_SPI1 25 /* Serial Peripheral Interface 1 */ | ||
45 | #define SAMA5D3_ID_TC0 26 /* Timer Counter 0 */ | ||
46 | #define SAMA5D3_ID_TC1 27 /* Timer Counter 2 */ | ||
47 | #define SAMA5D3_ID_PWM 28 /* Pulse Width Modulation Controller */ | ||
48 | #define SAMA5D3_ID_ADC 29 /* Touch Screen ADC Controller */ | ||
49 | #define SAMA5D3_ID_DMA0 30 /* DMA Controller 0 */ | ||
50 | #define SAMA5D3_ID_DMA1 31 /* DMA Controller 1 */ | ||
51 | #define SAMA5D3_ID_UHPHS 32 /* USB Host High Speed */ | ||
52 | #define SAMA5D3_ID_UDPHS 33 /* USB Device High Speed */ | ||
53 | #define SAMA5D3_ID_GMAC 34 /* Gigabit Ethernet MAC */ | ||
54 | #define SAMA5D3_ID_EMAC 35 /* Ethernet MAC */ | ||
55 | #define SAMA5D3_ID_LCDC 36 /* LCD Controller */ | ||
56 | #define SAMA5D3_ID_ISI 37 /* Image Sensor Interface */ | ||
57 | #define SAMA5D3_ID_SSC0 38 /* Synchronous Serial Controller 0 */ | ||
58 | #define SAMA5D3_ID_SSC1 39 /* Synchronous Serial Controller 1 */ | ||
59 | #define SAMA5D3_ID_CAN0 40 /* CAN Controller 0 */ | ||
60 | #define SAMA5D3_ID_CAN1 41 /* CAN Controller 1 */ | ||
61 | #define SAMA5D3_ID_SHA 42 /* Secure Hash Algorithm */ | ||
62 | #define SAMA5D3_ID_AES 43 /* Advanced Encryption Standard */ | ||
63 | #define SAMA5D3_ID_TDES 44 /* Triple Data Encryption Standard */ | ||
64 | #define SAMA5D3_ID_TRNG 45 /* True Random Generator Number */ | ||
65 | #define SAMA5D3_ID_IRQ0 47 /* Advanced Interrupt Controller (IRQ0) */ | ||
66 | |||
67 | /* | ||
68 | * Internal Memory | ||
69 | */ | ||
70 | #define SAMA5D3_SRAM_BASE 0x00300000 /* Internal SRAM base address */ | ||
71 | #define SAMA5D3_SRAM_SIZE (128 * SZ_1K) /* Internal SRAM size (128Kb) */ | ||
72 | |||
73 | #endif | ||
diff --git a/arch/arm/mach-at91/sama5d3.c b/arch/arm/mach-at91/sama5d3.c new file mode 100644 index 000000000000..401279715ab1 --- /dev/null +++ b/arch/arm/mach-at91/sama5d3.c | |||
@@ -0,0 +1,377 @@ | |||
1 | /* | ||
2 | * Chip-specific setup code for the SAMA5D3 family | ||
3 | * | ||
4 | * Copyright (C) 2013 Atmel, | ||
5 | * 2013 Ludovic Desroches <ludovic.desroches@atmel.com> | ||
6 | * | ||
7 | * Licensed under GPLv2 or later. | ||
8 | */ | ||
9 | |||
10 | #include <linux/module.h> | ||
11 | #include <linux/dma-mapping.h> | ||
12 | |||
13 | #include <asm/irq.h> | ||
14 | #include <asm/mach/arch.h> | ||
15 | #include <asm/mach/map.h> | ||
16 | #include <mach/sama5d3.h> | ||
17 | #include <mach/at91_pmc.h> | ||
18 | #include <mach/cpu.h> | ||
19 | |||
20 | #include "soc.h" | ||
21 | #include "generic.h" | ||
22 | #include "clock.h" | ||
23 | #include "sam9_smc.h" | ||
24 | |||
25 | /* -------------------------------------------------------------------- | ||
26 | * Clocks | ||
27 | * -------------------------------------------------------------------- */ | ||
28 | |||
29 | /* | ||
30 | * The peripheral clocks. | ||
31 | */ | ||
32 | |||
33 | static struct clk pioA_clk = { | ||
34 | .name = "pioA_clk", | ||
35 | .pid = SAMA5D3_ID_PIOA, | ||
36 | .type = CLK_TYPE_PERIPHERAL, | ||
37 | }; | ||
38 | static struct clk pioB_clk = { | ||
39 | .name = "pioB_clk", | ||
40 | .pid = SAMA5D3_ID_PIOB, | ||
41 | .type = CLK_TYPE_PERIPHERAL, | ||
42 | }; | ||
43 | static struct clk pioC_clk = { | ||
44 | .name = "pioC_clk", | ||
45 | .pid = SAMA5D3_ID_PIOC, | ||
46 | .type = CLK_TYPE_PERIPHERAL, | ||
47 | }; | ||
48 | static struct clk pioD_clk = { | ||
49 | .name = "pioD_clk", | ||
50 | .pid = SAMA5D3_ID_PIOD, | ||
51 | .type = CLK_TYPE_PERIPHERAL, | ||
52 | }; | ||
53 | static struct clk pioE_clk = { | ||
54 | .name = "pioE_clk", | ||
55 | .pid = SAMA5D3_ID_PIOE, | ||
56 | .type = CLK_TYPE_PERIPHERAL, | ||
57 | }; | ||
58 | static struct clk usart0_clk = { | ||
59 | .name = "usart0_clk", | ||
60 | .pid = SAMA5D3_ID_USART0, | ||
61 | .type = CLK_TYPE_PERIPHERAL, | ||
62 | .div = AT91_PMC_PCR_DIV2, | ||
63 | }; | ||
64 | static struct clk usart1_clk = { | ||
65 | .name = "usart1_clk", | ||
66 | .pid = SAMA5D3_ID_USART1, | ||
67 | .type = CLK_TYPE_PERIPHERAL, | ||
68 | .div = AT91_PMC_PCR_DIV2, | ||
69 | }; | ||
70 | static struct clk usart2_clk = { | ||
71 | .name = "usart2_clk", | ||
72 | .pid = SAMA5D3_ID_USART2, | ||
73 | .type = CLK_TYPE_PERIPHERAL, | ||
74 | .div = AT91_PMC_PCR_DIV2, | ||
75 | }; | ||
76 | static struct clk usart3_clk = { | ||
77 | .name = "usart3_clk", | ||
78 | .pid = SAMA5D3_ID_USART3, | ||
79 | .type = CLK_TYPE_PERIPHERAL, | ||
80 | .div = AT91_PMC_PCR_DIV2, | ||
81 | }; | ||
82 | static struct clk uart0_clk = { | ||
83 | .name = "uart0_clk", | ||
84 | .pid = SAMA5D3_ID_UART0, | ||
85 | .type = CLK_TYPE_PERIPHERAL, | ||
86 | .div = AT91_PMC_PCR_DIV2, | ||
87 | }; | ||
88 | static struct clk uart1_clk = { | ||
89 | .name = "uart1_clk", | ||
90 | .pid = SAMA5D3_ID_UART1, | ||
91 | .type = CLK_TYPE_PERIPHERAL, | ||
92 | .div = AT91_PMC_PCR_DIV2, | ||
93 | }; | ||
94 | static struct clk twi0_clk = { | ||
95 | .name = "twi0_clk", | ||
96 | .pid = SAMA5D3_ID_TWI0, | ||
97 | .type = CLK_TYPE_PERIPHERAL, | ||
98 | .div = AT91_PMC_PCR_DIV2, | ||
99 | }; | ||
100 | static struct clk twi1_clk = { | ||
101 | .name = "twi1_clk", | ||
102 | .pid = SAMA5D3_ID_TWI1, | ||
103 | .type = CLK_TYPE_PERIPHERAL, | ||
104 | .div = AT91_PMC_PCR_DIV2, | ||
105 | }; | ||
106 | static struct clk twi2_clk = { | ||
107 | .name = "twi2_clk", | ||
108 | .pid = SAMA5D3_ID_TWI2, | ||
109 | .type = CLK_TYPE_PERIPHERAL, | ||
110 | .div = AT91_PMC_PCR_DIV2, | ||
111 | }; | ||
112 | static struct clk mmc0_clk = { | ||
113 | .name = "mci0_clk", | ||
114 | .pid = SAMA5D3_ID_HSMCI0, | ||
115 | .type = CLK_TYPE_PERIPHERAL, | ||
116 | }; | ||
117 | static struct clk mmc1_clk = { | ||
118 | .name = "mci1_clk", | ||
119 | .pid = SAMA5D3_ID_HSMCI1, | ||
120 | .type = CLK_TYPE_PERIPHERAL, | ||
121 | }; | ||
122 | static struct clk mmc2_clk = { | ||
123 | .name = "mci2_clk", | ||
124 | .pid = SAMA5D3_ID_HSMCI2, | ||
125 | .type = CLK_TYPE_PERIPHERAL, | ||
126 | }; | ||
127 | static struct clk spi0_clk = { | ||
128 | .name = "spi0_clk", | ||
129 | .pid = SAMA5D3_ID_SPI0, | ||
130 | .type = CLK_TYPE_PERIPHERAL, | ||
131 | }; | ||
132 | static struct clk spi1_clk = { | ||
133 | .name = "spi1_clk", | ||
134 | .pid = SAMA5D3_ID_SPI1, | ||
135 | .type = CLK_TYPE_PERIPHERAL, | ||
136 | }; | ||
137 | static struct clk tcb0_clk = { | ||
138 | .name = "tcb0_clk", | ||
139 | .pid = SAMA5D3_ID_TC0, | ||
140 | .type = CLK_TYPE_PERIPHERAL, | ||
141 | .div = AT91_PMC_PCR_DIV2, | ||
142 | }; | ||
143 | static struct clk tcb1_clk = { | ||
144 | .name = "tcb1_clk", | ||
145 | .pid = SAMA5D3_ID_TC1, | ||
146 | .type = CLK_TYPE_PERIPHERAL, | ||
147 | .div = AT91_PMC_PCR_DIV2, | ||
148 | }; | ||
149 | static struct clk adc_clk = { | ||
150 | .name = "adc_clk", | ||
151 | .pid = SAMA5D3_ID_ADC, | ||
152 | .type = CLK_TYPE_PERIPHERAL, | ||
153 | .div = AT91_PMC_PCR_DIV2, | ||
154 | }; | ||
155 | static struct clk adc_op_clk = { | ||
156 | .name = "adc_op_clk", | ||
157 | .type = CLK_TYPE_PERIPHERAL, | ||
158 | .rate_hz = 5000000, | ||
159 | }; | ||
160 | static struct clk dma0_clk = { | ||
161 | .name = "dma0_clk", | ||
162 | .pid = SAMA5D3_ID_DMA0, | ||
163 | .type = CLK_TYPE_PERIPHERAL, | ||
164 | }; | ||
165 | static struct clk dma1_clk = { | ||
166 | .name = "dma1_clk", | ||
167 | .pid = SAMA5D3_ID_DMA1, | ||
168 | .type = CLK_TYPE_PERIPHERAL, | ||
169 | }; | ||
170 | static struct clk uhphs_clk = { | ||
171 | .name = "uhphs", | ||
172 | .pid = SAMA5D3_ID_UHPHS, | ||
173 | .type = CLK_TYPE_PERIPHERAL, | ||
174 | }; | ||
175 | static struct clk udphs_clk = { | ||
176 | .name = "udphs_clk", | ||
177 | .pid = SAMA5D3_ID_UDPHS, | ||
178 | .type = CLK_TYPE_PERIPHERAL, | ||
179 | }; | ||
180 | /* gmac only for sama5d33, sama5d34, sama5d35 */ | ||
181 | static struct clk macb0_clk = { | ||
182 | .name = "macb0_clk", | ||
183 | .pid = SAMA5D3_ID_GMAC, | ||
184 | .type = CLK_TYPE_PERIPHERAL, | ||
185 | }; | ||
186 | /* emac only for sama5d31, sama5d35 */ | ||
187 | static struct clk macb1_clk = { | ||
188 | .name = "macb1_clk", | ||
189 | .pid = SAMA5D3_ID_EMAC, | ||
190 | .type = CLK_TYPE_PERIPHERAL, | ||
191 | }; | ||
192 | /* lcd only for sama5d31, sama5d33, sama5d34 */ | ||
193 | static struct clk lcdc_clk = { | ||
194 | .name = "lcdc_clk", | ||
195 | .pid = SAMA5D3_ID_LCDC, | ||
196 | .type = CLK_TYPE_PERIPHERAL, | ||
197 | }; | ||
198 | /* isi only for sama5d33, sama5d35 */ | ||
199 | static struct clk isi_clk = { | ||
200 | .name = "isi_clk", | ||
201 | .pid = SAMA5D3_ID_ISI, | ||
202 | .type = CLK_TYPE_PERIPHERAL, | ||
203 | }; | ||
204 | static struct clk can0_clk = { | ||
205 | .name = "can0_clk", | ||
206 | .pid = SAMA5D3_ID_CAN0, | ||
207 | .type = CLK_TYPE_PERIPHERAL, | ||
208 | .div = AT91_PMC_PCR_DIV2, | ||
209 | }; | ||
210 | static struct clk can1_clk = { | ||
211 | .name = "can1_clk", | ||
212 | .pid = SAMA5D3_ID_CAN1, | ||
213 | .type = CLK_TYPE_PERIPHERAL, | ||
214 | .div = AT91_PMC_PCR_DIV2, | ||
215 | }; | ||
216 | static struct clk ssc0_clk = { | ||
217 | .name = "ssc0_clk", | ||
218 | .pid = SAMA5D3_ID_SSC0, | ||
219 | .type = CLK_TYPE_PERIPHERAL, | ||
220 | .div = AT91_PMC_PCR_DIV2, | ||
221 | }; | ||
222 | static struct clk ssc1_clk = { | ||
223 | .name = "ssc1_clk", | ||
224 | .pid = SAMA5D3_ID_SSC1, | ||
225 | .type = CLK_TYPE_PERIPHERAL, | ||
226 | .div = AT91_PMC_PCR_DIV2, | ||
227 | }; | ||
228 | static struct clk sha_clk = { | ||
229 | .name = "sha_clk", | ||
230 | .pid = SAMA5D3_ID_SHA, | ||
231 | .type = CLK_TYPE_PERIPHERAL, | ||
232 | .div = AT91_PMC_PCR_DIV8, | ||
233 | }; | ||
234 | static struct clk aes_clk = { | ||
235 | .name = "aes_clk", | ||
236 | .pid = SAMA5D3_ID_AES, | ||
237 | .type = CLK_TYPE_PERIPHERAL, | ||
238 | }; | ||
239 | static struct clk tdes_clk = { | ||
240 | .name = "tdes_clk", | ||
241 | .pid = SAMA5D3_ID_TDES, | ||
242 | .type = CLK_TYPE_PERIPHERAL, | ||
243 | }; | ||
244 | |||
245 | static struct clk *periph_clocks[] __initdata = { | ||
246 | &pioA_clk, | ||
247 | &pioB_clk, | ||
248 | &pioC_clk, | ||
249 | &pioD_clk, | ||
250 | &pioE_clk, | ||
251 | &usart0_clk, | ||
252 | &usart1_clk, | ||
253 | &usart2_clk, | ||
254 | &usart3_clk, | ||
255 | &uart0_clk, | ||
256 | &uart1_clk, | ||
257 | &twi0_clk, | ||
258 | &twi1_clk, | ||
259 | &twi2_clk, | ||
260 | &mmc0_clk, | ||
261 | &mmc1_clk, | ||
262 | &mmc2_clk, | ||
263 | &spi0_clk, | ||
264 | &spi1_clk, | ||
265 | &tcb0_clk, | ||
266 | &tcb1_clk, | ||
267 | &adc_clk, | ||
268 | &adc_op_clk, | ||
269 | &dma0_clk, | ||
270 | &dma1_clk, | ||
271 | &uhphs_clk, | ||
272 | &udphs_clk, | ||
273 | &macb0_clk, | ||
274 | &macb1_clk, | ||
275 | &lcdc_clk, | ||
276 | &isi_clk, | ||
277 | &can0_clk, | ||
278 | &can1_clk, | ||
279 | &ssc0_clk, | ||
280 | &ssc1_clk, | ||
281 | &sha_clk, | ||
282 | &aes_clk, | ||
283 | &tdes_clk, | ||
284 | }; | ||
285 | |||
286 | static struct clk pck0 = { | ||
287 | .name = "pck0", | ||
288 | .pmc_mask = AT91_PMC_PCK0, | ||
289 | .type = CLK_TYPE_PROGRAMMABLE, | ||
290 | .id = 0, | ||
291 | }; | ||
292 | |||
293 | static struct clk pck1 = { | ||
294 | .name = "pck1", | ||
295 | .pmc_mask = AT91_PMC_PCK1, | ||
296 | .type = CLK_TYPE_PROGRAMMABLE, | ||
297 | .id = 1, | ||
298 | }; | ||
299 | |||
300 | static struct clk pck2 = { | ||
301 | .name = "pck2", | ||
302 | .pmc_mask = AT91_PMC_PCK2, | ||
303 | .type = CLK_TYPE_PROGRAMMABLE, | ||
304 | .id = 2, | ||
305 | }; | ||
306 | |||
307 | static struct clk_lookup periph_clocks_lookups[] = { | ||
308 | /* lookup table for DT entries */ | ||
309 | CLKDEV_CON_DEV_ID("usart", "ffffee00.serial", &mck), | ||
310 | CLKDEV_CON_DEV_ID(NULL, "fffff200.gpio", &pioA_clk), | ||
311 | CLKDEV_CON_DEV_ID(NULL, "fffff400.gpio", &pioB_clk), | ||
312 | CLKDEV_CON_DEV_ID(NULL, "fffff600.gpio", &pioC_clk), | ||
313 | CLKDEV_CON_DEV_ID(NULL, "fffff800.gpio", &pioD_clk), | ||
314 | CLKDEV_CON_DEV_ID(NULL, "fffffa00.gpio", &pioE_clk), | ||
315 | CLKDEV_CON_DEV_ID("usart", "f001c000.serial", &usart0_clk), | ||
316 | CLKDEV_CON_DEV_ID("usart", "f0020000.serial", &usart1_clk), | ||
317 | CLKDEV_CON_DEV_ID("usart", "f8020000.serial", &usart2_clk), | ||
318 | CLKDEV_CON_DEV_ID("usart", "f8024000.serial", &usart3_clk), | ||
319 | CLKDEV_CON_DEV_ID(NULL, "f0014000.i2c", &twi0_clk), | ||
320 | CLKDEV_CON_DEV_ID(NULL, "f0018000.i2c", &twi1_clk), | ||
321 | CLKDEV_CON_DEV_ID(NULL, "f801c000.i2c", &twi2_clk), | ||
322 | CLKDEV_CON_DEV_ID("mci_clk", "f0000000.mmc", &mmc0_clk), | ||
323 | CLKDEV_CON_DEV_ID("mci_clk", "f8000000.mmc", &mmc1_clk), | ||
324 | CLKDEV_CON_DEV_ID("mci_clk", "f8004000.mmc", &mmc2_clk), | ||
325 | CLKDEV_CON_DEV_ID("spi_clk", "f0004000.spi", &spi0_clk), | ||
326 | CLKDEV_CON_DEV_ID("spi_clk", "f8008000.spi", &spi1_clk), | ||
327 | CLKDEV_CON_DEV_ID("t0_clk", "f0010000.timer", &tcb0_clk), | ||
328 | CLKDEV_CON_DEV_ID("t0_clk", "f8014000.timer", &tcb1_clk), | ||
329 | CLKDEV_CON_DEV_ID("tsc_clk", "f8018000.tsadcc", &adc_clk), | ||
330 | CLKDEV_CON_DEV_ID("dma_clk", "ffffe600.dma-controller", &dma0_clk), | ||
331 | CLKDEV_CON_DEV_ID("dma_clk", "ffffe800.dma-controller", &dma1_clk), | ||
332 | CLKDEV_CON_DEV_ID("hclk", "600000.ohci", &uhphs_clk), | ||
333 | CLKDEV_CON_DEV_ID("ohci_clk", "600000.ohci", &uhphs_clk), | ||
334 | CLKDEV_CON_DEV_ID("ehci_clk", "700000.ehci", &uhphs_clk), | ||
335 | CLKDEV_CON_DEV_ID("pclk", "500000.gadget", &udphs_clk), | ||
336 | CLKDEV_CON_DEV_ID("hclk", "500000.gadget", &utmi_clk), | ||
337 | CLKDEV_CON_DEV_ID("hclk", "f0028000.ethernet", &macb0_clk), | ||
338 | CLKDEV_CON_DEV_ID("pclk", "f0028000.ethernet", &macb0_clk), | ||
339 | CLKDEV_CON_DEV_ID("hclk", "f802c000.ethernet", &macb1_clk), | ||
340 | CLKDEV_CON_DEV_ID("pclk", "f802c000.ethernet", &macb1_clk), | ||
341 | CLKDEV_CON_DEV_ID("pclk", "f0008000.ssc", &ssc0_clk), | ||
342 | CLKDEV_CON_DEV_ID("pclk", "f000c000.ssc", &ssc1_clk), | ||
343 | CLKDEV_CON_DEV_ID("can_clk", "f000c000.can", &can0_clk), | ||
344 | CLKDEV_CON_DEV_ID("can_clk", "f8010000.can", &can1_clk), | ||
345 | CLKDEV_CON_DEV_ID("sha_clk", "f8034000.sha", &sha_clk), | ||
346 | CLKDEV_CON_DEV_ID("aes_clk", "f8038000.aes", &aes_clk), | ||
347 | CLKDEV_CON_DEV_ID("tdes_clk", "f803c000.tdes", &tdes_clk), | ||
348 | }; | ||
349 | |||
350 | static void __init sama5d3_register_clocks(void) | ||
351 | { | ||
352 | int i; | ||
353 | |||
354 | for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) | ||
355 | clk_register(periph_clocks[i]); | ||
356 | |||
357 | clkdev_add_table(periph_clocks_lookups, | ||
358 | ARRAY_SIZE(periph_clocks_lookups)); | ||
359 | |||
360 | clk_register(&pck0); | ||
361 | clk_register(&pck1); | ||
362 | clk_register(&pck2); | ||
363 | } | ||
364 | |||
365 | /* -------------------------------------------------------------------- | ||
366 | * AT91SAM9x5 processor initialization | ||
367 | * -------------------------------------------------------------------- */ | ||
368 | |||
369 | static void __init sama5d3_map_io(void) | ||
370 | { | ||
371 | at91_init_sram(0, SAMA5D3_SRAM_BASE, SAMA5D3_SRAM_SIZE); | ||
372 | } | ||
373 | |||
374 | AT91_SOC_START(sama5d3) | ||
375 | .map_io = sama5d3_map_io, | ||
376 | .register_clocks = sama5d3_register_clocks, | ||
377 | AT91_SOC_END | ||
diff --git a/arch/arm/mach-at91/setup.c b/arch/arm/mach-at91/setup.c index 4b678478cf95..2ecd1693c804 100644 --- a/arch/arm/mach-at91/setup.c +++ b/arch/arm/mach-at91/setup.c | |||
@@ -151,6 +151,11 @@ static void __init soc_detect(u32 dbgu_base) | |||
151 | at91_soc_initdata.type = AT91_SOC_SAM9N12; | 151 | at91_soc_initdata.type = AT91_SOC_SAM9N12; |
152 | at91_boot_soc = at91sam9n12_soc; | 152 | at91_boot_soc = at91sam9n12_soc; |
153 | break; | 153 | break; |
154 | |||
155 | case ARCH_ID_SAMA5D3: | ||
156 | at91_soc_initdata.type = AT91_SOC_SAMA5D3; | ||
157 | at91_boot_soc = sama5d3_soc; | ||
158 | break; | ||
154 | } | 159 | } |
155 | 160 | ||
156 | /* at91sam9g10 */ | 161 | /* at91sam9g10 */ |
@@ -206,6 +211,23 @@ static void __init soc_detect(u32 dbgu_base) | |||
206 | break; | 211 | break; |
207 | } | 212 | } |
208 | } | 213 | } |
214 | |||
215 | if (at91_soc_initdata.type == AT91_SOC_SAMA5D3) { | ||
216 | switch (at91_soc_initdata.exid) { | ||
217 | case ARCH_EXID_SAMA5D31: | ||
218 | at91_soc_initdata.subtype = AT91_SOC_SAMA5D31; | ||
219 | break; | ||
220 | case ARCH_EXID_SAMA5D33: | ||
221 | at91_soc_initdata.subtype = AT91_SOC_SAMA5D33; | ||
222 | break; | ||
223 | case ARCH_EXID_SAMA5D34: | ||
224 | at91_soc_initdata.subtype = AT91_SOC_SAMA5D34; | ||
225 | break; | ||
226 | case ARCH_EXID_SAMA5D35: | ||
227 | at91_soc_initdata.subtype = AT91_SOC_SAMA5D35; | ||
228 | break; | ||
229 | } | ||
230 | } | ||
209 | } | 231 | } |
210 | 232 | ||
211 | static const char *soc_name[] = { | 233 | static const char *soc_name[] = { |
@@ -219,6 +241,7 @@ static const char *soc_name[] = { | |||
219 | [AT91_SOC_SAM9RL] = "at91sam9rl", | 241 | [AT91_SOC_SAM9RL] = "at91sam9rl", |
220 | [AT91_SOC_SAM9X5] = "at91sam9x5", | 242 | [AT91_SOC_SAM9X5] = "at91sam9x5", |
221 | [AT91_SOC_SAM9N12] = "at91sam9n12", | 243 | [AT91_SOC_SAM9N12] = "at91sam9n12", |
244 | [AT91_SOC_SAMA5D3] = "sama5d3", | ||
222 | [AT91_SOC_NONE] = "Unknown" | 245 | [AT91_SOC_NONE] = "Unknown" |
223 | }; | 246 | }; |
224 | 247 | ||
@@ -241,6 +264,10 @@ static const char *soc_subtype_name[] = { | |||
241 | [AT91_SOC_SAM9X35] = "at91sam9x35", | 264 | [AT91_SOC_SAM9X35] = "at91sam9x35", |
242 | [AT91_SOC_SAM9G25] = "at91sam9g25", | 265 | [AT91_SOC_SAM9G25] = "at91sam9g25", |
243 | [AT91_SOC_SAM9X25] = "at91sam9x25", | 266 | [AT91_SOC_SAM9X25] = "at91sam9x25", |
267 | [AT91_SOC_SAMA5D31] = "sama5d31", | ||
268 | [AT91_SOC_SAMA5D33] = "sama5d33", | ||
269 | [AT91_SOC_SAMA5D34] = "sama5d34", | ||
270 | [AT91_SOC_SAMA5D35] = "sama5d35", | ||
244 | [AT91_SOC_SUBTYPE_NONE] = "Unknown" | 271 | [AT91_SOC_SUBTYPE_NONE] = "Unknown" |
245 | }; | 272 | }; |
246 | 273 | ||
diff --git a/arch/arm/mach-at91/soc.h b/arch/arm/mach-at91/soc.h index f3d350278565..43a225f9e713 100644 --- a/arch/arm/mach-at91/soc.h +++ b/arch/arm/mach-at91/soc.h | |||
@@ -22,6 +22,7 @@ extern struct at91_init_soc at91sam9g45_soc; | |||
22 | extern struct at91_init_soc at91sam9rl_soc; | 22 | extern struct at91_init_soc at91sam9rl_soc; |
23 | extern struct at91_init_soc at91sam9x5_soc; | 23 | extern struct at91_init_soc at91sam9x5_soc; |
24 | extern struct at91_init_soc at91sam9n12_soc; | 24 | extern struct at91_init_soc at91sam9n12_soc; |
25 | extern struct at91_init_soc sama5d3_soc; | ||
25 | 26 | ||
26 | #define AT91_SOC_START(_name) \ | 27 | #define AT91_SOC_START(_name) \ |
27 | struct at91_init_soc __initdata _name##_soc \ | 28 | struct at91_init_soc __initdata _name##_soc \ |
@@ -68,3 +69,7 @@ static inline int at91_soc_is_enabled(void) | |||
68 | #if !defined(CONFIG_SOC_AT91SAM9N12) | 69 | #if !defined(CONFIG_SOC_AT91SAM9N12) |
69 | #define at91sam9n12_soc at91_boot_soc | 70 | #define at91sam9n12_soc at91_boot_soc |
70 | #endif | 71 | #endif |
72 | |||
73 | #if !defined(CONFIG_SOC_SAMA5D3) | ||
74 | #define sama5d3_soc at91_boot_soc | ||
75 | #endif | ||