Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754065AbbLFQW7 (ORCPT ); Sun, 6 Dec 2015 11:22:59 -0500 Received: from relay4-d.mail.gandi.net ([217.70.183.196]:35105 "EHLO relay4-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753658AbbLFQWw (ORCPT ); Sun, 6 Dec 2015 11:22:52 -0500 X-Originating-IP: 81.57.43.44 From: Remi Pommarel To: Stephen Warren , Eric Anholt , Lee Jones , Michael Turquette , Stephen Boyd , Rob Herring Cc: linux-rpi-kernel@lists.infradead.org, linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org, Remi Pommarel Subject: [PATCH v3 1/4] clk: bcm2835: add a round up ability to the clock divisor Date: Sun, 6 Dec 2015 17:22:46 +0100 Message-Id: <1449418969-5565-2-git-send-email-repk@triplefau.lt> X-Mailer: git-send-email 2.0.1 In-Reply-To: <1449418969-5565-1-git-send-email-repk@triplefau.lt> References: <1449418969-5565-1-git-send-email-repk@triplefau.lt> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2599 Lines: 71 Make bcm2835_clock_choose_div to optionally round up the chosen MASH divisor so that the resulting average rate will not be higher than the requested one. Signed-off-by: Remi Pommarel --- drivers/clk/bcm/clk-bcm2835.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c index 39bf582..9e881ee 100644 --- a/drivers/clk/bcm/clk-bcm2835.c +++ b/drivers/clk/bcm/clk-bcm2835.c @@ -1148,22 +1148,24 @@ static int bcm2835_clock_is_on(struct clk_hw *hw) static u32 bcm2835_clock_choose_div(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) + unsigned long parent_rate, + bool round_up) { struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw); const struct bcm2835_clock_data *data = clock->data; - u32 unused_frac_mask = GENMASK(CM_DIV_FRAC_BITS - data->frac_bits, 0); + u32 unused_frac_mask = + GENMASK(CM_DIV_FRAC_BITS - data->frac_bits, 0) >> 1; u64 temp = (u64)parent_rate << CM_DIV_FRAC_BITS; + u64 rem; u32 div; - do_div(temp, rate); + rem = do_div(temp, rate); div = temp; - /* Round and mask off the unused bits */ - if (unused_frac_mask != 0) { - div += unused_frac_mask >> 1; - div &= ~unused_frac_mask; - } + /* Round up and mask off the unused bits */ + if (round_up && ((div & unused_frac_mask) != 0 || rem != 0)) + div += unused_frac_mask + 1; + div &= ~unused_frac_mask; /* Clamp to the limits. */ div = max(div, unused_frac_mask + 1); @@ -1202,7 +1204,7 @@ static long bcm2835_clock_round_rate(struct clk_hw *hw, unsigned long *parent_rate) { struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw); - u32 div = bcm2835_clock_choose_div(hw, rate, *parent_rate); + u32 div = bcm2835_clock_choose_div(hw, rate, *parent_rate, false); return bcm2835_clock_rate_from_divisor(clock, *parent_rate, div); } @@ -1271,7 +1273,7 @@ static int bcm2835_clock_set_rate(struct clk_hw *hw, struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw); struct bcm2835_cprman *cprman = clock->cprman; const struct bcm2835_clock_data *data = clock->data; - u32 div = bcm2835_clock_choose_div(hw, rate, parent_rate); + u32 div = bcm2835_clock_choose_div(hw, rate, parent_rate, false); cprman_write(cprman, data->div_reg, div); -- 2.0.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/