regulator: 88pm800: fix LDO vsel_mask value
[linux-drm-fsl-dcu.git] / arch / arc / kernel / setup.c
1 /*
2  * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  */
8
9 #include <linux/seq_file.h>
10 #include <linux/fs.h>
11 #include <linux/delay.h>
12 #include <linux/root_dev.h>
13 #include <linux/console.h>
14 #include <linux/module.h>
15 #include <linux/cpu.h>
16 #include <linux/clk-provider.h>
17 #include <linux/of_fdt.h>
18 #include <linux/of_platform.h>
19 #include <linux/cache.h>
20 #include <asm/sections.h>
21 #include <asm/arcregs.h>
22 #include <asm/tlb.h>
23 #include <asm/setup.h>
24 #include <asm/page.h>
25 #include <asm/irq.h>
26 #include <asm/unwind.h>
27 #include <asm/clk.h>
28 #include <asm/mach_desc.h>
29 #include <asm/smp.h>
30
31 #define FIX_PTR(x)  __asm__ __volatile__(";" : "+r"(x))
32
33 unsigned int intr_to_DE_cnt;
34
35 /* Part of U-boot ABI: see head.S */
36 int __initdata uboot_tag;
37 char __initdata *uboot_arg;
38
39 const struct machine_desc *machine_desc;
40
41 struct task_struct *_current_task[NR_CPUS];     /* For stack switching */
42
43 struct cpuinfo_arc cpuinfo_arc700[NR_CPUS];
44
45 static void read_arc_build_cfg_regs(void)
46 {
47         struct bcr_perip uncached_space;
48         struct bcr_generic bcr;
49         struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()];
50         FIX_PTR(cpu);
51
52         READ_BCR(AUX_IDENTITY, cpu->core);
53         READ_BCR(ARC_REG_ISA_CFG_BCR, cpu->isa);
54
55         READ_BCR(ARC_REG_TIMERS_BCR, cpu->timers);
56         cpu->vec_base = read_aux_reg(AUX_INTR_VEC_BASE);
57
58         READ_BCR(ARC_REG_D_UNCACH_BCR, uncached_space);
59         BUG_ON((uncached_space.start << 24) != ARC_UNCACHED_ADDR_SPACE);
60
61         READ_BCR(ARC_REG_MUL_BCR, cpu->extn_mpy);
62
63         cpu->extn.norm = read_aux_reg(ARC_REG_NORM_BCR) > 1 ? 1 : 0; /* 2,3 */
64         cpu->extn.barrel = read_aux_reg(ARC_REG_BARREL_BCR) > 1 ? 1 : 0; /* 2,3 */
65         cpu->extn.swap = read_aux_reg(ARC_REG_SWAP_BCR) ? 1 : 0;        /* 1,3 */
66         cpu->extn.crc = read_aux_reg(ARC_REG_CRC_BCR) ? 1 : 0;
67         cpu->extn.minmax = read_aux_reg(ARC_REG_MIXMAX_BCR) > 1 ? 1 : 0; /* 2 */
68
69         /* Note that we read the CCM BCRs independent of kernel config
70          * This is to catch the cases where user doesn't know that
71          * CCMs are present in hardware build
72          */
73         {
74                 struct bcr_iccm iccm;
75                 struct bcr_dccm dccm;
76                 struct bcr_dccm_base dccm_base;
77                 unsigned int bcr_32bit_val;
78
79                 bcr_32bit_val = read_aux_reg(ARC_REG_ICCM_BCR);
80                 if (bcr_32bit_val) {
81                         iccm = *((struct bcr_iccm *)&bcr_32bit_val);
82                         cpu->iccm.base_addr = iccm.base << 16;
83                         cpu->iccm.sz = 0x2000 << (iccm.sz - 1);
84                 }
85
86                 bcr_32bit_val = read_aux_reg(ARC_REG_DCCM_BCR);
87                 if (bcr_32bit_val) {
88                         dccm = *((struct bcr_dccm *)&bcr_32bit_val);
89                         cpu->dccm.sz = 0x800 << (dccm.sz);
90
91                         READ_BCR(ARC_REG_DCCMBASE_BCR, dccm_base);
92                         cpu->dccm.base_addr = dccm_base.addr << 8;
93                 }
94         }
95
96         READ_BCR(ARC_REG_XY_MEM_BCR, cpu->extn_xymem);
97
98         read_decode_mmu_bcr();
99         read_decode_cache_bcr();
100
101         if (is_isa_arcompact()) {
102                 struct bcr_fp_arcompact sp, dp;
103                 struct bcr_bpu_arcompact bpu;
104
105                 READ_BCR(ARC_REG_FP_BCR, sp);
106                 READ_BCR(ARC_REG_DPFP_BCR, dp);
107                 cpu->extn.fpu_sp = sp.ver ? 1 : 0;
108                 cpu->extn.fpu_dp = dp.ver ? 1 : 0;
109
110                 READ_BCR(ARC_REG_BPU_BCR, bpu);
111                 cpu->bpu.ver = bpu.ver;
112                 cpu->bpu.full = bpu.fam ? 1 : 0;
113                 if (bpu.ent) {
114                         cpu->bpu.num_cache = 256 << (bpu.ent - 1);
115                         cpu->bpu.num_pred = 256 << (bpu.ent - 1);
116                 }
117         } else {
118                 struct bcr_fp_arcv2 spdp;
119                 struct bcr_bpu_arcv2 bpu;
120
121                 READ_BCR(ARC_REG_FP_V2_BCR, spdp);
122                 cpu->extn.fpu_sp = spdp.sp ? 1 : 0;
123                 cpu->extn.fpu_dp = spdp.dp ? 1 : 0;
124
125                 READ_BCR(ARC_REG_BPU_BCR, bpu);
126                 cpu->bpu.ver = bpu.ver;
127                 cpu->bpu.full = bpu.ft;
128                 cpu->bpu.num_cache = 256 << bpu.bce;
129                 cpu->bpu.num_pred = 2048 << bpu.pte;
130         }
131
132         READ_BCR(ARC_REG_AP_BCR, bcr);
133         cpu->extn.ap = bcr.ver ? 1 : 0;
134
135         READ_BCR(ARC_REG_SMART_BCR, bcr);
136         cpu->extn.smart = bcr.ver ? 1 : 0;
137
138         READ_BCR(ARC_REG_RTT_BCR, bcr);
139         cpu->extn.rtt = bcr.ver ? 1 : 0;
140
141         cpu->extn.debug = cpu->extn.ap | cpu->extn.smart | cpu->extn.rtt;
142 }
143
144 static const struct cpuinfo_data arc_cpu_tbl[] = {
145         { {0x20, "ARC 600"      }, 0x2F},
146         { {0x30, "ARC 700"      }, 0x33},
147         { {0x34, "ARC 700 R4.10"}, 0x34},
148         { {0x35, "ARC 700 R4.11"}, 0x35},
149         { {0x50, "ARC HS38"     }, 0x51},
150         { {0x00, NULL           } }
151 };
152
153 #define IS_AVAIL1(v, str)       ((v) ? str : "")
154 #define IS_USED(cfg)            (IS_ENABLED(cfg) ? "" : "(not used) ")
155 #define IS_AVAIL2(v, str, cfg)  IS_AVAIL1(v, str), IS_AVAIL1(v, IS_USED(cfg))
156
157 static char *arc_cpu_mumbojumbo(int cpu_id, char *buf, int len)
158 {
159         struct cpuinfo_arc *cpu = &cpuinfo_arc700[cpu_id];
160         struct bcr_identity *core = &cpu->core;
161         const struct cpuinfo_data *tbl;
162         char *isa_nm;
163         int i, be, atomic;
164         int n = 0;
165
166         FIX_PTR(cpu);
167
168         if (is_isa_arcompact()) {
169                 isa_nm = "ARCompact";
170                 be = IS_ENABLED(CONFIG_CPU_BIG_ENDIAN);
171
172                 atomic = cpu->isa.atomic1;
173                 if (!cpu->isa.ver)      /* ISA BCR absent, use Kconfig info */
174                         atomic = IS_ENABLED(CONFIG_ARC_HAS_LLSC);
175         } else {
176                 isa_nm = "ARCv2";
177                 be = cpu->isa.be;
178                 atomic = cpu->isa.atomic;
179         }
180
181         n += scnprintf(buf + n, len - n,
182                        "\nIDENTITY\t: ARCVER [%#02x] ARCNUM [%#02x] CHIPID [%#4x]\n",
183                        core->family, core->cpu_id, core->chip_id);
184
185         for (tbl = &arc_cpu_tbl[0]; tbl->info.id != 0; tbl++) {
186                 if ((core->family >= tbl->info.id) &&
187                     (core->family <= tbl->up_range)) {
188                         n += scnprintf(buf + n, len - n,
189                                        "processor [%d]\t: %s (%s ISA) %s\n",
190                                        cpu_id, tbl->info.str, isa_nm,
191                                        IS_AVAIL1(be, "[Big-Endian]"));
192                         break;
193                 }
194         }
195
196         if (tbl->info.id == 0)
197                 n += scnprintf(buf + n, len - n, "UNKNOWN ARC Processor\n");
198
199         n += scnprintf(buf + n, len - n, "CPU speed\t: %u.%02u Mhz\n",
200                        (unsigned int)(arc_get_core_freq() / 1000000),
201                        (unsigned int)(arc_get_core_freq() / 10000) % 100);
202
203         n += scnprintf(buf + n, len - n, "Timers\t\t: %s%s%s%s\nISA Extn\t: ",
204                        IS_AVAIL1(cpu->timers.t0, "Timer0 "),
205                        IS_AVAIL1(cpu->timers.t1, "Timer1 "),
206                        IS_AVAIL2(cpu->timers.rtc, "64-bit RTC ",
207                                  CONFIG_ARC_HAS_RTC));
208
209         n += i = scnprintf(buf + n, len - n, "%s%s%s%s%s",
210                            IS_AVAIL2(atomic, "atomic ", CONFIG_ARC_HAS_LLSC),
211                            IS_AVAIL2(cpu->isa.ldd, "ll64 ", CONFIG_ARC_HAS_LL64),
212                            IS_AVAIL1(cpu->isa.unalign, "unalign (not used)"));
213
214         if (i)
215                 n += scnprintf(buf + n, len - n, "\n\t\t: ");
216
217         if (cpu->extn_mpy.ver) {
218                 if (cpu->extn_mpy.ver <= 0x2) { /* ARCompact */
219                         n += scnprintf(buf + n, len - n, "mpy ");
220                 } else {
221                         int opt = 2;    /* stock MPY/MPYH */
222
223                         if (cpu->extn_mpy.dsp)  /* OPT 7-9 */
224                                 opt = cpu->extn_mpy.dsp + 6;
225
226                         n += scnprintf(buf + n, len - n, "mpy[opt %d] ", opt);
227                 }
228                 n += scnprintf(buf + n, len - n, "%s",
229                                IS_USED(CONFIG_ARC_HAS_HW_MPY));
230         }
231
232         n += scnprintf(buf + n, len - n, "%s%s%s%s%s%s%s%s\n",
233                        IS_AVAIL1(cpu->isa.div_rem, "div_rem "),
234                        IS_AVAIL1(cpu->extn.norm, "norm "),
235                        IS_AVAIL1(cpu->extn.barrel, "barrel-shift "),
236                        IS_AVAIL1(cpu->extn.swap, "swap "),
237                        IS_AVAIL1(cpu->extn.minmax, "minmax "),
238                        IS_AVAIL1(cpu->extn.crc, "crc "),
239                        IS_AVAIL2(1, "swape", CONFIG_ARC_HAS_SWAPE));
240
241         if (cpu->bpu.ver)
242                 n += scnprintf(buf + n, len - n,
243                               "BPU\t\t: %s%s match, cache:%d, Predict Table:%d\n",
244                               IS_AVAIL1(cpu->bpu.full, "full"),
245                               IS_AVAIL1(!cpu->bpu.full, "partial"),
246                               cpu->bpu.num_cache, cpu->bpu.num_pred);
247
248         return buf;
249 }
250
251 static char *arc_extn_mumbojumbo(int cpu_id, char *buf, int len)
252 {
253         int n = 0;
254         struct cpuinfo_arc *cpu = &cpuinfo_arc700[cpu_id];
255
256         FIX_PTR(cpu);
257
258         n += scnprintf(buf + n, len - n,
259                        "Vector Table\t: %#x\nUncached Base\t: %#x\n",
260                        cpu->vec_base, ARC_UNCACHED_ADDR_SPACE);
261
262         if (cpu->extn.fpu_sp || cpu->extn.fpu_dp)
263                 n += scnprintf(buf + n, len - n, "FPU\t\t: %s%s\n",
264                                IS_AVAIL1(cpu->extn.fpu_sp, "SP "),
265                                IS_AVAIL1(cpu->extn.fpu_dp, "DP "));
266
267         if (cpu->extn.debug)
268                 n += scnprintf(buf + n, len - n, "DEBUG\t\t: %s%s%s\n",
269                                IS_AVAIL1(cpu->extn.ap, "ActionPoint "),
270                                IS_AVAIL1(cpu->extn.smart, "smaRT "),
271                                IS_AVAIL1(cpu->extn.rtt, "RTT "));
272
273         if (cpu->dccm.sz || cpu->iccm.sz)
274                 n += scnprintf(buf + n, len - n, "Extn [CCM]\t: DCCM @ %x, %d KB / ICCM: @ %x, %d KB\n",
275                                cpu->dccm.base_addr, TO_KB(cpu->dccm.sz),
276                                cpu->iccm.base_addr, TO_KB(cpu->iccm.sz));
277
278         n += scnprintf(buf + n, len - n,
279                        "OS ABI [v3]\t: no-legacy-syscalls\n");
280
281         return buf;
282 }
283
284 static void arc_chk_core_config(void)
285 {
286         struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()];
287         int fpu_enabled;
288
289         if (!cpu->timers.t0)
290                 panic("Timer0 is not present!\n");
291
292         if (!cpu->timers.t1)
293                 panic("Timer1 is not present!\n");
294
295         if (IS_ENABLED(CONFIG_ARC_HAS_RTC) && !cpu->timers.rtc)
296                 panic("RTC is not present\n");
297
298 #ifdef CONFIG_ARC_HAS_DCCM
299         /*
300          * DCCM can be arbit placed in hardware.
301          * Make sure it's placement/sz matches what Linux is built with
302          */
303         if ((unsigned int)__arc_dccm_base != cpu->dccm.base_addr)
304                 panic("Linux built with incorrect DCCM Base address\n");
305
306         if (CONFIG_ARC_DCCM_SZ != cpu->dccm.sz)
307                 panic("Linux built with incorrect DCCM Size\n");
308 #endif
309
310 #ifdef CONFIG_ARC_HAS_ICCM
311         if (CONFIG_ARC_ICCM_SZ != cpu->iccm.sz)
312                 panic("Linux built with incorrect ICCM Size\n");
313 #endif
314
315         /*
316          * FP hardware/software config sanity
317          * -If hardware contains DPFP, kernel needs to save/restore FPU state
318          * -If not, it will crash trying to save/restore the non-existant regs
319          *
320          * (only DPDP checked since SP has no arch visible regs)
321          */
322         fpu_enabled = IS_ENABLED(CONFIG_ARC_FPU_SAVE_RESTORE);
323
324         if (cpu->extn.fpu_dp && !fpu_enabled)
325                 pr_warn("CONFIG_ARC_FPU_SAVE_RESTORE needed for working apps\n");
326         else if (!cpu->extn.fpu_dp && fpu_enabled)
327                 panic("FPU non-existent, disable CONFIG_ARC_FPU_SAVE_RESTORE\n");
328 }
329
330 /*
331  * Initialize and setup the processor core
332  * This is called by all the CPUs thus should not do special case stuff
333  *    such as only for boot CPU etc
334  */
335
336 void setup_processor(void)
337 {
338         char str[512];
339         int cpu_id = smp_processor_id();
340
341         read_arc_build_cfg_regs();
342         arc_init_IRQ();
343
344         printk(arc_cpu_mumbojumbo(cpu_id, str, sizeof(str)));
345
346         arc_mmu_init();
347         arc_cache_init();
348
349         printk(arc_extn_mumbojumbo(cpu_id, str, sizeof(str)));
350         printk(arc_platform_smp_cpuinfo());
351
352         arc_chk_core_config();
353 }
354
355 static inline int is_kernel(unsigned long addr)
356 {
357         if (addr >= (unsigned long)_stext && addr <= (unsigned long)_end)
358                 return 1;
359         return 0;
360 }
361
362 void __init setup_arch(char **cmdline_p)
363 {
364 #ifdef CONFIG_ARC_UBOOT_SUPPORT
365         /* make sure that uboot passed pointer to cmdline/dtb is valid */
366         if (uboot_tag && is_kernel((unsigned long)uboot_arg))
367                 panic("Invalid uboot arg\n");
368
369         /* See if u-boot passed an external Device Tree blob */
370         machine_desc = setup_machine_fdt(uboot_arg);    /* uboot_tag == 2 */
371         if (!machine_desc)
372 #endif
373         {
374                 /* No, so try the embedded one */
375                 machine_desc = setup_machine_fdt(__dtb_start);
376                 if (!machine_desc)
377                         panic("Embedded DT invalid\n");
378
379                 /*
380                  * If we are here, it is established that @uboot_arg didn't
381                  * point to DT blob. Instead if u-boot says it is cmdline,
382                  * Appent to embedded DT cmdline.
383                  * setup_machine_fdt() would have populated @boot_command_line
384                  */
385                 if (uboot_tag == 1) {
386                         /* Ensure a whitespace between the 2 cmdlines */
387                         strlcat(boot_command_line, " ", COMMAND_LINE_SIZE);
388                         strlcat(boot_command_line, uboot_arg,
389                                 COMMAND_LINE_SIZE);
390                 }
391         }
392
393         /* Save unparsed command line copy for /proc/cmdline */
394         *cmdline_p = boot_command_line;
395
396         /* To force early parsing of things like mem=xxx */
397         parse_early_param();
398
399         /* Platform/board specific: e.g. early console registration */
400         if (machine_desc->init_early)
401                 machine_desc->init_early();
402
403         setup_processor();
404         smp_init_cpus();
405         setup_arch_memory();
406
407         /* copy flat DT out of .init and then unflatten it */
408         unflatten_and_copy_device_tree();
409
410         /* Can be issue if someone passes cmd line arg "ro"
411          * But that is unlikely so keeping it as it is
412          */
413         root_mountflags &= ~MS_RDONLY;
414
415 #if defined(CONFIG_VT) && defined(CONFIG_DUMMY_CONSOLE)
416         conswitchp = &dummy_con;
417 #endif
418
419         arc_unwind_init();
420         arc_unwind_setup();
421 }
422
423 static int __init customize_machine(void)
424 {
425         of_clk_init(NULL);
426         /*
427          * Traverses flattened DeviceTree - registering platform devices
428          * (if any) complete with their resources
429          */
430         of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
431
432         if (machine_desc->init_machine)
433                 machine_desc->init_machine();
434
435         return 0;
436 }
437 arch_initcall(customize_machine);
438
439 static int __init init_late_machine(void)
440 {
441         if (machine_desc->init_late)
442                 machine_desc->init_late();
443
444         return 0;
445 }
446 late_initcall(init_late_machine);
447 /*
448  *  Get CPU information for use by the procfs.
449  */
450
451 #define cpu_to_ptr(c)   ((void *)(0xFFFF0000 | (unsigned int)(c)))
452 #define ptr_to_cpu(p)   (~0xFFFF0000UL & (unsigned int)(p))
453
454 static int show_cpuinfo(struct seq_file *m, void *v)
455 {
456         char *str;
457         int cpu_id = ptr_to_cpu(v);
458
459         if (!cpu_online(cpu_id)) {
460                 seq_printf(m, "processor [%d]\t: Offline\n", cpu_id);
461                 goto done;
462         }
463
464         str = (char *)__get_free_page(GFP_TEMPORARY);
465         if (!str)
466                 goto done;
467
468         seq_printf(m, arc_cpu_mumbojumbo(cpu_id, str, PAGE_SIZE));
469
470         seq_printf(m, "Bogo MIPS\t: %lu.%02lu\n",
471                    loops_per_jiffy / (500000 / HZ),
472                    (loops_per_jiffy / (5000 / HZ)) % 100);
473
474         seq_printf(m, arc_mmu_mumbojumbo(cpu_id, str, PAGE_SIZE));
475         seq_printf(m, arc_cache_mumbojumbo(cpu_id, str, PAGE_SIZE));
476         seq_printf(m, arc_extn_mumbojumbo(cpu_id, str, PAGE_SIZE));
477         seq_printf(m, arc_platform_smp_cpuinfo());
478
479         free_page((unsigned long)str);
480 done:
481         seq_printf(m, "\n");
482
483         return 0;
484 }
485
486 static void *c_start(struct seq_file *m, loff_t *pos)
487 {
488         /*
489          * Callback returns cpu-id to iterator for show routine, NULL to stop.
490          * However since NULL is also a valid cpu-id (0), we use a round-about
491          * way to pass it w/o having to kmalloc/free a 2 byte string.
492          * Encode cpu-id as 0xFFcccc, which is decoded by show routine.
493          */
494         return *pos < num_possible_cpus() ? cpu_to_ptr(*pos) : NULL;
495 }
496
497 static void *c_next(struct seq_file *m, void *v, loff_t *pos)
498 {
499         ++*pos;
500         return c_start(m, pos);
501 }
502
503 static void c_stop(struct seq_file *m, void *v)
504 {
505 }
506
507 const struct seq_operations cpuinfo_op = {
508         .start  = c_start,
509         .next   = c_next,
510         .stop   = c_stop,
511         .show   = show_cpuinfo
512 };
513
514 static DEFINE_PER_CPU(struct cpu, cpu_topology);
515
516 static int __init topology_init(void)
517 {
518         int cpu;
519
520         for_each_present_cpu(cpu)
521             register_cpu(&per_cpu(cpu_topology, cpu), cpu);
522
523         return 0;
524 }
525
526 subsys_initcall(topology_init);