diff mbox

[3/4] clk: samsung: Add driver to control CLKOUT line on Exynos SoCs

Message ID 1400604211-9447-4-git-send-email-t.figa@samsung.com
State Accepted, archived
Commit 1e832e51018e960ecfc6f04abb1cbdd1ed82b8cb
Headers show

Commit Message

Tomasz Figa May 20, 2014, 4:43 p.m. UTC
This patch introduces a driver that handles configuration of CLKOUT pin
of Exynos SoCs that can be used to output certain clocks from inside of
the SoC to a dedicated output pin.

Signed-off-by: Tomasz Figa <t.figa@samsung.com>
---
 .../devicetree/bindings/arm/samsung/pmu.txt        |  30 ++++
 drivers/clk/samsung/Makefile                       |   1 +
 drivers/clk/samsung/clk-exynos-clkout.c            | 153 +++++++++++++++++++++
 3 files changed, 184 insertions(+)
 create mode 100644 drivers/clk/samsung/clk-exynos-clkout.c

Comments

Tushar Behera May 22, 2014, 4:28 a.m. UTC | #1
On 05/20/2014 10:13 PM, Tomasz Figa wrote:
> This patch introduces a driver that handles configuration of CLKOUT pin
> of Exynos SoCs that can be used to output certain clocks from inside of
> the SoC to a dedicated output pin.
> 
> Signed-off-by: Tomasz Figa <t.figa@samsung.com>
> ---
>  .../devicetree/bindings/arm/samsung/pmu.txt        |  30 ++++
>  drivers/clk/samsung/Makefile                       |   1 +
>  drivers/clk/samsung/clk-exynos-clkout.c            | 153 +++++++++++++++++++++
>  3 files changed, 184 insertions(+)
>  create mode 100644 drivers/clk/samsung/clk-exynos-clkout.c
> 
> diff --git a/Documentation/devicetree/bindings/arm/samsung/pmu.txt b/Documentation/devicetree/bindings/arm/samsung/pmu.txt
> index b562634..5ed94a9 100644
> --- a/Documentation/devicetree/bindings/arm/samsung/pmu.txt
> +++ b/Documentation/devicetree/bindings/arm/samsung/pmu.txt
> @@ -11,8 +11,38 @@ Properties:
>  
>   - reg : offset and length of the register set.
>  
> + - #clock-cells : must be <1>, since PMU requires once cell as clock specifier.

s/once/one

> +		The single specifier cell is used as index to list of clocks
> +		provided by PMU, which is currently:
> +			0 : SoC clock output (CLKOUT pin)

Will it make more sense if we add a macro for this clock number that
would be referred in the device tree files?

> +Example of clock consumer :
> +
> +usb3503: usb3503@08 {
> +	/* ... */
> +	clock-names = "refclk";
> +	clocks = <&pmu_system_controller 0>;
> +	/* ... */
>  };
Tushar Behera May 22, 2014, 5:13 a.m. UTC | #2
On 05/20/2014 10:13 PM, Tomasz Figa wrote:
> This patch introduces a driver that handles configuration of CLKOUT pin
> of Exynos SoCs that can be used to output certain clocks from inside of
> the SoC to a dedicated output pin.
> 
> Signed-off-by: Tomasz Figa <t.figa@samsung.com>
> ---
>  .../devicetree/bindings/arm/samsung/pmu.txt        |  30 ++++
>  drivers/clk/samsung/Makefile                       |   1 +
>  drivers/clk/samsung/clk-exynos-clkout.c            | 153 +++++++++++++++++++++
>  3 files changed, 184 insertions(+)
>  create mode 100644 drivers/clk/samsung/clk-exynos-clkout.c
> 

[ ... ]

> +	clkout->clk_table[0] = clk_register_composite(NULL, "clkout",
> +				parent_names, parent_count, &clkout->mux.hw,
> +				&clk_mux_ops, NULL, NULL, &clkout->gate.hw,
> +				&clk_gate_ops, CLK_SET_RATE_PARENT
> +				| CLK_SET_RATE_NO_REPARENT);

Would you please remove CLK_SET_RATE_NO_REPARENT flag from here? Let me
know if you have reservations against this.

