// SPDX-License-Identifier: GPL-2.0-only /* * prom.c * Early intialization code for the Realtek RTL838X SoC * * based on the original BSP by * Copyright (C) 2006-2012 Tony Wu (tonywu@realtek.com) * Copyright (C) 2020 B. Koblitz * */ #include #include #include #include #include #include #include #include #include #include extern char arcs_cmdline[]; extern const char __appended_dtb; struct rtl83xx_soc_info soc_info; const void *fdt; const char *get_system_type(void) { return soc_info.name; } void __init prom_free_prom_memory(void) { } void __init device_tree_init(void) { if (!fdt_check_header(&__appended_dtb)) { fdt = &__appended_dtb; pr_info("Using appended Device Tree.\n"); } initial_boot_params = (void *)fdt; unflatten_and_copy_device_tree(); } static void __init prom_init_cmdline(void) { int argc = fw_arg0; char **argv = (char **) KSEG1ADDR(fw_arg1); int i; arcs_cmdline[0] = '\0'; for (i = 0; i < argc; i++) { char *p = (char *) KSEG1ADDR(argv[i]); if (CPHYSADDR(p) && *p) { strlcat(arcs_cmdline, p, sizeof(arcs_cmdline)); strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline)); } } pr_info("Kernel command line: %s\n", arcs_cmdline); } void __init identify_rtl9302(void) { switch (sw_r32(RTL93XX_MODEL_NAME_INFO) & 0xfffffff0) { case 0x93020810: soc_info.name = "RTL9302A 12x2.5G"; break; case 0x93021010: soc_info.name = "RTL9302B 8x2.5G"; break; case 0x93021810: soc_info.name = "RTL9302C 16x2.5G"; break; case 0x93022010: soc_info.name = "RTL9302D 24x2.5G"; break; case 0x93020800: soc_info.name = "RTL9302A"; break; case 0x93021000: soc_info.name = "RTL9302B"; break; case 0x93021800: soc_info.name = "RTL9302C"; break; case 0x93022000: soc_info.name = "RTL9302D"; break; case 0x93023001: soc_info.name = "RTL9302F"; break; default: soc_info.name = "RTL9302"; } } void __init prom_init(void) { uint32_t model; /* uart0 */ setup_8250_early_printk_port(0xb8002000, 2, 0); model = sw_r32(RTL838X_MODEL_NAME_INFO); pr_info("RTL838X model is %x\n", model); model = model >> 16 & 0xFFFF; if ((model != 0x8328) && (model != 0x8330) && (model != 0x8332) && (model != 0x8380) && (model != 0x8382)) { model = sw_r32(RTL839X_MODEL_NAME_INFO); pr_info("RTL839X model is %x\n", model); model = model >> 16 & 0xFFFF; } if ((model & 0x8390) != 0x8380 && (model & 0x8390) != 0x8390) { model = sw_r32(RTL93XX_MODEL_NAME_INFO); pr_info("RTL93XX model is %x\n", model); model = model >> 16 & 0xFFFF; } soc_info.id = model; switch (model) { case 0x8328: soc_info.name = "RTL8328"; soc_info.family = RTL8328_FAMILY_ID; break; case 0x8332: soc_info.name = "RTL8332"; soc_info.family = RTL8380_FAMILY_ID; break; case 0x8380: soc_info.name = "RTL8380"; soc_info.family = RTL8380_FAMILY_ID; break; case 0x8382: soc_info.name = "RTL8382"; soc_info.family = RTL8380_FAMILY_ID; break; case 0x8390: soc_info.name = "RTL8390"; soc_info.family = RTL8390_FAMILY_ID; break; case 0x8391: soc_info.name = "RTL8391"; soc_info.family = RTL8390_FAMILY_ID; break; case 0x8392: soc_info.name = "RTL8392"; soc_info.family = RTL8390_FAMILY_ID; break; case 0x8393: soc_info.name = "RTL8393"; soc_info.family = RTL8390_FAMILY_ID; break; case 0x9301: soc_info.name = "RTL9301"; soc_info.family = RTL9300_FAMILY_ID; break; case 0x9302: identify_rtl9302(); soc_info.family = RTL9300_FAMILY_ID; break; case 0x9313: soc_info.name = "RTL9313"; soc_info.family = RTL9310_FAMILY_ID; break; default: soc_info.name = "DEFAULT"; soc_info.family = 0; } pr_info("SoC Type: %s\n", get_system_type()); prom_init_cmdline(); }