linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* Common/typical fractional divider HW API
@ 2016-02-05 14:49 Mason
  2016-02-05 15:05 ` Andy Shevchenko
  0 siblings, 1 reply; 8+ messages in thread
From: Mason @ 2016-02-05 14:49 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

AFAICT, the clk-fractional-divider driver implements the following
hardware API:

  M and N are two fields in the same register.
  DIV = M / N

Is this HW API common/typical in the embedded world?
in the PC world?


My hardware uses a slightly weird (to me) API:

  I = 0-255 (8 bits)
  F = 0-15  (4 bits)

  I = 0 => DIV = +INF
  I = 1 => DIV = 1 + F/(32-F)
  I > 1 => DIV = I + F/16

Is this HW API common/typical in the embedded world?
(Perhaps just the linear part for I > 1)

I see two downsides to this API:

1) I = 1 is a special case
2) A lot of the value space is wasted on large values.

For example, when I = 250, we don't really care about 250.0625, 250.125,
etc, or even nearby integer values, for that matter.

I think it's better to have a distribution with high density in small
values, and low density in high values (sort of like floating point).

For example:

  I = 0-15  (4 bits)
  F = 0-255 (8 bits)
  DIV = 2^I * (1 + F/256)

(We could probably even shave 2-4 bits on F.)

Are there downsides to this HW API?
Is this HW API common/typical in the embedded world?

Regards.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Common/typical fractional divider HW API
  2016-02-05 14:49 Common/typical fractional divider HW API Mason
@ 2016-02-05 15:05 ` Andy Shevchenko
  2016-02-05 16:01   ` Mason
  0 siblings, 1 reply; 8+ messages in thread
From: Andy Shevchenko @ 2016-02-05 15:05 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, 2016-02-05 at 15:49 +0100, Mason wrote:
> Hello,
> 
> AFAICT, the clk-fractional-divider driver implements the following
> hardware API:
> 
> ? M and N are two fields in the same register.
> ? DIV = M / N
> 
> Is this HW API common/typical in the embedded world?
> in the PC world?
> 

At least all new Intel SoCs have it, besides that there is one more
user of the struct clk_fractional_divider, but I have no idea if they
have something similar to this.

> 
> My hardware uses a slightly weird (to me) API:
> 
> ? I = 0-255 (8 bits)
> ? F = 0-15??(4 bits)

This part is okay.

> 
> ? I = 0 => DIV = +INF

On Intel we recognize this as an absence of the divider.

> ? I = 1 => DIV = 1 + F/(32-F)

Weird part, indeed. But seems it doubles a precision in a range
[1 .. 1 + 1/2]

> ? I > 1 => DIV = I + F/16

This just normal operation.

> 
> Is this HW API common/typical in the embedded world?
> (Perhaps just the linear part for I > 1)

I saw similar approach in few UART drivers, but they do not use CLK
framework.

So, I could consider this one is more popular / wider, than what we
have in Intel SoCs.

> 
> I see two downsides to this API:
> 
> 1) I = 1 is a special case

> 2) A lot of the value space is wasted on large values.
> 
> For example, when I = 250, we don't really care about 250.0625,
> 250.125,
> etc, or even nearby integer values, for that matter.
> 
> I think it's better to have a distribution with high density in small
> values, and low density in high values (sort of like floating point).
> 
> For example:
> 
> ? I = 0-15??(4 bits)
> ? F = 0-255 (8 bits)
> ? DIV = 2^I * (1 + F/256)
> 
> (We could probably even shave 2-4 bits on F.)
> 
> Are there downsides to this HW API?
> Is this HW API common/typical in the embedded world?

So, what is your intention? If you would like to use CLK framework you
might consider existing providers and users and might implement a
specific one for similar cases.

Also it's possible to convert clock providers for, e.g., UARTs to use
this kind of divider.

-- 
Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Intel Finland Oy

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Common/typical fractional divider HW API
  2016-02-05 15:05 ` Andy Shevchenko
