diff options
148 files changed, 7732 insertions, 3216 deletions
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt index f3cef1a6d95c..07c9d813465c 100644 --- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt | |||
@@ -10,6 +10,7 @@ Required Properties: | |||
10 | - "mediatek,mt7622-audsys", "syscon" | 10 | - "mediatek,mt7622-audsys", "syscon" |
11 | - "mediatek,mt7623-audsys", "mediatek,mt2701-audsys", "syscon" | 11 | - "mediatek,mt7623-audsys", "mediatek,mt2701-audsys", "syscon" |
12 | - "mediatek,mt8183-audiosys", "syscon" | 12 | - "mediatek,mt8183-audiosys", "syscon" |
13 | - "mediatek,mt8516-audsys", "syscon" | ||
13 | - #clock-cells: Must be 1 | 14 | - #clock-cells: Must be 1 |
14 | 15 | ||
15 | The AUDSYS controller uses the common clk binding from | 16 | The AUDSYS controller uses the common clk binding from |
diff --git a/Documentation/devicetree/bindings/clock/allwinner,sun4i-a10-ccu.yaml b/Documentation/devicetree/bindings/clock/allwinner,sun4i-a10-ccu.yaml new file mode 100644 index 000000000000..c935405458fe --- /dev/null +++ b/Documentation/devicetree/bindings/clock/allwinner,sun4i-a10-ccu.yaml | |||
@@ -0,0 +1,141 @@ | |||
1 | # SPDX-License-Identifier: GPL-2.0 | ||
2 | %YAML 1.2 | ||
3 | --- | ||
4 | $id: http://devicetree.org/schemas/phy/allwinner,sun4i-a10-ccu.yaml# | ||
5 | $schema: http://devicetree.org/meta-schemas/core.yaml# | ||
6 | |||
7 | title: Allwinner Clock Control Unit Device Tree Bindings | ||
8 | |||
9 | maintainers: | ||
10 | - Chen-Yu Tsai <wens@csie.org> | ||
11 | - Maxime Ripard <maxime.ripard@bootlin.com> | ||
12 | |||
13 | properties: | ||
14 | "#clock-cells": | ||
15 | const: 1 | ||
16 | |||
17 | "#reset-cells": | ||
18 | const: 1 | ||
19 | |||
20 | compatible: | ||
21 | enum: | ||
22 | - allwinner,sun4i-a10-ccu | ||
23 | - allwinner,sun5i-a10s-ccu | ||
24 | - allwinner,sun5i-a13-ccu | ||
25 | - allwinner,sun6i-a31-ccu | ||
26 | - allwinner,sun7i-a20-ccu | ||
27 | - allwinner,sun8i-a23-ccu | ||
28 | - allwinner,sun8i-a33-ccu | ||
29 | - allwinner,sun8i-a83t-ccu | ||
30 | - allwinner,sun8i-a83t-r-ccu | ||
31 | - allwinner,sun8i-h3-ccu | ||
32 | - allwinner,sun8i-h3-r-ccu | ||
33 | - allwinner,sun8i-r40-ccu | ||
34 | - allwinner,sun8i-v3s-ccu | ||
35 | - allwinner,sun9i-a80-ccu | ||
36 | - allwinner,sun50i-a64-ccu | ||
37 | - allwinner,sun50i-a64-r-ccu | ||
38 | - allwinner,sun50i-h5-ccu | ||
39 | - allwinner,sun50i-h6-ccu | ||
40 | - allwinner,sun50i-h6-r-ccu | ||
41 | - allwinner,suniv-f1c100s-ccu | ||
42 | - nextthing,gr8-ccu | ||
43 | |||
44 | reg: | ||
45 | maxItems: 1 | ||
46 | |||
47 | clocks: | ||
48 | minItems: 2 | ||
49 | maxItems: 4 | ||
50 | items: | ||
51 | - description: High Frequency Oscillator (usually at 24MHz) | ||
52 | - description: Low Frequency Oscillator (usually at 32kHz) | ||
53 | - description: Internal Oscillator | ||
54 | - description: Peripherals PLL | ||
55 | |||
56 | clock-names: | ||
57 | minItems: 2 | ||
58 | maxItems: 4 | ||
59 | items: | ||
60 | - const: hosc | ||
61 | - const: losc | ||
62 | - const: iosc | ||
63 | - const: pll-periph | ||
64 | |||
65 | required: | ||
66 | - "#clock-cells" | ||
67 | - "#reset-cells" | ||
68 | - compatible | ||
69 | - reg | ||
70 | - clocks | ||
71 | - clock-names | ||
72 | |||
73 | if: | ||
74 | properties: | ||
75 | compatible: | ||
76 | enum: | ||
77 | - allwinner,sun8i-a83t-r-ccu | ||
78 | - allwinner,sun8i-h3-r-ccu | ||
79 | - allwinner,sun50i-a64-r-ccu | ||
80 | - allwinner,sun50i-h6-r-ccu | ||
81 | |||
82 | then: | ||
83 | properties: | ||
84 | clocks: | ||
85 | minItems: 4 | ||
86 | maxItems: 4 | ||
87 | |||
88 | clock-names: | ||
89 | minItems: 4 | ||
90 | maxItems: 4 | ||
91 | |||
92 | else: | ||
93 | if: | ||
94 | properties: | ||
95 | compatible: | ||
96 | const: allwinner,sun50i-h6-ccu | ||
97 | |||
98 | then: | ||
99 | properties: | ||
100 | clocks: | ||
101 | minItems: 3 | ||
102 | maxItems: 3 | ||
103 | |||
104 | clock-names: | ||
105 | minItems: 3 | ||
106 | maxItems: 3 | ||
107 | |||
108 | else: | ||
109 | properties: | ||
110 | clocks: | ||
111 | minItems: 2 | ||
112 | maxItems: 2 | ||
113 | |||
114 | clock-names: | ||
115 | minItems: 2 | ||
116 | maxItems: 2 | ||
117 | |||
118 | additionalProperties: false | ||
119 | |||
120 | examples: | ||
121 | - | | ||
122 | ccu: clock@1c20000 { | ||
123 | compatible = "allwinner,sun8i-h3-ccu"; | ||
124 | reg = <0x01c20000 0x400>; | ||
125 | clocks = <&osc24M>, <&osc32k>; | ||
126 | clock-names = "hosc", "losc"; | ||
127 | #clock-cells = <1>; | ||
128 | #reset-cells = <1>; | ||
129 | }; | ||
130 | |||
131 | - | | ||
132 | r_ccu: clock@1f01400 { | ||
133 | compatible = "allwinner,sun50i-a64-r-ccu"; | ||
134 | reg = <0x01f01400 0x100>; | ||
135 | clocks = <&osc24M>, <&osc32k>, <&iosc>, <&ccu 11>; | ||
136 | clock-names = "hosc", "losc", "iosc", "pll-periph"; | ||
137 | #clock-cells = <1>; | ||
138 | #reset-cells = <1>; | ||
139 | }; | ||
140 | |||
141 | ... | ||
diff --git a/Documentation/devicetree/bindings/clock/amlogic,gxbb-clkc.txt b/Documentation/devicetree/bindings/clock/amlogic,gxbb-clkc.txt index 5c8b105be4d6..6eaa52092313 100644 --- a/Documentation/devicetree/bindings/clock/amlogic,gxbb-clkc.txt +++ b/Documentation/devicetree/bindings/clock/amlogic,gxbb-clkc.txt | |||
@@ -10,6 +10,7 @@ Required Properties: | |||
10 | "amlogic,gxl-clkc" for GXL and GXM SoC, | 10 | "amlogic,gxl-clkc" for GXL and GXM SoC, |
11 | "amlogic,axg-clkc" for AXG SoC. | 11 | "amlogic,axg-clkc" for AXG SoC. |
12 | "amlogic,g12a-clkc" for G12A SoC. | 12 | "amlogic,g12a-clkc" for G12A SoC. |
13 | "amlogic,g12b-clkc" for G12B SoC. | ||
13 | - clocks : list of clock phandle, one for each entry clock-names. | 14 | - clocks : list of clock phandle, one for each entry clock-names. |
14 | - clock-names : should contain the following: | 15 | - clock-names : should contain the following: |
15 | * "xtal": the platform xtal | 16 | * "xtal": the platform xtal |
diff --git a/Documentation/devicetree/bindings/clock/at91-clock.txt b/Documentation/devicetree/bindings/clock/at91-clock.txt index b520280e33ff..13f45db3b66d 100644 --- a/Documentation/devicetree/bindings/clock/at91-clock.txt +++ b/Documentation/devicetree/bindings/clock/at91-clock.txt | |||
@@ -9,10 +9,11 @@ Slow Clock controller: | |||
9 | Required properties: | 9 | Required properties: |
10 | - compatible : shall be one of the following: | 10 | - compatible : shall be one of the following: |
11 | "atmel,at91sam9x5-sckc", | 11 | "atmel,at91sam9x5-sckc", |
12 | "atmel,sama5d3-sckc" or | 12 | "atmel,sama5d3-sckc", |
13 | "atmel,sama5d4-sckc": | 13 | "atmel,sama5d4-sckc" or |
14 | "microchip,sam9x60-sckc": | ||
14 | at91 SCKC (Slow Clock Controller) | 15 | at91 SCKC (Slow Clock Controller) |
15 | - #clock-cells : shall be 0. | 16 | - #clock-cells : shall be 1 for "microchip,sam9x60-sckc" otherwise shall be 0. |
16 | - clocks : shall be the input parent clock phandle for the clock. | 17 | - clocks : shall be the input parent clock phandle for the clock. |
17 | 18 | ||
18 | Optional properties: | 19 | Optional properties: |
diff --git a/Documentation/devicetree/bindings/clock/brcm,bcm63xx-clocks.txt b/Documentation/devicetree/bindings/clock/brcm,bcm63xx-clocks.txt new file mode 100644 index 000000000000..3041657e2f96 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/brcm,bcm63xx-clocks.txt | |||
@@ -0,0 +1,22 @@ | |||
1 | Gated Clock Controller Bindings for MIPS based BCM63XX SoCs | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: must be one of: | ||
5 | "brcm,bcm3368-clocks" | ||
6 | "brcm,bcm6328-clocks" | ||
7 | "brcm,bcm6358-clocks" | ||
8 | "brcm,bcm6362-clocks" | ||
9 | "brcm,bcm6368-clocks" | ||
10 | "brcm,bcm63268-clocks" | ||
11 | |||
12 | - reg: Address and length of the register set | ||
13 | - #clock-cells: must be <1> | ||
14 | |||
15 | |||
16 | Example: | ||
17 | |||
18 | clkctl: clock-controller@10000004 { | ||
19 | compatible = "brcm,bcm6328-clocks"; | ||
20 | reg = <0x10000004 0x4>; | ||
21 | #clock-cells = <1>; | ||
22 | }; | ||
diff --git a/Documentation/devicetree/bindings/clock/cirrus,lochnagar.txt b/Documentation/devicetree/bindings/clock/cirrus,lochnagar.txt index b8d8ef3bdc5f..52a064c789ee 100644 --- a/Documentation/devicetree/bindings/clock/cirrus,lochnagar.txt +++ b/Documentation/devicetree/bindings/clock/cirrus,lochnagar.txt | |||
@@ -40,6 +40,7 @@ Optional properties: | |||
40 | input audio clocks from host system. | 40 | input audio clocks from host system. |
41 | - ln-psia1-mclk, ln-psia2-mclk : Optional input audio clocks from | 41 | - ln-psia1-mclk, ln-psia2-mclk : Optional input audio clocks from |
42 | external connector. | 42 | external connector. |
43 | - ln-spdif-mclk : Optional input audio clock from SPDIF. | ||
43 | - ln-spdif-clkout : Optional input audio clock from SPDIF. | 44 | - ln-spdif-clkout : Optional input audio clock from SPDIF. |
44 | - ln-adat-mclk : Optional input audio clock from ADAT. | 45 | - ln-adat-mclk : Optional input audio clock from ADAT. |
45 | - ln-pmic-32k : On board fixed clock. | 46 | - ln-pmic-32k : On board fixed clock. |
diff --git a/Documentation/devicetree/bindings/clock/mvebu-core-clock.txt b/Documentation/devicetree/bindings/clock/mvebu-core-clock.txt index 796c260c183d..d8f5c490f893 100644 --- a/Documentation/devicetree/bindings/clock/mvebu-core-clock.txt +++ b/Documentation/devicetree/bindings/clock/mvebu-core-clock.txt | |||
@@ -59,6 +59,7 @@ Required properties: | |||
59 | "marvell,dove-core-clock" - for Dove SoC core clocks | 59 | "marvell,dove-core-clock" - for Dove SoC core clocks |
60 | "marvell,kirkwood-core-clock" - for Kirkwood SoC (except mv88f6180) | 60 | "marvell,kirkwood-core-clock" - for Kirkwood SoC (except mv88f6180) |
61 | "marvell,mv88f6180-core-clock" - for Kirkwood MV88f6180 SoC | 61 | "marvell,mv88f6180-core-clock" - for Kirkwood MV88f6180 SoC |
62 | "marvell,mv98dx1135-core-clock" - for Kirkwood 98dx1135 SoC | ||
62 | "marvell,mv88f5181-core-clock" - for Orion MV88F5181 SoC | 63 | "marvell,mv88f5181-core-clock" - for Orion MV88F5181 SoC |
63 | "marvell,mv88f5182-core-clock" - for Orion MV88F5182 SoC | 64 | "marvell,mv88f5182-core-clock" - for Orion MV88F5182 SoC |
64 | "marvell,mv88f5281-core-clock" - for Orion MV88F5281 SoC | 65 | "marvell,mv88f5281-core-clock" - for Orion MV88F5281 SoC |
diff --git a/Documentation/devicetree/bindings/clock/qcom,gpucc.txt b/Documentation/devicetree/bindings/clock/qcom,gpucc.txt index 4e5215ef1acd..269afe8a757e 100644 --- a/Documentation/devicetree/bindings/clock/qcom,gpucc.txt +++ b/Documentation/devicetree/bindings/clock/qcom,gpucc.txt | |||
@@ -2,13 +2,15 @@ Qualcomm Graphics Clock & Reset Controller Binding | |||
2 | -------------------------------------------------- | 2 | -------------------------------------------------- |
3 | 3 | ||
4 | Required properties : | 4 | Required properties : |
5 | - compatible : shall contain "qcom,sdm845-gpucc" | 5 | - compatible : shall contain "qcom,sdm845-gpucc" or "qcom,msm8998-gpucc" |
6 | - reg : shall contain base register location and length | 6 | - reg : shall contain base register location and length |
7 | - #clock-cells : from common clock binding, shall contain 1 | 7 | - #clock-cells : from common clock binding, shall contain 1 |
8 | - #reset-cells : from common reset binding, shall contain 1 | 8 | - #reset-cells : from common reset binding, shall contain 1 |
9 | - #power-domain-cells : from generic power domain binding, shall contain 1 | 9 | - #power-domain-cells : from generic power domain binding, shall contain 1 |
10 | - clocks : shall contain the XO clock | 10 | - clocks : shall contain the XO clock |
11 | shall contain the gpll0 out main clock (msm8998) | ||
11 | - clock-names : shall be "xo" | 12 | - clock-names : shall be "xo" |
13 | shall be "gpll0" (msm8998) | ||
12 | 14 | ||
13 | Example: | 15 | Example: |
14 | gpucc: clock-controller@5090000 { | 16 | gpucc: clock-controller@5090000 { |
diff --git a/Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.txt b/Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.txt index d60b99756bb9..aed713cf0831 100644 --- a/Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.txt +++ b/Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.txt | |||
@@ -13,6 +13,7 @@ Required Properties: | |||
13 | - external (optional) RGMII_REFCLK | 13 | - external (optional) RGMII_REFCLK |
14 | - clock-names: Must be: | 14 | - clock-names: Must be: |
15 | clock-names = "mclk", "rtc", "jtag", "rgmii_ref_ext"; | 15 | clock-names = "mclk", "rtc", "jtag", "rgmii_ref_ext"; |
16 | - #power-domain-cells: Must be 0 | ||
16 | 17 | ||
17 | Examples | 18 | Examples |
18 | -------- | 19 | -------- |
@@ -27,6 +28,7 @@ Examples | |||
27 | clocks = <&ext_mclk>, <&ext_rtc_clk>, | 28 | clocks = <&ext_mclk>, <&ext_rtc_clk>, |
28 | <&ext_jtag_clk>, <&ext_rgmii_ref>; | 29 | <&ext_jtag_clk>, <&ext_rgmii_ref>; |
29 | clock-names = "mclk", "rtc", "jtag", "rgmii_ref_ext"; | 30 | clock-names = "mclk", "rtc", "jtag", "rgmii_ref_ext"; |
31 | #power-domain-cells = <0>; | ||
30 | }; | 32 | }; |
31 | 33 | ||
32 | - Other nodes can use the clocks provided by SYSCTRL as in: | 34 | - Other nodes can use the clocks provided by SYSCTRL as in: |
@@ -38,6 +40,7 @@ Examples | |||
38 | interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>; | 40 | interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>; |
39 | reg-shift = <2>; | 41 | reg-shift = <2>; |
40 | reg-io-width = <4>; | 42 | reg-io-width = <4>; |
41 | clocks = <&sysctrl R9A06G032_CLK_UART0>; | 43 | clocks = <&sysctrl R9A06G032_CLK_UART0>, <&sysctrl R9A06G032_HCLK_UART0>; |
42 | clock-names = "baudclk"; | 44 | clock-names = "baudclk", "apb_pclk"; |
45 | power-domains = <&sysctrl>; | ||
43 | }; | 46 | }; |
diff --git a/Documentation/devicetree/bindings/clock/silabs,si5341.txt b/Documentation/devicetree/bindings/clock/silabs,si5341.txt new file mode 100644 index 000000000000..a70c333e4cd4 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/silabs,si5341.txt | |||
@@ -0,0 +1,162 @@ | |||
1 | Binding for Silicon Labs Si5341 and Si5340 programmable i2c clock generator. | ||
2 | |||
3 | Reference | ||
4 | [1] Si5341 Data Sheet | ||
5 | https://www.silabs.com/documents/public/data-sheets/Si5341-40-D-DataSheet.pdf | ||
6 | [2] Si5341 Reference Manual | ||
7 | https://www.silabs.com/documents/public/reference-manuals/Si5341-40-D-RM.pdf | ||
8 | |||
9 | The Si5341 and Si5340 are programmable i2c clock generators with up to 10 output | ||
10 | clocks. The chip contains a PLL that sources 5 (or 4) multisynth clocks, which | ||
11 | in turn can be directed to any of the 10 (or 4) outputs through a divider. | ||
12 | The internal structure of the clock generators can be found in [2]. | ||
13 | |||
14 | The driver can be used in "as is" mode, reading the current settings from the | ||
15 | chip at boot, in case you have a (pre-)programmed device. If the PLL is not | ||
16 | configured when the driver probes, it assumes the driver must fully initialize | ||
17 | it. | ||
18 | |||
19 | The device type, speed grade and revision are determined runtime by probing. | ||
20 | |||
21 | The driver currently only supports XTAL input mode, and does not support any | ||
22 | fancy input configurations. They can still be programmed into the chip and | ||
23 | the driver will leave them "as is". | ||
24 | |||
25 | ==I2C device node== | ||
26 | |||
27 | Required properties: | ||
28 | - compatible: shall be one of the following: | ||
29 | "silabs,si5340" - Si5340 A/B/C/D | ||
30 | "silabs,si5341" - Si5341 A/B/C/D | ||
31 | - reg: i2c device address, usually 0x74 | ||
32 | - #clock-cells: from common clock binding; shall be set to 2. | ||
33 | The first value is "0" for outputs, "1" for synthesizers. | ||
34 | The second value is the output or synthesizer index. | ||
35 | - clocks: from common clock binding; list of parent clock handles, | ||
36 | corresponding to inputs. Use a fixed clock for the "xtal" input. | ||
37 | At least one must be present. | ||
38 | - clock-names: One of: "xtal", "in0", "in1", "in2" | ||
39 | - vdd-supply: Regulator node for VDD | ||
40 | |||
41 | Optional properties: | ||
42 | - vdda-supply: Regulator node for VDDA | ||
43 | - vdds-supply: Regulator node for VDDS | ||
44 | - silabs,pll-m-num, silabs,pll-m-den: Numerator and denominator for PLL | ||
45 | feedback divider. Must be such that the PLL output is in the valid range. For | ||
46 | example, to create 14GHz from a 48MHz xtal, use m-num=14000 and m-den=48. Only | ||
47 | the fraction matters, using 3500 and 12 will deliver the exact same result. | ||
48 | If these are not specified, and the PLL is not yet programmed when the driver | ||
49 | probes, the PLL will be set to 14GHz. | ||
50 | - silabs,reprogram: When present, the driver will always assume the device must | ||
51 | be initialized, and always performs the soft-reset routine. Since this will | ||
52 | temporarily stop all output clocks, don't do this if the chip is generating | ||
53 | the CPU clock for example. | ||
54 | - interrupts: Interrupt for INTRb pin. | ||
55 | - #address-cells: shall be set to 1. | ||
56 | - #size-cells: shall be set to 0. | ||
57 | |||
58 | |||
59 | == Child nodes: Outputs == | ||
60 | |||
61 | The child nodes list the output clocks. | ||
62 | |||
63 | Each of the clock outputs can be overwritten individually by using a child node. | ||
64 | If a child node for a clock output is not set, the configuration remains | ||
65 | unchanged. | ||
66 | |||
67 | Required child node properties: | ||
68 | - reg: number of clock output. | ||
69 | |||
70 | Optional child node properties: | ||
71 | - vdd-supply: Regulator node for VDD for this output. The driver selects default | ||
72 | values for common-mode and amplitude based on the voltage. | ||
73 | - silabs,format: Output format, one of: | ||
74 | 1 = differential (defaults to LVDS levels) | ||
75 | 2 = low-power (defaults to HCSL levels) | ||
76 | 4 = LVCMOS | ||
77 | - silabs,common-mode: Manually override output common mode, see [2] for values | ||
78 | - silabs,amplitude: Manually override output amplitude, see [2] for values | ||
79 | - silabs,synth-master: boolean. If present, this output is allowed to change the | ||
80 | multisynth frequency dynamically. | ||
81 | - silabs,silabs,disable-high: boolean. If set, the clock output is driven HIGH | ||
82 | when disabled, otherwise it's driven LOW. | ||
83 | |||
84 | ==Example== | ||
85 | |||
86 | /* 48MHz reference crystal */ | ||
87 | ref48: ref48M { | ||
88 | compatible = "fixed-clock"; | ||
89 | #clock-cells = <0>; | ||
90 | clock-frequency = <48000000>; | ||
91 | }; | ||
92 | |||
93 | i2c-master-node { | ||
94 | /* Programmable clock (for logic) */ | ||
95 | si5341: clock-generator@74 { | ||
96 | reg = <0x74>; | ||
97 | compatible = "silabs,si5341"; | ||
98 | #clock-cells = <2>; | ||
99 | #address-cells = <1>; | ||
100 | #size-cells = <0>; | ||
101 | clocks = <&ref48>; | ||
102 | clock-names = "xtal"; | ||
103 | |||
104 | silabs,pll-m-num = <14000>; /* PLL at 14.0 GHz */ | ||
105 | silabs,pll-m-den = <48>; | ||
106 | silabs,reprogram; /* Chips are not programmed, always reset */ | ||
107 | |||
108 | out@0 { | ||
109 | reg = <0>; | ||
110 | silabs,format = <1>; /* LVDS 3v3 */ | ||
111 | silabs,common-mode = <3>; | ||
112 | silabs,amplitude = <3>; | ||
113 | silabs,synth-master; | ||
114 | }; | ||
115 | |||
116 | /* | ||
117 | * Output 6 configuration: | ||
118 | * LVDS 1v8 | ||
119 | */ | ||
120 | out@6 { | ||
121 | reg = <6>; | ||
122 | silabs,format = <1>; /* LVDS 1v8 */ | ||
123 | silabs,common-mode = <13>; | ||
124 | silabs,amplitude = <3>; | ||
125 | }; | ||
126 | |||
127 | /* | ||
128 | * Output 8 configuration: | ||
129 | * HCSL 3v3 | ||
130 | */ | ||
131 | out@8 { | ||
132 | reg = <8>; | ||
133 | silabs,format = <2>; | ||
134 | silabs,common-mode = <11>; | ||
135 | silabs,amplitude = <3>; | ||
136 | }; | ||
137 | }; | ||
138 | }; | ||
139 | |||
140 | some-video-node { | ||
141 | /* Standard clock bindings */ | ||
142 | clock-names = "pixel"; | ||
143 | clocks = <&si5341 0 7>; /* Output 7 */ | ||
144 | |||
145 | /* Set output 7 to use syntesizer 3 as its parent */ | ||
146 | assigned-clocks = <&si5341 0 7>, <&si5341 1 3>; | ||
147 | assigned-clock-parents = <&si5341 1 3>; | ||
148 | /* Set output 7 to 148.5 MHz using a synth frequency of 594 MHz */ | ||
149 | assigned-clock-rates = <148500000>, <594000000>; | ||
150 | }; | ||
151 | |||
152 | some-audio-node { | ||
153 | clock-names = "i2s-clk"; | ||
154 | clocks = <&si5341 0 0>; | ||
155 | /* | ||
156 | * since output 0 is a synth-master, the synth will be automatically set | ||
157 | * to an appropriate frequency when the audio driver requests another | ||
158 | * frequency. We give control over synth 2 to this output here. | ||
159 | */ | ||
160 | assigned-clocks = <&si5341 0 0>; | ||
161 | assigned-clock-parents = <&si5341 1 2>; | ||
162 | }; | ||
diff --git a/Documentation/devicetree/bindings/clock/sunxi-ccu.txt b/Documentation/devicetree/bindings/clock/sunxi-ccu.txt deleted file mode 100644 index e3bd88ae456b..000000000000 --- a/Documentation/devicetree/bindings/clock/sunxi-ccu.txt +++ /dev/null | |||
@@ -1,62 +0,0 @@ | |||
1 | Allwinner Clock Control Unit Binding | ||
2 | ------------------------------------ | ||
3 | |||
4 | Required properties : | ||
5 | - compatible: must contain one of the following compatibles: | ||
6 | - "allwinner,sun4i-a10-ccu" | ||
7 | - "allwinner,sun5i-a10s-ccu" | ||
8 | - "allwinner,sun5i-a13-ccu" | ||
9 | - "allwinner,sun6i-a31-ccu" | ||
10 | - "allwinner,sun7i-a20-ccu" | ||
11 | - "allwinner,sun8i-a23-ccu" | ||
12 | - "allwinner,sun8i-a33-ccu" | ||
13 | - "allwinner,sun8i-a83t-ccu" | ||
14 | - "allwinner,sun8i-a83t-r-ccu" | ||
15 | - "allwinner,sun8i-h3-ccu" | ||
16 | - "allwinner,sun8i-h3-r-ccu" | ||
17 | + - "allwinner,sun8i-r40-ccu" | ||
18 | - "allwinner,sun8i-v3s-ccu" | ||
19 | - "allwinner,sun9i-a80-ccu" | ||
20 | - "allwinner,sun50i-a64-ccu" | ||
21 | - "allwinner,sun50i-a64-r-ccu" | ||
22 | - "allwinner,sun50i-h5-ccu" | ||
23 | - "allwinner,sun50i-h6-ccu" | ||
24 | - "allwinner,sun50i-h6-r-ccu" | ||
25 | - "allwinner,suniv-f1c100s-ccu" | ||
26 | - "nextthing,gr8-ccu" | ||
27 | |||
28 | - reg: Must contain the registers base address and length | ||
29 | - clocks: phandle to the oscillators feeding the CCU. Two are needed: | ||
30 | - "hosc": the high frequency oscillator (usually at 24MHz) | ||
31 | - "losc": the low frequency oscillator (usually at 32kHz) | ||
32 | On the A83T, this is the internal 16MHz oscillator divided by 512 | ||
33 | - clock-names: Must contain the clock names described just above | ||
34 | - #clock-cells : must contain 1 | ||
35 | - #reset-cells : must contain 1 | ||
36 | |||
37 | For the main CCU on H6, one more clock is needed: | ||
38 | - "iosc": the SoC's internal frequency oscillator | ||
39 | |||
40 | For the PRCM CCUs on A83T/H3/A64/H6, two more clocks are needed: | ||
41 | - "pll-periph": the SoC's peripheral PLL from the main CCU | ||
42 | - "iosc": the SoC's internal frequency oscillator | ||
43 | |||
44 | Example for generic CCU: | ||
45 | ccu: clock@1c20000 { | ||
46 | compatible = "allwinner,sun8i-h3-ccu"; | ||
47 | reg = <0x01c20000 0x400>; | ||
48 | clocks = <&osc24M>, <&osc32k>; | ||
49 | clock-names = "hosc", "losc"; | ||
50 | #clock-cells = <1>; | ||
51 | #reset-cells = <1>; | ||
52 | }; | ||
53 | |||
54 | Example for PRCM CCU: | ||
55 | r_ccu: clock@1f01400 { | ||
56 | compatible = "allwinner,sun50i-a64-r-ccu"; | ||
57 | reg = <0x01f01400 0x100>; | ||
58 | clocks = <&osc24M>, <&osc32k>, <&iosc>, <&ccu CLK_PLL_PERIPH0>; | ||
59 | clock-names = "hosc", "losc", "iosc", "pll-periph"; | ||
60 | #clock-cells = <1>; | ||
61 | #reset-cells = <1>; | ||
62 | }; | ||
diff --git a/Documentation/driver-api/driver-model/devres.rst b/Documentation/driver-api/driver-model/devres.rst index 4ac99122b5f1..a100bef54952 100644 --- a/Documentation/driver-api/driver-model/devres.rst +++ b/Documentation/driver-api/driver-model/devres.rst | |||
@@ -246,6 +246,10 @@ CLOCK | |||
246 | devm_clk_get() | 246 | devm_clk_get() |
247 | devm_clk_get_optional() | 247 | devm_clk_get_optional() |
248 | devm_clk_put() | 248 | devm_clk_put() |
249 | devm_clk_bulk_get() | ||
250 | devm_clk_bulk_get_all() | ||
251 | devm_clk_bulk_get_optional() | ||
252 | devm_get_clk_from_childl() | ||
249 | devm_clk_hw_register() | 253 | devm_clk_hw_register() |
250 | devm_of_clk_add_hw_provider() | 254 | devm_of_clk_add_hw_provider() |
251 | devm_clk_hw_register_clkdev() | 255 | devm_clk_hw_register_clkdev() |
diff --git a/arch/mips/include/asm/mach-jz4740/clock.h b/arch/mips/include/asm/mach-jz4740/clock.h deleted file mode 100644 index 600d5051691a..000000000000 --- a/arch/mips/include/asm/mach-jz4740/clock.h +++ /dev/null | |||
@@ -1,22 +0,0 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0-or-later */ | ||
2 | /* | ||
3 | * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de> | ||
4 | */ | ||
5 | |||
6 | #ifndef __ASM_JZ4740_CLOCK_H__ | ||
7 | #define __ASM_JZ4740_CLOCK_H__ | ||
8 | |||
9 | enum jz4740_wait_mode { | ||
10 | JZ4740_WAIT_MODE_IDLE, | ||
11 | JZ4740_WAIT_MODE_SLEEP, | ||
12 | }; | ||
13 | |||
14 | void jz4740_clock_set_wait_mode(enum jz4740_wait_mode mode); | ||
15 | |||
16 | void jz4740_clock_suspend(void); | ||
17 | void jz4740_clock_resume(void); | ||
18 | |||
19 | void jz4740_clock_udc_enable_auto_suspend(void); | ||
20 | void jz4740_clock_udc_disable_auto_suspend(void); | ||
21 | |||
22 | #endif | ||
diff --git a/arch/mips/jz4740/board-qi_lb60.c b/arch/mips/jz4740/board-qi_lb60.c index daed44ee116d..4a7a80c358c7 100644 --- a/arch/mips/jz4740/board-qi_lb60.c +++ b/arch/mips/jz4740/board-qi_lb60.c | |||
@@ -37,8 +37,6 @@ | |||
37 | 37 | ||
38 | #include <asm/mach-jz4740/platform.h> | 38 | #include <asm/mach-jz4740/platform.h> |
39 | 39 | ||
40 | #include "clock.h" | ||
41 | |||
42 | /* GPIOs */ | 40 | /* GPIOs */ |
43 | #define QI_LB60_GPIO_KEYOUT(x) (JZ_GPIO_PORTC(10) + (x)) | 41 | #define QI_LB60_GPIO_KEYOUT(x) (JZ_GPIO_PORTC(10) + (x)) |
44 | #define QI_LB60_GPIO_KEYIN(x) (JZ_GPIO_PORTD(18) + (x)) | 42 | #define QI_LB60_GPIO_KEYIN(x) (JZ_GPIO_PORTD(18) + (x)) |
diff --git a/arch/mips/jz4740/platform.c b/arch/mips/jz4740/platform.c index 4b89abb17950..c74c99f5951d 100644 --- a/arch/mips/jz4740/platform.c +++ b/arch/mips/jz4740/platform.c | |||
@@ -21,8 +21,6 @@ | |||
21 | #include <linux/serial_core.h> | 21 | #include <linux/serial_core.h> |
22 | #include <linux/serial_8250.h> | 22 | #include <linux/serial_8250.h> |
23 | 23 | ||
24 | #include "clock.h" | ||
25 | |||
26 | /* USB Device Controller */ | 24 | /* USB Device Controller */ |
27 | struct platform_device jz4740_udc_xceiv_device = { | 25 | struct platform_device jz4740_udc_xceiv_device = { |
28 | .name = "usb_phy_generic", | 26 | .name = "usb_phy_generic", |
diff --git a/arch/mips/jz4740/pm.c b/arch/mips/jz4740/pm.c index bbdd2b801e6e..f9b551f01f42 100644 --- a/arch/mips/jz4740/pm.c +++ b/arch/mips/jz4740/pm.c | |||
@@ -9,21 +9,13 @@ | |||
9 | #include <linux/delay.h> | 9 | #include <linux/delay.h> |
10 | #include <linux/suspend.h> | 10 | #include <linux/suspend.h> |
11 | 11 | ||
12 | #include <asm/mach-jz4740/clock.h> | ||
13 | |||
14 | static int jz4740_pm_enter(suspend_state_t state) | 12 | static int jz4740_pm_enter(suspend_state_t state) |
15 | { | 13 | { |
16 | jz4740_clock_suspend(); | ||
17 | |||
18 | jz4740_clock_set_wait_mode(JZ4740_WAIT_MODE_SLEEP); | ||
19 | |||
20 | __asm__(".set\tmips3\n\t" | 14 | __asm__(".set\tmips3\n\t" |
21 | "wait\n\t" | 15 | "wait\n\t" |
22 | ".set\tmips0"); | 16 | ".set\tmips0"); |
23 | 17 | ||
24 | jz4740_clock_set_wait_mode(JZ4740_WAIT_MODE_IDLE); | ||
25 | 18 | ||
26 | jz4740_clock_resume(); | ||
27 | 19 | ||
28 | return 0; | 20 | return 0; |
29 | } | 21 | } |
diff --git a/arch/mips/jz4740/time.c b/arch/mips/jz4740/time.c index a3260c754e65..cb768e560d8b 100644 --- a/arch/mips/jz4740/time.c +++ b/arch/mips/jz4740/time.c | |||
@@ -13,13 +13,10 @@ | |||
13 | #include <linux/clockchips.h> | 13 | #include <linux/clockchips.h> |
14 | #include <linux/sched_clock.h> | 14 | #include <linux/sched_clock.h> |
15 | 15 | ||
16 | #include <asm/mach-jz4740/clock.h> | ||
17 | #include <asm/mach-jz4740/irq.h> | 16 | #include <asm/mach-jz4740/irq.h> |
18 | #include <asm/mach-jz4740/timer.h> | 17 | #include <asm/mach-jz4740/timer.h> |
19 | #include <asm/time.h> | 18 | #include <asm/time.h> |
20 | 19 | ||
21 | #include "clock.h" | ||
22 | |||
23 | #define TIMER_CLOCKEVENT 0 | 20 | #define TIMER_CLOCKEVENT 0 |
24 | #define TIMER_CLOCKSOURCE 1 | 21 | #define TIMER_CLOCKSOURCE 1 |
25 | 22 | ||
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 7376af25f947..801fa1cd0321 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig | |||
@@ -90,6 +90,17 @@ config COMMON_CLK_SCPI | |||
90 | This driver uses SCPI Message Protocol to interact with the | 90 | This driver uses SCPI Message Protocol to interact with the |
91 | firmware providing all the clock controls. | 91 | firmware providing all the clock controls. |
92 | 92 | ||
93 | config COMMON_CLK_SI5341 | ||
94 | tristate "Clock driver for SiLabs 5341 and 5340 A/B/C/D devices" | ||
95 | depends on I2C | ||
96 | select REGMAP_I2C | ||
97 | help | ||
98 | This driver supports Silicon Labs Si5341 and Si5340 programmable clock | ||
99 | generators. Not all features of these chips are currently supported | ||
100 | by the driver, in particular it only supports XTAL input. The chip can | ||
101 | be pre-programmed to support other configurations and features not yet | ||
102 | implemented in the driver. | ||
103 | |||
93 | config COMMON_CLK_SI5351 | 104 | config COMMON_CLK_SI5351 |
94 | tristate "Clock driver for SiLabs 5351A/B/C" | 105 | tristate "Clock driver for SiLabs 5351A/B/C" |
95 | depends on I2C | 106 | depends on I2C |
@@ -214,7 +225,7 @@ config CLK_QORIQ | |||
214 | 225 | ||
215 | config COMMON_CLK_XGENE | 226 | config COMMON_CLK_XGENE |
216 | bool "Clock driver for APM XGene SoC" | 227 | bool "Clock driver for APM XGene SoC" |
217 | default y | 228 | default ARCH_XGENE |
218 | depends on ARM64 || COMPILE_TEST | 229 | depends on ARM64 || COMPILE_TEST |
219 | ---help--- | 230 | ---help--- |
220 | Sypport for the APM X-Gene SoC reference, PLL, and device clocks. | 231 | Sypport for the APM X-Gene SoC reference, PLL, and device clocks. |
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 9ef4305d55e0..0cad76021297 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile | |||
@@ -49,6 +49,7 @@ obj-$(CONFIG_COMMON_CLK_HI655X) += clk-hi655x.o | |||
49 | obj-$(CONFIG_COMMON_CLK_S2MPS11) += clk-s2mps11.o | 49 | obj-$(CONFIG_COMMON_CLK_S2MPS11) += clk-s2mps11.o |
50 | obj-$(CONFIG_COMMON_CLK_SCMI) += clk-scmi.o | 50 | obj-$(CONFIG_COMMON_CLK_SCMI) += clk-scmi.o |
51 | obj-$(CONFIG_COMMON_CLK_SCPI) += clk-scpi.o | 51 | obj-$(CONFIG_COMMON_CLK_SCPI) += clk-scpi.o |
52 | obj-$(CONFIG_COMMON_CLK_SI5341) += clk-si5341.o | ||
52 | obj-$(CONFIG_COMMON_CLK_SI5351) += clk-si5351.o | 53 | obj-$(CONFIG_COMMON_CLK_SI5351) += clk-si5351.o |
53 | obj-$(CONFIG_COMMON_CLK_SI514) += clk-si514.o | 54 | obj-$(CONFIG_COMMON_CLK_SI514) += clk-si514.o |
54 | obj-$(CONFIG_COMMON_CLK_SI544) += clk-si544.o | 55 | obj-$(CONFIG_COMMON_CLK_SI544) += clk-si544.o |
diff --git a/drivers/clk/at91/sckc.c b/drivers/clk/at91/sckc.c index 45526f56f1ba..9bfe9a28294a 100644 --- a/drivers/clk/at91/sckc.c +++ b/drivers/clk/at91/sckc.c | |||
@@ -18,14 +18,18 @@ | |||
18 | SLOW_CLOCK_FREQ) | 18 | SLOW_CLOCK_FREQ) |
19 | 19 | ||
20 | #define AT91_SCKC_CR 0x00 | 20 | #define AT91_SCKC_CR 0x00 |
21 | #define AT91_SCKC_RCEN (1 << 0) | 21 | |
22 | #define AT91_SCKC_OSC32EN (1 << 1) | 22 | struct clk_slow_bits { |
23 | #define AT91_SCKC_OSC32BYP (1 << 2) | 23 | u32 cr_rcen; |
24 | #define AT91_SCKC_OSCSEL (1 << 3) | 24 | u32 cr_osc32en; |
25 | u32 cr_osc32byp; | ||
26 | u32 cr_oscsel; | ||
27 | }; | ||
25 | 28 | ||
26 | struct clk_slow_osc { | 29 | struct clk_slow_osc { |
27 | struct clk_hw hw; | 30 | struct clk_hw hw; |
28 | void __iomem *sckcr; | 31 | void __iomem *sckcr; |
32 | const struct clk_slow_bits *bits; | ||
29 | unsigned long startup_usec; | 33 | unsigned long startup_usec; |
30 | }; | 34 | }; |
31 | 35 | ||
@@ -34,6 +38,7 @@ struct clk_slow_osc { | |||
34 | struct clk_sama5d4_slow_osc { | 38 | struct clk_sama5d4_slow_osc { |
35 | struct clk_hw hw; | 39 | struct clk_hw hw; |
36 | void __iomem *sckcr; | 40 | void __iomem *sckcr; |
41 | const struct clk_slow_bits *bits; | ||
37 | unsigned long startup_usec; | 42 | unsigned long startup_usec; |
38 | bool prepared; | 43 | bool prepared; |
39 | }; | 44 | }; |
@@ -43,6 +48,7 @@ struct clk_sama5d4_slow_osc { | |||
43 | struct clk_slow_rc_osc { | 48 | struct clk_slow_rc_osc { |
44 | struct clk_hw hw; | 49 | struct clk_hw hw; |
45 | void __iomem *sckcr; | 50 | void __iomem *sckcr; |
51 | const struct clk_slow_bits *bits; | ||
46 | unsigned long frequency; | 52 | unsigned long frequency; |
47 | unsigned long accuracy; | 53 | unsigned long accuracy; |
48 | unsigned long startup_usec; | 54 | unsigned long startup_usec; |
@@ -53,6 +59,7 @@ struct clk_slow_rc_osc { | |||
53 | struct clk_sam9x5_slow { | 59 | struct clk_sam9x5_slow { |
54 | struct clk_hw hw; | 60 | struct clk_hw hw; |
55 | void __iomem *sckcr; | 61 | void __iomem *sckcr; |
62 | const struct clk_slow_bits *bits; | ||
56 | u8 parent; | 63 | u8 parent; |
57 | }; | 64 | }; |
58 | 65 | ||
@@ -64,10 +71,10 @@ static int clk_slow_osc_prepare(struct clk_hw *hw) | |||
64 | void __iomem *sckcr = osc->sckcr; | 71 | void __iomem *sckcr = osc->sckcr; |
65 | u32 tmp = readl(sckcr); | 72 | u32 tmp = readl(sckcr); |
66 | 73 | ||
67 | if (tmp & (AT91_SCKC_OSC32BYP | AT91_SCKC_OSC32EN)) | 74 | if (tmp & (osc->bits->cr_osc32byp | osc->bits->cr_osc32en)) |
68 | return 0; | 75 | return 0; |
69 | 76 | ||
70 | writel(tmp | AT91_SCKC_OSC32EN, sckcr); | 77 | writel(tmp | osc->bits->cr_osc32en, sckcr); |
71 | 78 | ||
72 | usleep_range(osc->startup_usec, osc->startup_usec + 1); | 79 | usleep_range(osc->startup_usec, osc->startup_usec + 1); |
73 | 80 | ||
@@ -80,10 +87,10 @@ static void clk_slow_osc_unprepare(struct clk_hw *hw) | |||
80 | void __iomem *sckcr = osc->sckcr; | 87 | void __iomem *sckcr = osc->sckcr; |
81 | u32 tmp = readl(sckcr); | 88 | u32 tmp = readl(sckcr); |
82 | 89 | ||
83 | if (tmp & AT91_SCKC_OSC32BYP) | 90 | if (tmp & osc->bits->cr_osc32byp) |
84 | return; | 91 | return; |
85 | 92 | ||
86 | writel(tmp & ~AT91_SCKC_OSC32EN, sckcr); | 93 | writel(tmp & ~osc->bits->cr_osc32en, sckcr); |
87 | } | 94 | } |
88 | 95 | ||
89 | static int clk_slow_osc_is_prepared(struct clk_hw *hw) | 96 | static int clk_slow_osc_is_prepared(struct clk_hw *hw) |
@@ -92,10 +99,10 @@ static int clk_slow_osc_is_prepared(struct clk_hw *hw) | |||
92 | void __iomem *sckcr = osc->sckcr; | 99 | void __iomem *sckcr = osc->sckcr; |
93 | u32 tmp = readl(sckcr); | 100 | u32 tmp = readl(sckcr); |
94 | 101 | ||
95 | if (tmp & AT91_SCKC_OSC32BYP) | 102 | if (tmp & osc->bits->cr_osc32byp) |
96 | return 1; | 103 | return 1; |
97 | 104 | ||
98 | return !!(tmp & AT91_SCKC_OSC32EN); | 105 | return !!(tmp & osc->bits->cr_osc32en); |
99 | } | 106 | } |
100 | 107 | ||
101 | static const struct clk_ops slow_osc_ops = { | 108 | static const struct clk_ops slow_osc_ops = { |
@@ -109,7 +116,8 @@ at91_clk_register_slow_osc(void __iomem *sckcr, | |||
109 | const char *name, | 116 | const char *name, |
110 | const char *parent_name, | 117 | const char *parent_name, |
111 | unsigned long startup, | 118 | unsigned long startup, |
112 | bool bypass) | 119 | bool bypass, |
120 | const struct clk_slow_bits *bits) | ||
113 | { | 121 | { |
114 | struct clk_slow_osc *osc; | 122 | struct clk_slow_osc *osc; |
115 | struct clk_hw *hw; | 123 | struct clk_hw *hw; |
@@ -132,10 +140,11 @@ at91_clk_register_slow_osc(void __iomem *sckcr, | |||
132 | osc->hw.init = &init; | 140 | osc->hw.init = &init; |
133 | osc->sckcr = sckcr; | 141 | osc->sckcr = sckcr; |
134 | osc->startup_usec = startup; | 142 | osc->startup_usec = startup; |
143 | osc->bits = bits; | ||
135 | 144 | ||
136 | if (bypass) | 145 | if (bypass) |
137 | writel((readl(sckcr) & ~AT91_SCKC_OSC32EN) | AT91_SCKC_OSC32BYP, | 146 | writel((readl(sckcr) & ~osc->bits->cr_osc32en) | |
138 | sckcr); | 147 | osc->bits->cr_osc32byp, sckcr); |
139 | 148 | ||
140 | hw = &osc->hw; | 149 | hw = &osc->hw; |
141 | ret = clk_hw_register(NULL, &osc->hw); | 150 | ret = clk_hw_register(NULL, &osc->hw); |
@@ -147,6 +156,14 @@ at91_clk_register_slow_osc(void __iomem *sckcr, | |||
147 | return hw; | 156 | return hw; |
148 | } | 157 | } |
149 | 158 | ||
159 | static void at91_clk_unregister_slow_osc(struct clk_hw *hw) | ||
160 | { | ||
161 | struct clk_slow_osc *osc = to_clk_slow_osc(hw); | ||
162 | |||
163 | clk_hw_unregister(hw); | ||
164 | kfree(osc); | ||
165 | } | ||
166 | |||
150 | static unsigned long clk_slow_rc_osc_recalc_rate(struct clk_hw *hw, | 167 | static unsigned long clk_slow_rc_osc_recalc_rate(struct clk_hw *hw, |
151 | unsigned long parent_rate) | 168 | unsigned long parent_rate) |
152 | { | 169 | { |
@@ -168,7 +185,7 @@ static int clk_slow_rc_osc_prepare(struct clk_hw *hw) | |||
168 | struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw); | 185 | struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw); |
169 | void __iomem *sckcr = osc->sckcr; | 186 | void __iomem *sckcr = osc->sckcr; |
170 | 187 | ||
171 | writel(readl(sckcr) | AT91_SCKC_RCEN, sckcr); | 188 | writel(readl(sckcr) | osc->bits->cr_rcen, sckcr); |
172 | 189 | ||
173 | usleep_range(osc->startup_usec, osc->startup_usec + 1); | 190 | usleep_range(osc->startup_usec, osc->startup_usec + 1); |
174 | 191 | ||
@@ -180,14 +197,14 @@ static void clk_slow_rc_osc_unprepare(struct clk_hw *hw) | |||
180 | struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw); | 197 | struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw); |
181 | void __iomem *sckcr = osc->sckcr; | 198 | void __iomem *sckcr = osc->sckcr; |
182 | 199 | ||
183 | writel(readl(sckcr) & ~AT91_SCKC_RCEN, sckcr); | 200 | writel(readl(sckcr) & ~osc->bits->cr_rcen, sckcr); |
184 | } | 201 | } |
185 | 202 | ||
186 | static int clk_slow_rc_osc_is_prepared(struct clk_hw *hw) | 203 | static int clk_slow_rc_osc_is_prepared(struct clk_hw *hw) |
187 | { | 204 | { |
188 | struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw); | 205 | struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw); |
189 | 206 | ||
190 | return !!(readl(osc->sckcr) & AT91_SCKC_RCEN); | 207 | return !!(readl(osc->sckcr) & osc->bits->cr_rcen); |
191 | } | 208 | } |
192 | 209 | ||
193 | static const struct clk_ops slow_rc_osc_ops = { | 210 | static const struct clk_ops slow_rc_osc_ops = { |
@@ -203,7 +220,8 @@ at91_clk_register_slow_rc_osc(void __iomem *sckcr, | |||
203 | const char *name, | 220 | const char *name, |
204 | unsigned long frequency, | 221 | unsigned long frequency, |
205 | unsigned long accuracy, | 222 | unsigned long accuracy, |
206 | unsigned long startup) | 223 | unsigned long startup, |
224 | const struct clk_slow_bits *bits) | ||
207 | { | 225 | { |
208 | struct clk_slow_rc_osc *osc; | 226 | struct clk_slow_rc_osc *osc; |
209 | struct clk_hw *hw; | 227 | struct clk_hw *hw; |
@@ -225,6 +243,7 @@ at91_clk_register_slow_rc_osc(void __iomem *sckcr, | |||
225 | 243 | ||
226 | osc->hw.init = &init; | 244 | osc->hw.init = &init; |
227 | osc->sckcr = sckcr; | 245 | osc->sckcr = sckcr; |
246 | osc->bits = bits; | ||
228 | osc->frequency = frequency; | 247 | osc->frequency = frequency; |
229 | osc->accuracy = accuracy; | 248 | osc->accuracy = accuracy; |
230 | osc->startup_usec = startup; | 249 | osc->startup_usec = startup; |
@@ -239,6 +258,14 @@ at91_clk_register_slow_rc_osc(void __iomem *sckcr, | |||
239 | return hw; | 258 | return hw; |
240 | } | 259 | } |
241 | 260 | ||
261 | static void at91_clk_unregister_slow_rc_osc(struct clk_hw *hw) | ||
262 | { | ||
263 | struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw); | ||
264 | |||
265 | clk_hw_unregister(hw); | ||
266 | kfree(osc); | ||
267 | } | ||
268 | |||
242 | static int clk_sam9x5_slow_set_parent(struct clk_hw *hw, u8 index) | 269 | static int clk_sam9x5_slow_set_parent(struct clk_hw *hw, u8 index) |
243 | { | 270 | { |
244 | struct clk_sam9x5_slow *slowck = to_clk_sam9x5_slow(hw); | 271 | struct clk_sam9x5_slow *slowck = to_clk_sam9x5_slow(hw); |
@@ -250,14 +277,14 @@ static int clk_sam9x5_slow_set_parent(struct clk_hw *hw, u8 index) | |||
250 | 277 | ||
251 | tmp = readl(sckcr); | 278 | tmp = readl(sckcr); |
252 | 279 | ||
253 | if ((!index && !(tmp & AT91_SCKC_OSCSEL)) || | 280 | if ((!index && !(tmp & slowck->bits->cr_oscsel)) || |
254 | (index && (tmp & AT91_SCKC_OSCSEL))) | 281 | (index && (tmp & slowck->bits->cr_oscsel))) |
255 | return 0; | 282 | return 0; |
256 | 283 | ||
257 | if (index) | 284 | if (index) |
258 | tmp |= AT91_SCKC_OSCSEL; | 285 | tmp |= slowck->bits->cr_oscsel; |
259 | else | 286 | else |
260 | tmp &= ~AT91_SCKC_OSCSEL; | 287 | tmp &= ~slowck->bits->cr_oscsel; |
261 | 288 | ||
262 | writel(tmp, sckcr); | 289 | writel(tmp, sckcr); |
263 | 290 | ||
@@ -270,7 +297,7 @@ static u8 clk_sam9x5_slow_get_parent(struct clk_hw *hw) | |||
270 | { | 297 | { |
271 | struct clk_sam9x5_slow *slowck = to_clk_sam9x5_slow(hw); | 298 | struct clk_sam9x5_slow *slowck = to_clk_sam9x5_slow(hw); |
272 | 299 | ||
273 | return !!(readl(slowck->sckcr) & AT91_SCKC_OSCSEL); | 300 | return !!(readl(slowck->sckcr) & slowck->bits->cr_oscsel); |
274 | } | 301 | } |
275 | 302 | ||
276 | static const struct clk_ops sam9x5_slow_ops = { | 303 | static const struct clk_ops sam9x5_slow_ops = { |
@@ -282,7 +309,8 @@ static struct clk_hw * __init | |||
282 | at91_clk_register_sam9x5_slow(void __iomem *sckcr, | 309 | at91_clk_register_sam9x5_slow(void __iomem *sckcr, |
283 | const char *name, | 310 | const char *name, |
284 | const char **parent_names, | 311 | const char **parent_names, |
285 | int num_parents) | 312 | int num_parents, |
313 | const struct clk_slow_bits *bits) | ||
286 | { | 314 | { |
287 | struct clk_sam9x5_slow *slowck; | 315 | struct clk_sam9x5_slow *slowck; |
288 | struct clk_hw *hw; | 316 | struct clk_hw *hw; |
@@ -304,7 +332,8 @@ at91_clk_register_sam9x5_slow(void __iomem *sckcr, | |||
304 | 332 | ||
305 | slowck->hw.init = &init; | 333 | slowck->hw.init = &init; |
306 | slowck->sckcr = sckcr; | 334 | slowck->sckcr = sckcr; |
307 | slowck->parent = !!(readl(sckcr) & AT91_SCKC_OSCSEL); | 335 | slowck->bits = bits; |
336 | slowck->parent = !!(readl(sckcr) & slowck->bits->cr_oscsel); | ||
308 | 337 | ||
309 | hw = &slowck->hw; | 338 | hw = &slowck->hw; |
310 | ret = clk_hw_register(NULL, &slowck->hw); | 339 | ret = clk_hw_register(NULL, &slowck->hw); |
@@ -316,22 +345,33 @@ at91_clk_register_sam9x5_slow(void __iomem *sckcr, | |||
316 | return hw; | 345 | return hw; |
317 | } | 346 | } |
318 | 347 | ||
348 | static void at91_clk_unregister_sam9x5_slow(struct clk_hw *hw) | ||
349 | { | ||
350 | struct clk_sam9x5_slow *slowck = to_clk_sam9x5_slow(hw); | ||
351 | |||
352 | clk_hw_unregister(hw); | ||
353 | kfree(slowck); | ||
354 | } | ||
355 | |||
319 | static void __init at91sam9x5_sckc_register(struct device_node *np, | 356 | static void __init at91sam9x5_sckc_register(struct device_node *np, |
320 | unsigned int rc_osc_startup_us) | 357 | unsigned int rc_osc_startup_us, |
358 | const struct clk_slow_bits *bits) | ||
321 | { | 359 | { |
322 | const char *parent_names[2] = { "slow_rc_osc", "slow_osc" }; | 360 | const char *parent_names[2] = { "slow_rc_osc", "slow_osc" }; |
323 | void __iomem *regbase = of_iomap(np, 0); | 361 | void __iomem *regbase = of_iomap(np, 0); |
324 | struct device_node *child = NULL; | 362 | struct device_node *child = NULL; |
325 | const char *xtal_name; | 363 | const char *xtal_name; |
326 | struct clk_hw *hw; | 364 | struct clk_hw *slow_rc, *slow_osc, *slowck; |
327 | bool bypass; | 365 | bool bypass; |
366 | int ret; | ||
328 | 367 | ||
329 | if (!regbase) | 368 | if (!regbase) |
330 | return; | 369 | return; |
331 | 370 | ||
332 | hw = at91_clk_register_slow_rc_osc(regbase, parent_names[0], 32768, | 371 | slow_rc = at91_clk_register_slow_rc_osc(regbase, parent_names[0], |
333 | 50000000, rc_osc_startup_us); | 372 | 32768, 50000000, |
334 | if (IS_ERR(hw)) | 373 | rc_osc_startup_us, bits); |
374 | if (IS_ERR(slow_rc)) | ||
335 | return; | 375 | return; |
336 | 376 | ||
337 | xtal_name = of_clk_get_parent_name(np, 0); | 377 | xtal_name = of_clk_get_parent_name(np, 0); |
@@ -339,7 +379,7 @@ static void __init at91sam9x5_sckc_register(struct device_node *np, | |||
339 | /* DT backward compatibility */ | 379 | /* DT backward compatibility */ |
340 | child = of_get_compatible_child(np, "atmel,at91sam9x5-clk-slow-osc"); | 380 | child = of_get_compatible_child(np, "atmel,at91sam9x5-clk-slow-osc"); |
341 | if (!child) | 381 | if (!child) |
342 | return; | 382 | goto unregister_slow_rc; |
343 | 383 | ||
344 | xtal_name = of_clk_get_parent_name(child, 0); | 384 | xtal_name = of_clk_get_parent_name(child, 0); |
345 | bypass = of_property_read_bool(child, "atmel,osc-bypass"); | 385 | bypass = of_property_read_bool(child, "atmel,osc-bypass"); |
@@ -350,38 +390,133 @@ static void __init at91sam9x5_sckc_register(struct device_node *np, | |||
350 | } | 390 | } |
351 | 391 | ||
352 | if (!xtal_name) | 392 | if (!xtal_name) |
353 | return; | 393 | goto unregister_slow_rc; |
354 | |||
355 | hw = at91_clk_register_slow_osc(regbase, parent_names[1], xtal_name, | ||
356 | 1200000, bypass); | ||
357 | if (IS_ERR(hw)) | ||
358 | return; | ||
359 | 394 | ||
360 | hw = at91_clk_register_sam9x5_slow(regbase, "slowck", parent_names, 2); | 395 | slow_osc = at91_clk_register_slow_osc(regbase, parent_names[1], |
361 | if (IS_ERR(hw)) | 396 | xtal_name, 1200000, bypass, bits); |
362 | return; | 397 | if (IS_ERR(slow_osc)) |
398 | goto unregister_slow_rc; | ||
363 | 399 | ||
364 | of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw); | 400 | slowck = at91_clk_register_sam9x5_slow(regbase, "slowck", parent_names, |
401 | 2, bits); | ||
402 | if (IS_ERR(slowck)) | ||
403 | goto unregister_slow_osc; | ||
365 | 404 | ||
366 | /* DT backward compatibility */ | 405 | /* DT backward compatibility */ |
367 | if (child) | 406 | if (child) |
368 | of_clk_add_hw_provider(child, of_clk_hw_simple_get, hw); | 407 | ret = of_clk_add_hw_provider(child, of_clk_hw_simple_get, |
408 | slowck); | ||
409 | else | ||
410 | ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, slowck); | ||
411 | |||
412 | if (WARN_ON(ret)) | ||
413 | goto unregister_slowck; | ||
414 | |||
415 | return; | ||
416 | |||
417 | unregister_slowck: | ||
418 | at91_clk_unregister_sam9x5_slow(slowck); | ||
419 | unregister_slow_osc: | ||
420 | at91_clk_unregister_slow_osc(slow_osc); | ||
421 | unregister_slow_rc: | ||
422 | at91_clk_unregister_slow_rc_osc(slow_rc); | ||
369 | } | 423 | } |
370 | 424 | ||
425 | static const struct clk_slow_bits at91sam9x5_bits = { | ||
426 | .cr_rcen = BIT(0), | ||
427 | .cr_osc32en = BIT(1), | ||
428 | .cr_osc32byp = BIT(2), | ||
429 | .cr_oscsel = BIT(3), | ||
430 | }; | ||
431 | |||
371 | static void __init of_at91sam9x5_sckc_setup(struct device_node *np) | 432 | static void __init of_at91sam9x5_sckc_setup(struct device_node *np) |
372 | { | 433 | { |
373 | at91sam9x5_sckc_register(np, 75); | 434 | at91sam9x5_sckc_register(np, 75, &at91sam9x5_bits); |
374 | } | 435 | } |
375 | CLK_OF_DECLARE(at91sam9x5_clk_sckc, "atmel,at91sam9x5-sckc", | 436 | CLK_OF_DECLARE(at91sam9x5_clk_sckc, "atmel,at91sam9x5-sckc", |
376 | of_at91sam9x5_sckc_setup); | 437 | of_at91sam9x5_sckc_setup); |
377 | 438 | ||
378 | static void __init of_sama5d3_sckc_setup(struct device_node *np) | 439 | static void __init of_sama5d3_sckc_setup(struct device_node *np) |
379 | { | 440 | { |
380 | at91sam9x5_sckc_register(np, 500); | 441 | at91sam9x5_sckc_register(np, 500, &at91sam9x5_bits); |
381 | } | 442 | } |
382 | CLK_OF_DECLARE(sama5d3_clk_sckc, "atmel,sama5d3-sckc", | 443 | CLK_OF_DECLARE(sama5d3_clk_sckc, "atmel,sama5d3-sckc", |
383 | of_sama5d3_sckc_setup); | 444 | of_sama5d3_sckc_setup); |
384 | 445 | ||
446 | static const struct clk_slow_bits at91sam9x60_bits = { | ||
447 | .cr_osc32en = BIT(1), | ||
448 | .cr_osc32byp = BIT(2), | ||
449 | .cr_oscsel = BIT(24), | ||
450 | }; | ||
451 | |||
452 | static void __init of_sam9x60_sckc_setup(struct device_node *np) | ||
453 | { | ||
454 | void __iomem *regbase = of_iomap(np, 0); | ||
455 | struct clk_hw_onecell_data *clk_data; | ||
456 | struct clk_hw *slow_rc, *slow_osc; | ||
457 | const char *xtal_name; | ||
458 | const char *parent_names[2] = { "slow_rc_osc", "slow_osc" }; | ||
459 | bool bypass; | ||
460 | int ret; | ||
461 | |||
462 | if (!regbase) | ||
463 | return; | ||
464 | |||
465 | slow_rc = clk_hw_register_fixed_rate(NULL, parent_names[0], NULL, 0, | ||
466 | 32768); | ||
467 | if (IS_ERR(slow_rc)) | ||
468 | return; | ||
469 | |||
470 | xtal_name = of_clk_get_parent_name(np, 0); | ||
471 | if (!xtal_name) | ||
472 | goto unregister_slow_rc; | ||
473 | |||
474 | bypass = of_property_read_bool(np, "atmel,osc-bypass"); | ||
475 | slow_osc = at91_clk_register_slow_osc(regbase, parent_names[1], | ||
476 | xtal_name, 5000000, bypass, | ||
477 | &at91sam9x60_bits); | ||
478 | if (IS_ERR(slow_osc)) | ||
479 | goto unregister_slow_rc; | ||
480 | |||
481 | clk_data = kzalloc(sizeof(*clk_data) + (2 * sizeof(struct clk_hw *)), | ||
482 | GFP_KERNEL); | ||
483 | if (!clk_data) | ||
484 | goto unregister_slow_osc; | ||
485 | |||
486 | /* MD_SLCK and TD_SLCK. */ | ||
487 | clk_data->num = 2; | ||
488 | clk_data->hws[0] = clk_hw_register_fixed_rate(NULL, "md_slck", | ||
489 | parent_names[0], | ||
490 | 0, 32768); | ||
491 | if (IS_ERR(clk_data->hws[0])) | ||
492 | goto clk_data_free; | ||
493 | |||
494 | clk_data->hws[1] = at91_clk_register_sam9x5_slow(regbase, "td_slck", | ||
495 | parent_names, 2, | ||
496 | &at91sam9x60_bits); | ||
497 | if (IS_ERR(clk_data->hws[1])) | ||
498 | goto unregister_md_slck; | ||
499 | |||
500 | ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data); | ||
501 | if (WARN_ON(ret)) | ||
502 | goto unregister_td_slck; | ||
503 | |||
504 | return; | ||
505 | |||
506 | unregister_td_slck: | ||
507 | at91_clk_unregister_sam9x5_slow(clk_data->hws[1]); | ||
508 | unregister_md_slck: | ||
509 | clk_hw_unregister(clk_data->hws[0]); | ||
510 | clk_data_free: | ||
511 | kfree(clk_data); | ||
512 | unregister_slow_osc: | ||
513 | at91_clk_unregister_slow_osc(slow_osc); | ||
514 | unregister_slow_rc: | ||
515 | clk_hw_unregister(slow_rc); | ||
516 | } | ||
517 | CLK_OF_DECLARE(sam9x60_clk_sckc, "microchip,sam9x60-sckc", | ||
518 | of_sam9x60_sckc_setup); | ||
519 | |||
385 | static int clk_sama5d4_slow_osc_prepare(struct clk_hw *hw) | 520 | static int clk_sama5d4_slow_osc_prepare(struct clk_hw *hw) |
386 | { | 521 | { |
387 | struct clk_sama5d4_slow_osc *osc = to_clk_sama5d4_slow_osc(hw); | 522 | struct clk_sama5d4_slow_osc *osc = to_clk_sama5d4_slow_osc(hw); |
@@ -393,7 +528,7 @@ static int clk_sama5d4_slow_osc_prepare(struct clk_hw *hw) | |||
393 | * Assume that if it has already been selected (for example by the | 528 | * Assume that if it has already been selected (for example by the |
394 | * bootloader), enough time has aready passed. | 529 | * bootloader), enough time has aready passed. |
395 | */ | 530 | */ |
396 | if ((readl(osc->sckcr) & AT91_SCKC_OSCSEL)) { | 531 | if ((readl(osc->sckcr) & osc->bits->cr_oscsel)) { |
397 | osc->prepared = true; | 532 | osc->prepared = true; |
398 | return 0; | 533 | return 0; |
399 | } | 534 | } |
@@ -416,33 +551,35 @@ static const struct clk_ops sama5d4_slow_osc_ops = { | |||
416 | .is_prepared = clk_sama5d4_slow_osc_is_prepared, | 551 | .is_prepared = clk_sama5d4_slow_osc_is_prepared, |
417 | }; | 552 | }; |
418 | 553 | ||
554 | static const struct clk_slow_bits at91sama5d4_bits = { | ||
555 | .cr_oscsel = BIT(3), | ||
556 | }; | ||
557 | |||
419 | static void __init of_sama5d4_sckc_setup(struct device_node *np) | 558 | static void __init of_sama5d4_sckc_setup(struct device_node *np) |
420 | { | 559 | { |
421 | void __iomem *regbase = of_iomap(np, 0); | 560 | void __iomem *regbase = of_iomap(np, 0); |
422 | struct clk_hw *hw; | 561 | struct clk_hw *slow_rc, *slowck; |
423 | struct clk_sama5d4_slow_osc *osc; | 562 | struct clk_sama5d4_slow_osc *osc; |
424 | struct clk_init_data init; | 563 | struct clk_init_data init; |
425 | const char *xtal_name; | 564 | const char *xtal_name; |
426 | const char *parent_names[2] = { "slow_rc_osc", "slow_osc" }; | 565 | const char *parent_names[2] = { "slow_rc_osc", "slow_osc" }; |
427 | bool bypass; | ||
428 | int ret; | 566 | int ret; |
429 | 567 | ||
430 | if (!regbase) | 568 | if (!regbase) |
431 | return; | 569 | return; |
432 | 570 | ||
433 | hw = clk_hw_register_fixed_rate_with_accuracy(NULL, parent_names[0], | 571 | slow_rc = clk_hw_register_fixed_rate_with_accuracy(NULL, |
434 | NULL, 0, 32768, | 572 | parent_names[0], |
435 | 250000000); | 573 | NULL, 0, 32768, |
436 | if (IS_ERR(hw)) | 574 | 250000000); |
575 | if (IS_ERR(slow_rc)) | ||
437 | return; | 576 | return; |
438 | 577 | ||
439 | xtal_name = of_clk_get_parent_name(np, 0); | 578 | xtal_name = of_clk_get_parent_name(np, 0); |
440 | 579 | ||
441 | bypass = of_property_read_bool(np, "atmel,osc-bypass"); | ||
442 | |||
443 | osc = kzalloc(sizeof(*osc), GFP_KERNEL); | 580 | osc = kzalloc(sizeof(*osc), GFP_KERNEL); |
444 | if (!osc) | 581 | if (!osc) |
445 | return; | 582 | goto unregister_slow_rc; |
446 | 583 | ||
447 | init.name = parent_names[1]; | 584 | init.name = parent_names[1]; |
448 | init.ops = &sama5d4_slow_osc_ops; | 585 | init.ops = &sama5d4_slow_osc_ops; |
@@ -453,22 +590,32 @@ static void __init of_sama5d4_sckc_setup(struct device_node *np) | |||
453 | osc->hw.init = &init; | 590 | osc->hw.init = &init; |
454 | osc->sckcr = regbase; | 591 | osc->sckcr = regbase; |
455 | osc->startup_usec = 1200000; | 592 | osc->startup_usec = 1200000; |
593 | osc->bits = &at91sama5d4_bits; | ||
456 | 594 | ||
457 | if (bypass) | ||
458 | writel((readl(regbase) | AT91_SCKC_OSC32BYP), regbase); | ||
459 | |||
460 | hw = &osc->hw; | ||
461 | ret = clk_hw_register(NULL, &osc->hw); | 595 | ret = clk_hw_register(NULL, &osc->hw); |
462 | if (ret) { | 596 | if (ret) |
463 | kfree(osc); | 597 | goto free_slow_osc_data; |
464 | return; | 598 | |
465 | } | 599 | slowck = at91_clk_register_sam9x5_slow(regbase, "slowck", |
466 | 600 | parent_names, 2, | |
467 | hw = at91_clk_register_sam9x5_slow(regbase, "slowck", parent_names, 2); | 601 | &at91sama5d4_bits); |
468 | if (IS_ERR(hw)) | 602 | if (IS_ERR(slowck)) |
469 | return; | 603 | goto unregister_slow_osc; |
470 | 604 | ||
471 | of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw); | 605 | ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, slowck); |
606 | if (WARN_ON(ret)) | ||
607 | goto unregister_slowck; | ||
608 | |||
609 | return; | ||
610 | |||
611 | unregister_slowck: | ||
612 | at91_clk_unregister_sam9x5_slow(slowck); | ||
613 | unregister_slow_osc: | ||
614 | clk_hw_unregister(&osc->hw); | ||
615 | free_slow_osc_data: | ||
616 | kfree(osc); | ||
617 | unregister_slow_rc: | ||
618 | clk_hw_unregister(slow_rc); | ||
472 | } | 619 | } |
473 | CLK_OF_DECLARE(sama5d4_clk_sckc, "atmel,sama5d4-sckc", | 620 | CLK_OF_DECLARE(sama5d4_clk_sckc, "atmel,sama5d4-sckc", |
474 | of_sama5d4_sckc_setup); | 621 | of_sama5d4_sckc_setup); |
diff --git a/drivers/clk/bcm/Kconfig b/drivers/clk/bcm/Kconfig index 29ee7b776cd4..8c83977a7dc4 100644 --- a/drivers/clk/bcm/Kconfig +++ b/drivers/clk/bcm/Kconfig | |||
@@ -1,4 +1,13 @@ | |||
1 | # SPDX-License-Identifier: GPL-2.0-only | 1 | # SPDX-License-Identifier: GPL-2.0-only |
2 | config CLK_BCM2835 | ||
3 | bool "Broadcom BCM2835 clock support" | ||
4 | depends on ARCH_BCM2835 || ARCH_BRCMSTB || COMPILE_TEST | ||
5 | depends on COMMON_CLK | ||
6 | default ARCH_BCM2835 || ARCH_BRCMSTB | ||
7 | help | ||
8 | Enable common clock framework support for Broadcom BCM2835 | ||
9 | SoCs. | ||
10 | |||
2 | config CLK_BCM_63XX | 11 | config CLK_BCM_63XX |
3 | bool "Broadcom BCM63xx clock support" | 12 | bool "Broadcom BCM63xx clock support" |
4 | depends on ARCH_BCM_63XX || COMPILE_TEST | 13 | depends on ARCH_BCM_63XX || COMPILE_TEST |
@@ -8,6 +17,14 @@ config CLK_BCM_63XX | |||
8 | Enable common clock framework support for Broadcom BCM63xx DSL SoCs | 17 | Enable common clock framework support for Broadcom BCM63xx DSL SoCs |
9 | based on the ARM architecture | 18 | based on the ARM architecture |
10 | 19 | ||
20 | config CLK_BCM_63XX_GATE | ||
21 | bool "Broadcom BCM63xx gated clock support" | ||
22 | depends on BMIPS_GENERIC || COMPILE_TEST | ||
23 | default BMIPS_GENERIC | ||
24 | help | ||
25 | Enable common clock framework support for Broadcom BCM63xx DSL SoCs | ||
26 | based on the MIPS architecture | ||
27 | |||
11 | config CLK_BCM_KONA | 28 | config CLK_BCM_KONA |
12 | bool "Broadcom Kona CCU clock support" | 29 | bool "Broadcom Kona CCU clock support" |
13 | depends on ARCH_BCM_MOBILE || COMPILE_TEST | 30 | depends on ARCH_BCM_MOBILE || COMPILE_TEST |
@@ -64,3 +81,10 @@ config CLK_BCM_SR | |||
64 | default ARCH_BCM_IPROC | 81 | default ARCH_BCM_IPROC |
65 | help | 82 | help |
66 | Enable common clock framework support for the Broadcom Stingray SoC | 83 | Enable common clock framework support for the Broadcom Stingray SoC |
84 | |||
85 | config CLK_RASPBERRYPI | ||
86 | tristate "Raspberry Pi firmware based clock support" | ||
87 | depends on RASPBERRYPI_FIRMWARE || (COMPILE_TEST && !RASPBERRYPI_FIRMWARE) | ||
88 | help | ||
89 | Enable common clock framework support for Raspberry Pi's firmware | ||
90 | dependent clocks | ||
diff --git a/drivers/clk/bcm/Makefile b/drivers/clk/bcm/Makefile index 002661d39128..0070ddf6cdd2 100644 --- a/drivers/clk/bcm/Makefile +++ b/drivers/clk/bcm/Makefile | |||
@@ -1,12 +1,14 @@ | |||
1 | # SPDX-License-Identifier: GPL-2.0 | 1 | # SPDX-License-Identifier: GPL-2.0 |
2 | obj-$(CONFIG_CLK_BCM_63XX) += clk-bcm63xx.o | 2 | obj-$(CONFIG_CLK_BCM_63XX) += clk-bcm63xx.o |
3 | obj-$(CONFIG_CLK_BCM_63XX_GATE) += clk-bcm63xx-gate.o | ||
3 | obj-$(CONFIG_CLK_BCM_KONA) += clk-kona.o | 4 | obj-$(CONFIG_CLK_BCM_KONA) += clk-kona.o |
4 | obj-$(CONFIG_CLK_BCM_KONA) += clk-kona-setup.o | 5 | obj-$(CONFIG_CLK_BCM_KONA) += clk-kona-setup.o |
5 | obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm281xx.o | 6 | obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm281xx.o |
6 | obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm21664.o | 7 | obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm21664.o |
7 | obj-$(CONFIG_COMMON_CLK_IPROC) += clk-iproc-armpll.o clk-iproc-pll.o clk-iproc-asiu.o | 8 | obj-$(CONFIG_COMMON_CLK_IPROC) += clk-iproc-armpll.o clk-iproc-pll.o clk-iproc-asiu.o |
8 | obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835.o | 9 | obj-$(CONFIG_CLK_BCM2835) += clk-bcm2835.o |
9 | obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835-aux.o | 10 | obj-$(CONFIG_CLK_BCM2835) += clk-bcm2835-aux.o |
11 | obj-$(CONFIG_CLK_RASPBERRYPI) += clk-raspberrypi.o | ||
10 | obj-$(CONFIG_ARCH_BCM_53573) += clk-bcm53573-ilp.o | 12 | obj-$(CONFIG_ARCH_BCM_53573) += clk-bcm53573-ilp.o |
11 | obj-$(CONFIG_CLK_BCM_CYGNUS) += clk-cygnus.o | 13 | obj-$(CONFIG_CLK_BCM_CYGNUS) += clk-cygnus.o |
12 | obj-$(CONFIG_CLK_BCM_HR2) += clk-hr2.o | 14 | obj-$(CONFIG_CLK_BCM_HR2) += clk-hr2.o |
diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c index 770bb01f523e..867ae3c20041 100644 --- a/drivers/clk/bcm/clk-bcm2835.c +++ b/drivers/clk/bcm/clk-bcm2835.c | |||
@@ -1651,30 +1651,10 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { | |||
1651 | .fixed_divider = 1, | 1651 | .fixed_divider = 1, |
1652 | .flags = CLK_SET_RATE_PARENT), | 1652 | .flags = CLK_SET_RATE_PARENT), |
1653 | 1653 | ||
1654 | /* PLLB is used for the ARM's clock. */ | 1654 | /* |
1655 | [BCM2835_PLLB] = REGISTER_PLL( | 1655 | * PLLB is used for the ARM's clock. Controlled by firmware, see |
1656 | .name = "pllb", | 1656 | * clk-raspberrypi.c. |
1657 | .cm_ctrl_reg = CM_PLLB, | 1657 | */ |
1658 | .a2w_ctrl_reg = A2W_PLLB_CTRL, | ||
1659 | .frac_reg = A2W_PLLB_FRAC, | ||
1660 | .ana_reg_base = A2W_PLLB_ANA0, | ||
1661 | .reference_enable_mask = A2W_XOSC_CTRL_PLLB_ENABLE, | ||
1662 | .lock_mask = CM_LOCK_FLOCKB, | ||
1663 | |||
1664 | .ana = &bcm2835_ana_default, | ||
1665 | |||
1666 | .min_rate = 600000000u, | ||
1667 | .max_rate = 3000000000u, | ||
1668 | .max_fb_rate = BCM2835_MAX_FB_RATE), | ||
1669 | [BCM2835_PLLB_ARM] = REGISTER_PLL_DIV( | ||
1670 | .name = "pllb_arm", | ||
1671 | .source_pll = "pllb", | ||
1672 | .cm_reg = CM_PLLB, | ||
1673 | .a2w_reg = A2W_PLLB_ARM, | ||
1674 | .load_mask = CM_PLLB_LOADARM, | ||
1675 | .hold_mask = CM_PLLB_HOLDARM, | ||
1676 | .fixed_divider = 1, | ||
1677 | .flags = CLK_SET_RATE_PARENT), | ||
1678 | 1658 | ||
1679 | /* | 1659 | /* |
1680 | * PLLC is the core PLL, used to drive the core VPU clock. | 1660 | * PLLC is the core PLL, used to drive the core VPU clock. |
diff --git a/drivers/clk/bcm/clk-bcm63xx-gate.c b/drivers/clk/bcm/clk-bcm63xx-gate.c new file mode 100644 index 000000000000..9e1dcd43258c --- /dev/null +++ b/drivers/clk/bcm/clk-bcm63xx-gate.c | |||
@@ -0,0 +1,238 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | |||
3 | #include <linux/clk-provider.h> | ||
4 | #include <linux/init.h> | ||
5 | #include <linux/of.h> | ||
6 | #include <linux/of_device.h> | ||
7 | #include <linux/platform_device.h> | ||
8 | |||
9 | struct clk_bcm63xx_table_entry { | ||
10 | const char * const name; | ||
11 | u8 bit; | ||
12 | unsigned long flags; | ||
13 | }; | ||
14 | |||
15 | struct clk_bcm63xx_hw { | ||
16 | void __iomem *regs; | ||
17 | spinlock_t lock; | ||
18 | |||
19 | struct clk_hw_onecell_data data; | ||
20 | }; | ||
21 | |||
22 | static const struct clk_bcm63xx_table_entry bcm3368_clocks[] = { | ||
23 | { .name = "mac", .bit = 3, }, | ||
24 | { .name = "tc", .bit = 5, }, | ||
25 | { .name = "us_top", .bit = 6, }, | ||
26 | { .name = "ds_top", .bit = 7, }, | ||
27 | { .name = "acm", .bit = 8, }, | ||
28 | { .name = "spi", .bit = 9, }, | ||
29 | { .name = "usbs", .bit = 10, }, | ||
30 | { .name = "bmu", .bit = 11, }, | ||
31 | { .name = "pcm", .bit = 12, }, | ||
32 | { .name = "ntp", .bit = 13, }, | ||
33 | { .name = "acp_b", .bit = 14, }, | ||
34 | { .name = "acp_a", .bit = 15, }, | ||
35 | { .name = "emusb", .bit = 17, }, | ||
36 | { .name = "enet0", .bit = 18, }, | ||
37 | { .name = "enet1", .bit = 19, }, | ||
38 | { .name = "usbsu", .bit = 20, }, | ||
39 | { .name = "ephy", .bit = 21, }, | ||
40 | { }, | ||
41 | }; | ||
42 | |||
43 | static const struct clk_bcm63xx_table_entry bcm6328_clocks[] = { | ||
44 | { .name = "phy_mips", .bit = 0, }, | ||
45 | { .name = "adsl_qproc", .bit = 1, }, | ||
46 | { .name = "adsl_afe", .bit = 2, }, | ||
47 | { .name = "adsl", .bit = 3, }, | ||
48 | { .name = "mips", .bit = 4, .flags = CLK_IS_CRITICAL, }, | ||
49 | { .name = "sar", .bit = 5, }, | ||
50 | { .name = "pcm", .bit = 6, }, | ||
51 | { .name = "usbd", .bit = 7, }, | ||
52 | { .name = "usbh", .bit = 8, }, | ||
53 | { .name = "hsspi", .bit = 9, }, | ||
54 | { .name = "pcie", .bit = 10, }, | ||
55 | { .name = "robosw", .bit = 11, }, | ||
56 | { }, | ||
57 | }; | ||
58 | |||
59 | static const struct clk_bcm63xx_table_entry bcm6358_clocks[] = { | ||
60 | { .name = "enet", .bit = 4, }, | ||
61 | { .name = "adslphy", .bit = 5, }, | ||
62 | { .name = "pcm", .bit = 8, }, | ||
63 | { .name = "spi", .bit = 9, }, | ||
64 | { .name = "usbs", .bit = 10, }, | ||
65 | { .name = "sar", .bit = 11, }, | ||
66 | { .name = "emusb", .bit = 17, }, | ||
67 | { .name = "enet0", .bit = 18, }, | ||
68 | { .name = "enet1", .bit = 19, }, | ||
69 | { .name = "usbsu", .bit = 20, }, | ||
70 | { .name = "ephy", .bit = 21, }, | ||
71 | { }, | ||
72 | }; | ||
73 | |||
74 | static const struct clk_bcm63xx_table_entry bcm6362_clocks[] = { | ||
75 | { .name = "adsl_qproc", .bit = 1, }, | ||
76 | { .name = "adsl_afe", .bit = 2, }, | ||
77 | { .name = "adsl", .bit = 3, }, | ||
78 | { .name = "mips", .bit = 4, .flags = CLK_IS_CRITICAL, }, | ||
79 | { .name = "wlan_ocp", .bit = 5, }, | ||
80 | { .name = "swpkt_usb", .bit = 7, }, | ||
81 | { .name = "swpkt_sar", .bit = 8, }, | ||
82 | { .name = "sar", .bit = 9, }, | ||
83 | { .name = "robosw", .bit = 10, }, | ||
84 | { .name = "pcm", .bit = 11, }, | ||
85 | { .name = "usbd", .bit = 12, }, | ||
86 | { .name = "usbh", .bit = 13, }, | ||
87 | { .name = "ipsec", .bit = 14, }, | ||
88 | { .name = "spi", .bit = 15, }, | ||
89 | { .name = "hsspi", .bit = 16, }, | ||
90 | { .name = "pcie", .bit = 17, }, | ||
91 | { .name = "fap", .bit = 18, }, | ||
92 | { .name = "phymips", .bit = 19, }, | ||
93 | { .name = "nand", .bit = 20, }, | ||
94 | { }, | ||
95 | }; | ||
96 | |||
97 | static const struct clk_bcm63xx_table_entry bcm6368_clocks[] = { | ||
98 | { .name = "vdsl_qproc", .bit = 2, }, | ||
99 | { .name = "vdsl_afe", .bit = 3, }, | ||
100 | { .name = "vdsl_bonding", .bit = 4, }, | ||
101 | { .name = "vdsl", .bit = 5, }, | ||
102 | { .name = "phymips", .bit = 6, }, | ||
103 | { .name = "swpkt_usb", .bit = 7, }, | ||
104 | { .name = "swpkt_sar", .bit = 8, }, | ||
105 | { .name = "spi", .bit = 9, }, | ||
106 | { .name = "usbd", .bit = 10, }, | ||
107 | { .name = "sar", .bit = 11, }, | ||
108 | { .name = "robosw", .bit = 12, }, | ||
109 | { .name = "utopia", .bit = 13, }, | ||
110 | { .name = "pcm", .bit = 14, }, | ||
111 | { .name = "usbh", .bit = 15, }, | ||
112 | { .name = "disable_gless", .bit = 16, }, | ||
113 | { .name = "nand", .bit = 17, }, | ||
114 | { .name = "ipsec", .bit = 18, }, | ||
115 | { }, | ||
116 | }; | ||
117 | |||
118 | static const struct clk_bcm63xx_table_entry bcm63268_clocks[] = { | ||
119 | { .name = "disable_gless", .bit = 0, }, | ||
120 | { .name = "vdsl_qproc", .bit = 1, }, | ||
121 | { .name = "vdsl_afe", .bit = 2, }, | ||
122 | { .name = "vdsl", .bit = 3, }, | ||
123 | { .name = "mips", .bit = 4, .flags = CLK_IS_CRITICAL, }, | ||
124 | { .name = "wlan_ocp", .bit = 5, }, | ||
125 | { .name = "dect", .bit = 6, }, | ||
126 | { .name = "fap0", .bit = 7, }, | ||
127 | { .name = "fap1", .bit = 8, }, | ||
128 | { .name = "sar", .bit = 9, }, | ||
129 | { .name = "robosw", .bit = 10, }, | ||
130 | { .name = "pcm", .bit = 11, }, | ||
131 | { .name = "usbd", .bit = 12, }, | ||
132 | { .name = "usbh", .bit = 13, }, | ||
133 | { .name = "ipsec", .bit = 14, }, | ||
134 | { .name = "spi", .bit = 15, }, | ||
135 | { .name = "hsspi", .bit = 16, }, | ||
136 | { .name = "pcie", .bit = 17, }, | ||
137 | { .name = "phymips", .bit = 18, }, | ||
138 | { .name = "gmac", .bit = 19, }, | ||
139 | { .name = "nand", .bit = 20, }, | ||
140 | { .name = "tbus", .bit = 27, }, | ||
141 | { .name = "robosw250", .bit = 31, }, | ||
142 | { }, | ||
143 | }; | ||
144 | |||
145 | static int clk_bcm63xx_probe(struct platform_device *pdev) | ||
146 | { | ||
147 | const struct clk_bcm63xx_table_entry *entry, *table; | ||
148 | struct clk_bcm63xx_hw *hw; | ||
149 | struct resource *r; | ||
150 | u8 maxbit = 0; | ||
151 | int i, ret; | ||
152 | |||
153 | table = of_device_get_match_data(&pdev->dev); | ||
154 | if (!table) | ||
155 | return -EINVAL; | ||
156 | |||
157 | for (entry = table; entry->name; entry++) | ||
158 | maxbit = max_t(u8, maxbit, entry->bit); | ||
159 | |||
160 | hw = devm_kzalloc(&pdev->dev, struct_size(hw, data.hws, maxbit), | ||
161 | GFP_KERNEL); | ||
162 | if (!hw) | ||
163 | return -ENOMEM; | ||
164 | |||
165 | platform_set_drvdata(pdev, hw); | ||
166 | |||
167 | spin_lock_init(&hw->lock); | ||
168 | |||
169 | hw->data.num = maxbit; | ||
170 | for (i = 0; i < maxbit; i++) | ||
171 | hw->data.hws[i] = ERR_PTR(-ENODEV); | ||
172 | |||
173 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
174 | hw->regs = devm_ioremap_resource(&pdev->dev, r); | ||
175 | if (IS_ERR(hw->regs)) | ||
176 | return PTR_ERR(hw->regs); | ||
177 | |||
178 | for (entry = table; entry->name; entry++) { | ||
179 | struct clk_hw *clk; | ||
180 | |||
181 | clk = clk_hw_register_gate(&pdev->dev, entry->name, NULL, | ||
182 | entry->flags, hw->regs, entry->bit, | ||
183 | CLK_GATE_BIG_ENDIAN, &hw->lock); | ||
184 | if (IS_ERR(clk)) { | ||
185 | ret = PTR_ERR(clk); | ||
186 | goto out_err; | ||
187 | } | ||
188 | |||
189 | hw->data.hws[entry->bit] = clk; | ||
190 | } | ||
191 | |||
192 | ret = of_clk_add_hw_provider(pdev->dev.of_node, of_clk_hw_onecell_get, | ||
193 | &hw->data); | ||
194 | if (!ret) | ||
195 | return 0; | ||
196 | out_err: | ||
197 | for (i = 0; i < hw->data.num; i++) { | ||
198 | if (!IS_ERR(hw->data.hws[i])) | ||
199 | clk_hw_unregister_gate(hw->data.hws[i]); | ||
200 | } | ||
201 | |||
202 | return ret; | ||
203 | } | ||
204 | |||
205 | static int clk_bcm63xx_remove(struct platform_device *pdev) | ||
206 | { | ||
207 | struct clk_bcm63xx_hw *hw = platform_get_drvdata(pdev); | ||
208 | int i; | ||
209 | |||
210 | of_clk_del_provider(pdev->dev.of_node); | ||
211 | |||
212 | for (i = 0; i < hw->data.num; i++) { | ||
213 | if (!IS_ERR(hw->data.hws[i])) | ||
214 | clk_hw_unregister_gate(hw->data.hws[i]); | ||
215 | } | ||
216 | |||
217 | return 0; | ||
218 | } | ||
219 | |||
220 | static const struct of_device_id clk_bcm63xx_dt_ids[] = { | ||
221 | { .compatible = "brcm,bcm3368-clocks", .data = &bcm3368_clocks, }, | ||
222 | { .compatible = "brcm,bcm6328-clocks", .data = &bcm6328_clocks, }, | ||
223 | { .compatible = "brcm,bcm6358-clocks", .data = &bcm6358_clocks, }, | ||
224 | { .compatible = "brcm,bcm6362-clocks", .data = &bcm6362_clocks, }, | ||
225 | { .compatible = "brcm,bcm6368-clocks", .data = &bcm6368_clocks, }, | ||
226 | { .compatible = "brcm,bcm63268-clocks", .data = &bcm63268_clocks, }, | ||
227 | { } | ||
228 | }; | ||
229 | |||
230 | static struct platform_driver clk_bcm63xx = { | ||
231 | .probe = clk_bcm63xx_probe, | ||
232 | .remove = clk_bcm63xx_remove, | ||
233 | .driver = { | ||
234 | .name = "bcm63xx-clock", | ||
235 | .of_match_table = clk_bcm63xx_dt_ids, | ||
236 | }, | ||
237 | }; | ||
238 | builtin_platform_driver(clk_bcm63xx); | ||
diff --git a/drivers/clk/bcm/clk-raspberrypi.c b/drivers/clk/bcm/clk-raspberrypi.c new file mode 100644 index 000000000000..1654fd0eedc9 --- /dev/null +++ b/drivers/clk/bcm/clk-raspberrypi.c | |||
@@ -0,0 +1,315 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0+ | ||
2 | /* | ||
3 | * Raspberry Pi driver for firmware controlled clocks | ||
4 | * | ||
5 | * Even though clk-bcm2835 provides an interface to the hardware registers for | ||
6 | * the system clocks we've had to factor out 'pllb' as the firmware 'owns' it. | ||
7 | * We're not allowed to change it directly as we might race with the | ||
8 | * over-temperature and under-voltage protections provided by the firmware. | ||
9 | * | ||
10 | * Copyright (C) 2019 Nicolas Saenz Julienne <nsaenzjulienne@suse.de> | ||
11 | */ | ||
12 | |||
13 | #include <linux/clkdev.h> | ||
14 | #include <linux/clk-provider.h> | ||
15 | #include <linux/io.h> | ||
16 | #include <linux/module.h> | ||
17 | #include <linux/platform_device.h> | ||
18 | |||
19 | #include <soc/bcm2835/raspberrypi-firmware.h> | ||
20 | |||
21 | #define RPI_FIRMWARE_ARM_CLK_ID 0x00000003 | ||
22 | |||
23 | #define RPI_FIRMWARE_STATE_ENABLE_BIT BIT(0) | ||
24 | #define RPI_FIRMWARE_STATE_WAIT_BIT BIT(1) | ||
25 | |||
26 | /* | ||
27 | * Even though the firmware interface alters 'pllb' the frequencies are | ||
28 | * provided as per 'pllb_arm'. We need to scale before passing them trough. | ||
29 | */ | ||
30 | #define RPI_FIRMWARE_PLLB_ARM_DIV_RATE 2 | ||
31 | |||
32 | #define A2W_PLL_FRAC_BITS 20 | ||
33 | |||
34 | struct raspberrypi_clk { | ||
35 | struct device *dev; | ||
36 | struct rpi_firmware *firmware; | ||
37 | struct platform_device *cpufreq; | ||
38 | |||
39 | unsigned long min_rate; | ||
40 | unsigned long max_rate; | ||
41 | |||
42 | struct clk_hw pllb; | ||
43 | struct clk_hw *pllb_arm; | ||
44 | struct clk_lookup *pllb_arm_lookup; | ||
45 | }; | ||
46 | |||
47 | /* | ||
48 | * Structure of the message passed to Raspberry Pi's firmware in order to | ||
49 | * change clock rates. The 'disable_turbo' option is only available to the ARM | ||
50 | * clock (pllb) which we enable by default as turbo mode will alter multiple | ||
51 | * clocks at once. | ||
52 | * | ||
53 | * Even though we're able to access the clock registers directly we're bound to | ||
54 | * use the firmware interface as the firmware ultimately takes care of | ||
55 | * mitigating overheating/undervoltage situations and we would be changing | ||
56 | * frequencies behind his back. | ||
57 | * | ||
58 | * For more information on the firmware interface check: | ||
59 | * https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface | ||
60 | */ | ||
61 | struct raspberrypi_firmware_prop { | ||
62 | __le32 id; | ||
63 | __le32 val; | ||
64 | __le32 disable_turbo; | ||
65 | } __packed; | ||
66 | |||
67 | static int raspberrypi_clock_property(struct rpi_firmware *firmware, u32 tag, | ||
68 | u32 clk, u32 *val) | ||
69 | { | ||
70 | struct raspberrypi_firmware_prop msg = { | ||
71 | .id = cpu_to_le32(clk), | ||
72 | .val = cpu_to_le32(*val), | ||
73 | .disable_turbo = cpu_to_le32(1), | ||
74 | }; | ||
75 | int ret; | ||
76 | |||
77 | ret = rpi_firmware_property(firmware, tag, &msg, sizeof(msg)); | ||
78 | if (ret) | ||
79 | return ret; | ||
80 | |||
81 | *val = le32_to_cpu(msg.val); | ||
82 | |||
83 | return 0; | ||
84 | } | ||
85 | |||
86 | static int raspberrypi_fw_pll_is_on(struct clk_hw *hw) | ||
87 | { | ||
88 | struct raspberrypi_clk *rpi = container_of(hw, struct raspberrypi_clk, | ||
89 | pllb); | ||
90 | u32 val = 0; | ||
91 | int ret; | ||
92 | |||
93 | ret = raspberrypi_clock_property(rpi->firmware, | ||
94 | RPI_FIRMWARE_GET_CLOCK_STATE, | ||
95 | RPI_FIRMWARE_ARM_CLK_ID, &val); | ||
96 | if (ret) | ||
97 | return 0; | ||
98 | |||
99 | return !!(val & RPI_FIRMWARE_STATE_ENABLE_BIT); | ||
100 | } | ||
101 | |||
102 | |||
103 | static unsigned long raspberrypi_fw_pll_get_rate(struct clk_hw *hw, | ||
104 | unsigned long parent_rate) | ||
105 | { | ||
106 | struct raspberrypi_clk *rpi = container_of(hw, struct raspberrypi_clk, | ||
107 | pllb); | ||
108 | u32 val = 0; | ||
109 | int ret; | ||
110 | |||
111 | ret = raspberrypi_clock_property(rpi->firmware, | ||
112 | RPI_FIRMWARE_GET_CLOCK_RATE, | ||
113 | RPI_FIRMWARE_ARM_CLK_ID, | ||
114 | &val); | ||
115 | if (ret) | ||
116 | return ret; | ||
117 | |||
118 | return val * RPI_FIRMWARE_PLLB_ARM_DIV_RATE; | ||
119 | } | ||
120 | |||
121 | static int raspberrypi_fw_pll_set_rate(struct clk_hw *hw, unsigned long rate, | ||
122 | unsigned long parent_rate) | ||
123 | { | ||
124 | struct raspberrypi_clk *rpi = container_of(hw, struct raspberrypi_clk, | ||
125 | pllb); | ||
126 | u32 new_rate = rate / RPI_FIRMWARE_PLLB_ARM_DIV_RATE; | ||
127 | int ret; | ||
128 | |||
129 | ret = raspberrypi_clock_property(rpi->firmware, | ||
130 | RPI_FIRMWARE_SET_CLOCK_RATE, | ||
131 | RPI_FIRMWARE_ARM_CLK_ID, | ||
132 | &new_rate); | ||
133 | if (ret) | ||
134 | dev_err_ratelimited(rpi->dev, "Failed to change %s frequency: %d", | ||
135 | clk_hw_get_name(hw), ret); | ||
136 | |||
137 | return ret; | ||
138 | } | ||
139 | |||
140 | /* | ||
141 | * Sadly there is no firmware rate rounding interface. We borrowed it from | ||
142 | * clk-bcm2835. | ||
143 | */ | ||
144 | static int raspberrypi_pll_determine_rate(struct clk_hw *hw, | ||
145 | struct clk_rate_request *req) | ||
146 | { | ||
147 | struct raspberrypi_clk *rpi = container_of(hw, struct raspberrypi_clk, | ||
148 | pllb); | ||
149 | u64 div, final_rate; | ||
150 | u32 ndiv, fdiv; | ||
151 | |||
152 | /* We can't use req->rate directly as it would overflow */ | ||
153 | final_rate = clamp(req->rate, rpi->min_rate, rpi->max_rate); | ||
154 | |||
155 | div = (u64)final_rate << A2W_PLL_FRAC_BITS; | ||
156 | do_div(div, req->best_parent_rate); | ||
157 | |||
158 | ndiv = div >> A2W_PLL_FRAC_BITS; | ||
159 | fdiv = div & ((1 << A2W_PLL_FRAC_BITS) - 1); | ||
160 | |||
161 | final_rate = ((u64)req->best_parent_rate * | ||
162 | ((ndiv << A2W_PLL_FRAC_BITS) + fdiv)); | ||
163 | |||
164 | req->rate = final_rate >> A2W_PLL_FRAC_BITS; | ||
165 | |||
166 | return 0; | ||
167 | } | ||
168 | |||
169 | static const struct clk_ops raspberrypi_firmware_pll_clk_ops = { | ||
170 | .is_prepared = raspberrypi_fw_pll_is_on, | ||
171 | .recalc_rate = raspberrypi_fw_pll_get_rate, | ||
172 | .set_rate = raspberrypi_fw_pll_set_rate, | ||
173 | .determine_rate = raspberrypi_pll_determine_rate, | ||
174 | }; | ||
175 | |||
176 | static int raspberrypi_register_pllb(struct raspberrypi_clk *rpi) | ||
177 | { | ||
178 | u32 min_rate = 0, max_rate = 0; | ||
179 | struct clk_init_data init; | ||
180 | int ret; | ||
181 | |||
182 | memset(&init, 0, sizeof(init)); | ||
183 | |||
184 | /* All of the PLLs derive from the external oscillator. */ | ||
185 | init.parent_names = (const char *[]){ "osc" }; | ||
186 | init.num_parents = 1; | ||
187 | init.name = "pllb"; | ||
188 | init.ops = &raspberrypi_firmware_pll_clk_ops; | ||
189 | init.flags = CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED; | ||
190 | |||
191 | /* Get min & max rates set by the firmware */ | ||
192 | ret = raspberrypi_clock_property(rpi->firmware, | ||
193 | RPI_FIRMWARE_GET_MIN_CLOCK_RATE, | ||
194 | RPI_FIRMWARE_ARM_CLK_ID, | ||
195 | &min_rate); | ||
196 | if (ret) { | ||
197 | dev_err(rpi->dev, "Failed to get %s min freq: %d\n", | ||
198 | init.name, ret); | ||
199 | return ret; | ||
200 | } | ||
201 | |||
202 | ret = raspberrypi_clock_property(rpi->firmware, | ||
203 | RPI_FIRMWARE_GET_MAX_CLOCK_RATE, | ||
204 | RPI_FIRMWARE_ARM_CLK_ID, | ||
205 | &max_rate); | ||
206 | if (ret) { | ||
207 | dev_err(rpi->dev, "Failed to get %s max freq: %d\n", | ||
208 | init.name, ret); | ||
209 | return ret; | ||
210 | } | ||
211 | |||
212 | if (!min_rate || !max_rate) { | ||
213 | dev_err(rpi->dev, "Unexpected frequency range: min %u, max %u\n", | ||
214 | min_rate, max_rate); | ||
215 | return -EINVAL; | ||
216 | } | ||
217 | |||
218 | dev_info(rpi->dev, "CPU frequency range: min %u, max %u\n", | ||
219 | min_rate, max_rate); | ||
220 | |||
221 | rpi->min_rate = min_rate * RPI_FIRMWARE_PLLB_ARM_DIV_RATE; | ||
222 | rpi->max_rate = max_rate * RPI_FIRMWARE_PLLB_ARM_DIV_RATE; | ||
223 | |||
224 | rpi->pllb.init = &init; | ||
225 | |||
226 | return devm_clk_hw_register(rpi->dev, &rpi->pllb); | ||
227 | } | ||
228 | |||
229 | static int raspberrypi_register_pllb_arm(struct raspberrypi_clk *rpi) | ||
230 | { | ||
231 | rpi->pllb_arm = clk_hw_register_fixed_factor(rpi->dev, | ||
232 | "pllb_arm", "pllb", | ||
233 | CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, | ||
234 | 1, 2); | ||
235 | if (IS_ERR(rpi->pllb_arm)) { | ||
236 | dev_err(rpi->dev, "Failed to initialize pllb_arm\n"); | ||
237 | return PTR_ERR(rpi->pllb_arm); | ||
238 | } | ||
239 | |||
240 | rpi->pllb_arm_lookup = clkdev_hw_create(rpi->pllb_arm, NULL, "cpu0"); | ||
241 | if (!rpi->pllb_arm_lookup) { | ||
242 | dev_err(rpi->dev, "Failed to initialize pllb_arm_lookup\n"); | ||
243 | clk_hw_unregister_fixed_factor(rpi->pllb_arm); | ||
244 | return -ENOMEM; | ||
245 | } | ||
246 | |||
247 | return 0; | ||
248 | } | ||
249 | |||
250 | static int raspberrypi_clk_probe(struct platform_device *pdev) | ||
251 | { | ||
252 | struct device_node *firmware_node; | ||
253 | struct device *dev = &pdev->dev; | ||
254 | struct rpi_firmware *firmware; | ||
255 | struct raspberrypi_clk *rpi; | ||
256 | int ret; | ||
257 | |||
258 | firmware_node = of_find_compatible_node(NULL, NULL, | ||
259 | "raspberrypi,bcm2835-firmware"); | ||
260 | if (!firmware_node) { | ||
261 | dev_err(dev, "Missing firmware node\n"); | ||
262 | return -ENOENT; | ||
263 | } | ||
264 | |||
265 | firmware = rpi_firmware_get(firmware_node); | ||
266 | of_node_put(firmware_node); | ||
267 | if (!firmware) | ||
268 | return -EPROBE_DEFER; | ||
269 | |||
270 | rpi = devm_kzalloc(dev, sizeof(*rpi), GFP_KERNEL); | ||
271 | if (!rpi) | ||
272 | return -ENOMEM; | ||
273 | |||
274 | rpi->dev = dev; | ||
275 | rpi->firmware = firmware; | ||
276 | platform_set_drvdata(pdev, rpi); | ||
277 | |||
278 | ret = raspberrypi_register_pllb(rpi); | ||
279 | if (ret) { | ||
280 | dev_err(dev, "Failed to initialize pllb, %d\n", ret); | ||
281 | return ret; | ||
282 | } | ||
283 | |||
284 | ret = raspberrypi_register_pllb_arm(rpi); | ||
285 | if (ret) | ||
286 | return ret; | ||
287 | |||
288 | rpi->cpufreq = platform_device_register_data(dev, "raspberrypi-cpufreq", | ||
289 | -1, NULL, 0); | ||
290 | |||
291 | return 0; | ||
292 | } | ||
293 | |||
294 | static int raspberrypi_clk_remove(struct platform_device *pdev) | ||
295 | { | ||
296 | struct raspberrypi_clk *rpi = platform_get_drvdata(pdev); | ||
297 | |||
298 | platform_device_unregister(rpi->cpufreq); | ||
299 | |||
300 | return 0; | ||
301 | } | ||
302 | |||
303 | static struct platform_driver raspberrypi_clk_driver = { | ||
304 | .driver = { | ||
305 | .name = "raspberrypi-clk", | ||
306 | }, | ||
307 | .probe = raspberrypi_clk_probe, | ||
308 | .remove = raspberrypi_clk_remove, | ||
309 | }; | ||
310 | module_platform_driver(raspberrypi_clk_driver); | ||
311 | |||
312 | MODULE_AUTHOR("Nicolas Saenz Julienne <nsaenzjulienne@suse.de>"); | ||
313 | MODULE_DESCRIPTION("Raspberry Pi firmware clock driver"); | ||
314 | MODULE_LICENSE("GPL"); | ||
315 | MODULE_ALIAS("platform:raspberrypi-clk"); | ||
diff --git a/drivers/clk/clk-bulk.c b/drivers/clk/clk-bulk.c index 06499568cf07..524bf9a53098 100644 --- a/drivers/clk/clk-bulk.c +++ b/drivers/clk/clk-bulk.c | |||
@@ -75,8 +75,8 @@ void clk_bulk_put(int num_clks, struct clk_bulk_data *clks) | |||
75 | } | 75 | } |
76 | EXPORT_SYMBOL_GPL(clk_bulk_put); | 76 | EXPORT_SYMBOL_GPL(clk_bulk_put); |
77 | 77 | ||
78 | int __must_check clk_bulk_get(struct device *dev, int num_clks, | 78 | static int __clk_bulk_get(struct device *dev, int num_clks, |
79 | struct clk_bulk_data *clks) | 79 | struct clk_bulk_data *clks, bool optional) |
80 | { | 80 | { |
81 | int ret; | 81 | int ret; |
82 | int i; | 82 | int i; |
@@ -88,10 +88,14 @@ int __must_check clk_bulk_get(struct device *dev, int num_clks, | |||
88 | clks[i].clk = clk_get(dev, clks[i].id); | 88 | clks[i].clk = clk_get(dev, clks[i].id); |
89 | if (IS_ERR(clks[i].clk)) { | 89 | if (IS_ERR(clks[i].clk)) { |
90 | ret = PTR_ERR(clks[i].clk); | 90 | ret = PTR_ERR(clks[i].clk); |
91 | clks[i].clk = NULL; | ||
92 | |||
93 | if (ret == -ENOENT && optional) | ||
94 | continue; | ||
95 | |||
91 | if (ret != -EPROBE_DEFER) | 96 | if (ret != -EPROBE_DEFER) |
92 | dev_err(dev, "Failed to get clk '%s': %d\n", | 97 | dev_err(dev, "Failed to get clk '%s': %d\n", |
93 | clks[i].id, ret); | 98 | clks[i].id, ret); |
94 | clks[i].clk = NULL; | ||
95 | goto err; | 99 | goto err; |
96 | } | 100 | } |
97 | } | 101 | } |
@@ -103,8 +107,21 @@ err: | |||
103 | 107 | ||
104 | return ret; | 108 | return ret; |
105 | } | 109 | } |
110 | |||
111 | int __must_check clk_bulk_get(struct device *dev, int num_clks, | ||
112 | struct clk_bulk_data *clks) | ||
113 | { | ||
114 | return __clk_bulk_get(dev, num_clks, clks, false); | ||
115 | } | ||
106 | EXPORT_SYMBOL(clk_bulk_get); | 116 | EXPORT_SYMBOL(clk_bulk_get); |
107 | 117 | ||
118 | int __must_check clk_bulk_get_optional(struct device *dev, int num_clks, | ||
119 | struct clk_bulk_data *clks) | ||
120 | { | ||
121 | return __clk_bulk_get(dev, num_clks, clks, true); | ||
122 | } | ||
123 | EXPORT_SYMBOL_GPL(clk_bulk_get_optional); | ||
124 | |||
108 | void clk_bulk_put_all(int num_clks, struct clk_bulk_data *clks) | 125 | void clk_bulk_put_all(int num_clks, struct clk_bulk_data *clks) |
109 | { | 126 | { |
110 | if (IS_ERR_OR_NULL(clks)) | 127 | if (IS_ERR_OR_NULL(clks)) |
diff --git a/drivers/clk/clk-cdce706.c b/drivers/clk/clk-cdce706.c index 0443dfc82794..239102e37e2f 100644 --- a/drivers/clk/clk-cdce706.c +++ b/drivers/clk/clk-cdce706.c | |||
@@ -630,7 +630,7 @@ of_clk_cdce_get(struct of_phandle_args *clkspec, void *data) | |||
630 | static int cdce706_probe(struct i2c_client *client, | 630 | static int cdce706_probe(struct i2c_client *client, |
631 | const struct i2c_device_id *id) | 631 | const struct i2c_device_id *id) |
632 | { | 632 | { |
633 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); | 633 | struct i2c_adapter *adapter = client->adapter; |
634 | struct cdce706_dev_data *cdce; | 634 | struct cdce706_dev_data *cdce; |
635 | int ret; | 635 | int ret; |
636 | 636 | ||
diff --git a/drivers/clk/clk-devres.c b/drivers/clk/clk-devres.c index daa1fc8fba53..be160764911b 100644 --- a/drivers/clk/clk-devres.c +++ b/drivers/clk/clk-devres.c | |||
@@ -52,8 +52,8 @@ static void devm_clk_bulk_release(struct device *dev, void *res) | |||
52 | clk_bulk_put(devres->num_clks, devres->clks); | 52 | clk_bulk_put(devres->num_clks, devres->clks); |
53 | } | 53 | } |
54 | 54 | ||
55 | int __must_check devm_clk_bulk_get(struct device *dev, int num_clks, | 55 | static int __devm_clk_bulk_get(struct device *dev, int num_clks, |
56 | struct clk_bulk_data *clks) | 56 | struct clk_bulk_data *clks, bool optional) |
57 | { | 57 | { |
58 | struct clk_bulk_devres *devres; | 58 | struct clk_bulk_devres *devres; |
59 | int ret; | 59 | int ret; |
@@ -63,7 +63,10 @@ int __must_check devm_clk_bulk_get(struct device *dev, int num_clks, | |||
63 | if (!devres) | 63 | if (!devres) |
64 | return -ENOMEM; | 64 | return -ENOMEM; |
65 | 65 | ||
66 | ret = clk_bulk_get(dev, num_clks, clks); | 66 | if (optional) |
67 | ret = clk_bulk_get_optional(dev, num_clks, clks); | ||
68 | else | ||
69 | ret = clk_bulk_get(dev, num_clks, clks); | ||
67 | if (!ret) { | 70 | if (!ret) { |
68 | devres->clks = clks; | 71 | devres->clks = clks; |
69 | devres->num_clks = num_clks; | 72 | devres->num_clks = num_clks; |
@@ -74,8 +77,21 @@ int __must_check devm_clk_bulk_get(struct device *dev, int num_clks, | |||
74 | 77 | ||
75 | return ret; | 78 | return ret; |
76 | } | 79 | } |
80 | |||
81 | int __must_check devm_clk_bulk_get(struct device *dev, int num_clks, | ||
82 | struct clk_bulk_data *clks) | ||
83 | { | ||
84 | return __devm_clk_bulk_get(dev, num_clks, clks, false); | ||
85 | } | ||
77 | EXPORT_SYMBOL_GPL(devm_clk_bulk_get); | 86 | EXPORT_SYMBOL_GPL(devm_clk_bulk_get); |
78 | 87 | ||
88 | int __must_check devm_clk_bulk_get_optional(struct device *dev, int num_clks, | ||
89 | struct clk_bulk_data *clks) | ||
90 | { | ||
91 | return __devm_clk_bulk_get(dev, num_clks, clks, true); | ||
92 | } | ||
93 | EXPORT_SYMBOL_GPL(devm_clk_bulk_get_optional); | ||
94 | |||
79 | int __must_check devm_clk_bulk_get_all(struct device *dev, | 95 | int __must_check devm_clk_bulk_get_all(struct device *dev, |
80 | struct clk_bulk_data **clks) | 96 | struct clk_bulk_data **clks) |
81 | { | 97 | { |
diff --git a/drivers/clk/clk-lochnagar.c b/drivers/clk/clk-lochnagar.c index a2f31e58ee48..fa8c91758b1d 100644 --- a/drivers/clk/clk-lochnagar.c +++ b/drivers/clk/clk-lochnagar.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
17 | #include <linux/regmap.h> | 17 | #include <linux/regmap.h> |
18 | 18 | ||
19 | #include <linux/mfd/lochnagar.h> | ||
20 | #include <linux/mfd/lochnagar1_regs.h> | 19 | #include <linux/mfd/lochnagar1_regs.h> |
21 | #include <linux/mfd/lochnagar2_regs.h> | 20 | #include <linux/mfd/lochnagar2_regs.h> |
22 | 21 | ||
@@ -40,48 +39,46 @@ struct lochnagar_clk { | |||
40 | struct lochnagar_clk_priv { | 39 | struct lochnagar_clk_priv { |
41 | struct device *dev; | 40 | struct device *dev; |
42 | struct regmap *regmap; | 41 | struct regmap *regmap; |
43 | enum lochnagar_type type; | ||
44 | |||
45 | const char **parents; | ||
46 | unsigned int nparents; | ||
47 | 42 | ||
48 | struct lochnagar_clk lclks[LOCHNAGAR_NUM_CLOCKS]; | 43 | struct lochnagar_clk lclks[LOCHNAGAR_NUM_CLOCKS]; |
49 | }; | 44 | }; |
50 | 45 | ||
51 | static const char * const lochnagar1_clk_parents[] = { | 46 | #define LN_PARENT(NAME) { .name = NAME, .fw_name = NAME } |
52 | "ln-none", | 47 | |
53 | "ln-spdif-mclk", | 48 | static const struct clk_parent_data lochnagar1_clk_parents[] = { |
54 | "ln-psia1-mclk", | 49 | LN_PARENT("ln-none"), |
55 | "ln-psia2-mclk", | 50 | LN_PARENT("ln-spdif-mclk"), |
56 | "ln-cdc-clkout", | 51 | LN_PARENT("ln-psia1-mclk"), |
57 | "ln-dsp-clkout", | 52 | LN_PARENT("ln-psia2-mclk"), |
58 | "ln-pmic-32k", | 53 | LN_PARENT("ln-cdc-clkout"), |
59 | "ln-gf-mclk1", | 54 | LN_PARENT("ln-dsp-clkout"), |
60 | "ln-gf-mclk3", | 55 | LN_PARENT("ln-pmic-32k"), |
61 | "ln-gf-mclk2", | 56 | LN_PARENT("ln-gf-mclk1"), |
62 | "ln-gf-mclk4", | 57 | LN_PARENT("ln-gf-mclk3"), |
58 | LN_PARENT("ln-gf-mclk2"), | ||
59 | LN_PARENT("ln-gf-mclk4"), | ||
63 | }; | 60 | }; |
64 | 61 | ||
65 | static const char * const lochnagar2_clk_parents[] = { | 62 | static const struct clk_parent_data lochnagar2_clk_parents[] = { |
66 | "ln-none", | 63 | LN_PARENT("ln-none"), |
67 | "ln-cdc-clkout", | 64 | LN_PARENT("ln-cdc-clkout"), |
68 | "ln-dsp-clkout", | 65 | LN_PARENT("ln-dsp-clkout"), |
69 | "ln-pmic-32k", | 66 | LN_PARENT("ln-pmic-32k"), |
70 | "ln-spdif-mclk", | 67 | LN_PARENT("ln-spdif-mclk"), |
71 | "ln-clk-12m", | 68 | LN_PARENT("ln-clk-12m"), |
72 | "ln-clk-11m", | 69 | LN_PARENT("ln-clk-11m"), |
73 | "ln-clk-24m", | 70 | LN_PARENT("ln-clk-24m"), |
74 | "ln-clk-22m", | 71 | LN_PARENT("ln-clk-22m"), |
75 | "ln-clk-8m", | 72 | LN_PARENT("ln-clk-8m"), |
76 | "ln-usb-clk-24m", | 73 | LN_PARENT("ln-usb-clk-24m"), |
77 | "ln-gf-mclk1", | 74 | LN_PARENT("ln-gf-mclk1"), |
78 | "ln-gf-mclk3", | 75 | LN_PARENT("ln-gf-mclk3"), |
79 | "ln-gf-mclk2", | 76 | LN_PARENT("ln-gf-mclk2"), |
80 | "ln-psia1-mclk", | 77 | LN_PARENT("ln-psia1-mclk"), |
81 | "ln-psia2-mclk", | 78 | LN_PARENT("ln-psia2-mclk"), |
82 | "ln-spdif-clkout", | 79 | LN_PARENT("ln-spdif-clkout"), |
83 | "ln-adat-mclk", | 80 | LN_PARENT("ln-adat-mclk"), |
84 | "ln-usb-clk-12m", | 81 | LN_PARENT("ln-usb-clk-12m"), |
85 | }; | 82 | }; |
86 | 83 | ||
87 | #define LN1_CLK(ID, NAME, REG) \ | 84 | #define LN1_CLK(ID, NAME, REG) \ |
@@ -122,6 +119,24 @@ static const struct lochnagar_clk lochnagar2_clks[LOCHNAGAR_NUM_CLOCKS] = { | |||
122 | LN2_CLK(SOUNDCARD_MCLK, "ln-soundcard-mclk"), | 119 | LN2_CLK(SOUNDCARD_MCLK, "ln-soundcard-mclk"), |
123 | }; | 120 | }; |
124 | 121 | ||
122 | struct lochnagar_config { | ||
123 | const struct clk_parent_data *parents; | ||
124 | int nparents; | ||
125 | const struct lochnagar_clk *clks; | ||
126 | }; | ||
127 | |||
128 | static const struct lochnagar_config lochnagar1_conf = { | ||
129 | .parents = lochnagar1_clk_parents, | ||
130 | .nparents = ARRAY_SIZE(lochnagar1_clk_parents), | ||
131 | .clks = lochnagar1_clks, | ||
132 | }; | ||
133 | |||
134 | static const struct lochnagar_config lochnagar2_conf = { | ||
135 | .parents = lochnagar2_clk_parents, | ||
136 | .nparents = ARRAY_SIZE(lochnagar2_clk_parents), | ||
137 | .clks = lochnagar2_clks, | ||
138 | }; | ||
139 | |||
125 | static inline struct lochnagar_clk *lochnagar_hw_to_lclk(struct clk_hw *hw) | 140 | static inline struct lochnagar_clk *lochnagar_hw_to_lclk(struct clk_hw *hw) |
126 | { | 141 | { |
127 | return container_of(hw, struct lochnagar_clk, hw); | 142 | return container_of(hw, struct lochnagar_clk, hw); |
@@ -183,7 +198,7 @@ static u8 lochnagar_clk_get_parent(struct clk_hw *hw) | |||
183 | if (ret < 0) { | 198 | if (ret < 0) { |
184 | dev_dbg(priv->dev, "Failed to read parent of %s: %d\n", | 199 | dev_dbg(priv->dev, "Failed to read parent of %s: %d\n", |
185 | lclk->name, ret); | 200 | lclk->name, ret); |
186 | return priv->nparents; | 201 | return hw->init->num_parents; |
187 | } | 202 | } |
188 | 203 | ||
189 | val &= lclk->src_mask; | 204 | val &= lclk->src_mask; |
@@ -198,46 +213,6 @@ static const struct clk_ops lochnagar_clk_ops = { | |||
198 | .get_parent = lochnagar_clk_get_parent, | 213 | .get_parent = lochnagar_clk_get_parent, |
199 | }; | 214 | }; |
200 | 215 | ||
201 | static int lochnagar_init_parents(struct lochnagar_clk_priv *priv) | ||
202 | { | ||
203 | struct device_node *np = priv->dev->of_node; | ||
204 | int i, j; | ||
205 | |||
206 | switch (priv->type) { | ||
207 | case LOCHNAGAR1: | ||
208 | memcpy(priv->lclks, lochnagar1_clks, sizeof(lochnagar1_clks)); | ||
209 | |||
210 | priv->nparents = ARRAY_SIZE(lochnagar1_clk_parents); | ||
211 | priv->parents = devm_kmemdup(priv->dev, lochnagar1_clk_parents, | ||
212 | sizeof(lochnagar1_clk_parents), | ||
213 | GFP_KERNEL); | ||
214 | break; | ||
215 | case LOCHNAGAR2: | ||
216 | memcpy(priv->lclks, lochnagar2_clks, sizeof(lochnagar2_clks)); | ||
217 | |||
218 | priv->nparents = ARRAY_SIZE(lochnagar2_clk_parents); | ||
219 | priv->parents = devm_kmemdup(priv->dev, lochnagar2_clk_parents, | ||
220 | sizeof(lochnagar2_clk_parents), | ||
221 | GFP_KERNEL); | ||
222 | break; | ||
223 | default: | ||
224 | dev_err(priv->dev, "Unknown Lochnagar type: %d\n", priv->type); | ||
225 | return -EINVAL; | ||
226 | } | ||
227 | |||
228 | if (!priv->parents) | ||
229 | return -ENOMEM; | ||
230 | |||
231 | for (i = 0; i < priv->nparents; i++) { | ||
232 | j = of_property_match_string(np, "clock-names", | ||
233 | priv->parents[i]); | ||
234 | if (j >= 0) | ||
235 | priv->parents[i] = of_clk_get_parent_name(np, j); | ||
236 | } | ||
237 | |||
238 | return 0; | ||
239 | } | ||
240 | |||
241 | static struct clk_hw * | 216 | static struct clk_hw * |
242 | lochnagar_of_clk_hw_get(struct of_phandle_args *clkspec, void *data) | 217 | lochnagar_of_clk_hw_get(struct of_phandle_args *clkspec, void *data) |
243 | { | 218 | { |
@@ -252,16 +227,42 @@ lochnagar_of_clk_hw_get(struct of_phandle_args *clkspec, void *data) | |||
252 | return &priv->lclks[idx].hw; | 227 | return &priv->lclks[idx].hw; |
253 | } | 228 | } |
254 | 229 | ||
255 | static int lochnagar_init_clks(struct lochnagar_clk_priv *priv) | 230 | static const struct of_device_id lochnagar_of_match[] = { |
231 | { .compatible = "cirrus,lochnagar1-clk", .data = &lochnagar1_conf }, | ||
232 | { .compatible = "cirrus,lochnagar2-clk", .data = &lochnagar2_conf }, | ||
233 | {} | ||
234 | }; | ||
235 | MODULE_DEVICE_TABLE(of, lochnagar_of_match); | ||
236 | |||
237 | static int lochnagar_clk_probe(struct platform_device *pdev) | ||
256 | { | 238 | { |
257 | struct clk_init_data clk_init = { | 239 | struct clk_init_data clk_init = { |
258 | .ops = &lochnagar_clk_ops, | 240 | .ops = &lochnagar_clk_ops, |
259 | .parent_names = priv->parents, | ||
260 | .num_parents = priv->nparents, | ||
261 | }; | 241 | }; |
242 | struct device *dev = &pdev->dev; | ||
243 | struct lochnagar_clk_priv *priv; | ||
244 | const struct of_device_id *of_id; | ||
262 | struct lochnagar_clk *lclk; | 245 | struct lochnagar_clk *lclk; |
246 | struct lochnagar_config *conf; | ||
263 | int ret, i; | 247 | int ret, i; |
264 | 248 | ||
249 | of_id = of_match_device(lochnagar_of_match, dev); | ||
250 | if (!of_id) | ||
251 | return -EINVAL; | ||
252 | |||
253 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); | ||
254 | if (!priv) | ||
255 | return -ENOMEM; | ||
256 | |||
257 | priv->dev = dev; | ||
258 | priv->regmap = dev_get_regmap(dev->parent, NULL); | ||
259 | conf = (struct lochnagar_config *)of_id->data; | ||
260 | |||
261 | memcpy(priv->lclks, conf->clks, sizeof(priv->lclks)); | ||
262 | |||
263 | clk_init.parent_data = conf->parents; | ||
264 | clk_init.num_parents = conf->nparents; | ||
265 | |||
265 | for (i = 0; i < ARRAY_SIZE(priv->lclks); i++) { | 266 | for (i = 0; i < ARRAY_SIZE(priv->lclks); i++) { |
266 | lclk = &priv->lclks[i]; | 267 | lclk = &priv->lclks[i]; |
267 | 268 | ||
@@ -273,55 +274,21 @@ static int lochnagar_init_clks(struct lochnagar_clk_priv *priv) | |||
273 | lclk->priv = priv; | 274 | lclk->priv = priv; |
274 | lclk->hw.init = &clk_init; | 275 | lclk->hw.init = &clk_init; |
275 | 276 | ||
276 | ret = devm_clk_hw_register(priv->dev, &lclk->hw); | 277 | ret = devm_clk_hw_register(dev, &lclk->hw); |
277 | if (ret) { | 278 | if (ret) { |
278 | dev_err(priv->dev, "Failed to register %s: %d\n", | 279 | dev_err(dev, "Failed to register %s: %d\n", |
279 | lclk->name, ret); | 280 | lclk->name, ret); |
280 | return ret; | 281 | return ret; |
281 | } | 282 | } |
282 | } | 283 | } |
283 | 284 | ||
284 | ret = devm_of_clk_add_hw_provider(priv->dev, lochnagar_of_clk_hw_get, | 285 | ret = devm_of_clk_add_hw_provider(dev, lochnagar_of_clk_hw_get, priv); |
285 | priv); | ||
286 | if (ret < 0) | 286 | if (ret < 0) |
287 | dev_err(priv->dev, "Failed to register provider: %d\n", ret); | 287 | dev_err(dev, "Failed to register provider: %d\n", ret); |
288 | 288 | ||
289 | return ret; | 289 | return ret; |
290 | } | 290 | } |
291 | 291 | ||
292 | static const struct of_device_id lochnagar_of_match[] = { | ||
293 | { .compatible = "cirrus,lochnagar1-clk", .data = (void *)LOCHNAGAR1 }, | ||
294 | { .compatible = "cirrus,lochnagar2-clk", .data = (void *)LOCHNAGAR2 }, | ||
295 | {} | ||
296 | }; | ||
297 | MODULE_DEVICE_TABLE(of, lochnagar_of_match); | ||
298 | |||
299 | static int lochnagar_clk_probe(struct platform_device *pdev) | ||
300 | { | ||
301 | struct device *dev = &pdev->dev; | ||
302 | struct lochnagar_clk_priv *priv; | ||
303 | const struct of_device_id *of_id; | ||
304 | int ret; | ||
305 | |||
306 | of_id = of_match_device(lochnagar_of_match, dev); | ||
307 | if (!of_id) | ||
308 | return -EINVAL; | ||
309 | |||
310 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); | ||
311 | if (!priv) | ||
312 | return -ENOMEM; | ||
313 | |||
314 | priv->dev = dev; | ||
315 | priv->regmap = dev_get_regmap(dev->parent, NULL); | ||
316 | priv->type = (enum lochnagar_type)of_id->data; | ||
317 | |||
318 | ret = lochnagar_init_parents(priv); | ||
319 | if (ret) | ||
320 | return ret; | ||
321 | |||
322 | return lochnagar_init_clks(priv); | ||
323 | } | ||
324 | |||
325 | static struct platform_driver lochnagar_clk_driver = { | 292 | static struct platform_driver lochnagar_clk_driver = { |
326 | .driver = { | 293 | .driver = { |
327 | .name = "lochnagar-clk", | 294 | .name = "lochnagar-clk", |
diff --git a/drivers/clk/clk-pwm.c b/drivers/clk/clk-pwm.c index 5f0490b8f6cb..87fe0b0e01a3 100644 --- a/drivers/clk/clk-pwm.c +++ b/drivers/clk/clk-pwm.c | |||
@@ -44,10 +44,24 @@ static unsigned long clk_pwm_recalc_rate(struct clk_hw *hw, | |||
44 | return clk_pwm->fixed_rate; | 44 | return clk_pwm->fixed_rate; |
45 | } | 45 | } |
46 | 46 | ||
47 | static int clk_pwm_get_duty_cycle(struct clk_hw *hw, struct clk_duty *duty) | ||
48 | { | ||
49 | struct clk_pwm *clk_pwm = to_clk_pwm(hw); | ||
50 | struct pwm_state state; | ||
51 | |||
52 | pwm_get_state(clk_pwm->pwm, &state); | ||
53 | |||
54 | duty->num = state.duty_cycle; | ||
55 | duty->den = state.period; | ||
56 | |||
57 | return 0; | ||
58 | } | ||
59 | |||
47 | static const struct clk_ops clk_pwm_ops = { | 60 | static const struct clk_ops clk_pwm_ops = { |
48 | .prepare = clk_pwm_prepare, | 61 | .prepare = clk_pwm_prepare, |
49 | .unprepare = clk_pwm_unprepare, | 62 | .unprepare = clk_pwm_unprepare, |
50 | .recalc_rate = clk_pwm_recalc_rate, | 63 | .recalc_rate = clk_pwm_recalc_rate, |
64 | .get_duty_cycle = clk_pwm_get_duty_cycle, | ||
51 | }; | 65 | }; |
52 | 66 | ||
53 | static int clk_pwm_probe(struct platform_device *pdev) | 67 | static int clk_pwm_probe(struct platform_device *pdev) |
diff --git a/drivers/clk/clk-qoriq.c b/drivers/clk/clk-qoriq.c index dd93d3acc67d..07f3b252f3e0 100644 --- a/drivers/clk/clk-qoriq.c +++ b/drivers/clk/clk-qoriq.c | |||
@@ -635,6 +635,17 @@ static const struct clockgen_chipinfo chipinfo[] = { | |||
635 | .flags = CG_VER3 | CG_LITTLE_ENDIAN, | 635 | .flags = CG_VER3 | CG_LITTLE_ENDIAN, |
636 | }, | 636 | }, |
637 | { | 637 | { |
638 | .compat = "fsl,lx2160a-clockgen", | ||
639 | .cmux_groups = { | ||
640 | &clockgen2_cmux_cga12, &clockgen2_cmux_cgb | ||
641 | }, | ||
642 | .cmux_to_group = { | ||
643 | 0, 0, 0, 0, 1, 1, 1, 1, -1 | ||
644 | }, | ||
645 | .pll_mask = 0x37, | ||
646 | .flags = CG_VER3 | CG_LITTLE_ENDIAN, | ||
647 | }, | ||
648 | { | ||
638 | .compat = "fsl,p2041-clockgen", | 649 | .compat = "fsl,p2041-clockgen", |
639 | .guts_compat = "fsl,qoriq-device-config-1.0", | 650 | .guts_compat = "fsl,qoriq-device-config-1.0", |
640 | .init_periph = p2041_init_periph, | 651 | .init_periph = p2041_init_periph, |
@@ -1493,6 +1504,7 @@ CLK_OF_DECLARE(qoriq_clockgen_ls1043a, "fsl,ls1043a-clockgen", clockgen_init); | |||
1493 | CLK_OF_DECLARE(qoriq_clockgen_ls1046a, "fsl,ls1046a-clockgen", clockgen_init); | 1504 | CLK_OF_DECLARE(qoriq_clockgen_ls1046a, "fsl,ls1046a-clockgen", clockgen_init); |
1494 | CLK_OF_DECLARE(qoriq_clockgen_ls1088a, "fsl,ls1088a-clockgen", clockgen_init); | 1505 | CLK_OF_DECLARE(qoriq_clockgen_ls1088a, "fsl,ls1088a-clockgen", clockgen_init); |
1495 | CLK_OF_DECLARE(qoriq_clockgen_ls2080a, "fsl,ls2080a-clockgen", clockgen_init); | 1506 | CLK_OF_DECLARE(qoriq_clockgen_ls2080a, "fsl,ls2080a-clockgen", clockgen_init); |
1507 | CLK_OF_DECLARE(qoriq_clockgen_lx2160a, "fsl,lx2160a-clockgen", clockgen_init); | ||
1496 | CLK_OF_DECLARE(qoriq_clockgen_p2041, "fsl,p2041-clockgen", clockgen_init); | 1508 | CLK_OF_DECLARE(qoriq_clockgen_p2041, "fsl,p2041-clockgen", clockgen_init); |
1497 | CLK_OF_DECLARE(qoriq_clockgen_p3041, "fsl,p3041-clockgen", clockgen_init); | 1509 | CLK_OF_DECLARE(qoriq_clockgen_p3041, "fsl,p3041-clockgen", clockgen_init); |
1498 | CLK_OF_DECLARE(qoriq_clockgen_p4080, "fsl,p4080-clockgen", clockgen_init); | 1510 | CLK_OF_DECLARE(qoriq_clockgen_p4080, "fsl,p4080-clockgen", clockgen_init); |
diff --git a/drivers/clk/clk-si5341.c b/drivers/clk/clk-si5341.c new file mode 100644 index 000000000000..72424eb7e5f8 --- /dev/null +++ b/drivers/clk/clk-si5341.c | |||
@@ -0,0 +1,1346 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * Driver for Silicon Labs Si5341/Si5340 Clock generator | ||
4 | * Copyright (C) 2019 Topic Embedded Products | ||
5 | * Author: Mike Looijmans <mike.looijmans@topic.nl> | ||
6 | */ | ||
7 | |||
8 | #include <linux/clk.h> | ||
9 | #include <linux/clk-provider.h> | ||
10 | #include <linux/delay.h> | ||
11 | #include <linux/gcd.h> | ||
12 | #include <linux/math64.h> | ||
13 | #include <linux/i2c.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/regmap.h> | ||
16 | #include <linux/slab.h> | ||
17 | #include <asm/unaligned.h> | ||
18 | |||
19 | #define SI5341_MAX_NUM_OUTPUTS 10 | ||
20 | #define SI5340_MAX_NUM_OUTPUTS 4 | ||
21 | |||
22 | #define SI5341_NUM_SYNTH 5 | ||
23 | #define SI5340_NUM_SYNTH 4 | ||
24 | |||
25 | /* Range of the synthesizer fractional divider */ | ||
26 | #define SI5341_SYNTH_N_MIN 10 | ||
27 | #define SI5341_SYNTH_N_MAX 4095 | ||
28 | |||
29 | /* The chip can get its input clock from 3 input pins or an XTAL */ | ||
30 | |||
31 | /* There is one PLL running at 13500–14256 MHz */ | ||
32 | #define SI5341_PLL_VCO_MIN 13500000000ull | ||
33 | #define SI5341_PLL_VCO_MAX 14256000000ull | ||
34 | |||
35 | /* The 5 frequency synthesizers obtain their input from the PLL */ | ||
36 | struct clk_si5341_synth { | ||
37 | struct clk_hw hw; | ||
38 | struct clk_si5341 *data; | ||
39 | u8 index; | ||
40 | }; | ||
41 | #define to_clk_si5341_synth(_hw) \ | ||
42 | container_of(_hw, struct clk_si5341_synth, hw) | ||
43 | |||
44 | /* The output stages can be connected to any synth (full mux) */ | ||
45 | struct clk_si5341_output { | ||
46 | struct clk_hw hw; | ||
47 | struct clk_si5341 *data; | ||
48 | u8 index; | ||
49 | }; | ||
50 | #define to_clk_si5341_output(_hw) \ | ||
51 | container_of(_hw, struct clk_si5341_output, hw) | ||
52 | |||
53 | struct clk_si5341 { | ||
54 | struct clk_hw hw; | ||
55 | struct regmap *regmap; | ||
56 | struct i2c_client *i2c_client; | ||
57 | struct clk_si5341_synth synth[SI5341_NUM_SYNTH]; | ||
58 | struct clk_si5341_output clk[SI5341_MAX_NUM_OUTPUTS]; | ||
59 | struct clk *pxtal; | ||
60 | const char *pxtal_name; | ||
61 | const u16 *reg_output_offset; | ||
62 | const u16 *reg_rdiv_offset; | ||
63 | u64 freq_vco; /* 13500–14256 MHz */ | ||
64 | u8 num_outputs; | ||
65 | u8 num_synth; | ||
66 | }; | ||
67 | #define to_clk_si5341(_hw) container_of(_hw, struct clk_si5341, hw) | ||
68 | |||
69 | struct clk_si5341_output_config { | ||
70 | u8 out_format_drv_bits; | ||
71 | u8 out_cm_ampl_bits; | ||
72 | bool synth_master; | ||
73 | bool always_on; | ||
74 | }; | ||
75 | |||
76 | #define SI5341_PAGE 0x0001 | ||
77 | #define SI5341_PN_BASE 0x0002 | ||
78 | #define SI5341_DEVICE_REV 0x0005 | ||
79 | #define SI5341_STATUS 0x000C | ||
80 | #define SI5341_SOFT_RST 0x001C | ||
81 | |||
82 | /* Input dividers (48-bit) */ | ||
83 | #define SI5341_IN_PDIV(x) (0x0208 + ((x) * 10)) | ||
84 | #define SI5341_IN_PSET(x) (0x020E + ((x) * 10)) | ||
85 | |||
86 | /* PLL configuration */ | ||
87 | #define SI5341_PLL_M_NUM 0x0235 | ||
88 | #define SI5341_PLL_M_DEN 0x023B | ||
89 | |||
90 | /* Output configuration */ | ||
91 | #define SI5341_OUT_CONFIG(output) \ | ||
92 | ((output)->data->reg_output_offset[(output)->index]) | ||
93 | #define SI5341_OUT_FORMAT(output) (SI5341_OUT_CONFIG(output) + 1) | ||
94 | #define SI5341_OUT_CM(output) (SI5341_OUT_CONFIG(output) + 2) | ||
95 | #define SI5341_OUT_MUX_SEL(output) (SI5341_OUT_CONFIG(output) + 3) | ||
96 | #define SI5341_OUT_R_REG(output) \ | ||
97 | ((output)->data->reg_rdiv_offset[(output)->index]) | ||
98 | |||
99 | /* Synthesize N divider */ | ||
100 | #define SI5341_SYNTH_N_NUM(x) (0x0302 + ((x) * 11)) | ||
101 | #define SI5341_SYNTH_N_DEN(x) (0x0308 + ((x) * 11)) | ||
102 | #define SI5341_SYNTH_N_UPD(x) (0x030C + ((x) * 11)) | ||
103 | |||
104 | /* Synthesizer output enable, phase bypass, power mode */ | ||
105 | #define SI5341_SYNTH_N_CLK_TO_OUTX_EN 0x0A03 | ||
106 | #define SI5341_SYNTH_N_PIBYP 0x0A04 | ||
107 | #define SI5341_SYNTH_N_PDNB 0x0A05 | ||
108 | #define SI5341_SYNTH_N_CLK_DIS 0x0B4A | ||
109 | |||
110 | #define SI5341_REGISTER_MAX 0xBFF | ||
111 | |||
112 | /* SI5341_OUT_CONFIG bits */ | ||
113 | #define SI5341_OUT_CFG_PDN BIT(0) | ||
114 | #define SI5341_OUT_CFG_OE BIT(1) | ||
115 | #define SI5341_OUT_CFG_RDIV_FORCE2 BIT(2) | ||
116 | |||
117 | /* Static configuration (to be moved to firmware) */ | ||
118 | struct si5341_reg_default { | ||
119 | u16 address; | ||
120 | u8 value; | ||
121 | }; | ||
122 | |||
123 | /* Output configuration registers 0..9 are not quite logically organized */ | ||
124 | static const u16 si5341_reg_output_offset[] = { | ||
125 | 0x0108, | ||
126 | 0x010D, | ||
127 | 0x0112, | ||
128 | 0x0117, | ||
129 | 0x011C, | ||
130 | 0x0121, | ||
131 | 0x0126, | ||
132 | 0x012B, | ||
133 | 0x0130, | ||
134 | 0x013A, | ||
135 | }; | ||
136 | |||
137 | static const u16 si5340_reg_output_offset[] = { | ||
138 | 0x0112, | ||
139 | 0x0117, | ||
140 | 0x0126, | ||
141 | 0x012B, | ||
142 | }; | ||
143 | |||
144 | /* The location of the R divider registers */ | ||
145 | static const u16 si5341_reg_rdiv_offset[] = { | ||
146 | 0x024A, | ||
147 | 0x024D, | ||
148 | 0x0250, | ||
149 | 0x0253, | ||
150 | 0x0256, | ||
151 | 0x0259, | ||
152 | 0x025C, | ||
153 | 0x025F, | ||
154 | 0x0262, | ||
155 | 0x0268, | ||
156 | }; | ||
157 | static const u16 si5340_reg_rdiv_offset[] = { | ||
158 | 0x0250, | ||
159 | 0x0253, | ||
160 | 0x025C, | ||
161 | 0x025F, | ||
162 | }; | ||
163 | |||
164 | /* | ||
165 | * Programming sequence from ClockBuilder, settings to initialize the system | ||
166 | * using only the XTAL input, without pre-divider. | ||
167 | * This also contains settings that aren't mentioned anywhere in the datasheet. | ||
168 | * The "known" settings like synth and output configuration are done later. | ||
169 | */ | ||
170 | static const struct si5341_reg_default si5341_reg_defaults[] = { | ||
171 | { 0x0017, 0x3A }, /* INT mask (disable interrupts) */ | ||
172 | { 0x0018, 0xFF }, /* INT mask */ | ||
173 | { 0x0021, 0x0F }, /* Select XTAL as input */ | ||
174 | { 0x0022, 0x00 }, /* Not in datasheet */ | ||
175 | { 0x002B, 0x02 }, /* SPI config */ | ||
176 | { 0x002C, 0x20 }, /* LOS enable for XTAL */ | ||
177 | { 0x002D, 0x00 }, /* LOS timing */ | ||
178 | { 0x002E, 0x00 }, | ||
179 | { 0x002F, 0x00 }, | ||
180 | { 0x0030, 0x00 }, | ||
181 | { 0x0031, 0x00 }, | ||
182 | { 0x0032, 0x00 }, | ||
183 | { 0x0033, 0x00 }, | ||
184 | { 0x0034, 0x00 }, | ||
185 | { 0x0035, 0x00 }, | ||
186 | { 0x0036, 0x00 }, | ||
187 | { 0x0037, 0x00 }, | ||
188 | { 0x0038, 0x00 }, /* LOS setting (thresholds) */ | ||
189 | { 0x0039, 0x00 }, | ||
190 | { 0x003A, 0x00 }, | ||
191 | { 0x003B, 0x00 }, | ||
192 | { 0x003C, 0x00 }, | ||
193 | { 0x003D, 0x00 }, /* LOS setting (thresholds) end */ | ||
194 | { 0x0041, 0x00 }, /* LOS0_DIV_SEL */ | ||
195 | { 0x0042, 0x00 }, /* LOS1_DIV_SEL */ | ||
196 | { 0x0043, 0x00 }, /* LOS2_DIV_SEL */ | ||
197 | { 0x0044, 0x00 }, /* LOS3_DIV_SEL */ | ||
198 | { 0x009E, 0x00 }, /* Not in datasheet */ | ||
199 | { 0x0102, 0x01 }, /* Enable outputs */ | ||
200 | { 0x013F, 0x00 }, /* Not in datasheet */ | ||
201 | { 0x0140, 0x00 }, /* Not in datasheet */ | ||
202 | { 0x0141, 0x40 }, /* OUT LOS */ | ||
203 | { 0x0202, 0x00 }, /* XAXB_FREQ_OFFSET (=0)*/ | ||
204 | { 0x0203, 0x00 }, | ||
205 | { 0x0204, 0x00 }, | ||
206 | { 0x0205, 0x00 }, | ||
207 | { 0x0206, 0x00 }, /* PXAXB (2^x) */ | ||
208 | { 0x0208, 0x00 }, /* Px divider setting (usually 0) */ | ||
209 | { 0x0209, 0x00 }, | ||
210 | { 0x020A, 0x00 }, | ||
211 | { 0x020B, 0x00 }, | ||
212 | { 0x020C, 0x00 }, | ||
213 | { 0x020D, 0x00 }, | ||
214 | { 0x020E, 0x00 }, | ||
215 | { 0x020F, 0x00 }, | ||
216 | { 0x0210, 0x00 }, | ||
217 | { 0x0211, 0x00 }, | ||
218 | { 0x0212, 0x00 }, | ||
219 | { 0x0213, 0x00 }, | ||
220 | { 0x0214, 0x00 }, | ||
221 | { 0x0215, 0x00 }, | ||
222 | { 0x0216, 0x00 }, | ||
223 | { 0x0217, 0x00 }, | ||
224 | { 0x0218, 0x00 }, | ||
225 | { 0x0219, 0x00 }, | ||
226 | { 0x021A, 0x00 }, | ||
227 | { 0x021B, 0x00 }, | ||
228 | { 0x021C, 0x00 }, | ||
229 | { 0x021D, 0x00 }, | ||
230 | { 0x021E, 0x00 }, | ||
231 | { 0x021F, 0x00 }, | ||
232 | { 0x0220, 0x00 }, | ||
233 | { 0x0221, 0x00 }, | ||
234 | { 0x0222, 0x00 }, | ||
235 | { 0x0223, 0x00 }, | ||
236 | { 0x0224, 0x00 }, | ||
237 | { 0x0225, 0x00 }, | ||
238 | { 0x0226, 0x00 }, | ||
239 | { 0x0227, 0x00 }, | ||
240 | { 0x0228, 0x00 }, | ||
241 | { 0x0229, 0x00 }, | ||
242 | { 0x022A, 0x00 }, | ||
243 | { 0x022B, 0x00 }, | ||
244 | { 0x022C, 0x00 }, | ||
245 | { 0x022D, 0x00 }, | ||
246 | { 0x022E, 0x00 }, | ||
247 | { 0x022F, 0x00 }, /* Px divider setting (usually 0) end */ | ||
248 | { 0x026B, 0x00 }, /* DESIGN_ID (ASCII string) */ | ||
249 | { 0x026C, 0x00 }, | ||
250 | { 0x026D, 0x00 }, | ||
251 | { 0x026E, 0x00 }, | ||
252 | { 0x026F, 0x00 }, | ||
253 | { 0x0270, 0x00 }, | ||
254 | { 0x0271, 0x00 }, | ||
255 | { 0x0272, 0x00 }, /* DESIGN_ID (ASCII string) end */ | ||
256 | { 0x0339, 0x1F }, /* N_FSTEP_MSK */ | ||
257 | { 0x033B, 0x00 }, /* Nx_FSTEPW (Frequency step) */ | ||
258 | { 0x033C, 0x00 }, | ||
259 | { 0x033D, 0x00 }, | ||
260 | { 0x033E, 0x00 }, | ||
261 | { 0x033F, 0x00 }, | ||
262 | { 0x0340, 0x00 }, | ||
263 | { 0x0341, 0x00 }, | ||
264 | { 0x0342, 0x00 }, | ||
265 | { 0x0343, 0x00 }, | ||
266 | { 0x0344, 0x00 }, | ||
267 | { 0x0345, 0x00 }, | ||
268 | { 0x0346, 0x00 }, | ||
269 | { 0x0347, 0x00 }, | ||
270 | { 0x0348, 0x00 }, | ||
271 | { 0x0349, 0x00 }, | ||
272 | { 0x034A, 0x00 }, | ||
273 | { 0x034B, 0x00 }, | ||
274 | { 0x034C, 0x00 }, | ||
275 | { 0x034D, 0x00 }, | ||
276 | { 0x034E, 0x00 }, | ||
277 | { 0x034F, 0x00 }, | ||
278 | { 0x0350, 0x00 }, | ||
279 | { 0x0351, 0x00 }, | ||
280 | { 0x0352, 0x00 }, | ||
281 | { 0x0353, 0x00 }, | ||
282 | { 0x0354, 0x00 }, | ||
283 | { 0x0355, 0x00 }, | ||
284 | { 0x0356, 0x00 }, | ||
285 | { 0x0357, 0x00 }, | ||
286 | { 0x0358, 0x00 }, /* Nx_FSTEPW (Frequency step) end */ | ||
287 | { 0x0359, 0x00 }, /* Nx_DELAY */ | ||
288 | { 0x035A, 0x00 }, | ||
289 | { 0x035B, 0x00 }, | ||
290 | { 0x035C, 0x00 }, | ||
291 | { 0x035D, 0x00 }, | ||
292 | { 0x035E, 0x00 }, | ||
293 | { 0x035F, 0x00 }, | ||
294 | { 0x0360, 0x00 }, | ||
295 | { 0x0361, 0x00 }, | ||
296 | { 0x0362, 0x00 }, /* Nx_DELAY end */ | ||
297 | { 0x0802, 0x00 }, /* Not in datasheet */ | ||
298 | { 0x0803, 0x00 }, /* Not in datasheet */ | ||
299 | { 0x0804, 0x00 }, /* Not in datasheet */ | ||
300 | { 0x090E, 0x02 }, /* XAXB_EXTCLK_EN=0 XAXB_PDNB=1 (use XTAL) */ | ||
301 | { 0x091C, 0x04 }, /* ZDM_EN=4 (Normal mode) */ | ||
302 | { 0x0943, 0x00 }, /* IO_VDD_SEL=0 (0=1v8, use 1=3v3) */ | ||
303 | { 0x0949, 0x00 }, /* IN_EN (disable input clocks) */ | ||
304 | { 0x094A, 0x00 }, /* INx_TO_PFD_EN (disabled) */ | ||
305 | { 0x0A02, 0x00 }, /* Not in datasheet */ | ||
306 | { 0x0B44, 0x0F }, /* PDIV_ENB (datasheet does not mention what it is) */ | ||
307 | }; | ||
308 | |||
309 | /* Read and interpret a 44-bit followed by a 32-bit value in the regmap */ | ||
310 | static int si5341_decode_44_32(struct regmap *regmap, unsigned int reg, | ||
311 | u64 *val1, u32 *val2) | ||
312 | { | ||
313 | int err; | ||
314 | u8 r[10]; | ||
315 | |||
316 | err = regmap_bulk_read(regmap, reg, r, 10); | ||
317 | if (err < 0) | ||
318 | return err; | ||
319 | |||
320 | *val1 = ((u64)((r[5] & 0x0f) << 8 | r[4]) << 32) | | ||
321 | (get_unaligned_le32(r)); | ||
322 | *val2 = get_unaligned_le32(&r[6]); | ||
323 | |||
324 | return 0; | ||
325 | } | ||
326 | |||
327 | static int si5341_encode_44_32(struct regmap *regmap, unsigned int reg, | ||
328 | u64 n_num, u32 n_den) | ||
329 | { | ||
330 | u8 r[10]; | ||
331 | |||
332 | /* Shift left as far as possible without overflowing */ | ||
333 | while (!(n_num & BIT_ULL(43)) && !(n_den & BIT(31))) { | ||
334 | n_num <<= 1; | ||
335 | n_den <<= 1; | ||
336 | } | ||
337 | |||
338 | /* 44 bits (6 bytes) numerator */ | ||
339 | put_unaligned_le32(n_num, r); | ||
340 | r[4] = (n_num >> 32) & 0xff; | ||
341 | r[5] = (n_num >> 40) & 0x0f; | ||
342 | /* 32 bits denominator */ | ||
343 | put_unaligned_le32(n_den, &r[6]); | ||
344 | |||
345 | /* Program the fraction */ | ||
346 | return regmap_bulk_write(regmap, reg, r, sizeof(r)); | ||
347 | } | ||
348 | |||
349 | /* VCO, we assume it runs at a constant frequency */ | ||
350 | static unsigned long si5341_clk_recalc_rate(struct clk_hw *hw, | ||
351 | unsigned long parent_rate) | ||
352 | { | ||
353 | struct clk_si5341 *data = to_clk_si5341(hw); | ||
354 | int err; | ||
355 | u64 res; | ||
356 | u64 m_num; | ||
357 | u32 m_den; | ||
358 | unsigned int shift; | ||
359 | |||
360 | /* Assume that PDIV is not being used, just read the PLL setting */ | ||
361 | err = si5341_decode_44_32(data->regmap, SI5341_PLL_M_NUM, | ||
362 | &m_num, &m_den); | ||
363 | if (err < 0) | ||
364 | return 0; | ||
365 | |||
366 | if (!m_num || !m_den) | ||
367 | return 0; | ||
368 | |||
369 | /* | ||
370 | * Though m_num is 64-bit, only the upper bits are actually used. While | ||
371 | * calculating m_num and m_den, they are shifted as far as possible to | ||
372 | * the left. To avoid 96-bit division here, we just shift them back so | ||
373 | * we can do with just 64 bits. | ||
374 | */ | ||
375 | shift = 0; | ||
376 | res = m_num; | ||
377 | while (res & 0xffff00000000ULL) { | ||
378 | ++shift; | ||
379 | res >>= 1; | ||
380 | } | ||
381 | res *= parent_rate; | ||
382 | do_div(res, (m_den >> shift)); | ||
383 | |||
384 | /* We cannot return the actual frequency in 32 bit, store it locally */ | ||
385 | data->freq_vco = res; | ||
386 | |||
387 | /* Report kHz since the value is out of range */ | ||
388 | do_div(res, 1000); | ||
389 | |||
390 | return (unsigned long)res; | ||
391 | } | ||
392 | |||
393 | static const struct clk_ops si5341_clk_ops = { | ||
394 | .recalc_rate = si5341_clk_recalc_rate, | ||
395 | }; | ||
396 | |||
397 | /* Synthesizers, there are 5 synthesizers that connect to any of the outputs */ | ||
398 | |||
399 | /* The synthesizer is on if all power and enable bits are set */ | ||
400 | static int si5341_synth_clk_is_on(struct clk_hw *hw) | ||
401 | { | ||
402 | struct clk_si5341_synth *synth = to_clk_si5341_synth(hw); | ||
403 | int err; | ||
404 | u32 val; | ||
405 | u8 index = synth->index; | ||
406 | |||
407 | err = regmap_read(synth->data->regmap, | ||
408 | SI5341_SYNTH_N_CLK_TO_OUTX_EN, &val); | ||
409 | if (err < 0) | ||
410 | return 0; | ||
411 | |||
412 | if (!(val & BIT(index))) | ||
413 | return 0; | ||
414 | |||
415 | err = regmap_read(synth->data->regmap, SI5341_SYNTH_N_PDNB, &val); | ||
416 | if (err < 0) | ||
417 | return 0; | ||
418 | |||
419 | if (!(val & BIT(index))) | ||
420 | return 0; | ||
421 | |||
422 | /* This bit must be 0 for the synthesizer to receive clock input */ | ||
423 | err = regmap_read(synth->data->regmap, SI5341_SYNTH_N_CLK_DIS, &val); | ||
424 | if (err < 0) | ||
425 | return 0; | ||
426 | |||
427 | return !(val & BIT(index)); | ||
428 | } | ||
429 | |||
430 | static void si5341_synth_clk_unprepare(struct clk_hw *hw) | ||
431 | { | ||
432 | struct clk_si5341_synth *synth = to_clk_si5341_synth(hw); | ||
433 | u8 index = synth->index; /* In range 0..5 */ | ||
434 | u8 mask = BIT(index); | ||
435 | |||
436 | /* Disable output */ | ||
437 | regmap_update_bits(synth->data->regmap, | ||
438 | SI5341_SYNTH_N_CLK_TO_OUTX_EN, mask, 0); | ||
439 | /* Power down */ | ||
440 | regmap_update_bits(synth->data->regmap, | ||
441 | SI5341_SYNTH_N_PDNB, mask, 0); | ||
442 | /* Disable clock input to synth (set to 1 to disable) */ | ||
443 | regmap_update_bits(synth->data->regmap, | ||
444 | SI5341_SYNTH_N_CLK_DIS, mask, mask); | ||
445 | } | ||
446 | |||
447 | static int si5341_synth_clk_prepare(struct clk_hw *hw) | ||
448 | { | ||
449 | struct clk_si5341_synth *synth = to_clk_si5341_synth(hw); | ||
450 | int err; | ||
451 | u8 index = synth->index; | ||
452 | u8 mask = BIT(index); | ||
453 | |||
454 | /* Power up */ | ||
455 | err = regmap_update_bits(synth->data->regmap, | ||
456 | SI5341_SYNTH_N_PDNB, mask, mask); | ||
457 | if (err < 0) | ||
458 | return err; | ||
459 | |||
460 | /* Enable clock input to synth (set bit to 0 to enable) */ | ||
461 | err = regmap_update_bits(synth->data->regmap, | ||
462 | SI5341_SYNTH_N_CLK_DIS, mask, 0); | ||
463 | if (err < 0) | ||
464 | return err; | ||
465 | |||
466 | /* Enable output */ | ||
467 | return regmap_update_bits(synth->data->regmap, | ||
468 | SI5341_SYNTH_N_CLK_TO_OUTX_EN, mask, mask); | ||
469 | } | ||
470 | |||
471 | /* Synth clock frequency: Fvco * n_den / n_den, with Fvco in 13500-14256 MHz */ | ||
472 | static unsigned long si5341_synth_clk_recalc_rate(struct clk_hw *hw, | ||
473 | unsigned long parent_rate) | ||
474 | { | ||
475 | struct clk_si5341_synth *synth = to_clk_si5341_synth(hw); | ||
476 | u64 f; | ||
477 | u64 n_num; | ||
478 | u32 n_den; | ||
479 | int err; | ||
480 | |||
481 | err = si5341_decode_44_32(synth->data->regmap, | ||
482 | SI5341_SYNTH_N_NUM(synth->index), &n_num, &n_den); | ||
483 | if (err < 0) | ||
484 | return err; | ||
485 | |||
486 | /* | ||
487 | * n_num and n_den are shifted left as much as possible, so to prevent | ||
488 | * overflow in 64-bit math, we shift n_den 4 bits to the right | ||
489 | */ | ||
490 | f = synth->data->freq_vco; | ||
491 | f *= n_den >> 4; | ||
492 | |||
493 | /* Now we need to to 64-bit division: f/n_num */ | ||
494 | /* And compensate for the 4 bits we dropped */ | ||
495 | f = div64_u64(f, (n_num >> 4)); | ||
496 | |||
497 | return f; | ||
498 | } | ||
499 | |||
500 | static long si5341_synth_clk_round_rate(struct clk_hw *hw, unsigned long rate, | ||
501 | unsigned long *parent_rate) | ||
502 | { | ||
503 | struct clk_si5341_synth *synth = to_clk_si5341_synth(hw); | ||
504 | u64 f; | ||
505 | |||
506 | /* The synthesizer accuracy is such that anything in range will work */ | ||
507 | f = synth->data->freq_vco; | ||
508 | do_div(f, SI5341_SYNTH_N_MAX); | ||
509 | if (rate < f) | ||
510 | return f; | ||
511 | |||
512 | f = synth->data->freq_vco; | ||
513 | do_div(f, SI5341_SYNTH_N_MIN); | ||
514 | if (rate > f) | ||
515 | return f; | ||
516 | |||
517 | return rate; | ||
518 | } | ||
519 | |||
520 | static int si5341_synth_program(struct clk_si5341_synth *synth, | ||
521 | u64 n_num, u32 n_den, bool is_integer) | ||
522 | { | ||
523 | int err; | ||
524 | u8 index = synth->index; | ||
525 | |||
526 | err = si5341_encode_44_32(synth->data->regmap, | ||
527 | SI5341_SYNTH_N_NUM(index), n_num, n_den); | ||
528 | |||
529 | err = regmap_update_bits(synth->data->regmap, | ||
530 | SI5341_SYNTH_N_PIBYP, BIT(index), is_integer ? BIT(index) : 0); | ||
531 | if (err < 0) | ||
532 | return err; | ||
533 | |||
534 | return regmap_write(synth->data->regmap, | ||
535 | SI5341_SYNTH_N_UPD(index), 0x01); | ||
536 | } | ||
537 | |||
538 | |||
539 | static int si5341_synth_clk_set_rate(struct clk_hw *hw, unsigned long rate, | ||
540 | unsigned long parent_rate) | ||
541 | { | ||
542 | struct clk_si5341_synth *synth = to_clk_si5341_synth(hw); | ||
543 | u64 n_num; | ||
544 | u32 n_den; | ||
545 | u32 r; | ||
546 | u32 g; | ||
547 | bool is_integer; | ||
548 | |||
549 | n_num = synth->data->freq_vco; | ||
550 | n_den = rate; | ||
551 | |||
552 | /* see if there's an integer solution */ | ||
553 | r = do_div(n_num, rate); | ||
554 | is_integer = (r == 0); | ||
555 | if (is_integer) { | ||
556 | /* Integer divider equal to n_num */ | ||
557 | n_den = 1; | ||
558 | } else { | ||
559 | /* Calculate a fractional solution */ | ||
560 | g = gcd(r, rate); | ||
561 | n_den = rate / g; | ||
562 | n_num *= n_den; | ||
563 | n_num += r / g; | ||
564 | } | ||
565 | |||
566 | dev_dbg(&synth->data->i2c_client->dev, | ||
567 | "%s(%u): n=0x%llx d=0x%x %s\n", __func__, | ||
568 | synth->index, n_num, n_den, | ||
569 | is_integer ? "int" : "frac"); | ||
570 | |||
571 | return si5341_synth_program(synth, n_num, n_den, is_integer); | ||
572 | } | ||
573 | |||
574 | static const struct clk_ops si5341_synth_clk_ops = { | ||
575 | .is_prepared = si5341_synth_clk_is_on, | ||
576 | .prepare = si5341_synth_clk_prepare, | ||
577 | .unprepare = si5341_synth_clk_unprepare, | ||
578 | .recalc_rate = si5341_synth_clk_recalc_rate, | ||
579 | .round_rate = si5341_synth_clk_round_rate, | ||
580 | .set_rate = si5341_synth_clk_set_rate, | ||
581 | }; | ||
582 | |||
583 | static int si5341_output_clk_is_on(struct clk_hw *hw) | ||
584 | { | ||
585 | struct clk_si5341_output *output = to_clk_si5341_output(hw); | ||
586 | int err; | ||
587 | u32 val; | ||
588 | |||
589 | err = regmap_read(output->data->regmap, | ||
590 | SI5341_OUT_CONFIG(output), &val); | ||
591 | if (err < 0) | ||
592 | return err; | ||
593 | |||
594 | /* Bit 0=PDN, 1=OE so only a value of 0x2 enables the output */ | ||
595 | return (val & 0x03) == SI5341_OUT_CFG_OE; | ||
596 | } | ||
597 | |||
598 | /* Disables and then powers down the output */ | ||
599 | static void si5341_output_clk_unprepare(struct clk_hw *hw) | ||
600 | { | ||
601 | struct clk_si5341_output *output = to_clk_si5341_output(hw); | ||
602 | |||
603 | regmap_update_bits(output->data->regmap, | ||
604 | SI5341_OUT_CONFIG(output), | ||
605 | SI5341_OUT_CFG_OE, 0); | ||
606 | regmap_update_bits(output->data->regmap, | ||
607 | SI5341_OUT_CONFIG(output), | ||
608 | SI5341_OUT_CFG_PDN, SI5341_OUT_CFG_PDN); | ||
609 | } | ||
610 | |||
611 | /* Powers up and then enables the output */ | ||
612 | static int si5341_output_clk_prepare(struct clk_hw *hw) | ||
613 | { | ||
614 | struct clk_si5341_output *output = to_clk_si5341_output(hw); | ||
615 | int err; | ||
616 | |||
617 | err = regmap_update_bits(output->data->regmap, | ||
618 | SI5341_OUT_CONFIG(output), | ||
619 | SI5341_OUT_CFG_PDN, 0); | ||
620 | if (err < 0) | ||
621 | return err; | ||
622 | |||
623 | return regmap_update_bits(output->data->regmap, | ||
624 | SI5341_OUT_CONFIG(output), | ||
625 | SI5341_OUT_CFG_OE, SI5341_OUT_CFG_OE); | ||
626 | } | ||
627 | |||
628 | static unsigned long si5341_output_clk_recalc_rate(struct clk_hw *hw, | ||
629 | unsigned long parent_rate) | ||
630 | { | ||
631 | struct clk_si5341_output *output = to_clk_si5341_output(hw); | ||
632 | int err; | ||
633 | u32 val; | ||
634 | u32 r_divider; | ||
635 | u8 r[3]; | ||
636 | |||
637 | err = regmap_bulk_read(output->data->regmap, | ||
638 | SI5341_OUT_R_REG(output), r, 3); | ||
639 | if (err < 0) | ||
640 | return err; | ||
641 | |||
642 | /* Calculate value as 24-bit integer*/ | ||
643 | r_divider = r[2] << 16 | r[1] << 8 | r[0]; | ||
644 | |||
645 | /* If Rx_REG is zero, the divider is disabled, so return a "0" rate */ | ||
646 | if (!r_divider) | ||
647 | return 0; | ||
648 | |||
649 | /* Divider is 2*(Rx_REG+1) */ | ||
650 | r_divider += 1; | ||
651 | r_divider <<= 1; | ||
652 | |||
653 | err = regmap_read(output->data->regmap, | ||
654 | SI5341_OUT_CONFIG(output), &val); | ||
655 | if (err < 0) | ||
656 | return err; | ||
657 | |||
658 | if (val & SI5341_OUT_CFG_RDIV_FORCE2) | ||
659 | r_divider = 2; | ||
660 | |||
661 | return parent_rate / r_divider; | ||
662 | } | ||
663 | |||
664 | static long si5341_output_clk_round_rate(struct clk_hw *hw, unsigned long rate, | ||
665 | unsigned long *parent_rate) | ||
666 | { | ||
667 | unsigned long r; | ||
668 | |||
669 | r = *parent_rate >> 1; | ||
670 | |||
671 | /* If rate is an even divisor, no changes to parent required */ | ||
672 | if (r && !(r % rate)) | ||
673 | return (long)rate; | ||
674 | |||
675 | if (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) { | ||
676 | if (rate > 200000000) { | ||
677 | /* minimum r-divider is 2 */ | ||
678 | r = 2; | ||
679 | } else { | ||
680 | /* Take a parent frequency near 400 MHz */ | ||
681 | r = (400000000u / rate) & ~1; | ||
682 | } | ||
683 | *parent_rate = r * rate; | ||
684 | } else { | ||
685 | /* We cannot change our parent's rate, report what we can do */ | ||
686 | r /= rate; | ||
687 | rate = *parent_rate / (r << 1); | ||
688 | } | ||
689 | |||
690 | return rate; | ||
691 | } | ||
692 | |||
693 | static int si5341_output_clk_set_rate(struct clk_hw *hw, unsigned long rate, | ||
694 | unsigned long parent_rate) | ||
695 | { | ||
696 | struct clk_si5341_output *output = to_clk_si5341_output(hw); | ||
697 | /* Frequency divider is (r_div + 1) * 2 */ | ||
698 | u32 r_div = (parent_rate / rate) >> 1; | ||
699 | int err; | ||
700 | u8 r[3]; | ||
701 | |||
702 | if (r_div <= 1) | ||
703 | r_div = 0; | ||
704 | else if (r_div >= BIT(24)) | ||
705 | r_div = BIT(24) - 1; | ||
706 | else | ||
707 | --r_div; | ||
708 | |||
709 | /* For a value of "2", we set the "OUT0_RDIV_FORCE2" bit */ | ||
710 | err = regmap_update_bits(output->data->regmap, | ||
711 | SI5341_OUT_CONFIG(output), | ||
712 | SI5341_OUT_CFG_RDIV_FORCE2, | ||
713 | (r_div == 0) ? SI5341_OUT_CFG_RDIV_FORCE2 : 0); | ||
714 | if (err < 0) | ||
715 | return err; | ||
716 | |||
717 | /* Always write Rx_REG, because a zero value disables the divider */ | ||
718 | r[0] = r_div ? (r_div & 0xff) : 1; | ||
719 | r[1] = (r_div >> 8) & 0xff; | ||
720 | r[2] = (r_div >> 16) & 0xff; | ||
721 | err = regmap_bulk_write(output->data->regmap, | ||
722 | SI5341_OUT_R_REG(output), r, 3); | ||
723 | |||
724 | return 0; | ||
725 | } | ||
726 | |||
727 | static int si5341_output_reparent(struct clk_si5341_output *output, u8 index) | ||
728 | { | ||
729 | return regmap_update_bits(output->data->regmap, | ||
730 | SI5341_OUT_MUX_SEL(output), 0x07, index); | ||
731 | } | ||
732 | |||
733 | static int si5341_output_set_parent(struct clk_hw *hw, u8 index) | ||
734 | { | ||
735 | struct clk_si5341_output *output = to_clk_si5341_output(hw); | ||
736 | |||
737 | if (index >= output->data->num_synth) | ||
738 | return -EINVAL; | ||
739 | |||
740 | return si5341_output_reparent(output, index); | ||
741 | } | ||
742 | |||
743 | static u8 si5341_output_get_parent(struct clk_hw *hw) | ||
744 | { | ||
745 | struct clk_si5341_output *output = to_clk_si5341_output(hw); | ||
746 | int err; | ||
747 | u32 val; | ||
748 | |||
749 | err = regmap_read(output->data->regmap, | ||
750 | SI5341_OUT_MUX_SEL(output), &val); | ||
751 | |||
752 | return val & 0x7; | ||
753 | } | ||
754 | |||
755 | static const struct clk_ops si5341_output_clk_ops = { | ||
756 | .is_prepared = si5341_output_clk_is_on, | ||
757 | .prepare = si5341_output_clk_prepare, | ||
758 | .unprepare = si5341_output_clk_unprepare, | ||
759 | .recalc_rate = si5341_output_clk_recalc_rate, | ||
760 | .round_rate = si5341_output_clk_round_rate, | ||
761 | .set_rate = si5341_output_clk_set_rate, | ||
762 | .set_parent = si5341_output_set_parent, | ||
763 | .get_parent = si5341_output_get_parent, | ||
764 | }; | ||
765 | |||
766 | /* | ||
767 | * The chip can be bought in a pre-programmed version, or one can program the | ||
768 | * NVM in the chip to boot up in a preset mode. This routine tries to determine | ||
769 | * if that's the case, or if we need to reset and program everything from | ||
770 | * scratch. Returns negative error, or true/false. | ||
771 | */ | ||
772 | static int si5341_is_programmed_already(struct clk_si5341 *data) | ||
773 | { | ||
774 | int err; | ||
775 | u8 r[4]; | ||
776 | |||
777 | /* Read the PLL divider value, it must have a non-zero value */ | ||
778 | err = regmap_bulk_read(data->regmap, SI5341_PLL_M_DEN, | ||
779 | r, ARRAY_SIZE(r)); | ||
780 | if (err < 0) | ||
781 | return err; | ||
782 | |||
783 | return !!get_unaligned_le32(r); | ||
784 | } | ||
785 | |||
786 | static struct clk_hw * | ||
787 | of_clk_si5341_get(struct of_phandle_args *clkspec, void *_data) | ||
788 | { | ||
789 | struct clk_si5341 *data = _data; | ||
790 | unsigned int idx = clkspec->args[1]; | ||
791 | unsigned int group = clkspec->args[0]; | ||
792 | |||
793 | switch (group) { | ||
794 | case 0: | ||
795 | if (idx >= data->num_outputs) { | ||
796 | dev_err(&data->i2c_client->dev, | ||
797 | "invalid output index %u\n", idx); | ||
798 | return ERR_PTR(-EINVAL); | ||
799 | } | ||
800 | return &data->clk[idx].hw; | ||
801 | case 1: | ||
802 | if (idx >= data->num_synth) { | ||
803 | dev_err(&data->i2c_client->dev, | ||
804 | "invalid synthesizer index %u\n", idx); | ||
805 | return ERR_PTR(-EINVAL); | ||
806 | } | ||
807 | return &data->synth[idx].hw; | ||
808 | case 2: | ||
809 | if (idx > 0) { | ||
810 | dev_err(&data->i2c_client->dev, | ||
811 | "invalid PLL index %u\n", idx); | ||
812 | return ERR_PTR(-EINVAL); | ||
813 | } | ||
814 | return &data->hw; | ||
815 | default: | ||
816 | dev_err(&data->i2c_client->dev, "invalid group %u\n", group); | ||
817 | return ERR_PTR(-EINVAL); | ||
818 | } | ||
819 | } | ||
820 | |||
821 | static int si5341_probe_chip_id(struct clk_si5341 *data) | ||
822 | { | ||
823 | int err; | ||
824 | u8 reg[4]; | ||
825 | u16 model; | ||
826 | |||
827 | err = regmap_bulk_read(data->regmap, SI5341_PN_BASE, reg, | ||
828 | ARRAY_SIZE(reg)); | ||
829 | if (err < 0) { | ||
830 | dev_err(&data->i2c_client->dev, "Failed to read chip ID\n"); | ||
831 | return err; | ||
832 | } | ||
833 | |||
834 | model = get_unaligned_le16(reg); | ||
835 | |||
836 | dev_info(&data->i2c_client->dev, "Chip: %x Grade: %u Rev: %u\n", | ||
837 | model, reg[2], reg[3]); | ||
838 | |||
839 | switch (model) { | ||
840 | case 0x5340: | ||
841 | data->num_outputs = SI5340_MAX_NUM_OUTPUTS; | ||
842 | data->num_synth = SI5340_NUM_SYNTH; | ||
843 | data->reg_output_offset = si5340_reg_output_offset; | ||
844 | data->reg_rdiv_offset = si5340_reg_rdiv_offset; | ||
845 | break; | ||
846 | case 0x5341: | ||
847 | data->num_outputs = SI5341_MAX_NUM_OUTPUTS; | ||
848 | data->num_synth = SI5341_NUM_SYNTH; | ||
849 | data->reg_output_offset = si5341_reg_output_offset; | ||
850 | data->reg_rdiv_offset = si5341_reg_rdiv_offset; | ||
851 | break; | ||
852 | default: | ||
853 | dev_err(&data->i2c_client->dev, "Model '%x' not supported\n", | ||
854 | model); | ||
855 | return -EINVAL; | ||
856 | } | ||
857 | |||
858 | return 0; | ||
859 | } | ||
860 | |||
861 | /* Read active settings into the regmap cache for later reference */ | ||
862 | static int si5341_read_settings(struct clk_si5341 *data) | ||
863 | { | ||
864 | int err; | ||
865 | u8 i; | ||
866 | u8 r[10]; | ||
867 | |||
868 | err = regmap_bulk_read(data->regmap, SI5341_PLL_M_NUM, r, 10); | ||
869 | if (err < 0) | ||
870 | return err; | ||
871 | |||
872 | err = regmap_bulk_read(data->regmap, | ||
873 | SI5341_SYNTH_N_CLK_TO_OUTX_EN, r, 3); | ||
874 | if (err < 0) | ||
875 | return err; | ||
876 | |||
877 | err = regmap_bulk_read(data->regmap, | ||
878 | SI5341_SYNTH_N_CLK_DIS, r, 1); | ||
879 | if (err < 0) | ||
880 | return err; | ||
881 | |||
882 | for (i = 0; i < data->num_synth; ++i) { | ||
883 | err = regmap_bulk_read(data->regmap, | ||
884 | SI5341_SYNTH_N_NUM(i), r, 10); | ||
885 | if (err < 0) | ||
886 | return err; | ||
887 | } | ||
888 | |||
889 | for (i = 0; i < data->num_outputs; ++i) { | ||
890 | err = regmap_bulk_read(data->regmap, | ||
891 | data->reg_output_offset[i], r, 4); | ||
892 | if (err < 0) | ||
893 | return err; | ||
894 | |||
895 | err = regmap_bulk_read(data->regmap, | ||
896 | data->reg_rdiv_offset[i], r, 3); | ||
897 | if (err < 0) | ||
898 | return err; | ||
899 | } | ||
900 | |||
901 | return 0; | ||
902 | } | ||
903 | |||
904 | static int si5341_write_multiple(struct clk_si5341 *data, | ||
905 | const struct si5341_reg_default *values, unsigned int num_values) | ||
906 | { | ||
907 | unsigned int i; | ||
908 | int res; | ||
909 | |||
910 | for (i = 0; i < num_values; ++i) { | ||
911 | res = regmap_write(data->regmap, | ||
912 | values[i].address, values[i].value); | ||
913 | if (res < 0) { | ||
914 | dev_err(&data->i2c_client->dev, | ||
915 | "Failed to write %#x:%#x\n", | ||
916 | values[i].address, values[i].value); | ||
917 | return res; | ||
918 | } | ||
919 | } | ||
920 | |||
921 | return 0; | ||
922 | } | ||
923 | |||
924 | static const struct si5341_reg_default si5341_preamble[] = { | ||
925 | { 0x0B25, 0x00 }, | ||
926 | { 0x0502, 0x01 }, | ||
927 | { 0x0505, 0x03 }, | ||
928 | { 0x0957, 0x1F }, | ||
929 | { 0x0B4E, 0x1A }, | ||
930 | }; | ||
931 | |||
932 | static int si5341_send_preamble(struct clk_si5341 *data) | ||
933 | { | ||
934 | int res; | ||
935 | u32 revision; | ||
936 | |||
937 | /* For revision 2 and up, the values are slightly different */ | ||
938 | res = regmap_read(data->regmap, SI5341_DEVICE_REV, &revision); | ||
939 | if (res < 0) | ||
940 | return res; | ||
941 | |||
942 | /* Write "preamble" as specified by datasheet */ | ||
943 | res = regmap_write(data->regmap, 0xB24, revision < 2 ? 0xD8 : 0xC0); | ||
944 | if (res < 0) | ||
945 | return res; | ||
946 | res = si5341_write_multiple(data, | ||
947 | si5341_preamble, ARRAY_SIZE(si5341_preamble)); | ||
948 | if (res < 0) | ||
949 | return res; | ||
950 | |||
951 | /* Datasheet specifies a 300ms wait after sending the preamble */ | ||
952 | msleep(300); | ||
953 | |||
954 | return 0; | ||
955 | } | ||
956 | |||
957 | /* Perform a soft reset and write post-amble */ | ||
958 | static int si5341_finalize_defaults(struct clk_si5341 *data) | ||
959 | { | ||
960 | int res; | ||
961 | u32 revision; | ||
962 | |||
963 | res = regmap_read(data->regmap, SI5341_DEVICE_REV, &revision); | ||
964 | if (res < 0) | ||
965 | return res; | ||
966 | |||
967 | dev_dbg(&data->i2c_client->dev, "%s rev=%u\n", __func__, revision); | ||
968 | |||
969 | res = regmap_write(data->regmap, SI5341_SOFT_RST, 0x01); | ||
970 | if (res < 0) | ||
971 | return res; | ||
972 | |||
973 | /* Datasheet does not explain these nameless registers */ | ||
974 | res = regmap_write(data->regmap, 0xB24, revision < 2 ? 0xDB : 0xC3); | ||
975 | if (res < 0) | ||
976 | return res; | ||
977 | res = regmap_write(data->regmap, 0x0B25, 0x02); | ||
978 | if (res < 0) | ||
979 | return res; | ||
980 | |||
981 | return 0; | ||
982 | } | ||
983 | |||
984 | |||
985 | static const struct regmap_range si5341_regmap_volatile_range[] = { | ||
986 | regmap_reg_range(0x000C, 0x0012), /* Status */ | ||
987 | regmap_reg_range(0x001C, 0x001E), /* reset, finc/fdec */ | ||
988 | regmap_reg_range(0x00E2, 0x00FE), /* NVM, interrupts, device ready */ | ||
989 | /* Update bits for synth config */ | ||
990 | regmap_reg_range(SI5341_SYNTH_N_UPD(0), SI5341_SYNTH_N_UPD(0)), | ||
991 | regmap_reg_range(SI5341_SYNTH_N_UPD(1), SI5341_SYNTH_N_UPD(1)), | ||
992 | regmap_reg_range(SI5341_SYNTH_N_UPD(2), SI5341_SYNTH_N_UPD(2)), | ||
993 | regmap_reg_range(SI5341_SYNTH_N_UPD(3), SI5341_SYNTH_N_UPD(3)), | ||
994 | regmap_reg_range(SI5341_SYNTH_N_UPD(4), SI5341_SYNTH_N_UPD(4)), | ||
995 | }; | ||
996 | |||
997 | static const struct regmap_access_table si5341_regmap_volatile = { | ||
998 | .yes_ranges = si5341_regmap_volatile_range, | ||
999 | .n_yes_ranges = ARRAY_SIZE(si5341_regmap_volatile_range), | ||
1000 | }; | ||
1001 | |||
1002 | /* Pages 0, 1, 2, 3, 9, A, B are valid, so there are 12 pages */ | ||
1003 | static const struct regmap_range_cfg si5341_regmap_ranges[] = { | ||
1004 | { | ||
1005 | .range_min = 0, | ||
1006 | .range_max = SI5341_REGISTER_MAX, | ||
1007 | .selector_reg = SI5341_PAGE, | ||
1008 | .selector_mask = 0xff, | ||
1009 | .selector_shift = 0, | ||
1010 | .window_start = 0, | ||
1011 | .window_len = 256, | ||
1012 | }, | ||
1013 | }; | ||
1014 | |||
1015 | static const struct regmap_config si5341_regmap_config = { | ||
1016 | .reg_bits = 8, | ||
1017 | .val_bits = 8, | ||
1018 | .cache_type = REGCACHE_RBTREE, | ||
1019 | .ranges = si5341_regmap_ranges, | ||
1020 | .num_ranges = ARRAY_SIZE(si5341_regmap_ranges), | ||
1021 | .max_register = SI5341_REGISTER_MAX, | ||
1022 | .volatile_table = &si5341_regmap_volatile, | ||
1023 | }; | ||
1024 | |||
1025 | static int si5341_dt_parse_dt(struct i2c_client *client, | ||
1026 | struct clk_si5341_output_config *config) | ||
1027 | { | ||
1028 | struct device_node *child; | ||
1029 | struct device_node *np = client->dev.of_node; | ||
1030 | u32 num; | ||
1031 | u32 val; | ||
1032 | |||
1033 | memset(config, 0, sizeof(struct clk_si5341_output_config) * | ||
1034 | SI5341_MAX_NUM_OUTPUTS); | ||
1035 | |||
1036 | for_each_child_of_node(np, child) { | ||
1037 | if (of_property_read_u32(child, "reg", &num)) { | ||
1038 | dev_err(&client->dev, "missing reg property of %s\n", | ||
1039 | child->name); | ||
1040 | goto put_child; | ||
1041 | } | ||
1042 | |||
1043 | if (num >= SI5341_MAX_NUM_OUTPUTS) { | ||
1044 | dev_err(&client->dev, "invalid clkout %d\n", num); | ||
1045 | goto put_child; | ||
1046 | } | ||
1047 | |||
1048 | if (!of_property_read_u32(child, "silabs,format", &val)) { | ||
1049 | /* Set cm and ampl conservatively to 3v3 settings */ | ||
1050 | switch (val) { | ||
1051 | case 1: /* normal differential */ | ||
1052 | config[num].out_cm_ampl_bits = 0x33; | ||
1053 | break; | ||
1054 | case 2: /* low-power differential */ | ||
1055 | config[num].out_cm_ampl_bits = 0x13; | ||
1056 | break; | ||
1057 | case 4: /* LVCMOS */ | ||
1058 | config[num].out_cm_ampl_bits = 0x33; | ||
1059 | /* Set SI recommended impedance for LVCMOS */ | ||
1060 | config[num].out_format_drv_bits |= 0xc0; | ||
1061 | break; | ||
1062 | default: | ||
1063 | dev_err(&client->dev, | ||
1064 | "invalid silabs,format %u for %u\n", | ||
1065 | val, num); | ||
1066 | goto put_child; | ||
1067 | } | ||
1068 | config[num].out_format_drv_bits &= ~0x07; | ||
1069 | config[num].out_format_drv_bits |= val & 0x07; | ||
1070 | /* Always enable the SYNC feature */ | ||
1071 | config[num].out_format_drv_bits |= 0x08; | ||
1072 | } | ||
1073 | |||
1074 | if (!of_property_read_u32(child, "silabs,common-mode", &val)) { | ||
1075 | if (val > 0xf) { | ||
1076 | dev_err(&client->dev, | ||
1077 | "invalid silabs,common-mode %u\n", | ||
1078 | val); | ||
1079 | goto put_child; | ||
1080 | } | ||
1081 | config[num].out_cm_ampl_bits &= 0xf0; | ||
1082 | config[num].out_cm_ampl_bits |= val & 0x0f; | ||
1083 | } | ||
1084 | |||
1085 | if (!of_property_read_u32(child, "silabs,amplitude", &val)) { | ||
1086 | if (val > 0xf) { | ||
1087 | dev_err(&client->dev, | ||
1088 | "invalid silabs,amplitude %u\n", | ||
1089 | val); | ||
1090 | goto put_child; | ||
1091 | } | ||
1092 | config[num].out_cm_ampl_bits &= 0x0f; | ||
1093 | config[num].out_cm_ampl_bits |= (val << 4) & 0xf0; | ||
1094 | } | ||
1095 | |||
1096 | if (of_property_read_bool(child, "silabs,disable-high")) | ||
1097 | config[num].out_format_drv_bits |= 0x10; | ||
1098 | |||
1099 | config[num].synth_master = | ||
1100 | of_property_read_bool(child, "silabs,synth-master"); | ||
1101 | |||
1102 | config[num].always_on = | ||
1103 | of_property_read_bool(child, "always-on"); | ||
1104 | } | ||
1105 | |||
1106 | return 0; | ||
1107 | |||
1108 | put_child: | ||
1109 | of_node_put(child); | ||
1110 | return -EINVAL; | ||
1111 | } | ||
1112 | |||
1113 | /* | ||
1114 | * If not pre-configured, calculate and set the PLL configuration manually. | ||
1115 | * For low-jitter performance, the PLL should be set such that the synthesizers | ||
1116 | * only need integer division. | ||
1117 | * Without any user guidance, we'll set the PLL to 14GHz, which still allows | ||
1118 | * the chip to generate any frequency on its outputs, but jitter performance | ||
1119 | * may be sub-optimal. | ||
1120 | */ | ||
1121 | static int si5341_initialize_pll(struct clk_si5341 *data) | ||
1122 | { | ||
1123 | struct device_node *np = data->i2c_client->dev.of_node; | ||
1124 | u32 m_num = 0; | ||
1125 | u32 m_den = 0; | ||
1126 | |||
1127 | if (of_property_read_u32(np, "silabs,pll-m-num", &m_num)) { | ||
1128 | dev_err(&data->i2c_client->dev, | ||
1129 | "PLL configuration requires silabs,pll-m-num\n"); | ||
1130 | } | ||
1131 | if (of_property_read_u32(np, "silabs,pll-m-den", &m_den)) { | ||
1132 | dev_err(&data->i2c_client->dev, | ||
1133 | "PLL configuration requires silabs,pll-m-den\n"); | ||
1134 | } | ||
1135 | |||
1136 | if (!m_num || !m_den) { | ||
1137 | dev_err(&data->i2c_client->dev, | ||
1138 | "PLL configuration invalid, assume 14GHz\n"); | ||
1139 | m_den = clk_get_rate(data->pxtal) / 10; | ||
1140 | m_num = 1400000000; | ||
1141 | } | ||
1142 | |||
1143 | return si5341_encode_44_32(data->regmap, | ||
1144 | SI5341_PLL_M_NUM, m_num, m_den); | ||
1145 | } | ||
1146 | |||
1147 | static int si5341_probe(struct i2c_client *client, | ||
1148 | const struct i2c_device_id *id) | ||
1149 | { | ||
1150 | struct clk_si5341 *data; | ||
1151 | struct clk_init_data init; | ||
1152 | const char *root_clock_name; | ||
1153 | const char *synth_clock_names[SI5341_NUM_SYNTH]; | ||
1154 | int err; | ||
1155 | unsigned int i; | ||
1156 | struct clk_si5341_output_config config[SI5341_MAX_NUM_OUTPUTS]; | ||
1157 | bool initialization_required; | ||
1158 | |||
1159 | data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL); | ||
1160 | if (!data) | ||
1161 | return -ENOMEM; | ||
1162 | |||
1163 | data->i2c_client = client; | ||
1164 | |||
1165 | data->pxtal = devm_clk_get(&client->dev, "xtal"); | ||
1166 | if (IS_ERR(data->pxtal)) { | ||
1167 | if (PTR_ERR(data->pxtal) == -EPROBE_DEFER) | ||
1168 | return -EPROBE_DEFER; | ||
1169 | |||
1170 | dev_err(&client->dev, "Missing xtal clock input\n"); | ||
1171 | } | ||
1172 | |||
1173 | err = si5341_dt_parse_dt(client, config); | ||
1174 | if (err) | ||
1175 | return err; | ||
1176 | |||
1177 | if (of_property_read_string(client->dev.of_node, "clock-output-names", | ||
1178 | &init.name)) | ||
1179 | init.name = client->dev.of_node->name; | ||
1180 | root_clock_name = init.name; | ||
1181 | |||
1182 | data->regmap = devm_regmap_init_i2c(client, &si5341_regmap_config); | ||
1183 | if (IS_ERR(data->regmap)) | ||
1184 | return PTR_ERR(data->regmap); | ||
1185 | |||
1186 | i2c_set_clientdata(client, data); | ||
1187 | |||
1188 | err = si5341_probe_chip_id(data); | ||
1189 | if (err < 0) | ||
1190 | return err; | ||
1191 | |||
1192 | /* "Activate" the xtal (usually a fixed clock) */ | ||
1193 | clk_prepare_enable(data->pxtal); | ||
1194 | |||
1195 | if (of_property_read_bool(client->dev.of_node, "silabs,reprogram")) { | ||
1196 | initialization_required = true; | ||
1197 | } else { | ||
1198 | err = si5341_is_programmed_already(data); | ||
1199 | if (err < 0) | ||
1200 | return err; | ||
1201 | |||
1202 | initialization_required = !err; | ||
1203 | } | ||
1204 | |||
1205 | if (initialization_required) { | ||
1206 | /* Populate the regmap cache in preparation for "cache only" */ | ||
1207 | err = si5341_read_settings(data); | ||
1208 | if (err < 0) | ||
1209 | return err; | ||
1210 | |||
1211 | err = si5341_send_preamble(data); | ||
1212 | if (err < 0) | ||
1213 | return err; | ||
1214 | |||
1215 | /* | ||
1216 | * We intend to send all 'final' register values in a single | ||
1217 | * transaction. So cache all register writes until we're done | ||
1218 | * configuring. | ||
1219 | */ | ||
1220 | regcache_cache_only(data->regmap, true); | ||
1221 | |||
1222 | /* Write the configuration pairs from the firmware blob */ | ||
1223 | err = si5341_write_multiple(data, si5341_reg_defaults, | ||
1224 | ARRAY_SIZE(si5341_reg_defaults)); | ||
1225 | if (err < 0) | ||
1226 | return err; | ||
1227 | |||
1228 | /* PLL configuration is required */ | ||
1229 | err = si5341_initialize_pll(data); | ||
1230 | if (err < 0) | ||
1231 | return err; | ||
1232 | } | ||
1233 | |||
1234 | /* Register the PLL */ | ||
1235 | data->pxtal_name = __clk_get_name(data->pxtal); | ||
1236 | init.parent_names = &data->pxtal_name; | ||
1237 | init.num_parents = 1; /* For now, only XTAL input supported */ | ||
1238 | init.ops = &si5341_clk_ops; | ||
1239 | init.flags = 0; | ||
1240 | data->hw.init = &init; | ||
1241 | |||
1242 | err = devm_clk_hw_register(&client->dev, &data->hw); | ||
1243 | if (err) { | ||
1244 | dev_err(&client->dev, "clock registration failed\n"); | ||
1245 | return err; | ||
1246 | } | ||
1247 | |||
1248 | init.num_parents = 1; | ||
1249 | init.parent_names = &root_clock_name; | ||
1250 | init.ops = &si5341_synth_clk_ops; | ||
1251 | for (i = 0; i < data->num_synth; ++i) { | ||
1252 | synth_clock_names[i] = devm_kasprintf(&client->dev, GFP_KERNEL, | ||
1253 | "%s.N%u", client->dev.of_node->name, i); | ||
1254 | init.name = synth_clock_names[i]; | ||
1255 | data->synth[i].index = i; | ||
1256 | data->synth[i].data = data; | ||
1257 | data->synth[i].hw.init = &init; | ||
1258 | err = devm_clk_hw_register(&client->dev, &data->synth[i].hw); | ||
1259 | if (err) { | ||
1260 | dev_err(&client->dev, | ||
1261 | "synth N%u registration failed\n", i); | ||
1262 | } | ||
1263 | } | ||
1264 | |||
1265 | init.num_parents = data->num_synth; | ||
1266 | init.parent_names = synth_clock_names; | ||
1267 | init.ops = &si5341_output_clk_ops; | ||
1268 | for (i = 0; i < data->num_outputs; ++i) { | ||
1269 | init.name = kasprintf(GFP_KERNEL, "%s.%d", | ||
1270 | client->dev.of_node->name, i); | ||
1271 | init.flags = config[i].synth_master ? CLK_SET_RATE_PARENT : 0; | ||
1272 | data->clk[i].index = i; | ||
1273 | data->clk[i].data = data; | ||
1274 | data->clk[i].hw.init = &init; | ||
1275 | if (config[i].out_format_drv_bits & 0x07) { | ||
1276 | regmap_write(data->regmap, | ||
1277 | SI5341_OUT_FORMAT(&data->clk[i]), | ||
1278 | config[i].out_format_drv_bits); | ||
1279 | regmap_write(data->regmap, | ||
1280 | SI5341_OUT_CM(&data->clk[i]), | ||
1281 | config[i].out_cm_ampl_bits); | ||
1282 | } | ||
1283 | err = devm_clk_hw_register(&client->dev, &data->clk[i].hw); | ||
1284 | kfree(init.name); /* clock framework made a copy of the name */ | ||
1285 | if (err) { | ||
1286 | dev_err(&client->dev, | ||
1287 | "output %u registration failed\n", i); | ||
1288 | return err; | ||
1289 | } | ||
1290 | if (config[i].always_on) | ||
1291 | clk_prepare(data->clk[i].hw.clk); | ||
1292 | } | ||
1293 | |||
1294 | err = of_clk_add_hw_provider(client->dev.of_node, of_clk_si5341_get, | ||
1295 | data); | ||
1296 | if (err) { | ||
1297 | dev_err(&client->dev, "unable to add clk provider\n"); | ||
1298 | return err; | ||
1299 | } | ||
1300 | |||
1301 | if (initialization_required) { | ||
1302 | /* Synchronize */ | ||
1303 | regcache_cache_only(data->regmap, false); | ||
1304 | err = regcache_sync(data->regmap); | ||
1305 | if (err < 0) | ||
1306 | return err; | ||
1307 | |||
1308 | err = si5341_finalize_defaults(data); | ||
1309 | if (err < 0) | ||
1310 | return err; | ||
1311 | } | ||
1312 | |||
1313 | /* Free the names, clk framework makes copies */ | ||
1314 | for (i = 0; i < data->num_synth; ++i) | ||
1315 | devm_kfree(&client->dev, (void *)synth_clock_names[i]); | ||
1316 | |||
1317 | return 0; | ||
1318 | } | ||
1319 | |||
1320 | static const struct i2c_device_id si5341_id[] = { | ||
1321 | { "si5340", 0 }, | ||
1322 | { "si5341", 1 }, | ||
1323 | { } | ||
1324 | }; | ||
1325 | MODULE_DEVICE_TABLE(i2c, si5341_id); | ||
1326 | |||
1327 | static const struct of_device_id clk_si5341_of_match[] = { | ||
1328 | { .compatible = "silabs,si5340" }, | ||
1329 | { .compatible = "silabs,si5341" }, | ||
1330 | { } | ||
1331 | }; | ||
1332 | MODULE_DEVICE_TABLE(of, clk_si5341_of_match); | ||
1333 | |||
1334 | static struct i2c_driver si5341_driver = { | ||
1335 | .driver = { | ||
1336 | .name = "si5341", | ||
1337 | .of_match_table = clk_si5341_of_match, | ||
1338 | }, | ||
1339 | .probe = si5341_probe, | ||
1340 | .id_table = si5341_id, | ||
1341 | }; | ||
1342 | module_i2c_driver(si5341_driver); | ||
1343 | |||
1344 | MODULE_AUTHOR("Mike Looijmans <mike.looijmans@topic.nl>"); | ||
1345 | MODULE_DESCRIPTION("Si5341 driver"); | ||
1346 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/clk/clk-si544.c b/drivers/clk/clk-si544.c index 64e607f3232a..d9ec9086184d 100644 --- a/drivers/clk/clk-si544.c +++ b/drivers/clk/clk-si544.c | |||
@@ -7,6 +7,7 @@ | |||
7 | 7 | ||
8 | #include <linux/clk-provider.h> | 8 | #include <linux/clk-provider.h> |
9 | #include <linux/delay.h> | 9 | #include <linux/delay.h> |
10 | #include <linux/math64.h> | ||
10 | #include <linux/module.h> | 11 | #include <linux/module.h> |
11 | #include <linux/i2c.h> | 12 | #include <linux/i2c.h> |
12 | #include <linux/regmap.h> | 13 | #include <linux/regmap.h> |
@@ -50,6 +51,11 @@ | |||
50 | /* Lowest frequency synthesizeable using only the HS divider */ | 51 | /* Lowest frequency synthesizeable using only the HS divider */ |
51 | #define MIN_HSDIV_FREQ (FVCO_MIN / HS_DIV_MAX) | 52 | #define MIN_HSDIV_FREQ (FVCO_MIN / HS_DIV_MAX) |
52 | 53 | ||
54 | /* Range and interpretation of the adjustment value */ | ||
55 | #define DELTA_M_MAX 8161512 | ||
56 | #define DELTA_M_FRAC_NUM 19 | ||
57 | #define DELTA_M_FRAC_DEN 20000 | ||
58 | |||
53 | enum si544_speed_grade { | 59 | enum si544_speed_grade { |
54 | si544a, | 60 | si544a, |
55 | si544b, | 61 | si544b, |
@@ -71,12 +77,14 @@ struct clk_si544 { | |||
71 | * @hs_div: 1st divider, 5..2046, must be even when >33 | 77 | * @hs_div: 1st divider, 5..2046, must be even when >33 |
72 | * @ls_div_bits: 2nd divider, as 2^x, range 0..5 | 78 | * @ls_div_bits: 2nd divider, as 2^x, range 0..5 |
73 | * If ls_div_bits is non-zero, hs_div must be even | 79 | * If ls_div_bits is non-zero, hs_div must be even |
80 | * @delta_m: Frequency shift for small -950..+950 ppm changes, 24 bit | ||
74 | */ | 81 | */ |
75 | struct clk_si544_muldiv { | 82 | struct clk_si544_muldiv { |
76 | u32 fb_div_frac; | 83 | u32 fb_div_frac; |
77 | u16 fb_div_int; | 84 | u16 fb_div_int; |
78 | u16 hs_div; | 85 | u16 hs_div; |
79 | u8 ls_div_bits; | 86 | u8 ls_div_bits; |
87 | s32 delta_m; | ||
80 | }; | 88 | }; |
81 | 89 | ||
82 | /* Enables or disables the output driver */ | 90 | /* Enables or disables the output driver */ |
@@ -134,9 +142,30 @@ static int si544_get_muldiv(struct clk_si544 *data, | |||
134 | settings->fb_div_int = reg[4] | (reg[5] & 0x07) << 8; | 142 | settings->fb_div_int = reg[4] | (reg[5] & 0x07) << 8; |
135 | settings->fb_div_frac = reg[0] | reg[1] << 8 | reg[2] << 16 | | 143 | settings->fb_div_frac = reg[0] | reg[1] << 8 | reg[2] << 16 | |
136 | reg[3] << 24; | 144 | reg[3] << 24; |
145 | |||
146 | err = regmap_bulk_read(data->regmap, SI544_REG_ADPLL_DELTA_M0, reg, 3); | ||
147 | if (err) | ||
148 | return err; | ||
149 | |||
150 | /* Interpret as 24-bit signed number */ | ||
151 | settings->delta_m = reg[0] << 8 | reg[1] << 16 | reg[2] << 24; | ||
152 | settings->delta_m >>= 8; | ||
153 | |||
137 | return 0; | 154 | return 0; |
138 | } | 155 | } |
139 | 156 | ||
157 | static int si544_set_delta_m(struct clk_si544 *data, s32 delta_m) | ||
158 | { | ||
159 | u8 reg[3]; | ||
160 | |||
161 | reg[0] = delta_m; | ||
162 | reg[1] = delta_m >> 8; | ||
163 | reg[2] = delta_m >> 16; | ||
164 | |||
165 | return regmap_bulk_write(data->regmap, SI544_REG_ADPLL_DELTA_M0, | ||
166 | reg, 3); | ||
167 | } | ||
168 | |||
140 | static int si544_set_muldiv(struct clk_si544 *data, | 169 | static int si544_set_muldiv(struct clk_si544 *data, |
141 | struct clk_si544_muldiv *settings) | 170 | struct clk_si544_muldiv *settings) |
142 | { | 171 | { |
@@ -238,11 +267,15 @@ static int si544_calc_muldiv(struct clk_si544_muldiv *settings, | |||
238 | do_div(vco, FXO); | 267 | do_div(vco, FXO); |
239 | settings->fb_div_frac = vco; | 268 | settings->fb_div_frac = vco; |
240 | 269 | ||
270 | /* Reset the frequency adjustment */ | ||
271 | settings->delta_m = 0; | ||
272 | |||
241 | return 0; | 273 | return 0; |
242 | } | 274 | } |
243 | 275 | ||
244 | /* Calculate resulting frequency given the register settings */ | 276 | /* Calculate resulting frequency given the register settings */ |
245 | static unsigned long si544_calc_rate(struct clk_si544_muldiv *settings) | 277 | static unsigned long si544_calc_center_rate( |
278 | const struct clk_si544_muldiv *settings) | ||
246 | { | 279 | { |
247 | u32 d = settings->hs_div * BIT(settings->ls_div_bits); | 280 | u32 d = settings->hs_div * BIT(settings->ls_div_bits); |
248 | u64 vco; | 281 | u64 vco; |
@@ -261,6 +294,25 @@ static unsigned long si544_calc_rate(struct clk_si544_muldiv *settings) | |||
261 | return vco; | 294 | return vco; |
262 | } | 295 | } |
263 | 296 | ||
297 | static unsigned long si544_calc_rate(const struct clk_si544_muldiv *settings) | ||
298 | { | ||
299 | unsigned long rate = si544_calc_center_rate(settings); | ||
300 | s64 delta = (s64)rate * (DELTA_M_FRAC_NUM * settings->delta_m); | ||
301 | |||
302 | /* | ||
303 | * The clock adjustment is much smaller than 1 Hz, round to the | ||
304 | * nearest multiple. Apparently div64_s64 rounds towards zero, hence | ||
305 | * check the sign and adjust into the proper direction. | ||
306 | */ | ||
307 | if (settings->delta_m < 0) | ||
308 | delta -= ((s64)DELTA_M_MAX * DELTA_M_FRAC_DEN) / 2; | ||
309 | else | ||
310 | delta += ((s64)DELTA_M_MAX * DELTA_M_FRAC_DEN) / 2; | ||
311 | delta = div64_s64(delta, ((s64)DELTA_M_MAX * DELTA_M_FRAC_DEN)); | ||
312 | |||
313 | return rate + delta; | ||
314 | } | ||
315 | |||
264 | static unsigned long si544_recalc_rate(struct clk_hw *hw, | 316 | static unsigned long si544_recalc_rate(struct clk_hw *hw, |
265 | unsigned long parent_rate) | 317 | unsigned long parent_rate) |
266 | { | 318 | { |
@@ -279,33 +331,60 @@ static long si544_round_rate(struct clk_hw *hw, unsigned long rate, | |||
279 | unsigned long *parent_rate) | 331 | unsigned long *parent_rate) |
280 | { | 332 | { |
281 | struct clk_si544 *data = to_clk_si544(hw); | 333 | struct clk_si544 *data = to_clk_si544(hw); |
282 | struct clk_si544_muldiv settings; | ||
283 | int err; | ||
284 | 334 | ||
285 | if (!is_valid_frequency(data, rate)) | 335 | if (!is_valid_frequency(data, rate)) |
286 | return -EINVAL; | 336 | return -EINVAL; |
287 | 337 | ||
288 | err = si544_calc_muldiv(&settings, rate); | 338 | /* The accuracy is less than 1 Hz, so any rate is possible */ |
289 | if (err) | 339 | return rate; |
290 | return err; | 340 | } |
291 | 341 | ||
292 | return si544_calc_rate(&settings); | 342 | /* Calculates the maximum "small" change, 950 * rate / 1000000 */ |
343 | static unsigned long si544_max_delta(unsigned long rate) | ||
344 | { | ||
345 | u64 num = rate; | ||
346 | |||
347 | num *= DELTA_M_FRAC_NUM; | ||
348 | do_div(num, DELTA_M_FRAC_DEN); | ||
349 | |||
350 | return num; | ||
351 | } | ||
352 | |||
353 | static s32 si544_calc_delta(s32 delta, s32 max_delta) | ||
354 | { | ||
355 | s64 n = (s64)delta * DELTA_M_MAX; | ||
356 | |||
357 | return div_s64(n, max_delta); | ||
293 | } | 358 | } |
294 | 359 | ||
295 | /* | ||
296 | * Update output frequency for "big" frequency changes | ||
297 | */ | ||
298 | static int si544_set_rate(struct clk_hw *hw, unsigned long rate, | 360 | static int si544_set_rate(struct clk_hw *hw, unsigned long rate, |
299 | unsigned long parent_rate) | 361 | unsigned long parent_rate) |
300 | { | 362 | { |
301 | struct clk_si544 *data = to_clk_si544(hw); | 363 | struct clk_si544 *data = to_clk_si544(hw); |
302 | struct clk_si544_muldiv settings; | 364 | struct clk_si544_muldiv settings; |
365 | unsigned long center; | ||
366 | long max_delta; | ||
367 | long delta; | ||
303 | unsigned int old_oe_state; | 368 | unsigned int old_oe_state; |
304 | int err; | 369 | int err; |
305 | 370 | ||
306 | if (!is_valid_frequency(data, rate)) | 371 | if (!is_valid_frequency(data, rate)) |
307 | return -EINVAL; | 372 | return -EINVAL; |
308 | 373 | ||
374 | /* Try using the frequency adjustment feature for a <= 950ppm change */ | ||
375 | err = si544_get_muldiv(data, &settings); | ||
376 | if (err) | ||
377 | return err; | ||
378 | |||
379 | center = si544_calc_center_rate(&settings); | ||
380 | max_delta = si544_max_delta(center); | ||
381 | delta = rate - center; | ||
382 | |||
383 | if (abs(delta) <= max_delta) | ||
384 | return si544_set_delta_m(data, | ||
385 | si544_calc_delta(delta, max_delta)); | ||
386 | |||
387 | /* Too big for the delta adjustment, need to reprogram */ | ||
309 | err = si544_calc_muldiv(&settings, rate); | 388 | err = si544_calc_muldiv(&settings, rate); |
310 | if (err) | 389 | if (err) |
311 | return err; | 390 | return err; |
@@ -321,6 +400,9 @@ static int si544_set_rate(struct clk_hw *hw, unsigned long rate, | |||
321 | if (err < 0) | 400 | if (err < 0) |
322 | return err; | 401 | return err; |
323 | 402 | ||
403 | err = si544_set_delta_m(data, settings.delta_m); | ||
404 | if (err < 0) | ||
405 | return err; | ||
324 | 406 | ||
325 | err = si544_set_muldiv(data, &settings); | 407 | err = si544_set_muldiv(data, &settings); |
326 | if (err < 0) | 408 | if (err < 0) |
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 87b410d6e51d..c0990703ce54 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c | |||
@@ -1324,10 +1324,7 @@ static void clk_core_init_rate_req(struct clk_core * const core, | |||
1324 | 1324 | ||
1325 | static bool clk_core_can_round(struct clk_core * const core) | 1325 | static bool clk_core_can_round(struct clk_core * const core) |
1326 | { | 1326 | { |
1327 | if (core->ops->determine_rate || core->ops->round_rate) | 1327 | return core->ops->determine_rate || core->ops->round_rate; |
1328 | return true; | ||
1329 | |||
1330 | return false; | ||
1331 | } | 1328 | } |
1332 | 1329 | ||
1333 | static int clk_core_round_rate_nolock(struct clk_core *core, | 1330 | static int clk_core_round_rate_nolock(struct clk_core *core, |
@@ -2194,7 +2191,7 @@ int clk_set_rate(struct clk *clk, unsigned long rate) | |||
2194 | EXPORT_SYMBOL_GPL(clk_set_rate); | 2191 | EXPORT_SYMBOL_GPL(clk_set_rate); |
2195 | 2192 | ||
2196 | /** | 2193 | /** |
2197 | * clk_set_rate_exclusive - specify a new rate get exclusive control | 2194 | * clk_set_rate_exclusive - specify a new rate and get exclusive control |
2198 | * @clk: the clk whose rate is being changed | 2195 | * @clk: the clk whose rate is being changed |
2199 | * @rate: the new rate for clk | 2196 | * @rate: the new rate for clk |
2200 | * | 2197 | * |
@@ -2202,7 +2199,7 @@ EXPORT_SYMBOL_GPL(clk_set_rate); | |||
2202 | * within a critical section | 2199 | * within a critical section |
2203 | * | 2200 | * |
2204 | * This can be used initially to ensure that at least 1 consumer is | 2201 | * This can be used initially to ensure that at least 1 consumer is |
2205 | * statisfied when several consumers are competing for exclusivity over the | 2202 | * satisfied when several consumers are competing for exclusivity over the |
2206 | * same clock provider. | 2203 | * same clock provider. |
2207 | * | 2204 | * |
2208 | * The exclusivity is not applied if setting the rate failed. | 2205 | * The exclusivity is not applied if setting the rate failed. |
@@ -2997,20 +2994,65 @@ static int clk_flags_show(struct seq_file *s, void *data) | |||
2997 | } | 2994 | } |
2998 | DEFINE_SHOW_ATTRIBUTE(clk_flags); | 2995 | DEFINE_SHOW_ATTRIBUTE(clk_flags); |
2999 | 2996 | ||
2997 | static void possible_parent_show(struct seq_file *s, struct clk_core *core, | ||
2998 | unsigned int i, char terminator) | ||
2999 | { | ||
3000 | struct clk_core *parent; | ||
3001 | |||
3002 | /* | ||
3003 | * Go through the following options to fetch a parent's name. | ||
3004 | * | ||
3005 | * 1. Fetch the registered parent clock and use its name | ||
3006 | * 2. Use the global (fallback) name if specified | ||
3007 | * 3. Use the local fw_name if provided | ||
3008 | * 4. Fetch parent clock's clock-output-name if DT index was set | ||
3009 | * | ||
3010 | * This may still fail in some cases, such as when the parent is | ||
3011 | * specified directly via a struct clk_hw pointer, but it isn't | ||
3012 | * registered (yet). | ||
3013 | */ | ||
3014 | parent = clk_core_get_parent_by_index(core, i); | ||
3015 | if (parent) | ||
3016 | seq_printf(s, "%s", parent->name); | ||
3017 | else if (core->parents[i].name) | ||
3018 | seq_printf(s, "%s", core->parents[i].name); | ||
3019 | else if (core->parents[i].fw_name) | ||
3020 | seq_printf(s, "<%s>(fw)", core->parents[i].fw_name); | ||
3021 | else if (core->parents[i].index >= 0) | ||
3022 | seq_printf(s, "%s", | ||
3023 | of_clk_get_parent_name(core->of_node, | ||
3024 | core->parents[i].index)); | ||
3025 | else | ||
3026 | seq_puts(s, "(missing)"); | ||
3027 | |||
3028 | seq_putc(s, terminator); | ||
3029 | } | ||
3030 | |||
3000 | static int possible_parents_show(struct seq_file *s, void *data) | 3031 | static int possible_parents_show(struct seq_file *s, void *data) |
3001 | { | 3032 | { |
3002 | struct clk_core *core = s->private; | 3033 | struct clk_core *core = s->private; |
3003 | int i; | 3034 | int i; |
3004 | 3035 | ||
3005 | for (i = 0; i < core->num_parents - 1; i++) | 3036 | for (i = 0; i < core->num_parents - 1; i++) |
3006 | seq_printf(s, "%s ", core->parents[i].name); | 3037 | possible_parent_show(s, core, i, ' '); |
3007 | 3038 | ||
3008 | seq_printf(s, "%s\n", core->parents[i].name); | 3039 | possible_parent_show(s, core, i, '\n'); |
3009 | 3040 | ||
3010 | return 0; | 3041 | return 0; |
3011 | } | 3042 | } |
3012 | DEFINE_SHOW_ATTRIBUTE(possible_parents); | 3043 | DEFINE_SHOW_ATTRIBUTE(possible_parents); |
3013 | 3044 | ||
3045 | static int current_parent_show(struct seq_file *s, void *data) | ||
3046 | { | ||
3047 | struct clk_core *core = s->private; | ||
3048 | |||
3049 | if (core->parent) | ||
3050 | seq_printf(s, "%s\n", core->parent->name); | ||
3051 | |||
3052 | return 0; | ||
3053 | } | ||
3054 | DEFINE_SHOW_ATTRIBUTE(current_parent); | ||
3055 | |||
3014 | static int clk_duty_cycle_show(struct seq_file *s, void *data) | 3056 | static int clk_duty_cycle_show(struct seq_file *s, void *data) |
3015 | { | 3057 | { |
3016 | struct clk_core *core = s->private; | 3058 | struct clk_core *core = s->private; |
@@ -3043,6 +3085,10 @@ static void clk_debug_create_one(struct clk_core *core, struct dentry *pdentry) | |||
3043 | debugfs_create_file("clk_duty_cycle", 0444, root, core, | 3085 | debugfs_create_file("clk_duty_cycle", 0444, root, core, |
3044 | &clk_duty_cycle_fops); | 3086 | &clk_duty_cycle_fops); |
3045 | 3087 | ||
3088 | if (core->num_parents > 0) | ||
3089 | debugfs_create_file("clk_parent", 0444, root, core, | ||
3090 | ¤t_parent_fops); | ||
3091 | |||
3046 | if (core->num_parents > 1) | 3092 | if (core->num_parents > 1) |
3047 | debugfs_create_file("clk_possible_parents", 0444, root, core, | 3093 | debugfs_create_file("clk_possible_parents", 0444, root, core, |
3048 | &possible_parents_fops); | 3094 | &possible_parents_fops); |
@@ -4038,6 +4084,7 @@ struct of_clk_provider { | |||
4038 | void *data; | 4084 | void *data; |
4039 | }; | 4085 | }; |
4040 | 4086 | ||
4087 | extern struct of_device_id __clk_of_table; | ||
4041 | static const struct of_device_id __clk_of_table_sentinel | 4088 | static const struct of_device_id __clk_of_table_sentinel |
4042 | __used __section(__clk_of_table_end); | 4089 | __used __section(__clk_of_table_end); |
4043 | 4090 | ||
diff --git a/drivers/clk/clk.h b/drivers/clk/clk.h index d8400d623b34..2d801900cad5 100644 --- a/drivers/clk/clk.h +++ b/drivers/clk/clk.h | |||
@@ -33,10 +33,6 @@ clk_hw_create_clk(struct device *dev, struct clk_hw *hw, const char *dev_id, | |||
33 | { | 33 | { |
34 | return (struct clk *)hw; | 34 | return (struct clk *)hw; |
35 | } | 35 | } |
36 | static struct clk_hw *__clk_get_hw(struct clk *clk) | ||
37 | { | ||
38 | return (struct clk_hw *)clk; | ||
39 | } | ||
40 | static inline void __clk_put(struct clk *clk) { } | 36 | static inline void __clk_put(struct clk *clk) { } |
41 | 37 | ||
42 | #endif | 38 | #endif |
diff --git a/drivers/clk/imx/clk-busy.c b/drivers/clk/imx/clk-busy.c index 7b35a11238ca..25c863da32c7 100644 --- a/drivers/clk/imx/clk-busy.c +++ b/drivers/clk/imx/clk-busy.c | |||
@@ -72,13 +72,14 @@ static const struct clk_ops clk_busy_divider_ops = { | |||
72 | .set_rate = clk_busy_divider_set_rate, | 72 | .set_rate = clk_busy_divider_set_rate, |
73 | }; | 73 | }; |
74 | 74 | ||
75 | struct clk *imx_clk_busy_divider(const char *name, const char *parent_name, | 75 | struct clk_hw *imx_clk_hw_busy_divider(const char *name, const char *parent_name, |
76 | void __iomem *reg, u8 shift, u8 width, | 76 | void __iomem *reg, u8 shift, u8 width, |
77 | void __iomem *busy_reg, u8 busy_shift) | 77 | void __iomem *busy_reg, u8 busy_shift) |
78 | { | 78 | { |
79 | struct clk_busy_divider *busy; | 79 | struct clk_busy_divider *busy; |
80 | struct clk *clk; | 80 | struct clk_hw *hw; |
81 | struct clk_init_data init; | 81 | struct clk_init_data init; |
82 | int ret; | ||
82 | 83 | ||
83 | busy = kzalloc(sizeof(*busy), GFP_KERNEL); | 84 | busy = kzalloc(sizeof(*busy), GFP_KERNEL); |
84 | if (!busy) | 85 | if (!busy) |
@@ -101,11 +102,15 @@ struct clk *imx_clk_busy_divider(const char *name, const char *parent_name, | |||
101 | 102 | ||
102 | busy->div.hw.init = &init; | 103 | busy->div.hw.init = &init; |
103 | 104 | ||
104 | clk = clk_register(NULL, &busy->div.hw); | 105 | hw = &busy->div.hw; |
105 | if (IS_ERR(clk)) | 106 | |
107 | ret = clk_hw_register(NULL, hw); | ||
108 | if (ret) { | ||
106 | kfree(busy); | 109 | kfree(busy); |
110 | return ERR_PTR(ret); | ||
111 | } | ||
107 | 112 | ||
108 | return clk; | 113 | return hw; |
109 | } | 114 | } |
110 | 115 | ||
111 | struct clk_busy_mux { | 116 | struct clk_busy_mux { |
@@ -146,13 +151,14 @@ static const struct clk_ops clk_busy_mux_ops = { | |||
146 | .set_parent = clk_busy_mux_set_parent, | 151 | .set_parent = clk_busy_mux_set_parent, |
147 | }; | 152 | }; |
148 | 153 | ||
149 | struct clk *imx_clk_busy_mux(const char *name, void __iomem *reg, u8 shift, | 154 | struct clk_hw *imx_clk_hw_busy_mux(const char *name, void __iomem *reg, u8 shift, |
150 | u8 width, void __iomem *busy_reg, u8 busy_shift, | 155 | u8 width, void __iomem *busy_reg, u8 busy_shift, |
151 | const char * const *parent_names, int num_parents) | 156 | const char * const *parent_names, int num_parents) |
152 | { | 157 | { |
153 | struct clk_busy_mux *busy; | 158 | struct clk_busy_mux *busy; |
154 | struct clk *clk; | 159 | struct clk_hw *hw; |
155 | struct clk_init_data init; | 160 | struct clk_init_data init; |
161 | int ret; | ||
156 | 162 | ||
157 | busy = kzalloc(sizeof(*busy), GFP_KERNEL); | 163 | busy = kzalloc(sizeof(*busy), GFP_KERNEL); |
158 | if (!busy) | 164 | if (!busy) |
@@ -175,9 +181,13 @@ struct clk *imx_clk_busy_mux(const char *name, void __iomem *reg, u8 shift, | |||
175 | 181 | ||
176 | busy->mux.hw.init = &init; | 182 | busy->mux.hw.init = &init; |
177 | 183 | ||
178 | clk = clk_register(NULL, &busy->mux.hw); | 184 | hw = &busy->mux.hw; |
179 | if (IS_ERR(clk)) | 185 | |
186 | ret = clk_hw_register(NULL, hw); | ||
187 | if (ret) { | ||
180 | kfree(busy); | 188 | kfree(busy); |
189 | return ERR_PTR(ret); | ||
190 | } | ||
181 | 191 | ||
182 | return clk; | 192 | return hw; |
183 | } | 193 | } |
diff --git a/drivers/clk/imx/clk-cpu.c b/drivers/clk/imx/clk-cpu.c index 00d026eb7891..cb182bec79ba 100644 --- a/drivers/clk/imx/clk-cpu.c +++ b/drivers/clk/imx/clk-cpu.c | |||
@@ -69,13 +69,14 @@ static const struct clk_ops clk_cpu_ops = { | |||
69 | .set_rate = clk_cpu_set_rate, | 69 | .set_rate = clk_cpu_set_rate, |
70 | }; | 70 | }; |
71 | 71 | ||
72 | struct clk *imx_clk_cpu(const char *name, const char *parent_name, | 72 | struct clk_hw *imx_clk_hw_cpu(const char *name, const char *parent_name, |
73 | struct clk *div, struct clk *mux, struct clk *pll, | 73 | struct clk *div, struct clk *mux, struct clk *pll, |
74 | struct clk *step) | 74 | struct clk *step) |
75 | { | 75 | { |
76 | struct clk_cpu *cpu; | 76 | struct clk_cpu *cpu; |
77 | struct clk *clk; | 77 | struct clk_hw *hw; |
78 | struct clk_init_data init; | 78 | struct clk_init_data init; |
79 | int ret; | ||
79 | 80 | ||
80 | cpu = kzalloc(sizeof(*cpu), GFP_KERNEL); | 81 | cpu = kzalloc(sizeof(*cpu), GFP_KERNEL); |
81 | if (!cpu) | 82 | if (!cpu) |
@@ -93,10 +94,13 @@ struct clk *imx_clk_cpu(const char *name, const char *parent_name, | |||
93 | init.num_parents = 1; | 94 | init.num_parents = 1; |
94 | 95 | ||
95 | cpu->hw.init = &init; | 96 | cpu->hw.init = &init; |
97 | hw = &cpu->hw; | ||
96 | 98 | ||
97 | clk = clk_register(NULL, &cpu->hw); | 99 | ret = clk_hw_register(NULL, hw); |
98 | if (IS_ERR(clk)) | 100 | if (ret) { |
99 | kfree(cpu); | 101 | kfree(cpu); |
102 | return ERR_PTR(ret); | ||
103 | } | ||
100 | 104 | ||
101 | return clk; | 105 | return hw; |
102 | } | 106 | } |
diff --git a/drivers/clk/imx/clk-fixup-div.c b/drivers/clk/imx/clk-fixup-div.c index bab46c6fd3db..4b17b91504ed 100644 --- a/drivers/clk/imx/clk-fixup-div.c +++ b/drivers/clk/imx/clk-fixup-div.c | |||
@@ -85,13 +85,14 @@ static const struct clk_ops clk_fixup_div_ops = { | |||
85 | .set_rate = clk_fixup_div_set_rate, | 85 | .set_rate = clk_fixup_div_set_rate, |
86 | }; | 86 | }; |
87 | 87 | ||
88 | struct clk *imx_clk_fixup_divider(const char *name, const char *parent, | 88 | struct clk_hw *imx_clk_hw_fixup_divider(const char *name, const char *parent, |
89 | void __iomem *reg, u8 shift, u8 width, | 89 | void __iomem *reg, u8 shift, u8 width, |
90 | void (*fixup)(u32 *val)) | 90 | void (*fixup)(u32 *val)) |
91 | { | 91 | { |
92 | struct clk_fixup_div *fixup_div; | 92 | struct clk_fixup_div *fixup_div; |
93 | struct clk *clk; | 93 | struct clk_hw *hw; |
94 | struct clk_init_data init; | 94 | struct clk_init_data init; |
95 | int ret; | ||
95 | 96 | ||
96 | if (!fixup) | 97 | if (!fixup) |
97 | return ERR_PTR(-EINVAL); | 98 | return ERR_PTR(-EINVAL); |
@@ -114,9 +115,13 @@ struct clk *imx_clk_fixup_divider(const char *name, const char *parent, | |||
114 | fixup_div->ops = &clk_divider_ops; | 115 | fixup_div->ops = &clk_divider_ops; |
115 | fixup_div->fixup = fixup; | 116 | fixup_div->fixup = fixup; |
116 | 117 | ||
117 | clk = clk_register(NULL, &fixup_div->divider.hw); | 118 | hw = &fixup_div->divider.hw; |
118 | if (IS_ERR(clk)) | 119 | |
120 | ret = clk_hw_register(NULL, hw); | ||
121 | if (ret) { | ||
119 | kfree(fixup_div); | 122 | kfree(fixup_div); |
123 | return ERR_PTR(ret); | ||
124 | } | ||
120 | 125 | ||
121 | return clk; | 126 | return hw; |
122 | } | 127 | } |
diff --git a/drivers/clk/imx/clk-fixup-mux.c b/drivers/clk/imx/clk-fixup-mux.c index 1aa3e8d9abf3..b569d919c645 100644 --- a/drivers/clk/imx/clk-fixup-mux.c +++ b/drivers/clk/imx/clk-fixup-mux.c | |||
@@ -63,13 +63,14 @@ static const struct clk_ops clk_fixup_mux_ops = { | |||
63 | .set_parent = clk_fixup_mux_set_parent, | 63 | .set_parent = clk_fixup_mux_set_parent, |
64 | }; | 64 | }; |
65 | 65 | ||
66 | struct clk *imx_clk_fixup_mux(const char *name, void __iomem *reg, | 66 | struct clk_hw *imx_clk_hw_fixup_mux(const char *name, void __iomem *reg, |
67 | u8 shift, u8 width, const char * const *parents, | 67 | u8 shift, u8 width, const char * const *parents, |
68 | int num_parents, void (*fixup)(u32 *val)) | 68 | int num_parents, void (*fixup)(u32 *val)) |
69 | { | 69 | { |
70 | struct clk_fixup_mux *fixup_mux; | 70 | struct clk_fixup_mux *fixup_mux; |
71 | struct clk *clk; | 71 | struct clk_hw *hw; |
72 | struct clk_init_data init; | 72 | struct clk_init_data init; |
73 | int ret; | ||
73 | 74 | ||
74 | if (!fixup) | 75 | if (!fixup) |
75 | return ERR_PTR(-EINVAL); | 76 | return ERR_PTR(-EINVAL); |
@@ -92,9 +93,13 @@ struct clk *imx_clk_fixup_mux(const char *name, void __iomem *reg, | |||
92 | fixup_mux->ops = &clk_mux_ops; | 93 | fixup_mux->ops = &clk_mux_ops; |
93 | fixup_mux->fixup = fixup; | 94 | fixup_mux->fixup = fixup; |
94 | 95 | ||
95 | clk = clk_register(NULL, &fixup_mux->mux.hw); | 96 | hw = &fixup_mux->mux.hw; |
96 | if (IS_ERR(clk)) | 97 | |
98 | ret = clk_hw_register(NULL, hw); | ||
99 | if (ret) { | ||
97 | kfree(fixup_mux); | 100 | kfree(fixup_mux); |
101 | return ERR_PTR(ret); | ||
102 | } | ||
98 | 103 | ||
99 | return clk; | 104 | return hw; |
100 | } | 105 | } |
diff --git a/drivers/clk/imx/clk-gate-exclusive.c b/drivers/clk/imx/clk-gate-exclusive.c index cffa4966568d..77342893bb71 100644 --- a/drivers/clk/imx/clk-gate-exclusive.c +++ b/drivers/clk/imx/clk-gate-exclusive.c | |||
@@ -55,13 +55,14 @@ static const struct clk_ops clk_gate_exclusive_ops = { | |||
55 | .is_enabled = clk_gate_exclusive_is_enabled, | 55 | .is_enabled = clk_gate_exclusive_is_enabled, |
56 | }; | 56 | }; |
57 | 57 | ||
58 | struct clk *imx_clk_gate_exclusive(const char *name, const char *parent, | 58 | struct clk_hw *imx_clk_hw_gate_exclusive(const char *name, const char *parent, |
59 | void __iomem *reg, u8 shift, u32 exclusive_mask) | 59 | void __iomem *reg, u8 shift, u32 exclusive_mask) |
60 | { | 60 | { |
61 | struct clk_gate_exclusive *exgate; | 61 | struct clk_gate_exclusive *exgate; |
62 | struct clk_gate *gate; | 62 | struct clk_gate *gate; |
63 | struct clk *clk; | 63 | struct clk_hw *hw; |
64 | struct clk_init_data init; | 64 | struct clk_init_data init; |
65 | int ret; | ||
65 | 66 | ||
66 | if (exclusive_mask == 0) | 67 | if (exclusive_mask == 0) |
67 | return ERR_PTR(-EINVAL); | 68 | return ERR_PTR(-EINVAL); |
@@ -83,9 +84,13 @@ struct clk *imx_clk_gate_exclusive(const char *name, const char *parent, | |||
83 | gate->hw.init = &init; | 84 | gate->hw.init = &init; |
84 | exgate->exclusive_mask = exclusive_mask; | 85 | exgate->exclusive_mask = exclusive_mask; |
85 | 86 | ||
86 | clk = clk_register(NULL, &gate->hw); | 87 | hw = &gate->hw; |
87 | if (IS_ERR(clk)) | ||
88 | kfree(exgate); | ||
89 | 88 | ||
90 | return clk; | 89 | ret = clk_hw_register(NULL, hw); |
90 | if (ret) { | ||
91 | kfree(gate); | ||
92 | return ERR_PTR(ret); | ||
93 | } | ||
94 | |||
95 | return hw; | ||
91 | } | 96 | } |
diff --git a/drivers/clk/imx/clk-gate2.c b/drivers/clk/imx/clk-gate2.c index ec08fda547a3..7d44ce814806 100644 --- a/drivers/clk/imx/clk-gate2.c +++ b/drivers/clk/imx/clk-gate2.c | |||
@@ -122,15 +122,16 @@ static const struct clk_ops clk_gate2_ops = { | |||
122 | .is_enabled = clk_gate2_is_enabled, | 122 | .is_enabled = clk_gate2_is_enabled, |
123 | }; | 123 | }; |
124 | 124 | ||
125 | struct clk *clk_register_gate2(struct device *dev, const char *name, | 125 | struct clk_hw *clk_hw_register_gate2(struct device *dev, const char *name, |
126 | const char *parent_name, unsigned long flags, | 126 | const char *parent_name, unsigned long flags, |
127 | void __iomem *reg, u8 bit_idx, u8 cgr_val, | 127 | void __iomem *reg, u8 bit_idx, u8 cgr_val, |
128 | u8 clk_gate2_flags, spinlock_t *lock, | 128 | u8 clk_gate2_flags, spinlock_t *lock, |
129 | unsigned int *share_count) | 129 | unsigned int *share_count) |
130 | { | 130 | { |
131 | struct clk_gate2 *gate; | 131 | struct clk_gate2 *gate; |
132 | struct clk *clk; | 132 | struct clk_hw *hw; |
133 | struct clk_init_data init; | 133 | struct clk_init_data init; |
134 | int ret; | ||
134 | 135 | ||
135 | gate = kzalloc(sizeof(struct clk_gate2), GFP_KERNEL); | 136 | gate = kzalloc(sizeof(struct clk_gate2), GFP_KERNEL); |
136 | if (!gate) | 137 | if (!gate) |
@@ -151,10 +152,13 @@ struct clk *clk_register_gate2(struct device *dev, const char *name, | |||
151 | init.num_parents = parent_name ? 1 : 0; | 152 | init.num_parents = parent_name ? 1 : 0; |
152 | 153 | ||
153 | gate->hw.init = &init; | 154 | gate->hw.init = &init; |
155 | hw = &gate->hw; | ||
154 | 156 | ||
155 | clk = clk_register(dev, &gate->hw); | 157 | ret = clk_hw_register(NULL, hw); |
156 | if (IS_ERR(clk)) | 158 | if (ret) { |
157 | kfree(gate); | 159 | kfree(gate); |
160 | return ERR_PTR(ret); | ||
161 | } | ||
158 | 162 | ||
159 | return clk; | 163 | return hw; |
160 | } | 164 | } |
diff --git a/drivers/clk/imx/clk-imx6q.c b/drivers/clk/imx/clk-imx6q.c index d5de733f336e..60f2de851f39 100644 --- a/drivers/clk/imx/clk-imx6q.c +++ b/drivers/clk/imx/clk-imx6q.c | |||
@@ -8,6 +8,7 @@ | |||
8 | #include <linux/types.h> | 8 | #include <linux/types.h> |
9 | #include <linux/clk.h> | 9 | #include <linux/clk.h> |
10 | #include <linux/clkdev.h> | 10 | #include <linux/clkdev.h> |
11 | #include <linux/clk-provider.h> | ||
11 | #include <linux/err.h> | 12 | #include <linux/err.h> |
12 | #include <linux/io.h> | 13 | #include <linux/io.h> |
13 | #include <linux/of.h> | 14 | #include <linux/of.h> |
@@ -87,8 +88,8 @@ static const char *pll5_bypass_sels[] = { "pll5", "pll5_bypass_src", }; | |||
87 | static const char *pll6_bypass_sels[] = { "pll6", "pll6_bypass_src", }; | 88 | static const char *pll6_bypass_sels[] = { "pll6", "pll6_bypass_src", }; |
88 | static const char *pll7_bypass_sels[] = { "pll7", "pll7_bypass_src", }; | 89 | static const char *pll7_bypass_sels[] = { "pll7", "pll7_bypass_src", }; |
89 | 90 | ||
90 | static struct clk *clk[IMX6QDL_CLK_END]; | 91 | static struct clk_hw **hws; |
91 | static struct clk_onecell_data clk_data; | 92 | static struct clk_hw_onecell_data *clk_hw_data; |
92 | 93 | ||
93 | static struct clk_div_table clk_enet_ref_table[] = { | 94 | static struct clk_div_table clk_enet_ref_table[] = { |
94 | { .val = 0, .div = 20, }, | 95 | { .val = 0, .div = 20, }, |
@@ -138,12 +139,13 @@ static inline int clk_on_imx6dl(void) | |||
138 | return of_machine_is_compatible("fsl,imx6dl"); | 139 | return of_machine_is_compatible("fsl,imx6dl"); |
139 | } | 140 | } |
140 | 141 | ||
141 | static struct clk ** const uart_clks[] __initconst = { | 142 | static const int uart_clk_ids[] __initconst = { |
142 | &clk[IMX6QDL_CLK_UART_IPG], | 143 | IMX6QDL_CLK_UART_IPG, |
143 | &clk[IMX6QDL_CLK_UART_SERIAL], | 144 | IMX6QDL_CLK_UART_SERIAL, |
144 | NULL | ||
145 | }; | 145 | }; |
146 | 146 | ||
147 | static struct clk **uart_clks[ARRAY_SIZE(uart_clk_ids) + 1] __initdata; | ||
148 | |||
147 | static int ldb_di_sel_by_clock_id(int clock_id) | 149 | static int ldb_di_sel_by_clock_id(int clock_id) |
148 | { | 150 | { |
149 | switch (clock_id) { | 151 | switch (clock_id) { |
@@ -254,25 +256,14 @@ static bool pll6_bypassed(struct device_node *node) | |||
254 | return false; | 256 | return false; |
255 | } | 257 | } |
256 | 258 | ||
257 | #define CCM_CCDR 0x04 | ||
258 | #define CCM_CCSR 0x0c | 259 | #define CCM_CCSR 0x0c |
259 | #define CCM_CS2CDR 0x2c | 260 | #define CCM_CS2CDR 0x2c |
260 | 261 | ||
261 | #define CCDR_MMDC_CH1_MASK BIT(16) | ||
262 | #define CCSR_PLL3_SW_CLK_SEL BIT(0) | 262 | #define CCSR_PLL3_SW_CLK_SEL BIT(0) |
263 | 263 | ||
264 | #define CS2CDR_LDB_DI0_CLK_SEL_SHIFT 9 | 264 | #define CS2CDR_LDB_DI0_CLK_SEL_SHIFT 9 |
265 | #define CS2CDR_LDB_DI1_CLK_SEL_SHIFT 12 | 265 | #define CS2CDR_LDB_DI1_CLK_SEL_SHIFT 12 |
266 | 266 | ||
267 | static void __init imx6q_mmdc_ch1_mask_handshake(void __iomem *ccm_base) | ||
268 | { | ||
269 | unsigned int reg; | ||
270 | |||
271 | reg = readl_relaxed(ccm_base + CCM_CCDR); | ||
272 | reg |= CCDR_MMDC_CH1_MASK; | ||
273 | writel_relaxed(reg, ccm_base + CCM_CCDR); | ||
274 | } | ||
275 | |||
276 | /* | 267 | /* |
277 | * The only way to disable the MMDC_CH1 clock is to move it to pll3_sw_clk | 268 | * The only way to disable the MMDC_CH1 clock is to move it to pll3_sw_clk |
278 | * via periph2_clk2_sel and then to disable pll3_sw_clk by selecting the | 269 | * via periph2_clk2_sel and then to disable pll3_sw_clk by selecting the |
@@ -282,14 +273,8 @@ static void mmdc_ch1_disable(void __iomem *ccm_base) | |||
282 | { | 273 | { |
283 | unsigned int reg; | 274 | unsigned int reg; |
284 | 275 | ||
285 | clk_set_parent(clk[IMX6QDL_CLK_PERIPH2_CLK2_SEL], | 276 | clk_set_parent(hws[IMX6QDL_CLK_PERIPH2_CLK2_SEL]->clk, |
286 | clk[IMX6QDL_CLK_PLL3_USB_OTG]); | 277 | hws[IMX6QDL_CLK_PLL3_USB_OTG]->clk); |
287 | |||
288 | /* | ||
289 | * Handshake with mmdc_ch1 module must be masked when changing | ||
290 | * periph2_clk_sel. | ||
291 | */ | ||
292 | clk_set_parent(clk[IMX6QDL_CLK_PERIPH2], clk[IMX6QDL_CLK_PERIPH2_CLK2]); | ||
293 | 278 | ||
294 | /* Disable pll3_sw_clk by selecting the bypass clock source */ | 279 | /* Disable pll3_sw_clk by selecting the bypass clock source */ |
295 | reg = readl_relaxed(ccm_base + CCM_CCSR); | 280 | reg = readl_relaxed(ccm_base + CCM_CCSR); |
@@ -305,8 +290,6 @@ static void mmdc_ch1_reenable(void __iomem *ccm_base) | |||
305 | reg = readl_relaxed(ccm_base + CCM_CCSR); | 290 | reg = readl_relaxed(ccm_base + CCM_CCSR); |
306 | reg &= ~CCSR_PLL3_SW_CLK_SEL; | 291 | reg &= ~CCSR_PLL3_SW_CLK_SEL; |
307 | writel_relaxed(reg, ccm_base + CCM_CCSR); | 292 | writel_relaxed(reg, ccm_base + CCM_CCSR); |
308 | |||
309 | clk_set_parent(clk[IMX6QDL_CLK_PERIPH2], clk[IMX6QDL_CLK_PERIPH2_PRE]); | ||
310 | } | 293 | } |
311 | 294 | ||
312 | /* | 295 | /* |
@@ -365,8 +348,8 @@ static void init_ldb_clks(struct device_node *np, void __iomem *ccm_base) | |||
365 | 348 | ||
366 | /* Only switch to or from pll2_pfd2_396m if it is disabled */ | 349 | /* Only switch to or from pll2_pfd2_396m if it is disabled */ |
367 | if ((sel[i][0] == 2 || sel[i][3] == 2) && | 350 | if ((sel[i][0] == 2 || sel[i][3] == 2) && |
368 | (clk_get_parent(clk[IMX6QDL_CLK_PERIPH_PRE]) == | 351 | (clk_get_parent(hws[IMX6QDL_CLK_PERIPH_PRE]->clk) == |
369 | clk[IMX6QDL_CLK_PLL2_PFD2_396M])) { | 352 | hws[IMX6QDL_CLK_PLL2_PFD2_396M]->clk)) { |
370 | pr_err("ccm: ldb_di%d_sel: couldn't disable pll2_pfd2_396m\n", | 353 | pr_err("ccm: ldb_di%d_sel: couldn't disable pll2_pfd2_396m\n", |
371 | i); | 354 | i); |
372 | sel[i][3] = sel[i][2] = sel[i][1] = sel[i][0]; | 355 | sel[i][3] = sel[i][2] = sel[i][1] = sel[i][0]; |
@@ -418,8 +401,8 @@ static void disable_anatop_clocks(void __iomem *anatop_base) | |||
418 | /* Make sure PLL2 PFDs 0-2 are gated */ | 401 | /* Make sure PLL2 PFDs 0-2 are gated */ |
419 | reg = readl_relaxed(anatop_base + CCM_ANALOG_PFD_528); | 402 | reg = readl_relaxed(anatop_base + CCM_ANALOG_PFD_528); |
420 | /* Cannot gate PFD2 if pll2_pfd2_396m is the parent of MMDC clock */ | 403 | /* Cannot gate PFD2 if pll2_pfd2_396m is the parent of MMDC clock */ |
421 | if (clk_get_parent(clk[IMX6QDL_CLK_PERIPH_PRE]) == | 404 | if (clk_get_parent(hws[IMX6QDL_CLK_PERIPH_PRE]->clk) == |
422 | clk[IMX6QDL_CLK_PLL2_PFD2_396M]) | 405 | hws[IMX6QDL_CLK_PLL2_PFD2_396M]->clk) |
423 | reg |= PFD0_CLKGATE | PFD1_CLKGATE; | 406 | reg |= PFD0_CLKGATE | PFD1_CLKGATE; |
424 | else | 407 | else |
425 | reg |= PFD0_CLKGATE | PFD1_CLKGATE | PFD2_CLKGATE; | 408 | reg |= PFD0_CLKGATE | PFD1_CLKGATE | PFD2_CLKGATE; |
@@ -436,31 +419,45 @@ static void disable_anatop_clocks(void __iomem *anatop_base) | |||
436 | writel_relaxed(reg, anatop_base + CCM_ANALOG_PLL_VIDEO); | 419 | writel_relaxed(reg, anatop_base + CCM_ANALOG_PLL_VIDEO); |
437 | } | 420 | } |
438 | 421 | ||
422 | static struct clk_hw * __init imx6q_obtain_fixed_clk_hw(struct device_node *np, | ||
423 | const char *name, | ||
424 | unsigned long rate) | ||
425 | { | ||
426 | struct clk *clk = of_clk_get_by_name(np, name); | ||
427 | struct clk_hw *hw; | ||
428 | |||
429 | if (IS_ERR(clk)) | ||
430 | hw = imx_obtain_fixed_clock_hw(name, rate); | ||
431 | else | ||
432 | hw = __clk_get_hw(clk); | ||
433 | |||
434 | return hw; | ||
435 | } | ||
436 | |||
439 | static void __init imx6q_clocks_init(struct device_node *ccm_node) | 437 | static void __init imx6q_clocks_init(struct device_node *ccm_node) |
440 | { | 438 | { |
441 | struct device_node *np; | 439 | struct device_node *np; |
442 | void __iomem *anatop_base, *base; | 440 | void __iomem *anatop_base, *base; |
443 | int ret; | 441 | int ret; |
442 | int i; | ||
443 | |||
444 | clk_hw_data = kzalloc(struct_size(clk_hw_data, hws, | ||
445 | IMX6QDL_CLK_END), GFP_KERNEL); | ||
446 | if (WARN_ON(!clk_hw_data)) | ||
447 | return; | ||
444 | 448 | ||
445 | clk[IMX6QDL_CLK_DUMMY] = imx_clk_fixed("dummy", 0); | 449 | clk_hw_data->num = IMX6QDL_CLK_END; |
446 | clk[IMX6QDL_CLK_CKIL] = of_clk_get_by_name(ccm_node, "ckil"); | 450 | hws = clk_hw_data->hws; |
447 | if (IS_ERR(clk[IMX6QDL_CLK_CKIL])) | ||
448 | clk[IMX6QDL_CLK_CKIL] = imx_obtain_fixed_clock("ckil", 0); | ||
449 | clk[IMX6QDL_CLK_CKIH] = of_clk_get_by_name(ccm_node, "ckih1"); | ||
450 | if (IS_ERR(clk[IMX6QDL_CLK_CKIH])) | ||
451 | clk[IMX6QDL_CLK_CKIH] = imx_obtain_fixed_clock("ckih1", 0); | ||
452 | clk[IMX6QDL_CLK_OSC] = of_clk_get_by_name(ccm_node, "osc"); | ||
453 | if (IS_ERR(clk[IMX6QDL_CLK_OSC])) | ||
454 | clk[IMX6QDL_CLK_OSC] = imx_obtain_fixed_clock("osc", 0); | ||
455 | 451 | ||
456 | /* Clock source from external clock via CLK1/2 PADs */ | 452 | hws[IMX6QDL_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0); |
457 | clk[IMX6QDL_CLK_ANACLK1] = of_clk_get_by_name(ccm_node, "anaclk1"); | ||
458 | if (IS_ERR(clk[IMX6QDL_CLK_ANACLK1])) | ||
459 | clk[IMX6QDL_CLK_ANACLK1] = imx_obtain_fixed_clock("anaclk1", 0); | ||
460 | 453 | ||
461 | clk[IMX6QDL_CLK_ANACLK2] = of_clk_get_by_name(ccm_node, "anaclk2"); | 454 | hws[IMX6QDL_CLK_CKIL] = imx6q_obtain_fixed_clk_hw(ccm_node, "ckil", 0); |
462 | if (IS_ERR(clk[IMX6QDL_CLK_ANACLK2])) | 455 | hws[IMX6QDL_CLK_CKIH] = imx6q_obtain_fixed_clk_hw(ccm_node, "ckih1", 0); |
463 | clk[IMX6QDL_CLK_ANACLK2] = imx_obtain_fixed_clock("anaclk2", 0); | 456 | hws[IMX6QDL_CLK_OSC] = imx6q_obtain_fixed_clk_hw(ccm_node, "osc", 0); |
457 | |||
458 | /* Clock source from external clock via CLK1/2 PADs */ | ||
459 | hws[IMX6QDL_CLK_ANACLK1] = imx6q_obtain_fixed_clk_hw(ccm_node, "anaclk1", 0); | ||
460 | hws[IMX6QDL_CLK_ANACLK2] = imx6q_obtain_fixed_clk_hw(ccm_node, "anaclk2", 0); | ||
464 | 461 | ||
465 | np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop"); | 462 | np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop"); |
466 | anatop_base = base = of_iomap(np, 0); | 463 | anatop_base = base = of_iomap(np, 0); |
@@ -475,47 +472,47 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) | |||
475 | video_div_table[3].div = 1; | 472 | video_div_table[3].div = 1; |
476 | } | 473 | } |
477 | 474 | ||
478 | clk[IMX6QDL_PLL1_BYPASS_SRC] = imx_clk_mux("pll1_bypass_src", base + 0x00, 14, 2, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); | 475 | hws[IMX6QDL_PLL1_BYPASS_SRC] = imx_clk_hw_mux("pll1_bypass_src", base + 0x00, 14, 2, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); |
479 | clk[IMX6QDL_PLL2_BYPASS_SRC] = imx_clk_mux("pll2_bypass_src", base + 0x30, 14, 2, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); | 476 | hws[IMX6QDL_PLL2_BYPASS_SRC] = imx_clk_hw_mux("pll2_bypass_src", base + 0x30, 14, 2, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); |
480 | clk[IMX6QDL_PLL3_BYPASS_SRC] = imx_clk_mux("pll3_bypass_src", base + 0x10, 14, 2, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); | 477 | hws[IMX6QDL_PLL3_BYPASS_SRC] = imx_clk_hw_mux("pll3_bypass_src", base + 0x10, 14, 2, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); |
481 | clk[IMX6QDL_PLL4_BYPASS_SRC] = imx_clk_mux("pll4_bypass_src", base + 0x70, 14, 2, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); | 478 | hws[IMX6QDL_PLL4_BYPASS_SRC] = imx_clk_hw_mux("pll4_bypass_src", base + 0x70, 14, 2, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); |
482 | clk[IMX6QDL_PLL5_BYPASS_SRC] = imx_clk_mux("pll5_bypass_src", base + 0xa0, 14, 2, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); | 479 | hws[IMX6QDL_PLL5_BYPASS_SRC] = imx_clk_hw_mux("pll5_bypass_src", base + 0xa0, 14, 2, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); |
483 | clk[IMX6QDL_PLL6_BYPASS_SRC] = imx_clk_mux("pll6_bypass_src", base + 0xe0, 14, 2, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); | 480 | hws[IMX6QDL_PLL6_BYPASS_SRC] = imx_clk_hw_mux("pll6_bypass_src", base + 0xe0, 14, 2, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); |
484 | clk[IMX6QDL_PLL7_BYPASS_SRC] = imx_clk_mux("pll7_bypass_src", base + 0x20, 14, 2, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); | 481 | hws[IMX6QDL_PLL7_BYPASS_SRC] = imx_clk_hw_mux("pll7_bypass_src", base + 0x20, 14, 2, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); |
485 | 482 | ||
486 | /* type name parent_name base div_mask */ | 483 | /* type name parent_name base div_mask */ |
487 | clk[IMX6QDL_CLK_PLL1] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1", "osc", base + 0x00, 0x7f); | 484 | hws[IMX6QDL_CLK_PLL1] = imx_clk_hw_pllv3(IMX_PLLV3_SYS, "pll1", "osc", base + 0x00, 0x7f); |
488 | clk[IMX6QDL_CLK_PLL2] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2", "osc", base + 0x30, 0x1); | 485 | hws[IMX6QDL_CLK_PLL2] = imx_clk_hw_pllv3(IMX_PLLV3_GENERIC, "pll2", "osc", base + 0x30, 0x1); |
489 | clk[IMX6QDL_CLK_PLL3] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3", "osc", base + 0x10, 0x3); | 486 | hws[IMX6QDL_CLK_PLL3] = imx_clk_hw_pllv3(IMX_PLLV3_USB, "pll3", "osc", base + 0x10, 0x3); |
490 | clk[IMX6QDL_CLK_PLL4] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4", "osc", base + 0x70, 0x7f); | 487 | hws[IMX6QDL_CLK_PLL4] = imx_clk_hw_pllv3(IMX_PLLV3_AV, "pll4", "osc", base + 0x70, 0x7f); |
491 | clk[IMX6QDL_CLK_PLL5] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5", "osc", base + 0xa0, 0x7f); | 488 | hws[IMX6QDL_CLK_PLL5] = imx_clk_hw_pllv3(IMX_PLLV3_AV, "pll5", "osc", base + 0xa0, 0x7f); |
492 | clk[IMX6QDL_CLK_PLL6] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6", "osc", base + 0xe0, 0x3); | 489 | hws[IMX6QDL_CLK_PLL6] = imx_clk_hw_pllv3(IMX_PLLV3_ENET, "pll6", "osc", base + 0xe0, 0x3); |
493 | clk[IMX6QDL_CLK_PLL7] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7", "osc", base + 0x20, 0x3); | 490 | hws[IMX6QDL_CLK_PLL7] = imx_clk_hw_pllv3(IMX_PLLV3_USB, "pll7", "osc", base + 0x20, 0x3); |
494 | 491 | ||
495 | clk[IMX6QDL_PLL1_BYPASS] = imx_clk_mux_flags("pll1_bypass", base + 0x00, 16, 1, pll1_bypass_sels, ARRAY_SIZE(pll1_bypass_sels), CLK_SET_RATE_PARENT); | 492 | hws[IMX6QDL_PLL1_BYPASS] = imx_clk_hw_mux_flags("pll1_bypass", base + 0x00, 16, 1, pll1_bypass_sels, ARRAY_SIZE(pll1_bypass_sels), CLK_SET_RATE_PARENT); |
496 | clk[IMX6QDL_PLL2_BYPASS] = imx_clk_mux_flags("pll2_bypass", base + 0x30, 16, 1, pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels), CLK_SET_RATE_PARENT); | 493 | hws[IMX6QDL_PLL2_BYPASS] = imx_clk_hw_mux_flags("pll2_bypass", base + 0x30, 16, 1, pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels), CLK_SET_RATE_PARENT); |
497 | clk[IMX6QDL_PLL3_BYPASS] = imx_clk_mux_flags("pll3_bypass", base + 0x10, 16, 1, pll3_bypass_sels, ARRAY_SIZE(pll3_bypass_sels), CLK_SET_RATE_PARENT); | 494 | hws[IMX6QDL_PLL3_BYPASS] = imx_clk_hw_mux_flags("pll3_bypass", base + 0x10, 16, 1, pll3_bypass_sels, ARRAY_SIZE(pll3_bypass_sels), CLK_SET_RATE_PARENT); |
498 | clk[IMX6QDL_PLL4_BYPASS] = imx_clk_mux_flags("pll4_bypass", base + 0x70, 16, 1, pll4_bypass_sels, ARRAY_SIZE(pll4_bypass_sels), CLK_SET_RATE_PARENT); | 495 | hws[IMX6QDL_PLL4_BYPASS] = imx_clk_hw_mux_flags("pll4_bypass", base + 0x70, 16, 1, pll4_bypass_sels, ARRAY_SIZE(pll4_bypass_sels), CLK_SET_RATE_PARENT); |
499 | clk[IMX6QDL_PLL5_BYPASS] = imx_clk_mux_flags("pll5_bypass", base + 0xa0, 16, 1, pll5_bypass_sels, ARRAY_SIZE(pll5_bypass_sels), CLK_SET_RATE_PARENT); | 496 | hws[IMX6QDL_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); |
500 | clk[IMX6QDL_PLL6_BYPASS] = imx_clk_mux_flags("pll6_bypass", base + 0xe0, 16, 1, pll6_bypass_sels, ARRAY_SIZE(pll6_bypass_sels), CLK_SET_RATE_PARENT); | 497 | hws[IMX6QDL_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); |
501 | clk[IMX6QDL_PLL7_BYPASS] = imx_clk_mux_flags("pll7_bypass", base + 0x20, 16, 1, pll7_bypass_sels, ARRAY_SIZE(pll7_bypass_sels), CLK_SET_RATE_PARENT); | 498 | hws[IMX6QDL_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); |
502 | 499 | ||
503 | /* Do not bypass PLLs initially */ | 500 | /* Do not bypass PLLs initially */ |
504 | clk_set_parent(clk[IMX6QDL_PLL1_BYPASS], clk[IMX6QDL_CLK_PLL1]); | 501 | clk_set_parent(hws[IMX6QDL_PLL1_BYPASS]->clk, hws[IMX6QDL_CLK_PLL1]->clk); |
505 | clk_set_parent(clk[IMX6QDL_PLL2_BYPASS], clk[IMX6QDL_CLK_PLL2]); | 502 | clk_set_parent(hws[IMX6QDL_PLL2_BYPASS]->clk, hws[IMX6QDL_CLK_PLL2]->clk); |
506 | clk_set_parent(clk[IMX6QDL_PLL3_BYPASS], clk[IMX6QDL_CLK_PLL3]); | 503 | clk_set_parent(hws[IMX6QDL_PLL3_BYPASS]->clk, hws[IMX6QDL_CLK_PLL3]->clk); |
507 | clk_set_parent(clk[IMX6QDL_PLL4_BYPASS], clk[IMX6QDL_CLK_PLL4]); | 504 | clk_set_parent(hws[IMX6QDL_PLL4_BYPASS]->clk, hws[IMX6QDL_CLK_PLL4]->clk); |
508 | clk_set_parent(clk[IMX6QDL_PLL5_BYPASS], clk[IMX6QDL_CLK_PLL5]); | 505 | clk_set_parent(hws[IMX6QDL_PLL5_BYPASS]->clk, hws[IMX6QDL_CLK_PLL5]->clk); |
509 | clk_set_parent(clk[IMX6QDL_PLL6_BYPASS], clk[IMX6QDL_CLK_PLL6]); | 506 | clk_set_parent(hws[IMX6QDL_PLL6_BYPASS]->clk, hws[IMX6QDL_CLK_PLL6]->clk); |
510 | clk_set_parent(clk[IMX6QDL_PLL7_BYPASS], clk[IMX6QDL_CLK_PLL7]); | 507 | clk_set_parent(hws[IMX6QDL_PLL7_BYPASS]->clk, hws[IMX6QDL_CLK_PLL7]->clk); |
511 | 508 | ||
512 | clk[IMX6QDL_CLK_PLL1_SYS] = imx_clk_gate("pll1_sys", "pll1_bypass", base + 0x00, 13); | 509 | hws[IMX6QDL_CLK_PLL1_SYS] = imx_clk_hw_gate("pll1_sys", "pll1_bypass", base + 0x00, 13); |
513 | clk[IMX6QDL_CLK_PLL2_BUS] = imx_clk_gate("pll2_bus", "pll2_bypass", base + 0x30, 13); | 510 | hws[IMX6QDL_CLK_PLL2_BUS] = imx_clk_hw_gate("pll2_bus", "pll2_bypass", base + 0x30, 13); |
514 | clk[IMX6QDL_CLK_PLL3_USB_OTG] = imx_clk_gate("pll3_usb_otg", "pll3_bypass", base + 0x10, 13); | 511 | hws[IMX6QDL_CLK_PLL3_USB_OTG] = imx_clk_hw_gate("pll3_usb_otg", "pll3_bypass", base + 0x10, 13); |
515 | clk[IMX6QDL_CLK_PLL4_AUDIO] = imx_clk_gate("pll4_audio", "pll4_bypass", base + 0x70, 13); | 512 | hws[IMX6QDL_CLK_PLL4_AUDIO] = imx_clk_hw_gate("pll4_audio", "pll4_bypass", base + 0x70, 13); |
516 | clk[IMX6QDL_CLK_PLL5_VIDEO] = imx_clk_gate("pll5_video", "pll5_bypass", base + 0xa0, 13); | 513 | hws[IMX6QDL_CLK_PLL5_VIDEO] = imx_clk_hw_gate("pll5_video", "pll5_bypass", base + 0xa0, 13); |
517 | clk[IMX6QDL_CLK_PLL6_ENET] = imx_clk_gate("pll6_enet", "pll6_bypass", base + 0xe0, 13); | 514 | hws[IMX6QDL_CLK_PLL6_ENET] = imx_clk_hw_gate("pll6_enet", "pll6_bypass", base + 0xe0, 13); |
518 | clk[IMX6QDL_CLK_PLL7_USB_HOST] = imx_clk_gate("pll7_usb_host", "pll7_bypass", base + 0x20, 13); | 515 | hws[IMX6QDL_CLK_PLL7_USB_HOST] = imx_clk_hw_gate("pll7_usb_host", "pll7_bypass", base + 0x20, 13); |
519 | 516 | ||
520 | /* | 517 | /* |
521 | * Bit 20 is the reserved and read-only bit, we do this only for: | 518 | * Bit 20 is the reserved and read-only bit, we do this only for: |
@@ -523,15 +520,15 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) | |||
523 | * - Keep refcount when do usbphy clk_enable/disable, in that case, | 520 | * - Keep refcount when do usbphy clk_enable/disable, in that case, |
524 | * the clk framework may need to enable/disable usbphy's parent | 521 | * the clk framework may need to enable/disable usbphy's parent |
525 | */ | 522 | */ |
526 | clk[IMX6QDL_CLK_USBPHY1] = imx_clk_gate("usbphy1", "pll3_usb_otg", base + 0x10, 20); | 523 | hws[IMX6QDL_CLK_USBPHY1] = imx_clk_hw_gate("usbphy1", "pll3_usb_otg", base + 0x10, 20); |
527 | clk[IMX6QDL_CLK_USBPHY2] = imx_clk_gate("usbphy2", "pll7_usb_host", base + 0x20, 20); | 524 | hws[IMX6QDL_CLK_USBPHY2] = imx_clk_hw_gate("usbphy2", "pll7_usb_host", base + 0x20, 20); |
528 | 525 | ||
529 | /* | 526 | /* |
530 | * usbphy*_gate needs to be on after system boots up, and software | 527 | * usbphy*_gate needs to be on after system boots up, and software |
531 | * never needs to control it anymore. | 528 | * never needs to control it anymore. |
532 | */ | 529 | */ |
533 | clk[IMX6QDL_CLK_USBPHY1_GATE] = imx_clk_gate("usbphy1_gate", "dummy", base + 0x10, 6); | 530 | hws[IMX6QDL_CLK_USBPHY1_GATE] = imx_clk_hw_gate("usbphy1_gate", "dummy", base + 0x10, 6); |
534 | clk[IMX6QDL_CLK_USBPHY2_GATE] = imx_clk_gate("usbphy2_gate", "dummy", base + 0x20, 6); | 531 | hws[IMX6QDL_CLK_USBPHY2_GATE] = imx_clk_hw_gate("usbphy2_gate", "dummy", base + 0x20, 6); |
535 | 532 | ||
536 | /* | 533 | /* |
537 | * The ENET PLL is special in that is has multiple outputs with | 534 | * The ENET PLL is special in that is has multiple outputs with |
@@ -545,22 +542,22 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) | |||
545 | * | 542 | * |
546 | */ | 543 | */ |
547 | if (!pll6_bypassed(ccm_node)) { | 544 | if (!pll6_bypassed(ccm_node)) { |
548 | clk[IMX6QDL_CLK_SATA_REF] = imx_clk_fixed_factor("sata_ref", "pll6_enet", 1, 5); | 545 | hws[IMX6QDL_CLK_SATA_REF] = imx_clk_hw_fixed_factor("sata_ref", "pll6_enet", 1, 5); |
549 | clk[IMX6QDL_CLK_PCIE_REF] = imx_clk_fixed_factor("pcie_ref", "pll6_enet", 1, 4); | 546 | hws[IMX6QDL_CLK_PCIE_REF] = imx_clk_hw_fixed_factor("pcie_ref", "pll6_enet", 1, 4); |
550 | clk[IMX6QDL_CLK_ENET_REF] = clk_register_divider_table(NULL, "enet_ref", "pll6_enet", 0, | 547 | hws[IMX6QDL_CLK_ENET_REF] = clk_hw_register_divider_table(NULL, "enet_ref", "pll6_enet", 0, |
551 | base + 0xe0, 0, 2, 0, clk_enet_ref_table, | 548 | base + 0xe0, 0, 2, 0, clk_enet_ref_table, |
552 | &imx_ccm_lock); | 549 | &imx_ccm_lock); |
553 | } else { | 550 | } else { |
554 | clk[IMX6QDL_CLK_SATA_REF] = imx_clk_fixed_factor("sata_ref", "pll6_enet", 1, 1); | 551 | hws[IMX6QDL_CLK_SATA_REF] = imx_clk_hw_fixed_factor("sata_ref", "pll6_enet", 1, 1); |
555 | clk[IMX6QDL_CLK_PCIE_REF] = imx_clk_fixed_factor("pcie_ref", "pll6_enet", 1, 1); | 552 | hws[IMX6QDL_CLK_PCIE_REF] = imx_clk_hw_fixed_factor("pcie_ref", "pll6_enet", 1, 1); |
556 | clk[IMX6QDL_CLK_ENET_REF] = imx_clk_fixed_factor("enet_ref", "pll6_enet", 1, 1); | 553 | hws[IMX6QDL_CLK_ENET_REF] = imx_clk_hw_fixed_factor("enet_ref", "pll6_enet", 1, 1); |
557 | } | 554 | } |
558 | 555 | ||
559 | clk[IMX6QDL_CLK_SATA_REF_100M] = imx_clk_gate("sata_ref_100m", "sata_ref", base + 0xe0, 20); | 556 | hws[IMX6QDL_CLK_SATA_REF_100M] = imx_clk_hw_gate("sata_ref_100m", "sata_ref", base + 0xe0, 20); |
560 | clk[IMX6QDL_CLK_PCIE_REF_125M] = imx_clk_gate("pcie_ref_125m", "pcie_ref", base + 0xe0, 19); | 557 | hws[IMX6QDL_CLK_PCIE_REF_125M] = imx_clk_hw_gate("pcie_ref_125m", "pcie_ref", base + 0xe0, 19); |
561 | 558 | ||
562 | clk[IMX6QDL_CLK_LVDS1_SEL] = imx_clk_mux("lvds1_sel", base + 0x160, 0, 5, lvds_sels, ARRAY_SIZE(lvds_sels)); | 559 | hws[IMX6QDL_CLK_LVDS1_SEL] = imx_clk_hw_mux("lvds1_sel", base + 0x160, 0, 5, lvds_sels, ARRAY_SIZE(lvds_sels)); |
563 | clk[IMX6QDL_CLK_LVDS2_SEL] = imx_clk_mux("lvds2_sel", base + 0x160, 5, 5, lvds_sels, ARRAY_SIZE(lvds_sels)); | 560 | hws[IMX6QDL_CLK_LVDS2_SEL] = imx_clk_hw_mux("lvds2_sel", base + 0x160, 5, 5, lvds_sels, ARRAY_SIZE(lvds_sels)); |
564 | 561 | ||
565 | /* | 562 | /* |
566 | * lvds1_gate and lvds2_gate are pseudo-gates. Both can be | 563 | * lvds1_gate and lvds2_gate are pseudo-gates. Both can be |
@@ -572,84 +569,84 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) | |||
572 | * it. | 569 | * it. |
573 | */ | 570 | */ |
574 | writel(readl(base + 0x160) & ~0x3c00, base + 0x160); | 571 | writel(readl(base + 0x160) & ~0x3c00, base + 0x160); |
575 | clk[IMX6QDL_CLK_LVDS1_GATE] = imx_clk_gate_exclusive("lvds1_gate", "lvds1_sel", base + 0x160, 10, BIT(12)); | 572 | hws[IMX6QDL_CLK_LVDS1_GATE] = imx_clk_hw_gate_exclusive("lvds1_gate", "lvds1_sel", base + 0x160, 10, BIT(12)); |
576 | clk[IMX6QDL_CLK_LVDS2_GATE] = imx_clk_gate_exclusive("lvds2_gate", "lvds2_sel", base + 0x160, 11, BIT(13)); | 573 | hws[IMX6QDL_CLK_LVDS2_GATE] = imx_clk_hw_gate_exclusive("lvds2_gate", "lvds2_sel", base + 0x160, 11, BIT(13)); |
577 | 574 | ||
578 | clk[IMX6QDL_CLK_LVDS1_IN] = imx_clk_gate_exclusive("lvds1_in", "anaclk1", base + 0x160, 12, BIT(10)); | 575 | hws[IMX6QDL_CLK_LVDS1_IN] = imx_clk_hw_gate_exclusive("lvds1_in", "anaclk1", base + 0x160, 12, BIT(10)); |
579 | clk[IMX6QDL_CLK_LVDS2_IN] = imx_clk_gate_exclusive("lvds2_in", "anaclk2", base + 0x160, 13, BIT(11)); | 576 | hws[IMX6QDL_CLK_LVDS2_IN] = imx_clk_hw_gate_exclusive("lvds2_in", "anaclk2", base + 0x160, 13, BIT(11)); |
580 | 577 | ||
581 | /* name parent_name reg idx */ | 578 | /* name parent_name reg idx */ |
582 | clk[IMX6QDL_CLK_PLL2_PFD0_352M] = imx_clk_pfd("pll2_pfd0_352m", "pll2_bus", base + 0x100, 0); | 579 | hws[IMX6QDL_CLK_PLL2_PFD0_352M] = imx_clk_hw_pfd("pll2_pfd0_352m", "pll2_bus", base + 0x100, 0); |
583 | clk[IMX6QDL_CLK_PLL2_PFD1_594M] = imx_clk_pfd("pll2_pfd1_594m", "pll2_bus", base + 0x100, 1); | 580 | hws[IMX6QDL_CLK_PLL2_PFD1_594M] = imx_clk_hw_pfd("pll2_pfd1_594m", "pll2_bus", base + 0x100, 1); |
584 | clk[IMX6QDL_CLK_PLL2_PFD2_396M] = imx_clk_pfd("pll2_pfd2_396m", "pll2_bus", base + 0x100, 2); | 581 | hws[IMX6QDL_CLK_PLL2_PFD2_396M] = imx_clk_hw_pfd("pll2_pfd2_396m", "pll2_bus", base + 0x100, 2); |
585 | clk[IMX6QDL_CLK_PLL3_PFD0_720M] = imx_clk_pfd("pll3_pfd0_720m", "pll3_usb_otg", base + 0xf0, 0); | 582 | hws[IMX6QDL_CLK_PLL3_PFD0_720M] = imx_clk_hw_pfd("pll3_pfd0_720m", "pll3_usb_otg", base + 0xf0, 0); |
586 | clk[IMX6QDL_CLK_PLL3_PFD1_540M] = imx_clk_pfd("pll3_pfd1_540m", "pll3_usb_otg", base + 0xf0, 1); | 583 | hws[IMX6QDL_CLK_PLL3_PFD1_540M] = imx_clk_hw_pfd("pll3_pfd1_540m", "pll3_usb_otg", base + 0xf0, 1); |
587 | clk[IMX6QDL_CLK_PLL3_PFD2_508M] = imx_clk_pfd("pll3_pfd2_508m", "pll3_usb_otg", base + 0xf0, 2); | 584 | hws[IMX6QDL_CLK_PLL3_PFD2_508M] = imx_clk_hw_pfd("pll3_pfd2_508m", "pll3_usb_otg", base + 0xf0, 2); |
588 | clk[IMX6QDL_CLK_PLL3_PFD3_454M] = imx_clk_pfd("pll3_pfd3_454m", "pll3_usb_otg", base + 0xf0, 3); | 585 | hws[IMX6QDL_CLK_PLL3_PFD3_454M] = imx_clk_hw_pfd("pll3_pfd3_454m", "pll3_usb_otg", base + 0xf0, 3); |
589 | 586 | ||
590 | /* name parent_name mult div */ | 587 | /* name parent_name mult div */ |
591 | clk[IMX6QDL_CLK_PLL2_198M] = imx_clk_fixed_factor("pll2_198m", "pll2_pfd2_396m", 1, 2); | 588 | hws[IMX6QDL_CLK_PLL2_198M] = imx_clk_hw_fixed_factor("pll2_198m", "pll2_pfd2_396m", 1, 2); |
592 | clk[IMX6QDL_CLK_PLL3_120M] = imx_clk_fixed_factor("pll3_120m", "pll3_usb_otg", 1, 4); | 589 | hws[IMX6QDL_CLK_PLL3_120M] = imx_clk_hw_fixed_factor("pll3_120m", "pll3_usb_otg", 1, 4); |
593 | clk[IMX6QDL_CLK_PLL3_80M] = imx_clk_fixed_factor("pll3_80m", "pll3_usb_otg", 1, 6); | 590 | hws[IMX6QDL_CLK_PLL3_80M] = imx_clk_hw_fixed_factor("pll3_80m", "pll3_usb_otg", 1, 6); |
594 | clk[IMX6QDL_CLK_PLL3_60M] = imx_clk_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8); | 591 | hws[IMX6QDL_CLK_PLL3_60M] = imx_clk_hw_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8); |
595 | clk[IMX6QDL_CLK_TWD] = imx_clk_fixed_factor("twd", "arm", 1, 2); | 592 | hws[IMX6QDL_CLK_TWD] = imx_clk_hw_fixed_factor("twd", "arm", 1, 2); |
596 | clk[IMX6QDL_CLK_GPT_3M] = imx_clk_fixed_factor("gpt_3m", "osc", 1, 8); | 593 | hws[IMX6QDL_CLK_GPT_3M] = imx_clk_hw_fixed_factor("gpt_3m", "osc", 1, 8); |
597 | clk[IMX6QDL_CLK_VIDEO_27M] = imx_clk_fixed_factor("video_27m", "pll3_pfd1_540m", 1, 20); | 594 | hws[IMX6QDL_CLK_VIDEO_27M] = imx_clk_hw_fixed_factor("video_27m", "pll3_pfd1_540m", 1, 20); |
598 | if (clk_on_imx6dl() || clk_on_imx6qp()) { | 595 | if (clk_on_imx6dl() || clk_on_imx6qp()) { |
599 | clk[IMX6QDL_CLK_GPU2D_AXI] = imx_clk_fixed_factor("gpu2d_axi", "mmdc_ch0_axi_podf", 1, 1); | 596 | hws[IMX6QDL_CLK_GPU2D_AXI] = imx_clk_hw_fixed_factor("gpu2d_axi", "mmdc_ch0_axi_podf", 1, 1); |
600 | clk[IMX6QDL_CLK_GPU3D_AXI] = imx_clk_fixed_factor("gpu3d_axi", "mmdc_ch0_axi_podf", 1, 1); | 597 | hws[IMX6QDL_CLK_GPU3D_AXI] = imx_clk_hw_fixed_factor("gpu3d_axi", "mmdc_ch0_axi_podf", 1, 1); |
601 | } | 598 | } |
602 | 599 | ||
603 | clk[IMX6QDL_CLK_PLL4_POST_DIV] = clk_register_divider_table(NULL, "pll4_post_div", "pll4_audio", CLK_SET_RATE_PARENT, base + 0x70, 19, 2, 0, post_div_table, &imx_ccm_lock); | 600 | hws[IMX6QDL_CLK_PLL4_POST_DIV] = clk_hw_register_divider_table(NULL, "pll4_post_div", "pll4_audio", CLK_SET_RATE_PARENT, base + 0x70, 19, 2, 0, post_div_table, &imx_ccm_lock); |
604 | clk[IMX6QDL_CLK_PLL4_AUDIO_DIV] = clk_register_divider(NULL, "pll4_audio_div", "pll4_post_div", CLK_SET_RATE_PARENT, base + 0x170, 15, 1, 0, &imx_ccm_lock); | 601 | hws[IMX6QDL_CLK_PLL4_AUDIO_DIV] = clk_hw_register_divider(NULL, "pll4_audio_div", "pll4_post_div", CLK_SET_RATE_PARENT, base + 0x170, 15, 1, 0, &imx_ccm_lock); |
605 | clk[IMX6QDL_CLK_PLL5_POST_DIV] = clk_register_divider_table(NULL, "pll5_post_div", "pll5_video", CLK_SET_RATE_PARENT, base + 0xa0, 19, 2, 0, post_div_table, &imx_ccm_lock); | 602 | hws[IMX6QDL_CLK_PLL5_POST_DIV] = clk_hw_register_divider_table(NULL, "pll5_post_div", "pll5_video", CLK_SET_RATE_PARENT, base + 0xa0, 19, 2, 0, post_div_table, &imx_ccm_lock); |
606 | clk[IMX6QDL_CLK_PLL5_VIDEO_DIV] = clk_register_divider_table(NULL, "pll5_video_div", "pll5_post_div", CLK_SET_RATE_PARENT, base + 0x170, 30, 2, 0, video_div_table, &imx_ccm_lock); | 603 | hws[IMX6QDL_CLK_PLL5_VIDEO_DIV] = clk_hw_register_divider_table(NULL, "pll5_video_div", "pll5_post_div", CLK_SET_RATE_PARENT, base + 0x170, 30, 2, 0, video_div_table, &imx_ccm_lock); |
607 | 604 | ||
608 | np = ccm_node; | 605 | np = ccm_node; |
609 | base = of_iomap(np, 0); | 606 | base = of_iomap(np, 0); |
610 | WARN_ON(!base); | 607 | WARN_ON(!base); |
611 | 608 | ||
612 | /* name reg shift width parent_names num_parents */ | 609 | /* name reg shift width parent_names num_parents */ |
613 | clk[IMX6QDL_CLK_STEP] = imx_clk_mux("step", base + 0xc, 8, 1, step_sels, ARRAY_SIZE(step_sels)); | 610 | hws[IMX6QDL_CLK_STEP] = imx_clk_hw_mux("step", base + 0xc, 8, 1, step_sels, ARRAY_SIZE(step_sels)); |
614 | clk[IMX6QDL_CLK_PLL1_SW] = imx_clk_mux("pll1_sw", base + 0xc, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels)); | 611 | hws[IMX6QDL_CLK_PLL1_SW] = imx_clk_hw_mux("pll1_sw", base + 0xc, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels)); |
615 | clk[IMX6QDL_CLK_PERIPH_PRE] = imx_clk_mux("periph_pre", base + 0x18, 18, 2, periph_pre_sels, ARRAY_SIZE(periph_pre_sels)); | 612 | hws[IMX6QDL_CLK_PERIPH_PRE] = imx_clk_hw_mux("periph_pre", base + 0x18, 18, 2, periph_pre_sels, ARRAY_SIZE(periph_pre_sels)); |
616 | clk[IMX6QDL_CLK_PERIPH2_PRE] = imx_clk_mux("periph2_pre", base + 0x18, 21, 2, periph_pre_sels, ARRAY_SIZE(periph_pre_sels)); | 613 | hws[IMX6QDL_CLK_PERIPH2_PRE] = imx_clk_hw_mux("periph2_pre", base + 0x18, 21, 2, periph_pre_sels, ARRAY_SIZE(periph_pre_sels)); |
617 | clk[IMX6QDL_CLK_PERIPH_CLK2_SEL] = imx_clk_mux("periph_clk2_sel", base + 0x18, 12, 2, periph_clk2_sels, ARRAY_SIZE(periph_clk2_sels)); | 614 | hws[IMX6QDL_CLK_PERIPH_CLK2_SEL] = imx_clk_hw_mux("periph_clk2_sel", base + 0x18, 12, 2, periph_clk2_sels, ARRAY_SIZE(periph_clk2_sels)); |
618 | clk[IMX6QDL_CLK_PERIPH2_CLK2_SEL] = imx_clk_mux("periph2_clk2_sel", base + 0x18, 20, 1, periph2_clk2_sels, ARRAY_SIZE(periph2_clk2_sels)); | 615 | hws[IMX6QDL_CLK_PERIPH2_CLK2_SEL] = imx_clk_hw_mux("periph2_clk2_sel", base + 0x18, 20, 1, periph2_clk2_sels, ARRAY_SIZE(periph2_clk2_sels)); |
619 | clk[IMX6QDL_CLK_AXI_SEL] = imx_clk_mux("axi_sel", base + 0x14, 6, 2, axi_sels, ARRAY_SIZE(axi_sels)); | 616 | hws[IMX6QDL_CLK_AXI_SEL] = imx_clk_hw_mux("axi_sel", base + 0x14, 6, 2, axi_sels, ARRAY_SIZE(axi_sels)); |
620 | clk[IMX6QDL_CLK_ESAI_SEL] = imx_clk_mux("esai_sel", base + 0x20, 19, 2, audio_sels, ARRAY_SIZE(audio_sels)); | 617 | hws[IMX6QDL_CLK_ESAI_SEL] = imx_clk_hw_mux("esai_sel", base + 0x20, 19, 2, audio_sels, ARRAY_SIZE(audio_sels)); |
621 | clk[IMX6QDL_CLK_ASRC_SEL] = imx_clk_mux("asrc_sel", base + 0x30, 7, 2, audio_sels, ARRAY_SIZE(audio_sels)); | 618 | hws[IMX6QDL_CLK_ASRC_SEL] = imx_clk_hw_mux("asrc_sel", base + 0x30, 7, 2, audio_sels, ARRAY_SIZE(audio_sels)); |
622 | clk[IMX6QDL_CLK_SPDIF_SEL] = imx_clk_mux("spdif_sel", base + 0x30, 20, 2, audio_sels, ARRAY_SIZE(audio_sels)); | 619 | hws[IMX6QDL_CLK_SPDIF_SEL] = imx_clk_hw_mux("spdif_sel", base + 0x30, 20, 2, audio_sels, ARRAY_SIZE(audio_sels)); |
623 | if (clk_on_imx6q()) { | 620 | if (clk_on_imx6q()) { |
624 | clk[IMX6QDL_CLK_GPU2D_AXI] = imx_clk_mux("gpu2d_axi", base + 0x18, 0, 1, gpu_axi_sels, ARRAY_SIZE(gpu_axi_sels)); | 621 | hws[IMX6QDL_CLK_GPU2D_AXI] = imx_clk_hw_mux("gpu2d_axi", base + 0x18, 0, 1, gpu_axi_sels, ARRAY_SIZE(gpu_axi_sels)); |
625 | clk[IMX6QDL_CLK_GPU3D_AXI] = imx_clk_mux("gpu3d_axi", base + 0x18, 1, 1, gpu_axi_sels, ARRAY_SIZE(gpu_axi_sels)); | 622 | hws[IMX6QDL_CLK_GPU3D_AXI] = imx_clk_hw_mux("gpu3d_axi", base + 0x18, 1, 1, gpu_axi_sels, ARRAY_SIZE(gpu_axi_sels)); |
626 | } | 623 | } |
627 | if (clk_on_imx6qp()) { | 624 | if (clk_on_imx6qp()) { |
628 | clk[IMX6QDL_CLK_CAN_SEL] = imx_clk_mux("can_sel", base + 0x20, 8, 2, can_sels, ARRAY_SIZE(can_sels)); | 625 | hws[IMX6QDL_CLK_CAN_SEL] = imx_clk_hw_mux("can_sel", base + 0x20, 8, 2, can_sels, ARRAY_SIZE(can_sels)); |
629 | clk[IMX6QDL_CLK_ECSPI_SEL] = imx_clk_mux("ecspi_sel", base + 0x38, 18, 1, ecspi_sels, ARRAY_SIZE(ecspi_sels)); | 626 | hws[IMX6QDL_CLK_ECSPI_SEL] = imx_clk_hw_mux("ecspi_sel", base + 0x38, 18, 1, ecspi_sels, ARRAY_SIZE(ecspi_sels)); |
630 | clk[IMX6QDL_CLK_IPG_PER_SEL] = imx_clk_mux("ipg_per_sel", base + 0x1c, 6, 1, ipg_per_sels, ARRAY_SIZE(ipg_per_sels)); | 627 | hws[IMX6QDL_CLK_IPG_PER_SEL] = imx_clk_hw_mux("ipg_per_sel", base + 0x1c, 6, 1, ipg_per_sels, ARRAY_SIZE(ipg_per_sels)); |
631 | clk[IMX6QDL_CLK_UART_SEL] = imx_clk_mux("uart_sel", base + 0x24, 6, 1, uart_sels, ARRAY_SIZE(uart_sels)); | 628 | hws[IMX6QDL_CLK_UART_SEL] = imx_clk_hw_mux("uart_sel", base + 0x24, 6, 1, uart_sels, ARRAY_SIZE(uart_sels)); |
632 | clk[IMX6QDL_CLK_GPU2D_CORE_SEL] = imx_clk_mux("gpu2d_core_sel", base + 0x18, 16, 2, gpu2d_core_sels_2, ARRAY_SIZE(gpu2d_core_sels_2)); | 629 | hws[IMX6QDL_CLK_GPU2D_CORE_SEL] = imx_clk_hw_mux("gpu2d_core_sel", base + 0x18, 16, 2, gpu2d_core_sels_2, ARRAY_SIZE(gpu2d_core_sels_2)); |
633 | } else if (clk_on_imx6dl()) { | 630 | } else if (clk_on_imx6dl()) { |
634 | clk[IMX6QDL_CLK_MLB_SEL] = imx_clk_mux("mlb_sel", base + 0x18, 16, 2, gpu2d_core_sels, ARRAY_SIZE(gpu2d_core_sels)); | 631 | hws[IMX6QDL_CLK_MLB_SEL] = imx_clk_hw_mux("mlb_sel", base + 0x18, 16, 2, gpu2d_core_sels, ARRAY_SIZE(gpu2d_core_sels)); |
635 | } else { | 632 | } else { |
636 | clk[IMX6QDL_CLK_GPU2D_CORE_SEL] = imx_clk_mux("gpu2d_core_sel", base + 0x18, 16, 2, gpu2d_core_sels, ARRAY_SIZE(gpu2d_core_sels)); | 633 | hws[IMX6QDL_CLK_GPU2D_CORE_SEL] = imx_clk_hw_mux("gpu2d_core_sel", base + 0x18, 16, 2, gpu2d_core_sels, ARRAY_SIZE(gpu2d_core_sels)); |
637 | } | 634 | } |
638 | clk[IMX6QDL_CLK_GPU3D_CORE_SEL] = imx_clk_mux("gpu3d_core_sel", base + 0x18, 4, 2, gpu3d_core_sels, ARRAY_SIZE(gpu3d_core_sels)); | 635 | hws[IMX6QDL_CLK_GPU3D_CORE_SEL] = imx_clk_hw_mux("gpu3d_core_sel", base + 0x18, 4, 2, gpu3d_core_sels, ARRAY_SIZE(gpu3d_core_sels)); |
639 | if (clk_on_imx6dl()) | 636 | if (clk_on_imx6dl()) |
640 | clk[IMX6QDL_CLK_GPU2D_CORE_SEL] = imx_clk_mux("gpu2d_core_sel", base + 0x18, 8, 2, gpu3d_shader_sels, ARRAY_SIZE(gpu3d_shader_sels)); | 637 | hws[IMX6QDL_CLK_GPU2D_CORE_SEL] = imx_clk_hw_mux("gpu2d_core_sel", base + 0x18, 8, 2, gpu3d_shader_sels, ARRAY_SIZE(gpu3d_shader_sels)); |
641 | else | 638 | else |
642 | clk[IMX6QDL_CLK_GPU3D_SHADER_SEL] = imx_clk_mux("gpu3d_shader_sel", base + 0x18, 8, 2, gpu3d_shader_sels, ARRAY_SIZE(gpu3d_shader_sels)); | 639 | hws[IMX6QDL_CLK_GPU3D_SHADER_SEL] = imx_clk_hw_mux("gpu3d_shader_sel", base + 0x18, 8, 2, gpu3d_shader_sels, ARRAY_SIZE(gpu3d_shader_sels)); |
643 | clk[IMX6QDL_CLK_IPU1_SEL] = imx_clk_mux("ipu1_sel", base + 0x3c, 9, 2, ipu_sels, ARRAY_SIZE(ipu_sels)); | 640 | hws[IMX6QDL_CLK_IPU1_SEL] = imx_clk_hw_mux("ipu1_sel", base + 0x3c, 9, 2, ipu_sels, ARRAY_SIZE(ipu_sels)); |
644 | clk[IMX6QDL_CLK_IPU2_SEL] = imx_clk_mux("ipu2_sel", base + 0x3c, 14, 2, ipu_sels, ARRAY_SIZE(ipu_sels)); | 641 | hws[IMX6QDL_CLK_IPU2_SEL] = imx_clk_hw_mux("ipu2_sel", base + 0x3c, 14, 2, ipu_sels, ARRAY_SIZE(ipu_sels)); |
645 | 642 | ||
646 | disable_anatop_clocks(anatop_base); | 643 | disable_anatop_clocks(anatop_base); |
647 | 644 | ||
648 | imx6q_mmdc_ch1_mask_handshake(base); | 645 | imx_mmdc_mask_handshake(base, 1); |
649 | 646 | ||
650 | if (clk_on_imx6qp()) { | 647 | if (clk_on_imx6qp()) { |
651 | clk[IMX6QDL_CLK_LDB_DI0_SEL] = imx_clk_mux_flags("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels), CLK_SET_RATE_PARENT); | 648 | hws[IMX6QDL_CLK_LDB_DI0_SEL] = imx_clk_hw_mux_flags("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels), CLK_SET_RATE_PARENT); |
652 | clk[IMX6QDL_CLK_LDB_DI1_SEL] = imx_clk_mux_flags("ldb_di1_sel", base + 0x2c, 12, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels), CLK_SET_RATE_PARENT); | 649 | hws[IMX6QDL_CLK_LDB_DI1_SEL] = imx_clk_hw_mux_flags("ldb_di1_sel", base + 0x2c, 12, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels), CLK_SET_RATE_PARENT); |
653 | } else { | 650 | } else { |
654 | /* | 651 | /* |
655 | * The LDB_DI0/1_SEL muxes are registered read-only due to a hardware | 652 | * The LDB_DI0/1_SEL muxes are registered read-only due to a hardware |
@@ -658,322 +655,333 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) | |||
658 | */ | 655 | */ |
659 | init_ldb_clks(np, base); | 656 | init_ldb_clks(np, base); |
660 | 657 | ||
661 | clk[IMX6QDL_CLK_LDB_DI0_SEL] = imx_clk_mux_ldb("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels)); | 658 | hws[IMX6QDL_CLK_LDB_DI0_SEL] = imx_clk_hw_mux_ldb("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels)); |
662 | clk[IMX6QDL_CLK_LDB_DI1_SEL] = imx_clk_mux_ldb("ldb_di1_sel", base + 0x2c, 12, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels)); | 659 | hws[IMX6QDL_CLK_LDB_DI1_SEL] = imx_clk_hw_mux_ldb("ldb_di1_sel", base + 0x2c, 12, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels)); |
663 | } | 660 | } |
664 | clk[IMX6QDL_CLK_IPU1_DI0_PRE_SEL] = imx_clk_mux_flags("ipu1_di0_pre_sel", base + 0x34, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT); | 661 | |
665 | clk[IMX6QDL_CLK_IPU1_DI1_PRE_SEL] = imx_clk_mux_flags("ipu1_di1_pre_sel", base + 0x34, 15, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT); | 662 | hws[IMX6QDL_CLK_IPU1_DI0_PRE_SEL] = imx_clk_hw_mux_flags("ipu1_di0_pre_sel", base + 0x34, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT); |
666 | clk[IMX6QDL_CLK_IPU2_DI0_PRE_SEL] = imx_clk_mux_flags("ipu2_di0_pre_sel", base + 0x38, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT); | 663 | hws[IMX6QDL_CLK_IPU1_DI1_PRE_SEL] = imx_clk_hw_mux_flags("ipu1_di1_pre_sel", base + 0x34, 15, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT); |
667 | clk[IMX6QDL_CLK_IPU2_DI1_PRE_SEL] = imx_clk_mux_flags("ipu2_di1_pre_sel", base + 0x38, 15, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT); | 664 | hws[IMX6QDL_CLK_IPU2_DI0_PRE_SEL] = imx_clk_hw_mux_flags("ipu2_di0_pre_sel", base + 0x38, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT); |
668 | clk[IMX6QDL_CLK_HSI_TX_SEL] = imx_clk_mux("hsi_tx_sel", base + 0x30, 28, 1, hsi_tx_sels, ARRAY_SIZE(hsi_tx_sels)); | 665 | hws[IMX6QDL_CLK_IPU2_DI1_PRE_SEL] = imx_clk_hw_mux_flags("ipu2_di1_pre_sel", base + 0x38, 15, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT); |
669 | clk[IMX6QDL_CLK_PCIE_AXI_SEL] = imx_clk_mux("pcie_axi_sel", base + 0x18, 10, 1, pcie_axi_sels, ARRAY_SIZE(pcie_axi_sels)); | 666 | hws[IMX6QDL_CLK_HSI_TX_SEL] = imx_clk_hw_mux("hsi_tx_sel", base + 0x30, 28, 1, hsi_tx_sels, ARRAY_SIZE(hsi_tx_sels)); |
667 | hws[IMX6QDL_CLK_PCIE_AXI_SEL] = imx_clk_hw_mux("pcie_axi_sel", base + 0x18, 10, 1, pcie_axi_sels, ARRAY_SIZE(pcie_axi_sels)); | ||
668 | |||
670 | if (clk_on_imx6qp()) { | 669 | if (clk_on_imx6qp()) { |
671 | clk[IMX6QDL_CLK_IPU1_DI0_SEL] = imx_clk_mux_flags("ipu1_di0_sel", base + 0x34, 0, 3, ipu1_di0_sels_2, ARRAY_SIZE(ipu1_di0_sels_2), CLK_SET_RATE_PARENT); | 670 | hws[IMX6QDL_CLK_IPU1_DI0_SEL] = imx_clk_hw_mux_flags("ipu1_di0_sel", base + 0x34, 0, 3, ipu1_di0_sels_2, ARRAY_SIZE(ipu1_di0_sels_2), CLK_SET_RATE_PARENT); |
672 | clk[IMX6QDL_CLK_IPU1_DI1_SEL] = imx_clk_mux_flags("ipu1_di1_sel", base + 0x34, 9, 3, ipu1_di1_sels_2, ARRAY_SIZE(ipu1_di1_sels_2), CLK_SET_RATE_PARENT); | 671 | hws[IMX6QDL_CLK_IPU1_DI1_SEL] = imx_clk_hw_mux_flags("ipu1_di1_sel", base + 0x34, 9, 3, ipu1_di1_sels_2, ARRAY_SIZE(ipu1_di1_sels_2), CLK_SET_RATE_PARENT); |
673 | clk[IMX6QDL_CLK_IPU2_DI0_SEL] = imx_clk_mux_flags("ipu2_di0_sel", base + 0x38, 0, 3, ipu2_di0_sels_2, ARRAY_SIZE(ipu2_di0_sels_2), CLK_SET_RATE_PARENT); | 672 | hws[IMX6QDL_CLK_IPU2_DI0_SEL] = imx_clk_hw_mux_flags("ipu2_di0_sel", base + 0x38, 0, 3, ipu2_di0_sels_2, ARRAY_SIZE(ipu2_di0_sels_2), CLK_SET_RATE_PARENT); |
674 | clk[IMX6QDL_CLK_IPU2_DI1_SEL] = imx_clk_mux_flags("ipu2_di1_sel", base + 0x38, 9, 3, ipu2_di1_sels_2, ARRAY_SIZE(ipu2_di1_sels_2), CLK_SET_RATE_PARENT); | 673 | hws[IMX6QDL_CLK_IPU2_DI1_SEL] = imx_clk_hw_mux_flags("ipu2_di1_sel", base + 0x38, 9, 3, ipu2_di1_sels_2, ARRAY_SIZE(ipu2_di1_sels_2), CLK_SET_RATE_PARENT); |
675 | clk[IMX6QDL_CLK_SSI1_SEL] = imx_clk_mux("ssi1_sel", base + 0x1c, 10, 2, ssi_sels, ARRAY_SIZE(ssi_sels)); | 674 | hws[IMX6QDL_CLK_SSI1_SEL] = imx_clk_hw_mux("ssi1_sel", base + 0x1c, 10, 2, ssi_sels, ARRAY_SIZE(ssi_sels)); |
676 | clk[IMX6QDL_CLK_SSI2_SEL] = imx_clk_mux("ssi2_sel", base + 0x1c, 12, 2, ssi_sels, ARRAY_SIZE(ssi_sels)); | 675 | hws[IMX6QDL_CLK_SSI2_SEL] = imx_clk_hw_mux("ssi2_sel", base + 0x1c, 12, 2, ssi_sels, ARRAY_SIZE(ssi_sels)); |
677 | clk[IMX6QDL_CLK_SSI3_SEL] = imx_clk_mux("ssi3_sel", base + 0x1c, 14, 2, ssi_sels, ARRAY_SIZE(ssi_sels)); | 676 | hws[IMX6QDL_CLK_SSI3_SEL] = imx_clk_hw_mux("ssi3_sel", base + 0x1c, 14, 2, ssi_sels, ARRAY_SIZE(ssi_sels)); |
678 | clk[IMX6QDL_CLK_USDHC1_SEL] = imx_clk_mux("usdhc1_sel", base + 0x1c, 16, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels)); | 677 | hws[IMX6QDL_CLK_USDHC1_SEL] = imx_clk_hw_mux("usdhc1_sel", base + 0x1c, 16, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels)); |
679 | clk[IMX6QDL_CLK_USDHC2_SEL] = imx_clk_mux("usdhc2_sel", base + 0x1c, 17, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels)); | 678 | hws[IMX6QDL_CLK_USDHC2_SEL] = imx_clk_hw_mux("usdhc2_sel", base + 0x1c, 17, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels)); |
680 | clk[IMX6QDL_CLK_USDHC3_SEL] = imx_clk_mux("usdhc3_sel", base + 0x1c, 18, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels)); | 679 | hws[IMX6QDL_CLK_USDHC3_SEL] = imx_clk_hw_mux("usdhc3_sel", base + 0x1c, 18, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels)); |
681 | clk[IMX6QDL_CLK_USDHC4_SEL] = imx_clk_mux("usdhc4_sel", base + 0x1c, 19, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels)); | 680 | hws[IMX6QDL_CLK_USDHC4_SEL] = imx_clk_hw_mux("usdhc4_sel", base + 0x1c, 19, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels)); |
682 | clk[IMX6QDL_CLK_ENFC_SEL] = imx_clk_mux("enfc_sel", base + 0x2c, 15, 3, enfc_sels_2, ARRAY_SIZE(enfc_sels_2)); | 681 | hws[IMX6QDL_CLK_ENFC_SEL] = imx_clk_hw_mux("enfc_sel", base + 0x2c, 15, 3, enfc_sels_2, ARRAY_SIZE(enfc_sels_2)); |
683 | clk[IMX6QDL_CLK_EIM_SEL] = imx_clk_mux("eim_sel", base + 0x1c, 27, 2, eim_sels, ARRAY_SIZE(eim_sels)); | 682 | hws[IMX6QDL_CLK_EIM_SEL] = imx_clk_hw_mux("eim_sel", base + 0x1c, 27, 2, eim_sels, ARRAY_SIZE(eim_sels)); |
684 | clk[IMX6QDL_CLK_EIM_SLOW_SEL] = imx_clk_mux("eim_slow_sel", base + 0x1c, 29, 2, eim_slow_sels, ARRAY_SIZE(eim_slow_sels)); | 683 | hws[IMX6QDL_CLK_EIM_SLOW_SEL] = imx_clk_hw_mux("eim_slow_sel", base + 0x1c, 29, 2, eim_slow_sels, ARRAY_SIZE(eim_slow_sels)); |
685 | clk[IMX6QDL_CLK_PRE_AXI] = imx_clk_mux("pre_axi", base + 0x18, 1, 1, pre_axi_sels, ARRAY_SIZE(pre_axi_sels)); | 684 | hws[IMX6QDL_CLK_PRE_AXI] = imx_clk_hw_mux("pre_axi", base + 0x18, 1, 1, pre_axi_sels, ARRAY_SIZE(pre_axi_sels)); |
686 | } else { | 685 | } else { |
687 | clk[IMX6QDL_CLK_IPU1_DI0_SEL] = imx_clk_mux_flags("ipu1_di0_sel", base + 0x34, 0, 3, ipu1_di0_sels, ARRAY_SIZE(ipu1_di0_sels), CLK_SET_RATE_PARENT); | 686 | hws[IMX6QDL_CLK_IPU1_DI0_SEL] = imx_clk_hw_mux_flags("ipu1_di0_sel", base + 0x34, 0, 3, ipu1_di0_sels, ARRAY_SIZE(ipu1_di0_sels), CLK_SET_RATE_PARENT); |
688 | clk[IMX6QDL_CLK_IPU1_DI1_SEL] = imx_clk_mux_flags("ipu1_di1_sel", base + 0x34, 9, 3, ipu1_di1_sels, ARRAY_SIZE(ipu1_di1_sels), CLK_SET_RATE_PARENT); | 687 | hws[IMX6QDL_CLK_IPU1_DI1_SEL] = imx_clk_hw_mux_flags("ipu1_di1_sel", base + 0x34, 9, 3, ipu1_di1_sels, ARRAY_SIZE(ipu1_di1_sels), CLK_SET_RATE_PARENT); |
689 | clk[IMX6QDL_CLK_IPU2_DI0_SEL] = imx_clk_mux_flags("ipu2_di0_sel", base + 0x38, 0, 3, ipu2_di0_sels, ARRAY_SIZE(ipu2_di0_sels), CLK_SET_RATE_PARENT); | 688 | hws[IMX6QDL_CLK_IPU2_DI0_SEL] = imx_clk_hw_mux_flags("ipu2_di0_sel", base + 0x38, 0, 3, ipu2_di0_sels, ARRAY_SIZE(ipu2_di0_sels), CLK_SET_RATE_PARENT); |
690 | clk[IMX6QDL_CLK_IPU2_DI1_SEL] = imx_clk_mux_flags("ipu2_di1_sel", base + 0x38, 9, 3, ipu2_di1_sels, ARRAY_SIZE(ipu2_di1_sels), CLK_SET_RATE_PARENT); | 689 | hws[IMX6QDL_CLK_IPU2_DI1_SEL] = imx_clk_hw_mux_flags("ipu2_di1_sel", base + 0x38, 9, 3, ipu2_di1_sels, ARRAY_SIZE(ipu2_di1_sels), CLK_SET_RATE_PARENT); |
691 | clk[IMX6QDL_CLK_SSI1_SEL] = imx_clk_fixup_mux("ssi1_sel", base + 0x1c, 10, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup); | 690 | hws[IMX6QDL_CLK_SSI1_SEL] = imx_clk_hw_fixup_mux("ssi1_sel", base + 0x1c, 10, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup); |
692 | clk[IMX6QDL_CLK_SSI2_SEL] = imx_clk_fixup_mux("ssi2_sel", base + 0x1c, 12, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup); | 691 | hws[IMX6QDL_CLK_SSI2_SEL] = imx_clk_hw_fixup_mux("ssi2_sel", base + 0x1c, 12, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup); |
693 | clk[IMX6QDL_CLK_SSI3_SEL] = imx_clk_fixup_mux("ssi3_sel", base + 0x1c, 14, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup); | 692 | hws[IMX6QDL_CLK_SSI3_SEL] = imx_clk_hw_fixup_mux("ssi3_sel", base + 0x1c, 14, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup); |
694 | clk[IMX6QDL_CLK_USDHC1_SEL] = imx_clk_fixup_mux("usdhc1_sel", base + 0x1c, 16, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup); | 693 | hws[IMX6QDL_CLK_USDHC1_SEL] = imx_clk_hw_fixup_mux("usdhc1_sel", base + 0x1c, 16, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup); |
695 | clk[IMX6QDL_CLK_USDHC2_SEL] = imx_clk_fixup_mux("usdhc2_sel", base + 0x1c, 17, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup); | 694 | hws[IMX6QDL_CLK_USDHC2_SEL] = imx_clk_hw_fixup_mux("usdhc2_sel", base + 0x1c, 17, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup); |
696 | clk[IMX6QDL_CLK_USDHC3_SEL] = imx_clk_fixup_mux("usdhc3_sel", base + 0x1c, 18, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup); | 695 | hws[IMX6QDL_CLK_USDHC3_SEL] = imx_clk_hw_fixup_mux("usdhc3_sel", base + 0x1c, 18, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup); |
697 | clk[IMX6QDL_CLK_USDHC4_SEL] = imx_clk_fixup_mux("usdhc4_sel", base + 0x1c, 19, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup); | 696 | hws[IMX6QDL_CLK_USDHC4_SEL] = imx_clk_hw_fixup_mux("usdhc4_sel", base + 0x1c, 19, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup); |
698 | clk[IMX6QDL_CLK_ENFC_SEL] = imx_clk_mux("enfc_sel", base + 0x2c, 16, 2, enfc_sels, ARRAY_SIZE(enfc_sels)); | 697 | hws[IMX6QDL_CLK_ENFC_SEL] = imx_clk_hw_mux("enfc_sel", base + 0x2c, 16, 2, enfc_sels, ARRAY_SIZE(enfc_sels)); |
699 | clk[IMX6QDL_CLK_EIM_SEL] = imx_clk_fixup_mux("eim_sel", base + 0x1c, 27, 2, eim_sels, ARRAY_SIZE(eim_sels), imx_cscmr1_fixup); | 698 | hws[IMX6QDL_CLK_EIM_SEL] = imx_clk_hw_fixup_mux("eim_sel", base + 0x1c, 27, 2, eim_sels, ARRAY_SIZE(eim_sels), imx_cscmr1_fixup); |
700 | clk[IMX6QDL_CLK_EIM_SLOW_SEL] = imx_clk_fixup_mux("eim_slow_sel", base + 0x1c, 29, 2, eim_slow_sels, ARRAY_SIZE(eim_slow_sels), imx_cscmr1_fixup); | 699 | hws[IMX6QDL_CLK_EIM_SLOW_SEL] = imx_clk_hw_fixup_mux("eim_slow_sel", base + 0x1c, 29, 2, eim_slow_sels, ARRAY_SIZE(eim_slow_sels), imx_cscmr1_fixup); |
701 | } | 700 | } |
702 | clk[IMX6QDL_CLK_VDO_AXI_SEL] = imx_clk_mux("vdo_axi_sel", base + 0x18, 11, 1, vdo_axi_sels, ARRAY_SIZE(vdo_axi_sels)); | 701 | |
703 | clk[IMX6QDL_CLK_VPU_AXI_SEL] = imx_clk_mux("vpu_axi_sel", base + 0x18, 14, 2, vpu_axi_sels, ARRAY_SIZE(vpu_axi_sels)); | 702 | hws[IMX6QDL_CLK_VDO_AXI_SEL] = imx_clk_hw_mux("vdo_axi_sel", base + 0x18, 11, 1, vdo_axi_sels, ARRAY_SIZE(vdo_axi_sels)); |
704 | clk[IMX6QDL_CLK_CKO1_SEL] = imx_clk_mux("cko1_sel", base + 0x60, 0, 4, cko1_sels, ARRAY_SIZE(cko1_sels)); | 703 | hws[IMX6QDL_CLK_VPU_AXI_SEL] = imx_clk_hw_mux("vpu_axi_sel", base + 0x18, 14, 2, vpu_axi_sels, ARRAY_SIZE(vpu_axi_sels)); |
705 | clk[IMX6QDL_CLK_CKO2_SEL] = imx_clk_mux("cko2_sel", base + 0x60, 16, 5, cko2_sels, ARRAY_SIZE(cko2_sels)); | 704 | hws[IMX6QDL_CLK_CKO1_SEL] = imx_clk_hw_mux("cko1_sel", base + 0x60, 0, 4, cko1_sels, ARRAY_SIZE(cko1_sels)); |
706 | clk[IMX6QDL_CLK_CKO] = imx_clk_mux("cko", base + 0x60, 8, 1, cko_sels, ARRAY_SIZE(cko_sels)); | 705 | hws[IMX6QDL_CLK_CKO2_SEL] = imx_clk_hw_mux("cko2_sel", base + 0x60, 16, 5, cko2_sels, ARRAY_SIZE(cko2_sels)); |
706 | hws[IMX6QDL_CLK_CKO] = imx_clk_hw_mux("cko", base + 0x60, 8, 1, cko_sels, ARRAY_SIZE(cko_sels)); | ||
707 | 707 | ||
708 | /* name reg shift width busy: reg, shift parent_names num_parents */ | 708 | /* name reg shift width busy: reg, shift parent_names num_parents */ |
709 | clk[IMX6QDL_CLK_PERIPH] = imx_clk_busy_mux("periph", base + 0x14, 25, 1, base + 0x48, 5, periph_sels, ARRAY_SIZE(periph_sels)); | 709 | hws[IMX6QDL_CLK_PERIPH] = imx_clk_hw_busy_mux("periph", base + 0x14, 25, 1, base + 0x48, 5, periph_sels, ARRAY_SIZE(periph_sels)); |
710 | clk[IMX6QDL_CLK_PERIPH2] = imx_clk_busy_mux("periph2", base + 0x14, 26, 1, base + 0x48, 3, periph2_sels, ARRAY_SIZE(periph2_sels)); | 710 | hws[IMX6QDL_CLK_PERIPH2] = imx_clk_hw_busy_mux("periph2", base + 0x14, 26, 1, base + 0x48, 3, periph2_sels, ARRAY_SIZE(periph2_sels)); |
711 | 711 | ||
712 | /* name parent_name reg shift width */ | 712 | /* name parent_name reg shift width */ |
713 | clk[IMX6QDL_CLK_PERIPH_CLK2] = imx_clk_divider("periph_clk2", "periph_clk2_sel", base + 0x14, 27, 3); | 713 | hws[IMX6QDL_CLK_PERIPH_CLK2] = imx_clk_hw_divider("periph_clk2", "periph_clk2_sel", base + 0x14, 27, 3); |
714 | clk[IMX6QDL_CLK_PERIPH2_CLK2] = imx_clk_divider("periph2_clk2", "periph2_clk2_sel", base + 0x14, 0, 3); | 714 | hws[IMX6QDL_CLK_PERIPH2_CLK2] = imx_clk_hw_divider("periph2_clk2", "periph2_clk2_sel", base + 0x14, 0, 3); |
715 | clk[IMX6QDL_CLK_IPG] = imx_clk_divider("ipg", "ahb", base + 0x14, 8, 2); | 715 | hws[IMX6QDL_CLK_IPG] = imx_clk_hw_divider("ipg", "ahb", base + 0x14, 8, 2); |
716 | clk[IMX6QDL_CLK_ESAI_PRED] = imx_clk_divider("esai_pred", "esai_sel", base + 0x28, 9, 3); | 716 | hws[IMX6QDL_CLK_ESAI_PRED] = imx_clk_hw_divider("esai_pred", "esai_sel", base + 0x28, 9, 3); |
717 | clk[IMX6QDL_CLK_ESAI_PODF] = imx_clk_divider("esai_podf", "esai_pred", base + 0x28, 25, 3); | 717 | hws[IMX6QDL_CLK_ESAI_PODF] = imx_clk_hw_divider("esai_podf", "esai_pred", base + 0x28, 25, 3); |
718 | clk[IMX6QDL_CLK_ASRC_PRED] = imx_clk_divider("asrc_pred", "asrc_sel", base + 0x30, 12, 3); | 718 | hws[IMX6QDL_CLK_ASRC_PRED] = imx_clk_hw_divider("asrc_pred", "asrc_sel", base + 0x30, 12, 3); |
719 | clk[IMX6QDL_CLK_ASRC_PODF] = imx_clk_divider("asrc_podf", "asrc_pred", base + 0x30, 9, 3); | 719 | hws[IMX6QDL_CLK_ASRC_PODF] = imx_clk_hw_divider("asrc_podf", "asrc_pred", base + 0x30, 9, 3); |
720 | clk[IMX6QDL_CLK_SPDIF_PRED] = imx_clk_divider("spdif_pred", "spdif_sel", base + 0x30, 25, 3); | 720 | hws[IMX6QDL_CLK_SPDIF_PRED] = imx_clk_hw_divider("spdif_pred", "spdif_sel", base + 0x30, 25, 3); |
721 | clk[IMX6QDL_CLK_SPDIF_PODF] = imx_clk_divider("spdif_podf", "spdif_pred", base + 0x30, 22, 3); | 721 | hws[IMX6QDL_CLK_SPDIF_PODF] = imx_clk_hw_divider("spdif_podf", "spdif_pred", base + 0x30, 22, 3); |
722 | |||
722 | if (clk_on_imx6qp()) { | 723 | if (clk_on_imx6qp()) { |
723 | clk[IMX6QDL_CLK_IPG_PER] = imx_clk_divider("ipg_per", "ipg_per_sel", base + 0x1c, 0, 6); | 724 | hws[IMX6QDL_CLK_IPG_PER] = imx_clk_hw_divider("ipg_per", "ipg_per_sel", base + 0x1c, 0, 6); |
724 | clk[IMX6QDL_CLK_ECSPI_ROOT] = imx_clk_divider("ecspi_root", "ecspi_sel", base + 0x38, 19, 6); | 725 | hws[IMX6QDL_CLK_ECSPI_ROOT] = imx_clk_hw_divider("ecspi_root", "ecspi_sel", base + 0x38, 19, 6); |
725 | clk[IMX6QDL_CLK_CAN_ROOT] = imx_clk_divider("can_root", "can_sel", base + 0x20, 2, 6); | 726 | hws[IMX6QDL_CLK_CAN_ROOT] = imx_clk_hw_divider("can_root", "can_sel", base + 0x20, 2, 6); |
726 | clk[IMX6QDL_CLK_UART_SERIAL_PODF] = imx_clk_divider("uart_serial_podf", "uart_sel", base + 0x24, 0, 6); | 727 | hws[IMX6QDL_CLK_UART_SERIAL_PODF] = imx_clk_hw_divider("uart_serial_podf", "uart_sel", base + 0x24, 0, 6); |
727 | clk[IMX6QDL_CLK_LDB_DI0_DIV_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0", 2, 7); | 728 | hws[IMX6QDL_CLK_LDB_DI0_DIV_3_5] = imx_clk_hw_fixed_factor("ldb_di0_div_3_5", "ldb_di0", 2, 7); |
728 | clk[IMX6QDL_CLK_LDB_DI1_DIV_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1", 2, 7); | 729 | hws[IMX6QDL_CLK_LDB_DI1_DIV_3_5] = imx_clk_hw_fixed_factor("ldb_di1_div_3_5", "ldb_di1", 2, 7); |
729 | } else { | 730 | } else { |
730 | clk[IMX6QDL_CLK_ECSPI_ROOT] = imx_clk_divider("ecspi_root", "pll3_60m", base + 0x38, 19, 6); | 731 | hws[IMX6QDL_CLK_ECSPI_ROOT] = imx_clk_hw_divider("ecspi_root", "pll3_60m", base + 0x38, 19, 6); |
731 | clk[IMX6QDL_CLK_CAN_ROOT] = imx_clk_divider("can_root", "pll3_60m", base + 0x20, 2, 6); | 732 | hws[IMX6QDL_CLK_CAN_ROOT] = imx_clk_hw_divider("can_root", "pll3_60m", base + 0x20, 2, 6); |
732 | clk[IMX6QDL_CLK_IPG_PER] = imx_clk_fixup_divider("ipg_per", "ipg", base + 0x1c, 0, 6, imx_cscmr1_fixup); | 733 | hws[IMX6QDL_CLK_IPG_PER] = imx_clk_hw_fixup_divider("ipg_per", "ipg", base + 0x1c, 0, 6, imx_cscmr1_fixup); |
733 | clk[IMX6QDL_CLK_UART_SERIAL_PODF] = imx_clk_divider("uart_serial_podf", "pll3_80m", base + 0x24, 0, 6); | 734 | hws[IMX6QDL_CLK_UART_SERIAL_PODF] = imx_clk_hw_divider("uart_serial_podf", "pll3_80m", base + 0x24, 0, 6); |
734 | clk[IMX6QDL_CLK_LDB_DI0_DIV_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7); | 735 | hws[IMX6QDL_CLK_LDB_DI0_DIV_3_5] = imx_clk_hw_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7); |
735 | clk[IMX6QDL_CLK_LDB_DI1_DIV_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7); | 736 | hws[IMX6QDL_CLK_LDB_DI1_DIV_3_5] = imx_clk_hw_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7); |
736 | } | 737 | } |
738 | |||
737 | if (clk_on_imx6dl()) | 739 | if (clk_on_imx6dl()) |
738 | clk[IMX6QDL_CLK_MLB_PODF] = imx_clk_divider("mlb_podf", "mlb_sel", base + 0x18, 23, 3); | 740 | hws[IMX6QDL_CLK_MLB_PODF] = imx_clk_hw_divider("mlb_podf", "mlb_sel", base + 0x18, 23, 3); |
739 | else | 741 | else |
740 | clk[IMX6QDL_CLK_GPU2D_CORE_PODF] = imx_clk_divider("gpu2d_core_podf", "gpu2d_core_sel", base + 0x18, 23, 3); | 742 | hws[IMX6QDL_CLK_GPU2D_CORE_PODF] = imx_clk_hw_divider("gpu2d_core_podf", "gpu2d_core_sel", base + 0x18, 23, 3); |
741 | clk[IMX6QDL_CLK_GPU3D_CORE_PODF] = imx_clk_divider("gpu3d_core_podf", "gpu3d_core_sel", base + 0x18, 26, 3); | 743 | hws[IMX6QDL_CLK_GPU3D_CORE_PODF] = imx_clk_hw_divider("gpu3d_core_podf", "gpu3d_core_sel", base + 0x18, 26, 3); |
742 | if (clk_on_imx6dl()) | 744 | if (clk_on_imx6dl()) |
743 | clk[IMX6QDL_CLK_GPU2D_CORE_PODF] = imx_clk_divider("gpu2d_core_podf", "gpu2d_core_sel", base + 0x18, 29, 3); | 745 | hws[IMX6QDL_CLK_GPU2D_CORE_PODF] = imx_clk_hw_divider("gpu2d_core_podf", "gpu2d_core_sel", base + 0x18, 29, 3); |
744 | else | 746 | else |
745 | clk[IMX6QDL_CLK_GPU3D_SHADER] = imx_clk_divider("gpu3d_shader", "gpu3d_shader_sel", base + 0x18, 29, 3); | 747 | hws[IMX6QDL_CLK_GPU3D_SHADER] = imx_clk_hw_divider("gpu3d_shader", "gpu3d_shader_sel", base + 0x18, 29, 3); |
746 | clk[IMX6QDL_CLK_IPU1_PODF] = imx_clk_divider("ipu1_podf", "ipu1_sel", base + 0x3c, 11, 3); | 748 | hws[IMX6QDL_CLK_IPU1_PODF] = imx_clk_hw_divider("ipu1_podf", "ipu1_sel", base + 0x3c, 11, 3); |
747 | clk[IMX6QDL_CLK_IPU2_PODF] = imx_clk_divider("ipu2_podf", "ipu2_sel", base + 0x3c, 16, 3); | 749 | hws[IMX6QDL_CLK_IPU2_PODF] = imx_clk_hw_divider("ipu2_podf", "ipu2_sel", base + 0x3c, 16, 3); |
748 | clk[IMX6QDL_CLK_LDB_DI0_PODF] = imx_clk_divider_flags("ldb_di0_podf", "ldb_di0_div_3_5", base + 0x20, 10, 1, 0); | 750 | hws[IMX6QDL_CLK_LDB_DI0_PODF] = imx_clk_hw_divider_flags("ldb_di0_podf", "ldb_di0_div_3_5", base + 0x20, 10, 1, 0); |
749 | clk[IMX6QDL_CLK_LDB_DI1_PODF] = imx_clk_divider_flags("ldb_di1_podf", "ldb_di1_div_3_5", base + 0x20, 11, 1, 0); | 751 | hws[IMX6QDL_CLK_LDB_DI1_PODF] = imx_clk_hw_divider_flags("ldb_di1_podf", "ldb_di1_div_3_5", base + 0x20, 11, 1, 0); |
750 | clk[IMX6QDL_CLK_IPU1_DI0_PRE] = imx_clk_divider("ipu1_di0_pre", "ipu1_di0_pre_sel", base + 0x34, 3, 3); | 752 | hws[IMX6QDL_CLK_IPU1_DI0_PRE] = imx_clk_hw_divider("ipu1_di0_pre", "ipu1_di0_pre_sel", base + 0x34, 3, 3); |
751 | clk[IMX6QDL_CLK_IPU1_DI1_PRE] = imx_clk_divider("ipu1_di1_pre", "ipu1_di1_pre_sel", base + 0x34, 12, 3); | 753 | hws[IMX6QDL_CLK_IPU1_DI1_PRE] = imx_clk_hw_divider("ipu1_di1_pre", "ipu1_di1_pre_sel", base + 0x34, 12, 3); |
752 | clk[IMX6QDL_CLK_IPU2_DI0_PRE] = imx_clk_divider("ipu2_di0_pre", "ipu2_di0_pre_sel", base + 0x38, 3, 3); | 754 | hws[IMX6QDL_CLK_IPU2_DI0_PRE] = imx_clk_hw_divider("ipu2_di0_pre", "ipu2_di0_pre_sel", base + 0x38, 3, 3); |
753 | clk[IMX6QDL_CLK_IPU2_DI1_PRE] = imx_clk_divider("ipu2_di1_pre", "ipu2_di1_pre_sel", base + 0x38, 12, 3); | 755 | hws[IMX6QDL_CLK_IPU2_DI1_PRE] = imx_clk_hw_divider("ipu2_di1_pre", "ipu2_di1_pre_sel", base + 0x38, 12, 3); |
754 | clk[IMX6QDL_CLK_HSI_TX_PODF] = imx_clk_divider("hsi_tx_podf", "hsi_tx_sel", base + 0x30, 29, 3); | 756 | hws[IMX6QDL_CLK_HSI_TX_PODF] = imx_clk_hw_divider("hsi_tx_podf", "hsi_tx_sel", base + 0x30, 29, 3); |
755 | clk[IMX6QDL_CLK_SSI1_PRED] = imx_clk_divider("ssi1_pred", "ssi1_sel", base + 0x28, 6, 3); | 757 | hws[IMX6QDL_CLK_SSI1_PRED] = imx_clk_hw_divider("ssi1_pred", "ssi1_sel", base + 0x28, 6, 3); |
756 | clk[IMX6QDL_CLK_SSI1_PODF] = imx_clk_divider("ssi1_podf", "ssi1_pred", base + 0x28, 0, 6); | 758 | hws[IMX6QDL_CLK_SSI1_PODF] = imx_clk_hw_divider("ssi1_podf", "ssi1_pred", base + 0x28, 0, 6); |
757 | clk[IMX6QDL_CLK_SSI2_PRED] = imx_clk_divider("ssi2_pred", "ssi2_sel", base + 0x2c, 6, 3); | 759 | hws[IMX6QDL_CLK_SSI2_PRED] = imx_clk_hw_divider("ssi2_pred", "ssi2_sel", base + 0x2c, 6, 3); |
758 | clk[IMX6QDL_CLK_SSI2_PODF] = imx_clk_divider("ssi2_podf", "ssi2_pred", base + 0x2c, 0, 6); | 760 | hws[IMX6QDL_CLK_SSI2_PODF] = imx_clk_hw_divider("ssi2_podf", "ssi2_pred", base + 0x2c, 0, 6); |
759 | clk[IMX6QDL_CLK_SSI3_PRED] = imx_clk_divider("ssi3_pred", "ssi3_sel", base + 0x28, 22, 3); | 761 | hws[IMX6QDL_CLK_SSI3_PRED] = imx_clk_hw_divider("ssi3_pred", "ssi3_sel", base + 0x28, 22, 3); |
760 | clk[IMX6QDL_CLK_SSI3_PODF] = imx_clk_divider("ssi3_podf", "ssi3_pred", base + 0x28, 16, 6); | 762 | hws[IMX6QDL_CLK_SSI3_PODF] = imx_clk_hw_divider("ssi3_podf", "ssi3_pred", base + 0x28, 16, 6); |
761 | clk[IMX6QDL_CLK_USDHC1_PODF] = imx_clk_divider("usdhc1_podf", "usdhc1_sel", base + 0x24, 11, 3); | 763 | hws[IMX6QDL_CLK_USDHC1_PODF] = imx_clk_hw_divider("usdhc1_podf", "usdhc1_sel", base + 0x24, 11, 3); |
762 | clk[IMX6QDL_CLK_USDHC2_PODF] = imx_clk_divider("usdhc2_podf", "usdhc2_sel", base + 0x24, 16, 3); | 764 | hws[IMX6QDL_CLK_USDHC2_PODF] = imx_clk_hw_divider("usdhc2_podf", "usdhc2_sel", base + 0x24, 16, 3); |
763 | clk[IMX6QDL_CLK_USDHC3_PODF] = imx_clk_divider("usdhc3_podf", "usdhc3_sel", base + 0x24, 19, 3); | 765 | hws[IMX6QDL_CLK_USDHC3_PODF] = imx_clk_hw_divider("usdhc3_podf", "usdhc3_sel", base + 0x24, 19, 3); |
764 | clk[IMX6QDL_CLK_USDHC4_PODF] = imx_clk_divider("usdhc4_podf", "usdhc4_sel", base + 0x24, 22, 3); | 766 | hws[IMX6QDL_CLK_USDHC4_PODF] = imx_clk_hw_divider("usdhc4_podf", "usdhc4_sel", base + 0x24, 22, 3); |
765 | clk[IMX6QDL_CLK_ENFC_PRED] = imx_clk_divider("enfc_pred", "enfc_sel", base + 0x2c, 18, 3); | 767 | hws[IMX6QDL_CLK_ENFC_PRED] = imx_clk_hw_divider("enfc_pred", "enfc_sel", base + 0x2c, 18, 3); |
766 | clk[IMX6QDL_CLK_ENFC_PODF] = imx_clk_divider("enfc_podf", "enfc_pred", base + 0x2c, 21, 6); | 768 | hws[IMX6QDL_CLK_ENFC_PODF] = imx_clk_hw_divider("enfc_podf", "enfc_pred", base + 0x2c, 21, 6); |
767 | if (clk_on_imx6qp()) { | 769 | if (clk_on_imx6qp()) { |
768 | clk[IMX6QDL_CLK_EIM_PODF] = imx_clk_divider("eim_podf", "eim_sel", base + 0x1c, 20, 3); | 770 | hws[IMX6QDL_CLK_EIM_PODF] = imx_clk_hw_divider("eim_podf", "eim_sel", base + 0x1c, 20, 3); |
769 | clk[IMX6QDL_CLK_EIM_SLOW_PODF] = imx_clk_divider("eim_slow_podf", "eim_slow_sel", base + 0x1c, 23, 3); | 771 | hws[IMX6QDL_CLK_EIM_SLOW_PODF] = imx_clk_hw_divider("eim_slow_podf", "eim_slow_sel", base + 0x1c, 23, 3); |
770 | } else { | 772 | } else { |
771 | clk[IMX6QDL_CLK_EIM_PODF] = imx_clk_fixup_divider("eim_podf", "eim_sel", base + 0x1c, 20, 3, imx_cscmr1_fixup); | 773 | hws[IMX6QDL_CLK_EIM_PODF] = imx_clk_hw_fixup_divider("eim_podf", "eim_sel", base + 0x1c, 20, 3, imx_cscmr1_fixup); |
772 | clk[IMX6QDL_CLK_EIM_SLOW_PODF] = imx_clk_fixup_divider("eim_slow_podf", "eim_slow_sel", base + 0x1c, 23, 3, imx_cscmr1_fixup); | 774 | hws[IMX6QDL_CLK_EIM_SLOW_PODF] = imx_clk_hw_fixup_divider("eim_slow_podf", "eim_slow_sel", base + 0x1c, 23, 3, imx_cscmr1_fixup); |
773 | } | 775 | } |
774 | clk[IMX6QDL_CLK_VPU_AXI_PODF] = imx_clk_divider("vpu_axi_podf", "vpu_axi_sel", base + 0x24, 25, 3); | 776 | |
775 | clk[IMX6QDL_CLK_CKO1_PODF] = imx_clk_divider("cko1_podf", "cko1_sel", base + 0x60, 4, 3); | 777 | hws[IMX6QDL_CLK_VPU_AXI_PODF] = imx_clk_hw_divider("vpu_axi_podf", "vpu_axi_sel", base + 0x24, 25, 3); |
776 | clk[IMX6QDL_CLK_CKO2_PODF] = imx_clk_divider("cko2_podf", "cko2_sel", base + 0x60, 21, 3); | 778 | hws[IMX6QDL_CLK_CKO1_PODF] = imx_clk_hw_divider("cko1_podf", "cko1_sel", base + 0x60, 4, 3); |
779 | hws[IMX6QDL_CLK_CKO2_PODF] = imx_clk_hw_divider("cko2_podf", "cko2_sel", base + 0x60, 21, 3); | ||
777 | 780 | ||
778 | /* name parent_name reg shift width busy: reg, shift */ | 781 | /* name parent_name reg shift width busy: reg, shift */ |
779 | clk[IMX6QDL_CLK_AXI] = imx_clk_busy_divider("axi", "axi_sel", base + 0x14, 16, 3, base + 0x48, 0); | 782 | hws[IMX6QDL_CLK_AXI] = imx_clk_hw_busy_divider("axi", "axi_sel", base + 0x14, 16, 3, base + 0x48, 0); |
780 | clk[IMX6QDL_CLK_MMDC_CH0_AXI_PODF] = imx_clk_busy_divider("mmdc_ch0_axi_podf", "periph", base + 0x14, 19, 3, base + 0x48, 4); | 783 | hws[IMX6QDL_CLK_MMDC_CH0_AXI_PODF] = imx_clk_hw_busy_divider("mmdc_ch0_axi_podf", "periph", base + 0x14, 19, 3, base + 0x48, 4); |
781 | if (clk_on_imx6qp()) { | 784 | if (clk_on_imx6qp()) { |
782 | clk[IMX6QDL_CLK_MMDC_CH1_AXI_CG] = imx_clk_gate("mmdc_ch1_axi_cg", "periph2", base + 0x4, 18); | 785 | hws[IMX6QDL_CLK_MMDC_CH1_AXI_CG] = imx_clk_hw_gate("mmdc_ch1_axi_cg", "periph2", base + 0x4, 18); |
783 | clk[IMX6QDL_CLK_MMDC_CH1_AXI_PODF] = imx_clk_busy_divider("mmdc_ch1_axi_podf", "mmdc_ch1_axi_cg", base + 0x14, 3, 3, base + 0x48, 2); | 786 | hws[IMX6QDL_CLK_MMDC_CH1_AXI_PODF] = imx_clk_hw_busy_divider("mmdc_ch1_axi_podf", "mmdc_ch1_axi_cg", base + 0x14, 3, 3, base + 0x48, 2); |
784 | } else { | 787 | } else { |
785 | clk[IMX6QDL_CLK_MMDC_CH1_AXI_PODF] = imx_clk_busy_divider("mmdc_ch1_axi_podf", "periph2", base + 0x14, 3, 3, base + 0x48, 2); | 788 | hws[IMX6QDL_CLK_MMDC_CH1_AXI_PODF] = imx_clk_hw_busy_divider("mmdc_ch1_axi_podf", "periph2", base + 0x14, 3, 3, base + 0x48, 2); |
786 | } | 789 | } |
787 | clk[IMX6QDL_CLK_ARM] = imx_clk_busy_divider("arm", "pll1_sw", base + 0x10, 0, 3, base + 0x48, 16); | 790 | hws[IMX6QDL_CLK_ARM] = imx_clk_hw_busy_divider("arm", "pll1_sw", base + 0x10, 0, 3, base + 0x48, 16); |
788 | clk[IMX6QDL_CLK_AHB] = imx_clk_busy_divider("ahb", "periph", base + 0x14, 10, 3, base + 0x48, 1); | 791 | hws[IMX6QDL_CLK_AHB] = imx_clk_hw_busy_divider("ahb", "periph", base + 0x14, 10, 3, base + 0x48, 1); |
789 | 792 | ||
790 | /* name parent_name reg shift */ | 793 | /* name parent_name reg shift */ |
791 | clk[IMX6QDL_CLK_APBH_DMA] = imx_clk_gate2("apbh_dma", "usdhc3", base + 0x68, 4); | 794 | hws[IMX6QDL_CLK_APBH_DMA] = imx_clk_hw_gate2("apbh_dma", "usdhc3", base + 0x68, 4); |
792 | clk[IMX6QDL_CLK_ASRC] = imx_clk_gate2_shared("asrc", "asrc_podf", base + 0x68, 6, &share_count_asrc); | 795 | hws[IMX6QDL_CLK_ASRC] = imx_clk_hw_gate2_shared("asrc", "asrc_podf", base + 0x68, 6, &share_count_asrc); |
793 | clk[IMX6QDL_CLK_ASRC_IPG] = imx_clk_gate2_shared("asrc_ipg", "ahb", base + 0x68, 6, &share_count_asrc); | 796 | hws[IMX6QDL_CLK_ASRC_IPG] = imx_clk_hw_gate2_shared("asrc_ipg", "ahb", base + 0x68, 6, &share_count_asrc); |
794 | clk[IMX6QDL_CLK_ASRC_MEM] = imx_clk_gate2_shared("asrc_mem", "ahb", base + 0x68, 6, &share_count_asrc); | 797 | hws[IMX6QDL_CLK_ASRC_MEM] = imx_clk_hw_gate2_shared("asrc_mem", "ahb", base + 0x68, 6, &share_count_asrc); |
795 | clk[IMX6QDL_CLK_CAAM_MEM] = imx_clk_gate2("caam_mem", "ahb", base + 0x68, 8); | 798 | hws[IMX6QDL_CLK_CAAM_MEM] = imx_clk_hw_gate2("caam_mem", "ahb", base + 0x68, 8); |
796 | clk[IMX6QDL_CLK_CAAM_ACLK] = imx_clk_gate2("caam_aclk", "ahb", base + 0x68, 10); | 799 | hws[IMX6QDL_CLK_CAAM_ACLK] = imx_clk_hw_gate2("caam_aclk", "ahb", base + 0x68, 10); |
797 | clk[IMX6QDL_CLK_CAAM_IPG] = imx_clk_gate2("caam_ipg", "ipg", base + 0x68, 12); | 800 | hws[IMX6QDL_CLK_CAAM_IPG] = imx_clk_hw_gate2("caam_ipg", "ipg", base + 0x68, 12); |
798 | clk[IMX6QDL_CLK_CAN1_IPG] = imx_clk_gate2("can1_ipg", "ipg", base + 0x68, 14); | 801 | hws[IMX6QDL_CLK_CAN1_IPG] = imx_clk_hw_gate2("can1_ipg", "ipg", base + 0x68, 14); |
799 | clk[IMX6QDL_CLK_CAN1_SERIAL] = imx_clk_gate2("can1_serial", "can_root", base + 0x68, 16); | 802 | hws[IMX6QDL_CLK_CAN1_SERIAL] = imx_clk_hw_gate2("can1_serial", "can_root", base + 0x68, 16); |
800 | clk[IMX6QDL_CLK_CAN2_IPG] = imx_clk_gate2("can2_ipg", "ipg", base + 0x68, 18); | 803 | hws[IMX6QDL_CLK_CAN2_IPG] = imx_clk_hw_gate2("can2_ipg", "ipg", base + 0x68, 18); |
801 | clk[IMX6QDL_CLK_CAN2_SERIAL] = imx_clk_gate2("can2_serial", "can_root", base + 0x68, 20); | 804 | hws[IMX6QDL_CLK_CAN2_SERIAL] = imx_clk_hw_gate2("can2_serial", "can_root", base + 0x68, 20); |
802 | clk[IMX6QDL_CLK_DCIC1] = imx_clk_gate2("dcic1", "ipu1_podf", base + 0x68, 24); | 805 | hws[IMX6QDL_CLK_DCIC1] = imx_clk_hw_gate2("dcic1", "ipu1_podf", base + 0x68, 24); |
803 | clk[IMX6QDL_CLK_DCIC2] = imx_clk_gate2("dcic2", "ipu2_podf", base + 0x68, 26); | 806 | hws[IMX6QDL_CLK_DCIC2] = imx_clk_hw_gate2("dcic2", "ipu2_podf", base + 0x68, 26); |
804 | clk[IMX6QDL_CLK_ECSPI1] = imx_clk_gate2("ecspi1", "ecspi_root", base + 0x6c, 0); | 807 | hws[IMX6QDL_CLK_ECSPI1] = imx_clk_hw_gate2("ecspi1", "ecspi_root", base + 0x6c, 0); |
805 | clk[IMX6QDL_CLK_ECSPI2] = imx_clk_gate2("ecspi2", "ecspi_root", base + 0x6c, 2); | 808 | hws[IMX6QDL_CLK_ECSPI2] = imx_clk_hw_gate2("ecspi2", "ecspi_root", base + 0x6c, 2); |
806 | clk[IMX6QDL_CLK_ECSPI3] = imx_clk_gate2("ecspi3", "ecspi_root", base + 0x6c, 4); | 809 | hws[IMX6QDL_CLK_ECSPI3] = imx_clk_hw_gate2("ecspi3", "ecspi_root", base + 0x6c, 4); |
807 | clk[IMX6QDL_CLK_ECSPI4] = imx_clk_gate2("ecspi4", "ecspi_root", base + 0x6c, 6); | 810 | hws[IMX6QDL_CLK_ECSPI4] = imx_clk_hw_gate2("ecspi4", "ecspi_root", base + 0x6c, 6); |
808 | if (clk_on_imx6dl()) | 811 | if (clk_on_imx6dl()) |
809 | clk[IMX6DL_CLK_I2C4] = imx_clk_gate2("i2c4", "ipg_per", base + 0x6c, 8); | 812 | hws[IMX6DL_CLK_I2C4] = imx_clk_hw_gate2("i2c4", "ipg_per", base + 0x6c, 8); |
810 | else | 813 | else |
811 | clk[IMX6Q_CLK_ECSPI5] = imx_clk_gate2("ecspi5", "ecspi_root", base + 0x6c, 8); | 814 | hws[IMX6Q_CLK_ECSPI5] = imx_clk_hw_gate2("ecspi5", "ecspi_root", base + 0x6c, 8); |
812 | clk[IMX6QDL_CLK_ENET] = imx_clk_gate2("enet", "ipg", base + 0x6c, 10); | 815 | hws[IMX6QDL_CLK_ENET] = imx_clk_hw_gate2("enet", "ipg", base + 0x6c, 10); |
813 | clk[IMX6QDL_CLK_EPIT1] = imx_clk_gate2("epit1", "ipg", base + 0x6c, 12); | 816 | hws[IMX6QDL_CLK_EPIT1] = imx_clk_hw_gate2("epit1", "ipg", base + 0x6c, 12); |
814 | clk[IMX6QDL_CLK_EPIT2] = imx_clk_gate2("epit2", "ipg", base + 0x6c, 14); | 817 | hws[IMX6QDL_CLK_EPIT2] = imx_clk_hw_gate2("epit2", "ipg", base + 0x6c, 14); |
815 | clk[IMX6QDL_CLK_ESAI_EXTAL] = imx_clk_gate2_shared("esai_extal", "esai_podf", base + 0x6c, 16, &share_count_esai); | 818 | hws[IMX6QDL_CLK_ESAI_EXTAL] = imx_clk_hw_gate2_shared("esai_extal", "esai_podf", base + 0x6c, 16, &share_count_esai); |
816 | clk[IMX6QDL_CLK_ESAI_IPG] = imx_clk_gate2_shared("esai_ipg", "ahb", base + 0x6c, 16, &share_count_esai); | 819 | hws[IMX6QDL_CLK_ESAI_IPG] = imx_clk_hw_gate2_shared("esai_ipg", "ahb", base + 0x6c, 16, &share_count_esai); |
817 | clk[IMX6QDL_CLK_ESAI_MEM] = imx_clk_gate2_shared("esai_mem", "ahb", base + 0x6c, 16, &share_count_esai); | 820 | hws[IMX6QDL_CLK_ESAI_MEM] = imx_clk_hw_gate2_shared("esai_mem", "ahb", base + 0x6c, 16, &share_count_esai); |
818 | clk[IMX6QDL_CLK_GPT_IPG] = imx_clk_gate2("gpt_ipg", "ipg", base + 0x6c, 20); | 821 | hws[IMX6QDL_CLK_GPT_IPG] = imx_clk_hw_gate2("gpt_ipg", "ipg", base + 0x6c, 20); |
819 | clk[IMX6QDL_CLK_GPT_IPG_PER] = imx_clk_gate2("gpt_ipg_per", "ipg_per", base + 0x6c, 22); | 822 | hws[IMX6QDL_CLK_GPT_IPG_PER] = imx_clk_hw_gate2("gpt_ipg_per", "ipg_per", base + 0x6c, 22); |
820 | clk[IMX6QDL_CLK_GPU2D_CORE] = imx_clk_gate2("gpu2d_core", "gpu2d_core_podf", base + 0x6c, 24); | 823 | hws[IMX6QDL_CLK_GPU2D_CORE] = imx_clk_hw_gate2("gpu2d_core", "gpu2d_core_podf", base + 0x6c, 24); |
821 | clk[IMX6QDL_CLK_GPU3D_CORE] = imx_clk_gate2("gpu3d_core", "gpu3d_core_podf", base + 0x6c, 26); | 824 | hws[IMX6QDL_CLK_GPU3D_CORE] = imx_clk_hw_gate2("gpu3d_core", "gpu3d_core_podf", base + 0x6c, 26); |
822 | clk[IMX6QDL_CLK_HDMI_IAHB] = imx_clk_gate2("hdmi_iahb", "ahb", base + 0x70, 0); | 825 | hws[IMX6QDL_CLK_HDMI_IAHB] = imx_clk_hw_gate2("hdmi_iahb", "ahb", base + 0x70, 0); |
823 | clk[IMX6QDL_CLK_HDMI_ISFR] = imx_clk_gate2("hdmi_isfr", "mipi_core_cfg", base + 0x70, 4); | 826 | hws[IMX6QDL_CLK_HDMI_ISFR] = imx_clk_hw_gate2("hdmi_isfr", "mipi_core_cfg", base + 0x70, 4); |
824 | clk[IMX6QDL_CLK_I2C1] = imx_clk_gate2("i2c1", "ipg_per", base + 0x70, 6); | 827 | hws[IMX6QDL_CLK_I2C1] = imx_clk_hw_gate2("i2c1", "ipg_per", base + 0x70, 6); |
825 | clk[IMX6QDL_CLK_I2C2] = imx_clk_gate2("i2c2", "ipg_per", base + 0x70, 8); | 828 | hws[IMX6QDL_CLK_I2C2] = imx_clk_hw_gate2("i2c2", "ipg_per", base + 0x70, 8); |
826 | clk[IMX6QDL_CLK_I2C3] = imx_clk_gate2("i2c3", "ipg_per", base + 0x70, 10); | 829 | hws[IMX6QDL_CLK_I2C3] = imx_clk_hw_gate2("i2c3", "ipg_per", base + 0x70, 10); |
827 | clk[IMX6QDL_CLK_IIM] = imx_clk_gate2("iim", "ipg", base + 0x70, 12); | 830 | hws[IMX6QDL_CLK_IIM] = imx_clk_hw_gate2("iim", "ipg", base + 0x70, 12); |
828 | clk[IMX6QDL_CLK_ENFC] = imx_clk_gate2("enfc", "enfc_podf", base + 0x70, 14); | 831 | hws[IMX6QDL_CLK_ENFC] = imx_clk_hw_gate2("enfc", "enfc_podf", base + 0x70, 14); |
829 | clk[IMX6QDL_CLK_VDOA] = imx_clk_gate2("vdoa", "vdo_axi", base + 0x70, 26); | 832 | hws[IMX6QDL_CLK_VDOA] = imx_clk_hw_gate2("vdoa", "vdo_axi", base + 0x70, 26); |
830 | clk[IMX6QDL_CLK_IPU1] = imx_clk_gate2("ipu1", "ipu1_podf", base + 0x74, 0); | 833 | hws[IMX6QDL_CLK_IPU1] = imx_clk_hw_gate2("ipu1", "ipu1_podf", base + 0x74, 0); |
831 | clk[IMX6QDL_CLK_IPU1_DI0] = imx_clk_gate2("ipu1_di0", "ipu1_di0_sel", base + 0x74, 2); | 834 | hws[IMX6QDL_CLK_IPU1_DI0] = imx_clk_hw_gate2("ipu1_di0", "ipu1_di0_sel", base + 0x74, 2); |
832 | clk[IMX6QDL_CLK_IPU1_DI1] = imx_clk_gate2("ipu1_di1", "ipu1_di1_sel", base + 0x74, 4); | 835 | hws[IMX6QDL_CLK_IPU1_DI1] = imx_clk_hw_gate2("ipu1_di1", "ipu1_di1_sel", base + 0x74, 4); |
833 | clk[IMX6QDL_CLK_IPU2] = imx_clk_gate2("ipu2", "ipu2_podf", base + 0x74, 6); | 836 | hws[IMX6QDL_CLK_IPU2] = imx_clk_hw_gate2("ipu2", "ipu2_podf", base + 0x74, 6); |
834 | clk[IMX6QDL_CLK_IPU2_DI0] = imx_clk_gate2("ipu2_di0", "ipu2_di0_sel", base + 0x74, 8); | 837 | hws[IMX6QDL_CLK_IPU2_DI0] = imx_clk_hw_gate2("ipu2_di0", "ipu2_di0_sel", base + 0x74, 8); |
835 | if (clk_on_imx6qp()) { | 838 | if (clk_on_imx6qp()) { |
836 | clk[IMX6QDL_CLK_LDB_DI0] = imx_clk_gate2("ldb_di0", "ldb_di0_sel", base + 0x74, 12); | 839 | hws[IMX6QDL_CLK_LDB_DI0] = imx_clk_hw_gate2("ldb_di0", "ldb_di0_sel", base + 0x74, 12); |
837 | clk[IMX6QDL_CLK_LDB_DI1] = imx_clk_gate2("ldb_di1", "ldb_di1_sel", base + 0x74, 14); | 840 | hws[IMX6QDL_CLK_LDB_DI1] = imx_clk_hw_gate2("ldb_di1", "ldb_di1_sel", base + 0x74, 14); |
838 | } else { | 841 | } else { |
839 | clk[IMX6QDL_CLK_LDB_DI0] = imx_clk_gate2("ldb_di0", "ldb_di0_podf", base + 0x74, 12); | 842 | hws[IMX6QDL_CLK_LDB_DI0] = imx_clk_hw_gate2("ldb_di0", "ldb_di0_podf", base + 0x74, 12); |
840 | clk[IMX6QDL_CLK_LDB_DI1] = imx_clk_gate2("ldb_di1", "ldb_di1_podf", base + 0x74, 14); | 843 | hws[IMX6QDL_CLK_LDB_DI1] = imx_clk_hw_gate2("ldb_di1", "ldb_di1_podf", base + 0x74, 14); |
841 | } | 844 | } |
842 | clk[IMX6QDL_CLK_IPU2_DI1] = imx_clk_gate2("ipu2_di1", "ipu2_di1_sel", base + 0x74, 10); | 845 | hws[IMX6QDL_CLK_IPU2_DI1] = imx_clk_hw_gate2("ipu2_di1", "ipu2_di1_sel", base + 0x74, 10); |
843 | clk[IMX6QDL_CLK_HSI_TX] = imx_clk_gate2_shared("hsi_tx", "hsi_tx_podf", base + 0x74, 16, &share_count_mipi_core_cfg); | 846 | hws[IMX6QDL_CLK_HSI_TX] = imx_clk_hw_gate2_shared("hsi_tx", "hsi_tx_podf", base + 0x74, 16, &share_count_mipi_core_cfg); |
844 | clk[IMX6QDL_CLK_MIPI_CORE_CFG] = imx_clk_gate2_shared("mipi_core_cfg", "video_27m", base + 0x74, 16, &share_count_mipi_core_cfg); | 847 | hws[IMX6QDL_CLK_MIPI_CORE_CFG] = imx_clk_hw_gate2_shared("mipi_core_cfg", "video_27m", base + 0x74, 16, &share_count_mipi_core_cfg); |
845 | clk[IMX6QDL_CLK_MIPI_IPG] = imx_clk_gate2_shared("mipi_ipg", "ipg", base + 0x74, 16, &share_count_mipi_core_cfg); | 848 | hws[IMX6QDL_CLK_MIPI_IPG] = imx_clk_hw_gate2_shared("mipi_ipg", "ipg", base + 0x74, 16, &share_count_mipi_core_cfg); |
849 | |||
846 | if (clk_on_imx6dl()) | 850 | if (clk_on_imx6dl()) |
847 | /* | 851 | /* |
848 | * The multiplexer and divider of the imx6q clock gpu2d get | 852 | * The multiplexer and divider of the imx6q clock gpu2d get |
849 | * redefined/reused as mlb_sys_sel and mlb_sys_clk_podf on imx6dl. | 853 | * redefined/reused as mlb_sys_sel and mlb_sys_clk_podf on imx6dl. |
850 | */ | 854 | */ |
851 | clk[IMX6QDL_CLK_MLB] = imx_clk_gate2("mlb", "mlb_podf", base + 0x74, 18); | 855 | hws[IMX6QDL_CLK_MLB] = imx_clk_hw_gate2("mlb", "mlb_podf", base + 0x74, 18); |
852 | else | 856 | else |
853 | clk[IMX6QDL_CLK_MLB] = imx_clk_gate2("mlb", "axi", base + 0x74, 18); | 857 | hws[IMX6QDL_CLK_MLB] = imx_clk_hw_gate2("mlb", "axi", base + 0x74, 18); |
854 | clk[IMX6QDL_CLK_MMDC_CH0_AXI] = imx_clk_gate2_flags("mmdc_ch0_axi", "mmdc_ch0_axi_podf", base + 0x74, 20, CLK_IS_CRITICAL); | 858 | hws[IMX6QDL_CLK_MMDC_CH0_AXI] = imx_clk_hw_gate2_flags("mmdc_ch0_axi", "mmdc_ch0_axi_podf", base + 0x74, 20, CLK_IS_CRITICAL); |
855 | clk[IMX6QDL_CLK_MMDC_CH1_AXI] = imx_clk_gate2("mmdc_ch1_axi", "mmdc_ch1_axi_podf", base + 0x74, 22); | 859 | hws[IMX6QDL_CLK_MMDC_CH1_AXI] = imx_clk_hw_gate2("mmdc_ch1_axi", "mmdc_ch1_axi_podf", base + 0x74, 22); |
856 | clk[IMX6QDL_CLK_MMDC_P0_IPG] = imx_clk_gate2_flags("mmdc_p0_ipg", "ipg", base + 0x74, 24, CLK_IS_CRITICAL); | 860 | hws[IMX6QDL_CLK_MMDC_P0_IPG] = imx_clk_hw_gate2_flags("mmdc_p0_ipg", "ipg", base + 0x74, 24, CLK_IS_CRITICAL); |
857 | clk[IMX6QDL_CLK_OCRAM] = imx_clk_gate2("ocram", "ahb", base + 0x74, 28); | 861 | hws[IMX6QDL_CLK_OCRAM] = imx_clk_hw_gate2("ocram", "ahb", base + 0x74, 28); |
858 | clk[IMX6QDL_CLK_OPENVG_AXI] = imx_clk_gate2("openvg_axi", "axi", base + 0x74, 30); | 862 | hws[IMX6QDL_CLK_OPENVG_AXI] = imx_clk_hw_gate2("openvg_axi", "axi", base + 0x74, 30); |
859 | clk[IMX6QDL_CLK_PCIE_AXI] = imx_clk_gate2("pcie_axi", "pcie_axi_sel", base + 0x78, 0); | 863 | hws[IMX6QDL_CLK_PCIE_AXI] = imx_clk_hw_gate2("pcie_axi", "pcie_axi_sel", base + 0x78, 0); |
860 | clk[IMX6QDL_CLK_PER1_BCH] = imx_clk_gate2("per1_bch", "usdhc3", base + 0x78, 12); | 864 | hws[IMX6QDL_CLK_PER1_BCH] = imx_clk_hw_gate2("per1_bch", "usdhc3", base + 0x78, 12); |
861 | clk[IMX6QDL_CLK_PWM1] = imx_clk_gate2("pwm1", "ipg_per", base + 0x78, 16); | 865 | hws[IMX6QDL_CLK_PWM1] = imx_clk_hw_gate2("pwm1", "ipg_per", base + 0x78, 16); |
862 | clk[IMX6QDL_CLK_PWM2] = imx_clk_gate2("pwm2", "ipg_per", base + 0x78, 18); | 866 | hws[IMX6QDL_CLK_PWM2] = imx_clk_hw_gate2("pwm2", "ipg_per", base + 0x78, 18); |
863 | clk[IMX6QDL_CLK_PWM3] = imx_clk_gate2("pwm3", "ipg_per", base + 0x78, 20); | 867 | hws[IMX6QDL_CLK_PWM3] = imx_clk_hw_gate2("pwm3", "ipg_per", base + 0x78, 20); |
864 | clk[IMX6QDL_CLK_PWM4] = imx_clk_gate2("pwm4", "ipg_per", base + 0x78, 22); | 868 | hws[IMX6QDL_CLK_PWM4] = imx_clk_hw_gate2("pwm4", "ipg_per", base + 0x78, 22); |
865 | clk[IMX6QDL_CLK_GPMI_BCH_APB] = imx_clk_gate2("gpmi_bch_apb", "usdhc3", base + 0x78, 24); | 869 | hws[IMX6QDL_CLK_GPMI_BCH_APB] = imx_clk_hw_gate2("gpmi_bch_apb", "usdhc3", base + 0x78, 24); |
866 | clk[IMX6QDL_CLK_GPMI_BCH] = imx_clk_gate2("gpmi_bch", "usdhc4", base + 0x78, 26); | 870 | hws[IMX6QDL_CLK_GPMI_BCH] = imx_clk_hw_gate2("gpmi_bch", "usdhc4", base + 0x78, 26); |
867 | clk[IMX6QDL_CLK_GPMI_IO] = imx_clk_gate2("gpmi_io", "enfc", base + 0x78, 28); | 871 | hws[IMX6QDL_CLK_GPMI_IO] = imx_clk_hw_gate2("gpmi_io", "enfc", base + 0x78, 28); |
868 | clk[IMX6QDL_CLK_GPMI_APB] = imx_clk_gate2("gpmi_apb", "usdhc3", base + 0x78, 30); | 872 | hws[IMX6QDL_CLK_GPMI_APB] = imx_clk_hw_gate2("gpmi_apb", "usdhc3", base + 0x78, 30); |
869 | clk[IMX6QDL_CLK_ROM] = imx_clk_gate2_flags("rom", "ahb", base + 0x7c, 0, CLK_IS_CRITICAL); | 873 | hws[IMX6QDL_CLK_ROM] = imx_clk_hw_gate2_flags("rom", "ahb", base + 0x7c, 0, CLK_IS_CRITICAL); |
870 | clk[IMX6QDL_CLK_SATA] = imx_clk_gate2("sata", "ahb", base + 0x7c, 4); | 874 | hws[IMX6QDL_CLK_SATA] = imx_clk_hw_gate2("sata", "ahb", base + 0x7c, 4); |
871 | clk[IMX6QDL_CLK_SDMA] = imx_clk_gate2("sdma", "ahb", base + 0x7c, 6); | 875 | hws[IMX6QDL_CLK_SDMA] = imx_clk_hw_gate2("sdma", "ahb", base + 0x7c, 6); |
872 | clk[IMX6QDL_CLK_SPBA] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12); | 876 | hws[IMX6QDL_CLK_SPBA] = imx_clk_hw_gate2("spba", "ipg", base + 0x7c, 12); |
873 | clk[IMX6QDL_CLK_SPDIF] = imx_clk_gate2_shared("spdif", "spdif_podf", base + 0x7c, 14, &share_count_spdif); | 877 | hws[IMX6QDL_CLK_SPDIF] = imx_clk_hw_gate2_shared("spdif", "spdif_podf", base + 0x7c, 14, &share_count_spdif); |
874 | clk[IMX6QDL_CLK_SPDIF_GCLK] = imx_clk_gate2_shared("spdif_gclk", "ipg", base + 0x7c, 14, &share_count_spdif); | 878 | hws[IMX6QDL_CLK_SPDIF_GCLK] = imx_clk_hw_gate2_shared("spdif_gclk", "ipg", base + 0x7c, 14, &share_count_spdif); |
875 | clk[IMX6QDL_CLK_SSI1_IPG] = imx_clk_gate2_shared("ssi1_ipg", "ipg", base + 0x7c, 18, &share_count_ssi1); | 879 | hws[IMX6QDL_CLK_SSI1_IPG] = imx_clk_hw_gate2_shared("ssi1_ipg", "ipg", base + 0x7c, 18, &share_count_ssi1); |
876 | clk[IMX6QDL_CLK_SSI2_IPG] = imx_clk_gate2_shared("ssi2_ipg", "ipg", base + 0x7c, 20, &share_count_ssi2); | 880 | hws[IMX6QDL_CLK_SSI2_IPG] = imx_clk_hw_gate2_shared("ssi2_ipg", "ipg", base + 0x7c, 20, &share_count_ssi2); |
877 | clk[IMX6QDL_CLK_SSI3_IPG] = imx_clk_gate2_shared("ssi3_ipg", "ipg", base + 0x7c, 22, &share_count_ssi3); | 881 | hws[IMX6QDL_CLK_SSI3_IPG] = imx_clk_hw_gate2_shared("ssi3_ipg", "ipg", base + 0x7c, 22, &share_count_ssi3); |
878 | clk[IMX6QDL_CLK_SSI1] = imx_clk_gate2_shared("ssi1", "ssi1_podf", base + 0x7c, 18, &share_count_ssi1); | 882 | hws[IMX6QDL_CLK_SSI1] = imx_clk_hw_gate2_shared("ssi1", "ssi1_podf", base + 0x7c, 18, &share_count_ssi1); |
879 | clk[IMX6QDL_CLK_SSI2] = imx_clk_gate2_shared("ssi2", "ssi2_podf", base + 0x7c, 20, &share_count_ssi2); | 883 | hws[IMX6QDL_CLK_SSI2] = imx_clk_hw_gate2_shared("ssi2", "ssi2_podf", base + 0x7c, 20, &share_count_ssi2); |
880 | clk[IMX6QDL_CLK_SSI3] = imx_clk_gate2_shared("ssi3", "ssi3_podf", base + 0x7c, 22, &share_count_ssi3); | 884 | hws[IMX6QDL_CLK_SSI3] = imx_clk_hw_gate2_shared("ssi3", "ssi3_podf", base + 0x7c, 22, &share_count_ssi3); |
881 | clk[IMX6QDL_CLK_UART_IPG] = imx_clk_gate2("uart_ipg", "ipg", base + 0x7c, 24); | 885 | hws[IMX6QDL_CLK_UART_IPG] = imx_clk_hw_gate2("uart_ipg", "ipg", base + 0x7c, 24); |
882 | clk[IMX6QDL_CLK_UART_SERIAL] = imx_clk_gate2("uart_serial", "uart_serial_podf", base + 0x7c, 26); | 886 | hws[IMX6QDL_CLK_UART_SERIAL] = imx_clk_hw_gate2("uart_serial", "uart_serial_podf", base + 0x7c, 26); |
883 | clk[IMX6QDL_CLK_USBOH3] = imx_clk_gate2("usboh3", "ipg", base + 0x80, 0); | 887 | hws[IMX6QDL_CLK_USBOH3] = imx_clk_hw_gate2("usboh3", "ipg", base + 0x80, 0); |
884 | clk[IMX6QDL_CLK_USDHC1] = imx_clk_gate2("usdhc1", "usdhc1_podf", base + 0x80, 2); | 888 | hws[IMX6QDL_CLK_USDHC1] = imx_clk_hw_gate2("usdhc1", "usdhc1_podf", base + 0x80, 2); |
885 | clk[IMX6QDL_CLK_USDHC2] = imx_clk_gate2("usdhc2", "usdhc2_podf", base + 0x80, 4); | 889 | hws[IMX6QDL_CLK_USDHC2] = imx_clk_hw_gate2("usdhc2", "usdhc2_podf", base + 0x80, 4); |
886 | clk[IMX6QDL_CLK_USDHC3] = imx_clk_gate2("usdhc3", "usdhc3_podf", base + 0x80, 6); | 890 | hws[IMX6QDL_CLK_USDHC3] = imx_clk_hw_gate2("usdhc3", "usdhc3_podf", base + 0x80, 6); |
887 | clk[IMX6QDL_CLK_USDHC4] = imx_clk_gate2("usdhc4", "usdhc4_podf", base + 0x80, 8); | 891 | hws[IMX6QDL_CLK_USDHC4] = imx_clk_hw_gate2("usdhc4", "usdhc4_podf", base + 0x80, 8); |
888 | clk[IMX6QDL_CLK_EIM_SLOW] = imx_clk_gate2("eim_slow", "eim_slow_podf", base + 0x80, 10); | 892 | hws[IMX6QDL_CLK_EIM_SLOW] = imx_clk_hw_gate2("eim_slow", "eim_slow_podf", base + 0x80, 10); |
889 | clk[IMX6QDL_CLK_VDO_AXI] = imx_clk_gate2("vdo_axi", "vdo_axi_sel", base + 0x80, 12); | 893 | hws[IMX6QDL_CLK_VDO_AXI] = imx_clk_hw_gate2("vdo_axi", "vdo_axi_sel", base + 0x80, 12); |
890 | clk[IMX6QDL_CLK_VPU_AXI] = imx_clk_gate2("vpu_axi", "vpu_axi_podf", base + 0x80, 14); | 894 | hws[IMX6QDL_CLK_VPU_AXI] = imx_clk_hw_gate2("vpu_axi", "vpu_axi_podf", base + 0x80, 14); |
891 | if (clk_on_imx6qp()) { | 895 | if (clk_on_imx6qp()) { |
892 | clk[IMX6QDL_CLK_PRE0] = imx_clk_gate2("pre0", "pre_axi", base + 0x80, 16); | 896 | hws[IMX6QDL_CLK_PRE0] = imx_clk_hw_gate2("pre0", "pre_axi", base + 0x80, 16); |
893 | clk[IMX6QDL_CLK_PRE1] = imx_clk_gate2("pre1", "pre_axi", base + 0x80, 18); | 897 | hws[IMX6QDL_CLK_PRE1] = imx_clk_hw_gate2("pre1", "pre_axi", base + 0x80, 18); |
894 | clk[IMX6QDL_CLK_PRE2] = imx_clk_gate2("pre2", "pre_axi", base + 0x80, 20); | 898 | hws[IMX6QDL_CLK_PRE2] = imx_clk_hw_gate2("pre2", "pre_axi", base + 0x80, 20); |
895 | clk[IMX6QDL_CLK_PRE3] = imx_clk_gate2("pre3", "pre_axi", base + 0x80, 22); | 899 | hws[IMX6QDL_CLK_PRE3] = imx_clk_hw_gate2("pre3", "pre_axi", base + 0x80, 22); |
896 | clk[IMX6QDL_CLK_PRG0_AXI] = imx_clk_gate2_shared("prg0_axi", "ipu1_podf", base + 0x80, 24, &share_count_prg0); | 900 | hws[IMX6QDL_CLK_PRG0_AXI] = imx_clk_hw_gate2_shared("prg0_axi", "ipu1_podf", base + 0x80, 24, &share_count_prg0); |
897 | clk[IMX6QDL_CLK_PRG1_AXI] = imx_clk_gate2_shared("prg1_axi", "ipu2_podf", base + 0x80, 26, &share_count_prg1); | 901 | hws[IMX6QDL_CLK_PRG1_AXI] = imx_clk_hw_gate2_shared("prg1_axi", "ipu2_podf", base + 0x80, 26, &share_count_prg1); |
898 | clk[IMX6QDL_CLK_PRG0_APB] = imx_clk_gate2_shared("prg0_apb", "ipg", base + 0x80, 24, &share_count_prg0); | 902 | hws[IMX6QDL_CLK_PRG0_APB] = imx_clk_hw_gate2_shared("prg0_apb", "ipg", base + 0x80, 24, &share_count_prg0); |
899 | clk[IMX6QDL_CLK_PRG1_APB] = imx_clk_gate2_shared("prg1_apb", "ipg", base + 0x80, 26, &share_count_prg1); | 903 | hws[IMX6QDL_CLK_PRG1_APB] = imx_clk_hw_gate2_shared("prg1_apb", "ipg", base + 0x80, 26, &share_count_prg1); |
900 | } | 904 | } |
901 | clk[IMX6QDL_CLK_CKO1] = imx_clk_gate("cko1", "cko1_podf", base + 0x60, 7); | 905 | hws[IMX6QDL_CLK_CKO1] = imx_clk_hw_gate("cko1", "cko1_podf", base + 0x60, 7); |
902 | clk[IMX6QDL_CLK_CKO2] = imx_clk_gate("cko2", "cko2_podf", base + 0x60, 24); | 906 | hws[IMX6QDL_CLK_CKO2] = imx_clk_hw_gate("cko2", "cko2_podf", base + 0x60, 24); |
903 | 907 | ||
904 | /* | 908 | /* |
905 | * The gpt_3m clock is not available on i.MX6Q TO1.0. Let's point it | 909 | * The gpt_3m clock is not available on i.MX6Q TO1.0. Let's point it |
906 | * to clock gpt_ipg_per to ease the gpt driver code. | 910 | * to clock gpt_ipg_per to ease the gpt driver code. |
907 | */ | 911 | */ |
908 | if (clk_on_imx6q() && imx_get_soc_revision() == IMX_CHIP_REVISION_1_0) | 912 | if (clk_on_imx6q() && imx_get_soc_revision() == IMX_CHIP_REVISION_1_0) |
909 | clk[IMX6QDL_CLK_GPT_3M] = clk[IMX6QDL_CLK_GPT_IPG_PER]; | 913 | hws[IMX6QDL_CLK_GPT_3M] = hws[IMX6QDL_CLK_GPT_IPG_PER]; |
910 | 914 | ||
911 | imx_check_clocks(clk, ARRAY_SIZE(clk)); | 915 | imx_check_clk_hws(hws, IMX6QDL_CLK_END); |
912 | 916 | ||
913 | clk_data.clks = clk; | 917 | of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data); |
914 | clk_data.clk_num = ARRAY_SIZE(clk); | ||
915 | of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); | ||
916 | 918 | ||
917 | clk_register_clkdev(clk[IMX6QDL_CLK_ENET_REF], "enet_ref", NULL); | 919 | clk_hw_register_clkdev(hws[IMX6QDL_CLK_ENET_REF], "enet_ref", NULL); |
918 | 920 | ||
919 | clk_set_rate(clk[IMX6QDL_CLK_PLL3_PFD1_540M], 540000000); | 921 | clk_set_rate(hws[IMX6QDL_CLK_PLL3_PFD1_540M]->clk, 540000000); |
920 | if (clk_on_imx6dl()) | 922 | if (clk_on_imx6dl()) |
921 | clk_set_parent(clk[IMX6QDL_CLK_IPU1_SEL], clk[IMX6QDL_CLK_PLL3_PFD1_540M]); | 923 | clk_set_parent(hws[IMX6QDL_CLK_IPU1_SEL]->clk, hws[IMX6QDL_CLK_PLL3_PFD1_540M]->clk); |
922 | 924 | ||
923 | clk_set_parent(clk[IMX6QDL_CLK_IPU1_DI0_PRE_SEL], clk[IMX6QDL_CLK_PLL5_VIDEO_DIV]); | 925 | clk_set_parent(hws[IMX6QDL_CLK_IPU1_DI0_PRE_SEL]->clk, hws[IMX6QDL_CLK_PLL5_VIDEO_DIV]->clk); |
924 | clk_set_parent(clk[IMX6QDL_CLK_IPU1_DI1_PRE_SEL], clk[IMX6QDL_CLK_PLL5_VIDEO_DIV]); | 926 | clk_set_parent(hws[IMX6QDL_CLK_IPU1_DI1_PRE_SEL]->clk, hws[IMX6QDL_CLK_PLL5_VIDEO_DIV]->clk); |
925 | clk_set_parent(clk[IMX6QDL_CLK_IPU2_DI0_PRE_SEL], clk[IMX6QDL_CLK_PLL5_VIDEO_DIV]); | 927 | clk_set_parent(hws[IMX6QDL_CLK_IPU2_DI0_PRE_SEL]->clk, hws[IMX6QDL_CLK_PLL5_VIDEO_DIV]->clk); |
926 | clk_set_parent(clk[IMX6QDL_CLK_IPU2_DI1_PRE_SEL], clk[IMX6QDL_CLK_PLL5_VIDEO_DIV]); | 928 | clk_set_parent(hws[IMX6QDL_CLK_IPU2_DI1_PRE_SEL]->clk, hws[IMX6QDL_CLK_PLL5_VIDEO_DIV]->clk); |
927 | clk_set_parent(clk[IMX6QDL_CLK_IPU1_DI0_SEL], clk[IMX6QDL_CLK_IPU1_DI0_PRE]); | 929 | clk_set_parent(hws[IMX6QDL_CLK_IPU1_DI0_SEL]->clk, hws[IMX6QDL_CLK_IPU1_DI0_PRE]->clk); |
928 | clk_set_parent(clk[IMX6QDL_CLK_IPU1_DI1_SEL], clk[IMX6QDL_CLK_IPU1_DI1_PRE]); | 930 | clk_set_parent(hws[IMX6QDL_CLK_IPU1_DI1_SEL]->clk, hws[IMX6QDL_CLK_IPU1_DI1_PRE]->clk); |
929 | clk_set_parent(clk[IMX6QDL_CLK_IPU2_DI0_SEL], clk[IMX6QDL_CLK_IPU2_DI0_PRE]); | 931 | clk_set_parent(hws[IMX6QDL_CLK_IPU2_DI0_SEL]->clk, hws[IMX6QDL_CLK_IPU2_DI0_PRE]->clk); |
930 | clk_set_parent(clk[IMX6QDL_CLK_IPU2_DI1_SEL], clk[IMX6QDL_CLK_IPU2_DI1_PRE]); | 932 | clk_set_parent(hws[IMX6QDL_CLK_IPU2_DI1_SEL]->clk, hws[IMX6QDL_CLK_IPU2_DI1_PRE]->clk); |
931 | 933 | ||
932 | /* | 934 | /* |
933 | * The gpmi needs 100MHz frequency in the EDO/Sync mode, | 935 | * The gpmi needs 100MHz frequency in the EDO/Sync mode, |
934 | * We can not get the 100MHz from the pll2_pfd0_352m. | 936 | * We can not get the 100MHz from the pll2_pfd0_352m. |
935 | * So choose pll2_pfd2_396m as enfc_sel's parent. | 937 | * So choose pll2_pfd2_396m as enfc_sel's parent. |
936 | */ | 938 | */ |
937 | clk_set_parent(clk[IMX6QDL_CLK_ENFC_SEL], clk[IMX6QDL_CLK_PLL2_PFD2_396M]); | 939 | clk_set_parent(hws[IMX6QDL_CLK_ENFC_SEL]->clk, hws[IMX6QDL_CLK_PLL2_PFD2_396M]->clk); |
938 | 940 | ||
939 | if (IS_ENABLED(CONFIG_USB_MXS_PHY)) { | 941 | if (IS_ENABLED(CONFIG_USB_MXS_PHY)) { |
940 | clk_prepare_enable(clk[IMX6QDL_CLK_USBPHY1_GATE]); | 942 | clk_prepare_enable(hws[IMX6QDL_CLK_USBPHY1_GATE]->clk); |
941 | clk_prepare_enable(clk[IMX6QDL_CLK_USBPHY2_GATE]); | 943 | clk_prepare_enable(hws[IMX6QDL_CLK_USBPHY2_GATE]->clk); |
942 | } | 944 | } |
943 | 945 | ||
944 | /* | 946 | /* |
945 | * Let's initially set up CLKO with OSC24M, since this configuration | 947 | * Let's initially set up CLKO with OSC24M, since this configuration |
946 | * is widely used by imx6q board designs to clock audio codec. | 948 | * is widely used by imx6q board designs to clock audio codec. |
947 | */ | 949 | */ |
948 | ret = clk_set_parent(clk[IMX6QDL_CLK_CKO2_SEL], clk[IMX6QDL_CLK_OSC]); | 950 | ret = clk_set_parent(hws[IMX6QDL_CLK_CKO2_SEL]->clk, hws[IMX6QDL_CLK_OSC]->clk); |
949 | if (!ret) | 951 | if (!ret) |
950 | ret = clk_set_parent(clk[IMX6QDL_CLK_CKO], clk[IMX6QDL_CLK_CKO2]); | 952 | ret = clk_set_parent(hws[IMX6QDL_CLK_CKO]->clk, hws[IMX6QDL_CLK_CKO2]->clk); |
951 | if (ret) | 953 | if (ret) |
952 | pr_warn("failed to set up CLKO: %d\n", ret); | 954 | pr_warn("failed to set up CLKO: %d\n", ret); |
953 | 955 | ||
954 | /* Audio-related clocks configuration */ | 956 | /* Audio-related clocks configuration */ |
955 | clk_set_parent(clk[IMX6QDL_CLK_SPDIF_SEL], clk[IMX6QDL_CLK_PLL3_PFD3_454M]); | 957 | clk_set_parent(hws[IMX6QDL_CLK_SPDIF_SEL]->clk, hws[IMX6QDL_CLK_PLL3_PFD3_454M]->clk); |
956 | 958 | ||
957 | /* All existing boards with PCIe use LVDS1 */ | 959 | /* All existing boards with PCIe use LVDS1 */ |
958 | if (IS_ENABLED(CONFIG_PCI_IMX6)) | 960 | if (IS_ENABLED(CONFIG_PCI_IMX6)) |
959 | clk_set_parent(clk[IMX6QDL_CLK_LVDS1_SEL], clk[IMX6QDL_CLK_SATA_REF_100M]); | 961 | clk_set_parent(hws[IMX6QDL_CLK_LVDS1_SEL]->clk, hws[IMX6QDL_CLK_SATA_REF_100M]->clk); |
960 | 962 | ||
961 | /* | 963 | /* |
962 | * Initialize the GPU clock muxes, so that the maximum specified clock | 964 | * Initialize the GPU clock muxes, so that the maximum specified clock |
963 | * rates for the respective SoC are not exceeded. | 965 | * rates for the respective SoC are not exceeded. |
964 | */ | 966 | */ |
965 | if (clk_on_imx6dl()) { | 967 | if (clk_on_imx6dl()) { |
966 | clk_set_parent(clk[IMX6QDL_CLK_GPU3D_CORE_SEL], | 968 | clk_set_parent(hws[IMX6QDL_CLK_GPU3D_CORE_SEL]->clk, |
967 | clk[IMX6QDL_CLK_PLL2_PFD1_594M]); | 969 | hws[IMX6QDL_CLK_PLL2_PFD1_594M]->clk); |
968 | clk_set_parent(clk[IMX6QDL_CLK_GPU2D_CORE_SEL], | 970 | clk_set_parent(hws[IMX6QDL_CLK_GPU2D_CORE_SEL]->clk, |
969 | clk[IMX6QDL_CLK_PLL2_PFD1_594M]); | 971 | hws[IMX6QDL_CLK_PLL2_PFD1_594M]->clk); |
970 | } else if (clk_on_imx6q()) { | 972 | } else if (clk_on_imx6q()) { |
971 | clk_set_parent(clk[IMX6QDL_CLK_GPU3D_CORE_SEL], | 973 | clk_set_parent(hws[IMX6QDL_CLK_GPU3D_CORE_SEL]->clk, |
972 | clk[IMX6QDL_CLK_MMDC_CH0_AXI]); | 974 | hws[IMX6QDL_CLK_MMDC_CH0_AXI]->clk); |
973 | clk_set_parent(clk[IMX6QDL_CLK_GPU3D_SHADER_SEL], | 975 | clk_set_parent(hws[IMX6QDL_CLK_GPU3D_SHADER_SEL]->clk, |
974 | clk[IMX6QDL_CLK_PLL2_PFD1_594M]); | 976 | hws[IMX6QDL_CLK_PLL2_PFD1_594M]->clk); |
975 | clk_set_parent(clk[IMX6QDL_CLK_GPU2D_CORE_SEL], | 977 | clk_set_parent(hws[IMX6QDL_CLK_GPU2D_CORE_SEL]->clk, |
976 | clk[IMX6QDL_CLK_PLL3_USB_OTG]); | 978 | hws[IMX6QDL_CLK_PLL3_USB_OTG]->clk); |
979 | } | ||
980 | |||
981 | for (i = 0; i < ARRAY_SIZE(uart_clk_ids); i++) { | ||
982 | int index = uart_clk_ids[i]; | ||
983 | |||
984 | uart_clks[i] = &hws[index]->clk; | ||
977 | } | 985 | } |
978 | 986 | ||
979 | imx_register_uart_clocks(uart_clks); | 987 | imx_register_uart_clocks(uart_clks); |
diff --git a/drivers/clk/imx/clk-imx6sl.c b/drivers/clk/imx/clk-imx6sl.c index f9f1f8a95d92..4bd44d89eaaa 100644 --- a/drivers/clk/imx/clk-imx6sl.c +++ b/drivers/clk/imx/clk-imx6sl.c | |||
@@ -13,8 +13,6 @@ | |||
13 | 13 | ||
14 | #include "clk.h" | 14 | #include "clk.h" |
15 | 15 | ||
16 | #define CCDR 0x4 | ||
17 | #define BM_CCM_CCDR_MMDC_CH0_MASK (1 << 17) | ||
18 | #define CCSR 0xc | 16 | #define CCSR 0xc |
19 | #define BM_CCSR_PLL1_SW_CLK_SEL (1 << 2) | 17 | #define BM_CCSR_PLL1_SW_CLK_SEL (1 << 2) |
20 | #define CACRR 0x10 | 18 | #define CACRR 0x10 |
@@ -97,8 +95,8 @@ static unsigned int share_count_ssi2; | |||
97 | static unsigned int share_count_ssi3; | 95 | static unsigned int share_count_ssi3; |
98 | static unsigned int share_count_spdif; | 96 | static unsigned int share_count_spdif; |
99 | 97 | ||
100 | static struct clk *clks[IMX6SL_CLK_END]; | 98 | static struct clk_hw **hws; |
101 | static struct clk_onecell_data clk_data; | 99 | static struct clk_hw_onecell_data *clk_hw_data; |
102 | static void __iomem *ccm_base; | 100 | static void __iomem *ccm_base; |
103 | static void __iomem *anatop_base; | 101 | static void __iomem *anatop_base; |
104 | 102 | ||
@@ -179,74 +177,84 @@ void imx6sl_set_wait_clk(bool enter) | |||
179 | imx6sl_enable_pll_arm(false); | 177 | imx6sl_enable_pll_arm(false); |
180 | } | 178 | } |
181 | 179 | ||
182 | static struct clk ** const uart_clks[] __initconst = { | 180 | static const int uart_clk_ids[] __initconst = { |
183 | &clks[IMX6SL_CLK_UART], | 181 | IMX6SL_CLK_UART, |
184 | &clks[IMX6SL_CLK_UART_SERIAL], | 182 | IMX6SL_CLK_UART_SERIAL, |
185 | NULL | ||
186 | }; | 183 | }; |
187 | 184 | ||
185 | static struct clk **uart_clks[ARRAY_SIZE(uart_clk_ids) + 1] __initdata; | ||
186 | |||
188 | static void __init imx6sl_clocks_init(struct device_node *ccm_node) | 187 | static void __init imx6sl_clocks_init(struct device_node *ccm_node) |
189 | { | 188 | { |
190 | struct device_node *np; | 189 | struct device_node *np; |
191 | void __iomem *base; | 190 | void __iomem *base; |
192 | int ret; | 191 | int ret; |
192 | int i; | ||
193 | |||
194 | clk_hw_data = kzalloc(struct_size(clk_hw_data, hws, | ||
195 | IMX6SL_CLK_END), GFP_KERNEL); | ||
196 | if (WARN_ON(!clk_hw_data)) | ||
197 | return; | ||
198 | |||
199 | clk_hw_data->num = IMX6SL_CLK_END; | ||
200 | hws = clk_hw_data->hws; | ||
193 | 201 | ||
194 | clks[IMX6SL_CLK_DUMMY] = imx_clk_fixed("dummy", 0); | 202 | hws[IMX6SL_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0); |
195 | clks[IMX6SL_CLK_CKIL] = imx_obtain_fixed_clock("ckil", 0); | 203 | hws[IMX6SL_CLK_CKIL] = imx_obtain_fixed_clock_hw("ckil", 0); |
196 | clks[IMX6SL_CLK_OSC] = imx_obtain_fixed_clock("osc", 0); | 204 | hws[IMX6SL_CLK_OSC] = imx_obtain_fixed_clock_hw("osc", 0); |
197 | /* Clock source from external clock via CLK1 PAD */ | 205 | /* Clock source from external clock via CLK1 PAD */ |
198 | clks[IMX6SL_CLK_ANACLK1] = imx_obtain_fixed_clock("anaclk1", 0); | 206 | hws[IMX6SL_CLK_ANACLK1] = imx_obtain_fixed_clock_hw("anaclk1", 0); |
199 | 207 | ||
200 | np = of_find_compatible_node(NULL, NULL, "fsl,imx6sl-anatop"); | 208 | np = of_find_compatible_node(NULL, NULL, "fsl,imx6sl-anatop"); |
201 | base = of_iomap(np, 0); | 209 | base = of_iomap(np, 0); |
202 | WARN_ON(!base); | 210 | WARN_ON(!base); |
203 | anatop_base = base; | 211 | anatop_base = base; |
204 | 212 | ||
205 | clks[IMX6SL_PLL1_BYPASS_SRC] = imx_clk_mux("pll1_bypass_src", base + 0x00, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); | 213 | hws[IMX6SL_PLL1_BYPASS_SRC] = imx_clk_hw_mux("pll1_bypass_src", base + 0x00, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); |
206 | clks[IMX6SL_PLL2_BYPASS_SRC] = imx_clk_mux("pll2_bypass_src", base + 0x30, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); | 214 | hws[IMX6SL_PLL2_BYPASS_SRC] = imx_clk_hw_mux("pll2_bypass_src", base + 0x30, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); |
207 | clks[IMX6SL_PLL3_BYPASS_SRC] = imx_clk_mux("pll3_bypass_src", base + 0x10, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); | 215 | hws[IMX6SL_PLL3_BYPASS_SRC] = imx_clk_hw_mux("pll3_bypass_src", base + 0x10, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); |
208 | clks[IMX6SL_PLL4_BYPASS_SRC] = imx_clk_mux("pll4_bypass_src", base + 0x70, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); | 216 | hws[IMX6SL_PLL4_BYPASS_SRC] = imx_clk_hw_mux("pll4_bypass_src", base + 0x70, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); |
209 | clks[IMX6SL_PLL5_BYPASS_SRC] = imx_clk_mux("pll5_bypass_src", base + 0xa0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); | 217 | hws[IMX6SL_PLL5_BYPASS_SRC] = imx_clk_hw_mux("pll5_bypass_src", base + 0xa0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); |
210 | clks[IMX6SL_PLL6_BYPASS_SRC] = imx_clk_mux("pll6_bypass_src", base + 0xe0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); | 218 | hws[IMX6SL_PLL6_BYPASS_SRC] = imx_clk_hw_mux("pll6_bypass_src", base + 0xe0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); |
211 | clks[IMX6SL_PLL7_BYPASS_SRC] = imx_clk_mux("pll7_bypass_src", base + 0x20, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); | 219 | hws[IMX6SL_PLL7_BYPASS_SRC] = imx_clk_hw_mux("pll7_bypass_src", base + 0x20, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); |
212 | 220 | ||
213 | /* type name parent_name base div_mask */ | 221 | /* type name parent_name base div_mask */ |
214 | clks[IMX6SL_CLK_PLL1] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1", "osc", base + 0x00, 0x7f); | 222 | hws[IMX6SL_CLK_PLL1] = imx_clk_hw_pllv3(IMX_PLLV3_SYS, "pll1", "osc", base + 0x00, 0x7f); |
215 | clks[IMX6SL_CLK_PLL2] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2", "osc", base + 0x30, 0x1); | 223 | hws[IMX6SL_CLK_PLL2] = imx_clk_hw_pllv3(IMX_PLLV3_GENERIC, "pll2", "osc", base + 0x30, 0x1); |
216 | clks[IMX6SL_CLK_PLL3] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3", "osc", base + 0x10, 0x3); | 224 | hws[IMX6SL_CLK_PLL3] = imx_clk_hw_pllv3(IMX_PLLV3_USB, "pll3", "osc", base + 0x10, 0x3); |
217 | clks[IMX6SL_CLK_PLL4] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4", "osc", base + 0x70, 0x7f); | 225 | hws[IMX6SL_CLK_PLL4] = imx_clk_hw_pllv3(IMX_PLLV3_AV, "pll4", "osc", base + 0x70, 0x7f); |
218 | clks[IMX6SL_CLK_PLL5] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5", "osc", base + 0xa0, 0x7f); | 226 | hws[IMX6SL_CLK_PLL5] = imx_clk_hw_pllv3(IMX_PLLV3_AV, "pll5", "osc", base + 0xa0, 0x7f); |
219 | clks[IMX6SL_CLK_PLL6] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6", "osc", base + 0xe0, 0x3); | 227 | hws[IMX6SL_CLK_PLL6] = imx_clk_hw_pllv3(IMX_PLLV3_ENET, "pll6", "osc", base + 0xe0, 0x3); |
220 | clks[IMX6SL_CLK_PLL7] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7", "osc", base + 0x20, 0x3); | 228 | hws[IMX6SL_CLK_PLL7] = imx_clk_hw_pllv3(IMX_PLLV3_USB, "pll7", "osc", base + 0x20, 0x3); |
221 | 229 | ||
222 | clks[IMX6SL_PLL1_BYPASS] = imx_clk_mux_flags("pll1_bypass", base + 0x00, 16, 1, pll1_bypass_sels, ARRAY_SIZE(pll1_bypass_sels), CLK_SET_RATE_PARENT); | 230 | hws[IMX6SL_PLL1_BYPASS] = imx_clk_hw_mux_flags("pll1_bypass", base + 0x00, 16, 1, pll1_bypass_sels, ARRAY_SIZE(pll1_bypass_sels), CLK_SET_RATE_PARENT); |
223 | clks[IMX6SL_PLL2_BYPASS] = imx_clk_mux_flags("pll2_bypass", base + 0x30, 16, 1, pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels), CLK_SET_RATE_PARENT); | 231 | hws[IMX6SL_PLL2_BYPASS] = imx_clk_hw_mux_flags("pll2_bypass", base + 0x30, 16, 1, pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels), CLK_SET_RATE_PARENT); |
224 | clks[IMX6SL_PLL3_BYPASS] = imx_clk_mux_flags("pll3_bypass", base + 0x10, 16, 1, pll3_bypass_sels, ARRAY_SIZE(pll3_bypass_sels), CLK_SET_RATE_PARENT); | 232 | hws[IMX6SL_PLL3_BYPASS] = imx_clk_hw_mux_flags("pll3_bypass", base + 0x10, 16, 1, pll3_bypass_sels, ARRAY_SIZE(pll3_bypass_sels), CLK_SET_RATE_PARENT); |
225 | clks[IMX6SL_PLL4_BYPASS] = imx_clk_mux_flags("pll4_bypass", base + 0x70, 16, 1, pll4_bypass_sels, ARRAY_SIZE(pll4_bypass_sels), CLK_SET_RATE_PARENT); | 233 | hws[IMX6SL_PLL4_BYPASS] = imx_clk_hw_mux_flags("pll4_bypass", base + 0x70, 16, 1, pll4_bypass_sels, ARRAY_SIZE(pll4_bypass_sels), CLK_SET_RATE_PARENT); |
226 | clks[IMX6SL_PLL5_BYPASS] = imx_clk_mux_flags("pll5_bypass", base + 0xa0, 16, 1, pll5_bypass_sels, ARRAY_SIZE(pll5_bypass_sels), CLK_SET_RATE_PARENT); | 234 | hws[IMX6SL_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); |
227 | clks[IMX6SL_PLL6_BYPASS] = imx_clk_mux_flags("pll6_bypass", base + 0xe0, 16, 1, pll6_bypass_sels, ARRAY_SIZE(pll6_bypass_sels), CLK_SET_RATE_PARENT); | 235 | hws[IMX6SL_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); |
228 | clks[IMX6SL_PLL7_BYPASS] = imx_clk_mux_flags("pll7_bypass", base + 0x20, 16, 1, pll7_bypass_sels, ARRAY_SIZE(pll7_bypass_sels), CLK_SET_RATE_PARENT); | 236 | hws[IMX6SL_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); |
229 | 237 | ||
230 | /* Do not bypass PLLs initially */ | 238 | /* Do not bypass PLLs initially */ |
231 | clk_set_parent(clks[IMX6SL_PLL1_BYPASS], clks[IMX6SL_CLK_PLL1]); | 239 | clk_set_parent(hws[IMX6SL_PLL1_BYPASS]->clk, hws[IMX6SL_CLK_PLL1]->clk); |
232 | clk_set_parent(clks[IMX6SL_PLL2_BYPASS], clks[IMX6SL_CLK_PLL2]); | 240 | clk_set_parent(hws[IMX6SL_PLL2_BYPASS]->clk, hws[IMX6SL_CLK_PLL2]->clk); |
233 | clk_set_parent(clks[IMX6SL_PLL3_BYPASS], clks[IMX6SL_CLK_PLL3]); | 241 | clk_set_parent(hws[IMX6SL_PLL3_BYPASS]->clk, hws[IMX6SL_CLK_PLL3]->clk); |
234 | clk_set_parent(clks[IMX6SL_PLL4_BYPASS], clks[IMX6SL_CLK_PLL4]); | 242 | clk_set_parent(hws[IMX6SL_PLL4_BYPASS]->clk, hws[IMX6SL_CLK_PLL4]->clk); |
235 | clk_set_parent(clks[IMX6SL_PLL5_BYPASS], clks[IMX6SL_CLK_PLL5]); | 243 | clk_set_parent(hws[IMX6SL_PLL5_BYPASS]->clk, hws[IMX6SL_CLK_PLL5]->clk); |
236 | clk_set_parent(clks[IMX6SL_PLL6_BYPASS], clks[IMX6SL_CLK_PLL6]); | 244 | clk_set_parent(hws[IMX6SL_PLL6_BYPASS]->clk, hws[IMX6SL_CLK_PLL6]->clk); |
237 | clk_set_parent(clks[IMX6SL_PLL7_BYPASS], clks[IMX6SL_CLK_PLL7]); | 245 | clk_set_parent(hws[IMX6SL_PLL7_BYPASS]->clk, hws[IMX6SL_CLK_PLL7]->clk); |
238 | 246 | ||
239 | clks[IMX6SL_CLK_PLL1_SYS] = imx_clk_gate("pll1_sys", "pll1_bypass", base + 0x00, 13); | 247 | hws[IMX6SL_CLK_PLL1_SYS] = imx_clk_hw_gate("pll1_sys", "pll1_bypass", base + 0x00, 13); |
240 | clks[IMX6SL_CLK_PLL2_BUS] = imx_clk_gate("pll2_bus", "pll2_bypass", base + 0x30, 13); | 248 | hws[IMX6SL_CLK_PLL2_BUS] = imx_clk_hw_gate("pll2_bus", "pll2_bypass", base + 0x30, 13); |
241 | clks[IMX6SL_CLK_PLL3_USB_OTG] = imx_clk_gate("pll3_usb_otg", "pll3_bypass", base + 0x10, 13); | 249 | hws[IMX6SL_CLK_PLL3_USB_OTG] = imx_clk_hw_gate("pll3_usb_otg", "pll3_bypass", base + 0x10, 13); |
242 | clks[IMX6SL_CLK_PLL4_AUDIO] = imx_clk_gate("pll4_audio", "pll4_bypass", base + 0x70, 13); | 250 | hws[IMX6SL_CLK_PLL4_AUDIO] = imx_clk_hw_gate("pll4_audio", "pll4_bypass", base + 0x70, 13); |
243 | clks[IMX6SL_CLK_PLL5_VIDEO] = imx_clk_gate("pll5_video", "pll5_bypass", base + 0xa0, 13); | 251 | hws[IMX6SL_CLK_PLL5_VIDEO] = imx_clk_hw_gate("pll5_video", "pll5_bypass", base + 0xa0, 13); |
244 | clks[IMX6SL_CLK_PLL6_ENET] = imx_clk_gate("pll6_enet", "pll6_bypass", base + 0xe0, 13); | 252 | hws[IMX6SL_CLK_PLL6_ENET] = imx_clk_hw_gate("pll6_enet", "pll6_bypass", base + 0xe0, 13); |
245 | clks[IMX6SL_CLK_PLL7_USB_HOST] = imx_clk_gate("pll7_usb_host", "pll7_bypass", base + 0x20, 13); | 253 | hws[IMX6SL_CLK_PLL7_USB_HOST] = imx_clk_hw_gate("pll7_usb_host", "pll7_bypass", base + 0x20, 13); |
246 | 254 | ||
247 | clks[IMX6SL_CLK_LVDS1_SEL] = imx_clk_mux("lvds1_sel", base + 0x160, 0, 5, lvds_sels, ARRAY_SIZE(lvds_sels)); | 255 | hws[IMX6SL_CLK_LVDS1_SEL] = imx_clk_hw_mux("lvds1_sel", base + 0x160, 0, 5, lvds_sels, ARRAY_SIZE(lvds_sels)); |
248 | clks[IMX6SL_CLK_LVDS1_OUT] = imx_clk_gate_exclusive("lvds1_out", "lvds1_sel", base + 0x160, 10, BIT(12)); | 256 | hws[IMX6SL_CLK_LVDS1_OUT] = imx_clk_hw_gate_exclusive("lvds1_out", "lvds1_sel", base + 0x160, 10, BIT(12)); |
249 | clks[IMX6SL_CLK_LVDS1_IN] = imx_clk_gate_exclusive("lvds1_in", "anaclk1", base + 0x160, 12, BIT(10)); | 257 | hws[IMX6SL_CLK_LVDS1_IN] = imx_clk_hw_gate_exclusive("lvds1_in", "anaclk1", base + 0x160, 12, BIT(10)); |
250 | 258 | ||
251 | /* | 259 | /* |
252 | * usbphy1 and usbphy2 are implemented as dummy gates using reserve | 260 | * usbphy1 and usbphy2 are implemented as dummy gates using reserve |
@@ -255,32 +263,32 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node) | |||
255 | * turned on during boot, and software will not need to control it | 263 | * turned on during boot, and software will not need to control it |
256 | * anymore after that. | 264 | * anymore after that. |
257 | */ | 265 | */ |
258 | clks[IMX6SL_CLK_USBPHY1] = imx_clk_gate("usbphy1", "pll3_usb_otg", base + 0x10, 20); | 266 | hws[IMX6SL_CLK_USBPHY1] = imx_clk_hw_gate("usbphy1", "pll3_usb_otg", base + 0x10, 20); |
259 | clks[IMX6SL_CLK_USBPHY2] = imx_clk_gate("usbphy2", "pll7_usb_host", base + 0x20, 20); | 267 | hws[IMX6SL_CLK_USBPHY2] = imx_clk_hw_gate("usbphy2", "pll7_usb_host", base + 0x20, 20); |
260 | clks[IMX6SL_CLK_USBPHY1_GATE] = imx_clk_gate("usbphy1_gate", "dummy", base + 0x10, 6); | 268 | hws[IMX6SL_CLK_USBPHY1_GATE] = imx_clk_hw_gate("usbphy1_gate", "dummy", base + 0x10, 6); |
261 | clks[IMX6SL_CLK_USBPHY2_GATE] = imx_clk_gate("usbphy2_gate", "dummy", base + 0x20, 6); | 269 | hws[IMX6SL_CLK_USBPHY2_GATE] = imx_clk_hw_gate("usbphy2_gate", "dummy", base + 0x20, 6); |
262 | 270 | ||
263 | /* dev name parent_name flags reg shift width div: flags, div_table lock */ | 271 | /* dev name parent_name flags reg shift width div: flags, div_table lock */ |
264 | clks[IMX6SL_CLK_PLL4_POST_DIV] = clk_register_divider_table(NULL, "pll4_post_div", "pll4_audio", CLK_SET_RATE_PARENT, base + 0x70, 19, 2, 0, post_div_table, &imx_ccm_lock); | 272 | hws[IMX6SL_CLK_PLL4_POST_DIV] = clk_hw_register_divider_table(NULL, "pll4_post_div", "pll4_audio", CLK_SET_RATE_PARENT, base + 0x70, 19, 2, 0, post_div_table, &imx_ccm_lock); |
265 | clks[IMX6SL_CLK_PLL4_AUDIO_DIV] = clk_register_divider(NULL, "pll4_audio_div", "pll4_post_div", CLK_SET_RATE_PARENT, base + 0x170, 15, 1, 0, &imx_ccm_lock); | 273 | hws[IMX6SL_CLK_PLL4_AUDIO_DIV] = clk_hw_register_divider(NULL, "pll4_audio_div", "pll4_post_div", CLK_SET_RATE_PARENT, base + 0x170, 15, 1, 0, &imx_ccm_lock); |
266 | clks[IMX6SL_CLK_PLL5_POST_DIV] = clk_register_divider_table(NULL, "pll5_post_div", "pll5_video", CLK_SET_RATE_PARENT, base + 0xa0, 19, 2, 0, post_div_table, &imx_ccm_lock); | 274 | hws[IMX6SL_CLK_PLL5_POST_DIV] = clk_hw_register_divider_table(NULL, "pll5_post_div", "pll5_video", CLK_SET_RATE_PARENT, base + 0xa0, 19, 2, 0, post_div_table, &imx_ccm_lock); |
267 | clks[IMX6SL_CLK_PLL5_VIDEO_DIV] = clk_register_divider_table(NULL, "pll5_video_div", "pll5_post_div", CLK_SET_RATE_PARENT, base + 0x170, 30, 2, 0, video_div_table, &imx_ccm_lock); | 275 | hws[IMX6SL_CLK_PLL5_VIDEO_DIV] = clk_hw_register_divider_table(NULL, "pll5_video_div", "pll5_post_div", CLK_SET_RATE_PARENT, base + 0x170, 30, 2, 0, video_div_table, &imx_ccm_lock); |
268 | clks[IMX6SL_CLK_ENET_REF] = clk_register_divider_table(NULL, "enet_ref", "pll6_enet", 0, base + 0xe0, 0, 2, 0, clk_enet_ref_table, &imx_ccm_lock); | 276 | hws[IMX6SL_CLK_ENET_REF] = clk_hw_register_divider_table(NULL, "enet_ref", "pll6_enet", 0, base + 0xe0, 0, 2, 0, clk_enet_ref_table, &imx_ccm_lock); |
269 | 277 | ||
270 | /* name parent_name reg idx */ | 278 | /* name parent_name reg idx */ |
271 | clks[IMX6SL_CLK_PLL2_PFD0] = imx_clk_pfd("pll2_pfd0", "pll2_bus", base + 0x100, 0); | 279 | hws[IMX6SL_CLK_PLL2_PFD0] = imx_clk_hw_pfd("pll2_pfd0", "pll2_bus", base + 0x100, 0); |
272 | clks[IMX6SL_CLK_PLL2_PFD1] = imx_clk_pfd("pll2_pfd1", "pll2_bus", base + 0x100, 1); | 280 | hws[IMX6SL_CLK_PLL2_PFD1] = imx_clk_hw_pfd("pll2_pfd1", "pll2_bus", base + 0x100, 1); |
273 | clks[IMX6SL_CLK_PLL2_PFD2] = imx_clk_pfd("pll2_pfd2", "pll2_bus", base + 0x100, 2); | 281 | hws[IMX6SL_CLK_PLL2_PFD2] = imx_clk_hw_pfd("pll2_pfd2", "pll2_bus", base + 0x100, 2); |
274 | clks[IMX6SL_CLK_PLL3_PFD0] = imx_clk_pfd("pll3_pfd0", "pll3_usb_otg", base + 0xf0, 0); | 282 | hws[IMX6SL_CLK_PLL3_PFD0] = imx_clk_hw_pfd("pll3_pfd0", "pll3_usb_otg", base + 0xf0, 0); |
275 | clks[IMX6SL_CLK_PLL3_PFD1] = imx_clk_pfd("pll3_pfd1", "pll3_usb_otg", base + 0xf0, 1); | 283 | hws[IMX6SL_CLK_PLL3_PFD1] = imx_clk_hw_pfd("pll3_pfd1", "pll3_usb_otg", base + 0xf0, 1); |
276 | clks[IMX6SL_CLK_PLL3_PFD2] = imx_clk_pfd("pll3_pfd2", "pll3_usb_otg", base + 0xf0, 2); | 284 | hws[IMX6SL_CLK_PLL3_PFD2] = imx_clk_hw_pfd("pll3_pfd2", "pll3_usb_otg", base + 0xf0, 2); |
277 | clks[IMX6SL_CLK_PLL3_PFD3] = imx_clk_pfd("pll3_pfd3", "pll3_usb_otg", base + 0xf0, 3); | 285 | hws[IMX6SL_CLK_PLL3_PFD3] = imx_clk_hw_pfd("pll3_pfd3", "pll3_usb_otg", base + 0xf0, 3); |
278 | 286 | ||
279 | /* name parent_name mult div */ | 287 | /* name parent_name mult div */ |
280 | clks[IMX6SL_CLK_PLL2_198M] = imx_clk_fixed_factor("pll2_198m", "pll2_pfd2", 1, 2); | 288 | hws[IMX6SL_CLK_PLL2_198M] = imx_clk_hw_fixed_factor("pll2_198m", "pll2_pfd2", 1, 2); |
281 | clks[IMX6SL_CLK_PLL3_120M] = imx_clk_fixed_factor("pll3_120m", "pll3_usb_otg", 1, 4); | 289 | hws[IMX6SL_CLK_PLL3_120M] = imx_clk_hw_fixed_factor("pll3_120m", "pll3_usb_otg", 1, 4); |
282 | clks[IMX6SL_CLK_PLL3_80M] = imx_clk_fixed_factor("pll3_80m", "pll3_usb_otg", 1, 6); | 290 | hws[IMX6SL_CLK_PLL3_80M] = imx_clk_hw_fixed_factor("pll3_80m", "pll3_usb_otg", 1, 6); |
283 | clks[IMX6SL_CLK_PLL3_60M] = imx_clk_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8); | 291 | hws[IMX6SL_CLK_PLL3_60M] = imx_clk_hw_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8); |
284 | 292 | ||
285 | np = ccm_node; | 293 | np = ccm_node; |
286 | base = of_iomap(np, 0); | 294 | base = of_iomap(np, 0); |
@@ -288,157 +296,160 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node) | |||
288 | ccm_base = base; | 296 | ccm_base = base; |
289 | 297 | ||
290 | /* name reg shift width parent_names num_parents */ | 298 | /* name reg shift width parent_names num_parents */ |
291 | clks[IMX6SL_CLK_STEP] = imx_clk_mux("step", base + 0xc, 8, 1, step_sels, ARRAY_SIZE(step_sels)); | 299 | hws[IMX6SL_CLK_STEP] = imx_clk_hw_mux("step", base + 0xc, 8, 1, step_sels, ARRAY_SIZE(step_sels)); |
292 | clks[IMX6SL_CLK_PLL1_SW] = imx_clk_mux("pll1_sw", base + 0xc, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels)); | 300 | hws[IMX6SL_CLK_PLL1_SW] = imx_clk_hw_mux("pll1_sw", base + 0xc, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels)); |
293 | clks[IMX6SL_CLK_OCRAM_ALT_SEL] = imx_clk_mux("ocram_alt_sel", base + 0x14, 7, 1, ocram_alt_sels, ARRAY_SIZE(ocram_alt_sels)); | 301 | hws[IMX6SL_CLK_OCRAM_ALT_SEL] = imx_clk_hw_mux("ocram_alt_sel", base + 0x14, 7, 1, ocram_alt_sels, ARRAY_SIZE(ocram_alt_sels)); |
294 | clks[IMX6SL_CLK_OCRAM_SEL] = imx_clk_mux("ocram_sel", base + 0x14, 6, 1, ocram_sels, ARRAY_SIZE(ocram_sels)); | 302 | hws[IMX6SL_CLK_OCRAM_SEL] = imx_clk_hw_mux("ocram_sel", base + 0x14, 6, 1, ocram_sels, ARRAY_SIZE(ocram_sels)); |
295 | clks[IMX6SL_CLK_PRE_PERIPH2_SEL] = imx_clk_mux("pre_periph2_sel", base + 0x18, 21, 2, pre_periph_sels, ARRAY_SIZE(pre_periph_sels)); | 303 | hws[IMX6SL_CLK_PRE_PERIPH2_SEL] = imx_clk_hw_mux("pre_periph2_sel", base + 0x18, 21, 2, pre_periph_sels, ARRAY_SIZE(pre_periph_sels)); |
296 | clks[IMX6SL_CLK_PRE_PERIPH_SEL] = imx_clk_mux("pre_periph_sel", base + 0x18, 18, 2, pre_periph_sels, ARRAY_SIZE(pre_periph_sels)); | 304 | hws[IMX6SL_CLK_PRE_PERIPH_SEL] = imx_clk_hw_mux("pre_periph_sel", base + 0x18, 18, 2, pre_periph_sels, ARRAY_SIZE(pre_periph_sels)); |
297 | clks[IMX6SL_CLK_PERIPH2_CLK2_SEL] = imx_clk_mux("periph2_clk2_sel", base + 0x18, 20, 1, periph2_clk2_sels, ARRAY_SIZE(periph2_clk2_sels)); | 305 | hws[IMX6SL_CLK_PERIPH2_CLK2_SEL] = imx_clk_hw_mux("periph2_clk2_sel", base + 0x18, 20, 1, periph2_clk2_sels, ARRAY_SIZE(periph2_clk2_sels)); |
298 | clks[IMX6SL_CLK_PERIPH_CLK2_SEL] = imx_clk_mux("periph_clk2_sel", base + 0x18, 12, 2, periph_clk2_sels, ARRAY_SIZE(periph_clk2_sels)); | 306 | hws[IMX6SL_CLK_PERIPH_CLK2_SEL] = imx_clk_hw_mux("periph_clk2_sel", base + 0x18, 12, 2, periph_clk2_sels, ARRAY_SIZE(periph_clk2_sels)); |
299 | clks[IMX6SL_CLK_CSI_SEL] = imx_clk_mux("csi_sel", base + 0x3c, 9, 2, csi_sels, ARRAY_SIZE(csi_sels)); | 307 | hws[IMX6SL_CLK_CSI_SEL] = imx_clk_hw_mux("csi_sel", base + 0x3c, 9, 2, csi_sels, ARRAY_SIZE(csi_sels)); |
300 | clks[IMX6SL_CLK_LCDIF_AXI_SEL] = imx_clk_mux("lcdif_axi_sel", base + 0x3c, 14, 2, lcdif_axi_sels, ARRAY_SIZE(lcdif_axi_sels)); | 308 | hws[IMX6SL_CLK_LCDIF_AXI_SEL] = imx_clk_hw_mux("lcdif_axi_sel", base + 0x3c, 14, 2, lcdif_axi_sels, ARRAY_SIZE(lcdif_axi_sels)); |
301 | clks[IMX6SL_CLK_USDHC1_SEL] = imx_clk_fixup_mux("usdhc1_sel", base + 0x1c, 16, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup); | 309 | hws[IMX6SL_CLK_USDHC1_SEL] = imx_clk_hw_fixup_mux("usdhc1_sel", base + 0x1c, 16, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup); |
302 | clks[IMX6SL_CLK_USDHC2_SEL] = imx_clk_fixup_mux("usdhc2_sel", base + 0x1c, 17, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup); | 310 | hws[IMX6SL_CLK_USDHC2_SEL] = imx_clk_hw_fixup_mux("usdhc2_sel", base + 0x1c, 17, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup); |
303 | clks[IMX6SL_CLK_USDHC3_SEL] = imx_clk_fixup_mux("usdhc3_sel", base + 0x1c, 18, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup); | 311 | hws[IMX6SL_CLK_USDHC3_SEL] = imx_clk_hw_fixup_mux("usdhc3_sel", base + 0x1c, 18, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup); |
304 | clks[IMX6SL_CLK_USDHC4_SEL] = imx_clk_fixup_mux("usdhc4_sel", base + 0x1c, 19, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup); | 312 | hws[IMX6SL_CLK_USDHC4_SEL] = imx_clk_hw_fixup_mux("usdhc4_sel", base + 0x1c, 19, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup); |
305 | clks[IMX6SL_CLK_SSI1_SEL] = imx_clk_fixup_mux("ssi1_sel", base + 0x1c, 10, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup); | 313 | hws[IMX6SL_CLK_SSI1_SEL] = imx_clk_hw_fixup_mux("ssi1_sel", base + 0x1c, 10, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup); |
306 | clks[IMX6SL_CLK_SSI2_SEL] = imx_clk_fixup_mux("ssi2_sel", base + 0x1c, 12, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup); | 314 | hws[IMX6SL_CLK_SSI2_SEL] = imx_clk_hw_fixup_mux("ssi2_sel", base + 0x1c, 12, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup); |
307 | clks[IMX6SL_CLK_SSI3_SEL] = imx_clk_fixup_mux("ssi3_sel", base + 0x1c, 14, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup); | 315 | hws[IMX6SL_CLK_SSI3_SEL] = imx_clk_hw_fixup_mux("ssi3_sel", base + 0x1c, 14, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup); |
308 | clks[IMX6SL_CLK_PERCLK_SEL] = imx_clk_fixup_mux("perclk_sel", base + 0x1c, 6, 1, perclk_sels, ARRAY_SIZE(perclk_sels), imx_cscmr1_fixup); | 316 | hws[IMX6SL_CLK_PERCLK_SEL] = imx_clk_hw_fixup_mux("perclk_sel", base + 0x1c, 6, 1, perclk_sels, ARRAY_SIZE(perclk_sels), imx_cscmr1_fixup); |
309 | clks[IMX6SL_CLK_PXP_AXI_SEL] = imx_clk_mux("pxp_axi_sel", base + 0x34, 6, 3, pxp_axi_sels, ARRAY_SIZE(pxp_axi_sels)); | 317 | hws[IMX6SL_CLK_PXP_AXI_SEL] = imx_clk_hw_mux("pxp_axi_sel", base + 0x34, 6, 3, pxp_axi_sels, ARRAY_SIZE(pxp_axi_sels)); |
310 | clks[IMX6SL_CLK_EPDC_AXI_SEL] = imx_clk_mux("epdc_axi_sel", base + 0x34, 15, 3, epdc_axi_sels, ARRAY_SIZE(epdc_axi_sels)); | 318 | hws[IMX6SL_CLK_EPDC_AXI_SEL] = imx_clk_hw_mux("epdc_axi_sel", base + 0x34, 15, 3, epdc_axi_sels, ARRAY_SIZE(epdc_axi_sels)); |
311 | clks[IMX6SL_CLK_GPU2D_OVG_SEL] = imx_clk_mux("gpu2d_ovg_sel", base + 0x18, 4, 2, gpu2d_ovg_sels, ARRAY_SIZE(gpu2d_ovg_sels)); | 319 | hws[IMX6SL_CLK_GPU2D_OVG_SEL] = imx_clk_hw_mux("gpu2d_ovg_sel", base + 0x18, 4, 2, gpu2d_ovg_sels, ARRAY_SIZE(gpu2d_ovg_sels)); |
312 | clks[IMX6SL_CLK_GPU2D_SEL] = imx_clk_mux("gpu2d_sel", base + 0x18, 8, 2, gpu2d_sels, ARRAY_SIZE(gpu2d_sels)); | 320 | hws[IMX6SL_CLK_GPU2D_SEL] = imx_clk_hw_mux("gpu2d_sel", base + 0x18, 8, 2, gpu2d_sels, ARRAY_SIZE(gpu2d_sels)); |
313 | clks[IMX6SL_CLK_LCDIF_PIX_SEL] = imx_clk_mux("lcdif_pix_sel", base + 0x38, 6, 3, lcdif_pix_sels, ARRAY_SIZE(lcdif_pix_sels)); | 321 | hws[IMX6SL_CLK_LCDIF_PIX_SEL] = imx_clk_hw_mux("lcdif_pix_sel", base + 0x38, 6, 3, lcdif_pix_sels, ARRAY_SIZE(lcdif_pix_sels)); |
314 | clks[IMX6SL_CLK_EPDC_PIX_SEL] = imx_clk_mux("epdc_pix_sel", base + 0x38, 15, 3, epdc_pix_sels, ARRAY_SIZE(epdc_pix_sels)); | 322 | hws[IMX6SL_CLK_EPDC_PIX_SEL] = imx_clk_hw_mux("epdc_pix_sel", base + 0x38, 15, 3, epdc_pix_sels, ARRAY_SIZE(epdc_pix_sels)); |
315 | clks[IMX6SL_CLK_SPDIF0_SEL] = imx_clk_mux("spdif0_sel", base + 0x30, 20, 2, audio_sels, ARRAY_SIZE(audio_sels)); | 323 | hws[IMX6SL_CLK_SPDIF0_SEL] = imx_clk_hw_mux("spdif0_sel", base + 0x30, 20, 2, audio_sels, ARRAY_SIZE(audio_sels)); |
316 | clks[IMX6SL_CLK_SPDIF1_SEL] = imx_clk_mux("spdif1_sel", base + 0x30, 7, 2, audio_sels, ARRAY_SIZE(audio_sels)); | 324 | hws[IMX6SL_CLK_SPDIF1_SEL] = imx_clk_hw_mux("spdif1_sel", base + 0x30, 7, 2, audio_sels, ARRAY_SIZE(audio_sels)); |
317 | clks[IMX6SL_CLK_EXTERN_AUDIO_SEL] = imx_clk_mux("extern_audio_sel", base + 0x20, 19, 2, audio_sels, ARRAY_SIZE(audio_sels)); | 325 | hws[IMX6SL_CLK_EXTERN_AUDIO_SEL] = imx_clk_hw_mux("extern_audio_sel", base + 0x20, 19, 2, audio_sels, ARRAY_SIZE(audio_sels)); |
318 | clks[IMX6SL_CLK_ECSPI_SEL] = imx_clk_mux("ecspi_sel", base + 0x38, 18, 1, ecspi_sels, ARRAY_SIZE(ecspi_sels)); | 326 | hws[IMX6SL_CLK_ECSPI_SEL] = imx_clk_hw_mux("ecspi_sel", base + 0x38, 18, 1, ecspi_sels, ARRAY_SIZE(ecspi_sels)); |
319 | clks[IMX6SL_CLK_UART_SEL] = imx_clk_mux("uart_sel", base + 0x24, 6, 1, uart_sels, ARRAY_SIZE(uart_sels)); | 327 | hws[IMX6SL_CLK_UART_SEL] = imx_clk_hw_mux("uart_sel", base + 0x24, 6, 1, uart_sels, ARRAY_SIZE(uart_sels)); |
320 | 328 | ||
321 | /* name reg shift width busy: reg, shift parent_names num_parents */ | 329 | /* name reg shift width busy: reg, shift parent_names num_parents */ |
322 | clks[IMX6SL_CLK_PERIPH] = imx_clk_busy_mux("periph", base + 0x14, 25, 1, base + 0x48, 5, periph_sels, ARRAY_SIZE(periph_sels)); | 330 | hws[IMX6SL_CLK_PERIPH] = imx_clk_hw_busy_mux("periph", base + 0x14, 25, 1, base + 0x48, 5, periph_sels, ARRAY_SIZE(periph_sels)); |
323 | clks[IMX6SL_CLK_PERIPH2] = imx_clk_busy_mux("periph2", base + 0x14, 26, 1, base + 0x48, 3, periph2_sels, ARRAY_SIZE(periph2_sels)); | 331 | hws[IMX6SL_CLK_PERIPH2] = imx_clk_hw_busy_mux("periph2", base + 0x14, 26, 1, base + 0x48, 3, periph2_sels, ARRAY_SIZE(periph2_sels)); |
324 | 332 | ||
325 | /* name parent_name reg shift width */ | 333 | /* name parent_name reg shift width */ |
326 | clks[IMX6SL_CLK_OCRAM_PODF] = imx_clk_busy_divider("ocram_podf", "ocram_sel", base + 0x14, 16, 3, base + 0x48, 0); | 334 | hws[IMX6SL_CLK_OCRAM_PODF] = imx_clk_hw_busy_divider("ocram_podf", "ocram_sel", base + 0x14, 16, 3, base + 0x48, 0); |
327 | clks[IMX6SL_CLK_PERIPH_CLK2_PODF] = imx_clk_divider("periph_clk2_podf", "periph_clk2_sel", base + 0x14, 27, 3); | 335 | hws[IMX6SL_CLK_PERIPH_CLK2_PODF] = imx_clk_hw_divider("periph_clk2_podf", "periph_clk2_sel", base + 0x14, 27, 3); |
328 | clks[IMX6SL_CLK_PERIPH2_CLK2_PODF] = imx_clk_divider("periph2_clk2_podf", "periph2_clk2_sel", base + 0x14, 0, 3); | 336 | hws[IMX6SL_CLK_PERIPH2_CLK2_PODF] = imx_clk_hw_divider("periph2_clk2_podf", "periph2_clk2_sel", base + 0x14, 0, 3); |
329 | clks[IMX6SL_CLK_IPG] = imx_clk_divider("ipg", "ahb", base + 0x14, 8, 2); | 337 | hws[IMX6SL_CLK_IPG] = imx_clk_hw_divider("ipg", "ahb", base + 0x14, 8, 2); |
330 | clks[IMX6SL_CLK_CSI_PODF] = imx_clk_divider("csi_podf", "csi_sel", base + 0x3c, 11, 3); | 338 | hws[IMX6SL_CLK_CSI_PODF] = imx_clk_hw_divider("csi_podf", "csi_sel", base + 0x3c, 11, 3); |
331 | clks[IMX6SL_CLK_LCDIF_AXI_PODF] = imx_clk_divider("lcdif_axi_podf", "lcdif_axi_sel", base + 0x3c, 16, 3); | 339 | hws[IMX6SL_CLK_LCDIF_AXI_PODF] = imx_clk_hw_divider("lcdif_axi_podf", "lcdif_axi_sel", base + 0x3c, 16, 3); |
332 | clks[IMX6SL_CLK_USDHC1_PODF] = imx_clk_divider("usdhc1_podf", "usdhc1_sel", base + 0x24, 11, 3); | 340 | hws[IMX6SL_CLK_USDHC1_PODF] = imx_clk_hw_divider("usdhc1_podf", "usdhc1_sel", base + 0x24, 11, 3); |
333 | clks[IMX6SL_CLK_USDHC2_PODF] = imx_clk_divider("usdhc2_podf", "usdhc2_sel", base + 0x24, 16, 3); | 341 | hws[IMX6SL_CLK_USDHC2_PODF] = imx_clk_hw_divider("usdhc2_podf", "usdhc2_sel", base + 0x24, 16, 3); |
334 | clks[IMX6SL_CLK_USDHC3_PODF] = imx_clk_divider("usdhc3_podf", "usdhc3_sel", base + 0x24, 19, 3); | 342 | hws[IMX6SL_CLK_USDHC3_PODF] = imx_clk_hw_divider("usdhc3_podf", "usdhc3_sel", base + 0x24, 19, 3); |
335 | clks[IMX6SL_CLK_USDHC4_PODF] = imx_clk_divider("usdhc4_podf", "usdhc4_sel", base + 0x24, 22, 3); | 343 | hws[IMX6SL_CLK_USDHC4_PODF] = imx_clk_hw_divider("usdhc4_podf", "usdhc4_sel", base + 0x24, 22, 3); |
336 | clks[IMX6SL_CLK_SSI1_PRED] = imx_clk_divider("ssi1_pred", "ssi1_sel", base + 0x28, 6, 3); | 344 | hws[IMX6SL_CLK_SSI1_PRED] = imx_clk_hw_divider("ssi1_pred", "ssi1_sel", base + 0x28, 6, 3); |
337 | clks[IMX6SL_CLK_SSI1_PODF] = imx_clk_divider("ssi1_podf", "ssi1_pred", base + 0x28, 0, 6); | 345 | hws[IMX6SL_CLK_SSI1_PODF] = imx_clk_hw_divider("ssi1_podf", "ssi1_pred", base + 0x28, 0, 6); |
338 | clks[IMX6SL_CLK_SSI2_PRED] = imx_clk_divider("ssi2_pred", "ssi2_sel", base + 0x2c, 6, 3); | 346 | hws[IMX6SL_CLK_SSI2_PRED] = imx_clk_hw_divider("ssi2_pred", "ssi2_sel", base + 0x2c, 6, 3); |
339 | clks[IMX6SL_CLK_SSI2_PODF] = imx_clk_divider("ssi2_podf", "ssi2_pred", base + 0x2c, 0, 6); | 347 | hws[IMX6SL_CLK_SSI2_PODF] = imx_clk_hw_divider("ssi2_podf", "ssi2_pred", base + 0x2c, 0, 6); |
340 | clks[IMX6SL_CLK_SSI3_PRED] = imx_clk_divider("ssi3_pred", "ssi3_sel", base + 0x28, 22, 3); | 348 | hws[IMX6SL_CLK_SSI3_PRED] = imx_clk_hw_divider("ssi3_pred", "ssi3_sel", base + 0x28, 22, 3); |
341 | clks[IMX6SL_CLK_SSI3_PODF] = imx_clk_divider("ssi3_podf", "ssi3_pred", base + 0x28, 16, 6); | 349 | hws[IMX6SL_CLK_SSI3_PODF] = imx_clk_hw_divider("ssi3_podf", "ssi3_pred", base + 0x28, 16, 6); |
342 | clks[IMX6SL_CLK_PERCLK] = imx_clk_fixup_divider("perclk", "perclk_sel", base + 0x1c, 0, 6, imx_cscmr1_fixup); | 350 | hws[IMX6SL_CLK_PERCLK] = imx_clk_hw_fixup_divider("perclk", "perclk_sel", base + 0x1c, 0, 6, imx_cscmr1_fixup); |
343 | clks[IMX6SL_CLK_PXP_AXI_PODF] = imx_clk_divider("pxp_axi_podf", "pxp_axi_sel", base + 0x34, 3, 3); | 351 | hws[IMX6SL_CLK_PXP_AXI_PODF] = imx_clk_hw_divider("pxp_axi_podf", "pxp_axi_sel", base + 0x34, 3, 3); |
344 | clks[IMX6SL_CLK_EPDC_AXI_PODF] = imx_clk_divider("epdc_axi_podf", "epdc_axi_sel", base + 0x34, 12, 3); | 352 | hws[IMX6SL_CLK_EPDC_AXI_PODF] = imx_clk_hw_divider("epdc_axi_podf", "epdc_axi_sel", base + 0x34, 12, 3); |
345 | clks[IMX6SL_CLK_GPU2D_OVG_PODF] = imx_clk_divider("gpu2d_ovg_podf", "gpu2d_ovg_sel", base + 0x18, 26, 3); | 353 | hws[IMX6SL_CLK_GPU2D_OVG_PODF] = imx_clk_hw_divider("gpu2d_ovg_podf", "gpu2d_ovg_sel", base + 0x18, 26, 3); |
346 | clks[IMX6SL_CLK_GPU2D_PODF] = imx_clk_divider("gpu2d_podf", "gpu2d_sel", base + 0x18, 29, 3); | 354 | hws[IMX6SL_CLK_GPU2D_PODF] = imx_clk_hw_divider("gpu2d_podf", "gpu2d_sel", base + 0x18, 29, 3); |
347 | clks[IMX6SL_CLK_LCDIF_PIX_PRED] = imx_clk_divider("lcdif_pix_pred", "lcdif_pix_sel", base + 0x38, 3, 3); | 355 | hws[IMX6SL_CLK_LCDIF_PIX_PRED] = imx_clk_hw_divider("lcdif_pix_pred", "lcdif_pix_sel", base + 0x38, 3, 3); |
348 | clks[IMX6SL_CLK_EPDC_PIX_PRED] = imx_clk_divider("epdc_pix_pred", "epdc_pix_sel", base + 0x38, 12, 3); | 356 | hws[IMX6SL_CLK_EPDC_PIX_PRED] = imx_clk_hw_divider("epdc_pix_pred", "epdc_pix_sel", base + 0x38, 12, 3); |
349 | clks[IMX6SL_CLK_LCDIF_PIX_PODF] = imx_clk_fixup_divider("lcdif_pix_podf", "lcdif_pix_pred", base + 0x1c, 20, 3, imx_cscmr1_fixup); | 357 | hws[IMX6SL_CLK_LCDIF_PIX_PODF] = imx_clk_hw_fixup_divider("lcdif_pix_podf", "lcdif_pix_pred", base + 0x1c, 20, 3, imx_cscmr1_fixup); |
350 | clks[IMX6SL_CLK_EPDC_PIX_PODF] = imx_clk_divider("epdc_pix_podf", "epdc_pix_pred", base + 0x18, 23, 3); | 358 | hws[IMX6SL_CLK_EPDC_PIX_PODF] = imx_clk_hw_divider("epdc_pix_podf", "epdc_pix_pred", base + 0x18, 23, 3); |
351 | clks[IMX6SL_CLK_SPDIF0_PRED] = imx_clk_divider("spdif0_pred", "spdif0_sel", base + 0x30, 25, 3); | 359 | hws[IMX6SL_CLK_SPDIF0_PRED] = imx_clk_hw_divider("spdif0_pred", "spdif0_sel", base + 0x30, 25, 3); |
352 | clks[IMX6SL_CLK_SPDIF0_PODF] = imx_clk_divider("spdif0_podf", "spdif0_pred", base + 0x30, 22, 3); | 360 | hws[IMX6SL_CLK_SPDIF0_PODF] = imx_clk_hw_divider("spdif0_podf", "spdif0_pred", base + 0x30, 22, 3); |
353 | clks[IMX6SL_CLK_SPDIF1_PRED] = imx_clk_divider("spdif1_pred", "spdif1_sel", base + 0x30, 12, 3); | 361 | hws[IMX6SL_CLK_SPDIF1_PRED] = imx_clk_hw_divider("spdif1_pred", "spdif1_sel", base + 0x30, 12, 3); |
354 | clks[IMX6SL_CLK_SPDIF1_PODF] = imx_clk_divider("spdif1_podf", "spdif1_pred", base + 0x30, 9, 3); | 362 | hws[IMX6SL_CLK_SPDIF1_PODF] = imx_clk_hw_divider("spdif1_podf", "spdif1_pred", base + 0x30, 9, 3); |
355 | clks[IMX6SL_CLK_EXTERN_AUDIO_PRED] = imx_clk_divider("extern_audio_pred", "extern_audio_sel", base + 0x28, 9, 3); | 363 | hws[IMX6SL_CLK_EXTERN_AUDIO_PRED] = imx_clk_hw_divider("extern_audio_pred", "extern_audio_sel", base + 0x28, 9, 3); |
356 | clks[IMX6SL_CLK_EXTERN_AUDIO_PODF] = imx_clk_divider("extern_audio_podf", "extern_audio_pred", base + 0x28, 25, 3); | 364 | hws[IMX6SL_CLK_EXTERN_AUDIO_PODF] = imx_clk_hw_divider("extern_audio_podf", "extern_audio_pred", base + 0x28, 25, 3); |
357 | clks[IMX6SL_CLK_ECSPI_ROOT] = imx_clk_divider("ecspi_root", "ecspi_sel", base + 0x38, 19, 6); | 365 | hws[IMX6SL_CLK_ECSPI_ROOT] = imx_clk_hw_divider("ecspi_root", "ecspi_sel", base + 0x38, 19, 6); |
358 | clks[IMX6SL_CLK_UART_ROOT] = imx_clk_divider("uart_root", "uart_sel", base + 0x24, 0, 6); | 366 | hws[IMX6SL_CLK_UART_ROOT] = imx_clk_hw_divider("uart_root", "uart_sel", base + 0x24, 0, 6); |
359 | 367 | ||
360 | /* name parent_name reg shift width busy: reg, shift */ | 368 | /* name parent_name reg shift width busy: reg, shift */ |
361 | clks[IMX6SL_CLK_AHB] = imx_clk_busy_divider("ahb", "periph", base + 0x14, 10, 3, base + 0x48, 1); | 369 | hws[IMX6SL_CLK_AHB] = imx_clk_hw_busy_divider("ahb", "periph", base + 0x14, 10, 3, base + 0x48, 1); |
362 | clks[IMX6SL_CLK_MMDC_ROOT] = imx_clk_busy_divider("mmdc", "periph2", base + 0x14, 3, 3, base + 0x48, 2); | 370 | hws[IMX6SL_CLK_MMDC_ROOT] = imx_clk_hw_busy_divider("mmdc", "periph2", base + 0x14, 3, 3, base + 0x48, 2); |
363 | clks[IMX6SL_CLK_ARM] = imx_clk_busy_divider("arm", "pll1_sw", base + 0x10, 0, 3, base + 0x48, 16); | 371 | hws[IMX6SL_CLK_ARM] = imx_clk_hw_busy_divider("arm", "pll1_sw", base + 0x10, 0, 3, base + 0x48, 16); |
364 | 372 | ||
365 | /* name parent_name reg shift */ | 373 | /* name parent_name reg shift */ |
366 | clks[IMX6SL_CLK_ECSPI1] = imx_clk_gate2("ecspi1", "ecspi_root", base + 0x6c, 0); | 374 | hws[IMX6SL_CLK_ECSPI1] = imx_clk_hw_gate2("ecspi1", "ecspi_root", base + 0x6c, 0); |
367 | clks[IMX6SL_CLK_ECSPI2] = imx_clk_gate2("ecspi2", "ecspi_root", base + 0x6c, 2); | 375 | hws[IMX6SL_CLK_ECSPI2] = imx_clk_hw_gate2("ecspi2", "ecspi_root", base + 0x6c, 2); |
368 | clks[IMX6SL_CLK_ECSPI3] = imx_clk_gate2("ecspi3", "ecspi_root", base + 0x6c, 4); | 376 | hws[IMX6SL_CLK_ECSPI3] = imx_clk_hw_gate2("ecspi3", "ecspi_root", base + 0x6c, 4); |
369 | clks[IMX6SL_CLK_ECSPI4] = imx_clk_gate2("ecspi4", "ecspi_root", base + 0x6c, 6); | 377 | hws[IMX6SL_CLK_ECSPI4] = imx_clk_hw_gate2("ecspi4", "ecspi_root", base + 0x6c, 6); |
370 | clks[IMX6SL_CLK_ENET] = imx_clk_gate2("enet", "ipg", base + 0x6c, 10); | 378 | hws[IMX6SL_CLK_ENET] = imx_clk_hw_gate2("enet", "ipg", base + 0x6c, 10); |
371 | clks[IMX6SL_CLK_EPIT1] = imx_clk_gate2("epit1", "perclk", base + 0x6c, 12); | 379 | hws[IMX6SL_CLK_EPIT1] = imx_clk_hw_gate2("epit1", "perclk", base + 0x6c, 12); |
372 | clks[IMX6SL_CLK_EPIT2] = imx_clk_gate2("epit2", "perclk", base + 0x6c, 14); | 380 | hws[IMX6SL_CLK_EPIT2] = imx_clk_hw_gate2("epit2", "perclk", base + 0x6c, 14); |
373 | clks[IMX6SL_CLK_EXTERN_AUDIO] = imx_clk_gate2("extern_audio", "extern_audio_podf", base + 0x6c, 16); | 381 | hws[IMX6SL_CLK_EXTERN_AUDIO] = imx_clk_hw_gate2("extern_audio", "extern_audio_podf", base + 0x6c, 16); |
374 | clks[IMX6SL_CLK_GPT] = imx_clk_gate2("gpt", "perclk", base + 0x6c, 20); | 382 | hws[IMX6SL_CLK_GPT] = imx_clk_hw_gate2("gpt", "perclk", base + 0x6c, 20); |
375 | clks[IMX6SL_CLK_GPT_SERIAL] = imx_clk_gate2("gpt_serial", "perclk", base + 0x6c, 22); | 383 | hws[IMX6SL_CLK_GPT_SERIAL] = imx_clk_hw_gate2("gpt_serial", "perclk", base + 0x6c, 22); |
376 | clks[IMX6SL_CLK_GPU2D_OVG] = imx_clk_gate2("gpu2d_ovg", "gpu2d_ovg_podf", base + 0x6c, 26); | 384 | hws[IMX6SL_CLK_GPU2D_OVG] = imx_clk_hw_gate2("gpu2d_ovg", "gpu2d_ovg_podf", base + 0x6c, 26); |
377 | clks[IMX6SL_CLK_I2C1] = imx_clk_gate2("i2c1", "perclk", base + 0x70, 6); | 385 | hws[IMX6SL_CLK_I2C1] = imx_clk_hw_gate2("i2c1", "perclk", base + 0x70, 6); |
378 | clks[IMX6SL_CLK_I2C2] = imx_clk_gate2("i2c2", "perclk", base + 0x70, 8); | 386 | hws[IMX6SL_CLK_I2C2] = imx_clk_hw_gate2("i2c2", "perclk", base + 0x70, 8); |
379 | clks[IMX6SL_CLK_I2C3] = imx_clk_gate2("i2c3", "perclk", base + 0x70, 10); | 387 | hws[IMX6SL_CLK_I2C3] = imx_clk_hw_gate2("i2c3", "perclk", base + 0x70, 10); |
380 | clks[IMX6SL_CLK_OCOTP] = imx_clk_gate2("ocotp", "ipg", base + 0x70, 12); | 388 | hws[IMX6SL_CLK_OCOTP] = imx_clk_hw_gate2("ocotp", "ipg", base + 0x70, 12); |
381 | clks[IMX6SL_CLK_CSI] = imx_clk_gate2("csi", "csi_podf", base + 0x74, 0); | 389 | hws[IMX6SL_CLK_CSI] = imx_clk_hw_gate2("csi", "csi_podf", base + 0x74, 0); |
382 | clks[IMX6SL_CLK_PXP_AXI] = imx_clk_gate2("pxp_axi", "pxp_axi_podf", base + 0x74, 2); | 390 | hws[IMX6SL_CLK_PXP_AXI] = imx_clk_hw_gate2("pxp_axi", "pxp_axi_podf", base + 0x74, 2); |
383 | clks[IMX6SL_CLK_EPDC_AXI] = imx_clk_gate2("epdc_axi", "epdc_axi_podf", base + 0x74, 4); | 391 | hws[IMX6SL_CLK_EPDC_AXI] = imx_clk_hw_gate2("epdc_axi", "epdc_axi_podf", base + 0x74, 4); |
384 | clks[IMX6SL_CLK_LCDIF_AXI] = imx_clk_gate2("lcdif_axi", "lcdif_axi_podf", base + 0x74, 6); | 392 | hws[IMX6SL_CLK_LCDIF_AXI] = imx_clk_hw_gate2("lcdif_axi", "lcdif_axi_podf", base + 0x74, 6); |
385 | clks[IMX6SL_CLK_LCDIF_PIX] = imx_clk_gate2("lcdif_pix", "lcdif_pix_podf", base + 0x74, 8); | 393 | hws[IMX6SL_CLK_LCDIF_PIX] = imx_clk_hw_gate2("lcdif_pix", "lcdif_pix_podf", base + 0x74, 8); |
386 | clks[IMX6SL_CLK_EPDC_PIX] = imx_clk_gate2("epdc_pix", "epdc_pix_podf", base + 0x74, 10); | 394 | hws[IMX6SL_CLK_EPDC_PIX] = imx_clk_hw_gate2("epdc_pix", "epdc_pix_podf", base + 0x74, 10); |
387 | clks[IMX6SL_CLK_MMDC_P0_IPG] = imx_clk_gate2_flags("mmdc_p0_ipg", "ipg", base + 0x74, 24, CLK_IS_CRITICAL); | 395 | hws[IMX6SL_CLK_MMDC_P0_IPG] = imx_clk_hw_gate2_flags("mmdc_p0_ipg", "ipg", base + 0x74, 24, CLK_IS_CRITICAL); |
388 | clks[IMX6SL_CLK_MMDC_P1_IPG] = imx_clk_gate2("mmdc_p1_ipg", "ipg", base + 0x74, 26); | 396 | hws[IMX6SL_CLK_MMDC_P1_IPG] = imx_clk_hw_gate2("mmdc_p1_ipg", "ipg", base + 0x74, 26); |
389 | clks[IMX6SL_CLK_OCRAM] = imx_clk_gate2("ocram", "ocram_podf", base + 0x74, 28); | 397 | hws[IMX6SL_CLK_OCRAM] = imx_clk_hw_gate2("ocram", "ocram_podf", base + 0x74, 28); |
390 | clks[IMX6SL_CLK_PWM1] = imx_clk_gate2("pwm1", "perclk", base + 0x78, 16); | 398 | hws[IMX6SL_CLK_PWM1] = imx_clk_hw_gate2("pwm1", "perclk", base + 0x78, 16); |
391 | clks[IMX6SL_CLK_PWM2] = imx_clk_gate2("pwm2", "perclk", base + 0x78, 18); | 399 | hws[IMX6SL_CLK_PWM2] = imx_clk_hw_gate2("pwm2", "perclk", base + 0x78, 18); |
392 | clks[IMX6SL_CLK_PWM3] = imx_clk_gate2("pwm3", "perclk", base + 0x78, 20); | 400 | hws[IMX6SL_CLK_PWM3] = imx_clk_hw_gate2("pwm3", "perclk", base + 0x78, 20); |
393 | clks[IMX6SL_CLK_PWM4] = imx_clk_gate2("pwm4", "perclk", base + 0x78, 22); | 401 | hws[IMX6SL_CLK_PWM4] = imx_clk_hw_gate2("pwm4", "perclk", base + 0x78, 22); |
394 | clks[IMX6SL_CLK_SDMA] = imx_clk_gate2("sdma", "ipg", base + 0x7c, 6); | 402 | hws[IMX6SL_CLK_SDMA] = imx_clk_hw_gate2("sdma", "ipg", base + 0x7c, 6); |
395 | clks[IMX6SL_CLK_SPBA] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12); | 403 | hws[IMX6SL_CLK_SPBA] = imx_clk_hw_gate2("spba", "ipg", base + 0x7c, 12); |
396 | clks[IMX6SL_CLK_SPDIF] = imx_clk_gate2_shared("spdif", "spdif0_podf", base + 0x7c, 14, &share_count_spdif); | 404 | hws[IMX6SL_CLK_SPDIF] = imx_clk_hw_gate2_shared("spdif", "spdif0_podf", base + 0x7c, 14, &share_count_spdif); |
397 | clks[IMX6SL_CLK_SPDIF_GCLK] = imx_clk_gate2_shared("spdif_gclk", "ipg", base + 0x7c, 14, &share_count_spdif); | 405 | hws[IMX6SL_CLK_SPDIF_GCLK] = imx_clk_hw_gate2_shared("spdif_gclk", "ipg", base + 0x7c, 14, &share_count_spdif); |
398 | clks[IMX6SL_CLK_SSI1_IPG] = imx_clk_gate2_shared("ssi1_ipg", "ipg", base + 0x7c, 18, &share_count_ssi1); | 406 | hws[IMX6SL_CLK_SSI1_IPG] = imx_clk_hw_gate2_shared("ssi1_ipg", "ipg", base + 0x7c, 18, &share_count_ssi1); |
399 | clks[IMX6SL_CLK_SSI2_IPG] = imx_clk_gate2_shared("ssi2_ipg", "ipg", base + 0x7c, 20, &share_count_ssi2); | 407 | hws[IMX6SL_CLK_SSI2_IPG] = imx_clk_hw_gate2_shared("ssi2_ipg", "ipg", base + 0x7c, 20, &share_count_ssi2); |
400 | clks[IMX6SL_CLK_SSI3_IPG] = imx_clk_gate2_shared("ssi3_ipg", "ipg", base + 0x7c, 22, &share_count_ssi3); | 408 | hws[IMX6SL_CLK_SSI3_IPG] = imx_clk_hw_gate2_shared("ssi3_ipg", "ipg", base + 0x7c, 22, &share_count_ssi3); |
401 | clks[IMX6SL_CLK_SSI1] = imx_clk_gate2_shared("ssi1", "ssi1_podf", base + 0x7c, 18, &share_count_ssi1); | 409 | hws[IMX6SL_CLK_SSI1] = imx_clk_hw_gate2_shared("ssi1", "ssi1_podf", base + 0x7c, 18, &share_count_ssi1); |
402 | clks[IMX6SL_CLK_SSI2] = imx_clk_gate2_shared("ssi2", "ssi2_podf", base + 0x7c, 20, &share_count_ssi2); | 410 | hws[IMX6SL_CLK_SSI2] = imx_clk_hw_gate2_shared("ssi2", "ssi2_podf", base + 0x7c, 20, &share_count_ssi2); |
403 | clks[IMX6SL_CLK_SSI3] = imx_clk_gate2_shared("ssi3", "ssi3_podf", base + 0x7c, 22, &share_count_ssi3); | 411 | hws[IMX6SL_CLK_SSI3] = imx_clk_hw_gate2_shared("ssi3", "ssi3_podf", base + 0x7c, 22, &share_count_ssi3); |
404 | clks[IMX6SL_CLK_UART] = imx_clk_gate2("uart", "ipg", base + 0x7c, 24); | 412 | hws[IMX6SL_CLK_UART] = imx_clk_hw_gate2("uart", "ipg", base + 0x7c, 24); |
405 | clks[IMX6SL_CLK_UART_SERIAL] = imx_clk_gate2("uart_serial", "uart_root", base + 0x7c, 26); | 413 | hws[IMX6SL_CLK_UART_SERIAL] = imx_clk_hw_gate2("uart_serial", "uart_root", base + 0x7c, 26); |
406 | clks[IMX6SL_CLK_USBOH3] = imx_clk_gate2("usboh3", "ipg", base + 0x80, 0); | 414 | hws[IMX6SL_CLK_USBOH3] = imx_clk_hw_gate2("usboh3", "ipg", base + 0x80, 0); |
407 | clks[IMX6SL_CLK_USDHC1] = imx_clk_gate2("usdhc1", "usdhc1_podf", base + 0x80, 2); | 415 | hws[IMX6SL_CLK_USDHC1] = imx_clk_hw_gate2("usdhc1", "usdhc1_podf", base + 0x80, 2); |
408 | clks[IMX6SL_CLK_USDHC2] = imx_clk_gate2("usdhc2", "usdhc2_podf", base + 0x80, 4); | 416 | hws[IMX6SL_CLK_USDHC2] = imx_clk_hw_gate2("usdhc2", "usdhc2_podf", base + 0x80, 4); |
409 | clks[IMX6SL_CLK_USDHC3] = imx_clk_gate2("usdhc3", "usdhc3_podf", base + 0x80, 6); | 417 | hws[IMX6SL_CLK_USDHC3] = imx_clk_hw_gate2("usdhc3", "usdhc3_podf", base + 0x80, 6); |
410 | clks[IMX6SL_CLK_USDHC4] = imx_clk_gate2("usdhc4", "usdhc4_podf", base + 0x80, 8); | 418 | hws[IMX6SL_CLK_USDHC4] = imx_clk_hw_gate2("usdhc4", "usdhc4_podf", base + 0x80, 8); |
411 | 419 | ||
412 | /* Ensure the MMDC CH0 handshake is bypassed */ | 420 | /* Ensure the MMDC CH0 handshake is bypassed */ |
413 | writel_relaxed(readl_relaxed(base + CCDR) | | 421 | imx_mmdc_mask_handshake(base, 0); |
414 | BM_CCM_CCDR_MMDC_CH0_MASK, base + CCDR); | ||
415 | 422 | ||
416 | imx_check_clocks(clks, ARRAY_SIZE(clks)); | 423 | imx_check_clk_hws(hws, IMX6SL_CLK_END); |
417 | 424 | ||
418 | clk_data.clks = clks; | 425 | of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data); |
419 | clk_data.clk_num = ARRAY_SIZE(clks); | ||
420 | of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); | ||
421 | 426 | ||
422 | /* Ensure the AHB clk is at 132MHz. */ | 427 | /* Ensure the AHB clk is at 132MHz. */ |
423 | ret = clk_set_rate(clks[IMX6SL_CLK_AHB], 132000000); | 428 | ret = clk_set_rate(hws[IMX6SL_CLK_AHB]->clk, 132000000); |
424 | if (ret) | 429 | if (ret) |
425 | pr_warn("%s: failed to set AHB clock rate %d!\n", | 430 | pr_warn("%s: failed to set AHB clock rate %d!\n", |
426 | __func__, ret); | 431 | __func__, ret); |
427 | 432 | ||
428 | if (IS_ENABLED(CONFIG_USB_MXS_PHY)) { | 433 | if (IS_ENABLED(CONFIG_USB_MXS_PHY)) { |
429 | clk_prepare_enable(clks[IMX6SL_CLK_USBPHY1_GATE]); | 434 | clk_prepare_enable(hws[IMX6SL_CLK_USBPHY1_GATE]->clk); |
430 | clk_prepare_enable(clks[IMX6SL_CLK_USBPHY2_GATE]); | 435 | clk_prepare_enable(hws[IMX6SL_CLK_USBPHY2_GATE]->clk); |
431 | } | 436 | } |
432 | 437 | ||
433 | /* Audio-related clocks configuration */ | 438 | /* Audio-related clocks configuration */ |
434 | clk_set_parent(clks[IMX6SL_CLK_SPDIF0_SEL], clks[IMX6SL_CLK_PLL3_PFD3]); | 439 | clk_set_parent(hws[IMX6SL_CLK_SPDIF0_SEL]->clk, hws[IMX6SL_CLK_PLL3_PFD3]->clk); |
435 | 440 | ||
436 | /* set PLL5 video as lcdif pix parent clock */ | 441 | /* set PLL5 video as lcdif pix parent clock */ |
437 | clk_set_parent(clks[IMX6SL_CLK_LCDIF_PIX_SEL], | 442 | clk_set_parent(hws[IMX6SL_CLK_LCDIF_PIX_SEL]->clk, |
438 | clks[IMX6SL_CLK_PLL5_VIDEO_DIV]); | 443 | hws[IMX6SL_CLK_PLL5_VIDEO_DIV]->clk); |
439 | 444 | ||
440 | clk_set_parent(clks[IMX6SL_CLK_LCDIF_AXI_SEL], | 445 | clk_set_parent(hws[IMX6SL_CLK_LCDIF_AXI_SEL]->clk, |
441 | clks[IMX6SL_CLK_PLL2_PFD2]); | 446 | hws[IMX6SL_CLK_PLL2_PFD2]->clk); |
447 | |||
448 | for (i = 0; i < ARRAY_SIZE(uart_clk_ids); i++) { | ||
449 | int index = uart_clk_ids[i]; | ||
450 | |||
451 | uart_clks[i] = &hws[index]->clk; | ||
452 | } | ||
442 | 453 | ||
443 | imx_register_uart_clocks(uart_clks); | 454 | imx_register_uart_clocks(uart_clks); |
444 | } | 455 | } |
diff --git a/drivers/clk/imx/clk-imx6sll.c b/drivers/clk/imx/clk-imx6sll.c index 7eea448cb9a9..5f3e92c09a5e 100644 --- a/drivers/clk/imx/clk-imx6sll.c +++ b/drivers/clk/imx/clk-imx6sll.c | |||
@@ -7,6 +7,7 @@ | |||
7 | #include <dt-bindings/clock/imx6sll-clock.h> | 7 | #include <dt-bindings/clock/imx6sll-clock.h> |
8 | #include <linux/clk.h> | 8 | #include <linux/clk.h> |
9 | #include <linux/clkdev.h> | 9 | #include <linux/clkdev.h> |
10 | #include <linux/clk-provider.h> | ||
10 | #include <linux/err.h> | 11 | #include <linux/err.h> |
11 | #include <linux/init.h> | 12 | #include <linux/init.h> |
12 | #include <linux/io.h> | 13 | #include <linux/io.h> |
@@ -16,7 +17,6 @@ | |||
16 | #include "clk.h" | 17 | #include "clk.h" |
17 | 18 | ||
18 | #define CCM_ANALOG_PLL_BYPASS (0x1 << 16) | 19 | #define CCM_ANALOG_PLL_BYPASS (0x1 << 16) |
19 | #define BM_CCM_CCDR_MMDC_CH0_MASK (0x2 << 16) | ||
20 | #define xPLL_CLR(offset) (offset + 0x8) | 20 | #define xPLL_CLR(offset) (offset + 0x8) |
21 | 21 | ||
22 | static const char *pll_bypass_src_sels[] = { "osc", "dummy", }; | 22 | static const char *pll_bypass_src_sels[] = { "osc", "dummy", }; |
@@ -53,8 +53,8 @@ static const char *lcdif_sels[] = { "lcdif_podf", "ipp_di0", "ipp_di1", "ldb_di0 | |||
53 | static const char *epdc_pre_sels[] = { "pll2_bus", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd2_508m", }; | 53 | static const char *epdc_pre_sels[] = { "pll2_bus", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd2_508m", }; |
54 | static const char *epdc_sels[] = { "epdc_podf", "ipp_di0", "ipp_di1", "ldb_di0", "ldb_di1", }; | 54 | static const char *epdc_sels[] = { "epdc_podf", "ipp_di0", "ipp_di1", "ldb_di0", "ldb_di1", }; |
55 | 55 | ||
56 | static struct clk *clks[IMX6SLL_CLK_END]; | 56 | static struct clk_hw **hws; |
57 | static struct clk_onecell_data clk_data; | 57 | static struct clk_hw_onecell_data *clk_hw_data; |
58 | 58 | ||
59 | static const struct clk_div_table post_div_table[] = { | 59 | static const struct clk_div_table post_div_table[] = { |
60 | { .val = 2, .div = 1, }, | 60 | { .val = 2, .div = 1, }, |
@@ -76,33 +76,43 @@ static u32 share_count_ssi1; | |||
76 | static u32 share_count_ssi2; | 76 | static u32 share_count_ssi2; |
77 | static u32 share_count_ssi3; | 77 | static u32 share_count_ssi3; |
78 | 78 | ||
79 | static struct clk ** const uart_clks[] __initconst = { | 79 | static const int uart_clk_ids[] __initconst = { |
80 | &clks[IMX6SLL_CLK_UART1_IPG], | 80 | IMX6SLL_CLK_UART1_IPG, |
81 | &clks[IMX6SLL_CLK_UART1_SERIAL], | 81 | IMX6SLL_CLK_UART1_SERIAL, |
82 | &clks[IMX6SLL_CLK_UART2_IPG], | 82 | IMX6SLL_CLK_UART2_IPG, |
83 | &clks[IMX6SLL_CLK_UART2_SERIAL], | 83 | IMX6SLL_CLK_UART2_SERIAL, |
84 | &clks[IMX6SLL_CLK_UART3_IPG], | 84 | IMX6SLL_CLK_UART3_IPG, |
85 | &clks[IMX6SLL_CLK_UART3_SERIAL], | 85 | IMX6SLL_CLK_UART3_SERIAL, |
86 | &clks[IMX6SLL_CLK_UART4_IPG], | 86 | IMX6SLL_CLK_UART4_IPG, |
87 | &clks[IMX6SLL_CLK_UART4_SERIAL], | 87 | IMX6SLL_CLK_UART4_SERIAL, |
88 | &clks[IMX6SLL_CLK_UART5_IPG], | 88 | IMX6SLL_CLK_UART5_IPG, |
89 | &clks[IMX6SLL_CLK_UART5_SERIAL], | 89 | IMX6SLL_CLK_UART5_SERIAL, |
90 | NULL | ||
91 | }; | 90 | }; |
92 | 91 | ||
92 | static struct clk **uart_clks[ARRAY_SIZE(uart_clk_ids) + 1] __initdata; | ||
93 | |||
93 | static void __init imx6sll_clocks_init(struct device_node *ccm_node) | 94 | static void __init imx6sll_clocks_init(struct device_node *ccm_node) |
94 | { | 95 | { |
95 | struct device_node *np; | 96 | struct device_node *np; |
96 | void __iomem *base; | 97 | void __iomem *base; |
98 | int i; | ||
99 | |||
100 | clk_hw_data = kzalloc(struct_size(clk_hw_data, hws, | ||
101 | IMX6SLL_CLK_END), GFP_KERNEL); | ||
102 | if (WARN_ON(!clk_hw_data)) | ||
103 | return; | ||
104 | |||
105 | clk_hw_data->num = IMX6SLL_CLK_END; | ||
106 | hws = clk_hw_data->hws; | ||
97 | 107 | ||
98 | clks[IMX6SLL_CLK_DUMMY] = imx_clk_fixed("dummy", 0); | 108 | hws[IMX6SLL_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0); |
99 | 109 | ||
100 | clks[IMX6SLL_CLK_CKIL] = of_clk_get_by_name(ccm_node, "ckil"); | 110 | hws[IMX6SLL_CLK_CKIL] = __clk_get_hw(of_clk_get_by_name(ccm_node, "ckil")); |
101 | clks[IMX6SLL_CLK_OSC] = of_clk_get_by_name(ccm_node, "osc"); | 111 | hws[IMX6SLL_CLK_OSC] = __clk_get_hw(of_clk_get_by_name(ccm_node, "osc")); |
102 | 112 | ||
103 | /* ipp_di clock is external input */ | 113 | /* ipp_di clock is external input */ |
104 | clks[IMX6SLL_CLK_IPP_DI0] = of_clk_get_by_name(ccm_node, "ipp_di0"); | 114 | hws[IMX6SLL_CLK_IPP_DI0] = __clk_get_hw(of_clk_get_by_name(ccm_node, "ipp_di0")); |
105 | clks[IMX6SLL_CLK_IPP_DI1] = of_clk_get_by_name(ccm_node, "ipp_di1"); | 115 | hws[IMX6SLL_CLK_IPP_DI1] = __clk_get_hw(of_clk_get_by_name(ccm_node, "ipp_di1")); |
106 | 116 | ||
107 | np = of_find_compatible_node(NULL, NULL, "fsl,imx6sll-anatop"); | 117 | np = of_find_compatible_node(NULL, NULL, "fsl,imx6sll-anatop"); |
108 | base = of_iomap(np, 0); | 118 | base = of_iomap(np, 0); |
@@ -118,37 +128,37 @@ static void __init imx6sll_clocks_init(struct device_node *ccm_node) | |||
118 | writel_relaxed(CCM_ANALOG_PLL_BYPASS, base + xPLL_CLR(0xa0)); | 128 | writel_relaxed(CCM_ANALOG_PLL_BYPASS, base + xPLL_CLR(0xa0)); |
119 | writel_relaxed(CCM_ANALOG_PLL_BYPASS, base + xPLL_CLR(0xe0)); | 129 | writel_relaxed(CCM_ANALOG_PLL_BYPASS, base + xPLL_CLR(0xe0)); |
120 | 130 | ||
121 | clks[IMX6SLL_PLL1_BYPASS_SRC] = imx_clk_mux("pll1_bypass_src", base + 0x00, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); | 131 | hws[IMX6SLL_PLL1_BYPASS_SRC] = imx_clk_hw_mux("pll1_bypass_src", base + 0x00, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); |
122 | clks[IMX6SLL_PLL2_BYPASS_SRC] = imx_clk_mux("pll2_bypass_src", base + 0x30, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); | 132 | hws[IMX6SLL_PLL2_BYPASS_SRC] = imx_clk_hw_mux("pll2_bypass_src", base + 0x30, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); |
123 | clks[IMX6SLL_PLL3_BYPASS_SRC] = imx_clk_mux("pll3_bypass_src", base + 0x10, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); | 133 | hws[IMX6SLL_PLL3_BYPASS_SRC] = imx_clk_hw_mux("pll3_bypass_src", base + 0x10, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); |
124 | clks[IMX6SLL_PLL4_BYPASS_SRC] = imx_clk_mux("pll4_bypass_src", base + 0x70, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); | 134 | hws[IMX6SLL_PLL4_BYPASS_SRC] = imx_clk_hw_mux("pll4_bypass_src", base + 0x70, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); |
125 | clks[IMX6SLL_PLL5_BYPASS_SRC] = imx_clk_mux("pll5_bypass_src", base + 0xa0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); | 135 | hws[IMX6SLL_PLL5_BYPASS_SRC] = imx_clk_hw_mux("pll5_bypass_src", base + 0xa0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); |
126 | clks[IMX6SLL_PLL6_BYPASS_SRC] = imx_clk_mux("pll6_bypass_src", base + 0xe0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); | 136 | hws[IMX6SLL_PLL6_BYPASS_SRC] = imx_clk_hw_mux("pll6_bypass_src", base + 0xe0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); |
127 | clks[IMX6SLL_PLL7_BYPASS_SRC] = imx_clk_mux("pll7_bypass_src", base + 0x20, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); | 137 | hws[IMX6SLL_PLL7_BYPASS_SRC] = imx_clk_hw_mux("pll7_bypass_src", base + 0x20, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); |
128 | 138 | ||
129 | clks[IMX6SLL_CLK_PLL1] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1", "pll1_bypass_src", base + 0x00, 0x7f); | 139 | hws[IMX6SLL_CLK_PLL1] = imx_clk_hw_pllv3(IMX_PLLV3_SYS, "pll1", "pll1_bypass_src", base + 0x00, 0x7f); |
130 | clks[IMX6SLL_CLK_PLL2] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2", "pll2_bypass_src", base + 0x30, 0x1); | 140 | hws[IMX6SLL_CLK_PLL2] = imx_clk_hw_pllv3(IMX_PLLV3_GENERIC, "pll2", "pll2_bypass_src", base + 0x30, 0x1); |
131 | clks[IMX6SLL_CLK_PLL3] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3", "pll3_bypass_src", base + 0x10, 0x3); | 141 | hws[IMX6SLL_CLK_PLL3] = imx_clk_hw_pllv3(IMX_PLLV3_USB, "pll3", "pll3_bypass_src", base + 0x10, 0x3); |
132 | clks[IMX6SLL_CLK_PLL4] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4", "pll4_bypass_src", base + 0x70, 0x7f); | 142 | hws[IMX6SLL_CLK_PLL4] = imx_clk_hw_pllv3(IMX_PLLV3_AV, "pll4", "pll4_bypass_src", base + 0x70, 0x7f); |
133 | clks[IMX6SLL_CLK_PLL5] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5", "pll5_bypass_src", base + 0xa0, 0x7f); | 143 | hws[IMX6SLL_CLK_PLL5] = imx_clk_hw_pllv3(IMX_PLLV3_AV, "pll5", "pll5_bypass_src", base + 0xa0, 0x7f); |
134 | clks[IMX6SLL_CLK_PLL6] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6", "pll6_bypass_src", base + 0xe0, 0x3); | 144 | hws[IMX6SLL_CLK_PLL6] = imx_clk_hw_pllv3(IMX_PLLV3_ENET, "pll6", "pll6_bypass_src", base + 0xe0, 0x3); |
135 | clks[IMX6SLL_CLK_PLL7] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7", "pll7_bypass_src", base + 0x20, 0x3); | 145 | hws[IMX6SLL_CLK_PLL7] = imx_clk_hw_pllv3(IMX_PLLV3_USB, "pll7", "pll7_bypass_src", base + 0x20, 0x3); |
136 | 146 | ||
137 | clks[IMX6SLL_PLL1_BYPASS] = imx_clk_mux_flags("pll1_bypass", base + 0x00, 16, 1, pll1_bypass_sels, ARRAY_SIZE(pll1_bypass_sels), CLK_SET_RATE_PARENT); | 147 | hws[IMX6SLL_PLL1_BYPASS] = imx_clk_hw_mux_flags("pll1_bypass", base + 0x00, 16, 1, pll1_bypass_sels, ARRAY_SIZE(pll1_bypass_sels), CLK_SET_RATE_PARENT); |
138 | clks[IMX6SLL_PLL2_BYPASS] = imx_clk_mux_flags("pll2_bypass", base + 0x30, 16, 1, pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels), CLK_SET_RATE_PARENT); | 148 | hws[IMX6SLL_PLL2_BYPASS] = imx_clk_hw_mux_flags("pll2_bypass", base + 0x30, 16, 1, pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels), CLK_SET_RATE_PARENT); |
139 | clks[IMX6SLL_PLL3_BYPASS] = imx_clk_mux_flags("pll3_bypass", base + 0x10, 16, 1, pll3_bypass_sels, ARRAY_SIZE(pll3_bypass_sels), CLK_SET_RATE_PARENT); | 149 | hws[IMX6SLL_PLL3_BYPASS] = imx_clk_hw_mux_flags("pll3_bypass", base + 0x10, 16, 1, pll3_bypass_sels, ARRAY_SIZE(pll3_bypass_sels), CLK_SET_RATE_PARENT); |
140 | clks[IMX6SLL_PLL4_BYPASS] = imx_clk_mux_flags("pll4_bypass", base + 0x70, 16, 1, pll4_bypass_sels, ARRAY_SIZE(pll4_bypass_sels), CLK_SET_RATE_PARENT); | 150 | hws[IMX6SLL_PLL4_BYPASS] = imx_clk_hw_mux_flags("pll4_bypass", base + 0x70, 16, 1, pll4_bypass_sels, ARRAY_SIZE(pll4_bypass_sels), CLK_SET_RATE_PARENT); |
141 | clks[IMX6SLL_PLL5_BYPASS] = imx_clk_mux_flags("pll5_bypass", base + 0xa0, 16, 1, pll5_bypass_sels, ARRAY_SIZE(pll5_bypass_sels), CLK_SET_RATE_PARENT); | 151 | hws[IMX6SLL_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); |
142 | clks[IMX6SLL_PLL6_BYPASS] = imx_clk_mux_flags("pll6_bypass", base + 0xe0, 16, 1, pll6_bypass_sels, ARRAY_SIZE(pll6_bypass_sels), CLK_SET_RATE_PARENT); | 152 | hws[IMX6SLL_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); |
143 | clks[IMX6SLL_PLL7_BYPASS] = imx_clk_mux_flags("pll7_bypass", base + 0x20, 16, 1, pll7_bypass_sels, ARRAY_SIZE(pll7_bypass_sels), CLK_SET_RATE_PARENT); | 153 | hws[IMX6SLL_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); |
144 | 154 | ||
145 | clks[IMX6SLL_CLK_PLL1_SYS] = imx_clk_fixed_factor("pll1_sys", "pll1_bypass", 1, 1); | 155 | hws[IMX6SLL_CLK_PLL1_SYS] = imx_clk_hw_fixed_factor("pll1_sys", "pll1_bypass", 1, 1); |
146 | clks[IMX6SLL_CLK_PLL2_BUS] = imx_clk_gate("pll2_bus", "pll2_bypass", base + 0x30, 13); | 156 | hws[IMX6SLL_CLK_PLL2_BUS] = imx_clk_hw_gate("pll2_bus", "pll2_bypass", base + 0x30, 13); |
147 | clks[IMX6SLL_CLK_PLL3_USB_OTG] = imx_clk_gate("pll3_usb_otg", "pll3_bypass", base + 0x10, 13); | 157 | hws[IMX6SLL_CLK_PLL3_USB_OTG] = imx_clk_hw_gate("pll3_usb_otg", "pll3_bypass", base + 0x10, 13); |
148 | clks[IMX6SLL_CLK_PLL4_AUDIO] = imx_clk_gate("pll4_audio", "pll4_bypass", base + 0x70, 13); | 158 | hws[IMX6SLL_CLK_PLL4_AUDIO] = imx_clk_hw_gate("pll4_audio", "pll4_bypass", base + 0x70, 13); |
149 | clks[IMX6SLL_CLK_PLL5_VIDEO] = imx_clk_gate("pll5_video", "pll5_bypass", base + 0xa0, 13); | 159 | hws[IMX6SLL_CLK_PLL5_VIDEO] = imx_clk_hw_gate("pll5_video", "pll5_bypass", base + 0xa0, 13); |
150 | clks[IMX6SLL_CLK_PLL6_ENET] = imx_clk_gate("pll6_enet", "pll6_bypass", base + 0xe0, 13); | 160 | hws[IMX6SLL_CLK_PLL6_ENET] = imx_clk_hw_gate("pll6_enet", "pll6_bypass", base + 0xe0, 13); |
151 | clks[IMX6SLL_CLK_PLL7_USB_HOST] = imx_clk_gate("pll7_usb_host", "pll7_bypass", base + 0x20, 13); | 161 | hws[IMX6SLL_CLK_PLL7_USB_HOST] = imx_clk_hw_gate("pll7_usb_host", "pll7_bypass", base + 0x20, 13); |
152 | 162 | ||
153 | /* | 163 | /* |
154 | * Bit 20 is the reserved and read-only bit, we do this only for: | 164 | * Bit 20 is the reserved and read-only bit, we do this only for: |
@@ -156,209 +166,213 @@ static void __init imx6sll_clocks_init(struct device_node *ccm_node) | |||
156 | * - Keep refcount when do usbphy clk_enable/disable, in that case, | 166 | * - Keep refcount when do usbphy clk_enable/disable, in that case, |
157 | * the clk framework many need to enable/disable usbphy's parent | 167 | * the clk framework many need to enable/disable usbphy's parent |
158 | */ | 168 | */ |
159 | clks[IMX6SLL_CLK_USBPHY1] = imx_clk_gate("usbphy1", "pll3_usb_otg", base + 0x10, 20); | 169 | hws[IMX6SLL_CLK_USBPHY1] = imx_clk_hw_gate("usbphy1", "pll3_usb_otg", base + 0x10, 20); |
160 | clks[IMX6SLL_CLK_USBPHY2] = imx_clk_gate("usbphy2", "pll7_usb_host", base + 0x20, 20); | 170 | hws[IMX6SLL_CLK_USBPHY2] = imx_clk_hw_gate("usbphy2", "pll7_usb_host", base + 0x20, 20); |
161 | 171 | ||
162 | /* | 172 | /* |
163 | * usbphy*_gate needs to be on after system boots up, and software | 173 | * usbphy*_gate needs to be on after system boots up, and software |
164 | * never needs to control it anymore. | 174 | * never needs to control it anymore. |
165 | */ | 175 | */ |
166 | if (IS_ENABLED(CONFIG_USB_MXS_PHY)) { | 176 | if (IS_ENABLED(CONFIG_USB_MXS_PHY)) { |
167 | clks[IMX6SLL_CLK_USBPHY1_GATE] = imx_clk_gate_flags("usbphy1_gate", "dummy", base + 0x10, 6, CLK_IS_CRITICAL); | 177 | hws[IMX6SLL_CLK_USBPHY1_GATE] = imx_clk_hw_gate_flags("usbphy1_gate", "dummy", base + 0x10, 6, CLK_IS_CRITICAL); |
168 | clks[IMX6SLL_CLK_USBPHY2_GATE] = imx_clk_gate_flags("usbphy2_gate", "dummy", base + 0x20, 6, CLK_IS_CRITICAL); | 178 | hws[IMX6SLL_CLK_USBPHY2_GATE] = imx_clk_hw_gate_flags("usbphy2_gate", "dummy", base + 0x20, 6, CLK_IS_CRITICAL); |
169 | } | 179 | } |
170 | 180 | ||
171 | /* name parent_name reg idx */ | 181 | /* name parent_name reg idx */ |
172 | clks[IMX6SLL_CLK_PLL2_PFD0] = imx_clk_pfd("pll2_pfd0_352m", "pll2_bus", base + 0x100, 0); | 182 | hws[IMX6SLL_CLK_PLL2_PFD0] = imx_clk_hw_pfd("pll2_pfd0_352m", "pll2_bus", base + 0x100, 0); |
173 | clks[IMX6SLL_CLK_PLL2_PFD1] = imx_clk_pfd("pll2_pfd1_594m", "pll2_bus", base + 0x100, 1); | 183 | hws[IMX6SLL_CLK_PLL2_PFD1] = imx_clk_hw_pfd("pll2_pfd1_594m", "pll2_bus", base + 0x100, 1); |
174 | clks[IMX6SLL_CLK_PLL2_PFD2] = imx_clk_pfd("pll2_pfd2_396m", "pll2_bus", base + 0x100, 2); | 184 | hws[IMX6SLL_CLK_PLL2_PFD2] = imx_clk_hw_pfd("pll2_pfd2_396m", "pll2_bus", base + 0x100, 2); |
175 | clks[IMX6SLL_CLK_PLL2_PFD3] = imx_clk_pfd("pll2_pfd3_594m", "pll2_bus", base + 0x100, 3); | 185 | hws[IMX6SLL_CLK_PLL2_PFD3] = imx_clk_hw_pfd("pll2_pfd3_594m", "pll2_bus", base + 0x100, 3); |
176 | clks[IMX6SLL_CLK_PLL3_PFD0] = imx_clk_pfd("pll3_pfd0_720m", "pll3_usb_otg", base + 0xf0, 0); | 186 | hws[IMX6SLL_CLK_PLL3_PFD0] = imx_clk_hw_pfd("pll3_pfd0_720m", "pll3_usb_otg", base + 0xf0, 0); |
177 | clks[IMX6SLL_CLK_PLL3_PFD1] = imx_clk_pfd("pll3_pfd1_540m", "pll3_usb_otg", base + 0xf0, 1); | 187 | hws[IMX6SLL_CLK_PLL3_PFD1] = imx_clk_hw_pfd("pll3_pfd1_540m", "pll3_usb_otg", base + 0xf0, 1); |
178 | clks[IMX6SLL_CLK_PLL3_PFD2] = imx_clk_pfd("pll3_pfd2_508m", "pll3_usb_otg", base + 0xf0, 2); | 188 | hws[IMX6SLL_CLK_PLL3_PFD2] = imx_clk_hw_pfd("pll3_pfd2_508m", "pll3_usb_otg", base + 0xf0, 2); |
179 | clks[IMX6SLL_CLK_PLL3_PFD3] = imx_clk_pfd("pll3_pfd3_454m", "pll3_usb_otg", base + 0xf0, 3); | 189 | hws[IMX6SLL_CLK_PLL3_PFD3] = imx_clk_hw_pfd("pll3_pfd3_454m", "pll3_usb_otg", base + 0xf0, 3); |
180 | 190 | ||
181 | clks[IMX6SLL_CLK_PLL4_POST_DIV] = clk_register_divider_table(NULL, "pll4_post_div", "pll4_audio", | 191 | hws[IMX6SLL_CLK_PLL4_POST_DIV] = clk_hw_register_divider_table(NULL, "pll4_post_div", "pll4_audio", |
182 | CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0x70, 19, 2, 0, post_div_table, &imx_ccm_lock); | 192 | CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0x70, 19, 2, 0, post_div_table, &imx_ccm_lock); |
183 | clks[IMX6SLL_CLK_PLL4_AUDIO_DIV] = clk_register_divider(NULL, "pll4_audio_div", "pll4_post_div", | 193 | hws[IMX6SLL_CLK_PLL4_AUDIO_DIV] = clk_hw_register_divider(NULL, "pll4_audio_div", "pll4_post_div", |
184 | CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0x170, 15, 1, 0, &imx_ccm_lock); | 194 | CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0x170, 15, 1, 0, &imx_ccm_lock); |
185 | clks[IMX6SLL_CLK_PLL5_POST_DIV] = clk_register_divider_table(NULL, "pll5_post_div", "pll5_video", | 195 | hws[IMX6SLL_CLK_PLL5_POST_DIV] = clk_hw_register_divider_table(NULL, "pll5_post_div", "pll5_video", |
186 | CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0xa0, 19, 2, 0, post_div_table, &imx_ccm_lock); | 196 | CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0xa0, 19, 2, 0, post_div_table, &imx_ccm_lock); |
187 | clks[IMX6SLL_CLK_PLL5_VIDEO_DIV] = clk_register_divider_table(NULL, "pll5_video_div", "pll5_post_div", | 197 | hws[IMX6SLL_CLK_PLL5_VIDEO_DIV] = clk_hw_register_divider_table(NULL, "pll5_video_div", "pll5_post_div", |
188 | CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0x170, 30, 2, 0, video_div_table, &imx_ccm_lock); | 198 | CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0x170, 30, 2, 0, video_div_table, &imx_ccm_lock); |
189 | 199 | ||
190 | /* name parent_name mult div */ | 200 | /* name parent_name mult div */ |
191 | clks[IMX6SLL_CLK_PLL2_198M] = imx_clk_fixed_factor("pll2_198m", "pll2_pfd2_396m", 1, 2); | 201 | hws[IMX6SLL_CLK_PLL2_198M] = imx_clk_hw_fixed_factor("pll2_198m", "pll2_pfd2_396m", 1, 2); |
192 | clks[IMX6SLL_CLK_PLL3_120M] = imx_clk_fixed_factor("pll3_120m", "pll3_usb_otg", 1, 4); | 202 | hws[IMX6SLL_CLK_PLL3_120M] = imx_clk_hw_fixed_factor("pll3_120m", "pll3_usb_otg", 1, 4); |
193 | clks[IMX6SLL_CLK_PLL3_80M] = imx_clk_fixed_factor("pll3_80m", "pll3_usb_otg", 1, 6); | 203 | hws[IMX6SLL_CLK_PLL3_80M] = imx_clk_hw_fixed_factor("pll3_80m", "pll3_usb_otg", 1, 6); |
194 | clks[IMX6SLL_CLK_PLL3_60M] = imx_clk_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8); | 204 | hws[IMX6SLL_CLK_PLL3_60M] = imx_clk_hw_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8); |
195 | 205 | ||
196 | np = ccm_node; | 206 | np = ccm_node; |
197 | base = of_iomap(np, 0); | 207 | base = of_iomap(np, 0); |
198 | WARN_ON(!base); | 208 | WARN_ON(!base); |
199 | 209 | ||
200 | clks[IMX6SLL_CLK_STEP] = imx_clk_mux("step", base + 0x0c, 8, 1, step_sels, ARRAY_SIZE(step_sels)); | 210 | hws[IMX6SLL_CLK_STEP] = imx_clk_hw_mux("step", base + 0x0c, 8, 1, step_sels, ARRAY_SIZE(step_sels)); |
201 | clks[IMX6SLL_CLK_PLL1_SW] = imx_clk_mux_flags("pll1_sw", base + 0x0c, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels), 0); | 211 | hws[IMX6SLL_CLK_PLL1_SW] = imx_clk_hw_mux_flags("pll1_sw", base + 0x0c, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels), 0); |
202 | clks[IMX6SLL_CLK_AXI_ALT_SEL] = imx_clk_mux("axi_alt_sel", base + 0x14, 7, 1, axi_alt_sels, ARRAY_SIZE(axi_alt_sels)); | 212 | hws[IMX6SLL_CLK_AXI_ALT_SEL] = imx_clk_hw_mux("axi_alt_sel", base + 0x14, 7, 1, axi_alt_sels, ARRAY_SIZE(axi_alt_sels)); |
203 | clks[IMX6SLL_CLK_AXI_SEL] = imx_clk_mux_flags("axi_sel", base + 0x14, 6, 1, axi_sels, ARRAY_SIZE(axi_sels), 0); | 213 | hws[IMX6SLL_CLK_AXI_SEL] = imx_clk_hw_mux_flags("axi_sel", base + 0x14, 6, 1, axi_sels, ARRAY_SIZE(axi_sels), 0); |
204 | clks[IMX6SLL_CLK_PERIPH_PRE] = imx_clk_mux("periph_pre", base + 0x18, 18, 2, periph_pre_sels, ARRAY_SIZE(periph_pre_sels)); | 214 | hws[IMX6SLL_CLK_PERIPH_PRE] = imx_clk_hw_mux("periph_pre", base + 0x18, 18, 2, periph_pre_sels, ARRAY_SIZE(periph_pre_sels)); |
205 | clks[IMX6SLL_CLK_PERIPH2_PRE] = imx_clk_mux("periph2_pre", base + 0x18, 21, 2, periph2_pre_sels, ARRAY_SIZE(periph2_pre_sels)); | 215 | hws[IMX6SLL_CLK_PERIPH2_PRE] = imx_clk_hw_mux("periph2_pre", base + 0x18, 21, 2, periph2_pre_sels, ARRAY_SIZE(periph2_pre_sels)); |
206 | clks[IMX6SLL_CLK_PERIPH_CLK2_SEL] = imx_clk_mux("periph_clk2_sel", base + 0x18, 12, 2, periph_clk2_sels, ARRAY_SIZE(periph_clk2_sels)); | 216 | hws[IMX6SLL_CLK_PERIPH_CLK2_SEL] = imx_clk_hw_mux("periph_clk2_sel", base + 0x18, 12, 2, periph_clk2_sels, ARRAY_SIZE(periph_clk2_sels)); |
207 | clks[IMX6SLL_CLK_PERIPH2_CLK2_SEL] = imx_clk_mux("periph2_clk2_sel", base + 0x18, 20, 1, periph2_clk2_sels, ARRAY_SIZE(periph2_clk2_sels)); | 217 | hws[IMX6SLL_CLK_PERIPH2_CLK2_SEL] = imx_clk_hw_mux("periph2_clk2_sel", base + 0x18, 20, 1, periph2_clk2_sels, ARRAY_SIZE(periph2_clk2_sels)); |
208 | clks[IMX6SLL_CLK_USDHC1_SEL] = imx_clk_mux("usdhc1_sel", base + 0x1c, 16, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels)); | 218 | hws[IMX6SLL_CLK_USDHC1_SEL] = imx_clk_hw_mux("usdhc1_sel", base + 0x1c, 16, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels)); |
209 | clks[IMX6SLL_CLK_USDHC2_SEL] = imx_clk_mux("usdhc2_sel", base + 0x1c, 17, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels)); | 219 | hws[IMX6SLL_CLK_USDHC2_SEL] = imx_clk_hw_mux("usdhc2_sel", base + 0x1c, 17, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels)); |
210 | clks[IMX6SLL_CLK_USDHC3_SEL] = imx_clk_mux("usdhc3_sel", base + 0x1c, 18, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels)); | 220 | hws[IMX6SLL_CLK_USDHC3_SEL] = imx_clk_hw_mux("usdhc3_sel", base + 0x1c, 18, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels)); |
211 | clks[IMX6SLL_CLK_SSI1_SEL] = imx_clk_mux("ssi1_sel", base + 0x1c, 10, 2, ssi_sels, ARRAY_SIZE(ssi_sels)); | 221 | hws[IMX6SLL_CLK_SSI1_SEL] = imx_clk_hw_mux("ssi1_sel", base + 0x1c, 10, 2, ssi_sels, ARRAY_SIZE(ssi_sels)); |
212 | clks[IMX6SLL_CLK_SSI2_SEL] = imx_clk_mux("ssi2_sel", base + 0x1c, 12, 2, ssi_sels, ARRAY_SIZE(ssi_sels)); | 222 | hws[IMX6SLL_CLK_SSI2_SEL] = imx_clk_hw_mux("ssi2_sel", base + 0x1c, 12, 2, ssi_sels, ARRAY_SIZE(ssi_sels)); |
213 | clks[IMX6SLL_CLK_SSI3_SEL] = imx_clk_mux("ssi3_sel", base + 0x1c, 14, 2, ssi_sels, ARRAY_SIZE(ssi_sels)); | 223 | hws[IMX6SLL_CLK_SSI3_SEL] = imx_clk_hw_mux("ssi3_sel", base + 0x1c, 14, 2, ssi_sels, ARRAY_SIZE(ssi_sels)); |
214 | clks[IMX6SLL_CLK_PERCLK_SEL] = imx_clk_mux("perclk_sel", base + 0x1c, 6, 1, perclk_sels, ARRAY_SIZE(perclk_sels)); | 224 | hws[IMX6SLL_CLK_PERCLK_SEL] = imx_clk_hw_mux("perclk_sel", base + 0x1c, 6, 1, perclk_sels, ARRAY_SIZE(perclk_sels)); |
215 | clks[IMX6SLL_CLK_UART_SEL] = imx_clk_mux("uart_sel", base + 0x24, 6, 1, uart_sels, ARRAY_SIZE(uart_sels)); | 225 | hws[IMX6SLL_CLK_UART_SEL] = imx_clk_hw_mux("uart_sel", base + 0x24, 6, 1, uart_sels, ARRAY_SIZE(uart_sels)); |
216 | clks[IMX6SLL_CLK_SPDIF_SEL] = imx_clk_mux("spdif_sel", base + 0x30, 20, 2, spdif_sels, ARRAY_SIZE(spdif_sels)); | 226 | hws[IMX6SLL_CLK_SPDIF_SEL] = imx_clk_hw_mux("spdif_sel", base + 0x30, 20, 2, spdif_sels, ARRAY_SIZE(spdif_sels)); |
217 | clks[IMX6SLL_CLK_EXTERN_AUDIO_SEL] = imx_clk_mux("extern_audio_sel", base + 0x30, 7, 2, spdif_sels, ARRAY_SIZE(spdif_sels)); | 227 | hws[IMX6SLL_CLK_EXTERN_AUDIO_SEL] = imx_clk_hw_mux("extern_audio_sel", base + 0x30, 7, 2, spdif_sels, ARRAY_SIZE(spdif_sels)); |
218 | clks[IMX6SLL_CLK_EPDC_PRE_SEL] = imx_clk_mux("epdc_pre_sel", base + 0x34, 15, 3, epdc_pre_sels, ARRAY_SIZE(epdc_pre_sels)); | 228 | hws[IMX6SLL_CLK_EPDC_PRE_SEL] = imx_clk_hw_mux("epdc_pre_sel", base + 0x34, 15, 3, epdc_pre_sels, ARRAY_SIZE(epdc_pre_sels)); |
219 | clks[IMX6SLL_CLK_EPDC_SEL] = imx_clk_mux("epdc_sel", base + 0x34, 9, 3, epdc_sels, ARRAY_SIZE(epdc_sels)); | 229 | hws[IMX6SLL_CLK_EPDC_SEL] = imx_clk_hw_mux("epdc_sel", base + 0x34, 9, 3, epdc_sels, ARRAY_SIZE(epdc_sels)); |
220 | clks[IMX6SLL_CLK_ECSPI_SEL] = imx_clk_mux("ecspi_sel", base + 0x38, 18, 1, ecspi_sels, ARRAY_SIZE(ecspi_sels)); | 230 | hws[IMX6SLL_CLK_ECSPI_SEL] = imx_clk_hw_mux("ecspi_sel", base + 0x38, 18, 1, ecspi_sels, ARRAY_SIZE(ecspi_sels)); |
221 | clks[IMX6SLL_CLK_LCDIF_PRE_SEL] = imx_clk_mux("lcdif_pre_sel", base + 0x38, 15, 3, lcdif_pre_sels, ARRAY_SIZE(lcdif_pre_sels)); | 231 | hws[IMX6SLL_CLK_LCDIF_PRE_SEL] = imx_clk_hw_mux("lcdif_pre_sel", base + 0x38, 15, 3, lcdif_pre_sels, ARRAY_SIZE(lcdif_pre_sels)); |
222 | clks[IMX6SLL_CLK_LCDIF_SEL] = imx_clk_mux("lcdif_sel", base + 0x38, 9, 3, lcdif_sels, ARRAY_SIZE(lcdif_sels)); | 232 | hws[IMX6SLL_CLK_LCDIF_SEL] = imx_clk_hw_mux("lcdif_sel", base + 0x38, 9, 3, lcdif_sels, ARRAY_SIZE(lcdif_sels)); |
223 | 233 | ||
224 | clks[IMX6SLL_CLK_PERIPH] = imx_clk_busy_mux("periph", base + 0x14, 25, 1, base + 0x48, 5, periph_sels, ARRAY_SIZE(periph_sels)); | 234 | hws[IMX6SLL_CLK_PERIPH] = imx_clk_hw_busy_mux("periph", base + 0x14, 25, 1, base + 0x48, 5, periph_sels, ARRAY_SIZE(periph_sels)); |
225 | clks[IMX6SLL_CLK_PERIPH2] = imx_clk_busy_mux("periph2", base + 0x14, 26, 1, base + 0x48, 3, periph2_sels, ARRAY_SIZE(periph2_sels)); | 235 | hws[IMX6SLL_CLK_PERIPH2] = imx_clk_hw_busy_mux("periph2", base + 0x14, 26, 1, base + 0x48, 3, periph2_sels, ARRAY_SIZE(periph2_sels)); |
226 | 236 | ||
227 | clks[IMX6SLL_CLK_PERIPH_CLK2] = imx_clk_divider("periph_clk2", "periph_clk2_sel", base + 0x14, 27, 3); | 237 | hws[IMX6SLL_CLK_PERIPH_CLK2] = imx_clk_hw_divider("periph_clk2", "periph_clk2_sel", base + 0x14, 27, 3); |
228 | clks[IMX6SLL_CLK_PERIPH2_CLK2] = imx_clk_divider("periph2_clk2", "periph2_clk2_sel", base + 0x14, 0, 3); | 238 | hws[IMX6SLL_CLK_PERIPH2_CLK2] = imx_clk_hw_divider("periph2_clk2", "periph2_clk2_sel", base + 0x14, 0, 3); |
229 | clks[IMX6SLL_CLK_IPG] = imx_clk_divider("ipg", "ahb", base + 0x14, 8, 2); | 239 | hws[IMX6SLL_CLK_IPG] = imx_clk_hw_divider("ipg", "ahb", base + 0x14, 8, 2); |
230 | clks[IMX6SLL_CLK_LCDIF_PODF] = imx_clk_divider("lcdif_podf", "lcdif_pred", base + 0x18, 23, 3); | 240 | hws[IMX6SLL_CLK_LCDIF_PODF] = imx_clk_hw_divider("lcdif_podf", "lcdif_pred", base + 0x18, 23, 3); |
231 | clks[IMX6SLL_CLK_PERCLK] = imx_clk_divider("perclk", "perclk_sel", base + 0x1c, 0, 6); | 241 | hws[IMX6SLL_CLK_PERCLK] = imx_clk_hw_divider("perclk", "perclk_sel", base + 0x1c, 0, 6); |
232 | clks[IMX6SLL_CLK_USDHC3_PODF] = imx_clk_divider("usdhc3_podf", "usdhc3_sel", base + 0x24, 19, 3); | 242 | hws[IMX6SLL_CLK_USDHC3_PODF] = imx_clk_hw_divider("usdhc3_podf", "usdhc3_sel", base + 0x24, 19, 3); |
233 | clks[IMX6SLL_CLK_USDHC2_PODF] = imx_clk_divider("usdhc2_podf", "usdhc2_sel", base + 0x24, 16, 3); | 243 | hws[IMX6SLL_CLK_USDHC2_PODF] = imx_clk_hw_divider("usdhc2_podf", "usdhc2_sel", base + 0x24, 16, 3); |
234 | clks[IMX6SLL_CLK_USDHC1_PODF] = imx_clk_divider("usdhc1_podf", "usdhc1_sel", base + 0x24, 11, 3); | 244 | hws[IMX6SLL_CLK_USDHC1_PODF] = imx_clk_hw_divider("usdhc1_podf", "usdhc1_sel", base + 0x24, 11, 3); |
235 | clks[IMX6SLL_CLK_UART_PODF] = imx_clk_divider("uart_podf", "uart_sel", base + 0x24, 0, 6); | 245 | hws[IMX6SLL_CLK_UART_PODF] = imx_clk_hw_divider("uart_podf", "uart_sel", base + 0x24, 0, 6); |
236 | clks[IMX6SLL_CLK_SSI3_PRED] = imx_clk_divider("ssi3_pred", "ssi3_sel", base + 0x28, 22, 3); | 246 | hws[IMX6SLL_CLK_SSI3_PRED] = imx_clk_hw_divider("ssi3_pred", "ssi3_sel", base + 0x28, 22, 3); |
237 | clks[IMX6SLL_CLK_SSI3_PODF] = imx_clk_divider("ssi3_podf", "ssi3_pred", base + 0x28, 16, 6); | 247 | hws[IMX6SLL_CLK_SSI3_PODF] = imx_clk_hw_divider("ssi3_podf", "ssi3_pred", base + 0x28, 16, 6); |
238 | clks[IMX6SLL_CLK_SSI1_PRED] = imx_clk_divider("ssi1_pred", "ssi1_sel", base + 0x28, 6, 3); | 248 | hws[IMX6SLL_CLK_SSI1_PRED] = imx_clk_hw_divider("ssi1_pred", "ssi1_sel", base + 0x28, 6, 3); |
239 | clks[IMX6SLL_CLK_SSI1_PODF] = imx_clk_divider("ssi1_podf", "ssi1_pred", base + 0x28, 0, 6); | 249 | hws[IMX6SLL_CLK_SSI1_PODF] = imx_clk_hw_divider("ssi1_podf", "ssi1_pred", base + 0x28, 0, 6); |
240 | clks[IMX6SLL_CLK_SSI2_PRED] = imx_clk_divider("ssi2_pred", "ssi2_sel", base + 0x2c, 6, 3); | 250 | hws[IMX6SLL_CLK_SSI2_PRED] = imx_clk_hw_divider("ssi2_pred", "ssi2_sel", base + 0x2c, 6, 3); |
241 | clks[IMX6SLL_CLK_SSI2_PODF] = imx_clk_divider("ssi2_podf", "ssi2_pred", base + 0x2c, 0, 6); | 251 | hws[IMX6SLL_CLK_SSI2_PODF] = imx_clk_hw_divider("ssi2_podf", "ssi2_pred", base + 0x2c, 0, 6); |
242 | clks[IMX6SLL_CLK_SPDIF_PRED] = imx_clk_divider("spdif_pred", "spdif_sel", base + 0x30, 25, 3); | 252 | hws[IMX6SLL_CLK_SPDIF_PRED] = imx_clk_hw_divider("spdif_pred", "spdif_sel", base + 0x30, 25, 3); |
243 | clks[IMX6SLL_CLK_SPDIF_PODF] = imx_clk_divider("spdif_podf", "spdif_pred", base + 0x30, 22, 3); | 253 | hws[IMX6SLL_CLK_SPDIF_PODF] = imx_clk_hw_divider("spdif_podf", "spdif_pred", base + 0x30, 22, 3); |
244 | clks[IMX6SLL_CLK_EXTERN_AUDIO_PRED] = imx_clk_divider("extern_audio_pred", "extern_audio_sel", base + 0x30, 12, 3); | 254 | hws[IMX6SLL_CLK_EXTERN_AUDIO_PRED] = imx_clk_hw_divider("extern_audio_pred", "extern_audio_sel", base + 0x30, 12, 3); |
245 | clks[IMX6SLL_CLK_EXTERN_AUDIO_PODF] = imx_clk_divider("extern_audio_podf", "extern_audio_pred", base + 0x30, 9, 3); | 255 | hws[IMX6SLL_CLK_EXTERN_AUDIO_PODF] = imx_clk_hw_divider("extern_audio_podf", "extern_audio_pred", base + 0x30, 9, 3); |
246 | clks[IMX6SLL_CLK_EPDC_PODF] = imx_clk_divider("epdc_podf", "epdc_pre_sel", base + 0x34, 12, 3); | 256 | hws[IMX6SLL_CLK_EPDC_PODF] = imx_clk_hw_divider("epdc_podf", "epdc_pre_sel", base + 0x34, 12, 3); |
247 | clks[IMX6SLL_CLK_ECSPI_PODF] = imx_clk_divider("ecspi_podf", "ecspi_sel", base + 0x38, 19, 6); | 257 | hws[IMX6SLL_CLK_ECSPI_PODF] = imx_clk_hw_divider("ecspi_podf", "ecspi_sel", base + 0x38, 19, 6); |
248 | clks[IMX6SLL_CLK_LCDIF_PRED] = imx_clk_divider("lcdif_pred", "lcdif_pre_sel", base + 0x38, 12, 3); | 258 | hws[IMX6SLL_CLK_LCDIF_PRED] = imx_clk_hw_divider("lcdif_pred", "lcdif_pre_sel", base + 0x38, 12, 3); |
249 | 259 | ||
250 | clks[IMX6SLL_CLK_ARM] = imx_clk_busy_divider("arm", "pll1_sw", base + 0x10, 0, 3, base + 0x48, 16); | 260 | hws[IMX6SLL_CLK_ARM] = imx_clk_hw_busy_divider("arm", "pll1_sw", base + 0x10, 0, 3, base + 0x48, 16); |
251 | clks[IMX6SLL_CLK_MMDC_PODF] = imx_clk_busy_divider("mmdc_podf", "periph2", base + 0x14, 3, 3, base + 0x48, 2); | 261 | hws[IMX6SLL_CLK_MMDC_PODF] = imx_clk_hw_busy_divider("mmdc_podf", "periph2", base + 0x14, 3, 3, base + 0x48, 2); |
252 | clks[IMX6SLL_CLK_AXI_PODF] = imx_clk_busy_divider("axi", "axi_sel", base + 0x14, 16, 3, base + 0x48, 0); | 262 | hws[IMX6SLL_CLK_AXI_PODF] = imx_clk_hw_busy_divider("axi", "axi_sel", base + 0x14, 16, 3, base + 0x48, 0); |
253 | clks[IMX6SLL_CLK_AHB] = imx_clk_busy_divider("ahb", "periph", base + 0x14, 10, 3, base + 0x48, 1); | 263 | hws[IMX6SLL_CLK_AHB] = imx_clk_hw_busy_divider("ahb", "periph", base + 0x14, 10, 3, base + 0x48, 1); |
254 | 264 | ||
255 | clks[IMX6SLL_CLK_LDB_DI0_DIV_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7); | 265 | hws[IMX6SLL_CLK_LDB_DI0_DIV_3_5] = imx_clk_hw_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7); |
256 | clks[IMX6SLL_CLK_LDB_DI0_DIV_7] = imx_clk_fixed_factor("ldb_di0_div_7", "ldb_di0_sel", 1, 7); | 266 | hws[IMX6SLL_CLK_LDB_DI0_DIV_7] = imx_clk_hw_fixed_factor("ldb_di0_div_7", "ldb_di0_sel", 1, 7); |
257 | clks[IMX6SLL_CLK_LDB_DI1_DIV_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7); | 267 | hws[IMX6SLL_CLK_LDB_DI1_DIV_3_5] = imx_clk_hw_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7); |
258 | clks[IMX6SLL_CLK_LDB_DI1_DIV_7] = imx_clk_fixed_factor("ldb_di1_div_7", "ldb_di1_sel", 1, 7); | 268 | hws[IMX6SLL_CLK_LDB_DI1_DIV_7] = imx_clk_hw_fixed_factor("ldb_di1_div_7", "ldb_di1_sel", 1, 7); |
259 | 269 | ||
260 | clks[IMX6SLL_CLK_LDB_DI0_SEL] = imx_clk_mux("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di0_sels, ARRAY_SIZE(ldb_di0_sels)); | 270 | hws[IMX6SLL_CLK_LDB_DI0_SEL] = imx_clk_hw_mux("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di0_sels, ARRAY_SIZE(ldb_di0_sels)); |
261 | clks[IMX6SLL_CLK_LDB_DI1_SEL] = imx_clk_mux("ldb_di1_sel", base + 0x1c, 7, 3, ldb_di1_sels, ARRAY_SIZE(ldb_di1_sels)); | 271 | hws[IMX6SLL_CLK_LDB_DI1_SEL] = imx_clk_hw_mux("ldb_di1_sel", base + 0x1c, 7, 3, ldb_di1_sels, ARRAY_SIZE(ldb_di1_sels)); |
262 | clks[IMX6SLL_CLK_LDB_DI0_DIV_SEL] = imx_clk_mux("ldb_di0_div_sel", base + 0x20, 10, 1, ldb_di0_div_sels, ARRAY_SIZE(ldb_di0_div_sels)); | 272 | hws[IMX6SLL_CLK_LDB_DI0_DIV_SEL] = imx_clk_hw_mux("ldb_di0_div_sel", base + 0x20, 10, 1, ldb_di0_div_sels, ARRAY_SIZE(ldb_di0_div_sels)); |
263 | clks[IMX6SLL_CLK_LDB_DI1_DIV_SEL] = imx_clk_mux("ldb_di1_div_sel", base + 0x20, 10, 1, ldb_di1_div_sels, ARRAY_SIZE(ldb_di1_div_sels)); | 273 | hws[IMX6SLL_CLK_LDB_DI1_DIV_SEL] = imx_clk_hw_mux("ldb_di1_div_sel", base + 0x20, 10, 1, ldb_di1_div_sels, ARRAY_SIZE(ldb_di1_div_sels)); |
264 | 274 | ||
265 | /* CCGR0 */ | 275 | /* CCGR0 */ |
266 | clks[IMX6SLL_CLK_AIPSTZ1] = imx_clk_gate2_flags("aips_tz1", "ahb", base + 0x68, 0, CLK_IS_CRITICAL); | 276 | hws[IMX6SLL_CLK_AIPSTZ1] = imx_clk_hw_gate2_flags("aips_tz1", "ahb", base + 0x68, 0, CLK_IS_CRITICAL); |
267 | clks[IMX6SLL_CLK_AIPSTZ2] = imx_clk_gate2_flags("aips_tz2", "ahb", base + 0x68, 2, CLK_IS_CRITICAL); | 277 | hws[IMX6SLL_CLK_AIPSTZ2] = imx_clk_hw_gate2_flags("aips_tz2", "ahb", base + 0x68, 2, CLK_IS_CRITICAL); |
268 | clks[IMX6SLL_CLK_DCP] = imx_clk_gate2("dcp", "ahb", base + 0x68, 10); | 278 | hws[IMX6SLL_CLK_DCP] = imx_clk_hw_gate2("dcp", "ahb", base + 0x68, 10); |
269 | clks[IMX6SLL_CLK_UART2_IPG] = imx_clk_gate2("uart2_ipg", "ipg", base + 0x68, 28); | 279 | hws[IMX6SLL_CLK_UART2_IPG] = imx_clk_hw_gate2("uart2_ipg", "ipg", base + 0x68, 28); |
270 | clks[IMX6SLL_CLK_UART2_SERIAL] = imx_clk_gate2("uart2_serial", "uart_podf", base + 0x68, 28); | 280 | hws[IMX6SLL_CLK_UART2_SERIAL] = imx_clk_hw_gate2("uart2_serial", "uart_podf", base + 0x68, 28); |
271 | clks[IMX6SLL_CLK_GPIO2] = imx_clk_gate2("gpio2", "ipg", base + 0x68, 30); | 281 | hws[IMX6SLL_CLK_GPIO2] = imx_clk_hw_gate2("gpio2", "ipg", base + 0x68, 30); |
272 | 282 | ||
273 | /* CCGR1 */ | 283 | /* CCGR1 */ |
274 | clks[IMX6SLL_CLK_ECSPI1] = imx_clk_gate2("ecspi1", "ecspi_podf", base + 0x6c, 0); | 284 | hws[IMX6SLL_CLK_ECSPI1] = imx_clk_hw_gate2("ecspi1", "ecspi_podf", base + 0x6c, 0); |
275 | clks[IMX6SLL_CLK_ECSPI2] = imx_clk_gate2("ecspi2", "ecspi_podf", base + 0x6c, 2); | 285 | hws[IMX6SLL_CLK_ECSPI2] = imx_clk_hw_gate2("ecspi2", "ecspi_podf", base + 0x6c, 2); |
276 | clks[IMX6SLL_CLK_ECSPI3] = imx_clk_gate2("ecspi3", "ecspi_podf", base + 0x6c, 4); | 286 | hws[IMX6SLL_CLK_ECSPI3] = imx_clk_hw_gate2("ecspi3", "ecspi_podf", base + 0x6c, 4); |
277 | clks[IMX6SLL_CLK_ECSPI4] = imx_clk_gate2("ecspi4", "ecspi_podf", base + 0x6c, 6); | 287 | hws[IMX6SLL_CLK_ECSPI4] = imx_clk_hw_gate2("ecspi4", "ecspi_podf", base + 0x6c, 6); |
278 | clks[IMX6SLL_CLK_UART3_IPG] = imx_clk_gate2("uart3_ipg", "ipg", base + 0x6c, 10); | 288 | hws[IMX6SLL_CLK_UART3_IPG] = imx_clk_hw_gate2("uart3_ipg", "ipg", base + 0x6c, 10); |
279 | clks[IMX6SLL_CLK_UART3_SERIAL] = imx_clk_gate2("uart3_serial", "uart_podf", base + 0x6c, 10); | 289 | hws[IMX6SLL_CLK_UART3_SERIAL] = imx_clk_hw_gate2("uart3_serial", "uart_podf", base + 0x6c, 10); |
280 | clks[IMX6SLL_CLK_EPIT1] = imx_clk_gate2("epit1", "perclk", base + 0x6c, 12); | 290 | hws[IMX6SLL_CLK_EPIT1] = imx_clk_hw_gate2("epit1", "perclk", base + 0x6c, 12); |
281 | clks[IMX6SLL_CLK_EPIT2] = imx_clk_gate2("epit2", "perclk", base + 0x6c, 14); | 291 | hws[IMX6SLL_CLK_EPIT2] = imx_clk_hw_gate2("epit2", "perclk", base + 0x6c, 14); |
282 | clks[IMX6SLL_CLK_GPT_BUS] = imx_clk_gate2("gpt1_bus", "perclk", base + 0x6c, 20); | 292 | hws[IMX6SLL_CLK_GPT_BUS] = imx_clk_hw_gate2("gpt1_bus", "perclk", base + 0x6c, 20); |
283 | clks[IMX6SLL_CLK_GPT_SERIAL] = imx_clk_gate2("gpt1_serial", "perclk", base + 0x6c, 22); | 293 | hws[IMX6SLL_CLK_GPT_SERIAL] = imx_clk_hw_gate2("gpt1_serial", "perclk", base + 0x6c, 22); |
284 | clks[IMX6SLL_CLK_UART4_IPG] = imx_clk_gate2("uart4_ipg", "ipg", base + 0x6c, 24); | 294 | hws[IMX6SLL_CLK_UART4_IPG] = imx_clk_hw_gate2("uart4_ipg", "ipg", base + 0x6c, 24); |
285 | clks[IMX6SLL_CLK_UART4_SERIAL] = imx_clk_gate2("uart4_serial", "uart_podf", base + 0x6c, 24); | 295 | hws[IMX6SLL_CLK_UART4_SERIAL] = imx_clk_hw_gate2("uart4_serial", "uart_podf", base + 0x6c, 24); |
286 | clks[IMX6SLL_CLK_GPIO1] = imx_clk_gate2("gpio1", "ipg", base + 0x6c, 26); | 296 | hws[IMX6SLL_CLK_GPIO1] = imx_clk_hw_gate2("gpio1", "ipg", base + 0x6c, 26); |
287 | clks[IMX6SLL_CLK_GPIO5] = imx_clk_gate2("gpio5", "ipg", base + 0x6c, 30); | 297 | hws[IMX6SLL_CLK_GPIO5] = imx_clk_hw_gate2("gpio5", "ipg", base + 0x6c, 30); |
288 | 298 | ||
289 | /* CCGR2 */ | 299 | /* CCGR2 */ |
290 | clks[IMX6SLL_CLK_GPIO6] = imx_clk_gate2("gpio6", "ipg", base + 0x70, 0); | 300 | hws[IMX6SLL_CLK_GPIO6] = imx_clk_hw_gate2("gpio6", "ipg", base + 0x70, 0); |
291 | clks[IMX6SLL_CLK_CSI] = imx_clk_gate2("csi", "axi", base + 0x70, 2); | 301 | hws[IMX6SLL_CLK_CSI] = imx_clk_hw_gate2("csi", "axi", base + 0x70, 2); |
292 | clks[IMX6SLL_CLK_I2C1] = imx_clk_gate2("i2c1", "perclk", base + 0x70, 6); | 302 | hws[IMX6SLL_CLK_I2C1] = imx_clk_hw_gate2("i2c1", "perclk", base + 0x70, 6); |
293 | clks[IMX6SLL_CLK_I2C2] = imx_clk_gate2("i2c2", "perclk", base + 0x70, 8); | 303 | hws[IMX6SLL_CLK_I2C2] = imx_clk_hw_gate2("i2c2", "perclk", base + 0x70, 8); |
294 | clks[IMX6SLL_CLK_I2C3] = imx_clk_gate2("i2c3", "perclk", base + 0x70, 10); | 304 | hws[IMX6SLL_CLK_I2C3] = imx_clk_hw_gate2("i2c3", "perclk", base + 0x70, 10); |
295 | clks[IMX6SLL_CLK_OCOTP] = imx_clk_gate2("ocotp", "ipg", base + 0x70, 12); | 305 | hws[IMX6SLL_CLK_OCOTP] = imx_clk_hw_gate2("ocotp", "ipg", base + 0x70, 12); |
296 | clks[IMX6SLL_CLK_GPIO3] = imx_clk_gate2("gpio3", "ipg", base + 0x70, 26); | 306 | hws[IMX6SLL_CLK_GPIO3] = imx_clk_hw_gate2("gpio3", "ipg", base + 0x70, 26); |
297 | clks[IMX6SLL_CLK_LCDIF_APB] = imx_clk_gate2("lcdif_apb", "axi", base + 0x70, 28); | 307 | hws[IMX6SLL_CLK_LCDIF_APB] = imx_clk_hw_gate2("lcdif_apb", "axi", base + 0x70, 28); |
298 | clks[IMX6SLL_CLK_PXP] = imx_clk_gate2("pxp", "axi", base + 0x70, 30); | 308 | hws[IMX6SLL_CLK_PXP] = imx_clk_hw_gate2("pxp", "axi", base + 0x70, 30); |
299 | 309 | ||
300 | /* CCGR3 */ | 310 | /* CCGR3 */ |
301 | clks[IMX6SLL_CLK_UART5_IPG] = imx_clk_gate2("uart5_ipg", "ipg", base + 0x74, 2); | 311 | hws[IMX6SLL_CLK_UART5_IPG] = imx_clk_hw_gate2("uart5_ipg", "ipg", base + 0x74, 2); |
302 | clks[IMX6SLL_CLK_UART5_SERIAL] = imx_clk_gate2("uart5_serial", "uart_podf", base + 0x74, 2); | 312 | hws[IMX6SLL_CLK_UART5_SERIAL] = imx_clk_hw_gate2("uart5_serial", "uart_podf", base + 0x74, 2); |
303 | clks[IMX6SLL_CLK_EPDC_AXI] = imx_clk_gate2("epdc_aclk", "axi", base + 0x74, 4); | 313 | hws[IMX6SLL_CLK_EPDC_AXI] = imx_clk_hw_gate2("epdc_aclk", "axi", base + 0x74, 4); |
304 | clks[IMX6SLL_CLK_EPDC_PIX] = imx_clk_gate2("epdc_pix", "epdc_podf", base + 0x74, 4); | 314 | hws[IMX6SLL_CLK_EPDC_PIX] = imx_clk_hw_gate2("epdc_pix", "epdc_podf", base + 0x74, 4); |
305 | clks[IMX6SLL_CLK_LCDIF_PIX] = imx_clk_gate2("lcdif_pix", "lcdif_podf", base + 0x74, 10); | 315 | hws[IMX6SLL_CLK_LCDIF_PIX] = imx_clk_hw_gate2("lcdif_pix", "lcdif_podf", base + 0x74, 10); |
306 | clks[IMX6SLL_CLK_GPIO4] = imx_clk_gate2("gpio4", "ipg", base + 0x74, 12); | 316 | hws[IMX6SLL_CLK_GPIO4] = imx_clk_hw_gate2("gpio4", "ipg", base + 0x74, 12); |
307 | clks[IMX6SLL_CLK_WDOG1] = imx_clk_gate2("wdog1", "ipg", base + 0x74, 16); | 317 | hws[IMX6SLL_CLK_WDOG1] = imx_clk_hw_gate2("wdog1", "ipg", base + 0x74, 16); |
308 | clks[IMX6SLL_CLK_MMDC_P0_FAST] = imx_clk_gate_flags("mmdc_p0_fast", "mmdc_podf", base + 0x74, 20, CLK_IS_CRITICAL); | 318 | hws[IMX6SLL_CLK_MMDC_P0_FAST] = imx_clk_hw_gate_flags("mmdc_p0_fast", "mmdc_podf", base + 0x74, 20, CLK_IS_CRITICAL); |
309 | clks[IMX6SLL_CLK_MMDC_P0_IPG] = imx_clk_gate2_flags("mmdc_p0_ipg", "ipg", base + 0x74, 24, CLK_IS_CRITICAL); | 319 | hws[IMX6SLL_CLK_MMDC_P0_IPG] = imx_clk_hw_gate2_flags("mmdc_p0_ipg", "ipg", base + 0x74, 24, CLK_IS_CRITICAL); |
310 | clks[IMX6SLL_CLK_MMDC_P1_IPG] = imx_clk_gate2("mmdc_p1_ipg", "ipg", base + 0x74, 26); | 320 | hws[IMX6SLL_CLK_MMDC_P1_IPG] = imx_clk_hw_gate2_flags("mmdc_p1_ipg", "ipg", base + 0x74, 26, CLK_IS_CRITICAL); |
311 | clks[IMX6SLL_CLK_OCRAM] = imx_clk_gate_flags("ocram","ahb", base + 0x74, 28, CLK_IS_CRITICAL); | 321 | hws[IMX6SLL_CLK_OCRAM] = imx_clk_hw_gate_flags("ocram", "ahb", base + 0x74, 28, CLK_IS_CRITICAL); |
312 | 322 | ||
313 | /* CCGR4 */ | 323 | /* CCGR4 */ |
314 | clks[IMX6SLL_CLK_PWM1] = imx_clk_gate2("pwm1", "perclk", base + 0x78, 16); | 324 | hws[IMX6SLL_CLK_PWM1] = imx_clk_hw_gate2("pwm1", "perclk", base + 0x78, 16); |
315 | clks[IMX6SLL_CLK_PWM2] = imx_clk_gate2("pwm2", "perclk", base + 0x78, 18); | 325 | hws[IMX6SLL_CLK_PWM2] = imx_clk_hw_gate2("pwm2", "perclk", base + 0x78, 18); |
316 | clks[IMX6SLL_CLK_PWM3] = imx_clk_gate2("pwm3", "perclk", base + 0x78, 20); | 326 | hws[IMX6SLL_CLK_PWM3] = imx_clk_hw_gate2("pwm3", "perclk", base + 0x78, 20); |
317 | clks[IMX6SLL_CLK_PWM4] = imx_clk_gate2("pwm4", "perclk", base + 0x78, 22); | 327 | hws[IMX6SLL_CLK_PWM4] = imx_clk_hw_gate2("pwm4", "perclk", base + 0x78, 22); |
318 | 328 | ||
319 | /* CCGR5 */ | 329 | /* CCGR5 */ |
320 | clks[IMX6SLL_CLK_ROM] = imx_clk_gate2_flags("rom", "ahb", base + 0x7c, 0, CLK_IS_CRITICAL); | 330 | hws[IMX6SLL_CLK_ROM] = imx_clk_hw_gate2_flags("rom", "ahb", base + 0x7c, 0, CLK_IS_CRITICAL); |
321 | clks[IMX6SLL_CLK_SDMA] = imx_clk_gate2("sdma", "ahb", base + 0x7c, 6); | 331 | hws[IMX6SLL_CLK_SDMA] = imx_clk_hw_gate2("sdma", "ahb", base + 0x7c, 6); |
322 | clks[IMX6SLL_CLK_WDOG2] = imx_clk_gate2("wdog2", "ipg", base + 0x7c, 10); | 332 | hws[IMX6SLL_CLK_WDOG2] = imx_clk_hw_gate2("wdog2", "ipg", base + 0x7c, 10); |
323 | clks[IMX6SLL_CLK_SPBA] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12); | 333 | hws[IMX6SLL_CLK_SPBA] = imx_clk_hw_gate2("spba", "ipg", base + 0x7c, 12); |
324 | clks[IMX6SLL_CLK_EXTERN_AUDIO] = imx_clk_gate2_shared("extern_audio", "extern_audio_podf", base + 0x7c, 14, &share_count_audio); | 334 | hws[IMX6SLL_CLK_EXTERN_AUDIO] = imx_clk_hw_gate2_shared("extern_audio", "extern_audio_podf", base + 0x7c, 14, &share_count_audio); |
325 | clks[IMX6SLL_CLK_SPDIF] = imx_clk_gate2_shared("spdif", "spdif_podf", base + 0x7c, 14, &share_count_audio); | 335 | hws[IMX6SLL_CLK_SPDIF] = imx_clk_hw_gate2_shared("spdif", "spdif_podf", base + 0x7c, 14, &share_count_audio); |
326 | clks[IMX6SLL_CLK_SPDIF_GCLK] = imx_clk_gate2_shared("spdif_gclk", "ipg", base + 0x7c, 14, &share_count_audio); | 336 | hws[IMX6SLL_CLK_SPDIF_GCLK] = imx_clk_hw_gate2_shared("spdif_gclk", "ipg", base + 0x7c, 14, &share_count_audio); |
327 | clks[IMX6SLL_CLK_SSI1] = imx_clk_gate2_shared("ssi1", "ssi1_podf", base + 0x7c, 18, &share_count_ssi1); | 337 | hws[IMX6SLL_CLK_SSI1] = imx_clk_hw_gate2_shared("ssi1", "ssi1_podf", base + 0x7c, 18, &share_count_ssi1); |
328 | clks[IMX6SLL_CLK_SSI1_IPG] = imx_clk_gate2_shared("ssi1_ipg", "ipg", base + 0x7c, 18, &share_count_ssi1); | 338 | hws[IMX6SLL_CLK_SSI1_IPG] = imx_clk_hw_gate2_shared("ssi1_ipg", "ipg", base + 0x7c, 18, &share_count_ssi1); |
329 | clks[IMX6SLL_CLK_SSI2] = imx_clk_gate2_shared("ssi2", "ssi2_podf", base + 0x7c, 20, &share_count_ssi2); | 339 | hws[IMX6SLL_CLK_SSI2] = imx_clk_hw_gate2_shared("ssi2", "ssi2_podf", base + 0x7c, 20, &share_count_ssi2); |
330 | clks[IMX6SLL_CLK_SSI2_IPG] = imx_clk_gate2_shared("ssi2_ipg", "ipg", base + 0x7c, 20, &share_count_ssi2); | 340 | hws[IMX6SLL_CLK_SSI2_IPG] = imx_clk_hw_gate2_shared("ssi2_ipg", "ipg", base + 0x7c, 20, &share_count_ssi2); |
331 | clks[IMX6SLL_CLK_SSI3] = imx_clk_gate2_shared("ssi3", "ssi3_podf", base + 0x7c, 22, &share_count_ssi3); | 341 | hws[IMX6SLL_CLK_SSI3] = imx_clk_hw_gate2_shared("ssi3", "ssi3_podf", base + 0x7c, 22, &share_count_ssi3); |
332 | clks[IMX6SLL_CLK_SSI3_IPG] = imx_clk_gate2_shared("ssi3_ipg", "ipg", base + 0x7c, 22, &share_count_ssi3); | 342 | hws[IMX6SLL_CLK_SSI3_IPG] = imx_clk_hw_gate2_shared("ssi3_ipg", "ipg", base + 0x7c, 22, &share_count_ssi3); |
333 | clks[IMX6SLL_CLK_UART1_IPG] = imx_clk_gate2("uart1_ipg", "ipg", base + 0x7c, 24); | 343 | hws[IMX6SLL_CLK_UART1_IPG] = imx_clk_hw_gate2("uart1_ipg", "ipg", base + 0x7c, 24); |
334 | clks[IMX6SLL_CLK_UART1_SERIAL] = imx_clk_gate2("uart1_serial", "uart_podf", base + 0x7c, 24); | 344 | hws[IMX6SLL_CLK_UART1_SERIAL] = imx_clk_hw_gate2("uart1_serial", "uart_podf", base + 0x7c, 24); |
335 | 345 | ||
336 | /* CCGR6 */ | 346 | /* CCGR6 */ |
337 | clks[IMX6SLL_CLK_USBOH3] = imx_clk_gate2("usboh3", "ipg", base + 0x80, 0); | 347 | hws[IMX6SLL_CLK_USBOH3] = imx_clk_hw_gate2("usboh3", "ipg", base + 0x80, 0); |
338 | clks[IMX6SLL_CLK_USDHC1] = imx_clk_gate2("usdhc1", "usdhc1_podf", base + 0x80, 2); | 348 | hws[IMX6SLL_CLK_USDHC1] = imx_clk_hw_gate2("usdhc1", "usdhc1_podf", base + 0x80, 2); |
339 | clks[IMX6SLL_CLK_USDHC2] = imx_clk_gate2("usdhc2", "usdhc2_podf", base + 0x80, 4); | 349 | hws[IMX6SLL_CLK_USDHC2] = imx_clk_hw_gate2("usdhc2", "usdhc2_podf", base + 0x80, 4); |
340 | clks[IMX6SLL_CLK_USDHC3] = imx_clk_gate2("usdhc3", "usdhc3_podf", base + 0x80, 6); | 350 | hws[IMX6SLL_CLK_USDHC3] = imx_clk_hw_gate2("usdhc3", "usdhc3_podf", base + 0x80, 6); |
341 | 351 | ||
342 | /* mask handshake of mmdc */ | 352 | /* mask handshake of mmdc */ |
343 | writel_relaxed(BM_CCM_CCDR_MMDC_CH0_MASK, base + 0x4); | 353 | imx_mmdc_mask_handshake(base, 0); |
344 | 354 | ||
345 | imx_check_clocks(clks, ARRAY_SIZE(clks)); | 355 | imx_check_clk_hws(hws, IMX6SLL_CLK_END); |
346 | 356 | ||
347 | clk_data.clks = clks; | 357 | of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data); |
348 | clk_data.clk_num = ARRAY_SIZE(clks); | 358 | |
349 | of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); | 359 | for (i = 0; i < ARRAY_SIZE(uart_clk_ids); i++) { |
360 | int index = uart_clk_ids[i]; | ||
361 | |||
362 | uart_clks[i] = &hws[index]->clk; | ||
363 | } | ||
350 | 364 | ||
351 | imx_register_uart_clocks(uart_clks); | 365 | imx_register_uart_clocks(uart_clks); |
352 | 366 | ||
353 | /* Lower the AHB clock rate before changing the clock source. */ | 367 | /* Lower the AHB clock rate before changing the clock source. */ |
354 | clk_set_rate(clks[IMX6SLL_CLK_AHB], 99000000); | 368 | clk_set_rate(hws[IMX6SLL_CLK_AHB]->clk, 99000000); |
355 | 369 | ||
356 | /* Change periph_pre clock to pll2_bus to adjust AXI rate to 264MHz */ | 370 | /* Change periph_pre clock to pll2_bus to adjust AXI rate to 264MHz */ |
357 | clk_set_parent(clks[IMX6SLL_CLK_PERIPH_CLK2_SEL], clks[IMX6SLL_CLK_PLL3_USB_OTG]); | 371 | clk_set_parent(hws[IMX6SLL_CLK_PERIPH_CLK2_SEL]->clk, hws[IMX6SLL_CLK_PLL3_USB_OTG]->clk); |
358 | clk_set_parent(clks[IMX6SLL_CLK_PERIPH], clks[IMX6SLL_CLK_PERIPH_CLK2]); | 372 | clk_set_parent(hws[IMX6SLL_CLK_PERIPH]->clk, hws[IMX6SLL_CLK_PERIPH_CLK2]->clk); |
359 | clk_set_parent(clks[IMX6SLL_CLK_PERIPH_PRE], clks[IMX6SLL_CLK_PLL2_BUS]); | 373 | clk_set_parent(hws[IMX6SLL_CLK_PERIPH_PRE]->clk, hws[IMX6SLL_CLK_PLL2_BUS]->clk); |
360 | clk_set_parent(clks[IMX6SLL_CLK_PERIPH], clks[IMX6SLL_CLK_PERIPH_PRE]); | 374 | clk_set_parent(hws[IMX6SLL_CLK_PERIPH]->clk, hws[IMX6SLL_CLK_PERIPH_PRE]->clk); |
361 | 375 | ||
362 | clk_set_rate(clks[IMX6SLL_CLK_AHB], 132000000); | 376 | clk_set_rate(hws[IMX6SLL_CLK_AHB]->clk, 132000000); |
363 | } | 377 | } |
364 | CLK_OF_DECLARE_DRIVER(imx6sll, "fsl,imx6sll-ccm", imx6sll_clocks_init); | 378 | CLK_OF_DECLARE_DRIVER(imx6sll, "fsl,imx6sll-ccm", imx6sll_clocks_init); |
diff --git a/drivers/clk/imx/clk-imx6sx.c b/drivers/clk/imx/clk-imx6sx.c index d243e3483e24..c4685c01929a 100644 --- a/drivers/clk/imx/clk-imx6sx.c +++ b/drivers/clk/imx/clk-imx6sx.c | |||
@@ -6,6 +6,7 @@ | |||
6 | #include <dt-bindings/clock/imx6sx-clock.h> | 6 | #include <dt-bindings/clock/imx6sx-clock.h> |
7 | #include <linux/clk.h> | 7 | #include <linux/clk.h> |
8 | #include <linux/clkdev.h> | 8 | #include <linux/clkdev.h> |
9 | #include <linux/clk-provider.h> | ||
9 | #include <linux/err.h> | 10 | #include <linux/err.h> |
10 | #include <linux/init.h> | 11 | #include <linux/init.h> |
11 | #include <linux/io.h> | 12 | #include <linux/io.h> |
@@ -16,9 +17,6 @@ | |||
16 | 17 | ||
17 | #include "clk.h" | 18 | #include "clk.h" |
18 | 19 | ||
19 | #define CCDR 0x4 | ||
20 | #define BM_CCM_CCDR_MMDC_CH0_MASK (0x2 << 16) | ||
21 | |||
22 | static const char *step_sels[] = { "osc", "pll2_pfd2_396m", }; | 20 | static const char *step_sels[] = { "osc", "pll2_pfd2_396m", }; |
23 | static const char *pll1_sw_sels[] = { "pll1_sys", "step", }; | 21 | static const char *pll1_sw_sels[] = { "pll1_sys", "step", }; |
24 | static const char *periph_pre_sels[] = { "pll2_bus", "pll2_pfd2_396m", "pll2_pfd0_352m", "pll2_198m", }; | 22 | static const char *periph_pre_sels[] = { "pll2_bus", "pll2_pfd2_396m", "pll2_pfd0_352m", "pll2_198m", }; |
@@ -83,8 +81,8 @@ static const char *pll5_bypass_sels[] = { "pll5", "pll5_bypass_src", }; | |||
83 | static const char *pll6_bypass_sels[] = { "pll6", "pll6_bypass_src", }; | 81 | static const char *pll6_bypass_sels[] = { "pll6", "pll6_bypass_src", }; |
84 | static const char *pll7_bypass_sels[] = { "pll7", "pll7_bypass_src", }; | 82 | static const char *pll7_bypass_sels[] = { "pll7", "pll7_bypass_src", }; |
85 | 83 | ||
86 | static struct clk *clks[IMX6SX_CLK_CLK_END]; | 84 | static struct clk_hw **hws; |
87 | static struct clk_onecell_data clk_data; | 85 | static struct clk_hw_onecell_data *clk_hw_data; |
88 | 86 | ||
89 | static const struct clk_div_table clk_enet_ref_table[] = { | 87 | static const struct clk_div_table clk_enet_ref_table[] = { |
90 | { .val = 0, .div = 20, }, | 88 | { .val = 0, .div = 20, }, |
@@ -118,76 +116,86 @@ static u32 share_count_ssi3; | |||
118 | static u32 share_count_sai1; | 116 | static u32 share_count_sai1; |
119 | static u32 share_count_sai2; | 117 | static u32 share_count_sai2; |
120 | 118 | ||
121 | static struct clk ** const uart_clks[] __initconst = { | 119 | static const int uart_clk_ids[] __initconst = { |
122 | &clks[IMX6SX_CLK_UART_IPG], | 120 | IMX6SX_CLK_UART_IPG, |
123 | &clks[IMX6SX_CLK_UART_SERIAL], | 121 | IMX6SX_CLK_UART_SERIAL, |
124 | NULL | ||
125 | }; | 122 | }; |
126 | 123 | ||
124 | static struct clk **uart_clks[ARRAY_SIZE(uart_clk_ids) + 1] __initdata; | ||
125 | |||
127 | static void __init imx6sx_clocks_init(struct device_node *ccm_node) | 126 | static void __init imx6sx_clocks_init(struct device_node *ccm_node) |
128 | { | 127 | { |
129 | struct device_node *np; | 128 | struct device_node *np; |
130 | void __iomem *base; | 129 | void __iomem *base; |
130 | int i; | ||
131 | |||
132 | clk_hw_data = kzalloc(struct_size(clk_hw_data, hws, | ||
133 | IMX6SX_CLK_CLK_END), GFP_KERNEL); | ||
134 | if (WARN_ON(!clk_hw_data)) | ||
135 | return; | ||
136 | |||
137 | clk_hw_data->num = IMX6SX_CLK_CLK_END; | ||
138 | hws = clk_hw_data->hws; | ||
131 | 139 | ||
132 | clks[IMX6SX_CLK_DUMMY] = imx_clk_fixed("dummy", 0); | 140 | hws[IMX6SX_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0); |
133 | 141 | ||
134 | clks[IMX6SX_CLK_CKIL] = of_clk_get_by_name(ccm_node, "ckil"); | 142 | hws[IMX6SX_CLK_CKIL] = __clk_get_hw(of_clk_get_by_name(ccm_node, "ckil")); |
135 | clks[IMX6SX_CLK_OSC] = of_clk_get_by_name(ccm_node, "osc"); | 143 | hws[IMX6SX_CLK_OSC] = __clk_get_hw(of_clk_get_by_name(ccm_node, "osc")); |
136 | 144 | ||
137 | /* ipp_di clock is external input */ | 145 | /* ipp_di clock is external input */ |
138 | clks[IMX6SX_CLK_IPP_DI0] = of_clk_get_by_name(ccm_node, "ipp_di0"); | 146 | hws[IMX6SX_CLK_IPP_DI0] = __clk_get_hw(of_clk_get_by_name(ccm_node, "ipp_di0")); |
139 | clks[IMX6SX_CLK_IPP_DI1] = of_clk_get_by_name(ccm_node, "ipp_di1"); | 147 | hws[IMX6SX_CLK_IPP_DI1] = __clk_get_hw(of_clk_get_by_name(ccm_node, "ipp_di1")); |
140 | 148 | ||
141 | /* Clock source from external clock via CLK1/2 PAD */ | 149 | /* Clock source from external clock via CLK1/2 PAD */ |
142 | clks[IMX6SX_CLK_ANACLK1] = of_clk_get_by_name(ccm_node, "anaclk1"); | 150 | hws[IMX6SX_CLK_ANACLK1] = __clk_get_hw(of_clk_get_by_name(ccm_node, "anaclk1")); |
143 | clks[IMX6SX_CLK_ANACLK2] = of_clk_get_by_name(ccm_node, "anaclk2"); | 151 | hws[IMX6SX_CLK_ANACLK2] = __clk_get_hw(of_clk_get_by_name(ccm_node, "anaclk2")); |
144 | 152 | ||
145 | np = of_find_compatible_node(NULL, NULL, "fsl,imx6sx-anatop"); | 153 | np = of_find_compatible_node(NULL, NULL, "fsl,imx6sx-anatop"); |
146 | base = of_iomap(np, 0); | 154 | base = of_iomap(np, 0); |
147 | WARN_ON(!base); | 155 | WARN_ON(!base); |
148 | of_node_put(np); | 156 | of_node_put(np); |
149 | 157 | ||
150 | clks[IMX6SX_PLL1_BYPASS_SRC] = imx_clk_mux("pll1_bypass_src", base + 0x00, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); | 158 | hws[IMX6SX_PLL1_BYPASS_SRC] = imx_clk_hw_mux("pll1_bypass_src", base + 0x00, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); |
151 | clks[IMX6SX_PLL2_BYPASS_SRC] = imx_clk_mux("pll2_bypass_src", base + 0x30, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); | 159 | hws[IMX6SX_PLL2_BYPASS_SRC] = imx_clk_hw_mux("pll2_bypass_src", base + 0x30, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); |
152 | clks[IMX6SX_PLL3_BYPASS_SRC] = imx_clk_mux("pll3_bypass_src", base + 0x10, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); | 160 | hws[IMX6SX_PLL3_BYPASS_SRC] = imx_clk_hw_mux("pll3_bypass_src", base + 0x10, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); |
153 | clks[IMX6SX_PLL4_BYPASS_SRC] = imx_clk_mux("pll4_bypass_src", base + 0x70, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); | 161 | hws[IMX6SX_PLL4_BYPASS_SRC] = imx_clk_hw_mux("pll4_bypass_src", base + 0x70, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); |
154 | clks[IMX6SX_PLL5_BYPASS_SRC] = imx_clk_mux("pll5_bypass_src", base + 0xa0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); | 162 | hws[IMX6SX_PLL5_BYPASS_SRC] = imx_clk_hw_mux("pll5_bypass_src", base + 0xa0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); |
155 | clks[IMX6SX_PLL6_BYPASS_SRC] = imx_clk_mux("pll6_bypass_src", base + 0xe0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); | 163 | hws[IMX6SX_PLL6_BYPASS_SRC] = imx_clk_hw_mux("pll6_bypass_src", base + 0xe0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); |
156 | clks[IMX6SX_PLL7_BYPASS_SRC] = imx_clk_mux("pll7_bypass_src", base + 0x20, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); | 164 | hws[IMX6SX_PLL7_BYPASS_SRC] = imx_clk_hw_mux("pll7_bypass_src", base + 0x20, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); |
157 | 165 | ||
158 | /* type name parent_name base div_mask */ | 166 | /* type name parent_name base div_mask */ |
159 | clks[IMX6SX_CLK_PLL1] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1", "osc", base + 0x00, 0x7f); | 167 | hws[IMX6SX_CLK_PLL1] = imx_clk_hw_pllv3(IMX_PLLV3_SYS, "pll1", "osc", base + 0x00, 0x7f); |
160 | clks[IMX6SX_CLK_PLL2] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2", "osc", base + 0x30, 0x1); | 168 | hws[IMX6SX_CLK_PLL2] = imx_clk_hw_pllv3(IMX_PLLV3_GENERIC, "pll2", "osc", base + 0x30, 0x1); |
161 | clks[IMX6SX_CLK_PLL3] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3", "osc", base + 0x10, 0x3); | 169 | hws[IMX6SX_CLK_PLL3] = imx_clk_hw_pllv3(IMX_PLLV3_USB, "pll3", "osc", base + 0x10, 0x3); |
162 | clks[IMX6SX_CLK_PLL4] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4", "osc", base + 0x70, 0x7f); | 170 | hws[IMX6SX_CLK_PLL4] = imx_clk_hw_pllv3(IMX_PLLV3_AV, "pll4", "osc", base + 0x70, 0x7f); |
163 | clks[IMX6SX_CLK_PLL5] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5", "osc", base + 0xa0, 0x7f); | 171 | hws[IMX6SX_CLK_PLL5] = imx_clk_hw_pllv3(IMX_PLLV3_AV, "pll5", "osc", base + 0xa0, 0x7f); |
164 | clks[IMX6SX_CLK_PLL6] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6", "osc", base + 0xe0, 0x3); | 172 | hws[IMX6SX_CLK_PLL6] = imx_clk_hw_pllv3(IMX_PLLV3_ENET, "pll6", "osc", base + 0xe0, 0x3); |
165 | clks[IMX6SX_CLK_PLL7] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7", "osc", base + 0x20, 0x3); | 173 | hws[IMX6SX_CLK_PLL7] = imx_clk_hw_pllv3(IMX_PLLV3_USB, "pll7", "osc", base + 0x20, 0x3); |
166 | 174 | ||
167 | clks[IMX6SX_PLL1_BYPASS] = imx_clk_mux_flags("pll1_bypass", base + 0x00, 16, 1, pll1_bypass_sels, ARRAY_SIZE(pll1_bypass_sels), CLK_SET_RATE_PARENT); | 175 | hws[IMX6SX_PLL1_BYPASS] = imx_clk_hw_mux_flags("pll1_bypass", base + 0x00, 16, 1, pll1_bypass_sels, ARRAY_SIZE(pll1_bypass_sels), CLK_SET_RATE_PARENT); |
168 | clks[IMX6SX_PLL2_BYPASS] = imx_clk_mux_flags("pll2_bypass", base + 0x30, 16, 1, pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels), CLK_SET_RATE_PARENT); | 176 | hws[IMX6SX_PLL2_BYPASS] = imx_clk_hw_mux_flags("pll2_bypass", base + 0x30, 16, 1, pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels), CLK_SET_RATE_PARENT); |
169 | clks[IMX6SX_PLL3_BYPASS] = imx_clk_mux_flags("pll3_bypass", base + 0x10, 16, 1, pll3_bypass_sels, ARRAY_SIZE(pll3_bypass_sels), CLK_SET_RATE_PARENT); | 177 | hws[IMX6SX_PLL3_BYPASS] = imx_clk_hw_mux_flags("pll3_bypass", base + 0x10, 16, 1, pll3_bypass_sels, ARRAY_SIZE(pll3_bypass_sels), CLK_SET_RATE_PARENT); |
170 | clks[IMX6SX_PLL4_BYPASS] = imx_clk_mux_flags("pll4_bypass", base + 0x70, 16, 1, pll4_bypass_sels, ARRAY_SIZE(pll4_bypass_sels), CLK_SET_RATE_PARENT); | 178 | hws[IMX6SX_PLL4_BYPASS] = imx_clk_hw_mux_flags("pll4_bypass", base + 0x70, 16, 1, pll4_bypass_sels, ARRAY_SIZE(pll4_bypass_sels), CLK_SET_RATE_PARENT); |
171 | clks[IMX6SX_PLL5_BYPASS] = imx_clk_mux_flags("pll5_bypass", base + 0xa0, 16, 1, pll5_bypass_sels, ARRAY_SIZE(pll5_bypass_sels), CLK_SET_RATE_PARENT); | 179 | hws[IMX6SX_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); |
172 | clks[IMX6SX_PLL6_BYPASS] = imx_clk_mux_flags("pll6_bypass", base + 0xe0, 16, 1, pll6_bypass_sels, ARRAY_SIZE(pll6_bypass_sels), CLK_SET_RATE_PARENT); | 180 | hws[IMX6SX_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); |
173 | clks[IMX6SX_PLL7_BYPASS] = imx_clk_mux_flags("pll7_bypass", base + 0x20, 16, 1, pll7_bypass_sels, ARRAY_SIZE(pll7_bypass_sels), CLK_SET_RATE_PARENT); | 181 | hws[IMX6SX_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); |
174 | 182 | ||
175 | /* Do not bypass PLLs initially */ | 183 | /* Do not bypass PLLs initially */ |
176 | clk_set_parent(clks[IMX6SX_PLL1_BYPASS], clks[IMX6SX_CLK_PLL1]); | 184 | clk_set_parent(hws[IMX6SX_PLL1_BYPASS]->clk, hws[IMX6SX_CLK_PLL1]->clk); |
177 | clk_set_parent(clks[IMX6SX_PLL2_BYPASS], clks[IMX6SX_CLK_PLL2]); | 185 | clk_set_parent(hws[IMX6SX_PLL2_BYPASS]->clk, hws[IMX6SX_CLK_PLL2]->clk); |
178 | clk_set_parent(clks[IMX6SX_PLL3_BYPASS], clks[IMX6SX_CLK_PLL3]); | 186 | clk_set_parent(hws[IMX6SX_PLL3_BYPASS]->clk, hws[IMX6SX_CLK_PLL3]->clk); |
179 | clk_set_parent(clks[IMX6SX_PLL4_BYPASS], clks[IMX6SX_CLK_PLL4]); | 187 | clk_set_parent(hws[IMX6SX_PLL4_BYPASS]->clk, hws[IMX6SX_CLK_PLL4]->clk); |
180 | clk_set_parent(clks[IMX6SX_PLL5_BYPASS], clks[IMX6SX_CLK_PLL5]); | 188 | clk_set_parent(hws[IMX6SX_PLL5_BYPASS]->clk, hws[IMX6SX_CLK_PLL5]->clk); |
181 | clk_set_parent(clks[IMX6SX_PLL6_BYPASS], clks[IMX6SX_CLK_PLL6]); | 189 | clk_set_parent(hws[IMX6SX_PLL6_BYPASS]->clk, hws[IMX6SX_CLK_PLL6]->clk); |
182 | clk_set_parent(clks[IMX6SX_PLL7_BYPASS], clks[IMX6SX_CLK_PLL7]); | 190 | clk_set_parent(hws[IMX6SX_PLL7_BYPASS]->clk, hws[IMX6SX_CLK_PLL7]->clk); |
183 | 191 | ||
184 | clks[IMX6SX_CLK_PLL1_SYS] = imx_clk_gate("pll1_sys", "pll1_bypass", base + 0x00, 13); | 192 | hws[IMX6SX_CLK_PLL1_SYS] = imx_clk_hw_gate("pll1_sys", "pll1_bypass", base + 0x00, 13); |
185 | clks[IMX6SX_CLK_PLL2_BUS] = imx_clk_gate("pll2_bus", "pll2_bypass", base + 0x30, 13); | 193 | hws[IMX6SX_CLK_PLL2_BUS] = imx_clk_hw_gate("pll2_bus", "pll2_bypass", base + 0x30, 13); |
186 | clks[IMX6SX_CLK_PLL3_USB_OTG] = imx_clk_gate("pll3_usb_otg", "pll3_bypass", base + 0x10, 13); | 194 | hws[IMX6SX_CLK_PLL3_USB_OTG] = imx_clk_hw_gate("pll3_usb_otg", "pll3_bypass", base + 0x10, 13); |
187 | clks[IMX6SX_CLK_PLL4_AUDIO] = imx_clk_gate("pll4_audio", "pll4_bypass", base + 0x70, 13); | 195 | hws[IMX6SX_CLK_PLL4_AUDIO] = imx_clk_hw_gate("pll4_audio", "pll4_bypass", base + 0x70, 13); |
188 | clks[IMX6SX_CLK_PLL5_VIDEO] = imx_clk_gate("pll5_video", "pll5_bypass", base + 0xa0, 13); | 196 | hws[IMX6SX_CLK_PLL5_VIDEO] = imx_clk_hw_gate("pll5_video", "pll5_bypass", base + 0xa0, 13); |
189 | clks[IMX6SX_CLK_PLL6_ENET] = imx_clk_gate("pll6_enet", "pll6_bypass", base + 0xe0, 13); | 197 | hws[IMX6SX_CLK_PLL6_ENET] = imx_clk_hw_gate("pll6_enet", "pll6_bypass", base + 0xe0, 13); |
190 | clks[IMX6SX_CLK_PLL7_USB_HOST] = imx_clk_gate("pll7_usb_host", "pll7_bypass", base + 0x20, 13); | 198 | hws[IMX6SX_CLK_PLL7_USB_HOST] = imx_clk_hw_gate("pll7_usb_host", "pll7_bypass", base + 0x20, 13); |
191 | 199 | ||
192 | /* | 200 | /* |
193 | * Bit 20 is the reserved and read-only bit, we do this only for: | 201 | * Bit 20 is the reserved and read-only bit, we do this only for: |
@@ -195,361 +203,363 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node) | |||
195 | * - Keep refcount when do usbphy clk_enable/disable, in that case, | 203 | * - Keep refcount when do usbphy clk_enable/disable, in that case, |
196 | * the clk framework may need to enable/disable usbphy's parent | 204 | * the clk framework may need to enable/disable usbphy's parent |
197 | */ | 205 | */ |
198 | clks[IMX6SX_CLK_USBPHY1] = imx_clk_gate("usbphy1", "pll3_usb_otg", base + 0x10, 20); | 206 | hws[IMX6SX_CLK_USBPHY1] = imx_clk_hw_gate("usbphy1", "pll3_usb_otg", base + 0x10, 20); |
199 | clks[IMX6SX_CLK_USBPHY2] = imx_clk_gate("usbphy2", "pll7_usb_host", base + 0x20, 20); | 207 | hws[IMX6SX_CLK_USBPHY2] = imx_clk_hw_gate("usbphy2", "pll7_usb_host", base + 0x20, 20); |
200 | 208 | ||
201 | /* | 209 | /* |
202 | * usbphy*_gate needs to be on after system boots up, and software | 210 | * usbphy*_gate needs to be on after system boots up, and software |
203 | * never needs to control it anymore. | 211 | * never needs to control it anymore. |
204 | */ | 212 | */ |
205 | clks[IMX6SX_CLK_USBPHY1_GATE] = imx_clk_gate("usbphy1_gate", "dummy", base + 0x10, 6); | 213 | hws[IMX6SX_CLK_USBPHY1_GATE] = imx_clk_hw_gate("usbphy1_gate", "dummy", base + 0x10, 6); |
206 | clks[IMX6SX_CLK_USBPHY2_GATE] = imx_clk_gate("usbphy2_gate", "dummy", base + 0x20, 6); | 214 | hws[IMX6SX_CLK_USBPHY2_GATE] = imx_clk_hw_gate("usbphy2_gate", "dummy", base + 0x20, 6); |
207 | 215 | ||
208 | /* FIXME 100MHz is used for pcie ref for all imx6 pcie, excepted imx6q */ | 216 | /* FIXME 100MHz is used for pcie ref for all imx6 pcie, excepted imx6q */ |
209 | clks[IMX6SX_CLK_PCIE_REF] = imx_clk_fixed_factor("pcie_ref", "pll6_enet", 1, 5); | 217 | hws[IMX6SX_CLK_PCIE_REF] = imx_clk_hw_fixed_factor("pcie_ref", "pll6_enet", 1, 5); |
210 | clks[IMX6SX_CLK_PCIE_REF_125M] = imx_clk_gate("pcie_ref_125m", "pcie_ref", base + 0xe0, 19); | 218 | hws[IMX6SX_CLK_PCIE_REF_125M] = imx_clk_hw_gate("pcie_ref_125m", "pcie_ref", base + 0xe0, 19); |
211 | 219 | ||
212 | clks[IMX6SX_CLK_LVDS1_OUT] = imx_clk_gate_exclusive("lvds1_out", "lvds1_sel", base + 0x160, 10, BIT(12)); | 220 | hws[IMX6SX_CLK_LVDS1_OUT] = imx_clk_hw_gate_exclusive("lvds1_out", "lvds1_sel", base + 0x160, 10, BIT(12)); |
213 | clks[IMX6SX_CLK_LVDS2_OUT] = imx_clk_gate_exclusive("lvds2_out", "lvds2_sel", base + 0x160, 11, BIT(13)); | 221 | hws[IMX6SX_CLK_LVDS2_OUT] = imx_clk_hw_gate_exclusive("lvds2_out", "lvds2_sel", base + 0x160, 11, BIT(13)); |
214 | clks[IMX6SX_CLK_LVDS1_IN] = imx_clk_gate_exclusive("lvds1_in", "anaclk1", base + 0x160, 12, BIT(10)); | 222 | hws[IMX6SX_CLK_LVDS1_IN] = imx_clk_hw_gate_exclusive("lvds1_in", "anaclk1", base + 0x160, 12, BIT(10)); |
215 | clks[IMX6SX_CLK_LVDS2_IN] = imx_clk_gate_exclusive("lvds2_in", "anaclk2", base + 0x160, 13, BIT(11)); | 223 | hws[IMX6SX_CLK_LVDS2_IN] = imx_clk_hw_gate_exclusive("lvds2_in", "anaclk2", base + 0x160, 13, BIT(11)); |
216 | 224 | ||
217 | clks[IMX6SX_CLK_ENET_REF] = clk_register_divider_table(NULL, "enet_ref", "pll6_enet", 0, | 225 | hws[IMX6SX_CLK_ENET_REF] = clk_hw_register_divider_table(NULL, "enet_ref", "pll6_enet", 0, |
218 | base + 0xe0, 0, 2, 0, clk_enet_ref_table, | 226 | base + 0xe0, 0, 2, 0, clk_enet_ref_table, |
219 | &imx_ccm_lock); | 227 | &imx_ccm_lock); |
220 | clks[IMX6SX_CLK_ENET2_REF] = clk_register_divider_table(NULL, "enet2_ref", "pll6_enet", 0, | 228 | hws[IMX6SX_CLK_ENET2_REF] = clk_hw_register_divider_table(NULL, "enet2_ref", "pll6_enet", 0, |
221 | base + 0xe0, 2, 2, 0, clk_enet_ref_table, | 229 | base + 0xe0, 2, 2, 0, clk_enet_ref_table, |
222 | &imx_ccm_lock); | 230 | &imx_ccm_lock); |
223 | clks[IMX6SX_CLK_ENET2_REF_125M] = imx_clk_gate("enet2_ref_125m", "enet2_ref", base + 0xe0, 20); | 231 | hws[IMX6SX_CLK_ENET2_REF_125M] = imx_clk_hw_gate("enet2_ref_125m", "enet2_ref", base + 0xe0, 20); |
224 | 232 | ||
225 | clks[IMX6SX_CLK_ENET_PTP_REF] = imx_clk_fixed_factor("enet_ptp_ref", "pll6_enet", 1, 20); | 233 | hws[IMX6SX_CLK_ENET_PTP_REF] = imx_clk_hw_fixed_factor("enet_ptp_ref", "pll6_enet", 1, 20); |
226 | clks[IMX6SX_CLK_ENET_PTP] = imx_clk_gate("enet_ptp_25m", "enet_ptp_ref", base + 0xe0, 21); | 234 | hws[IMX6SX_CLK_ENET_PTP] = imx_clk_hw_gate("enet_ptp_25m", "enet_ptp_ref", base + 0xe0, 21); |
227 | 235 | ||
228 | /* name parent_name reg idx */ | 236 | /* name parent_name reg idx */ |
229 | clks[IMX6SX_CLK_PLL2_PFD0] = imx_clk_pfd("pll2_pfd0_352m", "pll2_bus", base + 0x100, 0); | 237 | hws[IMX6SX_CLK_PLL2_PFD0] = imx_clk_hw_pfd("pll2_pfd0_352m", "pll2_bus", base + 0x100, 0); |
230 | clks[IMX6SX_CLK_PLL2_PFD1] = imx_clk_pfd("pll2_pfd1_594m", "pll2_bus", base + 0x100, 1); | 238 | hws[IMX6SX_CLK_PLL2_PFD1] = imx_clk_hw_pfd("pll2_pfd1_594m", "pll2_bus", base + 0x100, 1); |
231 | clks[IMX6SX_CLK_PLL2_PFD2] = imx_clk_pfd("pll2_pfd2_396m", "pll2_bus", base + 0x100, 2); | 239 | hws[IMX6SX_CLK_PLL2_PFD2] = imx_clk_hw_pfd("pll2_pfd2_396m", "pll2_bus", base + 0x100, 2); |
232 | clks[IMX6SX_CLK_PLL2_PFD3] = imx_clk_pfd("pll2_pfd3_594m", "pll2_bus", base + 0x100, 3); | 240 | hws[IMX6SX_CLK_PLL2_PFD3] = imx_clk_hw_pfd("pll2_pfd3_594m", "pll2_bus", base + 0x100, 3); |
233 | clks[IMX6SX_CLK_PLL3_PFD0] = imx_clk_pfd("pll3_pfd0_720m", "pll3_usb_otg", base + 0xf0, 0); | 241 | hws[IMX6SX_CLK_PLL3_PFD0] = imx_clk_hw_pfd("pll3_pfd0_720m", "pll3_usb_otg", base + 0xf0, 0); |
234 | clks[IMX6SX_CLK_PLL3_PFD1] = imx_clk_pfd("pll3_pfd1_540m", "pll3_usb_otg", base + 0xf0, 1); | 242 | hws[IMX6SX_CLK_PLL3_PFD1] = imx_clk_hw_pfd("pll3_pfd1_540m", "pll3_usb_otg", base + 0xf0, 1); |
235 | clks[IMX6SX_CLK_PLL3_PFD2] = imx_clk_pfd("pll3_pfd2_508m", "pll3_usb_otg", base + 0xf0, 2); | 243 | hws[IMX6SX_CLK_PLL3_PFD2] = imx_clk_hw_pfd("pll3_pfd2_508m", "pll3_usb_otg", base + 0xf0, 2); |
236 | clks[IMX6SX_CLK_PLL3_PFD3] = imx_clk_pfd("pll3_pfd3_454m", "pll3_usb_otg", base + 0xf0, 3); | 244 | hws[IMX6SX_CLK_PLL3_PFD3] = imx_clk_hw_pfd("pll3_pfd3_454m", "pll3_usb_otg", base + 0xf0, 3); |
237 | 245 | ||
238 | /* name parent_name mult div */ | 246 | /* name parent_name mult div */ |
239 | clks[IMX6SX_CLK_PLL2_198M] = imx_clk_fixed_factor("pll2_198m", "pll2_pfd2_396m", 1, 2); | 247 | hws[IMX6SX_CLK_PLL2_198M] = imx_clk_hw_fixed_factor("pll2_198m", "pll2_pfd2_396m", 1, 2); |
240 | clks[IMX6SX_CLK_PLL3_120M] = imx_clk_fixed_factor("pll3_120m", "pll3_usb_otg", 1, 4); | 248 | hws[IMX6SX_CLK_PLL3_120M] = imx_clk_hw_fixed_factor("pll3_120m", "pll3_usb_otg", 1, 4); |
241 | clks[IMX6SX_CLK_PLL3_80M] = imx_clk_fixed_factor("pll3_80m", "pll3_usb_otg", 1, 6); | 249 | hws[IMX6SX_CLK_PLL3_80M] = imx_clk_hw_fixed_factor("pll3_80m", "pll3_usb_otg", 1, 6); |
242 | clks[IMX6SX_CLK_PLL3_60M] = imx_clk_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8); | 250 | hws[IMX6SX_CLK_PLL3_60M] = imx_clk_hw_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8); |
243 | clks[IMX6SX_CLK_TWD] = imx_clk_fixed_factor("twd", "arm", 1, 2); | 251 | hws[IMX6SX_CLK_TWD] = imx_clk_hw_fixed_factor("twd", "arm", 1, 2); |
244 | clks[IMX6SX_CLK_GPT_3M] = imx_clk_fixed_factor("gpt_3m", "osc", 1, 8); | 252 | hws[IMX6SX_CLK_GPT_3M] = imx_clk_hw_fixed_factor("gpt_3m", "osc", 1, 8); |
245 | 253 | ||
246 | clks[IMX6SX_CLK_PLL4_POST_DIV] = clk_register_divider_table(NULL, "pll4_post_div", "pll4_audio", | 254 | hws[IMX6SX_CLK_PLL4_POST_DIV] = clk_hw_register_divider_table(NULL, "pll4_post_div", "pll4_audio", |
247 | CLK_SET_RATE_PARENT, base + 0x70, 19, 2, 0, post_div_table, &imx_ccm_lock); | 255 | CLK_SET_RATE_PARENT, base + 0x70, 19, 2, 0, post_div_table, &imx_ccm_lock); |
248 | clks[IMX6SX_CLK_PLL4_AUDIO_DIV] = clk_register_divider(NULL, "pll4_audio_div", "pll4_post_div", | 256 | hws[IMX6SX_CLK_PLL4_AUDIO_DIV] = clk_hw_register_divider(NULL, "pll4_audio_div", "pll4_post_div", |
249 | CLK_SET_RATE_PARENT, base + 0x170, 15, 1, 0, &imx_ccm_lock); | 257 | CLK_SET_RATE_PARENT, base + 0x170, 15, 1, 0, &imx_ccm_lock); |
250 | clks[IMX6SX_CLK_PLL5_POST_DIV] = clk_register_divider_table(NULL, "pll5_post_div", "pll5_video", | 258 | hws[IMX6SX_CLK_PLL5_POST_DIV] = clk_hw_register_divider_table(NULL, "pll5_post_div", "pll5_video", |
251 | CLK_SET_RATE_PARENT, base + 0xa0, 19, 2, 0, post_div_table, &imx_ccm_lock); | 259 | CLK_SET_RATE_PARENT, base + 0xa0, 19, 2, 0, post_div_table, &imx_ccm_lock); |
252 | clks[IMX6SX_CLK_PLL5_VIDEO_DIV] = clk_register_divider_table(NULL, "pll5_video_div", "pll5_post_div", | 260 | hws[IMX6SX_CLK_PLL5_VIDEO_DIV] = clk_hw_register_divider_table(NULL, "pll5_video_div", "pll5_post_div", |
253 | CLK_SET_RATE_PARENT, base + 0x170, 30, 2, 0, video_div_table, &imx_ccm_lock); | 261 | CLK_SET_RATE_PARENT, base + 0x170, 30, 2, 0, video_div_table, &imx_ccm_lock); |
254 | 262 | ||
255 | /* name reg shift width parent_names num_parents */ | 263 | /* name reg shift width parent_names num_parents */ |
256 | clks[IMX6SX_CLK_LVDS1_SEL] = imx_clk_mux("lvds1_sel", base + 0x160, 0, 5, lvds_sels, ARRAY_SIZE(lvds_sels)); | 264 | hws[IMX6SX_CLK_LVDS1_SEL] = imx_clk_hw_mux("lvds1_sel", base + 0x160, 0, 5, lvds_sels, ARRAY_SIZE(lvds_sels)); |
257 | clks[IMX6SX_CLK_LVDS2_SEL] = imx_clk_mux("lvds2_sel", base + 0x160, 5, 5, lvds_sels, ARRAY_SIZE(lvds_sels)); | 265 | hws[IMX6SX_CLK_LVDS2_SEL] = imx_clk_hw_mux("lvds2_sel", base + 0x160, 5, 5, lvds_sels, ARRAY_SIZE(lvds_sels)); |
258 | 266 | ||
259 | np = ccm_node; | 267 | np = ccm_node; |
260 | base = of_iomap(np, 0); | 268 | base = of_iomap(np, 0); |
261 | WARN_ON(!base); | 269 | WARN_ON(!base); |
262 | 270 | ||
263 | /* name reg shift width parent_names num_parents */ | 271 | /* name reg shift width parent_names num_parents */ |
264 | clks[IMX6SX_CLK_STEP] = imx_clk_mux("step", base + 0xc, 8, 1, step_sels, ARRAY_SIZE(step_sels)); | 272 | hws[IMX6SX_CLK_STEP] = imx_clk_hw_mux("step", base + 0xc, 8, 1, step_sels, ARRAY_SIZE(step_sels)); |
265 | clks[IMX6SX_CLK_PLL1_SW] = imx_clk_mux("pll1_sw", base + 0xc, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels)); | 273 | hws[IMX6SX_CLK_PLL1_SW] = imx_clk_hw_mux("pll1_sw", base + 0xc, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels)); |
266 | clks[IMX6SX_CLK_OCRAM_SEL] = imx_clk_mux("ocram_sel", base + 0x14, 6, 2, ocram_sels, ARRAY_SIZE(ocram_sels)); | 274 | hws[IMX6SX_CLK_OCRAM_SEL] = imx_clk_hw_mux("ocram_sel", base + 0x14, 6, 2, ocram_sels, ARRAY_SIZE(ocram_sels)); |
267 | clks[IMX6SX_CLK_PERIPH_PRE] = imx_clk_mux("periph_pre", base + 0x18, 18, 2, periph_pre_sels, ARRAY_SIZE(periph_pre_sels)); | 275 | hws[IMX6SX_CLK_PERIPH_PRE] = imx_clk_hw_mux("periph_pre", base + 0x18, 18, 2, periph_pre_sels, ARRAY_SIZE(periph_pre_sels)); |
268 | clks[IMX6SX_CLK_PERIPH2_PRE] = imx_clk_mux("periph2_pre", base + 0x18, 21, 2, periph2_pre_sels, ARRAY_SIZE(periph2_pre_sels)); | 276 | hws[IMX6SX_CLK_PERIPH2_PRE] = imx_clk_hw_mux("periph2_pre", base + 0x18, 21, 2, periph2_pre_sels, ARRAY_SIZE(periph2_pre_sels)); |
269 | clks[IMX6SX_CLK_PERIPH_CLK2_SEL] = imx_clk_mux("periph_clk2_sel", base + 0x18, 12, 2, periph_clk2_sels, ARRAY_SIZE(periph_clk2_sels)); | 277 | hws[IMX6SX_CLK_PERIPH_CLK2_SEL] = imx_clk_hw_mux("periph_clk2_sel", base + 0x18, 12, 2, periph_clk2_sels, ARRAY_SIZE(periph_clk2_sels)); |
270 | clks[IMX6SX_CLK_PERIPH2_CLK2_SEL] = imx_clk_mux("periph2_clk2_sel", base + 0x18, 20, 1, periph2_clk2_sels, ARRAY_SIZE(periph2_clk2_sels)); | 278 | hws[IMX6SX_CLK_PERIPH2_CLK2_SEL] = imx_clk_hw_mux("periph2_clk2_sel", base + 0x18, 20, 1, periph2_clk2_sels, ARRAY_SIZE(periph2_clk2_sels)); |
271 | clks[IMX6SX_CLK_PCIE_AXI_SEL] = imx_clk_mux("pcie_axi_sel", base + 0x18, 10, 1, pcie_axi_sels, ARRAY_SIZE(pcie_axi_sels)); | 279 | hws[IMX6SX_CLK_PCIE_AXI_SEL] = imx_clk_hw_mux("pcie_axi_sel", base + 0x18, 10, 1, pcie_axi_sels, ARRAY_SIZE(pcie_axi_sels)); |
272 | clks[IMX6SX_CLK_GPU_AXI_SEL] = imx_clk_mux("gpu_axi_sel", base + 0x18, 8, 2, gpu_axi_sels, ARRAY_SIZE(gpu_axi_sels)); | 280 | hws[IMX6SX_CLK_GPU_AXI_SEL] = imx_clk_hw_mux("gpu_axi_sel", base + 0x18, 8, 2, gpu_axi_sels, ARRAY_SIZE(gpu_axi_sels)); |
273 | clks[IMX6SX_CLK_GPU_CORE_SEL] = imx_clk_mux("gpu_core_sel", base + 0x18, 4, 2, gpu_core_sels, ARRAY_SIZE(gpu_core_sels)); | 281 | hws[IMX6SX_CLK_GPU_CORE_SEL] = imx_clk_hw_mux("gpu_core_sel", base + 0x18, 4, 2, gpu_core_sels, ARRAY_SIZE(gpu_core_sels)); |
274 | clks[IMX6SX_CLK_EIM_SLOW_SEL] = imx_clk_mux("eim_slow_sel", base + 0x1c, 29, 2, eim_slow_sels, ARRAY_SIZE(eim_slow_sels)); | 282 | hws[IMX6SX_CLK_EIM_SLOW_SEL] = imx_clk_hw_mux("eim_slow_sel", base + 0x1c, 29, 2, eim_slow_sels, ARRAY_SIZE(eim_slow_sels)); |
275 | clks[IMX6SX_CLK_USDHC1_SEL] = imx_clk_mux("usdhc1_sel", base + 0x1c, 16, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels)); | 283 | hws[IMX6SX_CLK_USDHC1_SEL] = imx_clk_hw_mux("usdhc1_sel", base + 0x1c, 16, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels)); |
276 | clks[IMX6SX_CLK_USDHC2_SEL] = imx_clk_mux("usdhc2_sel", base + 0x1c, 17, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels)); | 284 | hws[IMX6SX_CLK_USDHC2_SEL] = imx_clk_hw_mux("usdhc2_sel", base + 0x1c, 17, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels)); |
277 | clks[IMX6SX_CLK_USDHC3_SEL] = imx_clk_mux("usdhc3_sel", base + 0x1c, 18, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels)); | 285 | hws[IMX6SX_CLK_USDHC3_SEL] = imx_clk_hw_mux("usdhc3_sel", base + 0x1c, 18, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels)); |
278 | clks[IMX6SX_CLK_USDHC4_SEL] = imx_clk_mux("usdhc4_sel", base + 0x1c, 19, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels)); | 286 | hws[IMX6SX_CLK_USDHC4_SEL] = imx_clk_hw_mux("usdhc4_sel", base + 0x1c, 19, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels)); |
279 | clks[IMX6SX_CLK_SSI3_SEL] = imx_clk_mux("ssi3_sel", base + 0x1c, 14, 2, ssi_sels, ARRAY_SIZE(ssi_sels)); | 287 | hws[IMX6SX_CLK_SSI3_SEL] = imx_clk_hw_mux("ssi3_sel", base + 0x1c, 14, 2, ssi_sels, ARRAY_SIZE(ssi_sels)); |
280 | clks[IMX6SX_CLK_SSI2_SEL] = imx_clk_mux("ssi2_sel", base + 0x1c, 12, 2, ssi_sels, ARRAY_SIZE(ssi_sels)); | 288 | hws[IMX6SX_CLK_SSI2_SEL] = imx_clk_hw_mux("ssi2_sel", base + 0x1c, 12, 2, ssi_sels, ARRAY_SIZE(ssi_sels)); |
281 | clks[IMX6SX_CLK_SSI1_SEL] = imx_clk_mux("ssi1_sel", base + 0x1c, 10, 2, ssi_sels, ARRAY_SIZE(ssi_sels)); | 289 | hws[IMX6SX_CLK_SSI1_SEL] = imx_clk_hw_mux("ssi1_sel", base + 0x1c, 10, 2, ssi_sels, ARRAY_SIZE(ssi_sels)); |
282 | clks[IMX6SX_CLK_QSPI1_SEL] = imx_clk_mux_flags("qspi1_sel", base + 0x1c, 7, 3, qspi1_sels, ARRAY_SIZE(qspi1_sels), CLK_SET_RATE_PARENT); | 290 | hws[IMX6SX_CLK_QSPI1_SEL] = imx_clk_hw_mux_flags("qspi1_sel", base + 0x1c, 7, 3, qspi1_sels, ARRAY_SIZE(qspi1_sels), CLK_SET_RATE_PARENT); |
283 | clks[IMX6SX_CLK_PERCLK_SEL] = imx_clk_mux("perclk_sel", base + 0x1c, 6, 1, perclk_sels, ARRAY_SIZE(perclk_sels)); | 291 | hws[IMX6SX_CLK_PERCLK_SEL] = imx_clk_hw_mux("perclk_sel", base + 0x1c, 6, 1, perclk_sels, ARRAY_SIZE(perclk_sels)); |
284 | clks[IMX6SX_CLK_VID_SEL] = imx_clk_mux("vid_sel", base + 0x20, 21, 3, vid_sels, ARRAY_SIZE(vid_sels)); | 292 | hws[IMX6SX_CLK_VID_SEL] = imx_clk_hw_mux("vid_sel", base + 0x20, 21, 3, vid_sels, ARRAY_SIZE(vid_sels)); |
285 | clks[IMX6SX_CLK_ESAI_SEL] = imx_clk_mux("esai_sel", base + 0x20, 19, 2, audio_sels, ARRAY_SIZE(audio_sels)); | 293 | hws[IMX6SX_CLK_ESAI_SEL] = imx_clk_hw_mux("esai_sel", base + 0x20, 19, 2, audio_sels, ARRAY_SIZE(audio_sels)); |
286 | clks[IMX6SX_CLK_CAN_SEL] = imx_clk_mux("can_sel", base + 0x20, 8, 2, can_sels, ARRAY_SIZE(can_sels)); | 294 | hws[IMX6SX_CLK_CAN_SEL] = imx_clk_hw_mux("can_sel", base + 0x20, 8, 2, can_sels, ARRAY_SIZE(can_sels)); |
287 | clks[IMX6SX_CLK_UART_SEL] = imx_clk_mux("uart_sel", base + 0x24, 6, 1, uart_sels, ARRAY_SIZE(uart_sels)); | 295 | hws[IMX6SX_CLK_UART_SEL] = imx_clk_hw_mux("uart_sel", base + 0x24, 6, 1, uart_sels, ARRAY_SIZE(uart_sels)); |
288 | clks[IMX6SX_CLK_QSPI2_SEL] = imx_clk_mux_flags("qspi2_sel", base + 0x2c, 15, 3, qspi2_sels, ARRAY_SIZE(qspi2_sels), CLK_SET_RATE_PARENT); | 296 | hws[IMX6SX_CLK_QSPI2_SEL] = imx_clk_hw_mux_flags("qspi2_sel", base + 0x2c, 15, 3, qspi2_sels, ARRAY_SIZE(qspi2_sels), CLK_SET_RATE_PARENT); |
289 | clks[IMX6SX_CLK_SPDIF_SEL] = imx_clk_mux("spdif_sel", base + 0x30, 20, 2, audio_sels, ARRAY_SIZE(audio_sels)); | 297 | hws[IMX6SX_CLK_SPDIF_SEL] = imx_clk_hw_mux("spdif_sel", base + 0x30, 20, 2, audio_sels, ARRAY_SIZE(audio_sels)); |
290 | clks[IMX6SX_CLK_AUDIO_SEL] = imx_clk_mux("audio_sel", base + 0x30, 7, 2, audio_sels, ARRAY_SIZE(audio_sels)); | 298 | hws[IMX6SX_CLK_AUDIO_SEL] = imx_clk_hw_mux("audio_sel", base + 0x30, 7, 2, audio_sels, ARRAY_SIZE(audio_sels)); |
291 | clks[IMX6SX_CLK_ENET_PRE_SEL] = imx_clk_mux("enet_pre_sel", base + 0x34, 15, 3, enet_pre_sels, ARRAY_SIZE(enet_pre_sels)); | 299 | hws[IMX6SX_CLK_ENET_PRE_SEL] = imx_clk_hw_mux("enet_pre_sel", base + 0x34, 15, 3, enet_pre_sels, ARRAY_SIZE(enet_pre_sels)); |
292 | clks[IMX6SX_CLK_ENET_SEL] = imx_clk_mux("enet_sel", base + 0x34, 9, 3, enet_sels, ARRAY_SIZE(enet_sels)); | 300 | hws[IMX6SX_CLK_ENET_SEL] = imx_clk_hw_mux("enet_sel", base + 0x34, 9, 3, enet_sels, ARRAY_SIZE(enet_sels)); |
293 | clks[IMX6SX_CLK_M4_PRE_SEL] = imx_clk_mux("m4_pre_sel", base + 0x34, 6, 3, m4_pre_sels, ARRAY_SIZE(m4_pre_sels)); | 301 | hws[IMX6SX_CLK_M4_PRE_SEL] = imx_clk_hw_mux("m4_pre_sel", base + 0x34, 6, 3, m4_pre_sels, ARRAY_SIZE(m4_pre_sels)); |
294 | clks[IMX6SX_CLK_M4_SEL] = imx_clk_mux("m4_sel", base + 0x34, 0, 3, m4_sels, ARRAY_SIZE(m4_sels)); | 302 | hws[IMX6SX_CLK_M4_SEL] = imx_clk_hw_mux("m4_sel", base + 0x34, 0, 3, m4_sels, ARRAY_SIZE(m4_sels)); |
295 | clks[IMX6SX_CLK_ECSPI_SEL] = imx_clk_mux("ecspi_sel", base + 0x38, 18, 1, ecspi_sels, ARRAY_SIZE(ecspi_sels)); | 303 | hws[IMX6SX_CLK_ECSPI_SEL] = imx_clk_hw_mux("ecspi_sel", base + 0x38, 18, 1, ecspi_sels, ARRAY_SIZE(ecspi_sels)); |
296 | clks[IMX6SX_CLK_LCDIF2_PRE_SEL] = imx_clk_mux("lcdif2_pre_sel", base + 0x38, 6, 3, lcdif2_pre_sels, ARRAY_SIZE(lcdif2_pre_sels)); | 304 | hws[IMX6SX_CLK_LCDIF2_PRE_SEL] = imx_clk_hw_mux("lcdif2_pre_sel", base + 0x38, 6, 3, lcdif2_pre_sels, ARRAY_SIZE(lcdif2_pre_sels)); |
297 | clks[IMX6SX_CLK_LCDIF2_SEL] = imx_clk_mux("lcdif2_sel", base + 0x38, 0, 3, lcdif2_sels, ARRAY_SIZE(lcdif2_sels)); | 305 | hws[IMX6SX_CLK_LCDIF2_SEL] = imx_clk_hw_mux("lcdif2_sel", base + 0x38, 0, 3, lcdif2_sels, ARRAY_SIZE(lcdif2_sels)); |
298 | clks[IMX6SX_CLK_DISPLAY_SEL] = imx_clk_mux("display_sel", base + 0x3c, 14, 2, display_sels, ARRAY_SIZE(display_sels)); | 306 | hws[IMX6SX_CLK_DISPLAY_SEL] = imx_clk_hw_mux("display_sel", base + 0x3c, 14, 2, display_sels, ARRAY_SIZE(display_sels)); |
299 | clks[IMX6SX_CLK_CSI_SEL] = imx_clk_mux("csi_sel", base + 0x3c, 9, 2, csi_sels, ARRAY_SIZE(csi_sels)); | 307 | hws[IMX6SX_CLK_CSI_SEL] = imx_clk_hw_mux("csi_sel", base + 0x3c, 9, 2, csi_sels, ARRAY_SIZE(csi_sels)); |
300 | clks[IMX6SX_CLK_CKO1_SEL] = imx_clk_mux("cko1_sel", base + 0x60, 0, 4, cko1_sels, ARRAY_SIZE(cko1_sels)); | 308 | hws[IMX6SX_CLK_CKO1_SEL] = imx_clk_hw_mux("cko1_sel", base + 0x60, 0, 4, cko1_sels, ARRAY_SIZE(cko1_sels)); |
301 | clks[IMX6SX_CLK_CKO2_SEL] = imx_clk_mux("cko2_sel", base + 0x60, 16, 5, cko2_sels, ARRAY_SIZE(cko2_sels)); | 309 | hws[IMX6SX_CLK_CKO2_SEL] = imx_clk_hw_mux("cko2_sel", base + 0x60, 16, 5, cko2_sels, ARRAY_SIZE(cko2_sels)); |
302 | clks[IMX6SX_CLK_CKO] = imx_clk_mux("cko", base + 0x60, 8, 1, cko_sels, ARRAY_SIZE(cko_sels)); | 310 | hws[IMX6SX_CLK_CKO] = imx_clk_hw_mux("cko", base + 0x60, 8, 1, cko_sels, ARRAY_SIZE(cko_sels)); |
303 | 311 | ||
304 | clks[IMX6SX_CLK_LDB_DI1_DIV_SEL] = imx_clk_mux_flags("ldb_di1_div_sel", base + 0x20, 11, 1, ldb_di1_div_sels, ARRAY_SIZE(ldb_di1_div_sels), CLK_SET_RATE_PARENT); | 312 | hws[IMX6SX_CLK_LDB_DI1_DIV_SEL] = imx_clk_hw_mux_flags("ldb_di1_div_sel", base + 0x20, 11, 1, ldb_di1_div_sels, ARRAY_SIZE(ldb_di1_div_sels), CLK_SET_RATE_PARENT); |
305 | clks[IMX6SX_CLK_LDB_DI0_DIV_SEL] = imx_clk_mux_flags("ldb_di0_div_sel", base + 0x20, 10, 1, ldb_di0_div_sels, ARRAY_SIZE(ldb_di0_div_sels), CLK_SET_RATE_PARENT); | 313 | hws[IMX6SX_CLK_LDB_DI0_DIV_SEL] = imx_clk_hw_mux_flags("ldb_di0_div_sel", base + 0x20, 10, 1, ldb_di0_div_sels, ARRAY_SIZE(ldb_di0_div_sels), CLK_SET_RATE_PARENT); |
306 | clks[IMX6SX_CLK_LDB_DI1_SEL] = imx_clk_mux_flags("ldb_di1_sel", base + 0x2c, 12, 3, ldb_di1_sels, ARRAY_SIZE(ldb_di1_sels), CLK_SET_RATE_PARENT); | 314 | hws[IMX6SX_CLK_LDB_DI1_SEL] = imx_clk_hw_mux_flags("ldb_di1_sel", base + 0x2c, 12, 3, ldb_di1_sels, ARRAY_SIZE(ldb_di1_sels), CLK_SET_RATE_PARENT); |
307 | clks[IMX6SX_CLK_LDB_DI0_SEL] = imx_clk_mux_flags("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di0_sels, ARRAY_SIZE(ldb_di0_sels), CLK_SET_RATE_PARENT); | 315 | hws[IMX6SX_CLK_LDB_DI0_SEL] = imx_clk_hw_mux_flags("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di0_sels, ARRAY_SIZE(ldb_di0_sels), CLK_SET_RATE_PARENT); |
308 | clks[IMX6SX_CLK_LCDIF1_PRE_SEL] = imx_clk_mux_flags("lcdif1_pre_sel", base + 0x38, 15, 3, lcdif1_pre_sels, ARRAY_SIZE(lcdif1_pre_sels), CLK_SET_RATE_PARENT); | 316 | hws[IMX6SX_CLK_LCDIF1_PRE_SEL] = imx_clk_hw_mux_flags("lcdif1_pre_sel", base + 0x38, 15, 3, lcdif1_pre_sels, ARRAY_SIZE(lcdif1_pre_sels), CLK_SET_RATE_PARENT); |
309 | clks[IMX6SX_CLK_LCDIF1_SEL] = imx_clk_mux_flags("lcdif1_sel", base + 0x38, 9, 3, lcdif1_sels, ARRAY_SIZE(lcdif1_sels), CLK_SET_RATE_PARENT); | 317 | hws[IMX6SX_CLK_LCDIF1_SEL] = imx_clk_hw_mux_flags("lcdif1_sel", base + 0x38, 9, 3, lcdif1_sels, ARRAY_SIZE(lcdif1_sels), CLK_SET_RATE_PARENT); |
310 | 318 | ||
311 | /* name parent_name reg shift width */ | 319 | /* name parent_name reg shift width */ |
312 | clks[IMX6SX_CLK_PERIPH_CLK2] = imx_clk_divider("periph_clk2", "periph_clk2_sel", base + 0x14, 27, 3); | 320 | hws[IMX6SX_CLK_PERIPH_CLK2] = imx_clk_hw_divider("periph_clk2", "periph_clk2_sel", base + 0x14, 27, 3); |
313 | clks[IMX6SX_CLK_PERIPH2_CLK2] = imx_clk_divider("periph2_clk2", "periph2_clk2_sel", base + 0x14, 0, 3); | 321 | hws[IMX6SX_CLK_PERIPH2_CLK2] = imx_clk_hw_divider("periph2_clk2", "periph2_clk2_sel", base + 0x14, 0, 3); |
314 | clks[IMX6SX_CLK_IPG] = imx_clk_divider("ipg", "ahb", base + 0x14, 8, 2); | 322 | hws[IMX6SX_CLK_IPG] = imx_clk_hw_divider("ipg", "ahb", base + 0x14, 8, 2); |
315 | clks[IMX6SX_CLK_GPU_CORE_PODF] = imx_clk_divider("gpu_core_podf", "gpu_core_sel", base + 0x18, 29, 3); | 323 | hws[IMX6SX_CLK_GPU_CORE_PODF] = imx_clk_hw_divider("gpu_core_podf", "gpu_core_sel", base + 0x18, 29, 3); |
316 | clks[IMX6SX_CLK_GPU_AXI_PODF] = imx_clk_divider("gpu_axi_podf", "gpu_axi_sel", base + 0x18, 26, 3); | 324 | hws[IMX6SX_CLK_GPU_AXI_PODF] = imx_clk_hw_divider("gpu_axi_podf", "gpu_axi_sel", base + 0x18, 26, 3); |
317 | clks[IMX6SX_CLK_LCDIF1_PODF] = imx_clk_divider("lcdif1_podf", "lcdif1_pred", base + 0x18, 23, 3); | 325 | hws[IMX6SX_CLK_LCDIF1_PODF] = imx_clk_hw_divider("lcdif1_podf", "lcdif1_pred", base + 0x18, 23, 3); |
318 | clks[IMX6SX_CLK_QSPI1_PODF] = imx_clk_divider("qspi1_podf", "qspi1_sel", base + 0x1c, 26, 3); | 326 | hws[IMX6SX_CLK_QSPI1_PODF] = imx_clk_hw_divider("qspi1_podf", "qspi1_sel", base + 0x1c, 26, 3); |
319 | clks[IMX6SX_CLK_EIM_SLOW_PODF] = imx_clk_divider("eim_slow_podf", "eim_slow_sel", base + 0x1c, 23, 3); | 327 | hws[IMX6SX_CLK_EIM_SLOW_PODF] = imx_clk_hw_divider("eim_slow_podf", "eim_slow_sel", base + 0x1c, 23, 3); |
320 | clks[IMX6SX_CLK_LCDIF2_PODF] = imx_clk_divider("lcdif2_podf", "lcdif2_pred", base + 0x1c, 20, 3); | 328 | hws[IMX6SX_CLK_LCDIF2_PODF] = imx_clk_hw_divider("lcdif2_podf", "lcdif2_pred", base + 0x1c, 20, 3); |
321 | clks[IMX6SX_CLK_PERCLK] = imx_clk_divider_flags("perclk", "perclk_sel", base + 0x1c, 0, 6, CLK_IS_CRITICAL); | 329 | hws[IMX6SX_CLK_PERCLK] = imx_clk_hw_divider_flags("perclk", "perclk_sel", base + 0x1c, 0, 6, CLK_IS_CRITICAL); |
322 | clks[IMX6SX_CLK_VID_PODF] = imx_clk_divider("vid_podf", "vid_sel", base + 0x20, 24, 2); | 330 | hws[IMX6SX_CLK_VID_PODF] = imx_clk_hw_divider("vid_podf", "vid_sel", base + 0x20, 24, 2); |
323 | clks[IMX6SX_CLK_CAN_PODF] = imx_clk_divider("can_podf", "can_sel", base + 0x20, 2, 6); | 331 | hws[IMX6SX_CLK_CAN_PODF] = imx_clk_hw_divider("can_podf", "can_sel", base + 0x20, 2, 6); |
324 | clks[IMX6SX_CLK_USDHC4_PODF] = imx_clk_divider("usdhc4_podf", "usdhc4_sel", base + 0x24, 22, 3); | 332 | hws[IMX6SX_CLK_USDHC4_PODF] = imx_clk_hw_divider("usdhc4_podf", "usdhc4_sel", base + 0x24, 22, 3); |
325 | clks[IMX6SX_CLK_USDHC3_PODF] = imx_clk_divider("usdhc3_podf", "usdhc3_sel", base + 0x24, 19, 3); | 333 | hws[IMX6SX_CLK_USDHC3_PODF] = imx_clk_hw_divider("usdhc3_podf", "usdhc3_sel", base + 0x24, 19, 3); |
326 | clks[IMX6SX_CLK_USDHC2_PODF] = imx_clk_divider("usdhc2_podf", "usdhc2_sel", base + 0x24, 16, 3); | 334 | hws[IMX6SX_CLK_USDHC2_PODF] = imx_clk_hw_divider("usdhc2_podf", "usdhc2_sel", base + 0x24, 16, 3); |
327 | clks[IMX6SX_CLK_USDHC1_PODF] = imx_clk_divider("usdhc1_podf", "usdhc1_sel", base + 0x24, 11, 3); | 335 | hws[IMX6SX_CLK_USDHC1_PODF] = imx_clk_hw_divider("usdhc1_podf", "usdhc1_sel", base + 0x24, 11, 3); |
328 | clks[IMX6SX_CLK_UART_PODF] = imx_clk_divider("uart_podf", "uart_sel", base + 0x24, 0, 6); | 336 | hws[IMX6SX_CLK_UART_PODF] = imx_clk_hw_divider("uart_podf", "uart_sel", base + 0x24, 0, 6); |
329 | clks[IMX6SX_CLK_ESAI_PRED] = imx_clk_divider("esai_pred", "esai_sel", base + 0x28, 9, 3); | 337 | hws[IMX6SX_CLK_ESAI_PRED] = imx_clk_hw_divider("esai_pred", "esai_sel", base + 0x28, 9, 3); |
330 | clks[IMX6SX_CLK_ESAI_PODF] = imx_clk_divider("esai_podf", "esai_pred", base + 0x28, 25, 3); | 338 | hws[IMX6SX_CLK_ESAI_PODF] = imx_clk_hw_divider("esai_podf", "esai_pred", base + 0x28, 25, 3); |
331 | clks[IMX6SX_CLK_SSI3_PRED] = imx_clk_divider("ssi3_pred", "ssi3_sel", base + 0x28, 22, 3); | 339 | hws[IMX6SX_CLK_SSI3_PRED] = imx_clk_hw_divider("ssi3_pred", "ssi3_sel", base + 0x28, 22, 3); |
332 | clks[IMX6SX_CLK_SSI3_PODF] = imx_clk_divider("ssi3_podf", "ssi3_pred", base + 0x28, 16, 6); | 340 | hws[IMX6SX_CLK_SSI3_PODF] = imx_clk_hw_divider("ssi3_podf", "ssi3_pred", base + 0x28, 16, 6); |
333 | clks[IMX6SX_CLK_SSI1_PRED] = imx_clk_divider("ssi1_pred", "ssi1_sel", base + 0x28, 6, 3); | 341 | hws[IMX6SX_CLK_SSI1_PRED] = imx_clk_hw_divider("ssi1_pred", "ssi1_sel", base + 0x28, 6, 3); |
334 | clks[IMX6SX_CLK_SSI1_PODF] = imx_clk_divider("ssi1_podf", "ssi1_pred", base + 0x28, 0, 6); | 342 | hws[IMX6SX_CLK_SSI1_PODF] = imx_clk_hw_divider("ssi1_podf", "ssi1_pred", base + 0x28, 0, 6); |
335 | clks[IMX6SX_CLK_QSPI2_PRED] = imx_clk_divider("qspi2_pred", "qspi2_sel", base + 0x2c, 18, 3); | 343 | hws[IMX6SX_CLK_QSPI2_PRED] = imx_clk_hw_divider("qspi2_pred", "qspi2_sel", base + 0x2c, 18, 3); |
336 | clks[IMX6SX_CLK_QSPI2_PODF] = imx_clk_divider("qspi2_podf", "qspi2_pred", base + 0x2c, 21, 6); | 344 | hws[IMX6SX_CLK_QSPI2_PODF] = imx_clk_hw_divider("qspi2_podf", "qspi2_pred", base + 0x2c, 21, 6); |
337 | clks[IMX6SX_CLK_SSI2_PRED] = imx_clk_divider("ssi2_pred", "ssi2_sel", base + 0x2c, 6, 3); | 345 | hws[IMX6SX_CLK_SSI2_PRED] = imx_clk_hw_divider("ssi2_pred", "ssi2_sel", base + 0x2c, 6, 3); |
338 | clks[IMX6SX_CLK_SSI2_PODF] = imx_clk_divider("ssi2_podf", "ssi2_pred", base + 0x2c, 0, 6); | 346 | hws[IMX6SX_CLK_SSI2_PODF] = imx_clk_hw_divider("ssi2_podf", "ssi2_pred", base + 0x2c, 0, 6); |
339 | clks[IMX6SX_CLK_SPDIF_PRED] = imx_clk_divider("spdif_pred", "spdif_sel", base + 0x30, 25, 3); | 347 | hws[IMX6SX_CLK_SPDIF_PRED] = imx_clk_hw_divider("spdif_pred", "spdif_sel", base + 0x30, 25, 3); |
340 | clks[IMX6SX_CLK_SPDIF_PODF] = imx_clk_divider("spdif_podf", "spdif_pred", base + 0x30, 22, 3); | 348 | hws[IMX6SX_CLK_SPDIF_PODF] = imx_clk_hw_divider("spdif_podf", "spdif_pred", base + 0x30, 22, 3); |
341 | clks[IMX6SX_CLK_AUDIO_PRED] = imx_clk_divider("audio_pred", "audio_sel", base + 0x30, 12, 3); | 349 | hws[IMX6SX_CLK_AUDIO_PRED] = imx_clk_hw_divider("audio_pred", "audio_sel", base + 0x30, 12, 3); |
342 | clks[IMX6SX_CLK_AUDIO_PODF] = imx_clk_divider("audio_podf", "audio_pred", base + 0x30, 9, 3); | 350 | hws[IMX6SX_CLK_AUDIO_PODF] = imx_clk_hw_divider("audio_podf", "audio_pred", base + 0x30, 9, 3); |
343 | clks[IMX6SX_CLK_ENET_PODF] = imx_clk_divider("enet_podf", "enet_pre_sel", base + 0x34, 12, 3); | 351 | hws[IMX6SX_CLK_ENET_PODF] = imx_clk_hw_divider("enet_podf", "enet_pre_sel", base + 0x34, 12, 3); |
344 | clks[IMX6SX_CLK_M4_PODF] = imx_clk_divider("m4_podf", "m4_sel", base + 0x34, 3, 3); | 352 | hws[IMX6SX_CLK_M4_PODF] = imx_clk_hw_divider("m4_podf", "m4_sel", base + 0x34, 3, 3); |
345 | clks[IMX6SX_CLK_ECSPI_PODF] = imx_clk_divider("ecspi_podf", "ecspi_sel", base + 0x38, 19, 6); | 353 | hws[IMX6SX_CLK_ECSPI_PODF] = imx_clk_hw_divider("ecspi_podf", "ecspi_sel", base + 0x38, 19, 6); |
346 | clks[IMX6SX_CLK_LCDIF1_PRED] = imx_clk_divider("lcdif1_pred", "lcdif1_pre_sel", base + 0x38, 12, 3); | 354 | hws[IMX6SX_CLK_LCDIF1_PRED] = imx_clk_hw_divider("lcdif1_pred", "lcdif1_pre_sel", base + 0x38, 12, 3); |
347 | clks[IMX6SX_CLK_LCDIF2_PRED] = imx_clk_divider("lcdif2_pred", "lcdif2_pre_sel", base + 0x38, 3, 3); | 355 | hws[IMX6SX_CLK_LCDIF2_PRED] = imx_clk_hw_divider("lcdif2_pred", "lcdif2_pre_sel", base + 0x38, 3, 3); |
348 | clks[IMX6SX_CLK_DISPLAY_PODF] = imx_clk_divider("display_podf", "display_sel", base + 0x3c, 16, 3); | 356 | hws[IMX6SX_CLK_DISPLAY_PODF] = imx_clk_hw_divider("display_podf", "display_sel", base + 0x3c, 16, 3); |
349 | clks[IMX6SX_CLK_CSI_PODF] = imx_clk_divider("csi_podf", "csi_sel", base + 0x3c, 11, 3); | 357 | hws[IMX6SX_CLK_CSI_PODF] = imx_clk_hw_divider("csi_podf", "csi_sel", base + 0x3c, 11, 3); |
350 | clks[IMX6SX_CLK_CKO1_PODF] = imx_clk_divider("cko1_podf", "cko1_sel", base + 0x60, 4, 3); | 358 | hws[IMX6SX_CLK_CKO1_PODF] = imx_clk_hw_divider("cko1_podf", "cko1_sel", base + 0x60, 4, 3); |
351 | clks[IMX6SX_CLK_CKO2_PODF] = imx_clk_divider("cko2_podf", "cko2_sel", base + 0x60, 21, 3); | 359 | hws[IMX6SX_CLK_CKO2_PODF] = imx_clk_hw_divider("cko2_podf", "cko2_sel", base + 0x60, 21, 3); |
352 | 360 | ||
353 | clks[IMX6SX_CLK_LDB_DI0_DIV_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7); | 361 | hws[IMX6SX_CLK_LDB_DI0_DIV_3_5] = imx_clk_hw_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7); |
354 | clks[IMX6SX_CLK_LDB_DI0_DIV_7] = imx_clk_fixed_factor("ldb_di0_div_7", "ldb_di0_sel", 1, 7); | 362 | hws[IMX6SX_CLK_LDB_DI0_DIV_7] = imx_clk_hw_fixed_factor("ldb_di0_div_7", "ldb_di0_sel", 1, 7); |
355 | clks[IMX6SX_CLK_LDB_DI1_DIV_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7); | 363 | hws[IMX6SX_CLK_LDB_DI1_DIV_3_5] = imx_clk_hw_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7); |
356 | clks[IMX6SX_CLK_LDB_DI1_DIV_7] = imx_clk_fixed_factor("ldb_di1_div_7", "ldb_di1_sel", 1, 7); | 364 | hws[IMX6SX_CLK_LDB_DI1_DIV_7] = imx_clk_hw_fixed_factor("ldb_di1_div_7", "ldb_di1_sel", 1, 7); |
357 | 365 | ||
358 | /* name reg shift width busy: reg, shift parent_names num_parents */ | 366 | /* name reg shift width busy: reg, shift parent_names num_parents */ |
359 | clks[IMX6SX_CLK_PERIPH] = imx_clk_busy_mux("periph", base + 0x14, 25, 1, base + 0x48, 5, periph_sels, ARRAY_SIZE(periph_sels)); | 367 | hws[IMX6SX_CLK_PERIPH] = imx_clk_hw_busy_mux("periph", base + 0x14, 25, 1, base + 0x48, 5, periph_sels, ARRAY_SIZE(periph_sels)); |
360 | clks[IMX6SX_CLK_PERIPH2] = imx_clk_busy_mux("periph2", base + 0x14, 26, 1, base + 0x48, 3, periph2_sels, ARRAY_SIZE(periph2_sels)); | 368 | hws[IMX6SX_CLK_PERIPH2] = imx_clk_hw_busy_mux("periph2", base + 0x14, 26, 1, base + 0x48, 3, periph2_sels, ARRAY_SIZE(periph2_sels)); |
361 | /* name parent_name reg shift width busy: reg, shift */ | 369 | /* name parent_name reg shift width busy: reg, shift */ |
362 | clks[IMX6SX_CLK_OCRAM_PODF] = imx_clk_busy_divider("ocram_podf", "ocram_sel", base + 0x14, 16, 3, base + 0x48, 0); | 370 | hws[IMX6SX_CLK_OCRAM_PODF] = imx_clk_hw_busy_divider("ocram_podf", "ocram_sel", base + 0x14, 16, 3, base + 0x48, 0); |
363 | clks[IMX6SX_CLK_AHB] = imx_clk_busy_divider("ahb", "periph", base + 0x14, 10, 3, base + 0x48, 1); | 371 | hws[IMX6SX_CLK_AHB] = imx_clk_hw_busy_divider("ahb", "periph", base + 0x14, 10, 3, base + 0x48, 1); |
364 | clks[IMX6SX_CLK_MMDC_PODF] = imx_clk_busy_divider("mmdc_podf", "periph2", base + 0x14, 3, 3, base + 0x48, 2); | 372 | hws[IMX6SX_CLK_MMDC_PODF] = imx_clk_hw_busy_divider("mmdc_podf", "periph2", base + 0x14, 3, 3, base + 0x48, 2); |
365 | clks[IMX6SX_CLK_ARM] = imx_clk_busy_divider("arm", "pll1_sw", base + 0x10, 0, 3, base + 0x48, 16); | 373 | hws[IMX6SX_CLK_ARM] = imx_clk_hw_busy_divider("arm", "pll1_sw", base + 0x10, 0, 3, base + 0x48, 16); |
366 | 374 | ||
367 | /* name parent_name reg shift */ | 375 | /* name parent_name reg shift */ |
368 | /* CCGR0 */ | 376 | /* CCGR0 */ |
369 | clks[IMX6SX_CLK_AIPS_TZ1] = imx_clk_gate2_flags("aips_tz1", "ahb", base + 0x68, 0, CLK_IS_CRITICAL); | 377 | hws[IMX6SX_CLK_AIPS_TZ1] = imx_clk_hw_gate2_flags("aips_tz1", "ahb", base + 0x68, 0, CLK_IS_CRITICAL); |
370 | clks[IMX6SX_CLK_AIPS_TZ2] = imx_clk_gate2_flags("aips_tz2", "ahb", base + 0x68, 2, CLK_IS_CRITICAL); | 378 | hws[IMX6SX_CLK_AIPS_TZ2] = imx_clk_hw_gate2_flags("aips_tz2", "ahb", base + 0x68, 2, CLK_IS_CRITICAL); |
371 | clks[IMX6SX_CLK_APBH_DMA] = imx_clk_gate2("apbh_dma", "usdhc3", base + 0x68, 4); | 379 | hws[IMX6SX_CLK_APBH_DMA] = imx_clk_hw_gate2("apbh_dma", "usdhc3", base + 0x68, 4); |
372 | clks[IMX6SX_CLK_ASRC_MEM] = imx_clk_gate2_shared("asrc_mem", "ahb", base + 0x68, 6, &share_count_asrc); | 380 | hws[IMX6SX_CLK_ASRC_MEM] = imx_clk_hw_gate2_shared("asrc_mem", "ahb", base + 0x68, 6, &share_count_asrc); |
373 | clks[IMX6SX_CLK_ASRC_IPG] = imx_clk_gate2_shared("asrc_ipg", "ahb", base + 0x68, 6, &share_count_asrc); | 381 | hws[IMX6SX_CLK_ASRC_IPG] = imx_clk_hw_gate2_shared("asrc_ipg", "ahb", base + 0x68, 6, &share_count_asrc); |
374 | clks[IMX6SX_CLK_CAAM_MEM] = imx_clk_gate2("caam_mem", "ahb", base + 0x68, 8); | 382 | hws[IMX6SX_CLK_CAAM_MEM] = imx_clk_hw_gate2("caam_mem", "ahb", base + 0x68, 8); |
375 | clks[IMX6SX_CLK_CAAM_ACLK] = imx_clk_gate2("caam_aclk", "ahb", base + 0x68, 10); | 383 | hws[IMX6SX_CLK_CAAM_ACLK] = imx_clk_hw_gate2("caam_aclk", "ahb", base + 0x68, 10); |
376 | clks[IMX6SX_CLK_CAAM_IPG] = imx_clk_gate2("caam_ipg", "ipg", base + 0x68, 12); | 384 | hws[IMX6SX_CLK_CAAM_IPG] = imx_clk_hw_gate2("caam_ipg", "ipg", base + 0x68, 12); |
377 | clks[IMX6SX_CLK_CAN1_IPG] = imx_clk_gate2("can1_ipg", "ipg", base + 0x68, 14); | 385 | hws[IMX6SX_CLK_CAN1_IPG] = imx_clk_hw_gate2("can1_ipg", "ipg", base + 0x68, 14); |
378 | clks[IMX6SX_CLK_CAN1_SERIAL] = imx_clk_gate2("can1_serial", "can_podf", base + 0x68, 16); | 386 | hws[IMX6SX_CLK_CAN1_SERIAL] = imx_clk_hw_gate2("can1_serial", "can_podf", base + 0x68, 16); |
379 | clks[IMX6SX_CLK_CAN2_IPG] = imx_clk_gate2("can2_ipg", "ipg", base + 0x68, 18); | 387 | hws[IMX6SX_CLK_CAN2_IPG] = imx_clk_hw_gate2("can2_ipg", "ipg", base + 0x68, 18); |
380 | clks[IMX6SX_CLK_CAN2_SERIAL] = imx_clk_gate2("can2_serial", "can_podf", base + 0x68, 20); | 388 | hws[IMX6SX_CLK_CAN2_SERIAL] = imx_clk_hw_gate2("can2_serial", "can_podf", base + 0x68, 20); |
381 | clks[IMX6SX_CLK_DCIC1] = imx_clk_gate2("dcic1", "display_podf", base + 0x68, 24); | 389 | hws[IMX6SX_CLK_DCIC1] = imx_clk_hw_gate2("dcic1", "display_podf", base + 0x68, 24); |
382 | clks[IMX6SX_CLK_DCIC2] = imx_clk_gate2("dcic2", "display_podf", base + 0x68, 26); | 390 | hws[IMX6SX_CLK_DCIC2] = imx_clk_hw_gate2("dcic2", "display_podf", base + 0x68, 26); |
383 | clks[IMX6SX_CLK_AIPS_TZ3] = imx_clk_gate2_flags("aips_tz3", "ahb", base + 0x68, 30, CLK_IS_CRITICAL); | 391 | hws[IMX6SX_CLK_AIPS_TZ3] = imx_clk_hw_gate2_flags("aips_tz3", "ahb", base + 0x68, 30, CLK_IS_CRITICAL); |
384 | 392 | ||
385 | /* CCGR1 */ | 393 | /* CCGR1 */ |
386 | clks[IMX6SX_CLK_ECSPI1] = imx_clk_gate2("ecspi1", "ecspi_podf", base + 0x6c, 0); | 394 | hws[IMX6SX_CLK_ECSPI1] = imx_clk_hw_gate2("ecspi1", "ecspi_podf", base + 0x6c, 0); |
387 | clks[IMX6SX_CLK_ECSPI2] = imx_clk_gate2("ecspi2", "ecspi_podf", base + 0x6c, 2); | 395 | hws[IMX6SX_CLK_ECSPI2] = imx_clk_hw_gate2("ecspi2", "ecspi_podf", base + 0x6c, 2); |
388 | clks[IMX6SX_CLK_ECSPI3] = imx_clk_gate2("ecspi3", "ecspi_podf", base + 0x6c, 4); | 396 | hws[IMX6SX_CLK_ECSPI3] = imx_clk_hw_gate2("ecspi3", "ecspi_podf", base + 0x6c, 4); |
389 | clks[IMX6SX_CLK_ECSPI4] = imx_clk_gate2("ecspi4", "ecspi_podf", base + 0x6c, 6); | 397 | hws[IMX6SX_CLK_ECSPI4] = imx_clk_hw_gate2("ecspi4", "ecspi_podf", base + 0x6c, 6); |
390 | clks[IMX6SX_CLK_ECSPI5] = imx_clk_gate2("ecspi5", "ecspi_podf", base + 0x6c, 8); | 398 | hws[IMX6SX_CLK_ECSPI5] = imx_clk_hw_gate2("ecspi5", "ecspi_podf", base + 0x6c, 8); |
391 | clks[IMX6SX_CLK_EPIT1] = imx_clk_gate2("epit1", "perclk", base + 0x6c, 12); | 399 | hws[IMX6SX_CLK_EPIT1] = imx_clk_hw_gate2("epit1", "perclk", base + 0x6c, 12); |
392 | clks[IMX6SX_CLK_EPIT2] = imx_clk_gate2("epit2", "perclk", base + 0x6c, 14); | 400 | hws[IMX6SX_CLK_EPIT2] = imx_clk_hw_gate2("epit2", "perclk", base + 0x6c, 14); |
393 | clks[IMX6SX_CLK_ESAI_EXTAL] = imx_clk_gate2_shared("esai_extal", "esai_podf", base + 0x6c, 16, &share_count_esai); | 401 | hws[IMX6SX_CLK_ESAI_EXTAL] = imx_clk_hw_gate2_shared("esai_extal", "esai_podf", base + 0x6c, 16, &share_count_esai); |
394 | clks[IMX6SX_CLK_ESAI_IPG] = imx_clk_gate2_shared("esai_ipg", "ahb", base + 0x6c, 16, &share_count_esai); | 402 | hws[IMX6SX_CLK_ESAI_IPG] = imx_clk_hw_gate2_shared("esai_ipg", "ahb", base + 0x6c, 16, &share_count_esai); |
395 | clks[IMX6SX_CLK_ESAI_MEM] = imx_clk_gate2_shared("esai_mem", "ahb", base + 0x6c, 16, &share_count_esai); | 403 | hws[IMX6SX_CLK_ESAI_MEM] = imx_clk_hw_gate2_shared("esai_mem", "ahb", base + 0x6c, 16, &share_count_esai); |
396 | clks[IMX6SX_CLK_WAKEUP] = imx_clk_gate2_flags("wakeup", "ipg", base + 0x6c, 18, CLK_IS_CRITICAL); | 404 | hws[IMX6SX_CLK_WAKEUP] = imx_clk_hw_gate2_flags("wakeup", "ipg", base + 0x6c, 18, CLK_IS_CRITICAL); |
397 | clks[IMX6SX_CLK_GPT_BUS] = imx_clk_gate2("gpt_bus", "perclk", base + 0x6c, 20); | 405 | hws[IMX6SX_CLK_GPT_BUS] = imx_clk_hw_gate2("gpt_bus", "perclk", base + 0x6c, 20); |
398 | clks[IMX6SX_CLK_GPT_SERIAL] = imx_clk_gate2("gpt_serial", "perclk", base + 0x6c, 22); | 406 | hws[IMX6SX_CLK_GPT_SERIAL] = imx_clk_hw_gate2("gpt_serial", "perclk", base + 0x6c, 22); |
399 | clks[IMX6SX_CLK_GPU] = imx_clk_gate2("gpu", "gpu_core_podf", base + 0x6c, 26); | 407 | hws[IMX6SX_CLK_GPU] = imx_clk_hw_gate2("gpu", "gpu_core_podf", base + 0x6c, 26); |
400 | clks[IMX6SX_CLK_OCRAM_S] = imx_clk_gate2("ocram_s", "ahb", base + 0x6c, 28); | 408 | hws[IMX6SX_CLK_OCRAM_S] = imx_clk_hw_gate2("ocram_s", "ahb", base + 0x6c, 28); |
401 | clks[IMX6SX_CLK_CANFD] = imx_clk_gate2("canfd", "can_podf", base + 0x6c, 30); | 409 | hws[IMX6SX_CLK_CANFD] = imx_clk_hw_gate2("canfd", "can_podf", base + 0x6c, 30); |
402 | 410 | ||
403 | /* CCGR2 */ | 411 | /* CCGR2 */ |
404 | clks[IMX6SX_CLK_CSI] = imx_clk_gate2("csi", "csi_podf", base + 0x70, 2); | 412 | hws[IMX6SX_CLK_CSI] = imx_clk_hw_gate2("csi", "csi_podf", base + 0x70, 2); |
405 | clks[IMX6SX_CLK_I2C1] = imx_clk_gate2("i2c1", "perclk", base + 0x70, 6); | 413 | hws[IMX6SX_CLK_I2C1] = imx_clk_hw_gate2("i2c1", "perclk", base + 0x70, 6); |
406 | clks[IMX6SX_CLK_I2C2] = imx_clk_gate2("i2c2", "perclk", base + 0x70, 8); | 414 | hws[IMX6SX_CLK_I2C2] = imx_clk_hw_gate2("i2c2", "perclk", base + 0x70, 8); |
407 | clks[IMX6SX_CLK_I2C3] = imx_clk_gate2("i2c3", "perclk", base + 0x70, 10); | 415 | hws[IMX6SX_CLK_I2C3] = imx_clk_hw_gate2("i2c3", "perclk", base + 0x70, 10); |
408 | clks[IMX6SX_CLK_OCOTP] = imx_clk_gate2("ocotp", "ipg", base + 0x70, 12); | 416 | hws[IMX6SX_CLK_OCOTP] = imx_clk_hw_gate2("ocotp", "ipg", base + 0x70, 12); |
409 | clks[IMX6SX_CLK_IOMUXC] = imx_clk_gate2("iomuxc", "lcdif1_podf", base + 0x70, 14); | 417 | hws[IMX6SX_CLK_IOMUXC] = imx_clk_hw_gate2("iomuxc", "lcdif1_podf", base + 0x70, 14); |
410 | clks[IMX6SX_CLK_IPMUX1] = imx_clk_gate2_flags("ipmux1", "ahb", base + 0x70, 16, CLK_IS_CRITICAL); | 418 | hws[IMX6SX_CLK_IPMUX1] = imx_clk_hw_gate2_flags("ipmux1", "ahb", base + 0x70, 16, CLK_IS_CRITICAL); |
411 | clks[IMX6SX_CLK_IPMUX2] = imx_clk_gate2_flags("ipmux2", "ahb", base + 0x70, 18, CLK_IS_CRITICAL); | 419 | hws[IMX6SX_CLK_IPMUX2] = imx_clk_hw_gate2_flags("ipmux2", "ahb", base + 0x70, 18, CLK_IS_CRITICAL); |
412 | clks[IMX6SX_CLK_IPMUX3] = imx_clk_gate2_flags("ipmux3", "ahb", base + 0x70, 20, CLK_IS_CRITICAL); | 420 | hws[IMX6SX_CLK_IPMUX3] = imx_clk_hw_gate2_flags("ipmux3", "ahb", base + 0x70, 20, CLK_IS_CRITICAL); |
413 | clks[IMX6SX_CLK_TZASC1] = imx_clk_gate2_flags("tzasc1", "mmdc_podf", base + 0x70, 22, CLK_IS_CRITICAL); | 421 | hws[IMX6SX_CLK_TZASC1] = imx_clk_hw_gate2_flags("tzasc1", "mmdc_podf", base + 0x70, 22, CLK_IS_CRITICAL); |
414 | clks[IMX6SX_CLK_LCDIF_APB] = imx_clk_gate2("lcdif_apb", "display_podf", base + 0x70, 28); | 422 | hws[IMX6SX_CLK_LCDIF_APB] = imx_clk_hw_gate2("lcdif_apb", "display_podf", base + 0x70, 28); |
415 | clks[IMX6SX_CLK_PXP_AXI] = imx_clk_gate2("pxp_axi", "display_podf", base + 0x70, 30); | 423 | hws[IMX6SX_CLK_PXP_AXI] = imx_clk_hw_gate2("pxp_axi", "display_podf", base + 0x70, 30); |
416 | 424 | ||
417 | /* CCGR3 */ | 425 | /* CCGR3 */ |
418 | clks[IMX6SX_CLK_M4] = imx_clk_gate2("m4", "m4_podf", base + 0x74, 2); | 426 | hws[IMX6SX_CLK_M4] = imx_clk_hw_gate2("m4", "m4_podf", base + 0x74, 2); |
419 | clks[IMX6SX_CLK_ENET] = imx_clk_gate2("enet", "ipg", base + 0x74, 4); | 427 | hws[IMX6SX_CLK_ENET] = imx_clk_hw_gate2("enet", "ipg", base + 0x74, 4); |
420 | clks[IMX6SX_CLK_ENET_AHB] = imx_clk_gate2("enet_ahb", "enet_sel", base + 0x74, 4); | 428 | hws[IMX6SX_CLK_ENET_AHB] = imx_clk_hw_gate2("enet_ahb", "enet_sel", base + 0x74, 4); |
421 | clks[IMX6SX_CLK_DISPLAY_AXI] = imx_clk_gate2("display_axi", "display_podf", base + 0x74, 6); | 429 | hws[IMX6SX_CLK_DISPLAY_AXI] = imx_clk_hw_gate2("display_axi", "display_podf", base + 0x74, 6); |
422 | clks[IMX6SX_CLK_LCDIF2_PIX] = imx_clk_gate2("lcdif2_pix", "lcdif2_sel", base + 0x74, 8); | 430 | hws[IMX6SX_CLK_LCDIF2_PIX] = imx_clk_hw_gate2("lcdif2_pix", "lcdif2_sel", base + 0x74, 8); |
423 | clks[IMX6SX_CLK_LCDIF1_PIX] = imx_clk_gate2("lcdif1_pix", "lcdif1_sel", base + 0x74, 10); | 431 | hws[IMX6SX_CLK_LCDIF1_PIX] = imx_clk_hw_gate2("lcdif1_pix", "lcdif1_sel", base + 0x74, 10); |
424 | clks[IMX6SX_CLK_LDB_DI0] = imx_clk_gate2("ldb_di0", "ldb_di0_div_sel", base + 0x74, 12); | 432 | hws[IMX6SX_CLK_LDB_DI0] = imx_clk_hw_gate2("ldb_di0", "ldb_di0_div_sel", base + 0x74, 12); |
425 | clks[IMX6SX_CLK_QSPI1] = imx_clk_gate2("qspi1", "qspi1_podf", base + 0x74, 14); | 433 | hws[IMX6SX_CLK_QSPI1] = imx_clk_hw_gate2("qspi1", "qspi1_podf", base + 0x74, 14); |
426 | clks[IMX6SX_CLK_MLB] = imx_clk_gate2("mlb", "ahb", base + 0x74, 18); | 434 | hws[IMX6SX_CLK_MLB] = imx_clk_hw_gate2("mlb", "ahb", base + 0x74, 18); |
427 | clks[IMX6SX_CLK_MMDC_P0_FAST] = imx_clk_gate2_flags("mmdc_p0_fast", "mmdc_podf", base + 0x74, 20, CLK_IS_CRITICAL); | 435 | hws[IMX6SX_CLK_MMDC_P0_FAST] = imx_clk_hw_gate2_flags("mmdc_p0_fast", "mmdc_podf", base + 0x74, 20, CLK_IS_CRITICAL); |
428 | clks[IMX6SX_CLK_MMDC_P0_IPG] = imx_clk_gate2_flags("mmdc_p0_ipg", "ipg", base + 0x74, 24, CLK_IS_CRITICAL); | 436 | hws[IMX6SX_CLK_MMDC_P0_IPG] = imx_clk_hw_gate2_flags("mmdc_p0_ipg", "ipg", base + 0x74, 24, CLK_IS_CRITICAL); |
429 | clks[IMX6SX_CLK_MMDC_P1_IPG] = imx_clk_gate2("mmdc_p1_ipg", "ipg", base + 0x74, 26); | 437 | hws[IMX6SX_CLK_MMDC_P1_IPG] = imx_clk_hw_gate2_flags("mmdc_p1_ipg", "ipg", base + 0x74, 26, CLK_IS_CRITICAL); |
430 | clks[IMX6SX_CLK_OCRAM] = imx_clk_gate2_flags("ocram", "ocram_podf", base + 0x74, 28, CLK_IS_CRITICAL); | 438 | hws[IMX6SX_CLK_OCRAM] = imx_clk_hw_gate2_flags("ocram", "ocram_podf", base + 0x74, 28, CLK_IS_CRITICAL); |
431 | 439 | ||
432 | /* CCGR4 */ | 440 | /* CCGR4 */ |
433 | clks[IMX6SX_CLK_PCIE_AXI] = imx_clk_gate2("pcie_axi", "display_podf", base + 0x78, 0); | 441 | hws[IMX6SX_CLK_PCIE_AXI] = imx_clk_hw_gate2("pcie_axi", "display_podf", base + 0x78, 0); |
434 | clks[IMX6SX_CLK_QSPI2] = imx_clk_gate2("qspi2", "qspi2_podf", base + 0x78, 10); | 442 | hws[IMX6SX_CLK_QSPI2] = imx_clk_hw_gate2("qspi2", "qspi2_podf", base + 0x78, 10); |
435 | clks[IMX6SX_CLK_PER1_BCH] = imx_clk_gate2("per1_bch", "usdhc3", base + 0x78, 12); | 443 | hws[IMX6SX_CLK_PER1_BCH] = imx_clk_hw_gate2("per1_bch", "usdhc3", base + 0x78, 12); |
436 | clks[IMX6SX_CLK_PER2_MAIN] = imx_clk_gate2_flags("per2_main", "ahb", base + 0x78, 14, CLK_IS_CRITICAL); | 444 | hws[IMX6SX_CLK_PER2_MAIN] = imx_clk_hw_gate2_flags("per2_main", "ahb", base + 0x78, 14, CLK_IS_CRITICAL); |
437 | clks[IMX6SX_CLK_PWM1] = imx_clk_gate2("pwm1", "perclk", base + 0x78, 16); | 445 | hws[IMX6SX_CLK_PWM1] = imx_clk_hw_gate2("pwm1", "perclk", base + 0x78, 16); |
438 | clks[IMX6SX_CLK_PWM2] = imx_clk_gate2("pwm2", "perclk", base + 0x78, 18); | 446 | hws[IMX6SX_CLK_PWM2] = imx_clk_hw_gate2("pwm2", "perclk", base + 0x78, 18); |
439 | clks[IMX6SX_CLK_PWM3] = imx_clk_gate2("pwm3", "perclk", base + 0x78, 20); | 447 | hws[IMX6SX_CLK_PWM3] = imx_clk_hw_gate2("pwm3", "perclk", base + 0x78, 20); |
440 | clks[IMX6SX_CLK_PWM4] = imx_clk_gate2("pwm4", "perclk", base + 0x78, 22); | 448 | hws[IMX6SX_CLK_PWM4] = imx_clk_hw_gate2("pwm4", "perclk", base + 0x78, 22); |
441 | clks[IMX6SX_CLK_GPMI_BCH_APB] = imx_clk_gate2("gpmi_bch_apb", "usdhc3", base + 0x78, 24); | 449 | hws[IMX6SX_CLK_GPMI_BCH_APB] = imx_clk_hw_gate2("gpmi_bch_apb", "usdhc3", base + 0x78, 24); |
442 | clks[IMX6SX_CLK_GPMI_BCH] = imx_clk_gate2("gpmi_bch", "usdhc4", base + 0x78, 26); | 450 | hws[IMX6SX_CLK_GPMI_BCH] = imx_clk_hw_gate2("gpmi_bch", "usdhc4", base + 0x78, 26); |
443 | clks[IMX6SX_CLK_GPMI_IO] = imx_clk_gate2("gpmi_io", "qspi2_podf", base + 0x78, 28); | 451 | hws[IMX6SX_CLK_GPMI_IO] = imx_clk_hw_gate2("gpmi_io", "qspi2_podf", base + 0x78, 28); |
444 | clks[IMX6SX_CLK_GPMI_APB] = imx_clk_gate2("gpmi_apb", "usdhc3", base + 0x78, 30); | 452 | hws[IMX6SX_CLK_GPMI_APB] = imx_clk_hw_gate2("gpmi_apb", "usdhc3", base + 0x78, 30); |
445 | 453 | ||
446 | /* CCGR5 */ | 454 | /* CCGR5 */ |
447 | clks[IMX6SX_CLK_ROM] = imx_clk_gate2_flags("rom", "ahb", base + 0x7c, 0, CLK_IS_CRITICAL); | 455 | hws[IMX6SX_CLK_ROM] = imx_clk_hw_gate2_flags("rom", "ahb", base + 0x7c, 0, CLK_IS_CRITICAL); |
448 | clks[IMX6SX_CLK_SDMA] = imx_clk_gate2("sdma", "ahb", base + 0x7c, 6); | 456 | hws[IMX6SX_CLK_SDMA] = imx_clk_hw_gate2("sdma", "ahb", base + 0x7c, 6); |
449 | clks[IMX6SX_CLK_SPBA] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12); | 457 | hws[IMX6SX_CLK_SPBA] = imx_clk_hw_gate2("spba", "ipg", base + 0x7c, 12); |
450 | clks[IMX6SX_CLK_AUDIO] = imx_clk_gate2_shared("audio", "audio_podf", base + 0x7c, 14, &share_count_audio); | 458 | hws[IMX6SX_CLK_AUDIO] = imx_clk_hw_gate2_shared("audio", "audio_podf", base + 0x7c, 14, &share_count_audio); |
451 | clks[IMX6SX_CLK_SPDIF] = imx_clk_gate2_shared("spdif", "spdif_podf", base + 0x7c, 14, &share_count_audio); | 459 | hws[IMX6SX_CLK_SPDIF] = imx_clk_hw_gate2_shared("spdif", "spdif_podf", base + 0x7c, 14, &share_count_audio); |
452 | clks[IMX6SX_CLK_SPDIF_GCLK] = imx_clk_gate2_shared("spdif_gclk", "ipg", base + 0x7c, 14, &share_count_audio); | 460 | hws[IMX6SX_CLK_SPDIF_GCLK] = imx_clk_hw_gate2_shared("spdif_gclk", "ipg", base + 0x7c, 14, &share_count_audio); |
453 | clks[IMX6SX_CLK_SSI1_IPG] = imx_clk_gate2_shared("ssi1_ipg", "ipg", base + 0x7c, 18, &share_count_ssi1); | 461 | hws[IMX6SX_CLK_SSI1_IPG] = imx_clk_hw_gate2_shared("ssi1_ipg", "ipg", base + 0x7c, 18, &share_count_ssi1); |
454 | clks[IMX6SX_CLK_SSI2_IPG] = imx_clk_gate2_shared("ssi2_ipg", "ipg", base + 0x7c, 20, &share_count_ssi2); | 462 | hws[IMX6SX_CLK_SSI2_IPG] = imx_clk_hw_gate2_shared("ssi2_ipg", "ipg", base + 0x7c, 20, &share_count_ssi2); |
455 | clks[IMX6SX_CLK_SSI3_IPG] = imx_clk_gate2_shared("ssi3_ipg", "ipg", base + 0x7c, 22, &share_count_ssi3); | 463 | hws[IMX6SX_CLK_SSI3_IPG] = imx_clk_hw_gate2_shared("ssi3_ipg", "ipg", base + 0x7c, 22, &share_count_ssi3); |
456 | clks[IMX6SX_CLK_SSI1] = imx_clk_gate2_shared("ssi1", "ssi1_podf", base + 0x7c, 18, &share_count_ssi1); | 464 | hws[IMX6SX_CLK_SSI1] = imx_clk_hw_gate2_shared("ssi1", "ssi1_podf", base + 0x7c, 18, &share_count_ssi1); |
457 | clks[IMX6SX_CLK_SSI2] = imx_clk_gate2_shared("ssi2", "ssi2_podf", base + 0x7c, 20, &share_count_ssi2); | 465 | hws[IMX6SX_CLK_SSI2] = imx_clk_hw_gate2_shared("ssi2", "ssi2_podf", base + 0x7c, 20, &share_count_ssi2); |
458 | clks[IMX6SX_CLK_SSI3] = imx_clk_gate2_shared("ssi3", "ssi3_podf", base + 0x7c, 22, &share_count_ssi3); | 466 | hws[IMX6SX_CLK_SSI3] = imx_clk_hw_gate2_shared("ssi3", "ssi3_podf", base + 0x7c, 22, &share_count_ssi3); |
459 | clks[IMX6SX_CLK_UART_IPG] = imx_clk_gate2("uart_ipg", "ipg", base + 0x7c, 24); | 467 | hws[IMX6SX_CLK_UART_IPG] = imx_clk_hw_gate2("uart_ipg", "ipg", base + 0x7c, 24); |
460 | clks[IMX6SX_CLK_UART_SERIAL] = imx_clk_gate2("uart_serial", "uart_podf", base + 0x7c, 26); | 468 | hws[IMX6SX_CLK_UART_SERIAL] = imx_clk_hw_gate2("uart_serial", "uart_podf", base + 0x7c, 26); |
461 | clks[IMX6SX_CLK_SAI1_IPG] = imx_clk_gate2_shared("sai1_ipg", "ipg", base + 0x7c, 28, &share_count_sai1); | 469 | hws[IMX6SX_CLK_SAI1_IPG] = imx_clk_hw_gate2_shared("sai1_ipg", "ipg", base + 0x7c, 28, &share_count_sai1); |
462 | clks[IMX6SX_CLK_SAI2_IPG] = imx_clk_gate2_shared("sai2_ipg", "ipg", base + 0x7c, 30, &share_count_sai2); | 470 | hws[IMX6SX_CLK_SAI2_IPG] = imx_clk_hw_gate2_shared("sai2_ipg", "ipg", base + 0x7c, 30, &share_count_sai2); |
463 | clks[IMX6SX_CLK_SAI1] = imx_clk_gate2_shared("sai1", "ssi1_podf", base + 0x7c, 28, &share_count_sai1); | 471 | hws[IMX6SX_CLK_SAI1] = imx_clk_hw_gate2_shared("sai1", "ssi1_podf", base + 0x7c, 28, &share_count_sai1); |
464 | clks[IMX6SX_CLK_SAI2] = imx_clk_gate2_shared("sai2", "ssi2_podf", base + 0x7c, 30, &share_count_sai2); | 472 | hws[IMX6SX_CLK_SAI2] = imx_clk_hw_gate2_shared("sai2", "ssi2_podf", base + 0x7c, 30, &share_count_sai2); |
465 | 473 | ||
466 | /* CCGR6 */ | 474 | /* CCGR6 */ |
467 | clks[IMX6SX_CLK_USBOH3] = imx_clk_gate2("usboh3", "ipg", base + 0x80, 0); | 475 | hws[IMX6SX_CLK_USBOH3] = imx_clk_hw_gate2("usboh3", "ipg", base + 0x80, 0); |
468 | clks[IMX6SX_CLK_USDHC1] = imx_clk_gate2("usdhc1", "usdhc1_podf", base + 0x80, 2); | 476 | hws[IMX6SX_CLK_USDHC1] = imx_clk_hw_gate2("usdhc1", "usdhc1_podf", base + 0x80, 2); |
469 | clks[IMX6SX_CLK_USDHC2] = imx_clk_gate2("usdhc2", "usdhc2_podf", base + 0x80, 4); | 477 | hws[IMX6SX_CLK_USDHC2] = imx_clk_hw_gate2("usdhc2", "usdhc2_podf", base + 0x80, 4); |
470 | clks[IMX6SX_CLK_USDHC3] = imx_clk_gate2("usdhc3", "usdhc3_podf", base + 0x80, 6); | 478 | hws[IMX6SX_CLK_USDHC3] = imx_clk_hw_gate2("usdhc3", "usdhc3_podf", base + 0x80, 6); |
471 | clks[IMX6SX_CLK_USDHC4] = imx_clk_gate2("usdhc4", "usdhc4_podf", base + 0x80, 8); | 479 | hws[IMX6SX_CLK_USDHC4] = imx_clk_hw_gate2("usdhc4", "usdhc4_podf", base + 0x80, 8); |
472 | clks[IMX6SX_CLK_EIM_SLOW] = imx_clk_gate2("eim_slow", "eim_slow_podf", base + 0x80, 10); | 480 | hws[IMX6SX_CLK_EIM_SLOW] = imx_clk_hw_gate2("eim_slow", "eim_slow_podf", base + 0x80, 10); |
473 | clks[IMX6SX_CLK_PWM8] = imx_clk_gate2("pwm8", "perclk", base + 0x80, 16); | 481 | hws[IMX6SX_CLK_PWM8] = imx_clk_hw_gate2("pwm8", "perclk", base + 0x80, 16); |
474 | clks[IMX6SX_CLK_VADC] = imx_clk_gate2("vadc", "vid_podf", base + 0x80, 20); | 482 | hws[IMX6SX_CLK_VADC] = imx_clk_hw_gate2("vadc", "vid_podf", base + 0x80, 20); |
475 | clks[IMX6SX_CLK_GIS] = imx_clk_gate2("gis", "display_podf", base + 0x80, 22); | 483 | hws[IMX6SX_CLK_GIS] = imx_clk_hw_gate2("gis", "display_podf", base + 0x80, 22); |
476 | clks[IMX6SX_CLK_I2C4] = imx_clk_gate2("i2c4", "perclk", base + 0x80, 24); | 484 | hws[IMX6SX_CLK_I2C4] = imx_clk_hw_gate2("i2c4", "perclk", base + 0x80, 24); |
477 | clks[IMX6SX_CLK_PWM5] = imx_clk_gate2("pwm5", "perclk", base + 0x80, 26); | 485 | hws[IMX6SX_CLK_PWM5] = imx_clk_hw_gate2("pwm5", "perclk", base + 0x80, 26); |
478 | clks[IMX6SX_CLK_PWM6] = imx_clk_gate2("pwm6", "perclk", base + 0x80, 28); | 486 | hws[IMX6SX_CLK_PWM6] = imx_clk_hw_gate2("pwm6", "perclk", base + 0x80, 28); |
479 | clks[IMX6SX_CLK_PWM7] = imx_clk_gate2("pwm7", "perclk", base + 0x80, 30); | 487 | hws[IMX6SX_CLK_PWM7] = imx_clk_hw_gate2("pwm7", "perclk", base + 0x80, 30); |
480 | 488 | ||
481 | clks[IMX6SX_CLK_CKO1] = imx_clk_gate("cko1", "cko1_podf", base + 0x60, 7); | 489 | hws[IMX6SX_CLK_CKO1] = imx_clk_hw_gate("cko1", "cko1_podf", base + 0x60, 7); |
482 | clks[IMX6SX_CLK_CKO2] = imx_clk_gate("cko2", "cko2_podf", base + 0x60, 24); | 490 | hws[IMX6SX_CLK_CKO2] = imx_clk_hw_gate("cko2", "cko2_podf", base + 0x60, 24); |
483 | 491 | ||
484 | /* mask handshake of mmdc */ | 492 | /* mask handshake of mmdc */ |
485 | writel_relaxed(BM_CCM_CCDR_MMDC_CH0_MASK, base + CCDR); | 493 | imx_mmdc_mask_handshake(base, 0); |
486 | 494 | ||
487 | imx_check_clocks(clks, ARRAY_SIZE(clks)); | 495 | imx_check_clk_hws(hws, IMX6SX_CLK_CLK_END); |
488 | 496 | ||
489 | clk_data.clks = clks; | 497 | of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data); |
490 | clk_data.clk_num = ARRAY_SIZE(clks); | ||
491 | of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); | ||
492 | 498 | ||
493 | if (IS_ENABLED(CONFIG_USB_MXS_PHY)) { | 499 | if (IS_ENABLED(CONFIG_USB_MXS_PHY)) { |
494 | clk_prepare_enable(clks[IMX6SX_CLK_USBPHY1_GATE]); | 500 | clk_prepare_enable(hws[IMX6SX_CLK_USBPHY1_GATE]->clk); |
495 | clk_prepare_enable(clks[IMX6SX_CLK_USBPHY2_GATE]); | 501 | clk_prepare_enable(hws[IMX6SX_CLK_USBPHY2_GATE]->clk); |
496 | } | 502 | } |
497 | 503 | ||
498 | /* Set the default 132MHz for EIM module */ | 504 | /* Set the default 132MHz for EIM module */ |
499 | clk_set_parent(clks[IMX6SX_CLK_EIM_SLOW_SEL], clks[IMX6SX_CLK_PLL2_PFD2]); | 505 | clk_set_parent(hws[IMX6SX_CLK_EIM_SLOW_SEL]->clk, hws[IMX6SX_CLK_PLL2_PFD2]->clk); |
500 | clk_set_rate(clks[IMX6SX_CLK_EIM_SLOW], 132000000); | 506 | clk_set_rate(hws[IMX6SX_CLK_EIM_SLOW]->clk, 132000000); |
501 | 507 | ||
502 | /* set parent clock for LCDIF1 pixel clock */ | 508 | /* set parent clock for LCDIF1 pixel clock */ |
503 | clk_set_parent(clks[IMX6SX_CLK_LCDIF1_PRE_SEL], clks[IMX6SX_CLK_PLL5_VIDEO_DIV]); | 509 | clk_set_parent(hws[IMX6SX_CLK_LCDIF1_PRE_SEL]->clk, hws[IMX6SX_CLK_PLL5_VIDEO_DIV]->clk); |
504 | clk_set_parent(clks[IMX6SX_CLK_LCDIF1_SEL], clks[IMX6SX_CLK_LCDIF1_PODF]); | 510 | clk_set_parent(hws[IMX6SX_CLK_LCDIF1_SEL]->clk, hws[IMX6SX_CLK_LCDIF1_PODF]->clk); |
505 | 511 | ||
506 | /* Set the parent clks of PCIe lvds1 and pcie_axi to be pcie ref, axi */ | 512 | /* Set the parent clks of PCIe lvds1 and pcie_axi to be pcie ref, axi */ |
507 | if (clk_set_parent(clks[IMX6SX_CLK_LVDS1_SEL], clks[IMX6SX_CLK_PCIE_REF_125M])) | 513 | if (clk_set_parent(hws[IMX6SX_CLK_LVDS1_SEL]->clk, hws[IMX6SX_CLK_PCIE_REF_125M]->clk)) |
508 | pr_err("Failed to set pcie bus parent clk.\n"); | 514 | pr_err("Failed to set pcie bus parent clk.\n"); |
509 | if (clk_set_parent(clks[IMX6SX_CLK_PCIE_AXI_SEL], clks[IMX6SX_CLK_AXI])) | ||
510 | pr_err("Failed to set pcie parent clk.\n"); | ||
511 | 515 | ||
512 | /* | 516 | /* |
513 | * Init enet system AHB clock, set to 200MHz | 517 | * Init enet system AHB clock, set to 200MHz |
514 | * pll2_pfd2_396m-> ENET_PODF-> ENET_AHB | 518 | * pll2_pfd2_396m-> ENET_PODF-> ENET_AHB |
515 | */ | 519 | */ |
516 | clk_set_parent(clks[IMX6SX_CLK_ENET_PRE_SEL], clks[IMX6SX_CLK_PLL2_PFD2]); | 520 | clk_set_parent(hws[IMX6SX_CLK_ENET_PRE_SEL]->clk, hws[IMX6SX_CLK_PLL2_PFD2]->clk); |
517 | clk_set_parent(clks[IMX6SX_CLK_ENET_SEL], clks[IMX6SX_CLK_ENET_PODF]); | 521 | clk_set_parent(hws[IMX6SX_CLK_ENET_SEL]->clk, hws[IMX6SX_CLK_ENET_PODF]->clk); |
518 | clk_set_rate(clks[IMX6SX_CLK_ENET_PODF], 200000000); | 522 | clk_set_rate(hws[IMX6SX_CLK_ENET_PODF]->clk, 200000000); |
519 | clk_set_rate(clks[IMX6SX_CLK_ENET_REF], 125000000); | 523 | clk_set_rate(hws[IMX6SX_CLK_ENET_REF]->clk, 125000000); |
520 | clk_set_rate(clks[IMX6SX_CLK_ENET2_REF], 125000000); | 524 | clk_set_rate(hws[IMX6SX_CLK_ENET2_REF]->clk, 125000000); |
521 | 525 | ||
522 | /* Audio clocks */ | 526 | /* Audio clocks */ |
523 | clk_set_rate(clks[IMX6SX_CLK_PLL4_AUDIO_DIV], 393216000); | 527 | clk_set_rate(hws[IMX6SX_CLK_PLL4_AUDIO_DIV]->clk, 393216000); |
524 | 528 | ||
525 | clk_set_parent(clks[IMX6SX_CLK_SPDIF_SEL], clks[IMX6SX_CLK_PLL4_AUDIO_DIV]); | 529 | clk_set_parent(hws[IMX6SX_CLK_SPDIF_SEL]->clk, hws[IMX6SX_CLK_PLL4_AUDIO_DIV]->clk); |
526 | clk_set_rate(clks[IMX6SX_CLK_SPDIF_PODF], 98304000); | 530 | clk_set_rate(hws[IMX6SX_CLK_SPDIF_PODF]->clk, 98304000); |
527 | 531 | ||
528 | clk_set_parent(clks[IMX6SX_CLK_AUDIO_SEL], clks[IMX6SX_CLK_PLL3_USB_OTG]); | 532 | clk_set_parent(hws[IMX6SX_CLK_AUDIO_SEL]->clk, hws[IMX6SX_CLK_PLL3_USB_OTG]->clk); |
529 | clk_set_rate(clks[IMX6SX_CLK_AUDIO_PODF], 24000000); | 533 | clk_set_rate(hws[IMX6SX_CLK_AUDIO_PODF]->clk, 24000000); |
530 | 534 | ||
531 | clk_set_parent(clks[IMX6SX_CLK_SSI1_SEL], clks[IMX6SX_CLK_PLL4_AUDIO_DIV]); | 535 | clk_set_parent(hws[IMX6SX_CLK_SSI1_SEL]->clk, hws[IMX6SX_CLK_PLL4_AUDIO_DIV]->clk); |
532 | clk_set_parent(clks[IMX6SX_CLK_SSI2_SEL], clks[IMX6SX_CLK_PLL4_AUDIO_DIV]); | 536 | clk_set_parent(hws[IMX6SX_CLK_SSI2_SEL]->clk, hws[IMX6SX_CLK_PLL4_AUDIO_DIV]->clk); |
533 | clk_set_parent(clks[IMX6SX_CLK_SSI3_SEL], clks[IMX6SX_CLK_PLL4_AUDIO_DIV]); | 537 | clk_set_parent(hws[IMX6SX_CLK_SSI3_SEL]->clk, hws[IMX6SX_CLK_PLL4_AUDIO_DIV]->clk); |
534 | clk_set_rate(clks[IMX6SX_CLK_SSI1_PODF], 24576000); | 538 | clk_set_rate(hws[IMX6SX_CLK_SSI1_PODF]->clk, 24576000); |
535 | clk_set_rate(clks[IMX6SX_CLK_SSI2_PODF], 24576000); | 539 | clk_set_rate(hws[IMX6SX_CLK_SSI2_PODF]->clk, 24576000); |
536 | clk_set_rate(clks[IMX6SX_CLK_SSI3_PODF], 24576000); | 540 | clk_set_rate(hws[IMX6SX_CLK_SSI3_PODF]->clk, 24576000); |
537 | 541 | ||
538 | clk_set_parent(clks[IMX6SX_CLK_ESAI_SEL], clks[IMX6SX_CLK_PLL4_AUDIO_DIV]); | 542 | clk_set_parent(hws[IMX6SX_CLK_ESAI_SEL]->clk, hws[IMX6SX_CLK_PLL4_AUDIO_DIV]->clk); |
539 | clk_set_rate(clks[IMX6SX_CLK_ESAI_PODF], 24576000); | 543 | clk_set_rate(hws[IMX6SX_CLK_ESAI_PODF]->clk, 24576000); |
540 | 544 | ||
541 | /* Set parent clock for vadc */ | 545 | /* Set parent clock for vadc */ |
542 | clk_set_parent(clks[IMX6SX_CLK_VID_SEL], clks[IMX6SX_CLK_PLL3_USB_OTG]); | 546 | clk_set_parent(hws[IMX6SX_CLK_VID_SEL]->clk, hws[IMX6SX_CLK_PLL3_USB_OTG]->clk); |
543 | 547 | ||
544 | /* default parent of can_sel clock is invalid, manually set it here */ | 548 | /* default parent of can_sel clock is invalid, manually set it here */ |
545 | clk_set_parent(clks[IMX6SX_CLK_CAN_SEL], clks[IMX6SX_CLK_PLL3_60M]); | 549 | clk_set_parent(hws[IMX6SX_CLK_CAN_SEL]->clk, hws[IMX6SX_CLK_PLL3_60M]->clk); |
546 | 550 | ||
547 | /* Update gpu clock from default 528M to 720M */ | 551 | /* Update gpu clock from default 528M to 720M */ |
548 | clk_set_parent(clks[IMX6SX_CLK_GPU_CORE_SEL], clks[IMX6SX_CLK_PLL3_PFD0]); | 552 | clk_set_parent(hws[IMX6SX_CLK_GPU_CORE_SEL]->clk, hws[IMX6SX_CLK_PLL3_PFD0]->clk); |
549 | clk_set_parent(clks[IMX6SX_CLK_GPU_AXI_SEL], clks[IMX6SX_CLK_PLL3_PFD0]); | 553 | clk_set_parent(hws[IMX6SX_CLK_GPU_AXI_SEL]->clk, hws[IMX6SX_CLK_PLL3_PFD0]->clk); |
550 | 554 | ||
551 | clk_set_parent(clks[IMX6SX_CLK_QSPI1_SEL], clks[IMX6SX_CLK_PLL2_BUS]); | 555 | clk_set_parent(hws[IMX6SX_CLK_QSPI1_SEL]->clk, hws[IMX6SX_CLK_PLL2_BUS]->clk); |
552 | clk_set_parent(clks[IMX6SX_CLK_QSPI2_SEL], clks[IMX6SX_CLK_PLL2_BUS]); | 556 | clk_set_parent(hws[IMX6SX_CLK_QSPI2_SEL]->clk, hws[IMX6SX_CLK_PLL2_BUS]->clk); |
557 | |||
558 | for (i = 0; i < ARRAY_SIZE(uart_clk_ids); i++) { | ||
559 | int index = uart_clk_ids[i]; | ||
560 | |||
561 | uart_clks[i] = &hws[index]->clk; | ||
562 | } | ||
553 | 563 | ||
554 | imx_register_uart_clocks(uart_clks); | 564 | imx_register_uart_clocks(uart_clks); |
555 | } | 565 | } |
diff --git a/drivers/clk/imx/clk-imx6ul.c b/drivers/clk/imx/clk-imx6ul.c index 8fd52e103cc2..bc931988fe7b 100644 --- a/drivers/clk/imx/clk-imx6ul.c +++ b/drivers/clk/imx/clk-imx6ul.c | |||
@@ -6,6 +6,7 @@ | |||
6 | #include <dt-bindings/clock/imx6ul-clock.h> | 6 | #include <dt-bindings/clock/imx6ul-clock.h> |
7 | #include <linux/clk.h> | 7 | #include <linux/clk.h> |
8 | #include <linux/clkdev.h> | 8 | #include <linux/clkdev.h> |
9 | #include <linux/clk-provider.h> | ||
9 | #include <linux/err.h> | 10 | #include <linux/err.h> |
10 | #include <linux/init.h> | 11 | #include <linux/init.h> |
11 | #include <linux/io.h> | 12 | #include <linux/io.h> |
@@ -16,9 +17,6 @@ | |||
16 | 17 | ||
17 | #include "clk.h" | 18 | #include "clk.h" |
18 | 19 | ||
19 | #define BM_CCM_CCDR_MMDC_CH0_MASK (0x2 << 16) | ||
20 | #define CCDR 0x4 | ||
21 | |||
22 | static const char *pll_bypass_src_sels[] = { "osc", "dummy", }; | 20 | static const char *pll_bypass_src_sels[] = { "osc", "dummy", }; |
23 | static const char *pll1_bypass_sels[] = { "pll1", "pll1_bypass_src", }; | 21 | static const char *pll1_bypass_sels[] = { "pll1", "pll1_bypass_src", }; |
24 | static const char *pll2_bypass_sels[] = { "pll2", "pll2_bypass_src", }; | 22 | static const char *pll2_bypass_sels[] = { "pll2", "pll2_bypass_src", }; |
@@ -70,8 +68,8 @@ static const char *cko2_sels[] = { "dummy", "dummy", "dummy", "usdhc1", "dummy", | |||
70 | "dummy", "dummy", "dummy", "dummy", "uart_serial", "spdif", "dummy", "dummy", }; | 68 | "dummy", "dummy", "dummy", "dummy", "uart_serial", "spdif", "dummy", "dummy", }; |
71 | static const char *cko_sels[] = { "cko1", "cko2", }; | 69 | static const char *cko_sels[] = { "cko1", "cko2", }; |
72 | 70 | ||
73 | static struct clk *clks[IMX6UL_CLK_END]; | 71 | static struct clk_hw **hws; |
74 | static struct clk_onecell_data clk_data; | 72 | static struct clk_hw_onecell_data *clk_hw_data; |
75 | 73 | ||
76 | static const struct clk_div_table clk_enet_ref_table[] = { | 74 | static const struct clk_div_table clk_enet_ref_table[] = { |
77 | { .val = 0, .div = 20, }, | 75 | { .val = 0, .div = 20, }, |
@@ -118,61 +116,69 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node) | |||
118 | struct device_node *np; | 116 | struct device_node *np; |
119 | void __iomem *base; | 117 | void __iomem *base; |
120 | 118 | ||
121 | clks[IMX6UL_CLK_DUMMY] = imx_clk_fixed("dummy", 0); | 119 | clk_hw_data = kzalloc(struct_size(clk_hw_data, hws, |
120 | IMX6UL_CLK_END), GFP_KERNEL); | ||
121 | if (WARN_ON(!clk_hw_data)) | ||
122 | return; | ||
123 | |||
124 | clk_hw_data->num = IMX6UL_CLK_END; | ||
125 | hws = clk_hw_data->hws; | ||
126 | |||
127 | hws[IMX6UL_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0); | ||
122 | 128 | ||
123 | clks[IMX6UL_CLK_CKIL] = of_clk_get_by_name(ccm_node, "ckil"); | 129 | hws[IMX6UL_CLK_CKIL] = __clk_get_hw(of_clk_get_by_name(ccm_node, "ckil")); |
124 | clks[IMX6UL_CLK_OSC] = of_clk_get_by_name(ccm_node, "osc"); | 130 | hws[IMX6UL_CLK_OSC] = __clk_get_hw(of_clk_get_by_name(ccm_node, "osc")); |
125 | 131 | ||
126 | /* ipp_di clock is external input */ | 132 | /* ipp_di clock is external input */ |
127 | clks[IMX6UL_CLK_IPP_DI0] = of_clk_get_by_name(ccm_node, "ipp_di0"); | 133 | hws[IMX6UL_CLK_IPP_DI0] = __clk_get_hw(of_clk_get_by_name(ccm_node, "ipp_di0")); |
128 | clks[IMX6UL_CLK_IPP_DI1] = of_clk_get_by_name(ccm_node, "ipp_di1"); | 134 | hws[IMX6UL_CLK_IPP_DI1] = __clk_get_hw(of_clk_get_by_name(ccm_node, "ipp_di1")); |
129 | 135 | ||
130 | np = of_find_compatible_node(NULL, NULL, "fsl,imx6ul-anatop"); | 136 | np = of_find_compatible_node(NULL, NULL, "fsl,imx6ul-anatop"); |
131 | base = of_iomap(np, 0); | 137 | base = of_iomap(np, 0); |
132 | of_node_put(np); | 138 | of_node_put(np); |
133 | WARN_ON(!base); | 139 | WARN_ON(!base); |
134 | 140 | ||
135 | clks[IMX6UL_PLL1_BYPASS_SRC] = imx_clk_mux("pll1_bypass_src", base + 0x00, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); | 141 | hws[IMX6UL_PLL1_BYPASS_SRC] = imx_clk_hw_mux("pll1_bypass_src", base + 0x00, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); |
136 | clks[IMX6UL_PLL2_BYPASS_SRC] = imx_clk_mux("pll2_bypass_src", base + 0x30, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); | 142 | hws[IMX6UL_PLL2_BYPASS_SRC] = imx_clk_hw_mux("pll2_bypass_src", base + 0x30, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); |
137 | clks[IMX6UL_PLL3_BYPASS_SRC] = imx_clk_mux("pll3_bypass_src", base + 0x10, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); | 143 | hws[IMX6UL_PLL3_BYPASS_SRC] = imx_clk_hw_mux("pll3_bypass_src", base + 0x10, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); |
138 | clks[IMX6UL_PLL4_BYPASS_SRC] = imx_clk_mux("pll4_bypass_src", base + 0x70, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); | 144 | hws[IMX6UL_PLL4_BYPASS_SRC] = imx_clk_hw_mux("pll4_bypass_src", base + 0x70, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); |
139 | clks[IMX6UL_PLL5_BYPASS_SRC] = imx_clk_mux("pll5_bypass_src", base + 0xa0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); | 145 | hws[IMX6UL_PLL5_BYPASS_SRC] = imx_clk_hw_mux("pll5_bypass_src", base + 0xa0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); |
140 | clks[IMX6UL_PLL6_BYPASS_SRC] = imx_clk_mux("pll6_bypass_src", base + 0xe0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); | 146 | hws[IMX6UL_PLL6_BYPASS_SRC] = imx_clk_hw_mux("pll6_bypass_src", base + 0xe0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); |
141 | clks[IMX6UL_PLL7_BYPASS_SRC] = imx_clk_mux("pll7_bypass_src", base + 0x20, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); | 147 | hws[IMX6UL_PLL7_BYPASS_SRC] = imx_clk_hw_mux("pll7_bypass_src", base + 0x20, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); |
142 | 148 | ||
143 | clks[IMX6UL_CLK_PLL1] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1", "osc", base + 0x00, 0x7f); | 149 | hws[IMX6UL_CLK_PLL1] = imx_clk_hw_pllv3(IMX_PLLV3_SYS, "pll1", "osc", base + 0x00, 0x7f); |
144 | clks[IMX6UL_CLK_PLL2] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2", "osc", base + 0x30, 0x1); | 150 | hws[IMX6UL_CLK_PLL2] = imx_clk_hw_pllv3(IMX_PLLV3_GENERIC, "pll2", "osc", base + 0x30, 0x1); |
145 | clks[IMX6UL_CLK_PLL3] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3", "osc", base + 0x10, 0x3); | 151 | hws[IMX6UL_CLK_PLL3] = imx_clk_hw_pllv3(IMX_PLLV3_USB, "pll3", "osc", base + 0x10, 0x3); |
146 | clks[IMX6UL_CLK_PLL4] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4", "osc", base + 0x70, 0x7f); | 152 | hws[IMX6UL_CLK_PLL4] = imx_clk_hw_pllv3(IMX_PLLV3_AV, "pll4", "osc", base + 0x70, 0x7f); |
147 | clks[IMX6UL_CLK_PLL5] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5", "osc", base + 0xa0, 0x7f); | 153 | hws[IMX6UL_CLK_PLL5] = imx_clk_hw_pllv3(IMX_PLLV3_AV, "pll5", "osc", base + 0xa0, 0x7f); |
148 | clks[IMX6UL_CLK_PLL6] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6", "osc", base + 0xe0, 0x3); | 154 | hws[IMX6UL_CLK_PLL6] = imx_clk_hw_pllv3(IMX_PLLV3_ENET, "pll6", "osc", base + 0xe0, 0x3); |
149 | clks[IMX6UL_CLK_PLL7] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7", "osc", base + 0x20, 0x3); | 155 | hws[IMX6UL_CLK_PLL7] = imx_clk_hw_pllv3(IMX_PLLV3_USB, "pll7", "osc", base + 0x20, 0x3); |
150 | 156 | ||
151 | clks[IMX6UL_PLL1_BYPASS] = imx_clk_mux_flags("pll1_bypass", base + 0x00, 16, 1, pll1_bypass_sels, ARRAY_SIZE(pll1_bypass_sels), CLK_SET_RATE_PARENT); | 157 | hws[IMX6UL_PLL1_BYPASS] = imx_clk_hw_mux_flags("pll1_bypass", base + 0x00, 16, 1, pll1_bypass_sels, ARRAY_SIZE(pll1_bypass_sels), CLK_SET_RATE_PARENT); |
152 | clks[IMX6UL_PLL2_BYPASS] = imx_clk_mux_flags("pll2_bypass", base + 0x30, 16, 1, pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels), CLK_SET_RATE_PARENT); | 158 | hws[IMX6UL_PLL2_BYPASS] = imx_clk_hw_mux_flags("pll2_bypass", base + 0x30, 16, 1, pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels), CLK_SET_RATE_PARENT); |
153 | clks[IMX6UL_PLL3_BYPASS] = imx_clk_mux_flags("pll3_bypass", base + 0x10, 16, 1, pll3_bypass_sels, ARRAY_SIZE(pll3_bypass_sels), CLK_SET_RATE_PARENT); | 159 | hws[IMX6UL_PLL3_BYPASS] = imx_clk_hw_mux_flags("pll3_bypass", base + 0x10, 16, 1, pll3_bypass_sels, ARRAY_SIZE(pll3_bypass_sels), CLK_SET_RATE_PARENT); |
154 | clks[IMX6UL_PLL4_BYPASS] = imx_clk_mux_flags("pll4_bypass", base + 0x70, 16, 1, pll4_bypass_sels, ARRAY_SIZE(pll4_bypass_sels), CLK_SET_RATE_PARENT); | 160 | hws[IMX6UL_PLL4_BYPASS] = imx_clk_hw_mux_flags("pll4_bypass", base + 0x70, 16, 1, pll4_bypass_sels, ARRAY_SIZE(pll4_bypass_sels), CLK_SET_RATE_PARENT); |
155 | clks[IMX6UL_PLL5_BYPASS] = imx_clk_mux_flags("pll5_bypass", base + 0xa0, 16, 1, pll5_bypass_sels, ARRAY_SIZE(pll5_bypass_sels), CLK_SET_RATE_PARENT); | 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); |
156 | clks[IMX6UL_PLL6_BYPASS] = imx_clk_mux_flags("pll6_bypass", base + 0xe0, 16, 1, pll6_bypass_sels, ARRAY_SIZE(pll6_bypass_sels), CLK_SET_RATE_PARENT); | 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); |
157 | clks[IMX6UL_PLL7_BYPASS] = imx_clk_mux_flags("pll7_bypass", base + 0x20, 16, 1, pll7_bypass_sels, ARRAY_SIZE(pll7_bypass_sels), CLK_SET_RATE_PARENT); | 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); |
158 | clks[IMX6UL_CLK_CSI_SEL] = imx_clk_mux_flags("csi_sel", base + 0x3c, 9, 2, csi_sels, ARRAY_SIZE(csi_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); |
159 | 165 | ||
160 | /* Do not bypass PLLs initially */ | 166 | /* Do not bypass PLLs initially */ |
161 | clk_set_parent(clks[IMX6UL_PLL1_BYPASS], clks[IMX6UL_CLK_PLL1]); | 167 | clk_set_parent(hws[IMX6UL_PLL1_BYPASS]->clk, hws[IMX6UL_CLK_PLL1]->clk); |
162 | clk_set_parent(clks[IMX6UL_PLL2_BYPASS], clks[IMX6UL_CLK_PLL2]); | 168 | clk_set_parent(hws[IMX6UL_PLL2_BYPASS]->clk, hws[IMX6UL_CLK_PLL2]->clk); |
163 | clk_set_parent(clks[IMX6UL_PLL3_BYPASS], clks[IMX6UL_CLK_PLL3]); | 169 | clk_set_parent(hws[IMX6UL_PLL3_BYPASS]->clk, hws[IMX6UL_CLK_PLL3]->clk); |
164 | clk_set_parent(clks[IMX6UL_PLL4_BYPASS], clks[IMX6UL_CLK_PLL4]); | 170 | clk_set_parent(hws[IMX6UL_PLL4_BYPASS]->clk, hws[IMX6UL_CLK_PLL4]->clk); |
165 | clk_set_parent(clks[IMX6UL_PLL5_BYPASS], clks[IMX6UL_CLK_PLL5]); | 171 | clk_set_parent(hws[IMX6UL_PLL5_BYPASS]->clk, hws[IMX6UL_CLK_PLL5]->clk); |
166 | clk_set_parent(clks[IMX6UL_PLL6_BYPASS], clks[IMX6UL_CLK_PLL6]); | 172 | clk_set_parent(hws[IMX6UL_PLL6_BYPASS]->clk, hws[IMX6UL_CLK_PLL6]->clk); |
167 | clk_set_parent(clks[IMX6UL_PLL7_BYPASS], clks[IMX6UL_CLK_PLL7]); | 173 | clk_set_parent(hws[IMX6UL_PLL7_BYPASS]->clk, hws[IMX6UL_CLK_PLL7]->clk); |
168 | 174 | ||
169 | clks[IMX6UL_CLK_PLL1_SYS] = imx_clk_fixed_factor("pll1_sys", "pll1_bypass", 1, 1); | 175 | hws[IMX6UL_CLK_PLL1_SYS] = imx_clk_hw_fixed_factor("pll1_sys", "pll1_bypass", 1, 1); |
170 | clks[IMX6UL_CLK_PLL2_BUS] = imx_clk_gate("pll2_bus", "pll2_bypass", base + 0x30, 13); | 176 | hws[IMX6UL_CLK_PLL2_BUS] = imx_clk_hw_gate("pll2_bus", "pll2_bypass", base + 0x30, 13); |
171 | clks[IMX6UL_CLK_PLL3_USB_OTG] = imx_clk_gate("pll3_usb_otg", "pll3_bypass", base + 0x10, 13); | 177 | hws[IMX6UL_CLK_PLL3_USB_OTG] = imx_clk_hw_gate("pll3_usb_otg", "pll3_bypass", base + 0x10, 13); |
172 | clks[IMX6UL_CLK_PLL4_AUDIO] = imx_clk_gate("pll4_audio", "pll4_bypass", base + 0x70, 13); | 178 | hws[IMX6UL_CLK_PLL4_AUDIO] = imx_clk_hw_gate("pll4_audio", "pll4_bypass", base + 0x70, 13); |
173 | clks[IMX6UL_CLK_PLL5_VIDEO] = imx_clk_gate("pll5_video", "pll5_bypass", base + 0xa0, 13); | 179 | hws[IMX6UL_CLK_PLL5_VIDEO] = imx_clk_hw_gate("pll5_video", "pll5_bypass", base + 0xa0, 13); |
174 | clks[IMX6UL_CLK_PLL6_ENET] = imx_clk_gate("pll6_enet", "pll6_bypass", base + 0xe0, 13); | 180 | hws[IMX6UL_CLK_PLL6_ENET] = imx_clk_hw_gate("pll6_enet", "pll6_bypass", base + 0xe0, 13); |
175 | clks[IMX6UL_CLK_PLL7_USB_HOST] = imx_clk_gate("pll7_usb_host", "pll7_bypass", base + 0x20, 13); | 181 | hws[IMX6UL_CLK_PLL7_USB_HOST] = imx_clk_hw_gate("pll7_usb_host", "pll7_bypass", base + 0x20, 13); |
176 | 182 | ||
177 | /* | 183 | /* |
178 | * Bit 20 is the reserved and read-only bit, we do this only for: | 184 | * Bit 20 is the reserved and read-only bit, we do this only for: |
@@ -180,291 +186,289 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node) | |||
180 | * - Keep refcount when do usbphy clk_enable/disable, in that case, | 186 | * - Keep refcount when do usbphy clk_enable/disable, in that case, |
181 | * the clk framework many need to enable/disable usbphy's parent | 187 | * the clk framework many need to enable/disable usbphy's parent |
182 | */ | 188 | */ |
183 | clks[IMX6UL_CLK_USBPHY1] = imx_clk_gate("usbphy1", "pll3_usb_otg", base + 0x10, 20); | 189 | hws[IMX6UL_CLK_USBPHY1] = imx_clk_hw_gate("usbphy1", "pll3_usb_otg", base + 0x10, 20); |
184 | clks[IMX6UL_CLK_USBPHY2] = imx_clk_gate("usbphy2", "pll7_usb_host", base + 0x20, 20); | 190 | hws[IMX6UL_CLK_USBPHY2] = imx_clk_hw_gate("usbphy2", "pll7_usb_host", base + 0x20, 20); |
185 | 191 | ||
186 | /* | 192 | /* |
187 | * usbphy*_gate needs to be on after system boots up, and software | 193 | * usbphy*_gate needs to be on after system boots up, and software |
188 | * never needs to control it anymore. | 194 | * never needs to control it anymore. |
189 | */ | 195 | */ |
190 | clks[IMX6UL_CLK_USBPHY1_GATE] = imx_clk_gate("usbphy1_gate", "dummy", base + 0x10, 6); | 196 | hws[IMX6UL_CLK_USBPHY1_GATE] = imx_clk_hw_gate("usbphy1_gate", "dummy", base + 0x10, 6); |
191 | clks[IMX6UL_CLK_USBPHY2_GATE] = imx_clk_gate("usbphy2_gate", "dummy", base + 0x20, 6); | 197 | hws[IMX6UL_CLK_USBPHY2_GATE] = imx_clk_hw_gate("usbphy2_gate", "dummy", base + 0x20, 6); |
192 | 198 | ||
193 | /* name parent_name reg idx */ | 199 | /* name parent_name reg idx */ |
194 | clks[IMX6UL_CLK_PLL2_PFD0] = imx_clk_pfd("pll2_pfd0_352m", "pll2_bus", base + 0x100, 0); | 200 | hws[IMX6UL_CLK_PLL2_PFD0] = imx_clk_hw_pfd("pll2_pfd0_352m", "pll2_bus", base + 0x100, 0); |
195 | clks[IMX6UL_CLK_PLL2_PFD1] = imx_clk_pfd("pll2_pfd1_594m", "pll2_bus", base + 0x100, 1); | 201 | hws[IMX6UL_CLK_PLL2_PFD1] = imx_clk_hw_pfd("pll2_pfd1_594m", "pll2_bus", base + 0x100, 1); |
196 | clks[IMX6UL_CLK_PLL2_PFD2] = imx_clk_pfd("pll2_pfd2_396m", "pll2_bus", base + 0x100, 2); | 202 | hws[IMX6UL_CLK_PLL2_PFD2] = imx_clk_hw_pfd("pll2_pfd2_396m", "pll2_bus", base + 0x100, 2); |
197 | clks[IMX6UL_CLK_PLL2_PFD3] = imx_clk_pfd("pll2_pfd3_594m", "pll2_bus", base + 0x100, 3); | 203 | hws[IMX6UL_CLK_PLL2_PFD3] = imx_clk_hw_pfd("pll2_pfd3_594m", "pll2_bus", base + 0x100, 3); |
198 | clks[IMX6UL_CLK_PLL3_PFD0] = imx_clk_pfd("pll3_pfd0_720m", "pll3_usb_otg", base + 0xf0, 0); | 204 | hws[IMX6UL_CLK_PLL3_PFD0] = imx_clk_hw_pfd("pll3_pfd0_720m", "pll3_usb_otg", base + 0xf0, 0); |
199 | clks[IMX6UL_CLK_PLL3_PFD1] = imx_clk_pfd("pll3_pfd1_540m", "pll3_usb_otg", base + 0xf0, 1); | 205 | hws[IMX6UL_CLK_PLL3_PFD1] = imx_clk_hw_pfd("pll3_pfd1_540m", "pll3_usb_otg", base + 0xf0, 1); |
200 | clks[IMX6UL_CLK_PLL3_PFD2] = imx_clk_pfd("pll3_pfd2_508m", "pll3_usb_otg", base + 0xf0, 2); | 206 | hws[IMX6UL_CLK_PLL3_PFD2] = imx_clk_hw_pfd("pll3_pfd2_508m", "pll3_usb_otg", base + 0xf0, 2); |
201 | clks[IMX6UL_CLK_PLL3_PFD3] = imx_clk_pfd("pll3_pfd3_454m", "pll3_usb_otg", base + 0xf0, 3); | 207 | hws[IMX6UL_CLK_PLL3_PFD3] = imx_clk_hw_pfd("pll3_pfd3_454m", "pll3_usb_otg", base + 0xf0, 3); |
202 | 208 | ||
203 | clks[IMX6UL_CLK_ENET_REF] = clk_register_divider_table(NULL, "enet_ref", "pll6_enet", 0, | 209 | hws[IMX6UL_CLK_ENET_REF] = clk_hw_register_divider_table(NULL, "enet_ref", "pll6_enet", 0, |
204 | base + 0xe0, 0, 2, 0, clk_enet_ref_table, &imx_ccm_lock); | 210 | base + 0xe0, 0, 2, 0, clk_enet_ref_table, &imx_ccm_lock); |
205 | clks[IMX6UL_CLK_ENET2_REF] = clk_register_divider_table(NULL, "enet2_ref", "pll6_enet", 0, | 211 | hws[IMX6UL_CLK_ENET2_REF] = clk_hw_register_divider_table(NULL, "enet2_ref", "pll6_enet", 0, |
206 | base + 0xe0, 2, 2, 0, clk_enet_ref_table, &imx_ccm_lock); | 212 | base + 0xe0, 2, 2, 0, clk_enet_ref_table, &imx_ccm_lock); |
207 | 213 | ||
208 | clks[IMX6UL_CLK_ENET2_REF_125M] = imx_clk_gate("enet_ref_125m", "enet2_ref", base + 0xe0, 20); | 214 | hws[IMX6UL_CLK_ENET2_REF_125M] = imx_clk_hw_gate("enet_ref_125m", "enet2_ref", base + 0xe0, 20); |
209 | clks[IMX6UL_CLK_ENET_PTP_REF] = imx_clk_fixed_factor("enet_ptp_ref", "pll6_enet", 1, 20); | 215 | hws[IMX6UL_CLK_ENET_PTP_REF] = imx_clk_hw_fixed_factor("enet_ptp_ref", "pll6_enet", 1, 20); |
210 | clks[IMX6UL_CLK_ENET_PTP] = imx_clk_gate("enet_ptp", "enet_ptp_ref", base + 0xe0, 21); | 216 | hws[IMX6UL_CLK_ENET_PTP] = imx_clk_hw_gate("enet_ptp", "enet_ptp_ref", base + 0xe0, 21); |
211 | 217 | ||
212 | clks[IMX6UL_CLK_PLL4_POST_DIV] = clk_register_divider_table(NULL, "pll4_post_div", "pll4_audio", | 218 | hws[IMX6UL_CLK_PLL4_POST_DIV] = clk_hw_register_divider_table(NULL, "pll4_post_div", "pll4_audio", |
213 | CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0x70, 19, 2, 0, post_div_table, &imx_ccm_lock); | 219 | CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0x70, 19, 2, 0, post_div_table, &imx_ccm_lock); |
214 | clks[IMX6UL_CLK_PLL4_AUDIO_DIV] = clk_register_divider(NULL, "pll4_audio_div", "pll4_post_div", | 220 | hws[IMX6UL_CLK_PLL4_AUDIO_DIV] = clk_hw_register_divider(NULL, "pll4_audio_div", "pll4_post_div", |
215 | CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0x170, 15, 1, 0, &imx_ccm_lock); | 221 | CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0x170, 15, 1, 0, &imx_ccm_lock); |
216 | clks[IMX6UL_CLK_PLL5_POST_DIV] = clk_register_divider_table(NULL, "pll5_post_div", "pll5_video", | 222 | hws[IMX6UL_CLK_PLL5_POST_DIV] = clk_hw_register_divider_table(NULL, "pll5_post_div", "pll5_video", |
217 | CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0xa0, 19, 2, 0, post_div_table, &imx_ccm_lock); | 223 | CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0xa0, 19, 2, 0, post_div_table, &imx_ccm_lock); |
218 | clks[IMX6UL_CLK_PLL5_VIDEO_DIV] = clk_register_divider_table(NULL, "pll5_video_div", "pll5_post_div", | 224 | hws[IMX6UL_CLK_PLL5_VIDEO_DIV] = clk_hw_register_divider_table(NULL, "pll5_video_div", "pll5_post_div", |
219 | CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0x170, 30, 2, 0, video_div_table, &imx_ccm_lock); | 225 | CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0x170, 30, 2, 0, video_div_table, &imx_ccm_lock); |
220 | 226 | ||
221 | /* name parent_name mult div */ | 227 | /* name parent_name mult div */ |
222 | clks[IMX6UL_CLK_PLL2_198M] = imx_clk_fixed_factor("pll2_198m", "pll2_pfd2_396m", 1, 2); | 228 | hws[IMX6UL_CLK_PLL2_198M] = imx_clk_hw_fixed_factor("pll2_198m", "pll2_pfd2_396m", 1, 2); |
223 | clks[IMX6UL_CLK_PLL3_80M] = imx_clk_fixed_factor("pll3_80m", "pll3_usb_otg", 1, 6); | 229 | hws[IMX6UL_CLK_PLL3_80M] = imx_clk_hw_fixed_factor("pll3_80m", "pll3_usb_otg", 1, 6); |
224 | clks[IMX6UL_CLK_PLL3_60M] = imx_clk_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8); | 230 | hws[IMX6UL_CLK_PLL3_60M] = imx_clk_hw_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8); |
225 | clks[IMX6UL_CLK_GPT_3M] = imx_clk_fixed_factor("gpt_3m", "osc", 1, 8); | 231 | hws[IMX6UL_CLK_GPT_3M] = imx_clk_hw_fixed_factor("gpt_3m", "osc", 1, 8); |
226 | 232 | ||
227 | np = ccm_node; | 233 | np = ccm_node; |
228 | base = of_iomap(np, 0); | 234 | base = of_iomap(np, 0); |
229 | WARN_ON(!base); | 235 | WARN_ON(!base); |
230 | 236 | ||
231 | clks[IMX6UL_CA7_SECONDARY_SEL] = imx_clk_mux("ca7_secondary_sel", base + 0xc, 3, 1, ca7_secondary_sels, ARRAY_SIZE(ca7_secondary_sels)); | 237 | hws[IMX6UL_CA7_SECONDARY_SEL] = imx_clk_hw_mux("ca7_secondary_sel", base + 0xc, 3, 1, ca7_secondary_sels, ARRAY_SIZE(ca7_secondary_sels)); |
232 | clks[IMX6UL_CLK_STEP] = imx_clk_mux("step", base + 0x0c, 8, 1, step_sels, ARRAY_SIZE(step_sels)); | 238 | hws[IMX6UL_CLK_STEP] = imx_clk_hw_mux("step", base + 0x0c, 8, 1, step_sels, ARRAY_SIZE(step_sels)); |
233 | clks[IMX6UL_CLK_PLL1_SW] = imx_clk_mux_flags("pll1_sw", base + 0x0c, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels), 0); | 239 | hws[IMX6UL_CLK_PLL1_SW] = imx_clk_hw_mux_flags("pll1_sw", base + 0x0c, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels), 0); |
234 | clks[IMX6UL_CLK_AXI_ALT_SEL] = imx_clk_mux("axi_alt_sel", base + 0x14, 7, 1, axi_alt_sels, ARRAY_SIZE(axi_alt_sels)); | 240 | hws[IMX6UL_CLK_AXI_ALT_SEL] = imx_clk_hw_mux("axi_alt_sel", base + 0x14, 7, 1, axi_alt_sels, ARRAY_SIZE(axi_alt_sels)); |
235 | clks[IMX6UL_CLK_AXI_SEL] = imx_clk_mux_flags("axi_sel", base + 0x14, 6, 1, axi_sels, ARRAY_SIZE(axi_sels), 0); | 241 | hws[IMX6UL_CLK_AXI_SEL] = imx_clk_hw_mux_flags("axi_sel", base + 0x14, 6, 1, axi_sels, ARRAY_SIZE(axi_sels), 0); |
236 | clks[IMX6UL_CLK_PERIPH_PRE] = imx_clk_mux("periph_pre", base + 0x18, 18, 2, periph_pre_sels, ARRAY_SIZE(periph_pre_sels)); | 242 | hws[IMX6UL_CLK_PERIPH_PRE] = imx_clk_hw_mux("periph_pre", base + 0x18, 18, 2, periph_pre_sels, ARRAY_SIZE(periph_pre_sels)); |
237 | clks[IMX6UL_CLK_PERIPH2_PRE] = imx_clk_mux("periph2_pre", base + 0x18, 21, 2, periph2_pre_sels, ARRAY_SIZE(periph2_pre_sels)); | 243 | hws[IMX6UL_CLK_PERIPH2_PRE] = imx_clk_hw_mux("periph2_pre", base + 0x18, 21, 2, periph2_pre_sels, ARRAY_SIZE(periph2_pre_sels)); |
238 | clks[IMX6UL_CLK_PERIPH_CLK2_SEL] = imx_clk_mux("periph_clk2_sel", base + 0x18, 12, 2, periph_clk2_sels, ARRAY_SIZE(periph_clk2_sels)); | 244 | hws[IMX6UL_CLK_PERIPH_CLK2_SEL] = imx_clk_hw_mux("periph_clk2_sel", base + 0x18, 12, 2, periph_clk2_sels, ARRAY_SIZE(periph_clk2_sels)); |
239 | clks[IMX6UL_CLK_PERIPH2_CLK2_SEL] = imx_clk_mux("periph2_clk2_sel", base + 0x18, 20, 1, periph2_clk2_sels, ARRAY_SIZE(periph2_clk2_sels)); | 245 | hws[IMX6UL_CLK_PERIPH2_CLK2_SEL] = imx_clk_hw_mux("periph2_clk2_sel", base + 0x18, 20, 1, periph2_clk2_sels, ARRAY_SIZE(periph2_clk2_sels)); |
240 | clks[IMX6UL_CLK_EIM_SLOW_SEL] = imx_clk_mux("eim_slow_sel", base + 0x1c, 29, 2, eim_slow_sels, ARRAY_SIZE(eim_slow_sels)); | 246 | hws[IMX6UL_CLK_EIM_SLOW_SEL] = imx_clk_hw_mux("eim_slow_sel", base + 0x1c, 29, 2, eim_slow_sels, ARRAY_SIZE(eim_slow_sels)); |
241 | clks[IMX6UL_CLK_GPMI_SEL] = imx_clk_mux("gpmi_sel", base + 0x1c, 19, 1, gpmi_sels, ARRAY_SIZE(gpmi_sels)); | 247 | hws[IMX6UL_CLK_GPMI_SEL] = imx_clk_hw_mux("gpmi_sel", base + 0x1c, 19, 1, gpmi_sels, ARRAY_SIZE(gpmi_sels)); |
242 | clks[IMX6UL_CLK_BCH_SEL] = imx_clk_mux("bch_sel", base + 0x1c, 18, 1, bch_sels, ARRAY_SIZE(bch_sels)); | 248 | hws[IMX6UL_CLK_BCH_SEL] = imx_clk_hw_mux("bch_sel", base + 0x1c, 18, 1, bch_sels, ARRAY_SIZE(bch_sels)); |
243 | clks[IMX6UL_CLK_USDHC2_SEL] = imx_clk_mux("usdhc2_sel", base + 0x1c, 17, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels)); | 249 | hws[IMX6UL_CLK_USDHC2_SEL] = imx_clk_hw_mux("usdhc2_sel", base + 0x1c, 17, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels)); |
244 | clks[IMX6UL_CLK_USDHC1_SEL] = imx_clk_mux("usdhc1_sel", base + 0x1c, 16, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels)); | 250 | hws[IMX6UL_CLK_USDHC1_SEL] = imx_clk_hw_mux("usdhc1_sel", base + 0x1c, 16, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels)); |
245 | clks[IMX6UL_CLK_SAI3_SEL] = imx_clk_mux("sai3_sel", base + 0x1c, 14, 2, sai_sels, ARRAY_SIZE(sai_sels)); | 251 | hws[IMX6UL_CLK_SAI3_SEL] = imx_clk_hw_mux("sai3_sel", base + 0x1c, 14, 2, sai_sels, ARRAY_SIZE(sai_sels)); |
246 | clks[IMX6UL_CLK_SAI2_SEL] = imx_clk_mux("sai2_sel", base + 0x1c, 12, 2, sai_sels, ARRAY_SIZE(sai_sels)); | 252 | hws[IMX6UL_CLK_SAI2_SEL] = imx_clk_hw_mux("sai2_sel", base + 0x1c, 12, 2, sai_sels, ARRAY_SIZE(sai_sels)); |
247 | clks[IMX6UL_CLK_SAI1_SEL] = imx_clk_mux("sai1_sel", base + 0x1c, 10, 2, sai_sels, ARRAY_SIZE(sai_sels)); | 253 | hws[IMX6UL_CLK_SAI1_SEL] = imx_clk_hw_mux("sai1_sel", base + 0x1c, 10, 2, sai_sels, ARRAY_SIZE(sai_sels)); |
248 | clks[IMX6UL_CLK_QSPI1_SEL] = imx_clk_mux("qspi1_sel", base + 0x1c, 7, 3, qspi1_sels, ARRAY_SIZE(qspi1_sels)); | 254 | hws[IMX6UL_CLK_QSPI1_SEL] = imx_clk_hw_mux("qspi1_sel", base + 0x1c, 7, 3, qspi1_sels, ARRAY_SIZE(qspi1_sels)); |
249 | clks[IMX6UL_CLK_PERCLK_SEL] = imx_clk_mux("perclk_sel", base + 0x1c, 6, 1, perclk_sels, ARRAY_SIZE(perclk_sels)); | 255 | hws[IMX6UL_CLK_PERCLK_SEL] = imx_clk_hw_mux("perclk_sel", base + 0x1c, 6, 1, perclk_sels, ARRAY_SIZE(perclk_sels)); |
250 | clks[IMX6UL_CLK_CAN_SEL] = imx_clk_mux("can_sel", base + 0x20, 8, 2, can_sels, ARRAY_SIZE(can_sels)); | 256 | hws[IMX6UL_CLK_CAN_SEL] = imx_clk_hw_mux("can_sel", base + 0x20, 8, 2, can_sels, ARRAY_SIZE(can_sels)); |
251 | if (clk_on_imx6ull()) | 257 | if (clk_on_imx6ull()) |
252 | clks[IMX6ULL_CLK_ESAI_SEL] = imx_clk_mux("esai_sel", base + 0x20, 19, 2, esai_sels, ARRAY_SIZE(esai_sels)); | 258 | hws[IMX6ULL_CLK_ESAI_SEL] = imx_clk_hw_mux("esai_sel", base + 0x20, 19, 2, esai_sels, ARRAY_SIZE(esai_sels)); |
253 | clks[IMX6UL_CLK_UART_SEL] = imx_clk_mux("uart_sel", base + 0x24, 6, 1, uart_sels, ARRAY_SIZE(uart_sels)); | 259 | hws[IMX6UL_CLK_UART_SEL] = imx_clk_hw_mux("uart_sel", base + 0x24, 6, 1, uart_sels, ARRAY_SIZE(uart_sels)); |
254 | clks[IMX6UL_CLK_ENFC_SEL] = imx_clk_mux("enfc_sel", base + 0x2c, 15, 3, enfc_sels, ARRAY_SIZE(enfc_sels)); | 260 | hws[IMX6UL_CLK_ENFC_SEL] = imx_clk_hw_mux("enfc_sel", base + 0x2c, 15, 3, enfc_sels, ARRAY_SIZE(enfc_sels)); |
255 | clks[IMX6UL_CLK_LDB_DI0_SEL] = imx_clk_mux("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di0_sels, ARRAY_SIZE(ldb_di0_sels)); | 261 | hws[IMX6UL_CLK_LDB_DI0_SEL] = imx_clk_hw_mux("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di0_sels, ARRAY_SIZE(ldb_di0_sels)); |
256 | clks[IMX6UL_CLK_SPDIF_SEL] = imx_clk_mux("spdif_sel", base + 0x30, 20, 2, spdif_sels, ARRAY_SIZE(spdif_sels)); | 262 | hws[IMX6UL_CLK_SPDIF_SEL] = imx_clk_hw_mux("spdif_sel", base + 0x30, 20, 2, spdif_sels, ARRAY_SIZE(spdif_sels)); |
257 | if (clk_on_imx6ul()) { | 263 | if (clk_on_imx6ul()) { |
258 | clks[IMX6UL_CLK_SIM_PRE_SEL] = imx_clk_mux("sim_pre_sel", base + 0x34, 15, 3, sim_pre_sels, ARRAY_SIZE(sim_pre_sels)); | 264 | hws[IMX6UL_CLK_SIM_PRE_SEL] = imx_clk_hw_mux("sim_pre_sel", base + 0x34, 15, 3, sim_pre_sels, ARRAY_SIZE(sim_pre_sels)); |
259 | clks[IMX6UL_CLK_SIM_SEL] = imx_clk_mux("sim_sel", base + 0x34, 9, 3, sim_sels, ARRAY_SIZE(sim_sels)); | 265 | hws[IMX6UL_CLK_SIM_SEL] = imx_clk_hw_mux("sim_sel", base + 0x34, 9, 3, sim_sels, ARRAY_SIZE(sim_sels)); |
260 | } else if (clk_on_imx6ull()) { | 266 | } else if (clk_on_imx6ull()) { |
261 | clks[IMX6ULL_CLK_EPDC_PRE_SEL] = imx_clk_mux("epdc_pre_sel", base + 0x34, 15, 3, epdc_pre_sels, ARRAY_SIZE(epdc_pre_sels)); | 267 | hws[IMX6ULL_CLK_EPDC_PRE_SEL] = imx_clk_hw_mux("epdc_pre_sel", base + 0x34, 15, 3, epdc_pre_sels, ARRAY_SIZE(epdc_pre_sels)); |
262 | clks[IMX6ULL_CLK_EPDC_SEL] = imx_clk_mux("epdc_sel", base + 0x34, 9, 3, epdc_sels, ARRAY_SIZE(epdc_sels)); | 268 | hws[IMX6ULL_CLK_EPDC_SEL] = imx_clk_hw_mux("epdc_sel", base + 0x34, 9, 3, epdc_sels, ARRAY_SIZE(epdc_sels)); |
263 | } | 269 | } |
264 | clks[IMX6UL_CLK_ECSPI_SEL] = imx_clk_mux("ecspi_sel", base + 0x38, 18, 1, ecspi_sels, ARRAY_SIZE(ecspi_sels)); | 270 | hws[IMX6UL_CLK_ECSPI_SEL] = imx_clk_hw_mux("ecspi_sel", base + 0x38, 18, 1, ecspi_sels, ARRAY_SIZE(ecspi_sels)); |
265 | clks[IMX6UL_CLK_LCDIF_PRE_SEL] = imx_clk_mux_flags("lcdif_pre_sel", base + 0x38, 15, 3, lcdif_pre_sels, ARRAY_SIZE(lcdif_pre_sels), CLK_SET_RATE_PARENT); | 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); |
266 | clks[IMX6UL_CLK_LCDIF_SEL] = imx_clk_mux("lcdif_sel", base + 0x38, 9, 3, lcdif_sels, ARRAY_SIZE(lcdif_sels)); | 272 | hws[IMX6UL_CLK_LCDIF_SEL] = imx_clk_hw_mux("lcdif_sel", base + 0x38, 9, 3, lcdif_sels, ARRAY_SIZE(lcdif_sels)); |
267 | 273 | ||
268 | clks[IMX6UL_CLK_LDB_DI0_DIV_SEL] = imx_clk_mux("ldb_di0", base + 0x20, 10, 1, ldb_di0_div_sels, ARRAY_SIZE(ldb_di0_div_sels)); | 274 | 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)); |
269 | clks[IMX6UL_CLK_LDB_DI1_DIV_SEL] = imx_clk_mux("ldb_di1", base + 0x20, 11, 1, ldb_di1_div_sels, ARRAY_SIZE(ldb_di1_div_sels)); | 275 | 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)); |
270 | 276 | ||
271 | clks[IMX6UL_CLK_CKO1_SEL] = imx_clk_mux("cko1_sel", base + 0x60, 0, 4, cko1_sels, ARRAY_SIZE(cko1_sels)); | 277 | hws[IMX6UL_CLK_CKO1_SEL] = imx_clk_hw_mux("cko1_sel", base + 0x60, 0, 4, cko1_sels, ARRAY_SIZE(cko1_sels)); |
272 | clks[IMX6UL_CLK_CKO2_SEL] = imx_clk_mux("cko2_sel", base + 0x60, 16, 5, cko2_sels, ARRAY_SIZE(cko2_sels)); | 278 | hws[IMX6UL_CLK_CKO2_SEL] = imx_clk_hw_mux("cko2_sel", base + 0x60, 16, 5, cko2_sels, ARRAY_SIZE(cko2_sels)); |
273 | clks[IMX6UL_CLK_CKO] = imx_clk_mux("cko", base + 0x60, 8, 1, cko_sels, ARRAY_SIZE(cko_sels)); | 279 | hws[IMX6UL_CLK_CKO] = imx_clk_hw_mux("cko", base + 0x60, 8, 1, cko_sels, ARRAY_SIZE(cko_sels)); |
274 | 280 | ||
275 | clks[IMX6UL_CLK_LDB_DI0_DIV_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7); | 281 | hws[IMX6UL_CLK_LDB_DI0_DIV_3_5] = imx_clk_hw_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7); |
276 | clks[IMX6UL_CLK_LDB_DI0_DIV_7] = imx_clk_fixed_factor("ldb_di0_div_7", "ldb_di0_sel", 1, 7); | 282 | hws[IMX6UL_CLK_LDB_DI0_DIV_7] = imx_clk_hw_fixed_factor("ldb_di0_div_7", "ldb_di0_sel", 1, 7); |
277 | clks[IMX6UL_CLK_LDB_DI1_DIV_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "qspi1_sel", 2, 7); | 283 | hws[IMX6UL_CLK_LDB_DI1_DIV_3_5] = imx_clk_hw_fixed_factor("ldb_di1_div_3_5", "qspi1_sel", 2, 7); |
278 | clks[IMX6UL_CLK_LDB_DI1_DIV_7] = imx_clk_fixed_factor("ldb_di1_div_7", "qspi1_sel", 1, 7); | 284 | hws[IMX6UL_CLK_LDB_DI1_DIV_7] = imx_clk_hw_fixed_factor("ldb_di1_div_7", "qspi1_sel", 1, 7); |
279 | 285 | ||
280 | clks[IMX6UL_CLK_PERIPH] = imx_clk_busy_mux("periph", base + 0x14, 25, 1, base + 0x48, 5, periph_sels, ARRAY_SIZE(periph_sels)); | 286 | hws[IMX6UL_CLK_PERIPH] = imx_clk_hw_busy_mux("periph", base + 0x14, 25, 1, base + 0x48, 5, periph_sels, ARRAY_SIZE(periph_sels)); |
281 | clks[IMX6UL_CLK_PERIPH2] = imx_clk_busy_mux("periph2", base + 0x14, 26, 1, base + 0x48, 3, periph2_sels, ARRAY_SIZE(periph2_sels)); | 287 | hws[IMX6UL_CLK_PERIPH2] = imx_clk_hw_busy_mux("periph2", base + 0x14, 26, 1, base + 0x48, 3, periph2_sels, ARRAY_SIZE(periph2_sels)); |
282 | 288 | ||
283 | clks[IMX6UL_CLK_PERIPH_CLK2] = imx_clk_divider("periph_clk2", "periph_clk2_sel", base + 0x14, 27, 3); | 289 | hws[IMX6UL_CLK_PERIPH_CLK2] = imx_clk_hw_divider("periph_clk2", "periph_clk2_sel", base + 0x14, 27, 3); |
284 | clks[IMX6UL_CLK_PERIPH2_CLK2] = imx_clk_divider("periph2_clk2", "periph2_clk2_sel", base + 0x14, 0, 3); | 290 | hws[IMX6UL_CLK_PERIPH2_CLK2] = imx_clk_hw_divider("periph2_clk2", "periph2_clk2_sel", base + 0x14, 0, 3); |
285 | clks[IMX6UL_CLK_IPG] = imx_clk_divider("ipg", "ahb", base + 0x14, 8, 2); | 291 | hws[IMX6UL_CLK_IPG] = imx_clk_hw_divider("ipg", "ahb", base + 0x14, 8, 2); |
286 | clks[IMX6UL_CLK_LCDIF_PODF] = imx_clk_divider("lcdif_podf", "lcdif_pred", base + 0x18, 23, 3); | 292 | hws[IMX6UL_CLK_LCDIF_PODF] = imx_clk_hw_divider("lcdif_podf", "lcdif_pred", base + 0x18, 23, 3); |
287 | clks[IMX6UL_CLK_QSPI1_PDOF] = imx_clk_divider("qspi1_podf", "qspi1_sel", base + 0x1c, 26, 3); | 293 | hws[IMX6UL_CLK_QSPI1_PDOF] = imx_clk_hw_divider("qspi1_podf", "qspi1_sel", base + 0x1c, 26, 3); |
288 | clks[IMX6UL_CLK_EIM_SLOW_PODF] = imx_clk_divider("eim_slow_podf", "eim_slow_sel", base + 0x1c, 23, 3); | 294 | hws[IMX6UL_CLK_EIM_SLOW_PODF] = imx_clk_hw_divider("eim_slow_podf", "eim_slow_sel", base + 0x1c, 23, 3); |
289 | clks[IMX6UL_CLK_PERCLK] = imx_clk_divider("perclk", "perclk_sel", base + 0x1c, 0, 6); | 295 | hws[IMX6UL_CLK_PERCLK] = imx_clk_hw_divider("perclk", "perclk_sel", base + 0x1c, 0, 6); |
290 | clks[IMX6UL_CLK_CAN_PODF] = imx_clk_divider("can_podf", "can_sel", base + 0x20, 2, 6); | 296 | hws[IMX6UL_CLK_CAN_PODF] = imx_clk_hw_divider("can_podf", "can_sel", base + 0x20, 2, 6); |
291 | clks[IMX6UL_CLK_GPMI_PODF] = imx_clk_divider("gpmi_podf", "gpmi_sel", base + 0x24, 22, 3); | 297 | hws[IMX6UL_CLK_GPMI_PODF] = imx_clk_hw_divider("gpmi_podf", "gpmi_sel", base + 0x24, 22, 3); |
292 | clks[IMX6UL_CLK_BCH_PODF] = imx_clk_divider("bch_podf", "bch_sel", base + 0x24, 19, 3); | 298 | hws[IMX6UL_CLK_BCH_PODF] = imx_clk_hw_divider("bch_podf", "bch_sel", base + 0x24, 19, 3); |
293 | clks[IMX6UL_CLK_USDHC2_PODF] = imx_clk_divider("usdhc2_podf", "usdhc2_sel", base + 0x24, 16, 3); | 299 | hws[IMX6UL_CLK_USDHC2_PODF] = imx_clk_hw_divider("usdhc2_podf", "usdhc2_sel", base + 0x24, 16, 3); |
294 | clks[IMX6UL_CLK_USDHC1_PODF] = imx_clk_divider("usdhc1_podf", "usdhc1_sel", base + 0x24, 11, 3); | 300 | hws[IMX6UL_CLK_USDHC1_PODF] = imx_clk_hw_divider("usdhc1_podf", "usdhc1_sel", base + 0x24, 11, 3); |
295 | clks[IMX6UL_CLK_UART_PODF] = imx_clk_divider("uart_podf", "uart_sel", base + 0x24, 0, 6); | 301 | hws[IMX6UL_CLK_UART_PODF] = imx_clk_hw_divider("uart_podf", "uart_sel", base + 0x24, 0, 6); |
296 | clks[IMX6UL_CLK_SAI3_PRED] = imx_clk_divider("sai3_pred", "sai3_sel", base + 0x28, 22, 3); | 302 | hws[IMX6UL_CLK_SAI3_PRED] = imx_clk_hw_divider("sai3_pred", "sai3_sel", base + 0x28, 22, 3); |
297 | clks[IMX6UL_CLK_SAI3_PODF] = imx_clk_divider("sai3_podf", "sai3_pred", base + 0x28, 16, 6); | 303 | hws[IMX6UL_CLK_SAI3_PODF] = imx_clk_hw_divider("sai3_podf", "sai3_pred", base + 0x28, 16, 6); |
298 | clks[IMX6UL_CLK_SAI1_PRED] = imx_clk_divider("sai1_pred", "sai1_sel", base + 0x28, 6, 3); | 304 | hws[IMX6UL_CLK_SAI1_PRED] = imx_clk_hw_divider("sai1_pred", "sai1_sel", base + 0x28, 6, 3); |
299 | clks[IMX6UL_CLK_SAI1_PODF] = imx_clk_divider("sai1_podf", "sai1_pred", base + 0x28, 0, 6); | 305 | hws[IMX6UL_CLK_SAI1_PODF] = imx_clk_hw_divider("sai1_podf", "sai1_pred", base + 0x28, 0, 6); |
300 | if (clk_on_imx6ull()) { | 306 | if (clk_on_imx6ull()) { |
301 | clks[IMX6ULL_CLK_ESAI_PRED] = imx_clk_divider("esai_pred", "esai_sel", base + 0x28, 9, 3); | 307 | hws[IMX6ULL_CLK_ESAI_PRED] = imx_clk_hw_divider("esai_pred", "esai_sel", base + 0x28, 9, 3); |
302 | clks[IMX6ULL_CLK_ESAI_PODF] = imx_clk_divider("esai_podf", "esai_pred", base + 0x28, 25, 3); | 308 | hws[IMX6ULL_CLK_ESAI_PODF] = imx_clk_hw_divider("esai_podf", "esai_pred", base + 0x28, 25, 3); |
303 | } | 309 | } |
304 | clks[IMX6UL_CLK_ENFC_PRED] = imx_clk_divider("enfc_pred", "enfc_sel", base + 0x2c, 18, 3); | 310 | hws[IMX6UL_CLK_ENFC_PRED] = imx_clk_hw_divider("enfc_pred", "enfc_sel", base + 0x2c, 18, 3); |
305 | clks[IMX6UL_CLK_ENFC_PODF] = imx_clk_divider("enfc_podf", "enfc_pred", base + 0x2c, 21, 6); | 311 | hws[IMX6UL_CLK_ENFC_PODF] = imx_clk_hw_divider("enfc_podf", "enfc_pred", base + 0x2c, 21, 6); |
306 | clks[IMX6UL_CLK_SAI2_PRED] = imx_clk_divider("sai2_pred", "sai2_sel", base + 0x2c, 6, 3); | 312 | hws[IMX6UL_CLK_SAI2_PRED] = imx_clk_hw_divider("sai2_pred", "sai2_sel", base + 0x2c, 6, 3); |
307 | clks[IMX6UL_CLK_SAI2_PODF] = imx_clk_divider("sai2_podf", "sai2_pred", base + 0x2c, 0, 6); | 313 | hws[IMX6UL_CLK_SAI2_PODF] = imx_clk_hw_divider("sai2_podf", "sai2_pred", base + 0x2c, 0, 6); |
308 | clks[IMX6UL_CLK_SPDIF_PRED] = imx_clk_divider("spdif_pred", "spdif_sel", base + 0x30, 25, 3); | 314 | hws[IMX6UL_CLK_SPDIF_PRED] = imx_clk_hw_divider("spdif_pred", "spdif_sel", base + 0x30, 25, 3); |
309 | clks[IMX6UL_CLK_SPDIF_PODF] = imx_clk_divider("spdif_podf", "spdif_pred", base + 0x30, 22, 3); | 315 | hws[IMX6UL_CLK_SPDIF_PODF] = imx_clk_hw_divider("spdif_podf", "spdif_pred", base + 0x30, 22, 3); |
310 | if (clk_on_imx6ul()) | 316 | if (clk_on_imx6ul()) |
311 | clks[IMX6UL_CLK_SIM_PODF] = imx_clk_divider("sim_podf", "sim_pre_sel", base + 0x34, 12, 3); | 317 | hws[IMX6UL_CLK_SIM_PODF] = imx_clk_hw_divider("sim_podf", "sim_pre_sel", base + 0x34, 12, 3); |
312 | else if (clk_on_imx6ull()) | 318 | else if (clk_on_imx6ull()) |
313 | clks[IMX6ULL_CLK_EPDC_PODF] = imx_clk_divider("epdc_podf", "epdc_pre_sel", base + 0x34, 12, 3); | 319 | hws[IMX6ULL_CLK_EPDC_PODF] = imx_clk_hw_divider("epdc_podf", "epdc_pre_sel", base + 0x34, 12, 3); |
314 | clks[IMX6UL_CLK_ECSPI_PODF] = imx_clk_divider("ecspi_podf", "ecspi_sel", base + 0x38, 19, 6); | 320 | hws[IMX6UL_CLK_ECSPI_PODF] = imx_clk_hw_divider("ecspi_podf", "ecspi_sel", base + 0x38, 19, 6); |
315 | clks[IMX6UL_CLK_LCDIF_PRED] = imx_clk_divider("lcdif_pred", "lcdif_pre_sel", base + 0x38, 12, 3); | 321 | hws[IMX6UL_CLK_LCDIF_PRED] = imx_clk_hw_divider("lcdif_pred", "lcdif_pre_sel", base + 0x38, 12, 3); |
316 | clks[IMX6UL_CLK_CSI_PODF] = imx_clk_divider("csi_podf", "csi_sel", base + 0x3c, 11, 3); | 322 | hws[IMX6UL_CLK_CSI_PODF] = imx_clk_hw_divider("csi_podf", "csi_sel", base + 0x3c, 11, 3); |
317 | 323 | ||
318 | clks[IMX6UL_CLK_CKO1_PODF] = imx_clk_divider("cko1_podf", "cko1_sel", base + 0x60, 4, 3); | 324 | hws[IMX6UL_CLK_CKO1_PODF] = imx_clk_hw_divider("cko1_podf", "cko1_sel", base + 0x60, 4, 3); |
319 | clks[IMX6UL_CLK_CKO2_PODF] = imx_clk_divider("cko2_podf", "cko2_sel", base + 0x60, 21, 3); | 325 | hws[IMX6UL_CLK_CKO2_PODF] = imx_clk_hw_divider("cko2_podf", "cko2_sel", base + 0x60, 21, 3); |
320 | 326 | ||
321 | clks[IMX6UL_CLK_ARM] = imx_clk_busy_divider("arm", "pll1_sw", base + 0x10, 0, 3, base + 0x48, 16); | 327 | hws[IMX6UL_CLK_ARM] = imx_clk_hw_busy_divider("arm", "pll1_sw", base + 0x10, 0, 3, base + 0x48, 16); |
322 | clks[IMX6UL_CLK_MMDC_PODF] = imx_clk_busy_divider("mmdc_podf", "periph2", base + 0x14, 3, 3, base + 0x48, 2); | 328 | hws[IMX6UL_CLK_MMDC_PODF] = imx_clk_hw_busy_divider("mmdc_podf", "periph2", base + 0x14, 3, 3, base + 0x48, 2); |
323 | clks[IMX6UL_CLK_AXI_PODF] = imx_clk_busy_divider("axi_podf", "axi_sel", base + 0x14, 16, 3, base + 0x48, 0); | 329 | hws[IMX6UL_CLK_AXI_PODF] = imx_clk_hw_busy_divider("axi_podf", "axi_sel", base + 0x14, 16, 3, base + 0x48, 0); |
324 | clks[IMX6UL_CLK_AHB] = imx_clk_busy_divider("ahb", "periph", base + 0x14, 10, 3, base + 0x48, 1); | 330 | hws[IMX6UL_CLK_AHB] = imx_clk_hw_busy_divider("ahb", "periph", base + 0x14, 10, 3, base + 0x48, 1); |
325 | 331 | ||
326 | /* CCGR0 */ | 332 | /* CCGR0 */ |
327 | clks[IMX6UL_CLK_AIPSTZ1] = imx_clk_gate2_flags("aips_tz1", "ahb", base + 0x68, 0, CLK_IS_CRITICAL); | 333 | hws[IMX6UL_CLK_AIPSTZ1] = imx_clk_hw_gate2_flags("aips_tz1", "ahb", base + 0x68, 0, CLK_IS_CRITICAL); |
328 | clks[IMX6UL_CLK_AIPSTZ2] = imx_clk_gate2_flags("aips_tz2", "ahb", base + 0x68, 2, CLK_IS_CRITICAL); | 334 | hws[IMX6UL_CLK_AIPSTZ2] = imx_clk_hw_gate2_flags("aips_tz2", "ahb", base + 0x68, 2, CLK_IS_CRITICAL); |
329 | clks[IMX6UL_CLK_APBHDMA] = imx_clk_gate2("apbh_dma", "bch_podf", base + 0x68, 4); | 335 | hws[IMX6UL_CLK_APBHDMA] = imx_clk_hw_gate2("apbh_dma", "bch_podf", base + 0x68, 4); |
330 | clks[IMX6UL_CLK_ASRC_IPG] = imx_clk_gate2_shared("asrc_ipg", "ahb", base + 0x68, 6, &share_count_asrc); | 336 | hws[IMX6UL_CLK_ASRC_IPG] = imx_clk_hw_gate2_shared("asrc_ipg", "ahb", base + 0x68, 6, &share_count_asrc); |
331 | clks[IMX6UL_CLK_ASRC_MEM] = imx_clk_gate2_shared("asrc_mem", "ahb", base + 0x68, 6, &share_count_asrc); | 337 | hws[IMX6UL_CLK_ASRC_MEM] = imx_clk_hw_gate2_shared("asrc_mem", "ahb", base + 0x68, 6, &share_count_asrc); |
332 | if (clk_on_imx6ul()) { | 338 | if (clk_on_imx6ul()) { |
333 | clks[IMX6UL_CLK_CAAM_MEM] = imx_clk_gate2("caam_mem", "ahb", base + 0x68, 8); | 339 | hws[IMX6UL_CLK_CAAM_MEM] = imx_clk_hw_gate2("caam_mem", "ahb", base + 0x68, 8); |
334 | clks[IMX6UL_CLK_CAAM_ACLK] = imx_clk_gate2("caam_aclk", "ahb", base + 0x68, 10); | 340 | hws[IMX6UL_CLK_CAAM_ACLK] = imx_clk_hw_gate2("caam_aclk", "ahb", base + 0x68, 10); |
335 | clks[IMX6UL_CLK_CAAM_IPG] = imx_clk_gate2("caam_ipg", "ipg", base + 0x68, 12); | 341 | hws[IMX6UL_CLK_CAAM_IPG] = imx_clk_hw_gate2("caam_ipg", "ipg", base + 0x68, 12); |
336 | } else if (clk_on_imx6ull()) { | 342 | } else if (clk_on_imx6ull()) { |
337 | clks[IMX6ULL_CLK_DCP_CLK] = imx_clk_gate2("dcp", "ahb", base + 0x68, 10); | 343 | hws[IMX6ULL_CLK_DCP_CLK] = imx_clk_hw_gate2("dcp", "ahb", base + 0x68, 10); |
338 | clks[IMX6UL_CLK_ENET] = imx_clk_gate2("enet", "ipg", base + 0x68, 12); | 344 | hws[IMX6UL_CLK_ENET] = imx_clk_hw_gate2("enet", "ipg", base + 0x68, 12); |
339 | clks[IMX6UL_CLK_ENET_AHB] = imx_clk_gate2("enet_ahb", "ahb", base + 0x68, 12); | 345 | hws[IMX6UL_CLK_ENET_AHB] = imx_clk_hw_gate2("enet_ahb", "ahb", base + 0x68, 12); |
340 | } | 346 | } |
341 | clks[IMX6UL_CLK_CAN1_IPG] = imx_clk_gate2("can1_ipg", "ipg", base + 0x68, 14); | 347 | hws[IMX6UL_CLK_CAN1_IPG] = imx_clk_hw_gate2("can1_ipg", "ipg", base + 0x68, 14); |
342 | clks[IMX6UL_CLK_CAN1_SERIAL] = imx_clk_gate2("can1_serial", "can_podf", base + 0x68, 16); | 348 | hws[IMX6UL_CLK_CAN1_SERIAL] = imx_clk_hw_gate2("can1_serial", "can_podf", base + 0x68, 16); |
343 | clks[IMX6UL_CLK_CAN2_IPG] = imx_clk_gate2("can2_ipg", "ipg", base + 0x68, 18); | 349 | hws[IMX6UL_CLK_CAN2_IPG] = imx_clk_hw_gate2("can2_ipg", "ipg", base + 0x68, 18); |
344 | clks[IMX6UL_CLK_CAN2_SERIAL] = imx_clk_gate2("can2_serial", "can_podf", base + 0x68, 20); | 350 | hws[IMX6UL_CLK_CAN2_SERIAL] = imx_clk_hw_gate2("can2_serial", "can_podf", base + 0x68, 20); |
345 | clks[IMX6UL_CLK_GPT2_BUS] = imx_clk_gate2("gpt2_bus", "perclk", base + 0x68, 24); | 351 | hws[IMX6UL_CLK_GPT2_BUS] = imx_clk_hw_gate2("gpt2_bus", "perclk", base + 0x68, 24); |
346 | clks[IMX6UL_CLK_GPT2_SERIAL] = imx_clk_gate2("gpt2_serial", "perclk", base + 0x68, 26); | 352 | hws[IMX6UL_CLK_GPT2_SERIAL] = imx_clk_hw_gate2("gpt2_serial", "perclk", base + 0x68, 26); |
347 | clks[IMX6UL_CLK_UART2_IPG] = imx_clk_gate2("uart2_ipg", "ipg", base + 0x68, 28); | 353 | hws[IMX6UL_CLK_UART2_IPG] = imx_clk_hw_gate2("uart2_ipg", "ipg", base + 0x68, 28); |
348 | clks[IMX6UL_CLK_UART2_SERIAL] = imx_clk_gate2("uart2_serial", "uart_podf", base + 0x68, 28); | 354 | hws[IMX6UL_CLK_UART2_SERIAL] = imx_clk_hw_gate2("uart2_serial", "uart_podf", base + 0x68, 28); |
349 | if (clk_on_imx6ull()) | 355 | if (clk_on_imx6ull()) |
350 | clks[IMX6UL_CLK_AIPSTZ3] = imx_clk_gate2("aips_tz3", "ahb", base + 0x80, 18); | 356 | hws[IMX6UL_CLK_AIPSTZ3] = imx_clk_hw_gate2("aips_tz3", "ahb", base + 0x80, 18); |
351 | clks[IMX6UL_CLK_GPIO2] = imx_clk_gate2("gpio2", "ipg", base + 0x68, 30); | 357 | hws[IMX6UL_CLK_GPIO2] = imx_clk_hw_gate2("gpio2", "ipg", base + 0x68, 30); |
352 | 358 | ||
353 | /* CCGR1 */ | 359 | /* CCGR1 */ |
354 | clks[IMX6UL_CLK_ECSPI1] = imx_clk_gate2("ecspi1", "ecspi_podf", base + 0x6c, 0); | 360 | hws[IMX6UL_CLK_ECSPI1] = imx_clk_hw_gate2("ecspi1", "ecspi_podf", base + 0x6c, 0); |
355 | clks[IMX6UL_CLK_ECSPI2] = imx_clk_gate2("ecspi2", "ecspi_podf", base + 0x6c, 2); | 361 | hws[IMX6UL_CLK_ECSPI2] = imx_clk_hw_gate2("ecspi2", "ecspi_podf", base + 0x6c, 2); |
356 | clks[IMX6UL_CLK_ECSPI3] = imx_clk_gate2("ecspi3", "ecspi_podf", base + 0x6c, 4); | 362 | hws[IMX6UL_CLK_ECSPI3] = imx_clk_hw_gate2("ecspi3", "ecspi_podf", base + 0x6c, 4); |
357 | clks[IMX6UL_CLK_ECSPI4] = imx_clk_gate2("ecspi4", "ecspi_podf", base + 0x6c, 6); | 363 | hws[IMX6UL_CLK_ECSPI4] = imx_clk_hw_gate2("ecspi4", "ecspi_podf", base + 0x6c, 6); |
358 | clks[IMX6UL_CLK_ADC2] = imx_clk_gate2("adc2", "ipg", base + 0x6c, 8); | 364 | hws[IMX6UL_CLK_ADC2] = imx_clk_hw_gate2("adc2", "ipg", base + 0x6c, 8); |
359 | clks[IMX6UL_CLK_UART3_IPG] = imx_clk_gate2("uart3_ipg", "ipg", base + 0x6c, 10); | 365 | hws[IMX6UL_CLK_UART3_IPG] = imx_clk_hw_gate2("uart3_ipg", "ipg", base + 0x6c, 10); |
360 | clks[IMX6UL_CLK_UART3_SERIAL] = imx_clk_gate2("uart3_serial", "uart_podf", base + 0x6c, 10); | 366 | hws[IMX6UL_CLK_UART3_SERIAL] = imx_clk_hw_gate2("uart3_serial", "uart_podf", base + 0x6c, 10); |
361 | clks[IMX6UL_CLK_EPIT1] = imx_clk_gate2("epit1", "perclk", base + 0x6c, 12); | 367 | hws[IMX6UL_CLK_EPIT1] = imx_clk_hw_gate2("epit1", "perclk", base + 0x6c, 12); |
362 | clks[IMX6UL_CLK_EPIT2] = imx_clk_gate2("epit2", "perclk", base + 0x6c, 14); | 368 | hws[IMX6UL_CLK_EPIT2] = imx_clk_hw_gate2("epit2", "perclk", base + 0x6c, 14); |
363 | clks[IMX6UL_CLK_ADC1] = imx_clk_gate2("adc1", "ipg", base + 0x6c, 16); | 369 | hws[IMX6UL_CLK_ADC1] = imx_clk_hw_gate2("adc1", "ipg", base + 0x6c, 16); |
364 | clks[IMX6UL_CLK_GPT1_BUS] = imx_clk_gate2("gpt1_bus", "perclk", base + 0x6c, 20); | 370 | hws[IMX6UL_CLK_GPT1_BUS] = imx_clk_hw_gate2("gpt1_bus", "perclk", base + 0x6c, 20); |
365 | clks[IMX6UL_CLK_GPT1_SERIAL] = imx_clk_gate2("gpt1_serial", "perclk", base + 0x6c, 22); | 371 | hws[IMX6UL_CLK_GPT1_SERIAL] = imx_clk_hw_gate2("gpt1_serial", "perclk", base + 0x6c, 22); |
366 | clks[IMX6UL_CLK_UART4_IPG] = imx_clk_gate2("uart4_ipg", "ipg", base + 0x6c, 24); | 372 | hws[IMX6UL_CLK_UART4_IPG] = imx_clk_hw_gate2("uart4_ipg", "ipg", base + 0x6c, 24); |
367 | clks[IMX6UL_CLK_UART4_SERIAL] = imx_clk_gate2("uart4_serial", "uart_podf", base + 0x6c, 24); | 373 | hws[IMX6UL_CLK_UART4_SERIAL] = imx_clk_hw_gate2("uart4_serial", "uart_podf", base + 0x6c, 24); |
368 | clks[IMX6UL_CLK_GPIO1] = imx_clk_gate2("gpio1", "ipg", base + 0x6c, 26); | 374 | hws[IMX6UL_CLK_GPIO1] = imx_clk_hw_gate2("gpio1", "ipg", base + 0x6c, 26); |
369 | clks[IMX6UL_CLK_GPIO5] = imx_clk_gate2("gpio5", "ipg", base + 0x6c, 30); | 375 | hws[IMX6UL_CLK_GPIO5] = imx_clk_hw_gate2("gpio5", "ipg", base + 0x6c, 30); |
370 | 376 | ||
371 | /* CCGR2 */ | 377 | /* CCGR2 */ |
372 | if (clk_on_imx6ull()) { | 378 | if (clk_on_imx6ull()) { |
373 | clks[IMX6ULL_CLK_ESAI_EXTAL] = imx_clk_gate2_shared("esai_extal", "esai_podf", base + 0x70, 0, &share_count_esai); | 379 | hws[IMX6ULL_CLK_ESAI_EXTAL] = imx_clk_hw_gate2_shared("esai_extal", "esai_podf", base + 0x70, 0, &share_count_esai); |
374 | clks[IMX6ULL_CLK_ESAI_IPG] = imx_clk_gate2_shared("esai_ipg", "ahb", base + 0x70, 0, &share_count_esai); | 380 | hws[IMX6ULL_CLK_ESAI_IPG] = imx_clk_hw_gate2_shared("esai_ipg", "ahb", base + 0x70, 0, &share_count_esai); |
375 | clks[IMX6ULL_CLK_ESAI_MEM] = imx_clk_gate2_shared("esai_mem", "ahb", base + 0x70, 0, &share_count_esai); | 381 | hws[IMX6ULL_CLK_ESAI_MEM] = imx_clk_hw_gate2_shared("esai_mem", "ahb", base + 0x70, 0, &share_count_esai); |
376 | } | 382 | } |
377 | clks[IMX6UL_CLK_CSI] = imx_clk_gate2("csi", "csi_podf", base + 0x70, 2); | 383 | hws[IMX6UL_CLK_CSI] = imx_clk_hw_gate2("csi", "csi_podf", base + 0x70, 2); |
378 | clks[IMX6UL_CLK_I2C1] = imx_clk_gate2("i2c1", "perclk", base + 0x70, 6); | 384 | hws[IMX6UL_CLK_I2C1] = imx_clk_hw_gate2("i2c1", "perclk", base + 0x70, 6); |
379 | clks[IMX6UL_CLK_I2C2] = imx_clk_gate2("i2c2", "perclk", base + 0x70, 8); | 385 | hws[IMX6UL_CLK_I2C2] = imx_clk_hw_gate2("i2c2", "perclk", base + 0x70, 8); |
380 | clks[IMX6UL_CLK_I2C3] = imx_clk_gate2("i2c3", "perclk", base + 0x70, 10); | 386 | hws[IMX6UL_CLK_I2C3] = imx_clk_hw_gate2("i2c3", "perclk", base + 0x70, 10); |
381 | clks[IMX6UL_CLK_OCOTP] = imx_clk_gate2("ocotp", "ipg", base + 0x70, 12); | 387 | hws[IMX6UL_CLK_OCOTP] = imx_clk_hw_gate2("ocotp", "ipg", base + 0x70, 12); |
382 | clks[IMX6UL_CLK_IOMUXC] = imx_clk_gate2("iomuxc", "lcdif_podf", base + 0x70, 14); | 388 | hws[IMX6UL_CLK_IOMUXC] = imx_clk_hw_gate2("iomuxc", "lcdif_podf", base + 0x70, 14); |
383 | clks[IMX6UL_CLK_GPIO3] = imx_clk_gate2("gpio3", "ipg", base + 0x70, 26); | 389 | hws[IMX6UL_CLK_GPIO3] = imx_clk_hw_gate2("gpio3", "ipg", base + 0x70, 26); |
384 | clks[IMX6UL_CLK_LCDIF_APB] = imx_clk_gate2("lcdif_apb", "axi", base + 0x70, 28); | 390 | hws[IMX6UL_CLK_LCDIF_APB] = imx_clk_hw_gate2("lcdif_apb", "axi", base + 0x70, 28); |
385 | clks[IMX6UL_CLK_PXP] = imx_clk_gate2("pxp", "axi", base + 0x70, 30); | 391 | hws[IMX6UL_CLK_PXP] = imx_clk_hw_gate2("pxp", "axi", base + 0x70, 30); |
386 | 392 | ||
387 | /* CCGR3 */ | 393 | /* CCGR3 */ |
388 | clks[IMX6UL_CLK_UART5_IPG] = imx_clk_gate2("uart5_ipg", "ipg", base + 0x74, 2); | 394 | hws[IMX6UL_CLK_UART5_IPG] = imx_clk_hw_gate2("uart5_ipg", "ipg", base + 0x74, 2); |
389 | clks[IMX6UL_CLK_UART5_SERIAL] = imx_clk_gate2("uart5_serial", "uart_podf", base + 0x74, 2); | 395 | hws[IMX6UL_CLK_UART5_SERIAL] = imx_clk_hw_gate2("uart5_serial", "uart_podf", base + 0x74, 2); |
390 | if (clk_on_imx6ul()) { | 396 | if (clk_on_imx6ul()) { |
391 | clks[IMX6UL_CLK_ENET] = imx_clk_gate2("enet", "ipg", base + 0x74, 4); | 397 | hws[IMX6UL_CLK_ENET] = imx_clk_hw_gate2("enet", "ipg", base + 0x74, 4); |
392 | clks[IMX6UL_CLK_ENET_AHB] = imx_clk_gate2("enet_ahb", "ahb", base + 0x74, 4); | 398 | hws[IMX6UL_CLK_ENET_AHB] = imx_clk_hw_gate2("enet_ahb", "ahb", base + 0x74, 4); |
393 | } else if (clk_on_imx6ull()) { | 399 | } else if (clk_on_imx6ull()) { |
394 | clks[IMX6ULL_CLK_EPDC_ACLK] = imx_clk_gate2("epdc_aclk", "axi", base + 0x74, 4); | 400 | hws[IMX6ULL_CLK_EPDC_ACLK] = imx_clk_hw_gate2("epdc_aclk", "axi", base + 0x74, 4); |
395 | clks[IMX6ULL_CLK_EPDC_PIX] = imx_clk_gate2("epdc_pix", "epdc_podf", base + 0x74, 4); | 401 | hws[IMX6ULL_CLK_EPDC_PIX] = imx_clk_hw_gate2("epdc_pix", "epdc_podf", base + 0x74, 4); |
396 | } | 402 | } |
397 | clks[IMX6UL_CLK_UART6_IPG] = imx_clk_gate2("uart6_ipg", "ipg", base + 0x74, 6); | 403 | hws[IMX6UL_CLK_UART6_IPG] = imx_clk_hw_gate2("uart6_ipg", "ipg", base + 0x74, 6); |
398 | clks[IMX6UL_CLK_UART6_SERIAL] = imx_clk_gate2("uart6_serial", "uart_podf", base + 0x74, 6); | 404 | hws[IMX6UL_CLK_UART6_SERIAL] = imx_clk_hw_gate2("uart6_serial", "uart_podf", base + 0x74, 6); |
399 | clks[IMX6UL_CLK_LCDIF_PIX] = imx_clk_gate2("lcdif_pix", "lcdif_podf", base + 0x74, 10); | 405 | hws[IMX6UL_CLK_LCDIF_PIX] = imx_clk_hw_gate2("lcdif_pix", "lcdif_podf", base + 0x74, 10); |
400 | clks[IMX6UL_CLK_GPIO4] = imx_clk_gate2("gpio4", "ipg", base + 0x74, 12); | 406 | hws[IMX6UL_CLK_GPIO4] = imx_clk_hw_gate2("gpio4", "ipg", base + 0x74, 12); |
401 | clks[IMX6UL_CLK_QSPI] = imx_clk_gate2("qspi1", "qspi1_podf", base + 0x74, 14); | 407 | hws[IMX6UL_CLK_QSPI] = imx_clk_hw_gate2("qspi1", "qspi1_podf", base + 0x74, 14); |
402 | clks[IMX6UL_CLK_WDOG1] = imx_clk_gate2("wdog1", "ipg", base + 0x74, 16); | 408 | hws[IMX6UL_CLK_WDOG1] = imx_clk_hw_gate2("wdog1", "ipg", base + 0x74, 16); |
403 | clks[IMX6UL_CLK_MMDC_P0_FAST] = imx_clk_gate_flags("mmdc_p0_fast", "mmdc_podf", base + 0x74, 20, CLK_IS_CRITICAL); | 409 | hws[IMX6UL_CLK_MMDC_P0_FAST] = imx_clk_hw_gate_flags("mmdc_p0_fast", "mmdc_podf", base + 0x74, 20, CLK_IS_CRITICAL); |
404 | clks[IMX6UL_CLK_MMDC_P0_IPG] = imx_clk_gate2_flags("mmdc_p0_ipg", "ipg", base + 0x74, 24, CLK_IS_CRITICAL); | 410 | hws[IMX6UL_CLK_MMDC_P0_IPG] = imx_clk_hw_gate2_flags("mmdc_p0_ipg", "ipg", base + 0x74, 24, CLK_IS_CRITICAL); |
405 | clks[IMX6UL_CLK_MMDC_P1_IPG] = imx_clk_gate2("mmdc_p1_ipg", "ipg", base + 0x74, 26); | 411 | hws[IMX6UL_CLK_MMDC_P1_IPG] = imx_clk_hw_gate2_flags("mmdc_p1_ipg", "ipg", base + 0x74, 26, CLK_IS_CRITICAL); |
406 | clks[IMX6UL_CLK_AXI] = imx_clk_gate_flags("axi", "axi_podf", base + 0x74, 28, CLK_IS_CRITICAL); | 412 | hws[IMX6UL_CLK_AXI] = imx_clk_hw_gate_flags("axi", "axi_podf", base + 0x74, 28, CLK_IS_CRITICAL); |
407 | 413 | ||
408 | /* CCGR4 */ | 414 | /* CCGR4 */ |
409 | clks[IMX6UL_CLK_PER_BCH] = imx_clk_gate2("per_bch", "bch_podf", base + 0x78, 12); | 415 | hws[IMX6UL_CLK_PER_BCH] = imx_clk_hw_gate2("per_bch", "bch_podf", base + 0x78, 12); |
410 | clks[IMX6UL_CLK_PWM1] = imx_clk_gate2("pwm1", "perclk", base + 0x78, 16); | 416 | hws[IMX6UL_CLK_PWM1] = imx_clk_hw_gate2("pwm1", "perclk", base + 0x78, 16); |
411 | clks[IMX6UL_CLK_PWM2] = imx_clk_gate2("pwm2", "perclk", base + 0x78, 18); | 417 | hws[IMX6UL_CLK_PWM2] = imx_clk_hw_gate2("pwm2", "perclk", base + 0x78, 18); |
412 | clks[IMX6UL_CLK_PWM3] = imx_clk_gate2("pwm3", "perclk", base + 0x78, 20); | 418 | hws[IMX6UL_CLK_PWM3] = imx_clk_hw_gate2("pwm3", "perclk", base + 0x78, 20); |
413 | clks[IMX6UL_CLK_PWM4] = imx_clk_gate2("pwm4", "perclk", base + 0x78, 22); | 419 | hws[IMX6UL_CLK_PWM4] = imx_clk_hw_gate2("pwm4", "perclk", base + 0x78, 22); |
414 | clks[IMX6UL_CLK_GPMI_BCH_APB] = imx_clk_gate2("gpmi_bch_apb", "bch_podf", base + 0x78, 24); | 420 | hws[IMX6UL_CLK_GPMI_BCH_APB] = imx_clk_hw_gate2("gpmi_bch_apb", "bch_podf", base + 0x78, 24); |
415 | clks[IMX6UL_CLK_GPMI_BCH] = imx_clk_gate2("gpmi_bch", "gpmi_podf", base + 0x78, 26); | 421 | hws[IMX6UL_CLK_GPMI_BCH] = imx_clk_hw_gate2("gpmi_bch", "gpmi_podf", base + 0x78, 26); |
416 | clks[IMX6UL_CLK_GPMI_IO] = imx_clk_gate2("gpmi_io", "enfc_podf", base + 0x78, 28); | 422 | hws[IMX6UL_CLK_GPMI_IO] = imx_clk_hw_gate2("gpmi_io", "enfc_podf", base + 0x78, 28); |
417 | clks[IMX6UL_CLK_GPMI_APB] = imx_clk_gate2("gpmi_apb", "bch_podf", base + 0x78, 30); | 423 | hws[IMX6UL_CLK_GPMI_APB] = imx_clk_hw_gate2("gpmi_apb", "bch_podf", base + 0x78, 30); |
418 | 424 | ||
419 | /* CCGR5 */ | 425 | /* CCGR5 */ |
420 | clks[IMX6UL_CLK_ROM] = imx_clk_gate2_flags("rom", "ahb", base + 0x7c, 0, CLK_IS_CRITICAL); | 426 | hws[IMX6UL_CLK_ROM] = imx_clk_hw_gate2_flags("rom", "ahb", base + 0x7c, 0, CLK_IS_CRITICAL); |
421 | clks[IMX6UL_CLK_SDMA] = imx_clk_gate2("sdma", "ahb", base + 0x7c, 6); | 427 | hws[IMX6UL_CLK_SDMA] = imx_clk_hw_gate2("sdma", "ahb", base + 0x7c, 6); |
422 | clks[IMX6UL_CLK_KPP] = imx_clk_gate2("kpp", "ipg", base + 0x7c, 8); | 428 | hws[IMX6UL_CLK_KPP] = imx_clk_hw_gate2("kpp", "ipg", base + 0x7c, 8); |
423 | clks[IMX6UL_CLK_WDOG2] = imx_clk_gate2("wdog2", "ipg", base + 0x7c, 10); | 429 | hws[IMX6UL_CLK_WDOG2] = imx_clk_hw_gate2("wdog2", "ipg", base + 0x7c, 10); |
424 | clks[IMX6UL_CLK_SPBA] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12); | 430 | hws[IMX6UL_CLK_SPBA] = imx_clk_hw_gate2("spba", "ipg", base + 0x7c, 12); |
425 | clks[IMX6UL_CLK_SPDIF] = imx_clk_gate2_shared("spdif", "spdif_podf", base + 0x7c, 14, &share_count_audio); | 431 | hws[IMX6UL_CLK_SPDIF] = imx_clk_hw_gate2_shared("spdif", "spdif_podf", base + 0x7c, 14, &share_count_audio); |
426 | clks[IMX6UL_CLK_SPDIF_GCLK] = imx_clk_gate2_shared("spdif_gclk", "ipg", base + 0x7c, 14, &share_count_audio); | 432 | hws[IMX6UL_CLK_SPDIF_GCLK] = imx_clk_hw_gate2_shared("spdif_gclk", "ipg", base + 0x7c, 14, &share_count_audio); |
427 | clks[IMX6UL_CLK_SAI3] = imx_clk_gate2_shared("sai3", "sai3_podf", base + 0x7c, 22, &share_count_sai3); | 433 | hws[IMX6UL_CLK_SAI3] = imx_clk_hw_gate2_shared("sai3", "sai3_podf", base + 0x7c, 22, &share_count_sai3); |
428 | clks[IMX6UL_CLK_SAI3_IPG] = imx_clk_gate2_shared("sai3_ipg", "ipg", base + 0x7c, 22, &share_count_sai3); | 434 | hws[IMX6UL_CLK_SAI3_IPG] = imx_clk_hw_gate2_shared("sai3_ipg", "ipg", base + 0x7c, 22, &share_count_sai3); |
429 | clks[IMX6UL_CLK_UART1_IPG] = imx_clk_gate2("uart1_ipg", "ipg", base + 0x7c, 24); | 435 | hws[IMX6UL_CLK_UART1_IPG] = imx_clk_hw_gate2("uart1_ipg", "ipg", base + 0x7c, 24); |
430 | clks[IMX6UL_CLK_UART1_SERIAL] = imx_clk_gate2("uart1_serial", "uart_podf", base + 0x7c, 24); | 436 | hws[IMX6UL_CLK_UART1_SERIAL] = imx_clk_hw_gate2("uart1_serial", "uart_podf", base + 0x7c, 24); |
431 | clks[IMX6UL_CLK_UART7_IPG] = imx_clk_gate2("uart7_ipg", "ipg", base + 0x7c, 26); | 437 | hws[IMX6UL_CLK_UART7_IPG] = imx_clk_hw_gate2("uart7_ipg", "ipg", base + 0x7c, 26); |
432 | clks[IMX6UL_CLK_UART7_SERIAL] = imx_clk_gate2("uart7_serial", "uart_podf", base + 0x7c, 26); | 438 | hws[IMX6UL_CLK_UART7_SERIAL] = imx_clk_hw_gate2("uart7_serial", "uart_podf", base + 0x7c, 26); |
433 | clks[IMX6UL_CLK_SAI1] = imx_clk_gate2_shared("sai1", "sai1_podf", base + 0x7c, 28, &share_count_sai1); | 439 | hws[IMX6UL_CLK_SAI1] = imx_clk_hw_gate2_shared("sai1", "sai1_podf", base + 0x7c, 28, &share_count_sai1); |
434 | clks[IMX6UL_CLK_SAI1_IPG] = imx_clk_gate2_shared("sai1_ipg", "ipg", base + 0x7c, 28, &share_count_sai1); | 440 | hws[IMX6UL_CLK_SAI1_IPG] = imx_clk_hw_gate2_shared("sai1_ipg", "ipg", base + 0x7c, 28, &share_count_sai1); |
435 | clks[IMX6UL_CLK_SAI2] = imx_clk_gate2_shared("sai2", "sai2_podf", base + 0x7c, 30, &share_count_sai2); | 441 | hws[IMX6UL_CLK_SAI2] = imx_clk_hw_gate2_shared("sai2", "sai2_podf", base + 0x7c, 30, &share_count_sai2); |
436 | clks[IMX6UL_CLK_SAI2_IPG] = imx_clk_gate2_shared("sai2_ipg", "ipg", base + 0x7c, 30, &share_count_sai2); | 442 | hws[IMX6UL_CLK_SAI2_IPG] = imx_clk_hw_gate2_shared("sai2_ipg", "ipg", base + 0x7c, 30, &share_count_sai2); |
437 | 443 | ||
438 | /* CCGR6 */ | 444 | /* CCGR6 */ |
439 | clks[IMX6UL_CLK_USBOH3] = imx_clk_gate2("usboh3", "ipg", base + 0x80, 0); | 445 | hws[IMX6UL_CLK_USBOH3] = imx_clk_hw_gate2("usboh3", "ipg", base + 0x80, 0); |
440 | clks[IMX6UL_CLK_USDHC1] = imx_clk_gate2("usdhc1", "usdhc1_podf", base + 0x80, 2); | 446 | hws[IMX6UL_CLK_USDHC1] = imx_clk_hw_gate2("usdhc1", "usdhc1_podf", base + 0x80, 2); |
441 | clks[IMX6UL_CLK_USDHC2] = imx_clk_gate2("usdhc2", "usdhc2_podf", base + 0x80, 4); | 447 | hws[IMX6UL_CLK_USDHC2] = imx_clk_hw_gate2("usdhc2", "usdhc2_podf", base + 0x80, 4); |
442 | if (clk_on_imx6ul()) { | 448 | if (clk_on_imx6ul()) { |
443 | clks[IMX6UL_CLK_SIM1] = imx_clk_gate2("sim1", "sim_sel", base + 0x80, 6); | 449 | hws[IMX6UL_CLK_SIM1] = imx_clk_hw_gate2("sim1", "sim_sel", base + 0x80, 6); |
444 | clks[IMX6UL_CLK_SIM2] = imx_clk_gate2("sim2", "sim_sel", base + 0x80, 8); | 450 | hws[IMX6UL_CLK_SIM2] = imx_clk_hw_gate2("sim2", "sim_sel", base + 0x80, 8); |
445 | } | 451 | } |
446 | clks[IMX6UL_CLK_EIM] = imx_clk_gate2("eim", "eim_slow_podf", base + 0x80, 10); | 452 | hws[IMX6UL_CLK_EIM] = imx_clk_hw_gate2("eim", "eim_slow_podf", base + 0x80, 10); |
447 | clks[IMX6UL_CLK_PWM8] = imx_clk_gate2("pwm8", "perclk", base + 0x80, 16); | 453 | hws[IMX6UL_CLK_PWM8] = imx_clk_hw_gate2("pwm8", "perclk", base + 0x80, 16); |
448 | clks[IMX6UL_CLK_UART8_IPG] = imx_clk_gate2("uart8_ipg", "ipg", base + 0x80, 14); | 454 | hws[IMX6UL_CLK_UART8_IPG] = imx_clk_hw_gate2("uart8_ipg", "ipg", base + 0x80, 14); |
449 | clks[IMX6UL_CLK_UART8_SERIAL] = imx_clk_gate2("uart8_serial", "uart_podf", base + 0x80, 14); | 455 | hws[IMX6UL_CLK_UART8_SERIAL] = imx_clk_hw_gate2("uart8_serial", "uart_podf", base + 0x80, 14); |
450 | clks[IMX6UL_CLK_WDOG3] = imx_clk_gate2("wdog3", "ipg", base + 0x80, 20); | 456 | hws[IMX6UL_CLK_WDOG3] = imx_clk_hw_gate2("wdog3", "ipg", base + 0x80, 20); |
451 | clks[IMX6UL_CLK_I2C4] = imx_clk_gate2("i2c4", "perclk", base + 0x80, 24); | 457 | hws[IMX6UL_CLK_I2C4] = imx_clk_hw_gate2("i2c4", "perclk", base + 0x80, 24); |
452 | clks[IMX6UL_CLK_PWM5] = imx_clk_gate2("pwm5", "perclk", base + 0x80, 26); | 458 | hws[IMX6UL_CLK_PWM5] = imx_clk_hw_gate2("pwm5", "perclk", base + 0x80, 26); |
453 | clks[IMX6UL_CLK_PWM6] = imx_clk_gate2("pwm6", "perclk", base + 0x80, 28); | 459 | hws[IMX6UL_CLK_PWM6] = imx_clk_hw_gate2("pwm6", "perclk", base + 0x80, 28); |
454 | clks[IMX6UL_CLK_PWM7] = imx_clk_gate2("pwm7", "perclk", base + 0x80, 30); | 460 | hws[IMX6UL_CLK_PWM7] = imx_clk_hw_gate2("pwm7", "perclk", base + 0x80, 30); |
455 | 461 | ||
456 | /* CCOSR */ | 462 | /* CCOSR */ |
457 | clks[IMX6UL_CLK_CKO1] = imx_clk_gate("cko1", "cko1_podf", base + 0x60, 7); | 463 | hws[IMX6UL_CLK_CKO1] = imx_clk_hw_gate("cko1", "cko1_podf", base + 0x60, 7); |
458 | clks[IMX6UL_CLK_CKO2] = imx_clk_gate("cko2", "cko2_podf", base + 0x60, 24); | 464 | hws[IMX6UL_CLK_CKO2] = imx_clk_hw_gate("cko2", "cko2_podf", base + 0x60, 24); |
459 | 465 | ||
460 | /* mask handshake of mmdc */ | 466 | /* mask handshake of mmdc */ |
461 | writel_relaxed(BM_CCM_CCDR_MMDC_CH0_MASK, base + CCDR); | 467 | imx_mmdc_mask_handshake(base, 0); |
462 | 468 | ||
463 | imx_check_clocks(clks, ARRAY_SIZE(clks)); | 469 | imx_check_clk_hws(hws, IMX6UL_CLK_END); |
464 | 470 | ||
465 | clk_data.clks = clks; | 471 | of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data); |
466 | clk_data.clk_num = ARRAY_SIZE(clks); | ||
467 | of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); | ||
468 | 472 | ||
469 | /* | 473 | /* |
470 | * Lower the AHB clock rate before changing the parent clock source, | 474 | * Lower the AHB clock rate before changing the parent clock source, |
@@ -473,39 +477,39 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node) | |||
473 | * AXI clock rate, so we need to lower AHB rate first to make sure at | 477 | * AXI clock rate, so we need to lower AHB rate first to make sure at |
474 | * any time, AHB rate is <= 133MHz. | 478 | * any time, AHB rate is <= 133MHz. |
475 | */ | 479 | */ |
476 | clk_set_rate(clks[IMX6UL_CLK_AHB], 99000000); | 480 | clk_set_rate(hws[IMX6UL_CLK_AHB]->clk, 99000000); |
477 | 481 | ||
478 | /* Change periph_pre clock to pll2_bus to adjust AXI rate to 264MHz */ | 482 | /* Change periph_pre clock to pll2_bus to adjust AXI rate to 264MHz */ |
479 | clk_set_parent(clks[IMX6UL_CLK_PERIPH_CLK2_SEL], clks[IMX6UL_CLK_OSC]); | 483 | clk_set_parent(hws[IMX6UL_CLK_PERIPH_CLK2_SEL]->clk, hws[IMX6UL_CLK_OSC]->clk); |
480 | clk_set_parent(clks[IMX6UL_CLK_PERIPH], clks[IMX6UL_CLK_PERIPH_CLK2]); | 484 | clk_set_parent(hws[IMX6UL_CLK_PERIPH]->clk, hws[IMX6UL_CLK_PERIPH_CLK2]->clk); |
481 | clk_set_parent(clks[IMX6UL_CLK_PERIPH_PRE], clks[IMX6UL_CLK_PLL2_BUS]); | 485 | clk_set_parent(hws[IMX6UL_CLK_PERIPH_PRE]->clk, hws[IMX6UL_CLK_PLL2_BUS]->clk); |
482 | clk_set_parent(clks[IMX6UL_CLK_PERIPH], clks[IMX6UL_CLK_PERIPH_PRE]); | 486 | clk_set_parent(hws[IMX6UL_CLK_PERIPH]->clk, hws[IMX6UL_CLK_PERIPH_PRE]->clk); |
483 | 487 | ||
484 | /* Make sure AHB rate is 132MHz */ | 488 | /* Make sure AHB rate is 132MHz */ |
485 | clk_set_rate(clks[IMX6UL_CLK_AHB], 132000000); | 489 | clk_set_rate(hws[IMX6UL_CLK_AHB]->clk, 132000000); |
486 | 490 | ||
487 | /* set perclk to from OSC */ | 491 | /* set perclk to from OSC */ |
488 | clk_set_parent(clks[IMX6UL_CLK_PERCLK_SEL], clks[IMX6UL_CLK_OSC]); | 492 | clk_set_parent(hws[IMX6UL_CLK_PERCLK_SEL]->clk, hws[IMX6UL_CLK_OSC]->clk); |
489 | 493 | ||
490 | clk_set_rate(clks[IMX6UL_CLK_ENET_REF], 50000000); | 494 | clk_set_rate(hws[IMX6UL_CLK_ENET_REF]->clk, 50000000); |
491 | clk_set_rate(clks[IMX6UL_CLK_ENET2_REF], 50000000); | 495 | clk_set_rate(hws[IMX6UL_CLK_ENET2_REF]->clk, 50000000); |
492 | clk_set_rate(clks[IMX6UL_CLK_CSI], 24000000); | 496 | clk_set_rate(hws[IMX6UL_CLK_CSI]->clk, 24000000); |
493 | 497 | ||
494 | if (clk_on_imx6ull()) | 498 | if (clk_on_imx6ull()) |
495 | clk_prepare_enable(clks[IMX6UL_CLK_AIPSTZ3]); | 499 | clk_prepare_enable(hws[IMX6UL_CLK_AIPSTZ3]->clk); |
496 | 500 | ||
497 | if (IS_ENABLED(CONFIG_USB_MXS_PHY)) { | 501 | if (IS_ENABLED(CONFIG_USB_MXS_PHY)) { |
498 | clk_prepare_enable(clks[IMX6UL_CLK_USBPHY1_GATE]); | 502 | clk_prepare_enable(hws[IMX6UL_CLK_USBPHY1_GATE]->clk); |
499 | clk_prepare_enable(clks[IMX6UL_CLK_USBPHY2_GATE]); | 503 | clk_prepare_enable(hws[IMX6UL_CLK_USBPHY2_GATE]->clk); |
500 | } | 504 | } |
501 | 505 | ||
502 | clk_set_parent(clks[IMX6UL_CLK_CAN_SEL], clks[IMX6UL_CLK_PLL3_60M]); | 506 | clk_set_parent(hws[IMX6UL_CLK_CAN_SEL]->clk, hws[IMX6UL_CLK_PLL3_60M]->clk); |
503 | if (clk_on_imx6ul()) | 507 | if (clk_on_imx6ul()) |
504 | clk_set_parent(clks[IMX6UL_CLK_SIM_PRE_SEL], clks[IMX6UL_CLK_PLL3_USB_OTG]); | 508 | clk_set_parent(hws[IMX6UL_CLK_SIM_PRE_SEL]->clk, hws[IMX6UL_CLK_PLL3_USB_OTG]->clk); |
505 | else if (clk_on_imx6ull()) | 509 | else if (clk_on_imx6ull()) |
506 | clk_set_parent(clks[IMX6ULL_CLK_EPDC_PRE_SEL], clks[IMX6UL_CLK_PLL3_PFD2]); | 510 | clk_set_parent(hws[IMX6ULL_CLK_EPDC_PRE_SEL]->clk, hws[IMX6UL_CLK_PLL3_PFD2]->clk); |
507 | 511 | ||
508 | clk_set_parent(clks[IMX6UL_CLK_ENFC_SEL], clks[IMX6UL_CLK_PLL2_PFD2]); | 512 | clk_set_parent(hws[IMX6UL_CLK_ENFC_SEL]->clk, hws[IMX6UL_CLK_PLL2_PFD2]->clk); |
509 | } | 513 | } |
510 | 514 | ||
511 | CLK_OF_DECLARE(imx6ul, "fsl,imx6ul-ccm", imx6ul_clocks_init); | 515 | CLK_OF_DECLARE(imx6ul, "fsl,imx6ul-ccm", imx6ul_clocks_init); |
diff --git a/drivers/clk/imx/clk-imx7d.c b/drivers/clk/imx/clk-imx7d.c index 8f3aa994c8f7..fbea774ef687 100644 --- a/drivers/clk/imx/clk-imx7d.c +++ b/drivers/clk/imx/clk-imx7d.c | |||
@@ -6,6 +6,7 @@ | |||
6 | #include <dt-bindings/clock/imx7d-clock.h> | 6 | #include <dt-bindings/clock/imx7d-clock.h> |
7 | #include <linux/clk.h> | 7 | #include <linux/clk.h> |
8 | #include <linux/clkdev.h> | 8 | #include <linux/clkdev.h> |
9 | #include <linux/clk-provider.h> | ||
9 | #include <linux/err.h> | 10 | #include <linux/err.h> |
10 | #include <linux/init.h> | 11 | #include <linux/init.h> |
11 | #include <linux/io.h> | 12 | #include <linux/io.h> |
@@ -39,7 +40,6 @@ static const struct clk_div_table post_div_table[] = { | |||
39 | { } | 40 | { } |
40 | }; | 41 | }; |
41 | 42 | ||
42 | static struct clk *clks[IMX7D_CLK_END]; | ||
43 | static const char *arm_a7_sel[] = { "osc", "pll_arm_main_clk", | 43 | static const char *arm_a7_sel[] = { "osc", "pll_arm_main_clk", |
44 | "pll_enet_500m_clk", "pll_dram_main_clk", | 44 | "pll_enet_500m_clk", "pll_dram_main_clk", |
45 | "pll_sys_main_clk", "pll_sys_pfd0_392m_clk", "pll_audio_post_div", | 45 | "pll_sys_main_clk", "pll_sys_pfd0_392m_clk", "pll_audio_post_div", |
@@ -373,517 +373,533 @@ static const char *pll_enet_bypass_sel[] = { "pll_enet_main", "pll_enet_main_src | |||
373 | static const char *pll_audio_bypass_sel[] = { "pll_audio_main", "pll_audio_main_src", }; | 373 | static const char *pll_audio_bypass_sel[] = { "pll_audio_main", "pll_audio_main_src", }; |
374 | static const char *pll_video_bypass_sel[] = { "pll_video_main", "pll_video_main_src", }; | 374 | static const char *pll_video_bypass_sel[] = { "pll_video_main", "pll_video_main_src", }; |
375 | 375 | ||
376 | static struct clk_onecell_data clk_data; | 376 | static struct clk_hw **hws; |
377 | 377 | static struct clk_hw_onecell_data *clk_hw_data; | |
378 | static struct clk ** const uart_clks[] __initconst = { | 378 | |
379 | &clks[IMX7D_UART1_ROOT_CLK], | 379 | static const int uart_clk_ids[] __initconst = { |
380 | &clks[IMX7D_UART2_ROOT_CLK], | 380 | IMX7D_UART1_ROOT_CLK, |
381 | &clks[IMX7D_UART3_ROOT_CLK], | 381 | IMX7D_UART2_ROOT_CLK, |
382 | &clks[IMX7D_UART4_ROOT_CLK], | 382 | IMX7D_UART3_ROOT_CLK, |
383 | &clks[IMX7D_UART5_ROOT_CLK], | 383 | IMX7D_UART4_ROOT_CLK, |
384 | &clks[IMX7D_UART6_ROOT_CLK], | 384 | IMX7D_UART5_ROOT_CLK, |
385 | &clks[IMX7D_UART7_ROOT_CLK], | 385 | IMX7D_UART6_ROOT_CLK, |
386 | NULL | 386 | IMX7D_UART7_ROOT_CLK, |
387 | }; | 387 | }; |
388 | 388 | ||
389 | static struct clk **uart_clks[ARRAY_SIZE(uart_clk_ids) + 1] __initdata; | ||
390 | |||
389 | static void __init imx7d_clocks_init(struct device_node *ccm_node) | 391 | static void __init imx7d_clocks_init(struct device_node *ccm_node) |
390 | { | 392 | { |
391 | struct device_node *np; | 393 | struct device_node *np; |
392 | void __iomem *base; | 394 | void __iomem *base; |
395 | int i; | ||
396 | |||
397 | clk_hw_data = kzalloc(struct_size(clk_hw_data, hws, | ||
398 | IMX7D_CLK_END), GFP_KERNEL); | ||
399 | if (WARN_ON(!clk_hw_data)) | ||
400 | return; | ||
401 | |||
402 | clk_hw_data->num = IMX7D_CLK_END; | ||
403 | hws = clk_hw_data->hws; | ||
393 | 404 | ||
394 | clks[IMX7D_CLK_DUMMY] = imx_clk_fixed("dummy", 0); | 405 | hws[IMX7D_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0); |
395 | clks[IMX7D_OSC_24M_CLK] = of_clk_get_by_name(ccm_node, "osc"); | 406 | hws[IMX7D_OSC_24M_CLK] = __clk_get_hw(of_clk_get_by_name(ccm_node, "osc")); |
396 | clks[IMX7D_CKIL] = of_clk_get_by_name(ccm_node, "ckil"); | 407 | hws[IMX7D_CKIL] = __clk_get_hw(of_clk_get_by_name(ccm_node, "ckil")); |
397 | 408 | ||
398 | np = of_find_compatible_node(NULL, NULL, "fsl,imx7d-anatop"); | 409 | np = of_find_compatible_node(NULL, NULL, "fsl,imx7d-anatop"); |
399 | base = of_iomap(np, 0); | 410 | base = of_iomap(np, 0); |
400 | WARN_ON(!base); | 411 | WARN_ON(!base); |
401 | of_node_put(np); | 412 | of_node_put(np); |
402 | 413 | ||
403 | clks[IMX7D_PLL_ARM_MAIN_SRC] = imx_clk_mux("pll_arm_main_src", base + 0x60, 14, 2, pll_bypass_src_sel, ARRAY_SIZE(pll_bypass_src_sel)); | 414 | hws[IMX7D_PLL_ARM_MAIN_SRC] = imx_clk_hw_mux("pll_arm_main_src", base + 0x60, 14, 2, pll_bypass_src_sel, ARRAY_SIZE(pll_bypass_src_sel)); |
404 | clks[IMX7D_PLL_DRAM_MAIN_SRC] = imx_clk_mux("pll_dram_main_src", base + 0x70, 14, 2, pll_bypass_src_sel, ARRAY_SIZE(pll_bypass_src_sel)); | 415 | hws[IMX7D_PLL_DRAM_MAIN_SRC] = imx_clk_hw_mux("pll_dram_main_src", base + 0x70, 14, 2, pll_bypass_src_sel, ARRAY_SIZE(pll_bypass_src_sel)); |
405 | clks[IMX7D_PLL_SYS_MAIN_SRC] = imx_clk_mux("pll_sys_main_src", base + 0xb0, 14, 2, pll_bypass_src_sel, ARRAY_SIZE(pll_bypass_src_sel)); | 416 | hws[IMX7D_PLL_SYS_MAIN_SRC] = imx_clk_hw_mux("pll_sys_main_src", base + 0xb0, 14, 2, pll_bypass_src_sel, ARRAY_SIZE(pll_bypass_src_sel)); |
406 | clks[IMX7D_PLL_ENET_MAIN_SRC] = imx_clk_mux("pll_enet_main_src", base + 0xe0, 14, 2, pll_bypass_src_sel, ARRAY_SIZE(pll_bypass_src_sel)); | 417 | hws[IMX7D_PLL_ENET_MAIN_SRC] = imx_clk_hw_mux("pll_enet_main_src", base + 0xe0, 14, 2, pll_bypass_src_sel, ARRAY_SIZE(pll_bypass_src_sel)); |
407 | clks[IMX7D_PLL_AUDIO_MAIN_SRC] = imx_clk_mux("pll_audio_main_src", base + 0xf0, 14, 2, pll_bypass_src_sel, ARRAY_SIZE(pll_bypass_src_sel)); | 418 | hws[IMX7D_PLL_AUDIO_MAIN_SRC] = imx_clk_hw_mux("pll_audio_main_src", base + 0xf0, 14, 2, pll_bypass_src_sel, ARRAY_SIZE(pll_bypass_src_sel)); |
408 | clks[IMX7D_PLL_VIDEO_MAIN_SRC] = imx_clk_mux("pll_video_main_src", base + 0x130, 14, 2, pll_bypass_src_sel, ARRAY_SIZE(pll_bypass_src_sel)); | 419 | hws[IMX7D_PLL_VIDEO_MAIN_SRC] = imx_clk_hw_mux("pll_video_main_src", base + 0x130, 14, 2, pll_bypass_src_sel, ARRAY_SIZE(pll_bypass_src_sel)); |
409 | 420 | ||
410 | clks[IMX7D_PLL_ARM_MAIN] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll_arm_main", "osc", base + 0x60, 0x7f); | 421 | hws[IMX7D_PLL_ARM_MAIN] = imx_clk_hw_pllv3(IMX_PLLV3_SYS, "pll_arm_main", "osc", base + 0x60, 0x7f); |
411 | clks[IMX7D_PLL_DRAM_MAIN] = imx_clk_pllv3(IMX_PLLV3_DDR_IMX7, "pll_dram_main", "osc", base + 0x70, 0x7f); | 422 | hws[IMX7D_PLL_DRAM_MAIN] = imx_clk_hw_pllv3(IMX_PLLV3_DDR_IMX7, "pll_dram_main", "osc", base + 0x70, 0x7f); |
412 | clks[IMX7D_PLL_SYS_MAIN] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll_sys_main", "osc", base + 0xb0, 0x1); | 423 | hws[IMX7D_PLL_SYS_MAIN] = imx_clk_hw_pllv3(IMX_PLLV3_GENERIC, "pll_sys_main", "osc", base + 0xb0, 0x1); |
413 | clks[IMX7D_PLL_ENET_MAIN] = imx_clk_pllv3(IMX_PLLV3_ENET_IMX7, "pll_enet_main", "osc", base + 0xe0, 0x0); | 424 | hws[IMX7D_PLL_ENET_MAIN] = imx_clk_hw_pllv3(IMX_PLLV3_ENET_IMX7, "pll_enet_main", "osc", base + 0xe0, 0x0); |
414 | clks[IMX7D_PLL_AUDIO_MAIN] = imx_clk_pllv3(IMX_PLLV3_AV_IMX7, "pll_audio_main", "osc", base + 0xf0, 0x7f); | 425 | hws[IMX7D_PLL_AUDIO_MAIN] = imx_clk_hw_pllv3(IMX_PLLV3_AV_IMX7, "pll_audio_main", "osc", base + 0xf0, 0x7f); |
415 | clks[IMX7D_PLL_VIDEO_MAIN] = imx_clk_pllv3(IMX_PLLV3_AV_IMX7, "pll_video_main", "osc", base + 0x130, 0x7f); | 426 | hws[IMX7D_PLL_VIDEO_MAIN] = imx_clk_hw_pllv3(IMX_PLLV3_AV_IMX7, "pll_video_main", "osc", base + 0x130, 0x7f); |
416 | 427 | ||
417 | clks[IMX7D_PLL_ARM_MAIN_BYPASS] = imx_clk_mux_flags("pll_arm_main_bypass", base + 0x60, 16, 1, pll_arm_bypass_sel, ARRAY_SIZE(pll_arm_bypass_sel), CLK_SET_RATE_PARENT); | 428 | hws[IMX7D_PLL_ARM_MAIN_BYPASS] = imx_clk_hw_mux_flags("pll_arm_main_bypass", base + 0x60, 16, 1, pll_arm_bypass_sel, ARRAY_SIZE(pll_arm_bypass_sel), CLK_SET_RATE_PARENT); |
418 | clks[IMX7D_PLL_DRAM_MAIN_BYPASS] = imx_clk_mux_flags("pll_dram_main_bypass", base + 0x70, 16, 1, pll_dram_bypass_sel, ARRAY_SIZE(pll_dram_bypass_sel), CLK_SET_RATE_PARENT); | 429 | hws[IMX7D_PLL_DRAM_MAIN_BYPASS] = imx_clk_hw_mux_flags("pll_dram_main_bypass", base + 0x70, 16, 1, pll_dram_bypass_sel, ARRAY_SIZE(pll_dram_bypass_sel), CLK_SET_RATE_PARENT); |
419 | clks[IMX7D_PLL_SYS_MAIN_BYPASS] = imx_clk_mux_flags("pll_sys_main_bypass", base + 0xb0, 16, 1, pll_sys_bypass_sel, ARRAY_SIZE(pll_sys_bypass_sel), CLK_SET_RATE_PARENT); | 430 | hws[IMX7D_PLL_SYS_MAIN_BYPASS] = imx_clk_hw_mux_flags("pll_sys_main_bypass", base + 0xb0, 16, 1, pll_sys_bypass_sel, ARRAY_SIZE(pll_sys_bypass_sel), CLK_SET_RATE_PARENT); |
420 | clks[IMX7D_PLL_ENET_MAIN_BYPASS] = imx_clk_mux_flags("pll_enet_main_bypass", base + 0xe0, 16, 1, pll_enet_bypass_sel, ARRAY_SIZE(pll_enet_bypass_sel), CLK_SET_RATE_PARENT); | 431 | hws[IMX7D_PLL_ENET_MAIN_BYPASS] = imx_clk_hw_mux_flags("pll_enet_main_bypass", base + 0xe0, 16, 1, pll_enet_bypass_sel, ARRAY_SIZE(pll_enet_bypass_sel), CLK_SET_RATE_PARENT); |
421 | clks[IMX7D_PLL_AUDIO_MAIN_BYPASS] = imx_clk_mux_flags("pll_audio_main_bypass", base + 0xf0, 16, 1, pll_audio_bypass_sel, ARRAY_SIZE(pll_audio_bypass_sel), CLK_SET_RATE_PARENT); | 432 | hws[IMX7D_PLL_AUDIO_MAIN_BYPASS] = imx_clk_hw_mux_flags("pll_audio_main_bypass", base + 0xf0, 16, 1, pll_audio_bypass_sel, ARRAY_SIZE(pll_audio_bypass_sel), CLK_SET_RATE_PARENT); |
422 | clks[IMX7D_PLL_VIDEO_MAIN_BYPASS] = imx_clk_mux_flags("pll_video_main_bypass", base + 0x130, 16, 1, pll_video_bypass_sel, ARRAY_SIZE(pll_video_bypass_sel), CLK_SET_RATE_PARENT); | 433 | hws[IMX7D_PLL_VIDEO_MAIN_BYPASS] = imx_clk_hw_mux_flags("pll_video_main_bypass", base + 0x130, 16, 1, pll_video_bypass_sel, ARRAY_SIZE(pll_video_bypass_sel), CLK_SET_RATE_PARENT); |
423 | 434 | ||
424 | clks[IMX7D_PLL_ARM_MAIN_CLK] = imx_clk_gate("pll_arm_main_clk", "pll_arm_main_bypass", base + 0x60, 13); | 435 | hws[IMX7D_PLL_ARM_MAIN_CLK] = imx_clk_hw_gate("pll_arm_main_clk", "pll_arm_main_bypass", base + 0x60, 13); |
425 | clks[IMX7D_PLL_DRAM_MAIN_CLK] = imx_clk_gate("pll_dram_main_clk", "pll_dram_test_div", base + 0x70, 13); | 436 | hws[IMX7D_PLL_DRAM_MAIN_CLK] = imx_clk_hw_gate("pll_dram_main_clk", "pll_dram_test_div", base + 0x70, 13); |
426 | clks[IMX7D_PLL_SYS_MAIN_CLK] = imx_clk_gate("pll_sys_main_clk", "pll_sys_main_bypass", base + 0xb0, 13); | 437 | hws[IMX7D_PLL_SYS_MAIN_CLK] = imx_clk_hw_gate("pll_sys_main_clk", "pll_sys_main_bypass", base + 0xb0, 13); |
427 | clks[IMX7D_PLL_AUDIO_MAIN_CLK] = imx_clk_gate("pll_audio_main_clk", "pll_audio_main_bypass", base + 0xf0, 13); | 438 | hws[IMX7D_PLL_AUDIO_MAIN_CLK] = imx_clk_hw_gate("pll_audio_main_clk", "pll_audio_main_bypass", base + 0xf0, 13); |
428 | clks[IMX7D_PLL_VIDEO_MAIN_CLK] = imx_clk_gate("pll_video_main_clk", "pll_video_main_bypass", base + 0x130, 13); | 439 | hws[IMX7D_PLL_VIDEO_MAIN_CLK] = imx_clk_hw_gate("pll_video_main_clk", "pll_video_main_bypass", base + 0x130, 13); |
429 | 440 | ||
430 | clks[IMX7D_PLL_DRAM_TEST_DIV] = clk_register_divider_table(NULL, "pll_dram_test_div", "pll_dram_main_bypass", | 441 | hws[IMX7D_PLL_DRAM_TEST_DIV] = clk_hw_register_divider_table(NULL, "pll_dram_test_div", "pll_dram_main_bypass", |
431 | CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0x70, 21, 2, 0, test_div_table, &imx_ccm_lock); | 442 | CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0x70, 21, 2, 0, test_div_table, &imx_ccm_lock); |
432 | clks[IMX7D_PLL_AUDIO_TEST_DIV] = clk_register_divider_table(NULL, "pll_audio_test_div", "pll_audio_main_clk", | 443 | hws[IMX7D_PLL_AUDIO_TEST_DIV] = clk_hw_register_divider_table(NULL, "pll_audio_test_div", "pll_audio_main_clk", |
433 | CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0xf0, 19, 2, 0, test_div_table, &imx_ccm_lock); | 444 | CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0xf0, 19, 2, 0, test_div_table, &imx_ccm_lock); |
434 | clks[IMX7D_PLL_AUDIO_POST_DIV] = clk_register_divider_table(NULL, "pll_audio_post_div", "pll_audio_test_div", | 445 | hws[IMX7D_PLL_AUDIO_POST_DIV] = clk_hw_register_divider_table(NULL, "pll_audio_post_div", "pll_audio_test_div", |
435 | CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0xf0, 22, 2, 0, post_div_table, &imx_ccm_lock); | 446 | CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0xf0, 22, 2, 0, post_div_table, &imx_ccm_lock); |
436 | clks[IMX7D_PLL_VIDEO_TEST_DIV] = clk_register_divider_table(NULL, "pll_video_test_div", "pll_video_main_clk", | 447 | hws[IMX7D_PLL_VIDEO_TEST_DIV] = clk_hw_register_divider_table(NULL, "pll_video_test_div", "pll_video_main_clk", |
437 | CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0x130, 19, 2, 0, test_div_table, &imx_ccm_lock); | 448 | CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0x130, 19, 2, 0, test_div_table, &imx_ccm_lock); |
438 | clks[IMX7D_PLL_VIDEO_POST_DIV] = clk_register_divider_table(NULL, "pll_video_post_div", "pll_video_test_div", | 449 | hws[IMX7D_PLL_VIDEO_POST_DIV] = clk_hw_register_divider_table(NULL, "pll_video_post_div", "pll_video_test_div", |
439 | CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0x130, 22, 2, 0, post_div_table, &imx_ccm_lock); | 450 | CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0x130, 22, 2, 0, post_div_table, &imx_ccm_lock); |
440 | 451 | ||
441 | clks[IMX7D_PLL_SYS_PFD0_392M_CLK] = imx_clk_pfd("pll_sys_pfd0_392m_clk", "pll_sys_main_clk", base + 0xc0, 0); | 452 | hws[IMX7D_PLL_SYS_PFD0_392M_CLK] = imx_clk_hw_pfd("pll_sys_pfd0_392m_clk", "pll_sys_main_clk", base + 0xc0, 0); |
442 | clks[IMX7D_PLL_SYS_PFD1_332M_CLK] = imx_clk_pfd("pll_sys_pfd1_332m_clk", "pll_sys_main_clk", base + 0xc0, 1); | 453 | hws[IMX7D_PLL_SYS_PFD1_332M_CLK] = imx_clk_hw_pfd("pll_sys_pfd1_332m_clk", "pll_sys_main_clk", base + 0xc0, 1); |
443 | clks[IMX7D_PLL_SYS_PFD2_270M_CLK] = imx_clk_pfd("pll_sys_pfd2_270m_clk", "pll_sys_main_clk", base + 0xc0, 2); | 454 | hws[IMX7D_PLL_SYS_PFD2_270M_CLK] = imx_clk_hw_pfd("pll_sys_pfd2_270m_clk", "pll_sys_main_clk", base + 0xc0, 2); |
444 | 455 | ||
445 | clks[IMX7D_PLL_SYS_PFD3_CLK] = imx_clk_pfd("pll_sys_pfd3_clk", "pll_sys_main_clk", base + 0xc0, 3); | 456 | hws[IMX7D_PLL_SYS_PFD3_CLK] = imx_clk_hw_pfd("pll_sys_pfd3_clk", "pll_sys_main_clk", base + 0xc0, 3); |
446 | clks[IMX7D_PLL_SYS_PFD4_CLK] = imx_clk_pfd("pll_sys_pfd4_clk", "pll_sys_main_clk", base + 0xd0, 0); | 457 | hws[IMX7D_PLL_SYS_PFD4_CLK] = imx_clk_hw_pfd("pll_sys_pfd4_clk", "pll_sys_main_clk", base + 0xd0, 0); |
447 | clks[IMX7D_PLL_SYS_PFD5_CLK] = imx_clk_pfd("pll_sys_pfd5_clk", "pll_sys_main_clk", base + 0xd0, 1); | 458 | hws[IMX7D_PLL_SYS_PFD5_CLK] = imx_clk_hw_pfd("pll_sys_pfd5_clk", "pll_sys_main_clk", base + 0xd0, 1); |
448 | clks[IMX7D_PLL_SYS_PFD6_CLK] = imx_clk_pfd("pll_sys_pfd6_clk", "pll_sys_main_clk", base + 0xd0, 2); | 459 | hws[IMX7D_PLL_SYS_PFD6_CLK] = imx_clk_hw_pfd("pll_sys_pfd6_clk", "pll_sys_main_clk", base + 0xd0, 2); |
449 | clks[IMX7D_PLL_SYS_PFD7_CLK] = imx_clk_pfd("pll_sys_pfd7_clk", "pll_sys_main_clk", base + 0xd0, 3); | 460 | hws[IMX7D_PLL_SYS_PFD7_CLK] = imx_clk_hw_pfd("pll_sys_pfd7_clk", "pll_sys_main_clk", base + 0xd0, 3); |
450 | 461 | ||
451 | clks[IMX7D_PLL_SYS_MAIN_480M] = imx_clk_fixed_factor("pll_sys_main_480m", "pll_sys_main_clk", 1, 1); | 462 | hws[IMX7D_PLL_SYS_MAIN_480M] = imx_clk_hw_fixed_factor("pll_sys_main_480m", "pll_sys_main_clk", 1, 1); |
452 | clks[IMX7D_PLL_SYS_MAIN_240M] = imx_clk_fixed_factor("pll_sys_main_240m", "pll_sys_main_clk", 1, 2); | 463 | hws[IMX7D_PLL_SYS_MAIN_240M] = imx_clk_hw_fixed_factor("pll_sys_main_240m", "pll_sys_main_clk", 1, 2); |
453 | clks[IMX7D_PLL_SYS_MAIN_120M] = imx_clk_fixed_factor("pll_sys_main_120m", "pll_sys_main_clk", 1, 4); | 464 | hws[IMX7D_PLL_SYS_MAIN_120M] = imx_clk_hw_fixed_factor("pll_sys_main_120m", "pll_sys_main_clk", 1, 4); |
454 | clks[IMX7D_PLL_DRAM_MAIN_533M] = imx_clk_fixed_factor("pll_dram_533m", "pll_dram_main_clk", 1, 2); | 465 | hws[IMX7D_PLL_DRAM_MAIN_533M] = imx_clk_hw_fixed_factor("pll_dram_533m", "pll_dram_main_clk", 1, 2); |
455 | 466 | ||
456 | clks[IMX7D_PLL_SYS_MAIN_480M_CLK] = imx_clk_gate_dis_flags("pll_sys_main_480m_clk", "pll_sys_main_480m", base + 0xb0, 4, CLK_IS_CRITICAL); | 467 | hws[IMX7D_PLL_SYS_MAIN_480M_CLK] = imx_clk_hw_gate_dis_flags("pll_sys_main_480m_clk", "pll_sys_main_480m", base + 0xb0, 4, CLK_IS_CRITICAL); |
457 | clks[IMX7D_PLL_SYS_MAIN_240M_CLK] = imx_clk_gate_dis("pll_sys_main_240m_clk", "pll_sys_main_240m", base + 0xb0, 5); | 468 | hws[IMX7D_PLL_SYS_MAIN_240M_CLK] = imx_clk_hw_gate_dis("pll_sys_main_240m_clk", "pll_sys_main_240m", base + 0xb0, 5); |
458 | clks[IMX7D_PLL_SYS_MAIN_120M_CLK] = imx_clk_gate_dis("pll_sys_main_120m_clk", "pll_sys_main_120m", base + 0xb0, 6); | 469 | hws[IMX7D_PLL_SYS_MAIN_120M_CLK] = imx_clk_hw_gate_dis("pll_sys_main_120m_clk", "pll_sys_main_120m", base + 0xb0, 6); |
459 | clks[IMX7D_PLL_DRAM_MAIN_533M_CLK] = imx_clk_gate("pll_dram_533m_clk", "pll_dram_533m", base + 0x70, 12); | 470 | hws[IMX7D_PLL_DRAM_MAIN_533M_CLK] = imx_clk_hw_gate("pll_dram_533m_clk", "pll_dram_533m", base + 0x70, 12); |
460 | 471 | ||
461 | clks[IMX7D_PLL_SYS_PFD0_196M] = imx_clk_fixed_factor("pll_sys_pfd0_196m", "pll_sys_pfd0_392m_clk", 1, 2); | 472 | hws[IMX7D_PLL_SYS_PFD0_196M] = imx_clk_hw_fixed_factor("pll_sys_pfd0_196m", "pll_sys_pfd0_392m_clk", 1, 2); |
462 | clks[IMX7D_PLL_SYS_PFD1_166M] = imx_clk_fixed_factor("pll_sys_pfd1_166m", "pll_sys_pfd1_332m_clk", 1, 2); | 473 | hws[IMX7D_PLL_SYS_PFD1_166M] = imx_clk_hw_fixed_factor("pll_sys_pfd1_166m", "pll_sys_pfd1_332m_clk", 1, 2); |
463 | clks[IMX7D_PLL_SYS_PFD2_135M] = imx_clk_fixed_factor("pll_sys_pfd2_135m", "pll_sys_pfd2_270m_clk", 1, 2); | 474 | hws[IMX7D_PLL_SYS_PFD2_135M] = imx_clk_hw_fixed_factor("pll_sys_pfd2_135m", "pll_sys_pfd2_270m_clk", 1, 2); |
464 | 475 | ||
465 | clks[IMX7D_PLL_SYS_PFD0_196M_CLK] = imx_clk_gate_dis("pll_sys_pfd0_196m_clk", "pll_sys_pfd0_196m", base + 0xb0, 26); | 476 | hws[IMX7D_PLL_SYS_PFD0_196M_CLK] = imx_clk_hw_gate_dis("pll_sys_pfd0_196m_clk", "pll_sys_pfd0_196m", base + 0xb0, 26); |
466 | clks[IMX7D_PLL_SYS_PFD1_166M_CLK] = imx_clk_gate_dis("pll_sys_pfd1_166m_clk", "pll_sys_pfd1_166m", base + 0xb0, 27); | 477 | hws[IMX7D_PLL_SYS_PFD1_166M_CLK] = imx_clk_hw_gate_dis("pll_sys_pfd1_166m_clk", "pll_sys_pfd1_166m", base + 0xb0, 27); |
467 | clks[IMX7D_PLL_SYS_PFD2_135M_CLK] = imx_clk_gate_dis("pll_sys_pfd2_135m_clk", "pll_sys_pfd2_135m", base + 0xb0, 28); | 478 | hws[IMX7D_PLL_SYS_PFD2_135M_CLK] = imx_clk_hw_gate_dis("pll_sys_pfd2_135m_clk", "pll_sys_pfd2_135m", base + 0xb0, 28); |
468 | 479 | ||
469 | clks[IMX7D_PLL_ENET_MAIN_CLK] = imx_clk_fixed_factor("pll_enet_main_clk", "pll_enet_main_bypass", 1, 1); | 480 | hws[IMX7D_PLL_ENET_MAIN_CLK] = imx_clk_hw_fixed_factor("pll_enet_main_clk", "pll_enet_main_bypass", 1, 1); |
470 | clks[IMX7D_PLL_ENET_MAIN_500M] = imx_clk_fixed_factor("pll_enet_500m", "pll_enet_main_clk", 1, 2); | 481 | hws[IMX7D_PLL_ENET_MAIN_500M] = imx_clk_hw_fixed_factor("pll_enet_500m", "pll_enet_main_clk", 1, 2); |
471 | clks[IMX7D_PLL_ENET_MAIN_250M] = imx_clk_fixed_factor("pll_enet_250m", "pll_enet_main_clk", 1, 4); | 482 | hws[IMX7D_PLL_ENET_MAIN_250M] = imx_clk_hw_fixed_factor("pll_enet_250m", "pll_enet_main_clk", 1, 4); |
472 | clks[IMX7D_PLL_ENET_MAIN_125M] = imx_clk_fixed_factor("pll_enet_125m", "pll_enet_main_clk", 1, 8); | 483 | hws[IMX7D_PLL_ENET_MAIN_125M] = imx_clk_hw_fixed_factor("pll_enet_125m", "pll_enet_main_clk", 1, 8); |
473 | clks[IMX7D_PLL_ENET_MAIN_100M] = imx_clk_fixed_factor("pll_enet_100m", "pll_enet_main_clk", 1, 10); | 484 | hws[IMX7D_PLL_ENET_MAIN_100M] = imx_clk_hw_fixed_factor("pll_enet_100m", "pll_enet_main_clk", 1, 10); |
474 | clks[IMX7D_PLL_ENET_MAIN_50M] = imx_clk_fixed_factor("pll_enet_50m", "pll_enet_main_clk", 1, 20); | 485 | hws[IMX7D_PLL_ENET_MAIN_50M] = imx_clk_hw_fixed_factor("pll_enet_50m", "pll_enet_main_clk", 1, 20); |
475 | clks[IMX7D_PLL_ENET_MAIN_40M] = imx_clk_fixed_factor("pll_enet_40m", "pll_enet_main_clk", 1, 25); | 486 | hws[IMX7D_PLL_ENET_MAIN_40M] = imx_clk_hw_fixed_factor("pll_enet_40m", "pll_enet_main_clk", 1, 25); |
476 | clks[IMX7D_PLL_ENET_MAIN_25M] = imx_clk_fixed_factor("pll_enet_25m", "pll_enet_main_clk", 1, 40); | 487 | hws[IMX7D_PLL_ENET_MAIN_25M] = imx_clk_hw_fixed_factor("pll_enet_25m", "pll_enet_main_clk", 1, 40); |
477 | 488 | ||
478 | clks[IMX7D_PLL_ENET_MAIN_500M_CLK] = imx_clk_gate("pll_enet_500m_clk", "pll_enet_500m", base + 0xe0, 12); | 489 | hws[IMX7D_PLL_ENET_MAIN_500M_CLK] = imx_clk_hw_gate("pll_enet_500m_clk", "pll_enet_500m", base + 0xe0, 12); |
479 | clks[IMX7D_PLL_ENET_MAIN_250M_CLK] = imx_clk_gate("pll_enet_250m_clk", "pll_enet_250m", base + 0xe0, 11); | 490 | hws[IMX7D_PLL_ENET_MAIN_250M_CLK] = imx_clk_hw_gate("pll_enet_250m_clk", "pll_enet_250m", base + 0xe0, 11); |
480 | clks[IMX7D_PLL_ENET_MAIN_125M_CLK] = imx_clk_gate("pll_enet_125m_clk", "pll_enet_125m", base + 0xe0, 10); | 491 | hws[IMX7D_PLL_ENET_MAIN_125M_CLK] = imx_clk_hw_gate("pll_enet_125m_clk", "pll_enet_125m", base + 0xe0, 10); |
481 | clks[IMX7D_PLL_ENET_MAIN_100M_CLK] = imx_clk_gate("pll_enet_100m_clk", "pll_enet_100m", base + 0xe0, 9); | 492 | hws[IMX7D_PLL_ENET_MAIN_100M_CLK] = imx_clk_hw_gate("pll_enet_100m_clk", "pll_enet_100m", base + 0xe0, 9); |
482 | clks[IMX7D_PLL_ENET_MAIN_50M_CLK] = imx_clk_gate("pll_enet_50m_clk", "pll_enet_50m", base + 0xe0, 8); | 493 | hws[IMX7D_PLL_ENET_MAIN_50M_CLK] = imx_clk_hw_gate("pll_enet_50m_clk", "pll_enet_50m", base + 0xe0, 8); |
483 | clks[IMX7D_PLL_ENET_MAIN_40M_CLK] = imx_clk_gate("pll_enet_40m_clk", "pll_enet_40m", base + 0xe0, 7); | 494 | hws[IMX7D_PLL_ENET_MAIN_40M_CLK] = imx_clk_hw_gate("pll_enet_40m_clk", "pll_enet_40m", base + 0xe0, 7); |
484 | clks[IMX7D_PLL_ENET_MAIN_25M_CLK] = imx_clk_gate("pll_enet_25m_clk", "pll_enet_25m", base + 0xe0, 6); | 495 | hws[IMX7D_PLL_ENET_MAIN_25M_CLK] = imx_clk_hw_gate("pll_enet_25m_clk", "pll_enet_25m", base + 0xe0, 6); |
485 | 496 | ||
486 | clks[IMX7D_LVDS1_OUT_SEL] = imx_clk_mux("lvds1_sel", base + 0x170, 0, 5, lvds1_sel, ARRAY_SIZE(lvds1_sel)); | 497 | hws[IMX7D_LVDS1_OUT_SEL] = imx_clk_hw_mux("lvds1_sel", base + 0x170, 0, 5, lvds1_sel, ARRAY_SIZE(lvds1_sel)); |
487 | clks[IMX7D_LVDS1_OUT_CLK] = imx_clk_gate_exclusive("lvds1_out", "lvds1_sel", base + 0x170, 5, BIT(6)); | 498 | hws[IMX7D_LVDS1_OUT_CLK] = imx_clk_hw_gate_exclusive("lvds1_out", "lvds1_sel", base + 0x170, 5, BIT(6)); |
488 | 499 | ||
489 | np = ccm_node; | 500 | np = ccm_node; |
490 | base = of_iomap(np, 0); | 501 | base = of_iomap(np, 0); |
491 | WARN_ON(!base); | 502 | WARN_ON(!base); |
492 | 503 | ||
493 | clks[IMX7D_ARM_A7_ROOT_SRC] = imx_clk_mux2("arm_a7_src", base + 0x8000, 24, 3, arm_a7_sel, ARRAY_SIZE(arm_a7_sel)); | 504 | hws[IMX7D_ARM_A7_ROOT_SRC] = imx_clk_hw_mux2("arm_a7_src", base + 0x8000, 24, 3, arm_a7_sel, ARRAY_SIZE(arm_a7_sel)); |
494 | clks[IMX7D_ARM_M4_ROOT_SRC] = imx_clk_mux2("arm_m4_src", base + 0x8080, 24, 3, arm_m4_sel, ARRAY_SIZE(arm_m4_sel)); | 505 | hws[IMX7D_ARM_M4_ROOT_SRC] = imx_clk_hw_mux2("arm_m4_src", base + 0x8080, 24, 3, arm_m4_sel, ARRAY_SIZE(arm_m4_sel)); |
495 | clks[IMX7D_MAIN_AXI_ROOT_SRC] = imx_clk_mux2("axi_src", base + 0x8800, 24, 3, axi_sel, ARRAY_SIZE(axi_sel)); | 506 | hws[IMX7D_MAIN_AXI_ROOT_SRC] = imx_clk_hw_mux2("axi_src", base + 0x8800, 24, 3, axi_sel, ARRAY_SIZE(axi_sel)); |
496 | clks[IMX7D_DISP_AXI_ROOT_SRC] = imx_clk_mux2("disp_axi_src", base + 0x8880, 24, 3, disp_axi_sel, ARRAY_SIZE(disp_axi_sel)); | 507 | hws[IMX7D_DISP_AXI_ROOT_SRC] = imx_clk_hw_mux2("disp_axi_src", base + 0x8880, 24, 3, disp_axi_sel, ARRAY_SIZE(disp_axi_sel)); |
497 | clks[IMX7D_ENET_AXI_ROOT_SRC] = imx_clk_mux2("enet_axi_src", base + 0x8900, 24, 3, enet_axi_sel, ARRAY_SIZE(enet_axi_sel)); | 508 | hws[IMX7D_ENET_AXI_ROOT_SRC] = imx_clk_hw_mux2("enet_axi_src", base + 0x8900, 24, 3, enet_axi_sel, ARRAY_SIZE(enet_axi_sel)); |
498 | clks[IMX7D_NAND_USDHC_BUS_ROOT_SRC] = imx_clk_mux2("nand_usdhc_src", base + 0x8980, 24, 3, nand_usdhc_bus_sel, ARRAY_SIZE(nand_usdhc_bus_sel)); | 509 | hws[IMX7D_NAND_USDHC_BUS_ROOT_SRC] = imx_clk_hw_mux2("nand_usdhc_src", base + 0x8980, 24, 3, nand_usdhc_bus_sel, ARRAY_SIZE(nand_usdhc_bus_sel)); |
499 | clks[IMX7D_AHB_CHANNEL_ROOT_SRC] = imx_clk_mux2("ahb_src", base + 0x9000, 24, 3, ahb_channel_sel, ARRAY_SIZE(ahb_channel_sel)); | 510 | hws[IMX7D_AHB_CHANNEL_ROOT_SRC] = imx_clk_hw_mux2("ahb_src", base + 0x9000, 24, 3, ahb_channel_sel, ARRAY_SIZE(ahb_channel_sel)); |
500 | clks[IMX7D_DRAM_PHYM_ROOT_SRC] = imx_clk_mux2("dram_phym_src", base + 0x9800, 24, 1, dram_phym_sel, ARRAY_SIZE(dram_phym_sel)); | 511 | hws[IMX7D_DRAM_PHYM_ROOT_SRC] = imx_clk_hw_mux2("dram_phym_src", base + 0x9800, 24, 1, dram_phym_sel, ARRAY_SIZE(dram_phym_sel)); |
501 | clks[IMX7D_DRAM_ROOT_SRC] = imx_clk_mux2("dram_src", base + 0x9880, 24, 1, dram_sel, ARRAY_SIZE(dram_sel)); | 512 | hws[IMX7D_DRAM_ROOT_SRC] = imx_clk_hw_mux2("dram_src", base + 0x9880, 24, 1, dram_sel, ARRAY_SIZE(dram_sel)); |
502 | clks[IMX7D_DRAM_PHYM_ALT_ROOT_SRC] = imx_clk_mux2("dram_phym_alt_src", base + 0xa000, 24, 3, dram_phym_alt_sel, ARRAY_SIZE(dram_phym_alt_sel)); | 513 | hws[IMX7D_DRAM_PHYM_ALT_ROOT_SRC] = imx_clk_hw_mux2("dram_phym_alt_src", base + 0xa000, 24, 3, dram_phym_alt_sel, ARRAY_SIZE(dram_phym_alt_sel)); |
503 | clks[IMX7D_DRAM_ALT_ROOT_SRC] = imx_clk_mux2("dram_alt_src", base + 0xa080, 24, 3, dram_alt_sel, ARRAY_SIZE(dram_alt_sel)); | 514 | hws[IMX7D_DRAM_ALT_ROOT_SRC] = imx_clk_hw_mux2("dram_alt_src", base + 0xa080, 24, 3, dram_alt_sel, ARRAY_SIZE(dram_alt_sel)); |
504 | clks[IMX7D_USB_HSIC_ROOT_SRC] = imx_clk_mux2("usb_hsic_src", base + 0xa100, 24, 3, usb_hsic_sel, ARRAY_SIZE(usb_hsic_sel)); | 515 | hws[IMX7D_USB_HSIC_ROOT_SRC] = imx_clk_hw_mux2("usb_hsic_src", base + 0xa100, 24, 3, usb_hsic_sel, ARRAY_SIZE(usb_hsic_sel)); |
505 | clks[IMX7D_PCIE_CTRL_ROOT_SRC] = imx_clk_mux2("pcie_ctrl_src", base + 0xa180, 24, 3, pcie_ctrl_sel, ARRAY_SIZE(pcie_ctrl_sel)); | 516 | hws[IMX7D_PCIE_CTRL_ROOT_SRC] = imx_clk_hw_mux2("pcie_ctrl_src", base + 0xa180, 24, 3, pcie_ctrl_sel, ARRAY_SIZE(pcie_ctrl_sel)); |
506 | clks[IMX7D_PCIE_PHY_ROOT_SRC] = imx_clk_mux2("pcie_phy_src", base + 0xa200, 24, 3, pcie_phy_sel, ARRAY_SIZE(pcie_phy_sel)); | 517 | hws[IMX7D_PCIE_PHY_ROOT_SRC] = imx_clk_hw_mux2("pcie_phy_src", base + 0xa200, 24, 3, pcie_phy_sel, ARRAY_SIZE(pcie_phy_sel)); |
507 | clks[IMX7D_EPDC_PIXEL_ROOT_SRC] = imx_clk_mux2("epdc_pixel_src", base + 0xa280, 24, 3, epdc_pixel_sel, ARRAY_SIZE(epdc_pixel_sel)); | 518 | hws[IMX7D_EPDC_PIXEL_ROOT_SRC] = imx_clk_hw_mux2("epdc_pixel_src", base + 0xa280, 24, 3, epdc_pixel_sel, ARRAY_SIZE(epdc_pixel_sel)); |
508 | clks[IMX7D_LCDIF_PIXEL_ROOT_SRC] = imx_clk_mux2("lcdif_pixel_src", base + 0xa300, 24, 3, lcdif_pixel_sel, ARRAY_SIZE(lcdif_pixel_sel)); | 519 | hws[IMX7D_LCDIF_PIXEL_ROOT_SRC] = imx_clk_hw_mux2("lcdif_pixel_src", base + 0xa300, 24, 3, lcdif_pixel_sel, ARRAY_SIZE(lcdif_pixel_sel)); |
509 | clks[IMX7D_MIPI_DSI_ROOT_SRC] = imx_clk_mux2("mipi_dsi_src", base + 0xa380, 24, 3, mipi_dsi_sel, ARRAY_SIZE(mipi_dsi_sel)); | 520 | hws[IMX7D_MIPI_DSI_ROOT_SRC] = imx_clk_hw_mux2("mipi_dsi_src", base + 0xa380, 24, 3, mipi_dsi_sel, ARRAY_SIZE(mipi_dsi_sel)); |
510 | clks[IMX7D_MIPI_CSI_ROOT_SRC] = imx_clk_mux2("mipi_csi_src", base + 0xa400, 24, 3, mipi_csi_sel, ARRAY_SIZE(mipi_csi_sel)); | 521 | hws[IMX7D_MIPI_CSI_ROOT_SRC] = imx_clk_hw_mux2("mipi_csi_src", base + 0xa400, 24, 3, mipi_csi_sel, ARRAY_SIZE(mipi_csi_sel)); |
511 | clks[IMX7D_MIPI_DPHY_ROOT_SRC] = imx_clk_mux2("mipi_dphy_src", base + 0xa480, 24, 3, mipi_dphy_sel, ARRAY_SIZE(mipi_dphy_sel)); | 522 | hws[IMX7D_MIPI_DPHY_ROOT_SRC] = imx_clk_hw_mux2("mipi_dphy_src", base + 0xa480, 24, 3, mipi_dphy_sel, ARRAY_SIZE(mipi_dphy_sel)); |
512 | clks[IMX7D_SAI1_ROOT_SRC] = imx_clk_mux2("sai1_src", base + 0xa500, 24, 3, sai1_sel, ARRAY_SIZE(sai1_sel)); | 523 | hws[IMX7D_SAI1_ROOT_SRC] = imx_clk_hw_mux2("sai1_src", base + 0xa500, 24, 3, sai1_sel, ARRAY_SIZE(sai1_sel)); |
513 | clks[IMX7D_SAI2_ROOT_SRC] = imx_clk_mux2("sai2_src", base + 0xa580, 24, 3, sai2_sel, ARRAY_SIZE(sai2_sel)); | 524 | hws[IMX7D_SAI2_ROOT_SRC] = imx_clk_hw_mux2("sai2_src", base + 0xa580, 24, 3, sai2_sel, ARRAY_SIZE(sai2_sel)); |
514 | clks[IMX7D_SAI3_ROOT_SRC] = imx_clk_mux2("sai3_src", base + 0xa600, 24, 3, sai3_sel, ARRAY_SIZE(sai3_sel)); | 525 | hws[IMX7D_SAI3_ROOT_SRC] = imx_clk_hw_mux2("sai3_src", base + 0xa600, 24, 3, sai3_sel, ARRAY_SIZE(sai3_sel)); |
515 | clks[IMX7D_SPDIF_ROOT_SRC] = imx_clk_mux2("spdif_src", base + 0xa680, 24, 3, spdif_sel, ARRAY_SIZE(spdif_sel)); | 526 | hws[IMX7D_SPDIF_ROOT_SRC] = imx_clk_hw_mux2("spdif_src", base + 0xa680, 24, 3, spdif_sel, ARRAY_SIZE(spdif_sel)); |
516 | clks[IMX7D_ENET1_REF_ROOT_SRC] = imx_clk_mux2("enet1_ref_src", base + 0xa700, 24, 3, enet1_ref_sel, ARRAY_SIZE(enet1_ref_sel)); | 527 | hws[IMX7D_ENET1_REF_ROOT_SRC] = imx_clk_hw_mux2("enet1_ref_src", base + 0xa700, 24, 3, enet1_ref_sel, ARRAY_SIZE(enet1_ref_sel)); |
517 | clks[IMX7D_ENET1_TIME_ROOT_SRC] = imx_clk_mux2("enet1_time_src", base + 0xa780, 24, 3, enet1_time_sel, ARRAY_SIZE(enet1_time_sel)); | 528 | hws[IMX7D_ENET1_TIME_ROOT_SRC] = imx_clk_hw_mux2("enet1_time_src", base + 0xa780, 24, 3, enet1_time_sel, ARRAY_SIZE(enet1_time_sel)); |
518 | clks[IMX7D_ENET2_REF_ROOT_SRC] = imx_clk_mux2("enet2_ref_src", base + 0xa800, 24, 3, enet2_ref_sel, ARRAY_SIZE(enet2_ref_sel)); | 529 | hws[IMX7D_ENET2_REF_ROOT_SRC] = imx_clk_hw_mux2("enet2_ref_src", base + 0xa800, 24, 3, enet2_ref_sel, ARRAY_SIZE(enet2_ref_sel)); |
519 | clks[IMX7D_ENET2_TIME_ROOT_SRC] = imx_clk_mux2("enet2_time_src", base + 0xa880, 24, 3, enet2_time_sel, ARRAY_SIZE(enet2_time_sel)); | 530 | hws[IMX7D_ENET2_TIME_ROOT_SRC] = imx_clk_hw_mux2("enet2_time_src", base + 0xa880, 24, 3, enet2_time_sel, ARRAY_SIZE(enet2_time_sel)); |
520 | clks[IMX7D_ENET_PHY_REF_ROOT_SRC] = imx_clk_mux2("enet_phy_ref_src", base + 0xa900, 24, 3, enet_phy_ref_sel, ARRAY_SIZE(enet_phy_ref_sel)); | 531 | hws[IMX7D_ENET_PHY_REF_ROOT_SRC] = imx_clk_hw_mux2("enet_phy_ref_src", base + 0xa900, 24, 3, enet_phy_ref_sel, ARRAY_SIZE(enet_phy_ref_sel)); |
521 | clks[IMX7D_EIM_ROOT_SRC] = imx_clk_mux2("eim_src", base + 0xa980, 24, 3, eim_sel, ARRAY_SIZE(eim_sel)); | 532 | hws[IMX7D_EIM_ROOT_SRC] = imx_clk_hw_mux2("eim_src", base + 0xa980, 24, 3, eim_sel, ARRAY_SIZE(eim_sel)); |
522 | clks[IMX7D_NAND_ROOT_SRC] = imx_clk_mux2("nand_src", base + 0xaa00, 24, 3, nand_sel, ARRAY_SIZE(nand_sel)); | 533 | hws[IMX7D_NAND_ROOT_SRC] = imx_clk_hw_mux2("nand_src", base + 0xaa00, 24, 3, nand_sel, ARRAY_SIZE(nand_sel)); |
523 | clks[IMX7D_QSPI_ROOT_SRC] = imx_clk_mux2("qspi_src", base + 0xaa80, 24, 3, qspi_sel, ARRAY_SIZE(qspi_sel)); | 534 | hws[IMX7D_QSPI_ROOT_SRC] = imx_clk_hw_mux2("qspi_src", base + 0xaa80, 24, 3, qspi_sel, ARRAY_SIZE(qspi_sel)); |
524 | clks[IMX7D_USDHC1_ROOT_SRC] = imx_clk_mux2("usdhc1_src", base + 0xab00, 24, 3, usdhc1_sel, ARRAY_SIZE(usdhc1_sel)); | 535 | hws[IMX7D_USDHC1_ROOT_SRC] = imx_clk_hw_mux2("usdhc1_src", base + 0xab00, 24, 3, usdhc1_sel, ARRAY_SIZE(usdhc1_sel)); |
525 | clks[IMX7D_USDHC2_ROOT_SRC] = imx_clk_mux2("usdhc2_src", base + 0xab80, 24, 3, usdhc2_sel, ARRAY_SIZE(usdhc2_sel)); | 536 | hws[IMX7D_USDHC2_ROOT_SRC] = imx_clk_hw_mux2("usdhc2_src", base + 0xab80, 24, 3, usdhc2_sel, ARRAY_SIZE(usdhc2_sel)); |
526 | clks[IMX7D_USDHC3_ROOT_SRC] = imx_clk_mux2("usdhc3_src", base + 0xac00, 24, 3, usdhc3_sel, ARRAY_SIZE(usdhc3_sel)); | 537 | hws[IMX7D_USDHC3_ROOT_SRC] = imx_clk_hw_mux2("usdhc3_src", base + 0xac00, 24, 3, usdhc3_sel, ARRAY_SIZE(usdhc3_sel)); |
527 | clks[IMX7D_CAN1_ROOT_SRC] = imx_clk_mux2("can1_src", base + 0xac80, 24, 3, can1_sel, ARRAY_SIZE(can1_sel)); | 538 | hws[IMX7D_CAN1_ROOT_SRC] = imx_clk_hw_mux2("can1_src", base + 0xac80, 24, 3, can1_sel, ARRAY_SIZE(can1_sel)); |
528 | clks[IMX7D_CAN2_ROOT_SRC] = imx_clk_mux2("can2_src", base + 0xad00, 24, 3, can2_sel, ARRAY_SIZE(can2_sel)); | 539 | hws[IMX7D_CAN2_ROOT_SRC] = imx_clk_hw_mux2("can2_src", base + 0xad00, 24, 3, can2_sel, ARRAY_SIZE(can2_sel)); |
529 | clks[IMX7D_I2C1_ROOT_SRC] = imx_clk_mux2("i2c1_src", base + 0xad80, 24, 3, i2c1_sel, ARRAY_SIZE(i2c1_sel)); | 540 | hws[IMX7D_I2C1_ROOT_SRC] = imx_clk_hw_mux2("i2c1_src", base + 0xad80, 24, 3, i2c1_sel, ARRAY_SIZE(i2c1_sel)); |
530 | clks[IMX7D_I2C2_ROOT_SRC] = imx_clk_mux2("i2c2_src", base + 0xae00, 24, 3, i2c2_sel, ARRAY_SIZE(i2c2_sel)); | 541 | hws[IMX7D_I2C2_ROOT_SRC] = imx_clk_hw_mux2("i2c2_src", base + 0xae00, 24, 3, i2c2_sel, ARRAY_SIZE(i2c2_sel)); |
531 | clks[IMX7D_I2C3_ROOT_SRC] = imx_clk_mux2("i2c3_src", base + 0xae80, 24, 3, i2c3_sel, ARRAY_SIZE(i2c3_sel)); | 542 | hws[IMX7D_I2C3_ROOT_SRC] = imx_clk_hw_mux2("i2c3_src", base + 0xae80, 24, 3, i2c3_sel, ARRAY_SIZE(i2c3_sel)); |
532 | clks[IMX7D_I2C4_ROOT_SRC] = imx_clk_mux2("i2c4_src", base + 0xaf00, 24, 3, i2c4_sel, ARRAY_SIZE(i2c4_sel)); | 543 | hws[IMX7D_I2C4_ROOT_SRC] = imx_clk_hw_mux2("i2c4_src", base + 0xaf00, 24, 3, i2c4_sel, ARRAY_SIZE(i2c4_sel)); |
533 | clks[IMX7D_UART1_ROOT_SRC] = imx_clk_mux2("uart1_src", base + 0xaf80, 24, 3, uart1_sel, ARRAY_SIZE(uart1_sel)); | 544 | hws[IMX7D_UART1_ROOT_SRC] = imx_clk_hw_mux2("uart1_src", base + 0xaf80, 24, 3, uart1_sel, ARRAY_SIZE(uart1_sel)); |
534 | clks[IMX7D_UART2_ROOT_SRC] = imx_clk_mux2("uart2_src", base + 0xb000, 24, 3, uart2_sel, ARRAY_SIZE(uart2_sel)); | 545 | hws[IMX7D_UART2_ROOT_SRC] = imx_clk_hw_mux2("uart2_src", base + 0xb000, 24, 3, uart2_sel, ARRAY_SIZE(uart2_sel)); |
535 | clks[IMX7D_UART3_ROOT_SRC] = imx_clk_mux2("uart3_src", base + 0xb080, 24, 3, uart3_sel, ARRAY_SIZE(uart3_sel)); | 546 | hws[IMX7D_UART3_ROOT_SRC] = imx_clk_hw_mux2("uart3_src", base + 0xb080, 24, 3, uart3_sel, ARRAY_SIZE(uart3_sel)); |
536 | clks[IMX7D_UART4_ROOT_SRC] = imx_clk_mux2("uart4_src", base + 0xb100, 24, 3, uart4_sel, ARRAY_SIZE(uart4_sel)); | 547 | hws[IMX7D_UART4_ROOT_SRC] = imx_clk_hw_mux2("uart4_src", base + 0xb100, 24, 3, uart4_sel, ARRAY_SIZE(uart4_sel)); |
537 | clks[IMX7D_UART5_ROOT_SRC] = imx_clk_mux2("uart5_src", base + 0xb180, 24, 3, uart5_sel, ARRAY_SIZE(uart5_sel)); | 548 | hws[IMX7D_UART5_ROOT_SRC] = imx_clk_hw_mux2("uart5_src", base + 0xb180, 24, 3, uart5_sel, ARRAY_SIZE(uart5_sel)); |
538 | clks[IMX7D_UART6_ROOT_SRC] = imx_clk_mux2("uart6_src", base + 0xb200, 24, 3, uart6_sel, ARRAY_SIZE(uart6_sel)); | 549 | hws[IMX7D_UART6_ROOT_SRC] = imx_clk_hw_mux2("uart6_src", base + 0xb200, 24, 3, uart6_sel, ARRAY_SIZE(uart6_sel)); |
539 | clks[IMX7D_UART7_ROOT_SRC] = imx_clk_mux2("uart7_src", base + 0xb280, 24, 3, uart7_sel, ARRAY_SIZE(uart7_sel)); | 550 | hws[IMX7D_UART7_ROOT_SRC] = imx_clk_hw_mux2("uart7_src", base + 0xb280, 24, 3, uart7_sel, ARRAY_SIZE(uart7_sel)); |
540 | clks[IMX7D_ECSPI1_ROOT_SRC] = imx_clk_mux2("ecspi1_src", base + 0xb300, 24, 3, ecspi1_sel, ARRAY_SIZE(ecspi1_sel)); | 551 | hws[IMX7D_ECSPI1_ROOT_SRC] = imx_clk_hw_mux2("ecspi1_src", base + 0xb300, 24, 3, ecspi1_sel, ARRAY_SIZE(ecspi1_sel)); |
541 | clks[IMX7D_ECSPI2_ROOT_SRC] = imx_clk_mux2("ecspi2_src", base + 0xb380, 24, 3, ecspi2_sel, ARRAY_SIZE(ecspi2_sel)); | 552 | hws[IMX7D_ECSPI2_ROOT_SRC] = imx_clk_hw_mux2("ecspi2_src", base + 0xb380, 24, 3, ecspi2_sel, ARRAY_SIZE(ecspi2_sel)); |
542 | clks[IMX7D_ECSPI3_ROOT_SRC] = imx_clk_mux2("ecspi3_src", base + 0xb400, 24, 3, ecspi3_sel, ARRAY_SIZE(ecspi3_sel)); | 553 | hws[IMX7D_ECSPI3_ROOT_SRC] = imx_clk_hw_mux2("ecspi3_src", base + 0xb400, 24, 3, ecspi3_sel, ARRAY_SIZE(ecspi3_sel)); |
543 | clks[IMX7D_ECSPI4_ROOT_SRC] = imx_clk_mux2("ecspi4_src", base + 0xb480, 24, 3, ecspi4_sel, ARRAY_SIZE(ecspi4_sel)); | 554 | hws[IMX7D_ECSPI4_ROOT_SRC] = imx_clk_hw_mux2("ecspi4_src", base + 0xb480, 24, 3, ecspi4_sel, ARRAY_SIZE(ecspi4_sel)); |
544 | clks[IMX7D_PWM1_ROOT_SRC] = imx_clk_mux2("pwm1_src", base + 0xb500, 24, 3, pwm1_sel, ARRAY_SIZE(pwm1_sel)); | 555 | hws[IMX7D_PWM1_ROOT_SRC] = imx_clk_hw_mux2("pwm1_src", base + 0xb500, 24, 3, pwm1_sel, ARRAY_SIZE(pwm1_sel)); |
545 | clks[IMX7D_PWM2_ROOT_SRC] = imx_clk_mux2("pwm2_src", base + 0xb580, 24, 3, pwm2_sel, ARRAY_SIZE(pwm2_sel)); | 556 | hws[IMX7D_PWM2_ROOT_SRC] = imx_clk_hw_mux2("pwm2_src", base + 0xb580, 24, 3, pwm2_sel, ARRAY_SIZE(pwm2_sel)); |
546 | clks[IMX7D_PWM3_ROOT_SRC] = imx_clk_mux2("pwm3_src", base + 0xb600, 24, 3, pwm3_sel, ARRAY_SIZE(pwm3_sel)); | 557 | hws[IMX7D_PWM3_ROOT_SRC] = imx_clk_hw_mux2("pwm3_src", base + 0xb600, 24, 3, pwm3_sel, ARRAY_SIZE(pwm3_sel)); |
547 | clks[IMX7D_PWM4_ROOT_SRC] = imx_clk_mux2("pwm4_src", base + 0xb680, 24, 3, pwm4_sel, ARRAY_SIZE(pwm4_sel)); | 558 | hws[IMX7D_PWM4_ROOT_SRC] = imx_clk_hw_mux2("pwm4_src", base + 0xb680, 24, 3, pwm4_sel, ARRAY_SIZE(pwm4_sel)); |
548 | clks[IMX7D_FLEXTIMER1_ROOT_SRC] = imx_clk_mux2("flextimer1_src", base + 0xb700, 24, 3, flextimer1_sel, ARRAY_SIZE(flextimer1_sel)); | 559 | hws[IMX7D_FLEXTIMER1_ROOT_SRC] = imx_clk_hw_mux2("flextimer1_src", base + 0xb700, 24, 3, flextimer1_sel, ARRAY_SIZE(flextimer1_sel)); |
549 | clks[IMX7D_FLEXTIMER2_ROOT_SRC] = imx_clk_mux2("flextimer2_src", base + 0xb780, 24, 3, flextimer2_sel, ARRAY_SIZE(flextimer2_sel)); | 560 | hws[IMX7D_FLEXTIMER2_ROOT_SRC] = imx_clk_hw_mux2("flextimer2_src", base + 0xb780, 24, 3, flextimer2_sel, ARRAY_SIZE(flextimer2_sel)); |
550 | clks[IMX7D_SIM1_ROOT_SRC] = imx_clk_mux2("sim1_src", base + 0xb800, 24, 3, sim1_sel, ARRAY_SIZE(sim1_sel)); | 561 | hws[IMX7D_SIM1_ROOT_SRC] = imx_clk_hw_mux2("sim1_src", base + 0xb800, 24, 3, sim1_sel, ARRAY_SIZE(sim1_sel)); |
551 | clks[IMX7D_SIM2_ROOT_SRC] = imx_clk_mux2("sim2_src", base + 0xb880, 24, 3, sim2_sel, ARRAY_SIZE(sim2_sel)); | 562 | hws[IMX7D_SIM2_ROOT_SRC] = imx_clk_hw_mux2("sim2_src", base + 0xb880, 24, 3, sim2_sel, ARRAY_SIZE(sim2_sel)); |
552 | clks[IMX7D_GPT1_ROOT_SRC] = imx_clk_mux2("gpt1_src", base + 0xb900, 24, 3, gpt1_sel, ARRAY_SIZE(gpt1_sel)); | 563 | hws[IMX7D_GPT1_ROOT_SRC] = imx_clk_hw_mux2("gpt1_src", base + 0xb900, 24, 3, gpt1_sel, ARRAY_SIZE(gpt1_sel)); |
553 | clks[IMX7D_GPT2_ROOT_SRC] = imx_clk_mux2("gpt2_src", base + 0xb980, 24, 3, gpt2_sel, ARRAY_SIZE(gpt2_sel)); | 564 | hws[IMX7D_GPT2_ROOT_SRC] = imx_clk_hw_mux2("gpt2_src", base + 0xb980, 24, 3, gpt2_sel, ARRAY_SIZE(gpt2_sel)); |
554 | clks[IMX7D_GPT3_ROOT_SRC] = imx_clk_mux2("gpt3_src", base + 0xba00, 24, 3, gpt3_sel, ARRAY_SIZE(gpt3_sel)); | 565 | hws[IMX7D_GPT3_ROOT_SRC] = imx_clk_hw_mux2("gpt3_src", base + 0xba00, 24, 3, gpt3_sel, ARRAY_SIZE(gpt3_sel)); |
555 | clks[IMX7D_GPT4_ROOT_SRC] = imx_clk_mux2("gpt4_src", base + 0xba80, 24, 3, gpt4_sel, ARRAY_SIZE(gpt4_sel)); | 566 | hws[IMX7D_GPT4_ROOT_SRC] = imx_clk_hw_mux2("gpt4_src", base + 0xba80, 24, 3, gpt4_sel, ARRAY_SIZE(gpt4_sel)); |
556 | clks[IMX7D_TRACE_ROOT_SRC] = imx_clk_mux2("trace_src", base + 0xbb00, 24, 3, trace_sel, ARRAY_SIZE(trace_sel)); | 567 | hws[IMX7D_TRACE_ROOT_SRC] = imx_clk_hw_mux2("trace_src", base + 0xbb00, 24, 3, trace_sel, ARRAY_SIZE(trace_sel)); |
557 | clks[IMX7D_WDOG_ROOT_SRC] = imx_clk_mux2("wdog_src", base + 0xbb80, 24, 3, wdog_sel, ARRAY_SIZE(wdog_sel)); | 568 | hws[IMX7D_WDOG_ROOT_SRC] = imx_clk_hw_mux2("wdog_src", base + 0xbb80, 24, 3, wdog_sel, ARRAY_SIZE(wdog_sel)); |
558 | clks[IMX7D_CSI_MCLK_ROOT_SRC] = imx_clk_mux2("csi_mclk_src", base + 0xbc00, 24, 3, csi_mclk_sel, ARRAY_SIZE(csi_mclk_sel)); | 569 | hws[IMX7D_CSI_MCLK_ROOT_SRC] = imx_clk_hw_mux2("csi_mclk_src", base + 0xbc00, 24, 3, csi_mclk_sel, ARRAY_SIZE(csi_mclk_sel)); |
559 | clks[IMX7D_AUDIO_MCLK_ROOT_SRC] = imx_clk_mux2("audio_mclk_src", base + 0xbc80, 24, 3, audio_mclk_sel, ARRAY_SIZE(audio_mclk_sel)); | 570 | hws[IMX7D_AUDIO_MCLK_ROOT_SRC] = imx_clk_hw_mux2("audio_mclk_src", base + 0xbc80, 24, 3, audio_mclk_sel, ARRAY_SIZE(audio_mclk_sel)); |
560 | clks[IMX7D_WRCLK_ROOT_SRC] = imx_clk_mux2("wrclk_src", base + 0xbd00, 24, 3, wrclk_sel, ARRAY_SIZE(wrclk_sel)); | 571 | hws[IMX7D_WRCLK_ROOT_SRC] = imx_clk_hw_mux2("wrclk_src", base + 0xbd00, 24, 3, wrclk_sel, ARRAY_SIZE(wrclk_sel)); |
561 | clks[IMX7D_CLKO1_ROOT_SRC] = imx_clk_mux2("clko1_src", base + 0xbd80, 24, 3, clko1_sel, ARRAY_SIZE(clko1_sel)); | 572 | hws[IMX7D_CLKO1_ROOT_SRC] = imx_clk_hw_mux2("clko1_src", base + 0xbd80, 24, 3, clko1_sel, ARRAY_SIZE(clko1_sel)); |
562 | clks[IMX7D_CLKO2_ROOT_SRC] = imx_clk_mux2("clko2_src", base + 0xbe00, 24, 3, clko2_sel, ARRAY_SIZE(clko2_sel)); | 573 | hws[IMX7D_CLKO2_ROOT_SRC] = imx_clk_hw_mux2("clko2_src", base + 0xbe00, 24, 3, clko2_sel, ARRAY_SIZE(clko2_sel)); |
563 | 574 | ||
564 | clks[IMX7D_ARM_A7_ROOT_CG] = imx_clk_gate3("arm_a7_cg", "arm_a7_src", base + 0x8000, 28); | 575 | hws[IMX7D_ARM_A7_ROOT_CG] = imx_clk_hw_gate3("arm_a7_cg", "arm_a7_src", base + 0x8000, 28); |
565 | clks[IMX7D_ARM_M4_ROOT_CG] = imx_clk_gate3("arm_m4_cg", "arm_m4_src", base + 0x8080, 28); | 576 | hws[IMX7D_ARM_M4_ROOT_CG] = imx_clk_hw_gate3("arm_m4_cg", "arm_m4_src", base + 0x8080, 28); |
566 | clks[IMX7D_MAIN_AXI_ROOT_CG] = imx_clk_gate3("axi_cg", "axi_src", base + 0x8800, 28); | 577 | hws[IMX7D_MAIN_AXI_ROOT_CG] = imx_clk_hw_gate3("axi_cg", "axi_src", base + 0x8800, 28); |
567 | clks[IMX7D_DISP_AXI_ROOT_CG] = imx_clk_gate3("disp_axi_cg", "disp_axi_src", base + 0x8880, 28); | 578 | hws[IMX7D_DISP_AXI_ROOT_CG] = imx_clk_hw_gate3("disp_axi_cg", "disp_axi_src", base + 0x8880, 28); |
568 | clks[IMX7D_ENET_AXI_ROOT_CG] = imx_clk_gate3("enet_axi_cg", "enet_axi_src", base + 0x8900, 28); | 579 | hws[IMX7D_ENET_AXI_ROOT_CG] = imx_clk_hw_gate3("enet_axi_cg", "enet_axi_src", base + 0x8900, 28); |
569 | clks[IMX7D_NAND_USDHC_BUS_ROOT_CG] = imx_clk_gate3("nand_usdhc_cg", "nand_usdhc_src", base + 0x8980, 28); | 580 | hws[IMX7D_NAND_USDHC_BUS_ROOT_CG] = imx_clk_hw_gate3("nand_usdhc_cg", "nand_usdhc_src", base + 0x8980, 28); |
570 | clks[IMX7D_AHB_CHANNEL_ROOT_CG] = imx_clk_gate3("ahb_cg", "ahb_src", base + 0x9000, 28); | 581 | hws[IMX7D_AHB_CHANNEL_ROOT_CG] = imx_clk_hw_gate3("ahb_cg", "ahb_src", base + 0x9000, 28); |
571 | clks[IMX7D_DRAM_PHYM_ROOT_CG] = imx_clk_gate3("dram_phym_cg", "dram_phym_src", base + 0x9800, 28); | 582 | hws[IMX7D_DRAM_PHYM_ROOT_CG] = imx_clk_hw_gate3("dram_phym_cg", "dram_phym_src", base + 0x9800, 28); |
572 | clks[IMX7D_DRAM_ROOT_CG] = imx_clk_gate3("dram_cg", "dram_src", base + 0x9880, 28); | 583 | hws[IMX7D_DRAM_ROOT_CG] = imx_clk_hw_gate3("dram_cg", "dram_src", base + 0x9880, 28); |
573 | clks[IMX7D_DRAM_PHYM_ALT_ROOT_CG] = imx_clk_gate3("dram_phym_alt_cg", "dram_phym_alt_src", base + 0xa000, 28); | 584 | hws[IMX7D_DRAM_PHYM_ALT_ROOT_CG] = imx_clk_hw_gate3("dram_phym_alt_cg", "dram_phym_alt_src", base + 0xa000, 28); |
574 | clks[IMX7D_DRAM_ALT_ROOT_CG] = imx_clk_gate3("dram_alt_cg", "dram_alt_src", base + 0xa080, 28); | 585 | hws[IMX7D_DRAM_ALT_ROOT_CG] = imx_clk_hw_gate3("dram_alt_cg", "dram_alt_src", base + 0xa080, 28); |
575 | clks[IMX7D_USB_HSIC_ROOT_CG] = imx_clk_gate3("usb_hsic_cg", "usb_hsic_src", base + 0xa100, 28); | 586 | hws[IMX7D_USB_HSIC_ROOT_CG] = imx_clk_hw_gate3("usb_hsic_cg", "usb_hsic_src", base + 0xa100, 28); |
576 | clks[IMX7D_PCIE_CTRL_ROOT_CG] = imx_clk_gate3("pcie_ctrl_cg", "pcie_ctrl_src", base + 0xa180, 28); | 587 | hws[IMX7D_PCIE_CTRL_ROOT_CG] = imx_clk_hw_gate3("pcie_ctrl_cg", "pcie_ctrl_src", base + 0xa180, 28); |
577 | clks[IMX7D_PCIE_PHY_ROOT_CG] = imx_clk_gate3("pcie_phy_cg", "pcie_phy_src", base + 0xa200, 28); | 588 | hws[IMX7D_PCIE_PHY_ROOT_CG] = imx_clk_hw_gate3("pcie_phy_cg", "pcie_phy_src", base + 0xa200, 28); |
578 | clks[IMX7D_EPDC_PIXEL_ROOT_CG] = imx_clk_gate3("epdc_pixel_cg", "epdc_pixel_src", base + 0xa280, 28); | 589 | hws[IMX7D_EPDC_PIXEL_ROOT_CG] = imx_clk_hw_gate3("epdc_pixel_cg", "epdc_pixel_src", base + 0xa280, 28); |
579 | clks[IMX7D_LCDIF_PIXEL_ROOT_CG] = imx_clk_gate3("lcdif_pixel_cg", "lcdif_pixel_src", base + 0xa300, 28); | 590 | hws[IMX7D_LCDIF_PIXEL_ROOT_CG] = imx_clk_hw_gate3("lcdif_pixel_cg", "lcdif_pixel_src", base + 0xa300, 28); |
580 | clks[IMX7D_MIPI_DSI_ROOT_CG] = imx_clk_gate3("mipi_dsi_cg", "mipi_dsi_src", base + 0xa380, 28); | 591 | hws[IMX7D_MIPI_DSI_ROOT_CG] = imx_clk_hw_gate3("mipi_dsi_cg", "mipi_dsi_src", base + 0xa380, 28); |
581 | clks[IMX7D_MIPI_CSI_ROOT_CG] = imx_clk_gate3("mipi_csi_cg", "mipi_csi_src", base + 0xa400, 28); | 592 | hws[IMX7D_MIPI_CSI_ROOT_CG] = imx_clk_hw_gate3("mipi_csi_cg", "mipi_csi_src", base + 0xa400, 28); |
582 | clks[IMX7D_MIPI_DPHY_ROOT_CG] = imx_clk_gate3("mipi_dphy_cg", "mipi_dphy_src", base + 0xa480, 28); | 593 | hws[IMX7D_MIPI_DPHY_ROOT_CG] = imx_clk_hw_gate3("mipi_dphy_cg", "mipi_dphy_src", base + 0xa480, 28); |
583 | clks[IMX7D_SAI1_ROOT_CG] = imx_clk_gate3("sai1_cg", "sai1_src", base + 0xa500, 28); | 594 | hws[IMX7D_SAI1_ROOT_CG] = imx_clk_hw_gate3("sai1_cg", "sai1_src", base + 0xa500, 28); |
584 | clks[IMX7D_SAI2_ROOT_CG] = imx_clk_gate3("sai2_cg", "sai2_src", base + 0xa580, 28); | 595 | hws[IMX7D_SAI2_ROOT_CG] = imx_clk_hw_gate3("sai2_cg", "sai2_src", base + 0xa580, 28); |
585 | clks[IMX7D_SAI3_ROOT_CG] = imx_clk_gate3("sai3_cg", "sai3_src", base + 0xa600, 28); | 596 | hws[IMX7D_SAI3_ROOT_CG] = imx_clk_hw_gate3("sai3_cg", "sai3_src", base + 0xa600, 28); |
586 | clks[IMX7D_SPDIF_ROOT_CG] = imx_clk_gate3("spdif_cg", "spdif_src", base + 0xa680, 28); | 597 | hws[IMX7D_SPDIF_ROOT_CG] = imx_clk_hw_gate3("spdif_cg", "spdif_src", base + 0xa680, 28); |
587 | clks[IMX7D_ENET1_REF_ROOT_CG] = imx_clk_gate3("enet1_ref_cg", "enet1_ref_src", base + 0xa700, 28); | 598 | hws[IMX7D_ENET1_REF_ROOT_CG] = imx_clk_hw_gate3("enet1_ref_cg", "enet1_ref_src", base + 0xa700, 28); |
588 | clks[IMX7D_ENET1_TIME_ROOT_CG] = imx_clk_gate3("enet1_time_cg", "enet1_time_src", base + 0xa780, 28); | 599 | hws[IMX7D_ENET1_TIME_ROOT_CG] = imx_clk_hw_gate3("enet1_time_cg", "enet1_time_src", base + 0xa780, 28); |
589 | clks[IMX7D_ENET2_REF_ROOT_CG] = imx_clk_gate3("enet2_ref_cg", "enet2_ref_src", base + 0xa800, 28); | 600 | hws[IMX7D_ENET2_REF_ROOT_CG] = imx_clk_hw_gate3("enet2_ref_cg", "enet2_ref_src", base + 0xa800, 28); |
590 | clks[IMX7D_ENET2_TIME_ROOT_CG] = imx_clk_gate3("enet2_time_cg", "enet2_time_src", base + 0xa880, 28); | 601 | hws[IMX7D_ENET2_TIME_ROOT_CG] = imx_clk_hw_gate3("enet2_time_cg", "enet2_time_src", base + 0xa880, 28); |
591 | clks[IMX7D_ENET_PHY_REF_ROOT_CG] = imx_clk_gate3("enet_phy_ref_cg", "enet_phy_ref_src", base + 0xa900, 28); | 602 | hws[IMX7D_ENET_PHY_REF_ROOT_CG] = imx_clk_hw_gate3("enet_phy_ref_cg", "enet_phy_ref_src", base + 0xa900, 28); |
592 | clks[IMX7D_EIM_ROOT_CG] = imx_clk_gate3("eim_cg", "eim_src", base + 0xa980, 28); | 603 | hws[IMX7D_EIM_ROOT_CG] = imx_clk_hw_gate3("eim_cg", "eim_src", base + 0xa980, 28); |
593 | clks[IMX7D_NAND_ROOT_CG] = imx_clk_gate3("nand_cg", "nand_src", base + 0xaa00, 28); | 604 | hws[IMX7D_NAND_ROOT_CG] = imx_clk_hw_gate3("nand_cg", "nand_src", base + 0xaa00, 28); |
594 | clks[IMX7D_QSPI_ROOT_CG] = imx_clk_gate3("qspi_cg", "qspi_src", base + 0xaa80, 28); | 605 | hws[IMX7D_QSPI_ROOT_CG] = imx_clk_hw_gate3("qspi_cg", "qspi_src", base + 0xaa80, 28); |
595 | clks[IMX7D_USDHC1_ROOT_CG] = imx_clk_gate3("usdhc1_cg", "usdhc1_src", base + 0xab00, 28); | 606 | hws[IMX7D_USDHC1_ROOT_CG] = imx_clk_hw_gate3("usdhc1_cg", "usdhc1_src", base + 0xab00, 28); |
596 | clks[IMX7D_USDHC2_ROOT_CG] = imx_clk_gate3("usdhc2_cg", "usdhc2_src", base + 0xab80, 28); | 607 | hws[IMX7D_USDHC2_ROOT_CG] = imx_clk_hw_gate3("usdhc2_cg", "usdhc2_src", base + 0xab80, 28); |
597 | clks[IMX7D_USDHC3_ROOT_CG] = imx_clk_gate3("usdhc3_cg", "usdhc3_src", base + 0xac00, 28); | 608 | hws[IMX7D_USDHC3_ROOT_CG] = imx_clk_hw_gate3("usdhc3_cg", "usdhc3_src", base + 0xac00, 28); |
598 | clks[IMX7D_CAN1_ROOT_CG] = imx_clk_gate3("can1_cg", "can1_src", base + 0xac80, 28); | 609 | hws[IMX7D_CAN1_ROOT_CG] = imx_clk_hw_gate3("can1_cg", "can1_src", base + 0xac80, 28); |
599 | clks[IMX7D_CAN2_ROOT_CG] = imx_clk_gate3("can2_cg", "can2_src", base + 0xad00, 28); | 610 | hws[IMX7D_CAN2_ROOT_CG] = imx_clk_hw_gate3("can2_cg", "can2_src", base + 0xad00, 28); |
600 | clks[IMX7D_I2C1_ROOT_CG] = imx_clk_gate3("i2c1_cg", "i2c1_src", base + 0xad80, 28); | 611 | hws[IMX7D_I2C1_ROOT_CG] = imx_clk_hw_gate3("i2c1_cg", "i2c1_src", base + 0xad80, 28); |
601 | clks[IMX7D_I2C2_ROOT_CG] = imx_clk_gate3("i2c2_cg", "i2c2_src", base + 0xae00, 28); | 612 | hws[IMX7D_I2C2_ROOT_CG] = imx_clk_hw_gate3("i2c2_cg", "i2c2_src", base + 0xae00, 28); |
602 | clks[IMX7D_I2C3_ROOT_CG] = imx_clk_gate3("i2c3_cg", "i2c3_src", base + 0xae80, 28); | 613 | hws[IMX7D_I2C3_ROOT_CG] = imx_clk_hw_gate3("i2c3_cg", "i2c3_src", base + 0xae80, 28); |
603 | clks[IMX7D_I2C4_ROOT_CG] = imx_clk_gate3("i2c4_cg", "i2c4_src", base + 0xaf00, 28); | 614 | hws[IMX7D_I2C4_ROOT_CG] = imx_clk_hw_gate3("i2c4_cg", "i2c4_src", base + 0xaf00, 28); |
604 | clks[IMX7D_UART1_ROOT_CG] = imx_clk_gate3("uart1_cg", "uart1_src", base + 0xaf80, 28); | 615 | hws[IMX7D_UART1_ROOT_CG] = imx_clk_hw_gate3("uart1_cg", "uart1_src", base + 0xaf80, 28); |
605 | clks[IMX7D_UART2_ROOT_CG] = imx_clk_gate3("uart2_cg", "uart2_src", base + 0xb000, 28); | 616 | hws[IMX7D_UART2_ROOT_CG] = imx_clk_hw_gate3("uart2_cg", "uart2_src", base + 0xb000, 28); |
606 | clks[IMX7D_UART3_ROOT_CG] = imx_clk_gate3("uart3_cg", "uart3_src", base + 0xb080, 28); | 617 | hws[IMX7D_UART3_ROOT_CG] = imx_clk_hw_gate3("uart3_cg", "uart3_src", base + 0xb080, 28); |
607 | clks[IMX7D_UART4_ROOT_CG] = imx_clk_gate3("uart4_cg", "uart4_src", base + 0xb100, 28); | 618 | hws[IMX7D_UART4_ROOT_CG] = imx_clk_hw_gate3("uart4_cg", "uart4_src", base + 0xb100, 28); |
608 | clks[IMX7D_UART5_ROOT_CG] = imx_clk_gate3("uart5_cg", "uart5_src", base + 0xb180, 28); | 619 | hws[IMX7D_UART5_ROOT_CG] = imx_clk_hw_gate3("uart5_cg", "uart5_src", base + 0xb180, 28); |
609 | clks[IMX7D_UART6_ROOT_CG] = imx_clk_gate3("uart6_cg", "uart6_src", base + 0xb200, 28); | 620 | hws[IMX7D_UART6_ROOT_CG] = imx_clk_hw_gate3("uart6_cg", "uart6_src", base + 0xb200, 28); |
610 | clks[IMX7D_UART7_ROOT_CG] = imx_clk_gate3("uart7_cg", "uart7_src", base + 0xb280, 28); | 621 | hws[IMX7D_UART7_ROOT_CG] = imx_clk_hw_gate3("uart7_cg", "uart7_src", base + 0xb280, 28); |
611 | clks[IMX7D_ECSPI1_ROOT_CG] = imx_clk_gate3("ecspi1_cg", "ecspi1_src", base + 0xb300, 28); | 622 | hws[IMX7D_ECSPI1_ROOT_CG] = imx_clk_hw_gate3("ecspi1_cg", "ecspi1_src", base + 0xb300, 28); |
612 | clks[IMX7D_ECSPI2_ROOT_CG] = imx_clk_gate3("ecspi2_cg", "ecspi2_src", base + 0xb380, 28); | 623 | hws[IMX7D_ECSPI2_ROOT_CG] = imx_clk_hw_gate3("ecspi2_cg", "ecspi2_src", base + 0xb380, 28); |
613 | clks[IMX7D_ECSPI3_ROOT_CG] = imx_clk_gate3("ecspi3_cg", "ecspi3_src", base + 0xb400, 28); | 624 | hws[IMX7D_ECSPI3_ROOT_CG] = imx_clk_hw_gate3("ecspi3_cg", "ecspi3_src", base + 0xb400, 28); |
614 | clks[IMX7D_ECSPI4_ROOT_CG] = imx_clk_gate3("ecspi4_cg", "ecspi4_src", base + 0xb480, 28); | 625 | hws[IMX7D_ECSPI4_ROOT_CG] = imx_clk_hw_gate3("ecspi4_cg", "ecspi4_src", base + 0xb480, 28); |
615 | clks[IMX7D_PWM1_ROOT_CG] = imx_clk_gate3("pwm1_cg", "pwm1_src", base + 0xb500, 28); | 626 | hws[IMX7D_PWM1_ROOT_CG] = imx_clk_hw_gate3("pwm1_cg", "pwm1_src", base + 0xb500, 28); |
616 | clks[IMX7D_PWM2_ROOT_CG] = imx_clk_gate3("pwm2_cg", "pwm2_src", base + 0xb580, 28); | 627 | hws[IMX7D_PWM2_ROOT_CG] = imx_clk_hw_gate3("pwm2_cg", "pwm2_src", base + 0xb580, 28); |
617 | clks[IMX7D_PWM3_ROOT_CG] = imx_clk_gate3("pwm3_cg", "pwm3_src", base + 0xb600, 28); | 628 | hws[IMX7D_PWM3_ROOT_CG] = imx_clk_hw_gate3("pwm3_cg", "pwm3_src", base + 0xb600, 28); |
618 | clks[IMX7D_PWM4_ROOT_CG] = imx_clk_gate3("pwm4_cg", "pwm4_src", base + 0xb680, 28); | 629 | hws[IMX7D_PWM4_ROOT_CG] = imx_clk_hw_gate3("pwm4_cg", "pwm4_src", base + 0xb680, 28); |
619 | clks[IMX7D_FLEXTIMER1_ROOT_CG] = imx_clk_gate3("flextimer1_cg", "flextimer1_src", base + 0xb700, 28); | 630 | hws[IMX7D_FLEXTIMER1_ROOT_CG] = imx_clk_hw_gate3("flextimer1_cg", "flextimer1_src", base + 0xb700, 28); |
620 | clks[IMX7D_FLEXTIMER2_ROOT_CG] = imx_clk_gate3("flextimer2_cg", "flextimer2_src", base + 0xb780, 28); | 631 | hws[IMX7D_FLEXTIMER2_ROOT_CG] = imx_clk_hw_gate3("flextimer2_cg", "flextimer2_src", base + 0xb780, 28); |
621 | clks[IMX7D_SIM1_ROOT_CG] = imx_clk_gate3("sim1_cg", "sim1_src", base + 0xb800, 28); | 632 | hws[IMX7D_SIM1_ROOT_CG] = imx_clk_hw_gate3("sim1_cg", "sim1_src", base + 0xb800, 28); |
622 | clks[IMX7D_SIM2_ROOT_CG] = imx_clk_gate3("sim2_cg", "sim2_src", base + 0xb880, 28); | 633 | hws[IMX7D_SIM2_ROOT_CG] = imx_clk_hw_gate3("sim2_cg", "sim2_src", base + 0xb880, 28); |
623 | clks[IMX7D_GPT1_ROOT_CG] = imx_clk_gate3("gpt1_cg", "gpt1_src", base + 0xb900, 28); | 634 | hws[IMX7D_GPT1_ROOT_CG] = imx_clk_hw_gate3("gpt1_cg", "gpt1_src", base + 0xb900, 28); |
624 | clks[IMX7D_GPT2_ROOT_CG] = imx_clk_gate3("gpt2_cg", "gpt2_src", base + 0xb980, 28); | 635 | hws[IMX7D_GPT2_ROOT_CG] = imx_clk_hw_gate3("gpt2_cg", "gpt2_src", base + 0xb980, 28); |
625 | clks[IMX7D_GPT3_ROOT_CG] = imx_clk_gate3("gpt3_cg", "gpt3_src", base + 0xbA00, 28); | 636 | hws[IMX7D_GPT3_ROOT_CG] = imx_clk_hw_gate3("gpt3_cg", "gpt3_src", base + 0xbA00, 28); |
626 | clks[IMX7D_GPT4_ROOT_CG] = imx_clk_gate3("gpt4_cg", "gpt4_src", base + 0xbA80, 28); | 637 | hws[IMX7D_GPT4_ROOT_CG] = imx_clk_hw_gate3("gpt4_cg", "gpt4_src", base + 0xbA80, 28); |
627 | clks[IMX7D_TRACE_ROOT_CG] = imx_clk_gate3("trace_cg", "trace_src", base + 0xbb00, 28); | 638 | hws[IMX7D_TRACE_ROOT_CG] = imx_clk_hw_gate3("trace_cg", "trace_src", base + 0xbb00, 28); |
628 | clks[IMX7D_WDOG_ROOT_CG] = imx_clk_gate3("wdog_cg", "wdog_src", base + 0xbb80, 28); | 639 | hws[IMX7D_WDOG_ROOT_CG] = imx_clk_hw_gate3("wdog_cg", "wdog_src", base + 0xbb80, 28); |
629 | clks[IMX7D_CSI_MCLK_ROOT_CG] = imx_clk_gate3("csi_mclk_cg", "csi_mclk_src", base + 0xbc00, 28); | 640 | hws[IMX7D_CSI_MCLK_ROOT_CG] = imx_clk_hw_gate3("csi_mclk_cg", "csi_mclk_src", base + 0xbc00, 28); |
630 | clks[IMX7D_AUDIO_MCLK_ROOT_CG] = imx_clk_gate3("audio_mclk_cg", "audio_mclk_src", base + 0xbc80, 28); | 641 | hws[IMX7D_AUDIO_MCLK_ROOT_CG] = imx_clk_hw_gate3("audio_mclk_cg", "audio_mclk_src", base + 0xbc80, 28); |
631 | clks[IMX7D_WRCLK_ROOT_CG] = imx_clk_gate3("wrclk_cg", "wrclk_src", base + 0xbd00, 28); | 642 | hws[IMX7D_WRCLK_ROOT_CG] = imx_clk_hw_gate3("wrclk_cg", "wrclk_src", base + 0xbd00, 28); |
632 | clks[IMX7D_CLKO1_ROOT_CG] = imx_clk_gate3("clko1_cg", "clko1_src", base + 0xbd80, 28); | 643 | hws[IMX7D_CLKO1_ROOT_CG] = imx_clk_hw_gate3("clko1_cg", "clko1_src", base + 0xbd80, 28); |
633 | clks[IMX7D_CLKO2_ROOT_CG] = imx_clk_gate3("clko2_cg", "clko2_src", base + 0xbe00, 28); | 644 | hws[IMX7D_CLKO2_ROOT_CG] = imx_clk_hw_gate3("clko2_cg", "clko2_src", base + 0xbe00, 28); |
634 | 645 | ||
635 | clks[IMX7D_MAIN_AXI_ROOT_PRE_DIV] = imx_clk_divider2("axi_pre_div", "axi_cg", base + 0x8800, 16, 3); | 646 | hws[IMX7D_MAIN_AXI_ROOT_PRE_DIV] = imx_clk_hw_divider2("axi_pre_div", "axi_cg", base + 0x8800, 16, 3); |
636 | clks[IMX7D_DISP_AXI_ROOT_PRE_DIV] = imx_clk_divider2("disp_axi_pre_div", "disp_axi_cg", base + 0x8880, 16, 3); | 647 | hws[IMX7D_DISP_AXI_ROOT_PRE_DIV] = imx_clk_hw_divider2("disp_axi_pre_div", "disp_axi_cg", base + 0x8880, 16, 3); |
637 | clks[IMX7D_ENET_AXI_ROOT_PRE_DIV] = imx_clk_divider2("enet_axi_pre_div", "enet_axi_cg", base + 0x8900, 16, 3); | 648 | hws[IMX7D_ENET_AXI_ROOT_PRE_DIV] = imx_clk_hw_divider2("enet_axi_pre_div", "enet_axi_cg", base + 0x8900, 16, 3); |
638 | clks[IMX7D_NAND_USDHC_BUS_ROOT_PRE_DIV] = imx_clk_divider2("nand_usdhc_pre_div", "nand_usdhc_cg", base + 0x8980, 16, 3); | 649 | hws[IMX7D_NAND_USDHC_BUS_ROOT_PRE_DIV] = imx_clk_hw_divider2("nand_usdhc_pre_div", "nand_usdhc_cg", base + 0x8980, 16, 3); |
639 | clks[IMX7D_AHB_CHANNEL_ROOT_PRE_DIV] = imx_clk_divider2("ahb_pre_div", "ahb_cg", base + 0x9000, 16, 3); | 650 | hws[IMX7D_AHB_CHANNEL_ROOT_PRE_DIV] = imx_clk_hw_divider2("ahb_pre_div", "ahb_cg", base + 0x9000, 16, 3); |
640 | clks[IMX7D_DRAM_PHYM_ALT_ROOT_PRE_DIV] = imx_clk_divider2("dram_phym_alt_pre_div", "dram_phym_alt_cg", base + 0xa000, 16, 3); | 651 | hws[IMX7D_DRAM_PHYM_ALT_ROOT_PRE_DIV] = imx_clk_hw_divider2("dram_phym_alt_pre_div", "dram_phym_alt_cg", base + 0xa000, 16, 3); |
641 | clks[IMX7D_DRAM_ALT_ROOT_PRE_DIV] = imx_clk_divider2("dram_alt_pre_div", "dram_alt_cg", base + 0xa080, 16, 3); | 652 | hws[IMX7D_DRAM_ALT_ROOT_PRE_DIV] = imx_clk_hw_divider2("dram_alt_pre_div", "dram_alt_cg", base + 0xa080, 16, 3); |
642 | clks[IMX7D_USB_HSIC_ROOT_PRE_DIV] = imx_clk_divider2("usb_hsic_pre_div", "usb_hsic_cg", base + 0xa100, 16, 3); | 653 | hws[IMX7D_USB_HSIC_ROOT_PRE_DIV] = imx_clk_hw_divider2("usb_hsic_pre_div", "usb_hsic_cg", base + 0xa100, 16, 3); |
643 | clks[IMX7D_PCIE_CTRL_ROOT_PRE_DIV] = imx_clk_divider2("pcie_ctrl_pre_div", "pcie_ctrl_cg", base + 0xa180, 16, 3); | 654 | hws[IMX7D_PCIE_CTRL_ROOT_PRE_DIV] = imx_clk_hw_divider2("pcie_ctrl_pre_div", "pcie_ctrl_cg", base + 0xa180, 16, 3); |
644 | clks[IMX7D_PCIE_PHY_ROOT_PRE_DIV] = imx_clk_divider2("pcie_phy_pre_div", "pcie_phy_cg", base + 0xa200, 16, 3); | 655 | hws[IMX7D_PCIE_PHY_ROOT_PRE_DIV] = imx_clk_hw_divider2("pcie_phy_pre_div", "pcie_phy_cg", base + 0xa200, 16, 3); |
645 | clks[IMX7D_EPDC_PIXEL_ROOT_PRE_DIV] = imx_clk_divider2("epdc_pixel_pre_div", "epdc_pixel_cg", base + 0xa280, 16, 3); | 656 | hws[IMX7D_EPDC_PIXEL_ROOT_PRE_DIV] = imx_clk_hw_divider2("epdc_pixel_pre_div", "epdc_pixel_cg", base + 0xa280, 16, 3); |
646 | clks[IMX7D_LCDIF_PIXEL_ROOT_PRE_DIV] = imx_clk_divider2("lcdif_pixel_pre_div", "lcdif_pixel_cg", base + 0xa300, 16, 3); | 657 | hws[IMX7D_LCDIF_PIXEL_ROOT_PRE_DIV] = imx_clk_hw_divider2("lcdif_pixel_pre_div", "lcdif_pixel_cg", base + 0xa300, 16, 3); |
647 | clks[IMX7D_MIPI_DSI_ROOT_PRE_DIV] = imx_clk_divider2("mipi_dsi_pre_div", "mipi_dsi_cg", base + 0xa380, 16, 3); | 658 | hws[IMX7D_MIPI_DSI_ROOT_PRE_DIV] = imx_clk_hw_divider2("mipi_dsi_pre_div", "mipi_dsi_cg", base + 0xa380, 16, 3); |
648 | clks[IMX7D_MIPI_CSI_ROOT_PRE_DIV] = imx_clk_divider2("mipi_csi_pre_div", "mipi_csi_cg", base + 0xa400, 16, 3); | 659 | hws[IMX7D_MIPI_CSI_ROOT_PRE_DIV] = imx_clk_hw_divider2("mipi_csi_pre_div", "mipi_csi_cg", base + 0xa400, 16, 3); |
649 | clks[IMX7D_MIPI_DPHY_ROOT_PRE_DIV] = imx_clk_divider2("mipi_dphy_pre_div", "mipi_dphy_cg", base + 0xa480, 16, 3); | 660 | hws[IMX7D_MIPI_DPHY_ROOT_PRE_DIV] = imx_clk_hw_divider2("mipi_dphy_pre_div", "mipi_dphy_cg", base + 0xa480, 16, 3); |
650 | clks[IMX7D_SAI1_ROOT_PRE_DIV] = imx_clk_divider2("sai1_pre_div", "sai1_cg", base + 0xa500, 16, 3); | 661 | hws[IMX7D_SAI1_ROOT_PRE_DIV] = imx_clk_hw_divider2("sai1_pre_div", "sai1_cg", base + 0xa500, 16, 3); |
651 | clks[IMX7D_SAI2_ROOT_PRE_DIV] = imx_clk_divider2("sai2_pre_div", "sai2_cg", base + 0xa580, 16, 3); | 662 | hws[IMX7D_SAI2_ROOT_PRE_DIV] = imx_clk_hw_divider2("sai2_pre_div", "sai2_cg", base + 0xa580, 16, 3); |
652 | clks[IMX7D_SAI3_ROOT_PRE_DIV] = imx_clk_divider2("sai3_pre_div", "sai3_cg", base + 0xa600, 16, 3); | 663 | hws[IMX7D_SAI3_ROOT_PRE_DIV] = imx_clk_hw_divider2("sai3_pre_div", "sai3_cg", base + 0xa600, 16, 3); |
653 | clks[IMX7D_SPDIF_ROOT_PRE_DIV] = imx_clk_divider2("spdif_pre_div", "spdif_cg", base + 0xa680, 16, 3); | 664 | hws[IMX7D_SPDIF_ROOT_PRE_DIV] = imx_clk_hw_divider2("spdif_pre_div", "spdif_cg", base + 0xa680, 16, 3); |
654 | clks[IMX7D_ENET1_REF_ROOT_PRE_DIV] = imx_clk_divider2("enet1_ref_pre_div", "enet1_ref_cg", base + 0xa700, 16, 3); | 665 | hws[IMX7D_ENET1_REF_ROOT_PRE_DIV] = imx_clk_hw_divider2("enet1_ref_pre_div", "enet1_ref_cg", base + 0xa700, 16, 3); |
655 | clks[IMX7D_ENET1_TIME_ROOT_PRE_DIV] = imx_clk_divider2("enet1_time_pre_div", "enet1_time_cg", base + 0xa780, 16, 3); | 666 | hws[IMX7D_ENET1_TIME_ROOT_PRE_DIV] = imx_clk_hw_divider2("enet1_time_pre_div", "enet1_time_cg", base + 0xa780, 16, 3); |
656 | clks[IMX7D_ENET2_REF_ROOT_PRE_DIV] = imx_clk_divider2("enet2_ref_pre_div", "enet2_ref_cg", base + 0xa800, 16, 3); | 667 | hws[IMX7D_ENET2_REF_ROOT_PRE_DIV] = imx_clk_hw_divider2("enet2_ref_pre_div", "enet2_ref_cg", base + 0xa800, 16, 3); |
657 | clks[IMX7D_ENET2_TIME_ROOT_PRE_DIV] = imx_clk_divider2("enet2_time_pre_div", "enet2_time_cg", base + 0xa880, 16, 3); | 668 | hws[IMX7D_ENET2_TIME_ROOT_PRE_DIV] = imx_clk_hw_divider2("enet2_time_pre_div", "enet2_time_cg", base + 0xa880, 16, 3); |
658 | clks[IMX7D_ENET_PHY_REF_ROOT_PRE_DIV] = imx_clk_divider2("enet_phy_ref_pre_div", "enet_phy_ref_cg", base + 0xa900, 16, 3); | 669 | hws[IMX7D_ENET_PHY_REF_ROOT_PRE_DIV] = imx_clk_hw_divider2("enet_phy_ref_pre_div", "enet_phy_ref_cg", base + 0xa900, 16, 3); |
659 | clks[IMX7D_EIM_ROOT_PRE_DIV] = imx_clk_divider2("eim_pre_div", "eim_cg", base + 0xa980, 16, 3); | 670 | hws[IMX7D_EIM_ROOT_PRE_DIV] = imx_clk_hw_divider2("eim_pre_div", "eim_cg", base + 0xa980, 16, 3); |
660 | clks[IMX7D_NAND_ROOT_PRE_DIV] = imx_clk_divider2("nand_pre_div", "nand_cg", base + 0xaa00, 16, 3); | 671 | hws[IMX7D_NAND_ROOT_PRE_DIV] = imx_clk_hw_divider2("nand_pre_div", "nand_cg", base + 0xaa00, 16, 3); |
661 | clks[IMX7D_QSPI_ROOT_PRE_DIV] = imx_clk_divider2("qspi_pre_div", "qspi_cg", base + 0xaa80, 16, 3); | 672 | hws[IMX7D_QSPI_ROOT_PRE_DIV] = imx_clk_hw_divider2("qspi_pre_div", "qspi_cg", base + 0xaa80, 16, 3); |
662 | clks[IMX7D_USDHC1_ROOT_PRE_DIV] = imx_clk_divider2("usdhc1_pre_div", "usdhc1_cg", base + 0xab00, 16, 3); | 673 | hws[IMX7D_USDHC1_ROOT_PRE_DIV] = imx_clk_hw_divider2("usdhc1_pre_div", "usdhc1_cg", base + 0xab00, 16, 3); |
663 | clks[IMX7D_USDHC2_ROOT_PRE_DIV] = imx_clk_divider2("usdhc2_pre_div", "usdhc2_cg", base + 0xab80, 16, 3); | 674 | hws[IMX7D_USDHC2_ROOT_PRE_DIV] = imx_clk_hw_divider2("usdhc2_pre_div", "usdhc2_cg", base + 0xab80, 16, 3); |
664 | clks[IMX7D_USDHC3_ROOT_PRE_DIV] = imx_clk_divider2("usdhc3_pre_div", "usdhc3_cg", base + 0xac00, 16, 3); | 675 | hws[IMX7D_USDHC3_ROOT_PRE_DIV] = imx_clk_hw_divider2("usdhc3_pre_div", "usdhc3_cg", base + 0xac00, 16, 3); |
665 | clks[IMX7D_CAN1_ROOT_PRE_DIV] = imx_clk_divider2("can1_pre_div", "can1_cg", base + 0xac80, 16, 3); | 676 | hws[IMX7D_CAN1_ROOT_PRE_DIV] = imx_clk_hw_divider2("can1_pre_div", "can1_cg", base + 0xac80, 16, 3); |
666 | clks[IMX7D_CAN2_ROOT_PRE_DIV] = imx_clk_divider2("can2_pre_div", "can2_cg", base + 0xad00, 16, 3); | 677 | hws[IMX7D_CAN2_ROOT_PRE_DIV] = imx_clk_hw_divider2("can2_pre_div", "can2_cg", base + 0xad00, 16, 3); |
667 | clks[IMX7D_I2C1_ROOT_PRE_DIV] = imx_clk_divider2("i2c1_pre_div", "i2c1_cg", base + 0xad80, 16, 3); | 678 | hws[IMX7D_I2C1_ROOT_PRE_DIV] = imx_clk_hw_divider2("i2c1_pre_div", "i2c1_cg", base + 0xad80, 16, 3); |
668 | clks[IMX7D_I2C2_ROOT_PRE_DIV] = imx_clk_divider2("i2c2_pre_div", "i2c2_cg", base + 0xae00, 16, 3); | 679 | hws[IMX7D_I2C2_ROOT_PRE_DIV] = imx_clk_hw_divider2("i2c2_pre_div", "i2c2_cg", base + 0xae00, 16, 3); |
669 | clks[IMX7D_I2C3_ROOT_PRE_DIV] = imx_clk_divider2("i2c3_pre_div", "i2c3_cg", base + 0xae80, 16, 3); | 680 | hws[IMX7D_I2C3_ROOT_PRE_DIV] = imx_clk_hw_divider2("i2c3_pre_div", "i2c3_cg", base + 0xae80, 16, 3); |
670 | clks[IMX7D_I2C4_ROOT_PRE_DIV] = imx_clk_divider2("i2c4_pre_div", "i2c4_cg", base + 0xaf00, 16, 3); | 681 | hws[IMX7D_I2C4_ROOT_PRE_DIV] = imx_clk_hw_divider2("i2c4_pre_div", "i2c4_cg", base + 0xaf00, 16, 3); |
671 | clks[IMX7D_UART1_ROOT_PRE_DIV] = imx_clk_divider2("uart1_pre_div", "uart1_cg", base + 0xaf80, 16, 3); | 682 | hws[IMX7D_UART1_ROOT_PRE_DIV] = imx_clk_hw_divider2("uart1_pre_div", "uart1_cg", base + 0xaf80, 16, 3); |
672 | clks[IMX7D_UART2_ROOT_PRE_DIV] = imx_clk_divider2("uart2_pre_div", "uart2_cg", base + 0xb000, 16, 3); | 683 | hws[IMX7D_UART2_ROOT_PRE_DIV] = imx_clk_hw_divider2("uart2_pre_div", "uart2_cg", base + 0xb000, 16, 3); |
673 | clks[IMX7D_UART3_ROOT_PRE_DIV] = imx_clk_divider2("uart3_pre_div", "uart3_cg", base + 0xb080, 16, 3); | 684 | hws[IMX7D_UART3_ROOT_PRE_DIV] = imx_clk_hw_divider2("uart3_pre_div", "uart3_cg", base + 0xb080, 16, 3); |
674 | clks[IMX7D_UART4_ROOT_PRE_DIV] = imx_clk_divider2("uart4_pre_div", "uart4_cg", base + 0xb100, 16, 3); | 685 | hws[IMX7D_UART4_ROOT_PRE_DIV] = imx_clk_hw_divider2("uart4_pre_div", "uart4_cg", base + 0xb100, 16, 3); |
675 | clks[IMX7D_UART5_ROOT_PRE_DIV] = imx_clk_divider2("uart5_pre_div", "uart5_cg", base + 0xb180, 16, 3); | 686 | hws[IMX7D_UART5_ROOT_PRE_DIV] = imx_clk_hw_divider2("uart5_pre_div", "uart5_cg", base + 0xb180, 16, 3); |
676 | clks[IMX7D_UART6_ROOT_PRE_DIV] = imx_clk_divider2("uart6_pre_div", "uart6_cg", base + 0xb200, 16, 3); | 687 | hws[IMX7D_UART6_ROOT_PRE_DIV] = imx_clk_hw_divider2("uart6_pre_div", "uart6_cg", base + 0xb200, 16, 3); |
677 | clks[IMX7D_UART7_ROOT_PRE_DIV] = imx_clk_divider2("uart7_pre_div", "uart7_cg", base + 0xb280, 16, 3); | 688 | hws[IMX7D_UART7_ROOT_PRE_DIV] = imx_clk_hw_divider2("uart7_pre_div", "uart7_cg", base + 0xb280, 16, 3); |
678 | clks[IMX7D_ECSPI1_ROOT_PRE_DIV] = imx_clk_divider2("ecspi1_pre_div", "ecspi1_cg", base + 0xb300, 16, 3); | 689 | hws[IMX7D_ECSPI1_ROOT_PRE_DIV] = imx_clk_hw_divider2("ecspi1_pre_div", "ecspi1_cg", base + 0xb300, 16, 3); |
679 | clks[IMX7D_ECSPI2_ROOT_PRE_DIV] = imx_clk_divider2("ecspi2_pre_div", "ecspi2_cg", base + 0xb380, 16, 3); | 690 | hws[IMX7D_ECSPI2_ROOT_PRE_DIV] = imx_clk_hw_divider2("ecspi2_pre_div", "ecspi2_cg", base + 0xb380, 16, 3); |
680 | clks[IMX7D_ECSPI3_ROOT_PRE_DIV] = imx_clk_divider2("ecspi3_pre_div", "ecspi3_cg", base + 0xb400, 16, 3); | 691 | hws[IMX7D_ECSPI3_ROOT_PRE_DIV] = imx_clk_hw_divider2("ecspi3_pre_div", "ecspi3_cg", base + 0xb400, 16, 3); |
681 | clks[IMX7D_ECSPI4_ROOT_PRE_DIV] = imx_clk_divider2("ecspi4_pre_div", "ecspi4_cg", base + 0xb480, 16, 3); | 692 | hws[IMX7D_ECSPI4_ROOT_PRE_DIV] = imx_clk_hw_divider2("ecspi4_pre_div", "ecspi4_cg", base + 0xb480, 16, 3); |
682 | clks[IMX7D_PWM1_ROOT_PRE_DIV] = imx_clk_divider2("pwm1_pre_div", "pwm1_cg", base + 0xb500, 16, 3); | 693 | hws[IMX7D_PWM1_ROOT_PRE_DIV] = imx_clk_hw_divider2("pwm1_pre_div", "pwm1_cg", base + 0xb500, 16, 3); |
683 | clks[IMX7D_PWM2_ROOT_PRE_DIV] = imx_clk_divider2("pwm2_pre_div", "pwm2_cg", base + 0xb580, 16, 3); | 694 | hws[IMX7D_PWM2_ROOT_PRE_DIV] = imx_clk_hw_divider2("pwm2_pre_div", "pwm2_cg", base + 0xb580, 16, 3); |
684 | clks[IMX7D_PWM3_ROOT_PRE_DIV] = imx_clk_divider2("pwm3_pre_div", "pwm3_cg", base + 0xb600, 16, 3); | 695 | hws[IMX7D_PWM3_ROOT_PRE_DIV] = imx_clk_hw_divider2("pwm3_pre_div", "pwm3_cg", base + 0xb600, 16, 3); |
685 | clks[IMX7D_PWM4_ROOT_PRE_DIV] = imx_clk_divider2("pwm4_pre_div", "pwm4_cg", base + 0xb680, 16, 3); | 696 | hws[IMX7D_PWM4_ROOT_PRE_DIV] = imx_clk_hw_divider2("pwm4_pre_div", "pwm4_cg", base + 0xb680, 16, 3); |
686 | clks[IMX7D_FLEXTIMER1_ROOT_PRE_DIV] = imx_clk_divider2("flextimer1_pre_div", "flextimer1_cg", base + 0xb700, 16, 3); | 697 | hws[IMX7D_FLEXTIMER1_ROOT_PRE_DIV] = imx_clk_hw_divider2("flextimer1_pre_div", "flextimer1_cg", base + 0xb700, 16, 3); |
687 | clks[IMX7D_FLEXTIMER2_ROOT_PRE_DIV] = imx_clk_divider2("flextimer2_pre_div", "flextimer2_cg", base + 0xb780, 16, 3); | 698 | hws[IMX7D_FLEXTIMER2_ROOT_PRE_DIV] = imx_clk_hw_divider2("flextimer2_pre_div", "flextimer2_cg", base + 0xb780, 16, 3); |
688 | clks[IMX7D_SIM1_ROOT_PRE_DIV] = imx_clk_divider2("sim1_pre_div", "sim1_cg", base + 0xb800, 16, 3); | 699 | hws[IMX7D_SIM1_ROOT_PRE_DIV] = imx_clk_hw_divider2("sim1_pre_div", "sim1_cg", base + 0xb800, 16, 3); |
689 | clks[IMX7D_SIM2_ROOT_PRE_DIV] = imx_clk_divider2("sim2_pre_div", "sim2_cg", base + 0xb880, 16, 3); | 700 | hws[IMX7D_SIM2_ROOT_PRE_DIV] = imx_clk_hw_divider2("sim2_pre_div", "sim2_cg", base + 0xb880, 16, 3); |
690 | clks[IMX7D_GPT1_ROOT_PRE_DIV] = imx_clk_divider2("gpt1_pre_div", "gpt1_cg", base + 0xb900, 16, 3); | 701 | hws[IMX7D_GPT1_ROOT_PRE_DIV] = imx_clk_hw_divider2("gpt1_pre_div", "gpt1_cg", base + 0xb900, 16, 3); |
691 | clks[IMX7D_GPT2_ROOT_PRE_DIV] = imx_clk_divider2("gpt2_pre_div", "gpt2_cg", base + 0xb980, 16, 3); | 702 | hws[IMX7D_GPT2_ROOT_PRE_DIV] = imx_clk_hw_divider2("gpt2_pre_div", "gpt2_cg", base + 0xb980, 16, 3); |
692 | clks[IMX7D_GPT3_ROOT_PRE_DIV] = imx_clk_divider2("gpt3_pre_div", "gpt3_cg", base + 0xba00, 16, 3); | 703 | hws[IMX7D_GPT3_ROOT_PRE_DIV] = imx_clk_hw_divider2("gpt3_pre_div", "gpt3_cg", base + 0xba00, 16, 3); |
693 | clks[IMX7D_GPT4_ROOT_PRE_DIV] = imx_clk_divider2("gpt4_pre_div", "gpt4_cg", base + 0xba80, 16, 3); | 704 | hws[IMX7D_GPT4_ROOT_PRE_DIV] = imx_clk_hw_divider2("gpt4_pre_div", "gpt4_cg", base + 0xba80, 16, 3); |
694 | clks[IMX7D_TRACE_ROOT_PRE_DIV] = imx_clk_divider2("trace_pre_div", "trace_cg", base + 0xbb00, 16, 3); | 705 | hws[IMX7D_TRACE_ROOT_PRE_DIV] = imx_clk_hw_divider2("trace_pre_div", "trace_cg", base + 0xbb00, 16, 3); |
695 | clks[IMX7D_WDOG_ROOT_PRE_DIV] = imx_clk_divider2("wdog_pre_div", "wdog_cg", base + 0xbb80, 16, 3); | 706 | hws[IMX7D_WDOG_ROOT_PRE_DIV] = imx_clk_hw_divider2("wdog_pre_div", "wdog_cg", base + 0xbb80, 16, 3); |
696 | clks[IMX7D_CSI_MCLK_ROOT_PRE_DIV] = imx_clk_divider2("csi_mclk_pre_div", "csi_mclk_cg", base + 0xbc00, 16, 3); | 707 | hws[IMX7D_CSI_MCLK_ROOT_PRE_DIV] = imx_clk_hw_divider2("csi_mclk_pre_div", "csi_mclk_cg", base + 0xbc00, 16, 3); |
697 | clks[IMX7D_AUDIO_MCLK_ROOT_PRE_DIV] = imx_clk_divider2("audio_mclk_pre_div", "audio_mclk_cg", base + 0xbc80, 16, 3); | 708 | hws[IMX7D_AUDIO_MCLK_ROOT_PRE_DIV] = imx_clk_hw_divider2("audio_mclk_pre_div", "audio_mclk_cg", base + 0xbc80, 16, 3); |
698 | clks[IMX7D_WRCLK_ROOT_PRE_DIV] = imx_clk_divider2("wrclk_pre_div", "wrclk_cg", base + 0xbd00, 16, 3); | 709 | hws[IMX7D_WRCLK_ROOT_PRE_DIV] = imx_clk_hw_divider2("wrclk_pre_div", "wrclk_cg", base + 0xbd00, 16, 3); |
699 | clks[IMX7D_CLKO1_ROOT_PRE_DIV] = imx_clk_divider2("clko1_pre_div", "clko1_cg", base + 0xbd80, 16, 3); | 710 | hws[IMX7D_CLKO1_ROOT_PRE_DIV] = imx_clk_hw_divider2("clko1_pre_div", "clko1_cg", base + 0xbd80, 16, 3); |
700 | clks[IMX7D_CLKO2_ROOT_PRE_DIV] = imx_clk_divider2("clko2_pre_div", "clko2_cg", base + 0xbe00, 16, 3); | 711 | hws[IMX7D_CLKO2_ROOT_PRE_DIV] = imx_clk_hw_divider2("clko2_pre_div", "clko2_cg", base + 0xbe00, 16, 3); |
701 | 712 | ||
702 | clks[IMX7D_ARM_A7_ROOT_DIV] = imx_clk_divider2("arm_a7_div", "arm_a7_cg", base + 0x8000, 0, 3); | 713 | hws[IMX7D_ARM_A7_ROOT_DIV] = imx_clk_hw_divider2("arm_a7_div", "arm_a7_cg", base + 0x8000, 0, 3); |
703 | clks[IMX7D_ARM_M4_ROOT_DIV] = imx_clk_divider2("arm_m4_div", "arm_m4_cg", base + 0x8080, 0, 3); | 714 | hws[IMX7D_ARM_M4_ROOT_DIV] = imx_clk_hw_divider2("arm_m4_div", "arm_m4_cg", base + 0x8080, 0, 3); |
704 | clks[IMX7D_MAIN_AXI_ROOT_DIV] = imx_clk_divider2("axi_post_div", "axi_pre_div", base + 0x8800, 0, 6); | 715 | hws[IMX7D_MAIN_AXI_ROOT_DIV] = imx_clk_hw_divider2("axi_post_div", "axi_pre_div", base + 0x8800, 0, 6); |
705 | clks[IMX7D_DISP_AXI_ROOT_DIV] = imx_clk_divider2("disp_axi_post_div", "disp_axi_pre_div", base + 0x8880, 0, 6); | 716 | hws[IMX7D_DISP_AXI_ROOT_DIV] = imx_clk_hw_divider2("disp_axi_post_div", "disp_axi_pre_div", base + 0x8880, 0, 6); |
706 | clks[IMX7D_ENET_AXI_ROOT_DIV] = imx_clk_divider2("enet_axi_post_div", "enet_axi_pre_div", base + 0x8900, 0, 6); | 717 | hws[IMX7D_ENET_AXI_ROOT_DIV] = imx_clk_hw_divider2("enet_axi_post_div", "enet_axi_pre_div", base + 0x8900, 0, 6); |
707 | clks[IMX7D_NAND_USDHC_BUS_ROOT_CLK] = imx_clk_divider2("nand_usdhc_root_clk", "nand_usdhc_pre_div", base + 0x8980, 0, 6); | 718 | hws[IMX7D_NAND_USDHC_BUS_ROOT_CLK] = imx_clk_hw_divider2("nand_usdhc_root_clk", "nand_usdhc_pre_div", base + 0x8980, 0, 6); |
708 | clks[IMX7D_AHB_CHANNEL_ROOT_DIV] = imx_clk_divider2("ahb_root_clk", "ahb_pre_div", base + 0x9000, 0, 6); | 719 | hws[IMX7D_AHB_CHANNEL_ROOT_DIV] = imx_clk_hw_divider2("ahb_root_clk", "ahb_pre_div", base + 0x9000, 0, 6); |
709 | clks[IMX7D_IPG_ROOT_CLK] = imx_clk_divider_flags("ipg_root_clk", "ahb_root_clk", base + 0x9080, 0, 2, CLK_IS_CRITICAL | CLK_OPS_PARENT_ENABLE | CLK_SET_RATE_PARENT); | 720 | hws[IMX7D_IPG_ROOT_CLK] = imx_clk_hw_divider_flags("ipg_root_clk", "ahb_root_clk", base + 0x9080, 0, 2, CLK_IS_CRITICAL | CLK_OPS_PARENT_ENABLE | CLK_SET_RATE_PARENT); |
710 | clks[IMX7D_DRAM_ROOT_DIV] = imx_clk_divider2("dram_post_div", "dram_cg", base + 0x9880, 0, 3); | 721 | hws[IMX7D_DRAM_ROOT_DIV] = imx_clk_hw_divider2("dram_post_div", "dram_cg", base + 0x9880, 0, 3); |
711 | clks[IMX7D_DRAM_PHYM_ALT_ROOT_DIV] = imx_clk_divider2("dram_phym_alt_post_div", "dram_phym_alt_pre_div", base + 0xa000, 0, 3); | 722 | hws[IMX7D_DRAM_PHYM_ALT_ROOT_DIV] = imx_clk_hw_divider2("dram_phym_alt_post_div", "dram_phym_alt_pre_div", base + 0xa000, 0, 3); |
712 | clks[IMX7D_DRAM_ALT_ROOT_DIV] = imx_clk_divider2("dram_alt_post_div", "dram_alt_pre_div", base + 0xa080, 0, 3); | 723 | hws[IMX7D_DRAM_ALT_ROOT_DIV] = imx_clk_hw_divider2("dram_alt_post_div", "dram_alt_pre_div", base + 0xa080, 0, 3); |
713 | clks[IMX7D_USB_HSIC_ROOT_DIV] = imx_clk_divider2("usb_hsic_post_div", "usb_hsic_pre_div", base + 0xa100, 0, 6); | 724 | hws[IMX7D_USB_HSIC_ROOT_DIV] = imx_clk_hw_divider2("usb_hsic_post_div", "usb_hsic_pre_div", base + 0xa100, 0, 6); |
714 | clks[IMX7D_PCIE_CTRL_ROOT_DIV] = imx_clk_divider2("pcie_ctrl_post_div", "pcie_ctrl_pre_div", base + 0xa180, 0, 6); | 725 | hws[IMX7D_PCIE_CTRL_ROOT_DIV] = imx_clk_hw_divider2("pcie_ctrl_post_div", "pcie_ctrl_pre_div", base + 0xa180, 0, 6); |
715 | clks[IMX7D_PCIE_PHY_ROOT_DIV] = imx_clk_divider2("pcie_phy_post_div", "pcie_phy_pre_div", base + 0xa200, 0, 6); | 726 | hws[IMX7D_PCIE_PHY_ROOT_DIV] = imx_clk_hw_divider2("pcie_phy_post_div", "pcie_phy_pre_div", base + 0xa200, 0, 6); |
716 | clks[IMX7D_EPDC_PIXEL_ROOT_DIV] = imx_clk_divider2("epdc_pixel_post_div", "epdc_pixel_pre_div", base + 0xa280, 0, 6); | 727 | hws[IMX7D_EPDC_PIXEL_ROOT_DIV] = imx_clk_hw_divider2("epdc_pixel_post_div", "epdc_pixel_pre_div", base + 0xa280, 0, 6); |
717 | clks[IMX7D_LCDIF_PIXEL_ROOT_DIV] = imx_clk_divider2("lcdif_pixel_post_div", "lcdif_pixel_pre_div", base + 0xa300, 0, 6); | 728 | hws[IMX7D_LCDIF_PIXEL_ROOT_DIV] = imx_clk_hw_divider2("lcdif_pixel_post_div", "lcdif_pixel_pre_div", base + 0xa300, 0, 6); |
718 | clks[IMX7D_MIPI_DSI_ROOT_DIV] = imx_clk_divider2("mipi_dsi_post_div", "mipi_dsi_pre_div", base + 0xa380, 0, 6); | 729 | hws[IMX7D_MIPI_DSI_ROOT_DIV] = imx_clk_hw_divider2("mipi_dsi_post_div", "mipi_dsi_pre_div", base + 0xa380, 0, 6); |
719 | clks[IMX7D_MIPI_CSI_ROOT_DIV] = imx_clk_divider2("mipi_csi_post_div", "mipi_csi_pre_div", base + 0xa400, 0, 6); | 730 | hws[IMX7D_MIPI_CSI_ROOT_DIV] = imx_clk_hw_divider2("mipi_csi_post_div", "mipi_csi_pre_div", base + 0xa400, 0, 6); |
720 | clks[IMX7D_MIPI_DPHY_ROOT_DIV] = imx_clk_divider2("mipi_dphy_post_div", "mipi_dphy_pre_div", base + 0xa480, 0, 6); | 731 | hws[IMX7D_MIPI_DPHY_ROOT_DIV] = imx_clk_hw_divider2("mipi_dphy_post_div", "mipi_dphy_pre_div", base + 0xa480, 0, 6); |
721 | clks[IMX7D_SAI1_ROOT_DIV] = imx_clk_divider2("sai1_post_div", "sai1_pre_div", base + 0xa500, 0, 6); | 732 | hws[IMX7D_SAI1_ROOT_DIV] = imx_clk_hw_divider2("sai1_post_div", "sai1_pre_div", base + 0xa500, 0, 6); |
722 | clks[IMX7D_SAI2_ROOT_DIV] = imx_clk_divider2("sai2_post_div", "sai2_pre_div", base + 0xa580, 0, 6); | 733 | hws[IMX7D_SAI2_ROOT_DIV] = imx_clk_hw_divider2("sai2_post_div", "sai2_pre_div", base + 0xa580, 0, 6); |
723 | clks[IMX7D_SAI3_ROOT_DIV] = imx_clk_divider2("sai3_post_div", "sai3_pre_div", base + 0xa600, 0, 6); | 734 | hws[IMX7D_SAI3_ROOT_DIV] = imx_clk_hw_divider2("sai3_post_div", "sai3_pre_div", base + 0xa600, 0, 6); |
724 | clks[IMX7D_SPDIF_ROOT_DIV] = imx_clk_divider2("spdif_post_div", "spdif_pre_div", base + 0xa680, 0, 6); | 735 | hws[IMX7D_SPDIF_ROOT_DIV] = imx_clk_hw_divider2("spdif_post_div", "spdif_pre_div", base + 0xa680, 0, 6); |
725 | clks[IMX7D_ENET1_REF_ROOT_DIV] = imx_clk_divider2("enet1_ref_post_div", "enet1_ref_pre_div", base + 0xa700, 0, 6); | 736 | hws[IMX7D_ENET1_REF_ROOT_DIV] = imx_clk_hw_divider2("enet1_ref_post_div", "enet1_ref_pre_div", base + 0xa700, 0, 6); |
726 | clks[IMX7D_ENET1_TIME_ROOT_DIV] = imx_clk_divider2("enet1_time_post_div", "enet1_time_pre_div", base + 0xa780, 0, 6); | 737 | hws[IMX7D_ENET1_TIME_ROOT_DIV] = imx_clk_hw_divider2("enet1_time_post_div", "enet1_time_pre_div", base + 0xa780, 0, 6); |
727 | clks[IMX7D_ENET2_REF_ROOT_DIV] = imx_clk_divider2("enet2_ref_post_div", "enet2_ref_pre_div", base + 0xa800, 0, 6); | 738 | hws[IMX7D_ENET2_REF_ROOT_DIV] = imx_clk_hw_divider2("enet2_ref_post_div", "enet2_ref_pre_div", base + 0xa800, 0, 6); |
728 | clks[IMX7D_ENET2_TIME_ROOT_DIV] = imx_clk_divider2("enet2_time_post_div", "enet2_time_pre_div", base + 0xa880, 0, 6); | 739 | hws[IMX7D_ENET2_TIME_ROOT_DIV] = imx_clk_hw_divider2("enet2_time_post_div", "enet2_time_pre_div", base + 0xa880, 0, 6); |
729 | clks[IMX7D_ENET_PHY_REF_ROOT_CLK] = imx_clk_divider2("enet_phy_ref_root_clk", "enet_phy_ref_pre_div", base + 0xa900, 0, 6); | 740 | hws[IMX7D_ENET_PHY_REF_ROOT_CLK] = imx_clk_hw_divider2("enet_phy_ref_root_clk", "enet_phy_ref_pre_div", base + 0xa900, 0, 6); |
730 | clks[IMX7D_EIM_ROOT_DIV] = imx_clk_divider2("eim_post_div", "eim_pre_div", base + 0xa980, 0, 6); | 741 | hws[IMX7D_EIM_ROOT_DIV] = imx_clk_hw_divider2("eim_post_div", "eim_pre_div", base + 0xa980, 0, 6); |
731 | clks[IMX7D_NAND_ROOT_CLK] = imx_clk_divider2("nand_root_clk", "nand_pre_div", base + 0xaa00, 0, 6); | 742 | hws[IMX7D_NAND_ROOT_CLK] = imx_clk_hw_divider2("nand_root_clk", "nand_pre_div", base + 0xaa00, 0, 6); |
732 | clks[IMX7D_QSPI_ROOT_DIV] = imx_clk_divider2("qspi_post_div", "qspi_pre_div", base + 0xaa80, 0, 6); | 743 | hws[IMX7D_QSPI_ROOT_DIV] = imx_clk_hw_divider2("qspi_post_div", "qspi_pre_div", base + 0xaa80, 0, 6); |
733 | clks[IMX7D_USDHC1_ROOT_DIV] = imx_clk_divider2("usdhc1_post_div", "usdhc1_pre_div", base + 0xab00, 0, 6); | 744 | hws[IMX7D_USDHC1_ROOT_DIV] = imx_clk_hw_divider2("usdhc1_post_div", "usdhc1_pre_div", base + 0xab00, 0, 6); |
734 | clks[IMX7D_USDHC2_ROOT_DIV] = imx_clk_divider2("usdhc2_post_div", "usdhc2_pre_div", base + 0xab80, 0, 6); | 745 | hws[IMX7D_USDHC2_ROOT_DIV] = imx_clk_hw_divider2("usdhc2_post_div", "usdhc2_pre_div", base + 0xab80, 0, 6); |
735 | clks[IMX7D_USDHC3_ROOT_DIV] = imx_clk_divider2("usdhc3_post_div", "usdhc3_pre_div", base + 0xac00, 0, 6); | 746 | hws[IMX7D_USDHC3_ROOT_DIV] = imx_clk_hw_divider2("usdhc3_post_div", "usdhc3_pre_div", base + 0xac00, 0, 6); |
736 | clks[IMX7D_CAN1_ROOT_DIV] = imx_clk_divider2("can1_post_div", "can1_pre_div", base + 0xac80, 0, 6); | 747 | hws[IMX7D_CAN1_ROOT_DIV] = imx_clk_hw_divider2("can1_post_div", "can1_pre_div", base + 0xac80, 0, 6); |
737 | clks[IMX7D_CAN2_ROOT_DIV] = imx_clk_divider2("can2_post_div", "can2_pre_div", base + 0xad00, 0, 6); | 748 | hws[IMX7D_CAN2_ROOT_DIV] = imx_clk_hw_divider2("can2_post_div", "can2_pre_div", base + 0xad00, 0, 6); |
738 | clks[IMX7D_I2C1_ROOT_DIV] = imx_clk_divider2("i2c1_post_div", "i2c1_pre_div", base + 0xad80, 0, 6); | 749 | hws[IMX7D_I2C1_ROOT_DIV] = imx_clk_hw_divider2("i2c1_post_div", "i2c1_pre_div", base + 0xad80, 0, 6); |
739 | clks[IMX7D_I2C2_ROOT_DIV] = imx_clk_divider2("i2c2_post_div", "i2c2_pre_div", base + 0xae00, 0, 6); | 750 | hws[IMX7D_I2C2_ROOT_DIV] = imx_clk_hw_divider2("i2c2_post_div", "i2c2_pre_div", base + 0xae00, 0, 6); |
740 | clks[IMX7D_I2C3_ROOT_DIV] = imx_clk_divider2("i2c3_post_div", "i2c3_pre_div", base + 0xae80, 0, 6); | 751 | hws[IMX7D_I2C3_ROOT_DIV] = imx_clk_hw_divider2("i2c3_post_div", "i2c3_pre_div", base + 0xae80, 0, 6); |
741 | clks[IMX7D_I2C4_ROOT_DIV] = imx_clk_divider2("i2c4_post_div", "i2c4_pre_div", base + 0xaf00, 0, 6); | 752 | hws[IMX7D_I2C4_ROOT_DIV] = imx_clk_hw_divider2("i2c4_post_div", "i2c4_pre_div", base + 0xaf00, 0, 6); |
742 | clks[IMX7D_UART1_ROOT_DIV] = imx_clk_divider2("uart1_post_div", "uart1_pre_div", base + 0xaf80, 0, 6); | 753 | hws[IMX7D_UART1_ROOT_DIV] = imx_clk_hw_divider2("uart1_post_div", "uart1_pre_div", base + 0xaf80, 0, 6); |
743 | clks[IMX7D_UART2_ROOT_DIV] = imx_clk_divider2("uart2_post_div", "uart2_pre_div", base + 0xb000, 0, 6); | 754 | hws[IMX7D_UART2_ROOT_DIV] = imx_clk_hw_divider2("uart2_post_div", "uart2_pre_div", base + 0xb000, 0, 6); |
744 | clks[IMX7D_UART3_ROOT_DIV] = imx_clk_divider2("uart3_post_div", "uart3_pre_div", base + 0xb080, 0, 6); | 755 | hws[IMX7D_UART3_ROOT_DIV] = imx_clk_hw_divider2("uart3_post_div", "uart3_pre_div", base + 0xb080, 0, 6); |
745 | clks[IMX7D_UART4_ROOT_DIV] = imx_clk_divider2("uart4_post_div", "uart4_pre_div", base + 0xb100, 0, 6); | 756 | hws[IMX7D_UART4_ROOT_DIV] = imx_clk_hw_divider2("uart4_post_div", "uart4_pre_div", base + 0xb100, 0, 6); |
746 | clks[IMX7D_UART5_ROOT_DIV] = imx_clk_divider2("uart5_post_div", "uart5_pre_div", base + 0xb180, 0, 6); | 757 | hws[IMX7D_UART5_ROOT_DIV] = imx_clk_hw_divider2("uart5_post_div", "uart5_pre_div", base + 0xb180, 0, 6); |
747 | clks[IMX7D_UART6_ROOT_DIV] = imx_clk_divider2("uart6_post_div", "uart6_pre_div", base + 0xb200, 0, 6); | 758 | hws[IMX7D_UART6_ROOT_DIV] = imx_clk_hw_divider2("uart6_post_div", "uart6_pre_div", base + 0xb200, 0, 6); |
748 | clks[IMX7D_UART7_ROOT_DIV] = imx_clk_divider2("uart7_post_div", "uart7_pre_div", base + 0xb280, 0, 6); | 759 | hws[IMX7D_UART7_ROOT_DIV] = imx_clk_hw_divider2("uart7_post_div", "uart7_pre_div", base + 0xb280, 0, 6); |
749 | clks[IMX7D_ECSPI1_ROOT_DIV] = imx_clk_divider2("ecspi1_post_div", "ecspi1_pre_div", base + 0xb300, 0, 6); | 760 | hws[IMX7D_ECSPI1_ROOT_DIV] = imx_clk_hw_divider2("ecspi1_post_div", "ecspi1_pre_div", base + 0xb300, 0, 6); |
750 | clks[IMX7D_ECSPI2_ROOT_DIV] = imx_clk_divider2("ecspi2_post_div", "ecspi2_pre_div", base + 0xb380, 0, 6); | 761 | hws[IMX7D_ECSPI2_ROOT_DIV] = imx_clk_hw_divider2("ecspi2_post_div", "ecspi2_pre_div", base + 0xb380, 0, 6); |
751 | clks[IMX7D_ECSPI3_ROOT_DIV] = imx_clk_divider2("ecspi3_post_div", "ecspi3_pre_div", base + 0xb400, 0, 6); | 762 | hws[IMX7D_ECSPI3_ROOT_DIV] = imx_clk_hw_divider2("ecspi3_post_div", "ecspi3_pre_div", base + 0xb400, 0, 6); |
752 | clks[IMX7D_ECSPI4_ROOT_DIV] = imx_clk_divider2("ecspi4_post_div", "ecspi4_pre_div", base + 0xb480, 0, 6); | 763 | hws[IMX7D_ECSPI4_ROOT_DIV] = imx_clk_hw_divider2("ecspi4_post_div", "ecspi4_pre_div", base + 0xb480, 0, 6); |
753 | clks[IMX7D_PWM1_ROOT_DIV] = imx_clk_divider2("pwm1_post_div", "pwm1_pre_div", base + 0xb500, 0, 6); | 764 | hws[IMX7D_PWM1_ROOT_DIV] = imx_clk_hw_divider2("pwm1_post_div", "pwm1_pre_div", base + 0xb500, 0, 6); |
754 | clks[IMX7D_PWM2_ROOT_DIV] = imx_clk_divider2("pwm2_post_div", "pwm2_pre_div", base + 0xb580, 0, 6); | 765 | hws[IMX7D_PWM2_ROOT_DIV] = imx_clk_hw_divider2("pwm2_post_div", "pwm2_pre_div", base + 0xb580, 0, 6); |
755 | clks[IMX7D_PWM3_ROOT_DIV] = imx_clk_divider2("pwm3_post_div", "pwm3_pre_div", base + 0xb600, 0, 6); | 766 | hws[IMX7D_PWM3_ROOT_DIV] = imx_clk_hw_divider2("pwm3_post_div", "pwm3_pre_div", base + 0xb600, 0, 6); |
756 | clks[IMX7D_PWM4_ROOT_DIV] = imx_clk_divider2("pwm4_post_div", "pwm4_pre_div", base + 0xb680, 0, 6); | 767 | hws[IMX7D_PWM4_ROOT_DIV] = imx_clk_hw_divider2("pwm4_post_div", "pwm4_pre_div", base + 0xb680, 0, 6); |
757 | clks[IMX7D_FLEXTIMER1_ROOT_DIV] = imx_clk_divider2("flextimer1_post_div", "flextimer1_pre_div", base + 0xb700, 0, 6); | 768 | hws[IMX7D_FLEXTIMER1_ROOT_DIV] = imx_clk_hw_divider2("flextimer1_post_div", "flextimer1_pre_div", base + 0xb700, 0, 6); |
758 | clks[IMX7D_FLEXTIMER2_ROOT_DIV] = imx_clk_divider2("flextimer2_post_div", "flextimer2_pre_div", base + 0xb780, 0, 6); | 769 | hws[IMX7D_FLEXTIMER2_ROOT_DIV] = imx_clk_hw_divider2("flextimer2_post_div", "flextimer2_pre_div", base + 0xb780, 0, 6); |
759 | clks[IMX7D_SIM1_ROOT_DIV] = imx_clk_divider2("sim1_post_div", "sim1_pre_div", base + 0xb800, 0, 6); | 770 | hws[IMX7D_SIM1_ROOT_DIV] = imx_clk_hw_divider2("sim1_post_div", "sim1_pre_div", base + 0xb800, 0, 6); |
760 | clks[IMX7D_SIM2_ROOT_DIV] = imx_clk_divider2("sim2_post_div", "sim2_pre_div", base + 0xb880, 0, 6); | 771 | hws[IMX7D_SIM2_ROOT_DIV] = imx_clk_hw_divider2("sim2_post_div", "sim2_pre_div", base + 0xb880, 0, 6); |
761 | clks[IMX7D_GPT1_ROOT_DIV] = imx_clk_divider2("gpt1_post_div", "gpt1_pre_div", base + 0xb900, 0, 6); | 772 | hws[IMX7D_GPT1_ROOT_DIV] = imx_clk_hw_divider2("gpt1_post_div", "gpt1_pre_div", base + 0xb900, 0, 6); |
762 | clks[IMX7D_GPT2_ROOT_DIV] = imx_clk_divider2("gpt2_post_div", "gpt2_pre_div", base + 0xb980, 0, 6); | 773 | hws[IMX7D_GPT2_ROOT_DIV] = imx_clk_hw_divider2("gpt2_post_div", "gpt2_pre_div", base + 0xb980, 0, 6); |
763 | clks[IMX7D_GPT3_ROOT_DIV] = imx_clk_divider2("gpt3_post_div", "gpt3_pre_div", base + 0xba00, 0, 6); | 774 | hws[IMX7D_GPT3_ROOT_DIV] = imx_clk_hw_divider2("gpt3_post_div", "gpt3_pre_div", base + 0xba00, 0, 6); |
764 | clks[IMX7D_GPT4_ROOT_DIV] = imx_clk_divider2("gpt4_post_div", "gpt4_pre_div", base + 0xba80, 0, 6); | 775 | hws[IMX7D_GPT4_ROOT_DIV] = imx_clk_hw_divider2("gpt4_post_div", "gpt4_pre_div", base + 0xba80, 0, 6); |
765 | clks[IMX7D_TRACE_ROOT_DIV] = imx_clk_divider2("trace_post_div", "trace_pre_div", base + 0xbb00, 0, 6); | 776 | hws[IMX7D_TRACE_ROOT_DIV] = imx_clk_hw_divider2("trace_post_div", "trace_pre_div", base + 0xbb00, 0, 6); |
766 | clks[IMX7D_WDOG_ROOT_DIV] = imx_clk_divider2("wdog_post_div", "wdog_pre_div", base + 0xbb80, 0, 6); | 777 | hws[IMX7D_WDOG_ROOT_DIV] = imx_clk_hw_divider2("wdog_post_div", "wdog_pre_div", base + 0xbb80, 0, 6); |
767 | clks[IMX7D_CSI_MCLK_ROOT_DIV] = imx_clk_divider2("csi_mclk_post_div", "csi_mclk_pre_div", base + 0xbc00, 0, 6); | 778 | hws[IMX7D_CSI_MCLK_ROOT_DIV] = imx_clk_hw_divider2("csi_mclk_post_div", "csi_mclk_pre_div", base + 0xbc00, 0, 6); |
768 | clks[IMX7D_AUDIO_MCLK_ROOT_DIV] = imx_clk_divider2("audio_mclk_post_div", "audio_mclk_pre_div", base + 0xbc80, 0, 6); | 779 | hws[IMX7D_AUDIO_MCLK_ROOT_DIV] = imx_clk_hw_divider2("audio_mclk_post_div", "audio_mclk_pre_div", base + 0xbc80, 0, 6); |
769 | clks[IMX7D_WRCLK_ROOT_DIV] = imx_clk_divider2("wrclk_post_div", "wrclk_pre_div", base + 0xbd00, 0, 6); | 780 | hws[IMX7D_WRCLK_ROOT_DIV] = imx_clk_hw_divider2("wrclk_post_div", "wrclk_pre_div", base + 0xbd00, 0, 6); |
770 | clks[IMX7D_CLKO1_ROOT_DIV] = imx_clk_divider2("clko1_post_div", "clko1_pre_div", base + 0xbd80, 0, 6); | 781 | hws[IMX7D_CLKO1_ROOT_DIV] = imx_clk_hw_divider2("clko1_post_div", "clko1_pre_div", base + 0xbd80, 0, 6); |
771 | clks[IMX7D_CLKO2_ROOT_DIV] = imx_clk_divider2("clko2_post_div", "clko2_pre_div", base + 0xbe00, 0, 6); | 782 | hws[IMX7D_CLKO2_ROOT_DIV] = imx_clk_hw_divider2("clko2_post_div", "clko2_pre_div", base + 0xbe00, 0, 6); |
772 | 783 | ||
773 | clks[IMX7D_ARM_A7_ROOT_CLK] = imx_clk_gate2_flags("arm_a7_root_clk", "arm_a7_div", base + 0x4000, 0, CLK_OPS_PARENT_ENABLE); | 784 | hws[IMX7D_ARM_A7_ROOT_CLK] = imx_clk_hw_gate2_flags("arm_a7_root_clk", "arm_a7_div", base + 0x4000, 0, CLK_OPS_PARENT_ENABLE); |
774 | clks[IMX7D_ARM_M4_ROOT_CLK] = imx_clk_gate4("arm_m4_root_clk", "arm_m4_div", base + 0x4010, 0); | 785 | hws[IMX7D_ARM_M4_ROOT_CLK] = imx_clk_hw_gate4("arm_m4_root_clk", "arm_m4_div", base + 0x4010, 0); |
775 | clks[IMX7D_MAIN_AXI_ROOT_CLK] = imx_clk_gate2_flags("main_axi_root_clk", "axi_post_div", base + 0x4040, 0, CLK_IS_CRITICAL | CLK_OPS_PARENT_ENABLE); | 786 | hws[IMX7D_MAIN_AXI_ROOT_CLK] = imx_clk_hw_gate2_flags("main_axi_root_clk", "axi_post_div", base + 0x4040, 0, CLK_IS_CRITICAL | CLK_OPS_PARENT_ENABLE); |
776 | clks[IMX7D_DISP_AXI_ROOT_CLK] = imx_clk_gate4("disp_axi_root_clk", "disp_axi_post_div", base + 0x4050, 0); | 787 | hws[IMX7D_DISP_AXI_ROOT_CLK] = imx_clk_hw_gate4("disp_axi_root_clk", "disp_axi_post_div", base + 0x4050, 0); |
777 | clks[IMX7D_ENET_AXI_ROOT_CLK] = imx_clk_gate4("enet_axi_root_clk", "enet_axi_post_div", base + 0x4060, 0); | 788 | hws[IMX7D_ENET_AXI_ROOT_CLK] = imx_clk_hw_gate4("enet_axi_root_clk", "enet_axi_post_div", base + 0x4060, 0); |
778 | clks[IMX7D_OCRAM_CLK] = imx_clk_gate4("ocram_clk", "main_axi_root_clk", base + 0x4110, 0); | 789 | hws[IMX7D_OCRAM_CLK] = imx_clk_hw_gate4("ocram_clk", "main_axi_root_clk", base + 0x4110, 0); |
779 | clks[IMX7D_OCRAM_S_CLK] = imx_clk_gate4("ocram_s_clk", "ahb_root_clk", base + 0x4120, 0); | 790 | hws[IMX7D_OCRAM_S_CLK] = imx_clk_hw_gate4("ocram_s_clk", "ahb_root_clk", base + 0x4120, 0); |
780 | clks[IMX7D_DRAM_ROOT_CLK] = imx_clk_gate2_flags("dram_root_clk", "dram_post_div", base + 0x4130, 0, CLK_IS_CRITICAL | CLK_OPS_PARENT_ENABLE); | 791 | hws[IMX7D_DRAM_ROOT_CLK] = imx_clk_hw_gate2_flags("dram_root_clk", "dram_post_div", base + 0x4130, 0, CLK_IS_CRITICAL | CLK_OPS_PARENT_ENABLE); |
781 | clks[IMX7D_DRAM_PHYM_ROOT_CLK] = imx_clk_gate2_flags("dram_phym_root_clk", "dram_phym_cg", base + 0x4130, 0, CLK_IS_CRITICAL | CLK_OPS_PARENT_ENABLE); | 792 | hws[IMX7D_DRAM_PHYM_ROOT_CLK] = imx_clk_hw_gate2_flags("dram_phym_root_clk", "dram_phym_cg", base + 0x4130, 0, CLK_IS_CRITICAL | CLK_OPS_PARENT_ENABLE); |
782 | clks[IMX7D_DRAM_PHYM_ALT_ROOT_CLK] = imx_clk_gate2_flags("dram_phym_alt_root_clk", "dram_phym_alt_post_div", base + 0x4130, 0, CLK_IS_CRITICAL | CLK_OPS_PARENT_ENABLE); | 793 | hws[IMX7D_DRAM_PHYM_ALT_ROOT_CLK] = imx_clk_hw_gate2_flags("dram_phym_alt_root_clk", "dram_phym_alt_post_div", base + 0x4130, 0, CLK_IS_CRITICAL | CLK_OPS_PARENT_ENABLE); |
783 | clks[IMX7D_DRAM_ALT_ROOT_CLK] = imx_clk_gate2_flags("dram_alt_root_clk", "dram_alt_post_div", base + 0x4130, 0, CLK_IS_CRITICAL | CLK_OPS_PARENT_ENABLE); | 794 | hws[IMX7D_DRAM_ALT_ROOT_CLK] = imx_clk_hw_gate2_flags("dram_alt_root_clk", "dram_alt_post_div", base + 0x4130, 0, CLK_IS_CRITICAL | CLK_OPS_PARENT_ENABLE); |
784 | clks[IMX7D_OCOTP_CLK] = imx_clk_gate4("ocotp_clk", "ipg_root_clk", base + 0x4230, 0); | 795 | hws[IMX7D_OCOTP_CLK] = imx_clk_hw_gate4("ocotp_clk", "ipg_root_clk", base + 0x4230, 0); |
785 | clks[IMX7D_SNVS_CLK] = imx_clk_gate4("snvs_clk", "ipg_root_clk", base + 0x4250, 0); | 796 | hws[IMX7D_SNVS_CLK] = imx_clk_hw_gate4("snvs_clk", "ipg_root_clk", base + 0x4250, 0); |
786 | clks[IMX7D_MU_ROOT_CLK] = imx_clk_gate4("mu_root_clk", "ipg_root_clk", base + 0x4270, 0); | 797 | hws[IMX7D_MU_ROOT_CLK] = imx_clk_hw_gate4("mu_root_clk", "ipg_root_clk", base + 0x4270, 0); |
787 | clks[IMX7D_CAAM_CLK] = imx_clk_gate4("caam_clk", "ipg_root_clk", base + 0x4240, 0); | 798 | hws[IMX7D_CAAM_CLK] = imx_clk_hw_gate4("caam_clk", "ipg_root_clk", base + 0x4240, 0); |
788 | clks[IMX7D_USB_HSIC_ROOT_CLK] = imx_clk_gate4("usb_hsic_root_clk", "usb_hsic_post_div", base + 0x4690, 0); | 799 | hws[IMX7D_USB_HSIC_ROOT_CLK] = imx_clk_hw_gate4("usb_hsic_root_clk", "usb_hsic_post_div", base + 0x4690, 0); |
789 | clks[IMX7D_SDMA_CORE_CLK] = imx_clk_gate4("sdma_root_clk", "ahb_root_clk", base + 0x4480, 0); | 800 | hws[IMX7D_SDMA_CORE_CLK] = imx_clk_hw_gate4("sdma_root_clk", "ahb_root_clk", base + 0x4480, 0); |
790 | clks[IMX7D_PCIE_CTRL_ROOT_CLK] = imx_clk_gate4("pcie_ctrl_root_clk", "pcie_ctrl_post_div", base + 0x4600, 0); | 801 | hws[IMX7D_PCIE_CTRL_ROOT_CLK] = imx_clk_hw_gate4("pcie_ctrl_root_clk", "pcie_ctrl_post_div", base + 0x4600, 0); |
791 | clks[IMX7D_PCIE_PHY_ROOT_CLK] = imx_clk_gate4("pcie_phy_root_clk", "pcie_phy_post_div", base + 0x4600, 0); | 802 | hws[IMX7D_PCIE_PHY_ROOT_CLK] = imx_clk_hw_gate4("pcie_phy_root_clk", "pcie_phy_post_div", base + 0x4600, 0); |
792 | clks[IMX7D_EPDC_PIXEL_ROOT_CLK] = imx_clk_gate4("epdc_pixel_root_clk", "epdc_pixel_post_div", base + 0x44a0, 0); | 803 | hws[IMX7D_EPDC_PIXEL_ROOT_CLK] = imx_clk_hw_gate4("epdc_pixel_root_clk", "epdc_pixel_post_div", base + 0x44a0, 0); |
793 | clks[IMX7D_LCDIF_PIXEL_ROOT_CLK] = imx_clk_gate4("lcdif_pixel_root_clk", "lcdif_pixel_post_div", base + 0x44b0, 0); | 804 | hws[IMX7D_LCDIF_PIXEL_ROOT_CLK] = imx_clk_hw_gate4("lcdif_pixel_root_clk", "lcdif_pixel_post_div", base + 0x44b0, 0); |
794 | clks[IMX7D_MIPI_DSI_ROOT_CLK] = imx_clk_gate4("mipi_dsi_root_clk", "mipi_dsi_post_div", base + 0x4650, 0); | 805 | hws[IMX7D_MIPI_DSI_ROOT_CLK] = imx_clk_hw_gate4("mipi_dsi_root_clk", "mipi_dsi_post_div", base + 0x4650, 0); |
795 | clks[IMX7D_MIPI_CSI_ROOT_CLK] = imx_clk_gate4("mipi_csi_root_clk", "mipi_csi_post_div", base + 0x4640, 0); | 806 | hws[IMX7D_MIPI_CSI_ROOT_CLK] = imx_clk_hw_gate4("mipi_csi_root_clk", "mipi_csi_post_div", base + 0x4640, 0); |
796 | clks[IMX7D_MIPI_DPHY_ROOT_CLK] = imx_clk_gate4("mipi_dphy_root_clk", "mipi_dphy_post_div", base + 0x4660, 0); | 807 | hws[IMX7D_MIPI_DPHY_ROOT_CLK] = imx_clk_hw_gate4("mipi_dphy_root_clk", "mipi_dphy_post_div", base + 0x4660, 0); |
797 | clks[IMX7D_ENET1_IPG_ROOT_CLK] = imx_clk_gate2_shared2("enet1_ipg_root_clk", "enet_axi_post_div", base + 0x4700, 0, &share_count_enet1); | 808 | hws[IMX7D_ENET1_IPG_ROOT_CLK] = imx_clk_hw_gate2_shared2("enet1_ipg_root_clk", "enet_axi_post_div", base + 0x4700, 0, &share_count_enet1); |
798 | clks[IMX7D_ENET1_TIME_ROOT_CLK] = imx_clk_gate2_shared2("enet1_time_root_clk", "enet1_time_post_div", base + 0x4700, 0, &share_count_enet1); | 809 | hws[IMX7D_ENET1_TIME_ROOT_CLK] = imx_clk_hw_gate2_shared2("enet1_time_root_clk", "enet1_time_post_div", base + 0x4700, 0, &share_count_enet1); |
799 | clks[IMX7D_ENET2_IPG_ROOT_CLK] = imx_clk_gate2_shared2("enet2_ipg_root_clk", "enet_axi_post_div", base + 0x4710, 0, &share_count_enet2); | 810 | hws[IMX7D_ENET2_IPG_ROOT_CLK] = imx_clk_hw_gate2_shared2("enet2_ipg_root_clk", "enet_axi_post_div", base + 0x4710, 0, &share_count_enet2); |
800 | clks[IMX7D_ENET2_TIME_ROOT_CLK] = imx_clk_gate2_shared2("enet2_time_root_clk", "enet2_time_post_div", base + 0x4710, 0, &share_count_enet2); | 811 | hws[IMX7D_ENET2_TIME_ROOT_CLK] = imx_clk_hw_gate2_shared2("enet2_time_root_clk", "enet2_time_post_div", base + 0x4710, 0, &share_count_enet2); |
801 | clks[IMX7D_SAI1_ROOT_CLK] = imx_clk_gate2_shared2("sai1_root_clk", "sai1_post_div", base + 0x48c0, 0, &share_count_sai1); | 812 | hws[IMX7D_SAI1_ROOT_CLK] = imx_clk_hw_gate2_shared2("sai1_root_clk", "sai1_post_div", base + 0x48c0, 0, &share_count_sai1); |
802 | clks[IMX7D_SAI1_IPG_CLK] = imx_clk_gate2_shared2("sai1_ipg_clk", "ipg_root_clk", base + 0x48c0, 0, &share_count_sai1); | 813 | hws[IMX7D_SAI1_IPG_CLK] = imx_clk_hw_gate2_shared2("sai1_ipg_clk", "ipg_root_clk", base + 0x48c0, 0, &share_count_sai1); |
803 | clks[IMX7D_SAI2_ROOT_CLK] = imx_clk_gate2_shared2("sai2_root_clk", "sai2_post_div", base + 0x48d0, 0, &share_count_sai2); | 814 | hws[IMX7D_SAI2_ROOT_CLK] = imx_clk_hw_gate2_shared2("sai2_root_clk", "sai2_post_div", base + 0x48d0, 0, &share_count_sai2); |
804 | clks[IMX7D_SAI2_IPG_CLK] = imx_clk_gate2_shared2("sai2_ipg_clk", "ipg_root_clk", base + 0x48d0, 0, &share_count_sai2); | 815 | hws[IMX7D_SAI2_IPG_CLK] = imx_clk_hw_gate2_shared2("sai2_ipg_clk", "ipg_root_clk", base + 0x48d0, 0, &share_count_sai2); |
805 | clks[IMX7D_SAI3_ROOT_CLK] = imx_clk_gate2_shared2("sai3_root_clk", "sai3_post_div", base + 0x48e0, 0, &share_count_sai3); | 816 | hws[IMX7D_SAI3_ROOT_CLK] = imx_clk_hw_gate2_shared2("sai3_root_clk", "sai3_post_div", base + 0x48e0, 0, &share_count_sai3); |
806 | clks[IMX7D_SAI3_IPG_CLK] = imx_clk_gate2_shared2("sai3_ipg_clk", "ipg_root_clk", base + 0x48e0, 0, &share_count_sai3); | 817 | hws[IMX7D_SAI3_IPG_CLK] = imx_clk_hw_gate2_shared2("sai3_ipg_clk", "ipg_root_clk", base + 0x48e0, 0, &share_count_sai3); |
807 | clks[IMX7D_SPDIF_ROOT_CLK] = imx_clk_gate4("spdif_root_clk", "spdif_post_div", base + 0x44d0, 0); | 818 | hws[IMX7D_SPDIF_ROOT_CLK] = imx_clk_hw_gate4("spdif_root_clk", "spdif_post_div", base + 0x44d0, 0); |
808 | clks[IMX7D_EIM_ROOT_CLK] = imx_clk_gate4("eim_root_clk", "eim_post_div", base + 0x4160, 0); | 819 | hws[IMX7D_EIM_ROOT_CLK] = imx_clk_hw_gate4("eim_root_clk", "eim_post_div", base + 0x4160, 0); |
809 | clks[IMX7D_NAND_RAWNAND_CLK] = imx_clk_gate2_shared2("nand_rawnand_clk", "nand_root_clk", base + 0x4140, 0, &share_count_nand); | 820 | hws[IMX7D_NAND_RAWNAND_CLK] = imx_clk_hw_gate2_shared2("nand_rawnand_clk", "nand_root_clk", base + 0x4140, 0, &share_count_nand); |
810 | clks[IMX7D_NAND_USDHC_BUS_RAWNAND_CLK] = imx_clk_gate2_shared2("nand_usdhc_rawnand_clk", "nand_usdhc_root_clk", base + 0x4140, 0, &share_count_nand); | 821 | hws[IMX7D_NAND_USDHC_BUS_RAWNAND_CLK] = imx_clk_hw_gate2_shared2("nand_usdhc_rawnand_clk", "nand_usdhc_root_clk", base + 0x4140, 0, &share_count_nand); |
811 | clks[IMX7D_QSPI_ROOT_CLK] = imx_clk_gate4("qspi_root_clk", "qspi_post_div", base + 0x4150, 0); | 822 | hws[IMX7D_QSPI_ROOT_CLK] = imx_clk_hw_gate4("qspi_root_clk", "qspi_post_div", base + 0x4150, 0); |
812 | clks[IMX7D_USDHC1_ROOT_CLK] = imx_clk_gate4("usdhc1_root_clk", "usdhc1_post_div", base + 0x46c0, 0); | 823 | hws[IMX7D_USDHC1_ROOT_CLK] = imx_clk_hw_gate4("usdhc1_root_clk", "usdhc1_post_div", base + 0x46c0, 0); |
813 | clks[IMX7D_USDHC2_ROOT_CLK] = imx_clk_gate4("usdhc2_root_clk", "usdhc2_post_div", base + 0x46d0, 0); | 824 | hws[IMX7D_USDHC2_ROOT_CLK] = imx_clk_hw_gate4("usdhc2_root_clk", "usdhc2_post_div", base + 0x46d0, 0); |
814 | clks[IMX7D_USDHC3_ROOT_CLK] = imx_clk_gate4("usdhc3_root_clk", "usdhc3_post_div", base + 0x46e0, 0); | 825 | hws[IMX7D_USDHC3_ROOT_CLK] = imx_clk_hw_gate4("usdhc3_root_clk", "usdhc3_post_div", base + 0x46e0, 0); |
815 | clks[IMX7D_CAN1_ROOT_CLK] = imx_clk_gate4("can1_root_clk", "can1_post_div", base + 0x4740, 0); | 826 | hws[IMX7D_CAN1_ROOT_CLK] = imx_clk_hw_gate4("can1_root_clk", "can1_post_div", base + 0x4740, 0); |
816 | clks[IMX7D_CAN2_ROOT_CLK] = imx_clk_gate4("can2_root_clk", "can2_post_div", base + 0x4750, 0); | 827 | hws[IMX7D_CAN2_ROOT_CLK] = imx_clk_hw_gate4("can2_root_clk", "can2_post_div", base + 0x4750, 0); |
817 | clks[IMX7D_I2C1_ROOT_CLK] = imx_clk_gate4("i2c1_root_clk", "i2c1_post_div", base + 0x4880, 0); | 828 | hws[IMX7D_I2C1_ROOT_CLK] = imx_clk_hw_gate4("i2c1_root_clk", "i2c1_post_div", base + 0x4880, 0); |
818 | clks[IMX7D_I2C2_ROOT_CLK] = imx_clk_gate4("i2c2_root_clk", "i2c2_post_div", base + 0x4890, 0); | 829 | hws[IMX7D_I2C2_ROOT_CLK] = imx_clk_hw_gate4("i2c2_root_clk", "i2c2_post_div", base + 0x4890, 0); |
819 | clks[IMX7D_I2C3_ROOT_CLK] = imx_clk_gate4("i2c3_root_clk", "i2c3_post_div", base + 0x48a0, 0); | 830 | hws[IMX7D_I2C3_ROOT_CLK] = imx_clk_hw_gate4("i2c3_root_clk", "i2c3_post_div", base + 0x48a0, 0); |
820 | clks[IMX7D_I2C4_ROOT_CLK] = imx_clk_gate4("i2c4_root_clk", "i2c4_post_div", base + 0x48b0, 0); | 831 | hws[IMX7D_I2C4_ROOT_CLK] = imx_clk_hw_gate4("i2c4_root_clk", "i2c4_post_div", base + 0x48b0, 0); |
821 | clks[IMX7D_UART1_ROOT_CLK] = imx_clk_gate4("uart1_root_clk", "uart1_post_div", base + 0x4940, 0); | 832 | hws[IMX7D_UART1_ROOT_CLK] = imx_clk_hw_gate4("uart1_root_clk", "uart1_post_div", base + 0x4940, 0); |
822 | clks[IMX7D_UART2_ROOT_CLK] = imx_clk_gate4("uart2_root_clk", "uart2_post_div", base + 0x4950, 0); | 833 | hws[IMX7D_UART2_ROOT_CLK] = imx_clk_hw_gate4("uart2_root_clk", "uart2_post_div", base + 0x4950, 0); |
823 | clks[IMX7D_UART3_ROOT_CLK] = imx_clk_gate4("uart3_root_clk", "uart3_post_div", base + 0x4960, 0); | 834 | hws[IMX7D_UART3_ROOT_CLK] = imx_clk_hw_gate4("uart3_root_clk", "uart3_post_div", base + 0x4960, 0); |
824 | clks[IMX7D_UART4_ROOT_CLK] = imx_clk_gate4("uart4_root_clk", "uart4_post_div", base + 0x4970, 0); | 835 | hws[IMX7D_UART4_ROOT_CLK] = imx_clk_hw_gate4("uart4_root_clk", "uart4_post_div", base + 0x4970, 0); |
825 | clks[IMX7D_UART5_ROOT_CLK] = imx_clk_gate4("uart5_root_clk", "uart5_post_div", base + 0x4980, 0); | 836 | hws[IMX7D_UART5_ROOT_CLK] = imx_clk_hw_gate4("uart5_root_clk", "uart5_post_div", base + 0x4980, 0); |
826 | clks[IMX7D_UART6_ROOT_CLK] = imx_clk_gate4("uart6_root_clk", "uart6_post_div", base + 0x4990, 0); | 837 | hws[IMX7D_UART6_ROOT_CLK] = imx_clk_hw_gate4("uart6_root_clk", "uart6_post_div", base + 0x4990, 0); |
827 | clks[IMX7D_UART7_ROOT_CLK] = imx_clk_gate4("uart7_root_clk", "uart7_post_div", base + 0x49a0, 0); | 838 | hws[IMX7D_UART7_ROOT_CLK] = imx_clk_hw_gate4("uart7_root_clk", "uart7_post_div", base + 0x49a0, 0); |
828 | clks[IMX7D_ECSPI1_ROOT_CLK] = imx_clk_gate4("ecspi1_root_clk", "ecspi1_post_div", base + 0x4780, 0); | 839 | hws[IMX7D_ECSPI1_ROOT_CLK] = imx_clk_hw_gate4("ecspi1_root_clk", "ecspi1_post_div", base + 0x4780, 0); |
829 | clks[IMX7D_ECSPI2_ROOT_CLK] = imx_clk_gate4("ecspi2_root_clk", "ecspi2_post_div", base + 0x4790, 0); | 840 | hws[IMX7D_ECSPI2_ROOT_CLK] = imx_clk_hw_gate4("ecspi2_root_clk", "ecspi2_post_div", base + 0x4790, 0); |
830 | clks[IMX7D_ECSPI3_ROOT_CLK] = imx_clk_gate4("ecspi3_root_clk", "ecspi3_post_div", base + 0x47a0, 0); | 841 | hws[IMX7D_ECSPI3_ROOT_CLK] = imx_clk_hw_gate4("ecspi3_root_clk", "ecspi3_post_div", base + 0x47a0, 0); |
831 | clks[IMX7D_ECSPI4_ROOT_CLK] = imx_clk_gate4("ecspi4_root_clk", "ecspi4_post_div", base + 0x47b0, 0); | 842 | hws[IMX7D_ECSPI4_ROOT_CLK] = imx_clk_hw_gate4("ecspi4_root_clk", "ecspi4_post_div", base + 0x47b0, 0); |
832 | clks[IMX7D_PWM1_ROOT_CLK] = imx_clk_gate4("pwm1_root_clk", "pwm1_post_div", base + 0x4840, 0); | 843 | hws[IMX7D_PWM1_ROOT_CLK] = imx_clk_hw_gate4("pwm1_root_clk", "pwm1_post_div", base + 0x4840, 0); |
833 | clks[IMX7D_PWM2_ROOT_CLK] = imx_clk_gate4("pwm2_root_clk", "pwm2_post_div", base + 0x4850, 0); | 844 | hws[IMX7D_PWM2_ROOT_CLK] = imx_clk_hw_gate4("pwm2_root_clk", "pwm2_post_div", base + 0x4850, 0); |
834 | clks[IMX7D_PWM3_ROOT_CLK] = imx_clk_gate4("pwm3_root_clk", "pwm3_post_div", base + 0x4860, 0); | 845 | hws[IMX7D_PWM3_ROOT_CLK] = imx_clk_hw_gate4("pwm3_root_clk", "pwm3_post_div", base + 0x4860, 0); |
835 | clks[IMX7D_PWM4_ROOT_CLK] = imx_clk_gate4("pwm4_root_clk", "pwm4_post_div", base + 0x4870, 0); | 846 | hws[IMX7D_PWM4_ROOT_CLK] = imx_clk_hw_gate4("pwm4_root_clk", "pwm4_post_div", base + 0x4870, 0); |
836 | clks[IMX7D_FLEXTIMER1_ROOT_CLK] = imx_clk_gate4("flextimer1_root_clk", "flextimer1_post_div", base + 0x4800, 0); | 847 | hws[IMX7D_FLEXTIMER1_ROOT_CLK] = imx_clk_hw_gate4("flextimer1_root_clk", "flextimer1_post_div", base + 0x4800, 0); |
837 | clks[IMX7D_FLEXTIMER2_ROOT_CLK] = imx_clk_gate4("flextimer2_root_clk", "flextimer2_post_div", base + 0x4810, 0); | 848 | hws[IMX7D_FLEXTIMER2_ROOT_CLK] = imx_clk_hw_gate4("flextimer2_root_clk", "flextimer2_post_div", base + 0x4810, 0); |
838 | clks[IMX7D_SIM1_ROOT_CLK] = imx_clk_gate4("sim1_root_clk", "sim1_post_div", base + 0x4900, 0); | 849 | hws[IMX7D_SIM1_ROOT_CLK] = imx_clk_hw_gate4("sim1_root_clk", "sim1_post_div", base + 0x4900, 0); |
839 | clks[IMX7D_SIM2_ROOT_CLK] = imx_clk_gate4("sim2_root_clk", "sim2_post_div", base + 0x4910, 0); | 850 | hws[IMX7D_SIM2_ROOT_CLK] = imx_clk_hw_gate4("sim2_root_clk", "sim2_post_div", base + 0x4910, 0); |
840 | clks[IMX7D_GPT1_ROOT_CLK] = imx_clk_gate4("gpt1_root_clk", "gpt1_post_div", base + 0x47c0, 0); | 851 | hws[IMX7D_GPT1_ROOT_CLK] = imx_clk_hw_gate4("gpt1_root_clk", "gpt1_post_div", base + 0x47c0, 0); |
841 | clks[IMX7D_GPT2_ROOT_CLK] = imx_clk_gate4("gpt2_root_clk", "gpt2_post_div", base + 0x47d0, 0); | 852 | hws[IMX7D_GPT2_ROOT_CLK] = imx_clk_hw_gate4("gpt2_root_clk", "gpt2_post_div", base + 0x47d0, 0); |
842 | clks[IMX7D_GPT3_ROOT_CLK] = imx_clk_gate4("gpt3_root_clk", "gpt3_post_div", base + 0x47e0, 0); | 853 | hws[IMX7D_GPT3_ROOT_CLK] = imx_clk_hw_gate4("gpt3_root_clk", "gpt3_post_div", base + 0x47e0, 0); |
843 | clks[IMX7D_GPT4_ROOT_CLK] = imx_clk_gate4("gpt4_root_clk", "gpt4_post_div", base + 0x47f0, 0); | 854 | hws[IMX7D_GPT4_ROOT_CLK] = imx_clk_hw_gate4("gpt4_root_clk", "gpt4_post_div", base + 0x47f0, 0); |
844 | clks[IMX7D_TRACE_ROOT_CLK] = imx_clk_gate4("trace_root_clk", "trace_post_div", base + 0x4300, 0); | 855 | hws[IMX7D_TRACE_ROOT_CLK] = imx_clk_hw_gate4("trace_root_clk", "trace_post_div", base + 0x4300, 0); |
845 | clks[IMX7D_WDOG1_ROOT_CLK] = imx_clk_gate4("wdog1_root_clk", "wdog_post_div", base + 0x49c0, 0); | 856 | hws[IMX7D_WDOG1_ROOT_CLK] = imx_clk_hw_gate4("wdog1_root_clk", "wdog_post_div", base + 0x49c0, 0); |
846 | clks[IMX7D_WDOG2_ROOT_CLK] = imx_clk_gate4("wdog2_root_clk", "wdog_post_div", base + 0x49d0, 0); | 857 | hws[IMX7D_WDOG2_ROOT_CLK] = imx_clk_hw_gate4("wdog2_root_clk", "wdog_post_div", base + 0x49d0, 0); |
847 | clks[IMX7D_WDOG3_ROOT_CLK] = imx_clk_gate4("wdog3_root_clk", "wdog_post_div", base + 0x49e0, 0); | 858 | hws[IMX7D_WDOG3_ROOT_CLK] = imx_clk_hw_gate4("wdog3_root_clk", "wdog_post_div", base + 0x49e0, 0); |
848 | clks[IMX7D_WDOG4_ROOT_CLK] = imx_clk_gate4("wdog4_root_clk", "wdog_post_div", base + 0x49f0, 0); | 859 | hws[IMX7D_WDOG4_ROOT_CLK] = imx_clk_hw_gate4("wdog4_root_clk", "wdog_post_div", base + 0x49f0, 0); |
849 | clks[IMX7D_KPP_ROOT_CLK] = imx_clk_gate4("kpp_root_clk", "ipg_root_clk", base + 0x4aa0, 0); | 860 | hws[IMX7D_KPP_ROOT_CLK] = imx_clk_hw_gate4("kpp_root_clk", "ipg_root_clk", base + 0x4aa0, 0); |
850 | clks[IMX7D_CSI_MCLK_ROOT_CLK] = imx_clk_gate4("csi_mclk_root_clk", "csi_mclk_post_div", base + 0x4490, 0); | 861 | hws[IMX7D_CSI_MCLK_ROOT_CLK] = imx_clk_hw_gate4("csi_mclk_root_clk", "csi_mclk_post_div", base + 0x4490, 0); |
851 | clks[IMX7D_AUDIO_MCLK_ROOT_CLK] = imx_clk_gate4("audio_mclk_root_clk", "audio_mclk_post_div", base + 0x4790, 0); | 862 | hws[IMX7D_AUDIO_MCLK_ROOT_CLK] = imx_clk_hw_gate4("audio_mclk_root_clk", "audio_mclk_post_div", base + 0x4790, 0); |
852 | clks[IMX7D_WRCLK_ROOT_CLK] = imx_clk_gate4("wrclk_root_clk", "wrclk_post_div", base + 0x47a0, 0); | 863 | hws[IMX7D_WRCLK_ROOT_CLK] = imx_clk_hw_gate4("wrclk_root_clk", "wrclk_post_div", base + 0x47a0, 0); |
853 | clks[IMX7D_USB_CTRL_CLK] = imx_clk_gate4("usb_ctrl_clk", "ahb_root_clk", base + 0x4680, 0); | 864 | hws[IMX7D_USB_CTRL_CLK] = imx_clk_hw_gate4("usb_ctrl_clk", "ahb_root_clk", base + 0x4680, 0); |
854 | clks[IMX7D_USB_PHY1_CLK] = imx_clk_gate4("usb_phy1_clk", "pll_usb1_main_clk", base + 0x46a0, 0); | 865 | hws[IMX7D_USB_PHY1_CLK] = imx_clk_hw_gate4("usb_phy1_clk", "pll_usb1_main_clk", base + 0x46a0, 0); |
855 | clks[IMX7D_USB_PHY2_CLK] = imx_clk_gate4("usb_phy2_clk", "pll_usb_main_clk", base + 0x46b0, 0); | 866 | hws[IMX7D_USB_PHY2_CLK] = imx_clk_hw_gate4("usb_phy2_clk", "pll_usb_main_clk", base + 0x46b0, 0); |
856 | clks[IMX7D_ADC_ROOT_CLK] = imx_clk_gate4("adc_root_clk", "ipg_root_clk", base + 0x4200, 0); | 867 | hws[IMX7D_ADC_ROOT_CLK] = imx_clk_hw_gate4("adc_root_clk", "ipg_root_clk", base + 0x4200, 0); |
857 | 868 | ||
858 | clks[IMX7D_GPT_3M_CLK] = imx_clk_fixed_factor("gpt_3m", "osc", 1, 8); | 869 | hws[IMX7D_GPT_3M_CLK] = imx_clk_hw_fixed_factor("gpt_3m", "osc", 1, 8); |
859 | 870 | ||
860 | clks[IMX7D_CLK_ARM] = imx_clk_cpu("arm", "arm_a7_root_clk", | 871 | hws[IMX7D_CLK_ARM] = imx_clk_hw_cpu("arm", "arm_a7_root_clk", |
861 | clks[IMX7D_ARM_A7_ROOT_CLK], | 872 | hws[IMX7D_ARM_A7_ROOT_CLK]->clk, |
862 | clks[IMX7D_ARM_A7_ROOT_SRC], | 873 | hws[IMX7D_ARM_A7_ROOT_SRC]->clk, |
863 | clks[IMX7D_PLL_ARM_MAIN_CLK], | 874 | hws[IMX7D_PLL_ARM_MAIN_CLK]->clk, |
864 | clks[IMX7D_PLL_SYS_MAIN_CLK]); | 875 | hws[IMX7D_PLL_SYS_MAIN_CLK]->clk); |
865 | 876 | ||
866 | imx_check_clocks(clks, ARRAY_SIZE(clks)); | 877 | imx_check_clk_hws(hws, IMX7D_CLK_END); |
867 | 878 | ||
868 | clk_data.clks = clks; | 879 | of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data); |
869 | clk_data.clk_num = ARRAY_SIZE(clks); | 880 | |
870 | of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); | 881 | clk_set_parent(hws[IMX7D_PLL_ARM_MAIN_BYPASS]->clk, hws[IMX7D_PLL_ARM_MAIN]->clk); |
871 | 882 | clk_set_parent(hws[IMX7D_PLL_DRAM_MAIN_BYPASS]->clk, hws[IMX7D_PLL_DRAM_MAIN]->clk); | |
872 | clk_set_parent(clks[IMX7D_PLL_ARM_MAIN_BYPASS], clks[IMX7D_PLL_ARM_MAIN]); | 883 | clk_set_parent(hws[IMX7D_PLL_SYS_MAIN_BYPASS]->clk, hws[IMX7D_PLL_SYS_MAIN]->clk); |
873 | clk_set_parent(clks[IMX7D_PLL_DRAM_MAIN_BYPASS], clks[IMX7D_PLL_DRAM_MAIN]); | 884 | clk_set_parent(hws[IMX7D_PLL_ENET_MAIN_BYPASS]->clk, hws[IMX7D_PLL_ENET_MAIN]->clk); |
874 | clk_set_parent(clks[IMX7D_PLL_SYS_MAIN_BYPASS], clks[IMX7D_PLL_SYS_MAIN]); | 885 | clk_set_parent(hws[IMX7D_PLL_AUDIO_MAIN_BYPASS]->clk, hws[IMX7D_PLL_AUDIO_MAIN]->clk); |
875 | clk_set_parent(clks[IMX7D_PLL_ENET_MAIN_BYPASS], clks[IMX7D_PLL_ENET_MAIN]); | 886 | clk_set_parent(hws[IMX7D_PLL_VIDEO_MAIN_BYPASS]->clk, hws[IMX7D_PLL_VIDEO_MAIN]->clk); |
876 | clk_set_parent(clks[IMX7D_PLL_AUDIO_MAIN_BYPASS], clks[IMX7D_PLL_AUDIO_MAIN]); | 887 | |
877 | clk_set_parent(clks[IMX7D_PLL_VIDEO_MAIN_BYPASS], clks[IMX7D_PLL_VIDEO_MAIN]); | 888 | clk_set_parent(hws[IMX7D_MIPI_CSI_ROOT_SRC]->clk, hws[IMX7D_PLL_SYS_PFD3_CLK]->clk); |
878 | |||
879 | clk_set_parent(clks[IMX7D_MIPI_CSI_ROOT_SRC], clks[IMX7D_PLL_SYS_PFD3_CLK]); | ||
880 | 889 | ||
881 | /* use old gpt clk setting, gpt1 root clk must be twice as gpt counter freq */ | 890 | /* use old gpt clk setting, gpt1 root clk must be twice as gpt counter freq */ |
882 | clk_set_parent(clks[IMX7D_GPT1_ROOT_SRC], clks[IMX7D_OSC_24M_CLK]); | 891 | clk_set_parent(hws[IMX7D_GPT1_ROOT_SRC]->clk, hws[IMX7D_OSC_24M_CLK]->clk); |
883 | 892 | ||
884 | /* Set clock rate for USBPHY, the USB_PLL at CCM is from USBOTG2 */ | 893 | /* Set clock rate for USBPHY, the USB_PLL at CCM is from USBOTG2 */ |
885 | clks[IMX7D_USB1_MAIN_480M_CLK] = imx_clk_fixed_factor("pll_usb1_main_clk", "osc", 20, 1); | 894 | hws[IMX7D_USB1_MAIN_480M_CLK] = imx_clk_hw_fixed_factor("pll_usb1_main_clk", "osc", 20, 1); |
886 | clks[IMX7D_USB_MAIN_480M_CLK] = imx_clk_fixed_factor("pll_usb_main_clk", "osc", 20, 1); | 895 | hws[IMX7D_USB_MAIN_480M_CLK] = imx_clk_hw_fixed_factor("pll_usb_main_clk", "osc", 20, 1); |
896 | |||
897 | for (i = 0; i < ARRAY_SIZE(uart_clk_ids); i++) { | ||
898 | int index = uart_clk_ids[i]; | ||
899 | |||
900 | uart_clks[i] = &hws[index]->clk; | ||
901 | } | ||
902 | |||
887 | 903 | ||
888 | imx_register_uart_clocks(uart_clks); | 904 | imx_register_uart_clocks(uart_clks); |
889 | 905 | ||
diff --git a/drivers/clk/imx/clk-imx7ulp.c b/drivers/clk/imx/clk-imx7ulp.c index 66682100f14c..42e4667f22fd 100644 --- a/drivers/clk/imx/clk-imx7ulp.c +++ b/drivers/clk/imx/clk-imx7ulp.c | |||
@@ -115,7 +115,7 @@ static void __init imx7ulp_clk_scg1_init(struct device_node *np) | |||
115 | 115 | ||
116 | clks[IMX7ULP_CLK_NIC0_DIV] = imx_clk_hw_divider_flags("nic0_clk", "nic_sel", base + 0x40, 24, 4, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL); | 116 | clks[IMX7ULP_CLK_NIC0_DIV] = imx_clk_hw_divider_flags("nic0_clk", "nic_sel", base + 0x40, 24, 4, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL); |
117 | clks[IMX7ULP_CLK_NIC1_DIV] = imx_clk_hw_divider_flags("nic1_clk", "nic0_clk", base + 0x40, 16, 4, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL); | 117 | clks[IMX7ULP_CLK_NIC1_DIV] = imx_clk_hw_divider_flags("nic1_clk", "nic0_clk", base + 0x40, 16, 4, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL); |
118 | clks[IMX7ULP_CLK_NIC1_BUS_DIV] = imx_clk_hw_divider_flags("nic1_bus_clk", "nic1_clk", base + 0x40, 4, 4, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL); | 118 | clks[IMX7ULP_CLK_NIC1_BUS_DIV] = imx_clk_hw_divider_flags("nic1_bus_clk", "nic0_clk", base + 0x40, 4, 4, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL); |
119 | 119 | ||
120 | clks[IMX7ULP_CLK_GPU_DIV] = imx_clk_hw_divider("gpu_clk", "nic0_clk", base + 0x40, 20, 4); | 120 | clks[IMX7ULP_CLK_GPU_DIV] = imx_clk_hw_divider("gpu_clk", "nic0_clk", base + 0x40, 20, 4); |
121 | 121 | ||
diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c index 122a81ab8e48..6b8e75df994d 100644 --- a/drivers/clk/imx/clk-imx8mm.c +++ b/drivers/clk/imx/clk-imx8mm.c | |||
@@ -288,6 +288,9 @@ static const char *imx8mm_usb_core_sels[] = {"osc_24m", "sys_pll1_100m", "sys_pl | |||
288 | static const char *imx8mm_usb_phy_sels[] = {"osc_24m", "sys_pll1_100m", "sys_pll1_40m", "sys_pll2_100m", | 288 | static const char *imx8mm_usb_phy_sels[] = {"osc_24m", "sys_pll1_100m", "sys_pll1_40m", "sys_pll2_100m", |
289 | "sys_pll2_200m", "clk_ext2", "clk_ext3", "audio_pll2_out", }; | 289 | "sys_pll2_200m", "clk_ext2", "clk_ext3", "audio_pll2_out", }; |
290 | 290 | ||
291 | static const char *imx8mm_gic_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m", "sys_pll2_100m", | ||
292 | "sys_pll1_800m", "clk_ext2", "clk_ext4", "audio_pll2_out" }; | ||
293 | |||
291 | static const char *imx8mm_ecspi1_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m", "sys_pll1_160m", | 294 | static const char *imx8mm_ecspi1_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m", "sys_pll1_160m", |
292 | "sys_pll1_800m", "sys_pll3_out", "sys_pll2_250m", "audio_pll2_out", }; | 295 | "sys_pll1_800m", "sys_pll3_out", "sys_pll2_250m", "audio_pll2_out", }; |
293 | 296 | ||
@@ -325,7 +328,7 @@ static const char *imx8mm_dsi_dbi_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll | |||
325 | "sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll1_out", }; | 328 | "sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll1_out", }; |
326 | 329 | ||
327 | static const char *imx8mm_usdhc3_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1_800m", "sys_pll2_500m", | 330 | static const char *imx8mm_usdhc3_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1_800m", "sys_pll2_500m", |
328 | "sys_pll3_out", "sys_pll1_266m", "audio_pll2_clk", "sys_pll1_100m", }; | 331 | "sys_pll3_out", "sys_pll1_266m", "audio_pll2_out", "sys_pll1_100m", }; |
329 | 332 | ||
330 | static const char *imx8mm_csi1_core_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m", "sys_pll1_800m", | 333 | static const char *imx8mm_csi1_core_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m", "sys_pll1_800m", |
331 | "sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll1_out", }; | 334 | "sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll1_out", }; |
@@ -361,11 +364,11 @@ static const char *imx8mm_pdm_sels[] = {"osc_24m", "sys_pll2_100m", "audio_pll1_ | |||
361 | "sys_pll2_1000m", "sys_pll3_out", "clk_ext3", "audio_pll2_out", }; | 364 | "sys_pll2_1000m", "sys_pll3_out", "clk_ext3", "audio_pll2_out", }; |
362 | 365 | ||
363 | static const char *imx8mm_vpu_h1_sels[] = {"osc_24m", "vpu_pll_out", "sys_pll1_800m", "sys_pll2_1000m", | 366 | static const char *imx8mm_vpu_h1_sels[] = {"osc_24m", "vpu_pll_out", "sys_pll1_800m", "sys_pll2_1000m", |
364 | "audio_pll2_clk", "sys_pll2_125m", "sys_pll3_clk", "audio_pll1_out", }; | 367 | "audio_pll2_out", "sys_pll2_125m", "sys_pll3_clk", "audio_pll1_out", }; |
365 | 368 | ||
366 | static const char *imx8mm_dram_core_sels[] = {"dram_pll_out", "dram_alt_root", }; | 369 | static const char *imx8mm_dram_core_sels[] = {"dram_pll_out", "dram_alt_root", }; |
367 | 370 | ||
368 | static const char *imx8mm_clko1_sels[] = {"osc_24m", "sys_pll1_800m", "osc_27m", "sys_pll1_200m", "audio_pll2_clk", | 371 | static const char *imx8mm_clko1_sels[] = {"osc_24m", "sys_pll1_800m", "osc_27m", "sys_pll1_200m", "audio_pll2_out", |
369 | "vpu_pll", "sys_pll1_80m", }; | 372 | "vpu_pll", "sys_pll1_80m", }; |
370 | 373 | ||
371 | static struct clk *clks[IMX8MM_CLK_END]; | 374 | static struct clk *clks[IMX8MM_CLK_END]; |
@@ -523,7 +526,7 @@ static int __init imx8mm_clocks_init(struct device_node *ccm_node) | |||
523 | 526 | ||
524 | /* IP */ | 527 | /* IP */ |
525 | clks[IMX8MM_CLK_DRAM_ALT] = imx8m_clk_composite("dram_alt", imx8mm_dram_alt_sels, base + 0xa000); | 528 | clks[IMX8MM_CLK_DRAM_ALT] = imx8m_clk_composite("dram_alt", imx8mm_dram_alt_sels, base + 0xa000); |
526 | clks[IMX8MM_CLK_DRAM_APB] = imx8m_clk_composite("dram_apb", imx8mm_dram_apb_sels, base + 0xa080); | 529 | clks[IMX8MM_CLK_DRAM_APB] = imx8m_clk_composite_critical("dram_apb", imx8mm_dram_apb_sels, base + 0xa080); |
527 | clks[IMX8MM_CLK_VPU_G1] = imx8m_clk_composite("vpu_g1", imx8mm_vpu_g1_sels, base + 0xa100); | 530 | clks[IMX8MM_CLK_VPU_G1] = imx8m_clk_composite("vpu_g1", imx8mm_vpu_g1_sels, base + 0xa100); |
528 | clks[IMX8MM_CLK_VPU_G2] = imx8m_clk_composite("vpu_g2", imx8mm_vpu_g2_sels, base + 0xa180); | 531 | clks[IMX8MM_CLK_VPU_G2] = imx8m_clk_composite("vpu_g2", imx8mm_vpu_g2_sels, base + 0xa180); |
529 | clks[IMX8MM_CLK_DISP_DTRC] = imx8m_clk_composite("disp_dtrc", imx8mm_disp_dtrc_sels, base + 0xa200); | 532 | clks[IMX8MM_CLK_DISP_DTRC] = imx8m_clk_composite("disp_dtrc", imx8mm_disp_dtrc_sels, base + 0xa200); |
@@ -558,6 +561,7 @@ static int __init imx8mm_clocks_init(struct device_node *ccm_node) | |||
558 | clks[IMX8MM_CLK_UART4] = imx8m_clk_composite("uart4", imx8mm_uart4_sels, base + 0xb080); | 561 | clks[IMX8MM_CLK_UART4] = imx8m_clk_composite("uart4", imx8mm_uart4_sels, base + 0xb080); |
559 | clks[IMX8MM_CLK_USB_CORE_REF] = imx8m_clk_composite("usb_core_ref", imx8mm_usb_core_sels, base + 0xb100); | 562 | clks[IMX8MM_CLK_USB_CORE_REF] = imx8m_clk_composite("usb_core_ref", imx8mm_usb_core_sels, base + 0xb100); |
560 | clks[IMX8MM_CLK_USB_PHY_REF] = imx8m_clk_composite("usb_phy_ref", imx8mm_usb_phy_sels, base + 0xb180); | 563 | clks[IMX8MM_CLK_USB_PHY_REF] = imx8m_clk_composite("usb_phy_ref", imx8mm_usb_phy_sels, base + 0xb180); |
564 | clks[IMX8MM_CLK_GIC] = imx8m_clk_composite_critical("gic", imx8mm_gic_sels, base + 0xb200); | ||
561 | clks[IMX8MM_CLK_ECSPI1] = imx8m_clk_composite("ecspi1", imx8mm_ecspi1_sels, base + 0xb280); | 565 | clks[IMX8MM_CLK_ECSPI1] = imx8m_clk_composite("ecspi1", imx8mm_ecspi1_sels, base + 0xb280); |
562 | clks[IMX8MM_CLK_ECSPI2] = imx8m_clk_composite("ecspi2", imx8mm_ecspi2_sels, base + 0xb300); | 566 | clks[IMX8MM_CLK_ECSPI2] = imx8m_clk_composite("ecspi2", imx8mm_ecspi2_sels, base + 0xb300); |
563 | clks[IMX8MM_CLK_PWM1] = imx8m_clk_composite("pwm1", imx8mm_pwm1_sels, base + 0xb380); | 567 | clks[IMX8MM_CLK_PWM1] = imx8m_clk_composite("pwm1", imx8mm_pwm1_sels, base + 0xb380); |
@@ -590,6 +594,11 @@ static int __init imx8mm_clocks_init(struct device_node *ccm_node) | |||
590 | clks[IMX8MM_CLK_ECSPI2_ROOT] = imx_clk_gate4("ecspi2_root_clk", "ecspi2", base + 0x4080, 0); | 594 | clks[IMX8MM_CLK_ECSPI2_ROOT] = imx_clk_gate4("ecspi2_root_clk", "ecspi2", base + 0x4080, 0); |
591 | clks[IMX8MM_CLK_ECSPI3_ROOT] = imx_clk_gate4("ecspi3_root_clk", "ecspi3", base + 0x4090, 0); | 595 | clks[IMX8MM_CLK_ECSPI3_ROOT] = imx_clk_gate4("ecspi3_root_clk", "ecspi3", base + 0x4090, 0); |
592 | clks[IMX8MM_CLK_ENET1_ROOT] = imx_clk_gate4("enet1_root_clk", "enet_axi", base + 0x40a0, 0); | 596 | clks[IMX8MM_CLK_ENET1_ROOT] = imx_clk_gate4("enet1_root_clk", "enet_axi", base + 0x40a0, 0); |
597 | clks[IMX8MM_CLK_GPIO1_ROOT] = imx_clk_gate4("gpio1_root_clk", "ipg_root", base + 0x40b0, 0); | ||
598 | clks[IMX8MM_CLK_GPIO2_ROOT] = imx_clk_gate4("gpio2_root_clk", "ipg_root", base + 0x40c0, 0); | ||
599 | clks[IMX8MM_CLK_GPIO3_ROOT] = imx_clk_gate4("gpio3_root_clk", "ipg_root", base + 0x40d0, 0); | ||
600 | clks[IMX8MM_CLK_GPIO4_ROOT] = imx_clk_gate4("gpio4_root_clk", "ipg_root", base + 0x40e0, 0); | ||
601 | clks[IMX8MM_CLK_GPIO5_ROOT] = imx_clk_gate4("gpio5_root_clk", "ipg_root", base + 0x40f0, 0); | ||
593 | clks[IMX8MM_CLK_GPT1_ROOT] = imx_clk_gate4("gpt1_root_clk", "gpt1", base + 0x4100, 0); | 602 | clks[IMX8MM_CLK_GPT1_ROOT] = imx_clk_gate4("gpt1_root_clk", "gpt1", base + 0x4100, 0); |
594 | clks[IMX8MM_CLK_I2C1_ROOT] = imx_clk_gate4("i2c1_root_clk", "i2c1", base + 0x4170, 0); | 603 | clks[IMX8MM_CLK_I2C1_ROOT] = imx_clk_gate4("i2c1_root_clk", "i2c1", base + 0x4170, 0); |
595 | clks[IMX8MM_CLK_I2C2_ROOT] = imx_clk_gate4("i2c2_root_clk", "i2c2", base + 0x4180, 0); | 604 | clks[IMX8MM_CLK_I2C2_ROOT] = imx_clk_gate4("i2c2_root_clk", "i2c2", base + 0x4180, 0); |
@@ -617,6 +626,7 @@ static int __init imx8mm_clocks_init(struct device_node *ccm_node) | |||
617 | clks[IMX8MM_CLK_SAI5_IPG] = imx_clk_gate2_shared2("sai5_ipg_clk", "ipg_audio_root", base + 0x4370, 0, &share_count_sai5); | 626 | clks[IMX8MM_CLK_SAI5_IPG] = imx_clk_gate2_shared2("sai5_ipg_clk", "ipg_audio_root", base + 0x4370, 0, &share_count_sai5); |
618 | clks[IMX8MM_CLK_SAI6_ROOT] = imx_clk_gate2_shared2("sai6_root_clk", "sai6", base + 0x4380, 0, &share_count_sai6); | 627 | clks[IMX8MM_CLK_SAI6_ROOT] = imx_clk_gate2_shared2("sai6_root_clk", "sai6", base + 0x4380, 0, &share_count_sai6); |
619 | clks[IMX8MM_CLK_SAI6_IPG] = imx_clk_gate2_shared2("sai6_ipg_clk", "ipg_audio_root", base + 0x4380, 0, &share_count_sai6); | 628 | clks[IMX8MM_CLK_SAI6_IPG] = imx_clk_gate2_shared2("sai6_ipg_clk", "ipg_audio_root", base + 0x4380, 0, &share_count_sai6); |
629 | clks[IMX8MM_CLK_SNVS_ROOT] = imx_clk_gate4("snvs_root_clk", "ipg_root", base + 0x4470, 0); | ||
620 | clks[IMX8MM_CLK_UART1_ROOT] = imx_clk_gate4("uart1_root_clk", "uart1", base + 0x4490, 0); | 630 | clks[IMX8MM_CLK_UART1_ROOT] = imx_clk_gate4("uart1_root_clk", "uart1", base + 0x4490, 0); |
621 | clks[IMX8MM_CLK_UART2_ROOT] = imx_clk_gate4("uart2_root_clk", "uart2", base + 0x44a0, 0); | 631 | clks[IMX8MM_CLK_UART2_ROOT] = imx_clk_gate4("uart2_root_clk", "uart2", base + 0x44a0, 0); |
622 | clks[IMX8MM_CLK_UART3_ROOT] = imx_clk_gate4("uart3_root_clk", "uart3", base + 0x44b0, 0); | 632 | clks[IMX8MM_CLK_UART3_ROOT] = imx_clk_gate4("uart3_root_clk", "uart3", base + 0x44b0, 0); |
diff --git a/drivers/clk/imx/clk-imx8mq.c b/drivers/clk/imx/clk-imx8mq.c index daf1841b2adb..d407a07e7e6d 100644 --- a/drivers/clk/imx/clk-imx8mq.c +++ b/drivers/clk/imx/clk-imx8mq.c | |||
@@ -192,6 +192,9 @@ static const char * const imx8mq_usb_core_sels[] = {"osc_25m", "sys1_pll_100m", | |||
192 | static const char * const imx8mq_usb_phy_sels[] = {"osc_25m", "sys1_pll_100m", "sys1_pll_40m", "sys2_pll_100m", | 192 | static const char * const imx8mq_usb_phy_sels[] = {"osc_25m", "sys1_pll_100m", "sys1_pll_40m", "sys2_pll_100m", |
193 | "sys2_pll_200m", "clk_ext2", "clk_ext3", "audio_pll2_out", }; | 193 | "sys2_pll_200m", "clk_ext2", "clk_ext3", "audio_pll2_out", }; |
194 | 194 | ||
195 | static const char * const imx8mq_gic_sels[] = {"osc_25m", "sys2_pll_200m", "sys1_pll_40m", "sys2_pll_100m", | ||
196 | "sys2_pll_200m", "clk_ext2", "clk_ext3", "audio_pll2_out" }; | ||
197 | |||
195 | static const char * const imx8mq_ecspi1_sels[] = {"osc_25m", "sys2_pll_200m", "sys1_pll_40m", "sys1_pll_160m", | 198 | static const char * const imx8mq_ecspi1_sels[] = {"osc_25m", "sys2_pll_200m", "sys1_pll_40m", "sys1_pll_160m", |
196 | "sys1_pll_800m", "sys3_pll2_out", "sys2_pll_250m", "audio_pll2_out", }; | 199 | "sys1_pll_800m", "sys3_pll2_out", "sys2_pll_250m", "audio_pll2_out", }; |
197 | 200 | ||
@@ -269,13 +272,20 @@ static const char * const imx8mq_clko2_sels[] = {"osc_25m", "sys2_pll_200m", "sy | |||
269 | 272 | ||
270 | static struct clk_onecell_data clk_data; | 273 | static struct clk_onecell_data clk_data; |
271 | 274 | ||
275 | static struct clk ** const uart_clks[] = { | ||
276 | &clks[IMX8MQ_CLK_UART1_ROOT], | ||
277 | &clks[IMX8MQ_CLK_UART2_ROOT], | ||
278 | &clks[IMX8MQ_CLK_UART3_ROOT], | ||
279 | &clks[IMX8MQ_CLK_UART4_ROOT], | ||
280 | NULL | ||
281 | }; | ||
282 | |||
272 | static int imx8mq_clocks_probe(struct platform_device *pdev) | 283 | static int imx8mq_clocks_probe(struct platform_device *pdev) |
273 | { | 284 | { |
274 | struct device *dev = &pdev->dev; | 285 | struct device *dev = &pdev->dev; |
275 | struct device_node *np = dev->of_node; | 286 | struct device_node *np = dev->of_node; |
276 | void __iomem *base; | 287 | void __iomem *base; |
277 | int err; | 288 | int err; |
278 | int i; | ||
279 | 289 | ||
280 | clks[IMX8MQ_CLK_DUMMY] = imx_clk_fixed("dummy", 0); | 290 | clks[IMX8MQ_CLK_DUMMY] = imx_clk_fixed("dummy", 0); |
281 | clks[IMX8MQ_CLK_32K] = of_clk_get_by_name(np, "ckil"); | 291 | clks[IMX8MQ_CLK_32K] = of_clk_get_by_name(np, "ckil"); |
@@ -358,9 +368,9 @@ static int imx8mq_clocks_probe(struct platform_device *pdev) | |||
358 | clks[IMX8MQ_SYS2_PLL_1000M] = imx_clk_fixed_factor("sys2_pll_1000m", "sys2_pll_out", 1, 1); | 368 | clks[IMX8MQ_SYS2_PLL_1000M] = imx_clk_fixed_factor("sys2_pll_1000m", "sys2_pll_out", 1, 1); |
359 | 369 | ||
360 | np = dev->of_node; | 370 | np = dev->of_node; |
361 | base = of_iomap(np, 0); | 371 | base = devm_platform_ioremap_resource(pdev, 0); |
362 | if (WARN_ON(!base)) | 372 | if (WARN_ON(IS_ERR(base))) |
363 | return -ENOMEM; | 373 | return PTR_ERR(base); |
364 | 374 | ||
365 | /* CORE */ | 375 | /* CORE */ |
366 | clks[IMX8MQ_CLK_A53_SRC] = imx_clk_mux2("arm_a53_src", base + 0x8000, 24, 3, imx8mq_a53_sels, ARRAY_SIZE(imx8mq_a53_sels)); | 376 | clks[IMX8MQ_CLK_A53_SRC] = imx_clk_mux2("arm_a53_src", base + 0x8000, 24, 3, imx8mq_a53_sels, ARRAY_SIZE(imx8mq_a53_sels)); |
@@ -442,6 +452,7 @@ static int imx8mq_clocks_probe(struct platform_device *pdev) | |||
442 | clks[IMX8MQ_CLK_UART4] = imx8m_clk_composite("uart4", imx8mq_uart4_sels, base + 0xb080); | 452 | clks[IMX8MQ_CLK_UART4] = imx8m_clk_composite("uart4", imx8mq_uart4_sels, base + 0xb080); |
443 | clks[IMX8MQ_CLK_USB_CORE_REF] = imx8m_clk_composite("usb_core_ref", imx8mq_usb_core_sels, base + 0xb100); | 453 | clks[IMX8MQ_CLK_USB_CORE_REF] = imx8m_clk_composite("usb_core_ref", imx8mq_usb_core_sels, base + 0xb100); |
444 | clks[IMX8MQ_CLK_USB_PHY_REF] = imx8m_clk_composite("usb_phy_ref", imx8mq_usb_phy_sels, base + 0xb180); | 454 | clks[IMX8MQ_CLK_USB_PHY_REF] = imx8m_clk_composite("usb_phy_ref", imx8mq_usb_phy_sels, base + 0xb180); |
455 | clks[IMX8MQ_CLK_GIC] = imx8m_clk_composite_critical("gic", imx8mq_gic_sels, base + 0xb200); | ||
445 | clks[IMX8MQ_CLK_ECSPI1] = imx8m_clk_composite("ecspi1", imx8mq_ecspi1_sels, base + 0xb280); | 456 | clks[IMX8MQ_CLK_ECSPI1] = imx8m_clk_composite("ecspi1", imx8mq_ecspi1_sels, base + 0xb280); |
446 | clks[IMX8MQ_CLK_ECSPI2] = imx8m_clk_composite("ecspi2", imx8mq_ecspi2_sels, base + 0xb300); | 457 | clks[IMX8MQ_CLK_ECSPI2] = imx8m_clk_composite("ecspi2", imx8mq_ecspi2_sels, base + 0xb300); |
447 | clks[IMX8MQ_CLK_PWM1] = imx8m_clk_composite("pwm1", imx8mq_pwm1_sels, base + 0xb380); | 458 | clks[IMX8MQ_CLK_PWM1] = imx8m_clk_composite("pwm1", imx8mq_pwm1_sels, base + 0xb380); |
@@ -507,6 +518,7 @@ static int imx8mq_clocks_probe(struct platform_device *pdev) | |||
507 | clks[IMX8MQ_CLK_SAI5_IPG] = imx_clk_gate2_shared2("sai5_ipg_clk", "ipg_audio_root", base + 0x4370, 0, &share_count_sai5); | 518 | clks[IMX8MQ_CLK_SAI5_IPG] = imx_clk_gate2_shared2("sai5_ipg_clk", "ipg_audio_root", base + 0x4370, 0, &share_count_sai5); |
508 | clks[IMX8MQ_CLK_SAI6_ROOT] = imx_clk_gate2_shared2("sai6_root_clk", "sai6", base + 0x4380, 0, &share_count_sai6); | 519 | clks[IMX8MQ_CLK_SAI6_ROOT] = imx_clk_gate2_shared2("sai6_root_clk", "sai6", base + 0x4380, 0, &share_count_sai6); |
509 | clks[IMX8MQ_CLK_SAI6_IPG] = imx_clk_gate2_shared2("sai6_ipg_clk", "ipg_audio_root", base + 0x4380, 0, &share_count_sai6); | 520 | clks[IMX8MQ_CLK_SAI6_IPG] = imx_clk_gate2_shared2("sai6_ipg_clk", "ipg_audio_root", base + 0x4380, 0, &share_count_sai6); |
521 | clks[IMX8MQ_CLK_SNVS_ROOT] = imx_clk_gate4("snvs_root_clk", "ipg_root", base + 0x4470, 0); | ||
510 | clks[IMX8MQ_CLK_UART1_ROOT] = imx_clk_gate4("uart1_root_clk", "uart1", base + 0x4490, 0); | 522 | clks[IMX8MQ_CLK_UART1_ROOT] = imx_clk_gate4("uart1_root_clk", "uart1", base + 0x4490, 0); |
511 | clks[IMX8MQ_CLK_UART2_ROOT] = imx_clk_gate4("uart2_root_clk", "uart2", base + 0x44a0, 0); | 523 | clks[IMX8MQ_CLK_UART2_ROOT] = imx_clk_gate4("uart2_root_clk", "uart2", base + 0x44a0, 0); |
512 | clks[IMX8MQ_CLK_UART3_ROOT] = imx_clk_gate4("uart3_root_clk", "uart3", base + 0x44b0, 0); | 524 | clks[IMX8MQ_CLK_UART3_ROOT] = imx_clk_gate4("uart3_root_clk", "uart3", base + 0x44b0, 0); |
@@ -543,10 +555,7 @@ static int imx8mq_clocks_probe(struct platform_device *pdev) | |||
543 | clks[IMX8MQ_ARM_PLL_OUT], | 555 | clks[IMX8MQ_ARM_PLL_OUT], |
544 | clks[IMX8MQ_SYS1_PLL_800M]); | 556 | clks[IMX8MQ_SYS1_PLL_800M]); |
545 | 557 | ||
546 | for (i = 0; i < IMX8MQ_CLK_END; i++) | 558 | imx_check_clocks(clks, ARRAY_SIZE(clks)); |
547 | if (IS_ERR(clks[i])) | ||
548 | pr_err("i.MX8mq clk %u register failed with %ld\n", | ||
549 | i, PTR_ERR(clks[i])); | ||
550 | 559 | ||
551 | clk_data.clks = clks; | 560 | clk_data.clks = clks; |
552 | clk_data.clk_num = ARRAY_SIZE(clks); | 561 | clk_data.clk_num = ARRAY_SIZE(clks); |
@@ -554,6 +563,8 @@ static int imx8mq_clocks_probe(struct platform_device *pdev) | |||
554 | err = of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); | 563 | err = of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); |
555 | WARN_ON(err); | 564 | WARN_ON(err); |
556 | 565 | ||
566 | imx_register_uart_clocks(uart_clks); | ||
567 | |||
557 | return err; | 568 | return err; |
558 | } | 569 | } |
559 | 570 | ||
diff --git a/drivers/clk/imx/clk-pfd.c b/drivers/clk/imx/clk-pfd.c index fa82ddea4996..50b7c30296f7 100644 --- a/drivers/clk/imx/clk-pfd.c +++ b/drivers/clk/imx/clk-pfd.c | |||
@@ -121,12 +121,13 @@ static const struct clk_ops clk_pfd_ops = { | |||
121 | .is_enabled = clk_pfd_is_enabled, | 121 | .is_enabled = clk_pfd_is_enabled, |
122 | }; | 122 | }; |
123 | 123 | ||
124 | struct clk *imx_clk_pfd(const char *name, const char *parent_name, | 124 | struct clk_hw *imx_clk_hw_pfd(const char *name, const char *parent_name, |
125 | void __iomem *reg, u8 idx) | 125 | void __iomem *reg, u8 idx) |
126 | { | 126 | { |
127 | struct clk_pfd *pfd; | 127 | struct clk_pfd *pfd; |
128 | struct clk *clk; | 128 | struct clk_hw *hw; |
129 | struct clk_init_data init; | 129 | struct clk_init_data init; |
130 | int ret; | ||
130 | 131 | ||
131 | pfd = kzalloc(sizeof(*pfd), GFP_KERNEL); | 132 | pfd = kzalloc(sizeof(*pfd), GFP_KERNEL); |
132 | if (!pfd) | 133 | if (!pfd) |
@@ -142,10 +143,13 @@ struct clk *imx_clk_pfd(const char *name, const char *parent_name, | |||
142 | init.num_parents = 1; | 143 | init.num_parents = 1; |
143 | 144 | ||
144 | pfd->hw.init = &init; | 145 | pfd->hw.init = &init; |
146 | hw = &pfd->hw; | ||
145 | 147 | ||
146 | clk = clk_register(NULL, &pfd->hw); | 148 | ret = clk_hw_register(NULL, hw); |
147 | if (IS_ERR(clk)) | 149 | if (ret) { |
148 | kfree(pfd); | 150 | kfree(pfd); |
151 | return ERR_PTR(ret); | ||
152 | } | ||
149 | 153 | ||
150 | return clk; | 154 | return hw; |
151 | } | 155 | } |
diff --git a/drivers/clk/imx/clk-pllv3.c b/drivers/clk/imx/clk-pllv3.c index 93b059608d3c..df91a8244fb4 100644 --- a/drivers/clk/imx/clk-pllv3.c +++ b/drivers/clk/imx/clk-pllv3.c | |||
@@ -410,14 +410,15 @@ static const struct clk_ops clk_pllv3_enet_ops = { | |||
410 | .recalc_rate = clk_pllv3_enet_recalc_rate, | 410 | .recalc_rate = clk_pllv3_enet_recalc_rate, |
411 | }; | 411 | }; |
412 | 412 | ||
413 | struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name, | 413 | struct clk_hw *imx_clk_hw_pllv3(enum imx_pllv3_type type, const char *name, |
414 | const char *parent_name, void __iomem *base, | 414 | const char *parent_name, void __iomem *base, |
415 | u32 div_mask) | 415 | u32 div_mask) |
416 | { | 416 | { |
417 | struct clk_pllv3 *pll; | 417 | struct clk_pllv3 *pll; |
418 | const struct clk_ops *ops; | 418 | const struct clk_ops *ops; |
419 | struct clk *clk; | 419 | struct clk_hw *hw; |
420 | struct clk_init_data init; | 420 | struct clk_init_data init; |
421 | int ret; | ||
421 | 422 | ||
422 | pll = kzalloc(sizeof(*pll), GFP_KERNEL); | 423 | pll = kzalloc(sizeof(*pll), GFP_KERNEL); |
423 | if (!pll) | 424 | if (!pll) |
@@ -478,10 +479,13 @@ struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name, | |||
478 | init.num_parents = 1; | 479 | init.num_parents = 1; |
479 | 480 | ||
480 | pll->hw.init = &init; | 481 | pll->hw.init = &init; |
482 | hw = &pll->hw; | ||
481 | 483 | ||
482 | clk = clk_register(NULL, &pll->hw); | 484 | ret = clk_hw_register(NULL, hw); |
483 | if (IS_ERR(clk)) | 485 | if (ret) { |
484 | kfree(pll); | 486 | kfree(pll); |
487 | return ERR_PTR(ret); | ||
488 | } | ||
485 | 489 | ||
486 | return clk; | 490 | return hw; |
487 | } | 491 | } |
diff --git a/drivers/clk/imx/clk.c b/drivers/clk/imx/clk.c index 1efed86217f7..f628071f6605 100644 --- a/drivers/clk/imx/clk.c +++ b/drivers/clk/imx/clk.c | |||
@@ -1,14 +1,30 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
2 | #include <linux/clk.h> | 2 | #include <linux/clk.h> |
3 | #include <linux/clk-provider.h> | ||
3 | #include <linux/err.h> | 4 | #include <linux/err.h> |
5 | #include <linux/io.h> | ||
4 | #include <linux/of.h> | 6 | #include <linux/of.h> |
5 | #include <linux/slab.h> | 7 | #include <linux/slab.h> |
6 | #include <linux/spinlock.h> | 8 | #include <linux/spinlock.h> |
7 | #include "clk.h" | 9 | #include "clk.h" |
8 | 10 | ||
11 | #define CCM_CCDR 0x4 | ||
12 | #define CCDR_MMDC_CH0_MASK BIT(17) | ||
13 | #define CCDR_MMDC_CH1_MASK BIT(16) | ||
14 | |||
9 | DEFINE_SPINLOCK(imx_ccm_lock); | 15 | DEFINE_SPINLOCK(imx_ccm_lock); |
10 | 16 | ||
11 | void __init imx_check_clocks(struct clk *clks[], unsigned int count) | 17 | void __init imx_mmdc_mask_handshake(void __iomem *ccm_base, |
18 | unsigned int chn) | ||
19 | { | ||
20 | unsigned int reg; | ||
21 | |||
22 | reg = readl_relaxed(ccm_base + CCM_CCDR); | ||
23 | reg |= chn == 0 ? CCDR_MMDC_CH0_MASK : CCDR_MMDC_CH1_MASK; | ||
24 | writel_relaxed(reg, ccm_base + CCM_CCDR); | ||
25 | } | ||
26 | |||
27 | void imx_check_clocks(struct clk *clks[], unsigned int count) | ||
12 | { | 28 | { |
13 | unsigned i; | 29 | unsigned i; |
14 | 30 | ||
@@ -59,6 +75,17 @@ struct clk * __init imx_obtain_fixed_clock( | |||
59 | return clk; | 75 | return clk; |
60 | } | 76 | } |
61 | 77 | ||
78 | struct clk_hw * __init imx_obtain_fixed_clock_hw( | ||
79 | const char *name, unsigned long rate) | ||
80 | { | ||
81 | struct clk *clk; | ||
82 | |||
83 | clk = imx_obtain_fixed_clock_from_dt(name); | ||
84 | if (IS_ERR(clk)) | ||
85 | clk = imx_clk_fixed(name, rate); | ||
86 | return __clk_get_hw(clk); | ||
87 | } | ||
88 | |||
62 | struct clk_hw * __init imx_obtain_fixed_clk_hw(struct device_node *np, | 89 | struct clk_hw * __init imx_obtain_fixed_clk_hw(struct device_node *np, |
63 | const char *name) | 90 | const char *name) |
64 | { | 91 | { |
@@ -97,8 +124,8 @@ void imx_cscmr1_fixup(u32 *val) | |||
97 | return; | 124 | return; |
98 | } | 125 | } |
99 | 126 | ||
100 | static int imx_keep_uart_clocks __initdata; | 127 | static int imx_keep_uart_clocks; |
101 | static struct clk ** const *imx_uart_clocks __initdata; | 128 | static struct clk ** const *imx_uart_clocks; |
102 | 129 | ||
103 | static int __init imx_keep_uart_clocks_param(char *str) | 130 | static int __init imx_keep_uart_clocks_param(char *str) |
104 | { | 131 | { |
@@ -111,7 +138,7 @@ __setup_param("earlycon", imx_keep_uart_earlycon, | |||
111 | __setup_param("earlyprintk", imx_keep_uart_earlyprintk, | 138 | __setup_param("earlyprintk", imx_keep_uart_earlyprintk, |
112 | imx_keep_uart_clocks_param, 0); | 139 | imx_keep_uart_clocks_param, 0); |
113 | 140 | ||
114 | void __init imx_register_uart_clocks(struct clk ** const clks[]) | 141 | void imx_register_uart_clocks(struct clk ** const clks[]) |
115 | { | 142 | { |
116 | if (imx_keep_uart_clocks) { | 143 | if (imx_keep_uart_clocks) { |
117 | int i; | 144 | int i; |
diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h index 8639a8f2153e..d94d9cb079d3 100644 --- a/drivers/clk/imx/clk.h +++ b/drivers/clk/imx/clk.h | |||
@@ -10,6 +10,8 @@ extern spinlock_t imx_ccm_lock; | |||
10 | void imx_check_clocks(struct clk *clks[], unsigned int count); | 10 | void imx_check_clocks(struct clk *clks[], unsigned int count); |
11 | void imx_check_clk_hws(struct clk_hw *clks[], unsigned int count); | 11 | void imx_check_clk_hws(struct clk_hw *clks[], unsigned int count); |
12 | void imx_register_uart_clocks(struct clk ** const clks[]); | 12 | void imx_register_uart_clocks(struct clk ** const clks[]); |
13 | void imx_register_uart_clocks_hws(struct clk_hw ** const hws[]); | ||
14 | void imx_mmdc_mask_handshake(void __iomem *ccm_base, unsigned int chn); | ||
13 | 15 | ||
14 | extern void imx_cscmr1_fixup(u32 *val); | 16 | extern void imx_cscmr1_fixup(u32 *val); |
15 | 17 | ||
@@ -48,6 +50,74 @@ struct imx_pll14xx_clk { | |||
48 | int flags; | 50 | int flags; |
49 | }; | 51 | }; |
50 | 52 | ||
53 | #define imx_clk_busy_divider(name, parent_name, reg, shift, width, busy_reg, busy_shift) \ | ||
54 | imx_clk_hw_busy_divider(name, parent_name, reg, shift, width, busy_reg, busy_shift)->clk | ||
55 | |||
56 | #define imx_clk_busy_mux(name, reg, shift, width, busy_reg, busy_shift, parent_names, num_parents) \ | ||
57 | imx_clk_hw_busy_mux(name, reg, shift, width, busy_reg, busy_shift, parent_names, num_parents)->clk | ||
58 | |||
59 | #define imx_clk_cpu(name, parent_name, div, mux, pll, step) \ | ||
60 | imx_clk_hw_cpu(name, parent_name, div, mux, pll, step)->clk | ||
61 | |||
62 | #define clk_register_gate2(dev, name, parent_name, flags, reg, bit_idx, \ | ||
63 | cgr_val, clk_gate_flags, lock, share_count) \ | ||
64 | clk_hw_register_gate2(dev, name, parent_name, flags, reg, bit_idx, \ | ||
65 | cgr_val, clk_gate_flags, lock, share_count)->clk | ||
66 | |||
67 | #define imx_clk_pllv3(type, name, parent_name, base, div_mask) \ | ||
68 | imx_clk_hw_pllv3(type, name, parent_name, base, div_mask)->clk | ||
69 | |||
70 | #define imx_clk_pfd(name, parent_name, reg, idx) \ | ||
71 | imx_clk_hw_pfd(name, parent_name, reg, idx)->clk | ||
72 | |||
73 | #define imx_clk_gate_exclusive(name, parent, reg, shift, exclusive_mask) \ | ||
74 | imx_clk_hw_gate_exclusive(name, parent, reg, shift, exclusive_mask)->clk | ||
75 | |||
76 | #define imx_clk_fixup_divider(name, parent, reg, shift, width, fixup) \ | ||
77 | imx_clk_hw_fixup_divider(name, parent, reg, shift, width, fixup)->clk | ||
78 | |||
79 | #define imx_clk_fixup_mux(name, reg, shift, width, parents, num_parents, fixup) \ | ||
80 | imx_clk_hw_fixup_mux(name, reg, shift, width, parents, num_parents, fixup)->clk | ||
81 | |||
82 | #define imx_clk_mux_ldb(name, reg, shift, width, parents, num_parents) \ | ||
83 | imx_clk_hw_mux_ldb(name, reg, shift, width, parents, num_parents)->clk | ||
84 | |||
85 | #define imx_clk_fixed_factor(name, parent, mult, div) \ | ||
86 | imx_clk_hw_fixed_factor(name, parent, mult, div)->clk | ||
87 | |||
88 | #define imx_clk_divider2(name, parent, reg, shift, width) \ | ||
89 | imx_clk_hw_divider2(name, parent, reg, shift, width)->clk | ||
90 | |||
91 | #define imx_clk_gate_dis(name, parent, reg, shift) \ | ||
92 | imx_clk_hw_gate_dis(name, parent, reg, shift)->clk | ||
93 | |||
94 | #define imx_clk_gate_dis_flags(name, parent, reg, shift, flags) \ | ||
95 | imx_clk_hw_gate_dis_flags(name, parent, reg, shift, flags)->clk | ||
96 | |||
97 | #define imx_clk_gate_flags(name, parent, reg, shift, flags) \ | ||
98 | imx_clk_hw_gate_flags(name, parent, reg, shift, flags)->clk | ||
99 | |||
100 | #define imx_clk_gate2(name, parent, reg, shift) \ | ||
101 | imx_clk_hw_gate2(name, parent, reg, shift)->clk | ||
102 | |||
103 | #define imx_clk_gate2_flags(name, parent, reg, shift, flags) \ | ||
104 | imx_clk_hw_gate2_flags(name, parent, reg, shift, flags)->clk | ||
105 | |||
106 | #define imx_clk_gate2_shared(name, parent, reg, shift, share_count) \ | ||
107 | imx_clk_hw_gate2_shared(name, parent, reg, shift, share_count)->clk | ||
108 | |||
109 | #define imx_clk_gate2_shared2(name, parent, reg, shift, share_count) \ | ||
110 | imx_clk_hw_gate2_shared2(name, parent, reg, shift, share_count)->clk | ||
111 | |||
112 | #define imx_clk_gate3(name, parent, reg, shift) \ | ||
113 | imx_clk_hw_gate3(name, parent, reg, shift)->clk | ||
114 | |||
115 | #define imx_clk_gate4(name, parent, reg, shift) \ | ||
116 | imx_clk_hw_gate4(name, parent, reg, shift)->clk | ||
117 | |||
118 | #define imx_clk_mux(name, reg, shift, width, parents, num_parents) \ | ||
119 | imx_clk_hw_mux(name, reg, shift, width, parents, num_parents)->clk | ||
120 | |||
51 | struct clk *imx_clk_pll14xx(const char *name, const char *parent_name, | 121 | struct clk *imx_clk_pll14xx(const char *name, const char *parent_name, |
52 | void __iomem *base, const struct imx_pll14xx_clk *pll_clk); | 122 | void __iomem *base, const struct imx_pll14xx_clk *pll_clk); |
53 | 123 | ||
@@ -80,13 +150,13 @@ enum imx_pllv3_type { | |||
80 | IMX_PLLV3_AV_IMX7, | 150 | IMX_PLLV3_AV_IMX7, |
81 | }; | 151 | }; |
82 | 152 | ||
83 | struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name, | 153 | struct clk_hw *imx_clk_hw_pllv3(enum imx_pllv3_type type, const char *name, |
84 | const char *parent_name, void __iomem *base, u32 div_mask); | 154 | const char *parent_name, void __iomem *base, u32 div_mask); |
85 | 155 | ||
86 | struct clk_hw *imx_clk_pllv4(const char *name, const char *parent_name, | 156 | struct clk_hw *imx_clk_pllv4(const char *name, const char *parent_name, |
87 | void __iomem *base); | 157 | void __iomem *base); |
88 | 158 | ||
89 | struct clk *clk_register_gate2(struct device *dev, const char *name, | 159 | struct clk_hw *clk_hw_register_gate2(struct device *dev, const char *name, |
90 | const char *parent_name, unsigned long flags, | 160 | const char *parent_name, unsigned long flags, |
91 | void __iomem *reg, u8 bit_idx, u8 cgr_val, | 161 | void __iomem *reg, u8 bit_idx, u8 cgr_val, |
92 | u8 clk_gate_flags, spinlock_t *lock, | 162 | u8 clk_gate_flags, spinlock_t *lock, |
@@ -95,23 +165,26 @@ struct clk *clk_register_gate2(struct device *dev, const char *name, | |||
95 | struct clk * imx_obtain_fixed_clock( | 165 | struct clk * imx_obtain_fixed_clock( |
96 | const char *name, unsigned long rate); | 166 | const char *name, unsigned long rate); |
97 | 167 | ||
168 | struct clk_hw *imx_obtain_fixed_clock_hw( | ||
169 | const char *name, unsigned long rate); | ||
170 | |||
98 | struct clk_hw *imx_obtain_fixed_clk_hw(struct device_node *np, | 171 | struct clk_hw *imx_obtain_fixed_clk_hw(struct device_node *np, |
99 | const char *name); | 172 | const char *name); |
100 | 173 | ||
101 | struct clk *imx_clk_gate_exclusive(const char *name, const char *parent, | 174 | struct clk_hw *imx_clk_hw_gate_exclusive(const char *name, const char *parent, |
102 | void __iomem *reg, u8 shift, u32 exclusive_mask); | 175 | void __iomem *reg, u8 shift, u32 exclusive_mask); |
103 | 176 | ||
104 | struct clk *imx_clk_pfd(const char *name, const char *parent_name, | 177 | struct clk_hw *imx_clk_hw_pfd(const char *name, const char *parent_name, |
105 | void __iomem *reg, u8 idx); | 178 | void __iomem *reg, u8 idx); |
106 | 179 | ||
107 | struct clk_hw *imx_clk_pfdv2(const char *name, const char *parent_name, | 180 | struct clk_hw *imx_clk_pfdv2(const char *name, const char *parent_name, |
108 | void __iomem *reg, u8 idx); | 181 | void __iomem *reg, u8 idx); |
109 | 182 | ||
110 | struct clk *imx_clk_busy_divider(const char *name, const char *parent_name, | 183 | struct clk_hw *imx_clk_hw_busy_divider(const char *name, const char *parent_name, |
111 | void __iomem *reg, u8 shift, u8 width, | 184 | void __iomem *reg, u8 shift, u8 width, |
112 | void __iomem *busy_reg, u8 busy_shift); | 185 | void __iomem *busy_reg, u8 busy_shift); |
113 | 186 | ||
114 | struct clk *imx_clk_busy_mux(const char *name, void __iomem *reg, u8 shift, | 187 | struct clk_hw *imx_clk_hw_busy_mux(const char *name, void __iomem *reg, u8 shift, |
115 | u8 width, void __iomem *busy_reg, u8 busy_shift, | 188 | u8 width, void __iomem *busy_reg, u8 busy_shift, |
116 | const char * const *parent_names, int num_parents); | 189 | const char * const *parent_names, int num_parents); |
117 | 190 | ||
@@ -121,11 +194,11 @@ struct clk_hw *imx7ulp_clk_composite(const char *name, | |||
121 | bool rate_present, bool gate_present, | 194 | bool rate_present, bool gate_present, |
122 | void __iomem *reg); | 195 | void __iomem *reg); |
123 | 196 | ||
124 | struct clk *imx_clk_fixup_divider(const char *name, const char *parent, | 197 | struct clk_hw *imx_clk_hw_fixup_divider(const char *name, const char *parent, |
125 | void __iomem *reg, u8 shift, u8 width, | 198 | void __iomem *reg, u8 shift, u8 width, |
126 | void (*fixup)(u32 *val)); | 199 | void (*fixup)(u32 *val)); |
127 | 200 | ||
128 | struct clk *imx_clk_fixup_mux(const char *name, void __iomem *reg, | 201 | struct clk_hw *imx_clk_hw_fixup_mux(const char *name, void __iomem *reg, |
129 | u8 shift, u8 width, const char * const *parents, | 202 | u8 shift, u8 width, const char * const *parents, |
130 | int num_parents, void (*fixup)(u32 *val)); | 203 | int num_parents, void (*fixup)(u32 *val)); |
131 | 204 | ||
@@ -139,19 +212,19 @@ static inline struct clk_hw *imx_clk_hw_fixed(const char *name, int rate) | |||
139 | return clk_hw_register_fixed_rate(NULL, name, NULL, 0, rate); | 212 | return clk_hw_register_fixed_rate(NULL, name, NULL, 0, rate); |
140 | } | 213 | } |
141 | 214 | ||
142 | static inline struct clk *imx_clk_mux_ldb(const char *name, void __iomem *reg, | 215 | static inline struct clk_hw *imx_clk_hw_mux_ldb(const char *name, void __iomem *reg, |
143 | u8 shift, u8 width, const char * const *parents, | 216 | u8 shift, u8 width, const char * const *parents, |
144 | int num_parents) | 217 | int num_parents) |
145 | { | 218 | { |
146 | return clk_register_mux(NULL, name, parents, num_parents, | 219 | return clk_hw_register_mux(NULL, name, parents, num_parents, |
147 | CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT, reg, | 220 | CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT, reg, |
148 | shift, width, CLK_MUX_READ_ONLY, &imx_ccm_lock); | 221 | shift, width, CLK_MUX_READ_ONLY, &imx_ccm_lock); |
149 | } | 222 | } |
150 | 223 | ||
151 | static inline struct clk *imx_clk_fixed_factor(const char *name, | 224 | static inline struct clk_hw *imx_clk_hw_fixed_factor(const char *name, |
152 | const char *parent, unsigned int mult, unsigned int div) | 225 | const char *parent, unsigned int mult, unsigned int div) |
153 | { | 226 | { |
154 | return clk_register_fixed_factor(NULL, name, parent, | 227 | return clk_hw_register_fixed_factor(NULL, name, parent, |
155 | CLK_SET_RATE_PARENT, mult, div); | 228 | CLK_SET_RATE_PARENT, mult, div); |
156 | } | 229 | } |
157 | 230 | ||
@@ -188,10 +261,10 @@ static inline struct clk_hw *imx_clk_hw_divider_flags(const char *name, | |||
188 | reg, shift, width, 0, &imx_ccm_lock); | 261 | reg, shift, width, 0, &imx_ccm_lock); |
189 | } | 262 | } |
190 | 263 | ||
191 | static inline struct clk *imx_clk_divider2(const char *name, const char *parent, | 264 | static inline struct clk_hw *imx_clk_hw_divider2(const char *name, const char *parent, |
192 | void __iomem *reg, u8 shift, u8 width) | 265 | void __iomem *reg, u8 shift, u8 width) |
193 | { | 266 | { |
194 | return clk_register_divider(NULL, name, parent, | 267 | return clk_hw_register_divider(NULL, name, parent, |
195 | CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, | 268 | CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, |
196 | reg, shift, width, 0, &imx_ccm_lock); | 269 | reg, shift, width, 0, &imx_ccm_lock); |
197 | } | 270 | } |
@@ -212,10 +285,10 @@ static inline struct clk *imx_clk_gate(const char *name, const char *parent, | |||
212 | shift, 0, &imx_ccm_lock); | 285 | shift, 0, &imx_ccm_lock); |
213 | } | 286 | } |
214 | 287 | ||
215 | static inline struct clk *imx_clk_gate_flags(const char *name, const char *parent, | 288 | static inline struct clk_hw *imx_clk_hw_gate_flags(const char *name, const char *parent, |
216 | void __iomem *reg, u8 shift, unsigned long flags) | 289 | void __iomem *reg, u8 shift, unsigned long flags) |
217 | { | 290 | { |
218 | return clk_register_gate(NULL, name, parent, flags | CLK_SET_RATE_PARENT, reg, | 291 | return clk_hw_register_gate(NULL, name, parent, flags | CLK_SET_RATE_PARENT, reg, |
219 | shift, 0, &imx_ccm_lock); | 292 | shift, 0, &imx_ccm_lock); |
220 | } | 293 | } |
221 | 294 | ||
@@ -226,47 +299,47 @@ static inline struct clk_hw *imx_clk_hw_gate(const char *name, const char *paren | |||
226 | shift, 0, &imx_ccm_lock); | 299 | shift, 0, &imx_ccm_lock); |
227 | } | 300 | } |
228 | 301 | ||
229 | static inline struct clk *imx_clk_gate_dis(const char *name, const char *parent, | 302 | static inline struct clk_hw *imx_clk_hw_gate_dis(const char *name, const char *parent, |
230 | void __iomem *reg, u8 shift) | 303 | void __iomem *reg, u8 shift) |
231 | { | 304 | { |
232 | return clk_register_gate(NULL, name, parent, CLK_SET_RATE_PARENT, reg, | 305 | return clk_hw_register_gate(NULL, name, parent, CLK_SET_RATE_PARENT, reg, |
233 | shift, CLK_GATE_SET_TO_DISABLE, &imx_ccm_lock); | 306 | shift, CLK_GATE_SET_TO_DISABLE, &imx_ccm_lock); |
234 | } | 307 | } |
235 | 308 | ||
236 | static inline struct clk *imx_clk_gate_dis_flags(const char *name, const char *parent, | 309 | static inline struct clk_hw *imx_clk_hw_gate_dis_flags(const char *name, const char *parent, |
237 | void __iomem *reg, u8 shift, unsigned long flags) | 310 | void __iomem *reg, u8 shift, unsigned long flags) |
238 | { | 311 | { |
239 | return clk_register_gate(NULL, name, parent, flags | CLK_SET_RATE_PARENT, reg, | 312 | return clk_hw_register_gate(NULL, name, parent, flags | CLK_SET_RATE_PARENT, reg, |
240 | shift, CLK_GATE_SET_TO_DISABLE, &imx_ccm_lock); | 313 | shift, CLK_GATE_SET_TO_DISABLE, &imx_ccm_lock); |
241 | } | 314 | } |
242 | 315 | ||
243 | static inline struct clk *imx_clk_gate2(const char *name, const char *parent, | 316 | static inline struct clk_hw *imx_clk_hw_gate2(const char *name, const char *parent, |
244 | void __iomem *reg, u8 shift) | 317 | void __iomem *reg, u8 shift) |
245 | { | 318 | { |
246 | return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg, | 319 | return clk_hw_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg, |
247 | shift, 0x3, 0, &imx_ccm_lock, NULL); | 320 | shift, 0x3, 0, &imx_ccm_lock, NULL); |
248 | } | 321 | } |
249 | 322 | ||
250 | static inline struct clk *imx_clk_gate2_flags(const char *name, const char *parent, | 323 | static inline struct clk_hw *imx_clk_hw_gate2_flags(const char *name, const char *parent, |
251 | void __iomem *reg, u8 shift, unsigned long flags) | 324 | void __iomem *reg, u8 shift, unsigned long flags) |
252 | { | 325 | { |
253 | return clk_register_gate2(NULL, name, parent, flags | CLK_SET_RATE_PARENT, reg, | 326 | return clk_hw_register_gate2(NULL, name, parent, flags | CLK_SET_RATE_PARENT, reg, |
254 | shift, 0x3, 0, &imx_ccm_lock, NULL); | 327 | shift, 0x3, 0, &imx_ccm_lock, NULL); |
255 | } | 328 | } |
256 | 329 | ||
257 | static inline struct clk *imx_clk_gate2_shared(const char *name, | 330 | static inline struct clk_hw *imx_clk_hw_gate2_shared(const char *name, |
258 | const char *parent, void __iomem *reg, u8 shift, | 331 | const char *parent, void __iomem *reg, u8 shift, |
259 | unsigned int *share_count) | 332 | unsigned int *share_count) |
260 | { | 333 | { |
261 | return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg, | 334 | return clk_hw_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg, |
262 | shift, 0x3, 0, &imx_ccm_lock, share_count); | 335 | shift, 0x3, 0, &imx_ccm_lock, share_count); |
263 | } | 336 | } |
264 | 337 | ||
265 | static inline struct clk *imx_clk_gate2_shared2(const char *name, | 338 | static inline struct clk_hw *imx_clk_hw_gate2_shared2(const char *name, |
266 | const char *parent, void __iomem *reg, u8 shift, | 339 | const char *parent, void __iomem *reg, u8 shift, |
267 | unsigned int *share_count) | 340 | unsigned int *share_count) |
268 | { | 341 | { |
269 | return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT | | 342 | return clk_hw_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT | |
270 | CLK_OPS_PARENT_ENABLE, reg, shift, 0x3, 0, | 343 | CLK_OPS_PARENT_ENABLE, reg, shift, 0x3, 0, |
271 | &imx_ccm_lock, share_count); | 344 | &imx_ccm_lock, share_count); |
272 | } | 345 | } |
@@ -278,10 +351,10 @@ static inline struct clk *imx_clk_gate2_cgr(const char *name, | |||
278 | shift, cgr_val, 0, &imx_ccm_lock, NULL); | 351 | shift, cgr_val, 0, &imx_ccm_lock, NULL); |
279 | } | 352 | } |
280 | 353 | ||
281 | static inline struct clk *imx_clk_gate3(const char *name, const char *parent, | 354 | static inline struct clk_hw *imx_clk_hw_gate3(const char *name, const char *parent, |
282 | void __iomem *reg, u8 shift) | 355 | void __iomem *reg, u8 shift) |
283 | { | 356 | { |
284 | return clk_register_gate(NULL, name, parent, | 357 | return clk_hw_register_gate(NULL, name, parent, |
285 | CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, | 358 | CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, |
286 | reg, shift, 0, &imx_ccm_lock); | 359 | reg, shift, 0, &imx_ccm_lock); |
287 | } | 360 | } |
@@ -295,10 +368,10 @@ static inline struct clk *imx_clk_gate3_flags(const char *name, | |||
295 | reg, shift, 0, &imx_ccm_lock); | 368 | reg, shift, 0, &imx_ccm_lock); |
296 | } | 369 | } |
297 | 370 | ||
298 | static inline struct clk *imx_clk_gate4(const char *name, const char *parent, | 371 | static inline struct clk_hw *imx_clk_hw_gate4(const char *name, const char *parent, |
299 | void __iomem *reg, u8 shift) | 372 | void __iomem *reg, u8 shift) |
300 | { | 373 | { |
301 | return clk_register_gate2(NULL, name, parent, | 374 | return clk_hw_register_gate2(NULL, name, parent, |
302 | CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, | 375 | CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, |
303 | reg, shift, 0x3, 0, &imx_ccm_lock, NULL); | 376 | reg, shift, 0x3, 0, &imx_ccm_lock, NULL); |
304 | } | 377 | } |
@@ -312,11 +385,11 @@ static inline struct clk *imx_clk_gate4_flags(const char *name, | |||
312 | reg, shift, 0x3, 0, &imx_ccm_lock, NULL); | 385 | reg, shift, 0x3, 0, &imx_ccm_lock, NULL); |
313 | } | 386 | } |
314 | 387 | ||
315 | static inline struct clk *imx_clk_mux(const char *name, void __iomem *reg, | 388 | static inline struct clk_hw *imx_clk_hw_mux(const char *name, void __iomem *reg, |
316 | u8 shift, u8 width, const char * const *parents, | 389 | u8 shift, u8 width, const char * const *parents, |
317 | int num_parents) | 390 | int num_parents) |
318 | { | 391 | { |
319 | return clk_register_mux(NULL, name, parents, num_parents, | 392 | return clk_hw_register_mux(NULL, name, parents, num_parents, |
320 | CLK_SET_RATE_NO_REPARENT, reg, shift, | 393 | CLK_SET_RATE_NO_REPARENT, reg, shift, |
321 | width, 0, &imx_ccm_lock); | 394 | width, 0, &imx_ccm_lock); |
322 | } | 395 | } |
@@ -373,7 +446,7 @@ static inline struct clk_hw *imx_clk_hw_mux_flags(const char *name, | |||
373 | reg, shift, width, 0, &imx_ccm_lock); | 446 | reg, shift, width, 0, &imx_ccm_lock); |
374 | } | 447 | } |
375 | 448 | ||
376 | struct clk *imx_clk_cpu(const char *name, const char *parent_name, | 449 | struct clk_hw *imx_clk_hw_cpu(const char *name, const char *parent_name, |
377 | struct clk *div, struct clk *mux, struct clk *pll, | 450 | struct clk *div, struct clk *mux, struct clk *pll, |
378 | struct clk *step); | 451 | struct clk *step); |
379 | 452 | ||
diff --git a/drivers/clk/ingenic/Makefile b/drivers/clk/ingenic/Makefile index ab58a6a862a5..250570a809d3 100644 --- a/drivers/clk/ingenic/Makefile +++ b/drivers/clk/ingenic/Makefile | |||
@@ -1,5 +1,5 @@ | |||
1 | # SPDX-License-Identifier: GPL-2.0-only | 1 | # SPDX-License-Identifier: GPL-2.0-only |
2 | obj-$(CONFIG_INGENIC_CGU_COMMON) += cgu.o | 2 | obj-$(CONFIG_INGENIC_CGU_COMMON) += cgu.o pm.o |
3 | obj-$(CONFIG_INGENIC_CGU_JZ4740) += jz4740-cgu.o | 3 | obj-$(CONFIG_INGENIC_CGU_JZ4740) += jz4740-cgu.o |
4 | obj-$(CONFIG_INGENIC_CGU_JZ4725B) += jz4725b-cgu.o | 4 | obj-$(CONFIG_INGENIC_CGU_JZ4725B) += jz4725b-cgu.o |
5 | obj-$(CONFIG_INGENIC_CGU_JZ4770) += jz4770-cgu.o | 5 | obj-$(CONFIG_INGENIC_CGU_JZ4770) += jz4770-cgu.o |
diff --git a/drivers/clk/ingenic/cgu.c b/drivers/clk/ingenic/cgu.c index 92c331427513..6e963031cd87 100644 --- a/drivers/clk/ingenic/cgu.c +++ b/drivers/clk/ingenic/cgu.c | |||
@@ -375,8 +375,11 @@ ingenic_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) | |||
375 | div_reg = readl(cgu->base + clk_info->div.reg); | 375 | div_reg = readl(cgu->base + clk_info->div.reg); |
376 | div = (div_reg >> clk_info->div.shift) & | 376 | div = (div_reg >> clk_info->div.shift) & |
377 | GENMASK(clk_info->div.bits - 1, 0); | 377 | GENMASK(clk_info->div.bits - 1, 0); |
378 | div += 1; | 378 | |
379 | div *= clk_info->div.div; | 379 | if (clk_info->div.div_table) |
380 | div = clk_info->div.div_table[div]; | ||
381 | else | ||
382 | div = (div + 1) * clk_info->div.div; | ||
380 | 383 | ||
381 | rate /= div; | 384 | rate /= div; |
382 | } else if (clk_info->type & CGU_CLK_FIXDIV) { | 385 | } else if (clk_info->type & CGU_CLK_FIXDIV) { |
@@ -386,16 +389,37 @@ ingenic_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) | |||
386 | return rate; | 389 | return rate; |
387 | } | 390 | } |
388 | 391 | ||
392 | static unsigned int | ||
393 | ingenic_clk_calc_hw_div(const struct ingenic_cgu_clk_info *clk_info, | ||
394 | unsigned int div) | ||
395 | { | ||
396 | unsigned int i; | ||
397 | |||
398 | for (i = 0; i < (1 << clk_info->div.bits) | ||
399 | && clk_info->div.div_table[i]; i++) { | ||
400 | if (clk_info->div.div_table[i] >= div) | ||
401 | return i; | ||
402 | } | ||
403 | |||
404 | return i - 1; | ||
405 | } | ||
406 | |||
389 | static unsigned | 407 | static unsigned |
390 | ingenic_clk_calc_div(const struct ingenic_cgu_clk_info *clk_info, | 408 | ingenic_clk_calc_div(const struct ingenic_cgu_clk_info *clk_info, |
391 | unsigned long parent_rate, unsigned long req_rate) | 409 | unsigned long parent_rate, unsigned long req_rate) |
392 | { | 410 | { |
393 | unsigned div; | 411 | unsigned int div, hw_div; |
394 | 412 | ||
395 | /* calculate the divide */ | 413 | /* calculate the divide */ |
396 | div = DIV_ROUND_UP(parent_rate, req_rate); | 414 | div = DIV_ROUND_UP(parent_rate, req_rate); |
397 | 415 | ||
398 | /* and impose hardware constraints */ | 416 | if (clk_info->div.div_table) { |
417 | hw_div = ingenic_clk_calc_hw_div(clk_info, div); | ||
418 | |||
419 | return clk_info->div.div_table[hw_div]; | ||
420 | } | ||
421 | |||
422 | /* Impose hardware constraints */ | ||
399 | div = min_t(unsigned, div, 1 << clk_info->div.bits); | 423 | div = min_t(unsigned, div, 1 << clk_info->div.bits); |
400 | div = max_t(unsigned, div, 1); | 424 | div = max_t(unsigned, div, 1); |
401 | 425 | ||
@@ -438,7 +462,7 @@ ingenic_clk_set_rate(struct clk_hw *hw, unsigned long req_rate, | |||
438 | const struct ingenic_cgu_clk_info *clk_info; | 462 | const struct ingenic_cgu_clk_info *clk_info; |
439 | const unsigned timeout = 100; | 463 | const unsigned timeout = 100; |
440 | unsigned long rate, flags; | 464 | unsigned long rate, flags; |
441 | unsigned div, i; | 465 | unsigned int hw_div, div, i; |
442 | u32 reg, mask; | 466 | u32 reg, mask; |
443 | int ret = 0; | 467 | int ret = 0; |
444 | 468 | ||
@@ -451,13 +475,18 @@ ingenic_clk_set_rate(struct clk_hw *hw, unsigned long req_rate, | |||
451 | if (rate != req_rate) | 475 | if (rate != req_rate) |
452 | return -EINVAL; | 476 | return -EINVAL; |
453 | 477 | ||
478 | if (clk_info->div.div_table) | ||
479 | hw_div = ingenic_clk_calc_hw_div(clk_info, div); | ||
480 | else | ||
481 | hw_div = ((div / clk_info->div.div) - 1); | ||
482 | |||
454 | spin_lock_irqsave(&cgu->lock, flags); | 483 | spin_lock_irqsave(&cgu->lock, flags); |
455 | reg = readl(cgu->base + clk_info->div.reg); | 484 | reg = readl(cgu->base + clk_info->div.reg); |
456 | 485 | ||
457 | /* update the divide */ | 486 | /* update the divide */ |
458 | mask = GENMASK(clk_info->div.bits - 1, 0); | 487 | mask = GENMASK(clk_info->div.bits - 1, 0); |
459 | reg &= ~(mask << clk_info->div.shift); | 488 | reg &= ~(mask << clk_info->div.shift); |
460 | reg |= ((div / clk_info->div.div) - 1) << clk_info->div.shift; | 489 | reg |= hw_div << clk_info->div.shift; |
461 | 490 | ||
462 | /* clear the stop bit */ | 491 | /* clear the stop bit */ |
463 | if (clk_info->div.stop_bit != -1) | 492 | if (clk_info->div.stop_bit != -1) |
diff --git a/drivers/clk/ingenic/cgu.h b/drivers/clk/ingenic/cgu.h index bfbcf6db437d..0dc8004079ee 100644 --- a/drivers/clk/ingenic/cgu.h +++ b/drivers/clk/ingenic/cgu.h | |||
@@ -10,6 +10,7 @@ | |||
10 | #define __DRIVERS_CLK_INGENIC_CGU_H__ | 10 | #define __DRIVERS_CLK_INGENIC_CGU_H__ |
11 | 11 | ||
12 | #include <linux/bitops.h> | 12 | #include <linux/bitops.h> |
13 | #include <linux/clk-provider.h> | ||
13 | #include <linux/of.h> | 14 | #include <linux/of.h> |
14 | #include <linux/spinlock.h> | 15 | #include <linux/spinlock.h> |
15 | 16 | ||
@@ -79,6 +80,8 @@ struct ingenic_cgu_mux_info { | |||
79 | * isn't one | 80 | * isn't one |
80 | * @busy_bit: the index of the busy bit within reg, or -1 if there isn't one | 81 | * @busy_bit: the index of the busy bit within reg, or -1 if there isn't one |
81 | * @stop_bit: the index of the stop bit within reg, or -1 if there isn't one | 82 | * @stop_bit: the index of the stop bit within reg, or -1 if there isn't one |
83 | * @div_table: optional table to map the value read from the register to the | ||
84 | * actual divider value | ||
82 | */ | 85 | */ |
83 | struct ingenic_cgu_div_info { | 86 | struct ingenic_cgu_div_info { |
84 | unsigned reg; | 87 | unsigned reg; |
@@ -88,6 +91,7 @@ struct ingenic_cgu_div_info { | |||
88 | s8 ce_bit; | 91 | s8 ce_bit; |
89 | s8 busy_bit; | 92 | s8 busy_bit; |
90 | s8 stop_bit; | 93 | s8 stop_bit; |
94 | const u8 *div_table; | ||
91 | }; | 95 | }; |
92 | 96 | ||
93 | /** | 97 | /** |
diff --git a/drivers/clk/ingenic/jz4725b-cgu.c b/drivers/clk/ingenic/jz4725b-cgu.c index 8901ea0295b7..2642d36d1e2c 100644 --- a/drivers/clk/ingenic/jz4725b-cgu.c +++ b/drivers/clk/ingenic/jz4725b-cgu.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/of.h> | 11 | #include <linux/of.h> |
12 | #include <dt-bindings/clock/jz4725b-cgu.h> | 12 | #include <dt-bindings/clock/jz4725b-cgu.h> |
13 | #include "cgu.h" | 13 | #include "cgu.h" |
14 | #include "pm.h" | ||
14 | 15 | ||
15 | /* CGU register offsets */ | 16 | /* CGU register offsets */ |
16 | #define CGU_REG_CPCCR 0x00 | 17 | #define CGU_REG_CPCCR 0x00 |
@@ -33,6 +34,14 @@ static const s8 pll_od_encoding[4] = { | |||
33 | 0x0, 0x1, -1, 0x3, | 34 | 0x0, 0x1, -1, 0x3, |
34 | }; | 35 | }; |
35 | 36 | ||
37 | static const u8 jz4725b_cgu_cpccr_div_table[] = { | ||
38 | 1, 2, 3, 4, 6, 8, | ||
39 | }; | ||
40 | |||
41 | static const u8 jz4725b_cgu_pll_half_div_table[] = { | ||
42 | 2, 1, | ||
43 | }; | ||
44 | |||
36 | static const struct ingenic_cgu_clk_info jz4725b_cgu_clocks[] = { | 45 | static const struct ingenic_cgu_clk_info jz4725b_cgu_clocks[] = { |
37 | 46 | ||
38 | /* External clocks */ | 47 | /* External clocks */ |
@@ -66,37 +75,55 @@ static const struct ingenic_cgu_clk_info jz4725b_cgu_clocks[] = { | |||
66 | [JZ4725B_CLK_PLL_HALF] = { | 75 | [JZ4725B_CLK_PLL_HALF] = { |
67 | "pll half", CGU_CLK_DIV, | 76 | "pll half", CGU_CLK_DIV, |
68 | .parents = { JZ4725B_CLK_PLL, -1, -1, -1 }, | 77 | .parents = { JZ4725B_CLK_PLL, -1, -1, -1 }, |
69 | .div = { CGU_REG_CPCCR, 21, 1, 1, -1, -1, -1 }, | 78 | .div = { |
79 | CGU_REG_CPCCR, 21, 1, 1, -1, -1, -1, | ||
80 | jz4725b_cgu_pll_half_div_table, | ||
81 | }, | ||
70 | }, | 82 | }, |
71 | 83 | ||
72 | [JZ4725B_CLK_CCLK] = { | 84 | [JZ4725B_CLK_CCLK] = { |
73 | "cclk", CGU_CLK_DIV, | 85 | "cclk", CGU_CLK_DIV, |
74 | .parents = { JZ4725B_CLK_PLL, -1, -1, -1 }, | 86 | .parents = { JZ4725B_CLK_PLL, -1, -1, -1 }, |
75 | .div = { CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1 }, | 87 | .div = { |
88 | CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1, | ||
89 | jz4725b_cgu_cpccr_div_table, | ||
90 | }, | ||
76 | }, | 91 | }, |
77 | 92 | ||
78 | [JZ4725B_CLK_HCLK] = { | 93 | [JZ4725B_CLK_HCLK] = { |
79 | "hclk", CGU_CLK_DIV, | 94 | "hclk", CGU_CLK_DIV, |
80 | .parents = { JZ4725B_CLK_PLL, -1, -1, -1 }, | 95 | .parents = { JZ4725B_CLK_PLL, -1, -1, -1 }, |
81 | .div = { CGU_REG_CPCCR, 4, 1, 4, 22, -1, -1 }, | 96 | .div = { |
97 | CGU_REG_CPCCR, 4, 1, 4, 22, -1, -1, | ||
98 | jz4725b_cgu_cpccr_div_table, | ||
99 | }, | ||
82 | }, | 100 | }, |
83 | 101 | ||
84 | [JZ4725B_CLK_PCLK] = { | 102 | [JZ4725B_CLK_PCLK] = { |
85 | "pclk", CGU_CLK_DIV, | 103 | "pclk", CGU_CLK_DIV, |
86 | .parents = { JZ4725B_CLK_PLL, -1, -1, -1 }, | 104 | .parents = { JZ4725B_CLK_PLL, -1, -1, -1 }, |
87 | .div = { CGU_REG_CPCCR, 8, 1, 4, 22, -1, -1 }, | 105 | .div = { |
106 | CGU_REG_CPCCR, 8, 1, 4, 22, -1, -1, | ||
107 | jz4725b_cgu_cpccr_div_table, | ||
108 | }, | ||
88 | }, | 109 | }, |
89 | 110 | ||
90 | [JZ4725B_CLK_MCLK] = { | 111 | [JZ4725B_CLK_MCLK] = { |
91 | "mclk", CGU_CLK_DIV, | 112 | "mclk", CGU_CLK_DIV, |
92 | .parents = { JZ4725B_CLK_PLL, -1, -1, -1 }, | 113 | .parents = { JZ4725B_CLK_PLL, -1, -1, -1 }, |
93 | .div = { CGU_REG_CPCCR, 12, 1, 4, 22, -1, -1 }, | 114 | .div = { |
115 | CGU_REG_CPCCR, 12, 1, 4, 22, -1, -1, | ||
116 | jz4725b_cgu_cpccr_div_table, | ||
117 | }, | ||
94 | }, | 118 | }, |
95 | 119 | ||
96 | [JZ4725B_CLK_IPU] = { | 120 | [JZ4725B_CLK_IPU] = { |
97 | "ipu", CGU_CLK_DIV | CGU_CLK_GATE, | 121 | "ipu", CGU_CLK_DIV | CGU_CLK_GATE, |
98 | .parents = { JZ4725B_CLK_PLL, -1, -1, -1 }, | 122 | .parents = { JZ4725B_CLK_PLL, -1, -1, -1 }, |
99 | .div = { CGU_REG_CPCCR, 16, 1, 4, 22, -1, -1 }, | 123 | .div = { |
124 | CGU_REG_CPCCR, 16, 1, 4, 22, -1, -1, | ||
125 | jz4725b_cgu_cpccr_div_table, | ||
126 | }, | ||
100 | .gate = { CGU_REG_CLKGR, 13 }, | 127 | .gate = { CGU_REG_CLKGR, 13 }, |
101 | }, | 128 | }, |
102 | 129 | ||
@@ -227,5 +254,7 @@ static void __init jz4725b_cgu_init(struct device_node *np) | |||
227 | retval = ingenic_cgu_register_clocks(cgu); | 254 | retval = ingenic_cgu_register_clocks(cgu); |
228 | if (retval) | 255 | if (retval) |
229 | pr_err("%s: failed to register CGU Clocks\n", __func__); | 256 | pr_err("%s: failed to register CGU Clocks\n", __func__); |
257 | |||
258 | ingenic_cgu_register_syscore_ops(cgu); | ||
230 | } | 259 | } |
231 | CLK_OF_DECLARE(jz4725b_cgu, "ingenic,jz4725b-cgu", jz4725b_cgu_init); | 260 | CLK_OF_DECLARE(jz4725b_cgu, "ingenic,jz4725b-cgu", jz4725b_cgu_init); |
diff --git a/drivers/clk/ingenic/jz4740-cgu.c b/drivers/clk/ingenic/jz4740-cgu.c index c77f4e1506dc..4c0a20949c2c 100644 --- a/drivers/clk/ingenic/jz4740-cgu.c +++ b/drivers/clk/ingenic/jz4740-cgu.c | |||
@@ -11,8 +11,8 @@ | |||
11 | #include <linux/io.h> | 11 | #include <linux/io.h> |
12 | #include <linux/of.h> | 12 | #include <linux/of.h> |
13 | #include <dt-bindings/clock/jz4740-cgu.h> | 13 | #include <dt-bindings/clock/jz4740-cgu.h> |
14 | #include <asm/mach-jz4740/clock.h> | ||
15 | #include "cgu.h" | 14 | #include "cgu.h" |
15 | #include "pm.h" | ||
16 | 16 | ||
17 | /* CGU register offsets */ | 17 | /* CGU register offsets */ |
18 | #define CGU_REG_CPCCR 0x00 | 18 | #define CGU_REG_CPCCR 0x00 |
@@ -49,6 +49,10 @@ static const s8 pll_od_encoding[4] = { | |||
49 | 0x0, 0x1, -1, 0x3, | 49 | 0x0, 0x1, -1, 0x3, |
50 | }; | 50 | }; |
51 | 51 | ||
52 | static const u8 jz4740_cgu_cpccr_div_table[] = { | ||
53 | 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, | ||
54 | }; | ||
55 | |||
52 | static const struct ingenic_cgu_clk_info jz4740_cgu_clocks[] = { | 56 | static const struct ingenic_cgu_clk_info jz4740_cgu_clocks[] = { |
53 | 57 | ||
54 | /* External clocks */ | 58 | /* External clocks */ |
@@ -88,31 +92,46 @@ static const struct ingenic_cgu_clk_info jz4740_cgu_clocks[] = { | |||
88 | [JZ4740_CLK_CCLK] = { | 92 | [JZ4740_CLK_CCLK] = { |
89 | "cclk", CGU_CLK_DIV, | 93 | "cclk", CGU_CLK_DIV, |
90 | .parents = { JZ4740_CLK_PLL, -1, -1, -1 }, | 94 | .parents = { JZ4740_CLK_PLL, -1, -1, -1 }, |
91 | .div = { CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1 }, | 95 | .div = { |
96 | CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1, | ||
97 | jz4740_cgu_cpccr_div_table, | ||
98 | }, | ||
92 | }, | 99 | }, |
93 | 100 | ||
94 | [JZ4740_CLK_HCLK] = { | 101 | [JZ4740_CLK_HCLK] = { |
95 | "hclk", CGU_CLK_DIV, | 102 | "hclk", CGU_CLK_DIV, |
96 | .parents = { JZ4740_CLK_PLL, -1, -1, -1 }, | 103 | .parents = { JZ4740_CLK_PLL, -1, -1, -1 }, |
97 | .div = { CGU_REG_CPCCR, 4, 1, 4, 22, -1, -1 }, | 104 | .div = { |
105 | CGU_REG_CPCCR, 4, 1, 4, 22, -1, -1, | ||
106 | jz4740_cgu_cpccr_div_table, | ||
107 | }, | ||
98 | }, | 108 | }, |
99 | 109 | ||
100 | [JZ4740_CLK_PCLK] = { | 110 | [JZ4740_CLK_PCLK] = { |
101 | "pclk", CGU_CLK_DIV, | 111 | "pclk", CGU_CLK_DIV, |
102 | .parents = { JZ4740_CLK_PLL, -1, -1, -1 }, | 112 | .parents = { JZ4740_CLK_PLL, -1, -1, -1 }, |
103 | .div = { CGU_REG_CPCCR, 8, 1, 4, 22, -1, -1 }, | 113 | .div = { |
114 | CGU_REG_CPCCR, 8, 1, 4, 22, -1, -1, | ||
115 | jz4740_cgu_cpccr_div_table, | ||
116 | }, | ||
104 | }, | 117 | }, |
105 | 118 | ||
106 | [JZ4740_CLK_MCLK] = { | 119 | [JZ4740_CLK_MCLK] = { |
107 | "mclk", CGU_CLK_DIV, | 120 | "mclk", CGU_CLK_DIV, |
108 | .parents = { JZ4740_CLK_PLL, -1, -1, -1 }, | 121 | .parents = { JZ4740_CLK_PLL, -1, -1, -1 }, |
109 | .div = { CGU_REG_CPCCR, 12, 1, 4, 22, -1, -1 }, | 122 | .div = { |
123 | CGU_REG_CPCCR, 12, 1, 4, 22, -1, -1, | ||
124 | jz4740_cgu_cpccr_div_table, | ||
125 | }, | ||
110 | }, | 126 | }, |
111 | 127 | ||
112 | [JZ4740_CLK_LCD] = { | 128 | [JZ4740_CLK_LCD] = { |
113 | "lcd", CGU_CLK_DIV | CGU_CLK_GATE, | 129 | "lcd", CGU_CLK_DIV | CGU_CLK_GATE, |
114 | .parents = { JZ4740_CLK_PLL_HALF, -1, -1, -1 }, | 130 | .parents = { JZ4740_CLK_PLL_HALF, -1, -1, -1 }, |
115 | .div = { CGU_REG_CPCCR, 16, 1, 5, 22, -1, -1 }, | 131 | .div = { |
132 | CGU_REG_CPCCR, 16, 1, 5, 22, -1, -1, | ||
133 | jz4740_cgu_cpccr_div_table, | ||
134 | }, | ||
116 | .gate = { CGU_REG_CLKGR, 10 }, | 135 | .gate = { CGU_REG_CLKGR, 10 }, |
117 | }, | 136 | }, |
118 | 137 | ||
@@ -219,77 +238,7 @@ static void __init jz4740_cgu_init(struct device_node *np) | |||
219 | retval = ingenic_cgu_register_clocks(cgu); | 238 | retval = ingenic_cgu_register_clocks(cgu); |
220 | if (retval) | 239 | if (retval) |
221 | pr_err("%s: failed to register CGU Clocks\n", __func__); | 240 | pr_err("%s: failed to register CGU Clocks\n", __func__); |
222 | } | ||
223 | CLK_OF_DECLARE(jz4740_cgu, "ingenic,jz4740-cgu", jz4740_cgu_init); | ||
224 | |||
225 | void jz4740_clock_set_wait_mode(enum jz4740_wait_mode mode) | ||
226 | { | ||
227 | uint32_t lcr = readl(cgu->base + CGU_REG_LCR); | ||
228 | |||
229 | switch (mode) { | ||
230 | case JZ4740_WAIT_MODE_IDLE: | ||
231 | lcr &= ~LCR_SLEEP; | ||
232 | break; | ||
233 | |||
234 | case JZ4740_WAIT_MODE_SLEEP: | ||
235 | lcr |= LCR_SLEEP; | ||
236 | break; | ||
237 | } | ||
238 | |||
239 | writel(lcr, cgu->base + CGU_REG_LCR); | ||
240 | } | ||
241 | 241 | ||
242 | void jz4740_clock_udc_disable_auto_suspend(void) | 242 | ingenic_cgu_register_syscore_ops(cgu); |
243 | { | ||
244 | uint32_t clkgr = readl(cgu->base + CGU_REG_CLKGR); | ||
245 | |||
246 | clkgr &= ~CLKGR_UDC; | ||
247 | writel(clkgr, cgu->base + CGU_REG_CLKGR); | ||
248 | } | ||
249 | EXPORT_SYMBOL_GPL(jz4740_clock_udc_disable_auto_suspend); | ||
250 | |||
251 | void jz4740_clock_udc_enable_auto_suspend(void) | ||
252 | { | ||
253 | uint32_t clkgr = readl(cgu->base + CGU_REG_CLKGR); | ||
254 | |||
255 | clkgr |= CLKGR_UDC; | ||
256 | writel(clkgr, cgu->base + CGU_REG_CLKGR); | ||
257 | } | ||
258 | EXPORT_SYMBOL_GPL(jz4740_clock_udc_enable_auto_suspend); | ||
259 | |||
260 | #define JZ_CLOCK_GATE_UART0 BIT(0) | ||
261 | #define JZ_CLOCK_GATE_TCU BIT(1) | ||
262 | #define JZ_CLOCK_GATE_DMAC BIT(12) | ||
263 | |||
264 | void jz4740_clock_suspend(void) | ||
265 | { | ||
266 | uint32_t clkgr, cppcr; | ||
267 | |||
268 | clkgr = readl(cgu->base + CGU_REG_CLKGR); | ||
269 | clkgr |= JZ_CLOCK_GATE_TCU | JZ_CLOCK_GATE_DMAC | JZ_CLOCK_GATE_UART0; | ||
270 | writel(clkgr, cgu->base + CGU_REG_CLKGR); | ||
271 | |||
272 | cppcr = readl(cgu->base + CGU_REG_CPPCR); | ||
273 | cppcr &= ~BIT(jz4740_cgu_clocks[JZ4740_CLK_PLL].pll.enable_bit); | ||
274 | writel(cppcr, cgu->base + CGU_REG_CPPCR); | ||
275 | } | ||
276 | |||
277 | void jz4740_clock_resume(void) | ||
278 | { | ||
279 | uint32_t clkgr, cppcr, stable; | ||
280 | |||
281 | cppcr = readl(cgu->base + CGU_REG_CPPCR); | ||
282 | cppcr |= BIT(jz4740_cgu_clocks[JZ4740_CLK_PLL].pll.enable_bit); | ||
283 | writel(cppcr, cgu->base + CGU_REG_CPPCR); | ||
284 | |||
285 | stable = BIT(jz4740_cgu_clocks[JZ4740_CLK_PLL].pll.stable_bit); | ||
286 | do { | ||
287 | cppcr = readl(cgu->base + CGU_REG_CPPCR); | ||
288 | } while (!(cppcr & stable)); | ||
289 | |||
290 | clkgr = readl(cgu->base + CGU_REG_CLKGR); | ||
291 | clkgr &= ~JZ_CLOCK_GATE_TCU; | ||
292 | clkgr &= ~JZ_CLOCK_GATE_DMAC; | ||
293 | clkgr &= ~JZ_CLOCK_GATE_UART0; | ||
294 | writel(clkgr, cgu->base + CGU_REG_CLKGR); | ||
295 | } | 243 | } |
244 | CLK_OF_DECLARE(jz4740_cgu, "ingenic,jz4740-cgu", jz4740_cgu_init); | ||
diff --git a/drivers/clk/ingenic/jz4770-cgu.c b/drivers/clk/ingenic/jz4770-cgu.c index dfce740c25a8..eebc1bea3841 100644 --- a/drivers/clk/ingenic/jz4770-cgu.c +++ b/drivers/clk/ingenic/jz4770-cgu.c | |||
@@ -9,9 +9,9 @@ | |||
9 | #include <linux/delay.h> | 9 | #include <linux/delay.h> |
10 | #include <linux/io.h> | 10 | #include <linux/io.h> |
11 | #include <linux/of.h> | 11 | #include <linux/of.h> |
12 | #include <linux/syscore_ops.h> | ||
13 | #include <dt-bindings/clock/jz4770-cgu.h> | 12 | #include <dt-bindings/clock/jz4770-cgu.h> |
14 | #include "cgu.h" | 13 | #include "cgu.h" |
14 | #include "pm.h" | ||
15 | 15 | ||
16 | /* | 16 | /* |
17 | * CPM registers offset address definition | 17 | * CPM registers offset address definition |
@@ -38,9 +38,6 @@ | |||
38 | #define CGU_REG_MSC2CDR 0xA8 | 38 | #define CGU_REG_MSC2CDR 0xA8 |
39 | #define CGU_REG_BCHCDR 0xAC | 39 | #define CGU_REG_BCHCDR 0xAC |
40 | 40 | ||
41 | /* bits within the LCR register */ | ||
42 | #define LCR_LPM BIT(0) /* Low Power Mode */ | ||
43 | |||
44 | /* bits within the OPCR register */ | 41 | /* bits within the OPCR register */ |
45 | #define OPCR_SPENDH BIT(5) /* UHC PHY suspend */ | 42 | #define OPCR_SPENDH BIT(5) /* UHC PHY suspend */ |
46 | 43 | ||
@@ -87,6 +84,10 @@ static const s8 pll_od_encoding[8] = { | |||
87 | 0x0, 0x1, -1, 0x2, -1, -1, -1, 0x3, | 84 | 0x0, 0x1, -1, 0x2, -1, -1, -1, 0x3, |
88 | }; | 85 | }; |
89 | 86 | ||
87 | static const u8 jz4770_cgu_cpccr_div_table[] = { | ||
88 | 1, 2, 3, 4, 6, 8, 12, | ||
89 | }; | ||
90 | |||
90 | static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = { | 91 | static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = { |
91 | 92 | ||
92 | /* External clocks */ | 93 | /* External clocks */ |
@@ -144,34 +145,52 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = { | |||
144 | [JZ4770_CLK_CCLK] = { | 145 | [JZ4770_CLK_CCLK] = { |
145 | "cclk", CGU_CLK_DIV, | 146 | "cclk", CGU_CLK_DIV, |
146 | .parents = { JZ4770_CLK_PLL0, }, | 147 | .parents = { JZ4770_CLK_PLL0, }, |
147 | .div = { CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1 }, | 148 | .div = { |
149 | CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1, | ||
150 | jz4770_cgu_cpccr_div_table, | ||
151 | }, | ||
148 | }, | 152 | }, |
149 | [JZ4770_CLK_H0CLK] = { | 153 | [JZ4770_CLK_H0CLK] = { |
150 | "h0clk", CGU_CLK_DIV, | 154 | "h0clk", CGU_CLK_DIV, |
151 | .parents = { JZ4770_CLK_PLL0, }, | 155 | .parents = { JZ4770_CLK_PLL0, }, |
152 | .div = { CGU_REG_CPCCR, 4, 1, 4, 22, -1, -1 }, | 156 | .div = { |
157 | CGU_REG_CPCCR, 4, 1, 4, 22, -1, -1, | ||
158 | jz4770_cgu_cpccr_div_table, | ||
159 | }, | ||
153 | }, | 160 | }, |
154 | [JZ4770_CLK_H1CLK] = { | 161 | [JZ4770_CLK_H1CLK] = { |
155 | "h1clk", CGU_CLK_DIV | CGU_CLK_GATE, | 162 | "h1clk", CGU_CLK_DIV | CGU_CLK_GATE, |
156 | .parents = { JZ4770_CLK_PLL0, }, | 163 | .parents = { JZ4770_CLK_PLL0, }, |
157 | .div = { CGU_REG_CPCCR, 24, 1, 4, 22, -1, -1 }, | 164 | .div = { |
165 | CGU_REG_CPCCR, 24, 1, 4, 22, -1, -1, | ||
166 | jz4770_cgu_cpccr_div_table, | ||
167 | }, | ||
158 | .gate = { CGU_REG_CLKGR1, 7 }, | 168 | .gate = { CGU_REG_CLKGR1, 7 }, |
159 | }, | 169 | }, |
160 | [JZ4770_CLK_H2CLK] = { | 170 | [JZ4770_CLK_H2CLK] = { |
161 | "h2clk", CGU_CLK_DIV, | 171 | "h2clk", CGU_CLK_DIV, |
162 | .parents = { JZ4770_CLK_PLL0, }, | 172 | .parents = { JZ4770_CLK_PLL0, }, |
163 | .div = { CGU_REG_CPCCR, 16, 1, 4, 22, -1, -1 }, | 173 | .div = { |
174 | CGU_REG_CPCCR, 16, 1, 4, 22, -1, -1, | ||
175 | jz4770_cgu_cpccr_div_table, | ||
176 | }, | ||
164 | }, | 177 | }, |
165 | [JZ4770_CLK_C1CLK] = { | 178 | [JZ4770_CLK_C1CLK] = { |
166 | "c1clk", CGU_CLK_DIV | CGU_CLK_GATE, | 179 | "c1clk", CGU_CLK_DIV | CGU_CLK_GATE, |
167 | .parents = { JZ4770_CLK_PLL0, }, | 180 | .parents = { JZ4770_CLK_PLL0, }, |
168 | .div = { CGU_REG_CPCCR, 12, 1, 4, 22, -1, -1 }, | 181 | .div = { |
182 | CGU_REG_CPCCR, 12, 1, 4, 22, -1, -1, | ||
183 | jz4770_cgu_cpccr_div_table, | ||
184 | }, | ||
169 | .gate = { CGU_REG_OPCR, 31, true }, // disable CCLK stop on idle | 185 | .gate = { CGU_REG_OPCR, 31, true }, // disable CCLK stop on idle |
170 | }, | 186 | }, |
171 | [JZ4770_CLK_PCLK] = { | 187 | [JZ4770_CLK_PCLK] = { |
172 | "pclk", CGU_CLK_DIV, | 188 | "pclk", CGU_CLK_DIV, |
173 | .parents = { JZ4770_CLK_PLL0, }, | 189 | .parents = { JZ4770_CLK_PLL0, }, |
174 | .div = { CGU_REG_CPCCR, 8, 1, 4, 22, -1, -1 }, | 190 | .div = { |
191 | CGU_REG_CPCCR, 8, 1, 4, 22, -1, -1, | ||
192 | jz4770_cgu_cpccr_div_table, | ||
193 | }, | ||
175 | }, | 194 | }, |
176 | 195 | ||
177 | /* Those divided clocks can connect to PLL0 or PLL1 */ | 196 | /* Those divided clocks can connect to PLL0 or PLL1 */ |
@@ -407,30 +426,6 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = { | |||
407 | }, | 426 | }, |
408 | }; | 427 | }; |
409 | 428 | ||
410 | #if IS_ENABLED(CONFIG_PM_SLEEP) | ||
411 | static int jz4770_cgu_pm_suspend(void) | ||
412 | { | ||
413 | u32 val; | ||
414 | |||
415 | val = readl(cgu->base + CGU_REG_LCR); | ||
416 | writel(val | LCR_LPM, cgu->base + CGU_REG_LCR); | ||
417 | return 0; | ||
418 | } | ||
419 | |||
420 | static void jz4770_cgu_pm_resume(void) | ||
421 | { | ||
422 | u32 val; | ||
423 | |||
424 | val = readl(cgu->base + CGU_REG_LCR); | ||
425 | writel(val & ~LCR_LPM, cgu->base + CGU_REG_LCR); | ||
426 | } | ||
427 | |||
428 | static struct syscore_ops jz4770_cgu_pm_ops = { | ||
429 | .suspend = jz4770_cgu_pm_suspend, | ||
430 | .resume = jz4770_cgu_pm_resume, | ||
431 | }; | ||
432 | #endif /* CONFIG_PM_SLEEP */ | ||
433 | |||
434 | static void __init jz4770_cgu_init(struct device_node *np) | 429 | static void __init jz4770_cgu_init(struct device_node *np) |
435 | { | 430 | { |
436 | int retval; | 431 | int retval; |
@@ -444,9 +439,7 @@ static void __init jz4770_cgu_init(struct device_node *np) | |||
444 | if (retval) | 439 | if (retval) |
445 | pr_err("%s: failed to register CGU Clocks\n", __func__); | 440 | pr_err("%s: failed to register CGU Clocks\n", __func__); |
446 | 441 | ||
447 | #if IS_ENABLED(CONFIG_PM_SLEEP) | 442 | ingenic_cgu_register_syscore_ops(cgu); |
448 | register_syscore_ops(&jz4770_cgu_pm_ops); | ||
449 | #endif | ||
450 | } | 443 | } |
451 | 444 | ||
452 | /* We only probe via devicetree, no need for a platform driver */ | 445 | /* We only probe via devicetree, no need for a platform driver */ |
diff --git a/drivers/clk/ingenic/jz4780-cgu.c b/drivers/clk/ingenic/jz4780-cgu.c index 2464fc4032af..8c67f89df25e 100644 --- a/drivers/clk/ingenic/jz4780-cgu.c +++ b/drivers/clk/ingenic/jz4780-cgu.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/of.h> | 12 | #include <linux/of.h> |
13 | #include <dt-bindings/clock/jz4780-cgu.h> | 13 | #include <dt-bindings/clock/jz4780-cgu.h> |
14 | #include "cgu.h" | 14 | #include "cgu.h" |
15 | #include "pm.h" | ||
15 | 16 | ||
16 | /* CGU register offsets */ | 17 | /* CGU register offsets */ |
17 | #define CGU_REG_CLOCKCONTROL 0x00 | 18 | #define CGU_REG_CLOCKCONTROL 0x00 |
@@ -721,5 +722,7 @@ static void __init jz4780_cgu_init(struct device_node *np) | |||
721 | pr_err("%s: failed to register CGU Clocks\n", __func__); | 722 | pr_err("%s: failed to register CGU Clocks\n", __func__); |
722 | return; | 723 | return; |
723 | } | 724 | } |
725 | |||
726 | ingenic_cgu_register_syscore_ops(cgu); | ||
724 | } | 727 | } |
725 | CLK_OF_DECLARE(jz4780_cgu, "ingenic,jz4780-cgu", jz4780_cgu_init); | 728 | CLK_OF_DECLARE(jz4780_cgu, "ingenic,jz4780-cgu", jz4780_cgu_init); |
diff --git a/drivers/clk/ingenic/pm.c b/drivers/clk/ingenic/pm.c new file mode 100644 index 000000000000..341752b640d2 --- /dev/null +++ b/drivers/clk/ingenic/pm.c | |||
@@ -0,0 +1,45 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * Copyright (C) 2019 Paul Cercueil <paul@crapouillou.net> | ||
4 | */ | ||
5 | |||
6 | #include "cgu.h" | ||
7 | #include "pm.h" | ||
8 | |||
9 | #include <linux/io.h> | ||
10 | #include <linux/syscore_ops.h> | ||
11 | |||
12 | #define CGU_REG_LCR 0x04 | ||
13 | |||
14 | #define LCR_LOW_POWER_MODE BIT(0) | ||
15 | |||
16 | static void __iomem * __maybe_unused ingenic_cgu_base; | ||
17 | |||
18 | static int __maybe_unused ingenic_cgu_pm_suspend(void) | ||
19 | { | ||
20 | u32 val = readl(ingenic_cgu_base + CGU_REG_LCR); | ||
21 | |||
22 | writel(val | LCR_LOW_POWER_MODE, ingenic_cgu_base + CGU_REG_LCR); | ||
23 | |||
24 | return 0; | ||
25 | } | ||
26 | |||
27 | static void __maybe_unused ingenic_cgu_pm_resume(void) | ||
28 | { | ||
29 | u32 val = readl(ingenic_cgu_base + CGU_REG_LCR); | ||
30 | |||
31 | writel(val & ~LCR_LOW_POWER_MODE, ingenic_cgu_base + CGU_REG_LCR); | ||
32 | } | ||
33 | |||
34 | static struct syscore_ops __maybe_unused ingenic_cgu_pm_ops = { | ||
35 | .suspend = ingenic_cgu_pm_suspend, | ||
36 | .resume = ingenic_cgu_pm_resume, | ||
37 | }; | ||
38 | |||
39 | void ingenic_cgu_register_syscore_ops(struct ingenic_cgu *cgu) | ||
40 | { | ||
41 | if (IS_ENABLED(CONFIG_PM_SLEEP)) { | ||
42 | ingenic_cgu_base = cgu->base; | ||
43 | register_syscore_ops(&ingenic_cgu_pm_ops); | ||
44 | } | ||
45 | } | ||
diff --git a/drivers/clk/ingenic/pm.h b/drivers/clk/ingenic/pm.h new file mode 100644 index 000000000000..fa7540407b6b --- /dev/null +++ b/drivers/clk/ingenic/pm.h | |||
@@ -0,0 +1,12 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | /* | ||
3 | * Copyright (C) 2019 Paul Cercueil <paul@crapouillou.net> | ||
4 | */ | ||
5 | #ifndef DRIVERS_CLK_INGENIC_PM_H | ||
6 | #define DRIVERS_CLK_INGENIC_PM_H | ||
7 | |||
8 | struct ingenic_cgu; | ||
9 | |||
10 | void ingenic_cgu_register_syscore_ops(struct ingenic_cgu *cgu); | ||
11 | |||
12 | #endif /* DRIVERS_CLK_INGENIC_PM_H */ | ||
diff --git a/drivers/clk/keystone/Kconfig b/drivers/clk/keystone/Kconfig index 0ca63014718a..38aeefb1e808 100644 --- a/drivers/clk/keystone/Kconfig +++ b/drivers/clk/keystone/Kconfig | |||
@@ -15,3 +15,14 @@ config TI_SCI_CLK | |||
15 | This adds the clock driver support over TI System Control Interface. | 15 | This adds the clock driver support over TI System Control Interface. |
16 | If you wish to use clock resources from the PMMC firmware, say Y. | 16 | If you wish to use clock resources from the PMMC firmware, say Y. |
17 | Otherwise, say N. | 17 | Otherwise, say N. |
18 | |||
19 | config TI_SCI_CLK_PROBE_FROM_FW | ||
20 | bool "Probe available clocks from firmware" | ||
21 | depends on TI_SCI_CLK | ||
22 | default n | ||
23 | help | ||
24 | Forces the TI SCI clock driver to probe available clocks from the | ||
25 | firmware. By default, only the used clocks are probed from DT. | ||
26 | This is mostly only useful for debugging purposes, and will | ||
27 | increase the boot time of the device. If you want the clocks probed | ||
28 | from firmware, say Y. Otherwise, say N. | ||
diff --git a/drivers/clk/keystone/sci-clk.c b/drivers/clk/keystone/sci-clk.c index 4cb70bed89a9..7edf8c8432b6 100644 --- a/drivers/clk/keystone/sci-clk.c +++ b/drivers/clk/keystone/sci-clk.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
24 | #include <linux/soc/ti/ti_sci_protocol.h> | 24 | #include <linux/soc/ti/ti_sci_protocol.h> |
25 | #include <linux/bsearch.h> | 25 | #include <linux/bsearch.h> |
26 | #include <linux/list_sort.h> | ||
26 | 27 | ||
27 | #define SCI_CLK_SSC_ENABLE BIT(0) | 28 | #define SCI_CLK_SSC_ENABLE BIT(0) |
28 | #define SCI_CLK_ALLOW_FREQ_CHANGE BIT(1) | 29 | #define SCI_CLK_ALLOW_FREQ_CHANGE BIT(1) |
@@ -52,14 +53,16 @@ struct sci_clk_provider { | |||
52 | * @num_parents: Number of parents for this clock | 53 | * @num_parents: Number of parents for this clock |
53 | * @provider: Master clock provider | 54 | * @provider: Master clock provider |
54 | * @flags: Flags for the clock | 55 | * @flags: Flags for the clock |
56 | * @node: Link for handling clocks probed via DT | ||
55 | */ | 57 | */ |
56 | struct sci_clk { | 58 | struct sci_clk { |
57 | struct clk_hw hw; | 59 | struct clk_hw hw; |
58 | u16 dev_id; | 60 | u16 dev_id; |
59 | u8 clk_id; | 61 | u32 clk_id; |
60 | u8 num_parents; | 62 | u32 num_parents; |
61 | struct sci_clk_provider *provider; | 63 | struct sci_clk_provider *provider; |
62 | u8 flags; | 64 | u8 flags; |
65 | struct list_head node; | ||
63 | }; | 66 | }; |
64 | 67 | ||
65 | #define to_sci_clk(_hw) container_of(_hw, struct sci_clk, hw) | 68 | #define to_sci_clk(_hw) container_of(_hw, struct sci_clk, hw) |
@@ -218,11 +221,11 @@ static int sci_clk_set_rate(struct clk_hw *hw, unsigned long rate, | |||
218 | static u8 sci_clk_get_parent(struct clk_hw *hw) | 221 | static u8 sci_clk_get_parent(struct clk_hw *hw) |
219 | { | 222 | { |
220 | struct sci_clk *clk = to_sci_clk(hw); | 223 | struct sci_clk *clk = to_sci_clk(hw); |
221 | u8 parent_id; | 224 | u32 parent_id = 0; |
222 | int ret; | 225 | int ret; |
223 | 226 | ||
224 | ret = clk->provider->ops->get_parent(clk->provider->sci, clk->dev_id, | 227 | ret = clk->provider->ops->get_parent(clk->provider->sci, clk->dev_id, |
225 | clk->clk_id, &parent_id); | 228 | clk->clk_id, (void *)&parent_id); |
226 | if (ret) { | 229 | if (ret) { |
227 | dev_err(clk->provider->dev, | 230 | dev_err(clk->provider->dev, |
228 | "get-parent failed for dev=%d, clk=%d, ret=%d\n", | 231 | "get-parent failed for dev=%d, clk=%d, ret=%d\n", |
@@ -230,7 +233,9 @@ static u8 sci_clk_get_parent(struct clk_hw *hw) | |||
230 | return 0; | 233 | return 0; |
231 | } | 234 | } |
232 | 235 | ||
233 | return parent_id - clk->clk_id - 1; | 236 | parent_id = parent_id - clk->clk_id - 1; |
237 | |||
238 | return (u8)parent_id; | ||
234 | } | 239 | } |
235 | 240 | ||
236 | /** | 241 | /** |
@@ -280,8 +285,8 @@ static int _sci_clk_build(struct sci_clk_provider *provider, | |||
280 | int i; | 285 | int i; |
281 | int ret = 0; | 286 | int ret = 0; |
282 | 287 | ||
283 | name = kasprintf(GFP_KERNEL, "%s:%d:%d", dev_name(provider->dev), | 288 | name = kasprintf(GFP_KERNEL, "clk:%d:%d", sci_clk->dev_id, |
284 | sci_clk->dev_id, sci_clk->clk_id); | 289 | sci_clk->clk_id); |
285 | 290 | ||
286 | init.name = name; | 291 | init.name = name; |
287 | 292 | ||
@@ -306,8 +311,7 @@ static int _sci_clk_build(struct sci_clk_provider *provider, | |||
306 | for (i = 0; i < sci_clk->num_parents; i++) { | 311 | for (i = 0; i < sci_clk->num_parents; i++) { |
307 | char *parent_name; | 312 | char *parent_name; |
308 | 313 | ||
309 | parent_name = kasprintf(GFP_KERNEL, "%s:%d:%d", | 314 | parent_name = kasprintf(GFP_KERNEL, "clk:%d:%d", |
310 | dev_name(provider->dev), | ||
311 | sci_clk->dev_id, | 315 | sci_clk->dev_id, |
312 | sci_clk->clk_id + 1 + i); | 316 | sci_clk->clk_id + 1 + i); |
313 | if (!parent_name) { | 317 | if (!parent_name) { |
@@ -404,22 +408,9 @@ static const struct of_device_id ti_sci_clk_of_match[] = { | |||
404 | }; | 408 | }; |
405 | MODULE_DEVICE_TABLE(of, ti_sci_clk_of_match); | 409 | MODULE_DEVICE_TABLE(of, ti_sci_clk_of_match); |
406 | 410 | ||
407 | /** | 411 | #ifdef CONFIG_TI_SCI_CLK_PROBE_FROM_FW |
408 | * ti_sci_clk_probe - Probe function for the TI SCI clock driver | 412 | static int ti_sci_scan_clocks_from_fw(struct sci_clk_provider *provider) |
409 | * @pdev: platform device pointer to be probed | ||
410 | * | ||
411 | * Probes the TI SCI clock device. Allocates a new clock provider | ||
412 | * and registers this to the common clock framework. Also applies | ||
413 | * any required flags to the identified clocks via clock lists | ||
414 | * supplied from DT. Returns 0 for success, negative error value | ||
415 | * for failure. | ||
416 | */ | ||
417 | static int ti_sci_clk_probe(struct platform_device *pdev) | ||
418 | { | 413 | { |
419 | struct device *dev = &pdev->dev; | ||
420 | struct device_node *np = dev->of_node; | ||
421 | struct sci_clk_provider *provider; | ||
422 | const struct ti_sci_handle *handle; | ||
423 | int ret; | 414 | int ret; |
424 | int num_clks = 0; | 415 | int num_clks = 0; |
425 | struct sci_clk **clks = NULL; | 416 | struct sci_clk **clks = NULL; |
@@ -428,24 +419,14 @@ static int ti_sci_clk_probe(struct platform_device *pdev) | |||
428 | int max_clks = 0; | 419 | int max_clks = 0; |
429 | int clk_id = 0; | 420 | int clk_id = 0; |
430 | int dev_id = 0; | 421 | int dev_id = 0; |
431 | u8 num_parents; | 422 | u32 num_parents = 0; |
432 | int gap_size = 0; | 423 | int gap_size = 0; |
433 | 424 | struct device *dev = provider->dev; | |
434 | handle = devm_ti_sci_get_handle(dev); | ||
435 | if (IS_ERR(handle)) | ||
436 | return PTR_ERR(handle); | ||
437 | |||
438 | provider = devm_kzalloc(dev, sizeof(*provider), GFP_KERNEL); | ||
439 | if (!provider) | ||
440 | return -ENOMEM; | ||
441 | |||
442 | provider->sci = handle; | ||
443 | provider->ops = &handle->ops.clk_ops; | ||
444 | provider->dev = dev; | ||
445 | 425 | ||
446 | while (1) { | 426 | while (1) { |
447 | ret = provider->ops->get_num_parents(provider->sci, dev_id, | 427 | ret = provider->ops->get_num_parents(provider->sci, dev_id, |
448 | clk_id, &num_parents); | 428 | clk_id, |
429 | (void *)&num_parents); | ||
449 | if (ret) { | 430 | if (ret) { |
450 | gap_size++; | 431 | gap_size++; |
451 | if (!clk_id) { | 432 | if (!clk_id) { |
@@ -502,6 +483,188 @@ static int ti_sci_clk_probe(struct platform_device *pdev) | |||
502 | 483 | ||
503 | devm_kfree(dev, clks); | 484 | devm_kfree(dev, clks); |
504 | 485 | ||
486 | return 0; | ||
487 | } | ||
488 | |||
489 | #else | ||
490 | |||
491 | static int _cmp_sci_clk_list(void *priv, struct list_head *a, | ||
492 | struct list_head *b) | ||
493 | { | ||
494 | struct sci_clk *ca = container_of(a, struct sci_clk, node); | ||
495 | struct sci_clk *cb = container_of(b, struct sci_clk, node); | ||
496 | |||
497 | return _cmp_sci_clk(ca, &cb); | ||
498 | } | ||
499 | |||
500 | static int ti_sci_scan_clocks_from_dt(struct sci_clk_provider *provider) | ||
501 | { | ||
502 | struct device *dev = provider->dev; | ||
503 | struct device_node *np = NULL; | ||
504 | int ret; | ||
505 | int index; | ||
506 | struct of_phandle_args args; | ||
507 | struct list_head clks; | ||
508 | struct sci_clk *sci_clk, *prev; | ||
509 | int num_clks = 0; | ||
510 | int num_parents; | ||
511 | int clk_id; | ||
512 | const char * const clk_names[] = { | ||
513 | "clocks", "assigned-clocks", "assigned-clock-parents", NULL | ||
514 | }; | ||
515 | const char * const *clk_name; | ||
516 | |||
517 | INIT_LIST_HEAD(&clks); | ||
518 | |||
519 | clk_name = clk_names; | ||
520 | |||
521 | while (*clk_name) { | ||
522 | np = of_find_node_with_property(np, *clk_name); | ||
523 | if (!np) { | ||
524 | clk_name++; | ||
525 | break; | ||
526 | } | ||
527 | |||
528 | if (!of_device_is_available(np)) | ||
529 | continue; | ||
530 | |||
531 | index = 0; | ||
532 | |||
533 | do { | ||
534 | ret = of_parse_phandle_with_args(np, *clk_name, | ||
535 | "#clock-cells", index, | ||
536 | &args); | ||
537 | if (ret) | ||
538 | break; | ||
539 | |||
540 | if (args.args_count == 2 && args.np == dev->of_node) { | ||
541 | sci_clk = devm_kzalloc(dev, sizeof(*sci_clk), | ||
542 | GFP_KERNEL); | ||
543 | if (!sci_clk) | ||
544 | return -ENOMEM; | ||
545 | |||
546 | sci_clk->dev_id = args.args[0]; | ||
547 | sci_clk->clk_id = args.args[1]; | ||
548 | sci_clk->provider = provider; | ||
549 | provider->ops->get_num_parents(provider->sci, | ||
550 | sci_clk->dev_id, | ||
551 | sci_clk->clk_id, | ||
552 | (void *)&sci_clk->num_parents); | ||
553 | list_add_tail(&sci_clk->node, &clks); | ||
554 | |||
555 | num_clks++; | ||
556 | |||
557 | num_parents = sci_clk->num_parents; | ||
558 | if (num_parents == 1) | ||
559 | num_parents = 0; | ||
560 | |||
561 | /* | ||
562 | * Linux kernel has inherent limitation | ||
563 | * of 255 clock parents at the moment. | ||
564 | * Right now, it is not expected that | ||
565 | * any mux clock from sci-clk driver | ||
566 | * would exceed that limit either, but | ||
567 | * the ABI basically provides that | ||
568 | * possibility. Print out a warning if | ||
569 | * this happens for any clock. | ||
570 | */ | ||
571 | if (num_parents >= 255) { | ||
572 | dev_warn(dev, "too many parents for dev=%d, clk=%d (%d), cropping to 255.\n", | ||
573 | sci_clk->dev_id, | ||
574 | sci_clk->clk_id, num_parents); | ||
575 | num_parents = 255; | ||
576 | } | ||
577 | |||
578 | clk_id = args.args[1] + 1; | ||
579 | |||
580 | while (num_parents--) { | ||
581 | sci_clk = devm_kzalloc(dev, | ||
582 | sizeof(*sci_clk), | ||
583 | GFP_KERNEL); | ||
584 | if (!sci_clk) | ||
585 | return -ENOMEM; | ||
586 | sci_clk->dev_id = args.args[0]; | ||
587 | sci_clk->clk_id = clk_id++; | ||
588 | sci_clk->provider = provider; | ||
589 | list_add_tail(&sci_clk->node, &clks); | ||
590 | |||
591 | num_clks++; | ||
592 | } | ||
593 | } | ||
594 | |||
595 | index++; | ||
596 | } while (args.np); | ||
597 | } | ||
598 | |||
599 | list_sort(NULL, &clks, _cmp_sci_clk_list); | ||
600 | |||
601 | provider->clocks = devm_kmalloc_array(dev, num_clks, sizeof(sci_clk), | ||
602 | GFP_KERNEL); | ||
603 | if (!provider->clocks) | ||
604 | return -ENOMEM; | ||
605 | |||
606 | num_clks = 0; | ||
607 | prev = NULL; | ||
608 | |||
609 | list_for_each_entry(sci_clk, &clks, node) { | ||
610 | if (prev && prev->dev_id == sci_clk->dev_id && | ||
611 | prev->clk_id == sci_clk->clk_id) | ||
612 | continue; | ||
613 | |||
614 | provider->clocks[num_clks++] = sci_clk; | ||
615 | prev = sci_clk; | ||
616 | } | ||
617 | |||
618 | provider->num_clocks = num_clks; | ||
619 | |||
620 | return 0; | ||
621 | } | ||
622 | #endif | ||
623 | |||
624 | /** | ||
625 | * ti_sci_clk_probe - Probe function for the TI SCI clock driver | ||
626 | * @pdev: platform device pointer to be probed | ||
627 | * | ||
628 | * Probes the TI SCI clock device. Allocates a new clock provider | ||
629 | * and registers this to the common clock framework. Also applies | ||
630 | * any required flags to the identified clocks via clock lists | ||
631 | * supplied from DT. Returns 0 for success, negative error value | ||
632 | * for failure. | ||
633 | */ | ||
634 | static int ti_sci_clk_probe(struct platform_device *pdev) | ||
635 | { | ||
636 | struct device *dev = &pdev->dev; | ||
637 | struct device_node *np = dev->of_node; | ||
638 | struct sci_clk_provider *provider; | ||
639 | const struct ti_sci_handle *handle; | ||
640 | int ret; | ||
641 | |||
642 | handle = devm_ti_sci_get_handle(dev); | ||
643 | if (IS_ERR(handle)) | ||
644 | return PTR_ERR(handle); | ||
645 | |||
646 | provider = devm_kzalloc(dev, sizeof(*provider), GFP_KERNEL); | ||
647 | if (!provider) | ||
648 | return -ENOMEM; | ||
649 | |||
650 | provider->sci = handle; | ||
651 | provider->ops = &handle->ops.clk_ops; | ||
652 | provider->dev = dev; | ||
653 | |||
654 | #ifdef CONFIG_TI_SCI_CLK_PROBE_FROM_FW | ||
655 | ret = ti_sci_scan_clocks_from_fw(provider); | ||
656 | if (ret) { | ||
657 | dev_err(dev, "scan clocks from FW failed: %d\n", ret); | ||
658 | return ret; | ||
659 | } | ||
660 | #else | ||
661 | ret = ti_sci_scan_clocks_from_dt(provider); | ||
662 | if (ret) { | ||
663 | dev_err(dev, "scan clocks from DT failed: %d\n", ret); | ||
664 | return ret; | ||
665 | } | ||
666 | #endif | ||
667 | |||
505 | ret = ti_sci_init_clocks(provider); | 668 | ret = ti_sci_init_clocks(provider); |
506 | if (ret) { | 669 | if (ret) { |
507 | pr_err("ti-sci-init-clocks failed.\n"); | 670 | pr_err("ti-sci-init-clocks failed.\n"); |
diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig index f797f09c6425..ce3d9b300bab 100644 --- a/drivers/clk/mediatek/Kconfig +++ b/drivers/clk/mediatek/Kconfig | |||
@@ -300,4 +300,10 @@ config COMMON_CLK_MT8516 | |||
300 | help | 300 | help |
301 | This driver supports MediaTek MT8516 clocks. | 301 | This driver supports MediaTek MT8516 clocks. |
302 | 302 | ||
303 | config COMMON_CLK_MT8516_AUDSYS | ||
304 | bool "Clock driver for MediaTek MT8516 audsys" | ||
305 | depends on COMMON_CLK_MT8516 | ||
306 | help | ||
307 | This driver supports MediaTek MT8516 audsys clocks. | ||
308 | |||
303 | endmenu | 309 | endmenu |
diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile index f74937b35f68..672de0099eef 100644 --- a/drivers/clk/mediatek/Makefile +++ b/drivers/clk/mediatek/Makefile | |||
@@ -45,3 +45,4 @@ obj-$(CONFIG_COMMON_CLK_MT8183_MMSYS) += clk-mt8183-mm.o | |||
45 | obj-$(CONFIG_COMMON_CLK_MT8183_VDECSYS) += clk-mt8183-vdec.o | 45 | obj-$(CONFIG_COMMON_CLK_MT8183_VDECSYS) += clk-mt8183-vdec.o |
46 | obj-$(CONFIG_COMMON_CLK_MT8183_VENCSYS) += clk-mt8183-venc.o | 46 | obj-$(CONFIG_COMMON_CLK_MT8183_VENCSYS) += clk-mt8183-venc.o |
47 | obj-$(CONFIG_COMMON_CLK_MT8516) += clk-mt8516.o | 47 | obj-$(CONFIG_COMMON_CLK_MT8516) += clk-mt8516.o |
48 | obj-$(CONFIG_COMMON_CLK_MT8516_AUDSYS) += clk-mt8516-aud.o | ||
diff --git a/drivers/clk/mediatek/clk-mt8183.c b/drivers/clk/mediatek/clk-mt8183.c index 9d8651033ae9..1aa5f4059251 100644 --- a/drivers/clk/mediatek/clk-mt8183.c +++ b/drivers/clk/mediatek/clk-mt8183.c | |||
@@ -395,14 +395,6 @@ static const char * const atb_parents[] = { | |||
395 | "syspll_d5" | 395 | "syspll_d5" |
396 | }; | 396 | }; |
397 | 397 | ||
398 | static const char * const sspm_parents[] = { | ||
399 | "clk26m", | ||
400 | "univpll_d2_d4", | ||
401 | "syspll_d2_d2", | ||
402 | "univpll_d2_d2", | ||
403 | "syspll_d3" | ||
404 | }; | ||
405 | |||
406 | static const char * const dpi0_parents[] = { | 398 | static const char * const dpi0_parents[] = { |
407 | "clk26m", | 399 | "clk26m", |
408 | "tvdpll_d2", | 400 | "tvdpll_d2", |
@@ -606,9 +598,6 @@ static const struct mtk_mux top_muxes[] = { | |||
606 | MUX_GATE_CLR_SET_UPD(CLK_TOP_MUX_ATB, "atb_sel", | 598 | MUX_GATE_CLR_SET_UPD(CLK_TOP_MUX_ATB, "atb_sel", |
607 | atb_parents, 0xa0, | 599 | atb_parents, 0xa0, |
608 | 0xa4, 0xa8, 0, 2, 7, 0x004, 24), | 600 | 0xa4, 0xa8, 0, 2, 7, 0x004, 24), |
609 | MUX_GATE_CLR_SET_UPD(CLK_TOP_MUX_SSPM, "sspm_sel", | ||
610 | sspm_parents, 0xa0, | ||
611 | 0xa4, 0xa8, 8, 3, 15, 0x004, 25), | ||
612 | MUX_GATE_CLR_SET_UPD(CLK_TOP_MUX_DPI0, "dpi0_sel", | 601 | MUX_GATE_CLR_SET_UPD(CLK_TOP_MUX_DPI0, "dpi0_sel", |
613 | dpi0_parents, 0xa0, | 602 | dpi0_parents, 0xa0, |
614 | 0xa4, 0xa8, 16, 4, 23, 0x004, 26), | 603 | 0xa4, 0xa8, 16, 4, 23, 0x004, 26), |
@@ -947,12 +936,8 @@ static const struct mtk_gate infra_clks[] = { | |||
947 | "fufs_sel", 13), | 936 | "fufs_sel", 13), |
948 | GATE_INFRA2(CLK_INFRA_MD32_BCLK, "infra_md32_bclk", | 937 | GATE_INFRA2(CLK_INFRA_MD32_BCLK, "infra_md32_bclk", |
949 | "axi_sel", 14), | 938 | "axi_sel", 14), |
950 | GATE_INFRA2(CLK_INFRA_SSPM, "infra_sspm", | ||
951 | "sspm_sel", 15), | ||
952 | GATE_INFRA2(CLK_INFRA_UNIPRO_MBIST, "infra_unipro_mbist", | 939 | GATE_INFRA2(CLK_INFRA_UNIPRO_MBIST, "infra_unipro_mbist", |
953 | "axi_sel", 16), | 940 | "axi_sel", 16), |
954 | GATE_INFRA2(CLK_INFRA_SSPM_BUS_HCLK, "infra_sspm_bus_hclk", | ||
955 | "axi_sel", 17), | ||
956 | GATE_INFRA2(CLK_INFRA_I2C5, "infra_i2c5", | 941 | GATE_INFRA2(CLK_INFRA_I2C5, "infra_i2c5", |
957 | "i2c_sel", 18), | 942 | "i2c_sel", 18), |
958 | GATE_INFRA2(CLK_INFRA_I2C5_ARBITER, "infra_i2c5_arbiter", | 943 | GATE_INFRA2(CLK_INFRA_I2C5_ARBITER, "infra_i2c5_arbiter", |
@@ -986,10 +971,6 @@ static const struct mtk_gate infra_clks[] = { | |||
986 | "msdc50_0_sel", 1), | 971 | "msdc50_0_sel", 1), |
987 | GATE_INFRA3(CLK_INFRA_MSDC2_SELF, "infra_msdc2_self", | 972 | GATE_INFRA3(CLK_INFRA_MSDC2_SELF, "infra_msdc2_self", |
988 | "msdc50_0_sel", 2), | 973 | "msdc50_0_sel", 2), |
989 | GATE_INFRA3(CLK_INFRA_SSPM_26M_SELF, "infra_sspm_26m_self", | ||
990 | "f_f26m_ck", 3), | ||
991 | GATE_INFRA3(CLK_INFRA_SSPM_32K_SELF, "infra_sspm_32k_self", | ||
992 | "f_f26m_ck", 4), | ||
993 | GATE_INFRA3(CLK_INFRA_UFS_AXI, "infra_ufs_axi", | 974 | GATE_INFRA3(CLK_INFRA_UFS_AXI, "infra_ufs_axi", |
994 | "axi_sel", 5), | 975 | "axi_sel", 5), |
995 | GATE_INFRA3(CLK_INFRA_I2C6, "infra_i2c6", | 976 | GATE_INFRA3(CLK_INFRA_I2C6, "infra_i2c6", |
diff --git a/drivers/clk/mediatek/clk-mt8516-aud.c b/drivers/clk/mediatek/clk-mt8516-aud.c new file mode 100644 index 000000000000..6ab3a06dc9d5 --- /dev/null +++ b/drivers/clk/mediatek/clk-mt8516-aud.c | |||
@@ -0,0 +1,65 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * Copyright (c) 2019 MediaTek Inc. | ||
4 | * Author: James Liao <jamesjj.liao@mediatek.com> | ||
5 | * Fabien Parent <fparent@baylibre.com> | ||
6 | */ | ||
7 | |||
8 | #include <linux/clk-provider.h> | ||
9 | #include <linux/of.h> | ||
10 | #include <linux/of_address.h> | ||
11 | #include <linux/of_device.h> | ||
12 | #include <linux/platform_device.h> | ||
13 | |||
14 | #include "clk-mtk.h" | ||
15 | #include "clk-gate.h" | ||
16 | |||
17 | #include <dt-bindings/clock/mt8516-clk.h> | ||
18 | |||
19 | static const struct mtk_gate_regs aud_cg_regs = { | ||
20 | .set_ofs = 0x0, | ||
21 | .clr_ofs = 0x0, | ||
22 | .sta_ofs = 0x0, | ||
23 | }; | ||
24 | |||
25 | #define GATE_AUD(_id, _name, _parent, _shift) { \ | ||
26 | .id = _id, \ | ||
27 | .name = _name, \ | ||
28 | .parent_name = _parent, \ | ||
29 | .regs = &aud_cg_regs, \ | ||
30 | .shift = _shift, \ | ||
31 | .ops = &mtk_clk_gate_ops_no_setclr, \ | ||
32 | } | ||
33 | |||
34 | static const struct mtk_gate aud_clks[] __initconst = { | ||
35 | GATE_AUD(CLK_AUD_AFE, "aud_afe", "clk26m_ck", 2), | ||
36 | GATE_AUD(CLK_AUD_I2S, "aud_i2s", "i2s_infra_bck", 6), | ||
37 | GATE_AUD(CLK_AUD_22M, "aud_22m", "rg_aud_engen1", 8), | ||
38 | GATE_AUD(CLK_AUD_24M, "aud_24m", "rg_aud_engen2", 9), | ||
39 | GATE_AUD(CLK_AUD_INTDIR, "aud_intdir", "rg_aud_spdif_in", 15), | ||
40 | GATE_AUD(CLK_AUD_APLL2_TUNER, "aud_apll2_tuner", "rg_aud_engen2", 18), | ||
41 | GATE_AUD(CLK_AUD_APLL_TUNER, "aud_apll_tuner", "rg_aud_engen1", 19), | ||
42 | GATE_AUD(CLK_AUD_HDMI, "aud_hdmi", "apll12_div4", 20), | ||
43 | GATE_AUD(CLK_AUD_SPDF, "aud_spdf", "apll12_div6", 21), | ||
44 | GATE_AUD(CLK_AUD_ADC, "aud_adc", "aud_afe", 24), | ||
45 | GATE_AUD(CLK_AUD_DAC, "aud_dac", "aud_afe", 25), | ||
46 | GATE_AUD(CLK_AUD_DAC_PREDIS, "aud_dac_predis", "aud_afe", 26), | ||
47 | GATE_AUD(CLK_AUD_TML, "aud_tml", "aud_afe", 27), | ||
48 | }; | ||
49 | |||
50 | static void __init mtk_audsys_init(struct device_node *node) | ||
51 | { | ||
52 | struct clk_onecell_data *clk_data; | ||
53 | int r; | ||
54 | |||
55 | clk_data = mtk_alloc_clk_data(CLK_AUD_NR_CLK); | ||
56 | |||
57 | mtk_clk_register_gates(node, aud_clks, ARRAY_SIZE(aud_clks), clk_data); | ||
58 | |||
59 | r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); | ||
60 | if (r) | ||
61 | pr_err("%s(): could not register clock provider: %d\n", | ||
62 | __func__, r); | ||
63 | |||
64 | } | ||
65 | CLK_OF_DECLARE(mtk_audsys, "mediatek,mt8516-audsys", mtk_audsys_init); | ||
diff --git a/drivers/clk/mediatek/clk-mt8516.c b/drivers/clk/mediatek/clk-mt8516.c index 26fe43cc9ea2..9d4261ecc760 100644 --- a/drivers/clk/mediatek/clk-mt8516.c +++ b/drivers/clk/mediatek/clk-mt8516.c | |||
@@ -231,11 +231,6 @@ static const char * const nfi1x_pad_parents[] __initconst = { | |||
231 | "nfi1x_ck" | 231 | "nfi1x_ck" |
232 | }; | 232 | }; |
233 | 233 | ||
234 | static const char * const ddrphycfg_parents[] __initconst = { | ||
235 | "clk26m_ck", | ||
236 | "mainpll_d16" | ||
237 | }; | ||
238 | |||
239 | static const char * const usb_78m_parents[] __initconst = { | 234 | static const char * const usb_78m_parents[] __initconst = { |
240 | "clk_null", | 235 | "clk_null", |
241 | "clk26m_ck", | 236 | "clk26m_ck", |
diff --git a/drivers/clk/meson/axg.c b/drivers/clk/meson/axg.c index 7a8ef80e5f2c..3ddd0efc9ee0 100644 --- a/drivers/clk/meson/axg.c +++ b/drivers/clk/meson/axg.c | |||
@@ -469,11 +469,6 @@ static struct clk_regmap axg_mpll0_div = { | |||
469 | .shift = 16, | 469 | .shift = 16, |
470 | .width = 9, | 470 | .width = 9, |
471 | }, | 471 | }, |
472 | .ssen = { | ||
473 | .reg_off = HHI_MPLL_CNTL, | ||
474 | .shift = 25, | ||
475 | .width = 1, | ||
476 | }, | ||
477 | .misc = { | 472 | .misc = { |
478 | .reg_off = HHI_PLL_TOP_MISC, | 473 | .reg_off = HHI_PLL_TOP_MISC, |
479 | .shift = 0, | 474 | .shift = 0, |
@@ -568,6 +563,11 @@ static struct clk_regmap axg_mpll2_div = { | |||
568 | .shift = 16, | 563 | .shift = 16, |
569 | .width = 9, | 564 | .width = 9, |
570 | }, | 565 | }, |
566 | .ssen = { | ||
567 | .reg_off = HHI_MPLL_CNTL, | ||
568 | .shift = 25, | ||
569 | .width = 1, | ||
570 | }, | ||
571 | .misc = { | 571 | .misc = { |
572 | .reg_off = HHI_PLL_TOP_MISC, | 572 | .reg_off = HHI_PLL_TOP_MISC, |
573 | .shift = 2, | 573 | .shift = 2, |
diff --git a/drivers/clk/meson/clk-mpll.c b/drivers/clk/meson/clk-mpll.c index f76850d99e59..2d39a8bc367c 100644 --- a/drivers/clk/meson/clk-mpll.c +++ b/drivers/clk/meson/clk-mpll.c | |||
@@ -115,21 +115,12 @@ static int mpll_set_rate(struct clk_hw *hw, | |||
115 | else | 115 | else |
116 | __acquire(mpll->lock); | 116 | __acquire(mpll->lock); |
117 | 117 | ||
118 | /* Enable and set the fractional part */ | 118 | /* Set the fractional part */ |
119 | meson_parm_write(clk->map, &mpll->sdm, sdm); | 119 | meson_parm_write(clk->map, &mpll->sdm, sdm); |
120 | meson_parm_write(clk->map, &mpll->sdm_en, 1); | ||
121 | |||
122 | /* Set additional fractional part enable if required */ | ||
123 | if (MESON_PARM_APPLICABLE(&mpll->ssen)) | ||
124 | meson_parm_write(clk->map, &mpll->ssen, 1); | ||
125 | 120 | ||
126 | /* Set the integer divider part */ | 121 | /* Set the integer divider part */ |
127 | meson_parm_write(clk->map, &mpll->n2, n2); | 122 | meson_parm_write(clk->map, &mpll->n2, n2); |
128 | 123 | ||
129 | /* Set the magic misc bit if required */ | ||
130 | if (MESON_PARM_APPLICABLE(&mpll->misc)) | ||
131 | meson_parm_write(clk->map, &mpll->misc, 1); | ||
132 | |||
133 | if (mpll->lock) | 124 | if (mpll->lock) |
134 | spin_unlock_irqrestore(mpll->lock, flags); | 125 | spin_unlock_irqrestore(mpll->lock, flags); |
135 | else | 126 | else |
@@ -138,6 +129,30 @@ static int mpll_set_rate(struct clk_hw *hw, | |||
138 | return 0; | 129 | return 0; |
139 | } | 130 | } |
140 | 131 | ||
132 | static void mpll_init(struct clk_hw *hw) | ||
133 | { | ||
134 | struct clk_regmap *clk = to_clk_regmap(hw); | ||
135 | struct meson_clk_mpll_data *mpll = meson_clk_mpll_data(clk); | ||
136 | |||
137 | if (mpll->init_count) | ||
138 | regmap_multi_reg_write(clk->map, mpll->init_regs, | ||
139 | mpll->init_count); | ||
140 | |||
141 | /* Enable the fractional part */ | ||
142 | meson_parm_write(clk->map, &mpll->sdm_en, 1); | ||
143 | |||
144 | /* Set spread spectrum if possible */ | ||
145 | if (MESON_PARM_APPLICABLE(&mpll->ssen)) { | ||
146 | unsigned int ss = | ||
147 | mpll->flags & CLK_MESON_MPLL_SPREAD_SPECTRUM ? 1 : 0; | ||
148 | meson_parm_write(clk->map, &mpll->ssen, ss); | ||
149 | } | ||
150 | |||
151 | /* Set the magic misc bit if required */ | ||
152 | if (MESON_PARM_APPLICABLE(&mpll->misc)) | ||
153 | meson_parm_write(clk->map, &mpll->misc, 1); | ||
154 | } | ||
155 | |||
141 | const struct clk_ops meson_clk_mpll_ro_ops = { | 156 | const struct clk_ops meson_clk_mpll_ro_ops = { |
142 | .recalc_rate = mpll_recalc_rate, | 157 | .recalc_rate = mpll_recalc_rate, |
143 | .round_rate = mpll_round_rate, | 158 | .round_rate = mpll_round_rate, |
@@ -148,6 +163,7 @@ const struct clk_ops meson_clk_mpll_ops = { | |||
148 | .recalc_rate = mpll_recalc_rate, | 163 | .recalc_rate = mpll_recalc_rate, |
149 | .round_rate = mpll_round_rate, | 164 | .round_rate = mpll_round_rate, |
150 | .set_rate = mpll_set_rate, | 165 | .set_rate = mpll_set_rate, |
166 | .init = mpll_init, | ||
151 | }; | 167 | }; |
152 | EXPORT_SYMBOL_GPL(meson_clk_mpll_ops); | 168 | EXPORT_SYMBOL_GPL(meson_clk_mpll_ops); |
153 | 169 | ||
diff --git a/drivers/clk/meson/clk-mpll.h b/drivers/clk/meson/clk-mpll.h index cf79340006dd..a991d568c43a 100644 --- a/drivers/clk/meson/clk-mpll.h +++ b/drivers/clk/meson/clk-mpll.h | |||
@@ -18,11 +18,14 @@ struct meson_clk_mpll_data { | |||
18 | struct parm n2; | 18 | struct parm n2; |
19 | struct parm ssen; | 19 | struct parm ssen; |
20 | struct parm misc; | 20 | struct parm misc; |
21 | const struct reg_sequence *init_regs; | ||
22 | unsigned int init_count; | ||
21 | spinlock_t *lock; | 23 | spinlock_t *lock; |
22 | u8 flags; | 24 | u8 flags; |
23 | }; | 25 | }; |
24 | 26 | ||
25 | #define CLK_MESON_MPLL_ROUND_CLOSEST BIT(0) | 27 | #define CLK_MESON_MPLL_ROUND_CLOSEST BIT(0) |
28 | #define CLK_MESON_MPLL_SPREAD_SPECTRUM BIT(1) | ||
26 | 29 | ||
27 | extern const struct clk_ops meson_clk_mpll_ro_ops; | 30 | extern const struct clk_ops meson_clk_mpll_ro_ops; |
28 | extern const struct clk_ops meson_clk_mpll_ops; | 31 | extern const struct clk_ops meson_clk_mpll_ops; |
diff --git a/drivers/clk/meson/g12a.c b/drivers/clk/meson/g12a.c index 206fafd299ea..db1c4ed9d54e 100644 --- a/drivers/clk/meson/g12a.c +++ b/drivers/clk/meson/g12a.c | |||
@@ -150,6 +150,57 @@ static struct clk_regmap g12a_sys_pll = { | |||
150 | }, | 150 | }, |
151 | }; | 151 | }; |
152 | 152 | ||
153 | static struct clk_regmap g12b_sys1_pll_dco = { | ||
154 | .data = &(struct meson_clk_pll_data){ | ||
155 | .en = { | ||
156 | .reg_off = HHI_SYS1_PLL_CNTL0, | ||
157 | .shift = 28, | ||
158 | .width = 1, | ||
159 | }, | ||
160 | .m = { | ||
161 | .reg_off = HHI_SYS1_PLL_CNTL0, | ||
162 | .shift = 0, | ||
163 | .width = 8, | ||
164 | }, | ||
165 | .n = { | ||
166 | .reg_off = HHI_SYS1_PLL_CNTL0, | ||
167 | .shift = 10, | ||
168 | .width = 5, | ||
169 | }, | ||
170 | .l = { | ||
171 | .reg_off = HHI_SYS1_PLL_CNTL0, | ||
172 | .shift = 31, | ||
173 | .width = 1, | ||
174 | }, | ||
175 | .rst = { | ||
176 | .reg_off = HHI_SYS1_PLL_CNTL0, | ||
177 | .shift = 29, | ||
178 | .width = 1, | ||
179 | }, | ||
180 | }, | ||
181 | .hw.init = &(struct clk_init_data){ | ||
182 | .name = "sys1_pll_dco", | ||
183 | .ops = &meson_clk_pll_ro_ops, | ||
184 | .parent_names = (const char *[]){ IN_PREFIX "xtal" }, | ||
185 | .num_parents = 1, | ||
186 | }, | ||
187 | }; | ||
188 | |||
189 | static struct clk_regmap g12b_sys1_pll = { | ||
190 | .data = &(struct clk_regmap_div_data){ | ||
191 | .offset = HHI_SYS1_PLL_CNTL0, | ||
192 | .shift = 16, | ||
193 | .width = 3, | ||
194 | .flags = CLK_DIVIDER_POWER_OF_TWO, | ||
195 | }, | ||
196 | .hw.init = &(struct clk_init_data){ | ||
197 | .name = "sys1_pll", | ||
198 | .ops = &clk_regmap_divider_ro_ops, | ||
199 | .parent_names = (const char *[]){ "sys1_pll_dco" }, | ||
200 | .num_parents = 1, | ||
201 | }, | ||
202 | }; | ||
203 | |||
153 | static struct clk_regmap g12a_sys_pll_div16_en = { | 204 | static struct clk_regmap g12a_sys_pll_div16_en = { |
154 | .data = &(struct clk_regmap_gate_data){ | 205 | .data = &(struct clk_regmap_gate_data){ |
155 | .offset = HHI_SYS_CPU_CLK_CNTL1, | 206 | .offset = HHI_SYS_CPU_CLK_CNTL1, |
@@ -167,6 +218,23 @@ static struct clk_regmap g12a_sys_pll_div16_en = { | |||
167 | }, | 218 | }, |
168 | }; | 219 | }; |
169 | 220 | ||
221 | static struct clk_regmap g12b_sys1_pll_div16_en = { | ||
222 | .data = &(struct clk_regmap_gate_data){ | ||
223 | .offset = HHI_SYS_CPUB_CLK_CNTL1, | ||
224 | .bit_idx = 24, | ||
225 | }, | ||
226 | .hw.init = &(struct clk_init_data) { | ||
227 | .name = "sys1_pll_div16_en", | ||
228 | .ops = &clk_regmap_gate_ro_ops, | ||
229 | .parent_names = (const char *[]){ "sys1_pll" }, | ||
230 | .num_parents = 1, | ||
231 | /* | ||
232 | * This clock is used to debug the sys_pll range | ||
233 | * Linux should not change it at runtime | ||
234 | */ | ||
235 | }, | ||
236 | }; | ||
237 | |||
170 | static struct clk_fixed_factor g12a_sys_pll_div16 = { | 238 | static struct clk_fixed_factor g12a_sys_pll_div16 = { |
171 | .mult = 1, | 239 | .mult = 1, |
172 | .div = 16, | 240 | .div = 16, |
@@ -178,6 +246,17 @@ static struct clk_fixed_factor g12a_sys_pll_div16 = { | |||
178 | }, | 246 | }, |
179 | }; | 247 | }; |
180 | 248 | ||
249 | static struct clk_fixed_factor g12b_sys1_pll_div16 = { | ||
250 | .mult = 1, | ||
251 | .div = 16, | ||
252 | .hw.init = &(struct clk_init_data){ | ||
253 | .name = "sys1_pll_div16", | ||
254 | .ops = &clk_fixed_factor_ops, | ||
255 | .parent_names = (const char *[]){ "sys1_pll_div16_en" }, | ||
256 | .num_parents = 1, | ||
257 | }, | ||
258 | }; | ||
259 | |||
181 | /* Datasheet names this field as "premux0" */ | 260 | /* Datasheet names this field as "premux0" */ |
182 | static struct clk_regmap g12a_cpu_clk_premux0 = { | 261 | static struct clk_regmap g12a_cpu_clk_premux0 = { |
183 | .data = &(struct clk_regmap_mux_data){ | 262 | .data = &(struct clk_regmap_mux_data){ |
@@ -306,6 +385,150 @@ static struct clk_regmap g12a_cpu_clk = { | |||
306 | }, | 385 | }, |
307 | }; | 386 | }; |
308 | 387 | ||
388 | /* Datasheet names this field as "Final_mux_sel" */ | ||
389 | static struct clk_regmap g12b_cpu_clk = { | ||
390 | .data = &(struct clk_regmap_mux_data){ | ||
391 | .offset = HHI_SYS_CPU_CLK_CNTL0, | ||
392 | .mask = 0x1, | ||
393 | .shift = 11, | ||
394 | }, | ||
395 | .hw.init = &(struct clk_init_data){ | ||
396 | .name = "cpu_clk", | ||
397 | .ops = &clk_regmap_mux_ro_ops, | ||
398 | .parent_names = (const char *[]){ "cpu_clk_dyn", | ||
399 | "sys1_pll" }, | ||
400 | .num_parents = 2, | ||
401 | }, | ||
402 | }; | ||
403 | |||
404 | /* Datasheet names this field as "premux0" */ | ||
405 | static struct clk_regmap g12b_cpub_clk_premux0 = { | ||
406 | .data = &(struct clk_regmap_mux_data){ | ||
407 | .offset = HHI_SYS_CPUB_CLK_CNTL, | ||
408 | .mask = 0x3, | ||
409 | .shift = 0, | ||
410 | }, | ||
411 | .hw.init = &(struct clk_init_data){ | ||
412 | .name = "cpub_clk_dyn0_sel", | ||
413 | .ops = &clk_regmap_mux_ro_ops, | ||
414 | .parent_names = (const char *[]){ IN_PREFIX "xtal", | ||
415 | "fclk_div2", | ||
416 | "fclk_div3" }, | ||
417 | .num_parents = 3, | ||
418 | }, | ||
419 | }; | ||
420 | |||
421 | /* Datasheet names this field as "mux0_divn_tcnt" */ | ||
422 | static struct clk_regmap g12b_cpub_clk_mux0_div = { | ||
423 | .data = &(struct clk_regmap_div_data){ | ||
424 | .offset = HHI_SYS_CPUB_CLK_CNTL, | ||
425 | .shift = 4, | ||
426 | .width = 6, | ||
427 | }, | ||
428 | .hw.init = &(struct clk_init_data){ | ||
429 | .name = "cpub_clk_dyn0_div", | ||
430 | .ops = &clk_regmap_divider_ro_ops, | ||
431 | .parent_names = (const char *[]){ "cpub_clk_dyn0_sel" }, | ||
432 | .num_parents = 1, | ||
433 | }, | ||
434 | }; | ||
435 | |||
436 | /* Datasheet names this field as "postmux0" */ | ||
437 | static struct clk_regmap g12b_cpub_clk_postmux0 = { | ||
438 | .data = &(struct clk_regmap_mux_data){ | ||
439 | .offset = HHI_SYS_CPUB_CLK_CNTL, | ||
440 | .mask = 0x1, | ||
441 | .shift = 2, | ||
442 | }, | ||
443 | .hw.init = &(struct clk_init_data){ | ||
444 | .name = "cpub_clk_dyn0", | ||
445 | .ops = &clk_regmap_mux_ro_ops, | ||
446 | .parent_names = (const char *[]){ "cpub_clk_dyn0_sel", | ||
447 | "cpub_clk_dyn0_div" }, | ||
448 | .num_parents = 2, | ||
449 | }, | ||
450 | }; | ||
451 | |||
452 | /* Datasheet names this field as "premux1" */ | ||
453 | static struct clk_regmap g12b_cpub_clk_premux1 = { | ||
454 | .data = &(struct clk_regmap_mux_data){ | ||
455 | .offset = HHI_SYS_CPUB_CLK_CNTL, | ||
456 | .mask = 0x3, | ||
457 | .shift = 16, | ||
458 | }, | ||
459 | .hw.init = &(struct clk_init_data){ | ||
460 | .name = "cpub_clk_dyn1_sel", | ||
461 | .ops = &clk_regmap_mux_ro_ops, | ||
462 | .parent_names = (const char *[]){ IN_PREFIX "xtal", | ||
463 | "fclk_div2", | ||
464 | "fclk_div3" }, | ||
465 | .num_parents = 3, | ||
466 | }, | ||
467 | }; | ||
468 | |||
469 | /* Datasheet names this field as "Mux1_divn_tcnt" */ | ||
470 | static struct clk_regmap g12b_cpub_clk_mux1_div = { | ||
471 | .data = &(struct clk_regmap_div_data){ | ||
472 | .offset = HHI_SYS_CPUB_CLK_CNTL, | ||
473 | .shift = 20, | ||
474 | .width = 6, | ||
475 | }, | ||
476 | .hw.init = &(struct clk_init_data){ | ||
477 | .name = "cpub_clk_dyn1_div", | ||
478 | .ops = &clk_regmap_divider_ro_ops, | ||
479 | .parent_names = (const char *[]){ "cpub_clk_dyn1_sel" }, | ||
480 | .num_parents = 1, | ||
481 | }, | ||
482 | }; | ||
483 | |||
484 | /* Datasheet names this field as "postmux1" */ | ||
485 | static struct clk_regmap g12b_cpub_clk_postmux1 = { | ||
486 | .data = &(struct clk_regmap_mux_data){ | ||
487 | .offset = HHI_SYS_CPUB_CLK_CNTL, | ||
488 | .mask = 0x1, | ||
489 | .shift = 18, | ||
490 | }, | ||
491 | .hw.init = &(struct clk_init_data){ | ||
492 | .name = "cpub_clk_dyn1", | ||
493 | .ops = &clk_regmap_mux_ro_ops, | ||
494 | .parent_names = (const char *[]){ "cpub_clk_dyn1_sel", | ||
495 | "cpub_clk_dyn1_div" }, | ||
496 | .num_parents = 2, | ||
497 | }, | ||
498 | }; | ||
499 | |||
500 | /* Datasheet names this field as "Final_dyn_mux_sel" */ | ||
501 | static struct clk_regmap g12b_cpub_clk_dyn = { | ||
502 | .data = &(struct clk_regmap_mux_data){ | ||
503 | .offset = HHI_SYS_CPUB_CLK_CNTL, | ||
504 | .mask = 0x1, | ||
505 | .shift = 10, | ||
506 | }, | ||
507 | .hw.init = &(struct clk_init_data){ | ||
508 | .name = "cpub_clk_dyn", | ||
509 | .ops = &clk_regmap_mux_ro_ops, | ||
510 | .parent_names = (const char *[]){ "cpub_clk_dyn0", | ||
511 | "cpub_clk_dyn1" }, | ||
512 | .num_parents = 2, | ||
513 | }, | ||
514 | }; | ||
515 | |||
516 | /* Datasheet names this field as "Final_mux_sel" */ | ||
517 | static struct clk_regmap g12b_cpub_clk = { | ||
518 | .data = &(struct clk_regmap_mux_data){ | ||
519 | .offset = HHI_SYS_CPUB_CLK_CNTL, | ||
520 | .mask = 0x1, | ||
521 | .shift = 11, | ||
522 | }, | ||
523 | .hw.init = &(struct clk_init_data){ | ||
524 | .name = "cpub_clk", | ||
525 | .ops = &clk_regmap_mux_ro_ops, | ||
526 | .parent_names = (const char *[]){ "cpub_clk_dyn", | ||
527 | "sys_pll" }, | ||
528 | .num_parents = 2, | ||
529 | }, | ||
530 | }; | ||
531 | |||
309 | static struct clk_regmap g12a_cpu_clk_div16_en = { | 532 | static struct clk_regmap g12a_cpu_clk_div16_en = { |
310 | .data = &(struct clk_regmap_gate_data){ | 533 | .data = &(struct clk_regmap_gate_data){ |
311 | .offset = HHI_SYS_CPU_CLK_CNTL1, | 534 | .offset = HHI_SYS_CPU_CLK_CNTL1, |
@@ -323,6 +546,23 @@ static struct clk_regmap g12a_cpu_clk_div16_en = { | |||
323 | }, | 546 | }, |
324 | }; | 547 | }; |
325 | 548 | ||
549 | static struct clk_regmap g12b_cpub_clk_div16_en = { | ||
550 | .data = &(struct clk_regmap_gate_data){ | ||
551 | .offset = HHI_SYS_CPUB_CLK_CNTL1, | ||
552 | .bit_idx = 1, | ||
553 | }, | ||
554 | .hw.init = &(struct clk_init_data) { | ||
555 | .name = "cpub_clk_div16_en", | ||
556 | .ops = &clk_regmap_gate_ro_ops, | ||
557 | .parent_names = (const char *[]){ "cpub_clk" }, | ||
558 | .num_parents = 1, | ||
559 | /* | ||
560 | * This clock is used to debug the cpu_clk range | ||
561 | * Linux should not change it at runtime | ||
562 | */ | ||
563 | }, | ||
564 | }; | ||
565 | |||
326 | static struct clk_fixed_factor g12a_cpu_clk_div16 = { | 566 | static struct clk_fixed_factor g12a_cpu_clk_div16 = { |
327 | .mult = 1, | 567 | .mult = 1, |
328 | .div = 16, | 568 | .div = 16, |
@@ -334,6 +574,17 @@ static struct clk_fixed_factor g12a_cpu_clk_div16 = { | |||
334 | }, | 574 | }, |
335 | }; | 575 | }; |
336 | 576 | ||
577 | static struct clk_fixed_factor g12b_cpub_clk_div16 = { | ||
578 | .mult = 1, | ||
579 | .div = 16, | ||
580 | .hw.init = &(struct clk_init_data){ | ||
581 | .name = "cpub_clk_div16", | ||
582 | .ops = &clk_fixed_factor_ops, | ||
583 | .parent_names = (const char *[]){ "cpub_clk_div16_en" }, | ||
584 | .num_parents = 1, | ||
585 | }, | ||
586 | }; | ||
587 | |||
337 | static struct clk_regmap g12a_cpu_clk_apb_div = { | 588 | static struct clk_regmap g12a_cpu_clk_apb_div = { |
338 | .data = &(struct clk_regmap_div_data){ | 589 | .data = &(struct clk_regmap_div_data){ |
339 | .offset = HHI_SYS_CPU_CLK_CNTL1, | 590 | .offset = HHI_SYS_CPU_CLK_CNTL1, |
@@ -462,6 +713,240 @@ static struct clk_regmap g12a_cpu_clk_trace = { | |||
462 | }, | 713 | }, |
463 | }; | 714 | }; |
464 | 715 | ||
716 | static struct clk_fixed_factor g12b_cpub_clk_div2 = { | ||
717 | .mult = 1, | ||
718 | .div = 2, | ||
719 | .hw.init = &(struct clk_init_data){ | ||
720 | .name = "cpub_clk_div2", | ||
721 | .ops = &clk_fixed_factor_ops, | ||
722 | .parent_names = (const char *[]){ "cpub_clk" }, | ||
723 | .num_parents = 1, | ||
724 | }, | ||
725 | }; | ||
726 | |||
727 | static struct clk_fixed_factor g12b_cpub_clk_div3 = { | ||
728 | .mult = 1, | ||
729 | .div = 3, | ||
730 | .hw.init = &(struct clk_init_data){ | ||
731 | .name = "cpub_clk_div3", | ||
732 | .ops = &clk_fixed_factor_ops, | ||
733 | .parent_names = (const char *[]){ "cpub_clk" }, | ||
734 | .num_parents = 1, | ||
735 | }, | ||
736 | }; | ||
737 | |||
738 | static struct clk_fixed_factor g12b_cpub_clk_div4 = { | ||
739 | .mult = 1, | ||
740 | .div = 4, | ||
741 | .hw.init = &(struct clk_init_data){ | ||
742 | .name = "cpub_clk_div4", | ||
743 | .ops = &clk_fixed_factor_ops, | ||
744 | .parent_names = (const char *[]){ "cpub_clk" }, | ||
745 | .num_parents = 1, | ||
746 | }, | ||
747 | }; | ||
748 | |||
749 | static struct clk_fixed_factor g12b_cpub_clk_div5 = { | ||
750 | .mult = 1, | ||
751 | .div = 5, | ||
752 | .hw.init = &(struct clk_init_data){ | ||
753 | .name = "cpub_clk_div5", | ||
754 | .ops = &clk_fixed_factor_ops, | ||
755 | .parent_names = (const char *[]){ "cpub_clk" }, | ||
756 | .num_parents = 1, | ||
757 | }, | ||
758 | }; | ||
759 | |||
760 | static struct clk_fixed_factor g12b_cpub_clk_div6 = { | ||
761 | .mult = 1, | ||
762 | .div = 6, | ||
763 | .hw.init = &(struct clk_init_data){ | ||
764 | .name = "cpub_clk_div6", | ||
765 | .ops = &clk_fixed_factor_ops, | ||
766 | .parent_names = (const char *[]){ "cpub_clk" }, | ||
767 | .num_parents = 1, | ||
768 | }, | ||
769 | }; | ||
770 | |||
771 | static struct clk_fixed_factor g12b_cpub_clk_div7 = { | ||
772 | .mult = 1, | ||
773 | .div = 7, | ||
774 | .hw.init = &(struct clk_init_data){ | ||
775 | .name = "cpub_clk_div7", | ||
776 | .ops = &clk_fixed_factor_ops, | ||
777 | .parent_names = (const char *[]){ "cpub_clk" }, | ||
778 | .num_parents = 1, | ||
779 | }, | ||
780 | }; | ||
781 | |||
782 | static struct clk_fixed_factor g12b_cpub_clk_div8 = { | ||
783 | .mult = 1, | ||
784 | .div = 8, | ||
785 | .hw.init = &(struct clk_init_data){ | ||
786 | .name = "cpub_clk_div8", | ||
787 | .ops = &clk_fixed_factor_ops, | ||
788 | .parent_names = (const char *[]){ "cpub_clk" }, | ||
789 | .num_parents = 1, | ||
790 | }, | ||
791 | }; | ||
792 | |||
793 | static u32 mux_table_cpub[] = { 1, 2, 3, 4, 5, 6, 7 }; | ||
794 | static struct clk_regmap g12b_cpub_clk_apb_sel = { | ||
795 | .data = &(struct clk_regmap_mux_data){ | ||
796 | .offset = HHI_SYS_CPUB_CLK_CNTL1, | ||
797 | .mask = 7, | ||
798 | .shift = 3, | ||
799 | .table = mux_table_cpub, | ||
800 | }, | ||
801 | .hw.init = &(struct clk_init_data){ | ||
802 | .name = "cpub_clk_apb_sel", | ||
803 | .ops = &clk_regmap_mux_ro_ops, | ||
804 | .parent_names = (const char *[]){ "cpub_clk_div2", | ||
805 | "cpub_clk_div3", | ||
806 | "cpub_clk_div4", | ||
807 | "cpub_clk_div5", | ||
808 | "cpub_clk_div6", | ||
809 | "cpub_clk_div7", | ||
810 | "cpub_clk_div8" }, | ||
811 | .num_parents = 7, | ||
812 | }, | ||
813 | }; | ||
814 | |||
815 | static struct clk_regmap g12b_cpub_clk_apb = { | ||
816 | .data = &(struct clk_regmap_gate_data){ | ||
817 | .offset = HHI_SYS_CPUB_CLK_CNTL1, | ||
818 | .bit_idx = 16, | ||
819 | .flags = CLK_GATE_SET_TO_DISABLE, | ||
820 | }, | ||
821 | .hw.init = &(struct clk_init_data) { | ||
822 | .name = "cpub_clk_apb", | ||
823 | .ops = &clk_regmap_gate_ro_ops, | ||
824 | .parent_names = (const char *[]){ "cpub_clk_apb_sel" }, | ||
825 | .num_parents = 1, | ||
826 | /* | ||
827 | * This clock is set by the ROM monitor code, | ||
828 | * Linux should not change it at runtime | ||
829 | */ | ||
830 | }, | ||
831 | }; | ||
832 | |||
833 | static struct clk_regmap g12b_cpub_clk_atb_sel = { | ||
834 | .data = &(struct clk_regmap_mux_data){ | ||
835 | .offset = HHI_SYS_CPUB_CLK_CNTL1, | ||
836 | .mask = 7, | ||
837 | .shift = 6, | ||
838 | .table = mux_table_cpub, | ||
839 | }, | ||
840 | .hw.init = &(struct clk_init_data){ | ||
841 | .name = "cpub_clk_atb_sel", | ||
842 | .ops = &clk_regmap_mux_ro_ops, | ||
843 | .parent_names = (const char *[]){ "cpub_clk_div2", | ||
844 | "cpub_clk_div3", | ||
845 | "cpub_clk_div4", | ||
846 | "cpub_clk_div5", | ||
847 | "cpub_clk_div6", | ||
848 | "cpub_clk_div7", | ||
849 | "cpub_clk_div8" }, | ||
850 | .num_parents = 7, | ||
851 | }, | ||
852 | }; | ||
853 | |||
854 | static struct clk_regmap g12b_cpub_clk_atb = { | ||
855 | .data = &(struct clk_regmap_gate_data){ | ||
856 | .offset = HHI_SYS_CPUB_CLK_CNTL1, | ||
857 | .bit_idx = 17, | ||
858 | .flags = CLK_GATE_SET_TO_DISABLE, | ||
859 | }, | ||
860 | .hw.init = &(struct clk_init_data) { | ||
861 | .name = "cpub_clk_atb", | ||
862 | .ops = &clk_regmap_gate_ro_ops, | ||
863 | .parent_names = (const char *[]){ "cpub_clk_atb_sel" }, | ||
864 | .num_parents = 1, | ||
865 | /* | ||
866 | * This clock is set by the ROM monitor code, | ||
867 | * Linux should not change it at runtime | ||
868 | */ | ||
869 | }, | ||
870 | }; | ||
871 | |||
872 | static struct clk_regmap g12b_cpub_clk_axi_sel = { | ||
873 | .data = &(struct clk_regmap_mux_data){ | ||
874 | .offset = HHI_SYS_CPUB_CLK_CNTL1, | ||
875 | .mask = 7, | ||
876 | .shift = 9, | ||
877 | .table = mux_table_cpub, | ||
878 | }, | ||
879 | .hw.init = &(struct clk_init_data){ | ||
880 | .name = "cpub_clk_axi_sel", | ||
881 | .ops = &clk_regmap_mux_ro_ops, | ||
882 | .parent_names = (const char *[]){ "cpub_clk_div2", | ||
883 | "cpub_clk_div3", | ||
884 | "cpub_clk_div4", | ||
885 | "cpub_clk_div5", | ||
886 | "cpub_clk_div6", | ||
887 | "cpub_clk_div7", | ||
888 | "cpub_clk_div8" }, | ||
889 | .num_parents = 7, | ||
890 | }, | ||
891 | }; | ||
892 | |||
893 | static struct clk_regmap g12b_cpub_clk_axi = { | ||
894 | .data = &(struct clk_regmap_gate_data){ | ||
895 | .offset = HHI_SYS_CPUB_CLK_CNTL1, | ||
896 | .bit_idx = 18, | ||
897 | .flags = CLK_GATE_SET_TO_DISABLE, | ||
898 | }, | ||
899 | .hw.init = &(struct clk_init_data) { | ||
900 | .name = "cpub_clk_axi", | ||
901 | .ops = &clk_regmap_gate_ro_ops, | ||
902 | .parent_names = (const char *[]){ "cpub_clk_axi_sel" }, | ||
903 | .num_parents = 1, | ||
904 | /* | ||
905 | * This clock is set by the ROM monitor code, | ||
906 | * Linux should not change it at runtime | ||
907 | */ | ||
908 | }, | ||
909 | }; | ||
910 | |||
911 | static struct clk_regmap g12b_cpub_clk_trace_sel = { | ||
912 | .data = &(struct clk_regmap_mux_data){ | ||
913 | .offset = HHI_SYS_CPUB_CLK_CNTL1, | ||
914 | .mask = 7, | ||
915 | .shift = 20, | ||
916 | .table = mux_table_cpub, | ||
917 | }, | ||
918 | .hw.init = &(struct clk_init_data){ | ||
919 | .name = "cpub_clk_trace_sel", | ||
920 | .ops = &clk_regmap_mux_ro_ops, | ||
921 | .parent_names = (const char *[]){ "cpub_clk_div2", | ||
922 | "cpub_clk_div3", | ||
923 | "cpub_clk_div4", | ||
924 | "cpub_clk_div5", | ||
925 | "cpub_clk_div6", | ||
926 | "cpub_clk_div7", | ||
927 | "cpub_clk_div8" }, | ||
928 | .num_parents = 7, | ||
929 | }, | ||
930 | }; | ||
931 | |||
932 | static struct clk_regmap g12b_cpub_clk_trace = { | ||
933 | .data = &(struct clk_regmap_gate_data){ | ||
934 | .offset = HHI_SYS_CPUB_CLK_CNTL1, | ||
935 | .bit_idx = 23, | ||
936 | .flags = CLK_GATE_SET_TO_DISABLE, | ||
937 | }, | ||
938 | .hw.init = &(struct clk_init_data) { | ||
939 | .name = "cpub_clk_trace", | ||
940 | .ops = &clk_regmap_gate_ro_ops, | ||
941 | .parent_names = (const char *[]){ "cpub_clk_trace_sel" }, | ||
942 | .num_parents = 1, | ||
943 | /* | ||
944 | * This clock is set by the ROM monitor code, | ||
945 | * Linux should not change it at runtime | ||
946 | */ | ||
947 | }, | ||
948 | }; | ||
949 | |||
465 | static const struct pll_mult_range g12a_gp0_pll_mult_range = { | 950 | static const struct pll_mult_range g12a_gp0_pll_mult_range = { |
466 | .min = 55, | 951 | .min = 55, |
467 | .max = 255, | 952 | .max = 255, |
@@ -865,6 +1350,16 @@ static struct clk_regmap g12a_fclk_div3 = { | |||
865 | .ops = &clk_regmap_gate_ops, | 1350 | .ops = &clk_regmap_gate_ops, |
866 | .parent_names = (const char *[]){ "fclk_div3_div" }, | 1351 | .parent_names = (const char *[]){ "fclk_div3_div" }, |
867 | .num_parents = 1, | 1352 | .num_parents = 1, |
1353 | /* | ||
1354 | * This clock is used by the resident firmware and is required | ||
1355 | * by the platform to operate correctly. | ||
1356 | * Until the following condition are met, we need this clock to | ||
1357 | * be marked as critical: | ||
1358 | * a) Mark the clock used by a firmware resource, if possible | ||
1359 | * b) CCF has a clock hand-off mechanism to make the sure the | ||
1360 | * clock stays on until the proper driver comes along | ||
1361 | */ | ||
1362 | .flags = CLK_IS_CRITICAL, | ||
868 | }, | 1363 | }, |
869 | }; | 1364 | }; |
870 | 1365 | ||
@@ -1001,6 +1496,10 @@ static struct clk_fixed_factor g12a_mpll_prediv = { | |||
1001 | }, | 1496 | }, |
1002 | }; | 1497 | }; |
1003 | 1498 | ||
1499 | static const struct reg_sequence g12a_mpll0_init_regs[] = { | ||
1500 | { .reg = HHI_MPLL_CNTL2, .def = 0x40000033 }, | ||
1501 | }; | ||
1502 | |||
1004 | static struct clk_regmap g12a_mpll0_div = { | 1503 | static struct clk_regmap g12a_mpll0_div = { |
1005 | .data = &(struct meson_clk_mpll_data){ | 1504 | .data = &(struct meson_clk_mpll_data){ |
1006 | .sdm = { | 1505 | .sdm = { |
@@ -1024,6 +1523,8 @@ static struct clk_regmap g12a_mpll0_div = { | |||
1024 | .width = 1, | 1523 | .width = 1, |
1025 | }, | 1524 | }, |
1026 | .lock = &meson_clk_lock, | 1525 | .lock = &meson_clk_lock, |
1526 | .init_regs = g12a_mpll0_init_regs, | ||
1527 | .init_count = ARRAY_SIZE(g12a_mpll0_init_regs), | ||
1027 | }, | 1528 | }, |
1028 | .hw.init = &(struct clk_init_data){ | 1529 | .hw.init = &(struct clk_init_data){ |
1029 | .name = "mpll0_div", | 1530 | .name = "mpll0_div", |
@@ -1047,6 +1548,10 @@ static struct clk_regmap g12a_mpll0 = { | |||
1047 | }, | 1548 | }, |
1048 | }; | 1549 | }; |
1049 | 1550 | ||
1551 | static const struct reg_sequence g12a_mpll1_init_regs[] = { | ||
1552 | { .reg = HHI_MPLL_CNTL4, .def = 0x40000033 }, | ||
1553 | }; | ||
1554 | |||
1050 | static struct clk_regmap g12a_mpll1_div = { | 1555 | static struct clk_regmap g12a_mpll1_div = { |
1051 | .data = &(struct meson_clk_mpll_data){ | 1556 | .data = &(struct meson_clk_mpll_data){ |
1052 | .sdm = { | 1557 | .sdm = { |
@@ -1070,6 +1575,8 @@ static struct clk_regmap g12a_mpll1_div = { | |||
1070 | .width = 1, | 1575 | .width = 1, |
1071 | }, | 1576 | }, |
1072 | .lock = &meson_clk_lock, | 1577 | .lock = &meson_clk_lock, |
1578 | .init_regs = g12a_mpll1_init_regs, | ||
1579 | .init_count = ARRAY_SIZE(g12a_mpll1_init_regs), | ||
1073 | }, | 1580 | }, |
1074 | .hw.init = &(struct clk_init_data){ | 1581 | .hw.init = &(struct clk_init_data){ |
1075 | .name = "mpll1_div", | 1582 | .name = "mpll1_div", |
@@ -1093,6 +1600,10 @@ static struct clk_regmap g12a_mpll1 = { | |||
1093 | }, | 1600 | }, |
1094 | }; | 1601 | }; |
1095 | 1602 | ||
1603 | static const struct reg_sequence g12a_mpll2_init_regs[] = { | ||
1604 | { .reg = HHI_MPLL_CNTL6, .def = 0x40000033 }, | ||
1605 | }; | ||
1606 | |||
1096 | static struct clk_regmap g12a_mpll2_div = { | 1607 | static struct clk_regmap g12a_mpll2_div = { |
1097 | .data = &(struct meson_clk_mpll_data){ | 1608 | .data = &(struct meson_clk_mpll_data){ |
1098 | .sdm = { | 1609 | .sdm = { |
@@ -1116,6 +1627,8 @@ static struct clk_regmap g12a_mpll2_div = { | |||
1116 | .width = 1, | 1627 | .width = 1, |
1117 | }, | 1628 | }, |
1118 | .lock = &meson_clk_lock, | 1629 | .lock = &meson_clk_lock, |
1630 | .init_regs = g12a_mpll2_init_regs, | ||
1631 | .init_count = ARRAY_SIZE(g12a_mpll2_init_regs), | ||
1119 | }, | 1632 | }, |
1120 | .hw.init = &(struct clk_init_data){ | 1633 | .hw.init = &(struct clk_init_data){ |
1121 | .name = "mpll2_div", | 1634 | .name = "mpll2_div", |
@@ -1139,6 +1652,10 @@ static struct clk_regmap g12a_mpll2 = { | |||
1139 | }, | 1652 | }, |
1140 | }; | 1653 | }; |
1141 | 1654 | ||
1655 | static const struct reg_sequence g12a_mpll3_init_regs[] = { | ||
1656 | { .reg = HHI_MPLL_CNTL8, .def = 0x40000033 }, | ||
1657 | }; | ||
1658 | |||
1142 | static struct clk_regmap g12a_mpll3_div = { | 1659 | static struct clk_regmap g12a_mpll3_div = { |
1143 | .data = &(struct meson_clk_mpll_data){ | 1660 | .data = &(struct meson_clk_mpll_data){ |
1144 | .sdm = { | 1661 | .sdm = { |
@@ -1162,6 +1679,8 @@ static struct clk_regmap g12a_mpll3_div = { | |||
1162 | .width = 1, | 1679 | .width = 1, |
1163 | }, | 1680 | }, |
1164 | .lock = &meson_clk_lock, | 1681 | .lock = &meson_clk_lock, |
1682 | .init_regs = g12a_mpll3_init_regs, | ||
1683 | .init_count = ARRAY_SIZE(g12a_mpll3_init_regs), | ||
1165 | }, | 1684 | }, |
1166 | .hw.init = &(struct clk_init_data){ | 1685 | .hw.init = &(struct clk_init_data){ |
1167 | .name = "mpll3_div", | 1686 | .name = "mpll3_div", |
@@ -2480,6 +2999,33 @@ static struct clk_regmap g12a_mali = { | |||
2480 | }, | 2999 | }, |
2481 | }; | 3000 | }; |
2482 | 3001 | ||
3002 | static struct clk_regmap g12a_ts_div = { | ||
3003 | .data = &(struct clk_regmap_div_data){ | ||
3004 | .offset = HHI_TS_CLK_CNTL, | ||
3005 | .shift = 0, | ||
3006 | .width = 8, | ||
3007 | }, | ||
3008 | .hw.init = &(struct clk_init_data){ | ||
3009 | .name = "ts_div", | ||
3010 | .ops = &clk_regmap_divider_ro_ops, | ||
3011 | .parent_names = (const char *[]){ "xtal" }, | ||
3012 | .num_parents = 1, | ||
3013 | }, | ||
3014 | }; | ||
3015 | |||
3016 | static struct clk_regmap g12a_ts = { | ||
3017 | .data = &(struct clk_regmap_gate_data){ | ||
3018 | .offset = HHI_TS_CLK_CNTL, | ||
3019 | .bit_idx = 8, | ||
3020 | }, | ||
3021 | .hw.init = &(struct clk_init_data){ | ||
3022 | .name = "ts", | ||
3023 | .ops = &clk_regmap_gate_ops, | ||
3024 | .parent_names = (const char *[]){ "ts_div" }, | ||
3025 | .num_parents = 1, | ||
3026 | }, | ||
3027 | }; | ||
3028 | |||
2483 | /* Everything Else (EE) domain gates */ | 3029 | /* Everything Else (EE) domain gates */ |
2484 | static MESON_GATE(g12a_ddr, HHI_GCLK_MPEG0, 0); | 3030 | static MESON_GATE(g12a_ddr, HHI_GCLK_MPEG0, 0); |
2485 | static MESON_GATE(g12a_dos, HHI_GCLK_MPEG0, 1); | 3031 | static MESON_GATE(g12a_dos, HHI_GCLK_MPEG0, 1); |
@@ -2769,6 +3315,257 @@ static struct clk_hw_onecell_data g12a_hw_onecell_data = { | |||
2769 | [CLKID_VDEC_HEVCF_SEL] = &g12a_vdec_hevcf_sel.hw, | 3315 | [CLKID_VDEC_HEVCF_SEL] = &g12a_vdec_hevcf_sel.hw, |
2770 | [CLKID_VDEC_HEVCF_DIV] = &g12a_vdec_hevcf_div.hw, | 3316 | [CLKID_VDEC_HEVCF_DIV] = &g12a_vdec_hevcf_div.hw, |
2771 | [CLKID_VDEC_HEVCF] = &g12a_vdec_hevcf.hw, | 3317 | [CLKID_VDEC_HEVCF] = &g12a_vdec_hevcf.hw, |
3318 | [CLKID_TS_DIV] = &g12a_ts_div.hw, | ||
3319 | [CLKID_TS] = &g12a_ts.hw, | ||
3320 | [NR_CLKS] = NULL, | ||
3321 | }, | ||
3322 | .num = NR_CLKS, | ||
3323 | }; | ||
3324 | |||
3325 | static struct clk_hw_onecell_data g12b_hw_onecell_data = { | ||
3326 | .hws = { | ||
3327 | [CLKID_SYS_PLL] = &g12a_sys_pll.hw, | ||
3328 | [CLKID_FIXED_PLL] = &g12a_fixed_pll.hw, | ||
3329 | [CLKID_FCLK_DIV2] = &g12a_fclk_div2.hw, | ||
3330 | [CLKID_FCLK_DIV3] = &g12a_fclk_div3.hw, | ||
3331 | [CLKID_FCLK_DIV4] = &g12a_fclk_div4.hw, | ||
3332 | [CLKID_FCLK_DIV5] = &g12a_fclk_div5.hw, | ||
3333 | [CLKID_FCLK_DIV7] = &g12a_fclk_div7.hw, | ||
3334 | [CLKID_FCLK_DIV2P5] = &g12a_fclk_div2p5.hw, | ||
3335 | [CLKID_GP0_PLL] = &g12a_gp0_pll.hw, | ||
3336 | [CLKID_MPEG_SEL] = &g12a_mpeg_clk_sel.hw, | ||
3337 | [CLKID_MPEG_DIV] = &g12a_mpeg_clk_div.hw, | ||
3338 | [CLKID_CLK81] = &g12a_clk81.hw, | ||
3339 | [CLKID_MPLL0] = &g12a_mpll0.hw, | ||
3340 | [CLKID_MPLL1] = &g12a_mpll1.hw, | ||
3341 | [CLKID_MPLL2] = &g12a_mpll2.hw, | ||
3342 | [CLKID_MPLL3] = &g12a_mpll3.hw, | ||
3343 | [CLKID_DDR] = &g12a_ddr.hw, | ||
3344 | [CLKID_DOS] = &g12a_dos.hw, | ||
3345 | [CLKID_AUDIO_LOCKER] = &g12a_audio_locker.hw, | ||
3346 | [CLKID_MIPI_DSI_HOST] = &g12a_mipi_dsi_host.hw, | ||
3347 | [CLKID_ETH_PHY] = &g12a_eth_phy.hw, | ||
3348 | [CLKID_ISA] = &g12a_isa.hw, | ||
3349 | [CLKID_PL301] = &g12a_pl301.hw, | ||
3350 | [CLKID_PERIPHS] = &g12a_periphs.hw, | ||
3351 | [CLKID_SPICC0] = &g12a_spicc_0.hw, | ||
3352 | [CLKID_I2C] = &g12a_i2c.hw, | ||
3353 | [CLKID_SANA] = &g12a_sana.hw, | ||
3354 | [CLKID_SD] = &g12a_sd.hw, | ||
3355 | [CLKID_RNG0] = &g12a_rng0.hw, | ||
3356 | [CLKID_UART0] = &g12a_uart0.hw, | ||
3357 | [CLKID_SPICC1] = &g12a_spicc_1.hw, | ||
3358 | [CLKID_HIU_IFACE] = &g12a_hiu_reg.hw, | ||
3359 | [CLKID_MIPI_DSI_PHY] = &g12a_mipi_dsi_phy.hw, | ||
3360 | [CLKID_ASSIST_MISC] = &g12a_assist_misc.hw, | ||
3361 | [CLKID_SD_EMMC_A] = &g12a_emmc_a.hw, | ||
3362 | [CLKID_SD_EMMC_B] = &g12a_emmc_b.hw, | ||
3363 | [CLKID_SD_EMMC_C] = &g12a_emmc_c.hw, | ||
3364 | [CLKID_AUDIO_CODEC] = &g12a_audio_codec.hw, | ||
3365 | [CLKID_AUDIO] = &g12a_audio.hw, | ||
3366 | [CLKID_ETH] = &g12a_eth_core.hw, | ||
3367 | [CLKID_DEMUX] = &g12a_demux.hw, | ||
3368 | [CLKID_AUDIO_IFIFO] = &g12a_audio_ififo.hw, | ||
3369 | [CLKID_ADC] = &g12a_adc.hw, | ||
3370 | [CLKID_UART1] = &g12a_uart1.hw, | ||
3371 | [CLKID_G2D] = &g12a_g2d.hw, | ||
3372 | [CLKID_RESET] = &g12a_reset.hw, | ||
3373 | [CLKID_PCIE_COMB] = &g12a_pcie_comb.hw, | ||
3374 | [CLKID_PARSER] = &g12a_parser.hw, | ||
3375 | [CLKID_USB] = &g12a_usb_general.hw, | ||
3376 | [CLKID_PCIE_PHY] = &g12a_pcie_phy.hw, | ||
3377 | [CLKID_AHB_ARB0] = &g12a_ahb_arb0.hw, | ||
3378 | [CLKID_AHB_DATA_BUS] = &g12a_ahb_data_bus.hw, | ||
3379 | [CLKID_AHB_CTRL_BUS] = &g12a_ahb_ctrl_bus.hw, | ||
3380 | [CLKID_HTX_HDCP22] = &g12a_htx_hdcp22.hw, | ||
3381 | [CLKID_HTX_PCLK] = &g12a_htx_pclk.hw, | ||
3382 | [CLKID_BT656] = &g12a_bt656.hw, | ||
3383 | [CLKID_USB1_DDR_BRIDGE] = &g12a_usb1_to_ddr.hw, | ||
3384 | [CLKID_MMC_PCLK] = &g12a_mmc_pclk.hw, | ||
3385 | [CLKID_UART2] = &g12a_uart2.hw, | ||
3386 | [CLKID_VPU_INTR] = &g12a_vpu_intr.hw, | ||
3387 | [CLKID_GIC] = &g12a_gic.hw, | ||
3388 | [CLKID_SD_EMMC_A_CLK0_SEL] = &g12a_sd_emmc_a_clk0_sel.hw, | ||
3389 | [CLKID_SD_EMMC_A_CLK0_DIV] = &g12a_sd_emmc_a_clk0_div.hw, | ||
3390 | [CLKID_SD_EMMC_A_CLK0] = &g12a_sd_emmc_a_clk0.hw, | ||
3391 | [CLKID_SD_EMMC_B_CLK0_SEL] = &g12a_sd_emmc_b_clk0_sel.hw, | ||
3392 | [CLKID_SD_EMMC_B_CLK0_DIV] = &g12a_sd_emmc_b_clk0_div.hw, | ||
3393 | [CLKID_SD_EMMC_B_CLK0] = &g12a_sd_emmc_b_clk0.hw, | ||
3394 | [CLKID_SD_EMMC_C_CLK0_SEL] = &g12a_sd_emmc_c_clk0_sel.hw, | ||
3395 | [CLKID_SD_EMMC_C_CLK0_DIV] = &g12a_sd_emmc_c_clk0_div.hw, | ||
3396 | [CLKID_SD_EMMC_C_CLK0] = &g12a_sd_emmc_c_clk0.hw, | ||
3397 | [CLKID_MPLL0_DIV] = &g12a_mpll0_div.hw, | ||
3398 | [CLKID_MPLL1_DIV] = &g12a_mpll1_div.hw, | ||
3399 | [CLKID_MPLL2_DIV] = &g12a_mpll2_div.hw, | ||
3400 | [CLKID_MPLL3_DIV] = &g12a_mpll3_div.hw, | ||
3401 | [CLKID_FCLK_DIV2_DIV] = &g12a_fclk_div2_div.hw, | ||
3402 | [CLKID_FCLK_DIV3_DIV] = &g12a_fclk_div3_div.hw, | ||
3403 | [CLKID_FCLK_DIV4_DIV] = &g12a_fclk_div4_div.hw, | ||
3404 | [CLKID_FCLK_DIV5_DIV] = &g12a_fclk_div5_div.hw, | ||
3405 | [CLKID_FCLK_DIV7_DIV] = &g12a_fclk_div7_div.hw, | ||
3406 | [CLKID_FCLK_DIV2P5_DIV] = &g12a_fclk_div2p5_div.hw, | ||
3407 | [CLKID_HIFI_PLL] = &g12a_hifi_pll.hw, | ||
3408 | [CLKID_VCLK2_VENCI0] = &g12a_vclk2_venci0.hw, | ||
3409 | [CLKID_VCLK2_VENCI1] = &g12a_vclk2_venci1.hw, | ||
3410 | [CLKID_VCLK2_VENCP0] = &g12a_vclk2_vencp0.hw, | ||
3411 | [CLKID_VCLK2_VENCP1] = &g12a_vclk2_vencp1.hw, | ||
3412 | [CLKID_VCLK2_VENCT0] = &g12a_vclk2_venct0.hw, | ||
3413 | [CLKID_VCLK2_VENCT1] = &g12a_vclk2_venct1.hw, | ||
3414 | [CLKID_VCLK2_OTHER] = &g12a_vclk2_other.hw, | ||
3415 | [CLKID_VCLK2_ENCI] = &g12a_vclk2_enci.hw, | ||
3416 | [CLKID_VCLK2_ENCP] = &g12a_vclk2_encp.hw, | ||
3417 | [CLKID_DAC_CLK] = &g12a_dac_clk.hw, | ||
3418 | [CLKID_AOCLK] = &g12a_aoclk_gate.hw, | ||
3419 | [CLKID_IEC958] = &g12a_iec958_gate.hw, | ||
3420 | [CLKID_ENC480P] = &g12a_enc480p.hw, | ||
3421 | [CLKID_RNG1] = &g12a_rng1.hw, | ||
3422 | [CLKID_VCLK2_ENCT] = &g12a_vclk2_enct.hw, | ||
3423 | [CLKID_VCLK2_ENCL] = &g12a_vclk2_encl.hw, | ||
3424 | [CLKID_VCLK2_VENCLMMC] = &g12a_vclk2_venclmmc.hw, | ||
3425 | [CLKID_VCLK2_VENCL] = &g12a_vclk2_vencl.hw, | ||
3426 | [CLKID_VCLK2_OTHER1] = &g12a_vclk2_other1.hw, | ||
3427 | [CLKID_FIXED_PLL_DCO] = &g12a_fixed_pll_dco.hw, | ||
3428 | [CLKID_SYS_PLL_DCO] = &g12a_sys_pll_dco.hw, | ||
3429 | [CLKID_GP0_PLL_DCO] = &g12a_gp0_pll_dco.hw, | ||
3430 | [CLKID_HIFI_PLL_DCO] = &g12a_hifi_pll_dco.hw, | ||
3431 | [CLKID_DMA] = &g12a_dma.hw, | ||
3432 | [CLKID_EFUSE] = &g12a_efuse.hw, | ||
3433 | [CLKID_ROM_BOOT] = &g12a_rom_boot.hw, | ||
3434 | [CLKID_RESET_SEC] = &g12a_reset_sec.hw, | ||
3435 | [CLKID_SEC_AHB_APB3] = &g12a_sec_ahb_apb3.hw, | ||
3436 | [CLKID_MPLL_PREDIV] = &g12a_mpll_prediv.hw, | ||
3437 | [CLKID_VPU_0_SEL] = &g12a_vpu_0_sel.hw, | ||
3438 | [CLKID_VPU_0_DIV] = &g12a_vpu_0_div.hw, | ||
3439 | [CLKID_VPU_0] = &g12a_vpu_0.hw, | ||
3440 | [CLKID_VPU_1_SEL] = &g12a_vpu_1_sel.hw, | ||
3441 | [CLKID_VPU_1_DIV] = &g12a_vpu_1_div.hw, | ||
3442 | [CLKID_VPU_1] = &g12a_vpu_1.hw, | ||
3443 | [CLKID_VPU] = &g12a_vpu.hw, | ||
3444 | [CLKID_VAPB_0_SEL] = &g12a_vapb_0_sel.hw, | ||
3445 | [CLKID_VAPB_0_DIV] = &g12a_vapb_0_div.hw, | ||
3446 | [CLKID_VAPB_0] = &g12a_vapb_0.hw, | ||
3447 | [CLKID_VAPB_1_SEL] = &g12a_vapb_1_sel.hw, | ||
3448 | [CLKID_VAPB_1_DIV] = &g12a_vapb_1_div.hw, | ||
3449 | [CLKID_VAPB_1] = &g12a_vapb_1.hw, | ||
3450 | [CLKID_VAPB_SEL] = &g12a_vapb_sel.hw, | ||
3451 | [CLKID_VAPB] = &g12a_vapb.hw, | ||
3452 | [CLKID_HDMI_PLL_DCO] = &g12a_hdmi_pll_dco.hw, | ||
3453 | [CLKID_HDMI_PLL_OD] = &g12a_hdmi_pll_od.hw, | ||
3454 | [CLKID_HDMI_PLL_OD2] = &g12a_hdmi_pll_od2.hw, | ||
3455 | [CLKID_HDMI_PLL] = &g12a_hdmi_pll.hw, | ||
3456 | [CLKID_VID_PLL] = &g12a_vid_pll_div.hw, | ||
3457 | [CLKID_VID_PLL_SEL] = &g12a_vid_pll_sel.hw, | ||
3458 | [CLKID_VID_PLL_DIV] = &g12a_vid_pll.hw, | ||
3459 | [CLKID_VCLK_SEL] = &g12a_vclk_sel.hw, | ||
3460 | [CLKID_VCLK2_SEL] = &g12a_vclk2_sel.hw, | ||
3461 | [CLKID_VCLK_INPUT] = &g12a_vclk_input.hw, | ||
3462 | [CLKID_VCLK2_INPUT] = &g12a_vclk2_input.hw, | ||
3463 | [CLKID_VCLK_DIV] = &g12a_vclk_div.hw, | ||
3464 | [CLKID_VCLK2_DIV] = &g12a_vclk2_div.hw, | ||
3465 | [CLKID_VCLK] = &g12a_vclk.hw, | ||
3466 | [CLKID_VCLK2] = &g12a_vclk2.hw, | ||
3467 | [CLKID_VCLK_DIV1] = &g12a_vclk_div1.hw, | ||
3468 | [CLKID_VCLK_DIV2_EN] = &g12a_vclk_div2_en.hw, | ||
3469 | [CLKID_VCLK_DIV4_EN] = &g12a_vclk_div4_en.hw, | ||
3470 | [CLKID_VCLK_DIV6_EN] = &g12a_vclk_div6_en.hw, | ||
3471 | [CLKID_VCLK_DIV12_EN] = &g12a_vclk_div12_en.hw, | ||
3472 | [CLKID_VCLK2_DIV1] = &g12a_vclk2_div1.hw, | ||
3473 | [CLKID_VCLK2_DIV2_EN] = &g12a_vclk2_div2_en.hw, | ||
3474 | [CLKID_VCLK2_DIV4_EN] = &g12a_vclk2_div4_en.hw, | ||
3475 | [CLKID_VCLK2_DIV6_EN] = &g12a_vclk2_div6_en.hw, | ||
3476 | [CLKID_VCLK2_DIV12_EN] = &g12a_vclk2_div12_en.hw, | ||
3477 | [CLKID_VCLK_DIV2] = &g12a_vclk_div2.hw, | ||
3478 | [CLKID_VCLK_DIV4] = &g12a_vclk_div4.hw, | ||
3479 | [CLKID_VCLK_DIV6] = &g12a_vclk_div6.hw, | ||
3480 | [CLKID_VCLK_DIV12] = &g12a_vclk_div12.hw, | ||
3481 | [CLKID_VCLK2_DIV2] = &g12a_vclk2_div2.hw, | ||
3482 | [CLKID_VCLK2_DIV4] = &g12a_vclk2_div4.hw, | ||
3483 | [CLKID_VCLK2_DIV6] = &g12a_vclk2_div6.hw, | ||
3484 | [CLKID_VCLK2_DIV12] = &g12a_vclk2_div12.hw, | ||
3485 | [CLKID_CTS_ENCI_SEL] = &g12a_cts_enci_sel.hw, | ||
3486 | [CLKID_CTS_ENCP_SEL] = &g12a_cts_encp_sel.hw, | ||
3487 | [CLKID_CTS_VDAC_SEL] = &g12a_cts_vdac_sel.hw, | ||
3488 | [CLKID_HDMI_TX_SEL] = &g12a_hdmi_tx_sel.hw, | ||
3489 | [CLKID_CTS_ENCI] = &g12a_cts_enci.hw, | ||
3490 | [CLKID_CTS_ENCP] = &g12a_cts_encp.hw, | ||
3491 | [CLKID_CTS_VDAC] = &g12a_cts_vdac.hw, | ||
3492 | [CLKID_HDMI_TX] = &g12a_hdmi_tx.hw, | ||
3493 | [CLKID_HDMI_SEL] = &g12a_hdmi_sel.hw, | ||
3494 | [CLKID_HDMI_DIV] = &g12a_hdmi_div.hw, | ||
3495 | [CLKID_HDMI] = &g12a_hdmi.hw, | ||
3496 | [CLKID_MALI_0_SEL] = &g12a_mali_0_sel.hw, | ||
3497 | [CLKID_MALI_0_DIV] = &g12a_mali_0_div.hw, | ||
3498 | [CLKID_MALI_0] = &g12a_mali_0.hw, | ||
3499 | [CLKID_MALI_1_SEL] = &g12a_mali_1_sel.hw, | ||
3500 | [CLKID_MALI_1_DIV] = &g12a_mali_1_div.hw, | ||
3501 | [CLKID_MALI_1] = &g12a_mali_1.hw, | ||
3502 | [CLKID_MALI] = &g12a_mali.hw, | ||
3503 | [CLKID_MPLL_50M_DIV] = &g12a_mpll_50m_div.hw, | ||
3504 | [CLKID_MPLL_50M] = &g12a_mpll_50m.hw, | ||
3505 | [CLKID_SYS_PLL_DIV16_EN] = &g12a_sys_pll_div16_en.hw, | ||
3506 | [CLKID_SYS_PLL_DIV16] = &g12a_sys_pll_div16.hw, | ||
3507 | [CLKID_CPU_CLK_DYN0_SEL] = &g12a_cpu_clk_premux0.hw, | ||
3508 | [CLKID_CPU_CLK_DYN0_DIV] = &g12a_cpu_clk_mux0_div.hw, | ||
3509 | [CLKID_CPU_CLK_DYN0] = &g12a_cpu_clk_postmux0.hw, | ||
3510 | [CLKID_CPU_CLK_DYN1_SEL] = &g12a_cpu_clk_premux1.hw, | ||
3511 | [CLKID_CPU_CLK_DYN1_DIV] = &g12a_cpu_clk_mux1_div.hw, | ||
3512 | [CLKID_CPU_CLK_DYN1] = &g12a_cpu_clk_postmux1.hw, | ||
3513 | [CLKID_CPU_CLK_DYN] = &g12a_cpu_clk_dyn.hw, | ||
3514 | [CLKID_CPU_CLK] = &g12b_cpu_clk.hw, | ||
3515 | [CLKID_CPU_CLK_DIV16_EN] = &g12a_cpu_clk_div16_en.hw, | ||
3516 | [CLKID_CPU_CLK_DIV16] = &g12a_cpu_clk_div16.hw, | ||
3517 | [CLKID_CPU_CLK_APB_DIV] = &g12a_cpu_clk_apb_div.hw, | ||
3518 | [CLKID_CPU_CLK_APB] = &g12a_cpu_clk_apb.hw, | ||
3519 | [CLKID_CPU_CLK_ATB_DIV] = &g12a_cpu_clk_atb_div.hw, | ||
3520 | [CLKID_CPU_CLK_ATB] = &g12a_cpu_clk_atb.hw, | ||
3521 | [CLKID_CPU_CLK_AXI_DIV] = &g12a_cpu_clk_axi_div.hw, | ||
3522 | [CLKID_CPU_CLK_AXI] = &g12a_cpu_clk_axi.hw, | ||
3523 | [CLKID_CPU_CLK_TRACE_DIV] = &g12a_cpu_clk_trace_div.hw, | ||
3524 | [CLKID_CPU_CLK_TRACE] = &g12a_cpu_clk_trace.hw, | ||
3525 | [CLKID_PCIE_PLL_DCO] = &g12a_pcie_pll_dco.hw, | ||
3526 | [CLKID_PCIE_PLL_DCO_DIV2] = &g12a_pcie_pll_dco_div2.hw, | ||
3527 | [CLKID_PCIE_PLL_OD] = &g12a_pcie_pll_od.hw, | ||
3528 | [CLKID_PCIE_PLL] = &g12a_pcie_pll.hw, | ||
3529 | [CLKID_VDEC_1_SEL] = &g12a_vdec_1_sel.hw, | ||
3530 | [CLKID_VDEC_1_DIV] = &g12a_vdec_1_div.hw, | ||
3531 | [CLKID_VDEC_1] = &g12a_vdec_1.hw, | ||
3532 | [CLKID_VDEC_HEVC_SEL] = &g12a_vdec_hevc_sel.hw, | ||
3533 | [CLKID_VDEC_HEVC_DIV] = &g12a_vdec_hevc_div.hw, | ||
3534 | [CLKID_VDEC_HEVC] = &g12a_vdec_hevc.hw, | ||
3535 | [CLKID_VDEC_HEVCF_SEL] = &g12a_vdec_hevcf_sel.hw, | ||
3536 | [CLKID_VDEC_HEVCF_DIV] = &g12a_vdec_hevcf_div.hw, | ||
3537 | [CLKID_VDEC_HEVCF] = &g12a_vdec_hevcf.hw, | ||
3538 | [CLKID_TS_DIV] = &g12a_ts_div.hw, | ||
3539 | [CLKID_TS] = &g12a_ts.hw, | ||
3540 | [CLKID_SYS1_PLL_DCO] = &g12b_sys1_pll_dco.hw, | ||
3541 | [CLKID_SYS1_PLL] = &g12b_sys1_pll.hw, | ||
3542 | [CLKID_SYS1_PLL_DIV16_EN] = &g12b_sys1_pll_div16_en.hw, | ||
3543 | [CLKID_SYS1_PLL_DIV16] = &g12b_sys1_pll_div16.hw, | ||
3544 | [CLKID_CPUB_CLK_DYN0_SEL] = &g12b_cpub_clk_premux0.hw, | ||
3545 | [CLKID_CPUB_CLK_DYN0_DIV] = &g12b_cpub_clk_mux0_div.hw, | ||
3546 | [CLKID_CPUB_CLK_DYN0] = &g12b_cpub_clk_postmux0.hw, | ||
3547 | [CLKID_CPUB_CLK_DYN1_SEL] = &g12b_cpub_clk_premux1.hw, | ||
3548 | [CLKID_CPUB_CLK_DYN1_DIV] = &g12b_cpub_clk_mux1_div.hw, | ||
3549 | [CLKID_CPUB_CLK_DYN1] = &g12b_cpub_clk_postmux1.hw, | ||
3550 | [CLKID_CPUB_CLK_DYN] = &g12b_cpub_clk_dyn.hw, | ||
3551 | [CLKID_CPUB_CLK] = &g12b_cpub_clk.hw, | ||
3552 | [CLKID_CPUB_CLK_DIV16_EN] = &g12b_cpub_clk_div16_en.hw, | ||
3553 | [CLKID_CPUB_CLK_DIV16] = &g12b_cpub_clk_div16.hw, | ||
3554 | [CLKID_CPUB_CLK_DIV2] = &g12b_cpub_clk_div2.hw, | ||
3555 | [CLKID_CPUB_CLK_DIV3] = &g12b_cpub_clk_div3.hw, | ||
3556 | [CLKID_CPUB_CLK_DIV4] = &g12b_cpub_clk_div4.hw, | ||
3557 | [CLKID_CPUB_CLK_DIV5] = &g12b_cpub_clk_div5.hw, | ||
3558 | [CLKID_CPUB_CLK_DIV6] = &g12b_cpub_clk_div6.hw, | ||
3559 | [CLKID_CPUB_CLK_DIV7] = &g12b_cpub_clk_div7.hw, | ||
3560 | [CLKID_CPUB_CLK_DIV8] = &g12b_cpub_clk_div8.hw, | ||
3561 | [CLKID_CPUB_CLK_APB_SEL] = &g12b_cpub_clk_apb_sel.hw, | ||
3562 | [CLKID_CPUB_CLK_APB] = &g12b_cpub_clk_apb.hw, | ||
3563 | [CLKID_CPUB_CLK_ATB_SEL] = &g12b_cpub_clk_atb_sel.hw, | ||
3564 | [CLKID_CPUB_CLK_ATB] = &g12b_cpub_clk_atb.hw, | ||
3565 | [CLKID_CPUB_CLK_AXI_SEL] = &g12b_cpub_clk_axi_sel.hw, | ||
3566 | [CLKID_CPUB_CLK_AXI] = &g12b_cpub_clk_axi.hw, | ||
3567 | [CLKID_CPUB_CLK_TRACE_SEL] = &g12b_cpub_clk_trace_sel.hw, | ||
3568 | [CLKID_CPUB_CLK_TRACE] = &g12b_cpub_clk_trace.hw, | ||
2772 | [NR_CLKS] = NULL, | 3569 | [NR_CLKS] = NULL, |
2773 | }, | 3570 | }, |
2774 | .num = NR_CLKS, | 3571 | .num = NR_CLKS, |
@@ -2966,16 +3763,52 @@ static struct clk_regmap *const g12a_clk_regmaps[] = { | |||
2966 | &g12a_vdec_hevcf_sel, | 3763 | &g12a_vdec_hevcf_sel, |
2967 | &g12a_vdec_hevcf_div, | 3764 | &g12a_vdec_hevcf_div, |
2968 | &g12a_vdec_hevcf, | 3765 | &g12a_vdec_hevcf, |
3766 | &g12a_ts_div, | ||
3767 | &g12a_ts, | ||
3768 | &g12b_cpu_clk, | ||
3769 | &g12b_sys1_pll_dco, | ||
3770 | &g12b_sys1_pll, | ||
3771 | &g12b_sys1_pll_div16_en, | ||
3772 | &g12b_cpub_clk_premux0, | ||
3773 | &g12b_cpub_clk_mux0_div, | ||
3774 | &g12b_cpub_clk_postmux0, | ||
3775 | &g12b_cpub_clk_premux1, | ||
3776 | &g12b_cpub_clk_mux1_div, | ||
3777 | &g12b_cpub_clk_postmux1, | ||
3778 | &g12b_cpub_clk_dyn, | ||
3779 | &g12b_cpub_clk, | ||
3780 | &g12b_cpub_clk_div16_en, | ||
3781 | &g12b_cpub_clk_apb_sel, | ||
3782 | &g12b_cpub_clk_apb, | ||
3783 | &g12b_cpub_clk_atb_sel, | ||
3784 | &g12b_cpub_clk_atb, | ||
3785 | &g12b_cpub_clk_axi_sel, | ||
3786 | &g12b_cpub_clk_axi, | ||
3787 | &g12b_cpub_clk_trace_sel, | ||
3788 | &g12b_cpub_clk_trace, | ||
3789 | }; | ||
3790 | |||
3791 | static const struct reg_sequence g12a_init_regs[] = { | ||
3792 | { .reg = HHI_MPLL_CNTL0, .def = 0x00000543 }, | ||
2969 | }; | 3793 | }; |
2970 | 3794 | ||
2971 | static const struct meson_eeclkc_data g12a_clkc_data = { | 3795 | static const struct meson_eeclkc_data g12a_clkc_data = { |
2972 | .regmap_clks = g12a_clk_regmaps, | 3796 | .regmap_clks = g12a_clk_regmaps, |
2973 | .regmap_clk_num = ARRAY_SIZE(g12a_clk_regmaps), | 3797 | .regmap_clk_num = ARRAY_SIZE(g12a_clk_regmaps), |
2974 | .hw_onecell_data = &g12a_hw_onecell_data | 3798 | .hw_onecell_data = &g12a_hw_onecell_data, |
3799 | .init_regs = g12a_init_regs, | ||
3800 | .init_count = ARRAY_SIZE(g12a_init_regs), | ||
3801 | }; | ||
3802 | |||
3803 | static const struct meson_eeclkc_data g12b_clkc_data = { | ||
3804 | .regmap_clks = g12a_clk_regmaps, | ||
3805 | .regmap_clk_num = ARRAY_SIZE(g12a_clk_regmaps), | ||
3806 | .hw_onecell_data = &g12b_hw_onecell_data | ||
2975 | }; | 3807 | }; |
2976 | 3808 | ||
2977 | static const struct of_device_id clkc_match_table[] = { | 3809 | static const struct of_device_id clkc_match_table[] = { |
2978 | { .compatible = "amlogic,g12a-clkc", .data = &g12a_clkc_data }, | 3810 | { .compatible = "amlogic,g12a-clkc", .data = &g12a_clkc_data }, |
3811 | { .compatible = "amlogic,g12b-clkc", .data = &g12b_clkc_data }, | ||
2979 | {} | 3812 | {} |
2980 | }; | 3813 | }; |
2981 | 3814 | ||
diff --git a/drivers/clk/meson/g12a.h b/drivers/clk/meson/g12a.h index bcc05cd9882f..c8aed31fbe17 100644 --- a/drivers/clk/meson/g12a.h +++ b/drivers/clk/meson/g12a.h | |||
@@ -69,6 +69,8 @@ | |||
69 | #define HHI_VDEC4_CLK_CNTL 0x1EC | 69 | #define HHI_VDEC4_CLK_CNTL 0x1EC |
70 | #define HHI_HDCP22_CLK_CNTL 0x1F0 | 70 | #define HHI_HDCP22_CLK_CNTL 0x1F0 |
71 | #define HHI_VAPBCLK_CNTL 0x1F4 | 71 | #define HHI_VAPBCLK_CNTL 0x1F4 |
72 | #define HHI_SYS_CPUB_CLK_CNTL1 0x200 | ||
73 | #define HHI_SYS_CPUB_CLK_CNTL 0x208 | ||
72 | #define HHI_VPU_CLKB_CNTL 0x20C | 74 | #define HHI_VPU_CLKB_CNTL 0x20C |
73 | #define HHI_GEN_CLK_CNTL 0x228 | 75 | #define HHI_GEN_CLK_CNTL 0x228 |
74 | #define HHI_VDIN_MEAS_CLK_CNTL 0x250 | 76 | #define HHI_VDIN_MEAS_CLK_CNTL 0x250 |
@@ -102,6 +104,13 @@ | |||
102 | #define HHI_HDMI_PLL_CNTL5 0x334 | 104 | #define HHI_HDMI_PLL_CNTL5 0x334 |
103 | #define HHI_HDMI_PLL_CNTL6 0x338 | 105 | #define HHI_HDMI_PLL_CNTL6 0x338 |
104 | #define HHI_SPICC_CLK_CNTL 0x3dc | 106 | #define HHI_SPICC_CLK_CNTL 0x3dc |
107 | #define HHI_SYS1_PLL_CNTL0 0x380 | ||
108 | #define HHI_SYS1_PLL_CNTL1 0x384 | ||
109 | #define HHI_SYS1_PLL_CNTL2 0x388 | ||
110 | #define HHI_SYS1_PLL_CNTL3 0x38c | ||
111 | #define HHI_SYS1_PLL_CNTL4 0x390 | ||
112 | #define HHI_SYS1_PLL_CNTL5 0x394 | ||
113 | #define HHI_SYS1_PLL_CNTL6 0x398 | ||
105 | 114 | ||
106 | /* | 115 | /* |
107 | * CLKID index values | 116 | * CLKID index values |
@@ -195,8 +204,38 @@ | |||
195 | #define CLKID_VDEC_HEVC_DIV 206 | 204 | #define CLKID_VDEC_HEVC_DIV 206 |
196 | #define CLKID_VDEC_HEVCF_SEL 208 | 205 | #define CLKID_VDEC_HEVCF_SEL 208 |
197 | #define CLKID_VDEC_HEVCF_DIV 209 | 206 | #define CLKID_VDEC_HEVCF_DIV 209 |
207 | #define CLKID_TS_DIV 211 | ||
208 | #define CLKID_SYS1_PLL_DCO 213 | ||
209 | #define CLKID_SYS1_PLL 214 | ||
210 | #define CLKID_SYS1_PLL_DIV16_EN 215 | ||
211 | #define CLKID_SYS1_PLL_DIV16 216 | ||
212 | #define CLKID_CPUB_CLK_DYN0_SEL 217 | ||
213 | #define CLKID_CPUB_CLK_DYN0_DIV 218 | ||
214 | #define CLKID_CPUB_CLK_DYN0 219 | ||
215 | #define CLKID_CPUB_CLK_DYN1_SEL 220 | ||
216 | #define CLKID_CPUB_CLK_DYN1_DIV 221 | ||
217 | #define CLKID_CPUB_CLK_DYN1 222 | ||
218 | #define CLKID_CPUB_CLK_DYN 223 | ||
219 | #define CLKID_CPUB_CLK 224 | ||
220 | #define CLKID_CPUB_CLK_DIV16_EN 225 | ||
221 | #define CLKID_CPUB_CLK_DIV16 226 | ||
222 | #define CLKID_CPUB_CLK_DIV2 227 | ||
223 | #define CLKID_CPUB_CLK_DIV3 228 | ||
224 | #define CLKID_CPUB_CLK_DIV4 229 | ||
225 | #define CLKID_CPUB_CLK_DIV5 230 | ||
226 | #define CLKID_CPUB_CLK_DIV6 231 | ||
227 | #define CLKID_CPUB_CLK_DIV7 232 | ||
228 | #define CLKID_CPUB_CLK_DIV8 233 | ||
229 | #define CLKID_CPUB_CLK_APB_SEL 234 | ||
230 | #define CLKID_CPUB_CLK_APB 235 | ||
231 | #define CLKID_CPUB_CLK_ATB_SEL 236 | ||
232 | #define CLKID_CPUB_CLK_ATB 237 | ||
233 | #define CLKID_CPUB_CLK_AXI_SEL 238 | ||
234 | #define CLKID_CPUB_CLK_AXI 239 | ||
235 | #define CLKID_CPUB_CLK_TRACE_SEL 240 | ||
236 | #define CLKID_CPUB_CLK_TRACE 241 | ||
198 | 237 | ||
199 | #define NR_CLKS 211 | 238 | #define NR_CLKS 242 |
200 | 239 | ||
201 | /* include the CLKIDs that have been made part of the DT binding */ | 240 | /* include the CLKIDs that have been made part of the DT binding */ |
202 | #include <dt-bindings/clock/g12a-clkc.h> | 241 | #include <dt-bindings/clock/g12a-clkc.h> |
diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c index 29ffb4fde714..dab16d9b1af8 100644 --- a/drivers/clk/meson/gxbb.c +++ b/drivers/clk/meson/gxbb.c | |||
@@ -679,11 +679,6 @@ static struct clk_regmap gxbb_mpll0_div = { | |||
679 | .shift = 16, | 679 | .shift = 16, |
680 | .width = 9, | 680 | .width = 9, |
681 | }, | 681 | }, |
682 | .ssen = { | ||
683 | .reg_off = HHI_MPLL_CNTL, | ||
684 | .shift = 25, | ||
685 | .width = 1, | ||
686 | }, | ||
687 | .lock = &meson_clk_lock, | 682 | .lock = &meson_clk_lock, |
688 | }, | 683 | }, |
689 | .hw.init = &(struct clk_init_data){ | 684 | .hw.init = &(struct clk_init_data){ |
diff --git a/drivers/clk/meson/meson-eeclk.c b/drivers/clk/meson/meson-eeclk.c index 37a34c9c3885..6ba2094be257 100644 --- a/drivers/clk/meson/meson-eeclk.c +++ b/drivers/clk/meson/meson-eeclk.c | |||
@@ -34,6 +34,9 @@ int meson_eeclkc_probe(struct platform_device *pdev) | |||
34 | return PTR_ERR(map); | 34 | return PTR_ERR(map); |
35 | } | 35 | } |
36 | 36 | ||
37 | if (data->init_count) | ||
38 | regmap_multi_reg_write(map, data->init_regs, data->init_count); | ||
39 | |||
37 | input = meson_clk_hw_register_input(dev, "xtal", IN_PREFIX "xtal", 0); | 40 | input = meson_clk_hw_register_input(dev, "xtal", IN_PREFIX "xtal", 0); |
38 | if (IS_ERR(input)) { | 41 | if (IS_ERR(input)) { |
39 | ret = PTR_ERR(input); | 42 | ret = PTR_ERR(input); |
diff --git a/drivers/clk/meson/meson-eeclk.h b/drivers/clk/meson/meson-eeclk.h index 1b809b1419fe..9ab5d6fa7ccb 100644 --- a/drivers/clk/meson/meson-eeclk.h +++ b/drivers/clk/meson/meson-eeclk.h | |||
@@ -17,6 +17,8 @@ struct platform_device; | |||
17 | struct meson_eeclkc_data { | 17 | struct meson_eeclkc_data { |
18 | struct clk_regmap *const *regmap_clks; | 18 | struct clk_regmap *const *regmap_clks; |
19 | unsigned int regmap_clk_num; | 19 | unsigned int regmap_clk_num; |
20 | const struct reg_sequence *init_regs; | ||
21 | unsigned int init_count; | ||
20 | struct clk_hw_onecell_data *hw_onecell_data; | 22 | struct clk_hw_onecell_data *hw_onecell_data; |
21 | }; | 23 | }; |
22 | 24 | ||
diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c index 62cd3a7f1f65..537219fa573e 100644 --- a/drivers/clk/meson/meson8b.c +++ b/drivers/clk/meson/meson8b.c | |||
@@ -2153,6 +2153,132 @@ static struct clk_regmap meson8b_vdec_hevc = { | |||
2153 | }, | 2153 | }, |
2154 | }; | 2154 | }; |
2155 | 2155 | ||
2156 | /* TODO: the clock at index 0 is "DDR_PLL" which we don't support yet */ | ||
2157 | static const char * const meson8b_cts_amclk_parent_names[] = { | ||
2158 | "mpll0", "mpll1", "mpll2" | ||
2159 | }; | ||
2160 | |||
2161 | static u32 meson8b_cts_amclk_mux_table[] = { 1, 2, 3 }; | ||
2162 | |||
2163 | static struct clk_regmap meson8b_cts_amclk_sel = { | ||
2164 | .data = &(struct clk_regmap_mux_data){ | ||
2165 | .offset = HHI_AUD_CLK_CNTL, | ||
2166 | .mask = 0x3, | ||
2167 | .shift = 9, | ||
2168 | .table = meson8b_cts_amclk_mux_table, | ||
2169 | .flags = CLK_MUX_ROUND_CLOSEST, | ||
2170 | }, | ||
2171 | .hw.init = &(struct clk_init_data){ | ||
2172 | .name = "cts_amclk_sel", | ||
2173 | .ops = &clk_regmap_mux_ops, | ||
2174 | .parent_names = meson8b_cts_amclk_parent_names, | ||
2175 | .num_parents = ARRAY_SIZE(meson8b_cts_amclk_parent_names), | ||
2176 | }, | ||
2177 | }; | ||
2178 | |||
2179 | static struct clk_regmap meson8b_cts_amclk_div = { | ||
2180 | .data = &(struct clk_regmap_div_data) { | ||
2181 | .offset = HHI_AUD_CLK_CNTL, | ||
2182 | .shift = 0, | ||
2183 | .width = 8, | ||
2184 | .flags = CLK_DIVIDER_ROUND_CLOSEST, | ||
2185 | }, | ||
2186 | .hw.init = &(struct clk_init_data){ | ||
2187 | .name = "cts_amclk_div", | ||
2188 | .ops = &clk_regmap_divider_ops, | ||
2189 | .parent_names = (const char *[]){ "cts_amclk_sel" }, | ||
2190 | .num_parents = 1, | ||
2191 | .flags = CLK_SET_RATE_PARENT, | ||
2192 | }, | ||
2193 | }; | ||
2194 | |||
2195 | static struct clk_regmap meson8b_cts_amclk = { | ||
2196 | .data = &(struct clk_regmap_gate_data){ | ||
2197 | .offset = HHI_AUD_CLK_CNTL, | ||
2198 | .bit_idx = 8, | ||
2199 | }, | ||
2200 | .hw.init = &(struct clk_init_data){ | ||
2201 | .name = "cts_amclk", | ||
2202 | .ops = &clk_regmap_gate_ops, | ||
2203 | .parent_names = (const char *[]){ "cts_amclk_div" }, | ||
2204 | .num_parents = 1, | ||
2205 | .flags = CLK_SET_RATE_PARENT, | ||
2206 | }, | ||
2207 | }; | ||
2208 | |||
2209 | /* TODO: the clock at index 0 is "DDR_PLL" which we don't support yet */ | ||
2210 | static const char * const meson8b_cts_mclk_i958_parent_names[] = { | ||
2211 | "mpll0", "mpll1", "mpll2" | ||
2212 | }; | ||
2213 | |||
2214 | static u32 meson8b_cts_mclk_i958_mux_table[] = { 1, 2, 3 }; | ||
2215 | |||
2216 | static struct clk_regmap meson8b_cts_mclk_i958_sel = { | ||
2217 | .data = &(struct clk_regmap_mux_data){ | ||
2218 | .offset = HHI_AUD_CLK_CNTL2, | ||
2219 | .mask = 0x3, | ||
2220 | .shift = 25, | ||
2221 | .table = meson8b_cts_mclk_i958_mux_table, | ||
2222 | .flags = CLK_MUX_ROUND_CLOSEST, | ||
2223 | }, | ||
2224 | .hw.init = &(struct clk_init_data) { | ||
2225 | .name = "cts_mclk_i958_sel", | ||
2226 | .ops = &clk_regmap_mux_ops, | ||
2227 | .parent_names = meson8b_cts_mclk_i958_parent_names, | ||
2228 | .num_parents = ARRAY_SIZE(meson8b_cts_mclk_i958_parent_names), | ||
2229 | }, | ||
2230 | }; | ||
2231 | |||
2232 | static struct clk_regmap meson8b_cts_mclk_i958_div = { | ||
2233 | .data = &(struct clk_regmap_div_data){ | ||
2234 | .offset = HHI_AUD_CLK_CNTL2, | ||
2235 | .shift = 16, | ||
2236 | .width = 8, | ||
2237 | .flags = CLK_DIVIDER_ROUND_CLOSEST, | ||
2238 | }, | ||
2239 | .hw.init = &(struct clk_init_data) { | ||
2240 | .name = "cts_mclk_i958_div", | ||
2241 | .ops = &clk_regmap_divider_ops, | ||
2242 | .parent_names = (const char *[]){ "cts_mclk_i958_sel" }, | ||
2243 | .num_parents = 1, | ||
2244 | .flags = CLK_SET_RATE_PARENT, | ||
2245 | }, | ||
2246 | }; | ||
2247 | |||
2248 | static struct clk_regmap meson8b_cts_mclk_i958 = { | ||
2249 | .data = &(struct clk_regmap_gate_data){ | ||
2250 | .offset = HHI_AUD_CLK_CNTL2, | ||
2251 | .bit_idx = 24, | ||
2252 | }, | ||
2253 | .hw.init = &(struct clk_init_data){ | ||
2254 | .name = "cts_mclk_i958", | ||
2255 | .ops = &clk_regmap_gate_ops, | ||
2256 | .parent_names = (const char *[]){ "cts_mclk_i958_div" }, | ||
2257 | .num_parents = 1, | ||
2258 | .flags = CLK_SET_RATE_PARENT, | ||
2259 | }, | ||
2260 | }; | ||
2261 | |||
2262 | static struct clk_regmap meson8b_cts_i958 = { | ||
2263 | .data = &(struct clk_regmap_mux_data){ | ||
2264 | .offset = HHI_AUD_CLK_CNTL2, | ||
2265 | .mask = 0x1, | ||
2266 | .shift = 27, | ||
2267 | }, | ||
2268 | .hw.init = &(struct clk_init_data){ | ||
2269 | .name = "cts_i958", | ||
2270 | .ops = &clk_regmap_mux_ops, | ||
2271 | .parent_names = (const char *[]){ "cts_amclk", | ||
2272 | "cts_mclk_i958" }, | ||
2273 | .num_parents = 2, | ||
2274 | /* | ||
2275 | * The parent is specific to origin of the audio data. Let the | ||
2276 | * consumer choose the appropriate parent. | ||
2277 | */ | ||
2278 | .flags = CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, | ||
2279 | }, | ||
2280 | }; | ||
2281 | |||
2156 | /* Everything Else (EE) domain gates */ | 2282 | /* Everything Else (EE) domain gates */ |
2157 | 2283 | ||
2158 | static MESON_GATE(meson8b_ddr, HHI_GCLK_MPEG0, 0); | 2284 | static MESON_GATE(meson8b_ddr, HHI_GCLK_MPEG0, 0); |
@@ -2432,6 +2558,13 @@ static struct clk_hw_onecell_data meson8_hw_onecell_data = { | |||
2432 | [CLKID_VDEC_HEVC_DIV] = &meson8b_vdec_hevc_div.hw, | 2558 | [CLKID_VDEC_HEVC_DIV] = &meson8b_vdec_hevc_div.hw, |
2433 | [CLKID_VDEC_HEVC_EN] = &meson8b_vdec_hevc_en.hw, | 2559 | [CLKID_VDEC_HEVC_EN] = &meson8b_vdec_hevc_en.hw, |
2434 | [CLKID_VDEC_HEVC] = &meson8b_vdec_hevc.hw, | 2560 | [CLKID_VDEC_HEVC] = &meson8b_vdec_hevc.hw, |
2561 | [CLKID_CTS_AMCLK_SEL] = &meson8b_cts_amclk_sel.hw, | ||
2562 | [CLKID_CTS_AMCLK_DIV] = &meson8b_cts_amclk_div.hw, | ||
2563 | [CLKID_CTS_AMCLK] = &meson8b_cts_amclk.hw, | ||
2564 | [CLKID_CTS_MCLK_I958_SEL] = &meson8b_cts_mclk_i958_sel.hw, | ||
2565 | [CLKID_CTS_MCLK_I958_DIV] = &meson8b_cts_mclk_i958_div.hw, | ||
2566 | [CLKID_CTS_MCLK_I958] = &meson8b_cts_mclk_i958.hw, | ||
2567 | [CLKID_CTS_I958] = &meson8b_cts_i958.hw, | ||
2435 | [CLK_NR_CLKS] = NULL, | 2568 | [CLK_NR_CLKS] = NULL, |
2436 | }, | 2569 | }, |
2437 | .num = CLK_NR_CLKS, | 2570 | .num = CLK_NR_CLKS, |
@@ -2641,6 +2774,13 @@ static struct clk_hw_onecell_data meson8b_hw_onecell_data = { | |||
2641 | [CLKID_VDEC_HEVC_DIV] = &meson8b_vdec_hevc_div.hw, | 2774 | [CLKID_VDEC_HEVC_DIV] = &meson8b_vdec_hevc_div.hw, |
2642 | [CLKID_VDEC_HEVC_EN] = &meson8b_vdec_hevc_en.hw, | 2775 | [CLKID_VDEC_HEVC_EN] = &meson8b_vdec_hevc_en.hw, |
2643 | [CLKID_VDEC_HEVC] = &meson8b_vdec_hevc.hw, | 2776 | [CLKID_VDEC_HEVC] = &meson8b_vdec_hevc.hw, |
2777 | [CLKID_CTS_AMCLK_SEL] = &meson8b_cts_amclk_sel.hw, | ||
2778 | [CLKID_CTS_AMCLK_DIV] = &meson8b_cts_amclk_div.hw, | ||
2779 | [CLKID_CTS_AMCLK] = &meson8b_cts_amclk.hw, | ||
2780 | [CLKID_CTS_MCLK_I958_SEL] = &meson8b_cts_mclk_i958_sel.hw, | ||
2781 | [CLKID_CTS_MCLK_I958_DIV] = &meson8b_cts_mclk_i958_div.hw, | ||
2782 | [CLKID_CTS_MCLK_I958] = &meson8b_cts_mclk_i958.hw, | ||
2783 | [CLKID_CTS_I958] = &meson8b_cts_i958.hw, | ||
2644 | [CLK_NR_CLKS] = NULL, | 2784 | [CLK_NR_CLKS] = NULL, |
2645 | }, | 2785 | }, |
2646 | .num = CLK_NR_CLKS, | 2786 | .num = CLK_NR_CLKS, |
@@ -2852,6 +2992,13 @@ static struct clk_hw_onecell_data meson8m2_hw_onecell_data = { | |||
2852 | [CLKID_VDEC_HEVC_DIV] = &meson8b_vdec_hevc_div.hw, | 2992 | [CLKID_VDEC_HEVC_DIV] = &meson8b_vdec_hevc_div.hw, |
2853 | [CLKID_VDEC_HEVC_EN] = &meson8b_vdec_hevc_en.hw, | 2993 | [CLKID_VDEC_HEVC_EN] = &meson8b_vdec_hevc_en.hw, |
2854 | [CLKID_VDEC_HEVC] = &meson8b_vdec_hevc.hw, | 2994 | [CLKID_VDEC_HEVC] = &meson8b_vdec_hevc.hw, |
2995 | [CLKID_CTS_AMCLK_SEL] = &meson8b_cts_amclk_sel.hw, | ||
2996 | [CLKID_CTS_AMCLK_DIV] = &meson8b_cts_amclk_div.hw, | ||
2997 | [CLKID_CTS_AMCLK] = &meson8b_cts_amclk.hw, | ||
2998 | [CLKID_CTS_MCLK_I958_SEL] = &meson8b_cts_mclk_i958_sel.hw, | ||
2999 | [CLKID_CTS_MCLK_I958_DIV] = &meson8b_cts_mclk_i958_div.hw, | ||
3000 | [CLKID_CTS_MCLK_I958] = &meson8b_cts_mclk_i958.hw, | ||
3001 | [CLKID_CTS_I958] = &meson8b_cts_i958.hw, | ||
2855 | [CLK_NR_CLKS] = NULL, | 3002 | [CLK_NR_CLKS] = NULL, |
2856 | }, | 3003 | }, |
2857 | .num = CLK_NR_CLKS, | 3004 | .num = CLK_NR_CLKS, |
@@ -3041,6 +3188,13 @@ static struct clk_regmap *const meson8b_clk_regmaps[] = { | |||
3041 | &meson8b_vdec_hevc_div, | 3188 | &meson8b_vdec_hevc_div, |
3042 | &meson8b_vdec_hevc_en, | 3189 | &meson8b_vdec_hevc_en, |
3043 | &meson8b_vdec_hevc, | 3190 | &meson8b_vdec_hevc, |
3191 | &meson8b_cts_amclk, | ||
3192 | &meson8b_cts_amclk_sel, | ||
3193 | &meson8b_cts_amclk_div, | ||
3194 | &meson8b_cts_mclk_i958_sel, | ||
3195 | &meson8b_cts_mclk_i958_div, | ||
3196 | &meson8b_cts_mclk_i958, | ||
3197 | &meson8b_cts_i958, | ||
3044 | }; | 3198 | }; |
3045 | 3199 | ||
3046 | static const struct meson8b_clk_reset_line { | 3200 | static const struct meson8b_clk_reset_line { |
diff --git a/drivers/clk/meson/meson8b.h b/drivers/clk/meson/meson8b.h index ed37196187e6..c889fbeec30f 100644 --- a/drivers/clk/meson/meson8b.h +++ b/drivers/clk/meson/meson8b.h | |||
@@ -30,7 +30,9 @@ | |||
30 | #define HHI_SYS_CPU_CLK_CNTL1 0x15c /* 0x57 offset in data sheet */ | 30 | #define HHI_SYS_CPU_CLK_CNTL1 0x15c /* 0x57 offset in data sheet */ |
31 | #define HHI_VID_CLK_DIV 0x164 /* 0x59 offset in data sheet */ | 31 | #define HHI_VID_CLK_DIV 0x164 /* 0x59 offset in data sheet */ |
32 | #define HHI_MPEG_CLK_CNTL 0x174 /* 0x5d offset in data sheet */ | 32 | #define HHI_MPEG_CLK_CNTL 0x174 /* 0x5d offset in data sheet */ |
33 | #define HHI_AUD_CLK_CNTL 0x178 /* 0x5e offset in data sheet */ | ||
33 | #define HHI_VID_CLK_CNTL 0x17c /* 0x5f offset in data sheet */ | 34 | #define HHI_VID_CLK_CNTL 0x17c /* 0x5f offset in data sheet */ |
35 | #define HHI_AUD_CLK_CNTL2 0x190 /* 0x64 offset in data sheet */ | ||
34 | #define HHI_VID_CLK_CNTL2 0x194 /* 0x65 offset in data sheet */ | 36 | #define HHI_VID_CLK_CNTL2 0x194 /* 0x65 offset in data sheet */ |
35 | #define HHI_VID_DIVIDER_CNTL 0x198 /* 0x66 offset in data sheet */ | 37 | #define HHI_VID_DIVIDER_CNTL 0x198 /* 0x66 offset in data sheet */ |
36 | #define HHI_SYS_CPU_CLK_CNTL0 0x19c /* 0x67 offset in data sheet */ | 38 | #define HHI_SYS_CPU_CLK_CNTL0 0x19c /* 0x67 offset in data sheet */ |
@@ -171,8 +173,12 @@ | |||
171 | #define CLKID_VDEC_HEVC_SEL 203 | 173 | #define CLKID_VDEC_HEVC_SEL 203 |
172 | #define CLKID_VDEC_HEVC_DIV 204 | 174 | #define CLKID_VDEC_HEVC_DIV 204 |
173 | #define CLKID_VDEC_HEVC_EN 205 | 175 | #define CLKID_VDEC_HEVC_EN 205 |
176 | #define CLKID_CTS_AMCLK_SEL 207 | ||
177 | #define CLKID_CTS_AMCLK_DIV 208 | ||
178 | #define CLKID_CTS_MCLK_I958_SEL 210 | ||
179 | #define CLKID_CTS_MCLK_I958_DIV 211 | ||
174 | 180 | ||
175 | #define CLK_NR_CLKS 207 | 181 | #define CLK_NR_CLKS 214 |
176 | 182 | ||
177 | /* | 183 | /* |
178 | * include the CLKID and RESETID that have | 184 | * include the CLKID and RESETID that have |
diff --git a/drivers/clk/mmp/clk-frac.c b/drivers/clk/mmp/clk-frac.c index cb43d54735b0..90bf181f191a 100644 --- a/drivers/clk/mmp/clk-frac.c +++ b/drivers/clk/mmp/clk-frac.c | |||
@@ -78,11 +78,10 @@ static int clk_factor_set_rate(struct clk_hw *hw, unsigned long drate, | |||
78 | struct mmp_clk_factor_masks *masks = factor->masks; | 78 | struct mmp_clk_factor_masks *masks = factor->masks; |
79 | int i; | 79 | int i; |
80 | unsigned long val; | 80 | unsigned long val; |
81 | unsigned long prev_rate, rate = 0; | 81 | unsigned long rate = 0; |
82 | unsigned long flags = 0; | 82 | unsigned long flags = 0; |
83 | 83 | ||
84 | for (i = 0; i < factor->ftbl_cnt; i++) { | 84 | for (i = 0; i < factor->ftbl_cnt; i++) { |
85 | prev_rate = rate; | ||
86 | rate = (((prate / 10000) * factor->ftbl[i].den) / | 85 | rate = (((prate / 10000) * factor->ftbl[i].den) / |
87 | (factor->ftbl[i].num * factor->masks->factor)) * 10000; | 86 | (factor->ftbl[i].num * factor->masks->factor)) * 10000; |
88 | if (rate > drate) | 87 | if (rate > drate) |
diff --git a/drivers/clk/mvebu/kirkwood.c b/drivers/clk/mvebu/kirkwood.c index 35af3aa18f1c..47680237d0be 100644 --- a/drivers/clk/mvebu/kirkwood.c +++ b/drivers/clk/mvebu/kirkwood.c | |||
@@ -185,6 +185,11 @@ static void __init mv88f6180_get_clk_ratio( | |||
185 | } | 185 | } |
186 | } | 186 | } |
187 | 187 | ||
188 | static u32 __init mv98dx1135_get_tclk_freq(void __iomem *sar) | ||
189 | { | ||
190 | return 166666667; | ||
191 | } | ||
192 | |||
188 | static const struct coreclk_soc_desc kirkwood_coreclks = { | 193 | static const struct coreclk_soc_desc kirkwood_coreclks = { |
189 | .get_tclk_freq = kirkwood_get_tclk_freq, | 194 | .get_tclk_freq = kirkwood_get_tclk_freq, |
190 | .get_cpu_freq = kirkwood_get_cpu_freq, | 195 | .get_cpu_freq = kirkwood_get_cpu_freq, |
@@ -201,6 +206,14 @@ static const struct coreclk_soc_desc mv88f6180_coreclks = { | |||
201 | .num_ratios = ARRAY_SIZE(kirkwood_coreclk_ratios), | 206 | .num_ratios = ARRAY_SIZE(kirkwood_coreclk_ratios), |
202 | }; | 207 | }; |
203 | 208 | ||
209 | static const struct coreclk_soc_desc mv98dx1135_coreclks = { | ||
210 | .get_tclk_freq = mv98dx1135_get_tclk_freq, | ||
211 | .get_cpu_freq = kirkwood_get_cpu_freq, | ||
212 | .get_clk_ratio = kirkwood_get_clk_ratio, | ||
213 | .ratios = kirkwood_coreclk_ratios, | ||
214 | .num_ratios = ARRAY_SIZE(kirkwood_coreclk_ratios), | ||
215 | }; | ||
216 | |||
204 | /* | 217 | /* |
205 | * Clock Gating Control | 218 | * Clock Gating Control |
206 | */ | 219 | */ |
@@ -325,6 +338,8 @@ static void __init kirkwood_clk_init(struct device_node *np) | |||
325 | 338 | ||
326 | if (of_device_is_compatible(np, "marvell,mv88f6180-core-clock")) | 339 | if (of_device_is_compatible(np, "marvell,mv88f6180-core-clock")) |
327 | mvebu_coreclk_setup(np, &mv88f6180_coreclks); | 340 | mvebu_coreclk_setup(np, &mv88f6180_coreclks); |
341 | else if (of_device_is_compatible(np, "marvell,mv98dx1135-core-clock")) | ||
342 | mvebu_coreclk_setup(np, &mv98dx1135_coreclks); | ||
328 | else | 343 | else |
329 | mvebu_coreclk_setup(np, &kirkwood_coreclks); | 344 | mvebu_coreclk_setup(np, &kirkwood_coreclks); |
330 | 345 | ||
@@ -339,3 +354,5 @@ CLK_OF_DECLARE(kirkwood_clk, "marvell,kirkwood-core-clock", | |||
339 | kirkwood_clk_init); | 354 | kirkwood_clk_init); |
340 | CLK_OF_DECLARE(mv88f6180_clk, "marvell,mv88f6180-core-clock", | 355 | CLK_OF_DECLARE(mv88f6180_clk, "marvell,mv88f6180-core-clock", |
341 | kirkwood_clk_init); | 356 | kirkwood_clk_init); |
357 | CLK_OF_DECLARE(98dx1135_clk, "marvell,mv98dx1135-core-clock", | ||
358 | kirkwood_clk_init); | ||
diff --git a/drivers/clk/qcom/gcc-msm8996.c b/drivers/clk/qcom/gcc-msm8996.c index d2f39a972cad..d004cdaa0e39 100644 --- a/drivers/clk/qcom/gcc-msm8996.c +++ b/drivers/clk/qcom/gcc-msm8996.c | |||
@@ -130,22 +130,6 @@ static const char * const gcc_xo_gpll0_gpll4_gpll0_early_div[] = { | |||
130 | "gpll0_early_div" | 130 | "gpll0_early_div" |
131 | }; | 131 | }; |
132 | 132 | ||
133 | static const struct parent_map gcc_xo_gpll0_gpll2_gpll3_gpll0_early_div_map[] = { | ||
134 | { P_XO, 0 }, | ||
135 | { P_GPLL0, 1 }, | ||
136 | { P_GPLL2, 2 }, | ||
137 | { P_GPLL3, 3 }, | ||
138 | { P_GPLL0_EARLY_DIV, 6 } | ||
139 | }; | ||
140 | |||
141 | static const char * const gcc_xo_gpll0_gpll2_gpll3_gpll0_early_div[] = { | ||
142 | "xo", | ||
143 | "gpll0", | ||
144 | "gpll2", | ||
145 | "gpll3", | ||
146 | "gpll0_early_div" | ||
147 | }; | ||
148 | |||
149 | static const struct parent_map gcc_xo_gpll0_gpll1_early_div_gpll1_gpll4_gpll0_early_div_map[] = { | 133 | static const struct parent_map gcc_xo_gpll0_gpll1_early_div_gpll1_gpll4_gpll0_early_div_map[] = { |
150 | { P_XO, 0 }, | 134 | { P_XO, 0 }, |
151 | { P_GPLL0, 1 }, | 135 | { P_GPLL0, 1 }, |
@@ -184,26 +168,6 @@ static const char * const gcc_xo_gpll0_gpll2_gpll3_gpll1_gpll2_early_gpll0_early | |||
184 | "gpll0_early_div" | 168 | "gpll0_early_div" |
185 | }; | 169 | }; |
186 | 170 | ||
187 | static const struct parent_map gcc_xo_gpll0_gpll2_gpll3_gpll1_gpll4_gpll0_early_div_map[] = { | ||
188 | { P_XO, 0 }, | ||
189 | { P_GPLL0, 1 }, | ||
190 | { P_GPLL2, 2 }, | ||
191 | { P_GPLL3, 3 }, | ||
192 | { P_GPLL1, 4 }, | ||
193 | { P_GPLL4, 5 }, | ||
194 | { P_GPLL0_EARLY_DIV, 6 } | ||
195 | }; | ||
196 | |||
197 | static const char * const gcc_xo_gpll0_gpll2_gpll3_gpll1_gpll4_gpll0_early_div[] = { | ||
198 | "xo", | ||
199 | "gpll0", | ||
200 | "gpll2", | ||
201 | "gpll3", | ||
202 | "gpll1", | ||
203 | "gpll4", | ||
204 | "gpll0_early_div" | ||
205 | }; | ||
206 | |||
207 | static struct clk_fixed_factor xo = { | 171 | static struct clk_fixed_factor xo = { |
208 | .mult = 1, | 172 | .mult = 1, |
209 | .div = 1, | 173 | .div = 1, |
diff --git a/drivers/clk/qcom/gcc-qcs404.c b/drivers/clk/qcom/gcc-qcs404.c index a54807eb3b28..29cf464dd2c8 100644 --- a/drivers/clk/qcom/gcc-qcs404.c +++ b/drivers/clk/qcom/gcc-qcs404.c | |||
@@ -2766,6 +2766,13 @@ static const struct qcom_reset_map gcc_qcs404_resets[] = { | |||
2766 | [GCC_PCIE_0_PHY_BCR] = { 0x3e004 }, | 2766 | [GCC_PCIE_0_PHY_BCR] = { 0x3e004 }, |
2767 | [GCC_PCIE_0_LINK_DOWN_BCR] = { 0x3e038 }, | 2767 | [GCC_PCIE_0_LINK_DOWN_BCR] = { 0x3e038 }, |
2768 | [GCC_PCIEPHY_0_PHY_BCR] = { 0x3e03c }, | 2768 | [GCC_PCIEPHY_0_PHY_BCR] = { 0x3e03c }, |
2769 | [GCC_PCIE_0_AXI_MASTER_STICKY_ARES] = { 0x3e040, 6}, | ||
2770 | [GCC_PCIE_0_AHB_ARES] = { 0x3e040, 5 }, | ||
2771 | [GCC_PCIE_0_AXI_SLAVE_ARES] = { 0x3e040, 4 }, | ||
2772 | [GCC_PCIE_0_AXI_MASTER_ARES] = { 0x3e040, 3 }, | ||
2773 | [GCC_PCIE_0_CORE_STICKY_ARES] = { 0x3e040, 2 }, | ||
2774 | [GCC_PCIE_0_SLEEP_ARES] = { 0x3e040, 1 }, | ||
2775 | [GCC_PCIE_0_PIPE_ARES] = { 0x3e040, 0 }, | ||
2769 | [GCC_EMAC_BCR] = { 0x4e000 }, | 2776 | [GCC_EMAC_BCR] = { 0x4e000 }, |
2770 | }; | 2777 | }; |
2771 | 2778 | ||
diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c index 679bc7d8950a..a250f59708d8 100644 --- a/drivers/clk/qcom/gdsc.c +++ b/drivers/clk/qcom/gdsc.c | |||
@@ -141,7 +141,9 @@ static int gdsc_toggle_logic(struct gdsc *sc, enum gdsc_status status) | |||
141 | udelay(1); | 141 | udelay(1); |
142 | } | 142 | } |
143 | 143 | ||
144 | return gdsc_poll_status(sc, status); | 144 | ret = gdsc_poll_status(sc, status); |
145 | WARN(ret, "%s status stuck at 'o%s'", sc->pd.name, status ? "ff" : "n"); | ||
146 | return ret; | ||
145 | } | 147 | } |
146 | 148 | ||
147 | static inline int gdsc_deassert_reset(struct gdsc *sc) | 149 | static inline int gdsc_deassert_reset(struct gdsc *sc) |
diff --git a/drivers/clk/renesas/clk-div6.c b/drivers/clk/renesas/clk-div6.c index e98a9f5b3c90..5ca183e70166 100644 --- a/drivers/clk/renesas/clk-div6.c +++ b/drivers/clk/renesas/clk-div6.c | |||
@@ -30,8 +30,8 @@ | |||
30 | * @div: divisor value (1-64) | 30 | * @div: divisor value (1-64) |
31 | * @src_shift: Shift to access the register bits to select the parent clock | 31 | * @src_shift: Shift to access the register bits to select the parent clock |
32 | * @src_width: Number of register bits to select the parent clock (may be 0) | 32 | * @src_width: Number of register bits to select the parent clock (may be 0) |
33 | * @parents: Array to map from valid parent clocks indices to hardware indices | ||
34 | * @nb: Notifier block to save/restore clock state for system resume | 33 | * @nb: Notifier block to save/restore clock state for system resume |
34 | * @parents: Array to map from valid parent clocks indices to hardware indices | ||
35 | */ | 35 | */ |
36 | struct div6_clock { | 36 | struct div6_clock { |
37 | struct clk_hw hw; | 37 | struct clk_hw hw; |
@@ -39,8 +39,8 @@ struct div6_clock { | |||
39 | unsigned int div; | 39 | unsigned int div; |
40 | u32 src_shift; | 40 | u32 src_shift; |
41 | u32 src_width; | 41 | u32 src_width; |
42 | u8 *parents; | ||
43 | struct notifier_block nb; | 42 | struct notifier_block nb; |
43 | u8 parents[]; | ||
44 | }; | 44 | }; |
45 | 45 | ||
46 | #define to_div6_clock(_hw) container_of(_hw, struct div6_clock, hw) | 46 | #define to_div6_clock(_hw) container_of(_hw, struct div6_clock, hw) |
@@ -221,17 +221,10 @@ struct clk * __init cpg_div6_register(const char *name, | |||
221 | struct clk *clk; | 221 | struct clk *clk; |
222 | unsigned int i; | 222 | unsigned int i; |
223 | 223 | ||
224 | clock = kzalloc(sizeof(*clock), GFP_KERNEL); | 224 | clock = kzalloc(struct_size(clock, parents, num_parents), GFP_KERNEL); |
225 | if (!clock) | 225 | if (!clock) |
226 | return ERR_PTR(-ENOMEM); | 226 | return ERR_PTR(-ENOMEM); |
227 | 227 | ||
228 | clock->parents = kmalloc_array(num_parents, sizeof(*clock->parents), | ||
229 | GFP_KERNEL); | ||
230 | if (!clock->parents) { | ||
231 | clk = ERR_PTR(-ENOMEM); | ||
232 | goto free_clock; | ||
233 | } | ||
234 | |||
235 | clock->reg = reg; | 228 | clock->reg = reg; |
236 | 229 | ||
237 | /* | 230 | /* |
@@ -259,7 +252,7 @@ struct clk * __init cpg_div6_register(const char *name, | |||
259 | pr_err("%s: invalid number of parents for DIV6 clock %s\n", | 252 | pr_err("%s: invalid number of parents for DIV6 clock %s\n", |
260 | __func__, name); | 253 | __func__, name); |
261 | clk = ERR_PTR(-EINVAL); | 254 | clk = ERR_PTR(-EINVAL); |
262 | goto free_parents; | 255 | goto free_clock; |
263 | } | 256 | } |
264 | 257 | ||
265 | /* Filter out invalid parents */ | 258 | /* Filter out invalid parents */ |
@@ -282,7 +275,7 @@ struct clk * __init cpg_div6_register(const char *name, | |||
282 | 275 | ||
283 | clk = clk_register(NULL, &clock->hw); | 276 | clk = clk_register(NULL, &clock->hw); |
284 | if (IS_ERR(clk)) | 277 | if (IS_ERR(clk)) |
285 | goto free_parents; | 278 | goto free_clock; |
286 | 279 | ||
287 | if (notifiers) { | 280 | if (notifiers) { |
288 | clock->nb.notifier_call = cpg_div6_clock_notifier_call; | 281 | clock->nb.notifier_call = cpg_div6_clock_notifier_call; |
@@ -291,8 +284,6 @@ struct clk * __init cpg_div6_register(const char *name, | |||
291 | 284 | ||
292 | return clk; | 285 | return clk; |
293 | 286 | ||
294 | free_parents: | ||
295 | kfree(clock->parents); | ||
296 | free_clock: | 287 | free_clock: |
297 | kfree(clock); | 288 | kfree(clock); |
298 | return clk; | 289 | return clk; |
diff --git a/drivers/clk/renesas/clk-mstp.c b/drivers/clk/renesas/clk-mstp.c index 92ece221b0d4..2db9093546c6 100644 --- a/drivers/clk/renesas/clk-mstp.c +++ b/drivers/clk/renesas/clk-mstp.c | |||
@@ -30,11 +30,12 @@ | |||
30 | /** | 30 | /** |
31 | * struct mstp_clock_group - MSTP gating clocks group | 31 | * struct mstp_clock_group - MSTP gating clocks group |
32 | * | 32 | * |
33 | * @data: clocks in this group | 33 | * @data: clock specifier translation for clocks in this group |
34 | * @smstpcr: module stop control register | 34 | * @smstpcr: module stop control register |
35 | * @mstpsr: module stop status register (optional) | 35 | * @mstpsr: module stop status register (optional) |
36 | * @lock: protects writes to SMSTPCR | 36 | * @lock: protects writes to SMSTPCR |
37 | * @width_8bit: registers are 8-bit, not 32-bit | 37 | * @width_8bit: registers are 8-bit, not 32-bit |
38 | * @clks: clocks in this group | ||
38 | */ | 39 | */ |
39 | struct mstp_clock_group { | 40 | struct mstp_clock_group { |
40 | struct clk_onecell_data data; | 41 | struct clk_onecell_data data; |
@@ -42,6 +43,7 @@ struct mstp_clock_group { | |||
42 | void __iomem *mstpsr; | 43 | void __iomem *mstpsr; |
43 | spinlock_t lock; | 44 | spinlock_t lock; |
44 | bool width_8bit; | 45 | bool width_8bit; |
46 | struct clk *clks[]; | ||
45 | }; | 47 | }; |
46 | 48 | ||
47 | /** | 49 | /** |
@@ -186,14 +188,13 @@ static void __init cpg_mstp_clocks_init(struct device_node *np) | |||
186 | struct clk **clks; | 188 | struct clk **clks; |
187 | unsigned int i; | 189 | unsigned int i; |
188 | 190 | ||
189 | group = kzalloc(sizeof(*group), GFP_KERNEL); | 191 | group = kzalloc(struct_size(group, clks, MSTP_MAX_CLOCKS), GFP_KERNEL); |
190 | clks = kmalloc_array(MSTP_MAX_CLOCKS, sizeof(*clks), GFP_KERNEL); | 192 | if (group == NULL) { |
191 | if (group == NULL || clks == NULL) { | ||
192 | kfree(group); | 193 | kfree(group); |
193 | kfree(clks); | ||
194 | return; | 194 | return; |
195 | } | 195 | } |
196 | 196 | ||
197 | clks = group->clks; | ||
197 | spin_lock_init(&group->lock); | 198 | spin_lock_init(&group->lock); |
198 | group->data.clks = clks; | 199 | group->data.clks = clks; |
199 | 200 | ||
@@ -203,7 +204,6 @@ static void __init cpg_mstp_clocks_init(struct device_node *np) | |||
203 | if (group->smstpcr == NULL) { | 204 | if (group->smstpcr == NULL) { |
204 | pr_err("%s: failed to remap SMSTPCR\n", __func__); | 205 | pr_err("%s: failed to remap SMSTPCR\n", __func__); |
205 | kfree(group); | 206 | kfree(group); |
206 | kfree(clks); | ||
207 | return; | 207 | return; |
208 | } | 208 | } |
209 | 209 | ||
@@ -297,16 +297,12 @@ found: | |||
297 | return PTR_ERR(clk); | 297 | return PTR_ERR(clk); |
298 | 298 | ||
299 | error = pm_clk_create(dev); | 299 | error = pm_clk_create(dev); |
300 | if (error) { | 300 | if (error) |
301 | dev_err(dev, "pm_clk_create failed %d\n", error); | ||
302 | goto fail_put; | 301 | goto fail_put; |
303 | } | ||
304 | 302 | ||
305 | error = pm_clk_add_clk(dev, clk); | 303 | error = pm_clk_add_clk(dev, clk); |
306 | if (error) { | 304 | if (error) |
307 | dev_err(dev, "pm_clk_add_clk %pC failed %d\n", clk, error); | ||
308 | goto fail_destroy; | 305 | goto fail_destroy; |
309 | } | ||
310 | 306 | ||
311 | return 0; | 307 | return 0; |
312 | 308 | ||
diff --git a/drivers/clk/renesas/r8a774a1-cpg-mssr.c b/drivers/clk/renesas/r8a774a1-cpg-mssr.c index 76ed7d1bae36..e05bfa200480 100644 --- a/drivers/clk/renesas/r8a774a1-cpg-mssr.c +++ b/drivers/clk/renesas/r8a774a1-cpg-mssr.c | |||
@@ -113,6 +113,11 @@ static const struct cpg_core_clk r8a774a1_core_clks[] __initconst = { | |||
113 | }; | 113 | }; |
114 | 114 | ||
115 | static const struct mssr_mod_clk r8a774a1_mod_clks[] __initconst = { | 115 | static const struct mssr_mod_clk r8a774a1_mod_clks[] __initconst = { |
116 | DEF_MOD("tmu4", 121, R8A774A1_CLK_S0D6), | ||
117 | DEF_MOD("tmu3", 122, R8A774A1_CLK_S3D2), | ||
118 | DEF_MOD("tmu2", 123, R8A774A1_CLK_S3D2), | ||
119 | DEF_MOD("tmu1", 124, R8A774A1_CLK_S3D2), | ||
120 | DEF_MOD("tmu0", 125, R8A774A1_CLK_CP), | ||
116 | DEF_MOD("fdp1-0", 119, R8A774A1_CLK_S0D1), | 121 | DEF_MOD("fdp1-0", 119, R8A774A1_CLK_S0D1), |
117 | DEF_MOD("scif5", 202, R8A774A1_CLK_S3D4), | 122 | DEF_MOD("scif5", 202, R8A774A1_CLK_S3D4), |
118 | DEF_MOD("scif4", 203, R8A774A1_CLK_S3D4), | 123 | DEF_MOD("scif4", 203, R8A774A1_CLK_S3D4), |
diff --git a/drivers/clk/renesas/r8a7795-cpg-mssr.c b/drivers/clk/renesas/r8a7795-cpg-mssr.c index 9e9a6f2c31e8..fbc8c75f4314 100644 --- a/drivers/clk/renesas/r8a7795-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7795-cpg-mssr.c | |||
@@ -138,6 +138,7 @@ static struct mssr_mod_clk r8a7795_mod_clks[] __initdata = { | |||
138 | DEF_MOD("cmt2", 301, R8A7795_CLK_R), | 138 | DEF_MOD("cmt2", 301, R8A7795_CLK_R), |
139 | DEF_MOD("cmt1", 302, R8A7795_CLK_R), | 139 | DEF_MOD("cmt1", 302, R8A7795_CLK_R), |
140 | DEF_MOD("cmt0", 303, R8A7795_CLK_R), | 140 | DEF_MOD("cmt0", 303, R8A7795_CLK_R), |
141 | DEF_MOD("tpu0", 304, R8A7795_CLK_S3D4), | ||
141 | DEF_MOD("scif2", 310, R8A7795_CLK_S3D4), | 142 | DEF_MOD("scif2", 310, R8A7795_CLK_S3D4), |
142 | DEF_MOD("sdif3", 311, R8A7795_CLK_SD3), | 143 | DEF_MOD("sdif3", 311, R8A7795_CLK_SD3), |
143 | DEF_MOD("sdif2", 312, R8A7795_CLK_SD2), | 144 | DEF_MOD("sdif2", 312, R8A7795_CLK_SD2), |
@@ -201,6 +202,10 @@ static struct mssr_mod_clk r8a7795_mod_clks[] __initdata = { | |||
201 | DEF_MOD("ehci0", 703, R8A7795_CLK_S3D2), | 202 | DEF_MOD("ehci0", 703, R8A7795_CLK_S3D2), |
202 | DEF_MOD("hsusb", 704, R8A7795_CLK_S3D2), | 203 | DEF_MOD("hsusb", 704, R8A7795_CLK_S3D2), |
203 | DEF_MOD("hsusb3", 705, R8A7795_CLK_S3D2), | 204 | DEF_MOD("hsusb3", 705, R8A7795_CLK_S3D2), |
205 | DEF_MOD("cmm3", 708, R8A7795_CLK_S2D1), | ||
206 | DEF_MOD("cmm2", 709, R8A7795_CLK_S2D1), | ||
207 | DEF_MOD("cmm1", 710, R8A7795_CLK_S2D1), | ||
208 | DEF_MOD("cmm0", 711, R8A7795_CLK_S2D1), | ||
204 | DEF_MOD("csi21", 713, R8A7795_CLK_CSI0), /* ES1.x */ | 209 | DEF_MOD("csi21", 713, R8A7795_CLK_CSI0), /* ES1.x */ |
205 | DEF_MOD("csi20", 714, R8A7795_CLK_CSI0), | 210 | DEF_MOD("csi20", 714, R8A7795_CLK_CSI0), |
206 | DEF_MOD("csi41", 715, R8A7795_CLK_CSI0), | 211 | DEF_MOD("csi41", 715, R8A7795_CLK_CSI0), |
diff --git a/drivers/clk/renesas/r8a7796-cpg-mssr.c b/drivers/clk/renesas/r8a7796-cpg-mssr.c index d8e9af5d9ae9..90cc6a102602 100644 --- a/drivers/clk/renesas/r8a7796-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7796-cpg-mssr.c | |||
@@ -134,6 +134,7 @@ static const struct mssr_mod_clk r8a7796_mod_clks[] __initconst = { | |||
134 | DEF_MOD("cmt2", 301, R8A7796_CLK_R), | 134 | DEF_MOD("cmt2", 301, R8A7796_CLK_R), |
135 | DEF_MOD("cmt1", 302, R8A7796_CLK_R), | 135 | DEF_MOD("cmt1", 302, R8A7796_CLK_R), |
136 | DEF_MOD("cmt0", 303, R8A7796_CLK_R), | 136 | DEF_MOD("cmt0", 303, R8A7796_CLK_R), |
137 | DEF_MOD("tpu0", 304, R8A7796_CLK_S3D4), | ||
137 | DEF_MOD("scif2", 310, R8A7796_CLK_S3D4), | 138 | DEF_MOD("scif2", 310, R8A7796_CLK_S3D4), |
138 | DEF_MOD("sdif3", 311, R8A7796_CLK_SD3), | 139 | DEF_MOD("sdif3", 311, R8A7796_CLK_SD3), |
139 | DEF_MOD("sdif2", 312, R8A7796_CLK_SD2), | 140 | DEF_MOD("sdif2", 312, R8A7796_CLK_SD2), |
@@ -180,6 +181,9 @@ static const struct mssr_mod_clk r8a7796_mod_clks[] __initconst = { | |||
180 | DEF_MOD("ehci1", 702, R8A7796_CLK_S3D2), | 181 | DEF_MOD("ehci1", 702, R8A7796_CLK_S3D2), |
181 | DEF_MOD("ehci0", 703, R8A7796_CLK_S3D2), | 182 | DEF_MOD("ehci0", 703, R8A7796_CLK_S3D2), |
182 | DEF_MOD("hsusb", 704, R8A7796_CLK_S3D2), | 183 | DEF_MOD("hsusb", 704, R8A7796_CLK_S3D2), |
184 | DEF_MOD("cmm2", 709, R8A7796_CLK_S2D1), | ||
185 | DEF_MOD("cmm1", 710, R8A7796_CLK_S2D1), | ||
186 | DEF_MOD("cmm0", 711, R8A7796_CLK_S2D1), | ||
183 | DEF_MOD("csi20", 714, R8A7796_CLK_CSI0), | 187 | DEF_MOD("csi20", 714, R8A7796_CLK_CSI0), |
184 | DEF_MOD("csi40", 716, R8A7796_CLK_CSI0), | 188 | DEF_MOD("csi40", 716, R8A7796_CLK_CSI0), |
185 | DEF_MOD("du2", 722, R8A7796_CLK_S2D1), | 189 | DEF_MOD("du2", 722, R8A7796_CLK_S2D1), |
diff --git a/drivers/clk/renesas/r8a77965-cpg-mssr.c b/drivers/clk/renesas/r8a77965-cpg-mssr.c index 8f87e314d949..b4e8c5b7d515 100644 --- a/drivers/clk/renesas/r8a77965-cpg-mssr.c +++ b/drivers/clk/renesas/r8a77965-cpg-mssr.c | |||
@@ -132,6 +132,7 @@ static const struct mssr_mod_clk r8a77965_mod_clks[] __initconst = { | |||
132 | DEF_MOD("cmt2", 301, R8A77965_CLK_R), | 132 | DEF_MOD("cmt2", 301, R8A77965_CLK_R), |
133 | DEF_MOD("cmt1", 302, R8A77965_CLK_R), | 133 | DEF_MOD("cmt1", 302, R8A77965_CLK_R), |
134 | DEF_MOD("cmt0", 303, R8A77965_CLK_R), | 134 | DEF_MOD("cmt0", 303, R8A77965_CLK_R), |
135 | DEF_MOD("tpu0", 304, R8A77965_CLK_S3D4), | ||
135 | DEF_MOD("scif2", 310, R8A77965_CLK_S3D4), | 136 | DEF_MOD("scif2", 310, R8A77965_CLK_S3D4), |
136 | DEF_MOD("sdif3", 311, R8A77965_CLK_SD3), | 137 | DEF_MOD("sdif3", 311, R8A77965_CLK_SD3), |
137 | DEF_MOD("sdif2", 312, R8A77965_CLK_SD2), | 138 | DEF_MOD("sdif2", 312, R8A77965_CLK_SD2), |
@@ -179,6 +180,9 @@ static const struct mssr_mod_clk r8a77965_mod_clks[] __initconst = { | |||
179 | DEF_MOD("ehci1", 702, R8A77965_CLK_S3D2), | 180 | DEF_MOD("ehci1", 702, R8A77965_CLK_S3D2), |
180 | DEF_MOD("ehci0", 703, R8A77965_CLK_S3D2), | 181 | DEF_MOD("ehci0", 703, R8A77965_CLK_S3D2), |
181 | DEF_MOD("hsusb", 704, R8A77965_CLK_S3D2), | 182 | DEF_MOD("hsusb", 704, R8A77965_CLK_S3D2), |
183 | DEF_MOD("cmm3", 708, R8A77965_CLK_S2D1), | ||
184 | DEF_MOD("cmm1", 710, R8A77965_CLK_S2D1), | ||
185 | DEF_MOD("cmm0", 711, R8A77965_CLK_S2D1), | ||
182 | DEF_MOD("csi20", 714, R8A77965_CLK_CSI0), | 186 | DEF_MOD("csi20", 714, R8A77965_CLK_CSI0), |
183 | DEF_MOD("csi40", 716, R8A77965_CLK_CSI0), | 187 | DEF_MOD("csi40", 716, R8A77965_CLK_CSI0), |
184 | DEF_MOD("du3", 721, R8A77965_CLK_S2D1), | 188 | DEF_MOD("du3", 721, R8A77965_CLK_S2D1), |
diff --git a/drivers/clk/renesas/r8a77990-cpg-mssr.c b/drivers/clk/renesas/r8a77990-cpg-mssr.c index 9570404baa58..ceabf55c21c2 100644 --- a/drivers/clk/renesas/r8a77990-cpg-mssr.c +++ b/drivers/clk/renesas/r8a77990-cpg-mssr.c | |||
@@ -183,6 +183,8 @@ static const struct mssr_mod_clk r8a77990_mod_clks[] __initconst = { | |||
183 | 183 | ||
184 | DEF_MOD("ehci0", 703, R8A77990_CLK_S3D2), | 184 | DEF_MOD("ehci0", 703, R8A77990_CLK_S3D2), |
185 | DEF_MOD("hsusb", 704, R8A77990_CLK_S3D2), | 185 | DEF_MOD("hsusb", 704, R8A77990_CLK_S3D2), |
186 | DEF_MOD("cmm1", 710, R8A77990_CLK_S1D1), | ||
187 | DEF_MOD("cmm0", 711, R8A77990_CLK_S1D1), | ||
186 | DEF_MOD("csi40", 716, R8A77990_CLK_CSI0), | 188 | DEF_MOD("csi40", 716, R8A77990_CLK_CSI0), |
187 | DEF_MOD("du1", 723, R8A77990_CLK_S1D1), | 189 | DEF_MOD("du1", 723, R8A77990_CLK_S1D1), |
188 | DEF_MOD("du0", 724, R8A77990_CLK_S1D1), | 190 | DEF_MOD("du0", 724, R8A77990_CLK_S1D1), |
diff --git a/drivers/clk/renesas/r8a77995-cpg-mssr.c b/drivers/clk/renesas/r8a77995-cpg-mssr.c index 68707277b17b..962bb337f2e7 100644 --- a/drivers/clk/renesas/r8a77995-cpg-mssr.c +++ b/drivers/clk/renesas/r8a77995-cpg-mssr.c | |||
@@ -146,6 +146,8 @@ static const struct mssr_mod_clk r8a77995_mod_clks[] __initconst = { | |||
146 | DEF_MOD("vspbs", 627, R8A77995_CLK_S0D1), | 146 | DEF_MOD("vspbs", 627, R8A77995_CLK_S0D1), |
147 | DEF_MOD("ehci0", 703, R8A77995_CLK_S3D2), | 147 | DEF_MOD("ehci0", 703, R8A77995_CLK_S3D2), |
148 | DEF_MOD("hsusb", 704, R8A77995_CLK_S3D2), | 148 | DEF_MOD("hsusb", 704, R8A77995_CLK_S3D2), |
149 | DEF_MOD("cmm1", 710, R8A77995_CLK_S1D1), | ||
150 | DEF_MOD("cmm0", 711, R8A77995_CLK_S1D1), | ||
149 | DEF_MOD("du1", 723, R8A77995_CLK_S1D1), | 151 | DEF_MOD("du1", 723, R8A77995_CLK_S1D1), |
150 | DEF_MOD("du0", 724, R8A77995_CLK_S1D1), | 152 | DEF_MOD("du0", 724, R8A77995_CLK_S1D1), |
151 | DEF_MOD("lvds", 727, R8A77995_CLK_S2D1), | 153 | DEF_MOD("lvds", 727, R8A77995_CLK_S2D1), |
diff --git a/drivers/clk/renesas/r9a06g032-clocks.c b/drivers/clk/renesas/r9a06g032-clocks.c index 7d042183aa37..b33e1383efe3 100644 --- a/drivers/clk/renesas/r9a06g032-clocks.c +++ b/drivers/clk/renesas/r9a06g032-clocks.c | |||
@@ -17,6 +17,8 @@ | |||
17 | #include <linux/of.h> | 17 | #include <linux/of.h> |
18 | #include <linux/of_address.h> | 18 | #include <linux/of_address.h> |
19 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
20 | #include <linux/pm_clock.h> | ||
21 | #include <linux/pm_domain.h> | ||
20 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
21 | #include <linux/spinlock.h> | 23 | #include <linux/spinlock.h> |
22 | #include <dt-bindings/clock/r9a06g032-sysctrl.h> | 24 | #include <dt-bindings/clock/r9a06g032-sysctrl.h> |
@@ -29,6 +31,7 @@ struct r9a06g032_gate { | |||
29 | /* This is used to describe a clock for instantiation */ | 31 | /* This is used to describe a clock for instantiation */ |
30 | struct r9a06g032_clkdesc { | 32 | struct r9a06g032_clkdesc { |
31 | const char *name; | 33 | const char *name; |
34 | uint32_t managed: 1; | ||
32 | uint32_t type: 3; | 35 | uint32_t type: 3; |
33 | uint32_t index: 8; | 36 | uint32_t index: 8; |
34 | uint32_t source : 8; /* source index + 1 (0 == none) */ | 37 | uint32_t source : 8; /* source index + 1 (0 == none) */ |
@@ -61,7 +64,11 @@ struct r9a06g032_clkdesc { | |||
61 | #define D_GATE(_idx, _n, _src, ...) \ | 64 | #define D_GATE(_idx, _n, _src, ...) \ |
62 | { .type = K_GATE, .index = R9A06G032_##_idx, \ | 65 | { .type = K_GATE, .index = R9A06G032_##_idx, \ |
63 | .source = 1 + R9A06G032_##_src, .name = _n, \ | 66 | .source = 1 + R9A06G032_##_src, .name = _n, \ |
64 | .gate = I_GATE(__VA_ARGS__), } | 67 | .gate = I_GATE(__VA_ARGS__) } |
68 | #define D_MODULE(_idx, _n, _src, ...) \ | ||
69 | { .type = K_GATE, .index = R9A06G032_##_idx, \ | ||
70 | .source = 1 + R9A06G032_##_src, .name = _n, \ | ||
71 | .managed = 1, .gate = I_GATE(__VA_ARGS__) } | ||
65 | #define D_ROOT(_idx, _n, _mul, _div) \ | 72 | #define D_ROOT(_idx, _n, _mul, _div) \ |
66 | { .type = K_FFC, .index = R9A06G032_##_idx, .name = _n, \ | 73 | { .type = K_FFC, .index = R9A06G032_##_idx, .name = _n, \ |
67 | .div = _div, .mul = _mul } | 74 | .div = _div, .mul = _mul } |
@@ -122,7 +129,7 @@ enum { K_GATE = 0, K_FFC, K_DIV, K_BITSEL, K_DUALGATE }; | |||
122 | 129 | ||
123 | #define R9A06G032_CLOCK_COUNT (R9A06G032_UART_GROUP_34567 + 1) | 130 | #define R9A06G032_CLOCK_COUNT (R9A06G032_UART_GROUP_34567 + 1) |
124 | 131 | ||
125 | static const struct r9a06g032_clkdesc r9a06g032_clocks[] __initconst = { | 132 | static const struct r9a06g032_clkdesc r9a06g032_clocks[] = { |
126 | D_ROOT(CLKOUT, "clkout", 25, 1), | 133 | D_ROOT(CLKOUT, "clkout", 25, 1), |
127 | D_ROOT(CLK_PLL_USB, "clk_pll_usb", 12, 10), | 134 | D_ROOT(CLK_PLL_USB, "clk_pll_usb", 12, 10), |
128 | D_FFC(CLKOUT_D10, "clkout_d10", CLKOUT, 10), | 135 | D_FFC(CLKOUT_D10, "clkout_d10", CLKOUT, 10), |
@@ -171,7 +178,7 @@ static const struct r9a06g032_clkdesc r9a06g032_clocks[] __initconst = { | |||
171 | D_GATE(CLK_P6_PG2, "clk_p6_pg2", DIV_P6_PG, 0x8a3, 0x8a4, 0x8a5, 0, 0xb61, 0, 0), | 178 | D_GATE(CLK_P6_PG2, "clk_p6_pg2", DIV_P6_PG, 0x8a3, 0x8a4, 0x8a5, 0, 0xb61, 0, 0), |
172 | D_GATE(CLK_P6_PG3, "clk_p6_pg3", DIV_P6_PG, 0x8a6, 0x8a7, 0x8a8, 0, 0xb62, 0, 0), | 179 | D_GATE(CLK_P6_PG3, "clk_p6_pg3", DIV_P6_PG, 0x8a6, 0x8a7, 0x8a8, 0, 0xb62, 0, 0), |
173 | D_GATE(CLK_P6_PG4, "clk_p6_pg4", DIV_P6_PG, 0x8a9, 0x8aa, 0x8ab, 0, 0xb63, 0, 0), | 180 | D_GATE(CLK_P6_PG4, "clk_p6_pg4", DIV_P6_PG, 0x8a9, 0x8aa, 0x8ab, 0, 0xb63, 0, 0), |
174 | D_GATE(CLK_PCI_USB, "clk_pci_usb", CLKOUT_D40, 0xe6, 0, 0, 0, 0, 0, 0), | 181 | D_MODULE(CLK_PCI_USB, "clk_pci_usb", CLKOUT_D40, 0xe6, 0, 0, 0, 0, 0, 0), |
175 | D_GATE(CLK_QSPI0, "clk_qspi0", DIV_QSPI0, 0x2a4, 0x2a5, 0, 0, 0, 0, 0), | 182 | D_GATE(CLK_QSPI0, "clk_qspi0", DIV_QSPI0, 0x2a4, 0x2a5, 0, 0, 0, 0, 0), |
176 | D_GATE(CLK_QSPI1, "clk_qspi1", DIV_QSPI1, 0x484, 0x485, 0, 0, 0, 0, 0), | 183 | D_GATE(CLK_QSPI1, "clk_qspi1", DIV_QSPI1, 0x484, 0x485, 0, 0, 0, 0, 0), |
177 | D_GATE(CLK_RGMII_REF, "clk_rgmii_ref", CLKOUT_D8, 0x340, 0, 0, 0, 0, 0, 0), | 184 | D_GATE(CLK_RGMII_REF, "clk_rgmii_ref", CLKOUT_D8, 0x340, 0, 0, 0, 0, 0, 0), |
@@ -188,17 +195,17 @@ static const struct r9a06g032_clkdesc r9a06g032_clocks[] __initconst = { | |||
188 | D_GATE(CLK_SPI5, "clk_spi5", DIV_P4_PG, 0x822, 0x823, 0, 0, 0, 0, 0), | 195 | D_GATE(CLK_SPI5, "clk_spi5", DIV_P4_PG, 0x822, 0x823, 0, 0, 0, 0, 0), |
189 | D_GATE(CLK_SWITCH, "clk_switch", DIV_SWITCH, 0x982, 0x983, 0, 0, 0, 0, 0), | 196 | D_GATE(CLK_SWITCH, "clk_switch", DIV_SWITCH, 0x982, 0x983, 0, 0, 0, 0, 0), |
190 | D_DIV(DIV_MOTOR, "div_motor", CLKOUT_D5, 84, 2, 8), | 197 | D_DIV(DIV_MOTOR, "div_motor", CLKOUT_D5, 84, 2, 8), |
191 | D_GATE(HCLK_ECAT125, "hclk_ecat125", CLKOUT_D8, 0x400, 0x401, 0, 0x402, 0, 0x440, 0x441), | 198 | D_MODULE(HCLK_ECAT125, "hclk_ecat125", CLKOUT_D8, 0x400, 0x401, 0, 0x402, 0, 0x440, 0x441), |
192 | D_GATE(HCLK_PINCONFIG, "hclk_pinconfig", CLKOUT_D40, 0x740, 0x741, 0x742, 0, 0xae0, 0, 0), | 199 | D_MODULE(HCLK_PINCONFIG, "hclk_pinconfig", CLKOUT_D40, 0x740, 0x741, 0x742, 0, 0xae0, 0, 0), |
193 | D_GATE(HCLK_SERCOS, "hclk_sercos", CLKOUT_D10, 0x420, 0x422, 0, 0x421, 0, 0x460, 0x461), | 200 | D_MODULE(HCLK_SERCOS, "hclk_sercos", CLKOUT_D10, 0x420, 0x422, 0, 0x421, 0, 0x460, 0x461), |
194 | D_GATE(HCLK_SGPIO2, "hclk_sgpio2", DIV_P5_PG, 0x8c3, 0x8c4, 0x8c5, 0, 0xb41, 0, 0), | 201 | D_MODULE(HCLK_SGPIO2, "hclk_sgpio2", DIV_P5_PG, 0x8c3, 0x8c4, 0x8c5, 0, 0xb41, 0, 0), |
195 | D_GATE(HCLK_SGPIO3, "hclk_sgpio3", DIV_P5_PG, 0x8c6, 0x8c7, 0x8c8, 0, 0xb42, 0, 0), | 202 | D_MODULE(HCLK_SGPIO3, "hclk_sgpio3", DIV_P5_PG, 0x8c6, 0x8c7, 0x8c8, 0, 0xb42, 0, 0), |
196 | D_GATE(HCLK_SGPIO4, "hclk_sgpio4", DIV_P5_PG, 0x8c9, 0x8ca, 0x8cb, 0, 0xb43, 0, 0), | 203 | D_MODULE(HCLK_SGPIO4, "hclk_sgpio4", DIV_P5_PG, 0x8c9, 0x8ca, 0x8cb, 0, 0xb43, 0, 0), |
197 | D_GATE(HCLK_TIMER0, "hclk_timer0", CLKOUT_D40, 0x743, 0x744, 0x745, 0, 0xae1, 0, 0), | 204 | D_MODULE(HCLK_TIMER0, "hclk_timer0", CLKOUT_D40, 0x743, 0x744, 0x745, 0, 0xae1, 0, 0), |
198 | D_GATE(HCLK_TIMER1, "hclk_timer1", CLKOUT_D40, 0x746, 0x747, 0x748, 0, 0xae2, 0, 0), | 205 | D_MODULE(HCLK_TIMER1, "hclk_timer1", CLKOUT_D40, 0x746, 0x747, 0x748, 0, 0xae2, 0, 0), |
199 | D_GATE(HCLK_USBF, "hclk_usbf", CLKOUT_D8, 0xe3, 0, 0, 0xe4, 0, 0x102, 0x103), | 206 | D_MODULE(HCLK_USBF, "hclk_usbf", CLKOUT_D8, 0xe3, 0, 0, 0xe4, 0, 0x102, 0x103), |
200 | D_GATE(HCLK_USBH, "hclk_usbh", CLKOUT_D8, 0xe0, 0xe1, 0, 0xe2, 0, 0x100, 0x101), | 207 | D_MODULE(HCLK_USBH, "hclk_usbh", CLKOUT_D8, 0xe0, 0xe1, 0, 0xe2, 0, 0x100, 0x101), |
201 | D_GATE(HCLK_USBPM, "hclk_usbpm", CLKOUT_D8, 0xe5, 0, 0, 0, 0, 0, 0), | 208 | D_MODULE(HCLK_USBPM, "hclk_usbpm", CLKOUT_D8, 0xe5, 0, 0, 0, 0, 0, 0), |
202 | D_GATE(CLK_48_PG_F, "clk_48_pg_f", CLK_48, 0x78c, 0x78d, 0, 0x78e, 0, 0xb04, 0xb05), | 209 | D_GATE(CLK_48_PG_F, "clk_48_pg_f", CLK_48, 0x78c, 0x78d, 0, 0x78e, 0, 0xb04, 0xb05), |
203 | D_GATE(CLK_48_PG4, "clk_48_pg4", CLK_48, 0x789, 0x78a, 0x78b, 0, 0xb03, 0, 0), | 210 | D_GATE(CLK_48_PG4, "clk_48_pg4", CLK_48, 0x789, 0x78a, 0x78b, 0, 0xb03, 0, 0), |
204 | D_FFC(CLK_DDRPHY_PLLCLK_D4, "clk_ddrphy_pllclk_d4", CLK_DDRPHY_PLLCLK, 4), | 211 | D_FFC(CLK_DDRPHY_PLLCLK_D4, "clk_ddrphy_pllclk_d4", CLK_DDRPHY_PLLCLK, 4), |
@@ -208,13 +215,13 @@ static const struct r9a06g032_clkdesc r9a06g032_clocks[] __initconst = { | |||
208 | D_FFC(CLK_REF_SYNC_D8, "clk_ref_sync_d8", CLK_REF_SYNC, 8), | 215 | D_FFC(CLK_REF_SYNC_D8, "clk_ref_sync_d8", CLK_REF_SYNC, 8), |
209 | D_FFC(CLK_SERCOS100_D2, "clk_sercos100_d2", CLK_SERCOS100, 2), | 216 | D_FFC(CLK_SERCOS100_D2, "clk_sercos100_d2", CLK_SERCOS100, 2), |
210 | D_DIV(DIV_CA7, "div_ca7", CLK_REF_SYNC, 57, 1, 4, 1, 2, 4), | 217 | D_DIV(DIV_CA7, "div_ca7", CLK_REF_SYNC, 57, 1, 4, 1, 2, 4), |
211 | D_GATE(HCLK_CAN0, "hclk_can0", CLK_48, 0x783, 0x784, 0x785, 0, 0xb01, 0, 0), | 218 | D_MODULE(HCLK_CAN0, "hclk_can0", CLK_48, 0x783, 0x784, 0x785, 0, 0xb01, 0, 0), |
212 | D_GATE(HCLK_CAN1, "hclk_can1", CLK_48, 0x786, 0x787, 0x788, 0, 0xb02, 0, 0), | 219 | D_MODULE(HCLK_CAN1, "hclk_can1", CLK_48, 0x786, 0x787, 0x788, 0, 0xb02, 0, 0), |
213 | D_GATE(HCLK_DELTASIGMA, "hclk_deltasigma", DIV_MOTOR, 0x1ef, 0x1f0, 0x1f1, 0, 0, 0, 0), | 220 | D_MODULE(HCLK_DELTASIGMA, "hclk_deltasigma", DIV_MOTOR, 0x1ef, 0x1f0, 0x1f1, 0, 0, 0, 0), |
214 | D_GATE(HCLK_PWMPTO, "hclk_pwmpto", DIV_MOTOR, 0x1ec, 0x1ed, 0x1ee, 0, 0, 0, 0), | 221 | D_MODULE(HCLK_PWMPTO, "hclk_pwmpto", DIV_MOTOR, 0x1ec, 0x1ed, 0x1ee, 0, 0, 0, 0), |
215 | D_GATE(HCLK_RSV, "hclk_rsv", CLK_48, 0x780, 0x781, 0x782, 0, 0xb00, 0, 0), | 222 | D_MODULE(HCLK_RSV, "hclk_rsv", CLK_48, 0x780, 0x781, 0x782, 0, 0xb00, 0, 0), |
216 | D_GATE(HCLK_SGPIO0, "hclk_sgpio0", DIV_MOTOR, 0x1e0, 0x1e1, 0x1e2, 0, 0, 0, 0), | 223 | D_MODULE(HCLK_SGPIO0, "hclk_sgpio0", DIV_MOTOR, 0x1e0, 0x1e1, 0x1e2, 0, 0, 0, 0), |
217 | D_GATE(HCLK_SGPIO1, "hclk_sgpio1", DIV_MOTOR, 0x1e3, 0x1e4, 0x1e5, 0, 0, 0, 0), | 224 | D_MODULE(HCLK_SGPIO1, "hclk_sgpio1", DIV_MOTOR, 0x1e3, 0x1e4, 0x1e5, 0, 0, 0, 0), |
218 | D_DIV(RTOS_MDC, "rtos_mdc", CLK_REF_SYNC, 100, 80, 640, 80, 160, 320, 640), | 225 | D_DIV(RTOS_MDC, "rtos_mdc", CLK_REF_SYNC, 100, 80, 640, 80, 160, 320, 640), |
219 | D_GATE(CLK_CM3, "clk_cm3", CLK_REF_SYNC_D4, 0xba0, 0xba1, 0, 0xba2, 0, 0xbc0, 0xbc1), | 226 | D_GATE(CLK_CM3, "clk_cm3", CLK_REF_SYNC_D4, 0xba0, 0xba1, 0, 0xba2, 0, 0xbc0, 0xbc1), |
220 | D_GATE(CLK_DDRC, "clk_ddrc", CLK_DDRPHY_PLLCLK_D4, 0x323, 0x324, 0, 0, 0, 0, 0), | 227 | D_GATE(CLK_DDRC, "clk_ddrc", CLK_DDRPHY_PLLCLK_D4, 0x323, 0x324, 0, 0, 0, 0, 0), |
@@ -222,53 +229,53 @@ static const struct r9a06g032_clkdesc r9a06g032_clocks[] __initconst = { | |||
222 | D_GATE(CLK_HSR50, "clk_hsr50", CLK_HSR100_D2, 0x484, 0x485, 0, 0, 0, 0, 0), | 229 | D_GATE(CLK_HSR50, "clk_hsr50", CLK_HSR100_D2, 0x484, 0x485, 0, 0, 0, 0, 0), |
223 | D_GATE(CLK_HW_RTOS, "clk_hw_rtos", CLK_REF_SYNC_D4, 0xc60, 0xc61, 0, 0, 0, 0, 0), | 230 | D_GATE(CLK_HW_RTOS, "clk_hw_rtos", CLK_REF_SYNC_D4, 0xc60, 0xc61, 0, 0, 0, 0, 0), |
224 | D_GATE(CLK_SERCOS50, "clk_sercos50", CLK_SERCOS100_D2, 0x424, 0x423, 0, 0, 0, 0, 0), | 231 | D_GATE(CLK_SERCOS50, "clk_sercos50", CLK_SERCOS100_D2, 0x424, 0x423, 0, 0, 0, 0, 0), |
225 | D_GATE(HCLK_ADC, "hclk_adc", CLK_REF_SYNC_D8, 0x1af, 0x1b0, 0x1b1, 0, 0, 0, 0), | 232 | D_MODULE(HCLK_ADC, "hclk_adc", CLK_REF_SYNC_D8, 0x1af, 0x1b0, 0x1b1, 0, 0, 0, 0), |
226 | D_GATE(HCLK_CM3, "hclk_cm3", CLK_REF_SYNC_D4, 0xc20, 0xc21, 0xc22, 0, 0, 0, 0), | 233 | D_MODULE(HCLK_CM3, "hclk_cm3", CLK_REF_SYNC_D4, 0xc20, 0xc21, 0xc22, 0, 0, 0, 0), |
227 | D_GATE(HCLK_CRYPTO_EIP150, "hclk_crypto_eip150", CLK_REF_SYNC_D4, 0x123, 0x124, 0x125, 0, 0x142, 0, 0), | 234 | D_MODULE(HCLK_CRYPTO_EIP150, "hclk_crypto_eip150", CLK_REF_SYNC_D4, 0x123, 0x124, 0x125, 0, 0x142, 0, 0), |
228 | D_GATE(HCLK_CRYPTO_EIP93, "hclk_crypto_eip93", CLK_REF_SYNC_D4, 0x120, 0x121, 0, 0x122, 0, 0x140, 0x141), | 235 | D_MODULE(HCLK_CRYPTO_EIP93, "hclk_crypto_eip93", CLK_REF_SYNC_D4, 0x120, 0x121, 0, 0x122, 0, 0x140, 0x141), |
229 | D_GATE(HCLK_DDRC, "hclk_ddrc", CLK_REF_SYNC_D4, 0x320, 0x322, 0, 0x321, 0, 0x3a0, 0x3a1), | 236 | D_MODULE(HCLK_DDRC, "hclk_ddrc", CLK_REF_SYNC_D4, 0x320, 0x322, 0, 0x321, 0, 0x3a0, 0x3a1), |
230 | D_GATE(HCLK_DMA0, "hclk_dma0", CLK_REF_SYNC_D4, 0x260, 0x261, 0x262, 0x263, 0x2c0, 0x2c1, 0x2c2), | 237 | D_MODULE(HCLK_DMA0, "hclk_dma0", CLK_REF_SYNC_D4, 0x260, 0x261, 0x262, 0x263, 0x2c0, 0x2c1, 0x2c2), |
231 | D_GATE(HCLK_DMA1, "hclk_dma1", CLK_REF_SYNC_D4, 0x264, 0x265, 0x266, 0x267, 0x2c3, 0x2c4, 0x2c5), | 238 | D_MODULE(HCLK_DMA1, "hclk_dma1", CLK_REF_SYNC_D4, 0x264, 0x265, 0x266, 0x267, 0x2c3, 0x2c4, 0x2c5), |
232 | D_GATE(HCLK_GMAC0, "hclk_gmac0", CLK_REF_SYNC_D4, 0x360, 0x361, 0x362, 0x363, 0x3c0, 0x3c1, 0x3c2), | 239 | D_MODULE(HCLK_GMAC0, "hclk_gmac0", CLK_REF_SYNC_D4, 0x360, 0x361, 0x362, 0x363, 0x3c0, 0x3c1, 0x3c2), |
233 | D_GATE(HCLK_GMAC1, "hclk_gmac1", CLK_REF_SYNC_D4, 0x380, 0x381, 0x382, 0x383, 0x3e0, 0x3e1, 0x3e2), | 240 | D_MODULE(HCLK_GMAC1, "hclk_gmac1", CLK_REF_SYNC_D4, 0x380, 0x381, 0x382, 0x383, 0x3e0, 0x3e1, 0x3e2), |
234 | D_GATE(HCLK_GPIO0, "hclk_gpio0", CLK_REF_SYNC_D4, 0x212, 0x213, 0x214, 0, 0, 0, 0), | 241 | D_MODULE(HCLK_GPIO0, "hclk_gpio0", CLK_REF_SYNC_D4, 0x212, 0x213, 0x214, 0, 0, 0, 0), |
235 | D_GATE(HCLK_GPIO1, "hclk_gpio1", CLK_REF_SYNC_D4, 0x215, 0x216, 0x217, 0, 0, 0, 0), | 242 | D_MODULE(HCLK_GPIO1, "hclk_gpio1", CLK_REF_SYNC_D4, 0x215, 0x216, 0x217, 0, 0, 0, 0), |
236 | D_GATE(HCLK_GPIO2, "hclk_gpio2", CLK_REF_SYNC_D4, 0x229, 0x22a, 0x22b, 0, 0, 0, 0), | 243 | D_MODULE(HCLK_GPIO2, "hclk_gpio2", CLK_REF_SYNC_D4, 0x229, 0x22a, 0x22b, 0, 0, 0, 0), |
237 | D_GATE(HCLK_HSR, "hclk_hsr", CLK_HSR100_D2, 0x480, 0x482, 0, 0x481, 0, 0x4c0, 0x4c1), | 244 | D_MODULE(HCLK_HSR, "hclk_hsr", CLK_HSR100_D2, 0x480, 0x482, 0, 0x481, 0, 0x4c0, 0x4c1), |
238 | D_GATE(HCLK_I2C0, "hclk_i2c0", CLK_REF_SYNC_D8, 0x1a9, 0x1aa, 0x1ab, 0, 0, 0, 0), | 245 | D_MODULE(HCLK_I2C0, "hclk_i2c0", CLK_REF_SYNC_D8, 0x1a9, 0x1aa, 0x1ab, 0, 0, 0, 0), |
239 | D_GATE(HCLK_I2C1, "hclk_i2c1", CLK_REF_SYNC_D8, 0x1ac, 0x1ad, 0x1ae, 0, 0, 0, 0), | 246 | D_MODULE(HCLK_I2C1, "hclk_i2c1", CLK_REF_SYNC_D8, 0x1ac, 0x1ad, 0x1ae, 0, 0, 0, 0), |
240 | D_GATE(HCLK_LCD, "hclk_lcd", CLK_REF_SYNC_D4, 0x7a0, 0x7a1, 0x7a2, 0, 0xb20, 0, 0), | 247 | D_MODULE(HCLK_LCD, "hclk_lcd", CLK_REF_SYNC_D4, 0x7a0, 0x7a1, 0x7a2, 0, 0xb20, 0, 0), |
241 | D_GATE(HCLK_MSEBI_M, "hclk_msebi_m", CLK_REF_SYNC_D4, 0x164, 0x165, 0x166, 0, 0x183, 0, 0), | 248 | D_MODULE(HCLK_MSEBI_M, "hclk_msebi_m", CLK_REF_SYNC_D4, 0x164, 0x165, 0x166, 0, 0x183, 0, 0), |
242 | D_GATE(HCLK_MSEBI_S, "hclk_msebi_s", CLK_REF_SYNC_D4, 0x160, 0x161, 0x162, 0x163, 0x180, 0x181, 0x182), | 249 | D_MODULE(HCLK_MSEBI_S, "hclk_msebi_s", CLK_REF_SYNC_D4, 0x160, 0x161, 0x162, 0x163, 0x180, 0x181, 0x182), |
243 | D_GATE(HCLK_NAND, "hclk_nand", CLK_REF_SYNC_D4, 0x280, 0x281, 0x282, 0x283, 0x2e0, 0x2e1, 0x2e2), | 250 | D_MODULE(HCLK_NAND, "hclk_nand", CLK_REF_SYNC_D4, 0x280, 0x281, 0x282, 0x283, 0x2e0, 0x2e1, 0x2e2), |
244 | D_GATE(HCLK_PG_I, "hclk_pg_i", CLK_REF_SYNC_D4, 0x7ac, 0x7ad, 0, 0x7ae, 0, 0xb24, 0xb25), | 251 | D_MODULE(HCLK_PG_I, "hclk_pg_i", CLK_REF_SYNC_D4, 0x7ac, 0x7ad, 0, 0x7ae, 0, 0xb24, 0xb25), |
245 | D_GATE(HCLK_PG19, "hclk_pg19", CLK_REF_SYNC_D4, 0x22c, 0x22d, 0x22e, 0, 0, 0, 0), | 252 | D_MODULE(HCLK_PG19, "hclk_pg19", CLK_REF_SYNC_D4, 0x22c, 0x22d, 0x22e, 0, 0, 0, 0), |
246 | D_GATE(HCLK_PG20, "hclk_pg20", CLK_REF_SYNC_D4, 0x22f, 0x230, 0x231, 0, 0, 0, 0), | 253 | D_MODULE(HCLK_PG20, "hclk_pg20", CLK_REF_SYNC_D4, 0x22f, 0x230, 0x231, 0, 0, 0, 0), |
247 | D_GATE(HCLK_PG3, "hclk_pg3", CLK_REF_SYNC_D4, 0x7a6, 0x7a7, 0x7a8, 0, 0xb22, 0, 0), | 254 | D_MODULE(HCLK_PG3, "hclk_pg3", CLK_REF_SYNC_D4, 0x7a6, 0x7a7, 0x7a8, 0, 0xb22, 0, 0), |
248 | D_GATE(HCLK_PG4, "hclk_pg4", CLK_REF_SYNC_D4, 0x7a9, 0x7aa, 0x7ab, 0, 0xb23, 0, 0), | 255 | D_MODULE(HCLK_PG4, "hclk_pg4", CLK_REF_SYNC_D4, 0x7a9, 0x7aa, 0x7ab, 0, 0xb23, 0, 0), |
249 | D_GATE(HCLK_QSPI0, "hclk_qspi0", CLK_REF_SYNC_D4, 0x2a0, 0x2a1, 0x2a2, 0x2a3, 0x300, 0x301, 0x302), | 256 | D_MODULE(HCLK_QSPI0, "hclk_qspi0", CLK_REF_SYNC_D4, 0x2a0, 0x2a1, 0x2a2, 0x2a3, 0x300, 0x301, 0x302), |
250 | D_GATE(HCLK_QSPI1, "hclk_qspi1", CLK_REF_SYNC_D4, 0x480, 0x481, 0x482, 0x483, 0x4c0, 0x4c1, 0x4c2), | 257 | D_MODULE(HCLK_QSPI1, "hclk_qspi1", CLK_REF_SYNC_D4, 0x480, 0x481, 0x482, 0x483, 0x4c0, 0x4c1, 0x4c2), |
251 | D_GATE(HCLK_ROM, "hclk_rom", CLK_REF_SYNC_D4, 0xaa0, 0xaa1, 0xaa2, 0, 0xb80, 0, 0), | 258 | D_MODULE(HCLK_ROM, "hclk_rom", CLK_REF_SYNC_D4, 0xaa0, 0xaa1, 0xaa2, 0, 0xb80, 0, 0), |
252 | D_GATE(HCLK_RTC, "hclk_rtc", CLK_REF_SYNC_D8, 0xa00, 0, 0, 0, 0, 0, 0), | 259 | D_MODULE(HCLK_RTC, "hclk_rtc", CLK_REF_SYNC_D8, 0xa00, 0, 0, 0, 0, 0, 0), |
253 | D_GATE(HCLK_SDIO0, "hclk_sdio0", CLK_REF_SYNC_D4, 0x60, 0x61, 0x62, 0x63, 0x80, 0x81, 0x82), | 260 | D_MODULE(HCLK_SDIO0, "hclk_sdio0", CLK_REF_SYNC_D4, 0x60, 0x61, 0x62, 0x63, 0x80, 0x81, 0x82), |
254 | D_GATE(HCLK_SDIO1, "hclk_sdio1", CLK_REF_SYNC_D4, 0x640, 0x641, 0x642, 0x643, 0x660, 0x661, 0x662), | 261 | D_MODULE(HCLK_SDIO1, "hclk_sdio1", CLK_REF_SYNC_D4, 0x640, 0x641, 0x642, 0x643, 0x660, 0x661, 0x662), |
255 | D_GATE(HCLK_SEMAP, "hclk_semap", CLK_REF_SYNC_D4, 0x7a3, 0x7a4, 0x7a5, 0, 0xb21, 0, 0), | 262 | D_MODULE(HCLK_SEMAP, "hclk_semap", CLK_REF_SYNC_D4, 0x7a3, 0x7a4, 0x7a5, 0, 0xb21, 0, 0), |
256 | D_GATE(HCLK_SPI0, "hclk_spi0", CLK_REF_SYNC_D4, 0x200, 0x201, 0x202, 0, 0, 0, 0), | 263 | D_MODULE(HCLK_SPI0, "hclk_spi0", CLK_REF_SYNC_D4, 0x200, 0x201, 0x202, 0, 0, 0, 0), |
257 | D_GATE(HCLK_SPI1, "hclk_spi1", CLK_REF_SYNC_D4, 0x203, 0x204, 0x205, 0, 0, 0, 0), | 264 | D_MODULE(HCLK_SPI1, "hclk_spi1", CLK_REF_SYNC_D4, 0x203, 0x204, 0x205, 0, 0, 0, 0), |
258 | D_GATE(HCLK_SPI2, "hclk_spi2", CLK_REF_SYNC_D4, 0x206, 0x207, 0x208, 0, 0, 0, 0), | 265 | D_MODULE(HCLK_SPI2, "hclk_spi2", CLK_REF_SYNC_D4, 0x206, 0x207, 0x208, 0, 0, 0, 0), |
259 | D_GATE(HCLK_SPI3, "hclk_spi3", CLK_REF_SYNC_D4, 0x209, 0x20a, 0x20b, 0, 0, 0, 0), | 266 | D_MODULE(HCLK_SPI3, "hclk_spi3", CLK_REF_SYNC_D4, 0x209, 0x20a, 0x20b, 0, 0, 0, 0), |
260 | D_GATE(HCLK_SPI4, "hclk_spi4", CLK_REF_SYNC_D4, 0x20c, 0x20d, 0x20e, 0, 0, 0, 0), | 267 | D_MODULE(HCLK_SPI4, "hclk_spi4", CLK_REF_SYNC_D4, 0x20c, 0x20d, 0x20e, 0, 0, 0, 0), |
261 | D_GATE(HCLK_SPI5, "hclk_spi5", CLK_REF_SYNC_D4, 0x20f, 0x210, 0x211, 0, 0, 0, 0), | 268 | D_MODULE(HCLK_SPI5, "hclk_spi5", CLK_REF_SYNC_D4, 0x20f, 0x210, 0x211, 0, 0, 0, 0), |
262 | D_GATE(HCLK_SWITCH, "hclk_switch", CLK_REF_SYNC_D4, 0x980, 0, 0x981, 0, 0, 0, 0), | 269 | D_MODULE(HCLK_SWITCH, "hclk_switch", CLK_REF_SYNC_D4, 0x980, 0, 0x981, 0, 0, 0, 0), |
263 | D_GATE(HCLK_SWITCH_RG, "hclk_switch_rg", CLK_REF_SYNC_D4, 0xc40, 0xc41, 0xc42, 0, 0, 0, 0), | 270 | D_MODULE(HCLK_SWITCH_RG, "hclk_switch_rg", CLK_REF_SYNC_D4, 0xc40, 0xc41, 0xc42, 0, 0, 0, 0), |
264 | D_GATE(HCLK_UART0, "hclk_uart0", CLK_REF_SYNC_D8, 0x1a0, 0x1a1, 0x1a2, 0, 0, 0, 0), | 271 | D_MODULE(HCLK_UART0, "hclk_uart0", CLK_REF_SYNC_D8, 0x1a0, 0x1a1, 0x1a2, 0, 0, 0, 0), |
265 | D_GATE(HCLK_UART1, "hclk_uart1", CLK_REF_SYNC_D8, 0x1a3, 0x1a4, 0x1a5, 0, 0, 0, 0), | 272 | D_MODULE(HCLK_UART1, "hclk_uart1", CLK_REF_SYNC_D8, 0x1a3, 0x1a4, 0x1a5, 0, 0, 0, 0), |
266 | D_GATE(HCLK_UART2, "hclk_uart2", CLK_REF_SYNC_D8, 0x1a6, 0x1a7, 0x1a8, 0, 0, 0, 0), | 273 | D_MODULE(HCLK_UART2, "hclk_uart2", CLK_REF_SYNC_D8, 0x1a6, 0x1a7, 0x1a8, 0, 0, 0, 0), |
267 | D_GATE(HCLK_UART3, "hclk_uart3", CLK_REF_SYNC_D4, 0x218, 0x219, 0x21a, 0, 0, 0, 0), | 274 | D_MODULE(HCLK_UART3, "hclk_uart3", CLK_REF_SYNC_D4, 0x218, 0x219, 0x21a, 0, 0, 0, 0), |
268 | D_GATE(HCLK_UART4, "hclk_uart4", CLK_REF_SYNC_D4, 0x21b, 0x21c, 0x21d, 0, 0, 0, 0), | 275 | D_MODULE(HCLK_UART4, "hclk_uart4", CLK_REF_SYNC_D4, 0x21b, 0x21c, 0x21d, 0, 0, 0, 0), |
269 | D_GATE(HCLK_UART5, "hclk_uart5", CLK_REF_SYNC_D4, 0x220, 0x221, 0x222, 0, 0, 0, 0), | 276 | D_MODULE(HCLK_UART5, "hclk_uart5", CLK_REF_SYNC_D4, 0x220, 0x221, 0x222, 0, 0, 0, 0), |
270 | D_GATE(HCLK_UART6, "hclk_uart6", CLK_REF_SYNC_D4, 0x223, 0x224, 0x225, 0, 0, 0, 0), | 277 | D_MODULE(HCLK_UART6, "hclk_uart6", CLK_REF_SYNC_D4, 0x223, 0x224, 0x225, 0, 0, 0, 0), |
271 | D_GATE(HCLK_UART7, "hclk_uart7", CLK_REF_SYNC_D4, 0x226, 0x227, 0x228, 0, 0, 0, 0), | 278 | D_MODULE(HCLK_UART7, "hclk_uart7", CLK_REF_SYNC_D4, 0x226, 0x227, 0x228, 0, 0, 0, 0), |
272 | /* | 279 | /* |
273 | * These are not hardware clocks, but are needed to handle the special | 280 | * These are not hardware clocks, but are needed to handle the special |
274 | * case where we have a 'selector bit' that doesn't just change the | 281 | * case where we have a 'selector bit' that doesn't just change the |
@@ -345,6 +352,84 @@ struct r9a06g032_clk_gate { | |||
345 | 352 | ||
346 | #define to_r9a06g032_gate(_hw) container_of(_hw, struct r9a06g032_clk_gate, hw) | 353 | #define to_r9a06g032_gate(_hw) container_of(_hw, struct r9a06g032_clk_gate, hw) |
347 | 354 | ||
355 | static int create_add_module_clock(struct of_phandle_args *clkspec, | ||
356 | struct device *dev) | ||
357 | { | ||
358 | struct clk *clk; | ||
359 | int error; | ||
360 | |||
361 | clk = of_clk_get_from_provider(clkspec); | ||
362 | if (IS_ERR(clk)) | ||
363 | return PTR_ERR(clk); | ||
364 | |||
365 | error = pm_clk_create(dev); | ||
366 | if (error) { | ||
367 | clk_put(clk); | ||
368 | return error; | ||
369 | } | ||
370 | |||
371 | error = pm_clk_add_clk(dev, clk); | ||
372 | if (error) { | ||
373 | pm_clk_destroy(dev); | ||
374 | clk_put(clk); | ||
375 | } | ||
376 | |||
377 | return error; | ||
378 | } | ||
379 | |||
380 | static int r9a06g032_attach_dev(struct generic_pm_domain *pd, | ||
381 | struct device *dev) | ||
382 | { | ||
383 | struct device_node *np = dev->of_node; | ||
384 | struct of_phandle_args clkspec; | ||
385 | int i = 0; | ||
386 | int error; | ||
387 | int index; | ||
388 | |||
389 | while (!of_parse_phandle_with_args(np, "clocks", "#clock-cells", i, | ||
390 | &clkspec)) { | ||
391 | if (clkspec.np != pd->dev.of_node) | ||
392 | continue; | ||
393 | |||
394 | index = clkspec.args[0]; | ||
395 | if (index < R9A06G032_CLOCK_COUNT && | ||
396 | r9a06g032_clocks[index].managed) { | ||
397 | error = create_add_module_clock(&clkspec, dev); | ||
398 | of_node_put(clkspec.np); | ||
399 | if (error) | ||
400 | return error; | ||
401 | } | ||
402 | i++; | ||
403 | } | ||
404 | |||
405 | return 0; | ||
406 | } | ||
407 | |||
408 | static void r9a06g032_detach_dev(struct generic_pm_domain *unused, struct device *dev) | ||
409 | { | ||
410 | if (!pm_clk_no_clocks(dev)) | ||
411 | pm_clk_destroy(dev); | ||
412 | } | ||
413 | |||
414 | static int r9a06g032_add_clk_domain(struct device *dev) | ||
415 | { | ||
416 | struct device_node *np = dev->of_node; | ||
417 | struct generic_pm_domain *pd; | ||
418 | |||
419 | pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL); | ||
420 | if (!pd) | ||
421 | return -ENOMEM; | ||
422 | |||
423 | pd->name = np->name; | ||
424 | pd->flags = GENPD_FLAG_PM_CLK | GENPD_FLAG_ACTIVE_WAKEUP; | ||
425 | pd->attach_dev = r9a06g032_attach_dev; | ||
426 | pd->detach_dev = r9a06g032_detach_dev; | ||
427 | pm_genpd_init(pd, &pm_domain_always_on_gov, false); | ||
428 | |||
429 | of_genpd_add_provider_simple(np, pd); | ||
430 | return 0; | ||
431 | } | ||
432 | |||
348 | static void | 433 | static void |
349 | r9a06g032_clk_gate_set(struct r9a06g032_priv *clocks, | 434 | r9a06g032_clk_gate_set(struct r9a06g032_priv *clocks, |
350 | struct r9a06g032_gate *g, int on) | 435 | struct r9a06g032_gate *g, int on) |
@@ -871,8 +956,12 @@ static int __init r9a06g032_clocks_probe(struct platform_device *pdev) | |||
871 | if (error) | 956 | if (error) |
872 | return error; | 957 | return error; |
873 | 958 | ||
874 | return devm_add_action_or_reset(dev, | 959 | error = devm_add_action_or_reset(dev, |
875 | r9a06g032_clocks_del_clk_provider, np); | 960 | r9a06g032_clocks_del_clk_provider, np); |
961 | if (error) | ||
962 | return error; | ||
963 | |||
964 | return r9a06g032_add_clk_domain(dev); | ||
876 | } | 965 | } |
877 | 966 | ||
878 | static const struct of_device_id r9a06g032_match[] = { | 967 | static const struct of_device_id r9a06g032_match[] = { |
diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index 0201809bbd37..52bbb9ce3807 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c | |||
@@ -112,14 +112,15 @@ static const u16 srcr[] = { | |||
112 | * @dev: CPG/MSSR device | 112 | * @dev: CPG/MSSR device |
113 | * @base: CPG/MSSR register block base address | 113 | * @base: CPG/MSSR register block base address |
114 | * @rmw_lock: protects RMW register accesses | 114 | * @rmw_lock: protects RMW register accesses |
115 | * @clks: Array containing all Core and Module Clocks | 115 | * @np: Device node in DT for this CPG/MSSR module |
116 | * @num_core_clks: Number of Core Clocks in clks[] | 116 | * @num_core_clks: Number of Core Clocks in clks[] |
117 | * @num_mod_clks: Number of Module Clocks in clks[] | 117 | * @num_mod_clks: Number of Module Clocks in clks[] |
118 | * @last_dt_core_clk: ID of the last Core Clock exported to DT | 118 | * @last_dt_core_clk: ID of the last Core Clock exported to DT |
119 | * @stbyctrl: This device has Standby Control Registers | ||
119 | * @notifiers: Notifier chain to save/restore clock state for system resume | 120 | * @notifiers: Notifier chain to save/restore clock state for system resume |
120 | * @smstpcr_saved[].mask: Mask of SMSTPCR[] bits under our control | 121 | * @smstpcr_saved[].mask: Mask of SMSTPCR[] bits under our control |
121 | * @smstpcr_saved[].val: Saved values of SMSTPCR[] | 122 | * @smstpcr_saved[].val: Saved values of SMSTPCR[] |
122 | * @stbyctrl: This device has Standby Control Registers | 123 | * @clks: Array containing all Core and Module Clocks |
123 | */ | 124 | */ |
124 | struct cpg_mssr_priv { | 125 | struct cpg_mssr_priv { |
125 | #ifdef CONFIG_RESET_CONTROLLER | 126 | #ifdef CONFIG_RESET_CONTROLLER |
@@ -130,7 +131,6 @@ struct cpg_mssr_priv { | |||
130 | spinlock_t rmw_lock; | 131 | spinlock_t rmw_lock; |
131 | struct device_node *np; | 132 | struct device_node *np; |
132 | 133 | ||
133 | struct clk **clks; | ||
134 | unsigned int num_core_clks; | 134 | unsigned int num_core_clks; |
135 | unsigned int num_mod_clks; | 135 | unsigned int num_mod_clks; |
136 | unsigned int last_dt_core_clk; | 136 | unsigned int last_dt_core_clk; |
@@ -141,6 +141,8 @@ struct cpg_mssr_priv { | |||
141 | u32 mask; | 141 | u32 mask; |
142 | u32 val; | 142 | u32 val; |
143 | } smstpcr_saved[ARRAY_SIZE(smstpcr)]; | 143 | } smstpcr_saved[ARRAY_SIZE(smstpcr)]; |
144 | |||
145 | struct clk *clks[]; | ||
144 | }; | 146 | }; |
145 | 147 | ||
146 | static struct cpg_mssr_priv *cpg_mssr_priv; | 148 | static struct cpg_mssr_priv *cpg_mssr_priv; |
@@ -447,9 +449,8 @@ fail: | |||
447 | 449 | ||
448 | struct cpg_mssr_clk_domain { | 450 | struct cpg_mssr_clk_domain { |
449 | struct generic_pm_domain genpd; | 451 | struct generic_pm_domain genpd; |
450 | struct device_node *np; | ||
451 | unsigned int num_core_pm_clks; | 452 | unsigned int num_core_pm_clks; |
452 | unsigned int core_pm_clks[0]; | 453 | unsigned int core_pm_clks[]; |
453 | }; | 454 | }; |
454 | 455 | ||
455 | static struct cpg_mssr_clk_domain *cpg_mssr_clk_domain; | 456 | static struct cpg_mssr_clk_domain *cpg_mssr_clk_domain; |
@@ -459,7 +460,7 @@ static bool cpg_mssr_is_pm_clk(const struct of_phandle_args *clkspec, | |||
459 | { | 460 | { |
460 | unsigned int i; | 461 | unsigned int i; |
461 | 462 | ||
462 | if (clkspec->np != pd->np || clkspec->args_count != 2) | 463 | if (clkspec->np != pd->genpd.dev.of_node || clkspec->args_count != 2) |
463 | return false; | 464 | return false; |
464 | 465 | ||
465 | switch (clkspec->args[0]) { | 466 | switch (clkspec->args[0]) { |
@@ -510,16 +511,12 @@ found: | |||
510 | return PTR_ERR(clk); | 511 | return PTR_ERR(clk); |
511 | 512 | ||
512 | error = pm_clk_create(dev); | 513 | error = pm_clk_create(dev); |
513 | if (error) { | 514 | if (error) |
514 | dev_err(dev, "pm_clk_create failed %d\n", error); | ||
515 | goto fail_put; | 515 | goto fail_put; |
516 | } | ||
517 | 516 | ||
518 | error = pm_clk_add_clk(dev, clk); | 517 | error = pm_clk_add_clk(dev, clk); |
519 | if (error) { | 518 | if (error) |
520 | dev_err(dev, "pm_clk_add_clk %pC failed %d\n", clk, error); | ||
521 | goto fail_destroy; | 519 | goto fail_destroy; |
522 | } | ||
523 | 520 | ||
524 | return 0; | 521 | return 0; |
525 | 522 | ||
@@ -549,7 +546,6 @@ static int __init cpg_mssr_add_clk_domain(struct device *dev, | |||
549 | if (!pd) | 546 | if (!pd) |
550 | return -ENOMEM; | 547 | return -ENOMEM; |
551 | 548 | ||
552 | pd->np = np; | ||
553 | pd->num_core_pm_clks = num_core_pm_clks; | 549 | pd->num_core_pm_clks = num_core_pm_clks; |
554 | memcpy(pd->core_pm_clks, core_pm_clks, pm_size); | 550 | memcpy(pd->core_pm_clks, core_pm_clks, pm_size); |
555 | 551 | ||
@@ -896,7 +892,6 @@ static int __init cpg_mssr_common_init(struct device *dev, | |||
896 | const struct cpg_mssr_info *info) | 892 | const struct cpg_mssr_info *info) |
897 | { | 893 | { |
898 | struct cpg_mssr_priv *priv; | 894 | struct cpg_mssr_priv *priv; |
899 | struct clk **clks = NULL; | ||
900 | unsigned int nclks, i; | 895 | unsigned int nclks, i; |
901 | int error; | 896 | int error; |
902 | 897 | ||
@@ -906,7 +901,8 @@ static int __init cpg_mssr_common_init(struct device *dev, | |||
906 | return error; | 901 | return error; |
907 | } | 902 | } |
908 | 903 | ||
909 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | 904 | nclks = info->num_total_core_clks + info->num_hw_mod_clks; |
905 | priv = kzalloc(struct_size(priv, clks, nclks), GFP_KERNEL); | ||
910 | if (!priv) | 906 | if (!priv) |
911 | return -ENOMEM; | 907 | return -ENOMEM; |
912 | 908 | ||
@@ -920,15 +916,7 @@ static int __init cpg_mssr_common_init(struct device *dev, | |||
920 | goto out_err; | 916 | goto out_err; |
921 | } | 917 | } |
922 | 918 | ||
923 | nclks = info->num_total_core_clks + info->num_hw_mod_clks; | ||
924 | clks = kmalloc_array(nclks, sizeof(*clks), GFP_KERNEL); | ||
925 | if (!clks) { | ||
926 | error = -ENOMEM; | ||
927 | goto out_err; | ||
928 | } | ||
929 | |||
930 | cpg_mssr_priv = priv; | 919 | cpg_mssr_priv = priv; |
931 | priv->clks = clks; | ||
932 | priv->num_core_clks = info->num_total_core_clks; | 920 | priv->num_core_clks = info->num_total_core_clks; |
933 | priv->num_mod_clks = info->num_hw_mod_clks; | 921 | priv->num_mod_clks = info->num_hw_mod_clks; |
934 | priv->last_dt_core_clk = info->last_dt_core_clk; | 922 | priv->last_dt_core_clk = info->last_dt_core_clk; |
@@ -936,7 +924,7 @@ static int __init cpg_mssr_common_init(struct device *dev, | |||
936 | priv->stbyctrl = info->stbyctrl; | 924 | priv->stbyctrl = info->stbyctrl; |
937 | 925 | ||
938 | for (i = 0; i < nclks; i++) | 926 | for (i = 0; i < nclks; i++) |
939 | clks[i] = ERR_PTR(-ENOENT); | 927 | priv->clks[i] = ERR_PTR(-ENOENT); |
940 | 928 | ||
941 | error = of_clk_add_provider(np, cpg_mssr_clk_src_twocell_get, priv); | 929 | error = of_clk_add_provider(np, cpg_mssr_clk_src_twocell_get, priv); |
942 | if (error) | 930 | if (error) |
@@ -945,7 +933,6 @@ static int __init cpg_mssr_common_init(struct device *dev, | |||
945 | return 0; | 933 | return 0; |
946 | 934 | ||
947 | out_err: | 935 | out_err: |
948 | kfree(clks); | ||
949 | if (priv->base) | 936 | if (priv->base) |
950 | iounmap(priv->base); | 937 | iounmap(priv->base); |
951 | kfree(priv); | 938 | kfree(priv); |
diff --git a/drivers/clk/rockchip/clk-mmc-phase.c b/drivers/clk/rockchip/clk-mmc-phase.c index c61f4d3e52e2..4abe7ff31f53 100644 --- a/drivers/clk/rockchip/clk-mmc-phase.c +++ b/drivers/clk/rockchip/clk-mmc-phase.c | |||
@@ -46,29 +46,27 @@ static unsigned long rockchip_mmc_recalc(struct clk_hw *hw, | |||
46 | static int rockchip_mmc_get_phase(struct clk_hw *hw) | 46 | static int rockchip_mmc_get_phase(struct clk_hw *hw) |
47 | { | 47 | { |
48 | struct rockchip_mmc_clock *mmc_clock = to_mmc_clock(hw); | 48 | struct rockchip_mmc_clock *mmc_clock = to_mmc_clock(hw); |
49 | unsigned long rate = clk_get_rate(hw->clk); | 49 | unsigned long rate = clk_hw_get_rate(hw); |
50 | u32 raw_value; | 50 | u32 raw_value; |
51 | u16 degrees; | 51 | u16 degrees; |
52 | u32 delay_num = 0; | 52 | u32 delay_num = 0; |
53 | 53 | ||
54 | /* See the comment for rockchip_mmc_set_phase below */ | 54 | /* See the comment for rockchip_mmc_set_phase below */ |
55 | if (!rate) { | 55 | if (!rate) |
56 | pr_err("%s: invalid clk rate\n", __func__); | ||
57 | return -EINVAL; | 56 | return -EINVAL; |
58 | } | ||
59 | 57 | ||
60 | raw_value = readl(mmc_clock->reg) >> (mmc_clock->shift); | 58 | raw_value = readl(mmc_clock->reg) >> (mmc_clock->shift); |
61 | 59 | ||
62 | degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90; | 60 | degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90; |
63 | 61 | ||
64 | if (raw_value & ROCKCHIP_MMC_DELAY_SEL) { | 62 | if (raw_value & ROCKCHIP_MMC_DELAY_SEL) { |
65 | /* degrees/delaynum * 10000 */ | 63 | /* degrees/delaynum * 1000000 */ |
66 | unsigned long factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) * | 64 | unsigned long factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) * |
67 | 36 * (rate / 1000000); | 65 | 36 * (rate / 10000); |
68 | 66 | ||
69 | delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK); | 67 | delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK); |
70 | delay_num >>= ROCKCHIP_MMC_DELAYNUM_OFFSET; | 68 | delay_num >>= ROCKCHIP_MMC_DELAYNUM_OFFSET; |
71 | degrees += DIV_ROUND_CLOSEST(delay_num * factor, 10000); | 69 | degrees += DIV_ROUND_CLOSEST(delay_num * factor, 1000000); |
72 | } | 70 | } |
73 | 71 | ||
74 | return degrees % 360; | 72 | return degrees % 360; |
@@ -77,7 +75,7 @@ static int rockchip_mmc_get_phase(struct clk_hw *hw) | |||
77 | static int rockchip_mmc_set_phase(struct clk_hw *hw, int degrees) | 75 | static int rockchip_mmc_set_phase(struct clk_hw *hw, int degrees) |
78 | { | 76 | { |
79 | struct rockchip_mmc_clock *mmc_clock = to_mmc_clock(hw); | 77 | struct rockchip_mmc_clock *mmc_clock = to_mmc_clock(hw); |
80 | unsigned long rate = clk_get_rate(hw->clk); | 78 | unsigned long rate = clk_hw_get_rate(hw); |
81 | u8 nineties, remainder; | 79 | u8 nineties, remainder; |
82 | u8 delay_num; | 80 | u8 delay_num; |
83 | u32 raw_value; | 81 | u32 raw_value; |
diff --git a/drivers/clk/rockchip/clk-px30.c b/drivers/clk/rockchip/clk-px30.c index bb39a799bdb5..3a501896b280 100644 --- a/drivers/clk/rockchip/clk-px30.c +++ b/drivers/clk/rockchip/clk-px30.c | |||
@@ -794,6 +794,9 @@ static struct rockchip_clk_branch px30_clk_branches[] __initdata = { | |||
794 | GATE(ACLK_GIC, "aclk_gic", "aclk_bus_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(13), 12, GFLAGS), | 794 | GATE(ACLK_GIC, "aclk_gic", "aclk_bus_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(13), 12, GFLAGS), |
795 | GATE(ACLK_DCF, "aclk_dcf", "aclk_bus_pre", 0, PX30_CLKGATE_CON(13), 15, GFLAGS), | 795 | GATE(ACLK_DCF, "aclk_dcf", "aclk_bus_pre", 0, PX30_CLKGATE_CON(13), 15, GFLAGS), |
796 | 796 | ||
797 | /* aclk_dmac is controlled by sgrf_soc_con1[11]. */ | ||
798 | SGRF_GATE(ACLK_DMAC, "aclk_dmac", "aclk_bus_pre"), | ||
799 | |||
797 | GATE(0, "hclk_bus_niu", "hclk_bus_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(13), 9, GFLAGS), | 800 | GATE(0, "hclk_bus_niu", "hclk_bus_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(13), 9, GFLAGS), |
798 | GATE(0, "hclk_rom", "hclk_bus_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(13), 14, GFLAGS), | 801 | GATE(0, "hclk_rom", "hclk_bus_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(13), 14, GFLAGS), |
799 | GATE(HCLK_PDM, "hclk_pdm", "hclk_bus_pre", 0, PX30_CLKGATE_CON(14), 1, GFLAGS), | 802 | GATE(HCLK_PDM, "hclk_pdm", "hclk_bus_pre", 0, PX30_CLKGATE_CON(14), 1, GFLAGS), |
@@ -957,7 +960,6 @@ static void __init px30_clk_init(struct device_node *np) | |||
957 | { | 960 | { |
958 | struct rockchip_clk_provider *ctx; | 961 | struct rockchip_clk_provider *ctx; |
959 | void __iomem *reg_base; | 962 | void __iomem *reg_base; |
960 | struct clk *clk; | ||
961 | 963 | ||
962 | reg_base = of_iomap(np, 0); | 964 | reg_base = of_iomap(np, 0); |
963 | if (!reg_base) { | 965 | if (!reg_base) { |
@@ -972,14 +974,6 @@ static void __init px30_clk_init(struct device_node *np) | |||
972 | return; | 974 | return; |
973 | } | 975 | } |
974 | 976 | ||
975 | /* aclk_dmac is controlled by sgrf_soc_con1[11]. */ | ||
976 | clk = clk_register_fixed_factor(NULL, "aclk_dmac", "aclk_bus_pre", 0, 1, 1); | ||
977 | if (IS_ERR(clk)) | ||
978 | pr_warn("%s: could not register clock aclk_dmac: %ld\n", | ||
979 | __func__, PTR_ERR(clk)); | ||
980 | else | ||
981 | rockchip_clk_add_lookup(ctx, clk, ACLK_DMAC); | ||
982 | |||
983 | rockchip_clk_register_plls(ctx, px30_pll_clks, | 977 | rockchip_clk_register_plls(ctx, px30_pll_clks, |
984 | ARRAY_SIZE(px30_pll_clks), | 978 | ARRAY_SIZE(px30_pll_clks), |
985 | PX30_GRF_SOC_STATUS0); | 979 | PX30_GRF_SOC_STATUS0); |
diff --git a/drivers/clk/rockchip/clk-rk3228.c b/drivers/clk/rockchip/clk-rk3228.c index bdb126321e56..d17cfb7a3ff4 100644 --- a/drivers/clk/rockchip/clk-rk3228.c +++ b/drivers/clk/rockchip/clk-rk3228.c | |||
@@ -101,6 +101,7 @@ static struct rockchip_cpuclk_rate_table rk3228_cpuclk_rates[] __initdata = { | |||
101 | RK3228_CPUCLK_RATE(1608000000, 1, 7), | 101 | RK3228_CPUCLK_RATE(1608000000, 1, 7), |
102 | RK3228_CPUCLK_RATE(1512000000, 1, 7), | 102 | RK3228_CPUCLK_RATE(1512000000, 1, 7), |
103 | RK3228_CPUCLK_RATE(1488000000, 1, 5), | 103 | RK3228_CPUCLK_RATE(1488000000, 1, 5), |
104 | RK3228_CPUCLK_RATE(1464000000, 1, 5), | ||
104 | RK3228_CPUCLK_RATE(1416000000, 1, 5), | 105 | RK3228_CPUCLK_RATE(1416000000, 1, 5), |
105 | RK3228_CPUCLK_RATE(1392000000, 1, 5), | 106 | RK3228_CPUCLK_RATE(1392000000, 1, 5), |
106 | RK3228_CPUCLK_RATE(1296000000, 1, 5), | 107 | RK3228_CPUCLK_RATE(1296000000, 1, 5), |
@@ -246,7 +247,7 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { | |||
246 | RK2928_CLKGATE_CON(4), 0, GFLAGS), | 247 | RK2928_CLKGATE_CON(4), 0, GFLAGS), |
247 | 248 | ||
248 | /* PD_MISC */ | 249 | /* PD_MISC */ |
249 | MUX(0, "hdmiphy", mux_hdmiphy_p, CLK_SET_RATE_PARENT, | 250 | MUX(SCLK_HDMI_PHY, "hdmiphy", mux_hdmiphy_p, CLK_SET_RATE_PARENT, |
250 | RK2928_MISC_CON, 13, 1, MFLAGS), | 251 | RK2928_MISC_CON, 13, 1, MFLAGS), |
251 | MUX(0, "usb480m_phy", mux_usb480m_phy_p, CLK_SET_RATE_PARENT, | 252 | MUX(0, "usb480m_phy", mux_usb480m_phy_p, CLK_SET_RATE_PARENT, |
252 | RK2928_MISC_CON, 14, 1, MFLAGS), | 253 | RK2928_MISC_CON, 14, 1, MFLAGS), |
diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c index 057629685ea1..cc2a177bbdbf 100644 --- a/drivers/clk/rockchip/clk-rk3288.c +++ b/drivers/clk/rockchip/clk-rk3288.c | |||
@@ -113,7 +113,6 @@ static struct rockchip_pll_rate_table rk3288_pll_rates[] = { | |||
113 | RK3066_PLL_RATE( 160000000, 1, 80, 12), | 113 | RK3066_PLL_RATE( 160000000, 1, 80, 12), |
114 | RK3066_PLL_RATE( 157500000, 1, 105, 16), | 114 | RK3066_PLL_RATE( 157500000, 1, 105, 16), |
115 | RK3066_PLL_RATE( 126000000, 1, 84, 16), | 115 | RK3066_PLL_RATE( 126000000, 1, 84, 16), |
116 | RK3066_PLL_RATE( 48000000, 1, 64, 32), | ||
117 | { /* sentinel */ }, | 116 | { /* sentinel */ }, |
118 | }; | 117 | }; |
119 | 118 | ||
@@ -767,6 +766,9 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { | |||
767 | GATE(PCLK_GRF, "pclk_grf", "pclk_pd_alive", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(14), 11, GFLAGS), | 766 | GATE(PCLK_GRF, "pclk_grf", "pclk_pd_alive", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(14), 11, GFLAGS), |
768 | GATE(0, "pclk_alive_niu", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 12, GFLAGS), | 767 | GATE(0, "pclk_alive_niu", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 12, GFLAGS), |
769 | 768 | ||
769 | /* Watchdog pclk is controlled by RK3288_SGRF_SOC_CON0[1]. */ | ||
770 | SGRF_GATE(PCLK_WDT, "pclk_wdt", "pclk_pd_alive"), | ||
771 | |||
770 | /* pclk_pd_pmu gates */ | 772 | /* pclk_pd_pmu gates */ |
771 | GATE(PCLK_PMU, "pclk_pmu", "pclk_pd_pmu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(17), 0, GFLAGS), | 773 | GATE(PCLK_PMU, "pclk_pmu", "pclk_pd_pmu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(17), 0, GFLAGS), |
772 | GATE(0, "pclk_intmem1", "pclk_pd_pmu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(17), 1, GFLAGS), | 774 | GATE(0, "pclk_intmem1", "pclk_pd_pmu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(17), 1, GFLAGS), |
@@ -915,7 +917,6 @@ static struct syscore_ops rk3288_clk_syscore_ops = { | |||
915 | static void __init rk3288_clk_init(struct device_node *np) | 917 | static void __init rk3288_clk_init(struct device_node *np) |
916 | { | 918 | { |
917 | struct rockchip_clk_provider *ctx; | 919 | struct rockchip_clk_provider *ctx; |
918 | struct clk *clk; | ||
919 | 920 | ||
920 | rk3288_cru_base = of_iomap(np, 0); | 921 | rk3288_cru_base = of_iomap(np, 0); |
921 | if (!rk3288_cru_base) { | 922 | if (!rk3288_cru_base) { |
@@ -930,14 +931,6 @@ static void __init rk3288_clk_init(struct device_node *np) | |||
930 | return; | 931 | return; |
931 | } | 932 | } |
932 | 933 | ||
933 | /* Watchdog pclk is controlled by RK3288_SGRF_SOC_CON0[1]. */ | ||
934 | clk = clk_register_fixed_factor(NULL, "pclk_wdt", "pclk_pd_alive", 0, 1, 1); | ||
935 | if (IS_ERR(clk)) | ||
936 | pr_warn("%s: could not register clock pclk_wdt: %ld\n", | ||
937 | __func__, PTR_ERR(clk)); | ||
938 | else | ||
939 | rockchip_clk_add_lookup(ctx, clk, PCLK_WDT); | ||
940 | |||
941 | rockchip_clk_register_plls(ctx, rk3288_pll_clks, | 934 | rockchip_clk_register_plls(ctx, rk3288_pll_clks, |
942 | ARRAY_SIZE(rk3288_pll_clks), | 935 | ARRAY_SIZE(rk3288_pll_clks), |
943 | RK3288_GRF_SOC_STATUS1); | 936 | RK3288_GRF_SOC_STATUS1); |
diff --git a/drivers/clk/rockchip/clk-rk3328.c b/drivers/clk/rockchip/clk-rk3328.c index 076b9777a955..c186a1985bf4 100644 --- a/drivers/clk/rockchip/clk-rk3328.c +++ b/drivers/clk/rockchip/clk-rk3328.c | |||
@@ -791,6 +791,9 @@ static struct rockchip_clk_branch rk3328_clk_branches[] __initdata = { | |||
791 | GATE(PCLK_SARADC, "pclk_saradc", "pclk_bus", 0, RK3328_CLKGATE_CON(17), 15, GFLAGS), | 791 | GATE(PCLK_SARADC, "pclk_saradc", "pclk_bus", 0, RK3328_CLKGATE_CON(17), 15, GFLAGS), |
792 | GATE(0, "pclk_pmu", "pclk_bus", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(28), 3, GFLAGS), | 792 | GATE(0, "pclk_pmu", "pclk_bus", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(28), 3, GFLAGS), |
793 | 793 | ||
794 | /* Watchdog pclk is controlled from the secure GRF */ | ||
795 | SGRF_GATE(PCLK_WDT, "pclk_wdt", "pclk_bus"), | ||
796 | |||
794 | GATE(PCLK_USB3PHY_OTG, "pclk_usb3phy_otg", "pclk_phy_pre", 0, RK3328_CLKGATE_CON(28), 1, GFLAGS), | 797 | GATE(PCLK_USB3PHY_OTG, "pclk_usb3phy_otg", "pclk_phy_pre", 0, RK3328_CLKGATE_CON(28), 1, GFLAGS), |
795 | GATE(PCLK_USB3PHY_PIPE, "pclk_usb3phy_pipe", "pclk_phy_pre", 0, RK3328_CLKGATE_CON(28), 2, GFLAGS), | 798 | GATE(PCLK_USB3PHY_PIPE, "pclk_usb3phy_pipe", "pclk_phy_pre", 0, RK3328_CLKGATE_CON(28), 2, GFLAGS), |
796 | GATE(PCLK_USB3_GRF, "pclk_usb3_grf", "pclk_phy_pre", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(17), 2, GFLAGS), | 799 | GATE(PCLK_USB3_GRF, "pclk_usb3_grf", "pclk_phy_pre", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(17), 2, GFLAGS), |
diff --git a/drivers/clk/rockchip/clk-rk3368.c b/drivers/clk/rockchip/clk-rk3368.c index 43b022d9393b..55443349439b 100644 --- a/drivers/clk/rockchip/clk-rk3368.c +++ b/drivers/clk/rockchip/clk-rk3368.c | |||
@@ -811,6 +811,9 @@ static struct rockchip_clk_branch rk3368_clk_branches[] __initdata = { | |||
811 | GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_pd_alive", 0, RK3368_CLKGATE_CON(22), 2, GFLAGS), | 811 | GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_pd_alive", 0, RK3368_CLKGATE_CON(22), 2, GFLAGS), |
812 | GATE(PCLK_GPIO1, "pclk_gpio1", "pclk_pd_alive", 0, RK3368_CLKGATE_CON(22), 1, GFLAGS), | 812 | GATE(PCLK_GPIO1, "pclk_gpio1", "pclk_pd_alive", 0, RK3368_CLKGATE_CON(22), 1, GFLAGS), |
813 | 813 | ||
814 | /* Watchdog pclk is controlled by sgrf_soc_con3[7]. */ | ||
815 | SGRF_GATE(PCLK_WDT, "pclk_wdt", "pclk_pd_alive"), | ||
816 | |||
814 | /* | 817 | /* |
815 | * pclk_vio gates | 818 | * pclk_vio gates |
816 | * pclk_vio comes from the exactly same source as hclk_vio | 819 | * pclk_vio comes from the exactly same source as hclk_vio |
@@ -862,7 +865,6 @@ static void __init rk3368_clk_init(struct device_node *np) | |||
862 | { | 865 | { |
863 | struct rockchip_clk_provider *ctx; | 866 | struct rockchip_clk_provider *ctx; |
864 | void __iomem *reg_base; | 867 | void __iomem *reg_base; |
865 | struct clk *clk; | ||
866 | 868 | ||
867 | reg_base = of_iomap(np, 0); | 869 | reg_base = of_iomap(np, 0); |
868 | if (!reg_base) { | 870 | if (!reg_base) { |
@@ -877,14 +879,6 @@ static void __init rk3368_clk_init(struct device_node *np) | |||
877 | return; | 879 | return; |
878 | } | 880 | } |
879 | 881 | ||
880 | /* Watchdog pclk is controlled by sgrf_soc_con3[7]. */ | ||
881 | clk = clk_register_fixed_factor(NULL, "pclk_wdt", "pclk_pd_alive", 0, 1, 1); | ||
882 | if (IS_ERR(clk)) | ||
883 | pr_warn("%s: could not register clock pclk_wdt: %ld\n", | ||
884 | __func__, PTR_ERR(clk)); | ||
885 | else | ||
886 | rockchip_clk_add_lookup(ctx, clk, PCLK_WDT); | ||
887 | |||
888 | rockchip_clk_register_plls(ctx, rk3368_pll_clks, | 882 | rockchip_clk_register_plls(ctx, rk3368_pll_clks, |
889 | ARRAY_SIZE(rk3368_pll_clks), | 883 | ARRAY_SIZE(rk3368_pll_clks), |
890 | RK3368_GRF_SOC_STATUS0); | 884 | RK3368_GRF_SOC_STATUS0); |
diff --git a/drivers/clk/rockchip/clk-rk3399.c b/drivers/clk/rockchip/clk-rk3399.c index a7ff71313278..ce1d2446f142 100644 --- a/drivers/clk/rockchip/clk-rk3399.c +++ b/drivers/clk/rockchip/clk-rk3399.c | |||
@@ -1295,6 +1295,9 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { | |||
1295 | GATE(PCLK_PMU_INTR_ARB, "pclk_pmu_intr_arb", "pclk_alive", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(31), 9, GFLAGS), | 1295 | GATE(PCLK_PMU_INTR_ARB, "pclk_pmu_intr_arb", "pclk_alive", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(31), 9, GFLAGS), |
1296 | GATE(PCLK_SGRF, "pclk_sgrf", "pclk_alive", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(31), 10, GFLAGS), | 1296 | GATE(PCLK_SGRF, "pclk_sgrf", "pclk_alive", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(31), 10, GFLAGS), |
1297 | 1297 | ||
1298 | /* Watchdog pclk is controlled by RK3399 SECURE_GRF_SOC_CON3[8]. */ | ||
1299 | SGRF_GATE(PCLK_WDT, "pclk_wdt", "pclk_alive"), | ||
1300 | |||
1298 | GATE(SCLK_MIPIDPHY_REF, "clk_mipidphy_ref", "xin24m", 0, RK3399_CLKGATE_CON(11), 14, GFLAGS), | 1301 | GATE(SCLK_MIPIDPHY_REF, "clk_mipidphy_ref", "xin24m", 0, RK3399_CLKGATE_CON(11), 14, GFLAGS), |
1299 | GATE(SCLK_DPHY_PLL, "clk_dphy_pll", "clk_mipidphy_ref", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(21), 0, GFLAGS), | 1302 | GATE(SCLK_DPHY_PLL, "clk_dphy_pll", "clk_mipidphy_ref", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(21), 0, GFLAGS), |
1300 | 1303 | ||
@@ -1522,7 +1525,6 @@ static void __init rk3399_clk_init(struct device_node *np) | |||
1522 | { | 1525 | { |
1523 | struct rockchip_clk_provider *ctx; | 1526 | struct rockchip_clk_provider *ctx; |
1524 | void __iomem *reg_base; | 1527 | void __iomem *reg_base; |
1525 | struct clk *clk; | ||
1526 | 1528 | ||
1527 | reg_base = of_iomap(np, 0); | 1529 | reg_base = of_iomap(np, 0); |
1528 | if (!reg_base) { | 1530 | if (!reg_base) { |
@@ -1537,14 +1539,6 @@ static void __init rk3399_clk_init(struct device_node *np) | |||
1537 | return; | 1539 | return; |
1538 | } | 1540 | } |
1539 | 1541 | ||
1540 | /* Watchdog pclk is controlled by RK3399 SECURE_GRF_SOC_CON3[8]. */ | ||
1541 | clk = clk_register_fixed_factor(NULL, "pclk_wdt", "pclk_alive", 0, 1, 1); | ||
1542 | if (IS_ERR(clk)) | ||
1543 | pr_warn("%s: could not register clock pclk_wdt: %ld\n", | ||
1544 | __func__, PTR_ERR(clk)); | ||
1545 | else | ||
1546 | rockchip_clk_add_lookup(ctx, clk, PCLK_WDT); | ||
1547 | |||
1548 | rockchip_clk_register_plls(ctx, rk3399_pll_clks, | 1542 | rockchip_clk_register_plls(ctx, rk3399_pll_clks, |
1549 | ARRAY_SIZE(rk3399_pll_clks), -1); | 1543 | ARRAY_SIZE(rk3399_pll_clks), -1); |
1550 | 1544 | ||
diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h index adb66cc94929..b811597a3d38 100644 --- a/drivers/clk/rockchip/clk.h +++ b/drivers/clk/rockchip/clk.h | |||
@@ -811,6 +811,10 @@ struct rockchip_clk_branch { | |||
811 | .gate_offset = -1, \ | 811 | .gate_offset = -1, \ |
812 | } | 812 | } |
813 | 813 | ||
814 | /* SGRF clocks are only accessible from secure mode, so not controllable */ | ||
815 | #define SGRF_GATE(_id, cname, pname) \ | ||
816 | FACTOR(_id, cname, pname, 0, 1, 1) | ||
817 | |||
814 | struct rockchip_clk_provider *rockchip_clk_init(struct device_node *np, | 818 | struct rockchip_clk_provider *rockchip_clk_init(struct device_node *np, |
815 | void __iomem *base, unsigned long nr_clks); | 819 | void __iomem *base, unsigned long nr_clks); |
816 | void rockchip_clk_of_add_provider(struct device_node *np, | 820 | void rockchip_clk_of_add_provider(struct device_node *np, |
diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c index 982eb02bafda..51564fc23c63 100644 --- a/drivers/clk/samsung/clk-exynos4.c +++ b/drivers/clk/samsung/clk-exynos4.c | |||
@@ -958,6 +958,7 @@ static const struct samsung_gate_clock exynos4210_gate_clks[] __initconst = { | |||
958 | 958 | ||
959 | /* list of gate clocks supported in exynos4x12 soc */ | 959 | /* list of gate clocks supported in exynos4x12 soc */ |
960 | static const struct samsung_gate_clock exynos4x12_gate_clks[] __initconst = { | 960 | static const struct samsung_gate_clock exynos4x12_gate_clks[] __initconst = { |
961 | GATE(CLK_ASYNC_G3D, "async_g3d", "aclk200", GATE_IP_LEFTBUS, 6, 0, 0), | ||
961 | GATE(CLK_AUDSS, "audss", "sclk_epll", E4X12_GATE_IP_MAUDIO, 0, 0, 0), | 962 | GATE(CLK_AUDSS, "audss", "sclk_epll", E4X12_GATE_IP_MAUDIO, 0, 0, 0), |
962 | GATE(CLK_MDNIE0, "mdnie0", "aclk160", GATE_IP_LCD0, 2, 0, 0), | 963 | GATE(CLK_MDNIE0, "mdnie0", "aclk160", GATE_IP_LCD0, 2, 0, 0), |
963 | GATE(CLK_ROTATOR, "rotator", "aclk200", E4X12_GATE_IP_IMAGE, 1, 0, 0), | 964 | GATE(CLK_ROTATOR, "rotator", "aclk200", E4X12_GATE_IP_IMAGE, 1, 0, 0), |
diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c index 12d800fd9528..01bca5a498b2 100644 --- a/drivers/clk/samsung/clk-exynos5420.c +++ b/drivers/clk/samsung/clk-exynos5420.c | |||
@@ -131,6 +131,8 @@ | |||
131 | #define SRC_CDREX 0x20200 | 131 | #define SRC_CDREX 0x20200 |
132 | #define DIV_CDREX0 0x20500 | 132 | #define DIV_CDREX0 0x20500 |
133 | #define DIV_CDREX1 0x20504 | 133 | #define DIV_CDREX1 0x20504 |
134 | #define GATE_BUS_CDREX0 0x20700 | ||
135 | #define GATE_BUS_CDREX1 0x20704 | ||
134 | #define KPLL_LOCK 0x28000 | 136 | #define KPLL_LOCK 0x28000 |
135 | #define KPLL_CON0 0x28100 | 137 | #define KPLL_CON0 0x28100 |
136 | #define SRC_KFC 0x28200 | 138 | #define SRC_KFC 0x28200 |
@@ -245,6 +247,8 @@ static const unsigned long exynos5x_clk_regs[] __initconst = { | |||
245 | DIV_CDREX1, | 247 | DIV_CDREX1, |
246 | SRC_KFC, | 248 | SRC_KFC, |
247 | DIV_KFC0, | 249 | DIV_KFC0, |
250 | GATE_BUS_CDREX0, | ||
251 | GATE_BUS_CDREX1, | ||
248 | }; | 252 | }; |
249 | 253 | ||
250 | static const unsigned long exynos5800_clk_regs[] __initconst = { | 254 | static const unsigned long exynos5800_clk_regs[] __initconst = { |
@@ -422,6 +426,9 @@ PNAME(mout_group13_5800_p) = { "dout_osc_div", "mout_sw_aclkfl1_550_cam" }; | |||
422 | PNAME(mout_group14_5800_p) = { "dout_aclk550_cam", "dout_sclk_sw" }; | 426 | PNAME(mout_group14_5800_p) = { "dout_aclk550_cam", "dout_sclk_sw" }; |
423 | PNAME(mout_group15_5800_p) = { "dout_osc_div", "mout_sw_aclk550_cam" }; | 427 | PNAME(mout_group15_5800_p) = { "dout_osc_div", "mout_sw_aclk550_cam" }; |
424 | PNAME(mout_group16_5800_p) = { "dout_osc_div", "mout_mau_epll_clk" }; | 428 | PNAME(mout_group16_5800_p) = { "dout_osc_div", "mout_mau_epll_clk" }; |
429 | PNAME(mout_mx_mspll_ccore_phy_p) = { "sclk_bpll", "mout_sclk_dpll", | ||
430 | "mout_sclk_mpll", "ff_dout_spll2", | ||
431 | "mout_sclk_spll", "mout_sclk_epll"}; | ||
425 | 432 | ||
426 | /* fixed rate clocks generated outside the soc */ | 433 | /* fixed rate clocks generated outside the soc */ |
427 | static struct samsung_fixed_rate_clock | 434 | static struct samsung_fixed_rate_clock |
@@ -447,7 +454,7 @@ static const struct samsung_fixed_factor_clock | |||
447 | static const struct samsung_fixed_factor_clock | 454 | static const struct samsung_fixed_factor_clock |
448 | exynos5800_fixed_factor_clks[] __initconst = { | 455 | exynos5800_fixed_factor_clks[] __initconst = { |
449 | FFACTOR(0, "ff_dout_epll2", "mout_sclk_epll", 1, 2, 0), | 456 | FFACTOR(0, "ff_dout_epll2", "mout_sclk_epll", 1, 2, 0), |
450 | FFACTOR(0, "ff_dout_spll2", "mout_sclk_spll", 1, 2, 0), | 457 | FFACTOR(CLK_FF_DOUT_SPLL2, "ff_dout_spll2", "mout_sclk_spll", 1, 2, 0), |
451 | }; | 458 | }; |
452 | 459 | ||
453 | static const struct samsung_mux_clock exynos5800_mux_clks[] __initconst = { | 460 | static const struct samsung_mux_clock exynos5800_mux_clks[] __initconst = { |
@@ -469,11 +476,14 @@ static const struct samsung_mux_clock exynos5800_mux_clks[] __initconst = { | |||
469 | MUX(0, "mout_aclk300_disp1", mout_group5_5800_p, SRC_TOP2, 24, 2), | 476 | MUX(0, "mout_aclk300_disp1", mout_group5_5800_p, SRC_TOP2, 24, 2), |
470 | MUX(0, "mout_aclk300_gscl", mout_group5_5800_p, SRC_TOP2, 28, 2), | 477 | MUX(0, "mout_aclk300_gscl", mout_group5_5800_p, SRC_TOP2, 28, 2), |
471 | 478 | ||
479 | MUX(CLK_MOUT_MX_MSPLL_CCORE_PHY, "mout_mx_mspll_ccore_phy", | ||
480 | mout_mx_mspll_ccore_phy_p, SRC_TOP7, 0, 3), | ||
481 | |||
472 | MUX(CLK_MOUT_MX_MSPLL_CCORE, "mout_mx_mspll_ccore", | 482 | MUX(CLK_MOUT_MX_MSPLL_CCORE, "mout_mx_mspll_ccore", |
473 | mout_mx_mspll_ccore_p, SRC_TOP7, 16, 2), | 483 | mout_mx_mspll_ccore_p, SRC_TOP7, 16, 3), |
474 | MUX_F(CLK_MOUT_MAU_EPLL, "mout_mau_epll_clk", mout_mau_epll_clk_5800_p, | 484 | MUX_F(CLK_MOUT_MAU_EPLL, "mout_mau_epll_clk", mout_mau_epll_clk_5800_p, |
475 | SRC_TOP7, 20, 2, CLK_SET_RATE_PARENT, 0), | 485 | SRC_TOP7, 20, 2, CLK_SET_RATE_PARENT, 0), |
476 | MUX(0, "sclk_bpll", mout_bpll_p, SRC_TOP7, 24, 1), | 486 | MUX(CLK_SCLK_BPLL, "sclk_bpll", mout_bpll_p, SRC_TOP7, 24, 1), |
477 | MUX(0, "mout_epll2", mout_epll2_5800_p, SRC_TOP7, 28, 1), | 487 | MUX(0, "mout_epll2", mout_epll2_5800_p, SRC_TOP7, 28, 1), |
478 | 488 | ||
479 | MUX(0, "mout_aclk550_cam", mout_group3_5800_p, SRC_TOP8, 16, 3), | 489 | MUX(0, "mout_aclk550_cam", mout_group3_5800_p, SRC_TOP8, 16, 3), |
@@ -645,7 +655,7 @@ static const struct samsung_mux_clock exynos5x_mux_clks[] __initconst = { | |||
645 | 655 | ||
646 | MUX(0, "mout_sclk_mpll", mout_mpll_p, SRC_TOP6, 0, 1), | 656 | MUX(0, "mout_sclk_mpll", mout_mpll_p, SRC_TOP6, 0, 1), |
647 | MUX(CLK_MOUT_VPLL, "mout_sclk_vpll", mout_vpll_p, SRC_TOP6, 4, 1), | 657 | MUX(CLK_MOUT_VPLL, "mout_sclk_vpll", mout_vpll_p, SRC_TOP6, 4, 1), |
648 | MUX(0, "mout_sclk_spll", mout_spll_p, SRC_TOP6, 8, 1), | 658 | MUX(CLK_MOUT_SCLK_SPLL, "mout_sclk_spll", mout_spll_p, SRC_TOP6, 8, 1), |
649 | MUX(0, "mout_sclk_ipll", mout_ipll_p, SRC_TOP6, 12, 1), | 659 | MUX(0, "mout_sclk_ipll", mout_ipll_p, SRC_TOP6, 12, 1), |
650 | MUX(0, "mout_sclk_rpll", mout_rpll_p, SRC_TOP6, 16, 1), | 660 | MUX(0, "mout_sclk_rpll", mout_rpll_p, SRC_TOP6, 16, 1), |
651 | MUX_F(CLK_MOUT_EPLL, "mout_sclk_epll", mout_epll_p, SRC_TOP6, 20, 1, | 661 | MUX_F(CLK_MOUT_EPLL, "mout_sclk_epll", mout_epll_p, SRC_TOP6, 20, 1, |
@@ -803,8 +813,21 @@ static const struct samsung_div_clock exynos5x_div_clks[] __initconst = { | |||
803 | "mout_aclk400_disp1", DIV_TOP2, 4, 3), | 813 | "mout_aclk400_disp1", DIV_TOP2, 4, 3), |
804 | 814 | ||
805 | /* CDREX Block */ | 815 | /* CDREX Block */ |
806 | DIV(CLK_DOUT_PCLK_CDREX, "dout_pclk_cdrex", "dout_aclk_cdrex1", | 816 | /* |
807 | DIV_CDREX0, 28, 3), | 817 | * The three clocks below are controlled using the same register and |
818 | * bits. They are put into one because there is a need of | ||
819 | * synchronization between the BUS and DREXs (two external memory | ||
820 | * interfaces). | ||
821 | * They are put here to show this HW assumption and for clock | ||
822 | * information summary completeness. | ||
823 | */ | ||
824 | DIV_F(CLK_DOUT_PCLK_CDREX, "dout_pclk_cdrex", "dout_aclk_cdrex1", | ||
825 | DIV_CDREX0, 28, 3, CLK_GET_RATE_NOCACHE, 0), | ||
826 | DIV_F(CLK_DOUT_PCLK_DREX0, "dout_pclk_drex0", "dout_cclk_drex0", | ||
827 | DIV_CDREX0, 28, 3, CLK_GET_RATE_NOCACHE, 0), | ||
828 | DIV_F(CLK_DOUT_PCLK_DREX1, "dout_pclk_drex1", "dout_cclk_drex0", | ||
829 | DIV_CDREX0, 28, 3, CLK_GET_RATE_NOCACHE, 0), | ||
830 | |||
808 | DIV_F(CLK_DOUT_SCLK_CDREX, "dout_sclk_cdrex", "mout_mclk_cdrex", | 831 | DIV_F(CLK_DOUT_SCLK_CDREX, "dout_sclk_cdrex", "mout_mclk_cdrex", |
809 | DIV_CDREX0, 24, 3, CLK_SET_RATE_PARENT, 0), | 832 | DIV_CDREX0, 24, 3, CLK_SET_RATE_PARENT, 0), |
810 | DIV(CLK_DOUT_ACLK_CDREX1, "dout_aclk_cdrex1", "dout_clk2x_phy0", | 833 | DIV(CLK_DOUT_ACLK_CDREX1, "dout_aclk_cdrex1", "dout_clk2x_phy0", |
@@ -1167,6 +1190,32 @@ static const struct samsung_gate_clock exynos5x_gate_clks[] __initconst = { | |||
1167 | GATE_TOP_SCLK_ISP, 12, CLK_SET_RATE_PARENT, 0), | 1190 | GATE_TOP_SCLK_ISP, 12, CLK_SET_RATE_PARENT, 0), |
1168 | 1191 | ||
1169 | GATE(CLK_G3D, "g3d", "mout_user_aclk_g3d", GATE_IP_G3D, 9, 0, 0), | 1192 | GATE(CLK_G3D, "g3d", "mout_user_aclk_g3d", GATE_IP_G3D, 9, 0, 0), |
1193 | |||
1194 | /* CDREX */ | ||
1195 | GATE(CLK_CLKM_PHY0, "clkm_phy0", "dout_sclk_cdrex", | ||
1196 | GATE_BUS_CDREX0, 0, 0, 0), | ||
1197 | GATE(CLK_CLKM_PHY1, "clkm_phy1", "dout_sclk_cdrex", | ||
1198 | GATE_BUS_CDREX0, 1, 0, 0), | ||
1199 | GATE(0, "mx_mspll_ccore_phy", "mout_mx_mspll_ccore_phy", | ||
1200 | SRC_MASK_TOP7, 0, CLK_IGNORE_UNUSED, 0), | ||
1201 | |||
1202 | GATE(CLK_ACLK_PPMU_DREX1_1, "aclk_ppmu_drex1_1", "dout_aclk_cdrex1", | ||
1203 | GATE_BUS_CDREX1, 12, CLK_IGNORE_UNUSED, 0), | ||
1204 | GATE(CLK_ACLK_PPMU_DREX1_0, "aclk_ppmu_drex1_0", "dout_aclk_cdrex1", | ||
1205 | GATE_BUS_CDREX1, 13, CLK_IGNORE_UNUSED, 0), | ||
1206 | GATE(CLK_ACLK_PPMU_DREX0_1, "aclk_ppmu_drex0_1", "dout_aclk_cdrex1", | ||
1207 | GATE_BUS_CDREX1, 14, CLK_IGNORE_UNUSED, 0), | ||
1208 | GATE(CLK_ACLK_PPMU_DREX0_0, "aclk_ppmu_drex0_0", "dout_aclk_cdrex1", | ||
1209 | GATE_BUS_CDREX1, 15, CLK_IGNORE_UNUSED, 0), | ||
1210 | |||
1211 | GATE(CLK_PCLK_PPMU_DREX1_1, "pclk_ppmu_drex1_1", "dout_pclk_cdrex", | ||
1212 | GATE_BUS_CDREX1, 26, CLK_IGNORE_UNUSED, 0), | ||
1213 | GATE(CLK_PCLK_PPMU_DREX1_0, "pclk_ppmu_drex1_0", "dout_pclk_cdrex", | ||
1214 | GATE_BUS_CDREX1, 27, CLK_IGNORE_UNUSED, 0), | ||
1215 | GATE(CLK_PCLK_PPMU_DREX0_1, "pclk_ppmu_drex0_1", "dout_pclk_cdrex", | ||
1216 | GATE_BUS_CDREX1, 28, CLK_IGNORE_UNUSED, 0), | ||
1217 | GATE(CLK_PCLK_PPMU_DREX0_0, "pclk_ppmu_drex0_0", "dout_pclk_cdrex", | ||
1218 | GATE_BUS_CDREX1, 29, CLK_IGNORE_UNUSED, 0), | ||
1170 | }; | 1219 | }; |
1171 | 1220 | ||
1172 | static const struct samsung_div_clock exynos5x_disp_div_clks[] __initconst = { | 1221 | static const struct samsung_div_clock exynos5x_disp_div_clks[] __initconst = { |
@@ -1282,6 +1331,17 @@ static const struct samsung_pll_rate_table exynos5420_pll2550x_24mhz_tbl[] __ini | |||
1282 | PLL_35XX_RATE(24 * MHZ, 200000000, 200, 3, 3), | 1331 | PLL_35XX_RATE(24 * MHZ, 200000000, 200, 3, 3), |
1283 | }; | 1332 | }; |
1284 | 1333 | ||
1334 | static const struct samsung_pll_rate_table exynos5422_bpll_rate_table[] = { | ||
1335 | PLL_35XX_RATE(24 * MHZ, 825000000, 275, 4, 1), | ||
1336 | PLL_35XX_RATE(24 * MHZ, 728000000, 182, 3, 1), | ||
1337 | PLL_35XX_RATE(24 * MHZ, 633000000, 211, 4, 1), | ||
1338 | PLL_35XX_RATE(24 * MHZ, 543000000, 181, 2, 2), | ||
1339 | PLL_35XX_RATE(24 * MHZ, 413000000, 413, 6, 2), | ||
1340 | PLL_35XX_RATE(24 * MHZ, 275000000, 275, 3, 3), | ||
1341 | PLL_35XX_RATE(24 * MHZ, 206000000, 206, 3, 3), | ||
1342 | PLL_35XX_RATE(24 * MHZ, 165000000, 110, 2, 3), | ||
1343 | }; | ||
1344 | |||
1285 | static const struct samsung_pll_rate_table exynos5420_epll_24mhz_tbl[] = { | 1345 | static const struct samsung_pll_rate_table exynos5420_epll_24mhz_tbl[] = { |
1286 | PLL_36XX_RATE(24 * MHZ, 600000000U, 100, 2, 1, 0), | 1346 | PLL_36XX_RATE(24 * MHZ, 600000000U, 100, 2, 1, 0), |
1287 | PLL_36XX_RATE(24 * MHZ, 400000000U, 200, 3, 2, 0), | 1347 | PLL_36XX_RATE(24 * MHZ, 400000000U, 200, 3, 2, 0), |
@@ -1424,9 +1484,13 @@ static void __init exynos5x_clk_init(struct device_node *np, | |||
1424 | exynos5x_plls[apll].rate_table = exynos5420_pll2550x_24mhz_tbl; | 1484 | exynos5x_plls[apll].rate_table = exynos5420_pll2550x_24mhz_tbl; |
1425 | exynos5x_plls[epll].rate_table = exynos5420_epll_24mhz_tbl; | 1485 | exynos5x_plls[epll].rate_table = exynos5420_epll_24mhz_tbl; |
1426 | exynos5x_plls[kpll].rate_table = exynos5420_pll2550x_24mhz_tbl; | 1486 | exynos5x_plls[kpll].rate_table = exynos5420_pll2550x_24mhz_tbl; |
1427 | exynos5x_plls[bpll].rate_table = exynos5420_pll2550x_24mhz_tbl; | ||
1428 | } | 1487 | } |
1429 | 1488 | ||
1489 | if (soc == EXYNOS5420) | ||
1490 | exynos5x_plls[bpll].rate_table = exynos5420_pll2550x_24mhz_tbl; | ||
1491 | else | ||
1492 | exynos5x_plls[bpll].rate_table = exynos5422_bpll_rate_table; | ||
1493 | |||
1430 | samsung_clk_register_pll(ctx, exynos5x_plls, ARRAY_SIZE(exynos5x_plls), | 1494 | samsung_clk_register_pll(ctx, exynos5x_plls, ARRAY_SIZE(exynos5x_plls), |
1431 | reg_base); | 1495 | reg_base); |
1432 | samsung_clk_register_fixed_rate(ctx, exynos5x_fixed_rate_clks, | 1496 | samsung_clk_register_fixed_rate(ctx, exynos5x_fixed_rate_clks, |
diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c index 945d5f2ad733..7824c2ba3d8e 100644 --- a/drivers/clk/samsung/clk-exynos5433.c +++ b/drivers/clk/samsung/clk-exynos5433.c | |||
@@ -5587,8 +5587,8 @@ static int __init exynos5433_cmu_probe(struct platform_device *pdev) | |||
5587 | data->nr_clk_save = info->nr_clk_regs; | 5587 | data->nr_clk_save = info->nr_clk_regs; |
5588 | data->clk_suspend = info->suspend_regs; | 5588 | data->clk_suspend = info->suspend_regs; |
5589 | data->nr_clk_suspend = info->nr_suspend_regs; | 5589 | data->nr_clk_suspend = info->nr_suspend_regs; |
5590 | data->nr_pclks = of_count_phandle_with_args(dev->of_node, "clocks", | 5590 | data->nr_pclks = of_clk_get_parent_count(dev->of_node); |
5591 | "#clock-cells"); | 5591 | |
5592 | if (data->nr_pclks > 0) { | 5592 | if (data->nr_pclks > 0) { |
5593 | data->pclks = devm_kcalloc(dev, sizeof(struct clk *), | 5593 | data->pclks = devm_kcalloc(dev, sizeof(struct clk *), |
5594 | data->nr_pclks, GFP_KERNEL); | 5594 | data->nr_pclks, GFP_KERNEL); |
diff --git a/drivers/clk/socfpga/clk-s10.c b/drivers/clk/socfpga/clk-s10.c index 5bed36e12951..993f3a73c71e 100644 --- a/drivers/clk/socfpga/clk-s10.c +++ b/drivers/clk/socfpga/clk-s10.c | |||
@@ -161,8 +161,12 @@ static const struct stratix10_gate_clock s10_gate_clks[] = { | |||
161 | 8, 0, 0, 0, 0, 0, 0}, | 161 | 8, 0, 0, 0, 0, 0, 0}, |
162 | { STRATIX10_SPI_M_CLK, "spi_m_clk", "l4_mp_clk", NULL, 1, 0, 0xA4, | 162 | { STRATIX10_SPI_M_CLK, "spi_m_clk", "l4_mp_clk", NULL, 1, 0, 0xA4, |
163 | 9, 0, 0, 0, 0, 0, 0}, | 163 | 9, 0, 0, 0, 0, 0, 0}, |
164 | { STRATIX10_NAND_CLK, "nand_clk", "l4_main_clk", NULL, 1, 0, 0xA4, | 164 | { STRATIX10_NAND_X_CLK, "nand_x_clk", "l4_mp_clk", NULL, 1, 0, 0xA4, |
165 | 10, 0, 0, 0, 0, 0, 0}, | 165 | 10, 0, 0, 0, 0, 0, 0}, |
166 | { STRATIX10_NAND_CLK, "nand_clk", "nand_x_clk", NULL, 1, 0, 0xA4, | ||
167 | 10, 0, 0, 0, 0, 0, 4}, | ||
168 | { STRATIX10_NAND_ECC_CLK, "nand_ecc_clk", "nand_x_clk", NULL, 1, 0, 0xA4, | ||
169 | 10, 0, 0, 0, 0, 0, 4}, | ||
166 | }; | 170 | }; |
167 | 171 | ||
168 | static int s10_clk_register_c_perip(const struct stratix10_perip_c_clock *clks, | 172 | static int s10_clk_register_c_perip(const struct stratix10_perip_c_clock *clks, |
diff --git a/drivers/clk/sprd/common.c b/drivers/clk/sprd/common.c index e038b0447206..a5bdca1de5d0 100644 --- a/drivers/clk/sprd/common.c +++ b/drivers/clk/sprd/common.c | |||
@@ -42,6 +42,7 @@ int sprd_clk_regmap_init(struct platform_device *pdev, | |||
42 | void __iomem *base; | 42 | void __iomem *base; |
43 | struct device_node *node = pdev->dev.of_node; | 43 | struct device_node *node = pdev->dev.of_node; |
44 | struct regmap *regmap; | 44 | struct regmap *regmap; |
45 | struct resource *res; | ||
45 | 46 | ||
46 | if (of_find_property(node, "sprd,syscon", NULL)) { | 47 | if (of_find_property(node, "sprd,syscon", NULL)) { |
47 | regmap = syscon_regmap_lookup_by_phandle(node, "sprd,syscon"); | 48 | regmap = syscon_regmap_lookup_by_phandle(node, "sprd,syscon"); |
@@ -50,10 +51,14 @@ int sprd_clk_regmap_init(struct platform_device *pdev, | |||
50 | return PTR_ERR(regmap); | 51 | return PTR_ERR(regmap); |
51 | } | 52 | } |
52 | } else { | 53 | } else { |
53 | base = of_iomap(node, 0); | 54 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
55 | base = devm_ioremap_resource(&pdev->dev, res); | ||
56 | if (IS_ERR(base)) | ||
57 | return PTR_ERR(base); | ||
58 | |||
54 | regmap = devm_regmap_init_mmio(&pdev->dev, base, | 59 | regmap = devm_regmap_init_mmio(&pdev->dev, base, |
55 | &sprdclk_regmap_config); | 60 | &sprdclk_regmap_config); |
56 | if (IS_ERR_OR_NULL(regmap)) { | 61 | if (IS_ERR(regmap)) { |
57 | pr_err("failed to init regmap\n"); | 62 | pr_err("failed to init regmap\n"); |
58 | return PTR_ERR(regmap); | 63 | return PTR_ERR(regmap); |
59 | } | 64 | } |
diff --git a/drivers/clk/sprd/sc9860-clk.c b/drivers/clk/sprd/sc9860-clk.c index 9980ab55271b..f76305b4bc8d 100644 --- a/drivers/clk/sprd/sc9860-clk.c +++ b/drivers/clk/sprd/sc9860-clk.c | |||
@@ -2023,6 +2023,7 @@ static int sc9860_clk_probe(struct platform_device *pdev) | |||
2023 | { | 2023 | { |
2024 | const struct of_device_id *match; | 2024 | const struct of_device_id *match; |
2025 | const struct sprd_clk_desc *desc; | 2025 | const struct sprd_clk_desc *desc; |
2026 | int ret; | ||
2026 | 2027 | ||
2027 | match = of_match_node(sprd_sc9860_clk_ids, pdev->dev.of_node); | 2028 | match = of_match_node(sprd_sc9860_clk_ids, pdev->dev.of_node); |
2028 | if (!match) { | 2029 | if (!match) { |
@@ -2031,7 +2032,9 @@ static int sc9860_clk_probe(struct platform_device *pdev) | |||
2031 | } | 2032 | } |
2032 | 2033 | ||
2033 | desc = match->data; | 2034 | desc = match->data; |
2034 | sprd_clk_regmap_init(pdev, desc); | 2035 | ret = sprd_clk_regmap_init(pdev, desc); |
2036 | if (ret) | ||
2037 | return ret; | ||
2035 | 2038 | ||
2036 | return sprd_clk_probe(&pdev->dev, desc->hw_clks); | 2039 | return sprd_clk_probe(&pdev->dev, desc->hw_clks); |
2037 | } | 2040 | } |
diff --git a/drivers/clk/sunxi-ng/ccu-sun4i-a10.c b/drivers/clk/sunxi-ng/ccu-sun4i-a10.c index df43952e403e..f32366d9336e 100644 --- a/drivers/clk/sunxi-ng/ccu-sun4i-a10.c +++ b/drivers/clk/sunxi-ng/ccu-sun4i-a10.c | |||
@@ -160,8 +160,9 @@ static struct ccu_nk pll_periph_base_clk = { | |||
160 | }, | 160 | }, |
161 | }; | 161 | }; |
162 | 162 | ||
163 | static CLK_FIXED_FACTOR(pll_periph_clk, "pll-periph", "pll-periph-base", | 163 | static CLK_FIXED_FACTOR_HW(pll_periph_clk, "pll-periph", |
164 | 2, 1, CLK_SET_RATE_PARENT); | 164 | &pll_periph_base_clk.common.hw, |
165 | 2, 1, CLK_SET_RATE_PARENT); | ||
165 | 166 | ||
166 | /* Not documented on A10 */ | 167 | /* Not documented on A10 */ |
167 | static struct ccu_div pll_periph_sata_clk = { | 168 | static struct ccu_div pll_periph_sata_clk = { |
@@ -1028,19 +1029,29 @@ static struct ccu_common *sun4i_sun7i_ccu_clks[] = { | |||
1028 | &out_b_clk.common | 1029 | &out_b_clk.common |
1029 | }; | 1030 | }; |
1030 | 1031 | ||
1032 | static const struct clk_hw *clk_parent_pll_audio[] = { | ||
1033 | &pll_audio_base_clk.common.hw | ||
1034 | }; | ||
1035 | |||
1031 | /* Post-divider for pll-audio is hardcoded to 1 */ | 1036 | /* Post-divider for pll-audio is hardcoded to 1 */ |
1032 | static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio", | 1037 | static CLK_FIXED_FACTOR_HWS(pll_audio_clk, "pll-audio", |
1033 | "pll-audio-base", 1, 1, CLK_SET_RATE_PARENT); | 1038 | clk_parent_pll_audio, |
1034 | static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x", | 1039 | 1, 1, CLK_SET_RATE_PARENT); |
1035 | "pll-audio-base", 2, 1, CLK_SET_RATE_PARENT); | 1040 | static CLK_FIXED_FACTOR_HWS(pll_audio_2x_clk, "pll-audio-2x", |
1036 | static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x", | 1041 | clk_parent_pll_audio, |
1037 | "pll-audio-base", 1, 1, CLK_SET_RATE_PARENT); | 1042 | 2, 1, CLK_SET_RATE_PARENT); |
1038 | static CLK_FIXED_FACTOR(pll_audio_8x_clk, "pll-audio-8x", | 1043 | static CLK_FIXED_FACTOR_HWS(pll_audio_4x_clk, "pll-audio-4x", |
1039 | "pll-audio-base", 1, 2, CLK_SET_RATE_PARENT); | 1044 | clk_parent_pll_audio, |
1040 | static CLK_FIXED_FACTOR(pll_video0_2x_clk, "pll-video0-2x", | 1045 | 1, 1, CLK_SET_RATE_PARENT); |
1041 | "pll-video0", 1, 2, CLK_SET_RATE_PARENT); | 1046 | static CLK_FIXED_FACTOR_HWS(pll_audio_8x_clk, "pll-audio-8x", |
1042 | static CLK_FIXED_FACTOR(pll_video1_2x_clk, "pll-video1-2x", | 1047 | clk_parent_pll_audio, |
1043 | "pll-video1", 1, 2, CLK_SET_RATE_PARENT); | 1048 | 1, 2, CLK_SET_RATE_PARENT); |
1049 | static CLK_FIXED_FACTOR_HW(pll_video0_2x_clk, "pll-video0-2x", | ||
1050 | &pll_video0_clk.common.hw, | ||
1051 | 1, 2, CLK_SET_RATE_PARENT); | ||
1052 | static CLK_FIXED_FACTOR_HW(pll_video1_2x_clk, "pll-video1-2x", | ||
1053 | &pll_video1_clk.common.hw, | ||
1054 | 1, 2, CLK_SET_RATE_PARENT); | ||
1044 | 1055 | ||
1045 | 1056 | ||
1046 | static struct clk_hw_onecell_data sun4i_a10_hw_clks = { | 1057 | static struct clk_hw_onecell_data sun4i_a10_hw_clks = { |
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c index 1786ee8fe8bb..49bd7a4c015c 100644 --- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c +++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c | |||
@@ -597,23 +597,34 @@ static SUNXI_CCU_M_WITH_GATE(gpu_clk, "gpu", "pll-gpu", | |||
597 | 0x1a0, 0, 3, BIT(31), CLK_SET_RATE_PARENT); | 597 | 0x1a0, 0, 3, BIT(31), CLK_SET_RATE_PARENT); |
598 | 598 | ||
599 | /* Fixed Factor clocks */ | 599 | /* Fixed Factor clocks */ |
600 | static CLK_FIXED_FACTOR(osc12M_clk, "osc12M", "osc24M", 2, 1, 0); | 600 | static CLK_FIXED_FACTOR_FW_NAME(osc12M_clk, "osc12M", "hosc", 2, 1, 0); |
601 | |||
602 | static const struct clk_hw *clk_parent_pll_audio[] = { | ||
603 | &pll_audio_base_clk.common.hw | ||
604 | }; | ||
601 | 605 | ||
602 | /* We hardcode the divider to 1 for now */ | 606 | /* We hardcode the divider to 1 for now */ |
603 | static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio", | 607 | static CLK_FIXED_FACTOR_HWS(pll_audio_clk, "pll-audio", |
604 | "pll-audio-base", 1, 1, CLK_SET_RATE_PARENT); | 608 | clk_parent_pll_audio, |
605 | static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x", | 609 | 1, 1, CLK_SET_RATE_PARENT); |
606 | "pll-audio-base", 2, 1, CLK_SET_RATE_PARENT); | 610 | static CLK_FIXED_FACTOR_HWS(pll_audio_2x_clk, "pll-audio-2x", |
607 | static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x", | 611 | clk_parent_pll_audio, |
608 | "pll-audio-base", 1, 1, CLK_SET_RATE_PARENT); | 612 | 2, 1, CLK_SET_RATE_PARENT); |
609 | static CLK_FIXED_FACTOR(pll_audio_8x_clk, "pll-audio-8x", | 613 | static CLK_FIXED_FACTOR_HWS(pll_audio_4x_clk, "pll-audio-4x", |
610 | "pll-audio-base", 1, 2, CLK_SET_RATE_PARENT); | 614 | clk_parent_pll_audio, |
611 | static CLK_FIXED_FACTOR(pll_periph0_2x_clk, "pll-periph0-2x", | 615 | 1, 1, CLK_SET_RATE_PARENT); |
612 | "pll-periph0", 1, 2, 0); | 616 | static CLK_FIXED_FACTOR_HWS(pll_audio_8x_clk, "pll-audio-8x", |
613 | static CLK_FIXED_FACTOR(pll_periph1_2x_clk, "pll-periph1-2x", | 617 | clk_parent_pll_audio, |
614 | "pll-periph1", 1, 2, 0); | 618 | 1, 2, CLK_SET_RATE_PARENT); |
615 | static CLK_FIXED_FACTOR(pll_video0_2x_clk, "pll-video0-2x", | 619 | static CLK_FIXED_FACTOR_HW(pll_periph0_2x_clk, "pll-periph0-2x", |
616 | "pll-video0", 1, 2, CLK_SET_RATE_PARENT); | 620 | &pll_periph0_clk.common.hw, |
621 | 1, 2, 0); | ||
622 | static CLK_FIXED_FACTOR_HW(pll_periph1_2x_clk, "pll-periph1-2x", | ||
623 | &pll_periph1_clk.common.hw, | ||
624 | 1, 2, 0); | ||
625 | static CLK_FIXED_FACTOR_HW(pll_video0_2x_clk, "pll-video0-2x", | ||
626 | &pll_video0_clk.common.hw, | ||
627 | 1, 2, CLK_SET_RATE_PARENT); | ||
617 | 628 | ||
618 | static struct ccu_common *sun50i_a64_ccu_clks[] = { | 629 | static struct ccu_common *sun50i_a64_ccu_clks[] = { |
619 | &pll_cpux_clk.common, | 630 | &pll_cpux_clk.common, |
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c b/drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c index 27554eaf6929..45a1ed3fe674 100644 --- a/drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c +++ b/drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c | |||
@@ -49,7 +49,7 @@ static struct ccu_div ar100_clk = { | |||
49 | }, | 49 | }, |
50 | }; | 50 | }; |
51 | 51 | ||
52 | static CLK_FIXED_FACTOR(r_ahb_clk, "r-ahb", "ar100", 1, 1, 0); | 52 | static CLK_FIXED_FACTOR_HW(r_ahb_clk, "r-ahb", &ar100_clk.common.hw, 1, 1, 0); |
53 | 53 | ||
54 | static struct ccu_div r_apb1_clk = { | 54 | static struct ccu_div r_apb1_clk = { |
55 | .div = _SUNXI_CCU_DIV(0, 2), | 55 | .div = _SUNXI_CCU_DIV(0, 2), |
@@ -104,7 +104,7 @@ static SUNXI_CCU_GATE(r_apb2_i2c_clk, "r-apb2-i2c", "r-apb2", | |||
104 | static SUNXI_CCU_GATE(r_apb1_ir_clk, "r-apb1-ir", "r-apb1", | 104 | static SUNXI_CCU_GATE(r_apb1_ir_clk, "r-apb1-ir", "r-apb1", |
105 | 0x1cc, BIT(0), 0); | 105 | 0x1cc, BIT(0), 0); |
106 | static SUNXI_CCU_GATE(r_apb1_w1_clk, "r-apb1-w1", "r-apb1", | 106 | static SUNXI_CCU_GATE(r_apb1_w1_clk, "r-apb1-w1", "r-apb1", |
107 | 0x1cc, BIT(0), 0); | 107 | 0x1ec, BIT(0), 0); |
108 | 108 | ||
109 | /* Information of IR(RX) mod clock is gathered from BSP source code */ | 109 | /* Information of IR(RX) mod clock is gathered from BSP source code */ |
110 | static const char * const r_mod0_default_parents[] = { "osc32k", "osc24M" }; | 110 | static const char * const r_mod0_default_parents[] = { "osc32k", "osc24M" }; |
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c index 9d3f98962779..aebef4af9861 100644 --- a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c +++ b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c | |||
@@ -622,8 +622,9 @@ static SUNXI_CCU_GATE(bus_xhci_clk, "bus-xhci", "ahb3", 0xa8c, BIT(5), 0); | |||
622 | static SUNXI_CCU_GATE(bus_ehci3_clk, "bus-ehci3", "ahb3", 0xa8c, BIT(7), 0); | 622 | static SUNXI_CCU_GATE(bus_ehci3_clk, "bus-ehci3", "ahb3", 0xa8c, BIT(7), 0); |
623 | static SUNXI_CCU_GATE(bus_otg_clk, "bus-otg", "ahb3", 0xa8c, BIT(8), 0); | 623 | static SUNXI_CCU_GATE(bus_otg_clk, "bus-otg", "ahb3", 0xa8c, BIT(8), 0); |
624 | 624 | ||
625 | static CLK_FIXED_FACTOR(pcie_ref_100m_clk, "pcie-ref-100M", | 625 | static struct clk_fixed_factor pll_periph0_4x_clk; |
626 | "pll-periph0-4x", 24, 1, 0); | 626 | static CLK_FIXED_FACTOR_HW(pcie_ref_100m_clk, "pcie-ref-100M", |
627 | &pll_periph0_4x_clk.hw, 24, 1, 0); | ||
627 | static SUNXI_CCU_GATE(pcie_ref_clk, "pcie-ref", "pcie-ref-100M", | 628 | static SUNXI_CCU_GATE(pcie_ref_clk, "pcie-ref", "pcie-ref-100M", |
628 | 0xab0, BIT(31), 0); | 629 | 0xab0, BIT(31), 0); |
629 | static SUNXI_CCU_GATE(pcie_ref_out_clk, "pcie-ref-out", "pcie-ref", | 630 | static SUNXI_CCU_GATE(pcie_ref_out_clk, "pcie-ref-out", "pcie-ref", |
@@ -745,34 +746,52 @@ static SUNXI_CCU_M_WITH_MUX_GATE(hdcp_clk, "hdcp", hdcp_parents, 0xc40, | |||
745 | static SUNXI_CCU_GATE(bus_hdcp_clk, "bus-hdcp", "ahb3", 0xc4c, BIT(0), 0); | 746 | static SUNXI_CCU_GATE(bus_hdcp_clk, "bus-hdcp", "ahb3", 0xc4c, BIT(0), 0); |
746 | 747 | ||
747 | /* Fixed factor clocks */ | 748 | /* Fixed factor clocks */ |
748 | static CLK_FIXED_FACTOR(osc12M_clk, "osc12M", "osc24M", 2, 1, 0); | 749 | static CLK_FIXED_FACTOR_FW_NAME(osc12M_clk, "osc12M", "hosc", 2, 1, 0); |
750 | |||
751 | static const struct clk_hw *clk_parent_pll_audio[] = { | ||
752 | &pll_audio_base_clk.common.hw | ||
753 | }; | ||
749 | 754 | ||
750 | /* | 755 | /* |
751 | * The divider of pll-audio is fixed to 8 now, as pll-audio-4x has a | 756 | * The divider of pll-audio is fixed to 8 now, as pll-audio-4x has a |
752 | * fixed post-divider 2. | 757 | * fixed post-divider 2. |
753 | */ | 758 | */ |
754 | static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio", | 759 | static CLK_FIXED_FACTOR_HWS(pll_audio_clk, "pll-audio", |
755 | "pll-audio-base", 8, 1, CLK_SET_RATE_PARENT); | 760 | clk_parent_pll_audio, |
756 | static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x", | 761 | 8, 1, CLK_SET_RATE_PARENT); |
757 | "pll-audio-base", 4, 1, CLK_SET_RATE_PARENT); | 762 | static CLK_FIXED_FACTOR_HWS(pll_audio_2x_clk, "pll-audio-2x", |
758 | static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x", | 763 | clk_parent_pll_audio, |
759 | "pll-audio-base", 2, 1, CLK_SET_RATE_PARENT); | 764 | 4, 1, CLK_SET_RATE_PARENT); |
760 | 765 | static CLK_FIXED_FACTOR_HWS(pll_audio_4x_clk, "pll-audio-4x", | |
761 | static CLK_FIXED_FACTOR(pll_periph0_4x_clk, "pll-periph0-4x", | 766 | clk_parent_pll_audio, |
762 | "pll-periph0", 1, 4, 0); | 767 | 2, 1, CLK_SET_RATE_PARENT); |
763 | static CLK_FIXED_FACTOR(pll_periph0_2x_clk, "pll-periph0-2x", | 768 | |
764 | "pll-periph0", 1, 2, 0); | 769 | static const struct clk_hw *pll_periph0_parents[] = { |
765 | 770 | &pll_periph0_clk.common.hw | |
766 | static CLK_FIXED_FACTOR(pll_periph1_4x_clk, "pll-periph1-4x", | 771 | }; |
767 | "pll-periph1", 1, 4, 0); | 772 | static CLK_FIXED_FACTOR_HWS(pll_periph0_4x_clk, "pll-periph0-4x", |
768 | static CLK_FIXED_FACTOR(pll_periph1_2x_clk, "pll-periph1-2x", | 773 | pll_periph0_parents, |
769 | "pll-periph1", 1, 2, 0); | 774 | 1, 4, 0); |
770 | 775 | static CLK_FIXED_FACTOR_HWS(pll_periph0_2x_clk, "pll-periph0-2x", | |
771 | static CLK_FIXED_FACTOR(pll_video0_4x_clk, "pll-video0-4x", | 776 | pll_periph0_parents, |
772 | "pll-video0", 1, 4, CLK_SET_RATE_PARENT); | 777 | 1, 2, 0); |
773 | 778 | ||
774 | static CLK_FIXED_FACTOR(pll_video1_4x_clk, "pll-video1-4x", | 779 | static const struct clk_hw *pll_periph1_parents[] = { |
775 | "pll-video1", 1, 4, CLK_SET_RATE_PARENT); | 780 | &pll_periph1_clk.common.hw |
781 | }; | ||
782 | static CLK_FIXED_FACTOR_HWS(pll_periph1_4x_clk, "pll-periph1-4x", | ||
783 | pll_periph1_parents, | ||
784 | 1, 4, 0); | ||
785 | static CLK_FIXED_FACTOR_HWS(pll_periph1_2x_clk, "pll-periph1-2x", | ||
786 | pll_periph1_parents, | ||
787 | 1, 2, 0); | ||
788 | |||
789 | static CLK_FIXED_FACTOR_HW(pll_video0_4x_clk, "pll-video0-4x", | ||
790 | &pll_video0_clk.common.hw, | ||
791 | 1, 4, CLK_SET_RATE_PARENT); | ||
792 | static CLK_FIXED_FACTOR_HW(pll_video1_4x_clk, "pll-video1-4x", | ||
793 | &pll_video1_clk.common.hw, | ||
794 | 1, 4, CLK_SET_RATE_PARENT); | ||
776 | 795 | ||
777 | static struct ccu_common *sun50i_h6_ccu_clks[] = { | 796 | static struct ccu_common *sun50i_h6_ccu_clks[] = { |
778 | &pll_cpux_clk.common, | 797 | &pll_cpux_clk.common, |
diff --git a/drivers/clk/sunxi-ng/ccu-sun5i.c b/drivers/clk/sunxi-ng/ccu-sun5i.c index b71ed0f6f785..b78e9b507c1c 100644 --- a/drivers/clk/sunxi-ng/ccu-sun5i.c +++ b/drivers/clk/sunxi-ng/ccu-sun5i.c | |||
@@ -603,19 +603,29 @@ static struct ccu_common *sun5i_a10s_ccu_clks[] = { | |||
603 | &iep_clk.common, | 603 | &iep_clk.common, |
604 | }; | 604 | }; |
605 | 605 | ||
606 | static const struct clk_hw *clk_parent_pll_audio[] = { | ||
607 | &pll_audio_base_clk.common.hw | ||
608 | }; | ||
609 | |||
606 | /* We hardcode the divider to 1 for now */ | 610 | /* We hardcode the divider to 1 for now */ |
607 | static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio", | 611 | static CLK_FIXED_FACTOR_HWS(pll_audio_clk, "pll-audio", |
608 | "pll-audio-base", 1, 1, CLK_SET_RATE_PARENT); | 612 | clk_parent_pll_audio, |
609 | static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x", | 613 | 1, 1, CLK_SET_RATE_PARENT); |
610 | "pll-audio-base", 2, 1, CLK_SET_RATE_PARENT); | 614 | static CLK_FIXED_FACTOR_HWS(pll_audio_2x_clk, "pll-audio-2x", |
611 | static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x", | 615 | clk_parent_pll_audio, |
612 | "pll-audio-base", 1, 1, CLK_SET_RATE_PARENT); | 616 | 2, 1, CLK_SET_RATE_PARENT); |
613 | static CLK_FIXED_FACTOR(pll_audio_8x_clk, "pll-audio-8x", | 617 | static CLK_FIXED_FACTOR_HWS(pll_audio_4x_clk, "pll-audio-4x", |
614 | "pll-audio-base", 1, 2, CLK_SET_RATE_PARENT); | 618 | clk_parent_pll_audio, |
615 | static CLK_FIXED_FACTOR(pll_video0_2x_clk, "pll-video0-2x", | 619 | 1, 1, CLK_SET_RATE_PARENT); |
616 | "pll-video0", 1, 2, CLK_SET_RATE_PARENT); | 620 | static CLK_FIXED_FACTOR_HWS(pll_audio_8x_clk, "pll-audio-8x", |
617 | static CLK_FIXED_FACTOR(pll_video1_2x_clk, "pll-video1-2x", | 621 | clk_parent_pll_audio, |
618 | "pll-video1", 1, 2, CLK_SET_RATE_PARENT); | 622 | 1, 2, CLK_SET_RATE_PARENT); |
623 | static CLK_FIXED_FACTOR_HW(pll_video0_2x_clk, "pll-video0-2x", | ||
624 | &pll_video0_clk.common.hw, | ||
625 | 1, 2, CLK_SET_RATE_PARENT); | ||
626 | static CLK_FIXED_FACTOR_HW(pll_video1_2x_clk, "pll-video1-2x", | ||
627 | &pll_video1_clk.common.hw, | ||
628 | 1, 2, CLK_SET_RATE_PARENT); | ||
619 | 629 | ||
620 | static struct clk_hw_onecell_data sun5i_a10s_hw_clks = { | 630 | static struct clk_hw_onecell_data sun5i_a10s_hw_clks = { |
621 | .hws = { | 631 | .hws = { |
diff --git a/drivers/clk/sunxi-ng/ccu-sun6i-a31.c b/drivers/clk/sunxi-ng/ccu-sun6i-a31.c index 2ff7b082df28..9b40d53266a3 100644 --- a/drivers/clk/sunxi-ng/ccu-sun6i-a31.c +++ b/drivers/clk/sunxi-ng/ccu-sun6i-a31.c | |||
@@ -955,21 +955,32 @@ static struct ccu_common *sun6i_a31_ccu_clks[] = { | |||
955 | &out_c_clk.common, | 955 | &out_c_clk.common, |
956 | }; | 956 | }; |
957 | 957 | ||
958 | static const struct clk_hw *clk_parent_pll_audio[] = { | ||
959 | &pll_audio_base_clk.common.hw | ||
960 | }; | ||
961 | |||
958 | /* We hardcode the divider to 1 for now */ | 962 | /* We hardcode the divider to 1 for now */ |
959 | static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio", | 963 | static CLK_FIXED_FACTOR_HWS(pll_audio_clk, "pll-audio", |
960 | "pll-audio-base", 1, 1, CLK_SET_RATE_PARENT); | 964 | clk_parent_pll_audio, |
961 | static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x", | 965 | 1, 1, CLK_SET_RATE_PARENT); |
962 | "pll-audio-base", 2, 1, CLK_SET_RATE_PARENT); | 966 | static CLK_FIXED_FACTOR_HWS(pll_audio_2x_clk, "pll-audio-2x", |
963 | static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x", | 967 | clk_parent_pll_audio, |
964 | "pll-audio-base", 1, 1, CLK_SET_RATE_PARENT); | 968 | 2, 1, CLK_SET_RATE_PARENT); |
965 | static CLK_FIXED_FACTOR(pll_audio_8x_clk, "pll-audio-8x", | 969 | static CLK_FIXED_FACTOR_HWS(pll_audio_4x_clk, "pll-audio-4x", |
966 | "pll-audio-base", 1, 2, CLK_SET_RATE_PARENT); | 970 | clk_parent_pll_audio, |
967 | static CLK_FIXED_FACTOR(pll_periph_2x_clk, "pll-periph-2x", | 971 | 1, 1, CLK_SET_RATE_PARENT); |
968 | "pll-periph", 1, 2, 0); | 972 | static CLK_FIXED_FACTOR_HWS(pll_audio_8x_clk, "pll-audio-8x", |
969 | static CLK_FIXED_FACTOR(pll_video0_2x_clk, "pll-video0-2x", | 973 | clk_parent_pll_audio, |
970 | "pll-video0", 1, 2, CLK_SET_RATE_PARENT); | 974 | 1, 2, CLK_SET_RATE_PARENT); |
971 | static CLK_FIXED_FACTOR(pll_video1_2x_clk, "pll-video1-2x", | 975 | static CLK_FIXED_FACTOR_HW(pll_periph_2x_clk, "pll-periph-2x", |
972 | "pll-video1", 1, 2, CLK_SET_RATE_PARENT); | 976 | &pll_periph_clk.common.hw, |
977 | 1, 2, 0); | ||
978 | static CLK_FIXED_FACTOR_HW(pll_video0_2x_clk, "pll-video0-2x", | ||
979 | &pll_video0_clk.common.hw, | ||
980 | 1, 2, CLK_SET_RATE_PARENT); | ||
981 | static CLK_FIXED_FACTOR_HW(pll_video1_2x_clk, "pll-video1-2x", | ||
982 | &pll_video1_clk.common.hw, | ||
983 | 1, 2, CLK_SET_RATE_PARENT); | ||
973 | 984 | ||
974 | static struct clk_hw_onecell_data sun6i_a31_hw_clks = { | 985 | static struct clk_hw_onecell_data sun6i_a31_hw_clks = { |
975 | .hws = { | 986 | .hws = { |
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a23.c b/drivers/clk/sunxi-ng/ccu-sun8i-a23.c index 14ced502788a..103aa504f6c8 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-a23.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-a23.c | |||
@@ -543,19 +543,29 @@ static struct ccu_common *sun8i_a23_ccu_clks[] = { | |||
543 | &ats_clk.common, | 543 | &ats_clk.common, |
544 | }; | 544 | }; |
545 | 545 | ||
546 | static const struct clk_hw *clk_parent_pll_audio[] = { | ||
547 | &pll_audio_base_clk.common.hw | ||
548 | }; | ||
549 | |||
546 | /* We hardcode the divider to 1 for now */ | 550 | /* We hardcode the divider to 1 for now */ |
547 | static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio", | 551 | static CLK_FIXED_FACTOR_HWS(pll_audio_clk, "pll-audio", |
548 | "pll-audio-base", 1, 1, CLK_SET_RATE_PARENT); | 552 | clk_parent_pll_audio, |
549 | static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x", | 553 | 1, 1, CLK_SET_RATE_PARENT); |
550 | "pll-audio-base", 2, 1, CLK_SET_RATE_PARENT); | 554 | static CLK_FIXED_FACTOR_HWS(pll_audio_2x_clk, "pll-audio-2x", |
551 | static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x", | 555 | clk_parent_pll_audio, |
552 | "pll-audio-base", 1, 1, CLK_SET_RATE_PARENT); | 556 | 2, 1, CLK_SET_RATE_PARENT); |
553 | static CLK_FIXED_FACTOR(pll_audio_8x_clk, "pll-audio-8x", | 557 | static CLK_FIXED_FACTOR_HWS(pll_audio_4x_clk, "pll-audio-4x", |
554 | "pll-audio-base", 1, 2, CLK_SET_RATE_PARENT); | 558 | clk_parent_pll_audio, |
555 | static CLK_FIXED_FACTOR(pll_periph_2x_clk, "pll-periph-2x", | 559 | 1, 1, CLK_SET_RATE_PARENT); |
556 | "pll-periph", 1, 2, 0); | 560 | static CLK_FIXED_FACTOR_HWS(pll_audio_8x_clk, "pll-audio-8x", |
557 | static CLK_FIXED_FACTOR(pll_video_2x_clk, "pll-video-2x", | 561 | clk_parent_pll_audio, |
558 | "pll-video", 1, 2, 0); | 562 | 1, 2, CLK_SET_RATE_PARENT); |
563 | static CLK_FIXED_FACTOR_HW(pll_periph_2x_clk, "pll-periph-2x", | ||
564 | &pll_periph_clk.common.hw, | ||
565 | 1, 2, 0); | ||
566 | static CLK_FIXED_FACTOR_HW(pll_video_2x_clk, "pll-video-2x", | ||
567 | &pll_video_clk.common.hw, | ||
568 | 1, 2, 0); | ||
559 | 569 | ||
560 | static struct clk_hw_onecell_data sun8i_a23_hw_clks = { | 570 | static struct clk_hw_onecell_data sun8i_a23_hw_clks = { |
561 | .hws = { | 571 | .hws = { |
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a33.c b/drivers/clk/sunxi-ng/ccu-sun8i-a33.c index 61fb41f4903c..91838cd11037 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-a33.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-a33.c | |||
@@ -580,19 +580,29 @@ static struct ccu_common *sun8i_a33_ccu_clks[] = { | |||
580 | &ats_clk.common, | 580 | &ats_clk.common, |
581 | }; | 581 | }; |
582 | 582 | ||
583 | static const struct clk_hw *clk_parent_pll_audio[] = { | ||
584 | &pll_audio_base_clk.common.hw | ||
585 | }; | ||
586 | |||
583 | /* We hardcode the divider to 1 for now */ | 587 | /* We hardcode the divider to 1 for now */ |
584 | static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio", | 588 | static CLK_FIXED_FACTOR_HWS(pll_audio_clk, "pll-audio", |
585 | "pll-audio-base", 1, 1, CLK_SET_RATE_PARENT); | 589 | clk_parent_pll_audio, |
586 | static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x", | 590 | 1, 1, CLK_SET_RATE_PARENT); |
587 | "pll-audio-base", 2, 1, CLK_SET_RATE_PARENT); | 591 | static CLK_FIXED_FACTOR_HWS(pll_audio_2x_clk, "pll-audio-2x", |
588 | static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x", | 592 | clk_parent_pll_audio, |
589 | "pll-audio-base", 1, 1, CLK_SET_RATE_PARENT); | 593 | 2, 1, CLK_SET_RATE_PARENT); |
590 | static CLK_FIXED_FACTOR(pll_audio_8x_clk, "pll-audio-8x", | 594 | static CLK_FIXED_FACTOR_HWS(pll_audio_4x_clk, "pll-audio-4x", |
591 | "pll-audio-base", 1, 2, CLK_SET_RATE_PARENT); | 595 | clk_parent_pll_audio, |
592 | static CLK_FIXED_FACTOR(pll_periph_2x_clk, "pll-periph-2x", | 596 | 1, 1, CLK_SET_RATE_PARENT); |
593 | "pll-periph", 1, 2, 0); | 597 | static CLK_FIXED_FACTOR_HWS(pll_audio_8x_clk, "pll-audio-8x", |
594 | static CLK_FIXED_FACTOR(pll_video_2x_clk, "pll-video-2x", | 598 | clk_parent_pll_audio, |
595 | "pll-video", 1, 2, 0); | 599 | 1, 2, CLK_SET_RATE_PARENT); |
600 | static CLK_FIXED_FACTOR_HW(pll_periph_2x_clk, "pll-periph-2x", | ||
601 | &pll_periph_clk.common.hw, | ||
602 | 1, 2, 0); | ||
603 | static CLK_FIXED_FACTOR_HW(pll_video_2x_clk, "pll-video-2x", | ||
604 | &pll_video_clk.common.hw, | ||
605 | 1, 2, 0); | ||
596 | 606 | ||
597 | static struct clk_hw_onecell_data sun8i_a33_hw_clks = { | 607 | static struct clk_hw_onecell_data sun8i_a33_hw_clks = { |
598 | .hws = { | 608 | .hws = { |
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c index 9601504905b2..6b636362379e 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c | |||
@@ -717,17 +717,26 @@ static struct ccu_common *sun50i_h5_ccu_clks[] = { | |||
717 | &gpu_clk.common, | 717 | &gpu_clk.common, |
718 | }; | 718 | }; |
719 | 719 | ||
720 | static const struct clk_hw *clk_parent_pll_audio[] = { | ||
721 | &pll_audio_base_clk.common.hw | ||
722 | }; | ||
723 | |||
720 | /* We hardcode the divider to 1 for now */ | 724 | /* We hardcode the divider to 1 for now */ |
721 | static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio", | 725 | static CLK_FIXED_FACTOR_HWS(pll_audio_clk, "pll-audio", |
722 | "pll-audio-base", 1, 1, CLK_SET_RATE_PARENT); | 726 | clk_parent_pll_audio, |
723 | static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x", | 727 | 1, 1, CLK_SET_RATE_PARENT); |
724 | "pll-audio-base", 2, 1, CLK_SET_RATE_PARENT); | 728 | static CLK_FIXED_FACTOR_HWS(pll_audio_2x_clk, "pll-audio-2x", |
725 | static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x", | 729 | clk_parent_pll_audio, |
726 | "pll-audio-base", 1, 1, CLK_SET_RATE_PARENT); | 730 | 2, 1, CLK_SET_RATE_PARENT); |
727 | static CLK_FIXED_FACTOR(pll_audio_8x_clk, "pll-audio-8x", | 731 | static CLK_FIXED_FACTOR_HWS(pll_audio_4x_clk, "pll-audio-4x", |
728 | "pll-audio-base", 1, 2, CLK_SET_RATE_PARENT); | 732 | clk_parent_pll_audio, |
729 | static CLK_FIXED_FACTOR(pll_periph0_2x_clk, "pll-periph0-2x", | 733 | 1, 1, CLK_SET_RATE_PARENT); |
730 | "pll-periph0", 1, 2, 0); | 734 | static CLK_FIXED_FACTOR_HWS(pll_audio_8x_clk, "pll-audio-8x", |
735 | clk_parent_pll_audio, | ||
736 | 1, 2, CLK_SET_RATE_PARENT); | ||
737 | static CLK_FIXED_FACTOR_HW(pll_periph0_2x_clk, "pll-periph0-2x", | ||
738 | &pll_periph0_clk.common.hw, | ||
739 | 1, 2, 0); | ||
731 | 740 | ||
732 | static struct clk_hw_onecell_data sun8i_h3_hw_clks = { | 741 | static struct clk_hw_onecell_data sun8i_h3_hw_clks = { |
733 | .hws = { | 742 | .hws = { |
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r.c b/drivers/clk/sunxi-ng/ccu-sun8i-r.c index b5be11e5de0d..4646fdc61053 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-r.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-r.c | |||
@@ -17,10 +17,13 @@ | |||
17 | 17 | ||
18 | #include "ccu-sun8i-r.h" | 18 | #include "ccu-sun8i-r.h" |
19 | 19 | ||
20 | static const char * const ar100_parents[] = { "osc32k", "osc24M", | 20 | static const struct clk_parent_data ar100_parents[] = { |
21 | "pll-periph0", "iosc" }; | 21 | { .fw_name = "losc" }, |
22 | static const char * const a83t_ar100_parents[] = { "osc16M-d512", "osc24M", | 22 | { .fw_name = "hosc" }, |
23 | "pll-periph0", "iosc" }; | 23 | { .fw_name = "pll-periph" }, |
24 | { .fw_name = "iosc" }, | ||
25 | }; | ||
26 | |||
24 | static const struct ccu_mux_var_prediv ar100_predivs[] = { | 27 | static const struct ccu_mux_var_prediv ar100_predivs[] = { |
25 | { .index = 2, .shift = 8, .width = 5 }, | 28 | { .index = 2, .shift = 8, .width = 5 }, |
26 | }; | 29 | }; |
@@ -39,64 +42,49 @@ static struct ccu_div ar100_clk = { | |||
39 | .common = { | 42 | .common = { |
40 | .reg = 0x00, | 43 | .reg = 0x00, |
41 | .features = CCU_FEATURE_VARIABLE_PREDIV, | 44 | .features = CCU_FEATURE_VARIABLE_PREDIV, |
42 | .hw.init = CLK_HW_INIT_PARENTS("ar100", | 45 | .hw.init = CLK_HW_INIT_PARENTS_DATA("ar100", |
43 | ar100_parents, | 46 | ar100_parents, |
44 | &ccu_div_ops, | 47 | &ccu_div_ops, |
45 | 0), | 48 | 0), |
46 | }, | ||
47 | }; | ||
48 | |||
49 | static struct ccu_div a83t_ar100_clk = { | ||
50 | .div = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO), | ||
51 | |||
52 | .mux = { | ||
53 | .shift = 16, | ||
54 | .width = 2, | ||
55 | |||
56 | .var_predivs = ar100_predivs, | ||
57 | .n_var_predivs = ARRAY_SIZE(ar100_predivs), | ||
58 | }, | ||
59 | |||
60 | .common = { | ||
61 | .reg = 0x00, | ||
62 | .features = CCU_FEATURE_VARIABLE_PREDIV, | ||
63 | .hw.init = CLK_HW_INIT_PARENTS("ar100", | ||
64 | a83t_ar100_parents, | ||
65 | &ccu_div_ops, | ||
66 | 0), | ||
67 | }, | 49 | }, |
68 | }; | 50 | }; |
69 | 51 | ||
70 | static CLK_FIXED_FACTOR(ahb0_clk, "ahb0", "ar100", 1, 1, 0); | 52 | static CLK_FIXED_FACTOR_HW(ahb0_clk, "ahb0", &ar100_clk.common.hw, 1, 1, 0); |
71 | 53 | ||
72 | static struct ccu_div apb0_clk = { | 54 | static struct ccu_div apb0_clk = { |
73 | .div = _SUNXI_CCU_DIV_FLAGS(0, 2, CLK_DIVIDER_POWER_OF_TWO), | 55 | .div = _SUNXI_CCU_DIV_FLAGS(0, 2, CLK_DIVIDER_POWER_OF_TWO), |
74 | 56 | ||
75 | .common = { | 57 | .common = { |
76 | .reg = 0x0c, | 58 | .reg = 0x0c, |
77 | .hw.init = CLK_HW_INIT("apb0", | 59 | .hw.init = CLK_HW_INIT_HW("apb0", |
78 | "ahb0", | 60 | &ahb0_clk.hw, |
79 | &ccu_div_ops, | 61 | &ccu_div_ops, |
80 | 0), | 62 | 0), |
81 | }, | 63 | }, |
82 | }; | 64 | }; |
83 | 65 | ||
84 | static SUNXI_CCU_M(a83t_apb0_clk, "apb0", "ahb0", 0x0c, 0, 2, 0); | 66 | static SUNXI_CCU_M(a83t_apb0_clk, "apb0", "ahb0", 0x0c, 0, 2, 0); |
85 | 67 | ||
86 | static SUNXI_CCU_GATE(apb0_pio_clk, "apb0-pio", "apb0", | 68 | /* |
87 | 0x28, BIT(0), 0); | 69 | * Define the parent as an array that can be reused to save space |
88 | static SUNXI_CCU_GATE(apb0_ir_clk, "apb0-ir", "apb0", | 70 | * instead of having compound literals for each gate. Also have it |
89 | 0x28, BIT(1), 0); | 71 | * non-const so we can change it on the A83T. |
90 | static SUNXI_CCU_GATE(apb0_timer_clk, "apb0-timer", "apb0", | 72 | */ |
91 | 0x28, BIT(2), 0); | 73 | static const struct clk_hw *apb0_gate_parent[] = { &apb0_clk.common.hw }; |
92 | static SUNXI_CCU_GATE(apb0_rsb_clk, "apb0-rsb", "apb0", | 74 | static SUNXI_CCU_GATE_HWS(apb0_pio_clk, "apb0-pio", |
93 | 0x28, BIT(3), 0); | 75 | apb0_gate_parent, 0x28, BIT(0), 0); |
94 | static SUNXI_CCU_GATE(apb0_uart_clk, "apb0-uart", "apb0", | 76 | static SUNXI_CCU_GATE_HWS(apb0_ir_clk, "apb0-ir", |
95 | 0x28, BIT(4), 0); | 77 | apb0_gate_parent, 0x28, BIT(1), 0); |
96 | static SUNXI_CCU_GATE(apb0_i2c_clk, "apb0-i2c", "apb0", | 78 | static SUNXI_CCU_GATE_HWS(apb0_timer_clk, "apb0-timer", |
97 | 0x28, BIT(6), 0); | 79 | apb0_gate_parent, 0x28, BIT(2), 0); |
98 | static SUNXI_CCU_GATE(apb0_twd_clk, "apb0-twd", "apb0", | 80 | static SUNXI_CCU_GATE_HWS(apb0_rsb_clk, "apb0-rsb", |
99 | 0x28, BIT(7), 0); | 81 | apb0_gate_parent, 0x28, BIT(3), 0); |
82 | static SUNXI_CCU_GATE_HWS(apb0_uart_clk, "apb0-uart", | ||
83 | apb0_gate_parent, 0x28, BIT(4), 0); | ||
84 | static SUNXI_CCU_GATE_HWS(apb0_i2c_clk, "apb0-i2c", | ||
85 | apb0_gate_parent, 0x28, BIT(6), 0); | ||
86 | static SUNXI_CCU_GATE_HWS(apb0_twd_clk, "apb0-twd", | ||
87 | apb0_gate_parent, 0x28, BIT(7), 0); | ||
100 | 88 | ||
101 | static const char * const r_mod0_default_parents[] = { "osc32k", "osc24M" }; | 89 | static const char * const r_mod0_default_parents[] = { "osc32k", "osc24M" }; |
102 | static SUNXI_CCU_MP_WITH_MUX_GATE(ir_clk, "ir", | 90 | static SUNXI_CCU_MP_WITH_MUX_GATE(ir_clk, "ir", |
@@ -107,7 +95,10 @@ static SUNXI_CCU_MP_WITH_MUX_GATE(ir_clk, "ir", | |||
107 | BIT(31), /* gate */ | 95 | BIT(31), /* gate */ |
108 | 0); | 96 | 0); |
109 | 97 | ||
110 | static const char *const a83t_r_mod0_parents[] = { "osc16M", "osc24M" }; | 98 | static const struct clk_parent_data a83t_r_mod0_parents[] = { |
99 | { .fw_name = "iosc" }, | ||
100 | { .fw_name = "hosc" }, | ||
101 | }; | ||
111 | static const struct ccu_mux_fixed_prediv a83t_ir_predivs[] = { | 102 | static const struct ccu_mux_fixed_prediv a83t_ir_predivs[] = { |
112 | { .index = 0, .div = 16 }, | 103 | { .index = 0, .div = 16 }, |
113 | }; | 104 | }; |
@@ -127,15 +118,15 @@ static struct ccu_mp a83t_ir_clk = { | |||
127 | .common = { | 118 | .common = { |
128 | .reg = 0x54, | 119 | .reg = 0x54, |
129 | .features = CCU_FEATURE_VARIABLE_PREDIV, | 120 | .features = CCU_FEATURE_VARIABLE_PREDIV, |
130 | .hw.init = CLK_HW_INIT_PARENTS("ir", | 121 | .hw.init = CLK_HW_INIT_PARENTS_DATA("ir", |
131 | a83t_r_mod0_parents, | 122 | a83t_r_mod0_parents, |
132 | &ccu_mp_ops, | 123 | &ccu_mp_ops, |
133 | 0), | 124 | 0), |
134 | }, | 125 | }, |
135 | }; | 126 | }; |
136 | 127 | ||
137 | static struct ccu_common *sun8i_a83t_r_ccu_clks[] = { | 128 | static struct ccu_common *sun8i_a83t_r_ccu_clks[] = { |
138 | &a83t_ar100_clk.common, | 129 | &ar100_clk.common, |
139 | &a83t_apb0_clk.common, | 130 | &a83t_apb0_clk.common, |
140 | &apb0_pio_clk.common, | 131 | &apb0_pio_clk.common, |
141 | &apb0_ir_clk.common, | 132 | &apb0_ir_clk.common, |
@@ -174,7 +165,7 @@ static struct ccu_common *sun50i_a64_r_ccu_clks[] = { | |||
174 | 165 | ||
175 | static struct clk_hw_onecell_data sun8i_a83t_r_hw_clks = { | 166 | static struct clk_hw_onecell_data sun8i_a83t_r_hw_clks = { |
176 | .hws = { | 167 | .hws = { |
177 | [CLK_AR100] = &a83t_ar100_clk.common.hw, | 168 | [CLK_AR100] = &ar100_clk.common.hw, |
178 | [CLK_AHB0] = &ahb0_clk.hw, | 169 | [CLK_AHB0] = &ahb0_clk.hw, |
179 | [CLK_APB0] = &a83t_apb0_clk.common.hw, | 170 | [CLK_APB0] = &a83t_apb0_clk.common.hw, |
180 | [CLK_APB0_PIO] = &apb0_pio_clk.common.hw, | 171 | [CLK_APB0_PIO] = &apb0_pio_clk.common.hw, |
@@ -291,6 +282,9 @@ static void __init sunxi_r_ccu_init(struct device_node *node, | |||
291 | 282 | ||
292 | static void __init sun8i_a83t_r_ccu_setup(struct device_node *node) | 283 | static void __init sun8i_a83t_r_ccu_setup(struct device_node *node) |
293 | { | 284 | { |
285 | /* Fix apb0 bus gate parents here */ | ||
286 | apb0_gate_parent[0] = &a83t_apb0_clk.common.hw; | ||
287 | |||
294 | sunxi_r_ccu_init(node, &sun8i_a83t_r_ccu_desc); | 288 | sunxi_r_ccu_init(node, &sun8i_a83t_r_ccu_desc); |
295 | } | 289 | } |
296 | CLK_OF_DECLARE(sun8i_a83t_r_ccu, "allwinner,sun8i-a83t-r-ccu", | 290 | CLK_OF_DECLARE(sun8i_a83t_r_ccu, "allwinner,sun8i-a83t-r-ccu", |
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r40.c b/drivers/clk/sunxi-ng/ccu-sun8i-r40.c index 540f5f7454fc..897490800102 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-r40.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-r40.c | |||
@@ -944,25 +944,37 @@ static struct ccu_common *sun8i_r40_ccu_clks[] = { | |||
944 | }; | 944 | }; |
945 | 945 | ||
946 | /* Fixed Factor clocks */ | 946 | /* Fixed Factor clocks */ |
947 | static CLK_FIXED_FACTOR(osc12M_clk, "osc12M", "osc24M", 2, 1, 0); | 947 | static CLK_FIXED_FACTOR_FW_NAME(osc12M_clk, "osc12M", "hosc", 2, 1, 0); |
948 | |||
949 | static const struct clk_hw *clk_parent_pll_audio[] = { | ||
950 | &pll_audio_base_clk.common.hw | ||
951 | }; | ||
948 | 952 | ||
949 | /* We hardcode the divider to 4 for now */ | 953 | /* We hardcode the divider to 4 for now */ |
950 | static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio", | 954 | static CLK_FIXED_FACTOR_HWS(pll_audio_clk, "pll-audio", |
951 | "pll-audio-base", 4, 1, CLK_SET_RATE_PARENT); | 955 | clk_parent_pll_audio, |
952 | static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x", | 956 | 4, 1, CLK_SET_RATE_PARENT); |
953 | "pll-audio-base", 2, 1, CLK_SET_RATE_PARENT); | 957 | static CLK_FIXED_FACTOR_HWS(pll_audio_2x_clk, "pll-audio-2x", |
954 | static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x", | 958 | clk_parent_pll_audio, |
955 | "pll-audio-base", 1, 1, CLK_SET_RATE_PARENT); | 959 | 2, 1, CLK_SET_RATE_PARENT); |
956 | static CLK_FIXED_FACTOR(pll_audio_8x_clk, "pll-audio-8x", | 960 | static CLK_FIXED_FACTOR_HWS(pll_audio_4x_clk, "pll-audio-4x", |
957 | "pll-audio-base", 1, 2, CLK_SET_RATE_PARENT); | 961 | clk_parent_pll_audio, |
958 | static CLK_FIXED_FACTOR(pll_periph0_2x_clk, "pll-periph0-2x", | 962 | 1, 1, CLK_SET_RATE_PARENT); |
959 | "pll-periph0", 1, 2, 0); | 963 | static CLK_FIXED_FACTOR_HWS(pll_audio_8x_clk, "pll-audio-8x", |
960 | static CLK_FIXED_FACTOR(pll_periph1_2x_clk, "pll-periph1-2x", | 964 | clk_parent_pll_audio, |
961 | "pll-periph1", 1, 2, 0); | 965 | 1, 2, CLK_SET_RATE_PARENT); |
962 | static CLK_FIXED_FACTOR(pll_video0_2x_clk, "pll-video0-2x", | 966 | static CLK_FIXED_FACTOR_HW(pll_periph0_2x_clk, "pll-periph0-2x", |
963 | "pll-video0", 1, 2, 0); | 967 | &pll_periph0_clk.common.hw, |
964 | static CLK_FIXED_FACTOR(pll_video1_2x_clk, "pll-video1-2x", | 968 | 1, 2, 0); |
965 | "pll-video1", 1, 2, 0); | 969 | static CLK_FIXED_FACTOR_HW(pll_periph1_2x_clk, "pll-periph1-2x", |
970 | &pll_periph1_clk.common.hw, | ||
971 | 1, 2, 0); | ||
972 | static CLK_FIXED_FACTOR_HW(pll_video0_2x_clk, "pll-video0-2x", | ||
973 | &pll_video0_clk.common.hw, | ||
974 | 1, 2, 0); | ||
975 | static CLK_FIXED_FACTOR_HW(pll_video1_2x_clk, "pll-video1-2x", | ||
976 | &pll_video1_clk.common.hw, | ||
977 | 1, 2, 0); | ||
966 | 978 | ||
967 | static struct clk_hw_onecell_data sun8i_r40_hw_clks = { | 979 | static struct clk_hw_onecell_data sun8i_r40_hw_clks = { |
968 | .hws = { | 980 | .hws = { |
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c b/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c index cbbf06d42c2c..9b3939fc7faa 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c | |||
@@ -429,17 +429,26 @@ static struct ccu_common *sun8i_v3s_ccu_clks[] = { | |||
429 | &mipi_csi_clk.common, | 429 | &mipi_csi_clk.common, |
430 | }; | 430 | }; |
431 | 431 | ||
432 | static const struct clk_hw *clk_parent_pll_audio[] = { | ||
433 | &pll_audio_base_clk.common.hw | ||
434 | }; | ||
435 | |||
432 | /* We hardcode the divider to 4 for now */ | 436 | /* We hardcode the divider to 4 for now */ |
433 | static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio", | 437 | static CLK_FIXED_FACTOR_HWS(pll_audio_clk, "pll-audio", |
434 | "pll-audio-base", 4, 1, CLK_SET_RATE_PARENT); | 438 | clk_parent_pll_audio, |
435 | static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x", | 439 | 4, 1, CLK_SET_RATE_PARENT); |
436 | "pll-audio-base", 2, 1, CLK_SET_RATE_PARENT); | 440 | static CLK_FIXED_FACTOR_HWS(pll_audio_2x_clk, "pll-audio-2x", |
437 | static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x", | 441 | clk_parent_pll_audio, |
438 | "pll-audio-base", 1, 1, CLK_SET_RATE_PARENT); | 442 | 2, 1, CLK_SET_RATE_PARENT); |
439 | static CLK_FIXED_FACTOR(pll_audio_8x_clk, "pll-audio-8x", | 443 | static CLK_FIXED_FACTOR_HWS(pll_audio_4x_clk, "pll-audio-4x", |
440 | "pll-audio-base", 1, 2, CLK_SET_RATE_PARENT); | 444 | clk_parent_pll_audio, |
441 | static CLK_FIXED_FACTOR(pll_periph0_2x_clk, "pll-periph0-2x", | 445 | 1, 1, CLK_SET_RATE_PARENT); |
442 | "pll-periph0", 1, 2, 0); | 446 | static CLK_FIXED_FACTOR_HWS(pll_audio_8x_clk, "pll-audio-8x", |
447 | clk_parent_pll_audio, | ||
448 | 1, 2, CLK_SET_RATE_PARENT); | ||
449 | static CLK_FIXED_FACTOR_HW(pll_periph0_2x_clk, "pll-periph0-2x", | ||
450 | &pll_periph0_clk.common.hw, | ||
451 | 1, 2, 0); | ||
443 | 452 | ||
444 | static struct clk_hw_onecell_data sun8i_v3s_hw_clks = { | 453 | static struct clk_hw_onecell_data sun8i_v3s_hw_clks = { |
445 | .hws = { | 454 | .hws = { |
diff --git a/drivers/clk/sunxi-ng/ccu-sun9i-a80-usb.c b/drivers/clk/sunxi-ng/ccu-sun9i-a80-usb.c index 2f82cd855b0f..4b4a507d04ed 100644 --- a/drivers/clk/sunxi-ng/ccu-sun9i-a80-usb.c +++ b/drivers/clk/sunxi-ng/ccu-sun9i-a80-usb.c | |||
@@ -14,18 +14,26 @@ | |||
14 | 14 | ||
15 | #include "ccu-sun9i-a80-usb.h" | 15 | #include "ccu-sun9i-a80-usb.h" |
16 | 16 | ||
17 | static SUNXI_CCU_GATE(bus_hci0_clk, "bus-hci0", "bus-usb", 0x0, BIT(1), 0); | 17 | static const struct clk_parent_data clk_parent_hosc[] = { |
18 | static SUNXI_CCU_GATE(usb_ohci0_clk, "usb-ohci0", "osc24M", 0x0, BIT(2), 0); | 18 | { .fw_name = "hosc" }, |
19 | static SUNXI_CCU_GATE(bus_hci1_clk, "bus-hci1", "bus-usb", 0x0, BIT(3), 0); | 19 | }; |
20 | static SUNXI_CCU_GATE(bus_hci2_clk, "bus-hci2", "bus-usb", 0x0, BIT(5), 0); | 20 | |
21 | static SUNXI_CCU_GATE(usb_ohci2_clk, "usb-ohci2", "osc24M", 0x0, BIT(6), 0); | 21 | static const struct clk_parent_data clk_parent_bus[] = { |
22 | 22 | { .fw_name = "bus" }, | |
23 | static SUNXI_CCU_GATE(usb0_phy_clk, "usb0-phy", "osc24M", 0x4, BIT(1), 0); | 23 | }; |
24 | static SUNXI_CCU_GATE(usb1_hsic_clk, "usb1-hsic", "osc24M", 0x4, BIT(2), 0); | 24 | |
25 | static SUNXI_CCU_GATE(usb1_phy_clk, "usb1-phy", "osc24M", 0x4, BIT(3), 0); | 25 | static SUNXI_CCU_GATE_DATA(bus_hci0_clk, "bus-hci0", clk_parent_bus, 0x0, BIT(1), 0); |
26 | static SUNXI_CCU_GATE(usb2_hsic_clk, "usb2-hsic", "osc24M", 0x4, BIT(4), 0); | 26 | static SUNXI_CCU_GATE_DATA(usb_ohci0_clk, "usb-ohci0", clk_parent_hosc, 0x0, BIT(2), 0); |
27 | static SUNXI_CCU_GATE(usb2_phy_clk, "usb2-phy", "osc24M", 0x4, BIT(5), 0); | 27 | static SUNXI_CCU_GATE_DATA(bus_hci1_clk, "bus-hci1", clk_parent_bus, 0x0, BIT(3), 0); |
28 | static SUNXI_CCU_GATE(usb_hsic_clk, "usb-hsic", "osc24M", 0x4, BIT(10), 0); | 28 | static SUNXI_CCU_GATE_DATA(bus_hci2_clk, "bus-hci2", clk_parent_bus, 0x0, BIT(5), 0); |
29 | static SUNXI_CCU_GATE_DATA(usb_ohci2_clk, "usb-ohci2", clk_parent_hosc, 0x0, BIT(6), 0); | ||
30 | |||
31 | static SUNXI_CCU_GATE_DATA(usb0_phy_clk, "usb0-phy", clk_parent_hosc, 0x4, BIT(1), 0); | ||
32 | static SUNXI_CCU_GATE_DATA(usb1_hsic_clk, "usb1-hsic", clk_parent_hosc, 0x4, BIT(2), 0); | ||
33 | static SUNXI_CCU_GATE_DATA(usb1_phy_clk, "usb1-phy", clk_parent_hosc, 0x4, BIT(3), 0); | ||
34 | static SUNXI_CCU_GATE_DATA(usb2_hsic_clk, "usb2-hsic", clk_parent_hosc, 0x4, BIT(4), 0); | ||
35 | static SUNXI_CCU_GATE_DATA(usb2_phy_clk, "usb2-phy", clk_parent_hosc, 0x4, BIT(5), 0); | ||
36 | static SUNXI_CCU_GATE_DATA(usb_hsic_clk, "usb-hsic", clk_parent_hosc, 0x4, BIT(10), 0); | ||
29 | 37 | ||
30 | static struct ccu_common *sun9i_a80_usb_clks[] = { | 38 | static struct ccu_common *sun9i_a80_usb_clks[] = { |
31 | &bus_hci0_clk.common, | 39 | &bus_hci0_clk.common, |
diff --git a/drivers/clk/sunxi-ng/ccu-suniv-f1c100s.c b/drivers/clk/sunxi-ng/ccu-suniv-f1c100s.c index e748b8a6f3c5..7ecc3a5a5b5e 100644 --- a/drivers/clk/sunxi-ng/ccu-suniv-f1c100s.c +++ b/drivers/clk/sunxi-ng/ccu-suniv-f1c100s.c | |||
@@ -374,16 +374,25 @@ static struct ccu_common *suniv_ccu_clks[] = { | |||
374 | &avs_clk.common, | 374 | &avs_clk.common, |
375 | }; | 375 | }; |
376 | 376 | ||
377 | static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio", | 377 | static const struct clk_hw *clk_parent_pll_audio[] = { |
378 | "pll-audio-base", 4, 1, CLK_SET_RATE_PARENT); | 378 | &pll_audio_base_clk.common.hw |
379 | static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x", | 379 | }; |
380 | "pll-audio-base", 2, 1, CLK_SET_RATE_PARENT); | 380 | |
381 | static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x", | 381 | static CLK_FIXED_FACTOR_HWS(pll_audio_clk, "pll-audio", |
382 | "pll-audio-base", 1, 1, CLK_SET_RATE_PARENT); | 382 | clk_parent_pll_audio, |
383 | static CLK_FIXED_FACTOR(pll_audio_8x_clk, "pll-audio-8x", | 383 | 4, 1, CLK_SET_RATE_PARENT); |
384 | "pll-audio-base", 1, 2, CLK_SET_RATE_PARENT); | 384 | static CLK_FIXED_FACTOR_HWS(pll_audio_2x_clk, "pll-audio-2x", |
385 | static CLK_FIXED_FACTOR(pll_video_2x_clk, "pll-video-2x", | 385 | clk_parent_pll_audio, |
386 | "pll-video", 1, 2, 0); | 386 | 2, 1, CLK_SET_RATE_PARENT); |
387 | static CLK_FIXED_FACTOR_HWS(pll_audio_4x_clk, "pll-audio-4x", | ||
388 | clk_parent_pll_audio, | ||
389 | 1, 1, CLK_SET_RATE_PARENT); | ||
390 | static CLK_FIXED_FACTOR_HWS(pll_audio_8x_clk, "pll-audio-8x", | ||
391 | clk_parent_pll_audio, | ||
392 | 1, 2, CLK_SET_RATE_PARENT); | ||
393 | static CLK_FIXED_FACTOR_HW(pll_video_2x_clk, "pll-video-2x", | ||
394 | &pll_video_clk.common.hw, | ||
395 | 1, 2, 0); | ||
387 | 396 | ||
388 | static struct clk_hw_onecell_data suniv_hw_clks = { | 397 | static struct clk_hw_onecell_data suniv_hw_clks = { |
389 | .hws = { | 398 | .hws = { |
diff --git a/drivers/clk/sunxi-ng/ccu_common.c b/drivers/clk/sunxi-ng/ccu_common.c index c173778c8a78..7fe3ac980e5f 100644 --- a/drivers/clk/sunxi-ng/ccu_common.c +++ b/drivers/clk/sunxi-ng/ccu_common.c | |||
@@ -101,7 +101,7 @@ int sunxi_ccu_probe(struct device_node *node, void __iomem *reg, | |||
101 | if (!hw) | 101 | if (!hw) |
102 | continue; | 102 | continue; |
103 | 103 | ||
104 | ret = clk_hw_register(NULL, hw); | 104 | ret = of_clk_hw_register(node, hw); |
105 | if (ret) { | 105 | if (ret) { |
106 | pr_err("Couldn't register clock %d - %s\n", | 106 | pr_err("Couldn't register clock %d - %s\n", |
107 | i, clk_hw_get_name(hw)); | 107 | i, clk_hw_get_name(hw)); |
diff --git a/drivers/clk/sunxi-ng/ccu_gate.h b/drivers/clk/sunxi-ng/ccu_gate.h index da8100e8846d..c386689a952b 100644 --- a/drivers/clk/sunxi-ng/ccu_gate.h +++ b/drivers/clk/sunxi-ng/ccu_gate.h | |||
@@ -28,6 +28,59 @@ struct ccu_gate { | |||
28 | } \ | 28 | } \ |
29 | } | 29 | } |
30 | 30 | ||
31 | #define SUNXI_CCU_GATE_HW(_struct, _name, _parent, _reg, _gate, _flags) \ | ||
32 | struct ccu_gate _struct = { \ | ||
33 | .enable = _gate, \ | ||
34 | .common = { \ | ||
35 | .reg = _reg, \ | ||
36 | .hw.init = CLK_HW_INIT_HW(_name, \ | ||
37 | _parent, \ | ||
38 | &ccu_gate_ops, \ | ||
39 | _flags), \ | ||
40 | } \ | ||
41 | } | ||
42 | |||
43 | #define SUNXI_CCU_GATE_FW(_struct, _name, _parent, _reg, _gate, _flags) \ | ||
44 | struct ccu_gate _struct = { \ | ||
45 | .enable = _gate, \ | ||
46 | .common = { \ | ||
47 | .reg = _reg, \ | ||
48 | .hw.init = CLK_HW_INIT_FW_NAME(_name, \ | ||
49 | _parent, \ | ||
50 | &ccu_gate_ops, \ | ||
51 | _flags), \ | ||
52 | } \ | ||
53 | } | ||
54 | |||
55 | /* | ||
56 | * The following two macros allow the re-use of the data structure | ||
57 | * holding the parent info. | ||
58 | */ | ||
59 | #define SUNXI_CCU_GATE_HWS(_struct, _name, _parent, _reg, _gate, _flags) \ | ||
60 | struct ccu_gate _struct = { \ | ||
61 | .enable = _gate, \ | ||
62 | .common = { \ | ||
63 | .reg = _reg, \ | ||
64 | .hw.init = CLK_HW_INIT_HWS(_name, \ | ||
65 | _parent, \ | ||
66 | &ccu_gate_ops, \ | ||
67 | _flags), \ | ||
68 | } \ | ||
69 | } | ||
70 | |||
71 | #define SUNXI_CCU_GATE_DATA(_struct, _name, _data, _reg, _gate, _flags) \ | ||
72 | struct ccu_gate _struct = { \ | ||
73 | .enable = _gate, \ | ||
74 | .common = { \ | ||
75 | .reg = _reg, \ | ||
76 | .hw.init = \ | ||
77 | CLK_HW_INIT_PARENTS_DATA(_name, \ | ||
78 | _data, \ | ||
79 | &ccu_gate_ops, \ | ||
80 | _flags), \ | ||
81 | } \ | ||
82 | } | ||
83 | |||
31 | static inline struct ccu_gate *hw_to_ccu_gate(struct clk_hw *hw) | 84 | static inline struct ccu_gate *hw_to_ccu_gate(struct clk_hw *hw) |
32 | { | 85 | { |
33 | struct ccu_common *common = hw_to_ccu_common(hw); | 86 | struct ccu_common *common = hw_to_ccu_common(hw); |
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c index 623fda5e911f..d3a43381a792 100644 --- a/drivers/clk/sunxi/clk-sunxi.c +++ b/drivers/clk/sunxi/clk-sunxi.c | |||
@@ -980,6 +980,8 @@ static struct clk ** __init sunxi_divs_clk_setup(struct device_node *node, | |||
980 | if (endp) { | 980 | if (endp) { |
981 | derived_name = kstrndup(clk_name, endp - clk_name, | 981 | derived_name = kstrndup(clk_name, endp - clk_name, |
982 | GFP_KERNEL); | 982 | GFP_KERNEL); |
983 | if (!derived_name) | ||
984 | return NULL; | ||
983 | factors.name = derived_name; | 985 | factors.name = derived_name; |
984 | } else { | 986 | } else { |
985 | factors.name = clk_name; | 987 | factors.name = clk_name; |
diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c index ac1d27a8c650..df172d5772d7 100644 --- a/drivers/clk/tegra/clk-tegra210.c +++ b/drivers/clk/tegra/clk-tegra210.c | |||
@@ -984,8 +984,6 @@ static void tegra210_pllre_set_defaults(struct tegra_clk_pll *pllre) | |||
984 | pllre->params->defaults_set = true; | 984 | pllre->params->defaults_set = true; |
985 | 985 | ||
986 | if (val & PLL_ENABLE) { | 986 | if (val & PLL_ENABLE) { |
987 | pr_warn("PLL_RE already enabled. Postponing set full defaults\n"); | ||
988 | |||
989 | /* | 987 | /* |
990 | * PLL is ON: check if defaults already set, then set those | 988 | * PLL is ON: check if defaults already set, then set those |
991 | * that can be updated in flight. | 989 | * that can be updated in flight. |
@@ -1005,13 +1003,20 @@ static void tegra210_pllre_set_defaults(struct tegra_clk_pll *pllre) | |||
1005 | _pll_misc_chk_default(clk_base, pllre->params, 0, val, | 1003 | _pll_misc_chk_default(clk_base, pllre->params, 0, val, |
1006 | ~mask & PLLRE_MISC0_WRITE_MASK); | 1004 | ~mask & PLLRE_MISC0_WRITE_MASK); |
1007 | 1005 | ||
1008 | /* Enable lock detect */ | 1006 | /* The PLL doesn't work if it's in IDDQ. */ |
1009 | val = readl_relaxed(clk_base + pllre->params->ext_misc_reg[0]); | 1007 | val = readl_relaxed(clk_base + pllre->params->ext_misc_reg[0]); |
1008 | if (val & PLLRE_MISC0_IDDQ) | ||
1009 | pr_warn("unexpected IDDQ bit set for enabled clock\n"); | ||
1010 | |||
1011 | /* Enable lock detect */ | ||
1010 | val &= ~mask; | 1012 | val &= ~mask; |
1011 | val |= PLLRE_MISC0_DEFAULT_VALUE & mask; | 1013 | val |= PLLRE_MISC0_DEFAULT_VALUE & mask; |
1012 | writel_relaxed(val, clk_base + pllre->params->ext_misc_reg[0]); | 1014 | writel_relaxed(val, clk_base + pllre->params->ext_misc_reg[0]); |
1013 | udelay(1); | 1015 | udelay(1); |
1014 | 1016 | ||
1017 | if (!pllre->params->defaults_set) | ||
1018 | pr_warn("PLL_RE already enabled. Postponing set full defaults\n"); | ||
1019 | |||
1015 | return; | 1020 | return; |
1016 | } | 1021 | } |
1017 | 1022 | ||
@@ -2204,9 +2209,9 @@ static struct div_nmp pllu_nmp = { | |||
2204 | }; | 2209 | }; |
2205 | 2210 | ||
2206 | static struct tegra_clk_pll_freq_table pll_u_freq_table[] = { | 2211 | static struct tegra_clk_pll_freq_table pll_u_freq_table[] = { |
2207 | { 12000000, 480000000, 40, 1, 0, 0 }, | 2212 | { 12000000, 480000000, 40, 1, 1, 0 }, |
2208 | { 13000000, 480000000, 36, 1, 0, 0 }, /* actual: 468.0 MHz */ | 2213 | { 13000000, 480000000, 36, 1, 1, 0 }, /* actual: 468.0 MHz */ |
2209 | { 38400000, 480000000, 25, 2, 0, 0 }, | 2214 | { 38400000, 480000000, 25, 2, 1, 0 }, |
2210 | { 0, 0, 0, 0, 0, 0 }, | 2215 | { 0, 0, 0, 0, 0, 0 }, |
2211 | }; | 2216 | }; |
2212 | 2217 | ||
@@ -3332,7 +3337,7 @@ static struct tegra_clk_init_table init_table[] __initdata = { | |||
3332 | { TEGRA210_CLK_DFLL_SOC, TEGRA210_CLK_PLL_P, 51000000, 1 }, | 3337 | { TEGRA210_CLK_DFLL_SOC, TEGRA210_CLK_PLL_P, 51000000, 1 }, |
3333 | { TEGRA210_CLK_DFLL_REF, TEGRA210_CLK_PLL_P, 51000000, 1 }, | 3338 | { TEGRA210_CLK_DFLL_REF, TEGRA210_CLK_PLL_P, 51000000, 1 }, |
3334 | { TEGRA210_CLK_SBC4, TEGRA210_CLK_PLL_P, 12000000, 1 }, | 3339 | { TEGRA210_CLK_SBC4, TEGRA210_CLK_PLL_P, 12000000, 1 }, |
3335 | { TEGRA210_CLK_PLL_RE_VCO, TEGRA210_CLK_CLK_MAX, 672000000, 1 }, | 3340 | { TEGRA210_CLK_PLL_U_OUT1, TEGRA210_CLK_CLK_MAX, 48000000, 1 }, |
3336 | { TEGRA210_CLK_XUSB_GATE, TEGRA210_CLK_CLK_MAX, 0, 1 }, | 3341 | { TEGRA210_CLK_XUSB_GATE, TEGRA210_CLK_CLK_MAX, 0, 1 }, |
3337 | { TEGRA210_CLK_XUSB_SS_SRC, TEGRA210_CLK_PLL_U_480M, 120000000, 0 }, | 3342 | { TEGRA210_CLK_XUSB_SS_SRC, TEGRA210_CLK_PLL_U_480M, 120000000, 0 }, |
3338 | { TEGRA210_CLK_XUSB_FS_SRC, TEGRA210_CLK_PLL_U_48M, 48000000, 0 }, | 3343 | { TEGRA210_CLK_XUSB_FS_SRC, TEGRA210_CLK_PLL_U_48M, 48000000, 0 }, |
@@ -3357,7 +3362,6 @@ static struct tegra_clk_init_table init_table[] __initdata = { | |||
3357 | { TEGRA210_CLK_PLL_DP, TEGRA210_CLK_CLK_MAX, 270000000, 0 }, | 3362 | { TEGRA210_CLK_PLL_DP, TEGRA210_CLK_CLK_MAX, 270000000, 0 }, |
3358 | { TEGRA210_CLK_SOC_THERM, TEGRA210_CLK_PLL_P, 51000000, 0 }, | 3363 | { TEGRA210_CLK_SOC_THERM, TEGRA210_CLK_PLL_P, 51000000, 0 }, |
3359 | { TEGRA210_CLK_CCLK_G, TEGRA210_CLK_CLK_MAX, 0, 1 }, | 3364 | { TEGRA210_CLK_CCLK_G, TEGRA210_CLK_CLK_MAX, 0, 1 }, |
3360 | { TEGRA210_CLK_PLL_U_OUT1, TEGRA210_CLK_CLK_MAX, 48000000, 1 }, | ||
3361 | { TEGRA210_CLK_PLL_U_OUT2, TEGRA210_CLK_CLK_MAX, 60000000, 1 }, | 3365 | { TEGRA210_CLK_PLL_U_OUT2, TEGRA210_CLK_CLK_MAX, 60000000, 1 }, |
3362 | { TEGRA210_CLK_SPDIF_IN_SYNC, TEGRA210_CLK_CLK_MAX, 24576000, 0 }, | 3366 | { TEGRA210_CLK_SPDIF_IN_SYNC, TEGRA210_CLK_CLK_MAX, 24576000, 0 }, |
3363 | { TEGRA210_CLK_I2S0_SYNC, TEGRA210_CLK_CLK_MAX, 24576000, 0 }, | 3367 | { TEGRA210_CLK_I2S0_SYNC, TEGRA210_CLK_CLK_MAX, 24576000, 0 }, |
diff --git a/drivers/clk/ti/divider.c b/drivers/clk/ti/divider.c index 4786e0ebc2e8..6cb863c13648 100644 --- a/drivers/clk/ti/divider.c +++ b/drivers/clk/ti/divider.c | |||
@@ -425,91 +425,6 @@ int ti_clk_parse_divider_data(int *div_table, int num_dividers, int max_div, | |||
425 | return 0; | 425 | return 0; |
426 | } | 426 | } |
427 | 427 | ||
428 | static const struct clk_div_table * | ||
429 | _get_div_table_from_setup(struct ti_clk_divider *setup, u8 *width) | ||
430 | { | ||
431 | const struct clk_div_table *table = NULL; | ||
432 | |||
433 | ti_clk_parse_divider_data(setup->dividers, setup->num_dividers, | ||
434 | setup->max_div, setup->flags, width, | ||
435 | &table); | ||
436 | |||
437 | return table; | ||
438 | } | ||
439 | |||
440 | struct clk_hw *ti_clk_build_component_div(struct ti_clk_divider *setup) | ||
441 | { | ||
442 | struct clk_omap_divider *div; | ||
443 | struct clk_omap_reg *reg; | ||
444 | int ret; | ||
445 | |||
446 | if (!setup) | ||
447 | return NULL; | ||
448 | |||
449 | div = kzalloc(sizeof(*div), GFP_KERNEL); | ||
450 | if (!div) | ||
451 | return ERR_PTR(-ENOMEM); | ||
452 | |||
453 | reg = (struct clk_omap_reg *)&div->reg; | ||
454 | reg->index = setup->module; | ||
455 | reg->offset = setup->reg; | ||
456 | |||
457 | if (setup->flags & CLKF_INDEX_STARTS_AT_ONE) | ||
458 | div->flags |= CLK_DIVIDER_ONE_BASED; | ||
459 | |||
460 | if (setup->flags & CLKF_INDEX_POWER_OF_TWO) | ||
461 | div->flags |= CLK_DIVIDER_POWER_OF_TWO; | ||
462 | |||
463 | div->table = _get_div_table_from_setup(setup, &div->width); | ||
464 | if (IS_ERR(div->table)) { | ||
465 | ret = PTR_ERR(div->table); | ||
466 | kfree(div); | ||
467 | return ERR_PTR(ret); | ||
468 | } | ||
469 | |||
470 | |||
471 | div->shift = setup->bit_shift; | ||
472 | div->latch = -EINVAL; | ||
473 | |||
474 | return &div->hw; | ||
475 | } | ||
476 | |||
477 | struct clk *ti_clk_register_divider(struct ti_clk *setup) | ||
478 | { | ||
479 | struct ti_clk_divider *div = setup->data; | ||
480 | struct clk_omap_reg reg = { | ||
481 | .index = div->module, | ||
482 | .offset = div->reg, | ||
483 | }; | ||
484 | u8 width; | ||
485 | u32 flags = 0; | ||
486 | u8 div_flags = 0; | ||
487 | const struct clk_div_table *table; | ||
488 | struct clk *clk; | ||
489 | |||
490 | if (div->flags & CLKF_INDEX_STARTS_AT_ONE) | ||
491 | div_flags |= CLK_DIVIDER_ONE_BASED; | ||
492 | |||
493 | if (div->flags & CLKF_INDEX_POWER_OF_TWO) | ||
494 | div_flags |= CLK_DIVIDER_POWER_OF_TWO; | ||
495 | |||
496 | if (div->flags & CLKF_SET_RATE_PARENT) | ||
497 | flags |= CLK_SET_RATE_PARENT; | ||
498 | |||
499 | table = _get_div_table_from_setup(div, &width); | ||
500 | if (IS_ERR(table)) | ||
501 | return (struct clk *)table; | ||
502 | |||
503 | clk = _register_divider(NULL, setup->name, div->parent, | ||
504 | flags, ®, div->bit_shift, | ||
505 | width, -EINVAL, div_flags, table); | ||
506 | |||
507 | if (IS_ERR(clk)) | ||
508 | kfree(table); | ||
509 | |||
510 | return clk; | ||
511 | } | ||
512 | |||
513 | static struct clk_div_table * | 428 | static struct clk_div_table * |
514 | __init ti_clk_get_div_table(struct device_node *node) | 429 | __init ti_clk_get_div_table(struct device_node *node) |
515 | { | 430 | { |
diff --git a/drivers/clk/ti/gate.c b/drivers/clk/ti/gate.c index 504c0e91cdc7..42389558418c 100644 --- a/drivers/clk/ti/gate.c +++ b/drivers/clk/ti/gate.c | |||
@@ -131,36 +131,6 @@ static struct clk *_register_gate(struct device *dev, const char *name, | |||
131 | return clk; | 131 | return clk; |
132 | } | 132 | } |
133 | 133 | ||
134 | struct clk_hw *ti_clk_build_component_gate(struct ti_clk_gate *setup) | ||
135 | { | ||
136 | struct clk_hw_omap *gate; | ||
137 | struct clk_omap_reg *reg; | ||
138 | const struct clk_hw_omap_ops *ops = &clkhwops_wait; | ||
139 | |||
140 | if (!setup) | ||
141 | return NULL; | ||
142 | |||
143 | gate = kzalloc(sizeof(*gate), GFP_KERNEL); | ||
144 | if (!gate) | ||
145 | return ERR_PTR(-ENOMEM); | ||
146 | |||
147 | reg = (struct clk_omap_reg *)&gate->enable_reg; | ||
148 | reg->index = setup->module; | ||
149 | reg->offset = setup->reg; | ||
150 | |||
151 | gate->enable_bit = setup->bit_shift; | ||
152 | |||
153 | if (setup->flags & CLKF_NO_WAIT) | ||
154 | ops = NULL; | ||
155 | |||
156 | if (setup->flags & CLKF_INTERFACE) | ||
157 | ops = &clkhwops_iclk_wait; | ||
158 | |||
159 | gate->ops = ops; | ||
160 | |||
161 | return &gate->hw; | ||
162 | } | ||
163 | |||
164 | static void __init _of_ti_gate_clk_setup(struct device_node *node, | 134 | static void __init _of_ti_gate_clk_setup(struct device_node *node, |
165 | const struct clk_ops *ops, | 135 | const struct clk_ops *ops, |
166 | const struct clk_hw_omap_ops *hw_ops) | 136 | const struct clk_hw_omap_ops *hw_ops) |
diff --git a/drivers/clk/ti/mux.c b/drivers/clk/ti/mux.c index b7f9a4f068bf..0069e7cf3ebc 100644 --- a/drivers/clk/ti/mux.c +++ b/drivers/clk/ti/mux.c | |||
@@ -164,37 +164,6 @@ static struct clk *_register_mux(struct device *dev, const char *name, | |||
164 | return clk; | 164 | return clk; |
165 | } | 165 | } |
166 | 166 | ||
167 | struct clk *ti_clk_register_mux(struct ti_clk *setup) | ||
168 | { | ||
169 | struct ti_clk_mux *mux; | ||
170 | u32 flags; | ||
171 | u8 mux_flags = 0; | ||
172 | struct clk_omap_reg reg; | ||
173 | u32 mask; | ||
174 | |||
175 | mux = setup->data; | ||
176 | flags = CLK_SET_RATE_NO_REPARENT; | ||
177 | |||
178 | mask = mux->num_parents; | ||
179 | if (!(mux->flags & CLKF_INDEX_STARTS_AT_ONE)) | ||
180 | mask--; | ||
181 | |||
182 | mask = (1 << fls(mask)) - 1; | ||
183 | reg.index = mux->module; | ||
184 | reg.offset = mux->reg; | ||
185 | reg.ptr = NULL; | ||
186 | |||
187 | if (mux->flags & CLKF_INDEX_STARTS_AT_ONE) | ||
188 | mux_flags |= CLK_MUX_INDEX_ONE; | ||
189 | |||
190 | if (mux->flags & CLKF_SET_RATE_PARENT) | ||
191 | flags |= CLK_SET_RATE_PARENT; | ||
192 | |||
193 | return _register_mux(NULL, setup->name, mux->parents, mux->num_parents, | ||
194 | flags, ®, mux->bit_shift, mask, -EINVAL, | ||
195 | mux_flags, NULL); | ||
196 | } | ||
197 | |||
198 | /** | 167 | /** |
199 | * of_mux_clk_setup - Setup function for simple mux rate clock | 168 | * of_mux_clk_setup - Setup function for simple mux rate clock |
200 | * @node: DT node for the clock | 169 | * @node: DT node for the clock |
diff --git a/drivers/firmware/raspberrypi.c b/drivers/firmware/raspberrypi.c index 61be15d9df7d..da26a584dca0 100644 --- a/drivers/firmware/raspberrypi.c +++ b/drivers/firmware/raspberrypi.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #define MBOX_CHAN_PROPERTY 8 | 20 | #define MBOX_CHAN_PROPERTY 8 |
21 | 21 | ||
22 | static struct platform_device *rpi_hwmon; | 22 | static struct platform_device *rpi_hwmon; |
23 | static struct platform_device *rpi_clk; | ||
23 | 24 | ||
24 | struct rpi_firmware { | 25 | struct rpi_firmware { |
25 | struct mbox_client cl; | 26 | struct mbox_client cl; |
@@ -207,6 +208,12 @@ rpi_register_hwmon_driver(struct device *dev, struct rpi_firmware *fw) | |||
207 | -1, NULL, 0); | 208 | -1, NULL, 0); |
208 | } | 209 | } |
209 | 210 | ||
211 | static void rpi_register_clk_driver(struct device *dev) | ||
212 | { | ||
213 | rpi_clk = platform_device_register_data(dev, "raspberrypi-clk", | ||
214 | -1, NULL, 0); | ||
215 | } | ||
216 | |||
210 | static int rpi_firmware_probe(struct platform_device *pdev) | 217 | static int rpi_firmware_probe(struct platform_device *pdev) |
211 | { | 218 | { |
212 | struct device *dev = &pdev->dev; | 219 | struct device *dev = &pdev->dev; |
@@ -234,6 +241,7 @@ static int rpi_firmware_probe(struct platform_device *pdev) | |||
234 | 241 | ||
235 | rpi_firmware_print_firmware_revision(fw); | 242 | rpi_firmware_print_firmware_revision(fw); |
236 | rpi_register_hwmon_driver(dev, fw); | 243 | rpi_register_hwmon_driver(dev, fw); |
244 | rpi_register_clk_driver(dev); | ||
237 | 245 | ||
238 | return 0; | 246 | return 0; |
239 | } | 247 | } |
@@ -254,6 +262,8 @@ static int rpi_firmware_remove(struct platform_device *pdev) | |||
254 | 262 | ||
255 | platform_device_unregister(rpi_hwmon); | 263 | platform_device_unregister(rpi_hwmon); |
256 | rpi_hwmon = NULL; | 264 | rpi_hwmon = NULL; |
265 | platform_device_unregister(rpi_clk); | ||
266 | rpi_clk = NULL; | ||
257 | mbox_free_channel(fw->chan); | 267 | mbox_free_channel(fw->chan); |
258 | 268 | ||
259 | return 0; | 269 | return 0; |
diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c index ef93406ace1b..7696c692ad5a 100644 --- a/drivers/firmware/ti_sci.c +++ b/drivers/firmware/ti_sci.c | |||
@@ -916,7 +916,7 @@ static int ti_sci_cmd_get_device_resets(const struct ti_sci_handle *handle, | |||
916 | * Return: 0 if all went well, else returns appropriate error value. | 916 | * Return: 0 if all went well, else returns appropriate error value. |
917 | */ | 917 | */ |
918 | static int ti_sci_set_clock_state(const struct ti_sci_handle *handle, | 918 | static int ti_sci_set_clock_state(const struct ti_sci_handle *handle, |
919 | u32 dev_id, u8 clk_id, | 919 | u32 dev_id, u32 clk_id, |
920 | u32 flags, u8 state) | 920 | u32 flags, u8 state) |
921 | { | 921 | { |
922 | struct ti_sci_info *info; | 922 | struct ti_sci_info *info; |
@@ -944,7 +944,12 @@ static int ti_sci_set_clock_state(const struct ti_sci_handle *handle, | |||
944 | } | 944 | } |
945 | req = (struct ti_sci_msg_req_set_clock_state *)xfer->xfer_buf; | 945 | req = (struct ti_sci_msg_req_set_clock_state *)xfer->xfer_buf; |
946 | req->dev_id = dev_id; | 946 | req->dev_id = dev_id; |
947 | req->clk_id = clk_id; | 947 | if (clk_id < 255) { |
948 | req->clk_id = clk_id; | ||
949 | } else { | ||
950 | req->clk_id = 255; | ||
951 | req->clk_id_32 = clk_id; | ||
952 | } | ||
948 | req->request_state = state; | 953 | req->request_state = state; |
949 | 954 | ||
950 | ret = ti_sci_do_xfer(info, xfer); | 955 | ret = ti_sci_do_xfer(info, xfer); |
@@ -976,7 +981,7 @@ fail: | |||
976 | * Return: 0 if all went well, else returns appropriate error value. | 981 | * Return: 0 if all went well, else returns appropriate error value. |
977 | */ | 982 | */ |
978 | static int ti_sci_cmd_get_clock_state(const struct ti_sci_handle *handle, | 983 | static int ti_sci_cmd_get_clock_state(const struct ti_sci_handle *handle, |
979 | u32 dev_id, u8 clk_id, | 984 | u32 dev_id, u32 clk_id, |
980 | u8 *programmed_state, u8 *current_state) | 985 | u8 *programmed_state, u8 *current_state) |
981 | { | 986 | { |
982 | struct ti_sci_info *info; | 987 | struct ti_sci_info *info; |
@@ -1007,7 +1012,12 @@ static int ti_sci_cmd_get_clock_state(const struct ti_sci_handle *handle, | |||
1007 | } | 1012 | } |
1008 | req = (struct ti_sci_msg_req_get_clock_state *)xfer->xfer_buf; | 1013 | req = (struct ti_sci_msg_req_get_clock_state *)xfer->xfer_buf; |
1009 | req->dev_id = dev_id; | 1014 | req->dev_id = dev_id; |
1010 | req->clk_id = clk_id; | 1015 | if (clk_id < 255) { |
1016 | req->clk_id = clk_id; | ||
1017 | } else { | ||
1018 | req->clk_id = 255; | ||
1019 | req->clk_id_32 = clk_id; | ||
1020 | } | ||
1011 | 1021 | ||
1012 | ret = ti_sci_do_xfer(info, xfer); | 1022 | ret = ti_sci_do_xfer(info, xfer); |
1013 | if (ret) { | 1023 | if (ret) { |
@@ -1047,8 +1057,8 @@ fail: | |||
1047 | * Return: 0 if all went well, else returns appropriate error value. | 1057 | * Return: 0 if all went well, else returns appropriate error value. |
1048 | */ | 1058 | */ |
1049 | static int ti_sci_cmd_get_clock(const struct ti_sci_handle *handle, u32 dev_id, | 1059 | static int ti_sci_cmd_get_clock(const struct ti_sci_handle *handle, u32 dev_id, |
1050 | u8 clk_id, bool needs_ssc, bool can_change_freq, | 1060 | u32 clk_id, bool needs_ssc, |
1051 | bool enable_input_term) | 1061 | bool can_change_freq, bool enable_input_term) |
1052 | { | 1062 | { |
1053 | u32 flags = 0; | 1063 | u32 flags = 0; |
1054 | 1064 | ||
@@ -1073,7 +1083,7 @@ static int ti_sci_cmd_get_clock(const struct ti_sci_handle *handle, u32 dev_id, | |||
1073 | * Return: 0 if all went well, else returns appropriate error value. | 1083 | * Return: 0 if all went well, else returns appropriate error value. |
1074 | */ | 1084 | */ |
1075 | static int ti_sci_cmd_idle_clock(const struct ti_sci_handle *handle, | 1085 | static int ti_sci_cmd_idle_clock(const struct ti_sci_handle *handle, |
1076 | u32 dev_id, u8 clk_id) | 1086 | u32 dev_id, u32 clk_id) |
1077 | { | 1087 | { |
1078 | return ti_sci_set_clock_state(handle, dev_id, clk_id, 0, | 1088 | return ti_sci_set_clock_state(handle, dev_id, clk_id, 0, |
1079 | MSG_CLOCK_SW_STATE_UNREQ); | 1089 | MSG_CLOCK_SW_STATE_UNREQ); |
@@ -1092,7 +1102,7 @@ static int ti_sci_cmd_idle_clock(const struct ti_sci_handle *handle, | |||
1092 | * Return: 0 if all went well, else returns appropriate error value. | 1102 | * Return: 0 if all went well, else returns appropriate error value. |
1093 | */ | 1103 | */ |
1094 | static int ti_sci_cmd_put_clock(const struct ti_sci_handle *handle, | 1104 | static int ti_sci_cmd_put_clock(const struct ti_sci_handle *handle, |
1095 | u32 dev_id, u8 clk_id) | 1105 | u32 dev_id, u32 clk_id) |
1096 | { | 1106 | { |
1097 | return ti_sci_set_clock_state(handle, dev_id, clk_id, 0, | 1107 | return ti_sci_set_clock_state(handle, dev_id, clk_id, 0, |
1098 | MSG_CLOCK_SW_STATE_AUTO); | 1108 | MSG_CLOCK_SW_STATE_AUTO); |
@@ -1110,7 +1120,7 @@ static int ti_sci_cmd_put_clock(const struct ti_sci_handle *handle, | |||
1110 | * Return: 0 if all went well, else returns appropriate error value. | 1120 | * Return: 0 if all went well, else returns appropriate error value. |
1111 | */ | 1121 | */ |
1112 | static int ti_sci_cmd_clk_is_auto(const struct ti_sci_handle *handle, | 1122 | static int ti_sci_cmd_clk_is_auto(const struct ti_sci_handle *handle, |
1113 | u32 dev_id, u8 clk_id, bool *req_state) | 1123 | u32 dev_id, u32 clk_id, bool *req_state) |
1114 | { | 1124 | { |
1115 | u8 state = 0; | 1125 | u8 state = 0; |
1116 | int ret; | 1126 | int ret; |
@@ -1139,7 +1149,7 @@ static int ti_sci_cmd_clk_is_auto(const struct ti_sci_handle *handle, | |||
1139 | * Return: 0 if all went well, else returns appropriate error value. | 1149 | * Return: 0 if all went well, else returns appropriate error value. |
1140 | */ | 1150 | */ |
1141 | static int ti_sci_cmd_clk_is_on(const struct ti_sci_handle *handle, u32 dev_id, | 1151 | static int ti_sci_cmd_clk_is_on(const struct ti_sci_handle *handle, u32 dev_id, |
1142 | u8 clk_id, bool *req_state, bool *curr_state) | 1152 | u32 clk_id, bool *req_state, bool *curr_state) |
1143 | { | 1153 | { |
1144 | u8 c_state = 0, r_state = 0; | 1154 | u8 c_state = 0, r_state = 0; |
1145 | int ret; | 1155 | int ret; |
@@ -1172,7 +1182,7 @@ static int ti_sci_cmd_clk_is_on(const struct ti_sci_handle *handle, u32 dev_id, | |||
1172 | * Return: 0 if all went well, else returns appropriate error value. | 1182 | * Return: 0 if all went well, else returns appropriate error value. |
1173 | */ | 1183 | */ |
1174 | static int ti_sci_cmd_clk_is_off(const struct ti_sci_handle *handle, u32 dev_id, | 1184 | static int ti_sci_cmd_clk_is_off(const struct ti_sci_handle *handle, u32 dev_id, |
1175 | u8 clk_id, bool *req_state, bool *curr_state) | 1185 | u32 clk_id, bool *req_state, bool *curr_state) |
1176 | { | 1186 | { |
1177 | u8 c_state = 0, r_state = 0; | 1187 | u8 c_state = 0, r_state = 0; |
1178 | int ret; | 1188 | int ret; |
@@ -1204,7 +1214,7 @@ static int ti_sci_cmd_clk_is_off(const struct ti_sci_handle *handle, u32 dev_id, | |||
1204 | * Return: 0 if all went well, else returns appropriate error value. | 1214 | * Return: 0 if all went well, else returns appropriate error value. |
1205 | */ | 1215 | */ |
1206 | static int ti_sci_cmd_clk_set_parent(const struct ti_sci_handle *handle, | 1216 | static int ti_sci_cmd_clk_set_parent(const struct ti_sci_handle *handle, |
1207 | u32 dev_id, u8 clk_id, u8 parent_id) | 1217 | u32 dev_id, u32 clk_id, u32 parent_id) |
1208 | { | 1218 | { |
1209 | struct ti_sci_info *info; | 1219 | struct ti_sci_info *info; |
1210 | struct ti_sci_msg_req_set_clock_parent *req; | 1220 | struct ti_sci_msg_req_set_clock_parent *req; |
@@ -1231,8 +1241,18 @@ static int ti_sci_cmd_clk_set_parent(const struct ti_sci_handle *handle, | |||
1231 | } | 1241 | } |
1232 | req = (struct ti_sci_msg_req_set_clock_parent *)xfer->xfer_buf; | 1242 | req = (struct ti_sci_msg_req_set_clock_parent *)xfer->xfer_buf; |
1233 | req->dev_id = dev_id; | 1243 | req->dev_id = dev_id; |
1234 | req->clk_id = clk_id; | 1244 | if (clk_id < 255) { |
1235 | req->parent_id = parent_id; | 1245 | req->clk_id = clk_id; |
1246 | } else { | ||
1247 | req->clk_id = 255; | ||
1248 | req->clk_id_32 = clk_id; | ||
1249 | } | ||
1250 | if (parent_id < 255) { | ||
1251 | req->parent_id = parent_id; | ||
1252 | } else { | ||
1253 | req->parent_id = 255; | ||
1254 | req->parent_id_32 = parent_id; | ||
1255 | } | ||
1236 | 1256 | ||
1237 | ret = ti_sci_do_xfer(info, xfer); | 1257 | ret = ti_sci_do_xfer(info, xfer); |
1238 | if (ret) { | 1258 | if (ret) { |
@@ -1262,7 +1282,7 @@ fail: | |||
1262 | * Return: 0 if all went well, else returns appropriate error value. | 1282 | * Return: 0 if all went well, else returns appropriate error value. |
1263 | */ | 1283 | */ |
1264 | static int ti_sci_cmd_clk_get_parent(const struct ti_sci_handle *handle, | 1284 | static int ti_sci_cmd_clk_get_parent(const struct ti_sci_handle *handle, |
1265 | u32 dev_id, u8 clk_id, u8 *parent_id) | 1285 | u32 dev_id, u32 clk_id, u32 *parent_id) |
1266 | { | 1286 | { |
1267 | struct ti_sci_info *info; | 1287 | struct ti_sci_info *info; |
1268 | struct ti_sci_msg_req_get_clock_parent *req; | 1288 | struct ti_sci_msg_req_get_clock_parent *req; |
@@ -1289,7 +1309,12 @@ static int ti_sci_cmd_clk_get_parent(const struct ti_sci_handle *handle, | |||
1289 | } | 1309 | } |
1290 | req = (struct ti_sci_msg_req_get_clock_parent *)xfer->xfer_buf; | 1310 | req = (struct ti_sci_msg_req_get_clock_parent *)xfer->xfer_buf; |
1291 | req->dev_id = dev_id; | 1311 | req->dev_id = dev_id; |
1292 | req->clk_id = clk_id; | 1312 | if (clk_id < 255) { |
1313 | req->clk_id = clk_id; | ||
1314 | } else { | ||
1315 | req->clk_id = 255; | ||
1316 | req->clk_id_32 = clk_id; | ||
1317 | } | ||
1293 | 1318 | ||
1294 | ret = ti_sci_do_xfer(info, xfer); | 1319 | ret = ti_sci_do_xfer(info, xfer); |
1295 | if (ret) { | 1320 | if (ret) { |
@@ -1299,10 +1324,14 @@ static int ti_sci_cmd_clk_get_parent(const struct ti_sci_handle *handle, | |||
1299 | 1324 | ||
1300 | resp = (struct ti_sci_msg_resp_get_clock_parent *)xfer->xfer_buf; | 1325 | resp = (struct ti_sci_msg_resp_get_clock_parent *)xfer->xfer_buf; |
1301 | 1326 | ||
1302 | if (!ti_sci_is_response_ack(resp)) | 1327 | if (!ti_sci_is_response_ack(resp)) { |
1303 | ret = -ENODEV; | 1328 | ret = -ENODEV; |
1304 | else | 1329 | } else { |
1305 | *parent_id = resp->parent_id; | 1330 | if (resp->parent_id < 255) |
1331 | *parent_id = resp->parent_id; | ||
1332 | else | ||
1333 | *parent_id = resp->parent_id_32; | ||
1334 | } | ||
1306 | 1335 | ||
1307 | fail: | 1336 | fail: |
1308 | ti_sci_put_one_xfer(&info->minfo, xfer); | 1337 | ti_sci_put_one_xfer(&info->minfo, xfer); |
@@ -1322,8 +1351,8 @@ fail: | |||
1322 | * Return: 0 if all went well, else returns appropriate error value. | 1351 | * Return: 0 if all went well, else returns appropriate error value. |
1323 | */ | 1352 | */ |
1324 | static int ti_sci_cmd_clk_get_num_parents(const struct ti_sci_handle *handle, | 1353 | static int ti_sci_cmd_clk_get_num_parents(const struct ti_sci_handle *handle, |
1325 | u32 dev_id, u8 clk_id, | 1354 | u32 dev_id, u32 clk_id, |
1326 | u8 *num_parents) | 1355 | u32 *num_parents) |
1327 | { | 1356 | { |
1328 | struct ti_sci_info *info; | 1357 | struct ti_sci_info *info; |
1329 | struct ti_sci_msg_req_get_clock_num_parents *req; | 1358 | struct ti_sci_msg_req_get_clock_num_parents *req; |
@@ -1350,7 +1379,12 @@ static int ti_sci_cmd_clk_get_num_parents(const struct ti_sci_handle *handle, | |||
1350 | } | 1379 | } |
1351 | req = (struct ti_sci_msg_req_get_clock_num_parents *)xfer->xfer_buf; | 1380 | req = (struct ti_sci_msg_req_get_clock_num_parents *)xfer->xfer_buf; |
1352 | req->dev_id = dev_id; | 1381 | req->dev_id = dev_id; |
1353 | req->clk_id = clk_id; | 1382 | if (clk_id < 255) { |
1383 | req->clk_id = clk_id; | ||
1384 | } else { | ||
1385 | req->clk_id = 255; | ||
1386 | req->clk_id_32 = clk_id; | ||
1387 | } | ||
1354 | 1388 | ||
1355 | ret = ti_sci_do_xfer(info, xfer); | 1389 | ret = ti_sci_do_xfer(info, xfer); |
1356 | if (ret) { | 1390 | if (ret) { |
@@ -1360,10 +1394,14 @@ static int ti_sci_cmd_clk_get_num_parents(const struct ti_sci_handle *handle, | |||
1360 | 1394 | ||
1361 | resp = (struct ti_sci_msg_resp_get_clock_num_parents *)xfer->xfer_buf; | 1395 | resp = (struct ti_sci_msg_resp_get_clock_num_parents *)xfer->xfer_buf; |
1362 | 1396 | ||
1363 | if (!ti_sci_is_response_ack(resp)) | 1397 | if (!ti_sci_is_response_ack(resp)) { |
1364 | ret = -ENODEV; | 1398 | ret = -ENODEV; |
1365 | else | 1399 | } else { |
1366 | *num_parents = resp->num_parents; | 1400 | if (resp->num_parents < 255) |
1401 | *num_parents = resp->num_parents; | ||
1402 | else | ||
1403 | *num_parents = resp->num_parents_32; | ||
1404 | } | ||
1367 | 1405 | ||
1368 | fail: | 1406 | fail: |
1369 | ti_sci_put_one_xfer(&info->minfo, xfer); | 1407 | ti_sci_put_one_xfer(&info->minfo, xfer); |
@@ -1391,7 +1429,7 @@ fail: | |||
1391 | * Return: 0 if all went well, else returns appropriate error value. | 1429 | * Return: 0 if all went well, else returns appropriate error value. |
1392 | */ | 1430 | */ |
1393 | static int ti_sci_cmd_clk_get_match_freq(const struct ti_sci_handle *handle, | 1431 | static int ti_sci_cmd_clk_get_match_freq(const struct ti_sci_handle *handle, |
1394 | u32 dev_id, u8 clk_id, u64 min_freq, | 1432 | u32 dev_id, u32 clk_id, u64 min_freq, |
1395 | u64 target_freq, u64 max_freq, | 1433 | u64 target_freq, u64 max_freq, |
1396 | u64 *match_freq) | 1434 | u64 *match_freq) |
1397 | { | 1435 | { |
@@ -1420,7 +1458,12 @@ static int ti_sci_cmd_clk_get_match_freq(const struct ti_sci_handle *handle, | |||
1420 | } | 1458 | } |
1421 | req = (struct ti_sci_msg_req_query_clock_freq *)xfer->xfer_buf; | 1459 | req = (struct ti_sci_msg_req_query_clock_freq *)xfer->xfer_buf; |
1422 | req->dev_id = dev_id; | 1460 | req->dev_id = dev_id; |
1423 | req->clk_id = clk_id; | 1461 | if (clk_id < 255) { |
1462 | req->clk_id = clk_id; | ||
1463 | } else { | ||
1464 | req->clk_id = 255; | ||
1465 | req->clk_id_32 = clk_id; | ||
1466 | } | ||
1424 | req->min_freq_hz = min_freq; | 1467 | req->min_freq_hz = min_freq; |
1425 | req->target_freq_hz = target_freq; | 1468 | req->target_freq_hz = target_freq; |
1426 | req->max_freq_hz = max_freq; | 1469 | req->max_freq_hz = max_freq; |
@@ -1463,7 +1506,7 @@ fail: | |||
1463 | * Return: 0 if all went well, else returns appropriate error value. | 1506 | * Return: 0 if all went well, else returns appropriate error value. |
1464 | */ | 1507 | */ |
1465 | static int ti_sci_cmd_clk_set_freq(const struct ti_sci_handle *handle, | 1508 | static int ti_sci_cmd_clk_set_freq(const struct ti_sci_handle *handle, |
1466 | u32 dev_id, u8 clk_id, u64 min_freq, | 1509 | u32 dev_id, u32 clk_id, u64 min_freq, |
1467 | u64 target_freq, u64 max_freq) | 1510 | u64 target_freq, u64 max_freq) |
1468 | { | 1511 | { |
1469 | struct ti_sci_info *info; | 1512 | struct ti_sci_info *info; |
@@ -1491,7 +1534,12 @@ static int ti_sci_cmd_clk_set_freq(const struct ti_sci_handle *handle, | |||
1491 | } | 1534 | } |
1492 | req = (struct ti_sci_msg_req_set_clock_freq *)xfer->xfer_buf; | 1535 | req = (struct ti_sci_msg_req_set_clock_freq *)xfer->xfer_buf; |
1493 | req->dev_id = dev_id; | 1536 | req->dev_id = dev_id; |
1494 | req->clk_id = clk_id; | 1537 | if (clk_id < 255) { |
1538 | req->clk_id = clk_id; | ||
1539 | } else { | ||
1540 | req->clk_id = 255; | ||
1541 | req->clk_id_32 = clk_id; | ||
1542 | } | ||
1495 | req->min_freq_hz = min_freq; | 1543 | req->min_freq_hz = min_freq; |
1496 | req->target_freq_hz = target_freq; | 1544 | req->target_freq_hz = target_freq; |
1497 | req->max_freq_hz = max_freq; | 1545 | req->max_freq_hz = max_freq; |
@@ -1524,7 +1572,7 @@ fail: | |||
1524 | * Return: 0 if all went well, else returns appropriate error value. | 1572 | * Return: 0 if all went well, else returns appropriate error value. |
1525 | */ | 1573 | */ |
1526 | static int ti_sci_cmd_clk_get_freq(const struct ti_sci_handle *handle, | 1574 | static int ti_sci_cmd_clk_get_freq(const struct ti_sci_handle *handle, |
1527 | u32 dev_id, u8 clk_id, u64 *freq) | 1575 | u32 dev_id, u32 clk_id, u64 *freq) |
1528 | { | 1576 | { |
1529 | struct ti_sci_info *info; | 1577 | struct ti_sci_info *info; |
1530 | struct ti_sci_msg_req_get_clock_freq *req; | 1578 | struct ti_sci_msg_req_get_clock_freq *req; |
@@ -1551,7 +1599,12 @@ static int ti_sci_cmd_clk_get_freq(const struct ti_sci_handle *handle, | |||
1551 | } | 1599 | } |
1552 | req = (struct ti_sci_msg_req_get_clock_freq *)xfer->xfer_buf; | 1600 | req = (struct ti_sci_msg_req_get_clock_freq *)xfer->xfer_buf; |
1553 | req->dev_id = dev_id; | 1601 | req->dev_id = dev_id; |
1554 | req->clk_id = clk_id; | 1602 | if (clk_id < 255) { |
1603 | req->clk_id = clk_id; | ||
1604 | } else { | ||
1605 | req->clk_id = 255; | ||
1606 | req->clk_id_32 = clk_id; | ||
1607 | } | ||
1555 | 1608 | ||
1556 | ret = ti_sci_do_xfer(info, xfer); | 1609 | ret = ti_sci_do_xfer(info, xfer); |
1557 | if (ret) { | 1610 | if (ret) { |
@@ -2349,12 +2402,13 @@ devm_ti_sci_get_of_resource(const struct ti_sci_handle *handle, | |||
2349 | if (!res) | 2402 | if (!res) |
2350 | return ERR_PTR(-ENOMEM); | 2403 | return ERR_PTR(-ENOMEM); |
2351 | 2404 | ||
2352 | res->sets = of_property_count_elems_of_size(dev_of_node(dev), of_prop, | 2405 | ret = of_property_count_elems_of_size(dev_of_node(dev), of_prop, |
2353 | sizeof(u32)); | 2406 | sizeof(u32)); |
2354 | if (res->sets < 0) { | 2407 | if (ret < 0) { |
2355 | dev_err(dev, "%s resource type ids not available\n", of_prop); | 2408 | dev_err(dev, "%s resource type ids not available\n", of_prop); |
2356 | return ERR_PTR(res->sets); | 2409 | return ERR_PTR(ret); |
2357 | } | 2410 | } |
2411 | res->sets = ret; | ||
2358 | 2412 | ||
2359 | res->desc = devm_kcalloc(dev, res->sets, sizeof(*res->desc), | 2413 | res->desc = devm_kcalloc(dev, res->sets, sizeof(*res->desc), |
2360 | GFP_KERNEL); | 2414 | GFP_KERNEL); |
diff --git a/drivers/firmware/ti_sci.h b/drivers/firmware/ti_sci.h index adbeeefaca92..414e0ced5409 100644 --- a/drivers/firmware/ti_sci.h +++ b/drivers/firmware/ti_sci.h | |||
@@ -202,7 +202,8 @@ struct ti_sci_msg_req_set_device_resets { | |||
202 | * @dev_id: Device identifier this request is for | 202 | * @dev_id: Device identifier this request is for |
203 | * @clk_id: Clock identifier for the device for this request. | 203 | * @clk_id: Clock identifier for the device for this request. |
204 | * Each device has it's own set of clock inputs. This indexes | 204 | * Each device has it's own set of clock inputs. This indexes |
205 | * which clock input to modify. | 205 | * which clock input to modify. Set to 255 if clock ID is |
206 | * greater than or equal to 255. | ||
206 | * @request_state: Request the state for the clock to be set to. | 207 | * @request_state: Request the state for the clock to be set to. |
207 | * MSG_CLOCK_SW_STATE_UNREQ: The IP does not require this clock, | 208 | * MSG_CLOCK_SW_STATE_UNREQ: The IP does not require this clock, |
208 | * it can be disabled, regardless of the state of the device | 209 | * it can be disabled, regardless of the state of the device |
@@ -213,6 +214,9 @@ struct ti_sci_msg_req_set_device_resets { | |||
213 | * being required by the device.(default) | 214 | * being required by the device.(default) |
214 | * MSG_CLOCK_SW_STATE_REQ: Configure the clock to be enabled, | 215 | * MSG_CLOCK_SW_STATE_REQ: Configure the clock to be enabled, |
215 | * regardless of the state of the device. | 216 | * regardless of the state of the device. |
217 | * @clk_id_32: Clock identifier for the device for this request. | ||
218 | * Only to be used if the clock ID is greater than or equal to | ||
219 | * 255. | ||
216 | * | 220 | * |
217 | * Normally, all required clocks are managed by TISCI entity, this is used | 221 | * Normally, all required clocks are managed by TISCI entity, this is used |
218 | * only for specific control *IF* required. Auto managed state is | 222 | * only for specific control *IF* required. Auto managed state is |
@@ -234,6 +238,7 @@ struct ti_sci_msg_req_set_clock_state { | |||
234 | #define MSG_CLOCK_SW_STATE_AUTO 1 | 238 | #define MSG_CLOCK_SW_STATE_AUTO 1 |
235 | #define MSG_CLOCK_SW_STATE_REQ 2 | 239 | #define MSG_CLOCK_SW_STATE_REQ 2 |
236 | u8 request_state; | 240 | u8 request_state; |
241 | u32 clk_id_32; | ||
237 | } __packed; | 242 | } __packed; |
238 | 243 | ||
239 | /** | 244 | /** |
@@ -242,7 +247,11 @@ struct ti_sci_msg_req_set_clock_state { | |||
242 | * @dev_id: Device identifier this request is for | 247 | * @dev_id: Device identifier this request is for |
243 | * @clk_id: Clock identifier for the device for this request. | 248 | * @clk_id: Clock identifier for the device for this request. |
244 | * Each device has it's own set of clock inputs. This indexes | 249 | * Each device has it's own set of clock inputs. This indexes |
245 | * which clock input to get state of. | 250 | * which clock input to get state of. Set to 255 if the clock |
251 | * ID is greater than or equal to 255. | ||
252 | * @clk_id_32: Clock identifier for the device for the request. | ||
253 | * Only to be used if the clock ID is greater than or equal to | ||
254 | * 255. | ||
246 | * | 255 | * |
247 | * Request type is TI_SCI_MSG_GET_CLOCK_STATE, response is state | 256 | * Request type is TI_SCI_MSG_GET_CLOCK_STATE, response is state |
248 | * of the clock | 257 | * of the clock |
@@ -251,6 +260,7 @@ struct ti_sci_msg_req_get_clock_state { | |||
251 | struct ti_sci_msg_hdr hdr; | 260 | struct ti_sci_msg_hdr hdr; |
252 | u32 dev_id; | 261 | u32 dev_id; |
253 | u8 clk_id; | 262 | u8 clk_id; |
263 | u32 clk_id_32; | ||
254 | } __packed; | 264 | } __packed; |
255 | 265 | ||
256 | /** | 266 | /** |
@@ -278,9 +288,13 @@ struct ti_sci_msg_resp_get_clock_state { | |||
278 | * @dev_id: Device identifier this request is for | 288 | * @dev_id: Device identifier this request is for |
279 | * @clk_id: Clock identifier for the device for this request. | 289 | * @clk_id: Clock identifier for the device for this request. |
280 | * Each device has it's own set of clock inputs. This indexes | 290 | * Each device has it's own set of clock inputs. This indexes |
281 | * which clock input to modify. | 291 | * which clock input to modify. Set to 255 if clock ID is |
292 | * greater than or equal to 255. | ||
282 | * @parent_id: The new clock parent is selectable by an index via this | 293 | * @parent_id: The new clock parent is selectable by an index via this |
283 | * parameter. | 294 | * parameter. Set to 255 if clock ID is greater than or |
295 | * equal to 255. | ||
296 | * @clk_id_32: Clock identifier if @clk_id field is 255. | ||
297 | * @parent_id_32: Parent identifier if @parent_id is 255. | ||
284 | * | 298 | * |
285 | * Request type is TI_SCI_MSG_SET_CLOCK_PARENT, response is generic | 299 | * Request type is TI_SCI_MSG_SET_CLOCK_PARENT, response is generic |
286 | * ACK / NACK message. | 300 | * ACK / NACK message. |
@@ -290,6 +304,8 @@ struct ti_sci_msg_req_set_clock_parent { | |||
290 | u32 dev_id; | 304 | u32 dev_id; |
291 | u8 clk_id; | 305 | u8 clk_id; |
292 | u8 parent_id; | 306 | u8 parent_id; |
307 | u32 clk_id_32; | ||
308 | u32 parent_id_32; | ||
293 | } __packed; | 309 | } __packed; |
294 | 310 | ||
295 | /** | 311 | /** |
@@ -298,7 +314,10 @@ struct ti_sci_msg_req_set_clock_parent { | |||
298 | * @dev_id: Device identifier this request is for | 314 | * @dev_id: Device identifier this request is for |
299 | * @clk_id: Clock identifier for the device for this request. | 315 | * @clk_id: Clock identifier for the device for this request. |
300 | * Each device has it's own set of clock inputs. This indexes | 316 | * Each device has it's own set of clock inputs. This indexes |
301 | * which clock input to get the parent for. | 317 | * which clock input to get the parent for. If this field |
318 | * contains 255, the actual clock identifier is stored in | ||
319 | * @clk_id_32. | ||
320 | * @clk_id_32: Clock identifier if the @clk_id field contains 255. | ||
302 | * | 321 | * |
303 | * Request type is TI_SCI_MSG_GET_CLOCK_PARENT, response is parent information | 322 | * Request type is TI_SCI_MSG_GET_CLOCK_PARENT, response is parent information |
304 | */ | 323 | */ |
@@ -306,25 +325,32 @@ struct ti_sci_msg_req_get_clock_parent { | |||
306 | struct ti_sci_msg_hdr hdr; | 325 | struct ti_sci_msg_hdr hdr; |
307 | u32 dev_id; | 326 | u32 dev_id; |
308 | u8 clk_id; | 327 | u8 clk_id; |
328 | u32 clk_id_32; | ||
309 | } __packed; | 329 | } __packed; |
310 | 330 | ||
311 | /** | 331 | /** |
312 | * struct ti_sci_msg_resp_get_clock_parent - Response with clock parent | 332 | * struct ti_sci_msg_resp_get_clock_parent - Response with clock parent |
313 | * @hdr: Generic Header | 333 | * @hdr: Generic Header |
314 | * @parent_id: The current clock parent | 334 | * @parent_id: The current clock parent. If set to 255, the current parent |
335 | * ID can be found from the @parent_id_32 field. | ||
336 | * @parent_id_32: Current clock parent if @parent_id field is set to | ||
337 | * 255. | ||
315 | * | 338 | * |
316 | * Response to TI_SCI_MSG_GET_CLOCK_PARENT. | 339 | * Response to TI_SCI_MSG_GET_CLOCK_PARENT. |
317 | */ | 340 | */ |
318 | struct ti_sci_msg_resp_get_clock_parent { | 341 | struct ti_sci_msg_resp_get_clock_parent { |
319 | struct ti_sci_msg_hdr hdr; | 342 | struct ti_sci_msg_hdr hdr; |
320 | u8 parent_id; | 343 | u8 parent_id; |
344 | u32 parent_id_32; | ||
321 | } __packed; | 345 | } __packed; |
322 | 346 | ||
323 | /** | 347 | /** |
324 | * struct ti_sci_msg_req_get_clock_num_parents - Request to get clock parents | 348 | * struct ti_sci_msg_req_get_clock_num_parents - Request to get clock parents |
325 | * @hdr: Generic header | 349 | * @hdr: Generic header |
326 | * @dev_id: Device identifier this request is for | 350 | * @dev_id: Device identifier this request is for |
327 | * @clk_id: Clock identifier for the device for this request. | 351 | * @clk_id: Clock identifier for the device for this request. Set to |
352 | * 255 if clock ID is greater than or equal to 255. | ||
353 | * @clk_id_32: Clock identifier if the @clk_id field contains 255. | ||
328 | * | 354 | * |
329 | * This request provides information about how many clock parent options | 355 | * This request provides information about how many clock parent options |
330 | * are available for a given clock to a device. This is typically used | 356 | * are available for a given clock to a device. This is typically used |
@@ -337,18 +363,24 @@ struct ti_sci_msg_req_get_clock_num_parents { | |||
337 | struct ti_sci_msg_hdr hdr; | 363 | struct ti_sci_msg_hdr hdr; |
338 | u32 dev_id; | 364 | u32 dev_id; |
339 | u8 clk_id; | 365 | u8 clk_id; |
366 | u32 clk_id_32; | ||
340 | } __packed; | 367 | } __packed; |
341 | 368 | ||
342 | /** | 369 | /** |
343 | * struct ti_sci_msg_resp_get_clock_num_parents - Response for get clk parents | 370 | * struct ti_sci_msg_resp_get_clock_num_parents - Response for get clk parents |
344 | * @hdr: Generic header | 371 | * @hdr: Generic header |
345 | * @num_parents: Number of clock parents | 372 | * @num_parents: Number of clock parents. If set to 255, the actual |
373 | * number of parents is stored into @num_parents_32 | ||
374 | * field instead. | ||
375 | * @num_parents_32: Number of clock parents if @num_parents field is | ||
376 | * set to 255. | ||
346 | * | 377 | * |
347 | * Response to TI_SCI_MSG_GET_NUM_CLOCK_PARENTS | 378 | * Response to TI_SCI_MSG_GET_NUM_CLOCK_PARENTS |
348 | */ | 379 | */ |
349 | struct ti_sci_msg_resp_get_clock_num_parents { | 380 | struct ti_sci_msg_resp_get_clock_num_parents { |
350 | struct ti_sci_msg_hdr hdr; | 381 | struct ti_sci_msg_hdr hdr; |
351 | u8 num_parents; | 382 | u8 num_parents; |
383 | u32 num_parents_32; | ||
352 | } __packed; | 384 | } __packed; |
353 | 385 | ||
354 | /** | 386 | /** |
@@ -363,7 +395,9 @@ struct ti_sci_msg_resp_get_clock_num_parents { | |||
363 | * @max_freq_hz: The maximum allowable frequency in Hz. This is the maximum | 395 | * @max_freq_hz: The maximum allowable frequency in Hz. This is the maximum |
364 | * allowable programmed frequency and does not account for clock | 396 | * allowable programmed frequency and does not account for clock |
365 | * tolerances and jitter. | 397 | * tolerances and jitter. |
366 | * @clk_id: Clock identifier for the device for this request. | 398 | * @clk_id: Clock identifier for the device for this request. Set to |
399 | * 255 if clock identifier is greater than or equal to 255. | ||
400 | * @clk_id_32: Clock identifier if @clk_id is set to 255. | ||
367 | * | 401 | * |
368 | * NOTE: Normally clock frequency management is automatically done by TISCI | 402 | * NOTE: Normally clock frequency management is automatically done by TISCI |
369 | * entity. In case of specific requests, TISCI evaluates capability to achieve | 403 | * entity. In case of specific requests, TISCI evaluates capability to achieve |
@@ -380,6 +414,7 @@ struct ti_sci_msg_req_query_clock_freq { | |||
380 | u64 target_freq_hz; | 414 | u64 target_freq_hz; |
381 | u64 max_freq_hz; | 415 | u64 max_freq_hz; |
382 | u8 clk_id; | 416 | u8 clk_id; |
417 | u32 clk_id_32; | ||
383 | } __packed; | 418 | } __packed; |
384 | 419 | ||
385 | /** | 420 | /** |
@@ -407,7 +442,9 @@ struct ti_sci_msg_resp_query_clock_freq { | |||
407 | * @max_freq_hz: The maximum allowable frequency in Hz. This is the maximum | 442 | * @max_freq_hz: The maximum allowable frequency in Hz. This is the maximum |
408 | * allowable programmed frequency and does not account for clock | 443 | * allowable programmed frequency and does not account for clock |
409 | * tolerances and jitter. | 444 | * tolerances and jitter. |
410 | * @clk_id: Clock identifier for the device for this request. | 445 | * @clk_id: Clock identifier for the device for this request. Set to |
446 | * 255 if clock ID is greater than or equal to 255. | ||
447 | * @clk_id_32: Clock identifier if @clk_id field is set to 255. | ||
411 | * | 448 | * |
412 | * NOTE: Normally clock frequency management is automatically done by TISCI | 449 | * NOTE: Normally clock frequency management is automatically done by TISCI |
413 | * entity. In case of specific requests, TISCI evaluates capability to achieve | 450 | * entity. In case of specific requests, TISCI evaluates capability to achieve |
@@ -436,13 +473,16 @@ struct ti_sci_msg_req_set_clock_freq { | |||
436 | u64 target_freq_hz; | 473 | u64 target_freq_hz; |
437 | u64 max_freq_hz; | 474 | u64 max_freq_hz; |
438 | u8 clk_id; | 475 | u8 clk_id; |
476 | u32 clk_id_32; | ||
439 | } __packed; | 477 | } __packed; |
440 | 478 | ||
441 | /** | 479 | /** |
442 | * struct ti_sci_msg_req_get_clock_freq - Request to get the clock frequency | 480 | * struct ti_sci_msg_req_get_clock_freq - Request to get the clock frequency |
443 | * @hdr: Generic Header | 481 | * @hdr: Generic Header |
444 | * @dev_id: Device identifier this request is for | 482 | * @dev_id: Device identifier this request is for |
445 | * @clk_id: Clock identifier for the device for this request. | 483 | * @clk_id: Clock identifier for the device for this request. Set to |
484 | * 255 if clock ID is greater than or equal to 255. | ||
485 | * @clk_id_32: Clock identifier if @clk_id field is set to 255. | ||
446 | * | 486 | * |
447 | * NOTE: Normally clock frequency management is automatically done by TISCI | 487 | * NOTE: Normally clock frequency management is automatically done by TISCI |
448 | * entity. In some cases, clock frequencies are configured by host. | 488 | * entity. In some cases, clock frequencies are configured by host. |
@@ -454,6 +494,7 @@ struct ti_sci_msg_req_get_clock_freq { | |||
454 | struct ti_sci_msg_hdr hdr; | 494 | struct ti_sci_msg_hdr hdr; |
455 | u32 dev_id; | 495 | u32 dev_id; |
456 | u8 clk_id; | 496 | u8 clk_id; |
497 | u32 clk_id_32; | ||
457 | } __packed; | 498 | } __packed; |
458 | 499 | ||
459 | /** | 500 | /** |
diff --git a/include/dt-bindings/clock/exynos4.h b/include/dt-bindings/clock/exynos4.h index a0439ce8e8d3..88ec3968b90a 100644 --- a/include/dt-bindings/clock/exynos4.h +++ b/include/dt-bindings/clock/exynos4.h | |||
@@ -187,6 +187,7 @@ | |||
187 | #define CLK_MIPI_HSI 349 /* Exynos4210 only */ | 187 | #define CLK_MIPI_HSI 349 /* Exynos4210 only */ |
188 | #define CLK_PIXELASYNCM0 351 | 188 | #define CLK_PIXELASYNCM0 351 |
189 | #define CLK_PIXELASYNCM1 352 | 189 | #define CLK_PIXELASYNCM1 352 |
190 | #define CLK_ASYNC_G3D 353 /* Exynos4x12 only */ | ||
190 | #define CLK_PWM_ISP_SCLK 379 /* Exynos4x12 only */ | 191 | #define CLK_PWM_ISP_SCLK 379 /* Exynos4x12 only */ |
191 | #define CLK_SPI0_ISP_SCLK 380 /* Exynos4x12 only */ | 192 | #define CLK_SPI0_ISP_SCLK 380 /* Exynos4x12 only */ |
192 | #define CLK_SPI1_ISP_SCLK 381 /* Exynos4x12 only */ | 193 | #define CLK_SPI1_ISP_SCLK 381 /* Exynos4x12 only */ |
diff --git a/include/dt-bindings/clock/exynos5420.h b/include/dt-bindings/clock/exynos5420.h index 355f469943f1..02d5ac469a3d 100644 --- a/include/dt-bindings/clock/exynos5420.h +++ b/include/dt-bindings/clock/exynos5420.h | |||
@@ -60,6 +60,7 @@ | |||
60 | #define CLK_MAU_EPLL 159 | 60 | #define CLK_MAU_EPLL 159 |
61 | #define CLK_SCLK_HSIC_12M 160 | 61 | #define CLK_SCLK_HSIC_12M 160 |
62 | #define CLK_SCLK_MPHY_IXTAL24 161 | 62 | #define CLK_SCLK_MPHY_IXTAL24 161 |
63 | #define CLK_SCLK_BPLL 162 | ||
63 | 64 | ||
64 | /* gate clocks */ | 65 | /* gate clocks */ |
65 | #define CLK_UART0 257 | 66 | #define CLK_UART0 257 |
@@ -195,6 +196,16 @@ | |||
195 | #define CLK_ACLK432_CAM 518 | 196 | #define CLK_ACLK432_CAM 518 |
196 | #define CLK_ACLK_FL1550_CAM 519 | 197 | #define CLK_ACLK_FL1550_CAM 519 |
197 | #define CLK_ACLK550_CAM 520 | 198 | #define CLK_ACLK550_CAM 520 |
199 | #define CLK_CLKM_PHY0 521 | ||
200 | #define CLK_CLKM_PHY1 522 | ||
201 | #define CLK_ACLK_PPMU_DREX0_0 523 | ||
202 | #define CLK_ACLK_PPMU_DREX0_1 524 | ||
203 | #define CLK_ACLK_PPMU_DREX1_0 525 | ||
204 | #define CLK_ACLK_PPMU_DREX1_1 526 | ||
205 | #define CLK_PCLK_PPMU_DREX0_0 527 | ||
206 | #define CLK_PCLK_PPMU_DREX0_1 528 | ||
207 | #define CLK_PCLK_PPMU_DREX1_0 529 | ||
208 | #define CLK_PCLK_PPMU_DREX1_1 530 | ||
198 | 209 | ||
199 | /* mux clocks */ | 210 | /* mux clocks */ |
200 | #define CLK_MOUT_HDMI 640 | 211 | #define CLK_MOUT_HDMI 640 |
@@ -217,6 +228,8 @@ | |||
217 | #define CLK_MOUT_EPLL 657 | 228 | #define CLK_MOUT_EPLL 657 |
218 | #define CLK_MOUT_MAU_EPLL 658 | 229 | #define CLK_MOUT_MAU_EPLL 658 |
219 | #define CLK_MOUT_USER_MAU_EPLL 659 | 230 | #define CLK_MOUT_USER_MAU_EPLL 659 |
231 | #define CLK_MOUT_SCLK_SPLL 660 | ||
232 | #define CLK_MOUT_MX_MSPLL_CCORE_PHY 661 | ||
220 | 233 | ||
221 | /* divider clocks */ | 234 | /* divider clocks */ |
222 | #define CLK_DOUT_PIXEL 768 | 235 | #define CLK_DOUT_PIXEL 768 |
@@ -248,8 +261,11 @@ | |||
248 | #define CLK_DOUT_CCLK_DREX0 794 | 261 | #define CLK_DOUT_CCLK_DREX0 794 |
249 | #define CLK_DOUT_CLK2X_PHY0 795 | 262 | #define CLK_DOUT_CLK2X_PHY0 795 |
250 | #define CLK_DOUT_PCLK_CORE_MEM 796 | 263 | #define CLK_DOUT_PCLK_CORE_MEM 796 |
264 | #define CLK_FF_DOUT_SPLL2 797 | ||
265 | #define CLK_DOUT_PCLK_DREX0 798 | ||
266 | #define CLK_DOUT_PCLK_DREX1 799 | ||
251 | 267 | ||
252 | /* must be greater than maximal clock id */ | 268 | /* must be greater than maximal clock id */ |
253 | #define CLK_NR_CLKS 797 | 269 | #define CLK_NR_CLKS 800 |
254 | 270 | ||
255 | #endif /* _DT_BINDINGS_CLOCK_EXYNOS_5420_H */ | 271 | #endif /* _DT_BINDINGS_CLOCK_EXYNOS_5420_H */ |
diff --git a/include/dt-bindings/clock/g12a-clkc.h b/include/dt-bindings/clock/g12a-clkc.h index e10470ed7c4f..b6b127e45634 100644 --- a/include/dt-bindings/clock/g12a-clkc.h +++ b/include/dt-bindings/clock/g12a-clkc.h | |||
@@ -136,5 +136,6 @@ | |||
136 | #define CLKID_VDEC_1 204 | 136 | #define CLKID_VDEC_1 204 |
137 | #define CLKID_VDEC_HEVC 207 | 137 | #define CLKID_VDEC_HEVC 207 |
138 | #define CLKID_VDEC_HEVCF 210 | 138 | #define CLKID_VDEC_HEVCF 210 |
139 | #define CLKID_TS 212 | ||
139 | 140 | ||
140 | #endif /* __G12A_CLKC_H */ | 141 | #endif /* __G12A_CLKC_H */ |
diff --git a/include/dt-bindings/clock/imx8mm-clock.h b/include/dt-bindings/clock/imx8mm-clock.h index 1b4353e7b486..07e6c686f3ef 100644 --- a/include/dt-bindings/clock/imx8mm-clock.h +++ b/include/dt-bindings/clock/imx8mm-clock.h | |||
@@ -239,6 +239,15 @@ | |||
239 | 239 | ||
240 | #define IMX8MM_CLK_NAND_USDHC_BUS_RAWNAND_CLK 222 | 240 | #define IMX8MM_CLK_NAND_USDHC_BUS_RAWNAND_CLK 222 |
241 | 241 | ||
242 | #define IMX8MM_CLK_END 223 | 242 | #define IMX8MM_CLK_GPIO1_ROOT 223 |
243 | #define IMX8MM_CLK_GPIO2_ROOT 224 | ||
244 | #define IMX8MM_CLK_GPIO3_ROOT 225 | ||
245 | #define IMX8MM_CLK_GPIO4_ROOT 226 | ||
246 | #define IMX8MM_CLK_GPIO5_ROOT 227 | ||
247 | |||
248 | #define IMX8MM_CLK_SNVS_ROOT 228 | ||
249 | #define IMX8MM_CLK_GIC 229 | ||
250 | |||
251 | #define IMX8MM_CLK_END 230 | ||
243 | 252 | ||
244 | #endif | 253 | #endif |
diff --git a/include/dt-bindings/clock/imx8mq-clock.h b/include/dt-bindings/clock/imx8mq-clock.h index 6677e920dc2d..65463673d25e 100644 --- a/include/dt-bindings/clock/imx8mq-clock.h +++ b/include/dt-bindings/clock/imx8mq-clock.h | |||
@@ -400,5 +400,8 @@ | |||
400 | #define IMX8MQ_CLK_GPIO4_ROOT 262 | 400 | #define IMX8MQ_CLK_GPIO4_ROOT 262 |
401 | #define IMX8MQ_CLK_GPIO5_ROOT 263 | 401 | #define IMX8MQ_CLK_GPIO5_ROOT 263 |
402 | 402 | ||
403 | #define IMX8MQ_CLK_END 264 | 403 | #define IMX8MQ_CLK_SNVS_ROOT 264 |
404 | #define IMX8MQ_CLK_GIC 265 | ||
405 | |||
406 | #define IMX8MQ_CLK_END 266 | ||
404 | #endif /* __DT_BINDINGS_CLOCK_IMX8MQ_H */ | 407 | #endif /* __DT_BINDINGS_CLOCK_IMX8MQ_H */ |
diff --git a/include/dt-bindings/clock/meson8b-clkc.h b/include/dt-bindings/clock/meson8b-clkc.h index 47556539f0ee..68862aaf977e 100644 --- a/include/dt-bindings/clock/meson8b-clkc.h +++ b/include/dt-bindings/clock/meson8b-clkc.h | |||
@@ -112,5 +112,8 @@ | |||
112 | #define CLKID_VDEC_HCODEC 199 | 112 | #define CLKID_VDEC_HCODEC 199 |
113 | #define CLKID_VDEC_2 202 | 113 | #define CLKID_VDEC_2 202 |
114 | #define CLKID_VDEC_HEVC 206 | 114 | #define CLKID_VDEC_HEVC 206 |
115 | #define CLKID_CTS_AMCLK 209 | ||
116 | #define CLKID_CTS_MCLK_I958 212 | ||
117 | #define CLKID_CTS_I958 213 | ||
115 | 118 | ||
116 | #endif /* __MESON8B_CLKC_H */ | 119 | #endif /* __MESON8B_CLKC_H */ |
diff --git a/include/dt-bindings/clock/mt8516-clk.h b/include/dt-bindings/clock/mt8516-clk.h index 9cfca53cd78d..816447b98edd 100644 --- a/include/dt-bindings/clock/mt8516-clk.h +++ b/include/dt-bindings/clock/mt8516-clk.h | |||
@@ -208,4 +208,21 @@ | |||
208 | #define CLK_TOP_MSDC2_INFRA 176 | 208 | #define CLK_TOP_MSDC2_INFRA 176 |
209 | #define CLK_TOP_NR_CLK 177 | 209 | #define CLK_TOP_NR_CLK 177 |
210 | 210 | ||
211 | /* AUDSYS */ | ||
212 | |||
213 | #define CLK_AUD_AFE 0 | ||
214 | #define CLK_AUD_I2S 1 | ||
215 | #define CLK_AUD_22M 2 | ||
216 | #define CLK_AUD_24M 3 | ||
217 | #define CLK_AUD_INTDIR 4 | ||
218 | #define CLK_AUD_APLL2_TUNER 5 | ||
219 | #define CLK_AUD_APLL_TUNER 6 | ||
220 | #define CLK_AUD_HDMI 7 | ||
221 | #define CLK_AUD_SPDF 8 | ||
222 | #define CLK_AUD_ADC 9 | ||
223 | #define CLK_AUD_DAC 10 | ||
224 | #define CLK_AUD_DAC_PREDIS 11 | ||
225 | #define CLK_AUD_TML 12 | ||
226 | #define CLK_AUD_NR_CLK 13 | ||
227 | |||
211 | #endif /* _DT_BINDINGS_CLK_MT8516_H */ | 228 | #endif /* _DT_BINDINGS_CLK_MT8516_H */ |
diff --git a/include/dt-bindings/clock/qcom,gcc-qcs404.h b/include/dt-bindings/clock/qcom,gcc-qcs404.h index 454b3f43f538..2cd62c98561f 100644 --- a/include/dt-bindings/clock/qcom,gcc-qcs404.h +++ b/include/dt-bindings/clock/qcom,gcc-qcs404.h | |||
@@ -166,5 +166,12 @@ | |||
166 | #define GCC_PCIEPHY_0_PHY_BCR 12 | 166 | #define GCC_PCIEPHY_0_PHY_BCR 12 |
167 | #define GCC_EMAC_BCR 13 | 167 | #define GCC_EMAC_BCR 13 |
168 | #define GCC_CDSP_RESTART 14 | 168 | #define GCC_CDSP_RESTART 14 |
169 | #define GCC_PCIE_0_AXI_MASTER_STICKY_ARES 15 | ||
170 | #define GCC_PCIE_0_AHB_ARES 16 | ||
171 | #define GCC_PCIE_0_AXI_SLAVE_ARES 17 | ||
172 | #define GCC_PCIE_0_AXI_MASTER_ARES 18 | ||
173 | #define GCC_PCIE_0_CORE_STICKY_ARES 19 | ||
174 | #define GCC_PCIE_0_SLEEP_ARES 20 | ||
175 | #define GCC_PCIE_0_PIPE_ARES 21 | ||
169 | 176 | ||
170 | #endif | 177 | #endif |
diff --git a/include/dt-bindings/clock/qcom,gpucc-msm8998.h b/include/dt-bindings/clock/qcom,gpucc-msm8998.h new file mode 100644 index 000000000000..2623570ee974 --- /dev/null +++ b/include/dt-bindings/clock/qcom,gpucc-msm8998.h | |||
@@ -0,0 +1,29 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | /* | ||
3 | * Copyright (c) 2019, Jeffrey Hugo | ||
4 | */ | ||
5 | |||
6 | #ifndef _DT_BINDINGS_CLK_MSM_GPUCC_8998_H | ||
7 | #define _DT_BINDINGS_CLK_MSM_GPUCC_8998_H | ||
8 | |||
9 | #define GPUPLL0 0 | ||
10 | #define GPUPLL0_OUT_EVEN 1 | ||
11 | #define RBCPR_CLK_SRC 2 | ||
12 | #define GFX3D_CLK_SRC 3 | ||
13 | #define RBBMTIMER_CLK_SRC 4 | ||
14 | #define GFX3D_ISENSE_CLK_SRC 5 | ||
15 | #define RBCPR_CLK 6 | ||
16 | #define GFX3D_CLK 7 | ||
17 | #define RBBMTIMER_CLK 8 | ||
18 | #define GFX3D_ISENSE_CLK 9 | ||
19 | #define GPUCC_CXO_CLK 10 | ||
20 | |||
21 | #define GPU_CX_BCR 0 | ||
22 | #define RBCPR_BCR 1 | ||
23 | #define GPU_GX_BCR 2 | ||
24 | #define GPU_ISENSE_BCR 3 | ||
25 | |||
26 | #define GPU_CX_GDSC 1 | ||
27 | #define GPU_GX_GDSC 2 | ||
28 | |||
29 | #endif | ||
diff --git a/include/dt-bindings/clock/rk3228-cru.h b/include/dt-bindings/clock/rk3228-cru.h index 3b245e3df8da..de550ea56eeb 100644 --- a/include/dt-bindings/clock/rk3228-cru.h +++ b/include/dt-bindings/clock/rk3228-cru.h | |||
@@ -64,6 +64,7 @@ | |||
64 | #define SCLK_WIFI 141 | 64 | #define SCLK_WIFI 141 |
65 | #define SCLK_OTGPHY0 142 | 65 | #define SCLK_OTGPHY0 142 |
66 | #define SCLK_OTGPHY1 143 | 66 | #define SCLK_OTGPHY1 143 |
67 | #define SCLK_HDMI_PHY 144 | ||
67 | 68 | ||
68 | /* dclk gates */ | 69 | /* dclk gates */ |
69 | #define DCLK_VOP 190 | 70 | #define DCLK_VOP 190 |
diff --git a/include/dt-bindings/clock/rk3328-cru.h b/include/dt-bindings/clock/rk3328-cru.h index afb811340382..555b4ff660ae 100644 --- a/include/dt-bindings/clock/rk3328-cru.h +++ b/include/dt-bindings/clock/rk3328-cru.h | |||
@@ -164,6 +164,7 @@ | |||
164 | #define PCLK_DCF 233 | 164 | #define PCLK_DCF 233 |
165 | #define PCLK_SARADC 234 | 165 | #define PCLK_SARADC 234 |
166 | #define PCLK_ACODECPHY 235 | 166 | #define PCLK_ACODECPHY 235 |
167 | #define PCLK_WDT 236 | ||
167 | 168 | ||
168 | /* hclk gates */ | 169 | /* hclk gates */ |
169 | #define HCLK_PERI 308 | 170 | #define HCLK_PERI 308 |
diff --git a/include/dt-bindings/clock/stratix10-clock.h b/include/dt-bindings/clock/stratix10-clock.h index 0ac1c90a18bf..08b98e20b7cc 100644 --- a/include/dt-bindings/clock/stratix10-clock.h +++ b/include/dt-bindings/clock/stratix10-clock.h | |||
@@ -79,6 +79,8 @@ | |||
79 | #define STRATIX10_USB_CLK 59 | 79 | #define STRATIX10_USB_CLK 59 |
80 | #define STRATIX10_SPI_M_CLK 60 | 80 | #define STRATIX10_SPI_M_CLK 60 |
81 | #define STRATIX10_NAND_CLK 61 | 81 | #define STRATIX10_NAND_CLK 61 |
82 | #define STRATIX10_NUM_CLKS 62 | 82 | #define STRATIX10_NAND_X_CLK 62 |
83 | #define STRATIX10_NAND_ECC_CLK 63 | ||
84 | #define STRATIX10_NUM_CLKS 64 | ||
83 | 85 | ||
84 | #endif /* __STRATIX10_CLOCK_H */ | 86 | #endif /* __STRATIX10_CLOCK_H */ |
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index bb6118f79784..2ae7604783dd 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h | |||
@@ -9,8 +9,6 @@ | |||
9 | #include <linux/of.h> | 9 | #include <linux/of.h> |
10 | #include <linux/of_clk.h> | 10 | #include <linux/of_clk.h> |
11 | 11 | ||
12 | #ifdef CONFIG_COMMON_CLK | ||
13 | |||
14 | /* | 12 | /* |
15 | * flags used across common struct clk. these flags should only affect the | 13 | * flags used across common struct clk. these flags should only affect the |
16 | * top-level framework. custom flags for dealing with hardware specifics | 14 | * top-level framework. custom flags for dealing with hardware specifics |
@@ -807,7 +805,14 @@ void devm_clk_hw_unregister(struct device *dev, struct clk_hw *hw); | |||
807 | /* helper functions */ | 805 | /* helper functions */ |
808 | const char *__clk_get_name(const struct clk *clk); | 806 | const char *__clk_get_name(const struct clk *clk); |
809 | const char *clk_hw_get_name(const struct clk_hw *hw); | 807 | const char *clk_hw_get_name(const struct clk_hw *hw); |
808 | #ifdef CONFIG_COMMON_CLK | ||
810 | struct clk_hw *__clk_get_hw(struct clk *clk); | 809 | struct clk_hw *__clk_get_hw(struct clk *clk); |
810 | #else | ||
811 | static inline struct clk_hw *__clk_get_hw(struct clk *clk) | ||
812 | { | ||
813 | return (struct clk_hw *)clk; | ||
814 | } | ||
815 | #endif | ||
811 | unsigned int clk_hw_get_num_parents(const struct clk_hw *hw); | 816 | unsigned int clk_hw_get_num_parents(const struct clk_hw *hw); |
812 | struct clk_hw *clk_hw_get_parent(const struct clk_hw *hw); | 817 | struct clk_hw *clk_hw_get_parent(const struct clk_hw *hw); |
813 | struct clk_hw *clk_hw_get_parent_by_index(const struct clk_hw *hw, | 818 | struct clk_hw *clk_hw_get_parent_by_index(const struct clk_hw *hw, |
@@ -867,8 +872,6 @@ static inline long divider_ro_round_rate(struct clk_hw *hw, unsigned long rate, | |||
867 | */ | 872 | */ |
868 | unsigned long clk_hw_round_rate(struct clk_hw *hw, unsigned long rate); | 873 | unsigned long clk_hw_round_rate(struct clk_hw *hw, unsigned long rate); |
869 | 874 | ||
870 | struct of_device_id; | ||
871 | |||
872 | struct clk_onecell_data { | 875 | struct clk_onecell_data { |
873 | struct clk **clks; | 876 | struct clk **clks; |
874 | unsigned int clk_num; | 877 | unsigned int clk_num; |
@@ -879,8 +882,6 @@ struct clk_hw_onecell_data { | |||
879 | struct clk_hw *hws[]; | 882 | struct clk_hw *hws[]; |
880 | }; | 883 | }; |
881 | 884 | ||
882 | extern struct of_device_id __clk_of_table; | ||
883 | |||
884 | #define CLK_OF_DECLARE(name, compat, fn) OF_DECLARE_1(clk, name, compat, fn) | 885 | #define CLK_OF_DECLARE(name, compat, fn) OF_DECLARE_1(clk, name, compat, fn) |
885 | 886 | ||
886 | /* | 887 | /* |
@@ -904,6 +905,40 @@ extern struct of_device_id __clk_of_table; | |||
904 | .ops = _ops, \ | 905 | .ops = _ops, \ |
905 | }) | 906 | }) |
906 | 907 | ||
908 | #define CLK_HW_INIT_HW(_name, _parent, _ops, _flags) \ | ||
909 | (&(struct clk_init_data) { \ | ||
910 | .flags = _flags, \ | ||
911 | .name = _name, \ | ||
912 | .parent_hws = (const struct clk_hw*[]) { _parent }, \ | ||
913 | .num_parents = 1, \ | ||
914 | .ops = _ops, \ | ||
915 | }) | ||
916 | |||
917 | /* | ||
918 | * This macro is intended for drivers to be able to share the otherwise | ||
919 | * individual struct clk_hw[] compound literals created by the compiler | ||
920 | * when using CLK_HW_INIT_HW. It does NOT support multiple parents. | ||
921 | */ | ||
922 | #define CLK_HW_INIT_HWS(_name, _parent, _ops, _flags) \ | ||
923 | (&(struct clk_init_data) { \ | ||
924 | .flags = _flags, \ | ||
925 | .name = _name, \ | ||
926 | .parent_hws = _parent, \ | ||
927 | .num_parents = 1, \ | ||
928 | .ops = _ops, \ | ||
929 | }) | ||
930 | |||
931 | #define CLK_HW_INIT_FW_NAME(_name, _parent, _ops, _flags) \ | ||
932 | (&(struct clk_init_data) { \ | ||
933 | .flags = _flags, \ | ||
934 | .name = _name, \ | ||
935 | .parent_data = (const struct clk_parent_data[]) { \ | ||
936 | { .fw_name = _parent }, \ | ||
937 | }, \ | ||
938 | .num_parents = 1, \ | ||
939 | .ops = _ops, \ | ||
940 | }) | ||
941 | |||
907 | #define CLK_HW_INIT_PARENTS(_name, _parents, _ops, _flags) \ | 942 | #define CLK_HW_INIT_PARENTS(_name, _parents, _ops, _flags) \ |
908 | (&(struct clk_init_data) { \ | 943 | (&(struct clk_init_data) { \ |
909 | .flags = _flags, \ | 944 | .flags = _flags, \ |
@@ -913,6 +948,24 @@ extern struct of_device_id __clk_of_table; | |||
913 | .ops = _ops, \ | 948 | .ops = _ops, \ |
914 | }) | 949 | }) |
915 | 950 | ||
951 | #define CLK_HW_INIT_PARENTS_HW(_name, _parents, _ops, _flags) \ | ||
952 | (&(struct clk_init_data) { \ | ||
953 | .flags = _flags, \ | ||
954 | .name = _name, \ | ||
955 | .parent_hws = _parents, \ | ||
956 | .num_parents = ARRAY_SIZE(_parents), \ | ||
957 | .ops = _ops, \ | ||
958 | }) | ||
959 | |||
960 | #define CLK_HW_INIT_PARENTS_DATA(_name, _parents, _ops, _flags) \ | ||
961 | (&(struct clk_init_data) { \ | ||
962 | .flags = _flags, \ | ||
963 | .name = _name, \ | ||
964 | .parent_data = _parents, \ | ||
965 | .num_parents = ARRAY_SIZE(_parents), \ | ||
966 | .ops = _ops, \ | ||
967 | }) | ||
968 | |||
916 | #define CLK_HW_INIT_NO_PARENT(_name, _ops, _flags) \ | 969 | #define CLK_HW_INIT_NO_PARENT(_name, _ops, _flags) \ |
917 | (&(struct clk_init_data) { \ | 970 | (&(struct clk_init_data) { \ |
918 | .flags = _flags, \ | 971 | .flags = _flags, \ |
@@ -933,6 +986,43 @@ extern struct of_device_id __clk_of_table; | |||
933 | _flags), \ | 986 | _flags), \ |
934 | } | 987 | } |
935 | 988 | ||
989 | #define CLK_FIXED_FACTOR_HW(_struct, _name, _parent, \ | ||
990 | _div, _mult, _flags) \ | ||
991 | struct clk_fixed_factor _struct = { \ | ||
992 | .div = _div, \ | ||
993 | .mult = _mult, \ | ||
994 | .hw.init = CLK_HW_INIT_HW(_name, \ | ||
995 | _parent, \ | ||
996 | &clk_fixed_factor_ops, \ | ||
997 | _flags), \ | ||
998 | } | ||
999 | |||
1000 | /* | ||
1001 | * This macro allows the driver to reuse the _parent array for multiple | ||
1002 | * fixed factor clk declarations. | ||
1003 | */ | ||
1004 | #define CLK_FIXED_FACTOR_HWS(_struct, _name, _parent, \ | ||
1005 | _div, _mult, _flags) \ | ||
1006 | struct clk_fixed_factor _struct = { \ | ||
1007 | .div = _div, \ | ||
1008 | .mult = _mult, \ | ||
1009 | .hw.init = CLK_HW_INIT_HWS(_name, \ | ||
1010 | _parent, \ | ||
1011 | &clk_fixed_factor_ops, \ | ||
1012 | _flags), \ | ||
1013 | } | ||
1014 | |||
1015 | #define CLK_FIXED_FACTOR_FW_NAME(_struct, _name, _parent, \ | ||
1016 | _div, _mult, _flags) \ | ||
1017 | struct clk_fixed_factor _struct = { \ | ||
1018 | .div = _div, \ | ||
1019 | .mult = _mult, \ | ||
1020 | .hw.init = CLK_HW_INIT_FW_NAME(_name, \ | ||
1021 | _parent, \ | ||
1022 | &clk_fixed_factor_ops, \ | ||
1023 | _flags), \ | ||
1024 | } | ||
1025 | |||
936 | #ifdef CONFIG_OF | 1026 | #ifdef CONFIG_OF |
937 | int of_clk_add_provider(struct device_node *np, | 1027 | int of_clk_add_provider(struct device_node *np, |
938 | struct clk *(*clk_src_get)(struct of_phandle_args *args, | 1028 | struct clk *(*clk_src_get)(struct of_phandle_args *args, |
@@ -1019,5 +1109,4 @@ static inline int of_clk_detect_critical(struct device_node *np, int index, | |||
1019 | 1109 | ||
1020 | void clk_gate_restore_context(struct clk_hw *hw); | 1110 | void clk_gate_restore_context(struct clk_hw *hw); |
1021 | 1111 | ||
1022 | #endif /* CONFIG_COMMON_CLK */ | ||
1023 | #endif /* CLK_PROVIDER_H */ | 1112 | #endif /* CLK_PROVIDER_H */ |
diff --git a/include/linux/clk.h b/include/linux/clk.h index c8e3325868bd..3c096c7a51dc 100644 --- a/include/linux/clk.h +++ b/include/linux/clk.h | |||
@@ -329,6 +329,19 @@ int __must_check clk_bulk_get(struct device *dev, int num_clks, | |||
329 | */ | 329 | */ |
330 | int __must_check clk_bulk_get_all(struct device *dev, | 330 | int __must_check clk_bulk_get_all(struct device *dev, |
331 | struct clk_bulk_data **clks); | 331 | struct clk_bulk_data **clks); |
332 | |||
333 | /** | ||
334 | * clk_bulk_get_optional - lookup and obtain a number of references to clock producer | ||
335 | * @dev: device for clock "consumer" | ||
336 | * @num_clks: the number of clk_bulk_data | ||
337 | * @clks: the clk_bulk_data table of consumer | ||
338 | * | ||
339 | * Behaves the same as clk_bulk_get() except where there is no clock producer. | ||
340 | * In this case, instead of returning -ENOENT, the function returns 0 and | ||
341 | * NULL for a clk for which a clock producer could not be determined. | ||
342 | */ | ||
343 | int __must_check clk_bulk_get_optional(struct device *dev, int num_clks, | ||
344 | struct clk_bulk_data *clks); | ||
332 | /** | 345 | /** |
333 | * devm_clk_bulk_get - managed get multiple clk consumers | 346 | * devm_clk_bulk_get - managed get multiple clk consumers |
334 | * @dev: device for clock "consumer" | 347 | * @dev: device for clock "consumer" |
@@ -344,6 +357,28 @@ int __must_check clk_bulk_get_all(struct device *dev, | |||
344 | int __must_check devm_clk_bulk_get(struct device *dev, int num_clks, | 357 | int __must_check devm_clk_bulk_get(struct device *dev, int num_clks, |
345 | struct clk_bulk_data *clks); | 358 | struct clk_bulk_data *clks); |
346 | /** | 359 | /** |
360 | * devm_clk_bulk_get_optional - managed get multiple optional consumer clocks | ||
361 | * @dev: device for clock "consumer" | ||
362 | * @clks: pointer to the clk_bulk_data table of consumer | ||
363 | * | ||
364 | * Behaves the same as devm_clk_bulk_get() except where there is no clock | ||
365 | * producer. In this case, instead of returning -ENOENT, the function returns | ||
366 | * NULL for given clk. It is assumed all clocks in clk_bulk_data are optional. | ||
367 | * | ||
368 | * Returns 0 if all clocks specified in clk_bulk_data table are obtained | ||
369 | * successfully or for any clk there was no clk provider available, otherwise | ||
370 | * returns valid IS_ERR() condition containing errno. | ||
371 | * The implementation uses @dev and @clk_bulk_data.id to determine the | ||
372 | * clock consumer, and thereby the clock producer. | ||
373 | * The clock returned is stored in each @clk_bulk_data.clk field. | ||
374 | * | ||
375 | * Drivers must assume that the clock source is not enabled. | ||
376 | * | ||
377 | * clk_bulk_get should not be called from within interrupt context. | ||
378 | */ | ||
379 | int __must_check devm_clk_bulk_get_optional(struct device *dev, int num_clks, | ||
380 | struct clk_bulk_data *clks); | ||
381 | /** | ||
347 | * devm_clk_bulk_get_all - managed get multiple clk consumers | 382 | * devm_clk_bulk_get_all - managed get multiple clk consumers |
348 | * @dev: device for clock "consumer" | 383 | * @dev: device for clock "consumer" |
349 | * @clks: pointer to the clk_bulk_data table of consumer | 384 | * @clks: pointer to the clk_bulk_data table of consumer |
@@ -715,6 +750,12 @@ static inline int __must_check clk_bulk_get(struct device *dev, int num_clks, | |||
715 | return 0; | 750 | return 0; |
716 | } | 751 | } |
717 | 752 | ||
753 | static inline int __must_check clk_bulk_get_optional(struct device *dev, | ||
754 | int num_clks, struct clk_bulk_data *clks) | ||
755 | { | ||
756 | return 0; | ||
757 | } | ||
758 | |||
718 | static inline int __must_check clk_bulk_get_all(struct device *dev, | 759 | static inline int __must_check clk_bulk_get_all(struct device *dev, |
719 | struct clk_bulk_data **clks) | 760 | struct clk_bulk_data **clks) |
720 | { | 761 | { |
@@ -738,6 +779,12 @@ static inline int __must_check devm_clk_bulk_get(struct device *dev, int num_clk | |||
738 | return 0; | 779 | return 0; |
739 | } | 780 | } |
740 | 781 | ||
782 | static inline int __must_check devm_clk_bulk_get_optional(struct device *dev, | ||
783 | int num_clks, struct clk_bulk_data *clks) | ||
784 | { | ||
785 | return 0; | ||
786 | } | ||
787 | |||
741 | static inline int __must_check devm_clk_bulk_get_all(struct device *dev, | 788 | static inline int __must_check devm_clk_bulk_get_all(struct device *dev, |
742 | struct clk_bulk_data **clks) | 789 | struct clk_bulk_data **clks) |
743 | { | 790 | { |
diff --git a/include/linux/soc/ti/ti_sci_protocol.h b/include/linux/soc/ti/ti_sci_protocol.h index 568722a041bf..406e6717d252 100644 --- a/include/linux/soc/ti/ti_sci_protocol.h +++ b/include/linux/soc/ti/ti_sci_protocol.h | |||
@@ -166,29 +166,29 @@ struct ti_sci_dev_ops { | |||
166 | * managed by driver for that purpose. | 166 | * managed by driver for that purpose. |
167 | */ | 167 | */ |
168 | struct ti_sci_clk_ops { | 168 | struct ti_sci_clk_ops { |
169 | int (*get_clock)(const struct ti_sci_handle *handle, u32 did, u8 cid, | 169 | int (*get_clock)(const struct ti_sci_handle *handle, u32 did, u32 cid, |
170 | bool needs_ssc, bool can_change_freq, | 170 | bool needs_ssc, bool can_change_freq, |
171 | bool enable_input_term); | 171 | bool enable_input_term); |
172 | int (*idle_clock)(const struct ti_sci_handle *handle, u32 did, u8 cid); | 172 | int (*idle_clock)(const struct ti_sci_handle *handle, u32 did, u32 cid); |
173 | int (*put_clock)(const struct ti_sci_handle *handle, u32 did, u8 cid); | 173 | int (*put_clock)(const struct ti_sci_handle *handle, u32 did, u32 cid); |
174 | int (*is_auto)(const struct ti_sci_handle *handle, u32 did, u8 cid, | 174 | int (*is_auto)(const struct ti_sci_handle *handle, u32 did, u32 cid, |
175 | bool *req_state); | 175 | bool *req_state); |
176 | int (*is_on)(const struct ti_sci_handle *handle, u32 did, u8 cid, | 176 | int (*is_on)(const struct ti_sci_handle *handle, u32 did, u32 cid, |
177 | bool *req_state, bool *current_state); | 177 | bool *req_state, bool *current_state); |
178 | int (*is_off)(const struct ti_sci_handle *handle, u32 did, u8 cid, | 178 | int (*is_off)(const struct ti_sci_handle *handle, u32 did, u32 cid, |
179 | bool *req_state, bool *current_state); | 179 | bool *req_state, bool *current_state); |
180 | int (*set_parent)(const struct ti_sci_handle *handle, u32 did, u8 cid, | 180 | int (*set_parent)(const struct ti_sci_handle *handle, u32 did, u32 cid, |
181 | u8 parent_id); | 181 | u32 parent_id); |
182 | int (*get_parent)(const struct ti_sci_handle *handle, u32 did, u8 cid, | 182 | int (*get_parent)(const struct ti_sci_handle *handle, u32 did, u32 cid, |
183 | u8 *parent_id); | 183 | u32 *parent_id); |
184 | int (*get_num_parents)(const struct ti_sci_handle *handle, u32 did, | 184 | int (*get_num_parents)(const struct ti_sci_handle *handle, u32 did, |
185 | u8 cid, u8 *num_parents); | 185 | u32 cid, u32 *num_parents); |
186 | int (*get_best_match_freq)(const struct ti_sci_handle *handle, u32 did, | 186 | int (*get_best_match_freq)(const struct ti_sci_handle *handle, u32 did, |
187 | u8 cid, u64 min_freq, u64 target_freq, | 187 | u32 cid, u64 min_freq, u64 target_freq, |
188 | u64 max_freq, u64 *match_freq); | 188 | u64 max_freq, u64 *match_freq); |
189 | int (*set_freq)(const struct ti_sci_handle *handle, u32 did, u8 cid, | 189 | int (*set_freq)(const struct ti_sci_handle *handle, u32 did, u32 cid, |
190 | u64 min_freq, u64 target_freq, u64 max_freq); | 190 | u64 min_freq, u64 target_freq, u64 max_freq); |
191 | int (*get_freq)(const struct ti_sci_handle *handle, u32 did, u8 cid, | 191 | int (*get_freq)(const struct ti_sci_handle *handle, u32 did, u32 cid, |
192 | u64 *current_freq); | 192 | u64 *current_freq); |
193 | }; | 193 | }; |
194 | 194 | ||