47
47
#define PDIV (val ) FIELD_GET(GENMASK(5, 0), val)
48
48
#define SDIV (val ) FIELD_GET(GENMASK(2, 0), val)
49
49
50
+ #define RZG3S_DIV_P GENMASK(28, 26)
51
+ #define RZG3S_DIV_M GENMASK(25, 22)
52
+ #define RZG3S_DIV_NI GENMASK(21, 13)
53
+ #define RZG3S_DIV_NF GENMASK(12, 1)
54
+
50
55
#define CLK_ON_R (reg ) (reg)
51
56
#define CLK_MON_R (reg ) (0x180 + (reg))
52
57
#define CLK_RST_R (reg ) (reg)
@@ -713,11 +718,43 @@ static const struct clk_ops rzg2l_cpg_pll_ops = {
713
718
.recalc_rate = rzg2l_cpg_pll_clk_recalc_rate ,
714
719
};
715
720
721
+ static unsigned long rzg3s_cpg_pll_clk_recalc_rate (struct clk_hw * hw ,
722
+ unsigned long parent_rate )
723
+ {
724
+ struct pll_clk * pll_clk = to_pll (hw );
725
+ struct rzg2l_cpg_priv * priv = pll_clk -> priv ;
726
+ u32 nir , nfr , mr , pr , val ;
727
+ u64 rate ;
728
+
729
+ if (pll_clk -> type != CLK_TYPE_G3S_PLL )
730
+ return parent_rate ;
731
+
732
+ val = readl (priv -> base + GET_REG_SAMPLL_CLK1 (pll_clk -> conf ));
733
+
734
+ pr = 1 << FIELD_GET (RZG3S_DIV_P , val );
735
+ /* Hardware interprets values higher than 8 as p = 16. */
736
+ if (pr > 8 )
737
+ pr = 16 ;
738
+
739
+ mr = FIELD_GET (RZG3S_DIV_M , val ) + 1 ;
740
+ nir = FIELD_GET (RZG3S_DIV_NI , val ) + 1 ;
741
+ nfr = FIELD_GET (RZG3S_DIV_NF , val );
742
+
743
+ rate = mul_u64_u32_shr (parent_rate , 4096 * nir + nfr , 12 );
744
+
745
+ return DIV_ROUND_CLOSEST_ULL (rate , (mr * pr ));
746
+ }
747
+
748
+ static const struct clk_ops rzg3s_cpg_pll_ops = {
749
+ .recalc_rate = rzg3s_cpg_pll_clk_recalc_rate ,
750
+ };
751
+
716
752
static struct clk * __init
717
753
rzg2l_cpg_pll_clk_register (const struct cpg_core_clk * core ,
718
754
struct clk * * clks ,
719
755
void __iomem * base ,
720
- struct rzg2l_cpg_priv * priv )
756
+ struct rzg2l_cpg_priv * priv ,
757
+ const struct clk_ops * ops )
721
758
{
722
759
struct device * dev = priv -> dev ;
723
760
const struct clk * parent ;
@@ -735,7 +772,7 @@ rzg2l_cpg_pll_clk_register(const struct cpg_core_clk *core,
735
772
736
773
parent_name = __clk_get_name (parent );
737
774
init .name = core -> name ;
738
- init .ops = & rzg2l_cpg_pll_ops ;
775
+ init .ops = ops ;
739
776
init .flags = 0 ;
740
777
init .parent_names = & parent_name ;
741
778
init .num_parents = 1 ;
@@ -830,8 +867,12 @@ rzg2l_cpg_register_core_clk(const struct cpg_core_clk *core,
830
867
core -> mult , div );
831
868
break ;
832
869
case CLK_TYPE_SAM_PLL :
833
- clk = rzg2l_cpg_pll_clk_register (core , priv -> clks ,
834
- priv -> base , priv );
870
+ clk = rzg2l_cpg_pll_clk_register (core , priv -> clks , priv -> base , priv ,
871
+ & rzg2l_cpg_pll_ops );
872
+ break ;
873
+ case CLK_TYPE_G3S_PLL :
874
+ clk = rzg2l_cpg_pll_clk_register (core , priv -> clks , priv -> base , priv ,
875
+ & rzg3s_cpg_pll_ops );
835
876
break ;
836
877
case CLK_TYPE_SIPLL5 :
837
878
clk = rzg2l_cpg_sipll5_register (core , priv -> clks , priv );
0 commit comments