All of lore.kernel.org
 help / color / mirror / Atom feed
* Common clock: function clock and bus clock
@ 2014-03-11  2:06 Chao Xie
  2014-03-11  2:48 ` Haojian Zhuang
  2014-03-20  9:45 ` Ben Dooks
  0 siblings, 2 replies; 11+ messages in thread
From: Chao Xie @ 2014-03-11  2:06 UTC (permalink / raw)
  To: linux-arm-kernel

hi

I can not find any examples for handling function clock and bus clock
in drivers/clk/.

For a device, it will have a function clock and bus clock. function
clock will control the fucntionality of this device, while bus clock
will control the communication part to the bus.

For some SOCes, they do not export bus clock, so from the hardware it
seems that function clock is combined with bus clock, while for some
SOCes, they are not.

For most of the device driver, they will enable/disable function clock
and bus clock both. While for some devices, they may share bus clock,
and have different function clocks.

In fact, i want to define the APIs as below:

struct clk* soc_register_bus_clock(struct device *dev, char **parent_name, ...);
This function will  create and register bus clock

struct clk* soc_register_fucntion_clock(struct device *dev, char
**parent_name, ...);
This function will create and register function clock

struct clk* soc_register_clk(struct device *dev, char **parent_name);
This function will create and register a device clock. Then this clock
is enable, it will enable bus clock and function clock both, and it is
similar for disabling.

struct clk* soc_register_composite_clk(struct device *dev, char
*bus_clk_name, char *function_clk_name);
This function will create and register a composite device clock. When
enable this clock, it will invoke clk_enable(bus_clk) and
clk_enable(function_clk) both. It is similar for disabling.

So for the device which has its own control register and bits for
function clock and bus clock. We can call  soc_register_clk.
For the device share bus clock with other devices, we create the clock
for the device by calling  soc_register_composite_clk.

1. Now clk_enable can be preempted by same caller.
2. For above devices, the bus clock only have enable/disable ops.

Based on above conditions, I think soc_register_composite_clk is fine.

Does anyone have same problems? Will above proposal break common clock rules.

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

* Common clock: function clock and bus clock
  2014-03-11  2:06 Common clock: function clock and bus clock Chao Xie
@ 2014-03-11  2:48 ` Haojian Zhuang
  2014-03-12  2:30   ` Chao Xie
  2014-03-20  9:45 ` Ben Dooks
  1 sibling, 1 reply; 11+ messages in thread
From: Haojian Zhuang @ 2014-03-11  2:48 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Mar 11, 2014 at 10:06 AM, Chao Xie <xiechao.mail@gmail.com> wrote:
> hi
>
> I can not find any examples for handling function clock and bus clock
> in drivers/clk/.
>
> For a device, it will have a function clock and bus clock. function
> clock will control the fucntionality of this device, while bus clock
> will control the communication part to the bus.
>
> For some SOCes, they do not export bus clock, so from the hardware it
> seems that function clock is combined with bus clock, while for some
> SOCes, they are not.
>
> For most of the device driver, they will enable/disable function clock
> and bus clock both. While for some devices, they may share bus clock,
> and have different function clocks.
>
> In fact, i want to define the APIs as below:
>
> struct clk* soc_register_bus_clock(struct device *dev, char **parent_name, ...);
> This function will  create and register bus clock
>
> struct clk* soc_register_fucntion_clock(struct device *dev, char
> **parent_name, ...);
> This function will create and register function clock
>
> struct clk* soc_register_clk(struct device *dev, char **parent_name);
> This function will create and register a device clock. Then this clock
> is enable, it will enable bus clock and function clock both, and it is
> similar for disabling.
>
> struct clk* soc_register_composite_clk(struct device *dev, char
> *bus_clk_name, char *function_clk_name);
> This function will create and register a composite device clock. When
> enable this clock, it will invoke clk_enable(bus_clk) and
> clk_enable(function_clk) both. It is similar for disabling.
>
> So for the device which has its own control register and bits for
> function clock and bus clock. We can call  soc_register_clk.
> For the device share bus clock with other devices, we create the clock
> for the device by calling  soc_register_composite_clk.
>
> 1. Now clk_enable can be preempted by same caller.
> 2. For above devices, the bus clock only have enable/disable ops.
>
> Based on above conditions, I think soc_register_composite_clk is fine.
>
> Does anyone have same problems? Will above proposal break common clock rules.

I think it's too complex.

If the bus clock and function clock is only used for gating, maybe you
can set the bus clock as parent of function clock.

If both of them are complex, why not define two clocks in your device driver?

Regards
Haojian

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

* Common clock: function clock and bus clock
  2014-03-11  2:48 ` Haojian Zhuang
