* moving Tegra30 to the common clock framework @ 2012-05-03 16:13 Peter De Schrijver 2012-05-07 0:03 ` Mike Turquette 0 siblings, 1 reply; 26+ messages in thread From: Peter De Schrijver @ 2012-05-03 16:13 UTC (permalink / raw) To: linux-arm-kernel Hi, I started looking into what would be needed to move our tegra30 clock code to the common clock framework. The tegra30 clocktree is rather flat. Basically there are a bunch of sources (13 PLLs, external audio clocks, osc and 32Khz) and peripheral clocks which have a mux (with 4 or more inputs), a divider and a gate. So almost every peripheral clock can have multiple parents. Some questions: 1) should these peripheral clocks be modelled as 3 different clocks (mux -> divider -> gate) or would it be better to make a new clock type for this? 2) how to define the default parent? in many cases the hw reset value isn't a very sensible choice, so the kernel probably needs to set a parent of many of them if we don't want to rely on bootloader configuration. Cheers, Peter. ^ permalink raw reply [flat|nested] 26+ messages in thread
* moving Tegra30 to the common clock framework 2012-05-03 16:13 moving Tegra30 to the common clock framework Peter De Schrijver @ 2012-05-07 0:03 ` Mike Turquette 2012-05-07 15:39 ` Stephen Warren 2012-05-09 11:13 ` Peter De Schrijver 0 siblings, 2 replies; 26+ messages in thread From: Mike Turquette @ 2012-05-07 0:03 UTC (permalink / raw) To: linux-arm-kernel On 20120503-19:13, Peter De Schrijver wrote: > Hi, > > I started looking into what would be needed to move our tegra30 clock code > to the common clock framework. The tegra30 clocktree is rather flat. Basically > there are a bunch of sources (13 PLLs, external audio clocks, osc and 32Khz) > and peripheral clocks which have a mux (with 4 or more inputs), a divider and > a gate. So almost every peripheral clock can have multiple parents. > > Some questions: > > 1) should these peripheral clocks be modelled as 3 different clocks > (mux -> divider -> gate) or would it be better to make a new clock type for > this? > That is really for you to decide. If the semantics of the existing mux, divider and gate in drivers/clk/clk-*.c work well for you then I think the answer is "yes". There is infrastructure for register-access locking in those common types which might help your complex clocks. Thanks to the parent rate propagation stuff in clk_set_rate it should be possible for your drivers to only be aware of the gate and call clk_set_rate on only that clock, which propagates up to the divider and, if necessary, again propagates up to the mux. I encourage you to try that first. But if you find the semantics of those basic clock types aren't cutting it for you then you must create a type which is platform-specific. > 2) how to define the default parent? in many cases the hw reset value isn't > a very sensible choice, so the kernel probably needs to set a parent of > many of them if we don't want to rely on bootloader configuration. The only related thing handled at the framework level is _discovery_ of the parent during clock registration/initialization. If you don't trust the bootloader and want to set things up as soon as possible (a wise move) then I suggest you do so from your platform clock code at the same time that you register your clocks with the framework. Something like: struct clk *c; c = clk_register(...); if (IS_ERR(c)) omg_fail(); clk_set_parent(c, b); Where 'b' is a parent of 'c'. Register your clock tree top-down and you can re-parent as you go. Regards, Mike ^ permalink raw reply [flat|nested] 26+ messages in thread
* moving Tegra30 to the common clock framework 2012-05-07 0:03 ` Mike Turquette @ 2012-05-07 15:39 ` Stephen Warren 2012-05-07 16:12 ` Turquette, Mike 2012-05-09 11:13 ` Peter De Schrijver 1 sibling, 1 reply; 26+ messages in thread From: Stephen Warren @ 2012-05-07 15:39 UTC (permalink / raw) To: linux-arm-kernel On 05/06/2012 06:03 PM, Mike Turquette wrote: > On 20120503-19:13, Peter De Schrijver wrote: >> Hi, >> >> I started looking into what would be needed to move our tegra30 clock code >> to the common clock framework. The tegra30 clocktree is rather flat. Basically >> there are a bunch of sources (13 PLLs, external audio clocks, osc and 32Khz) >> and peripheral clocks which have a mux (with 4 or more inputs), a divider and >> a gate. So almost every peripheral clock can have multiple parents. >> >> Some questions: >> >> 1) should these peripheral clocks be modelled as 3 different clocks >> (mux -> divider -> gate) or would it be better to make a new clock type for >> this? >> > > That is really for you to decide. If the semantics of the existing mux, > divider and gate in drivers/clk/clk-*.c work well for you then I think > the answer is "yes". There is infrastructure for register-access > locking in those common types which might help your complex clocks. > > Thanks to the parent rate propagation stuff in clk_set_rate it should be > possible for your drivers to only be aware of the gate and call > clk_set_rate on only that clock, which propagates up to the divider and, > if necessary, again propagates up to the mux. > > I encourage you to try that first. But if you find the semantics of > those basic clock types aren't cutting it for you then you must create a > type which is platform-specific. A lot of these mux/divider/gate clocks go out to peripherals, whose drivers want to call both clk_set_rate() and clk_en/disable() on the clock. There's only 1 clock reaching the peripheral in HW, so the driver should only call clk_get() once, and similarly the DT should only provide a single clock to the driver. Given the mux->divider->gate clock construction, that clock would presumably be the gate object. clk_en/disable() clearly work there, but is clk_set_rate() intended to propagate up the chain until it can be satisfied, i.e. does the gate clock object's set_rate() op simply call the parent's set_rate() op? If the order were instead mux->gate->divider, would it be correct for enable/disable to propagate from the divider to the gate? >> 2) how to define the default parent? in many cases the hw reset value isn't >> a very sensible choice, so the kernel probably needs to set a parent of >> many of them if we don't want to rely on bootloader configuration. > > The only related thing handled at the framework level is _discovery_ of > the parent during clock registration/initialization. If you don't trust > the bootloader and want to set things up as soon as possible (a wise > move) then I suggest you do so from your platform clock code at the same > time that you register your clocks with the framework. Something like: > > struct clk *c; > c = clk_register(...); > if (IS_ERR(c)) > omg_fail(); > clk_set_parent(c, b); > > Where 'b' is a parent of 'c'. Register your clock tree top-down and you > can re-parent as you go. I'm hoping we can represent this in device tree somehow, so that individual boards can set the clock tree up differently depending on their needs (e.g. Tegra20 doesn't have quite enough PLLs, so sometimes a particular PLL will be used to generate the 2nd display's pixel clock, whereas on other boards it may be used for some peripherals). So, we'd like to describe this in DT. It seems like it'd be pretty common to want the kernel to fully initialize the clock tree, and to do this from device tree, so perhaps this might evolve into a common (part of) a cross-SoC clock binding, or some kind of utility function that parsed a clock-tree-init-table from DT? ^ permalink raw reply [flat|nested] 26+ messages in thread
* moving Tegra30 to the common clock framework 2012-05-07 15:39 ` Stephen Warren @ 2012-05-07 16:12 ` Turquette, Mike 2012-05-08 5:07 ` zhoujie wu 0 siblings, 1 reply; 26+ messages in thread From: Turquette, Mike @ 2012-05-07 16:12 UTC (permalink / raw) To: linux-arm-kernel On Mon, May 7, 2012 at 8:39 AM, Stephen Warren <swarren@wwwdotorg.org> wrote: > On 05/06/2012 06:03 PM, Mike Turquette wrote: >> On 20120503-19:13, Peter De Schrijver wrote: >>> Hi, >>> >>> I started looking into what would be needed to move our tegra30 clock code >>> to the common clock framework. The tegra30 clocktree is rather flat. Basically >>> there are a bunch of sources (13 PLLs, external audio clocks, osc and 32Khz) >>> and peripheral clocks which have a mux (with 4 or more inputs), a divider and >>> a gate. So almost every peripheral clock can have multiple parents. >>> >>> Some questions: >>> >>> 1) should these peripheral clocks be modelled as 3 different clocks >>> ? ?(mux -> divider -> gate) or would it be better to make a new clock type for >>> ? ?this? >>> >> >> That is really for you to decide. ?If the semantics of the existing mux, >> divider and gate in drivers/clk/clk-*.c work well for you then I think >> the answer is "yes". ?There is infrastructure for register-access >> locking in those common types which might help your complex clocks. >> >> Thanks to the parent rate propagation stuff in clk_set_rate it should be >> possible for your drivers to only be aware of the gate and call >> clk_set_rate on only that clock, which propagates up to the divider and, >> if necessary, again propagates up to the mux. >> >> I encourage you to try that first. ?But if you find the semantics of >> those basic clock types aren't cutting it for you then you must create a >> type which is platform-specific. > > A lot of these mux/divider/gate clocks go out to peripherals, whose > drivers want to call both clk_set_rate() and clk_en/disable() on the clock. > > There's only 1 clock reaching the peripheral in HW, so the driver should > only call clk_get() once, and similarly the DT should only provide a > single clock to the driver. > Sounds good so far. > Given the mux->divider->gate clock construction, that clock would > presumably be the gate object. clk_en/disable() clearly work there, but > is clk_set_rate() intended to propagate up the chain until it can be > satisfied, i.e. does the gate clock object's set_rate() op simply call > the parent's set_rate() op? > Only if you set the CLK_SET_RATE_PARENT flag on the children. Take the following example sub-tree: mux | div | gate If gate does NOT have CLK_SET_RATE_PARENT set in struct clk->flags then clk_set_rate will do nothing (since it does not implement a .set_rate callback). If the flag is set then the framework will kick the rate request up to the parent, 'div'. Div implements a .set_rate callback and may or may not set the CLK_SET_RATE_PARENT flag. Having a .set_rate implemenation does preclude one from propagating the rate change up the tree, so it is possible to adjust the divider to a new rate AND still kick the rate change request up to the parent, 'mux'. In your case 'mux' should probably not set CLK_SET_RATE_PARENT and the propagation will end there. 'mux' might implement a re-parenting operation as part of it's .set_rate implementation. This is covered fairly well in Documentation/clk.txt > If the order were instead mux->gate->divider, would it be correct for > enable/disable to propagate from the divider to the gate? > Correct. Order doesn't matter. Even in the absence of a .prepare/.enable callback the framework will still propagate these changes as part of typical use-counting rules. >>> 2) how to define the default parent? in many cases the hw reset value isn't >>> ? ?a very sensible choice, so the kernel probably needs to set a parent of >>> ? ?many of them if we don't want to rely on bootloader configuration. >> >> The only related thing handled at the framework level is _discovery_ of >> the parent during clock registration/initialization. ?If you don't trust >> the bootloader and want to set things up as soon as possible (a wise >> move) then I suggest you do so from your platform clock code at the same >> time that you register your clocks with the framework. ?Something like: >> >> ? ? ? struct clk *c; >> ? ? ? c = clk_register(...); >> ? ? ? if (IS_ERR(c)) >> ? ? ? ? ? ? ? omg_fail(); >> ? ? ? clk_set_parent(c, b); >> >> Where 'b' is a parent of 'c'. ?Register your clock tree top-down and you >> can re-parent as you go. > > I'm hoping we can represent this in device tree somehow, so that > individual boards can set the clock tree up differently depending on > their needs (e.g. Tegra20 doesn't have quite enough PLLs, so sometimes a > particular PLL will be used to generate the 2nd display's pixel clock, > whereas on other boards it may be used for some peripherals). So, we'd > like to describe this in DT. > > It seems like it'd be pretty common to want the kernel to fully > initialize the clock tree, and to do this from device tree, so perhaps > this might evolve into a common (part of) a cross-SoC clock binding, or > some kind of utility function that parsed a clock-tree-init-table from DT? As long as the configuration of your clocks can be expressed by the existing clk api, e.g. clk_prepare / clk_enable / clk_set_rate / clk_set_parent, then I think it would be easy to define a format whereby the clock is configured immediately after being registered. Essentially it would do what I outline in my original email above, but the configuration could be encoded into DT. Any platform-specific clock configuration (bits that aren't obviously expressed by the clk.h api) will be harder to configure through generic DT bindings. Regards, Mike ^ permalink raw reply [flat|nested] 26+ messages in thread
* moving Tegra30 to the common clock framework 2012-05-07 16:12 ` Turquette, Mike @ 2012-05-08 5:07 ` zhoujie wu 2012-05-08 17:15 ` Turquette, Mike 0 siblings, 1 reply; 26+ messages in thread From: zhoujie wu @ 2012-05-08 5:07 UTC (permalink / raw) To: linux-arm-kernel Hi Mike, Could you please explain more details about how to implement a re-parenting operation as part of it's .set_rate implementation? As far as I know, we can not call clk_set_parent in .set_rate function directly, since clk_set_rate and clk_set_parent are using the same prepare_lock. Any other interface can be used to implement it? Thanks. 2012/5/8 Turquette, Mike <mturquette@ti.com>: > On Mon, May 7, 2012 at 8:39 AM, Stephen Warren <swarren@wwwdotorg.org> wrote: >> On 05/06/2012 06:03 PM, Mike Turquette wrote: >>> On 20120503-19:13, Peter De Schrijver wrote: >>>> Hi, >>>> >>>> I started looking into what would be needed to move our tegra30 clock code >>>> to the common clock framework. The tegra30 clocktree is rather flat. Basically >>>> there are a bunch of sources (13 PLLs, external audio clocks, osc and 32Khz) >>>> and peripheral clocks which have a mux (with 4 or more inputs), a divider and >>>> a gate. So almost every peripheral clock can have multiple parents. >>>> >>>> Some questions: >>>> >>>> 1) should these peripheral clocks be modelled as 3 different clocks >>>> ? ?(mux -> divider -> gate) or would it be better to make a new clock type for >>>> ? ?this? >>>> >>> >>> That is really for you to decide. ?If the semantics of the existing mux, >>> divider and gate in drivers/clk/clk-*.c work well for you then I think >>> the answer is "yes". ?There is infrastructure for register-access >>> locking in those common types which might help your complex clocks. >>> >>> Thanks to the parent rate propagation stuff in clk_set_rate it should be >>> possible for your drivers to only be aware of the gate and call >>> clk_set_rate on only that clock, which propagates up to the divider and, >>> if necessary, again propagates up to the mux. >>> >>> I encourage you to try that first. ?But if you find the semantics of >>> those basic clock types aren't cutting it for you then you must create a >>> type which is platform-specific. >> >> A lot of these mux/divider/gate clocks go out to peripherals, whose >> drivers want to call both clk_set_rate() and clk_en/disable() on the clock. >> >> There's only 1 clock reaching the peripheral in HW, so the driver should >> only call clk_get() once, and similarly the DT should only provide a >> single clock to the driver. >> > > Sounds good so far. > >> Given the mux->divider->gate clock construction, that clock would >> presumably be the gate object. clk_en/disable() clearly work there, but >> is clk_set_rate() intended to propagate up the chain until it can be >> satisfied, i.e. does the gate clock object's set_rate() op simply call >> the parent's set_rate() op? >> > > Only if you set the CLK_SET_RATE_PARENT flag on the children. ?Take > the following example sub-tree: > > mux > ?| > div > ?| > gate > > If gate does NOT have CLK_SET_RATE_PARENT set in struct clk->flags > then clk_set_rate will do nothing (since it does not implement a > .set_rate callback). ?If the flag is set then the framework will kick > the rate request up to the parent, 'div'. ?Div implements a .set_rate > callback and may or may not set the CLK_SET_RATE_PARENT flag. ?Having > a .set_rate implemenation does preclude one from propagating the rate > change up the tree, so it is possible to adjust the divider to a new > rate AND still kick the rate change request up to the parent, 'mux'. > In your case 'mux' should probably not set CLK_SET_RATE_PARENT and the > propagation will end there. ?'mux' might implement a re-parenting > operation as part of it's .set_rate implementation. > > This is covered fairly well in Documentation/clk.txt > >> If the order were instead mux->gate->divider, would it be correct for >> enable/disable to propagate from the divider to the gate? >> > > Correct. ?Order doesn't matter. ?Even in the absence of a > .prepare/.enable callback the framework will still propagate these > changes as part of typical use-counting rules. > >>>> 2) how to define the default parent? in many cases the hw reset value isn't >>>> ? ?a very sensible choice, so the kernel probably needs to set a parent of >>>> ? ?many of them if we don't want to rely on bootloader configuration. >>> >>> The only related thing handled at the framework level is _discovery_ of >>> the parent during clock registration/initialization. ?If you don't trust >>> the bootloader and want to set things up as soon as possible (a wise >>> move) then I suggest you do so from your platform clock code at the same >>> time that you register your clocks with the framework. ?Something like: >>> >>> ? ? ? struct clk *c; >>> ? ? ? c = clk_register(...); >>> ? ? ? if (IS_ERR(c)) >>> ? ? ? ? ? ? ? omg_fail(); >>> ? ? ? clk_set_parent(c, b); >>> >>> Where 'b' is a parent of 'c'. ?Register your clock tree top-down and you >>> can re-parent as you go. >> >> I'm hoping we can represent this in device tree somehow, so that >> individual boards can set the clock tree up differently depending on >> their needs (e.g. Tegra20 doesn't have quite enough PLLs, so sometimes a >> particular PLL will be used to generate the 2nd display's pixel clock, >> whereas on other boards it may be used for some peripherals). So, we'd >> like to describe this in DT. >> >> It seems like it'd be pretty common to want the kernel to fully >> initialize the clock tree, and to do this from device tree, so perhaps >> this might evolve into a common (part of) a cross-SoC clock binding, or >> some kind of utility function that parsed a clock-tree-init-table from DT? > > As long as the configuration of your clocks can be expressed by the > existing clk api, e.g. clk_prepare / clk_enable / clk_set_rate / > clk_set_parent, then I think it would be easy to define a format > whereby the clock is configured immediately after being registered. > Essentially it would do what I outline in my original email above, but > the configuration could be encoded into DT. > > Any platform-specific clock configuration (bits that aren't obviously > expressed by the clk.h api) will be harder to configure through > generic DT bindings. > > Regards, > Mike > > _______________________________________________ > linux-arm-kernel mailing list > linux-arm-kernel at lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel -- Zhoujie Wu ^ permalink raw reply [flat|nested] 26+ messages in thread
* moving Tegra30 to the common clock framework 2012-05-08 5:07 ` zhoujie wu @ 2012-05-08 17:15 ` Turquette, Mike 2012-05-09 0:41 ` Saravana Kannan 0 siblings, 1 reply; 26+ messages in thread From: Turquette, Mike @ 2012-05-08 17:15 UTC (permalink / raw) To: linux-arm-kernel On Mon, May 7, 2012 at 10:07 PM, zhoujie wu <zhoujiewu@gmail.com> wrote: > Hi Mike, > Could you please explain more details about how to implement a > re-parenting operation as part of it's .set_rate implementation? Sure. > As far as I know, we can not call clk_set_parent in .set_rate function > directly, since clk_set_rate and clk_set_parent are using the same > prepare_lock. That is correct. > Any other interface can be used to implement it? You have two options available to you. 1) __clk_reparent can be used from your .set_rate callback today to reflect changes made to the tree topology. OMAP uses this in our PLL .set_rate implementation: depending on the re-lock frequency the PLL may switch parents dynamically. __clk_reparent does the framework-level cleanup needed for this (that function is also used when populating the clock tree with new clock nodes). 2) __clk_set_parent could be made non-static if you needed this (I've been meaning to talk to Saravana about this since I think MSM needs something like this). This is not done today but perhaps you can experiment with it and let me know what you find? If you stare at the code for a while I'm sure you'll see how it comes together. If any infrastructure that you require is missing please let me know. Regards, Mike > Thanks. > > 2012/5/8 Turquette, Mike <mturquette@ti.com>: >> On Mon, May 7, 2012 at 8:39 AM, Stephen Warren <swarren@wwwdotorg.org> wrote: >>> On 05/06/2012 06:03 PM, Mike Turquette wrote: >>>> On 20120503-19:13, Peter De Schrijver wrote: >>>>> Hi, >>>>> >>>>> I started looking into what would be needed to move our tegra30 clock code >>>>> to the common clock framework. The tegra30 clocktree is rather flat. Basically >>>>> there are a bunch of sources (13 PLLs, external audio clocks, osc and 32Khz) >>>>> and peripheral clocks which have a mux (with 4 or more inputs), a divider and >>>>> a gate. So almost every peripheral clock can have multiple parents. >>>>> >>>>> Some questions: >>>>> >>>>> 1) should these peripheral clocks be modelled as 3 different clocks >>>>> ? ?(mux -> divider -> gate) or would it be better to make a new clock type for >>>>> ? ?this? >>>>> >>>> >>>> That is really for you to decide. ?If the semantics of the existing mux, >>>> divider and gate in drivers/clk/clk-*.c work well for you then I think >>>> the answer is "yes". ?There is infrastructure for register-access >>>> locking in those common types which might help your complex clocks. >>>> >>>> Thanks to the parent rate propagation stuff in clk_set_rate it should be >>>> possible for your drivers to only be aware of the gate and call >>>> clk_set_rate on only that clock, which propagates up to the divider and, >>>> if necessary, again propagates up to the mux. >>>> >>>> I encourage you to try that first. ?But if you find the semantics of >>>> those basic clock types aren't cutting it for you then you must create a >>>> type which is platform-specific. >>> >>> A lot of these mux/divider/gate clocks go out to peripherals, whose >>> drivers want to call both clk_set_rate() and clk_en/disable() on the clock. >>> >>> There's only 1 clock reaching the peripheral in HW, so the driver should >>> only call clk_get() once, and similarly the DT should only provide a >>> single clock to the driver. >>> >> >> Sounds good so far. >> >>> Given the mux->divider->gate clock construction, that clock would >>> presumably be the gate object. clk_en/disable() clearly work there, but >>> is clk_set_rate() intended to propagate up the chain until it can be >>> satisfied, i.e. does the gate clock object's set_rate() op simply call >>> the parent's set_rate() op? >>> >> >> Only if you set the CLK_SET_RATE_PARENT flag on the children. ?Take >> the following example sub-tree: >> >> mux >> ?| >> div >> ?| >> gate >> >> If gate does NOT have CLK_SET_RATE_PARENT set in struct clk->flags >> then clk_set_rate will do nothing (since it does not implement a >> .set_rate callback). ?If the flag is set then the framework will kick >> the rate request up to the parent, 'div'. ?Div implements a .set_rate >> callback and may or may not set the CLK_SET_RATE_PARENT flag. ?Having >> a .set_rate implemenation does preclude one from propagating the rate >> change up the tree, so it is possible to adjust the divider to a new >> rate AND still kick the rate change request up to the parent, 'mux'. >> In your case 'mux' should probably not set CLK_SET_RATE_PARENT and the >> propagation will end there. ?'mux' might implement a re-parenting >> operation as part of it's .set_rate implementation. >> >> This is covered fairly well in Documentation/clk.txt >> >>> If the order were instead mux->gate->divider, would it be correct for >>> enable/disable to propagate from the divider to the gate? >>> >> >> Correct. ?Order doesn't matter. ?Even in the absence of a >> .prepare/.enable callback the framework will still propagate these >> changes as part of typical use-counting rules. >> >>>>> 2) how to define the default parent? in many cases the hw reset value isn't >>>>> ? ?a very sensible choice, so the kernel probably needs to set a parent of >>>>> ? ?many of them if we don't want to rely on bootloader configuration. >>>> >>>> The only related thing handled at the framework level is _discovery_ of >>>> the parent during clock registration/initialization. ?If you don't trust >>>> the bootloader and want to set things up as soon as possible (a wise >>>> move) then I suggest you do so from your platform clock code at the same >>>> time that you register your clocks with the framework. ?Something like: >>>> >>>> ? ? ? struct clk *c; >>>> ? ? ? c = clk_register(...); >>>> ? ? ? if (IS_ERR(c)) >>>> ? ? ? ? ? ? ? omg_fail(); >>>> ? ? ? clk_set_parent(c, b); >>>> >>>> Where 'b' is a parent of 'c'. ?Register your clock tree top-down and you >>>> can re-parent as you go. >>> >>> I'm hoping we can represent this in device tree somehow, so that >>> individual boards can set the clock tree up differently depending on >>> their needs (e.g. Tegra20 doesn't have quite enough PLLs, so sometimes a >>> particular PLL will be used to generate the 2nd display's pixel clock, >>> whereas on other boards it may be used for some peripherals). So, we'd >>> like to describe this in DT. >>> >>> It seems like it'd be pretty common to want the kernel to fully >>> initialize the clock tree, and to do this from device tree, so perhaps >>> this might evolve into a common (part of) a cross-SoC clock binding, or >>> some kind of utility function that parsed a clock-tree-init-table from DT? >> >> As long as the configuration of your clocks can be expressed by the >> existing clk api, e.g. clk_prepare / clk_enable / clk_set_rate / >> clk_set_parent, then I think it would be easy to define a format >> whereby the clock is configured immediately after being registered. >> Essentially it would do what I outline in my original email above, but >> the configuration could be encoded into DT. >> >> Any platform-specific clock configuration (bits that aren't obviously >> expressed by the clk.h api) will be harder to configure through >> generic DT bindings. >> >> Regards, >> Mike >> >> _______________________________________________ >> linux-arm-kernel mailing list >> linux-arm-kernel at lists.infradead.org >> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel > > > > -- > Zhoujie Wu ^ permalink raw reply [flat|nested] 26+ messages in thread
* moving Tegra30 to the common clock framework 2012-05-08 17:15 ` Turquette, Mike @ 2012-05-09 0:41 ` Saravana Kannan 2012-05-09 2:20 ` skannan at codeaurora.org 2012-05-09 10:36 ` Peter De Schrijver 0 siblings, 2 replies; 26+ messages in thread From: Saravana Kannan @ 2012-05-09 0:41 UTC (permalink / raw) To: linux-arm-kernel On 05/08/2012 10:15 AM, Turquette, Mike wrote: > On Mon, May 7, 2012 at 10:07 PM, zhoujie wu<zhoujiewu@gmail.com> wrote: >> Hi Mike, >> Could you please explain more details about how to implement a >> re-parenting operation as part of it's .set_rate implementation? > > Sure. > >> As far as I know, we can not call clk_set_parent in .set_rate function >> directly, since clk_set_rate and clk_set_parent are using the same >> prepare_lock. > > That is correct. > >> Any other interface can be used to implement it? > > You have two options available to you. > > 1) __clk_reparent can be used from your .set_rate callback today to > reflect changes made to the tree topology. OMAP uses this in our PLL > .set_rate implementation: depending on the re-lock frequency the PLL > may switch parents dynamically. __clk_reparent does the > framework-level cleanup needed for this (that function is also used > when populating the clock tree with new clock nodes). > > 2) __clk_set_parent could be made non-static if you needed this (I've > been meaning to talk to Saravana about this since I think MSM needs > something like this). Thanks! I don't think I need (2). But I don't think I can use (1) as is either. I can use (1) with some additional code in my set rate op. While set rate is in progress, both the parents might need to stay enabled for a short duration. So, in my internal set rate, I need to check if my clock is prepared/enabled and call prepare/enable on the "old parent", call __clk_reparent (which will reduce the ref count for the old parents and increase it for the new parents), finish the reparent in HW and then unprepare/disable the old parent if I have prepared/enabled them earlier. It might be beneficial to provide something like a __clk_reparent_start(new_parent, *scratch_pointer) and __clk_reparent_finish(*scratch_pointer) if it will be useful for more than just MSM. Based on this email, I would guess that Tegra would want something similar too. Thanks, Saravana -- Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum. ^ permalink raw reply [flat|nested] 26+ messages in thread
* moving Tegra30 to the common clock framework 2012-05-09 0:41 ` Saravana Kannan @ 2012-05-09 2:20 ` skannan at codeaurora.org 2012-05-09 6:21 ` Turquette, Mike 2012-05-09 10:36 ` Peter De Schrijver 1 sibling, 1 reply; 26+ messages in thread From: skannan at codeaurora.org @ 2012-05-09 2:20 UTC (permalink / raw) To: linux-arm-kernel > On 05/08/2012 10:15 AM, Turquette, Mike wrote: >> On Mon, May 7, 2012 at 10:07 PM, zhoujie wu<zhoujiewu@gmail.com> wrote: >>> Hi Mike, >>> Could you please explain more details about how to implement a >>> re-parenting operation as part of it's .set_rate implementation? >> >> Sure. >> >>> As far as I know, we can not call clk_set_parent in .set_rate function >>> directly, since clk_set_rate and clk_set_parent are using the same >>> prepare_lock. >> >> That is correct. >> >>> Any other interface can be used to implement it? >> >> You have two options available to you. >> >> 1) __clk_reparent can be used from your .set_rate callback today to >> reflect changes made to the tree topology. OMAP uses this in our PLL >> .set_rate implementation: depending on the re-lock frequency the PLL >> may switch parents dynamically. __clk_reparent does the >> framework-level cleanup needed for this (that function is also used >> when populating the clock tree with new clock nodes). >> >> 2) __clk_set_parent could be made non-static if you needed this (I've >> been meaning to talk to Saravana about this since I think MSM needs >> something like this). > > Thanks! > > I don't think I need (2). But I don't think I can use (1) as is either. > I can use (1) with some additional code in my set rate op. > > While set rate is in progress, both the parents might need to stay > enabled for a short duration. So, in my internal set rate, I need to > check if my clock is prepared/enabled and call prepare/enable on the > "old parent", call __clk_reparent (which will reduce the ref count for > the old parents and increase it for the new parents), finish the > reparent in HW and then unprepare/disable the old parent if I have > prepared/enabled them earlier. > > It might be beneficial to provide something like a > __clk_reparent_start(new_parent, *scratch_pointer) and > __clk_reparent_finish(*scratch_pointer) if it will be useful for more > than just MSM. Based on this email, I would guess that Tegra would want > something similar too. Thinking more about this, I think this is how any clk op that might change the parent should operate. I will try to write up an RFC patch for this and send it out soon. I'm in a hurry, so will explain more in the RFC patch or in a later email. Thanks, Saravana -- Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum. ^ permalink raw reply [flat|nested] 26+ messages in thread
* moving Tegra30 to the common clock framework 2012-05-09 2:20 ` skannan at codeaurora.org @ 2012-05-09 6:21 ` Turquette, Mike 2012-05-10 0:02 ` Saravana Kannan 0 siblings, 1 reply; 26+ messages in thread From: Turquette, Mike @ 2012-05-09 6:21 UTC (permalink / raw) To: linux-arm-kernel On 20120508-19:20, skannan at codeaurora.org wrote: > > While set rate is in progress, both the parents might need to stay > > enabled for a short duration. So, in my internal set rate, I need to > > check if my clock is prepared/enabled and call prepare/enable on the > > "old parent", call __clk_reparent (which will reduce the ref count for > > the old parents and increase it for the new parents), finish the > > reparent in HW and then unprepare/disable the old parent if I have > > prepared/enabled them earlier. > > The .set_rate implemenation for OMAP's PLLs has the same requirement and this is handled by nested calls to __clk_prepare and clk_enable. Please refer the omap3_noncore_dpll_set_rate definition: http://git.linaro.org/gitweb?p=people/mturquette/linux.git;a=blob;f=arch/arm/mach-omap2/dpll3xxx.c;h=63e92e2d4bb80ea702572b919c17b0ac9f93cc0e;hb=clk-next-omap#l425 > > It might be beneficial to provide something like a > > __clk_reparent_start(new_parent, *scratch_pointer) and > > __clk_reparent_finish(*scratch_pointer) if it will be useful for more > > than just MSM. Based on this email, I would guess that Tegra would want > > something similar too. > > Thinking more about this, I think this is how any clk op that might change > the parent should operate. I will try to write up an RFC patch for this > and send it out soon. I'm in a hurry, so will explain more in the RFC > patch or in a later email. I'm interested to see your patch, as I might not be fully understanding your requirements. Is there any reason why making nested calls to __clk_prepare and clk_enable from your .set_rate callback isn't enough? Thanks, Mike ^ permalink raw reply [flat|nested] 26+ messages in thread
* moving Tegra30 to the common clock framework 2012-05-09 6:21 ` Turquette, Mike @ 2012-05-10 0:02 ` Saravana Kannan 0 siblings, 0 replies; 26+ messages in thread From: Saravana Kannan @ 2012-05-10 0:02 UTC (permalink / raw) To: linux-arm-kernel On 05/08/2012 11:21 PM, Turquette, Mike wrote: > On 20120508-19:20, skannan at codeaurora.org wrote: >>> It might be beneficial to provide something like a >>> __clk_reparent_start(new_parent, *scratch_pointer) and >>> __clk_reparent_finish(*scratch_pointer) if it will be useful for more >>> than just MSM. Based on this email, I would guess that Tegra would want >>> something similar too. >> >> Thinking more about this, I think this is how any clk op that might change >> the parent should operate. I will try to write up an RFC patch for this >> and send it out soon. I'm in a hurry, so will explain more in the RFC >> patch or in a later email. > > I'm interested to see your patch, as I might not be fully understanding > your requirements. Is there any reason why making nested calls to > __clk_prepare and clk_enable from your .set_rate callback isn't enough? > Sorry if I wasn't clear -- my plan with the current framework IS to make nested (as in, inside the set rate op) calls to __clk_prepare() and enable() as needed. But my point is that everyone really wants to do the same, so we might as well make it better by putting it in the common code and having everyone use it instead of having to redo the same code all over the place. Will send out the patch soon. -Saravana -- Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum. ^ permalink raw reply [flat|nested] 26+ messages in thread
* moving Tegra30 to the common clock framework 2012-05-09 0:41 ` Saravana Kannan 2012-05-09 2:20 ` skannan at codeaurora.org @ 2012-05-09 10:36 ` Peter De Schrijver 2012-05-12 2:58 ` Saravana Kannan 1 sibling, 1 reply; 26+ messages in thread From: Peter De Schrijver @ 2012-05-09 10:36 UTC (permalink / raw) To: linux-arm-kernel On Wed, May 09, 2012 at 02:41:37AM +0200, Saravana Kannan wrote: > On 05/08/2012 10:15 AM, Turquette, Mike wrote: > > On Mon, May 7, 2012 at 10:07 PM, zhoujie wu<zhoujiewu@gmail.com> wrote: > >> Hi Mike, > >> Could you please explain more details about how to implement a > >> re-parenting operation as part of it's .set_rate implementation? > > > > Sure. > > > >> As far as I know, we can not call clk_set_parent in .set_rate function > >> directly, since clk_set_rate and clk_set_parent are using the same > >> prepare_lock. > > > > That is correct. > > > >> Any other interface can be used to implement it? > > > > You have two options available to you. > > > > 1) __clk_reparent can be used from your .set_rate callback today to > > reflect changes made to the tree topology. OMAP uses this in our PLL > > .set_rate implementation: depending on the re-lock frequency the PLL > > may switch parents dynamically. __clk_reparent does the > > framework-level cleanup needed for this (that function is also used > > when populating the clock tree with new clock nodes). > > > > 2) __clk_set_parent could be made non-static if you needed this (I've > > been meaning to talk to Saravana about this since I think MSM needs > > something like this). > > Thanks! > > I don't think I need (2). But I don't think I can use (1) as is either. > I can use (1) with some additional code in my set rate op. > > While set rate is in progress, both the parents might need to stay > enabled for a short duration. So, in my internal set rate, I need to > check if my clock is prepared/enabled and call prepare/enable on the > "old parent", call __clk_reparent (which will reduce the ref count for > the old parents and increase it for the new parents), finish the > reparent in HW and then unprepare/disable the old parent if I have > prepared/enabled them earlier. > > It might be beneficial to provide something like a > __clk_reparent_start(new_parent, *scratch_pointer) and > __clk_reparent_finish(*scratch_pointer) if it will be useful for more > than just MSM. Based on this email, I would guess that Tegra would want > something similar too. > We also need to reparent clocks using a pll if we want to change the PLLs rate while the users are active. Cheers, Peter. ^ permalink raw reply [flat|nested] 26+ messages in thread
* moving Tegra30 to the common clock framework 2012-05-09 10:36 ` Peter De Schrijver @ 2012-05-12 2:58 ` Saravana Kannan 2012-05-13 4:31 ` Stephen Warren 2012-05-14 21:36 ` Turquette, Mike 0 siblings, 2 replies; 26+ messages in thread From: Saravana Kannan @ 2012-05-12 2:58 UTC (permalink / raw) To: linux-arm-kernel On 05/09/2012 03:36 AM, Peter De Schrijver wrote: > On Wed, May 09, 2012 at 02:41:37AM +0200, Saravana Kannan wrote: >> On 05/08/2012 10:15 AM, Turquette, Mike wrote: >>> On Mon, May 7, 2012 at 10:07 PM, zhoujie wu<zhoujiewu@gmail.com> wrote: >>>> Hi Mike, >>>> Could you please explain more details about how to implement a >>>> re-parenting operation as part of it's .set_rate implementation? >>> >>> Sure. >>> >>>> As far as I know, we can not call clk_set_parent in .set_rate function >>>> directly, since clk_set_rate and clk_set_parent are using the same >>>> prepare_lock. >>> >>> That is correct. >>> >>>> Any other interface can be used to implement it? >>> >>> You have two options available to you. >>> >>> 1) __clk_reparent can be used from your .set_rate callback today to >>> reflect changes made to the tree topology. OMAP uses this in our PLL >>> .set_rate implementation: depending on the re-lock frequency the PLL >>> may switch parents dynamically. __clk_reparent does the >>> framework-level cleanup needed for this (that function is also used >>> when populating the clock tree with new clock nodes). >>> >>> 2) __clk_set_parent could be made non-static if you needed this (I've >>> been meaning to talk to Saravana about this since I think MSM needs >>> something like this). >> >> Thanks! >> >> I don't think I need (2). But I don't think I can use (1) as is either. >> I can use (1) with some additional code in my set rate op. >> >> While set rate is in progress, both the parents might need to stay >> enabled for a short duration. So, in my internal set rate, I need to >> check if my clock is prepared/enabled and call prepare/enable on the >> "old parent", call __clk_reparent (which will reduce the ref count for >> the old parents and increase it for the new parents), finish the >> reparent in HW and then unprepare/disable the old parent if I have >> prepared/enabled them earlier. >> >> It might be beneficial to provide something like a >> __clk_reparent_start(new_parent, *scratch_pointer) and >> __clk_reparent_finish(*scratch_pointer) if it will be useful for more >> than just MSM. Based on this email, I would guess that Tegra would want >> something similar too. >> > > We also need to reparent clocks using a pll if we want to change the PLLs rate > while the users are active. Peter, Is this reparent permanent (as in, stays reparented when you return from clk_set_rate()) or is it a reparenting for just a short duration inside the set_rate ops? If it's the latter, I don't think you would need any helper code in clock framework other than the already existing __clk_prepare() and clk_enable(). Just turn on the temp parent, reparent to it, do whatever you need to do, and go back to your original parent. If it's the former (permanent reparent), can I assume that the CLK_SET_RATE_PARENT flag won't be set for this clock? Otherwise, it's going to be quite yucky/convoluted. I'm not sure how well a reparent would work with the code in common clock framwework that walks up the parents to propagate the rate change to them. I wouldn't say that it's wrong to only want to propagate the rate for certain rates and for certain parents, but I will have to stare at the common clock code for a while. Mike, I was looking at the code to make the changes and I noticed this snippet (reformatted for email) in clk_change_rate(): if (clk->ops->set_rate) clk->ops->set_rate(clk->hw, clk->new_rate, clk->parent->rate); if (clk->ops->recalc_rate) clk->rate = clk->ops->recalc_rate(clk->hw, clk->parent->rate); else clk->rate = clk->parent->rate; I'm a bit confused. I thought recalc_rates was optional. But if I don't implement it, the clocks rate will get set to parent's rate? Or is that a bug in the code? Also, if the clock's rate was just set with set_rate, why do we need to recalc the rate by reading hardware? I'm a bit confused. Can you please clarify what's going on here? Would you mind adding more comments inside clk_calc_new_rates() and clk_change_rate() trying to explain what cases you are trying to account for? Also, in clk_calc_new_rates(), if (!clk->ops->round_rate) { top = clk_calc_new_rates(clk->parent, rate); new_rate = clk->parent->new_rate; goto out; } Is the code assuming that if there is no round rate ops that that clock node is only a gating clock (as in, can't change frequency the input freq)? Just trying to understand the assumptions made in the code. Thanks, Saravana -- Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum. ^ permalink raw reply [flat|nested] 26+ messages in thread
* moving Tegra30 to the common clock framework 2012-05-12 2:58 ` Saravana Kannan @ 2012-05-13 4:31 ` Stephen Warren 2012-05-14 11:08 ` Peter De Schrijver 2012-05-14 21:36 ` Turquette, Mike 1 sibling, 1 reply; 26+ messages in thread From: Stephen Warren @ 2012-05-13 4:31 UTC (permalink / raw) To: linux-arm-kernel On 05/11/2012 08:58 PM, Saravana Kannan wrote: > On 05/09/2012 03:36 AM, Peter De Schrijver wrote: >> On Wed, May 09, 2012 at 02:41:37AM +0200, Saravana Kannan wrote: >>> On 05/08/2012 10:15 AM, Turquette, Mike wrote: >>>> On Mon, May 7, 2012 at 10:07 PM, zhoujie wu<zhoujiewu@gmail.com> >>>> wrote: >>>>> Hi Mike, >>>>> Could you please explain more details about how to implement a >>>>> re-parenting operation as part of it's .set_rate implementation? >>>> >>>> Sure. >>>> >>>>> As far as I know, we can not call clk_set_parent in .set_rate function >>>>> directly, since clk_set_rate and clk_set_parent are using the same >>>>> prepare_lock. >>>> >>>> That is correct. >>>> >>>>> Any other interface can be used to implement it? >>>> >>>> You have two options available to you. >>>> >>>> 1) __clk_reparent can be used from your .set_rate callback today to >>>> reflect changes made to the tree topology. OMAP uses this in our PLL >>>> .set_rate implementation: depending on the re-lock frequency the PLL >>>> may switch parents dynamically. __clk_reparent does the >>>> framework-level cleanup needed for this (that function is also used >>>> when populating the clock tree with new clock nodes). >>>> >>>> 2) __clk_set_parent could be made non-static if you needed this (I've >>>> been meaning to talk to Saravana about this since I think MSM needs >>>> something like this). >>> >>> Thanks! >>> >>> I don't think I need (2). But I don't think I can use (1) as is either. >>> I can use (1) with some additional code in my set rate op. >>> >>> While set rate is in progress, both the parents might need to stay >>> enabled for a short duration. So, in my internal set rate, I need to >>> check if my clock is prepared/enabled and call prepare/enable on the >>> "old parent", call __clk_reparent (which will reduce the ref count for >>> the old parents and increase it for the new parents), finish the >>> reparent in HW and then unprepare/disable the old parent if I have >>> prepared/enabled them earlier. >>> >>> It might be beneficial to provide something like a >>> __clk_reparent_start(new_parent, *scratch_pointer) and >>> __clk_reparent_finish(*scratch_pointer) if it will be useful for more >>> than just MSM. Based on this email, I would guess that Tegra would want >>> something similar too. >>> >> >> We also need to reparent clocks using a pll if we want to change the >> PLLs rate >> while the users are active. > > Peter, > > Is this reparent permanent (as in, stays reparented when you return from > clk_set_rate()) or is it a reparenting for just a short duration inside > the set_rate ops? I've seen both cases, and indeed the case sometimes depends on the target rate of the clock. For example, when the CPU clock changes, we basically do the following within set_rate: * Set CPU clock parent to some "backup" PLL * Change the CPU PLL to the desired rate * Set CPU clock parent to the CPU PLL However, the lowest CPU clock rate we support is actually the rate that the backup PLL runs at, so if we're targeting that rate, the CPU clock set_rate /just/ does: * Set CPU clock parent to some "backup" PLL and leaves it there, until a different CPU clock rate is requested, at which time the CPU clock will be re-parented back to the CPU PLL. ^ permalink raw reply [flat|nested] 26+ messages in thread
* moving Tegra30 to the common clock framework 2012-05-13 4:31 ` Stephen Warren @ 2012-05-14 11:08 ` Peter De Schrijver 2012-05-15 0:10 ` Saravana Kannan 0 siblings, 1 reply; 26+ messages in thread From: Peter De Schrijver @ 2012-05-14 11:08 UTC (permalink / raw) To: linux-arm-kernel On Sun, May 13, 2012 at 06:31:42AM +0200, Stephen Warren wrote: > On 05/11/2012 08:58 PM, Saravana Kannan wrote: > > On 05/09/2012 03:36 AM, Peter De Schrijver wrote: > >> On Wed, May 09, 2012 at 02:41:37AM +0200, Saravana Kannan wrote: > >>> On 05/08/2012 10:15 AM, Turquette, Mike wrote: > >>>> On Mon, May 7, 2012 at 10:07 PM, zhoujie wu<zhoujiewu@gmail.com> > >>>> wrote: > >>>>> Hi Mike, > >>>>> Could you please explain more details about how to implement a > >>>>> re-parenting operation as part of it's .set_rate implementation? > >>>> > >>>> Sure. > >>>> > >>>>> As far as I know, we can not call clk_set_parent in .set_rate function > >>>>> directly, since clk_set_rate and clk_set_parent are using the same > >>>>> prepare_lock. > >>>> > >>>> That is correct. > >>>> > >>>>> Any other interface can be used to implement it? > >>>> > >>>> You have two options available to you. > >>>> > >>>> 1) __clk_reparent can be used from your .set_rate callback today to > >>>> reflect changes made to the tree topology. OMAP uses this in our PLL > >>>> .set_rate implementation: depending on the re-lock frequency the PLL > >>>> may switch parents dynamically. __clk_reparent does the > >>>> framework-level cleanup needed for this (that function is also used > >>>> when populating the clock tree with new clock nodes). > >>>> > >>>> 2) __clk_set_parent could be made non-static if you needed this (I've > >>>> been meaning to talk to Saravana about this since I think MSM needs > >>>> something like this). > >>> > >>> Thanks! > >>> > >>> I don't think I need (2). But I don't think I can use (1) as is either. > >>> I can use (1) with some additional code in my set rate op. > >>> > >>> While set rate is in progress, both the parents might need to stay > >>> enabled for a short duration. So, in my internal set rate, I need to > >>> check if my clock is prepared/enabled and call prepare/enable on the > >>> "old parent", call __clk_reparent (which will reduce the ref count for > >>> the old parents and increase it for the new parents), finish the > >>> reparent in HW and then unprepare/disable the old parent if I have > >>> prepared/enabled them earlier. > >>> > >>> It might be beneficial to provide something like a > >>> __clk_reparent_start(new_parent, *scratch_pointer) and > >>> __clk_reparent_finish(*scratch_pointer) if it will be useful for more > >>> than just MSM. Based on this email, I would guess that Tegra would want > >>> something similar too. > >>> > >> > >> We also need to reparent clocks using a pll if we want to change the > >> PLLs rate > >> while the users are active. > > > > Peter, > > > > Is this reparent permanent (as in, stays reparented when you return from > > clk_set_rate()) or is it a reparenting for just a short duration inside > > the set_rate ops? > > I've seen both cases, and indeed the case sometimes depends on the > target rate of the clock. > > For example, when the CPU clock changes, we basically do the following > within set_rate: > > * Set CPU clock parent to some "backup" PLL > * Change the CPU PLL to the desired rate > * Set CPU clock parent to the CPU PLL > > However, the lowest CPU clock rate we support is actually the rate that > the backup PLL runs at, so if we're targeting that rate, the CPU clock > set_rate /just/ does: > > * Set CPU clock parent to some "backup" PLL > > and leaves it there, until a different CPU clock rate is requested, at > which time the CPU clock will be re-parented back to the CPU PLL. The backup PLL and rate are statically defined however. It's not chosen at runtime. Cheers, Peter. ^ permalink raw reply [flat|nested] 26+ messages in thread
* moving Tegra30 to the common clock framework 2012-05-14 11:08 ` Peter De Schrijver @ 2012-05-15 0:10 ` Saravana Kannan 0 siblings, 0 replies; 26+ messages in thread From: Saravana Kannan @ 2012-05-15 0:10 UTC (permalink / raw) To: linux-arm-kernel On 05/14/2012 04:08 AM, Peter De Schrijver wrote: > On Sun, May 13, 2012 at 06:31:42AM +0200, Stephen Warren wrote: >> On 05/11/2012 08:58 PM, Saravana Kannan wrote: >>> On 05/09/2012 03:36 AM, Peter De Schrijver wrote: >>>> On Wed, May 09, 2012 at 02:41:37AM +0200, Saravana Kannan wrote: >>>>> On 05/08/2012 10:15 AM, Turquette, Mike wrote: >>>>>> On Mon, May 7, 2012 at 10:07 PM, zhoujie wu<zhoujiewu@gmail.com> >>>>>> wrote: >>>>>>> Hi Mike, >>>>>>> Could you please explain more details about how to implement a >>>>>>> re-parenting operation as part of it's .set_rate implementation? >>>>>> >>>>>> Sure. >>>>>> >>>>>>> As far as I know, we can not call clk_set_parent in .set_rate function >>>>>>> directly, since clk_set_rate and clk_set_parent are using the same >>>>>>> prepare_lock. >>>>>> >>>>>> That is correct. >>>>>> >>>>>>> Any other interface can be used to implement it? >>>>>> >>>>>> You have two options available to you. >>>>>> >>>>>> 1) __clk_reparent can be used from your .set_rate callback today to >>>>>> reflect changes made to the tree topology. OMAP uses this in our PLL >>>>>> .set_rate implementation: depending on the re-lock frequency the PLL >>>>>> may switch parents dynamically. __clk_reparent does the >>>>>> framework-level cleanup needed for this (that function is also used >>>>>> when populating the clock tree with new clock nodes). >>>>>> >>>>>> 2) __clk_set_parent could be made non-static if you needed this (I've >>>>>> been meaning to talk to Saravana about this since I think MSM needs >>>>>> something like this). >>>>> >>>>> Thanks! >>>>> >>>>> I don't think I need (2). But I don't think I can use (1) as is either. >>>>> I can use (1) with some additional code in my set rate op. >>>>> >>>>> While set rate is in progress, both the parents might need to stay >>>>> enabled for a short duration. So, in my internal set rate, I need to >>>>> check if my clock is prepared/enabled and call prepare/enable on the >>>>> "old parent", call __clk_reparent (which will reduce the ref count for >>>>> the old parents and increase it for the new parents), finish the >>>>> reparent in HW and then unprepare/disable the old parent if I have >>>>> prepared/enabled them earlier. >>>>> >>>>> It might be beneficial to provide something like a >>>>> __clk_reparent_start(new_parent, *scratch_pointer) and >>>>> __clk_reparent_finish(*scratch_pointer) if it will be useful for more >>>>> than just MSM. Based on this email, I would guess that Tegra would want >>>>> something similar too. >>>>> >>>> >>>> We also need to reparent clocks using a pll if we want to change the >>>> PLLs rate >>>> while the users are active. >>> >>> Peter, >>> >>> Is this reparent permanent (as in, stays reparented when you return from >>> clk_set_rate()) or is it a reparenting for just a short duration inside >>> the set_rate ops? >> >> I've seen both cases, and indeed the case sometimes depends on the >> target rate of the clock. >> >> For example, when the CPU clock changes, we basically do the following >> within set_rate: >> >> * Set CPU clock parent to some "backup" PLL >> * Change the CPU PLL to the desired rate >> * Set CPU clock parent to the CPU PLL >> >> However, the lowest CPU clock rate we support is actually the rate that >> the backup PLL runs at, so if we're targeting that rate, the CPU clock >> set_rate /just/ does: >> >> * Set CPU clock parent to some "backup" PLL >> >> and leaves it there, until a different CPU clock rate is requested, at >> which time the CPU clock will be re-parented back to the CPU PLL. > > The backup PLL and rate are statically defined however. It's not chosen at > runtime. Yeah, this is pretty much what MSM has been doing for a while for our CPU clocks too. But in MSM we made the decision of not to control the CPU clocks through the clock APIs. It makes your life so much more easier. Really, the CPU clocks are very different from the rest of the clocks -- the set rate operation of the clock needs the clock to be running. We also never disable the CPU clock we are running on. Just that it might not be as useful as it might appear. It was especially hard when we didn't have clk_prepare/_unprepare(). Anyway, not saying this is the only way to proceed or using the clock APIs to control the CPU clock is wrong. Just some food for thought. Anyway, getting back to the point of this thread, you might look at the other email I sent out on Friday [1]. Sorry I forgot to cc you on that. I have a list of people I copy paste when sending clock patches. I can add you to that list if you want (or remove anyone who is annoyed by it). If you are doing the parent management inside the .set_rate ops, I believe you will have a race condition with the current clock framework. We need to update the clock framework to provide more APIs to implement this correctly. I was confused by some code and pinged Mike about it. Now that I understand what the code was trying to do, I think I might be able to clean it up a bit and then fix up set rate support. Thanks, Saravana [1] http://thread.gmane.org/gmane.linux.ports.arm.msm/2655 -- Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum. ^ permalink raw reply [flat|nested] 26+ messages in thread
* moving Tegra30 to the common clock framework 2012-05-12 2:58 ` Saravana Kannan 2012-05-13 4:31 ` Stephen Warren @ 2012-05-14 21:36 ` Turquette, Mike 2012-05-14 23:48 ` Saravana Kannan 1 sibling, 1 reply; 26+ messages in thread From: Turquette, Mike @ 2012-05-14 21:36 UTC (permalink / raw) To: linux-arm-kernel On Fri, May 11, 2012 at 7:58 PM, Saravana Kannan <skannan@codeaurora.org> wrote: > Mike, > > I was looking at the code to make the changes and I noticed this snippet > (reformatted for email) in clk_change_rate(): > > ? ? ? if (clk->ops->set_rate) > ? ? ? ? ? ? ? ?clk->ops->set_rate(clk->hw, clk->new_rate, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?clk->parent->rate); > > > ? ? ? ?if (clk->ops->recalc_rate) > ? ? ? ? ? ? ? ?clk->rate = clk->ops->recalc_rate(clk->hw, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?clk->parent->rate); > ? ? ? ?else > ? ? ? ? ? ? ? ?clk->rate = clk->parent->rate; > > I'm a bit confused. I thought recalc_rates was optional. But if I don't > implement it, the clocks rate will get set to parent's rate? Or is that a > bug in the code? > It is not a bug. The handsome ascii art in Documentation/clk.txt covers this requirement. I have copy/pasted the relevant bits below for convenience: clock hardware characteristics ----------------------------------------------------------- | gate | change rate | single parent | multiplexer | root | |------|-------------|---------------|-------------|------| ... | | | | | | .recalc_rate | | y | | | | .round_rate | | y | | | | .set_rate | | y | | | | ... | | | | | | ----------------------------------------------------------- The take-away is that a clock that can adjust its rate (eg: implements a .set_rate callback) must also implement .recalc_rate and .round_rate callbacks. > Also, if the clock's rate was just set with set_rate, why do we need to > recalc the rate by reading hardware? I'm a bit confused. Can you please > clarify what's going on here? > This is simply being very cautious. For platforms adjusting dividers with direct register writes this might feel unnecessary. However this strict checking is in anticipation of clock hardware that might not actually output the precise rate passed into .set_rate. In principal this isn't different from how CPUfreq and devfreq drivers inspect rates after requesting them. > Would you mind adding more comments inside clk_calc_new_rates() and > clk_change_rate() trying to explain what cases you are trying to account > for? > Someday I'll have a comment/kerneldoc cleanup session. Things in the clock core are likely to change in the next couple of release cycles which will deprecate some of the kerneldoc making a big cleanup unavoidable. In the mean time are there any other specific question you have for clk_change_rate? > Also, in clk_calc_new_rates(), > > ? ? ? ?if (!clk->ops->round_rate) { > ? ? ? ? ? ? ? ?top = clk_calc_new_rates(clk->parent, rate); > ? ? ? ? ? ? ? ?new_rate = clk->parent->new_rate; > > ? ? ? ? ? ? ? ?goto out; > ? ? ? ?} > > Is the code assuming that if there is no round rate ops that that clock node > is only a gating clock (as in, can't change frequency the input freq)? Just > trying to understand the assumptions made in the code. > This is also covered by the ascii art above. There is no assumption about gating, per se. However if a clock can adjust it's rate (more specifically, if the input rate for a clock differs from the output rate) then a .round_rate callback must exist. The code above reads like it does because in the absence of a .round_rate callback it is implied that the clock cannot set it's own rate and should thus rely on its parent's rate. Regards, Mike > > Thanks, > Saravana > > -- > Sent by an employee of the Qualcomm Innovation Center, Inc. > The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum. ^ permalink raw reply [flat|nested] 26+ messages in thread
* moving Tegra30 to the common clock framework 2012-05-14 21:36 ` Turquette, Mike @ 2012-05-14 23:48 ` Saravana Kannan 2012-05-15 2:00 ` Mike Turquette 0 siblings, 1 reply; 26+ messages in thread From: Saravana Kannan @ 2012-05-14 23:48 UTC (permalink / raw) To: linux-arm-kernel On 05/14/2012 02:36 PM, Turquette, Mike wrote: > On Fri, May 11, 2012 at 7:58 PM, Saravana Kannan<skannan@codeaurora.org> wrote: >> Mike, >> >> I was looking at the code to make the changes and I noticed this snippet >> (reformatted for email) in clk_change_rate(): >> >> if (clk->ops->set_rate) >> clk->ops->set_rate(clk->hw, clk->new_rate, >> clk->parent->rate); >> >> >> if (clk->ops->recalc_rate) >> clk->rate = clk->ops->recalc_rate(clk->hw, >> clk->parent->rate); >> else >> clk->rate = clk->parent->rate; >> >> I'm a bit confused. I thought recalc_rates was optional. But if I don't >> implement it, the clocks rate will get set to parent's rate? Or is that a >> bug in the code? >> > > It is not a bug. The handsome ascii art in Documentation/clk.txt covers > this requirement. I have copy/pasted the relevant bits below for > convenience: > > clock hardware characteristics > ----------------------------------------------------------- > | gate | change rate | single parent | multiplexer | root | > |------|-------------|---------------|-------------|------| > ... > | | | | | | > .recalc_rate | | y | | | | > .round_rate | | y | | | | > .set_rate | | y | | | | > ... > | | | | | | > ----------------------------------------------------------- > > The take-away is that a clock that can adjust its rate (eg: implements a > .set_rate callback) must also implement .recalc_rate and .round_rate > callbacks. I get the round_rate ops part. But I don't see a need to force a recalc_rate ops. Can we just check for the existence of .set_rate() to figure out if the clock will take up the rate of the parent or will output a different rate? > >> Also, if the clock's rate was just set with set_rate, why do we need to >> recalc the rate by reading hardware? I'm a bit confused. Can you please >> clarify what's going on here? >> > > This is simply being very cautious. For platforms adjusting dividers > with direct register writes this might feel unnecessary. However this > strict checking is in anticipation of clock hardware that might not > actually output the precise rate passed into .set_rate. In principal > this isn't different from how CPUfreq and devfreq drivers inspect rates > after requesting them. Sorry, this still doesn't make much sense to me. This essentially means we can't trust the HW to do what we are asking it to do? CPUfreq and devfreq are clients of external clock APIs. That's different from whether the HW will do what the platform driver will ask it to. Even if this unusual HW exists, I certainly don't want to deal with recalc_rate(). It's also quite a bit of register reads that I would like to avoid. I want to keep the clock APIs as fast as I can since it affects power. Can we do something like this in clk_change_rate()? if (ops->set_rate) { ops->set_rate(clk->new_rate,...); clk->rate = clk->new_rate; } else { clk->rate = clk->parent->rate; } if (ops->recalc_rate()) { clk->rate = ops->recalc_rate(...); } This code also makes the assumptions more intuitive and easy to understand. >> Would you mind adding more comments inside clk_calc_new_rates() and >> clk_change_rate() trying to explain what cases you are trying to account >> for? >> > > Someday I'll have a comment/kerneldoc cleanup session. Things in the > clock core are likely to change in the next couple of release cycles > which will deprecate some of the kerneldoc making a big cleanup > unavoidable. > > In the mean time are there any other specific question you have for > clk_change_rate? > >> Also, in clk_calc_new_rates(), >> >> if (!clk->ops->round_rate) { >> top = clk_calc_new_rates(clk->parent, rate); >> new_rate = clk->parent->new_rate; >> >> goto out; >> } >> >> Is the code assuming that if there is no round rate ops that that clock node >> is only a gating clock (as in, can't change frequency the input freq)? Just >> trying to understand the assumptions made in the code. >> > > This is also covered by the ascii art above. There is no assumption > about gating, per se. However if a clock can adjust it's rate (more > specifically, if the input rate for a clock differs from the output > rate) then a .round_rate callback must exist. > > The code above reads like it does because in the absence of a > .round_rate callback it is implied that the clock cannot set it's own > rate and should thus rely on its parent's rate. I agree that anyone implementing .set_rate should also provide .round_rate. May be we should enforce that in clk_init/clk_register? But can we please the above "if" check more explicit? "Your rate has to be same as the parent rate since you don't implement set rate" is clearer than "Your rate has to be the same as the parent rate since you don't implement round rate". if (!clk->ops->set_rate) { top = clk_calc_new_rates(clk->parent, rate); new_rate = clk->parent->new_rate; goto out; } Thanks, Saravana -- Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum. ^ permalink raw reply [flat|nested] 26+ messages in thread
* moving Tegra30 to the common clock framework 2012-05-14 23:48 ` Saravana Kannan @ 2012-05-15 2:00 ` Mike Turquette 2012-05-15 4:20 ` Saravana Kannan 0 siblings, 1 reply; 26+ messages in thread From: Mike Turquette @ 2012-05-15 2:00 UTC (permalink / raw) To: linux-arm-kernel On 20120514-16:48, Saravana Kannan wrote: > On 05/14/2012 02:36 PM, Turquette, Mike wrote: > >On Fri, May 11, 2012 at 7:58 PM, Saravana Kannan<skannan@codeaurora.org> wrote: > >>Mike, > >> > >>I was looking at the code to make the changes and I noticed this snippet > >>(reformatted for email) in clk_change_rate(): > >> > >> if (clk->ops->set_rate) > >> clk->ops->set_rate(clk->hw, clk->new_rate, > >> clk->parent->rate); > >> > >> > >> if (clk->ops->recalc_rate) > >> clk->rate = clk->ops->recalc_rate(clk->hw, > >> clk->parent->rate); > >> else > >> clk->rate = clk->parent->rate; > >> > >>I'm a bit confused. I thought recalc_rates was optional. But if I don't > >>implement it, the clocks rate will get set to parent's rate? Or is that a > >>bug in the code? > >> > > > >It is not a bug. The handsome ascii art in Documentation/clk.txt covers > >this requirement. I have copy/pasted the relevant bits below for > >convenience: > > > > clock hardware characteristics > > ----------------------------------------------------------- > > | gate | change rate | single parent | multiplexer | root | > > |------|-------------|---------------|-------------|------| > > ... > > | | | | | | > >.recalc_rate | | y | | | | > >.round_rate | | y | | | | > >.set_rate | | y | | | | > > ... > > | | | | | | > > ----------------------------------------------------------- > > > >The take-away is that a clock that can adjust its rate (eg: implements a > >.set_rate callback) must also implement .recalc_rate and .round_rate > >callbacks. > > I get the round_rate ops part. But I don't see a need to force a > recalc_rate ops. Can we just check for the existence of .set_rate() > to figure out if the clock will take up the rate of the parent or > will output a different rate? > I think you are forgetting the case where a clock can adjust its output rate but doesn't always have its .set_rate callback called. The trivial example of this is an adjustable divider that is downstream from some parent clock whose rate is being changed. In any such case it is quite necessary to have a .recalc_rate callback on the downstream clock. The sanity checks in __clk_init (and the documenation) make it clear that .recalc_rate callbacks must exist due to this exact scenario. I guess we could leave it up to the implementor to "get it right" and only provide .recalc_rate callbacks for clocks whose parents' rates might change, but why take that risk? > > > >>Also, if the clock's rate was just set with set_rate, why do we need to > >>recalc the rate by reading hardware? I'm a bit confused. Can you please > >>clarify what's going on here? > >> > > > >This is simply being very cautious. For platforms adjusting dividers > >with direct register writes this might feel unnecessary. However this > >strict checking is in anticipation of clock hardware that might not > >actually output the precise rate passed into .set_rate. In principal > >this isn't different from how CPUfreq and devfreq drivers inspect rates > >after requesting them. > > Sorry, this still doesn't make much sense to me. This essentially > means we can't trust the HW to do what we are asking it to do? > My bit about being "cautious" above is not the driving force behind the requirement for implementing .recalc_rate. I thought that you were specifically complaining about calling .recalc_rate AFTER we called .set_rate, in which case my point above stands from the perspective of being future-proof. Your hardware even has a feature to sample it's own frequency at run-time... does that mean your hardware doesn't trust itself? Let's move past the "I don't trust the hardware" bit for a second. It is clear to me in your latest email that you not only think that we should not call .recalc_rate immediately following a call to .set_rate (which is an interesting point to discuss) but you also feel that we should not have a requirement to implement .recalc_rate on clocks that can adjust their rate again. I'll only repeat what I said at the top of this email: for the scenario where an adjustable-rate clock can have a parents' rate change it is absolutely necessary to implement .recalc_rate to correctly determine the chain of rates as we propagate down the tree. That we force this at the framework level is simply good design. I'm willing to discuss removing the (sometimes) redundant .recalc_rate calls immediately following .set_rate (since we basically perform a preemptive .recalc_rate in clk_calc_subtree, called by clk_calc_rates). But to assert that we can entirely remove the requirement to implement .recalc_rates on clocks that support .set_rate sounds insane to me. Please let me know if I've misunderstood what you meant by the statement, "I don't see a need to force a recalc_rate ops". > Can we do something like this in clk_change_rate()? > > if (ops->set_rate) { > ops->set_rate(clk->new_rate,...); > clk->rate = clk->new_rate; > } else { > clk->rate = clk->parent->rate; > } > > if (ops->recalc_rate()) { > clk->rate = ops->recalc_rate(...); > } > > This code also makes the assumptions more intuitive and easy to understand. > What does this code buy us? There is absolutely no difference in this code and it is misleading. For the case where we do not implement .set_rate but we do implement .recalc_rate (consider a fixed divide-by-2) this code would assign clk->rate twice. Furthermore we must still implement .recalc_rate in an adjustable-rate clock for the case where a parent rate can change. Thus every adjustable-rate clock that implements .set_rate will also implement .recalc_rate and both will get called in the code above, so we've gained nothing here. Your code above is functionally equivalent to the current clk_change_rate but assigns clk->rate in three different places and is more confusing. > >>Would you mind adding more comments inside clk_calc_new_rates() and > >>clk_change_rate() trying to explain what cases you are trying to account > >>for? > >> > > > >Someday I'll have a comment/kerneldoc cleanup session. Things in the > >clock core are likely to change in the next couple of release cycles > >which will deprecate some of the kerneldoc making a big cleanup > >unavoidable. > > > >In the mean time are there any other specific question you have for > >clk_change_rate? > > > >>Also, in clk_calc_new_rates(), > >> > >> if (!clk->ops->round_rate) { > >> top = clk_calc_new_rates(clk->parent, rate); > >> new_rate = clk->parent->new_rate; > >> > >> goto out; > >> } > >> > >>Is the code assuming that if there is no round rate ops that that clock node > >>is only a gating clock (as in, can't change frequency the input freq)? Just > >>trying to understand the assumptions made in the code. > >> > > > >This is also covered by the ascii art above. There is no assumption > >about gating, per se. However if a clock can adjust it's rate (more > >specifically, if the input rate for a clock differs from the output > >rate) then a .round_rate callback must exist. > > > >The code above reads like it does because in the absence of a > >.round_rate callback it is implied that the clock cannot set it's own > >rate and should thus rely on its parent's rate. > > I agree that anyone implementing .set_rate should also provide > .round_rate. May be we should enforce that in clk_init/clk_register? > It is enforced already. Please review __clk_init. I hope that after reading this email you agree that anyone implementing .set_rate must also implement .recalc_rate. > But can we please the above "if" check more explicit? "Your rate has > to be same as the parent rate since you don't implement set rate" is > clearer than "Your rate has to be the same as the parent rate since > you don't implement round rate". > > if (!clk->ops->set_rate) { > top = clk_calc_new_rates(clk->parent, rate); > new_rate = clk->parent->new_rate; > > goto out; > } I like that we check the function pointer before calling it. That is sane. Anyone that has read Documentation/clk.txt or reviewed the sanity checks in __clk_init should realize the relationship between .set_rate, .round_rate and .recalc_rate. I see no reason to make the change above. Regards, Mike ^ permalink raw reply [flat|nested] 26+ messages in thread
* moving Tegra30 to the common clock framework 2012-05-15 2:00 ` Mike Turquette @ 2012-05-15 4:20 ` Saravana Kannan 2012-05-16 5:36 ` Turquette, Mike 0 siblings, 1 reply; 26+ messages in thread From: Saravana Kannan @ 2012-05-15 4:20 UTC (permalink / raw) To: linux-arm-kernel On 05/14/2012 07:00 PM, Mike Turquette wrote: > On 20120514-16:48, Saravana Kannan wrote: >> On 05/14/2012 02:36 PM, Turquette, Mike wrote: >>> On Fri, May 11, 2012 at 7:58 PM, Saravana Kannan<skannan@codeaurora.org> wrote: >>>> Mike, >>>> <snip> >>> The take-away is that a clock that can adjust its rate (eg: implements a >>> .set_rate callback) must also implement .recalc_rate and .round_rate >>> callbacks. >> >> I get the round_rate ops part. But I don't see a need to force a >> recalc_rate ops. Can we just check for the existence of .set_rate() >> to figure out if the clock will take up the rate of the parent or >> will output a different rate? >> > > I think you are forgetting the case where a clock can adjust its output > rate but doesn't always have its .set_rate callback called. The trivial > example of this is an adjustable divider that is downstream from some > parent clock whose rate is being changed. In any such case it is quite > necessary to have a .recalc_rate callback on the downstream clock. > > The sanity checks in __clk_init (and the documenation) make it clear > that .recalc_rate callbacks must exist due to this exact scenario. I > guess we could leave it up to the implementor to "get it right" and only > provide .recalc_rate callbacks for clocks whose parents' rates might > change, but why take that risk? My comment about forcing recalc rates is limited to "a clock that can adjust its rate (eg: implements a .set_rate callback) must also implement .recalc_rate.". As you mention, this is really a function of whether the parent rate can change or not. I stand corrected on my orthogonal point that "if .set_rate is not implemented, we can assume the rate matches the parent". >>>> Also, if the clock's rate was just set with set_rate, why do we need to >>>> recalc the rate by reading hardware? I'm a bit confused. Can you please >>>> clarify what's going on here? >>>> >>> >>> This is simply being very cautious. For platforms adjusting dividers >>> with direct register writes this might feel unnecessary. However this >>> strict checking is in anticipation of clock hardware that might not >>> actually output the precise rate passed into .set_rate. In principal >>> this isn't different from how CPUfreq and devfreq drivers inspect rates >>> after requesting them. >> >> Sorry, this still doesn't make much sense to me. This essentially >> means we can't trust the HW to do what we are asking it to do? >> > > My bit about being "cautious" above is not the driving force behind the > requirement for implementing .recalc_rate. I thought that you were > specifically complaining about calling .recalc_rate AFTER we called > .set_rate, in which case my point above stands from the perspective of > being future-proof. I agree the with the need for recalc_rates you mentioned above (parent changes rate and it will affect children). But I still don't get why you have to recalc the rate of the clock that you just set. Can you please give an example? > Your hardware even has a feature to sample it's own frequency at > run-time... does that mean your hardware doesn't trust itself? No. This is for debugging the software. <snip> > but you also feel that we > should not have a requirement to implement .recalc_rate on clocks that > can adjust their rate again. I never questioned the need for recalc rates. I also didn't make the above blanket statement -- in fact, I was saying the opposite. My point was whether we needed to check for .recalc_rates or if we can just look for .set_rate to figure out if the clock will take the parent's rate. Your fixed factor div-2 example corrected me on that point. > I'm willing to discuss removing the (sometimes) redundant .recalc_rate > calls immediately following .set_rate Yes, please. This was one of the main points of my previous email. > (since we basically perform a > preemptive .recalc_rate in clk_calc_subtree, called by clk_calc_rates). Do you do a recalc on the clock that the clk_set_rate() is called on? You only seem to make the preemptive calls on the children. Which makes sense (But I have one concern. I will get to it at the end). > But to assert that we can entirely remove the requirement to implement > .recalc_rates on clocks that support .set_rate sounds insane to me. > > Please let me know if I've misunderstood what you meant by the > statement, "I don't see a need to force a recalc_rate ops". Yeah, I think you mistook my comment that was specific to clocks that implement set rate as applying to all clocks. <snip> > I hope that after > reading this email you agree that anyone implementing .set_rate must > also implement .recalc_rate. This is the original point I raised. To be clear, I'm not denying the need for .recalc_rate. I'm just saying that it's not related to .set_rate(). As you mentioned in your response above, this is not really a function of whether a clock can set it's rate or not. It's a function of whether a parent's rate can change. So, I don't see why we should arbitrarily tie it to .set_rate. For example, there are several PLLs in MSM that get their input from a fixed crystal oscillator. There's no point in implementing recalc_rate for them (except for figuring out the rate during init). Which brings me to another point: I think we should split out the "figure out the clock's rate during boot/init" to a separate op. That operation by definition has to go through many registers, and if it's a rate settable clock, go through all the possible frequencies to figure out the rate. That seems too expensive for something that's done often like .recalc_rate. In pretty much every other call to .recalc_rate, it doesn't really need to check the hardware. It just needs to recompute the rate based on the software model of that clock. If we do add this new op (say, .sync), the expense of calling .recalc_rate after calling .set_rate would be much much lower and I won't really complain much about it (would still be nice to not do it). Regards, Saravana -- Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum. ^ permalink raw reply [flat|nested] 26+ messages in thread
* moving Tegra30 to the common clock framework 2012-05-15 4:20 ` Saravana Kannan @ 2012-05-16 5:36 ` Turquette, Mike 0 siblings, 0 replies; 26+ messages in thread From: Turquette, Mike @ 2012-05-16 5:36 UTC (permalink / raw) To: linux-arm-kernel On Mon, May 14, 2012 at 9:20 PM, Saravana Kannan <skannan@codeaurora.org> wrote: > On 05/14/2012 07:00 PM, Mike Turquette wrote: > I agree the with the need for recalc_rates you mentioned above (parent > changes rate and it will affect children). But I still don't get why you > have to recalc the rate of the clock that you just set. Can you please give > an example? I don't have a clock that needs "immediate recalculation after setting it's rate". However the code is not incorrect as-is, just suboptimal. I'm not currently looking into improving this since I have bigger problems to solve. Patches are welcome, otherwise I'll toss it on the back-burner and fix it up some day (not for initial 3.5 merge window). >> I'm willing to discuss removing the (sometimes) redundant .recalc_rate >> calls immediately following .set_rate > > Yes, please. This was one of the main points of my previous email. Same as above. >> (since we basically perform a >> preemptive .recalc_rate in clk_calc_subtree, called by clk_calc_rates). > > > Do you do a recalc on the clock that the clk_set_rate() is called on? You > only seem to make the preemptive calls on the children. Which makes sense > (But I have one concern. I will get to it at the end). Preemptive calls happen once only, in a cascade starting from the "top" clock (which may or may not be the original clock in the clk_set_rate call due to upwards parent propagation). However we do recalc the rate for each clock (even after calling its .set_rate callback) in clk_change_rate. This could be improved, but I'm not looking at it right now. ... > For example, there are several PLLs in MSM that get their input from a fixed > crystal oscillator. There's no point in implementing recalc_rate for them > (except for figuring out the rate during init). I still feel that, fundamentally, any clock which can output a different rate than is fed into must implement .recalc_rates. The set of clocks which can output a different rate than their input often exceeds the set of clocks that implement .set_rate (as evidenced by my fixed-divide-by-2 example). But forcing a check for .recalc_rate on clocks that implement .set_rate at least helps us catch some which should implement and do not. For your PLLs which are fed from a fixed input clock, we can optimize the code to not _call_ .recalc_rates unnecessarily. But some day when your chip changes and you have multiple inputs to your PLLs or an adjustable rate parent you'll be glad you had .recalc_rates implemented and ready to go. It's simply a matter of correctness. > Which brings me to another point: > I think we should split out the "figure out the clock's rate during > boot/init" to a separate op. That operation by definition has to go through > many registers, and if it's a rate settable clock, go through all the > possible frequencies to figure out the rate. That seems too expensive for > something that's done often like .recalc_rate. In pretty much every other > call to .recalc_rate, it doesn't really need to check the hardware. It just > needs to recompute the rate based on the software model of that clock. If we > do add this new op (say, .sync), the expense of calling .recalc_rate after > calling .set_rate would be much much lower and I won't really complain much > about it (would still be nice to not do it). This is also worth thinking about, but it changes the existing interfaces for clock code to implement and it's yet another optimization. So patches are welcome, otherwise I'll toss it onto the stack somewhere. Regards, Mike ^ permalink raw reply [flat|nested] 26+ messages in thread
* moving Tegra30 to the common clock framework 2012-05-07 0:03 ` Mike Turquette 2012-05-07 15:39 ` Stephen Warren @ 2012-05-09 11:13 ` Peter De Schrijver 2012-05-09 16:49 ` Mike Turquette ` (2 more replies) 1 sibling, 3 replies; 26+ messages in thread From: Peter De Schrijver @ 2012-05-09 11:13 UTC (permalink / raw) To: linux-arm-kernel On Mon, May 07, 2012 at 02:03:29AM +0200, Mike Turquette wrote: > On 20120503-19:13, Peter De Schrijver wrote: > > Hi, > > > > I started looking into what would be needed to move our tegra30 clock code > > to the common clock framework. The tegra30 clocktree is rather flat. Basically > > there are a bunch of sources (13 PLLs, external audio clocks, osc and 32Khz) > > and peripheral clocks which have a mux (with 4 or more inputs), a divider and > > a gate. So almost every peripheral clock can have multiple parents. > > > > Some questions: > > > > 1) should these peripheral clocks be modelled as 3 different clocks > > (mux -> divider -> gate) or would it be better to make a new clock type for > > this? > > > > That is really for you to decide. If the semantics of the existing mux, > divider and gate in drivers/clk/clk-*.c work well for you then I think > the answer is "yes". There is infrastructure for register-access > locking in those common types which might help your complex clocks. > > Thanks to the parent rate propagation stuff in clk_set_rate it should be > possible for your drivers to only be aware of the gate and call > clk_set_rate on only that clock, which propagates up to the divider and, > if necessary, again propagates up to the mux. > > I encourage you to try that first. But if you find the semantics of > those basic clock types aren't cutting it for you then you must create a > type which is platform-specific. > > > 2) how to define the default parent? in many cases the hw reset value isn't > > a very sensible choice, so the kernel probably needs to set a parent of > > many of them if we don't want to rely on bootloader configuration. > > The only related thing handled at the framework level is _discovery_ of > the parent during clock registration/initialization. If you don't trust > the bootloader and want to set things up as soon as possible (a wise > move) then I suggest you do so from your platform clock code at the same > time that you register your clocks with the framework. Something like: > > struct clk *c; > c = clk_register(...); > if (IS_ERR(c)) > omg_fail(); > clk_set_parent(c, b); > > Where 'b' is a parent of 'c'. Register your clock tree top-down and you > can re-parent as you go. Ok. Thanks. One more question. We have some clocks with special features such as request lines for clock outputs, delays for clocks recovered from an external source or several divisors which are used based on the state of the module which is served by the clock (eg. an idle divisor and an active divisor). How should these be modelled? Thanks, Peter. ^ permalink raw reply [flat|nested] 26+ messages in thread
* moving Tegra30 to the common clock framework 2012-05-09 11:13 ` Peter De Schrijver @ 2012-05-09 16:49 ` Mike Turquette 2012-05-10 11:36 ` Peter De Schrijver 2012-05-12 18:04 ` Mark Brown 2012-05-14 12:36 ` Peter De Schrijver 2 siblings, 1 reply; 26+ messages in thread From: Mike Turquette @ 2012-05-09 16:49 UTC (permalink / raw) To: linux-arm-kernel On 20120509-14:13, Peter De Schrijver wrote: > Ok. Thanks. One more question. We have some clocks with special features > such as request lines for clock outputs, delays for clocks recovered from > an external source or several divisors which are used based on the state > of the module which is served by the clock (eg. an idle divisor and an active > divisor). How should these be modelled? My platform also has some "special" clocks. The worst case is that you must create some platform clock types and eschew the common basic types. A common example of this is that everyone has their own PLL implementation. However it is possible to subclass some existing basic types if your needs aren't too complicated. Check out the patch from Andrew that builds on top of the basic gate: http://git.linaro.org/gitweb?p=people/mturquette/linux.git;a=commitdiff;h=98d9986cb8bf65f8316b45244fdafc1d12c303be;hp=e919c71665d2386eec6dc2ecd58d01bae69fc0fd In fact the basic clock types were originally discussed as targeting only "simple platforms". I don't think anyone thought that we would get as much use out of them as we have had for complex SoCs. Regards, Mike ^ permalink raw reply [flat|nested] 26+ messages in thread
* moving Tegra30 to the common clock framework 2012-05-09 16:49 ` Mike Turquette @ 2012-05-10 11:36 ` Peter De Schrijver 0 siblings, 0 replies; 26+ messages in thread From: Peter De Schrijver @ 2012-05-10 11:36 UTC (permalink / raw) To: linux-arm-kernel On Wed, May 09, 2012 at 06:49:15PM +0200, Mike Turquette wrote: > On 20120509-14:13, Peter De Schrijver wrote: > > Ok. Thanks. One more question. We have some clocks with special features > > such as request lines for clock outputs, delays for clocks recovered from > > an external source or several divisors which are used based on the state > > of the module which is served by the clock (eg. an idle divisor and an active > > divisor). How should these be modelled? > > My platform also has some "special" clocks. The worst case is that you > must create some platform clock types and eschew the common basic types. > A common example of this is that everyone has their own PLL > implementation. > Ok. I was more wondering on how to expose those features which don't fit into the normal clock API. Currently we have tegra_clk_cfg_ex() which is some kind of ioctl for clocks. > However it is possible to subclass some existing basic types if your > needs aren't too complicated. Check out the patch from Andrew that > builds on top of the basic gate: > http://git.linaro.org/gitweb?p=people/mturquette/linux.git;a=commitdiff;h=98d9986cb8bf65f8316b45244fdafc1d12c303be;hp=e919c71665d2386eec6dc2ecd58d01bae69fc0fd > > In fact the basic clock types were originally discussed as targeting > only "simple platforms". I don't think anyone thought that we would get > as much use out of them as we have had for complex SoCs. Ok. Might be useful at some point. Cheers, Peter. ^ permalink raw reply [flat|nested] 26+ messages in thread
* moving Tegra30 to the common clock framework 2012-05-09 11:13 ` Peter De Schrijver 2012-05-09 16:49 ` Mike Turquette @ 2012-05-12 18:04 ` Mark Brown 2012-05-14 12:29 ` Peter De Schrijver 2012-05-14 12:36 ` Peter De Schrijver 2 siblings, 1 reply; 26+ messages in thread From: Mark Brown @ 2012-05-12 18:04 UTC (permalink / raw) To: linux-arm-kernel On Wed, May 09, 2012 at 02:13:35PM +0300, Peter De Schrijver wrote: > Ok. Thanks. One more question. We have some clocks with special features > such as request lines for clock outputs, delays for clocks recovered from > an external source or several divisors which are used based on the state > of the module which is served by the clock (eg. an idle divisor and an active > divisor). How should these be modelled? For the idle/active divisors could they be represented as separate clocks? ^ permalink raw reply [flat|nested] 26+ messages in thread
* moving Tegra30 to the common clock framework 2012-05-12 18:04 ` Mark Brown @ 2012-05-14 12:29 ` Peter De Schrijver 0 siblings, 0 replies; 26+ messages in thread From: Peter De Schrijver @ 2012-05-14 12:29 UTC (permalink / raw) To: linux-arm-kernel On Sat, May 12, 2012 at 08:04:41PM +0200, Mark Brown wrote: > On Wed, May 09, 2012 at 02:13:35PM +0300, Peter De Schrijver wrote: > > > Ok. Thanks. One more question. We have some clocks with special features > > such as request lines for clock outputs, delays for clocks recovered from > > an external source or several divisors which are used based on the state > > of the module which is served by the clock (eg. an idle divisor and an active > > divisor). How should these be modelled? > > For the idle/active divisors could they be represented as separate > clocks? I guess that might be possible. Need to look into it. Cheers, Peter. ^ permalink raw reply [flat|nested] 26+ messages in thread
* moving Tegra30 to the common clock framework 2012-05-09 11:13 ` Peter De Schrijver 2012-05-09 16:49 ` Mike Turquette 2012-05-12 18:04 ` Mark Brown @ 2012-05-14 12:36 ` Peter De Schrijver 2 siblings, 0 replies; 26+ messages in thread From: Peter De Schrijver @ 2012-05-14 12:36 UTC (permalink / raw) To: linux-arm-kernel On Wed, May 09, 2012 at 01:13:35PM +0200, Peter De Schrijver wrote: > > Ok. Thanks. One more question. We have some clocks with special features > such as request lines for clock outputs, delays for clocks recovered from > an external source or several divisors which are used based on the state > of the module which is served by the clock (eg. an idle divisor and an active > divisor). How should these be modelled? One more thing: we have muxes where not all possible register values are valid. I could make a special mux type which contains a mapping array, but that doesn't seem like a good solution to me. Is there a reason why we don't have a struct clk_parent like this: struct clk_parents { char *name; struct clk *clk; int index; } where index is the value to be written to the hw to select that clock as a parent. It would also avoid having to pass 2 arrays (name and clk pointer). Cheers, Peter. ^ permalink raw reply [flat|nested] 26+ messages in thread
end of thread, other threads:[~2012-05-16 5:36 UTC | newest] Thread overview: 26+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2012-05-03 16:13 moving Tegra30 to the common clock framework Peter De Schrijver 2012-05-07 0:03 ` Mike Turquette 2012-05-07 15:39 ` Stephen Warren 2012-05-07 16:12 ` Turquette, Mike 2012-05-08 5:07 ` zhoujie wu 2012-05-08 17:15 ` Turquette, Mike 2012-05-09 0:41 ` Saravana Kannan 2012-05-09 2:20 ` skannan at codeaurora.org 2012-05-09 6:21 ` Turquette, Mike 2012-05-10 0:02 ` Saravana Kannan 2012-05-09 10:36 ` Peter De Schrijver 2012-05-12 2:58 ` Saravana Kannan 2012-05-13 4:31 ` Stephen Warren 2012-05-14 11:08 ` Peter De Schrijver 2012-05-15 0:10 ` Saravana Kannan 2012-05-14 21:36 ` Turquette, Mike 2012-05-14 23:48 ` Saravana Kannan 2012-05-15 2:00 ` Mike Turquette 2012-05-15 4:20 ` Saravana Kannan 2012-05-16 5:36 ` Turquette, Mike 2012-05-09 11:13 ` Peter De Schrijver 2012-05-09 16:49 ` Mike Turquette 2012-05-10 11:36 ` Peter De Schrijver 2012-05-12 18:04 ` Mark Brown 2012-05-14 12:29 ` Peter De Schrijver 2012-05-14 12:36 ` Peter De Schrijver
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).