Tero, * Ladislav Michl <ladis@xxxxxxxxxxxxxx> [160322 08:34]: > On Tue, Mar 22, 2016 at 08:57:13AM +0200, Tero Kristo wrote: > > You can drop the checks against 120MHz inside round_rate then. > > What if omap3630_dpll_round_rate is called directly as ops->round_rate()? What's the status of this fix? Would be good to have this out of the way. Regards, Tony > --- drivers/clk/ti/dpll3xxx.c.orig 2016-03-21 22:55:29.515746383 +0100 > +++ drivers/clk/ti/dpll3xxx.c 2016-03-22 01:43:54.004896607 +0100 > @@ -534,6 +534,33 @@ > return 0; > } > > +int omap3630_noncore_dpll_determine_rate(struct clk_hw *hw, > + struct clk_rate_request *req) > +{ > + struct clk_hw_omap *clk = to_clk_hw_omap(hw); > + struct dpll_data *dd; > + > + if (!req->rate) > + return -EINVAL; > + > + dd = clk->dpll_data; > + if (!dd) > + return -EINVAL; > + > + if (clk_get_rate(dd->clk_bypass) == req->rate && > + (dd->modes & (1 << DPLL_LOW_POWER_BYPASS))) { > + req->best_parent_hw = __clk_get_hw(dd->clk_bypass); > + } else { > + req->rate = omap3630_dpll_round_rate(hw, req->rate, > + &req->best_parent_rate); > + req->best_parent_hw = __clk_get_hw(dd->clk_ref); > + } > + > + req->best_parent_rate = req->rate; > + > + return 0; > +} > + > /** > * omap3_noncore_dpll_set_parent - set parent for a DPLL clock > * @hw: pointer to the clock to set parent for > --- drivers/clk/ti/clkt_dpll.c.orig 2016-03-22 01:59:21.724896607 +0100 > +++ drivers/clk/ti/clkt_dpll.c 2016-03-22 16:23:22.804383248 +0100 > @@ -368,3 +368,52 @@ > > return dd->last_rounded_rate; > } > + > +/** > + * omap3630_dpll_round_rate - round a target rate for an OMAP DPLL > + * @clk: struct clk * for a DPLL > + * @target_rate: desired DPLL clock rate > + * > + * DM3730 errata (sprz319e), advisory 2.1 > + */ > +long omap3630_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate, > + unsigned long *parent_rate) > +{ > + unsigned int i, m, n; > + unsigned long r; > + struct dpll_data *dd; > + > + static const struct { > + unsigned long rate; > + unsigned int m; > + unsigned int n; /* value of the register is n - 1 */ > + } dpll5_advisory[] = { > + { 12000000, 80, 0 + 1, }, > + { 19200000, 50, 0 + 1, }, > + { 38400000, 25, 0 + 1, }, > + { 13000000, 443, 5 + 1, }, > + { 26000000, 443, 11 + 1, }, > + { 26000000, 480, 12 + 1, }, > + }; > + > + if (target_rate == 120000000) > + for (i = 0; i < ARRAY_SIZE(dpll5_advisory); i++) > + if (*parent_rate == dpll5_advisory[i].rate) { > + m = dpll5_advisory[i].m; > + n = dpll5_advisory[i].n; > + r = _dpll_compute_new_rate(*parent_rate, m, n); > + r /= 8; > + > + printk("clock %s: m=%d, n=%d, rate=%lu\n", > + clk_hw_get_name(hw), m, n, r); > + > + dd = to_clk_hw_omap(hw)->dpll_data; > + dd->last_rounded_m = m; > + dd->last_rounded_n = n; > + dd->last_rounded_rate = r; > + > + return r; > + } > + > + return omap2_dpll_round_rate(hw, target_rate, parent_rate); > +} > --- drivers/clk/ti/dpll.c.orig 2016-03-21 22:53:16.379746383 +0100 > +++ drivers/clk/ti/dpll.c 2016-03-22 16:27:08.284383248 +0100 > @@ -114,6 +114,18 @@ > .round_rate = &omap2_dpll_round_rate, > }; > > +static const struct clk_ops omap3630_dpll_ck_ops = { > + .enable = &omap3_noncore_dpll_enable, > + .disable = &omap3_noncore_dpll_disable, > + .get_parent = &omap2_init_dpll_parent, > + .recalc_rate = &omap3_dpll_recalc, > + .set_rate = &omap3_noncore_dpll_set_rate, > + .set_parent = &omap3_noncore_dpll_set_parent, > + .set_rate_and_parent = &omap3_noncore_dpll_set_rate_and_parent, > + .determine_rate = &omap3630_noncore_dpll_determine_rate, > + .round_rate = &omap3630_dpll_round_rate, > +}; > + > static const struct clk_ops omap3_dpll_per_ck_ops = { > .enable = &omap3_noncore_dpll_enable, > .disable = &omap3_noncore_dpll_disable, > @@ -466,6 +478,26 @@ > CLK_OF_DECLARE(ti_omap3_dpll_clock, "ti,omap3-dpll-clock", > of_ti_omap3_dpll_setup); > > +static void __init of_ti_omap3630_dpll5_setup(struct device_node *node) > +{ > + const struct dpll_data dd = { > + .idlest_mask = 0x1, > + .enable_mask = 0x7, > + .autoidle_mask = 0x7, > + .mult_mask = 0x7ff << 8, > + .div1_mask = 0x7f, > + .max_multiplier = 2047, > + .max_divider = 128, > + .min_divider = 1, > + .freqsel_mask = 0xf0, > + .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), > + }; > + > + of_ti_dpll_setup(node, &omap3630_dpll_ck_ops, &dd); > +} > +CLK_OF_DECLARE(ti_omap3630_dpll5_clock, "ti,omap3630-dpll5-clock", > + of_ti_omap3630_dpll5_setup); > + > static void __init of_ti_omap3_core_dpll_setup(struct device_node *node) > { > const struct dpll_data dd = { > --- drivers/clk/ti/clock.h.orig 2016-03-21 22:55:09.011746383 +0100 > +++ drivers/clk/ti/clock.h 2016-03-22 01:42:45.840896607 +0100 > @@ -252,8 +252,12 @@ > u8 index); > int omap3_noncore_dpll_determine_rate(struct clk_hw *hw, > struct clk_rate_request *req); > +int omap3630_noncore_dpll_determine_rate(struct clk_hw *hw, > + struct clk_rate_request *req); > long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate, > unsigned long *parent_rate); > +long omap3630_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate, > + unsigned long *parent_rate); > unsigned long omap3_clkoutx2_recalc(struct clk_hw *hw, > unsigned long parent_rate); > > > -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html