Merge branch 'adm8668'
[lede.git] / target / linux / adm8668 / files / arch / mips / adm8668 / prom.c
1 /*
2  * Copyright (C) 2010 Scott Nicholas <neutronscott@scottn.us>
3  *
4  * based on work of rb532 prom.c
5  *  Copyright (C) 2003, Peter Sadik <peter.sadik@idt.com>
6  *  Copyright (C) 2005-2006, P.Christeas <p_christ@hol.gr>
7  *  Copyright (C) 2007, Gabor Juhos <juhosg@openwrt.org>
8  *                      Felix Fietkau <nbd@openwrt.org>
9  *                      Florian Fainelli <florian@openwrt.org>
10  *
11  * This file is subject to the terms and conditions of the GNU General Public
12  * License.  See the file "COPYING" in the main directory of this archive
13  * for more details.
14  */
15
16 #include <linux/init.h>
17 #include <linux/kernel.h>
18 #include <linux/types.h>
19 #include <linux/console.h>
20 #include <linux/string.h>
21 #include <linux/serial_core.h>
22 #include <asm/bootinfo.h>
23 #include <adm8668.h>
24 #include "u-boot.h"
25
26 register volatile struct global_data *gd asm ("k0");
27
28 #ifdef CONFIG_SERIAL_ADM8668_CONSOLE
29 static inline unsigned int adm_uart_readl(unsigned int offset)
30 {
31         return (*(volatile unsigned int *)(0xbe400000 + offset));
32 }
33
34 static inline void adm_uart_writel(unsigned int value, unsigned int offset)
35 {
36         (*((volatile unsigned int *)(0xbe400000 + offset))) = value;
37 }
38
39 static void prom_putchar(char c)
40 {
41         adm_uart_writel(c, UART_DR_REG);
42         while ((adm_uart_readl(UART_FR_REG) & UART_TX_FIFO_FULL) != 0)
43                 ;
44 }
45
46 static void __init
47 early_console_write(struct console *con, const char *s, unsigned n)
48 {
49         while (n-- && *s) {
50                 if (*s == '\n')
51                         prom_putchar('\r');
52                 prom_putchar(*s);
53                 s++;
54         }
55 }
56
57 static struct console early_console __initdata = {
58         .name   = "early",
59         .write  = early_console_write,
60         .flags  = CON_BOOT,
61         .index  = -1
62 };
63
64 #endif
65
66 void __init prom_free_prom_memory(void)
67 {
68         /* No prom memory to free */
69 }
70
71 static inline int match_tag(char *arg, const char *tag)
72 {
73         return strncmp(arg, tag, strlen(tag)) == 0;
74 }
75
76 static inline unsigned long tag2ul(char *arg, const char *tag)
77 {
78         char *num;
79
80         num = arg + strlen(tag);
81         return simple_strtoul(num, 0, 10);
82 }
83
84 void __init prom_setup_cmdline(void)
85 {
86         char *cp;
87         int prom_argc;
88         char **prom_argv;
89         int i;
90
91         prom_argc = fw_arg0;
92         prom_argv = (char **)KSEG0ADDR(fw_arg1);
93
94         cp = &(arcs_cmdline[0]);
95         for (i = 1; i < prom_argc; i++) {
96                 prom_argv[i] = (char *)KSEG0ADDR(prom_argv[i]);
97
98                 /* default bootargs has "console=/dev/ttyS0" yet console won't
99                  * show up at all if you do this ... */
100                 if (match_tag(prom_argv[i], "console=/dev/")) {
101                         char *ptr = prom_argv[i] + strlen("console=/dev/");
102
103                         strcpy(cp, "console=");
104                         cp += strlen("console=");
105                         strcpy(cp, ptr);
106                         cp += strlen(ptr);
107                         *cp++ = ' ';
108                         continue;
109                 }
110                 strcpy(cp, prom_argv[i]);
111                 cp += strlen(prom_argv[i]);
112                 *cp++ = ' ';
113         }
114         if (prom_argc > 1)
115                 --cp; /* trailing space */
116
117         *cp = '\0';
118 }
119
120 void __init prom_init(void)
121 {
122         bd_t *bd = gd->bd;
123         int memsize;
124
125 #ifdef CONFIG_SERIAL_ADM8668_CONSOLE
126         register_console(&early_console);
127 #endif
128
129         memsize = bd->bi_memsize;
130         printk("Board info:\n");
131         printk("  Board ID: %#lx\n", bd->bi_arch_number);
132         printk("  RAM size: %d MB\n", (int)memsize/(1024*1024));
133         printk("  NOR start: %#lx\n", bd->bi_flashstart);
134         printk("  NOR size: %#lx\n", bd->bi_flashsize);
135
136         prom_setup_cmdline();
137         add_memory_region(0, memsize, BOOT_MEM_RAM);
138 }