mbox series

[0/6] clk: samsung: Introduce Exynos850 SoC clock driver

Message ID 20210914155607.14122-1-semen.protsenko@linaro.org
Headers show
Series clk: samsung: Introduce Exynos850 SoC clock driver | expand

Message

Sam Protsenko Sept. 14, 2021, 3:56 p.m. UTC
This patch series provides the implementation for Exynos850 clock
driver, its documentation and corresponding changes for Samsung clock
infrastructure:
  - Adds new PLL types used in Exynos850 SoC, following TRM
  - Enables bus clock for each registered CMU, if it's provided

I tried to follow already established design for Samsung clock drivers
(getting most insights from Exynos7 and Exynos5433 clock drivers), and
integrate the driver in existing infrastructure. The whole driver was
implemented from scratch, using mostly TRM.

For now only basic clocks are implemented, including next blocks:
  - CMU_TOP
  - CMU_PERI
  - CMU_CORE
  - CMU_HSI

Some CMUs are still not implemented, but that can be added in future,
when the need arises. The driver also lacks CLKOUT support, PM ops and
automatic clocks control (using Q-Channel protocol). All that can be
added independently later.

Implemented clock tree was tested via UART and MMC drivers, and using
DebugFS clk support (e.g. using 'clk_summary' file). In order to keep
all clocks running I added 'clk_ignore_unused' kernel param in my local
tree, and defined CLOCK_ALLOW_WRITE_DEBUGFS in clk.c for actually
testing clocks via DebugFS.

Sam Protsenko (6):
  clk: samsung: Enable bus clock on init
  clk: samsung: clk-pll: Implement pll0822x PLL type
  clk: samsung: clk-pll: Implement pll0831x PLL type
  dt-bindings: clock: Add bindings definitions for Exynos850 CMU
  dt-bindings: clock: Document Exynos850 CMU bindings
  clk: samsung: Introduce Exynos850 clock driver

 .../clock/samsung,exynos850-clock.yaml        | 190 +++++
 drivers/clk/samsung/Makefile                  |   1 +
 drivers/clk/samsung/clk-exynos850.c           | 700 ++++++++++++++++++
 drivers/clk/samsung/clk-pll.c                 | 196 +++++
 drivers/clk/samsung/clk-pll.h                 |   2 +
 drivers/clk/samsung/clk.c                     |  13 +
 include/dt-bindings/clock/exynos850.h         |  72 ++
 7 files changed, 1174 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/samsung,exynos850-clock.yaml
 create mode 100644 drivers/clk/samsung/clk-exynos850.c
 create mode 100644 include/dt-bindings/clock/exynos850.h

Comments

Rob Herring (Arm) Sept. 14, 2021, 9:35 p.m. UTC | #1
On Tue, 14 Sep 2021 18:56:06 +0300, Sam Protsenko wrote:
> Provide dt-schema documentation for Exynos850 SoC clock controller.
> 
> Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
> ---
>  .../clock/samsung,exynos850-clock.yaml        | 190 ++++++++++++++++++
>  1 file changed, 190 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/samsung,exynos850-clock.yaml
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
Documentation/devicetree/bindings/clock/samsung,exynos850-clock.example.dt.yaml:0:0: /example-2/serial@13820000: failed to match any schema with compatible: ['samsung,exynos850-uart']

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/patch/1528063

This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit.
Krzysztof Kozlowski Sept. 15, 2021, 8:26 a.m. UTC | #2
On 14/09/2021 17:56, Sam Protsenko wrote:
> pll0831x PLL is used in Exynos850 SoC for top-level fractional PLLs. The

> code was derived from very similar pll36xx type, with next differences:

> 

> 1. Lock time for pll0831x is 500*P_DIV, when for pll36xx it's 3000*P_DIV

> 2. It's not suggested in Exynos850 TRM that S_DIV change doesn't require

>    performing PLL lock procedure (which is done in pll36xx

>    implementation)

> 3. The offset from PMS-values register to K-value register is 0x8 for

>    pll0831x, when for pll36xx it's 0x4

> 

> When defining pll0831x type, CON3 register offset should be provided as

> a "con" parameter of PLL() macro, like this:

> 

>     PLL(pll_0831x, 0, "fout_mmc_pll", "oscclk",

>         PLL_LOCKTIME_PLL_MMC, PLL_CON3_PLL_MMC, pll0831x_26mhz_tbl),

> 

> To define PLL rates table, one can use PLL_36XX_RATE() macro, e.g.:

> 

>     PLL_36XX_RATE(26 * MHZ, 799999877, 31, 1, 0, -15124)

> 

> as it's completely appropriate for pl0831x type and there is no sense in

> duplicating that.