@ 2016-02-05 16:01   ` Mason
  2016-02-05 16:12     ` Andy Shevchenko
  0 siblings, 1 reply; 8+ messages in thread
From: Mason @ 2016-02-05 16:01 UTC (permalink / raw)
  To: linux-arm-kernel

On 05/02/2016 16:05, Andy Shevchenko wrote:

> On Fri, 2016-02-05 at 15:49 +0100, Mason wrote:
>
>> AFAICT, the clk-fractional-divider driver implements the following
>> hardware API:
>>
>>   M and N are two fields in the same register.
>>   DIV = M / N
>>
>> Is this HW API common/typical in the embedded world?
>> in the PC world?
> 
> At least all new Intel SoCs have it, besides that there is one more
> user of the struct clk_fractional_divider, but I have no idea if they
> have something similar to this.
> 
>> My hardware uses a slightly weird (to me) API:
>>
>>   I = 0-255 (8 bits)
>>   F = 0-15  (4 bits)
> 
> This part is okay.
> 
>>   I = 0 => DIV = +INF
> 
> On Intel we recognize this as an absence of the divider.
> 
>>   I = 1 => DIV = 1 + F/(32-F)
> 
> Weird part, indeed. But seems it doubles a precision in a range
> [1 .. 1 + 1/2]
> 
>>   I > 1 => DIV = I + F/16
> 
> This just normal operation.
> 
>> Is this HW API common/typical in the embedded world?
>> (Perhaps just the linear part for I > 1)
> 
> I saw similar approach in few UART drivers, but they do not use CLK
> framework.
> 
> So, I could consider this one is more popular / wider, than what we
> have in Intel SoCs.
> 
>> I see two downsides to this API:
>>
>> 1) I = 1 is a special case
>> 
>> 2) A lot of the value space is wasted on large values.
>>
>> For example, when I = 250, we don't really care about 250.0625,
>> 250.125,
>> etc, or even nearby integer values, for that matter.
>>
>> I think it's better to have a distribution with high density in small
>> values, and low density in high values (sort of like floating point).
>>
>> For example:
>>
>>   I = 0-15  (4 bits)
>>   F = 0-255 (8 bits)
>>   DIV = 2^I * (1 + F/256)
>>
>> (We could probably even shave 2-4 bits on F.)
>>
>> Are there downsides to this HW API?
>> Is this HW API common/typical in the embedded world?
> 
> So, what is your intention? If you would like to use CLK framework you
> might consider existing providers and users and might implement a
> specific one for similar cases.

Right now, I'm using the clk-divider driver (integer divider).
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/drivers/clk/clk-tango4.c

I was trying to avoid writing any code, but it looks like I would
need a specific driver if I want to support the hardware's fractional
divider logic.

Once I started looking at the HW API, I was thinking that it
could be improved (and perhaps the HW engineers would agree
to make the change) but I wanted to get feedback from seasoned
devs with respect to the proposed HW API.

So, do you agree that

  DIV = 2^I * (1 + F/256)

gives a more useful DIV distribution than

  DIV = I + F/16

> Also it's possible to convert clock providers for, e.g., UARTs to use
> this kind of divider.

I'm not sure how to parse that. I'm using the divider driver
for a CPU clock, to do D(V)FS in cpufreq.

Regards.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Common/typical fractional divider HW API
  2016-02-05 16:01   ` Mason
@ 2016-02-05 16:12     ` Andy Shevchenko
  2016-02-05 16:29       ` Mason
  0 siblings, 1 reply; 8+ messages in thread
From: Andy Shevchenko @ 2016-02-05 16:12 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, 2016-02-05 at 17:01 +0100, Mason wrote:

> So, do you agree that
> 
> ? DIV = 2^I * (1 + F/256)
> 
> gives a more useful DIV distribution than
> 
> ? DIV = I + F/16

If you can change hardware why not to use any existing approach which
suits better to your device?

I don't remember any existing, though I didn't check much, divider
register which takes something like that.

> > Also it's possible to convert clock providers for, e.g., UARTs to
> > use
> > this kind of divider.
> 
> I'm not sure how to parse that. I'm using the divider driver
> for a CPU clock, to do D(V)FS in cpufreq.

If you are using custom stuff for custom hardware, I hope it's okay.
But if we are talking about generic solutions (like clk-fractional-
divider), I would suggest to consider existing users / hardware.

What I saw is mostly about

I [0 .. 2^n - 1]
F [0 .. 2^k - 1]
n + k < 32

And I + 1 / (2^k - F) as a formula.

-- 
Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Intel Finland Oy

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Common/typical fractional divider HW API
  2016-02-05 16:12     ` Andy Shevchenko