With RFC patches, I am able to do a clk_set_rate() on this clock to
get a 24MHz output to the codec clock. With this flag set, I again have
to rely on the default value set to this register in bootloader.
Tomasz Figa May 22, 2014, 10:30 a.m. UTC | #3
On 22.05.2014 06:28, Tushar Behera wrote:
> On 05/20/2014 10:13 PM, Tomasz Figa wrote:
>> This patch introduces a driver that handles configuration of CLKOUT pin
>> of Exynos SoCs that can be used to output certain clocks from inside of
>> the SoC to a dedicated output pin.
>>
>> Signed-off-by: Tomasz Figa <t.figa@samsung.com>
>> ---
>>  .../devicetree/bindings/arm/samsung/pmu.txt        |  30 ++++
>>  drivers/clk/samsung/Makefile                       |   1 +
>>  drivers/clk/samsung/clk-exynos-clkout.c            | 153 +++++++++++++++++++++
>>  3 files changed, 184 insertions(+)
>>  create mode 100644 drivers/clk/samsung/clk-exynos-clkout.c
>>
>> diff --git a/Documentation/devicetree/bindings/arm/samsung/pmu.txt b/Documentation/devicetree/bindings/arm/samsung/pmu.txt
>> index b562634..5ed94a9 100644
>> --- a/Documentation/devicetree/bindings/arm/samsung/pmu.txt
>> +++ b/Documentation/devicetree/bindings/arm/samsung/pmu.txt
>> @@ -11,8 +11,38 @@ Properties:
>>  
>>   - reg : offset and length of the register set.
>>  
>> + - #clock-cells : must be <1>, since PMU requires once cell as clock specifier.
> 
> s/once/one
> 
>> +		The single specifier cell is used as index to list of clocks
>> +		provided by PMU, which is currently:
>> +			0 : SoC clock output (CLKOUT pin)
> 
> Will it make more sense if we add a macro for this clock number that
> would be referred in the device tree files?

Right now, with just one clock, it doesn't make sense, but if further
clocks show up with newer SoCs, then macros will have to be added.

Best regards,
Tomasz
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Tomasz Figa May 22, 2014, 10:34 a.m. UTC | #4
On 22.05.2014 07:13, Tushar Behera wrote:
> On 05/20/2014 10:13 PM, Tomasz Figa wrote:
>> This patch introduces a driver that handles configuration of CLKOUT pin
>> of Exynos SoCs that can be used to output certain clocks from inside of
>> the SoC to a dedicated output pin.
>>
>> Signed-off-by: Tomasz Figa <t.figa@samsung.com>
>> ---
>>  .../devicetree/bindings/arm/samsung/pmu.txt        |  30 ++++
>>  drivers/clk/samsung/Makefile                       |   1 +
>>  drivers/clk/samsung/clk-exynos-clkout.c            | 153 +++++++++++++++++++++
>>  3 files changed, 184 insertions(+)
>>  create mode 100644 drivers/clk/samsung/clk-exynos-clkout.c
>>
> 
> [ ... ]
> 
>> +	clkout->clk_table[0] = clk_register_composite(NULL, "clkout",
>> +				parent_names, parent_count, &clkout->mux.hw,
>> +				&clk_mux_ops, NULL, NULL, &clkout->gate.hw,
>> +				&clk_gate_ops, CLK_SET_RATE_PARENT
>> +				| CLK_SET_RATE_NO_REPARENT);
> 
> Would you please remove CLK_SET_RATE_NO_REPARENT flag from here? Let me
> know if you have reservations against this.

The problem with clock reparenting is that there are certain parent
clocks of CLKOUT, rate of which changes at runtime, e.g. clocks derived
from APLL or bus clocks, which can be reconfigured by cpufreq or devfreq.

> 
> With RFC patches, I am able to do a clk_set_rate() on this clock to
> get a 24MHz output to the codec clock. With this flag set, I again have
> to rely on the default value set to this register in bootloader.
> 

This problem should be handled by initializing clocks from DT. I'm not
sure why it hasn't been implemented yet...