> 

> If bit #1 (MANUAL_PLL_CTRL) is not set in CON1 register, it won't be

> possible to set new rate, with next error showing in kernel log:

> 

>     Could not lock PLL fout_mmc_pll

> 

> That can happen for example if bootloader clears that bit beforehand.

> PLL driver doesn't account for that, so if MANUAL_PLL_CTRL bit was

> cleared, it's assumed it was done for a reason and it shouldn't be

> possible to change that PLL's rate at all.

> 

> Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>

> ---

>  drivers/clk/samsung/clk-pll.c | 105 ++++++++++++++++++++++++++++++++++

>  drivers/clk/samsung/clk-pll.h |   1 +

>  2 files changed, 106 insertions(+)

> 



Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>



Best regards,
Krzysztof
Krzysztof Kozlowski Sept. 15, 2021, 8:28 a.m. UTC | #3
On 14/09/2021 17:56, Sam Protsenko wrote:
> Provide dt-schema documentation for Exynos850 SoC clock controller.

> 

> Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>

> ---

>  .../clock/samsung,exynos850-clock.yaml        | 190 ++++++++++++++++++

>  1 file changed, 190 insertions(+)

>  create mode 100644 Documentation/devicetree/bindings/clock/samsung,exynos850-clock.yaml

> 

> diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos850-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos850-clock.yaml

> new file mode 100644

> index 000000000000..b69ba4125421

> --- /dev/null

> +++ b/Documentation/devicetree/bindings/clock/samsung,exynos850-clock.yaml

> @@ -0,0 +1,190 @@

> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)

> +%YAML 1.2

> +---

> +$id: http://devicetree.org/schemas/clock/samsung,exynos850-clock.yaml#

> +$schema: http://devicetree.org/meta-schemas/core.yaml#

> +

> +title: Samsung Exynos850 SoC clock controller

> +

> +maintainers:

> +  - Sam Protsenko <semen.protsenko@linaro.org>

> +  - Chanwoo Choi <cw00.choi@samsung.com>

> +  - Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>

> +  - Sylwester Nawrocki <s.nawrocki@samsung.com>

> +  - Tomasz Figa <tomasz.figa@gmail.com>

> +

> +description: |

> +  Exynos850 clock controller is comprised of several CMU units, generating

> +  clocks for different domains. Those CMU units are modeled as separate device

> +  tree nodes, and might depend on each other. Root clocks in that clock tree are

> +  two external clocks:: OSCCLK (26 MHz) and RTCCLK (32768 Hz). Those external

> +  clocks must be defined as fixed-rate clocks in dts.

> +

> +  CMU_TOP is a top-level CMU, where all base clocks are prepared using PLLs and

> +  dividers; all other leaf clocks (other CMUs) are usually derived from CMU_TOP.

> +

> +  Each clock is assigned an identifier and client nodes can use this identifier

> +  to specify the clock which they consume. All clocks that available for usage

> +  in clock consumer nodes are defined as preprocessor macros in

> +  'dt-bindings/clock/exynos850.h' header.

> +

> +properties:

> +  compatible:

> +    enum:

> +      - samsung,exynos850-cmu-top

> +      - samsung,exynos850-cmu-core

> +      - samsung,exynos850-cmu-hsi

> +      - samsung,exynos850-cmu-peri

> +

> +  clocks:

> +    minItems: 1

> +    maxItems: 5

> +

> +  clock-names:

> +    minItems: 1

> +    maxItems: 5

> +

> +  "#clock-cells":

> +    const: 1

> +

> +  reg:

> +    maxItems: 1

> +

> +allOf:

> +  - if:

> +      properties:

> +        compatible:

> +          contains:

> +            const: samsung,exynos850-cmu-top

> +

> +    then:

> +      properties:

> +        clocks:

> +          items:

> +            - description: External reference clock (26 MHz)

> +

> +        clock-names:

> +          items:

> +            - const: oscclk

> +

> +  - if:

> +      properties:

> +        compatible:

> +          contains:

> +            const: samsung,exynos850-cmu-core

> +

> +    then:

> +      properties:

> +        clocks:

> +          items:

> +            - description: External reference clock (26 MHz)

> +            - description: CMU_CORE bus clock (from CMU_TOP)

> +            - description: CCI clock (from CMU_TOP)

> +            - description: eMMC clock (from CMU_TOP)

> +            - description: SSS clock (from CMU_TOP)

> +

> +        clock-names:

> +          items:

> +            - const: oscclk

> +            - const: dout_core_bus

> +            - const: dout_core_cci

> +            - const: dout_core_mmc_embd

> +            - const: dout_core_sss

> +

> +  - if:

> +      properties:

> +        compatible:

