From: Markus Stockhausen Date: Wed, 22 Jul 2026 15:20:58 +0000 (+0200) Subject: realtek: convert to generic machine initialization X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7cc31af7bdd4;p=thirdparty%2Fopenwrt.git realtek: convert to generic machine initialization Upstream has implemented MACH_REALTEK_RTL with the MIPS generic startup framework. Until now OpenWrt disables that with a patch and instead uses dedicated legacy startup sources. Convert to upstream startup and take over the missing downstream bits from the legacy code. Due to the complex nature of this patch only focus on board-realtek.c for now. Moving other pieces around (like headers) needs to be done in a separate patch. Link: https://github.com/openwrt/openwrt/pull/24390 Signed-off-by: Markus Stockhausen --- diff --git a/target/linux/realtek/files-6.18/arch/mips/rtl-otto/Makefile b/target/linux/realtek/files-6.18/arch/mips/rtl-otto/Makefile deleted file mode 100644 index a9d1666d465..00000000000 --- a/target/linux/realtek/files-6.18/arch/mips/rtl-otto/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# -# Makefile for the rtl838x specific parts of the kernel -# - -obj-y := setup.o prom.o diff --git a/target/linux/realtek/files-6.18/arch/mips/rtl-otto/Platform b/target/linux/realtek/files-6.18/arch/mips/rtl-otto/Platform deleted file mode 100644 index 0b98b3927bd..00000000000 --- a/target/linux/realtek/files-6.18/arch/mips/rtl-otto/Platform +++ /dev/null @@ -1,5 +0,0 @@ -# -# Realtek RTL838x SoCs -# -cflags-$(CONFIG_MACH_REALTEK_RTL) += -I$(srctree)/arch/mips/include/asm/mach-rtl-otto/ -load-$(CONFIG_MACH_REALTEK_RTL) += 0xffffffff80100000 diff --git a/target/linux/realtek/files-6.18/arch/mips/rtl-otto/prom.c b/target/linux/realtek/files-6.18/arch/mips/rtl-otto/prom.c deleted file mode 100644 index 3e59253f87a..00000000000 --- a/target/linux/realtek/files-6.18/arch/mips/rtl-otto/prom.c +++ /dev/null @@ -1,415 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * prom.c - * Early initialization 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 - -#define RTL_SOC_BASE ((volatile void *) 0xB8000000) - -#define RTL83XX_DRAM_CONFIG 0x1004 - -#define RTL9300_SRAMSAR0 0x4000 -#define RTL9300_SRAMSAR1 0x4010 -#define RTL9300_SRAMSAR2 0x4020 -#define RTL9300_SRAMSAR3 0x4030 -#define RTL9300_UMSAR0 0x1300 -#define RTL9300_UMSAR1 0x1310 -#define RTL9300_UMSAR2 0x1320 -#define RTL9300_UMSAR3 0x1330 -#define RTL9300_O0DOR2 0x4220 -#define RTL9300_O0DMAR2 0x4224 - -#define RTL931X_DRAM_CONFIG 0x14304c - -#define soc_r32(reg) __raw_readl(RTL_SOC_BASE + reg) -#define soc_w32(val, reg) __raw_writel(val, RTL_SOC_BASE + reg) - -struct rtl83xx_soc_info soc_info; -EXPORT_SYMBOL(soc_info); - -const void *fdt; - -#ifdef CONFIG_MIPS_MT_SMP - -extern const struct plat_smp_ops vsmp_smp_ops; -static struct plat_smp_ops rtl_smp_ops; - -static void rtlsmp_init_secondary(void) -{ - /* - * Enable all CPU interrupts, as everything is managed by the external controller. - * TODO: Standard vsmp_init_secondary() has special treatment for Malta if external - * GIC is available. Maybe we need this too. - */ - if (mips_gic_present()) - pr_warn("%s: GIC present. Maybe interrupt enabling required.\n", __func__); - else - set_c0_status(ST0_IM); -} - -static void rtlsmp_finish(void) -{ - /* These devices are low on resources. There might be the chance that CEVT_R4K is - * not enabled in kernel build. Nevertheless the timer and interrupt 7 might be - * active by default after startup of secondary VPEs. With no registered handler - * that leads to continuous unhandeled interrupts. Disable it but keep the counter - * running so it can still be used as an entropy source. - */ - if (!IS_ENABLED(CONFIG_CEVT_R4K)) { - write_c0_status(read_c0_status() & ~CAUSEF_IP7); - write_c0_compare(read_c0_count() - 1); - } - - local_irq_enable(); -} - -static int rtlsmp_register(void) -{ - if (!cpu_has_mipsmt) - return 1; - - rtl_smp_ops = vsmp_smp_ops; - rtl_smp_ops.init_secondary = rtlsmp_init_secondary; - rtl_smp_ops.smp_finish = rtlsmp_finish; - register_smp_ops(&rtl_smp_ops); - - return 0; -} - -#else /* !CONFIG_MIPS_MT_SMP */ - -#define rtlsmp_register() (1) - -#endif - -static void __init apply_early_quirks(void) -{ - if (soc_info.family == RTL8380_FAMILY_ID) { - /* - * Open up write protected registers. SDK opens/closes this whenever needed. For - * simplicity always work with an "open" register set. - */ - sw_w32(0x3, RTL838X_INT_RW_CTRL); - /* - * Disable 4 byte address mode of flash controller. If this bit is not cleared - * the watchdog cannot reset the SoC. The SDK changes this short before restart. - * Until this quirk was implemented all RTL838x devices ran with this disabled - * because of a coding error. As no issues were detected keep the behaviour - * until more details are known. - */ - sw_w32_mask(BIT(30), 0, RTL838X_PLL_CML_CTRL); - } -} - -static void __init apply_dts_quirks(void) -{ - struct device_node *node; - - node = of_find_compatible_node(NULL, NULL, "diodes,pt7a75xx-wdt"); - if (node) { - if (soc_info.family == RTL9310_FAMILY_ID) { - pr_info("apply quirk for diodes pt7a75xx watchdog\n"); - sw_w32_mask(GENMASK(13, 12), BIT(12), RTL931X_LED_GLB_CTRL); - sw_w32_mask(0x0, BIT(8), RTL931X_MAC_L2_GLOBAL_CTRL2); - }; - of_node_put(node); - } -} - -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(); - apply_dts_quirks(); - - /* delay cpc & smp probing to allow devicetree access */ - mips_cpc_probe(); - - if (!register_cps_smp_ops()) - return; - - if (!rtlsmp_register()) - return; - - register_up_smp_ops(); -} - -const char *get_system_type(void) -{ - return soc_info.system_type; -} - -static void __init rtl838x_read_details(u32 model) -{ - u32 chip_info, ext_version, tmp; - - sw_w32(0xa << 28, RTL838X_CHIP_INFO); - - chip_info = sw_r32(RTL838X_CHIP_INFO); - soc_info.cpu = chip_info & 0xffff; - - ext_version = sw_r32(RTL838X_EXT_VERSION); - tmp = ext_version & 0x1f; - - if (tmp == 2) { - soc_info.revision = 1; - } else { - tmp = (chip_info >> 16) & 0x1f; - if (soc_info.cpu == 0x0477) { - soc_info.revision = tmp; - soc_info.testchip = true; - } else { - soc_info.revision = tmp - 1; - } - } -} - -static void __init rtl839x_read_details(u32 model) -{ - u32 chip_info; - - sw_w32(0xa << 28, RTL839X_CHIP_INFO); - - chip_info = sw_r32(RTL839X_CHIP_INFO); - soc_info.cpu = chip_info & 0xffff; - - soc_info.revision = (model >> 1) & 0x1f; - - if (!(model & 0x3e)) - soc_info.testchip = true; -} - -static void __init rtl93xx_read_details(u32 model) -{ - u32 chip_info; - - sw_w32(0xa << 16, RTL93XX_CHIP_INFO); - - chip_info = sw_r32(RTL93XX_CHIP_INFO); - soc_info.cpu = chip_info & 0xffff; - - soc_info.revision = model & 0xf; - - if (model & 0x30) - soc_info.testchip = true; -} - -static void __init rtl96xx_read_details(u32 model) -{ - u32 chip_info, chip_subtype; - - sw_w32(0xa << 28, RTL96XX_CHIP_INFO); - - chip_info = sw_r32(RTL96XX_CHIP_INFO); - soc_info.cpu = chip_info & 0xffff; - - sw_w32(0xb << 28, RTL96XX_CHIP_SUB_INFO); - - chip_subtype = sw_r32(RTL96XX_CHIP_SUB_INFO); - soc_info.subtype = chip_subtype & 0x1f; - - soc_info.revision = model & 0xf; -} - -static u32 __init read_model(void) -{ - u32 model, id; - - model = sw_r32(RTL838X_MODEL_NAME_INFO); - id = model >> 16 & 0xffff; - if ((id >= 0x8380 && id <= 0x8382) || id == 0x8330 || id == 0x8332) { - soc_info.id = id; - soc_info.family = RTL8380_FAMILY_ID; - soc_info.cpu_port = RTL838X_CPU_PORT; - apply_early_quirks(); - rtl838x_read_details(model); - return model; - } - - model = sw_r32(RTL839X_MODEL_NAME_INFO); - id = model >> 16 & 0xffff; - if ((id >= 0x8391 && id <= 0x8396) || (id >= 0x8351 && id <= 0x8353)) { - soc_info.id = id; - soc_info.family = RTL8390_FAMILY_ID; - soc_info.cpu_port = RTL839X_CPU_PORT; - apply_early_quirks(); - rtl839x_read_details(model); - return model; - } - - model = sw_r32(RTL93XX_MODEL_NAME_INFO); - id = model >> 16 & 0xffff; - if (id >= 0x9301 && id <= 0x9303) { - soc_info.id = id; - soc_info.family = RTL9300_FAMILY_ID; - soc_info.cpu_port = RTL930X_CPU_PORT; - apply_early_quirks(); - rtl93xx_read_details(model); - return model; - } else if (id >= 0x9311 && id <= 0x9313) { - soc_info.id = id; - soc_info.family = RTL9310_FAMILY_ID; - soc_info.cpu_port = RTL931X_CPU_PORT; - apply_early_quirks(); - rtl93xx_read_details(model); - return model; - } - - model = sw_r32(RTL96XX_MODEL_NAME_INFO); - id = model >> 16 & 0xffff; - if (id == 0x9607) { - soc_info.id = id; - soc_info.family = RTL9607_FAMILY_ID; - soc_info.cpu_port = RTL9607_CPU_PORT; - rtl96xx_read_details(model); - return model; - } - - return 0; -} - -static void __init parse_model(u32 model) -{ - int val; - char suffix = 0; - - val = (model >> 11) & 0x1f; - if (val > 0 && val <= 26) - suffix = 'A' + (val - 1); - - snprintf(soc_info.name, sizeof(soc_info.name), "RTL%04X%c", - soc_info.id, suffix); -} - -static void __init set_system_type(void) -{ - char revision = '?'; - char *es = ""; - char subtype[12] = ""; - - if (soc_info.revision >= 0 && soc_info.revision < 26) - revision = 'A' + soc_info.revision; - - if (soc_info.testchip) - es = " ES"; - - if (soc_info.subtype) - snprintf(subtype, sizeof(subtype), " subtype %02X", soc_info.subtype); - - snprintf(soc_info.system_type, sizeof(soc_info.system_type), - "Realtek %s%s%s rev %c (%04X)", - soc_info.name, es, subtype, revision, soc_info.cpu); -} - -static void get_system_memory(void) -{ - unsigned int dcr, bits; - - if (soc_info.family == RTL9310_FAMILY_ID) { - dcr = soc_r32(RTL931X_DRAM_CONFIG); - bits = (dcr >> 12) + ((dcr >> 6) & 0x3f) + (dcr & 0x3f); - } else { - dcr = soc_r32(RTL83XX_DRAM_CONFIG); - bits = ((dcr >> 28) & 0x3) + ((dcr >> 24) & 0x3) + - ((dcr >> 20) & 0xf) + ((dcr >> 16) & 0xf) + 20; - } - - soc_info.memory_size = 1 << bits; -} - -static void prepare_highmem(void) -{ - if (soc_info.family != RTL9300_FAMILY_ID && - soc_info.family != RTL9607_FAMILY_ID) - return; - - if ((soc_info.memory_size <= 256 * 1024 * 1024) || - !IS_ENABLED(CONFIG_HIGHMEM)) - return; - - /* - * The RTL930x provides 3 logical adressing zones that can be configured individually - * and offer an additional memory access indirection. Memory is accessed via the OCP - * bus that checks these regions and maps logical addresses to physical ones. They are - * - * zone 1: logical address 0x00000000-0x0fffffff (256 MB) - map register 0xb8004200 - * zone 2: logical address 0x10000000-0x13ffffff (64 MB) - map register 0xb8004210 - * zone 3: logical address 0x20000000-0x9fffffff (2 GB) - map register 0xb8004220 - * - * Whenever CPU accesses memory the normal MIPS translation is applied and afterwards - * the bus adds the zone mapping. E.g. a read to 0x81230000 is converted to an cached - * memory access to logical address 0x01230000. It is issued to the OCP bus and the - * mapping from zone 1 register is added. That allows for two memory topologies: - * - * Linear memory with a maximum of 320 MB: - * - * Zone | map content | logical | physical - * -------------------+-----------------------+----------------------- - * 1 | 0x00000000 | 0x00000000-0x0fffffff | 0x00000000-0x0fffffff - * 2 | 0x00000000 | 0x10000000-0x13ffffff | 0x10000000-0x13ffffff - * - * 256MB low memory plus up to 2GB high memory: - * - * Zone | map content | logical | physical - * -------------------+-----------------------+----------------------- - * 1 | 0x00000000 | 0x00000000-0x0fffffff | 0x00000000-0x0fffffff - * 3 | 0x70000000 | 0x20000000-0x9fffffff | 0x10000000-0x7fffffff - */ - - pr_info("highmem kernel on RTL930x with > 256 MB RAM, adapt SoC memory mapping\n"); - - soc_w32(0, RTL9300_UMSAR0); - soc_w32(0, RTL9300_UMSAR1); - soc_w32(0, RTL9300_UMSAR2); - soc_w32(0, RTL9300_UMSAR3); - soc_w32(0, RTL9300_SRAMSAR0); - soc_w32(0, RTL9300_SRAMSAR1); - soc_w32(0, RTL9300_SRAMSAR2); - soc_w32(0, RTL9300_SRAMSAR3); - __sync(); - - soc_w32(0x70000000, RTL9300_O0DOR2); - soc_w32(0x7fffffff, RTL9300_O0DMAR2); - __sync(); -} - -void __init prom_init(void) -{ - u32 model = read_model(); - - parse_model(model); - set_system_type(); - get_system_memory(); - - pr_info("%s SoC with %d MB\n", get_system_type(), soc_info.memory_size >> 20); - - prepare_highmem(); - - /* - * fw_arg2 is be the pointer to the environment. Some devices (e.g. HP JG924A) hand - * over other than expected kernel boot arguments. Something like 0xfffdffff looks - * suspicous. Do extra cleanup for fw_init_cmdline() to avoid a hang during boot. - */ - if (fw_arg2 >= CKSEG2) - fw_arg2 = 0; - - fw_init_cmdline(); -} diff --git a/target/linux/realtek/files-6.18/arch/mips/rtl-otto/setup.c b/target/linux/realtek/files-6.18/arch/mips/rtl-otto/setup.c deleted file mode 100644 index b02d2530ab2..00000000000 --- a/target/linux/realtek/files-6.18/arch/mips/rtl-otto/setup.c +++ /dev/null @@ -1,81 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2020 B. Koblitz - * based on the original BSP by - * Copyright (C) 2006-2012 Tony Wu (tonywu@realtek.com) - */ - -#include -#include -#include -#include -#include -#include - -void __init plat_mem_setup(void) -{ - void *dtb; - - set_io_port_base(KSEG1); - - dtb = get_fdt(); - if (!dtb) - panic("no dtb found"); - - /* Load the devicetree to let the memory appear. */ - __dt_setup_arch(dtb); -} - -static void plat_time_init_fallback(void) -{ - struct device_node *np; - u32 freq = 500000000; - - np = of_find_node_by_name(NULL, "cpus"); - if (!np) { - pr_err("Missing 'cpus' DT node, using default frequency."); - } else { - if (of_property_read_u32(np, "frequency", &freq) < 0) - pr_err("No 'frequency' property in DT, using default."); - else - pr_info("CPU frequency from device tree: %dMHz", freq / 1000000); - of_node_put(np); - } - mips_hpt_frequency = freq / 2; -} - -void __init plat_time_init(void) -{ - /* - * Initialization routine resembles generic MIPS plat_time_init() with lazy error - * handling. The final fallback is needed until all device trees use new clock syntax. - */ - struct device_node *np; - struct clk *clk; - - of_clk_init(NULL); - - mips_hpt_frequency = 0; - np = of_get_cpu_node(0, NULL); - if (!np) { - pr_err("Failed to get CPU node\n"); - } else { - clk = of_clk_get(np, 0); - if (IS_ERR(clk)) { - pr_err("Failed to get CPU clock: %ld\n", PTR_ERR(clk)); - } else { - mips_hpt_frequency = clk_get_rate(clk) / 2; - clk_put(clk); - } - } - - if (!mips_hpt_frequency) - plat_time_init_fallback(); - - timer_probe(); -} - -void __init arch_init_irq(void) -{ - irqchip_init(); -} diff --git a/target/linux/realtek/patches-6.18/300-mips-add-rtl838x-platform.patch b/target/linux/realtek/patches-6.18/300-01-enhance-realtek-platform-config.patch similarity index 77% rename from target/linux/realtek/patches-6.18/300-mips-add-rtl838x-platform.patch rename to target/linux/realtek/patches-6.18/300-01-enhance-realtek-platform-config.patch index bbaf0910435..70d4f7990e1 100644 --- a/target/linux/realtek/patches-6.18/300-mips-add-rtl838x-platform.patch +++ b/target/linux/realtek/patches-6.18/300-01-enhance-realtek-platform-config.patch @@ -9,24 +9,10 @@ configurations for the SoCs, which are introduced in addition. Submitted-by: Birger Koblitz --- ---- a/arch/mips/Kbuild.platforms -+++ b/arch/mips/Kbuild.platforms -@@ -23,6 +23,7 @@ platform-$(CONFIG_MACH_NINTENDO64) += n6 - platform-$(CONFIG_PIC32MZDA) += pic32/ - platform-$(CONFIG_RALINK) += ralink/ - platform-$(CONFIG_MIKROTIK_RB532) += rb532/ -+platform-$(CONFIG_MACH_REALTEK_RTL) += rtl-otto/ - platform-$(CONFIG_SGI_IP22) += sgi-ip22/ - platform-$(CONFIG_SGI_IP27) += sgi-ip27/ - platform-$(CONFIG_SGI_IP28) += sgi-ip22/ --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig -@@ -696,23 +696,24 @@ config RALINK - - config MACH_REALTEK_RTL - bool "Realtek RTL838x/RTL839x based machines" -- select MIPS_GENERIC -- select MACH_GENERIC_CORE +@@ -700,19 +700,22 @@ config MACH_REALTEK_RTL + select MACH_GENERIC_CORE select DMA_NONCOHERENT select IRQ_MIPS_CPU - select CSRC_R4K @@ -52,7 +38,7 @@ Submitted-by: Birger Koblitz config SGI_IP22 bool "SGI IP22 (Indy/Indigo2)" -@@ -1056,6 +1057,37 @@ config FIT_IMAGE_FDT_EPM5 +@@ -1056,6 +1059,37 @@ config FIT_IMAGE_FDT_EPM5 from Mobileye in the FIT kernel image. This requires u-boot on the platform. diff --git a/target/linux/realtek/patches-6.18/300-02-enhance-realtek-board-setup.patch b/target/linux/realtek/patches-6.18/300-02-enhance-realtek-board-setup.patch new file mode 100644 index 00000000000..3fd3d1393da --- /dev/null +++ b/target/linux/realtek/patches-6.18/300-02-enhance-realtek-board-setup.patch @@ -0,0 +1,406 @@ +From 5899b3e8af412d5ad6edd3c7fb7bdf4800cf52d1 Mon Sep 17 00:00:00 2001 +From: Markus Stockhausen +Date: Mon, 18 May 2026 18:07:21 +0200 +Subject: [PATCH] realtek: enhance board setup + +The Realtek targets need more than the upstream available code +for proper initialization. Add what is needed. + +Signed-off-by: Markus Stockhausen +--- + +--- a/arch/mips/generic/Platform ++++ b/arch/mips/generic/Platform +@@ -10,6 +10,7 @@ + + # Note: order matters, keep the asm/mach-generic include last. + cflags-$(CONFIG_MACH_INGENIC_SOC) += -I$(srctree)/arch/mips/include/asm/mach-ingenic ++cflags-$(CONFIG_MACH_REALTEK_RTL) += -I$(srctree)/arch/mips/include/asm/mach-rtl-otto + cflags-$(CONFIG_MIPS_GENERIC) += -I$(srctree)/arch/mips/include/asm/mach-generic + + load-$(CONFIG_MIPS_GENERIC) += 0xffffffff80100000 +--- a/arch/mips/generic/board-realtek.c ++++ b/arch/mips/generic/board-realtek.c +@@ -10,6 +10,344 @@ + + #include + #include ++ ++#include ++ ++#define RTL_SOC_BASE ((volatile void *) 0xB8000000) ++ ++#define RTL83XX_DRAM_CONFIG 0x1004 ++ ++#define RTL9300_SRAMSAR0 0x4000 ++#define RTL9300_SRAMSAR1 0x4010 ++#define RTL9300_SRAMSAR2 0x4020 ++#define RTL9300_SRAMSAR3 0x4030 ++#define RTL9300_UMSAR0 0x1300 ++#define RTL9300_UMSAR1 0x1310 ++#define RTL9300_UMSAR2 0x1320 ++#define RTL9300_UMSAR3 0x1330 ++#define RTL9300_O0DOR2 0x4220 ++#define RTL9300_O0DMAR2 0x4224 ++ ++#define RTL931X_DRAM_CONFIG 0x14304c ++ ++#define soc_r32(reg) __raw_readl(RTL_SOC_BASE + reg) ++#define soc_w32(val, reg) __raw_writel(val, RTL_SOC_BASE + reg) ++ ++struct rtl83xx_soc_info soc_info; ++ ++static unsigned int __init realtek_measure_hpt_freq(void) ++{ ++ struct device_node *np; ++ u32 freq = 500000000; ++ ++ np = of_find_node_by_name(NULL, "cpus"); ++ if (!np) { ++ pr_err("Missing 'cpus' DT node, using default frequency."); ++ } else { ++ if (of_property_read_u32(np, "frequency", &freq) < 0) ++ pr_err("No 'frequency' property in DT, using default."); ++ else ++ pr_info("CPU frequency from device tree: %dMHz", freq / 1000000); ++ of_node_put(np); ++ } ++ ++ return freq / 2; ++} ++ ++static int __init realtek_apply_dts_quirks(void) ++{ ++ struct device_node *node; ++ ++ node = of_find_compatible_node(NULL, NULL, "diodes,pt7a75xx-wdt"); ++ if (node) { ++ if (soc_info.family == RTL9310_FAMILY_ID) { ++ pr_info("apply quirk for diodes pt7a75xx watchdog\n"); ++ sw_w32_mask(GENMASK(13, 12), BIT(12), RTL931X_LED_GLB_CTRL); ++ sw_w32_mask(0x0, BIT(8), RTL931X_MAC_L2_GLOBAL_CTRL2); ++ }; ++ of_node_put(node); ++ } ++ ++ return 0; ++} ++ ++arch_initcall(realtek_apply_dts_quirks); ++ ++static void __init realtek_apply_early_quirks(void) ++{ ++ if (soc_info.family == RTL8380_FAMILY_ID) { ++ /* ++ * Open up write protected registers. SDK opens/closes this whenever needed. For ++ * simplicity always work with an "open" register set. ++ */ ++ sw_w32(0x3, RTL838X_INT_RW_CTRL); ++ /* ++ * Disable 4 byte address mode of flash controller. If this bit is not cleared ++ * the watchdog cannot reset the SoC. The SDK changes this short before restart. ++ * Until this quirk was implemented all RTL838x devices ran with this disabled ++ * because of a coding error. As no issues were detected keep the behaviour ++ * until more details are known. ++ */ ++ sw_w32_mask(BIT(30), 0, RTL838X_PLL_CML_CTRL); ++ } ++} ++ ++static void __init rtl838x_read_details(u32 model) ++{ ++ u32 chip_info, ext_version, tmp; ++ ++ sw_w32(0xa << 28, RTL838X_CHIP_INFO); ++ ++ chip_info = sw_r32(RTL838X_CHIP_INFO); ++ soc_info.cpu = chip_info & 0xffff; ++ ++ ext_version = sw_r32(RTL838X_EXT_VERSION); ++ tmp = ext_version & 0x1f; ++ ++ if (tmp == 2) { ++ soc_info.revision = 1; ++ } else { ++ tmp = (chip_info >> 16) & 0x1f; ++ if (soc_info.cpu == 0x0477) { ++ soc_info.revision = tmp; ++ soc_info.testchip = true; ++ } else { ++ soc_info.revision = tmp - 1; ++ } ++ } ++} ++ ++static void __init rtl839x_read_details(u32 model) ++{ ++ u32 chip_info; ++ ++ sw_w32(0xa << 28, RTL839X_CHIP_INFO); ++ ++ chip_info = sw_r32(RTL839X_CHIP_INFO); ++ soc_info.cpu = chip_info & 0xffff; ++ ++ soc_info.revision = (model >> 1) & 0x1f; ++ ++ if (!(model & 0x3e)) ++ soc_info.testchip = true; ++} ++ ++static void __init rtl93xx_read_details(u32 model) ++{ ++ u32 chip_info; ++ ++ sw_w32(0xa << 16, RTL93XX_CHIP_INFO); ++ ++ chip_info = sw_r32(RTL93XX_CHIP_INFO); ++ soc_info.cpu = chip_info & 0xffff; ++ ++ soc_info.revision = model & 0xf; ++ ++ if (model & 0x30) ++ soc_info.testchip = true; ++} ++ ++static void __init rtl96xx_read_details(u32 model) ++{ ++ u32 chip_info, chip_subtype; ++ ++ sw_w32(0xa << 28, RTL96XX_CHIP_INFO); ++ ++ chip_info = sw_r32(RTL96XX_CHIP_INFO); ++ soc_info.cpu = chip_info & 0xffff; ++ ++ sw_w32(0xb << 28, RTL96XX_CHIP_SUB_INFO); ++ ++ chip_subtype = sw_r32(RTL96XX_CHIP_SUB_INFO); ++ soc_info.subtype = chip_subtype & 0x1f; ++ ++ soc_info.revision = model & 0xf; ++} ++ ++static u32 __init realtek_read_model(void) ++{ ++ u32 model, id; ++ ++ model = sw_r32(RTL838X_MODEL_NAME_INFO); ++ id = model >> 16 & 0xffff; ++ if ((id >= 0x8380 && id <= 0x8382) || id == 0x8330 || id == 0x8332) { ++ soc_info.id = id; ++ soc_info.family = RTL8380_FAMILY_ID; ++ soc_info.cpu_port = RTL838X_CPU_PORT; ++ realtek_apply_early_quirks(); ++ rtl838x_read_details(model); ++ return model; ++ } ++ ++ model = sw_r32(RTL839X_MODEL_NAME_INFO); ++ id = model >> 16 & 0xffff; ++ if ((id >= 0x8391 && id <= 0x8396) || (id >= 0x8351 && id <= 0x8353)) { ++ soc_info.id = id; ++ soc_info.family = RTL8390_FAMILY_ID; ++ soc_info.cpu_port = RTL839X_CPU_PORT; ++ realtek_apply_early_quirks(); ++ rtl839x_read_details(model); ++ return model; ++ } ++ ++ model = sw_r32(RTL93XX_MODEL_NAME_INFO); ++ id = model >> 16 & 0xffff; ++ if (id >= 0x9301 && id <= 0x9303) { ++ soc_info.id = id; ++ soc_info.family = RTL9300_FAMILY_ID; ++ soc_info.cpu_port = RTL930X_CPU_PORT; ++ realtek_apply_early_quirks(); ++ rtl93xx_read_details(model); ++ return model; ++ } else if (id >= 0x9311 && id <= 0x9313) { ++ soc_info.id = id; ++ soc_info.family = RTL9310_FAMILY_ID; ++ soc_info.cpu_port = RTL931X_CPU_PORT; ++ realtek_apply_early_quirks(); ++ rtl93xx_read_details(model); ++ return model; ++ } ++ ++ model = sw_r32(RTL96XX_MODEL_NAME_INFO); ++ id = model >> 16 & 0xffff; ++ if (id == 0x9607) { ++ soc_info.id = id; ++ soc_info.family = RTL9607_FAMILY_ID; ++ soc_info.cpu_port = RTL9607_CPU_PORT; ++ rtl96xx_read_details(model); ++ return model; ++ } ++ ++ return 0; ++} ++ ++static void __init realtek_parse_model(u32 model) ++{ ++ int val; ++ char suffix = 0; ++ ++ val = (model >> 11) & 0x1f; ++ if (val > 0 && val <= 26) ++ suffix = 'A' + (val - 1); ++ ++ snprintf(soc_info.name, sizeof(soc_info.name), "RTL%04X%c", ++ soc_info.id, suffix); ++} ++ ++static void __init realtek_set_system_type(void) ++{ ++ char revision = '?'; ++ char *es = ""; ++ char subtype[12] = ""; ++ ++ if (soc_info.revision >= 0 && soc_info.revision < 26) ++ revision = 'A' + soc_info.revision; ++ ++ if (soc_info.testchip) ++ es = " ES"; ++ ++ if (soc_info.subtype) ++ snprintf(subtype, sizeof(subtype), " subtype %02X", soc_info.subtype); ++ ++ snprintf(soc_info.system_type, sizeof(soc_info.system_type), ++ "Realtek %s%s%s rev %c (%04X)", ++ soc_info.name, es, subtype, revision, soc_info.cpu); ++ ++ system_type = soc_info.system_type; ++} ++ ++static void realtek_get_system_memory(void) ++{ ++ unsigned int dcr, bits; ++ ++ if (soc_info.family == RTL9310_FAMILY_ID) { ++ dcr = soc_r32(RTL931X_DRAM_CONFIG); ++ bits = (dcr >> 12) + ((dcr >> 6) & 0x3f) + (dcr & 0x3f); ++ } else { ++ dcr = soc_r32(RTL83XX_DRAM_CONFIG); ++ bits = ((dcr >> 28) & 0x3) + ((dcr >> 24) & 0x3) + ++ ((dcr >> 20) & 0xf) + ((dcr >> 16) & 0xf) + 20; ++ } ++ ++ soc_info.memory_size = 1 << bits; ++} ++ ++static void realtek_prepare_highmem(void) ++{ ++ if (soc_info.family != RTL9300_FAMILY_ID && ++ soc_info.family != RTL9607_FAMILY_ID) ++ return; ++ ++ if ((soc_info.memory_size <= 256 * 1024 * 1024) || ++ !IS_ENABLED(CONFIG_HIGHMEM)) ++ return; ++ ++ /* ++ * The RTL930x provides 3 logical adressing zones that can be configured individually ++ * and offer an additional memory access indirection. Memory is accessed via the OCP ++ * bus that checks these regions and maps logical addresses to physical ones. They are ++ * ++ * zone 1: logical address 0x00000000-0x0fffffff (256 MB) - map register 0xb8004200 ++ * zone 2: logical address 0x10000000-0x13ffffff (64 MB) - map register 0xb8004210 ++ * zone 3: logical address 0x20000000-0x9fffffff (2 GB) - map register 0xb8004220 ++ * ++ * Whenever CPU accesses memory the normal MIPS translation is applied and afterwards ++ * the bus adds the zone mapping. E.g. a read to 0x81230000 is converted to an cached ++ * memory access to logical address 0x01230000. It is issued to the OCP bus and the ++ * mapping from zone 1 register is added. That allows for two memory topologies: ++ * ++ * Linear memory with a maximum of 320 MB: ++ * ++ * Zone | map content | logical | physical ++ * -------------------+-----------------------+----------------------- ++ * 1 | 0x00000000 | 0x00000000-0x0fffffff | 0x00000000-0x0fffffff ++ * 2 | 0x00000000 | 0x10000000-0x13ffffff | 0x10000000-0x13ffffff ++ * ++ * 256MB low memory plus up to 2GB high memory: ++ * ++ * Zone | map content | logical | physical ++ * -------------------+-----------------------+----------------------- ++ * 1 | 0x00000000 | 0x00000000-0x0fffffff | 0x00000000-0x0fffffff ++ * 3 | 0x70000000 | 0x20000000-0x9fffffff | 0x10000000-0x7fffffff ++ */ ++ ++ pr_info("highmem kernel on RTL930x with > 256 MB RAM, adapt SoC memory mapping\n"); ++ ++ soc_w32(0, RTL9300_UMSAR0); ++ soc_w32(0, RTL9300_UMSAR1); ++ soc_w32(0, RTL9300_UMSAR2); ++ soc_w32(0, RTL9300_UMSAR3); ++ soc_w32(0, RTL9300_SRAMSAR0); ++ soc_w32(0, RTL9300_SRAMSAR1); ++ soc_w32(0, RTL9300_SRAMSAR2); ++ soc_w32(0, RTL9300_SRAMSAR3); ++ __sync(); ++ ++ soc_w32(0x70000000, RTL9300_O0DOR2); ++ soc_w32(0x7fffffff, RTL9300_O0DMAR2); ++ __sync(); ++} ++ ++static void __init realtek_prom_init(void) ++{ ++ u32 model = realtek_read_model(); ++ ++ realtek_parse_model(model); ++ realtek_set_system_type(); ++ realtek_get_system_memory(); ++ realtek_prepare_highmem(); ++ ++ pr_info("%s SoC with %d MB\n", get_system_type(), soc_info.memory_size >> 20); ++ ++ /* ++ * fw_arg2 is the pointer to the environment. Some devices (e.g. HP JG924A) hand ++ * over other than expected kernel boot arguments. Something like 0xfffdffff looks ++ * suspicous. Do extra cleanup for fw_init_cmdline() to avoid a hang during boot. ++ */ ++ if (fw_arg2 >= CKSEG2) ++ fw_arg2 = 0; ++} ++ + + static __init int realtek_add_initrd(void *fdt) + { +@@ -54,6 +393,8 @@ static __init const void *realtek_fixup_ + { + static unsigned char fdt_buf[16 << 10] __initdata; + int err; ++ ++ realtek_prom_init(); + + if (fdt_check_header(fdt)) + panic("Corrupt DT"); +@@ -69,11 +410,28 @@ static __init const void *realtek_fixup_ + } + + static const struct of_device_id realtek_of_match[] __initconst = { ++ { .compatible = "realtek,rtl8380-soc" }, ++ { .compatible = "realtek,rtl8381-soc" }, ++ { .compatible = "realtek,rtl8382-soc" }, ++ { .compatible = "realtek,rtl838x-soc" }, ++ { .compatible = "realtek,rtl8391-soc" }, ++ { .compatible = "realtek,rtl8392-soc" }, ++ { .compatible = "realtek,rtl8393-soc" }, ++ { .compatible = "realtek,rtl839x-soc" }, ++ { .compatible = "realtek,rtl9301-soc" }, + { .compatible = "realtek,rtl9302-soc" }, ++ { .compatible = "realtek,rtl9302c-soc" }, ++ { .compatible = "realtek,rtl9303-soc" }, ++ { .compatible = "realtek,rtl930x-soc" }, ++ { .compatible = "realtek,rtl9311-soc" }, ++ { .compatible = "realtek,rtl9312-soc" }, ++ { .compatible = "realtek,rtl9313-soc" }, ++ { .compatible = "realtek,rtl931x-soc" }, + {} + }; + + MIPS_MACHINE(realtek) = { + .matches = realtek_of_match, + .fixup_fdt = realtek_fixup_fdt, ++ .measure_hpt_freq = realtek_measure_hpt_freq, + }; diff --git a/target/linux/realtek/patches-6.18/306-disable-upstream-realtek-board.patch b/target/linux/realtek/patches-6.18/306-disable-upstream-realtek-board.patch deleted file mode 100644 index 62dd64223e2..00000000000 --- a/target/linux/realtek/patches-6.18/306-disable-upstream-realtek-board.patch +++ /dev/null @@ -1,16 +0,0 @@ -From: Markus Stockhausen -Subject: [PATCH] realtek: disable upstream Realtek board - -Upstream now has integrated the Realtek target into the generic -MIPS initialization. For now disable the board compilation. - -Submitted-by: Markus Stockhausen ---- ---- a/arch/mips/generic/Makefile -+++ b/arch/mips/generic/Makefile -@@ -13,4 +13,4 @@ obj-$(CONFIG_LEGACY_BOARD_SEAD3) += boar - obj-$(CONFIG_LEGACY_BOARD_OCELOT) += board-ocelot.o - obj-$(CONFIG_MACH_INGENIC) += board-ingenic.o - obj-$(CONFIG_VIRT_BOARD_RANCHU) += board-ranchu.o --obj-$(CONFIG_MACH_REALTEK_RTL) += board-realtek.o -+# obj-$(CONFIG_MACH_REALTEK_RTL) += board-realtek.o