lkml.org 
[lkml]   [2015]   [Nov]   [18]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    From
    SubjectRe: [PATCH v2 2/3] clk: bcm2835: Support for clock parent selection
    Date
    Remi Pommarel <repk@triplefau.lt> writes:

    > Some bcm2835 clocks used by hardware (like "PWM" or "H264") can have multiple
    > parent clocks. These clocks divide the rate of a parent which can be selected by
    > setting the proper bits in the clock control register.
    >
    > Previously all these parents where handled by a mux clock. But a mux clock
    > cannot be used because updating clock control register to select parent needs a
    > password to be xor'd with the parent index.
    >
    > This patch get rid of mux clock and make these clocks handle their own parent,
    > allowing them to select the one to use.
    >
    > Signed-off-by: Remi Pommarel <repk@triplefau.lt>
    > ---
    > drivers/clk/bcm/clk-bcm2835.c | 122 ++++++++++++++++++++++++++----------------
    > 1 file changed, 77 insertions(+), 45 deletions(-)
    >
    > diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
    > index 1237716..2b01a53 100644
    > --- a/drivers/clk/bcm/clk-bcm2835.c
    > +++ b/drivers/clk/bcm/clk-bcm2835.c
    > @@ -1198,16 +1198,6 @@ static long bcm2835_clock_rate_from_divisor(struct bcm2835_clock *clock,
    > return temp;
    > }
    >
    > -static long bcm2835_clock_round_rate(struct clk_hw *hw,
    > - unsigned long rate,
    > - unsigned long *parent_rate)
    > -{
    > - struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
    > - u32 div = bcm2835_clock_choose_div(hw, rate, *parent_rate);
    > -
    > - return bcm2835_clock_rate_from_divisor(clock, *parent_rate, div);
    > -}
    > -
    > static unsigned long bcm2835_clock_get_rate(struct clk_hw *hw,
    > unsigned long parent_rate)
    > {
    > @@ -1279,13 +1269,75 @@ static int bcm2835_clock_set_rate(struct clk_hw *hw,
    > return 0;
    > }
    >
    > +static int bcm2835_clock_determine_rate(struct clk_hw *hw,
    > + struct clk_rate_request *req)
    > +{
    > + struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
    > + struct clk_hw *parent, *best_parent = NULL;
    > + struct clk_rate_request parent_req;
    > + unsigned long rate, best_rate = 0;
    > + unsigned long prate, best_prate = 0;
    > + size_t i;
    > + u32 div;
    > +
    > + /*
    > + * Select parent clock that results in the closest but lower rate
    > + */
    > + for (i = 0; i < clk_hw_get_num_parents(hw); ++i) {
    > + parent = clk_hw_get_parent_by_index(hw, i);
    > + if (!parent)
    > + continue;
    > + parent_req = *req;

    parent_req appears dead, so it should be removed.

    > + prate = clk_hw_get_rate(parent);
    > + div = bcm2835_clock_choose_div(hw, req->rate, prate);
    > + rate = bcm2835_clock_rate_from_divisor(clock, prate, div);
    > + if (rate > best_rate && rate <= req->rate) {
    > + best_parent = parent;
    > + best_prate = prate;
    > + best_rate = rate;
    > + }
    > + }
    > +
    > + if (!best_parent)
    > + return -EINVAL;
    > +
    > + req->best_parent_hw = best_parent;
    > + req->best_parent_rate = best_prate;

    I think you're supposed to req->rate = best_rate, here, too. With these
    two fixes,

    Reviewed-by: Eric Anholt <eric@anholt.net>
    [unhandled content-type:application/pgp-signature]
    \
     
     \ /
      Last update: 2015-11-18 20:01    [W:4.044 / U:0.236 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site