> +          contains:

> +            const: samsung,exynos850-cmu-hsi

> +

> +    then:

> +      properties:

> +        clocks:

> +          items:

> +            - description: External reference clock (26 MHz)

> +            - description: External RTC clock (32768 Hz)

> +            - description: CMU_HSI bus clock (from CMU_TOP)

> +            - description: SD card clock (from CMU_TOP)

> +            - description: "USB 2.0 DRD clock (from CMU_TOP)"

> +

> +        clock-names:

> +          items:

> +            - const: oscclk

> +            - const: rtcclk

> +            - const: dout_hsi_bus

> +            - const: dout_hsi_mmc_card

> +            - const: dout_hsi_usb20drd

> +

> +  - if:

> +      properties:

> +        compatible:

> +          contains:

> +            const: samsung,exynos850-cmu-peri

> +

> +    then:

> +      properties:

> +        clocks:

> +          items:

> +            - description: External reference clock (26 MHz)

> +            - description: CMU_PERI bus clock (from CMU_TOP)

> +            - description: UART clock (from CMU_TOP)

> +            - description: Parent clock for HSI2C and SPI (from CMU_TOP)

> +

> +        clock-names:

> +          items:

> +            - const: oscclk

> +            - const: dout_peri_bus

> +            - const: dout_peri_uart

> +            - const: dout_peri_ip

> +

> +required:

> +  - compatible

> +  - "#clock-cells"

> +  - clocks

> +  - clock-names

> +  - reg

> +

> +additionalProperties: false

> +

> +examples:

> +  # Clock controller node for CMU_PERI

> +  - |

> +    #include <dt-bindings/clock/exynos850.h>

> +

> +    cmu_peri: clock-controller@10030000 {

> +        compatible = "samsung,exynos850-cmu-peri";

> +        reg = <0x10030000 0x8000>;

> +        #clock-cells = <1>;

> +

> +        clocks = <&oscclk>, <&cmu_top DOUT_PERI_BUS>,

> +                 <&cmu_top DOUT_PERI_UART>,

> +                 <&cmu_top DOUT_PERI_IP>;

> +        clock-names = "oscclk", "dout_peri_bus",

> +                      "dout_peri_uart", "dout_peri_ip";

> +    };

> +

> +  # External reference clock (should be provided in particular board DTS)

> +  - |

> +    oscclk: clock-oscclk {

> +        compatible = "fixed-clock";

> +        #clock-cells = <0>;

> +        clock-output-names = "oscclk";

> +        clock-frequency = <26000000>;

> +    };


Skip ossclk - it's trivial and not related to these bindings.

> +

> +  # UART controller node that consumes the clock generated by CMU_PERI

> +  - |

> +    #include <dt-bindings/clock/exynos850.h>

> +    #include <dt-bindings/interrupt-controller/arm-gic.h>

> +

