^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * linux/arch/h8300/kernel/setup.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2001-2014 Yoshinori Sato <ysato@users.sourceforge.jp>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * This file handles the architecture-dependent parts of system setup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/console.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/seq_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/of_fdt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/of_address.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/clk-provider.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/memblock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/screen_info.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/clocksource.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <asm/setup.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <asm/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <asm/sections.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <asm/page.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #if defined(CONFIG_CPU_H8300H)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define CPU "H8/300H"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #elif defined(CONFIG_CPU_H8S)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define CPU "H8S"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define CPU "Unknown"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) unsigned long memory_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) unsigned long memory_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) EXPORT_SYMBOL(memory_end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) static unsigned long freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) extern char __dtb_start[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #ifdef CONFIG_VT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) struct screen_info screen_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) char __initdata command_line[COMMAND_LINE_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) void sim_console_register(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) void __init h8300_fdt_init(void *fdt, char *bootargs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) if (!fdt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) fdt = __dtb_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) strcpy(command_line, bootargs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) early_init_dt_scan(fdt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) memblock_allow_resize();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) static void __init bootmem_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) struct memblock_region *region;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) memory_end = memory_start = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) /* Find main memory where is the kernel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) memory_start = memblock_start_of_DRAM();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) memory_end = memblock_end_of_DRAM();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) if (!memory_end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) panic("No memory!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) /* setup bootmem globals (we use no_bootmem, but mm still depends on this) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) min_low_pfn = PFN_UP(memory_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) max_low_pfn = PFN_DOWN(memory_end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) max_pfn = max_low_pfn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) memblock_reserve(__pa(_stext), _end - _stext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) early_init_fdt_reserve_self();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) early_init_fdt_scan_reserved_mem();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) memblock_dump_all();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) void __init setup_arch(char **cmdline_p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) unflatten_and_copy_device_tree();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) init_mm.start_code = (unsigned long) _stext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) init_mm.end_code = (unsigned long) _etext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) init_mm.end_data = (unsigned long) _edata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) init_mm.brk = (unsigned long) 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) pr_notice("\r\n\nuClinux " CPU "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) pr_notice("Flat model support (C) 1998,1999 Kenneth Albanowski, D. Jeff Dionne\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) if (*command_line)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) strcpy(boot_command_line, command_line);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) *cmdline_p = boot_command_line;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) parse_early_param();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) bootmem_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * get kmalloc into gear
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) paging_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * Get CPU information for use by the procfs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) static int show_cpuinfo(struct seq_file *m, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) char *cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) cpu = CPU;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) seq_printf(m, "CPU:\t\t%s\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) "Clock:\t\t%lu.%1luMHz\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) "BogoMips:\t%lu.%02lu\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) "Calibration:\t%lu loops\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) cpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) freq/1000, freq%1000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) (loops_per_jiffy*HZ)/500000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) ((loops_per_jiffy*HZ)/5000)%100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) (loops_per_jiffy*HZ));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) static void *c_start(struct seq_file *m, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) return *pos < num_possible_cpus() ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) ((void *) 0x12345678) : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) static void *c_next(struct seq_file *m, void *v, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) ++*pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) return c_start(m, pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) static void c_stop(struct seq_file *m, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) const struct seq_operations cpuinfo_op = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) .start = c_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) .next = c_next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) .stop = c_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) .show = show_cpuinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) #if defined(CONFIG_CPU_H8300H)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) #define get_wait(base, addr) ({ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) int baddr; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) baddr = ((addr) / 0x200000 * 2); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) w *= (readw((base) + 2) & (3 << baddr)) + 1; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) #if defined(CONFIG_CPU_H8S)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) #define get_wait(base, addr) ({ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) int baddr; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) baddr = ((addr) / 0x200000 * 16); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) w *= (readl((base) + 2) & (7 << baddr)) + 1; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) static __init int access_timing(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) struct device_node *bsc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) void __iomem *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) unsigned long addr = (unsigned long)&__delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) int bit = 1 << (addr / 0x200000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) int w;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) bsc = of_find_compatible_node(NULL, NULL, "renesas,h8300-bsc");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) base = of_iomap(bsc, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) w = (readb(base + 0) & bit)?2:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) if (readb(base + 1) & bit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) w *= get_wait(base, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) w *= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) return w * 3 / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) void __init calibrate_delay(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) struct device_node *cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) int freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) cpu = of_find_compatible_node(NULL, NULL, "renesas,h8300");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) of_property_read_s32(cpu, "clock-frequency", &freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) loops_per_jiffy = freq / HZ / (access_timing() * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) pr_cont("%lu.%02lu BogoMIPS (lpj=%lu)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) loops_per_jiffy / (500000 / HZ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) (loops_per_jiffy / (5000 / HZ)) % 100, loops_per_jiffy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) void __init time_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) of_clk_init(NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) timer_probe();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) }