Message ID | 20160322153332.GA1042@localhost.localdomain (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Tero, * Ladislav Michl <ladis@linux-mips.org> [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@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On 26/04/16 19:19, Tony Lindgren wrote: > Tero, > > * Ladislav Michl <ladis@linux-mips.org> [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. Sorry I think this got buried in my inbox... Yea I think the last inline patch looks reasonably good to me. Added a couple of comments below, but once those are fixed (+ any checkpatch issues), it should be good to go. I haven't tested the patch itself though as I don't have local access to omap36xx hw. > > 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, }, >> + }; I would avoid local/mixed definition like this. >> + >> + 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); Debugging info should be dropped. Thanks, Tero. >> + >> + 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@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
--- 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);