> +    serial_0: serial@13820000 {

> +        compatible = "samsung,exynos850-uart";

> +        reg = <0x13820000 0x100>;

> +        interrupts = <GIC_SPI 227 IRQ_TYPE_LEVEL_HIGH>;

> +        pinctrl-names = "default";

> +        pinctrl-0 = <&uart0_pins>;

> +        clocks = <&cmu_peri GOUT_UART_PCLK>, <&cmu_peri GOUT_UART_IPCLK>;

> +        clock-names = "uart", "clk_uart_baud0";


The same, skip it because it is trivial and common with all clock providers.

Also Rob's robot checker complains about it.

Best regards,
Krzysztof
Chanwoo Choi Sept. 15, 2021, 4:11 p.m. UTC | #4
On 21. 9. 15. 오전 12:56, Sam Protsenko wrote:
> pll0831x PLL is used in Exynos850 SoC for top-level fractional PLLs. The
> code was derived from very similar pll36xx type, with next differences:
> 
> 1. Lock time for pll0831x is 500*P_DIV, when for pll36xx it's 3000*P_DIV
> 2. It's not suggested in Exynos850 TRM that S_DIV change doesn't require
>     performing PLL lock procedure (which is done in pll36xx
>     implementation)
> 3. The offset from PMS-values register to K-value register is 0x8 for
>     pll0831x, when for pll36xx it's 0x4
> 
> When defining pll0831x type, CON3 register offset should be provided as
> a "con" parameter of PLL() macro, like this:
> 
>      PLL(pll_0831x, 0, "fout_mmc_pll", "oscclk",
>          PLL_LOCKTIME_PLL_MMC, PLL_CON3_PLL_MMC, pll0831x_26mhz_tbl),
> 
> To define PLL rates table, one can use PLL_36XX_RATE() macro, e.g.:
> 
>      PLL_36XX_RATE(26 * MHZ, 799999877, 31, 1, 0, -15124)
> 
> as it's completely appropriate for pl0831x type and there is no sense in
> duplicating that.
> 
> If bit #1 (MANUAL_PLL_CTRL) is not set in CON1 register, it won't be
> possible to set new rate, with next error showing in kernel log:
> 
>      Could not lock PLL fout_mmc_pll
> 
> That can happen for example if bootloader clears that bit beforehand.
> PLL driver doesn't account for that, so if MANUAL_PLL_CTRL bit was
> cleared, it's assumed it was done for a reason and it shouldn't be
> possible to change that PLL's rate at all.
> 
> Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
> ---
>   drivers/clk/samsung/clk-pll.c | 105 ++++++++++++++++++++++++++++++++++
>   drivers/clk/samsung/clk-pll.h |   1 +
>   2 files changed, 106 insertions(+)
> 
> diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
> index 03131b149c0b..83d1b03647db 100644
> --- a/drivers/clk/samsung/clk-pll.c
> +++ b/drivers/clk/samsung/clk-pll.c
> @@ -498,6 +498,103 @@ static const struct clk_ops samsung_pll0822x_clk_min_ops = {
>   	.recalc_rate = samsung_pll0822x_recalc_rate,
>   };
>   
> +/*
> + * PLL0831x Clock Type
> + */
> +/* Maximum lock time can be 500 * PDIV cycles */
> +#define PLL0831X_LOCK_FACTOR		(500)
> +
> +#define PLL0831X_KDIV_MASK		(0xFFFF)
> +#define PLL0831X_MDIV_MASK		(0x1FF)
> +#define PLL0831X_PDIV_MASK		(0x3F)
> +#define PLL0831X_SDIV_MASK		(0x7)
> +#define PLL0831X_MDIV_SHIFT		(16)
> +#define PLL0831X_PDIV_SHIFT		(8)
> +#define PLL0831X_SDIV_SHIFT		(0)
> +#define PLL0831X_KDIV_SHIFT		(0)
> +#define PLL0831X_LOCK_STAT_SHIFT	(29)
> +#define PLL0831X_ENABLE_SHIFT		(31)
> +
> +static unsigned long samsung_pll0831x_recalc_rate(struct clk_hw *hw,
> +						  unsigned long parent_rate)
> +{
> +	struct samsung_clk_pll *pll = to_clk_pll(hw);
> +	u32 mdiv, pdiv, sdiv, pll_con3, pll_con5;
> +	s16 kdiv;
> +	u64 fvco = parent_rate;
> +
> +	pll_con3 = readl_relaxed(pll->con_reg);
> +	pll_con5 = readl_relaxed(pll->con_reg + 8);
> +	mdiv = (pll_con3 >> PLL0831X_MDIV_SHIFT) & PLL0831X_MDIV_MASK;
> +	pdiv = (pll_con3 >> PLL0831X_PDIV_SHIFT) & PLL0831X_PDIV_MASK;
> +	sdiv = (pll_con3 >> PLL0831X_SDIV_SHIFT) & PLL0831X_SDIV_MASK;
> +	kdiv = (s16)((pll_con5 >> PLL0831X_KDIV_SHIFT) & PLL0831X_KDIV_MASK);
> +
> +	fvco *= (mdiv << 16) + kdiv;
> +	do_div(fvco, (pdiv << sdiv));
> +	fvco >>= 16;
> +
> +	return (unsigned long)fvco;
> +}
> +
> +static int samsung_pll0831x_set_rate(struct clk_hw *hw, unsigned long drate,
> +				     unsigned long parent_rate)
> +{
> +	const struct samsung_pll_rate_table *rate;
> +	struct samsung_clk_pll *pll = to_clk_pll(hw);
> +	u32 pll_con3, pll_con5;
> +
> +	/* Get required rate settings from table */
> +	rate = samsung_get_pll_settings(pll, drate);
> +	if (!rate) {
> +		pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
> +			drate, clk_hw_get_name(hw));
> +		return -EINVAL;
> +	}
> +
> +	pll_con3 = readl_relaxed(pll->con_reg);
> +	pll_con5 = readl_relaxed(pll->con_reg + 8);
> +
> +	/* Change PLL PMSK values */
> +	pll_con3 &= ~((PLL0831X_MDIV_MASK << PLL0831X_MDIV_SHIFT) |
> +			(PLL0831X_PDIV_MASK << PLL0831X_PDIV_SHIFT) |
> +			(PLL0831X_SDIV_MASK << PLL0831X_SDIV_SHIFT));
> +	pll_con3 |= (rate->mdiv << PLL0831X_MDIV_SHIFT) |
> +			(rate->pdiv << PLL0831X_PDIV_SHIFT) |
> +			(rate->sdiv << PLL0831X_SDIV_SHIFT);
> +	pll_con5 &= ~(PLL0831X_KDIV_MASK << PLL0831X_KDIV_SHIFT);
> +	/*
> +	 * kdiv is 16-bit 2's complement (s16), but stored as unsigned int.
> +	 * Cast it to u16 to avoid leading 0xffff's in case of negative value.
> +	 */
> +	pll_con5 |= ((u16)rate->kdiv << PLL0831X_KDIV_SHIFT);
> +
> +	/* Set PLL lock time */
> +	writel_relaxed(rate->pdiv * PLL0831X_LOCK_FACTOR, pll->lock_reg);
> +
> +	/* Write PMSK values */
> +	writel_relaxed(pll_con3, pll->con_reg);
> +	writel_relaxed(pll_con5, pll->con_reg + 8);
> +
> +	/* Wait for PLL lock if the PLL is enabled */
> +	if (pll_con3 & BIT(pll->enable_offs))
> +		return samsung_pll_lock_wait(pll, BIT(pll->lock_offs));
> +
> +	return 0;
> +}
> +
> +static const struct clk_ops samsung_pll0831x_clk_ops = {
> +	.recalc_rate = samsung_pll0831x_recalc_rate,
> +	.set_rate = samsung_pll0831x_set_rate,
> +	.round_rate = samsung_pll_round_rate,
> +	.enable = samsung_pll3xxx_enable,
> +	.disable = samsung_pll3xxx_disable,
> +};
> +
> +static const struct clk_ops samsung_pll0831x_clk_min_ops = {
> +	.recalc_rate = samsung_pll0831x_recalc_rate,
> +};
> +
>   /*
>    * PLL45xx Clock Type
>    */
> @@ -1407,6 +1504,14 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
>   		else
>   			init.ops = &samsung_pll36xx_clk_ops;
>   		break;
> +	case pll_0831x:
> +		pll->enable_offs = PLL0831X_ENABLE_SHIFT;
> +		pll->lock_offs = PLL0831X_LOCK_STAT_SHIFT;
> +		if (!pll->rate_table)
> +			init.ops = &samsung_pll0831x_clk_min_ops;
> +		else
> +			init.ops = &samsung_pll0831x_clk_ops;
> +		break;
>   	case pll_6552:
>   	case pll_6552_s3c2416:
>   		init.ops = &samsung_pll6552_clk_ops;
> diff --git a/drivers/clk/samsung/clk-pll.h b/drivers/clk/samsung/clk-pll.h
> index 213e94a97f23..a739f2b7ae80 100644
> --- a/drivers/clk/samsung/clk-pll.h
> +++ b/drivers/clk/samsung/clk-pll.h
> @@ -37,6 +37,7 @@ enum samsung_pll_type {
>   	pll_1452x,
>   	pll_1460x,
>   	pll_0822x,
> +	pll_0831x,
>   };
>   
>   #define PLL_RATE(_fin, _m, _p, _s, _k, _ks) \
> 

