* [PATCH 01/14] dt-bindings: Document STM32MP1 Reset Clock Controller (RCC) bindings
[not found] ` <1517580222-23301-1-git-send-email-gabriel.fernandez-qxv4g6HH51o@public.gmane.org>
@ 2018-02-02 14:03 ` gabriel.fernandez-qxv4g6HH51o
2018-02-05 6:09 ` Rob Herring
2018-02-02 14:03 ` [PATCH 03/14] clk: stm32mp1: Introduce STM32MP1 clock driver gabriel.fernandez-qxv4g6HH51o
` (6 subsequent siblings)
7 siblings, 1 reply; 22+ messages in thread
From: gabriel.fernandez-qxv4g6HH51o @ 2018-02-02 14:03 UTC (permalink / raw)
To: Rob Herring, Mark Rutland, Lee Jones, Maxime Coquelin,
Alexandre Torgue, Michael Turquette, Stephen Boyd,
Gabriel Fernandez
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-clk-u79uwXL29TY76Z2rM5mHXA,
gabriel.fernandez.st-Re5JQEeQqe8AvxtiuMwx3w,
olivier.bideau-qxv4g6HH51o
From: Gabriel Fernandez <gabriel.fernandez-qxv4g6HH51o@public.gmane.org>
The RCC block is responsible of the management of the clock and reset
generation for the complete circuit.
Signed-off-by: Gabriel Fernandez <gabriel.fernandez-qxv4g6HH51o@public.gmane.org>
---
.../devicetree/bindings/mfd/st,stm32-rcc.txt | 85 ++++++++++++++++++++++
1 file changed, 85 insertions(+)
create mode 100644 Documentation/devicetree/bindings/mfd/st,stm32-rcc.txt
diff --git a/Documentation/devicetree/bindings/mfd/st,stm32-rcc.txt b/Documentation/devicetree/bindings/mfd/st,stm32-rcc.txt
new file mode 100644
index 0000000..28017a1
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/st,stm32-rcc.txt
@@ -0,0 +1,85 @@
+STMicroelectronics STM32 Peripheral Reset Clock Controller
+==========================================================
+
+The RCC IP is both a reset and a clock controller.
+
+Please also refer to reset.txt for common reset controller binding usage.
+
+Please also refer to clock-bindings.txt for common clock controller
+binding usage.
+
+
+Required properties:
+- compatible: "simple-mfd", "syscon"
+- reg: should be register base and length as documented in the datasheet
+
+- Sub-nodes:
+ - compatible: "st,stm32mp1-rcc-clk"
+ - #clock-cells: 1, device nodes should specify the clock in their
+ "clocks" property, containing a phandle to the clock device node,
+ an index specifying the clock to use.
+
+ - compatible: "st,stm32mp1-rcc-rst"
+ - #reset-cells: Shall be 1
+
+Example:
+ rcc: rcc@50000000 {
+ compatible = "syscon", "simple-mfd";
+ reg = <0x50000000 0x1000>;
+
+ rcc_clk: rcc-clk@50000000 {
+ #clock-cells = <1>;
+ compatible = "st,stm32mp1-rcc-clk";
+ };
+
+ rcc_rst: rcc-reset@50000000 {
+ #reset-cells = <1>;
+ compatible = "st,stm32mp1-rcc-rst";
+ };
+ };
+
+Specifying clocks
+=================
+
+All available clocks are defined as preprocessor macros in
+dt-bindings/clock/stm32mp1-clks.h header and can be used in device
+tree sources.
+
+Example:
+
+ /* Accessing DMA1 clock */
+ ... {
+ clocks = <&rcc_clk DMA1>
+ };
+
+ /* Accessing SPI6 kernel clock */
+ ... {
+ clocks = <&rcc_clk SPI6_K>
+ };
+
+Specifying softreset control of devices
+=======================================
+
+Device nodes should specify the reset channel required in their "resets"
+property, containing a phandle to the reset device node and an index specifying
+which channel to use.
+The index is the bit number within the RCC registers bank, starting from RCC
+base address.
+It is calculated as: index = register_offset / 4 * 32 + bit_offset.
+Where bit_offset is the bit offset within the register.
+
+For example on STM32MP1, for LTDC reset:
+ ltdc = APB4_RSTSETR_offset / 4 * 32 + LTDC_bit_offset
+ = 0x180 / 4 * 32 + 0 = 3072
+
+The list of valid indices for STM32MP1 is available in:
+include/dt-bindings/reset-controller/stm32mp1-resets.h
+
+This file implements defines like:
+#define LTDC_R 3072
+
+example:
+
+ ltdc {
+ resets = <&rcc_rst LTDC_R>;
+ };
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH 01/14] dt-bindings: Document STM32MP1 Reset Clock Controller (RCC) bindings
2018-02-02 14:03 ` [PATCH 01/14] dt-bindings: Document STM32MP1 Reset Clock Controller (RCC) bindings gabriel.fernandez-qxv4g6HH51o
@ 2018-02-05 6:09 ` Rob Herring
2018-02-05 7:01 ` Gabriel FERNANDEZ
2018-02-05 7:15 ` Gabriel FERNANDEZ
0 siblings, 2 replies; 22+ messages in thread
From: Rob Herring @ 2018-02-05 6:09 UTC (permalink / raw)
To: gabriel.fernandez
Cc: Mark Rutland, Lee Jones, Maxime Coquelin, Alexandre Torgue,
Michael Turquette, Stephen Boyd, devicetree, linux-arm-kernel,
linux-kernel, linux-clk, gabriel.fernandez.st, olivier.bideau
On Fri, Feb 02, 2018 at 03:03:29PM +0100, gabriel.fernandez@st.com wrote:
> From: Gabriel Fernandez <gabriel.fernandez@st.com>
>
> The RCC block is responsible of the management of the clock and reset
> generation for the complete circuit.
>
> Signed-off-by: Gabriel Fernandez <gabriel.fernandez@st.com>
> ---
> .../devicetree/bindings/mfd/st,stm32-rcc.txt | 85 ++++++++++++++++++++++
> 1 file changed, 85 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/mfd/st,stm32-rcc.txt
>
> diff --git a/Documentation/devicetree/bindings/mfd/st,stm32-rcc.txt b/Documentation/devicetree/bindings/mfd/st,stm32-rcc.txt
> new file mode 100644
> index 0000000..28017a1
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mfd/st,stm32-rcc.txt
> @@ -0,0 +1,85 @@
> +STMicroelectronics STM32 Peripheral Reset Clock Controller
> +==========================================================
> +
> +The RCC IP is both a reset and a clock controller.
> +
> +Please also refer to reset.txt for common reset controller binding usage.
> +
> +Please also refer to clock-bindings.txt for common clock controller
> +binding usage.
> +
> +
> +Required properties:
> +- compatible: "simple-mfd", "syscon"
> +- reg: should be register base and length as documented in the datasheet
> +
> +- Sub-nodes:
> + - compatible: "st,stm32mp1-rcc-clk"
> + - #clock-cells: 1, device nodes should specify the clock in their
> + "clocks" property, containing a phandle to the clock device node,
> + an index specifying the clock to use.
> +
> + - compatible: "st,stm32mp1-rcc-rst"
> + - #reset-cells: Shall be 1
> +
> +Example:
> + rcc: rcc@50000000 {
> + compatible = "syscon", "simple-mfd";
> + reg = <0x50000000 0x1000>;
> +
> + rcc_clk: rcc-clk@50000000 {
> + #clock-cells = <1>;
> + compatible = "st,stm32mp1-rcc-clk";
> + };
> +
> + rcc_rst: rcc-reset@50000000 {
You should not have the same unit-address twice.
IMO, this should just be:
rcc: rcc@50000000 {
compatible = "st-stm32mp1-rcc";
reg = <0x50000000 0x1000>;
#clock-cells = <1>;
#reset-cells = <1>;
};
There's no reason a node can't provide more than 1 function.
> + #reset-cells = <1>;
> + compatible = "st,stm32mp1-rcc-rst";
> + };
> + };
> +
> +Specifying clocks
> +=================
> +
> +All available clocks are defined as preprocessor macros in
> +dt-bindings/clock/stm32mp1-clks.h header and can be used in device
> +tree sources.
> +
> +Example:
> +
> + /* Accessing DMA1 clock */
> + ... {
> + clocks = <&rcc_clk DMA1>
> + };
> +
> + /* Accessing SPI6 kernel clock */
> + ... {
> + clocks = <&rcc_clk SPI6_K>
> + };
Other than the path to header, the clock binding explains all this. No
need to duplicate here.
> +
> +Specifying softreset control of devices
> +=======================================
> +
> +Device nodes should specify the reset channel required in their "resets"
> +property, containing a phandle to the reset device node and an index specifying
> +which channel to use.
> +The index is the bit number within the RCC registers bank, starting from RCC
> +base address.
> +It is calculated as: index = register_offset / 4 * 32 + bit_offset.
> +Where bit_offset is the bit offset within the register.
> +
> +For example on STM32MP1, for LTDC reset:
> + ltdc = APB4_RSTSETR_offset / 4 * 32 + LTDC_bit_offset
> + = 0x180 / 4 * 32 + 0 = 3072
> +
> +The list of valid indices for STM32MP1 is available in:
> +include/dt-bindings/reset-controller/stm32mp1-resets.h
> +
> +This file implements defines like:
> +#define LTDC_R 3072
> +
> +example:
> +
> + ltdc {
> + resets = <&rcc_rst LTDC_R>;
> + };
> --
> 1.9.1
>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 01/14] dt-bindings: Document STM32MP1 Reset Clock Controller (RCC) bindings
2018-02-05 6:09 ` Rob Herring
@ 2018-02-05 7:01 ` Gabriel FERNANDEZ
2018-02-07 18:03 ` Rob Herring
2018-02-05 7:15 ` Gabriel FERNANDEZ
1 sibling, 1 reply; 22+ messages in thread
From: Gabriel FERNANDEZ @ 2018-02-05 7:01 UTC (permalink / raw)
To: Rob Herring
Cc: Mark Rutland, Lee Jones, Maxime Coquelin, Alexandre TORGUE,
Michael Turquette, Stephen Boyd, devicetree, linux-arm-kernel,
linux-kernel, linux-clk, gabriel.fernandez.st, Olivier BIDEAU
Hi Rob,
Thanks for reviewing.
On 02/05/2018 07:09 AM, Rob Herring wrote:
> On Fri, Feb 02, 2018 at 03:03:29PM +0100, gabriel.fernandez@st.com wrote:
>> From: Gabriel Fernandez <gabriel.fernandez@st.com>
>>
>> The RCC block is responsible of the management of the clock and reset
>> generation for the complete circuit.
>>
>> Signed-off-by: Gabriel Fernandez <gabriel.fernandez@st.com>
>> ---
>> .../devicetree/bindings/mfd/st,stm32-rcc.txt | 85 ++++++++++++++++++++++
>> 1 file changed, 85 insertions(+)
>> create mode 100644 Documentation/devicetree/bindings/mfd/st,stm32-rcc.txt
>>
>> diff --git a/Documentation/devicetree/bindings/mfd/st,stm32-rcc.txt b/Documentation/devicetree/bindings/mfd/st,stm32-rcc.txt
>> new file mode 100644
>> index 0000000..28017a1
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/mfd/st,stm32-rcc.txt
>> @@ -0,0 +1,85 @@
>> +STMicroelectronics STM32 Peripheral Reset Clock Controller
>> +==========================================================
>> +
>> +The RCC IP is both a reset and a clock controller.
>> +
>> +Please also refer to reset.txt for common reset controller binding usage.
>> +
>> +Please also refer to clock-bindings.txt for common clock controller
>> +binding usage.
>> +
>> +
>> +Required properties:
>> +- compatible: "simple-mfd", "syscon"
>
>> +- reg: should be register base and length as documented in the datasheet
>> +
>> +- Sub-nodes:
>> + - compatible: "st,stm32mp1-rcc-clk"
>> + - #clock-cells: 1, device nodes should specify the clock in their
>> + "clocks" property, containing a phandle to the clock device node,
>> + an index specifying the clock to use.
>> +
>> + - compatible: "st,stm32mp1-rcc-rst"
>> + - #reset-cells: Shall be 1
>> +
>> +Example:
>> + rcc: rcc@50000000 {
>> + compatible = "syscon", "simple-mfd";
>> + reg = <0x50000000 0x1000>;
>> +
>> + rcc_clk: rcc-clk@50000000 {
>> + #clock-cells = <1>;
>> + compatible = "st,stm32mp1-rcc-clk";
>> + };
>> +
>> + rcc_rst: rcc-reset@50000000 {
> You should not have the same unit-address twice.
>
> IMO, this should just be:
>
> rcc: rcc@50000000 {
> compatible = "st-stm32mp1-rcc";
> reg = <0x50000000 0x1000>;
> #clock-cells = <1>;
> #reset-cells = <1>;
> };
>
> There's no reason a node can't provide more than 1 function.
RCC is an dedicated IP for clocks and resets, but also for power
management (patches will be sent later)
Then i need to probe 3 drivers with same IP.
It's also a way to avoid use of 'CLK_OF_DECLARE_DRIVER' and i need it to
probe the 3th driver.
BR
Gabriel
>
>
>> + #reset-cells = <1>;
>> + compatible = "st,stm32mp1-rcc-rst";
>> + };
>> + };
>> +
>> +Specifying clocks
>> +=================
>> +
>> +All available clocks are defined as preprocessor macros in
>> +dt-bindings/clock/stm32mp1-clks.h header and can be used in device
>> +tree sources.
>> +
>> +Example:
>> +
>> + /* Accessing DMA1 clock */
>> + ... {
>> + clocks = <&rcc_clk DMA1>
>> + };
>> +
>> + /* Accessing SPI6 kernel clock */
>> + ... {
>> + clocks = <&rcc_clk SPI6_K>
>> + };
> Other than the path to header, the clock binding explains all this. No
> need to duplicate here.
ok
>> +
>> +Specifying softreset control of devices
>> +=======================================
>> +
>> +Device nodes should specify the reset channel required in their "resets"
>> +property, containing a phandle to the reset device node and an index specifying
>> +which channel to use.
>> +The index is the bit number within the RCC registers bank, starting from RCC
>> +base address.
>> +It is calculated as: index = register_offset / 4 * 32 + bit_offset.
>> +Where bit_offset is the bit offset within the register.
>> +
>> +For example on STM32MP1, for LTDC reset:
>> + ltdc = APB4_RSTSETR_offset / 4 * 32 + LTDC_bit_offset
>> + = 0x180 / 4 * 32 + 0 = 3072
>> +
>> +The list of valid indices for STM32MP1 is available in:
>> +include/dt-bindings/reset-controller/stm32mp1-resets.h
>> +
>> +This file implements defines like:
>> +#define LTDC_R 3072
>> +
>> +example:
>> +
>> + ltdc {
>> + resets = <&rcc_rst LTDC_R>;
>> + };
>> --
>> 1.9.1
>>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 01/14] dt-bindings: Document STM32MP1 Reset Clock Controller (RCC) bindings
2018-02-05 7:01 ` Gabriel FERNANDEZ
@ 2018-02-07 18:03 ` Rob Herring
2018-02-13 14:36 ` Gabriel FERNANDEZ
0 siblings, 1 reply; 22+ messages in thread
From: Rob Herring @ 2018-02-07 18:03 UTC (permalink / raw)
To: Gabriel FERNANDEZ
Cc: Mark Rutland, Lee Jones, Maxime Coquelin, Alexandre TORGUE,
Michael Turquette, Stephen Boyd, devicetree, linux-arm-kernel,
linux-kernel, linux-clk, gabriel.fernandez.st, Olivier BIDEAU
On Mon, Feb 5, 2018 at 1:01 AM, Gabriel FERNANDEZ
<gabriel.fernandez@st.com> wrote:
> Hi Rob,
>
> Thanks for reviewing.
>
>
> On 02/05/2018 07:09 AM, Rob Herring wrote:
>> On Fri, Feb 02, 2018 at 03:03:29PM +0100, gabriel.fernandez@st.com wrote:
>>> From: Gabriel Fernandez <gabriel.fernandez@st.com>
>>>
>>> The RCC block is responsible of the management of the clock and reset
>>> generation for the complete circuit.
>>>
>>> Signed-off-by: Gabriel Fernandez <gabriel.fernandez@st.com>
>>> ---
>>> .../devicetree/bindings/mfd/st,stm32-rcc.txt | 85 ++++++++++++++++++++++
>>> 1 file changed, 85 insertions(+)
>>> create mode 100644 Documentation/devicetree/bindings/mfd/st,stm32-rcc.txt
>>>
>>> diff --git a/Documentation/devicetree/bindings/mfd/st,stm32-rcc.txt b/Documentation/devicetree/bindings/mfd/st,stm32-rcc.txt
>>> new file mode 100644
>>> index 0000000..28017a1
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/mfd/st,stm32-rcc.txt
>>> @@ -0,0 +1,85 @@
>>> +STMicroelectronics STM32 Peripheral Reset Clock Controller
>>> +==========================================================
>>> +
>>> +The RCC IP is both a reset and a clock controller.
>>> +
>>> +Please also refer to reset.txt for common reset controller binding usage.
>>> +
>>> +Please also refer to clock-bindings.txt for common clock controller
>>> +binding usage.
>>> +
>>> +
>>> +Required properties:
>>> +- compatible: "simple-mfd", "syscon"
>>
>>> +- reg: should be register base and length as documented in the datasheet
>>> +
>>> +- Sub-nodes:
>>> + - compatible: "st,stm32mp1-rcc-clk"
>>> + - #clock-cells: 1, device nodes should specify the clock in their
>>> + "clocks" property, containing a phandle to the clock device node,
>>> + an index specifying the clock to use.
>>> +
>>> + - compatible: "st,stm32mp1-rcc-rst"
>>> + - #reset-cells: Shall be 1
>>> +
>>> +Example:
>>> + rcc: rcc@50000000 {
>>> + compatible = "syscon", "simple-mfd";
>>> + reg = <0x50000000 0x1000>;
>>> +
>>> + rcc_clk: rcc-clk@50000000 {
>>> + #clock-cells = <1>;
>>> + compatible = "st,stm32mp1-rcc-clk";
>>> + };
>>> +
>>> + rcc_rst: rcc-reset@50000000 {
>> You should not have the same unit-address twice.
>>
>> IMO, this should just be:
>>
>> rcc: rcc@50000000 {
>> compatible = "st-stm32mp1-rcc";
>> reg = <0x50000000 0x1000>;
>> #clock-cells = <1>;
>> #reset-cells = <1>;
>> };
>>
>> There's no reason a node can't provide more than 1 function.
> RCC is an dedicated IP for clocks and resets, but also for power
> management (patches will be sent later)
If there's additional functions, they should be part of the binding
now, not later. bindings should not unnecessarily evolve.
> Then i need to probe 3 drivers with same IP.
Drivers and DT nodes don't have to be 1-1. A parent driver can create
additional child devices.
Also, looking at your existing bindings for RCC IP, it is done as I suggested.
> It's also a way to avoid use of 'CLK_OF_DECLARE_DRIVER' and i need it to
> probe the 3th driver.
Sounds like a Linux problem, not a DT issue.
Rob
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 01/14] dt-bindings: Document STM32MP1 Reset Clock Controller (RCC) bindings
2018-02-07 18:03 ` Rob Herring
@ 2018-02-13 14:36 ` Gabriel FERNANDEZ
0 siblings, 0 replies; 22+ messages in thread
From: Gabriel FERNANDEZ @ 2018-02-13 14:36 UTC (permalink / raw)
To: Rob Herring
Cc: Mark Rutland, Lee Jones, Maxime Coquelin, Alexandre TORGUE,
Michael Turquette, Stephen Boyd, devicetree, linux-arm-kernel,
linux-kernel, linux-clk, gabriel.fernandez.st, Olivier BIDEAU
On 02/07/2018 07:03 PM, Rob Herring wrote:
> On Mon, Feb 5, 2018 at 1:01 AM, Gabriel FERNANDEZ
> <gabriel.fernandez@st.com> wrote:
>> Hi Rob,
>>
>> Thanks for reviewing.
>>
>>
>> On 02/05/2018 07:09 AM, Rob Herring wrote:
>>> On Fri, Feb 02, 2018 at 03:03:29PM +0100,gabriel.fernandez@st.com wrote:
>>>> From: Gabriel Fernandez<gabriel.fernandez@st.com>
>>>>
>>>> The RCC block is responsible of the management of the clock and reset
>>>> generation for the complete circuit.
>>>>
>>>> Signed-off-by: Gabriel Fernandez<gabriel.fernandez@st.com>
>>>> ---
>>>> .../devicetree/bindings/mfd/st,stm32-rcc.txt | 85 ++++++++++++++++++++++
>>>> 1 file changed, 85 insertions(+)
>>>> create mode 100644 Documentation/devicetree/bindings/mfd/st,stm32-rcc.txt
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/mfd/st,stm32-rcc.txt b/Documentation/devicetree/bindings/mfd/st,stm32-rcc.txt
>>>> new file mode 100644
>>>> index 0000000..28017a1
>>>> --- /dev/null
>>>> +++ b/Documentation/devicetree/bindings/mfd/st,stm32-rcc.txt
>>>> @@ -0,0 +1,85 @@
>>>> +STMicroelectronics STM32 Peripheral Reset Clock Controller
>>>> +==========================================================
>>>> +
>>>> +The RCC IP is both a reset and a clock controller.
>>>> +
>>>> +Please also refer to reset.txt for common reset controller binding usage.
>>>> +
>>>> +Please also refer to clock-bindings.txt for common clock controller
>>>> +binding usage.
>>>> +
>>>> +
>>>> +Required properties:
>>>> +- compatible: "simple-mfd", "syscon"
>>>> +- reg: should be register base and length as documented in the datasheet
>>>> +
>>>> +- Sub-nodes:
>>>> + - compatible: "st,stm32mp1-rcc-clk"
>>>> + - #clock-cells: 1, device nodes should specify the clock in their
>>>> + "clocks" property, containing a phandle to the clock device node,
>>>> + an index specifying the clock to use.
>>>> +
>>>> + - compatible: "st,stm32mp1-rcc-rst"
>>>> + - #reset-cells: Shall be 1
>>>> +
>>>> +Example:
>>>> + rcc: rcc@50000000 {
>>>> + compatible = "syscon", "simple-mfd";
>>>> + reg = <0x50000000 0x1000>;
>>>> +
>>>> + rcc_clk: rcc-clk@50000000 {
>>>> + #clock-cells = <1>;
>>>> + compatible = "st,stm32mp1-rcc-clk";
>>>> + };
>>>> +
>>>> + rcc_rst: rcc-reset@50000000 {
>>> You should not have the same unit-address twice.
>>>
>>> IMO, this should just be:
>>>
>>> rcc: rcc@50000000 {
>>> compatible = "st-stm32mp1-rcc";
>>> reg = <0x50000000 0x1000>;
>>> #clock-cells = <1>;
>>> #reset-cells = <1>;
>>> };
>>>
>>> There's no reason a node can't provide more than 1 function.
>> RCC is an dedicated IP for clocks and resets, but also for power
>> management (patches will be sent later)
> If there's additional functions, they should be part of the binding
> now, not later. bindings should not unnecessarily evolve.
Yes you're right i will do it.
>> Then i need to probe 3 drivers with same IP.
> Drivers and DT nodes don't have to be 1-1. A parent driver can create
> additional child devices.
>
> Also, looking at your existing bindings for RCC IP, it is done as I suggested.
>
>> It's also a way to avoid use of 'CLK_OF_DECLARE_DRIVER' and i need it to
>> probe the 3th driver.
> Sounds like a Linux problem, not a DT issue.
>
> Rob
RCC is an IP block wich exposed multiple functionalities (clock, reset,
power management),
mfd should be the best solution to populate each functionality in
natural way,
and to access to registers ?
Gabriel
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 01/14] dt-bindings: Document STM32MP1 Reset Clock Controller (RCC) bindings
2018-02-05 6:09 ` Rob Herring
2018-02-05 7:01 ` Gabriel FERNANDEZ
@ 2018-02-05 7:15 ` Gabriel FERNANDEZ
1 sibling, 0 replies; 22+ messages in thread
From: Gabriel FERNANDEZ @ 2018-02-05 7:15 UTC (permalink / raw)
To: Rob Herring
Cc: Mark Rutland, Lee Jones, Maxime Coquelin, Alexandre TORGUE,
Michael Turquette, Stephen Boyd,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-clk-u79uwXL29TY76Z2rM5mHXA,
gabriel.fernandez.st-Re5JQEeQqe8AvxtiuMwx3w, Olivier BIDEAU
On 02/05/2018 07:09 AM, Rob Herring wrote:
> On Fri, Feb 02, 2018 at 03:03:29PM +0100, gabriel.fernandez@st.com wrote:
>> From: Gabriel Fernandez <gabriel.fernandez@st.com>
>>
>> The RCC block is responsible of the management of the clock and reset
>> generation for the complete circuit.
>>
>> Signed-off-by: Gabriel Fernandez <gabriel.fernandez@st.com>
>> ---
>> .../devicetree/bindings/mfd/st,stm32-rcc.txt | 85 ++++++++++++++++++++++
>> 1 file changed, 85 insertions(+)
>> create mode 100644 Documentation/devicetree/bindings/mfd/st,stm32-rcc.txt
>>
>> diff --git a/Documentation/devicetree/bindings/mfd/st,stm32-rcc.txt b/Documentation/devicetree/bindings/mfd/st,stm32-rcc.txt
>> new file mode 100644
>> index 0000000..28017a1
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/mfd/st,stm32-rcc.txt
>> @@ -0,0 +1,85 @@
>> +STMicroelectronics STM32 Peripheral Reset Clock Controller
>> +==========================================================
>> +
>> +The RCC IP is both a reset and a clock controller.
>> +
>> +Please also refer to reset.txt for common reset controller binding usage.
>> +
>> +Please also refer to clock-bindings.txt for common clock controller
>> +binding usage.
>> +
>> +
>> +Required properties:
>> +- compatible: "simple-mfd", "syscon"
>
>> +- reg: should be register base and length as documented in the datasheet
>> +
>> +- Sub-nodes:
>> + - compatible: "st,stm32mp1-rcc-clk"
>> + - #clock-cells: 1, device nodes should specify the clock in their
>> + "clocks" property, containing a phandle to the clock device node,
>> + an index specifying the clock to use.
>> +
>> + - compatible: "st,stm32mp1-rcc-rst"
>> + - #reset-cells: Shall be 1
>> +
>> +Example:
>> + rcc: rcc@50000000 {
>> + compatible = "syscon", "simple-mfd";
>> + reg = <0x50000000 0x1000>;
>> +
>> + rcc_clk: rcc-clk@50000000 {
>> + #clock-cells = <1>;
>> + compatible = "st,stm32mp1-rcc-clk";
>> + };
>> +
>> + rcc_rst: rcc-reset@50000000 {
> You should not have the same unit-address twice.
i can change if you want into:
rcc: rcc@50000000 {
compatible = "syscon", "simple-mfd";
reg = <0x50000000 0x1000>;
rcc_clk: rcc-clk {
#clock-cells = <1>;
compatible = "st,stm32mp1-rcc-clk";
};
rcc_rst: rcc-reset {
#reset-cells = <1>;
compatible = "st,stm32mp1-rcc-rst";
};
BR
Gabriel
> IMO, this should just be:
>
> rcc: rcc@50000000 {
> compatible = "st-stm32mp1-rcc";
> reg = <0x50000000 0x1000>;
> #clock-cells = <1>;
> #reset-cells = <1>;
> };
>
> There's no reason a node can't provide more than 1 function.
>
>
>> + #reset-cells = <1>;
>> + compatible = "st,stm32mp1-rcc-rst";
>> + };
>> + };
>> +
>> +Specifying clocks
>> +=================
>> +
>> +All available clocks are defined as preprocessor macros in
>> +dt-bindings/clock/stm32mp1-clks.h header and can be used in device
>> +tree sources.
>> +
>> +Example:
>> +
>> + /* Accessing DMA1 clock */
>> + ... {
>> + clocks = <&rcc_clk DMA1>
>> + };
>> +
>> + /* Accessing SPI6 kernel clock */
>> + ... {
>> + clocks = <&rcc_clk SPI6_K>
>> + };
> Other than the path to header, the clock binding explains all this. No
> need to duplicate here.
>
>> +
>> +Specifying softreset control of devices
>> +=======================================
>> +
>> +Device nodes should specify the reset channel required in their "resets"
>> +property, containing a phandle to the reset device node and an index specifying
>> +which channel to use.
>> +The index is the bit number within the RCC registers bank, starting from RCC
>> +base address.
>> +It is calculated as: index = register_offset / 4 * 32 + bit_offset.
>> +Where bit_offset is the bit offset within the register.
>> +
>> +For example on STM32MP1, for LTDC reset:
>> + ltdc = APB4_RSTSETR_offset / 4 * 32 + LTDC_bit_offset
>> + = 0x180 / 4 * 32 + 0 = 3072
>> +
>> +The list of valid indices for STM32MP1 is available in:
>> +include/dt-bindings/reset-controller/stm32mp1-resets.h
>> +
>> +This file implements defines like:
>> +#define LTDC_R 3072
>> +
>> +example:
>> +
>> + ltdc {
>> + resets = <&rcc_rst LTDC_R>;
>> + };
>> --
>> 1.9.1
>>
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH 03/14] clk: stm32mp1: Introduce STM32MP1 clock driver
[not found] ` <1517580222-23301-1-git-send-email-gabriel.fernandez-qxv4g6HH51o@public.gmane.org>
2018-02-02 14:03 ` [PATCH 01/14] dt-bindings: Document STM32MP1 Reset Clock Controller (RCC) bindings gabriel.fernandez-qxv4g6HH51o
@ 2018-02-02 14:03 ` gabriel.fernandez-qxv4g6HH51o
2018-02-02 14:03 ` [PATCH 05/14] clk: stm32mp1: add Source Clocks for PLLs gabriel.fernandez-qxv4g6HH51o
` (5 subsequent siblings)
7 siblings, 0 replies; 22+ messages in thread
From: gabriel.fernandez-qxv4g6HH51o @ 2018-02-02 14:03 UTC (permalink / raw)
To: Rob Herring, Mark Rutland, Lee Jones, Maxime Coquelin,
Alexandre Torgue, Michael Turquette, Stephen Boyd,
Gabriel Fernandez
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-clk-u79uwXL29TY76Z2rM5mHXA,
gabriel.fernandez.st-Re5JQEeQqe8AvxtiuMwx3w,
olivier.bideau-qxv4g6HH51o
From: Gabriel Fernandez <gabriel.fernandez-qxv4g6HH51o@public.gmane.org>
This patch introduces the mechanism to probe stm32mp1 driver.
It also defines registers and clocks source definition.
This patch also introduces the generic mechanism to register
a clock (a simple gate).
All clocks will be defined in one table.
Signed-off-by: Gabriel Fernandez <gabriel.fernandez-qxv4g6HH51o@public.gmane.org>
---
drivers/clk/Kconfig | 6 +
drivers/clk/Makefile | 1 +
drivers/clk/clk-stm32mp1.c | 513 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 520 insertions(+)
create mode 100644 drivers/clk/clk-stm32mp1.c
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 1c4e1aa..517c4b3 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -226,6 +226,12 @@ config COMMON_CLK_VC5
This driver supports the IDT VersaClock 5 and VersaClock 6
programmable clock generators.
+config COMMON_CLK_STM32MP157
+ def_bool COMMON_CLK && MACH_STM32MP157
+ help
+ ---help---
+ Support for stm32mp157 SoC family clocks
+
source "drivers/clk/bcm/Kconfig"
source "drivers/clk/hisilicon/Kconfig"
source "drivers/clk/imgtec/Kconfig"
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index f7f761b..69f6f59 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_COMMON_CLK_SI514) += clk-si514.o
obj-$(CONFIG_COMMON_CLK_SI570) += clk-si570.o
obj-$(CONFIG_ARCH_STM32) += clk-stm32f4.o
obj-$(CONFIG_ARCH_STM32) += clk-stm32h7.o
+obj-$(CONFIG_COMMON_CLK_STM32MP157) += clk-stm32mp1.o
obj-$(CONFIG_ARCH_TANGO) += clk-tango4.o
obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o
obj-$(CONFIG_ARCH_U300) += clk-u300.o
diff --git a/drivers/clk/clk-stm32mp1.c b/drivers/clk/clk-stm32mp1.c
new file mode 100644
index 0000000..6e39e85
--- /dev/null
+++ b/drivers/clk/clk-stm32mp1.c
@@ -0,0 +1,513 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) STMicroelectronics 2018 - All Rights Reserved
+ * Author: Olivier Bideau <olivier.bideau-qxv4g6HH51o@public.gmane.org> for STMicroelectronics.
+ * Author: Gabriel Fernandez <gabriel.fernandez-qxv4g6HH51o@public.gmane.org> for STMicroelectronics.
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+
+#include <dt-bindings/clock/stm32mp1-clks.h>
+
+static DEFINE_SPINLOCK(rlock);
+
+#define RCC_OCENSETR 0x0C
+#define RCC_OCENCLRR 0x10
+#define RCC_OCRDYR 0x808
+#define RCC_HSICFGR 0x18
+#define RCC_RDLSICR 0x144
+#define RCC_PLL1CR 0x80
+#define RCC_PLL1CFGR1 0x84
+#define RCC_PLL1CFGR2 0x88
+#define RCC_PLL2CR 0x94
+#define RCC_PLL2CFGR1 0x98
+#define RCC_PLL2CFGR2 0x9C
+#define RCC_PLL3CR 0x880
+#define RCC_PLL3CFGR1 0x884
+#define RCC_PLL3CFGR2 0x888
+#define RCC_PLL4CR 0x894
+#define RCC_PLL4CFGR1 0x898
+#define RCC_PLL4CFGR2 0x89C
+#define RCC_APB1ENSETR 0xA00
+#define RCC_APB2ENSETR 0xA08
+#define RCC_APB3ENSETR 0xA10
+#define RCC_APB4ENSETR 0x200
+#define RCC_APB5ENSETR 0x208
+#define RCC_AHB2ENSETR 0xA18
+#define RCC_AHB3ENSETR 0xA20
+#define RCC_AHB4ENSETR 0xA28
+#define RCC_AHB5ENSETR 0x210
+#define RCC_AHB6ENSETR 0x218
+#define RCC_AHB6LPENSETR 0x318
+#define RCC_RCK12SELR 0x28
+#define RCC_RCK3SELR 0x820
+#define RCC_RCK4SELR 0x824
+#define RCC_MPCKSELR 0x20
+#define RCC_ASSCKSELR 0x24
+#define RCC_MSSCKSELR 0x48
+#define RCC_SPI6CKSELR 0xC4
+#define RCC_SDMMC12CKSELR 0x8F4
+#define RCC_SDMMC3CKSELR 0x8F8
+#define RCC_FMCCKSELR 0x904
+#define RCC_I2C4CKSELR 0xC0
+#define RCC_I2C12CKSELR 0x8C0
+#define RCC_I2C35CKSELR 0x8C4
+#define RCC_UART1CKSELR 0xC8
+#define RCC_QSPICKSELR 0x900
+#define RCC_ETHCKSELR 0x8FC
+#define RCC_RNG1CKSELR 0xCC
+#define RCC_RNG2CKSELR 0x920
+#define RCC_GPUCKSELR 0x938
+#define RCC_USBCKSELR 0x91C
+#define RCC_STGENCKSELR 0xD4
+#define RCC_SPDIFCKSELR 0x914
+#define RCC_SPI2S1CKSELR 0x8D8
+#define RCC_SPI2S23CKSELR 0x8DC
+#define RCC_SPI2S45CKSELR 0x8E0
+#define RCC_CECCKSELR 0x918
+#define RCC_LPTIM1CKSELR 0x934
+#define RCC_LPTIM23CKSELR 0x930
+#define RCC_LPTIM45CKSELR 0x92C
+#define RCC_UART24CKSELR 0x8E8
+#define RCC_UART35CKSELR 0x8EC
+#define RCC_UART6CKSELR 0x8E4
+#define RCC_UART78CKSELR 0x8F0
+#define RCC_DFSDMCKSELR 0x910
+#define RCC_FDCANCKSELR 0x90C
+#define RCC_SAI1CKSELR 0x8C8
+#define RCC_SAI2CKSELR 0x8CC
+#define RCC_SAI3CKSELR 0x8D0
+#define RCC_SAI4CKSELR 0x8D4
+#define RCC_ADCCKSELR 0x928
+#define RCC_MPCKDIVR 0x2C
+#define RCC_DSICKSELR 0x924
+#define RCC_CPERCKSELR 0xD0
+#define RCC_GRSTCSETR 0x404
+#define RCC_MCO1CFGR 0x800
+#define RCC_MCO2CFGR 0x804
+#define RCC_BDCR 0x140
+#define RCC_AXIDIVR 0x30
+#define RCC_MCUDIVR 0x830
+#define RCC_APB1DIVR 0x834
+#define RCC_APB2DIVR 0x838
+#define RCC_APB3DIVR 0x83C
+#define RCC_APB4DIVR 0x3C
+#define RCC_APB5DIVR 0x40
+#define RCC_TIMG1PRER 0x828
+#define RCC_TIMG2PRER 0x82C
+#define RCC_RTCDIVR 0x44
+#define RCC_DBGCFGR 0x80C
+
+#define RCC_CLR 0x4
+
+static const char * const ref12_parents[] = {
+ "ck_hsi", "ck_hse"
+};
+
+static const char * const ref3_parents[] = {
+ "ck_hsi", "ck_hse", "ck_csi"
+};
+
+static const char * const ref4_parents[] = {
+ "ck_hsi", "ck_hse", "ck_csi"
+};
+
+static const char * const cpu_src[] = {
+ "ck_hsi", "ck_hse", "pll1_p"
+};
+
+static const char * const axi_src[] = {
+ "ck_hsi", "ck_hse", "pll2_p", "pll3_p"
+};
+
+static const char * const per_src[] = {
+ "ck_hsi", "ck_csi", "ck_hse"
+};
+
+static const char * const mcu_src[] = {
+ "ck_hsi", "ck_hse", "ck_csi", "pll3_p"
+};
+
+static const char * const sdmmc1_src[] = {
+ "ck_axi", "pll3_r", "pll4_p", "ck_hsi"
+};
+
+static const char * const sdmmc2_src[] = {
+ "ck_axi", "pll3_r", "pll4_p", "ck_hsi"
+};
+
+static const char * const sdmmc3_src[] = {
+ "ck_mcu", "pll3_r", "pll4_p", "ck_hsi"
+};
+
+static const char * const fmc_src[] = {
+ "ck_axi", "pll3_r", "pll4_p", "ck_per"
+};
+
+static const char * const qspi_src[] = {
+ "ck_axi", "pll3_r", "pll4_p", "ck_per"
+};
+
+static const char * const eth_src[] = {
+ "pll4_p", "pll3_q"
+};
+
+static const char * const rng_src[] = {
+ "ck_csi", "pll4_r", "ck_lse", "ck_lsi"
+};
+
+static const char * const usbphy_src[] = {
+ "ck_hse", "pll4_r", "clk-hse-div2"
+};
+
+static const char * const usbo_src[] = {
+ "pll4_r", "ck_usbo_48m"
+};
+
+static const char * const stgen_src[] = {
+ "ck_hsi", "ck_hse"
+};
+
+static const char * const spdif_src[] = {
+ "pll4_p", "pll3_q", "ck_hsi"
+};
+
+static const char * const spi1_src[] = {
+ "pll4_p", "pll3_q", "i2s_ckin", "ck_per"
+};
+
+static const char * const spi2_src[] = {
+ "pll4_p", "pll3_q", "i2s_ckin", "ck_per"
+};
+
+static const char * const spi3_src[] = {
+ "pll4_p", "pll3_q", "i2s_ckin", "ck_per"
+};
+
+static const char * const spi4_src[] = {
+ "pclk2", "pll4_q", "ck_hsi", "ck_csi", "ck_hse"
+};
+
+const char * const spi5_src[] = {
+ "pclk2", "pll4_q", "ck_hsi", "ck_csi", "ck_hse"
+};
+
+static const char * const spi6_src[] = {
+ "pclk5", "pll4_q", "ck_hsi", "ck_csi", "ck_hse", "pll3_q"
+};
+
+static const char * const cec_src[] = {
+ "ck_lse", "ck_lsi", "ck_csi"
+};
+
+static const char * const i2c1_src[] = {
+ "pclk1", "pll4_r", "ck_hsi", "ck_csi"
+};
+
+static const char * const i2c2_src[] = {
+ "pclk1", "pll4_r", "ck_hsi", "ck_csi"
+};
+
+static const char * const i2c3_src[] = {
+ "pclk1", "pll4_r", "ck_hsi", "ck_csi"
+};
+
+static const char * const i2c4_src[] = {
+ "pclk5", "pll3_q", "ck_hsi", "ck_csi"
+};
+
+static const char * const i2c5_src[] = {
+ "pclk1", "pll4_r", "ck_hsi", "ck_csi"
+};
+
+static const char * const i2c6_src[] = {
+ "pclk5", "pll3_q", "ck_hsi", "ck_csi"
+};
+
+static const char * const lptim1_src[] = {
+ "pclk1", "pll4_p", "pll3_q", "ck_lse", "ck_lsi", "ck_per"
+};
+
+static const char * const lptim2_src[] = {
+ "pclk3", "pll4_q", "ck_per", "ck_lse", "ck_lsi"
+};
+
+static const char * const lptim3_src[] = {
+ "pclk3", "pll4_q", "ck_per", "ck_lse", "ck_lsi"
+};
+
+static const char * const lptim4_src[] = {
+ "pclk3", "pll4_p", "pll3_q", "ck_lse", "ck_lsi", "ck_per"
+};
+
+static const char * const lptim5_src[] = {
+ "pclk3", "pll4_p", "pll3_q", "ck_lse", "ck_lsi", "ck_per"
+};
+
+static const char * const usart1_src[] = {
+ "pclk5", "pll3_q", "ck_hsi", "ck_csi", "pll4_q", "ck_hse"
+};
+
+const char * const usart2_src[] = {
+ "pclk1", "pll4_q", "ck_hsi", "ck_csi", "ck_hse"
+};
+
+static const char * const usart3_src[] = {
+ "pclk1", "pll4_q", "ck_hsi", "ck_csi", "ck_hse"
+};
+
+static const char * const uart4_src[] = {
+ "pclk1", "pll4_q", "ck_hsi", "ck_csi", "ck_hse"
+};
+
+static const char * const uart5_src[] = {
+ "pclk1", "pll4_q", "ck_hsi", "ck_csi", "ck_hse"
+};
+
+static const char * const usart6_src[] = {
+ "pclk2", "pll4_q", "ck_hsi", "ck_csi", "ck_hse"
+};
+
+static const char * const uart7_src[] = {
+ "pclk1", "pll4_q", "ck_hsi", "ck_csi", "ck_hse"
+};
+
+static const char * const uart8_src[] = {
+ "pclk1", "pll4_q", "ck_hsi", "ck_csi", "ck_hse"
+};
+
+static const char * const adfsdm_src[] = {
+ "pll4_q", "pll3_q", "i2s_ckin", "ck_per"
+};
+
+static const char * const dfsdm_src[] = {
+ "pclk2", "ck_mcu"
+};
+
+static const char * const fdcan_src[] = {
+ "ck_hse", "pll3_q", "pll4_q"
+};
+
+static const char * const sai_src[] = {
+ "pll4_q", "pll3_q", "i2s_ckin", "ck_per"
+};
+
+static const char * const sai2_src[] = {
+ "pll4_q", "pll3_q", "i2s_ckin", "ck_per", "spdif_ck_symb"
+};
+
+static const char * const adc12_src[] = {
+ "pll4_q", "ck_per"
+};
+
+static const char * const dsi_src[] = {
+ "ck_dsi_phy", "pll4_p"
+};
+
+static const char * const rtc_src[] = {
+ "off", "ck_lse", "ck_lsi", "ck_hse_rtc"
+};
+
+static const char * const ltdc_src[] = {
+ "pll4_q"
+};
+
+static const char * const ck_trace_src[] = {
+ "ck_axi"
+};
+
+static const char * const mco1_src[] = {
+ "ck_hsi", "ck_hse", "ck_csi", "ck_lsi", "ck_lse"
+};
+
+static const char * const mco2_src[] = {
+ "ck_mpu", "ck_axi", "ck_mcu", "pll4_p", "ck_hse", "ck_hsi"
+};
+
+struct clock_config {
+ u32 id;
+ const char *name;
+ union {
+ const char *parent_name;
+ const char * const *parent_names;
+ };
+ int num_parents;
+ unsigned long flags;
+ void *cfg;
+ struct clk_hw * (*func)(struct device *dev,
+ struct clk_hw_onecell_data *clk_data,
+ void __iomem *base, spinlock_t *lock,
+ const struct clock_config *cfg);
+};
+
+#define NO_ID ~0
+
+struct gate_cfg {
+ u32 reg_off;
+ u8 bit_idx;
+ u8 gate_flags;
+};
+
+static struct clk_hw *
+_clk_hw_register_gate(struct device *dev,
+ struct clk_hw_onecell_data *clk_data,
+ void __iomem *base, spinlock_t *lock,
+ const struct clock_config *cfg)
+{
+ struct gate_cfg *gate_cfg = cfg->cfg;
+
+ return clk_hw_register_gate(dev,
+ cfg->name,
+ cfg->parent_name,
+ cfg->flags,
+ gate_cfg->reg_off + base,
+ gate_cfg->bit_idx,
+ gate_cfg->gate_flags,
+ lock);
+}
+
+#define GATE(_id, _name, _parent, _flags, _offset, _bit_idx, _gate_flags)\
+{\
+ .id = _id,\
+ .name = _name,\
+ .parent_name = _parent,\
+ .flags = _flags,\
+ .cfg = &(struct gate_cfg) {\
+ .reg_off = _offset,\
+ .bit_idx = _bit_idx,\
+ .gate_flags = _gate_flags,\
+ },\
+ .func = _clk_hw_register_gate,\
+}
+
+static const struct clock_config stm32mp1_clock_cfg[] = {
+ /* External / Internal Oscillators */
+ GATE(CK_LSI, "ck_lsi", "clk-lsi", 0, RCC_RDLSICR, 0, 0),
+ GATE(CK_LSE, "ck_lse", "clk-lse", 0, RCC_BDCR, 0, 0),
+};
+
+struct stm32_clock_match_data {
+ const struct clock_config *cfg;
+ unsigned int num;
+ unsigned int maxbinding;
+};
+
+static struct stm32_clock_match_data stm32mp1_data = {
+ .cfg = stm32mp1_clock_cfg,
+ .num = ARRAY_SIZE(stm32mp1_clock_cfg),
+ .maxbinding = STM32MP1_LAST_CLK,
+};
+
+static const struct of_device_id stm32mp1_match_data[] = {
+ {
+ .compatible = "st,stm32mp1-rcc-clk",
+ .data = &stm32mp1_data,
+ },
+ { }
+};
+
+static int stm32_register_hw_clk(struct device *dev,
+ struct clk_hw_onecell_data *clk_data,
+ void __iomem *base, spinlock_t *lock,
+ const struct clock_config *cfg)
+{
+ static struct clk_hw **hws;
+ struct clk_hw *hw = ERR_PTR(-ENOENT);
+
+ hws = clk_data->hws;
+
+ if (cfg->func)
+ hw = (*cfg->func)(dev, clk_data, base, lock, cfg);
+
+ if (IS_ERR(hw)) {
+ pr_err("Unable to register %s\n", cfg->name);
+ return PTR_ERR(hw);
+ }
+
+ if (cfg->id != NO_ID)
+ hws[cfg->id] = hw;
+
+ return 0;
+}
+
+static int stm32_rcc_init(struct device_node *np,
+ void __iomem *base,
+ const struct of_device_id *match_data)
+{
+ struct clk_hw_onecell_data *clk_data;
+ struct clk_hw **hws;
+ const struct of_device_id *match;
+ const struct stm32_clock_match_data *data;
+ int err, n, max_binding;
+
+ match = of_match_node(match_data, np);
+ if (!match) {
+ pr_err("%s: match data not found\n", __func__);
+ return -ENODEV;
+ }
+
+ data = match->data;
+
+ max_binding = data->maxbinding;
+
+ clk_data = kzalloc(sizeof(*clk_data) +
+ sizeof(*clk_data->hws) * max_binding,
+ GFP_KERNEL);
+ if (!clk_data)
+ return -ENOMEM;
+
+ clk_data->num = max_binding;
+
+ hws = clk_data->hws;
+
+ for (n = 0; n < max_binding; n++)
+ hws[n] = ERR_PTR(-ENOENT);
+
+ for (n = 0; n < data->num; n++) {
+ err = stm32_register_hw_clk(NULL, clk_data, base, &rlock,
+ &data->cfg[n]);
+ if (err) {
+ pr_err("%s: can't register %s\n", __func__,
+ data->cfg[n].name);
+
+ kfree(clk_data);
+
+ return err;
+ }
+ }
+
+ return of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data);
+}
+
+static void stm32mp1_rcc_init(struct device_node *np)
+{
+ struct device_node *parent;
+ void __iomem *base;
+
+ parent = of_get_parent(np);
+ if (!parent) {
+ pr_err("%s: parent should be syscon node\n", __func__);
+ return;
+ }
+
+ base = of_iomap(parent, 0);
+ if (!base) {
+ pr_err("%s: unable to map resource", parent->name);
+ of_node_put(parent);
+ return;
+ }
+
+ if (stm32_rcc_init(np, base, stm32mp1_match_data)) {
+ iounmap(base);
+ of_node_put(parent);
+ }
+}
+
+CLK_OF_DECLARE(stm32mp1_rcc, "st,stm32mp1-rcc-clk", stm32mp1_rcc_init);
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 05/14] clk: stm32mp1: add Source Clocks for PLLs
[not found] ` <1517580222-23301-1-git-send-email-gabriel.fernandez-qxv4g6HH51o@public.gmane.org>
2018-02-02 14:03 ` [PATCH 01/14] dt-bindings: Document STM32MP1 Reset Clock Controller (RCC) bindings gabriel.fernandez-qxv4g6HH51o
2018-02-02 14:03 ` [PATCH 03/14] clk: stm32mp1: Introduce STM32MP1 clock driver gabriel.fernandez-qxv4g6HH51o
@ 2018-02-02 14:03 ` gabriel.fernandez-qxv4g6HH51o
2018-02-02 14:03 ` [PATCH 06/14] clk: stm32mp1: add PLL clocks gabriel.fernandez-qxv4g6HH51o
` (4 subsequent siblings)
7 siblings, 0 replies; 22+ messages in thread
From: gabriel.fernandez-qxv4g6HH51o @ 2018-02-02 14:03 UTC (permalink / raw)
To: Rob Herring, Mark Rutland, Lee Jones, Maxime Coquelin,
Alexandre Torgue, Michael Turquette, Stephen Boyd,
Gabriel Fernandez
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-clk-u79uwXL29TY76Z2rM5mHXA,
gabriel.fernandez.st-Re5JQEeQqe8AvxtiuMwx3w,
olivier.bideau-qxv4g6HH51o
From: Gabriel Fernandez <gabriel.fernandez-qxv4g6HH51o@public.gmane.org>
This patch adds source clocks for PLLs
This patch also introduces MUX clock API.
Signed-off-by: Gabriel Fernandez <gabriel.fernandez-qxv4g6HH51o@public.gmane.org>
---
drivers/clk/clk-stm32mp1.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 48 insertions(+)
diff --git a/drivers/clk/clk-stm32mp1.c b/drivers/clk/clk-stm32mp1.c
index be5a4e5..1c9a84a 100644
--- a/drivers/clk/clk-stm32mp1.c
+++ b/drivers/clk/clk-stm32mp1.c
@@ -368,6 +368,14 @@ struct div_cfg {
const struct clk_div_table *table;
};
+struct mux_cfg {
+ u32 reg_off;
+ u8 shift;
+ u8 width;
+ u8 mux_flags;
+ u32 *table;
+};
+
static struct clk_hw *
_clk_hw_register_gate(struct device *dev,
struct clk_hw_onecell_data *clk_data,
@@ -419,6 +427,20 @@ struct div_cfg {
lock);
}
+static struct clk_hw *
+_clk_hw_register_mux(struct device *dev,
+ struct clk_hw_onecell_data *clk_data,
+ void __iomem *base, spinlock_t *lock,
+ const struct clock_config *cfg)
+{
+ struct mux_cfg *mux_cfg = cfg->cfg;
+
+ return clk_hw_register_mux(dev, cfg->name, cfg->parent_names,
+ cfg->num_parents, cfg->flags,
+ mux_cfg->reg_off + base, mux_cfg->shift,
+ mux_cfg->width, mux_cfg->mux_flags, lock);
+}
+
/* MP1 Gate clock with set & clear registers */
static int mp1_gate_clk_enable(struct clk_hw *hw)
@@ -550,6 +572,22 @@ static struct clk_hw *clk_register_mp1_gate(struct device *dev,
DIV_TABLE(_id, _name, _parent, _flags, _offset, _shift, _width,\
_div_flags, NULL)
+#define MUX(_id, _name, _parents, _flags, _offset, _shift, _width, _mux_flags)\
+{\
+ .id = _id,\
+ .name = _name,\
+ .parent_names = _parents,\
+ .num_parents = ARRAY_SIZE(_parents),\
+ .flags = _flags,\
+ .cfg = &(struct mux_cfg) {\
+ .reg_off = _offset,\
+ .shift = _shift,\
+ .width = _width,\
+ .mux_flags = _mux_flags,\
+ },\
+ .func = _clk_hw_register_mux,\
+}
+
#define MP1_GATE(_id, _name, _parent, _flags, _offset, _bit_idx, _gate_flags)\
{\
.id = _id,\
@@ -577,6 +615,16 @@ static struct clk_hw *clk_register_mp1_gate(struct device *dev,
GATE(CK_LSE, "ck_lse", "clk-lse", 0, RCC_BDCR, 0, 0),
FIXED_FACTOR(CK_HSE_DIV2, "clk-hse-div2", "ck_hse", 0, 1, 2),
+
+ /* ref clock pll */
+ MUX(NO_ID, "ref1", ref12_parents, CLK_OPS_PARENT_ENABLE, RCC_RCK12SELR,
+ 0, 2, CLK_MUX_READ_ONLY),
+
+ MUX(NO_ID, "ref3", ref3_parents, CLK_OPS_PARENT_ENABLE, RCC_RCK3SELR,
+ 0, 2, CLK_MUX_READ_ONLY),
+
+ MUX(NO_ID, "ref4", ref4_parents, CLK_OPS_PARENT_ENABLE, RCC_RCK4SELR,
+ 0, 2, CLK_MUX_READ_ONLY),
};
struct stm32_clock_match_data {
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 06/14] clk: stm32mp1: add PLL clocks
[not found] ` <1517580222-23301-1-git-send-email-gabriel.fernandez-qxv4g6HH51o@public.gmane.org>
` (2 preceding siblings ...)
2018-02-02 14:03 ` [PATCH 05/14] clk: stm32mp1: add Source Clocks for PLLs gabriel.fernandez-qxv4g6HH51o
@ 2018-02-02 14:03 ` gabriel.fernandez-qxv4g6HH51o
2018-02-02 14:03 ` [PATCH 07/14] clk: stm32mp1: add Post-dividers for PLL gabriel.fernandez-qxv4g6HH51o
` (3 subsequent siblings)
7 siblings, 0 replies; 22+ messages in thread
From: gabriel.fernandez-qxv4g6HH51o @ 2018-02-02 14:03 UTC (permalink / raw)
To: Rob Herring, Mark Rutland, Lee Jones, Maxime Coquelin,
Alexandre Torgue, Michael Turquette, Stephen Boyd,
Gabriel Fernandez
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-clk-u79uwXL29TY76Z2rM5mHXA,
gabriel.fernandez.st-Re5JQEeQqe8AvxtiuMwx3w,
olivier.bideau-qxv4g6HH51o
From: Gabriel Fernandez <gabriel.fernandez-qxv4g6HH51o@public.gmane.org>
STMP32MP1 has 4 PLLs.
PLL supports integer and fractional mode.
Each PLL has 3 output dividers (p, q, r)
Signed-off-by: Gabriel Fernandez <gabriel.fernandez-qxv4g6HH51o@public.gmane.org>
---
drivers/clk/clk-stm32mp1.c | 209 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 209 insertions(+)
diff --git a/drivers/clk/clk-stm32mp1.c b/drivers/clk/clk-stm32mp1.c
index 1c9a84a..33f0d09 100644
--- a/drivers/clk/clk-stm32mp1.c
+++ b/drivers/clk/clk-stm32mp1.c
@@ -7,6 +7,7 @@
#include <linux/clk.h>
#include <linux/clk-provider.h>
+#include <linux/delay.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/of.h>
@@ -506,6 +507,181 @@ static struct clk_hw *clk_register_mp1_gate(struct device *dev,
return hw;
}
+/* STM32 PLL */
+
+struct stm32_pll_obj {
+ /* lock pll enable/disable registers */
+ spinlock_t *lock;
+ void __iomem *reg;
+ struct clk_hw hw;
+};
+
+#define to_pll(_hw) container_of(_hw, struct stm32_pll_obj, hw)
+
+#define PLL_ON BIT(0)
+#define PLL_RDY BIT(1)
+#define DIVN_MASK 0x1FF
+#define DIVM_MASK 0x3F
+#define DIVM_SHIFT 16
+#define DIVN_SHIFT 0
+#define FRAC_OFFSET 0xC
+#define FRAC_MASK 0x1FFF
+#define FRAC_SHIFT 3
+#define FRACLE BIT(16)
+
+static int __pll_is_enabled(struct clk_hw *hw)
+{
+ struct stm32_pll_obj *clk_elem = to_pll(hw);
+
+ return readl_relaxed(clk_elem->reg) & PLL_ON;
+}
+
+#define TIMEOUT 5
+
+static int pll_enable(struct clk_hw *hw)
+{
+ struct stm32_pll_obj *clk_elem = to_pll(hw);
+ u32 reg;
+ unsigned long flags = 0;
+ unsigned int timeout = TIMEOUT;
+ int bit_status = 0;
+
+ spin_lock_irqsave(clk_elem->lock, flags);
+
+ if (__pll_is_enabled(hw))
+ goto unlock;
+
+ reg = readl_relaxed(clk_elem->reg);
+ reg |= PLL_ON;
+ writel_relaxed(reg, clk_elem->reg);
+
+ /* We can't use readl_poll_timeout() because we can be blocked if
+ * someone enables this clock before clocksource changes.
+ * Only jiffies counter is available. Jiffies are incremented by
+ * interruptions and enable op does not allow to be interrupted.
+ */
+ do {
+ bit_status = !(readl_relaxed(clk_elem->reg) & PLL_RDY);
+
+ if (bit_status)
+ udelay(120);
+
+ } while (bit_status && --timeout);
+
+unlock:
+ spin_unlock_irqrestore(clk_elem->lock, flags);
+
+ return bit_status;
+}
+
+static void pll_disable(struct clk_hw *hw)
+{
+ struct stm32_pll_obj *clk_elem = to_pll(hw);
+ u32 reg;
+ unsigned long flags = 0;
+
+ spin_lock_irqsave(clk_elem->lock, flags);
+
+ reg = readl_relaxed(clk_elem->reg);
+ reg &= ~PLL_ON;
+ writel_relaxed(reg, clk_elem->reg);
+
+ spin_unlock_irqrestore(clk_elem->lock, flags);
+}
+
+static u32 pll_frac_val(struct clk_hw *hw)
+{
+ struct stm32_pll_obj *clk_elem = to_pll(hw);
+ u32 reg, frac = 0;
+
+ reg = readl_relaxed(clk_elem->reg + FRAC_OFFSET);
+ if (reg & FRACLE)
+ frac = (reg >> FRAC_SHIFT) & FRAC_MASK;
+
+ return frac;
+}
+
+static unsigned long pll_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct stm32_pll_obj *clk_elem = to_pll(hw);
+ u32 reg;
+ u32 frac, divm, divn;
+ u64 rate, rate_frac = 0;
+
+ reg = readl_relaxed(clk_elem->reg + 4);
+
+ divm = ((reg >> DIVM_SHIFT) & DIVM_MASK) + 1;
+ divn = ((reg >> DIVN_SHIFT) & DIVN_MASK) + 1;
+ rate = (u64)parent_rate * divn;
+
+ do_div(rate, divm);
+
+ frac = pll_frac_val(hw);
+ if (frac) {
+ rate_frac = (u64)parent_rate * (u64)frac;
+ do_div(rate_frac, (divm * 8192));
+ }
+
+ return rate + rate_frac;
+}
+
+static int pll_is_enabled(struct clk_hw *hw)
+{
+ struct stm32_pll_obj *clk_elem = to_pll(hw);
+ unsigned long flags = 0;
+ int ret;
+
+ spin_lock_irqsave(clk_elem->lock, flags);
+ ret = __pll_is_enabled(hw);
+ spin_unlock_irqrestore(clk_elem->lock, flags);
+
+ return ret;
+}
+
+static const struct clk_ops pll_ops = {
+ .enable = pll_enable,
+ .disable = pll_disable,
+ .recalc_rate = pll_recalc_rate,
+ .is_enabled = pll_is_enabled,
+};
+
+static struct clk_hw *clk_register_pll(struct device *dev, const char *name,
+ const char *parent_name,
+ void __iomem *reg,
+ unsigned long flags,
+ spinlock_t *lock)
+{
+ struct stm32_pll_obj *element;
+ struct clk_init_data init;
+ struct clk_hw *hw;
+ int err;
+
+ element = kzalloc(sizeof(*element), GFP_KERNEL);
+ if (!element)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = name;
+ init.ops = &pll_ops;
+ init.flags = flags;
+ init.parent_names = &parent_name;
+ init.num_parents = 1;
+
+ element->hw.init = &init;
+ element->reg = reg;
+ element->lock = lock;
+
+ hw = &element->hw;
+ err = clk_hw_register(dev, hw);
+
+ if (err) {
+ kfree(element);
+ return ERR_PTR(err);
+ }
+
+ return hw;
+}
+
static struct clk_hw *
_clk_register_mp1_gate(struct device *dev,
struct clk_hw_onecell_data *clk_data,
@@ -524,6 +700,21 @@ static struct clk_hw *clk_register_mp1_gate(struct device *dev,
lock);
}
+struct stm32_pll_cfg {
+ u32 offset;
+};
+
+struct clk_hw *_clk_register_pll(struct device *dev,
+ struct clk_hw_onecell_data *clk_data,
+ void __iomem *base, spinlock_t *lock,
+ const struct clock_config *cfg)
+{
+ struct stm32_pll_cfg *stm_pll_cfg = cfg->cfg;
+
+ return clk_register_pll(dev, cfg->name, cfg->parent_name,
+ base + stm_pll_cfg->offset, cfg->flags, lock);
+}
+
#define GATE(_id, _name, _parent, _flags, _offset, _bit_idx, _gate_flags)\
{\
.id = _id,\
@@ -602,6 +793,18 @@ static struct clk_hw *clk_register_mp1_gate(struct device *dev,
.func = _clk_register_mp1_gate,\
}
+#define PLL(_id, _name, _parent, _flags, _offset)\
+{\
+ .id = _id,\
+ .name = _name,\
+ .parent_name = _parent,\
+ .flags = _flags,\
+ .cfg = &(struct stm32_pll_cfg) {\
+ .offset = _offset,\
+ },\
+ .func = _clk_register_pll,\
+}
+
static const struct clock_config stm32mp1_clock_cfg[] = {
/* Oscillator divider */
DIV(NO_ID, "clk-hsi-div", "clk-hsi", 0, RCC_HSICFGR, 0, 2,
@@ -625,6 +828,12 @@ static struct clk_hw *clk_register_mp1_gate(struct device *dev,
MUX(NO_ID, "ref4", ref4_parents, CLK_OPS_PARENT_ENABLE, RCC_RCK4SELR,
0, 2, CLK_MUX_READ_ONLY),
+
+ /* PLLs */
+ PLL(PLL1, "pll1", "ref1", CLK_IGNORE_UNUSED, RCC_PLL1CR),
+ PLL(PLL2, "pll2", "ref1", CLK_IGNORE_UNUSED, RCC_PLL2CR),
+ PLL(PLL3, "pll3", "ref3", CLK_IGNORE_UNUSED, RCC_PLL3CR),
+ PLL(PLL4, "pll4", "ref4", CLK_IGNORE_UNUSED, RCC_PLL4CR),
};
struct stm32_clock_match_data {
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 07/14] clk: stm32mp1: add Post-dividers for PLL
[not found] ` <1517580222-23301-1-git-send-email-gabriel.fernandez-qxv4g6HH51o@public.gmane.org>
` (3 preceding siblings ...)
2018-02-02 14:03 ` [PATCH 06/14] clk: stm32mp1: add PLL clocks gabriel.fernandez-qxv4g6HH51o
@ 2018-02-02 14:03 ` gabriel.fernandez-qxv4g6HH51o
2018-02-02 14:03 ` [PATCH 08/14] clk: stm32mp1: add Sub System clocks gabriel.fernandez-qxv4g6HH51o
` (2 subsequent siblings)
7 siblings, 0 replies; 22+ messages in thread
From: gabriel.fernandez-qxv4g6HH51o @ 2018-02-02 14:03 UTC (permalink / raw)
To: Rob Herring, Mark Rutland, Lee Jones, Maxime Coquelin,
Alexandre Torgue, Michael Turquette, Stephen Boyd,
Gabriel Fernandez
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-clk-u79uwXL29TY76Z2rM5mHXA,
gabriel.fernandez.st-Re5JQEeQqe8AvxtiuMwx3w,
olivier.bideau-qxv4g6HH51o
From: Gabriel Fernandez <gabriel.fernandez-qxv4g6HH51o@public.gmane.org>
Each PLL has 3 outputs with post-dividers.
pll1_p is dedicated for Cortex-A7
pll1_q is not connected
pll1_r is not connected
pll2_p is dedicated for AXI
pll2_q is dedicated for GPU
pll2_r is dedicated for DDR
pll3_p is dedicated for mcu
pll3_q is for Peripheral Kernel Clock
pll3_r is for Peripheral Kernel Clock
pll4_p is for Peripheral Kernel Clock
pll4_q is for Peripheral Kernel Clock
pll4_r is for Peripheral Kernel Clock
Signed-off-by: Gabriel Fernandez <gabriel.fernandez-qxv4g6HH51o@public.gmane.org>
---
drivers/clk/clk-stm32mp1.c | 257 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 257 insertions(+)
diff --git a/drivers/clk/clk-stm32mp1.c b/drivers/clk/clk-stm32mp1.c
index 33f0d09..15cd488 100644
--- a/drivers/clk/clk-stm32mp1.c
+++ b/drivers/clk/clk-stm32mp1.c
@@ -377,6 +377,147 @@ struct mux_cfg {
u32 *table;
};
+/* STM32 Composite clock */
+struct composite_cfg {
+ struct gate_cfg *gate;
+ struct mux_cfg *mux;
+ struct div_cfg *div;
+ const struct clk_ops *mux_ops;
+ const struct clk_ops *div_ops;
+ const struct clk_ops *gate_ops;
+};
+
+static struct clk_mux *_get_cmux(void __iomem *reg, u8 shift, u8 width,
+ u32 flags, u32 *table, spinlock_t *lock)
+{
+ struct clk_mux *mux;
+
+ mux = kzalloc(sizeof(*mux), GFP_KERNEL);
+ if (!mux)
+ return ERR_PTR(-ENOMEM);
+
+ mux->reg = reg;
+ mux->shift = shift;
+ mux->mask = (1 << width) - 1;
+ mux->flags = flags;
+ mux->lock = lock;
+ mux->table = table;
+
+ return mux;
+}
+
+static struct clk_divider *_get_cdiv(void __iomem *reg, u8 shift, u8 width,
+ u32 flags,
+ const struct clk_div_table *table,
+ spinlock_t *lock)
+{
+ struct clk_divider *div;
+
+ div = kzalloc(sizeof(*div), GFP_KERNEL);
+
+ if (!div)
+ return ERR_PTR(-ENOMEM);
+
+ div->reg = reg;
+ div->shift = shift;
+ div->width = width;
+ div->flags = flags;
+ div->lock = lock;
+ div->table = table;
+
+ return div;
+}
+
+static struct clk_gate *_get_cgate(void __iomem *reg, u8 bit_idx, u32 flags,
+ spinlock_t *lock)
+{
+ struct clk_gate *gate;
+
+ gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+ if (!gate)
+ return ERR_PTR(-ENOMEM);
+
+ gate->reg = reg;
+ gate->bit_idx = bit_idx;
+ gate->flags = flags;
+ gate->lock = lock;
+
+ return gate;
+}
+
+static struct clk_hw *
+clk_stm_register_composite(struct device *dev,
+ const char *name, const char * const *parent_names,
+ int num_parents, void __iomem *base,
+ const struct composite_cfg *cfg,
+ unsigned long flags, spinlock_t *lock)
+{
+ struct clk_mux *mux = NULL;
+ struct clk_divider *div = NULL;
+ struct clk_gate *gate = NULL;
+ const struct clk_ops *mux_ops, *div_ops, *gate_ops;
+ struct clk_hw *hw;
+ struct clk_hw *mux_hw;
+ struct clk_hw *div_hw;
+ struct clk_hw *gate_hw;
+
+ mux_hw = NULL;
+ div_hw = NULL;
+ gate_hw = NULL;
+ mux_ops = NULL;
+ div_ops = NULL;
+ gate_ops = NULL;
+
+ if (cfg->mux) {
+ mux = _get_cmux(base + cfg->mux->reg_off,
+ cfg->mux->shift,
+ cfg->mux->width,
+ cfg->mux->mux_flags,
+ cfg->mux->table,
+ lock);
+
+ if (!IS_ERR(mux)) {
+ mux_hw = &mux->hw;
+ mux_ops = cfg->mux_ops ?
+ cfg->mux_ops : &clk_mux_ops;
+ }
+ }
+
+ if (cfg->div) {
+ div = _get_cdiv(base + cfg->div->reg_off,
+ cfg->div->shift,
+ cfg->div->width,
+ cfg->div->div_flags,
+ cfg->div->table,
+ lock);
+
+ if (!IS_ERR(div)) {
+ div_hw = &div->hw;
+ div_ops = cfg->div_ops ?
+ cfg->div_ops : &clk_divider_ops;
+ }
+ }
+
+ if (cfg->gate) {
+ gate = _get_cgate(base + cfg->gate->reg_off,
+ cfg->gate->bit_idx,
+ cfg->gate->gate_flags,
+ lock);
+
+ if (!IS_ERR(gate)) {
+ gate_hw = &gate->hw;
+ gate_ops = cfg->gate_ops ?
+ cfg->gate_ops : &clk_gate_ops;
+ }
+ }
+
+ hw = clk_hw_register_composite(dev, name, parent_names, num_parents,
+ mux_hw, mux_ops, div_hw, div_ops,
+ gate_hw, gate_ops, flags);
+
+ return hw;
+}
+
static struct clk_hw *
_clk_hw_register_gate(struct device *dev,
struct clk_hw_onecell_data *clk_data,
@@ -442,6 +583,17 @@ struct mux_cfg {
mux_cfg->width, mux_cfg->mux_flags, lock);
}
+static struct clk_hw *
+_clk_stm_register_composite(struct device *dev,
+ struct clk_hw_onecell_data *clk_data,
+ void __iomem *base, spinlock_t *lock,
+ const struct clock_config *cfg)
+{
+ return clk_stm_register_composite(dev, cfg->name, cfg->parent_names,
+ cfg->num_parents, base, cfg->cfg,
+ cfg->flags, lock);
+}
+
/* MP1 Gate clock with set & clear registers */
static int mp1_gate_clk_enable(struct clk_hw *hw)
@@ -779,6 +931,76 @@ struct clk_hw *_clk_register_pll(struct device *dev,
.func = _clk_hw_register_mux,\
}
+#define COMPOSITE(_id, _name, _parents, _flags, _cfg)\
+{\
+ .id = _id,\
+ .name = _name,\
+ .parent_names = _parents,\
+ .num_parents = ARRAY_SIZE(_parents),\
+ .flags = _flags,\
+ .cfg = &(struct composite_cfg)_cfg,\
+ .func = _clk_stm_register_composite,\
+}
+
+#define PARENT(_parent) ((const char *[]) { _parent})
+
+#define _NO_MUX .mux = NULL, .mux_ops = NULL
+#define _NO_DIV .div = NULL, .div_ops = NULL
+#define _NO_GATE .gate = NULL, .gate_ops = NULL
+
+#define _GATE_OPS(_offset, _bit_idx, _gate_flags, _gate_ops) \
+ .gate = &(struct gate_cfg) {\
+ .reg_off = _offset,\
+ .bit_idx = _bit_idx,\
+ },\
+ .gate_ops = _gate_ops
+
+#define _GATE(_offset, _bit_idx, _gate_flags)\
+ _GATE_OPS(_offset, _bit_idx, _gate_flags, NULL)
+
+#define _DIV_TABLE_OPS(_offset, _shift, _width, _div_flags, _div_table,\
+ _div_ops)\
+ .div = &(struct div_cfg) {\
+ .reg_off = _offset,\
+ .shift = _shift,\
+ .width = _width,\
+ .div_flags = _div_flags,\
+ .table = _div_table,\
+ },\
+ .div_ops = _div_ops
+
+#define _DIV_TABLE(_offset, _shift, _width, _div_flags, _div_table)\
+ _DIV_TABLE_OPS(_offset, _shift, _width, _div_flags,\
+ _div_table, NULL)
+
+#define _DIV_OPS(_offset, _shift, _width, _div_flags, _div_ops)\
+ _DIV_TABLE_OPS(_offset, _shift, _width, _div_flags, NULL, _div_ops)
+
+#define _DIV(_offset, _shift, _width, _div_flags)\
+ _DIV_OPS(_offset, _shift, _width, _div_flags, NULL)
+
+#define _MUX(_offset, _shift, _width, _mux_flags)\
+ .mux = &(struct mux_cfg) {\
+ .reg_off = _offset,\
+ .shift = _shift,\
+ .width = _width,\
+ .mux_flags = _mux_flags,\
+ .table = NULL,\
+ },\
+ .mux_ops = NULL
+
+#define _GATEDIV(_gate_offset,\
+ _bit_idx,\
+ _div_offset,\
+ _div_shift,\
+ _div_width,\
+ _div_table)\
+{\
+ _DIV_TABLE(_div_offset, _div_shift, _div_width, 0, _div_table),\
+ _GATE(_gate_offset, _bit_idx, 0),\
+ _NO_MUX,\
+}
+
#define MP1_GATE(_id, _name, _parent, _flags, _offset, _bit_idx, _gate_flags)\
{\
.id = _id,\
@@ -834,6 +1056,41 @@ struct clk_hw *_clk_register_pll(struct device *dev,
PLL(PLL2, "pll2", "ref1", CLK_IGNORE_UNUSED, RCC_PLL2CR),
PLL(PLL3, "pll3", "ref3", CLK_IGNORE_UNUSED, RCC_PLL3CR),
PLL(PLL4, "pll4", "ref4", CLK_IGNORE_UNUSED, RCC_PLL4CR),
+
+ /* ODF */
+ COMPOSITE(PLL1_P, "pll1_p", PARENT("pll1"), 0,
+ _GATEDIV(RCC_PLL1CR, 4,
+ RCC_PLL1CFGR2, 0, 7, NULL)),
+
+ COMPOSITE(PLL2_P, "pll2_p", PARENT("pll2"), 0,
+ _GATEDIV(RCC_PLL2CR, 4,
+ RCC_PLL2CFGR2, 0, 7, NULL)),
+ COMPOSITE(PLL2_Q, "pll2_q", PARENT("pll2"), 0,
+ _GATEDIV(RCC_PLL2CR, 5,
+ RCC_PLL2CFGR2, 8, 7, NULL)),
+ COMPOSITE(PLL2_R, "pll2_r", PARENT("pll2"), CLK_IS_CRITICAL,
+ _GATEDIV(RCC_PLL2CR, 6,
+ RCC_PLL2CFGR2, 16, 7, NULL)),
+
+ COMPOSITE(PLL3_P, "pll3_p", PARENT("pll3"), 0,
+ _GATEDIV(RCC_PLL3CR, 4,
+ RCC_PLL3CFGR2, 0, 7, NULL)),
+ COMPOSITE(PLL3_Q, "pll3_q", PARENT("pll3"), 0,
+ _GATEDIV(RCC_PLL3CR, 5,
+ RCC_PLL3CFGR2, 8, 7, NULL)),
+ COMPOSITE(PLL3_R, "pll3_r", PARENT("pll3"), 0,
+ _GATEDIV(RCC_PLL3CR, 6,
+ RCC_PLL3CFGR2, 16, 7, NULL)),
+
+ COMPOSITE(PLL4_P, "pll4_p", PARENT("pll4"), 0,
+ _GATEDIV(RCC_PLL4CR, 4,
+ RCC_PLL4CFGR2, 0, 7, NULL)),
+ COMPOSITE(PLL4_Q, "pll4_q", PARENT("pll4"), 0,
+ _GATEDIV(RCC_PLL4CR, 5,
+ RCC_PLL4CFGR2, 8, 7, NULL)),
+ COMPOSITE(PLL4_R, "pll4_r", PARENT("pll4"), 0,
+ _GATEDIV(RCC_PLL4CR, 6,
+ RCC_PLL4CFGR2, 16, 7, NULL)),
};
struct stm32_clock_match_data {
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 08/14] clk: stm32mp1: add Sub System clocks
[not found] ` <1517580222-23301-1-git-send-email-gabriel.fernandez-qxv4g6HH51o@public.gmane.org>
` (4 preceding siblings ...)
2018-02-02 14:03 ` [PATCH 07/14] clk: stm32mp1: add Post-dividers for PLL gabriel.fernandez-qxv4g6HH51o
@ 2018-02-02 14:03 ` gabriel.fernandez-qxv4g6HH51o
2018-02-02 14:03 ` [PATCH 11/14] clk: stm32mp1: add Kernel clocks gabriel.fernandez-qxv4g6HH51o
2018-02-02 14:03 ` [PATCH 12/14] clk: stm32mp1: add RTC clock gabriel.fernandez-qxv4g6HH51o
7 siblings, 0 replies; 22+ messages in thread
From: gabriel.fernandez-qxv4g6HH51o @ 2018-02-02 14:03 UTC (permalink / raw)
To: Rob Herring, Mark Rutland, Lee Jones, Maxime Coquelin,
Alexandre Torgue, Michael Turquette, Stephen Boyd,
Gabriel Fernandez
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-clk-u79uwXL29TY76Z2rM5mHXA,
gabriel.fernandez.st-Re5JQEeQqe8AvxtiuMwx3w,
olivier.bideau-qxv4g6HH51o
From: Gabriel Fernandez <gabriel.fernandez-qxv4g6HH51o@public.gmane.org>
The RCC handles three sub-system clocks: ck_mpuss, ck_axiss and ck_mcuss.
This patch adds also some MUX system and several prescalers.
Signed-off-by: Gabriel Fernandez <gabriel.fernandez-qxv4g6HH51o@public.gmane.org>
---
drivers/clk/clk-stm32mp1.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 61 insertions(+)
diff --git a/drivers/clk/clk-stm32mp1.c b/drivers/clk/clk-stm32mp1.c
index 15cd488..d85c619 100644
--- a/drivers/clk/clk-stm32mp1.c
+++ b/drivers/clk/clk-stm32mp1.c
@@ -332,6 +332,26 @@
"ck_mpu", "ck_axi", "ck_mcu", "pll4_p", "ck_hse", "ck_hsi"
};
+static const struct clk_div_table axi_div_table[] = {
+ { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 4 },
+ { 4, 4 }, { 5, 4 }, { 6, 4 }, { 7, 4 },
+ { 0 },
+};
+
+static const struct clk_div_table mcu_div_table[] = {
+ { 0, 1 }, { 1, 2 }, { 2, 4 }, { 3, 8 },
+ { 4, 16 }, { 5, 32 }, { 6, 64 }, { 7, 128 },
+ { 8, 512 }, { 9, 512 }, { 10, 512}, { 11, 512 },
+ { 12, 512 }, { 13, 512 }, { 14, 512}, { 15, 512 },
+ { 0 },
+};
+
+static const struct clk_div_table apb_div_table[] = {
+ { 0, 1 }, { 1, 2 }, { 2, 4 }, { 3, 8 },
+ { 4, 16 }, { 5, 16 }, { 6, 16 }, { 7, 16 },
+ { 0 },
+};
+
struct clock_config {
u32 id;
const char *name;
@@ -1001,6 +1021,15 @@ struct clk_hw *_clk_register_pll(struct device *dev,
_NO_MUX,\
}
+#define _MUXDIV(_mux_offset, _mux_bit, _mux_width,\
+ _div_offset, _div_shift, _div_width,\
+ _div_table)\
+{\
+ _DIV_TABLE(_div_offset, _div_shift, _div_width, 0, _div_table),\
+ _NO_GATE,\
+ _MUX(_mux_offset, _mux_bit, _mux_width, 0),\
+}
+
#define MP1_GATE(_id, _name, _parent, _flags, _offset, _bit_idx, _gate_flags)\
{\
.id = _id,\
@@ -1091,6 +1120,38 @@ struct clk_hw *_clk_register_pll(struct device *dev,
COMPOSITE(PLL4_R, "pll4_r", PARENT("pll4"), 0,
_GATEDIV(RCC_PLL4CR, 6,
RCC_PLL4CFGR2, 16, 7, NULL)),
+
+ /* MUX system clocks */
+ MUX(CK_PER, "ck_per", per_src, CLK_OPS_PARENT_ENABLE,
+ RCC_CPERCKSELR, 0, 2, 0),
+
+ MUX(CK_MPU, "ck_mpu", cpu_src, CLK_OPS_PARENT_ENABLE | CLK_IS_CRITICAL,
+ RCC_MPCKSELR, 0, 2, 0),
+
+ COMPOSITE(CK_AXI, "ck_axi", axi_src, CLK_IS_CRITICAL |
+ CLK_OPS_PARENT_ENABLE,
+ _MUXDIV(RCC_ASSCKSELR, 0, 2,
+ RCC_AXIDIVR, 0, 3, axi_div_table)),
+
+ COMPOSITE(CK_MCU, "ck_mcu", mcu_src, CLK_IS_CRITICAL |
+ CLK_OPS_PARENT_ENABLE,
+ _MUXDIV(RCC_MSSCKSELR, 0, 2,
+ RCC_MCUDIVR, 0, 4, mcu_div_table)),
+
+ DIV_TABLE(NO_ID, "pclk1", "ck_mcu", CLK_IGNORE_UNUSED, RCC_APB1DIVR, 0,
+ 3, CLK_DIVIDER_READ_ONLY, apb_div_table),
+
+ DIV_TABLE(NO_ID, "pclk2", "ck_mcu", CLK_IGNORE_UNUSED, RCC_APB2DIVR, 0,
+ 3, CLK_DIVIDER_READ_ONLY, apb_div_table),
+
+ DIV_TABLE(NO_ID, "pclk3", "ck_mcu", CLK_IGNORE_UNUSED, RCC_APB3DIVR, 0,
+ 3, CLK_DIVIDER_READ_ONLY, apb_div_table),
+
+ DIV_TABLE(NO_ID, "pclk4", "ck_axi", CLK_IGNORE_UNUSED, RCC_APB4DIVR, 0,
+ 3, CLK_DIVIDER_READ_ONLY, apb_div_table),
+
+ DIV_TABLE(NO_ID, "pclk5", "ck_axi", CLK_IGNORE_UNUSED, RCC_APB5DIVR, 0,
+ 3, CLK_DIVIDER_READ_ONLY, apb_div_table),
};
struct stm32_clock_match_data {
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 11/14] clk: stm32mp1: add Kernel clocks
[not found] ` <1517580222-23301-1-git-send-email-gabriel.fernandez-qxv4g6HH51o@public.gmane.org>
` (5 preceding siblings ...)
2018-02-02 14:03 ` [PATCH 08/14] clk: stm32mp1: add Sub System clocks gabriel.fernandez-qxv4g6HH51o
@ 2018-02-02 14:03 ` gabriel.fernandez-qxv4g6HH51o
2018-02-02 14:03 ` [PATCH 12/14] clk: stm32mp1: add RTC clock gabriel.fernandez-qxv4g6HH51o
7 siblings, 0 replies; 22+ messages in thread
From: gabriel.fernandez-qxv4g6HH51o @ 2018-02-02 14:03 UTC (permalink / raw)
To: Rob Herring, Mark Rutland, Lee Jones, Maxime Coquelin,
Alexandre Torgue, Michael Turquette, Stephen Boyd,
Gabriel Fernandez
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-clk-u79uwXL29TY76Z2rM5mHXA,
gabriel.fernandez.st-Re5JQEeQqe8AvxtiuMwx3w,
olivier.bideau-qxv4g6HH51o
From: Gabriel Fernandez <gabriel.fernandez-qxv4g6HH51o@public.gmane.org>
Some peripherals need also a dedicated clock for their communication
interface, this clock is generally asynchronous with respect to the bus
interface clock (peripheral clock), and is named kernel clock.
Signed-off-by: Gabriel Fernandez <gabriel.fernandez-qxv4g6HH51o@public.gmane.org>
---
drivers/clk/clk-stm32mp1.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 75 insertions(+)
diff --git a/drivers/clk/clk-stm32mp1.c b/drivers/clk/clk-stm32mp1.c
index ea78a6a..5a1142c 100644
--- a/drivers/clk/clk-stm32mp1.c
+++ b/drivers/clk/clk-stm32mp1.c
@@ -1179,6 +1179,17 @@ static struct clk_hw *_clk_register_cktim(struct device *dev,
_MUX(_mux_offset, _mux_bit, _mux_width, 0),\
}
+#define _MP1_GATE(_gate_offset, _bit_idx, _flags)\
+ _GATE_OPS(_gate_offset, _bit_idx, _flags, &mp1_gate_clk_ops)
+
+#define _MP1_GATEMUX(_gate_offset, _bit_idx,\
+ _mux_offset, _mux_bit, _mux_width)\
+{\
+ _NO_DIV,\
+ _MP1_GATE(_gate_offset, _bit_idx, 0),\
+ _MUX(_mux_offset, _mux_bit, _mux_width, 0),\
+}
+
#define MP1_GATE(_id, _name, _parent, _flags, _offset, _bit_idx, _gate_flags)\
{\
.id = _id,\
@@ -1226,6 +1237,11 @@ static struct clk_hw *_clk_register_cktim(struct device *dev,
MP1_GATE(_id, _name, _parent, _flags,\
RCC_##_reg##ENSETR, _gate_idx, 0)
+#define KCLK(_reg, _id, _bit_idx, _mux_offset, _name, _parents, _flags)\
+ COMPOSITE(_id, _name, _parents, CLK_OPS_PARENT_ENABLE | _flags,\
+ _MP1_GATEMUX(RCC_##_reg##ENSETR, _bit_idx,\
+ _mux_offset, 0, 3))
+
static const struct clock_config stm32mp1_clock_cfg[] = {
/* Oscillator divider */
DIV(NO_ID, "clk-hsi-div", "clk-hsi", 0, RCC_HSICFGR, 0, 2,
@@ -1451,6 +1467,65 @@ static struct clk_hw *_clk_register_cktim(struct device *dev,
PCLK(AHB6, CRC1, "crc1", "ck_axi", 20, 0),
PCLK(AHB6, USBH, "usbh", "ck_axi", 24, 0),
PCLK(AHB6LP, ETHSTP, "ethstp", "ck_axi", 11, 0),
+
+ /* Kernel clocks */
+ KCLK(AHB6, SDMMC1_K, 16, RCC_SDMMC12CKSELR, "sdmmc1_k", sdmmc1_src, 0),
+ KCLK(AHB6, SDMMC2_K, 17, RCC_SDMMC12CKSELR, "sdmmc2_k", sdmmc2_src, 0),
+ KCLK(AHB2, SDMMC3_K, 16, RCC_SDMMC3CKSELR, "sdmmc3_k", sdmmc3_src, 0),
+ KCLK(AHB6, FMC_K, 12, RCC_FMCCKSELR, "fmc_k", fmc_src, 0),
+ KCLK(AHB6, QSPI_K, 14, RCC_QSPICKSELR, "qspi_k", qspi_src, 0),
+ KCLK(AHB6, ETHMAC_K, 10, RCC_ETHCKSELR, "ethmac_k", eth_src, 0),
+ KCLK(AHB5, RNG1_K, 6, RCC_RNG1CKSELR, "rng1_k", rng_src, 0),
+ KCLK(AHB3, RNG2_K, 6, RCC_RNG2CKSELR, "rng2_k", rng_src, 0),
+ KCLK(APB4, USBPHY_K, 16, RCC_USBCKSELR, "usbphy_k", usbphy_src, 0),
+ KCLK(APB5, STGEN_K, 20, RCC_STGENCKSELR, "stgen_k", stgen_src,
+ CLK_IGNORE_UNUSED),
+ KCLK(APB1, SPDIF_K, 26, RCC_SPDIFCKSELR, "spdif_k", spdif_src, 0),
+ KCLK(APB2, SPI1_K, 8, RCC_SPI2S1CKSELR, "spi1_k", spi1_src, 0),
+ KCLK(APB1, SPI2_K, 11, RCC_SPI2S23CKSELR, "spi2_k", spi2_src, 0),
+ KCLK(APB1, SPI3_K, 12, RCC_SPI2S23CKSELR, "spi3_k", spi3_src, 0),
+ KCLK(APB2, SPI4_K, 9, RCC_SPI2S45CKSELR, "spi4_k", spi4_src, 0),
+ KCLK(APB2, SPI5_K, 10, RCC_SPI2S45CKSELR, "spi5_k", spi5_src, 0),
+ KCLK(APB5, SPI6_K, 0, RCC_SPI6CKSELR, "spi6_k", spi6_src, 0),
+ KCLK(APB1, CEC_K, 27, RCC_CECCKSELR, "cec_k", cec_src, 0),
+ KCLK(APB1, I2C1_K, 21, RCC_I2C12CKSELR, "i2c1_k", i2c1_src, 0),
+ KCLK(APB1, I2C2_K, 22, RCC_I2C12CKSELR, "i2c2_k", i2c2_src, 0),
+ KCLK(APB1, I2C3_K, 23, RCC_I2C35CKSELR, "i2c3_k", i2c3_src, 0),
+ KCLK(APB5, I2C4_K, 2, RCC_I2C4CKSELR, "i2c4_k", i2c4_src, 0),
+ KCLK(APB1, I2C5_K, 24, RCC_I2C35CKSELR, "i2c5_k", i2c5_src, 0),
+ KCLK(APB5, I2C6_K, 3, RCC_I2C4CKSELR, "i2c6_k", i2c6_src, 0),
+ KCLK(APB1, LPTIM1_K, 9, RCC_LPTIM1CKSELR, "lptim1_k", lptim1_src, 0),
+ KCLK(APB3, LPTIM2_K, 0, RCC_LPTIM23CKSELR, "lptim2_k", lptim2_src, 0),
+ KCLK(APB3, LPTIM3_K, 1, RCC_LPTIM23CKSELR, "lptim3_k", lptim3_src, 0),
+ KCLK(APB3, LPTIM4_K, 2, RCC_LPTIM45CKSELR, "lptim4_k", lptim4_src, 0),
+ KCLK(APB3, LPTIM5_K, 3, RCC_LPTIM45CKSELR, "lptim5_k", lptim5_src, 0),
+ KCLK(APB5, USART1_K, 4, RCC_UART1CKSELR, "usart1_k", usart1_src, 0),
+ KCLK(APB1, USART2_K, 14, RCC_UART24CKSELR, "usart2_k", usart2_src, 0),
+ KCLK(APB1, USART3_K, 15, RCC_UART35CKSELR, "usart3_k", usart3_src, 0),
+ KCLK(APB1, UART4_K, 16, RCC_UART24CKSELR, "uart4_k", uart4_src, 0),
+ KCLK(APB1, UART5_K, 17, RCC_UART35CKSELR, "uart5_k", uart5_src, 0),
+ KCLK(APB2, USART6_K, 13, RCC_UART6CKSELR, "uart6_k", usart6_src, 0),
+ KCLK(APB1, UART7_K, 18, RCC_UART78CKSELR, "uart7_k", uart7_src, 0),
+ KCLK(APB1, UART8_K, 19, RCC_UART78CKSELR, "uart8_k", uart8_src, 0),
+ KCLK(APB2, DFSDM_K, 20, RCC_DFSDMCKSELR, "dfsdm_k", dfsdm_src, 0),
+ KCLK(APB2, FDCAN_K, 24, RCC_FDCANCKSELR, "fdcan_k", fdcan_src, 0),
+ KCLK(APB2, SAI1_K, 16, RCC_SAI1CKSELR, "sai1_k", sai_src, 0),
+ KCLK(APB2, SAI2_K, 17, RCC_SAI2CKSELR, "sai2_k", sai2_src, 0),
+ KCLK(APB2, SAI3_K, 18, RCC_SAI3CKSELR, "sai3_k", sai_src, 0),
+ KCLK(APB3, SAI4_K, 8, RCC_SAI4CKSELR, "sai4_k", sai_src, 0),
+ KCLK(AHB2, ADC12_K, 5, RCC_ADCCKSELR, "adc12_k", adc12_src,
+ CLK_IGNORE_UNUSED),
+ KCLK(APB4, DSI_K, 4, RCC_DSICKSELR, "dsi_k", dsi_src, 0),
+ KCLK(APB2, ADFSDM_K, 21, RCC_SAI1CKSELR, "adfsdm_k", adfsdm_src, 0),
+
+ /* particulary Kernel clocks */
+ COMPOSITE(USBO_K, "usbo_k", usbo_src, CLK_OPS_PARENT_ENABLE,
+ _MP1_GATEMUX(RCC_AHB2ENSETR, 8, RCC_USBCKSELR, 4, 1)),
+
+ MP1_GATE(LTDC_K, "ltdc_k", "pll4_q", CLK_SET_RATE_PARENT,
+ RCC_APB4ENSETR, 0, 0),
+
+ MP1_GATE(GPU_K, "gpu_k", "pll2_q", 0, RCC_AHB6ENSETR, 5, 0),
};
struct stm32_clock_match_data {
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 12/14] clk: stm32mp1: add RTC clock
[not found] ` <1517580222-23301-1-git-send-email-gabriel.fernandez-qxv4g6HH51o@public.gmane.org>
` (6 preceding siblings ...)
2018-02-02 14:03 ` [PATCH 11/14] clk: stm32mp1: add Kernel clocks gabriel.fernandez-qxv4g6HH51o
@ 2018-02-02 14:03 ` gabriel.fernandez-qxv4g6HH51o
7 siblings, 0 replies; 22+ messages in thread
From: gabriel.fernandez-qxv4g6HH51o @ 2018-02-02 14:03 UTC (permalink / raw)
To: Rob Herring, Mark Rutland, Lee Jones, Maxime Coquelin,
Alexandre Torgue, Michael Turquette, Stephen Boyd,
Gabriel Fernandez
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-clk-u79uwXL29TY76Z2rM5mHXA,
gabriel.fernandez.st-Re5JQEeQqe8AvxtiuMwx3w,
olivier.bideau-qxv4g6HH51o
From: Gabriel Fernandez <gabriel.fernandez-qxv4g6HH51o@public.gmane.org>
This patch adds the RTC clock.
Signed-off-by: Gabriel Fernandez <gabriel.fernandez-qxv4g6HH51o@public.gmane.org>
---
drivers/clk/clk-stm32mp1.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/drivers/clk/clk-stm32mp1.c b/drivers/clk/clk-stm32mp1.c
index 5a1142c..1cb06b0 100644
--- a/drivers/clk/clk-stm32mp1.c
+++ b/drivers/clk/clk-stm32mp1.c
@@ -1179,6 +1179,15 @@ static struct clk_hw *_clk_register_cktim(struct device *dev,
_MUX(_mux_offset, _mux_bit, _mux_width, 0),\
}
+#define _GATEMUX(_gate_offset,\
+ _bit_idx,\
+ _mux_offset, _mux_bit, _mux_width)\
+{\
+ _NO_DIV,\
+ _GATE(_gate_offset, _bit_idx, 0),\
+ _MUX(_mux_offset, _mux_bit, _mux_width, 0),\
+}
+
#define _MP1_GATE(_gate_offset, _bit_idx, _flags)\
_GATE_OPS(_gate_offset, _bit_idx, _flags, &mp1_gate_clk_ops)
@@ -1526,6 +1535,14 @@ static struct clk_hw *_clk_register_cktim(struct device *dev,
RCC_APB4ENSETR, 0, 0),
MP1_GATE(GPU_K, "gpu_k", "pll2_q", 0, RCC_AHB6ENSETR, 5, 0),
+
+ /* RTC clock */
+ DIV(NO_ID, "ck_hse_rtc", "ck_hse", 0, RCC_RTCDIVR, 0, 7,
+ CLK_DIVIDER_ALLOW_ZERO),
+
+ COMPOSITE(RTC, "ck_rtc", rtc_src, CLK_OPS_PARENT_ENABLE |
+ CLK_SET_RATE_PARENT,
+ _GATEMUX(RCC_BDCR, 20, RCC_BDCR, 16, 2)),
};
struct stm32_clock_match_data {
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 22+ messages in thread