* [PATCH V4 0/5] mx: add i.MX93 clk bindings and driver
@ 2022-02-24 8:22 Peng Fan (OSS)
2022-02-24 8:22 ` [PATCH V4 1/5] dt-bindings: clock: Add imx93 clock support Peng Fan (OSS)
` (4 more replies)
0 siblings, 5 replies; 10+ messages in thread
From: Peng Fan (OSS) @ 2022-02-24 8:22 UTC (permalink / raw)
To: sboyd, robh+dt, shawnguo, s.hauer, abel.vesa
Cc: kernel, festevam, linux-imx, linux-clk, devicetree,
linux-arm-kernel, linux-kernel, Peng Fan
From: Peng Fan <peng.fan@nxp.com>
V4:
Add Abel's R-b and Krzysztof's A-b
Address Krzysztof's comments
Address Sascha's comments in patch 4/5
Typo fix
V3:
Drop an error included header file in 5/5
V2:
Split yaml binding and clock header
apply to Abel's tree
Add i.MX93 clk bindings and clk.
Peng Fan (5):
dt-bindings: clock: Add imx93 clock support
dt-bindings: clock: add i.MX93 clock definition
clk: imx: add i.MX93 composite clk
clk: imx: support fracn gppll
clk: imx: add i.MX93 clk
.../bindings/clock/imx93-clock.yaml | 62 ++++
drivers/clk/imx/Kconfig | 6 +
drivers/clk/imx/Makefile | 4 +
drivers/clk/imx/clk-composite-93.c | 93 +++++
drivers/clk/imx/clk-fracn-gppll.c | 326 +++++++++++++++++
drivers/clk/imx/clk-imx93.c | 338 ++++++++++++++++++
drivers/clk/imx/clk.h | 30 ++
include/dt-bindings/clock/imx93-clock.h | 201 +++++++++++
8 files changed, 1060 insertions(+)
create mode 100644 Documentation/devicetree/bindings/clock/imx93-clock.yaml
create mode 100644 drivers/clk/imx/clk-composite-93.c
create mode 100644 drivers/clk/imx/clk-fracn-gppll.c
create mode 100644 drivers/clk/imx/clk-imx93.c
create mode 100644 include/dt-bindings/clock/imx93-clock.h
--
2.25.1
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH V4 1/5] dt-bindings: clock: Add imx93 clock support
2022-02-24 8:22 [PATCH V4 0/5] mx: add i.MX93 clk bindings and driver Peng Fan (OSS)
@ 2022-02-24 8:22 ` Peng Fan (OSS)
2022-02-24 19:23 ` Rob Herring
2022-02-24 8:22 ` [PATCH V4 2/5] dt-bindings: clock: add i.MX93 clock definition Peng Fan (OSS)
` (3 subsequent siblings)
4 siblings, 1 reply; 10+ messages in thread
From: Peng Fan (OSS) @ 2022-02-24 8:22 UTC (permalink / raw)
To: sboyd, robh+dt, shawnguo, s.hauer, abel.vesa
Cc: kernel, festevam, linux-imx, linux-clk, devicetree,
linux-arm-kernel, linux-kernel, Peng Fan
From: Peng Fan <peng.fan@nxp.com>
Add the clock dt-binding file for i.MX93.
Reviewed-by: Abel Vesa <abel.vesa@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
.../bindings/clock/imx93-clock.yaml | 62 +++++++++++++++++++
1 file changed, 62 insertions(+)
create mode 100644 Documentation/devicetree/bindings/clock/imx93-clock.yaml
diff --git a/Documentation/devicetree/bindings/clock/imx93-clock.yaml b/Documentation/devicetree/bindings/clock/imx93-clock.yaml
new file mode 100644
index 000000000000..21a06194e4a3
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/imx93-clock.yaml
@@ -0,0 +1,62 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/imx93-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NXP i.MX93 Clock Control Module Binding
+
+maintainers:
+ - Peng Fan <peng.fan@nxp.com>
+
+description: |
+ i.MX93 clock control module is an integrated clock controller, which
+ includes clock generator, clock gate and supplies to all modules.
+
+properties:
+ compatible:
+ enum:
+ - fsl,imx93-ccm
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ description:
+ specify the external clocks used by the CCM module.
+ items:
+ - description: 32k osc
+ - description: 24m osc
+ - description: ext1 clock input
+
+ clock-names:
+ description:
+ specify the external clocks names used by the CCM module.
+ items:
+ - const: osc_32k
+ - const: osc_24m
+ - const: clk_ext1
+
+ '#clock-cells':
+ const: 1
+ description:
+ See include/dt-bindings/clock/imx93-clock.h for the full list of
+ i.MX93 clock IDs.
+
+required:
+ - compatible
+ - reg
+ - '#clock-cells'
+
+additionalProperties: false
+
+examples:
+ # Clock Control Module node:
+ - |
+ clock-controller@44450000 {
+ compatible = "fsl,imx93-ccm";
+ reg = <0x44450000 0x10000>;
+ #clock-cells = <1>;
+ };
+
+...
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH V4 2/5] dt-bindings: clock: add i.MX93 clock definition
2022-02-24 8:22 [PATCH V4 0/5] mx: add i.MX93 clk bindings and driver Peng Fan (OSS)
2022-02-24 8:22 ` [PATCH V4 1/5] dt-bindings: clock: Add imx93 clock support Peng Fan (OSS)
@ 2022-02-24 8:22 ` Peng Fan (OSS)
2022-02-24 19:24 ` Rob Herring
2022-02-24 8:22 ` [PATCH V4 3/5] clk: imx: add i.MX93 composite clk Peng Fan (OSS)
` (2 subsequent siblings)
4 siblings, 1 reply; 10+ messages in thread
From: Peng Fan (OSS) @ 2022-02-24 8:22 UTC (permalink / raw)
To: sboyd, robh+dt, shawnguo, s.hauer, abel.vesa
Cc: kernel, festevam, linux-imx, linux-clk, devicetree,
linux-arm-kernel, linux-kernel, Peng Fan, Krzysztof Kozlowski
From: Peng Fan <peng.fan@nxp.com>
Add i.MX93 clock definition
Reviewed-by: Abel Vesa <abel.vesa@nxp.com>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
include/dt-bindings/clock/imx93-clock.h | 201 ++++++++++++++++++++++++
1 file changed, 201 insertions(+)
create mode 100644 include/dt-bindings/clock/imx93-clock.h
diff --git a/include/dt-bindings/clock/imx93-clock.h b/include/dt-bindings/clock/imx93-clock.h
new file mode 100644
index 000000000000..21fda9c5cb5e
--- /dev/null
+++ b/include/dt-bindings/clock/imx93-clock.h
@@ -0,0 +1,201 @@
+/* SPDX-License-Identifier: GPL-2.0+ OR MIT */
+/*
+ * Copyright 2022 NXP
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_IMX93_CLK_H
+#define __DT_BINDINGS_CLOCK_IMX93_CLK_H
+
+#define IMX93_CLK_DUMMY 0
+#define IMX93_CLK_24M 1
+#define IMX93_CLK_EXT1 2
+#define IMX93_CLK_SYS_PLL_PFD0 3
+#define IMX93_CLK_SYS_PLL_PFD0_DIV2 4
+#define IMX93_CLK_SYS_PLL_PFD1 5
+#define IMX93_CLK_SYS_PLL_PFD1_DIV2 6
+#define IMX93_CLK_SYS_PLL_PFD2 7
+#define IMX93_CLK_SYS_PLL_PFD2_DIV2 8
+#define IMX93_CLK_AUDIO_PLL 9
+#define IMX93_CLK_VIDEO_PLL 10
+#define IMX93_CLK_A55_PERIPH 11
+#define IMX93_CLK_A55_MTR_BUS 12
+#define IMX93_CLK_A55 13
+#define IMX93_CLK_M33 14
+#define IMX93_CLK_BUS_WAKEUP 15
+#define IMX93_CLK_BUS_AON 16
+#define IMX93_CLK_WAKEUP_AXI 17
+#define IMX93_CLK_SWO_TRACE 18
+#define IMX93_CLK_M33_SYSTICK 19
+#define IMX93_CLK_FLEXIO1 20
+#define IMX93_CLK_FLEXIO2 21
+#define IMX93_CLK_LPIT1 22
+#define IMX93_CLK_LPIT2 23
+#define IMX93_CLK_LPTMR1 24
+#define IMX93_CLK_LPTMR2 25
+#define IMX93_CLK_TPM1 26
+#define IMX93_CLK_TPM2 27
+#define IMX93_CLK_TPM3 28
+#define IMX93_CLK_TPM4 29
+#define IMX93_CLK_TPM5 30
+#define IMX93_CLK_TPM6 31
+#define IMX93_CLK_FLEXSPI1 32
+#define IMX93_CLK_CAN1 33
+#define IMX93_CLK_CAN2 34
+#define IMX93_CLK_LPUART1 35
+#define IMX93_CLK_LPUART2 36
+#define IMX93_CLK_LPUART3 37
+#define IMX93_CLK_LPUART4 38
+#define IMX93_CLK_LPUART5 39
+#define IMX93_CLK_LPUART6 40
+#define IMX93_CLK_LPUART7 41
+#define IMX93_CLK_LPUART8 42
+#define IMX93_CLK_LPI2C1 43
+#define IMX93_CLK_LPI2C2 44
+#define IMX93_CLK_LPI2C3 45
+#define IMX93_CLK_LPI2C4 46
+#define IMX93_CLK_LPI2C5 47
+#define IMX93_CLK_LPI2C6 48
+#define IMX93_CLK_LPI2C7 49
+#define IMX93_CLK_LPI2C8 50
+#define IMX93_CLK_LPSPI1 51
+#define IMX93_CLK_LPSPI2 52
+#define IMX93_CLK_LPSPI3 53
+#define IMX93_CLK_LPSPI4 54
+#define IMX93_CLK_LPSPI5 55
+#define IMX93_CLK_LPSPI6 56
+#define IMX93_CLK_LPSPI7 57
+#define IMX93_CLK_LPSPI8 58
+#define IMX93_CLK_I3C1 59
+#define IMX93_CLK_I3C2 60
+#define IMX93_CLK_USDHC1 61
+#define IMX93_CLK_USDHC2 62
+#define IMX93_CLK_USDHC3 63
+#define IMX93_CLK_SAI1 64
+#define IMX93_CLK_SAI2 65
+#define IMX93_CLK_SAI3 66
+#define IMX93_CLK_CCM_CKO1 67
+#define IMX93_CLK_CCM_CKO2 68
+#define IMX93_CLK_CCM_CKO3 69
+#define IMX93_CLK_CCM_CKO4 70
+#define IMX93_CLK_HSIO 71
+#define IMX93_CLK_HSIO_USB_TEST_60M 72
+#define IMX93_CLK_HSIO_ACSCAN_80M 73
+#define IMX93_CLK_HSIO_ACSCAN_480M 74
+#define IMX93_CLK_ML_APB 75
+#define IMX93_CLK_ML 76
+#define IMX93_CLK_MEDIA_AXI 77
+#define IMX93_CLK_MEDIA_APB 78
+#define IMX93_CLK_MEDIA_LDB 79
+#define IMX93_CLK_MEDIA_DISP_PIX 80
+#define IMX93_CLK_CAM_PIX 81
+#define IMX93_CLK_MIPI_TEST_BYTE 82
+#define IMX93_CLK_MIPI_PHY_CFG 83
+#define IMX93_CLK_ADC 84
+#define IMX93_CLK_PDM 85
+#define IMX93_CLK_TSTMR1 86
+#define IMX93_CLK_TSTMR2 87
+#define IMX93_CLK_MQS1 88
+#define IMX93_CLK_MQS2 89
+#define IMX93_CLK_AUDIO_XCVR 90
+#define IMX93_CLK_SPDIF 91
+#define IMX93_CLK_ENET 92
+#define IMX93_CLK_ENET_TIMER1 93
+#define IMX93_CLK_ENET_TIMER2 94
+#define IMX93_CLK_ENET_REF 95
+#define IMX93_CLK_ENET_REF_PHY 96
+#define IMX93_CLK_I3C1_SLOW 97
+#define IMX93_CLK_I3C2_SLOW 98
+#define IMX93_CLK_USB_PHY_BURUNIN 99
+#define IMX93_CLK_PAL_CAME_SCAN 100
+#define IMX93_CLK_A55_GATE 101
+#define IMX93_CLK_CM33_GATE 102
+#define IMX93_CLK_ADC1_GATE 103
+#define IMX93_CLK_WDOG1_GATE 104
+#define IMX93_CLK_WDOG2_GATE 105
+#define IMX93_CLK_WDOG3_GATE 106
+#define IMX93_CLK_WDOG4_GATE 107
+#define IMX93_CLK_WDOG5_GATE 108
+#define IMX93_CLK_SEMA1_GATE 109
+#define IMX93_CLK_SEMA2_GATE 110
+#define IMX93_CLK_MU_A_GATE 111
+#define IMX93_CLK_MU_B_GATE 112
+#define IMX93_CLK_EDMA1_GATE 113
+#define IMX93_CLK_EDMA2_GATE 114
+#define IMX93_CLK_FLEXSPI1_GATE 115
+#define IMX93_CLK_GPIO1_GATE 116
+#define IMX93_CLK_GPIO2_GATE 117
+#define IMX93_CLK_GPIO3_GATE 118
+#define IMX93_CLK_GPIO4_GATE 119
+#define IMX93_CLK_FLEXIO1_GATE 120
+#define IMX93_CLK_FLEXIO2_GATE 121
+#define IMX93_CLK_LPIT1_GATE 122
+#define IMX93_CLK_LPIT2_GATE 123
+#define IMX93_CLK_LPTMR1_GATE 124
+#define IMX93_CLK_LPTMR2_GATE 125
+#define IMX93_CLK_TPM1_GATE 126
+#define IMX93_CLK_TPM2_GATE 127
+#define IMX93_CLK_TPM3_GATE 128
+#define IMX93_CLK_TPM4_GATE 129
+#define IMX93_CLK_TPM5_GATE 130
+#define IMX93_CLK_TPM6_GATE 131
+#define IMX93_CLK_CAN1_GATE 132
+#define IMX93_CLK_CAN2_GATE 133
+#define IMX93_CLK_LPUART1_GATE 134
+#define IMX93_CLK_LPUART2_GATE 135
+#define IMX93_CLK_LPUART3_GATE 136
+#define IMX93_CLK_LPUART4_GATE 137
+#define IMX93_CLK_LPUART5_GATE 138
+#define IMX93_CLK_LPUART6_GATE 139
+#define IMX93_CLK_LPUART7_GATE 140
+#define IMX93_CLK_LPUART8_GATE 141
+#define IMX93_CLK_LPI2C1_GATE 142
+#define IMX93_CLK_LPI2C2_GATE 143
+#define IMX93_CLK_LPI2C3_GATE 144
+#define IMX93_CLK_LPI2C4_GATE 145
+#define IMX93_CLK_LPI2C5_GATE 146
+#define IMX93_CLK_LPI2C6_GATE 147
+#define IMX93_CLK_LPI2C7_GATE 148
+#define IMX93_CLK_LPI2C8_GATE 149
+#define IMX93_CLK_LPSPI1_GATE 150
+#define IMX93_CLK_LPSPI2_GATE 151
+#define IMX93_CLK_LPSPI3_GATE 152
+#define IMX93_CLK_LPSPI4_GATE 153
+#define IMX93_CLK_LPSPI5_GATE 154
+#define IMX93_CLK_LPSPI6_GATE 155
+#define IMX93_CLK_LPSPI7_GATE 156
+#define IMX93_CLK_LPSPI8_GATE 157
+#define IMX93_CLK_I3C1_GATE 158
+#define IMX93_CLK_I3C2_GATE 159
+#define IMX93_CLK_USDHC1_GATE 160
+#define IMX93_CLK_USDHC2_GATE 161
+#define IMX93_CLK_USDHC3_GATE 162
+#define IMX93_CLK_SAI1_GATE 163
+#define IMX93_CLK_SAI2_GATE 164
+#define IMX93_CLK_SAI3_GATE 165
+#define IMX93_CLK_MIPI_CSI_GATE 166
+#define IMX93_CLK_MIPI_DSI_GATE 167
+#define IMX93_CLK_LVDS_GATE 168
+#define IMX93_CLK_LCDIF_GATE 169
+#define IMX93_CLK_PXP_GATE 170
+#define IMX93_CLK_ISI_GATE 171
+#define IMX93_CLK_NIC_MEDIA_GATE 172
+#define IMX93_CLK_USB_CONTROLLER_GATE 173
+#define IMX93_CLK_USB_TEST_60M_GATE 174
+#define IMX93_CLK_HSIO_TROUT_24M_GATE 175
+#define IMX93_CLK_PDM_GATE 176
+#define IMX93_CLK_MQS1_GATE 177
+#define IMX93_CLK_MQS2_GATE 178
+#define IMX93_CLK_AUD_XCVR_GATE 179
+#define IMX93_CLK_SPDIF_GATE 180
+#define IMX93_CLK_HSIO_32K_GATE 181
+#define IMX93_CLK_ENET1_GATE 182
+#define IMX93_CLK_ENET_QOS_GATE 183
+#define IMX93_CLK_SYS_CNT_GATE 184
+#define IMX93_CLK_TSTMR1_GATE 185
+#define IMX93_CLK_TSTMR2_GATE 186
+#define IMX93_CLK_TMC_GATE 187
+#define IMX93_CLK_PMRO_GATE 188
+#define IMX93_CLK_32K 189
+#define IMX93_CLK_END 190
+
+#endif
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH V4 3/5] clk: imx: add i.MX93 composite clk
2022-02-24 8:22 [PATCH V4 0/5] mx: add i.MX93 clk bindings and driver Peng Fan (OSS)
2022-02-24 8:22 ` [PATCH V4 1/5] dt-bindings: clock: Add imx93 clock support Peng Fan (OSS)
2022-02-24 8:22 ` [PATCH V4 2/5] dt-bindings: clock: add i.MX93 clock definition Peng Fan (OSS)
@ 2022-02-24 8:22 ` Peng Fan (OSS)
2022-02-24 8:22 ` [PATCH V4 4/5] clk: imx: support fracn gppll Peng Fan (OSS)
2022-02-24 8:22 ` [PATCH V4 5/5] clk: imx: add i.MX93 clk Peng Fan (OSS)
4 siblings, 0 replies; 10+ messages in thread
From: Peng Fan (OSS) @ 2022-02-24 8:22 UTC (permalink / raw)
To: sboyd, robh+dt, shawnguo, s.hauer, abel.vesa
Cc: kernel, festevam, linux-imx, linux-clk, devicetree,
linux-arm-kernel, linux-kernel, Peng Fan
From: Peng Fan <peng.fan@nxp.com>
i.MX93 CCM ROOT clock has a mux, gate and divider in one register, here
is to combine all these into one composite clk and simplify clk tree.
i.MX93 CCM is a new IP compared with i.MX8M, so introduce a new file.
Reviewed-by: Abel Vesa <abel.vesa@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
drivers/clk/imx/Makefile | 1 +
drivers/clk/imx/clk-composite-93.c | 93 ++++++++++++++++++++++++++++++
drivers/clk/imx/clk.h | 9 +++
3 files changed, 103 insertions(+)
create mode 100644 drivers/clk/imx/clk-composite-93.c
diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile
index aa8f5204d7e1..36c04922d789 100644
--- a/drivers/clk/imx/Makefile
+++ b/drivers/clk/imx/Makefile
@@ -4,6 +4,7 @@ mxc-clk-objs += clk.o
mxc-clk-objs += clk-busy.o
mxc-clk-objs += clk-composite-7ulp.o
mxc-clk-objs += clk-composite-8m.o
+mxc-clk-objs += clk-composite-93.o
mxc-clk-objs += clk-cpu.o
mxc-clk-objs += clk-divider-gate.o
mxc-clk-objs += clk-fixup-div.o
diff --git a/drivers/clk/imx/clk-composite-93.c b/drivers/clk/imx/clk-composite-93.c
new file mode 100644
index 000000000000..b44619aa5ca5
--- /dev/null
+++ b/drivers/clk/imx/clk-composite-93.c
@@ -0,0 +1,93 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2021 NXP
+ *
+ * Peng Fan <peng.fan@nxp.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/errno.h>
+#include <linux/export.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+
+#include "clk.h"
+
+#define CCM_DIV_SHIFT 0
+#define CCM_DIV_WIDTH 8
+#define CCM_MUX_SHIFT 8
+#define CCM_MUX_MASK 3
+#define CCM_OFF_SHIFT 24
+
+#define AUTHEN_OFFSET 0x30
+#define TZ_NS_SHIFT 9
+#define TZ_NS_MASK BIT(9)
+
+struct clk_hw *imx93_clk_composite_flags(const char *name, const char * const *parent_names,
+ int num_parents, void __iomem *reg,
+ unsigned long flags)
+{
+ struct clk_hw *hw = ERR_PTR(-ENOMEM), *mux_hw;
+ struct clk_hw *div_hw, *gate_hw;
+ struct clk_divider *div = NULL;
+ struct clk_gate *gate = NULL;
+ struct clk_mux *mux = NULL;
+ bool clk_ro = false;
+
+ mux = kzalloc(sizeof(*mux), GFP_KERNEL);
+ if (!mux)
+ goto fail;
+
+ mux_hw = &mux->hw;
+ mux->reg = reg;
+ mux->shift = CCM_MUX_SHIFT;
+ mux->mask = CCM_MUX_MASK;
+ mux->lock = &imx_ccm_lock;
+
+ div = kzalloc(sizeof(*div), GFP_KERNEL);
+ if (!div)
+ goto fail;
+
+ div_hw = &div->hw;
+ div->reg = reg;
+ div->shift = CCM_DIV_SHIFT;
+ div->width = CCM_DIV_WIDTH;
+ div->lock = &imx_ccm_lock;
+ div->flags = CLK_DIVIDER_ROUND_CLOSEST;
+
+ if (!(readl(reg + AUTHEN_OFFSET) & TZ_NS_MASK))
+ clk_ro = true;
+
+ if (clk_ro) {
+ hw = clk_hw_register_composite(NULL, name, parent_names, num_parents,
+ mux_hw, &clk_mux_ro_ops, div_hw,
+ &clk_divider_ro_ops, NULL, NULL, flags);
+ } else {
+ gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+ if (!gate)
+ goto fail;
+
+ gate_hw = &gate->hw;
+ gate->reg = reg;
+ gate->bit_idx = CCM_OFF_SHIFT;
+ gate->lock = &imx_ccm_lock;
+ gate->flags = CLK_GATE_SET_TO_DISABLE;
+
+ hw = clk_hw_register_composite(NULL, name, parent_names, num_parents,
+ mux_hw, &clk_mux_ops, div_hw,
+ &clk_divider_ops, gate_hw,
+ &clk_gate_ops, flags | CLK_SET_RATE_NO_REPARENT);
+ }
+
+ if (IS_ERR(hw))
+ goto fail;
+
+ return hw;
+
+fail:
+ kfree(gate);
+ kfree(div);
+ kfree(mux);
+ return ERR_CAST(hw);
+}
+EXPORT_SYMBOL_GPL(imx93_clk_composite_flags);
diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
index 7d220a01de1f..63eb7c53b123 100644
--- a/drivers/clk/imx/clk.h
+++ b/drivers/clk/imx/clk.h
@@ -419,6 +419,15 @@ struct clk_hw *__imx8m_clk_hw_composite(const char *name,
IMX_COMPOSITE_FW_MANAGED, \
IMX_COMPOSITE_CLK_FLAGS_CRITICAL_GET_RATE_NO_CACHE)
+struct clk_hw *imx93_clk_composite_flags(const char *name,
+ const char * const *parent_names,
+ int num_parents,
+ void __iomem *reg,
+ unsigned long flags);
+#define imx93_clk_composite(name, parent_names, num_parents, reg) \
+ imx93_clk_composite_flags(name, parent_names, num_parents, reg, \
+ CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE)
+
struct clk_hw *imx_clk_hw_divider_gate(const char *name, const char *parent_name,
unsigned long flags, void __iomem *reg, u8 shift, u8 width,
u8 clk_divider_flags, const struct clk_div_table *table,
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH V4 4/5] clk: imx: support fracn gppll
2022-02-24 8:22 [PATCH V4 0/5] mx: add i.MX93 clk bindings and driver Peng Fan (OSS)
` (2 preceding siblings ...)
2022-02-24 8:22 ` [PATCH V4 3/5] clk: imx: add i.MX93 composite clk Peng Fan (OSS)
@ 2022-02-24 8:22 ` Peng Fan (OSS)
2022-02-24 9:58 ` Sascha Hauer
2022-02-24 8:22 ` [PATCH V4 5/5] clk: imx: add i.MX93 clk Peng Fan (OSS)
4 siblings, 1 reply; 10+ messages in thread
From: Peng Fan (OSS) @ 2022-02-24 8:22 UTC (permalink / raw)
To: sboyd, robh+dt, shawnguo, s.hauer, abel.vesa
Cc: kernel, festevam, linux-imx, linux-clk, devicetree,
linux-arm-kernel, linux-kernel, Peng Fan
From: Peng Fan <peng.fan@nxp.com>
This PLL module is a Fractional-N synthesizer,
supporting 30-bit numerator and denominator. Numerator is a signed
number. It has feature to adjust fractional portion of feedback
divider dynamically. This fracn gppll is used in i.MX93.
Reviewed-by: Abel Vesa <abel.vesa@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
drivers/clk/imx/Makefile | 1 +
drivers/clk/imx/clk-fracn-gppll.c | 326 ++++++++++++++++++++++++++++++
drivers/clk/imx/clk.h | 21 ++
3 files changed, 348 insertions(+)
create mode 100644 drivers/clk/imx/clk-fracn-gppll.c
diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile
index 36c04922d789..60c8a4bb7574 100644
--- a/drivers/clk/imx/Makefile
+++ b/drivers/clk/imx/Makefile
@@ -5,6 +5,7 @@ mxc-clk-objs += clk-busy.o
mxc-clk-objs += clk-composite-7ulp.o
mxc-clk-objs += clk-composite-8m.o
mxc-clk-objs += clk-composite-93.o
+mxc-clk-objs += clk-fracn-gppll.o
mxc-clk-objs += clk-cpu.o
mxc-clk-objs += clk-divider-gate.o
mxc-clk-objs += clk-fixup-div.o
diff --git a/drivers/clk/imx/clk-fracn-gppll.c b/drivers/clk/imx/clk-fracn-gppll.c
new file mode 100644
index 000000000000..b6add3a2e472
--- /dev/null
+++ b/drivers/clk/imx/clk-fracn-gppll.c
@@ -0,0 +1,326 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2021 NXP
+ */
+
+#include <asm/div64.h>
+#include <linux/bitfield.h>
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/export.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+
+#include "clk.h"
+
+#define PLL_CTRL 0x0
+#define CLKMUX_BYPASS BIT(2)
+#define CLKMUX_EN BIT(1)
+#define POWERUP_MASK BIT(0)
+
+#define PLL_ANA_PRG 0x10
+#define PLL_SPREAD_SPECTRUM 0x30
+
+#define PLL_NUMERATOR 0x40
+#define PLL_MFN_MASK GENMASK(31, 2)
+#define PLL_MFN_SHIFT 2
+
+#define PLL_DENOMINATOR 0x50
+#define PLL_MFD_MASK GENMASK(29, 0)
+
+#define PLL_DIV 0x60
+#define PLL_MFI_MASK GENMASK(24, 16)
+#define PLL_MFI_SHIFT 16
+#define PLL_RDIV_MASK GENMASK(15, 13)
+#define PLL_RDIV_SHIFT 13
+#define PLL_ODIV_MASK GENMASK(7, 0)
+
+#define PLL_DFS_CTRL(x) (0x70 + (x) * 0x10)
+
+#define PLL_STATUS 0xF0
+#define LOCK_STATUS BIT(0)
+
+#define DFS_STATUS 0xF4
+
+#define LOCK_TIMEOUT_US 200
+
+#define PLL_FRACN_GP(_rate, _mfi, _mfn, _mfd, _rdiv, _odiv) \
+ { \
+ .rate = (_rate), \
+ .mfi = (_mfi), \
+ .mfn = (_mfn), \
+ .mfd = (_mfd), \
+ .rdiv = (_rdiv), \
+ .odiv = (_odiv), \
+ }
+
+struct clk_fracn_gppll {
+ struct clk_hw hw;
+ void __iomem *base;
+ const struct imx_fracn_gppll_rate_table *rate_table;
+ int rate_count;
+};
+
+/*
+ * Fvco = Fref * (MFI + MFN / MFD)
+ * Fout = Fvco / (rdiv * odiv)
+ */
+static const struct imx_fracn_gppll_rate_table fracn_tbl[] = {
+ PLL_FRACN_GP(650000000U, 81, 0, 0, 0, 3),
+ PLL_FRACN_GP(594000000U, 198, 0, 0, 0, 8),
+ PLL_FRACN_GP(560000000U, 70, 0, 0, 0, 3),
+ PLL_FRACN_GP(400000000U, 50, 0, 0, 0, 3),
+ PLL_FRACN_GP(393216000U, 81, 92, 100, 0, 5)
+};
+
+struct imx_fracn_gppll_clk imx_fracn_gppll = {
+ .rate_table = fracn_tbl,
+ .rate_count = ARRAY_SIZE(fracn_tbl),
+};
+EXPORT_SYMBOL_GPL(imx_fracn_gppll);
+
+static inline struct clk_fracn_gppll *to_clk_fracn_gppll(struct clk_hw *hw)
+{
+ return container_of(hw, struct clk_fracn_gppll, hw);
+}
+
+static const struct imx_fracn_gppll_rate_table *
+imx_get_pll_settings(struct clk_fracn_gppll *pll, unsigned long rate)
+{
+ const struct imx_fracn_gppll_rate_table *rate_table = pll->rate_table;
+ int i;
+
+ for (i = 0; i < pll->rate_count; i++)
+ if (rate == rate_table[i].rate)
+ return &rate_table[i];
+
+ return NULL;
+}
+
+static long clk_fracn_gppll_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *prate)
+{
+ struct clk_fracn_gppll *pll = to_clk_fracn_gppll(hw);
+ const struct imx_fracn_gppll_rate_table *rate_table = pll->rate_table;
+ int i;
+
+ /* Assuming rate_table is in descending order */
+ for (i = 0; i < pll->rate_count; i++)
+ if (rate >= rate_table[i].rate)
+ return rate_table[i].rate;
+
+ /* return minimum supported value */
+ return rate_table[pll->rate_count - 1].rate;
+}
+
+static unsigned long clk_fracn_gppll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
+{
+ struct clk_fracn_gppll *pll = to_clk_fracn_gppll(hw);
+ const struct imx_fracn_gppll_rate_table *rate_table = pll->rate_table;
+ u32 pll_numerator, pll_denominator, pll_div;
+ u32 mfi, mfn, mfd, rdiv, odiv;
+ u64 fvco = parent_rate;
+ long rate = 0;
+ int i;
+
+ pll_numerator = readl_relaxed(pll->base + PLL_NUMERATOR);
+ mfn = FIELD_GET(PLL_MFN_MASK, pll_numerator);
+
+ pll_denominator = readl_relaxed(pll->base + PLL_DENOMINATOR);
+ mfd = FIELD_GET(PLL_MFD_MASK, pll_denominator);
+
+ pll_div = readl_relaxed(pll->base + PLL_DIV);
+ mfi = FIELD_GET(PLL_MFI_MASK, pll_div);
+
+ rdiv = FIELD_GET(PLL_RDIV_MASK, pll_div);
+ rdiv = rdiv + 1;
+ odiv = FIELD_GET(PLL_ODIV_MASK, pll_div);
+ switch (odiv) {
+ case 0:
+ odiv = 2;
+ break;
+ case 1:
+ odiv = 3;
+ break;
+ default:
+ break;
+ }
+
+ /*
+ * Sometimes, the recalculated rate has deviation due to
+ * the frac part. So find the accurate pll rate from the table
+ * first, if no match rate in the table, use the rate calculated
+ * from the equation below.
+ */
+ for (i = 0; i < pll->rate_count; i++) {
+ if (rate_table[i].mfn == mfn && rate_table[i].mfi == mfi &&
+ rate_table[i].mfd == mfd && rate_table[i].rdiv == rdiv &&
+ rate_table[i].odiv == odiv)
+ rate = rate_table[i].rate;
+ }
+
+ if (rate)
+ return (unsigned long)rate;
+
+ /* Fvco = Fref * (MFI + MFN / MFD) */
+ fvco = fvco * mfi * mfd + fvco * mfn;
+ do_div(fvco, mfd * rdiv * odiv);
+
+ return (unsigned long)fvco;
+}
+
+static int clk_fracn_gppll_wait_lock(struct clk_fracn_gppll *pll)
+{
+ u32 val;
+
+ return readl_poll_timeout(pll->base + PLL_STATUS, val,
+ val & LOCK_STATUS, 0, LOCK_TIMEOUT_US);
+}
+
+static int clk_fracn_gppll_set_rate(struct clk_hw *hw, unsigned long drate,
+ unsigned long prate)
+{
+ struct clk_fracn_gppll *pll = to_clk_fracn_gppll(hw);
+ const struct imx_fracn_gppll_rate_table *rate;
+ u32 tmp, pll_div, ana_mfn;
+ int ret;
+
+ rate = imx_get_pll_settings(pll, drate);
+
+ /* Disable output */
+ tmp = readl_relaxed(pll->base + PLL_CTRL);
+ tmp &= ~CLKMUX_EN;
+ writel_relaxed(tmp, pll->base + PLL_CTRL);
+
+ /* Power Down */
+ tmp &= ~POWERUP_MASK;
+ writel_relaxed(tmp, pll->base + PLL_CTRL);
+
+ /* Disable BYPASS */
+ tmp &= ~CLKMUX_BYPASS;
+ writel_relaxed(tmp, pll->base + PLL_CTRL);
+
+ pll_div = FIELD_PREP(PLL_RDIV_MASK, rate->rdiv) | rate->odiv |
+ FIELD_PREP(PLL_MFI_MASK, rate->mfi);
+ writel_relaxed(pll_div, pll->base + PLL_DIV);
+ writel_relaxed(rate->mfd, pll->base + PLL_DENOMINATOR);
+ writel_relaxed(rate->mfn << PLL_MFN_SHIFT, pll->base + PLL_NUMERATOR);
+
+ /* Wait for 5us according to fracn mode pll doc */
+ udelay(5);
+
+ /* Enable Powerup */
+ tmp |= POWERUP_MASK;
+ writel_relaxed(tmp, pll->base + PLL_CTRL);
+
+ /* Wait Lock */
+ ret = clk_fracn_gppll_wait_lock(pll);
+ if (ret)
+ return ret;
+
+ /* Enable output */
+ tmp |= CLKMUX_EN;
+ writel_relaxed(tmp, pll->base + PLL_CTRL);
+
+ ana_mfn = (readl_relaxed(pll->base + PLL_STATUS) & PLL_MFN_MASK) >> PLL_MFN_SHIFT;
+
+ WARN(ana_mfn != rate->mfn, "ana_mfn != rate->mfn\n");
+
+ return 0;
+}
+
+static int clk_fracn_gppll_prepare(struct clk_hw *hw)
+{
+ struct clk_fracn_gppll *pll = to_clk_fracn_gppll(hw);
+ u32 val;
+ int ret;
+
+ val = readl_relaxed(pll->base + PLL_CTRL);
+ if (val & POWERUP_MASK)
+ return 0;
+
+ val |= CLKMUX_BYPASS;
+ writel_relaxed(val, pll->base + PLL_CTRL);
+
+ val |= POWERUP_MASK;
+ writel_relaxed(val, pll->base + PLL_CTRL);
+
+ val |= CLKMUX_EN;
+ writel_relaxed(val, pll->base + PLL_CTRL);
+
+ ret = clk_fracn_gppll_wait_lock(pll);
+ if (ret)
+ return ret;
+
+ val &= ~CLKMUX_BYPASS;
+ writel_relaxed(val, pll->base + PLL_CTRL);
+
+ return 0;
+}
+
+static int clk_fracn_gppll_is_prepared(struct clk_hw *hw)
+{
+ struct clk_fracn_gppll *pll = to_clk_fracn_gppll(hw);
+ u32 val;
+
+ val = readl_relaxed(pll->base + PLL_CTRL);
+
+ return (val & POWERUP_MASK) ? 1 : 0;
+}
+
+static void clk_fracn_gppll_unprepare(struct clk_hw *hw)
+{
+ struct clk_fracn_gppll *pll = to_clk_fracn_gppll(hw);
+ u32 val;
+
+ val = readl_relaxed(pll->base + PLL_CTRL);
+ val &= ~POWERUP_MASK;
+ writel_relaxed(val, pll->base + PLL_CTRL);
+}
+
+static const struct clk_ops clk_fracn_gppll_ops = {
+ .prepare = clk_fracn_gppll_prepare,
+ .unprepare = clk_fracn_gppll_unprepare,
+ .is_prepared = clk_fracn_gppll_is_prepared,
+ .recalc_rate = clk_fracn_gppll_recalc_rate,
+ .round_rate = clk_fracn_gppll_round_rate,
+ .set_rate = clk_fracn_gppll_set_rate,
+};
+
+struct clk_hw *imx_clk_fracn_gppll(const char *name, const char *parent_name, void __iomem *base,
+ const struct imx_fracn_gppll_clk *pll_clk)
+{
+ struct clk_fracn_gppll *pll;
+ struct clk_hw *hw;
+ struct clk_init_data init;
+ int ret;
+
+ pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+ if (!pll)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = name;
+ init.flags = pll_clk->flags;
+ init.parent_names = &parent_name;
+ init.num_parents = 1;
+ init.ops = &clk_fracn_gppll_ops;
+
+ pll->base = base;
+ pll->hw.init = &init;
+ pll->rate_table = pll_clk->rate_table;
+ pll->rate_count = pll_clk->rate_count;
+
+ hw = &pll->hw;
+
+ ret = clk_hw_register(NULL, hw);
+ if (ret) {
+ pr_err("%s: failed to register pll %s %d\n", __func__, name, ret);
+ kfree(pll);
+ return ERR_PTR(ret);
+ }
+
+ return hw;
+}
+EXPORT_SYMBOL_GPL(imx_clk_fracn_gppll);
diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
index 63eb7c53b123..a7cbbcd1a3f4 100644
--- a/drivers/clk/imx/clk.h
+++ b/drivers/clk/imx/clk.h
@@ -72,6 +72,27 @@ extern struct imx_pll14xx_clk imx_1416x_pll;
extern struct imx_pll14xx_clk imx_1443x_pll;
extern struct imx_pll14xx_clk imx_1443x_dram_pll;
+/* NOTE: Rate table should be kept sorted in descending order. */
+struct imx_fracn_gppll_rate_table {
+ unsigned int rate;
+ unsigned int mfi;
+ unsigned int mfn;
+ unsigned int mfd;
+ unsigned int rdiv;
+ unsigned int odiv;
+};
+
+struct imx_fracn_gppll_clk {
+ const struct imx_fracn_gppll_rate_table *rate_table;
+ int rate_count;
+ int flags;
+};
+
+struct clk_hw *imx_clk_fracn_gppll(const char *name, const char *parent_name, void __iomem *base,
+ const struct imx_fracn_gppll_clk *pll_clk);
+
+extern struct imx_fracn_gppll_clk imx_fracn_gppll;
+
#define imx_clk_cpu(name, parent_name, div, mux, pll, step) \
to_clk(imx_clk_hw_cpu(name, parent_name, div, mux, pll, step))
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH V4 5/5] clk: imx: add i.MX93 clk
2022-02-24 8:22 [PATCH V4 0/5] mx: add i.MX93 clk bindings and driver Peng Fan (OSS)
` (3 preceding siblings ...)
2022-02-24 8:22 ` [PATCH V4 4/5] clk: imx: support fracn gppll Peng Fan (OSS)
@ 2022-02-24 8:22 ` Peng Fan (OSS)
4 siblings, 0 replies; 10+ messages in thread
From: Peng Fan (OSS) @ 2022-02-24 8:22 UTC (permalink / raw)
To: sboyd, robh+dt, shawnguo, s.hauer, abel.vesa
Cc: kernel, festevam, linux-imx, linux-clk, devicetree,
linux-arm-kernel, linux-kernel, Peng Fan
From: Peng Fan <peng.fan@nxp.com>
Add i.MX93 clk driver. i.MX93 clk hardware design is different compared
with i.MX8M. It supports 4 sources for each clk root and the sources
are separated into a few groups, low speed/fast io/audio and etc.
Reviewed-by: Abel Vesa <abel.vesa@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
drivers/clk/imx/Kconfig | 6 +
drivers/clk/imx/Makefile | 2 +
drivers/clk/imx/clk-imx93.c | 338 ++++++++++++++++++++++++++++++++++++
3 files changed, 346 insertions(+)
create mode 100644 drivers/clk/imx/clk-imx93.c
diff --git a/drivers/clk/imx/Kconfig b/drivers/clk/imx/Kconfig
index 45641b8bdc50..cc464a42d646 100644
--- a/drivers/clk/imx/Kconfig
+++ b/drivers/clk/imx/Kconfig
@@ -106,6 +106,12 @@ config CLK_IMX8ULP
help
Build the driver for i.MX8ULP CCM Clock Driver
+config CLK_IMX93
+ tristate "IMX93 CCM Clock Driver"
+ depends on ARCH_MXC || COMPILE_TEST
+ help
+ Build the driver for i.MX93 CCM Clock Driver
+
config CLK_IMXRT1050
tristate "IMXRT1050 CCM Clock Driver"
depends on SOC_IMXRT
diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile
index 60c8a4bb7574..88b9b9285d22 100644
--- a/drivers/clk/imx/Makefile
+++ b/drivers/clk/imx/Makefile
@@ -28,6 +28,8 @@ obj-$(CONFIG_CLK_IMX8MN) += clk-imx8mn.o
obj-$(CONFIG_CLK_IMX8MP) += clk-imx8mp.o
obj-$(CONFIG_CLK_IMX8MQ) += clk-imx8mq.o
+obj-$(CONFIG_CLK_IMX93) += clk-imx93.o
+
obj-$(CONFIG_MXC_CLK_SCU) += clk-imx-scu.o clk-imx-lpcg-scu.o
clk-imx-scu-$(CONFIG_CLK_IMX8QXP) += clk-scu.o clk-imx8qxp.o \
clk-imx8qxp-rsrc.o clk-imx8qm-rsrc.o \
diff --git a/drivers/clk/imx/clk-imx93.c b/drivers/clk/imx/clk-imx93.c
new file mode 100644
index 000000000000..7cd5e7fb0c8b
--- /dev/null
+++ b/drivers/clk/imx/clk-imx93.c
@@ -0,0 +1,338 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2021 NXP.
+ */
+
+#include <dt-bindings/clock/imx93-clock.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/debugfs.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#include "clk.h"
+
+enum clk_sel {
+ LOW_SPEED_IO_SEL,
+ NON_IO_SEL,
+ FAST_SEL,
+ AUDIO_SEL,
+ VIDEO_SEL,
+ TPM_SEL,
+ CKO1_SEL,
+ CKO2_SEL,
+ MISC_SEL,
+ MAX_SEL
+};
+
+static const char *parent_names[MAX_SEL][4] = {
+ {"osc_24m", "sys_pll_pfd0_div2", "sys_pll_pfd1_div2", "video_pll"},
+ {"osc_24m", "sys_pll_pfd0_div2", "sys_pll_pfd1_div2", "sys_pll_pfd2_div2"},
+ {"osc_24m", "sys_pll_pfd0", "sys_pll_pfd1", "sys_pll_pfd2"},
+ {"osc_24m", "audio_pll", "video_pll", "clk_ext1"},
+ {"osc_24m", "audio_pll", "video_pll", "sys_pll_pfd0"},
+ {"osc_24m", "sys_pll_pfd0", "audio_pll", "clk_ext1"},
+ {"osc_24m", "sys_pll_pfd0", "sys_pll_pfd1", "audio_pll"},
+ {"osc_24m", "sys_pll_pfd0", "sys_pll_pfd1", "video_pll"},
+ {"osc_24m", "audio_pll", "video_pll", "sys_pll_pfd2"},
+};
+
+struct imx93_clk_root {
+ u32 clk;
+ char *name;
+ u32 off;
+ enum clk_sel sel;
+ unsigned long flags;
+} root_array[] = {
+ { IMX93_CLK_A55_PERIPH, "a55_periph_root", 0x0000, FAST_SEL, CLK_IS_CRITICAL },
+ { IMX93_CLK_A55_MTR_BUS, "a55_mtr_bus_root", 0x0080, LOW_SPEED_IO_SEL, CLK_IS_CRITICAL },
+ { IMX93_CLK_A55, "a55_root", 0x0100, FAST_SEL, CLK_IS_CRITICAL },
+ { IMX93_CLK_M33, "m33_root", 0x0180, LOW_SPEED_IO_SEL, CLK_IS_CRITICAL },
+ { IMX93_CLK_BUS_WAKEUP, "bus_wakeup_root", 0x0280, LOW_SPEED_IO_SEL, CLK_IS_CRITICAL },
+ { IMX93_CLK_BUS_AON, "bus_aon_root", 0x0300, LOW_SPEED_IO_SEL, CLK_IS_CRITICAL },
+ { IMX93_CLK_WAKEUP_AXI, "wakeup_axi_root", 0x0380, FAST_SEL, CLK_IS_CRITICAL },
+ { IMX93_CLK_SWO_TRACE, "swo_trace_root", 0x0400, LOW_SPEED_IO_SEL, },
+ { IMX93_CLK_M33_SYSTICK, "m33_systick_root", 0x0480, LOW_SPEED_IO_SEL, },
+ { IMX93_CLK_FLEXIO1, "flexio1_root", 0x0500, LOW_SPEED_IO_SEL, },
+ { IMX93_CLK_FLEXIO2, "flexio2_root", 0x0580, LOW_SPEED_IO_SEL, },
+ { IMX93_CLK_LPIT1, "lpit1_root", 0x0600, LOW_SPEED_IO_SEL, },
+ { IMX93_CLK_LPIT2, "lpit2_root", 0x0680, LOW_SPEED_IO_SEL, },
+ { IMX93_CLK_LPTMR1, "lptmr1_root", 0x0700, LOW_SPEED_IO_SEL, },
+ { IMX93_CLK_LPTMR2, "lptmr2_root", 0x0780, LOW_SPEED_IO_SEL, },
+ { IMX93_CLK_TPM1, "tpm1_root", 0x0800, TPM_SEL, },
+ { IMX93_CLK_TPM2, "tpm2_root", 0x0880, TPM_SEL, },
+ { IMX93_CLK_TPM3, "tpm3_root", 0x0900, TPM_SEL, },
+ { IMX93_CLK_TPM4, "tpm4_root", 0x0980, TPM_SEL, },
+ { IMX93_CLK_TPM5, "tpm5_root", 0x0a00, TPM_SEL, },
+ { IMX93_CLK_TPM6, "tpm6_root", 0x0a80, TPM_SEL, },
+ { IMX93_CLK_FLEXSPI1, "flexspi1_root", 0x0b00, FAST_SEL, },
+ { IMX93_CLK_CAN1, "can1_root", 0x0b80, LOW_SPEED_IO_SEL, },
+ { IMX93_CLK_CAN2, "can2_root", 0x0c00, LOW_SPEED_IO_SEL, },
+ { IMX93_CLK_LPUART1, "lpuart1_root", 0x0c80, LOW_SPEED_IO_SEL, },
+ { IMX93_CLK_LPUART2, "lpuart2_root", 0x0d00, LOW_SPEED_IO_SEL, },
+ { IMX93_CLK_LPUART3, "lpuart3_root", 0x0d80, LOW_SPEED_IO_SEL, },
+ { IMX93_CLK_LPUART4, "lpuart4_root", 0x0e00, LOW_SPEED_IO_SEL, },
+ { IMX93_CLK_LPUART5, "lpuart5_root", 0x0e80, LOW_SPEED_IO_SEL, },
+ { IMX93_CLK_LPUART6, "lpuart6_root", 0x0f00, LOW_SPEED_IO_SEL, },
+ { IMX93_CLK_LPUART7, "lpuart7_root", 0x0f80, LOW_SPEED_IO_SEL, },
+ { IMX93_CLK_LPUART8, "lpuart8_root", 0x1000, LOW_SPEED_IO_SEL, },
+ { IMX93_CLK_LPI2C1, "lpi2c1_root", 0x1080, LOW_SPEED_IO_SEL, },
+ { IMX93_CLK_LPI2C2, "lpi2c2_root", 0x1100, LOW_SPEED_IO_SEL, },
+ { IMX93_CLK_LPI2C3, "lpi2c3_root", 0x1180, LOW_SPEED_IO_SEL, },
+ { IMX93_CLK_LPI2C4, "lpi2c4_root", 0x1200, LOW_SPEED_IO_SEL, },
+ { IMX93_CLK_LPI2C5, "lpi2c5_root", 0x1280, LOW_SPEED_IO_SEL, },
+ { IMX93_CLK_LPI2C6, "lpi2c6_root", 0x1300, LOW_SPEED_IO_SEL, },
+ { IMX93_CLK_LPI2C7, "lpi2c7_root", 0x1380, LOW_SPEED_IO_SEL, },
+ { IMX93_CLK_LPI2C8, "lpi2c8_root", 0x1400, LOW_SPEED_IO_SEL, },
+ { IMX93_CLK_LPSPI1, "lpspi1_root", 0x1480, LOW_SPEED_IO_SEL, },
+ { IMX93_CLK_LPSPI2, "lpspi2_root", 0x1500, LOW_SPEED_IO_SEL, },
+ { IMX93_CLK_LPSPI3, "lpspi3_root", 0x1580, LOW_SPEED_IO_SEL, },
+ { IMX93_CLK_LPSPI4, "lpspi4_root", 0x1600, LOW_SPEED_IO_SEL, },
+ { IMX93_CLK_LPSPI5, "lpspi5_root", 0x1680, LOW_SPEED_IO_SEL, },
+ { IMX93_CLK_LPSPI6, "lpspi6_root", 0x1700, LOW_SPEED_IO_SEL, },
+ { IMX93_CLK_LPSPI7, "lpspi7_root", 0x1780, LOW_SPEED_IO_SEL, },
+ { IMX93_CLK_LPSPI8, "lpspi8_root", 0x1800, LOW_SPEED_IO_SEL, },
+ { IMX93_CLK_I3C1, "i3c1_root", 0x1880, LOW_SPEED_IO_SEL, },
+ { IMX93_CLK_I3C2, "i3c2_root", 0x1900, LOW_SPEED_IO_SEL, },
+ { IMX93_CLK_USDHC1, "usdhc1_root", 0x1980, FAST_SEL, },
+ { IMX93_CLK_USDHC2, "usdhc2_root", 0x1a00, FAST_SEL, },
+ { IMX93_CLK_USDHC3, "usdhc3_root", 0x1a80, FAST_SEL, },
+ { IMX93_CLK_SAI1, "sai1_root", 0x1b00, AUDIO_SEL, },
+ { IMX93_CLK_SAI2, "sai2_root", 0x1b80, AUDIO_SEL, },
+ { IMX93_CLK_SAI3, "sai3_root", 0x1c00, AUDIO_SEL, },
+ { IMX93_CLK_CCM_CKO1, "ccm_cko1_root", 0x1c80, CKO1_SEL, },
+ { IMX93_CLK_CCM_CKO2, "ccm_cko2_root", 0x1d00, CKO2_SEL, },
+ { IMX93_CLK_CCM_CKO3, "ccm_cko3_root", 0x1d80, CKO1_SEL, },
+ { IMX93_CLK_CCM_CKO4, "ccm_cko4_root", 0x1e00, CKO2_SEL, },
+ { IMX93_CLK_HSIO, "hsio_root", 0x1e80, LOW_SPEED_IO_SEL, },
+ { IMX93_CLK_HSIO_USB_TEST_60M, "hsio_usb_test_60m_root", 0x1f00, LOW_SPEED_IO_SEL, },
+ { IMX93_CLK_HSIO_ACSCAN_80M, "hsio_acscan_80m_root", 0x1f80, LOW_SPEED_IO_SEL, },
+ { IMX93_CLK_HSIO_ACSCAN_480M, "hsio_acscan_480m_root", 0x2000, MISC_SEL, },
+ { IMX93_CLK_ML_APB, "ml_apb_root", 0x2180, LOW_SPEED_IO_SEL, },
+ { IMX93_CLK_ML, "ml_root", 0x2200, FAST_SEL, },
+ { IMX93_CLK_MEDIA_AXI, "media_axi_root", 0x2280, FAST_SEL, },
+ { IMX93_CLK_MEDIA_APB, "media_apb_root", 0x2300, LOW_SPEED_IO_SEL, },
+ { IMX93_CLK_MEDIA_LDB, "media_ldb_root", 0x2380, VIDEO_SEL, },
+ { IMX93_CLK_MEDIA_DISP_PIX, "media_disp_pix_root", 0x2400, VIDEO_SEL, },
+ { IMX93_CLK_CAM_PIX, "cam_pix_root", 0x2480, VIDEO_SEL, },
+ { IMX93_CLK_MIPI_TEST_BYTE, "mipi_test_byte_root", 0x2500, VIDEO_SEL, },
+ { IMX93_CLK_MIPI_PHY_CFG, "mipi_phy_cfg_root", 0x2580, VIDEO_SEL, },
+ { IMX93_CLK_ADC, "adc_root", 0x2700, LOW_SPEED_IO_SEL, },
+ { IMX93_CLK_PDM, "pdm_root", 0x2780, AUDIO_SEL, },
+ { IMX93_CLK_TSTMR1, "tstmr1_root", 0x2800, LOW_SPEED_IO_SEL, },
+ { IMX93_CLK_TSTMR2, "tstmr2_root", 0x2880, LOW_SPEED_IO_SEL, },
+ { IMX93_CLK_MQS1, "mqs1_root", 0x2900, AUDIO_SEL, },
+ { IMX93_CLK_MQS2, "mqs2_root", 0x2980, AUDIO_SEL, },
+ { IMX93_CLK_AUDIO_XCVR, "audio_xcvr_root", 0x2a00, NON_IO_SEL, },
+ { IMX93_CLK_SPDIF, "spdif_root", 0x2a80, AUDIO_SEL, },
+ { IMX93_CLK_ENET, "enet_root", 0x2b00, NON_IO_SEL, },
+ { IMX93_CLK_ENET_TIMER1, "enet_timer1_root", 0x2b80, LOW_SPEED_IO_SEL, },
+ { IMX93_CLK_ENET_TIMER2, "enet_timer2_root", 0x2c00, LOW_SPEED_IO_SEL, },
+ { IMX93_CLK_ENET_REF, "enet_ref_root", 0x2c80, NON_IO_SEL, },
+ { IMX93_CLK_ENET_REF_PHY, "enet_ref_phy_root", 0x2d00, LOW_SPEED_IO_SEL, },
+ { IMX93_CLK_I3C1_SLOW, "i3c1_slow_root", 0x2d80, LOW_SPEED_IO_SEL, },
+ { IMX93_CLK_I3C2_SLOW, "i3c2_slow_root", 0x2e00, LOW_SPEED_IO_SEL, },
+ { IMX93_CLK_USB_PHY_BURUNIN, "usb_phy_root", 0x2e80, LOW_SPEED_IO_SEL, },
+ { IMX93_CLK_PAL_CAME_SCAN, "pal_came_scan_root", 0x2f00, MISC_SEL, }
+};
+
+struct imx93_clk_ccgr {
+ u32 clk;
+ char *name;
+ char *parent_name;
+ u32 off;
+ unsigned long flags;
+} ccgr_array[] = {
+ { IMX93_CLK_A55_GATE, "a55", "a55_root", 0x8000, CLK_IS_CRITICAL },
+ { IMX93_CLK_CM33_GATE, "cm33", "m33_root", 0x8040, CLK_IS_CRITICAL },
+ { IMX93_CLK_ADC1_GATE, "adc1", "osc_24m", 0x82c0, },
+ { IMX93_CLK_WDOG1_GATE, "wdog1", "osc_24m", 0x8300, },
+ { IMX93_CLK_WDOG2_GATE, "wdog2", "osc_24m", 0x8340, },
+ { IMX93_CLK_WDOG3_GATE, "wdog3", "osc_24m", 0x8380, },
+ { IMX93_CLK_WDOG4_GATE, "wdog4", "osc_24m", 0x83c0, },
+ { IMX93_CLK_WDOG5_GATE, "wdog5", "osc_24m", 0x8400, },
+ { IMX93_CLK_SEMA1_GATE, "sema1", "bus_aon_root", 0x8440, },
+ { IMX93_CLK_SEMA2_GATE, "sema2", "bus_wakeup_root", 0x8480, },
+ { IMX93_CLK_MU_A_GATE, "mu_a", "bus_aon_root", 0x84c0, },
+ { IMX93_CLK_MU_B_GATE, "mu_b", "bus_aon_root", 0x8500, },
+ { IMX93_CLK_EDMA1_GATE, "edma1", "wakeup_axi_root", 0x8540, },
+ { IMX93_CLK_EDMA2_GATE, "edma2", "wakeup_axi_root", 0x8580, },
+ { IMX93_CLK_FLEXSPI1_GATE, "flexspi", "flexspi_root", 0x8640, },
+ { IMX93_CLK_GPIO1_GATE, "gpio1", "m33_root", 0x8880, },
+ { IMX93_CLK_GPIO2_GATE, "gpio2", "bus_wakeup_root", 0x88c0, },
+ { IMX93_CLK_GPIO3_GATE, "gpio3", "bus_wakeup_root", 0x8900, },
+ { IMX93_CLK_GPIO4_GATE, "gpio4", "bus_wakeup_root", 0x8940, },
+ { IMX93_CLK_FLEXIO1_GATE, "flexio1", "flexio1_root", 0x8980, },
+ { IMX93_CLK_FLEXIO2_GATE, "flexio2", "flexio2_root", 0x89c0, },
+ { IMX93_CLK_LPIT1_GATE, "lpit1", "lpit1_root", 0x8a00, },
+ { IMX93_CLK_LPIT2_GATE, "lpit2", "lpit2_root", 0x8a40, },
+ { IMX93_CLK_LPTMR1_GATE, "lptmr1", "lptmr1_root", 0x8a80, },
+ { IMX93_CLK_LPTMR2_GATE, "lptmr2", "lptmr2_root", 0x8ac0, },
+ { IMX93_CLK_TPM1_GATE, "tpm1", "tpm1_root", 0x8b00, },
+ { IMX93_CLK_TPM2_GATE, "tpm2", "tpm2_root", 0x8b40, },
+ { IMX93_CLK_TPM3_GATE, "tpm3", "tpm3_root", 0x8b80, },
+ { IMX93_CLK_TPM4_GATE, "tpm4", "tpm4_root", 0x8bc0, },
+ { IMX93_CLK_TPM5_GATE, "tpm5", "tpm5_root", 0x8c00, },
+ { IMX93_CLK_TPM6_GATE, "tpm6", "tpm6_root", 0x8c40, },
+ { IMX93_CLK_CAN1_GATE, "can1", "can1_root", 0x8c80, },
+ { IMX93_CLK_CAN2_GATE, "can2", "can2_root", 0x8cc0, },
+ { IMX93_CLK_LPUART1_GATE, "lpuart1", "lpuart1_root", 0x8d00, },
+ { IMX93_CLK_LPUART2_GATE, "lpuart2", "lpuart2_root", 0x8d40, },
+ { IMX93_CLK_LPUART3_GATE, "lpuart3", "lpuart3_root", 0x8d80, },
+ { IMX93_CLK_LPUART4_GATE, "lpuart4", "lpuart4_root", 0x8dc0, },
+ { IMX93_CLK_LPUART5_GATE, "lpuart5", "lpuart5_root", 0x8e00, },
+ { IMX93_CLK_LPUART6_GATE, "lpuart6", "lpuart6_root", 0x8e40, },
+ { IMX93_CLK_LPUART7_GATE, "lpuart7", "lpuart7_root", 0x8e80, },
+ { IMX93_CLK_LPUART8_GATE, "lpuart8", "lpuart8_root", 0x8ec0, },
+ { IMX93_CLK_LPI2C1_GATE, "lpi2c1", "lpi2c1_root", 0x8f00, },
+ { IMX93_CLK_LPI2C2_GATE, "lpi2c2", "lpi2c2_root", 0x8f40, },
+ { IMX93_CLK_LPI2C3_GATE, "lpi2c3", "lpi2c3_root", 0x8f80, },
+ { IMX93_CLK_LPI2C4_GATE, "lpi2c4", "lpi2c4_root", 0x8fc0, },
+ { IMX93_CLK_LPI2C5_GATE, "lpi2c5", "lpi2c5_root", 0x9000, },
+ { IMX93_CLK_LPI2C6_GATE, "lpi2c6", "lpi2c6_root", 0x9040, },
+ { IMX93_CLK_LPI2C7_GATE, "lpi2c7", "lpi2c7_root", 0x9080, },
+ { IMX93_CLK_LPI2C8_GATE, "lpi2c8", "lpi2c8_root", 0x90c0, },
+ { IMX93_CLK_LPSPI1_GATE, "lpspi1", "lpspi1_root", 0x9100, },
+ { IMX93_CLK_LPSPI2_GATE, "lpspi2", "lpspi2_root", 0x9140, },
+ { IMX93_CLK_LPSPI3_GATE, "lpspi3", "lpspi3_root", 0x9180, },
+ { IMX93_CLK_LPSPI4_GATE, "lpspi4", "lpspi4_root", 0x91c0, },
+ { IMX93_CLK_LPSPI5_GATE, "lpspi5", "lpspi5_root", 0x9200, },
+ { IMX93_CLK_LPSPI6_GATE, "lpspi6", "lpspi6_root", 0x9240, },
+ { IMX93_CLK_LPSPI7_GATE, "lpspi7", "lpspi7_root", 0x9280, },
+ { IMX93_CLK_LPSPI8_GATE, "lpspi8", "lpspi8_root", 0x92c0, },
+ { IMX93_CLK_I3C1_GATE, "i3c1", "i3c1_root", 0x9300, },
+ { IMX93_CLK_I3C2_GATE, "i3c2", "i3c2_root", 0x9340, },
+ { IMX93_CLK_USDHC1_GATE, "usdhc1", "usdhc1_root", 0x9380, },
+ { IMX93_CLK_USDHC2_GATE, "usdhc2", "usdhc2_root", 0x93c0, },
+ { IMX93_CLK_USDHC3_GATE, "usdhc3", "usdhc3_root", 0x9400, },
+ { IMX93_CLK_SAI1_GATE, "sai1", "sai1_root", 0x9440, },
+ { IMX93_CLK_SAI2_GATE, "sai2", "sai2_root", 0x9480, },
+ { IMX93_CLK_SAI3_GATE, "sai3", "sai3_root", 0x94c0, },
+ { IMX93_CLK_MIPI_CSI_GATE, "mipi_csi", "media_apb_root", 0x9580, },
+ { IMX93_CLK_MIPI_DSI_GATE, "mipi_dsi", "media_apb_root", 0x95c0, },
+ { IMX93_CLK_LVDS_GATE, "lvds", "media_ldb_root", 0x9600, },
+ { IMX93_CLK_LCDIF_GATE, "lcdif", "media_apb_root", 0x9640, },
+ { IMX93_CLK_PXP_GATE, "pxp", "media_apb_root", 0x9680, },
+ { IMX93_CLK_ISI_GATE, "isi", "media_apb_root", 0x96c0, },
+ { IMX93_CLK_NIC_MEDIA_GATE, "nic_media", "media_apb_root", 0x9700, },
+ { IMX93_CLK_USB_CONTROLLER_GATE, "usb_controller", "hsio_root", 0x9a00, },
+ { IMX93_CLK_USB_TEST_60M_GATE, "usb_test_60m", "hsio_usb_test_60m_root", 0x9a40, },
+ { IMX93_CLK_HSIO_TROUT_24M_GATE, "hsio_trout_24m", "osc_24m", 0x9a80, },
+ { IMX93_CLK_PDM_GATE, "pdm", "pdm_root", 0x9ac0, },
+ { IMX93_CLK_MQS1_GATE, "mqs1", "sai1_root", 0x9b00, },
+ { IMX93_CLK_MQS2_GATE, "mqs2", "sai3_root", 0x9b40, },
+ { IMX93_CLK_AUD_XCVR_GATE, "aud_xcvr", "audio_xcvr_root", 0x9b80, },
+ { IMX93_CLK_SPDIF_GATE, "spdif", "spdif_root", 0x9c00, },
+ { IMX93_CLK_HSIO_32K_GATE, "hsio_32k", "osc_32k", 0x9dc0, },
+ { IMX93_CLK_ENET1_GATE, "enet1", "enet_root", 0x9e00, },
+ { IMX93_CLK_ENET_QOS_GATE, "enet_qos", "wakeup_axi_root", 0x9e40, },
+ { IMX93_CLK_SYS_CNT_GATE, "sys_cnt", "osc_24m", 0x9e80, },
+ { IMX93_CLK_TSTMR1_GATE, "tstmr1", "bus_aon_root", 0x9ec0, },
+ { IMX93_CLK_TSTMR2_GATE, "tstmr2", "bus_wakeup_root", 0x9f00, },
+ { IMX93_CLK_TMC_GATE, "tmc", "osc_24m", 0x9f40, },
+ { IMX93_CLK_PMRO_GATE, "pmro", "osc_24m", 0x9f80, }
+};
+
+static struct clk_hw_onecell_data *clk_hw_data;
+static struct clk_hw **clks;
+
+static int imx93_clocks_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ struct imx93_clk_root *root;
+ struct imx93_clk_ccgr *ccgr;
+ void __iomem *base = NULL;
+ int i, ret;
+
+ clk_hw_data = kzalloc(struct_size(clk_hw_data, hws,
+ IMX93_CLK_END), GFP_KERNEL);
+ if (WARN_ON(!clk_hw_data))
+ return -ENOMEM;
+
+ clk_hw_data->num = IMX93_CLK_END;
+ clks = clk_hw_data->hws;
+
+ clks[IMX93_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0);
+ clks[IMX93_CLK_24M] = imx_obtain_fixed_clk_hw(np, "osc_24m");
+ clks[IMX93_CLK_32K] = imx_obtain_fixed_clk_hw(np, "osc_32k");
+ clks[IMX93_CLK_EXT1] = imx_obtain_fixed_clk_hw(np, "clk_ext1");
+
+ clks[IMX93_CLK_SYS_PLL_PFD0] = imx_clk_hw_fixed("sys_pll_pfd0", 1000000000);
+ clks[IMX93_CLK_SYS_PLL_PFD0_DIV2] = imx_clk_hw_fixed_factor("sys_pll_pfd0_div2",
+ "sys_pll_pfd0", 1, 2);
+ clks[IMX93_CLK_SYS_PLL_PFD1] = imx_clk_hw_fixed("sys_pll_pfd1", 800000000);
+ clks[IMX93_CLK_SYS_PLL_PFD1_DIV2] = imx_clk_hw_fixed_factor("sys_pll_pfd1_div2",
+ "sys_pll_pfd1", 1, 2);
+ clks[IMX93_CLK_SYS_PLL_PFD2] = imx_clk_hw_fixed("sys_pll_pfd2", 625000000);
+ clks[IMX93_CLK_SYS_PLL_PFD2_DIV2] = imx_clk_hw_fixed_factor("sys_pll_pfd2_div2",
+ "sys_pll_pfd2", 1, 2);
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx93-anatop");
+ base = of_iomap(np, 0);
+ of_node_put(np);
+ if (WARN_ON(!base))
+ return -ENOMEM;
+
+ clks[IMX93_CLK_AUDIO_PLL] = imx_clk_fracn_gppll("audio_pll", "osc_24m", base + 0x1200,
+ &imx_fracn_gppll);
+ clks[IMX93_CLK_VIDEO_PLL] = imx_clk_fracn_gppll("video_pll", "osc_24m", base + 0x1400,
+ &imx_fracn_gppll);
+
+ np = dev->of_node;
+ base = devm_platform_ioremap_resource(pdev, 0);
+ if (WARN_ON(IS_ERR(base)))
+ return PTR_ERR(base);
+
+ for (i = 0; i < ARRAY_SIZE(root_array); i++) {
+ root = &root_array[i];
+ clks[root->clk] = imx93_clk_composite_flags(root->name,
+ parent_names[root->sel],
+ 4, base + root->off,
+ root->flags);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(ccgr_array); i++) {
+ ccgr = &ccgr_array[i];
+ clks[ccgr->clk] = imx_clk_hw_gate4_flags(ccgr->name,
+ ccgr->parent_name,
+ base + ccgr->off, 0,
+ ccgr->flags);
+ }
+
+ imx_check_clk_hws(clks, IMX93_CLK_END);
+
+ ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
+ if (ret < 0) {
+ dev_err(dev, "failed to register clks for i.MX93\n");
+ goto unregister_hws;
+ }
+
+ return 0;
+
+unregister_hws:
+ imx_unregister_hw_clocks(clks, IMX93_CLK_END);
+
+ return ret;
+}
+
+static const struct of_device_id imx93_clk_of_match[] = {
+ { .compatible = "fsl,imx93-ccm" },
+ { /* Sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, imx93_clk_of_match);
+
+static struct platform_driver imx93_clk_driver = {
+ .probe = imx93_clocks_probe,
+ .driver = {
+ .name = "imx93-ccm",
+ .suppress_bind_attrs = true,
+ .of_match_table = of_match_ptr(imx93_clk_of_match),
+ },
+};
+module_platform_driver(imx93_clk_driver);
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH V4 4/5] clk: imx: support fracn gppll
2022-02-24 8:22 ` [PATCH V4 4/5] clk: imx: support fracn gppll Peng Fan (OSS)
@ 2022-02-24 9:58 ` Sascha Hauer
2022-02-24 10:20 ` Peng Fan
0 siblings, 1 reply; 10+ messages in thread
From: Sascha Hauer @ 2022-02-24 9:58 UTC (permalink / raw)
To: Peng Fan (OSS)
Cc: sboyd, robh+dt, shawnguo, abel.vesa, kernel, festevam, linux-imx,
linux-clk, devicetree, linux-arm-kernel, linux-kernel, Peng Fan
On Thu, Feb 24, 2022 at 04:22:50PM +0800, Peng Fan (OSS) wrote:
> From: Peng Fan <peng.fan@nxp.com>
>
> This PLL module is a Fractional-N synthesizer,
> supporting 30-bit numerator and denominator. Numerator is a signed
> number. It has feature to adjust fractional portion of feedback
> divider dynamically. This fracn gppll is used in i.MX93.
>
> Reviewed-by: Abel Vesa <abel.vesa@nxp.com>
> Signed-off-by: Peng Fan <peng.fan@nxp.com>
> ---
> drivers/clk/imx/Makefile | 1 +
> drivers/clk/imx/clk-fracn-gppll.c | 326 ++++++++++++++++++++++++++++++
> drivers/clk/imx/clk.h | 21 ++
> 3 files changed, 348 insertions(+)
> create mode 100644 drivers/clk/imx/clk-fracn-gppll.c
>
> diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile
> index 36c04922d789..60c8a4bb7574 100644
> --- a/drivers/clk/imx/Makefile
> +++ b/drivers/clk/imx/Makefile
> @@ -5,6 +5,7 @@ mxc-clk-objs += clk-busy.o
> mxc-clk-objs += clk-composite-7ulp.o
> mxc-clk-objs += clk-composite-8m.o
> mxc-clk-objs += clk-composite-93.o
> +mxc-clk-objs += clk-fracn-gppll.o
> mxc-clk-objs += clk-cpu.o
> mxc-clk-objs += clk-divider-gate.o
> mxc-clk-objs += clk-fixup-div.o
> diff --git a/drivers/clk/imx/clk-fracn-gppll.c b/drivers/clk/imx/clk-fracn-gppll.c
> new file mode 100644
> index 000000000000..b6add3a2e472
> --- /dev/null
> +++ b/drivers/clk/imx/clk-fracn-gppll.c
> @@ -0,0 +1,326 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright 2021 NXP
> + */
> +
> +#include <asm/div64.h>
> +#include <linux/bitfield.h>
> +#include <linux/clk-provider.h>
> +#include <linux/err.h>
> +#include <linux/export.h>
> +#include <linux/io.h>
> +#include <linux/iopoll.h>
> +#include <linux/slab.h>
> +#include <linux/jiffies.h>
> +
> +#include "clk.h"
> +
> +#define PLL_CTRL 0x0
> +#define CLKMUX_BYPASS BIT(2)
> +#define CLKMUX_EN BIT(1)
> +#define POWERUP_MASK BIT(0)
> +
> +#define PLL_ANA_PRG 0x10
> +#define PLL_SPREAD_SPECTRUM 0x30
> +
> +#define PLL_NUMERATOR 0x40
> +#define PLL_MFN_MASK GENMASK(31, 2)
> +#define PLL_MFN_SHIFT 2
> +
> +#define PLL_DENOMINATOR 0x50
> +#define PLL_MFD_MASK GENMASK(29, 0)
> +
> +#define PLL_DIV 0x60
> +#define PLL_MFI_MASK GENMASK(24, 16)
Is the MFI field really 9 bits wide? Could be, I don't have the
reference manual. It just looks like it could be a one-off.
> +#define PLL_MFI_SHIFT 16
> +#define PLL_RDIV_MASK GENMASK(15, 13)
> +#define PLL_RDIV_SHIFT 13
> +#define PLL_ODIV_MASK GENMASK(7, 0)
The *_SHIFT defines can be removed.
> +static int clk_fracn_gppll_set_rate(struct clk_hw *hw, unsigned long drate,
> + unsigned long prate)
> +{
> + struct clk_fracn_gppll *pll = to_clk_fracn_gppll(hw);
> + const struct imx_fracn_gppll_rate_table *rate;
> + u32 tmp, pll_div, ana_mfn;
> + int ret;
> +
> + rate = imx_get_pll_settings(pll, drate);
> +
> + /* Disable output */
> + tmp = readl_relaxed(pll->base + PLL_CTRL);
> + tmp &= ~CLKMUX_EN;
> + writel_relaxed(tmp, pll->base + PLL_CTRL);
> +
> + /* Power Down */
> + tmp &= ~POWERUP_MASK;
> + writel_relaxed(tmp, pll->base + PLL_CTRL);
> +
> + /* Disable BYPASS */
> + tmp &= ~CLKMUX_BYPASS;
> + writel_relaxed(tmp, pll->base + PLL_CTRL);
> +
> + pll_div = FIELD_PREP(PLL_RDIV_MASK, rate->rdiv) | rate->odiv |
> + FIELD_PREP(PLL_MFI_MASK, rate->mfi);
> + writel_relaxed(pll_div, pll->base + PLL_DIV);
> + writel_relaxed(rate->mfd, pll->base + PLL_DENOMINATOR);
> + writel_relaxed(rate->mfn << PLL_MFN_SHIFT, pll->base + PLL_NUMERATOR);
FIELD_PREP
> +
> + /* Wait for 5us according to fracn mode pll doc */
> + udelay(5);
> +
> + /* Enable Powerup */
> + tmp |= POWERUP_MASK;
> + writel_relaxed(tmp, pll->base + PLL_CTRL);
> +
> + /* Wait Lock */
> + ret = clk_fracn_gppll_wait_lock(pll);
> + if (ret)
> + return ret;
> +
> + /* Enable output */
> + tmp |= CLKMUX_EN;
> + writel_relaxed(tmp, pll->base + PLL_CTRL);
> +
> + ana_mfn = (readl_relaxed(pll->base + PLL_STATUS) & PLL_MFN_MASK) >> PLL_MFN_SHIFT;
FIELD_GET
Sascha
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply [flat|nested] 10+ messages in thread
* RE: [PATCH V4 4/5] clk: imx: support fracn gppll
2022-02-24 9:58 ` Sascha Hauer
@ 2022-02-24 10:20 ` Peng Fan
0 siblings, 0 replies; 10+ messages in thread
From: Peng Fan @ 2022-02-24 10:20 UTC (permalink / raw)
To: Sascha Hauer, Peng Fan (OSS)
Cc: sboyd, robh+dt, shawnguo, Abel Vesa, kernel, festevam,
dl-linux-imx, linux-clk, devicetree, linux-arm-kernel,
linux-kernel
> Subject: Re: [PATCH V4 4/5] clk: imx: support fracn gppll
>
> On Thu, Feb 24, 2022 at 04:22:50PM +0800, Peng Fan (OSS) wrote:
> > From: Peng Fan <peng.fan@nxp.com>
> >
> > This PLL module is a Fractional-N synthesizer, supporting 30-bit
> > numerator and denominator. Numerator is a signed number. It has
> > feature to adjust fractional portion of feedback divider dynamically.
> > This fracn gppll is used in i.MX93.
> >
> > Reviewed-by: Abel Vesa <abel.vesa@nxp.com>
> > Signed-off-by: Peng Fan <peng.fan@nxp.com>
> > ---
> > drivers/clk/imx/Makefile | 1 +
> > drivers/clk/imx/clk-fracn-gppll.c | 326
> ++++++++++++++++++++++++++++++
> > drivers/clk/imx/clk.h | 21 ++
> > 3 files changed, 348 insertions(+)
> > create mode 100644 drivers/clk/imx/clk-fracn-gppll.c
> >
> > diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile index
> > 36c04922d789..60c8a4bb7574 100644
> > --- a/drivers/clk/imx/Makefile
> > +++ b/drivers/clk/imx/Makefile
> > @@ -5,6 +5,7 @@ mxc-clk-objs += clk-busy.o mxc-clk-objs +=
> > clk-composite-7ulp.o mxc-clk-objs += clk-composite-8m.o mxc-clk-objs
> > += clk-composite-93.o
> > +mxc-clk-objs += clk-fracn-gppll.o
> > mxc-clk-objs += clk-cpu.o
> > mxc-clk-objs += clk-divider-gate.o
> > mxc-clk-objs += clk-fixup-div.o
> > diff --git a/drivers/clk/imx/clk-fracn-gppll.c
> > b/drivers/clk/imx/clk-fracn-gppll.c
> > new file mode 100644
> > index 000000000000..b6add3a2e472
> > --- /dev/null
> > +++ b/drivers/clk/imx/clk-fracn-gppll.c
> > @@ -0,0 +1,326 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright 2021 NXP
> > + */
> > +
> > +#include <asm/div64.h>
> > +#include <linux/bitfield.h>
> > +#include <linux/clk-provider.h>
> > +#include <linux/err.h>
> > +#include <linux/export.h>
> > +#include <linux/io.h>
> > +#include <linux/iopoll.h>
> > +#include <linux/slab.h>
> > +#include <linux/jiffies.h>
> > +
> > +#include "clk.h"
> > +
> > +#define PLL_CTRL 0x0
> > +#define CLKMUX_BYPASS BIT(2)
> > +#define CLKMUX_EN BIT(1)
> > +#define POWERUP_MASK BIT(0)
> > +
> > +#define PLL_ANA_PRG 0x10
> > +#define PLL_SPREAD_SPECTRUM 0x30
> > +
> > +#define PLL_NUMERATOR 0x40
> > +#define PLL_MFN_MASK GENMASK(31, 2)
> > +#define PLL_MFN_SHIFT 2
> > +
> > +#define PLL_DENOMINATOR 0x50
> > +#define PLL_MFD_MASK GENMASK(29, 0)
> > +
> > +#define PLL_DIV 0x60
> > +#define PLL_MFI_MASK GENMASK(24, 16)
>
> Is the MFI field really 9 bits wide? Could be, I don't have the reference manual.
> It just looks like it could be a one-off.
Yes, 9 bits wide. MFI: 24-16
Integer portion of loop divider
Sets the value of the divider in the PLL feedback loop, and the value specified establishes the
multiplication factor applied to the reference frequency. Divider value = MFI, where the chosen MFI does
not violate VCO frequency specifications.
>
> > +#define PLL_MFI_SHIFT 16
> > +#define PLL_RDIV_MASK GENMASK(15, 13)
> > +#define PLL_RDIV_SHIFT 13
> > +#define PLL_ODIV_MASK GENMASK(7, 0)
>
> The *_SHIFT defines can be removed.
ok
>
> > +static int clk_fracn_gppll_set_rate(struct clk_hw *hw, unsigned long drate,
> > + unsigned long prate)
> > +{
> > + struct clk_fracn_gppll *pll = to_clk_fracn_gppll(hw);
> > + const struct imx_fracn_gppll_rate_table *rate;
> > + u32 tmp, pll_div, ana_mfn;
> > + int ret;
> > +
> > + rate = imx_get_pll_settings(pll, drate);
> > +
> > + /* Disable output */
> > + tmp = readl_relaxed(pll->base + PLL_CTRL);
> > + tmp &= ~CLKMUX_EN;
> > + writel_relaxed(tmp, pll->base + PLL_CTRL);
> > +
> > + /* Power Down */
> > + tmp &= ~POWERUP_MASK;
> > + writel_relaxed(tmp, pll->base + PLL_CTRL);
> > +
> > + /* Disable BYPASS */
> > + tmp &= ~CLKMUX_BYPASS;
> > + writel_relaxed(tmp, pll->base + PLL_CTRL);
> > +
> > + pll_div = FIELD_PREP(PLL_RDIV_MASK, rate->rdiv) | rate->odiv |
> > + FIELD_PREP(PLL_MFI_MASK, rate->mfi);
> > + writel_relaxed(pll_div, pll->base + PLL_DIV);
> > + writel_relaxed(rate->mfd, pll->base + PLL_DENOMINATOR);
> > + writel_relaxed(rate->mfn << PLL_MFN_SHIFT, pll->base +
> > +PLL_NUMERATOR);
>
> FIELD_PREP
Fix in V5.
>
> > +
> > + /* Wait for 5us according to fracn mode pll doc */
> > + udelay(5);
> > +
> > + /* Enable Powerup */
> > + tmp |= POWERUP_MASK;
> > + writel_relaxed(tmp, pll->base + PLL_CTRL);
> > +
> > + /* Wait Lock */
> > + ret = clk_fracn_gppll_wait_lock(pll);
> > + if (ret)
> > + return ret;
> > +
> > + /* Enable output */
> > + tmp |= CLKMUX_EN;
> > + writel_relaxed(tmp, pll->base + PLL_CTRL);
> > +
> > + ana_mfn = (readl_relaxed(pll->base + PLL_STATUS) &
> PLL_MFN_MASK) >>
> > +PLL_MFN_SHIFT;
>
> FIELD_GET
Fix in V5.
Thanks,
Peng.
>
> Sascha
>
> --
> Pengutronix e.K. |
> |
> Steuerwalder Str. 21 |
> https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.p
> engutronix.de%2F&data=04%7C01%7Cpeng.fan%40nxp.com%7C4dc747
> 31b1f34e99946108d9f77c488f%7C686ea1d3bc2b4c6fa92cd99c5c301635%7
> C0%7C0%7C637812935432676998%7CUnknown%7CTWFpbGZsb3d8eyJWIjoi
> MC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C30
> 00&sdata=0MkuXWdHlLdazu63dgaTlqJdf1RJKwZcSeI2dnE0Uho%3D&am
> p;reserved=0 |
> 31137 Hildesheim, Germany | Phone:
> +49-5121-206917-0 |
> Amtsgericht Hildesheim, HRA 2686 | Fax:
> +49-5121-206917-5555 |
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH V4 1/5] dt-bindings: clock: Add imx93 clock support
2022-02-24 8:22 ` [PATCH V4 1/5] dt-bindings: clock: Add imx93 clock support Peng Fan (OSS)
@ 2022-02-24 19:23 ` Rob Herring
0 siblings, 0 replies; 10+ messages in thread
From: Rob Herring @ 2022-02-24 19:23 UTC (permalink / raw)
To: Peng Fan (OSS)
Cc: kernel, shawnguo, linux-clk, devicetree, festevam, Peng Fan,
robh+dt, s.hauer, linux-arm-kernel, linux-kernel, abel.vesa,
linux-imx, sboyd
On Thu, 24 Feb 2022 16:22:47 +0800, Peng Fan (OSS) wrote:
> From: Peng Fan <peng.fan@nxp.com>
>
> Add the clock dt-binding file for i.MX93.
>
> Reviewed-by: Abel Vesa <abel.vesa@nxp.com>
> Signed-off-by: Peng Fan <peng.fan@nxp.com>
> ---
> .../bindings/clock/imx93-clock.yaml | 62 +++++++++++++++++++
> 1 file changed, 62 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/clock/imx93-clock.yaml
>
Reviewed-by: Rob Herring <robh@kernel.org>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH V4 2/5] dt-bindings: clock: add i.MX93 clock definition
2022-02-24 8:22 ` [PATCH V4 2/5] dt-bindings: clock: add i.MX93 clock definition Peng Fan (OSS)
@ 2022-02-24 19:24 ` Rob Herring
0 siblings, 0 replies; 10+ messages in thread
From: Rob Herring @ 2022-02-24 19:24 UTC (permalink / raw)
To: Peng Fan (OSS)
Cc: kernel, robh+dt, linux-arm-kernel, devicetree, sboyd, abel.vesa,
Peng Fan, linux-clk, linux-imx, linux-kernel, festevam,
Krzysztof Kozlowski, s.hauer, shawnguo
On Thu, 24 Feb 2022 16:22:48 +0800, Peng Fan (OSS) wrote:
> From: Peng Fan <peng.fan@nxp.com>
>
> Add i.MX93 clock definition
>
> Reviewed-by: Abel Vesa <abel.vesa@nxp.com>
> Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
> Signed-off-by: Peng Fan <peng.fan@nxp.com>
> ---
> include/dt-bindings/clock/imx93-clock.h | 201 ++++++++++++++++++++++++
> 1 file changed, 201 insertions(+)
> create mode 100644 include/dt-bindings/clock/imx93-clock.h
>
Acked-by: Rob Herring <robh@kernel.org>
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2022-02-24 19:24 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-02-24 8:22 [PATCH V4 0/5] mx: add i.MX93 clk bindings and driver Peng Fan (OSS)
2022-02-24 8:22 ` [PATCH V4 1/5] dt-bindings: clock: Add imx93 clock support Peng Fan (OSS)
2022-02-24 19:23 ` Rob Herring
2022-02-24 8:22 ` [PATCH V4 2/5] dt-bindings: clock: add i.MX93 clock definition Peng Fan (OSS)
2022-02-24 19:24 ` Rob Herring
2022-02-24 8:22 ` [PATCH V4 3/5] clk: imx: add i.MX93 composite clk Peng Fan (OSS)
2022-02-24 8:22 ` [PATCH V4 4/5] clk: imx: support fracn gppll Peng Fan (OSS)
2022-02-24 9:58 ` Sascha Hauer
2022-02-24 10:20 ` Peng Fan
2022-02-24 8:22 ` [PATCH V4 5/5] clk: imx: add i.MX93 clk Peng Fan (OSS)
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).