Acked-by: Chanwoo Choi <cw00.choi@samsung.com>
Chanwoo Choi Sept. 15, 2021, 4:47 p.m. UTC | #5
On 21. 9. 15. 오전 12:56, Sam Protsenko wrote:
> Provide dt-schema documentation for Exynos850 SoC clock controller.

> 

> Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>

> ---

>   .../clock/samsung,exynos850-clock.yaml        | 190 ++++++++++++++++++

>   1 file changed, 190 insertions(+)

>   create mode 100644 Documentation/devicetree/bindings/clock/samsung,exynos850-clock.yaml

> 

> diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos850-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos850-clock.yaml

> new file mode 100644

> index 000000000000..b69ba4125421

> --- /dev/null

> +++ b/Documentation/devicetree/bindings/clock/samsung,exynos850-clock.yaml

> @@ -0,0 +1,190 @@

> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)

> +%YAML 1.2

> +---

> +$id: http://devicetree.org/schemas/clock/samsung,exynos850-clock.yaml#

> +$schema: http://devicetree.org/meta-schemas/core.yaml#

> +

> +title: Samsung Exynos850 SoC clock controller

> +

> +maintainers:

> +  - Sam Protsenko <semen.protsenko@linaro.org>

> +  - Chanwoo Choi <cw00.choi@samsung.com>

> +  - Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>

> +  - Sylwester Nawrocki <s.nawrocki@samsung.com>

> +  - Tomasz Figa <tomasz.figa@gmail.com>

> +

> +description: |

> +  Exynos850 clock controller is comprised of several CMU units, generating

