aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/ralink
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-03-02 10:44:16 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-03-02 10:44:16 -0500
commitaebb2afd5420c860b7fbc3882a323ef1247fbf16 (patch)
tree05ee0efcebca5ec421de44de7a6d6271088c64a8 /arch/mips/ralink
parent8eae508b7c6ff502a71d0293b69e97c5505d5840 (diff)
parentedb15d83a875a1f4b1576188844db5c330c3267d (diff)
Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus
Pull MIPS updates from Ralf Baechle: o Add basic support for the Mediatek/Ralink Wireless SoC family. o The Qualcomm Atheros platform is extended by support for the new QCA955X SoC series as well as a bunch of patches that get the code ready for OF support. o Lantiq and BCM47XX platform have a few improvements and bug fixes. o MIPS has sent a few patches that get the kernel ready for the upcoming microMIPS support. o The rest of the series is made up of small bug fixes and cleanups that relate to various parts of the MIPS code. The biggy in there is a whitespace cleanup. After I was sent another set of whitespace cleanup patches I decided it was the time to clean the whitespace "issues" for once and and that touches many files below arch/mips/. Fix up silly conflicts, mostly due to whitespace cleanups. * 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus: (105 commits) MIPS: Quit exporting kernel internel break codes to uapi/asm/break.h MIPS: remove broken conditional inside vpe loader code MIPS: SMTC: fix implicit declaration of set_vi_handler MIPS: early_printk: drop __init annotations MIPS: Probe for and report hardware virtualization support. MIPS: ath79: add support for the Qualcomm Atheros AP136-010 board MIPS: ath79: add USB controller registration code for the QCA955X SoCs MIPS: ath79: add PCI controller registration code for the QCA955X SoCs MIPS: ath79: add WMAC registration code for the QCA955X SoCs MIPS: ath79: register UART for the QCA955X SoCs MIPS: ath79: add QCA955X specific glue to ath79_device_reset_{set, clear} MIPS: ath79: add GPIO setup code for the QCA955X SoCs MIPS: ath79: add IRQ handling code for the QCA955X SoCs MIPS: ath79: add clock setup code for the QCA955X SoCs MIPS: ath79: add SoC detection code for the QCA955X SoCs MIPS: ath79: add early printk support for the QCA955X SoCs MIPS: ath79: fix WMAC IRQ resource assignment mips: reserve elfcorehdr mips: Make sure kernel memory is in iomem MIPS: ath79: use dynamically allocated USB platform devices ...
Diffstat (limited to 'arch/mips/ralink')
-rw-r--r--arch/mips/ralink/Kconfig32
-rw-r--r--arch/mips/ralink/Makefile15
-rw-r--r--arch/mips/ralink/Platform10
-rw-r--r--arch/mips/ralink/clk.c72
-rw-r--r--arch/mips/ralink/common.h44
-rw-r--r--arch/mips/ralink/dts/Makefile1
-rw-r--r--arch/mips/ralink/dts/rt3050.dtsi106
-rw-r--r--arch/mips/ralink/dts/rt3052_eval.dts52
-rw-r--r--arch/mips/ralink/early_printk.c44
-rw-r--r--arch/mips/ralink/irq.c180
-rw-r--r--arch/mips/ralink/of.c107
-rw-r--r--arch/mips/ralink/prom.c69
-rw-r--r--arch/mips/ralink/reset.c44
-rw-r--r--arch/mips/ralink/rt305x.c242
14 files changed, 1018 insertions, 0 deletions
diff --git a/arch/mips/ralink/Kconfig b/arch/mips/ralink/Kconfig
new file mode 100644
index 000000000000..a0b0197cab0a
--- /dev/null
+++ b/arch/mips/ralink/Kconfig
@@ -0,0 +1,32 @@
1if RALINK
2
3choice
4 prompt "Ralink SoC selection"
5 default SOC_RT305X
6 help
7 Select Ralink MIPS SoC type.
8
9 config SOC_RT305X
10 bool "RT305x"
11 select USB_ARCH_HAS_HCD
12 select USB_ARCH_HAS_OHCI
13 select USB_ARCH_HAS_EHCI
14
15endchoice
16
17choice
18 prompt "Devicetree selection"
19 default DTB_RT_NONE
20 help
21 Select the devicetree.
22
23 config DTB_RT_NONE
24 bool "None"
25
26 config DTB_RT305X_EVAL
27 bool "RT305x eval kit"
28 depends on SOC_RT305X
29
30endchoice
31
32endif
diff --git a/arch/mips/ralink/Makefile b/arch/mips/ralink/Makefile
new file mode 100644
index 000000000000..939757f0e71f
--- /dev/null
+++ b/arch/mips/ralink/Makefile
@@ -0,0 +1,15 @@
1# This program is free software; you can redistribute it and/or modify it
2# under the terms of the GNU General Public License version 2 as published
3# by the Free Software Foundation.#
4# Makefile for the Ralink common stuff
5#
6# Copyright (C) 2009-2011 Gabor Juhos <juhosg@openwrt.org>
7# Copyright (C) 2013 John Crispin <blogic@openwrt.org>
8
9obj-y := prom.o of.o reset.o clk.o irq.o
10
11obj-$(CONFIG_SOC_RT305X) += rt305x.o
12
13obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
14
15obj-y += dts/
diff --git a/arch/mips/ralink/Platform b/arch/mips/ralink/Platform
new file mode 100644
index 000000000000..6babd65765e6
--- /dev/null
+++ b/arch/mips/ralink/Platform
@@ -0,0 +1,10 @@
1#
2# Ralink SoC common stuff
3#
4core-$(CONFIG_RALINK) += arch/mips/ralink/
5cflags-$(CONFIG_RALINK) += -I$(srctree)/arch/mips/include/asm/mach-ralink
6
7#
8# Ralink RT305x
9#
10load-$(CONFIG_SOC_RT305X) += 0xffffffff80000000
diff --git a/arch/mips/ralink/clk.c b/arch/mips/ralink/clk.c
new file mode 100644
index 000000000000..8dfa22ff300b
--- /dev/null
+++ b/arch/mips/ralink/clk.c
@@ -0,0 +1,72 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License version 2 as published
4 * by the Free Software Foundation.
5 *
6 * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org>
7 * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
8 */
9
10#include <linux/kernel.h>
11#include <linux/module.h>
12#include <linux/clkdev.h>
13#include <linux/clk.h>
14
15#include <asm/time.h>
16
17#include "common.h"
18
19struct clk {
20 struct clk_lookup cl;
21 unsigned long rate;
22};
23
24void ralink_clk_add(const char *dev, unsigned long rate)
25{
26 struct clk *clk = kzalloc(sizeof(struct clk), GFP_KERNEL);
27
28 if (!clk)
29 panic("failed to add clock\n");
30
31 clk->cl.dev_id = dev;
32 clk->cl.clk = clk;
33
34 clk->rate = rate;
35
36 clkdev_add(&clk->cl);
37}
38
39/*
40 * Linux clock API
41 */
42int clk_enable(struct clk *clk)
43{
44 return 0;
45}
46EXPORT_SYMBOL_GPL(clk_enable);
47
48void clk_disable(struct clk *clk)
49{
50}
51EXPORT_SYMBOL_GPL(clk_disable);
52
53unsigned long clk_get_rate(struct clk *clk)
54{
55 return clk->rate;
56}
57EXPORT_SYMBOL_GPL(clk_get_rate);
58
59void __init plat_time_init(void)
60{
61 struct clk *clk;
62
63 ralink_of_remap();
64
65 ralink_clk_init();
66 clk = clk_get_sys("cpu", NULL);
67 if (IS_ERR(clk))
68 panic("unable to get CPU clock, err=%ld", PTR_ERR(clk));
69 pr_info("CPU Clock: %ldMHz\n", clk_get_rate(clk) / 1000000);
70 mips_hpt_frequency = clk_get_rate(clk) / 2;
71 clk_put(clk);
72}
diff --git a/arch/mips/ralink/common.h b/arch/mips/ralink/common.h
new file mode 100644
index 000000000000..300990313e1b
--- /dev/null
+++ b/arch/mips/ralink/common.h
@@ -0,0 +1,44 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License version 2 as published
4 * by the Free Software Foundation.
5 *
6 * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
7 */
8
9#ifndef _RALINK_COMMON_H__
10#define _RALINK_COMMON_H__
11
12#define RAMIPS_SYS_TYPE_LEN 32
13
14struct ralink_pinmux_grp {
15 const char *name;
16 u32 mask;
17 int gpio_first;
18 int gpio_last;
19};
20
21struct ralink_pinmux {
22 struct ralink_pinmux_grp *mode;
23 struct ralink_pinmux_grp *uart;
24 int uart_shift;
25 void (*wdt_reset)(void);
26};
27extern struct ralink_pinmux gpio_pinmux;
28
29struct ralink_soc_info {
30 unsigned char sys_type[RAMIPS_SYS_TYPE_LEN];
31 unsigned char *compatible;
32};
33extern struct ralink_soc_info soc_info;
34
35extern void ralink_of_remap(void);
36
37extern void ralink_clk_init(void);
38extern void ralink_clk_add(const char *dev, unsigned long rate);
39
40extern void prom_soc_init(struct ralink_soc_info *soc_info);
41
42__iomem void *plat_of_remap_node(const char *node);
43
44#endif /* _RALINK_COMMON_H__ */
diff --git a/arch/mips/ralink/dts/Makefile b/arch/mips/ralink/dts/Makefile
new file mode 100644
index 000000000000..1a69fb300955
--- /dev/null
+++ b/arch/mips/ralink/dts/Makefile
@@ -0,0 +1 @@
obj-$(CONFIG_DTB_RT305X_EVAL) := rt3052_eval.dtb.o
diff --git a/arch/mips/ralink/dts/rt3050.dtsi b/arch/mips/ralink/dts/rt3050.dtsi
new file mode 100644
index 000000000000..069d0660e1dd
--- /dev/null
+++ b/arch/mips/ralink/dts/rt3050.dtsi
@@ -0,0 +1,106 @@
1/ {
2 #address-cells = <1>;
3 #size-cells = <1>;
4 compatible = "ralink,rt3050-soc", "ralink,rt3052-soc";
5
6 cpus {
7 cpu@0 {
8 compatible = "mips,mips24KEc";
9 };
10 };
11
12 chosen {
13 bootargs = "console=ttyS0,57600 init=/init";
14 };
15
16 cpuintc: cpuintc@0 {
17 #address-cells = <0>;
18 #interrupt-cells = <1>;
19 interrupt-controller;
20 compatible = "mti,cpu-interrupt-controller";
21 };
22
23 palmbus@10000000 {
24 compatible = "palmbus";
25 reg = <0x10000000 0x200000>;
26 ranges = <0x0 0x10000000 0x1FFFFF>;
27
28 #address-cells = <1>;
29 #size-cells = <1>;
30
31 sysc@0 {
32 compatible = "ralink,rt3052-sysc", "ralink,rt3050-sysc";
33 reg = <0x0 0x100>;
34 };
35
36 timer@100 {
37 compatible = "ralink,rt3052-wdt", "ralink,rt2880-wdt";
38 reg = <0x100 0x100>;
39 };
40
41 intc: intc@200 {
42 compatible = "ralink,rt3052-intc", "ralink,rt2880-intc";
43 reg = <0x200 0x100>;
44
45 interrupt-controller;
46 #interrupt-cells = <1>;
47
48 interrupt-parent = <&cpuintc>;
49 interrupts = <2>;
50 };
51
52 memc@300 {
53 compatible = "ralink,rt3052-memc", "ralink,rt3050-memc";
54 reg = <0x300 0x100>;
55 };
56
57 gpio0: gpio@600 {
58 compatible = "ralink,rt3052-gpio", "ralink,rt2880-gpio";
59 reg = <0x600 0x34>;
60
61 gpio-controller;
62 #gpio-cells = <2>;
63
64 ralink,ngpio = <24>;
65 ralink,regs = [ 00 04 08 0c
66 20 24 28 2c
67 30 34 ];
68 };
69
70 gpio1: gpio@638 {
71 compatible = "ralink,rt3052-gpio", "ralink,rt2880-gpio";
72 reg = <0x638 0x24>;
73
74 gpio-controller;
75 #gpio-cells = <2>;
76
77 ralink,ngpio = <16>;
78 ralink,regs = [ 00 04 08 0c
79 10 14 18 1c
80 20 24 ];
81 };
82
83 gpio2: gpio@660 {
84 compatible = "ralink,rt3052-gpio", "ralink,rt2880-gpio";
85 reg = <0x660 0x24>;
86
87 gpio-controller;
88 #gpio-cells = <2>;
89
90 ralink,ngpio = <12>;
91 ralink,regs = [ 00 04 08 0c
92 10 14 18 1c
93 20 24 ];
94 };
95
96 uartlite@c00 {
97 compatible = "ralink,rt3052-uart", "ralink,rt2880-uart", "ns16550a";
98 reg = <0xc00 0x100>;
99
100 interrupt-parent = <&intc>;
101 interrupts = <12>;
102
103 reg-shift = <2>;
104 };
105 };
106};
diff --git a/arch/mips/ralink/dts/rt3052_eval.dts b/arch/mips/ralink/dts/rt3052_eval.dts
new file mode 100644
index 000000000000..148a590bc419
--- /dev/null
+++ b/arch/mips/ralink/dts/rt3052_eval.dts
@@ -0,0 +1,52 @@
1/dts-v1/;
2
3/include/ "rt3050.dtsi"
4
5/ {
6 #address-cells = <1>;
7 #size-cells = <1>;
8 compatible = "ralink,rt3052-eval-board", "ralink,rt3052-soc";
9 model = "Ralink RT3052 evaluation board";
10
11 memory@0 {
12 reg = <0x0 0x2000000>;
13 };
14
15 palmbus@10000000 {
16 sysc@0 {
17 ralink,pinmmux = "uartlite", "spi";
18 ralink,uartmux = "gpio";
19 ralink,wdtmux = <0>;
20 };
21 };
22
23 cfi@1f000000 {
24 compatible = "cfi-flash";
25 reg = <0x1f000000 0x800000>;
26
27 bank-width = <2>;
28 device-width = <2>;
29 #address-cells = <1>;
30 #size-cells = <1>;
31
32 partition@0 {
33 label = "uboot";
34 reg = <0x0 0x30000>;
35 read-only;
36 };
37 partition@30000 {
38 label = "uboot-env";
39 reg = <0x30000 0x10000>;
40 read-only;
41 };
42 partition@40000 {
43 label = "calibration";
44 reg = <0x40000 0x10000>;
45 read-only;
46 };
47 partition@50000 {
48 label = "linux";
49 reg = <0x50000 0x7b0000>;
50 };
51 };
52};
diff --git a/arch/mips/ralink/early_printk.c b/arch/mips/ralink/early_printk.c
new file mode 100644
index 000000000000..c4ae47eb24ab
--- /dev/null
+++ b/arch/mips/ralink/early_printk.c
@@ -0,0 +1,44 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License version 2 as published
4 * by the Free Software Foundation.
5 *
6 * Copyright (C) 2011-2012 Gabor Juhos <juhosg@openwrt.org>
7 */
8
9#include <linux/io.h>
10#include <linux/serial_reg.h>
11
12#include <asm/addrspace.h>
13
14#define EARLY_UART_BASE 0x10000c00
15
16#define UART_REG_RX 0x00
17#define UART_REG_TX 0x04
18#define UART_REG_IER 0x08
19#define UART_REG_IIR 0x0c
20#define UART_REG_FCR 0x10
21#define UART_REG_LCR 0x14
22#define UART_REG_MCR 0x18
23#define UART_REG_LSR 0x1c
24
25static __iomem void *uart_membase = (__iomem void *) KSEG1ADDR(EARLY_UART_BASE);
26
27static inline void uart_w32(u32 val, unsigned reg)
28{
29 __raw_writel(val, uart_membase + reg);
30}
31
32static inline u32 uart_r32(unsigned reg)
33{
34 return __raw_readl(uart_membase + reg);
35}
36
37void prom_putchar(unsigned char ch)
38{
39 while ((uart_r32(UART_REG_LSR) & UART_LSR_THRE) == 0)
40 ;
41 uart_w32(ch, UART_REG_TX);
42 while ((uart_r32(UART_REG_LSR) & UART_LSR_THRE) == 0)
43 ;
44}
diff --git a/arch/mips/ralink/irq.c b/arch/mips/ralink/irq.c
new file mode 100644
index 000000000000..6d054c5ec9ab
--- /dev/null
+++ b/arch/mips/ralink/irq.c
@@ -0,0 +1,180 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License version 2 as published
4 * by the Free Software Foundation.
5 *
6 * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
7 * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
8 */
9
10#include <linux/io.h>
11#include <linux/bitops.h>
12#include <linux/of_platform.h>
13#include <linux/of_address.h>
14#include <linux/of_irq.h>
15#include <linux/irqdomain.h>
16#include <linux/interrupt.h>
17
18#include <asm/irq_cpu.h>
19#include <asm/mipsregs.h>
20
21#include "common.h"
22
23/* INTC register offsets */
24#define INTC_REG_STATUS0 0x00
25#define INTC_REG_STATUS1 0x04
26#define INTC_REG_TYPE 0x20
27#define INTC_REG_RAW_STATUS 0x30
28#define INTC_REG_ENABLE 0x34
29#define INTC_REG_DISABLE 0x38
30
31#define INTC_INT_GLOBAL BIT(31)
32
33#define RALINK_CPU_IRQ_INTC (MIPS_CPU_IRQ_BASE + 2)
34#define RALINK_CPU_IRQ_FE (MIPS_CPU_IRQ_BASE + 5)
35#define RALINK_CPU_IRQ_WIFI (MIPS_CPU_IRQ_BASE + 6)
36#define RALINK_CPU_IRQ_COUNTER (MIPS_CPU_IRQ_BASE + 7)
37
38/* we have a cascade of 8 irqs */
39#define RALINK_INTC_IRQ_BASE 8
40
41/* we have 32 SoC irqs */
42#define RALINK_INTC_IRQ_COUNT 32
43
44#define RALINK_INTC_IRQ_PERFC (RALINK_INTC_IRQ_BASE + 9)
45
46static void __iomem *rt_intc_membase;
47
48static inline void rt_intc_w32(u32 val, unsigned reg)
49{
50 __raw_writel(val, rt_intc_membase + reg);
51}
52
53static inline u32 rt_intc_r32(unsigned reg)
54{
55 return __raw_readl(rt_intc_membase + reg);
56}
57
58static void ralink_intc_irq_unmask(struct irq_data *d)
59{
60 rt_intc_w32(BIT(d->hwirq), INTC_REG_ENABLE);
61}
62
63static void ralink_intc_irq_mask(struct irq_data *d)
64{
65 rt_intc_w32(BIT(d->hwirq), INTC_REG_DISABLE);
66}
67
68static struct irq_chip ralink_intc_irq_chip = {
69 .name = "INTC",
70 .irq_unmask = ralink_intc_irq_unmask,
71 .irq_mask = ralink_intc_irq_mask,
72 .irq_mask_ack = ralink_intc_irq_mask,
73};
74
75unsigned int __cpuinit get_c0_compare_int(void)
76{
77 return CP0_LEGACY_COMPARE_IRQ;
78}
79
80static void ralink_intc_irq_handler(unsigned int irq, struct irq_desc *desc)
81{
82 u32 pending = rt_intc_r32(INTC_REG_STATUS0);
83
84 if (pending) {
85 struct irq_domain *domain = irq_get_handler_data(irq);
86 generic_handle_irq(irq_find_mapping(domain, __ffs(pending)));
87 } else {
88 spurious_interrupt();
89 }
90}
91
92asmlinkage void plat_irq_dispatch(void)
93{
94 unsigned long pending;
95
96 pending = read_c0_status() & read_c0_cause() & ST0_IM;
97
98 if (pending & STATUSF_IP7)
99 do_IRQ(RALINK_CPU_IRQ_COUNTER);
100
101 else if (pending & STATUSF_IP5)
102 do_IRQ(RALINK_CPU_IRQ_FE);
103
104 else if (pending & STATUSF_IP6)
105 do_IRQ(RALINK_CPU_IRQ_WIFI);
106
107 else if (pending & STATUSF_IP2)
108 do_IRQ(RALINK_CPU_IRQ_INTC);
109
110 else
111 spurious_interrupt();
112}
113
114static int intc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
115{
116 irq_set_chip_and_handler(irq, &ralink_intc_irq_chip, handle_level_irq);
117
118 return 0;
119}
120
121static const struct irq_domain_ops irq_domain_ops = {
122 .xlate = irq_domain_xlate_onecell,
123 .map = intc_map,
124};
125
126static int __init intc_of_init(struct device_node *node,
127 struct device_node *parent)
128{
129 struct resource res;
130 struct irq_domain *domain;
131 int irq;
132
133 irq = irq_of_parse_and_map(node, 0);
134 if (!irq)
135 panic("Failed to get INTC IRQ");
136
137 if (of_address_to_resource(node, 0, &res))
138 panic("Failed to get intc memory range");
139
140 if (request_mem_region(res.start, resource_size(&res),
141 res.name) < 0)
142 pr_err("Failed to request intc memory");
143
144 rt_intc_membase = ioremap_nocache(res.start,
145 resource_size(&res));
146 if (!rt_intc_membase)
147 panic("Failed to remap intc memory");
148
149 /* disable all interrupts */
150 rt_intc_w32(~0, INTC_REG_DISABLE);
151
152 /* route all INTC interrupts to MIPS HW0 interrupt */
153 rt_intc_w32(0, INTC_REG_TYPE);
154
155 domain = irq_domain_add_legacy(node, RALINK_INTC_IRQ_COUNT,
156 RALINK_INTC_IRQ_BASE, 0, &irq_domain_ops, NULL);
157 if (!domain)
158 panic("Failed to add irqdomain");
159
160 rt_intc_w32(INTC_INT_GLOBAL, INTC_REG_ENABLE);
161
162 irq_set_chained_handler(irq, ralink_intc_irq_handler);
163 irq_set_handler_data(irq, domain);
164
165 cp0_perfcount_irq = irq_create_mapping(domain, 9);
166
167 return 0;
168}
169
170static struct of_device_id __initdata of_irq_ids[] = {
171 { .compatible = "mti,cpu-interrupt-controller", .data = mips_cpu_intc_init },
172 { .compatible = "ralink,rt2880-intc", .data = intc_of_init },
173 {},
174};
175
176void __init arch_init_irq(void)
177{
178 of_irq_init(of_irq_ids);
179}
180
diff --git a/arch/mips/ralink/of.c b/arch/mips/ralink/of.c
new file mode 100644
index 000000000000..4165e70775be
--- /dev/null
+++ b/arch/mips/ralink/of.c
@@ -0,0 +1,107 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License version 2 as published
4 * by the Free Software Foundation.
5 *
6 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
7 * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
8 * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
9 */
10
11#include <linux/io.h>
12#include <linux/clk.h>
13#include <linux/init.h>
14#include <linux/of_fdt.h>
15#include <linux/kernel.h>
16#include <linux/bootmem.h>
17#include <linux/of_platform.h>
18#include <linux/of_address.h>
19
20#include <asm/reboot.h>
21#include <asm/bootinfo.h>
22#include <asm/addrspace.h>
23
24#include "common.h"
25
26__iomem void *rt_sysc_membase;
27__iomem void *rt_memc_membase;
28
29extern struct boot_param_header __dtb_start;
30
31__iomem void *plat_of_remap_node(const char *node)
32{
33 struct resource res;
34 struct device_node *np;
35
36 np = of_find_compatible_node(NULL, NULL, node);
37 if (!np)
38 panic("Failed to find %s node", node);
39
40 if (of_address_to_resource(np, 0, &res))
41 panic("Failed to get resource for %s", node);
42
43 if ((request_mem_region(res.start,
44 resource_size(&res),
45 res.name) < 0))
46 panic("Failed to request resources for %s", node);
47
48 return ioremap_nocache(res.start, resource_size(&res));
49}
50
51void __init device_tree_init(void)
52{
53 unsigned long base, size;
54 void *fdt_copy;
55
56 if (!initial_boot_params)
57 return;
58
59 base = virt_to_phys((void *)initial_boot_params);
60 size = be32_to_cpu(initial_boot_params->totalsize);
61
62 /* Before we do anything, lets reserve the dt blob */
63 reserve_bootmem(base, size, BOOTMEM_DEFAULT);
64
65 /* The strings in the flattened tree are referenced directly by the
66 * device tree, so copy the flattened device tree from init memory
67 * to regular memory.
68 */
69 fdt_copy = alloc_bootmem(size);
70 memcpy(fdt_copy, initial_boot_params, size);
71 initial_boot_params = fdt_copy;
72
73 unflatten_device_tree();
74
75 /* free the space reserved for the dt blob */
76 free_bootmem(base, size);
77}
78
79void __init plat_mem_setup(void)
80{
81 set_io_port_base(KSEG1);
82
83 /*
84 * Load the builtin devicetree. This causes the chosen node to be
85 * parsed resulting in our memory appearing
86 */
87 __dt_setup_arch(&__dtb_start);
88}
89
90static int __init plat_of_setup(void)
91{
92 static struct of_device_id of_ids[3];
93 int len = sizeof(of_ids[0].compatible);
94
95 if (!of_have_populated_dt())
96 panic("device tree not present");
97
98 strncpy(of_ids[0].compatible, soc_info.compatible, len);
99 strncpy(of_ids[1].compatible, "palmbus", len);
100
101 if (of_platform_populate(NULL, of_ids, NULL, NULL))
102 panic("failed to populate DT\n");
103
104 return 0;
105}
106
107arch_initcall(plat_of_setup);
diff --git a/arch/mips/ralink/prom.c b/arch/mips/ralink/prom.c
new file mode 100644
index 000000000000..9c64f029d047
--- /dev/null
+++ b/arch/mips/ralink/prom.c
@@ -0,0 +1,69 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License version 2 as published
4 * by the Free Software Foundation.
5 *
6 * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
7 * Copyright (C) 2010 Joonas Lahtinen <joonas.lahtinen@gmail.com>
8 * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
9 */
10
11#include <linux/string.h>
12#include <linux/of_fdt.h>
13#include <linux/of_platform.h>
14
15#include <asm/bootinfo.h>
16#include <asm/addrspace.h>
17
18#include "common.h"
19
20struct ralink_soc_info soc_info;
21
22const char *get_system_type(void)
23{
24 return soc_info.sys_type;
25}
26
27static __init void prom_init_cmdline(int argc, char **argv)
28{
29 int i;
30
31 pr_debug("prom: fw_arg0=%08x fw_arg1=%08x fw_arg2=%08x fw_arg3=%08x\n",
32 (unsigned int)fw_arg0, (unsigned int)fw_arg1,
33 (unsigned int)fw_arg2, (unsigned int)fw_arg3);
34
35 argc = fw_arg0;
36 argv = (char **) KSEG1ADDR(fw_arg1);
37
38 if (!argv) {
39 pr_debug("argv=%p is invalid, skipping\n",
40 argv);
41 return;
42 }
43
44 for (i = 0; i < argc; i++) {
45 char *p = (char *) KSEG1ADDR(argv[i]);
46
47 if (CPHYSADDR(p) && *p) {
48 pr_debug("argv[%d]: %s\n", i, p);
49 strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline));
50 strlcat(arcs_cmdline, p, sizeof(arcs_cmdline));
51 }
52 }
53}
54
55void __init prom_init(void)
56{
57 int argc;
58 char **argv;
59
60 prom_soc_init(&soc_info);
61
62 pr_info("SoC Type: %s\n", get_system_type());
63
64 prom_init_cmdline(argc, argv);
65}
66
67void __init prom_free_prom_memory(void)
68{
69}
diff --git a/arch/mips/ralink/reset.c b/arch/mips/ralink/reset.c
new file mode 100644
index 000000000000..22120e512e7e
--- /dev/null
+++ b/arch/mips/ralink/reset.c
@@ -0,0 +1,44 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License version 2 as published
4 * by the Free Software Foundation.
5 *
6 * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
7 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
8 * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
9 */
10
11#include <linux/pm.h>
12#include <linux/io.h>
13
14#include <asm/reboot.h>
15
16#include <asm/mach-ralink/ralink_regs.h>
17
18/* Reset Control */
19#define SYSC_REG_RESET_CTRL 0x034
20#define RSTCTL_RESET_SYSTEM BIT(0)
21
22static void ralink_restart(char *command)
23{
24 local_irq_disable();
25 rt_sysc_w32(RSTCTL_RESET_SYSTEM, SYSC_REG_RESET_CTRL);
26 unreachable();
27}
28
29static void ralink_halt(void)
30{
31 local_irq_disable();
32 unreachable();
33}
34
35static int __init mips_reboot_setup(void)
36{
37 _machine_restart = ralink_restart;
38 _machine_halt = ralink_halt;
39 pm_power_off = ralink_halt;
40
41 return 0;
42}
43
44arch_initcall(mips_reboot_setup);
diff --git a/arch/mips/ralink/rt305x.c b/arch/mips/ralink/rt305x.c
new file mode 100644
index 000000000000..0a4bbdcf59d9
--- /dev/null
+++ b/arch/mips/ralink/rt305x.c
@@ -0,0 +1,242 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License version 2 as published
4 * by the Free Software Foundation.
5 *
6 * Parts of this file are based on Ralink's 2.6.21 BSP
7 *
8 * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
9 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
10 * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
11 */
12
13#include <linux/kernel.h>
14#include <linux/init.h>
15#include <linux/module.h>
16
17#include <asm/mipsregs.h>
18#include <asm/mach-ralink/ralink_regs.h>
19#include <asm/mach-ralink/rt305x.h>
20
21#include "common.h"
22
23enum rt305x_soc_type rt305x_soc;
24
25struct ralink_pinmux_grp mode_mux[] = {
26 {
27 .name = "i2c",
28 .mask = RT305X_GPIO_MODE_I2C,
29 .gpio_first = RT305X_GPIO_I2C_SD,
30 .gpio_last = RT305X_GPIO_I2C_SCLK,
31 }, {
32 .name = "spi",
33 .mask = RT305X_GPIO_MODE_SPI,
34 .gpio_first = RT305X_GPIO_SPI_EN,
35 .gpio_last = RT305X_GPIO_SPI_CLK,
36 }, {
37 .name = "uartlite",
38 .mask = RT305X_GPIO_MODE_UART1,
39 .gpio_first = RT305X_GPIO_UART1_TXD,
40 .gpio_last = RT305X_GPIO_UART1_RXD,
41 }, {
42 .name = "jtag",
43 .mask = RT305X_GPIO_MODE_JTAG,
44 .gpio_first = RT305X_GPIO_JTAG_TDO,
45 .gpio_last = RT305X_GPIO_JTAG_TDI,
46 }, {
47 .name = "mdio",
48 .mask = RT305X_GPIO_MODE_MDIO,
49 .gpio_first = RT305X_GPIO_MDIO_MDC,
50 .gpio_last = RT305X_GPIO_MDIO_MDIO,
51 }, {
52 .name = "sdram",
53 .mask = RT305X_GPIO_MODE_SDRAM,
54 .gpio_first = RT305X_GPIO_SDRAM_MD16,
55 .gpio_last = RT305X_GPIO_SDRAM_MD31,
56 }, {
57 .name = "rgmii",
58 .mask = RT305X_GPIO_MODE_RGMII,
59 .gpio_first = RT305X_GPIO_GE0_TXD0,
60 .gpio_last = RT305X_GPIO_GE0_RXCLK,
61 }, {0}
62};
63
64struct ralink_pinmux_grp uart_mux[] = {
65 {
66 .name = "uartf",
67 .mask = RT305X_GPIO_MODE_UARTF,
68 .gpio_first = RT305X_GPIO_7,
69 .gpio_last = RT305X_GPIO_14,
70 }, {
71 .name = "pcm uartf",
72 .mask = RT305X_GPIO_MODE_PCM_UARTF,
73 .gpio_first = RT305X_GPIO_7,
74 .gpio_last = RT305X_GPIO_14,
75 }, {
76 .name = "pcm i2s",
77 .mask = RT305X_GPIO_MODE_PCM_I2S,
78 .gpio_first = RT305X_GPIO_7,
79 .gpio_last = RT305X_GPIO_14,
80 }, {
81 .name = "i2s uartf",
82 .mask = RT305X_GPIO_MODE_I2S_UARTF,
83 .gpio_first = RT305X_GPIO_7,
84 .gpio_last = RT305X_GPIO_14,
85 }, {
86 .name = "pcm gpio",
87 .mask = RT305X_GPIO_MODE_PCM_GPIO,
88 .gpio_first = RT305X_GPIO_10,
89 .gpio_last = RT305X_GPIO_14,
90 }, {
91 .name = "gpio uartf",
92 .mask = RT305X_GPIO_MODE_GPIO_UARTF,
93 .gpio_first = RT305X_GPIO_7,
94 .gpio_last = RT305X_GPIO_14,
95 }, {
96 .name = "gpio i2s",
97 .mask = RT305X_GPIO_MODE_GPIO_I2S,
98 .gpio_first = RT305X_GPIO_7,
99 .gpio_last = RT305X_GPIO_14,
100 }, {
101 .name = "gpio",
102 .mask = RT305X_GPIO_MODE_GPIO,
103 }, {0}
104};
105
106void rt305x_wdt_reset(void)
107{
108 u32 t;
109
110 /* enable WDT reset output on pin SRAM_CS_N */
111 t = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG);
112 t |= RT305X_SYSCFG_SRAM_CS0_MODE_WDT <<
113 RT305X_SYSCFG_SRAM_CS0_MODE_SHIFT;
114 rt_sysc_w32(t, SYSC_REG_SYSTEM_CONFIG);
115}
116
117struct ralink_pinmux gpio_pinmux = {
118 .mode = mode_mux,
119 .uart = uart_mux,
120 .uart_shift = RT305X_GPIO_MODE_UART0_SHIFT,
121 .wdt_reset = rt305x_wdt_reset,
122};
123
124void __init ralink_clk_init(void)
125{
126 unsigned long cpu_rate, sys_rate, wdt_rate, uart_rate;
127 u32 t = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG);
128
129 if (soc_is_rt305x() || soc_is_rt3350()) {
130 t = (t >> RT305X_SYSCFG_CPUCLK_SHIFT) &
131 RT305X_SYSCFG_CPUCLK_MASK;
132 switch (t) {
133 case RT305X_SYSCFG_CPUCLK_LOW:
134 cpu_rate = 320000000;
135 break;
136 case RT305X_SYSCFG_CPUCLK_HIGH:
137 cpu_rate = 384000000;
138 break;
139 }
140 sys_rate = uart_rate = wdt_rate = cpu_rate / 3;
141 } else if (soc_is_rt3352()) {
142 t = (t >> RT3352_SYSCFG0_CPUCLK_SHIFT) &
143 RT3352_SYSCFG0_CPUCLK_MASK;
144 switch (t) {
145 case RT3352_SYSCFG0_CPUCLK_LOW:
146 cpu_rate = 384000000;
147 break;
148 case RT3352_SYSCFG0_CPUCLK_HIGH:
149 cpu_rate = 400000000;
150 break;
151 }
152 sys_rate = wdt_rate = cpu_rate / 3;
153 uart_rate = 40000000;
154 } else if (soc_is_rt5350()) {
155 t = (t >> RT5350_SYSCFG0_CPUCLK_SHIFT) &
156 RT5350_SYSCFG0_CPUCLK_MASK;
157 switch (t) {
158 case RT5350_SYSCFG0_CPUCLK_360:
159 cpu_rate = 360000000;
160 sys_rate = cpu_rate / 3;
161 break;
162 case RT5350_SYSCFG0_CPUCLK_320:
163 cpu_rate = 320000000;
164 sys_rate = cpu_rate / 4;
165 break;
166 case RT5350_SYSCFG0_CPUCLK_300:
167 cpu_rate = 300000000;
168 sys_rate = cpu_rate / 3;
169 break;
170 default:
171 BUG();
172 }
173 uart_rate = 40000000;
174 wdt_rate = sys_rate;
175 } else {
176 BUG();
177 }
178
179 ralink_clk_add("cpu", cpu_rate);
180 ralink_clk_add("10000b00.spi", sys_rate);
181 ralink_clk_add("10000100.timer", wdt_rate);
182 ralink_clk_add("10000500.uart", uart_rate);
183 ralink_clk_add("10000c00.uartlite", uart_rate);
184}
185
186void __init ralink_of_remap(void)
187{
188 rt_sysc_membase = plat_of_remap_node("ralink,rt3050-sysc");
189 rt_memc_membase = plat_of_remap_node("ralink,rt3050-memc");
190
191 if (!rt_sysc_membase || !rt_memc_membase)
192 panic("Failed to remap core resources");
193}
194
195void prom_soc_init(struct ralink_soc_info *soc_info)
196{
197 void __iomem *sysc = (void __iomem *) KSEG1ADDR(RT305X_SYSC_BASE);
198 unsigned char *name;
199 u32 n0;
200 u32 n1;
201 u32 id;
202
203 n0 = __raw_readl(sysc + SYSC_REG_CHIP_NAME0);
204 n1 = __raw_readl(sysc + SYSC_REG_CHIP_NAME1);
205
206 if (n0 == RT3052_CHIP_NAME0 && n1 == RT3052_CHIP_NAME1) {
207 unsigned long icache_sets;
208
209 icache_sets = (read_c0_config1() >> 22) & 7;
210 if (icache_sets == 1) {
211 rt305x_soc = RT305X_SOC_RT3050;
212 name = "RT3050";
213 soc_info->compatible = "ralink,rt3050-soc";
214 } else {
215 rt305x_soc = RT305X_SOC_RT3052;
216 name = "RT3052";
217 soc_info->compatible = "ralink,rt3052-soc";
218 }
219 } else if (n0 == RT3350_CHIP_NAME0 && n1 == RT3350_CHIP_NAME1) {
220 rt305x_soc = RT305X_SOC_RT3350;
221 name = "RT3350";
222 soc_info->compatible = "ralink,rt3350-soc";
223 } else if (n0 == RT3352_CHIP_NAME0 && n1 == RT3352_CHIP_NAME1) {
224 rt305x_soc = RT305X_SOC_RT3352;
225 name = "RT3352";
226 soc_info->compatible = "ralink,rt3352-soc";
227 } else if (n0 == RT5350_CHIP_NAME0 && n1 == RT5350_CHIP_NAME1) {
228 rt305x_soc = RT305X_SOC_RT5350;
229 name = "RT5350";
230 soc_info->compatible = "ralink,rt5350-soc";
231 } else {
232 panic("rt305x: unknown SoC, n0:%08x n1:%08x\n", n0, n1);
233 }
234
235 id = __raw_readl(sysc + SYSC_REG_CHIP_ID);
236
237 snprintf(soc_info->sys_type, RAMIPS_SYS_TYPE_LEN,
238 "Ralink %s id:%u rev:%u",
239 name,
240 (id >> CHIP_ID_ID_SHIFT) & CHIP_ID_ID_MASK,
241 (id & CHIP_ID_REV_MASK));
242}