@ 2016-02-05 16:29       ` Mason
  2016-02-05 16:43         ` Andy Shevchenko
  0 siblings, 1 reply; 8+ messages in thread
From: Mason @ 2016-02-05 16:29 UTC (permalink / raw)
  To: linux-arm-kernel

On 05/02/2016 17:12, Andy Shevchenko wrote:

> On Fri, 2016-02-05 at 17:01 +0100, Mason wrote:
> 
>> So, do you agree that
>>
>>   DIV = 2^I * (1 + F/256)
>>
>> gives a more useful DIV distribution than
>>
>>   DIV = I + F/16
> 
> If you can change hardware why not to use any existing approach which
> suits better to your device?

Sorry, I don't understand the question.

In this part of my message, I was trying to argue that one HW API
"2^I * (1 + F/256)" seemed better than another one "I + F/16" on
any hardware.

> I don't remember any existing, though I didn't check much, divider
> register which takes something like that.

IIUC, you are saying that you've never seen hardware use the
"2^I * (1 + F/256)" formula, is that correct?

>> I'm not sure how to parse that. I'm using the divider driver
>> for a CPU clock, to do D(V)FS in cpufreq.
> 
> If you are using custom stuff for custom hardware, I hope it's okay.
> But if we are talking about generic solutions (like clk-fractional-
> divider), I would suggest to consider existing users / hardware.

Are you saying that I could use the clk-fractional-divider with
hardware that computes "I + F/16" ?

Maybe the clk-fractional-divider could be made more generic by having
the register update part done in a call-back function?

Regards.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Common/typical fractional divider HW API
  2016-02-05 16:29       ` Mason
@ 2016-02-05 16:43         ` Andy Shevchenko
  2016-02-07 16:04           ` Mason
  0 siblings, 1 reply; 8+ messages in thread
From: Andy Shevchenko @ 2016-02-05 16:43 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, 2016-02-05 at 17:29 +0100, Mason wrote:
> On 05/02/2016 17:12, Andy Shevchenko wrote:
> 
> > On Fri, 2016-02-05 at 17:01 +0100, Mason wrote:
> > 
> > > So, do you agree that
> > > 
> > > ? DIV = 2^I * (1 + F/256)
> > > 
> > > gives a more useful DIV distribution than
> > > 
> > > ? DIV = I + F/16
> > 
> > If you can change hardware why not to use any existing approach
> > which
> > suits better to your device?
> 
> Sorry, I don't understand the question.
> 

There are plenty of implementations of the divider. You might consider
to use one than inventing new one:

https://xkcd.com/927/

> In this part of my message, I was trying to argue that one HW API
> "2^I * (1 + F/256)" seemed better than another one "I + F/16" on
> any hardware.

I disagree in a part 2^I.

> 
> > I don't remember any existing, though I didn't check much, divider
> > register which takes something like that.
> 
> IIUC, you are saying that you've never seen hardware use the
> "2^I * (1 + F/256)" formula, is that correct?

Yep, though it doesn't mean there is no such.

> I'm not sure how to parse that. I'm using the divider driver
> > > for a CPU clock, to do D(V)FS in cpufreq.
> > 
> > If you are using custom stuff for custom hardware, I hope it's
> > okay.
> > But if we are talking about generic solutions (like clk-fractional-
> > divider), I would suggest to consider existing users / hardware.
> 
> Are you saying that I could use the clk-fractional-divider with
> hardware that computes "I + F/16" ?

No.

> Maybe the clk-fractional-divider could be made more generic by having
> the register update part done in a call-back function?

Why do you need to touch that module at all if your hardware doesn't
suit it?

-- 
Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Intel Finland Oy

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Common/typical fractional divider HW API
  2016-02-05 16:43         ` Andy Shevchenko