@ 2014-03-12  2:30   ` Chao Xie
  2014-03-12 10:14     ` Grygorii Strashko
  0 siblings, 1 reply; 11+ messages in thread
From: Chao Xie @ 2014-03-12  2:30 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Mar 11, 2014 at 10:48 AM, Haojian Zhuang
<haojian.zhuang@gmail.com> wrote:
> On Tue, Mar 11, 2014 at 10:06 AM, Chao Xie <xiechao.mail@gmail.com> wrote:
>> hi
>>
>> I can not find any examples for handling function clock and bus clock
>> in drivers/clk/.
>>
>> For a device, it will have a function clock and bus clock. function
>> clock will control the fucntionality of this device, while bus clock
>> will control the communication part to the bus.
>>
>> For some SOCes, they do not export bus clock, so from the hardware it
>> seems that function clock is combined with bus clock, while for some
>> SOCes, they are not.
>>
>> For most of the device driver, they will enable/disable function clock
>> and bus clock both. While for some devices, they may share bus clock,
>> and have different function clocks.
>>
>> In fact, i want to define the APIs as below:
>>
>> struct clk* soc_register_bus_clock(struct device *dev, char **parent_name, ...);
>> This function will  create and register bus clock
>>
>> struct clk* soc_register_fucntion_clock(struct device *dev, char
>> **parent_name, ...);
>> This function will create and register function clock
>>
>> struct clk* soc_register_clk(struct device *dev, char **parent_name);
>> This function will create and register a device clock. Then this clock
>> is enable, it will enable bus clock and function clock both, and it is
>> similar for disabling.
>>
>> struct clk* soc_register_composite_clk(struct device *dev, char
>> *bus_clk_name, char *function_clk_name);
>> This function will create and register a composite device clock. When
>> enable this clock, it will invoke clk_enable(bus_clk) and
>> clk_enable(function_clk) both. It is similar for disabling.
>>
>> So for the device which has its own control register and bits for
>> function clock and bus clock. We can call  soc_register_clk.
>> For the device share bus clock with other devices, we create the clock
>> for the device by calling  soc_register_composite_clk.
>>
>> 1. Now clk_enable can be preempted by same caller.
>> 2. For above devices, the bus clock only have enable/disable ops.
>>
>> Based on above conditions, I think soc_register_composite_clk is fine.
>>
>> Does anyone have same problems? Will above proposal break common clock rules.
>
> I think it's too complex.
>
> If the bus clock and function clock is only used for gating, maybe you
> can set the bus clock as parent of function clock.
>
You can not do it. Because the function clock may have mux and div, it
can not depends on bus clock's rate.

> If both of them are complex, why not define two clocks in your device driver?
>
It is the problem. In fact for different SOCes, we can not know which
device will have such limitation.
Even for same device, for SOC-a, it has the limitation, for SOC-b, it does not.
So the choice is make all the device drivers to grap two clocks. There
are too many of them, and for
the devices does not have such limitation, it is redundant.
So the point is we donot want to change the device driver, and we want
to make the device driver interfaces
maintain unchanged. .

> Regards
> Haojian

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