Best regards,
Tomasz
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Tushar Behera May 22, 2014, 11:44 a.m. UTC | #5
On 22 May 2014 16:04, Tomasz Figa <t.figa@samsung.com> wrote:
> On 22.05.2014 07:13, Tushar Behera wrote:
>> On 05/20/2014 10:13 PM, Tomasz Figa wrote:
>>> This patch introduces a driver that handles configuration of CLKOUT pin
>>> of Exynos SoCs that can be used to output certain clocks from inside of
>>> the SoC to a dedicated output pin.
>>>
>>> Signed-off-by: Tomasz Figa <t.figa@samsung.com>
>>> ---
>>>  .../devicetree/bindings/arm/samsung/pmu.txt        |  30 ++++
>>>  drivers/clk/samsung/Makefile                       |   1 +
>>>  drivers/clk/samsung/clk-exynos-clkout.c            | 153 +++++++++++++++++++++
>>>  3 files changed, 184 insertions(+)
>>>  create mode 100644 drivers/clk/samsung/clk-exynos-clkout.c
>>>
>>
>> [ ... ]
>>
>>> +    clkout->clk_table[0] = clk_register_composite(NULL, "clkout",
>>> +                            parent_names, parent_count, &clkout->mux.hw,
>>> +                            &clk_mux_ops, NULL, NULL, &clkout->gate.hw,
>>> +                            &clk_gate_ops, CLK_SET_RATE_PARENT
>>> +                            | CLK_SET_RATE_NO_REPARENT);
>>
>> Would you please remove CLK_SET_RATE_NO_REPARENT flag from here? Let me
>> know if you have reservations against this.
>
> The problem with clock reparenting is that there are certain parent
> clocks of CLKOUT, rate of which changes at runtime, e.g. clocks derived
> from APLL or bus clocks, which can be reconfigured by cpufreq or devfreq.
>

+CC: Sylwester Nawrocki

Okay. But in cases where there is only 1 valid parent clock provided
through DT (at the moment for Exynos5250/Exynos5420), would it be safe
to set that clock as the parent of CLKOUT? Otherwise, this clock is
not usable ATM.

>>
>> With RFC patches, I am able to do a clk_set_rate() on this clock to
>> get a 24MHz output to the codec clock. With this flag set, I again have
>> to rely on the default value set to this register in bootloader.
>>
>
> This problem should be handled by initializing clocks from DT. I'm not
> sure why it hasn't been implemented yet...

I would be happy to get it done that way. I can see a patch from
Sylwester regarding this, but there hasn't been a conclusion as of
yet.

https://lkml.org/lkml/2014/4/9/173

Thanks,
Tomasz Figa May 22, 2014, 12:01 p.m. UTC | #6
On 22.05.2014 13:44, Tushar Behera wrote:
> On 22 May 2014 16:04, Tomasz Figa <t.figa@samsung.com> wrote:
>> On 22.05.2014 07:13, Tushar Behera wrote:
>>> On 05/20/2014 10:13 PM, Tomasz Figa wrote:
>>>> This patch introduces a driver that handles configuration of CLKOUT pin
>>>> of Exynos SoCs that can be used to output certain clocks from inside of
>>>> the SoC to a dedicated output pin.
>>>>
>>>> Signed-off-by: Tomasz Figa <t.figa@samsung.com>
>>>> ---
>>>>  .../devicetree/bindings/arm/samsung/pmu.txt        |  30 ++++
>>>>  drivers/clk/samsung/Makefile                       |   1 +
>>>>  drivers/clk/samsung/clk-exynos-clkout.c            | 153 +++++++++++++++++++++
>>>>  3 files changed, 184 insertions(+)
>>>>  create mode 100644 drivers/clk/samsung/clk-exynos-clkout.c
>>>>
>>>
>>> [ ... ]
>>>
>>>> +    clkout->clk_table[0] = clk_register_composite(NULL, "clkout",
>>>> +                            parent_names, parent_count, &clkout->mux.hw,
>>>> +                            &clk_mux_ops, NULL, NULL, &clkout->gate.hw,
>>>> +                            &clk_gate_ops, CLK_SET_RATE_PARENT
>>>> +                            | CLK_SET_RATE_NO_REPARENT);
>>>
>>> Would you please remove CLK_SET_RATE_NO_REPARENT flag from here? Let me
>>> know if you have reservations against this.
>>
>> The problem with clock reparenting is that there are certain parent
>> clocks of CLKOUT, rate of which changes at runtime, e.g. clocks derived
>> from APLL or bus clocks, which can be reconfigured by cpufreq or devfreq.
>>
> 
> +CC: Sylwester Nawrocki
> 
> Okay. But in cases where there is only 1 valid parent clock provided
> through DT (at the moment for Exynos5250/Exynos5420), would it be safe
> to set that clock as the parent of CLKOUT?