@ 2016-02-07 16:04           ` Mason
  2016-02-15 15:35             ` Andy Shevchenko
  0 siblings, 1 reply; 8+ messages in thread
From: Mason @ 2016-02-07 16:04 UTC (permalink / raw)
  To: linux-arm-kernel

On 05/02/2016 17:43, Andy Shevchenko wrote:

> There are plenty of implementations of the divider.

I'd be happy to read an overview on the subject, if you have
some links to share.

> You might consider to use one than inventing new one

I find it hard to believe that the interface I'm discussing
has not been used (several times) in the past. (It's merely
a trivial floating point scheme.)

As a matter of fact, the integer divider driver supports
"I" and "2^I", so extending 2^I to "2^I * (1 + F/256)"
is an obvious step.

>> In this part of my message, I was trying to argue that one HW API
>> "2^I * (1 + F/256)" seemed better than another one "I + F/16" on
>> any hardware.
> 
> I disagree in a part 2^I.

I don't know what that means. If you speak Russian, maybe you
can write in Russian, and I'll try to figure it out.

>> Maybe the clk-fractional-divider could be made more generic by having
>> the register update part done in a call-back function?
> 
> Why do you need to touch that module at all if your hardware doesn't
> suit it?

What does it mean "your hardware doesn't suit it" ?

I am saying that if the register update were moved into a call-back
function, then any scheme could be supported. Maybe you think this
is just vague hand-waving. I'll send a patch to illustrate what
I'm saying.

Regards.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Common/typical fractional divider HW API
  2016-02-07 16:04           ` Mason
@ 2016-02-15 15:35             ` Andy Shevchenko
  0 siblings, 0 replies; 8+ messages in thread
From: Andy Shevchenko @ 2016-02-15 15:35 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, 2016-02-07 at 17:04 +0100, Mason wrote:
> On 05/02/2016 17:43, Andy Shevchenko wrote:
> 
> > There are plenty of implementations of the divider.
> 
> I'd be happy to read an overview on the subject, if you have
> some links to share.

drivers/tty/serial/*

> 
> > You might consider to use one than inventing new one
> 
> I find it hard to believe that the interface I'm discussing
> has not been used (several times) in the past. (It's merely
> a trivial floating point scheme.)
> 
> As a matter of fact, the integer divider driver supports
> "I" and "2^I", so extending 2^I to "2^I * (1 + F/256)"
> is an obvious step.

Just to be simple:
Why do you have to modify existing clk-fractional-divider.c module?

May I suggest to reconsider your design to be fit in the existing CLK
divider implementations? Also, some of the hardware IPs have inside
divider registers, like mentioned above UARTs. I already suggested to
look at them to see how hardware is done.

Again, (actually I bored to repeat) I didn't see (yet!) any HW divider
which has integer part as 2^I. I don't get why you stuck with that
formula and why 1/256? Who prevents to have 1/32768 in HW (like we have
in LPSS of Intel SoCs)?

Here I'm giving up this discussion. Perhaps more experienced people
could correct me.

-- 
Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Intel Finland Oy

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2016-02-15 15:35 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-02-05 14:49 Common/typical fractional divider HW API Mason
2016-02-05 15:05 ` Andy Shevchenko
2016-02-05 16:01   ` Mason
2016-02-05 16:12     ` Andy Shevchenko
2016-02-05 16:29       ` Mason
2016-02-05 16:43         ` Andy Shevchenko
2016-02-07 16:04           ` Mason
2016-02-15 15:35             ` Andy Shevchenko

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).