Skip to content

Commit 1af29db

Browse files
jameywinerobimarko
authored andcommitted
realtek: clk: add rtl9607 clock support
This commit adds support for RTL9607C/RTL8198D clocks to the existing clk-rtl83xx driver. Setting clock rates is not supported due to lack of knowledge on this topic at the moment. Clocks for CPU1, SRAM and SPI can also be calculated but not included in this commit. Since the registers, calculations are widely different to RTL83XX it was decide to have different clk_ops for RTL960X. The code was partly based on naseef's work with some changes to integrate it into the clk-rtl83xx driver. Tested-by: Ahmed Naseef <naseefkm@gmail.com> Signed-off-by: Rustam Adilov <adilov@tutamail.com> Link: openwrt/openwrt#22080 Signed-off-by: Robert Marko <robimarko@gmail.com>
1 parent 10db6fc commit 1af29db

3 files changed

Lines changed: 127 additions & 5 deletions

File tree

target/linux/realtek/files-6.12/drivers/clk/realtek/Kconfig

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,14 @@ menuconfig COMMON_CLK_REALTEK
77
if COMMON_CLK_REALTEK
88

99
config COMMON_CLK_RTL83XX
10-
bool "Clock driver for Realtek RTL83XX"
10+
bool "Clock driver for Realtek RTL83XX and RTL960X"
1111
depends on MACH_REALTEK_RTL
1212
select SRAM
1313
help
1414
This driver adds support for the Realtek RTL83xx series basic clocks.
1515
This includes chips in the RTL838x series, such as RTL8380, RTL8381,
16-
RTL832, as well as chips from the RTL839x series, such as RTL8390,
17-
RT8391, RTL8392, RTL8393 and RTL8396.
16+
RTL832, chips from the RTL839x series, such as RTL8390, RT8391,
17+
RTL8392, RTL8393 and RTL8396 as well as chips from the RTL960X
18+
series, such as RTL9607C, RTL8198D.
1819

1920
endif

target/linux/realtek/files-6.12/drivers/clk/realtek/clk-rtl83xx.c

Lines changed: 101 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,8 @@
9292

9393
#define SOC_RTL838X 0
9494
#define SOC_RTL839X 1
95-
#define SOC_COUNT 2
95+
#define SOC_RTL960X 2
96+
#define SOC_COUNT 3
9697

9798
#define MEM_DDR1 1
9899
#define MEM_DDR2 2
@@ -264,6 +265,8 @@ static const struct rtcl_round_set rtcl_round_set[SOC_COUNT][CLK_COUNT] = {
264265
RTCL_ROUND_SET(400000000, 850000000, 25000000),
265266
RTCL_ROUND_SET(100000000, 400000000, 25000000),
266267
RTCL_ROUND_SET(50000000, 200000000, 50000000)
268+
}, {
269+
RTCL_ROUND_SET(500000000, 1200000000, 25000000)
267270
}
268271
};
269272

@@ -465,6 +468,91 @@ static long rtcl_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long
465468
return rrate;
466469
}
467470