This is not something to rely on. I have simply omitted remaining CLKOUT
parents on Exynos 5 SoCs, as I don't have any board with them on which I
could test this. Eventually they will be added.

> Otherwise, this clock is
> not usable ATM.

On many boards it is already configured properly by the bootloader.
Although I don't see any reason why you couldn't reparent it in
(board-specific) sound card driver right now.

> 
>>>
>>> With RFC patches, I am able to do a clk_set_rate() on this clock to
>>> get a 24MHz output to the codec clock. With this flag set, I again have
>>> to rely on the default value set to this register in bootloader.
>>>
>>
>> This problem should be handled by initializing clocks from DT. I'm not
>> sure why it hasn't been implemented yet...
> 
> I would be happy to get it done that way. I can see a patch from
> Sylwester regarding this, but there hasn't been a conclusion as of
> yet.
> 
> https://lkml.org/lkml/2014/4/9/173

Have you mentioned your use case there? It might indicate that this is
indeed an important problem and that too much bikeshedding doesn't
really make us closer to the solution.

Best regards,
Tomasz
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Sylwester Nawrocki May 22, 2014, 12:10 p.m. UTC | #7
On 22/05/14 13:44, Tushar Behera wrote:
> On 22 May 2014 16:04, Tomasz Figa <t.figa@samsung.com> wrote:
>> On 22.05.2014 07:13, Tushar Behera wrote:
>>> On 05/20/2014 10:13 PM, Tomasz Figa wrote:
>>>> This patch introduces a driver that handles configuration of CLKOUT pin
>>>> of Exynos SoCs that can be used to output certain clocks from inside of
>>>> the SoC to a dedicated output pin.
>>>>
>>>> Signed-off-by: Tomasz Figa <t.figa@samsung.com>
>>>> ---
>>>>  .../devicetree/bindings/arm/samsung/pmu.txt        |  30 ++++
>>>>  drivers/clk/samsung/Makefile                       |   1 +
>>>>  drivers/clk/samsung/clk-exynos-clkout.c            | 153 +++++++++++++++++++++
>>>>  3 files changed, 184 insertions(+)
>>>>  create mode 100644 drivers/clk/samsung/clk-exynos-clkout.c
>>>>
>>>
>>> [ ... ]
>>>
>>>> +    clkout->clk_table[0] = clk_register_composite(NULL, "clkout",
>>>> +                            parent_names, parent_count, &clkout->mux.hw,
>>>> +                            &clk_mux_ops, NULL, NULL, &clkout->gate.hw,
>>>> +                            &clk_gate_ops, CLK_SET_RATE_PARENT
>>>> +                            | CLK_SET_RATE_NO_REPARENT);
>>>
>>> Would you please remove CLK_SET_RATE_NO_REPARENT flag from here? Let me
>>> know if you have reservations against this.
>>
>> The problem with clock reparenting is that there are certain parent
>> clocks of CLKOUT, rate of which changes at runtime, e.g. clocks derived
>> from APLL or bus clocks, which can be reconfigured by cpufreq or devfreq.
>>
> 
> +CC: Sylwester Nawrocki
> 
> Okay. But in cases where there is only 1 valid parent clock provided
> through DT (at the moment for Exynos5250/Exynos5420), would it be safe
> to set that clock as the parent of CLKOUT? Otherwise, this clock is
> not usable ATM.

I'd prefer to not allow re-parenting here, as it will not work in all system
configurations and seems not reliable in general.

>>> With RFC patches, I am able to do a clk_set_rate() on this clock to
>>> get a 24MHz output to the codec clock. With this flag set, I again have
>>> to rely on the default value set to this register in bootloader.
>>>
>>
>> This problem should be handled by initializing clocks from DT. I'm not
>> sure why it hasn't been implemented yet...
> 
> I would be happy to get it done that way. I can see a patch from
> Sylwester regarding this, but there hasn't been a conclusion as of
> yet.
> 
> https://lkml.org/lkml/2014/4/9/173

I posted a next version recently [1], any feedback on that is welcome.
I used these patches for the camera on Trats2 and the audio on Odroid U3
clocks configuration.

