604b01806c1d260690ba6696c0c0134a98c4b0d5
[openwrt/staging/mkresin.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 //extern int __init rtl838x_serial_init(void);
28
29 void prom_console_init(void)
30 {
31 /* UART 16550A is initialized by the bootloader */
32 }
33
34 #ifdef CONFIG_EARLY_PRINTK
35 #define rtl838x_r8(reg) __raw_readb(reg)
36 #define rtl838x_w8(val, reg) __raw_writeb(val, reg)
37
38 void unregister_prom_console(void)
39 {
40
41 }
42
43 void disable_early_printk(void)
44 {
45
46 }
47
48 void prom_putchar(char c)
49 {
50 unsigned int retry = 0;
51
52 do {
53 if (retry++ >= 30000) {
54 /* Reset Tx FIFO */
55 rtl838x_w8(TXRST | CHAR_TRIGGER_14, UART0_FCR);
56 return;
57 }
58 } while ((rtl838x_r8(UART0_LSR) & LSR_THRE) == TxCHAR_AVAIL);
59
60 /* Send Character */
61 rtl838x_w8(c, UART0_THR);
62 }
63
64 char prom_getchar(void)
65 {
66 return '\0';
67 }
68 #endif
69
70 struct rtl838x_soc_info soc_info;
71
72 const char *get_system_type(void)
73 {
74 return soc_info.name;
75 }
76
77
78 void __init prom_free_prom_memory(void)
79 {
80
81 }
82
83 void __init device_tree_init(void)
84 {
85 pr_info("%s called\r\n", __func__);
86 if (!fdt_check_header(&__appended_dtb)) {
87 fdt = &__appended_dtb;
88 pr_info("Using appended Device Tree.\n");
89 }
90 initial_boot_params = (void *)fdt;
91 unflatten_and_copy_device_tree();
92 }
93
94 static void __init prom_init_cmdline(void)
95 {
96 int argc = fw_arg0;
97 char **argv = (char **) KSEG1ADDR(fw_arg1);
98 int i;
99
100 arcs_cmdline[0] = '\0';
101
102 for (i = 0; i < argc; i++) {
103 char *p = (char *) KSEG1ADDR(argv[i]);
104
105 if (CPHYSADDR(p) && *p) {
106 strlcat(arcs_cmdline, p, sizeof(arcs_cmdline));
107 strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline));
108 }
109 }
110 pr_info("Kernel command line: %s\n", arcs_cmdline);
111 }
112
113 /* Do basic initialization */
114 void __init prom_init(void)
115 {
116 uint32_t model;
117
118 pr_info("%s called\n", __func__);
119 soc_info.sw_base = RTL838X_SW_BASE;
120
121 model = sw_r32(RTL838X_MODEL_NAME_INFO);
122 pr_info("RTL838X model is %x\n", model);
123 model = model >> 16 & 0xFFFF;
124
125 if ((model != 0x8328) && (model != 0x8330) && (model != 0x8332)
126 && (model != 0x8380) && (model != 0x8382)) {
127 model = sw_r32(RTL839X_MODEL_NAME_INFO);
128 pr_info("RTL839X model is %x\n", model);
129 model = model >> 16 & 0xFFFF;
130 }
131
132 soc_info.id = model;
133
134 switch (model) {
135 case 0x8328:
136 soc_info.name = "RTL8328";
137 soc_info.family = RTL8328_FAMILY_ID;
138 break;
139 case 0x8332:
140 soc_info.name = "RTL8332";
141 soc_info.family = RTL8380_FAMILY_ID;
142 break;
143 case 0x8380:
144 soc_info.name = "RTL8380";
145 soc_info.family = RTL8380_FAMILY_ID;
146 break;
147 case 0x8382:
148 soc_info.name = "RTL8382";
149 soc_info.family = RTL8380_FAMILY_ID;
150 break;
151 case 0x8390:
152 soc_info.name = "RTL8390";
153 soc_info.family = RTL8390_FAMILY_ID;
154 break;
155 case 0x8391:
156 soc_info.name = "RTL8391";
157 soc_info.family = RTL8390_FAMILY_ID;
158 break;
159 case 0x8392:
160 soc_info.name = "RTL8392";
161 soc_info.family = RTL8390_FAMILY_ID;
162 break;
163 case 0x8393:
164 soc_info.name = "RTL8393";
165 soc_info.family = RTL8390_FAMILY_ID;
166 break;
167 default:
168 soc_info.name = "DEFAULT";
169 soc_info.family = 0;
170 }
171 pr_info("SoC Type: %s\n", get_system_type());
172 prom_init_cmdline();
173 }
174