* Common clock: function clock and bus clock
  2014-03-12  2:30   ` Chao Xie
@ 2014-03-12 10:14     ` Grygorii Strashko
  2014-03-13  2:15       ` Chao Xie
  0 siblings, 1 reply; 11+ messages in thread
From: Grygorii Strashko @ 2014-03-12 10:14 UTC (permalink / raw)
  To: linux-arm-kernel

On 03/12/2014 04:30 AM, Chao Xie wrote:
> On Tue, Mar 11, 2014 at 10:48 AM, Haojian Zhuang
> <haojian.zhuang@gmail.com> wrote:
>> On Tue, Mar 11, 2014 at 10:06 AM, Chao Xie <xiechao.mail@gmail.com> wrote:
>>> hi
>>>
>>> I can not find any examples for handling function clock and bus clock
>>> in drivers/clk/.
>>>
>>> For a device, it will have a function clock and bus clock. function
>>> clock will control the fucntionality of this device, while bus clock
>>> will control the communication part to the bus.
>>>
>>> For some SOCes, they do not export bus clock, so from the hardware it
>>> seems that function clock is combined with bus clock, while for some
>>> SOCes, they are not.
>>>
>>> For most of the device driver, they will enable/disable function clock
>>> and bus clock both. While for some devices, they may share bus clock,
>>> and have different function clocks.
>>>
>>> In fact, i want to define the APIs as below:
>>>
>>> struct clk* soc_register_bus_clock(struct device *dev, char **parent_name, ...);
>>> This function will  create and register bus clock
>>>
>>> struct clk* soc_register_fucntion_clock(struct device *dev, char
>>> **parent_name, ...);
>>> This function will create and register function clock
>>>
>>> struct clk* soc_register_clk(struct device *dev, char **parent_name);
>>> This function will create and register a device clock. Then this clock
>>> is enable, it will enable bus clock and function clock both, and it is
>>> similar for disabling.
>>>
>>> struct clk* soc_register_composite_clk(struct device *dev, char
>>> *bus_clk_name, char *function_clk_name);
>>> This function will create and register a composite device clock. When
>>> enable this clock, it will invoke clk_enable(bus_clk) and
>>> clk_enable(function_clk) both. It is similar for disabling.
>>>
>>> So for the device which has its own control register and bits for
>>> function clock and bus clock. We can call  soc_register_clk.
>>> For the device share bus clock with other devices, we create the clock
>>> for the device by calling  soc_register_composite_clk.
>>>
>>> 1. Now clk_enable can be preempted by same caller.
>>> 2. For above devices, the bus clock only have enable/disable ops.
>>>
>>> Based on above conditions, I think soc_register_composite_clk is fine.
>>>
>>> Does anyone have same problems? Will above proposal break common clock rules.
>>
>> I think it's too complex.
>>
>> If the bus clock and function clock is only used for gating, maybe you
>> can set the bus clock as parent of function clock.
>>
> You can not do it. Because the function clock may have mux and div, it
> can not depends on bus clock's rate.
>
>> If both of them are complex, why not define two clocks in your device driver?
>>
> It is the problem. In fact for different SOCes, we can not know which
> device will have such limitation.
> Even for same device, for SOC-a, it has the limitation, for SOC-b, it does not.
> So the choice is make all the device drivers to grap two clocks. There
> are too many of them, and for
> the devices does not have such limitation, it is redundant.
> So the point is we donot want to change the device driver, and we want
> to make the device driver interfaces
> maintain unchanged. .

Clk pm domain - Is it what you want?
drivers/base/power/clock_ops.c

Usage example:
arch/arm/mach-davinci/pm_domain.c
arch/arm/mach-keystone/pm_domain.c

Then you can simply use Runtime PM API to control clocks.

Regrads,
-grygorii

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

* Common clock: function clock and bus clock
  2014-03-12 10:14     ` Grygorii Strashko