[1] http://www.spinics.net/lists/devicetree/msg34718.html

--
Thanks,
Sylwester
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Tushar Behera May 22, 2014, 12:14 p.m. UTC | #8
On 22 May 2014 17:31, Tomasz Figa <t.figa@samsung.com> wrote:
> On 22.05.2014 13:44, Tushar Behera wrote:
>> On 22 May 2014 16:04, Tomasz Figa <t.figa@samsung.com> wrote:
>>> On 22.05.2014 07:13, Tushar Behera wrote:
>>>> On 05/20/2014 10:13 PM, Tomasz Figa wrote:
>>>>> This patch introduces a driver that handles configuration of CLKOUT pin
>>>>> of Exynos SoCs that can be used to output certain clocks from inside of
>>>>> the SoC to a dedicated output pin.
>>>>>
>>>>> Signed-off-by: Tomasz Figa <t.figa@samsung.com>
>>>>> ---
>>>>>  .../devicetree/bindings/arm/samsung/pmu.txt        |  30 ++++
>>>>>  drivers/clk/samsung/Makefile                       |   1 +
>>>>>  drivers/clk/samsung/clk-exynos-clkout.c            | 153 +++++++++++++++++++++
>>>>>  3 files changed, 184 insertions(+)
>>>>>  create mode 100644 drivers/clk/samsung/clk-exynos-clkout.c
>>>>>
>>>>
>>>> [ ... ]
>>>>
>>>>> +    clkout->clk_table[0] = clk_register_composite(NULL, "clkout",
>>>>> +                            parent_names, parent_count, &clkout->mux.hw,
>>>>> +                            &clk_mux_ops, NULL, NULL, &clkout->gate.hw,
>>>>> +                            &clk_gate_ops, CLK_SET_RATE_PARENT
>>>>> +                            | CLK_SET_RATE_NO_REPARENT);
>>>>
>>>> Would you please remove CLK_SET_RATE_NO_REPARENT flag from here? Let me
>>>> know if you have reservations against this.
>>>
>>> The problem with clock reparenting is that there are certain parent
>>> clocks of CLKOUT, rate of which changes at runtime, e.g. clocks derived
>>> from APLL or bus clocks, which can be reconfigured by cpufreq or devfreq.
>>>
>>
>> +CC: Sylwester Nawrocki
>>
>> Okay. But in cases where there is only 1 valid parent clock provided
>> through DT (at the moment for Exynos5250/Exynos5420), would it be safe
>> to set that clock as the parent of CLKOUT?
>
> This is not something to rely on. I have simply omitted remaining CLKOUT
> parents on Exynos 5 SoCs, as I don't have any board with them on which I
> could test this. Eventually they will be added.
>
>> Otherwise, this clock is
>> not usable ATM.
>
> On many boards it is already configured properly by the bootloader.
> Although I don't see any reason why you couldn't reparent it in
> (board-specific) sound card driver right now.
>

Mark,

Is this (clock reparenting in sound card driver) an acceptable solution for you?
Sylwester Nawrocki May 22, 2014, 12:25 p.m. UTC | #9
On 22/05/14 14:01, Tomasz Figa wrote:
>>>> >>> [ ... ]
>>>> >>>
>>>>> >>>> +    clkout->clk_table[0] = clk_register_composite(NULL, "clkout",
>>>>> >>>> +                            parent_names, parent_count, &clkout->mux.hw,
>>>>> >>>> +                            &clk_mux_ops, NULL, NULL, &clkout->gate.hw,
>>>>> >>>> +                            &clk_gate_ops, CLK_SET_RATE_PARENT
>>>>> >>>> +                            | CLK_SET_RATE_NO_REPARENT);
>>>> >>>
>>>> >>> Would you please remove CLK_SET_RATE_NO_REPARENT flag from here? Let me
>>>> >>> know if you have reservations against this.
>>> >>
>>> >> The problem with clock reparenting is that there are certain parent
>>> >> clocks of CLKOUT, rate of which changes at runtime, e.g. clocks derived
>>> >> from APLL or bus clocks, which can be reconfigured by cpufreq or devfreq.
>>> >>
>> > 
>> > +CC: Sylwester Nawrocki
>> > 
>> > Okay. But in cases where there is only 1 valid parent clock provided
>> > through DT (at the moment for Exynos5250/Exynos5420), would it be safe
>> > to set that clock as the parent of CLKOUT?
>
> This is not something to rely on. I have simply omitted remaining CLKOUT
> parents on Exynos 5 SoCs, as I don't have any board with them on which I
> could test this. Eventually they will be added.
> 
>> > Otherwise, this clock is
>> > not usable ATM.
>
> On many boards it is already configured properly by the bootloader.
> Although I don't see any reason why you couldn't reparent it in
> (board-specific) sound card driver right now.