471+
static unsigned long rtcl_960x_cpu_recalc_rate(struct clk_hw *hw,
472+
unsigned long parent_rate)
473+
{
474+
u32 ocp_pll_ctrl0, ocp_pll_ctrl3, cmu_gcr;
475+
u32 cpu_freq_sel0, en_div2_cpu0, cmu_mode, freq_div;
476+
unsigned long rate;
477+
478+
ocp_pll_ctrl0 = read_soc(RTL960X_OCP_PLL_CTRL0);
479+
ocp_pll_ctrl3 = read_soc(RTL960X_OCP_PLL_CTRL3);
480+
cmu_gcr = read_soc(RTL960X_CMU_GCR);
481+
482+
cpu_freq_sel0 = RTL960X_OCP_CTRL0_CPU_FREQ_SEL0(ocp_pll_ctrl0);
483+
en_div2_cpu0 = RTL960X_OCP_CTRL3_EN_DIV2_CPU0(ocp_pll_ctrl3);
484+
cmu_mode = RTL960X_CMU_GCR_CMU_MODE(cmu_gcr);
485+
freq_div = RTL960X_CMU_GCR_FREQ_DIV(cmu_gcr);
486+
487+
rate = ((cpu_freq_sel0 + 2) * 2 * parent_rate) >> en_div2_cpu0;
488+
if (cmu_mode != 0)
489+
rate >>= freq_div;
490+
491+
return rate;
492+
}
493+
494+
static unsigned long rtcl_960x_lxb_recalc_rate(struct clk_hw *hw,
495+
unsigned long parent_rate)
496+
{
497+
u32 phy_rg5x_pll, lx_freq_sel;
498+
unsigned long rate;
499+
500+
phy_rg5x_pll = read_sw(RTL960X_PHY_RG5X_PLL);
501+
lx_freq_sel = RTL960X_LX_FREQ_SEL(phy_rg5x_pll);
502+
503+
rate = (40 * parent_rate) / (lx_freq_sel + 5);
504+
505+
return rate;
506+
}
507+
508+
static unsigned long rtcl_960x_mem_recalc_rate(struct clk_hw *hw,
509+
unsigned long parent_rate)
510+
{
511+
u32 mem_pll_ctrl2, mem_pll_ctrl3, mem_pll_ctrl5;
512+
u32 n_code, pdiv, f_code;
513+
unsigned long rate;
514+
u64 t;
515+
516+
mem_pll_ctrl2 = read_soc(RTL960X_MEM_PLL_CTRL2);
517+
mem_pll_ctrl3 = read_soc(RTL960X_MEM_PLL_CTRL3);
518+
mem_pll_ctrl5 = read_soc(RTL960X_MEM_PLL_CTRL5);
519+
520+
pdiv = RTL960X_MEM_CTRL2_PDIV(mem_pll_ctrl2);
521+
n_code = RTL960X_MEM_CTRL3_N_CODE(mem_pll_ctrl3);
522+
f_code = RTL960X_MEM_CTRL5_F_CODE(mem_pll_ctrl5);
523+
524+
rate = (parent_rate * (n_code + 3)) / (2 * (1 << pdiv));
525+
t = parent_rate;
526+
t *= f_code;
527+
t /= 16384;
528+
rate += t;
529+
530+
return rate;
531+
}
532+
533+
static unsigned long rtcl_960x_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
534+
{
535+
struct rtcl_clk *clk = rtcl_hw_to_clk(hw);
536+
unsigned long rate;
537+
538+
if ((clk->idx >= CLK_COUNT) || (!rtcl_ccu) || (rtcl_ccu->soc >= SOC_COUNT))
539+
return 0;
540+
541+
switch (clk->idx) {
542+
case CLK_CPU:
543+
rate = rtcl_960x_cpu_recalc_rate(hw, parent_rate);
544+
break;
545+
case CLK_MEM:
546+
rate = rtcl_960x_mem_recalc_rate(hw, parent_rate);
547+
break;
548+
case CLK_LXB:
549+
rate = rtcl_960x_lxb_recalc_rate(hw, parent_rate);
550+
break;
551+
}
552+
553+
return rate;
554+
}
555+
468556
/*
469557
* Initialization functions to register the CCU and its clocks
470558
*/
@@ -474,6 +562,10 @@ static long rtcl_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long
474562
(void *)&rtcl_##SOC##_dram_start) + \
475563
(void *)PBASE; })
476564

