* 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).