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+
477569static 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
720818CLK_OF_DECLARE_DRIVER (rtl838x_clk , "realtek,rtl8380-clock" , rtcl_probe_early );
721819CLK_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
0 commit comments