Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *  RouterBoard 500 specific prom routines
0004  *
0005  *  Copyright (C) 2003, Peter Sadik <peter.sadik@idt.com>
0006  *  Copyright (C) 2005-2006, P.Christeas <p_christ@hol.gr>
0007  *  Copyright (C) 2007, Gabor Juhos <juhosg@openwrt.org>
0008  *          Felix Fietkau <nbd@openwrt.org>
0009  *          Florian Fainelli <florian@openwrt.org>
0010  */
0011 
0012 #include <linux/init.h>
0013 #include <linux/mm.h>
0014 #include <linux/export.h>
0015 #include <linux/string.h>
0016 #include <linux/console.h>
0017 #include <linux/memblock.h>
0018 #include <linux/ioport.h>
0019 
0020 #include <asm/bootinfo.h>
0021 #include <asm/mach-rc32434/ddr.h>
0022 #include <asm/mach-rc32434/prom.h>
0023 
0024 unsigned int idt_cpu_freq = 132000000;
0025 EXPORT_SYMBOL(idt_cpu_freq);
0026 
0027 static struct resource ddr_reg[] = {
0028     {
0029         .name = "ddr-reg",
0030         .start = DDR0_PHYS_ADDR,
0031         .end = DDR0_PHYS_ADDR + sizeof(struct ddr_ram),
0032         .flags = IORESOURCE_MEM,
0033     }
0034 };
0035 
0036 static inline int match_tag(char *arg, const char *tag)
0037 {
0038     return strncmp(arg, tag, strlen(tag)) == 0;
0039 }
0040 
0041 static inline unsigned long tag2ul(char *arg, const char *tag)
0042 {
0043     char *num;
0044 
0045     num = arg + strlen(tag);
0046     return simple_strtoul(num, 0, 10);
0047 }
0048 
0049 void __init prom_setup_cmdline(void)
0050 {
0051     static char cmd_line[COMMAND_LINE_SIZE] __initdata;
0052     char *cp, *board;
0053     int prom_argc;
0054     char **prom_argv;
0055     int i;
0056 
0057     prom_argc = fw_arg0;
0058     prom_argv = (char **) fw_arg1;
0059 
0060     cp = cmd_line;
0061         /* Note: it is common that parameters start
0062          * at argv[1] and not argv[0],
0063          * however, our elf loader starts at [0] */
0064     for (i = 0; i < prom_argc; i++) {
0065         if (match_tag(prom_argv[i], FREQ_TAG)) {
0066             idt_cpu_freq = tag2ul(prom_argv[i], FREQ_TAG);
0067             continue;
0068         }
0069 #ifdef IGNORE_CMDLINE_MEM
0070         /* parses out the "mem=xx" arg */
0071         if (match_tag(prom_argv[i], MEM_TAG))
0072             continue;
0073 #endif
0074         if (i > 0)
0075             *(cp++) = ' ';
0076         if (match_tag(prom_argv[i], BOARD_TAG)) {
0077             board = prom_argv[i] + strlen(BOARD_TAG);
0078 
0079             if (match_tag(board, BOARD_RB532A))
0080                 mips_machtype = MACH_MIKROTIK_RB532A;
0081             else
0082                 mips_machtype = MACH_MIKROTIK_RB532;
0083         }
0084 
0085         strcpy(cp, prom_argv[i]);
0086         cp += strlen(prom_argv[i]);
0087     }
0088     *(cp++) = ' ';
0089 
0090     i = strlen(arcs_cmdline);
0091     if (i > 0) {
0092         *(cp++) = ' ';
0093         strcpy(cp, arcs_cmdline);
0094         cp += strlen(arcs_cmdline);
0095     }
0096     cmd_line[COMMAND_LINE_SIZE - 1] = '\0';
0097 
0098     strcpy(arcs_cmdline, cmd_line);
0099 }
0100 
0101 void __init prom_init(void)
0102 {
0103     struct ddr_ram __iomem *ddr;
0104     phys_addr_t memsize;
0105     phys_addr_t ddrbase;
0106 
0107     ddr = ioremap(ddr_reg[0].start,
0108             ddr_reg[0].end - ddr_reg[0].start);
0109 
0110     if (!ddr) {
0111         printk(KERN_ERR "Unable to remap DDR register\n");
0112         return;
0113     }
0114 
0115     ddrbase = (phys_addr_t)&ddr->ddrbase;
0116     memsize = (phys_addr_t)&ddr->ddrmask;
0117     memsize = 0 - memsize;
0118 
0119     prom_setup_cmdline();
0120 
0121     /* give all RAM to boot allocator,
0122      * except for the first 0x400 and the last 0x200 bytes */
0123     memblock_add(ddrbase + 0x400, memsize - 0x600);
0124 }