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