@ 2014-03-13  2:15       ` Chao Xie
  2014-03-13  3:16         ` Emilio López
  2014-03-20 11:42         ` Russell King - ARM Linux
  0 siblings, 2 replies; 11+ messages in thread
From: Chao Xie @ 2014-03-13  2:15 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Mar 12, 2014 at 6:14 PM, Grygorii Strashko
<grygorii.strashko@ti.com> wrote:
> On 03/12/2014 04:30 AM, Chao Xie wrote:
>>
>> On Tue, Mar 11, 2014 at 10:48 AM, Haojian Zhuang
>> <haojian.zhuang@gmail.com> wrote:
>>>
>>> On Tue, Mar 11, 2014 at 10:06 AM, Chao Xie <xiechao.mail@gmail.com>
>>> wrote:
>>>>
>>>> hi
>>>>
>>>> I can not find any examples for handling function clock and bus clock
>>>> in drivers/clk/.
>>>>
>>>> For a device, it will have a function clock and bus clock. function
>>>> clock will control the fucntionality of this device, while bus clock
>>>> will control the communication part to the bus.
>>>>
>>>> For some SOCes, they do not export bus clock, so from the hardware it
>>>> seems that function clock is combined with bus clock, while for some
>>>> SOCes, they are not.
>>>>
>>>> For most of the device driver, they will enable/disable function clock
>>>> and bus clock both. While for some devices, they may share bus clock,
>>>> and have different function clocks.
>>>>
>>>> In fact, i want to define the APIs as below:
>>>>
>>>> struct clk* soc_register_bus_clock(struct device *dev, char
>>>> **parent_name, ...);
>>>> This function will  create and register bus clock
>>>>
>>>> struct clk* soc_register_fucntion_clock(struct device *dev, char
>>>> **parent_name, ...);
>>>> This function will create and register function clock
>>>>
>>>> struct clk* soc_register_clk(struct device *dev, char **parent_name);
>>>> This function will create and register a device clock. Then this clock
>>>> is enable, it will enable bus clock and function clock both, and it is
>>>> similar for disabling.
>>>>
>>>> struct clk* soc_register_composite_clk(struct device *dev, char
>>>> *bus_clk_name, char *function_clk_name);
>>>> This function will create and register a composite device clock. When
>>>> enable this clock, it will invoke clk_enable(bus_clk) and
>>>> clk_enable(function_clk) both. It is similar for disabling.
>>>>
>>>> So for the device which has its own control register and bits for
>>>> function clock and bus clock. We can call  soc_register_clk.
>>>> For the device share bus clock with other devices, we create the clock
>>>> for the device by calling  soc_register_composite_clk.
>>>>
>>>> 1. Now clk_enable can be preempted by same caller.
>>>> 2. For above devices, the bus clock only have enable/disable ops.
>>>>
>>>> Based on above conditions, I think soc_register_composite_clk is fine.
>>>>
>>>> Does anyone have same problems? Will above proposal break common clock
>>>> rules.
>>>
>>>
>>> I think it's too complex.
>>>
>>> If the bus clock and function clock is only used for gating, maybe you
>>> can set the bus clock as parent of function clock.
>>>
>> You can not do it. Because the function clock may have mux and div, it
>> can not depends on bus clock's rate.
>>
>>> If both of them are complex, why not define two clocks in your device
>>> driver?
>>>
>> It is the problem. In fact for different SOCes, we can not know which
>> device will have such limitation.
>> Even for same device, for SOC-a, it has the limitation, for SOC-b, it does
>> not.
>> So the choice is make all the device drivers to grap two clocks. There
>> are too many of them, and for
>> the devices does not have such limitation, it is redundant.
>> So the point is we donot want to change the device driver, and we want
>> to make the device driver interfaces
>> maintain unchanged. .
>
>
> Clk pm domain - Is it what you want?
> drivers/base/power/clock_ops.c
>
> Usage example:
> arch/arm/mach-davinci/pm_domain.c
> arch/arm/mach-keystone/pm_domain.c
>
> Then you can simply use Runtime PM API to control clocks.
>
It is not related to clk pm domain. It is related to clock depenency.

For a device, it has bus clock and function clock. usally bus clock is
a gate type clock.

some devices share same bus clock, but have different function clock.
If we want to use the device, we have to enable the bus clock and
function clock both.

The problem is for some SOCes, there is no sharing of bus clock while
for others, it has, and this limitation can happen at all clocks in
clock domain.

So i do not want to make device driver be aware of it. I just let it
know there is only one clock, and keep the dependency in clock
framework.

> Regrads,
> -grygorii

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

* Common clock: function clock and bus clock
  2014-03-13  2:15       ` Chao Xie