> +  clocks for different domains. Those CMU units are modeled as separate device

> +  tree nodes, and might depend on each other. Root clocks in that clock tree are

> +  two external clocks:: OSCCLK (26 MHz) and RTCCLK (32768 Hz). Those external

> +  clocks must be defined as fixed-rate clocks in dts.

> +

> +  CMU_TOP is a top-level CMU, where all base clocks are prepared using PLLs and

> +  dividers; all other leaf clocks (other CMUs) are usually derived from CMU_TOP.

> +

> +  Each clock is assigned an identifier and client nodes can use this identifier

> +  to specify the clock which they consume. All clocks that available for usage

> +  in clock consumer nodes are defined as preprocessor macros in

> +  'dt-bindings/clock/exynos850.h' header.

> +

> +properties:

> +  compatible:

> +    enum:

> +      - samsung,exynos850-cmu-top

> +      - samsung,exynos850-cmu-core

> +      - samsung,exynos850-cmu-hsi

> +      - samsung,exynos850-cmu-peri

> +

> +  clocks:

> +    minItems: 1

> +    maxItems: 5

> +

> +  clock-names:

> +    minItems: 1

> +    maxItems: 5

> +

> +  "#clock-cells":

> +    const: 1

> +

> +  reg:

> +    maxItems: 1

> +

> +allOf:

> +  - if:

> +      properties:

> +        compatible:

> +          contains:

> +            const: samsung,exynos850-cmu-top

> +

> +    then:

> +      properties:

> +        clocks:

> +          items:

> +            - description: External reference clock (26 MHz)

> +

> +        clock-names:

> +          items:

> +            - const: oscclk

> +

> +  - if:

> +      properties:

> +        compatible:

> +          contains:

> +            const: samsung,exynos850-cmu-core

> +

> +    then:

> +      properties:

> +        clocks:

> +          items:

> +            - description: External reference clock (26 MHz)

> +            - description: CMU_CORE bus clock (from CMU_TOP)

> +            - description: CCI clock (from CMU_TOP)

> +            - description: eMMC clock (from CMU_TOP)

> +            - description: SSS clock (from CMU_TOP)

> +

> +        clock-names:

> +          items:

> +            - const: oscclk

> +            - const: dout_core_bus

> +            - const: dout_core_cci

> +            - const: dout_core_mmc_embd

> +            - const: dout_core_sss

> +

> +  - if:

> +      properties:

> +        compatible:

> +          contains:

> +            const: samsung,exynos850-cmu-hsi

> +

> +    then:

> +      properties:

> +        clocks:

> +          items:

> +            - description: External reference clock (26 MHz)

> +            - description: External RTC clock (32768 Hz)

> +            - description: CMU_HSI bus clock (from CMU_TOP)

> +            - description: SD card clock (from CMU_TOP)

> +            - description: "USB 2.0 DRD clock (from CMU_TOP)"

> +

> +        clock-names:

> +          items:

> +            - const: oscclk

> +            - const: rtcclk

> +            - const: dout_hsi_bus

> +            - const: dout_hsi_mmc_card

> +            - const: dout_hsi_usb20drd

> +

> +  - if:

> +      properties:

> +        compatible:

> +          contains:

> +            const: samsung,exynos850-cmu-peri

> +

> +    then:

> +      properties:

> +        clocks:

> +          items:

> +            - description: External reference clock (26 MHz)

> +            - description: CMU_PERI bus clock (from CMU_TOP)

> +            - description: UART clock (from CMU_TOP)

> +            - description: Parent clock for HSI2C and SPI (from CMU_TOP)

> +

> +        clock-names:

> +          items:

> +            - const: oscclk

> +            - const: dout_peri_bus

> +            - const: dout_peri_uart

> +            - const: dout_peri_ip

> +

> +required:

> +  - compatible

> +  - "#clock-cells"

> +  - clocks

> +  - clock-names

> +  - reg

> +

> +additionalProperties: false

> +

> +examples:

> +  # Clock controller node for CMU_PERI

> +  - |

> +    #include <dt-bindings/clock/exynos850.h>

> +

> +    cmu_peri: clock-controller@10030000 {

> +        compatible = "samsung,exynos850-cmu-peri";

> +        reg = <0x10030000 0x8000>;

> +        #clock-cells = <1>;

> +

> +        clocks = <&oscclk>, <&cmu_top DOUT_PERI_BUS>,

> +                 <&cmu_top DOUT_PERI_UART>,

> +                 <&cmu_top DOUT_PERI_IP>;

> +        clock-names = "oscclk", "dout_peri_bus",

> +                      "dout_peri_uart", "dout_peri_ip";

> +    };

> +

> +  # External reference clock (should be provided in particular board DTS)

