+++ /dev/null
-#
-# Makefile for the rtl838x specific parts of the kernel
-#
-
-obj-y := setup.o prom.o
+++ /dev/null
-#
-# Realtek RTL838x SoCs
-#
-cflags-$(CONFIG_MACH_REALTEK_RTL) += -I$(srctree)/arch/mips/include/asm/mach-rtl-otto/
-load-$(CONFIG_MACH_REALTEK_RTL) += 0xffffffff80100000
+++ /dev/null
-// 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 <asm/fw/fw.h>
-#include <asm/mips-cps.h>
-#include <asm/prom.h>
-#include <asm/smp-ops.h>
-#include <linux/of.h>
-#include <linux/smp.h>
-
-#include <mach-rtl-otto.h>
-
-#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();
-}
+++ /dev/null
-// 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 <asm/bootinfo.h>
-#include <asm/prom.h>
-#include <asm/time.h>
-#include <linux/clk.h>
-#include <linux/irqchip.h>
-#include <linux/of_clk.h>
-
-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();
-}
Submitted-by: Birger Koblitz <git@birger-koblitz.de>
---
---- 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
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.
--- /dev/null
+From 5899b3e8af412d5ad6edd3c7fb7bdf4800cf52d1 Mon Sep 17 00:00:00 2001
+From: Markus Stockhausen <markus.stockhausen@gmx.de>
+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 <markus.stockhausen@gmx.de>
+---
+
+--- 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 <asm/fw/fw.h>
+ #include <asm/machine.h>
++
++#include <mach-rtl-otto.h>
++
++#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,
+ };
+++ /dev/null
-From: Markus Stockhausen <markus.stockhausen@gmx.de>
-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 <markus.stockhausen@gmx.de>
----
---- 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