@ 2014-03-13  3:16         ` Emilio López
  2014-03-13 11:30           ` Grygorii Strashko
  2014-03-20 11:42         ` Russell King - ARM Linux
  1 sibling, 1 reply; 11+ messages in thread
From: Emilio López @ 2014-03-13  3:16 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

El mi? 12 mar 2014 23:15:20 ART, Chao Xie escribi?:
> On Wed, Mar 12, 2014 at 6:14 PM, Grygorii Strashko
> <grygorii.strashko@ti.com> wrote:
>> On 03/12/2014 04:30 AM, Chao Xie wrote:
>>>
>>> On Tue, Mar 11, 2014 at 10:48 AM, Haojian Zhuang
>>> <haojian.zhuang@gmail.com> wrote:
>>>>
>>>> On Tue, Mar 11, 2014 at 10:06 AM, Chao Xie <xiechao.mail@gmail.com>
>>>> wrote:
>>>>>
>>>>> hi
>>>>>
>>>>> I can not find any examples for handling function clock and bus clock
>>>>> in drivers/clk/.
>>>>>
>>>>> For a device, it will have a function clock and bus clock. function
>>>>> clock will control the fucntionality of this device, while bus clock
>>>>> will control the communication part to the bus.
>>>>>
>>>>> For some SOCes, they do not export bus clock, so from the hardware it
>>>>> seems that function clock is combined with bus clock, while for some
>>>>> SOCes, they are not.
>>>>>
>>>>> For most of the device driver, they will enable/disable function clock
>>>>> and bus clock both. While for some devices, they may share bus clock,
>>>>> and have different function clocks.

You can define two normal clocks and use them like this

* If a device has both bus and module

clocks = <&abc ...>, <&xyz ...>;
clock-names = "bus", "module";

* If a device only has module clock

clocks = <&xyz ...>;
clock-names = "module";

Then on the driver to control this specific hardware you can do 
something like

/* mandatory module clock */
mod = devm_clk_get(dev, "module");
if (!IS_ERR(mod))
	clk_prepare_enable(mod)
else
	goto fail;	

/* optional bus clock */
bus = devm_clk_get(dev, "bus");
if (!IS_ERR(bus))
	clk_prepare_enable(bus)


The framework keeps count of how many times clocks have been enabled, so 
as long as a device needs the bus clock, it will remain operational.

You can find many examples of this pattern with

$ grep 'clock-names.*ahb' arch/arm/boot/dts/*dts*

Cheers,

Emilio

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

* Common clock: function clock and bus clock
  2014-03-13  3:16         ` Emilio López
@ 2014-03-13 11:30           ` Grygorii Strashko
       [not found]             ` <20140319210428.31449.19420@quantum>
  0 siblings, 1 reply; 11+ messages in thread
From: Grygorii Strashko @ 2014-03-13 11:30 UTC (permalink / raw)
  To: linux-arm-kernel

On 03/13/2014 05:16 AM, Emilio L?pez wrote:
> Hi,
> 
> El mi? 12 mar 2014 23:15:20 ART, Chao Xie escribi?:
>> On Wed, Mar 12, 2014 at 6:14 PM, Grygorii Strashko
>> <grygorii.strashko@ti.com> wrote:
>>> On 03/12/2014 04:30 AM, Chao Xie wrote:
>>>>
>>>> On Tue, Mar 11, 2014 at 10:48 AM, Haojian Zhuang
>>>> <haojian.zhuang@gmail.com> wrote:
>>>>>
>>>>> On Tue, Mar 11, 2014 at 10:06 AM, Chao Xie <xiechao.mail@gmail.com>
>>>>> wrote:
>>>>>>
>>>>>> hi
>>>>>>
>>>>>> I can not find any examples for handling function clock and bus clock
>>>>>> in drivers/clk/.
>>>>>>
>>>>>> For a device, it will have a function clock and bus clock. function
>>>>>> clock will control the fucntionality of this device, while bus clock
>>>>>> will control the communication part to the bus.
>>>>>>
>>>>>> For some SOCes, they do not export bus clock, so from the hardware it
>>>>>> seems that function clock is combined with bus clock, while for some
>>>>>> SOCes, they are not.
>>>>>>
>>>>>> For most of the device driver, they will enable/disable function 
>>>>>> clock
>>>>>> and bus clock both. While for some devices, they may share bus clock,
>>>>>> and have different function clocks.
> 
> You can define two normal clocks and use them like this
> 
> * If a device has both bus and module
> 
> clocks = <&abc ...>, <&xyz ...>;
> clock-names = "bus", "module";
> 
> * If a device only has module clock
> 
> clocks = <&xyz ...>;
> clock-names = "module";
> 
> Then on the driver to control this specific hardware you can do 
> something like
> 
> /* mandatory module clock */
> mod = devm_clk_get(dev, "module");
> if (!IS_ERR(mod))
>      clk_prepare_enable(mod)
> else
>      goto fail;
> 
> /* optional bus clock */
> bus = devm_clk_get(dev, "bus");
> if (!IS_ERR(bus))
>      clk_prepare_enable(bus)
> 

