4747#define PDIV (val ) FIELD_GET(GENMASK(5, 0), val)
4848#define SDIV (val ) FIELD_GET(GENMASK(2, 0), val)
4949
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+
5055#define CLK_ON_R (reg ) (reg)
5156#define CLK_MON_R (reg ) (0x180 + (reg))
5257#define CLK_RST_R (reg ) (reg)
@@ -713,11 +718,43 @@ static const struct clk_ops rzg2l_cpg_pll_ops = {
713718 .recalc_rate = rzg2l_cpg_pll_clk_recalc_rate ,
714719};
715720
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+
716752static struct clk * __init
717753rzg2l_cpg_pll_clk_register (const struct cpg_core_clk * core ,
718754 struct clk * * clks ,
719755 void __iomem * base ,
720- struct rzg2l_cpg_priv * priv )
756+ struct rzg2l_cpg_priv * priv ,
757+ const struct clk_ops * ops )
721758{
722759 struct device * dev = priv -> dev ;
723760 const struct clk * parent ;
@@ -735,7 +772,7 @@ rzg2l_cpg_pll_clk_register(const struct cpg_core_clk *core,
735772
736773 parent_name = __clk_get_name (parent );
737774 init .name = core -> name ;
738- init .ops = & rzg2l_cpg_pll_ops ;
775+ init .ops = ops ;
739776 init .flags = 0 ;
740777 init .parent_names = & parent_name ;
741778 init .num_parents = 1 ;
@@ -830,8 +867,12 @@ rzg2l_cpg_register_core_clk(const struct cpg_core_clk *core,
830867 core -> mult , div );
831868 break ;
832869 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 );
835876 break ;
836877 case CLK_TYPE_SIPLL5 :
837878 clk = rzg2l_cpg_sipll5_register (core , priv -> clks , priv );
0 commit comments