[lantiq] add linux-v3.7
[openwrt.git] / target / linux / lantiq / patches-3.7 / 0101-MIPS-lantiq-adds-support-for-SVIP-SoC-Family.patch
1 From 4d77ad216ad86b3b25c196a189fa28f3e53c3ffd Mon Sep 17 00:00:00 2001
2 From: John Crispin <blogic@openwrt.org>
3 Date: Fri, 30 Nov 2012 21:32:00 +0100
4 Subject: [PATCH 101/123] MIPS: lantiq: adds support for SVIP SoC Family
5
6 ---
7  arch/mips/kernel/cevt-r4k.c     |    4 +-
8  arch/mips/lantiq/Kconfig        |    4 ++
9  arch/mips/lantiq/Makefile       |    1 +
10  arch/mips/lantiq/Platform       |    1 +
11  arch/mips/lantiq/clk.c          |    7 +++
12  arch/mips/lantiq/clk.h          |    4 ++
13  arch/mips/lantiq/svip/Makefile  |    1 +
14  arch/mips/lantiq/svip/clk.c     |   70 ++++++++++++++++++++++++++
15  arch/mips/lantiq/svip/prom.c    |   43 ++++++++++++++++
16  arch/mips/lantiq/svip/reset.c   |  105 +++++++++++++++++++++++++++++++++++++++
17  arch/mips/lantiq/svip/sysctrl.c |   81 ++++++++++++++++++++++++++++++
18  11 files changed, 320 insertions(+), 1 deletion(-)
19  create mode 100644 arch/mips/lantiq/svip/Makefile
20  create mode 100644 arch/mips/lantiq/svip/clk.c
21  create mode 100644 arch/mips/lantiq/svip/prom.c
22  create mode 100644 arch/mips/lantiq/svip/reset.c
23  create mode 100644 arch/mips/lantiq/svip/sysctrl.c
24
25 diff --git a/arch/mips/kernel/cevt-r4k.c b/arch/mips/kernel/cevt-r4k.c
26 index 7532392..06b45e4 100644
27 --- a/arch/mips/kernel/cevt-r4k.c
28 +++ b/arch/mips/kernel/cevt-r4k.c
29 @@ -176,8 +176,10 @@ int __cpuinit r4k_clockevent_init(void)
30         if (!cpu_has_counter || !mips_hpt_frequency)
31                 return -ENXIO;
32  
33 -       if (!c0_compare_int_usable())
34 +       if (!c0_compare_int_usable()) {
35 +               printk("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
36                 return -ENXIO;
37 +       }
38  
39         /*
40          * With vectored interrupts things are getting platform specific.
41 diff --git a/arch/mips/lantiq/Kconfig b/arch/mips/lantiq/Kconfig
42 index c002191..edeb58c 100644
43 --- a/arch/mips/lantiq/Kconfig
44 +++ b/arch/mips/lantiq/Kconfig
45 @@ -22,6 +22,10 @@ config SOC_FALCON
46         bool "FALCON"
47         select PINCTRL_FALCON
48  
49 +config SOC_SVIP
50 +       bool "SVIP"
51 +       select MIPS_CPU_SCACHE
52 +
53  endchoice
54  
55  choice
56 diff --git a/arch/mips/lantiq/Makefile b/arch/mips/lantiq/Makefile
57 index d6bdc57..edeb30b 100644
58 --- a/arch/mips/lantiq/Makefile
59 +++ b/arch/mips/lantiq/Makefile
60 @@ -12,3 +12,4 @@ obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
61  
62  obj-$(CONFIG_SOC_TYPE_XWAY) += xway/
63  obj-$(CONFIG_SOC_FALCON) += falcon/
64 +obj-$(CONFIG_SOC_SVIP) += svip/
65 diff --git a/arch/mips/lantiq/Platform b/arch/mips/lantiq/Platform
66 index b3ec498..857548c 100644
67 --- a/arch/mips/lantiq/Platform
68 +++ b/arch/mips/lantiq/Platform
69 @@ -7,3 +7,4 @@ cflags-$(CONFIG_LANTIQ)         += -I$(srctree)/arch/mips/include/asm/mach-lantiq
70  load-$(CONFIG_LANTIQ)          = 0xffffffff80002000
71  cflags-$(CONFIG_SOC_TYPE_XWAY) += -I$(srctree)/arch/mips/include/asm/mach-lantiq/xway
72  cflags-$(CONFIG_SOC_FALCON)    += -I$(srctree)/arch/mips/include/asm/mach-lantiq/falcon
73 +cflags-$(CONFIG_SOC_SVIP)      += -I$(srctree)/arch/mips/include/asm/mach-lantiq/svip
74 diff --git a/arch/mips/lantiq/clk.c b/arch/mips/lantiq/clk.c
75 index ce2f129..9128ff8 100644
76 --- a/arch/mips/lantiq/clk.c
77 +++ b/arch/mips/lantiq/clk.c
78 @@ -163,8 +163,15 @@ void __init plat_time_init(void)
79         ltq_soc_init();
80  
81         clk = clk_get_cpu();
82 +#ifdef CONFIG_SOC_SVIP
83 +       mips_hpt_frequency = ltq_svip_cpu_hz() / get_counter_resolution();
84 +       write_c0_count(0);
85 +       write_c0_compare(mips_hpt_frequency / HZ);
86 +       enable_irq(MIPS_CPU_TIMER_IRQ);
87 +#else
88         mips_hpt_frequency = clk_get_rate(clk) / get_counter_resolution();
89         write_c0_compare(read_c0_count());
90 +#endif
91         pr_info("CPU Clock: %ldMHz\n", clk_get_rate(clk) / 1000000);
92         clk_put(clk);
93  }
94 diff --git a/arch/mips/lantiq/clk.h b/arch/mips/lantiq/clk.h
95 index fa67060..c169e2b 100644
96 --- a/arch/mips/lantiq/clk.h
97 +++ b/arch/mips/lantiq/clk.h
98 @@ -75,4 +75,8 @@ extern unsigned long ltq_ar9_fpi_hz(void);
99  extern unsigned long ltq_vr9_cpu_hz(void);
100  extern unsigned long ltq_vr9_fpi_hz(void);
101  
102 +extern unsigned long ltq_svip_cpu_hz(void);
103 +extern unsigned long ltq_svip_fpi_hz(void);
104 +extern unsigned long ltq_svip_io_hz(void);
105 +
106  #endif
107 diff --git a/arch/mips/lantiq/svip/Makefile b/arch/mips/lantiq/svip/Makefile
108 new file mode 100644
109 index 0000000..74308b2
110 --- /dev/null
111 +++ b/arch/mips/lantiq/svip/Makefile
112 @@ -0,0 +1 @@
113 +obj-y := prom.o reset.o sysctrl.o clk.o
114 diff --git a/arch/mips/lantiq/svip/clk.c b/arch/mips/lantiq/svip/clk.c
115 new file mode 100644
116 index 0000000..3a7b665
117 --- /dev/null
118 +++ b/arch/mips/lantiq/svip/clk.c
119 @@ -0,0 +1,70 @@
120 +/*
121 + *  This program is free software; you can redistribute it and/or modify it
122 + *  under the terms of the GNU General Public License version 2 as published
123 + *  by the Free Software Foundation.
124 + *
125 + *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
126 + */
127 +
128 +#include <linux/io.h>
129 +#include <linux/export.h>
130 +#include <linux/init.h>
131 +#include <linux/clk.h>
132 +
133 +#include <asm/time.h>
134 +#include <asm/irq.h>
135 +#include <asm/div64.h>
136 +
137 +#include <lantiq_soc.h>
138 +
139 +#include "../clk.h"
140 +
141 +#define STATUS_CONFIG_CLK_MODE         (0x1 << 1)
142 +#define STATUS_CONFIG_CLK_MODE_GET(val)        ((((val) & STATUS_CONFIG_CLK_MODE) >> 4) & 0x1)
143 +#define STATUS_CONFIG                  0x0010
144 +
145 +#define SYS0_PLL1CR_PLLDIV             (0x3)
146 +#define SYS0_PLL1CR_PLLDIV_GET(val)    ((((val) & SYS0_PLL1CR_PLLDIV) >> 0) & 0x3)
147 +#define SYS0_PLL1CR                    0x0008
148 +
149 +#define SYS1_FPICR_FPIDIV              (0x1)
150 +#define SYS1_FPICR_FPIDIV_GET(val)     ((((val) & SYS1_FPICR_FPIDIV) >> 0) & 0x1)
151 +#define SYS1_FPICR                     0x0014
152 +
153 +unsigned long ltq_svip_io_hz(void)
154 +{
155 +       return 200000000; /* 200 MHz */
156 +}
157 +
158 +unsigned long ltq_svip_cpu_hz(void)
159 +{
160 +       /* Magic BootROM speed location... */
161 +       if ((*(u32 *)0x9fc07ff0) == 1)
162 +               return *(u32 *)0x9fc07ff4;
163 +
164 +       if (STATUS_CONFIG_CLK_MODE_GET(ltq_status_r32(STATUS_CONFIG)) == 1) {
165 +       /* xT16 */
166 +               return 393216000;
167 +       } else {
168 +               switch (SYS0_PLL1CR_PLLDIV_GET(ltq_sys0_r32(SYS0_PLL1CR))) {
169 +               case 3:
170 +                       return 475000000;
171 +               case 2:
172 +                       return 450000000;
173 +               case 1:
174 +                       return 425000000;
175 +               default:
176 +                       break;
177 +               }
178 +       }
179 +       return 400000000;
180 +}
181 +
182 +unsigned long ltq_svip_fpi_hz(void)
183 +{
184 +       u32 fbs0_div[2] = {4, 8};
185 +       u32 div;
186 +
187 +       div = SYS1_FPICR_FPIDIV_GET(ltq_sys1_r32(SYS1_FPICR));
188 +       return ltq_svip_cpu_hz() / fbs0_div[div];
189 +}
190 diff --git a/arch/mips/lantiq/svip/prom.c b/arch/mips/lantiq/svip/prom.c
191 new file mode 100644
192 index 0000000..01d2018
193 --- /dev/null
194 +++ b/arch/mips/lantiq/svip/prom.c
195 @@ -0,0 +1,43 @@
196 +/*
197 + * This program is free software; you can redistribute it and/or modify it
198 + * under the terms of the GNU General Public License version 2 as published
199 + * by the Free Software Foundation.
200 + *
201 + * Copyright (C) 2012 Thomas Langer <thomas.langer@lantiq.com>
202 + * Copyright (C) 2012 John Crispin <blogic@openwrt.org>
203 + */
204 +
205 +#include <linux/kernel.h>
206 +#include <asm/io.h>
207 +
208 +#include <lantiq_soc.h>
209 +
210 +#include "../prom.h"
211 +
212 +#define SOC_SVIP       "SVIP"
213 +
214 +#define COMP_SVIP      "lantiq,svip"
215 +
216 +#define PART_SHIFT     12
217 +#define PART_MASK      0x0FFFF000
218 +#define REV_SHIFT      28
219 +#define REV_MASK       0xF0000000
220 +
221 +void __init ltq_soc_detect(struct ltq_soc_info *i)
222 +{
223 +       i->partnum = (ltq_r32(LTQ_STATUS_CHIPID) & PART_MASK) >> PART_SHIFT;
224 +       i->rev = (ltq_r32(LTQ_STATUS_CHIPID) & REV_MASK) >> REV_SHIFT;
225 +       sprintf(i->rev_type, "1.%d", i->rev);
226 +
227 +       switch (i->partnum) {
228 +       case SOC_ID_SVIP:
229 +               i->name = SOC_SVIP;
230 +               i->type = SOC_TYPE_SVIP;
231 +               i->compatible = COMP_SVIP;
232 +               break;
233 +
234 +       default:
235 +               printk("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
236 +               break;
237 +       }
238 +}
239 diff --git a/arch/mips/lantiq/svip/reset.c b/arch/mips/lantiq/svip/reset.c
240 new file mode 100644
241 index 0000000..4b41dd1
242 --- /dev/null
243 +++ b/arch/mips/lantiq/svip/reset.c
244 @@ -0,0 +1,105 @@
245 +/*
246 + *  This program is free software; you can redistribute it and/or modify it
247 + *  under the terms of the GNU General Public License version 2 as published
248 + *  by the Free Software Foundation.
249 + *
250 + *  Copyright (C) 2012 John Crispin <blogic@openwrt.org>
251 + */
252 +
253 +#include <linux/init.h>
254 +#include <linux/io.h>
255 +#include <linux/ioport.h>
256 +#include <linux/pm.h>
257 +#include <linux/module.h>
258 +#include <asm/reboot.h>
259 +
260 +#include <lantiq_soc.h>
261 +
262 +#define CPLD_CMDREG3  ((volatile unsigned char*)(KSEG1 + 0x120000f3))
263 +
264 +#define LTQ_EBU_ADDRSEL2       0x0028
265 +#define LTQ_EBU_BUSCON2         0x0068
266 +#define LTQ_BOOT_CPU_OFFSET    0x20
267 +
268 +#define LTQ_L2_SPRAM_BASE      (KSEG1 + 0x1F1E8000)
269 +#define LTQ_BOOT_RVEC(cpu)     (volatile u32*)(LTQ_L2_SPRAM_BASE + \
270 +                               (cpu * LTQ_BOOT_CPU_OFFSET))
271 +
272 +#define SYS0_BCR               0x0004
273 +#define BMODE_SHIFT            16
274 +#define BMODE_MASK             0x1f
275 +
276 +#define SYS1_CLKCLR            0x0008
277 +#define SYS1_RREQR             0x0044
278 +#define SYS1_RRLSR             0x0048
279 +#define SYS1_RBTR              0x004c
280 +#define SYS1_CPU0RSR           0x0060
281 +#define SYS1_CPU0RSR_MASK      0x0007
282 +
283 +/* This function is used by the watchdog driver */
284 +int ltq_reset_cause(void)
285 +{
286 +       return ltq_sys1_r32(SYS1_CPU0RSR) & SYS1_CPU0RSR_MASK;
287 +}
288 +EXPORT_SYMBOL_GPL(ltq_reset_cause);
289 +
290 +/* allow platform code to find out what source we booted from */
291 +unsigned char ltq_boot_select(void)
292 +{
293 +       return (ltq_sys0_r32(SYS0_BCR) >> BMODE_SHIFT) & BMODE_MASK;
294 +}
295 +
296 +static void ltq_machine_restart(char *command)
297 +{
298 +       local_irq_disable();
299 +       if (/*mips_machtype == LANTIQ_MACH_EASY33016 ||
300 +           mips_machtype == LANTIQ_MACH_EASY336)*/
301 +           1) {
302 +               /* We just use the CPLD function to reset the entire system as a
303 +                  workaround for the switch reset problem */
304 +               local_irq_disable();
305 +               ltq_ebu_w32(0x120000f1, LTQ_EBU_ADDRSEL2);
306 +               ltq_ebu_w32(0x404027ff, LTQ_EBU_BUSCON2);
307 +
308 +               if (/*mips_machtype == LANTIQ_MACH_EASY336*/
309 +                       0)
310 +                       /* set bit 0 to reset SVIP */
311 +                       *CPLD_CMDREG3 = (1<<0);
312 +               else
313 +                       /* set bit 7 to reset SVIP, set bit 3 to reset xT */
314 +                       *CPLD_CMDREG3 = (1<<7) | (1<<3);
315 +       } else {
316 +               *LTQ_BOOT_RVEC(0) = 0;
317 +               /* reset all except PER, SUBSYS and CPU0 */
318 +               ltq_sys1_w32(0x00043F3E, SYS1_RREQR);
319 +               /* release WDT0 reset */
320 +               ltq_sys1_w32(0x00000100, SYS1_RRLSR);
321 +               /* restore reset value for clock enables */
322 +               ltq_sys1_w32(~0x0c000040, SYS1_CLKCLR);
323 +               /* reset SUBSYS (incl. DDR2) and CPU0 */
324 +               ltq_sys1_w32(0x00030001, SYS1_RBTR);
325 +       }
326 +
327 +       unreachable();
328 +}
329 +
330 +static void ltq_machine_halt(void)
331 +{
332 +       local_irq_disable();
333 +       unreachable();
334 +}
335 +
336 +static void ltq_machine_power_off(void)
337 +{
338 +       local_irq_disable();
339 +}
340 +
341 +static int __init mips_reboot_setup(void)
342 +{
343 +       _machine_restart = ltq_machine_restart;
344 +       _machine_halt = ltq_machine_halt;
345 +       pm_power_off = ltq_machine_power_off;
346 +       return 0;
347 +}
348 +
349 +arch_initcall(mips_reboot_setup);
350 diff --git a/arch/mips/lantiq/svip/sysctrl.c b/arch/mips/lantiq/svip/sysctrl.c
351 new file mode 100644
352 index 0000000..d2b636b
353 --- /dev/null
354 +++ b/arch/mips/lantiq/svip/sysctrl.c
355 @@ -0,0 +1,81 @@
356 +/*
357 + *  This program is free software; you can redistribute it and/or modify it
358 + *  under the terms of the GNU General Public License version 2 as published
359 + *  by the Free Software Foundation.
360 + *
361 + *  Copyright (C) 2011-2012 John Crispin <blogic@openwrt.org>
362 + */
363 +
364 +#include <linux/ioport.h>
365 +#include <linux/export.h>
366 +#include <linux/clkdev.h>
367 +#include <linux/of.h>
368 +#include <linux/of_platform.h>
369 +#include <linux/of_address.h>
370 +
371 +#include <lantiq_soc.h>
372 +
373 +#include "../clk.h"
374 +#include "../prom.h"
375 +
376 +void __iomem *ltq_sys0_membase;
377 +void __iomem *ltq_sys1_membase;
378 +void __iomem *ltq_sys2_membase;
379 +void __iomem *ltq_status_membase;
380 +void __iomem *ltq_ebu_membase;
381 +
382 +/* bring up all register ranges that we need for basic system control */
383 +void __init ltq_soc_init(void)
384 +{
385 +       struct resource res_sys0, res_sys1, res_sys2, res_status, res_ebu;
386 +       struct device_node *np_sys0 =
387 +                       of_find_compatible_node(NULL, NULL, "lantiq,sys0-svip");
388 +       struct device_node *np_sys1 =
389 +                       of_find_compatible_node(NULL, NULL, "lantiq,sys1-svip");
390 +       struct device_node *np_sys2 =
391 +                       of_find_compatible_node(NULL, NULL, "lantiq,sys2-svip");
392 +       struct device_node *np_status =
393 +                       of_find_compatible_node(NULL, NULL, "lantiq,status-svip");
394 +       struct device_node *np_ebu =
395 +                       of_find_compatible_node(NULL, NULL, "lantiq,ebu-svip");
396 +
397 +       /* check if all the core register ranges are available */
398 +       if (!np_sys0 || !np_sys1 || !np_sys2 || !np_status || !np_ebu)
399 +               panic("Failed to load core nodes from devicetree");
400 +
401 +       if (of_address_to_resource(np_sys0, 0, &res_sys0) ||
402 +                       of_address_to_resource(np_sys1, 0, &res_sys1) ||
403 +                       of_address_to_resource(np_sys2, 0, &res_sys2) ||
404 +                       of_address_to_resource(np_status, 0, &res_status) ||
405 +                       of_address_to_resource(np_ebu, 0, &res_ebu))
406 +               panic("Failed to get core resources");
407 +
408 +       if ((request_mem_region(res_sys0.start, resource_size(&res_sys0),
409 +                               res_sys0.name) < 0) ||
410 +               (request_mem_region(res_sys1.start, resource_size(&res_sys1),
411 +                               res_sys1.name) < 0) ||
412 +               (request_mem_region(res_sys2.start, resource_size(&res_sys2),
413 +                               res_sys2.name) < 0) ||
414 +               (request_mem_region(res_status.start, resource_size(&res_status),
415 +                               res_status.name) < 0) ||
416 +               (request_mem_region(res_ebu.start, resource_size(&res_ebu),
417 +                               res_ebu.name) < 0))
418 +               pr_err("Failed to request core reources");
419 +
420 +       ltq_sys0_membase = ioremap_nocache(res_sys0.start,
421 +                                               resource_size(&res_sys0));
422 +       ltq_sys1_membase = ioremap_nocache(res_sys1.start,
423 +                                               resource_size(&res_sys1));
424 +       ltq_sys2_membase = ioremap_nocache(res_sys2.start,
425 +                                               resource_size(&res_sys2));
426 +       ltq_status_membase = ioremap_nocache(res_status.start,
427 +                                               resource_size(&res_status));
428 +       ltq_ebu_membase = ioremap_nocache(res_ebu.start,
429 +                                               resource_size(&res_ebu));
430 +       if (!ltq_sys0_membase || !ltq_sys1_membase || !ltq_sys2_membase ||
431 +                       !ltq_status_membase || !ltq_ebu_membase)
432 +               panic("Failed to remap core resources");
433 +
434 +       clkdev_add_static(ltq_svip_cpu_hz(), ltq_svip_fpi_hz(),
435 +                               ltq_svip_io_hz());
436 +}
437 -- 
438 1.7.10.4
439