That what exactly Clock PM domain is doing :)

In Davinci it is defined as:
static struct pm_clk_notifier_block platform_bus_notifier = {
	.pm_domain = &davinci_pm_domain,
	.con_ids = { "fck", "master", "slave", NULL },
};

When device is created the Clk PM domain core (clock_ops.c) recollects all clocks
specified for device (in DT or in clkdev tables) by their names (DT) or con_id (clkdev).
One device can specify clocks: "master", "slave"
and another only "fck".

Then in driver you need only do:
 pm_runtime_enable(dev);
 error = pm_runtime_get_sync(dev);
 ^ all clocks assigned to the device will be enabled

...
 error = pm_runtime_put_sync(dev);
 ^ all clocks assigned to the device will be disabled


Regards,
- grygorii

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

* Common clock: function clock and bus clock
  2014-03-11  2:06 Common clock: function clock and bus clock Chao Xie
  2014-03-11  2:48 ` Haojian Zhuang
@ 2014-03-20  9:45 ` Ben Dooks
  2014-03-20 11:35   ` Russell King - ARM Linux
  1 sibling, 1 reply; 11+ messages in thread
From: Ben Dooks @ 2014-03-20  9:45 UTC (permalink / raw)
  To: linux-arm-kernel

On 11/03/14 03:06, Chao Xie wrote:
> hi
>
> I can not find any examples for handling function clock and bus clock
> in drivers/clk/.

The convention is that clk_get(dev, NULL) will get the bus clock
for the device and that any other clocks are appropriately named.

In the device tree case, the bus clock is first, and can generally
be named anything you like, such as "bus".

If the module does not have one, then you can always supply a dummy
clock.

-- 
Ben Dooks				http://www.codethink.co.uk/
Senior Engineer				Codethink - Providing Genius

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

* Common clock: function clock and bus clock
       [not found]               ` <CAPDyKFqg230Ob5Wxu0tvXqia+B3WG5+YdKTdxTQ0ySbZokb+7Q@mail.gmail.com>
