From a81595729be6561d25ae64d5bbae059058234363 Mon Sep 17 00:00:00 2001 From: Giulio Benetti Date: Tue, 11 Jan 2022 16:54:11 -0500 Subject: [PATCH 01/43] dt-bindings: imx: Add clock binding for i.MXRT1050 Add the clock binding doc for i.MXRT1050. Signed-off-by: Giulio Benetti Signed-off-by: Jesse Taube [Jesse: added clocks from IMXRT1050_CLK_IPG_PDOF to IMXRT1050_CLK_DMA_MUX and moved IMXRT1050_CLK_END on] Acked-by: Stephen Boyd Link: https://lore.kernel.org/r/20220111215415.2075257-4-Mr.Bossman075@gmail.com Signed-off-by: Abel Vesa --- include/dt-bindings/clock/imxrt1050-clock.h | 72 +++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 include/dt-bindings/clock/imxrt1050-clock.h diff --git a/include/dt-bindings/clock/imxrt1050-clock.h b/include/dt-bindings/clock/imxrt1050-clock.h new file mode 100644 index 0000000000000..93bef0832d16d --- /dev/null +++ b/include/dt-bindings/clock/imxrt1050-clock.h @@ -0,0 +1,72 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ +/* + * Copyright(C) 2019 + * Author(s): Giulio Benetti + */ + +#ifndef __DT_BINDINGS_CLOCK_IMXRT1050_H +#define __DT_BINDINGS_CLOCK_IMXRT1050_H + +#define IMXRT1050_CLK_DUMMY 0 +#define IMXRT1050_CLK_CKIL 1 +#define IMXRT1050_CLK_CKIH 2 +#define IMXRT1050_CLK_OSC 3 +#define IMXRT1050_CLK_PLL2_PFD0_352M 4 +#define IMXRT1050_CLK_PLL2_PFD1_594M 5 +#define IMXRT1050_CLK_PLL2_PFD2_396M 6 +#define IMXRT1050_CLK_PLL3_PFD0_720M 7 +#define IMXRT1050_CLK_PLL3_PFD1_664_62M 8 +#define IMXRT1050_CLK_PLL3_PFD2_508_24M 9 +#define IMXRT1050_CLK_PLL3_PFD3_454_74M 10 +#define IMXRT1050_CLK_PLL2_198M 11 +#define IMXRT1050_CLK_PLL3_120M 12 +#define IMXRT1050_CLK_PLL3_80M 13 +#define IMXRT1050_CLK_PLL3_60M 14 +#define IMXRT1050_CLK_PLL1_BYPASS 15 +#define IMXRT1050_CLK_PLL2_BYPASS 16 +#define IMXRT1050_CLK_PLL3_BYPASS 17 +#define IMXRT1050_CLK_PLL5_BYPASS 19 +#define IMXRT1050_CLK_PLL1_REF_SEL 20 +#define IMXRT1050_CLK_PLL2_REF_SEL 21 +#define IMXRT1050_CLK_PLL3_REF_SEL 22 +#define IMXRT1050_CLK_PLL5_REF_SEL 23 +#define IMXRT1050_CLK_PRE_PERIPH_SEL 24 +#define IMXRT1050_CLK_PERIPH_SEL 25 +#define IMXRT1050_CLK_SEMC_ALT_SEL 26 +#define IMXRT1050_CLK_SEMC_SEL 27 +#define IMXRT1050_CLK_USDHC1_SEL 28 +#define IMXRT1050_CLK_USDHC2_SEL 29 +#define IMXRT1050_CLK_LPUART_SEL 30 +#define IMXRT1050_CLK_LCDIF_SEL 31 +#define IMXRT1050_CLK_VIDEO_POST_DIV_SEL 32 +#define IMXRT1050_CLK_VIDEO_DIV 33 +#define IMXRT1050_CLK_ARM_PODF 34 +#define IMXRT1050_CLK_LPUART_PODF 35 +#define IMXRT1050_CLK_USDHC1_PODF 36 +#define IMXRT1050_CLK_USDHC2_PODF 37 +#define IMXRT1050_CLK_SEMC_PODF 38 +#define IMXRT1050_CLK_AHB_PODF 39 +#define IMXRT1050_CLK_LCDIF_PRED 40 +#define IMXRT1050_CLK_LCDIF_PODF 41 +#define IMXRT1050_CLK_USDHC1 42 +#define IMXRT1050_CLK_USDHC2 43 +#define IMXRT1050_CLK_LPUART1 44 +#define IMXRT1050_CLK_SEMC 45 +#define IMXRT1050_CLK_LCDIF_APB 46 +#define IMXRT1050_CLK_PLL1_ARM 47 +#define IMXRT1050_CLK_PLL2_SYS 48 +#define IMXRT1050_CLK_PLL3_USB_OTG 49 +#define IMXRT1050_CLK_PLL4_AUDIO 50 +#define IMXRT1050_CLK_PLL5_VIDEO 51 +#define IMXRT1050_CLK_PLL6_ENET 52 +#define IMXRT1050_CLK_PLL7_USB_HOST 53 +#define IMXRT1050_CLK_LCDIF_PIX 54 +#define IMXRT1050_CLK_USBOH3 55 +#define IMXRT1050_CLK_IPG_PDOF 56 +#define IMXRT1050_CLK_PER_CLK_SEL 57 +#define IMXRT1050_CLK_PER_PDOF 58 +#define IMXRT1050_CLK_DMA 59 +#define IMXRT1050_CLK_DMA_MUX 60 +#define IMXRT1050_CLK_END 61 + +#endif /* __DT_BINDINGS_CLOCK_IMXRT1050_H */ From d6e359305b4500c93af79765b5067cbc5898e973 Mon Sep 17 00:00:00 2001 From: Jesse Taube Date: Tue, 11 Jan 2022 16:54:12 -0500 Subject: [PATCH 02/43] dt-bindings: clock: imx: Add documentation for i.MXRT1050 clock Add DT binding documentation for i.MXRT1050 clock driver. Cc: Giulio Benetti Signed-off-by: Jesse Taube Reviewed-by: Stephen Boyd Link: https://lore.kernel.org/r/20220111215415.2075257-5-Mr.Bossman075@gmail.com Signed-off-by: Abel Vesa --- .../bindings/clock/imxrt1050-clock.yaml | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/imxrt1050-clock.yaml diff --git a/Documentation/devicetree/bindings/clock/imxrt1050-clock.yaml b/Documentation/devicetree/bindings/clock/imxrt1050-clock.yaml new file mode 100644 index 0000000000000..35fd08c143f43 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/imxrt1050-clock.yaml @@ -0,0 +1,67 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/imxrt1050-clock.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Clock bindings for Freescale i.MXRT + +maintainers: + - Giulio Benetti + - Jesse Taube + +description: | + The clock consumer should specify the desired clock by having the clock + ID in its "clocks" phandle cell. See include/dt-bindings/clock/imxrt*-clock.h + for the full list of i.MXRT clock IDs. + +properties: + compatible: + const: fsl,imxrt1050-ccm + + reg: + maxItems: 1 + + interrupts: + maxItems: 2 + + clocks: + description: 24m osc + maxItems: 1 + + clock-names: + const: osc + + '#clock-cells': + const: 1 + +required: + - compatible + - reg + - interrupts + - clocks + - clock-names + - '#clock-cells' + +additionalProperties: false + +examples: + - | + #include + + clks: clock-controller@400fc000 { + compatible = "fsl,imxrt1050-ccm"; + reg = <0x400fc000 0x4000>; + interrupts = <95>, <96>; + clocks = <&osc>; + clock-names = "osc"; + #clock-cells = <1>; + }; + + lpuart1: serial@40184000 { + compatible = "fsl,imxrt1050-lpuart"; + reg = <0x40184000 0x4000>; + interrupts = <20>; + clocks = <&clks IMXRT1050_CLK_LPUART1>; + clock-names = "ipg"; + }; From 7154b046d8f3a441474ced1688eb348d42f5f165 Mon Sep 17 00:00:00 2001 From: Jesse Taube Date: Tue, 11 Jan 2022 16:54:13 -0500 Subject: [PATCH 03/43] clk: imx: Add initial support for i.MXRT1050 clock driver Add clock driver support for i.MXRT1050. Signed-off-by: Jesse Taube Suggested-by: Giulio Benetti Reviewed-by: Stephen Boyd Link: https://lore.kernel.org/r/20220111215415.2075257-6-Mr.Bossman075@gmail.com Signed-off-by: Abel Vesa --- drivers/clk/imx/Kconfig | 7 ++ drivers/clk/imx/Makefile | 1 + drivers/clk/imx/clk-imxrt1050.c | 168 ++++++++++++++++++++++++++++++++ 3 files changed, 176 insertions(+) create mode 100644 drivers/clk/imx/clk-imxrt1050.c diff --git a/drivers/clk/imx/Kconfig b/drivers/clk/imx/Kconfig index c08edbd04d223..45641b8bdc50a 100644 --- a/drivers/clk/imx/Kconfig +++ b/drivers/clk/imx/Kconfig @@ -105,3 +105,10 @@ config CLK_IMX8ULP select MXC_CLK help Build the driver for i.MX8ULP CCM Clock Driver + +config CLK_IMXRT1050 + tristate "IMXRT1050 CCM Clock Driver" + depends on SOC_IMXRT + select MXC_CLK + help + Build the driver for i.MXRT1050 CCM Clock Driver diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile index b5e040026dfb8..1e13c5cb37d96 100644 --- a/drivers/clk/imx/Makefile +++ b/drivers/clk/imx/Makefile @@ -46,4 +46,5 @@ obj-$(CONFIG_CLK_IMX6SX) += clk-imx6sx.o obj-$(CONFIG_CLK_IMX6UL) += clk-imx6ul.o obj-$(CONFIG_CLK_IMX7D) += clk-imx7d.o obj-$(CONFIG_CLK_IMX7ULP) += clk-imx7ulp.o +obj-$(CONFIG_CLK_IMXRT1050) += clk-imxrt1050.o obj-$(CONFIG_CLK_VF610) += clk-vf610.o diff --git a/drivers/clk/imx/clk-imxrt1050.c b/drivers/clk/imx/clk-imxrt1050.c new file mode 100644 index 0000000000000..9539d35588ee9 --- /dev/null +++ b/drivers/clk/imx/clk-imxrt1050.c @@ -0,0 +1,168 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (C) 2021 + * Author(s): + * Jesse Taube + * Giulio Benetti + */ +#include +#include +#include +#include +#include + +#include "clk.h" + +static const char * const pll_ref_sels[] = {"osc", "dummy", }; +static const char * const per_sels[] = {"ipg_pdof", "osc", }; +static const char * const pll1_bypass_sels[] = {"pll1_arm", "pll1_arm_ref_sel", }; +static const char * const pll2_bypass_sels[] = {"pll2_sys", "pll2_sys_ref_sel", }; +static const char * const pll3_bypass_sels[] = {"pll3_usb_otg", "pll3_usb_otg_ref_sel", }; +static const char * const pll5_bypass_sels[] = {"pll5_video", "pll5_video_ref_sel", }; +static const char *const pre_periph_sels[] = { + "pll2_sys", "pll2_pfd2_396m", "pll2_pfd0_352m", "arm_podf", }; +static const char *const periph_sels[] = { "pre_periph_sel", "todo", }; +static const char *const usdhc_sels[] = { "pll2_pfd2_396m", "pll2_pfd0_352m", }; +static const char *const lpuart_sels[] = { "pll3_80m", "osc", }; +static const char *const lcdif_sels[] = { + "pll2_sys", "pll3_pfd3_454_74m", "pll5_video", "pll2_pfd0_352m", + "pll2_pfd1_594m", "pll3_pfd1_664_62m", }; +static const char *const semc_alt_sels[] = { "pll2_pfd2_396m", "pll3_pfd1_664_62m", }; +static const char *const semc_sels[] = { "periph_sel", "semc_alt_sel", }; + +static struct clk_hw **hws; +static struct clk_hw_onecell_data *clk_hw_data; + +static int imxrt1050_clocks_probe(struct platform_device *pdev) +{ + void __iomem *ccm_base; + void __iomem *pll_base; + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct device_node *anp; + int ret; + + clk_hw_data = kzalloc(struct_size(clk_hw_data, hws, + IMXRT1050_CLK_END), GFP_KERNEL); + if (WARN_ON(!clk_hw_data)) + return -ENOMEM; + + clk_hw_data->num = IMXRT1050_CLK_END; + hws = clk_hw_data->hws; + + hws[IMXRT1050_CLK_OSC] = imx_obtain_fixed_clk_hw(np, "osc"); + + anp = of_find_compatible_node(NULL, NULL, "fsl,imxrt-anatop"); + pll_base = of_iomap(anp, 0); + of_node_put(anp); + if (WARN_ON(!pll_base)) + return -ENOMEM; + + /* Anatop clocks */ + hws[IMXRT1050_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0UL); + + hws[IMXRT1050_CLK_PLL1_REF_SEL] = imx_clk_hw_mux("pll1_arm_ref_sel", + pll_base + 0x0, 14, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + hws[IMXRT1050_CLK_PLL2_REF_SEL] = imx_clk_hw_mux("pll2_sys_ref_sel", + pll_base + 0x30, 14, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + hws[IMXRT1050_CLK_PLL3_REF_SEL] = imx_clk_hw_mux("pll3_usb_otg_ref_sel", + pll_base + 0x10, 14, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + hws[IMXRT1050_CLK_PLL5_REF_SEL] = imx_clk_hw_mux("pll5_video_ref_sel", + pll_base + 0xa0, 14, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + + hws[IMXRT1050_CLK_PLL1_ARM] = imx_clk_hw_pllv3(IMX_PLLV3_SYS, "pll1_arm", + "pll1_arm_ref_sel", pll_base + 0x0, 0x7f); + hws[IMXRT1050_CLK_PLL2_SYS] = imx_clk_hw_pllv3(IMX_PLLV3_GENERIC, "pll2_sys", + "pll2_sys_ref_sel", pll_base + 0x30, 0x1); + hws[IMXRT1050_CLK_PLL3_USB_OTG] = imx_clk_hw_pllv3(IMX_PLLV3_USB, "pll3_usb_otg", + "pll3_usb_otg_ref_sel", pll_base + 0x10, 0x1); + hws[IMXRT1050_CLK_PLL5_VIDEO] = imx_clk_hw_pllv3(IMX_PLLV3_AV, "pll5_video", + "pll5_video_ref_sel", pll_base + 0xa0, 0x7f); + + /* PLL bypass out */ + hws[IMXRT1050_CLK_PLL1_BYPASS] = imx_clk_hw_mux_flags("pll1_bypass", pll_base + 0x0, 16, 1, + pll1_bypass_sels, ARRAY_SIZE(pll1_bypass_sels), CLK_SET_RATE_PARENT); + hws[IMXRT1050_CLK_PLL2_BYPASS] = imx_clk_hw_mux_flags("pll2_bypass", pll_base + 0x30, 16, 1, + pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels), CLK_SET_RATE_PARENT); + hws[IMXRT1050_CLK_PLL3_BYPASS] = imx_clk_hw_mux_flags("pll3_bypass", pll_base + 0x10, 16, 1, + pll3_bypass_sels, ARRAY_SIZE(pll3_bypass_sels), CLK_SET_RATE_PARENT); + hws[IMXRT1050_CLK_PLL5_BYPASS] = imx_clk_hw_mux_flags("pll5_bypass", pll_base + 0xa0, 16, 1, + pll5_bypass_sels, ARRAY_SIZE(pll5_bypass_sels), CLK_SET_RATE_PARENT); + + hws[IMXRT1050_CLK_VIDEO_POST_DIV_SEL] = imx_clk_hw_divider("video_post_div_sel", + "pll5_video", pll_base + 0xa0, 19, 2); + hws[IMXRT1050_CLK_VIDEO_DIV] = imx_clk_hw_divider("video_div", + "video_post_div_sel", pll_base + 0x170, 30, 2); + + hws[IMXRT1050_CLK_PLL3_80M] = imx_clk_hw_fixed_factor("pll3_80m", "pll3_usb_otg", 1, 6); + + hws[IMXRT1050_CLK_PLL2_PFD0_352M] = imx_clk_hw_pfd("pll2_pfd0_352m", "pll2_sys", pll_base + 0x100, 0); + hws[IMXRT1050_CLK_PLL2_PFD1_594M] = imx_clk_hw_pfd("pll2_pfd1_594m", "pll2_sys", pll_base + 0x100, 1); + hws[IMXRT1050_CLK_PLL2_PFD2_396M] = imx_clk_hw_pfd("pll2_pfd2_396m", "pll2_sys", pll_base + 0x100, 2); + hws[IMXRT1050_CLK_PLL3_PFD1_664_62M] = imx_clk_hw_pfd("pll3_pfd1_664_62m", "pll3_usb_otg", pll_base + 0xf0, 1); + hws[IMXRT1050_CLK_PLL3_PFD3_454_74M] = imx_clk_hw_pfd("pll3_pfd3_454_74m", "pll3_usb_otg", pll_base + 0xf0, 3); + + /* CCM clocks */ + ccm_base = devm_platform_ioremap_resource(pdev, 0); + if (WARN_ON(IS_ERR(ccm_base))) + return PTR_ERR(ccm_base); + + hws[IMXRT1050_CLK_ARM_PODF] = imx_clk_hw_divider("arm_podf", "pll1_arm", ccm_base + 0x10, 0, 3); + hws[IMXRT1050_CLK_PRE_PERIPH_SEL] = imx_clk_hw_mux("pre_periph_sel", ccm_base + 0x18, 18, 2, + pre_periph_sels, ARRAY_SIZE(pre_periph_sels)); + hws[IMXRT1050_CLK_PERIPH_SEL] = imx_clk_hw_mux("periph_sel", ccm_base + 0x14, 25, 1, + periph_sels, ARRAY_SIZE(periph_sels)); + hws[IMXRT1050_CLK_USDHC1_SEL] = imx_clk_hw_mux("usdhc1_sel", ccm_base + 0x1c, 16, 1, + usdhc_sels, ARRAY_SIZE(usdhc_sels)); + hws[IMXRT1050_CLK_USDHC2_SEL] = imx_clk_hw_mux("usdhc2_sel", ccm_base + 0x1c, 17, 1, + usdhc_sels, ARRAY_SIZE(usdhc_sels)); + hws[IMXRT1050_CLK_LPUART_SEL] = imx_clk_hw_mux("lpuart_sel", ccm_base + 0x24, 6, 1, + lpuart_sels, ARRAY_SIZE(lpuart_sels)); + hws[IMXRT1050_CLK_LCDIF_SEL] = imx_clk_hw_mux("lcdif_sel", ccm_base + 0x38, 15, 3, + lcdif_sels, ARRAY_SIZE(lcdif_sels)); + hws[IMXRT1050_CLK_PER_CLK_SEL] = imx_clk_hw_mux("per_sel", ccm_base + 0x1C, 6, 1, + per_sels, ARRAY_SIZE(per_sels)); + hws[IMXRT1050_CLK_SEMC_ALT_SEL] = imx_clk_hw_mux("semc_alt_sel", ccm_base + 0x14, 7, 1, + semc_alt_sels, ARRAY_SIZE(semc_alt_sels)); + hws[IMXRT1050_CLK_SEMC_SEL] = imx_clk_hw_mux_flags("semc_sel", ccm_base + 0x14, 6, 1, + semc_sels, ARRAY_SIZE(semc_sels), CLK_IS_CRITICAL); + + hws[IMXRT1050_CLK_AHB_PODF] = imx_clk_hw_divider("ahb", "periph_sel", ccm_base + 0x14, 10, 3); + hws[IMXRT1050_CLK_IPG_PDOF] = imx_clk_hw_divider("ipg", "ahb", ccm_base + 0x14, 8, 2); + hws[IMXRT1050_CLK_PER_PDOF] = imx_clk_hw_divider("per", "per_sel", ccm_base + 0x1C, 0, 5); + + hws[IMXRT1050_CLK_USDHC1_PODF] = imx_clk_hw_divider("usdhc1_podf", "usdhc1_sel", ccm_base + 0x24, 11, 3); + hws[IMXRT1050_CLK_USDHC2_PODF] = imx_clk_hw_divider("usdhc2_podf", "usdhc2_sel", ccm_base + 0x24, 16, 3); + hws[IMXRT1050_CLK_LPUART_PODF] = imx_clk_hw_divider("lpuart_podf", "lpuart_sel", ccm_base + 0x24, 0, 6); + hws[IMXRT1050_CLK_LCDIF_PRED] = imx_clk_hw_divider("lcdif_pred", "lcdif_sel", ccm_base + 0x38, 12, 3); + hws[IMXRT1050_CLK_LCDIF_PODF] = imx_clk_hw_divider("lcdif_podf", "lcdif_pred", ccm_base + 0x18, 23, 3); + + hws[IMXRT1050_CLK_USDHC1] = imx_clk_hw_gate2("usdhc1", "usdhc1_podf", ccm_base + 0x80, 2); + hws[IMXRT1050_CLK_USDHC2] = imx_clk_hw_gate2("usdhc2", "usdhc2_podf", ccm_base + 0x80, 4); + hws[IMXRT1050_CLK_LPUART1] = imx_clk_hw_gate2("lpuart1", "lpuart_podf", ccm_base + 0x7c, 24); + hws[IMXRT1050_CLK_LCDIF_APB] = imx_clk_hw_gate2("lcdif", "lcdif_podf", ccm_base + 0x74, 10); + hws[IMXRT1050_CLK_DMA] = imx_clk_hw_gate("dma", "ipg", ccm_base + 0x7C, 6); + hws[IMXRT1050_CLK_DMA_MUX] = imx_clk_hw_gate("dmamux0", "ipg", ccm_base + 0x7C, 7); + imx_check_clk_hws(hws, IMXRT1050_CLK_END); + + ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data); + if (ret < 0) { + dev_err(dev, "Failed to register clks for i.MXRT1050.\n"); + imx_unregister_hw_clocks(hws, IMXRT1050_CLK_END); + } + return ret; +} +static const struct of_device_id imxrt1050_clk_of_match[] = { + { .compatible = "fsl,imxrt1050-ccm" }, + { /* Sentinel */ } +}; +MODULE_DEVICE_TABLE(of, imxrt1050_clk_of_match); + +static struct platform_driver imxrt1050_clk_driver = { + .probe = imxrt1050_clocks_probe, + .driver = { + .name = "imxrt1050-ccm", + .of_match_table = imxrt1050_clk_of_match, + }, +}; +module_platform_driver(imxrt1050_clk_driver); From 036a4b4b4dfa6c56806b71daf8589044ff7aeeaa Mon Sep 17 00:00:00 2001 From: Jacky Bai Date: Fri, 17 Dec 2021 15:25:33 +0200 Subject: [PATCH 04/43] clk: imx: Add imx8dxl clk driver Add files for imx8dxl clk driver which is based on imx8qxp clock driver. Signed-off-by: Jacky Bai Signed-off-by: Abel Vesa Acked-by: Stephen Boyd Link: https://lore.kernel.org/r/1639747533-9778-1-git-send-email-abel.vesa@nxp.com --- drivers/clk/imx/Makefile | 3 +- drivers/clk/imx/clk-imx8dxl-rsrc.c | 66 ++++++++++++++++++++++++++++++ drivers/clk/imx/clk-imx8qxp.c | 1 + drivers/clk/imx/clk-scu.h | 1 + 4 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 drivers/clk/imx/clk-imx8dxl-rsrc.c diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile index 1e13c5cb37d96..aa8f5204d7e10 100644 --- a/drivers/clk/imx/Makefile +++ b/drivers/clk/imx/Makefile @@ -28,7 +28,8 @@ obj-$(CONFIG_CLK_IMX8MQ) += clk-imx8mq.o obj-$(CONFIG_MXC_CLK_SCU) += clk-imx-scu.o clk-imx-lpcg-scu.o clk-imx-scu-$(CONFIG_CLK_IMX8QXP) += clk-scu.o clk-imx8qxp.o \ - clk-imx8qxp-rsrc.o clk-imx8qm-rsrc.o + clk-imx8qxp-rsrc.o clk-imx8qm-rsrc.o \ + clk-imx8dxl-rsrc.o clk-imx-lpcg-scu-$(CONFIG_CLK_IMX8QXP) += clk-lpcg-scu.o clk-imx8qxp-lpcg.o obj-$(CONFIG_CLK_IMX8ULP) += clk-imx8ulp.o diff --git a/drivers/clk/imx/clk-imx8dxl-rsrc.c b/drivers/clk/imx/clk-imx8dxl-rsrc.c new file mode 100644 index 0000000000000..69b7aa34fff5c --- /dev/null +++ b/drivers/clk/imx/clk-imx8dxl-rsrc.c @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2019~2020 NXP + */ + +#include + +#include "clk-scu.h" + +/* Keep sorted in the ascending order */ +static u32 imx8dxl_clk_scu_rsrc_table[] = { + IMX_SC_R_SPI_0, + IMX_SC_R_SPI_1, + IMX_SC_R_SPI_2, + IMX_SC_R_SPI_3, + IMX_SC_R_UART_0, + IMX_SC_R_UART_1, + IMX_SC_R_UART_2, + IMX_SC_R_UART_3, + IMX_SC_R_I2C_0, + IMX_SC_R_I2C_1, + IMX_SC_R_I2C_2, + IMX_SC_R_I2C_3, + IMX_SC_R_ADC_0, + IMX_SC_R_FTM_0, + IMX_SC_R_FTM_1, + IMX_SC_R_CAN_0, + IMX_SC_R_LCD_0, + IMX_SC_R_LCD_0_PWM_0, + IMX_SC_R_PWM_0, + IMX_SC_R_PWM_1, + IMX_SC_R_PWM_2, + IMX_SC_R_PWM_3, + IMX_SC_R_PWM_4, + IMX_SC_R_PWM_5, + IMX_SC_R_PWM_6, + IMX_SC_R_PWM_7, + IMX_SC_R_GPT_0, + IMX_SC_R_GPT_1, + IMX_SC_R_GPT_2, + IMX_SC_R_GPT_3, + IMX_SC_R_GPT_4, + IMX_SC_R_FSPI_0, + IMX_SC_R_FSPI_1, + IMX_SC_R_SDHC_0, + IMX_SC_R_SDHC_1, + IMX_SC_R_SDHC_2, + IMX_SC_R_ENET_0, + IMX_SC_R_ENET_1, + IMX_SC_R_MLB_0, + IMX_SC_R_USB_1, + IMX_SC_R_NAND, + IMX_SC_R_M4_0_I2C, + IMX_SC_R_M4_0_UART, + IMX_SC_R_ELCDIF_PLL, + IMX_SC_R_AUDIO_PLL_0, + IMX_SC_R_AUDIO_PLL_1, + IMX_SC_R_AUDIO_CLK_0, + IMX_SC_R_AUDIO_CLK_1, + IMX_SC_R_A35 +}; + +const struct imx_clk_scu_rsrc_table imx_clk_scu_rsrc_imx8dxl = { + .rsrc = imx8dxl_clk_scu_rsrc_table, + .num = ARRAY_SIZE(imx8dxl_clk_scu_rsrc_table), +}; diff --git a/drivers/clk/imx/clk-imx8qxp.c b/drivers/clk/imx/clk-imx8qxp.c index 40a2efb1329be..546a3703bfeb2 100644 --- a/drivers/clk/imx/clk-imx8qxp.c +++ b/drivers/clk/imx/clk-imx8qxp.c @@ -295,6 +295,7 @@ static int imx8qxp_clk_probe(struct platform_device *pdev) static const struct of_device_id imx8qxp_match[] = { { .compatible = "fsl,scu-clk", }, + { .compatible = "fsl,imx8dxl-clk", &imx_clk_scu_rsrc_imx8dxl, }, { .compatible = "fsl,imx8qxp-clk", &imx_clk_scu_rsrc_imx8qxp, }, { .compatible = "fsl,imx8qm-clk", &imx_clk_scu_rsrc_imx8qm, }, { /* sentinel */ } diff --git a/drivers/clk/imx/clk-scu.h b/drivers/clk/imx/clk-scu.h index 22156e93b85d2..af7b697f51cae 100644 --- a/drivers/clk/imx/clk-scu.h +++ b/drivers/clk/imx/clk-scu.h @@ -21,6 +21,7 @@ struct imx_clk_scu_rsrc_table { extern struct list_head imx_scu_clks[]; extern const struct dev_pm_ops imx_clk_lpcg_scu_pm_ops; +extern const struct imx_clk_scu_rsrc_table imx_clk_scu_rsrc_imx8dxl; extern const struct imx_clk_scu_rsrc_table imx_clk_scu_rsrc_imx8qxp; extern const struct imx_clk_scu_rsrc_table imx_clk_scu_rsrc_imx8qm; From 842f4cb7263953020f4e2f2f0005fc3e6fc56144 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 26 Jan 2022 15:55:33 +0100 Subject: [PATCH 05/43] clk: rockchip: Add more PLL rates for rk3568 This adds a few more PLL settings needed for some standard resolutions: 297MHz 3840x2160-30.00 241.5MHz 2560x1440-59.95 135MHz 1280x1024-75.02 119MHz 1680x1050-59.88 108MHz 1280x1024-60.02 78.75MHz 1024x768-75.03 Changes since v3: - new patch Signed-off-by: Sascha Hauer Link: https://lore.kernel.org/r/20220126145549.617165-12-s.hauer@pengutronix.de Signed-off-by: Heiko Stuebner --- drivers/clk/rockchip/clk-rk3568.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/clk/rockchip/clk-rk3568.c b/drivers/clk/rockchip/clk-rk3568.c index 69a9e8069a486..9d889fc46811f 100644 --- a/drivers/clk/rockchip/clk-rk3568.c +++ b/drivers/clk/rockchip/clk-rk3568.c @@ -71,11 +71,17 @@ static struct rockchip_pll_rate_table rk3568_pll_rates[] = { RK3036_PLL_RATE(500000000, 1, 125, 6, 1, 1, 0), RK3036_PLL_RATE(408000000, 1, 68, 2, 2, 1, 0), RK3036_PLL_RATE(312000000, 1, 78, 6, 1, 1, 0), + RK3036_PLL_RATE(297000000, 2, 99, 4, 1, 1, 0), + RK3036_PLL_RATE(241500000, 2, 161, 4, 2, 1, 0), RK3036_PLL_RATE(216000000, 1, 72, 4, 2, 1, 0), RK3036_PLL_RATE(200000000, 1, 100, 3, 4, 1, 0), RK3036_PLL_RATE(148500000, 1, 99, 4, 4, 1, 0), + RK3036_PLL_RATE(135000000, 2, 45, 4, 1, 1, 0), + RK3036_PLL_RATE(119000000, 3, 119, 4, 2, 1, 0), + RK3036_PLL_RATE(108000000, 2, 45, 5, 1, 1, 0), RK3036_PLL_RATE(100000000, 1, 150, 6, 6, 1, 0), RK3036_PLL_RATE(96000000, 1, 96, 6, 4, 1, 0), + RK3036_PLL_RATE(78750000, 1, 96, 6, 4, 1, 0), RK3036_PLL_RATE(74250000, 2, 99, 4, 4, 1, 0), { /* sentinel */ }, }; From ff3187eabb5ce478d15b6ed62eb286756adefac3 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 26 Jan 2022 15:55:46 +0100 Subject: [PATCH 06/43] clk: rockchip: drop CLK_SET_RATE_PARENT from dclk_vop* on rk3568 The pixel clocks dclk_vop[012] can be clocked from hpll, vpll, gpll or cpll. gpll and cpll also drive many other clocks, so changing the dclk_vop[012] clocks could change these other clocks as well. Drop CLK_SET_RATE_PARENT to fix that. With this change the VOP2 driver can only adjust the pixel clocks with the divider between the PLL and the dclk_vop[012] which means the user may have to adjust the PLL clock to a suitable rate using the assigned-clock-rate device tree property. Signed-off-by: Sascha Hauer Link: https://lore.kernel.org/r/20220126145549.617165-25-s.hauer@pengutronix.de Signed-off-by: Heiko Stuebner --- drivers/clk/rockchip/clk-rk3568.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/clk/rockchip/clk-rk3568.c b/drivers/clk/rockchip/clk-rk3568.c index 9d889fc46811f..7687c62d1fa84 100644 --- a/drivers/clk/rockchip/clk-rk3568.c +++ b/drivers/clk/rockchip/clk-rk3568.c @@ -1044,13 +1044,13 @@ static struct rockchip_clk_branch rk3568_clk_branches[] __initdata = { RK3568_CLKGATE_CON(20), 8, GFLAGS), GATE(HCLK_VOP, "hclk_vop", "hclk_vo", 0, RK3568_CLKGATE_CON(20), 9, GFLAGS), - COMPOSITE(DCLK_VOP0, "dclk_vop0", hpll_vpll_gpll_cpll_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, + COMPOSITE(DCLK_VOP0, "dclk_vop0", hpll_vpll_gpll_cpll_p, CLK_SET_RATE_NO_REPARENT, RK3568_CLKSEL_CON(39), 10, 2, MFLAGS, 0, 8, DFLAGS, RK3568_CLKGATE_CON(20), 10, GFLAGS), - COMPOSITE(DCLK_VOP1, "dclk_vop1", hpll_vpll_gpll_cpll_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, + COMPOSITE(DCLK_VOP1, "dclk_vop1", hpll_vpll_gpll_cpll_p, CLK_SET_RATE_NO_REPARENT, RK3568_CLKSEL_CON(40), 10, 2, MFLAGS, 0, 8, DFLAGS, RK3568_CLKGATE_CON(20), 11, GFLAGS), - COMPOSITE(DCLK_VOP2, "dclk_vop2", hpll_vpll_gpll_cpll_p, 0, + COMPOSITE(DCLK_VOP2, "dclk_vop2", hpll_vpll_gpll_cpll_p, CLK_SET_RATE_NO_REPARENT, RK3568_CLKSEL_CON(41), 10, 2, MFLAGS, 0, 8, DFLAGS, RK3568_CLKGATE_CON(20), 12, GFLAGS), GATE(CLK_VOP_PWM, "clk_vop_pwm", "xin24m", 0, From 6e69052f01d9131388cfcfaee929120118a267f4 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 26 Jan 2022 15:55:47 +0100 Subject: [PATCH 07/43] clk: rockchip: Add CLK_SET_RATE_PARENT to the HDMI reference clock on rk3568 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On the rk3568 we have this (simplified) situation: .--------. .-----. .---------. -| hpll |--.--| /n |----|dclk_vop0|- `--------´ | `-----´ `---------´ | .-----. .---------. `--| /m |----|dclk_vop1|- | `-----´ `---------´ | .---------. `-------------|hdmi_ref |- `---------´ For the HDMI to work the HDMI reference clock needs to be the same as the pixel clock which means the dividers have be set to one. The last patch removed the CLK_SET_RATE_PARENT flag from the pixel clocks which means the hpll is not changed on pixel clock changes. In order to allow the HDMI controller to set a suitable PLL rate we now add the CLK_SET_RATE_PARENT flag to the HDMI reference clock. With this the flow becomes: 1) HDMI controller driver sets the rate to its pixel clock which means hpll is set to the pixel clock 2) VOP2 driver sets dclk_vop[012] to the pixel clock. As this can't change the hpll clock anymore this means only the divider is adjusted to the desired value of dividing by one. Signed-off-by: Sascha Hauer Link: https://lore.kernel.org/r/20220126145549.617165-26-s.hauer@pengutronix.de Signed-off-by: Heiko Stuebner --- drivers/clk/rockchip/clk-rk3568.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/rockchip/clk-rk3568.c b/drivers/clk/rockchip/clk-rk3568.c index 7687c62d1fa84..63dfbeeeb06d9 100644 --- a/drivers/clk/rockchip/clk-rk3568.c +++ b/drivers/clk/rockchip/clk-rk3568.c @@ -1568,7 +1568,7 @@ static struct rockchip_clk_branch rk3568_clk_pmu_branches[] __initdata = { RK3568_PMU_CLKGATE_CON(2), 14, GFLAGS), GATE(XIN_OSC0_EDPPHY_G, "xin_osc0_edpphy_g", "xin24m", 0, RK3568_PMU_CLKGATE_CON(2), 15, GFLAGS), - MUX(CLK_HDMI_REF, "clk_hdmi_ref", clk_hdmi_ref_p, 0, + MUX(CLK_HDMI_REF, "clk_hdmi_ref", clk_hdmi_ref_p, CLK_SET_RATE_PARENT, RK3568_PMU_CLKSEL_CON(8), 7, 1, MFLAGS), }; From b191fe39a5ff2334b60ef4588ec15a0abd88f6a4 Mon Sep 17 00:00:00 2001 From: Wang Qing Date: Mon, 14 Feb 2022 17:55:39 -0800 Subject: [PATCH 08/43] clk: mvebu: use time_is_before_eq_jiffies() instead of open coding it Use the helper function time_is_{before,after}_jiffies() to improve code readability. Signed-off-by: Wang Qing Link: https://lore.kernel.org/r/1644890154-64915-3-git-send-email-wangqing@vivo.com Signed-off-by: Stephen Boyd --- drivers/clk/mvebu/armada-37xx-periph.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/clk/mvebu/armada-37xx-periph.c b/drivers/clk/mvebu/armada-37xx-periph.c index 32ac6b6b75306..e3777ca659120 100644 --- a/drivers/clk/mvebu/armada-37xx-periph.c +++ b/drivers/clk/mvebu/armada-37xx-periph.c @@ -25,6 +25,7 @@ #include #include #include +#include #define TBG_SEL 0x0 #define DIV_SEL0 0x4 @@ -541,7 +542,7 @@ static void clk_pm_cpu_set_rate_wa(struct clk_pm_cpu *pm_cpu, * We are going to L0 with rate >= 1GHz. Check whether we have been at * L1 for long enough time. If not, go to L1 for 20ms. */ - if (pm_cpu->l1_expiration && jiffies >= pm_cpu->l1_expiration) + if (pm_cpu->l1_expiration && time_is_before_eq_jiffies(pm_cpu->l1_expiration)) goto invalidate_l1_exp; regmap_update_bits(base, ARMADA_37XX_NB_CPU_LOAD, From 39d1e443173a58a6a3452bb931907ce0fb4061e3 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 11 Feb 2022 11:13:11 +0200 Subject: [PATCH 09/43] clk: imx8mp: Add missing IMX8MP_CLK_MEDIA_MIPI_PHY1_REF_ROOT clock The IMX8MP_CLK_MEDIA_MIPI_PHY1_REF_ROOT clock derives from the media_mipi_phy1_ref clock and is gated by the shared media clock gate. Its identifier is defined in dt-bindings/clock/imx8mp-clock.h but its definition is missing from the driver. Add it. Signed-off-by: Laurent Pinchart Reviewed-by: Paul Elder Link: https://lore.kernel.org/r/20220211091311.28146-1-laurent.pinchart@ideasonboard.com Signed-off-by: Abel Vesa --- drivers/clk/imx/clk-imx8mp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/imx/clk-imx8mp.c b/drivers/clk/imx/clk-imx8mp.c index c990ad37882bf..f23b92906d3bf 100644 --- a/drivers/clk/imx/clk-imx8mp.c +++ b/drivers/clk/imx/clk-imx8mp.c @@ -694,6 +694,7 @@ static int imx8mp_clocks_probe(struct platform_device *pdev) hws[IMX8MP_CLK_MEDIA_CAM2_PIX_ROOT] = imx_clk_hw_gate2_shared2("media_cam2_pix_root_clk", "media_cam2_pix", ccm_base + 0x45d0, 0, &share_count_media); hws[IMX8MP_CLK_MEDIA_DISP1_PIX_ROOT] = imx_clk_hw_gate2_shared2("media_disp1_pix_root_clk", "media_disp1_pix", ccm_base + 0x45d0, 0, &share_count_media); hws[IMX8MP_CLK_MEDIA_DISP2_PIX_ROOT] = imx_clk_hw_gate2_shared2("media_disp2_pix_root_clk", "media_disp2_pix", ccm_base + 0x45d0, 0, &share_count_media); + hws[IMX8MP_CLK_MEDIA_MIPI_PHY1_REF_ROOT] = imx_clk_hw_gate2_shared2("media_mipi_phy1_ref_root", "media_mipi_phy1_ref", ccm_base + 0x45d0, 0, &share_count_media); hws[IMX8MP_CLK_MEDIA_ISP_ROOT] = imx_clk_hw_gate2_shared2("media_isp_root_clk", "media_isp", ccm_base + 0x45d0, 0, &share_count_media); hws[IMX8MP_CLK_USDHC3_ROOT] = imx_clk_hw_gate4("usdhc3_root_clk", "usdhc3", ccm_base + 0x45e0, 0); From 9f565399ad0739dbdeac868e40e86e80f54dc77b Mon Sep 17 00:00:00 2001 From: "Minghao Chi (CGEL ZTE)" Date: Mon, 21 Feb 2022 02:01:03 +0000 Subject: [PATCH 10/43] clk/rockchip: Use of_device_get_match_data() Use of_device_get_match_data() to simplify the code. Reported-by: Zeal Robot Signed-off-by: Minghao Chi (CGEL ZTE) Link: https://lore.kernel.org/r/20220221020103.1925026-1-chi.minghao@zte.com.cn Signed-off-by: Heiko Stuebner --- drivers/clk/rockchip/clk-rk3568.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/clk/rockchip/clk-rk3568.c b/drivers/clk/rockchip/clk-rk3568.c index 63dfbeeeb06d9..606ae6cd918b2 100644 --- a/drivers/clk/rockchip/clk-rk3568.c +++ b/drivers/clk/rockchip/clk-rk3568.c @@ -1703,14 +1703,12 @@ static const struct of_device_id clk_rk3568_match_table[] = { static int __init clk_rk3568_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; - const struct of_device_id *match; const struct clk_rk3568_inits *init_data; - match = of_match_device(clk_rk3568_match_table, &pdev->dev); - if (!match || !match->data) + init_data = (struct clk_rk3568_inits *)of_device_get_match_data(&pdev->dev); + if (!init_data) return -EINVAL; - init_data = match->data; if (init_data->inits) init_data->inits(np); From 10b74af310735860510a533433b1d3ab2e05a138 Mon Sep 17 00:00:00 2001 From: Quentin Schulz Date: Mon, 31 Jan 2022 17:32:24 +0100 Subject: [PATCH 11/43] clk: rockchip: re-add rational best approximation algorithm to the fractional divider In commit 4e7cf74fa3b2 ("clk: fractional-divider: Export approximation algorithm to the CCF users"), the code handling the rational best approximation algorithm was replaced by a call to the core clk_fractional_divider_general_approximation function which did the same thing back then. However, in commit 82f53f9ee577 ("clk: fractional-divider: Introduce POWER_OF_TWO_PS flag"), this common code was made conditional on CLK_FRAC_DIVIDER_POWER_OF_TWO_PS flag which was not added back to the rockchip clock driver. This broke the ltk050h3146w-a2 MIPI DSI display present on a PX30-based downstream board. Let's add the flag to the fractional divider flags so that the original and intended behavior is brought back to the rockchip clock drivers. Fixes: 82f53f9ee577 ("clk: fractional-divider: Introduce POWER_OF_TWO_PS flag") Cc: stable@vger.kernel.org Cc: Quentin Schulz Signed-off-by: Quentin Schulz Link: https://lore.kernel.org/r/20220131163224.708002-1-quentin.schulz@theobroma-systems.com Signed-off-by: Heiko Stuebner --- drivers/clk/rockchip/clk.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c index b7be7e11b0dfe..bb8a844309bf5 100644 --- a/drivers/clk/rockchip/clk.c +++ b/drivers/clk/rockchip/clk.c @@ -180,6 +180,7 @@ static void rockchip_fractional_approximation(struct clk_hw *hw, unsigned long rate, unsigned long *parent_rate, unsigned long *m, unsigned long *n) { + struct clk_fractional_divider *fd = to_clk_fd(hw); unsigned long p_rate, p_parent_rate; struct clk_hw *p_parent; @@ -190,6 +191,8 @@ static void rockchip_fractional_approximation(struct clk_hw *hw, *parent_rate = p_parent_rate; } + fd->flags |= CLK_FRAC_DIVIDER_POWER_OF_TWO_PS; + clk_fractional_divider_general_approximation(hw, rate, parent_rate, m, n); } From 703da2aed99c7882486defedb78d5e1cc7f47cf7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Neusch=C3=A4fer?= Date: Sat, 5 Feb 2022 11:36:07 +0100 Subject: [PATCH 12/43] clk: nxp: Remove unused variable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GCC warns: > ../drivers/clk/nxp/clk-lpc18xx-cgu.c: In function ‘lpc18xx_pll1_recalc_rate’: > ../drivers/clk/nxp/clk-lpc18xx-cgu.c:460:13: warning: variable ‘stat’ set but not used [-Wunused-but-set-variable] > 460 | u32 stat, ctrl; > | ^~~~ Get rid of the (apparently) useless read from the PLL1_STAT register and the declaration of stat. Reported-by: kernel test robot Fixes: b04e0b8fd5443 ("clk: add lpc18xx cgu clk driver") Signed-off-by: Jonathan Neuschäfer Link: https://lore.kernel.org/r/20220205103613.1216218-2-j.neuschaefer@gmx.net Signed-off-by: Stephen Boyd --- drivers/clk/nxp/clk-lpc18xx-cgu.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/clk/nxp/clk-lpc18xx-cgu.c b/drivers/clk/nxp/clk-lpc18xx-cgu.c index 8b686da5577b3..349eebf69ed93 100644 --- a/drivers/clk/nxp/clk-lpc18xx-cgu.c +++ b/drivers/clk/nxp/clk-lpc18xx-cgu.c @@ -457,9 +457,8 @@ static unsigned long lpc18xx_pll1_recalc_rate(struct clk_hw *hw, struct lpc18xx_pll *pll = to_lpc_pll(hw); u16 msel, nsel, psel; bool direct, fbsel; - u32 stat, ctrl; + u32 ctrl; - stat = readl(pll->reg + LPC18XX_CGU_PLL1_STAT); ctrl = readl(pll->reg + LPC18XX_CGU_PLL1_CTRL); direct = (ctrl & LPC18XX_PLL1_CTRL_DIRECT) ? true : false; From 2eb3b3f0e87084a365321a61c9230fb16d94f1ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Neusch=C3=A4fer?= Date: Sat, 5 Feb 2022 11:36:08 +0100 Subject: [PATCH 13/43] clk: nxp: Declare mux table parameter as const u32 * MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit lpc18xx_fill_parent_names's "id" parameter isn't used for writing, so let's make it const. Signed-off-by: Jonathan Neuschäfer Link: https://lore.kernel.org/r/20220205103613.1216218-3-j.neuschaefer@gmx.net Signed-off-by: Stephen Boyd --- drivers/clk/nxp/clk-lpc18xx-cgu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/nxp/clk-lpc18xx-cgu.c b/drivers/clk/nxp/clk-lpc18xx-cgu.c index 349eebf69ed93..c23ac463ab0fa 100644 --- a/drivers/clk/nxp/clk-lpc18xx-cgu.c +++ b/drivers/clk/nxp/clk-lpc18xx-cgu.c @@ -522,7 +522,7 @@ static struct lpc18xx_cgu_pll_clk lpc18xx_cgu_src_clk_plls[] = { LPC1XX_CGU_CLK_PLL(PLL1, pll1_src_ids, pll1_ops), }; -static void lpc18xx_fill_parent_names(const char **parent, u32 *id, int size) +static void lpc18xx_fill_parent_names(const char **parent, const u32 *id, int size) { int i; From 891b7023010cc0d62d814619b1893745d7613f7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Neusch=C3=A4fer?= Date: Sat, 5 Feb 2022 11:36:09 +0100 Subject: [PATCH 14/43] clk: mux: Declare u32 *table parameter as const MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The elements of the table are never modified in clk-mux.c. To make this clear to clock drivers, declare the parameter as const u32 *table. Signed-off-by: Jonathan Neuschäfer Link: https://lore.kernel.org/r/20220205103613.1216218-4-j.neuschaefer@gmx.net Signed-off-by: Stephen Boyd --- drivers/clk/clk-mux.c | 10 +++++----- include/linux/clk-provider.h | 12 ++++++------ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c index 20582aae7a35f..214045f6e9895 100644 --- a/drivers/clk/clk-mux.c +++ b/drivers/clk/clk-mux.c @@ -40,7 +40,7 @@ static inline void clk_mux_writel(struct clk_mux *mux, u32 val) writel(val, mux->reg); } -int clk_mux_val_to_index(struct clk_hw *hw, u32 *table, unsigned int flags, +int clk_mux_val_to_index(struct clk_hw *hw, const u32 *table, unsigned int flags, unsigned int val) { int num_parents = clk_hw_get_num_parents(hw); @@ -67,7 +67,7 @@ int clk_mux_val_to_index(struct clk_hw *hw, u32 *table, unsigned int flags, } EXPORT_SYMBOL_GPL(clk_mux_val_to_index); -unsigned int clk_mux_index_to_val(u32 *table, unsigned int flags, u8 index) +unsigned int clk_mux_index_to_val(const u32 *table, unsigned int flags, u8 index) { unsigned int val = index; @@ -152,7 +152,7 @@ struct clk_hw *__clk_hw_register_mux(struct device *dev, struct device_node *np, const struct clk_hw **parent_hws, const struct clk_parent_data *parent_data, unsigned long flags, void __iomem *reg, u8 shift, u32 mask, - u8 clk_mux_flags, u32 *table, spinlock_t *lock) + u8 clk_mux_flags, const u32 *table, spinlock_t *lock) { struct clk_mux *mux; struct clk_hw *hw; @@ -218,7 +218,7 @@ struct clk_hw *__devm_clk_hw_register_mux(struct device *dev, struct device_node const struct clk_hw **parent_hws, const struct clk_parent_data *parent_data, unsigned long flags, void __iomem *reg, u8 shift, u32 mask, - u8 clk_mux_flags, u32 *table, spinlock_t *lock) + u8 clk_mux_flags, const u32 *table, spinlock_t *lock) { struct clk_hw **ptr, *hw; @@ -244,7 +244,7 @@ EXPORT_SYMBOL_GPL(__devm_clk_hw_register_mux); struct clk *clk_register_mux_table(struct device *dev, const char *name, const char * const *parent_names, u8 num_parents, unsigned long flags, void __iomem *reg, u8 shift, u32 mask, - u8 clk_mux_flags, u32 *table, spinlock_t *lock) + u8 clk_mux_flags, const u32 *table, spinlock_t *lock) { struct clk_hw *hw; diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index 2faa6f7aa8a87..27be575288747 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -888,7 +888,7 @@ void clk_hw_unregister_divider(struct clk_hw *hw); struct clk_mux { struct clk_hw hw; void __iomem *reg; - u32 *table; + const u32 *table; u32 mask; u8 shift; u8 flags; @@ -913,18 +913,18 @@ struct clk_hw *__clk_hw_register_mux(struct device *dev, struct device_node *np, const struct clk_hw **parent_hws, const struct clk_parent_data *parent_data, unsigned long flags, void __iomem *reg, u8 shift, u32 mask, - u8 clk_mux_flags, u32 *table, spinlock_t *lock); + u8 clk_mux_flags, const u32 *table, spinlock_t *lock); struct clk_hw *__devm_clk_hw_register_mux(struct device *dev, struct device_node *np, const char *name, u8 num_parents, const char * const *parent_names, const struct clk_hw **parent_hws, const struct clk_parent_data *parent_data, unsigned long flags, void __iomem *reg, u8 shift, u32 mask, - u8 clk_mux_flags, u32 *table, spinlock_t *lock); + u8 clk_mux_flags, const u32 *table, spinlock_t *lock); struct clk *clk_register_mux_table(struct device *dev, const char *name, const char * const *parent_names, u8 num_parents, unsigned long flags, void __iomem *reg, u8 shift, u32 mask, - u8 clk_mux_flags, u32 *table, spinlock_t *lock); + u8 clk_mux_flags, const u32 *table, spinlock_t *lock); #define clk_register_mux(dev, name, parent_names, num_parents, flags, reg, \ shift, width, clk_mux_flags, lock) \ @@ -962,9 +962,9 @@ struct clk *clk_register_mux_table(struct device *dev, const char *name, (shift), BIT((width)) - 1, (clk_mux_flags), \ NULL, (lock)) -int clk_mux_val_to_index(struct clk_hw *hw, u32 *table, unsigned int flags, +int clk_mux_val_to_index(struct clk_hw *hw, const u32 *table, unsigned int flags, unsigned int val); -unsigned int clk_mux_index_to_val(u32 *table, unsigned int flags, u8 index); +unsigned int clk_mux_index_to_val(const u32 *table, unsigned int flags, u8 index); void clk_unregister_mux(struct clk *clk); void clk_hw_unregister_mux(struct clk_hw *hw); From 08edf70457b375d2f09aaee5ba07777046293d93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Neusch=C3=A4fer?= Date: Sat, 5 Feb 2022 11:36:10 +0100 Subject: [PATCH 15/43] clk: hisilicon: Remove unnecessary cast of mux table to u32 * MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that clk_register_mux_table takes a const u32 *, we don't need the cast anymore. Signed-off-by: Jonathan Neuschäfer Link: https://lore.kernel.org/r/20220205103613.1216218-5-j.neuschaefer@gmx.net Signed-off-by: Stephen Boyd --- drivers/clk/hisilicon/clk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/hisilicon/clk.c b/drivers/clk/hisilicon/clk.c index 9361fba7cd4cf..54d9fdc935990 100644 --- a/drivers/clk/hisilicon/clk.c +++ b/drivers/clk/hisilicon/clk.c @@ -162,7 +162,7 @@ int hisi_clk_register_mux(const struct hisi_mux_clock *clks, clks[i].num_parents, clks[i].flags, base + clks[i].offset, clks[i].shift, mask, clks[i].mux_flags, - (u32 *)clks[i].table, &hisi_clk_lock); + clks[i].table, &hisi_clk_lock); if (IS_ERR(clk)) { pr_err("%s: failed to register clock %s\n", __func__, clks[i].name); From 8a8e164b1de0edaf94afd27a74b2e06ef1117060 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Neusch=C3=A4fer?= Date: Sat, 5 Feb 2022 11:36:11 +0100 Subject: [PATCH 16/43] clk: mmp: Declare mux tables as const u32[] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that clk_register_mux_table takes a const u32 *, we can declare the mux tables as const u32[]. Signed-off-by: Jonathan Neuschäfer Link: https://lore.kernel.org/r/20220205103613.1216218-6-j.neuschaefer@gmx.net Signed-off-by: Stephen Boyd --- drivers/clk/mmp/clk-of-mmp2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/mmp/clk-of-mmp2.c b/drivers/clk/mmp/clk-of-mmp2.c index 0839fb2049e94..50a780274ba0c 100644 --- a/drivers/clk/mmp/clk-of-mmp2.c +++ b/drivers/clk/mmp/clk-of-mmp2.c @@ -317,9 +317,9 @@ static const char * const ccic_parent_names[] = {"pll1_2", "pll1_16", "vctcxo"}; static DEFINE_SPINLOCK(gpu_lock); static const char * const mmp2_gpu_gc_parent_names[] = {"pll1_2", "pll1_3", "pll2_2", "pll2_3", "pll2", "usb_pll"}; -static u32 mmp2_gpu_gc_parent_table[] = { 0x0000, 0x0040, 0x0080, 0x00c0, 0x1000, 0x1040 }; +static const u32 mmp2_gpu_gc_parent_table[] = { 0x0000, 0x0040, 0x0080, 0x00c0, 0x1000, 0x1040 }; static const char * const mmp2_gpu_bus_parent_names[] = {"pll1_4", "pll2", "pll2_2", "usb_pll"}; -static u32 mmp2_gpu_bus_parent_table[] = { 0x0000, 0x0020, 0x0030, 0x4020 }; +static const u32 mmp2_gpu_bus_parent_table[] = { 0x0000, 0x0020, 0x0030, 0x4020 }; static const char * const mmp3_gpu_bus_parent_names[] = {"pll1_4", "pll1_6", "pll1_2", "pll2_2"}; static const char * const mmp3_gpu_gc_parent_names[] = {"pll1", "pll2", "pll1_p", "pll2_p"}; From eac03cb010a9f5df37550b6082a6a8ba5e8b84dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Neusch=C3=A4fer?= Date: Sat, 5 Feb 2022 11:36:12 +0100 Subject: [PATCH 17/43] clk: qcom: Declare mux table as const u32[] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that clk_register_mux_table takes a const u32 *, we can declare the mux tables as const u32[]. Signed-off-by: Jonathan Neuschäfer Link: https://lore.kernel.org/r/20220205103613.1216218-7-j.neuschaefer@gmx.net Signed-off-by: Stephen Boyd --- drivers/clk/qcom/kpss-xcc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/qcom/kpss-xcc.c b/drivers/clk/qcom/kpss-xcc.c index 4fec1f9142b82..88d4b33ac0cc3 100644 --- a/drivers/clk/qcom/kpss-xcc.c +++ b/drivers/clk/qcom/kpss-xcc.c @@ -17,7 +17,7 @@ static const char *aux_parents[] = { "pxo", }; -static unsigned int aux_parent_map[] = { +static const u32 aux_parent_map[] = { 3, 0, }; From fa6ffe65cce5e596a411f6a878f9ad6588f3b8a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Neusch=C3=A4fer?= Date: Sat, 5 Feb 2022 11:36:13 +0100 Subject: [PATCH 18/43] clk: pistachio: Declare mux table as const u32[] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that clk_register_mux_table takes a const u32 *, we can declare the mux table as const u32[]. Signed-off-by: Jonathan Neuschäfer Link: https://lore.kernel.org/r/20220205103613.1216218-8-j.neuschaefer@gmx.net Signed-off-by: Stephen Boyd --- drivers/clk/pistachio/clk-pistachio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/pistachio/clk-pistachio.c b/drivers/clk/pistachio/clk-pistachio.c index 76f492c7e917e..2a6d583237dc7 100644 --- a/drivers/clk/pistachio/clk-pistachio.c +++ b/drivers/clk/pistachio/clk-pistachio.c @@ -154,7 +154,7 @@ static struct pistachio_pll pistachio_plls[] __initdata = { PNAME(mux_debug) = { "mips_pll_mux", "rpu_v_pll_mux", "rpu_l_pll_mux", "sys_pll_mux", "wifi_pll_mux", "bt_pll_mux" }; -static u32 mux_debug_idx[] = { 0x0, 0x1, 0x2, 0x4, 0x8, 0x10 }; +static const u32 mux_debug_idx[] = { 0x0, 0x1, 0x2, 0x4, 0x8, 0x10 }; static unsigned int pistachio_critical_clks_core[] __initdata = { CLK_MIPS From 75061a6ff49ba3482c6319ded0c26e6a526b0967 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Thu, 17 Feb 2022 14:05:53 -0800 Subject: [PATCH 19/43] clk: Mark 'all_lists' as const This list array doesn't change at runtime. Mark it const to move to RO memory. Signed-off-by: Stephen Boyd Link: https://lore.kernel.org/r/20220217220554.2711696-2-sboyd@kernel.org --- drivers/clk/clk.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 8de6a22498e70..16384e9437f59 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -37,7 +37,7 @@ static HLIST_HEAD(clk_root_list); static HLIST_HEAD(clk_orphan_list); static LIST_HEAD(clk_notifier_list); -static struct hlist_head *all_lists[] = { +static const struct hlist_head *all_lists[] = { &clk_root_list, &clk_orphan_list, NULL, @@ -4095,7 +4095,7 @@ static void clk_core_evict_parent_cache_subtree(struct clk_core *root, /* Remove this clk from all parent caches */ static void clk_core_evict_parent_cache(struct clk_core *core) { - struct hlist_head **lists; + const struct hlist_head **lists; struct clk_core *root; lockdep_assert_held(&prepare_lock); From 8df64183b8b71c751cf81c3d7655227fbea837b2 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Thu, 17 Feb 2022 14:05:54 -0800 Subject: [PATCH 20/43] clk: Mark clk_core_evict_parent_cache_subtree() 'target' const Clarify that the 'target' clk isn't being modified, instead it's being searched for. Mark it const so the function can't modify it. Signed-off-by: Stephen Boyd Link: https://lore.kernel.org/r/20220217220554.2711696-3-sboyd@kernel.org --- drivers/clk/clk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 16384e9437f59..d15997ea3930e 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -4079,7 +4079,7 @@ static const struct clk_ops clk_nodrv_ops = { }; static void clk_core_evict_parent_cache_subtree(struct clk_core *root, - struct clk_core *target) + const struct clk_core *target) { int i; struct clk_core *child; From eccac77ede3946c90143447cdc785dc16aec4b24 Mon Sep 17 00:00:00 2001 From: Abel Vesa Date: Thu, 27 Jan 2022 16:10:52 +0200 Subject: [PATCH 21/43] clk: imx7d: Remove audio_mclk_root_clk The audio_mclk_root_clk was added as a gate with the CCGR121 (0x4790), but according to the reference manual, there is no such gate. The CCGR121 belongs to ECSPI2 and it is not shared. Fixes: 8f6d8094b215b57 ("ARM: imx: add imx7d clk tree support") Reported-by: David Wolfe Signed-off-by: Abel Vesa Reviewed-by: Peng Fan Link: https://lore.kernel.org/r/20220127141052.1900174-2-abel.vesa@nxp.com --- drivers/clk/imx/clk-imx7d.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/clk/imx/clk-imx7d.c b/drivers/clk/imx/clk-imx7d.c index c4e0f1c07192f..3f6fd7ef2a68f 100644 --- a/drivers/clk/imx/clk-imx7d.c +++ b/drivers/clk/imx/clk-imx7d.c @@ -849,7 +849,6 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node) hws[IMX7D_WDOG4_ROOT_CLK] = imx_clk_hw_gate4("wdog4_root_clk", "wdog_post_div", base + 0x49f0, 0); hws[IMX7D_KPP_ROOT_CLK] = imx_clk_hw_gate4("kpp_root_clk", "ipg_root_clk", base + 0x4aa0, 0); hws[IMX7D_CSI_MCLK_ROOT_CLK] = imx_clk_hw_gate4("csi_mclk_root_clk", "csi_mclk_post_div", base + 0x4490, 0); - hws[IMX7D_AUDIO_MCLK_ROOT_CLK] = imx_clk_hw_gate4("audio_mclk_root_clk", "audio_mclk_post_div", base + 0x4790, 0); hws[IMX7D_WRCLK_ROOT_CLK] = imx_clk_hw_gate4("wrclk_root_clk", "wrclk_post_div", base + 0x47a0, 0); hws[IMX7D_USB_CTRL_CLK] = imx_clk_hw_gate4("usb_ctrl_clk", "ahb_root_clk", base + 0x4680, 0); hws[IMX7D_USB_PHY1_CLK] = imx_clk_hw_gate4("usb_phy1_clk", "pll_usb1_main_clk", base + 0x46a0, 0); From 8cf0e06a72306d30e1a01b2b68ab362036757d32 Mon Sep 17 00:00:00 2001 From: Abel Vesa Date: Tue, 22 Feb 2022 10:21:40 +0200 Subject: [PATCH 22/43] dt-bindings: fsl: scu: add imx8dxl scu clock support Add imx8dxl scu clock support. Signed-off-by: Abel Vesa Acked-by: Rob Herring Acked-by: Stephen Boyd Link: https://lore.kernel.org/r/20220222082140.2073629-1-abel.vesa@nxp.com --- Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt b/Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt index fd0061712443c..a87ec15e28d2b 100644 --- a/Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt +++ b/Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt @@ -86,6 +86,7 @@ This binding uses the common clock binding[1]. Required properties: - compatible: Should be one of: + "fsl,imx8dxl-clk" "fsl,imx8qm-clk" "fsl,imx8qxp-clk" followed by "fsl,scu-clk" From 135efc3a76d127691afaf1864e4ab627bf09d53d Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 28 Feb 2022 10:50:14 +0300 Subject: [PATCH 23/43] clk: imx: off by one in imx_lpcg_parse_clks_from_dt() The > needs to be >= to prevent an off by one access. Fixes: d5f1e6a2bb61 ("clk: imx: imx8qxp-lpcg: add parsing clocks from device tree") Reported-by: kernel test robot Signed-off-by: Dan Carpenter Reviewed-by: Abel Vesa Link: https://lore.kernel.org/r/20220228075014.GD13685@kili Signed-off-by: Abel Vesa --- drivers/clk/imx/clk-imx8qxp-lpcg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/imx/clk-imx8qxp-lpcg.c b/drivers/clk/imx/clk-imx8qxp-lpcg.c index b23758083ce52..5e31a6a24b3a3 100644 --- a/drivers/clk/imx/clk-imx8qxp-lpcg.c +++ b/drivers/clk/imx/clk-imx8qxp-lpcg.c @@ -248,7 +248,7 @@ static int imx_lpcg_parse_clks_from_dt(struct platform_device *pdev, for (i = 0; i < count; i++) { idx = bit_offset[i] / 4; - if (idx > IMX_LPCG_MAX_CLKS) { + if (idx >= IMX_LPCG_MAX_CLKS) { dev_warn(&pdev->dev, "invalid bit offset of clock %d\n", i); ret = -EINVAL; From 245830990da69abc913b80af0b43c5cbeb902c5d Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Mon, 28 Feb 2022 10:09:04 +0800 Subject: [PATCH 24/43] dt-bindings: clock: Add imx93 clock support Add the clock dt-binding file for i.MX93. Reviewed-by: Abel Vesa Reviewed-by: Rob Herring Reviewed-by: Stephen Boyd Signed-off-by: Peng Fan Link: https://lore.kernel.org/r/20220228020908.2810346-2-peng.fan@oss.nxp.com Signed-off-by: Abel Vesa --- .../bindings/clock/imx93-clock.yaml | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/imx93-clock.yaml diff --git a/Documentation/devicetree/bindings/clock/imx93-clock.yaml b/Documentation/devicetree/bindings/clock/imx93-clock.yaml new file mode 100644 index 0000000000000..21a06194e4a3a --- /dev/null +++ b/Documentation/devicetree/bindings/clock/imx93-clock.yaml @@ -0,0 +1,62 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/imx93-clock.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: NXP i.MX93 Clock Control Module Binding + +maintainers: + - Peng Fan + +description: | + i.MX93 clock control module is an integrated clock controller, which + includes clock generator, clock gate and supplies to all modules. + +properties: + compatible: + enum: + - fsl,imx93-ccm + + reg: + maxItems: 1 + + clocks: + description: + specify the external clocks used by the CCM module. + items: + - description: 32k osc + - description: 24m osc + - description: ext1 clock input + + clock-names: + description: + specify the external clocks names used by the CCM module. + items: + - const: osc_32k + - const: osc_24m + - const: clk_ext1 + + '#clock-cells': + const: 1 + description: + See include/dt-bindings/clock/imx93-clock.h for the full list of + i.MX93 clock IDs. + +required: + - compatible + - reg + - '#clock-cells' + +additionalProperties: false + +examples: + # Clock Control Module node: + - | + clock-controller@44450000 { + compatible = "fsl,imx93-ccm"; + reg = <0x44450000 0x10000>; + #clock-cells = <1>; + }; + +... From 9a45081bb1fd5d15253994fcdbed652a56174d5e Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Mon, 28 Feb 2022 10:09:05 +0800 Subject: [PATCH 25/43] dt-bindings: clock: add i.MX93 clock definition Add i.MX93 clock definition Reviewed-by: Abel Vesa Acked-by: Krzysztof Kozlowski Acked-by: Rob Herring Reviewed-by: Stephen Boyd Signed-off-by: Peng Fan Link: https://lore.kernel.org/r/20220228020908.2810346-3-peng.fan@oss.nxp.com Signed-off-by: Abel Vesa --- include/dt-bindings/clock/imx93-clock.h | 201 ++++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 include/dt-bindings/clock/imx93-clock.h diff --git a/include/dt-bindings/clock/imx93-clock.h b/include/dt-bindings/clock/imx93-clock.h new file mode 100644 index 0000000000000..21fda9c5cb5e5 --- /dev/null +++ b/include/dt-bindings/clock/imx93-clock.h @@ -0,0 +1,201 @@ +/* SPDX-License-Identifier: GPL-2.0+ OR MIT */ +/* + * Copyright 2022 NXP + */ + +#ifndef __DT_BINDINGS_CLOCK_IMX93_CLK_H +#define __DT_BINDINGS_CLOCK_IMX93_CLK_H + +#define IMX93_CLK_DUMMY 0 +#define IMX93_CLK_24M 1 +#define IMX93_CLK_EXT1 2 +#define IMX93_CLK_SYS_PLL_PFD0 3 +#define IMX93_CLK_SYS_PLL_PFD0_DIV2 4 +#define IMX93_CLK_SYS_PLL_PFD1 5 +#define IMX93_CLK_SYS_PLL_PFD1_DIV2 6 +#define IMX93_CLK_SYS_PLL_PFD2 7 +#define IMX93_CLK_SYS_PLL_PFD2_DIV2 8 +#define IMX93_CLK_AUDIO_PLL 9 +#define IMX93_CLK_VIDEO_PLL 10 +#define IMX93_CLK_A55_PERIPH 11 +#define IMX93_CLK_A55_MTR_BUS 12 +#define IMX93_CLK_A55 13 +#define IMX93_CLK_M33 14 +#define IMX93_CLK_BUS_WAKEUP 15 +#define IMX93_CLK_BUS_AON 16 +#define IMX93_CLK_WAKEUP_AXI 17 +#define IMX93_CLK_SWO_TRACE 18 +#define IMX93_CLK_M33_SYSTICK 19 +#define IMX93_CLK_FLEXIO1 20 +#define IMX93_CLK_FLEXIO2 21 +#define IMX93_CLK_LPIT1 22 +#define IMX93_CLK_LPIT2 23 +#define IMX93_CLK_LPTMR1 24 +#define IMX93_CLK_LPTMR2 25 +#define IMX93_CLK_TPM1 26 +#define IMX93_CLK_TPM2 27 +#define IMX93_CLK_TPM3 28 +#define IMX93_CLK_TPM4 29 +#define IMX93_CLK_TPM5 30 +#define IMX93_CLK_TPM6 31 +#define IMX93_CLK_FLEXSPI1 32 +#define IMX93_CLK_CAN1 33 +#define IMX93_CLK_CAN2 34 +#define IMX93_CLK_LPUART1 35 +#define IMX93_CLK_LPUART2 36 +#define IMX93_CLK_LPUART3 37 +#define IMX93_CLK_LPUART4 38 +#define IMX93_CLK_LPUART5 39 +#define IMX93_CLK_LPUART6 40 +#define IMX93_CLK_LPUART7 41 +#define IMX93_CLK_LPUART8 42 +#define IMX93_CLK_LPI2C1 43 +#define IMX93_CLK_LPI2C2 44 +#define IMX93_CLK_LPI2C3 45 +#define IMX93_CLK_LPI2C4 46 +#define IMX93_CLK_LPI2C5 47 +#define IMX93_CLK_LPI2C6 48 +#define IMX93_CLK_LPI2C7 49 +#define IMX93_CLK_LPI2C8 50 +#define IMX93_CLK_LPSPI1 51 +#define IMX93_CLK_LPSPI2 52 +#define IMX93_CLK_LPSPI3 53 +#define IMX93_CLK_LPSPI4 54 +#define IMX93_CLK_LPSPI5 55 +#define IMX93_CLK_LPSPI6 56 +#define IMX93_CLK_LPSPI7 57 +#define IMX93_CLK_LPSPI8 58 +#define IMX93_CLK_I3C1 59 +#define IMX93_CLK_I3C2 60 +#define IMX93_CLK_USDHC1 61 +#define IMX93_CLK_USDHC2 62 +#define IMX93_CLK_USDHC3 63 +#define IMX93_CLK_SAI1 64 +#define IMX93_CLK_SAI2 65 +#define IMX93_CLK_SAI3 66 +#define IMX93_CLK_CCM_CKO1 67 +#define IMX93_CLK_CCM_CKO2 68 +#define IMX93_CLK_CCM_CKO3 69 +#define IMX93_CLK_CCM_CKO4 70 +#define IMX93_CLK_HSIO 71 +#define IMX93_CLK_HSIO_USB_TEST_60M 72 +#define IMX93_CLK_HSIO_ACSCAN_80M 73 +#define IMX93_CLK_HSIO_ACSCAN_480M 74 +#define IMX93_CLK_ML_APB 75 +#define IMX93_CLK_ML 76 +#define IMX93_CLK_MEDIA_AXI 77 +#define IMX93_CLK_MEDIA_APB 78 +#define IMX93_CLK_MEDIA_LDB 79 +#define IMX93_CLK_MEDIA_DISP_PIX 80 +#define IMX93_CLK_CAM_PIX 81 +#define IMX93_CLK_MIPI_TEST_BYTE 82 +#define IMX93_CLK_MIPI_PHY_CFG 83 +#define IMX93_CLK_ADC 84 +#define IMX93_CLK_PDM 85 +#define IMX93_CLK_TSTMR1 86 +#define IMX93_CLK_TSTMR2 87 +#define IMX93_CLK_MQS1 88 +#define IMX93_CLK_MQS2 89 +#define IMX93_CLK_AUDIO_XCVR 90 +#define IMX93_CLK_SPDIF 91 +#define IMX93_CLK_ENET 92 +#define IMX93_CLK_ENET_TIMER1 93 +#define IMX93_CLK_ENET_TIMER2 94 +#define IMX93_CLK_ENET_REF 95 +#define IMX93_CLK_ENET_REF_PHY 96 +#define IMX93_CLK_I3C1_SLOW 97 +#define IMX93_CLK_I3C2_SLOW 98 +#define IMX93_CLK_USB_PHY_BURUNIN 99 +#define IMX93_CLK_PAL_CAME_SCAN 100 +#define IMX93_CLK_A55_GATE 101 +#define IMX93_CLK_CM33_GATE 102 +#define IMX93_CLK_ADC1_GATE 103 +#define IMX93_CLK_WDOG1_GATE 104 +#define IMX93_CLK_WDOG2_GATE 105 +#define IMX93_CLK_WDOG3_GATE 106 +#define IMX93_CLK_WDOG4_GATE 107 +#define IMX93_CLK_WDOG5_GATE 108 +#define IMX93_CLK_SEMA1_GATE 109 +#define IMX93_CLK_SEMA2_GATE 110 +#define IMX93_CLK_MU_A_GATE 111 +#define IMX93_CLK_MU_B_GATE 112 +#define IMX93_CLK_EDMA1_GATE 113 +#define IMX93_CLK_EDMA2_GATE 114 +#define IMX93_CLK_FLEXSPI1_GATE 115 +#define IMX93_CLK_GPIO1_GATE 116 +#define IMX93_CLK_GPIO2_GATE 117 +#define IMX93_CLK_GPIO3_GATE 118 +#define IMX93_CLK_GPIO4_GATE 119 +#define IMX93_CLK_FLEXIO1_GATE 120 +#define IMX93_CLK_FLEXIO2_GATE 121 +#define IMX93_CLK_LPIT1_GATE 122 +#define IMX93_CLK_LPIT2_GATE 123 +#define IMX93_CLK_LPTMR1_GATE 124 +#define IMX93_CLK_LPTMR2_GATE 125 +#define IMX93_CLK_TPM1_GATE 126 +#define IMX93_CLK_TPM2_GATE 127 +#define IMX93_CLK_TPM3_GATE 128 +#define IMX93_CLK_TPM4_GATE 129 +#define IMX93_CLK_TPM5_GATE 130 +#define IMX93_CLK_TPM6_GATE 131 +#define IMX93_CLK_CAN1_GATE 132 +#define IMX93_CLK_CAN2_GATE 133 +#define IMX93_CLK_LPUART1_GATE 134 +#define IMX93_CLK_LPUART2_GATE 135 +#define IMX93_CLK_LPUART3_GATE 136 +#define IMX93_CLK_LPUART4_GATE 137 +#define IMX93_CLK_LPUART5_GATE 138 +#define IMX93_CLK_LPUART6_GATE 139 +#define IMX93_CLK_LPUART7_GATE 140 +#define IMX93_CLK_LPUART8_GATE 141 +#define IMX93_CLK_LPI2C1_GATE 142 +#define IMX93_CLK_LPI2C2_GATE 143 +#define IMX93_CLK_LPI2C3_GATE 144 +#define IMX93_CLK_LPI2C4_GATE 145 +#define IMX93_CLK_LPI2C5_GATE 146 +#define IMX93_CLK_LPI2C6_GATE 147 +#define IMX93_CLK_LPI2C7_GATE 148 +#define IMX93_CLK_LPI2C8_GATE 149 +#define IMX93_CLK_LPSPI1_GATE 150 +#define IMX93_CLK_LPSPI2_GATE 151 +#define IMX93_CLK_LPSPI3_GATE 152 +#define IMX93_CLK_LPSPI4_GATE 153 +#define IMX93_CLK_LPSPI5_GATE 154 +#define IMX93_CLK_LPSPI6_GATE 155 +#define IMX93_CLK_LPSPI7_GATE 156 +#define IMX93_CLK_LPSPI8_GATE 157 +#define IMX93_CLK_I3C1_GATE 158 +#define IMX93_CLK_I3C2_GATE 159 +#define IMX93_CLK_USDHC1_GATE 160 +#define IMX93_CLK_USDHC2_GATE 161 +#define IMX93_CLK_USDHC3_GATE 162 +#define IMX93_CLK_SAI1_GATE 163 +#define IMX93_CLK_SAI2_GATE 164 +#define IMX93_CLK_SAI3_GATE 165 +#define IMX93_CLK_MIPI_CSI_GATE 166 +#define IMX93_CLK_MIPI_DSI_GATE 167 +#define IMX93_CLK_LVDS_GATE 168 +#define IMX93_CLK_LCDIF_GATE 169 +#define IMX93_CLK_PXP_GATE 170 +#define IMX93_CLK_ISI_GATE 171 +#define IMX93_CLK_NIC_MEDIA_GATE 172 +#define IMX93_CLK_USB_CONTROLLER_GATE 173 +#define IMX93_CLK_USB_TEST_60M_GATE 174 +#define IMX93_CLK_HSIO_TROUT_24M_GATE 175 +#define IMX93_CLK_PDM_GATE 176 +#define IMX93_CLK_MQS1_GATE 177 +#define IMX93_CLK_MQS2_GATE 178 +#define IMX93_CLK_AUD_XCVR_GATE 179 +#define IMX93_CLK_SPDIF_GATE 180 +#define IMX93_CLK_HSIO_32K_GATE 181 +#define IMX93_CLK_ENET1_GATE 182 +#define IMX93_CLK_ENET_QOS_GATE 183 +#define IMX93_CLK_SYS_CNT_GATE 184 +#define IMX93_CLK_TSTMR1_GATE 185 +#define IMX93_CLK_TSTMR2_GATE 186 +#define IMX93_CLK_TMC_GATE 187 +#define IMX93_CLK_PMRO_GATE 188 +#define IMX93_CLK_32K 189 +#define IMX93_CLK_END 190 + +#endif From 11994196178d9038d659c2b9468d7c219b708a37 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Mon, 28 Feb 2022 10:09:06 +0800 Subject: [PATCH 26/43] clk: imx: add i.MX93 composite clk i.MX93 CCM ROOT clock has a mux, gate and divider in one register, here is to combine all these into one composite clk and simplify clk tree. i.MX93 CCM is a new IP compared with i.MX8M, so introduce a new file. Reviewed-by: Abel Vesa Reviewed-by: Stephen Boyd Signed-off-by: Peng Fan Link: https://lore.kernel.org/r/20220228020908.2810346-4-peng.fan@oss.nxp.com Signed-off-by: Abel Vesa --- drivers/clk/imx/Makefile | 1 + drivers/clk/imx/clk-composite-93.c | 93 ++++++++++++++++++++++++++++++ drivers/clk/imx/clk.h | 9 +++ 3 files changed, 103 insertions(+) create mode 100644 drivers/clk/imx/clk-composite-93.c diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile index aa8f5204d7e10..36c04922d7893 100644 --- a/drivers/clk/imx/Makefile +++ b/drivers/clk/imx/Makefile @@ -4,6 +4,7 @@ mxc-clk-objs += clk.o mxc-clk-objs += clk-busy.o mxc-clk-objs += clk-composite-7ulp.o mxc-clk-objs += clk-composite-8m.o +mxc-clk-objs += clk-composite-93.o mxc-clk-objs += clk-cpu.o mxc-clk-objs += clk-divider-gate.o mxc-clk-objs += clk-fixup-div.o diff --git a/drivers/clk/imx/clk-composite-93.c b/drivers/clk/imx/clk-composite-93.c new file mode 100644 index 0000000000000..b44619aa5ca5e --- /dev/null +++ b/drivers/clk/imx/clk-composite-93.c @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2021 NXP + * + * Peng Fan + */ + +#include +#include +#include +#include +#include + +#include "clk.h" + +#define CCM_DIV_SHIFT 0 +#define CCM_DIV_WIDTH 8 +#define CCM_MUX_SHIFT 8 +#define CCM_MUX_MASK 3 +#define CCM_OFF_SHIFT 24 + +#define AUTHEN_OFFSET 0x30 +#define TZ_NS_SHIFT 9 +#define TZ_NS_MASK BIT(9) + +struct clk_hw *imx93_clk_composite_flags(const char *name, const char * const *parent_names, + int num_parents, void __iomem *reg, + unsigned long flags) +{ + struct clk_hw *hw = ERR_PTR(-ENOMEM), *mux_hw; + struct clk_hw *div_hw, *gate_hw; + struct clk_divider *div = NULL; + struct clk_gate *gate = NULL; + struct clk_mux *mux = NULL; + bool clk_ro = false; + + mux = kzalloc(sizeof(*mux), GFP_KERNEL); + if (!mux) + goto fail; + + mux_hw = &mux->hw; + mux->reg = reg; + mux->shift = CCM_MUX_SHIFT; + mux->mask = CCM_MUX_MASK; + mux->lock = &imx_ccm_lock; + + div = kzalloc(sizeof(*div), GFP_KERNEL); + if (!div) + goto fail; + + div_hw = &div->hw; + div->reg = reg; + div->shift = CCM_DIV_SHIFT; + div->width = CCM_DIV_WIDTH; + div->lock = &imx_ccm_lock; + div->flags = CLK_DIVIDER_ROUND_CLOSEST; + + if (!(readl(reg + AUTHEN_OFFSET) & TZ_NS_MASK)) + clk_ro = true; + + if (clk_ro) { + hw = clk_hw_register_composite(NULL, name, parent_names, num_parents, + mux_hw, &clk_mux_ro_ops, div_hw, + &clk_divider_ro_ops, NULL, NULL, flags); + } else { + gate = kzalloc(sizeof(*gate), GFP_KERNEL); + if (!gate) + goto fail; + + gate_hw = &gate->hw; + gate->reg = reg; + gate->bit_idx = CCM_OFF_SHIFT; + gate->lock = &imx_ccm_lock; + gate->flags = CLK_GATE_SET_TO_DISABLE; + + hw = clk_hw_register_composite(NULL, name, parent_names, num_parents, + mux_hw, &clk_mux_ops, div_hw, + &clk_divider_ops, gate_hw, + &clk_gate_ops, flags | CLK_SET_RATE_NO_REPARENT); + } + + if (IS_ERR(hw)) + goto fail; + + return hw; + +fail: + kfree(gate); + kfree(div); + kfree(mux); + return ERR_CAST(hw); +} +EXPORT_SYMBOL_GPL(imx93_clk_composite_flags); diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h index 7d220a01de1f8..63eb7c53b123c 100644 --- a/drivers/clk/imx/clk.h +++ b/drivers/clk/imx/clk.h @@ -419,6 +419,15 @@ struct clk_hw *__imx8m_clk_hw_composite(const char *name, IMX_COMPOSITE_FW_MANAGED, \ IMX_COMPOSITE_CLK_FLAGS_CRITICAL_GET_RATE_NO_CACHE) +struct clk_hw *imx93_clk_composite_flags(const char *name, + const char * const *parent_names, + int num_parents, + void __iomem *reg, + unsigned long flags); +#define imx93_clk_composite(name, parent_names, num_parents, reg) \ + imx93_clk_composite_flags(name, parent_names, num_parents, reg, \ + CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE) + struct clk_hw *imx_clk_hw_divider_gate(const char *name, const char *parent_name, unsigned long flags, void __iomem *reg, u8 shift, u8 width, u8 clk_divider_flags, const struct clk_div_table *table, From 1b26cb8a77a49d8f8b5b723ef1db4cd6d2434dfc Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Mon, 28 Feb 2022 10:09:07 +0800 Subject: [PATCH 27/43] clk: imx: support fracn gppll This PLL module is a Fractional-N synthesizer, supporting 30-bit numerator and denominator. Numerator is a signed number. It has feature to adjust fractional portion of feedback divider dynamically. This fracn gppll is used in i.MX93. Reviewed-by: Abel Vesa Reviewed-by: Sascha Hauer Signed-off-by: Peng Fan Link: https://lore.kernel.org/r/20220228020908.2810346-5-peng.fan@oss.nxp.com Signed-off-by: Abel Vesa --- drivers/clk/imx/Makefile | 1 + drivers/clk/imx/clk-fracn-gppll.c | 323 ++++++++++++++++++++++++++++++ drivers/clk/imx/clk.h | 21 ++ 3 files changed, 345 insertions(+) create mode 100644 drivers/clk/imx/clk-fracn-gppll.c diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile index 36c04922d7893..60c8a4bb75744 100644 --- a/drivers/clk/imx/Makefile +++ b/drivers/clk/imx/Makefile @@ -5,6 +5,7 @@ mxc-clk-objs += clk-busy.o mxc-clk-objs += clk-composite-7ulp.o mxc-clk-objs += clk-composite-8m.o mxc-clk-objs += clk-composite-93.o +mxc-clk-objs += clk-fracn-gppll.o mxc-clk-objs += clk-cpu.o mxc-clk-objs += clk-divider-gate.o mxc-clk-objs += clk-fixup-div.o diff --git a/drivers/clk/imx/clk-fracn-gppll.c b/drivers/clk/imx/clk-fracn-gppll.c new file mode 100644 index 0000000000000..71c102d950ab0 --- /dev/null +++ b/drivers/clk/imx/clk-fracn-gppll.c @@ -0,0 +1,323 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2021 NXP + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "clk.h" + +#define PLL_CTRL 0x0 +#define CLKMUX_BYPASS BIT(2) +#define CLKMUX_EN BIT(1) +#define POWERUP_MASK BIT(0) + +#define PLL_ANA_PRG 0x10 +#define PLL_SPREAD_SPECTRUM 0x30 + +#define PLL_NUMERATOR 0x40 +#define PLL_MFN_MASK GENMASK(31, 2) + +#define PLL_DENOMINATOR 0x50 +#define PLL_MFD_MASK GENMASK(29, 0) + +#define PLL_DIV 0x60 +#define PLL_MFI_MASK GENMASK(24, 16) +#define PLL_RDIV_MASK GENMASK(15, 13) +#define PLL_ODIV_MASK GENMASK(7, 0) + +#define PLL_DFS_CTRL(x) (0x70 + (x) * 0x10) + +#define PLL_STATUS 0xF0 +#define LOCK_STATUS BIT(0) + +#define DFS_STATUS 0xF4 + +#define LOCK_TIMEOUT_US 200 + +#define PLL_FRACN_GP(_rate, _mfi, _mfn, _mfd, _rdiv, _odiv) \ + { \ + .rate = (_rate), \ + .mfi = (_mfi), \ + .mfn = (_mfn), \ + .mfd = (_mfd), \ + .rdiv = (_rdiv), \ + .odiv = (_odiv), \ + } + +struct clk_fracn_gppll { + struct clk_hw hw; + void __iomem *base; + const struct imx_fracn_gppll_rate_table *rate_table; + int rate_count; +}; + +/* + * Fvco = Fref * (MFI + MFN / MFD) + * Fout = Fvco / (rdiv * odiv) + */ +static const struct imx_fracn_gppll_rate_table fracn_tbl[] = { + PLL_FRACN_GP(650000000U, 81, 0, 0, 0, 3), + PLL_FRACN_GP(594000000U, 198, 0, 0, 0, 8), + PLL_FRACN_GP(560000000U, 70, 0, 0, 0, 3), + PLL_FRACN_GP(400000000U, 50, 0, 0, 0, 3), + PLL_FRACN_GP(393216000U, 81, 92, 100, 0, 5) +}; + +struct imx_fracn_gppll_clk imx_fracn_gppll = { + .rate_table = fracn_tbl, + .rate_count = ARRAY_SIZE(fracn_tbl), +}; +EXPORT_SYMBOL_GPL(imx_fracn_gppll); + +static inline struct clk_fracn_gppll *to_clk_fracn_gppll(struct clk_hw *hw) +{ + return container_of(hw, struct clk_fracn_gppll, hw); +} + +static const struct imx_fracn_gppll_rate_table * +imx_get_pll_settings(struct clk_fracn_gppll *pll, unsigned long rate) +{ + const struct imx_fracn_gppll_rate_table *rate_table = pll->rate_table; + int i; + + for (i = 0; i < pll->rate_count; i++) + if (rate == rate_table[i].rate) + return &rate_table[i]; + + return NULL; +} + +static long clk_fracn_gppll_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *prate) +{ + struct clk_fracn_gppll *pll = to_clk_fracn_gppll(hw); + const struct imx_fracn_gppll_rate_table *rate_table = pll->rate_table; + int i; + + /* Assuming rate_table is in descending order */ + for (i = 0; i < pll->rate_count; i++) + if (rate >= rate_table[i].rate) + return rate_table[i].rate; + + /* return minimum supported value */ + return rate_table[pll->rate_count - 1].rate; +} + +static unsigned long clk_fracn_gppll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) +{ + struct clk_fracn_gppll *pll = to_clk_fracn_gppll(hw); + const struct imx_fracn_gppll_rate_table *rate_table = pll->rate_table; + u32 pll_numerator, pll_denominator, pll_div; + u32 mfi, mfn, mfd, rdiv, odiv; + u64 fvco = parent_rate; + long rate = 0; + int i; + + pll_numerator = readl_relaxed(pll->base + PLL_NUMERATOR); + mfn = FIELD_GET(PLL_MFN_MASK, pll_numerator); + + pll_denominator = readl_relaxed(pll->base + PLL_DENOMINATOR); + mfd = FIELD_GET(PLL_MFD_MASK, pll_denominator); + + pll_div = readl_relaxed(pll->base + PLL_DIV); + mfi = FIELD_GET(PLL_MFI_MASK, pll_div); + + rdiv = FIELD_GET(PLL_RDIV_MASK, pll_div); + rdiv = rdiv + 1; + odiv = FIELD_GET(PLL_ODIV_MASK, pll_div); + switch (odiv) { + case 0: + odiv = 2; + break; + case 1: + odiv = 3; + break; + default: + break; + } + + /* + * Sometimes, the recalculated rate has deviation due to + * the frac part. So find the accurate pll rate from the table + * first, if no match rate in the table, use the rate calculated + * from the equation below. + */ + for (i = 0; i < pll->rate_count; i++) { + if (rate_table[i].mfn == mfn && rate_table[i].mfi == mfi && + rate_table[i].mfd == mfd && rate_table[i].rdiv == rdiv && + rate_table[i].odiv == odiv) + rate = rate_table[i].rate; + } + + if (rate) + return (unsigned long)rate; + + /* Fvco = Fref * (MFI + MFN / MFD) */ + fvco = fvco * mfi * mfd + fvco * mfn; + do_div(fvco, mfd * rdiv * odiv); + + return (unsigned long)fvco; +} + +static int clk_fracn_gppll_wait_lock(struct clk_fracn_gppll *pll) +{ + u32 val; + + return readl_poll_timeout(pll->base + PLL_STATUS, val, + val & LOCK_STATUS, 0, LOCK_TIMEOUT_US); +} + +static int clk_fracn_gppll_set_rate(struct clk_hw *hw, unsigned long drate, + unsigned long prate) +{ + struct clk_fracn_gppll *pll = to_clk_fracn_gppll(hw); + const struct imx_fracn_gppll_rate_table *rate; + u32 tmp, pll_div, ana_mfn; + int ret; + + rate = imx_get_pll_settings(pll, drate); + + /* Disable output */ + tmp = readl_relaxed(pll->base + PLL_CTRL); + tmp &= ~CLKMUX_EN; + writel_relaxed(tmp, pll->base + PLL_CTRL); + + /* Power Down */ + tmp &= ~POWERUP_MASK; + writel_relaxed(tmp, pll->base + PLL_CTRL); + + /* Disable BYPASS */ + tmp &= ~CLKMUX_BYPASS; + writel_relaxed(tmp, pll->base + PLL_CTRL); + + pll_div = FIELD_PREP(PLL_RDIV_MASK, rate->rdiv) | rate->odiv | + FIELD_PREP(PLL_MFI_MASK, rate->mfi); + writel_relaxed(pll_div, pll->base + PLL_DIV); + writel_relaxed(rate->mfd, pll->base + PLL_DENOMINATOR); + writel_relaxed(FIELD_PREP(PLL_MFN_MASK, rate->mfn), pll->base + PLL_NUMERATOR); + + /* Wait for 5us according to fracn mode pll doc */ + udelay(5); + + /* Enable Powerup */ + tmp |= POWERUP_MASK; + writel_relaxed(tmp, pll->base + PLL_CTRL); + + /* Wait Lock */ + ret = clk_fracn_gppll_wait_lock(pll); + if (ret) + return ret; + + /* Enable output */ + tmp |= CLKMUX_EN; + writel_relaxed(tmp, pll->base + PLL_CTRL); + + ana_mfn = readl_relaxed(pll->base + PLL_STATUS); + ana_mfn = FIELD_GET(PLL_MFN_MASK, ana_mfn); + + WARN(ana_mfn != rate->mfn, "ana_mfn != rate->mfn\n"); + + return 0; +} + +static int clk_fracn_gppll_prepare(struct clk_hw *hw) +{ + struct clk_fracn_gppll *pll = to_clk_fracn_gppll(hw); + u32 val; + int ret; + + val = readl_relaxed(pll->base + PLL_CTRL); + if (val & POWERUP_MASK) + return 0; + + val |= CLKMUX_BYPASS; + writel_relaxed(val, pll->base + PLL_CTRL); + + val |= POWERUP_MASK; + writel_relaxed(val, pll->base + PLL_CTRL); + + val |= CLKMUX_EN; + writel_relaxed(val, pll->base + PLL_CTRL); + + ret = clk_fracn_gppll_wait_lock(pll); + if (ret) + return ret; + + val &= ~CLKMUX_BYPASS; + writel_relaxed(val, pll->base + PLL_CTRL); + + return 0; +} + +static int clk_fracn_gppll_is_prepared(struct clk_hw *hw) +{ + struct clk_fracn_gppll *pll = to_clk_fracn_gppll(hw); + u32 val; + + val = readl_relaxed(pll->base + PLL_CTRL); + + return (val & POWERUP_MASK) ? 1 : 0; +} + +static void clk_fracn_gppll_unprepare(struct clk_hw *hw) +{ + struct clk_fracn_gppll *pll = to_clk_fracn_gppll(hw); + u32 val; + + val = readl_relaxed(pll->base + PLL_CTRL); + val &= ~POWERUP_MASK; + writel_relaxed(val, pll->base + PLL_CTRL); +} + +static const struct clk_ops clk_fracn_gppll_ops = { + .prepare = clk_fracn_gppll_prepare, + .unprepare = clk_fracn_gppll_unprepare, + .is_prepared = clk_fracn_gppll_is_prepared, + .recalc_rate = clk_fracn_gppll_recalc_rate, + .round_rate = clk_fracn_gppll_round_rate, + .set_rate = clk_fracn_gppll_set_rate, +}; + +struct clk_hw *imx_clk_fracn_gppll(const char *name, const char *parent_name, void __iomem *base, + const struct imx_fracn_gppll_clk *pll_clk) +{ + struct clk_fracn_gppll *pll; + struct clk_hw *hw; + struct clk_init_data init; + int ret; + + pll = kzalloc(sizeof(*pll), GFP_KERNEL); + if (!pll) + return ERR_PTR(-ENOMEM); + + init.name = name; + init.flags = pll_clk->flags; + init.parent_names = &parent_name; + init.num_parents = 1; + init.ops = &clk_fracn_gppll_ops; + + pll->base = base; + pll->hw.init = &init; + pll->rate_table = pll_clk->rate_table; + pll->rate_count = pll_clk->rate_count; + + hw = &pll->hw; + + ret = clk_hw_register(NULL, hw); + if (ret) { + pr_err("%s: failed to register pll %s %d\n", __func__, name, ret); + kfree(pll); + return ERR_PTR(ret); + } + + return hw; +} +EXPORT_SYMBOL_GPL(imx_clk_fracn_gppll); diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h index 63eb7c53b123c..a7cbbcd1a3f46 100644 --- a/drivers/clk/imx/clk.h +++ b/drivers/clk/imx/clk.h @@ -72,6 +72,27 @@ extern struct imx_pll14xx_clk imx_1416x_pll; extern struct imx_pll14xx_clk imx_1443x_pll; extern struct imx_pll14xx_clk imx_1443x_dram_pll; +/* NOTE: Rate table should be kept sorted in descending order. */ +struct imx_fracn_gppll_rate_table { + unsigned int rate; + unsigned int mfi; + unsigned int mfn; + unsigned int mfd; + unsigned int rdiv; + unsigned int odiv; +}; + +struct imx_fracn_gppll_clk { + const struct imx_fracn_gppll_rate_table *rate_table; + int rate_count; + int flags; +}; + +struct clk_hw *imx_clk_fracn_gppll(const char *name, const char *parent_name, void __iomem *base, + const struct imx_fracn_gppll_clk *pll_clk); + +extern struct imx_fracn_gppll_clk imx_fracn_gppll; + #define imx_clk_cpu(name, parent_name, div, mux, pll, step) \ to_clk(imx_clk_hw_cpu(name, parent_name, div, mux, pll, step)) From 24defbe194b650218680fcd9dec8cd103537b531 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Mon, 28 Feb 2022 10:09:08 +0800 Subject: [PATCH 28/43] clk: imx: add i.MX93 clk Add i.MX93 clk driver. i.MX93 clk hardware design is different compared with i.MX8M. It supports 4 sources for each clk root and the sources are separated into a few groups, low speed/fast io/audio and etc. Reviewed-by: Abel Vesa Signed-off-by: Peng Fan Link: https://lore.kernel.org/r/20220228020908.2810346-6-peng.fan@oss.nxp.com [abel.vesa@nxp.com: Added missing module license and description] Signed-off-by: Abel Vesa --- drivers/clk/imx/Kconfig | 6 + drivers/clk/imx/Makefile | 2 + drivers/clk/imx/clk-imx93.c | 341 ++++++++++++++++++++++++++++++++++++ 3 files changed, 349 insertions(+) create mode 100644 drivers/clk/imx/clk-imx93.c diff --git a/drivers/clk/imx/Kconfig b/drivers/clk/imx/Kconfig index 45641b8bdc50a..cc464a42d6463 100644 --- a/drivers/clk/imx/Kconfig +++ b/drivers/clk/imx/Kconfig @@ -106,6 +106,12 @@ config CLK_IMX8ULP help Build the driver for i.MX8ULP CCM Clock Driver +config CLK_IMX93 + tristate "IMX93 CCM Clock Driver" + depends on ARCH_MXC || COMPILE_TEST + help + Build the driver for i.MX93 CCM Clock Driver + config CLK_IMXRT1050 tristate "IMXRT1050 CCM Clock Driver" depends on SOC_IMXRT diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile index 60c8a4bb75744..88b9b9285d22e 100644 --- a/drivers/clk/imx/Makefile +++ b/drivers/clk/imx/Makefile @@ -28,6 +28,8 @@ obj-$(CONFIG_CLK_IMX8MN) += clk-imx8mn.o obj-$(CONFIG_CLK_IMX8MP) += clk-imx8mp.o obj-$(CONFIG_CLK_IMX8MQ) += clk-imx8mq.o +obj-$(CONFIG_CLK_IMX93) += clk-imx93.o + obj-$(CONFIG_MXC_CLK_SCU) += clk-imx-scu.o clk-imx-lpcg-scu.o clk-imx-scu-$(CONFIG_CLK_IMX8QXP) += clk-scu.o clk-imx8qxp.o \ clk-imx8qxp-rsrc.o clk-imx8qm-rsrc.o \ diff --git a/drivers/clk/imx/clk-imx93.c b/drivers/clk/imx/clk-imx93.c new file mode 100644 index 0000000000000..edcc87661d1f6 --- /dev/null +++ b/drivers/clk/imx/clk-imx93.c @@ -0,0 +1,341 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2021 NXP. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "clk.h" + +enum clk_sel { + LOW_SPEED_IO_SEL, + NON_IO_SEL, + FAST_SEL, + AUDIO_SEL, + VIDEO_SEL, + TPM_SEL, + CKO1_SEL, + CKO2_SEL, + MISC_SEL, + MAX_SEL +}; + +static const char *parent_names[MAX_SEL][4] = { + {"osc_24m", "sys_pll_pfd0_div2", "sys_pll_pfd1_div2", "video_pll"}, + {"osc_24m", "sys_pll_pfd0_div2", "sys_pll_pfd1_div2", "sys_pll_pfd2_div2"}, + {"osc_24m", "sys_pll_pfd0", "sys_pll_pfd1", "sys_pll_pfd2"}, + {"osc_24m", "audio_pll", "video_pll", "clk_ext1"}, + {"osc_24m", "audio_pll", "video_pll", "sys_pll_pfd0"}, + {"osc_24m", "sys_pll_pfd0", "audio_pll", "clk_ext1"}, + {"osc_24m", "sys_pll_pfd0", "sys_pll_pfd1", "audio_pll"}, + {"osc_24m", "sys_pll_pfd0", "sys_pll_pfd1", "video_pll"}, + {"osc_24m", "audio_pll", "video_pll", "sys_pll_pfd2"}, +}; + +static const struct imx93_clk_root { + u32 clk; + char *name; + u32 off; + enum clk_sel sel; + unsigned long flags; +} root_array[] = { + /* a55/m33/bus critical clk for system run */ + { IMX93_CLK_A55_PERIPH, "a55_periph_root", 0x0000, FAST_SEL, CLK_IS_CRITICAL }, + { IMX93_CLK_A55_MTR_BUS, "a55_mtr_bus_root", 0x0080, LOW_SPEED_IO_SEL, CLK_IS_CRITICAL }, + { IMX93_CLK_A55, "a55_root", 0x0100, FAST_SEL, CLK_IS_CRITICAL }, + { IMX93_CLK_M33, "m33_root", 0x0180, LOW_SPEED_IO_SEL, CLK_IS_CRITICAL }, + { IMX93_CLK_BUS_WAKEUP, "bus_wakeup_root", 0x0280, LOW_SPEED_IO_SEL, CLK_IS_CRITICAL }, + { IMX93_CLK_BUS_AON, "bus_aon_root", 0x0300, LOW_SPEED_IO_SEL, CLK_IS_CRITICAL }, + { IMX93_CLK_WAKEUP_AXI, "wakeup_axi_root", 0x0380, FAST_SEL, CLK_IS_CRITICAL }, + { IMX93_CLK_SWO_TRACE, "swo_trace_root", 0x0400, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_M33_SYSTICK, "m33_systick_root", 0x0480, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_FLEXIO1, "flexio1_root", 0x0500, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_FLEXIO2, "flexio2_root", 0x0580, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_LPIT1, "lpit1_root", 0x0600, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_LPIT2, "lpit2_root", 0x0680, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_LPTMR1, "lptmr1_root", 0x0700, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_LPTMR2, "lptmr2_root", 0x0780, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_TPM1, "tpm1_root", 0x0800, TPM_SEL, }, + { IMX93_CLK_TPM2, "tpm2_root", 0x0880, TPM_SEL, }, + { IMX93_CLK_TPM3, "tpm3_root", 0x0900, TPM_SEL, }, + { IMX93_CLK_TPM4, "tpm4_root", 0x0980, TPM_SEL, }, + { IMX93_CLK_TPM5, "tpm5_root", 0x0a00, TPM_SEL, }, + { IMX93_CLK_TPM6, "tpm6_root", 0x0a80, TPM_SEL, }, + { IMX93_CLK_FLEXSPI1, "flexspi1_root", 0x0b00, FAST_SEL, }, + { IMX93_CLK_CAN1, "can1_root", 0x0b80, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_CAN2, "can2_root", 0x0c00, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_LPUART1, "lpuart1_root", 0x0c80, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_LPUART2, "lpuart2_root", 0x0d00, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_LPUART3, "lpuart3_root", 0x0d80, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_LPUART4, "lpuart4_root", 0x0e00, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_LPUART5, "lpuart5_root", 0x0e80, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_LPUART6, "lpuart6_root", 0x0f00, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_LPUART7, "lpuart7_root", 0x0f80, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_LPUART8, "lpuart8_root", 0x1000, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_LPI2C1, "lpi2c1_root", 0x1080, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_LPI2C2, "lpi2c2_root", 0x1100, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_LPI2C3, "lpi2c3_root", 0x1180, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_LPI2C4, "lpi2c4_root", 0x1200, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_LPI2C5, "lpi2c5_root", 0x1280, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_LPI2C6, "lpi2c6_root", 0x1300, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_LPI2C7, "lpi2c7_root", 0x1380, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_LPI2C8, "lpi2c8_root", 0x1400, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_LPSPI1, "lpspi1_root", 0x1480, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_LPSPI2, "lpspi2_root", 0x1500, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_LPSPI3, "lpspi3_root", 0x1580, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_LPSPI4, "lpspi4_root", 0x1600, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_LPSPI5, "lpspi5_root", 0x1680, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_LPSPI6, "lpspi6_root", 0x1700, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_LPSPI7, "lpspi7_root", 0x1780, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_LPSPI8, "lpspi8_root", 0x1800, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_I3C1, "i3c1_root", 0x1880, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_I3C2, "i3c2_root", 0x1900, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_USDHC1, "usdhc1_root", 0x1980, FAST_SEL, }, + { IMX93_CLK_USDHC2, "usdhc2_root", 0x1a00, FAST_SEL, }, + { IMX93_CLK_USDHC3, "usdhc3_root", 0x1a80, FAST_SEL, }, + { IMX93_CLK_SAI1, "sai1_root", 0x1b00, AUDIO_SEL, }, + { IMX93_CLK_SAI2, "sai2_root", 0x1b80, AUDIO_SEL, }, + { IMX93_CLK_SAI3, "sai3_root", 0x1c00, AUDIO_SEL, }, + { IMX93_CLK_CCM_CKO1, "ccm_cko1_root", 0x1c80, CKO1_SEL, }, + { IMX93_CLK_CCM_CKO2, "ccm_cko2_root", 0x1d00, CKO2_SEL, }, + { IMX93_CLK_CCM_CKO3, "ccm_cko3_root", 0x1d80, CKO1_SEL, }, + { IMX93_CLK_CCM_CKO4, "ccm_cko4_root", 0x1e00, CKO2_SEL, }, + { IMX93_CLK_HSIO, "hsio_root", 0x1e80, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_HSIO_USB_TEST_60M, "hsio_usb_test_60m_root", 0x1f00, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_HSIO_ACSCAN_80M, "hsio_acscan_80m_root", 0x1f80, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_HSIO_ACSCAN_480M, "hsio_acscan_480m_root", 0x2000, MISC_SEL, }, + { IMX93_CLK_ML_APB, "ml_apb_root", 0x2180, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_ML, "ml_root", 0x2200, FAST_SEL, }, + { IMX93_CLK_MEDIA_AXI, "media_axi_root", 0x2280, FAST_SEL, }, + { IMX93_CLK_MEDIA_APB, "media_apb_root", 0x2300, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_MEDIA_LDB, "media_ldb_root", 0x2380, VIDEO_SEL, }, + { IMX93_CLK_MEDIA_DISP_PIX, "media_disp_pix_root", 0x2400, VIDEO_SEL, }, + { IMX93_CLK_CAM_PIX, "cam_pix_root", 0x2480, VIDEO_SEL, }, + { IMX93_CLK_MIPI_TEST_BYTE, "mipi_test_byte_root", 0x2500, VIDEO_SEL, }, + { IMX93_CLK_MIPI_PHY_CFG, "mipi_phy_cfg_root", 0x2580, VIDEO_SEL, }, + { IMX93_CLK_ADC, "adc_root", 0x2700, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_PDM, "pdm_root", 0x2780, AUDIO_SEL, }, + { IMX93_CLK_TSTMR1, "tstmr1_root", 0x2800, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_TSTMR2, "tstmr2_root", 0x2880, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_MQS1, "mqs1_root", 0x2900, AUDIO_SEL, }, + { IMX93_CLK_MQS2, "mqs2_root", 0x2980, AUDIO_SEL, }, + { IMX93_CLK_AUDIO_XCVR, "audio_xcvr_root", 0x2a00, NON_IO_SEL, }, + { IMX93_CLK_SPDIF, "spdif_root", 0x2a80, AUDIO_SEL, }, + { IMX93_CLK_ENET, "enet_root", 0x2b00, NON_IO_SEL, }, + { IMX93_CLK_ENET_TIMER1, "enet_timer1_root", 0x2b80, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_ENET_TIMER2, "enet_timer2_root", 0x2c00, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_ENET_REF, "enet_ref_root", 0x2c80, NON_IO_SEL, }, + { IMX93_CLK_ENET_REF_PHY, "enet_ref_phy_root", 0x2d00, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_I3C1_SLOW, "i3c1_slow_root", 0x2d80, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_I3C2_SLOW, "i3c2_slow_root", 0x2e00, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_USB_PHY_BURUNIN, "usb_phy_root", 0x2e80, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_PAL_CAME_SCAN, "pal_came_scan_root", 0x2f00, MISC_SEL, } +}; + +static const struct imx93_clk_ccgr { + u32 clk; + char *name; + char *parent_name; + u32 off; + unsigned long flags; +} ccgr_array[] = { + { IMX93_CLK_A55_GATE, "a55", "a55_root", 0x8000, }, + /* M33 critical clk for system run */ + { IMX93_CLK_CM33_GATE, "cm33", "m33_root", 0x8040, CLK_IS_CRITICAL }, + { IMX93_CLK_ADC1_GATE, "adc1", "osc_24m", 0x82c0, }, + { IMX93_CLK_WDOG1_GATE, "wdog1", "osc_24m", 0x8300, }, + { IMX93_CLK_WDOG2_GATE, "wdog2", "osc_24m", 0x8340, }, + { IMX93_CLK_WDOG3_GATE, "wdog3", "osc_24m", 0x8380, }, + { IMX93_CLK_WDOG4_GATE, "wdog4", "osc_24m", 0x83c0, }, + { IMX93_CLK_WDOG5_GATE, "wdog5", "osc_24m", 0x8400, }, + { IMX93_CLK_SEMA1_GATE, "sema1", "bus_aon_root", 0x8440, }, + { IMX93_CLK_SEMA2_GATE, "sema2", "bus_wakeup_root", 0x8480, }, + { IMX93_CLK_MU_A_GATE, "mu_a", "bus_aon_root", 0x84c0, }, + { IMX93_CLK_MU_B_GATE, "mu_b", "bus_aon_root", 0x8500, }, + { IMX93_CLK_EDMA1_GATE, "edma1", "wakeup_axi_root", 0x8540, }, + { IMX93_CLK_EDMA2_GATE, "edma2", "wakeup_axi_root", 0x8580, }, + { IMX93_CLK_FLEXSPI1_GATE, "flexspi", "flexspi_root", 0x8640, }, + { IMX93_CLK_GPIO1_GATE, "gpio1", "m33_root", 0x8880, }, + { IMX93_CLK_GPIO2_GATE, "gpio2", "bus_wakeup_root", 0x88c0, }, + { IMX93_CLK_GPIO3_GATE, "gpio3", "bus_wakeup_root", 0x8900, }, + { IMX93_CLK_GPIO4_GATE, "gpio4", "bus_wakeup_root", 0x8940, }, + { IMX93_CLK_FLEXIO1_GATE, "flexio1", "flexio1_root", 0x8980, }, + { IMX93_CLK_FLEXIO2_GATE, "flexio2", "flexio2_root", 0x89c0, }, + { IMX93_CLK_LPIT1_GATE, "lpit1", "lpit1_root", 0x8a00, }, + { IMX93_CLK_LPIT2_GATE, "lpit2", "lpit2_root", 0x8a40, }, + { IMX93_CLK_LPTMR1_GATE, "lptmr1", "lptmr1_root", 0x8a80, }, + { IMX93_CLK_LPTMR2_GATE, "lptmr2", "lptmr2_root", 0x8ac0, }, + { IMX93_CLK_TPM1_GATE, "tpm1", "tpm1_root", 0x8b00, }, + { IMX93_CLK_TPM2_GATE, "tpm2", "tpm2_root", 0x8b40, }, + { IMX93_CLK_TPM3_GATE, "tpm3", "tpm3_root", 0x8b80, }, + { IMX93_CLK_TPM4_GATE, "tpm4", "tpm4_root", 0x8bc0, }, + { IMX93_CLK_TPM5_GATE, "tpm5", "tpm5_root", 0x8c00, }, + { IMX93_CLK_TPM6_GATE, "tpm6", "tpm6_root", 0x8c40, }, + { IMX93_CLK_CAN1_GATE, "can1", "can1_root", 0x8c80, }, + { IMX93_CLK_CAN2_GATE, "can2", "can2_root", 0x8cc0, }, + { IMX93_CLK_LPUART1_GATE, "lpuart1", "lpuart1_root", 0x8d00, }, + { IMX93_CLK_LPUART2_GATE, "lpuart2", "lpuart2_root", 0x8d40, }, + { IMX93_CLK_LPUART3_GATE, "lpuart3", "lpuart3_root", 0x8d80, }, + { IMX93_CLK_LPUART4_GATE, "lpuart4", "lpuart4_root", 0x8dc0, }, + { IMX93_CLK_LPUART5_GATE, "lpuart5", "lpuart5_root", 0x8e00, }, + { IMX93_CLK_LPUART6_GATE, "lpuart6", "lpuart6_root", 0x8e40, }, + { IMX93_CLK_LPUART7_GATE, "lpuart7", "lpuart7_root", 0x8e80, }, + { IMX93_CLK_LPUART8_GATE, "lpuart8", "lpuart8_root", 0x8ec0, }, + { IMX93_CLK_LPI2C1_GATE, "lpi2c1", "lpi2c1_root", 0x8f00, }, + { IMX93_CLK_LPI2C2_GATE, "lpi2c2", "lpi2c2_root", 0x8f40, }, + { IMX93_CLK_LPI2C3_GATE, "lpi2c3", "lpi2c3_root", 0x8f80, }, + { IMX93_CLK_LPI2C4_GATE, "lpi2c4", "lpi2c4_root", 0x8fc0, }, + { IMX93_CLK_LPI2C5_GATE, "lpi2c5", "lpi2c5_root", 0x9000, }, + { IMX93_CLK_LPI2C6_GATE, "lpi2c6", "lpi2c6_root", 0x9040, }, + { IMX93_CLK_LPI2C7_GATE, "lpi2c7", "lpi2c7_root", 0x9080, }, + { IMX93_CLK_LPI2C8_GATE, "lpi2c8", "lpi2c8_root", 0x90c0, }, + { IMX93_CLK_LPSPI1_GATE, "lpspi1", "lpspi1_root", 0x9100, }, + { IMX93_CLK_LPSPI2_GATE, "lpspi2", "lpspi2_root", 0x9140, }, + { IMX93_CLK_LPSPI3_GATE, "lpspi3", "lpspi3_root", 0x9180, }, + { IMX93_CLK_LPSPI4_GATE, "lpspi4", "lpspi4_root", 0x91c0, }, + { IMX93_CLK_LPSPI5_GATE, "lpspi5", "lpspi5_root", 0x9200, }, + { IMX93_CLK_LPSPI6_GATE, "lpspi6", "lpspi6_root", 0x9240, }, + { IMX93_CLK_LPSPI7_GATE, "lpspi7", "lpspi7_root", 0x9280, }, + { IMX93_CLK_LPSPI8_GATE, "lpspi8", "lpspi8_root", 0x92c0, }, + { IMX93_CLK_I3C1_GATE, "i3c1", "i3c1_root", 0x9300, }, + { IMX93_CLK_I3C2_GATE, "i3c2", "i3c2_root", 0x9340, }, + { IMX93_CLK_USDHC1_GATE, "usdhc1", "usdhc1_root", 0x9380, }, + { IMX93_CLK_USDHC2_GATE, "usdhc2", "usdhc2_root", 0x93c0, }, + { IMX93_CLK_USDHC3_GATE, "usdhc3", "usdhc3_root", 0x9400, }, + { IMX93_CLK_SAI1_GATE, "sai1", "sai1_root", 0x9440, }, + { IMX93_CLK_SAI2_GATE, "sai2", "sai2_root", 0x9480, }, + { IMX93_CLK_SAI3_GATE, "sai3", "sai3_root", 0x94c0, }, + { IMX93_CLK_MIPI_CSI_GATE, "mipi_csi", "media_apb_root", 0x9580, }, + { IMX93_CLK_MIPI_DSI_GATE, "mipi_dsi", "media_apb_root", 0x95c0, }, + { IMX93_CLK_LVDS_GATE, "lvds", "media_ldb_root", 0x9600, }, + { IMX93_CLK_LCDIF_GATE, "lcdif", "media_apb_root", 0x9640, }, + { IMX93_CLK_PXP_GATE, "pxp", "media_apb_root", 0x9680, }, + { IMX93_CLK_ISI_GATE, "isi", "media_apb_root", 0x96c0, }, + { IMX93_CLK_NIC_MEDIA_GATE, "nic_media", "media_apb_root", 0x9700, }, + { IMX93_CLK_USB_CONTROLLER_GATE, "usb_controller", "hsio_root", 0x9a00, }, + { IMX93_CLK_USB_TEST_60M_GATE, "usb_test_60m", "hsio_usb_test_60m_root", 0x9a40, }, + { IMX93_CLK_HSIO_TROUT_24M_GATE, "hsio_trout_24m", "osc_24m", 0x9a80, }, + { IMX93_CLK_PDM_GATE, "pdm", "pdm_root", 0x9ac0, }, + { IMX93_CLK_MQS1_GATE, "mqs1", "sai1_root", 0x9b00, }, + { IMX93_CLK_MQS2_GATE, "mqs2", "sai3_root", 0x9b40, }, + { IMX93_CLK_AUD_XCVR_GATE, "aud_xcvr", "audio_xcvr_root", 0x9b80, }, + { IMX93_CLK_SPDIF_GATE, "spdif", "spdif_root", 0x9c00, }, + { IMX93_CLK_HSIO_32K_GATE, "hsio_32k", "osc_32k", 0x9dc0, }, + { IMX93_CLK_ENET1_GATE, "enet1", "enet_root", 0x9e00, }, + { IMX93_CLK_ENET_QOS_GATE, "enet_qos", "wakeup_axi_root", 0x9e40, }, + { IMX93_CLK_SYS_CNT_GATE, "sys_cnt", "osc_24m", 0x9e80, }, + { IMX93_CLK_TSTMR1_GATE, "tstmr1", "bus_aon_root", 0x9ec0, }, + { IMX93_CLK_TSTMR2_GATE, "tstmr2", "bus_wakeup_root", 0x9f00, }, + { IMX93_CLK_TMC_GATE, "tmc", "osc_24m", 0x9f40, }, + { IMX93_CLK_PMRO_GATE, "pmro", "osc_24m", 0x9f80, } +}; + +static struct clk_hw_onecell_data *clk_hw_data; +static struct clk_hw **clks; + +static int imx93_clocks_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + const struct imx93_clk_root *root; + const struct imx93_clk_ccgr *ccgr; + void __iomem *base = NULL; + int i, ret; + + clk_hw_data = kzalloc(struct_size(clk_hw_data, hws, + IMX93_CLK_END), GFP_KERNEL); + if (!clk_hw_data) + return -ENOMEM; + + clk_hw_data->num = IMX93_CLK_END; + clks = clk_hw_data->hws; + + clks[IMX93_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0); + clks[IMX93_CLK_24M] = imx_obtain_fixed_clk_hw(np, "osc_24m"); + clks[IMX93_CLK_32K] = imx_obtain_fixed_clk_hw(np, "osc_32k"); + clks[IMX93_CLK_EXT1] = imx_obtain_fixed_clk_hw(np, "clk_ext1"); + + clks[IMX93_CLK_SYS_PLL_PFD0] = imx_clk_hw_fixed("sys_pll_pfd0", 1000000000); + clks[IMX93_CLK_SYS_PLL_PFD0_DIV2] = imx_clk_hw_fixed_factor("sys_pll_pfd0_div2", + "sys_pll_pfd0", 1, 2); + clks[IMX93_CLK_SYS_PLL_PFD1] = imx_clk_hw_fixed("sys_pll_pfd1", 800000000); + clks[IMX93_CLK_SYS_PLL_PFD1_DIV2] = imx_clk_hw_fixed_factor("sys_pll_pfd1_div2", + "sys_pll_pfd1", 1, 2); + clks[IMX93_CLK_SYS_PLL_PFD2] = imx_clk_hw_fixed("sys_pll_pfd2", 625000000); + clks[IMX93_CLK_SYS_PLL_PFD2_DIV2] = imx_clk_hw_fixed_factor("sys_pll_pfd2_div2", + "sys_pll_pfd2", 1, 2); + + np = of_find_compatible_node(NULL, NULL, "fsl,imx93-anatop"); + base = of_iomap(np, 0); + of_node_put(np); + if (WARN_ON(!base)) + return -ENOMEM; + + clks[IMX93_CLK_AUDIO_PLL] = imx_clk_fracn_gppll("audio_pll", "osc_24m", base + 0x1200, + &imx_fracn_gppll); + clks[IMX93_CLK_VIDEO_PLL] = imx_clk_fracn_gppll("video_pll", "osc_24m", base + 0x1400, + &imx_fracn_gppll); + + np = dev->of_node; + base = devm_platform_ioremap_resource(pdev, 0); + if (WARN_ON(IS_ERR(base))) + return PTR_ERR(base); + + for (i = 0; i < ARRAY_SIZE(root_array); i++) { + root = &root_array[i]; + clks[root->clk] = imx93_clk_composite_flags(root->name, + parent_names[root->sel], + 4, base + root->off, + root->flags); + } + + for (i = 0; i < ARRAY_SIZE(ccgr_array); i++) { + ccgr = &ccgr_array[i]; + clks[ccgr->clk] = imx_clk_hw_gate4_flags(ccgr->name, + ccgr->parent_name, + base + ccgr->off, 0, + ccgr->flags); + } + + imx_check_clk_hws(clks, IMX93_CLK_END); + + ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data); + if (ret < 0) { + dev_err(dev, "failed to register clks for i.MX93\n"); + goto unregister_hws; + } + + return 0; + +unregister_hws: + imx_unregister_hw_clocks(clks, IMX93_CLK_END); + + return ret; +} + +static const struct of_device_id imx93_clk_of_match[] = { + { .compatible = "fsl,imx93-ccm" }, + { /* Sentinel */ }, +}; +MODULE_DEVICE_TABLE(of, imx93_clk_of_match); + +static struct platform_driver imx93_clk_driver = { + .probe = imx93_clocks_probe, + .driver = { + .name = "imx93-ccm", + .suppress_bind_attrs = true, + .of_match_table = of_match_ptr(imx93_clk_of_match), + }, +}; +module_platform_driver(imx93_clk_driver); + +MODULE_DESCRIPTION("NXP i.MX93 clock driver"); +MODULE_LICENSE("GPL v2"); From d25cbd3e392730f459f1fbf5f959c16b460a59ca Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Fri, 25 Feb 2022 16:17:31 +0800 Subject: [PATCH 29/43] clk: imx8mm: remove SYS PLL 1/2 clock gates Remove the PLL 1/2 gates as it make AMP clock management harder without obvious benifit. Signed-off-by: Peng Fan Reviewed-by: Abel Vesa Link: https://lore.kernel.org/r/20220225081733.2294166-2-peng.fan@oss.nxp.com Signed-off-by: Abel Vesa --- drivers/clk/imx/clk-imx8mm.c | 49 ++++++++++++------------------------ 1 file changed, 16 insertions(+), 33 deletions(-) diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c index e92621fa8b9cd..e8cbe181ec06d 100644 --- a/drivers/clk/imx/clk-imx8mm.c +++ b/drivers/clk/imx/clk-imx8mm.c @@ -366,45 +366,28 @@ static int imx8mm_clocks_probe(struct platform_device *pdev) hws[IMX8MM_SYS_PLL3_OUT] = imx_clk_hw_gate("sys_pll3_out", "sys_pll3_bypass", base + 0x114, 11); /* SYS PLL1 fixed output */ - hws[IMX8MM_SYS_PLL1_40M_CG] = imx_clk_hw_gate("sys_pll1_40m_cg", "sys_pll1", base + 0x94, 27); - hws[IMX8MM_SYS_PLL1_80M_CG] = imx_clk_hw_gate("sys_pll1_80m_cg", "sys_pll1", base + 0x94, 25); - hws[IMX8MM_SYS_PLL1_100M_CG] = imx_clk_hw_gate("sys_pll1_100m_cg", "sys_pll1", base + 0x94, 23); - hws[IMX8MM_SYS_PLL1_133M_CG] = imx_clk_hw_gate("sys_pll1_133m_cg", "sys_pll1", base + 0x94, 21); - hws[IMX8MM_SYS_PLL1_160M_CG] = imx_clk_hw_gate("sys_pll1_160m_cg", "sys_pll1", base + 0x94, 19); - hws[IMX8MM_SYS_PLL1_200M_CG] = imx_clk_hw_gate("sys_pll1_200m_cg", "sys_pll1", base + 0x94, 17); - hws[IMX8MM_SYS_PLL1_266M_CG] = imx_clk_hw_gate("sys_pll1_266m_cg", "sys_pll1", base + 0x94, 15); - hws[IMX8MM_SYS_PLL1_400M_CG] = imx_clk_hw_gate("sys_pll1_400m_cg", "sys_pll1", base + 0x94, 13); hws[IMX8MM_SYS_PLL1_OUT] = imx_clk_hw_gate("sys_pll1_out", "sys_pll1", base + 0x94, 11); - hws[IMX8MM_SYS_PLL1_40M] = imx_clk_hw_fixed_factor("sys_pll1_40m", "sys_pll1_40m_cg", 1, 20); - hws[IMX8MM_SYS_PLL1_80M] = imx_clk_hw_fixed_factor("sys_pll1_80m", "sys_pll1_80m_cg", 1, 10); - hws[IMX8MM_SYS_PLL1_100M] = imx_clk_hw_fixed_factor("sys_pll1_100m", "sys_pll1_100m_cg", 1, 8); - hws[IMX8MM_SYS_PLL1_133M] = imx_clk_hw_fixed_factor("sys_pll1_133m", "sys_pll1_133m_cg", 1, 6); - hws[IMX8MM_SYS_PLL1_160M] = imx_clk_hw_fixed_factor("sys_pll1_160m", "sys_pll1_160m_cg", 1, 5); - hws[IMX8MM_SYS_PLL1_200M] = imx_clk_hw_fixed_factor("sys_pll1_200m", "sys_pll1_200m_cg", 1, 4); - hws[IMX8MM_SYS_PLL1_266M] = imx_clk_hw_fixed_factor("sys_pll1_266m", "sys_pll1_266m_cg", 1, 3); - hws[IMX8MM_SYS_PLL1_400M] = imx_clk_hw_fixed_factor("sys_pll1_400m", "sys_pll1_400m_cg", 1, 2); + hws[IMX8MM_SYS_PLL1_40M] = imx_clk_hw_fixed_factor("sys_pll1_40m", "sys_pll1_out", 1, 20); + hws[IMX8MM_SYS_PLL1_80M] = imx_clk_hw_fixed_factor("sys_pll1_80m", "sys_pll1_out", 1, 10); + hws[IMX8MM_SYS_PLL1_100M] = imx_clk_hw_fixed_factor("sys_pll1_100m", "sys_pll1_out", 1, 8); + hws[IMX8MM_SYS_PLL1_133M] = imx_clk_hw_fixed_factor("sys_pll1_133m", "sys_pll1_out", 1, 6); + hws[IMX8MM_SYS_PLL1_160M] = imx_clk_hw_fixed_factor("sys_pll1_160m", "sys_pll1_out", 1, 5); + hws[IMX8MM_SYS_PLL1_200M] = imx_clk_hw_fixed_factor("sys_pll1_200m", "sys_pll1_out", 1, 4); + hws[IMX8MM_SYS_PLL1_266M] = imx_clk_hw_fixed_factor("sys_pll1_266m", "sys_pll1_out", 1, 3); + hws[IMX8MM_SYS_PLL1_400M] = imx_clk_hw_fixed_factor("sys_pll1_400m", "sys_pll1_out", 1, 2); hws[IMX8MM_SYS_PLL1_800M] = imx_clk_hw_fixed_factor("sys_pll1_800m", "sys_pll1_out", 1, 1); /* SYS PLL2 fixed output */ - hws[IMX8MM_SYS_PLL2_50M_CG] = imx_clk_hw_gate("sys_pll2_50m_cg", "sys_pll2", base + 0x104, 27); - hws[IMX8MM_SYS_PLL2_100M_CG] = imx_clk_hw_gate("sys_pll2_100m_cg", "sys_pll2", base + 0x104, 25); - hws[IMX8MM_SYS_PLL2_125M_CG] = imx_clk_hw_gate("sys_pll2_125m_cg", "sys_pll2", base + 0x104, 23); - hws[IMX8MM_SYS_PLL2_166M_CG] = imx_clk_hw_gate("sys_pll2_166m_cg", "sys_pll2", base + 0x104, 21); - hws[IMX8MM_SYS_PLL2_200M_CG] = imx_clk_hw_gate("sys_pll2_200m_cg", "sys_pll2", base + 0x104, 19); - hws[IMX8MM_SYS_PLL2_250M_CG] = imx_clk_hw_gate("sys_pll2_250m_cg", "sys_pll2", base + 0x104, 17); - hws[IMX8MM_SYS_PLL2_333M_CG] = imx_clk_hw_gate("sys_pll2_333m_cg", "sys_pll2", base + 0x104, 15); - hws[IMX8MM_SYS_PLL2_500M_CG] = imx_clk_hw_gate("sys_pll2_500m_cg", "sys_pll2", base + 0x104, 13); hws[IMX8MM_SYS_PLL2_OUT] = imx_clk_hw_gate("sys_pll2_out", "sys_pll2", base + 0x104, 11); - - hws[IMX8MM_SYS_PLL2_50M] = imx_clk_hw_fixed_factor("sys_pll2_50m", "sys_pll2_50m_cg", 1, 20); - hws[IMX8MM_SYS_PLL2_100M] = imx_clk_hw_fixed_factor("sys_pll2_100m", "sys_pll2_100m_cg", 1, 10); - hws[IMX8MM_SYS_PLL2_125M] = imx_clk_hw_fixed_factor("sys_pll2_125m", "sys_pll2_125m_cg", 1, 8); - hws[IMX8MM_SYS_PLL2_166M] = imx_clk_hw_fixed_factor("sys_pll2_166m", "sys_pll2_166m_cg", 1, 6); - hws[IMX8MM_SYS_PLL2_200M] = imx_clk_hw_fixed_factor("sys_pll2_200m", "sys_pll2_200m_cg", 1, 5); - hws[IMX8MM_SYS_PLL2_250M] = imx_clk_hw_fixed_factor("sys_pll2_250m", "sys_pll2_250m_cg", 1, 4); - hws[IMX8MM_SYS_PLL2_333M] = imx_clk_hw_fixed_factor("sys_pll2_333m", "sys_pll2_333m_cg", 1, 3); - hws[IMX8MM_SYS_PLL2_500M] = imx_clk_hw_fixed_factor("sys_pll2_500m", "sys_pll2_500m_cg", 1, 2); + hws[IMX8MM_SYS_PLL2_50M] = imx_clk_hw_fixed_factor("sys_pll2_50m", "sys_pll2_out", 1, 20); + hws[IMX8MM_SYS_PLL2_100M] = imx_clk_hw_fixed_factor("sys_pll2_100m", "sys_pll2_out", 1, 10); + hws[IMX8MM_SYS_PLL2_125M] = imx_clk_hw_fixed_factor("sys_pll2_125m", "sys_pll2_out", 1, 8); + hws[IMX8MM_SYS_PLL2_166M] = imx_clk_hw_fixed_factor("sys_pll2_166m", "sys_pll2_out", 1, 6); + hws[IMX8MM_SYS_PLL2_200M] = imx_clk_hw_fixed_factor("sys_pll2_200m", "sys_pll2_out", 1, 5); + hws[IMX8MM_SYS_PLL2_250M] = imx_clk_hw_fixed_factor("sys_pll2_250m", "sys_pll2_out", 1, 4); + hws[IMX8MM_SYS_PLL2_333M] = imx_clk_hw_fixed_factor("sys_pll2_333m", "sys_pll2_out", 1, 3); + hws[IMX8MM_SYS_PLL2_500M] = imx_clk_hw_fixed_factor("sys_pll2_500m", "sys_pll2_out", 1, 2); hws[IMX8MM_SYS_PLL2_1000M] = imx_clk_hw_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1); hws[IMX8MM_CLK_CLKOUT1_SEL] = imx_clk_hw_mux2("clkout1_sel", base + 0x128, 4, 4, clkout_sels, ARRAY_SIZE(clkout_sels)); From 38ce00adc16319544c8c56edd36324d2c1b98a50 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Fri, 25 Feb 2022 16:17:32 +0800 Subject: [PATCH 30/43] clk: imx8mn: remove SYS PLL 1/2 clock gates Remove the PLL 1/2 gates as it make AMP clock management harder without obvious benifit. Signed-off-by: Peng Fan Reviewed-by: Abel Vesa Link: https://lore.kernel.org/r/20220225081733.2294166-3-peng.fan@oss.nxp.com Signed-off-by: Abel Vesa --- drivers/clk/imx/clk-imx8mn.c | 50 ++++++++++++------------------------ 1 file changed, 16 insertions(+), 34 deletions(-) diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c index 021355a247081..92fcbab4f5bee 100644 --- a/drivers/clk/imx/clk-imx8mn.c +++ b/drivers/clk/imx/clk-imx8mn.c @@ -364,45 +364,27 @@ static int imx8mn_clocks_probe(struct platform_device *pdev) hws[IMX8MN_SYS_PLL3_OUT] = imx_clk_hw_gate("sys_pll3_out", "sys_pll3_bypass", base + 0x114, 11); /* SYS PLL1 fixed output */ - hws[IMX8MN_SYS_PLL1_40M_CG] = imx_clk_hw_gate("sys_pll1_40m_cg", "sys_pll1", base + 0x94, 27); - hws[IMX8MN_SYS_PLL1_80M_CG] = imx_clk_hw_gate("sys_pll1_80m_cg", "sys_pll1", base + 0x94, 25); - hws[IMX8MN_SYS_PLL1_100M_CG] = imx_clk_hw_gate("sys_pll1_100m_cg", "sys_pll1", base + 0x94, 23); - hws[IMX8MN_SYS_PLL1_133M_CG] = imx_clk_hw_gate("sys_pll1_133m_cg", "sys_pll1", base + 0x94, 21); - hws[IMX8MN_SYS_PLL1_160M_CG] = imx_clk_hw_gate("sys_pll1_160m_cg", "sys_pll1", base + 0x94, 19); - hws[IMX8MN_SYS_PLL1_200M_CG] = imx_clk_hw_gate("sys_pll1_200m_cg", "sys_pll1", base + 0x94, 17); - hws[IMX8MN_SYS_PLL1_266M_CG] = imx_clk_hw_gate("sys_pll1_266m_cg", "sys_pll1", base + 0x94, 15); - hws[IMX8MN_SYS_PLL1_400M_CG] = imx_clk_hw_gate("sys_pll1_400m_cg", "sys_pll1", base + 0x94, 13); hws[IMX8MN_SYS_PLL1_OUT] = imx_clk_hw_gate("sys_pll1_out", "sys_pll1", base + 0x94, 11); - - hws[IMX8MN_SYS_PLL1_40M] = imx_clk_hw_fixed_factor("sys_pll1_40m", "sys_pll1_40m_cg", 1, 20); - hws[IMX8MN_SYS_PLL1_80M] = imx_clk_hw_fixed_factor("sys_pll1_80m", "sys_pll1_80m_cg", 1, 10); - hws[IMX8MN_SYS_PLL1_100M] = imx_clk_hw_fixed_factor("sys_pll1_100m", "sys_pll1_100m_cg", 1, 8); - hws[IMX8MN_SYS_PLL1_133M] = imx_clk_hw_fixed_factor("sys_pll1_133m", "sys_pll1_133m_cg", 1, 6); - hws[IMX8MN_SYS_PLL1_160M] = imx_clk_hw_fixed_factor("sys_pll1_160m", "sys_pll1_160m_cg", 1, 5); - hws[IMX8MN_SYS_PLL1_200M] = imx_clk_hw_fixed_factor("sys_pll1_200m", "sys_pll1_200m_cg", 1, 4); - hws[IMX8MN_SYS_PLL1_266M] = imx_clk_hw_fixed_factor("sys_pll1_266m", "sys_pll1_266m_cg", 1, 3); - hws[IMX8MN_SYS_PLL1_400M] = imx_clk_hw_fixed_factor("sys_pll1_400m", "sys_pll1_400m_cg", 1, 2); + hws[IMX8MN_SYS_PLL1_40M] = imx_clk_hw_fixed_factor("sys_pll1_40m", "sys_pll1_out", 1, 20); + hws[IMX8MN_SYS_PLL1_80M] = imx_clk_hw_fixed_factor("sys_pll1_80m", "sys_pll1_out", 1, 10); + hws[IMX8MN_SYS_PLL1_100M] = imx_clk_hw_fixed_factor("sys_pll1_100m", "sys_pll1_out", 1, 8); + hws[IMX8MN_SYS_PLL1_133M] = imx_clk_hw_fixed_factor("sys_pll1_133m", "sys_pll1_out", 1, 6); + hws[IMX8MN_SYS_PLL1_160M] = imx_clk_hw_fixed_factor("sys_pll1_160m", "sys_pll1_out", 1, 5); + hws[IMX8MN_SYS_PLL1_200M] = imx_clk_hw_fixed_factor("sys_pll1_200m", "sys_pll1_out", 1, 4); + hws[IMX8MN_SYS_PLL1_266M] = imx_clk_hw_fixed_factor("sys_pll1_266m", "sys_pll1_out", 1, 3); + hws[IMX8MN_SYS_PLL1_400M] = imx_clk_hw_fixed_factor("sys_pll1_400m", "sys_pll1_out", 1, 2); hws[IMX8MN_SYS_PLL1_800M] = imx_clk_hw_fixed_factor("sys_pll1_800m", "sys_pll1_out", 1, 1); /* SYS PLL2 fixed output */ - hws[IMX8MN_SYS_PLL2_50M_CG] = imx_clk_hw_gate("sys_pll2_50m_cg", "sys_pll2", base + 0x104, 27); - hws[IMX8MN_SYS_PLL2_100M_CG] = imx_clk_hw_gate("sys_pll2_100m_cg", "sys_pll2", base + 0x104, 25); - hws[IMX8MN_SYS_PLL2_125M_CG] = imx_clk_hw_gate("sys_pll2_125m_cg", "sys_pll2", base + 0x104, 23); - hws[IMX8MN_SYS_PLL2_166M_CG] = imx_clk_hw_gate("sys_pll2_166m_cg", "sys_pll2", base + 0x104, 21); - hws[IMX8MN_SYS_PLL2_200M_CG] = imx_clk_hw_gate("sys_pll2_200m_cg", "sys_pll2", base + 0x104, 19); - hws[IMX8MN_SYS_PLL2_250M_CG] = imx_clk_hw_gate("sys_pll2_250m_cg", "sys_pll2", base + 0x104, 17); - hws[IMX8MN_SYS_PLL2_333M_CG] = imx_clk_hw_gate("sys_pll2_333m_cg", "sys_pll2", base + 0x104, 15); - hws[IMX8MN_SYS_PLL2_500M_CG] = imx_clk_hw_gate("sys_pll2_500m_cg", "sys_pll2", base + 0x104, 13); hws[IMX8MN_SYS_PLL2_OUT] = imx_clk_hw_gate("sys_pll2_out", "sys_pll2", base + 0x104, 11); - - hws[IMX8MN_SYS_PLL2_50M] = imx_clk_hw_fixed_factor("sys_pll2_50m", "sys_pll2_50m_cg", 1, 20); - hws[IMX8MN_SYS_PLL2_100M] = imx_clk_hw_fixed_factor("sys_pll2_100m", "sys_pll2_100m_cg", 1, 10); - hws[IMX8MN_SYS_PLL2_125M] = imx_clk_hw_fixed_factor("sys_pll2_125m", "sys_pll2_125m_cg", 1, 8); - hws[IMX8MN_SYS_PLL2_166M] = imx_clk_hw_fixed_factor("sys_pll2_166m", "sys_pll2_166m_cg", 1, 6); - hws[IMX8MN_SYS_PLL2_200M] = imx_clk_hw_fixed_factor("sys_pll2_200m", "sys_pll2_200m_cg", 1, 5); - hws[IMX8MN_SYS_PLL2_250M] = imx_clk_hw_fixed_factor("sys_pll2_250m", "sys_pll2_250m_cg", 1, 4); - hws[IMX8MN_SYS_PLL2_333M] = imx_clk_hw_fixed_factor("sys_pll2_333m", "sys_pll2_333m_cg", 1, 3); - hws[IMX8MN_SYS_PLL2_500M] = imx_clk_hw_fixed_factor("sys_pll2_500m", "sys_pll2_500m_cg", 1, 2); + hws[IMX8MN_SYS_PLL2_50M] = imx_clk_hw_fixed_factor("sys_pll2_50m", "sys_pll2_out", 1, 20); + hws[IMX8MN_SYS_PLL2_100M] = imx_clk_hw_fixed_factor("sys_pll2_100m", "sys_pll2_out", 1, 10); + hws[IMX8MN_SYS_PLL2_125M] = imx_clk_hw_fixed_factor("sys_pll2_125m", "sys_pll2_out", 1, 8); + hws[IMX8MN_SYS_PLL2_166M] = imx_clk_hw_fixed_factor("sys_pll2_166m", "sys_pll2_out", 1, 6); + hws[IMX8MN_SYS_PLL2_200M] = imx_clk_hw_fixed_factor("sys_pll2_200m", "sys_pll2_out", 1, 5); + hws[IMX8MN_SYS_PLL2_250M] = imx_clk_hw_fixed_factor("sys_pll2_250m", "sys_pll2_out", 1, 4); + hws[IMX8MN_SYS_PLL2_333M] = imx_clk_hw_fixed_factor("sys_pll2_333m", "sys_pll2_out", 1, 3); + hws[IMX8MN_SYS_PLL2_500M] = imx_clk_hw_fixed_factor("sys_pll2_500m", "sys_pll2_out", 1, 2); hws[IMX8MN_SYS_PLL2_1000M] = imx_clk_hw_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1); hws[IMX8MN_CLK_CLKOUT1_SEL] = imx_clk_hw_mux2("clkout1_sel", base + 0x128, 4, 4, clkout_sels, ARRAY_SIZE(clkout_sels)); From d097cc045b64948ca3048ced4a43cc74eaf641a5 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Fri, 25 Feb 2022 16:17:33 +0800 Subject: [PATCH 31/43] clk: imx8mp: remove SYS PLL 1/2 clock gates Remove the PLL 1/2 gates as it make AMP clock management harder without obvious benifit. Signed-off-by: Peng Fan Reviewed-by: Abel Vesa Link: https://lore.kernel.org/r/20220225081733.2294166-4-peng.fan@oss.nxp.com Signed-off-by: Abel Vesa --- drivers/clk/imx/clk-imx8mp.c | 48 ++++++++++++------------------------ 1 file changed, 16 insertions(+), 32 deletions(-) diff --git a/drivers/clk/imx/clk-imx8mp.c b/drivers/clk/imx/clk-imx8mp.c index f23b92906d3bf..18f5b7c3ca9d8 100644 --- a/drivers/clk/imx/clk-imx8mp.c +++ b/drivers/clk/imx/clk-imx8mp.c @@ -480,44 +480,28 @@ static int imx8mp_clocks_probe(struct platform_device *pdev) hws[IMX8MP_ARM_PLL_OUT] = imx_clk_hw_gate("arm_pll_out", "arm_pll_bypass", anatop_base + 0x84, 11); hws[IMX8MP_SYS_PLL3_OUT] = imx_clk_hw_gate("sys_pll3_out", "sys_pll3_bypass", anatop_base + 0x114, 11); - hws[IMX8MP_SYS_PLL1_40M_CG] = imx_clk_hw_gate("sys_pll1_40m_cg", "sys_pll1_bypass", anatop_base + 0x94, 27); - hws[IMX8MP_SYS_PLL1_80M_CG] = imx_clk_hw_gate("sys_pll1_80m_cg", "sys_pll1_bypass", anatop_base + 0x94, 25); - hws[IMX8MP_SYS_PLL1_100M_CG] = imx_clk_hw_gate("sys_pll1_100m_cg", "sys_pll1_bypass", anatop_base + 0x94, 23); - hws[IMX8MP_SYS_PLL1_133M_CG] = imx_clk_hw_gate("sys_pll1_133m_cg", "sys_pll1_bypass", anatop_base + 0x94, 21); - hws[IMX8MP_SYS_PLL1_160M_CG] = imx_clk_hw_gate("sys_pll1_160m_cg", "sys_pll1_bypass", anatop_base + 0x94, 19); - hws[IMX8MP_SYS_PLL1_200M_CG] = imx_clk_hw_gate("sys_pll1_200m_cg", "sys_pll1_bypass", anatop_base + 0x94, 17); - hws[IMX8MP_SYS_PLL1_266M_CG] = imx_clk_hw_gate("sys_pll1_266m_cg", "sys_pll1_bypass", anatop_base + 0x94, 15); - hws[IMX8MP_SYS_PLL1_400M_CG] = imx_clk_hw_gate("sys_pll1_400m_cg", "sys_pll1_bypass", anatop_base + 0x94, 13); hws[IMX8MP_SYS_PLL1_OUT] = imx_clk_hw_gate("sys_pll1_out", "sys_pll1_bypass", anatop_base + 0x94, 11); - hws[IMX8MP_SYS_PLL1_40M] = imx_clk_hw_fixed_factor("sys_pll1_40m", "sys_pll1_40m_cg", 1, 20); - hws[IMX8MP_SYS_PLL1_80M] = imx_clk_hw_fixed_factor("sys_pll1_80m", "sys_pll1_80m_cg", 1, 10); - hws[IMX8MP_SYS_PLL1_100M] = imx_clk_hw_fixed_factor("sys_pll1_100m", "sys_pll1_100m_cg", 1, 8); - hws[IMX8MP_SYS_PLL1_133M] = imx_clk_hw_fixed_factor("sys_pll1_133m", "sys_pll1_133m_cg", 1, 6); - hws[IMX8MP_SYS_PLL1_160M] = imx_clk_hw_fixed_factor("sys_pll1_160m", "sys_pll1_160m_cg", 1, 5); - hws[IMX8MP_SYS_PLL1_200M] = imx_clk_hw_fixed_factor("sys_pll1_200m", "sys_pll1_200m_cg", 1, 4); - hws[IMX8MP_SYS_PLL1_266M] = imx_clk_hw_fixed_factor("sys_pll1_266m", "sys_pll1_266m_cg", 1, 3); - hws[IMX8MP_SYS_PLL1_400M] = imx_clk_hw_fixed_factor("sys_pll1_400m", "sys_pll1_400m_cg", 1, 2); + hws[IMX8MP_SYS_PLL1_40M] = imx_clk_hw_fixed_factor("sys_pll1_40m", "sys_pll1_out", 1, 20); + hws[IMX8MP_SYS_PLL1_80M] = imx_clk_hw_fixed_factor("sys_pll1_80m", "sys_pll1_out", 1, 10); + hws[IMX8MP_SYS_PLL1_100M] = imx_clk_hw_fixed_factor("sys_pll1_100m", "sys_pll1_out", 1, 8); + hws[IMX8MP_SYS_PLL1_133M] = imx_clk_hw_fixed_factor("sys_pll1_133m", "sys_pll1_out", 1, 6); + hws[IMX8MP_SYS_PLL1_160M] = imx_clk_hw_fixed_factor("sys_pll1_160m", "sys_pll1_out", 1, 5); + hws[IMX8MP_SYS_PLL1_200M] = imx_clk_hw_fixed_factor("sys_pll1_200m", "sys_pll1_out", 1, 4); + hws[IMX8MP_SYS_PLL1_266M] = imx_clk_hw_fixed_factor("sys_pll1_266m", "sys_pll1_out", 1, 3); + hws[IMX8MP_SYS_PLL1_400M] = imx_clk_hw_fixed_factor("sys_pll1_400m", "sys_pll1_out", 1, 2); hws[IMX8MP_SYS_PLL1_800M] = imx_clk_hw_fixed_factor("sys_pll1_800m", "sys_pll1_out", 1, 1); - hws[IMX8MP_SYS_PLL2_50M_CG] = imx_clk_hw_gate("sys_pll2_50m_cg", "sys_pll2_bypass", anatop_base + 0x104, 27); - hws[IMX8MP_SYS_PLL2_100M_CG] = imx_clk_hw_gate("sys_pll2_100m_cg", "sys_pll2_bypass", anatop_base + 0x104, 25); - hws[IMX8MP_SYS_PLL2_125M_CG] = imx_clk_hw_gate("sys_pll2_125m_cg", "sys_pll2_bypass", anatop_base + 0x104, 23); - hws[IMX8MP_SYS_PLL2_166M_CG] = imx_clk_hw_gate("sys_pll2_166m_cg", "sys_pll2_bypass", anatop_base + 0x104, 21); - hws[IMX8MP_SYS_PLL2_200M_CG] = imx_clk_hw_gate("sys_pll2_200m_cg", "sys_pll2_bypass", anatop_base + 0x104, 19); - hws[IMX8MP_SYS_PLL2_250M_CG] = imx_clk_hw_gate("sys_pll2_250m_cg", "sys_pll2_bypass", anatop_base + 0x104, 17); - hws[IMX8MP_SYS_PLL2_333M_CG] = imx_clk_hw_gate("sys_pll2_333m_cg", "sys_pll2_bypass", anatop_base + 0x104, 15); - hws[IMX8MP_SYS_PLL2_500M_CG] = imx_clk_hw_gate("sys_pll2_500m_cg", "sys_pll2_bypass", anatop_base + 0x104, 13); hws[IMX8MP_SYS_PLL2_OUT] = imx_clk_hw_gate("sys_pll2_out", "sys_pll2_bypass", anatop_base + 0x104, 11); - hws[IMX8MP_SYS_PLL2_50M] = imx_clk_hw_fixed_factor("sys_pll2_50m", "sys_pll2_50m_cg", 1, 20); - hws[IMX8MP_SYS_PLL2_100M] = imx_clk_hw_fixed_factor("sys_pll2_100m", "sys_pll2_100m_cg", 1, 10); - hws[IMX8MP_SYS_PLL2_125M] = imx_clk_hw_fixed_factor("sys_pll2_125m", "sys_pll2_125m_cg", 1, 8); - hws[IMX8MP_SYS_PLL2_166M] = imx_clk_hw_fixed_factor("sys_pll2_166m", "sys_pll2_166m_cg", 1, 6); - hws[IMX8MP_SYS_PLL2_200M] = imx_clk_hw_fixed_factor("sys_pll2_200m", "sys_pll2_200m_cg", 1, 5); - hws[IMX8MP_SYS_PLL2_250M] = imx_clk_hw_fixed_factor("sys_pll2_250m", "sys_pll2_250m_cg", 1, 4); - hws[IMX8MP_SYS_PLL2_333M] = imx_clk_hw_fixed_factor("sys_pll2_333m", "sys_pll2_333m_cg", 1, 3); - hws[IMX8MP_SYS_PLL2_500M] = imx_clk_hw_fixed_factor("sys_pll2_500m", "sys_pll2_500m_cg", 1, 2); + hws[IMX8MP_SYS_PLL2_50M] = imx_clk_hw_fixed_factor("sys_pll2_50m", "sys_pll2_out", 1, 20); + hws[IMX8MP_SYS_PLL2_100M] = imx_clk_hw_fixed_factor("sys_pll2_100m", "sys_pll2_out", 1, 10); + hws[IMX8MP_SYS_PLL2_125M] = imx_clk_hw_fixed_factor("sys_pll2_125m", "sys_pll2_out", 1, 8); + hws[IMX8MP_SYS_PLL2_166M] = imx_clk_hw_fixed_factor("sys_pll2_166m", "sys_pll2_out", 1, 6); + hws[IMX8MP_SYS_PLL2_200M] = imx_clk_hw_fixed_factor("sys_pll2_200m", "sys_pll2_out", 1, 5); + hws[IMX8MP_SYS_PLL2_250M] = imx_clk_hw_fixed_factor("sys_pll2_250m", "sys_pll2_out", 1, 4); + hws[IMX8MP_SYS_PLL2_333M] = imx_clk_hw_fixed_factor("sys_pll2_333m", "sys_pll2_out", 1, 3); + hws[IMX8MP_SYS_PLL2_500M] = imx_clk_hw_fixed_factor("sys_pll2_500m", "sys_pll2_out", 1, 2); hws[IMX8MP_SYS_PLL2_1000M] = imx_clk_hw_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1); hws[IMX8MP_CLK_A53_DIV] = imx8m_clk_hw_composite_core("arm_a53_div", imx8mp_a53_sels, ccm_base + 0x8000); From 485b4ff57c2777c15bfe2e6e6a204200b040e131 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 4 Mar 2022 13:52:49 +0100 Subject: [PATCH 32/43] clk: imx: pll14xx: Use register defines consistently The driver has defines for the registers, but they are mostly unused. Use the defines consistently throughout the driver. While at it rename DIV_CTL to DIV_CTL0 because that's the name in the reference manual. Signed-off-by: Sascha Hauer Reviewed-by: Abel Vesa Link: https://lore.kernel.org/r/20220304125256.2125023-2-s.hauer@pengutronix.de Signed-off-by: Abel Vesa --- drivers/clk/imx/clk-pll14xx.c | 49 ++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c index 2b5ed86b9dbbb..cae64d750672e 100644 --- a/drivers/clk/imx/clk-pll14xx.c +++ b/drivers/clk/imx/clk-pll14xx.c @@ -15,7 +15,8 @@ #include "clk.h" #define GNRL_CTL 0x0 -#define DIV_CTL 0x4 +#define DIV_CTL0 0x4 +#define DIV_CTL1 0x8 #define LOCK_STATUS BIT(31) #define LOCK_SEL_MASK BIT(29) #define CLKE_MASK BIT(11) @@ -122,7 +123,7 @@ static unsigned long clk_pll1416x_recalc_rate(struct clk_hw *hw, u32 mdiv, pdiv, sdiv, pll_div; u64 fvco = parent_rate; - pll_div = readl_relaxed(pll->base + 4); + pll_div = readl_relaxed(pll->base + DIV_CTL0); mdiv = (pll_div & MDIV_MASK) >> MDIV_SHIFT; pdiv = (pll_div & PDIV_MASK) >> PDIV_SHIFT; sdiv = (pll_div & SDIV_MASK) >> SDIV_SHIFT; @@ -141,8 +142,8 @@ static unsigned long clk_pll1443x_recalc_rate(struct clk_hw *hw, short int kdiv; u64 fvco = parent_rate; - pll_div_ctl0 = readl_relaxed(pll->base + 4); - pll_div_ctl1 = readl_relaxed(pll->base + 8); + pll_div_ctl0 = readl_relaxed(pll->base + DIV_CTL0); + pll_div_ctl1 = readl_relaxed(pll->base + DIV_CTL1); mdiv = (pll_div_ctl0 & MDIV_MASK) >> MDIV_SHIFT; pdiv = (pll_div_ctl0 & PDIV_MASK) >> PDIV_SHIFT; sdiv = (pll_div_ctl0 & SDIV_MASK) >> SDIV_SHIFT; @@ -172,7 +173,7 @@ static int clk_pll14xx_wait_lock(struct clk_pll14xx *pll) { u32 val; - return readl_poll_timeout(pll->base, val, val & LOCK_STATUS, 0, + return readl_poll_timeout(pll->base + GNRL_CTL, val, val & LOCK_STATUS, 0, LOCK_TIMEOUT_US); } @@ -191,32 +192,32 @@ static int clk_pll1416x_set_rate(struct clk_hw *hw, unsigned long drate, return -EINVAL; } - tmp = readl_relaxed(pll->base + 4); + tmp = readl_relaxed(pll->base + DIV_CTL0); if (!clk_pll14xx_mp_change(rate, tmp)) { tmp &= ~(SDIV_MASK) << SDIV_SHIFT; tmp |= rate->sdiv << SDIV_SHIFT; - writel_relaxed(tmp, pll->base + 4); + writel_relaxed(tmp, pll->base + DIV_CTL0); return 0; } /* Bypass clock and set lock to pll output lock */ - tmp = readl_relaxed(pll->base); + tmp = readl_relaxed(pll->base + GNRL_CTL); tmp |= LOCK_SEL_MASK; - writel_relaxed(tmp, pll->base); + writel_relaxed(tmp, pll->base + GNRL_CTL); /* Enable RST */ tmp &= ~RST_MASK; - writel_relaxed(tmp, pll->base); + writel_relaxed(tmp, pll->base + GNRL_CTL); /* Enable BYPASS */ tmp |= BYPASS_MASK; - writel(tmp, pll->base); + writel(tmp, pll->base + GNRL_CTL); div_val = (rate->mdiv << MDIV_SHIFT) | (rate->pdiv << PDIV_SHIFT) | (rate->sdiv << SDIV_SHIFT); - writel_relaxed(div_val, pll->base + 0x4); + writel_relaxed(div_val, pll->base + DIV_CTL0); /* * According to SPEC, t3 - t2 need to be greater than @@ -228,7 +229,7 @@ static int clk_pll1416x_set_rate(struct clk_hw *hw, unsigned long drate, /* Disable RST */ tmp |= RST_MASK; - writel_relaxed(tmp, pll->base); + writel_relaxed(tmp, pll->base + GNRL_CTL); /* Wait Lock */ ret = clk_pll14xx_wait_lock(pll); @@ -237,7 +238,7 @@ static int clk_pll1416x_set_rate(struct clk_hw *hw, unsigned long drate, /* Bypass */ tmp &= ~BYPASS_MASK; - writel_relaxed(tmp, pll->base); + writel_relaxed(tmp, pll->base + GNRL_CTL); return 0; } @@ -257,32 +258,32 @@ static int clk_pll1443x_set_rate(struct clk_hw *hw, unsigned long drate, return -EINVAL; } - tmp = readl_relaxed(pll->base + 4); + tmp = readl_relaxed(pll->base + DIV_CTL0); if (!clk_pll14xx_mp_change(rate, tmp)) { tmp &= ~(SDIV_MASK) << SDIV_SHIFT; tmp |= rate->sdiv << SDIV_SHIFT; - writel_relaxed(tmp, pll->base + 4); + writel_relaxed(tmp, pll->base + DIV_CTL0); tmp = rate->kdiv << KDIV_SHIFT; - writel_relaxed(tmp, pll->base + 8); + writel_relaxed(tmp, pll->base + DIV_CTL1); return 0; } /* Enable RST */ - tmp = readl_relaxed(pll->base); + tmp = readl_relaxed(pll->base + GNRL_CTL); tmp &= ~RST_MASK; - writel_relaxed(tmp, pll->base); + writel_relaxed(tmp, pll->base + GNRL_CTL); /* Enable BYPASS */ tmp |= BYPASS_MASK; - writel_relaxed(tmp, pll->base); + writel_relaxed(tmp, pll->base + GNRL_CTL); div_val = (rate->mdiv << MDIV_SHIFT) | (rate->pdiv << PDIV_SHIFT) | (rate->sdiv << SDIV_SHIFT); - writel_relaxed(div_val, pll->base + 0x4); - writel_relaxed(rate->kdiv << KDIV_SHIFT, pll->base + 0x8); + writel_relaxed(div_val, pll->base + DIV_CTL0); + writel_relaxed(rate->kdiv << KDIV_SHIFT, pll->base + DIV_CTL1); /* * According to SPEC, t3 - t2 need to be greater than @@ -294,7 +295,7 @@ static int clk_pll1443x_set_rate(struct clk_hw *hw, unsigned long drate, /* Disable RST */ tmp |= RST_MASK; - writel_relaxed(tmp, pll->base); + writel_relaxed(tmp, pll->base + GNRL_CTL); /* Wait Lock*/ ret = clk_pll14xx_wait_lock(pll); @@ -303,7 +304,7 @@ static int clk_pll1443x_set_rate(struct clk_hw *hw, unsigned long drate, /* Bypass */ tmp &= ~BYPASS_MASK; - writel_relaxed(tmp, pll->base); + writel_relaxed(tmp, pll->base + GNRL_CTL); return 0; } From d77461a616b659bd88dc153e3a86dba5bf78aa8a Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 4 Mar 2022 13:52:50 +0100 Subject: [PATCH 33/43] clk: imx: pll14xx: Drop wrong shifting The code tries to mask the bits in SDIV_MASK from 'tmp'. SDIV_MASK already contains the shifted value, so shifting it again is wrong. No functional change though as SDIV_SHIFT is zero. Signed-off-by: Sascha Hauer Reviewed-by: Abel Vesa Link: https://lore.kernel.org/r/20220304125256.2125023-3-s.hauer@pengutronix.de Signed-off-by: Abel Vesa --- drivers/clk/imx/clk-pll14xx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c index cae64d750672e..b295d8a049009 100644 --- a/drivers/clk/imx/clk-pll14xx.c +++ b/drivers/clk/imx/clk-pll14xx.c @@ -195,7 +195,7 @@ static int clk_pll1416x_set_rate(struct clk_hw *hw, unsigned long drate, tmp = readl_relaxed(pll->base + DIV_CTL0); if (!clk_pll14xx_mp_change(rate, tmp)) { - tmp &= ~(SDIV_MASK) << SDIV_SHIFT; + tmp &= ~SDIV_MASK; tmp |= rate->sdiv << SDIV_SHIFT; writel_relaxed(tmp, pll->base + DIV_CTL0); @@ -261,7 +261,7 @@ static int clk_pll1443x_set_rate(struct clk_hw *hw, unsigned long drate, tmp = readl_relaxed(pll->base + DIV_CTL0); if (!clk_pll14xx_mp_change(rate, tmp)) { - tmp &= ~(SDIV_MASK) << SDIV_SHIFT; + tmp &= ~SDIV_MASK; tmp |= rate->sdiv << SDIV_SHIFT; writel_relaxed(tmp, pll->base + DIV_CTL0); From 58f4980ccbecf633df1fcb113e2a9f04842eccc6 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 4 Mar 2022 13:52:51 +0100 Subject: [PATCH 34/43] clk: imx: pll14xx: Use FIELD_GET/FIELD_PREP Linux has these marvelous FIELD_GET/FIELD_PREP macros for easy access to bitfields in registers. Use them and remove the now unused *_SHIFT defines. Signed-off-by: Sascha Hauer Reviewed-by: Abel Vesa Link: https://lore.kernel.org/r/20220304125256.2125023-4-s.hauer@pengutronix.de Signed-off-by: Abel Vesa --- drivers/clk/imx/clk-pll14xx.c | 40 +++++++++++++++++------------------ 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c index b295d8a049009..fabb380b87305 100644 --- a/drivers/clk/imx/clk-pll14xx.c +++ b/drivers/clk/imx/clk-pll14xx.c @@ -3,6 +3,7 @@ * Copyright 2017-2018 NXP. */ +#include #include #include #include @@ -22,13 +23,9 @@ #define CLKE_MASK BIT(11) #define RST_MASK BIT(9) #define BYPASS_MASK BIT(4) -#define MDIV_SHIFT 12 #define MDIV_MASK GENMASK(21, 12) -#define PDIV_SHIFT 4 #define PDIV_MASK GENMASK(9, 4) -#define SDIV_SHIFT 0 #define SDIV_MASK GENMASK(2, 0) -#define KDIV_SHIFT 0 #define KDIV_MASK GENMASK(15, 0) #define LOCK_TIMEOUT_US 10000 @@ -124,9 +121,9 @@ static unsigned long clk_pll1416x_recalc_rate(struct clk_hw *hw, u64 fvco = parent_rate; pll_div = readl_relaxed(pll->base + DIV_CTL0); - mdiv = (pll_div & MDIV_MASK) >> MDIV_SHIFT; - pdiv = (pll_div & PDIV_MASK) >> PDIV_SHIFT; - sdiv = (pll_div & SDIV_MASK) >> SDIV_SHIFT; + mdiv = FIELD_GET(MDIV_MASK, pll_div); + pdiv = FIELD_GET(PDIV_MASK, pll_div); + sdiv = FIELD_GET(SDIV_MASK, pll_div); fvco *= mdiv; do_div(fvco, pdiv << sdiv); @@ -144,10 +141,10 @@ static unsigned long clk_pll1443x_recalc_rate(struct clk_hw *hw, pll_div_ctl0 = readl_relaxed(pll->base + DIV_CTL0); pll_div_ctl1 = readl_relaxed(pll->base + DIV_CTL1); - mdiv = (pll_div_ctl0 & MDIV_MASK) >> MDIV_SHIFT; - pdiv = (pll_div_ctl0 & PDIV_MASK) >> PDIV_SHIFT; - sdiv = (pll_div_ctl0 & SDIV_MASK) >> SDIV_SHIFT; - kdiv = pll_div_ctl1 & KDIV_MASK; + mdiv = FIELD_GET(MDIV_MASK, pll_div_ctl0); + pdiv = FIELD_GET(PDIV_MASK, pll_div_ctl0); + sdiv = FIELD_GET(SDIV_MASK, pll_div_ctl0); + kdiv = FIELD_GET(KDIV_MASK, pll_div_ctl1); /* fvco = (m * 65536 + k) * Fin / (p * 65536) */ fvco *= (mdiv * 65536 + kdiv); @@ -163,8 +160,8 @@ static inline bool clk_pll14xx_mp_change(const struct imx_pll14xx_rate_table *ra { u32 old_mdiv, old_pdiv; - old_mdiv = (pll_div & MDIV_MASK) >> MDIV_SHIFT; - old_pdiv = (pll_div & PDIV_MASK) >> PDIV_SHIFT; + old_mdiv = FIELD_GET(MDIV_MASK, pll_div); + old_pdiv = FIELD_GET(PDIV_MASK, pll_div); return rate->mdiv != old_mdiv || rate->pdiv != old_pdiv; } @@ -196,7 +193,7 @@ static int clk_pll1416x_set_rate(struct clk_hw *hw, unsigned long drate, if (!clk_pll14xx_mp_change(rate, tmp)) { tmp &= ~SDIV_MASK; - tmp |= rate->sdiv << SDIV_SHIFT; + tmp |= FIELD_PREP(SDIV_MASK, rate->sdiv); writel_relaxed(tmp, pll->base + DIV_CTL0); return 0; @@ -215,8 +212,8 @@ static int clk_pll1416x_set_rate(struct clk_hw *hw, unsigned long drate, tmp |= BYPASS_MASK; writel(tmp, pll->base + GNRL_CTL); - div_val = (rate->mdiv << MDIV_SHIFT) | (rate->pdiv << PDIV_SHIFT) | - (rate->sdiv << SDIV_SHIFT); + div_val = FIELD_PREP(MDIV_MASK, rate->mdiv) | FIELD_PREP(PDIV_MASK, rate->pdiv) | + FIELD_PREP(SDIV_MASK, rate->sdiv); writel_relaxed(div_val, pll->base + DIV_CTL0); /* @@ -262,10 +259,10 @@ static int clk_pll1443x_set_rate(struct clk_hw *hw, unsigned long drate, if (!clk_pll14xx_mp_change(rate, tmp)) { tmp &= ~SDIV_MASK; - tmp |= rate->sdiv << SDIV_SHIFT; + tmp |= FIELD_PREP(SDIV_MASK, rate->sdiv); writel_relaxed(tmp, pll->base + DIV_CTL0); - tmp = rate->kdiv << KDIV_SHIFT; + tmp = FIELD_PREP(KDIV_MASK, rate->kdiv); writel_relaxed(tmp, pll->base + DIV_CTL1); return 0; @@ -280,10 +277,11 @@ static int clk_pll1443x_set_rate(struct clk_hw *hw, unsigned long drate, tmp |= BYPASS_MASK; writel_relaxed(tmp, pll->base + GNRL_CTL); - div_val = (rate->mdiv << MDIV_SHIFT) | (rate->pdiv << PDIV_SHIFT) | - (rate->sdiv << SDIV_SHIFT); + div_val = FIELD_PREP(MDIV_MASK, rate->mdiv) | + FIELD_PREP(PDIV_MASK, rate->pdiv) | + FIELD_PREP(SDIV_MASK, rate->sdiv); writel_relaxed(div_val, pll->base + DIV_CTL0); - writel_relaxed(rate->kdiv << KDIV_SHIFT, pll->base + DIV_CTL1); + writel_relaxed(FIELD_PREP(KDIV_MASK, rate->kdiv), pll->base + DIV_CTL1); /* * According to SPEC, t3 - t2 need to be greater than From 53990cf9d5b489fc0ec08e5c4df7139fc311a824 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 4 Mar 2022 13:52:52 +0100 Subject: [PATCH 35/43] clk: imx: pll14xx: consolidate rate calculation The PLL driver has support for two different PLLs: The pll1416x and the pll1443x. The latter has support for an additional kdiv value. recalc_rate can be the same calculation when kdiv is assumed to be zero for the PLL which doesn't support that value. Signed-off-by: Sascha Hauer Reviewed-by: Abel Vesa Link: https://lore.kernel.org/r/20220304125256.2125023-5-s.hauer@pengutronix.de Signed-off-by: Abel Vesa --- drivers/clk/imx/clk-pll14xx.c | 59 +++++++++++++++-------------------- 1 file changed, 26 insertions(+), 33 deletions(-) diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c index fabb380b87305..ebd5d888fea6d 100644 --- a/drivers/clk/imx/clk-pll14xx.c +++ b/drivers/clk/imx/clk-pll14xx.c @@ -97,6 +97,20 @@ static const struct imx_pll14xx_rate_table *imx_get_pll_settings( return NULL; } +static long pll14xx_calc_rate(struct clk_pll14xx *pll, int mdiv, int pdiv, + int sdiv, int kdiv, unsigned long prate) +{ + u64 fvco = prate; + + /* fvco = (m * 65536 + k) * Fin / (p * 65536) */ + fvco *= (mdiv * 65536 + kdiv); + pdiv *= 65536; + + do_div(fvco, pdiv << sdiv); + + return fvco; +} + static long clk_pll14xx_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *prate) { @@ -113,46 +127,25 @@ static long clk_pll14xx_round_rate(struct clk_hw *hw, unsigned long rate, return rate_table[i - 1].rate; } -static unsigned long clk_pll1416x_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) -{ - struct clk_pll14xx *pll = to_clk_pll14xx(hw); - u32 mdiv, pdiv, sdiv, pll_div; - u64 fvco = parent_rate; - - pll_div = readl_relaxed(pll->base + DIV_CTL0); - mdiv = FIELD_GET(MDIV_MASK, pll_div); - pdiv = FIELD_GET(PDIV_MASK, pll_div); - sdiv = FIELD_GET(SDIV_MASK, pll_div); - - fvco *= mdiv; - do_div(fvco, pdiv << sdiv); - - return fvco; -} - -static unsigned long clk_pll1443x_recalc_rate(struct clk_hw *hw, +static unsigned long clk_pll14xx_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { struct clk_pll14xx *pll = to_clk_pll14xx(hw); - u32 mdiv, pdiv, sdiv, pll_div_ctl0, pll_div_ctl1; - short int kdiv; - u64 fvco = parent_rate; + u32 mdiv, pdiv, sdiv, kdiv, pll_div_ctl0, pll_div_ctl1; pll_div_ctl0 = readl_relaxed(pll->base + DIV_CTL0); - pll_div_ctl1 = readl_relaxed(pll->base + DIV_CTL1); mdiv = FIELD_GET(MDIV_MASK, pll_div_ctl0); pdiv = FIELD_GET(PDIV_MASK, pll_div_ctl0); sdiv = FIELD_GET(SDIV_MASK, pll_div_ctl0); - kdiv = FIELD_GET(KDIV_MASK, pll_div_ctl1); - /* fvco = (m * 65536 + k) * Fin / (p * 65536) */ - fvco *= (mdiv * 65536 + kdiv); - pdiv *= 65536; - - do_div(fvco, pdiv << sdiv); + if (pll->type == PLL_1443X) { + pll_div_ctl1 = readl_relaxed(pll->base + DIV_CTL1); + kdiv = FIELD_GET(KDIV_MASK, pll_div_ctl1); + } else { + kdiv = 0; + } - return fvco; + return pll14xx_calc_rate(pll, mdiv, pdiv, sdiv, kdiv, parent_rate); } static inline bool clk_pll14xx_mp_change(const struct imx_pll14xx_rate_table *rate, @@ -363,20 +356,20 @@ static const struct clk_ops clk_pll1416x_ops = { .prepare = clk_pll14xx_prepare, .unprepare = clk_pll14xx_unprepare, .is_prepared = clk_pll14xx_is_prepared, - .recalc_rate = clk_pll1416x_recalc_rate, + .recalc_rate = clk_pll14xx_recalc_rate, .round_rate = clk_pll14xx_round_rate, .set_rate = clk_pll1416x_set_rate, }; static const struct clk_ops clk_pll1416x_min_ops = { - .recalc_rate = clk_pll1416x_recalc_rate, + .recalc_rate = clk_pll14xx_recalc_rate, }; static const struct clk_ops clk_pll1443x_ops = { .prepare = clk_pll14xx_prepare, .unprepare = clk_pll14xx_unprepare, .is_prepared = clk_pll14xx_is_prepared, - .recalc_rate = clk_pll1443x_recalc_rate, + .recalc_rate = clk_pll14xx_recalc_rate, .round_rate = clk_pll14xx_round_rate, .set_rate = clk_pll1443x_set_rate, }; From 052d03a043afebb8e26ec17de52e8cdc8b217ef9 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 4 Mar 2022 13:52:53 +0100 Subject: [PATCH 36/43] clk: imx: pll14xx: name variables after usage In clk_pll1443x_set_rate() 'tmp' is used for the content of different registers which makes it a bit hard to follow. Use different variables named after the registers to make it clearer. No functional change intended. Signed-off-by: Sascha Hauer Reviewed-by: Abel Vesa Link: https://lore.kernel.org/r/20220304125256.2125023-6-s.hauer@pengutronix.de Signed-off-by: Abel Vesa --- drivers/clk/imx/clk-pll14xx.c | 42 +++++++++++++++++------------------ 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c index ebd5d888fea6d..b464e1155e25b 100644 --- a/drivers/clk/imx/clk-pll14xx.c +++ b/drivers/clk/imx/clk-pll14xx.c @@ -238,7 +238,7 @@ static int clk_pll1443x_set_rate(struct clk_hw *hw, unsigned long drate, { struct clk_pll14xx *pll = to_clk_pll14xx(hw); const struct imx_pll14xx_rate_table *rate; - u32 tmp, div_val; + u32 gnrl_ctl, div_ctl0; int ret; rate = imx_get_pll_settings(pll, drate); @@ -248,32 +248,32 @@ static int clk_pll1443x_set_rate(struct clk_hw *hw, unsigned long drate, return -EINVAL; } - tmp = readl_relaxed(pll->base + DIV_CTL0); + div_ctl0 = readl_relaxed(pll->base + DIV_CTL0); - if (!clk_pll14xx_mp_change(rate, tmp)) { - tmp &= ~SDIV_MASK; - tmp |= FIELD_PREP(SDIV_MASK, rate->sdiv); - writel_relaxed(tmp, pll->base + DIV_CTL0); + if (!clk_pll14xx_mp_change(rate, div_ctl0)) { + div_ctl0 &= ~SDIV_MASK; + div_ctl0 |= FIELD_PREP(SDIV_MASK, rate->sdiv); + writel_relaxed(div_ctl0, pll->base + DIV_CTL0); - tmp = FIELD_PREP(KDIV_MASK, rate->kdiv); - writel_relaxed(tmp, pll->base + DIV_CTL1); + writel_relaxed(FIELD_PREP(KDIV_MASK, rate->kdiv), + pll->base + DIV_CTL1); return 0; } /* Enable RST */ - tmp = readl_relaxed(pll->base + GNRL_CTL); - tmp &= ~RST_MASK; - writel_relaxed(tmp, pll->base + GNRL_CTL); + gnrl_ctl = readl_relaxed(pll->base + GNRL_CTL); + gnrl_ctl &= ~RST_MASK; + writel_relaxed(gnrl_ctl, pll->base + GNRL_CTL); /* Enable BYPASS */ - tmp |= BYPASS_MASK; - writel_relaxed(tmp, pll->base + GNRL_CTL); + gnrl_ctl |= BYPASS_MASK; + writel_relaxed(gnrl_ctl, pll->base + GNRL_CTL); - div_val = FIELD_PREP(MDIV_MASK, rate->mdiv) | - FIELD_PREP(PDIV_MASK, rate->pdiv) | - FIELD_PREP(SDIV_MASK, rate->sdiv); - writel_relaxed(div_val, pll->base + DIV_CTL0); + div_ctl0 = FIELD_PREP(MDIV_MASK, rate->mdiv) | + FIELD_PREP(PDIV_MASK, rate->pdiv) | + FIELD_PREP(SDIV_MASK, rate->sdiv); + writel_relaxed(div_ctl0, pll->base + DIV_CTL0); writel_relaxed(FIELD_PREP(KDIV_MASK, rate->kdiv), pll->base + DIV_CTL1); /* @@ -285,8 +285,8 @@ static int clk_pll1443x_set_rate(struct clk_hw *hw, unsigned long drate, udelay(3); /* Disable RST */ - tmp |= RST_MASK; - writel_relaxed(tmp, pll->base + GNRL_CTL); + gnrl_ctl |= RST_MASK; + writel_relaxed(gnrl_ctl, pll->base + GNRL_CTL); /* Wait Lock*/ ret = clk_pll14xx_wait_lock(pll); @@ -294,8 +294,8 @@ static int clk_pll1443x_set_rate(struct clk_hw *hw, unsigned long drate, return ret; /* Bypass */ - tmp &= ~BYPASS_MASK; - writel_relaxed(tmp, pll->base + GNRL_CTL); + gnrl_ctl &= ~BYPASS_MASK; + writel_relaxed(gnrl_ctl, pll->base + GNRL_CTL); return 0; } From 5ff50031cb8852bfcf587d003ba6bad3c2336852 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 4 Mar 2022 13:52:54 +0100 Subject: [PATCH 37/43] clk: imx: pll14xx: explicitly return lowest rate clk_pll14xx_round_rate() returns the lowest rate by indexing into the rate table with the variable i. i is actually pll->rate_count as this is the value we come out of the loop with. Use pll->rate_count explicitly to make it a bit more clear what is being done. While at it fix a typo in the comment. No functional change. Signed-off-by: Sascha Hauer Reviewed-by: Abel Vesa Link: https://lore.kernel.org/r/20220304125256.2125023-7-s.hauer@pengutronix.de Signed-off-by: Abel Vesa --- drivers/clk/imx/clk-pll14xx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c index b464e1155e25b..af4c979e70a64 100644 --- a/drivers/clk/imx/clk-pll14xx.c +++ b/drivers/clk/imx/clk-pll14xx.c @@ -118,13 +118,13 @@ static long clk_pll14xx_round_rate(struct clk_hw *hw, unsigned long rate, const struct imx_pll14xx_rate_table *rate_table = pll->rate_table; int i; - /* Assumming rate_table is in descending order */ + /* Assuming rate_table is in descending order */ for (i = 0; i < pll->rate_count; i++) if (rate >= rate_table[i].rate) return rate_table[i].rate; /* return minimum supported value */ - return rate_table[i - 1].rate; + return rate_table[pll->rate_count - 1].rate; } static unsigned long clk_pll14xx_recalc_rate(struct clk_hw *hw, From 80cbc80612a01461a257f2c2eb9976cbadfb7be2 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 4 Mar 2022 13:52:55 +0100 Subject: [PATCH 38/43] clk: imx: pll14xx: Add pr_fmt Print all messages from within the pll14xx driver with a common prefix using pr_fmt. No need to print function names anymore, so drop them from the messages. Signed-off-by: Sascha Hauer Reviewed-by: Abel Vesa Link: https://lore.kernel.org/r/20220304125256.2125023-8-s.hauer@pengutronix.de Signed-off-by: Abel Vesa --- drivers/clk/imx/clk-pll14xx.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c index af4c979e70a64..646e0ce7d6242 100644 --- a/drivers/clk/imx/clk-pll14xx.c +++ b/drivers/clk/imx/clk-pll14xx.c @@ -3,6 +3,8 @@ * Copyright 2017-2018 NXP. */ +#define pr_fmt(fmt) "pll14xx: " fmt + #include #include #include @@ -177,8 +179,8 @@ static int clk_pll1416x_set_rate(struct clk_hw *hw, unsigned long drate, rate = imx_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)); + pr_err("Invalid rate %lu for pll clk %s\n", drate, + clk_hw_get_name(hw)); return -EINVAL; } @@ -404,8 +406,7 @@ struct clk_hw *imx_dev_clk_hw_pll14xx(struct device *dev, const char *name, init.ops = &clk_pll1443x_ops; break; default: - pr_err("%s: Unknown pll type for pll clk %s\n", - __func__, name); + pr_err("Unknown pll type for pll clk %s\n", name); kfree(pll); return ERR_PTR(-EINVAL); } @@ -424,8 +425,7 @@ struct clk_hw *imx_dev_clk_hw_pll14xx(struct device *dev, const char *name, ret = clk_hw_register(dev, hw); if (ret) { - pr_err("%s: failed to register pll %s %d\n", - __func__, name, ret); + pr_err("failed to register pll %s %d\n", name, ret); kfree(pll); return ERR_PTR(ret); } From b09c68dc57c9d44071d83bb935b733f53ea2b2b4 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 4 Mar 2022 13:52:56 +0100 Subject: [PATCH 39/43] clk: imx: pll14xx: Support dynamic rates The pll1443x PLL so far only supports rates from a rate table passed during initialization. Calculating PLL settings dynamically helps audio applications to get their desired rates, so support for this is added in this patch. The strategy to get to the PLL setting for a rate is: - First try to only adjust kdiv which specifies the fractional part of the PLL. This setting can be changed without glitches on the output and is therefore preferred - When that isn't possible then the rate table is searched for suitable rates, so for standard rates the same settings are used as without this patch - As a last resort the best settings are calculated dynamically The code in this patch is based on patches from Adrian Alonso and Mads Bligaard Nielsen Signed-off-by: Sascha Hauer Reviewed-by: Abel Vesa Link: https://lore.kernel.org/r/20220304125256.2125023-9-s.hauer@pengutronix.de Signed-off-by: Abel Vesa --- drivers/clk/imx/clk-pll14xx.c | 143 ++++++++++++++++++++++++++++++---- 1 file changed, 126 insertions(+), 17 deletions(-) diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c index 646e0ce7d6242..1d0f79e9c3467 100644 --- a/drivers/clk/imx/clk-pll14xx.c +++ b/drivers/clk/imx/clk-pll14xx.c @@ -29,6 +29,8 @@ #define PDIV_MASK GENMASK(9, 4) #define SDIV_MASK GENMASK(2, 0) #define KDIV_MASK GENMASK(15, 0) +#define KDIV_MIN SHRT_MIN +#define KDIV_MAX SHRT_MAX #define LOCK_TIMEOUT_US 10000 @@ -113,7 +115,106 @@ static long pll14xx_calc_rate(struct clk_pll14xx *pll, int mdiv, int pdiv, return fvco; } -static long clk_pll14xx_round_rate(struct clk_hw *hw, unsigned long rate, +static long pll1443x_calc_kdiv(int mdiv, int pdiv, int sdiv, + unsigned long rate, unsigned long prate) +{ + long kdiv; + + /* calc kdiv = round(rate * pdiv * 65536 * 2^sdiv / prate) - (mdiv * 65536) */ + kdiv = ((rate * ((pdiv * 65536) << sdiv) + prate / 2) / prate) - (mdiv * 65536); + + return clamp_t(short, kdiv, KDIV_MIN, KDIV_MAX); +} + +static void imx_pll14xx_calc_settings(struct clk_pll14xx *pll, unsigned long rate, + unsigned long prate, struct imx_pll14xx_rate_table *t) +{ + u32 pll_div_ctl0, pll_div_ctl1; + int mdiv, pdiv, sdiv, kdiv; + long fvco, rate_min, rate_max, dist, best = LONG_MAX; + const struct imx_pll14xx_rate_table *tt; + + /* + * Fractional PLL constrains: + * + * a) 6MHz <= prate <= 25MHz + * b) 1 <= p <= 63 (1 <= p <= 4 prate = 24MHz) + * c) 64 <= m <= 1023 + * d) 0 <= s <= 6 + * e) -32768 <= k <= 32767 + * + * fvco = (m * 65536 + k) * prate / (p * 65536) + */ + + /* First try if we can get the desired rate from one of the static entries */ + tt = imx_get_pll_settings(pll, rate); + if (tt) { + pr_debug("%s: in=%ld, want=%ld, Using PLL setting from table\n", + clk_hw_get_name(&pll->hw), prate, rate); + t->rate = tt->rate; + t->mdiv = tt->mdiv; + t->pdiv = tt->pdiv; + t->sdiv = tt->sdiv; + t->kdiv = tt->kdiv; + return; + } + + pll_div_ctl0 = readl_relaxed(pll->base + DIV_CTL0); + mdiv = FIELD_GET(MDIV_MASK, pll_div_ctl0); + pdiv = FIELD_GET(PDIV_MASK, pll_div_ctl0); + sdiv = FIELD_GET(SDIV_MASK, pll_div_ctl0); + pll_div_ctl1 = readl_relaxed(pll->base + DIV_CTL1); + + /* Then see if we can get the desired rate by only adjusting kdiv (glitch free) */ + rate_min = pll14xx_calc_rate(pll, mdiv, pdiv, sdiv, KDIV_MIN, prate); + rate_max = pll14xx_calc_rate(pll, mdiv, pdiv, sdiv, KDIV_MAX, prate); + + if (rate >= rate_min && rate <= rate_max) { + kdiv = pll1443x_calc_kdiv(mdiv, pdiv, sdiv, rate, prate); + pr_debug("%s: in=%ld, want=%ld Only adjust kdiv %ld -> %d\n", + clk_hw_get_name(&pll->hw), prate, rate, + FIELD_GET(KDIV_MASK, pll_div_ctl1), kdiv); + fvco = pll14xx_calc_rate(pll, mdiv, pdiv, sdiv, kdiv, prate); + t->rate = (unsigned int)fvco; + t->mdiv = mdiv; + t->pdiv = pdiv; + t->sdiv = sdiv; + t->kdiv = kdiv; + return; + } + + /* Finally calculate best values */ + for (pdiv = 1; pdiv <= 7; pdiv++) { + for (sdiv = 0; sdiv <= 6; sdiv++) { + /* calc mdiv = round(rate * pdiv * 2^sdiv) / prate) */ + mdiv = DIV_ROUND_CLOSEST(rate * (pdiv << sdiv), prate); + mdiv = clamp(mdiv, 64, 1023); + + kdiv = pll1443x_calc_kdiv(mdiv, pdiv, sdiv, rate, prate); + fvco = pll14xx_calc_rate(pll, mdiv, pdiv, sdiv, kdiv, prate); + + /* best match */ + dist = abs((long)rate - (long)fvco); + if (dist < best) { + best = dist; + t->rate = (unsigned int)fvco; + t->mdiv = mdiv; + t->pdiv = pdiv; + t->sdiv = sdiv; + t->kdiv = kdiv; + + if (!dist) + goto found; + } + } + } +found: + pr_debug("%s: in=%ld, want=%ld got=%d (pdiv=%d sdiv=%d mdiv=%d kdiv=%d)\n", + clk_hw_get_name(&pll->hw), prate, rate, t->rate, t->pdiv, t->sdiv, + t->mdiv, t->kdiv); +} + +static long clk_pll1416x_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *prate) { struct clk_pll14xx *pll = to_clk_pll14xx(hw); @@ -129,6 +230,17 @@ static long clk_pll14xx_round_rate(struct clk_hw *hw, unsigned long rate, return rate_table[pll->rate_count - 1].rate; } +static long clk_pll1443x_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *prate) +{ + struct clk_pll14xx *pll = to_clk_pll14xx(hw); + struct imx_pll14xx_rate_table t; + + imx_pll14xx_calc_settings(pll, rate, *prate, &t); + + return t.rate; +} + static unsigned long clk_pll14xx_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { @@ -239,25 +351,21 @@ static int clk_pll1443x_set_rate(struct clk_hw *hw, unsigned long drate, unsigned long prate) { struct clk_pll14xx *pll = to_clk_pll14xx(hw); - const struct imx_pll14xx_rate_table *rate; + struct imx_pll14xx_rate_table rate; u32 gnrl_ctl, div_ctl0; int ret; - rate = imx_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; - } + imx_pll14xx_calc_settings(pll, drate, prate, &rate); div_ctl0 = readl_relaxed(pll->base + DIV_CTL0); - if (!clk_pll14xx_mp_change(rate, div_ctl0)) { + if (!clk_pll14xx_mp_change(&rate, div_ctl0)) { + /* only sdiv and/or kdiv changed - no need to RESET PLL */ div_ctl0 &= ~SDIV_MASK; - div_ctl0 |= FIELD_PREP(SDIV_MASK, rate->sdiv); + div_ctl0 |= FIELD_PREP(SDIV_MASK, rate.sdiv); writel_relaxed(div_ctl0, pll->base + DIV_CTL0); - writel_relaxed(FIELD_PREP(KDIV_MASK, rate->kdiv), + writel_relaxed(FIELD_PREP(KDIV_MASK, rate.kdiv), pll->base + DIV_CTL1); return 0; @@ -272,11 +380,12 @@ static int clk_pll1443x_set_rate(struct clk_hw *hw, unsigned long drate, gnrl_ctl |= BYPASS_MASK; writel_relaxed(gnrl_ctl, pll->base + GNRL_CTL); - div_ctl0 = FIELD_PREP(MDIV_MASK, rate->mdiv) | - FIELD_PREP(PDIV_MASK, rate->pdiv) | - FIELD_PREP(SDIV_MASK, rate->sdiv); + div_ctl0 = FIELD_PREP(MDIV_MASK, rate.mdiv) | + FIELD_PREP(PDIV_MASK, rate.pdiv) | + FIELD_PREP(SDIV_MASK, rate.sdiv); writel_relaxed(div_ctl0, pll->base + DIV_CTL0); - writel_relaxed(FIELD_PREP(KDIV_MASK, rate->kdiv), pll->base + DIV_CTL1); + + writel_relaxed(FIELD_PREP(KDIV_MASK, rate.kdiv), pll->base + DIV_CTL1); /* * According to SPEC, t3 - t2 need to be greater than @@ -359,7 +468,7 @@ static const struct clk_ops clk_pll1416x_ops = { .unprepare = clk_pll14xx_unprepare, .is_prepared = clk_pll14xx_is_prepared, .recalc_rate = clk_pll14xx_recalc_rate, - .round_rate = clk_pll14xx_round_rate, + .round_rate = clk_pll1416x_round_rate, .set_rate = clk_pll1416x_set_rate, }; @@ -372,7 +481,7 @@ static const struct clk_ops clk_pll1443x_ops = { .unprepare = clk_pll14xx_unprepare, .is_prepared = clk_pll14xx_is_prepared, .recalc_rate = clk_pll14xx_recalc_rate, - .round_rate = clk_pll14xx_round_rate, + .round_rate = clk_pll1443x_round_rate, .set_rate = clk_pll1443x_set_rate, }; From c62b1f34e93f29e5ee213d7c5797c99bd6439e35 Mon Sep 17 00:00:00 2001 From: Abel Vesa Date: Wed, 16 Feb 2022 15:22:14 +0200 Subject: [PATCH 40/43] MAINTAINERS: clk: imx: add git tree and dt-bindings files The i.MX clocks dt-bindings are going through the same tree as the drivers, so add them to the same entry. Also add the git tree and branch used. Signed-off-by: Abel Vesa Link: https://lore.kernel.org/r/20220216132214.258865-1-abel.vesa@nxp.com Signed-off-by: Stephen Boyd --- MAINTAINERS | 3 +++ 1 file changed, 3 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index ea3e6c9143848..1593312f321d0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -13818,7 +13818,10 @@ M: Abel Vesa L: linux-clk@vger.kernel.org L: linux-imx@nxp.com S: Maintained +T: git git://git.kernel.org/pub/scm/linux/kernel/git/abelvesa/linux.git clk/imx +F: Documentation/devicetree/bindings/clock/imx* F: drivers/clk/imx/ +F: include/dt-bindings/clock/imx* NXP i.MX 8MQ DCSS DRIVER M: Laurentiu Palcu From 3e6054d043c01e0d47a51cddc814f8d3409fc355 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Thu, 3 Mar 2022 09:05:08 +0000 Subject: [PATCH 41/43] clk: imx: remove redundant re-assignment of pll->base There are two identical assignments of pll->base to the same value, the second assignment is redundant and can be removed. Cleans up cppcheck warning: drivers/clk/imx/clk-sscg-pll.c:528:12: style: Variable 'pll->base' is reassigned a value before the old one has been used. [redundantAssignment] Signed-off-by: Colin Ian King Link: https://lore.kernel.org/r/20220303090508.1125175-1-colin.i.king@gmail.com Signed-off-by: Stephen Boyd --- drivers/clk/imx/clk-sscg-pll.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/clk/imx/clk-sscg-pll.c b/drivers/clk/imx/clk-sscg-pll.c index 9d6cdff0537f0..81f304fae9084 100644 --- a/drivers/clk/imx/clk-sscg-pll.c +++ b/drivers/clk/imx/clk-sscg-pll.c @@ -525,7 +525,6 @@ struct clk_hw *imx_clk_hw_sscg_pll(const char *name, init.parent_names = parent_names; init.num_parents = num_parents; - pll->base = base; pll->hw.init = &init; hw = &pll->hw; From 7a74e1e49622698fbf106fdc98da55f9e6634c14 Mon Sep 17 00:00:00 2001 From: Abel Vesa Date: Tue, 15 Mar 2022 10:24:46 +0200 Subject: [PATCH 42/43] clk: imx: Select MXC_CLK for i.MX93 clock driver Most of the i.MX clock generic API is built by selecting MXC_CLK. Without it, the i.MX93 clock driver will fail to build: aarch64-linux-gnu-ld: drivers/clk/imx/clk-imx93.o: in function `imx93_clocks_probe': clk-imx93.c:(.text+0xa8): undefined reference to `imx_obtain_fixed_clk_hw' So fix this by selecting MXC_CLK for the CLK_IMX93. Fixes: 24defbe194b6 ("clk: imx: add i.MX93 clk") Signed-off-by: Abel Vesa Reported-by: kernel test robot Link: https://lore.kernel.org/r/20220315082446.3120850-1-abel.vesa@nxp.com Reviewed-by: Peng Fan Signed-off-by: Stephen Boyd --- drivers/clk/imx/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/imx/Kconfig b/drivers/clk/imx/Kconfig index cc464a42d6463..25785ec9c2762 100644 --- a/drivers/clk/imx/Kconfig +++ b/drivers/clk/imx/Kconfig @@ -109,6 +109,7 @@ config CLK_IMX8ULP config CLK_IMX93 tristate "IMX93 CCM Clock Driver" depends on ARCH_MXC || COMPILE_TEST + select MXC_CLK help Build the driver for i.MX93 CCM Clock Driver From ec8b55780508044b19a6084d2a6a9bd8b96f1b0a Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 16 Mar 2022 14:08:58 +0100 Subject: [PATCH 43/43] dt-bindings: clock: drop useless consumer example Consumer examples in the bindings of resource providers are trivial, useless and duplication of code. Remove the example code for consumer Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20220316130858.93455-2-krzysztof.kozlowski@canonical.com Acked-by: Rob Herring Signed-off-by: Stephen Boyd --- .../bindings/clock/bitmain,bm1880-clk.yaml | 12 ------------ .../devicetree/bindings/clock/idt,versaclock5.yaml | 7 ------- .../devicetree/bindings/clock/imx1-clock.yaml | 9 --------- .../devicetree/bindings/clock/imx21-clock.yaml | 9 --------- .../devicetree/bindings/clock/imx23-clock.yaml | 9 --------- .../devicetree/bindings/clock/imx25-clock.yaml | 8 -------- .../devicetree/bindings/clock/imx27-clock.yaml | 9 --------- .../devicetree/bindings/clock/imx28-clock.yaml | 9 --------- .../devicetree/bindings/clock/imx31-clock.yaml | 8 -------- .../devicetree/bindings/clock/imx35-clock.yaml | 8 -------- .../devicetree/bindings/clock/imx7ulp-pcc-clock.yaml | 11 ----------- .../devicetree/bindings/clock/imx7ulp-scg-clock.yaml | 11 ----------- .../devicetree/bindings/clock/imx8qxp-lpcg.yaml | 11 ----------- .../devicetree/bindings/clock/imxrt1050-clock.yaml | 8 -------- .../bindings/clock/nvidia,tegra124-car.yaml | 7 ------- .../bindings/clock/nvidia,tegra20-car.yaml | 7 ------- 16 files changed, 143 deletions(-) diff --git a/Documentation/devicetree/bindings/clock/bitmain,bm1880-clk.yaml b/Documentation/devicetree/bindings/clock/bitmain,bm1880-clk.yaml index 228c9313df530..f0f9392470a6d 100644 --- a/Documentation/devicetree/bindings/clock/bitmain,bm1880-clk.yaml +++ b/Documentation/devicetree/bindings/clock/bitmain,bm1880-clk.yaml @@ -61,16 +61,4 @@ examples: #clock-cells = <1>; }; - # Example UART controller node that consumes clock generated by the clock controller: - - | - uart0: serial@58018000 { - compatible = "snps,dw-apb-uart"; - reg = <0x58018000 0x2000>; - clocks = <&clk 45>, <&clk 46>; - clock-names = "baudclk", "apb_pclk"; - interrupts = <0 9 4>; - reg-shift = <2>; - reg-io-width = <4>; - }; - ... diff --git a/Documentation/devicetree/bindings/clock/idt,versaclock5.yaml b/Documentation/devicetree/bindings/clock/idt,versaclock5.yaml index ffd6ae0eed644..be66f1e8b5476 100644 --- a/Documentation/devicetree/bindings/clock/idt,versaclock5.yaml +++ b/Documentation/devicetree/bindings/clock/idt,versaclock5.yaml @@ -191,11 +191,4 @@ examples: }; }; - /* Consumer referencing the 5P49V5923 pin OUT1 */ - consumer { - /* ... */ - clocks = <&vc5 1>; - /* ... */ - }; - ... diff --git a/Documentation/devicetree/bindings/clock/imx1-clock.yaml b/Documentation/devicetree/bindings/clock/imx1-clock.yaml index f4833a29b79e2..56f524780b1a6 100644 --- a/Documentation/devicetree/bindings/clock/imx1-clock.yaml +++ b/Documentation/devicetree/bindings/clock/imx1-clock.yaml @@ -40,12 +40,3 @@ examples: compatible = "fsl,imx1-ccm"; reg = <0x0021b000 0x1000>; }; - - pwm@208000 { - #pwm-cells = <2>; - compatible = "fsl,imx1-pwm"; - reg = <0x00208000 0x1000>; - interrupts = <34>; - clocks = <&clks IMX1_CLK_DUMMY>, <&clks IMX1_CLK_PER1>; - clock-names = "ipg", "per"; - }; diff --git a/Documentation/devicetree/bindings/clock/imx21-clock.yaml b/Documentation/devicetree/bindings/clock/imx21-clock.yaml index 518ad9a4733c7..e2d50544700a2 100644 --- a/Documentation/devicetree/bindings/clock/imx21-clock.yaml +++ b/Documentation/devicetree/bindings/clock/imx21-clock.yaml @@ -40,12 +40,3 @@ examples: reg = <0x10027000 0x800>; #clock-cells = <1>; }; - - serial@1000a000 { - compatible = "fsl,imx21-uart"; - reg = <0x1000a000 0x1000>; - interrupts = <20>; - clocks = <&clks IMX21_CLK_UART1_IPG_GATE>, - <&clks IMX21_CLK_PER1>; - clock-names = "ipg", "per"; - }; diff --git a/Documentation/devicetree/bindings/clock/imx23-clock.yaml b/Documentation/devicetree/bindings/clock/imx23-clock.yaml index 5e296a00e14f6..7e890ab9c77d2 100644 --- a/Documentation/devicetree/bindings/clock/imx23-clock.yaml +++ b/Documentation/devicetree/bindings/clock/imx23-clock.yaml @@ -83,12 +83,3 @@ examples: reg = <0x80040000 0x2000>; #clock-cells = <1>; }; - - serial@8006c000 { - compatible = "fsl,imx23-auart"; - reg = <0x8006c000 0x2000>; - interrupts = <24>; - clocks = <&clks 32>; - dmas = <&dma_apbx 6>, <&dma_apbx 7>; - dma-names = "rx", "tx"; - }; diff --git a/Documentation/devicetree/bindings/clock/imx25-clock.yaml b/Documentation/devicetree/bindings/clock/imx25-clock.yaml index 2a2b10778e72b..1792e138984b9 100644 --- a/Documentation/devicetree/bindings/clock/imx25-clock.yaml +++ b/Documentation/devicetree/bindings/clock/imx25-clock.yaml @@ -176,11 +176,3 @@ examples: interrupts = <31>; #clock-cells = <1>; }; - - serial@43f90000 { - compatible = "fsl,imx25-uart", "fsl,imx21-uart"; - reg = <0x43f90000 0x4000>; - interrupts = <45>; - clocks = <&clks 79>, <&clks 50>; - clock-names = "ipg", "per"; - }; diff --git a/Documentation/devicetree/bindings/clock/imx27-clock.yaml b/Documentation/devicetree/bindings/clock/imx27-clock.yaml index 160268f244874..99925aa22a4c8 100644 --- a/Documentation/devicetree/bindings/clock/imx27-clock.yaml +++ b/Documentation/devicetree/bindings/clock/imx27-clock.yaml @@ -44,12 +44,3 @@ examples: interrupts = <31>; #clock-cells = <1>; }; - - serial@1000a000 { - compatible = "fsl,imx27-uart", "fsl,imx21-uart"; - reg = <0x1000a000 0x1000>; - interrupts = <20>; - clocks = <&clks IMX27_CLK_UART1_IPG_GATE>, - <&clks IMX27_CLK_PER1_GATE>; - clock-names = "ipg", "per"; - }; diff --git a/Documentation/devicetree/bindings/clock/imx28-clock.yaml b/Documentation/devicetree/bindings/clock/imx28-clock.yaml index f831b780f9514..a542d680b1ca8 100644 --- a/Documentation/devicetree/bindings/clock/imx28-clock.yaml +++ b/Documentation/devicetree/bindings/clock/imx28-clock.yaml @@ -106,12 +106,3 @@ examples: reg = <0x80040000 0x2000>; #clock-cells = <1>; }; - - serial@8006a000 { - compatible = "fsl,imx28-auart"; - reg = <0x8006a000 0x2000>; - interrupts = <112>; - dmas = <&dma_apbx 8>, <&dma_apbx 9>; - dma-names = "rx", "tx"; - clocks = <&clks 45>; - }; diff --git a/Documentation/devicetree/bindings/clock/imx31-clock.yaml b/Documentation/devicetree/bindings/clock/imx31-clock.yaml index d2336261c922a..168c8ada5e81c 100644 --- a/Documentation/devicetree/bindings/clock/imx31-clock.yaml +++ b/Documentation/devicetree/bindings/clock/imx31-clock.yaml @@ -110,11 +110,3 @@ examples: interrupts = <31>, <53>; #clock-cells = <1>; }; - - serial@43f90000 { - compatible = "fsl,imx31-uart", "fsl,imx21-uart"; - reg = <0x43f90000 0x4000>; - interrupts = <45>; - clocks = <&clks 10>, <&clks 30>; - clock-names = "ipg", "per"; - }; diff --git a/Documentation/devicetree/bindings/clock/imx35-clock.yaml b/Documentation/devicetree/bindings/clock/imx35-clock.yaml index 3e20ccaf81318..6415bb6a8d041 100644 --- a/Documentation/devicetree/bindings/clock/imx35-clock.yaml +++ b/Documentation/devicetree/bindings/clock/imx35-clock.yaml @@ -129,11 +129,3 @@ examples: interrupts = <31>; #clock-cells = <1>; }; - - mmc@53fb4000 { - compatible = "fsl,imx35-esdhc"; - reg = <0x53fb4000 0x4000>; - interrupts = <7>; - clocks = <&clks 9>, <&clks 8>, <&clks 43>; - clock-names = "ipg", "ahb", "per"; - }; diff --git a/Documentation/devicetree/bindings/clock/imx7ulp-pcc-clock.yaml b/Documentation/devicetree/bindings/clock/imx7ulp-pcc-clock.yaml index 7caf5cee91997..739c3378f8c8f 100644 --- a/Documentation/devicetree/bindings/clock/imx7ulp-pcc-clock.yaml +++ b/Documentation/devicetree/bindings/clock/imx7ulp-pcc-clock.yaml @@ -108,14 +108,3 @@ examples: "upll", "sosc_bus_clk", "firc_bus_clk", "rosc", "spll_bus_clk"; }; - - mmc@40380000 { - compatible = "fsl,imx7ulp-usdhc"; - reg = <0x40380000 0x10000>; - interrupts = ; - clocks = <&scg1 IMX7ULP_CLK_NIC1_BUS_DIV>, - <&scg1 IMX7ULP_CLK_NIC1_DIV>, - <&pcc2 IMX7ULP_CLK_USDHC1>; - clock-names ="ipg", "ahb", "per"; - bus-width = <4>; - }; diff --git a/Documentation/devicetree/bindings/clock/imx7ulp-scg-clock.yaml b/Documentation/devicetree/bindings/clock/imx7ulp-scg-clock.yaml index ee8efb4ed5999..d06344d7e34fe 100644 --- a/Documentation/devicetree/bindings/clock/imx7ulp-scg-clock.yaml +++ b/Documentation/devicetree/bindings/clock/imx7ulp-scg-clock.yaml @@ -86,14 +86,3 @@ examples: "firc", "upll"; #clock-cells = <1>; }; - - mmc@40380000 { - compatible = "fsl,imx7ulp-usdhc"; - reg = <0x40380000 0x10000>; - interrupts = ; - clocks = <&scg1 IMX7ULP_CLK_NIC1_BUS_DIV>, - <&scg1 IMX7ULP_CLK_NIC1_DIV>, - <&pcc2 IMX7ULP_CLK_USDHC1>; - clock-names ="ipg", "ahb", "per"; - bus-width = <4>; - }; diff --git a/Documentation/devicetree/bindings/clock/imx8qxp-lpcg.yaml b/Documentation/devicetree/bindings/clock/imx8qxp-lpcg.yaml index 0f6fe365ebf30..cb80105b3c708 100644 --- a/Documentation/devicetree/bindings/clock/imx8qxp-lpcg.yaml +++ b/Documentation/devicetree/bindings/clock/imx8qxp-lpcg.yaml @@ -101,14 +101,3 @@ examples: "sdhc0_lpcg_ahb_clk"; power-domains = <&pd IMX_SC_R_SDHC_0>; }; - - mmc@5b010000 { - compatible = "fsl,imx8qxp-usdhc", "fsl,imx7d-usdhc"; - interrupts = ; - reg = <0x5b010000 0x10000>; - clocks = <&sdhc0_lpcg IMX_LPCG_CLK_4>, - <&sdhc0_lpcg IMX_LPCG_CLK_5>, - <&sdhc0_lpcg IMX_LPCG_CLK_0>; - clock-names = "ipg", "ahb", "per"; - power-domains = <&pd IMX_SC_R_SDHC_0>; - }; diff --git a/Documentation/devicetree/bindings/clock/imxrt1050-clock.yaml b/Documentation/devicetree/bindings/clock/imxrt1050-clock.yaml index 35fd08c143f43..03fc5c1a29399 100644 --- a/Documentation/devicetree/bindings/clock/imxrt1050-clock.yaml +++ b/Documentation/devicetree/bindings/clock/imxrt1050-clock.yaml @@ -57,11 +57,3 @@ examples: clock-names = "osc"; #clock-cells = <1>; }; - - lpuart1: serial@40184000 { - compatible = "fsl,imxrt1050-lpuart"; - reg = <0x40184000 0x4000>; - interrupts = <20>; - clocks = <&clks IMXRT1050_CLK_LPUART1>; - clock-names = "ipg"; - }; diff --git a/Documentation/devicetree/bindings/clock/nvidia,tegra124-car.yaml b/Documentation/devicetree/bindings/clock/nvidia,tegra124-car.yaml index ec7ab14836525..1b2181f6d4401 100644 --- a/Documentation/devicetree/bindings/clock/nvidia,tegra124-car.yaml +++ b/Documentation/devicetree/bindings/clock/nvidia,tegra124-car.yaml @@ -106,10 +106,3 @@ examples: #clock-cells = <1>; #reset-cells = <1>; }; - - usb-controller@c5004000 { - compatible = "nvidia,tegra20-ehci"; - reg = <0xc5004000 0x4000>; - clocks = <&car TEGRA124_CLK_USB2>; - resets = <&car TEGRA124_CLK_USB2>; - }; diff --git a/Documentation/devicetree/bindings/clock/nvidia,tegra20-car.yaml b/Documentation/devicetree/bindings/clock/nvidia,tegra20-car.yaml index f832abb7f11ae..bee2dd4b29bfe 100644 --- a/Documentation/devicetree/bindings/clock/nvidia,tegra20-car.yaml +++ b/Documentation/devicetree/bindings/clock/nvidia,tegra20-car.yaml @@ -97,10 +97,3 @@ examples: power-domains = <&domain>; }; }; - - usb-controller@c5004000 { - compatible = "nvidia,tegra20-ehci"; - reg = <0xc5004000 0x4000>; - clocks = <&car TEGRA20_CLK_USB2>; - resets = <&car TEGRA20_CLK_USB2>; - };