This would require passing the parent's clock specifier in 'clocks'
property of the sound card device node, which I assume is not something
we're generally expected to do in mainline. Although some drivers
happen to be doing it already I think that's a bad example. It sounds
like an abuse of the current clock bindings.

--
Regards,
Sylwester
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Tomasz Figa May 22, 2014, 12:32 p.m. UTC | #10
On 22.05.2014 14:25, Sylwester Nawrocki wrote:
> On 22/05/14 14:01, Tomasz Figa wrote:
>>>>>>>> [ ... ]
>>>>>>>>
>>>>>>>>>> +    clkout->clk_table[0] = clk_register_composite(NULL, "clkout",
>>>>>>>>>> +                            parent_names, parent_count, &clkout->mux.hw,
>>>>>>>>>> +                            &clk_mux_ops, NULL, NULL, &clkout->gate.hw,
>>>>>>>>>> +                            &clk_gate_ops, CLK_SET_RATE_PARENT
>>>>>>>>>> +                            | CLK_SET_RATE_NO_REPARENT);
>>>>>>>>
>>>>>>>> Would you please remove CLK_SET_RATE_NO_REPARENT flag from here? Let me
>>>>>>>> know if you have reservations against this.
>>>>>>
>>>>>> The problem with clock reparenting is that there are certain parent
>>>>>> clocks of CLKOUT, rate of which changes at runtime, e.g. clocks derived
>>>>>> from APLL or bus clocks, which can be reconfigured by cpufreq or devfreq.
>>>>>>
>>>>
>>>> +CC: Sylwester Nawrocki
>>>>
>>>> Okay. But in cases where there is only 1 valid parent clock provided
>>>> through DT (at the moment for Exynos5250/Exynos5420), would it be safe
>>>> to set that clock as the parent of CLKOUT?
>>
>> This is not something to rely on. I have simply omitted remaining CLKOUT
>> parents on Exynos 5 SoCs, as I don't have any board with them on which I
>> could test this. Eventually they will be added.
>>
>>>> Otherwise, this clock is
>>>> not usable ATM.
>>
>> On many boards it is already configured properly by the bootloader.
>> Although I don't see any reason why you couldn't reparent it in
>> (board-specific) sound card driver right now.
> 
> This would require passing the parent's clock specifier in 'clocks'
> property of the sound card device node, which I assume is not something
> we're generally expected to do in mainline. Although some drivers
> happen to be doing it already I think that's a bad example. It sounds
> like an abuse of the current clock bindings.

Well, an already board-specific driver might have some knowledge of the
SoC, so it might not be a huge problem, but I agree that this is not an
optimal solution.

Best regards,
Tomasz
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Mark Brown May 22, 2014, 7:20 p.m. UTC | #11
On Thu, May 22, 2014 at 02:01:24PM +0200, Tomasz Figa wrote:
> On 22.05.2014 13:44, Tushar Behera wrote:

> > I would be happy to get it done that way. I can see a patch from
> > Sylwester regarding this, but there hasn't been a conclusion as of
> > yet.

> > https://lkml.org/lkml/2014/4/9/173

> Have you mentioned your use case there? It might indicate that this is
> indeed an important problem and that too much bikeshedding doesn't
> really make us closer to the solution.

I've certainly discussed the requirement for this feature with Mike in
person a few times, I don't know if anyone else has been doing anything.
diff mbox

Patch

diff --git a/Documentation/devicetree/bindings/arm/samsung/pmu.txt b/Documentation/devicetree/bindings/arm/samsung/pmu.txt
index b562634..5ed94a9 100644
--- a/Documentation/devicetree/bindings/arm/samsung/pmu.txt
+++ b/Documentation/devicetree/bindings/arm/samsung/pmu.txt
@@ -11,8 +11,38 @@  Properties:
 
  - reg : offset and length of the register set.
 