@ 2014-03-20 10:30                 ` Grygorii Strashko
  0 siblings, 0 replies; 11+ messages in thread
From: Grygorii Strashko @ 2014-03-20 10:30 UTC (permalink / raw)
  To: linux-arm-kernel

On 03/20/2014 10:25 AM, Ulf Hansson wrote:
> On 19 March 2014 22:04, Mike Turquette <mturquette@linaro.org> wrote:
>> Quoting Grygorii Strashko (2014-03-13 04:30:43)
>>> On 03/13/2014 05:16 AM, Emilio L?pez wrote:
>>>> Hi,
>>>>
>>>> El mi? 12 mar 2014 23:15:20 ART, Chao Xie escribi?:
>>>>> On Wed, Mar 12, 2014 at 6:14 PM, Grygorii Strashko
>>>>> <grygorii.strashko@ti.com> wrote:
>>>>>> On 03/12/2014 04:30 AM, Chao Xie wrote:
>>>>>>>
>>>>>>> On Tue, Mar 11, 2014 at 10:48 AM, Haojian Zhuang
>>>>>>> <haojian.zhuang@gmail.com> wrote:
>>>>>>>>
>>>>>>>> On Tue, Mar 11, 2014 at 10:06 AM, Chao Xie <xiechao.mail@gmail.com>
>>>>>>>> wrote:
>>>>>>>>>
>>>>>>>>> hi
>>>>>>>>>
>>>>>>>>> I can not find any examples for handling function clock and bus clock
>>>>>>>>> in drivers/clk/.
>>>>>>>>>
>>>>>>>>> For a device, it will have a function clock and bus clock. function
>>>>>>>>> clock will control the fucntionality of this device, while bus clock
>>>>>>>>> will control the communication part to the bus.
>>>>>>>>>
>>>>>>>>> For some SOCes, they do not export bus clock, so from the hardware it
>>>>>>>>> seems that function clock is combined with bus clock, while for some
>>>>>>>>> SOCes, they are not.
>>>>>>>>>
>>>>>>>>> For most of the device driver, they will enable/disable function
>>>>>>>>> clock
>>>>>>>>> and bus clock both. While for some devices, they may share bus clock,
>>>>>>>>> and have different function clocks.
>>>>
>>>> You can define two normal clocks and use them like this
>>>>
>>>> * If a device has both bus and module
>>>>
>>>> clocks = <&abc ...>, <&xyz ...>;
>>>> clock-names = "bus", "module";
>>>>
>>>> * If a device only has module clock
>>>>
>>>> clocks = <&xyz ...>;
>>>> clock-names = "module";
>>>>
>>>> Then on the driver to control this specific hardware you can do
>>>> something like
>>>>
>>>> /* mandatory module clock */
>>>> mod = devm_clk_get(dev, "module");
>>>> if (!IS_ERR(mod))
>>>>       clk_prepare_enable(mod)
>>>> else
>>>>       goto fail;
>>>>
>>>> /* optional bus clock */
>>>> bus = devm_clk_get(dev, "bus");
>>>> if (!IS_ERR(bus))
>>>>       clk_prepare_enable(bus)
>>>>
> 
> This won't work for a cross SOC driver, since in one cases it should
> be optional, but in the other mandatory.
> 
> I suggest you point the "bus" clock to the same clock clock as the
> "module" for those SOCs that don't have them as separate clocks. Thus
> the driver can keep both of them mandatory. Wouldn't that work?
> 
> Like this:
> clocks = <&xyz ...>, <&xyz ...>;
> clock-names = "bus", "module";
> 
>>>
>>> That what exactly Clock PM domain is doing :)
>>
>> I agree with Grygorii. Emilio's solution is correct as well, but using
>> runtime pm is the best way forward, especially for examples like the
>> OP's, where the goal is to do whatever is necessary to make the hardware
>> ready for doing work.
>>
>> Ulf is doing some work towards creating a "best practices" example of pm
>> runtime adaptation and I've Cc'd him in case he has any comments.
>>
>> Regards,
>> Mike
>>
>>>
>>> In Davinci it is defined as:
>>> static struct pm_clk_notifier_block platform_bus_notifier = {
>>>          .pm_domain = &davinci_pm_domain,
>>>          .con_ids = { "fck", "master", "slave", NULL },
>>> };
>>>
>>> When device is created the Clk PM domain core (clock_ops.c) recollects all clocks
>>> specified for device (in DT or in clkdev tables) by their names (DT) or con_id (clkdev).
>>> One device can specify clocks: "master", "slave"
>>> and another only "fck".
>>>
>>> Then in driver you need only do:
>>>   pm_runtime_enable(dev);
>>>   error = pm_runtime_get_sync(dev);
>>>   ^ all clocks assigned to the device will be enabled
>>>
>>> ...
>>>   error = pm_runtime_put_sync(dev);
>>>   ^ all clocks assigned to the device will be disabled
> 
> I would not recommend using the clk PM domain to solve this issue.
> Especially not through a power domain. Simply because we must not
> force each an every SOC to implement a pm_domain just to be sure
> clocks are handled properly for a device.

It depends on SoC :). PM on Keystone 2 is very simple, and It's
just based on clocks. HW block is on if its clocks are on.
So, Clk PM domain (clock_ops.c) fits such kind of SoCs the best.
Also, it allows to simplify reusing of HW block between different SoCs
- a lot of HW blocks in Keystone 2 are compatible to Davinci, but
used different set of clocks per HW block.

As for me, There are no need to force anyone to use anything :)
There are set of frameworks and Libs in Kernel which declared
as generic and the platform developer can select what is
the best for his Platform (another question is lack of documentation
for some of them).
Exception: some generic code is declared as deprecated.

So, please, treat all my previous comments as "recommendation" only :)

> 
> Still, of course runtime PM should be implemented, since it give you
> the option to gate your clocks at "request inactivity" and thus saving
> power.

Regards,
 - grygorii

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

* Common clock: function clock and bus clock
  2014-03-20  9:45 ` Ben Dooks
