All of lore.kernel.org
 help / color / mirror / Atom feed
From: s.hauer@pengutronix.de (Sascha Hauer)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 05/10] clk: Add support for simple dividers
Date: Mon, 18 Apr 2011 12:07:16 +0200	[thread overview]
Message-ID: <20110418100716.GJ14770@pengutronix.de> (raw)
In-Reply-To: <20110418094909.GE31131@pengutronix.de>

On Mon, Apr 18, 2011 at 11:49:09AM +0200, Uwe Kleine-K?nig wrote:
> On Fri, Apr 15, 2011 at 09:08:10PM +0200, Sascha Hauer wrote:
> > This patch adds support for the most common type of divider,
> > which expects a register, width and shift values to desacribe
> > the location of the divider. The divider can be zero based
> > or one based (div = reg_val + 1 vs. div = reg_val).
> > 
> > Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> > Cc: Jeremy Kerr <jeremy.kerr@canonical.com>
> > ---
> >  drivers/clk/Kconfig       |    3 +
> >  drivers/clk/Makefile      |    1 +
> >  drivers/clk/clk-divider.c |  132 +++++++++++++++++++++++++++++++++++++++++++++
> >  include/linux/clk.h       |   31 +++++++++++
> >  4 files changed, 167 insertions(+), 0 deletions(-)
> >  create mode 100644 drivers/clk/clk-divider.c
> > 
> > diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
> > index 6e3ae54..76bb4c9 100644
> > --- a/drivers/clk/Kconfig
> > +++ b/drivers/clk/Kconfig
> > @@ -5,3 +5,6 @@ config CLKDEV_LOOKUP
> >  
> >  config USE_COMMON_STRUCT_CLK
> >  	bool
> > +
> > +config USE_COMMON_CLK_DIVIDER
> > +	bool
> > diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
> > index a1a06d3..723d884 100644
> > --- a/drivers/clk/Makefile
> > +++ b/drivers/clk/Makefile
> > @@ -1,3 +1,4 @@
> >  
> >  obj-$(CONFIG_CLKDEV_LOOKUP)	+= clkdev.o
> >  obj-$(CONFIG_USE_COMMON_STRUCT_CLK) += clk.o
> > +obj-$(CONFIG_USE_COMMON_CLK_DIVIDER) += clk-divider.o
> > diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c
> > new file mode 100644
> > index 0000000..2de94df
> > --- /dev/null
> > +++ b/drivers/clk/clk-divider.c
> > @@ -0,0 +1,132 @@
> > +/*
> > + * Copyright (C) 2011 Sascha Hauer <s.hauer@pengutronix.de>
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + *
> > + * Standard functionality for the common clock API.
> > + */
> > +#include <linux/module.h>
> > +#include <linux/clk.h>
> > +#include <linux/io.h>
> > +
> > +#define to_clk_divider(clk) (container_of(clk, struct clk_divider, clk))
> > +
> > +static unsigned long clk_divider_get_rate(struct clk *clk)
> > +{
> > +	struct clk_divider *divider = to_clk_divider(clk);
> > +	unsigned long rate = clk_get_rate(divider->parent);
> > +	unsigned int div;
> > +
> > +	div = readl(divider->reg) >> divider->shift;
> > +	div &= (1 << divider->width) - 1;
> > +
> > +	if (!(divider->flags & CLK_DIVIDER_FLAG_ONE_BASED))
> > +		div++;
> > +
> > +	return rate / div;
> DIV_ROUND_UP(rate, div)? (There is DIV_ROUND_CLOSEST, too, but I think
> you need to round up, see below.)
> 
> > +}
> > +
> > +static int clk_divider_bestdiv(struct clk *clk, unsigned long rate,
> > +		unsigned long *best_parent_rate)
> conceptually this returns an unsigned value
> 
> > +{
> > +	struct clk_divider *divider = to_clk_divider(clk);
> > +	int i, bestdiv = 0;
> > +	unsigned long parent_rate, best = 0, now, maxdiv;
> > +
> > +	maxdiv = (1 << divider->width);
> Is divider->width == 32 a valid scenario? If so, this overflows.
> 
> > +
> > +	if (divider->flags & CLK_DIVIDER_FLAG_ONE_BASED)
> > +		maxdiv--;
> > +
> > +	/*
> > +	 * The maximum divider we can use without overflowing
> > +	 * unsigned long in rate * i below
> > +	 */
> > +	maxdiv = min(ULONG_MAX / rate, maxdiv);
> > +
> > +	for (i = 1; i <= maxdiv; i++) {
> > +		parent_rate = clk_round_rate(divider->parent, (rate + 1) * i);
> > +		now = parent_rate / i;
> This is buggy, take rate = 25, i = 4. You request the parent to set
> 104. If you get that, the resulting rate is 26. (And even if
> clk_round_rate only return 101 this might be too much.)
> 
> I think you need:
> 
> 	parent_rate = clk_round_rate(divider->parent, rate * i)
> 	now = DIV_ROUND_UP(parent_rate, i);
> 
> I think you really need DIV_ROUND_UP here, DIV_ROUND_CLOSEST won't work.
> Consider that a rate of 25 is requested, again with i=4. So the parent
> is asked for 100 and might return 97. With DIV_ROUND_CLOSEST you report
> to be able to set 24 now, but in fact it's more (24.25). If now further
> up in the recursion another divider considers 24 to be a great value to
> make 12Hz the value actually provided is too big.

I will give it a try using the DIV_ROUND_ macros. I had problems with
two cascaded dividers where due to rounding errors while dividing I
got got the next smaller divider value when passing in a value which
I could exactly get.

> > +static int clk_divider_set_rate(struct clk *clk, unsigned long rate)
> > +{
> > +	unsigned long best_parent_rate;
> > +	struct clk_divider *divider = to_clk_divider(clk);
> > +	unsigned int div;
> > +	int ret;
> > +	unsigned long flags = 0;
> > +	u32 val;
> > +
> > +	div = clk_divider_bestdiv(clk, rate, &best_parent_rate);
> > +
> > +	if (rate != best_parent_rate / div)
> > +		return -EINVAL;
> This is too harsh, isn't it. Or can you expect to only get values that
> are returned by round_rate? Again you need DIV_ROUND_UP.

AFAIK there are two different implementation types in the tree. Some
implementations only allow to set to the exact rate round_rate returns
while others round down in set_rate.

Has this been specified what behaviour is expected?

> >  
> > +/**
> > + * clock divider
> > + *
> > + * @clk		clock source
> > + * @reg		register containing the divider
> > + * @shift	shift to the divider
> > + * @width	width of the divider
> > + * @lock	register lock
> "optional register lock"?

ok.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

  reply	other threads:[~2011-04-18 10:07 UTC|newest]

Thread overview: 165+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-04-15 19:08 [RFC] sanitizing crazy clock data files Sascha Hauer
2011-04-15 19:08 ` [PATCH 01/10] Add a common struct clk Sascha Hauer
2011-04-21 19:48   ` Thomas Gleixner
2011-04-22  0:28     ` Richard Zhao
2011-04-22  9:23       ` Thomas Gleixner
2011-04-23 14:08         ` Richard Zhao
2011-04-23 15:30           ` Thomas Gleixner
2011-04-24  2:54             ` Richard Zhao
2011-04-24  7:20             ` Linus Walleij
2011-04-24  9:55               ` Richard Zhao
2011-04-22  4:57     ` Saravana Kannan
2011-04-22  9:13       ` Thomas Gleixner
2011-04-29 10:09     ` Russell King - ARM Linux
2011-04-29 10:45       ` Thomas Gleixner
2011-04-29 10:58         ` Tony Lindgren
2011-04-29 11:01         ` Russell King - ARM Linux
2011-04-30 18:30           ` Pavel Machek
2011-04-30  8:06   ` Linus Walleij
2011-04-30  9:01     ` Russell King - ARM Linux
2011-04-30 16:30       ` Linus Walleij
2011-05-01 20:33   ` Rob Herring
2011-05-02  1:09     ` Jeremy Kerr
2011-05-02  3:09       ` Rob Herring
2011-05-02  3:40         ` Jeremy Kerr
2011-05-02 16:30           ` Rob Herring
2011-05-02 22:36             ` Russell King - ARM Linux
2011-05-03  0:22               ` Saravana Kannan
2011-05-04  6:40                 ` Sascha Hauer
2011-05-04 18:33                   ` Saravana Kannan
2011-05-04 23:35               ` Paul Walmsley
2011-05-10 20:06                 ` Saravana Kannan
2011-05-02 16:55           ` David Brown
2011-05-02 17:31             ` Stephen Boyd
2011-04-15 19:08 ` [PATCH 02/10] clk: Generic support for fixed-rate clocks Sascha Hauer
2011-04-15 19:08 ` [PATCH 03/10] clk: Make NULL a valid clock again Sascha Hauer
2011-04-19  0:53   ` Jeremy Kerr
2011-04-19  6:25     ` Sascha Hauer
2011-04-20 12:53   ` Uwe Kleine-König
2011-04-15 19:08 ` [PATCH 04/10] clk: implement parent pass through functions Sascha Hauer
2011-04-18  9:25   ` Uwe Kleine-König
2011-04-18  9:48     ` Sascha Hauer
2011-04-19 17:20   ` Stephen Boyd
2011-04-19 17:53     ` Sascha Hauer
2011-04-19 19:09       ` Uwe Kleine-König
2011-04-19 20:58         ` Sascha Hauer
2011-04-19 21:54         ` Thomas Gleixner
2011-04-20  7:16           ` Uwe Kleine-König
2011-04-20  8:34             ` Thomas Gleixner
2011-04-20 14:07           ` [PATCH RFC] clk: add support for automatic parent handling Uwe Kleine-König
2011-04-20 16:16             ` Thomas Gleixner
2011-04-20 18:59               ` Uwe Kleine-König
2011-04-20 19:52                 ` Thomas Gleixner
2011-04-21  6:58                   ` Saravana Kannan
2011-04-21  6:58                     ` Saravana Kannan
2011-04-21  6:58                     ` Saravana Kannan
2011-04-21 10:33                     ` Thomas Gleixner
2011-04-21 10:33                       ` Thomas Gleixner
2011-04-21 10:33                       ` Thomas Gleixner
2011-04-21 19:22                       ` torbenh
2011-04-21 19:22                         ` torbenh
2011-04-21 19:22                         ` torbenh
2011-04-23 23:26                       ` Benjamin Herrenschmidt
2011-04-23 23:26                         ` Benjamin Herrenschmidt
2011-04-23 23:26                         ` Benjamin Herrenschmidt
2011-04-21  7:22                   ` Uwe Kleine-König
2011-04-21  9:12                     ` Thomas Gleixner
2011-04-21 10:31                       ` Mark Brown
2011-04-21 11:42                         ` Tony Lindgren
2011-04-21 14:52                           ` Thomas Gleixner
2011-04-22  7:09                             ` Tony Lindgren
2011-04-22  8:22                               ` Thomas Gleixner
2011-04-21 14:29                         ` Thomas Gleixner
2011-04-29 10:37                       ` Russell King - ARM Linux
2011-04-29 11:01                         ` Thomas Gleixner
2011-04-29 11:06                           ` Russell King - ARM Linux
2011-04-29 12:13                             ` Thomas Gleixner
2011-04-29 13:26                               ` Russell King - ARM Linux
2011-04-29 15:31                                 ` Thomas Gleixner
2011-04-29 22:07                                   ` Russell King - ARM Linux
2011-04-29 22:16                                     ` Thomas Gleixner
2011-04-29 22:19                                       ` Russell King - ARM Linux
2011-04-29 22:47                                         ` Thomas Gleixner
2011-04-30 14:27                                 ` torbenh
2011-05-03  6:35                                   ` Colin Cross
2011-05-05  8:35                                     ` torbenh
2011-05-03  2:44                                 ` Saravana Kannan
2011-05-03  2:46                                   ` Saravana Kannan
2011-04-21 10:13                     ` Mark Brown
2011-04-21 11:39                       ` Tony Lindgren
2011-04-21  7:42                   ` Sascha Hauer
2011-04-21  9:21                     ` Thomas Gleixner
2011-04-21 11:50                       ` Mark Brown
2011-04-21 12:20                         ` Thomas Gleixner
2011-04-21 12:35                           ` Mark Brown
2011-04-25  2:03                             ` Richard Zhao
2011-04-25 10:57                               ` Mark Brown
2011-04-25 14:41                                 ` Richard Zhao
2011-04-25 14:44                                   ` Mark Brown
2011-04-29 10:49                           ` Russell King - ARM Linux
2011-04-29 11:11                             ` Thomas Gleixner
2011-04-29 11:38                               ` Russell King - ARM Linux
2011-04-29 12:19                                 ` Thomas Gleixner
2011-04-29 13:27                                   ` Russell King - ARM Linux
2011-04-29 15:47                                     ` Thomas Gleixner
2011-04-21 12:06                       ` Sascha Hauer
2011-04-21 15:38                         ` Thomas Gleixner
2011-04-22  0:23                           ` Colin Cross
2011-04-22  9:51                             ` Thomas Gleixner
2011-04-22 16:14                               ` Thomas Gleixner
2011-04-22 16:39                               ` Colin Cross
2011-04-22 16:57                                 ` Thomas Gleixner
2011-04-22 22:26                                   ` Saravana Kannan
2011-04-22 22:55                                     ` Thomas Gleixner
2011-04-23  0:48                                       ` Saravana Kannan
2011-04-23 23:34                                         ` Benjamin Herrenschmidt
2011-04-22  4:54                           ` Saravana Kannan
2011-04-22  9:06                             ` Thomas Gleixner
2011-04-29 10:30                   ` Russell King - ARM Linux
2011-04-29 10:51                     ` Thomas Gleixner
2011-04-29 10:56                       ` Russell King - ARM Linux
2011-04-24  9:45             ` Richard Zhao
2011-04-24 20:14               ` Uwe Kleine-König
2011-04-29 10:20       ` [PATCH 04/10] clk: implement parent pass through functions Russell King - ARM Linux
2011-04-15 19:08 ` [PATCH 05/10] clk: Add support for simple dividers Sascha Hauer
2011-04-18  9:49   ` Uwe Kleine-König
2011-04-18 10:07     ` Sascha Hauer [this message]
2011-04-19  2:45       ` Saravana Kannan
2011-04-19  7:32         ` Uwe Kleine-König
2011-04-19  8:55           ` Saravana Kannan
2011-04-19  9:31             ` Sascha Hauer
2011-04-19 22:28               ` Saravana Kannan
2011-04-20  6:36                 ` Sascha Hauer
2011-04-20 21:45                   ` Saravana Kannan
2011-04-21  7:39                     ` Uwe Kleine-König
2011-04-28 15:14         ` Russell King - ARM Linux
2011-05-03  3:37           ` Saravana Kannan
2011-05-03  7:12             ` Uwe Kleine-König
2011-04-28 15:22     ` Russell King - ARM Linux
2011-05-02  7:58       ` Sascha Hauer
2011-04-18 22:40   ` Stephen Boyd
2011-04-19  0:32     ` Jeremy Kerr
2011-04-19  5:41       ` Stephen Boyd
2011-04-24 13:48   ` Richard Zhao
2011-04-25 18:51     ` Sascha Hauer
2011-04-26  1:54       ` Richard Zhao
2011-04-15 19:08 ` [PATCH 06/10] clk: Add support for a generic clock multiplexer Sascha Hauer
2011-04-18 13:15   ` Uwe Kleine-König
2011-04-18 13:33     ` Sascha Hauer
2011-04-18 13:54       ` Uwe Kleine-König
2011-04-18 17:54       ` Stephen Boyd
2011-04-18 18:34         ` Russell King - ARM Linux
2011-04-18 18:41           ` Russell King - ARM Linux
2011-04-18 18:46             ` Stephen Boyd
2011-04-15 19:08 ` [PATCH 07/10] ARM i.MX: Support for clock building blocks Sascha Hauer
2011-04-15 19:08 ` [PATCH 08/10] ARM i.MX: Add generic support for pllv2 Sascha Hauer
2011-04-15 19:08 ` [PATCH 09/10] ARM i.MX51/53: reimplement clock support Sascha Hauer
2011-04-15 19:08 ` [PATCH 10/10] ARM i.MX51/53: remove old " Sascha Hauer
2011-04-15 19:36 ` [RFC] sanitizing crazy clock data files Russell King - ARM Linux
2011-04-15 20:12   ` Sascha Hauer
2011-04-15 20:25     ` Russell King - ARM Linux
2011-04-15 20:28       ` Russell King - ARM Linux
2011-04-15 20:49         ` Uwe Kleine-König
2011-04-18  4:07     ` Shawn Guo
2011-04-15 20:45 ` Uwe Kleine-König
2011-04-18  7:42 ` Sascha Hauer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20110418100716.GJ14770@pengutronix.de \
    --to=s.hauer@pengutronix.de \
    --cc=linux-arm-kernel@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.