1 // SPDX-License-Identifier: GPL-2.0-only
4 * Parts of this file are based on Ralink's 2.6.21 BSP
11 #include <linux/kernel.h>
12 #include <linux/init.h>
13 #include <linux/bug.h>
14 #include <linux/slab.h>
15 #include <linux/sys_soc.h>
18 #include <asm/mipsregs.h>
19 #include <asm/mach-ralink/ralink_regs.h>
20 #include <asm/mach-ralink/rt305x.h>
24 static struct ralink_soc_info *soc_info_ptr;
26 static unsigned long rt5350_get_mem_size(void)
31 t = __raw_readl(RT305X_SYSC_BASE + SYSC_REG_SYSTEM_CONFIG);
32 t = (t >> RT5350_SYSCFG0_DRAM_SIZE_SHIFT) &
33 RT5350_SYSCFG0_DRAM_SIZE_MASK;
36 case RT5350_SYSCFG0_DRAM_SIZE_2M:
39 case RT5350_SYSCFG0_DRAM_SIZE_8M:
42 case RT5350_SYSCFG0_DRAM_SIZE_16M:
45 case RT5350_SYSCFG0_DRAM_SIZE_32M:
48 case RT5350_SYSCFG0_DRAM_SIZE_64M:
52 panic("rt5350: invalid DRAM size: %u", t);
59 void __init ralink_clk_init(void)
61 unsigned long cpu_rate, sys_rate, wdt_rate, uart_rate;
62 unsigned long wmac_rate = 40000000;
64 u32 t = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG);
66 if (soc_is_rt305x() || soc_is_rt3350()) {
67 t = (t >> RT305X_SYSCFG_CPUCLK_SHIFT) &
68 RT305X_SYSCFG_CPUCLK_MASK;
70 case RT305X_SYSCFG_CPUCLK_LOW:
73 case RT305X_SYSCFG_CPUCLK_HIGH:
77 sys_rate = uart_rate = wdt_rate = cpu_rate / 3;
78 } else if (soc_is_rt3352()) {
79 t = (t >> RT3352_SYSCFG0_CPUCLK_SHIFT) &
80 RT3352_SYSCFG0_CPUCLK_MASK;
82 case RT3352_SYSCFG0_CPUCLK_LOW:
85 case RT3352_SYSCFG0_CPUCLK_HIGH:
89 sys_rate = wdt_rate = cpu_rate / 3;
91 } else if (soc_is_rt5350()) {
92 t = (t >> RT5350_SYSCFG0_CPUCLK_SHIFT) &
93 RT5350_SYSCFG0_CPUCLK_MASK;
95 case RT5350_SYSCFG0_CPUCLK_360:
97 sys_rate = cpu_rate / 3;
99 case RT5350_SYSCFG0_CPUCLK_320:
100 cpu_rate = 320000000;
101 sys_rate = cpu_rate / 4;
103 case RT5350_SYSCFG0_CPUCLK_300:
104 cpu_rate = 300000000;
105 sys_rate = cpu_rate / 3;
110 uart_rate = 40000000;
116 if (soc_is_rt3352() || soc_is_rt5350()) {
117 u32 val = rt_sysc_r32(RT3352_SYSC_REG_SYSCFG0);
119 if (!(val & RT3352_CLKCFG0_XTAL_SEL))
120 wmac_rate = 20000000;
123 ralink_clk_add("cpu", cpu_rate);
124 ralink_clk_add("sys", sys_rate);
125 ralink_clk_add("10000900.i2c", uart_rate);
126 ralink_clk_add("10000a00.i2s", uart_rate);
127 ralink_clk_add("10000b00.spi", sys_rate);
128 ralink_clk_add("10000b40.spi", sys_rate);
129 ralink_clk_add("10000100.timer", wdt_rate);
130 ralink_clk_add("10000120.watchdog", wdt_rate);
131 ralink_clk_add("10000500.uart", uart_rate);
132 ralink_clk_add("10000c00.uartlite", uart_rate);
133 ralink_clk_add("10100000.ethernet", sys_rate);
134 ralink_clk_add("10180000.wmac", wmac_rate);
137 void __init ralink_of_remap(void)
139 rt_sysc_membase = plat_of_remap_node("ralink,rt3050-sysc");
140 rt_memc_membase = plat_of_remap_node("ralink,rt3050-memc");
142 if (!rt_sysc_membase || !rt_memc_membase)
143 panic("Failed to remap core resources");
146 static unsigned int __init rt305x_get_soc_name0(void)
148 return __raw_readl(RT305X_SYSC_BASE + SYSC_REG_CHIP_NAME0);
151 static unsigned int __init rt305x_get_soc_name1(void)
153 return __raw_readl(RT305X_SYSC_BASE + SYSC_REG_CHIP_NAME1);
156 static bool __init rt3052_soc_valid(void)
158 if (rt305x_get_soc_name0() == RT3052_CHIP_NAME0 &&
159 rt305x_get_soc_name1() == RT3052_CHIP_NAME1)
165 static bool __init rt3350_soc_valid(void)
167 if (rt305x_get_soc_name0() == RT3350_CHIP_NAME0 &&
168 rt305x_get_soc_name1() == RT3350_CHIP_NAME1)
174 static bool __init rt3352_soc_valid(void)
176 if (rt305x_get_soc_name0() == RT3352_CHIP_NAME0 &&
177 rt305x_get_soc_name1() == RT3352_CHIP_NAME1)
183 static bool __init rt5350_soc_valid(void)
185 if (rt305x_get_soc_name0() == RT5350_CHIP_NAME0 &&
186 rt305x_get_soc_name1() == RT5350_CHIP_NAME1)
192 static const char __init *rt305x_get_soc_name(struct ralink_soc_info *soc_info)
194 if (rt3052_soc_valid()) {
195 unsigned long icache_sets;
197 icache_sets = (read_c0_config1() >> 22) & 7;
198 if (icache_sets == 1) {
199 ralink_soc = RT305X_SOC_RT3050;
200 soc_info->compatible = "ralink,rt3050-soc";
203 ralink_soc = RT305X_SOC_RT3052;
204 soc_info->compatible = "ralink,rt3052-soc";
207 } else if (rt3350_soc_valid()) {
208 ralink_soc = RT305X_SOC_RT3350;
209 soc_info->compatible = "ralink,rt3350-soc";
211 } else if (rt3352_soc_valid()) {
212 ralink_soc = RT305X_SOC_RT3352;
213 soc_info->compatible = "ralink,rt3352-soc";
215 } else if (rt5350_soc_valid()) {
216 ralink_soc = RT305X_SOC_RT5350;
217 soc_info->compatible = "ralink,rt5350-soc";
220 panic("rt305x: unknown SoC, n0:%08x n1:%08x",
221 rt305x_get_soc_name0(), rt305x_get_soc_name1());
225 static unsigned int __init rt305x_get_soc_id(void)
227 return __raw_readl(RT305X_SYSC_BASE + SYSC_REG_CHIP_ID);
230 static unsigned int __init rt305x_get_soc_ver(void)
232 return (rt305x_get_soc_id() >> CHIP_ID_ID_SHIFT) & CHIP_ID_ID_MASK;
235 static unsigned int __init rt305x_get_soc_rev(void)
237 return (rt305x_get_soc_id() & CHIP_ID_REV_MASK);
240 static const char __init *rt305x_get_soc_id_name(void)
244 else if (soc_is_rt3052())
246 else if (soc_is_rt3350())
248 else if (soc_is_rt3352())
250 else if (soc_is_rt5350())
256 static int __init rt305x_soc_dev_init(void)
258 struct soc_device *soc_dev;
259 struct soc_device_attribute *soc_dev_attr;
261 soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
265 soc_dev_attr->family = "Ralink";
266 soc_dev_attr->soc_id = rt305x_get_soc_id_name();
268 soc_dev_attr->data = soc_info_ptr;
270 soc_dev = soc_device_register(soc_dev_attr);
271 if (IS_ERR(soc_dev)) {
273 return PTR_ERR(soc_dev);
278 device_initcall(rt305x_soc_dev_init);
280 void __init prom_soc_init(struct ralink_soc_info *soc_info)
282 const char *name = rt305x_get_soc_name(soc_info);
284 snprintf(soc_info->sys_type, RAMIPS_SYS_TYPE_LEN,
285 "Ralink %s id:%u rev:%u",
287 rt305x_get_soc_ver(),
288 rt305x_get_soc_rev());
290 soc_info->mem_base = RT305X_SDRAM_BASE;
291 if (soc_is_rt5350()) {
292 soc_info->mem_size = rt5350_get_mem_size();
293 } else if (soc_is_rt305x() || soc_is_rt3350()) {
294 soc_info->mem_size_min = RT305X_MEM_SIZE_MIN;
295 soc_info->mem_size_max = RT305X_MEM_SIZE_MAX;
296 } else if (soc_is_rt3352()) {
297 soc_info->mem_size_min = RT3352_MEM_SIZE_MIN;
298 soc_info->mem_size_max = RT3352_MEM_SIZE_MAX;
301 soc_info_ptr = soc_info;