From a31ae981c8fee48a6dea61e1935987b96f33b89c Mon Sep 17 00:00:00 2001 From: Markus Stockhausen Date: Tue, 6 Sep 2022 11:44:49 +0200 Subject: [PATCH] realtek: clock driver: enhancement for RTL930X The previous version only covered the RTL83XX series. Add all required features to support also the RTL930X devices. Signed-off-by: Markus Stockhausen [remove trailing spaces in clk-rtl930x-sram.S] Signed-off-by: Sander Vanheule --- .../files-5.10/drivers/clk/realtek/Kconfig | 5 +- .../files-5.10/drivers/clk/realtek/Makefile | 2 +- .../drivers/clk/realtek/clk-rtl83xx.c | 141 ++++++++++++++++- .../drivers/clk/realtek/clk-rtl83xx.h | 34 ++++- .../drivers/clk/realtek/clk-rtl930x-sram.S | 143 ++++++++++++++++++ 5 files changed, 312 insertions(+), 13 deletions(-) create mode 100644 target/linux/realtek/files-5.10/drivers/clk/realtek/clk-rtl930x-sram.S diff --git a/target/linux/realtek/files-5.10/drivers/clk/realtek/Kconfig b/target/linux/realtek/files-5.10/drivers/clk/realtek/Kconfig index 4cf3cd9633..0d106a6bd7 100644 --- a/target/linux/realtek/files-5.10/drivers/clk/realtek/Kconfig +++ b/target/linux/realtek/files-5.10/drivers/clk/realtek/Kconfig @@ -7,13 +7,14 @@ menuconfig COMMON_CLK_REALTEK if COMMON_CLK_REALTEK config COMMON_CLK_RTL83XX - bool "Clock driver for Realtek RTL83XX" + bool "Clock driver for Realtek RTL83XX and RTL93XX" depends on RTL83XX select SRAM help This driver adds support for the Realtek RTL83xx series basic clocks. This includes chips in the RTL838x series, such as RTL8380, RTL8381, RTL832, as well as chips from the RTL839x series, such as RTL8390, - RT8391, RTL8392, RTL8393 and RTL8396. + RT8391, RTL8392, RTL8393 and RTL8396 and chips of the RTL930X series + such as RTL9301, RTL9302 or RTL9303. endif diff --git a/target/linux/realtek/files-5.10/drivers/clk/realtek/Makefile b/target/linux/realtek/files-5.10/drivers/clk/realtek/Makefile index 7bc4ed910c..32d3046238 100644 --- a/target/linux/realtek/files-5.10/drivers/clk/realtek/Makefile +++ b/target/linux/realtek/files-5.10/drivers/clk/realtek/Makefile @@ -1,2 +1,2 @@ # SPDX-License-Identifier: GPL-2.0-only -obj-$(CONFIG_COMMON_CLK_RTL83XX) += clk-rtl83xx.o clk-rtl838x-sram.o clk-rtl839x-sram.o +obj-$(CONFIG_COMMON_CLK_RTL83XX) += clk-rtl83xx.o clk-rtl838x-sram.o clk-rtl839x-sram.o clk-rtl930x-sram.o diff --git a/target/linux/realtek/files-5.10/drivers/clk/realtek/clk-rtl83xx.c b/target/linux/realtek/files-5.10/drivers/clk/realtek/clk-rtl83xx.c index 0488517f80..88bdeacb35 100644 --- a/target/linux/realtek/files-5.10/drivers/clk/realtek/clk-rtl83xx.c +++ b/target/linux/realtek/files-5.10/drivers/clk/realtek/clk-rtl83xx.c @@ -28,7 +28,8 @@ #define RTCL_SOC838X 0 #define RTCL_SOC839X 1 -#define RTCL_SOCCNT 2 +#define RTCL_SOC930X 2 +#define RTCL_SOCCNT 3 #define RTCL_DDR1 1 #define RTCL_DDR2 2 @@ -65,6 +66,18 @@ static const int rtcl_regs[RTCL_SOCCNT][RTCL_REGCNT][CLK_COUNT] = { RTL_SW_CORE_BASE + RTL839X_PLL_MEM_CTRL1, RTL_SW_CORE_BASE + RTL839X_PLL_LXB_CTRL1 } + }, { + { + RTL_SW_CORE_BASE + RTL930X_PLL_SW_CTRL0, + RTL_SW_CORE_BASE + RTL930X_PLL_CPU_CTRL0, + RTL_SOC_BASE + RTL930X_PLL_MEM_CTRL2, + RTL_SW_CORE_BASE + RTL930X_PLL_SW_DIV_CTRL + }, { + RTL_SW_CORE_BASE + RTL930X_PLL_SW_CTRL1, + RTL_SW_CORE_BASE + RTL930X_PLL_CPU_MISC_CTRL, + RTL_SOC_BASE + RTL930X_PLL_MEM_CTRL3, + RTL_SW_CORE_BASE + RTL930X_PLL_SW_DIV_CTRL + } } }; @@ -172,6 +185,49 @@ static const struct rtcl_reg_set rtcl_839x_lxb_reg_set[] = { RTCL_REG_SET(200000000, 0x0414, 7) }; +static const struct rtcl_reg_set rtcl_930x_cpu_reg_set[] = { +/* + * TODO: The SRAM runs on 250 MHz. Depending on the the CPU speed we need + * additional magic register settings to make things work. For now remember + * that, provide all PLL values and exclude unwanted settings in DT. + */ + RTCL_REG_SET(400000000, 0x002e, 4), /* sram_oc0_pulse=1 oc0_sram_pulse=0 */ + RTCL_REG_SET(425000000, 0x0031, 4), /* ... */ + RTCL_REG_SET(450000000, 0x0034, 4), + RTCL_REG_SET(475000000, 0x0037, 4), /* sram_oc0_pulse=1 oc0_sram_pulse=0 */ + RTCL_REG_SET(500000000, 0x003a, 4), /* sram_oc0_pulse=1 oc0_sram_pulse=1 */ + RTCL_REG_SET(525000000, 0x0032, 3), /* sram_oc0_pulse=0 oc0_sram_pulse=1 */ + RTCL_REG_SET(550000000, 0x0035, 3), /* ... */ + RTCL_REG_SET(575000000, 0x0037, 3), + RTCL_REG_SET(600000000, 0x002e, 2), + RTCL_REG_SET(625000000, 0x0030, 2), + RTCL_REG_SET(650000000, 0x0032, 2), + RTCL_REG_SET(675000000, 0x0034, 2), + RTCL_REG_SET(700000000, 0x0036, 2), + RTCL_REG_SET(725000000, 0x0038, 2), + RTCL_REG_SET(750000000, 0x003a, 2), + RTCL_REG_SET(775000000, 0x003c, 2), + RTCL_REG_SET(800000000, 0x003e, 2), + RTCL_REG_SET(825000000, 0x0040, 2), + RTCL_REG_SET(850000000, 0x0042, 2), + RTCL_REG_SET(875000000, 0x0044, 2), + RTCL_REG_SET(900000000, 0x0046, 2), + RTCL_REG_SET(925000000, 0x0048, 2), + RTCL_REG_SET(950000000, 0x004a, 2), + RTCL_REG_SET(975000000, 0x004c, 2), /* sram_oc0_pulse=0 oc0_sram_pulse=1 */ + RTCL_REG_SET(1000000000, 0x004e, 2), /* sram_oc0_pulse=0 oc0_sram_pulse=2 */ + RTCL_REG_SET(1025000000, 0x0050, 2), /* ... */ +}; + +static const struct rtcl_reg_set rtcl_930x_mem_reg_set[] = { + RTCL_REG_SET(600000000, 0x0000, 0), +}; + +static const struct rtcl_reg_set rtcl_930x_lxb_reg_set[] = { + RTCL_REG_SET(153125000, 0x0c00, 0), + RTCL_REG_SET(175000000, 0x0a00, 0) +}; + struct rtcl_rtab_set { int count; const struct rtcl_reg_set *rset; @@ -191,6 +247,11 @@ static const struct rtcl_rtab_set rtcl_rtab_set[RTCL_SOCCNT][CLK_COUNT] = { RTCL_RTAB_SET(rtcl_839x_cpu_reg_set), RTCL_RTAB_SET(rtcl_839x_mem_reg_set), RTCL_RTAB_SET(rtcl_839x_lxb_reg_set) + }, { + RTCL_RTAB_SET_NONE, + RTCL_RTAB_SET(rtcl_930x_cpu_reg_set), + RTCL_RTAB_SET(rtcl_930x_mem_reg_set), + RTCL_RTAB_SET(rtcl_930x_lxb_reg_set) } }; @@ -214,6 +275,11 @@ static const struct rtcl_round_set rtcl_round_set[RTCL_SOCCNT][CLK_COUNT] = { RTCL_ROUND_SET(400000000, 850000000, 25000000), RTCL_ROUND_SET(100000000, 400000000, 25000000), RTCL_ROUND_SET(50000000, 200000000, 50000000) + }, { + RTCL_ROUND_SET_NONE, + RTCL_ROUND_SET(400000000, 975000000, 25000000), + RTCL_ROUND_SET(600000000, 600000000, 1), + RTCL_ROUND_SET(153125000, 175000000, 21875000) } }; @@ -224,12 +290,13 @@ static const int rtcl_xdiv[] = { 1, 2, 4, 2 }; * module data structures */ -#define RTCL_CLK_INFO(_idx, _name, _pname0, _pname1, _dname) \ +#define RTCL_CLK_INFO(_idx, _name, _pname0, _pname1, _pname2, _dname) \ { \ .idx = _idx, \ .name = _name, \ .parent_name[RTCL_SOC838X] = _pname0, \ .parent_name[RTCL_SOC839X] = _pname1, \ + .parent_name[RTCL_SOC930X] = _pname2, \ .display_name = _dname, \ } @@ -247,12 +314,16 @@ struct rtcl_clk { unsigned long max; unsigned long startup; }; - +/* + * PLLs on the devices are mostly pretty straight forward derived from 25 MHz + * oscillator clock. Only exception is RTL930X where LXB clock has only dividers + * and is derived from switch clock. + */ static const struct rtcl_clk_info rtcl_clk_info[CLK_COUNT] = { - RTCL_CLK_INFO(CLK_SW, "sw_clk", "xtal_clk", "xtal_clk", "SW"), - RTCL_CLK_INFO(CLK_CPU, "cpu_clk", "xtal_clk", "xtal_clk", "CPU"), - RTCL_CLK_INFO(CLK_MEM, "mem_clk", "xtal_clk", "xtal_clk", "MEM"), - RTCL_CLK_INFO(CLK_LXB, "lxb_clk", "xtal_clk", "xtal_clk", "LXB") + RTCL_CLK_INFO(CLK_SW, "sw_clk", "xtal_clk", "xtal_clk", "xtal_clk", "SW"), + RTCL_CLK_INFO(CLK_CPU, "cpu_clk", "xtal_clk", "xtal_clk", "xtal_clk", "CPU"), + RTCL_CLK_INFO(CLK_MEM, "mem_clk", "xtal_clk", "xtal_clk", "xtal_clk", "MEM"), + RTCL_CLK_INFO(CLK_LXB, "lxb_clk", "xtal_clk", "xtal_clk", "sw_clk", "LXB") }; struct rtcl_dram { @@ -296,6 +367,12 @@ extern int rtcl_839x_dram_size; extern void rtcl_839x_dram_set_rate(int clk_idx, int ctrl0, int ctrl1); static void (*rtcl_839x_sram_set_rate)(int clk_idx, int ctrl0, int ctrl1); +extern void rtcl_930x_dram_start(void); +extern int rtcl_930x_dram_size; + +extern void rtcl_930x_dram_set_rate(int clk_idx, int ctrl0, int ctrl1); +static void (*rtcl_930x_sram_set_rate)(int clk_idx, int ctrl0, int ctrl1); + /* * clock setter/getter functions */ @@ -346,6 +423,26 @@ static unsigned long rtcl_recalc_rate(struct clk_hw *hw, unsigned long parent_ra mul2 = RTL_PLL_CTRL0_CMU_SEL_DIV4(read0) ? 4 : 1; div1 = 1 << RTL_PLL_CTRL0_CMU_SEL_PREDIV(read0); break; + case RTCL_SOC_CLK(RTCL_SOC930X, CLK_CPU): + mul1 = (RTL_PLL_CTRL0_CMU_NCODE_IN(read0) + 2) * 2; + mul2 = RTL_PLL_CTRL0_CMU_SEL_DIV4(read0) ? 4 : 1; + div1 = 1 << RTL_PLL_CTRL0_CMU_SEL_PREDIV(read0); + div2 = RTL930X_PLL_MISC_CMU_DIVN2(read1) + 2; + div3 = RTL930X_PLL_CTRL0_CMU_DIVN3_CPU(read0) + 1; + break; + case RTCL_SOC_CLK(RTCL_SOC930X, CLK_SW): + mul1 = (RTL_PLL_CTRL0_CMU_NCODE_IN(read0) + 2) * 2; + mul2 = RTL_PLL_CTRL0_CMU_SEL_DIV4(read0) ? 4 : 1; + div1 = 1 << RTL_PLL_CTRL0_CMU_SEL_PREDIV(read0); + break; + case RTCL_SOC_CLK(RTCL_SOC930X, CLK_MEM): + mul1 = RTL930X_PLL_MEM_CTRL3_CMU_NCODE_IN(read1) + 2; + div1 = 1 << RTL930X_PLL_MEM_CTRL2_PREDIV(read0); + div2 = 2; + break; + case RTCL_SOC_CLK(RTCL_SOC930X, CLK_LXB): + div1 = (RTL930X_PLL_SW_DIV_CTRL_DIVN2_LXB(read0) + 2) * 2; + break; } /* * Do the math in a way that interim values stay inside 32 bit bounds @@ -384,6 +481,23 @@ static int rtcl_839x_set_rate(int clk_idx, const struct rtcl_reg_set *reg) return 0; } +static int rtcl_930x_set_rate(int clk_idx, const struct rtcl_reg_set *reg) +{ + unsigned long vpflags; + unsigned long irqflags; +/* + * Runtime of this function (including locking) + * CPU: up 19000 cycles / up to 48 us at 400 MHz (half default speed) + */ + spin_lock_irqsave(&rtcl_ccu->lock, irqflags); + vpflags = dvpe(); + rtcl_930x_dram_set_rate(clk_idx, reg->ctrl0, reg->ctrl1); + evpe(vpflags); + spin_unlock_irqrestore(&rtcl_ccu->lock, irqflags); + + return 0; +} + static int rtcl_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { int tab_idx; @@ -412,6 +526,8 @@ static int rtcl_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long pa return rtcl_838x_set_rate(clk->idx, &rtab->rset[tab_idx]); case RTCL_SOC839X: return rtcl_839x_set_rate(clk->idx, &rtab->rset[tab_idx]); + case RTCL_SOC930X: + return rtcl_930x_set_rate(clk->idx, &rtab->rset[tab_idx]); } return -ENXIO; @@ -473,6 +589,8 @@ static int rtcl_ccu_create(struct device_node *np) soc = RTCL_SOC838X; else if (of_device_is_compatible(np, "realtek,rtl8390-clock")) soc = RTCL_SOC839X; + else if (of_device_is_compatible(np, "realtek,rtl9300-clock")) + soc = RTCL_SOC930X; else return -ENXIO; @@ -603,6 +721,10 @@ int rtcl_init_sram(void) dram_start = &rtcl_839x_dram_start; dram_size = rtcl_839x_dram_size; break; + case RTCL_SOC930X: + dram_start = &rtcl_930x_dram_start; + dram_size = rtcl_930x_dram_size; + break; default: return -ENXIO; } @@ -643,6 +765,9 @@ int rtcl_init_sram(void) case RTCL_SOC839X: RTCL_SRAM_FUNC(839x, sram_pbase, set_rate); break; + case RTCL_SOC930X: + RTCL_SRAM_FUNC(930x, sram_pbase, set_rate); + break; } rtcl_ccu->sram.pmark = (int *)((void *)sram_pbase + (dram_size - 4)); @@ -714,6 +839,7 @@ static void __init rtcl_probe_early(struct device_node *np) CLK_OF_DECLARE_DRIVER(rtl838x_clk, "realtek,rtl8380-clock", rtcl_probe_early); CLK_OF_DECLARE_DRIVER(rtl839x_clk, "realtek,rtl8390-clock", rtcl_probe_early); +CLK_OF_DECLARE_DRIVER(rtl930x_clk, "realtek,rtl9300-clock", rtcl_probe_early); /* * Late registration: Finally register as normal platform driver. At this point @@ -723,6 +849,7 @@ CLK_OF_DECLARE_DRIVER(rtl839x_clk, "realtek,rtl8390-clock", rtcl_probe_early); static const struct of_device_id rtcl_dt_ids[] = { { .compatible = "realtek,rtl8380-clock" }, { .compatible = "realtek,rtl8390-clock" }, + { .compatible = "realtek,rtl9300-clock" }, {} }; diff --git a/target/linux/realtek/files-5.10/drivers/clk/realtek/clk-rtl83xx.h b/target/linux/realtek/files-5.10/drivers/clk/realtek/clk-rtl83xx.h index 4e2afee911..3e30fc248f 100644 --- a/target/linux/realtek/files-5.10/drivers/clk/realtek/clk-rtl83xx.h +++ b/target/linux/realtek/files-5.10/drivers/clk/realtek/clk-rtl83xx.h @@ -5,7 +5,7 @@ */ /* - * Switch registers (e.g. PLL) + * Switch registers (e.g. switch configuration, CPU PLL, ...) */ #define RTL_SW_CORE_BASE (0xbb000000) @@ -38,6 +38,17 @@ #define RTL839X_PLL_SW_CTRL (0x0058) #define RTL839X_PLL_SW_MISC_CTRL (0x005c) +#define RTL930X_MODEL_NAME_INFO (0x0004) +#define RTL930X_PLL_GLB_CTRL0 (0xe200) +#define RTL930X_PLL_GLB_CTRL1 (0xe200) +#define RTL930X_PLL_CPU_CTRL0 (0xe208) +#define RTL930X_PLL_CPU_CTRL1 (0xe20c) +#define RTL930X_PLL_CPU_MISC_CTRL (0xe210) +#define RTL930X_PLL_SW_CTRL0 (0xe214) +#define RTL930X_PLL_SW_CTRL1 (0xe218) +#define RTL930X_PLL_SW_MISC_CTRL (0xe21c) +#define RTL930X_PLL_SW_DIV_CTRL (0xe220) + #define RTL_PLL_CTRL0_CMU_SEL_PREDIV(v) (((v) >> 0) & 0x3) #define RTL_PLL_CTRL0_CMU_SEL_DIV4(v) (((v) >> 2) & 0x1) #define RTL_PLL_CTRL0_CMU_NCODE_IN(v) (((v) >> 4) & 0xff) @@ -64,8 +75,12 @@ #define RTL839X_PLL_CTRL1_CMU_DIVN2_SELB(v) (((v) >> 2) & 0x1) #define RTL839X_PLL_CTRL1_CMU_DIVN3_SEL(v) (((v) >> 0) & 0x3) +#define RTL930X_PLL_CTRL0_CMU_DIVN3_CPU(v) (((v) >> 25) & 0x3) +#define RTL930X_PLL_MISC_CMU_DIVN2(v) (((v) >> 4) & 0x3) +#define RTL930X_PLL_SW_DIV_CTRL_DIVN2_LXB(v) (((v) >> 9) & 0xf) + /* - * Core registers (e.g. memory controller) + * Core registers (e.g. memory controller, ...) */ #define RTL_SOC_BASE (0xB8000000) @@ -79,12 +94,25 @@ #define RTL_MC_DACCR (0x1500) #define RTL_MC_DCDR (0x1060) +#define RTL930X_SYS_STATUS (0x0044) +#define RTL930X_PLL_MEM_CTRL0 (0x0234) +#define RTL930X_PLL_MEM_CTRL1 (0x0238) +#define RTL930X_PLL_MEM_CTRL2 (0x023c) +#define RTL930X_PLL_MEM_CTRL3 (0x0240) +#define RTL930X_PLL_MEM_CTRL4 (0x0244) +#define RTL930X_PLL_MEM_CTRL5 (0x0248) +#define RTL930X_PLL_MEM_CTRL6 (0x024c) + #define RTL_MC_MCR_DRAMTYPE(v) ((((v) >> 28) & 0xf) + 1) #define RTL_MC_DCR_BUSWIDTH(v) (8 << (((v) >> 24) & 0xf)) +#define RTL930X_PLL_MEM_CTRL2_PREDIV(v) (((v) >> 14) & 0x3) +#define RTL930X_PLL_MEM_CTRL3_CMU_NCODE_IN(v) (((v) >> 24) & 0xff) + /* - * Other stuff + * SRAM stuff */ #define RTL_SRAM_MARKER (0x5eaf00d5) #define RTL_SRAM_BASE_CACHED (0x9f000000) +#define RTL_SRAM_BASE_UNCACHED (0xbf000000) diff --git a/target/linux/realtek/files-5.10/drivers/clk/realtek/clk-rtl930x-sram.S b/target/linux/realtek/files-5.10/drivers/clk/realtek/clk-rtl930x-sram.S new file mode 100644 index 0000000000..4894923f0c --- /dev/null +++ b/target/linux/realtek/files-5.10/drivers/clk/realtek/clk-rtl930x-sram.S @@ -0,0 +1,143 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Realtek RTL930X SRAM clock setters + * Copyright (C) 2022 Markus Stockhausen + */ + +#include +#include + +#include "clk-rtl83xx.h" + +#define rSW $t0 +#define rSOC $t1 +#define rMSK $t2 +#define rREG $t3 +#define rTMP1 $t4 +#define rTMP2 $t5 +#define rCP0 $t6 +#define rONE $t7 + +.set noreorder + +.globl rtcl_930x_dram_start +rtcl_930x_dram_start: + +/* + * Functions start here and should avoid access to normal memory. REMARK! Do not + * forget about stack pointer and dirty caches that might interfere. + */ + +.globl rtcl_930x_dram_set_rate +.ent rtcl_930x_dram_set_rate +rtcl_930x_dram_set_rate: + +#ifdef CONFIG_RTL930X + + /* disable MIPS 34K branch and return prediction */ + mfc0 rCP0, CP0_CONFIG, 7 + ori rTMP1, rTMP1, 0xC + mtc0 rTMP1, CP0_CONFIG, 7 + + li rONE, 1 + + /* write & read SRAM staging to clear ongoing traffic */ + li rMSK, RTL_SRAM_BASE_UNCACHED + lw rTMP1, 0(rMSK) + lw rTMP2, 4(rMSK) + sw rTMP1, 0(rMSK) + sw rTMP2, 4(rMSK) + lw rTMP1, 0(rMSK) + lw rTMP2, 4(rMSK) + + li rSW, RTL_SW_CORE_BASE + li rSOC, RTL_SOC_BASE + + /* switch CPU to LXB clock */ + ori rREG, rSOC, RTL930X_SYS_STATUS + lw rTMP1, 0(rREG) + ins rTMP1, $0, 0x2, 0x1 + sw rTMP1, 0(rREG) + + /* set new PLL values */ + ori rREG, rSW, RTL930X_PLL_CPU_CTRL0 + lw rTMP1, 0(rREG) + li rMSK, 0xfffff00f + and rTMP1, rTMP1, rMSK + sll $a1, $a1, 4 + or rTMP1, rTMP1, $a1 + sw rTMP1, 0(rREG) + lw rTMP1, 8(rREG) + li rMSK, 0xffffff8f + and rTMP1, rTMP1, rMSK + sll $a2, $a2, 4 + or rTMP1, rTMP1, $a2 + sw rTMP1, 8(rREG) + + /* use trigger depending on model */ + ori rREG, rSW, RTL930X_MODEL_NAME_INFO + lw rTMP1, 0(rREG) + ext rTMP2, rTMP1, 0x4, 0x1 + beqz rTMP2, trigger_glb_ctrl + li rTMP2, 0x3 + ext rTMP1, rTMP1, 0x0, 0x4 + bge rTMP1, rTMP2, trigger_glb_ctrl + nop +trigger_sw_div_ctrl: + ori rREG, rSW, RTL930X_PLL_SW_DIV_CTRL + lw rTMP1, 0(rREG) + ins rTMP1, $0, 17, 0x1 + sw rTMP1, 0(rREG) + ins rTMP1, rONE, 17, 0x1 + sw rTMP1, 0(rREG) + b wait_pll_ready + nop +trigger_glb_ctrl: + ori rREG, rSW, RTL930X_PLL_GLB_CTRL0 + lw rTMP1, 0(rREG) + ins rTMP1, $0, 30, 0x1 + sw rTMP1, 0(rREG) + ins rTMP1, rONE, 30, 0x1 + sw rTMP1, 0(rREG) + + ori rREG, rSW, RTL930X_PLL_GLB_CTRL0 +wait_pll_ready: + lw rTMP1, 0(rREG) + ext rTMP2, rTMP1, 0xF, 0x1 + beqz rTMP2, wait_pll_ready + nop + + /* switch CPU to PLL clock */ + ori rREG, rSOC, RTL930X_SYS_STATUS + lw rTMP1, 0(rREG) + ins rTMP1, rONE, 0x2, 0x1 + sw rTMP1, 0(rREG) + + /* stabilize clock */ + li rTMP1, 5000 +wait_clock: + bnez rTMP1, wait_clock + addiu rTMP1, rTMP1, -1 + + /* restore branch prediction */ + mtc0 rCP0, CP0_CONFIG, 7 + jr $ra + nop + +#else /* !CONFIG_RTL930X */ + + jr $ra + nop + +#endif + +.end rtcl_930x_dram_set_rate + +/* + * End marker. Do not delete. + */ + .word RTL_SRAM_MARKER +.globl rtcl_930x_dram_size +rtcl_930x_dram_size: + .word .-rtcl_930x_dram_start + -- 2.30.2