Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branches 'clk-imx', 'clk-ux500' and 'clk-debugfs' into clk-next

* clk-imx: (21 commits)
clk: imx: Make CLK_IMX8ULP select MXC_CLK
clk: imx: imx6ul: Fix csi clk gate register
clk: imx: imx6ul: Move csi_sel mux to correct base register
clk: imx: Fix the build break when clk-imx8ulp build as module
clk: imx: Add the pcc reset controller support on imx8ulp
clk: imx: Add clock driver for imx8ulp
clk: imx: Update the pfdv2 for 8ulp specific support
clk: imx: disable the pfd when set pfdv2 clock rate
clk: imx: Add 'CLK_SET_RATE_NO_REPARENT' for composite-7ulp
clk: imx: disable i.mx7ulp composite clock during initialization
clk: imx: Update the compsite driver to support imx8ulp
clk: imx: Update the pllv4 to support imx8ulp
dt-bindings: clock: Add imx8ulp clock support
clk: imx: Rework imx_clk_hw_pll14xx wrapper
clk: imx: Rework all imx_clk_hw_composite wrappers
clk: imx: Rework all clk_hw_register_divider wrappers
clk: imx: Rework all clk_hw_register_mux wrappers
clk: imx: Rework all clk_hw_register_gate2 wrappers
clk: imx: Rework all clk_hw_register_gate wrappers
clk: imx: Make mux/mux2 clk based helpers use clk_hw based ones
...

* clk-ux500:
clk: ux500: Add driver for the reset portions of PRCC
dt-bindings: clock: u8500: Rewrite in YAML and extend

* clk-debugfs:
clk: use clk_core_get_rate_recalc() in clk_rate_get()

