load-$(CONFIG_MIPS_GENERIC) += 0xffffffff80100000
--- a/arch/mips/generic/board-realtek.c
+++ b/arch/mips/generic/board-realtek.c
-@@ -11,6 +11,344 @@
+@@ -11,6 +11,312 @@
#include <asm/fw/fw.h>
#include <asm/machine.h>
+#define soc_r32(reg) __raw_readl(RTL_SOC_BASE + reg)
+#define soc_w32(val, reg) __raw_writel(val, RTL_SOC_BASE + reg)
+
++struct realtek_soc_data {
++ u32 model_info_reg;
++ u32 family;
++ int cpu_port;
++ void (*read_details)(u32 model);
++ void (*apply_quirks)(void);
++ void (*get_memory)(void);
++ void (*prepare_highmem)(void);
++};
++
+struct rtl83xx_soc_info soc_info;
+
+static unsigned int __init realtek_measure_hpt_freq(void)
+ };
+ of_node_put(node);
+ }
-+
++
+ return 0;
+}
+
+arch_initcall(realtek_apply_dts_quirks);
+
-+static void __init realtek_apply_early_quirks(void)
++static void __init rtl838x_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);
-+ }
++ /*
++ * 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)
+ 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;
+{
+ 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;
-+ }
++ 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)
++static void rtl931x_get_system_memory(void)
+{
-+ if (soc_info.family != RTL9300_FAMILY_ID &&
-+ soc_info.family != RTL9607_FAMILY_ID)
-+ return;
++ unsigned int dcr, bits;
++
++ dcr = soc_r32(RTL931X_DRAM_CONFIG);
++ bits = (dcr >> 12) + ((dcr >> 6) & 0x3f) + (dcr & 0x3f);
+
++ soc_info.memory_size = 1 << bits;
++}
++
++static void rtl930x_prepare_highmem(void)
++{
+ if ((soc_info.memory_size <= 256 * 1024 * 1024) ||
+ !IS_ENABLED(CONFIG_HIGHMEM))
+ return;
+ * 3 | 0x70000000 | 0x20000000-0x9fffffff | 0x10000000-0x7fffffff
+ */
+
-+ pr_info("highmem kernel on RTL930x with > 256 MB RAM, adapt SoC memory mapping\n");
++ pr_info("highmem kernel with > 256 MB RAM, adapt SoC memory mapping\n");
+
+ soc_w32(0, RTL9300_UMSAR0);
+ soc_w32(0, RTL9300_UMSAR1);
+ __sync();
+}
+
-+static void __init realtek_prom_init(void)
++static void __init realtek_prom_init(const void *match_data)
+{
-+ u32 model = realtek_read_model();
++ const struct realtek_soc_data *cfg = match_data;
++ u32 model;
++
++ if (!cfg)
++ panic("No match_data found!");
+
++ model = sw_r32(cfg->model_info_reg);
++
++ soc_info.id = model >> 16 & 0xffff;
++ soc_info.family = cfg->family;
++ soc_info.cpu_port = cfg->cpu_port;
++
++ if (cfg->apply_quirks)
++ cfg->apply_quirks();
++
++ cfg->read_details(model);
+ realtek_parse_model(model);
+ realtek_set_system_type();
-+ realtek_get_system_memory();
-+ realtek_prepare_highmem();
++ cfg->get_memory();
++
++ if (cfg->prepare_highmem)
++ cfg->prepare_highmem();
+
+ pr_info("%s SoC with %d MB\n", get_system_type(), soc_info.memory_size >> 20);
+
static __init int realtek_add_initrd(void *fdt)
{
int node, err;
-@@ -54,6 +392,8 @@ static __init const void *realtek_fixup_
- {
+@@ -55,6 +361,8 @@ static __init const void *realtek_fixup_
static unsigned char fdt_buf[16 << 10] __initdata;
int err;
-+
-+ realtek_prom_init();
++ realtek_prom_init(match_data);
++
if (fdt_check_header(fdt))
panic("Corrupt DT");
-@@ -69,11 +409,28 @@ static __init const void *realtek_fixup_
+
+@@ -68,12 +376,76 @@ static __init const void *realtek_fixup_
+
}
++static const struct realtek_soc_data rtl838x_soc __initconst = {
++ .model_info_reg = RTL838X_MODEL_NAME_INFO,
++ .family = RTL8380_FAMILY_ID,
++ .cpu_port = RTL838X_CPU_PORT,
++ .read_details = rtl838x_read_details,
++ .apply_quirks = rtl838x_apply_early_quirks,
++ .get_memory = realtek_get_system_memory,
++};
++
++static const struct realtek_soc_data rtl839x_soc __initconst = {
++ .model_info_reg = RTL839X_MODEL_NAME_INFO,
++ .family = RTL8390_FAMILY_ID,
++ .cpu_port = RTL839X_CPU_PORT,
++ .read_details = rtl839x_read_details,
++ .get_memory = realtek_get_system_memory,
++};
++
++static const struct realtek_soc_data rtl930x_soc __initconst = {
++ .model_info_reg = RTL93XX_MODEL_NAME_INFO,
++ .family = RTL9300_FAMILY_ID,
++ .cpu_port = RTL930X_CPU_PORT,
++ .read_details = rtl93xx_read_details,
++ .get_memory = realtek_get_system_memory,
++ .prepare_highmem = rtl930x_prepare_highmem,
++};
++
++static const struct realtek_soc_data rtl931x_soc __initconst = {
++ .model_info_reg = RTL93XX_MODEL_NAME_INFO,
++ .family = RTL9310_FAMILY_ID,
++ .cpu_port = RTL931X_CPU_PORT,
++ .read_details = rtl93xx_read_details,
++ .get_memory = rtl931x_get_system_memory,
++};
++
++static const struct realtek_soc_data rtl960x_soc __initconst = {
++ .model_info_reg = RTL96XX_MODEL_NAME_INFO,
++ .family = RTL9607_FAMILY_ID,
++ .cpu_port = RTL9607_CPU_PORT,
++ .read_details = rtl96xx_read_details,
++ .get_memory = realtek_get_system_memory,
++ .prepare_highmem = rtl930x_prepare_highmem,
++};
++
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" },
+- { .compatible = "realtek,rtl9302-soc" },
++ { .compatible = "realtek,rtl8380-soc", .data = &rtl838x_soc },
++ { .compatible = "realtek,rtl8381-soc", .data = &rtl838x_soc },
++ { .compatible = "realtek,rtl8382-soc", .data = &rtl838x_soc },
++ { .compatible = "realtek,rtl838x-soc", .data = &rtl838x_soc },
++ { .compatible = "realtek,rtl8391-soc", .data = &rtl839x_soc },
++ { .compatible = "realtek,rtl8392-soc", .data = &rtl839x_soc },
++ { .compatible = "realtek,rtl8393-soc", .data = &rtl839x_soc },
++ { .compatible = "realtek,rtl839x-soc", .data = &rtl839x_soc },
++ { .compatible = "realtek,rtl9301-soc", .data = &rtl930x_soc },
++ { .compatible = "realtek,rtl9302-soc", .data = &rtl930x_soc },
++ { .compatible = "realtek,rtl9302c-soc", .data = &rtl930x_soc },
++ { .compatible = "realtek,rtl9303-soc", .data = &rtl930x_soc },
++ { .compatible = "realtek,rtl930x-soc", .data = &rtl930x_soc },
++ { .compatible = "realtek,rtl9311-soc", .data = &rtl931x_soc },
++ { .compatible = "realtek,rtl9312-soc", .data = &rtl931x_soc },
++ { .compatible = "realtek,rtl9313-soc", .data = &rtl931x_soc },
++ { .compatible = "realtek,rtl931x-soc", .data = &rtl931x_soc },
++ { .compatible = "realtek,rtl8198d-soc", .data = &rtl960x_soc },
++ { .compatible = "realtek,rtl9607-soc", .data = &rtl960x_soc },
++ { .compatible = "realtek,rtl9607c-soc", .data = &rtl960x_soc },
++ { .compatible = "realtek,rtl960x-soc", .data = &rtl960x_soc },
{}
};