diff options
author | Paul Mundt <lethal@linux-sh.org> | 2007-06-20 05:27:10 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2007-06-20 05:27:10 -0400 |
commit | 2b1bd1ac5d4bffe3fd542bfe1784a583bd7df4fa (patch) | |
tree | 9c9840807d84cb4d9ca981fbae5093eef1c9ed12 /arch/sh/kernel/cpu/sh4a | |
parent | 027e56e68543780870fda74360ca45e392c50e1c (diff) |
sh: Preliminary support for the SH-X3 CPU.
This adds basic support for UP SH-X3.
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/kernel/cpu/sh4a')
-rw-r--r-- | arch/sh/kernel/cpu/sh4a/Makefile | 2 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh4a/clock-shx3.c | 135 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh4a/setup-shx3.c | 85 |
3 files changed, 222 insertions, 0 deletions
diff --git a/arch/sh/kernel/cpu/sh4a/Makefile b/arch/sh/kernel/cpu/sh4a/Makefile index ab7422f8f820..400623286487 100644 --- a/arch/sh/kernel/cpu/sh4a/Makefile +++ b/arch/sh/kernel/cpu/sh4a/Makefile | |||
@@ -9,6 +9,7 @@ obj-$(CONFIG_CPU_SUBTYPE_SH7785) += setup-sh7785.o | |||
9 | obj-$(CONFIG_CPU_SUBTYPE_SH73180) += setup-sh73180.o | 9 | obj-$(CONFIG_CPU_SUBTYPE_SH73180) += setup-sh73180.o |
10 | obj-$(CONFIG_CPU_SUBTYPE_SH7343) += setup-sh7343.o | 10 | obj-$(CONFIG_CPU_SUBTYPE_SH7343) += setup-sh7343.o |
11 | obj-$(CONFIG_CPU_SUBTYPE_SH7722) += setup-sh7722.o | 11 | obj-$(CONFIG_CPU_SUBTYPE_SH7722) += setup-sh7722.o |
12 | obj-$(CONFIG_CPU_SUBTYPE_SHX3) += setup-shx3.o | ||
12 | 13 | ||
13 | # Primary on-chip clocks (common) | 14 | # Primary on-chip clocks (common) |
14 | clock-$(CONFIG_CPU_SUBTYPE_SH73180) := clock-sh73180.o | 15 | clock-$(CONFIG_CPU_SUBTYPE_SH73180) := clock-sh73180.o |
@@ -17,5 +18,6 @@ clock-$(CONFIG_CPU_SUBTYPE_SH7780) := clock-sh7780.o | |||
17 | clock-$(CONFIG_CPU_SUBTYPE_SH7785) := clock-sh7785.o | 18 | clock-$(CONFIG_CPU_SUBTYPE_SH7785) := clock-sh7785.o |
18 | clock-$(CONFIG_CPU_SUBTYPE_SH7343) := clock-sh7343.o | 19 | clock-$(CONFIG_CPU_SUBTYPE_SH7343) := clock-sh7343.o |
19 | clock-$(CONFIG_CPU_SUBTYPE_SH7722) := clock-sh7722.o | 20 | clock-$(CONFIG_CPU_SUBTYPE_SH7722) := clock-sh7722.o |
21 | clock-$(CONFIG_CPU_SUBTYPE_SHX3) := clock-shx3.o | ||
20 | 22 | ||
21 | obj-y += $(clock-y) | 23 | obj-y += $(clock-y) |
diff --git a/arch/sh/kernel/cpu/sh4a/clock-shx3.c b/arch/sh/kernel/cpu/sh4a/clock-shx3.c new file mode 100644 index 000000000000..c630b29e06a8 --- /dev/null +++ b/arch/sh/kernel/cpu/sh4a/clock-shx3.c | |||
@@ -0,0 +1,135 @@ | |||
1 | /* | ||
2 | * arch/sh/kernel/cpu/sh4/clock-shx3.c | ||
3 | * | ||
4 | * SH-X3 support for the clock framework | ||
5 | * | ||
6 | * Copyright (C) 2006-2007 Renesas Technology Corp. | ||
7 | * Copyright (C) 2006-2007 Renesas Solutions Corp. | ||
8 | * Copyright (C) 2006-2007 Paul Mundt | ||
9 | * | ||
10 | * This file is subject to the terms and conditions of the GNU General Public | ||
11 | * License. See the file "COPYING" in the main directory of this archive | ||
12 | * for more details. | ||
13 | */ | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/kernel.h> | ||
16 | #include <asm/clock.h> | ||
17 | #include <asm/freq.h> | ||
18 | #include <asm/io.h> | ||
19 | |||
20 | static int ifc_divisors[] = { 1, 2, 4 ,6 }; | ||
21 | static int bfc_divisors[] = { 1, 1, 1, 1, 1, 12, 16, 18, 24, 32, 36, 48 }; | ||
22 | static int pfc_divisors[] = { 1, 1, 1, 1, 1, 1, 1, 18, 24, 32, 36, 48 }; | ||
23 | static int cfc_divisors[] = { 1, 1, 4, 6 }; | ||
24 | |||
25 | #define IFC_POS 28 | ||
26 | #define IFC_MSK 0x0003 | ||
27 | #define BFC_MSK 0x000f | ||
28 | #define PFC_MSK 0x000f | ||
29 | #define CFC_MSK 0x0003 | ||
30 | #define BFC_POS 16 | ||
31 | #define PFC_POS 0 | ||
32 | #define CFC_POS 20 | ||
33 | |||
34 | static void master_clk_init(struct clk *clk) | ||
35 | { | ||
36 | clk->rate *= pfc_divisors[(ctrl_inl(FRQCR) >> PFC_POS) & PFC_MSK]; | ||
37 | } | ||
38 | |||
39 | static struct clk_ops shx3_master_clk_ops = { | ||
40 | .init = master_clk_init, | ||
41 | }; | ||
42 | |||
43 | static void module_clk_recalc(struct clk *clk) | ||
44 | { | ||
45 | int idx = ((ctrl_inl(FRQCR) >> PFC_POS) & PFC_MSK); | ||
46 | clk->rate = clk->parent->rate / pfc_divisors[idx]; | ||
47 | } | ||
48 | |||
49 | static struct clk_ops shx3_module_clk_ops = { | ||
50 | .recalc = module_clk_recalc, | ||
51 | }; | ||
52 | |||
53 | static void bus_clk_recalc(struct clk *clk) | ||
54 | { | ||
55 | int idx = ((ctrl_inl(FRQCR) >> BFC_POS) & BFC_MSK); | ||
56 | clk->rate = clk->parent->rate / bfc_divisors[idx]; | ||
57 | } | ||
58 | |||
59 | static struct clk_ops shx3_bus_clk_ops = { | ||
60 | .recalc = bus_clk_recalc, | ||
61 | }; | ||
62 | |||
63 | static void cpu_clk_recalc(struct clk *clk) | ||
64 | { | ||
65 | int idx = ((ctrl_inl(FRQCR) >> IFC_POS) & IFC_MSK); | ||
66 | clk->rate = clk->parent->rate / ifc_divisors[idx]; | ||
67 | } | ||
68 | |||
69 | static struct clk_ops shx3_cpu_clk_ops = { | ||
70 | .recalc = cpu_clk_recalc, | ||
71 | }; | ||
72 | |||
73 | static struct clk_ops *shx3_clk_ops[] = { | ||
74 | &shx3_master_clk_ops, | ||
75 | &shx3_module_clk_ops, | ||
76 | &shx3_bus_clk_ops, | ||
77 | &shx3_cpu_clk_ops, | ||
78 | }; | ||
79 | |||
80 | void __init arch_init_clk_ops(struct clk_ops **ops, int idx) | ||
81 | { | ||
82 | if (idx < ARRAY_SIZE(shx3_clk_ops)) | ||
83 | *ops = shx3_clk_ops[idx]; | ||
84 | } | ||
85 | |||
86 | static void shyway_clk_recalc(struct clk *clk) | ||
87 | { | ||
88 | int idx = ((ctrl_inl(FRQCR) >> CFC_POS) & CFC_MSK); | ||
89 | clk->rate = clk->parent->rate / cfc_divisors[idx]; | ||
90 | } | ||
91 | |||
92 | static struct clk_ops shx3_shyway_clk_ops = { | ||
93 | .recalc = shyway_clk_recalc, | ||
94 | }; | ||
95 | |||
96 | static struct clk shx3_shyway_clk = { | ||
97 | .name = "shyway_clk", | ||
98 | .flags = CLK_ALWAYS_ENABLED, | ||
99 | .ops = &shx3_shyway_clk_ops, | ||
100 | }; | ||
101 | |||
102 | /* | ||
103 | * Additional SHx3-specific on-chip clocks that aren't already part of the | ||
104 | * clock framework | ||
105 | */ | ||
106 | static struct clk *shx3_onchip_clocks[] = { | ||
107 | &shx3_shyway_clk, | ||
108 | }; | ||
109 | |||
110 | static int __init shx3_clk_init(void) | ||
111 | { | ||
112 | struct clk *clk = clk_get(NULL, "master_clk"); | ||
113 | int i; | ||
114 | |||
115 | for (i = 0; i < ARRAY_SIZE(shx3_onchip_clocks); i++) { | ||
116 | struct clk *clkp = shx3_onchip_clocks[i]; | ||
117 | |||
118 | clkp->parent = clk; | ||
119 | clk_register(clkp); | ||
120 | clk_enable(clkp); | ||
121 | } | ||
122 | |||
123 | /* | ||
124 | * Now that we have the rest of the clocks registered, we need to | ||
125 | * force the parent clock to propagate so that these clocks will | ||
126 | * automatically figure out their rate. We cheat by handing the | ||
127 | * parent clock its current rate and forcing child propagation. | ||
128 | */ | ||
129 | clk_set_rate(clk, clk_get_rate(clk)); | ||
130 | |||
131 | clk_put(clk); | ||
132 | |||
133 | return 0; | ||
134 | } | ||
135 | arch_initcall(shx3_clk_init); | ||
diff --git a/arch/sh/kernel/cpu/sh4a/setup-shx3.c b/arch/sh/kernel/cpu/sh4a/setup-shx3.c new file mode 100644 index 000000000000..70683ea12b83 --- /dev/null +++ b/arch/sh/kernel/cpu/sh4a/setup-shx3.c | |||
@@ -0,0 +1,85 @@ | |||
1 | /* | ||
2 | * SH-X3 Setup | ||
3 | * | ||
4 | * Copyright (C) 2007 Paul Mundt | ||
5 | * | ||
6 | * This file is subject to the terms and conditions of the GNU General Public | ||
7 | * License. See the file "COPYING" in the main directory of this archive | ||
8 | * for more details. | ||
9 | */ | ||
10 | #include <linux/platform_device.h> | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/serial.h> | ||
13 | #include <linux/io.h> | ||
14 | #include <asm/sci.h> | ||
15 | |||
16 | static struct plat_sci_port sci_platform_data[] = { | ||
17 | { | ||
18 | .mapbase = 0xffc30000, | ||
19 | .flags = UPF_BOOT_AUTOCONF, | ||
20 | .type = PORT_SCIF, | ||
21 | .irqs = { 40, 41, 43, 42 }, | ||
22 | }, { | ||
23 | .mapbase = 0xffc40000, | ||
24 | .flags = UPF_BOOT_AUTOCONF, | ||
25 | .type = PORT_SCIF, | ||
26 | .irqs = { 44, 45, 47, 46 }, | ||
27 | }, { | ||
28 | .mapbase = 0xffc50000, | ||
29 | .flags = UPF_BOOT_AUTOCONF, | ||
30 | .type = PORT_SCIF, | ||
31 | .irqs = { 48, 49, 51, 50 }, | ||
32 | }, { | ||
33 | .mapbase = 0xffc60000, | ||
34 | .flags = UPF_BOOT_AUTOCONF, | ||
35 | .type = PORT_SCIF, | ||
36 | .irqs = { 52, 53, 55, 54 }, | ||
37 | }, { | ||
38 | .flags = 0, | ||
39 | } | ||
40 | }; | ||
41 | |||
42 | static struct platform_device sci_device = { | ||
43 | .name = "sh-sci", | ||
44 | .id = -1, | ||
45 | .dev = { | ||
46 | .platform_data = sci_platform_data, | ||
47 | }, | ||
48 | }; | ||
49 | |||
50 | static struct platform_device *shx3_devices[] __initdata = { | ||
51 | &sci_device, | ||
52 | }; | ||
53 | |||
54 | static int __init shx3_devices_setup(void) | ||
55 | { | ||
56 | return platform_add_devices(shx3_devices, | ||
57 | ARRAY_SIZE(shx3_devices)); | ||
58 | } | ||
59 | __initcall(shx3_devices_setup); | ||
60 | |||
61 | static struct intc2_data intc2_irq_table[] = { | ||
62 | { 16, 0, 0, 0, 1, 2 }, /* TMU0 */ | ||
63 | { 40, 4, 0, 0x20, 0, 3 }, /* SCIF0 ERI */ | ||
64 | { 41, 4, 0, 0x20, 1, 3 }, /* SCIF0 RXI */ | ||
65 | { 42, 4, 0, 0x20, 2, 3 }, /* SCIF0 BRI */ | ||
66 | { 43, 4, 0, 0x20, 3, 3 }, /* SCIF0 TXI */ | ||
67 | }; | ||
68 | |||
69 | static struct intc2_desc intc2_irq_desc __read_mostly = { | ||
70 | .prio_base = 0xfe410000, | ||
71 | .msk_base = 0xfe410820, | ||
72 | .mskclr_base = 0xfe410850, | ||
73 | |||
74 | .intc2_data = intc2_irq_table, | ||
75 | .nr_irqs = ARRAY_SIZE(intc2_irq_table), | ||
76 | |||
77 | .chip = { | ||
78 | .name = "INTC2-SHX3", | ||
79 | }, | ||
80 | }; | ||
81 | |||
82 | void __init init_IRQ_intc2(void) | ||
83 | { | ||
84 | register_intc2_controller(&intc2_irq_desc); | ||
85 | } | ||