+1700 -430
+43
Documentation/devicetree/bindings/clock/imx8ulp-cgc-clock.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/clock/imx8ulp-cgc-clock.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: NXP i.MX8ULP Clock Generation & Control(CGC) Module Binding 8 + 9 + maintainers: 10 + - Jacky Bai <ping.bai@nxp.com> 11 + 12 + description: | 13 + On i.MX8ULP, The clock sources generation, distribution and management is 14 + under the control of several CGCs & PCCs modules. The CGC modules generate 15 + and distribute clocks on the device. 16 + 17 + properties: 18 + compatible: 19 + enum: 20 + - fsl,imx8ulp-cgc1 21 + - fsl,imx8ulp-cgc2 22 + 23 + reg: 24 + maxItems: 1 25 + 26 + '#clock-cells': 27 + const: 1 28 + 29 + required: 30 + - compatible 31 + - reg 32 + - '#clock-cells' 33 + 34 + additionalProperties: false 35 + 36 + examples: 37 + # Clock Generation & Control Module node: 38 + - | 39 + clock-controller@292c0000 { 40 + compatible = "fsl,imx8ulp-cgc1"; 41 + reg = <0x292c0000 0x10000>; 42 + #clock-cells = <1>; 43 + };
+50
Documentation/devicetree/bindings/clock/imx8ulp-pcc-clock.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/clock/imx8ulp-pcc-clock.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: NXP i.MX8ULP Peripheral Clock Controller(PCC) Module Binding 8 + 9 + maintainers: 10 + - Jacky Bai <ping.bai@nxp.com> 11 + 12 + description: | 13 + On i.MX8ULP, The clock sources generation, distribution and management is 14 + under the control of several CGCs & PCCs modules. The PCC modules control 15 + software reset, clock selection, optional division and clock gating mode 16 + for peripherals. 17 + 18 + properties: 19 + compatible: 20 + enum: 21 + - fsl,imx8ulp-pcc3 22 + - fsl,imx8ulp-pcc4 23 + - fsl,imx8ulp-pcc5 24 + 25 + reg: 26 + maxItems: 1 27 + 28 + '#clock-cells': 29 + const: 1 30 + 31 + '#reset-cells': 32 + const: 1 33 + 34 + required: 35 + - compatible 36 + - reg 37 + - '#clock-cells' 38 + - '#reset-cells' 39 + 40 + additionalProperties: false 41 + 42 + examples: 43 + # Peripheral Clock Control Module node: 44 + - | 45 + clock-controller@292d0000 { 46 + compatible = "fsl,imx8ulp-pcc3"; 47 + reg = <0x292d0000 0x10000>; 48 + #clock-cells = <1>; 49 + #reset-cells = <1>; 50 + };
+121
Documentation/devicetree/bindings/clock/stericsson,u8500-clks.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/clock/stericsson,u8500-clks.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: ST-Ericsson DB8500 (U8500) clocks 8 + 9 + maintainers: 10 + - Ulf Hansson <ulf.hansson@linaro.org> 11 + - Linus Walleij <linus.walleij@linaro.org> 12 + 13 + description: While named "U8500 clocks" these clocks are inside the 14 + DB8500 digital baseband system-on-chip and its siblings such as 15 + DB8520. These bindings consider the clocks present in the SoC 16 + itself, not off-chip clocks. There are four different on-chip 17 + clocks - RTC (32 kHz), CPU clock (SMP TWD), PRCMU (power reset and 18 + control management unit) clocks and PRCC (peripheral reset and 19 + clock controller) clocks. For some reason PRCC 4 does not exist so 20 + the itemization can be a bit unintuitive. 21 + 22 + properties: 23 + compatible: 24 + enum: 25 + - stericsson,u8500-clks 26 + - stericsson,u8540-clks 27 + - stericsson,u9540-clks 28 + 29 + reg: 30 + items: 31 + - description: PRCC 1 register area 32 + - description: PRCC 2 register area 33 + - description: PRCC 3 register area 34 + - description: PRCC 5 register area 35 + - description: PRCC 6 register area 36 + 37 + prcmu-clock: 38 + description: A subnode with one clock cell for PRCMU (power, reset, control 39 + management unit) clocks. The cell indicates which PRCMU clock in the 40 + prcmu-clock node the consumer wants to use. 41 + type: object 42 + 43 + properties: 44 + '#clock-cells': 45 + const: 1 46 + 47 + additionalProperties: false 48 + 49 + prcc-periph-clock: 50 + description: A subnode with two clock cells for PRCC (peripheral 51 + reset and clock controller) peripheral clocks. The first cell indicates 52 + which PRCC block the consumer wants to use, possible values are 1, 2, 3, 53 + 5, 6. The second cell indicates which clock inside the PRCC block it 54 + wants, possible values are 0 thru 31. 55 + type: object 56 + 57 + properties: 58 + '#clock-cells': 59 + const: 2 60 + 61 + additionalProperties: false 62 + 63 + prcc-kernel-clock: 64 + description: A subnode with two clock cells for PRCC (peripheral reset 65 + and clock controller) kernel clocks. The first cell indicates which PRCC 66 + block the consumer wants to use, possible values are 1, 2, 3, 5, 6. The 67 + second cell indicates which clock inside the PRCC block it wants, possible 68 + values are 0 thru 31. 69 + type: object 70 + 71 + properties: 72 + '#clock-cells': 73 + const: 2 74 + 75 + additionalProperties: false 76 + 77 + prcc-reset-controller: 78 + description: A subnode with two reset cells for the reset portions of the 79 + PRCC (peripheral reset and clock controller). The first cell indicates 80 + which PRCC block the consumer wants to use, possible values are 1, 2, 3 81 + 5 and 6. The second cell indicates which reset line inside the PRCC block 82 + it wants to control, possible values are 0 thru 31. 83 + type: object 84 + 85 + properties: 86 + '#reset-cells': 87 + const: 2 88 + 89 + additionalProperties: false 90 + 91 + rtc32k-clock: 92 + description: A subnode with zero clock cells for the 32kHz RTC clock. 93 + type: object 94 + 95 + properties: 96 + '#clock-cells': 97 + const: 0 98 + 99 + additionalProperties: false 100 + 101 + smp-twd-clock: 102 + description: A subnode for the ARM SMP Timer Watchdog cluster with zero 103 + clock cells. 104 + type: object 105 + 106 + properties: 107 + '#clock-cells': 108 + const: 0 109 + 110 + additionalProperties: false 111 + 112 + required: 113 + - compatible 114 + - reg 115 + - prcmu-clock 116 + - prcc-periph-clock 117 + - prcc-kernel-clock 118 + - rtc32k-clock 119 + - smp-twd-clock 120 + 121 + additionalProperties: false
-64
Documentation/devicetree/bindings/clock/ux500.txt
··· 1 - Clock bindings for ST-Ericsson Ux500 clocks 2 - 3 - Required properties : 4 - - compatible : shall contain only one of the following: 5 - "stericsson,u8500-clks" 6 - "stericsson,u8540-clks" 7 - "stericsson,u9540-clks" 8 - - reg : shall contain base register location and length for 9 - CLKRST1, 2, 3, 5, and 6 in an array. Note the absence of 10 - CLKRST4, which does not exist. 11 - 12 - Required subnodes: 13 - - prcmu-clock: a subnode with one clock cell for PRCMU (power, 14 - reset, control unit) clocks. The cell indicates which PRCMU 15 - clock in the prcmu-clock node the consumer wants to use. 16 - - prcc-periph-clock: a subnode with two clock cells for 17 - PRCC (programmable reset- and clock controller) peripheral clocks. 18 - The first cell indicates which PRCC block the consumer 19 - wants to use, possible values are 1, 2, 3, 5, 6. The second 20 - cell indicates which clock inside the PRCC block it wants, 21 - possible values are 0 thru 31. 22 - - prcc-kernel-clock: a subnode with two clock cells for 23 - PRCC (programmable reset- and clock controller) kernel clocks 24 - The first cell indicates which PRCC block the consumer 25 - wants to use, possible values are 1, 2, 3, 5, 6. The second 26 - cell indicates which clock inside the PRCC block it wants, 27 - possible values are 0 thru 31. 28 - - rtc32k-clock: a subnode with zero clock cells for the 32kHz 29 - RTC clock. 30 - - smp-twd-clock: a subnode for the ARM SMP Timer Watchdog cluster 31 - with zero clock cells. 32 - 33 - Example: 34 - 35 - clocks { 36 - compatible = "stericsson,u8500-clks"; 37 - /* 38 - * Registers for the CLKRST block on peripheral 39 - * groups 1, 2, 3, 5, 6, 40 - */ 41 - reg = <0x8012f000 0x1000>, <0x8011f000 0x1000>, 42 - <0x8000f000 0x1000>, <0xa03ff000 0x1000>, 43 - <0xa03cf000 0x1000>; 44 - 45 - prcmu_clk: prcmu-clock { 46 - #clock-cells = <1>; 47 - }; 48 - 49 - prcc_pclk: prcc-periph-clock { 50 - #clock-cells = <2>; 51 - }; 52 - 53 - prcc_kclk: prcc-kernel-clock { 54 - #clock-cells = <2>; 55 - }; 56 - 57 - rtc_clk: rtc32k-clock { 58 - #clock-cells = <0>; 59 - }; 60 - 61 - smp_twd_clk: smp-twd-clock { 62 - #clock-cells = <0>; 63 - }; 64 - };
+1
arch/arm/mach-ux500/Kconfig
··· 29 29 select REGULATOR_DB8500_PRCMU 30 30 select REGULATOR_FIXED_VOLTAGE 31 31 select SOC_BUS 32 + select RESET_CONTROLLER 32 33 help 33 34 Support for ST-Ericsson's Ux500 architecture 34 35
+4 -1
drivers/clk/clk.c
··· 3108 3108 { 3109 3109 struct clk_core *core = data; 3110 3110 3111 - *val = core->rate; 3111 + clk_prepare_lock(); 3112 + *val = clk_core_get_rate_recalc(core); 3113 + clk_prepare_unlock(); 3114 + 3112 3115 return 0; 3113 3116 } 3114 3117
+7
drivers/clk/imx/Kconfig
··· 98 98 select MXC_CLK_SCU 99 99 help 100 100 Build the driver for IMX8QXP SCU based clocks. 101 + 102 + config CLK_IMX8ULP 103 + tristate "IMX8ULP CCM Clock Driver" 104 + depends on ARCH_MXC || COMPILE_TEST 105 + select MXC_CLK 106 + help 107 + Build the driver for i.MX8ULP CCM Clock Driver
+2
drivers/clk/imx/Makefile
··· 31 31 clk-imx8qxp-rsrc.o clk-imx8qm-rsrc.o 32 32 clk-imx-lpcg-scu-$(CONFIG_CLK_IMX8QXP) += clk-lpcg-scu.o clk-imx8qxp-lpcg.o 33 33 34 + obj-$(CONFIG_CLK_IMX8ULP) += clk-imx8ulp.o 35 + 34 36 obj-$(CONFIG_CLK_IMX1) += clk-imx1.o 35 37 obj-$(CONFIG_CLK_IMX25) += clk-imx25.o 36 38 obj-$(CONFIG_CLK_IMX27) += clk-imx27.o
+84 -4
drivers/clk/imx/clk-composite-7ulp.c
··· 8 8 #include <linux/bits.h> 9 9 #include <linux/clk-provider.h> 10 10 #include <linux/err.h> 11 + #include <linux/io.h> 11 12 #include <linux/slab.h> 12 13 13 14 #include "../clk-fractional-divider.h" ··· 24 23 #define PCG_PCD_WIDTH 3 25 24 #define PCG_PCD_MASK 0x7 26 25 27 - struct clk_hw *imx7ulp_clk_hw_composite(const char *name, 26 + #define SW_RST BIT(28) 27 + 28 + static int pcc_gate_enable(struct clk_hw *hw) 29 + { 30 + struct clk_gate *gate = to_clk_gate(hw); 31 + unsigned long flags; 32 + u32 val; 33 + int ret; 34 + 35 + ret = clk_gate_ops.enable(hw); 36 + if (ret) 37 + return ret; 38 + 39 + spin_lock_irqsave(gate->lock, flags); 40 + /* 41 + * release the sw reset for peripherals associated with 42 + * with this pcc clock. 43 + */ 44 + val = readl(gate->reg); 45 + val |= SW_RST; 46 + writel(val, gate->reg); 47 + 48 + spin_unlock_irqrestore(gate->lock, flags); 49 + 50 + return 0; 51 + } 52 + 53 + static void pcc_gate_disable(struct clk_hw *hw) 54 + { 55 + clk_gate_ops.disable(hw); 56 + } 57 + 58 + static int pcc_gate_is_enabled(struct clk_hw *hw) 59 + { 60 + return clk_gate_ops.is_enabled(hw); 61 + } 62 + 63 + static const struct clk_ops pcc_gate_ops = { 64 + .enable = pcc_gate_enable, 65 + .disable = pcc_gate_disable, 66 + .is_enabled = pcc_gate_is_enabled, 67 + }; 68 + 69 + static struct clk_hw *imx_ulp_clk_hw_composite(const char *name, 28 70 const char * const *parent_names, 29 71 int num_parents, bool mux_present, 30 72 bool rate_present, bool gate_present, 31 - void __iomem *reg) 73 + void __iomem *reg, bool has_swrst) 32 74 { 33 75 struct clk_hw *mux_hw = NULL, *fd_hw = NULL, *gate_hw = NULL; 34 76 struct clk_fractional_divider *fd = NULL; 35 77 struct clk_gate *gate = NULL; 36 78 struct clk_mux *mux = NULL; 37 79 struct clk_hw *hw; 80 + u32 val; 38 81 39 82 if (mux_present) { 40 83 mux = kzalloc(sizeof(*mux), GFP_KERNEL); ··· 88 43 mux->reg = reg; 89 44 mux->shift = PCG_PCS_SHIFT; 90 45 mux->mask = PCG_PCS_MASK; 46 + if (has_swrst) 47 + mux->lock = &imx_ccm_lock; 91 48 } 92 49 93 50 if (rate_present) { ··· 107 60 fd->nwidth = PCG_PCD_WIDTH; 108 61 fd->nmask = PCG_PCD_MASK; 109 62 fd->flags = CLK_FRAC_DIVIDER_ZERO_BASED; 63 + if (has_swrst) 64 + fd->lock = &imx_ccm_lock; 110 65 } 111 66 112 67 if (gate_present) { ··· 121 72 gate_hw = &gate->hw; 122 73 gate->reg = reg; 123 74 gate->bit_idx = PCG_CGC_SHIFT; 75 + if (has_swrst) 76 + gate->lock = &imx_ccm_lock; 77 + /* 78 + * make sure clock is gated during clock tree initialization, 79 + * the HW ONLY allow clock parent/rate changed with clock gated, 80 + * during clock tree initialization, clocks could be enabled 81 + * by bootloader, so the HW status will mismatch with clock tree 82 + * prepare count, then clock core driver will allow parent/rate 83 + * change since the prepare count is zero, but HW actually 84 + * prevent the parent/rate change due to the clock is enabled. 85 + */ 86 + val = readl_relaxed(reg); 87 + val &= ~(1 << PCG_CGC_SHIFT); 88 + writel_relaxed(val, reg); 124 89 } 125 90 126 91 hw = clk_hw_register_composite(NULL, name, parent_names, num_parents, 127 92 mux_hw, &clk_mux_ops, fd_hw, 128 93 &clk_fractional_divider_ops, gate_hw, 129 - &clk_gate_ops, CLK_SET_RATE_GATE | 130 - CLK_SET_PARENT_GATE); 94 + has_swrst ? &pcc_gate_ops : &clk_gate_ops, CLK_SET_RATE_GATE | 95 + CLK_SET_PARENT_GATE | CLK_SET_RATE_NO_REPARENT); 131 96 if (IS_ERR(hw)) { 132 97 kfree(mux); 133 98 kfree(fd); ··· 150 87 151 88 return hw; 152 89 } 90 + 91 + struct clk_hw *imx7ulp_clk_hw_composite(const char *name, const char * const *parent_names, 92 + int num_parents, bool mux_present, bool rate_present, 93 + bool gate_present, void __iomem *reg) 94 + { 95 + return imx_ulp_clk_hw_composite(name, parent_names, num_parents, mux_present, rate_present, 96 + gate_present, reg, false); 97 + } 98 + 99 + struct clk_hw *imx8ulp_clk_hw_composite(const char *name, const char * const *parent_names, 100 + int num_parents, bool mux_present, bool rate_present, 101 + bool gate_present, void __iomem *reg, bool has_swrst) 102 + { 103 + return imx_ulp_clk_hw_composite(name, parent_names, num_parents, mux_present, rate_present, 104 + gate_present, reg, has_swrst); 105 + } 106 + EXPORT_SYMBOL_GPL(imx8ulp_clk_hw_composite);
+2 -2
drivers/clk/imx/clk-composite-8m.c
··· 171 171 .determine_rate = imx8m_clk_composite_mux_determine_rate, 172 172 }; 173 173 174 - struct clk_hw *imx8m_clk_hw_composite_flags(const char *name, 174 + struct clk_hw *__imx8m_clk_hw_composite(const char *name, 175 175 const char * const *parent_names, 176 176 int num_parents, void __iomem *reg, 177 177 u32 composite_flags, ··· 246 246 kfree(mux); 247 247 return ERR_CAST(hw); 248 248 } 249 - EXPORT_SYMBOL_GPL(imx8m_clk_hw_composite_flags); 249 + EXPORT_SYMBOL_GPL(__imx8m_clk_hw_composite);
+7 -2
drivers/clk/imx/clk-imx6ul.c
··· 161 161 hws[IMX6UL_PLL5_BYPASS] = imx_clk_hw_mux_flags("pll5_bypass", base + 0xa0, 16, 1, pll5_bypass_sels, ARRAY_SIZE(pll5_bypass_sels), CLK_SET_RATE_PARENT); 162 162 hws[IMX6UL_PLL6_BYPASS] = imx_clk_hw_mux_flags("pll6_bypass", base + 0xe0, 16, 1, pll6_bypass_sels, ARRAY_SIZE(pll6_bypass_sels), CLK_SET_RATE_PARENT); 163 163 hws[IMX6UL_PLL7_BYPASS] = imx_clk_hw_mux_flags("pll7_bypass", base + 0x20, 16, 1, pll7_bypass_sels, ARRAY_SIZE(pll7_bypass_sels), CLK_SET_RATE_PARENT); 164 - hws[IMX6UL_CLK_CSI_SEL] = imx_clk_hw_mux_flags("csi_sel", base + 0x3c, 9, 2, csi_sels, ARRAY_SIZE(csi_sels), CLK_SET_RATE_PARENT); 165 164 166 165 /* Do not bypass PLLs initially */ 167 166 clk_set_parent(hws[IMX6UL_PLL1_BYPASS]->clk, hws[IMX6UL_CLK_PLL1]->clk); ··· 269 270 hws[IMX6UL_CLK_ECSPI_SEL] = imx_clk_hw_mux("ecspi_sel", base + 0x38, 18, 1, ecspi_sels, ARRAY_SIZE(ecspi_sels)); 270 271 hws[IMX6UL_CLK_LCDIF_PRE_SEL] = imx_clk_hw_mux_flags("lcdif_pre_sel", base + 0x38, 15, 3, lcdif_pre_sels, ARRAY_SIZE(lcdif_pre_sels), CLK_SET_RATE_PARENT); 271 272 hws[IMX6UL_CLK_LCDIF_SEL] = imx_clk_hw_mux("lcdif_sel", base + 0x38, 9, 3, lcdif_sels, ARRAY_SIZE(lcdif_sels)); 273 + hws[IMX6UL_CLK_CSI_SEL] = imx_clk_hw_mux("csi_sel", base + 0x3c, 9, 2, csi_sels, ARRAY_SIZE(csi_sels)); 272 274 273 275 hws[IMX6UL_CLK_LDB_DI0_DIV_SEL] = imx_clk_hw_mux("ldb_di0", base + 0x20, 10, 1, ldb_di0_div_sels, ARRAY_SIZE(ldb_di0_div_sels)); 274 276 hws[IMX6UL_CLK_LDB_DI1_DIV_SEL] = imx_clk_hw_mux("ldb_di1", base + 0x20, 11, 1, ldb_di1_div_sels, ARRAY_SIZE(ldb_di1_div_sels)); ··· 380 380 hws[IMX6ULL_CLK_ESAI_IPG] = imx_clk_hw_gate2_shared("esai_ipg", "ahb", base + 0x70, 0, &share_count_esai); 381 381 hws[IMX6ULL_CLK_ESAI_MEM] = imx_clk_hw_gate2_shared("esai_mem", "ahb", base + 0x70, 0, &share_count_esai); 382 382 } 383 - hws[IMX6UL_CLK_CSI] = imx_clk_hw_gate2("csi", "csi_podf", base + 0x70, 2); 384 383 hws[IMX6UL_CLK_I2C1] = imx_clk_hw_gate2("i2c1", "perclk", base + 0x70, 6); 385 384 hws[IMX6UL_CLK_I2C2] = imx_clk_hw_gate2("i2c2", "perclk", base + 0x70, 8); 386 385 hws[IMX6UL_CLK_I2C3] = imx_clk_hw_gate2("i2c3", "perclk", base + 0x70, 10); ··· 390 391 hws[IMX6UL_CLK_PXP] = imx_clk_hw_gate2("pxp", "axi", base + 0x70, 30); 391 392 392 393 /* CCGR3 */ 394 + /* 395 + * Although the imx6ull reference manual lists CCGR2 as the csi clk 396 + * gate register, tests have shown that it is actually the CCGR3 397 + * register bit 0/1, same as for the imx6ul. 398 + */ 399 + hws[IMX6UL_CLK_CSI] = imx_clk_hw_gate2("csi", "csi_podf", base + 0x74, 0); 393 400 hws[IMX6UL_CLK_UART5_IPG] = imx_clk_hw_gate2("uart5_ipg", "ipg", base + 0x74, 2); 394 401 hws[IMX6UL_CLK_UART5_SERIAL] = imx_clk_hw_gate2("uart5_serial", "uart_podf", base + 0x74, 2); 395 402 if (clk_on_imx6ul()) {
+10 -10
drivers/clk/imx/clk-imx7ulp.c
··· 78 78 hws[IMX7ULP_CLK_SPLL_PRE_DIV] = imx_clk_hw_divider_flags("spll_pre_div", "spll_pre_sel", base + 0x608, 8, 3, CLK_SET_RATE_GATE); 79 79 80 80 /* name parent_name base */ 81 - hws[IMX7ULP_CLK_APLL] = imx_clk_hw_pllv4("apll", "apll_pre_div", base + 0x500); 82 - hws[IMX7ULP_CLK_SPLL] = imx_clk_hw_pllv4("spll", "spll_pre_div", base + 0x600); 81 + hws[IMX7ULP_CLK_APLL] = imx_clk_hw_pllv4(IMX_PLLV4_IMX7ULP, "apll", "apll_pre_div", base + 0x500); 82 + hws[IMX7ULP_CLK_SPLL] = imx_clk_hw_pllv4(IMX_PLLV4_IMX7ULP, "spll", "spll_pre_div", base + 0x600); 83 83 84 84 /* APLL PFDs */ 85 - hws[IMX7ULP_CLK_APLL_PFD0] = imx_clk_hw_pfdv2("apll_pfd0", "apll", base + 0x50c, 0); 86 - hws[IMX7ULP_CLK_APLL_PFD1] = imx_clk_hw_pfdv2("apll_pfd1", "apll", base + 0x50c, 1); 87 - hws[IMX7ULP_CLK_APLL_PFD2] = imx_clk_hw_pfdv2("apll_pfd2", "apll", base + 0x50c, 2); 88 - hws[IMX7ULP_CLK_APLL_PFD3] = imx_clk_hw_pfdv2("apll_pfd3", "apll", base + 0x50c, 3); 85 + hws[IMX7ULP_CLK_APLL_PFD0] = imx_clk_hw_pfdv2(IMX_PFDV2_IMX7ULP, "apll_pfd0", "apll", base + 0x50c, 0); 86 + hws[IMX7ULP_CLK_APLL_PFD1] = imx_clk_hw_pfdv2(IMX_PFDV2_IMX7ULP, "apll_pfd1", "apll", base + 0x50c, 1); 87 + hws[IMX7ULP_CLK_APLL_PFD2] = imx_clk_hw_pfdv2(IMX_PFDV2_IMX7ULP, "apll_pfd2", "apll", base + 0x50c, 2); 88 + hws[IMX7ULP_CLK_APLL_PFD3] = imx_clk_hw_pfdv2(IMX_PFDV2_IMX7ULP, "apll_pfd3", "apll", base + 0x50c, 3); 89 89 90 90 /* SPLL PFDs */ 91 - hws[IMX7ULP_CLK_SPLL_PFD0] = imx_clk_hw_pfdv2("spll_pfd0", "spll", base + 0x60C, 0); 92 - hws[IMX7ULP_CLK_SPLL_PFD1] = imx_clk_hw_pfdv2("spll_pfd1", "spll", base + 0x60C, 1); 93 - hws[IMX7ULP_CLK_SPLL_PFD2] = imx_clk_hw_pfdv2("spll_pfd2", "spll", base + 0x60C, 2); 94 - hws[IMX7ULP_CLK_SPLL_PFD3] = imx_clk_hw_pfdv2("spll_pfd3", "spll", base + 0x60C, 3); 91 + hws[IMX7ULP_CLK_SPLL_PFD0] = imx_clk_hw_pfdv2(IMX_PFDV2_IMX7ULP, "spll_pfd0", "spll", base + 0x60C, 0); 92 + hws[IMX7ULP_CLK_SPLL_PFD1] = imx_clk_hw_pfdv2(IMX_PFDV2_IMX7ULP, "spll_pfd1", "spll", base + 0x60C, 1); 93 + hws[IMX7ULP_CLK_SPLL_PFD2] = imx_clk_hw_pfdv2(IMX_PFDV2_IMX7ULP, "spll_pfd2", "spll", base + 0x60C, 2); 94 + hws[IMX7ULP_CLK_SPLL_PFD3] = imx_clk_hw_pfdv2(IMX_PFDV2_IMX7ULP, "spll_pfd3", "spll", base + 0x60C, 3); 95 95 96 96 /* PLL Mux */ 97 97 hws[IMX7ULP_CLK_APLL_PFD_SEL] = imx_clk_hw_mux_flags("apll_pfd_sel", base + 0x508, 14, 2, apll_pfd_sels, ARRAY_SIZE(apll_pfd_sels), CLK_SET_RATE_PARENT | CLK_SET_PARENT_GATE);
+569
drivers/clk/imx/clk-imx8ulp.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* 3 + * Copyright 2021 NXP 4 + */ 5 + 6 + #include <dt-bindings/clock/imx8ulp-clock.h> 7 + #include <linux/err.h> 8 + #include <linux/io.h> 9 + #include <linux/module.h> 10 + #include <linux/of_device.h> 11 + #include <linux/platform_device.h> 12 + #include <linux/reset-controller.h> 13 + #include <linux/slab.h> 14 + 15 + #include "clk.h" 16 + 17 + static const char * const pll_pre_sels[] = { "sosc", "frosc", }; 18 + static const char * const a35_sels[] = { "frosc", "spll2", "sosc", "lvds", }; 19 + static const char * const nic_sels[] = { "frosc", "spll3_pfd0", "sosc", "lvds", }; 20 + static const char * const pcc3_periph_bus_sels[] = { "dummy", "lposc", "sosc_div2", 21 + "frosc_div2", "xbar_divbus", "spll3_pfd1_div1", 22 + "spll3_pfd0_div2", "spll3_pfd0_div1", }; 23 + static const char * const pcc4_periph_bus_sels[] = { "dummy", "dummy", "lposc", 24 + "sosc_div2", "frosc_div2", "xbar_divbus", 25 + "spll3_vcodiv", "spll3_pfd0_div1", }; 26 + static const char * const pcc4_periph_plat_sels[] = { "dummy", "sosc_div1", "frosc_div1", 27 + "spll3_pfd3_div2", "spll3_pfd3_div1", 28 + "spll3_pfd2_div2", "spll3_pfd2_div1", 29 + "spll3_pfd1_div2", }; 30 + static const char * const pcc5_periph_bus_sels[] = { "dummy", "dummy", "lposc", 31 + "sosc_div2", "frosc_div2", "lpav_bus_clk", 32 + "pll4_vcodiv", "pll4_pfd3_div1", }; 33 + static const char * const pcc5_periph_plat_sels[] = { "dummy", "pll4_pfd3_div2", "pll4_pfd2_div2", 34 + "pll4_pfd2_div1", "pll4_pfd1_div2", 35 + "pll4_pfd1_div1", "pll4_pfd0_div2", 36 + "pll4_pfd0_div1", }; 37 + static const char * const hifi_sels[] = { "frosc", "pll4", "pll4_pfd0", "sosc", 38 + "lvds", "dummy", "dummy", "dummy", }; 39 + static const char * const ddr_sels[] = { "frosc", "pll4_pfd1", "sosc", "lvds", 40 + "pll4", "pll4", "pll4", "pll4", }; 41 + static const char * const lpav_sels[] = { "frosc", "pll4_pfd1", "sosc", "lvds", }; 42 + static const char * const sai45_sels[] = { "spll3_pfd1_div1", "aud_clk1", "aud_clk2", "sosc", }; 43 + static const char * const sai67_sels[] = { "spll1_pfd2_div", "spll3_pfd1_div1", "aud_clk0", "aud_clk1", "aud_clk2", "sosc", "dummy", "dummy", }; 44 + static const char * const aud_clk1_sels[] = { "ext_aud_mclk2", "sai4_rx_bclk", "sai4_tx_bclk", "sai5_rx_bclk", "sai5_tx_bclk", "dummy", "dummy", "dummy", }; 45 + static const char * const aud_clk2_sels[] = { "ext_aud_mclk3", "sai6_rx_bclk", "sai6_tx_bclk", "sai7_rx_bclk", "sai7_tx_bclk", "spdif_rx", "dummy", "dummy", }; 46 + static const char * const enet_ts_sels[] = { "ext_rmii_clk", "ext_ts_clk", "rosc", "ext_aud_mclk", "sosc", "dummy", "dummy", "dummy"}; 47 + static const char * const xbar_divbus[] = { "xbar_divbus" }; 48 + static const char * const nic_per_divplat[] = { "nic_per_divplat" }; 49 + static const char * const lpav_axi_div[] = { "lpav_axi_div" }; 50 + static const char * const lpav_bus_div[] = { "lpav_bus_div" }; 51 + 52 + struct pcc_reset_dev { 53 + void __iomem *base; 54 + struct reset_controller_dev rcdev; 55 + const u32 *resets; 56 + /* Set to imx_ccm_lock to protect register access shared with clock control */ 57 + spinlock_t *lock; 58 + }; 59 + 60 + #define PCC_SW_RST BIT(28) 61 + #define to_pcc_reset_dev(_rcdev) container_of(_rcdev, struct pcc_reset_dev, rcdev) 62 + 63 + static const u32 pcc3_resets[] = { 64 + 0xa8, 0xac, 0xc8, 0xcc, 0xd0, 65 + 0xd4, 0xd8, 0xdc, 0xe0, 0xe4, 66 + 0xe8, 0xec, 0xf0 67 + }; 68 + 69 + static const u32 pcc4_resets[] = { 70 + 0x4, 0x8, 0xc, 0x10, 0x14, 71 + 0x18, 0x1c, 0x20, 0x24, 0x34, 72 + 0x38, 0x3c, 0x40, 0x44, 0x48, 73 + 0x4c, 0x54 74 + }; 75 + 76 + static const u32 pcc5_resets[] = { 77 + 0xa0, 0xa4, 0xa8, 0xac, 0xb0, 78 + 0xb4, 0xbc, 0xc0, 0xc8, 0xcc, 79 + 0xd0, 0xf0, 0xf4, 0xf8 80 + }; 81 + 82 + static int imx8ulp_pcc_assert(struct reset_controller_dev *rcdev, unsigned long id) 83 + { 84 + struct pcc_reset_dev *pcc_reset = to_pcc_reset_dev(rcdev); 85 + u32 offset = pcc_reset->resets[id]; 86 + unsigned long flags; 87 + u32 val; 88 + 89 + spin_lock_irqsave(pcc_reset->lock, flags); 90 + 91 + val = readl(pcc_reset->base + offset); 92 + val &= ~PCC_SW_RST; 93 + writel(val, pcc_reset->base + offset); 94 + 95 + spin_unlock_irqrestore(pcc_reset->lock, flags); 96 + 97 + return 0; 98 + } 99 + 100 + static int imx8ulp_pcc_deassert(struct reset_controller_dev *rcdev, unsigned long id) 101 + { 102 + struct pcc_reset_dev *pcc_reset = to_pcc_reset_dev(rcdev); 103 + u32 offset = pcc_reset->resets[id]; 104 + unsigned long flags; 105 + u32 val; 106 + 107 + spin_lock_irqsave(pcc_reset->lock, flags); 108 + 109 + val = readl(pcc_reset->base + offset); 110 + val |= PCC_SW_RST; 111 + writel(val, pcc_reset->base + offset); 112 + 113 + spin_unlock_irqrestore(pcc_reset->lock, flags); 114 + 115 + return 0; 116 + } 117 + 118 + static const struct reset_control_ops imx8ulp_pcc_reset_ops = { 119 + .assert = imx8ulp_pcc_assert, 120 + .deassert = imx8ulp_pcc_deassert, 121 + }; 122 + 123 + static int imx8ulp_pcc_reset_init(struct platform_device *pdev, void __iomem *base, 124 + const u32 *resets, unsigned int nr_resets) 125 + { 126 + struct device_node *np = pdev->dev.of_node; 127 + struct device *dev = &pdev->dev; 128 + struct pcc_reset_dev *pcc_reset; 129 + 130 + pcc_reset = devm_kzalloc(dev, sizeof(*pcc_reset), GFP_KERNEL); 131 + if (!pcc_reset) 132 + return -ENOMEM; 133 + 134 + pcc_reset->base = base; 135 + pcc_reset->lock = &imx_ccm_lock; 136 + pcc_reset->resets = resets; 137 + pcc_reset->rcdev.owner = THIS_MODULE; 138 + pcc_reset->rcdev.nr_resets = nr_resets; 139 + pcc_reset->rcdev.ops = &imx8ulp_pcc_reset_ops; 140 + pcc_reset->rcdev.of_node = np; 141 + 142 + return devm_reset_controller_register(dev, &pcc_reset->rcdev); 143 + } 144 + 145 + static int imx8ulp_clk_cgc1_init(struct platform_device *pdev) 146 + { 147 + struct device *dev = &pdev->dev; 148 + struct clk_hw_onecell_data *clk_data; 149 + struct clk_hw **clks; 150 + void __iomem *base; 151 + 152 + clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, IMX8ULP_CLK_CGC1_END), 153 + GFP_KERNEL); 154 + if (!clk_data) 155 + return -ENOMEM; 156 + 157 + clk_data->num = IMX8ULP_CLK_CGC1_END; 158 + clks = clk_data->hws; 159 + 160 + clks[IMX8ULP_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0); 161 + 162 + /* CGC1 */ 163 + base = devm_platform_ioremap_resource(pdev, 0); 164 + if (WARN_ON(IS_ERR(base))) 165 + return PTR_ERR(base); 166 + 167 + clks[IMX8ULP_CLK_SPLL2_PRE_SEL] = imx_clk_hw_mux_flags("spll2_pre_sel", base + 0x510, 0, 1, pll_pre_sels, ARRAY_SIZE(pll_pre_sels), CLK_SET_PARENT_GATE); 168 + clks[IMX8ULP_CLK_SPLL3_PRE_SEL] = imx_clk_hw_mux_flags("spll3_pre_sel", base + 0x610, 0, 1, pll_pre_sels, ARRAY_SIZE(pll_pre_sels), CLK_SET_PARENT_GATE); 169 + 170 + clks[IMX8ULP_CLK_SPLL2] = imx_clk_hw_pllv4(IMX_PLLV4_IMX8ULP, "spll2", "spll2_pre_sel", base + 0x500); 171 + clks[IMX8ULP_CLK_SPLL3] = imx_clk_hw_pllv4(IMX_PLLV4_IMX8ULP, "spll3", "spll3_pre_sel", base + 0x600); 172 + clks[IMX8ULP_CLK_SPLL3_VCODIV] = imx_clk_hw_divider("spll3_vcodiv", "spll3", base + 0x604, 0, 6); 173 + 174 + clks[IMX8ULP_CLK_SPLL3_PFD0] = imx_clk_hw_pfdv2(IMX_PFDV2_IMX8ULP, "spll3_pfd0", "spll3_vcodiv", base + 0x614, 0); 175 + clks[IMX8ULP_CLK_SPLL3_PFD1] = imx_clk_hw_pfdv2(IMX_PFDV2_IMX8ULP, "spll3_pfd1", "spll3_vcodiv", base + 0x614, 1); 176 + clks[IMX8ULP_CLK_SPLL3_PFD2] = imx_clk_hw_pfdv2(IMX_PFDV2_IMX8ULP, "spll3_pfd2", "spll3_vcodiv", base + 0x614, 2); 177 + clks[IMX8ULP_CLK_SPLL3_PFD3] = imx_clk_hw_pfdv2(IMX_PFDV2_IMX8ULP, "spll3_pfd3", "spll3_vcodiv", base + 0x614, 3); 178 + 179 + clks[IMX8ULP_CLK_SPLL3_PFD0_DIV1_GATE] = imx_clk_hw_gate_dis("spll3_pfd0_div1_gate", "spll3_pfd0", base + 0x608, 7); 180 + clks[IMX8ULP_CLK_SPLL3_PFD0_DIV2_GATE] = imx_clk_hw_gate_dis("spll3_pfd0_div2_gate", "spll3_pfd0", base + 0x608, 15); 181 + clks[IMX8ULP_CLK_SPLL3_PFD1_DIV1_GATE] = imx_clk_hw_gate_dis("spll3_pfd1_div1_gate", "spll3_pfd1", base + 0x608, 23); 182 + clks[IMX8ULP_CLK_SPLL3_PFD1_DIV2_GATE] = imx_clk_hw_gate_dis("spll3_pfd1_div2_gate", "spll3_pfd1", base + 0x608, 31); 183 + clks[IMX8ULP_CLK_SPLL3_PFD2_DIV1_GATE] = imx_clk_hw_gate_dis("spll3_pfd2_div1_gate", "spll3_pfd2", base + 0x60c, 7); 184 + clks[IMX8ULP_CLK_SPLL3_PFD2_DIV2_GATE] = imx_clk_hw_gate_dis("spll3_pfd2_div2_gate", "spll3_pfd2", base + 0x60c, 15); 185 + clks[IMX8ULP_CLK_SPLL3_PFD3_DIV1_GATE] = imx_clk_hw_gate_dis("spll3_pfd3_div1_gate", "spll3_pfd3", base + 0x60c, 23); 186 + clks[IMX8ULP_CLK_SPLL3_PFD3_DIV2_GATE] = imx_clk_hw_gate_dis("spll3_pfd3_div2_gate", "spll3_pfd3", base + 0x60c, 31); 187 + clks[IMX8ULP_CLK_SPLL3_PFD0_DIV1] = imx_clk_hw_divider("spll3_pfd0_div1", "spll3_pfd0_div1_gate", base + 0x608, 0, 6); 188 + clks[IMX8ULP_CLK_SPLL3_PFD0_DIV2] = imx_clk_hw_divider("spll3_pfd0_div2", "spll3_pfd0_div2_gate", base + 0x608, 8, 6); 189 + clks[IMX8ULP_CLK_SPLL3_PFD1_DIV1] = imx_clk_hw_divider("spll3_pfd1_div1", "spll3_pfd1_div1_gate", base + 0x608, 16, 6); 190 + clks[IMX8ULP_CLK_SPLL3_PFD1_DIV2] = imx_clk_hw_divider("spll3_pfd1_div2", "spll3_pfd1_div2_gate", base + 0x608, 24, 6); 191 + clks[IMX8ULP_CLK_SPLL3_PFD2_DIV1] = imx_clk_hw_divider("spll3_pfd2_div1", "spll3_pfd2_div1_gate", base + 0x60c, 0, 6); 192 + clks[IMX8ULP_CLK_SPLL3_PFD2_DIV2] = imx_clk_hw_divider("spll3_pfd2_div2", "spll3_pfd2_div2_gate", base + 0x60c, 8, 6); 193 + clks[IMX8ULP_CLK_SPLL3_PFD3_DIV1] = imx_clk_hw_divider("spll3_pfd3_div1", "spll3_pfd3_div1_gate", base + 0x60c, 16, 6); 194 + clks[IMX8ULP_CLK_SPLL3_PFD3_DIV2] = imx_clk_hw_divider("spll3_pfd3_div2", "spll3_pfd3_div2_gate", base + 0x60c, 24, 6); 195 + 196 + clks[IMX8ULP_CLK_A35_SEL] = imx_clk_hw_mux2("a35_sel", base + 0x14, 28, 2, a35_sels, ARRAY_SIZE(a35_sels)); 197 + clks[IMX8ULP_CLK_A35_DIV] = imx_clk_hw_divider_flags("a35_div", "a35_sel", base + 0x14, 21, 6, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL); 198 + 199 + clks[IMX8ULP_CLK_NIC_SEL] = imx_clk_hw_mux2("nic_sel", base + 0x34, 28, 2, nic_sels, ARRAY_SIZE(nic_sels)); 200 + clks[IMX8ULP_CLK_NIC_AD_DIVPLAT] = imx_clk_hw_divider_flags("nic_ad_divplat", "nic_sel", base + 0x34, 21, 6, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL); 201 + clks[IMX8ULP_CLK_NIC_PER_DIVPLAT] = imx_clk_hw_divider_flags("nic_per_divplat", "nic_ad_divplat", base + 0x34, 14, 6, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL); 202 + clks[IMX8ULP_CLK_XBAR_AD_DIVPLAT] = imx_clk_hw_divider_flags("xbar_ad_divplat", "nic_ad_divplat", base + 0x38, 14, 6, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL); 203 + clks[IMX8ULP_CLK_XBAR_DIVBUS] = imx_clk_hw_divider_flags("xbar_divbus", "nic_ad_divplat", base + 0x38, 7, 6, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL); 204 + clks[IMX8ULP_CLK_XBAR_AD_SLOW] = imx_clk_hw_divider_flags("xbar_ad_slow", "nic_ad_divplat", base + 0x38, 0, 6, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL); 205 + 206 + clks[IMX8ULP_CLK_SOSC_DIV1_GATE] = imx_clk_hw_gate_dis("sosc_div1_gate", "sosc", base + 0x108, 7); 207 + clks[IMX8ULP_CLK_SOSC_DIV2_GATE] = imx_clk_hw_gate_dis("sosc_div2_gate", "sosc", base + 0x108, 15); 208 + clks[IMX8ULP_CLK_SOSC_DIV3_GATE] = imx_clk_hw_gate_dis("sosc_div3_gate", "sosc", base + 0x108, 23); 209 + clks[IMX8ULP_CLK_SOSC_DIV1] = imx_clk_hw_divider("sosc_div1", "sosc_div1_gate", base + 0x108, 0, 6); 210 + clks[IMX8ULP_CLK_SOSC_DIV2] = imx_clk_hw_divider("sosc_div2", "sosc_div2_gate", base + 0x108, 8, 6); 211 + clks[IMX8ULP_CLK_SOSC_DIV3] = imx_clk_hw_divider("sosc_div3", "sosc_div3_gate", base + 0x108, 16, 6); 212 + 213 + clks[IMX8ULP_CLK_FROSC_DIV1_GATE] = imx_clk_hw_gate_dis("frosc_div1_gate", "frosc", base + 0x208, 7); 214 + clks[IMX8ULP_CLK_FROSC_DIV2_GATE] = imx_clk_hw_gate_dis("frosc_div2_gate", "frosc", base + 0x208, 15); 215 + clks[IMX8ULP_CLK_FROSC_DIV3_GATE] = imx_clk_hw_gate_dis("frosc_div3_gate", "frosc", base + 0x208, 23); 216 + clks[IMX8ULP_CLK_FROSC_DIV1] = imx_clk_hw_divider("frosc_div1", "frosc_div1_gate", base + 0x208, 0, 6); 217 + clks[IMX8ULP_CLK_FROSC_DIV2] = imx_clk_hw_divider("frosc_div2", "frosc_div2_gate", base + 0x208, 8, 6); 218 + clks[IMX8ULP_CLK_FROSC_DIV3] = imx_clk_hw_divider("frosc_div3", "frosc_div3_gate", base + 0x208, 16, 6); 219 + clks[IMX8ULP_CLK_AUD_CLK1] = imx_clk_hw_mux2("aud_clk1", base + 0x900, 0, 3, aud_clk1_sels, ARRAY_SIZE(aud_clk1_sels)); 220 + clks[IMX8ULP_CLK_SAI4_SEL] = imx_clk_hw_mux2("sai4_sel", base + 0x904, 0, 2, sai45_sels, ARRAY_SIZE(sai45_sels)); 221 + clks[IMX8ULP_CLK_SAI5_SEL] = imx_clk_hw_mux2("sai5_sel", base + 0x904, 8, 2, sai45_sels, ARRAY_SIZE(sai45_sels)); 222 + clks[IMX8ULP_CLK_ENET_TS_SEL] = imx_clk_hw_mux2("enet_ts", base + 0x700, 24, 3, enet_ts_sels, ARRAY_SIZE(enet_ts_sels)); 223 + 224 + imx_check_clk_hws(clks, clk_data->num); 225 + 226 + return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data); 227 + } 228 + 229 + static int imx8ulp_clk_cgc2_init(struct platform_device *pdev) 230 + { 231 + struct device *dev = &pdev->dev; 232 + struct clk_hw_onecell_data *clk_data; 233 + struct clk_hw **clks; 234 + void __iomem *base; 235 + 236 + clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, IMX8ULP_CLK_CGC2_END), 237 + GFP_KERNEL); 238 + if (!clk_data) 239 + return -ENOMEM; 240 + 241 + clk_data->num = IMX8ULP_CLK_CGC2_END; 242 + clks = clk_data->hws; 243 + 244 + /* CGC2 */ 245 + base = devm_platform_ioremap_resource(pdev, 0); 246 + if (WARN_ON(IS_ERR(base))) 247 + return PTR_ERR(base); 248 + 249 + clks[IMX8ULP_CLK_PLL4_PRE_SEL] = imx_clk_hw_mux_flags("pll4_pre_sel", base + 0x610, 0, 1, pll_pre_sels, ARRAY_SIZE(pll_pre_sels), CLK_SET_PARENT_GATE); 250 + 251 + clks[IMX8ULP_CLK_PLL4] = imx_clk_hw_pllv4(IMX_PLLV4_IMX8ULP, "pll4", "pll4_pre_sel", base + 0x600); 252 + clks[IMX8ULP_CLK_PLL4_VCODIV] = imx_clk_hw_divider("pll4_vcodiv", "pll4", base + 0x604, 0, 6); 253 + 254 + clks[IMX8ULP_CLK_HIFI_SEL] = imx_clk_hw_mux_flags("hifi_sel", base + 0x14, 28, 3, hifi_sels, ARRAY_SIZE(hifi_sels), CLK_SET_PARENT_GATE); 255 + clks[IMX8ULP_CLK_HIFI_DIVCORE] = imx_clk_hw_divider("hifi_core_div", "hifi_sel", base + 0x14, 21, 6); 256 + clks[IMX8ULP_CLK_HIFI_DIVPLAT] = imx_clk_hw_divider("hifi_plat_div", "hifi_core_div", base + 0x14, 14, 6); 257 + 258 + clks[IMX8ULP_CLK_DDR_SEL] = imx_clk_hw_mux_flags("ddr_sel", base + 0x40, 28, 3, ddr_sels, ARRAY_SIZE(ddr_sels), CLK_SET_PARENT_GATE); 259 + clks[IMX8ULP_CLK_DDR_DIV] = imx_clk_hw_divider_flags("ddr_div", "ddr_sel", base + 0x40, 21, 6, CLK_IS_CRITICAL); 260 + clks[IMX8ULP_CLK_LPAV_AXI_SEL] = imx_clk_hw_mux("lpav_sel", base + 0x3c, 28, 2, lpav_sels, ARRAY_SIZE(lpav_sels)); 261 + clks[IMX8ULP_CLK_LPAV_AXI_DIV] = imx_clk_hw_divider_flags("lpav_axi_div", "lpav_sel", base + 0x3c, 21, 6, CLK_IS_CRITICAL); 262 + clks[IMX8ULP_CLK_LPAV_AHB_DIV] = imx_clk_hw_divider_flags("lpav_ahb_div", "lpav_axi_div", base + 0x3c, 14, 6, CLK_IS_CRITICAL); 263 + clks[IMX8ULP_CLK_LPAV_BUS_DIV] = imx_clk_hw_divider_flags("lpav_bus_div", "lpav_axi_div", base + 0x3c, 7, 6, CLK_IS_CRITICAL); 264 + 265 + clks[IMX8ULP_CLK_PLL4_PFD0] = imx_clk_hw_pfdv2(IMX_PFDV2_IMX8ULP, "pll4_pfd0", "pll4_vcodiv", base + 0x614, 0); 266 + clks[IMX8ULP_CLK_PLL4_PFD1] = imx_clk_hw_pfdv2(IMX_PFDV2_IMX8ULP, "pll4_pfd1", "pll4_vcodiv", base + 0x614, 1); 267 + clks[IMX8ULP_CLK_PLL4_PFD2] = imx_clk_hw_pfdv2(IMX_PFDV2_IMX8ULP, "pll4_pfd2", "pll4_vcodiv", base + 0x614, 2); 268 + clks[IMX8ULP_CLK_PLL4_PFD3] = imx_clk_hw_pfdv2(IMX_PFDV2_IMX8ULP, "pll4_pfd3", "pll4_vcodiv", base + 0x614, 3); 269 + 270 + clks[IMX8ULP_CLK_PLL4_PFD0_DIV1_GATE] = imx_clk_hw_gate_dis("pll4_pfd0_div1_gate", "pll4_pfd0", base + 0x608, 7); 271 + clks[IMX8ULP_CLK_PLL4_PFD0_DIV2_GATE] = imx_clk_hw_gate_dis("pll4_pfd0_div2_gate", "pll4_pfd0", base + 0x608, 15); 272 + clks[IMX8ULP_CLK_PLL4_PFD1_DIV1_GATE] = imx_clk_hw_gate_dis("pll4_pfd1_div1_gate", "pll4_pfd1", base + 0x608, 23); 273 + clks[IMX8ULP_CLK_PLL4_PFD1_DIV2_GATE] = imx_clk_hw_gate_dis("pll4_pfd1_div2_gate", "pll4_pfd1", base + 0x608, 31); 274 + clks[IMX8ULP_CLK_PLL4_PFD2_DIV1_GATE] = imx_clk_hw_gate_dis("pll4_pfd2_div1_gate", "pll4_pfd2", base + 0x60c, 7); 275 + clks[IMX8ULP_CLK_PLL4_PFD2_DIV2_GATE] = imx_clk_hw_gate_dis("pll4_pfd2_div2_gate", "pll4_pfd2", base + 0x60c, 15); 276 + clks[IMX8ULP_CLK_PLL4_PFD3_DIV1_GATE] = imx_clk_hw_gate_dis("pll4_pfd3_div1_gate", "pll4_pfd3", base + 0x60c, 23); 277 + clks[IMX8ULP_CLK_PLL4_PFD3_DIV2_GATE] = imx_clk_hw_gate_dis("pll4_pfd3_div2_gate", "pll4_pfd3", base + 0x60c, 31); 278 + clks[IMX8ULP_CLK_PLL4_PFD0_DIV1] = imx_clk_hw_divider("pll4_pfd0_div1", "pll4_pfd0_div1_gate", base + 0x608, 0, 6); 279 + clks[IMX8ULP_CLK_PLL4_PFD0_DIV2] = imx_clk_hw_divider("pll4_pfd0_div2", "pll4_pfd0_div2_gate", base + 0x608, 8, 6); 280 + clks[IMX8ULP_CLK_PLL4_PFD1_DIV1] = imx_clk_hw_divider("pll4_pfd1_div1", "pll4_pfd1_div1_gate", base + 0x608, 16, 6); 281 + clks[IMX8ULP_CLK_PLL4_PFD1_DIV2] = imx_clk_hw_divider("pll4_pfd1_div2", "pll4_pfd1_div2_gate", base + 0x608, 24, 6); 282 + clks[IMX8ULP_CLK_PLL4_PFD2_DIV1] = imx_clk_hw_divider("pll4_pfd2_div1", "pll4_pfd2_div1_gate", base + 0x60c, 0, 6); 283 + clks[IMX8ULP_CLK_PLL4_PFD2_DIV2] = imx_clk_hw_divider("pll4_pfd2_div2", "pll4_pfd2_div2_gate", base + 0x60c, 8, 6); 284 + clks[IMX8ULP_CLK_PLL4_PFD3_DIV1] = imx_clk_hw_divider("pll4_pfd3_div1", "pll4_pfd3_div1_gate", base + 0x60c, 16, 6); 285 + clks[IMX8ULP_CLK_PLL4_PFD3_DIV2] = imx_clk_hw_divider("pll4_pfd3_div2", "pll4_pfd3_div2_gate", base + 0x60c, 24, 6); 286 + 287 + clks[IMX8ULP_CLK_CGC2_SOSC_DIV1_GATE] = imx_clk_hw_gate_dis("cgc2_sosc_div1_gate", "sosc", base + 0x108, 7); 288 + clks[IMX8ULP_CLK_CGC2_SOSC_DIV2_GATE] = imx_clk_hw_gate_dis("cgc2_sosc_div2_gate", "sosc", base + 0x108, 15); 289 + clks[IMX8ULP_CLK_CGC2_SOSC_DIV3_GATE] = imx_clk_hw_gate_dis("cgc2_sosc_div3_gate", "sosc", base + 0x108, 23); 290 + clks[IMX8ULP_CLK_CGC2_SOSC_DIV1] = imx_clk_hw_divider("cgc2_sosc_div1", "cgc2_sosc_div1_gate", base + 0x108, 0, 6); 291 + clks[IMX8ULP_CLK_CGC2_SOSC_DIV2] = imx_clk_hw_divider("cgc2_sosc_div2", "cgc2_sosc_div2_gate", base + 0x108, 8, 6); 292 + clks[IMX8ULP_CLK_CGC2_SOSC_DIV3] = imx_clk_hw_divider("cgc2_sosc_div3", "cgc2_sosc_div3_gate", base + 0x108, 16, 6); 293 + 294 + clks[IMX8ULP_CLK_CGC2_FROSC_DIV1_GATE] = imx_clk_hw_gate_dis("cgc2_frosc_div1_gate", "frosc", base + 0x208, 7); 295 + clks[IMX8ULP_CLK_CGC2_FROSC_DIV2_GATE] = imx_clk_hw_gate_dis("cgc2_frosc_div2_gate", "frosc", base + 0x208, 15); 296 + clks[IMX8ULP_CLK_CGC2_FROSC_DIV3_GATE] = imx_clk_hw_gate_dis("cgc2_frosc_div3_gate", "frosc", base + 0x208, 23); 297 + clks[IMX8ULP_CLK_CGC2_FROSC_DIV1] = imx_clk_hw_divider("cgc2_frosc_div1", "cgc2_frosc_div1_gate", base + 0x208, 0, 6); 298 + clks[IMX8ULP_CLK_CGC2_FROSC_DIV2] = imx_clk_hw_divider("cgc2_frosc_div2", "cgc2_frosc_div2_gate", base + 0x208, 8, 6); 299 + clks[IMX8ULP_CLK_CGC2_FROSC_DIV3] = imx_clk_hw_divider("cgc2_frosc_div3", "cgc2_frosc_div3_gate", base + 0x208, 16, 6); 300 + clks[IMX8ULP_CLK_AUD_CLK2] = imx_clk_hw_mux2("aud_clk2", base + 0x900, 0, 3, aud_clk2_sels, ARRAY_SIZE(aud_clk2_sels)); 301 + clks[IMX8ULP_CLK_SAI6_SEL] = imx_clk_hw_mux2("sai6_sel", base + 0x904, 0, 3, sai67_sels, ARRAY_SIZE(sai67_sels)); 302 + clks[IMX8ULP_CLK_SAI7_SEL] = imx_clk_hw_mux2("sai7_sel", base + 0x904, 8, 3, sai67_sels, ARRAY_SIZE(sai67_sels)); 303 + clks[IMX8ULP_CLK_SPDIF_SEL] = imx_clk_hw_mux2("spdif_sel", base + 0x910, 0, 3, sai67_sels, ARRAY_SIZE(sai67_sels)); 304 + clks[IMX8ULP_CLK_DSI_PHY_REF] = imx_clk_hw_fixed("dsi_phy_ref", 24000000); 305 + 306 + imx_check_clk_hws(clks, clk_data->num); 307 + 308 + return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data); 309 + } 310 + 311 + static int imx8ulp_clk_pcc3_init(struct platform_device *pdev) 312 + { 313 + struct device *dev = &pdev->dev; 314 + struct clk_hw_onecell_data *clk_data; 315 + struct clk_hw **clks; 316 + void __iomem *base; 317 + int ret; 318 + 319 + clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, IMX8ULP_CLK_PCC3_END), 320 + GFP_KERNEL); 321 + if (!clk_data) 322 + return -ENOMEM; 323 + 324 + clk_data->num = IMX8ULP_CLK_PCC3_END; 325 + clks = clk_data->hws; 326 + 327 + /* PCC3 */ 328 + base = devm_platform_ioremap_resource(pdev, 0); 329 + if (WARN_ON(IS_ERR(base))) 330 + return PTR_ERR(base); 331 + 332 + clks[IMX8ULP_CLK_WDOG3] = imx8ulp_clk_hw_composite("wdog3", pcc3_periph_bus_sels, ARRAY_SIZE(pcc3_periph_bus_sels), true, true, true, base + 0xa8, 1); 333 + clks[IMX8ULP_CLK_WDOG4] = imx8ulp_clk_hw_composite("wdog4", pcc3_periph_bus_sels, ARRAY_SIZE(pcc3_periph_bus_sels), true, true, true, base + 0xac, 1); 334 + clks[IMX8ULP_CLK_LPIT1] = imx8ulp_clk_hw_composite("lpit1", pcc3_periph_bus_sels, ARRAY_SIZE(pcc3_periph_bus_sels), true, true, true, base + 0xc8, 1); 335 + clks[IMX8ULP_CLK_TPM4] = imx8ulp_clk_hw_composite("tpm4", pcc3_periph_bus_sels, ARRAY_SIZE(pcc3_periph_bus_sels), true, true, true, base + 0xcc, 1); 336 + clks[IMX8ULP_CLK_TPM5] = imx8ulp_clk_hw_composite("tpm5", pcc3_periph_bus_sels, ARRAY_SIZE(pcc3_periph_bus_sels), true, true, true, base + 0xd0, 1); 337 + clks[IMX8ULP_CLK_FLEXIO1] = imx8ulp_clk_hw_composite("flexio1", pcc3_periph_bus_sels, ARRAY_SIZE(pcc3_periph_bus_sels), true, true, true, base + 0xd4, 1); 338 + clks[IMX8ULP_CLK_I3C2] = imx8ulp_clk_hw_composite("i3c2", pcc3_periph_bus_sels, ARRAY_SIZE(pcc3_periph_bus_sels), true, true, true, base + 0xd8, 1); 339 + clks[IMX8ULP_CLK_LPI2C4] = imx8ulp_clk_hw_composite("lpi2c4", pcc3_periph_bus_sels, ARRAY_SIZE(pcc3_periph_bus_sels), true, true, true, base + 0xdc, 1); 340 + clks[IMX8ULP_CLK_LPI2C5] = imx8ulp_clk_hw_composite("lpi2c5", pcc3_periph_bus_sels, ARRAY_SIZE(pcc3_periph_bus_sels), true, true, true, base + 0xe0, 1); 341 + clks[IMX8ULP_CLK_LPUART4] = imx8ulp_clk_hw_composite("lpuart4", pcc3_periph_bus_sels, ARRAY_SIZE(pcc3_periph_bus_sels), true, true, true, base + 0xe4, 1); 342 + clks[IMX8ULP_CLK_LPUART5] = imx8ulp_clk_hw_composite("lpuart5", pcc3_periph_bus_sels, ARRAY_SIZE(pcc3_periph_bus_sels), true, true, true, base + 0xe8, 1); 343 + clks[IMX8ULP_CLK_LPSPI4] = imx8ulp_clk_hw_composite("lpspi4", pcc3_periph_bus_sels, ARRAY_SIZE(pcc3_periph_bus_sels), true, true, true, base + 0xec, 1); 344 + clks[IMX8ULP_CLK_LPSPI5] = imx8ulp_clk_hw_composite("lpspi5", pcc3_periph_bus_sels, ARRAY_SIZE(pcc3_periph_bus_sels), true, true, true, base + 0xf0, 1); 345 + 346 + clks[IMX8ULP_CLK_DMA1_MP] = imx_clk_hw_gate("pcc_dma1_mp", "xbar_ad_divplat", base + 0x4, 30); 347 + clks[IMX8ULP_CLK_DMA1_CH0] = imx_clk_hw_gate("pcc_dma1_ch0", "xbar_ad_divplat", base + 0x8, 30); 348 + clks[IMX8ULP_CLK_DMA1_CH1] = imx_clk_hw_gate("pcc_dma1_ch1", "xbar_ad_divplat", base + 0xc, 30); 349 + clks[IMX8ULP_CLK_DMA1_CH2] = imx_clk_hw_gate("pcc_dma1_ch2", "xbar_ad_divplat", base + 0x10, 30); 350 + clks[IMX8ULP_CLK_DMA1_CH3] = imx_clk_hw_gate("pcc_dma1_ch3", "xbar_ad_divplat", base + 0x14, 30); 351 + clks[IMX8ULP_CLK_DMA1_CH4] = imx_clk_hw_gate("pcc_dma1_ch4", "xbar_ad_divplat", base + 0x18, 30); 352 + clks[IMX8ULP_CLK_DMA1_CH5] = imx_clk_hw_gate("pcc_dma1_ch5", "xbar_ad_divplat", base + 0x1c, 30); 353 + clks[IMX8ULP_CLK_DMA1_CH6] = imx_clk_hw_gate("pcc_dma1_ch6", "xbar_ad_divplat", base + 0x20, 30); 354 + clks[IMX8ULP_CLK_DMA1_CH7] = imx_clk_hw_gate("pcc_dma1_ch7", "xbar_ad_divplat", base + 0x24, 30); 355 + clks[IMX8ULP_CLK_DMA1_CH8] = imx_clk_hw_gate("pcc_dma1_ch8", "xbar_ad_divplat", base + 0x28, 30); 356 + clks[IMX8ULP_CLK_DMA1_CH9] = imx_clk_hw_gate("pcc_dma1_ch9", "xbar_ad_divplat", base + 0x2c, 30); 357 + clks[IMX8ULP_CLK_DMA1_CH10] = imx_clk_hw_gate("pcc_dma1_ch10", "xbar_ad_divplat", base + 0x30, 30); 358 + clks[IMX8ULP_CLK_DMA1_CH11] = imx_clk_hw_gate("pcc_dma1_ch11", "xbar_ad_divplat", base + 0x34, 30); 359 + clks[IMX8ULP_CLK_DMA1_CH12] = imx_clk_hw_gate("pcc_dma1_ch12", "xbar_ad_divplat", base + 0x38, 30); 360 + clks[IMX8ULP_CLK_DMA1_CH13] = imx_clk_hw_gate("pcc_dma1_ch13", "xbar_ad_divplat", base + 0x3c, 30); 361 + clks[IMX8ULP_CLK_DMA1_CH14] = imx_clk_hw_gate("pcc_dma1_ch14", "xbar_ad_divplat", base + 0x40, 30); 362 + clks[IMX8ULP_CLK_DMA1_CH15] = imx_clk_hw_gate("pcc_dma1_ch15", "xbar_ad_divplat", base + 0x44, 30); 363 + clks[IMX8ULP_CLK_DMA1_CH16] = imx_clk_hw_gate("pcc_dma1_ch16", "xbar_ad_divplat", base + 0x48, 30); 364 + clks[IMX8ULP_CLK_DMA1_CH17] = imx_clk_hw_gate("pcc_dma1_ch17", "xbar_ad_divplat", base + 0x4c, 30); 365 + clks[IMX8ULP_CLK_DMA1_CH18] = imx_clk_hw_gate("pcc_dma1_ch18", "xbar_ad_divplat", base + 0x50, 30); 366 + clks[IMX8ULP_CLK_DMA1_CH19] = imx_clk_hw_gate("pcc_dma1_ch19", "xbar_ad_divplat", base + 0x54, 30); 367 + clks[IMX8ULP_CLK_DMA1_CH20] = imx_clk_hw_gate("pcc_dma1_ch20", "xbar_ad_divplat", base + 0x58, 30); 368 + clks[IMX8ULP_CLK_DMA1_CH21] = imx_clk_hw_gate("pcc_dma1_ch21", "xbar_ad_divplat", base + 0x5c, 30); 369 + clks[IMX8ULP_CLK_DMA1_CH22] = imx_clk_hw_gate("pcc_dma1_ch22", "xbar_ad_divplat", base + 0x60, 30); 370 + clks[IMX8ULP_CLK_DMA1_CH23] = imx_clk_hw_gate("pcc_dma1_ch23", "xbar_ad_divplat", base + 0x64, 30); 371 + clks[IMX8ULP_CLK_DMA1_CH24] = imx_clk_hw_gate("pcc_dma1_ch24", "xbar_ad_divplat", base + 0x68, 30); 372 + clks[IMX8ULP_CLK_DMA1_CH25] = imx_clk_hw_gate("pcc_dma1_ch25", "xbar_ad_divplat", base + 0x6c, 30); 373 + clks[IMX8ULP_CLK_DMA1_CH26] = imx_clk_hw_gate("pcc_dma1_ch26", "xbar_ad_divplat", base + 0x70, 30); 374 + clks[IMX8ULP_CLK_DMA1_CH27] = imx_clk_hw_gate("pcc_dma1_ch27", "xbar_ad_divplat", base + 0x74, 30); 375 + clks[IMX8ULP_CLK_DMA1_CH28] = imx_clk_hw_gate("pcc_dma1_ch28", "xbar_ad_divplat", base + 0x78, 30); 376 + clks[IMX8ULP_CLK_DMA1_CH29] = imx_clk_hw_gate("pcc_dma1_ch29", "xbar_ad_divplat", base + 0x7c, 30); 377 + clks[IMX8ULP_CLK_DMA1_CH30] = imx_clk_hw_gate("pcc_dma1_ch30", "xbar_ad_divplat", base + 0x80, 30); 378 + clks[IMX8ULP_CLK_DMA1_CH31] = imx_clk_hw_gate("pcc_dma1_ch31", "xbar_ad_divplat", base + 0x84, 30); 379 + clks[IMX8ULP_CLK_MU0_B] = imx_clk_hw_gate("mu0_b", "xbar_ad_divplat", base + 0x88, 30); 380 + clks[IMX8ULP_CLK_MU3_A] = imx_clk_hw_gate("mu3_a", "xbar_ad_divplat", base + 0x8c, 30); 381 + 382 + imx_check_clk_hws(clks, clk_data->num); 383 + 384 + ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data); 385 + if (ret) 386 + return ret; 387 + 388 + imx_register_uart_clocks(1); 389 + 390 + /* register the pcc3 reset controller */ 391 + return imx8ulp_pcc_reset_init(pdev, base, pcc3_resets, ARRAY_SIZE(pcc3_resets)); 392 + } 393 + 394 + static int imx8ulp_clk_pcc4_init(struct platform_device *pdev) 395 + { 396 + struct device *dev = &pdev->dev; 397 + struct clk_hw_onecell_data *clk_data; 398 + struct clk_hw **clks; 399 + void __iomem *base; 400 + int ret; 401 + 402 + clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, IMX8ULP_CLK_PCC4_END), 403 + GFP_KERNEL); 404 + if (!clk_data) 405 + return -ENOMEM; 406 + 407 + clk_data->num = IMX8ULP_CLK_PCC4_END; 408 + clks = clk_data->hws; 409 + 410 + /* PCC4 */ 411 + base = devm_platform_ioremap_resource(pdev, 0); 412 + if (WARN_ON(IS_ERR(base))) 413 + return PTR_ERR(base); 414 + 415 + clks[IMX8ULP_CLK_FLEXSPI2] = imx8ulp_clk_hw_composite("flexspi2", pcc4_periph_plat_sels, ARRAY_SIZE(pcc4_periph_plat_sels), true, true, true, base + 0x4, 1); 416 + clks[IMX8ULP_CLK_TPM6] = imx8ulp_clk_hw_composite("tpm6", pcc4_periph_bus_sels, ARRAY_SIZE(pcc4_periph_bus_sels), true, true, true, base + 0x8, 1); 417 + clks[IMX8ULP_CLK_TPM7] = imx8ulp_clk_hw_composite("tpm7", pcc4_periph_bus_sels, ARRAY_SIZE(pcc4_periph_bus_sels), true, true, true, base + 0xc, 1); 418 + clks[IMX8ULP_CLK_LPI2C6] = imx8ulp_clk_hw_composite("lpi2c6", pcc4_periph_bus_sels, ARRAY_SIZE(pcc4_periph_bus_sels), true, true, true, base + 0x10, 1); 419 + clks[IMX8ULP_CLK_LPI2C7] = imx8ulp_clk_hw_composite("lpi2c7", pcc4_periph_bus_sels, ARRAY_SIZE(pcc4_periph_bus_sels), true, true, true, base + 0x14, 1); 420 + clks[IMX8ULP_CLK_LPUART6] = imx8ulp_clk_hw_composite("lpuart6", pcc4_periph_bus_sels, ARRAY_SIZE(pcc4_periph_bus_sels), true, true, true, base + 0x18, 1); 421 + clks[IMX8ULP_CLK_LPUART7] = imx8ulp_clk_hw_composite("lpuart7", pcc4_periph_bus_sels, ARRAY_SIZE(pcc4_periph_bus_sels), true, true, true, base + 0x1c, 1); 422 + clks[IMX8ULP_CLK_SAI4] = imx8ulp_clk_hw_composite("sai4", xbar_divbus, 1, false, false, true, base + 0x20, 1); /* sai ipg, NOT from sai sel */ 423 + clks[IMX8ULP_CLK_SAI5] = imx8ulp_clk_hw_composite("sai5", xbar_divbus, 1, false, false, true, base + 0x24, 1); /* sai ipg */ 424 + clks[IMX8ULP_CLK_PCTLE] = imx_clk_hw_gate("pctle", "xbar_divbus", base + 0x28, 30); 425 + clks[IMX8ULP_CLK_PCTLF] = imx_clk_hw_gate("pctlf", "xbar_divbus", base + 0x2c, 30); 426 + clks[IMX8ULP_CLK_USDHC0] = imx8ulp_clk_hw_composite("usdhc0", pcc4_periph_plat_sels, ARRAY_SIZE(pcc4_periph_plat_sels), true, false, true, base + 0x34, 1); 427 + clks[IMX8ULP_CLK_USDHC1] = imx8ulp_clk_hw_composite("usdhc1", pcc4_periph_plat_sels, ARRAY_SIZE(pcc4_periph_plat_sels), true, false, true, base + 0x38, 1); 428 + clks[IMX8ULP_CLK_USDHC2] = imx8ulp_clk_hw_composite("usdhc2", pcc4_periph_plat_sels, ARRAY_SIZE(pcc4_periph_plat_sels), true, false, true, base + 0x3c, 1); 429 + clks[IMX8ULP_CLK_USB0] = imx8ulp_clk_hw_composite("usb0", nic_per_divplat, 1, false, false, true, base + 0x40, 1); 430 + clks[IMX8ULP_CLK_USB0_PHY] = imx8ulp_clk_hw_composite("usb0_phy", xbar_divbus, 1, false, false, true, base + 0x44, 1); 431 + clks[IMX8ULP_CLK_USB1] = imx8ulp_clk_hw_composite("usb1", nic_per_divplat, 1, false, false, true, base + 0x48, 1); 432 + clks[IMX8ULP_CLK_USB1_PHY] = imx8ulp_clk_hw_composite("usb1_phy", xbar_divbus, 1, false, false, true, base + 0x4c, 1); 433 + clks[IMX8ULP_CLK_USB_XBAR] = imx_clk_hw_gate("usb_xbar", "xbar_divbus", base + 0x50, 30); 434 + clks[IMX8ULP_CLK_ENET] = imx8ulp_clk_hw_composite("enet", nic_per_divplat, 1, false, false, true, base + 0x54, 1); 435 + clks[IMX8ULP_CLK_RGPIOE] = imx_clk_hw_gate("rgpioe", "nic_per_divplat", base + 0x78, 30); 436 + clks[IMX8ULP_CLK_RGPIOF] = imx_clk_hw_gate("rgpiof", "nic_per_divplat", base + 0x7c, 30); 437 + 438 + imx_check_clk_hws(clks, clk_data->num); 439 + 440 + ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data); 441 + if (ret) 442 + return ret; 443 + 444 + /* register the pcc4 reset controller */ 445 + return imx8ulp_pcc_reset_init(pdev, base, pcc4_resets, ARRAY_SIZE(pcc4_resets)); 446 + 447 + } 448 + 449 + static int imx8ulp_clk_pcc5_init(struct platform_device *pdev) 450 + { 451 + struct device *dev = &pdev->dev; 452 + struct clk_hw_onecell_data *clk_data; 453 + struct clk_hw **clks; 454 + void __iomem *base; 455 + int ret; 456 + 457 + clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, IMX8ULP_CLK_PCC5_END), 458 + GFP_KERNEL); 459 + if (!clk_data) 460 + return -ENOMEM; 461 + 462 + clk_data->num = IMX8ULP_CLK_PCC5_END; 463 + clks = clk_data->hws; 464 + 465 + /* PCC5 */ 466 + base = devm_platform_ioremap_resource(pdev, 0); 467 + if (WARN_ON(IS_ERR(base))) 468 + return PTR_ERR(base); 469 + 470 + clks[IMX8ULP_CLK_DMA2_MP] = imx_clk_hw_gate("pcc_dma2_mp", "lpav_axi_div", base + 0x0, 30); 471 + clks[IMX8ULP_CLK_DMA2_CH0] = imx_clk_hw_gate("pcc_dma2_ch0", "lpav_axi_div", base + 0x4, 30); 472 + clks[IMX8ULP_CLK_DMA2_CH1] = imx_clk_hw_gate("pcc_dma2_ch1", "lpav_axi_div", base + 0x8, 30); 473 + clks[IMX8ULP_CLK_DMA2_CH2] = imx_clk_hw_gate("pcc_dma2_ch2", "lpav_axi_div", base + 0xc, 30); 474 + clks[IMX8ULP_CLK_DMA2_CH3] = imx_clk_hw_gate("pcc_dma2_ch3", "lpav_axi_div", base + 0x10, 30); 475 + clks[IMX8ULP_CLK_DMA2_CH4] = imx_clk_hw_gate("pcc_dma2_ch4", "lpav_axi_div", base + 0x14, 30); 476 + clks[IMX8ULP_CLK_DMA2_CH5] = imx_clk_hw_gate("pcc_dma2_ch5", "lpav_axi_div", base + 0x18, 30); 477 + clks[IMX8ULP_CLK_DMA2_CH6] = imx_clk_hw_gate("pcc_dma2_ch6", "lpav_axi_div", base + 0x1c, 30); 478 + clks[IMX8ULP_CLK_DMA2_CH7] = imx_clk_hw_gate("pcc_dma2_ch7", "lpav_axi_div", base + 0x20, 30); 479 + clks[IMX8ULP_CLK_DMA2_CH8] = imx_clk_hw_gate("pcc_dma2_ch8", "lpav_axi_div", base + 0x24, 30); 480 + clks[IMX8ULP_CLK_DMA2_CH9] = imx_clk_hw_gate("pcc_dma2_ch9", "lpav_axi_div", base + 0x28, 30); 481 + clks[IMX8ULP_CLK_DMA2_CH10] = imx_clk_hw_gate("pcc_dma2_ch10", "lpav_axi_div", base + 0x2c, 30); 482 + clks[IMX8ULP_CLK_DMA2_CH11] = imx_clk_hw_gate("pcc_dma2_ch11", "lpav_axi_div", base + 0x30, 30); 483 + clks[IMX8ULP_CLK_DMA2_CH12] = imx_clk_hw_gate("pcc_dma2_ch12", "lpav_axi_div", base + 0x34, 30); 484 + clks[IMX8ULP_CLK_DMA2_CH13] = imx_clk_hw_gate("pcc_dma2_ch13", "lpav_axi_div", base + 0x38, 30); 485 + clks[IMX8ULP_CLK_DMA2_CH14] = imx_clk_hw_gate("pcc_dma2_ch14", "lpav_axi_div", base + 0x3c, 30); 486 + clks[IMX8ULP_CLK_DMA2_CH15] = imx_clk_hw_gate("pcc_dma2_ch15", "lpav_axi_div", base + 0x40, 30); 487 + clks[IMX8ULP_CLK_DMA2_CH16] = imx_clk_hw_gate("pcc_dma2_ch16", "lpav_axi_div", base + 0x44, 30); 488 + clks[IMX8ULP_CLK_DMA2_CH17] = imx_clk_hw_gate("pcc_dma2_ch17", "lpav_axi_div", base + 0x48, 30); 489 + clks[IMX8ULP_CLK_DMA2_CH18] = imx_clk_hw_gate("pcc_dma2_ch18", "lpav_axi_div", base + 0x4c, 30); 490 + clks[IMX8ULP_CLK_DMA2_CH19] = imx_clk_hw_gate("pcc_dma2_ch19", "lpav_axi_div", base + 0x50, 30); 491 + clks[IMX8ULP_CLK_DMA2_CH20] = imx_clk_hw_gate("pcc_dma2_ch20", "lpav_axi_div", base + 0x54, 30); 492 + clks[IMX8ULP_CLK_DMA2_CH21] = imx_clk_hw_gate("pcc_dma2_ch21", "lpav_axi_div", base + 0x58, 30); 493 + clks[IMX8ULP_CLK_DMA2_CH22] = imx_clk_hw_gate("pcc_dma2_ch22", "lpav_axi_div", base + 0x5c, 30); 494 + clks[IMX8ULP_CLK_DMA2_CH23] = imx_clk_hw_gate("pcc_dma2_ch23", "lpav_axi_div", base + 0x60, 30); 495 + clks[IMX8ULP_CLK_DMA2_CH24] = imx_clk_hw_gate("pcc_dma2_ch24", "lpav_axi_div", base + 0x64, 30); 496 + clks[IMX8ULP_CLK_DMA2_CH25] = imx_clk_hw_gate("pcc_dma2_ch25", "lpav_axi_div", base + 0x68, 30); 497 + clks[IMX8ULP_CLK_DMA2_CH26] = imx_clk_hw_gate("pcc_dma2_ch26", "lpav_axi_div", base + 0x6c, 30); 498 + clks[IMX8ULP_CLK_DMA2_CH27] = imx_clk_hw_gate("pcc_dma2_ch27", "lpav_axi_div", base + 0x70, 30); 499 + clks[IMX8ULP_CLK_DMA2_CH28] = imx_clk_hw_gate("pcc_dma2_ch28", "lpav_axi_div", base + 0x74, 30); 500 + clks[IMX8ULP_CLK_DMA2_CH29] = imx_clk_hw_gate("pcc_dma2_ch29", "lpav_axi_div", base + 0x78, 30); 501 + clks[IMX8ULP_CLK_DMA2_CH30] = imx_clk_hw_gate("pcc_dma2_ch30", "lpav_axi_div", base + 0x7c, 30); 502 + clks[IMX8ULP_CLK_DMA2_CH31] = imx_clk_hw_gate("pcc_dma2_ch31", "lpav_axi_div", base + 0x80, 30); 503 + 504 + clks[IMX8ULP_CLK_AVD_SIM] = imx_clk_hw_gate("avd_sim", "lpav_bus_div", base + 0x94, 30); 505 + clks[IMX8ULP_CLK_TPM8] = imx8ulp_clk_hw_composite("tpm8", pcc5_periph_bus_sels, ARRAY_SIZE(pcc5_periph_bus_sels), true, true, true, base + 0xa0, 1); 506 + clks[IMX8ULP_CLK_MU2_B] = imx_clk_hw_gate("mu2_b", "lpav_bus_div", base + 0x84, 30); 507 + clks[IMX8ULP_CLK_MU3_B] = imx_clk_hw_gate("mu3_b", "lpav_bus_div", base + 0x88, 30); 508 + clks[IMX8ULP_CLK_SAI6] = imx8ulp_clk_hw_composite("sai6", lpav_bus_div, 1, false, false, true, base + 0xa4, 1); 509 + clks[IMX8ULP_CLK_SAI7] = imx8ulp_clk_hw_composite("sai7", lpav_bus_div, 1, false, false, true, base + 0xa8, 1); 510 + clks[IMX8ULP_CLK_SPDIF] = imx8ulp_clk_hw_composite("spdif", lpav_bus_div, 1, false, false, true, base + 0xac, 1); 511 + clks[IMX8ULP_CLK_ISI] = imx8ulp_clk_hw_composite("isi", lpav_axi_div, 1, false, false, true, base + 0xb0, 1); 512 + clks[IMX8ULP_CLK_CSI_REGS] = imx8ulp_clk_hw_composite("csi_regs", lpav_bus_div, 1, false, false, true, base + 0xb4, 1); 513 + clks[IMX8ULP_CLK_CSI] = imx8ulp_clk_hw_composite("csi", pcc5_periph_plat_sels, ARRAY_SIZE(pcc5_periph_plat_sels), true, true, true, base + 0xbc, 1); 514 + clks[IMX8ULP_CLK_DSI] = imx8ulp_clk_hw_composite("dsi", pcc5_periph_plat_sels, ARRAY_SIZE(pcc5_periph_plat_sels), true, true, true, base + 0xc0, 1); 515 + clks[IMX8ULP_CLK_WDOG5] = imx8ulp_clk_hw_composite("wdog5", pcc5_periph_bus_sels, ARRAY_SIZE(pcc5_periph_bus_sels), true, true, true, base + 0xc8, 1); 516 + clks[IMX8ULP_CLK_EPDC] = imx8ulp_clk_hw_composite("epdc", pcc5_periph_plat_sels, ARRAY_SIZE(pcc5_periph_plat_sels), true, true, true, base + 0xcc, 1); 517 + clks[IMX8ULP_CLK_PXP] = imx8ulp_clk_hw_composite("pxp", lpav_axi_div, 1, false, false, true, base + 0xd0, 1); 518 + clks[IMX8ULP_CLK_GPU2D] = imx8ulp_clk_hw_composite("gpu2d", pcc5_periph_plat_sels, ARRAY_SIZE(pcc5_periph_plat_sels), true, true, true, base + 0xf0, 1); 519 + clks[IMX8ULP_CLK_GPU3D] = imx8ulp_clk_hw_composite("gpu3d", pcc5_periph_plat_sels, ARRAY_SIZE(pcc5_periph_plat_sels), true, true, true, base + 0xf4, 1); 520 + clks[IMX8ULP_CLK_DC_NANO] = imx8ulp_clk_hw_composite("dc_nano", pcc5_periph_plat_sels, ARRAY_SIZE(pcc5_periph_plat_sels), true, true, true, base + 0xf8, 1); 521 + clks[IMX8ULP_CLK_CSI_CLK_UI] = imx8ulp_clk_hw_composite("csi_clk_ui", pcc5_periph_plat_sels, ARRAY_SIZE(pcc5_periph_plat_sels), true, true, true, base + 0x10c, 1); 522 + clks[IMX8ULP_CLK_CSI_CLK_ESC] = imx8ulp_clk_hw_composite("csi_clk_esc", pcc5_periph_plat_sels, ARRAY_SIZE(pcc5_periph_plat_sels), true, true, true, base + 0x110, 1); 523 + clks[IMX8ULP_CLK_RGPIOD] = imx_clk_hw_gate("rgpiod", "lpav_axi_div", base + 0x114, 30); 524 + clks[IMX8ULP_CLK_DSI_TX_ESC] = imx_clk_hw_fixed_factor("mipi_dsi_tx_esc", "dsi", 1, 4); 525 + 526 + imx_check_clk_hws(clks, clk_data->num); 527 + 528 + ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data); 529 + if (ret) 530 + return ret; 531 + 532 + /* register the pcc5 reset controller */ 533 + return imx8ulp_pcc_reset_init(pdev, base, pcc5_resets, ARRAY_SIZE(pcc5_resets)); 534 + } 535 + 536 + static int imx8ulp_clk_probe(struct platform_device *pdev) 537 + { 538 + int (*probe)(struct platform_device *pdev); 539 + 540 + probe = of_device_get_match_data(&pdev->dev); 541 + 542 + if (probe) 543 + return probe(pdev); 544 + 545 + return 0; 546 + } 547 + 548 + static const struct of_device_id imx8ulp_clk_dt_ids[] = { 549 + { .compatible = "fsl,imx8ulp-pcc3", .data = imx8ulp_clk_pcc3_init }, 550 + { .compatible = "fsl,imx8ulp-pcc4", .data = imx8ulp_clk_pcc4_init }, 551 + { .compatible = "fsl,imx8ulp-pcc5", .data = imx8ulp_clk_pcc5_init }, 552 + { .compatible = "fsl,imx8ulp-cgc2", .data = imx8ulp_clk_cgc2_init }, 553 + { .compatible = "fsl,imx8ulp-cgc1", .data = imx8ulp_clk_cgc1_init }, 554 + { /* sentinel */ }, 555 + }; 556 + MODULE_DEVICE_TABLE(of, imx8ulp_clk_dt_ids); 557 + 558 + static struct platform_driver imx8ulp_clk_driver = { 559 + .probe = imx8ulp_clk_probe, 560 + .driver = { 561 + .name = KBUILD_MODNAME, 562 + .of_match_table = imx8ulp_clk_dt_ids, 563 + }, 564 + }; 565 + module_platform_driver(imx8ulp_clk_driver); 566 + 567 + MODULE_AUTHOR("Peng Fan <peng.fan@nxp.com>"); 568 + MODULE_DESCRIPTION("NXP i.MX8ULP clock driver"); 569 + MODULE_LICENSE("GPL v2");
+18 -5
drivers/clk/imx/clk-pfdv2.c
··· 161 161 if (!rate) 162 162 return -EINVAL; 163 163 164 - /* PFD can NOT change rate without gating */ 165 - WARN_ON(clk_pfdv2_is_enabled(hw)); 164 + /* 165 + * PFD can NOT change rate without gating. 166 + * as the PFDs may enabled in HW by default but no 167 + * consumer used it, the enable count is '0', so the 168 + * 'SET_RATE_GATE' can NOT help on blocking the set_rate 169 + * ops especially for 'assigned-clock-xxx'. In order 170 + * to simplify the case, just disable the PFD if it is 171 + * enabled in HW but not in SW. 172 + */ 173 + if (clk_pfdv2_is_enabled(hw)) 174 + clk_pfdv2_disable(hw); 166 175 167 176 tmp = tmp * 18 + rate / 2; 168 177 do_div(tmp, rate); ··· 200 191 .is_enabled = clk_pfdv2_is_enabled, 201 192 }; 202 193 203 - struct clk_hw *imx_clk_hw_pfdv2(const char *name, const char *parent_name, 204 - void __iomem *reg, u8 idx) 194 + struct clk_hw *imx_clk_hw_pfdv2(enum imx_pfdv2_type type, const char *name, 195 + const char *parent_name, void __iomem *reg, u8 idx) 205 196 { 206 197 struct clk_init_data init; 207 198 struct clk_pfdv2 *pfd; ··· 223 214 init.ops = &clk_pfdv2_ops; 224 215 init.parent_names = &parent_name; 225 216 init.num_parents = 1; 226 - init.flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT; 217 + if (type == IMX_PFDV2_IMX7ULP) 218 + init.flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT; 219 + else 220 + init.flags = CLK_SET_RATE_GATE; 227 221 228 222 pfd->hw.init = &init; 229 223 ··· 239 227 240 228 return hw; 241 229 } 230 + EXPORT_SYMBOL_GPL(imx_clk_hw_pfdv2);
+26 -9
drivers/clk/imx/clk-pllv4.c
··· 23 23 24 24 /* PLL Configuration Register (xPLLCFG) */ 25 25 #define PLL_CFG_OFFSET 0x08 26 + #define IMX8ULP_PLL_CFG_OFFSET 0x10 26 27 #define BP_PLL_MULT 16 27 28 #define BM_PLL_MULT (0x7f << 16) 28 29 29 30 /* PLL Numerator Register (xPLLNUM) */ 30 31 #define PLL_NUM_OFFSET 0x10 32 + #define IMX8ULP_PLL_NUM_OFFSET 0x1c 31 33 32 34 /* PLL Denominator Register (xPLLDENOM) */ 33 35 #define PLL_DENOM_OFFSET 0x14 36 + #define IMX8ULP_PLL_DENOM_OFFSET 0x18 34 37 35 38 #define MAX_MFD 0x3fffffff 36 39 #define DEFAULT_MFD 1000000 ··· 41 38 struct clk_pllv4 { 42 39 struct clk_hw hw; 43 40 void __iomem *base; 41 + u32 cfg_offset; 42 + u32 num_offset; 43 + u32 denom_offset; 44 44 }; 45 45 46 46 /* Valid PLL MULT Table */ ··· 78 72 u32 mult, mfn, mfd; 79 73 u64 temp64; 80 74 81 - mult = readl_relaxed(pll->base + PLL_CFG_OFFSET); 75 + mult = readl_relaxed(pll->base + pll->cfg_offset); 82 76 mult &= BM_PLL_MULT; 83 77 mult >>= BP_PLL_MULT; 84 78 85 - mfn = readl_relaxed(pll->base + PLL_NUM_OFFSET); 86 - mfd = readl_relaxed(pll->base + PLL_DENOM_OFFSET); 79 + mfn = readl_relaxed(pll->base + pll->num_offset); 80 + mfd = readl_relaxed(pll->base + pll->denom_offset); 87 81 temp64 = parent_rate; 88 82 temp64 *= mfn; 89 83 do_div(temp64, mfd); ··· 171 165 do_div(temp64, parent_rate); 172 166 mfn = temp64; 173 167 174 - val = readl_relaxed(pll->base + PLL_CFG_OFFSET); 168 + val = readl_relaxed(pll->base + pll->cfg_offset); 175 169 val &= ~BM_PLL_MULT; 176 170 val |= mult << BP_PLL_MULT; 177 - writel_relaxed(val, pll->base + PLL_CFG_OFFSET); 171 + writel_relaxed(val, pll->base + pll->cfg_offset); 178 172 179 - writel_relaxed(mfn, pll->base + PLL_NUM_OFFSET); 180 - writel_relaxed(mfd, pll->base + PLL_DENOM_OFFSET); 173 + writel_relaxed(mfn, pll->base + pll->num_offset); 174 + writel_relaxed(mfd, pll->base + pll->denom_offset); 181 175 182 176 return 0; 183 177 } ··· 213 207 .is_prepared = clk_pllv4_is_prepared, 214 208 }; 215 209 216 - struct clk_hw *imx_clk_hw_pllv4(const char *name, const char *parent_name, 217 - void __iomem *base) 210 + struct clk_hw *imx_clk_hw_pllv4(enum imx_pllv4_type type, const char *name, 211 + const char *parent_name, void __iomem *base) 218 212 { 219 213 struct clk_pllv4 *pll; 220 214 struct clk_hw *hw; ··· 226 220 return ERR_PTR(-ENOMEM); 227 221 228 222 pll->base = base; 223 + 224 + if (type == IMX_PLLV4_IMX8ULP) { 225 + pll->cfg_offset = IMX8ULP_PLL_CFG_OFFSET; 226 + pll->num_offset = IMX8ULP_PLL_NUM_OFFSET; 227 + pll->denom_offset = IMX8ULP_PLL_DENOM_OFFSET; 228 + } else { 229 + pll->cfg_offset = PLL_CFG_OFFSET; 230 + pll->num_offset = PLL_NUM_OFFSET; 231 + pll->denom_offset = PLL_DENOM_OFFSET; 232 + } 229 233 230 234 init.name = name; 231 235 init.ops = &clk_pllv4_ops; ··· 254 238 255 239 return hw; 256 240 } 241 + EXPORT_SYMBOL_GPL(imx_clk_hw_pllv4);
+145 -320
drivers/clk/imx/clk.h
··· 42 42 PLL_1443X, 43 43 }; 44 44 45 + enum imx_pllv4_type { 46 + IMX_PLLV4_IMX7ULP, 47 + IMX_PLLV4_IMX8ULP, 48 + }; 49 + 50 + enum imx_pfdv2_type { 51 + IMX_PFDV2_IMX7ULP, 52 + IMX_PFDV2_IMX8ULP, 53 + }; 54 + 45 55 /* NOTE: Rate table should be kept sorted in descending order. */ 46 56 struct imx_pll14xx_rate_table { 47 57 unsigned int rate; ··· 98 88 #define imx_clk_divider(name, parent, reg, shift, width) \ 99 89 to_clk(imx_clk_hw_divider(name, parent, reg, shift, width)) 100 90 101 - #define imx_clk_divider2(name, parent, reg, shift, width) \ 102 - to_clk(imx_clk_hw_divider2(name, parent, reg, shift, width)) 103 - 104 91 #define imx_clk_divider_flags(name, parent, reg, shift, width, flags) \ 105 92 to_clk(imx_clk_hw_divider_flags(name, parent, reg, shift, width, flags)) 106 93 ··· 110 103 #define imx_clk_gate2(name, parent, reg, shift) \ 111 104 to_clk(imx_clk_hw_gate2(name, parent, reg, shift)) 112 105 106 + #define imx_clk_gate2_cgr(name, parent, reg, shift, cgr_val) \ 107 + to_clk(__imx_clk_hw_gate2(name, parent, reg, shift, cgr_val, 0, NULL)) 108 + 113 109 #define imx_clk_gate2_flags(name, parent, reg, shift, flags) \ 114 110 to_clk(imx_clk_hw_gate2_flags(name, parent, reg, shift, flags)) 115 111 116 - #define imx_clk_gate2_shared2(name, parent, reg, shift, share_count) \ 117 - to_clk(imx_clk_hw_gate2_shared2(name, parent, reg, shift, share_count)) 118 - 119 - #define imx_clk_gate3(name, parent, reg, shift) \ 120 - to_clk(imx_clk_hw_gate3(name, parent, reg, shift)) 121 - 122 - #define imx_clk_gate4(name, parent, reg, shift) \ 123 - to_clk(imx_clk_hw_gate4(name, parent, reg, shift)) 124 - 125 112 #define imx_clk_mux(name, reg, shift, width, parents, num_parents) \ 126 113 to_clk(imx_clk_hw_mux(name, reg, shift, width, parents, num_parents)) 114 + 115 + #define imx_clk_mux_flags(name, reg, shift, width, parents, num_parents, flags) \ 116 + to_clk(imx_clk_hw_mux_flags(name, reg, shift, width, parents, num_parents, flags)) 117 + 118 + #define imx_clk_mux2_flags(name, reg, shift, width, parents, num_parents, flags) \ 119 + to_clk(imx_clk_hw_mux2_flags(name, reg, shift, width, parents, num_parents, flags)) 127 120 128 121 #define imx_clk_pllv1(type, name, parent, base) \ 129 122 to_clk(imx_clk_hw_pllv1(type, name, parent, base)) ··· 131 124 #define imx_clk_pllv2(name, parent, base) \ 132 125 to_clk(imx_clk_hw_pllv2(name, parent, base)) 133 126 134 - #define imx_clk_frac_pll(name, parent_name, base) \ 135 - to_clk(imx_clk_hw_frac_pll(name, parent_name, base)) 127 + #define imx_clk_mux_flags(name, reg, shift, width, parents, num_parents, flags) \ 128 + to_clk(imx_clk_hw_mux_flags(name, reg, shift, width, parents, num_parents, flags)) 136 129 137 - #define imx_clk_sscg_pll(name, parent_names, num_parents, parent,\ 138 - bypass1, bypass2, base, flags) \ 139 - to_clk(imx_clk_hw_sscg_pll(name, parent_names, num_parents, parent,\ 140 - bypass1, bypass2, base, flags)) 130 + #define imx_clk_hw_gate(name, parent, reg, shift) \ 131 + imx_clk_hw_gate_flags(name, parent, reg, shift, 0) 141 132 142 - struct clk *imx_clk_pll14xx(const char *name, const char *parent_name, 143 - void __iomem *base, const struct imx_pll14xx_clk *pll_clk); 133 + #define imx_clk_hw_gate2(name, parent, reg, shift) \ 134 + imx_clk_hw_gate2_flags(name, parent, reg, shift, 0) 144 135 145 - #define imx_clk_pll14xx(name, parent_name, base, pll_clk) \ 146 - to_clk(imx_clk_hw_pll14xx(name, parent_name, base, pll_clk)) 136 + #define imx_clk_hw_gate_dis(name, parent, reg, shift) \ 137 + imx_clk_hw_gate_dis_flags(name, parent, reg, shift, 0) 138 + 139 + #define imx_clk_hw_gate_dis_flags(name, parent, reg, shift, flags) \ 140 + __imx_clk_hw_gate(name, parent, reg, shift, flags, CLK_GATE_SET_TO_DISABLE) 141 + 142 + #define imx_clk_hw_gate_flags(name, parent, reg, shift, flags) \ 143 + __imx_clk_hw_gate(name, parent, reg, shift, flags, 0) 144 + 145 + #define imx_clk_hw_gate2_flags(name, parent, reg, shift, flags) \ 146 + __imx_clk_hw_gate2(name, parent, reg, shift, 0x3, flags, NULL) 147 + 148 + #define imx_clk_hw_gate2_shared(name, parent, reg, shift, shared_count) \ 149 + __imx_clk_hw_gate2(name, parent, reg, shift, 0x3, 0, shared_count) 150 + 151 + #define imx_clk_hw_gate2_shared2(name, parent, reg, shift, shared_count) \ 152 + __imx_clk_hw_gate2(name, parent, reg, shift, 0x3, CLK_OPS_PARENT_ENABLE, shared_count) 153 + 154 + #define imx_clk_hw_gate3(name, parent, reg, shift) \ 155 + imx_clk_hw_gate3_flags(name, parent, reg, shift, 0) 156 + 157 + #define imx_clk_hw_gate3_flags(name, parent, reg, shift, flags) \ 158 + __imx_clk_hw_gate(name, parent, reg, shift, flags | CLK_OPS_PARENT_ENABLE, 0) 159 + 160 + #define imx_clk_hw_gate4(name, parent, reg, shift) \ 161 + imx_clk_hw_gate4_flags(name, parent, reg, shift, 0) 162 + 163 + #define imx_clk_hw_gate4_flags(name, parent, reg, shift, flags) \ 164 + imx_clk_hw_gate2_flags(name, parent, reg, shift, flags | CLK_OPS_PARENT_ENABLE) 165 + 166 + #define imx_clk_hw_mux2(name, reg, shift, width, parents, num_parents) \ 167 + imx_clk_hw_mux2_flags(name, reg, shift, width, parents, num_parents, 0) 168 + 169 + #define imx_clk_hw_mux(name, reg, shift, width, parents, num_parents) \ 170 + __imx_clk_hw_mux(name, reg, shift, width, parents, num_parents, 0, 0) 171 + 172 + #define imx_clk_hw_mux_flags(name, reg, shift, width, parents, num_parents, flags) \ 173 + __imx_clk_hw_mux(name, reg, shift, width, parents, num_parents, flags, 0) 174 + 175 + #define imx_clk_hw_mux_ldb(name, reg, shift, width, parents, num_parents) \ 176 + __imx_clk_hw_mux(name, reg, shift, width, parents, num_parents, CLK_SET_RATE_PARENT, CLK_MUX_READ_ONLY) 177 + 178 + #define imx_clk_hw_mux2_flags(name, reg, shift, width, parents, num_parents, flags) \ 179 + __imx_clk_hw_mux(name, reg, shift, width, parents, num_parents, flags | CLK_OPS_PARENT_ENABLE, 0) 180 + 181 + #define imx_clk_hw_divider(name, parent, reg, shift, width) \ 182 + __imx_clk_hw_divider(name, parent, reg, shift, width, CLK_SET_RATE_PARENT) 183 + 184 + #define imx_clk_hw_divider2(name, parent, reg, shift, width) \ 185 + __imx_clk_hw_divider(name, parent, reg, shift, width, \ 186 + CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE) 187 + 188 + #define imx_clk_hw_divider_flags(name, parent, reg, shift, width, flags) \ 189 + __imx_clk_hw_divider(name, parent, reg, shift, width, flags) 190 + 191 + #define imx_clk_hw_pll14xx(name, parent_name, base, pll_clk) \ 192 + imx_dev_clk_hw_pll14xx(NULL, name, parent_name, base, pll_clk) 147 193 148 194 struct clk_hw *imx_dev_clk_hw_pll14xx(struct device *dev, const char *name, 149 195 const char *parent_name, void __iomem *base, ··· 251 191 .kdiv = (_k), \ 252 192 } 253 193 254 - struct clk_hw *imx_clk_hw_pllv4(const char *name, const char *parent_name, 255 - void __iomem *base); 194 + struct clk_hw *imx_clk_hw_pllv4(enum imx_pllv4_type type, const char *name, 195 + const char *parent_name, void __iomem *base); 256 196 257 197 struct clk_hw *clk_hw_register_gate2(struct device *dev, const char *name, 258 198 const char *parent_name, unsigned long flags, ··· 275 215 struct clk_hw *imx_clk_hw_pfd(const char *name, const char *parent_name, 276 216 void __iomem *reg, u8 idx); 277 217 278 - struct clk_hw *imx_clk_hw_pfdv2(const char *name, const char *parent_name, 279 - void __iomem *reg, u8 idx); 218 + struct clk_hw *imx_clk_hw_pfdv2(enum imx_pfdv2_type type, const char *name, 219 + const char *parent_name, void __iomem *reg, u8 idx); 280 220 281 221 struct clk_hw *imx_clk_hw_busy_divider(const char *name, const char *parent_name, 282 222 void __iomem *reg, u8 shift, u8 width, ··· 291 231 int num_parents, bool mux_present, 292 232 bool rate_present, bool gate_present, 293 233 void __iomem *reg); 234 + 235 + struct clk_hw *imx8ulp_clk_hw_composite(const char *name, 236 + const char * const *parent_names, 237 + int num_parents, bool mux_present, 238 + bool rate_present, bool gate_present, 239 + void __iomem *reg, bool has_swrst); 294 240 295 241 struct clk_hw *imx_clk_hw_fixup_divider(const char *name, const char *parent, 296 242 void __iomem *reg, u8 shift, u8 width, ··· 313 247 return hw->clk; 314 248 } 315 249 316 - static inline struct clk_hw *imx_clk_hw_pll14xx(const char *name, const char *parent_name, 317 - void __iomem *base, 318 - const struct imx_pll14xx_clk *pll_clk) 319 - { 320 - return imx_dev_clk_hw_pll14xx(NULL, name, parent_name, base, pll_clk); 321 - } 322 - 323 250 static inline struct clk_hw *imx_clk_hw_fixed(const char *name, int rate) 324 251 { 325 252 return clk_hw_register_fixed_rate(NULL, name, NULL, 0, rate); 326 - } 327 - 328 - static inline struct clk_hw *imx_clk_hw_mux_ldb(const char *name, void __iomem *reg, 329 - u8 shift, u8 width, const char * const *parents, 330 - int num_parents) 331 - { 332 - return clk_hw_register_mux(NULL, name, parents, num_parents, 333 - CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT, reg, 334 - shift, width, CLK_MUX_READ_ONLY, &imx_ccm_lock); 335 253 } 336 254 337 255 static inline struct clk_hw *imx_clk_hw_fixed_factor(const char *name, ··· 325 275 CLK_SET_RATE_PARENT, mult, div); 326 276 } 327 277 328 - static inline struct clk_hw *imx_clk_hw_divider(const char *name, 329 - const char *parent, 330 - void __iomem *reg, u8 shift, 331 - u8 width) 332 - { 333 - return clk_hw_register_divider(NULL, name, parent, CLK_SET_RATE_PARENT, 334 - reg, shift, width, 0, &imx_ccm_lock); 335 - } 336 - 337 - static inline struct clk_hw *imx_clk_hw_divider_flags(const char *name, 278 + static inline struct clk_hw *__imx_clk_hw_divider(const char *name, 338 279 const char *parent, 339 280 void __iomem *reg, u8 shift, 340 281 u8 width, unsigned long flags) ··· 334 293 reg, shift, width, 0, &imx_ccm_lock); 335 294 } 336 295 337 - static inline struct clk_hw *imx_clk_hw_divider2(const char *name, const char *parent, 338 - void __iomem *reg, u8 shift, u8 width) 339 - { 340 - return clk_hw_register_divider(NULL, name, parent, 341 - CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, 342 - reg, shift, width, 0, &imx_ccm_lock); 343 - } 344 - 345 - static inline struct clk *imx_clk_divider2_flags(const char *name, 346 - const char *parent, void __iomem *reg, u8 shift, u8 width, 347 - unsigned long flags) 348 - { 349 - return clk_register_divider(NULL, name, parent, 350 - flags | CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, 351 - reg, shift, width, 0, &imx_ccm_lock); 352 - } 353 - 354 - static inline struct clk_hw *imx_clk_hw_gate_flags(const char *name, const char *parent, 355 - void __iomem *reg, u8 shift, unsigned long flags) 296 + static inline struct clk_hw *__imx_clk_hw_gate(const char *name, const char *parent, 297 + void __iomem *reg, u8 shift, 298 + unsigned long flags, 299 + unsigned long clk_gate_flags) 356 300 { 357 301 return clk_hw_register_gate(NULL, name, parent, flags | CLK_SET_RATE_PARENT, reg, 358 - shift, 0, &imx_ccm_lock); 302 + shift, clk_gate_flags, &imx_ccm_lock); 359 303 } 360 304 361 - static inline struct clk_hw *imx_clk_hw_gate(const char *name, const char *parent, 362 - void __iomem *reg, u8 shift) 363 - { 364 - return clk_hw_register_gate(NULL, name, parent, CLK_SET_RATE_PARENT, reg, 365 - shift, 0, &imx_ccm_lock); 366 - } 367 - 368 - static inline struct clk_hw *imx_dev_clk_hw_gate(struct device *dev, const char *name, 369 - const char *parent, void __iomem *reg, u8 shift) 370 - { 371 - return clk_hw_register_gate(dev, name, parent, CLK_SET_RATE_PARENT, reg, 372 - shift, 0, &imx_ccm_lock); 373 - } 374 - 375 - static inline struct clk_hw *imx_clk_hw_gate_dis(const char *name, const char *parent, 376 - void __iomem *reg, u8 shift) 377 - { 378 - return clk_hw_register_gate(NULL, name, parent, CLK_SET_RATE_PARENT, reg, 379 - shift, CLK_GATE_SET_TO_DISABLE, &imx_ccm_lock); 380 - } 381 - 382 - static inline struct clk_hw *imx_clk_hw_gate_dis_flags(const char *name, const char *parent, 383 - void __iomem *reg, u8 shift, unsigned long flags) 384 - { 385 - return clk_hw_register_gate(NULL, name, parent, flags | CLK_SET_RATE_PARENT, reg, 386 - shift, CLK_GATE_SET_TO_DISABLE, &imx_ccm_lock); 387 - } 388 - 389 - static inline struct clk_hw *imx_clk_hw_gate2(const char *name, const char *parent, 390 - void __iomem *reg, u8 shift) 391 - { 392 - return clk_hw_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg, 393 - shift, 0x3, 0x3, 0, &imx_ccm_lock, NULL); 394 - } 395 - 396 - static inline struct clk_hw *imx_clk_hw_gate2_flags(const char *name, const char *parent, 397 - void __iomem *reg, u8 shift, unsigned long flags) 305 + static inline struct clk_hw *__imx_clk_hw_gate2(const char *name, const char *parent, 306 + void __iomem *reg, u8 shift, u8 cgr_val, 307 + unsigned long flags, 308 + unsigned int *share_count) 398 309 { 399 310 return clk_hw_register_gate2(NULL, name, parent, flags | CLK_SET_RATE_PARENT, reg, 400 - shift, 0x3, 0x3, 0, &imx_ccm_lock, NULL); 311 + shift, cgr_val, 0x3, 0, &imx_ccm_lock, share_count); 401 312 } 402 313 403 - static inline struct clk_hw *imx_clk_hw_gate2_shared(const char *name, 404 - const char *parent, void __iomem *reg, u8 shift, 405 - unsigned int *share_count) 406 - { 407 - return clk_hw_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg, 408 - shift, 0x3, 0x3, 0, &imx_ccm_lock, share_count); 409 - } 410 - 411 - static inline struct clk_hw *imx_clk_hw_gate2_shared2(const char *name, 412 - const char *parent, void __iomem *reg, u8 shift, 413 - unsigned int *share_count) 414 - { 415 - return clk_hw_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT | 416 - CLK_OPS_PARENT_ENABLE, reg, shift, 0x3, 0x3, 0, 417 - &imx_ccm_lock, share_count); 418 - } 419 - 420 - static inline struct clk_hw *imx_dev_clk_hw_gate_shared(struct device *dev, 421 - const char *name, const char *parent, 422 - void __iomem *reg, u8 shift, 423 - unsigned int *share_count) 424 - { 425 - return clk_hw_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT | 426 - CLK_OPS_PARENT_ENABLE, reg, shift, 0x1, 427 - 0x1, 0, &imx_ccm_lock, share_count); 428 - } 429 - 430 - static inline struct clk *imx_clk_gate2_cgr(const char *name, 431 - const char *parent, void __iomem *reg, u8 shift, u8 cgr_val) 432 - { 433 - return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg, 434 - shift, cgr_val, 0x3, 0, &imx_ccm_lock, NULL); 435 - } 436 - 437 - static inline struct clk_hw *imx_clk_hw_gate3(const char *name, const char *parent, 438 - void __iomem *reg, u8 shift) 439 - { 440 - return clk_hw_register_gate(NULL, name, parent, 441 - CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, 442 - reg, shift, 0, &imx_ccm_lock); 443 - } 444 - 445 - static inline struct clk_hw *imx_clk_hw_gate3_flags(const char *name, 446 - const char *parent, void __iomem *reg, u8 shift, 447 - unsigned long flags) 448 - { 449 - return clk_hw_register_gate(NULL, name, parent, 450 - flags | CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, 451 - reg, shift, 0, &imx_ccm_lock); 452 - } 453 - 454 - #define imx_clk_gate3_flags(name, parent, reg, shift, flags) \ 455 - to_clk(imx_clk_hw_gate3_flags(name, parent, reg, shift, flags)) 456 - 457 - static inline struct clk_hw *imx_clk_hw_gate4(const char *name, const char *parent, 458 - void __iomem *reg, u8 shift) 459 - { 460 - return clk_hw_register_gate2(NULL, name, parent, 461 - CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, 462 - reg, shift, 0x3, 0x3, 0, &imx_ccm_lock, NULL); 463 - } 464 - 465 - static inline struct clk_hw *imx_clk_hw_gate4_flags(const char *name, 466 - const char *parent, void __iomem *reg, u8 shift, 467 - unsigned long flags) 468 - { 469 - return clk_hw_register_gate2(NULL, name, parent, 470 - flags | CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, 471 - reg, shift, 0x3, 0x3, 0, &imx_ccm_lock, NULL); 472 - } 473 - 474 - #define imx_clk_gate4_flags(name, parent, reg, shift, flags) \ 475 - to_clk(imx_clk_hw_gate4_flags(name, parent, reg, shift, flags)) 476 - 477 - static inline struct clk_hw *imx_clk_hw_mux(const char *name, void __iomem *reg, 314 + static inline struct clk_hw *__imx_clk_hw_mux(const char *name, void __iomem *reg, 478 315 u8 shift, u8 width, const char * const *parents, 479 - int num_parents) 316 + int num_parents, unsigned long flags, unsigned long clk_mux_flags) 480 317 { 481 318 return clk_hw_register_mux(NULL, name, parents, num_parents, 482 - CLK_SET_RATE_NO_REPARENT, reg, shift, 483 - width, 0, &imx_ccm_lock); 484 - } 485 - 486 - static inline struct clk_hw *imx_dev_clk_hw_mux(struct device *dev, 487 - const char *name, void __iomem *reg, u8 shift, 488 - u8 width, const char * const *parents, int num_parents) 489 - { 490 - return clk_hw_register_mux(dev, name, parents, num_parents, 491 - CLK_SET_RATE_NO_REPARENT | CLK_SET_PARENT_GATE, 492 - reg, shift, width, 0, &imx_ccm_lock); 493 - } 494 - 495 - static inline struct clk *imx_clk_mux2(const char *name, void __iomem *reg, 496 - u8 shift, u8 width, const char * const *parents, 497 - int num_parents) 498 - { 499 - return clk_register_mux(NULL, name, parents, num_parents, 500 - CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE, 501 - reg, shift, width, 0, &imx_ccm_lock); 502 - } 503 - 504 - static inline struct clk_hw *imx_clk_hw_mux2(const char *name, void __iomem *reg, 505 - u8 shift, u8 width, 506 - const char * const *parents, 507 - int num_parents) 508 - { 509 - return clk_hw_register_mux(NULL, name, parents, num_parents, 510 - CLK_SET_RATE_NO_REPARENT | 511 - CLK_OPS_PARENT_ENABLE, 512 - reg, shift, width, 0, &imx_ccm_lock); 513 - } 514 - 515 - static inline struct clk *imx_clk_mux_flags(const char *name, 516 - void __iomem *reg, u8 shift, u8 width, 517 - const char * const *parents, int num_parents, 518 - unsigned long flags) 519 - { 520 - return clk_register_mux(NULL, name, parents, num_parents, 521 - flags | CLK_SET_RATE_NO_REPARENT, reg, shift, width, 0, 522 - &imx_ccm_lock); 523 - } 524 - 525 - static inline struct clk_hw *imx_clk_hw_mux2_flags(const char *name, 526 - void __iomem *reg, u8 shift, u8 width, 527 - const char * const *parents, 528 - int num_parents, unsigned long flags) 529 - { 530 - return clk_hw_register_mux(NULL, name, parents, num_parents, 531 - flags | CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE, 532 - reg, shift, width, 0, &imx_ccm_lock); 533 - } 534 - 535 - static inline struct clk *imx_clk_mux2_flags(const char *name, 536 - void __iomem *reg, u8 shift, u8 width, 537 - const char * const *parents, 538 - int num_parents, unsigned long flags) 539 - { 540 - return clk_register_mux(NULL, name, parents, num_parents, 541 - flags | CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE, 542 - reg, shift, width, 0, &imx_ccm_lock); 543 - } 544 - 545 - static inline struct clk_hw *imx_clk_hw_mux_flags(const char *name, 546 - void __iomem *reg, u8 shift, 547 - u8 width, 548 - const char * const *parents, 549 - int num_parents, 550 - unsigned long flags) 551 - { 552 - return clk_hw_register_mux(NULL, name, parents, num_parents, 553 - flags | CLK_SET_RATE_NO_REPARENT, 554 - reg, shift, width, 0, &imx_ccm_lock); 555 - } 556 - 557 - static inline struct clk_hw *imx_dev_clk_hw_mux_flags(struct device *dev, 558 - const char *name, 559 - void __iomem *reg, u8 shift, 560 - u8 width, 561 - const char * const *parents, 562 - int num_parents, 563 - unsigned long flags) 564 - { 565 - return clk_hw_register_mux(dev, name, parents, num_parents, 566 - flags | CLK_SET_RATE_NO_REPARENT, 567 - reg, shift, width, 0, &imx_ccm_lock); 319 + flags | CLK_SET_RATE_NO_REPARENT, reg, shift, 320 + width, clk_mux_flags, &imx_ccm_lock); 568 321 } 569 322 570 323 struct clk_hw *imx_clk_hw_cpu(const char *name, const char *parent_name, ··· 369 534 #define IMX_COMPOSITE_BUS BIT(1) 370 535 #define IMX_COMPOSITE_FW_MANAGED BIT(2) 371 536 372 - struct clk_hw *imx8m_clk_hw_composite_flags(const char *name, 537 + #define IMX_COMPOSITE_CLK_FLAGS_DEFAULT \ 538 + (CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE) 539 + #define IMX_COMPOSITE_CLK_FLAGS_CRITICAL \ 540 + (IMX_COMPOSITE_CLK_FLAGS_DEFAULT | CLK_IS_CRITICAL) 541 + #define IMX_COMPOSITE_CLK_FLAGS_GET_RATE_NO_CACHE \ 542 + (IMX_COMPOSITE_CLK_FLAGS_DEFAULT | CLK_GET_RATE_NOCACHE) 543 + #define IMX_COMPOSITE_CLK_FLAGS_CRITICAL_GET_RATE_NO_CACHE \ 544 + (IMX_COMPOSITE_CLK_FLAGS_GET_RATE_NO_CACHE | CLK_IS_CRITICAL) 545 + 546 + struct clk_hw *__imx8m_clk_hw_composite(const char *name, 373 547 const char * const *parent_names, 374 548 int num_parents, 375 549 void __iomem *reg, 376 550 u32 composite_flags, 377 551 unsigned long flags); 378 552 379 - #define imx8m_clk_hw_composite_bus(name, parent_names, reg) \ 380 - imx8m_clk_hw_composite_flags(name, parent_names, \ 381 - ARRAY_SIZE(parent_names), reg, \ 382 - IMX_COMPOSITE_BUS, \ 383 - CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE) 384 - 385 - #define imx8m_clk_hw_composite_bus_critical(name, parent_names, reg) \ 386 - imx8m_clk_hw_composite_flags(name, parent_names, ARRAY_SIZE(parent_names), reg, \ 387 - IMX_COMPOSITE_BUS, \ 388 - CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE | CLK_IS_CRITICAL) 389 - 390 - #define imx8m_clk_hw_composite_core(name, parent_names, reg) \ 391 - imx8m_clk_hw_composite_flags(name, parent_names, \ 392 - ARRAY_SIZE(parent_names), reg, \ 393 - IMX_COMPOSITE_CORE, \ 394 - CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE) 395 - 396 - #define imx8m_clk_composite_flags(name, parent_names, num_parents, reg, \ 397 - flags) \ 398 - to_clk(imx8m_clk_hw_composite_flags(name, parent_names, \ 399 - num_parents, reg, 0, flags)) 400 - 401 - #define __imx8m_clk_hw_composite(name, parent_names, reg, flags) \ 402 - imx8m_clk_hw_composite_flags(name, parent_names, \ 403 - ARRAY_SIZE(parent_names), reg, 0, \ 404 - flags | CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE) 405 - 406 - #define __imx8m_clk_hw_fw_managed_composite(name, parent_names, reg, flags) \ 407 - imx8m_clk_hw_composite_flags(name, parent_names, \ 408 - ARRAY_SIZE(parent_names), reg, IMX_COMPOSITE_FW_MANAGED, \ 409 - flags | CLK_GET_RATE_NOCACHE | CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE) 410 - 411 - #define imx8m_clk_hw_fw_managed_composite(name, parent_names, reg) \ 412 - __imx8m_clk_hw_fw_managed_composite(name, parent_names, reg, 0) 413 - 414 - #define imx8m_clk_hw_fw_managed_composite_critical(name, parent_names, reg) \ 415 - __imx8m_clk_hw_fw_managed_composite(name, parent_names, reg, CLK_IS_CRITICAL) 416 - 417 - #define __imx8m_clk_composite(name, parent_names, reg, flags) \ 418 - to_clk(__imx8m_clk_hw_composite(name, parent_names, reg, flags)) 553 + #define _imx8m_clk_hw_composite(name, parent_names, reg, composite_flags, flags) \ 554 + __imx8m_clk_hw_composite(name, parent_names, \ 555 + ARRAY_SIZE(parent_names), reg, composite_flags, flags) 419 556 420 557 #define imx8m_clk_hw_composite(name, parent_names, reg) \ 421 - __imx8m_clk_hw_composite(name, parent_names, reg, 0) 422 - 423 - #define imx8m_clk_composite(name, parent_names, reg) \ 424 - __imx8m_clk_composite(name, parent_names, reg, 0) 558 + _imx8m_clk_hw_composite(name, parent_names, reg, \ 559 + IMX_COMPOSITE_CORE, IMX_COMPOSITE_CLK_FLAGS_DEFAULT) 425 560 426 561 #define imx8m_clk_hw_composite_critical(name, parent_names, reg) \ 427 - __imx8m_clk_hw_composite(name, parent_names, reg, CLK_IS_CRITICAL) 562 + _imx8m_clk_hw_composite(name, parent_names, reg, \ 563 + IMX_COMPOSITE_CORE, IMX_COMPOSITE_CLK_FLAGS_CRITICAL) 428 564 429 - #define imx8m_clk_composite_critical(name, parent_names, reg) \ 430 - __imx8m_clk_composite(name, parent_names, reg, CLK_IS_CRITICAL) 565 + #define imx8m_clk_hw_composite_bus(name, parent_names, reg) \ 566 + _imx8m_clk_hw_composite(name, parent_names, reg, \ 567 + IMX_COMPOSITE_BUS, IMX_COMPOSITE_CLK_FLAGS_DEFAULT) 568 + 569 + #define imx8m_clk_hw_composite_bus_critical(name, parent_names, reg) \ 570 + _imx8m_clk_hw_composite(name, parent_names, reg, \ 571 + IMX_COMPOSITE_BUS, IMX_COMPOSITE_CLK_FLAGS_CRITICAL) 572 + 573 + #define imx8m_clk_hw_composite_core(name, parent_names, reg) \ 574 + _imx8m_clk_hw_composite(name, parent_names, reg, \ 575 + IMX_COMPOSITE_CORE, IMX_COMPOSITE_CLK_FLAGS_DEFAULT) 576 + 577 + #define imx8m_clk_hw_fw_managed_composite(name, parent_names, reg) \ 578 + _imx8m_clk_hw_composite(name, parent_names, reg, \ 579 + IMX_COMPOSITE_FW_MANAGED, \ 580 + IMX_COMPOSITE_CLK_FLAGS_GET_RATE_NO_CACHE) 581 + 582 + #define imx8m_clk_hw_fw_managed_composite_critical(name, parent_names, reg) \ 583 + _imx8m_clk_hw_composite(name, parent_names, reg, \ 584 + IMX_COMPOSITE_FW_MANAGED, \ 585 + IMX_COMPOSITE_CLK_FLAGS_CRITICAL_GET_RATE_NO_CACHE) 431 586 432 587 struct clk_hw *imx_clk_hw_divider_gate(const char *name, const char *parent_name, 433 588 unsigned long flags, void __iomem *reg, u8 shift, u8 width,
+3
drivers/clk/ux500/Makefile
··· 8 8 obj-y += clk-prcmu.o 9 9 obj-y += clk-sysctrl.o 10 10 11 + # Reset control 12 + obj-y += reset-prcc.o 13 + 11 14 # Clock definitions 12 15 obj-y += u8500_of_clk.o 13 16
+19
drivers/clk/ux500/prcc.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + 3 + #ifndef __PRCC_H 4 + #define __PRCC_H 5 + 6 + #define PRCC_NUM_PERIPH_CLUSTERS 6 7 + #define PRCC_PERIPHS_PER_CLUSTER 32 8 + 9 + /* CLKRST4 is missing making it hard to index things */ 10 + enum clkrst_index { 11 + CLKRST1_INDEX = 0, 12 + CLKRST2_INDEX, 13 + CLKRST3_INDEX, 14 + CLKRST5_INDEX, 15 + CLKRST6_INDEX, 16 + CLKRST_MAX, 17 + }; 18 + 19 + #endif
+181
drivers/clk/ux500/reset-prcc.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Reset controller portions for the U8500 PRCC 4 + * Copyright (C) 2021 Linus Walleij <linus.walleij@linaro.org> 5 + */ 6 + #include <linux/of.h> 7 + #include <linux/of_address.h> 8 + #include <linux/slab.h> 9 + #include <linux/io.h> 10 + #include <linux/err.h> 11 + #include <linux/types.h> 12 + #include <linux/reset-controller.h> 13 + #include <linux/bits.h> 14 + #include <linux/delay.h> 15 + 16 + #include "prcc.h" 17 + #include "reset-prcc.h" 18 + 19 + #define to_u8500_prcc_reset(p) container_of((p), struct u8500_prcc_reset, rcdev) 20 + 21 + /* This macro flattens the 2-dimensional PRCC numberspace */ 22 + #define PRCC_RESET_LINE(prcc_num, bit) \ 23 + (((prcc_num) * PRCC_PERIPHS_PER_CLUSTER) + (bit)) 24 + 25 + /* 26 + * Reset registers in each PRCC - the reset lines are active low 27 + * so what you need to do is write a bit for the peripheral you 28 + * want to put into reset into the CLEAR register, this will assert 29 + * the reset by pulling the line low. SET take the device out of 30 + * reset. The status reflects the actual state of the line. 31 + */ 32 + #define PRCC_K_SOFTRST_SET 0x018 33 + #define PRCC_K_SOFTRST_CLEAR 0x01c 34 + #define PRCC_K_RST_STATUS 0x020 35 + 36 + static int prcc_num_to_index(unsigned int num) 37 + { 38 + switch (num) { 39 + case 1: 40 + return CLKRST1_INDEX; 41 + case 2: 42 + return CLKRST2_INDEX; 43 + case 3: 44 + return CLKRST3_INDEX; 45 + case 5: 46 + return CLKRST5_INDEX; 47 + case 6: 48 + return CLKRST6_INDEX; 49 + } 50 + return -EINVAL; 51 + } 52 + 53 + static void __iomem *u8500_prcc_reset_base(struct u8500_prcc_reset *ur, 54 + unsigned long id) 55 + { 56 + unsigned int prcc_num, index; 57 + 58 + prcc_num = id / PRCC_PERIPHS_PER_CLUSTER; 59 + index = prcc_num_to_index(prcc_num); 60 + 61 + if (index > ARRAY_SIZE(ur->base)) 62 + return NULL; 63 + 64 + return ur->base[index]; 65 + } 66 + 67 + static int u8500_prcc_reset(struct reset_controller_dev *rcdev, 68 + unsigned long id) 69 + { 70 + struct u8500_prcc_reset *ur = to_u8500_prcc_reset(rcdev); 71 + void __iomem *base = u8500_prcc_reset_base(ur, id); 72 + unsigned int bit = id % PRCC_PERIPHS_PER_CLUSTER; 73 + 74 + pr_debug("PRCC cycle reset id %lu, bit %u\n", id, bit); 75 + 76 + /* 77 + * Assert reset and then release it. The one microsecond 78 + * delay is found in the vendor reference code. 79 + */ 80 + writel(BIT(bit), base + PRCC_K_SOFTRST_CLEAR); 81 + udelay(1); 82 + writel(BIT(bit), base + PRCC_K_SOFTRST_SET); 83 + udelay(1); 84 + 85 + return 0; 86 + } 87 + 88 + static int u8500_prcc_reset_assert(struct reset_controller_dev *rcdev, 89 + unsigned long id) 90 + { 91 + struct u8500_prcc_reset *ur = to_u8500_prcc_reset(rcdev); 92 + void __iomem *base = u8500_prcc_reset_base(ur, id); 93 + unsigned int bit = id % PRCC_PERIPHS_PER_CLUSTER; 94 + 95 + pr_debug("PRCC assert reset id %lu, bit %u\n", id, bit); 96 + writel(BIT(bit), base + PRCC_K_SOFTRST_CLEAR); 97 + 98 + return 0; 99 + } 100 + 101 + static int u8500_prcc_reset_deassert(struct reset_controller_dev *rcdev, 102 + unsigned long id) 103 + { 104 + struct u8500_prcc_reset *ur = to_u8500_prcc_reset(rcdev); 105 + void __iomem *base = u8500_prcc_reset_base(ur, id); 106 + unsigned int bit = id % PRCC_PERIPHS_PER_CLUSTER; 107 + 108 + pr_debug("PRCC deassert reset id %lu, bit %u\n", id, bit); 109 + writel(BIT(bit), base + PRCC_K_SOFTRST_SET); 110 + 111 + return 0; 112 + } 113 + 114 + static int u8500_prcc_reset_status(struct reset_controller_dev *rcdev, 115 + unsigned long id) 116 + { 117 + struct u8500_prcc_reset *ur = to_u8500_prcc_reset(rcdev); 118 + void __iomem *base = u8500_prcc_reset_base(ur, id); 119 + unsigned int bit = id % PRCC_PERIPHS_PER_CLUSTER; 120 + u32 val; 121 + 122 + pr_debug("PRCC check status on reset line id %lu, bit %u\n", id, bit); 123 + val = readl(base + PRCC_K_RST_STATUS); 124 + 125 + /* Active low so return the inverse value of the bit */ 126 + return !(val & BIT(bit)); 127 + } 128 + 129 + static const struct reset_control_ops u8500_prcc_reset_ops = { 130 + .reset = u8500_prcc_reset, 131 + .assert = u8500_prcc_reset_assert, 132 + .deassert = u8500_prcc_reset_deassert, 133 + .status = u8500_prcc_reset_status, 134 + }; 135 + 136 + static int u8500_prcc_reset_xlate(struct reset_controller_dev *rcdev, 137 + const struct of_phandle_args *reset_spec) 138 + { 139 + unsigned int prcc_num, bit; 140 + 141 + if (reset_spec->args_count != 2) 142 + return -EINVAL; 143 + 144 + prcc_num = reset_spec->args[0]; 145 + bit = reset_spec->args[1]; 146 + 147 + if (prcc_num != 1 && prcc_num != 2 && prcc_num != 3 && 148 + prcc_num != 5 && prcc_num != 6) { 149 + pr_err("%s: invalid PRCC %d\n", __func__, prcc_num); 150 + return -EINVAL; 151 + } 152 + 153 + pr_debug("located reset line %d at PRCC %d bit %d\n", 154 + PRCC_RESET_LINE(prcc_num, bit), prcc_num, bit); 155 + 156 + return PRCC_RESET_LINE(prcc_num, bit); 157 + } 158 + 159 + void u8500_prcc_reset_init(struct device_node *np, struct u8500_prcc_reset *ur) 160 + { 161 + struct reset_controller_dev *rcdev = &ur->rcdev; 162 + int ret; 163 + int i; 164 + 165 + for (i = 0; i < CLKRST_MAX; i++) { 166 + ur->base[i] = ioremap(ur->phy_base[i], SZ_4K); 167 + if (!ur->base[i]) 168 + pr_err("PRCC failed to remap for reset base %d (%08x)\n", 169 + i, ur->phy_base[i]); 170 + } 171 + 172 + rcdev->owner = THIS_MODULE; 173 + rcdev->ops = &u8500_prcc_reset_ops; 174 + rcdev->of_node = np; 175 + rcdev->of_reset_n_cells = 2; 176 + rcdev->of_xlate = u8500_prcc_reset_xlate; 177 + 178 + ret = reset_controller_register(rcdev); 179 + if (ret) 180 + pr_err("PRCC failed to register reset controller\n"); 181 + }
+23
drivers/clk/ux500/reset-prcc.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + 3 + #ifndef __RESET_PRCC_H 4 + #define __RESET_PRCC_H 5 + 6 + #include <linux/reset-controller.h> 7 + #include <linux/io.h> 8 + 9 + /** 10 + * struct u8500_prcc_reset - U8500 PRCC reset controller state 11 + * @rcdev: reset controller device 12 + * @phy_base: the physical base address for each PRCC block 13 + * @base: the remapped PRCC bases 14 + */ 15 + struct u8500_prcc_reset { 16 + struct reset_controller_dev rcdev; 17 + u32 phy_base[CLKRST_MAX]; 18 + void __iomem *base[CLKRST_MAX]; 19 + }; 20 + 21 + void u8500_prcc_reset_init(struct device_node *np, struct u8500_prcc_reset *ur); 22 + 23 + #endif
+17 -13
drivers/clk/ux500/u8500_of_clk.c
··· 10 10 #include <linux/of_address.h> 11 11 #include <linux/clk-provider.h> 12 12 #include <linux/mfd/dbx500-prcmu.h> 13 - #include "clk.h" 14 13 15 - #define PRCC_NUM_PERIPH_CLUSTERS 6 16 - #define PRCC_PERIPHS_PER_CLUSTER 32 14 + #include "clk.h" 15 + #include "prcc.h" 16 + #include "reset-prcc.h" 17 17 18 18 static struct clk *prcmu_clk[PRCMU_NUM_CLKS]; 19 19 static struct clk *prcc_pclk[(PRCC_NUM_PERIPH_CLUSTERS + 1) * PRCC_PERIPHS_PER_CLUSTER]; ··· 46 46 return PRCC_SHOW(clk_data, base, bit); 47 47 } 48 48 49 - /* CLKRST4 is missing making it hard to index things */ 50 - enum clkrst_index { 51 - CLKRST1_INDEX = 0, 52 - CLKRST2_INDEX, 53 - CLKRST3_INDEX, 54 - CLKRST5_INDEX, 55 - CLKRST6_INDEX, 56 - CLKRST_MAX, 57 - }; 58 - 59 49 static void u8500_clk_init(struct device_node *np) 60 50 { 61 51 struct prcmu_fw_version *fw_version; ··· 53 63 const char *sgaclk_parent = NULL; 54 64 struct clk *clk, *rtc_clk, *twd_clk; 55 65 u32 bases[CLKRST_MAX]; 66 + struct u8500_prcc_reset *rstc; 56 67 int i; 68 + 69 + /* 70 + * We allocate the reset controller here so that we can fill in the 71 + * base addresses properly and pass to the reset controller init 72 + * function later on. 73 + */ 74 + rstc = kzalloc(sizeof(*rstc), GFP_KERNEL); 75 + if (!rstc) 76 + return; 57 77 58 78 for (i = 0; i < ARRAY_SIZE(bases); i++) { 59 79 struct resource r; ··· 73 73 pr_err("failed to get CLKRST %d base address\n", 74 74 i + 1); 75 75 bases[i] = r.start; 76 + rstc->phy_base[i] = r.start; 76 77 } 77 78 78 79 /* Clock sources */ ··· 564 563 565 564 if (of_node_name_eq(child, "smp-twd-clock")) 566 565 of_clk_add_provider(child, of_clk_src_simple_get, twd_clk); 566 + 567 + if (of_node_name_eq(child, "prcc-reset-controller")) 568 + u8500_prcc_reset_init(child, rstc); 567 569 } 568 570 } 569 571 CLK_OF_DECLARE(u8500_clks, "stericsson,u8500-clks", u8500_clk_init);
+258
include/dt-bindings/clock/imx8ulp-clock.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0+ OR MIT */ 2 + /* 3 + * Copyright 2021 NXP 4 + */ 5 + 6 + #ifndef __DT_BINDINGS_CLOCK_IMX8ULP_H 7 + #define __DT_BINDINGS_CLOCK_IMX8ULP_H 8 + 9 + #define IMX8ULP_CLK_DUMMY 0 10 + 11 + /* CGC1 */ 12 + #define IMX8ULP_CLK_SPLL2 5 13 + #define IMX8ULP_CLK_SPLL3 6 14 + #define IMX8ULP_CLK_A35_SEL 7 15 + #define IMX8ULP_CLK_A35_DIV 8 16 + #define IMX8ULP_CLK_SPLL2_PRE_SEL 9 17 + #define IMX8ULP_CLK_SPLL3_PRE_SEL 10 18 + #define IMX8ULP_CLK_SPLL3_PFD0 11 19 + #define IMX8ULP_CLK_SPLL3_PFD1 12 20 + #define IMX8ULP_CLK_SPLL3_PFD2 13 21 + #define IMX8ULP_CLK_SPLL3_PFD3 14 22 + #define IMX8ULP_CLK_SPLL3_PFD0_DIV1 15 23 + #define IMX8ULP_CLK_SPLL3_PFD0_DIV2 16 24 + #define IMX8ULP_CLK_SPLL3_PFD1_DIV1 17 25 + #define IMX8ULP_CLK_SPLL3_PFD1_DIV2 18 26 + #define IMX8ULP_CLK_SPLL3_PFD2_DIV1 19 27 + #define IMX8ULP_CLK_SPLL3_PFD2_DIV2 20 28 + #define IMX8ULP_CLK_SPLL3_PFD3_DIV1 21 29 + #define IMX8ULP_CLK_SPLL3_PFD3_DIV2 22 30 + #define IMX8ULP_CLK_NIC_SEL 23 31 + #define IMX8ULP_CLK_NIC_AD_DIVPLAT 24 32 + #define IMX8ULP_CLK_NIC_PER_DIVPLAT 25 33 + #define IMX8ULP_CLK_XBAR_SEL 26 34 + #define IMX8ULP_CLK_XBAR_AD_DIVPLAT 27 35 + #define IMX8ULP_CLK_XBAR_DIVBUS 28 36 + #define IMX8ULP_CLK_XBAR_AD_SLOW 29 37 + #define IMX8ULP_CLK_SOSC_DIV1 30 38 + #define IMX8ULP_CLK_SOSC_DIV2 31 39 + #define IMX8ULP_CLK_SOSC_DIV3 32 40 + #define IMX8ULP_CLK_FROSC_DIV1 33 41 + #define IMX8ULP_CLK_FROSC_DIV2 34 42 + #define IMX8ULP_CLK_FROSC_DIV3 35 43 + #define IMX8ULP_CLK_SPLL3_VCODIV 36 44 + #define IMX8ULP_CLK_SPLL3_PFD0_DIV1_GATE 37 45 + #define IMX8ULP_CLK_SPLL3_PFD0_DIV2_GATE 38 46 + #define IMX8ULP_CLK_SPLL3_PFD1_DIV1_GATE 39 47 + #define IMX8ULP_CLK_SPLL3_PFD1_DIV2_GATE 40 48 + #define IMX8ULP_CLK_SPLL3_PFD2_DIV1_GATE 41 49 + #define IMX8ULP_CLK_SPLL3_PFD2_DIV2_GATE 42 50 + #define IMX8ULP_CLK_SPLL3_PFD3_DIV1_GATE 43 51 + #define IMX8ULP_CLK_SPLL3_PFD3_DIV2_GATE 44 52 + #define IMX8ULP_CLK_SOSC_DIV1_GATE 45 53 + #define IMX8ULP_CLK_SOSC_DIV2_GATE 46 54 + #define IMX8ULP_CLK_SOSC_DIV3_GATE 47 55 + #define IMX8ULP_CLK_FROSC_DIV1_GATE 48 56 + #define IMX8ULP_CLK_FROSC_DIV2_GATE 49 57 + #define IMX8ULP_CLK_FROSC_DIV3_GATE 50 58 + #define IMX8ULP_CLK_SAI4_SEL 51 59 + #define IMX8ULP_CLK_SAI5_SEL 52 60 + #define IMX8ULP_CLK_AUD_CLK1 53 61 + #define IMX8ULP_CLK_ARM 54 62 + #define IMX8ULP_CLK_ENET_TS_SEL 55 63 + 64 + #define IMX8ULP_CLK_CGC1_END 56 65 + 66 + /* CGC2 */ 67 + #define IMX8ULP_CLK_PLL4_PRE_SEL 0 68 + #define IMX8ULP_CLK_PLL4 1 69 + #define IMX8ULP_CLK_PLL4_VCODIV 2 70 + #define IMX8ULP_CLK_DDR_SEL 3 71 + #define IMX8ULP_CLK_DDR_DIV 4 72 + #define IMX8ULP_CLK_LPAV_AXI_SEL 5 73 + #define IMX8ULP_CLK_LPAV_AXI_DIV 6 74 + #define IMX8ULP_CLK_LPAV_AHB_DIV 7 75 + #define IMX8ULP_CLK_LPAV_BUS_DIV 8 76 + #define IMX8ULP_CLK_PLL4_PFD0 9 77 + #define IMX8ULP_CLK_PLL4_PFD1 10 78 + #define IMX8ULP_CLK_PLL4_PFD2 11 79 + #define IMX8ULP_CLK_PLL4_PFD3 12 80 + #define IMX8ULP_CLK_PLL4_PFD0_DIV1_GATE 13 81 + #define IMX8ULP_CLK_PLL4_PFD0_DIV2_GATE 14 82 + #define IMX8ULP_CLK_PLL4_PFD1_DIV1_GATE 15 83 + #define IMX8ULP_CLK_PLL4_PFD1_DIV2_GATE 16 84 + #define IMX8ULP_CLK_PLL4_PFD2_DIV1_GATE 17 85 + #define IMX8ULP_CLK_PLL4_PFD2_DIV2_GATE 18 86 + #define IMX8ULP_CLK_PLL4_PFD3_DIV1_GATE 19 87 + #define IMX8ULP_CLK_PLL4_PFD3_DIV2_GATE 20 88 + #define IMX8ULP_CLK_PLL4_PFD0_DIV1 21 89 + #define IMX8ULP_CLK_PLL4_PFD0_DIV2 22 90 + #define IMX8ULP_CLK_PLL4_PFD1_DIV1 23 91 + #define IMX8ULP_CLK_PLL4_PFD1_DIV2 24 92 + #define IMX8ULP_CLK_PLL4_PFD2_DIV1 25 93 + #define IMX8ULP_CLK_PLL4_PFD2_DIV2 26 94 + #define IMX8ULP_CLK_PLL4_PFD3_DIV1 27 95 + #define IMX8ULP_CLK_PLL4_PFD3_DIV2 28 96 + #define IMX8ULP_CLK_CGC2_SOSC_DIV1_GATE 29 97 + #define IMX8ULP_CLK_CGC2_SOSC_DIV2_GATE 30 98 + #define IMX8ULP_CLK_CGC2_SOSC_DIV3_GATE 31 99 + #define IMX8ULP_CLK_CGC2_SOSC_DIV1 32 100 + #define IMX8ULP_CLK_CGC2_SOSC_DIV2 33 101 + #define IMX8ULP_CLK_CGC2_SOSC_DIV3 34 102 + #define IMX8ULP_CLK_CGC2_FROSC_DIV1_GATE 35 103 + #define IMX8ULP_CLK_CGC2_FROSC_DIV2_GATE 36 104 + #define IMX8ULP_CLK_CGC2_FROSC_DIV3_GATE 37 105 + #define IMX8ULP_CLK_CGC2_FROSC_DIV1 38 106 + #define IMX8ULP_CLK_CGC2_FROSC_DIV2 39 107 + #define IMX8ULP_CLK_CGC2_FROSC_DIV3 40 108 + #define IMX8ULP_CLK_AUD_CLK2 41 109 + #define IMX8ULP_CLK_SAI6_SEL 42 110 + #define IMX8ULP_CLK_SAI7_SEL 43 111 + #define IMX8ULP_CLK_SPDIF_SEL 44 112 + #define IMX8ULP_CLK_HIFI_SEL 45 113 + #define IMX8ULP_CLK_HIFI_DIVCORE 46 114 + #define IMX8ULP_CLK_HIFI_DIVPLAT 47 115 + #define IMX8ULP_CLK_DSI_PHY_REF 48 116 + 117 + #define IMX8ULP_CLK_CGC2_END 49 118 + 119 + /* PCC3 */ 120 + #define IMX8ULP_CLK_WDOG3 0 121 + #define IMX8ULP_CLK_WDOG4 1 122 + #define IMX8ULP_CLK_LPIT1 2 123 + #define IMX8ULP_CLK_TPM4 3 124 + #define IMX8ULP_CLK_TPM5 4 125 + #define IMX8ULP_CLK_FLEXIO1 5 126 + #define IMX8ULP_CLK_I3C2 6 127 + #define IMX8ULP_CLK_LPI2C4 7 128 + #define IMX8ULP_CLK_LPI2C5 8 129 + #define IMX8ULP_CLK_LPUART4 9 130 + #define IMX8ULP_CLK_LPUART5 10 131 + #define IMX8ULP_CLK_LPSPI4 11 132 + #define IMX8ULP_CLK_LPSPI5 12 133 + #define IMX8ULP_CLK_DMA1_MP 13 134 + #define IMX8ULP_CLK_DMA1_CH0 14 135 + #define IMX8ULP_CLK_DMA1_CH1 15 136 + #define IMX8ULP_CLK_DMA1_CH2 16 137 + #define IMX8ULP_CLK_DMA1_CH3 17 138 + #define IMX8ULP_CLK_DMA1_CH4 18 139 + #define IMX8ULP_CLK_DMA1_CH5 19 140 + #define IMX8ULP_CLK_DMA1_CH6 20 141 + #define IMX8ULP_CLK_DMA1_CH7 21 142 + #define IMX8ULP_CLK_DMA1_CH8 22 143 + #define IMX8ULP_CLK_DMA1_CH9 23 144 + #define IMX8ULP_CLK_DMA1_CH10 24 145 + #define IMX8ULP_CLK_DMA1_CH11 25 146 + #define IMX8ULP_CLK_DMA1_CH12 26 147 + #define IMX8ULP_CLK_DMA1_CH13 27 148 + #define IMX8ULP_CLK_DMA1_CH14 28 149 + #define IMX8ULP_CLK_DMA1_CH15 29 150 + #define IMX8ULP_CLK_DMA1_CH16 30 151 + #define IMX8ULP_CLK_DMA1_CH17 31 152 + #define IMX8ULP_CLK_DMA1_CH18 32 153 + #define IMX8ULP_CLK_DMA1_CH19 33 154 + #define IMX8ULP_CLK_DMA1_CH20 34 155 + #define IMX8ULP_CLK_DMA1_CH21 35 156 + #define IMX8ULP_CLK_DMA1_CH22 36 157 + #define IMX8ULP_CLK_DMA1_CH23 37 158 + #define IMX8ULP_CLK_DMA1_CH24 38 159 + #define IMX8ULP_CLK_DMA1_CH25 39 160 + #define IMX8ULP_CLK_DMA1_CH26 40 161 + #define IMX8ULP_CLK_DMA1_CH27 41 162 + #define IMX8ULP_CLK_DMA1_CH28 42 163 + #define IMX8ULP_CLK_DMA1_CH29 43 164 + #define IMX8ULP_CLK_DMA1_CH30 44 165 + #define IMX8ULP_CLK_DMA1_CH31 45 166 + #define IMX8ULP_CLK_MU3_A 46 167 + #define IMX8ULP_CLK_MU0_B 47 168 + 169 + #define IMX8ULP_CLK_PCC3_END 48 170 + 171 + /* PCC4 */ 172 + #define IMX8ULP_CLK_FLEXSPI2 0 173 + #define IMX8ULP_CLK_TPM6 1 174 + #define IMX8ULP_CLK_TPM7 2 175 + #define IMX8ULP_CLK_LPI2C6 3 176 + #define IMX8ULP_CLK_LPI2C7 4 177 + #define IMX8ULP_CLK_LPUART6 5 178 + #define IMX8ULP_CLK_LPUART7 6 179 + #define IMX8ULP_CLK_SAI4 7 180 + #define IMX8ULP_CLK_SAI5 8 181 + #define IMX8ULP_CLK_PCTLE 9 182 + #define IMX8ULP_CLK_PCTLF 10 183 + #define IMX8ULP_CLK_USDHC0 11 184 + #define IMX8ULP_CLK_USDHC1 12 185 + #define IMX8ULP_CLK_USDHC2 13 186 + #define IMX8ULP_CLK_USB0 14 187 + #define IMX8ULP_CLK_USB0_PHY 15 188 + #define IMX8ULP_CLK_USB1 16 189 + #define IMX8ULP_CLK_USB1_PHY 17 190 + #define IMX8ULP_CLK_USB_XBAR 18 191 + #define IMX8ULP_CLK_ENET 19 192 + #define IMX8ULP_CLK_SFA1 20 193 + #define IMX8ULP_CLK_RGPIOE 21 194 + #define IMX8ULP_CLK_RGPIOF 22 195 + 196 + #define IMX8ULP_CLK_PCC4_END 23 197 + 198 + /* PCC5 */ 199 + #define IMX8ULP_CLK_TPM8 0 200 + #define IMX8ULP_CLK_SAI6 1 201 + #define IMX8ULP_CLK_SAI7 2 202 + #define IMX8ULP_CLK_SPDIF 3 203 + #define IMX8ULP_CLK_ISI 4 204 + #define IMX8ULP_CLK_CSI_REGS 5 205 + #define IMX8ULP_CLK_PCTLD 6 206 + #define IMX8ULP_CLK_CSI 7 207 + #define IMX8ULP_CLK_DSI 8 208 + #define IMX8ULP_CLK_WDOG5 9 209 + #define IMX8ULP_CLK_EPDC 10 210 + #define IMX8ULP_CLK_PXP 11 211 + #define IMX8ULP_CLK_SFA2 12 212 + #define IMX8ULP_CLK_GPU2D 13 213 + #define IMX8ULP_CLK_GPU3D 14 214 + #define IMX8ULP_CLK_DC_NANO 15 215 + #define IMX8ULP_CLK_CSI_CLK_UI 16 216 + #define IMX8ULP_CLK_CSI_CLK_ESC 17 217 + #define IMX8ULP_CLK_RGPIOD 18 218 + #define IMX8ULP_CLK_DMA2_MP 19 219 + #define IMX8ULP_CLK_DMA2_CH0 20 220 + #define IMX8ULP_CLK_DMA2_CH1 21 221 + #define IMX8ULP_CLK_DMA2_CH2 22 222 + #define IMX8ULP_CLK_DMA2_CH3 23 223 + #define IMX8ULP_CLK_DMA2_CH4 24 224 + #define IMX8ULP_CLK_DMA2_CH5 25 225 + #define IMX8ULP_CLK_DMA2_CH6 26 226 + #define IMX8ULP_CLK_DMA2_CH7 27 227 + #define IMX8ULP_CLK_DMA2_CH8 28 228 + #define IMX8ULP_CLK_DMA2_CH9 29 229 + #define IMX8ULP_CLK_DMA2_CH10 30 230 + #define IMX8ULP_CLK_DMA2_CH11 31 231 + #define IMX8ULP_CLK_DMA2_CH12 32 232 + #define IMX8ULP_CLK_DMA2_CH13 33 233 + #define IMX8ULP_CLK_DMA2_CH14 34 234 + #define IMX8ULP_CLK_DMA2_CH15 35 235 + #define IMX8ULP_CLK_DMA2_CH16 36 236 + #define IMX8ULP_CLK_DMA2_CH17 37 237 + #define IMX8ULP_CLK_DMA2_CH18 38 238 + #define IMX8ULP_CLK_DMA2_CH19 39 239 + #define IMX8ULP_CLK_DMA2_CH20 40 240 + #define IMX8ULP_CLK_DMA2_CH21 41 241 + #define IMX8ULP_CLK_DMA2_CH22 42 242 + #define IMX8ULP_CLK_DMA2_CH23 43 243 + #define IMX8ULP_CLK_DMA2_CH24 44 244 + #define IMX8ULP_CLK_DMA2_CH25 45 245 + #define IMX8ULP_CLK_DMA2_CH26 46 246 + #define IMX8ULP_CLK_DMA2_CH27 47 247 + #define IMX8ULP_CLK_DMA2_CH28 48 248 + #define IMX8ULP_CLK_DMA2_CH29 49 249 + #define IMX8ULP_CLK_DMA2_CH30 50 250 + #define IMX8ULP_CLK_DMA2_CH31 51 251 + #define IMX8ULP_CLK_MU2_B 52 252 + #define IMX8ULP_CLK_MU3_B 53 253 + #define IMX8ULP_CLK_AVD_SIM 54 254 + #define IMX8ULP_CLK_DSI_TX_ESC 55 255 + 256 + #define IMX8ULP_CLK_PCC5_END 56 257 + 258 + #endif
+59
include/dt-bindings/reset/imx8ulp-pcc-reset.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /* 3 + * Copyright 2021 NXP 4 + */ 5 + 6 + #ifndef DT_BINDING_PCC_RESET_IMX8ULP_H 7 + #define DT_BINDING_PCC_RESET_IMX8ULP_H 8 + 9 + /* PCC3 */ 10 + #define PCC3_WDOG3_SWRST 0 11 + #define PCC3_WDOG4_SWRST 1 12 + #define PCC3_LPIT1_SWRST 2 13 + #define PCC3_TPM4_SWRST 3 14 + #define PCC3_TPM5_SWRST 4 15 + #define PCC3_FLEXIO1_SWRST 5 16 + #define PCC3_I3C2_SWRST 6 17 + #define PCC3_LPI2C4_SWRST 7 18 + #define PCC3_LPI2C5_SWRST 8 19 + #define PCC3_LPUART4_SWRST 9 20 + #define PCC3_LPUART5_SWRST 10 21 + #define PCC3_LPSPI4_SWRST 11 22 + #define PCC3_LPSPI5_SWRST 12 23 + 24 + /* PCC4 */ 25 + #define PCC4_FLEXSPI2_SWRST 0 26 + #define PCC4_TPM6_SWRST 1 27 + #define PCC4_TPM7_SWRST 2 28 + #define PCC4_LPI2C6_SWRST 3 29 + #define PCC4_LPI2C7_SWRST 4 30 + #define PCC4_LPUART6_SWRST 5 31 + #define PCC4_LPUART7_SWRST 6 32 + #define PCC4_SAI4_SWRST 7 33 + #define PCC4_SAI5_SWRST 8 34 + #define PCC4_USDHC0_SWRST 9 35 + #define PCC4_USDHC1_SWRST 10 36 + #define PCC4_USDHC2_SWRST 11 37 + #define PCC4_USB0_SWRST 12 38 + #define PCC4_USB0_PHY_SWRST 13 39 + #define PCC4_USB1_SWRST 14 40 + #define PCC4_USB1_PHY_SWRST 15 41 + #define PCC4_ENET_SWRST 16 42 + 43 + /* PCC5 */ 44 + #define PCC5_TPM8_SWRST 0 45 + #define PCC5_SAI6_SWRST 1 46 + #define PCC5_SAI7_SWRST 2 47 + #define PCC5_SPDIF_SWRST 3 48 + #define PCC5_ISI_SWRST 4 49 + #define PCC5_CSI_REGS_SWRST 5 50 + #define PCC5_CSI_SWRST 6 51 + #define PCC5_DSI_SWRST 7 52 + #define PCC5_WDOG5_SWRST 8 53 + #define PCC5_EPDC_SWRST 9 54 + #define PCC5_PXP_SWRST 10 55 + #define PCC5_GPU2D_SWRST 11 56 + #define PCC5_GPU3D_SWRST 12 57 + #define PCC5_DC_NANO_SWRST 13 58 + 59 + #endif /*DT_BINDING_RESET_IMX8ULP_H */
+51
include/dt-bindings/reset/stericsson,db8500-prcc-reset.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + 3 + #ifndef _DT_BINDINGS_STE_PRCC_RESET 4 + #define _DT_BINDINGS_STE_PRCC_RESET 5 + 6 + #define DB8500_PRCC_1 1 7 + #define DB8500_PRCC_2 2 8 + #define DB8500_PRCC_3 3 9 + #define DB8500_PRCC_6 6 10 + 11 + /* Reset lines on PRCC 1 */ 12 + #define DB8500_PRCC_1_RESET_UART0 0 13 + #define DB8500_PRCC_1_RESET_UART1 1 14 + #define DB8500_PRCC_1_RESET_I2C1 2 15 + #define DB8500_PRCC_1_RESET_MSP0 3 16 + #define DB8500_PRCC_1_RESET_MSP1 4 17 + #define DB8500_PRCC_1_RESET_SDI0 5 18 + #define DB8500_PRCC_1_RESET_I2C2 6 19 + #define DB8500_PRCC_1_RESET_SPI3 7 20 + #define DB8500_PRCC_1_RESET_SLIMBUS0 8 21 + #define DB8500_PRCC_1_RESET_I2C4 9 22 + #define DB8500_PRCC_1_RESET_MSP3 10 23 + #define DB8500_PRCC_1_RESET_PER_MSP3 11 24 + #define DB8500_PRCC_1_RESET_PER_MSP1 12 25 + #define DB8500_PRCC_1_RESET_PER_MSP0 13 26 + #define DB8500_PRCC_1_RESET_PER_SLIMBUS 14 27 + 28 + /* Reset lines on PRCC 2 */ 29 + #define DB8500_PRCC_2_RESET_I2C3 0 30 + #define DB8500_PRCC_2_RESET_PWL 1 31 + #define DB8500_PRCC_2_RESET_SDI4 2 32 + #define DB8500_PRCC_2_RESET_MSP2 3 33 + #define DB8500_PRCC_2_RESET_SDI1 4 34 + #define DB8500_PRCC_2_RESET_SDI3 5 35 + #define DB8500_PRCC_2_RESET_HSIRX 6 36 + #define DB8500_PRCC_2_RESET_HSITX 7 37 + #define DB8500_PRCC_1_RESET_PER_MSP2 8 38 + 39 + /* Reset lines on PRCC 3 */ 40 + #define DB8500_PRCC_3_RESET_SSP0 1 41 + #define DB8500_PRCC_3_RESET_SSP1 2 42 + #define DB8500_PRCC_3_RESET_I2C0 3 43 + #define DB8500_PRCC_3_RESET_SDI2 4 44 + #define DB8500_PRCC_3_RESET_SKE 5 45 + #define DB8500_PRCC_3_RESET_UART2 6 46 + #define DB8500_PRCC_3_RESET_SDI5 7 47 + 48 + /* Reset lines on PRCC 6 */ 49 + #define DB8500_PRCC_3_RESET_RNG 0 50 + 51 + #endif