@ 2014-03-20 11:35   ` Russell King - ARM Linux
  0 siblings, 0 replies; 11+ messages in thread
From: Russell King - ARM Linux @ 2014-03-20 11:35 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Mar 20, 2014 at 10:45:27AM +0100, Ben Dooks wrote:
> On 11/03/14 03:06, Chao Xie wrote:
>> hi
>>
>> I can not find any examples for handling function clock and bus clock
>> in drivers/clk/.
>
> The convention is that clk_get(dev, NULL) will get the bus clock
> for the device and that any other clocks are appropriately named.

There is no such convention.  clk_get(dev, NULL) with clkdev (the
reference) will find a clock in the table for the device also with
a NULL connection ID.  That's the only "limitation".

There's no implication that NULL is some kind of bus clock.

-- 
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.

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

* Common clock: function clock and bus clock
  2014-03-13  2:15       ` Chao Xie
  2014-03-13  3:16         ` Emilio López
@ 2014-03-20 11:42         ` Russell King - ARM Linux
  1 sibling, 0 replies; 11+ messages in thread
From: Russell King - ARM Linux @ 2014-03-20 11:42 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Mar 13, 2014 at 10:15:20AM +0800, Chao Xie wrote:
> For a device, it has bus clock and function clock. usally bus clock is
> a gate type clock.
> 
> some devices share same bus clock, but have different function clock.
> If we want to use the device, we have to enable the bus clock and
> function clock both.
> 
> The problem is for some SOCes, there is no sharing of bus clock while
> for others, it has, and this limitation can happen at all clocks in
> clock domain.
> 
> So i do not want to make device driver be aware of it. I just let it
> know there is only one clock, and keep the dependency in clock
> framework.

This is something I really hate.  Of course the device driver needs to
be aware of it.

A dumb device driver which enables all its clocks at probe time and
turns them all off at remove time doesn't need to know about it, but
if you're doing something more clever - like what the clk API was
designed for such as power saving, where you would turn off the
function clock while it wasn't used but still access the device, then
the device driver /does/ need to have control of the two separately.

The big mistake here is everyone latching on to platform devices,
which provide almost zero assistance with any of this.  If you look
at something like the AMBA primecell stuff, then that:

- deals with runtime PM for the device driver before it's probed
- handles the device bus clock, ensuring that it is running for the
  probe, and disabling it after the remove
- provides the driver with a simple API to allow the bus clock to be
  disabled and re-enabled should the driver wish to go that far.

That's the right way to deal with this.

Note that the driver model maintainer, Greg KH, has stated a number of
times that he wishes people would stop using platform devices... so,
the solution here seems quite simple.

- Stop using platform devices
- Create a bus infrastructure which helps with this problem

And don't try and hide this kind of stuff inside the clk layer.

-- 
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.

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

end of thread, other threads:[~2014-03-20 11:42 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-03-11  2:06 Common clock: function clock and bus clock Chao Xie
2014-03-11  2:48 ` Haojian Zhuang
2014-03-12  2:30   ` Chao Xie
2014-03-12 10:14     ` Grygorii Strashko
2014-03-13  2:15       ` Chao Xie
2014-03-13  3:16         ` Emilio López
2014-03-13 11:30           ` Grygorii Strashko
     [not found]             ` <20140319210428.31449.19420@quantum>
     [not found]               ` <CAPDyKFqg230Ob5Wxu0tvXqia+B3WG5+YdKTdxTQ0ySbZokb+7Q@mail.gmail.com>
2014-03-20 10:30                 ` Grygorii Strashko
2014-03-20 11:42         ` Russell King - ARM Linux
2014-03-20  9:45 ` Ben Dooks
2014-03-20 11:35   ` Russell King - ARM Linux

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.