> +  - |

> +    oscclk: clock-oscclk {

> +        compatible = "fixed-clock";

> +        #clock-cells = <0>;

> +        clock-output-names = "oscclk";

> +        clock-frequency = <26000000>;

> +    };

> +

> +  # UART controller node that consumes the clock generated by CMU_PERI

> +  - |

> +    #include <dt-bindings/clock/exynos850.h>

> +    #include <dt-bindings/interrupt-controller/arm-gic.h>

> +

> +    serial_0: serial@13820000 {

> +        compatible = "samsung,exynos850-uart";

> +        reg = <0x13820000 0x100>;

> +        interrupts = <GIC_SPI 227 IRQ_TYPE_LEVEL_HIGH>;

> +        pinctrl-names = "default";

> +        pinctrl-0 = <&uart0_pins>;

> +        clocks = <&cmu_peri GOUT_UART_PCLK>, <&cmu_peri GOUT_UART_IPCLK>;

> +        clock-names = "uart", "clk_uart_baud0";

> +    };

> +

> +...

> 


Looks good for very detailed description and example. Thanks.

Acked-by: Chanwoo Choi <cw00.choi@samsung.com>


-- 
Best Regards,
Samsung Electronics
Chanwoo Choi
Sam Protsenko Oct. 5, 2021, 11:48 a.m. UTC | #6
On Wed, 15 Sept 2021 at 11:28, Krzysztof Kozlowski
<krzysztof.kozlowski@canonical.com> wrote:
>

> On 14/09/2021 17:56, Sam Protsenko wrote:

> > Provide dt-schema documentation for Exynos850 SoC clock controller.

> >

> > Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>

> > ---

> >  .../clock/samsung,exynos850-clock.yaml        | 190 ++++++++++++++++++

> >  1 file changed, 190 insertions(+)

> >  create mode 100644 Documentation/devicetree/bindings/clock/samsung,exynos850-clock.yaml

> >

> > diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos850-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos850-clock.yaml

> > new file mode 100644

> > index 000000000000..b69ba4125421

> > --- /dev/null

> > +++ b/Documentation/devicetree/bindings/clock/samsung,exynos850-clock.yaml

> > @@ -0,0 +1,190 @@

> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)

> > +%YAML 1.2

> > +---

> > +$id: http://devicetree.org/schemas/clock/samsung,exynos850-clock.yaml#

> > +$schema: http://devicetree.org/meta-schemas/core.yaml#

> > +

> > +title: Samsung Exynos850 SoC clock controller

> > +

> > +maintainers:

> > +  - Sam Protsenko <semen.protsenko@linaro.org>

> > +  - Chanwoo Choi <cw00.choi@samsung.com>

> > +  - Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>

> > +  - Sylwester Nawrocki <s.nawrocki@samsung.com>

> > +  - Tomasz Figa <tomasz.figa@gmail.com>

> > +

> > +description: |

> > +  Exynos850 clock controller is comprised of several CMU units, generating

> > +  clocks for different domains. Those CMU units are modeled as separate device

> > +  tree nodes, and might depend on each other. Root clocks in that clock tree are

> > +  two external clocks:: OSCCLK (26 MHz) and RTCCLK (32768 Hz). Those external

> > +  clocks must be defined as fixed-rate clocks in dts.

> > +

> > +  CMU_TOP is a top-level CMU, where all base clocks are prepared using PLLs and

> > +  dividers; all other leaf clocks (other CMUs) are usually derived from CMU_TOP.

> > +

> > +  Each clock is assigned an identifier and client nodes can use this identifier

> > +  to specify the clock which they consume. All clocks that available for usage

> > +  in clock consumer nodes are defined as preprocessor macros in

> > +  'dt-bindings/clock/exynos850.h' header.

> > +

> > +properties:

> > +  compatible:

> > +    enum:

> > +      - samsung,exynos850-cmu-top

> > +      - samsung,exynos850-cmu-core

> > +      - samsung,exynos850-cmu-hsi

> > +      - samsung,exynos850-cmu-peri

> > +

> > +  clocks:

> > +    minItems: 1

> > +    maxItems: 5

> > +

> > +  clock-names:

> > +    minItems: 1

> > +    maxItems: 5

> > +

> > +  "#clock-cells":

> > +    const: 1

> > +

> > +  reg:

> > +    maxItems: 1

> > +

> > +allOf:

> > +  - if:

> > +      properties:

> > +        compatible:

> > +          contains:

> > +            const: samsung,exynos850-cmu-top

> > +

> > +    then:

> > +      properties:

> > +        clocks:

> > +          items:

> > +            - description: External reference clock (26 MHz)

> > +

> > +        clock-names:

> > +          items:

> > +            - const: oscclk

> > +

> > +  - if:

> > +      properties:

> > +        compatible:

> > +          contains:

> > +            const: samsung,exynos850-cmu-core

> > +

> > +    then:

> > +      properties:

> > +        clocks:

> > +          items:

> > +            - description: External reference clock (26 MHz)

> > +            - description: CMU_CORE bus clock (from CMU_TOP)

> > +            - description: CCI clock (from CMU_TOP)

> > +            - description: eMMC clock (from CMU_TOP)

> > +            - description: SSS clock (from CMU_TOP)

> > +

> > +        clock-names:

> > +          items:

> > +            - const: oscclk

> > +            - const: dout_core_bus

> > +            - const: dout_core_cci

> > +            - const: dout_core_mmc_embd

> > +            - const: dout_core_sss

> > +

> > +  - if:

> > +      properties:

> > +        compatible:

> > +          contains:

> > +            const: samsung,exynos850-cmu-hsi

> > +

> > +    then:

> > +      properties:

> > +        clocks:

> > +          items:

> > +            - description: External reference clock (26 MHz)

> > +            - description: External RTC clock (32768 Hz)

> > +            - description: CMU_HSI bus clock (from CMU_TOP)

> > +            - description: SD card clock (from CMU_TOP)

> > +            - description: "USB 2.0 DRD clock (from CMU_TOP)"

> > +

> > +        clock-names:

> > +          items:

> > +            - const: oscclk

> > +            - const: rtcclk

> > +            - const: dout_hsi_bus

> > +            - const: dout_hsi_mmc_card

> > +            - const: dout_hsi_usb20drd

> > +

> > +  - if:

> > +      properties:

> > +        compatible:

> > +          contains:

> > +            const: samsung,exynos850-cmu-peri

> > +

> > +    then:

> > +      properties:

> > +        clocks:

> > +          items:

> > +            - description: External reference clock (26 MHz)

> > +            - description: CMU_PERI bus clock (from CMU_TOP)

> > +            - description: UART clock (from CMU_TOP)

> > +            - description: Parent clock for HSI2C and SPI (from CMU_TOP)

> > +

> > +        clock-names:

> > +          items:

> > +            - const: oscclk

> > +            - const: dout_peri_bus

> > +            - const: dout_peri_uart

> > +            - const: dout_peri_ip

> > +

> > +required:

> > +  - compatible

> > +  - "#clock-cells"

> > +  - clocks

> > +  - clock-names

> > +  - reg

> > +

> > +additionalProperties: false

> > +

> > +examples:

> > +  # Clock controller node for CMU_PERI

> > +  - |

> > +    #include <dt-bindings/clock/exynos850.h>

> > +

> > +    cmu_peri: clock-controller@10030000 {

> > +        compatible = "samsung,exynos850-cmu-peri";

> > +        reg = <0x10030000 0x8000>;

> > +        #clock-cells = <1>;

> > +

> > +        clocks = <&oscclk>, <&cmu_top DOUT_PERI_BUS>,

> > +                 <&cmu_top DOUT_PERI_UART>,

> > +                 <&cmu_top DOUT_PERI_IP>;

> > +        clock-names = "oscclk", "dout_peri_bus",

> > +                      "dout_peri_uart", "dout_peri_ip";

> > +    };

> > +

> > +  # External reference clock (should be provided in particular board DTS)

> > +  - |

> > +    oscclk: clock-oscclk {

> > +        compatible = "fixed-clock";

> > +        #clock-cells = <0>;

> > +        clock-output-names = "oscclk";

> > +        clock-frequency = <26000000>;

> > +    };

>

> Skip ossclk - it's trivial and not related to these bindings.

>

> > +

> > +  # UART controller node that consumes the clock generated by CMU_PERI

> > +  - |

> > +    #include <dt-bindings/clock/exynos850.h>

> > +    #include <dt-bindings/interrupt-controller/arm-gic.h>

> > +

> > +    serial_0: serial@13820000 {

> > +        compatible = "samsung,exynos850-uart";

> > +        reg = <0x13820000 0x100>;

> > +        interrupts = <GIC_SPI 227 IRQ_TYPE_LEVEL_HIGH>;

> > +        pinctrl-names = "default";

> > +        pinctrl-0 = <&uart0_pins>;

> > +        clocks = <&cmu_peri GOUT_UART_PCLK>, <&cmu_peri GOUT_UART_IPCLK>;

> > +        clock-names = "uart", "clk_uart_baud0";

>

> The same, skip it because it is trivial and common with all clock providers.

>


Sure, will do in v2.

> Also Rob's robot checker complains about it.

>

> Best regards,

> Krzysztof