> +static unsigned long rk3399_dmcclk_recalc_rate(struct clk_hw *hw, > + unsigned long parent_rate) > +{ > + struct rk3399_dmcclk *dmc = to_rk3399_dmcclk(&hw); > + u32 val; > + > + /* > + * Get parent rate since it changed in this clks set_rate op. The parent > + * rate passed into this function is cached before set_rate is called in > + * the common clk code, so we have to get it here. > + */ > + parent_rate = clk_get_rate(clk_get_parent(hw->clk)); > + > + val = readl(dmc->cru + CRU_CLKSEL6_CON); > + val = (val >> CLK_DDRC_DIV_CON_SHIFT) & CLK_DDRC_DIV_CON_MASK; > + > + return parent_rate / (val + 1); > +} > + > +/* > + * TODO: set ddr frequcney in dcf which run in ATF > + */ > +static int rk3399_dmcclk_set_rate(struct clk_hw *hw, unsigned long rate, > + unsigned long parent_rate) > +{ > + return 0; > +} Is it correct that you didn't fill this up because your Trustzone driver (SMC) is not ready yet? Then, why don't you fill that function assuming that TrustZone is not activated and add SMC call functions with if or #if after its TrustZone driver is ready? Or does your SoC mandate the usage ot TrustZone, restricting the usage of CRU_CLKSEL6_CON write? (I don't see why SoC vendors will do this..) I'll be ready to merge the RK3399 devfreq driver if you fill this up (assuming that TZ is not enabled) or add TZ driver and SMC calls. Cheers, MyungJoo ps. according to rk339_dmcclk_recalc_rate(), filling rk339_dmcclk_set_rate assuming that TZ is not enabled seems trivial.