565+
static const struct clk_ops rtcl_960x_clk_ops = {
566+
.recalc_rate = rtcl_960x_recalc_rate,
567+
};
568+
477569
static const struct clk_ops rtcl_clk_ops = {
478570
.set_rate = rtcl_set_rate,
479571
.round_rate = rtcl_round_rate,
@@ -488,6 +580,8 @@ static int rtcl_ccu_create(struct device_node *np)
488580
soc = SOC_RTL838X;
489581
else if (of_device_is_compatible(np, "realtek,rtl8390-clock"))
490582
soc = SOC_RTL839X;
583+
else if (of_device_is_compatible(np, "realtek,rtl9607-clock"))
584+
soc = SOC_RTL960X;
491585
else
492586
return -ENXIO;
493587

@@ -516,10 +610,14 @@ static int rtcl_register_clkhw(int clk_idx)
516610
rclk->hw.init = &hw_init;
517611

518612
hw_init.num_parents = 1;
519-
hw_init.ops = &rtcl_clk_ops;
520613
hw_init.parent_data = &parent_data;
521614
hw_init.name = rtcl_clk_info[clk_idx].name;
522615

616+
if (rtcl_ccu->soc == SOC_RTL960X)
617+
hw_init.ops = &rtcl_960x_clk_ops;
618+
else
619+
hw_init.ops = &rtcl_clk_ops;
620+
523621
ret = of_clk_hw_register(rtcl_ccu->np, &rclk->hw);
524622
if (ret)
525623
return ret;
@@ -719,6 +817,7 @@ static void __init rtcl_probe_early(struct device_node *np)
719817

720818
CLK_OF_DECLARE_DRIVER(rtl838x_clk, "realtek,rtl8380-clock", rtcl_probe_early);
721819
CLK_OF_DECLARE_DRIVER(rtl839x_clk, "realtek,rtl8390-clock", rtcl_probe_early);
820+
CLK_OF_DECLARE_DRIVER(rtl960x_clk, "realtek,rtl9607-clock", rtcl_probe_early);
722821

723822
/*
724823
* Late registration: Finally register as normal platform driver. At this point

target/linux/realtek/files-6.12/drivers/clk/realtek/clk-rtl83xx.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
#define RTL839X_PLL_MEM_CTRL0 (0x0048)
2727
#define RTL839X_PLL_MEM_CTRL1 (0x004c)
2828

29+
#define RTL960X_PHY_RG5X_PLL (0x1f054)
30+
2931
#define RTL_PLL_CTRL0_CMU_SEL_PREDIV(v) (((v) >> 0) & 0x3)
3032
#define RTL_PLL_CTRL0_CMU_SEL_DIV4(v) (((v) >> 2) & 0x1)
3133
#define RTL_PLL_CTRL0_CMU_NCODE_IN(v) (((v) >> 4) & 0xff)
@@ -49,6 +51,8 @@
4951
#define RTL839X_PLL_CTRL1_CMU_DIVN2_SELB(v) (((v) >> 2) & 0x1)
5052
#define RTL839X_PLL_CTRL1_CMU_DIVN3_SEL(v) (((v) >> 0) & 0x3)
5153

54+
#define RTL960X_LX_FREQ_SEL(v) ((v) & 0xf)
55+
5256
/*
5357
* Core registers (e.g. memory controller)
5458
*/
@@ -67,6 +71,24 @@
6771
#define RTL_MC_MCR_DRAMTYPE(v) ((((v) >> 28) & 0xf) + 1)
6872
#define RTL_MC_DCR_BUSWIDTH(v) (8 << (((v) >> 24) & 0xf))
6973

74+
#define RTL960X_OCP_PLL_CTRL0 (0x0200)
75+
#define RTL960X_OCP_PLL_CTRL3 (0x020c)
76+
#define RTL960X_CMU_GCR (0x0380)
77+
#define RTL960X_MEM_PLL_CTRL2 (0x023c)
78+
#define RTL960X_MEM_PLL_CTRL3 (0x0240)
79+
#define RTL960X_MEM_PLL_CTRL5 (0x0248)
80+
81+
#define RTL960X_OCP_CTRL0_CPU_FREQ_SEL0(v) (((v) >> 16) & 0x3f)
82+
83+
#define RTL960X_OCP_CTRL3_EN_DIV2_CPU0(v) (((v) >> 18) & 0x1)
84+
85+
#define RTL960X_CMU_GCR_CMU_MODE(v) ((v) & 0x3)
86+
#define RTL960X_CMU_GCR_FREQ_DIV(v) (((v) >> 4) & 0x7)
87+
88+
#define RTL960X_MEM_CTRL2_PDIV(v) (((v) >> 14) & 0x3)
89+
#define RTL960X_MEM_CTRL3_N_CODE(v) (((v) >> 24) & 0xff)
90+
#define RTL960X_MEM_CTRL5_F_CODE(v) ((v) & 0x1fff)
91+
7092
/*
7193
* Other stuff
7294
*/

0 commit comments

Comments
 (0)