81507e235b642b9e4fe5496cf493c9fdc9aa47a4
[openwrt/staging/rmilecki.git] / target / linux / rtl838x / files-5.4 / arch / mips / rtl838x / prom.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * prom.c
4 * Early intialization code for the Realtek RTL838X SoC
5 *
6 * based on the original BSP by
7 * Copyright (C) 2006-2012 Tony Wu (tonywu@realtek.com)
8 * Copyright (C) 2020 B. Koblitz
9 *
10 */
11
12 #include <linux/init.h>
13 #include <linux/kernel.h>
14 #include <linux/string.h>
15 #include <linux/of_fdt.h>
16 #include <linux/libfdt.h>
17 #include <asm/bootinfo.h>
18 #include <asm/addrspace.h>
19 #include <asm/page.h>
20 #include <asm/cpu.h>
21
22 #include <mach-rtl838x.h>
23
24 extern char arcs_cmdline[];
25 const void *fdt;
26 extern const char __appended_dtb;
27
28 void prom_console_init(void)
29 {
30 /* UART 16550A is initialized by the bootloader */
31 }
32
33 #ifdef CONFIG_EARLY_PRINTK
34 #define rtl838x_r8(reg) __raw_readb(reg)
35 #define rtl838x_w8(val, reg) __raw_writeb(val, reg)
36
37 void unregister_prom_console(void)
38 {
39
40 }
41
42 void disable_early_printk(void)
43 {
44
45 }
46
47 void prom_putchar(char c)
48 {
49 unsigned int retry = 0;
50
51 do {
52 if (retry++ >= 30000) {
53 /* Reset Tx FIFO */
54 rtl838x_w8(TXRST | CHAR_TRIGGER_14, UART0_FCR);
55 return;
56 }
57 } while ((rtl838x_r8(UART0_LSR) & LSR_THRE) == TxCHAR_AVAIL);
58
59 /* Send Character */
60 rtl838x_w8(c, UART0_THR);
61 }
62
63 char prom_getchar(void)
64 {
65 return '\0';
66 }
67 #endif
68
69 const char *get_system_type(void)
70 {
71 return soc_info.name;
72 }
73
74
75 void __init prom_free_prom_memory(void)
76 {
77
78 }
79
80 void __init device_tree_init(void)
81 {
82 pr_info("%s called\r\n", __func__);
83 if (!fdt_check_header(&__appended_dtb)) {
84 fdt = &__appended_dtb;
85 pr_info("Using appended Device Tree.\n");
86 }
87 initial_boot_params = (void *)fdt;
88 unflatten_and_copy_device_tree();
89 }
90
91 static void __init prom_init_cmdline(void)
92 {
93 int argc = fw_arg0;
94 char **argv = (char **) KSEG1ADDR(fw_arg1);
95 int i;
96
97 arcs_cmdline[0] = '\0';
98
99 for (i = 0; i < argc; i++) {
100 char *p = (char *) KSEG1ADDR(argv[i]);
101
102 if (CPHYSADDR(p) && *p) {
103 strlcat(arcs_cmdline, p, sizeof(arcs_cmdline));
104 strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline));
105 }
106 }
107 pr_info("Kernel command line: %s\n", arcs_cmdline);
108 }
109
110 /* Do basic initialization */
111 void __init prom_init(void)
112 {
113 uint32_t model;
114
115 pr_info("%s called\n", __func__);
116 soc_info.sw_base = RTL838X_SW_BASE;
117
118 model = sw_r32(RTL838X_MODEL_NAME_INFO);
119 pr_info("RTL838X model is %x\n", model);
120 model = model >> 16 & 0xFFFF;
121
122 if ((model != 0x8328) && (model != 0x8330) && (model != 0x8332)
123 && (model != 0x8380) && (model != 0x8382)) {
124 model = sw_r32(RTL839X_MODEL_NAME_INFO);
125 pr_info("RTL839X model is %x\n", model);
126 model = model >> 16 & 0xFFFF;
127 }
128
129 soc_info.id = model;
130
131 switch (model) {
132 case 0x8328:
133 soc_info.name = "RTL8328";
134 soc_info.family = RTL8328_FAMILY_ID;
135 break;
136 case 0x8332:
137 soc_info.name = "RTL8332";
138 soc_info.family = RTL8380_FAMILY_ID;
139 break;
140 case 0x8380:
141 soc_info.name = "RTL8380";
142 soc_info.family = RTL8380_FAMILY_ID;
143 break;
144 case 0x8382:
145 soc_info.name = "RTL8382";
146 soc_info.family = RTL8380_FAMILY_ID;
147 break;
148 case 0x8390:
149 soc_info.name = "RTL8390";
150 soc_info.family = RTL8390_FAMILY_ID;
151 break;
152 case 0x8391:
153 soc_info.name = "RTL8391";
154 soc_info.family = RTL8390_FAMILY_ID;
155 break;
156 case 0x8392:
157 soc_info.name = "RTL8392";
158 soc_info.family = RTL8390_FAMILY_ID;
159 break;
160 case 0x8393:
161 soc_info.name = "RTL8393";
162 soc_info.family = RTL8390_FAMILY_ID;
163 break;
164 default:
165 soc_info.name = "DEFAULT";
166 soc_info.family = 0;
167 }
168 pr_info("SoC Type: %s\n", get_system_type());
169 prom_init_cmdline();
170 }