linux/arch/h8300/kernel/setup.c
<<
>>
Prefs
   1/*
   2 *  linux/arch/h8300/kernel/setup.c
   3 *
   4 *  Copyright (C) 2001-2014 Yoshinori Sato <ysato@users.sourceforge.jp>
   5 */
   6
   7/*
   8 * This file handles the architecture-dependent parts of system setup
   9 */
  10
  11#include <linux/kernel.h>
  12#include <linux/sched.h>
  13#include <linux/delay.h>
  14#include <linux/interrupt.h>
  15#include <linux/mm.h>
  16#include <linux/fs.h>
  17#include <linux/console.h>
  18#include <linux/errno.h>
  19#include <linux/string.h>
  20#include <linux/bootmem.h>
  21#include <linux/seq_file.h>
  22#include <linux/init.h>
  23#include <linux/platform_device.h>
  24#include <linux/module.h>
  25#include <linux/of.h>
  26#include <linux/of_fdt.h>
  27#include <linux/of_platform.h>
  28#include <linux/of_address.h>
  29#include <linux/clk-provider.h>
  30#include <linux/memblock.h>
  31#include <linux/screen_info.h>
  32#include <linux/clocksource.h>
  33
  34#include <asm/setup.h>
  35#include <asm/irq.h>
  36#include <asm/pgtable.h>
  37#include <asm/sections.h>
  38#include <asm/page.h>
  39
  40#if defined(CONFIG_CPU_H8300H)
  41#define CPU "H8/300H"
  42#elif defined(CONFIG_CPU_H8S)
  43#define CPU "H8S"
  44#else
  45#define CPU "Unknown"
  46#endif
  47
  48unsigned long memory_start;
  49unsigned long memory_end;
  50EXPORT_SYMBOL(memory_end);
  51static unsigned long freq;
  52extern char __dtb_start[];
  53
  54#ifdef CONFIG_VT
  55struct screen_info screen_info;
  56#endif
  57
  58char __initdata command_line[COMMAND_LINE_SIZE];
  59
  60void sim_console_register(void);
  61
  62void __init h8300_fdt_init(void *fdt, char *bootargs)
  63{
  64        if (!fdt)
  65                fdt = __dtb_start;
  66        else
  67                strcpy(command_line, bootargs);
  68
  69        early_init_dt_scan(fdt);
  70        memblock_allow_resize();
  71}
  72
  73static void __init bootmem_init(void)
  74{
  75        int bootmap_size;
  76        unsigned long ram_start_pfn;
  77        unsigned long free_ram_start_pfn;
  78        unsigned long ram_end_pfn;
  79        struct memblock_region *region;
  80
  81        memory_end = memory_start = 0;
  82
  83        /* Find main memory where is the kernel */
  84        for_each_memblock(memory, region) {
  85                memory_start = region->base;
  86                memory_end = region->base + region->size;
  87        }
  88
  89        if (!memory_end)
  90                panic("No memory!");
  91
  92        ram_start_pfn = PFN_UP(memory_start);
  93        /* free_ram_start_pfn is first page after kernel */
  94        free_ram_start_pfn = PFN_UP(__pa(_end));
  95        ram_end_pfn = PFN_DOWN(memblock_end_of_DRAM());
  96
  97        max_pfn = ram_end_pfn;
  98
  99        /*
 100         * give all the memory to the bootmap allocator,  tell it to put the
 101         * boot mem_map at the start of memory
 102         */
 103        bootmap_size = init_bootmem_node(NODE_DATA(0),
 104                                         free_ram_start_pfn,
 105                                         0,
 106                                         ram_end_pfn);
 107        /*
 108         * free the usable memory,  we have to make sure we do not free
 109         * the bootmem bitmap so we then reserve it after freeing it :-)
 110         */
 111        free_bootmem(PFN_PHYS(free_ram_start_pfn),
 112                     (ram_end_pfn - free_ram_start_pfn) << PAGE_SHIFT);
 113        reserve_bootmem(PFN_PHYS(free_ram_start_pfn), bootmap_size,
 114                        BOOTMEM_DEFAULT);
 115
 116        for_each_memblock(reserved, region) {
 117                reserve_bootmem(region->base, region->size, BOOTMEM_DEFAULT);
 118        }
 119}
 120
 121void __init setup_arch(char **cmdline_p)
 122{
 123        unflatten_and_copy_device_tree();
 124
 125        init_mm.start_code = (unsigned long) _stext;
 126        init_mm.end_code = (unsigned long) _etext;
 127        init_mm.end_data = (unsigned long) _edata;
 128        init_mm.brk = (unsigned long) 0;
 129
 130        pr_notice("\r\n\nuClinux " CPU "\n");
 131        pr_notice("Flat model support (C) 1998,1999 Kenneth Albanowski, D. Jeff Dionne\n");
 132
 133        if (*command_line)
 134                strcpy(boot_command_line, command_line);
 135        *cmdline_p = boot_command_line;
 136
 137        parse_early_param();
 138
 139        bootmem_init();
 140#if defined(CONFIG_H8300H_SIM) || defined(CONFIG_H8S_SIM)
 141        sim_console_register();
 142#endif
 143
 144        early_platform_driver_probe("earlyprintk", 1, 0);
 145        /*
 146         * get kmalloc into gear
 147         */
 148        paging_init();
 149}
 150
 151/*
 152 *      Get CPU information for use by the procfs.
 153 */
 154
 155static int show_cpuinfo(struct seq_file *m, void *v)
 156{
 157        char *cpu;
 158
 159        cpu = CPU;
 160
 161        seq_printf(m,  "CPU:\t\t%s\n"
 162                   "Clock:\t\t%lu.%1luMHz\n"
 163                   "BogoMips:\t%lu.%02lu\n"
 164                   "Calibration:\t%lu loops\n",
 165                   cpu,
 166                   freq/1000, freq%1000,
 167                   (loops_per_jiffy*HZ)/500000,
 168                   ((loops_per_jiffy*HZ)/5000)%100,
 169                   (loops_per_jiffy*HZ));
 170
 171        return 0;
 172}
 173
 174static void *c_start(struct seq_file *m, loff_t *pos)
 175{
 176        return *pos < num_possible_cpus() ?
 177                ((void *) 0x12345678) : NULL;
 178}
 179
 180static void *c_next(struct seq_file *m, void *v, loff_t *pos)
 181{
 182        ++*pos;
 183        return c_start(m, pos);
 184}
 185
 186static void c_stop(struct seq_file *m, void *v)
 187{
 188}
 189
 190const struct seq_operations cpuinfo_op = {
 191        .start  = c_start,
 192        .next   = c_next,
 193        .stop   = c_stop,
 194        .show   = show_cpuinfo,
 195};
 196
 197static int __init device_probe(void)
 198{
 199        of_platform_populate(NULL, NULL, NULL, NULL);
 200
 201        return 0;
 202}
 203
 204device_initcall(device_probe);
 205
 206#if defined(CONFIG_CPU_H8300H)
 207#define get_wait(base, addr) ({         \
 208        int baddr;                      \
 209        baddr = ((addr) / 0x200000 * 2);                             \
 210        w *= (readw((base) + 2) & (3 << baddr)) + 1;                 \
 211        })
 212#endif
 213#if defined(CONFIG_CPU_H8S)
 214#define get_wait(base, addr) ({         \
 215        int baddr;                      \
 216        baddr = ((addr) / 0x200000 * 16);                            \
 217        w *= (readl((base) + 2) & (7 << baddr)) + 1;    \
 218        })
 219#endif
 220
 221static __init int access_timing(void)
 222{
 223        struct device_node *bsc;
 224        void __iomem *base;
 225        unsigned long addr = (unsigned long)&__delay;
 226        int bit = 1 << (addr / 0x200000);
 227        int w;
 228
 229        bsc = of_find_compatible_node(NULL, NULL, "renesas,h8300-bsc");
 230        base = of_iomap(bsc, 0);
 231        w = (readb(base + 0) & bit)?2:1;
 232        if (readb(base + 1) & bit)
 233                w *= get_wait(base, addr);
 234        else
 235                w *= 2;
 236        return w * 3 / 2;
 237}
 238
 239void __init calibrate_delay(void)
 240{
 241        struct device_node *cpu;
 242        int freq;
 243
 244        cpu = of_find_compatible_node(NULL, NULL, "renesas,h8300");
 245        of_property_read_s32(cpu, "clock-frequency", &freq);
 246        loops_per_jiffy = freq / HZ / (access_timing() * 2);
 247        pr_cont("%lu.%02lu BogoMIPS (lpj=%lu)\n",
 248                loops_per_jiffy / (500000 / HZ),
 249                (loops_per_jiffy / (5000 / HZ)) % 100, loops_per_jiffy);
 250}
 251
 252
 253void __init time_init(void)
 254{
 255        of_clk_init(NULL);
 256        clocksource_probe();
 257}
 258