+ - #clock-cells : must be <1>, since PMU requires once cell as clock specifier.
+		The single specifier cell is used as index to list of clocks
+		provided by PMU, which is currently:
+			0 : SoC clock output (CLKOUT pin)
+
+ - clock-names : list of clock names for particular CLKOUT mux inputs in
+		following format:
+			"clkoutN", where N is a decimal number corresponding to
+			CLKOUT mux control bits value for given input, e.g.
+				"clkout0", "clkout7", "clkout15".
+
+ - clocks : list of phandles and specifiers to all input clocks listed in
+		clock-names property.
+
 Example :
 pmu_system_controller: system-controller@10040000 {
 	compatible = "samsung,exynos5250-pmu", "syscon";
 	reg = <0x10040000 0x5000>;
+	#clock-cells = <1>;
+	clock-names = "clkout0", "clkout1", "clkout2", "clkout3",
+			"clkout4", "clkout8", "clkout9";
+	clocks = <&clock CLK_OUT_DMC>, <&clock CLK_OUT_TOP>,
+		<&clock CLK_OUT_LEFTBUS>, <&clock CLK_OUT_RIGHTBUS>,
+		<&clock CLK_OUT_CPU>, <&clock CLK_XXTI>,
+		<&clock CLK_XUSBXTI>;
+};
+
+Example of clock consumer :
+
+usb3503: usb3503@08 {
+	/* ... */
+	clock-names = "refclk";
+	clocks = <&pmu_system_controller 0>;
+	/* ... */
 };
diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
index 25646c6..efeb8e5 100644
--- a/drivers/clk/samsung/Makefile
+++ b/drivers/clk/samsung/Makefile
@@ -10,6 +10,7 @@  obj-$(CONFIG_SOC_EXYNOS5260)	+= clk-exynos5260.o
 obj-$(CONFIG_SOC_EXYNOS5420)	+= clk-exynos5420.o
 obj-$(CONFIG_SOC_EXYNOS5440)	+= clk-exynos5440.o
 obj-$(CONFIG_ARCH_EXYNOS)	+= clk-exynos-audss.o
+obj-$(CONFIG_ARCH_EXYNOS)	+= clk-exynos-clkout.o
 obj-$(CONFIG_S3C2410_COMMON_CLK)+= clk-s3c2410.o
 obj-$(CONFIG_S3C2410_COMMON_DCLK)+= clk-s3c2410-dclk.o
 obj-$(CONFIG_S3C2412_COMMON_CLK)+= clk-s3c2412.o
diff --git a/drivers/clk/samsung/clk-exynos-clkout.c b/drivers/clk/samsung/clk-exynos-clkout.c
new file mode 100644
index 0000000..3a7cb25
--- /dev/null
+++ b/drivers/clk/samsung/clk-exynos-clkout.c
@@ -0,0 +1,153 @@ 
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Author: Tomasz Figa <t.figa@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Clock driver for Exynos clock output
+ */
+
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/syscore_ops.h>
+
+#define EXYNOS_CLKOUT_NR_CLKS		1
+#define EXYNOS_CLKOUT_PARENTS		32
+
+#define EXYNOS_PMU_DEBUG_REG		0xa00
+#define EXYNOS_CLKOUT_DISABLE_SHIFT	0
+#define EXYNOS_CLKOUT_MUX_SHIFT		8
+#define EXYNOS4_CLKOUT_MUX_MASK		0xf
+#define EXYNOS5_CLKOUT_MUX_MASK		0x1f
+
+struct exynos_clkout {
+	struct clk_gate gate;
+	struct clk_mux mux;
+	spinlock_t slock;
+	struct clk_onecell_data data;
+	struct clk *clk_table[EXYNOS_CLKOUT_NR_CLKS];
+	void __iomem *reg;
+	u32 pmu_debug_save;
+};
+
+static struct exynos_clkout *clkout;
+
+static int exynos_clkout_suspend(void)
+{
+	clkout->pmu_debug_save = readl(clkout->reg + EXYNOS_PMU_DEBUG_REG);
+
+	return 0;
+}
+
+static void exynos_clkout_resume(void)
+{
+	writel(clkout->pmu_debug_save, clkout->reg + EXYNOS_PMU_DEBUG_REG);
+}
+
+static struct syscore_ops exynos_clkout_syscore_ops = {
+	.suspend = exynos_clkout_suspend,
+	.resume = exynos_clkout_resume,
+};
+
+static void __init exynos_clkout_init(struct device_node *node, u32 mux_mask)
+{
+	const char *parent_names[EXYNOS_CLKOUT_PARENTS];
+	struct clk *parents[EXYNOS_CLKOUT_PARENTS];
+	int parent_count;
+	int ret;
+	int i;
+
+	clkout = kzalloc(sizeof(*clkout), GFP_KERNEL);
+	if (!clkout)
+		return;
+
+	spin_lock_init(&clkout->slock);
+
+	parent_count = 0;
+	for (i = 0; i < EXYNOS_CLKOUT_PARENTS; ++i) {
+		char name[] = "clkoutXX";
+
+		snprintf(name, sizeof(name), "clkout%d", i);
+		parents[i] = of_clk_get_by_name(node, name);
+		if (IS_ERR(parents[i])) {
+			parent_names[i] = "none";
+			continue;
+		}
+
+		parent_names[i] = __clk_get_name(parents[i]);
+		parent_count = i + 1;
+	}
+
+	if (!parent_count)
+		goto free_clkout;
+
+	clkout->reg = of_iomap(node, 0);
+	if (!clkout->reg)
+		goto clks_put;
+
+	clkout->gate.reg = clkout->reg + EXYNOS_PMU_DEBUG_REG;
+	clkout->gate.bit_idx = EXYNOS_CLKOUT_DISABLE_SHIFT;
+	clkout->gate.flags = CLK_GATE_SET_TO_DISABLE;
+	clkout->gate.lock = &clkout->slock;
+
+	clkout->mux.reg = clkout->reg + EXYNOS_PMU_DEBUG_REG;
+	clkout->mux.mask = mux_mask;
+	clkout->mux.shift = EXYNOS_CLKOUT_MUX_SHIFT;
+	clkout->mux.lock = &clkout->slock;
+
+	clkout->clk_table[0] = clk_register_composite(NULL, "clkout",
+				parent_names, parent_count, &clkout->mux.hw,
+				&clk_mux_ops, NULL, NULL, &clkout->gate.hw,
+				&clk_gate_ops, CLK_SET_RATE_PARENT
+				| CLK_SET_RATE_NO_REPARENT);
+	if (IS_ERR(clkout->clk_table[0]))
+		goto err_unmap;
+
+	clkout->data.clks = clkout->clk_table;
+	clkout->data.clk_num = EXYNOS_CLKOUT_NR_CLKS;
+	ret = of_clk_add_provider(node, of_clk_src_onecell_get, &clkout->data);
+	if (ret)
+		goto err_clk_unreg;
+
+	register_syscore_ops(&exynos_clkout_syscore_ops);
+
+	return;
+
+err_clk_unreg:
+	clk_unregister(clkout->clk_table[0]);
+err_unmap:
+	iounmap(clkout->reg);
+clks_put:
+	for (i = 0; i < EXYNOS_CLKOUT_PARENTS; ++i)
+		if (!IS_ERR(parents[i]))
+			clk_put(parents[i]);
+free_clkout:
+	kfree(clkout);
+
+	pr_err("%s: failed to register clkout clock\n", __func__);
+}
+
+static void __init exynos4_clkout_init(struct device_node *node)
+{
+	exynos_clkout_init(node, EXYNOS4_CLKOUT_MUX_MASK);
+}
+CLK_OF_DECLARE(exynos4210_clkout, "samsung,exynos4210-pmu",
+		exynos4_clkout_init);
+CLK_OF_DECLARE(exynos4212_clkout, "samsung,exynos4212-pmu",
+		exynos4_clkout_init);
+CLK_OF_DECLARE(exynos4412_clkout, "samsung,exynos4412-pmu",
+		exynos4_clkout_init);
+
+static void __init exynos5_clkout_init(struct device_node *node)
+{
+	exynos_clkout_init(node, EXYNOS5_CLKOUT_MUX_MASK);
+}
+CLK_OF_DECLARE(exynos5250_clkout, "samsung,exynos5250-pmu",
+		exynos5_clkout_init);
+CLK_OF_DECLARE(exynos5420_clkout, "samsung,exynos5420-pmu",
+		exynos5_clkout_init);