diff options
122 files changed, 7979 insertions, 581 deletions
diff --git a/Documentation/devicetree/bindings/clock/actions,s900-cmu.txt b/Documentation/devicetree/bindings/clock/actions,owl-cmu.txt index 93e4fb827cd6..d1e60d297387 100644 --- a/Documentation/devicetree/bindings/clock/actions,s900-cmu.txt +++ b/Documentation/devicetree/bindings/clock/actions,owl-cmu.txt | |||
@@ -1,12 +1,14 @@ | |||
1 | * Actions S900 Clock Management Unit (CMU) | 1 | * Actions Semi Owl Clock Management Unit (CMU) |
2 | 2 | ||
3 | The Actions S900 clock management unit generates and supplies clock to various | 3 | The Actions Semi Owl Clock Management Unit generates and supplies clock |
4 | controllers within the SoC. The clock binding described here is applicable to | 4 | to various controllers within the SoC. The clock binding described here is |
5 | S900 SoC. | 5 | applicable to S900 and S700 SoC's. |
6 | 6 | ||
7 | Required Properties: | 7 | Required Properties: |
8 | 8 | ||
9 | - compatible: should be "actions,s900-cmu" | 9 | - compatible: should be one of the following, |
10 | "actions,s900-cmu" | ||
11 | "actions,s700-cmu" | ||
10 | - reg: physical base address of the controller and length of memory mapped | 12 | - reg: physical base address of the controller and length of memory mapped |
11 | region. | 13 | region. |
12 | - clocks: Reference to the parent clocks ("hosc", "losc") | 14 | - clocks: Reference to the parent clocks ("hosc", "losc") |
@@ -15,16 +17,16 @@ Required Properties: | |||
15 | Each clock is assigned an identifier, and client nodes can use this identifier | 17 | Each clock is assigned an identifier, and client nodes can use this identifier |
16 | to specify the clock which they consume. | 18 | to specify the clock which they consume. |
17 | 19 | ||
18 | All available clocks are defined as preprocessor macros in | 20 | All available clocks are defined as preprocessor macros in corresponding |
19 | dt-bindings/clock/actions,s900-cmu.h header and can be used in device | 21 | dt-bindings/clock/actions,s900-cmu.h or actions,s700-cmu.h header and can be |
20 | tree sources. | 22 | used in device tree sources. |
21 | 23 | ||
22 | External clocks: | 24 | External clocks: |
23 | 25 | ||
24 | The hosc clock used as input for the plls is generated outside the SoC. It is | 26 | The hosc clock used as input for the plls is generated outside the SoC. It is |
25 | expected that it is defined using standard clock bindings as "hosc". | 27 | expected that it is defined using standard clock bindings as "hosc". |
26 | 28 | ||
27 | Actions S900 CMU also requires one more clock: | 29 | Actions Semi S900 CMU also requires one more clock: |
28 | - "losc" - internal low frequency oscillator | 30 | - "losc" - internal low frequency oscillator |
29 | 31 | ||
30 | Example: Clock Management Unit node: | 32 | Example: Clock Management Unit node: |
diff --git a/Documentation/devicetree/bindings/clock/amlogic,axg-audio-clkc.txt b/Documentation/devicetree/bindings/clock/amlogic,axg-audio-clkc.txt new file mode 100644 index 000000000000..61777ad24f61 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/amlogic,axg-audio-clkc.txt | |||
@@ -0,0 +1,56 @@ | |||
1 | * Amlogic AXG Audio Clock Controllers | ||
2 | |||
3 | The Amlogic AXG audio clock controller generates and supplies clock to the | ||
4 | other elements of the audio subsystem, such as fifos, i2s, spdif and pdm | ||
5 | devices. | ||
6 | |||
7 | Required Properties: | ||
8 | |||
9 | - compatible : should be "amlogic,axg-audio-clkc" for the A113X and A113D | ||
10 | - reg : physical base address of the clock controller and length of | ||
11 | memory mapped region. | ||
12 | - clocks : a list of phandle + clock-specifier pairs for the clocks listed | ||
13 | in clock-names. | ||
14 | - clock-names : must contain the following: | ||
15 | * "pclk" - Main peripheral bus clock | ||
16 | may contain the following: | ||
17 | * "mst_in[0-7]" - 8 input plls to generate clock signals | ||
18 | * "slv_sclk[0-9]" - 10 slave bit clocks provided by external | ||
19 | components. | ||
20 | * "slv_lrclk[0-9]" - 10 slave sample clocks provided by external | ||
21 | components. | ||
22 | - resets : phandle of the internal reset line | ||
23 | - #clock-cells : should be 1. | ||
24 | |||
25 | Each clock is assigned an identifier and client nodes can use this identifier | ||
26 | to specify the clock which they consume. All available clocks are defined as | ||
27 | preprocessor macros in the dt-bindings/clock/axg-audio-clkc.h header and can be | ||
28 | used in device tree sources. | ||
29 | |||
30 | Example: | ||
31 | |||
32 | clkc_audio: clock-controller@0 { | ||
33 | compatible = "amlogic,axg-audio-clkc"; | ||
34 | reg = <0x0 0x0 0x0 0xb4>; | ||
35 | #clock-cells = <1>; | ||
36 | |||
37 | clocks = <&clkc CLKID_AUDIO>, | ||
38 | <&clkc CLKID_MPLL0>, | ||
39 | <&clkc CLKID_MPLL1>, | ||
40 | <&clkc CLKID_MPLL2>, | ||
41 | <&clkc CLKID_MPLL3>, | ||
42 | <&clkc CLKID_HIFI_PLL>, | ||
43 | <&clkc CLKID_FCLK_DIV3>, | ||
44 | <&clkc CLKID_FCLK_DIV4>, | ||
45 | <&clkc CLKID_GP0_PLL>; | ||
46 | clock-names = "pclk", | ||
47 | "mst_in0", | ||
48 | "mst_in1", | ||
49 | "mst_in2", | ||
50 | "mst_in3", | ||
51 | "mst_in4", | ||
52 | "mst_in5", | ||
53 | "mst_in6", | ||
54 | "mst_in7"; | ||
55 | resets = <&reset RESET_AUDIO>; | ||
56 | }; | ||
diff --git a/Documentation/devicetree/bindings/clock/at91-clock.txt b/Documentation/devicetree/bindings/clock/at91-clock.txt index 33fe9591e904..09968ee224d8 100644 --- a/Documentation/devicetree/bindings/clock/at91-clock.txt +++ b/Documentation/devicetree/bindings/clock/at91-clock.txt | |||
@@ -91,6 +91,9 @@ Required properties: | |||
91 | at91 audio pll output on AUDIOPLLCLK that feeds the PMC | 91 | at91 audio pll output on AUDIOPLLCLK that feeds the PMC |
92 | and can be used by peripheral clock or generic clock | 92 | and can be used by peripheral clock or generic clock |
93 | 93 | ||
94 | "atmel,sama5d2-clk-i2s-mux" (under pmc node): | ||
95 | at91 I2S clock source selection | ||
96 | |||
94 | Required properties for SCKC node: | 97 | Required properties for SCKC node: |
95 | - reg : defines the IO memory reserved for the SCKC. | 98 | - reg : defines the IO memory reserved for the SCKC. |
96 | - #size-cells : shall be 0 (reg is used to encode clk id). | 99 | - #size-cells : shall be 0 (reg is used to encode clk id). |
@@ -500,3 +503,35 @@ For example: | |||
500 | atmel,clk-output-range = <0 83000000>; | 503 | atmel,clk-output-range = <0 83000000>; |
501 | }; | 504 | }; |
502 | }; | 505 | }; |
506 | |||
507 | Required properties for I2S mux clocks: | ||
508 | - #size-cells : shall be 0 (reg is used to encode I2S bus id). | ||
509 | - #address-cells : shall be 1 (reg is used to encode I2S bus id). | ||
510 | - name: device tree node describing a specific mux clock. | ||
511 | * #clock-cells : from common clock binding; shall be set to 0. | ||
512 | * clocks : shall be the mux clock parent phandles; shall be 2 phandles: | ||
513 | peripheral and generated clock; the first phandle shall belong to the | ||
514 | peripheral clock and the second one shall belong to the generated | ||
515 | clock; "clock-indices" property can be user to specify | ||
516 | the correct order. | ||
517 | * reg: I2S bus id of the corresponding mux clock. | ||
518 | e.g. reg = <0>; for i2s0, reg = <1>; for i2s1 | ||
519 | |||
520 | For example: | ||
521 | i2s_clkmux { | ||
522 | compatible = "atmel,sama5d2-clk-i2s-mux"; | ||
523 | #address-cells = <1>; | ||
524 | #size-cells = <0>; | ||
525 | |||
526 | i2s0muxck: i2s0_muxclk { | ||
527 | clocks = <&i2s0_clk>, <&i2s0_gclk>; | ||
528 | #clock-cells = <0>; | ||
529 | reg = <0>; | ||
530 | }; | ||
531 | |||
532 | i2s1muxck: i2s1_muxclk { | ||
533 | clocks = <&i2s1_clk>, <&i2s1_gclk>; | ||
534 | #clock-cells = <0>; | ||
535 | reg = <1>; | ||
536 | }; | ||
537 | }; | ||
diff --git a/Documentation/devicetree/bindings/clock/maxim,max9485.txt b/Documentation/devicetree/bindings/clock/maxim,max9485.txt new file mode 100644 index 000000000000..61bec1100a94 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/maxim,max9485.txt | |||
@@ -0,0 +1,59 @@ | |||
1 | Devicetree bindings for Maxim MAX9485 Programmable Audio Clock Generator | ||
2 | |||
3 | This device exposes 4 clocks in total: | ||
4 | |||
5 | - MAX9485_MCLKOUT: A gated, buffered output of the input clock of 27 MHz | ||
6 | - MAX9485_CLKOUT: A PLL that can be configured to 16 different discrete | ||
7 | frequencies | ||
8 | - MAX9485_CLKOUT[1,2]: Two gated outputs for MAX9485_CLKOUT | ||
9 | |||
10 | MAX9485_CLKOUT[1,2] are children of MAX9485_CLKOUT which upchain all rate set | ||
11 | requests. | ||
12 | |||
13 | Required properties: | ||
14 | - compatible: "maxim,max9485" | ||
15 | - clocks: Input clock, must provice 27.000 MHz | ||
16 | - clock-names: Must be set to "xclk" | ||
17 | - #clock-cells: From common clock binding; shall be set to 1 | ||
18 | |||
19 | Optional properties: | ||
20 | - reset-gpios: GPIO descriptor connected to the #RESET input pin | ||
21 | - vdd-supply: A regulator node for Vdd | ||
22 | - clock-output-names: Name of output clocks, as defined in common clock | ||
23 | bindings | ||
24 | |||
25 | If not explicitly set, the output names are "mclkout", "clkout", "clkout1" | ||
26 | and "clkout2". | ||
27 | |||
28 | Clocks are defined as preprocessor macros in the dt-binding header. | ||
29 | |||
30 | Example: | ||
31 | |||
32 | #include <dt-bindings/clock/maxim,max9485.h> | ||
33 | |||
34 | xo-27mhz: xo-27mhz { | ||
35 | compatible = "fixed-clock"; | ||
36 | #clock-cells = <0>; | ||
37 | clock-frequency = <27000000>; | ||
38 | }; | ||
39 | |||
40 | &i2c0 { | ||
41 | max9485: audio-clock@63 { | ||
42 | reg = <0x63>; | ||
43 | compatible = "maxim,max9485"; | ||
44 | clock-names = "xclk"; | ||
45 | clocks = <&xo-27mhz>; | ||
46 | reset-gpios = <&gpio 1 GPIO_ACTIVE_HIGH>; | ||
47 | vdd-supply = <&3v3-reg>; | ||
48 | #clock-cells = <1>; | ||
49 | }; | ||
50 | }; | ||
51 | |||
52 | // Clock consumer node | ||
53 | |||
54 | foo@0 { | ||
55 | compatible = "bar,foo"; | ||
56 | /* ... */ | ||
57 | clock-names = "foo-input-clk"; | ||
58 | clocks = <&max9485 MAX9485_CLKOUT1>; | ||
59 | }; | ||
diff --git a/Documentation/devicetree/bindings/clock/qcom,dispcc.txt b/Documentation/devicetree/bindings/clock/qcom,dispcc.txt new file mode 100644 index 000000000000..d639e18d0b85 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,dispcc.txt | |||
@@ -0,0 +1,19 @@ | |||
1 | Qualcomm Technologies, Inc. Display Clock Controller Binding | ||
2 | ------------------------------------------------------------ | ||
3 | |||
4 | Required properties : | ||
5 | |||
6 | - compatible : shall contain "qcom,sdm845-dispcc" | ||
7 | - reg : shall contain base register location and length. | ||
8 | - #clock-cells : from common clock binding, shall contain 1. | ||
9 | - #reset-cells : from common reset binding, shall contain 1. | ||
10 | - #power-domain-cells : from generic power domain binding, shall contain 1. | ||
11 | |||
12 | Example: | ||
13 | dispcc: clock-controller@af00000 { | ||
14 | compatible = "qcom,sdm845-dispcc"; | ||
15 | reg = <0xaf00000 0x100000>; | ||
16 | #clock-cells = <1>; | ||
17 | #reset-cells = <1>; | ||
18 | #power-domain-cells = <1>; | ||
19 | }; | ||
diff --git a/Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.txt b/Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.txt new file mode 100644 index 000000000000..d60b99756bb9 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.txt | |||
@@ -0,0 +1,43 @@ | |||
1 | * Renesas R9A06G032 SYSCTRL | ||
2 | |||
3 | Required Properties: | ||
4 | |||
5 | - compatible: Must be: | ||
6 | - "renesas,r9a06g032-sysctrl" | ||
7 | - reg: Base address and length of the SYSCTRL IO block. | ||
8 | - #clock-cells: Must be 1 | ||
9 | - clocks: References to the parent clocks: | ||
10 | - external 40mhz crystal. | ||
11 | - external (optional) 32.768khz | ||
12 | - external (optional) jtag input | ||
13 | - external (optional) RGMII_REFCLK | ||
14 | - clock-names: Must be: | ||
15 | clock-names = "mclk", "rtc", "jtag", "rgmii_ref_ext"; | ||
16 | |||
17 | Examples | ||
18 | -------- | ||
19 | |||
20 | - SYSCTRL node: | ||
21 | |||
22 | sysctrl: system-controller@4000c000 { | ||
23 | compatible = "renesas,r9a06g032-sysctrl"; | ||
24 | reg = <0x4000c000 0x1000>; | ||
25 | #clock-cells = <1>; | ||
26 | |||
27 | clocks = <&ext_mclk>, <&ext_rtc_clk>, | ||
28 | <&ext_jtag_clk>, <&ext_rgmii_ref>; | ||
29 | clock-names = "mclk", "rtc", "jtag", "rgmii_ref_ext"; | ||
30 | }; | ||
31 | |||
32 | - Other nodes can use the clocks provided by SYSCTRL as in: | ||
33 | |||
34 | #include <dt-bindings/clock/r9a06g032-sysctrl.h> | ||
35 | uart0: serial@40060000 { | ||
36 | compatible = "snps,dw-apb-uart"; | ||
37 | reg = <0x40060000 0x400>; | ||
38 | interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>; | ||
39 | reg-shift = <2>; | ||
40 | reg-io-width = <4>; | ||
41 | clocks = <&sysctrl R9A06G032_CLK_UART0>; | ||
42 | clock-names = "baudclk"; | ||
43 | }; | ||
diff --git a/Documentation/devicetree/bindings/clock/rockchip,px30-cru.txt b/Documentation/devicetree/bindings/clock/rockchip,px30-cru.txt new file mode 100644 index 000000000000..39f0c1ac84ee --- /dev/null +++ b/Documentation/devicetree/bindings/clock/rockchip,px30-cru.txt | |||
@@ -0,0 +1,65 @@ | |||
1 | * Rockchip PX30 Clock and Reset Unit | ||
2 | |||
3 | The PX30 clock controller generates and supplies clock to various | ||
4 | controllers within the SoC and also implements a reset controller for SoC | ||
5 | peripherals. | ||
6 | |||
7 | Required Properties: | ||
8 | |||
9 | - compatible: PMU for CRU should be "rockchip,px30-pmu-cru" | ||
10 | - compatible: CRU should be "rockchip,px30-cru" | ||
11 | - reg: physical base address of the controller and length of memory mapped | ||
12 | region. | ||
13 | - #clock-cells: should be 1. | ||
14 | - #reset-cells: should be 1. | ||
15 | |||
16 | Optional Properties: | ||
17 | |||
18 | - rockchip,grf: phandle to the syscon managing the "general register files" | ||
19 | If missing, pll rates are not changeable, due to the missing pll lock status. | ||
20 | |||
21 | Each clock is assigned an identifier and client nodes can use this identifier | ||
22 | to specify the clock which they consume. All available clocks are defined as | ||
23 | preprocessor macros in the dt-bindings/clock/px30-cru.h headers and can be | ||
24 | used in device tree sources. Similar macros exist for the reset sources in | ||
25 | these files. | ||
26 | |||
27 | External clocks: | ||
28 | |||
29 | There are several clocks that are generated outside the SoC. It is expected | ||
30 | that they are defined using standard clock bindings with following | ||
31 | clock-output-names: | ||
32 | - "xin24m" - crystal input - required, | ||
33 | - "xin32k" - rtc clock - optional, | ||
34 | - "i2sx_clkin" - external I2S clock - optional, | ||
35 | - "gmac_clkin" - external GMAC clock - optional | ||
36 | |||
37 | Example: Clock controller node: | ||
38 | |||
39 | pmucru: clock-controller@ff2bc000 { | ||
40 | compatible = "rockchip,px30-pmucru"; | ||
41 | reg = <0x0 0xff2bc000 0x0 0x1000>; | ||
42 | #clock-cells = <1>; | ||
43 | #reset-cells = <1>; | ||
44 | }; | ||
45 | |||
46 | cru: clock-controller@ff2b0000 { | ||
47 | compatible = "rockchip,px30-cru"; | ||
48 | reg = <0x0 0xff2b0000 0x0 0x1000>; | ||
49 | rockchip,grf = <&grf>; | ||
50 | #clock-cells = <1>; | ||
51 | #reset-cells = <1>; | ||
52 | }; | ||
53 | |||
54 | Example: UART controller node that consumes the clock generated by the clock | ||
55 | controller: | ||
56 | |||
57 | uart0: serial@ff030000 { | ||
58 | compatible = "rockchip,px30-uart", "snps,dw-apb-uart"; | ||
59 | reg = <0x0 0xff030000 0x0 0x100>; | ||
60 | interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>; | ||
61 | clocks = <&pmucru SCLK_UART0_PMU>, <&pmucru PCLK_UART0_PMU>; | ||
62 | clock-names = "baudclk", "apb_pclk"; | ||
63 | reg-shift = <2>; | ||
64 | reg-io-width = <4>; | ||
65 | }; | ||
diff --git a/Documentation/devicetree/bindings/clock/sun8i-de2.txt b/Documentation/devicetree/bindings/clock/sun8i-de2.txt index f2fa87c4765c..e94582e8b8a9 100644 --- a/Documentation/devicetree/bindings/clock/sun8i-de2.txt +++ b/Documentation/devicetree/bindings/clock/sun8i-de2.txt | |||
@@ -6,6 +6,7 @@ Required properties : | |||
6 | - "allwinner,sun8i-a83t-de2-clk" | 6 | - "allwinner,sun8i-a83t-de2-clk" |
7 | - "allwinner,sun8i-h3-de2-clk" | 7 | - "allwinner,sun8i-h3-de2-clk" |
8 | - "allwinner,sun8i-v3s-de2-clk" | 8 | - "allwinner,sun8i-v3s-de2-clk" |
9 | - "allwinner,sun50i-a64-de2-clk" | ||
9 | - "allwinner,sun50i-h5-de2-clk" | 10 | - "allwinner,sun50i-h5-de2-clk" |
10 | 11 | ||
11 | - reg: Must contain the registers base address and length | 12 | - reg: Must contain the registers base address and length |
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index 1254bf9d91b4..903f23c309df 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig | |||
@@ -27,6 +27,7 @@ config SOC_SAMA5D2 | |||
27 | select HAVE_AT91_H32MX | 27 | select HAVE_AT91_H32MX |
28 | select HAVE_AT91_GENERATED_CLK | 28 | select HAVE_AT91_GENERATED_CLK |
29 | select HAVE_AT91_AUDIO_PLL | 29 | select HAVE_AT91_AUDIO_PLL |
30 | select HAVE_AT91_I2S_MUX_CLK | ||
30 | select PINCTRL_AT91PIO4 | 31 | select PINCTRL_AT91PIO4 |
31 | help | 32 | help |
32 | Select this if ou are using one of Microchip's SAMA5D2 family SoC. | 33 | Select this if ou are using one of Microchip's SAMA5D2 family SoC. |
@@ -129,6 +130,9 @@ config HAVE_AT91_GENERATED_CLK | |||
129 | config HAVE_AT91_AUDIO_PLL | 130 | config HAVE_AT91_AUDIO_PLL |
130 | bool | 131 | bool |
131 | 132 | ||
133 | config HAVE_AT91_I2S_MUX_CLK | ||
134 | bool | ||
135 | |||
132 | config SOC_SAM_V4_V5 | 136 | config SOC_SAM_V4_V5 |
133 | bool | 137 | bool |
134 | 138 | ||
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 721572a8c429..292056bbb30e 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig | |||
@@ -45,6 +45,12 @@ config COMMON_CLK_MAX77686 | |||
45 | This driver supports Maxim 77620/77686/77802 crystal oscillator | 45 | This driver supports Maxim 77620/77686/77802 crystal oscillator |
46 | clock. | 46 | clock. |
47 | 47 | ||
48 | config COMMON_CLK_MAX9485 | ||
49 | tristate "Maxim 9485 Programmable Clock Generator" | ||
50 | depends on I2C | ||
51 | help | ||
52 | This driver supports Maxim 9485 Programmable Audio Clock Generator | ||
53 | |||
48 | config COMMON_CLK_RK808 | 54 | config COMMON_CLK_RK808 |
49 | tristate "Clock driver for RK805/RK808/RK818" | 55 | tristate "Clock driver for RK805/RK808/RK818" |
50 | depends on MFD_RK808 | 56 | depends on MFD_RK808 |
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 0bb25dd009d1..a84c5573cabe 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile | |||
@@ -31,6 +31,7 @@ obj-$(CONFIG_COMMON_CLK_ASPEED) += clk-aspeed.o | |||
31 | obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o | 31 | obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o |
32 | obj-$(CONFIG_CLK_HSDK) += clk-hsdk-pll.o | 32 | obj-$(CONFIG_CLK_HSDK) += clk-hsdk-pll.o |
33 | obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o | 33 | obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o |
34 | obj-$(CONFIG_COMMON_CLK_MAX9485) += clk-max9485.o | ||
34 | obj-$(CONFIG_ARCH_MOXART) += clk-moxart.o | 35 | obj-$(CONFIG_ARCH_MOXART) += clk-moxart.o |
35 | obj-$(CONFIG_ARCH_NOMADIK) += clk-nomadik.o | 36 | obj-$(CONFIG_ARCH_NOMADIK) += clk-nomadik.o |
36 | obj-$(CONFIG_ARCH_NPCM7XX) += clk-npcm7xx.o | 37 | obj-$(CONFIG_ARCH_NPCM7XX) += clk-npcm7xx.o |
diff --git a/drivers/clk/actions/Kconfig b/drivers/clk/actions/Kconfig index 8854adb37847..dc38c85a4833 100644 --- a/drivers/clk/actions/Kconfig +++ b/drivers/clk/actions/Kconfig | |||
@@ -1,14 +1,21 @@ | |||
1 | config CLK_ACTIONS | 1 | config CLK_ACTIONS |
2 | bool "Clock driver for Actions Semi SoCs" | 2 | bool "Clock driver for Actions Semi SoCs" |
3 | depends on ARCH_ACTIONS || COMPILE_TEST | 3 | depends on ARCH_ACTIONS || COMPILE_TEST |
4 | select REGMAP_MMIO | ||
4 | default ARCH_ACTIONS | 5 | default ARCH_ACTIONS |
5 | 6 | ||
6 | if CLK_ACTIONS | 7 | if CLK_ACTIONS |
7 | 8 | ||
8 | # SoC Drivers | 9 | # SoC Drivers |
9 | 10 | ||
11 | config CLK_OWL_S700 | ||
12 | bool "Support for the Actions Semi OWL S700 clocks" | ||
13 | depends on (ARM64 && ARCH_ACTIONS) || COMPILE_TEST | ||
14 | default ARM64 && ARCH_ACTIONS | ||
15 | |||
10 | config CLK_OWL_S900 | 16 | config CLK_OWL_S900 |
11 | bool "Support for the Actions Semi OWL S900 clocks" | 17 | bool "Support for the Actions Semi OWL S900 clocks" |
12 | depends on (ARM64 && ARCH_ACTIONS) || COMPILE_TEST | 18 | depends on (ARM64 && ARCH_ACTIONS) || COMPILE_TEST |
13 | default ARM64 && ARCH_ACTIONS | 19 | default ARM64 && ARCH_ACTIONS |
20 | |||
14 | endif | 21 | endif |
diff --git a/drivers/clk/actions/Makefile b/drivers/clk/actions/Makefile index 76e431434d10..78c17d56f991 100644 --- a/drivers/clk/actions/Makefile +++ b/drivers/clk/actions/Makefile | |||
@@ -9,4 +9,5 @@ clk-owl-y += owl-composite.o | |||
9 | clk-owl-y += owl-pll.o | 9 | clk-owl-y += owl-pll.o |
10 | 10 | ||
11 | # SoC support | 11 | # SoC support |
12 | obj-$(CONFIG_CLK_OWL_S700) += owl-s700.o | ||
12 | obj-$(CONFIG_CLK_OWL_S900) += owl-s900.o | 13 | obj-$(CONFIG_CLK_OWL_S900) += owl-s900.o |
diff --git a/drivers/clk/actions/owl-s700.c b/drivers/clk/actions/owl-s700.c new file mode 100644 index 000000000000..5e9531392ee5 --- /dev/null +++ b/drivers/clk/actions/owl-s700.c | |||
@@ -0,0 +1,606 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0+ | ||
2 | /* | ||
3 | * Actions Semi S700 clock driver | ||
4 | * | ||
5 | * Copyright (c) 2014 Actions Semi Inc. | ||
6 | * Author: David Liu <liuwei@actions-semi.com> | ||
7 | * | ||
8 | * Author: Pathiban Nallathambi <pn@denx.de> | ||
9 | * Author: Saravanan Sekar <sravanhome@gmail.com> | ||
10 | */ | ||
11 | |||
12 | #include <linux/clk-provider.h> | ||
13 | #include <linux/platform_device.h> | ||
14 | |||
15 | #include "owl-common.h" | ||
16 | #include "owl-composite.h" | ||
17 | #include "owl-divider.h" | ||
18 | #include "owl-factor.h" | ||
19 | #include "owl-fixed-factor.h" | ||
20 | #include "owl-gate.h" | ||
21 | #include "owl-mux.h" | ||
22 | #include "owl-pll.h" | ||
23 | |||
24 | #include <dt-bindings/clock/actions,s700-cmu.h> | ||
25 | |||
26 | #define CMU_COREPLL (0x0000) | ||
27 | #define CMU_DEVPLL (0x0004) | ||
28 | #define CMU_DDRPLL (0x0008) | ||
29 | #define CMU_NANDPLL (0x000C) | ||
30 | #define CMU_DISPLAYPLL (0x0010) | ||
31 | #define CMU_AUDIOPLL (0x0014) | ||
32 | #define CMU_TVOUTPLL (0x0018) | ||
33 | #define CMU_BUSCLK (0x001C) | ||
34 | #define CMU_SENSORCLK (0x0020) | ||
35 | #define CMU_LCDCLK (0x0024) | ||
36 | #define CMU_DSIPLLCLK (0x0028) | ||
37 | #define CMU_CSICLK (0x002C) | ||
38 | #define CMU_DECLK (0x0030) | ||
39 | #define CMU_SICLK (0x0034) | ||
40 | #define CMU_BUSCLK1 (0x0038) | ||
41 | #define CMU_HDECLK (0x003C) | ||
42 | #define CMU_VDECLK (0x0040) | ||
43 | #define CMU_VCECLK (0x0044) | ||
44 | #define CMU_NANDCCLK (0x004C) | ||
45 | #define CMU_SD0CLK (0x0050) | ||
46 | #define CMU_SD1CLK (0x0054) | ||
47 | #define CMU_SD2CLK (0x0058) | ||
48 | #define CMU_UART0CLK (0x005C) | ||
49 | #define CMU_UART1CLK (0x0060) | ||
50 | #define CMU_UART2CLK (0x0064) | ||
51 | #define CMU_UART3CLK (0x0068) | ||
52 | #define CMU_UART4CLK (0x006C) | ||
53 | #define CMU_UART5CLK (0x0070) | ||
54 | #define CMU_UART6CLK (0x0074) | ||
55 | #define CMU_PWM0CLK (0x0078) | ||
56 | #define CMU_PWM1CLK (0x007C) | ||
57 | #define CMU_PWM2CLK (0x0080) | ||
58 | #define CMU_PWM3CLK (0x0084) | ||
59 | #define CMU_PWM4CLK (0x0088) | ||
60 | #define CMU_PWM5CLK (0x008C) | ||
61 | #define CMU_GPU3DCLK (0x0090) | ||
62 | #define CMU_CORECTL (0x009C) | ||
63 | #define CMU_DEVCLKEN0 (0x00A0) | ||
64 | #define CMU_DEVCLKEN1 (0x00A4) | ||
65 | #define CMU_DEVRST0 (0x00A8) | ||
66 | #define CMU_DEVRST1 (0x00AC) | ||
67 | #define CMU_USBPLL (0x00B0) | ||
68 | #define CMU_ETHERNETPLL (0x00B4) | ||
69 | #define CMU_CVBSPLL (0x00B8) | ||
70 | #define CMU_SSTSCLK (0x00C0) | ||
71 | |||
72 | static struct clk_pll_table clk_audio_pll_table[] = { | ||
73 | {0, 45158400}, {1, 49152000}, | ||
74 | {0, 0}, | ||
75 | }; | ||
76 | |||
77 | static struct clk_pll_table clk_cvbs_pll_table[] = { | ||
78 | {27, 29 * 12000000}, {28, 30 * 12000000}, {29, 31 * 12000000}, | ||
79 | {30, 32 * 12000000}, {31, 33 * 12000000}, {32, 34 * 12000000}, | ||
80 | {33, 35 * 12000000}, {34, 36 * 12000000}, {35, 37 * 12000000}, | ||
81 | {36, 38 * 12000000}, {37, 39 * 12000000}, {38, 40 * 12000000}, | ||
82 | {39, 41 * 12000000}, {40, 42 * 12000000}, {41, 43 * 12000000}, | ||
83 | {42, 44 * 12000000}, {43, 45 * 12000000}, {0, 0}, | ||
84 | }; | ||
85 | |||
86 | /* pll clocks */ | ||
87 | static OWL_PLL_NO_PARENT(clk_core_pll, "core_pll", CMU_COREPLL, 12000000, 9, 0, 8, 4, 174, NULL, CLK_IGNORE_UNUSED); | ||
88 | static OWL_PLL_NO_PARENT(clk_dev_pll, "dev_pll", CMU_DEVPLL, 6000000, 8, 0, 8, 8, 126, NULL, CLK_IGNORE_UNUSED); | ||
89 | static OWL_PLL_NO_PARENT(clk_ddr_pll, "ddr_pll", CMU_DDRPLL, 6000000, 8, 0, 8, 2, 180, NULL, CLK_IGNORE_UNUSED); | ||
90 | static OWL_PLL_NO_PARENT(clk_nand_pll, "nand_pll", CMU_NANDPLL, 6000000, 8, 0, 8, 2, 86, NULL, CLK_IGNORE_UNUSED); | ||
91 | static OWL_PLL_NO_PARENT(clk_display_pll, "display_pll", CMU_DISPLAYPLL, 6000000, 8, 0, 8, 2, 140, NULL, CLK_IGNORE_UNUSED); | ||
92 | static OWL_PLL_NO_PARENT(clk_cvbs_pll, "cvbs_pll", CMU_CVBSPLL, 0, 8, 0, 8, 27, 43, clk_cvbs_pll_table, CLK_IGNORE_UNUSED); | ||
93 | static OWL_PLL_NO_PARENT(clk_audio_pll, "audio_pll", CMU_AUDIOPLL, 0, 4, 0, 1, 0, 0, clk_audio_pll_table, CLK_IGNORE_UNUSED); | ||
94 | static OWL_PLL_NO_PARENT(clk_ethernet_pll, "ethernet_pll", CMU_ETHERNETPLL, 500000000, 0, 0, 0, 0, 0, NULL, CLK_IGNORE_UNUSED); | ||
95 | |||
96 | static const char *cpu_clk_mux_p[] = {"losc", "hosc", "core_pll", "noc1_clk_div"}; | ||
97 | static const char *dev_clk_p[] = { "hosc", "dev_pll"}; | ||
98 | static const char *noc_clk_mux_p[] = { "dev_clk", "display_pll", "nand_pll", "ddr_pll", "cvbs_pll"}; | ||
99 | |||
100 | static const char *csi_clk_mux_p[] = { "display_pll", "dev_clk"}; | ||
101 | static const char *de_clk_mux_p[] = { "display_pll", "dev_clk"}; | ||
102 | static const char *hde_clk_mux_p[] = { "dev_clk", "display_pll", "nand_pll", "ddr_pll"}; | ||
103 | static const char *nand_clk_mux_p[] = { "nand_pll", "display_pll", "dev_clk", "ddr_pll"}; | ||
104 | static const char *sd_clk_mux_p[] = { "dev_clk", "nand_pll", }; | ||
105 | static const char *uart_clk_mux_p[] = { "hosc", "dev_pll"}; | ||
106 | static const char *pwm_clk_mux_p[] = { "losc", "hosc"}; | ||
107 | static const char *gpu_clk_mux_p[] = { "dev_clk", "display_pll", "nand_pll", "ddr_clk", "cvbs_pll"}; | ||
108 | static const char *lcd_clk_mux_p[] = { "display_pll", "dev_clk" }; | ||
109 | static const char *i2s_clk_mux_p[] = { "audio_pll" }; | ||
110 | static const char *sensor_clk_mux_p[] = { "hosc", "si"}; | ||
111 | |||
112 | /* mux clocks */ | ||
113 | static OWL_MUX(clk_cpu, "cpu_clk", cpu_clk_mux_p, CMU_BUSCLK, 0, 2, CLK_SET_RATE_PARENT); | ||
114 | static OWL_MUX(clk_dev, "dev_clk", dev_clk_p, CMU_DEVPLL, 12, 1, CLK_SET_RATE_PARENT); | ||
115 | static OWL_MUX(clk_noc0_clk_mux, "noc0_clk_mux", noc_clk_mux_p, CMU_BUSCLK, 4, 3, CLK_SET_RATE_PARENT); | ||
116 | static OWL_MUX(clk_noc1_clk_mux, "noc1_clk_mux", noc_clk_mux_p, CMU_BUSCLK1, 4, 3, CLK_SET_RATE_PARENT); | ||
117 | static OWL_MUX(clk_hp_clk_mux, "hp_clk_mux", noc_clk_mux_p, CMU_BUSCLK1, 8, 3, CLK_SET_RATE_PARENT); | ||
118 | |||
119 | static struct clk_factor_table sd_factor_table[] = { | ||
120 | /* bit0 ~ 4 */ | ||
121 | {0, 1, 1}, {1, 1, 2}, {2, 1, 3}, {3, 1, 4}, | ||
122 | {4, 1, 5}, {5, 1, 6}, {6, 1, 7}, {7, 1, 8}, | ||
123 | {8, 1, 9}, {9, 1, 10}, {10, 1, 11}, {11, 1, 12}, | ||
124 | {12, 1, 13}, {13, 1, 14}, {14, 1, 15}, {15, 1, 16}, | ||
125 | {16, 1, 17}, {17, 1, 18}, {18, 1, 19}, {19, 1, 20}, | ||
126 | {20, 1, 21}, {21, 1, 22}, {22, 1, 23}, {23, 1, 24}, | ||
127 | {24, 1, 25}, {25, 1, 26}, | ||
128 | |||
129 | /* bit8: /128 */ | ||
130 | {256, 1, 1 * 128}, {257, 1, 2 * 128}, {258, 1, 3 * 128}, {259, 1, 4 * 128}, | ||
131 | {260, 1, 5 * 128}, {261, 1, 6 * 128}, {262, 1, 7 * 128}, {263, 1, 8 * 128}, | ||
132 | {264, 1, 9 * 128}, {265, 1, 10 * 128}, {266, 1, 11 * 128}, {267, 1, 12 * 128}, | ||
133 | {268, 1, 13 * 128}, {269, 1, 14 * 128}, {270, 1, 15 * 128}, {271, 1, 16 * 128}, | ||
134 | {272, 1, 17 * 128}, {273, 1, 18 * 128}, {274, 1, 19 * 128}, {275, 1, 20 * 128}, | ||
135 | {276, 1, 21 * 128}, {277, 1, 22 * 128}, {278, 1, 23 * 128}, {279, 1, 24 * 128}, | ||
136 | {280, 1, 25 * 128}, {281, 1, 26 * 128}, | ||
137 | |||
138 | {0, 0}, | ||
139 | }; | ||
140 | |||
141 | static struct clk_factor_table lcd_factor_table[] = { | ||
142 | /* bit0 ~ 3 */ | ||
143 | {0, 1, 1}, {1, 1, 2}, {2, 1, 3}, {3, 1, 4}, | ||
144 | {4, 1, 5}, {5, 1, 6}, {6, 1, 7}, {7, 1, 8}, | ||
145 | {8, 1, 9}, {9, 1, 10}, {10, 1, 11}, {11, 1, 12}, | ||
146 | |||
147 | /* bit8: /7 */ | ||
148 | {256, 1, 1 * 7}, {257, 1, 2 * 7}, {258, 1, 3 * 7}, {259, 1, 4 * 7}, | ||
149 | {260, 1, 5 * 7}, {261, 1, 6 * 7}, {262, 1, 7 * 7}, {263, 1, 8 * 7}, | ||
150 | {264, 1, 9 * 7}, {265, 1, 10 * 7}, {266, 1, 11 * 7}, {267, 1, 12 * 7}, | ||
151 | {0, 0}, | ||
152 | }; | ||
153 | |||
154 | static struct clk_div_table hdmia_div_table[] = { | ||
155 | {0, 1}, {1, 2}, {2, 3}, {3, 4}, | ||
156 | {4, 6}, {5, 8}, {6, 12}, {7, 16}, | ||
157 | {8, 24}, | ||
158 | {0, 0}, | ||
159 | }; | ||
160 | |||
161 | static struct clk_div_table rmii_div_table[] = { | ||
162 | {0, 4}, {1, 10}, | ||
163 | }; | ||
164 | |||
165 | /* divider clocks */ | ||
166 | static OWL_DIVIDER(clk_noc0, "noc0_clk", "noc0_clk_mux", CMU_BUSCLK, 16, 2, NULL, 0, 0); | ||
167 | static OWL_DIVIDER(clk_noc1, "noc1_clk", "noc1_clk_mux", CMU_BUSCLK1, 16, 2, NULL, 0, 0); | ||
168 | static OWL_DIVIDER(clk_noc1_clk_div, "noc1_clk_div", "noc1_clk", CMU_BUSCLK1, 20, 1, NULL, 0, 0); | ||
169 | static OWL_DIVIDER(clk_hp_clk_div, "hp_clk_div", "hp_clk_mux", CMU_BUSCLK1, 12, 2, NULL, 0, 0); | ||
170 | static OWL_DIVIDER(clk_ahb, "ahb_clk", "hp_clk_div", CMU_BUSCLK1, 2, 2, NULL, 0, 0); | ||
171 | static OWL_DIVIDER(clk_apb, "apb_clk", "ahb_clk", CMU_BUSCLK1, 14, 2, NULL, 0, 0); | ||
172 | static OWL_DIVIDER(clk_sensor0, "sensor0", "sensor_src", CMU_SENSORCLK, 0, 4, NULL, 0, 0); | ||
173 | static OWL_DIVIDER(clk_sensor1, "sensor1", "sensor_src", CMU_SENSORCLK, 8, 4, NULL, 0, 0); | ||
174 | static OWL_DIVIDER(clk_rmii_ref, "rmii_ref", "ethernet_pll", CMU_ETHERNETPLL, 2, 1, rmii_div_table, 0, 0); | ||
175 | |||
176 | static struct clk_factor_table de_factor_table[] = { | ||
177 | {0, 1, 1}, {1, 2, 3}, {2, 1, 2}, {3, 2, 5}, | ||
178 | {4, 1, 3}, {5, 1, 4}, {6, 1, 6}, {7, 1, 8}, | ||
179 | {8, 1, 12}, {0, 0, 0}, | ||
180 | }; | ||
181 | |||
182 | static struct clk_factor_table hde_factor_table[] = { | ||
183 | {0, 1, 1}, {1, 2, 3}, {2, 1, 2}, {3, 2, 5}, | ||
184 | {4, 1, 3}, {5, 1, 4}, {6, 1, 6}, {7, 1, 8}, | ||
185 | {0, 0, 0}, | ||
186 | }; | ||
187 | |||
188 | /* gate clocks */ | ||
189 | static OWL_GATE(clk_gpio, "gpio", "apb_clk", CMU_DEVCLKEN1, 25, 0, 0); | ||
190 | static OWL_GATE(clk_dmac, "dmac", "hp_clk_div", CMU_DEVCLKEN0, 17, 0, 0); | ||
191 | static OWL_GATE(clk_timer, "timer", "hosc", CMU_DEVCLKEN1, 22, 0, 0); | ||
192 | static OWL_GATE_NO_PARENT(clk_dsi, "dsi_clk", CMU_DEVCLKEN0, 2, 0, 0); | ||
193 | static OWL_GATE_NO_PARENT(clk_tvout, "tvout_clk", CMU_DEVCLKEN0, 3, 0, 0); | ||
194 | static OWL_GATE_NO_PARENT(clk_hdmi_dev, "hdmi_dev", CMU_DEVCLKEN0, 5, 0, 0); | ||
195 | static OWL_GATE_NO_PARENT(clk_usb3_480mpll0, "usb3_480mpll0", CMU_USBPLL, 3, 0, 0); | ||
196 | static OWL_GATE_NO_PARENT(clk_usb3_480mphy0, "usb3_480mphy0", CMU_USBPLL, 2, 0, 0); | ||
197 | static OWL_GATE_NO_PARENT(clk_usb3_5gphy, "usb3_5gphy", CMU_USBPLL, 1, 0, 0); | ||
198 | static OWL_GATE_NO_PARENT(clk_usb3_cce, "usb3_cce", CMU_DEVCLKEN0, 25, 0, 0); | ||
199 | static OWL_GATE(clk_i2c0, "i2c0", "hosc", CMU_DEVCLKEN1, 0, 0, 0); | ||
200 | static OWL_GATE(clk_i2c1, "i2c1", "hosc", CMU_DEVCLKEN1, 1, 0, 0); | ||
201 | static OWL_GATE(clk_i2c2, "i2c2", "hosc", CMU_DEVCLKEN1, 2, 0, 0); | ||
202 | static OWL_GATE(clk_i2c3, "i2c3", "hosc", CMU_DEVCLKEN1, 3, 0, 0); | ||
203 | static OWL_GATE(clk_spi0, "spi0", "ahb_clk", CMU_DEVCLKEN1, 4, 0, 0); | ||
204 | static OWL_GATE(clk_spi1, "spi1", "ahb_clk", CMU_DEVCLKEN1, 5, 0, 0); | ||
205 | static OWL_GATE(clk_spi2, "spi2", "ahb_clk", CMU_DEVCLKEN1, 6, 0, 0); | ||
206 | static OWL_GATE(clk_spi3, "spi3", "ahb_clk", CMU_DEVCLKEN1, 7, 0, 0); | ||
207 | static OWL_GATE_NO_PARENT(clk_usb2h0_pllen, "usbh0_pllen", CMU_USBPLL, 12, 0, 0); | ||
208 | static OWL_GATE_NO_PARENT(clk_usb2h0_phy, "usbh0_phy", CMU_USBPLL, 10, 0, 0); | ||
209 | static OWL_GATE_NO_PARENT(clk_usb2h0_cce, "usbh0_cce", CMU_DEVCLKEN0, 26, 0, 0); | ||
210 | static OWL_GATE_NO_PARENT(clk_usb2h1_pllen, "usbh1_pllen", CMU_USBPLL, 13, 0, 0); | ||
211 | static OWL_GATE_NO_PARENT(clk_usb2h1_phy, "usbh1_phy", CMU_USBPLL, 11, 0, 0); | ||
212 | static OWL_GATE_NO_PARENT(clk_usb2h1_cce, "usbh1_cce", CMU_DEVCLKEN0, 27, 0, 0); | ||
213 | static OWL_GATE_NO_PARENT(clk_irc_switch, "irc_switch", CMU_DEVCLKEN1, 15, 0, 0); | ||
214 | |||
215 | /* composite clocks */ | ||
216 | |||
217 | static OWL_COMP_DIV(clk_csi, "csi", csi_clk_mux_p, | ||
218 | OWL_MUX_HW(CMU_CSICLK, 4, 1), | ||
219 | OWL_GATE_HW(CMU_DEVCLKEN0, 13, 0), | ||
220 | OWL_DIVIDER_HW(CMU_CSICLK, 0, 4, 0, NULL), | ||
221 | 0); | ||
222 | |||
223 | static OWL_COMP_DIV(clk_si, "si", csi_clk_mux_p, | ||
224 | OWL_MUX_HW(CMU_SICLK, 4, 1), | ||
225 | OWL_GATE_HW(CMU_DEVCLKEN0, 14, 0), | ||
226 | OWL_DIVIDER_HW(CMU_SICLK, 0, 4, 0, NULL), | ||
227 | 0); | ||
228 | |||
229 | static OWL_COMP_FACTOR(clk_de, "de", de_clk_mux_p, | ||
230 | OWL_MUX_HW(CMU_DECLK, 12, 1), | ||
231 | OWL_GATE_HW(CMU_DEVCLKEN0, 0, 0), | ||
232 | OWL_FACTOR_HW(CMU_DECLK, 0, 3, 0, de_factor_table), | ||
233 | 0); | ||
234 | |||
235 | static OWL_COMP_FACTOR(clk_hde, "hde", hde_clk_mux_p, | ||
236 | OWL_MUX_HW(CMU_HDECLK, 4, 2), | ||
237 | OWL_GATE_HW(CMU_DEVCLKEN0, 9, 0), | ||
238 | OWL_FACTOR_HW(CMU_HDECLK, 0, 3, 0, hde_factor_table), | ||
239 | 0); | ||
240 | |||
241 | static OWL_COMP_FACTOR(clk_vde, "vde", hde_clk_mux_p, | ||
242 | OWL_MUX_HW(CMU_VDECLK, 4, 2), | ||
243 | OWL_GATE_HW(CMU_DEVCLKEN0, 10, 0), | ||
244 | OWL_FACTOR_HW(CMU_VDECLK, 0, 3, 0, hde_factor_table), | ||
245 | 0); | ||
246 | |||
247 | static OWL_COMP_FACTOR(clk_vce, "vce", hde_clk_mux_p, | ||
248 | OWL_MUX_HW(CMU_VCECLK, 4, 2), | ||
249 | OWL_GATE_HW(CMU_DEVCLKEN0, 11, 0), | ||
250 | OWL_FACTOR_HW(CMU_VCECLK, 0, 3, 0, hde_factor_table), | ||
251 | 0); | ||
252 | |||
253 | static OWL_COMP_DIV(clk_nand, "nand", nand_clk_mux_p, | ||
254 | OWL_MUX_HW(CMU_NANDCCLK, 8, 2), | ||
255 | OWL_GATE_HW(CMU_DEVCLKEN0, 21, 0), | ||
256 | OWL_DIVIDER_HW(CMU_NANDCCLK, 0, 3, 0, NULL), | ||
257 | CLK_SET_RATE_PARENT); | ||
258 | |||
259 | static OWL_COMP_FACTOR(clk_sd0, "sd0", sd_clk_mux_p, | ||
260 | OWL_MUX_HW(CMU_SD0CLK, 9, 1), | ||
261 | OWL_GATE_HW(CMU_DEVCLKEN0, 22, 0), | ||
262 | OWL_FACTOR_HW(CMU_SD0CLK, 0, 9, 0, sd_factor_table), | ||
263 | 0); | ||
264 | |||
265 | static OWL_COMP_FACTOR(clk_sd1, "sd1", sd_clk_mux_p, | ||
266 | OWL_MUX_HW(CMU_SD1CLK, 9, 1), | ||
267 | OWL_GATE_HW(CMU_DEVCLKEN0, 23, 0), | ||
268 | OWL_FACTOR_HW(CMU_SD1CLK, 0, 9, 0, sd_factor_table), | ||
269 | 0); | ||
270 | |||
271 | static OWL_COMP_FACTOR(clk_sd2, "sd2", sd_clk_mux_p, | ||
272 | OWL_MUX_HW(CMU_SD2CLK, 9, 1), | ||
273 | OWL_GATE_HW(CMU_DEVCLKEN0, 24, 0), | ||
274 | OWL_FACTOR_HW(CMU_SD2CLK, 0, 9, 0, sd_factor_table), | ||
275 | 0); | ||
276 | |||
277 | static OWL_COMP_DIV(clk_uart0, "uart0", uart_clk_mux_p, | ||
278 | OWL_MUX_HW(CMU_UART0CLK, 16, 1), | ||
279 | OWL_GATE_HW(CMU_DEVCLKEN1, 8, 0), | ||
280 | OWL_DIVIDER_HW(CMU_UART0CLK, 0, 9, CLK_DIVIDER_ROUND_CLOSEST, NULL), | ||
281 | 0); | ||
282 | |||
283 | static OWL_COMP_DIV(clk_uart1, "uart1", uart_clk_mux_p, | ||
284 | OWL_MUX_HW(CMU_UART1CLK, 16, 1), | ||
285 | OWL_GATE_HW(CMU_DEVCLKEN1, 9, 0), | ||
286 | OWL_DIVIDER_HW(CMU_UART1CLK, 0, 9, CLK_DIVIDER_ROUND_CLOSEST, NULL), | ||
287 | 0); | ||
288 | |||
289 | static OWL_COMP_DIV(clk_uart2, "uart2", uart_clk_mux_p, | ||
290 | OWL_MUX_HW(CMU_UART2CLK, 16, 1), | ||
291 | OWL_GATE_HW(CMU_DEVCLKEN1, 10, 0), | ||
292 | OWL_DIVIDER_HW(CMU_UART2CLK, 0, 9, CLK_DIVIDER_ROUND_CLOSEST, NULL), | ||
293 | 0); | ||
294 | |||
295 | static OWL_COMP_DIV(clk_uart3, "uart3", uart_clk_mux_p, | ||
296 | OWL_MUX_HW(CMU_UART3CLK, 16, 1), | ||
297 | OWL_GATE_HW(CMU_DEVCLKEN1, 11, 0), | ||
298 | OWL_DIVIDER_HW(CMU_UART3CLK, 0, 9, CLK_DIVIDER_ROUND_CLOSEST, NULL), | ||
299 | 0); | ||
300 | |||
301 | static OWL_COMP_DIV(clk_uart4, "uart4", uart_clk_mux_p, | ||
302 | OWL_MUX_HW(CMU_UART4CLK, 16, 1), | ||
303 | OWL_GATE_HW(CMU_DEVCLKEN1, 12, 0), | ||
304 | OWL_DIVIDER_HW(CMU_UART4CLK, 0, 9, CLK_DIVIDER_ROUND_CLOSEST, NULL), | ||
305 | 0); | ||
306 | |||
307 | static OWL_COMP_DIV(clk_uart5, "uart5", uart_clk_mux_p, | ||
308 | OWL_MUX_HW(CMU_UART5CLK, 16, 1), | ||
309 | OWL_GATE_HW(CMU_DEVCLKEN1, 13, 0), | ||
310 | OWL_DIVIDER_HW(CMU_UART5CLK, 0, 9, CLK_DIVIDER_ROUND_CLOSEST, NULL), | ||
311 | 0); | ||
312 | |||
313 | static OWL_COMP_DIV(clk_uart6, "uart6", uart_clk_mux_p, | ||
314 | OWL_MUX_HW(CMU_UART6CLK, 16, 1), | ||
315 | OWL_GATE_HW(CMU_DEVCLKEN1, 14, 0), | ||
316 | OWL_DIVIDER_HW(CMU_UART6CLK, 0, 9, CLK_DIVIDER_ROUND_CLOSEST, NULL), | ||
317 | 0); | ||
318 | |||
319 | static OWL_COMP_DIV(clk_pwm0, "pwm0", pwm_clk_mux_p, | ||
320 | OWL_MUX_HW(CMU_PWM0CLK, 12, 1), | ||
321 | OWL_GATE_HW(CMU_DEVCLKEN1, 16, 0), | ||
322 | OWL_DIVIDER_HW(CMU_PWM0CLK, 0, 10, 0, NULL), | ||
323 | CLK_IGNORE_UNUSED); | ||
324 | |||
325 | static OWL_COMP_DIV(clk_pwm1, "pwm1", pwm_clk_mux_p, | ||
326 | OWL_MUX_HW(CMU_PWM1CLK, 12, 1), | ||
327 | OWL_GATE_HW(CMU_DEVCLKEN1, 17, 0), | ||
328 | OWL_DIVIDER_HW(CMU_PWM1CLK, 0, 10, 0, NULL), | ||
329 | 0); | ||
330 | |||
331 | static OWL_COMP_DIV(clk_pwm2, "pwm2", pwm_clk_mux_p, | ||
332 | OWL_MUX_HW(CMU_PWM2CLK, 12, 1), | ||
333 | OWL_GATE_HW(CMU_DEVCLKEN1, 18, 0), | ||
334 | OWL_DIVIDER_HW(CMU_PWM2CLK, 0, 10, 0, NULL), | ||
335 | 0); | ||
336 | |||
337 | static OWL_COMP_DIV(clk_pwm3, "pwm3", pwm_clk_mux_p, | ||
338 | OWL_MUX_HW(CMU_PWM3CLK, 12, 1), | ||
339 | OWL_GATE_HW(CMU_DEVCLKEN1, 19, 0), | ||
340 | OWL_DIVIDER_HW(CMU_PWM3CLK, 0, 10, 0, NULL), | ||
341 | 0); | ||
342 | |||
343 | static OWL_COMP_DIV(clk_pwm4, "pwm4", pwm_clk_mux_p, | ||
344 | OWL_MUX_HW(CMU_PWM4CLK, 12, 1), | ||
345 | OWL_GATE_HW(CMU_DEVCLKEN1, 20, 0), | ||
346 | OWL_DIVIDER_HW(CMU_PWM4CLK, 0, 10, 0, NULL), | ||
347 | 0); | ||
348 | |||
349 | static OWL_COMP_DIV(clk_pwm5, "pwm5", pwm_clk_mux_p, | ||
350 | OWL_MUX_HW(CMU_PWM5CLK, 12, 1), | ||
351 | OWL_GATE_HW(CMU_DEVCLKEN1, 21, 0), | ||
352 | OWL_DIVIDER_HW(CMU_PWM5CLK, 0, 10, 0, NULL), | ||
353 | 0); | ||
354 | |||
355 | static OWL_COMP_FACTOR(clk_gpu3d, "gpu3d", gpu_clk_mux_p, | ||
356 | OWL_MUX_HW(CMU_GPU3DCLK, 4, 3), | ||
357 | OWL_GATE_HW(CMU_DEVCLKEN0, 8, 0), | ||
358 | OWL_FACTOR_HW(CMU_GPU3DCLK, 0, 3, 0, hde_factor_table), | ||
359 | 0); | ||
360 | |||
361 | static OWL_COMP_FACTOR(clk_lcd, "lcd", lcd_clk_mux_p, | ||
362 | OWL_MUX_HW(CMU_LCDCLK, 12, 2), | ||
363 | OWL_GATE_HW(CMU_DEVCLKEN0, 1, 0), | ||
364 | OWL_FACTOR_HW(CMU_LCDCLK, 0, 9, 0, lcd_factor_table), | ||
365 | 0); | ||
366 | |||
367 | static OWL_COMP_DIV(clk_hdmi_audio, "hdmia", i2s_clk_mux_p, | ||
368 | OWL_MUX_HW(CMU_AUDIOPLL, 24, 1), /*CMU_AUDIOPLL 24,1 unused*/ | ||
369 | OWL_GATE_HW(CMU_DEVCLKEN1, 28, 0), | ||
370 | OWL_DIVIDER_HW(CMU_AUDIOPLL, 24, 4, 0, hdmia_div_table), | ||
371 | 0); | ||
372 | |||
373 | static OWL_COMP_DIV(clk_i2srx, "i2srx", i2s_clk_mux_p, | ||
374 | OWL_MUX_HW(CMU_AUDIOPLL, 24, 1), | ||
375 | OWL_GATE_HW(CMU_DEVCLKEN1, 27, 0), | ||
376 | OWL_DIVIDER_HW(CMU_AUDIOPLL, 20, 4, 0, hdmia_div_table), | ||
377 | 0); | ||
378 | |||
379 | static OWL_COMP_DIV(clk_i2stx, "i2stx", i2s_clk_mux_p, | ||
380 | OWL_MUX_HW(CMU_AUDIOPLL, 24, 1), | ||
381 | OWL_GATE_HW(CMU_DEVCLKEN1, 26, 0), | ||
382 | OWL_DIVIDER_HW(CMU_AUDIOPLL, 16, 4, 0, hdmia_div_table), | ||
383 | 0); | ||
384 | |||
385 | /* for bluetooth pcm communication */ | ||
386 | static OWL_COMP_FIXED_FACTOR(clk_pcm1, "pcm1", "audio_pll", | ||
387 | OWL_GATE_HW(CMU_DEVCLKEN1, 31, 0), | ||
388 | 1, 2, 0); | ||
389 | |||
390 | static OWL_COMP_DIV(clk_sensor_src, "sensor_src", sensor_clk_mux_p, | ||
391 | OWL_MUX_HW(CMU_SENSORCLK, 4, 1), | ||
392 | {0}, | ||
393 | OWL_DIVIDER_HW(CMU_SENSORCLK, 5, 2, 0, NULL), | ||
394 | 0); | ||
395 | |||
396 | static OWL_COMP_FIXED_FACTOR(clk_ethernet, "ethernet", "ethernet_pll", | ||
397 | OWL_GATE_HW(CMU_DEVCLKEN1, 23, 0), | ||
398 | 1, 20, 0); | ||
399 | |||
400 | static OWL_COMP_DIV_FIXED(clk_thermal_sensor, "thermal_sensor", "hosc", | ||
401 | OWL_GATE_HW(CMU_DEVCLKEN0, 31, 0), | ||
402 | OWL_DIVIDER_HW(CMU_SSTSCLK, 20, 10, 0, NULL), | ||
403 | 0); | ||
404 | |||
405 | static struct owl_clk_common *s700_clks[] = { | ||
406 | &clk_core_pll.common, | ||
407 | &clk_dev_pll.common, | ||
408 | &clk_ddr_pll.common, | ||
409 | &clk_nand_pll.common, | ||
410 | &clk_display_pll.common, | ||
411 | &clk_cvbs_pll .common, | ||
412 | &clk_audio_pll.common, | ||
413 | &clk_ethernet_pll.common, | ||
414 | &clk_cpu.common, | ||
415 | &clk_dev.common, | ||
416 | &clk_ahb.common, | ||
417 | &clk_apb.common, | ||
418 | &clk_dmac.common, | ||
419 | &clk_noc0_clk_mux.common, | ||
420 | &clk_noc1_clk_mux.common, | ||
421 | &clk_hp_clk_mux.common, | ||
422 | &clk_hp_clk_div.common, | ||
423 | &clk_noc1_clk_div.common, | ||
424 | &clk_noc0.common, | ||
425 | &clk_noc1.common, | ||
426 | &clk_sensor_src.common, | ||
427 | &clk_gpio.common, | ||
428 | &clk_timer.common, | ||
429 | &clk_dsi.common, | ||
430 | &clk_csi.common, | ||
431 | &clk_si.common, | ||
432 | &clk_de.common, | ||
433 | &clk_hde.common, | ||
434 | &clk_vde.common, | ||
435 | &clk_vce.common, | ||
436 | &clk_nand.common, | ||
437 | &clk_sd0.common, | ||
438 | &clk_sd1.common, | ||
439 | &clk_sd2.common, | ||
440 | &clk_uart0.common, | ||
441 | &clk_uart1.common, | ||
442 | &clk_uart2.common, | ||
443 | &clk_uart3.common, | ||
444 | &clk_uart4.common, | ||
445 | &clk_uart5.common, | ||
446 | &clk_uart6.common, | ||
447 | &clk_pwm0.common, | ||
448 | &clk_pwm1.common, | ||
449 | &clk_pwm2.common, | ||
450 | &clk_pwm3.common, | ||
451 | &clk_pwm4.common, | ||
452 | &clk_pwm5.common, | ||
453 | &clk_gpu3d.common, | ||
454 | &clk_i2c0.common, | ||
455 | &clk_i2c1.common, | ||
456 | &clk_i2c2.common, | ||
457 | &clk_i2c3.common, | ||
458 | &clk_spi0.common, | ||
459 | &clk_spi1.common, | ||
460 | &clk_spi2.common, | ||
461 | &clk_spi3.common, | ||
462 | &clk_usb3_480mpll0.common, | ||
463 | &clk_usb3_480mphy0.common, | ||
464 | &clk_usb3_5gphy.common, | ||
465 | &clk_usb3_cce.common, | ||
466 | &clk_lcd.common, | ||
467 | &clk_hdmi_audio.common, | ||
468 | &clk_i2srx.common, | ||
469 | &clk_i2stx.common, | ||
470 | &clk_sensor0.common, | ||
471 | &clk_sensor1.common, | ||
472 | &clk_hdmi_dev.common, | ||
473 | &clk_ethernet.common, | ||
474 | &clk_rmii_ref.common, | ||
475 | &clk_usb2h0_pllen.common, | ||
476 | &clk_usb2h0_phy.common, | ||
477 | &clk_usb2h0_cce.common, | ||
478 | &clk_usb2h1_pllen.common, | ||
479 | &clk_usb2h1_phy.common, | ||
480 | &clk_usb2h1_cce.common, | ||
481 | &clk_tvout.common, | ||
482 | &clk_thermal_sensor.common, | ||
483 | &clk_irc_switch.common, | ||
484 | &clk_pcm1.common, | ||
485 | }; | ||
486 | |||
487 | static struct clk_hw_onecell_data s700_hw_clks = { | ||
488 | .hws = { | ||
489 | [CLK_CORE_PLL] = &clk_core_pll.common.hw, | ||
490 | [CLK_DEV_PLL] = &clk_dev_pll.common.hw, | ||
491 | [CLK_DDR_PLL] = &clk_ddr_pll.common.hw, | ||
492 | [CLK_NAND_PLL] = &clk_nand_pll.common.hw, | ||
493 | [CLK_DISPLAY_PLL] = &clk_display_pll.common.hw, | ||
494 | [CLK_CVBS_PLL] = &clk_cvbs_pll .common.hw, | ||
495 | [CLK_AUDIO_PLL] = &clk_audio_pll.common.hw, | ||
496 | [CLK_ETHERNET_PLL] = &clk_ethernet_pll.common.hw, | ||
497 | [CLK_CPU] = &clk_cpu.common.hw, | ||
498 | [CLK_DEV] = &clk_dev.common.hw, | ||
499 | [CLK_AHB] = &clk_ahb.common.hw, | ||
500 | [CLK_APB] = &clk_apb.common.hw, | ||
501 | [CLK_DMAC] = &clk_dmac.common.hw, | ||
502 | [CLK_NOC0_CLK_MUX] = &clk_noc0_clk_mux.common.hw, | ||
503 | [CLK_NOC1_CLK_MUX] = &clk_noc1_clk_mux.common.hw, | ||
504 | [CLK_HP_CLK_MUX] = &clk_hp_clk_mux.common.hw, | ||
505 | [CLK_HP_CLK_DIV] = &clk_hp_clk_div.common.hw, | ||
506 | [CLK_NOC1_CLK_DIV] = &clk_noc1_clk_div.common.hw, | ||
507 | [CLK_NOC0] = &clk_noc0.common.hw, | ||
508 | [CLK_NOC1] = &clk_noc1.common.hw, | ||
509 | [CLK_SENOR_SRC] = &clk_sensor_src.common.hw, | ||
510 | [CLK_GPIO] = &clk_gpio.common.hw, | ||
511 | [CLK_TIMER] = &clk_timer.common.hw, | ||
512 | [CLK_DSI] = &clk_dsi.common.hw, | ||
513 | [CLK_CSI] = &clk_csi.common.hw, | ||
514 | [CLK_SI] = &clk_si.common.hw, | ||
515 | [CLK_DE] = &clk_de.common.hw, | ||
516 | [CLK_HDE] = &clk_hde.common.hw, | ||
517 | [CLK_VDE] = &clk_vde.common.hw, | ||
518 | [CLK_VCE] = &clk_vce.common.hw, | ||
519 | [CLK_NAND] = &clk_nand.common.hw, | ||
520 | [CLK_SD0] = &clk_sd0.common.hw, | ||
521 | [CLK_SD1] = &clk_sd1.common.hw, | ||
522 | [CLK_SD2] = &clk_sd2.common.hw, | ||
523 | [CLK_UART0] = &clk_uart0.common.hw, | ||
524 | [CLK_UART1] = &clk_uart1.common.hw, | ||
525 | [CLK_UART2] = &clk_uart2.common.hw, | ||
526 | [CLK_UART3] = &clk_uart3.common.hw, | ||
527 | [CLK_UART4] = &clk_uart4.common.hw, | ||
528 | [CLK_UART5] = &clk_uart5.common.hw, | ||
529 | [CLK_UART6] = &clk_uart6.common.hw, | ||
530 | [CLK_PWM0] = &clk_pwm0.common.hw, | ||
531 | [CLK_PWM1] = &clk_pwm1.common.hw, | ||
532 | [CLK_PWM2] = &clk_pwm2.common.hw, | ||
533 | [CLK_PWM3] = &clk_pwm3.common.hw, | ||
534 | [CLK_PWM4] = &clk_pwm4.common.hw, | ||
535 | [CLK_PWM5] = &clk_pwm5.common.hw, | ||
536 | [CLK_GPU3D] = &clk_gpu3d.common.hw, | ||
537 | [CLK_I2C0] = &clk_i2c0.common.hw, | ||
538 | [CLK_I2C1] = &clk_i2c1.common.hw, | ||
539 | [CLK_I2C2] = &clk_i2c2.common.hw, | ||
540 | [CLK_I2C3] = &clk_i2c3.common.hw, | ||
541 | [CLK_SPI0] = &clk_spi0.common.hw, | ||
542 | [CLK_SPI1] = &clk_spi1.common.hw, | ||
543 | [CLK_SPI2] = &clk_spi2.common.hw, | ||
544 | [CLK_SPI3] = &clk_spi3.common.hw, | ||
545 | [CLK_USB3_480MPLL0] = &clk_usb3_480mpll0.common.hw, | ||
546 | [CLK_USB3_480MPHY0] = &clk_usb3_480mphy0.common.hw, | ||
547 | [CLK_USB3_5GPHY] = &clk_usb3_5gphy.common.hw, | ||
548 | [CLK_USB3_CCE] = &clk_usb3_cce.common.hw, | ||
549 | [CLK_LCD] = &clk_lcd.common.hw, | ||
550 | [CLK_HDMI_AUDIO] = &clk_hdmi_audio.common.hw, | ||
551 | [CLK_I2SRX] = &clk_i2srx.common.hw, | ||
552 | [CLK_I2STX] = &clk_i2stx.common.hw, | ||
553 | [CLK_SENSOR0] = &clk_sensor0.common.hw, | ||
554 | [CLK_SENSOR1] = &clk_sensor1.common.hw, | ||
555 | [CLK_HDMI_DEV] = &clk_hdmi_dev.common.hw, | ||
556 | [CLK_ETHERNET] = &clk_ethernet.common.hw, | ||
557 | [CLK_RMII_REF] = &clk_rmii_ref.common.hw, | ||
558 | [CLK_USB2H0_PLLEN] = &clk_usb2h0_pllen.common.hw, | ||
559 | [CLK_USB2H0_PHY] = &clk_usb2h0_phy.common.hw, | ||
560 | [CLK_USB2H0_CCE] = &clk_usb2h0_cce.common.hw, | ||
561 | [CLK_USB2H1_PLLEN] = &clk_usb2h1_pllen.common.hw, | ||
562 | [CLK_USB2H1_PHY] = &clk_usb2h1_phy.common.hw, | ||
563 | [CLK_USB2H1_CCE] = &clk_usb2h1_cce.common.hw, | ||
564 | [CLK_TVOUT] = &clk_tvout.common.hw, | ||
565 | [CLK_THERMAL_SENSOR] = &clk_thermal_sensor.common.hw, | ||
566 | [CLK_IRC_SWITCH] = &clk_irc_switch.common.hw, | ||
567 | [CLK_PCM1] = &clk_pcm1.common.hw, | ||
568 | }, | ||
569 | .num = CLK_NR_CLKS, | ||
570 | }; | ||
571 | |||
572 | static const struct owl_clk_desc s700_clk_desc = { | ||
573 | .clks = s700_clks, | ||
574 | .num_clks = ARRAY_SIZE(s700_clks), | ||
575 | |||
576 | .hw_clks = &s700_hw_clks, | ||
577 | }; | ||
578 | |||
579 | static int s700_clk_probe(struct platform_device *pdev) | ||
580 | { | ||
581 | const struct owl_clk_desc *desc; | ||
582 | |||
583 | desc = &s700_clk_desc; | ||
584 | owl_clk_regmap_init(pdev, desc); | ||
585 | |||
586 | return owl_clk_probe(&pdev->dev, desc->hw_clks); | ||
587 | } | ||
588 | |||
589 | static const struct of_device_id s700_clk_of_match[] = { | ||
590 | { .compatible = "actions,s700-cmu", }, | ||
591 | { /* sentinel */ } | ||
592 | }; | ||
593 | |||
594 | static struct platform_driver s700_clk_driver = { | ||
595 | .probe = s700_clk_probe, | ||
596 | .driver = { | ||
597 | .name = "s700-cmu", | ||
598 | .of_match_table = s700_clk_of_match | ||
599 | }, | ||
600 | }; | ||
601 | |||
602 | static int __init s700_clk_init(void) | ||
603 | { | ||
604 | return platform_driver_register(&s700_clk_driver); | ||
605 | } | ||
606 | core_initcall(s700_clk_init); | ||
diff --git a/drivers/clk/at91/Makefile b/drivers/clk/at91/Makefile index 082596f37c1d..facc169ebb68 100644 --- a/drivers/clk/at91/Makefile +++ b/drivers/clk/at91/Makefile | |||
@@ -13,3 +13,4 @@ obj-$(CONFIG_HAVE_AT91_USB_CLK) += clk-usb.o | |||
13 | obj-$(CONFIG_HAVE_AT91_SMD) += clk-smd.o | 13 | obj-$(CONFIG_HAVE_AT91_SMD) += clk-smd.o |
14 | obj-$(CONFIG_HAVE_AT91_H32MX) += clk-h32mx.o | 14 | obj-$(CONFIG_HAVE_AT91_H32MX) += clk-h32mx.o |
15 | obj-$(CONFIG_HAVE_AT91_GENERATED_CLK) += clk-generated.o | 15 | obj-$(CONFIG_HAVE_AT91_GENERATED_CLK) += clk-generated.o |
16 | obj-$(CONFIG_HAVE_AT91_I2S_MUX_CLK) += clk-i2s-mux.o | ||
diff --git a/drivers/clk/at91/clk-i2s-mux.c b/drivers/clk/at91/clk-i2s-mux.c new file mode 100644 index 000000000000..f0c3c3079f04 --- /dev/null +++ b/drivers/clk/at91/clk-i2s-mux.c | |||
@@ -0,0 +1,116 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * Copyright (C) 2018 Microchip Technology Inc, | ||
4 | * Codrin Ciubotariu <codrin.ciubotariu@microchip.com> | ||
5 | * | ||
6 | * | ||
7 | */ | ||
8 | |||
9 | #include <linux/clk-provider.h> | ||
10 | #include <linux/of.h> | ||
11 | #include <linux/mfd/syscon.h> | ||
12 | #include <linux/regmap.h> | ||
13 | #include <linux/slab.h> | ||
14 | |||
15 | #include <soc/at91/atmel-sfr.h> | ||
16 | |||
17 | #define I2S_BUS_NR 2 | ||
18 | |||
19 | struct clk_i2s_mux { | ||
20 | struct clk_hw hw; | ||
21 | struct regmap *regmap; | ||
22 | u8 bus_id; | ||
23 | }; | ||
24 | |||
25 | #define to_clk_i2s_mux(hw) container_of(hw, struct clk_i2s_mux, hw) | ||
26 | |||
27 | static u8 clk_i2s_mux_get_parent(struct clk_hw *hw) | ||
28 | { | ||
29 | struct clk_i2s_mux *mux = to_clk_i2s_mux(hw); | ||
30 | u32 val; | ||
31 | |||
32 | regmap_read(mux->regmap, AT91_SFR_I2SCLKSEL, &val); | ||
33 | |||
34 | return (val & BIT(mux->bus_id)) >> mux->bus_id; | ||
35 | } | ||
36 | |||
37 | static int clk_i2s_mux_set_parent(struct clk_hw *hw, u8 index) | ||
38 | { | ||
39 | struct clk_i2s_mux *mux = to_clk_i2s_mux(hw); | ||
40 | |||
41 | return regmap_update_bits(mux->regmap, AT91_SFR_I2SCLKSEL, | ||
42 | BIT(mux->bus_id), index << mux->bus_id); | ||
43 | } | ||
44 | |||
45 | static const struct clk_ops clk_i2s_mux_ops = { | ||
46 | .get_parent = clk_i2s_mux_get_parent, | ||
47 | .set_parent = clk_i2s_mux_set_parent, | ||
48 | .determine_rate = __clk_mux_determine_rate, | ||
49 | }; | ||
50 | |||
51 | static struct clk_hw * __init | ||
52 | at91_clk_i2s_mux_register(struct regmap *regmap, const char *name, | ||
53 | const char * const *parent_names, | ||
54 | unsigned int num_parents, u8 bus_id) | ||
55 | { | ||
56 | struct clk_init_data init = {}; | ||
57 | struct clk_i2s_mux *i2s_ck; | ||
58 | int ret; | ||
59 | |||
60 | i2s_ck = kzalloc(sizeof(*i2s_ck), GFP_KERNEL); | ||
61 | if (!i2s_ck) | ||
62 | return ERR_PTR(-ENOMEM); | ||
63 | |||
64 | init.name = name; | ||
65 | init.ops = &clk_i2s_mux_ops; | ||
66 | init.parent_names = parent_names; | ||
67 | init.num_parents = num_parents; | ||
68 | |||
69 | i2s_ck->hw.init = &init; | ||
70 | i2s_ck->bus_id = bus_id; | ||
71 | i2s_ck->regmap = regmap; | ||
72 | |||
73 | ret = clk_hw_register(NULL, &i2s_ck->hw); | ||
74 | if (ret) { | ||
75 | kfree(i2s_ck); | ||
76 | return ERR_PTR(ret); | ||
77 | } | ||
78 | |||
79 | return &i2s_ck->hw; | ||
80 | } | ||
81 | |||
82 | static void __init of_sama5d2_clk_i2s_mux_setup(struct device_node *np) | ||
83 | { | ||
84 | struct regmap *regmap_sfr; | ||
85 | u8 bus_id; | ||
86 | const char *parent_names[2]; | ||
87 | struct device_node *i2s_mux_np; | ||
88 | struct clk_hw *hw; | ||
89 | int ret; | ||
90 | |||
91 | regmap_sfr = syscon_regmap_lookup_by_compatible("atmel,sama5d2-sfr"); | ||
92 | if (IS_ERR(regmap_sfr)) | ||
93 | return; | ||
94 | |||
95 | for_each_child_of_node(np, i2s_mux_np) { | ||
96 | if (of_property_read_u8(i2s_mux_np, "reg", &bus_id)) | ||
97 | continue; | ||
98 | |||
99 | if (bus_id > I2S_BUS_NR) | ||
100 | continue; | ||
101 | |||
102 | ret = of_clk_parent_fill(i2s_mux_np, parent_names, 2); | ||
103 | if (ret != 2) | ||
104 | continue; | ||
105 | |||
106 | hw = at91_clk_i2s_mux_register(regmap_sfr, i2s_mux_np->name, | ||
107 | parent_names, 2, bus_id); | ||
108 | if (IS_ERR(hw)) | ||
109 | continue; | ||
110 | |||
111 | of_clk_add_hw_provider(i2s_mux_np, of_clk_hw_simple_get, hw); | ||
112 | } | ||
113 | } | ||
114 | |||
115 | CLK_OF_DECLARE(sama5d2_clk_i2s_mux, "atmel,sama5d2-clk-i2s-mux", | ||
116 | of_sama5d2_clk_i2s_mux_setup); | ||
diff --git a/drivers/clk/clk-aspeed.c b/drivers/clk/clk-aspeed.c index 7b70a074095d..596136793fc4 100644 --- a/drivers/clk/clk-aspeed.c +++ b/drivers/clk/clk-aspeed.c | |||
@@ -109,7 +109,7 @@ static const struct aspeed_gate_data aspeed_gates[] = { | |||
109 | [ASPEED_CLK_GATE_RSACLK] = { 24, -1, "rsaclk-gate", NULL, 0 }, /* RSA */ | 109 | [ASPEED_CLK_GATE_RSACLK] = { 24, -1, "rsaclk-gate", NULL, 0 }, /* RSA */ |
110 | [ASPEED_CLK_GATE_UART3CLK] = { 25, -1, "uart3clk-gate", "uart", 0 }, /* UART3 */ | 110 | [ASPEED_CLK_GATE_UART3CLK] = { 25, -1, "uart3clk-gate", "uart", 0 }, /* UART3 */ |
111 | [ASPEED_CLK_GATE_UART4CLK] = { 26, -1, "uart4clk-gate", "uart", 0 }, /* UART4 */ | 111 | [ASPEED_CLK_GATE_UART4CLK] = { 26, -1, "uart4clk-gate", "uart", 0 }, /* UART4 */ |
112 | [ASPEED_CLK_GATE_SDCLKCLK] = { 27, 16, "sdclk-gate", NULL, 0 }, /* SDIO/SD */ | 112 | [ASPEED_CLK_GATE_SDCLK] = { 27, 16, "sdclk-gate", NULL, 0 }, /* SDIO/SD */ |
113 | [ASPEED_CLK_GATE_LHCCLK] = { 28, -1, "lhclk-gate", "lhclk", 0 }, /* LPC master/LPC+ */ | 113 | [ASPEED_CLK_GATE_LHCCLK] = { 28, -1, "lhclk-gate", "lhclk", 0 }, /* LPC master/LPC+ */ |
114 | }; | 114 | }; |
115 | 115 | ||
diff --git a/drivers/clk/clk-cs2000-cp.c b/drivers/clk/clk-cs2000-cp.c index a2f8c42e527a..92bc4aca0f95 100644 --- a/drivers/clk/clk-cs2000-cp.c +++ b/drivers/clk/clk-cs2000-cp.c | |||
@@ -1,12 +1,9 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
1 | /* | 2 | /* |
2 | * CS2000 -- CIRRUS LOGIC Fractional-N Clock Synthesizer & Clock Multiplier | 3 | * CS2000 -- CIRRUS LOGIC Fractional-N Clock Synthesizer & Clock Multiplier |
3 | * | 4 | * |
4 | * Copyright (C) 2015 Renesas Electronics Corporation | 5 | * Copyright (C) 2015 Renesas Electronics Corporation |
5 | * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | 6 | * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> |
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | 7 | */ |
11 | #include <linux/clk-provider.h> | 8 | #include <linux/clk-provider.h> |
12 | #include <linux/delay.h> | 9 | #include <linux/delay.h> |
diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c index a5d402de5584..20724abd38bd 100644 --- a/drivers/clk/clk-fixed-factor.c +++ b/drivers/clk/clk-fixed-factor.c | |||
@@ -177,8 +177,15 @@ static struct clk *_of_fixed_factor_clk_setup(struct device_node *node) | |||
177 | 177 | ||
178 | clk = clk_register_fixed_factor(NULL, clk_name, parent_name, flags, | 178 | clk = clk_register_fixed_factor(NULL, clk_name, parent_name, flags, |
179 | mult, div); | 179 | mult, div); |
180 | if (IS_ERR(clk)) | 180 | if (IS_ERR(clk)) { |
181 | /* | ||
182 | * If parent clock is not registered, registration would fail. | ||
183 | * Clear OF_POPULATED flag so that clock registration can be | ||
184 | * attempted again from probe function. | ||
185 | */ | ||
186 | of_node_clear_flag(node, OF_POPULATED); | ||
181 | return clk; | 187 | return clk; |
188 | } | ||
182 | 189 | ||
183 | ret = of_clk_add_provider(node, of_clk_src_simple_get, clk); | 190 | ret = of_clk_add_provider(node, of_clk_src_simple_get, clk); |
184 | if (ret) { | 191 | if (ret) { |
diff --git a/drivers/clk/clk-max9485.c b/drivers/clk/clk-max9485.c new file mode 100644 index 000000000000..5e80f3d090f3 --- /dev/null +++ b/drivers/clk/clk-max9485.c | |||
@@ -0,0 +1,387 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | |||
3 | #include <linux/module.h> | ||
4 | #include <linux/kernel.h> | ||
5 | #include <linux/clk.h> | ||
6 | #include <linux/clk-provider.h> | ||
7 | #include <linux/err.h> | ||
8 | #include <linux/errno.h> | ||
9 | #include <linux/gpio/consumer.h> | ||
10 | #include <linux/i2c.h> | ||
11 | #include <linux/regulator/consumer.h> | ||
12 | |||
13 | #include <dt-bindings/clock/maxim,max9485.h> | ||
14 | |||
15 | #define MAX9485_NUM_CLKS 4 | ||
16 | |||
17 | /* This chip has only one register of 8 bit width. */ | ||
18 | |||
19 | #define MAX9485_FS_12KHZ (0 << 0) | ||
20 | #define MAX9485_FS_32KHZ (1 << 0) | ||
21 | #define MAX9485_FS_44_1KHZ (2 << 0) | ||
22 | #define MAX9485_FS_48KHZ (3 << 0) | ||
23 | |||
24 | #define MAX9485_SCALE_256 (0 << 2) | ||
25 | #define MAX9485_SCALE_384 (1 << 2) | ||
26 | #define MAX9485_SCALE_768 (2 << 2) | ||
27 | |||
28 | #define MAX9485_DOUBLE BIT(4) | ||
29 | #define MAX9485_CLKOUT1_ENABLE BIT(5) | ||
30 | #define MAX9485_CLKOUT2_ENABLE BIT(6) | ||
31 | #define MAX9485_MCLK_ENABLE BIT(7) | ||
32 | #define MAX9485_FREQ_MASK 0x1f | ||
33 | |||
34 | struct max9485_rate { | ||
35 | unsigned long out; | ||
36 | u8 reg_value; | ||
37 | }; | ||
38 | |||
39 | /* | ||
40 | * Ordered by frequency. For frequency the hardware can generate with | ||
41 | * multiple settings, the one with lowest jitter is listed first. | ||
42 | */ | ||
43 | static const struct max9485_rate max9485_rates[] = { | ||
44 | { 3072000, MAX9485_FS_12KHZ | MAX9485_SCALE_256 }, | ||
45 | { 4608000, MAX9485_FS_12KHZ | MAX9485_SCALE_384 }, | ||
46 | { 8192000, MAX9485_FS_32KHZ | MAX9485_SCALE_256 }, | ||
47 | { 9126000, MAX9485_FS_12KHZ | MAX9485_SCALE_768 }, | ||
48 | { 11289600, MAX9485_FS_44_1KHZ | MAX9485_SCALE_256 }, | ||
49 | { 12288000, MAX9485_FS_48KHZ | MAX9485_SCALE_256 }, | ||
50 | { 12288000, MAX9485_FS_32KHZ | MAX9485_SCALE_384 }, | ||
51 | { 16384000, MAX9485_FS_32KHZ | MAX9485_SCALE_256 | MAX9485_DOUBLE }, | ||
52 | { 16934400, MAX9485_FS_44_1KHZ | MAX9485_SCALE_384 }, | ||
53 | { 18384000, MAX9485_FS_48KHZ | MAX9485_SCALE_384 }, | ||
54 | { 22579200, MAX9485_FS_44_1KHZ | MAX9485_SCALE_256 | MAX9485_DOUBLE }, | ||
55 | { 24576000, MAX9485_FS_48KHZ | MAX9485_SCALE_256 | MAX9485_DOUBLE }, | ||
56 | { 24576000, MAX9485_FS_32KHZ | MAX9485_SCALE_384 | MAX9485_DOUBLE }, | ||
57 | { 24576000, MAX9485_FS_32KHZ | MAX9485_SCALE_768 }, | ||
58 | { 33868800, MAX9485_FS_44_1KHZ | MAX9485_SCALE_384 | MAX9485_DOUBLE }, | ||
59 | { 33868800, MAX9485_FS_44_1KHZ | MAX9485_SCALE_768 }, | ||
60 | { 36864000, MAX9485_FS_48KHZ | MAX9485_SCALE_384 | MAX9485_DOUBLE }, | ||
61 | { 36864000, MAX9485_FS_48KHZ | MAX9485_SCALE_768 }, | ||
62 | { 49152000, MAX9485_FS_32KHZ | MAX9485_SCALE_768 | MAX9485_DOUBLE }, | ||
63 | { 67737600, MAX9485_FS_44_1KHZ | MAX9485_SCALE_768 | MAX9485_DOUBLE }, | ||
64 | { 73728000, MAX9485_FS_48KHZ | MAX9485_SCALE_768 | MAX9485_DOUBLE }, | ||
65 | { } /* sentinel */ | ||
66 | }; | ||
67 | |||
68 | struct max9485_driver_data; | ||
69 | |||
70 | struct max9485_clk_hw { | ||
71 | struct clk_hw hw; | ||
72 | struct clk_init_data init; | ||
73 | u8 enable_bit; | ||
74 | struct max9485_driver_data *drvdata; | ||
75 | }; | ||
76 | |||
77 | struct max9485_driver_data { | ||
78 | struct clk *xclk; | ||
79 | struct i2c_client *client; | ||
80 | u8 reg_value; | ||
81 | struct regulator *supply; | ||
82 | struct gpio_desc *reset_gpio; | ||
83 | struct max9485_clk_hw hw[MAX9485_NUM_CLKS]; | ||
84 | }; | ||
85 | |||
86 | static inline struct max9485_clk_hw *to_max9485_clk(struct clk_hw *hw) | ||
87 | { | ||
88 | return container_of(hw, struct max9485_clk_hw, hw); | ||
89 | } | ||
90 | |||
91 | static int max9485_update_bits(struct max9485_driver_data *drvdata, | ||
92 | u8 mask, u8 value) | ||
93 | { | ||
94 | int ret; | ||
95 | |||
96 | drvdata->reg_value &= ~mask; | ||
97 | drvdata->reg_value |= value; | ||
98 | |||
99 | dev_dbg(&drvdata->client->dev, | ||
100 | "updating mask 0x%02x value 0x%02x -> 0x%02x\n", | ||
101 | mask, value, drvdata->reg_value); | ||
102 | |||
103 | ret = i2c_master_send(drvdata->client, | ||
104 | &drvdata->reg_value, | ||
105 | sizeof(drvdata->reg_value)); | ||
106 | |||
107 | return ret < 0 ? ret : 0; | ||
108 | } | ||
109 | |||
110 | static int max9485_clk_prepare(struct clk_hw *hw) | ||
111 | { | ||
112 | struct max9485_clk_hw *clk_hw = to_max9485_clk(hw); | ||
113 | |||
114 | return max9485_update_bits(clk_hw->drvdata, | ||
115 | clk_hw->enable_bit, | ||
116 | clk_hw->enable_bit); | ||
117 | } | ||
118 | |||
119 | static void max9485_clk_unprepare(struct clk_hw *hw) | ||
120 | { | ||
121 | struct max9485_clk_hw *clk_hw = to_max9485_clk(hw); | ||
122 | |||
123 | max9485_update_bits(clk_hw->drvdata, clk_hw->enable_bit, 0); | ||
124 | } | ||
125 | |||
126 | /* | ||
127 | * CLKOUT - configurable clock output | ||
128 | */ | ||
129 | static int max9485_clkout_set_rate(struct clk_hw *hw, unsigned long rate, | ||
130 | unsigned long parent_rate) | ||
131 | { | ||
132 | struct max9485_clk_hw *clk_hw = to_max9485_clk(hw); | ||
133 | const struct max9485_rate *entry; | ||
134 | |||
135 | for (entry = max9485_rates; entry->out != 0; entry++) | ||
136 | if (entry->out == rate) | ||
137 | break; | ||
138 | |||
139 | if (entry->out == 0) | ||
140 | return -EINVAL; | ||
141 | |||
142 | return max9485_update_bits(clk_hw->drvdata, | ||
143 | MAX9485_FREQ_MASK, | ||
144 | entry->reg_value); | ||
145 | } | ||
146 | |||
147 | static unsigned long max9485_clkout_recalc_rate(struct clk_hw *hw, | ||
148 | unsigned long parent_rate) | ||
149 | { | ||
150 | struct max9485_clk_hw *clk_hw = to_max9485_clk(hw); | ||
151 | struct max9485_driver_data *drvdata = clk_hw->drvdata; | ||
152 | u8 val = drvdata->reg_value & MAX9485_FREQ_MASK; | ||
153 | const struct max9485_rate *entry; | ||
154 | |||
155 | for (entry = max9485_rates; entry->out != 0; entry++) | ||
156 | if (val == entry->reg_value) | ||
157 | return entry->out; | ||
158 | |||
159 | return 0; | ||
160 | } | ||
161 | |||
162 | static long max9485_clkout_round_rate(struct clk_hw *hw, unsigned long rate, | ||
163 | unsigned long *parent_rate) | ||
164 | { | ||
165 | const struct max9485_rate *curr, *prev = NULL; | ||
166 | |||
167 | for (curr = max9485_rates; curr->out != 0; curr++) { | ||
168 | /* Exact matches */ | ||
169 | if (curr->out == rate) | ||
170 | return rate; | ||
171 | |||
172 | /* | ||
173 | * Find the first entry that has a frequency higher than the | ||
174 | * requested one. | ||
175 | */ | ||
176 | if (curr->out > rate) { | ||
177 | unsigned int mid; | ||
178 | |||
179 | /* | ||
180 | * If this is the first entry, clamp the value to the | ||
181 | * lowest possible frequency. | ||
182 | */ | ||
183 | if (!prev) | ||
184 | return curr->out; | ||
185 | |||
186 | /* | ||
187 | * Otherwise, determine whether the previous entry or | ||
188 | * current one is closer. | ||
189 | */ | ||
190 | mid = prev->out + ((curr->out - prev->out) / 2); | ||
191 | |||
192 | return (mid > rate) ? prev->out : curr->out; | ||
193 | } | ||
194 | |||
195 | prev = curr; | ||
196 | } | ||
197 | |||
198 | /* If the last entry was still too high, clamp the value */ | ||
199 | return prev->out; | ||
200 | } | ||
201 | |||
202 | struct max9485_clk { | ||
203 | const char *name; | ||
204 | int parent_index; | ||
205 | const struct clk_ops ops; | ||
206 | u8 enable_bit; | ||
207 | }; | ||
208 | |||
209 | static const struct max9485_clk max9485_clks[MAX9485_NUM_CLKS] = { | ||
210 | [MAX9485_MCLKOUT] = { | ||
211 | .name = "mclkout", | ||
212 | .parent_index = -1, | ||
213 | .enable_bit = MAX9485_MCLK_ENABLE, | ||
214 | .ops = { | ||
215 | .prepare = max9485_clk_prepare, | ||
216 | .unprepare = max9485_clk_unprepare, | ||
217 | }, | ||
218 | }, | ||
219 | [MAX9485_CLKOUT] = { | ||
220 | .name = "clkout", | ||
221 | .parent_index = -1, | ||
222 | .ops = { | ||
223 | .set_rate = max9485_clkout_set_rate, | ||
224 | .round_rate = max9485_clkout_round_rate, | ||
225 | .recalc_rate = max9485_clkout_recalc_rate, | ||
226 | }, | ||
227 | }, | ||
228 | [MAX9485_CLKOUT1] = { | ||
229 | .name = "clkout1", | ||
230 | .parent_index = MAX9485_CLKOUT, | ||
231 | .enable_bit = MAX9485_CLKOUT1_ENABLE, | ||
232 | .ops = { | ||
233 | .prepare = max9485_clk_prepare, | ||
234 | .unprepare = max9485_clk_unprepare, | ||
235 | }, | ||
236 | }, | ||
237 | [MAX9485_CLKOUT2] = { | ||
238 | .name = "clkout2", | ||
239 | .parent_index = MAX9485_CLKOUT, | ||
240 | .enable_bit = MAX9485_CLKOUT2_ENABLE, | ||
241 | .ops = { | ||
242 | .prepare = max9485_clk_prepare, | ||
243 | .unprepare = max9485_clk_unprepare, | ||
244 | }, | ||
245 | }, | ||
246 | }; | ||
247 | |||
248 | static struct clk_hw * | ||
249 | max9485_of_clk_get(struct of_phandle_args *clkspec, void *data) | ||
250 | { | ||
251 | struct max9485_driver_data *drvdata = data; | ||
252 | unsigned int idx = clkspec->args[0]; | ||
253 | |||
254 | return &drvdata->hw[idx].hw; | ||
255 | } | ||
256 | |||
257 | static int max9485_i2c_probe(struct i2c_client *client, | ||
258 | const struct i2c_device_id *id) | ||
259 | { | ||
260 | struct max9485_driver_data *drvdata; | ||
261 | struct device *dev = &client->dev; | ||
262 | const char *xclk_name; | ||
263 | int i, ret; | ||
264 | |||
265 | drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); | ||
266 | if (!drvdata) | ||
267 | return -ENOMEM; | ||
268 | |||
269 | drvdata->xclk = devm_clk_get(dev, "xclk"); | ||
270 | if (IS_ERR(drvdata->xclk)) | ||
271 | return PTR_ERR(drvdata->xclk); | ||
272 | |||
273 | xclk_name = __clk_get_name(drvdata->xclk); | ||
274 | |||
275 | drvdata->supply = devm_regulator_get(dev, "vdd"); | ||
276 | if (IS_ERR(drvdata->supply)) | ||
277 | return PTR_ERR(drvdata->supply); | ||
278 | |||
279 | ret = regulator_enable(drvdata->supply); | ||
280 | if (ret < 0) | ||
281 | return ret; | ||
282 | |||
283 | drvdata->reset_gpio = | ||
284 | devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); | ||
285 | if (IS_ERR(drvdata->reset_gpio)) | ||
286 | return PTR_ERR(drvdata->reset_gpio); | ||
287 | |||
288 | i2c_set_clientdata(client, drvdata); | ||
289 | drvdata->client = client; | ||
290 | |||
291 | ret = i2c_master_recv(drvdata->client, &drvdata->reg_value, | ||
292 | sizeof(drvdata->reg_value)); | ||
293 | if (ret < 0) { | ||
294 | dev_warn(dev, "Unable to read device register: %d\n", ret); | ||
295 | return ret; | ||
296 | } | ||
297 | |||
298 | for (i = 0; i < MAX9485_NUM_CLKS; i++) { | ||
299 | int parent_index = max9485_clks[i].parent_index; | ||
300 | const char *name; | ||
301 | |||
302 | if (of_property_read_string_index(dev->of_node, | ||
303 | "clock-output-names", | ||
304 | i, &name) == 0) { | ||
305 | drvdata->hw[i].init.name = name; | ||
306 | } else { | ||
307 | drvdata->hw[i].init.name = max9485_clks[i].name; | ||
308 | } | ||
309 | |||
310 | drvdata->hw[i].init.ops = &max9485_clks[i].ops; | ||
311 | drvdata->hw[i].init.num_parents = 1; | ||
312 | drvdata->hw[i].init.flags = 0; | ||
313 | |||
314 | if (parent_index > 0) { | ||
315 | drvdata->hw[i].init.parent_names = | ||
316 | &drvdata->hw[parent_index].init.name; | ||
317 | drvdata->hw[i].init.flags |= CLK_SET_RATE_PARENT; | ||
318 | } else { | ||
319 | drvdata->hw[i].init.parent_names = &xclk_name; | ||
320 | } | ||
321 | |||
322 | drvdata->hw[i].enable_bit = max9485_clks[i].enable_bit; | ||
323 | drvdata->hw[i].hw.init = &drvdata->hw[i].init; | ||
324 | drvdata->hw[i].drvdata = drvdata; | ||
325 | |||
326 | ret = devm_clk_hw_register(dev, &drvdata->hw[i].hw); | ||
327 | if (ret < 0) | ||
328 | return ret; | ||
329 | } | ||
330 | |||
331 | return devm_of_clk_add_hw_provider(dev, max9485_of_clk_get, drvdata); | ||
332 | } | ||
333 | |||
334 | static int __maybe_unused max9485_suspend(struct device *dev) | ||
335 | { | ||
336 | struct i2c_client *client = to_i2c_client(dev); | ||
337 | struct max9485_driver_data *drvdata = i2c_get_clientdata(client); | ||
338 | |||
339 | gpiod_set_value_cansleep(drvdata->reset_gpio, 0); | ||
340 | |||
341 | return 0; | ||
342 | } | ||
343 | |||
344 | static int __maybe_unused max9485_resume(struct device *dev) | ||
345 | { | ||
346 | struct i2c_client *client = to_i2c_client(dev); | ||
347 | struct max9485_driver_data *drvdata = i2c_get_clientdata(client); | ||
348 | int ret; | ||
349 | |||
350 | gpiod_set_value_cansleep(drvdata->reset_gpio, 1); | ||
351 | |||
352 | ret = i2c_master_send(client, &drvdata->reg_value, | ||
353 | sizeof(drvdata->reg_value)); | ||
354 | |||
355 | return ret < 0 ? ret : 0; | ||
356 | } | ||
357 | |||
358 | static const struct dev_pm_ops max9485_pm_ops = { | ||
359 | SET_SYSTEM_SLEEP_PM_OPS(max9485_suspend, max9485_resume) | ||
360 | }; | ||
361 | |||
362 | static const struct of_device_id max9485_dt_ids[] = { | ||
363 | { .compatible = "maxim,max9485", }, | ||
364 | { } | ||
365 | }; | ||
366 | MODULE_DEVICE_TABLE(of, max9485_dt_ids); | ||
367 | |||
368 | static const struct i2c_device_id max9485_i2c_ids[] = { | ||
369 | { .name = "max9485", }, | ||
370 | { } | ||
371 | }; | ||
372 | MODULE_DEVICE_TABLE(i2c, max9485_i2c_ids); | ||
373 | |||
374 | static struct i2c_driver max9485_driver = { | ||
375 | .driver = { | ||
376 | .name = "max9485", | ||
377 | .pm = &max9485_pm_ops, | ||
378 | .of_match_table = max9485_dt_ids, | ||
379 | }, | ||
380 | .probe = max9485_i2c_probe, | ||
381 | .id_table = max9485_i2c_ids, | ||
382 | }; | ||
383 | module_i2c_driver(max9485_driver); | ||
384 | |||
385 | MODULE_AUTHOR("Daniel Mack <daniel@zonque.org>"); | ||
386 | MODULE_DESCRIPTION("MAX9485 Programmable Audio Clock Generator"); | ||
387 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/clk/clk-scmi.c b/drivers/clk/clk-scmi.c index bb2a6f2f5516..a985bf5e1ac6 100644 --- a/drivers/clk/clk-scmi.c +++ b/drivers/clk/clk-scmi.c | |||
@@ -38,7 +38,6 @@ static unsigned long scmi_clk_recalc_rate(struct clk_hw *hw, | |||
38 | static long scmi_clk_round_rate(struct clk_hw *hw, unsigned long rate, | 38 | static long scmi_clk_round_rate(struct clk_hw *hw, unsigned long rate, |
39 | unsigned long *parent_rate) | 39 | unsigned long *parent_rate) |
40 | { | 40 | { |
41 | int step; | ||
42 | u64 fmin, fmax, ftmp; | 41 | u64 fmin, fmax, ftmp; |
43 | struct scmi_clk *clk = to_scmi_clk(hw); | 42 | struct scmi_clk *clk = to_scmi_clk(hw); |
44 | 43 | ||
@@ -60,9 +59,9 @@ static long scmi_clk_round_rate(struct clk_hw *hw, unsigned long rate, | |||
60 | 59 | ||
61 | ftmp = rate - fmin; | 60 | ftmp = rate - fmin; |
62 | ftmp += clk->info->range.step_size - 1; /* to round up */ | 61 | ftmp += clk->info->range.step_size - 1; /* to round up */ |
63 | step = do_div(ftmp, clk->info->range.step_size); | 62 | do_div(ftmp, clk->info->range.step_size); |
64 | 63 | ||
65 | return step * clk->info->range.step_size + fmin; | 64 | return ftmp * clk->info->range.step_size + fmin; |
66 | } | 65 | } |
67 | 66 | ||
68 | static int scmi_clk_set_rate(struct clk_hw *hw, unsigned long rate, | 67 | static int scmi_clk_set_rate(struct clk_hw *hw, unsigned long rate, |
diff --git a/drivers/clk/clk-si514.c b/drivers/clk/clk-si514.c index 09b6718956bd..153b3a2b5857 100644 --- a/drivers/clk/clk-si514.c +++ b/drivers/clk/clk-si514.c | |||
@@ -74,6 +74,33 @@ static int si514_enable_output(struct clk_si514 *data, bool enable) | |||
74 | SI514_CONTROL_OE, enable ? SI514_CONTROL_OE : 0); | 74 | SI514_CONTROL_OE, enable ? SI514_CONTROL_OE : 0); |
75 | } | 75 | } |
76 | 76 | ||
77 | static int si514_prepare(struct clk_hw *hw) | ||
78 | { | ||
79 | struct clk_si514 *data = to_clk_si514(hw); | ||
80 | |||
81 | return si514_enable_output(data, true); | ||
82 | } | ||
83 | |||
84 | static void si514_unprepare(struct clk_hw *hw) | ||
85 | { | ||
86 | struct clk_si514 *data = to_clk_si514(hw); | ||
87 | |||
88 | si514_enable_output(data, false); | ||
89 | } | ||
90 | |||
91 | static int si514_is_prepared(struct clk_hw *hw) | ||
92 | { | ||
93 | struct clk_si514 *data = to_clk_si514(hw); | ||
94 | unsigned int val; | ||
95 | int err; | ||
96 | |||
97 | err = regmap_read(data->regmap, SI514_REG_CONTROL, &val); | ||
98 | if (err < 0) | ||
99 | return err; | ||
100 | |||
101 | return !!(val & SI514_CONTROL_OE); | ||
102 | } | ||
103 | |||
77 | /* Retrieve clock multiplier and dividers from hardware */ | 104 | /* Retrieve clock multiplier and dividers from hardware */ |
78 | static int si514_get_muldiv(struct clk_si514 *data, | 105 | static int si514_get_muldiv(struct clk_si514 *data, |
79 | struct clk_si514_muldiv *settings) | 106 | struct clk_si514_muldiv *settings) |
@@ -235,12 +262,17 @@ static int si514_set_rate(struct clk_hw *hw, unsigned long rate, | |||
235 | { | 262 | { |
236 | struct clk_si514 *data = to_clk_si514(hw); | 263 | struct clk_si514 *data = to_clk_si514(hw); |
237 | struct clk_si514_muldiv settings; | 264 | struct clk_si514_muldiv settings; |
265 | unsigned int old_oe_state; | ||
238 | int err; | 266 | int err; |
239 | 267 | ||
240 | err = si514_calc_muldiv(&settings, rate); | 268 | err = si514_calc_muldiv(&settings, rate); |
241 | if (err) | 269 | if (err) |
242 | return err; | 270 | return err; |
243 | 271 | ||
272 | err = regmap_read(data->regmap, SI514_REG_CONTROL, &old_oe_state); | ||
273 | if (err) | ||
274 | return err; | ||
275 | |||
244 | si514_enable_output(data, false); | 276 | si514_enable_output(data, false); |
245 | 277 | ||
246 | err = si514_set_muldiv(data, &settings); | 278 | err = si514_set_muldiv(data, &settings); |
@@ -255,12 +287,16 @@ static int si514_set_rate(struct clk_hw *hw, unsigned long rate, | |||
255 | /* Applying a new frequency can take up to 10ms */ | 287 | /* Applying a new frequency can take up to 10ms */ |
256 | usleep_range(10000, 12000); | 288 | usleep_range(10000, 12000); |
257 | 289 | ||
258 | si514_enable_output(data, true); | 290 | if (old_oe_state & SI514_CONTROL_OE) |
291 | si514_enable_output(data, true); | ||
259 | 292 | ||
260 | return err; | 293 | return err; |
261 | } | 294 | } |
262 | 295 | ||
263 | static const struct clk_ops si514_clk_ops = { | 296 | static const struct clk_ops si514_clk_ops = { |
297 | .prepare = si514_prepare, | ||
298 | .unprepare = si514_unprepare, | ||
299 | .is_prepared = si514_is_prepared, | ||
264 | .recalc_rate = si514_recalc_rate, | 300 | .recalc_rate = si514_recalc_rate, |
265 | .round_rate = si514_round_rate, | 301 | .round_rate = si514_round_rate, |
266 | .set_rate = si514_set_rate, | 302 | .set_rate = si514_set_rate, |
diff --git a/drivers/clk/clk-si544.c b/drivers/clk/clk-si544.c index 1e2a3b8f9454..64e607f3232a 100644 --- a/drivers/clk/clk-si544.c +++ b/drivers/clk/clk-si544.c | |||
@@ -86,6 +86,33 @@ static int si544_enable_output(struct clk_si544 *data, bool enable) | |||
86 | SI544_OE_STATE_ODC_OE, enable ? SI544_OE_STATE_ODC_OE : 0); | 86 | SI544_OE_STATE_ODC_OE, enable ? SI544_OE_STATE_ODC_OE : 0); |
87 | } | 87 | } |
88 | 88 | ||
89 | static int si544_prepare(struct clk_hw *hw) | ||
90 | { | ||
91 | struct clk_si544 *data = to_clk_si544(hw); | ||
92 | |||
93 | return si544_enable_output(data, true); | ||
94 | } | ||
95 | |||
96 | static void si544_unprepare(struct clk_hw *hw) | ||
97 | { | ||
98 | struct clk_si544 *data = to_clk_si544(hw); | ||
99 | |||
100 | si544_enable_output(data, false); | ||
101 | } | ||
102 | |||
103 | static int si544_is_prepared(struct clk_hw *hw) | ||
104 | { | ||
105 | struct clk_si544 *data = to_clk_si544(hw); | ||
106 | unsigned int val; | ||
107 | int err; | ||
108 | |||
109 | err = regmap_read(data->regmap, SI544_REG_OE_STATE, &val); | ||
110 | if (err < 0) | ||
111 | return err; | ||
112 | |||
113 | return !!(val & SI544_OE_STATE_ODC_OE); | ||
114 | } | ||
115 | |||
89 | /* Retrieve clock multiplier and dividers from hardware */ | 116 | /* Retrieve clock multiplier and dividers from hardware */ |
90 | static int si544_get_muldiv(struct clk_si544 *data, | 117 | static int si544_get_muldiv(struct clk_si544 *data, |
91 | struct clk_si544_muldiv *settings) | 118 | struct clk_si544_muldiv *settings) |
@@ -273,6 +300,7 @@ static int si544_set_rate(struct clk_hw *hw, unsigned long rate, | |||
273 | { | 300 | { |
274 | struct clk_si544 *data = to_clk_si544(hw); | 301 | struct clk_si544 *data = to_clk_si544(hw); |
275 | struct clk_si544_muldiv settings; | 302 | struct clk_si544_muldiv settings; |
303 | unsigned int old_oe_state; | ||
276 | int err; | 304 | int err; |
277 | 305 | ||
278 | if (!is_valid_frequency(data, rate)) | 306 | if (!is_valid_frequency(data, rate)) |
@@ -282,6 +310,10 @@ static int si544_set_rate(struct clk_hw *hw, unsigned long rate, | |||
282 | if (err) | 310 | if (err) |
283 | return err; | 311 | return err; |
284 | 312 | ||
313 | err = regmap_read(data->regmap, SI544_REG_OE_STATE, &old_oe_state); | ||
314 | if (err) | ||
315 | return err; | ||
316 | |||
285 | si544_enable_output(data, false); | 317 | si544_enable_output(data, false); |
286 | 318 | ||
287 | /* Allow FCAL for this frequency update */ | 319 | /* Allow FCAL for this frequency update */ |
@@ -303,12 +335,16 @@ static int si544_set_rate(struct clk_hw *hw, unsigned long rate, | |||
303 | /* Applying a new frequency can take up to 10ms */ | 335 | /* Applying a new frequency can take up to 10ms */ |
304 | usleep_range(10000, 12000); | 336 | usleep_range(10000, 12000); |
305 | 337 | ||
306 | si544_enable_output(data, true); | 338 | if (old_oe_state & SI544_OE_STATE_ODC_OE) |
339 | si544_enable_output(data, true); | ||
307 | 340 | ||
308 | return err; | 341 | return err; |
309 | } | 342 | } |
310 | 343 | ||
311 | static const struct clk_ops si544_clk_ops = { | 344 | static const struct clk_ops si544_clk_ops = { |
345 | .prepare = si544_prepare, | ||
346 | .unprepare = si544_unprepare, | ||
347 | .is_prepared = si544_is_prepared, | ||
312 | .recalc_rate = si544_recalc_rate, | 348 | .recalc_rate = si544_recalc_rate, |
313 | .round_rate = si544_round_rate, | 349 | .round_rate = si544_round_rate, |
314 | .set_rate = si544_set_rate, | 350 | .set_rate = si544_set_rate, |
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 976f59e11f9a..d31055ae6ec6 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c | |||
@@ -691,6 +691,9 @@ static void clk_core_unprepare(struct clk_core *core) | |||
691 | "Unpreparing critical %s\n", core->name)) | 691 | "Unpreparing critical %s\n", core->name)) |
692 | return; | 692 | return; |
693 | 693 | ||
694 | if (core->flags & CLK_SET_RATE_GATE) | ||
695 | clk_core_rate_unprotect(core); | ||
696 | |||
694 | if (--core->prepare_count > 0) | 697 | if (--core->prepare_count > 0) |
695 | return; | 698 | return; |
696 | 699 | ||
@@ -765,6 +768,16 @@ static int clk_core_prepare(struct clk_core *core) | |||
765 | 768 | ||
766 | core->prepare_count++; | 769 | core->prepare_count++; |
767 | 770 | ||
771 | /* | ||
772 | * CLK_SET_RATE_GATE is a special case of clock protection | ||
773 | * Instead of a consumer claiming exclusive rate control, it is | ||
774 | * actually the provider which prevents any consumer from making any | ||
775 | * operation which could result in a rate change or rate glitch while | ||
776 | * the clock is prepared. | ||
777 | */ | ||
778 | if (core->flags & CLK_SET_RATE_GATE) | ||
779 | clk_core_rate_protect(core); | ||
780 | |||
768 | return 0; | 781 | return 0; |
769 | unprepare: | 782 | unprepare: |
770 | clk_core_unprepare(core->parent); | 783 | clk_core_unprepare(core->parent); |
@@ -1888,9 +1901,6 @@ static int clk_core_set_rate_nolock(struct clk_core *core, | |||
1888 | if (clk_core_rate_is_protected(core)) | 1901 | if (clk_core_rate_is_protected(core)) |
1889 | return -EBUSY; | 1902 | return -EBUSY; |
1890 | 1903 | ||
1891 | if ((core->flags & CLK_SET_RATE_GATE) && core->prepare_count) | ||
1892 | return -EBUSY; | ||
1893 | |||
1894 | /* calculate new rates and get the topmost changed clock */ | 1904 | /* calculate new rates and get the topmost changed clock */ |
1895 | top = clk_calc_new_rates(core, req_rate); | 1905 | top = clk_calc_new_rates(core, req_rate); |
1896 | if (!top) | 1906 | if (!top) |
@@ -3122,6 +3132,7 @@ struct clk *__clk_create_clk(struct clk_hw *hw, const char *dev_id, | |||
3122 | return clk; | 3132 | return clk; |
3123 | } | 3133 | } |
3124 | 3134 | ||
3135 | /* keep in sync with __clk_put */ | ||
3125 | void __clk_free_clk(struct clk *clk) | 3136 | void __clk_free_clk(struct clk *clk) |
3126 | { | 3137 | { |
3127 | clk_prepare_lock(); | 3138 | clk_prepare_lock(); |
@@ -3501,6 +3512,7 @@ int __clk_get(struct clk *clk) | |||
3501 | return 1; | 3512 | return 1; |
3502 | } | 3513 | } |
3503 | 3514 | ||
3515 | /* keep in sync with __clk_free_clk */ | ||
3504 | void __clk_put(struct clk *clk) | 3516 | void __clk_put(struct clk *clk) |
3505 | { | 3517 | { |
3506 | struct module *owner; | 3518 | struct module *owner; |
@@ -3534,6 +3546,7 @@ void __clk_put(struct clk *clk) | |||
3534 | 3546 | ||
3535 | module_put(owner); | 3547 | module_put(owner); |
3536 | 3548 | ||
3549 | kfree_const(clk->con_id); | ||
3537 | kfree(clk); | 3550 | kfree(clk); |
3538 | } | 3551 | } |
3539 | 3552 | ||
diff --git a/drivers/clk/imx/clk-imx51-imx53.c b/drivers/clk/imx/clk-imx51-imx53.c index caa8bd40692c..fc8e782d817b 100644 --- a/drivers/clk/imx/clk-imx51-imx53.c +++ b/drivers/clk/imx/clk-imx51-imx53.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/of.h> | 16 | #include <linux/of.h> |
17 | #include <linux/of_address.h> | 17 | #include <linux/of_address.h> |
18 | #include <linux/of_irq.h> | 18 | #include <linux/of_irq.h> |
19 | #include <linux/sizes.h> | ||
19 | #include <soc/imx/revision.h> | 20 | #include <soc/imx/revision.h> |
20 | #include <dt-bindings/clock/imx5-clock.h> | 21 | #include <dt-bindings/clock/imx5-clock.h> |
21 | 22 | ||
@@ -175,13 +176,13 @@ static void __init mx5_clocks_common_init(void __iomem *ccm_base) | |||
175 | clk[IMX5_CLK_PER_ROOT] = imx_clk_mux("per_root", MXC_CCM_CBCMR, 0, 1, | 176 | clk[IMX5_CLK_PER_ROOT] = imx_clk_mux("per_root", MXC_CCM_CBCMR, 0, 1, |
176 | per_root_sel, ARRAY_SIZE(per_root_sel)); | 177 | per_root_sel, ARRAY_SIZE(per_root_sel)); |
177 | clk[IMX5_CLK_AHB] = imx_clk_divider("ahb", "main_bus", MXC_CCM_CBCDR, 10, 3); | 178 | clk[IMX5_CLK_AHB] = imx_clk_divider("ahb", "main_bus", MXC_CCM_CBCDR, 10, 3); |
178 | clk[IMX5_CLK_AHB_MAX] = imx_clk_gate2("ahb_max", "ahb", MXC_CCM_CCGR0, 28); | 179 | clk[IMX5_CLK_AHB_MAX] = imx_clk_gate2_flags("ahb_max", "ahb", MXC_CCM_CCGR0, 28, CLK_IS_CRITICAL); |
179 | clk[IMX5_CLK_AIPS_TZ1] = imx_clk_gate2("aips_tz1", "ahb", MXC_CCM_CCGR0, 24); | 180 | clk[IMX5_CLK_AIPS_TZ1] = imx_clk_gate2_flags("aips_tz1", "ahb", MXC_CCM_CCGR0, 24, CLK_IS_CRITICAL); |
180 | clk[IMX5_CLK_AIPS_TZ2] = imx_clk_gate2("aips_tz2", "ahb", MXC_CCM_CCGR0, 26); | 181 | clk[IMX5_CLK_AIPS_TZ2] = imx_clk_gate2_flags("aips_tz2", "ahb", MXC_CCM_CCGR0, 26, CLK_IS_CRITICAL); |
181 | clk[IMX5_CLK_TMAX1] = imx_clk_gate2("tmax1", "ahb", MXC_CCM_CCGR1, 0); | 182 | clk[IMX5_CLK_TMAX1] = imx_clk_gate2_flags("tmax1", "ahb", MXC_CCM_CCGR1, 0, CLK_IS_CRITICAL); |
182 | clk[IMX5_CLK_TMAX2] = imx_clk_gate2("tmax2", "ahb", MXC_CCM_CCGR1, 2); | 183 | clk[IMX5_CLK_TMAX2] = imx_clk_gate2_flags("tmax2", "ahb", MXC_CCM_CCGR1, 2, CLK_IS_CRITICAL); |
183 | clk[IMX5_CLK_TMAX3] = imx_clk_gate2("tmax3", "ahb", MXC_CCM_CCGR1, 4); | 184 | clk[IMX5_CLK_TMAX3] = imx_clk_gate2_flags("tmax3", "ahb", MXC_CCM_CCGR1, 4, CLK_IS_CRITICAL); |
184 | clk[IMX5_CLK_SPBA] = imx_clk_gate2("spba", "ipg", MXC_CCM_CCGR5, 0); | 185 | clk[IMX5_CLK_SPBA] = imx_clk_gate2_flags("spba", "ipg", MXC_CCM_CCGR5, 0, CLK_IS_CRITICAL); |
185 | clk[IMX5_CLK_IPG] = imx_clk_divider("ipg", "ahb", MXC_CCM_CBCDR, 8, 2); | 186 | clk[IMX5_CLK_IPG] = imx_clk_divider("ipg", "ahb", MXC_CCM_CBCDR, 8, 2); |
186 | clk[IMX5_CLK_AXI_A] = imx_clk_divider("axi_a", "main_bus", MXC_CCM_CBCDR, 16, 3); | 187 | clk[IMX5_CLK_AXI_A] = imx_clk_divider("axi_a", "main_bus", MXC_CCM_CBCDR, 16, 3); |
187 | clk[IMX5_CLK_AXI_B] = imx_clk_divider("axi_b", "main_bus", MXC_CCM_CBCDR, 19, 3); | 188 | clk[IMX5_CLK_AXI_B] = imx_clk_divider("axi_b", "main_bus", MXC_CCM_CBCDR, 19, 3); |
@@ -252,8 +253,8 @@ static void __init mx5_clocks_common_init(void __iomem *ccm_base) | |||
252 | clk[IMX5_CLK_ECSPI2_PER_GATE] = imx_clk_gate2("ecspi2_per_gate", "ecspi_podf", MXC_CCM_CCGR4, 24); | 253 | clk[IMX5_CLK_ECSPI2_PER_GATE] = imx_clk_gate2("ecspi2_per_gate", "ecspi_podf", MXC_CCM_CCGR4, 24); |
253 | clk[IMX5_CLK_CSPI_IPG_GATE] = imx_clk_gate2("cspi_ipg_gate", "ipg", MXC_CCM_CCGR4, 26); | 254 | clk[IMX5_CLK_CSPI_IPG_GATE] = imx_clk_gate2("cspi_ipg_gate", "ipg", MXC_CCM_CCGR4, 26); |
254 | clk[IMX5_CLK_SDMA_GATE] = imx_clk_gate2("sdma_gate", "ipg", MXC_CCM_CCGR4, 30); | 255 | clk[IMX5_CLK_SDMA_GATE] = imx_clk_gate2("sdma_gate", "ipg", MXC_CCM_CCGR4, 30); |
255 | clk[IMX5_CLK_EMI_FAST_GATE] = imx_clk_gate2("emi_fast_gate", "dummy", MXC_CCM_CCGR5, 14); | 256 | clk[IMX5_CLK_EMI_FAST_GATE] = imx_clk_gate2_flags("emi_fast_gate", "dummy", MXC_CCM_CCGR5, 14, CLK_IS_CRITICAL); |
256 | clk[IMX5_CLK_EMI_SLOW_GATE] = imx_clk_gate2("emi_slow_gate", "emi_slow_podf", MXC_CCM_CCGR5, 16); | 257 | clk[IMX5_CLK_EMI_SLOW_GATE] = imx_clk_gate2_flags("emi_slow_gate", "emi_slow_podf", MXC_CCM_CCGR5, 16, CLK_IS_CRITICAL); |
257 | clk[IMX5_CLK_IPU_SEL] = imx_clk_mux("ipu_sel", MXC_CCM_CBCMR, 6, 2, ipu_sel, ARRAY_SIZE(ipu_sel)); | 258 | clk[IMX5_CLK_IPU_SEL] = imx_clk_mux("ipu_sel", MXC_CCM_CBCMR, 6, 2, ipu_sel, ARRAY_SIZE(ipu_sel)); |
258 | clk[IMX5_CLK_IPU_GATE] = imx_clk_gate2("ipu_gate", "ipu_sel", MXC_CCM_CCGR5, 10); | 259 | clk[IMX5_CLK_IPU_GATE] = imx_clk_gate2("ipu_gate", "ipu_sel", MXC_CCM_CCGR5, 10); |
259 | clk[IMX5_CLK_NFC_GATE] = imx_clk_gate2("nfc_gate", "nfc_podf", MXC_CCM_CCGR5, 20); | 260 | clk[IMX5_CLK_NFC_GATE] = imx_clk_gate2("nfc_gate", "nfc_podf", MXC_CCM_CCGR5, 20); |
@@ -267,7 +268,7 @@ static void __init mx5_clocks_common_init(void __iomem *ccm_base) | |||
267 | clk[IMX5_CLK_VPU_SEL] = imx_clk_mux("vpu_sel", MXC_CCM_CBCMR, 14, 2, vpu_sel, ARRAY_SIZE(vpu_sel)); | 268 | clk[IMX5_CLK_VPU_SEL] = imx_clk_mux("vpu_sel", MXC_CCM_CBCMR, 14, 2, vpu_sel, ARRAY_SIZE(vpu_sel)); |
268 | clk[IMX5_CLK_VPU_GATE] = imx_clk_gate2("vpu_gate", "vpu_sel", MXC_CCM_CCGR5, 6); | 269 | clk[IMX5_CLK_VPU_GATE] = imx_clk_gate2("vpu_gate", "vpu_sel", MXC_CCM_CCGR5, 6); |
269 | clk[IMX5_CLK_VPU_REFERENCE_GATE] = imx_clk_gate2("vpu_reference_gate", "osc", MXC_CCM_CCGR5, 8); | 270 | clk[IMX5_CLK_VPU_REFERENCE_GATE] = imx_clk_gate2("vpu_reference_gate", "osc", MXC_CCM_CCGR5, 8); |
270 | clk[IMX5_CLK_GPC_DVFS] = imx_clk_gate2("gpc_dvfs", "dummy", MXC_CCM_CCGR5, 24); | 271 | clk[IMX5_CLK_GPC_DVFS] = imx_clk_gate2_flags("gpc_dvfs", "dummy", MXC_CCM_CCGR5, 24, CLK_IS_CRITICAL); |
271 | 272 | ||
272 | clk[IMX5_CLK_SSI_APM] = imx_clk_mux("ssi_apm", MXC_CCM_CSCMR1, 8, 2, ssi_apm_sels, ARRAY_SIZE(ssi_apm_sels)); | 273 | clk[IMX5_CLK_SSI_APM] = imx_clk_mux("ssi_apm", MXC_CCM_CSCMR1, 8, 2, ssi_apm_sels, ARRAY_SIZE(ssi_apm_sels)); |
273 | clk[IMX5_CLK_SSI1_ROOT_SEL] = imx_clk_mux("ssi1_root_sel", MXC_CCM_CSCMR1, 14, 2, ssi_clk_sels, ARRAY_SIZE(ssi_clk_sels)); | 274 | clk[IMX5_CLK_SSI1_ROOT_SEL] = imx_clk_mux("ssi1_root_sel", MXC_CCM_CSCMR1, 14, 2, ssi_clk_sels, ARRAY_SIZE(ssi_clk_sels)); |
@@ -316,21 +317,6 @@ static void __init mx5_clocks_common_init(void __iomem *ccm_base) | |||
316 | 317 | ||
317 | /* move usb phy clk to 24MHz */ | 318 | /* move usb phy clk to 24MHz */ |
318 | clk_set_parent(clk[IMX5_CLK_USB_PHY_SEL], clk[IMX5_CLK_OSC]); | 319 | clk_set_parent(clk[IMX5_CLK_USB_PHY_SEL], clk[IMX5_CLK_OSC]); |
319 | |||
320 | clk_prepare_enable(clk[IMX5_CLK_GPC_DVFS]); | ||
321 | clk_prepare_enable(clk[IMX5_CLK_AHB_MAX]); /* esdhc3 */ | ||
322 | clk_prepare_enable(clk[IMX5_CLK_AIPS_TZ1]); | ||
323 | clk_prepare_enable(clk[IMX5_CLK_AIPS_TZ2]); /* fec */ | ||
324 | clk_prepare_enable(clk[IMX5_CLK_SPBA]); | ||
325 | clk_prepare_enable(clk[IMX5_CLK_EMI_FAST_GATE]); /* fec */ | ||
326 | clk_prepare_enable(clk[IMX5_CLK_EMI_SLOW_GATE]); /* eim */ | ||
327 | clk_prepare_enable(clk[IMX5_CLK_MIPI_HSC1_GATE]); | ||
328 | clk_prepare_enable(clk[IMX5_CLK_MIPI_HSC2_GATE]); | ||
329 | clk_prepare_enable(clk[IMX5_CLK_MIPI_ESC_GATE]); | ||
330 | clk_prepare_enable(clk[IMX5_CLK_MIPI_HSP_GATE]); | ||
331 | clk_prepare_enable(clk[IMX5_CLK_TMAX1]); | ||
332 | clk_prepare_enable(clk[IMX5_CLK_TMAX2]); /* esdhc2, fec */ | ||
333 | clk_prepare_enable(clk[IMX5_CLK_TMAX3]); /* esdhc1, esdhc4 */ | ||
334 | } | 320 | } |
335 | 321 | ||
336 | static void __init mx50_clocks_init(struct device_node *np) | 322 | static void __init mx50_clocks_init(struct device_node *np) |
@@ -442,10 +428,10 @@ static void __init mx51_clocks_init(struct device_node *np) | |||
442 | clk[IMX5_CLK_ESDHC4_PER_GATE] = imx_clk_gate2("esdhc4_per_gate", "esdhc_d_sel", MXC_CCM_CCGR3, 14); | 428 | clk[IMX5_CLK_ESDHC4_PER_GATE] = imx_clk_gate2("esdhc4_per_gate", "esdhc_d_sel", MXC_CCM_CCGR3, 14); |
443 | clk[IMX5_CLK_USB_PHY_GATE] = imx_clk_gate2("usb_phy_gate", "usb_phy_sel", MXC_CCM_CCGR2, 0); | 429 | clk[IMX5_CLK_USB_PHY_GATE] = imx_clk_gate2("usb_phy_gate", "usb_phy_sel", MXC_CCM_CCGR2, 0); |
444 | clk[IMX5_CLK_HSI2C_GATE] = imx_clk_gate2("hsi2c_gate", "ipg", MXC_CCM_CCGR1, 22); | 430 | clk[IMX5_CLK_HSI2C_GATE] = imx_clk_gate2("hsi2c_gate", "ipg", MXC_CCM_CCGR1, 22); |
445 | clk[IMX5_CLK_MIPI_HSC1_GATE] = imx_clk_gate2("mipi_hsc1_gate", "ipg", MXC_CCM_CCGR4, 6); | 431 | clk[IMX5_CLK_MIPI_HSC1_GATE] = imx_clk_gate2_flags("mipi_hsc1_gate", "ipg", MXC_CCM_CCGR4, 6, CLK_IS_CRITICAL); |
446 | clk[IMX5_CLK_MIPI_HSC2_GATE] = imx_clk_gate2("mipi_hsc2_gate", "ipg", MXC_CCM_CCGR4, 8); | 432 | clk[IMX5_CLK_MIPI_HSC2_GATE] = imx_clk_gate2_flags("mipi_hsc2_gate", "ipg", MXC_CCM_CCGR4, 8, CLK_IS_CRITICAL); |
447 | clk[IMX5_CLK_MIPI_ESC_GATE] = imx_clk_gate2("mipi_esc_gate", "ipg", MXC_CCM_CCGR4, 10); | 433 | clk[IMX5_CLK_MIPI_ESC_GATE] = imx_clk_gate2_flags("mipi_esc_gate", "ipg", MXC_CCM_CCGR4, 10, CLK_IS_CRITICAL); |
448 | clk[IMX5_CLK_MIPI_HSP_GATE] = imx_clk_gate2("mipi_hsp_gate", "ipg", MXC_CCM_CCGR4, 12); | 434 | clk[IMX5_CLK_MIPI_HSP_GATE] = imx_clk_gate2_flags("mipi_hsp_gate", "ipg", MXC_CCM_CCGR4, 12, CLK_IS_CRITICAL); |
449 | clk[IMX5_CLK_SPDIF_XTAL_SEL] = imx_clk_mux("spdif_xtal_sel", MXC_CCM_CSCMR1, 2, 2, | 435 | clk[IMX5_CLK_SPDIF_XTAL_SEL] = imx_clk_mux("spdif_xtal_sel", MXC_CCM_CSCMR1, 2, 2, |
450 | mx51_spdif_xtal_sel, ARRAY_SIZE(mx51_spdif_xtal_sel)); | 436 | mx51_spdif_xtal_sel, ARRAY_SIZE(mx51_spdif_xtal_sel)); |
451 | clk[IMX5_CLK_SPDIF1_SEL] = imx_clk_mux("spdif1_sel", MXC_CCM_CSCMR2, 2, 2, | 437 | clk[IMX5_CLK_SPDIF1_SEL] = imx_clk_mux("spdif1_sel", MXC_CCM_CSCMR2, 2, 2, |
diff --git a/drivers/clk/imx/clk-imx6q.c b/drivers/clk/imx/clk-imx6q.c index b9ea7037e193..8c7c2fcb8d94 100644 --- a/drivers/clk/imx/clk-imx6q.c +++ b/drivers/clk/imx/clk-imx6q.c | |||
@@ -65,7 +65,7 @@ static const char *ipg_per_sels[] = { "ipg", "osc", }; | |||
65 | static const char *ecspi_sels[] = { "pll3_60m", "osc", }; | 65 | static const char *ecspi_sels[] = { "pll3_60m", "osc", }; |
66 | static const char *can_sels[] = { "pll3_60m", "osc", "pll3_80m", }; | 66 | static const char *can_sels[] = { "pll3_60m", "osc", "pll3_80m", }; |
67 | static const char *cko1_sels[] = { "pll3_usb_otg", "pll2_bus", "pll1_sys", "pll5_video_div", | 67 | static const char *cko1_sels[] = { "pll3_usb_otg", "pll2_bus", "pll1_sys", "pll5_video_div", |
68 | "dummy", "axi", "enfc", "ipu1_di0", "ipu1_di1", "ipu2_di0", | 68 | "video_27m", "axi", "enfc", "ipu1_di0", "ipu1_di1", "ipu2_di0", |
69 | "ipu2_di1", "ahb", "ipg", "ipg_per", "ckil", "pll4_audio_div", }; | 69 | "ipu2_di1", "ahb", "ipg", "ipg_per", "ckil", "pll4_audio_div", }; |
70 | static const char *cko2_sels[] = { | 70 | static const char *cko2_sels[] = { |
71 | "mmdc_ch0_axi", "mmdc_ch1_axi", "usdhc4", "usdhc1", | 71 | "mmdc_ch0_axi", "mmdc_ch1_axi", "usdhc4", "usdhc1", |
@@ -96,12 +96,6 @@ static const char *pll7_bypass_sels[] = { "pll7", "pll7_bypass_src", }; | |||
96 | static struct clk *clk[IMX6QDL_CLK_END]; | 96 | static struct clk *clk[IMX6QDL_CLK_END]; |
97 | static struct clk_onecell_data clk_data; | 97 | static struct clk_onecell_data clk_data; |
98 | 98 | ||
99 | static unsigned int const clks_init_on[] __initconst = { | ||
100 | IMX6QDL_CLK_MMDC_CH0_AXI, | ||
101 | IMX6QDL_CLK_ROM, | ||
102 | IMX6QDL_CLK_ARM, | ||
103 | }; | ||
104 | |||
105 | static struct clk_div_table clk_enet_ref_table[] = { | 99 | static struct clk_div_table clk_enet_ref_table[] = { |
106 | { .val = 0, .div = 20, }, | 100 | { .val = 0, .div = 20, }, |
107 | { .val = 1, .div = 10, }, | 101 | { .val = 1, .div = 10, }, |
@@ -417,7 +411,6 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) | |||
417 | { | 411 | { |
418 | struct device_node *np; | 412 | struct device_node *np; |
419 | void __iomem *anatop_base, *base; | 413 | void __iomem *anatop_base, *base; |
420 | int i; | ||
421 | int ret; | 414 | int ret; |
422 | 415 | ||
423 | clk[IMX6QDL_CLK_DUMMY] = imx_clk_fixed("dummy", 0); | 416 | clk[IMX6QDL_CLK_DUMMY] = imx_clk_fixed("dummy", 0); |
@@ -794,7 +787,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) | |||
794 | clk[IMX6QDL_CLK_MLB] = imx_clk_gate2("mlb", "mlb_podf", base + 0x74, 18); | 787 | clk[IMX6QDL_CLK_MLB] = imx_clk_gate2("mlb", "mlb_podf", base + 0x74, 18); |
795 | else | 788 | else |
796 | clk[IMX6QDL_CLK_MLB] = imx_clk_gate2("mlb", "axi", base + 0x74, 18); | 789 | clk[IMX6QDL_CLK_MLB] = imx_clk_gate2("mlb", "axi", base + 0x74, 18); |
797 | clk[IMX6QDL_CLK_MMDC_CH0_AXI] = imx_clk_gate2("mmdc_ch0_axi", "mmdc_ch0_axi_podf", base + 0x74, 20); | 790 | clk[IMX6QDL_CLK_MMDC_CH0_AXI] = imx_clk_gate2_flags("mmdc_ch0_axi", "mmdc_ch0_axi_podf", base + 0x74, 20, CLK_IS_CRITICAL); |
798 | clk[IMX6QDL_CLK_MMDC_CH1_AXI] = imx_clk_gate2("mmdc_ch1_axi", "mmdc_ch1_axi_podf", base + 0x74, 22); | 791 | clk[IMX6QDL_CLK_MMDC_CH1_AXI] = imx_clk_gate2("mmdc_ch1_axi", "mmdc_ch1_axi_podf", base + 0x74, 22); |
799 | clk[IMX6QDL_CLK_OCRAM] = imx_clk_gate2("ocram", "ahb", base + 0x74, 28); | 792 | clk[IMX6QDL_CLK_OCRAM] = imx_clk_gate2("ocram", "ahb", base + 0x74, 28); |
800 | clk[IMX6QDL_CLK_OPENVG_AXI] = imx_clk_gate2("openvg_axi", "axi", base + 0x74, 30); | 793 | clk[IMX6QDL_CLK_OPENVG_AXI] = imx_clk_gate2("openvg_axi", "axi", base + 0x74, 30); |
@@ -808,7 +801,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) | |||
808 | clk[IMX6QDL_CLK_GPMI_BCH] = imx_clk_gate2("gpmi_bch", "usdhc4", base + 0x78, 26); | 801 | clk[IMX6QDL_CLK_GPMI_BCH] = imx_clk_gate2("gpmi_bch", "usdhc4", base + 0x78, 26); |
809 | clk[IMX6QDL_CLK_GPMI_IO] = imx_clk_gate2("gpmi_io", "enfc", base + 0x78, 28); | 802 | clk[IMX6QDL_CLK_GPMI_IO] = imx_clk_gate2("gpmi_io", "enfc", base + 0x78, 28); |
810 | clk[IMX6QDL_CLK_GPMI_APB] = imx_clk_gate2("gpmi_apb", "usdhc3", base + 0x78, 30); | 803 | clk[IMX6QDL_CLK_GPMI_APB] = imx_clk_gate2("gpmi_apb", "usdhc3", base + 0x78, 30); |
811 | clk[IMX6QDL_CLK_ROM] = imx_clk_gate2("rom", "ahb", base + 0x7c, 0); | 804 | clk[IMX6QDL_CLK_ROM] = imx_clk_gate2_flags("rom", "ahb", base + 0x7c, 0, CLK_IS_CRITICAL); |
812 | clk[IMX6QDL_CLK_SATA] = imx_clk_gate2("sata", "ahb", base + 0x7c, 4); | 805 | clk[IMX6QDL_CLK_SATA] = imx_clk_gate2("sata", "ahb", base + 0x7c, 4); |
813 | clk[IMX6QDL_CLK_SDMA] = imx_clk_gate2("sdma", "ahb", base + 0x7c, 6); | 806 | clk[IMX6QDL_CLK_SDMA] = imx_clk_gate2("sdma", "ahb", base + 0x7c, 6); |
814 | clk[IMX6QDL_CLK_SPBA] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12); | 807 | clk[IMX6QDL_CLK_SPBA] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12); |
@@ -878,9 +871,6 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) | |||
878 | */ | 871 | */ |
879 | clk_set_parent(clk[IMX6QDL_CLK_ENFC_SEL], clk[IMX6QDL_CLK_PLL2_PFD2_396M]); | 872 | clk_set_parent(clk[IMX6QDL_CLK_ENFC_SEL], clk[IMX6QDL_CLK_PLL2_PFD2_396M]); |
880 | 873 | ||
881 | for (i = 0; i < ARRAY_SIZE(clks_init_on); i++) | ||
882 | clk_prepare_enable(clk[clks_init_on[i]]); | ||
883 | |||
884 | if (IS_ENABLED(CONFIG_USB_MXS_PHY)) { | 874 | if (IS_ENABLED(CONFIG_USB_MXS_PHY)) { |
885 | clk_prepare_enable(clk[IMX6QDL_CLK_USBPHY1_GATE]); | 875 | clk_prepare_enable(clk[IMX6QDL_CLK_USBPHY1_GATE]); |
886 | clk_prepare_enable(clk[IMX6QDL_CLK_USBPHY2_GATE]); | 876 | clk_prepare_enable(clk[IMX6QDL_CLK_USBPHY2_GATE]); |
diff --git a/drivers/clk/imx/clk-imx6sl.c b/drivers/clk/imx/clk-imx6sl.c index 66b1dd1cfad0..eb6bcbf345a3 100644 --- a/drivers/clk/imx/clk-imx6sl.c +++ b/drivers/clk/imx/clk-imx6sl.c | |||
@@ -104,10 +104,6 @@ static struct clk_onecell_data clk_data; | |||
104 | static void __iomem *ccm_base; | 104 | static void __iomem *ccm_base; |
105 | static void __iomem *anatop_base; | 105 | static void __iomem *anatop_base; |
106 | 106 | ||
107 | static const u32 clks_init_on[] __initconst = { | ||
108 | IMX6SL_CLK_IPG, IMX6SL_CLK_ARM, IMX6SL_CLK_MMDC_ROOT, | ||
109 | }; | ||
110 | |||
111 | /* | 107 | /* |
112 | * ERR005311 CCM: After exit from WAIT mode, unwanted interrupt(s) taken | 108 | * ERR005311 CCM: After exit from WAIT mode, unwanted interrupt(s) taken |
113 | * during WAIT mode entry process could cause cache memory | 109 | * during WAIT mode entry process could cause cache memory |
@@ -195,7 +191,6 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node) | |||
195 | { | 191 | { |
196 | struct device_node *np; | 192 | struct device_node *np; |
197 | void __iomem *base; | 193 | void __iomem *base; |
198 | int i; | ||
199 | int ret; | 194 | int ret; |
200 | 195 | ||
201 | clks[IMX6SL_CLK_DUMMY] = imx_clk_fixed("dummy", 0); | 196 | clks[IMX6SL_CLK_DUMMY] = imx_clk_fixed("dummy", 0); |
@@ -426,13 +421,6 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node) | |||
426 | pr_warn("%s: failed to set AHB clock rate %d!\n", | 421 | pr_warn("%s: failed to set AHB clock rate %d!\n", |
427 | __func__, ret); | 422 | __func__, ret); |
428 | 423 | ||
429 | /* | ||
430 | * Make sure those always on clocks are enabled to maintain the correct | ||
431 | * usecount and enabling/disabling of parent PLLs. | ||
432 | */ | ||
433 | for (i = 0; i < ARRAY_SIZE(clks_init_on); i++) | ||
434 | clk_prepare_enable(clks[clks_init_on[i]]); | ||
435 | |||
436 | if (IS_ENABLED(CONFIG_USB_MXS_PHY)) { | 424 | if (IS_ENABLED(CONFIG_USB_MXS_PHY)) { |
437 | clk_prepare_enable(clks[IMX6SL_CLK_USBPHY1_GATE]); | 425 | clk_prepare_enable(clks[IMX6SL_CLK_USBPHY1_GATE]); |
438 | clk_prepare_enable(clks[IMX6SL_CLK_USBPHY2_GATE]); | 426 | clk_prepare_enable(clks[IMX6SL_CLK_USBPHY2_GATE]); |
diff --git a/drivers/clk/imx/clk-imx6sll.c b/drivers/clk/imx/clk-imx6sll.c index 3651c77fbabe..52379ee49aec 100644 --- a/drivers/clk/imx/clk-imx6sll.c +++ b/drivers/clk/imx/clk-imx6sll.c | |||
@@ -92,6 +92,7 @@ static void __init imx6sll_clocks_init(struct device_node *ccm_node) | |||
92 | 92 | ||
93 | np = of_find_compatible_node(NULL, NULL, "fsl,imx6sll-anatop"); | 93 | np = of_find_compatible_node(NULL, NULL, "fsl,imx6sll-anatop"); |
94 | base = of_iomap(np, 0); | 94 | base = of_iomap(np, 0); |
95 | of_node_put(np); | ||
95 | WARN_ON(!base); | 96 | WARN_ON(!base); |
96 | 97 | ||
97 | /* Do not bypass PLLs initially */ | 98 | /* Do not bypass PLLs initially */ |
@@ -253,6 +254,7 @@ static void __init imx6sll_clocks_init(struct device_node *ccm_node) | |||
253 | clks[IMX6SLL_CLK_DCP] = imx_clk_gate2("dcp", "ahb", base + 0x68, 10); | 254 | clks[IMX6SLL_CLK_DCP] = imx_clk_gate2("dcp", "ahb", base + 0x68, 10); |
254 | clks[IMX6SLL_CLK_UART2_IPG] = imx_clk_gate2("uart2_ipg", "ipg", base + 0x68, 28); | 255 | clks[IMX6SLL_CLK_UART2_IPG] = imx_clk_gate2("uart2_ipg", "ipg", base + 0x68, 28); |
255 | clks[IMX6SLL_CLK_UART2_SERIAL] = imx_clk_gate2("uart2_serial", "uart_podf", base + 0x68, 28); | 256 | clks[IMX6SLL_CLK_UART2_SERIAL] = imx_clk_gate2("uart2_serial", "uart_podf", base + 0x68, 28); |
257 | clks[IMX6SLL_CLK_GPIO2] = imx_clk_gate2("gpio2", "ipg", base + 0x68, 30); | ||
256 | 258 | ||
257 | /* CCGR1 */ | 259 | /* CCGR1 */ |
258 | clks[IMX6SLL_CLK_ECSPI1] = imx_clk_gate2("ecspi1", "ecspi_podf", base + 0x6c, 0); | 260 | clks[IMX6SLL_CLK_ECSPI1] = imx_clk_gate2("ecspi1", "ecspi_podf", base + 0x6c, 0); |
@@ -267,13 +269,17 @@ static void __init imx6sll_clocks_init(struct device_node *ccm_node) | |||
267 | clks[IMX6SLL_CLK_GPT_SERIAL] = imx_clk_gate2("gpt1_serial", "perclk", base + 0x6c, 22); | 269 | clks[IMX6SLL_CLK_GPT_SERIAL] = imx_clk_gate2("gpt1_serial", "perclk", base + 0x6c, 22); |
268 | clks[IMX6SLL_CLK_UART4_IPG] = imx_clk_gate2("uart4_ipg", "ipg", base + 0x6c, 24); | 270 | clks[IMX6SLL_CLK_UART4_IPG] = imx_clk_gate2("uart4_ipg", "ipg", base + 0x6c, 24); |
269 | clks[IMX6SLL_CLK_UART4_SERIAL] = imx_clk_gate2("uart4_serail", "uart_podf", base + 0x6c, 24); | 271 | clks[IMX6SLL_CLK_UART4_SERIAL] = imx_clk_gate2("uart4_serail", "uart_podf", base + 0x6c, 24); |
272 | clks[IMX6SLL_CLK_GPIO1] = imx_clk_gate2("gpio1", "ipg", base + 0x6c, 26); | ||
273 | clks[IMX6SLL_CLK_GPIO5] = imx_clk_gate2("gpio5", "ipg", base + 0x6c, 30); | ||
270 | 274 | ||
271 | /* CCGR2 */ | 275 | /* CCGR2 */ |
276 | clks[IMX6SLL_CLK_GPIO6] = imx_clk_gate2("gpio6", "ipg", base + 0x70, 0); | ||
272 | clks[IMX6SLL_CLK_CSI] = imx_clk_gate2("csi", "axi", base + 0x70, 2); | 277 | clks[IMX6SLL_CLK_CSI] = imx_clk_gate2("csi", "axi", base + 0x70, 2); |
273 | clks[IMX6SLL_CLK_I2C1] = imx_clk_gate2("i2c1", "perclk", base + 0x70, 6); | 278 | clks[IMX6SLL_CLK_I2C1] = imx_clk_gate2("i2c1", "perclk", base + 0x70, 6); |
274 | clks[IMX6SLL_CLK_I2C2] = imx_clk_gate2("i2c2", "perclk", base + 0x70, 8); | 279 | clks[IMX6SLL_CLK_I2C2] = imx_clk_gate2("i2c2", "perclk", base + 0x70, 8); |
275 | clks[IMX6SLL_CLK_I2C3] = imx_clk_gate2("i2c3", "perclk", base + 0x70, 10); | 280 | clks[IMX6SLL_CLK_I2C3] = imx_clk_gate2("i2c3", "perclk", base + 0x70, 10); |
276 | clks[IMX6SLL_CLK_OCOTP] = imx_clk_gate2("ocotp", "ipg", base + 0x70, 12); | 281 | clks[IMX6SLL_CLK_OCOTP] = imx_clk_gate2("ocotp", "ipg", base + 0x70, 12); |
282 | clks[IMX6SLL_CLK_GPIO3] = imx_clk_gate2("gpio3", "ipg", base + 0x70, 26); | ||
277 | clks[IMX6SLL_CLK_LCDIF_APB] = imx_clk_gate2("lcdif_apb", "axi", base + 0x70, 28); | 283 | clks[IMX6SLL_CLK_LCDIF_APB] = imx_clk_gate2("lcdif_apb", "axi", base + 0x70, 28); |
278 | clks[IMX6SLL_CLK_PXP] = imx_clk_gate2("pxp", "axi", base + 0x70, 30); | 284 | clks[IMX6SLL_CLK_PXP] = imx_clk_gate2("pxp", "axi", base + 0x70, 30); |
279 | 285 | ||
@@ -283,6 +289,7 @@ static void __init imx6sll_clocks_init(struct device_node *ccm_node) | |||
283 | clks[IMX6SLL_CLK_EPDC_AXI] = imx_clk_gate2("epdc_aclk", "axi", base + 0x74, 4); | 289 | clks[IMX6SLL_CLK_EPDC_AXI] = imx_clk_gate2("epdc_aclk", "axi", base + 0x74, 4); |
284 | clks[IMX6SLL_CLK_EPDC_PIX] = imx_clk_gate2("epdc_pix", "epdc_podf", base + 0x74, 4); | 290 | clks[IMX6SLL_CLK_EPDC_PIX] = imx_clk_gate2("epdc_pix", "epdc_podf", base + 0x74, 4); |
285 | clks[IMX6SLL_CLK_LCDIF_PIX] = imx_clk_gate2("lcdif_pix", "lcdif_podf", base + 0x74, 10); | 291 | clks[IMX6SLL_CLK_LCDIF_PIX] = imx_clk_gate2("lcdif_pix", "lcdif_podf", base + 0x74, 10); |
292 | clks[IMX6SLL_CLK_GPIO4] = imx_clk_gate2("gpio4", "ipg", base + 0x74, 12); | ||
286 | clks[IMX6SLL_CLK_WDOG1] = imx_clk_gate2("wdog1", "ipg", base + 0x74, 16); | 293 | clks[IMX6SLL_CLK_WDOG1] = imx_clk_gate2("wdog1", "ipg", base + 0x74, 16); |
287 | clks[IMX6SLL_CLK_MMDC_P0_FAST] = imx_clk_gate_flags("mmdc_p0_fast", "mmdc_podf", base + 0x74, 20, CLK_IS_CRITICAL); | 294 | clks[IMX6SLL_CLK_MMDC_P0_FAST] = imx_clk_gate_flags("mmdc_p0_fast", "mmdc_podf", base + 0x74, 20, CLK_IS_CRITICAL); |
288 | clks[IMX6SLL_CLK_MMDC_P0_IPG] = imx_clk_gate2_flags("mmdc_p0_ipg", "ipg", base + 0x74, 24, CLK_IS_CRITICAL); | 295 | clks[IMX6SLL_CLK_MMDC_P0_IPG] = imx_clk_gate2_flags("mmdc_p0_ipg", "ipg", base + 0x74, 24, CLK_IS_CRITICAL); |
diff --git a/drivers/clk/imx/clk-imx6sx.c b/drivers/clk/imx/clk-imx6sx.c index 10c771b91ef6..d9f2890ffe62 100644 --- a/drivers/clk/imx/clk-imx6sx.c +++ b/drivers/clk/imx/clk-imx6sx.c | |||
@@ -92,14 +92,6 @@ static const char *pll7_bypass_sels[] = { "pll7", "pll7_bypass_src", }; | |||
92 | static struct clk *clks[IMX6SX_CLK_CLK_END]; | 92 | static struct clk *clks[IMX6SX_CLK_CLK_END]; |
93 | static struct clk_onecell_data clk_data; | 93 | static struct clk_onecell_data clk_data; |
94 | 94 | ||
95 | static int const clks_init_on[] __initconst = { | ||
96 | IMX6SX_CLK_AIPS_TZ1, IMX6SX_CLK_AIPS_TZ2, IMX6SX_CLK_AIPS_TZ3, | ||
97 | IMX6SX_CLK_IPMUX1, IMX6SX_CLK_IPMUX2, IMX6SX_CLK_IPMUX3, | ||
98 | IMX6SX_CLK_WAKEUP, IMX6SX_CLK_MMDC_P0_FAST, IMX6SX_CLK_MMDC_P0_IPG, | ||
99 | IMX6SX_CLK_ROM, IMX6SX_CLK_ARM, IMX6SX_CLK_IPG, IMX6SX_CLK_OCRAM, | ||
100 | IMX6SX_CLK_PER2_MAIN, IMX6SX_CLK_PERCLK, IMX6SX_CLK_TZASC1, | ||
101 | }; | ||
102 | |||
103 | static const struct clk_div_table clk_enet_ref_table[] = { | 95 | static const struct clk_div_table clk_enet_ref_table[] = { |
104 | { .val = 0, .div = 20, }, | 96 | { .val = 0, .div = 20, }, |
105 | { .val = 1, .div = 10, }, | 97 | { .val = 1, .div = 10, }, |
@@ -142,7 +134,6 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node) | |||
142 | { | 134 | { |
143 | struct device_node *np; | 135 | struct device_node *np; |
144 | void __iomem *base; | 136 | void __iomem *base; |
145 | int i; | ||
146 | 137 | ||
147 | clks[IMX6SX_CLK_DUMMY] = imx_clk_fixed("dummy", 0); | 138 | clks[IMX6SX_CLK_DUMMY] = imx_clk_fixed("dummy", 0); |
148 | 139 | ||
@@ -332,7 +323,7 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node) | |||
332 | clks[IMX6SX_CLK_QSPI1_PODF] = imx_clk_divider("qspi1_podf", "qspi1_sel", base + 0x1c, 26, 3); | 323 | clks[IMX6SX_CLK_QSPI1_PODF] = imx_clk_divider("qspi1_podf", "qspi1_sel", base + 0x1c, 26, 3); |
333 | clks[IMX6SX_CLK_EIM_SLOW_PODF] = imx_clk_divider("eim_slow_podf", "eim_slow_sel", base + 0x1c, 23, 3); | 324 | clks[IMX6SX_CLK_EIM_SLOW_PODF] = imx_clk_divider("eim_slow_podf", "eim_slow_sel", base + 0x1c, 23, 3); |
334 | clks[IMX6SX_CLK_LCDIF2_PODF] = imx_clk_divider("lcdif2_podf", "lcdif2_pred", base + 0x1c, 20, 3); | 325 | clks[IMX6SX_CLK_LCDIF2_PODF] = imx_clk_divider("lcdif2_podf", "lcdif2_pred", base + 0x1c, 20, 3); |
335 | clks[IMX6SX_CLK_PERCLK] = imx_clk_divider("perclk", "perclk_sel", base + 0x1c, 0, 6); | 326 | clks[IMX6SX_CLK_PERCLK] = imx_clk_divider_flags("perclk", "perclk_sel", base + 0x1c, 0, 6, CLK_IS_CRITICAL); |
336 | clks[IMX6SX_CLK_VID_PODF] = imx_clk_divider("vid_podf", "vid_sel", base + 0x20, 24, 2); | 327 | clks[IMX6SX_CLK_VID_PODF] = imx_clk_divider("vid_podf", "vid_sel", base + 0x20, 24, 2); |
337 | clks[IMX6SX_CLK_CAN_PODF] = imx_clk_divider("can_podf", "can_sel", base + 0x20, 2, 6); | 328 | clks[IMX6SX_CLK_CAN_PODF] = imx_clk_divider("can_podf", "can_sel", base + 0x20, 2, 6); |
338 | clks[IMX6SX_CLK_USDHC4_PODF] = imx_clk_divider("usdhc4_podf", "usdhc4_sel", base + 0x24, 22, 3); | 329 | clks[IMX6SX_CLK_USDHC4_PODF] = imx_clk_divider("usdhc4_podf", "usdhc4_sel", base + 0x24, 22, 3); |
@@ -380,8 +371,8 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node) | |||
380 | 371 | ||
381 | /* name parent_name reg shift */ | 372 | /* name parent_name reg shift */ |
382 | /* CCGR0 */ | 373 | /* CCGR0 */ |
383 | clks[IMX6SX_CLK_AIPS_TZ1] = imx_clk_gate2("aips_tz1", "ahb", base + 0x68, 0); | 374 | clks[IMX6SX_CLK_AIPS_TZ1] = imx_clk_gate2_flags("aips_tz1", "ahb", base + 0x68, 0, CLK_IS_CRITICAL); |
384 | clks[IMX6SX_CLK_AIPS_TZ2] = imx_clk_gate2("aips_tz2", "ahb", base + 0x68, 2); | 375 | clks[IMX6SX_CLK_AIPS_TZ2] = imx_clk_gate2_flags("aips_tz2", "ahb", base + 0x68, 2, CLK_IS_CRITICAL); |
385 | clks[IMX6SX_CLK_APBH_DMA] = imx_clk_gate2("apbh_dma", "usdhc3", base + 0x68, 4); | 376 | clks[IMX6SX_CLK_APBH_DMA] = imx_clk_gate2("apbh_dma", "usdhc3", base + 0x68, 4); |
386 | clks[IMX6SX_CLK_ASRC_MEM] = imx_clk_gate2_shared("asrc_mem", "ahb", base + 0x68, 6, &share_count_asrc); | 377 | clks[IMX6SX_CLK_ASRC_MEM] = imx_clk_gate2_shared("asrc_mem", "ahb", base + 0x68, 6, &share_count_asrc); |
387 | clks[IMX6SX_CLK_ASRC_IPG] = imx_clk_gate2_shared("asrc_ipg", "ahb", base + 0x68, 6, &share_count_asrc); | 378 | clks[IMX6SX_CLK_ASRC_IPG] = imx_clk_gate2_shared("asrc_ipg", "ahb", base + 0x68, 6, &share_count_asrc); |
@@ -394,7 +385,7 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node) | |||
394 | clks[IMX6SX_CLK_CAN2_SERIAL] = imx_clk_gate2("can2_serial", "can_podf", base + 0x68, 20); | 385 | clks[IMX6SX_CLK_CAN2_SERIAL] = imx_clk_gate2("can2_serial", "can_podf", base + 0x68, 20); |
395 | clks[IMX6SX_CLK_DCIC1] = imx_clk_gate2("dcic1", "display_podf", base + 0x68, 24); | 386 | clks[IMX6SX_CLK_DCIC1] = imx_clk_gate2("dcic1", "display_podf", base + 0x68, 24); |
396 | clks[IMX6SX_CLK_DCIC2] = imx_clk_gate2("dcic2", "display_podf", base + 0x68, 26); | 387 | clks[IMX6SX_CLK_DCIC2] = imx_clk_gate2("dcic2", "display_podf", base + 0x68, 26); |
397 | clks[IMX6SX_CLK_AIPS_TZ3] = imx_clk_gate2("aips_tz3", "ahb", base + 0x68, 30); | 388 | clks[IMX6SX_CLK_AIPS_TZ3] = imx_clk_gate2_flags("aips_tz3", "ahb", base + 0x68, 30, CLK_IS_CRITICAL); |
398 | 389 | ||
399 | /* CCGR1 */ | 390 | /* CCGR1 */ |
400 | clks[IMX6SX_CLK_ECSPI1] = imx_clk_gate2("ecspi1", "ecspi_podf", base + 0x6c, 0); | 391 | clks[IMX6SX_CLK_ECSPI1] = imx_clk_gate2("ecspi1", "ecspi_podf", base + 0x6c, 0); |
@@ -407,10 +398,11 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node) | |||
407 | clks[IMX6SX_CLK_ESAI_EXTAL] = imx_clk_gate2_shared("esai_extal", "esai_podf", base + 0x6c, 16, &share_count_esai); | 398 | clks[IMX6SX_CLK_ESAI_EXTAL] = imx_clk_gate2_shared("esai_extal", "esai_podf", base + 0x6c, 16, &share_count_esai); |
408 | clks[IMX6SX_CLK_ESAI_IPG] = imx_clk_gate2_shared("esai_ipg", "ahb", base + 0x6c, 16, &share_count_esai); | 399 | clks[IMX6SX_CLK_ESAI_IPG] = imx_clk_gate2_shared("esai_ipg", "ahb", base + 0x6c, 16, &share_count_esai); |
409 | clks[IMX6SX_CLK_ESAI_MEM] = imx_clk_gate2_shared("esai_mem", "ahb", base + 0x6c, 16, &share_count_esai); | 400 | clks[IMX6SX_CLK_ESAI_MEM] = imx_clk_gate2_shared("esai_mem", "ahb", base + 0x6c, 16, &share_count_esai); |
410 | clks[IMX6SX_CLK_WAKEUP] = imx_clk_gate2("wakeup", "ipg", base + 0x6c, 18); | 401 | clks[IMX6SX_CLK_WAKEUP] = imx_clk_gate2_flags("wakeup", "ipg", base + 0x6c, 18, CLK_IS_CRITICAL); |
411 | clks[IMX6SX_CLK_GPT_BUS] = imx_clk_gate2("gpt_bus", "perclk", base + 0x6c, 20); | 402 | clks[IMX6SX_CLK_GPT_BUS] = imx_clk_gate2("gpt_bus", "perclk", base + 0x6c, 20); |
412 | clks[IMX6SX_CLK_GPT_SERIAL] = imx_clk_gate2("gpt_serial", "perclk", base + 0x6c, 22); | 403 | clks[IMX6SX_CLK_GPT_SERIAL] = imx_clk_gate2("gpt_serial", "perclk", base + 0x6c, 22); |
413 | clks[IMX6SX_CLK_GPU] = imx_clk_gate2("gpu", "gpu_core_podf", base + 0x6c, 26); | 404 | clks[IMX6SX_CLK_GPU] = imx_clk_gate2("gpu", "gpu_core_podf", base + 0x6c, 26); |
405 | clks[IMX6SX_CLK_OCRAM_S] = imx_clk_gate2("ocram_s", "ahb", base + 0x6c, 28); | ||
414 | clks[IMX6SX_CLK_CANFD] = imx_clk_gate2("canfd", "can_podf", base + 0x6c, 30); | 406 | clks[IMX6SX_CLK_CANFD] = imx_clk_gate2("canfd", "can_podf", base + 0x6c, 30); |
415 | 407 | ||
416 | /* CCGR2 */ | 408 | /* CCGR2 */ |
@@ -420,10 +412,10 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node) | |||
420 | clks[IMX6SX_CLK_I2C3] = imx_clk_gate2("i2c3", "perclk", base + 0x70, 10); | 412 | clks[IMX6SX_CLK_I2C3] = imx_clk_gate2("i2c3", "perclk", base + 0x70, 10); |
421 | clks[IMX6SX_CLK_OCOTP] = imx_clk_gate2("ocotp", "ipg", base + 0x70, 12); | 413 | clks[IMX6SX_CLK_OCOTP] = imx_clk_gate2("ocotp", "ipg", base + 0x70, 12); |
422 | clks[IMX6SX_CLK_IOMUXC] = imx_clk_gate2("iomuxc", "lcdif1_podf", base + 0x70, 14); | 414 | clks[IMX6SX_CLK_IOMUXC] = imx_clk_gate2("iomuxc", "lcdif1_podf", base + 0x70, 14); |
423 | clks[IMX6SX_CLK_IPMUX1] = imx_clk_gate2("ipmux1", "ahb", base + 0x70, 16); | 415 | clks[IMX6SX_CLK_IPMUX1] = imx_clk_gate2_flags("ipmux1", "ahb", base + 0x70, 16, CLK_IS_CRITICAL); |
424 | clks[IMX6SX_CLK_IPMUX2] = imx_clk_gate2("ipmux2", "ahb", base + 0x70, 18); | 416 | clks[IMX6SX_CLK_IPMUX2] = imx_clk_gate2_flags("ipmux2", "ahb", base + 0x70, 18, CLK_IS_CRITICAL); |
425 | clks[IMX6SX_CLK_IPMUX3] = imx_clk_gate2("ipmux3", "ahb", base + 0x70, 20); | 417 | clks[IMX6SX_CLK_IPMUX3] = imx_clk_gate2_flags("ipmux3", "ahb", base + 0x70, 20, CLK_IS_CRITICAL); |
426 | clks[IMX6SX_CLK_TZASC1] = imx_clk_gate2("tzasc1", "mmdc_podf", base + 0x70, 22); | 418 | clks[IMX6SX_CLK_TZASC1] = imx_clk_gate2_flags("tzasc1", "mmdc_podf", base + 0x70, 22, CLK_IS_CRITICAL); |
427 | clks[IMX6SX_CLK_LCDIF_APB] = imx_clk_gate2("lcdif_apb", "display_podf", base + 0x70, 28); | 419 | clks[IMX6SX_CLK_LCDIF_APB] = imx_clk_gate2("lcdif_apb", "display_podf", base + 0x70, 28); |
428 | clks[IMX6SX_CLK_PXP_AXI] = imx_clk_gate2("pxp_axi", "display_podf", base + 0x70, 30); | 420 | clks[IMX6SX_CLK_PXP_AXI] = imx_clk_gate2("pxp_axi", "display_podf", base + 0x70, 30); |
429 | 421 | ||
@@ -437,15 +429,15 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node) | |||
437 | clks[IMX6SX_CLK_LDB_DI0] = imx_clk_gate2("ldb_di0", "ldb_di0_div_sel", base + 0x74, 12); | 429 | clks[IMX6SX_CLK_LDB_DI0] = imx_clk_gate2("ldb_di0", "ldb_di0_div_sel", base + 0x74, 12); |
438 | clks[IMX6SX_CLK_QSPI1] = imx_clk_gate2("qspi1", "qspi1_podf", base + 0x74, 14); | 430 | clks[IMX6SX_CLK_QSPI1] = imx_clk_gate2("qspi1", "qspi1_podf", base + 0x74, 14); |
439 | clks[IMX6SX_CLK_MLB] = imx_clk_gate2("mlb", "ahb", base + 0x74, 18); | 431 | clks[IMX6SX_CLK_MLB] = imx_clk_gate2("mlb", "ahb", base + 0x74, 18); |
440 | clks[IMX6SX_CLK_MMDC_P0_FAST] = imx_clk_gate2("mmdc_p0_fast", "mmdc_podf", base + 0x74, 20); | 432 | clks[IMX6SX_CLK_MMDC_P0_FAST] = imx_clk_gate2_flags("mmdc_p0_fast", "mmdc_podf", base + 0x74, 20, CLK_IS_CRITICAL); |
441 | clks[IMX6SX_CLK_MMDC_P0_IPG] = imx_clk_gate2("mmdc_p0_ipg", "ipg", base + 0x74, 24); | 433 | clks[IMX6SX_CLK_MMDC_P0_IPG] = imx_clk_gate2_flags("mmdc_p0_ipg", "ipg", base + 0x74, 24, CLK_IS_CRITICAL); |
442 | clks[IMX6SX_CLK_OCRAM] = imx_clk_gate2("ocram", "ocram_podf", base + 0x74, 28); | 434 | clks[IMX6SX_CLK_OCRAM] = imx_clk_gate2_flags("ocram", "ocram_podf", base + 0x74, 28, CLK_IS_CRITICAL); |
443 | 435 | ||
444 | /* CCGR4 */ | 436 | /* CCGR4 */ |
445 | clks[IMX6SX_CLK_PCIE_AXI] = imx_clk_gate2("pcie_axi", "display_podf", base + 0x78, 0); | 437 | clks[IMX6SX_CLK_PCIE_AXI] = imx_clk_gate2("pcie_axi", "display_podf", base + 0x78, 0); |
446 | clks[IMX6SX_CLK_QSPI2] = imx_clk_gate2("qspi2", "qspi2_podf", base + 0x78, 10); | 438 | clks[IMX6SX_CLK_QSPI2] = imx_clk_gate2("qspi2", "qspi2_podf", base + 0x78, 10); |
447 | clks[IMX6SX_CLK_PER1_BCH] = imx_clk_gate2("per1_bch", "usdhc3", base + 0x78, 12); | 439 | clks[IMX6SX_CLK_PER1_BCH] = imx_clk_gate2("per1_bch", "usdhc3", base + 0x78, 12); |
448 | clks[IMX6SX_CLK_PER2_MAIN] = imx_clk_gate2("per2_main", "ahb", base + 0x78, 14); | 440 | clks[IMX6SX_CLK_PER2_MAIN] = imx_clk_gate2_flags("per2_main", "ahb", base + 0x78, 14, CLK_IS_CRITICAL); |
449 | clks[IMX6SX_CLK_PWM1] = imx_clk_gate2("pwm1", "perclk", base + 0x78, 16); | 441 | clks[IMX6SX_CLK_PWM1] = imx_clk_gate2("pwm1", "perclk", base + 0x78, 16); |
450 | clks[IMX6SX_CLK_PWM2] = imx_clk_gate2("pwm2", "perclk", base + 0x78, 18); | 442 | clks[IMX6SX_CLK_PWM2] = imx_clk_gate2("pwm2", "perclk", base + 0x78, 18); |
451 | clks[IMX6SX_CLK_PWM3] = imx_clk_gate2("pwm3", "perclk", base + 0x78, 20); | 443 | clks[IMX6SX_CLK_PWM3] = imx_clk_gate2("pwm3", "perclk", base + 0x78, 20); |
@@ -456,7 +448,7 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node) | |||
456 | clks[IMX6SX_CLK_GPMI_APB] = imx_clk_gate2("gpmi_apb", "usdhc3", base + 0x78, 30); | 448 | clks[IMX6SX_CLK_GPMI_APB] = imx_clk_gate2("gpmi_apb", "usdhc3", base + 0x78, 30); |
457 | 449 | ||
458 | /* CCGR5 */ | 450 | /* CCGR5 */ |
459 | clks[IMX6SX_CLK_ROM] = imx_clk_gate2("rom", "ahb", base + 0x7c, 0); | 451 | clks[IMX6SX_CLK_ROM] = imx_clk_gate2_flags("rom", "ahb", base + 0x7c, 0, CLK_IS_CRITICAL); |
460 | clks[IMX6SX_CLK_SDMA] = imx_clk_gate2("sdma", "ahb", base + 0x7c, 6); | 452 | clks[IMX6SX_CLK_SDMA] = imx_clk_gate2("sdma", "ahb", base + 0x7c, 6); |
461 | clks[IMX6SX_CLK_SPBA] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12); | 453 | clks[IMX6SX_CLK_SPBA] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12); |
462 | clks[IMX6SX_CLK_AUDIO] = imx_clk_gate2_shared("audio", "audio_podf", base + 0x7c, 14, &share_count_audio); | 454 | clks[IMX6SX_CLK_AUDIO] = imx_clk_gate2_shared("audio", "audio_podf", base + 0x7c, 14, &share_count_audio); |
@@ -502,9 +494,6 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node) | |||
502 | clk_data.clk_num = ARRAY_SIZE(clks); | 494 | clk_data.clk_num = ARRAY_SIZE(clks); |
503 | of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); | 495 | of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); |
504 | 496 | ||
505 | for (i = 0; i < ARRAY_SIZE(clks_init_on); i++) | ||
506 | clk_prepare_enable(clks[clks_init_on[i]]); | ||
507 | |||
508 | if (IS_ENABLED(CONFIG_USB_MXS_PHY)) { | 497 | if (IS_ENABLED(CONFIG_USB_MXS_PHY)) { |
509 | clk_prepare_enable(clks[IMX6SX_CLK_USBPHY1_GATE]); | 498 | clk_prepare_enable(clks[IMX6SX_CLK_USBPHY1_GATE]); |
510 | clk_prepare_enable(clks[IMX6SX_CLK_USBPHY2_GATE]); | 499 | clk_prepare_enable(clks[IMX6SX_CLK_USBPHY2_GATE]); |
diff --git a/drivers/clk/imx/clk-imx6ul.c b/drivers/clk/imx/clk-imx6ul.c index ba563ba50b40..361b43f9742e 100644 --- a/drivers/clk/imx/clk-imx6ul.c +++ b/drivers/clk/imx/clk-imx6ul.c | |||
@@ -79,12 +79,6 @@ static const char *cko_sels[] = { "cko1", "cko2", }; | |||
79 | static struct clk *clks[IMX6UL_CLK_END]; | 79 | static struct clk *clks[IMX6UL_CLK_END]; |
80 | static struct clk_onecell_data clk_data; | 80 | static struct clk_onecell_data clk_data; |
81 | 81 | ||
82 | static int const clks_init_on[] __initconst = { | ||
83 | IMX6UL_CLK_AIPSTZ1, IMX6UL_CLK_AIPSTZ2, | ||
84 | IMX6UL_CLK_AXI, IMX6UL_CLK_ARM, IMX6UL_CLK_ROM, | ||
85 | IMX6UL_CLK_MMDC_P0_FAST, IMX6UL_CLK_MMDC_P0_IPG, | ||
86 | }; | ||
87 | |||
88 | static const struct clk_div_table clk_enet_ref_table[] = { | 82 | static const struct clk_div_table clk_enet_ref_table[] = { |
89 | { .val = 0, .div = 20, }, | 83 | { .val = 0, .div = 20, }, |
90 | { .val = 1, .div = 10, }, | 84 | { .val = 1, .div = 10, }, |
@@ -129,7 +123,6 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node) | |||
129 | { | 123 | { |
130 | struct device_node *np; | 124 | struct device_node *np; |
131 | void __iomem *base; | 125 | void __iomem *base; |
132 | int i; | ||
133 | 126 | ||
134 | clks[IMX6UL_CLK_DUMMY] = imx_clk_fixed("dummy", 0); | 127 | clks[IMX6UL_CLK_DUMMY] = imx_clk_fixed("dummy", 0); |
135 | 128 | ||
@@ -142,6 +135,7 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node) | |||
142 | 135 | ||
143 | np = of_find_compatible_node(NULL, NULL, "fsl,imx6ul-anatop"); | 136 | np = of_find_compatible_node(NULL, NULL, "fsl,imx6ul-anatop"); |
144 | base = of_iomap(np, 0); | 137 | base = of_iomap(np, 0); |
138 | of_node_put(np); | ||
145 | WARN_ON(!base); | 139 | WARN_ON(!base); |
146 | 140 | ||
147 | 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 | 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)); |
@@ -336,8 +330,8 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node) | |||
336 | clks[IMX6UL_CLK_AHB] = imx_clk_busy_divider("ahb", "periph", base + 0x14, 10, 3, base + 0x48, 1); | 330 | clks[IMX6UL_CLK_AHB] = imx_clk_busy_divider("ahb", "periph", base + 0x14, 10, 3, base + 0x48, 1); |
337 | 331 | ||
338 | /* CCGR0 */ | 332 | /* CCGR0 */ |
339 | clks[IMX6UL_CLK_AIPSTZ1] = imx_clk_gate2("aips_tz1", "ahb", base + 0x68, 0); | 333 | clks[IMX6UL_CLK_AIPSTZ1] = imx_clk_gate2_flags("aips_tz1", "ahb", base + 0x68, 0, CLK_IS_CRITICAL); |
340 | clks[IMX6UL_CLK_AIPSTZ2] = imx_clk_gate2("aips_tz2", "ahb", base + 0x68, 2); | 334 | clks[IMX6UL_CLK_AIPSTZ2] = imx_clk_gate2_flags("aips_tz2", "ahb", base + 0x68, 2, CLK_IS_CRITICAL); |
341 | clks[IMX6UL_CLK_APBHDMA] = imx_clk_gate2("apbh_dma", "bch_podf", base + 0x68, 4); | 335 | clks[IMX6UL_CLK_APBHDMA] = imx_clk_gate2("apbh_dma", "bch_podf", base + 0x68, 4); |
342 | clks[IMX6UL_CLK_ASRC_IPG] = imx_clk_gate2_shared("asrc_ipg", "ahb", base + 0x68, 6, &share_count_asrc); | 336 | clks[IMX6UL_CLK_ASRC_IPG] = imx_clk_gate2_shared("asrc_ipg", "ahb", base + 0x68, 6, &share_count_asrc); |
343 | clks[IMX6UL_CLK_ASRC_MEM] = imx_clk_gate2_shared("asrc_mem", "ahb", base + 0x68, 6, &share_count_asrc); | 337 | clks[IMX6UL_CLK_ASRC_MEM] = imx_clk_gate2_shared("asrc_mem", "ahb", base + 0x68, 6, &share_count_asrc); |
@@ -360,6 +354,7 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node) | |||
360 | clks[IMX6UL_CLK_UART2_SERIAL] = imx_clk_gate2("uart2_serial", "uart_podf", base + 0x68, 28); | 354 | clks[IMX6UL_CLK_UART2_SERIAL] = imx_clk_gate2("uart2_serial", "uart_podf", base + 0x68, 28); |
361 | if (clk_on_imx6ull()) | 355 | if (clk_on_imx6ull()) |
362 | clks[IMX6UL_CLK_AIPSTZ3] = imx_clk_gate2("aips_tz3", "ahb", base + 0x80, 18); | 356 | clks[IMX6UL_CLK_AIPSTZ3] = imx_clk_gate2("aips_tz3", "ahb", base + 0x80, 18); |
357 | clks[IMX6UL_CLK_GPIO2] = imx_clk_gate2("gpio2", "ipg", base + 0x68, 30); | ||
363 | 358 | ||
364 | /* CCGR1 */ | 359 | /* CCGR1 */ |
365 | clks[IMX6UL_CLK_ECSPI1] = imx_clk_gate2("ecspi1", "ecspi_podf", base + 0x6c, 0); | 360 | clks[IMX6UL_CLK_ECSPI1] = imx_clk_gate2("ecspi1", "ecspi_podf", base + 0x6c, 0); |
@@ -376,6 +371,8 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node) | |||
376 | clks[IMX6UL_CLK_GPT1_SERIAL] = imx_clk_gate2("gpt1_serial", "perclk", base + 0x6c, 22); | 371 | clks[IMX6UL_CLK_GPT1_SERIAL] = imx_clk_gate2("gpt1_serial", "perclk", base + 0x6c, 22); |
377 | clks[IMX6UL_CLK_UART4_IPG] = imx_clk_gate2("uart4_ipg", "ipg", base + 0x6c, 24); | 372 | clks[IMX6UL_CLK_UART4_IPG] = imx_clk_gate2("uart4_ipg", "ipg", base + 0x6c, 24); |
378 | clks[IMX6UL_CLK_UART4_SERIAL] = imx_clk_gate2("uart4_serial", "uart_podf", base + 0x6c, 24); | 373 | clks[IMX6UL_CLK_UART4_SERIAL] = imx_clk_gate2("uart4_serial", "uart_podf", base + 0x6c, 24); |
374 | clks[IMX6UL_CLK_GPIO1] = imx_clk_gate2("gpio1", "ipg", base + 0x6c, 26); | ||
375 | clks[IMX6UL_CLK_GPIO5] = imx_clk_gate2("gpio5", "ipg", base + 0x6c, 30); | ||
379 | 376 | ||
380 | /* CCGR2 */ | 377 | /* CCGR2 */ |
381 | if (clk_on_imx6ull()) { | 378 | if (clk_on_imx6ull()) { |
@@ -389,6 +386,7 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node) | |||
389 | clks[IMX6UL_CLK_I2C3] = imx_clk_gate2("i2c3", "perclk", base + 0x70, 10); | 386 | clks[IMX6UL_CLK_I2C3] = imx_clk_gate2("i2c3", "perclk", base + 0x70, 10); |
390 | clks[IMX6UL_CLK_OCOTP] = imx_clk_gate2("ocotp", "ipg", base + 0x70, 12); | 387 | clks[IMX6UL_CLK_OCOTP] = imx_clk_gate2("ocotp", "ipg", base + 0x70, 12); |
391 | clks[IMX6UL_CLK_IOMUXC] = imx_clk_gate2("iomuxc", "lcdif_podf", base + 0x70, 14); | 388 | clks[IMX6UL_CLK_IOMUXC] = imx_clk_gate2("iomuxc", "lcdif_podf", base + 0x70, 14); |
389 | clks[IMX6UL_CLK_GPIO3] = imx_clk_gate2("gpio3", "ipg", base + 0x70, 26); | ||
392 | clks[IMX6UL_CLK_LCDIF_APB] = imx_clk_gate2("lcdif_apb", "axi", base + 0x70, 28); | 390 | clks[IMX6UL_CLK_LCDIF_APB] = imx_clk_gate2("lcdif_apb", "axi", base + 0x70, 28); |
393 | clks[IMX6UL_CLK_PXP] = imx_clk_gate2("pxp", "axi", base + 0x70, 30); | 391 | clks[IMX6UL_CLK_PXP] = imx_clk_gate2("pxp", "axi", base + 0x70, 30); |
394 | 392 | ||
@@ -405,11 +403,12 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node) | |||
405 | clks[IMX6UL_CLK_UART6_IPG] = imx_clk_gate2("uart6_ipg", "ipg", base + 0x74, 6); | 403 | clks[IMX6UL_CLK_UART6_IPG] = imx_clk_gate2("uart6_ipg", "ipg", base + 0x74, 6); |
406 | clks[IMX6UL_CLK_UART6_SERIAL] = imx_clk_gate2("uart6_serial", "uart_podf", base + 0x74, 6); | 404 | clks[IMX6UL_CLK_UART6_SERIAL] = imx_clk_gate2("uart6_serial", "uart_podf", base + 0x74, 6); |
407 | clks[IMX6UL_CLK_LCDIF_PIX] = imx_clk_gate2("lcdif_pix", "lcdif_podf", base + 0x74, 10); | 405 | clks[IMX6UL_CLK_LCDIF_PIX] = imx_clk_gate2("lcdif_pix", "lcdif_podf", base + 0x74, 10); |
406 | clks[IMX6UL_CLK_GPIO4] = imx_clk_gate2("gpio4", "ipg", base + 0x74, 12); | ||
408 | clks[IMX6UL_CLK_QSPI] = imx_clk_gate2("qspi1", "qspi1_podf", base + 0x74, 14); | 407 | clks[IMX6UL_CLK_QSPI] = imx_clk_gate2("qspi1", "qspi1_podf", base + 0x74, 14); |
409 | clks[IMX6UL_CLK_WDOG1] = imx_clk_gate2("wdog1", "ipg", base + 0x74, 16); | 408 | clks[IMX6UL_CLK_WDOG1] = imx_clk_gate2("wdog1", "ipg", base + 0x74, 16); |
410 | clks[IMX6UL_CLK_MMDC_P0_FAST] = imx_clk_gate("mmdc_p0_fast", "mmdc_podf", base + 0x74, 20); | 409 | clks[IMX6UL_CLK_MMDC_P0_FAST] = imx_clk_gate_flags("mmdc_p0_fast", "mmdc_podf", base + 0x74, 20, CLK_IS_CRITICAL); |
411 | clks[IMX6UL_CLK_MMDC_P0_IPG] = imx_clk_gate2("mmdc_p0_ipg", "ipg", base + 0x74, 24); | 410 | clks[IMX6UL_CLK_MMDC_P0_IPG] = imx_clk_gate2_flags("mmdc_p0_ipg", "ipg", base + 0x74, 24, CLK_IS_CRITICAL); |
412 | clks[IMX6UL_CLK_AXI] = imx_clk_gate("axi", "axi_podf", base + 0x74, 28); | 411 | clks[IMX6UL_CLK_AXI] = imx_clk_gate_flags("axi", "axi_podf", base + 0x74, 28, CLK_IS_CRITICAL); |
413 | 412 | ||
414 | /* CCGR4 */ | 413 | /* CCGR4 */ |
415 | clks[IMX6UL_CLK_PER_BCH] = imx_clk_gate2("per_bch", "bch_podf", base + 0x78, 12); | 414 | clks[IMX6UL_CLK_PER_BCH] = imx_clk_gate2("per_bch", "bch_podf", base + 0x78, 12); |
@@ -423,7 +422,7 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node) | |||
423 | clks[IMX6UL_CLK_GPMI_APB] = imx_clk_gate2("gpmi_apb", "bch_podf", base + 0x78, 30); | 422 | clks[IMX6UL_CLK_GPMI_APB] = imx_clk_gate2("gpmi_apb", "bch_podf", base + 0x78, 30); |
424 | 423 | ||
425 | /* CCGR5 */ | 424 | /* CCGR5 */ |
426 | clks[IMX6UL_CLK_ROM] = imx_clk_gate2("rom", "ahb", base + 0x7c, 0); | 425 | clks[IMX6UL_CLK_ROM] = imx_clk_gate2_flags("rom", "ahb", base + 0x7c, 0, CLK_IS_CRITICAL); |
427 | clks[IMX6UL_CLK_SDMA] = imx_clk_gate2("sdma", "ahb", base + 0x7c, 6); | 426 | clks[IMX6UL_CLK_SDMA] = imx_clk_gate2("sdma", "ahb", base + 0x7c, 6); |
428 | clks[IMX6UL_CLK_KPP] = imx_clk_gate2("kpp", "ipg", base + 0x7c, 8); | 427 | clks[IMX6UL_CLK_KPP] = imx_clk_gate2("kpp", "ipg", base + 0x7c, 8); |
429 | clks[IMX6UL_CLK_WDOG2] = imx_clk_gate2("wdog2", "ipg", base + 0x7c, 10); | 428 | clks[IMX6UL_CLK_WDOG2] = imx_clk_gate2("wdog2", "ipg", base + 0x7c, 10); |
@@ -497,10 +496,6 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node) | |||
497 | clk_set_rate(clks[IMX6UL_CLK_ENET2_REF], 50000000); | 496 | clk_set_rate(clks[IMX6UL_CLK_ENET2_REF], 50000000); |
498 | clk_set_rate(clks[IMX6UL_CLK_CSI], 24000000); | 497 | clk_set_rate(clks[IMX6UL_CLK_CSI], 24000000); |
499 | 498 | ||
500 | /* keep all the clks on just for bringup */ | ||
501 | for (i = 0; i < ARRAY_SIZE(clks_init_on); i++) | ||
502 | clk_prepare_enable(clks[clks_init_on[i]]); | ||
503 | |||
504 | if (clk_on_imx6ull()) | 499 | if (clk_on_imx6ull()) |
505 | clk_prepare_enable(clks[IMX6UL_CLK_AIPSTZ3]); | 500 | clk_prepare_enable(clks[IMX6UL_CLK_AIPSTZ3]); |
506 | 501 | ||
diff --git a/drivers/clk/imx/clk-imx7d.c b/drivers/clk/imx/clk-imx7d.c index 27217a7ea17e..881b772c4ac9 100644 --- a/drivers/clk/imx/clk-imx7d.c +++ b/drivers/clk/imx/clk-imx7d.c | |||
@@ -797,6 +797,7 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node) | |||
797 | clks[IMX7D_DRAM_ALT_ROOT_CLK] = imx_clk_gate4("dram_alt_root_clk", "dram_alt_post_div", base + 0x4130, 0); | 797 | clks[IMX7D_DRAM_ALT_ROOT_CLK] = imx_clk_gate4("dram_alt_root_clk", "dram_alt_post_div", base + 0x4130, 0); |
798 | clks[IMX7D_OCOTP_CLK] = imx_clk_gate4("ocotp_clk", "ipg_root_clk", base + 0x4230, 0); | 798 | clks[IMX7D_OCOTP_CLK] = imx_clk_gate4("ocotp_clk", "ipg_root_clk", base + 0x4230, 0); |
799 | clks[IMX7D_SNVS_CLK] = imx_clk_gate4("snvs_clk", "ipg_root_clk", base + 0x4250, 0); | 799 | clks[IMX7D_SNVS_CLK] = imx_clk_gate4("snvs_clk", "ipg_root_clk", base + 0x4250, 0); |
800 | clks[IMX7D_MU_ROOT_CLK] = imx_clk_gate4("mu_root_clk", "ipg_root_clk", base + 0x4270, 0); | ||
800 | clks[IMX7D_CAAM_CLK] = imx_clk_gate4("caam_clk", "ipg_root_clk", base + 0x4240, 0); | 801 | clks[IMX7D_CAAM_CLK] = imx_clk_gate4("caam_clk", "ipg_root_clk", base + 0x4240, 0); |
801 | clks[IMX7D_USB_HSIC_ROOT_CLK] = imx_clk_gate4("usb_hsic_root_clk", "usb_hsic_post_div", base + 0x4690, 0); | 802 | clks[IMX7D_USB_HSIC_ROOT_CLK] = imx_clk_gate4("usb_hsic_root_clk", "usb_hsic_post_div", base + 0x4690, 0); |
802 | clks[IMX7D_SDMA_CORE_CLK] = imx_clk_gate4("sdma_root_clk", "ahb_root_clk", base + 0x4480, 0); | 803 | clks[IMX7D_SDMA_CORE_CLK] = imx_clk_gate4("sdma_root_clk", "ahb_root_clk", base + 0x4480, 0); |
diff --git a/drivers/clk/ingenic/jz4740-cgu.c b/drivers/clk/ingenic/jz4740-cgu.c index 32fcc75f6f77..4479c102e899 100644 --- a/drivers/clk/ingenic/jz4740-cgu.c +++ b/drivers/clk/ingenic/jz4740-cgu.c | |||
@@ -134,7 +134,7 @@ static const struct ingenic_cgu_clk_info jz4740_cgu_clocks[] = { | |||
134 | "i2s", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE, | 134 | "i2s", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE, |
135 | .parents = { JZ4740_CLK_EXT, JZ4740_CLK_PLL_HALF, -1, -1 }, | 135 | .parents = { JZ4740_CLK_EXT, JZ4740_CLK_PLL_HALF, -1, -1 }, |
136 | .mux = { CGU_REG_CPCCR, 31, 1 }, | 136 | .mux = { CGU_REG_CPCCR, 31, 1 }, |
137 | .div = { CGU_REG_I2SCDR, 0, 1, 8, -1, -1, -1 }, | 137 | .div = { CGU_REG_I2SCDR, 0, 1, 9, -1, -1, -1 }, |
138 | .gate = { CGU_REG_CLKGR, 6 }, | 138 | .gate = { CGU_REG_CLKGR, 6 }, |
139 | }, | 139 | }, |
140 | 140 | ||
@@ -161,7 +161,7 @@ static const struct ingenic_cgu_clk_info jz4740_cgu_clocks[] = { | |||
161 | }, | 161 | }, |
162 | 162 | ||
163 | [JZ4740_CLK_UDC] = { | 163 | [JZ4740_CLK_UDC] = { |
164 | "udc", CGU_CLK_MUX | CGU_CLK_DIV, | 164 | "udc", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE, |
165 | .parents = { JZ4740_CLK_EXT, JZ4740_CLK_PLL_HALF, -1, -1 }, | 165 | .parents = { JZ4740_CLK_EXT, JZ4740_CLK_PLL_HALF, -1, -1 }, |
166 | .mux = { CGU_REG_CPCCR, 29, 1 }, | 166 | .mux = { CGU_REG_CPCCR, 29, 1 }, |
167 | .div = { CGU_REG_CPCCR, 23, 1, 6, -1, -1, -1 }, | 167 | .div = { CGU_REG_CPCCR, 23, 1, 6, -1, -1, -1 }, |
diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig index 815659eebea3..efaa70f682b4 100644 --- a/drivers/clk/meson/Kconfig +++ b/drivers/clk/meson/Kconfig | |||
@@ -1,13 +1,19 @@ | |||
1 | config COMMON_CLK_AMLOGIC | 1 | config COMMON_CLK_AMLOGIC |
2 | bool | 2 | bool |
3 | depends on OF | ||
4 | depends on ARCH_MESON || COMPILE_TEST | 3 | depends on ARCH_MESON || COMPILE_TEST |
4 | select COMMON_CLK_REGMAP_MESON | ||
5 | |||
6 | config COMMON_CLK_AMLOGIC_AUDIO | ||
7 | bool | ||
8 | depends on ARCH_MESON || COMPILE_TEST | ||
9 | select COMMON_CLK_AMLOGIC | ||
5 | 10 | ||
6 | config COMMON_CLK_MESON_AO | 11 | config COMMON_CLK_MESON_AO |
7 | bool | 12 | bool |
8 | depends on OF | 13 | depends on OF |
9 | depends on ARCH_MESON || COMPILE_TEST | 14 | depends on ARCH_MESON || COMPILE_TEST |
10 | select COMMON_CLK_REGMAP_MESON | 15 | select COMMON_CLK_REGMAP_MESON |
16 | select RESET_CONTROLLER | ||
11 | 17 | ||
12 | config COMMON_CLK_REGMAP_MESON | 18 | config COMMON_CLK_REGMAP_MESON |
13 | bool | 19 | bool |
@@ -15,9 +21,8 @@ config COMMON_CLK_REGMAP_MESON | |||
15 | 21 | ||
16 | config COMMON_CLK_MESON8B | 22 | config COMMON_CLK_MESON8B |
17 | bool | 23 | bool |
18 | depends on COMMON_CLK_AMLOGIC | 24 | select COMMON_CLK_AMLOGIC |
19 | select RESET_CONTROLLER | 25 | select RESET_CONTROLLER |
20 | select COMMON_CLK_REGMAP_MESON | ||
21 | help | 26 | help |
22 | Support for the clock controller on AmLogic S802 (Meson8), | 27 | Support for the clock controller on AmLogic S802 (Meson8), |
23 | S805 (Meson8b) and S812 (Meson8m2) devices. Say Y if you | 28 | S805 (Meson8b) and S812 (Meson8m2) devices. Say Y if you |
@@ -25,10 +30,8 @@ config COMMON_CLK_MESON8B | |||
25 | 30 | ||
26 | config COMMON_CLK_GXBB | 31 | config COMMON_CLK_GXBB |
27 | bool | 32 | bool |
28 | depends on COMMON_CLK_AMLOGIC | 33 | select COMMON_CLK_AMLOGIC |
29 | select RESET_CONTROLLER | ||
30 | select COMMON_CLK_MESON_AO | 34 | select COMMON_CLK_MESON_AO |
31 | select COMMON_CLK_REGMAP_MESON | ||
32 | select MFD_SYSCON | 35 | select MFD_SYSCON |
33 | help | 36 | help |
34 | Support for the clock controller on AmLogic S905 devices, aka gxbb. | 37 | Support for the clock controller on AmLogic S905 devices, aka gxbb. |
@@ -36,11 +39,18 @@ config COMMON_CLK_GXBB | |||
36 | 39 | ||
37 | config COMMON_CLK_AXG | 40 | config COMMON_CLK_AXG |
38 | bool | 41 | bool |
39 | depends on COMMON_CLK_AMLOGIC | 42 | select COMMON_CLK_AMLOGIC |
40 | select RESET_CONTROLLER | ||
41 | select COMMON_CLK_MESON_AO | 43 | select COMMON_CLK_MESON_AO |
42 | select COMMON_CLK_REGMAP_MESON | ||
43 | select MFD_SYSCON | 44 | select MFD_SYSCON |
44 | help | 45 | help |
45 | Support for the clock controller on AmLogic A113D devices, aka axg. | 46 | Support for the clock controller on AmLogic A113D devices, aka axg. |
46 | Say Y if you want peripherals and CPU frequency scaling to work. | 47 | Say Y if you want peripherals and CPU frequency scaling to work. |
48 | |||
49 | config COMMON_CLK_AXG_AUDIO | ||
50 | tristate "Meson AXG Audio Clock Controller Driver" | ||
51 | depends on COMMON_CLK_AXG | ||
52 | select COMMON_CLK_AMLOGIC_AUDIO | ||
53 | select MFD_SYSCON | ||
54 | help | ||
55 | Support for the audio clock controller on AmLogic A113D devices, | ||
56 | aka axg, Say Y if you want audio subsystem to work. | ||
diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile index d0d13aeb369a..72ec8c40d848 100644 --- a/drivers/clk/meson/Makefile +++ b/drivers/clk/meson/Makefile | |||
@@ -2,9 +2,11 @@ | |||
2 | # Makefile for Meson specific clk | 2 | # Makefile for Meson specific clk |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-$(CONFIG_COMMON_CLK_AMLOGIC) += clk-pll.o clk-mpll.o clk-audio-divider.o | 5 | obj-$(CONFIG_COMMON_CLK_AMLOGIC) += clk-pll.o clk-mpll.o clk-phase.o |
6 | obj-$(CONFIG_COMMON_CLK_AMLOGIC_AUDIO) += clk-triphase.o sclk-div.o | ||
6 | obj-$(CONFIG_COMMON_CLK_MESON_AO) += meson-aoclk.o | 7 | obj-$(CONFIG_COMMON_CLK_MESON_AO) += meson-aoclk.o |
7 | obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o | 8 | obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o |
8 | obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o gxbb-aoclk-32k.o | 9 | obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o gxbb-aoclk-32k.o |
9 | obj-$(CONFIG_COMMON_CLK_AXG) += axg.o axg-aoclk.o | 10 | obj-$(CONFIG_COMMON_CLK_AXG) += axg.o axg-aoclk.o |
11 | obj-$(CONFIG_COMMON_CLK_AXG_AUDIO) += axg-audio.o | ||
10 | obj-$(CONFIG_COMMON_CLK_REGMAP_MESON) += clk-regmap.o | 12 | obj-$(CONFIG_COMMON_CLK_REGMAP_MESON) += clk-regmap.o |
diff --git a/drivers/clk/meson/axg-audio.c b/drivers/clk/meson/axg-audio.c new file mode 100644 index 000000000000..a0ed41e73bde --- /dev/null +++ b/drivers/clk/meson/axg-audio.c | |||
@@ -0,0 +1,845 @@ | |||
1 | // SPDX-License-Identifier: (GPL-2.0 OR MIT) | ||
2 | /* | ||
3 | * Copyright (c) 2018 BayLibre, SAS. | ||
4 | * Author: Jerome Brunet <jbrunet@baylibre.com> | ||
5 | */ | ||
6 | |||
7 | #include <linux/clk.h> | ||
8 | #include <linux/clk-provider.h> | ||
9 | #include <linux/init.h> | ||
10 | #include <linux/of_device.h> | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/platform_device.h> | ||
13 | #include <linux/regmap.h> | ||
14 | #include <linux/reset.h> | ||
15 | #include <linux/slab.h> | ||
16 | |||
17 | #include "clkc-audio.h" | ||
18 | #include "axg-audio.h" | ||
19 | |||
20 | #define AXG_MST_IN_COUNT 8 | ||
21 | #define AXG_SLV_SCLK_COUNT 10 | ||
22 | #define AXG_SLV_LRCLK_COUNT 10 | ||
23 | |||
24 | #define AXG_AUD_GATE(_name, _reg, _bit, _pname, _iflags) \ | ||
25 | struct clk_regmap axg_##_name = { \ | ||
26 | .data = &(struct clk_regmap_gate_data){ \ | ||
27 | .offset = (_reg), \ | ||
28 | .bit_idx = (_bit), \ | ||
29 | }, \ | ||
30 | .hw.init = &(struct clk_init_data) { \ | ||
31 | .name = "axg_"#_name, \ | ||
32 | .ops = &clk_regmap_gate_ops, \ | ||
33 | .parent_names = (const char *[]){ _pname }, \ | ||
34 | .num_parents = 1, \ | ||
35 | .flags = CLK_DUTY_CYCLE_PARENT | (_iflags), \ | ||
36 | }, \ | ||
37 | } | ||
38 | |||
39 | #define AXG_AUD_MUX(_name, _reg, _mask, _shift, _dflags, _pnames, _iflags) \ | ||
40 | struct clk_regmap axg_##_name = { \ | ||
41 | .data = &(struct clk_regmap_mux_data){ \ | ||
42 | .offset = (_reg), \ | ||
43 | .mask = (_mask), \ | ||
44 | .shift = (_shift), \ | ||
45 | .flags = (_dflags), \ | ||
46 | }, \ | ||
47 | .hw.init = &(struct clk_init_data){ \ | ||
48 | .name = "axg_"#_name, \ | ||
49 | .ops = &clk_regmap_mux_ops, \ | ||
50 | .parent_names = (_pnames), \ | ||
51 | .num_parents = ARRAY_SIZE(_pnames), \ | ||
52 | .flags = CLK_DUTY_CYCLE_PARENT | (_iflags), \ | ||
53 | }, \ | ||
54 | } | ||
55 | |||
56 | #define AXG_AUD_DIV(_name, _reg, _shift, _width, _dflags, _pname, _iflags) \ | ||
57 | struct clk_regmap axg_##_name = { \ | ||
58 | .data = &(struct clk_regmap_div_data){ \ | ||
59 | .offset = (_reg), \ | ||
60 | .shift = (_shift), \ | ||
61 | .width = (_width), \ | ||
62 | .flags = (_dflags), \ | ||
63 | }, \ | ||
64 | .hw.init = &(struct clk_init_data){ \ | ||
65 | .name = "axg_"#_name, \ | ||
66 | .ops = &clk_regmap_divider_ops, \ | ||
67 | .parent_names = (const char *[]) { _pname }, \ | ||
68 | .num_parents = 1, \ | ||
69 | .flags = (_iflags), \ | ||
70 | }, \ | ||
71 | } | ||
72 | |||
73 | #define AXG_PCLK_GATE(_name, _bit) \ | ||
74 | AXG_AUD_GATE(_name, AUDIO_CLK_GATE_EN, _bit, "axg_audio_pclk", 0) | ||
75 | |||
76 | /* Audio peripheral clocks */ | ||
77 | static AXG_PCLK_GATE(ddr_arb, 0); | ||
78 | static AXG_PCLK_GATE(pdm, 1); | ||
79 | static AXG_PCLK_GATE(tdmin_a, 2); | ||
80 | static AXG_PCLK_GATE(tdmin_b, 3); | ||
81 | static AXG_PCLK_GATE(tdmin_c, 4); | ||
82 | static AXG_PCLK_GATE(tdmin_lb, 5); | ||
83 | static AXG_PCLK_GATE(tdmout_a, 6); | ||
84 | static AXG_PCLK_GATE(tdmout_b, 7); | ||
85 | static AXG_PCLK_GATE(tdmout_c, 8); | ||
86 | static AXG_PCLK_GATE(frddr_a, 9); | ||
87 | static AXG_PCLK_GATE(frddr_b, 10); | ||
88 | static AXG_PCLK_GATE(frddr_c, 11); | ||
89 | static AXG_PCLK_GATE(toddr_a, 12); | ||
90 | static AXG_PCLK_GATE(toddr_b, 13); | ||
91 | static AXG_PCLK_GATE(toddr_c, 14); | ||
92 | static AXG_PCLK_GATE(loopback, 15); | ||
93 | static AXG_PCLK_GATE(spdifin, 16); | ||
94 | static AXG_PCLK_GATE(spdifout, 17); | ||
95 | static AXG_PCLK_GATE(resample, 18); | ||
96 | static AXG_PCLK_GATE(power_detect, 19); | ||
97 | |||
98 | /* Audio Master Clocks */ | ||
99 | static const char * const mst_mux_parent_names[] = { | ||
100 | "axg_mst_in0", "axg_mst_in1", "axg_mst_in2", "axg_mst_in3", | ||
101 | "axg_mst_in4", "axg_mst_in5", "axg_mst_in6", "axg_mst_in7", | ||
102 | }; | ||
103 | |||
104 | #define AXG_MST_MCLK_MUX(_name, _reg) \ | ||
105 | AXG_AUD_MUX(_name##_sel, _reg, 0x7, 24, CLK_MUX_ROUND_CLOSEST, \ | ||
106 | mst_mux_parent_names, CLK_SET_RATE_PARENT) | ||
107 | |||
108 | static AXG_MST_MCLK_MUX(mst_a_mclk, AUDIO_MCLK_A_CTRL); | ||
109 | static AXG_MST_MCLK_MUX(mst_b_mclk, AUDIO_MCLK_B_CTRL); | ||
110 | static AXG_MST_MCLK_MUX(mst_c_mclk, AUDIO_MCLK_C_CTRL); | ||
111 | static AXG_MST_MCLK_MUX(mst_d_mclk, AUDIO_MCLK_D_CTRL); | ||
112 | static AXG_MST_MCLK_MUX(mst_e_mclk, AUDIO_MCLK_E_CTRL); | ||
113 | static AXG_MST_MCLK_MUX(mst_f_mclk, AUDIO_MCLK_F_CTRL); | ||
114 | static AXG_MST_MCLK_MUX(spdifout_clk, AUDIO_CLK_SPDIFOUT_CTRL); | ||
115 | static AXG_MST_MCLK_MUX(spdifin_clk, AUDIO_CLK_SPDIFIN_CTRL); | ||
116 | static AXG_MST_MCLK_MUX(pdm_dclk, AUDIO_CLK_PDMIN_CTRL0); | ||
117 | static AXG_MST_MCLK_MUX(pdm_sysclk, AUDIO_CLK_PDMIN_CTRL1); | ||
118 | |||
119 | #define AXG_MST_MCLK_DIV(_name, _reg) \ | ||
120 | AXG_AUD_DIV(_name##_div, _reg, 0, 16, CLK_DIVIDER_ROUND_CLOSEST, \ | ||
121 | "axg_"#_name"_sel", CLK_SET_RATE_PARENT) \ | ||
122 | |||
123 | static AXG_MST_MCLK_DIV(mst_a_mclk, AUDIO_MCLK_A_CTRL); | ||
124 | static AXG_MST_MCLK_DIV(mst_b_mclk, AUDIO_MCLK_B_CTRL); | ||
125 | static AXG_MST_MCLK_DIV(mst_c_mclk, AUDIO_MCLK_C_CTRL); | ||
126 | static AXG_MST_MCLK_DIV(mst_d_mclk, AUDIO_MCLK_D_CTRL); | ||
127 | static AXG_MST_MCLK_DIV(mst_e_mclk, AUDIO_MCLK_E_CTRL); | ||
128 | static AXG_MST_MCLK_DIV(mst_f_mclk, AUDIO_MCLK_F_CTRL); | ||
129 | static AXG_MST_MCLK_DIV(spdifout_clk, AUDIO_CLK_SPDIFOUT_CTRL); | ||
130 | static AXG_MST_MCLK_DIV(spdifin_clk, AUDIO_CLK_SPDIFIN_CTRL); | ||
131 | static AXG_MST_MCLK_DIV(pdm_dclk, AUDIO_CLK_PDMIN_CTRL0); | ||
132 | static AXG_MST_MCLK_DIV(pdm_sysclk, AUDIO_CLK_PDMIN_CTRL1); | ||
133 | |||
134 | #define AXG_MST_MCLK_GATE(_name, _reg) \ | ||
135 | AXG_AUD_GATE(_name, _reg, 31, "axg_"#_name"_div", \ | ||
136 | CLK_SET_RATE_PARENT) | ||
137 | |||
138 | static AXG_MST_MCLK_GATE(mst_a_mclk, AUDIO_MCLK_A_CTRL); | ||
139 | static AXG_MST_MCLK_GATE(mst_b_mclk, AUDIO_MCLK_B_CTRL); | ||
140 | static AXG_MST_MCLK_GATE(mst_c_mclk, AUDIO_MCLK_C_CTRL); | ||
141 | static AXG_MST_MCLK_GATE(mst_d_mclk, AUDIO_MCLK_D_CTRL); | ||
142 | static AXG_MST_MCLK_GATE(mst_e_mclk, AUDIO_MCLK_E_CTRL); | ||
143 | static AXG_MST_MCLK_GATE(mst_f_mclk, AUDIO_MCLK_F_CTRL); | ||
144 | static AXG_MST_MCLK_GATE(spdifout_clk, AUDIO_CLK_SPDIFOUT_CTRL); | ||
145 | static AXG_MST_MCLK_GATE(spdifin_clk, AUDIO_CLK_SPDIFIN_CTRL); | ||
146 | static AXG_MST_MCLK_GATE(pdm_dclk, AUDIO_CLK_PDMIN_CTRL0); | ||
147 | static AXG_MST_MCLK_GATE(pdm_sysclk, AUDIO_CLK_PDMIN_CTRL1); | ||
148 | |||
149 | /* Sample Clocks */ | ||
150 | #define AXG_MST_SCLK_PRE_EN(_name, _reg) \ | ||
151 | AXG_AUD_GATE(mst_##_name##_sclk_pre_en, _reg, 31, \ | ||
152 | "axg_mst_"#_name"_mclk", 0) | ||
153 | |||
154 | static AXG_MST_SCLK_PRE_EN(a, AUDIO_MST_A_SCLK_CTRL0); | ||
155 | static AXG_MST_SCLK_PRE_EN(b, AUDIO_MST_B_SCLK_CTRL0); | ||
156 | static AXG_MST_SCLK_PRE_EN(c, AUDIO_MST_C_SCLK_CTRL0); | ||
157 | static AXG_MST_SCLK_PRE_EN(d, AUDIO_MST_D_SCLK_CTRL0); | ||
158 | static AXG_MST_SCLK_PRE_EN(e, AUDIO_MST_E_SCLK_CTRL0); | ||
159 | static AXG_MST_SCLK_PRE_EN(f, AUDIO_MST_F_SCLK_CTRL0); | ||
160 | |||
161 | #define AXG_AUD_SCLK_DIV(_name, _reg, _div_shift, _div_width, \ | ||
162 | _hi_shift, _hi_width, _pname, _iflags) \ | ||
163 | struct clk_regmap axg_##_name = { \ | ||
164 | .data = &(struct meson_sclk_div_data) { \ | ||
165 | .div = { \ | ||
166 | .reg_off = (_reg), \ | ||
167 | .shift = (_div_shift), \ | ||
168 | .width = (_div_width), \ | ||
169 | }, \ | ||
170 | .hi = { \ | ||
171 | .reg_off = (_reg), \ | ||
172 | .shift = (_hi_shift), \ | ||
173 | .width = (_hi_width), \ | ||
174 | }, \ | ||
175 | }, \ | ||
176 | .hw.init = &(struct clk_init_data) { \ | ||
177 | .name = "axg_"#_name, \ | ||
178 | .ops = &meson_sclk_div_ops, \ | ||
179 | .parent_names = (const char *[]) { _pname }, \ | ||
180 | .num_parents = 1, \ | ||
181 | .flags = (_iflags), \ | ||
182 | }, \ | ||
183 | } | ||
184 | |||
185 | #define AXG_MST_SCLK_DIV(_name, _reg) \ | ||
186 | AXG_AUD_SCLK_DIV(mst_##_name##_sclk_div, _reg, 20, 10, 0, 0, \ | ||
187 | "axg_mst_"#_name"_sclk_pre_en", \ | ||
188 | CLK_SET_RATE_PARENT) | ||
189 | |||
190 | static AXG_MST_SCLK_DIV(a, AUDIO_MST_A_SCLK_CTRL0); | ||
191 | static AXG_MST_SCLK_DIV(b, AUDIO_MST_B_SCLK_CTRL0); | ||
192 | static AXG_MST_SCLK_DIV(c, AUDIO_MST_C_SCLK_CTRL0); | ||
193 | static AXG_MST_SCLK_DIV(d, AUDIO_MST_D_SCLK_CTRL0); | ||
194 | static AXG_MST_SCLK_DIV(e, AUDIO_MST_E_SCLK_CTRL0); | ||
195 | static AXG_MST_SCLK_DIV(f, AUDIO_MST_F_SCLK_CTRL0); | ||
196 | |||
197 | #define AXG_MST_SCLK_POST_EN(_name, _reg) \ | ||
198 | AXG_AUD_GATE(mst_##_name##_sclk_post_en, _reg, 30, \ | ||
199 | "axg_mst_"#_name"_sclk_div", CLK_SET_RATE_PARENT) | ||
200 | |||
201 | static AXG_MST_SCLK_POST_EN(a, AUDIO_MST_A_SCLK_CTRL0); | ||
202 | static AXG_MST_SCLK_POST_EN(b, AUDIO_MST_B_SCLK_CTRL0); | ||
203 | static AXG_MST_SCLK_POST_EN(c, AUDIO_MST_C_SCLK_CTRL0); | ||
204 | static AXG_MST_SCLK_POST_EN(d, AUDIO_MST_D_SCLK_CTRL0); | ||
205 | static AXG_MST_SCLK_POST_EN(e, AUDIO_MST_E_SCLK_CTRL0); | ||
206 | static AXG_MST_SCLK_POST_EN(f, AUDIO_MST_F_SCLK_CTRL0); | ||
207 | |||
208 | #define AXG_AUD_TRIPHASE(_name, _reg, _width, _shift0, _shift1, _shift2, \ | ||
209 | _pname, _iflags) \ | ||
210 | struct clk_regmap axg_##_name = { \ | ||
211 | .data = &(struct meson_clk_triphase_data) { \ | ||
212 | .ph0 = { \ | ||
213 | .reg_off = (_reg), \ | ||
214 | .shift = (_shift0), \ | ||
215 | .width = (_width), \ | ||
216 | }, \ | ||
217 | .ph1 = { \ | ||
218 | .reg_off = (_reg), \ | ||
219 | .shift = (_shift1), \ | ||
220 | .width = (_width), \ | ||
221 | }, \ | ||
222 | .ph2 = { \ | ||
223 | .reg_off = (_reg), \ | ||
224 | .shift = (_shift2), \ | ||
225 | .width = (_width), \ | ||
226 | }, \ | ||
227 | }, \ | ||
228 | .hw.init = &(struct clk_init_data) { \ | ||
229 | .name = "axg_"#_name, \ | ||
230 | .ops = &meson_clk_triphase_ops, \ | ||
231 | .parent_names = (const char *[]) { _pname }, \ | ||
232 | .num_parents = 1, \ | ||
233 | .flags = CLK_DUTY_CYCLE_PARENT | (_iflags), \ | ||
234 | }, \ | ||
235 | } | ||
236 | |||
237 | #define AXG_MST_SCLK(_name, _reg) \ | ||
238 | AXG_AUD_TRIPHASE(mst_##_name##_sclk, _reg, 1, 0, 2, 4, \ | ||
239 | "axg_mst_"#_name"_sclk_post_en", CLK_SET_RATE_PARENT) | ||
240 | |||
241 | static AXG_MST_SCLK(a, AUDIO_MST_A_SCLK_CTRL1); | ||
242 | static AXG_MST_SCLK(b, AUDIO_MST_B_SCLK_CTRL1); | ||
243 | static AXG_MST_SCLK(c, AUDIO_MST_C_SCLK_CTRL1); | ||
244 | static AXG_MST_SCLK(d, AUDIO_MST_D_SCLK_CTRL1); | ||
245 | static AXG_MST_SCLK(e, AUDIO_MST_E_SCLK_CTRL1); | ||
246 | static AXG_MST_SCLK(f, AUDIO_MST_F_SCLK_CTRL1); | ||
247 | |||
248 | #define AXG_MST_LRCLK_DIV(_name, _reg) \ | ||
249 | AXG_AUD_SCLK_DIV(mst_##_name##_lrclk_div, _reg, 0, 10, 10, 10, \ | ||
250 | "axg_mst_"#_name"_sclk_post_en", 0) \ | ||
251 | |||
252 | static AXG_MST_LRCLK_DIV(a, AUDIO_MST_A_SCLK_CTRL0); | ||
253 | static AXG_MST_LRCLK_DIV(b, AUDIO_MST_B_SCLK_CTRL0); | ||
254 | static AXG_MST_LRCLK_DIV(c, AUDIO_MST_C_SCLK_CTRL0); | ||
255 | static AXG_MST_LRCLK_DIV(d, AUDIO_MST_D_SCLK_CTRL0); | ||
256 | static AXG_MST_LRCLK_DIV(e, AUDIO_MST_E_SCLK_CTRL0); | ||
257 | static AXG_MST_LRCLK_DIV(f, AUDIO_MST_F_SCLK_CTRL0); | ||
258 | |||
259 | #define AXG_MST_LRCLK(_name, _reg) \ | ||
260 | AXG_AUD_TRIPHASE(mst_##_name##_lrclk, _reg, 1, 1, 3, 5, \ | ||
261 | "axg_mst_"#_name"_lrclk_div", CLK_SET_RATE_PARENT) | ||
262 | |||
263 | static AXG_MST_LRCLK(a, AUDIO_MST_A_SCLK_CTRL1); | ||
264 | static AXG_MST_LRCLK(b, AUDIO_MST_B_SCLK_CTRL1); | ||
265 | static AXG_MST_LRCLK(c, AUDIO_MST_C_SCLK_CTRL1); | ||
266 | static AXG_MST_LRCLK(d, AUDIO_MST_D_SCLK_CTRL1); | ||
267 | static AXG_MST_LRCLK(e, AUDIO_MST_E_SCLK_CTRL1); | ||
268 | static AXG_MST_LRCLK(f, AUDIO_MST_F_SCLK_CTRL1); | ||
269 | |||
270 | static const char * const tdm_sclk_parent_names[] = { | ||
271 | "axg_mst_a_sclk", "axg_mst_b_sclk", "axg_mst_c_sclk", | ||
272 | "axg_mst_d_sclk", "axg_mst_e_sclk", "axg_mst_f_sclk", | ||
273 | "axg_slv_sclk0", "axg_slv_sclk1", "axg_slv_sclk2", | ||
274 | "axg_slv_sclk3", "axg_slv_sclk4", "axg_slv_sclk5", | ||
275 | "axg_slv_sclk6", "axg_slv_sclk7", "axg_slv_sclk8", | ||
276 | "axg_slv_sclk9" | ||
277 | }; | ||
278 | |||
279 | #define AXG_TDM_SCLK_MUX(_name, _reg) \ | ||
280 | AXG_AUD_MUX(tdm##_name##_sclk_sel, _reg, 0xf, 24, \ | ||
281 | CLK_MUX_ROUND_CLOSEST, \ | ||
282 | tdm_sclk_parent_names, 0) | ||
283 | |||
284 | static AXG_TDM_SCLK_MUX(in_a, AUDIO_CLK_TDMIN_A_CTRL); | ||
285 | static AXG_TDM_SCLK_MUX(in_b, AUDIO_CLK_TDMIN_B_CTRL); | ||
286 | static AXG_TDM_SCLK_MUX(in_c, AUDIO_CLK_TDMIN_C_CTRL); | ||
287 | static AXG_TDM_SCLK_MUX(in_lb, AUDIO_CLK_TDMIN_LB_CTRL); | ||
288 | static AXG_TDM_SCLK_MUX(out_a, AUDIO_CLK_TDMOUT_A_CTRL); | ||
289 | static AXG_TDM_SCLK_MUX(out_b, AUDIO_CLK_TDMOUT_B_CTRL); | ||
290 | static AXG_TDM_SCLK_MUX(out_c, AUDIO_CLK_TDMOUT_C_CTRL); | ||
291 | |||
292 | #define AXG_TDM_SCLK_PRE_EN(_name, _reg) \ | ||
293 | AXG_AUD_GATE(tdm##_name##_sclk_pre_en, _reg, 31, \ | ||
294 | "axg_tdm"#_name"_sclk_sel", CLK_SET_RATE_PARENT) | ||
295 | |||
296 | static AXG_TDM_SCLK_PRE_EN(in_a, AUDIO_CLK_TDMIN_A_CTRL); | ||
297 | static AXG_TDM_SCLK_PRE_EN(in_b, AUDIO_CLK_TDMIN_B_CTRL); | ||
298 | static AXG_TDM_SCLK_PRE_EN(in_c, AUDIO_CLK_TDMIN_C_CTRL); | ||
299 | static AXG_TDM_SCLK_PRE_EN(in_lb, AUDIO_CLK_TDMIN_LB_CTRL); | ||
300 | static AXG_TDM_SCLK_PRE_EN(out_a, AUDIO_CLK_TDMOUT_A_CTRL); | ||
301 | static AXG_TDM_SCLK_PRE_EN(out_b, AUDIO_CLK_TDMOUT_B_CTRL); | ||
302 | static AXG_TDM_SCLK_PRE_EN(out_c, AUDIO_CLK_TDMOUT_C_CTRL); | ||
303 | |||
304 | #define AXG_TDM_SCLK_POST_EN(_name, _reg) \ | ||
305 | AXG_AUD_GATE(tdm##_name##_sclk_post_en, _reg, 30, \ | ||
306 | "axg_tdm"#_name"_sclk_pre_en", CLK_SET_RATE_PARENT) | ||
307 | |||
308 | static AXG_TDM_SCLK_POST_EN(in_a, AUDIO_CLK_TDMIN_A_CTRL); | ||
309 | static AXG_TDM_SCLK_POST_EN(in_b, AUDIO_CLK_TDMIN_B_CTRL); | ||
310 | static AXG_TDM_SCLK_POST_EN(in_c, AUDIO_CLK_TDMIN_C_CTRL); | ||
311 | static AXG_TDM_SCLK_POST_EN(in_lb, AUDIO_CLK_TDMIN_LB_CTRL); | ||
312 | static AXG_TDM_SCLK_POST_EN(out_a, AUDIO_CLK_TDMOUT_A_CTRL); | ||
313 | static AXG_TDM_SCLK_POST_EN(out_b, AUDIO_CLK_TDMOUT_B_CTRL); | ||
314 | static AXG_TDM_SCLK_POST_EN(out_c, AUDIO_CLK_TDMOUT_C_CTRL); | ||
315 | |||
316 | #define AXG_TDM_SCLK(_name, _reg) \ | ||
317 | struct clk_regmap axg_tdm##_name##_sclk = { \ | ||
318 | .data = &(struct meson_clk_phase_data) { \ | ||
319 | .ph = { \ | ||
320 | .reg_off = (_reg), \ | ||
321 | .shift = 29, \ | ||
322 | .width = 1, \ | ||
323 | }, \ | ||
324 | }, \ | ||
325 | .hw.init = &(struct clk_init_data) { \ | ||
326 | .name = "axg_tdm"#_name"_sclk", \ | ||
327 | .ops = &meson_clk_phase_ops, \ | ||
328 | .parent_names = (const char *[]) \ | ||
329 | { "axg_tdm"#_name"_sclk_post_en" }, \ | ||
330 | .num_parents = 1, \ | ||
331 | .flags = CLK_DUTY_CYCLE_PARENT | CLK_SET_RATE_PARENT, \ | ||
332 | }, \ | ||
333 | } | ||
334 | |||
335 | static AXG_TDM_SCLK(in_a, AUDIO_CLK_TDMIN_A_CTRL); | ||
336 | static AXG_TDM_SCLK(in_b, AUDIO_CLK_TDMIN_B_CTRL); | ||
337 | static AXG_TDM_SCLK(in_c, AUDIO_CLK_TDMIN_C_CTRL); | ||
338 | static AXG_TDM_SCLK(in_lb, AUDIO_CLK_TDMIN_LB_CTRL); | ||
339 | static AXG_TDM_SCLK(out_a, AUDIO_CLK_TDMOUT_A_CTRL); | ||
340 | static AXG_TDM_SCLK(out_b, AUDIO_CLK_TDMOUT_B_CTRL); | ||
341 | static AXG_TDM_SCLK(out_c, AUDIO_CLK_TDMOUT_C_CTRL); | ||
342 | |||
343 | static const char * const tdm_lrclk_parent_names[] = { | ||
344 | "axg_mst_a_lrclk", "axg_mst_b_lrclk", "axg_mst_c_lrclk", | ||
345 | "axg_mst_d_lrclk", "axg_mst_e_lrclk", "axg_mst_f_lrclk", | ||
346 | "axg_slv_lrclk0", "axg_slv_lrclk1", "axg_slv_lrclk2", | ||
347 | "axg_slv_lrclk3", "axg_slv_lrclk4", "axg_slv_lrclk5", | ||
348 | "axg_slv_lrclk6", "axg_slv_lrclk7", "axg_slv_lrclk8", | ||
349 | "axg_slv_lrclk9" | ||
350 | }; | ||
351 | |||
352 | #define AXG_TDM_LRLCK(_name, _reg) \ | ||
353 | AXG_AUD_MUX(tdm##_name##_lrclk, _reg, 0xf, 20, \ | ||
354 | CLK_MUX_ROUND_CLOSEST, \ | ||
355 | tdm_lrclk_parent_names, 0) | ||
356 | |||
357 | static AXG_TDM_LRLCK(in_a, AUDIO_CLK_TDMIN_A_CTRL); | ||
358 | static AXG_TDM_LRLCK(in_b, AUDIO_CLK_TDMIN_B_CTRL); | ||
359 | static AXG_TDM_LRLCK(in_c, AUDIO_CLK_TDMIN_C_CTRL); | ||
360 | static AXG_TDM_LRLCK(in_lb, AUDIO_CLK_TDMIN_LB_CTRL); | ||
361 | static AXG_TDM_LRLCK(out_a, AUDIO_CLK_TDMOUT_A_CTRL); | ||
362 | static AXG_TDM_LRLCK(out_b, AUDIO_CLK_TDMOUT_B_CTRL); | ||
363 | static AXG_TDM_LRLCK(out_c, AUDIO_CLK_TDMOUT_C_CTRL); | ||
364 | |||
365 | /* | ||
366 | * Array of all clocks provided by this provider | ||
367 | * The input clocks of the controller will be populated at runtime | ||
368 | */ | ||
369 | static struct clk_hw_onecell_data axg_audio_hw_onecell_data = { | ||
370 | .hws = { | ||
371 | [AUD_CLKID_DDR_ARB] = &axg_ddr_arb.hw, | ||
372 | [AUD_CLKID_PDM] = &axg_pdm.hw, | ||
373 | [AUD_CLKID_TDMIN_A] = &axg_tdmin_a.hw, | ||
374 | [AUD_CLKID_TDMIN_B] = &axg_tdmin_b.hw, | ||
375 | [AUD_CLKID_TDMIN_C] = &axg_tdmin_c.hw, | ||
376 | [AUD_CLKID_TDMIN_LB] = &axg_tdmin_lb.hw, | ||
377 | [AUD_CLKID_TDMOUT_A] = &axg_tdmout_a.hw, | ||
378 | [AUD_CLKID_TDMOUT_B] = &axg_tdmout_b.hw, | ||
379 | [AUD_CLKID_TDMOUT_C] = &axg_tdmout_c.hw, | ||
380 | [AUD_CLKID_FRDDR_A] = &axg_frddr_a.hw, | ||
381 | [AUD_CLKID_FRDDR_B] = &axg_frddr_b.hw, | ||
382 | [AUD_CLKID_FRDDR_C] = &axg_frddr_c.hw, | ||
383 | [AUD_CLKID_TODDR_A] = &axg_toddr_a.hw, | ||
384 | [AUD_CLKID_TODDR_B] = &axg_toddr_b.hw, | ||
385 | [AUD_CLKID_TODDR_C] = &axg_toddr_c.hw, | ||
386 | [AUD_CLKID_LOOPBACK] = &axg_loopback.hw, | ||
387 | [AUD_CLKID_SPDIFIN] = &axg_spdifin.hw, | ||
388 | [AUD_CLKID_SPDIFOUT] = &axg_spdifout.hw, | ||
389 | [AUD_CLKID_RESAMPLE] = &axg_resample.hw, | ||
390 | [AUD_CLKID_POWER_DETECT] = &axg_power_detect.hw, | ||
391 | [AUD_CLKID_MST_A_MCLK_SEL] = &axg_mst_a_mclk_sel.hw, | ||
392 | [AUD_CLKID_MST_B_MCLK_SEL] = &axg_mst_b_mclk_sel.hw, | ||
393 | [AUD_CLKID_MST_C_MCLK_SEL] = &axg_mst_c_mclk_sel.hw, | ||
394 | [AUD_CLKID_MST_D_MCLK_SEL] = &axg_mst_d_mclk_sel.hw, | ||
395 | [AUD_CLKID_MST_E_MCLK_SEL] = &axg_mst_e_mclk_sel.hw, | ||
396 | [AUD_CLKID_MST_F_MCLK_SEL] = &axg_mst_f_mclk_sel.hw, | ||
397 | [AUD_CLKID_MST_A_MCLK_DIV] = &axg_mst_a_mclk_div.hw, | ||
398 | [AUD_CLKID_MST_B_MCLK_DIV] = &axg_mst_b_mclk_div.hw, | ||
399 | [AUD_CLKID_MST_C_MCLK_DIV] = &axg_mst_c_mclk_div.hw, | ||
400 | [AUD_CLKID_MST_D_MCLK_DIV] = &axg_mst_d_mclk_div.hw, | ||
401 | [AUD_CLKID_MST_E_MCLK_DIV] = &axg_mst_e_mclk_div.hw, | ||
402 | [AUD_CLKID_MST_F_MCLK_DIV] = &axg_mst_f_mclk_div.hw, | ||
403 | [AUD_CLKID_MST_A_MCLK] = &axg_mst_a_mclk.hw, | ||
404 | [AUD_CLKID_MST_B_MCLK] = &axg_mst_b_mclk.hw, | ||
405 | [AUD_CLKID_MST_C_MCLK] = &axg_mst_c_mclk.hw, | ||
406 | [AUD_CLKID_MST_D_MCLK] = &axg_mst_d_mclk.hw, | ||
407 | [AUD_CLKID_MST_E_MCLK] = &axg_mst_e_mclk.hw, | ||
408 | [AUD_CLKID_MST_F_MCLK] = &axg_mst_f_mclk.hw, | ||
409 | [AUD_CLKID_SPDIFOUT_CLK_SEL] = &axg_spdifout_clk_sel.hw, | ||
410 | [AUD_CLKID_SPDIFOUT_CLK_DIV] = &axg_spdifout_clk_div.hw, | ||
411 | [AUD_CLKID_SPDIFOUT_CLK] = &axg_spdifout_clk.hw, | ||
412 | [AUD_CLKID_SPDIFIN_CLK_SEL] = &axg_spdifin_clk_sel.hw, | ||
413 | [AUD_CLKID_SPDIFIN_CLK_DIV] = &axg_spdifin_clk_div.hw, | ||
414 | [AUD_CLKID_SPDIFIN_CLK] = &axg_spdifin_clk.hw, | ||
415 | [AUD_CLKID_PDM_DCLK_SEL] = &axg_pdm_dclk_sel.hw, | ||
416 | [AUD_CLKID_PDM_DCLK_DIV] = &axg_pdm_dclk_div.hw, | ||
417 | [AUD_CLKID_PDM_DCLK] = &axg_pdm_dclk.hw, | ||
418 | [AUD_CLKID_PDM_SYSCLK_SEL] = &axg_pdm_sysclk_sel.hw, | ||
419 | [AUD_CLKID_PDM_SYSCLK_DIV] = &axg_pdm_sysclk_div.hw, | ||
420 | [AUD_CLKID_PDM_SYSCLK] = &axg_pdm_sysclk.hw, | ||
421 | [AUD_CLKID_MST_A_SCLK_PRE_EN] = &axg_mst_a_sclk_pre_en.hw, | ||
422 | [AUD_CLKID_MST_B_SCLK_PRE_EN] = &axg_mst_b_sclk_pre_en.hw, | ||
423 | [AUD_CLKID_MST_C_SCLK_PRE_EN] = &axg_mst_c_sclk_pre_en.hw, | ||
424 | [AUD_CLKID_MST_D_SCLK_PRE_EN] = &axg_mst_d_sclk_pre_en.hw, | ||
425 | [AUD_CLKID_MST_E_SCLK_PRE_EN] = &axg_mst_e_sclk_pre_en.hw, | ||
426 | [AUD_CLKID_MST_F_SCLK_PRE_EN] = &axg_mst_f_sclk_pre_en.hw, | ||
427 | [AUD_CLKID_MST_A_SCLK_DIV] = &axg_mst_a_sclk_div.hw, | ||
428 | [AUD_CLKID_MST_B_SCLK_DIV] = &axg_mst_b_sclk_div.hw, | ||
429 | [AUD_CLKID_MST_C_SCLK_DIV] = &axg_mst_c_sclk_div.hw, | ||
430 | [AUD_CLKID_MST_D_SCLK_DIV] = &axg_mst_d_sclk_div.hw, | ||
431 | [AUD_CLKID_MST_E_SCLK_DIV] = &axg_mst_e_sclk_div.hw, | ||
432 | [AUD_CLKID_MST_F_SCLK_DIV] = &axg_mst_f_sclk_div.hw, | ||
433 | [AUD_CLKID_MST_A_SCLK_POST_EN] = &axg_mst_a_sclk_post_en.hw, | ||
434 | [AUD_CLKID_MST_B_SCLK_POST_EN] = &axg_mst_b_sclk_post_en.hw, | ||
435 | [AUD_CLKID_MST_C_SCLK_POST_EN] = &axg_mst_c_sclk_post_en.hw, | ||
436 | [AUD_CLKID_MST_D_SCLK_POST_EN] = &axg_mst_d_sclk_post_en.hw, | ||
437 | [AUD_CLKID_MST_E_SCLK_POST_EN] = &axg_mst_e_sclk_post_en.hw, | ||
438 | [AUD_CLKID_MST_F_SCLK_POST_EN] = &axg_mst_f_sclk_post_en.hw, | ||
439 | [AUD_CLKID_MST_A_SCLK] = &axg_mst_a_sclk.hw, | ||
440 | [AUD_CLKID_MST_B_SCLK] = &axg_mst_b_sclk.hw, | ||
441 | [AUD_CLKID_MST_C_SCLK] = &axg_mst_c_sclk.hw, | ||
442 | [AUD_CLKID_MST_D_SCLK] = &axg_mst_d_sclk.hw, | ||
443 | [AUD_CLKID_MST_E_SCLK] = &axg_mst_e_sclk.hw, | ||
444 | [AUD_CLKID_MST_F_SCLK] = &axg_mst_f_sclk.hw, | ||
445 | [AUD_CLKID_MST_A_LRCLK_DIV] = &axg_mst_a_lrclk_div.hw, | ||
446 | [AUD_CLKID_MST_B_LRCLK_DIV] = &axg_mst_b_lrclk_div.hw, | ||
447 | [AUD_CLKID_MST_C_LRCLK_DIV] = &axg_mst_c_lrclk_div.hw, | ||
448 | [AUD_CLKID_MST_D_LRCLK_DIV] = &axg_mst_d_lrclk_div.hw, | ||
449 | [AUD_CLKID_MST_E_LRCLK_DIV] = &axg_mst_e_lrclk_div.hw, | ||
450 | [AUD_CLKID_MST_F_LRCLK_DIV] = &axg_mst_f_lrclk_div.hw, | ||
451 | [AUD_CLKID_MST_A_LRCLK] = &axg_mst_a_lrclk.hw, | ||
452 | [AUD_CLKID_MST_B_LRCLK] = &axg_mst_b_lrclk.hw, | ||
453 | [AUD_CLKID_MST_C_LRCLK] = &axg_mst_c_lrclk.hw, | ||
454 | [AUD_CLKID_MST_D_LRCLK] = &axg_mst_d_lrclk.hw, | ||
455 | [AUD_CLKID_MST_E_LRCLK] = &axg_mst_e_lrclk.hw, | ||
456 | [AUD_CLKID_MST_F_LRCLK] = &axg_mst_f_lrclk.hw, | ||
457 | [AUD_CLKID_TDMIN_A_SCLK_SEL] = &axg_tdmin_a_sclk_sel.hw, | ||
458 | [AUD_CLKID_TDMIN_B_SCLK_SEL] = &axg_tdmin_b_sclk_sel.hw, | ||
459 | [AUD_CLKID_TDMIN_C_SCLK_SEL] = &axg_tdmin_c_sclk_sel.hw, | ||
460 | [AUD_CLKID_TDMIN_LB_SCLK_SEL] = &axg_tdmin_lb_sclk_sel.hw, | ||
461 | [AUD_CLKID_TDMOUT_A_SCLK_SEL] = &axg_tdmout_a_sclk_sel.hw, | ||
462 | [AUD_CLKID_TDMOUT_B_SCLK_SEL] = &axg_tdmout_b_sclk_sel.hw, | ||
463 | [AUD_CLKID_TDMOUT_C_SCLK_SEL] = &axg_tdmout_c_sclk_sel.hw, | ||
464 | [AUD_CLKID_TDMIN_A_SCLK_PRE_EN] = &axg_tdmin_a_sclk_pre_en.hw, | ||
465 | [AUD_CLKID_TDMIN_B_SCLK_PRE_EN] = &axg_tdmin_b_sclk_pre_en.hw, | ||
466 | [AUD_CLKID_TDMIN_C_SCLK_PRE_EN] = &axg_tdmin_c_sclk_pre_en.hw, | ||
467 | [AUD_CLKID_TDMIN_LB_SCLK_PRE_EN] = &axg_tdmin_lb_sclk_pre_en.hw, | ||
468 | [AUD_CLKID_TDMOUT_A_SCLK_PRE_EN] = &axg_tdmout_a_sclk_pre_en.hw, | ||
469 | [AUD_CLKID_TDMOUT_B_SCLK_PRE_EN] = &axg_tdmout_b_sclk_pre_en.hw, | ||
470 | [AUD_CLKID_TDMOUT_C_SCLK_PRE_EN] = &axg_tdmout_c_sclk_pre_en.hw, | ||
471 | [AUD_CLKID_TDMIN_A_SCLK_POST_EN] = &axg_tdmin_a_sclk_post_en.hw, | ||
472 | [AUD_CLKID_TDMIN_B_SCLK_POST_EN] = &axg_tdmin_b_sclk_post_en.hw, | ||
473 | [AUD_CLKID_TDMIN_C_SCLK_POST_EN] = &axg_tdmin_c_sclk_post_en.hw, | ||
474 | [AUD_CLKID_TDMIN_LB_SCLK_POST_EN] = &axg_tdmin_lb_sclk_post_en.hw, | ||
475 | [AUD_CLKID_TDMOUT_A_SCLK_POST_EN] = &axg_tdmout_a_sclk_post_en.hw, | ||
476 | [AUD_CLKID_TDMOUT_B_SCLK_POST_EN] = &axg_tdmout_b_sclk_post_en.hw, | ||
477 | [AUD_CLKID_TDMOUT_C_SCLK_POST_EN] = &axg_tdmout_c_sclk_post_en.hw, | ||
478 | [AUD_CLKID_TDMIN_A_SCLK] = &axg_tdmin_a_sclk.hw, | ||
479 | [AUD_CLKID_TDMIN_B_SCLK] = &axg_tdmin_b_sclk.hw, | ||
480 | [AUD_CLKID_TDMIN_C_SCLK] = &axg_tdmin_c_sclk.hw, | ||
481 | [AUD_CLKID_TDMIN_LB_SCLK] = &axg_tdmin_lb_sclk.hw, | ||
482 | [AUD_CLKID_TDMOUT_A_SCLK] = &axg_tdmout_a_sclk.hw, | ||
483 | [AUD_CLKID_TDMOUT_B_SCLK] = &axg_tdmout_b_sclk.hw, | ||
484 | [AUD_CLKID_TDMOUT_C_SCLK] = &axg_tdmout_c_sclk.hw, | ||
485 | [AUD_CLKID_TDMIN_A_LRCLK] = &axg_tdmin_a_lrclk.hw, | ||
486 | [AUD_CLKID_TDMIN_B_LRCLK] = &axg_tdmin_b_lrclk.hw, | ||
487 | [AUD_CLKID_TDMIN_C_LRCLK] = &axg_tdmin_c_lrclk.hw, | ||
488 | [AUD_CLKID_TDMIN_LB_LRCLK] = &axg_tdmin_lb_lrclk.hw, | ||
489 | [AUD_CLKID_TDMOUT_A_LRCLK] = &axg_tdmout_a_lrclk.hw, | ||
490 | [AUD_CLKID_TDMOUT_B_LRCLK] = &axg_tdmout_b_lrclk.hw, | ||
491 | [AUD_CLKID_TDMOUT_C_LRCLK] = &axg_tdmout_c_lrclk.hw, | ||
492 | [NR_CLKS] = NULL, | ||
493 | }, | ||
494 | .num = NR_CLKS, | ||
495 | }; | ||
496 | |||
497 | /* Convenience table to populate regmap in .probe() */ | ||
498 | static struct clk_regmap *const axg_audio_clk_regmaps[] = { | ||
499 | &axg_ddr_arb, | ||
500 | &axg_pdm, | ||
501 | &axg_tdmin_a, | ||
502 | &axg_tdmin_b, | ||
503 | &axg_tdmin_c, | ||
504 | &axg_tdmin_lb, | ||
505 | &axg_tdmout_a, | ||
506 | &axg_tdmout_b, | ||
507 | &axg_tdmout_c, | ||
508 | &axg_frddr_a, | ||
509 | &axg_frddr_b, | ||
510 | &axg_frddr_c, | ||
511 | &axg_toddr_a, | ||
512 | &axg_toddr_b, | ||
513 | &axg_toddr_c, | ||
514 | &axg_loopback, | ||
515 | &axg_spdifin, | ||
516 | &axg_spdifout, | ||
517 | &axg_resample, | ||
518 | &axg_power_detect, | ||
519 | &axg_mst_a_mclk_sel, | ||
520 | &axg_mst_b_mclk_sel, | ||
521 | &axg_mst_c_mclk_sel, | ||
522 | &axg_mst_d_mclk_sel, | ||
523 | &axg_mst_e_mclk_sel, | ||
524 | &axg_mst_f_mclk_sel, | ||
525 | &axg_mst_a_mclk_div, | ||
526 | &axg_mst_b_mclk_div, | ||
527 | &axg_mst_c_mclk_div, | ||
528 | &axg_mst_d_mclk_div, | ||
529 | &axg_mst_e_mclk_div, | ||
530 | &axg_mst_f_mclk_div, | ||
531 | &axg_mst_a_mclk, | ||
532 | &axg_mst_b_mclk, | ||
533 | &axg_mst_c_mclk, | ||
534 | &axg_mst_d_mclk, | ||
535 | &axg_mst_e_mclk, | ||
536 | &axg_mst_f_mclk, | ||
537 | &axg_spdifout_clk_sel, | ||
538 | &axg_spdifout_clk_div, | ||
539 | &axg_spdifout_clk, | ||
540 | &axg_spdifin_clk_sel, | ||
541 | &axg_spdifin_clk_div, | ||
542 | &axg_spdifin_clk, | ||
543 | &axg_pdm_dclk_sel, | ||
544 | &axg_pdm_dclk_div, | ||
545 | &axg_pdm_dclk, | ||
546 | &axg_pdm_sysclk_sel, | ||
547 | &axg_pdm_sysclk_div, | ||
548 | &axg_pdm_sysclk, | ||
549 | &axg_mst_a_sclk_pre_en, | ||
550 | &axg_mst_b_sclk_pre_en, | ||
551 | &axg_mst_c_sclk_pre_en, | ||
552 | &axg_mst_d_sclk_pre_en, | ||
553 | &axg_mst_e_sclk_pre_en, | ||
554 | &axg_mst_f_sclk_pre_en, | ||
555 | &axg_mst_a_sclk_div, | ||
556 | &axg_mst_b_sclk_div, | ||
557 | &axg_mst_c_sclk_div, | ||
558 | &axg_mst_d_sclk_div, | ||
559 | &axg_mst_e_sclk_div, | ||
560 | &axg_mst_f_sclk_div, | ||
561 | &axg_mst_a_sclk_post_en, | ||
562 | &axg_mst_b_sclk_post_en, | ||
563 | &axg_mst_c_sclk_post_en, | ||
564 | &axg_mst_d_sclk_post_en, | ||
565 | &axg_mst_e_sclk_post_en, | ||
566 | &axg_mst_f_sclk_post_en, | ||
567 | &axg_mst_a_sclk, | ||
568 | &axg_mst_b_sclk, | ||
569 | &axg_mst_c_sclk, | ||
570 | &axg_mst_d_sclk, | ||
571 | &axg_mst_e_sclk, | ||
572 | &axg_mst_f_sclk, | ||
573 | &axg_mst_a_lrclk_div, | ||
574 | &axg_mst_b_lrclk_div, | ||
575 | &axg_mst_c_lrclk_div, | ||
576 | &axg_mst_d_lrclk_div, | ||
577 | &axg_mst_e_lrclk_div, | ||
578 | &axg_mst_f_lrclk_div, | ||
579 | &axg_mst_a_lrclk, | ||
580 | &axg_mst_b_lrclk, | ||
581 | &axg_mst_c_lrclk, | ||
582 | &axg_mst_d_lrclk, | ||
583 | &axg_mst_e_lrclk, | ||
584 | &axg_mst_f_lrclk, | ||
585 | &axg_tdmin_a_sclk_sel, | ||
586 | &axg_tdmin_b_sclk_sel, | ||
587 | &axg_tdmin_c_sclk_sel, | ||
588 | &axg_tdmin_lb_sclk_sel, | ||
589 | &axg_tdmout_a_sclk_sel, | ||
590 | &axg_tdmout_b_sclk_sel, | ||
591 | &axg_tdmout_c_sclk_sel, | ||
592 | &axg_tdmin_a_sclk_pre_en, | ||
593 | &axg_tdmin_b_sclk_pre_en, | ||
594 | &axg_tdmin_c_sclk_pre_en, | ||
595 | &axg_tdmin_lb_sclk_pre_en, | ||
596 | &axg_tdmout_a_sclk_pre_en, | ||
597 | &axg_tdmout_b_sclk_pre_en, | ||
598 | &axg_tdmout_c_sclk_pre_en, | ||
599 | &axg_tdmin_a_sclk_post_en, | ||
600 | &axg_tdmin_b_sclk_post_en, | ||
601 | &axg_tdmin_c_sclk_post_en, | ||
602 | &axg_tdmin_lb_sclk_post_en, | ||
603 | &axg_tdmout_a_sclk_post_en, | ||
604 | &axg_tdmout_b_sclk_post_en, | ||
605 | &axg_tdmout_c_sclk_post_en, | ||
606 | &axg_tdmin_a_sclk, | ||
607 | &axg_tdmin_b_sclk, | ||
608 | &axg_tdmin_c_sclk, | ||
609 | &axg_tdmin_lb_sclk, | ||
610 | &axg_tdmout_a_sclk, | ||
611 | &axg_tdmout_b_sclk, | ||
612 | &axg_tdmout_c_sclk, | ||
613 | &axg_tdmin_a_lrclk, | ||
614 | &axg_tdmin_b_lrclk, | ||
615 | &axg_tdmin_c_lrclk, | ||
616 | &axg_tdmin_lb_lrclk, | ||
617 | &axg_tdmout_a_lrclk, | ||
618 | &axg_tdmout_b_lrclk, | ||
619 | &axg_tdmout_c_lrclk, | ||
620 | }; | ||
621 | |||
622 | static struct clk *devm_clk_get_enable(struct device *dev, char *id) | ||
623 | { | ||
624 | struct clk *clk; | ||
625 | int ret; | ||
626 | |||
627 | clk = devm_clk_get(dev, id); | ||
628 | if (IS_ERR(clk)) { | ||
629 | if (PTR_ERR(clk) != -EPROBE_DEFER) | ||
630 | dev_err(dev, "failed to get %s", id); | ||
631 | return clk; | ||
632 | } | ||
633 | |||
634 | ret = clk_prepare_enable(clk); | ||
635 | if (ret) { | ||
636 | dev_err(dev, "failed to enable %s", id); | ||
637 | return ERR_PTR(ret); | ||
638 | } | ||
639 | |||
640 | ret = devm_add_action_or_reset(dev, | ||
641 | (void(*)(void *))clk_disable_unprepare, | ||
642 | clk); | ||
643 | if (ret) { | ||
644 | dev_err(dev, "failed to add reset action on %s", id); | ||
645 | return ERR_PTR(ret); | ||
646 | } | ||
647 | |||
648 | return clk; | ||
649 | } | ||
650 | |||
651 | static const struct clk_ops axg_clk_no_ops = {}; | ||
652 | |||
653 | static struct clk_hw *axg_clk_hw_register_bypass(struct device *dev, | ||
654 | const char *name, | ||
655 | const char *parent_name) | ||
656 | { | ||
657 | struct clk_hw *hw; | ||
658 | struct clk_init_data init; | ||
659 | char *clk_name; | ||
660 | int ret; | ||
661 | |||
662 | hw = devm_kzalloc(dev, sizeof(*hw), GFP_KERNEL); | ||
663 | if (!hw) | ||
664 | return ERR_PTR(-ENOMEM); | ||
665 | |||
666 | clk_name = kasprintf(GFP_KERNEL, "axg_%s", name); | ||
667 | if (!clk_name) | ||
668 | return ERR_PTR(-ENOMEM); | ||
669 | |||
670 | init.name = clk_name; | ||
671 | init.ops = &axg_clk_no_ops; | ||
672 | init.flags = 0; | ||
673 | init.parent_names = parent_name ? &parent_name : NULL; | ||
674 | init.num_parents = parent_name ? 1 : 0; | ||
675 | hw->init = &init; | ||
676 | |||
677 | ret = devm_clk_hw_register(dev, hw); | ||
678 | kfree(clk_name); | ||
679 | |||
680 | return ret ? ERR_PTR(ret) : hw; | ||
681 | } | ||
682 | |||
683 | static int axg_register_clk_hw_input(struct device *dev, | ||
684 | const char *name, | ||
685 | unsigned int clkid) | ||
686 | { | ||
687 | struct clk *parent_clk = devm_clk_get(dev, name); | ||
688 | struct clk_hw *hw = NULL; | ||
689 | |||
690 | if (IS_ERR(parent_clk)) { | ||
691 | int err = PTR_ERR(parent_clk); | ||
692 | |||
693 | /* It is ok if an input clock is missing */ | ||
694 | if (err == -ENOENT) { | ||
695 | dev_dbg(dev, "%s not provided", name); | ||
696 | } else { | ||
697 | if (err != -EPROBE_DEFER) | ||
698 | dev_err(dev, "failed to get %s clock", name); | ||
699 | return err; | ||
700 | } | ||
701 | } else { | ||
702 | hw = axg_clk_hw_register_bypass(dev, name, | ||
703 | __clk_get_name(parent_clk)); | ||
704 | } | ||
705 | |||
706 | if (IS_ERR(hw)) { | ||
707 | dev_err(dev, "failed to register %s clock", name); | ||
708 | return PTR_ERR(hw); | ||
709 | } | ||
710 | |||
711 | axg_audio_hw_onecell_data.hws[clkid] = hw; | ||
712 | return 0; | ||
713 | } | ||
714 | |||
715 | static int axg_register_clk_hw_inputs(struct device *dev, | ||
716 | const char *basename, | ||
717 | unsigned int count, | ||
718 | unsigned int clkid) | ||
719 | { | ||
720 | char *name; | ||
721 | int i, ret; | ||
722 | |||
723 | for (i = 0; i < count; i++) { | ||
724 | name = kasprintf(GFP_KERNEL, "%s%d", basename, i); | ||
725 | if (!name) | ||
726 | return -ENOMEM; | ||
727 | |||
728 | ret = axg_register_clk_hw_input(dev, name, clkid + i); | ||
729 | kfree(name); | ||
730 | if (ret) | ||
731 | return ret; | ||
732 | } | ||
733 | |||
734 | return 0; | ||
735 | } | ||
736 | |||
737 | static const struct regmap_config axg_audio_regmap_cfg = { | ||
738 | .reg_bits = 32, | ||
739 | .val_bits = 32, | ||
740 | .reg_stride = 4, | ||
741 | .max_register = AUDIO_CLK_PDMIN_CTRL1, | ||
742 | }; | ||
743 | |||
744 | static int axg_audio_clkc_probe(struct platform_device *pdev) | ||
745 | { | ||
746 | struct device *dev = &pdev->dev; | ||
747 | struct regmap *map; | ||
748 | struct resource *res; | ||
749 | void __iomem *regs; | ||
750 | struct clk *clk; | ||
751 | struct clk_hw *hw; | ||
752 | int ret, i; | ||
753 | |||
754 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
755 | regs = devm_ioremap_resource(dev, res); | ||
756 | if (IS_ERR(regs)) | ||
757 | return PTR_ERR(regs); | ||
758 | |||
759 | map = devm_regmap_init_mmio(dev, regs, &axg_audio_regmap_cfg); | ||
760 | if (IS_ERR(map)) { | ||
761 | dev_err(dev, "failed to init regmap: %ld\n", PTR_ERR(map)); | ||
762 | return PTR_ERR(map); | ||
763 | } | ||
764 | |||
765 | /* Get the mandatory peripheral clock */ | ||
766 | clk = devm_clk_get_enable(dev, "pclk"); | ||
767 | if (IS_ERR(clk)) | ||
768 | return PTR_ERR(clk); | ||
769 | |||
770 | ret = device_reset(dev); | ||
771 | if (ret) { | ||
772 | dev_err(dev, "failed to reset device\n"); | ||
773 | return ret; | ||
774 | } | ||
775 | |||
776 | /* Register the peripheral input clock */ | ||
777 | hw = axg_clk_hw_register_bypass(dev, "audio_pclk", | ||
778 | __clk_get_name(clk)); | ||
779 | if (IS_ERR(hw)) | ||
780 | return PTR_ERR(hw); | ||
781 | |||
782 | axg_audio_hw_onecell_data.hws[AUD_CLKID_PCLK] = hw; | ||
783 | |||
784 | /* Register optional input master clocks */ | ||
785 | ret = axg_register_clk_hw_inputs(dev, "mst_in", | ||
786 | AXG_MST_IN_COUNT, | ||
787 | AUD_CLKID_MST0); | ||
788 | if (ret) | ||
789 | return ret; | ||
790 | |||
791 | /* Register optional input slave sclks */ | ||
792 | ret = axg_register_clk_hw_inputs(dev, "slv_sclk", | ||
793 | AXG_SLV_SCLK_COUNT, | ||
794 | AUD_CLKID_SLV_SCLK0); | ||
795 | if (ret) | ||
796 | return ret; | ||
797 | |||
798 | /* Register optional input slave lrclks */ | ||
799 | ret = axg_register_clk_hw_inputs(dev, "slv_lrclk", | ||
800 | AXG_SLV_LRCLK_COUNT, | ||
801 | AUD_CLKID_SLV_LRCLK0); | ||
802 | if (ret) | ||
803 | return ret; | ||
804 | |||
805 | /* Populate regmap for the regmap backed clocks */ | ||
806 | for (i = 0; i < ARRAY_SIZE(axg_audio_clk_regmaps); i++) | ||
807 | axg_audio_clk_regmaps[i]->map = map; | ||
808 | |||
809 | /* Take care to skip the registered input clocks */ | ||
810 | for (i = AUD_CLKID_DDR_ARB; i < axg_audio_hw_onecell_data.num; i++) { | ||
811 | hw = axg_audio_hw_onecell_data.hws[i]; | ||
812 | /* array might be sparse */ | ||
813 | if (!hw) | ||
814 | continue; | ||
815 | |||
816 | ret = devm_clk_hw_register(dev, hw); | ||
817 | if (ret) { | ||
818 | dev_err(dev, "failed to register clock %s\n", | ||
819 | hw->init->name); | ||
820 | return ret; | ||
821 | } | ||
822 | } | ||
823 | |||
824 | return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, | ||
825 | &axg_audio_hw_onecell_data); | ||
826 | } | ||
827 | |||
828 | static const struct of_device_id clkc_match_table[] = { | ||
829 | { .compatible = "amlogic,axg-audio-clkc" }, | ||
830 | {} | ||
831 | }; | ||
832 | MODULE_DEVICE_TABLE(of, clkc_match_table); | ||
833 | |||
834 | static struct platform_driver axg_audio_driver = { | ||
835 | .probe = axg_audio_clkc_probe, | ||
836 | .driver = { | ||
837 | .name = "axg-audio-clkc", | ||
838 | .of_match_table = clkc_match_table, | ||
839 | }, | ||
840 | }; | ||
841 | module_platform_driver(axg_audio_driver); | ||
842 | |||
843 | MODULE_DESCRIPTION("Amlogic A113x Audio Clock driver"); | ||
844 | MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>"); | ||
845 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/clk/meson/axg-audio.h b/drivers/clk/meson/axg-audio.h new file mode 100644 index 000000000000..7191b39c9d65 --- /dev/null +++ b/drivers/clk/meson/axg-audio.h | |||
@@ -0,0 +1,127 @@ | |||
1 | /* SPDX-License-Identifier: (GPL-2.0 OR MIT) */ | ||
2 | /* | ||
3 | * Copyright (c) 2018 BayLibre, SAS. | ||
4 | * Author: Jerome Brunet <jbrunet@baylibre.com> | ||
5 | */ | ||
6 | |||
7 | #ifndef __AXG_AUDIO_CLKC_H | ||
8 | #define __AXG_AUDIO_CLKC_H | ||
9 | |||
10 | /* | ||
11 | * Audio Clock register offsets | ||
12 | * | ||
13 | * Register offsets from the datasheet must be multiplied by 4 before | ||
14 | * to get the right offset | ||
15 | */ | ||
16 | #define AUDIO_CLK_GATE_EN 0x000 | ||
17 | #define AUDIO_MCLK_A_CTRL 0x004 | ||
18 | #define AUDIO_MCLK_B_CTRL 0x008 | ||
19 | #define AUDIO_MCLK_C_CTRL 0x00C | ||
20 | #define AUDIO_MCLK_D_CTRL 0x010 | ||
21 | #define AUDIO_MCLK_E_CTRL 0x014 | ||
22 | #define AUDIO_MCLK_F_CTRL 0x018 | ||
23 | #define AUDIO_MST_A_SCLK_CTRL0 0x040 | ||
24 | #define AUDIO_MST_A_SCLK_CTRL1 0x044 | ||
25 | #define AUDIO_MST_B_SCLK_CTRL0 0x048 | ||
26 | #define AUDIO_MST_B_SCLK_CTRL1 0x04C | ||
27 | #define AUDIO_MST_C_SCLK_CTRL0 0x050 | ||
28 | #define AUDIO_MST_C_SCLK_CTRL1 0x054 | ||
29 | #define AUDIO_MST_D_SCLK_CTRL0 0x058 | ||
30 | #define AUDIO_MST_D_SCLK_CTRL1 0x05C | ||
31 | #define AUDIO_MST_E_SCLK_CTRL0 0x060 | ||
32 | #define AUDIO_MST_E_SCLK_CTRL1 0x064 | ||
33 | #define AUDIO_MST_F_SCLK_CTRL0 0x068 | ||
34 | #define AUDIO_MST_F_SCLK_CTRL1 0x06C | ||
35 | #define AUDIO_CLK_TDMIN_A_CTRL 0x080 | ||
36 | #define AUDIO_CLK_TDMIN_B_CTRL 0x084 | ||
37 | #define AUDIO_CLK_TDMIN_C_CTRL 0x088 | ||
38 | #define AUDIO_CLK_TDMIN_LB_CTRL 0x08C | ||
39 | #define AUDIO_CLK_TDMOUT_A_CTRL 0x090 | ||
40 | #define AUDIO_CLK_TDMOUT_B_CTRL 0x094 | ||
41 | #define AUDIO_CLK_TDMOUT_C_CTRL 0x098 | ||
42 | #define AUDIO_CLK_SPDIFIN_CTRL 0x09C | ||
43 | #define AUDIO_CLK_SPDIFOUT_CTRL 0x0A0 | ||
44 | #define AUDIO_CLK_RESAMPLE_CTRL 0x0A4 | ||
45 | #define AUDIO_CLK_LOCKER_CTRL 0x0A8 | ||
46 | #define AUDIO_CLK_PDMIN_CTRL0 0x0AC | ||
47 | #define AUDIO_CLK_PDMIN_CTRL1 0x0B0 | ||
48 | |||
49 | /* | ||
50 | * CLKID index values | ||
51 | * These indices are entirely contrived and do not map onto the hardware. | ||
52 | */ | ||
53 | |||
54 | #define AUD_CLKID_PCLK 0 | ||
55 | #define AUD_CLKID_MST0 1 | ||
56 | #define AUD_CLKID_MST1 2 | ||
57 | #define AUD_CLKID_MST2 3 | ||
58 | #define AUD_CLKID_MST3 4 | ||
59 | #define AUD_CLKID_MST4 5 | ||
60 | #define AUD_CLKID_MST5 6 | ||
61 | #define AUD_CLKID_MST6 7 | ||
62 | #define AUD_CLKID_MST7 8 | ||
63 | #define AUD_CLKID_MST_A_MCLK_SEL 59 | ||
64 | #define AUD_CLKID_MST_B_MCLK_SEL 60 | ||
65 | #define AUD_CLKID_MST_C_MCLK_SEL 61 | ||
66 | #define AUD_CLKID_MST_D_MCLK_SEL 62 | ||
67 | #define AUD_CLKID_MST_E_MCLK_SEL 63 | ||
68 | #define AUD_CLKID_MST_F_MCLK_SEL 64 | ||
69 | #define AUD_CLKID_MST_A_MCLK_DIV 65 | ||
70 | #define AUD_CLKID_MST_B_MCLK_DIV 66 | ||
71 | #define AUD_CLKID_MST_C_MCLK_DIV 67 | ||
72 | #define AUD_CLKID_MST_D_MCLK_DIV 68 | ||
73 | #define AUD_CLKID_MST_E_MCLK_DIV 69 | ||
74 | #define AUD_CLKID_MST_F_MCLK_DIV 70 | ||
75 | #define AUD_CLKID_SPDIFOUT_CLK_SEL 71 | ||
76 | #define AUD_CLKID_SPDIFOUT_CLK_DIV 72 | ||
77 | #define AUD_CLKID_SPDIFIN_CLK_SEL 73 | ||
78 | #define AUD_CLKID_SPDIFIN_CLK_DIV 74 | ||
79 | #define AUD_CLKID_PDM_DCLK_SEL 75 | ||
80 | #define AUD_CLKID_PDM_DCLK_DIV 76 | ||
81 | #define AUD_CLKID_PDM_SYSCLK_SEL 77 | ||
82 | #define AUD_CLKID_PDM_SYSCLK_DIV 78 | ||
83 | #define AUD_CLKID_MST_A_SCLK_PRE_EN 92 | ||
84 | #define AUD_CLKID_MST_B_SCLK_PRE_EN 93 | ||
85 | #define AUD_CLKID_MST_C_SCLK_PRE_EN 94 | ||
86 | #define AUD_CLKID_MST_D_SCLK_PRE_EN 95 | ||
87 | #define AUD_CLKID_MST_E_SCLK_PRE_EN 96 | ||
88 | #define AUD_CLKID_MST_F_SCLK_PRE_EN 97 | ||
89 | #define AUD_CLKID_MST_A_SCLK_DIV 98 | ||
90 | #define AUD_CLKID_MST_B_SCLK_DIV 99 | ||
91 | #define AUD_CLKID_MST_C_SCLK_DIV 100 | ||
92 | #define AUD_CLKID_MST_D_SCLK_DIV 101 | ||
93 | #define AUD_CLKID_MST_E_SCLK_DIV 102 | ||
94 | #define AUD_CLKID_MST_F_SCLK_DIV 103 | ||
95 | #define AUD_CLKID_MST_A_SCLK_POST_EN 104 | ||
96 | #define AUD_CLKID_MST_B_SCLK_POST_EN 105 | ||
97 | #define AUD_CLKID_MST_C_SCLK_POST_EN 106 | ||
98 | #define AUD_CLKID_MST_D_SCLK_POST_EN 107 | ||
99 | #define AUD_CLKID_MST_E_SCLK_POST_EN 108 | ||
100 | #define AUD_CLKID_MST_F_SCLK_POST_EN 109 | ||
101 | #define AUD_CLKID_MST_A_LRCLK_DIV 110 | ||
102 | #define AUD_CLKID_MST_B_LRCLK_DIV 111 | ||
103 | #define AUD_CLKID_MST_C_LRCLK_DIV 112 | ||
104 | #define AUD_CLKID_MST_D_LRCLK_DIV 113 | ||
105 | #define AUD_CLKID_MST_E_LRCLK_DIV 114 | ||
106 | #define AUD_CLKID_MST_F_LRCLK_DIV 115 | ||
107 | #define AUD_CLKID_TDMIN_A_SCLK_PRE_EN 137 | ||
108 | #define AUD_CLKID_TDMIN_B_SCLK_PRE_EN 138 | ||
109 | #define AUD_CLKID_TDMIN_C_SCLK_PRE_EN 139 | ||
110 | #define AUD_CLKID_TDMIN_LB_SCLK_PRE_EN 140 | ||
111 | #define AUD_CLKID_TDMOUT_A_SCLK_PRE_EN 141 | ||
112 | #define AUD_CLKID_TDMOUT_B_SCLK_PRE_EN 142 | ||
113 | #define AUD_CLKID_TDMOUT_C_SCLK_PRE_EN 143 | ||
114 | #define AUD_CLKID_TDMIN_A_SCLK_POST_EN 144 | ||
115 | #define AUD_CLKID_TDMIN_B_SCLK_POST_EN 145 | ||
116 | #define AUD_CLKID_TDMIN_C_SCLK_POST_EN 146 | ||
117 | #define AUD_CLKID_TDMIN_LB_SCLK_POST_EN 147 | ||
118 | #define AUD_CLKID_TDMOUT_A_SCLK_POST_EN 148 | ||
119 | #define AUD_CLKID_TDMOUT_B_SCLK_POST_EN 149 | ||
120 | #define AUD_CLKID_TDMOUT_C_SCLK_POST_EN 150 | ||
121 | |||
122 | /* include the CLKIDs which are part of the DT bindings */ | ||
123 | #include <dt-bindings/clock/axg-audio-clkc.h> | ||
124 | |||
125 | #define NR_CLKS 151 | ||
126 | |||
127 | #endif /*__AXG_AUDIO_CLKC_H */ | ||
diff --git a/drivers/clk/meson/axg.c b/drivers/clk/meson/axg.c index bd4dbc696b88..00ce62ad6416 100644 --- a/drivers/clk/meson/axg.c +++ b/drivers/clk/meson/axg.c | |||
@@ -12,7 +12,6 @@ | |||
12 | #include <linux/clk.h> | 12 | #include <linux/clk.h> |
13 | #include <linux/clk-provider.h> | 13 | #include <linux/clk-provider.h> |
14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
15 | #include <linux/of_address.h> | ||
16 | #include <linux/of_device.h> | 15 | #include <linux/of_device.h> |
17 | #include <linux/mfd/syscon.h> | 16 | #include <linux/mfd/syscon.h> |
18 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
@@ -626,6 +625,137 @@ static struct clk_regmap axg_mpll3 = { | |||
626 | }, | 625 | }, |
627 | }; | 626 | }; |
628 | 627 | ||
628 | static const struct pll_rate_table axg_pcie_pll_rate_table[] = { | ||
629 | { | ||
630 | .rate = 100000000, | ||
631 | .m = 200, | ||
632 | .n = 3, | ||
633 | .od = 1, | ||
634 | .od2 = 3, | ||
635 | }, | ||
636 | { /* sentinel */ }, | ||
637 | }; | ||
638 | |||
639 | static const struct reg_sequence axg_pcie_init_regs[] = { | ||
640 | { .reg = HHI_PCIE_PLL_CNTL, .def = 0x400106c8 }, | ||
641 | { .reg = HHI_PCIE_PLL_CNTL1, .def = 0x0084a2aa }, | ||
642 | { .reg = HHI_PCIE_PLL_CNTL2, .def = 0xb75020be }, | ||
643 | { .reg = HHI_PCIE_PLL_CNTL3, .def = 0x0a47488e }, | ||
644 | { .reg = HHI_PCIE_PLL_CNTL4, .def = 0xc000004d }, | ||
645 | { .reg = HHI_PCIE_PLL_CNTL5, .def = 0x00078000 }, | ||
646 | { .reg = HHI_PCIE_PLL_CNTL6, .def = 0x002323c6 }, | ||
647 | }; | ||
648 | |||
649 | static struct clk_regmap axg_pcie_pll = { | ||
650 | .data = &(struct meson_clk_pll_data){ | ||
651 | .m = { | ||
652 | .reg_off = HHI_PCIE_PLL_CNTL, | ||
653 | .shift = 0, | ||
654 | .width = 9, | ||
655 | }, | ||
656 | .n = { | ||
657 | .reg_off = HHI_PCIE_PLL_CNTL, | ||
658 | .shift = 9, | ||
659 | .width = 5, | ||
660 | }, | ||
661 | .od = { | ||
662 | .reg_off = HHI_PCIE_PLL_CNTL, | ||
663 | .shift = 16, | ||
664 | .width = 2, | ||
665 | }, | ||
666 | .od2 = { | ||
667 | .reg_off = HHI_PCIE_PLL_CNTL6, | ||
668 | .shift = 6, | ||
669 | .width = 2, | ||
670 | }, | ||
671 | .frac = { | ||
672 | .reg_off = HHI_PCIE_PLL_CNTL1, | ||
673 | .shift = 0, | ||
674 | .width = 12, | ||
675 | }, | ||
676 | .l = { | ||
677 | .reg_off = HHI_PCIE_PLL_CNTL, | ||
678 | .shift = 31, | ||
679 | .width = 1, | ||
680 | }, | ||
681 | .rst = { | ||
682 | .reg_off = HHI_PCIE_PLL_CNTL, | ||
683 | .shift = 29, | ||
684 | .width = 1, | ||
685 | }, | ||
686 | .table = axg_pcie_pll_rate_table, | ||
687 | .init_regs = axg_pcie_init_regs, | ||
688 | .init_count = ARRAY_SIZE(axg_pcie_init_regs), | ||
689 | }, | ||
690 | .hw.init = &(struct clk_init_data){ | ||
691 | .name = "pcie_pll", | ||
692 | .ops = &meson_clk_pll_ops, | ||
693 | .parent_names = (const char *[]){ "xtal" }, | ||
694 | .num_parents = 1, | ||
695 | }, | ||
696 | }; | ||
697 | |||
698 | static struct clk_regmap axg_pcie_mux = { | ||
699 | .data = &(struct clk_regmap_mux_data){ | ||
700 | .offset = HHI_PCIE_PLL_CNTL6, | ||
701 | .mask = 0x1, | ||
702 | .shift = 2, | ||
703 | }, | ||
704 | .hw.init = &(struct clk_init_data){ | ||
705 | .name = "pcie_mux", | ||
706 | .ops = &clk_regmap_mux_ops, | ||
707 | .parent_names = (const char *[]){ "mpll3", "pcie_pll" }, | ||
708 | .num_parents = 2, | ||
709 | .flags = CLK_SET_RATE_PARENT, | ||
710 | }, | ||
711 | }; | ||
712 | |||
713 | static struct clk_regmap axg_pcie_ref = { | ||
714 | .data = &(struct clk_regmap_mux_data){ | ||
715 | .offset = HHI_PCIE_PLL_CNTL6, | ||
716 | .mask = 0x1, | ||
717 | .shift = 1, | ||
718 | /* skip the parent 0, reserved for debug */ | ||
719 | .table = (u32[]){ 1 }, | ||
720 | }, | ||
721 | .hw.init = &(struct clk_init_data){ | ||
722 | .name = "pcie_ref", | ||
723 | .ops = &clk_regmap_mux_ops, | ||
724 | .parent_names = (const char *[]){ "pcie_mux" }, | ||
725 | .num_parents = 1, | ||
726 | .flags = CLK_SET_RATE_PARENT, | ||
727 | }, | ||
728 | }; | ||
729 | |||
730 | static struct clk_regmap axg_pcie_cml_en0 = { | ||
731 | .data = &(struct clk_regmap_gate_data){ | ||
732 | .offset = HHI_PCIE_PLL_CNTL6, | ||
733 | .bit_idx = 4, | ||
734 | }, | ||
735 | .hw.init = &(struct clk_init_data) { | ||
736 | .name = "pcie_cml_en0", | ||
737 | .ops = &clk_regmap_gate_ops, | ||
738 | .parent_names = (const char *[]){ "pcie_ref" }, | ||
739 | .num_parents = 1, | ||
740 | .flags = CLK_SET_RATE_PARENT, | ||
741 | |||
742 | }, | ||
743 | }; | ||
744 | |||
745 | static struct clk_regmap axg_pcie_cml_en1 = { | ||
746 | .data = &(struct clk_regmap_gate_data){ | ||
747 | .offset = HHI_PCIE_PLL_CNTL6, | ||
748 | .bit_idx = 3, | ||
749 | }, | ||
750 | .hw.init = &(struct clk_init_data) { | ||
751 | .name = "pcie_cml_en1", | ||
752 | .ops = &clk_regmap_gate_ops, | ||
753 | .parent_names = (const char *[]){ "pcie_ref" }, | ||
754 | .num_parents = 1, | ||
755 | .flags = CLK_SET_RATE_PARENT, | ||
756 | }, | ||
757 | }; | ||
758 | |||
629 | static u32 mux_table_clk81[] = { 0, 2, 3, 4, 5, 6, 7 }; | 759 | static u32 mux_table_clk81[] = { 0, 2, 3, 4, 5, 6, 7 }; |
630 | static const char * const clk81_parent_names[] = { | 760 | static const char * const clk81_parent_names[] = { |
631 | "xtal", "fclk_div7", "mpll1", "mpll2", "fclk_div4", | 761 | "xtal", "fclk_div7", "mpll1", "mpll2", "fclk_div4", |
@@ -779,6 +909,63 @@ static struct clk_regmap axg_sd_emmc_c_clk0 = { | |||
779 | }, | 909 | }, |
780 | }; | 910 | }; |
781 | 911 | ||
912 | static u32 mux_table_gen_clk[] = { 0, 4, 5, 6, 7, 8, | ||
913 | 9, 10, 11, 13, 14, }; | ||
914 | static const char * const gen_clk_parent_names[] = { | ||
915 | "xtal", "hifi_pll", "mpll0", "mpll1", "mpll2", "mpll3", | ||
916 | "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7", "gp0_pll", | ||
917 | }; | ||
918 | |||
919 | static struct clk_regmap axg_gen_clk_sel = { | ||
920 | .data = &(struct clk_regmap_mux_data){ | ||
921 | .offset = HHI_GEN_CLK_CNTL, | ||
922 | .mask = 0xf, | ||
923 | .shift = 12, | ||
924 | .table = mux_table_gen_clk, | ||
925 | }, | ||
926 | .hw.init = &(struct clk_init_data){ | ||
927 | .name = "gen_clk_sel", | ||
928 | .ops = &clk_regmap_mux_ops, | ||
929 | /* | ||
930 | * bits 15:12 selects from 14 possible parents: | ||
931 | * xtal, [rtc_oscin_i], [sys_cpu_div16], [ddr_dpll_pt], | ||
932 | * hifi_pll, mpll0, mpll1, mpll2, mpll3, fdiv4, | ||
933 | * fdiv3, fdiv5, [cts_msr_clk], fdiv7, gp0_pll | ||
934 | */ | ||
935 | .parent_names = gen_clk_parent_names, | ||
936 | .num_parents = ARRAY_SIZE(gen_clk_parent_names), | ||
937 | }, | ||
938 | }; | ||
939 | |||
940 | static struct clk_regmap axg_gen_clk_div = { | ||
941 | .data = &(struct clk_regmap_div_data){ | ||
942 | .offset = HHI_GEN_CLK_CNTL, | ||
943 | .shift = 0, | ||
944 | .width = 11, | ||
945 | }, | ||
946 | .hw.init = &(struct clk_init_data){ | ||
947 | .name = "gen_clk_div", | ||
948 | .ops = &clk_regmap_divider_ops, | ||
949 | .parent_names = (const char *[]){ "gen_clk_sel" }, | ||
950 | .num_parents = 1, | ||
951 | .flags = CLK_SET_RATE_PARENT, | ||
952 | }, | ||
953 | }; | ||
954 | |||
955 | static struct clk_regmap axg_gen_clk = { | ||
956 | .data = &(struct clk_regmap_gate_data){ | ||
957 | .offset = HHI_GEN_CLK_CNTL, | ||
958 | .bit_idx = 7, | ||
959 | }, | ||
960 | .hw.init = &(struct clk_init_data){ | ||
961 | .name = "gen_clk", | ||
962 | .ops = &clk_regmap_gate_ops, | ||
963 | .parent_names = (const char *[]){ "gen_clk_div" }, | ||
964 | .num_parents = 1, | ||
965 | .flags = CLK_SET_RATE_PARENT, | ||
966 | }, | ||
967 | }; | ||
968 | |||
782 | /* Everything Else (EE) domain gates */ | 969 | /* Everything Else (EE) domain gates */ |
783 | static MESON_GATE(axg_ddr, HHI_GCLK_MPEG0, 0); | 970 | static MESON_GATE(axg_ddr, HHI_GCLK_MPEG0, 0); |
784 | static MESON_GATE(axg_audio_locker, HHI_GCLK_MPEG0, 2); | 971 | static MESON_GATE(axg_audio_locker, HHI_GCLK_MPEG0, 2); |
@@ -821,6 +1008,7 @@ static MESON_GATE(axg_mmc_pclk, HHI_GCLK_MPEG2, 11); | |||
821 | static MESON_GATE(axg_vpu_intr, HHI_GCLK_MPEG2, 25); | 1008 | static MESON_GATE(axg_vpu_intr, HHI_GCLK_MPEG2, 25); |
822 | static MESON_GATE(axg_sec_ahb_ahb3_bridge, HHI_GCLK_MPEG2, 26); | 1009 | static MESON_GATE(axg_sec_ahb_ahb3_bridge, HHI_GCLK_MPEG2, 26); |
823 | static MESON_GATE(axg_gic, HHI_GCLK_MPEG2, 30); | 1010 | static MESON_GATE(axg_gic, HHI_GCLK_MPEG2, 30); |
1011 | static MESON_GATE(axg_mipi_enable, HHI_MIPI_CNTL0, 29); | ||
824 | 1012 | ||
825 | /* Always On (AO) domain gates */ | 1013 | /* Always On (AO) domain gates */ |
826 | 1014 | ||
@@ -910,6 +1098,15 @@ static struct clk_hw_onecell_data axg_hw_onecell_data = { | |||
910 | [CLKID_FCLK_DIV4_DIV] = &axg_fclk_div4_div.hw, | 1098 | [CLKID_FCLK_DIV4_DIV] = &axg_fclk_div4_div.hw, |
911 | [CLKID_FCLK_DIV5_DIV] = &axg_fclk_div5_div.hw, | 1099 | [CLKID_FCLK_DIV5_DIV] = &axg_fclk_div5_div.hw, |
912 | [CLKID_FCLK_DIV7_DIV] = &axg_fclk_div7_div.hw, | 1100 | [CLKID_FCLK_DIV7_DIV] = &axg_fclk_div7_div.hw, |
1101 | [CLKID_PCIE_PLL] = &axg_pcie_pll.hw, | ||
1102 | [CLKID_PCIE_MUX] = &axg_pcie_mux.hw, | ||
1103 | [CLKID_PCIE_REF] = &axg_pcie_ref.hw, | ||
1104 | [CLKID_PCIE_CML_EN0] = &axg_pcie_cml_en0.hw, | ||
1105 | [CLKID_PCIE_CML_EN1] = &axg_pcie_cml_en1.hw, | ||
1106 | [CLKID_MIPI_ENABLE] = &axg_mipi_enable.hw, | ||
1107 | [CLKID_GEN_CLK_SEL] = &axg_gen_clk_sel.hw, | ||
1108 | [CLKID_GEN_CLK_DIV] = &axg_gen_clk_div.hw, | ||
1109 | [CLKID_GEN_CLK] = &axg_gen_clk.hw, | ||
913 | [NR_CLKS] = NULL, | 1110 | [NR_CLKS] = NULL, |
914 | }, | 1111 | }, |
915 | .num = NR_CLKS, | 1112 | .num = NR_CLKS, |
@@ -988,6 +1185,15 @@ static struct clk_regmap *const axg_clk_regmaps[] = { | |||
988 | &axg_fclk_div4, | 1185 | &axg_fclk_div4, |
989 | &axg_fclk_div5, | 1186 | &axg_fclk_div5, |
990 | &axg_fclk_div7, | 1187 | &axg_fclk_div7, |
1188 | &axg_pcie_pll, | ||
1189 | &axg_pcie_mux, | ||
1190 | &axg_pcie_ref, | ||
1191 | &axg_pcie_cml_en0, | ||
1192 | &axg_pcie_cml_en1, | ||
1193 | &axg_mipi_enable, | ||
1194 | &axg_gen_clk_sel, | ||
1195 | &axg_gen_clk_div, | ||
1196 | &axg_gen_clk, | ||
991 | }; | 1197 | }; |
992 | 1198 | ||
993 | static const struct of_device_id clkc_match_table[] = { | 1199 | static const struct of_device_id clkc_match_table[] = { |
@@ -995,49 +1201,17 @@ static const struct of_device_id clkc_match_table[] = { | |||
995 | {} | 1201 | {} |
996 | }; | 1202 | }; |
997 | 1203 | ||
998 | static const struct regmap_config clkc_regmap_config = { | ||
999 | .reg_bits = 32, | ||
1000 | .val_bits = 32, | ||
1001 | .reg_stride = 4, | ||
1002 | }; | ||
1003 | |||
1004 | static int axg_clkc_probe(struct platform_device *pdev) | 1204 | static int axg_clkc_probe(struct platform_device *pdev) |
1005 | { | 1205 | { |
1006 | struct device *dev = &pdev->dev; | 1206 | struct device *dev = &pdev->dev; |
1007 | struct resource *res; | ||
1008 | void __iomem *clk_base = NULL; | ||
1009 | struct regmap *map; | 1207 | struct regmap *map; |
1010 | int ret, i; | 1208 | int ret, i; |
1011 | 1209 | ||
1012 | /* Get the hhi system controller node if available */ | 1210 | /* Get the hhi system controller node if available */ |
1013 | map = syscon_node_to_regmap(of_get_parent(dev->of_node)); | 1211 | map = syscon_node_to_regmap(of_get_parent(dev->of_node)); |
1014 | if (IS_ERR(map)) { | 1212 | if (IS_ERR(map)) { |
1015 | dev_err(dev, | 1213 | dev_err(dev, "failed to get HHI regmap\n"); |
1016 | "failed to get HHI regmap - Trying obsolete regs\n"); | 1214 | return PTR_ERR(map); |
1017 | |||
1018 | /* | ||
1019 | * FIXME: HHI registers should be accessed through | ||
1020 | * the appropriate system controller. This is required because | ||
1021 | * there is more than just clocks in this register space | ||
1022 | * | ||
1023 | * This fallback method is only provided temporarily until | ||
1024 | * all the platform DTs are properly using the syscon node | ||
1025 | */ | ||
1026 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
1027 | if (!res) | ||
1028 | return -EINVAL; | ||
1029 | |||
1030 | |||
1031 | clk_base = devm_ioremap(dev, res->start, resource_size(res)); | ||
1032 | if (!clk_base) { | ||
1033 | dev_err(dev, "Unable to map clk base\n"); | ||
1034 | return -ENXIO; | ||
1035 | } | ||
1036 | |||
1037 | map = devm_regmap_init_mmio(dev, clk_base, | ||
1038 | &clkc_regmap_config); | ||
1039 | if (IS_ERR(map)) | ||
1040 | return PTR_ERR(map); | ||
1041 | } | 1215 | } |
1042 | 1216 | ||
1043 | /* Populate regmap for the regmap backed clocks */ | 1217 | /* Populate regmap for the regmap backed clocks */ |
diff --git a/drivers/clk/meson/axg.h b/drivers/clk/meson/axg.h index b421df6a7ea0..1d04144a1b2c 100644 --- a/drivers/clk/meson/axg.h +++ b/drivers/clk/meson/axg.h | |||
@@ -16,6 +16,7 @@ | |||
16 | * Register offsets from the data sheet must be multiplied by 4 before | 16 | * Register offsets from the data sheet must be multiplied by 4 before |
17 | * adding them to the base address to get the right value. | 17 | * adding them to the base address to get the right value. |
18 | */ | 18 | */ |
19 | #define HHI_MIPI_CNTL0 0x00 | ||
19 | #define HHI_GP0_PLL_CNTL 0x40 | 20 | #define HHI_GP0_PLL_CNTL 0x40 |
20 | #define HHI_GP0_PLL_CNTL2 0x44 | 21 | #define HHI_GP0_PLL_CNTL2 0x44 |
21 | #define HHI_GP0_PLL_CNTL3 0x48 | 22 | #define HHI_GP0_PLL_CNTL3 0x48 |
@@ -127,8 +128,13 @@ | |||
127 | #define CLKID_FCLK_DIV4_DIV 73 | 128 | #define CLKID_FCLK_DIV4_DIV 73 |
128 | #define CLKID_FCLK_DIV5_DIV 74 | 129 | #define CLKID_FCLK_DIV5_DIV 74 |
129 | #define CLKID_FCLK_DIV7_DIV 75 | 130 | #define CLKID_FCLK_DIV7_DIV 75 |
131 | #define CLKID_PCIE_PLL 76 | ||
132 | #define CLKID_PCIE_MUX 77 | ||
133 | #define CLKID_PCIE_REF 78 | ||
134 | #define CLKID_GEN_CLK_SEL 82 | ||
135 | #define CLKID_GEN_CLK_DIV 83 | ||
130 | 136 | ||
131 | #define NR_CLKS 76 | 137 | #define NR_CLKS 85 |
132 | 138 | ||
133 | /* include the CLKIDs that have been made part of the DT binding */ | 139 | /* include the CLKIDs that have been made part of the DT binding */ |
134 | #include <dt-bindings/clock/axg-clkc.h> | 140 | #include <dt-bindings/clock/axg-clkc.h> |
diff --git a/drivers/clk/meson/clk-audio-divider.c b/drivers/clk/meson/clk-audio-divider.c deleted file mode 100644 index e4cf96ba704e..000000000000 --- a/drivers/clk/meson/clk-audio-divider.c +++ /dev/null | |||
@@ -1,110 +0,0 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * Copyright (c) 2017 AmLogic, Inc. | ||
4 | * Author: Jerome Brunet <jbrunet@baylibre.com> | ||
5 | */ | ||
6 | |||
7 | /* | ||
8 | * i2s master clock divider: The algorithm of the generic clk-divider used with | ||
9 | * a very precise clock parent such as the mpll tends to select a low divider | ||
10 | * factor. This gives poor results with this particular divider, especially with | ||
11 | * high frequencies (> 100 MHz) | ||
12 | * | ||
13 | * This driver try to select the maximum possible divider with the rate the | ||
14 | * upstream clock can provide. | ||
15 | */ | ||
16 | |||
17 | #include <linux/clk-provider.h> | ||
18 | #include "clkc.h" | ||
19 | |||
20 | static inline struct meson_clk_audio_div_data * | ||
21 | meson_clk_audio_div_data(struct clk_regmap *clk) | ||
22 | { | ||
23 | return (struct meson_clk_audio_div_data *)clk->data; | ||
24 | } | ||
25 | |||
26 | static int _div_round(unsigned long parent_rate, unsigned long rate, | ||
27 | unsigned long flags) | ||
28 | { | ||
29 | if (flags & CLK_DIVIDER_ROUND_CLOSEST) | ||
30 | return DIV_ROUND_CLOSEST_ULL((u64)parent_rate, rate); | ||
31 | |||
32 | return DIV_ROUND_UP_ULL((u64)parent_rate, rate); | ||
33 | } | ||
34 | |||
35 | static int _get_val(unsigned long parent_rate, unsigned long rate) | ||
36 | { | ||
37 | return DIV_ROUND_UP_ULL((u64)parent_rate, rate) - 1; | ||
38 | } | ||
39 | |||
40 | static int _valid_divider(unsigned int width, int divider) | ||
41 | { | ||
42 | int max_divider = 1 << width; | ||
43 | |||
44 | return clamp(divider, 1, max_divider); | ||
45 | } | ||
46 | |||
47 | static unsigned long audio_divider_recalc_rate(struct clk_hw *hw, | ||
48 | unsigned long parent_rate) | ||
49 | { | ||
50 | struct clk_regmap *clk = to_clk_regmap(hw); | ||
51 | struct meson_clk_audio_div_data *adiv = meson_clk_audio_div_data(clk); | ||
52 | unsigned long divider; | ||
53 | |||
54 | divider = meson_parm_read(clk->map, &adiv->div) + 1; | ||
55 | |||
56 | return DIV_ROUND_UP_ULL((u64)parent_rate, divider); | ||
57 | } | ||
58 | |||
59 | static long audio_divider_round_rate(struct clk_hw *hw, | ||
60 | unsigned long rate, | ||
61 | unsigned long *parent_rate) | ||
62 | { | ||
63 | struct clk_regmap *clk = to_clk_regmap(hw); | ||
64 | struct meson_clk_audio_div_data *adiv = meson_clk_audio_div_data(clk); | ||
65 | unsigned long max_prate; | ||
66 | int divider; | ||
67 | |||
68 | if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) { | ||
69 | divider = _div_round(*parent_rate, rate, adiv->flags); | ||
70 | divider = _valid_divider(adiv->div.width, divider); | ||
71 | return DIV_ROUND_UP_ULL((u64)*parent_rate, divider); | ||
72 | } | ||
73 | |||
74 | /* Get the maximum parent rate */ | ||
75 | max_prate = clk_hw_round_rate(clk_hw_get_parent(hw), ULONG_MAX); | ||
76 | |||
77 | /* Get the corresponding rounded down divider */ | ||
78 | divider = max_prate / rate; | ||
79 | divider = _valid_divider(adiv->div.width, divider); | ||
80 | |||
81 | /* Get actual rate of the parent */ | ||
82 | *parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw), | ||
83 | divider * rate); | ||
84 | |||
85 | return DIV_ROUND_UP_ULL((u64)*parent_rate, divider); | ||
86 | } | ||
87 | |||
88 | static int audio_divider_set_rate(struct clk_hw *hw, | ||
89 | unsigned long rate, | ||
90 | unsigned long parent_rate) | ||
91 | { | ||
92 | struct clk_regmap *clk = to_clk_regmap(hw); | ||
93 | struct meson_clk_audio_div_data *adiv = meson_clk_audio_div_data(clk); | ||
94 | int val = _get_val(parent_rate, rate); | ||
95 | |||
96 | meson_parm_write(clk->map, &adiv->div, val); | ||
97 | |||
98 | return 0; | ||
99 | } | ||
100 | |||
101 | const struct clk_ops meson_clk_audio_divider_ro_ops = { | ||
102 | .recalc_rate = audio_divider_recalc_rate, | ||
103 | .round_rate = audio_divider_round_rate, | ||
104 | }; | ||
105 | |||
106 | const struct clk_ops meson_clk_audio_divider_ops = { | ||
107 | .recalc_rate = audio_divider_recalc_rate, | ||
108 | .round_rate = audio_divider_round_rate, | ||
109 | .set_rate = audio_divider_set_rate, | ||
110 | }; | ||
diff --git a/drivers/clk/meson/clk-phase.c b/drivers/clk/meson/clk-phase.c new file mode 100644 index 000000000000..cba43748ce3d --- /dev/null +++ b/drivers/clk/meson/clk-phase.c | |||
@@ -0,0 +1,63 @@ | |||
1 | // SPDX-License-Identifier: (GPL-2.0 OR MIT) | ||
2 | /* | ||
3 | * Copyright (c) 2018 BayLibre, SAS. | ||
4 | * Author: Jerome Brunet <jbrunet@baylibre.com> | ||
5 | */ | ||
6 | |||
7 | #include <linux/clk-provider.h> | ||
8 | #include "clkc.h" | ||
9 | |||
10 | #define phase_step(_width) (360 / (1 << (_width))) | ||
11 | |||
12 | static inline struct meson_clk_phase_data * | ||
13 | meson_clk_phase_data(struct clk_regmap *clk) | ||
14 | { | ||
15 | return (struct meson_clk_phase_data *)clk->data; | ||
16 | } | ||
17 | |||
18 | int meson_clk_degrees_from_val(unsigned int val, unsigned int width) | ||
19 | { | ||
20 | return phase_step(width) * val; | ||
21 | } | ||
22 | EXPORT_SYMBOL_GPL(meson_clk_degrees_from_val); | ||
23 | |||
24 | unsigned int meson_clk_degrees_to_val(int degrees, unsigned int width) | ||
25 | { | ||
26 | unsigned int val = DIV_ROUND_CLOSEST(degrees, phase_step(width)); | ||
27 | |||
28 | /* | ||
29 | * This last calculation is here for cases when degrees is rounded | ||
30 | * to 360, in which case val == (1 << width). | ||
31 | */ | ||
32 | return val % (1 << width); | ||
33 | } | ||
34 | EXPORT_SYMBOL_GPL(meson_clk_degrees_to_val); | ||
35 | |||
36 | static int meson_clk_phase_get_phase(struct clk_hw *hw) | ||
37 | { | ||
38 | struct clk_regmap *clk = to_clk_regmap(hw); | ||
39 | struct meson_clk_phase_data *phase = meson_clk_phase_data(clk); | ||
40 | unsigned int val; | ||
41 | |||
42 | val = meson_parm_read(clk->map, &phase->ph); | ||
43 | |||
44 | return meson_clk_degrees_from_val(val, phase->ph.width); | ||
45 | } | ||
46 | |||
47 | static int meson_clk_phase_set_phase(struct clk_hw *hw, int degrees) | ||
48 | { | ||
49 | struct clk_regmap *clk = to_clk_regmap(hw); | ||
50 | struct meson_clk_phase_data *phase = meson_clk_phase_data(clk); | ||
51 | unsigned int val; | ||
52 | |||
53 | val = meson_clk_degrees_to_val(degrees, phase->ph.width); | ||
54 | meson_parm_write(clk->map, &phase->ph, val); | ||
55 | |||
56 | return 0; | ||
57 | } | ||
58 | |||
59 | const struct clk_ops meson_clk_phase_ops = { | ||
60 | .get_phase = meson_clk_phase_get_phase, | ||
61 | .set_phase = meson_clk_phase_set_phase, | ||
62 | }; | ||
63 | EXPORT_SYMBOL_GPL(meson_clk_phase_ops); | ||
diff --git a/drivers/clk/meson/clk-triphase.c b/drivers/clk/meson/clk-triphase.c new file mode 100644 index 000000000000..4a59936251e5 --- /dev/null +++ b/drivers/clk/meson/clk-triphase.c | |||
@@ -0,0 +1,68 @@ | |||
1 | // SPDX-License-Identifier: (GPL-2.0 OR MIT) | ||
2 | /* | ||
3 | * Copyright (c) 2018 BayLibre, SAS. | ||
4 | * Author: Jerome Brunet <jbrunet@baylibre.com> | ||
5 | */ | ||
6 | |||
7 | #include <linux/clk-provider.h> | ||
8 | #include "clkc-audio.h" | ||
9 | |||
10 | /* | ||
11 | * This is a special clock for the audio controller. | ||
12 | * The phase of mst_sclk clock output can be controlled independently | ||
13 | * for the outside world (ph0), the tdmout (ph1) and tdmin (ph2). | ||
14 | * Controlling these 3 phases as just one makes things simpler and | ||
15 | * give the same clock view to all the element on the i2s bus. | ||
16 | * If necessary, we can still control the phase in the tdm block | ||
17 | * which makes these independent control redundant. | ||
18 | */ | ||
19 | static inline struct meson_clk_triphase_data * | ||
20 | meson_clk_triphase_data(struct clk_regmap *clk) | ||
21 | { | ||
22 | return (struct meson_clk_triphase_data *)clk->data; | ||
23 | } | ||
24 | |||
25 | static void meson_clk_triphase_sync(struct clk_hw *hw) | ||
26 | { | ||
27 | struct clk_regmap *clk = to_clk_regmap(hw); | ||
28 | struct meson_clk_triphase_data *tph = meson_clk_triphase_data(clk); | ||
29 | unsigned int val; | ||
30 | |||
31 | /* Get phase 0 and sync it to phase 1 and 2 */ | ||
32 | val = meson_parm_read(clk->map, &tph->ph0); | ||
33 | meson_parm_write(clk->map, &tph->ph1, val); | ||
34 | meson_parm_write(clk->map, &tph->ph2, val); | ||
35 | } | ||
36 | |||
37 | static int meson_clk_triphase_get_phase(struct clk_hw *hw) | ||
38 | { | ||
39 | struct clk_regmap *clk = to_clk_regmap(hw); | ||
40 | struct meson_clk_triphase_data *tph = meson_clk_triphase_data(clk); | ||
41 | unsigned int val; | ||
42 | |||
43 | /* Phase are in sync, reading phase 0 is enough */ | ||
44 | val = meson_parm_read(clk->map, &tph->ph0); | ||
45 | |||
46 | return meson_clk_degrees_from_val(val, tph->ph0.width); | ||
47 | } | ||
48 | |||
49 | static int meson_clk_triphase_set_phase(struct clk_hw *hw, int degrees) | ||
50 | { | ||
51 | struct clk_regmap *clk = to_clk_regmap(hw); | ||
52 | struct meson_clk_triphase_data *tph = meson_clk_triphase_data(clk); | ||
53 | unsigned int val; | ||
54 | |||
55 | val = meson_clk_degrees_to_val(degrees, tph->ph0.width); | ||
56 | meson_parm_write(clk->map, &tph->ph0, val); | ||
57 | meson_parm_write(clk->map, &tph->ph1, val); | ||
58 | meson_parm_write(clk->map, &tph->ph2, val); | ||
59 | |||
60 | return 0; | ||
61 | } | ||
62 | |||
63 | const struct clk_ops meson_clk_triphase_ops = { | ||
64 | .init = meson_clk_triphase_sync, | ||
65 | .get_phase = meson_clk_triphase_get_phase, | ||
66 | .set_phase = meson_clk_triphase_set_phase, | ||
67 | }; | ||
68 | EXPORT_SYMBOL_GPL(meson_clk_triphase_ops); | ||
diff --git a/drivers/clk/meson/clkc-audio.h b/drivers/clk/meson/clkc-audio.h new file mode 100644 index 000000000000..0a7c157ebf81 --- /dev/null +++ b/drivers/clk/meson/clkc-audio.h | |||
@@ -0,0 +1,28 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | /* | ||
3 | * Copyright (c) 2018 BayLibre, SAS. | ||
4 | * Author: Jerome Brunet <jbrunet@baylibre.com> | ||
5 | */ | ||
6 | |||
7 | #ifndef __MESON_CLKC_AUDIO_H | ||
8 | #define __MESON_CLKC_AUDIO_H | ||
9 | |||
10 | #include "clkc.h" | ||
11 | |||
12 | struct meson_clk_triphase_data { | ||
13 | struct parm ph0; | ||
14 | struct parm ph1; | ||
15 | struct parm ph2; | ||
16 | }; | ||
17 | |||
18 | struct meson_sclk_div_data { | ||
19 | struct parm div; | ||
20 | struct parm hi; | ||
21 | unsigned int cached_div; | ||
22 | struct clk_duty cached_duty; | ||
23 | }; | ||
24 | |||
25 | extern const struct clk_ops meson_clk_triphase_ops; | ||
26 | extern const struct clk_ops meson_sclk_div_ops; | ||
27 | |||
28 | #endif /* __MESON_CLKC_AUDIO_H */ | ||
diff --git a/drivers/clk/meson/clkc.h b/drivers/clk/meson/clkc.h index 2fb084330ee9..24cec16b6038 100644 --- a/drivers/clk/meson/clkc.h +++ b/drivers/clk/meson/clkc.h | |||
@@ -91,11 +91,13 @@ struct meson_clk_mpll_data { | |||
91 | 91 | ||
92 | #define CLK_MESON_MPLL_ROUND_CLOSEST BIT(0) | 92 | #define CLK_MESON_MPLL_ROUND_CLOSEST BIT(0) |
93 | 93 | ||
94 | struct meson_clk_audio_div_data { | 94 | struct meson_clk_phase_data { |
95 | struct parm div; | 95 | struct parm ph; |
96 | u8 flags; | ||
97 | }; | 96 | }; |
98 | 97 | ||
98 | int meson_clk_degrees_from_val(unsigned int val, unsigned int width); | ||
99 | unsigned int meson_clk_degrees_to_val(int degrees, unsigned int width); | ||
100 | |||
99 | #define MESON_GATE(_name, _reg, _bit) \ | 101 | #define MESON_GATE(_name, _reg, _bit) \ |
100 | struct clk_regmap _name = { \ | 102 | struct clk_regmap _name = { \ |
101 | .data = &(struct clk_regmap_gate_data){ \ | 103 | .data = &(struct clk_regmap_gate_data){ \ |
@@ -117,7 +119,6 @@ extern const struct clk_ops meson_clk_pll_ops; | |||
117 | extern const struct clk_ops meson_clk_cpu_ops; | 119 | extern const struct clk_ops meson_clk_cpu_ops; |
118 | extern const struct clk_ops meson_clk_mpll_ro_ops; | 120 | extern const struct clk_ops meson_clk_mpll_ro_ops; |
119 | extern const struct clk_ops meson_clk_mpll_ops; | 121 | extern const struct clk_ops meson_clk_mpll_ops; |
120 | extern const struct clk_ops meson_clk_audio_divider_ro_ops; | 122 | extern const struct clk_ops meson_clk_phase_ops; |
121 | extern const struct clk_ops meson_clk_audio_divider_ops; | ||
122 | 123 | ||
123 | #endif /* __CLKC_H */ | 124 | #endif /* __CLKC_H */ |
diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c index 177fffb9ebef..86d3ae58e84c 100644 --- a/drivers/clk/meson/gxbb.c +++ b/drivers/clk/meson/gxbb.c | |||
@@ -7,7 +7,6 @@ | |||
7 | #include <linux/clk.h> | 7 | #include <linux/clk.h> |
8 | #include <linux/clk-provider.h> | 8 | #include <linux/clk-provider.h> |
9 | #include <linux/init.h> | 9 | #include <linux/init.h> |
10 | #include <linux/of_address.h> | ||
11 | #include <linux/of_device.h> | 10 | #include <linux/of_device.h> |
12 | #include <linux/mfd/syscon.h> | 11 | #include <linux/mfd/syscon.h> |
13 | #include <linux/platform_device.h> | 12 | #include <linux/platform_device.h> |
@@ -971,28 +970,26 @@ static struct clk_regmap gxbb_cts_amclk_sel = { | |||
971 | .mask = 0x3, | 970 | .mask = 0x3, |
972 | .shift = 9, | 971 | .shift = 9, |
973 | .table = (u32[]){ 1, 2, 3 }, | 972 | .table = (u32[]){ 1, 2, 3 }, |
973 | .flags = CLK_MUX_ROUND_CLOSEST, | ||
974 | }, | 974 | }, |
975 | .hw.init = &(struct clk_init_data){ | 975 | .hw.init = &(struct clk_init_data){ |
976 | .name = "cts_amclk_sel", | 976 | .name = "cts_amclk_sel", |
977 | .ops = &clk_regmap_mux_ops, | 977 | .ops = &clk_regmap_mux_ops, |
978 | .parent_names = (const char *[]){ "mpll0", "mpll1", "mpll2" }, | 978 | .parent_names = (const char *[]){ "mpll0", "mpll1", "mpll2" }, |
979 | .num_parents = 3, | 979 | .num_parents = 3, |
980 | .flags = CLK_SET_RATE_PARENT, | ||
981 | }, | 980 | }, |
982 | }; | 981 | }; |
983 | 982 | ||
984 | static struct clk_regmap gxbb_cts_amclk_div = { | 983 | static struct clk_regmap gxbb_cts_amclk_div = { |
985 | .data = &(struct meson_clk_audio_div_data){ | 984 | .data = &(struct clk_regmap_div_data) { |
986 | .div = { | 985 | .offset = HHI_AUD_CLK_CNTL, |
987 | .reg_off = HHI_AUD_CLK_CNTL, | 986 | .shift = 0, |
988 | .shift = 0, | 987 | .width = 8, |
989 | .width = 8, | ||
990 | }, | ||
991 | .flags = CLK_DIVIDER_ROUND_CLOSEST, | 988 | .flags = CLK_DIVIDER_ROUND_CLOSEST, |
992 | }, | 989 | }, |
993 | .hw.init = &(struct clk_init_data){ | 990 | .hw.init = &(struct clk_init_data){ |
994 | .name = "cts_amclk_div", | 991 | .name = "cts_amclk_div", |
995 | .ops = &meson_clk_audio_divider_ops, | 992 | .ops = &clk_regmap_divider_ops, |
996 | .parent_names = (const char *[]){ "cts_amclk_sel" }, | 993 | .parent_names = (const char *[]){ "cts_amclk_sel" }, |
997 | .num_parents = 1, | 994 | .num_parents = 1, |
998 | .flags = CLK_SET_RATE_PARENT, | 995 | .flags = CLK_SET_RATE_PARENT, |
@@ -1019,13 +1016,13 @@ static struct clk_regmap gxbb_cts_mclk_i958_sel = { | |||
1019 | .mask = 0x3, | 1016 | .mask = 0x3, |
1020 | .shift = 25, | 1017 | .shift = 25, |
1021 | .table = (u32[]){ 1, 2, 3 }, | 1018 | .table = (u32[]){ 1, 2, 3 }, |
1019 | .flags = CLK_MUX_ROUND_CLOSEST, | ||
1022 | }, | 1020 | }, |
1023 | .hw.init = &(struct clk_init_data) { | 1021 | .hw.init = &(struct clk_init_data) { |
1024 | .name = "cts_mclk_i958_sel", | 1022 | .name = "cts_mclk_i958_sel", |
1025 | .ops = &clk_regmap_mux_ops, | 1023 | .ops = &clk_regmap_mux_ops, |
1026 | .parent_names = (const char *[]){ "mpll0", "mpll1", "mpll2" }, | 1024 | .parent_names = (const char *[]){ "mpll0", "mpll1", "mpll2" }, |
1027 | .num_parents = 3, | 1025 | .num_parents = 3, |
1028 | .flags = CLK_SET_RATE_PARENT, | ||
1029 | }, | 1026 | }, |
1030 | }; | 1027 | }; |
1031 | 1028 | ||
@@ -1627,6 +1624,63 @@ static struct clk_regmap gxbb_vdec_hevc = { | |||
1627 | }, | 1624 | }, |
1628 | }; | 1625 | }; |
1629 | 1626 | ||
1627 | static u32 mux_table_gen_clk[] = { 0, 4, 5, 6, 7, 8, | ||
1628 | 9, 10, 11, 13, 14, }; | ||
1629 | static const char * const gen_clk_parent_names[] = { | ||
1630 | "xtal", "vdec_1", "vdec_hevc", "mpll0", "mpll1", "mpll2", | ||
1631 | "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7", "gp0_pll", | ||
1632 | }; | ||
1633 | |||
1634 | static struct clk_regmap gxbb_gen_clk_sel = { | ||
1635 | .data = &(struct clk_regmap_mux_data){ | ||
1636 | .offset = HHI_GEN_CLK_CNTL, | ||
1637 | .mask = 0xf, | ||
1638 | .shift = 12, | ||
1639 | .table = mux_table_gen_clk, | ||
1640 | }, | ||
1641 | .hw.init = &(struct clk_init_data){ | ||
1642 | .name = "gen_clk_sel", | ||
1643 | .ops = &clk_regmap_mux_ops, | ||
1644 | /* | ||
1645 | * bits 15:12 selects from 14 possible parents: | ||
1646 | * xtal, [rtc_oscin_i], [sys_cpu_div16], [ddr_dpll_pt], | ||
1647 | * vid_pll, vid2_pll (hevc), mpll0, mpll1, mpll2, fdiv4, | ||
1648 | * fdiv3, fdiv5, [cts_msr_clk], fdiv7, gp0_pll | ||
1649 | */ | ||
1650 | .parent_names = gen_clk_parent_names, | ||
1651 | .num_parents = ARRAY_SIZE(gen_clk_parent_names), | ||
1652 | }, | ||
1653 | }; | ||
1654 | |||
1655 | static struct clk_regmap gxbb_gen_clk_div = { | ||
1656 | .data = &(struct clk_regmap_div_data){ | ||
1657 | .offset = HHI_GEN_CLK_CNTL, | ||
1658 | .shift = 0, | ||
1659 | .width = 11, | ||
1660 | }, | ||
1661 | .hw.init = &(struct clk_init_data){ | ||
1662 | .name = "gen_clk_div", | ||
1663 | .ops = &clk_regmap_divider_ops, | ||
1664 | .parent_names = (const char *[]){ "gen_clk_sel" }, | ||
1665 | .num_parents = 1, | ||
1666 | .flags = CLK_SET_RATE_PARENT, | ||
1667 | }, | ||
1668 | }; | ||
1669 | |||
1670 | static struct clk_regmap gxbb_gen_clk = { | ||
1671 | .data = &(struct clk_regmap_gate_data){ | ||
1672 | .offset = HHI_GEN_CLK_CNTL, | ||
1673 | .bit_idx = 7, | ||
1674 | }, | ||
1675 | .hw.init = &(struct clk_init_data){ | ||
1676 | .name = "gen_clk", | ||
1677 | .ops = &clk_regmap_gate_ops, | ||
1678 | .parent_names = (const char *[]){ "gen_clk_div" }, | ||
1679 | .num_parents = 1, | ||
1680 | .flags = CLK_SET_RATE_PARENT, | ||
1681 | }, | ||
1682 | }; | ||
1683 | |||
1630 | /* Everything Else (EE) domain gates */ | 1684 | /* Everything Else (EE) domain gates */ |
1631 | static MESON_GATE(gxbb_ddr, HHI_GCLK_MPEG0, 0); | 1685 | static MESON_GATE(gxbb_ddr, HHI_GCLK_MPEG0, 0); |
1632 | static MESON_GATE(gxbb_dos, HHI_GCLK_MPEG0, 1); | 1686 | static MESON_GATE(gxbb_dos, HHI_GCLK_MPEG0, 1); |
@@ -1876,6 +1930,9 @@ static struct clk_hw_onecell_data gxbb_hw_onecell_data = { | |||
1876 | [CLKID_VDEC_HEVC_SEL] = &gxbb_vdec_hevc_sel.hw, | 1930 | [CLKID_VDEC_HEVC_SEL] = &gxbb_vdec_hevc_sel.hw, |
1877 | [CLKID_VDEC_HEVC_DIV] = &gxbb_vdec_hevc_div.hw, | 1931 | [CLKID_VDEC_HEVC_DIV] = &gxbb_vdec_hevc_div.hw, |
1878 | [CLKID_VDEC_HEVC] = &gxbb_vdec_hevc.hw, | 1932 | [CLKID_VDEC_HEVC] = &gxbb_vdec_hevc.hw, |
1933 | [CLKID_GEN_CLK_SEL] = &gxbb_gen_clk_sel.hw, | ||
1934 | [CLKID_GEN_CLK_DIV] = &gxbb_gen_clk_div.hw, | ||
1935 | [CLKID_GEN_CLK] = &gxbb_gen_clk.hw, | ||
1879 | [NR_CLKS] = NULL, | 1936 | [NR_CLKS] = NULL, |
1880 | }, | 1937 | }, |
1881 | .num = NR_CLKS, | 1938 | .num = NR_CLKS, |
@@ -2038,6 +2095,9 @@ static struct clk_hw_onecell_data gxl_hw_onecell_data = { | |||
2038 | [CLKID_VDEC_HEVC_SEL] = &gxbb_vdec_hevc_sel.hw, | 2095 | [CLKID_VDEC_HEVC_SEL] = &gxbb_vdec_hevc_sel.hw, |
2039 | [CLKID_VDEC_HEVC_DIV] = &gxbb_vdec_hevc_div.hw, | 2096 | [CLKID_VDEC_HEVC_DIV] = &gxbb_vdec_hevc_div.hw, |
2040 | [CLKID_VDEC_HEVC] = &gxbb_vdec_hevc.hw, | 2097 | [CLKID_VDEC_HEVC] = &gxbb_vdec_hevc.hw, |
2098 | [CLKID_GEN_CLK_SEL] = &gxbb_gen_clk_sel.hw, | ||
2099 | [CLKID_GEN_CLK_DIV] = &gxbb_gen_clk_div.hw, | ||
2100 | [CLKID_GEN_CLK] = &gxbb_gen_clk.hw, | ||
2041 | [NR_CLKS] = NULL, | 2101 | [NR_CLKS] = NULL, |
2042 | }, | 2102 | }, |
2043 | .num = NR_CLKS, | 2103 | .num = NR_CLKS, |
@@ -2202,6 +2262,9 @@ static struct clk_regmap *const gx_clk_regmaps[] = { | |||
2202 | &gxbb_vdec_hevc_sel, | 2262 | &gxbb_vdec_hevc_sel, |
2203 | &gxbb_vdec_hevc_div, | 2263 | &gxbb_vdec_hevc_div, |
2204 | &gxbb_vdec_hevc, | 2264 | &gxbb_vdec_hevc, |
2265 | &gxbb_gen_clk_sel, | ||
2266 | &gxbb_gen_clk_div, | ||
2267 | &gxbb_gen_clk, | ||
2205 | }; | 2268 | }; |
2206 | 2269 | ||
2207 | struct clkc_data { | 2270 | struct clkc_data { |
@@ -2228,17 +2291,9 @@ static const struct of_device_id clkc_match_table[] = { | |||
2228 | {}, | 2291 | {}, |
2229 | }; | 2292 | }; |
2230 | 2293 | ||
2231 | static const struct regmap_config clkc_regmap_config = { | ||
2232 | .reg_bits = 32, | ||
2233 | .val_bits = 32, | ||
2234 | .reg_stride = 4, | ||
2235 | }; | ||
2236 | |||
2237 | static int gxbb_clkc_probe(struct platform_device *pdev) | 2294 | static int gxbb_clkc_probe(struct platform_device *pdev) |
2238 | { | 2295 | { |
2239 | const struct clkc_data *clkc_data; | 2296 | const struct clkc_data *clkc_data; |
2240 | struct resource *res; | ||
2241 | void __iomem *clk_base; | ||
2242 | struct regmap *map; | 2297 | struct regmap *map; |
2243 | int ret, i; | 2298 | int ret, i; |
2244 | struct device *dev = &pdev->dev; | 2299 | struct device *dev = &pdev->dev; |
@@ -2250,31 +2305,8 @@ static int gxbb_clkc_probe(struct platform_device *pdev) | |||
2250 | /* Get the hhi system controller node if available */ | 2305 | /* Get the hhi system controller node if available */ |
2251 | map = syscon_node_to_regmap(of_get_parent(dev->of_node)); | 2306 | map = syscon_node_to_regmap(of_get_parent(dev->of_node)); |
2252 | if (IS_ERR(map)) { | 2307 | if (IS_ERR(map)) { |
2253 | dev_err(dev, | 2308 | dev_err(dev, "failed to get HHI regmap\n"); |
2254 | "failed to get HHI regmap - Trying obsolete regs\n"); | 2309 | return PTR_ERR(map); |
2255 | |||
2256 | /* | ||
2257 | * FIXME: HHI registers should be accessed through | ||
2258 | * the appropriate system controller. This is required because | ||
2259 | * there is more than just clocks in this register space | ||
2260 | * | ||
2261 | * This fallback method is only provided temporarily until | ||
2262 | * all the platform DTs are properly using the syscon node | ||
2263 | */ | ||
2264 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
2265 | if (!res) | ||
2266 | return -EINVAL; | ||
2267 | |||
2268 | clk_base = devm_ioremap(dev, res->start, resource_size(res)); | ||
2269 | if (!clk_base) { | ||
2270 | dev_err(dev, "Unable to map clk base\n"); | ||
2271 | return -ENXIO; | ||
2272 | } | ||
2273 | |||
2274 | map = devm_regmap_init_mmio(dev, clk_base, | ||
2275 | &clkc_regmap_config); | ||
2276 | if (IS_ERR(map)) | ||
2277 | return PTR_ERR(map); | ||
2278 | } | 2310 | } |
2279 | 2311 | ||
2280 | /* Populate regmap for the common regmap backed clocks */ | 2312 | /* Populate regmap for the common regmap backed clocks */ |
diff --git a/drivers/clk/meson/gxbb.h b/drivers/clk/meson/gxbb.h index ec1a812bf1fd..20dfb1daf5b8 100644 --- a/drivers/clk/meson/gxbb.h +++ b/drivers/clk/meson/gxbb.h | |||
@@ -66,7 +66,6 @@ | |||
66 | #define HHI_USB_CLK_CNTL 0x220 /* 0x88 offset in data sheet */ | 66 | #define HHI_USB_CLK_CNTL 0x220 /* 0x88 offset in data sheet */ |
67 | #define HHI_32K_CLK_CNTL 0x224 /* 0x89 offset in data sheet */ | 67 | #define HHI_32K_CLK_CNTL 0x224 /* 0x89 offset in data sheet */ |
68 | #define HHI_GEN_CLK_CNTL 0x228 /* 0x8a offset in data sheet */ | 68 | #define HHI_GEN_CLK_CNTL 0x228 /* 0x8a offset in data sheet */ |
69 | #define HHI_GEN_CLK_CNTL 0x228 /* 0x8a offset in data sheet */ | ||
70 | 69 | ||
71 | #define HHI_PCM_CLK_CNTL 0x258 /* 0x96 offset in data sheet */ | 70 | #define HHI_PCM_CLK_CNTL 0x258 /* 0x96 offset in data sheet */ |
72 | #define HHI_NAND_CLK_CNTL 0x25C /* 0x97 offset in data sheet */ | 71 | #define HHI_NAND_CLK_CNTL 0x25C /* 0x97 offset in data sheet */ |
@@ -158,8 +157,10 @@ | |||
158 | #define CLKID_VDEC_1_DIV 152 | 157 | #define CLKID_VDEC_1_DIV 152 |
159 | #define CLKID_VDEC_HEVC_SEL 154 | 158 | #define CLKID_VDEC_HEVC_SEL 154 |
160 | #define CLKID_VDEC_HEVC_DIV 155 | 159 | #define CLKID_VDEC_HEVC_DIV 155 |
160 | #define CLKID_GEN_CLK_SEL 157 | ||
161 | #define CLKID_GEN_CLK_DIV 158 | ||
161 | 162 | ||
162 | #define NR_CLKS 157 | 163 | #define NR_CLKS 160 |
163 | 164 | ||
164 | /* include the CLKIDs that have been made part of the DT binding */ | 165 | /* include the CLKIDs that have been made part of the DT binding */ |
165 | #include <dt-bindings/clock/gxbb-clkc.h> | 166 | #include <dt-bindings/clock/gxbb-clkc.h> |
diff --git a/drivers/clk/meson/sclk-div.c b/drivers/clk/meson/sclk-div.c new file mode 100644 index 000000000000..bc64019b8eeb --- /dev/null +++ b/drivers/clk/meson/sclk-div.c | |||
@@ -0,0 +1,243 @@ | |||
1 | // SPDX-License-Identifier: (GPL-2.0 OR MIT) | ||
2 | /* | ||
3 | * Copyright (c) 2018 BayLibre, SAS. | ||
4 | * Author: Jerome Brunet <jbrunet@baylibre.com> | ||
5 | * | ||
6 | * Sample clock generator divider: | ||
7 | * This HW divider gates with value 0 but is otherwise a zero based divider: | ||
8 | * | ||
9 | * val >= 1 | ||
10 | * divider = val + 1 | ||
11 | * | ||
12 | * The duty cycle may also be set for the LR clock variant. The duty cycle | ||
13 | * ratio is: | ||
14 | * | ||
15 | * hi = [0 - val] | ||
16 | * duty_cycle = (1 + hi) / (1 + val) | ||
17 | */ | ||
18 | |||
19 | #include "clkc-audio.h" | ||
20 | |||
21 | static inline struct meson_sclk_div_data * | ||
22 | meson_sclk_div_data(struct clk_regmap *clk) | ||
23 | { | ||
24 | return (struct meson_sclk_div_data *)clk->data; | ||
25 | } | ||
26 | |||
27 | static int sclk_div_maxval(struct meson_sclk_div_data *sclk) | ||
28 | { | ||
29 | return (1 << sclk->div.width) - 1; | ||
30 | } | ||
31 | |||
32 | static int sclk_div_maxdiv(struct meson_sclk_div_data *sclk) | ||
33 | { | ||
34 | return sclk_div_maxval(sclk) + 1; | ||
35 | } | ||
36 | |||
37 | static int sclk_div_getdiv(struct clk_hw *hw, unsigned long rate, | ||
38 | unsigned long prate, int maxdiv) | ||
39 | { | ||
40 | int div = DIV_ROUND_CLOSEST_ULL((u64)prate, rate); | ||
41 | |||
42 | return clamp(div, 2, maxdiv); | ||
43 | } | ||
44 | |||
45 | static int sclk_div_bestdiv(struct clk_hw *hw, unsigned long rate, | ||
46 | unsigned long *prate, | ||
47 | struct meson_sclk_div_data *sclk) | ||
48 | { | ||
49 | struct clk_hw *parent = clk_hw_get_parent(hw); | ||
50 | int bestdiv = 0, i; | ||
51 | unsigned long maxdiv, now, parent_now; | ||
52 | unsigned long best = 0, best_parent = 0; | ||
53 | |||
54 | if (!rate) | ||
55 | rate = 1; | ||
56 | |||
57 | maxdiv = sclk_div_maxdiv(sclk); | ||
58 | |||
59 | if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) | ||
60 | return sclk_div_getdiv(hw, rate, *prate, maxdiv); | ||
61 | |||
62 | /* | ||
63 | * The maximum divider we can use without overflowing | ||
64 | * unsigned long in rate * i below | ||
65 | */ | ||
66 | maxdiv = min(ULONG_MAX / rate, maxdiv); | ||
67 | |||
68 | for (i = 2; i <= maxdiv; i++) { | ||
69 | /* | ||
70 | * It's the most ideal case if the requested rate can be | ||
71 | * divided from parent clock without needing to change | ||
72 | * parent rate, so return the divider immediately. | ||
73 | */ | ||
74 | if (rate * i == *prate) | ||
75 | return i; | ||
76 | |||
77 | parent_now = clk_hw_round_rate(parent, rate * i); | ||
78 | now = DIV_ROUND_UP_ULL((u64)parent_now, i); | ||
79 | |||
80 | if (abs(rate - now) < abs(rate - best)) { | ||
81 | bestdiv = i; | ||
82 | best = now; | ||
83 | best_parent = parent_now; | ||
84 | } | ||
85 | } | ||
86 | |||
87 | if (!bestdiv) | ||
88 | bestdiv = sclk_div_maxdiv(sclk); | ||
89 | else | ||
90 | *prate = best_parent; | ||
91 | |||
92 | return bestdiv; | ||
93 | } | ||
94 | |||
95 | static long sclk_div_round_rate(struct clk_hw *hw, unsigned long rate, | ||
96 | unsigned long *prate) | ||
97 | { | ||
98 | struct clk_regmap *clk = to_clk_regmap(hw); | ||
99 | struct meson_sclk_div_data *sclk = meson_sclk_div_data(clk); | ||
100 | int div; | ||
101 | |||
102 | div = sclk_div_bestdiv(hw, rate, prate, sclk); | ||
103 | |||
104 | return DIV_ROUND_UP_ULL((u64)*prate, div); | ||
105 | } | ||
106 | |||
107 | static void sclk_apply_ratio(struct clk_regmap *clk, | ||
108 | struct meson_sclk_div_data *sclk) | ||
109 | { | ||
110 | unsigned int hi = DIV_ROUND_CLOSEST(sclk->cached_div * | ||
111 | sclk->cached_duty.num, | ||
112 | sclk->cached_duty.den); | ||
113 | |||
114 | if (hi) | ||
115 | hi -= 1; | ||
116 | |||
117 | meson_parm_write(clk->map, &sclk->hi, hi); | ||
118 | } | ||
119 | |||
120 | static int sclk_div_set_duty_cycle(struct clk_hw *hw, | ||
121 | struct clk_duty *duty) | ||
122 | { | ||
123 | struct clk_regmap *clk = to_clk_regmap(hw); | ||
124 | struct meson_sclk_div_data *sclk = meson_sclk_div_data(clk); | ||
125 | |||
126 | if (MESON_PARM_APPLICABLE(&sclk->hi)) { | ||
127 | memcpy(&sclk->cached_duty, duty, sizeof(*duty)); | ||
128 | sclk_apply_ratio(clk, sclk); | ||
129 | } | ||
130 | |||
131 | return 0; | ||
132 | } | ||
133 | |||
134 | static int sclk_div_get_duty_cycle(struct clk_hw *hw, | ||
135 | struct clk_duty *duty) | ||
136 | { | ||
137 | struct clk_regmap *clk = to_clk_regmap(hw); | ||
138 | struct meson_sclk_div_data *sclk = meson_sclk_div_data(clk); | ||
139 | int hi; | ||
140 | |||
141 | if (!MESON_PARM_APPLICABLE(&sclk->hi)) { | ||
142 | duty->num = 1; | ||
143 | duty->den = 2; | ||
144 | return 0; | ||
145 | } | ||
146 | |||
147 | hi = meson_parm_read(clk->map, &sclk->hi); | ||
148 | duty->num = hi + 1; | ||
149 | duty->den = sclk->cached_div; | ||
150 | return 0; | ||
151 | } | ||
152 | |||
153 | static void sclk_apply_divider(struct clk_regmap *clk, | ||
154 | struct meson_sclk_div_data *sclk) | ||
155 | { | ||
156 | if (MESON_PARM_APPLICABLE(&sclk->hi)) | ||
157 | sclk_apply_ratio(clk, sclk); | ||
158 | |||
159 | meson_parm_write(clk->map, &sclk->div, sclk->cached_div - 1); | ||
160 | } | ||
161 | |||
162 | static int sclk_div_set_rate(struct clk_hw *hw, unsigned long rate, | ||
163 | unsigned long prate) | ||
164 | { | ||
165 | struct clk_regmap *clk = to_clk_regmap(hw); | ||
166 | struct meson_sclk_div_data *sclk = meson_sclk_div_data(clk); | ||
167 | unsigned long maxdiv = sclk_div_maxdiv(sclk); | ||
168 | |||
169 | sclk->cached_div = sclk_div_getdiv(hw, rate, prate, maxdiv); | ||
170 | |||
171 | if (clk_hw_is_enabled(hw)) | ||
172 | sclk_apply_divider(clk, sclk); | ||
173 | |||
174 | return 0; | ||
175 | } | ||
176 | |||
177 | static unsigned long sclk_div_recalc_rate(struct clk_hw *hw, | ||
178 | unsigned long prate) | ||
179 | { | ||
180 | struct clk_regmap *clk = to_clk_regmap(hw); | ||
181 | struct meson_sclk_div_data *sclk = meson_sclk_div_data(clk); | ||
182 | |||
183 | return DIV_ROUND_UP_ULL((u64)prate, sclk->cached_div); | ||
184 | } | ||
185 | |||
186 | static int sclk_div_enable(struct clk_hw *hw) | ||
187 | { | ||
188 | struct clk_regmap *clk = to_clk_regmap(hw); | ||
189 | struct meson_sclk_div_data *sclk = meson_sclk_div_data(clk); | ||
190 | |||
191 | sclk_apply_divider(clk, sclk); | ||
192 | |||
193 | return 0; | ||
194 | } | ||
195 | |||
196 | static void sclk_div_disable(struct clk_hw *hw) | ||
197 | { | ||
198 | struct clk_regmap *clk = to_clk_regmap(hw); | ||
199 | struct meson_sclk_div_data *sclk = meson_sclk_div_data(clk); | ||
200 | |||
201 | meson_parm_write(clk->map, &sclk->div, 0); | ||
202 | } | ||
203 | |||
204 | static int sclk_div_is_enabled(struct clk_hw *hw) | ||
205 | { | ||
206 | struct clk_regmap *clk = to_clk_regmap(hw); | ||
207 | struct meson_sclk_div_data *sclk = meson_sclk_div_data(clk); | ||
208 | |||
209 | if (meson_parm_read(clk->map, &sclk->div)) | ||
210 | return 1; | ||
211 | |||
212 | return 0; | ||
213 | } | ||
214 | |||
215 | static void sclk_div_init(struct clk_hw *hw) | ||
216 | { | ||
217 | struct clk_regmap *clk = to_clk_regmap(hw); | ||
218 | struct meson_sclk_div_data *sclk = meson_sclk_div_data(clk); | ||
219 | unsigned int val; | ||
220 | |||
221 | val = meson_parm_read(clk->map, &sclk->div); | ||
222 | |||
223 | /* if the divider is initially disabled, assume max */ | ||
224 | if (!val) | ||
225 | sclk->cached_div = sclk_div_maxdiv(sclk); | ||
226 | else | ||
227 | sclk->cached_div = val + 1; | ||
228 | |||
229 | sclk_div_get_duty_cycle(hw, &sclk->cached_duty); | ||
230 | } | ||
231 | |||
232 | const struct clk_ops meson_sclk_div_ops = { | ||
233 | .recalc_rate = sclk_div_recalc_rate, | ||
234 | .round_rate = sclk_div_round_rate, | ||
235 | .set_rate = sclk_div_set_rate, | ||
236 | .enable = sclk_div_enable, | ||
237 | .disable = sclk_div_disable, | ||
238 | .is_enabled = sclk_div_is_enabled, | ||
239 | .get_duty_cycle = sclk_div_get_duty_cycle, | ||
240 | .set_duty_cycle = sclk_div_set_duty_cycle, | ||
241 | .init = sclk_div_init, | ||
242 | }; | ||
243 | EXPORT_SYMBOL_GPL(meson_sclk_div_ops); | ||
diff --git a/drivers/clk/mvebu/armada-37xx-periph.c b/drivers/clk/mvebu/armada-37xx-periph.c index 44e4e27eddad..499f5962c8b0 100644 --- a/drivers/clk/mvebu/armada-37xx-periph.c +++ b/drivers/clk/mvebu/armada-37xx-periph.c | |||
@@ -1,3 +1,4 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0+ | ||
1 | /* | 2 | /* |
2 | * Marvell Armada 37xx SoC Peripheral clocks | 3 | * Marvell Armada 37xx SoC Peripheral clocks |
3 | * | 4 | * |
@@ -5,10 +6,6 @@ | |||
5 | * | 6 | * |
6 | * Gregory CLEMENT <gregory.clement@free-electrons.com> | 7 | * Gregory CLEMENT <gregory.clement@free-electrons.com> |
7 | * | 8 | * |
8 | * This file is licensed under the terms of the GNU General Public | ||
9 | * License version 2 or later. This program is licensed "as is" | ||
10 | * without any warranty of any kind, whether express or implied. | ||
11 | * | ||
12 | * Most of the peripheral clocks can be modelled like this: | 9 | * Most of the peripheral clocks can be modelled like this: |
13 | * _____ _______ _______ | 10 | * _____ _______ _______ |
14 | * TBG-A-P --| | | | | | ______ | 11 | * TBG-A-P --| | | | | | ______ |
@@ -419,7 +416,6 @@ static unsigned int armada_3700_pm_dvfs_get_cpu_parent(struct regmap *base) | |||
419 | static u8 clk_pm_cpu_get_parent(struct clk_hw *hw) | 416 | static u8 clk_pm_cpu_get_parent(struct clk_hw *hw) |
420 | { | 417 | { |
421 | struct clk_pm_cpu *pm_cpu = to_clk_pm_cpu(hw); | 418 | struct clk_pm_cpu *pm_cpu = to_clk_pm_cpu(hw); |
422 | int num_parents = clk_hw_get_num_parents(hw); | ||
423 | u32 val; | 419 | u32 val; |
424 | 420 | ||
425 | if (armada_3700_pm_dvfs_is_enabled(pm_cpu->nb_pm_base)) { | 421 | if (armada_3700_pm_dvfs_is_enabled(pm_cpu->nb_pm_base)) { |
@@ -429,9 +425,6 @@ static u8 clk_pm_cpu_get_parent(struct clk_hw *hw) | |||
429 | val &= pm_cpu->mask_mux; | 425 | val &= pm_cpu->mask_mux; |
430 | } | 426 | } |
431 | 427 | ||
432 | if (val >= num_parents) | ||
433 | return -EINVAL; | ||
434 | |||
435 | return val; | 428 | return val; |
436 | } | 429 | } |
437 | 430 | ||
diff --git a/drivers/clk/pxa/clk-pxa25x.c b/drivers/clk/pxa/clk-pxa25x.c index 6416c1f8e632..e88f8e01fe3a 100644 --- a/drivers/clk/pxa/clk-pxa25x.c +++ b/drivers/clk/pxa/clk-pxa25x.c | |||
@@ -292,8 +292,10 @@ static void __init pxa25x_register_plls(void) | |||
292 | { | 292 | { |
293 | clk_register_fixed_rate(NULL, "osc_3_6864mhz", NULL, | 293 | clk_register_fixed_rate(NULL, "osc_3_6864mhz", NULL, |
294 | CLK_GET_RATE_NOCACHE, 3686400); | 294 | CLK_GET_RATE_NOCACHE, 3686400); |
295 | clk_register_fixed_rate(NULL, "osc_32_768khz", NULL, | 295 | clkdev_pxa_register(CLK_OSC32k768, "osc_32_768khz", NULL, |
296 | CLK_GET_RATE_NOCACHE, 32768); | 296 | clk_register_fixed_rate(NULL, "osc_32_768khz", NULL, |
297 | CLK_GET_RATE_NOCACHE, | ||
298 | 32768)); | ||
297 | clk_register_fixed_rate(NULL, "clk_dummy", NULL, 0, 0); | 299 | clk_register_fixed_rate(NULL, "clk_dummy", NULL, 0, 0); |
298 | clk_register_fixed_factor(NULL, "ppll_95_85mhz", "osc_3_6864mhz", | 300 | clk_register_fixed_factor(NULL, "ppll_95_85mhz", "osc_3_6864mhz", |
299 | 0, 26, 1); | 301 | 0, 26, 1); |
diff --git a/drivers/clk/pxa/clk-pxa27x.c b/drivers/clk/pxa/clk-pxa27x.c index 25a30194d27a..d40b63e7bbce 100644 --- a/drivers/clk/pxa/clk-pxa27x.c +++ b/drivers/clk/pxa/clk-pxa27x.c | |||
@@ -314,9 +314,10 @@ static void __init pxa27x_register_plls(void) | |||
314 | clk_register_fixed_rate(NULL, "osc_13mhz", NULL, | 314 | clk_register_fixed_rate(NULL, "osc_13mhz", NULL, |
315 | CLK_GET_RATE_NOCACHE, | 315 | CLK_GET_RATE_NOCACHE, |
316 | 13 * MHz); | 316 | 13 * MHz); |
317 | clk_register_fixed_rate(NULL, "osc_32_768khz", NULL, | 317 | clkdev_pxa_register(CLK_OSC32k768, "osc_32_768khz", NULL, |
318 | CLK_GET_RATE_NOCACHE, | 318 | clk_register_fixed_rate(NULL, "osc_32_768khz", NULL, |
319 | 32768 * KHz); | 319 | CLK_GET_RATE_NOCACHE, |
320 | 32768 * KHz)); | ||
320 | clk_register_fixed_rate(NULL, "clk_dummy", NULL, 0, 0); | 321 | clk_register_fixed_rate(NULL, "clk_dummy", NULL, 0, 0); |
321 | clk_register_fixed_factor(NULL, "ppll_312mhz", "osc_13mhz", 0, 24, 1); | 322 | clk_register_fixed_factor(NULL, "ppll_312mhz", "osc_13mhz", 0, 24, 1); |
322 | } | 323 | } |
diff --git a/drivers/clk/pxa/clk-pxa3xx.c b/drivers/clk/pxa/clk-pxa3xx.c index 2d126df2bccd..7aa120c3bd08 100644 --- a/drivers/clk/pxa/clk-pxa3xx.c +++ b/drivers/clk/pxa/clk-pxa3xx.c | |||
@@ -286,9 +286,10 @@ static void __init pxa3xx_register_plls(void) | |||
286 | clk_register_fixed_rate(NULL, "osc_13mhz", NULL, | 286 | clk_register_fixed_rate(NULL, "osc_13mhz", NULL, |
287 | CLK_GET_RATE_NOCACHE, | 287 | CLK_GET_RATE_NOCACHE, |
288 | 13 * MHz); | 288 | 13 * MHz); |
289 | clk_register_fixed_rate(NULL, "osc_32_768khz", NULL, | 289 | clkdev_pxa_register(CLK_OSC32k768, "osc_32_768khz", NULL, |
290 | CLK_GET_RATE_NOCACHE, | 290 | clk_register_fixed_rate(NULL, "osc_32_768khz", NULL, |
291 | 32768); | 291 | CLK_GET_RATE_NOCACHE, |
292 | 32768)); | ||
292 | clk_register_fixed_rate(NULL, "ring_osc_120mhz", NULL, | 293 | clk_register_fixed_rate(NULL, "ring_osc_120mhz", NULL, |
293 | CLK_GET_RATE_NOCACHE, | 294 | CLK_GET_RATE_NOCACHE, |
294 | 120 * MHz); | 295 | 120 * MHz); |
diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 9c3480dcc38a..064768699fe7 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig | |||
@@ -59,6 +59,15 @@ config QCOM_CLK_SMD_RPM | |||
59 | Say Y if you want to support the clocks exposed by the RPM on | 59 | Say Y if you want to support the clocks exposed by the RPM on |
60 | platforms such as apq8016, apq8084, msm8974 etc. | 60 | platforms such as apq8016, apq8084, msm8974 etc. |
61 | 61 | ||
62 | config QCOM_CLK_RPMH | ||
63 | tristate "RPMh Clock Driver" | ||
64 | depends on COMMON_CLK_QCOM && QCOM_RPMH | ||
65 | help | ||
66 | RPMh manages shared resources on some Qualcomm Technologies, Inc. | ||
67 | SoCs. It accepts requests from other hardware subsystems via RSC. | ||
68 | Say Y if you want to support the clocks exposed by RPMh on | ||
69 | platforms such as SDM845. | ||
70 | |||
62 | config APQ_GCC_8084 | 71 | config APQ_GCC_8084 |
63 | tristate "APQ8084 Global Clock Controller" | 72 | tristate "APQ8084 Global Clock Controller" |
64 | select QCOM_GDSC | 73 | select QCOM_GDSC |
@@ -245,6 +254,16 @@ config SDM_VIDEOCC_845 | |||
245 | Say Y if you want to support video devices and functionality such as | 254 | Say Y if you want to support video devices and functionality such as |
246 | video encode and decode. | 255 | video encode and decode. |
247 | 256 | ||
257 | config SDM_DISPCC_845 | ||
258 | tristate "SDM845 Display Clock Controller" | ||
259 | select SDM_GCC_845 | ||
260 | depends on COMMON_CLK_QCOM | ||
261 | help | ||
262 | Support for the display clock controller on Qualcomm Technologies, Inc | ||
263 | SDM845 devices. | ||
264 | Say Y if you want to support display devices and functionality such as | ||
265 | splash screen. | ||
266 | |||
248 | config SPMI_PMIC_CLKDIV | 267 | config SPMI_PMIC_CLKDIV |
249 | tristate "SPMI PMIC clkdiv Support" | 268 | tristate "SPMI PMIC clkdiv Support" |
250 | depends on (COMMON_CLK_QCOM && SPMI) || COMPILE_TEST | 269 | depends on (COMMON_CLK_QCOM && SPMI) || COMPILE_TEST |
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 762c01137c2f..21a45035930d 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile | |||
@@ -37,7 +37,9 @@ obj-$(CONFIG_MSM_MMCC_8996) += mmcc-msm8996.o | |||
37 | obj-$(CONFIG_QCOM_A53PLL) += a53-pll.o | 37 | obj-$(CONFIG_QCOM_A53PLL) += a53-pll.o |
38 | obj-$(CONFIG_QCOM_CLK_APCS_MSM8916) += apcs-msm8916.o | 38 | obj-$(CONFIG_QCOM_CLK_APCS_MSM8916) += apcs-msm8916.o |
39 | obj-$(CONFIG_QCOM_CLK_RPM) += clk-rpm.o | 39 | obj-$(CONFIG_QCOM_CLK_RPM) += clk-rpm.o |
40 | obj-$(CONFIG_QCOM_CLK_RPMH) += clk-rpmh.o | ||
40 | obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o | 41 | obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o |
42 | obj-$(CONFIG_SDM_DISPCC_845) += dispcc-sdm845.o | ||
41 | obj-$(CONFIG_SDM_GCC_845) += gcc-sdm845.o | 43 | obj-$(CONFIG_SDM_GCC_845) += gcc-sdm845.o |
42 | obj-$(CONFIG_SDM_VIDEOCC_845) += videocc-sdm845.o | 44 | obj-$(CONFIG_SDM_VIDEOCC_845) += videocc-sdm845.o |
43 | obj-$(CONFIG_SPMI_PMIC_CLKDIV) += clk-spmi-pmic-div.o | 45 | obj-$(CONFIG_SPMI_PMIC_CLKDIV) += clk-spmi-pmic-div.o |
diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c index 3c49a60072f1..a91d97cecbad 100644 --- a/drivers/clk/qcom/clk-alpha-pll.c +++ b/drivers/clk/qcom/clk-alpha-pll.c | |||
@@ -1,14 +1,6 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
1 | /* | 2 | /* |
2 | * Copyright (c) 2015, 2018, The Linux Foundation. All rights reserved. | 3 | * Copyright (c) 2015, 2018, The Linux Foundation. All rights reserved. |
3 | * | ||
4 | * This software is licensed under the terms of the GNU General Public | ||
5 | * License version 2, as published by the Free Software Foundation, and | ||
6 | * may be copied, distributed, and modified under those terms. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | */ | 4 | */ |
13 | 5 | ||
14 | #include <linux/kernel.h> | 6 | #include <linux/kernel.h> |
diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h index f981b486c468..66755f0f84fc 100644 --- a/drivers/clk/qcom/clk-alpha-pll.h +++ b/drivers/clk/qcom/clk-alpha-pll.h | |||
@@ -1,15 +1,5 @@ | |||
1 | /* | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | * Copyright (c) 2015, 2018, The Linux Foundation. All rights reserved. | 2 | /* Copyright (c) 2015, 2018, The Linux Foundation. All rights reserved. */ |
3 | * | ||
4 | * This software is licensed under the terms of the GNU General Public | ||
5 | * License version 2, as published by the Free Software Foundation, and | ||
6 | * may be copied, distributed, and modified under those terms. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | */ | ||
13 | 3 | ||
14 | #ifndef __QCOM_CLK_ALPHA_PLL_H__ | 4 | #ifndef __QCOM_CLK_ALPHA_PLL_H__ |
15 | #define __QCOM_CLK_ALPHA_PLL_H__ | 5 | #define __QCOM_CLK_ALPHA_PLL_H__ |
diff --git a/drivers/clk/qcom/clk-branch.c b/drivers/clk/qcom/clk-branch.c index c58c5538b1b6..bc2205c450b6 100644 --- a/drivers/clk/qcom/clk-branch.c +++ b/drivers/clk/qcom/clk-branch.c | |||
@@ -1,14 +1,6 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
1 | /* | 2 | /* |
2 | * Copyright (c) 2013, The Linux Foundation. All rights reserved. | 3 | * Copyright (c) 2013, The Linux Foundation. All rights reserved. |
3 | * | ||
4 | * This software is licensed under the terms of the GNU General Public | ||
5 | * License version 2, as published by the Free Software Foundation, and | ||
6 | * may be copied, distributed, and modified under those terms. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | */ | 4 | */ |
13 | 5 | ||
14 | #include <linux/kernel.h> | 6 | #include <linux/kernel.h> |
diff --git a/drivers/clk/qcom/clk-branch.h b/drivers/clk/qcom/clk-branch.h index 1702efb1c511..b3561e0a3984 100644 --- a/drivers/clk/qcom/clk-branch.h +++ b/drivers/clk/qcom/clk-branch.h | |||
@@ -1,15 +1,5 @@ | |||
1 | /* | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | * Copyright (c) 2013, The Linux Foundation. All rights reserved. | 2 | /* Copyright (c) 2013, The Linux Foundation. All rights reserved. */ |
3 | * | ||
4 | * This software is licensed under the terms of the GNU General Public | ||
5 | * License version 2, as published by the Free Software Foundation, and | ||
6 | * may be copied, distributed, and modified under those terms. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | */ | ||
13 | 3 | ||
14 | #ifndef __QCOM_CLK_BRANCH_H__ | 4 | #ifndef __QCOM_CLK_BRANCH_H__ |
15 | #define __QCOM_CLK_BRANCH_H__ | 5 | #define __QCOM_CLK_BRANCH_H__ |
diff --git a/drivers/clk/qcom/clk-rcg.h b/drivers/clk/qcom/clk-rcg.h index b209a2fe86b9..dbd5a9e83554 100644 --- a/drivers/clk/qcom/clk-rcg.h +++ b/drivers/clk/qcom/clk-rcg.h | |||
@@ -7,6 +7,8 @@ | |||
7 | #include <linux/clk-provider.h> | 7 | #include <linux/clk-provider.h> |
8 | #include "clk-regmap.h" | 8 | #include "clk-regmap.h" |
9 | 9 | ||
10 | #define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } | ||
11 | |||
10 | struct freq_tbl { | 12 | struct freq_tbl { |
11 | unsigned long freq; | 13 | unsigned long freq; |
12 | u8 src; | 14 | u8 src; |
diff --git a/drivers/clk/qcom/clk-regmap.c b/drivers/clk/qcom/clk-regmap.c index 1c856d330733..ce80db27ccf2 100644 --- a/drivers/clk/qcom/clk-regmap.c +++ b/drivers/clk/qcom/clk-regmap.c | |||
@@ -1,14 +1,6 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
1 | /* | 2 | /* |
2 | * Copyright (c) 2014, The Linux Foundation. All rights reserved. | 3 | * Copyright (c) 2014, The Linux Foundation. All rights reserved. |
3 | * | ||
4 | * This software is licensed under the terms of the GNU General Public | ||
5 | * License version 2, as published by the Free Software Foundation, and | ||
6 | * may be copied, distributed, and modified under those terms. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | */ | 4 | */ |
13 | 5 | ||
14 | #include <linux/device.h> | 6 | #include <linux/device.h> |
diff --git a/drivers/clk/qcom/clk-regmap.h b/drivers/clk/qcom/clk-regmap.h index 90d95cd11ec6..6cfc1bccb255 100644 --- a/drivers/clk/qcom/clk-regmap.h +++ b/drivers/clk/qcom/clk-regmap.h | |||
@@ -1,15 +1,5 @@ | |||
1 | /* | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | * Copyright (c) 2014, The Linux Foundation. All rights reserved. | 2 | /* Copyright (c) 2014, The Linux Foundation. All rights reserved. */ |
3 | * | ||
4 | * This software is licensed under the terms of the GNU General Public | ||
5 | * License version 2, as published by the Free Software Foundation, and | ||
6 | * may be copied, distributed, and modified under those terms. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | */ | ||
13 | 3 | ||
14 | #ifndef __QCOM_CLK_REGMAP_H__ | 4 | #ifndef __QCOM_CLK_REGMAP_H__ |
15 | #define __QCOM_CLK_REGMAP_H__ | 5 | #define __QCOM_CLK_REGMAP_H__ |
diff --git a/drivers/clk/qcom/clk-rpmh.c b/drivers/clk/qcom/clk-rpmh.c new file mode 100644 index 000000000000..9f4fc7773fb2 --- /dev/null +++ b/drivers/clk/qcom/clk-rpmh.c | |||
@@ -0,0 +1,329 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * Copyright (c) 2018, The Linux Foundation. All rights reserved. | ||
4 | */ | ||
5 | |||
6 | #include <linux/clk-provider.h> | ||
7 | #include <linux/err.h> | ||
8 | #include <linux/kernel.h> | ||
9 | #include <linux/module.h> | ||
10 | #include <linux/of.h> | ||
11 | #include <linux/of_device.h> | ||
12 | #include <linux/platform_device.h> | ||
13 | #include <soc/qcom/cmd-db.h> | ||
14 | #include <soc/qcom/rpmh.h> | ||
15 | |||
16 | #include <dt-bindings/clock/qcom,rpmh.h> | ||
17 | |||
18 | #define CLK_RPMH_ARC_EN_OFFSET 0 | ||
19 | #define CLK_RPMH_VRM_EN_OFFSET 4 | ||
20 | |||
21 | /** | ||
22 | * struct clk_rpmh - individual rpmh clock data structure | ||
23 | * @hw: handle between common and hardware-specific interfaces | ||
24 | * @res_name: resource name for the rpmh clock | ||
25 | * @div: clock divider to compute the clock rate | ||
26 | * @res_addr: base address of the rpmh resource within the RPMh | ||
27 | * @res_on_val: rpmh clock enable value | ||
28 | * @state: rpmh clock requested state | ||
29 | * @aggr_state: rpmh clock aggregated state | ||
30 | * @last_sent_aggr_state: rpmh clock last aggr state sent to RPMh | ||
31 | * @valid_state_mask: mask to determine the state of the rpmh clock | ||
32 | * @dev: device to which it is attached | ||
33 | * @peer: pointer to the clock rpmh sibling | ||
34 | */ | ||
35 | struct clk_rpmh { | ||
36 | struct clk_hw hw; | ||
37 | const char *res_name; | ||
38 | u8 div; | ||
39 | u32 res_addr; | ||
40 | u32 res_on_val; | ||
41 | u32 state; | ||
42 | u32 aggr_state; | ||
43 | u32 last_sent_aggr_state; | ||
44 | u32 valid_state_mask; | ||
45 | struct device *dev; | ||
46 | struct clk_rpmh *peer; | ||
47 | }; | ||
48 | |||
49 | struct clk_rpmh_desc { | ||
50 | struct clk_hw **clks; | ||
51 | size_t num_clks; | ||
52 | }; | ||
53 | |||
54 | static DEFINE_MUTEX(rpmh_clk_lock); | ||
55 | |||
56 | #define __DEFINE_CLK_RPMH(_platform, _name, _name_active, _res_name, \ | ||
57 | _res_en_offset, _res_on, _div) \ | ||
58 | static struct clk_rpmh _platform##_##_name_active; \ | ||
59 | static struct clk_rpmh _platform##_##_name = { \ | ||
60 | .res_name = _res_name, \ | ||
61 | .res_addr = _res_en_offset, \ | ||
62 | .res_on_val = _res_on, \ | ||
63 | .div = _div, \ | ||
64 | .peer = &_platform##_##_name_active, \ | ||
65 | .valid_state_mask = (BIT(RPMH_WAKE_ONLY_STATE) | \ | ||
66 | BIT(RPMH_ACTIVE_ONLY_STATE) | \ | ||
67 | BIT(RPMH_SLEEP_STATE)), \ | ||
68 | .hw.init = &(struct clk_init_data){ \ | ||
69 | .ops = &clk_rpmh_ops, \ | ||
70 | .name = #_name, \ | ||
71 | .parent_names = (const char *[]){ "xo_board" }, \ | ||
72 | .num_parents = 1, \ | ||
73 | }, \ | ||
74 | }; \ | ||
75 | static struct clk_rpmh _platform##_##_name_active = { \ | ||
76 | .res_name = _res_name, \ | ||
77 | .res_addr = _res_en_offset, \ | ||
78 | .res_on_val = _res_on, \ | ||
79 | .div = _div, \ | ||
80 | .peer = &_platform##_##_name, \ | ||
81 | .valid_state_mask = (BIT(RPMH_WAKE_ONLY_STATE) | \ | ||
82 | BIT(RPMH_ACTIVE_ONLY_STATE)), \ | ||
83 | .hw.init = &(struct clk_init_data){ \ | ||
84 | .ops = &clk_rpmh_ops, \ | ||
85 | .name = #_name_active, \ | ||
86 | .parent_names = (const char *[]){ "xo_board" }, \ | ||
87 | .num_parents = 1, \ | ||
88 | }, \ | ||
89 | } | ||
90 | |||
91 | #define DEFINE_CLK_RPMH_ARC(_platform, _name, _name_active, _res_name, \ | ||
92 | _res_on, _div) \ | ||
93 | __DEFINE_CLK_RPMH(_platform, _name, _name_active, _res_name, \ | ||
94 | CLK_RPMH_ARC_EN_OFFSET, _res_on, _div) | ||
95 | |||
96 | #define DEFINE_CLK_RPMH_VRM(_platform, _name, _name_active, _res_name, \ | ||
97 | _div) \ | ||
98 | __DEFINE_CLK_RPMH(_platform, _name, _name_active, _res_name, \ | ||
99 | CLK_RPMH_VRM_EN_OFFSET, 1, _div) | ||
100 | |||
101 | static inline struct clk_rpmh *to_clk_rpmh(struct clk_hw *_hw) | ||
102 | { | ||
103 | return container_of(_hw, struct clk_rpmh, hw); | ||
104 | } | ||
105 | |||
106 | static inline bool has_state_changed(struct clk_rpmh *c, u32 state) | ||
107 | { | ||
108 | return (c->last_sent_aggr_state & BIT(state)) | ||
109 | != (c->aggr_state & BIT(state)); | ||
110 | } | ||
111 | |||
112 | static int clk_rpmh_send_aggregate_command(struct clk_rpmh *c) | ||
113 | { | ||
114 | struct tcs_cmd cmd = { 0 }; | ||
115 | u32 cmd_state, on_val; | ||
116 | enum rpmh_state state = RPMH_SLEEP_STATE; | ||
117 | int ret; | ||
118 | |||
119 | cmd.addr = c->res_addr; | ||
120 | cmd_state = c->aggr_state; | ||
121 | on_val = c->res_on_val; | ||
122 | |||
123 | for (; state <= RPMH_ACTIVE_ONLY_STATE; state++) { | ||
124 | if (has_state_changed(c, state)) { | ||
125 | if (cmd_state & BIT(state)) | ||
126 | cmd.data = on_val; | ||
127 | |||
128 | ret = rpmh_write_async(c->dev, state, &cmd, 1); | ||
129 | if (ret) { | ||
130 | dev_err(c->dev, "set %s state of %s failed: (%d)\n", | ||
131 | !state ? "sleep" : | ||
132 | state == RPMH_WAKE_ONLY_STATE ? | ||
133 | "wake" : "active", c->res_name, ret); | ||
134 | return ret; | ||
135 | } | ||
136 | } | ||
137 | } | ||
138 | |||
139 | c->last_sent_aggr_state = c->aggr_state; | ||
140 | c->peer->last_sent_aggr_state = c->last_sent_aggr_state; | ||
141 | |||
142 | return 0; | ||
143 | } | ||
144 | |||
145 | /* | ||
146 | * Update state and aggregate state values based on enable value. | ||
147 | */ | ||
148 | static int clk_rpmh_aggregate_state_send_command(struct clk_rpmh *c, | ||
149 | bool enable) | ||
150 | { | ||
151 | int ret; | ||
152 | |||
153 | /* Nothing required to be done if already off or on */ | ||
154 | if (enable == c->state) | ||
155 | return 0; | ||
156 | |||
157 | c->state = enable ? c->valid_state_mask : 0; | ||
158 | c->aggr_state = c->state | c->peer->state; | ||
159 | c->peer->aggr_state = c->aggr_state; | ||
160 | |||
161 | ret = clk_rpmh_send_aggregate_command(c); | ||
162 | if (!ret) | ||
163 | return 0; | ||
164 | |||
165 | if (ret && enable) | ||
166 | c->state = 0; | ||
167 | else if (ret) | ||
168 | c->state = c->valid_state_mask; | ||
169 | |||
170 | WARN(1, "clk: %s failed to %s\n", c->res_name, | ||
171 | enable ? "enable" : "disable"); | ||
172 | return ret; | ||
173 | } | ||
174 | |||
175 | static int clk_rpmh_prepare(struct clk_hw *hw) | ||
176 | { | ||
177 | struct clk_rpmh *c = to_clk_rpmh(hw); | ||
178 | int ret = 0; | ||
179 | |||
180 | mutex_lock(&rpmh_clk_lock); | ||
181 | ret = clk_rpmh_aggregate_state_send_command(c, true); | ||
182 | mutex_unlock(&rpmh_clk_lock); | ||
183 | |||
184 | return ret; | ||
185 | }; | ||
186 | |||
187 | static void clk_rpmh_unprepare(struct clk_hw *hw) | ||
188 | { | ||
189 | struct clk_rpmh *c = to_clk_rpmh(hw); | ||
190 | |||
191 | mutex_lock(&rpmh_clk_lock); | ||
192 | clk_rpmh_aggregate_state_send_command(c, false); | ||
193 | mutex_unlock(&rpmh_clk_lock); | ||
194 | }; | ||
195 | |||
196 | static unsigned long clk_rpmh_recalc_rate(struct clk_hw *hw, | ||
197 | unsigned long prate) | ||
198 | { | ||
199 | struct clk_rpmh *r = to_clk_rpmh(hw); | ||
200 | |||
201 | /* | ||
202 | * RPMh clocks have a fixed rate. Return static rate. | ||
203 | */ | ||
204 | return prate / r->div; | ||
205 | } | ||
206 | |||
207 | static const struct clk_ops clk_rpmh_ops = { | ||
208 | .prepare = clk_rpmh_prepare, | ||
209 | .unprepare = clk_rpmh_unprepare, | ||
210 | .recalc_rate = clk_rpmh_recalc_rate, | ||
211 | }; | ||
212 | |||
213 | /* Resource name must match resource id present in cmd-db. */ | ||
214 | DEFINE_CLK_RPMH_ARC(sdm845, bi_tcxo, bi_tcxo_ao, "xo.lvl", 0x3, 2); | ||
215 | DEFINE_CLK_RPMH_VRM(sdm845, ln_bb_clk2, ln_bb_clk2_ao, "lnbclka2", 2); | ||
216 | DEFINE_CLK_RPMH_VRM(sdm845, ln_bb_clk3, ln_bb_clk3_ao, "lnbclka3", 2); | ||
217 | DEFINE_CLK_RPMH_VRM(sdm845, rf_clk1, rf_clk1_ao, "rfclka1", 1); | ||
218 | DEFINE_CLK_RPMH_VRM(sdm845, rf_clk2, rf_clk2_ao, "rfclka2", 1); | ||
219 | DEFINE_CLK_RPMH_VRM(sdm845, rf_clk3, rf_clk3_ao, "rfclka3", 1); | ||
220 | |||
221 | static struct clk_hw *sdm845_rpmh_clocks[] = { | ||
222 | [RPMH_CXO_CLK] = &sdm845_bi_tcxo.hw, | ||
223 | [RPMH_CXO_CLK_A] = &sdm845_bi_tcxo_ao.hw, | ||
224 | [RPMH_LN_BB_CLK2] = &sdm845_ln_bb_clk2.hw, | ||
225 | [RPMH_LN_BB_CLK2_A] = &sdm845_ln_bb_clk2_ao.hw, | ||
226 | [RPMH_LN_BB_CLK3] = &sdm845_ln_bb_clk3.hw, | ||
227 | [RPMH_LN_BB_CLK3_A] = &sdm845_ln_bb_clk3_ao.hw, | ||
228 | [RPMH_RF_CLK1] = &sdm845_rf_clk1.hw, | ||
229 | [RPMH_RF_CLK1_A] = &sdm845_rf_clk1_ao.hw, | ||
230 | [RPMH_RF_CLK2] = &sdm845_rf_clk2.hw, | ||
231 | [RPMH_RF_CLK2_A] = &sdm845_rf_clk2_ao.hw, | ||
232 | [RPMH_RF_CLK3] = &sdm845_rf_clk3.hw, | ||
233 | [RPMH_RF_CLK3_A] = &sdm845_rf_clk3_ao.hw, | ||
234 | }; | ||
235 | |||
236 | static const struct clk_rpmh_desc clk_rpmh_sdm845 = { | ||
237 | .clks = sdm845_rpmh_clocks, | ||
238 | .num_clks = ARRAY_SIZE(sdm845_rpmh_clocks), | ||
239 | }; | ||
240 | |||
241 | static struct clk_hw *of_clk_rpmh_hw_get(struct of_phandle_args *clkspec, | ||
242 | void *data) | ||
243 | { | ||
244 | struct clk_rpmh_desc *rpmh = data; | ||
245 | unsigned int idx = clkspec->args[0]; | ||
246 | |||
247 | if (idx >= rpmh->num_clks) { | ||
248 | pr_err("%s: invalid index %u\n", __func__, idx); | ||
249 | return ERR_PTR(-EINVAL); | ||
250 | } | ||
251 | |||
252 | return rpmh->clks[idx]; | ||
253 | } | ||
254 | |||
255 | static int clk_rpmh_probe(struct platform_device *pdev) | ||
256 | { | ||
257 | struct clk_hw **hw_clks; | ||
258 | struct clk_rpmh *rpmh_clk; | ||
259 | const struct clk_rpmh_desc *desc; | ||
260 | int ret, i; | ||
261 | |||
262 | desc = of_device_get_match_data(&pdev->dev); | ||
263 | if (!desc) | ||
264 | return -ENODEV; | ||
265 | |||
266 | hw_clks = desc->clks; | ||
267 | |||
268 | for (i = 0; i < desc->num_clks; i++) { | ||
269 | u32 res_addr; | ||
270 | |||
271 | rpmh_clk = to_clk_rpmh(hw_clks[i]); | ||
272 | res_addr = cmd_db_read_addr(rpmh_clk->res_name); | ||
273 | if (!res_addr) { | ||
274 | dev_err(&pdev->dev, "missing RPMh resource address for %s\n", | ||
275 | rpmh_clk->res_name); | ||
276 | return -ENODEV; | ||
277 | } | ||
278 | rpmh_clk->res_addr += res_addr; | ||
279 | rpmh_clk->dev = &pdev->dev; | ||
280 | |||
281 | ret = devm_clk_hw_register(&pdev->dev, hw_clks[i]); | ||
282 | if (ret) { | ||
283 | dev_err(&pdev->dev, "failed to register %s\n", | ||
284 | hw_clks[i]->init->name); | ||
285 | return ret; | ||
286 | } | ||
287 | } | ||
288 | |||
289 | /* typecast to silence compiler warning */ | ||
290 | ret = devm_of_clk_add_hw_provider(&pdev->dev, of_clk_rpmh_hw_get, | ||
291 | (void *)desc); | ||
292 | if (ret) { | ||
293 | dev_err(&pdev->dev, "Failed to add clock provider\n"); | ||
294 | return ret; | ||
295 | } | ||
296 | |||
297 | dev_dbg(&pdev->dev, "Registered RPMh clocks\n"); | ||
298 | |||
299 | return 0; | ||
300 | } | ||
301 | |||
302 | static const struct of_device_id clk_rpmh_match_table[] = { | ||
303 | { .compatible = "qcom,sdm845-rpmh-clk", .data = &clk_rpmh_sdm845}, | ||
304 | { } | ||
305 | }; | ||
306 | MODULE_DEVICE_TABLE(of, clk_rpmh_match_table); | ||
307 | |||
308 | static struct platform_driver clk_rpmh_driver = { | ||
309 | .probe = clk_rpmh_probe, | ||
310 | .driver = { | ||
311 | .name = "clk-rpmh", | ||
312 | .of_match_table = clk_rpmh_match_table, | ||
313 | }, | ||
314 | }; | ||
315 | |||
316 | static int __init clk_rpmh_init(void) | ||
317 | { | ||
318 | return platform_driver_register(&clk_rpmh_driver); | ||
319 | } | ||
320 | subsys_initcall(clk_rpmh_init); | ||
321 | |||
322 | static void __exit clk_rpmh_exit(void) | ||
323 | { | ||
324 | platform_driver_unregister(&clk_rpmh_driver); | ||
325 | } | ||
326 | module_exit(clk_rpmh_exit); | ||
327 | |||
328 | MODULE_DESCRIPTION("QCOM RPMh Clock Driver"); | ||
329 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/clk/qcom/common.c b/drivers/clk/qcom/common.c index 39ce64c2783b..db9b2471ac40 100644 --- a/drivers/clk/qcom/common.c +++ b/drivers/clk/qcom/common.c | |||
@@ -1,14 +1,6 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
1 | /* | 2 | /* |
2 | * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. | 3 | * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. |
3 | * | ||
4 | * This software is licensed under the terms of the GNU General Public | ||
5 | * License version 2, as published by the Free Software Foundation, and | ||
6 | * may be copied, distributed, and modified under those terms. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | */ | 4 | */ |
13 | 5 | ||
14 | #include <linux/export.h> | 6 | #include <linux/export.h> |
diff --git a/drivers/clk/qcom/common.h b/drivers/clk/qcom/common.h index 00196ee15e73..4aa33ee70bae 100644 --- a/drivers/clk/qcom/common.h +++ b/drivers/clk/qcom/common.h | |||
@@ -1,15 +1,6 @@ | |||
1 | /* | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | * Copyright (c) 2014, The Linux Foundation. All rights reserved. | 2 | /* Copyright (c) 2014, The Linux Foundation. All rights reserved. */ |
3 | * | 3 | |
4 | * This software is licensed under the terms of the GNU General Public | ||
5 | * License version 2, as published by the Free Software Foundation, and | ||
6 | * may be copied, distributed, and modified under those terms. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | */ | ||
13 | #ifndef __QCOM_CLK_COMMON_H__ | 4 | #ifndef __QCOM_CLK_COMMON_H__ |
14 | #define __QCOM_CLK_COMMON_H__ | 5 | #define __QCOM_CLK_COMMON_H__ |
15 | 6 | ||
diff --git a/drivers/clk/qcom/dispcc-sdm845.c b/drivers/clk/qcom/dispcc-sdm845.c new file mode 100644 index 000000000000..0cc4909b5dbe --- /dev/null +++ b/drivers/clk/qcom/dispcc-sdm845.c | |||
@@ -0,0 +1,685 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * Copyright (c) 2018, The Linux Foundation. All rights reserved. | ||
4 | */ | ||
5 | |||
6 | #include <linux/clk-provider.h> | ||
7 | #include <linux/module.h> | ||
8 | #include <linux/platform_device.h> | ||
9 | #include <linux/regmap.h> | ||
10 | #include <linux/reset-controller.h> | ||
11 | |||
12 | #include <dt-bindings/clock/qcom,dispcc-sdm845.h> | ||
13 | |||
14 | #include "clk-alpha-pll.h" | ||
15 | #include "clk-branch.h" | ||
16 | #include "clk-rcg.h" | ||
17 | #include "clk-regmap-divider.h" | ||
18 | #include "common.h" | ||
19 | #include "gdsc.h" | ||
20 | #include "reset.h" | ||
21 | |||
22 | enum { | ||
23 | P_BI_TCXO, | ||
24 | P_CORE_BI_PLL_TEST_SE, | ||
25 | P_DISP_CC_PLL0_OUT_MAIN, | ||
26 | P_DSI0_PHY_PLL_OUT_BYTECLK, | ||
27 | P_DSI0_PHY_PLL_OUT_DSICLK, | ||
28 | P_DSI1_PHY_PLL_OUT_BYTECLK, | ||
29 | P_DSI1_PHY_PLL_OUT_DSICLK, | ||
30 | P_GPLL0_OUT_MAIN, | ||
31 | P_GPLL0_OUT_MAIN_DIV, | ||
32 | }; | ||
33 | |||
34 | static const struct parent_map disp_cc_parent_map_0[] = { | ||
35 | { P_BI_TCXO, 0 }, | ||
36 | { P_DSI0_PHY_PLL_OUT_BYTECLK, 1 }, | ||
37 | { P_DSI1_PHY_PLL_OUT_BYTECLK, 2 }, | ||
38 | { P_CORE_BI_PLL_TEST_SE, 7 }, | ||
39 | }; | ||
40 | |||
41 | static const char * const disp_cc_parent_names_0[] = { | ||
42 | "bi_tcxo", | ||
43 | "dsi0_phy_pll_out_byteclk", | ||
44 | "dsi1_phy_pll_out_byteclk", | ||
45 | "core_bi_pll_test_se", | ||
46 | }; | ||
47 | |||
48 | static const struct parent_map disp_cc_parent_map_2[] = { | ||
49 | { P_BI_TCXO, 0 }, | ||
50 | { P_CORE_BI_PLL_TEST_SE, 7 }, | ||
51 | }; | ||
52 | |||
53 | static const char * const disp_cc_parent_names_2[] = { | ||
54 | "bi_tcxo", | ||
55 | "core_bi_pll_test_se", | ||
56 | }; | ||
57 | |||
58 | static const struct parent_map disp_cc_parent_map_3[] = { | ||
59 | { P_BI_TCXO, 0 }, | ||
60 | { P_DISP_CC_PLL0_OUT_MAIN, 1 }, | ||
61 | { P_GPLL0_OUT_MAIN, 4 }, | ||
62 | { P_GPLL0_OUT_MAIN_DIV, 5 }, | ||
63 | { P_CORE_BI_PLL_TEST_SE, 7 }, | ||
64 | }; | ||
65 | |||
66 | static const char * const disp_cc_parent_names_3[] = { | ||
67 | "bi_tcxo", | ||
68 | "disp_cc_pll0", | ||
69 | "gcc_disp_gpll0_clk_src", | ||
70 | "gcc_disp_gpll0_div_clk_src", | ||
71 | "core_bi_pll_test_se", | ||
72 | }; | ||
73 | |||
74 | static const struct parent_map disp_cc_parent_map_4[] = { | ||
75 | { P_BI_TCXO, 0 }, | ||
76 | { P_DSI0_PHY_PLL_OUT_DSICLK, 1 }, | ||
77 | { P_DSI1_PHY_PLL_OUT_DSICLK, 2 }, | ||
78 | { P_CORE_BI_PLL_TEST_SE, 7 }, | ||
79 | }; | ||
80 | |||
81 | static const char * const disp_cc_parent_names_4[] = { | ||
82 | "bi_tcxo", | ||
83 | "dsi0_phy_pll_out_dsiclk", | ||
84 | "dsi1_phy_pll_out_dsiclk", | ||
85 | "core_bi_pll_test_se", | ||
86 | }; | ||
87 | |||
88 | static struct clk_alpha_pll disp_cc_pll0 = { | ||
89 | .offset = 0x0, | ||
90 | .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], | ||
91 | .clkr = { | ||
92 | .hw.init = &(struct clk_init_data){ | ||
93 | .name = "disp_cc_pll0", | ||
94 | .parent_names = (const char *[]){ "bi_tcxo" }, | ||
95 | .num_parents = 1, | ||
96 | .ops = &clk_alpha_pll_fabia_ops, | ||
97 | }, | ||
98 | }, | ||
99 | }; | ||
100 | |||
101 | /* Return the HW recalc rate for idle use case */ | ||
102 | static struct clk_rcg2 disp_cc_mdss_byte0_clk_src = { | ||
103 | .cmd_rcgr = 0x20d0, | ||
104 | .mnd_width = 0, | ||
105 | .hid_width = 5, | ||
106 | .parent_map = disp_cc_parent_map_0, | ||
107 | .clkr.hw.init = &(struct clk_init_data){ | ||
108 | .name = "disp_cc_mdss_byte0_clk_src", | ||
109 | .parent_names = disp_cc_parent_names_0, | ||
110 | .num_parents = 4, | ||
111 | .flags = CLK_SET_RATE_PARENT, | ||
112 | .ops = &clk_byte2_ops, | ||
113 | }, | ||
114 | }; | ||
115 | |||
116 | /* Return the HW recalc rate for idle use case */ | ||
117 | static struct clk_rcg2 disp_cc_mdss_byte1_clk_src = { | ||
118 | .cmd_rcgr = 0x20ec, | ||
119 | .mnd_width = 0, | ||
120 | .hid_width = 5, | ||
121 | .parent_map = disp_cc_parent_map_0, | ||
122 | .clkr.hw.init = &(struct clk_init_data){ | ||
123 | .name = "disp_cc_mdss_byte1_clk_src", | ||
124 | .parent_names = disp_cc_parent_names_0, | ||
125 | .num_parents = 4, | ||
126 | .flags = CLK_SET_RATE_PARENT, | ||
127 | .ops = &clk_byte2_ops, | ||
128 | }, | ||
129 | }; | ||
130 | |||
131 | static const struct freq_tbl ftbl_disp_cc_mdss_esc0_clk_src[] = { | ||
132 | F(19200000, P_BI_TCXO, 1, 0, 0), | ||
133 | { } | ||
134 | }; | ||
135 | |||
136 | static struct clk_rcg2 disp_cc_mdss_esc0_clk_src = { | ||
137 | .cmd_rcgr = 0x2108, | ||
138 | .mnd_width = 0, | ||
139 | .hid_width = 5, | ||
140 | .parent_map = disp_cc_parent_map_0, | ||
141 | .freq_tbl = ftbl_disp_cc_mdss_esc0_clk_src, | ||
142 | .clkr.hw.init = &(struct clk_init_data){ | ||
143 | .name = "disp_cc_mdss_esc0_clk_src", | ||
144 | .parent_names = disp_cc_parent_names_0, | ||
145 | .num_parents = 4, | ||
146 | .ops = &clk_rcg2_ops, | ||
147 | }, | ||
148 | }; | ||
149 | |||
150 | static struct clk_rcg2 disp_cc_mdss_esc1_clk_src = { | ||
151 | .cmd_rcgr = 0x2120, | ||
152 | .mnd_width = 0, | ||
153 | .hid_width = 5, | ||
154 | .parent_map = disp_cc_parent_map_0, | ||
155 | .freq_tbl = ftbl_disp_cc_mdss_esc0_clk_src, | ||
156 | .clkr.hw.init = &(struct clk_init_data){ | ||
157 | .name = "disp_cc_mdss_esc1_clk_src", | ||
158 | .parent_names = disp_cc_parent_names_0, | ||
159 | .num_parents = 4, | ||
160 | .ops = &clk_rcg2_ops, | ||
161 | }, | ||
162 | }; | ||
163 | |||
164 | static const struct freq_tbl ftbl_disp_cc_mdss_mdp_clk_src[] = { | ||
165 | F(19200000, P_BI_TCXO, 1, 0, 0), | ||
166 | F(85714286, P_GPLL0_OUT_MAIN, 7, 0, 0), | ||
167 | F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0), | ||
168 | F(150000000, P_GPLL0_OUT_MAIN, 4, 0, 0), | ||
169 | F(171428571, P_GPLL0_OUT_MAIN, 3.5, 0, 0), | ||
170 | F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0), | ||
171 | F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0), | ||
172 | F(344000000, P_DISP_CC_PLL0_OUT_MAIN, 2.5, 0, 0), | ||
173 | F(430000000, P_DISP_CC_PLL0_OUT_MAIN, 2, 0, 0), | ||
174 | { } | ||
175 | }; | ||
176 | |||
177 | static struct clk_rcg2 disp_cc_mdss_mdp_clk_src = { | ||
178 | .cmd_rcgr = 0x2088, | ||
179 | .mnd_width = 0, | ||
180 | .hid_width = 5, | ||
181 | .parent_map = disp_cc_parent_map_3, | ||
182 | .freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src, | ||
183 | .clkr.hw.init = &(struct clk_init_data){ | ||
184 | .name = "disp_cc_mdss_mdp_clk_src", | ||
185 | .parent_names = disp_cc_parent_names_3, | ||
186 | .num_parents = 5, | ||
187 | .ops = &clk_rcg2_shared_ops, | ||
188 | }, | ||
189 | }; | ||
190 | |||
191 | /* Return the HW recalc rate for idle use case */ | ||
192 | static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = { | ||
193 | .cmd_rcgr = 0x2058, | ||
194 | .mnd_width = 8, | ||
195 | .hid_width = 5, | ||
196 | .parent_map = disp_cc_parent_map_4, | ||
197 | .clkr.hw.init = &(struct clk_init_data){ | ||
198 | .name = "disp_cc_mdss_pclk0_clk_src", | ||
199 | .parent_names = disp_cc_parent_names_4, | ||
200 | .num_parents = 4, | ||
201 | .flags = CLK_SET_RATE_PARENT, | ||
202 | .ops = &clk_pixel_ops, | ||
203 | }, | ||
204 | }; | ||
205 | |||
206 | /* Return the HW recalc rate for idle use case */ | ||
207 | static struct clk_rcg2 disp_cc_mdss_pclk1_clk_src = { | ||
208 | .cmd_rcgr = 0x2070, | ||
209 | .mnd_width = 8, | ||
210 | .hid_width = 5, | ||
211 | .parent_map = disp_cc_parent_map_4, | ||
212 | .clkr.hw.init = &(struct clk_init_data){ | ||
213 | .name = "disp_cc_mdss_pclk1_clk_src", | ||
214 | .parent_names = disp_cc_parent_names_4, | ||
215 | .num_parents = 4, | ||
216 | .flags = CLK_SET_RATE_PARENT, | ||
217 | .ops = &clk_pixel_ops, | ||
218 | }, | ||
219 | }; | ||
220 | |||
221 | static const struct freq_tbl ftbl_disp_cc_mdss_rot_clk_src[] = { | ||
222 | F(19200000, P_BI_TCXO, 1, 0, 0), | ||
223 | F(171428571, P_GPLL0_OUT_MAIN, 3.5, 0, 0), | ||
224 | F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0), | ||
225 | F(344000000, P_DISP_CC_PLL0_OUT_MAIN, 2.5, 0, 0), | ||
226 | F(430000000, P_DISP_CC_PLL0_OUT_MAIN, 2, 0, 0), | ||
227 | { } | ||
228 | }; | ||
229 | |||
230 | static struct clk_rcg2 disp_cc_mdss_rot_clk_src = { | ||
231 | .cmd_rcgr = 0x20a0, | ||
232 | .mnd_width = 0, | ||
233 | .hid_width = 5, | ||
234 | .parent_map = disp_cc_parent_map_3, | ||
235 | .freq_tbl = ftbl_disp_cc_mdss_rot_clk_src, | ||
236 | .clkr.hw.init = &(struct clk_init_data){ | ||
237 | .name = "disp_cc_mdss_rot_clk_src", | ||
238 | .parent_names = disp_cc_parent_names_3, | ||
239 | .num_parents = 5, | ||
240 | .ops = &clk_rcg2_shared_ops, | ||
241 | }, | ||
242 | }; | ||
243 | |||
244 | static struct clk_rcg2 disp_cc_mdss_vsync_clk_src = { | ||
245 | .cmd_rcgr = 0x20b8, | ||
246 | .mnd_width = 0, | ||
247 | .hid_width = 5, | ||
248 | .parent_map = disp_cc_parent_map_2, | ||
249 | .freq_tbl = ftbl_disp_cc_mdss_esc0_clk_src, | ||
250 | .clkr.hw.init = &(struct clk_init_data){ | ||
251 | .name = "disp_cc_mdss_vsync_clk_src", | ||
252 | .parent_names = disp_cc_parent_names_2, | ||
253 | .num_parents = 2, | ||
254 | .ops = &clk_rcg2_ops, | ||
255 | }, | ||
256 | }; | ||
257 | |||
258 | static struct clk_branch disp_cc_mdss_ahb_clk = { | ||
259 | .halt_reg = 0x4004, | ||
260 | .halt_check = BRANCH_HALT, | ||
261 | .clkr = { | ||
262 | .enable_reg = 0x4004, | ||
263 | .enable_mask = BIT(0), | ||
264 | .hw.init = &(struct clk_init_data){ | ||
265 | .name = "disp_cc_mdss_ahb_clk", | ||
266 | .ops = &clk_branch2_ops, | ||
267 | }, | ||
268 | }, | ||
269 | }; | ||
270 | |||
271 | static struct clk_branch disp_cc_mdss_axi_clk = { | ||
272 | .halt_reg = 0x4008, | ||
273 | .halt_check = BRANCH_HALT, | ||
274 | .clkr = { | ||
275 | .enable_reg = 0x4008, | ||
276 | .enable_mask = BIT(0), | ||
277 | .hw.init = &(struct clk_init_data){ | ||
278 | .name = "disp_cc_mdss_axi_clk", | ||
279 | .ops = &clk_branch2_ops, | ||
280 | }, | ||
281 | }, | ||
282 | }; | ||
283 | |||
284 | /* Return the HW recalc rate for idle use case */ | ||
285 | static struct clk_branch disp_cc_mdss_byte0_clk = { | ||
286 | .halt_reg = 0x2028, | ||
287 | .halt_check = BRANCH_HALT, | ||
288 | .clkr = { | ||
289 | .enable_reg = 0x2028, | ||
290 | .enable_mask = BIT(0), | ||
291 | .hw.init = &(struct clk_init_data){ | ||
292 | .name = "disp_cc_mdss_byte0_clk", | ||
293 | .parent_names = (const char *[]){ | ||
294 | "disp_cc_mdss_byte0_clk_src", | ||
295 | }, | ||
296 | .num_parents = 1, | ||
297 | .flags = CLK_SET_RATE_PARENT, | ||
298 | .ops = &clk_branch2_ops, | ||
299 | }, | ||
300 | }, | ||
301 | }; | ||
302 | |||
303 | /* Return the HW recalc rate for idle use case */ | ||
304 | static struct clk_regmap_div disp_cc_mdss_byte0_div_clk_src = { | ||
305 | .reg = 0x20e8, | ||
306 | .shift = 0, | ||
307 | .width = 2, | ||
308 | .clkr = { | ||
309 | .hw.init = &(struct clk_init_data){ | ||
310 | .name = "disp_cc_mdss_byte0_div_clk_src", | ||
311 | .parent_names = (const char *[]){ | ||
312 | "disp_cc_mdss_byte0_clk_src", | ||
313 | }, | ||
314 | .num_parents = 1, | ||
315 | .ops = &clk_regmap_div_ops, | ||
316 | }, | ||
317 | }, | ||
318 | }; | ||
319 | |||
320 | /* Return the HW recalc rate for idle use case */ | ||
321 | static struct clk_branch disp_cc_mdss_byte0_intf_clk = { | ||
322 | .halt_reg = 0x202c, | ||
323 | .halt_check = BRANCH_HALT, | ||
324 | .clkr = { | ||
325 | .enable_reg = 0x202c, | ||
326 | .enable_mask = BIT(0), | ||
327 | .hw.init = &(struct clk_init_data){ | ||
328 | .name = "disp_cc_mdss_byte0_intf_clk", | ||
329 | .parent_names = (const char *[]){ | ||
330 | "disp_cc_mdss_byte0_div_clk_src", | ||
331 | }, | ||
332 | .num_parents = 1, | ||
333 | .flags = CLK_SET_RATE_PARENT, | ||
334 | .ops = &clk_branch2_ops, | ||
335 | }, | ||
336 | }, | ||
337 | }; | ||
338 | |||
339 | /* Return the HW recalc rate for idle use case */ | ||
340 | static struct clk_branch disp_cc_mdss_byte1_clk = { | ||
341 | .halt_reg = 0x2030, | ||
342 | .halt_check = BRANCH_HALT, | ||
343 | .clkr = { | ||
344 | .enable_reg = 0x2030, | ||
345 | .enable_mask = BIT(0), | ||
346 | .hw.init = &(struct clk_init_data){ | ||
347 | .name = "disp_cc_mdss_byte1_clk", | ||
348 | .parent_names = (const char *[]){ | ||
349 | "disp_cc_mdss_byte1_clk_src", | ||
350 | }, | ||
351 | .num_parents = 1, | ||
352 | .flags = CLK_SET_RATE_PARENT, | ||
353 | .ops = &clk_branch2_ops, | ||
354 | }, | ||
355 | }, | ||
356 | }; | ||
357 | |||
358 | /* Return the HW recalc rate for idle use case */ | ||
359 | static struct clk_regmap_div disp_cc_mdss_byte1_div_clk_src = { | ||
360 | .reg = 0x2104, | ||
361 | .shift = 0, | ||
362 | .width = 2, | ||
363 | .clkr = { | ||
364 | .hw.init = &(struct clk_init_data){ | ||
365 | .name = "disp_cc_mdss_byte1_div_clk_src", | ||
366 | .parent_names = (const char *[]){ | ||
367 | "disp_cc_mdss_byte1_clk_src", | ||
368 | }, | ||
369 | .num_parents = 1, | ||
370 | .ops = &clk_regmap_div_ops, | ||
371 | }, | ||
372 | }, | ||
373 | }; | ||
374 | |||
375 | /* Return the HW recalc rate for idle use case */ | ||
376 | static struct clk_branch disp_cc_mdss_byte1_intf_clk = { | ||
377 | .halt_reg = 0x2034, | ||
378 | .halt_check = BRANCH_HALT, | ||
379 | .clkr = { | ||
380 | .enable_reg = 0x2034, | ||
381 | .enable_mask = BIT(0), | ||
382 | .hw.init = &(struct clk_init_data){ | ||
383 | .name = "disp_cc_mdss_byte1_intf_clk", | ||
384 | .parent_names = (const char *[]){ | ||
385 | "disp_cc_mdss_byte1_div_clk_src", | ||
386 | }, | ||
387 | .num_parents = 1, | ||
388 | .flags = CLK_SET_RATE_PARENT, | ||
389 | .ops = &clk_branch2_ops, | ||
390 | }, | ||
391 | }, | ||
392 | }; | ||
393 | |||
394 | static struct clk_branch disp_cc_mdss_esc0_clk = { | ||
395 | .halt_reg = 0x2038, | ||
396 | .halt_check = BRANCH_HALT, | ||
397 | .clkr = { | ||
398 | .enable_reg = 0x2038, | ||
399 | .enable_mask = BIT(0), | ||
400 | .hw.init = &(struct clk_init_data){ | ||
401 | .name = "disp_cc_mdss_esc0_clk", | ||
402 | .parent_names = (const char *[]){ | ||
403 | "disp_cc_mdss_esc0_clk_src", | ||
404 | }, | ||
405 | .num_parents = 1, | ||
406 | .flags = CLK_SET_RATE_PARENT, | ||
407 | .ops = &clk_branch2_ops, | ||
408 | }, | ||
409 | }, | ||
410 | }; | ||
411 | |||
412 | static struct clk_branch disp_cc_mdss_esc1_clk = { | ||
413 | .halt_reg = 0x203c, | ||
414 | .halt_check = BRANCH_HALT, | ||
415 | .clkr = { | ||
416 | .enable_reg = 0x203c, | ||
417 | .enable_mask = BIT(0), | ||
418 | .hw.init = &(struct clk_init_data){ | ||
419 | .name = "disp_cc_mdss_esc1_clk", | ||
420 | .parent_names = (const char *[]){ | ||
421 | "disp_cc_mdss_esc1_clk_src", | ||
422 | }, | ||
423 | .num_parents = 1, | ||
424 | .flags = CLK_SET_RATE_PARENT, | ||
425 | .ops = &clk_branch2_ops, | ||
426 | }, | ||
427 | }, | ||
428 | }; | ||
429 | |||
430 | static struct clk_branch disp_cc_mdss_mdp_clk = { | ||
431 | .halt_reg = 0x200c, | ||
432 | .halt_check = BRANCH_HALT, | ||
433 | .clkr = { | ||
434 | .enable_reg = 0x200c, | ||
435 | .enable_mask = BIT(0), | ||
436 | .hw.init = &(struct clk_init_data){ | ||
437 | .name = "disp_cc_mdss_mdp_clk", | ||
438 | .parent_names = (const char *[]){ | ||
439 | "disp_cc_mdss_mdp_clk_src", | ||
440 | }, | ||
441 | .num_parents = 1, | ||
442 | .flags = CLK_SET_RATE_PARENT, | ||
443 | .ops = &clk_branch2_ops, | ||
444 | }, | ||
445 | }, | ||
446 | }; | ||
447 | |||
448 | static struct clk_branch disp_cc_mdss_mdp_lut_clk = { | ||
449 | .halt_reg = 0x201c, | ||
450 | .halt_check = BRANCH_HALT, | ||
451 | .clkr = { | ||
452 | .enable_reg = 0x201c, | ||
453 | .enable_mask = BIT(0), | ||
454 | .hw.init = &(struct clk_init_data){ | ||
455 | .name = "disp_cc_mdss_mdp_lut_clk", | ||
456 | .parent_names = (const char *[]){ | ||
457 | "disp_cc_mdss_mdp_clk_src", | ||
458 | }, | ||
459 | .num_parents = 1, | ||
460 | .ops = &clk_branch2_ops, | ||
461 | }, | ||
462 | }, | ||
463 | }; | ||
464 | |||
465 | /* Return the HW recalc rate for idle use case */ | ||
466 | static struct clk_branch disp_cc_mdss_pclk0_clk = { | ||
467 | .halt_reg = 0x2004, | ||
468 | .halt_check = BRANCH_HALT, | ||
469 | .clkr = { | ||
470 | .enable_reg = 0x2004, | ||
471 | .enable_mask = BIT(0), | ||
472 | .hw.init = &(struct clk_init_data){ | ||
473 | .name = "disp_cc_mdss_pclk0_clk", | ||
474 | .parent_names = (const char *[]){ | ||
475 | "disp_cc_mdss_pclk0_clk_src", | ||
476 | }, | ||
477 | .num_parents = 1, | ||
478 | .flags = CLK_SET_RATE_PARENT, | ||
479 | .ops = &clk_branch2_ops, | ||
480 | }, | ||
481 | }, | ||
482 | }; | ||
483 | |||
484 | /* Return the HW recalc rate for idle use case */ | ||
485 | static struct clk_branch disp_cc_mdss_pclk1_clk = { | ||
486 | .halt_reg = 0x2008, | ||
487 | .halt_check = BRANCH_HALT, | ||
488 | .clkr = { | ||
489 | .enable_reg = 0x2008, | ||
490 | .enable_mask = BIT(0), | ||
491 | .hw.init = &(struct clk_init_data){ | ||
492 | .name = "disp_cc_mdss_pclk1_clk", | ||
493 | .parent_names = (const char *[]){ | ||
494 | "disp_cc_mdss_pclk1_clk_src", | ||
495 | }, | ||
496 | .num_parents = 1, | ||
497 | .flags = CLK_SET_RATE_PARENT, | ||
498 | .ops = &clk_branch2_ops, | ||
499 | }, | ||
500 | }, | ||
501 | }; | ||
502 | |||
503 | static struct clk_branch disp_cc_mdss_rot_clk = { | ||
504 | .halt_reg = 0x2014, | ||
505 | .halt_check = BRANCH_HALT, | ||
506 | .clkr = { | ||
507 | .enable_reg = 0x2014, | ||
508 | .enable_mask = BIT(0), | ||
509 | .hw.init = &(struct clk_init_data){ | ||
510 | .name = "disp_cc_mdss_rot_clk", | ||
511 | .parent_names = (const char *[]){ | ||
512 | "disp_cc_mdss_rot_clk_src", | ||
513 | }, | ||
514 | .num_parents = 1, | ||
515 | .flags = CLK_SET_RATE_PARENT, | ||
516 | .ops = &clk_branch2_ops, | ||
517 | }, | ||
518 | }, | ||
519 | }; | ||
520 | |||
521 | static struct clk_branch disp_cc_mdss_rscc_ahb_clk = { | ||
522 | .halt_reg = 0x5004, | ||
523 | .halt_check = BRANCH_HALT, | ||
524 | .clkr = { | ||
525 | .enable_reg = 0x5004, | ||
526 | .enable_mask = BIT(0), | ||
527 | .hw.init = &(struct clk_init_data){ | ||
528 | .name = "disp_cc_mdss_rscc_ahb_clk", | ||
529 | .ops = &clk_branch2_ops, | ||
530 | }, | ||
531 | }, | ||
532 | }; | ||
533 | |||
534 | static struct clk_branch disp_cc_mdss_rscc_vsync_clk = { | ||
535 | .halt_reg = 0x5008, | ||
536 | .halt_check = BRANCH_HALT, | ||
537 | .clkr = { | ||
538 | .enable_reg = 0x5008, | ||
539 | .enable_mask = BIT(0), | ||
540 | .hw.init = &(struct clk_init_data){ | ||
541 | .name = "disp_cc_mdss_rscc_vsync_clk", | ||
542 | .parent_names = (const char *[]){ | ||
543 | "disp_cc_mdss_vsync_clk_src", | ||
544 | }, | ||
545 | .num_parents = 1, | ||
546 | .flags = CLK_SET_RATE_PARENT, | ||
547 | .ops = &clk_branch2_ops, | ||
548 | }, | ||
549 | }, | ||
550 | }; | ||
551 | |||
552 | static struct clk_branch disp_cc_mdss_vsync_clk = { | ||
553 | .halt_reg = 0x2024, | ||
554 | .halt_check = BRANCH_HALT, | ||
555 | .clkr = { | ||
556 | .enable_reg = 0x2024, | ||
557 | .enable_mask = BIT(0), | ||
558 | .hw.init = &(struct clk_init_data){ | ||
559 | .name = "disp_cc_mdss_vsync_clk", | ||
560 | .parent_names = (const char *[]){ | ||
561 | "disp_cc_mdss_vsync_clk_src", | ||
562 | }, | ||
563 | .num_parents = 1, | ||
564 | .flags = CLK_SET_RATE_PARENT, | ||
565 | .ops = &clk_branch2_ops, | ||
566 | }, | ||
567 | }, | ||
568 | }; | ||
569 | |||
570 | static struct gdsc mdss_gdsc = { | ||
571 | .gdscr = 0x3000, | ||
572 | .pd = { | ||
573 | .name = "mdss_gdsc", | ||
574 | }, | ||
575 | .pwrsts = PWRSTS_OFF_ON, | ||
576 | .flags = HW_CTRL | POLL_CFG_GDSCR, | ||
577 | }; | ||
578 | |||
579 | static struct clk_regmap *disp_cc_sdm845_clocks[] = { | ||
580 | [DISP_CC_MDSS_AHB_CLK] = &disp_cc_mdss_ahb_clk.clkr, | ||
581 | [DISP_CC_MDSS_AXI_CLK] = &disp_cc_mdss_axi_clk.clkr, | ||
582 | [DISP_CC_MDSS_BYTE0_CLK] = &disp_cc_mdss_byte0_clk.clkr, | ||
583 | [DISP_CC_MDSS_BYTE0_CLK_SRC] = &disp_cc_mdss_byte0_clk_src.clkr, | ||
584 | [DISP_CC_MDSS_BYTE0_INTF_CLK] = &disp_cc_mdss_byte0_intf_clk.clkr, | ||
585 | [DISP_CC_MDSS_BYTE0_DIV_CLK_SRC] = | ||
586 | &disp_cc_mdss_byte0_div_clk_src.clkr, | ||
587 | [DISP_CC_MDSS_BYTE1_CLK] = &disp_cc_mdss_byte1_clk.clkr, | ||
588 | [DISP_CC_MDSS_BYTE1_CLK_SRC] = &disp_cc_mdss_byte1_clk_src.clkr, | ||
589 | [DISP_CC_MDSS_BYTE1_INTF_CLK] = &disp_cc_mdss_byte1_intf_clk.clkr, | ||
590 | [DISP_CC_MDSS_BYTE1_DIV_CLK_SRC] = | ||
591 | &disp_cc_mdss_byte1_div_clk_src.clkr, | ||
592 | [DISP_CC_MDSS_ESC0_CLK] = &disp_cc_mdss_esc0_clk.clkr, | ||
593 | [DISP_CC_MDSS_ESC0_CLK_SRC] = &disp_cc_mdss_esc0_clk_src.clkr, | ||
594 | [DISP_CC_MDSS_ESC1_CLK] = &disp_cc_mdss_esc1_clk.clkr, | ||
595 | [DISP_CC_MDSS_ESC1_CLK_SRC] = &disp_cc_mdss_esc1_clk_src.clkr, | ||
596 | [DISP_CC_MDSS_MDP_CLK] = &disp_cc_mdss_mdp_clk.clkr, | ||
597 | [DISP_CC_MDSS_MDP_CLK_SRC] = &disp_cc_mdss_mdp_clk_src.clkr, | ||
598 | [DISP_CC_MDSS_MDP_LUT_CLK] = &disp_cc_mdss_mdp_lut_clk.clkr, | ||
599 | [DISP_CC_MDSS_PCLK0_CLK] = &disp_cc_mdss_pclk0_clk.clkr, | ||
600 | [DISP_CC_MDSS_PCLK0_CLK_SRC] = &disp_cc_mdss_pclk0_clk_src.clkr, | ||
601 | [DISP_CC_MDSS_PCLK1_CLK] = &disp_cc_mdss_pclk1_clk.clkr, | ||
602 | [DISP_CC_MDSS_PCLK1_CLK_SRC] = &disp_cc_mdss_pclk1_clk_src.clkr, | ||
603 | [DISP_CC_MDSS_ROT_CLK] = &disp_cc_mdss_rot_clk.clkr, | ||
604 | [DISP_CC_MDSS_ROT_CLK_SRC] = &disp_cc_mdss_rot_clk_src.clkr, | ||
605 | [DISP_CC_MDSS_RSCC_AHB_CLK] = &disp_cc_mdss_rscc_ahb_clk.clkr, | ||
606 | [DISP_CC_MDSS_RSCC_VSYNC_CLK] = &disp_cc_mdss_rscc_vsync_clk.clkr, | ||
607 | [DISP_CC_MDSS_VSYNC_CLK] = &disp_cc_mdss_vsync_clk.clkr, | ||
608 | [DISP_CC_MDSS_VSYNC_CLK_SRC] = &disp_cc_mdss_vsync_clk_src.clkr, | ||
609 | [DISP_CC_PLL0] = &disp_cc_pll0.clkr, | ||
610 | }; | ||
611 | |||
612 | static const struct qcom_reset_map disp_cc_sdm845_resets[] = { | ||
613 | [DISP_CC_MDSS_RSCC_BCR] = { 0x5000 }, | ||
614 | }; | ||
615 | |||
616 | static struct gdsc *disp_cc_sdm845_gdscs[] = { | ||
617 | [MDSS_GDSC] = &mdss_gdsc, | ||
618 | }; | ||
619 | |||
620 | static const struct regmap_config disp_cc_sdm845_regmap_config = { | ||
621 | .reg_bits = 32, | ||
622 | .reg_stride = 4, | ||
623 | .val_bits = 32, | ||
624 | .max_register = 0x10000, | ||
625 | .fast_io = true, | ||
626 | }; | ||
627 | |||
628 | static const struct qcom_cc_desc disp_cc_sdm845_desc = { | ||
629 | .config = &disp_cc_sdm845_regmap_config, | ||
630 | .clks = disp_cc_sdm845_clocks, | ||
631 | .num_clks = ARRAY_SIZE(disp_cc_sdm845_clocks), | ||
632 | .resets = disp_cc_sdm845_resets, | ||
633 | .num_resets = ARRAY_SIZE(disp_cc_sdm845_resets), | ||
634 | .gdscs = disp_cc_sdm845_gdscs, | ||
635 | .num_gdscs = ARRAY_SIZE(disp_cc_sdm845_gdscs), | ||
636 | }; | ||
637 | |||
638 | static const struct of_device_id disp_cc_sdm845_match_table[] = { | ||
639 | { .compatible = "qcom,sdm845-dispcc" }, | ||
640 | { } | ||
641 | }; | ||
642 | MODULE_DEVICE_TABLE(of, disp_cc_sdm845_match_table); | ||
643 | |||
644 | static int disp_cc_sdm845_probe(struct platform_device *pdev) | ||
645 | { | ||
646 | struct regmap *regmap; | ||
647 | struct alpha_pll_config disp_cc_pll0_config = {}; | ||
648 | |||
649 | regmap = qcom_cc_map(pdev, &disp_cc_sdm845_desc); | ||
650 | if (IS_ERR(regmap)) | ||
651 | return PTR_ERR(regmap); | ||
652 | |||
653 | disp_cc_pll0_config.l = 0x2c; | ||
654 | disp_cc_pll0_config.alpha = 0xcaaa; | ||
655 | |||
656 | clk_fabia_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll0_config); | ||
657 | |||
658 | /* Enable hardware clock gating for DSI and MDP clocks */ | ||
659 | regmap_update_bits(regmap, 0x8000, 0x7f0, 0x7f0); | ||
660 | |||
661 | return qcom_cc_really_probe(pdev, &disp_cc_sdm845_desc, regmap); | ||
662 | } | ||
663 | |||
664 | static struct platform_driver disp_cc_sdm845_driver = { | ||
665 | .probe = disp_cc_sdm845_probe, | ||
666 | .driver = { | ||
667 | .name = "disp_cc-sdm845", | ||
668 | .of_match_table = disp_cc_sdm845_match_table, | ||
669 | }, | ||
670 | }; | ||
671 | |||
672 | static int __init disp_cc_sdm845_init(void) | ||
673 | { | ||
674 | return platform_driver_register(&disp_cc_sdm845_driver); | ||
675 | } | ||
676 | subsys_initcall(disp_cc_sdm845_init); | ||
677 | |||
678 | static void __exit disp_cc_sdm845_exit(void) | ||
679 | { | ||
680 | platform_driver_unregister(&disp_cc_sdm845_driver); | ||
681 | } | ||
682 | module_exit(disp_cc_sdm845_exit); | ||
683 | |||
684 | MODULE_LICENSE("GPL v2"); | ||
685 | MODULE_DESCRIPTION("QTI DISPCC SDM845 Driver"); | ||
diff --git a/drivers/clk/qcom/gcc-apq8084.c b/drivers/clk/qcom/gcc-apq8084.c index 486d9610355c..9c99a71ea71e 100644 --- a/drivers/clk/qcom/gcc-apq8084.c +++ b/drivers/clk/qcom/gcc-apq8084.c | |||
@@ -106,8 +106,6 @@ static const char * const gcc_xo_pcie_sleep[] = { | |||
106 | "sleep_clk_src", | 106 | "sleep_clk_src", |
107 | }; | 107 | }; |
108 | 108 | ||
109 | #define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } | ||
110 | |||
111 | static struct clk_pll gpll0 = { | 109 | static struct clk_pll gpll0 = { |
112 | .l_reg = 0x0004, | 110 | .l_reg = 0x0004, |
113 | .m_reg = 0x0008, | 111 | .m_reg = 0x0008, |
diff --git a/drivers/clk/qcom/gcc-ipq4019.c b/drivers/clk/qcom/gcc-ipq4019.c index 46cb256b4aa2..8902ad42ba87 100644 --- a/drivers/clk/qcom/gcc-ipq4019.c +++ b/drivers/clk/qcom/gcc-ipq4019.c | |||
@@ -179,8 +179,6 @@ static const char * const gcc_xo_ddr_500_200[] = { | |||
179 | "ddrpllapss", | 179 | "ddrpllapss", |
180 | }; | 180 | }; |
181 | 181 | ||
182 | #define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } | ||
183 | |||
184 | static const struct freq_tbl ftbl_gcc_audio_pwm_clk[] = { | 182 | static const struct freq_tbl ftbl_gcc_audio_pwm_clk[] = { |
185 | F(48000000, P_XO, 1, 0, 0), | 183 | F(48000000, P_XO, 1, 0, 0), |
186 | F(200000000, P_FEPLL200, 1, 0, 0), | 184 | F(200000000, P_FEPLL200, 1, 0, 0), |
diff --git a/drivers/clk/qcom/gcc-ipq806x.c b/drivers/clk/qcom/gcc-ipq806x.c index 28eb200d0f1e..5f61225657ab 100644 --- a/drivers/clk/qcom/gcc-ipq806x.c +++ b/drivers/clk/qcom/gcc-ipq806x.c | |||
@@ -1220,7 +1220,6 @@ static struct clk_rcg sdc1_src = { | |||
1220 | .parent_names = gcc_pxo_pll8, | 1220 | .parent_names = gcc_pxo_pll8, |
1221 | .num_parents = 2, | 1221 | .num_parents = 2, |
1222 | .ops = &clk_rcg_ops, | 1222 | .ops = &clk_rcg_ops, |
1223 | .flags = CLK_SET_RATE_GATE, | ||
1224 | }, | 1223 | }, |
1225 | } | 1224 | } |
1226 | }; | 1225 | }; |
@@ -1269,7 +1268,6 @@ static struct clk_rcg sdc3_src = { | |||
1269 | .parent_names = gcc_pxo_pll8, | 1268 | .parent_names = gcc_pxo_pll8, |
1270 | .num_parents = 2, | 1269 | .num_parents = 2, |
1271 | .ops = &clk_rcg_ops, | 1270 | .ops = &clk_rcg_ops, |
1272 | .flags = CLK_SET_RATE_GATE, | ||
1273 | }, | 1271 | }, |
1274 | } | 1272 | } |
1275 | }; | 1273 | }; |
@@ -1353,7 +1351,6 @@ static struct clk_rcg tsif_ref_src = { | |||
1353 | .parent_names = gcc_pxo_pll8, | 1351 | .parent_names = gcc_pxo_pll8, |
1354 | .num_parents = 2, | 1352 | .num_parents = 2, |
1355 | .ops = &clk_rcg_ops, | 1353 | .ops = &clk_rcg_ops, |
1356 | .flags = CLK_SET_RATE_GATE, | ||
1357 | }, | 1354 | }, |
1358 | } | 1355 | } |
1359 | }; | 1356 | }; |
diff --git a/drivers/clk/qcom/gcc-ipq8074.c b/drivers/clk/qcom/gcc-ipq8074.c index 0462f4a8c932..505c6263141d 100644 --- a/drivers/clk/qcom/gcc-ipq8074.c +++ b/drivers/clk/qcom/gcc-ipq8074.c | |||
@@ -32,8 +32,6 @@ | |||
32 | #include "clk-regmap-mux.h" | 32 | #include "clk-regmap-mux.h" |
33 | #include "reset.h" | 33 | #include "reset.h" |
34 | 34 | ||
35 | #define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } | ||
36 | |||
37 | enum { | 35 | enum { |
38 | P_XO, | 36 | P_XO, |
39 | P_GPLL0, | 37 | P_GPLL0, |
diff --git a/drivers/clk/qcom/gcc-mdm9615.c b/drivers/clk/qcom/gcc-mdm9615.c index b99dd406e907..849046fbed6d 100644 --- a/drivers/clk/qcom/gcc-mdm9615.c +++ b/drivers/clk/qcom/gcc-mdm9615.c | |||
@@ -947,7 +947,6 @@ static struct clk_rcg sdc1_src = { | |||
947 | .parent_names = gcc_cxo_pll8, | 947 | .parent_names = gcc_cxo_pll8, |
948 | .num_parents = 2, | 948 | .num_parents = 2, |
949 | .ops = &clk_rcg_ops, | 949 | .ops = &clk_rcg_ops, |
950 | .flags = CLK_SET_RATE_GATE, | ||
951 | }, | 950 | }, |
952 | } | 951 | } |
953 | }; | 952 | }; |
@@ -996,7 +995,6 @@ static struct clk_rcg sdc2_src = { | |||
996 | .parent_names = gcc_cxo_pll8, | 995 | .parent_names = gcc_cxo_pll8, |
997 | .num_parents = 2, | 996 | .num_parents = 2, |
998 | .ops = &clk_rcg_ops, | 997 | .ops = &clk_rcg_ops, |
999 | .flags = CLK_SET_RATE_GATE, | ||
1000 | }, | 998 | }, |
1001 | } | 999 | } |
1002 | }; | 1000 | }; |
diff --git a/drivers/clk/qcom/gcc-msm8660.c b/drivers/clk/qcom/gcc-msm8660.c index c347a0d44bc8..7e930e25c79f 100644 --- a/drivers/clk/qcom/gcc-msm8660.c +++ b/drivers/clk/qcom/gcc-msm8660.c | |||
@@ -1558,7 +1558,6 @@ static struct clk_rcg sdc1_src = { | |||
1558 | .parent_names = gcc_pxo_pll8, | 1558 | .parent_names = gcc_pxo_pll8, |
1559 | .num_parents = 2, | 1559 | .num_parents = 2, |
1560 | .ops = &clk_rcg_ops, | 1560 | .ops = &clk_rcg_ops, |
1561 | .flags = CLK_SET_RATE_GATE, | ||
1562 | }, | 1561 | }, |
1563 | } | 1562 | } |
1564 | }; | 1563 | }; |
@@ -1607,7 +1606,6 @@ static struct clk_rcg sdc2_src = { | |||
1607 | .parent_names = gcc_pxo_pll8, | 1606 | .parent_names = gcc_pxo_pll8, |
1608 | .num_parents = 2, | 1607 | .num_parents = 2, |
1609 | .ops = &clk_rcg_ops, | 1608 | .ops = &clk_rcg_ops, |
1610 | .flags = CLK_SET_RATE_GATE, | ||
1611 | }, | 1609 | }, |
1612 | } | 1610 | } |
1613 | }; | 1611 | }; |
@@ -1656,7 +1654,6 @@ static struct clk_rcg sdc3_src = { | |||
1656 | .parent_names = gcc_pxo_pll8, | 1654 | .parent_names = gcc_pxo_pll8, |
1657 | .num_parents = 2, | 1655 | .num_parents = 2, |
1658 | .ops = &clk_rcg_ops, | 1656 | .ops = &clk_rcg_ops, |
1659 | .flags = CLK_SET_RATE_GATE, | ||
1660 | }, | 1657 | }, |
1661 | } | 1658 | } |
1662 | }; | 1659 | }; |
@@ -1705,7 +1702,6 @@ static struct clk_rcg sdc4_src = { | |||
1705 | .parent_names = gcc_pxo_pll8, | 1702 | .parent_names = gcc_pxo_pll8, |
1706 | .num_parents = 2, | 1703 | .num_parents = 2, |
1707 | .ops = &clk_rcg_ops, | 1704 | .ops = &clk_rcg_ops, |
1708 | .flags = CLK_SET_RATE_GATE, | ||
1709 | }, | 1705 | }, |
1710 | } | 1706 | } |
1711 | }; | 1707 | }; |
@@ -1754,7 +1750,6 @@ static struct clk_rcg sdc5_src = { | |||
1754 | .parent_names = gcc_pxo_pll8, | 1750 | .parent_names = gcc_pxo_pll8, |
1755 | .num_parents = 2, | 1751 | .num_parents = 2, |
1756 | .ops = &clk_rcg_ops, | 1752 | .ops = &clk_rcg_ops, |
1757 | .flags = CLK_SET_RATE_GATE, | ||
1758 | }, | 1753 | }, |
1759 | } | 1754 | } |
1760 | }; | 1755 | }; |
diff --git a/drivers/clk/qcom/gcc-msm8916.c b/drivers/clk/qcom/gcc-msm8916.c index d6c7f50ba86a..ac2b0aa1e8b5 100644 --- a/drivers/clk/qcom/gcc-msm8916.c +++ b/drivers/clk/qcom/gcc-msm8916.c | |||
@@ -264,8 +264,6 @@ static const char * const gcc_xo_gpll1_emclk_sleep[] = { | |||
264 | "sleep_clk", | 264 | "sleep_clk", |
265 | }; | 265 | }; |
266 | 266 | ||
267 | #define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } | ||
268 | |||
269 | static struct clk_pll gpll0 = { | 267 | static struct clk_pll gpll0 = { |
270 | .l_reg = 0x21004, | 268 | .l_reg = 0x21004, |
271 | .m_reg = 0x21008, | 269 | .m_reg = 0x21008, |
diff --git a/drivers/clk/qcom/gcc-msm8960.c b/drivers/clk/qcom/gcc-msm8960.c index eb551c75fba6..fd495e0471bb 100644 --- a/drivers/clk/qcom/gcc-msm8960.c +++ b/drivers/clk/qcom/gcc-msm8960.c | |||
@@ -1628,7 +1628,6 @@ static struct clk_rcg sdc1_src = { | |||
1628 | .parent_names = gcc_pxo_pll8, | 1628 | .parent_names = gcc_pxo_pll8, |
1629 | .num_parents = 2, | 1629 | .num_parents = 2, |
1630 | .ops = &clk_rcg_ops, | 1630 | .ops = &clk_rcg_ops, |
1631 | .flags = CLK_SET_RATE_GATE, | ||
1632 | }, | 1631 | }, |
1633 | } | 1632 | } |
1634 | }; | 1633 | }; |
@@ -1677,7 +1676,6 @@ static struct clk_rcg sdc2_src = { | |||
1677 | .parent_names = gcc_pxo_pll8, | 1676 | .parent_names = gcc_pxo_pll8, |
1678 | .num_parents = 2, | 1677 | .num_parents = 2, |
1679 | .ops = &clk_rcg_ops, | 1678 | .ops = &clk_rcg_ops, |
1680 | .flags = CLK_SET_RATE_GATE, | ||
1681 | }, | 1679 | }, |
1682 | } | 1680 | } |
1683 | }; | 1681 | }; |
@@ -1726,7 +1724,6 @@ static struct clk_rcg sdc3_src = { | |||
1726 | .parent_names = gcc_pxo_pll8, | 1724 | .parent_names = gcc_pxo_pll8, |
1727 | .num_parents = 2, | 1725 | .num_parents = 2, |
1728 | .ops = &clk_rcg_ops, | 1726 | .ops = &clk_rcg_ops, |
1729 | .flags = CLK_SET_RATE_GATE, | ||
1730 | }, | 1727 | }, |
1731 | } | 1728 | } |
1732 | }; | 1729 | }; |
@@ -1775,7 +1772,6 @@ static struct clk_rcg sdc4_src = { | |||
1775 | .parent_names = gcc_pxo_pll8, | 1772 | .parent_names = gcc_pxo_pll8, |
1776 | .num_parents = 2, | 1773 | .num_parents = 2, |
1777 | .ops = &clk_rcg_ops, | 1774 | .ops = &clk_rcg_ops, |
1778 | .flags = CLK_SET_RATE_GATE, | ||
1779 | }, | 1775 | }, |
1780 | } | 1776 | } |
1781 | }; | 1777 | }; |
@@ -1824,7 +1820,6 @@ static struct clk_rcg sdc5_src = { | |||
1824 | .parent_names = gcc_pxo_pll8, | 1820 | .parent_names = gcc_pxo_pll8, |
1825 | .num_parents = 2, | 1821 | .num_parents = 2, |
1826 | .ops = &clk_rcg_ops, | 1822 | .ops = &clk_rcg_ops, |
1827 | .flags = CLK_SET_RATE_GATE, | ||
1828 | }, | 1823 | }, |
1829 | } | 1824 | } |
1830 | }; | 1825 | }; |
diff --git a/drivers/clk/qcom/gcc-msm8974.c b/drivers/clk/qcom/gcc-msm8974.c index 348e30da4f18..08e2900d172c 100644 --- a/drivers/clk/qcom/gcc-msm8974.c +++ b/drivers/clk/qcom/gcc-msm8974.c | |||
@@ -62,8 +62,6 @@ static const char * const gcc_xo_gpll0_gpll4[] = { | |||
62 | "gpll4_vote", | 62 | "gpll4_vote", |
63 | }; | 63 | }; |
64 | 64 | ||
65 | #define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } | ||
66 | |||
67 | static struct clk_pll gpll0 = { | 65 | static struct clk_pll gpll0 = { |
68 | .l_reg = 0x0004, | 66 | .l_reg = 0x0004, |
69 | .m_reg = 0x0008, | 67 | .m_reg = 0x0008, |
diff --git a/drivers/clk/qcom/gcc-msm8994.c b/drivers/clk/qcom/gcc-msm8994.c index 1e38efc37180..53f0f369a33e 100644 --- a/drivers/clk/qcom/gcc-msm8994.c +++ b/drivers/clk/qcom/gcc-msm8994.c | |||
@@ -57,8 +57,6 @@ static const char * const gcc_xo_gpll0_gpll4[] = { | |||
57 | "gpll4", | 57 | "gpll4", |
58 | }; | 58 | }; |
59 | 59 | ||
60 | #define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } | ||
61 | |||
62 | static struct clk_fixed_factor xo = { | 60 | static struct clk_fixed_factor xo = { |
63 | .mult = 1, | 61 | .mult = 1, |
64 | .div = 1, | 62 | .div = 1, |
diff --git a/drivers/clk/qcom/gcc-msm8996.c b/drivers/clk/qcom/gcc-msm8996.c index ff8d66fd94e6..9a3290fdd01b 100644 --- a/drivers/clk/qcom/gcc-msm8996.c +++ b/drivers/clk/qcom/gcc-msm8996.c | |||
@@ -32,8 +32,6 @@ | |||
32 | #include "reset.h" | 32 | #include "reset.h" |
33 | #include "gdsc.h" | 33 | #include "gdsc.h" |
34 | 34 | ||
35 | #define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } | ||
36 | |||
37 | enum { | 35 | enum { |
38 | P_XO, | 36 | P_XO, |
39 | P_GPLL0, | 37 | P_GPLL0, |
diff --git a/drivers/clk/qcom/gcc-msm8998.c b/drivers/clk/qcom/gcc-msm8998.c index 78d87f5c7098..9f0ae403d5f5 100644 --- a/drivers/clk/qcom/gcc-msm8998.c +++ b/drivers/clk/qcom/gcc-msm8998.c | |||
@@ -25,8 +25,6 @@ | |||
25 | #include "reset.h" | 25 | #include "reset.h" |
26 | #include "gdsc.h" | 26 | #include "gdsc.h" |
27 | 27 | ||
28 | #define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } | ||
29 | |||
30 | enum { | 28 | enum { |
31 | P_AUD_REF_CLK, | 29 | P_AUD_REF_CLK, |
32 | P_CORE_BI_PLL_TEST_SE, | 30 | P_CORE_BI_PLL_TEST_SE, |
diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c index e78e6f5b99fc..fa1a196350f1 100644 --- a/drivers/clk/qcom/gcc-sdm845.c +++ b/drivers/clk/qcom/gcc-sdm845.c | |||
@@ -25,8 +25,6 @@ | |||
25 | #include "gdsc.h" | 25 | #include "gdsc.h" |
26 | #include "reset.h" | 26 | #include "reset.h" |
27 | 27 | ||
28 | #define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } | ||
29 | |||
30 | enum { | 28 | enum { |
31 | P_BI_TCXO, | 29 | P_BI_TCXO, |
32 | P_AUD_REF_CLK, | 30 | P_AUD_REF_CLK, |
@@ -1103,6 +1101,7 @@ static struct clk_branch gcc_camera_ahb_clk = { | |||
1103 | .enable_mask = BIT(0), | 1101 | .enable_mask = BIT(0), |
1104 | .hw.init = &(struct clk_init_data){ | 1102 | .hw.init = &(struct clk_init_data){ |
1105 | .name = "gcc_camera_ahb_clk", | 1103 | .name = "gcc_camera_ahb_clk", |
1104 | .flags = CLK_IS_CRITICAL, | ||
1106 | .ops = &clk_branch2_ops, | 1105 | .ops = &clk_branch2_ops, |
1107 | }, | 1106 | }, |
1108 | }, | 1107 | }, |
@@ -1129,6 +1128,7 @@ static struct clk_branch gcc_camera_xo_clk = { | |||
1129 | .enable_mask = BIT(0), | 1128 | .enable_mask = BIT(0), |
1130 | .hw.init = &(struct clk_init_data){ | 1129 | .hw.init = &(struct clk_init_data){ |
1131 | .name = "gcc_camera_xo_clk", | 1130 | .name = "gcc_camera_xo_clk", |
1131 | .flags = CLK_IS_CRITICAL, | ||
1132 | .ops = &clk_branch2_ops, | 1132 | .ops = &clk_branch2_ops, |
1133 | }, | 1133 | }, |
1134 | }, | 1134 | }, |
@@ -1270,6 +1270,7 @@ static struct clk_branch gcc_disp_ahb_clk = { | |||
1270 | .enable_mask = BIT(0), | 1270 | .enable_mask = BIT(0), |
1271 | .hw.init = &(struct clk_init_data){ | 1271 | .hw.init = &(struct clk_init_data){ |
1272 | .name = "gcc_disp_ahb_clk", | 1272 | .name = "gcc_disp_ahb_clk", |
1273 | .flags = CLK_IS_CRITICAL, | ||
1273 | .ops = &clk_branch2_ops, | 1274 | .ops = &clk_branch2_ops, |
1274 | }, | 1275 | }, |
1275 | }, | 1276 | }, |
@@ -1328,6 +1329,7 @@ static struct clk_branch gcc_disp_xo_clk = { | |||
1328 | .enable_mask = BIT(0), | 1329 | .enable_mask = BIT(0), |
1329 | .hw.init = &(struct clk_init_data){ | 1330 | .hw.init = &(struct clk_init_data){ |
1330 | .name = "gcc_disp_xo_clk", | 1331 | .name = "gcc_disp_xo_clk", |
1332 | .flags = CLK_IS_CRITICAL, | ||
1331 | .ops = &clk_branch2_ops, | 1333 | .ops = &clk_branch2_ops, |
1332 | }, | 1334 | }, |
1333 | }, | 1335 | }, |
@@ -1397,6 +1399,7 @@ static struct clk_branch gcc_gpu_cfg_ahb_clk = { | |||
1397 | .enable_mask = BIT(0), | 1399 | .enable_mask = BIT(0), |
1398 | .hw.init = &(struct clk_init_data){ | 1400 | .hw.init = &(struct clk_init_data){ |
1399 | .name = "gcc_gpu_cfg_ahb_clk", | 1401 | .name = "gcc_gpu_cfg_ahb_clk", |
1402 | .flags = CLK_IS_CRITICAL, | ||
1400 | .ops = &clk_branch2_ops, | 1403 | .ops = &clk_branch2_ops, |
1401 | }, | 1404 | }, |
1402 | }, | 1405 | }, |
@@ -2985,6 +2988,7 @@ static struct clk_branch gcc_video_ahb_clk = { | |||
2985 | .enable_mask = BIT(0), | 2988 | .enable_mask = BIT(0), |
2986 | .hw.init = &(struct clk_init_data){ | 2989 | .hw.init = &(struct clk_init_data){ |
2987 | .name = "gcc_video_ahb_clk", | 2990 | .name = "gcc_video_ahb_clk", |
2991 | .flags = CLK_IS_CRITICAL, | ||
2988 | .ops = &clk_branch2_ops, | 2992 | .ops = &clk_branch2_ops, |
2989 | }, | 2993 | }, |
2990 | }, | 2994 | }, |
@@ -3011,6 +3015,7 @@ static struct clk_branch gcc_video_xo_clk = { | |||
3011 | .enable_mask = BIT(0), | 3015 | .enable_mask = BIT(0), |
3012 | .hw.init = &(struct clk_init_data){ | 3016 | .hw.init = &(struct clk_init_data){ |
3013 | .name = "gcc_video_xo_clk", | 3017 | .name = "gcc_video_xo_clk", |
3018 | .flags = CLK_IS_CRITICAL, | ||
3014 | .ops = &clk_branch2_ops, | 3019 | .ops = &clk_branch2_ops, |
3015 | }, | 3020 | }, |
3016 | }, | 3021 | }, |
@@ -3049,6 +3054,36 @@ static struct clk_branch gcc_vs_ctrl_clk = { | |||
3049 | }, | 3054 | }, |
3050 | }; | 3055 | }; |
3051 | 3056 | ||
3057 | static struct clk_branch gcc_cpuss_dvm_bus_clk = { | ||
3058 | .halt_reg = 0x48190, | ||
3059 | .halt_check = BRANCH_HALT, | ||
3060 | .clkr = { | ||
3061 | .enable_reg = 0x48190, | ||
3062 | .enable_mask = BIT(0), | ||
3063 | .hw.init = &(struct clk_init_data){ | ||
3064 | .name = "gcc_cpuss_dvm_bus_clk", | ||
3065 | .flags = CLK_IS_CRITICAL, | ||
3066 | .ops = &clk_branch2_ops, | ||
3067 | }, | ||
3068 | }, | ||
3069 | }; | ||
3070 | |||
3071 | static struct clk_branch gcc_cpuss_gnoc_clk = { | ||
3072 | .halt_reg = 0x48004, | ||
3073 | .halt_check = BRANCH_HALT_VOTED, | ||
3074 | .hwcg_reg = 0x48004, | ||
3075 | .hwcg_bit = 1, | ||
3076 | .clkr = { | ||
3077 | .enable_reg = 0x52004, | ||
3078 | .enable_mask = BIT(22), | ||
3079 | .hw.init = &(struct clk_init_data){ | ||
3080 | .name = "gcc_cpuss_gnoc_clk", | ||
3081 | .flags = CLK_IS_CRITICAL, | ||
3082 | .ops = &clk_branch2_ops, | ||
3083 | }, | ||
3084 | }, | ||
3085 | }; | ||
3086 | |||
3052 | static struct gdsc pcie_0_gdsc = { | 3087 | static struct gdsc pcie_0_gdsc = { |
3053 | .gdscr = 0x6b004, | 3088 | .gdscr = 0x6b004, |
3054 | .pd = { | 3089 | .pd = { |
@@ -3344,6 +3379,8 @@ static struct clk_regmap *gcc_sdm845_clocks[] = { | |||
3344 | [GPLL0] = &gpll0.clkr, | 3379 | [GPLL0] = &gpll0.clkr, |
3345 | [GPLL0_OUT_EVEN] = &gpll0_out_even.clkr, | 3380 | [GPLL0_OUT_EVEN] = &gpll0_out_even.clkr, |
3346 | [GPLL4] = &gpll4.clkr, | 3381 | [GPLL4] = &gpll4.clkr, |
3382 | [GCC_CPUSS_DVM_BUS_CLK] = &gcc_cpuss_dvm_bus_clk.clkr, | ||
3383 | [GCC_CPUSS_GNOC_CLK] = &gcc_cpuss_gnoc_clk.clkr, | ||
3347 | }; | 3384 | }; |
3348 | 3385 | ||
3349 | static const struct qcom_reset_map gcc_sdm845_resets[] = { | 3386 | static const struct qcom_reset_map gcc_sdm845_resets[] = { |
@@ -3433,10 +3470,6 @@ static int gcc_sdm845_probe(struct platform_device *pdev) | |||
3433 | regmap_update_bits(regmap, 0x09ffc, 0x3, 0x3); | 3470 | regmap_update_bits(regmap, 0x09ffc, 0x3, 0x3); |
3434 | regmap_update_bits(regmap, 0x71028, 0x3, 0x3); | 3471 | regmap_update_bits(regmap, 0x71028, 0x3, 0x3); |
3435 | 3472 | ||
3436 | /* Enable CPUSS clocks */ | ||
3437 | regmap_update_bits(regmap, 0x48190, BIT(0), 0x1); | ||
3438 | regmap_update_bits(regmap, 0x52004, BIT(22), 0x1); | ||
3439 | |||
3440 | return qcom_cc_really_probe(pdev, &gcc_sdm845_desc, regmap); | 3473 | return qcom_cc_really_probe(pdev, &gcc_sdm845_desc, regmap); |
3441 | } | 3474 | } |
3442 | 3475 | ||
diff --git a/drivers/clk/qcom/mmcc-apq8084.c b/drivers/clk/qcom/mmcc-apq8084.c index 30777f9f1a43..4ce1d7c88377 100644 --- a/drivers/clk/qcom/mmcc-apq8084.c +++ b/drivers/clk/qcom/mmcc-apq8084.c | |||
@@ -219,8 +219,6 @@ static const char * const mmcc_xo_mmpll0_1_4_gpll1_0_sleep[] = { | |||
219 | "sleep_clk_src", | 219 | "sleep_clk_src", |
220 | }; | 220 | }; |
221 | 221 | ||
222 | #define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } | ||
223 | |||
224 | static struct clk_pll mmpll0 = { | 222 | static struct clk_pll mmpll0 = { |
225 | .l_reg = 0x0004, | 223 | .l_reg = 0x0004, |
226 | .m_reg = 0x0008, | 224 | .m_reg = 0x0008, |
diff --git a/drivers/clk/qcom/mmcc-msm8974.c b/drivers/clk/qcom/mmcc-msm8974.c index 715e7cd94125..91818516c3e0 100644 --- a/drivers/clk/qcom/mmcc-msm8974.c +++ b/drivers/clk/qcom/mmcc-msm8974.c | |||
@@ -184,8 +184,6 @@ static const char * const mmcc_xo_dsibyte_hdmi_edp_gpll0[] = { | |||
184 | "dsi1pllbyte", | 184 | "dsi1pllbyte", |
185 | }; | 185 | }; |
186 | 186 | ||
187 | #define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } | ||
188 | |||
189 | static struct clk_pll mmpll0 = { | 187 | static struct clk_pll mmpll0 = { |
190 | .l_reg = 0x0004, | 188 | .l_reg = 0x0004, |
191 | .m_reg = 0x0008, | 189 | .m_reg = 0x0008, |
diff --git a/drivers/clk/qcom/mmcc-msm8996.c b/drivers/clk/qcom/mmcc-msm8996.c index 4b20d1b67a1b..7d4ee109435c 100644 --- a/drivers/clk/qcom/mmcc-msm8996.c +++ b/drivers/clk/qcom/mmcc-msm8996.c | |||
@@ -34,8 +34,6 @@ | |||
34 | #include "reset.h" | 34 | #include "reset.h" |
35 | #include "gdsc.h" | 35 | #include "gdsc.h" |
36 | 36 | ||
37 | #define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } | ||
38 | |||
39 | enum { | 37 | enum { |
40 | P_XO, | 38 | P_XO, |
41 | P_MMPLL0, | 39 | P_MMPLL0, |
diff --git a/drivers/clk/qcom/videocc-sdm845.c b/drivers/clk/qcom/videocc-sdm845.c index 9073b7a710ac..5d6a7724a194 100644 --- a/drivers/clk/qcom/videocc-sdm845.c +++ b/drivers/clk/qcom/videocc-sdm845.c | |||
@@ -18,8 +18,6 @@ | |||
18 | #include "clk-pll.h" | 18 | #include "clk-pll.h" |
19 | #include "gdsc.h" | 19 | #include "gdsc.h" |
20 | 20 | ||
21 | #define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } | ||
22 | |||
23 | enum { | 21 | enum { |
24 | P_BI_TCXO, | 22 | P_BI_TCXO, |
25 | P_CORE_BI_PLL_TEST_SE, | 23 | P_CORE_BI_PLL_TEST_SE, |
diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig index f9ba71311727..9022bbe1297e 100644 --- a/drivers/clk/renesas/Kconfig +++ b/drivers/clk/renesas/Kconfig | |||
@@ -21,6 +21,7 @@ config CLK_RENESAS | |||
21 | select CLK_R8A77980 if ARCH_R8A77980 | 21 | select CLK_R8A77980 if ARCH_R8A77980 |
22 | select CLK_R8A77990 if ARCH_R8A77990 | 22 | select CLK_R8A77990 if ARCH_R8A77990 |
23 | select CLK_R8A77995 if ARCH_R8A77995 | 23 | select CLK_R8A77995 if ARCH_R8A77995 |
24 | select CLK_R9A06G032 if ARCH_R9A06G032 | ||
24 | select CLK_SH73A0 if ARCH_SH73A0 | 25 | select CLK_SH73A0 if ARCH_SH73A0 |
25 | 26 | ||
26 | if CLK_RENESAS | 27 | if CLK_RENESAS |
@@ -125,6 +126,11 @@ config CLK_R8A77995 | |||
125 | bool "R-Car D3 clock support" if COMPILE_TEST | 126 | bool "R-Car D3 clock support" if COMPILE_TEST |
126 | select CLK_RCAR_GEN3_CPG | 127 | select CLK_RCAR_GEN3_CPG |
127 | 128 | ||
129 | config CLK_R9A06G032 | ||
130 | bool "Renesas R9A06G032 clock driver" | ||
131 | help | ||
132 | This is a driver for R9A06G032 clocks | ||
133 | |||
128 | config CLK_SH73A0 | 134 | config CLK_SH73A0 |
129 | bool "SH-Mobile AG5 clock support" if COMPILE_TEST | 135 | bool "SH-Mobile AG5 clock support" if COMPILE_TEST |
130 | select CLK_RENESAS_CPG_MSTP | 136 | select CLK_RENESAS_CPG_MSTP |
diff --git a/drivers/clk/renesas/Makefile b/drivers/clk/renesas/Makefile index fe5bac9215e5..e4aa3d6143d2 100644 --- a/drivers/clk/renesas/Makefile +++ b/drivers/clk/renesas/Makefile | |||
@@ -20,6 +20,7 @@ obj-$(CONFIG_CLK_R8A77970) += r8a77970-cpg-mssr.o | |||
20 | obj-$(CONFIG_CLK_R8A77980) += r8a77980-cpg-mssr.o | 20 | obj-$(CONFIG_CLK_R8A77980) += r8a77980-cpg-mssr.o |
21 | obj-$(CONFIG_CLK_R8A77990) += r8a77990-cpg-mssr.o | 21 | obj-$(CONFIG_CLK_R8A77990) += r8a77990-cpg-mssr.o |
22 | obj-$(CONFIG_CLK_R8A77995) += r8a77995-cpg-mssr.o | 22 | obj-$(CONFIG_CLK_R8A77995) += r8a77995-cpg-mssr.o |
23 | obj-$(CONFIG_CLK_R9A06G032) += r9a06g032-clocks.o | ||
23 | obj-$(CONFIG_CLK_SH73A0) += clk-sh73a0.o | 24 | obj-$(CONFIG_CLK_SH73A0) += clk-sh73a0.o |
24 | 25 | ||
25 | # Family | 26 | # Family |
diff --git a/drivers/clk/renesas/r8a7795-cpg-mssr.c b/drivers/clk/renesas/r8a7795-cpg-mssr.c index 775b0ceaa337..a85dd50e8911 100644 --- a/drivers/clk/renesas/r8a7795-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7795-cpg-mssr.c | |||
@@ -103,6 +103,7 @@ static struct cpg_core_clk r8a7795_core_clks[] __initdata = { | |||
103 | DEF_GEN3_SD("sd3", R8A7795_CLK_SD3, CLK_SDSRC, 0x26c), | 103 | DEF_GEN3_SD("sd3", R8A7795_CLK_SD3, CLK_SDSRC, 0x26c), |
104 | 104 | ||
105 | DEF_FIXED("cl", R8A7795_CLK_CL, CLK_PLL1_DIV2, 48, 1), | 105 | DEF_FIXED("cl", R8A7795_CLK_CL, CLK_PLL1_DIV2, 48, 1), |
106 | DEF_FIXED("cr", R8A7795_CLK_CR, CLK_PLL1_DIV4, 2, 1), | ||
106 | DEF_FIXED("cp", R8A7795_CLK_CP, CLK_EXTAL, 2, 1), | 107 | DEF_FIXED("cp", R8A7795_CLK_CP, CLK_EXTAL, 2, 1), |
107 | 108 | ||
108 | DEF_DIV6P1("canfd", R8A7795_CLK_CANFD, CLK_PLL1_DIV4, 0x244), | 109 | DEF_DIV6P1("canfd", R8A7795_CLK_CANFD, CLK_PLL1_DIV4, 0x244), |
@@ -132,6 +133,7 @@ static struct mssr_mod_clk r8a7795_mod_clks[] __initdata = { | |||
132 | DEF_MOD("sys-dmac2", 217, R8A7795_CLK_S0D3), | 133 | DEF_MOD("sys-dmac2", 217, R8A7795_CLK_S0D3), |
133 | DEF_MOD("sys-dmac1", 218, R8A7795_CLK_S0D3), | 134 | DEF_MOD("sys-dmac1", 218, R8A7795_CLK_S0D3), |
134 | DEF_MOD("sys-dmac0", 219, R8A7795_CLK_S0D3), | 135 | DEF_MOD("sys-dmac0", 219, R8A7795_CLK_S0D3), |
136 | DEF_MOD("sceg-pub", 229, R8A7795_CLK_CR), | ||
135 | DEF_MOD("cmt3", 300, R8A7795_CLK_R), | 137 | DEF_MOD("cmt3", 300, R8A7795_CLK_R), |
136 | DEF_MOD("cmt2", 301, R8A7795_CLK_R), | 138 | DEF_MOD("cmt2", 301, R8A7795_CLK_R), |
137 | DEF_MOD("cmt1", 302, R8A7795_CLK_R), | 139 | DEF_MOD("cmt1", 302, R8A7795_CLK_R), |
diff --git a/drivers/clk/renesas/r9a06g032-clocks.c b/drivers/clk/renesas/r9a06g032-clocks.c new file mode 100644 index 000000000000..a0b6ecdc63dd --- /dev/null +++ b/drivers/clk/renesas/r9a06g032-clocks.c | |||
@@ -0,0 +1,893 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * R9A09G032 clock driver | ||
4 | * | ||
5 | * Copyright (C) 2018 Renesas Electronics Europe Limited | ||
6 | * | ||
7 | * Michel Pollet <michel.pollet@bp.renesas.com>, <buserror@gmail.com> | ||
8 | */ | ||
9 | |||
10 | #include <linux/clk.h> | ||
11 | #include <linux/clk-provider.h> | ||
12 | #include <linux/delay.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/math64.h> | ||
16 | #include <linux/of.h> | ||
17 | #include <linux/of_address.h> | ||
18 | #include <linux/platform_device.h> | ||
19 | #include <linux/slab.h> | ||
20 | #include <linux/spinlock.h> | ||
21 | #include <dt-bindings/clock/r9a06g032-sysctrl.h> | ||
22 | |||
23 | struct r9a06g032_gate { | ||
24 | u16 gate, reset, ready, midle, | ||
25 | scon, mirack, mistat; | ||
26 | }; | ||
27 | |||
28 | /* This is used to describe a clock for instantiation */ | ||
29 | struct r9a06g032_clkdesc { | ||
30 | const char *name; | ||
31 | uint32_t type: 3; | ||
32 | uint32_t index: 8; | ||
33 | uint32_t source : 8; /* source index + 1 (0 == none) */ | ||
34 | /* these are used to populate the bitsel struct */ | ||
35 | union { | ||
36 | struct r9a06g032_gate gate; | ||
37 | /* for dividers */ | ||
38 | struct { | ||
39 | unsigned int div_min : 10, div_max : 10, reg: 10; | ||
40 | u16 div_table[4]; | ||
41 | }; | ||
42 | /* For fixed-factor ones */ | ||
43 | struct { | ||
44 | u16 div, mul; | ||
45 | }; | ||
46 | unsigned int factor; | ||
47 | unsigned int frequency; | ||
48 | /* for dual gate */ | ||
49 | struct { | ||
50 | uint16_t group : 1, index: 3; | ||
51 | u16 sel, g1, r1, g2, r2; | ||
52 | } dual; | ||
53 | }; | ||
54 | } __packed; | ||
55 | |||
56 | #define I_GATE(_clk, _rst, _rdy, _midle, _scon, _mirack, _mistat) \ | ||
57 | { .gate = _clk, .reset = _rst, \ | ||
58 | .ready = _rdy, .midle = _midle, \ | ||
59 | .scon = _scon, .mirack = _mirack, .mistat = _mistat } | ||
60 | #define D_GATE(_idx, _n, _src, ...) \ | ||
61 | { .type = K_GATE, .index = R9A06G032_##_idx, \ | ||
62 | .source = 1 + R9A06G032_##_src, .name = _n, \ | ||
63 | .gate = I_GATE(__VA_ARGS__), } | ||
64 | #define D_ROOT(_idx, _n, _mul, _div) \ | ||
65 | { .type = K_FFC, .index = R9A06G032_##_idx, .name = _n, \ | ||
66 | .div = _div, .mul = _mul } | ||
67 | #define D_FFC(_idx, _n, _src, _div) \ | ||
68 | { .type = K_FFC, .index = R9A06G032_##_idx, \ | ||
69 | .source = 1 + R9A06G032_##_src, .name = _n, \ | ||
70 | .div = _div, .mul = 1} | ||
71 | #define D_DIV(_idx, _n, _src, _reg, _min, _max, ...) \ | ||
72 | { .type = K_DIV, .index = R9A06G032_##_idx, \ | ||
73 | .source = 1 + R9A06G032_##_src, .name = _n, \ | ||
74 | .reg = _reg, .div_min = _min, .div_max = _max, \ | ||
75 | .div_table = { __VA_ARGS__ } } | ||
76 | #define D_UGATE(_idx, _n, _src, _g, _gi, _g1, _r1, _g2, _r2) \ | ||
77 | { .type = K_DUALGATE, .index = R9A06G032_##_idx, \ | ||
78 | .source = 1 + R9A06G032_##_src, .name = _n, \ | ||
79 | .dual = { .group = _g, .index = _gi, \ | ||
80 | .g1 = _g1, .r1 = _r1, .g2 = _g2, .r2 = _r2 }, } | ||
81 | |||
82 | enum { K_GATE = 0, K_FFC, K_DIV, K_BITSEL, K_DUALGATE }; | ||
83 | |||
84 | /* Internal clock IDs */ | ||
85 | #define R9A06G032_CLKOUT 0 | ||
86 | #define R9A06G032_CLKOUT_D10 2 | ||
87 | #define R9A06G032_CLKOUT_D16 3 | ||
88 | #define R9A06G032_CLKOUT_D160 4 | ||
89 | #define R9A06G032_CLKOUT_D1OR2 5 | ||
90 | #define R9A06G032_CLKOUT_D20 6 | ||
91 | #define R9A06G032_CLKOUT_D40 7 | ||
92 | #define R9A06G032_CLKOUT_D5 8 | ||
93 | #define R9A06G032_CLKOUT_D8 9 | ||
94 | #define R9A06G032_DIV_ADC 10 | ||
95 | #define R9A06G032_DIV_I2C 11 | ||
96 | #define R9A06G032_DIV_NAND 12 | ||
97 | #define R9A06G032_DIV_P1_PG 13 | ||
98 | #define R9A06G032_DIV_P2_PG 14 | ||
99 | #define R9A06G032_DIV_P3_PG 15 | ||
100 | #define R9A06G032_DIV_P4_PG 16 | ||
101 | #define R9A06G032_DIV_P5_PG 17 | ||
102 | #define R9A06G032_DIV_P6_PG 18 | ||
103 | #define R9A06G032_DIV_QSPI0 19 | ||
104 | #define R9A06G032_DIV_QSPI1 20 | ||
105 | #define R9A06G032_DIV_REF_SYNC 21 | ||
106 | #define R9A06G032_DIV_SDIO0 22 | ||
107 | #define R9A06G032_DIV_SDIO1 23 | ||
108 | #define R9A06G032_DIV_SWITCH 24 | ||
109 | #define R9A06G032_DIV_UART 25 | ||
110 | #define R9A06G032_DIV_MOTOR 64 | ||
111 | #define R9A06G032_CLK_DDRPHY_PLLCLK_D4 78 | ||
112 | #define R9A06G032_CLK_ECAT100_D4 79 | ||
113 | #define R9A06G032_CLK_HSR100_D2 80 | ||
114 | #define R9A06G032_CLK_REF_SYNC_D4 81 | ||
115 | #define R9A06G032_CLK_REF_SYNC_D8 82 | ||
116 | #define R9A06G032_CLK_SERCOS100_D2 83 | ||
117 | #define R9A06G032_DIV_CA7 84 | ||
118 | |||
119 | #define R9A06G032_UART_GROUP_012 154 | ||
120 | #define R9A06G032_UART_GROUP_34567 155 | ||
121 | |||
122 | #define R9A06G032_CLOCK_COUNT (R9A06G032_UART_GROUP_34567 + 1) | ||
123 | |||
124 | static const struct r9a06g032_clkdesc r9a06g032_clocks[] __initconst = { | ||
125 | D_ROOT(CLKOUT, "clkout", 25, 1), | ||
126 | D_ROOT(CLK_PLL_USB, "clk_pll_usb", 12, 10), | ||
127 | D_FFC(CLKOUT_D10, "clkout_d10", CLKOUT, 10), | ||
128 | D_FFC(CLKOUT_D16, "clkout_d16", CLKOUT, 16), | ||
129 | D_FFC(CLKOUT_D160, "clkout_d160", CLKOUT, 160), | ||
130 | D_DIV(CLKOUT_D1OR2, "clkout_d1or2", CLKOUT, 0, 1, 2), | ||
131 | D_FFC(CLKOUT_D20, "clkout_d20", CLKOUT, 20), | ||
132 | D_FFC(CLKOUT_D40, "clkout_d40", CLKOUT, 40), | ||
133 | D_FFC(CLKOUT_D5, "clkout_d5", CLKOUT, 5), | ||
134 | D_FFC(CLKOUT_D8, "clkout_d8", CLKOUT, 8), | ||
135 | D_DIV(DIV_ADC, "div_adc", CLKOUT, 77, 50, 250), | ||
136 | D_DIV(DIV_I2C, "div_i2c", CLKOUT, 78, 12, 16), | ||
137 | D_DIV(DIV_NAND, "div_nand", CLKOUT, 82, 12, 32), | ||
138 | D_DIV(DIV_P1_PG, "div_p1_pg", CLKOUT, 68, 12, 200), | ||
139 | D_DIV(DIV_P2_PG, "div_p2_pg", CLKOUT, 62, 12, 128), | ||
140 | D_DIV(DIV_P3_PG, "div_p3_pg", CLKOUT, 64, 8, 128), | ||
141 | D_DIV(DIV_P4_PG, "div_p4_pg", CLKOUT, 66, 8, 128), | ||
142 | D_DIV(DIV_P5_PG, "div_p5_pg", CLKOUT, 71, 10, 40), | ||
143 | D_DIV(DIV_P6_PG, "div_p6_pg", CLKOUT, 18, 12, 64), | ||
144 | D_DIV(DIV_QSPI0, "div_qspi0", CLKOUT, 73, 3, 7), | ||
145 | D_DIV(DIV_QSPI1, "div_qspi1", CLKOUT, 25, 3, 7), | ||
146 | D_DIV(DIV_REF_SYNC, "div_ref_sync", CLKOUT, 56, 2, 16, 2, 4, 8, 16), | ||
147 | D_DIV(DIV_SDIO0, "div_sdio0", CLKOUT, 74, 20, 128), | ||
148 | D_DIV(DIV_SDIO1, "div_sdio1", CLKOUT, 75, 20, 128), | ||
149 | D_DIV(DIV_SWITCH, "div_switch", CLKOUT, 37, 5, 40), | ||
150 | D_DIV(DIV_UART, "div_uart", CLKOUT, 79, 12, 128), | ||
151 | D_GATE(CLK_25_PG4, "clk_25_pg4", CLKOUT_D40, 0x749, 0x74a, 0x74b, 0, 0xae3, 0, 0), | ||
152 | D_GATE(CLK_25_PG5, "clk_25_pg5", CLKOUT_D40, 0x74c, 0x74d, 0x74e, 0, 0xae4, 0, 0), | ||
153 | D_GATE(CLK_25_PG6, "clk_25_pg6", CLKOUT_D40, 0x74f, 0x750, 0x751, 0, 0xae5, 0, 0), | ||
154 | D_GATE(CLK_25_PG7, "clk_25_pg7", CLKOUT_D40, 0x752, 0x753, 0x754, 0, 0xae6, 0, 0), | ||
155 | D_GATE(CLK_25_PG8, "clk_25_pg8", CLKOUT_D40, 0x755, 0x756, 0x757, 0, 0xae7, 0, 0), | ||
156 | D_GATE(CLK_ADC, "clk_adc", DIV_ADC, 0x1ea, 0x1eb, 0, 0, 0, 0, 0), | ||
157 | D_GATE(CLK_ECAT100, "clk_ecat100", CLKOUT_D10, 0x405, 0, 0, 0, 0, 0, 0), | ||
158 | D_GATE(CLK_HSR100, "clk_hsr100", CLKOUT_D10, 0x483, 0, 0, 0, 0, 0, 0), | ||
159 | D_GATE(CLK_I2C0, "clk_i2c0", DIV_I2C, 0x1e6, 0x1e7, 0, 0, 0, 0, 0), | ||
160 | D_GATE(CLK_I2C1, "clk_i2c1", DIV_I2C, 0x1e8, 0x1e9, 0, 0, 0, 0, 0), | ||
161 | D_GATE(CLK_MII_REF, "clk_mii_ref", CLKOUT_D40, 0x342, 0, 0, 0, 0, 0, 0), | ||
162 | D_GATE(CLK_NAND, "clk_nand", DIV_NAND, 0x284, 0x285, 0, 0, 0, 0, 0), | ||
163 | D_GATE(CLK_NOUSBP2_PG6, "clk_nousbp2_pg6", DIV_P2_PG, 0x774, 0x775, 0, 0, 0, 0, 0), | ||
164 | D_GATE(CLK_P1_PG2, "clk_p1_pg2", DIV_P1_PG, 0x862, 0x863, 0, 0, 0, 0, 0), | ||
165 | D_GATE(CLK_P1_PG3, "clk_p1_pg3", DIV_P1_PG, 0x864, 0x865, 0, 0, 0, 0, 0), | ||
166 | D_GATE(CLK_P1_PG4, "clk_p1_pg4", DIV_P1_PG, 0x866, 0x867, 0, 0, 0, 0, 0), | ||
167 | D_GATE(CLK_P4_PG3, "clk_p4_pg3", DIV_P4_PG, 0x824, 0x825, 0, 0, 0, 0, 0), | ||
168 | D_GATE(CLK_P4_PG4, "clk_p4_pg4", DIV_P4_PG, 0x826, 0x827, 0, 0, 0, 0, 0), | ||
169 | D_GATE(CLK_P6_PG1, "clk_p6_pg1", DIV_P6_PG, 0x8a0, 0x8a1, 0x8a2, 0, 0xb60, 0, 0), | ||
170 | D_GATE(CLK_P6_PG2, "clk_p6_pg2", DIV_P6_PG, 0x8a3, 0x8a4, 0x8a5, 0, 0xb61, 0, 0), | ||
171 | D_GATE(CLK_P6_PG3, "clk_p6_pg3", DIV_P6_PG, 0x8a6, 0x8a7, 0x8a8, 0, 0xb62, 0, 0), | ||
172 | D_GATE(CLK_P6_PG4, "clk_p6_pg4", DIV_P6_PG, 0x8a9, 0x8aa, 0x8ab, 0, 0xb63, 0, 0), | ||
173 | D_GATE(CLK_QSPI0, "clk_qspi0", DIV_QSPI0, 0x2a4, 0x2a5, 0, 0, 0, 0, 0), | ||
174 | D_GATE(CLK_QSPI1, "clk_qspi1", DIV_QSPI1, 0x484, 0x485, 0, 0, 0, 0, 0), | ||
175 | D_GATE(CLK_RGMII_REF, "clk_rgmii_ref", CLKOUT_D8, 0x340, 0, 0, 0, 0, 0, 0), | ||
176 | D_GATE(CLK_RMII_REF, "clk_rmii_ref", CLKOUT_D20, 0x341, 0, 0, 0, 0, 0, 0), | ||
177 | D_GATE(CLK_SDIO0, "clk_sdio0", DIV_SDIO0, 0x64, 0, 0, 0, 0, 0, 0), | ||
178 | D_GATE(CLK_SDIO1, "clk_sdio1", DIV_SDIO1, 0x644, 0, 0, 0, 0, 0, 0), | ||
179 | D_GATE(CLK_SERCOS100, "clk_sercos100", CLKOUT_D10, 0x425, 0, 0, 0, 0, 0, 0), | ||
180 | D_GATE(CLK_SLCD, "clk_slcd", DIV_P1_PG, 0x860, 0x861, 0, 0, 0, 0, 0), | ||
181 | D_GATE(CLK_SPI0, "clk_spi0", DIV_P3_PG, 0x7e0, 0x7e1, 0, 0, 0, 0, 0), | ||
182 | D_GATE(CLK_SPI1, "clk_spi1", DIV_P3_PG, 0x7e2, 0x7e3, 0, 0, 0, 0, 0), | ||
183 | D_GATE(CLK_SPI2, "clk_spi2", DIV_P3_PG, 0x7e4, 0x7e5, 0, 0, 0, 0, 0), | ||
184 | D_GATE(CLK_SPI3, "clk_spi3", DIV_P3_PG, 0x7e6, 0x7e7, 0, 0, 0, 0, 0), | ||
185 | D_GATE(CLK_SPI4, "clk_spi4", DIV_P4_PG, 0x820, 0x821, 0, 0, 0, 0, 0), | ||
186 | D_GATE(CLK_SPI5, "clk_spi5", DIV_P4_PG, 0x822, 0x823, 0, 0, 0, 0, 0), | ||
187 | D_GATE(CLK_SWITCH, "clk_switch", DIV_SWITCH, 0x982, 0x983, 0, 0, 0, 0, 0), | ||
188 | D_DIV(DIV_MOTOR, "div_motor", CLKOUT_D5, 84, 2, 8), | ||
189 | D_GATE(HCLK_ECAT125, "hclk_ecat125", CLKOUT_D8, 0x400, 0x401, 0, 0x402, 0, 0x440, 0x441), | ||
190 | D_GATE(HCLK_PINCONFIG, "hclk_pinconfig", CLKOUT_D40, 0x740, 0x741, 0x742, 0, 0xae0, 0, 0), | ||
191 | D_GATE(HCLK_SERCOS, "hclk_sercos", CLKOUT_D10, 0x420, 0x422, 0, 0x421, 0, 0x460, 0x461), | ||
192 | D_GATE(HCLK_SGPIO2, "hclk_sgpio2", DIV_P5_PG, 0x8c3, 0x8c4, 0x8c5, 0, 0xb41, 0, 0), | ||
193 | D_GATE(HCLK_SGPIO3, "hclk_sgpio3", DIV_P5_PG, 0x8c6, 0x8c7, 0x8c8, 0, 0xb42, 0, 0), | ||
194 | D_GATE(HCLK_SGPIO4, "hclk_sgpio4", DIV_P5_PG, 0x8c9, 0x8ca, 0x8cb, 0, 0xb43, 0, 0), | ||
195 | D_GATE(HCLK_TIMER0, "hclk_timer0", CLKOUT_D40, 0x743, 0x744, 0x745, 0, 0xae1, 0, 0), | ||
196 | D_GATE(HCLK_TIMER1, "hclk_timer1", CLKOUT_D40, 0x746, 0x747, 0x748, 0, 0xae2, 0, 0), | ||
197 | D_GATE(HCLK_USBF, "hclk_usbf", CLKOUT_D8, 0xe3, 0, 0, 0xe4, 0, 0x102, 0x103), | ||
198 | D_GATE(HCLK_USBH, "hclk_usbh", CLKOUT_D8, 0xe0, 0xe1, 0, 0xe2, 0, 0x100, 0x101), | ||
199 | D_GATE(HCLK_USBPM, "hclk_usbpm", CLKOUT_D8, 0xe5, 0, 0, 0, 0, 0, 0), | ||
200 | D_GATE(CLK_48_PG_F, "clk_48_pg_f", CLK_48, 0x78c, 0x78d, 0, 0x78e, 0, 0xb04, 0xb05), | ||
201 | D_GATE(CLK_48_PG4, "clk_48_pg4", CLK_48, 0x789, 0x78a, 0x78b, 0, 0xb03, 0, 0), | ||
202 | D_FFC(CLK_DDRPHY_PLLCLK_D4, "clk_ddrphy_pllclk_d4", CLK_DDRPHY_PLLCLK, 4), | ||
203 | D_FFC(CLK_ECAT100_D4, "clk_ecat100_d4", CLK_ECAT100, 4), | ||
204 | D_FFC(CLK_HSR100_D2, "clk_hsr100_d2", CLK_HSR100, 2), | ||
205 | D_FFC(CLK_REF_SYNC_D4, "clk_ref_sync_d4", CLK_REF_SYNC, 4), | ||
206 | D_FFC(CLK_REF_SYNC_D8, "clk_ref_sync_d8", CLK_REF_SYNC, 8), | ||
207 | D_FFC(CLK_SERCOS100_D2, "clk_sercos100_d2", CLK_SERCOS100, 2), | ||
208 | D_DIV(DIV_CA7, "div_ca7", CLK_REF_SYNC, 57, 1, 4, 1, 2, 4), | ||
209 | D_GATE(HCLK_CAN0, "hclk_can0", CLK_48, 0x783, 0x784, 0x785, 0, 0xb01, 0, 0), | ||
210 | D_GATE(HCLK_CAN1, "hclk_can1", CLK_48, 0x786, 0x787, 0x788, 0, 0xb02, 0, 0), | ||
211 | D_GATE(HCLK_DELTASIGMA, "hclk_deltasigma", DIV_MOTOR, 0x1ef, 0x1f0, 0x1f1, 0, 0, 0, 0), | ||
212 | D_GATE(HCLK_PWMPTO, "hclk_pwmpto", DIV_MOTOR, 0x1ec, 0x1ed, 0x1ee, 0, 0, 0, 0), | ||
213 | D_GATE(HCLK_RSV, "hclk_rsv", CLK_48, 0x780, 0x781, 0x782, 0, 0xb00, 0, 0), | ||
214 | D_GATE(HCLK_SGPIO0, "hclk_sgpio0", DIV_MOTOR, 0x1e0, 0x1e1, 0x1e2, 0, 0, 0, 0), | ||
215 | D_GATE(HCLK_SGPIO1, "hclk_sgpio1", DIV_MOTOR, 0x1e3, 0x1e4, 0x1e5, 0, 0, 0, 0), | ||
216 | D_DIV(RTOS_MDC, "rtos_mdc", CLK_REF_SYNC, 100, 80, 640, 80, 160, 320, 640), | ||
217 | D_GATE(CLK_CM3, "clk_cm3", CLK_REF_SYNC_D4, 0xba0, 0xba1, 0, 0xba2, 0, 0xbc0, 0xbc1), | ||
218 | D_GATE(CLK_DDRC, "clk_ddrc", CLK_DDRPHY_PLLCLK_D4, 0x323, 0x324, 0, 0, 0, 0, 0), | ||
219 | D_GATE(CLK_ECAT25, "clk_ecat25", CLK_ECAT100_D4, 0x403, 0x404, 0, 0, 0, 0, 0), | ||
220 | D_GATE(CLK_HSR50, "clk_hsr50", CLK_HSR100_D2, 0x484, 0x485, 0, 0, 0, 0, 0), | ||
221 | D_GATE(CLK_HW_RTOS, "clk_hw_rtos", CLK_REF_SYNC_D4, 0xc60, 0xc61, 0, 0, 0, 0, 0), | ||
222 | D_GATE(CLK_SERCOS50, "clk_sercos50", CLK_SERCOS100_D2, 0x424, 0x423, 0, 0, 0, 0, 0), | ||
223 | D_GATE(HCLK_ADC, "hclk_adc", CLK_REF_SYNC_D8, 0x1af, 0x1b0, 0x1b1, 0, 0, 0, 0), | ||
224 | D_GATE(HCLK_CM3, "hclk_cm3", CLK_REF_SYNC_D4, 0xc20, 0xc21, 0xc22, 0, 0, 0, 0), | ||
225 | D_GATE(HCLK_CRYPTO_EIP150, "hclk_crypto_eip150", CLK_REF_SYNC_D4, 0x123, 0x124, 0x125, 0, 0x142, 0, 0), | ||
226 | D_GATE(HCLK_CRYPTO_EIP93, "hclk_crypto_eip93", CLK_REF_SYNC_D4, 0x120, 0x121, 0, 0x122, 0, 0x140, 0x141), | ||
227 | D_GATE(HCLK_DDRC, "hclk_ddrc", CLK_REF_SYNC_D4, 0x320, 0x322, 0, 0x321, 0, 0x3a0, 0x3a1), | ||
228 | D_GATE(HCLK_DMA0, "hclk_dma0", CLK_REF_SYNC_D4, 0x260, 0x261, 0x262, 0x263, 0x2c0, 0x2c1, 0x2c2), | ||
229 | D_GATE(HCLK_DMA1, "hclk_dma1", CLK_REF_SYNC_D4, 0x264, 0x265, 0x266, 0x267, 0x2c3, 0x2c4, 0x2c5), | ||
230 | D_GATE(HCLK_GMAC0, "hclk_gmac0", CLK_REF_SYNC_D4, 0x360, 0x361, 0x362, 0x363, 0x3c0, 0x3c1, 0x3c2), | ||
231 | D_GATE(HCLK_GMAC1, "hclk_gmac1", CLK_REF_SYNC_D4, 0x380, 0x381, 0x382, 0x383, 0x3e0, 0x3e1, 0x3e2), | ||
232 | D_GATE(HCLK_GPIO0, "hclk_gpio0", CLK_REF_SYNC_D4, 0x212, 0x213, 0x214, 0, 0, 0, 0), | ||
233 | D_GATE(HCLK_GPIO1, "hclk_gpio1", CLK_REF_SYNC_D4, 0x215, 0x216, 0x217, 0, 0, 0, 0), | ||
234 | D_GATE(HCLK_GPIO2, "hclk_gpio2", CLK_REF_SYNC_D4, 0x229, 0x22a, 0x22b, 0, 0, 0, 0), | ||
235 | D_GATE(HCLK_HSR, "hclk_hsr", CLK_HSR100_D2, 0x480, 0x482, 0, 0x481, 0, 0x4c0, 0x4c1), | ||
236 | D_GATE(HCLK_I2C0, "hclk_i2c0", CLK_REF_SYNC_D8, 0x1a9, 0x1aa, 0x1ab, 0, 0, 0, 0), | ||
237 | D_GATE(HCLK_I2C1, "hclk_i2c1", CLK_REF_SYNC_D8, 0x1ac, 0x1ad, 0x1ae, 0, 0, 0, 0), | ||
238 | D_GATE(HCLK_LCD, "hclk_lcd", CLK_REF_SYNC_D4, 0x7a0, 0x7a1, 0x7a2, 0, 0xb20, 0, 0), | ||
239 | D_GATE(HCLK_MSEBI_M, "hclk_msebi_m", CLK_REF_SYNC_D4, 0x164, 0x165, 0x166, 0, 0x183, 0, 0), | ||
240 | D_GATE(HCLK_MSEBI_S, "hclk_msebi_s", CLK_REF_SYNC_D4, 0x160, 0x161, 0x162, 0x163, 0x180, 0x181, 0x182), | ||
241 | D_GATE(HCLK_NAND, "hclk_nand", CLK_REF_SYNC_D4, 0x280, 0x281, 0x282, 0x283, 0x2e0, 0x2e1, 0x2e2), | ||
242 | D_GATE(HCLK_PG_I, "hclk_pg_i", CLK_REF_SYNC_D4, 0x7ac, 0x7ad, 0, 0x7ae, 0, 0xb24, 0xb25), | ||
243 | D_GATE(HCLK_PG19, "hclk_pg19", CLK_REF_SYNC_D4, 0x22c, 0x22d, 0x22e, 0, 0, 0, 0), | ||
244 | D_GATE(HCLK_PG20, "hclk_pg20", CLK_REF_SYNC_D4, 0x22f, 0x230, 0x231, 0, 0, 0, 0), | ||
245 | D_GATE(HCLK_PG3, "hclk_pg3", CLK_REF_SYNC_D4, 0x7a6, 0x7a7, 0x7a8, 0, 0xb22, 0, 0), | ||
246 | D_GATE(HCLK_PG4, "hclk_pg4", CLK_REF_SYNC_D4, 0x7a9, 0x7aa, 0x7ab, 0, 0xb23, 0, 0), | ||
247 | D_GATE(HCLK_QSPI0, "hclk_qspi0", CLK_REF_SYNC_D4, 0x2a0, 0x2a1, 0x2a2, 0x2a3, 0x300, 0x301, 0x302), | ||
248 | D_GATE(HCLK_QSPI1, "hclk_qspi1", CLK_REF_SYNC_D4, 0x480, 0x481, 0x482, 0x483, 0x4c0, 0x4c1, 0x4c2), | ||
249 | D_GATE(HCLK_ROM, "hclk_rom", CLK_REF_SYNC_D4, 0xaa0, 0xaa1, 0xaa2, 0, 0xb80, 0, 0), | ||
250 | D_GATE(HCLK_RTC, "hclk_rtc", CLK_REF_SYNC_D8, 0xa00, 0, 0, 0, 0, 0, 0), | ||
251 | D_GATE(HCLK_SDIO0, "hclk_sdio0", CLK_REF_SYNC_D4, 0x60, 0x61, 0x62, 0x63, 0x80, 0x81, 0x82), | ||
252 | D_GATE(HCLK_SDIO1, "hclk_sdio1", CLK_REF_SYNC_D4, 0x640, 0x641, 0x642, 0x643, 0x660, 0x661, 0x662), | ||
253 | D_GATE(HCLK_SEMAP, "hclk_semap", CLK_REF_SYNC_D4, 0x7a3, 0x7a4, 0x7a5, 0, 0xb21, 0, 0), | ||
254 | D_GATE(HCLK_SPI0, "hclk_spi0", CLK_REF_SYNC_D4, 0x200, 0x201, 0x202, 0, 0, 0, 0), | ||
255 | D_GATE(HCLK_SPI1, "hclk_spi1", CLK_REF_SYNC_D4, 0x203, 0x204, 0x205, 0, 0, 0, 0), | ||
256 | D_GATE(HCLK_SPI2, "hclk_spi2", CLK_REF_SYNC_D4, 0x206, 0x207, 0x208, 0, 0, 0, 0), | ||
257 | D_GATE(HCLK_SPI3, "hclk_spi3", CLK_REF_SYNC_D4, 0x209, 0x20a, 0x20b, 0, 0, 0, 0), | ||
258 | D_GATE(HCLK_SPI4, "hclk_spi4", CLK_REF_SYNC_D4, 0x20c, 0x20d, 0x20e, 0, 0, 0, 0), | ||
259 | D_GATE(HCLK_SPI5, "hclk_spi5", CLK_REF_SYNC_D4, 0x20f, 0x210, 0x211, 0, 0, 0, 0), | ||
260 | D_GATE(HCLK_SWITCH, "hclk_switch", CLK_REF_SYNC_D4, 0x980, 0, 0x981, 0, 0, 0, 0), | ||
261 | D_GATE(HCLK_SWITCH_RG, "hclk_switch_rg", CLK_REF_SYNC_D4, 0xc40, 0xc41, 0xc42, 0, 0, 0, 0), | ||
262 | D_GATE(HCLK_UART0, "hclk_uart0", CLK_REF_SYNC_D8, 0x1a0, 0x1a1, 0x1a2, 0, 0, 0, 0), | ||
263 | D_GATE(HCLK_UART1, "hclk_uart1", CLK_REF_SYNC_D8, 0x1a3, 0x1a4, 0x1a5, 0, 0, 0, 0), | ||
264 | D_GATE(HCLK_UART2, "hclk_uart2", CLK_REF_SYNC_D8, 0x1a6, 0x1a7, 0x1a8, 0, 0, 0, 0), | ||
265 | D_GATE(HCLK_UART3, "hclk_uart3", CLK_REF_SYNC_D4, 0x218, 0x219, 0x21a, 0, 0, 0, 0), | ||
266 | D_GATE(HCLK_UART4, "hclk_uart4", CLK_REF_SYNC_D4, 0x21b, 0x21c, 0x21d, 0, 0, 0, 0), | ||
267 | D_GATE(HCLK_UART5, "hclk_uart5", CLK_REF_SYNC_D4, 0x220, 0x221, 0x222, 0, 0, 0, 0), | ||
268 | D_GATE(HCLK_UART6, "hclk_uart6", CLK_REF_SYNC_D4, 0x223, 0x224, 0x225, 0, 0, 0, 0), | ||
269 | D_GATE(HCLK_UART7, "hclk_uart7", CLK_REF_SYNC_D4, 0x226, 0x227, 0x228, 0, 0, 0, 0), | ||
270 | /* | ||
271 | * These are not hardware clocks, but are needed to handle the special | ||
272 | * case where we have a 'selector bit' that doesn't just change the | ||
273 | * parent for a clock, but also the gate it's suposed to use. | ||
274 | */ | ||
275 | { | ||
276 | .index = R9A06G032_UART_GROUP_012, | ||
277 | .name = "uart_group_012", | ||
278 | .type = K_BITSEL, | ||
279 | .source = 1 + R9A06G032_DIV_UART, | ||
280 | /* R9A06G032_SYSCTRL_REG_PWRCTRL_PG1_PR2 */ | ||
281 | .dual.sel = ((0xec / 4) << 5) | 24, | ||
282 | .dual.group = 0, | ||
283 | }, | ||
284 | { | ||
285 | .index = R9A06G032_UART_GROUP_34567, | ||
286 | .name = "uart_group_34567", | ||
287 | .type = K_BITSEL, | ||
288 | .source = 1 + R9A06G032_DIV_P2_PG, | ||
289 | /* R9A06G032_SYSCTRL_REG_PWRCTRL_PG0_0 */ | ||
290 | .dual.sel = ((0x34 / 4) << 5) | 30, | ||
291 | .dual.group = 1, | ||
292 | }, | ||
293 | D_UGATE(CLK_UART0, "clk_uart0", UART_GROUP_012, 0, 0, 0x1b2, 0x1b3, 0x1b4, 0x1b5), | ||
294 | D_UGATE(CLK_UART1, "clk_uart1", UART_GROUP_012, 0, 1, 0x1b6, 0x1b7, 0x1b8, 0x1b9), | ||
295 | D_UGATE(CLK_UART2, "clk_uart2", UART_GROUP_012, 0, 2, 0x1ba, 0x1bb, 0x1bc, 0x1bd), | ||
296 | D_UGATE(CLK_UART3, "clk_uart3", UART_GROUP_34567, 1, 0, 0x760, 0x761, 0x762, 0x763), | ||
297 | D_UGATE(CLK_UART4, "clk_uart4", UART_GROUP_34567, 1, 1, 0x764, 0x765, 0x766, 0x767), | ||
298 | D_UGATE(CLK_UART5, "clk_uart5", UART_GROUP_34567, 1, 2, 0x768, 0x769, 0x76a, 0x76b), | ||
299 | D_UGATE(CLK_UART6, "clk_uart6", UART_GROUP_34567, 1, 3, 0x76c, 0x76d, 0x76e, 0x76f), | ||
300 | D_UGATE(CLK_UART7, "clk_uart7", UART_GROUP_34567, 1, 4, 0x770, 0x771, 0x772, 0x773), | ||
301 | }; | ||
302 | |||
303 | struct r9a06g032_priv { | ||
304 | struct clk_onecell_data data; | ||
305 | spinlock_t lock; /* protects concurent access to gates */ | ||
306 | void __iomem *reg; | ||
307 | }; | ||
308 | |||
309 | /* register/bit pairs are encoded as an uint16_t */ | ||
310 | static void | ||
311 | clk_rdesc_set(struct r9a06g032_priv *clocks, | ||
312 | u16 one, unsigned int on) | ||
313 | { | ||
314 | u32 __iomem *reg = clocks->reg + (4 * (one >> 5)); | ||
315 | u32 val = readl(reg); | ||
316 | |||
317 | val = (val & ~(1U << (one & 0x1f))) | ((!!on) << (one & 0x1f)); | ||
318 | writel(val, reg); | ||
319 | } | ||
320 | |||
321 | static int | ||
322 | clk_rdesc_get(struct r9a06g032_priv *clocks, | ||
323 | uint16_t one) | ||
324 | { | ||
325 | u32 __iomem *reg = clocks->reg + (4 * (one >> 5)); | ||
326 | u32 val = readl(reg); | ||
327 | |||
328 | return !!(val & (1U << (one & 0x1f))); | ||
329 | } | ||
330 | |||
331 | /* | ||
332 | * This implements the R9A09G032 clock gate 'driver'. We cannot use the system's | ||
333 | * clock gate framework as the gates on the R9A09G032 have a special enabling | ||
334 | * sequence, therefore we use this little proxy. | ||
335 | */ | ||
336 | struct r9a06g032_clk_gate { | ||
337 | struct clk_hw hw; | ||
338 | struct r9a06g032_priv *clocks; | ||
339 | u16 index; | ||
340 | |||
341 | struct r9a06g032_gate gate; | ||
342 | }; | ||
343 | |||
344 | #define to_r9a06g032_gate(_hw) container_of(_hw, struct r9a06g032_clk_gate, hw) | ||
345 | |||
346 | static void | ||
347 | r9a06g032_clk_gate_set(struct r9a06g032_priv *clocks, | ||
348 | struct r9a06g032_gate *g, int on) | ||
349 | { | ||
350 | unsigned long flags; | ||
351 | |||
352 | WARN_ON(!g->gate); | ||
353 | |||
354 | spin_lock_irqsave(&clocks->lock, flags); | ||
355 | clk_rdesc_set(clocks, g->gate, on); | ||
356 | /* De-assert reset */ | ||
357 | if (g->reset) | ||
358 | clk_rdesc_set(clocks, g->reset, 1); | ||
359 | spin_unlock_irqrestore(&clocks->lock, flags); | ||
360 | |||
361 | /* Hardware manual recommends 5us delay after enabling clock & reset */ | ||
362 | udelay(5); | ||
363 | |||
364 | /* If the peripheral is memory mapped (i.e. an AXI slave), there is an | ||
365 | * associated SLVRDY bit in the System Controller that needs to be set | ||
366 | * so that the FlexWAY bus fabric passes on the read/write requests. | ||
367 | */ | ||
368 | if (g->ready || g->midle) { | ||
369 | spin_lock_irqsave(&clocks->lock, flags); | ||
370 | if (g->ready) | ||
371 | clk_rdesc_set(clocks, g->ready, on); | ||
372 | /* Clear 'Master Idle Request' bit */ | ||
373 | if (g->midle) | ||
374 | clk_rdesc_set(clocks, g->midle, !on); | ||
375 | spin_unlock_irqrestore(&clocks->lock, flags); | ||
376 | } | ||
377 | /* Note: We don't wait for FlexWAY Socket Connection signal */ | ||
378 | } | ||
379 | |||
380 | static int r9a06g032_clk_gate_enable(struct clk_hw *hw) | ||
381 | { | ||
382 | struct r9a06g032_clk_gate *g = to_r9a06g032_gate(hw); | ||
383 | |||
384 | r9a06g032_clk_gate_set(g->clocks, &g->gate, 1); | ||
385 | return 0; | ||
386 | } | ||
387 | |||
388 | static void r9a06g032_clk_gate_disable(struct clk_hw *hw) | ||
389 | { | ||
390 | struct r9a06g032_clk_gate *g = to_r9a06g032_gate(hw); | ||
391 | |||
392 | r9a06g032_clk_gate_set(g->clocks, &g->gate, 0); | ||
393 | } | ||
394 | |||
395 | static int r9a06g032_clk_gate_is_enabled(struct clk_hw *hw) | ||
396 | { | ||
397 | struct r9a06g032_clk_gate *g = to_r9a06g032_gate(hw); | ||
398 | |||
399 | /* if clock is in reset, the gate might be on, and still not 'be' on */ | ||
400 | if (g->gate.reset && !clk_rdesc_get(g->clocks, g->gate.reset)) | ||
401 | return 0; | ||
402 | |||
403 | return clk_rdesc_get(g->clocks, g->gate.gate); | ||
404 | } | ||
405 | |||
406 | static const struct clk_ops r9a06g032_clk_gate_ops = { | ||
407 | .enable = r9a06g032_clk_gate_enable, | ||
408 | .disable = r9a06g032_clk_gate_disable, | ||
409 | .is_enabled = r9a06g032_clk_gate_is_enabled, | ||
410 | }; | ||
411 | |||
412 | static struct clk * | ||
413 | r9a06g032_register_gate(struct r9a06g032_priv *clocks, | ||
414 | const char *parent_name, | ||
415 | const struct r9a06g032_clkdesc *desc) | ||
416 | { | ||
417 | struct clk *clk; | ||
418 | struct r9a06g032_clk_gate *g; | ||
419 | struct clk_init_data init; | ||
420 | |||
421 | g = kzalloc(sizeof(*g), GFP_KERNEL); | ||
422 | if (!g) | ||
423 | return NULL; | ||
424 | |||
425 | init.name = desc->name; | ||
426 | init.ops = &r9a06g032_clk_gate_ops; | ||
427 | init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT; | ||
428 | init.parent_names = parent_name ? &parent_name : NULL; | ||
429 | init.num_parents = parent_name ? 1 : 0; | ||
430 | |||
431 | g->clocks = clocks; | ||
432 | g->index = desc->index; | ||
433 | g->gate = desc->gate; | ||
434 | g->hw.init = &init; | ||
435 | |||
436 | /* | ||
437 | * important here, some clocks are already in use by the CM3, we | ||
438 | * have to assume they are not Linux's to play with and try to disable | ||
439 | * at the end of the boot! | ||
440 | */ | ||
441 | if (r9a06g032_clk_gate_is_enabled(&g->hw)) { | ||
442 | init.flags |= CLK_IS_CRITICAL; | ||
443 | pr_debug("%s was enabled, making read-only\n", desc->name); | ||
444 | } | ||
445 | |||
446 | clk = clk_register(NULL, &g->hw); | ||
447 | if (IS_ERR(clk)) { | ||
448 | kfree(g); | ||
449 | return NULL; | ||
450 | } | ||
451 | return clk; | ||
452 | } | ||
453 | |||
454 | struct r9a06g032_clk_div { | ||
455 | struct clk_hw hw; | ||
456 | struct r9a06g032_priv *clocks; | ||
457 | u16 index; | ||
458 | u16 reg; | ||
459 | u16 min, max; | ||
460 | u8 table_size; | ||
461 | u16 table[8]; /* we know there are no more than 8 */ | ||
462 | }; | ||
463 | |||
464 | #define to_r9a06g032_div(_hw) \ | ||
465 | container_of(_hw, struct r9a06g032_clk_div, hw) | ||
466 | |||
467 | static unsigned long | ||
468 | r9a06g032_div_recalc_rate(struct clk_hw *hw, | ||
469 | unsigned long parent_rate) | ||
470 | { | ||
471 | struct r9a06g032_clk_div *clk = to_r9a06g032_div(hw); | ||
472 | u32 __iomem *reg = clk->clocks->reg + (4 * clk->reg); | ||
473 | u32 div = readl(reg); | ||
474 | |||
475 | if (div < clk->min) | ||
476 | div = clk->min; | ||
477 | else if (div > clk->max) | ||
478 | div = clk->max; | ||
479 | return DIV_ROUND_UP(parent_rate, div); | ||
480 | } | ||
481 | |||
482 | /* | ||
483 | * Attempts to find a value that is in range of min,max, | ||
484 | * and if a table of set dividers was specified for this | ||
485 | * register, try to find the fixed divider that is the closest | ||
486 | * to the target frequency | ||
487 | */ | ||
488 | static long | ||
489 | r9a06g032_div_clamp_div(struct r9a06g032_clk_div *clk, | ||
490 | unsigned long rate, unsigned long prate) | ||
491 | { | ||
492 | /* + 1 to cope with rates that have the remainder dropped */ | ||
493 | u32 div = DIV_ROUND_UP(prate, rate + 1); | ||
494 | int i; | ||
495 | |||
496 | if (div <= clk->min) | ||
497 | return clk->min; | ||
498 | if (div >= clk->max) | ||
499 | return clk->max; | ||
500 | |||
501 | for (i = 0; clk->table_size && i < clk->table_size - 1; i++) { | ||
502 | if (div >= clk->table[i] && div <= clk->table[i + 1]) { | ||
503 | unsigned long m = rate - | ||
504 | DIV_ROUND_UP(prate, clk->table[i]); | ||
505 | unsigned long p = | ||
506 | DIV_ROUND_UP(prate, clk->table[i + 1]) - | ||
507 | rate; | ||
508 | /* | ||
509 | * select the divider that generates | ||
510 | * the value closest to the ideal frequency | ||
511 | */ | ||
512 | div = p >= m ? clk->table[i] : clk->table[i + 1]; | ||
513 | return div; | ||
514 | } | ||
515 | } | ||
516 | return div; | ||
517 | } | ||
518 | |||
519 | static long | ||
520 | r9a06g032_div_round_rate(struct clk_hw *hw, | ||
521 | unsigned long rate, unsigned long *prate) | ||
522 | { | ||
523 | struct r9a06g032_clk_div *clk = to_r9a06g032_div(hw); | ||
524 | u32 div = DIV_ROUND_UP(*prate, rate); | ||
525 | |||
526 | pr_devel("%s %pC %ld (prate %ld) (wanted div %u)\n", __func__, | ||
527 | hw->clk, rate, *prate, div); | ||
528 | pr_devel(" min %d (%ld) max %d (%ld)\n", | ||
529 | clk->min, DIV_ROUND_UP(*prate, clk->min), | ||
530 | clk->max, DIV_ROUND_UP(*prate, clk->max)); | ||
531 | |||
532 | div = r9a06g032_div_clamp_div(clk, rate, *prate); | ||
533 | /* | ||
534 | * this is a hack. Currently the serial driver asks for a clock rate | ||
535 | * that is 16 times the baud rate -- and that is wildly outside the | ||
536 | * range of the UART divider, somehow there is no provision for that | ||
537 | * case of 'let the divider as is if outside range'. | ||
538 | * The serial driver *shouldn't* play with these clocks anyway, there's | ||
539 | * several uarts attached to this divider, and changing this impacts | ||
540 | * everyone. | ||
541 | */ | ||
542 | if (clk->index == R9A06G032_DIV_UART) { | ||
543 | pr_devel("%s div uart hack!\n", __func__); | ||
544 | return clk_get_rate(hw->clk); | ||
545 | } | ||
546 | pr_devel("%s %pC %ld / %u = %ld\n", __func__, hw->clk, | ||
547 | *prate, div, DIV_ROUND_UP(*prate, div)); | ||
548 | return DIV_ROUND_UP(*prate, div); | ||
549 | } | ||
550 | |||
551 | static int | ||
552 | r9a06g032_div_set_rate(struct clk_hw *hw, | ||
553 | unsigned long rate, unsigned long parent_rate) | ||
554 | { | ||
555 | struct r9a06g032_clk_div *clk = to_r9a06g032_div(hw); | ||
556 | /* + 1 to cope with rates that have the remainder dropped */ | ||
557 | u32 div = DIV_ROUND_UP(parent_rate, rate + 1); | ||
558 | u32 __iomem *reg = clk->clocks->reg + (4 * clk->reg); | ||
559 | |||
560 | pr_devel("%s %pC rate %ld parent %ld div %d\n", __func__, hw->clk, | ||
561 | rate, parent_rate, div); | ||
562 | |||
563 | /* | ||
564 | * Need to write the bit 31 with the divider value to | ||
565 | * latch it. Technically we should wait until it has been | ||
566 | * cleared too. | ||
567 | * TODO: Find whether this callback is sleepable, in case | ||
568 | * the hardware /does/ require some sort of spinloop here. | ||
569 | */ | ||
570 | writel(div | BIT(31), reg); | ||
571 | |||
572 | return 0; | ||
573 | } | ||
574 | |||
575 | static const struct clk_ops r9a06g032_clk_div_ops = { | ||
576 | .recalc_rate = r9a06g032_div_recalc_rate, | ||
577 | .round_rate = r9a06g032_div_round_rate, | ||
578 | .set_rate = r9a06g032_div_set_rate, | ||
579 | }; | ||
580 | |||
581 | static struct clk * | ||
582 | r9a06g032_register_div(struct r9a06g032_priv *clocks, | ||
583 | const char *parent_name, | ||
584 | const struct r9a06g032_clkdesc *desc) | ||
585 | { | ||
586 | struct r9a06g032_clk_div *div; | ||
587 | struct clk *clk; | ||
588 | struct clk_init_data init; | ||
589 | unsigned int i; | ||
590 | |||
591 | div = kzalloc(sizeof(*div), GFP_KERNEL); | ||
592 | if (!div) | ||
593 | return NULL; | ||
594 | |||
595 | init.name = desc->name; | ||
596 | init.ops = &r9a06g032_clk_div_ops; | ||
597 | init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT; | ||
598 | init.parent_names = parent_name ? &parent_name : NULL; | ||
599 | init.num_parents = parent_name ? 1 : 0; | ||
600 | |||
601 | div->clocks = clocks; | ||
602 | div->index = desc->index; | ||
603 | div->reg = desc->reg; | ||
604 | div->hw.init = &init; | ||
605 | div->min = desc->div_min; | ||
606 | div->max = desc->div_max; | ||
607 | /* populate (optional) divider table fixed values */ | ||
608 | for (i = 0; i < ARRAY_SIZE(div->table) && | ||
609 | i < ARRAY_SIZE(desc->div_table) && desc->div_table[i]; i++) { | ||
610 | div->table[div->table_size++] = desc->div_table[i]; | ||
611 | } | ||
612 | |||
613 | clk = clk_register(NULL, &div->hw); | ||
614 | if (IS_ERR(clk)) { | ||
615 | kfree(div); | ||
616 | return NULL; | ||
617 | } | ||
618 | return clk; | ||
619 | } | ||
620 | |||
621 | /* | ||
622 | * This clock provider handles the case of the R9A06G032 where you have | ||
623 | * peripherals that have two potential clock source and two gates, one for | ||
624 | * each of the clock source - the used clock source (for all sub clocks) | ||
625 | * is selected by a single bit. | ||
626 | * That single bit affects all sub-clocks, and therefore needs to change the | ||
627 | * active gate (and turn the others off) and force a recalculation of the rates. | ||
628 | * | ||
629 | * This implements two clock providers, one 'bitselect' that | ||
630 | * handles the switch between both parents, and another 'dualgate' | ||
631 | * that knows which gate to poke at, depending on the parent's bit position. | ||
632 | */ | ||
633 | struct r9a06g032_clk_bitsel { | ||
634 | struct clk_hw hw; | ||
635 | struct r9a06g032_priv *clocks; | ||
636 | u16 index; | ||
637 | u16 selector; /* selector register + bit */ | ||
638 | }; | ||
639 | |||
640 | #define to_clk_bitselect(_hw) \ | ||
641 | container_of(_hw, struct r9a06g032_clk_bitsel, hw) | ||
642 | |||
643 | static u8 r9a06g032_clk_mux_get_parent(struct clk_hw *hw) | ||
644 | { | ||
645 | struct r9a06g032_clk_bitsel *set = to_clk_bitselect(hw); | ||
646 | |||
647 | return clk_rdesc_get(set->clocks, set->selector); | ||
648 | } | ||
649 | |||
650 | static int r9a06g032_clk_mux_set_parent(struct clk_hw *hw, u8 index) | ||
651 | { | ||
652 | struct r9a06g032_clk_bitsel *set = to_clk_bitselect(hw); | ||
653 | |||
654 | /* a single bit in the register selects one of two parent clocks */ | ||
655 | clk_rdesc_set(set->clocks, set->selector, !!index); | ||
656 | |||
657 | return 0; | ||
658 | } | ||
659 | |||
660 | static const struct clk_ops clk_bitselect_ops = { | ||
661 | .get_parent = r9a06g032_clk_mux_get_parent, | ||
662 | .set_parent = r9a06g032_clk_mux_set_parent, | ||
663 | }; | ||
664 | |||
665 | static struct clk * | ||
666 | r9a06g032_register_bitsel(struct r9a06g032_priv *clocks, | ||
667 | const char *parent_name, | ||
668 | const struct r9a06g032_clkdesc *desc) | ||
669 | { | ||
670 | struct clk *clk; | ||
671 | struct r9a06g032_clk_bitsel *g; | ||
672 | struct clk_init_data init; | ||
673 | const char *names[2]; | ||
674 | |||
675 | /* allocate the gate */ | ||
676 | g = kzalloc(sizeof(*g), GFP_KERNEL); | ||
677 | if (!g) | ||
678 | return NULL; | ||
679 | |||
680 | names[0] = parent_name; | ||
681 | names[1] = "clk_pll_usb"; | ||
682 | |||
683 | init.name = desc->name; | ||
684 | init.ops = &clk_bitselect_ops; | ||
685 | init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT; | ||
686 | init.parent_names = names; | ||
687 | init.num_parents = 2; | ||
688 | |||
689 | g->clocks = clocks; | ||
690 | g->index = desc->index; | ||
691 | g->selector = desc->dual.sel; | ||
692 | g->hw.init = &init; | ||
693 | |||
694 | clk = clk_register(NULL, &g->hw); | ||
695 | if (IS_ERR(clk)) { | ||
696 | kfree(g); | ||
697 | return NULL; | ||
698 | } | ||
699 | return clk; | ||
700 | } | ||
701 | |||
702 | struct r9a06g032_clk_dualgate { | ||
703 | struct clk_hw hw; | ||
704 | struct r9a06g032_priv *clocks; | ||
705 | u16 index; | ||
706 | u16 selector; /* selector register + bit */ | ||
707 | struct r9a06g032_gate gate[2]; | ||
708 | }; | ||
709 | |||
710 | #define to_clk_dualgate(_hw) \ | ||
711 | container_of(_hw, struct r9a06g032_clk_dualgate, hw) | ||
712 | |||
713 | static int | ||
714 | r9a06g032_clk_dualgate_setenable(struct r9a06g032_clk_dualgate *g, int enable) | ||
715 | { | ||
716 | u8 sel_bit = clk_rdesc_get(g->clocks, g->selector); | ||
717 | |||
718 | /* we always turn off the 'other' gate, regardless */ | ||
719 | r9a06g032_clk_gate_set(g->clocks, &g->gate[!sel_bit], 0); | ||
720 | r9a06g032_clk_gate_set(g->clocks, &g->gate[sel_bit], enable); | ||
721 | |||
722 | return 0; | ||
723 | } | ||
724 | |||
725 | static int r9a06g032_clk_dualgate_enable(struct clk_hw *hw) | ||
726 | { | ||
727 | struct r9a06g032_clk_dualgate *gate = to_clk_dualgate(hw); | ||
728 | |||
729 | r9a06g032_clk_dualgate_setenable(gate, 1); | ||
730 | |||
731 | return 0; | ||
732 | } | ||
733 | |||
734 | static void r9a06g032_clk_dualgate_disable(struct clk_hw *hw) | ||
735 | { | ||
736 | struct r9a06g032_clk_dualgate *gate = to_clk_dualgate(hw); | ||
737 | |||
738 | r9a06g032_clk_dualgate_setenable(gate, 0); | ||
739 | } | ||
740 | |||
741 | static int r9a06g032_clk_dualgate_is_enabled(struct clk_hw *hw) | ||
742 | { | ||
743 | struct r9a06g032_clk_dualgate *g = to_clk_dualgate(hw); | ||
744 | u8 sel_bit = clk_rdesc_get(g->clocks, g->selector); | ||
745 | |||
746 | return clk_rdesc_get(g->clocks, g->gate[sel_bit].gate); | ||
747 | } | ||
748 | |||
749 | static const struct clk_ops r9a06g032_clk_dualgate_ops = { | ||
750 | .enable = r9a06g032_clk_dualgate_enable, | ||
751 | .disable = r9a06g032_clk_dualgate_disable, | ||
752 | .is_enabled = r9a06g032_clk_dualgate_is_enabled, | ||
753 | }; | ||
754 | |||
755 | static struct clk * | ||
756 | r9a06g032_register_dualgate(struct r9a06g032_priv *clocks, | ||
757 | const char *parent_name, | ||
758 | const struct r9a06g032_clkdesc *desc, | ||
759 | uint16_t sel) | ||
760 | { | ||
761 | struct r9a06g032_clk_dualgate *g; | ||
762 | struct clk *clk; | ||
763 | struct clk_init_data init; | ||
764 | |||
765 | /* allocate the gate */ | ||
766 | g = kzalloc(sizeof(*g), GFP_KERNEL); | ||
767 | if (!g) | ||
768 | return NULL; | ||
769 | g->clocks = clocks; | ||
770 | g->index = desc->index; | ||
771 | g->selector = sel; | ||
772 | g->gate[0].gate = desc->dual.g1; | ||
773 | g->gate[0].reset = desc->dual.r1; | ||
774 | g->gate[1].gate = desc->dual.g2; | ||
775 | g->gate[1].reset = desc->dual.r2; | ||
776 | |||
777 | init.name = desc->name; | ||
778 | init.ops = &r9a06g032_clk_dualgate_ops; | ||
779 | init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT; | ||
780 | init.parent_names = &parent_name; | ||
781 | init.num_parents = 1; | ||
782 | g->hw.init = &init; | ||
783 | /* | ||
784 | * important here, some clocks are already in use by the CM3, we | ||
785 | * have to assume they are not Linux's to play with and try to disable | ||
786 | * at the end of the boot! | ||
787 | */ | ||
788 | if (r9a06g032_clk_dualgate_is_enabled(&g->hw)) { | ||
789 | init.flags |= CLK_IS_CRITICAL; | ||
790 | pr_debug("%s was enabled, making read-only\n", desc->name); | ||
791 | } | ||
792 | |||
793 | clk = clk_register(NULL, &g->hw); | ||
794 | if (IS_ERR(clk)) { | ||
795 | kfree(g); | ||
796 | return NULL; | ||
797 | } | ||
798 | return clk; | ||
799 | } | ||
800 | |||
801 | static void r9a06g032_clocks_del_clk_provider(void *data) | ||
802 | { | ||
803 | of_clk_del_provider(data); | ||
804 | } | ||
805 | |||
806 | static int __init r9a06g032_clocks_probe(struct platform_device *pdev) | ||
807 | { | ||
808 | struct device *dev = &pdev->dev; | ||
809 | struct device_node *np = dev->of_node; | ||
810 | struct r9a06g032_priv *clocks; | ||
811 | struct clk **clks; | ||
812 | struct clk *mclk; | ||
813 | unsigned int i; | ||
814 | u16 uart_group_sel[2]; | ||
815 | int error; | ||
816 | |||
817 | clocks = devm_kzalloc(dev, sizeof(*clocks), GFP_KERNEL); | ||
818 | clks = devm_kcalloc(dev, R9A06G032_CLOCK_COUNT, sizeof(struct clk *), | ||
819 | GFP_KERNEL); | ||
820 | if (!clocks || !clks) | ||
821 | return -ENOMEM; | ||
822 | |||
823 | spin_lock_init(&clocks->lock); | ||
824 | |||
825 | clocks->data.clks = clks; | ||
826 | clocks->data.clk_num = R9A06G032_CLOCK_COUNT; | ||
827 | |||
828 | mclk = devm_clk_get(dev, "mclk"); | ||
829 | if (IS_ERR(mclk)) | ||
830 | return PTR_ERR(mclk); | ||
831 | |||
832 | clocks->reg = of_iomap(np, 0); | ||
833 | if (WARN_ON(!clocks->reg)) | ||
834 | return -ENOMEM; | ||
835 | for (i = 0; i < ARRAY_SIZE(r9a06g032_clocks); ++i) { | ||
836 | const struct r9a06g032_clkdesc *d = &r9a06g032_clocks[i]; | ||
837 | const char *parent_name = d->source ? | ||
838 | __clk_get_name(clocks->data.clks[d->source - 1]) : | ||
839 | __clk_get_name(mclk); | ||
840 | struct clk *clk = NULL; | ||
841 | |||
842 | switch (d->type) { | ||
843 | case K_FFC: | ||
844 | clk = clk_register_fixed_factor(NULL, d->name, | ||
845 | parent_name, 0, | ||
846 | d->mul, d->div); | ||
847 | break; | ||
848 | case K_GATE: | ||
849 | clk = r9a06g032_register_gate(clocks, parent_name, d); | ||
850 | break; | ||
851 | case K_DIV: | ||
852 | clk = r9a06g032_register_div(clocks, parent_name, d); | ||
853 | break; | ||
854 | case K_BITSEL: | ||
855 | /* keep that selector register around */ | ||
856 | uart_group_sel[d->dual.group] = d->dual.sel; | ||
857 | clk = r9a06g032_register_bitsel(clocks, parent_name, d); | ||
858 | break; | ||
859 | case K_DUALGATE: | ||
860 | clk = r9a06g032_register_dualgate(clocks, parent_name, | ||
861 | d, | ||
862 | uart_group_sel[d->dual.group]); | ||
863 | break; | ||
864 | } | ||
865 | clocks->data.clks[d->index] = clk; | ||
866 | } | ||
867 | error = of_clk_add_provider(np, of_clk_src_onecell_get, &clocks->data); | ||
868 | if (error) | ||
869 | return error; | ||
870 | |||
871 | return devm_add_action_or_reset(dev, | ||
872 | r9a06g032_clocks_del_clk_provider, np); | ||
873 | } | ||
874 | |||
875 | static const struct of_device_id r9a06g032_match[] = { | ||
876 | { .compatible = "renesas,r9a06g032-sysctrl" }, | ||
877 | { } | ||
878 | }; | ||
879 | |||
880 | static struct platform_driver r9a06g032_clock_driver = { | ||
881 | .driver = { | ||
882 | .name = "renesas,r9a06g032-sysctrl", | ||
883 | .of_match_table = r9a06g032_match, | ||
884 | }, | ||
885 | }; | ||
886 | |||
887 | static int __init r9a06g032_clocks_init(void) | ||
888 | { | ||
889 | return platform_driver_probe(&r9a06g032_clock_driver, | ||
890 | r9a06g032_clocks_probe); | ||
891 | } | ||
892 | |||
893 | subsys_initcall(r9a06g032_clocks_init); | ||
diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile index 98e7b9429b83..ff35ab463a6f 100644 --- a/drivers/clk/rockchip/Makefile +++ b/drivers/clk/rockchip/Makefile | |||
@@ -6,12 +6,14 @@ | |||
6 | obj-y += clk.o | 6 | obj-y += clk.o |
7 | obj-y += clk-pll.o | 7 | obj-y += clk-pll.o |
8 | obj-y += clk-cpu.o | 8 | obj-y += clk-cpu.o |
9 | obj-y += clk-half-divider.o | ||
9 | obj-y += clk-inverter.o | 10 | obj-y += clk-inverter.o |
10 | obj-y += clk-mmc-phase.o | 11 | obj-y += clk-mmc-phase.o |
11 | obj-y += clk-muxgrf.o | 12 | obj-y += clk-muxgrf.o |
12 | obj-y += clk-ddr.o | 13 | obj-y += clk-ddr.o |
13 | obj-$(CONFIG_RESET_CONTROLLER) += softrst.o | 14 | obj-$(CONFIG_RESET_CONTROLLER) += softrst.o |
14 | 15 | ||
16 | obj-y += clk-px30.o | ||
15 | obj-y += clk-rv1108.o | 17 | obj-y += clk-rv1108.o |
16 | obj-y += clk-rk3036.o | 18 | obj-y += clk-rk3036.o |
17 | obj-y += clk-rk3128.o | 19 | obj-y += clk-rk3128.o |
diff --git a/drivers/clk/rockchip/clk-half-divider.c b/drivers/clk/rockchip/clk-half-divider.c new file mode 100644 index 000000000000..b8da6e799423 --- /dev/null +++ b/drivers/clk/rockchip/clk-half-divider.c | |||
@@ -0,0 +1,227 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd | ||
4 | */ | ||
5 | |||
6 | #include <linux/slab.h> | ||
7 | #include <linux/clk-provider.h> | ||
8 | #include "clk.h" | ||
9 | |||
10 | #define div_mask(width) ((1 << (width)) - 1) | ||
11 | |||
12 | static bool _is_best_half_div(unsigned long rate, unsigned long now, | ||
13 | unsigned long best, unsigned long flags) | ||
14 | { | ||
15 | if (flags & CLK_DIVIDER_ROUND_CLOSEST) | ||
16 | return abs(rate - now) < abs(rate - best); | ||
17 | |||
18 | return now <= rate && now > best; | ||
19 | } | ||
20 | |||
21 | static unsigned long clk_half_divider_recalc_rate(struct clk_hw *hw, | ||
22 | unsigned long parent_rate) | ||
23 | { | ||
24 | struct clk_divider *divider = to_clk_divider(hw); | ||
25 | unsigned int val; | ||
26 | |||
27 | val = clk_readl(divider->reg) >> divider->shift; | ||
28 | val &= div_mask(divider->width); | ||
29 | val = val * 2 + 3; | ||
30 | |||
31 | return DIV_ROUND_UP_ULL(((u64)parent_rate * 2), val); | ||
32 | } | ||
33 | |||
34 | static int clk_half_divider_bestdiv(struct clk_hw *hw, unsigned long rate, | ||
35 | unsigned long *best_parent_rate, u8 width, | ||
36 | unsigned long flags) | ||
37 | { | ||
38 | unsigned int i, bestdiv = 0; | ||
39 | unsigned long parent_rate, best = 0, now, maxdiv; | ||
40 | unsigned long parent_rate_saved = *best_parent_rate; | ||
41 | |||
42 | if (!rate) | ||
43 | rate = 1; | ||
44 | |||
45 | maxdiv = div_mask(width); | ||
46 | |||
47 | if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) { | ||
48 | parent_rate = *best_parent_rate; | ||
49 | bestdiv = DIV_ROUND_UP_ULL(((u64)parent_rate * 2), rate); | ||
50 | if (bestdiv < 3) | ||
51 | bestdiv = 0; | ||
52 | else | ||
53 | bestdiv = (bestdiv - 3) / 2; | ||
54 | bestdiv = bestdiv > maxdiv ? maxdiv : bestdiv; | ||
55 | return bestdiv; | ||
56 | } | ||
57 | |||
58 | /* | ||
59 | * The maximum divider we can use without overflowing | ||
60 | * unsigned long in rate * i below | ||
61 | */ | ||
62 | maxdiv = min(ULONG_MAX / rate, maxdiv); | ||
63 | |||
64 | for (i = 0; i <= maxdiv; i++) { | ||
65 | if (((u64)rate * (i * 2 + 3)) == ((u64)parent_rate_saved * 2)) { | ||
66 | /* | ||
67 | * It's the most ideal case if the requested rate can be | ||
68 | * divided from parent clock without needing to change | ||
69 | * parent rate, so return the divider immediately. | ||
70 | */ | ||
71 | *best_parent_rate = parent_rate_saved; | ||
72 | return i; | ||
73 | } | ||
74 | parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw), | ||
75 | ((u64)rate * (i * 2 + 3)) / 2); | ||
76 | now = DIV_ROUND_UP_ULL(((u64)parent_rate * 2), | ||
77 | (i * 2 + 3)); | ||
78 | |||
79 | if (_is_best_half_div(rate, now, best, flags)) { | ||
80 | bestdiv = i; | ||
81 | best = now; | ||
82 | *best_parent_rate = parent_rate; | ||
83 | } | ||
84 | } | ||
85 | |||
86 | if (!bestdiv) { | ||
87 | bestdiv = div_mask(width); | ||
88 | *best_parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw), 1); | ||
89 | } | ||
90 | |||
91 | return bestdiv; | ||
92 | } | ||
93 | |||
94 | static long clk_half_divider_round_rate(struct clk_hw *hw, unsigned long rate, | ||
95 | unsigned long *prate) | ||
96 | { | ||
97 | struct clk_divider *divider = to_clk_divider(hw); | ||
98 | int div; | ||
99 | |||
100 | div = clk_half_divider_bestdiv(hw, rate, prate, | ||
101 | divider->width, | ||
102 | divider->flags); | ||
103 | |||
104 | return DIV_ROUND_UP_ULL(((u64)*prate * 2), div * 2 + 3); | ||
105 | } | ||
106 | |||
107 | static int clk_half_divider_set_rate(struct clk_hw *hw, unsigned long rate, | ||
108 | unsigned long parent_rate) | ||
109 | { | ||
110 | struct clk_divider *divider = to_clk_divider(hw); | ||
111 | unsigned int value; | ||
112 | unsigned long flags = 0; | ||
113 | u32 val; | ||
114 | |||
115 | value = DIV_ROUND_UP_ULL(((u64)parent_rate * 2), rate); | ||
116 | value = (value - 3) / 2; | ||
117 | value = min_t(unsigned int, value, div_mask(divider->width)); | ||
118 | |||
119 | if (divider->lock) | ||
120 | spin_lock_irqsave(divider->lock, flags); | ||
121 | else | ||
122 | __acquire(divider->lock); | ||
123 | |||
124 | if (divider->flags & CLK_DIVIDER_HIWORD_MASK) { | ||
125 | val = div_mask(divider->width) << (divider->shift + 16); | ||
126 | } else { | ||
127 | val = clk_readl(divider->reg); | ||
128 | val &= ~(div_mask(divider->width) << divider->shift); | ||
129 | } | ||
130 | val |= value << divider->shift; | ||
131 | clk_writel(val, divider->reg); | ||
132 | |||
133 | if (divider->lock) | ||
134 | spin_unlock_irqrestore(divider->lock, flags); | ||
135 | else | ||
136 | __release(divider->lock); | ||
137 | |||
138 | return 0; | ||
139 | } | ||
140 | |||
141 | const struct clk_ops clk_half_divider_ops = { | ||
142 | .recalc_rate = clk_half_divider_recalc_rate, | ||
143 | .round_rate = clk_half_divider_round_rate, | ||
144 | .set_rate = clk_half_divider_set_rate, | ||
145 | }; | ||
146 | EXPORT_SYMBOL_GPL(clk_half_divider_ops); | ||
147 | |||
148 | /** | ||
149 | * Register a clock branch. | ||
150 | * Most clock branches have a form like | ||
151 | * | ||
152 | * src1 --|--\ | ||
153 | * |M |--[GATE]-[DIV]- | ||
154 | * src2 --|--/ | ||
155 | * | ||
156 | * sometimes without one of those components. | ||
157 | */ | ||
158 | struct clk *rockchip_clk_register_halfdiv(const char *name, | ||
159 | const char *const *parent_names, | ||
160 | u8 num_parents, void __iomem *base, | ||
161 | int muxdiv_offset, u8 mux_shift, | ||
162 | u8 mux_width, u8 mux_flags, | ||
163 | u8 div_shift, u8 div_width, | ||
164 | u8 div_flags, int gate_offset, | ||
165 | u8 gate_shift, u8 gate_flags, | ||
166 | unsigned long flags, | ||
167 | spinlock_t *lock) | ||
168 | { | ||
169 | struct clk *clk; | ||
170 | struct clk_mux *mux = NULL; | ||
171 | struct clk_gate *gate = NULL; | ||
172 | struct clk_divider *div = NULL; | ||
173 | const struct clk_ops *mux_ops = NULL, *div_ops = NULL, | ||
174 | *gate_ops = NULL; | ||
175 | |||
176 | if (num_parents > 1) { | ||
177 | mux = kzalloc(sizeof(*mux), GFP_KERNEL); | ||
178 | if (!mux) | ||
179 | return ERR_PTR(-ENOMEM); | ||
180 | |||
181 | mux->reg = base + muxdiv_offset; | ||
182 | mux->shift = mux_shift; | ||
183 | mux->mask = BIT(mux_width) - 1; | ||
184 | mux->flags = mux_flags; | ||
185 | mux->lock = lock; | ||
186 | mux_ops = (mux_flags & CLK_MUX_READ_ONLY) ? &clk_mux_ro_ops | ||
187 | : &clk_mux_ops; | ||
188 | } | ||
189 | |||
190 | if (gate_offset >= 0) { | ||
191 | gate = kzalloc(sizeof(*gate), GFP_KERNEL); | ||
192 | if (!gate) | ||
193 | goto err_gate; | ||
194 | |||
195 | gate->flags = gate_flags; | ||
196 | gate->reg = base + gate_offset; | ||
197 | gate->bit_idx = gate_shift; | ||
198 | gate->lock = lock; | ||
199 | gate_ops = &clk_gate_ops; | ||
200 | } | ||
201 | |||
202 | if (div_width > 0) { | ||
203 | div = kzalloc(sizeof(*div), GFP_KERNEL); | ||
204 | if (!div) | ||
205 | goto err_div; | ||
206 | |||
207 | div->flags = div_flags; | ||
208 | div->reg = base + muxdiv_offset; | ||
209 | div->shift = div_shift; | ||
210 | div->width = div_width; | ||
211 | div->lock = lock; | ||
212 | div_ops = &clk_half_divider_ops; | ||
213 | } | ||
214 | |||
215 | clk = clk_register_composite(NULL, name, parent_names, num_parents, | ||
216 | mux ? &mux->hw : NULL, mux_ops, | ||
217 | div ? &div->hw : NULL, div_ops, | ||
218 | gate ? &gate->hw : NULL, gate_ops, | ||
219 | flags); | ||
220 | |||
221 | return clk; | ||
222 | err_div: | ||
223 | kfree(gate); | ||
224 | err_gate: | ||
225 | kfree(mux); | ||
226 | return ERR_PTR(-ENOMEM); | ||
227 | } | ||
diff --git a/drivers/clk/rockchip/clk-px30.c b/drivers/clk/rockchip/clk-px30.c new file mode 100644 index 000000000000..601a77f1af78 --- /dev/null +++ b/drivers/clk/rockchip/clk-px30.c | |||
@@ -0,0 +1,1039 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2018 Rockchip Electronics Co. Ltd. | ||
3 | * Author: Elaine Zhang<zhangqing@rock-chips.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | */ | ||
15 | |||
16 | #include <linux/clk-provider.h> | ||
17 | #include <linux/of.h> | ||
18 | #include <linux/of_address.h> | ||
19 | #include <linux/syscore_ops.h> | ||
20 | #include <dt-bindings/clock/px30-cru.h> | ||
21 | #include "clk.h" | ||
22 | |||
23 | #define PX30_GRF_SOC_STATUS0 0x480 | ||
24 | |||
25 | enum px30_plls { | ||
26 | apll, dpll, cpll, npll, apll_b_h, apll_b_l, | ||
27 | }; | ||
28 | |||
29 | enum px30_pmu_plls { | ||
30 | gpll, | ||
31 | }; | ||
32 | |||
33 | static struct rockchip_pll_rate_table px30_pll_rates[] = { | ||
34 | /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */ | ||
35 | RK3036_PLL_RATE(1608000000, 1, 67, 1, 1, 1, 0), | ||
36 | RK3036_PLL_RATE(1584000000, 1, 66, 1, 1, 1, 0), | ||
37 | RK3036_PLL_RATE(1560000000, 1, 65, 1, 1, 1, 0), | ||
38 | RK3036_PLL_RATE(1536000000, 1, 64, 1, 1, 1, 0), | ||
39 | RK3036_PLL_RATE(1512000000, 1, 63, 1, 1, 1, 0), | ||
40 | RK3036_PLL_RATE(1488000000, 1, 62, 1, 1, 1, 0), | ||
41 | RK3036_PLL_RATE(1464000000, 1, 61, 1, 1, 1, 0), | ||
42 | RK3036_PLL_RATE(1440000000, 1, 60, 1, 1, 1, 0), | ||
43 | RK3036_PLL_RATE(1416000000, 1, 59, 1, 1, 1, 0), | ||
44 | RK3036_PLL_RATE(1392000000, 1, 58, 1, 1, 1, 0), | ||
45 | RK3036_PLL_RATE(1368000000, 1, 57, 1, 1, 1, 0), | ||
46 | RK3036_PLL_RATE(1344000000, 1, 56, 1, 1, 1, 0), | ||
47 | RK3036_PLL_RATE(1320000000, 1, 55, 1, 1, 1, 0), | ||
48 | RK3036_PLL_RATE(1296000000, 1, 54, 1, 1, 1, 0), | ||
49 | RK3036_PLL_RATE(1272000000, 1, 53, 1, 1, 1, 0), | ||
50 | RK3036_PLL_RATE(1248000000, 1, 52, 1, 1, 1, 0), | ||
51 | RK3036_PLL_RATE(1200000000, 1, 50, 1, 1, 1, 0), | ||
52 | RK3036_PLL_RATE(1188000000, 2, 99, 1, 1, 1, 0), | ||
53 | RK3036_PLL_RATE(1104000000, 1, 46, 1, 1, 1, 0), | ||
54 | RK3036_PLL_RATE(1100000000, 12, 550, 1, 1, 1, 0), | ||
55 | RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0), | ||
56 | RK3036_PLL_RATE(1000000000, 6, 500, 2, 1, 1, 0), | ||
57 | RK3036_PLL_RATE(984000000, 1, 82, 2, 1, 1, 0), | ||
58 | RK3036_PLL_RATE(960000000, 1, 80, 2, 1, 1, 0), | ||
59 | RK3036_PLL_RATE(936000000, 1, 78, 2, 1, 1, 0), | ||
60 | RK3036_PLL_RATE(912000000, 1, 76, 2, 1, 1, 0), | ||
61 | RK3036_PLL_RATE(900000000, 4, 300, 2, 1, 1, 0), | ||
62 | RK3036_PLL_RATE(888000000, 1, 74, 2, 1, 1, 0), | ||
63 | RK3036_PLL_RATE(864000000, 1, 72, 2, 1, 1, 0), | ||
64 | RK3036_PLL_RATE(840000000, 1, 70, 2, 1, 1, 0), | ||
65 | RK3036_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0), | ||
66 | RK3036_PLL_RATE(800000000, 6, 400, 2, 1, 1, 0), | ||
67 | RK3036_PLL_RATE(700000000, 6, 350, 2, 1, 1, 0), | ||
68 | RK3036_PLL_RATE(696000000, 1, 58, 2, 1, 1, 0), | ||
69 | RK3036_PLL_RATE(624000000, 1, 52, 2, 1, 1, 0), | ||
70 | RK3036_PLL_RATE(600000000, 1, 75, 3, 1, 1, 0), | ||
71 | RK3036_PLL_RATE(594000000, 2, 99, 2, 1, 1, 0), | ||
72 | RK3036_PLL_RATE(504000000, 1, 63, 3, 1, 1, 0), | ||
73 | RK3036_PLL_RATE(500000000, 6, 250, 2, 1, 1, 0), | ||
74 | RK3036_PLL_RATE(408000000, 1, 68, 2, 2, 1, 0), | ||
75 | RK3036_PLL_RATE(312000000, 1, 52, 2, 2, 1, 0), | ||
76 | RK3036_PLL_RATE(216000000, 1, 72, 4, 2, 1, 0), | ||
77 | RK3036_PLL_RATE(96000000, 1, 64, 4, 4, 1, 0), | ||
78 | { /* sentinel */ }, | ||
79 | }; | ||
80 | |||
81 | #define PX30_DIV_ACLKM_MASK 0x7 | ||
82 | #define PX30_DIV_ACLKM_SHIFT 12 | ||
83 | #define PX30_DIV_PCLK_DBG_MASK 0xf | ||
84 | #define PX30_DIV_PCLK_DBG_SHIFT 8 | ||
85 | |||
86 | #define PX30_CLKSEL0(_aclk_core, _pclk_dbg) \ | ||
87 | { \ | ||
88 | .reg = PX30_CLKSEL_CON(0), \ | ||
89 | .val = HIWORD_UPDATE(_aclk_core, PX30_DIV_ACLKM_MASK, \ | ||
90 | PX30_DIV_ACLKM_SHIFT) | \ | ||
91 | HIWORD_UPDATE(_pclk_dbg, PX30_DIV_PCLK_DBG_MASK, \ | ||
92 | PX30_DIV_PCLK_DBG_SHIFT), \ | ||
93 | } | ||
94 | |||
95 | #define PX30_CPUCLK_RATE(_prate, _aclk_core, _pclk_dbg) \ | ||
96 | { \ | ||
97 | .prate = _prate, \ | ||
98 | .divs = { \ | ||
99 | PX30_CLKSEL0(_aclk_core, _pclk_dbg), \ | ||
100 | }, \ | ||
101 | } | ||
102 | |||
103 | static struct rockchip_cpuclk_rate_table px30_cpuclk_rates[] __initdata = { | ||
104 | PX30_CPUCLK_RATE(1608000000, 1, 7), | ||
105 | PX30_CPUCLK_RATE(1584000000, 1, 7), | ||
106 | PX30_CPUCLK_RATE(1560000000, 1, 7), | ||
107 | PX30_CPUCLK_RATE(1536000000, 1, 7), | ||
108 | PX30_CPUCLK_RATE(1512000000, 1, 7), | ||
109 | PX30_CPUCLK_RATE(1488000000, 1, 5), | ||
110 | PX30_CPUCLK_RATE(1464000000, 1, 5), | ||
111 | PX30_CPUCLK_RATE(1440000000, 1, 5), | ||
112 | PX30_CPUCLK_RATE(1416000000, 1, 5), | ||
113 | PX30_CPUCLK_RATE(1392000000, 1, 5), | ||
114 | PX30_CPUCLK_RATE(1368000000, 1, 5), | ||
115 | PX30_CPUCLK_RATE(1344000000, 1, 5), | ||
116 | PX30_CPUCLK_RATE(1320000000, 1, 5), | ||
117 | PX30_CPUCLK_RATE(1296000000, 1, 5), | ||
118 | PX30_CPUCLK_RATE(1272000000, 1, 5), | ||
119 | PX30_CPUCLK_RATE(1248000000, 1, 5), | ||
120 | PX30_CPUCLK_RATE(1224000000, 1, 5), | ||
121 | PX30_CPUCLK_RATE(1200000000, 1, 5), | ||
122 | PX30_CPUCLK_RATE(1104000000, 1, 5), | ||
123 | PX30_CPUCLK_RATE(1008000000, 1, 5), | ||
124 | PX30_CPUCLK_RATE(912000000, 1, 5), | ||
125 | PX30_CPUCLK_RATE(816000000, 1, 3), | ||
126 | PX30_CPUCLK_RATE(696000000, 1, 3), | ||
127 | PX30_CPUCLK_RATE(600000000, 1, 3), | ||
128 | PX30_CPUCLK_RATE(408000000, 1, 1), | ||
129 | PX30_CPUCLK_RATE(312000000, 1, 1), | ||
130 | PX30_CPUCLK_RATE(216000000, 1, 1), | ||
131 | PX30_CPUCLK_RATE(96000000, 1, 1), | ||
132 | }; | ||
133 | |||
134 | static const struct rockchip_cpuclk_reg_data px30_cpuclk_data = { | ||
135 | .core_reg = PX30_CLKSEL_CON(0), | ||
136 | .div_core_shift = 0, | ||
137 | .div_core_mask = 0xf, | ||
138 | .mux_core_alt = 1, | ||
139 | .mux_core_main = 0, | ||
140 | .mux_core_shift = 7, | ||
141 | .mux_core_mask = 0x1, | ||
142 | }; | ||
143 | |||
144 | PNAME(mux_pll_p) = { "xin24m"}; | ||
145 | PNAME(mux_usb480m_p) = { "xin24m", "usb480m_phy", "clk_rtc32k_pmu" }; | ||
146 | PNAME(mux_armclk_p) = { "apll_core", "gpll_core" }; | ||
147 | PNAME(mux_ddrphy_p) = { "dpll_ddr", "gpll_ddr" }; | ||
148 | PNAME(mux_ddrstdby_p) = { "clk_ddrphy1x", "clk_stdby_2wrap" }; | ||
149 | PNAME(mux_4plls_p) = { "gpll", "dummy_cpll", "usb480m", "npll" }; | ||
150 | PNAME(mux_cpll_npll_p) = { "cpll", "npll" }; | ||
151 | PNAME(mux_npll_cpll_p) = { "npll", "cpll" }; | ||
152 | PNAME(mux_gpll_cpll_p) = { "gpll", "dummy_cpll" }; | ||
153 | PNAME(mux_gpll_npll_p) = { "gpll", "npll" }; | ||
154 | PNAME(mux_gpll_xin24m_p) = { "gpll", "xin24m"}; | ||
155 | PNAME(mux_gpll_cpll_npll_p) = { "gpll", "dummy_cpll", "npll" }; | ||
156 | PNAME(mux_gpll_cpll_npll_xin24m_p) = { "gpll", "dummy_cpll", "npll", "xin24m" }; | ||
157 | PNAME(mux_gpll_xin24m_npll_p) = { "gpll", "xin24m", "npll"}; | ||
158 | PNAME(mux_pdm_p) = { "clk_pdm_src", "clk_pdm_frac" }; | ||
159 | PNAME(mux_i2s0_tx_p) = { "clk_i2s0_tx_src", "clk_i2s0_tx_frac", "mclk_i2s0_tx_in", "xin12m"}; | ||
160 | PNAME(mux_i2s0_rx_p) = { "clk_i2s0_rx_src", "clk_i2s0_rx_frac", "mclk_i2s0_rx_in", "xin12m"}; | ||
161 | PNAME(mux_i2s1_p) = { "clk_i2s1_src", "clk_i2s1_frac", "i2s1_clkin", "xin12m"}; | ||
162 | PNAME(mux_i2s2_p) = { "clk_i2s2_src", "clk_i2s2_frac", "i2s2_clkin", "xin12m"}; | ||
163 | PNAME(mux_i2s0_tx_out_p) = { "clk_i2s0_tx", "xin12m", "clk_i2s0_rx"}; | ||
164 | PNAME(mux_i2s0_rx_out_p) = { "clk_i2s0_rx", "xin12m", "clk_i2s0_tx"}; | ||
165 | PNAME(mux_i2s1_out_p) = { "clk_i2s1", "xin12m"}; | ||
166 | PNAME(mux_i2s2_out_p) = { "clk_i2s2", "xin12m"}; | ||
167 | PNAME(mux_i2s0_tx_rx_p) = { "clk_i2s0_tx_mux", "clk_i2s0_rx_mux"}; | ||
168 | PNAME(mux_i2s0_rx_tx_p) = { "clk_i2s0_rx_mux", "clk_i2s0_tx_mux"}; | ||
169 | PNAME(mux_uart_src_p) = { "gpll", "xin24m", "usb480m", "npll" }; | ||
170 | PNAME(mux_uart1_p) = { "clk_uart1_src", "clk_uart1_np5", "clk_uart1_frac" }; | ||
171 | PNAME(mux_uart2_p) = { "clk_uart2_src", "clk_uart2_np5", "clk_uart2_frac" }; | ||
172 | PNAME(mux_uart3_p) = { "clk_uart3_src", "clk_uart3_np5", "clk_uart3_frac" }; | ||
173 | PNAME(mux_uart4_p) = { "clk_uart4_src", "clk_uart4_np5", "clk_uart4_frac" }; | ||
174 | PNAME(mux_uart5_p) = { "clk_uart5_src", "clk_uart5_np5", "clk_uart5_frac" }; | ||
175 | PNAME(mux_cif_out_p) = { "xin24m", "dummy_cpll", "npll", "usb480m" }; | ||
176 | PNAME(mux_dclk_vopb_p) = { "dclk_vopb_src", "dclk_vopb_frac", "xin24m" }; | ||
177 | PNAME(mux_dclk_vopl_p) = { "dclk_vopl_src", "dclk_vopl_frac", "xin24m" }; | ||
178 | PNAME(mux_gmac_p) = { "clk_gmac_src", "gmac_clkin" }; | ||
179 | PNAME(mux_gmac_rmii_sel_p) = { "clk_gmac_rx_tx_div20", "clk_gmac_rx_tx_div2" }; | ||
180 | PNAME(mux_rtc32k_pmu_p) = { "xin32k", "pmu_pvtm_32k", "clk_rtc32k_frac", }; | ||
181 | PNAME(mux_wifi_pmu_p) = { "xin24m", "clk_wifi_pmu_src" }; | ||
182 | PNAME(mux_uart0_pmu_p) = { "clk_uart0_pmu_src", "clk_uart0_np5", "clk_uart0_frac" }; | ||
183 | PNAME(mux_usbphy_ref_p) = { "xin24m", "clk_ref24m_pmu" }; | ||
184 | PNAME(mux_mipidsiphy_ref_p) = { "xin24m", "clk_ref24m_pmu" }; | ||
185 | PNAME(mux_gpu_p) = { "clk_gpu_div", "clk_gpu_np5" }; | ||
186 | |||
187 | static struct rockchip_pll_clock px30_pll_clks[] __initdata = { | ||
188 | [apll] = PLL(pll_rk3328, PLL_APLL, "apll", mux_pll_p, | ||
189 | 0, PX30_PLL_CON(0), | ||
190 | PX30_MODE_CON, 0, 0, 0, px30_pll_rates), | ||
191 | [dpll] = PLL(pll_rk3328, PLL_DPLL, "dpll", mux_pll_p, | ||
192 | 0, PX30_PLL_CON(8), | ||
193 | PX30_MODE_CON, 4, 1, 0, NULL), | ||
194 | [cpll] = PLL(pll_rk3328, PLL_CPLL, "cpll", mux_pll_p, | ||
195 | 0, PX30_PLL_CON(16), | ||
196 | PX30_MODE_CON, 2, 2, 0, px30_pll_rates), | ||
197 | [npll] = PLL(pll_rk3328, PLL_NPLL, "npll", mux_pll_p, | ||
198 | 0, PX30_PLL_CON(24), | ||
199 | PX30_MODE_CON, 6, 4, 0, px30_pll_rates), | ||
200 | }; | ||
201 | |||
202 | static struct rockchip_pll_clock px30_pmu_pll_clks[] __initdata = { | ||
203 | [gpll] = PLL(pll_rk3328, PLL_GPLL, "gpll", mux_pll_p, 0, PX30_PMU_PLL_CON(0), | ||
204 | PX30_PMU_MODE, 0, 3, 0, px30_pll_rates), | ||
205 | }; | ||
206 | |||
207 | #define MFLAGS CLK_MUX_HIWORD_MASK | ||
208 | #define DFLAGS CLK_DIVIDER_HIWORD_MASK | ||
209 | #define GFLAGS (CLK_GATE_HIWORD_MASK | CLK_GATE_SET_TO_DISABLE) | ||
210 | |||
211 | static struct rockchip_clk_branch px30_pdm_fracmux __initdata = | ||
212 | MUX(0, "clk_pdm_mux", mux_pdm_p, CLK_SET_RATE_PARENT, | ||
213 | PX30_CLKSEL_CON(26), 15, 1, MFLAGS); | ||
214 | |||
215 | static struct rockchip_clk_branch px30_i2s0_tx_fracmux __initdata = | ||
216 | MUX(0, "clk_i2s0_tx_mux", mux_i2s0_tx_p, CLK_SET_RATE_PARENT, | ||
217 | PX30_CLKSEL_CON(28), 10, 2, MFLAGS); | ||
218 | |||
219 | static struct rockchip_clk_branch px30_i2s0_rx_fracmux __initdata = | ||
220 | MUX(0, "clk_i2s0_rx_mux", mux_i2s0_rx_p, CLK_SET_RATE_PARENT, | ||
221 | PX30_CLKSEL_CON(58), 10, 2, MFLAGS); | ||
222 | |||
223 | static struct rockchip_clk_branch px30_i2s1_fracmux __initdata = | ||
224 | MUX(0, "clk_i2s1_mux", mux_i2s1_p, CLK_SET_RATE_PARENT, | ||
225 | PX30_CLKSEL_CON(30), 10, 2, MFLAGS); | ||
226 | |||
227 | static struct rockchip_clk_branch px30_i2s2_fracmux __initdata = | ||
228 | MUX(0, "clk_i2s2_mux", mux_i2s2_p, CLK_SET_RATE_PARENT, | ||
229 | PX30_CLKSEL_CON(32), 10, 2, MFLAGS); | ||
230 | |||
231 | static struct rockchip_clk_branch px30_uart1_fracmux __initdata = | ||
232 | MUX(0, "clk_uart1_mux", mux_uart1_p, CLK_SET_RATE_PARENT, | ||
233 | PX30_CLKSEL_CON(35), 14, 2, MFLAGS); | ||
234 | |||
235 | static struct rockchip_clk_branch px30_uart2_fracmux __initdata = | ||
236 | MUX(0, "clk_uart2_mux", mux_uart2_p, CLK_SET_RATE_PARENT, | ||
237 | PX30_CLKSEL_CON(38), 14, 2, MFLAGS); | ||
238 | |||
239 | static struct rockchip_clk_branch px30_uart3_fracmux __initdata = | ||
240 | MUX(0, "clk_uart3_mux", mux_uart3_p, CLK_SET_RATE_PARENT, | ||
241 | PX30_CLKSEL_CON(41), 14, 2, MFLAGS); | ||
242 | |||
243 | static struct rockchip_clk_branch px30_uart4_fracmux __initdata = | ||
244 | MUX(0, "clk_uart4_mux", mux_uart4_p, CLK_SET_RATE_PARENT, | ||
245 | PX30_CLKSEL_CON(44), 14, 2, MFLAGS); | ||
246 | |||
247 | static struct rockchip_clk_branch px30_uart5_fracmux __initdata = | ||
248 | MUX(0, "clk_uart5_mux", mux_uart5_p, CLK_SET_RATE_PARENT, | ||
249 | PX30_CLKSEL_CON(47), 14, 2, MFLAGS); | ||
250 | |||
251 | static struct rockchip_clk_branch px30_dclk_vopb_fracmux __initdata = | ||
252 | MUX(0, "dclk_vopb_mux", mux_dclk_vopb_p, CLK_SET_RATE_PARENT, | ||
253 | PX30_CLKSEL_CON(5), 14, 2, MFLAGS); | ||
254 | |||
255 | static struct rockchip_clk_branch px30_dclk_vopl_fracmux __initdata = | ||
256 | MUX(0, "dclk_vopl_mux", mux_dclk_vopl_p, CLK_SET_RATE_PARENT, | ||
257 | PX30_CLKSEL_CON(8), 14, 2, MFLAGS); | ||
258 | |||
259 | static struct rockchip_clk_branch px30_rtc32k_pmu_fracmux __initdata = | ||
260 | MUX(SCLK_RTC32K_PMU, "clk_rtc32k_pmu", mux_rtc32k_pmu_p, CLK_SET_RATE_PARENT, | ||
261 | PX30_PMU_CLKSEL_CON(0), 14, 2, MFLAGS); | ||
262 | |||
263 | static struct rockchip_clk_branch px30_uart0_pmu_fracmux __initdata = | ||
264 | MUX(0, "clk_uart0_pmu_mux", mux_uart0_pmu_p, CLK_SET_RATE_PARENT, | ||
265 | PX30_PMU_CLKSEL_CON(4), 14, 2, MFLAGS); | ||
266 | |||
267 | static struct rockchip_clk_branch px30_clk_branches[] __initdata = { | ||
268 | /* | ||
269 | * Clock-Architecture Diagram 1 | ||
270 | */ | ||
271 | |||
272 | MUX(USB480M, "usb480m", mux_usb480m_p, CLK_SET_RATE_PARENT, | ||
273 | PX30_MODE_CON, 8, 2, MFLAGS), | ||
274 | FACTOR(0, "xin12m", "xin24m", 0, 1, 2), | ||
275 | |||
276 | /* | ||
277 | * Clock-Architecture Diagram 3 | ||
278 | */ | ||
279 | |||
280 | /* PD_CORE */ | ||
281 | GATE(0, "apll_core", "apll", CLK_IGNORE_UNUSED, | ||
282 | PX30_CLKGATE_CON(0), 0, GFLAGS), | ||
283 | GATE(0, "gpll_core", "gpll", CLK_IGNORE_UNUSED, | ||
284 | PX30_CLKGATE_CON(0), 0, GFLAGS), | ||
285 | COMPOSITE_NOMUX(0, "pclk_dbg", "armclk", CLK_IGNORE_UNUSED, | ||
286 | PX30_CLKSEL_CON(0), 8, 4, DFLAGS | CLK_DIVIDER_READ_ONLY, | ||
287 | PX30_CLKGATE_CON(0), 2, GFLAGS), | ||
288 | COMPOSITE_NOMUX(0, "aclk_core", "armclk", CLK_IGNORE_UNUSED, | ||
289 | PX30_CLKSEL_CON(0), 12, 3, DFLAGS | CLK_DIVIDER_READ_ONLY, | ||
290 | PX30_CLKGATE_CON(0), 1, GFLAGS), | ||
291 | GATE(0, "aclk_core_niu", "aclk_core", CLK_IGNORE_UNUSED, | ||
292 | PX30_CLKGATE_CON(0), 4, GFLAGS), | ||
293 | GATE(0, "aclk_core_prf", "aclk_core", CLK_IGNORE_UNUSED, | ||
294 | PX30_CLKGATE_CON(17), 5, GFLAGS), | ||
295 | GATE(0, "pclk_dbg_niu", "pclk_dbg", CLK_IGNORE_UNUSED, | ||
296 | PX30_CLKGATE_CON(0), 5, GFLAGS), | ||
297 | GATE(0, "pclk_core_dbg", "pclk_dbg", CLK_IGNORE_UNUSED, | ||
298 | PX30_CLKGATE_CON(0), 6, GFLAGS), | ||
299 | GATE(0, "pclk_core_grf", "pclk_dbg", CLK_IGNORE_UNUSED, | ||
300 | PX30_CLKGATE_CON(17), 6, GFLAGS), | ||
301 | |||
302 | GATE(0, "clk_jtag", "jtag_clkin", CLK_IGNORE_UNUSED, | ||
303 | PX30_CLKGATE_CON(0), 3, GFLAGS), | ||
304 | GATE(SCLK_PVTM, "clk_pvtm", "xin24m", 0, | ||
305 | PX30_CLKGATE_CON(17), 4, GFLAGS), | ||
306 | |||
307 | /* PD_GPU */ | ||
308 | COMPOSITE_NODIV(0, "clk_gpu_src", mux_4plls_p, 0, | ||
309 | PX30_CLKSEL_CON(1), 6, 2, MFLAGS, | ||
310 | PX30_CLKGATE_CON(0), 8, GFLAGS), | ||
311 | COMPOSITE_NOMUX(0, "clk_gpu_div", "clk_gpu_src", 0, | ||
312 | PX30_CLKSEL_CON(1), 0, 4, DFLAGS, | ||
313 | PX30_CLKGATE_CON(0), 12, GFLAGS), | ||
314 | COMPOSITE_NOMUX_HALFDIV(0, "clk_gpu_np5", "clk_gpu_src", 0, | ||
315 | PX30_CLKSEL_CON(1), 8, 4, DFLAGS, | ||
316 | PX30_CLKGATE_CON(0), 9, GFLAGS), | ||
317 | COMPOSITE_NODIV(SCLK_GPU, "clk_gpu", mux_gpu_p, CLK_SET_RATE_PARENT, | ||
318 | PX30_CLKSEL_CON(1), 15, 1, MFLAGS, | ||
319 | PX30_CLKGATE_CON(0), 10, GFLAGS), | ||
320 | COMPOSITE_NOMUX(0, "aclk_gpu", "clk_gpu", CLK_IGNORE_UNUSED, | ||
321 | PX30_CLKSEL_CON(1), 13, 2, DFLAGS, | ||
322 | PX30_CLKGATE_CON(17), 10, GFLAGS), | ||
323 | GATE(0, "aclk_gpu_niu", "aclk_gpu", CLK_IGNORE_UNUSED, | ||
324 | PX30_CLKGATE_CON(0), 11, GFLAGS), | ||
325 | GATE(0, "aclk_gpu_prf", "aclk_gpu", CLK_IGNORE_UNUSED, | ||
326 | PX30_CLKGATE_CON(17), 8, GFLAGS), | ||
327 | GATE(0, "pclk_gpu_grf", "aclk_gpu", CLK_IGNORE_UNUSED, | ||
328 | PX30_CLKGATE_CON(17), 9, GFLAGS), | ||
329 | |||
330 | /* | ||
331 | * Clock-Architecture Diagram 4 | ||
332 | */ | ||
333 | |||
334 | /* PD_DDR */ | ||
335 | GATE(0, "dpll_ddr", "dpll", CLK_IGNORE_UNUSED, | ||
336 | PX30_CLKGATE_CON(0), 7, GFLAGS), | ||
337 | GATE(0, "gpll_ddr", "gpll", CLK_IGNORE_UNUSED, | ||
338 | PX30_CLKGATE_CON(0), 13, GFLAGS), | ||
339 | COMPOSITE_NOGATE(SCLK_DDRCLK, "sclk_ddrc", mux_ddrphy_p, CLK_IGNORE_UNUSED, | ||
340 | PX30_CLKSEL_CON(2), 7, 1, MFLAGS, 0, 3, DFLAGS | CLK_DIVIDER_POWER_OF_TWO), | ||
341 | COMPOSITE_NOGATE(0, "clk_ddrphy4x", mux_ddrphy_p, CLK_IGNORE_UNUSED, | ||
342 | PX30_CLKSEL_CON(2), 7, 1, MFLAGS, 0, 3, DFLAGS), | ||
343 | FACTOR_GATE(0, "clk_ddrphy1x", "clk_ddrphy4x", CLK_IGNORE_UNUSED, 1, 4, | ||
344 | PX30_CLKGATE_CON(0), 14, GFLAGS), | ||
345 | FACTOR_GATE(0, "clk_stdby_2wrap", "clk_ddrphy4x", CLK_IGNORE_UNUSED, 1, 4, | ||
346 | PX30_CLKGATE_CON(1), 0, GFLAGS), | ||
347 | COMPOSITE_NODIV(0, "clk_ddrstdby", mux_ddrstdby_p, CLK_IGNORE_UNUSED, | ||
348 | PX30_CLKSEL_CON(2), 4, 1, MFLAGS, | ||
349 | PX30_CLKGATE_CON(1), 13, GFLAGS), | ||
350 | GATE(0, "aclk_split", "clk_ddrphy1x", CLK_IGNORE_UNUSED, | ||
351 | PX30_CLKGATE_CON(1), 15, GFLAGS), | ||
352 | GATE(0, "clk_msch", "clk_ddrphy1x", CLK_IGNORE_UNUSED, | ||
353 | PX30_CLKGATE_CON(1), 8, GFLAGS), | ||
354 | GATE(0, "aclk_ddrc", "clk_ddrphy1x", CLK_IGNORE_UNUSED, | ||
355 | PX30_CLKGATE_CON(1), 5, GFLAGS), | ||
356 | GATE(0, "clk_core_ddrc", "clk_ddrphy1x", CLK_IGNORE_UNUSED, | ||
357 | PX30_CLKGATE_CON(1), 6, GFLAGS), | ||
358 | GATE(0, "aclk_cmd_buff", "clk_ddrphy1x", CLK_IGNORE_UNUSED, | ||
359 | PX30_CLKGATE_CON(1), 6, GFLAGS), | ||
360 | GATE(0, "clk_ddrmon", "clk_ddrphy1x", CLK_IGNORE_UNUSED, | ||
361 | PX30_CLKGATE_CON(1), 11, GFLAGS), | ||
362 | |||
363 | GATE(0, "clk_ddrmon_timer", "xin24m", CLK_IGNORE_UNUSED, | ||
364 | PX30_CLKGATE_CON(0), 15, GFLAGS), | ||
365 | |||
366 | COMPOSITE_NOMUX(PCLK_DDR, "pclk_ddr", "gpll", CLK_IGNORE_UNUSED, | ||
367 | PX30_CLKSEL_CON(2), 8, 5, DFLAGS, | ||
368 | PX30_CLKGATE_CON(1), 1, GFLAGS), | ||
369 | GATE(0, "pclk_ddrmon", "pclk_ddr", CLK_IGNORE_UNUSED, | ||
370 | PX30_CLKGATE_CON(1), 10, GFLAGS), | ||
371 | GATE(0, "pclk_ddrc", "pclk_ddr", CLK_IGNORE_UNUSED, | ||
372 | PX30_CLKGATE_CON(1), 7, GFLAGS), | ||
373 | GATE(0, "pclk_msch", "pclk_ddr", CLK_IGNORE_UNUSED, | ||
374 | PX30_CLKGATE_CON(1), 9, GFLAGS), | ||
375 | GATE(0, "pclk_stdby", "pclk_ddr", CLK_IGNORE_UNUSED, | ||
376 | PX30_CLKGATE_CON(1), 12, GFLAGS), | ||
377 | GATE(0, "pclk_ddr_grf", "pclk_ddr", CLK_IGNORE_UNUSED, | ||
378 | PX30_CLKGATE_CON(1), 14, GFLAGS), | ||
379 | GATE(0, "pclk_cmdbuff", "pclk_ddr", CLK_IGNORE_UNUSED, | ||
380 | PX30_CLKGATE_CON(1), 3, GFLAGS), | ||
381 | |||
382 | /* | ||
383 | * Clock-Architecture Diagram 5 | ||
384 | */ | ||
385 | |||
386 | /* PD_VI */ | ||
387 | COMPOSITE(ACLK_VI_PRE, "aclk_vi_pre", mux_gpll_cpll_npll_p, 0, | ||
388 | PX30_CLKSEL_CON(11), 6, 2, MFLAGS, 0, 5, DFLAGS, | ||
389 | PX30_CLKGATE_CON(4), 8, GFLAGS), | ||
390 | COMPOSITE_NOMUX(HCLK_VI_PRE, "hclk_vi_pre", "aclk_vi_pre", 0, | ||
391 | PX30_CLKSEL_CON(11), 8, 4, DFLAGS, | ||
392 | PX30_CLKGATE_CON(4), 12, GFLAGS), | ||
393 | COMPOSITE(SCLK_ISP, "clk_isp", mux_gpll_cpll_npll_p, 0, | ||
394 | PX30_CLKSEL_CON(12), 6, 2, MFLAGS, 0, 5, DFLAGS, | ||
395 | PX30_CLKGATE_CON(4), 9, GFLAGS), | ||
396 | COMPOSITE(SCLK_CIF_OUT, "clk_cif_out", mux_cif_out_p, 0, | ||
397 | PX30_CLKSEL_CON(13), 6, 2, MFLAGS, 0, 6, DFLAGS, | ||
398 | PX30_CLKGATE_CON(4), 11, GFLAGS), | ||
399 | GATE(PCLK_ISP, "pclkin_isp", "ext_pclkin", 0, | ||
400 | PX30_CLKGATE_CON(4), 13, GFLAGS), | ||
401 | GATE(PCLK_CIF, "pclkin_cif", "ext_pclkin", 0, | ||
402 | PX30_CLKGATE_CON(4), 14, GFLAGS), | ||
403 | |||
404 | /* | ||
405 | * Clock-Architecture Diagram 6 | ||
406 | */ | ||
407 | |||
408 | /* PD_VO */ | ||
409 | COMPOSITE(ACLK_VO_PRE, "aclk_vo_pre", mux_gpll_cpll_npll_p, 0, | ||
410 | PX30_CLKSEL_CON(3), 6, 2, MFLAGS, 0, 5, DFLAGS, | ||
411 | PX30_CLKGATE_CON(2), 0, GFLAGS), | ||
412 | COMPOSITE_NOMUX(HCLK_VO_PRE, "hclk_vo_pre", "aclk_vo_pre", 0, | ||
413 | PX30_CLKSEL_CON(3), 8, 4, DFLAGS, | ||
414 | PX30_CLKGATE_CON(2), 12, GFLAGS), | ||
415 | COMPOSITE_NOMUX(PCLK_VO_PRE, "pclk_vo_pre", "aclk_vo_pre", 0, | ||
416 | PX30_CLKSEL_CON(3), 12, 4, DFLAGS, | ||
417 | PX30_CLKGATE_CON(2), 13, GFLAGS), | ||
418 | COMPOSITE(SCLK_RGA_CORE, "clk_rga_core", mux_gpll_cpll_npll_p, 0, | ||
419 | PX30_CLKSEL_CON(4), 6, 2, MFLAGS, 0, 5, DFLAGS, | ||
420 | PX30_CLKGATE_CON(2), 1, GFLAGS), | ||
421 | |||
422 | COMPOSITE(SCLK_VOPB_PWM, "clk_vopb_pwm", mux_gpll_xin24m_p, 0, | ||
423 | PX30_CLKSEL_CON(7), 7, 1, MFLAGS, 0, 7, DFLAGS, | ||
424 | PX30_CLKGATE_CON(2), 5, GFLAGS), | ||
425 | COMPOSITE(0, "dclk_vopb_src", mux_cpll_npll_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, | ||
426 | PX30_CLKSEL_CON(5), 11, 1, MFLAGS, 0, 8, DFLAGS, | ||
427 | PX30_CLKGATE_CON(2), 2, GFLAGS), | ||
428 | COMPOSITE_FRACMUX(0, "dclk_vopb_frac", "dclk_vopb_src", CLK_SET_RATE_PARENT, | ||
429 | PX30_CLKSEL_CON(6), 0, | ||
430 | PX30_CLKGATE_CON(2), 3, GFLAGS, | ||
431 | &px30_dclk_vopb_fracmux), | ||
432 | GATE(DCLK_VOPB, "dclk_vopb", "dclk_vopb_mux", CLK_SET_RATE_PARENT, | ||
433 | PX30_CLKGATE_CON(2), 4, GFLAGS), | ||
434 | COMPOSITE(0, "dclk_vopl_src", mux_npll_cpll_p, 0, | ||
435 | PX30_CLKSEL_CON(8), 11, 1, MFLAGS, 0, 8, DFLAGS, | ||
436 | PX30_CLKGATE_CON(2), 6, GFLAGS), | ||
437 | COMPOSITE_FRACMUX(0, "dclk_vopl_frac", "dclk_vopl_src", CLK_SET_RATE_PARENT, | ||
438 | PX30_CLKSEL_CON(9), 0, | ||
439 | PX30_CLKGATE_CON(2), 7, GFLAGS, | ||
440 | &px30_dclk_vopl_fracmux), | ||
441 | GATE(DCLK_VOPL, "dclk_vopl", "dclk_vopl_mux", CLK_SET_RATE_PARENT, | ||
442 | PX30_CLKGATE_CON(2), 8, GFLAGS), | ||
443 | |||
444 | /* PD_VPU */ | ||
445 | COMPOSITE(0, "aclk_vpu_pre", mux_gpll_cpll_npll_p, 0, | ||
446 | PX30_CLKSEL_CON(10), 6, 2, MFLAGS, 0, 5, DFLAGS, | ||
447 | PX30_CLKGATE_CON(4), 0, GFLAGS), | ||
448 | COMPOSITE_NOMUX(0, "hclk_vpu_pre", "aclk_vpu_pre", 0, | ||
449 | PX30_CLKSEL_CON(10), 8, 4, DFLAGS, | ||
450 | PX30_CLKGATE_CON(4), 2, GFLAGS), | ||
451 | COMPOSITE(SCLK_CORE_VPU, "sclk_core_vpu", mux_gpll_cpll_npll_p, 0, | ||
452 | PX30_CLKSEL_CON(13), 14, 2, MFLAGS, 8, 5, DFLAGS, | ||
453 | PX30_CLKGATE_CON(4), 1, GFLAGS), | ||
454 | |||
455 | /* | ||
456 | * Clock-Architecture Diagram 7 | ||
457 | */ | ||
458 | |||
459 | COMPOSITE_NODIV(ACLK_PERI_SRC, "aclk_peri_src", mux_gpll_cpll_p, 0, | ||
460 | PX30_CLKSEL_CON(14), 15, 1, MFLAGS, | ||
461 | PX30_CLKGATE_CON(5), 7, GFLAGS), | ||
462 | COMPOSITE_NOMUX(ACLK_PERI_PRE, "aclk_peri_pre", "aclk_peri_src", CLK_IGNORE_UNUSED, | ||
463 | PX30_CLKSEL_CON(14), 0, 5, DFLAGS, | ||
464 | PX30_CLKGATE_CON(5), 8, GFLAGS), | ||
465 | DIV(HCLK_PERI_PRE, "hclk_peri_pre", "aclk_peri_src", CLK_IGNORE_UNUSED, | ||
466 | PX30_CLKSEL_CON(14), 8, 5, DFLAGS), | ||
467 | |||
468 | /* PD_MMC_NAND */ | ||
469 | GATE(HCLK_MMC_NAND, "hclk_mmc_nand", "hclk_peri_pre", 0, | ||
470 | PX30_CLKGATE_CON(6), 0, GFLAGS), | ||
471 | COMPOSITE(SCLK_NANDC, "clk_nandc", mux_gpll_cpll_npll_p, 0, | ||
472 | PX30_CLKSEL_CON(15), 6, 2, MFLAGS, 0, 5, DFLAGS, | ||
473 | PX30_CLKGATE_CON(5), 13, GFLAGS), | ||
474 | |||
475 | COMPOSITE(SCLK_SDIO, "clk_sdio", mux_gpll_cpll_npll_xin24m_p, 0, | ||
476 | PX30_CLKSEL_CON(18), 14, 2, MFLAGS, 0, 8, DFLAGS, | ||
477 | PX30_CLKGATE_CON(6), 3, GFLAGS), | ||
478 | |||
479 | COMPOSITE(SCLK_EMMC, "clk_emmc", mux_gpll_cpll_npll_xin24m_p, 0, | ||
480 | PX30_CLKSEL_CON(20), 14, 2, MFLAGS, 0, 8, DFLAGS, | ||
481 | PX30_CLKGATE_CON(6), 6, GFLAGS), | ||
482 | |||
483 | COMPOSITE(SCLK_SFC, "clk_sfc", mux_gpll_cpll_p, 0, | ||
484 | PX30_CLKSEL_CON(22), 7, 1, MFLAGS, 0, 7, DFLAGS, | ||
485 | PX30_CLKGATE_CON(6), 7, GFLAGS), | ||
486 | |||
487 | MMC(SCLK_SDMMC_DRV, "sdmmc_drv", "clk_sdmmc", | ||
488 | PX30_SDMMC_CON0, 1), | ||
489 | MMC(SCLK_SDMMC_SAMPLE, "sdmmc_sample", "clk_sdmmc", | ||
490 | PX30_SDMMC_CON1, 1), | ||
491 | |||
492 | MMC(SCLK_SDIO_DRV, "sdio_drv", "clk_sdio", | ||
493 | PX30_SDIO_CON0, 1), | ||
494 | MMC(SCLK_SDIO_SAMPLE, "sdio_sample", "clk_sdio", | ||
495 | PX30_SDIO_CON1, 1), | ||
496 | |||
497 | MMC(SCLK_EMMC_DRV, "emmc_drv", "clk_emmc", | ||
498 | PX30_EMMC_CON0, 1), | ||
499 | MMC(SCLK_EMMC_SAMPLE, "emmc_sample", "clk_emmc", | ||
500 | PX30_EMMC_CON1, 1), | ||
501 | |||
502 | /* PD_SDCARD */ | ||
503 | GATE(0, "hclk_sdmmc_pre", "hclk_peri_pre", 0, | ||
504 | PX30_CLKGATE_CON(6), 12, GFLAGS), | ||
505 | COMPOSITE(SCLK_SDMMC, "clk_sdmmc", mux_gpll_cpll_npll_xin24m_p, 0, | ||
506 | PX30_CLKSEL_CON(16), 14, 2, MFLAGS, 0, 8, DFLAGS, | ||
507 | PX30_CLKGATE_CON(6), 15, GFLAGS), | ||
508 | |||
509 | /* PD_USB */ | ||
510 | GATE(HCLK_USB, "hclk_usb", "hclk_peri_pre", 0, | ||
511 | PX30_CLKGATE_CON(7), 2, GFLAGS), | ||
512 | GATE(SCLK_OTG_ADP, "clk_otg_adp", "clk_rtc32k_pmu", 0, | ||
513 | PX30_CLKGATE_CON(7), 3, GFLAGS), | ||
514 | |||
515 | /* PD_GMAC */ | ||
516 | COMPOSITE(SCLK_GMAC_SRC, "clk_gmac_src", mux_gpll_cpll_npll_p, 0, | ||
517 | PX30_CLKSEL_CON(22), 14, 2, MFLAGS, 8, 5, DFLAGS, | ||
518 | PX30_CLKGATE_CON(7), 11, GFLAGS), | ||
519 | MUX(SCLK_GMAC, "clk_gmac", mux_gmac_p, CLK_SET_RATE_PARENT, | ||
520 | PX30_CLKSEL_CON(23), 6, 1, MFLAGS), | ||
521 | GATE(SCLK_MAC_REF, "clk_mac_ref", "clk_gmac", 0, | ||
522 | PX30_CLKGATE_CON(7), 15, GFLAGS), | ||
523 | GATE(SCLK_GMAC_RX_TX, "clk_gmac_rx_tx", "clk_gmac", 0, | ||
524 | PX30_CLKGATE_CON(7), 13, GFLAGS), | ||
525 | FACTOR(0, "clk_gmac_rx_tx_div2", "clk_gmac_rx_tx", 0, 1, 2), | ||
526 | FACTOR(0, "clk_gmac_rx_tx_div20", "clk_gmac_rx_tx", 0, 1, 20), | ||
527 | MUX(SCLK_GMAC_RMII, "clk_gmac_rmii_sel", mux_gmac_rmii_sel_p, CLK_SET_RATE_PARENT, | ||
528 | PX30_CLKSEL_CON(23), 7, 1, MFLAGS), | ||
529 | |||
530 | GATE(0, "aclk_gmac_pre", "aclk_peri_pre", 0, | ||
531 | PX30_CLKGATE_CON(7), 10, GFLAGS), | ||
532 | COMPOSITE_NOMUX(0, "pclk_gmac_pre", "aclk_gmac_pre", 0, | ||
533 | PX30_CLKSEL_CON(23), 0, 4, DFLAGS, | ||
534 | PX30_CLKGATE_CON(7), 12, GFLAGS), | ||
535 | |||
536 | COMPOSITE(SCLK_MAC_OUT, "clk_mac_out", mux_gpll_cpll_npll_p, 0, | ||
537 | PX30_CLKSEL_CON(12), 14, 2, MFLAGS, 8, 5, DFLAGS, | ||
538 | PX30_CLKGATE_CON(8), 5, GFLAGS), | ||
539 | |||
540 | /* | ||
541 | * Clock-Architecture Diagram 8 | ||
542 | */ | ||
543 | |||
544 | /* PD_BUS */ | ||
545 | COMPOSITE_NODIV(ACLK_BUS_SRC, "aclk_bus_src", mux_gpll_cpll_p, CLK_IGNORE_UNUSED, | ||
546 | PX30_CLKSEL_CON(23), 15, 1, MFLAGS, | ||
547 | PX30_CLKGATE_CON(8), 6, GFLAGS), | ||
548 | COMPOSITE_NOMUX(HCLK_BUS_PRE, "hclk_bus_pre", "aclk_bus_src", CLK_IGNORE_UNUSED, | ||
549 | PX30_CLKSEL_CON(24), 0, 5, DFLAGS, | ||
550 | PX30_CLKGATE_CON(8), 8, GFLAGS), | ||
551 | COMPOSITE_NOMUX(ACLK_BUS_PRE, "aclk_bus_pre", "aclk_bus_src", CLK_IGNORE_UNUSED, | ||
552 | PX30_CLKSEL_CON(23), 8, 5, DFLAGS, | ||
553 | PX30_CLKGATE_CON(8), 7, GFLAGS), | ||
554 | COMPOSITE_NOMUX(PCLK_BUS_PRE, "pclk_bus_pre", "aclk_bus_pre", CLK_IGNORE_UNUSED, | ||
555 | PX30_CLKSEL_CON(24), 8, 2, DFLAGS, | ||
556 | PX30_CLKGATE_CON(8), 9, GFLAGS), | ||
557 | GATE(0, "pclk_top_pre", "pclk_bus_pre", CLK_IGNORE_UNUSED, | ||
558 | PX30_CLKGATE_CON(8), 10, GFLAGS), | ||
559 | |||
560 | COMPOSITE(0, "clk_pdm_src", mux_gpll_xin24m_npll_p, 0, | ||
561 | PX30_CLKSEL_CON(26), 8, 2, MFLAGS, 0, 7, DFLAGS, | ||
562 | PX30_CLKGATE_CON(9), 9, GFLAGS), | ||
563 | COMPOSITE_FRACMUX(0, "clk_pdm_frac", "clk_pdm_src", CLK_SET_RATE_PARENT, | ||
564 | PX30_CLKSEL_CON(27), 0, | ||
565 | PX30_CLKGATE_CON(9), 10, GFLAGS, | ||
566 | &px30_pdm_fracmux), | ||
567 | GATE(SCLK_PDM, "clk_pdm", "clk_pdm_mux", CLK_SET_RATE_PARENT, | ||
568 | PX30_CLKGATE_CON(9), 11, GFLAGS), | ||
569 | |||
570 | COMPOSITE(0, "clk_i2s0_tx_src", mux_gpll_npll_p, 0, | ||
571 | PX30_CLKSEL_CON(28), 8, 1, MFLAGS, 0, 7, DFLAGS, | ||
572 | PX30_CLKGATE_CON(9), 12, GFLAGS), | ||
573 | COMPOSITE_FRACMUX(0, "clk_i2s0_tx_frac", "clk_i2s0_tx_src", CLK_SET_RATE_PARENT, | ||
574 | PX30_CLKSEL_CON(29), 0, | ||
575 | PX30_CLKGATE_CON(9), 13, GFLAGS, | ||
576 | &px30_i2s0_tx_fracmux), | ||
577 | COMPOSITE_NODIV(SCLK_I2S0_TX, "clk_i2s0_tx", mux_i2s0_tx_rx_p, CLK_SET_RATE_PARENT, | ||
578 | PX30_CLKSEL_CON(28), 12, 1, MFLAGS, | ||
579 | PX30_CLKGATE_CON(9), 14, GFLAGS), | ||
580 | COMPOSITE_NODIV(0, "clk_i2s0_tx_out_pre", mux_i2s0_tx_out_p, 0, | ||
581 | PX30_CLKSEL_CON(28), 14, 2, MFLAGS, | ||
582 | PX30_CLKGATE_CON(9), 15, GFLAGS), | ||
583 | GATE(SCLK_I2S0_TX_OUT, "clk_i2s0_tx_out", "clk_i2s0_tx_out_pre", CLK_SET_RATE_PARENT, | ||
584 | PX30_CLKGATE_CON(10), 8, CLK_GATE_HIWORD_MASK), | ||
585 | |||
586 | COMPOSITE(0, "clk_i2s0_rx_src", mux_gpll_npll_p, 0, | ||
587 | PX30_CLKSEL_CON(58), 8, 1, MFLAGS, 0, 7, DFLAGS, | ||
588 | PX30_CLKGATE_CON(17), 0, GFLAGS), | ||
589 | COMPOSITE_FRACMUX(0, "clk_i2s0_rx_frac", "clk_i2s0_rx_src", CLK_SET_RATE_PARENT, | ||
590 | PX30_CLKSEL_CON(59), 0, | ||
591 | PX30_CLKGATE_CON(17), 1, GFLAGS, | ||
592 | &px30_i2s0_rx_fracmux), | ||
593 | COMPOSITE_NODIV(SCLK_I2S0_RX, "clk_i2s0_rx", mux_i2s0_rx_tx_p, CLK_SET_RATE_PARENT, | ||
594 | PX30_CLKSEL_CON(58), 12, 1, MFLAGS, | ||
595 | PX30_CLKGATE_CON(17), 2, GFLAGS), | ||
596 | COMPOSITE_NODIV(0, "clk_i2s0_rx_out_pre", mux_i2s0_rx_out_p, 0, | ||
597 | PX30_CLKSEL_CON(58), 14, 2, MFLAGS, | ||
598 | PX30_CLKGATE_CON(17), 3, GFLAGS), | ||
599 | GATE(SCLK_I2S0_RX_OUT, "clk_i2s0_rx_out", "clk_i2s0_rx_out_pre", CLK_SET_RATE_PARENT, | ||
600 | PX30_CLKGATE_CON(10), 11, CLK_GATE_HIWORD_MASK), | ||
601 | |||
602 | COMPOSITE(0, "clk_i2s1_src", mux_gpll_npll_p, 0, | ||
603 | PX30_CLKSEL_CON(30), 8, 1, MFLAGS, 0, 7, DFLAGS, | ||
604 | PX30_CLKGATE_CON(10), 0, GFLAGS), | ||
605 | COMPOSITE_FRACMUX(0, "clk_i2s1_frac", "clk_i2s1_src", CLK_SET_RATE_PARENT, | ||
606 | PX30_CLKSEL_CON(31), 0, | ||
607 | PX30_CLKGATE_CON(10), 1, GFLAGS, | ||
608 | &px30_i2s1_fracmux), | ||
609 | GATE(SCLK_I2S1, "clk_i2s1", "clk_i2s1_mux", CLK_SET_RATE_PARENT, | ||
610 | PX30_CLKGATE_CON(10), 2, GFLAGS), | ||
611 | COMPOSITE_NODIV(0, "clk_i2s1_out_pre", mux_i2s1_out_p, 0, | ||
612 | PX30_CLKSEL_CON(30), 15, 1, MFLAGS, | ||
613 | PX30_CLKGATE_CON(10), 3, GFLAGS), | ||
614 | GATE(SCLK_I2S1_OUT, "clk_i2s1_out", "clk_i2s1_out_pre", CLK_SET_RATE_PARENT, | ||
615 | PX30_CLKGATE_CON(10), 9, CLK_GATE_HIWORD_MASK), | ||
616 | |||
617 | COMPOSITE(0, "clk_i2s2_src", mux_gpll_npll_p, 0, | ||
618 | PX30_CLKSEL_CON(32), 8, 1, MFLAGS, 0, 7, DFLAGS, | ||
619 | PX30_CLKGATE_CON(10), 4, GFLAGS), | ||
620 | COMPOSITE_FRACMUX(0, "clk_i2s2_frac", "clk_i2s2_src", CLK_SET_RATE_PARENT, | ||
621 | PX30_CLKSEL_CON(33), 0, | ||
622 | PX30_CLKGATE_CON(10), 5, GFLAGS, | ||
623 | &px30_i2s2_fracmux), | ||
624 | GATE(SCLK_I2S2, "clk_i2s2", "clk_i2s2_mux", CLK_SET_RATE_PARENT, | ||
625 | PX30_CLKGATE_CON(10), 6, GFLAGS), | ||
626 | COMPOSITE_NODIV(0, "clk_i2s2_out_pre", mux_i2s2_out_p, 0, | ||
627 | PX30_CLKSEL_CON(32), 15, 1, MFLAGS, | ||
628 | PX30_CLKGATE_CON(10), 7, GFLAGS), | ||
629 | GATE(SCLK_I2S2_OUT, "clk_i2s2_out", "clk_i2s2_out_pre", CLK_SET_RATE_PARENT, | ||
630 | PX30_CLKGATE_CON(10), 10, CLK_GATE_HIWORD_MASK), | ||
631 | |||
632 | COMPOSITE(SCLK_UART1_SRC, "clk_uart1_src", mux_uart_src_p, CLK_SET_RATE_NO_REPARENT, | ||
633 | PX30_CLKSEL_CON(34), 14, 2, MFLAGS, 0, 5, DFLAGS, | ||
634 | PX30_CLKGATE_CON(10), 12, GFLAGS), | ||
635 | COMPOSITE_NOMUX_HALFDIV(0, "clk_uart1_np5", "clk_uart1_src", 0, | ||
636 | PX30_CLKSEL_CON(35), 0, 5, DFLAGS, | ||
637 | PX30_CLKGATE_CON(10), 13, GFLAGS), | ||
638 | COMPOSITE_FRACMUX(0, "clk_uart1_frac", "clk_uart1_src", CLK_SET_RATE_PARENT, | ||
639 | PX30_CLKSEL_CON(36), 0, | ||
640 | PX30_CLKGATE_CON(10), 14, GFLAGS, | ||
641 | &px30_uart1_fracmux), | ||
642 | GATE(SCLK_UART1, "clk_uart1", "clk_uart1_mux", CLK_SET_RATE_PARENT, | ||
643 | PX30_CLKGATE_CON(10), 15, GFLAGS), | ||
644 | |||
645 | COMPOSITE(SCLK_UART2_SRC, "clk_uart2_src", mux_uart_src_p, 0, | ||
646 | PX30_CLKSEL_CON(37), 14, 2, MFLAGS, 0, 5, DFLAGS, | ||
647 | PX30_CLKGATE_CON(11), 0, GFLAGS), | ||
648 | COMPOSITE_NOMUX_HALFDIV(0, "clk_uart2_np5", "clk_uart2_src", 0, | ||
649 | PX30_CLKSEL_CON(38), 0, 5, DFLAGS, | ||
650 | PX30_CLKGATE_CON(11), 1, GFLAGS), | ||
651 | COMPOSITE_FRACMUX(0, "clk_uart2_frac", "clk_uart2_src", CLK_SET_RATE_PARENT, | ||
652 | PX30_CLKSEL_CON(39), 0, | ||
653 | PX30_CLKGATE_CON(11), 2, GFLAGS, | ||
654 | &px30_uart2_fracmux), | ||
655 | GATE(SCLK_UART2, "clk_uart2", "clk_uart2_mux", CLK_SET_RATE_PARENT, | ||
656 | PX30_CLKGATE_CON(11), 3, GFLAGS), | ||
657 | |||
658 | COMPOSITE(0, "clk_uart3_src", mux_uart_src_p, 0, | ||
659 | PX30_CLKSEL_CON(40), 14, 2, MFLAGS, 0, 5, DFLAGS, | ||
660 | PX30_CLKGATE_CON(11), 4, GFLAGS), | ||
661 | COMPOSITE_NOMUX_HALFDIV(0, "clk_uart3_np5", "clk_uart3_src", 0, | ||
662 | PX30_CLKSEL_CON(41), 0, 5, DFLAGS, | ||
663 | PX30_CLKGATE_CON(11), 5, GFLAGS), | ||
664 | COMPOSITE_FRACMUX(0, "clk_uart3_frac", "clk_uart3_src", CLK_SET_RATE_PARENT, | ||
665 | PX30_CLKSEL_CON(42), 0, | ||
666 | PX30_CLKGATE_CON(11), 6, GFLAGS, | ||
667 | &px30_uart3_fracmux), | ||
668 | GATE(SCLK_UART3, "clk_uart3", "clk_uart3_mux", CLK_SET_RATE_PARENT, | ||
669 | PX30_CLKGATE_CON(11), 7, GFLAGS), | ||
670 | |||
671 | COMPOSITE(0, "clk_uart4_src", mux_uart_src_p, 0, | ||
672 | PX30_CLKSEL_CON(43), 14, 2, MFLAGS, 0, 5, DFLAGS, | ||
673 | PX30_CLKGATE_CON(11), 8, GFLAGS), | ||
674 | COMPOSITE_NOMUX_HALFDIV(0, "clk_uart4_np5", "clk_uart4_src", 0, | ||
675 | PX30_CLKSEL_CON(44), 0, 5, DFLAGS, | ||
676 | PX30_CLKGATE_CON(11), 9, GFLAGS), | ||
677 | COMPOSITE_FRACMUX(0, "clk_uart4_frac", "clk_uart4_src", CLK_SET_RATE_PARENT, | ||
678 | PX30_CLKSEL_CON(45), 0, | ||
679 | PX30_CLKGATE_CON(11), 10, GFLAGS, | ||
680 | &px30_uart4_fracmux), | ||
681 | GATE(SCLK_UART4, "clk_uart4", "clk_uart4_mux", CLK_SET_RATE_PARENT, | ||
682 | PX30_CLKGATE_CON(11), 11, GFLAGS), | ||
683 | |||
684 | COMPOSITE(0, "clk_uart5_src", mux_uart_src_p, 0, | ||
685 | PX30_CLKSEL_CON(46), 14, 2, MFLAGS, 0, 5, DFLAGS, | ||
686 | PX30_CLKGATE_CON(11), 12, GFLAGS), | ||
687 | COMPOSITE_NOMUX_HALFDIV(0, "clk_uart5_np5", "clk_uart5_src", 0, | ||
688 | PX30_CLKSEL_CON(47), 0, 5, DFLAGS, | ||
689 | PX30_CLKGATE_CON(11), 13, GFLAGS), | ||
690 | COMPOSITE_FRACMUX(0, "clk_uart5_frac", "clk_uart5_src", CLK_SET_RATE_PARENT, | ||
691 | PX30_CLKSEL_CON(48), 0, | ||
692 | PX30_CLKGATE_CON(11), 14, GFLAGS, | ||
693 | &px30_uart5_fracmux), | ||
694 | GATE(SCLK_UART5, "clk_uart5", "clk_uart5_mux", CLK_SET_RATE_PARENT, | ||
695 | PX30_CLKGATE_CON(11), 15, GFLAGS), | ||
696 | |||
697 | COMPOSITE(SCLK_I2C0, "clk_i2c0", mux_gpll_xin24m_p, 0, | ||
698 | PX30_CLKSEL_CON(49), 7, 1, MFLAGS, 0, 7, DFLAGS, | ||
699 | PX30_CLKGATE_CON(12), 0, GFLAGS), | ||
700 | COMPOSITE(SCLK_I2C1, "clk_i2c1", mux_gpll_xin24m_p, 0, | ||
701 | PX30_CLKSEL_CON(49), 15, 1, MFLAGS, 8, 7, DFLAGS, | ||
702 | PX30_CLKGATE_CON(12), 1, GFLAGS), | ||
703 | COMPOSITE(SCLK_I2C2, "clk_i2c2", mux_gpll_xin24m_p, 0, | ||
704 | PX30_CLKSEL_CON(50), 7, 1, MFLAGS, 0, 7, DFLAGS, | ||
705 | PX30_CLKGATE_CON(12), 2, GFLAGS), | ||
706 | COMPOSITE(SCLK_I2C3, "clk_i2c3", mux_gpll_xin24m_p, 0, | ||
707 | PX30_CLKSEL_CON(50), 15, 1, MFLAGS, 8, 7, DFLAGS, | ||
708 | PX30_CLKGATE_CON(12), 3, GFLAGS), | ||
709 | COMPOSITE(SCLK_PWM0, "clk_pwm0", mux_gpll_xin24m_p, 0, | ||
710 | PX30_CLKSEL_CON(52), 7, 1, MFLAGS, 0, 7, DFLAGS, | ||
711 | PX30_CLKGATE_CON(12), 5, GFLAGS), | ||
712 | COMPOSITE(SCLK_PWM1, "clk_pwm1", mux_gpll_xin24m_p, 0, | ||
713 | PX30_CLKSEL_CON(52), 15, 1, MFLAGS, 8, 7, DFLAGS, | ||
714 | PX30_CLKGATE_CON(12), 6, GFLAGS), | ||
715 | COMPOSITE(SCLK_SPI0, "clk_spi0", mux_gpll_xin24m_p, 0, | ||
716 | PX30_CLKSEL_CON(53), 7, 1, MFLAGS, 0, 7, DFLAGS, | ||
717 | PX30_CLKGATE_CON(12), 7, GFLAGS), | ||
718 | COMPOSITE(SCLK_SPI1, "clk_spi1", mux_gpll_xin24m_p, 0, | ||
719 | PX30_CLKSEL_CON(53), 15, 1, MFLAGS, 8, 7, DFLAGS, | ||
720 | PX30_CLKGATE_CON(12), 8, GFLAGS), | ||
721 | |||
722 | GATE(SCLK_TIMER0, "sclk_timer0", "xin24m", 0, | ||
723 | PX30_CLKGATE_CON(13), 0, GFLAGS), | ||
724 | GATE(SCLK_TIMER1, "sclk_timer1", "xin24m", 0, | ||
725 | PX30_CLKGATE_CON(13), 1, GFLAGS), | ||
726 | GATE(SCLK_TIMER2, "sclk_timer2", "xin24m", 0, | ||
727 | PX30_CLKGATE_CON(13), 2, GFLAGS), | ||
728 | GATE(SCLK_TIMER3, "sclk_timer3", "xin24m", 0, | ||
729 | PX30_CLKGATE_CON(13), 3, GFLAGS), | ||
730 | GATE(SCLK_TIMER4, "sclk_timer4", "xin24m", 0, | ||
731 | PX30_CLKGATE_CON(13), 4, GFLAGS), | ||
732 | GATE(SCLK_TIMER5, "sclk_timer5", "xin24m", 0, | ||
733 | PX30_CLKGATE_CON(13), 5, GFLAGS), | ||
734 | |||
735 | COMPOSITE_NOMUX(SCLK_TSADC, "clk_tsadc", "xin24m", 0, | ||
736 | PX30_CLKSEL_CON(54), 0, 11, DFLAGS, | ||
737 | PX30_CLKGATE_CON(12), 9, GFLAGS), | ||
738 | COMPOSITE_NOMUX(SCLK_SARADC, "clk_saradc", "xin24m", 0, | ||
739 | PX30_CLKSEL_CON(55), 0, 11, DFLAGS, | ||
740 | PX30_CLKGATE_CON(12), 10, GFLAGS), | ||
741 | COMPOSITE_NOMUX(SCLK_OTP, "clk_otp", "xin24m", 0, | ||
742 | PX30_CLKSEL_CON(56), 0, 3, DFLAGS, | ||
743 | PX30_CLKGATE_CON(12), 11, GFLAGS), | ||
744 | COMPOSITE_NOMUX(SCLK_OTP_USR, "clk_otp_usr", "clk_otp", 0, | ||
745 | PX30_CLKSEL_CON(56), 4, 2, DFLAGS, | ||
746 | PX30_CLKGATE_CON(13), 6, GFLAGS), | ||
747 | |||
748 | GATE(0, "clk_cpu_boost", "xin24m", CLK_IGNORE_UNUSED, | ||
749 | PX30_CLKGATE_CON(12), 12, GFLAGS), | ||
750 | |||
751 | /* PD_CRYPTO */ | ||
752 | GATE(0, "aclk_crypto_pre", "aclk_bus_pre", 0, | ||
753 | PX30_CLKGATE_CON(8), 12, GFLAGS), | ||
754 | GATE(0, "hclk_crypto_pre", "hclk_bus_pre", 0, | ||
755 | PX30_CLKGATE_CON(8), 13, GFLAGS), | ||
756 | COMPOSITE(SCLK_CRYPTO, "clk_crypto", mux_gpll_cpll_npll_p, 0, | ||
757 | PX30_CLKSEL_CON(25), 6, 2, MFLAGS, 0, 5, DFLAGS, | ||
758 | PX30_CLKGATE_CON(8), 14, GFLAGS), | ||
759 | COMPOSITE(SCLK_CRYPTO_APK, "clk_crypto_apk", mux_gpll_cpll_npll_p, 0, | ||
760 | PX30_CLKSEL_CON(25), 14, 2, MFLAGS, 8, 5, DFLAGS, | ||
761 | PX30_CLKGATE_CON(8), 15, GFLAGS), | ||
762 | |||
763 | /* | ||
764 | * Clock-Architecture Diagram 9 | ||
765 | */ | ||
766 | |||
767 | /* PD_BUS_TOP */ | ||
768 | GATE(0, "pclk_top_niu", "pclk_top_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(16), 0, GFLAGS), | ||
769 | GATE(0, "pclk_top_cru", "pclk_top_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(16), 1, GFLAGS), | ||
770 | GATE(PCLK_OTP_PHY, "pclk_otp_phy", "pclk_top_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(16), 2, GFLAGS), | ||
771 | GATE(0, "pclk_ddrphy", "pclk_top_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(16), 3, GFLAGS), | ||
772 | GATE(PCLK_MIPIDSIPHY, "pclk_mipidsiphy", "pclk_top_pre", 0, PX30_CLKGATE_CON(16), 4, GFLAGS), | ||
773 | GATE(PCLK_MIPICSIPHY, "pclk_mipicsiphy", "pclk_top_pre", 0, PX30_CLKGATE_CON(16), 5, GFLAGS), | ||
774 | GATE(PCLK_USB_GRF, "pclk_usb_grf", "pclk_top_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(16), 6, GFLAGS), | ||
775 | GATE(0, "pclk_cpu_hoost", "pclk_top_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(16), 7, GFLAGS), | ||
776 | |||
777 | /* PD_VI */ | ||
778 | GATE(0, "aclk_vi_niu", "aclk_vi_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(4), 15, GFLAGS), | ||
779 | GATE(ACLK_CIF, "aclk_cif", "aclk_vi_pre", 0, PX30_CLKGATE_CON(5), 1, GFLAGS), | ||
780 | GATE(ACLK_ISP, "aclk_isp", "aclk_vi_pre", 0, PX30_CLKGATE_CON(5), 3, GFLAGS), | ||
781 | GATE(0, "hclk_vi_niu", "hclk_vi_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(5), 0, GFLAGS), | ||
782 | GATE(HCLK_CIF, "hclk_cif", "hclk_vi_pre", 0, PX30_CLKGATE_CON(5), 2, GFLAGS), | ||
783 | GATE(HCLK_ISP, "hclk_isp", "hclk_vi_pre", 0, PX30_CLKGATE_CON(5), 4, GFLAGS), | ||
784 | |||
785 | /* PD_VO */ | ||
786 | GATE(0, "aclk_vo_niu", "aclk_vo_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(3), 0, GFLAGS), | ||
787 | GATE(ACLK_VOPB, "aclk_vopb", "aclk_vo_pre", 0, PX30_CLKGATE_CON(3), 3, GFLAGS), | ||
788 | GATE(ACLK_RGA, "aclk_rga", "aclk_vo_pre", 0, PX30_CLKGATE_CON(3), 7, GFLAGS), | ||
789 | GATE(ACLK_VOPL, "aclk_vopl", "aclk_vo_pre", 0, PX30_CLKGATE_CON(3), 5, GFLAGS), | ||
790 | |||
791 | GATE(0, "hclk_vo_niu", "hclk_vo_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(3), 1, GFLAGS), | ||
792 | GATE(HCLK_VOPB, "hclk_vopb", "hclk_vo_pre", 0, PX30_CLKGATE_CON(3), 4, GFLAGS), | ||
793 | GATE(HCLK_RGA, "hclk_rga", "hclk_vo_pre", 0, PX30_CLKGATE_CON(3), 8, GFLAGS), | ||
794 | GATE(HCLK_VOPL, "hclk_vopl", "hclk_vo_pre", 0, PX30_CLKGATE_CON(3), 6, GFLAGS), | ||
795 | |||
796 | GATE(0, "pclk_vo_niu", "pclk_vo_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(3), 2, GFLAGS), | ||
797 | GATE(PCLK_MIPI_DSI, "pclk_mipi_dsi", "pclk_vo_pre", 0, PX30_CLKGATE_CON(3), 9, GFLAGS), | ||
798 | |||
799 | /* PD_BUS */ | ||
800 | GATE(0, "aclk_bus_niu", "aclk_bus_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(13), 8, GFLAGS), | ||
801 | GATE(0, "aclk_intmem", "aclk_bus_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(13), 11, GFLAGS), | ||
802 | GATE(ACLK_GIC, "aclk_gic", "aclk_bus_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(13), 12, GFLAGS), | ||
803 | GATE(ACLK_DCF, "aclk_dcf", "aclk_bus_pre", 0, PX30_CLKGATE_CON(13), 15, GFLAGS), | ||
804 | |||
805 | GATE(0, "hclk_bus_niu", "hclk_bus_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(13), 9, GFLAGS), | ||
806 | GATE(0, "hclk_rom", "hclk_bus_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(13), 14, GFLAGS), | ||
807 | GATE(HCLK_PDM, "hclk_pdm", "hclk_bus_pre", 0, PX30_CLKGATE_CON(14), 1, GFLAGS), | ||
808 | GATE(HCLK_I2S0, "hclk_i2s0", "hclk_bus_pre", 0, PX30_CLKGATE_CON(14), 2, GFLAGS), | ||
809 | GATE(HCLK_I2S1, "hclk_i2s1", "hclk_bus_pre", 0, PX30_CLKGATE_CON(14), 3, GFLAGS), | ||
810 | GATE(HCLK_I2S2, "hclk_i2s2", "hclk_bus_pre", 0, PX30_CLKGATE_CON(14), 4, GFLAGS), | ||
811 | |||
812 | GATE(0, "pclk_bus_niu", "pclk_bus_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(13), 10, GFLAGS), | ||
813 | GATE(PCLK_DCF, "pclk_dcf", "pclk_bus_pre", 0, PX30_CLKGATE_CON(14), 0, GFLAGS), | ||
814 | GATE(PCLK_UART1, "pclk_uart1", "pclk_bus_pre", 0, PX30_CLKGATE_CON(14), 5, GFLAGS), | ||
815 | GATE(PCLK_UART2, "pclk_uart2", "pclk_bus_pre", 0, PX30_CLKGATE_CON(14), 6, GFLAGS), | ||
816 | GATE(PCLK_UART3, "pclk_uart3", "pclk_bus_pre", 0, PX30_CLKGATE_CON(14), 7, GFLAGS), | ||
817 | GATE(PCLK_UART4, "pclk_uart4", "pclk_bus_pre", 0, PX30_CLKGATE_CON(14), 8, GFLAGS), | ||
818 | GATE(PCLK_UART5, "pclk_uart5", "pclk_bus_pre", 0, PX30_CLKGATE_CON(14), 9, GFLAGS), | ||
819 | GATE(PCLK_I2C0, "pclk_i2c0", "pclk_bus_pre", 0, PX30_CLKGATE_CON(14), 10, GFLAGS), | ||
820 | GATE(PCLK_I2C1, "pclk_i2c1", "pclk_bus_pre", 0, PX30_CLKGATE_CON(14), 11, GFLAGS), | ||
821 | GATE(PCLK_I2C2, "pclk_i2c2", "pclk_bus_pre", 0, PX30_CLKGATE_CON(14), 12, GFLAGS), | ||
822 | GATE(PCLK_I2C3, "pclk_i2c3", "pclk_bus_pre", 0, PX30_CLKGATE_CON(14), 13, GFLAGS), | ||
823 | GATE(PCLK_I2C4, "pclk_i2c4", "pclk_bus_pre", 0, PX30_CLKGATE_CON(14), 14, GFLAGS), | ||
824 | GATE(PCLK_PWM0, "pclk_pwm0", "pclk_bus_pre", 0, PX30_CLKGATE_CON(14), 15, GFLAGS), | ||
825 | GATE(PCLK_PWM1, "pclk_pwm1", "pclk_bus_pre", 0, PX30_CLKGATE_CON(15), 0, GFLAGS), | ||
826 | GATE(PCLK_SPI0, "pclk_spi0", "pclk_bus_pre", 0, PX30_CLKGATE_CON(15), 1, GFLAGS), | ||
827 | GATE(PCLK_SPI1, "pclk_spi1", "pclk_bus_pre", 0, PX30_CLKGATE_CON(15), 2, GFLAGS), | ||
828 | GATE(PCLK_SARADC, "pclk_saradc", "pclk_bus_pre", 0, PX30_CLKGATE_CON(15), 3, GFLAGS), | ||
829 | GATE(PCLK_TSADC, "pclk_tsadc", "pclk_bus_pre", 0, PX30_CLKGATE_CON(15), 4, GFLAGS), | ||
830 | GATE(PCLK_TIMER, "pclk_timer", "pclk_bus_pre", 0, PX30_CLKGATE_CON(15), 5, GFLAGS), | ||
831 | GATE(PCLK_OTP_NS, "pclk_otp_ns", "pclk_bus_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(15), 6, GFLAGS), | ||
832 | GATE(PCLK_WDT_NS, "pclk_wdt_ns", "pclk_bus_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(15), 7, GFLAGS), | ||
833 | GATE(PCLK_GPIO1, "pclk_gpio1", "pclk_bus_pre", 0, PX30_CLKGATE_CON(15), 8, GFLAGS), | ||
834 | GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_bus_pre", 0, PX30_CLKGATE_CON(15), 9, GFLAGS), | ||
835 | GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_bus_pre", 0, PX30_CLKGATE_CON(15), 10, GFLAGS), | ||
836 | GATE(0, "pclk_grf", "pclk_bus_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(15), 11, GFLAGS), | ||
837 | GATE(0, "pclk_sgrf", "pclk_bus_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(15), 12, GFLAGS), | ||
838 | |||
839 | /* PD_VPU */ | ||
840 | GATE(0, "hclk_vpu_niu", "hclk_vpu_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(4), 7, GFLAGS), | ||
841 | GATE(HCLK_VPU, "hclk_vpu", "hclk_vpu_pre", 0, PX30_CLKGATE_CON(4), 6, GFLAGS), | ||
842 | GATE(0, "aclk_vpu_niu", "aclk_vpu_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(4), 5, GFLAGS), | ||
843 | GATE(ACLK_VPU, "aclk_vpu", "aclk_vpu_pre", 0, PX30_CLKGATE_CON(4), 4, GFLAGS), | ||
844 | |||
845 | /* PD_CRYPTO */ | ||
846 | GATE(0, "hclk_crypto_niu", "hclk_crypto_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(9), 3, GFLAGS), | ||
847 | GATE(HCLK_CRYPTO, "hclk_crypto", "hclk_crypto_pre", 0, PX30_CLKGATE_CON(9), 5, GFLAGS), | ||
848 | GATE(0, "aclk_crypto_niu", "aclk_crypto_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(9), 2, GFLAGS), | ||
849 | GATE(ACLK_CRYPTO, "aclk_crypto", "aclk_crypto_pre", 0, PX30_CLKGATE_CON(9), 4, GFLAGS), | ||
850 | |||
851 | /* PD_SDCARD */ | ||
852 | GATE(0, "hclk_sdmmc_niu", "hclk_sdmmc_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(7), 0, GFLAGS), | ||
853 | GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_sdmmc_pre", 0, PX30_CLKGATE_CON(7), 1, GFLAGS), | ||
854 | |||
855 | /* PD_PERI */ | ||
856 | GATE(0, "aclk_peri_niu", "aclk_peri_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(5), 9, GFLAGS), | ||
857 | |||
858 | /* PD_MMC_NAND */ | ||
859 | GATE(HCLK_NANDC, "hclk_nandc", "hclk_mmc_nand", 0, PX30_CLKGATE_CON(5), 15, GFLAGS), | ||
860 | GATE(0, "hclk_mmc_nand_niu", "hclk_mmc_nand", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(6), 8, GFLAGS), | ||
861 | GATE(HCLK_SDIO, "hclk_sdio", "hclk_mmc_nand", 0, PX30_CLKGATE_CON(6), 9, GFLAGS), | ||
862 | GATE(HCLK_EMMC, "hclk_emmc", "hclk_mmc_nand", 0, PX30_CLKGATE_CON(6), 10, GFLAGS), | ||
863 | GATE(HCLK_SFC, "hclk_sfc", "hclk_mmc_nand", 0, PX30_CLKGATE_CON(6), 11, GFLAGS), | ||
864 | |||
865 | /* PD_USB */ | ||
866 | GATE(0, "hclk_usb_niu", "hclk_usb", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(7), 4, GFLAGS), | ||
867 | GATE(HCLK_OTG, "hclk_otg", "hclk_usb", 0, PX30_CLKGATE_CON(7), 5, GFLAGS), | ||
868 | GATE(HCLK_HOST, "hclk_host", "hclk_usb", 0, PX30_CLKGATE_CON(7), 6, GFLAGS), | ||
869 | GATE(HCLK_HOST_ARB, "hclk_host_arb", "hclk_usb", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(7), 8, GFLAGS), | ||
870 | |||
871 | /* PD_GMAC */ | ||
872 | GATE(0, "aclk_gmac_niu", "aclk_gmac_pre", CLK_IGNORE_UNUSED, | ||
873 | PX30_CLKGATE_CON(8), 0, GFLAGS), | ||
874 | GATE(ACLK_GMAC, "aclk_gmac", "aclk_gmac_pre", 0, | ||
875 | PX30_CLKGATE_CON(8), 2, GFLAGS), | ||
876 | GATE(0, "pclk_gmac_niu", "pclk_gmac_pre", CLK_IGNORE_UNUSED, | ||
877 | PX30_CLKGATE_CON(8), 1, GFLAGS), | ||
878 | GATE(PCLK_GMAC, "pclk_gmac", "pclk_gmac_pre", 0, | ||
879 | PX30_CLKGATE_CON(8), 3, GFLAGS), | ||
880 | }; | ||
881 | |||
882 | static struct rockchip_clk_branch px30_clk_pmu_branches[] __initdata = { | ||
883 | /* | ||
884 | * Clock-Architecture Diagram 2 | ||
885 | */ | ||
886 | |||
887 | COMPOSITE_FRACMUX(0, "clk_rtc32k_frac", "xin24m", CLK_IGNORE_UNUSED, | ||
888 | PX30_PMU_CLKSEL_CON(1), 0, | ||
889 | PX30_PMU_CLKGATE_CON(0), 13, GFLAGS, | ||
890 | &px30_rtc32k_pmu_fracmux), | ||
891 | |||
892 | COMPOSITE_NOMUX(XIN24M_DIV, "xin24m_div", "xin24m", CLK_IGNORE_UNUSED, | ||
893 | PX30_PMU_CLKSEL_CON(0), 8, 5, DFLAGS, | ||
894 | PX30_PMU_CLKGATE_CON(0), 12, GFLAGS), | ||
895 | |||
896 | COMPOSITE_NOMUX(0, "clk_wifi_pmu_src", "gpll", 0, | ||
897 | PX30_PMU_CLKSEL_CON(2), 8, 6, DFLAGS, | ||
898 | PX30_PMU_CLKGATE_CON(0), 14, GFLAGS), | ||
899 | COMPOSITE_NODIV(SCLK_WIFI_PMU, "clk_wifi_pmu", mux_wifi_pmu_p, CLK_SET_RATE_PARENT, | ||
900 | PX30_PMU_CLKSEL_CON(2), 15, 1, MFLAGS, | ||
901 | PX30_PMU_CLKGATE_CON(0), 15, GFLAGS), | ||
902 | |||
903 | COMPOSITE(0, "clk_uart0_pmu_src", mux_uart_src_p, 0, | ||
904 | PX30_PMU_CLKSEL_CON(3), 14, 2, MFLAGS, 0, 5, DFLAGS, | ||
905 | PX30_PMU_CLKGATE_CON(1), 0, GFLAGS), | ||
906 | COMPOSITE_NOMUX_HALFDIV(0, "clk_uart0_np5", "clk_uart0_pmu_src", 0, | ||
907 | PX30_PMU_CLKSEL_CON(4), 0, 5, DFLAGS, | ||
908 | PX30_PMU_CLKGATE_CON(1), 1, GFLAGS), | ||
909 | COMPOSITE_FRACMUX(0, "clk_uart0_frac", "clk_uart0_pmu_src", CLK_SET_RATE_PARENT, | ||
910 | PX30_PMU_CLKSEL_CON(5), 0, | ||
911 | PX30_PMU_CLKGATE_CON(1), 2, GFLAGS, | ||
912 | &px30_uart0_pmu_fracmux), | ||
913 | GATE(SCLK_UART0_PMU, "clk_uart0_pmu", "clk_uart0_pmu_mux", CLK_SET_RATE_PARENT, | ||
914 | PX30_PMU_CLKGATE_CON(1), 3, GFLAGS), | ||
915 | |||
916 | GATE(SCLK_PVTM_PMU, "clk_pvtm_pmu", "xin24m", 0, | ||
917 | PX30_PMU_CLKGATE_CON(1), 4, GFLAGS), | ||
918 | |||
919 | COMPOSITE_NOMUX(PCLK_PMU_PRE, "pclk_pmu_pre", "gpll", 0, | ||
920 | PX30_PMU_CLKSEL_CON(0), 0, 5, DFLAGS, | ||
921 | PX30_PMU_CLKGATE_CON(0), 0, GFLAGS), | ||
922 | |||
923 | COMPOSITE_NOMUX(SCLK_REF24M_PMU, "clk_ref24m_pmu", "gpll", 0, | ||
924 | PX30_PMU_CLKSEL_CON(2), 0, 6, DFLAGS, | ||
925 | PX30_PMU_CLKGATE_CON(1), 8, GFLAGS), | ||
926 | COMPOSITE_NODIV(SCLK_USBPHY_REF, "clk_usbphy_ref", mux_usbphy_ref_p, CLK_SET_RATE_PARENT, | ||
927 | PX30_PMU_CLKSEL_CON(2), 6, 1, MFLAGS, | ||
928 | PX30_PMU_CLKGATE_CON(1), 9, GFLAGS), | ||
929 | COMPOSITE_NODIV(SCLK_MIPIDSIPHY_REF, "clk_mipidsiphy_ref", mux_mipidsiphy_ref_p, CLK_SET_RATE_PARENT, | ||
930 | PX30_PMU_CLKSEL_CON(2), 7, 1, MFLAGS, | ||
931 | PX30_PMU_CLKGATE_CON(1), 10, GFLAGS), | ||
932 | |||
933 | /* | ||
934 | * Clock-Architecture Diagram 9 | ||
935 | */ | ||
936 | |||
937 | /* PD_PMU */ | ||
938 | GATE(0, "pclk_pmu_niu", "pclk_pmu_pre", CLK_IGNORE_UNUSED, PX30_PMU_CLKGATE_CON(0), 1, GFLAGS), | ||
939 | GATE(0, "pclk_pmu_sgrf", "pclk_pmu_pre", CLK_IGNORE_UNUSED, PX30_PMU_CLKGATE_CON(0), 2, GFLAGS), | ||
940 | GATE(0, "pclk_pmu_grf", "pclk_pmu_pre", CLK_IGNORE_UNUSED, PX30_PMU_CLKGATE_CON(0), 3, GFLAGS), | ||
941 | GATE(0, "pclk_pmu", "pclk_pmu_pre", CLK_IGNORE_UNUSED, PX30_PMU_CLKGATE_CON(0), 4, GFLAGS), | ||
942 | GATE(0, "pclk_pmu_mem", "pclk_pmu_pre", CLK_IGNORE_UNUSED, PX30_PMU_CLKGATE_CON(0), 5, GFLAGS), | ||
943 | GATE(PCLK_GPIO0_PMU, "pclk_gpio0_pmu", "pclk_pmu_pre", 0, PX30_PMU_CLKGATE_CON(0), 6, GFLAGS), | ||
944 | GATE(PCLK_UART0_PMU, "pclk_uart0_pmu", "pclk_pmu_pre", 0, PX30_PMU_CLKGATE_CON(0), 7, GFLAGS), | ||
945 | GATE(0, "pclk_cru_pmu", "pclk_pmu_pre", CLK_IGNORE_UNUSED, PX30_PMU_CLKGATE_CON(0), 8, GFLAGS), | ||
946 | }; | ||
947 | |||
948 | static const char *const px30_pmucru_critical_clocks[] __initconst = { | ||
949 | "aclk_bus_pre", | ||
950 | "pclk_bus_pre", | ||
951 | "hclk_bus_pre", | ||
952 | "aclk_peri_pre", | ||
953 | "hclk_peri_pre", | ||
954 | "aclk_gpu_niu", | ||
955 | "pclk_top_pre", | ||
956 | "pclk_pmu_pre", | ||
957 | "hclk_usb_niu", | ||
958 | "pll_npll", | ||
959 | "usb480m", | ||
960 | "clk_uart2", | ||
961 | "pclk_uart2", | ||
962 | }; | ||
963 | |||
964 | static void __init px30_clk_init(struct device_node *np) | ||
965 | { | ||
966 | struct rockchip_clk_provider *ctx; | ||
967 | void __iomem *reg_base; | ||
968 | struct clk *clk; | ||
969 | |||
970 | reg_base = of_iomap(np, 0); | ||
971 | if (!reg_base) { | ||
972 | pr_err("%s: could not map cru region\n", __func__); | ||
973 | return; | ||
974 | } | ||
975 | |||
976 | ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS); | ||
977 | if (IS_ERR(ctx)) { | ||
978 | pr_err("%s: rockchip clk init failed\n", __func__); | ||
979 | iounmap(reg_base); | ||
980 | return; | ||
981 | } | ||
982 | |||
983 | /* aclk_dmac is controlled by sgrf_soc_con1[11]. */ | ||
984 | clk = clk_register_fixed_factor(NULL, "aclk_dmac", "aclk_bus_pre", 0, 1, 1); | ||
985 | if (IS_ERR(clk)) | ||
986 | pr_warn("%s: could not register clock aclk_dmac: %ld\n", | ||
987 | __func__, PTR_ERR(clk)); | ||
988 | else | ||
989 | rockchip_clk_add_lookup(ctx, clk, ACLK_DMAC); | ||
990 | |||
991 | rockchip_clk_register_plls(ctx, px30_pll_clks, | ||
992 | ARRAY_SIZE(px30_pll_clks), | ||
993 | PX30_GRF_SOC_STATUS0); | ||
994 | rockchip_clk_register_branches(ctx, px30_clk_branches, | ||
995 | ARRAY_SIZE(px30_clk_branches)); | ||
996 | |||
997 | rockchip_clk_register_armclk(ctx, ARMCLK, "armclk", | ||
998 | mux_armclk_p, ARRAY_SIZE(mux_armclk_p), | ||
999 | &px30_cpuclk_data, px30_cpuclk_rates, | ||
1000 | ARRAY_SIZE(px30_cpuclk_rates)); | ||
1001 | |||
1002 | rockchip_register_softrst(np, 12, reg_base + PX30_SOFTRST_CON(0), | ||
1003 | ROCKCHIP_SOFTRST_HIWORD_MASK); | ||
1004 | |||
1005 | rockchip_register_restart_notifier(ctx, PX30_GLB_SRST_FST, NULL); | ||
1006 | |||
1007 | rockchip_clk_of_add_provider(np, ctx); | ||
1008 | } | ||
1009 | CLK_OF_DECLARE(px30_cru, "rockchip,px30-cru", px30_clk_init); | ||
1010 | |||
1011 | static void __init px30_pmu_clk_init(struct device_node *np) | ||
1012 | { | ||
1013 | struct rockchip_clk_provider *ctx; | ||
1014 | void __iomem *reg_base; | ||
1015 | |||
1016 | reg_base = of_iomap(np, 0); | ||
1017 | if (!reg_base) { | ||
1018 | pr_err("%s: could not map cru pmu region\n", __func__); | ||
1019 | return; | ||
1020 | } | ||
1021 | |||
1022 | ctx = rockchip_clk_init(np, reg_base, CLKPMU_NR_CLKS); | ||
1023 | if (IS_ERR(ctx)) { | ||
1024 | pr_err("%s: rockchip pmu clk init failed\n", __func__); | ||
1025 | return; | ||
1026 | } | ||
1027 | |||
1028 | rockchip_clk_register_plls(ctx, px30_pmu_pll_clks, | ||
1029 | ARRAY_SIZE(px30_pmu_pll_clks), PX30_GRF_SOC_STATUS0); | ||
1030 | |||
1031 | rockchip_clk_register_branches(ctx, px30_clk_pmu_branches, | ||
1032 | ARRAY_SIZE(px30_clk_pmu_branches)); | ||
1033 | |||
1034 | rockchip_clk_protect_critical(px30_pmucru_critical_clocks, | ||
1035 | ARRAY_SIZE(px30_pmucru_critical_clocks)); | ||
1036 | |||
1037 | rockchip_clk_of_add_provider(np, ctx); | ||
1038 | } | ||
1039 | CLK_OF_DECLARE(px30_cru_pmu, "rockchip,px30-pmucru", px30_pmu_clk_init); | ||
diff --git a/drivers/clk/rockchip/clk-rk3399.c b/drivers/clk/rockchip/clk-rk3399.c index bca10d618f0a..5a628148f3f0 100644 --- a/drivers/clk/rockchip/clk-rk3399.c +++ b/drivers/clk/rockchip/clk-rk3399.c | |||
@@ -631,7 +631,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { | |||
631 | MUX(0, "clk_i2sout_src", mux_i2sch_p, CLK_SET_RATE_PARENT, | 631 | MUX(0, "clk_i2sout_src", mux_i2sch_p, CLK_SET_RATE_PARENT, |
632 | RK3399_CLKSEL_CON(31), 0, 2, MFLAGS), | 632 | RK3399_CLKSEL_CON(31), 0, 2, MFLAGS), |
633 | COMPOSITE_NODIV(SCLK_I2S_8CH_OUT, "clk_i2sout", mux_i2sout_p, CLK_SET_RATE_PARENT, | 633 | COMPOSITE_NODIV(SCLK_I2S_8CH_OUT, "clk_i2sout", mux_i2sout_p, CLK_SET_RATE_PARENT, |
634 | RK3399_CLKSEL_CON(30), 8, 2, MFLAGS, | 634 | RK3399_CLKSEL_CON(31), 2, 1, MFLAGS, |
635 | RK3399_CLKGATE_CON(8), 12, GFLAGS), | 635 | RK3399_CLKGATE_CON(8), 12, GFLAGS), |
636 | 636 | ||
637 | /* uart */ | 637 | /* uart */ |
@@ -1523,6 +1523,7 @@ static const char *const rk3399_pmucru_critical_clocks[] __initconst = { | |||
1523 | "pclk_pmu_src", | 1523 | "pclk_pmu_src", |
1524 | "fclk_cm0s_src_pmu", | 1524 | "fclk_cm0s_src_pmu", |
1525 | "clk_timer_src_pmu", | 1525 | "clk_timer_src_pmu", |
1526 | "pclk_rkpwm_pmu", | ||
1526 | }; | 1527 | }; |
1527 | 1528 | ||
1528 | static void __init rk3399_clk_init(struct device_node *np) | 1529 | static void __init rk3399_clk_init(struct device_node *np) |
diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c index 326b3fa44f5d..c3ad92965823 100644 --- a/drivers/clk/rockchip/clk.c +++ b/drivers/clk/rockchip/clk.c | |||
@@ -492,6 +492,16 @@ void __init rockchip_clk_register_branches( | |||
492 | list->gate_flags, flags, list->child, | 492 | list->gate_flags, flags, list->child, |
493 | &ctx->lock); | 493 | &ctx->lock); |
494 | break; | 494 | break; |
495 | case branch_half_divider: | ||
496 | clk = rockchip_clk_register_halfdiv(list->name, | ||
497 | list->parent_names, list->num_parents, | ||
498 | ctx->reg_base, list->muxdiv_offset, | ||
499 | list->mux_shift, list->mux_width, | ||
500 | list->mux_flags, list->div_shift, | ||
501 | list->div_width, list->div_flags, | ||
502 | list->gate_offset, list->gate_shift, | ||
503 | list->gate_flags, flags, &ctx->lock); | ||
504 | break; | ||
495 | case branch_gate: | 505 | case branch_gate: |
496 | flags |= CLK_SET_RATE_PARENT; | 506 | flags |= CLK_SET_RATE_PARENT; |
497 | 507 | ||
diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h index ef601dded32c..6b53fff4cc96 100644 --- a/drivers/clk/rockchip/clk.h +++ b/drivers/clk/rockchip/clk.h | |||
@@ -34,7 +34,46 @@ struct clk; | |||
34 | #define HIWORD_UPDATE(val, mask, shift) \ | 34 | #define HIWORD_UPDATE(val, mask, shift) \ |
35 | ((val) << (shift) | (mask) << ((shift) + 16)) | 35 | ((val) << (shift) | (mask) << ((shift) + 16)) |
36 | 36 | ||
37 | /* register positions shared by RV1108, RK2928, RK3036, RK3066, RK3188 and RK3228 */ | 37 | /* register positions shared by PX30, RV1108, RK2928, RK3036, RK3066, RK3188 and RK3228 */ |
38 | #define BOOST_PLL_H_CON(x) ((x) * 0x4) | ||
39 | #define BOOST_CLK_CON 0x0008 | ||
40 | #define BOOST_BOOST_CON 0x000c | ||
41 | #define BOOST_SWITCH_CNT 0x0010 | ||
42 | #define BOOST_HIGH_PERF_CNT0 0x0014 | ||
43 | #define BOOST_HIGH_PERF_CNT1 0x0018 | ||
44 | #define BOOST_STATIS_THRESHOLD 0x001c | ||
45 | #define BOOST_SHORT_SWITCH_CNT 0x0020 | ||
46 | #define BOOST_SWITCH_THRESHOLD 0x0024 | ||
47 | #define BOOST_FSM_STATUS 0x0028 | ||
48 | #define BOOST_PLL_L_CON(x) ((x) * 0x4 + 0x2c) | ||
49 | #define BOOST_RECOVERY_MASK 0x1 | ||
50 | #define BOOST_RECOVERY_SHIFT 1 | ||
51 | #define BOOST_SW_CTRL_MASK 0x1 | ||
52 | #define BOOST_SW_CTRL_SHIFT 2 | ||
53 | #define BOOST_LOW_FREQ_EN_MASK 0x1 | ||
54 | #define BOOST_LOW_FREQ_EN_SHIFT 3 | ||
55 | #define BOOST_BUSY_STATE BIT(8) | ||
56 | |||
57 | #define PX30_PLL_CON(x) ((x) * 0x4) | ||
58 | #define PX30_CLKSEL_CON(x) ((x) * 0x4 + 0x100) | ||
59 | #define PX30_CLKGATE_CON(x) ((x) * 0x4 + 0x200) | ||
60 | #define PX30_GLB_SRST_FST 0xb8 | ||
61 | #define PX30_GLB_SRST_SND 0xbc | ||
62 | #define PX30_SOFTRST_CON(x) ((x) * 0x4 + 0x300) | ||
63 | #define PX30_MODE_CON 0xa0 | ||
64 | #define PX30_MISC_CON 0xa4 | ||
65 | #define PX30_SDMMC_CON0 0x380 | ||
66 | #define PX30_SDMMC_CON1 0x384 | ||
67 | #define PX30_SDIO_CON0 0x388 | ||
68 | #define PX30_SDIO_CON1 0x38c | ||
69 | #define PX30_EMMC_CON0 0x390 | ||
70 | #define PX30_EMMC_CON1 0x394 | ||
71 | |||
72 | #define PX30_PMU_PLL_CON(x) ((x) * 0x4) | ||
73 | #define PX30_PMU_CLKSEL_CON(x) ((x) * 0x4 + 0x40) | ||
74 | #define PX30_PMU_CLKGATE_CON(x) ((x) * 0x4 + 0x80) | ||
75 | #define PX30_PMU_MODE 0x0020 | ||
76 | |||
38 | #define RV1108_PLL_CON(x) ((x) * 0x4) | 77 | #define RV1108_PLL_CON(x) ((x) * 0x4) |
39 | #define RV1108_CLKSEL_CON(x) ((x) * 0x4 + 0x60) | 78 | #define RV1108_CLKSEL_CON(x) ((x) * 0x4 + 0x60) |
40 | #define RV1108_CLKGATE_CON(x) ((x) * 0x4 + 0x120) | 79 | #define RV1108_CLKGATE_CON(x) ((x) * 0x4 + 0x120) |
@@ -354,6 +393,7 @@ enum rockchip_clk_branch_type { | |||
354 | branch_inverter, | 393 | branch_inverter, |
355 | branch_factor, | 394 | branch_factor, |
356 | branch_ddrclk, | 395 | branch_ddrclk, |
396 | branch_half_divider, | ||
357 | }; | 397 | }; |
358 | 398 | ||
359 | struct rockchip_clk_branch { | 399 | struct rockchip_clk_branch { |
@@ -684,6 +724,79 @@ struct rockchip_clk_branch { | |||
684 | .gate_flags = gf, \ | 724 | .gate_flags = gf, \ |
685 | } | 725 | } |
686 | 726 | ||
727 | #define COMPOSITE_HALFDIV(_id, cname, pnames, f, mo, ms, mw, mf, ds, dw,\ | ||
728 | df, go, gs, gf) \ | ||
729 | { \ | ||
730 | .id = _id, \ | ||
731 | .branch_type = branch_half_divider, \ | ||
732 | .name = cname, \ | ||
733 | .parent_names = pnames, \ | ||
734 | .num_parents = ARRAY_SIZE(pnames), \ | ||
735 | .flags = f, \ | ||
736 | .muxdiv_offset = mo, \ | ||
737 | .mux_shift = ms, \ | ||
738 | .mux_width = mw, \ | ||
739 | .mux_flags = mf, \ | ||
740 | .div_shift = ds, \ | ||
741 | .div_width = dw, \ | ||
742 | .div_flags = df, \ | ||
743 | .gate_offset = go, \ | ||
744 | .gate_shift = gs, \ | ||
745 | .gate_flags = gf, \ | ||
746 | } | ||
747 | |||
748 | #define COMPOSITE_NOGATE_HALFDIV(_id, cname, pnames, f, mo, ms, mw, mf, \ | ||
749 | ds, dw, df) \ | ||
750 | { \ | ||
751 | .id = _id, \ | ||
752 | .branch_type = branch_half_divider, \ | ||
753 | .name = cname, \ | ||
754 | .parent_names = pnames, \ | ||
755 | .num_parents = ARRAY_SIZE(pnames), \ | ||
756 | .flags = f, \ | ||
757 | .muxdiv_offset = mo, \ | ||
758 | .mux_shift = ms, \ | ||
759 | .mux_width = mw, \ | ||
760 | .mux_flags = mf, \ | ||
761 | .div_shift = ds, \ | ||
762 | .div_width = dw, \ | ||
763 | .div_flags = df, \ | ||
764 | .gate_offset = -1, \ | ||
765 | } | ||
766 | |||
767 | #define COMPOSITE_NOMUX_HALFDIV(_id, cname, pname, f, mo, ds, dw, df, \ | ||
768 | go, gs, gf) \ | ||
769 | { \ | ||
770 | .id = _id, \ | ||
771 | .branch_type = branch_half_divider, \ | ||
772 | .name = cname, \ | ||
773 | .parent_names = (const char *[]){ pname }, \ | ||
774 | .num_parents = 1, \ | ||
775 | .flags = f, \ | ||
776 | .muxdiv_offset = mo, \ | ||
777 | .div_shift = ds, \ | ||
778 | .div_width = dw, \ | ||
779 | .div_flags = df, \ | ||
780 | .gate_offset = go, \ | ||
781 | .gate_shift = gs, \ | ||
782 | .gate_flags = gf, \ | ||
783 | } | ||
784 | |||
785 | #define DIV_HALF(_id, cname, pname, f, o, s, w, df) \ | ||
786 | { \ | ||
787 | .id = _id, \ | ||
788 | .branch_type = branch_half_divider, \ | ||
789 | .name = cname, \ | ||
790 | .parent_names = (const char *[]){ pname }, \ | ||
791 | .num_parents = 1, \ | ||
792 | .flags = f, \ | ||
793 | .muxdiv_offset = o, \ | ||
794 | .div_shift = s, \ | ||
795 | .div_width = w, \ | ||
796 | .div_flags = df, \ | ||
797 | .gate_offset = -1, \ | ||
798 | } | ||
799 | |||
687 | struct rockchip_clk_provider *rockchip_clk_init(struct device_node *np, | 800 | struct rockchip_clk_provider *rockchip_clk_init(struct device_node *np, |
688 | void __iomem *base, unsigned long nr_clks); | 801 | void __iomem *base, unsigned long nr_clks); |
689 | void rockchip_clk_of_add_provider(struct device_node *np, | 802 | void rockchip_clk_of_add_provider(struct device_node *np, |
@@ -708,6 +821,17 @@ void rockchip_register_restart_notifier(struct rockchip_clk_provider *ctx, | |||
708 | 821 | ||
709 | #define ROCKCHIP_SOFTRST_HIWORD_MASK BIT(0) | 822 | #define ROCKCHIP_SOFTRST_HIWORD_MASK BIT(0) |
710 | 823 | ||
824 | struct clk *rockchip_clk_register_halfdiv(const char *name, | ||
825 | const char *const *parent_names, | ||
826 | u8 num_parents, void __iomem *base, | ||
827 | int muxdiv_offset, u8 mux_shift, | ||
828 | u8 mux_width, u8 mux_flags, | ||
829 | u8 div_shift, u8 div_width, | ||
830 | u8 div_flags, int gate_offset, | ||
831 | u8 gate_shift, u8 gate_flags, | ||
832 | unsigned long flags, | ||
833 | spinlock_t *lock); | ||
834 | |||
711 | #ifdef CONFIG_RESET_CONTROLLER | 835 | #ifdef CONFIG_RESET_CONTROLLER |
712 | void rockchip_register_softrst(struct device_node *np, | 836 | void rockchip_register_softrst(struct device_node *np, |
713 | unsigned int num_regs, | 837 | unsigned int num_regs, |
diff --git a/drivers/clk/samsung/clk-exynos4412-isp.c b/drivers/clk/samsung/clk-exynos4412-isp.c index d5f1ccb36300..cfaa057035ad 100644 --- a/drivers/clk/samsung/clk-exynos4412-isp.c +++ b/drivers/clk/samsung/clk-exynos4412-isp.c | |||
@@ -37,8 +37,6 @@ static const unsigned long exynos4x12_clk_isp_save[] __initconst = { | |||
37 | E4X12_GATE_ISP1, | 37 | E4X12_GATE_ISP1, |
38 | }; | 38 | }; |
39 | 39 | ||
40 | PNAME(mout_user_aclk400_mcuisp_p4x12) = { "fin_pll", "div_aclk400_mcuisp", }; | ||
41 | |||
42 | static struct samsung_div_clock exynos4x12_isp_div_clks[] = { | 40 | static struct samsung_div_clock exynos4x12_isp_div_clks[] = { |
43 | DIV(CLK_ISP_DIV_ISP0, "div_isp0", "aclk200", E4X12_DIV_ISP0, 0, 3), | 41 | DIV(CLK_ISP_DIV_ISP0, "div_isp0", "aclk200", E4X12_DIV_ISP0, 0, 3), |
44 | DIV(CLK_ISP_DIV_ISP1, "div_isp1", "aclk200", E4X12_DIV_ISP0, 4, 3), | 42 | DIV(CLK_ISP_DIV_ISP1, "div_isp1", "aclk200", E4X12_DIV_ISP0, 4, 3), |
diff --git a/drivers/clk/socfpga/clk-s10.c b/drivers/clk/socfpga/clk-s10.c index 72714633e39c..5b238fc314ac 100644 --- a/drivers/clk/socfpga/clk-s10.c +++ b/drivers/clk/socfpga/clk-s10.c | |||
@@ -28,7 +28,7 @@ static const char * const emaca_free_mux[] = {"peri_emaca_clk", "boot_clk"}; | |||
28 | static const char * const emacb_free_mux[] = {"peri_emacb_clk", "boot_clk"}; | 28 | static const char * const emacb_free_mux[] = {"peri_emacb_clk", "boot_clk"}; |
29 | static const char * const emac_ptp_free_mux[] = {"peri_emac_ptp_clk", "boot_clk"}; | 29 | static const char * const emac_ptp_free_mux[] = {"peri_emac_ptp_clk", "boot_clk"}; |
30 | static const char * const gpio_db_free_mux[] = {"peri_gpio_db_clk", "boot_clk"}; | 30 | static const char * const gpio_db_free_mux[] = {"peri_gpio_db_clk", "boot_clk"}; |
31 | static const char * const sdmmc_free_mux[] = {"peri_sdmmc_clk", "boot_clk"}; | 31 | static const char * const sdmmc_free_mux[] = {"main_sdmmc_clk", "boot_clk"}; |
32 | static const char * const s2f_usr1_free_mux[] = {"peri_s2f_usr1_clk", "boot_clk"}; | 32 | static const char * const s2f_usr1_free_mux[] = {"peri_s2f_usr1_clk", "boot_clk"}; |
33 | static const char * const psi_ref_free_mux[] = {"peri_psi_ref_clk", "boot_clk"}; | 33 | static const char * const psi_ref_free_mux[] = {"peri_psi_ref_clk", "boot_clk"}; |
34 | static const char * const mpu_mux[] = { "mpu_free_clk", "boot_clk",}; | 34 | static const char * const mpu_mux[] = { "mpu_free_clk", "boot_clk",}; |
@@ -37,6 +37,11 @@ static const char * const s2f_usr0_mux[] = {"f2s_free_clk", "boot_clk"}; | |||
37 | static const char * const emac_mux[] = {"emaca_free_clk", "emacb_free_clk"}; | 37 | static const char * const emac_mux[] = {"emaca_free_clk", "emacb_free_clk"}; |
38 | static const char * const noc_mux[] = {"noc_free_clk", "boot_clk"}; | 38 | static const char * const noc_mux[] = {"noc_free_clk", "boot_clk"}; |
39 | 39 | ||
40 | static const char * const mpu_free_mux[] = {"main_mpu_base_clk", | ||
41 | "peri_mpu_base_clk", | ||
42 | "osc1", "cb_intosc_hs_div2_clk", | ||
43 | "f2s_free_clk"}; | ||
44 | |||
40 | /* clocks in AO (always on) controller */ | 45 | /* clocks in AO (always on) controller */ |
41 | static const struct stratix10_pll_clock s10_pll_clks[] = { | 46 | static const struct stratix10_pll_clock s10_pll_clks[] = { |
42 | { STRATIX10_BOOT_CLK, "boot_clk", boot_mux, ARRAY_SIZE(boot_mux), 0, | 47 | { STRATIX10_BOOT_CLK, "boot_clk", boot_mux, ARRAY_SIZE(boot_mux), 0, |
@@ -57,7 +62,7 @@ static const struct stratix10_perip_c_clock s10_main_perip_c_clks[] = { | |||
57 | }; | 62 | }; |
58 | 63 | ||
59 | static const struct stratix10_perip_cnt_clock s10_main_perip_cnt_clks[] = { | 64 | static const struct stratix10_perip_cnt_clock s10_main_perip_cnt_clks[] = { |
60 | { STRATIX10_MPU_FREE_CLK, "mpu_free_clk", NULL, cntr_mux, ARRAY_SIZE(cntr_mux), | 65 | { STRATIX10_MPU_FREE_CLK, "mpu_free_clk", NULL, mpu_free_mux, ARRAY_SIZE(mpu_free_mux), |
61 | 0, 0x48, 0, 0, 0}, | 66 | 0, 0x48, 0, 0, 0}, |
62 | { STRATIX10_NOC_FREE_CLK, "noc_free_clk", NULL, noc_free_mux, ARRAY_SIZE(noc_free_mux), | 67 | { STRATIX10_NOC_FREE_CLK, "noc_free_clk", NULL, noc_free_mux, ARRAY_SIZE(noc_free_mux), |
63 | 0, 0x4C, 0, 0, 0}, | 68 | 0, 0x4C, 0, 0, 0}, |
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-de2.c b/drivers/clk/sunxi-ng/ccu-sun8i-de2.c index 468d1abaf0ee..bae5ee67a797 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-de2.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-de2.c | |||
@@ -289,16 +289,13 @@ static const struct of_device_id sunxi_de2_clk_ids[] = { | |||
289 | .data = &sun8i_v3s_de2_clk_desc, | 289 | .data = &sun8i_v3s_de2_clk_desc, |
290 | }, | 290 | }, |
291 | { | 291 | { |
292 | .compatible = "allwinner,sun50i-a64-de2-clk", | ||
293 | .data = &sun50i_a64_de2_clk_desc, | ||
294 | }, | ||
295 | { | ||
292 | .compatible = "allwinner,sun50i-h5-de2-clk", | 296 | .compatible = "allwinner,sun50i-h5-de2-clk", |
293 | .data = &sun50i_a64_de2_clk_desc, | 297 | .data = &sun50i_a64_de2_clk_desc, |
294 | }, | 298 | }, |
295 | /* | ||
296 | * The Allwinner A64 SoC needs some bit to be poke in syscon to make | ||
297 | * DE2 really working. | ||
298 | * So there's currently no A64 compatible here. | ||
299 | * H5 shares the same reset line with A64, so here H5 is using the | ||
300 | * clock description of A64. | ||
301 | */ | ||
302 | { } | 299 | { } |
303 | }; | 300 | }; |
304 | 301 | ||
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r40.c b/drivers/clk/sunxi-ng/ccu-sun8i-r40.c index 65ba6455feb7..0f388f6944d5 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-r40.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-r40.c | |||
@@ -66,17 +66,18 @@ static SUNXI_CCU_NM_WITH_GATE_LOCK(pll_audio_base_clk, "pll-audio-base", | |||
66 | CLK_SET_RATE_UNGATE); | 66 | CLK_SET_RATE_UNGATE); |
67 | 67 | ||
68 | /* TODO: The result of N/M is required to be in [8, 25] range. */ | 68 | /* TODO: The result of N/M is required to be in [8, 25] range. */ |
69 | static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video0_clk, "pll-video0", | 69 | static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN(pll_video0_clk, "pll-video0", |
70 | "osc24M", 0x0010, | 70 | "osc24M", 0x0010, |
71 | 8, 7, /* N */ | 71 | 192000000, /* Minimum rate */ |
72 | 0, 4, /* M */ | 72 | 8, 7, /* N */ |
73 | BIT(24), /* frac enable */ | 73 | 0, 4, /* M */ |
74 | BIT(25), /* frac select */ | 74 | BIT(24), /* frac enable */ |
75 | 270000000, /* frac rate 0 */ | 75 | BIT(25), /* frac select */ |
76 | 297000000, /* frac rate 1 */ | 76 | 270000000, /* frac rate 0 */ |
77 | BIT(31), /* gate */ | 77 | 297000000, /* frac rate 1 */ |
78 | BIT(28), /* lock */ | 78 | BIT(31), /* gate */ |
79 | CLK_SET_RATE_UNGATE); | 79 | BIT(28), /* lock */ |
80 | CLK_SET_RATE_UNGATE); | ||
80 | 81 | ||
81 | /* TODO: The result of N/M is required to be in [8, 25] range. */ | 82 | /* TODO: The result of N/M is required to be in [8, 25] range. */ |
82 | static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve", | 83 | static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve", |
@@ -152,17 +153,18 @@ static struct ccu_nk pll_periph1_clk = { | |||
152 | }; | 153 | }; |
153 | 154 | ||
154 | /* TODO: The result of N/M is required to be in [8, 25] range. */ | 155 | /* TODO: The result of N/M is required to be in [8, 25] range. */ |
155 | static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video1_clk, "pll-video1", | 156 | static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN(pll_video1_clk, "pll-video1", |
156 | "osc24M", 0x030, | 157 | "osc24M", 0x030, |
157 | 8, 7, /* N */ | 158 | 192000000, /* Minimum rate */ |
158 | 0, 4, /* M */ | 159 | 8, 7, /* N */ |
159 | BIT(24), /* frac enable */ | 160 | 0, 4, /* M */ |
160 | BIT(25), /* frac select */ | 161 | BIT(24), /* frac enable */ |
161 | 270000000, /* frac rate 0 */ | 162 | BIT(25), /* frac select */ |
162 | 297000000, /* frac rate 1 */ | 163 | 270000000, /* frac rate 0 */ |
163 | BIT(31), /* gate */ | 164 | 297000000, /* frac rate 1 */ |
164 | BIT(28), /* lock */ | 165 | BIT(31), /* gate */ |
165 | CLK_SET_RATE_UNGATE); | 166 | BIT(28), /* lock */ |
167 | CLK_SET_RATE_UNGATE); | ||
166 | 168 | ||
167 | static struct ccu_nkm pll_sata_clk = { | 169 | static struct ccu_nkm pll_sata_clk = { |
168 | .enable = BIT(31), | 170 | .enable = BIT(31), |
@@ -654,7 +656,8 @@ static SUNXI_CCU_GATE(dram_deinterlace_clk, "dram-deinterlace", "dram", | |||
654 | 656 | ||
655 | static const char * const de_parents[] = { "pll-periph0-2x", "pll-de" }; | 657 | static const char * const de_parents[] = { "pll-periph0-2x", "pll-de" }; |
656 | static SUNXI_CCU_M_WITH_MUX_GATE(de_clk, "de", de_parents, | 658 | static SUNXI_CCU_M_WITH_MUX_GATE(de_clk, "de", de_parents, |
657 | 0x104, 0, 4, 24, 3, BIT(31), 0); | 659 | 0x104, 0, 4, 24, 3, BIT(31), |
660 | CLK_SET_RATE_PARENT); | ||
658 | static SUNXI_CCU_M_WITH_MUX_GATE(mp_clk, "mp", de_parents, | 661 | static SUNXI_CCU_M_WITH_MUX_GATE(mp_clk, "mp", de_parents, |
659 | 0x108, 0, 4, 24, 3, BIT(31), 0); | 662 | 0x108, 0, 4, 24, 3, BIT(31), 0); |
660 | 663 | ||
@@ -666,9 +669,11 @@ static SUNXI_CCU_MUX_WITH_GATE(tcon_lcd0_clk, "tcon-lcd0", tcon_parents, | |||
666 | static SUNXI_CCU_MUX_WITH_GATE(tcon_lcd1_clk, "tcon-lcd1", tcon_parents, | 669 | static SUNXI_CCU_MUX_WITH_GATE(tcon_lcd1_clk, "tcon-lcd1", tcon_parents, |
667 | 0x114, 24, 3, BIT(31), CLK_SET_RATE_PARENT); | 670 | 0x114, 24, 3, BIT(31), CLK_SET_RATE_PARENT); |
668 | static SUNXI_CCU_M_WITH_MUX_GATE(tcon_tv0_clk, "tcon-tv0", tcon_parents, | 671 | static SUNXI_CCU_M_WITH_MUX_GATE(tcon_tv0_clk, "tcon-tv0", tcon_parents, |
669 | 0x118, 0, 4, 24, 3, BIT(31), 0); | 672 | 0x118, 0, 4, 24, 3, BIT(31), |
673 | CLK_SET_RATE_PARENT); | ||
670 | static SUNXI_CCU_M_WITH_MUX_GATE(tcon_tv1_clk, "tcon-tv1", tcon_parents, | 674 | static SUNXI_CCU_M_WITH_MUX_GATE(tcon_tv1_clk, "tcon-tv1", tcon_parents, |
671 | 0x11c, 0, 4, 24, 3, BIT(31), 0); | 675 | 0x11c, 0, 4, 24, 3, BIT(31), |
676 | CLK_SET_RATE_PARENT); | ||
672 | 677 | ||
673 | static const char * const deinterlace_parents[] = { "pll-periph0", | 678 | static const char * const deinterlace_parents[] = { "pll-periph0", |
674 | "pll-periph1" }; | 679 | "pll-periph1" }; |
@@ -698,7 +703,8 @@ static SUNXI_CCU_GATE(avs_clk, "avs", "osc24M", | |||
698 | 703 | ||
699 | static const char * const hdmi_parents[] = { "pll-video0", "pll-video1" }; | 704 | static const char * const hdmi_parents[] = { "pll-video0", "pll-video1" }; |
700 | static SUNXI_CCU_M_WITH_MUX_GATE(hdmi_clk, "hdmi", hdmi_parents, | 705 | static SUNXI_CCU_M_WITH_MUX_GATE(hdmi_clk, "hdmi", hdmi_parents, |
701 | 0x150, 0, 4, 24, 2, BIT(31), 0); | 706 | 0x150, 0, 4, 24, 2, BIT(31), |
707 | CLK_SET_RATE_PARENT); | ||
702 | 708 | ||
703 | static SUNXI_CCU_GATE(hdmi_slow_clk, "hdmi-slow", "osc24M", | 709 | static SUNXI_CCU_GATE(hdmi_slow_clk, "hdmi-slow", "osc24M", |
704 | 0x154, BIT(31), 0); | 710 | 0x154, BIT(31), 0); |
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r40.h b/drivers/clk/sunxi-ng/ccu-sun8i-r40.h index 0db8e1e97af8..db2a1243f9ff 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-r40.h +++ b/drivers/clk/sunxi-ng/ccu-sun8i-r40.h | |||
@@ -25,7 +25,9 @@ | |||
25 | #define CLK_PLL_AUDIO_2X 4 | 25 | #define CLK_PLL_AUDIO_2X 4 |
26 | #define CLK_PLL_AUDIO_4X 5 | 26 | #define CLK_PLL_AUDIO_4X 5 |
27 | #define CLK_PLL_AUDIO_8X 6 | 27 | #define CLK_PLL_AUDIO_8X 6 |
28 | #define CLK_PLL_VIDEO0 7 | 28 | |
29 | /* PLL_VIDEO0 is exported */ | ||
30 | |||
29 | #define CLK_PLL_VIDEO0_2X 8 | 31 | #define CLK_PLL_VIDEO0_2X 8 |
30 | #define CLK_PLL_VE 9 | 32 | #define CLK_PLL_VE 9 |
31 | #define CLK_PLL_DDR0 10 | 33 | #define CLK_PLL_DDR0 10 |
@@ -34,7 +36,9 @@ | |||
34 | #define CLK_PLL_PERIPH0_2X 13 | 36 | #define CLK_PLL_PERIPH0_2X 13 |
35 | #define CLK_PLL_PERIPH1 14 | 37 | #define CLK_PLL_PERIPH1 14 |
36 | #define CLK_PLL_PERIPH1_2X 15 | 38 | #define CLK_PLL_PERIPH1_2X 15 |
37 | #define CLK_PLL_VIDEO1 16 | 39 | |
40 | /* PLL_VIDEO1 is exported */ | ||
41 | |||
38 | #define CLK_PLL_VIDEO1_2X 17 | 42 | #define CLK_PLL_VIDEO1_2X 17 |
39 | #define CLK_PLL_SATA 18 | 43 | #define CLK_PLL_SATA 18 |
40 | #define CLK_PLL_SATA_OUT 19 | 44 | #define CLK_PLL_SATA_OUT 19 |
diff --git a/drivers/clk/tegra/Makefile b/drivers/clk/tegra/Makefile index b71692391bd6..6507acc843c7 100644 --- a/drivers/clk/tegra/Makefile +++ b/drivers/clk/tegra/Makefile | |||
@@ -8,6 +8,7 @@ obj-y += clk-periph-fixed.o | |||
8 | obj-y += clk-periph-gate.o | 8 | obj-y += clk-periph-gate.o |
9 | obj-y += clk-pll.o | 9 | obj-y += clk-pll.o |
10 | obj-y += clk-pll-out.o | 10 | obj-y += clk-pll-out.o |
11 | obj-y += clk-sdmmc-mux.o | ||
11 | obj-y += clk-super.o | 12 | obj-y += clk-super.o |
12 | obj-y += clk-tegra-audio.o | 13 | obj-y += clk-tegra-audio.o |
13 | obj-y += clk-tegra-periph.o | 14 | obj-y += clk-tegra-periph.o |
@@ -24,3 +25,4 @@ obj-$(CONFIG_ARCH_TEGRA_132_SOC) += clk-tegra124.o | |||
24 | obj-y += cvb.o | 25 | obj-y += cvb.o |
25 | obj-$(CONFIG_ARCH_TEGRA_210_SOC) += clk-tegra210.o | 26 | obj-$(CONFIG_ARCH_TEGRA_210_SOC) += clk-tegra210.o |
26 | obj-$(CONFIG_CLK_TEGRA_BPMP) += clk-bpmp.o | 27 | obj-$(CONFIG_CLK_TEGRA_BPMP) += clk-bpmp.o |
28 | obj-y += clk-utils.o | ||
diff --git a/drivers/clk/tegra/clk-bpmp.c b/drivers/clk/tegra/clk-bpmp.c index a896692b74ec..01dada561c10 100644 --- a/drivers/clk/tegra/clk-bpmp.c +++ b/drivers/clk/tegra/clk-bpmp.c | |||
@@ -586,9 +586,15 @@ static struct clk_hw *tegra_bpmp_clk_of_xlate(struct of_phandle_args *clkspec, | |||
586 | unsigned int id = clkspec->args[0], i; | 586 | unsigned int id = clkspec->args[0], i; |
587 | struct tegra_bpmp *bpmp = data; | 587 | struct tegra_bpmp *bpmp = data; |
588 | 588 | ||
589 | for (i = 0; i < bpmp->num_clocks; i++) | 589 | for (i = 0; i < bpmp->num_clocks; i++) { |
590 | if (bpmp->clocks[i]->id == id) | 590 | struct tegra_bpmp_clk *clk = bpmp->clocks[i]; |
591 | return &bpmp->clocks[i]->hw; | 591 | |
592 | if (!clk) | ||
593 | continue; | ||
594 | |||
595 | if (clk->id == id) | ||
596 | return &clk->hw; | ||
597 | } | ||
592 | 598 | ||
593 | return NULL; | 599 | return NULL; |
594 | } | 600 | } |
diff --git a/drivers/clk/tegra/clk-divider.c b/drivers/clk/tegra/clk-divider.c index 16e0aee14773..205fe8ff63f0 100644 --- a/drivers/clk/tegra/clk-divider.c +++ b/drivers/clk/tegra/clk-divider.c | |||
@@ -32,35 +32,15 @@ | |||
32 | static int get_div(struct tegra_clk_frac_div *divider, unsigned long rate, | 32 | static int get_div(struct tegra_clk_frac_div *divider, unsigned long rate, |
33 | unsigned long parent_rate) | 33 | unsigned long parent_rate) |
34 | { | 34 | { |
35 | u64 divider_ux1 = parent_rate; | 35 | int div; |
36 | u8 flags = divider->flags; | ||
37 | int mul; | ||
38 | |||
39 | if (!rate) | ||
40 | return 0; | ||
41 | |||
42 | mul = get_mul(divider); | ||
43 | |||
44 | if (!(flags & TEGRA_DIVIDER_INT)) | ||
45 | divider_ux1 *= mul; | ||
46 | |||
47 | if (flags & TEGRA_DIVIDER_ROUND_UP) | ||
48 | divider_ux1 += rate - 1; | ||
49 | |||
50 | do_div(divider_ux1, rate); | ||
51 | |||
52 | if (flags & TEGRA_DIVIDER_INT) | ||
53 | divider_ux1 *= mul; | ||
54 | 36 | ||
55 | divider_ux1 -= mul; | 37 | div = div_frac_get(rate, parent_rate, divider->width, |
38 | divider->frac_width, divider->flags); | ||
56 | 39 | ||
57 | if ((s64)divider_ux1 < 0) | 40 | if (div < 0) |
58 | return 0; | 41 | return 0; |
59 | 42 | ||
60 | if (divider_ux1 > get_max_div(divider)) | 43 | return div; |
61 | return get_max_div(divider); | ||
62 | |||
63 | return divider_ux1; | ||
64 | } | 44 | } |
65 | 45 | ||
66 | static unsigned long clk_frac_div_recalc_rate(struct clk_hw *hw, | 46 | static unsigned long clk_frac_div_recalc_rate(struct clk_hw *hw, |
@@ -194,6 +174,7 @@ static const struct clk_div_table mc_div_table[] = { | |||
194 | struct clk *tegra_clk_register_mc(const char *name, const char *parent_name, | 174 | struct clk *tegra_clk_register_mc(const char *name, const char *parent_name, |
195 | void __iomem *reg, spinlock_t *lock) | 175 | void __iomem *reg, spinlock_t *lock) |
196 | { | 176 | { |
197 | return clk_register_divider_table(NULL, name, parent_name, 0, reg, | 177 | return clk_register_divider_table(NULL, name, parent_name, |
198 | 16, 1, 0, mc_div_table, lock); | 178 | CLK_IS_CRITICAL, reg, 16, 1, 0, |
179 | mc_div_table, lock); | ||
199 | } | 180 | } |
diff --git a/drivers/clk/tegra/clk-emc.c b/drivers/clk/tegra/clk-emc.c index 5234acd30e89..0621a3a82ea6 100644 --- a/drivers/clk/tegra/clk-emc.c +++ b/drivers/clk/tegra/clk-emc.c | |||
@@ -132,7 +132,7 @@ static int emc_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) | |||
132 | timing = tegra->timings + i; | 132 | timing = tegra->timings + i; |
133 | 133 | ||
134 | if (timing->rate > req->max_rate) { | 134 | if (timing->rate > req->max_rate) { |
135 | i = min(i, 1); | 135 | i = max(i, 1); |
136 | req->rate = tegra->timings[i - 1].rate; | 136 | req->rate = tegra->timings[i - 1].rate; |
137 | return 0; | 137 | return 0; |
138 | } | 138 | } |
diff --git a/drivers/clk/tegra/clk-id.h b/drivers/clk/tegra/clk-id.h index b616e33c5255..de466b4446da 100644 --- a/drivers/clk/tegra/clk-id.h +++ b/drivers/clk/tegra/clk-id.h | |||
@@ -227,13 +227,11 @@ enum clk_id { | |||
227 | tegra_clk_sdmmc1_9, | 227 | tegra_clk_sdmmc1_9, |
228 | tegra_clk_sdmmc2, | 228 | tegra_clk_sdmmc2, |
229 | tegra_clk_sdmmc2_8, | 229 | tegra_clk_sdmmc2_8, |
230 | tegra_clk_sdmmc2_9, | ||
231 | tegra_clk_sdmmc3, | 230 | tegra_clk_sdmmc3, |
232 | tegra_clk_sdmmc3_8, | 231 | tegra_clk_sdmmc3_8, |
233 | tegra_clk_sdmmc3_9, | 232 | tegra_clk_sdmmc3_9, |
234 | tegra_clk_sdmmc4, | 233 | tegra_clk_sdmmc4, |
235 | tegra_clk_sdmmc4_8, | 234 | tegra_clk_sdmmc4_8, |
236 | tegra_clk_sdmmc4_9, | ||
237 | tegra_clk_se, | 235 | tegra_clk_se, |
238 | tegra_clk_soc_therm, | 236 | tegra_clk_soc_therm, |
239 | tegra_clk_soc_therm_8, | 237 | tegra_clk_soc_therm_8, |
diff --git a/drivers/clk/tegra/clk-sdmmc-mux.c b/drivers/clk/tegra/clk-sdmmc-mux.c new file mode 100644 index 000000000000..473d418533cb --- /dev/null +++ b/drivers/clk/tegra/clk-sdmmc-mux.c | |||
@@ -0,0 +1,251 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * Copyright (c) 2018 NVIDIA CORPORATION. All rights reserved. | ||
4 | * | ||
5 | * based on clk-mux.c | ||
6 | * | ||
7 | * Copyright (C) 2011 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de> | ||
8 | * Copyright (C) 2011 Richard Zhao, Linaro <richard.zhao@linaro.org> | ||
9 | * Copyright (C) 2011-2012 Mike Turquette, Linaro Ltd <mturquette@linaro.org> | ||
10 | * | ||
11 | */ | ||
12 | |||
13 | #include <linux/clk-provider.h> | ||
14 | #include <linux/err.h> | ||
15 | #include <linux/types.h> | ||
16 | |||
17 | #include "clk.h" | ||
18 | |||
19 | #define DIV_MASK GENMASK(7, 0) | ||
20 | #define MUX_SHIFT 29 | ||
21 | #define MUX_MASK GENMASK(MUX_SHIFT + 2, MUX_SHIFT) | ||
22 | #define SDMMC_MUL 2 | ||
23 | |||
24 | #define get_max_div(d) DIV_MASK | ||
25 | #define get_div_field(val) ((val) & DIV_MASK) | ||
26 | #define get_mux_field(val) (((val) & MUX_MASK) >> MUX_SHIFT) | ||
27 | |||
28 | static const char * const mux_sdmmc_parents[] = { | ||
29 | "pll_p", "pll_c4_out2", "pll_c4_out0", "pll_c4_out1", "clk_m" | ||
30 | }; | ||
31 | |||
32 | static const u8 mux_lj_idx[] = { | ||
33 | [0] = 0, [1] = 1, [2] = 2, [3] = 5, [4] = 6 | ||
34 | }; | ||
35 | |||
36 | static const u8 mux_non_lj_idx[] = { | ||
37 | [0] = 0, [1] = 3, [2] = 7, [3] = 4, [4] = 6 | ||
38 | }; | ||
39 | |||
40 | static u8 clk_sdmmc_mux_get_parent(struct clk_hw *hw) | ||
41 | { | ||
42 | struct tegra_sdmmc_mux *sdmmc_mux = to_clk_sdmmc_mux(hw); | ||
43 | int num_parents, i; | ||
44 | u32 src, val; | ||
45 | const u8 *mux_idx; | ||
46 | |||
47 | num_parents = clk_hw_get_num_parents(hw); | ||
48 | |||
49 | val = readl_relaxed(sdmmc_mux->reg); | ||
50 | src = get_mux_field(val); | ||
51 | if (get_div_field(val)) | ||
52 | mux_idx = mux_non_lj_idx; | ||
53 | else | ||
54 | mux_idx = mux_lj_idx; | ||
55 | |||
56 | for (i = 0; i < num_parents; i++) { | ||
57 | if (mux_idx[i] == src) | ||
58 | return i; | ||
59 | } | ||
60 | |||
61 | WARN(1, "Unknown parent selector %d\n", src); | ||
62 | |||
63 | return 0; | ||
64 | } | ||
65 | |||
66 | static int clk_sdmmc_mux_set_parent(struct clk_hw *hw, u8 index) | ||
67 | { | ||
68 | struct tegra_sdmmc_mux *sdmmc_mux = to_clk_sdmmc_mux(hw); | ||
69 | u32 val; | ||
70 | |||
71 | |||
72 | val = readl_relaxed(sdmmc_mux->reg); | ||
73 | if (get_div_field(val)) | ||
74 | index = mux_non_lj_idx[index]; | ||
75 | else | ||
76 | index = mux_lj_idx[index]; | ||
77 | |||
78 | val &= ~MUX_MASK; | ||
79 | val |= index << MUX_SHIFT; | ||
80 | |||
81 | writel(val, sdmmc_mux->reg); | ||
82 | |||
83 | return 0; | ||
84 | } | ||
85 | |||
86 | static unsigned long clk_sdmmc_mux_recalc_rate(struct clk_hw *hw, | ||
87 | unsigned long parent_rate) | ||
88 | { | ||
89 | struct tegra_sdmmc_mux *sdmmc_mux = to_clk_sdmmc_mux(hw); | ||
90 | u32 val; | ||
91 | int div; | ||
92 | u64 rate = parent_rate; | ||
93 | |||
94 | val = readl_relaxed(sdmmc_mux->reg); | ||
95 | div = get_div_field(val); | ||
96 | |||
97 | div += SDMMC_MUL; | ||
98 | |||
99 | rate *= SDMMC_MUL; | ||
100 | rate += div - 1; | ||
101 | do_div(rate, div); | ||
102 | |||
103 | return rate; | ||
104 | } | ||
105 | |||
106 | static int clk_sdmmc_mux_determine_rate(struct clk_hw *hw, | ||
107 | struct clk_rate_request *req) | ||
108 | { | ||
109 | struct tegra_sdmmc_mux *sdmmc_mux = to_clk_sdmmc_mux(hw); | ||
110 | int div; | ||
111 | unsigned long output_rate = req->best_parent_rate; | ||
112 | |||
113 | req->rate = max(req->rate, req->min_rate); | ||
114 | req->rate = min(req->rate, req->max_rate); | ||
115 | |||
116 | if (!req->rate) | ||
117 | return output_rate; | ||
118 | |||
119 | div = div_frac_get(req->rate, output_rate, 8, 1, sdmmc_mux->div_flags); | ||
120 | if (div < 0) | ||
121 | div = 0; | ||
122 | |||
123 | if (sdmmc_mux->div_flags & TEGRA_DIVIDER_ROUND_UP) | ||
124 | req->rate = DIV_ROUND_UP(output_rate * SDMMC_MUL, | ||
125 | div + SDMMC_MUL); | ||
126 | else | ||
127 | req->rate = output_rate * SDMMC_MUL / (div + SDMMC_MUL); | ||
128 | |||
129 | return 0; | ||
130 | } | ||
131 | |||
132 | static int clk_sdmmc_mux_set_rate(struct clk_hw *hw, unsigned long rate, | ||
133 | unsigned long parent_rate) | ||
134 | { | ||
135 | struct tegra_sdmmc_mux *sdmmc_mux = to_clk_sdmmc_mux(hw); | ||
136 | int div; | ||
137 | unsigned long flags = 0; | ||
138 | u32 val; | ||
139 | u8 src; | ||
140 | |||
141 | div = div_frac_get(rate, parent_rate, 8, 1, sdmmc_mux->div_flags); | ||
142 | if (div < 0) | ||
143 | return div; | ||
144 | |||
145 | if (sdmmc_mux->lock) | ||
146 | spin_lock_irqsave(sdmmc_mux->lock, flags); | ||
147 | |||
148 | src = clk_sdmmc_mux_get_parent(hw); | ||
149 | if (div) | ||
150 | src = mux_non_lj_idx[src]; | ||
151 | else | ||
152 | src = mux_lj_idx[src]; | ||
153 | |||
154 | val = src << MUX_SHIFT; | ||
155 | val |= div; | ||
156 | writel(val, sdmmc_mux->reg); | ||
157 | fence_udelay(2, sdmmc_mux->reg); | ||
158 | |||
159 | if (sdmmc_mux->lock) | ||
160 | spin_unlock_irqrestore(sdmmc_mux->lock, flags); | ||
161 | |||
162 | return 0; | ||
163 | } | ||
164 | |||
165 | static int clk_sdmmc_mux_is_enabled(struct clk_hw *hw) | ||
166 | { | ||
167 | struct tegra_sdmmc_mux *sdmmc_mux = to_clk_sdmmc_mux(hw); | ||
168 | const struct clk_ops *gate_ops = sdmmc_mux->gate_ops; | ||
169 | struct clk_hw *gate_hw = &sdmmc_mux->gate.hw; | ||
170 | |||
171 | __clk_hw_set_clk(gate_hw, hw); | ||
172 | |||
173 | return gate_ops->is_enabled(gate_hw); | ||
174 | } | ||
175 | |||
176 | static int clk_sdmmc_mux_enable(struct clk_hw *hw) | ||
177 | { | ||
178 | struct tegra_sdmmc_mux *sdmmc_mux = to_clk_sdmmc_mux(hw); | ||
179 | const struct clk_ops *gate_ops = sdmmc_mux->gate_ops; | ||
180 | struct clk_hw *gate_hw = &sdmmc_mux->gate.hw; | ||
181 | |||
182 | __clk_hw_set_clk(gate_hw, hw); | ||
183 | |||
184 | return gate_ops->enable(gate_hw); | ||
185 | } | ||
186 | |||
187 | static void clk_sdmmc_mux_disable(struct clk_hw *hw) | ||
188 | { | ||
189 | struct tegra_sdmmc_mux *sdmmc_mux = to_clk_sdmmc_mux(hw); | ||
190 | const struct clk_ops *gate_ops = sdmmc_mux->gate_ops; | ||
191 | struct clk_hw *gate_hw = &sdmmc_mux->gate.hw; | ||
192 | |||
193 | gate_ops->disable(gate_hw); | ||
194 | } | ||
195 | |||
196 | static const struct clk_ops tegra_clk_sdmmc_mux_ops = { | ||
197 | .get_parent = clk_sdmmc_mux_get_parent, | ||
198 | .set_parent = clk_sdmmc_mux_set_parent, | ||
199 | .determine_rate = clk_sdmmc_mux_determine_rate, | ||
200 | .recalc_rate = clk_sdmmc_mux_recalc_rate, | ||
201 | .set_rate = clk_sdmmc_mux_set_rate, | ||
202 | .is_enabled = clk_sdmmc_mux_is_enabled, | ||
203 | .enable = clk_sdmmc_mux_enable, | ||
204 | .disable = clk_sdmmc_mux_disable, | ||
205 | }; | ||
206 | |||
207 | struct clk *tegra_clk_register_sdmmc_mux_div(const char *name, | ||
208 | void __iomem *clk_base, u32 offset, u32 clk_num, u8 div_flags, | ||
209 | unsigned long flags, void *lock) | ||
210 | { | ||
211 | struct clk *clk; | ||
212 | struct clk_init_data init; | ||
213 | const struct tegra_clk_periph_regs *bank; | ||
214 | struct tegra_sdmmc_mux *sdmmc_mux; | ||
215 | |||
216 | init.ops = &tegra_clk_sdmmc_mux_ops; | ||
217 | init.name = name; | ||
218 | init.flags = flags; | ||
219 | init.parent_names = mux_sdmmc_parents; | ||
220 | init.num_parents = ARRAY_SIZE(mux_sdmmc_parents); | ||
221 | |||
222 | bank = get_reg_bank(clk_num); | ||
223 | if (!bank) | ||
224 | return ERR_PTR(-EINVAL); | ||
225 | |||
226 | sdmmc_mux = kzalloc(sizeof(*sdmmc_mux), GFP_KERNEL); | ||
227 | if (!sdmmc_mux) | ||
228 | return ERR_PTR(-ENOMEM); | ||
229 | |||
230 | /* Data in .init is copied by clk_register(), so stack variable OK */ | ||
231 | sdmmc_mux->hw.init = &init; | ||
232 | sdmmc_mux->reg = clk_base + offset; | ||
233 | sdmmc_mux->lock = lock; | ||
234 | sdmmc_mux->gate.clk_base = clk_base; | ||
235 | sdmmc_mux->gate.regs = bank; | ||
236 | sdmmc_mux->gate.enable_refcnt = periph_clk_enb_refcnt; | ||
237 | sdmmc_mux->gate.clk_num = clk_num; | ||
238 | sdmmc_mux->gate.flags = TEGRA_PERIPH_ON_APB; | ||
239 | sdmmc_mux->div_flags = div_flags; | ||
240 | sdmmc_mux->gate_ops = &tegra_clk_periph_gate_ops; | ||
241 | |||
242 | clk = clk_register(NULL, &sdmmc_mux->hw); | ||
243 | if (IS_ERR(clk)) { | ||
244 | kfree(sdmmc_mux); | ||
245 | return clk; | ||
246 | } | ||
247 | |||
248 | sdmmc_mux->gate.hw.clk = clk; | ||
249 | |||
250 | return clk; | ||
251 | } | ||
diff --git a/drivers/clk/tegra/clk-tegra-periph.c b/drivers/clk/tegra/clk-tegra-periph.c index 2acba2986bc6..38c4eb28c8bf 100644 --- a/drivers/clk/tegra/clk-tegra-periph.c +++ b/drivers/clk/tegra/clk-tegra-periph.c | |||
@@ -451,15 +451,6 @@ static u32 mux_pllp_pllc4_out2_pllc4_out1_clkm_pllc4_out0_idx[] = { | |||
451 | [0] = 0, [1] = 3, [2] = 4, [3] = 6, [4] = 7, | 451 | [0] = 0, [1] = 3, [2] = 4, [3] = 6, [4] = 7, |
452 | }; | 452 | }; |
453 | 453 | ||
454 | static const char *mux_pllp_clkm_pllc4_out2_out1_out0_lj[] = { | ||
455 | "pll_p", | ||
456 | "pll_c4_out2", "pll_c4_out0", /* LJ input */ | ||
457 | "pll_c4_out2", "pll_c4_out1", | ||
458 | "pll_c4_out1", /* LJ input */ | ||
459 | "clk_m", "pll_c4_out0" | ||
460 | }; | ||
461 | #define mux_pllp_clkm_pllc4_out2_out1_out0_lj_idx NULL | ||
462 | |||
463 | static const char *mux_pllp_pllc2_c_c3_clkm[] = { | 454 | static const char *mux_pllp_pllc2_c_c3_clkm[] = { |
464 | "pll_p", "pll_c2", "pll_c", "pll_c3", "clk_m" | 455 | "pll_p", "pll_c2", "pll_c", "pll_c3", "clk_m" |
465 | }; | 456 | }; |
@@ -686,9 +677,7 @@ static struct tegra_periph_init_data periph_clks[] = { | |||
686 | MUX("sdmmc3", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC3, 69, TEGRA_PERIPH_ON_APB, tegra_clk_sdmmc3), | 677 | MUX("sdmmc3", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC3, 69, TEGRA_PERIPH_ON_APB, tegra_clk_sdmmc3), |
687 | MUX("sdmmc4", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC4, 15, TEGRA_PERIPH_ON_APB, tegra_clk_sdmmc4), | 678 | MUX("sdmmc4", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC4, 15, TEGRA_PERIPH_ON_APB, tegra_clk_sdmmc4), |
688 | MUX8("sdmmc1", mux_pllp_pllc4_out2_pllc4_out1_clkm_pllc4_out0, CLK_SOURCE_SDMMC1, 14, TEGRA_PERIPH_ON_APB, tegra_clk_sdmmc1_9), | 679 | MUX8("sdmmc1", mux_pllp_pllc4_out2_pllc4_out1_clkm_pllc4_out0, CLK_SOURCE_SDMMC1, 14, TEGRA_PERIPH_ON_APB, tegra_clk_sdmmc1_9), |
689 | MUX8("sdmmc2", mux_pllp_clkm_pllc4_out2_out1_out0_lj, CLK_SOURCE_SDMMC2, 9, TEGRA_PERIPH_ON_APB, tegra_clk_sdmmc2_9), | ||
690 | MUX8("sdmmc3", mux_pllp_pllc4_out2_pllc4_out1_clkm_pllc4_out0, CLK_SOURCE_SDMMC3, 69, TEGRA_PERIPH_ON_APB, tegra_clk_sdmmc3_9), | 680 | MUX8("sdmmc3", mux_pllp_pllc4_out2_pllc4_out1_clkm_pllc4_out0, CLK_SOURCE_SDMMC3, 69, TEGRA_PERIPH_ON_APB, tegra_clk_sdmmc3_9), |
691 | MUX8("sdmmc4", mux_pllp_clkm_pllc4_out2_out1_out0_lj, CLK_SOURCE_SDMMC4, 15, TEGRA_PERIPH_ON_APB, tegra_clk_sdmmc4_9), | ||
692 | MUX("la", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_LA, 76, TEGRA_PERIPH_ON_APB, tegra_clk_la), | 681 | MUX("la", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_LA, 76, TEGRA_PERIPH_ON_APB, tegra_clk_la), |
693 | MUX("trace", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_TRACE, 77, TEGRA_PERIPH_ON_APB, tegra_clk_trace), | 682 | MUX("trace", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_TRACE, 77, TEGRA_PERIPH_ON_APB, tegra_clk_trace), |
694 | MUX("owr", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_OWR, 71, TEGRA_PERIPH_ON_APB, tegra_clk_owr), | 683 | MUX("owr", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_OWR, 71, TEGRA_PERIPH_ON_APB, tegra_clk_owr), |
diff --git a/drivers/clk/tegra/clk-tegra124.c b/drivers/clk/tegra/clk-tegra124.c index 0c69c7970950..b6cf28ca2ed2 100644 --- a/drivers/clk/tegra/clk-tegra124.c +++ b/drivers/clk/tegra/clk-tegra124.c | |||
@@ -1267,7 +1267,7 @@ static struct tegra_clk_init_table common_init_table[] __initdata = { | |||
1267 | { TEGRA124_CLK_I2S2, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0 }, | 1267 | { TEGRA124_CLK_I2S2, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0 }, |
1268 | { TEGRA124_CLK_I2S3, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0 }, | 1268 | { TEGRA124_CLK_I2S3, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0 }, |
1269 | { TEGRA124_CLK_I2S4, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0 }, | 1269 | { TEGRA124_CLK_I2S4, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0 }, |
1270 | { TEGRA124_CLK_VDE, TEGRA124_CLK_CLK_MAX, 600000000, 0 }, | 1270 | { TEGRA124_CLK_VDE, TEGRA124_CLK_PLL_C3, 600000000, 0 }, |
1271 | { TEGRA124_CLK_HOST1X, TEGRA124_CLK_PLL_P, 136000000, 1 }, | 1271 | { TEGRA124_CLK_HOST1X, TEGRA124_CLK_PLL_P, 136000000, 1 }, |
1272 | { TEGRA124_CLK_DSIALP, TEGRA124_CLK_PLL_P, 68000000, 0 }, | 1272 | { TEGRA124_CLK_DSIALP, TEGRA124_CLK_PLL_P, 68000000, 0 }, |
1273 | { TEGRA124_CLK_DSIBLP, TEGRA124_CLK_PLL_P, 68000000, 0 }, | 1273 | { TEGRA124_CLK_DSIBLP, TEGRA124_CLK_PLL_P, 68000000, 0 }, |
@@ -1290,6 +1290,7 @@ static struct tegra_clk_init_table common_init_table[] __initdata = { | |||
1290 | { TEGRA124_CLK_MSELECT, TEGRA124_CLK_CLK_MAX, 0, 1 }, | 1290 | { TEGRA124_CLK_MSELECT, TEGRA124_CLK_CLK_MAX, 0, 1 }, |
1291 | { TEGRA124_CLK_CSITE, TEGRA124_CLK_CLK_MAX, 0, 1 }, | 1291 | { TEGRA124_CLK_CSITE, TEGRA124_CLK_CLK_MAX, 0, 1 }, |
1292 | { TEGRA124_CLK_TSENSOR, TEGRA124_CLK_CLK_M, 400000, 0 }, | 1292 | { TEGRA124_CLK_TSENSOR, TEGRA124_CLK_CLK_M, 400000, 0 }, |
1293 | { TEGRA124_CLK_VIC03, TEGRA124_CLK_PLL_C3, 0, 0 }, | ||
1293 | /* must be the last entry */ | 1294 | /* must be the last entry */ |
1294 | { TEGRA124_CLK_CLK_MAX, TEGRA124_CLK_CLK_MAX, 0, 0 }, | 1295 | { TEGRA124_CLK_CLK_MAX, TEGRA124_CLK_CLK_MAX, 0, 0 }, |
1295 | }; | 1296 | }; |
diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c index 5435d01c636a..9eb1cb14fce1 100644 --- a/drivers/clk/tegra/clk-tegra210.c +++ b/drivers/clk/tegra/clk-tegra210.c | |||
@@ -44,6 +44,8 @@ | |||
44 | #define CLK_SOURCE_EMC 0x19c | 44 | #define CLK_SOURCE_EMC 0x19c |
45 | #define CLK_SOURCE_SOR1 0x410 | 45 | #define CLK_SOURCE_SOR1 0x410 |
46 | #define CLK_SOURCE_LA 0x1f8 | 46 | #define CLK_SOURCE_LA 0x1f8 |
47 | #define CLK_SOURCE_SDMMC2 0x154 | ||
48 | #define CLK_SOURCE_SDMMC4 0x164 | ||
47 | 49 | ||
48 | #define PLLC_BASE 0x80 | 50 | #define PLLC_BASE 0x80 |
49 | #define PLLC_OUT 0x84 | 51 | #define PLLC_OUT 0x84 |
@@ -2286,11 +2288,9 @@ static struct tegra_clk tegra210_clks[tegra_clk_max] __initdata = { | |||
2286 | [tegra_clk_rtc] = { .dt_id = TEGRA210_CLK_RTC, .present = true }, | 2288 | [tegra_clk_rtc] = { .dt_id = TEGRA210_CLK_RTC, .present = true }, |
2287 | [tegra_clk_timer] = { .dt_id = TEGRA210_CLK_TIMER, .present = true }, | 2289 | [tegra_clk_timer] = { .dt_id = TEGRA210_CLK_TIMER, .present = true }, |
2288 | [tegra_clk_uarta_8] = { .dt_id = TEGRA210_CLK_UARTA, .present = true }, | 2290 | [tegra_clk_uarta_8] = { .dt_id = TEGRA210_CLK_UARTA, .present = true }, |
2289 | [tegra_clk_sdmmc2_9] = { .dt_id = TEGRA210_CLK_SDMMC2, .present = true }, | ||
2290 | [tegra_clk_i2s1] = { .dt_id = TEGRA210_CLK_I2S1, .present = true }, | 2291 | [tegra_clk_i2s1] = { .dt_id = TEGRA210_CLK_I2S1, .present = true }, |
2291 | [tegra_clk_i2c1] = { .dt_id = TEGRA210_CLK_I2C1, .present = true }, | 2292 | [tegra_clk_i2c1] = { .dt_id = TEGRA210_CLK_I2C1, .present = true }, |
2292 | [tegra_clk_sdmmc1_9] = { .dt_id = TEGRA210_CLK_SDMMC1, .present = true }, | 2293 | [tegra_clk_sdmmc1_9] = { .dt_id = TEGRA210_CLK_SDMMC1, .present = true }, |
2293 | [tegra_clk_sdmmc4_9] = { .dt_id = TEGRA210_CLK_SDMMC4, .present = true }, | ||
2294 | [tegra_clk_pwm] = { .dt_id = TEGRA210_CLK_PWM, .present = true }, | 2294 | [tegra_clk_pwm] = { .dt_id = TEGRA210_CLK_PWM, .present = true }, |
2295 | [tegra_clk_i2s2] = { .dt_id = TEGRA210_CLK_I2S2, .present = true }, | 2295 | [tegra_clk_i2s2] = { .dt_id = TEGRA210_CLK_I2S2, .present = true }, |
2296 | [tegra_clk_usbd] = { .dt_id = TEGRA210_CLK_USBD, .present = true }, | 2296 | [tegra_clk_usbd] = { .dt_id = TEGRA210_CLK_USBD, .present = true }, |
@@ -3030,6 +3030,16 @@ static __init void tegra210_periph_clk_init(void __iomem *clk_base, | |||
3030 | 0, NULL); | 3030 | 0, NULL); |
3031 | clks[TEGRA210_CLK_ACLK] = clk; | 3031 | clks[TEGRA210_CLK_ACLK] = clk; |
3032 | 3032 | ||
3033 | clk = tegra_clk_register_sdmmc_mux_div("sdmmc2", clk_base, | ||
3034 | CLK_SOURCE_SDMMC2, 9, | ||
3035 | TEGRA_DIVIDER_ROUND_UP, 0, NULL); | ||
3036 | clks[TEGRA210_CLK_SDMMC2] = clk; | ||
3037 | |||
3038 | clk = tegra_clk_register_sdmmc_mux_div("sdmmc4", clk_base, | ||
3039 | CLK_SOURCE_SDMMC4, 15, | ||
3040 | TEGRA_DIVIDER_ROUND_UP, 0, NULL); | ||
3041 | clks[TEGRA210_CLK_SDMMC4] = clk; | ||
3042 | |||
3033 | for (i = 0; i < ARRAY_SIZE(tegra210_periph); i++) { | 3043 | for (i = 0; i < ARRAY_SIZE(tegra210_periph); i++) { |
3034 | struct tegra_periph_init_data *init = &tegra210_periph[i]; | 3044 | struct tegra_periph_init_data *init = &tegra210_periph[i]; |
3035 | struct clk **clkp; | 3045 | struct clk **clkp; |
diff --git a/drivers/clk/tegra/clk-utils.c b/drivers/clk/tegra/clk-utils.c new file mode 100644 index 000000000000..1a5daae4e501 --- /dev/null +++ b/drivers/clk/tegra/clk-utils.c | |||
@@ -0,0 +1,43 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. | ||
4 | */ | ||
5 | |||
6 | #include <asm/div64.h> | ||
7 | |||
8 | #include "clk.h" | ||
9 | |||
10 | #define div_mask(w) ((1 << (w)) - 1) | ||
11 | |||
12 | int div_frac_get(unsigned long rate, unsigned parent_rate, u8 width, | ||
13 | u8 frac_width, u8 flags) | ||
14 | { | ||
15 | u64 divider_ux1 = parent_rate; | ||
16 | int mul; | ||
17 | |||
18 | if (!rate) | ||
19 | return 0; | ||
20 | |||
21 | mul = 1 << frac_width; | ||
22 | |||
23 | if (!(flags & TEGRA_DIVIDER_INT)) | ||
24 | divider_ux1 *= mul; | ||
25 | |||
26 | if (flags & TEGRA_DIVIDER_ROUND_UP) | ||
27 | divider_ux1 += rate - 1; | ||
28 | |||
29 | do_div(divider_ux1, rate); | ||
30 | |||
31 | if (flags & TEGRA_DIVIDER_INT) | ||
32 | divider_ux1 *= mul; | ||
33 | |||
34 | if (divider_ux1 < mul) | ||
35 | return 0; | ||
36 | |||
37 | divider_ux1 -= mul; | ||
38 | |||
39 | if (divider_ux1 > div_mask(width)) | ||
40 | return div_mask(width); | ||
41 | |||
42 | return divider_ux1; | ||
43 | } | ||
diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index e1f88463b600..d2c3a010f8e9 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h | |||
@@ -19,6 +19,7 @@ | |||
19 | 19 | ||
20 | #include <linux/clk-provider.h> | 20 | #include <linux/clk-provider.h> |
21 | #include <linux/clkdev.h> | 21 | #include <linux/clkdev.h> |
22 | #include <linux/delay.h> | ||
22 | 23 | ||
23 | /** | 24 | /** |
24 | * struct tegra_clk_sync_source - external clock source from codec | 25 | * struct tegra_clk_sync_source - external clock source from codec |
@@ -705,6 +706,32 @@ struct clk *tegra_clk_register_super_clk(const char *name, | |||
705 | const char * const *parent_names, u8 num_parents, | 706 | const char * const *parent_names, u8 num_parents, |
706 | unsigned long flags, void __iomem *reg, u8 clk_super_flags, | 707 | unsigned long flags, void __iomem *reg, u8 clk_super_flags, |
707 | spinlock_t *lock); | 708 | spinlock_t *lock); |
709 | |||
710 | /** | ||
711 | * struct tegra_sdmmc_mux - switch divider with Low Jitter inputs for SDMMC | ||
712 | * | ||
713 | * @hw: handle between common and hardware-specific interfaces | ||
714 | * @reg: register controlling mux and divider | ||
715 | * @flags: hardware-specific flags | ||
716 | * @lock: optional register lock | ||
717 | * @gate: gate clock | ||
718 | * @gate_ops: gate clock ops | ||
719 | */ | ||
720 | struct tegra_sdmmc_mux { | ||
721 | struct clk_hw hw; | ||
722 | void __iomem *reg; | ||
723 | spinlock_t *lock; | ||
724 | const struct clk_ops *gate_ops; | ||
725 | struct tegra_clk_periph_gate gate; | ||
726 | u8 div_flags; | ||
727 | }; | ||
728 | |||
729 | #define to_clk_sdmmc_mux(_hw) container_of(_hw, struct tegra_sdmmc_mux, hw) | ||
730 | |||
731 | struct clk *tegra_clk_register_sdmmc_mux_div(const char *name, | ||
732 | void __iomem *clk_base, u32 offset, u32 clk_num, u8 div_flags, | ||
733 | unsigned long flags, void *lock); | ||
734 | |||
708 | /** | 735 | /** |
709 | * struct clk_init_table - clock initialization table | 736 | * struct clk_init_table - clock initialization table |
710 | * @clk_id: clock id as mentioned in device tree bindings | 737 | * @clk_id: clock id as mentioned in device tree bindings |
@@ -811,6 +838,9 @@ extern tegra_clk_apply_init_table_func tegra_clk_apply_init_table; | |||
811 | int tegra_pll_wait_for_lock(struct tegra_clk_pll *pll); | 838 | int tegra_pll_wait_for_lock(struct tegra_clk_pll *pll); |
812 | u16 tegra_pll_get_fixed_mdiv(struct clk_hw *hw, unsigned long input_rate); | 839 | u16 tegra_pll_get_fixed_mdiv(struct clk_hw *hw, unsigned long input_rate); |
813 | int tegra_pll_p_div_to_hw(struct tegra_clk_pll *pll, u8 p_div); | 840 | int tegra_pll_p_div_to_hw(struct tegra_clk_pll *pll, u8 p_div); |
841 | int div_frac_get(unsigned long rate, unsigned parent_rate, u8 width, | ||
842 | u8 frac_width, u8 flags); | ||
843 | |||
814 | 844 | ||
815 | /* Combined read fence with delay */ | 845 | /* Combined read fence with delay */ |
816 | #define fence_udelay(delay, reg) \ | 846 | #define fence_udelay(delay, reg) \ |
diff --git a/drivers/clk/uniphier/clk-uniphier-peri.c b/drivers/clk/uniphier/clk-uniphier-peri.c index 521c80e9a06f..89b3ac378b3f 100644 --- a/drivers/clk/uniphier/clk-uniphier-peri.c +++ b/drivers/clk/uniphier/clk-uniphier-peri.c | |||
@@ -27,6 +27,12 @@ | |||
27 | #define UNIPHIER_PERI_CLK_FI2C(idx, ch) \ | 27 | #define UNIPHIER_PERI_CLK_FI2C(idx, ch) \ |
28 | UNIPHIER_CLK_GATE("i2c" #ch, (idx), "i2c", 0x24, 24 + (ch)) | 28 | UNIPHIER_CLK_GATE("i2c" #ch, (idx), "i2c", 0x24, 24 + (ch)) |
29 | 29 | ||
30 | #define UNIPHIER_PERI_CLK_SCSSI(idx) \ | ||
31 | UNIPHIER_CLK_GATE("scssi", (idx), "spi", 0x20, 17) | ||
32 | |||
33 | #define UNIPHIER_PERI_CLK_MCSSI(idx) \ | ||
34 | UNIPHIER_CLK_GATE("mcssi", (idx), "spi", 0x24, 14) | ||
35 | |||
30 | const struct uniphier_clk_data uniphier_ld4_peri_clk_data[] = { | 36 | const struct uniphier_clk_data uniphier_ld4_peri_clk_data[] = { |
31 | UNIPHIER_PERI_CLK_UART(0, 0), | 37 | UNIPHIER_PERI_CLK_UART(0, 0), |
32 | UNIPHIER_PERI_CLK_UART(1, 1), | 38 | UNIPHIER_PERI_CLK_UART(1, 1), |
@@ -38,6 +44,7 @@ const struct uniphier_clk_data uniphier_ld4_peri_clk_data[] = { | |||
38 | UNIPHIER_PERI_CLK_I2C(6, 2), | 44 | UNIPHIER_PERI_CLK_I2C(6, 2), |
39 | UNIPHIER_PERI_CLK_I2C(7, 3), | 45 | UNIPHIER_PERI_CLK_I2C(7, 3), |
40 | UNIPHIER_PERI_CLK_I2C(8, 4), | 46 | UNIPHIER_PERI_CLK_I2C(8, 4), |
47 | UNIPHIER_PERI_CLK_SCSSI(11), | ||
41 | { /* sentinel */ } | 48 | { /* sentinel */ } |
42 | }; | 49 | }; |
43 | 50 | ||
@@ -53,5 +60,7 @@ const struct uniphier_clk_data uniphier_pro4_peri_clk_data[] = { | |||
53 | UNIPHIER_PERI_CLK_FI2C(8, 4), | 60 | UNIPHIER_PERI_CLK_FI2C(8, 4), |
54 | UNIPHIER_PERI_CLK_FI2C(9, 5), | 61 | UNIPHIER_PERI_CLK_FI2C(9, 5), |
55 | UNIPHIER_PERI_CLK_FI2C(10, 6), | 62 | UNIPHIER_PERI_CLK_FI2C(10, 6), |
63 | UNIPHIER_PERI_CLK_SCSSI(11), | ||
64 | UNIPHIER_PERI_CLK_MCSSI(12), | ||
56 | { /* sentinel */ } | 65 | { /* sentinel */ } |
57 | }; | 66 | }; |
diff --git a/drivers/clk/uniphier/clk-uniphier-sys.c b/drivers/clk/uniphier/clk-uniphier-sys.c index 4f5ff9fa11fd..2bb5a8570adc 100644 --- a/drivers/clk/uniphier/clk-uniphier-sys.c +++ b/drivers/clk/uniphier/clk-uniphier-sys.c | |||
@@ -29,18 +29,20 @@ | |||
29 | UNIPHIER_CLK_FACTOR("sd-200m", -1, "spll", 1, 10), \ | 29 | UNIPHIER_CLK_FACTOR("sd-200m", -1, "spll", 1, 10), \ |
30 | UNIPHIER_CLK_FACTOR("sd-133m", -1, "spll", 1, 15) | 30 | UNIPHIER_CLK_FACTOR("sd-133m", -1, "spll", 1, 15) |
31 | 31 | ||
32 | /* Denali driver requires clk_x rate (clk: 50MHz, clk_x & ecc_clk: 200MHz) */ | ||
33 | #define UNIPHIER_LD4_SYS_CLK_NAND(idx) \ | 32 | #define UNIPHIER_LD4_SYS_CLK_NAND(idx) \ |
34 | UNIPHIER_CLK_FACTOR("nand-200m", -1, "spll", 1, 8), \ | 33 | UNIPHIER_CLK_FACTOR("nand-50m", -1, "spll", 1, 32), \ |
35 | UNIPHIER_CLK_GATE("nand", (idx), "nand-200m", 0x2104, 2) | 34 | UNIPHIER_CLK_GATE("nand", (idx), "nand-50m", 0x2104, 2) |
36 | 35 | ||
37 | #define UNIPHIER_PRO5_SYS_CLK_NAND(idx) \ | 36 | #define UNIPHIER_PRO5_SYS_CLK_NAND(idx) \ |
38 | UNIPHIER_CLK_FACTOR("nand-200m", -1, "spll", 1, 12), \ | 37 | UNIPHIER_CLK_FACTOR("nand-50m", -1, "spll", 1, 48), \ |
39 | UNIPHIER_CLK_GATE("nand", (idx), "nand-200m", 0x2104, 2) | 38 | UNIPHIER_CLK_GATE("nand", (idx), "nand-50m", 0x2104, 2) |
40 | 39 | ||
41 | #define UNIPHIER_LD11_SYS_CLK_NAND(idx) \ | 40 | #define UNIPHIER_LD11_SYS_CLK_NAND(idx) \ |
42 | UNIPHIER_CLK_FACTOR("nand-200m", -1, "spll", 1, 10), \ | 41 | UNIPHIER_CLK_FACTOR("nand-50m", -1, "spll", 1, 40), \ |
43 | UNIPHIER_CLK_GATE("nand", (idx), "nand-200m", 0x210c, 0) | 42 | UNIPHIER_CLK_GATE("nand", (idx), "nand-50m", 0x210c, 0) |
43 | |||
44 | #define UNIPHIER_SYS_CLK_NAND_4X(idx) \ | ||
45 | UNIPHIER_CLK_FACTOR("nand-4x", (idx), "nand", 4, 1) | ||
44 | 46 | ||
45 | #define UNIPHIER_LD11_SYS_CLK_EMMC(idx) \ | 47 | #define UNIPHIER_LD11_SYS_CLK_EMMC(idx) \ |
46 | UNIPHIER_CLK_GATE("emmc", (idx), NULL, 0x210c, 2) | 48 | UNIPHIER_CLK_GATE("emmc", (idx), NULL, 0x210c, 2) |
@@ -93,7 +95,9 @@ const struct uniphier_clk_data uniphier_ld4_sys_clk_data[] = { | |||
93 | UNIPHIER_CLK_FACTOR("vpll27a", -1, "ref", 5625, 512), /* 270 MHz */ | 95 | UNIPHIER_CLK_FACTOR("vpll27a", -1, "ref", 5625, 512), /* 270 MHz */ |
94 | UNIPHIER_CLK_FACTOR("uart", 0, "a2pll", 1, 16), | 96 | UNIPHIER_CLK_FACTOR("uart", 0, "a2pll", 1, 16), |
95 | UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 16), | 97 | UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 16), |
98 | UNIPHIER_CLK_FACTOR("spi", -1, "spll", 1, 32), | ||
96 | UNIPHIER_LD4_SYS_CLK_NAND(2), | 99 | UNIPHIER_LD4_SYS_CLK_NAND(2), |
100 | UNIPHIER_SYS_CLK_NAND_4X(3), | ||
97 | UNIPHIER_LD4_SYS_CLK_SD, | 101 | UNIPHIER_LD4_SYS_CLK_SD, |
98 | UNIPHIER_CLK_FACTOR("usb2", -1, "upll", 1, 12), | 102 | UNIPHIER_CLK_FACTOR("usb2", -1, "upll", 1, 12), |
99 | UNIPHIER_LD4_SYS_CLK_STDMAC(8), /* Ether, HSC, MIO */ | 103 | UNIPHIER_LD4_SYS_CLK_STDMAC(8), /* Ether, HSC, MIO */ |
@@ -108,7 +112,9 @@ const struct uniphier_clk_data uniphier_pro4_sys_clk_data[] = { | |||
108 | UNIPHIER_CLK_FACTOR("gpll", -1, "ref", 10, 1), /* 250 MHz */ | 112 | UNIPHIER_CLK_FACTOR("gpll", -1, "ref", 10, 1), /* 250 MHz */ |
109 | UNIPHIER_CLK_FACTOR("uart", 0, "a2pll", 1, 8), | 113 | UNIPHIER_CLK_FACTOR("uart", 0, "a2pll", 1, 8), |
110 | UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 32), | 114 | UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 32), |
115 | UNIPHIER_CLK_FACTOR("spi", 1, "spll", 1, 32), | ||
111 | UNIPHIER_LD4_SYS_CLK_NAND(2), | 116 | UNIPHIER_LD4_SYS_CLK_NAND(2), |
117 | UNIPHIER_SYS_CLK_NAND_4X(3), | ||
112 | UNIPHIER_LD4_SYS_CLK_SD, | 118 | UNIPHIER_LD4_SYS_CLK_SD, |
113 | UNIPHIER_CLK_FACTOR("usb2", -1, "upll", 1, 12), | 119 | UNIPHIER_CLK_FACTOR("usb2", -1, "upll", 1, 12), |
114 | UNIPHIER_PRO4_SYS_CLK_ETHER(6), | 120 | UNIPHIER_PRO4_SYS_CLK_ETHER(6), |
@@ -118,6 +124,9 @@ const struct uniphier_clk_data uniphier_pro4_sys_clk_data[] = { | |||
118 | UNIPHIER_PRO4_SYS_CLK_GIO(12), /* Ether, SATA, USB3 */ | 124 | UNIPHIER_PRO4_SYS_CLK_GIO(12), /* Ether, SATA, USB3 */ |
119 | UNIPHIER_PRO4_SYS_CLK_USB3(14, 0), | 125 | UNIPHIER_PRO4_SYS_CLK_USB3(14, 0), |
120 | UNIPHIER_PRO4_SYS_CLK_USB3(15, 1), | 126 | UNIPHIER_PRO4_SYS_CLK_USB3(15, 1), |
127 | UNIPHIER_CLK_FACTOR("usb30-hsphy0", 16, "upll", 1, 12), | ||
128 | UNIPHIER_CLK_FACTOR("usb30-ssphy0", 17, "ref", 1, 1), | ||
129 | UNIPHIER_CLK_FACTOR("usb31-ssphy0", 20, "ref", 1, 1), | ||
121 | UNIPHIER_CLK_GATE("sata0", 28, NULL, 0x2104, 18), | 130 | UNIPHIER_CLK_GATE("sata0", 28, NULL, 0x2104, 18), |
122 | UNIPHIER_CLK_GATE("sata1", 29, NULL, 0x2104, 19), | 131 | UNIPHIER_CLK_GATE("sata1", 29, NULL, 0x2104, 19), |
123 | UNIPHIER_PRO4_SYS_CLK_AIO(40), | 132 | UNIPHIER_PRO4_SYS_CLK_AIO(40), |
@@ -130,7 +139,9 @@ const struct uniphier_clk_data uniphier_sld8_sys_clk_data[] = { | |||
130 | UNIPHIER_CLK_FACTOR("vpll27a", -1, "ref", 270, 25), /* 270 MHz */ | 139 | UNIPHIER_CLK_FACTOR("vpll27a", -1, "ref", 270, 25), /* 270 MHz */ |
131 | UNIPHIER_CLK_FACTOR("uart", 0, "spll", 1, 20), | 140 | UNIPHIER_CLK_FACTOR("uart", 0, "spll", 1, 20), |
132 | UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 16), | 141 | UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 16), |
142 | UNIPHIER_CLK_FACTOR("spi", -1, "spll", 1, 32), | ||
133 | UNIPHIER_LD4_SYS_CLK_NAND(2), | 143 | UNIPHIER_LD4_SYS_CLK_NAND(2), |
144 | UNIPHIER_SYS_CLK_NAND_4X(3), | ||
134 | UNIPHIER_LD4_SYS_CLK_SD, | 145 | UNIPHIER_LD4_SYS_CLK_SD, |
135 | UNIPHIER_CLK_FACTOR("usb2", -1, "upll", 1, 12), | 146 | UNIPHIER_CLK_FACTOR("usb2", -1, "upll", 1, 12), |
136 | UNIPHIER_LD4_SYS_CLK_STDMAC(8), /* Ether, HSC, MIO */ | 147 | UNIPHIER_LD4_SYS_CLK_STDMAC(8), /* Ether, HSC, MIO */ |
@@ -143,7 +154,9 @@ const struct uniphier_clk_data uniphier_pro5_sys_clk_data[] = { | |||
143 | UNIPHIER_CLK_FACTOR("dapll2", -1, "dapll1", 144, 125), /* 2949.12 MHz */ | 154 | UNIPHIER_CLK_FACTOR("dapll2", -1, "dapll1", 144, 125), /* 2949.12 MHz */ |
144 | UNIPHIER_CLK_FACTOR("uart", 0, "dapll2", 1, 40), | 155 | UNIPHIER_CLK_FACTOR("uart", 0, "dapll2", 1, 40), |
145 | UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 48), | 156 | UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 48), |
157 | UNIPHIER_CLK_FACTOR("spi", -1, "spll", 1, 48), | ||
146 | UNIPHIER_PRO5_SYS_CLK_NAND(2), | 158 | UNIPHIER_PRO5_SYS_CLK_NAND(2), |
159 | UNIPHIER_SYS_CLK_NAND_4X(3), | ||
147 | UNIPHIER_PRO5_SYS_CLK_SD, | 160 | UNIPHIER_PRO5_SYS_CLK_SD, |
148 | UNIPHIER_LD4_SYS_CLK_STDMAC(8), /* HSC */ | 161 | UNIPHIER_LD4_SYS_CLK_STDMAC(8), /* HSC */ |
149 | UNIPHIER_PRO4_SYS_CLK_GIO(12), /* PCIe, USB3 */ | 162 | UNIPHIER_PRO4_SYS_CLK_GIO(12), /* PCIe, USB3 */ |
@@ -158,7 +171,9 @@ const struct uniphier_clk_data uniphier_pxs2_sys_clk_data[] = { | |||
158 | UNIPHIER_CLK_FACTOR("spll", -1, "ref", 96, 1), /* 2400 MHz */ | 171 | UNIPHIER_CLK_FACTOR("spll", -1, "ref", 96, 1), /* 2400 MHz */ |
159 | UNIPHIER_CLK_FACTOR("uart", 0, "spll", 1, 27), | 172 | UNIPHIER_CLK_FACTOR("uart", 0, "spll", 1, 27), |
160 | UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 48), | 173 | UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 48), |
174 | UNIPHIER_CLK_FACTOR("spi", -1, "spll", 1, 48), | ||
161 | UNIPHIER_PRO5_SYS_CLK_NAND(2), | 175 | UNIPHIER_PRO5_SYS_CLK_NAND(2), |
176 | UNIPHIER_SYS_CLK_NAND_4X(3), | ||
162 | UNIPHIER_PRO5_SYS_CLK_SD, | 177 | UNIPHIER_PRO5_SYS_CLK_SD, |
163 | UNIPHIER_PRO4_SYS_CLK_ETHER(6), | 178 | UNIPHIER_PRO4_SYS_CLK_ETHER(6), |
164 | UNIPHIER_LD4_SYS_CLK_STDMAC(8), /* HSC, RLE */ | 179 | UNIPHIER_LD4_SYS_CLK_STDMAC(8), /* HSC, RLE */ |
@@ -166,8 +181,11 @@ const struct uniphier_clk_data uniphier_pxs2_sys_clk_data[] = { | |||
166 | UNIPHIER_PRO4_SYS_CLK_USB3(14, 0), | 181 | UNIPHIER_PRO4_SYS_CLK_USB3(14, 0), |
167 | UNIPHIER_PRO4_SYS_CLK_USB3(15, 1), | 182 | UNIPHIER_PRO4_SYS_CLK_USB3(15, 1), |
168 | /* The document mentions 0x2104 bit 18, but not functional */ | 183 | /* The document mentions 0x2104 bit 18, but not functional */ |
169 | UNIPHIER_CLK_GATE("usb30-phy", 16, NULL, 0x2104, 19), | 184 | UNIPHIER_CLK_GATE("usb30-hsphy0", 16, NULL, 0x2104, 19), |
170 | UNIPHIER_CLK_GATE("usb31-phy", 20, NULL, 0x2104, 20), | 185 | UNIPHIER_CLK_FACTOR("usb30-ssphy0", 17, "ref", 1, 1), |
186 | UNIPHIER_CLK_FACTOR("usb30-ssphy1", 18, "ref", 1, 1), | ||
187 | UNIPHIER_CLK_GATE("usb31-hsphy0", 20, NULL, 0x2104, 20), | ||
188 | UNIPHIER_CLK_FACTOR("usb31-ssphy0", 21, "ref", 1, 1), | ||
171 | UNIPHIER_CLK_GATE("sata0", 28, NULL, 0x2104, 22), | 189 | UNIPHIER_CLK_GATE("sata0", 28, NULL, 0x2104, 22), |
172 | UNIPHIER_PRO5_SYS_CLK_AIO(40), | 190 | UNIPHIER_PRO5_SYS_CLK_AIO(40), |
173 | { /* sentinel */ } | 191 | { /* sentinel */ } |
@@ -180,7 +198,9 @@ const struct uniphier_clk_data uniphier_ld11_sys_clk_data[] = { | |||
180 | UNIPHIER_CLK_FACTOR("vspll", -1, "ref", 80, 1), /* 2000 MHz */ | 198 | UNIPHIER_CLK_FACTOR("vspll", -1, "ref", 80, 1), /* 2000 MHz */ |
181 | UNIPHIER_CLK_FACTOR("uart", 0, "spll", 1, 34), | 199 | UNIPHIER_CLK_FACTOR("uart", 0, "spll", 1, 34), |
182 | UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 40), | 200 | UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 40), |
201 | UNIPHIER_CLK_FACTOR("spi", -1, "spll", 1, 40), | ||
183 | UNIPHIER_LD11_SYS_CLK_NAND(2), | 202 | UNIPHIER_LD11_SYS_CLK_NAND(2), |
203 | UNIPHIER_SYS_CLK_NAND_4X(3), | ||
184 | UNIPHIER_LD11_SYS_CLK_EMMC(4), | 204 | UNIPHIER_LD11_SYS_CLK_EMMC(4), |
185 | /* Index 5 reserved for eMMC PHY */ | 205 | /* Index 5 reserved for eMMC PHY */ |
186 | UNIPHIER_LD11_SYS_CLK_ETHER(6), | 206 | UNIPHIER_LD11_SYS_CLK_ETHER(6), |
@@ -213,7 +233,9 @@ const struct uniphier_clk_data uniphier_ld20_sys_clk_data[] = { | |||
213 | UNIPHIER_CLK_FACTOR("vppll", -1, "ref", 504, 5), /* 2520 MHz */ | 233 | UNIPHIER_CLK_FACTOR("vppll", -1, "ref", 504, 5), /* 2520 MHz */ |
214 | UNIPHIER_CLK_FACTOR("uart", 0, "spll", 1, 34), | 234 | UNIPHIER_CLK_FACTOR("uart", 0, "spll", 1, 34), |
215 | UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 40), | 235 | UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 40), |
236 | UNIPHIER_CLK_FACTOR("spi", -1, "spll", 1, 40), | ||
216 | UNIPHIER_LD11_SYS_CLK_NAND(2), | 237 | UNIPHIER_LD11_SYS_CLK_NAND(2), |
238 | UNIPHIER_SYS_CLK_NAND_4X(3), | ||
217 | UNIPHIER_LD11_SYS_CLK_EMMC(4), | 239 | UNIPHIER_LD11_SYS_CLK_EMMC(4), |
218 | /* Index 5 reserved for eMMC PHY */ | 240 | /* Index 5 reserved for eMMC PHY */ |
219 | UNIPHIER_LD20_SYS_CLK_SD, | 241 | UNIPHIER_LD20_SYS_CLK_SD, |
@@ -226,8 +248,10 @@ const struct uniphier_clk_data uniphier_ld20_sys_clk_data[] = { | |||
226 | * We do not use bit 15 here. | 248 | * We do not use bit 15 here. |
227 | */ | 249 | */ |
228 | UNIPHIER_CLK_GATE("usb30", 14, NULL, 0x210c, 14), | 250 | UNIPHIER_CLK_GATE("usb30", 14, NULL, 0x210c, 14), |
229 | UNIPHIER_CLK_GATE("usb30-phy0", 16, NULL, 0x210c, 12), | 251 | UNIPHIER_CLK_GATE("usb30-hsphy0", 16, NULL, 0x210c, 12), |
230 | UNIPHIER_CLK_GATE("usb30-phy1", 17, NULL, 0x210c, 13), | 252 | UNIPHIER_CLK_GATE("usb30-hsphy1", 17, NULL, 0x210c, 13), |
253 | UNIPHIER_CLK_FACTOR("usb30-ssphy0", 18, "ref", 1, 1), | ||
254 | UNIPHIER_CLK_FACTOR("usb30-ssphy1", 19, "ref", 1, 1), | ||
231 | UNIPHIER_CLK_GATE("pcie", 24, NULL, 0x210c, 4), | 255 | UNIPHIER_CLK_GATE("pcie", 24, NULL, 0x210c, 4), |
232 | UNIPHIER_LD11_SYS_CLK_AIO(40), | 256 | UNIPHIER_LD11_SYS_CLK_AIO(40), |
233 | UNIPHIER_LD11_SYS_CLK_EVEA(41), | 257 | UNIPHIER_LD11_SYS_CLK_EVEA(41), |
@@ -254,19 +278,21 @@ const struct uniphier_clk_data uniphier_pxs3_sys_clk_data[] = { | |||
254 | UNIPHIER_CLK_FACTOR("s2pll", -1, "ref", 88, 1), /* IPP: 2400 MHz */ | 278 | UNIPHIER_CLK_FACTOR("s2pll", -1, "ref", 88, 1), /* IPP: 2400 MHz */ |
255 | UNIPHIER_CLK_FACTOR("uart", 0, "spll", 1, 34), | 279 | UNIPHIER_CLK_FACTOR("uart", 0, "spll", 1, 34), |
256 | UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 40), | 280 | UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 40), |
281 | UNIPHIER_CLK_FACTOR("spi", -1, "spll", 1, 40), | ||
257 | UNIPHIER_LD20_SYS_CLK_SD, | 282 | UNIPHIER_LD20_SYS_CLK_SD, |
258 | UNIPHIER_LD11_SYS_CLK_NAND(2), | 283 | UNIPHIER_LD11_SYS_CLK_NAND(2), |
284 | UNIPHIER_SYS_CLK_NAND_4X(3), | ||
259 | UNIPHIER_LD11_SYS_CLK_EMMC(4), | 285 | UNIPHIER_LD11_SYS_CLK_EMMC(4), |
260 | UNIPHIER_CLK_GATE("ether0", 6, NULL, 0x210c, 9), | 286 | UNIPHIER_CLK_GATE("ether0", 6, NULL, 0x210c, 9), |
261 | UNIPHIER_CLK_GATE("ether1", 7, NULL, 0x210c, 10), | 287 | UNIPHIER_CLK_GATE("ether1", 7, NULL, 0x210c, 10), |
262 | UNIPHIER_CLK_GATE("usb30", 12, NULL, 0x210c, 4), /* =GIO0 */ | 288 | UNIPHIER_CLK_GATE("usb30", 12, NULL, 0x210c, 4), /* =GIO0 */ |
263 | UNIPHIER_CLK_GATE("usb31-0", 13, NULL, 0x210c, 5), /* =GIO1 */ | 289 | UNIPHIER_CLK_GATE("usb31-0", 13, NULL, 0x210c, 5), /* =GIO1 */ |
264 | UNIPHIER_CLK_GATE("usb31-1", 14, NULL, 0x210c, 6), /* =GIO1-1 */ | 290 | UNIPHIER_CLK_GATE("usb31-1", 14, NULL, 0x210c, 6), /* =GIO1-1 */ |
265 | UNIPHIER_CLK_GATE("usb30-phy0", 16, NULL, 0x210c, 16), | 291 | UNIPHIER_CLK_GATE("usb30-hsphy0", 16, NULL, 0x210c, 16), |
266 | UNIPHIER_CLK_GATE("usb30-phy1", 17, NULL, 0x210c, 18), | 292 | UNIPHIER_CLK_GATE("usb30-ssphy0", 17, NULL, 0x210c, 18), |
267 | UNIPHIER_CLK_GATE("usb30-phy2", 18, NULL, 0x210c, 20), | 293 | UNIPHIER_CLK_GATE("usb30-ssphy1", 18, NULL, 0x210c, 20), |
268 | UNIPHIER_CLK_GATE("usb31-phy0", 20, NULL, 0x210c, 17), | 294 | UNIPHIER_CLK_GATE("usb31-hsphy0", 20, NULL, 0x210c, 17), |
269 | UNIPHIER_CLK_GATE("usb31-phy1", 21, NULL, 0x210c, 19), | 295 | UNIPHIER_CLK_GATE("usb31-ssphy0", 21, NULL, 0x210c, 19), |
270 | UNIPHIER_CLK_GATE("pcie", 24, NULL, 0x210c, 3), | 296 | UNIPHIER_CLK_GATE("pcie", 24, NULL, 0x210c, 3), |
271 | UNIPHIER_CLK_GATE("sata0", 28, NULL, 0x210c, 7), | 297 | UNIPHIER_CLK_GATE("sata0", 28, NULL, 0x210c, 7), |
272 | UNIPHIER_CLK_GATE("sata1", 29, NULL, 0x210c, 8), | 298 | UNIPHIER_CLK_GATE("sata1", 29, NULL, 0x210c, 8), |
diff --git a/include/dt-bindings/clock/actions,s700-cmu.h b/include/dt-bindings/clock/actions,s700-cmu.h new file mode 100644 index 000000000000..3e1942996724 --- /dev/null +++ b/include/dt-bindings/clock/actions,s700-cmu.h | |||
@@ -0,0 +1,118 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 | ||
2 | * | ||
3 | * Device Tree binding constants for Actions Semi S700 Clock Management Unit | ||
4 | * | ||
5 | * Copyright (c) 2014 Actions Semi Inc. | ||
6 | * Author: David Liu <liuwei@actions-semi.com> | ||
7 | * | ||
8 | * Author: Pathiban Nallathambi <pn@denx.de> | ||
9 | * Author: Saravanan Sekar <sravanhome@gmail.com> | ||
10 | */ | ||
11 | |||
12 | #ifndef __DT_BINDINGS_CLOCK_S700_H | ||
13 | #define __DT_BINDINGS_CLOCK_S700_H | ||
14 | |||
15 | #define CLK_NONE 0 | ||
16 | |||
17 | /* pll clocks */ | ||
18 | #define CLK_CORE_PLL 1 | ||
19 | #define CLK_DEV_PLL 2 | ||
20 | #define CLK_DDR_PLL 3 | ||
21 | #define CLK_NAND_PLL 4 | ||
22 | #define CLK_DISPLAY_PLL 5 | ||
23 | #define CLK_TVOUT_PLL 6 | ||
24 | #define CLK_CVBS_PLL 7 | ||
25 | #define CLK_AUDIO_PLL 8 | ||
26 | #define CLK_ETHERNET_PLL 9 | ||
27 | |||
28 | /* system clock */ | ||
29 | #define CLK_CPU 10 | ||
30 | #define CLK_DEV 11 | ||
31 | #define CLK_AHB 12 | ||
32 | #define CLK_APB 13 | ||
33 | #define CLK_DMAC 14 | ||
34 | #define CLK_NOC0_CLK_MUX 15 | ||
35 | #define CLK_NOC1_CLK_MUX 16 | ||
36 | #define CLK_HP_CLK_MUX 17 | ||
37 | #define CLK_HP_CLK_DIV 18 | ||
38 | #define CLK_NOC1_CLK_DIV 19 | ||
39 | #define CLK_NOC0 20 | ||
40 | #define CLK_NOC1 21 | ||
41 | #define CLK_SENOR_SRC 22 | ||
42 | |||
43 | /* peripheral device clock */ | ||
44 | #define CLK_GPIO 23 | ||
45 | #define CLK_TIMER 24 | ||
46 | #define CLK_DSI 25 | ||
47 | #define CLK_CSI 26 | ||
48 | #define CLK_SI 27 | ||
49 | #define CLK_DE 28 | ||
50 | #define CLK_HDE 29 | ||
51 | #define CLK_VDE 30 | ||
52 | #define CLK_VCE 31 | ||
53 | #define CLK_NAND 32 | ||
54 | #define CLK_SD0 33 | ||
55 | #define CLK_SD1 34 | ||
56 | #define CLK_SD2 35 | ||
57 | |||
58 | #define CLK_UART0 36 | ||
59 | #define CLK_UART1 37 | ||
60 | #define CLK_UART2 38 | ||
61 | #define CLK_UART3 39 | ||
62 | #define CLK_UART4 40 | ||
63 | #define CLK_UART5 41 | ||
64 | #define CLK_UART6 42 | ||
65 | |||
66 | #define CLK_PWM0 43 | ||
67 | #define CLK_PWM1 44 | ||
68 | #define CLK_PWM2 45 | ||
69 | #define CLK_PWM3 46 | ||
70 | #define CLK_PWM4 47 | ||
71 | #define CLK_PWM5 48 | ||
72 | #define CLK_GPU3D 49 | ||
73 | |||
74 | #define CLK_I2C0 50 | ||
75 | #define CLK_I2C1 51 | ||
76 | #define CLK_I2C2 52 | ||
77 | #define CLK_I2C3 53 | ||
78 | |||
79 | #define CLK_SPI0 54 | ||
80 | #define CLK_SPI1 55 | ||
81 | #define CLK_SPI2 56 | ||
82 | #define CLK_SPI3 57 | ||
83 | |||
84 | #define CLK_USB3_480MPLL0 58 | ||
85 | #define CLK_USB3_480MPHY0 59 | ||
86 | #define CLK_USB3_5GPHY 60 | ||
87 | #define CLK_USB3_CCE 61 | ||
88 | #define CLK_USB3_MAC 62 | ||
89 | |||
90 | #define CLK_LCD 63 | ||
91 | #define CLK_HDMI_AUDIO 64 | ||
92 | #define CLK_I2SRX 65 | ||
93 | #define CLK_I2STX 66 | ||
94 | |||
95 | #define CLK_SENSOR0 67 | ||
96 | #define CLK_SENSOR1 68 | ||
97 | |||
98 | #define CLK_HDMI_DEV 69 | ||
99 | |||
100 | #define CLK_ETHERNET 70 | ||
101 | #define CLK_RMII_REF 71 | ||
102 | |||
103 | #define CLK_USB2H0_PLLEN 72 | ||
104 | #define CLK_USB2H0_PHY 73 | ||
105 | #define CLK_USB2H0_CCE 74 | ||
106 | #define CLK_USB2H1_PLLEN 75 | ||
107 | #define CLK_USB2H1_PHY 76 | ||
108 | #define CLK_USB2H1_CCE 77 | ||
109 | |||
110 | #define CLK_TVOUT 78 | ||
111 | |||
112 | #define CLK_THERMAL_SENSOR 79 | ||
113 | |||
114 | #define CLK_IRC_SWITCH 80 | ||
115 | #define CLK_PCM1 81 | ||
116 | #define CLK_NR_CLKS (CLK_PCM1 + 1) | ||
117 | |||
118 | #endif /* __DT_BINDINGS_CLOCK_S700_H */ | ||
diff --git a/include/dt-bindings/clock/aspeed-clock.h b/include/dt-bindings/clock/aspeed-clock.h index 44761849fcbe..f43738607d77 100644 --- a/include/dt-bindings/clock/aspeed-clock.h +++ b/include/dt-bindings/clock/aspeed-clock.h | |||
@@ -25,7 +25,7 @@ | |||
25 | #define ASPEED_CLK_GATE_RSACLK 19 | 25 | #define ASPEED_CLK_GATE_RSACLK 19 |
26 | #define ASPEED_CLK_GATE_UART3CLK 20 | 26 | #define ASPEED_CLK_GATE_UART3CLK 20 |
27 | #define ASPEED_CLK_GATE_UART4CLK 21 | 27 | #define ASPEED_CLK_GATE_UART4CLK 21 |
28 | #define ASPEED_CLK_GATE_SDCLKCLK 22 | 28 | #define ASPEED_CLK_GATE_SDCLK 22 |
29 | #define ASPEED_CLK_GATE_LHCCLK 23 | 29 | #define ASPEED_CLK_GATE_LHCCLK 23 |
30 | #define ASPEED_CLK_HPLL 24 | 30 | #define ASPEED_CLK_HPLL 24 |
31 | #define ASPEED_CLK_AHB 25 | 31 | #define ASPEED_CLK_AHB 25 |
diff --git a/include/dt-bindings/clock/axg-audio-clkc.h b/include/dt-bindings/clock/axg-audio-clkc.h new file mode 100644 index 000000000000..fd9c362099d9 --- /dev/null +++ b/include/dt-bindings/clock/axg-audio-clkc.h | |||
@@ -0,0 +1,94 @@ | |||
1 | /* SPDX-License-Identifier: (GPL-2.0 OR MIT) */ | ||
2 | /* | ||
3 | * Copyright (c) 2018 Baylibre SAS. | ||
4 | * Author: Jerome Brunet <jbrunet@baylibre.com> | ||
5 | */ | ||
6 | |||
7 | #ifndef __AXG_AUDIO_CLKC_BINDINGS_H | ||
8 | #define __AXG_AUDIO_CLKC_BINDINGS_H | ||
9 | |||
10 | #define AUD_CLKID_SLV_SCLK0 9 | ||
11 | #define AUD_CLKID_SLV_SCLK1 10 | ||
12 | #define AUD_CLKID_SLV_SCLK2 11 | ||
13 | #define AUD_CLKID_SLV_SCLK3 12 | ||
14 | #define AUD_CLKID_SLV_SCLK4 13 | ||
15 | #define AUD_CLKID_SLV_SCLK5 14 | ||
16 | #define AUD_CLKID_SLV_SCLK6 15 | ||
17 | #define AUD_CLKID_SLV_SCLK7 16 | ||
18 | #define AUD_CLKID_SLV_SCLK8 17 | ||
19 | #define AUD_CLKID_SLV_SCLK9 18 | ||
20 | #define AUD_CLKID_SLV_LRCLK0 19 | ||
21 | #define AUD_CLKID_SLV_LRCLK1 20 | ||
22 | #define AUD_CLKID_SLV_LRCLK2 21 | ||
23 | #define AUD_CLKID_SLV_LRCLK3 22 | ||
24 | #define AUD_CLKID_SLV_LRCLK4 23 | ||
25 | #define AUD_CLKID_SLV_LRCLK5 24 | ||
26 | #define AUD_CLKID_SLV_LRCLK6 25 | ||
27 | #define AUD_CLKID_SLV_LRCLK7 26 | ||
28 | #define AUD_CLKID_SLV_LRCLK8 27 | ||
29 | #define AUD_CLKID_SLV_LRCLK9 28 | ||
30 | #define AUD_CLKID_DDR_ARB 29 | ||
31 | #define AUD_CLKID_PDM 30 | ||
32 | #define AUD_CLKID_TDMIN_A 31 | ||
33 | #define AUD_CLKID_TDMIN_B 32 | ||
34 | #define AUD_CLKID_TDMIN_C 33 | ||
35 | #define AUD_CLKID_TDMIN_LB 34 | ||
36 | #define AUD_CLKID_TDMOUT_A 35 | ||
37 | #define AUD_CLKID_TDMOUT_B 36 | ||
38 | #define AUD_CLKID_TDMOUT_C 37 | ||
39 | #define AUD_CLKID_FRDDR_A 38 | ||
40 | #define AUD_CLKID_FRDDR_B 39 | ||
41 | #define AUD_CLKID_FRDDR_C 40 | ||
42 | #define AUD_CLKID_TODDR_A 41 | ||
43 | #define AUD_CLKID_TODDR_B 42 | ||
44 | #define AUD_CLKID_TODDR_C 43 | ||
45 | #define AUD_CLKID_LOOPBACK 44 | ||
46 | #define AUD_CLKID_SPDIFIN 45 | ||
47 | #define AUD_CLKID_SPDIFOUT 46 | ||
48 | #define AUD_CLKID_RESAMPLE 47 | ||
49 | #define AUD_CLKID_POWER_DETECT 48 | ||
50 | #define AUD_CLKID_MST_A_MCLK 49 | ||
51 | #define AUD_CLKID_MST_B_MCLK 50 | ||
52 | #define AUD_CLKID_MST_C_MCLK 51 | ||
53 | #define AUD_CLKID_MST_D_MCLK 52 | ||
54 | #define AUD_CLKID_MST_E_MCLK 53 | ||
55 | #define AUD_CLKID_MST_F_MCLK 54 | ||
56 | #define AUD_CLKID_SPDIFOUT_CLK 55 | ||
57 | #define AUD_CLKID_SPDIFIN_CLK 56 | ||
58 | #define AUD_CLKID_PDM_DCLK 57 | ||
59 | #define AUD_CLKID_PDM_SYSCLK 58 | ||
60 | #define AUD_CLKID_MST_A_SCLK 79 | ||
61 | #define AUD_CLKID_MST_B_SCLK 80 | ||
62 | #define AUD_CLKID_MST_C_SCLK 81 | ||
63 | #define AUD_CLKID_MST_D_SCLK 82 | ||
64 | #define AUD_CLKID_MST_E_SCLK 83 | ||
65 | #define AUD_CLKID_MST_F_SCLK 84 | ||
66 | #define AUD_CLKID_MST_A_LRCLK 86 | ||
67 | #define AUD_CLKID_MST_B_LRCLK 87 | ||
68 | #define AUD_CLKID_MST_C_LRCLK 88 | ||
69 | #define AUD_CLKID_MST_D_LRCLK 89 | ||
70 | #define AUD_CLKID_MST_E_LRCLK 90 | ||
71 | #define AUD_CLKID_MST_F_LRCLK 91 | ||
72 | #define AUD_CLKID_TDMIN_A_SCLK_SEL 116 | ||
73 | #define AUD_CLKID_TDMIN_B_SCLK_SEL 117 | ||
74 | #define AUD_CLKID_TDMIN_C_SCLK_SEL 118 | ||
75 | #define AUD_CLKID_TDMIN_LB_SCLK_SEL 119 | ||
76 | #define AUD_CLKID_TDMOUT_A_SCLK_SEL 120 | ||
77 | #define AUD_CLKID_TDMOUT_B_SCLK_SEL 121 | ||
78 | #define AUD_CLKID_TDMOUT_C_SCLK_SEL 122 | ||
79 | #define AUD_CLKID_TDMIN_A_SCLK 123 | ||
80 | #define AUD_CLKID_TDMIN_B_SCLK 124 | ||
81 | #define AUD_CLKID_TDMIN_C_SCLK 125 | ||
82 | #define AUD_CLKID_TDMIN_LB_SCLK 126 | ||
83 | #define AUD_CLKID_TDMOUT_A_SCLK 127 | ||
84 | #define AUD_CLKID_TDMOUT_B_SCLK 128 | ||
85 | #define AUD_CLKID_TDMOUT_C_SCLK 129 | ||
86 | #define AUD_CLKID_TDMIN_A_LRCLK 130 | ||
87 | #define AUD_CLKID_TDMIN_B_LRCLK 131 | ||
88 | #define AUD_CLKID_TDMIN_C_LRCLK 132 | ||
89 | #define AUD_CLKID_TDMIN_LB_LRCLK 133 | ||
90 | #define AUD_CLKID_TDMOUT_A_LRCLK 134 | ||
91 | #define AUD_CLKID_TDMOUT_B_LRCLK 135 | ||
92 | #define AUD_CLKID_TDMOUT_C_LRCLK 136 | ||
93 | |||
94 | #endif /* __AXG_AUDIO_CLKC_BINDINGS_H */ | ||
diff --git a/include/dt-bindings/clock/axg-clkc.h b/include/dt-bindings/clock/axg-clkc.h index 555937a25504..fd1f938c38d1 100644 --- a/include/dt-bindings/clock/axg-clkc.h +++ b/include/dt-bindings/clock/axg-clkc.h | |||
@@ -68,5 +68,9 @@ | |||
68 | #define CLKID_SD_EMMC_B_CLK0 59 | 68 | #define CLKID_SD_EMMC_B_CLK0 59 |
69 | #define CLKID_SD_EMMC_C_CLK0 60 | 69 | #define CLKID_SD_EMMC_C_CLK0 60 |
70 | #define CLKID_HIFI_PLL 69 | 70 | #define CLKID_HIFI_PLL 69 |
71 | #define CLKID_PCIE_CML_EN0 79 | ||
72 | #define CLKID_PCIE_CML_EN1 80 | ||
73 | #define CLKID_MIPI_ENABLE 81 | ||
74 | #define CLKID_GEN_CLK 84 | ||
71 | 75 | ||
72 | #endif /* __AXG_CLKC_H */ | 76 | #endif /* __AXG_CLKC_H */ |
diff --git a/include/dt-bindings/clock/gxbb-clkc.h b/include/dt-bindings/clock/gxbb-clkc.h index 7a892be90549..3979d48c025f 100644 --- a/include/dt-bindings/clock/gxbb-clkc.h +++ b/include/dt-bindings/clock/gxbb-clkc.h | |||
@@ -127,5 +127,6 @@ | |||
127 | #define CLKID_VAPB 140 | 127 | #define CLKID_VAPB 140 |
128 | #define CLKID_VDEC_1 153 | 128 | #define CLKID_VDEC_1 153 |
129 | #define CLKID_VDEC_HEVC 156 | 129 | #define CLKID_VDEC_HEVC 156 |
130 | #define CLKID_GEN_CLK 159 | ||
130 | 131 | ||
131 | #endif /* __GXBB_CLKC_H */ | 132 | #endif /* __GXBB_CLKC_H */ |
diff --git a/include/dt-bindings/clock/imx6sll-clock.h b/include/dt-bindings/clock/imx6sll-clock.h index 151111e68f4f..1036475f997d 100644 --- a/include/dt-bindings/clock/imx6sll-clock.h +++ b/include/dt-bindings/clock/imx6sll-clock.h | |||
@@ -197,6 +197,13 @@ | |||
197 | #define IMX6SLL_CLK_EXTERN_AUDIO_PODF 171 | 197 | #define IMX6SLL_CLK_EXTERN_AUDIO_PODF 171 |
198 | #define IMX6SLL_CLK_EXTERN_AUDIO 172 | 198 | #define IMX6SLL_CLK_EXTERN_AUDIO 172 |
199 | 199 | ||
200 | #define IMX6SLL_CLK_END 173 | 200 | #define IMX6SLL_CLK_GPIO1 173 |
201 | #define IMX6SLL_CLK_GPIO2 174 | ||
202 | #define IMX6SLL_CLK_GPIO3 175 | ||
203 | #define IMX6SLL_CLK_GPIO4 176 | ||
204 | #define IMX6SLL_CLK_GPIO5 177 | ||
205 | #define IMX6SLL_CLK_GPIO6 178 | ||
206 | |||
207 | #define IMX6SLL_CLK_END 179 | ||
201 | 208 | ||
202 | #endif /* __DT_BINDINGS_CLOCK_IMX6SLL_H */ | 209 | #endif /* __DT_BINDINGS_CLOCK_IMX6SLL_H */ |
diff --git a/include/dt-bindings/clock/imx6ul-clock.h b/include/dt-bindings/clock/imx6ul-clock.h index 0aa1d9c3e0b9..f8e0476a3a0e 100644 --- a/include/dt-bindings/clock/imx6ul-clock.h +++ b/include/dt-bindings/clock/imx6ul-clock.h | |||
@@ -254,6 +254,12 @@ | |||
254 | #define IMX6UL_CLK_CKO2_PODF 241 | 254 | #define IMX6UL_CLK_CKO2_PODF 241 |
255 | #define IMX6UL_CLK_CKO2 242 | 255 | #define IMX6UL_CLK_CKO2 242 |
256 | #define IMX6UL_CLK_CKO 243 | 256 | #define IMX6UL_CLK_CKO 243 |
257 | #define IMX6UL_CLK_END 244 | 257 | #define IMX6UL_CLK_GPIO1 244 |
258 | #define IMX6UL_CLK_GPIO2 245 | ||
259 | #define IMX6UL_CLK_GPIO3 246 | ||
260 | #define IMX6UL_CLK_GPIO4 247 | ||
261 | #define IMX6UL_CLK_GPIO5 248 | ||
262 | |||
263 | #define IMX6UL_CLK_END 249 | ||
258 | 264 | ||
259 | #endif /* __DT_BINDINGS_CLOCK_IMX6UL_H */ | 265 | #endif /* __DT_BINDINGS_CLOCK_IMX6UL_H */ |
diff --git a/include/dt-bindings/clock/maxim,max9485.h b/include/dt-bindings/clock/maxim,max9485.h new file mode 100644 index 000000000000..185b09ce1869 --- /dev/null +++ b/include/dt-bindings/clock/maxim,max9485.h | |||
@@ -0,0 +1,18 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2018 Daniel Mack | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | * | ||
8 | */ | ||
9 | |||
10 | #ifndef __DT_BINDINGS_MAX9485_CLK_H | ||
11 | #define __DT_BINDINGS_MAX9485_CLK_H | ||
12 | |||
13 | #define MAX9485_MCLKOUT 0 | ||
14 | #define MAX9485_CLKOUT 1 | ||
15 | #define MAX9485_CLKOUT1 2 | ||
16 | #define MAX9485_CLKOUT2 3 | ||
17 | |||
18 | #endif /* __DT_BINDINGS_MAX9485_CLK_H */ | ||
diff --git a/include/dt-bindings/clock/px30-cru.h b/include/dt-bindings/clock/px30-cru.h new file mode 100644 index 000000000000..00101479f7c4 --- /dev/null +++ b/include/dt-bindings/clock/px30-cru.h | |||
@@ -0,0 +1,389 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | |||
3 | #ifndef _DT_BINDINGS_CLK_ROCKCHIP_PX30_H | ||
4 | #define _DT_BINDINGS_CLK_ROCKCHIP_PX30_H | ||
5 | |||
6 | /* core clocks */ | ||
7 | #define PLL_APLL 1 | ||
8 | #define PLL_DPLL 2 | ||
9 | #define PLL_CPLL 3 | ||
10 | #define PLL_NPLL 4 | ||
11 | #define APLL_BOOST_H 5 | ||
12 | #define APLL_BOOST_L 6 | ||
13 | #define ARMCLK 7 | ||
14 | |||
15 | /* sclk gates (special clocks) */ | ||
16 | #define USB480M 14 | ||
17 | #define SCLK_PDM 15 | ||
18 | #define SCLK_I2S0_TX 16 | ||
19 | #define SCLK_I2S0_TX_OUT 17 | ||
20 | #define SCLK_I2S0_RX 18 | ||
21 | #define SCLK_I2S0_RX_OUT 19 | ||
22 | #define SCLK_I2S1 20 | ||
23 | #define SCLK_I2S1_OUT 21 | ||
24 | #define SCLK_I2S2 22 | ||
25 | #define SCLK_I2S2_OUT 23 | ||
26 | #define SCLK_UART1 24 | ||
27 | #define SCLK_UART2 25 | ||
28 | #define SCLK_UART3 26 | ||
29 | #define SCLK_UART4 27 | ||
30 | #define SCLK_UART5 28 | ||
31 | #define SCLK_I2C0 29 | ||
32 | #define SCLK_I2C1 30 | ||
33 | #define SCLK_I2C2 31 | ||
34 | #define SCLK_I2C3 32 | ||
35 | #define SCLK_I2C4 33 | ||
36 | #define SCLK_PWM0 34 | ||
37 | #define SCLK_PWM1 35 | ||
38 | #define SCLK_SPI0 36 | ||
39 | #define SCLK_SPI1 37 | ||
40 | #define SCLK_TIMER0 38 | ||
41 | #define SCLK_TIMER1 39 | ||
42 | #define SCLK_TIMER2 40 | ||
43 | #define SCLK_TIMER3 41 | ||
44 | #define SCLK_TIMER4 42 | ||
45 | #define SCLK_TIMER5 43 | ||
46 | #define SCLK_TSADC 44 | ||
47 | #define SCLK_SARADC 45 | ||
48 | #define SCLK_OTP 46 | ||
49 | #define SCLK_OTP_USR 47 | ||
50 | #define SCLK_CRYPTO 48 | ||
51 | #define SCLK_CRYPTO_APK 49 | ||
52 | #define SCLK_DDRC 50 | ||
53 | #define SCLK_ISP 51 | ||
54 | #define SCLK_CIF_OUT 52 | ||
55 | #define SCLK_RGA_CORE 53 | ||
56 | #define SCLK_VOPB_PWM 54 | ||
57 | #define SCLK_NANDC 55 | ||
58 | #define SCLK_SDIO 56 | ||
59 | #define SCLK_EMMC 57 | ||
60 | #define SCLK_SFC 58 | ||
61 | #define SCLK_SDMMC 59 | ||
62 | #define SCLK_OTG_ADP 60 | ||
63 | #define SCLK_GMAC_SRC 61 | ||
64 | #define SCLK_GMAC 62 | ||
65 | #define SCLK_GMAC_RX_TX 63 | ||
66 | #define SCLK_MAC_REF 64 | ||
67 | #define SCLK_MAC_REFOUT 65 | ||
68 | #define SCLK_MAC_OUT 66 | ||
69 | #define SCLK_SDMMC_DRV 67 | ||
70 | #define SCLK_SDMMC_SAMPLE 68 | ||
71 | #define SCLK_SDIO_DRV 69 | ||
72 | #define SCLK_SDIO_SAMPLE 70 | ||
73 | #define SCLK_EMMC_DRV 71 | ||
74 | #define SCLK_EMMC_SAMPLE 72 | ||
75 | #define SCLK_GPU 73 | ||
76 | #define SCLK_PVTM 74 | ||
77 | #define SCLK_CORE_VPU 75 | ||
78 | #define SCLK_GMAC_RMII 76 | ||
79 | #define SCLK_UART2_SRC 77 | ||
80 | #define SCLK_NANDC_DIV 78 | ||
81 | #define SCLK_NANDC_DIV50 79 | ||
82 | #define SCLK_SDIO_DIV 80 | ||
83 | #define SCLK_SDIO_DIV50 81 | ||
84 | #define SCLK_EMMC_DIV 82 | ||
85 | #define SCLK_EMMC_DIV50 83 | ||
86 | #define SCLK_DDRCLK 84 | ||
87 | #define SCLK_UART1_SRC 85 | ||
88 | |||
89 | /* dclk gates */ | ||
90 | #define DCLK_VOPB 150 | ||
91 | #define DCLK_VOPL 151 | ||
92 | |||
93 | /* aclk gates */ | ||
94 | #define ACLK_GPU 170 | ||
95 | #define ACLK_BUS_PRE 171 | ||
96 | #define ACLK_CRYPTO 172 | ||
97 | #define ACLK_VI_PRE 173 | ||
98 | #define ACLK_VO_PRE 174 | ||
99 | #define ACLK_VPU 175 | ||
100 | #define ACLK_PERI_PRE 176 | ||
101 | #define ACLK_GMAC 178 | ||
102 | #define ACLK_CIF 179 | ||
103 | #define ACLK_ISP 180 | ||
104 | #define ACLK_VOPB 181 | ||
105 | #define ACLK_VOPL 182 | ||
106 | #define ACLK_RGA 183 | ||
107 | #define ACLK_GIC 184 | ||
108 | #define ACLK_DCF 186 | ||
109 | #define ACLK_DMAC 187 | ||
110 | #define ACLK_BUS_SRC 188 | ||
111 | #define ACLK_PERI_SRC 189 | ||
112 | |||
113 | /* hclk gates */ | ||
114 | #define HCLK_BUS_PRE 240 | ||
115 | #define HCLK_CRYPTO 241 | ||
116 | #define HCLK_VI_PRE 242 | ||
117 | #define HCLK_VO_PRE 243 | ||
118 | #define HCLK_VPU 244 | ||
119 | #define HCLK_PERI_PRE 245 | ||
120 | #define HCLK_MMC_NAND 246 | ||
121 | #define HCLK_SDMMC 247 | ||
122 | #define HCLK_USB 248 | ||
123 | #define HCLK_CIF 249 | ||
124 | #define HCLK_ISP 250 | ||
125 | #define HCLK_VOPB 251 | ||
126 | #define HCLK_VOPL 252 | ||
127 | #define HCLK_RGA 253 | ||
128 | #define HCLK_NANDC 254 | ||
129 | #define HCLK_SDIO 255 | ||
130 | #define HCLK_EMMC 256 | ||
131 | #define HCLK_SFC 257 | ||
132 | #define HCLK_OTG 258 | ||
133 | #define HCLK_HOST 259 | ||
134 | #define HCLK_HOST_ARB 260 | ||
135 | #define HCLK_PDM 261 | ||
136 | #define HCLK_I2S0 262 | ||
137 | #define HCLK_I2S1 263 | ||
138 | #define HCLK_I2S2 264 | ||
139 | |||
140 | /* pclk gates */ | ||
141 | #define PCLK_BUS_PRE 320 | ||
142 | #define PCLK_DDR 321 | ||
143 | #define PCLK_VO_PRE 322 | ||
144 | #define PCLK_GMAC 323 | ||
145 | #define PCLK_MIPI_DSI 324 | ||
146 | #define PCLK_MIPIDSIPHY 325 | ||
147 | #define PCLK_MIPICSIPHY 326 | ||
148 | #define PCLK_USB_GRF 327 | ||
149 | #define PCLK_DCF 328 | ||
150 | #define PCLK_UART1 329 | ||
151 | #define PCLK_UART2 330 | ||
152 | #define PCLK_UART3 331 | ||
153 | #define PCLK_UART4 332 | ||
154 | #define PCLK_UART5 333 | ||
155 | #define PCLK_I2C0 334 | ||
156 | #define PCLK_I2C1 335 | ||
157 | #define PCLK_I2C2 336 | ||
158 | #define PCLK_I2C3 337 | ||
159 | #define PCLK_I2C4 338 | ||
160 | #define PCLK_PWM0 339 | ||
161 | #define PCLK_PWM1 340 | ||
162 | #define PCLK_SPI0 341 | ||
163 | #define PCLK_SPI1 342 | ||
164 | #define PCLK_SARADC 343 | ||
165 | #define PCLK_TSADC 344 | ||
166 | #define PCLK_TIMER 345 | ||
167 | #define PCLK_OTP_NS 346 | ||
168 | #define PCLK_WDT_NS 347 | ||
169 | #define PCLK_GPIO1 348 | ||
170 | #define PCLK_GPIO2 349 | ||
171 | #define PCLK_GPIO3 350 | ||
172 | #define PCLK_ISP 351 | ||
173 | #define PCLK_CIF 352 | ||
174 | #define PCLK_OTP_PHY 353 | ||
175 | |||
176 | #define CLK_NR_CLKS (PCLK_OTP_PHY + 1) | ||
177 | |||
178 | /* pmu-clocks indices */ | ||
179 | |||
180 | #define PLL_GPLL 1 | ||
181 | |||
182 | #define SCLK_RTC32K_PMU 4 | ||
183 | #define SCLK_WIFI_PMU 5 | ||
184 | #define SCLK_UART0_PMU 6 | ||
185 | #define SCLK_PVTM_PMU 7 | ||
186 | #define PCLK_PMU_PRE 8 | ||
187 | #define SCLK_REF24M_PMU 9 | ||
188 | #define SCLK_USBPHY_REF 10 | ||
189 | #define SCLK_MIPIDSIPHY_REF 11 | ||
190 | |||
191 | #define XIN24M_DIV 12 | ||
192 | |||
193 | #define PCLK_GPIO0_PMU 20 | ||
194 | #define PCLK_UART0_PMU 21 | ||
195 | |||
196 | #define CLKPMU_NR_CLKS (PCLK_UART0_PMU + 1) | ||
197 | |||
198 | /* soft-reset indices */ | ||
199 | #define SRST_CORE0_PO 0 | ||
200 | #define SRST_CORE1_PO 1 | ||
201 | #define SRST_CORE2_PO 2 | ||
202 | #define SRST_CORE3_PO 3 | ||
203 | #define SRST_CORE0 4 | ||
204 | #define SRST_CORE1 5 | ||
205 | #define SRST_CORE2 6 | ||
206 | #define SRST_CORE3 7 | ||
207 | #define SRST_CORE0_DBG 8 | ||
208 | #define SRST_CORE1_DBG 9 | ||
209 | #define SRST_CORE2_DBG 10 | ||
210 | #define SRST_CORE3_DBG 11 | ||
211 | #define SRST_TOPDBG 12 | ||
212 | #define SRST_CORE_NOC 13 | ||
213 | #define SRST_STRC_A 14 | ||
214 | #define SRST_L2C 15 | ||
215 | |||
216 | #define SRST_DAP 16 | ||
217 | #define SRST_CORE_PVTM 17 | ||
218 | #define SRST_GPU 18 | ||
219 | #define SRST_GPU_NIU 19 | ||
220 | #define SRST_UPCTL2 20 | ||
221 | #define SRST_UPCTL2_A 21 | ||
222 | #define SRST_UPCTL2_P 22 | ||
223 | #define SRST_MSCH 23 | ||
224 | #define SRST_MSCH_P 24 | ||
225 | #define SRST_DDRMON_P 25 | ||
226 | #define SRST_DDRSTDBY_P 26 | ||
227 | #define SRST_DDRSTDBY 27 | ||
228 | #define SRST_DDRGRF_p 28 | ||
229 | #define SRST_AXI_SPLIT_A 29 | ||
230 | #define SRST_AXI_CMD_A 30 | ||
231 | #define SRST_AXI_CMD_P 31 | ||
232 | |||
233 | #define SRST_DDRPHY 32 | ||
234 | #define SRST_DDRPHYDIV 33 | ||
235 | #define SRST_DDRPHY_P 34 | ||
236 | #define SRST_VPU_A 36 | ||
237 | #define SRST_VPU_NIU_A 37 | ||
238 | #define SRST_VPU_H 38 | ||
239 | #define SRST_VPU_NIU_H 39 | ||
240 | #define SRST_VI_NIU_A 40 | ||
241 | #define SRST_VI_NIU_H 41 | ||
242 | #define SRST_ISP_H 42 | ||
243 | #define SRST_ISP 43 | ||
244 | #define SRST_CIF_A 44 | ||
245 | #define SRST_CIF_H 45 | ||
246 | #define SRST_CIF_PCLKIN 46 | ||
247 | #define SRST_MIPICSIPHY_P 47 | ||
248 | |||
249 | #define SRST_VO_NIU_A 48 | ||
250 | #define SRST_VO_NIU_H 49 | ||
251 | #define SRST_VO_NIU_P 50 | ||
252 | #define SRST_VOPB_A 51 | ||
253 | #define SRST_VOPB_H 52 | ||
254 | #define SRST_VOPB 53 | ||
255 | #define SRST_PWM_VOPB 54 | ||
256 | #define SRST_VOPL_A 55 | ||
257 | #define SRST_VOPL_H 56 | ||
258 | #define SRST_VOPL 57 | ||
259 | #define SRST_RGA_A 58 | ||
260 | #define SRST_RGA_H 59 | ||
261 | #define SRST_RGA 60 | ||
262 | #define SRST_MIPIDSI_HOST_P 61 | ||
263 | #define SRST_MIPIDSIPHY_P 62 | ||
264 | #define SRST_VPU_CORE 63 | ||
265 | |||
266 | #define SRST_PERI_NIU_A 64 | ||
267 | #define SRST_USB_NIU_H 65 | ||
268 | #define SRST_USB2OTG_H 66 | ||
269 | #define SRST_USB2OTG 67 | ||
270 | #define SRST_USB2OTG_ADP 68 | ||
271 | #define SRST_USB2HOST_H 69 | ||
272 | #define SRST_USB2HOST_ARB_H 70 | ||
273 | #define SRST_USB2HOST_AUX_H 71 | ||
274 | #define SRST_USB2HOST_EHCI 72 | ||
275 | #define SRST_USB2HOST 73 | ||
276 | #define SRST_USBPHYPOR 74 | ||
277 | #define SRST_USBPHY_OTG_PORT 75 | ||
278 | #define SRST_USBPHY_HOST_PORT 76 | ||
279 | #define SRST_USBPHY_GRF 77 | ||
280 | #define SRST_CPU_BOOST_P 78 | ||
281 | #define SRST_CPU_BOOST 79 | ||
282 | |||
283 | #define SRST_MMC_NAND_NIU_H 80 | ||
284 | #define SRST_SDIO_H 81 | ||
285 | #define SRST_EMMC_H 82 | ||
286 | #define SRST_SFC_H 83 | ||
287 | #define SRST_SFC 84 | ||
288 | #define SRST_SDCARD_NIU_H 85 | ||
289 | #define SRST_SDMMC_H 86 | ||
290 | #define SRST_NANDC_H 89 | ||
291 | #define SRST_NANDC 90 | ||
292 | #define SRST_GMAC_NIU_A 92 | ||
293 | #define SRST_GMAC_NIU_P 93 | ||
294 | #define SRST_GMAC_A 94 | ||
295 | |||
296 | #define SRST_PMU_NIU_P 96 | ||
297 | #define SRST_PMU_SGRF_P 97 | ||
298 | #define SRST_PMU_GRF_P 98 | ||
299 | #define SRST_PMU 99 | ||
300 | #define SRST_PMU_MEM_P 100 | ||
301 | #define SRST_PMU_GPIO0_P 101 | ||
302 | #define SRST_PMU_UART0_P 102 | ||
303 | #define SRST_PMU_CRU_P 103 | ||
304 | #define SRST_PMU_PVTM 104 | ||
305 | #define SRST_PMU_UART 105 | ||
306 | #define SRST_PMU_NIU_H 106 | ||
307 | #define SRST_PMU_DDR_FAIL_SAVE 107 | ||
308 | #define SRST_PMU_CORE_PERF_A 108 | ||
309 | #define SRST_PMU_CORE_GRF_P 109 | ||
310 | #define SRST_PMU_GPU_PERF_A 110 | ||
311 | #define SRST_PMU_GPU_GRF_P 111 | ||
312 | |||
313 | #define SRST_CRYPTO_NIU_A 112 | ||
314 | #define SRST_CRYPTO_NIU_H 113 | ||
315 | #define SRST_CRYPTO_A 114 | ||
316 | #define SRST_CRYPTO_H 115 | ||
317 | #define SRST_CRYPTO 116 | ||
318 | #define SRST_CRYPTO_APK 117 | ||
319 | #define SRST_BUS_NIU_H 120 | ||
320 | #define SRST_USB_NIU_P 121 | ||
321 | #define SRST_BUS_TOP_NIU_P 122 | ||
322 | #define SRST_INTMEM_A 123 | ||
323 | #define SRST_GIC_A 124 | ||
324 | #define SRST_ROM_H 126 | ||
325 | #define SRST_DCF_A 127 | ||
326 | |||
327 | #define SRST_DCF_P 128 | ||
328 | #define SRST_PDM_H 129 | ||
329 | #define SRST_PDM 130 | ||
330 | #define SRST_I2S0_H 131 | ||
331 | #define SRST_I2S0_TX 132 | ||
332 | #define SRST_I2S1_H 133 | ||
333 | #define SRST_I2S1 134 | ||
334 | #define SRST_I2S2_H 135 | ||
335 | #define SRST_I2S2 136 | ||
336 | #define SRST_UART1_P 137 | ||
337 | #define SRST_UART1 138 | ||
338 | #define SRST_UART2_P 139 | ||
339 | #define SRST_UART2 140 | ||
340 | #define SRST_UART3_P 141 | ||
341 | #define SRST_UART3 142 | ||
342 | #define SRST_UART4_P 143 | ||
343 | |||
344 | #define SRST_UART4 144 | ||
345 | #define SRST_UART5_P 145 | ||
346 | #define SRST_UART5 146 | ||
347 | #define SRST_I2C0_P 147 | ||
348 | #define SRST_I2C0 148 | ||
349 | #define SRST_I2C1_P 149 | ||
350 | #define SRST_I2C1 150 | ||
351 | #define SRST_I2C2_P 151 | ||
352 | #define SRST_I2C2 152 | ||
353 | #define SRST_I2C3_P 153 | ||
354 | #define SRST_I2C3 154 | ||
355 | #define SRST_PWM0_P 157 | ||
356 | #define SRST_PWM0 158 | ||
357 | #define SRST_PWM1_P 159 | ||
358 | |||
359 | #define SRST_PWM1 160 | ||
360 | #define SRST_SPI0_P 161 | ||
361 | #define SRST_SPI0 162 | ||
362 | #define SRST_SPI1_P 163 | ||
363 | #define SRST_SPI1 164 | ||
364 | #define SRST_SARADC_P 165 | ||
365 | #define SRST_SARADC 166 | ||
366 | #define SRST_TSADC_P 167 | ||
367 | #define SRST_TSADC 168 | ||
368 | #define SRST_TIMER_P 169 | ||
369 | #define SRST_TIMER0 170 | ||
370 | #define SRST_TIMER1 171 | ||
371 | #define SRST_TIMER2 172 | ||
372 | #define SRST_TIMER3 173 | ||
373 | #define SRST_TIMER4 174 | ||
374 | #define SRST_TIMER5 175 | ||
375 | |||
376 | #define SRST_OTP_NS_P 176 | ||
377 | #define SRST_OTP_NS_SBPI 177 | ||
378 | #define SRST_OTP_NS_USR 178 | ||
379 | #define SRST_OTP_PHY_P 179 | ||
380 | #define SRST_OTP_PHY 180 | ||
381 | #define SRST_WDT_NS_P 181 | ||
382 | #define SRST_GPIO1_P 182 | ||
383 | #define SRST_GPIO2_P 183 | ||
384 | #define SRST_GPIO3_P 184 | ||
385 | #define SRST_SGRF_P 185 | ||
386 | #define SRST_GRF_P 186 | ||
387 | #define SRST_I2S0_RX 191 | ||
388 | |||
389 | #endif | ||
diff --git a/include/dt-bindings/clock/pxa-clock.h b/include/dt-bindings/clock/pxa-clock.h index e65803b1dc7e..0b0fd2b01538 100644 --- a/include/dt-bindings/clock/pxa-clock.h +++ b/include/dt-bindings/clock/pxa-clock.h | |||
@@ -72,6 +72,7 @@ | |||
72 | #define CLK_USIM 58 | 72 | #define CLK_USIM 58 |
73 | #define CLK_USIM1 59 | 73 | #define CLK_USIM1 59 |
74 | #define CLK_USMI0 60 | 74 | #define CLK_USMI0 60 |
75 | #define CLK_MAX 61 | 75 | #define CLK_OSC32k768 61 |
76 | #define CLK_MAX 62 | ||
76 | 77 | ||
77 | #endif | 78 | #endif |
diff --git a/include/dt-bindings/clock/qcom,dispcc-sdm845.h b/include/dt-bindings/clock/qcom,dispcc-sdm845.h new file mode 100644 index 000000000000..11eed4bc9646 --- /dev/null +++ b/include/dt-bindings/clock/qcom,dispcc-sdm845.h | |||
@@ -0,0 +1,45 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | /* | ||
3 | * Copyright (c) 2018, The Linux Foundation. All rights reserved. | ||
4 | */ | ||
5 | |||
6 | #ifndef _DT_BINDINGS_CLK_SDM_DISP_CC_SDM845_H | ||
7 | #define _DT_BINDINGS_CLK_SDM_DISP_CC_SDM845_H | ||
8 | |||
9 | /* DISP_CC clock registers */ | ||
10 | #define DISP_CC_MDSS_AHB_CLK 0 | ||
11 | #define DISP_CC_MDSS_AXI_CLK 1 | ||
12 | #define DISP_CC_MDSS_BYTE0_CLK 2 | ||
13 | #define DISP_CC_MDSS_BYTE0_CLK_SRC 3 | ||
14 | #define DISP_CC_MDSS_BYTE0_INTF_CLK 4 | ||
15 | #define DISP_CC_MDSS_BYTE1_CLK 5 | ||
16 | #define DISP_CC_MDSS_BYTE1_CLK_SRC 6 | ||
17 | #define DISP_CC_MDSS_BYTE1_INTF_CLK 7 | ||
18 | #define DISP_CC_MDSS_ESC0_CLK 8 | ||
19 | #define DISP_CC_MDSS_ESC0_CLK_SRC 9 | ||
20 | #define DISP_CC_MDSS_ESC1_CLK 10 | ||
21 | #define DISP_CC_MDSS_ESC1_CLK_SRC 11 | ||
22 | #define DISP_CC_MDSS_MDP_CLK 12 | ||
23 | #define DISP_CC_MDSS_MDP_CLK_SRC 13 | ||
24 | #define DISP_CC_MDSS_MDP_LUT_CLK 14 | ||
25 | #define DISP_CC_MDSS_PCLK0_CLK 15 | ||
26 | #define DISP_CC_MDSS_PCLK0_CLK_SRC 16 | ||
27 | #define DISP_CC_MDSS_PCLK1_CLK 17 | ||
28 | #define DISP_CC_MDSS_PCLK1_CLK_SRC 18 | ||
29 | #define DISP_CC_MDSS_ROT_CLK 19 | ||
30 | #define DISP_CC_MDSS_ROT_CLK_SRC 20 | ||
31 | #define DISP_CC_MDSS_RSCC_AHB_CLK 21 | ||
32 | #define DISP_CC_MDSS_RSCC_VSYNC_CLK 22 | ||
33 | #define DISP_CC_MDSS_VSYNC_CLK 23 | ||
34 | #define DISP_CC_MDSS_VSYNC_CLK_SRC 24 | ||
35 | #define DISP_CC_PLL0 25 | ||
36 | #define DISP_CC_MDSS_BYTE0_DIV_CLK_SRC 26 | ||
37 | #define DISP_CC_MDSS_BYTE1_DIV_CLK_SRC 27 | ||
38 | |||
39 | /* DISP_CC Reset */ | ||
40 | #define DISP_CC_MDSS_RSCC_BCR 0 | ||
41 | |||
42 | /* DISP_CC GDSCR */ | ||
43 | #define MDSS_GDSC 0 | ||
44 | |||
45 | #endif | ||
diff --git a/include/dt-bindings/clock/qcom,gcc-sdm845.h b/include/dt-bindings/clock/qcom,gcc-sdm845.h index aca61264f12c..f96fc2dbf60e 100644 --- a/include/dt-bindings/clock/qcom,gcc-sdm845.h +++ b/include/dt-bindings/clock/qcom,gcc-sdm845.h | |||
@@ -192,6 +192,8 @@ | |||
192 | #define GCC_VS_CTRL_CLK_SRC 182 | 192 | #define GCC_VS_CTRL_CLK_SRC 182 |
193 | #define GCC_VSENSOR_CLK_SRC 183 | 193 | #define GCC_VSENSOR_CLK_SRC 183 |
194 | #define GPLL4 184 | 194 | #define GPLL4 184 |
195 | #define GCC_CPUSS_DVM_BUS_CLK 185 | ||
196 | #define GCC_CPUSS_GNOC_CLK 186 | ||
195 | 197 | ||
196 | /* GCC Resets */ | 198 | /* GCC Resets */ |
197 | #define GCC_MMSS_BCR 0 | 199 | #define GCC_MMSS_BCR 0 |
diff --git a/include/dt-bindings/clock/r9a06g032-sysctrl.h b/include/dt-bindings/clock/r9a06g032-sysctrl.h new file mode 100644 index 000000000000..90c0f3dc1ba1 --- /dev/null +++ b/include/dt-bindings/clock/r9a06g032-sysctrl.h | |||
@@ -0,0 +1,148 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | /* | ||
3 | * R9A06G032 sysctrl IDs | ||
4 | * | ||
5 | * Copyright (C) 2018 Renesas Electronics Europe Limited | ||
6 | * | ||
7 | * Michel Pollet <michel.pollet@bp.renesas.com>, <buserror@gmail.com> | ||
8 | */ | ||
9 | |||
10 | #ifndef __DT_BINDINGS_R9A06G032_SYSCTRL_H__ | ||
11 | #define __DT_BINDINGS_R9A06G032_SYSCTRL_H__ | ||
12 | |||
13 | #define R9A06G032_CLK_PLL_USB 1 | ||
14 | #define R9A06G032_CLK_48 1 /* AKA CLK_PLL_USB */ | ||
15 | #define R9A06G032_MSEBIS_CLK 3 /* AKA CLKOUT_D16 */ | ||
16 | #define R9A06G032_MSEBIM_CLK 3 /* AKA CLKOUT_D16 */ | ||
17 | #define R9A06G032_CLK_DDRPHY_PLLCLK 5 /* AKA CLKOUT_D1OR2 */ | ||
18 | #define R9A06G032_CLK50 6 /* AKA CLKOUT_D20 */ | ||
19 | #define R9A06G032_CLK25 7 /* AKA CLKOUT_D40 */ | ||
20 | #define R9A06G032_CLK125 9 /* AKA CLKOUT_D8 */ | ||
21 | #define R9A06G032_CLK_P5_PG1 17 /* AKA DIV_P5_PG */ | ||
22 | #define R9A06G032_CLK_REF_SYNC 21 /* AKA DIV_REF_SYNC */ | ||
23 | #define R9A06G032_CLK_25_PG4 26 | ||
24 | #define R9A06G032_CLK_25_PG5 27 | ||
25 | #define R9A06G032_CLK_25_PG6 28 | ||
26 | #define R9A06G032_CLK_25_PG7 29 | ||
27 | #define R9A06G032_CLK_25_PG8 30 | ||
28 | #define R9A06G032_CLK_ADC 31 | ||
29 | #define R9A06G032_CLK_ECAT100 32 | ||
30 | #define R9A06G032_CLK_HSR100 33 | ||
31 | #define R9A06G032_CLK_I2C0 34 | ||
32 | #define R9A06G032_CLK_I2C1 35 | ||
33 | #define R9A06G032_CLK_MII_REF 36 | ||
34 | #define R9A06G032_CLK_NAND 37 | ||
35 | #define R9A06G032_CLK_NOUSBP2_PG6 38 | ||
36 | #define R9A06G032_CLK_P1_PG2 39 | ||
37 | #define R9A06G032_CLK_P1_PG3 40 | ||
38 | #define R9A06G032_CLK_P1_PG4 41 | ||
39 | #define R9A06G032_CLK_P4_PG3 42 | ||
40 | #define R9A06G032_CLK_P4_PG4 43 | ||
41 | #define R9A06G032_CLK_P6_PG1 44 | ||
42 | #define R9A06G032_CLK_P6_PG2 45 | ||
43 | #define R9A06G032_CLK_P6_PG3 46 | ||
44 | #define R9A06G032_CLK_P6_PG4 47 | ||
45 | #define R9A06G032_CLK_PCI_USB 48 | ||
46 | #define R9A06G032_CLK_QSPI0 49 | ||
47 | #define R9A06G032_CLK_QSPI1 50 | ||
48 | #define R9A06G032_CLK_RGMII_REF 51 | ||
49 | #define R9A06G032_CLK_RMII_REF 52 | ||
50 | #define R9A06G032_CLK_SDIO0 53 | ||
51 | #define R9A06G032_CLK_SDIO1 54 | ||
52 | #define R9A06G032_CLK_SERCOS100 55 | ||
53 | #define R9A06G032_CLK_SLCD 56 | ||
54 | #define R9A06G032_CLK_SPI0 57 | ||
55 | #define R9A06G032_CLK_SPI1 58 | ||
56 | #define R9A06G032_CLK_SPI2 59 | ||
57 | #define R9A06G032_CLK_SPI3 60 | ||
58 | #define R9A06G032_CLK_SPI4 61 | ||
59 | #define R9A06G032_CLK_SPI5 62 | ||
60 | #define R9A06G032_CLK_SWITCH 63 | ||
61 | #define R9A06G032_HCLK_ECAT125 65 | ||
62 | #define R9A06G032_HCLK_PINCONFIG 66 | ||
63 | #define R9A06G032_HCLK_SERCOS 67 | ||
64 | #define R9A06G032_HCLK_SGPIO2 68 | ||
65 | #define R9A06G032_HCLK_SGPIO3 69 | ||
66 | #define R9A06G032_HCLK_SGPIO4 70 | ||
67 | #define R9A06G032_HCLK_TIMER0 71 | ||
68 | #define R9A06G032_HCLK_TIMER1 72 | ||
69 | #define R9A06G032_HCLK_USBF 73 | ||
70 | #define R9A06G032_HCLK_USBH 74 | ||
71 | #define R9A06G032_HCLK_USBPM 75 | ||
72 | #define R9A06G032_CLK_48_PG_F 76 | ||
73 | #define R9A06G032_CLK_48_PG4 77 | ||
74 | #define R9A06G032_CLK_DDRPHY_PCLK 81 /* AKA CLK_REF_SYNC_D4 */ | ||
75 | #define R9A06G032_CLK_FW 81 /* AKA CLK_REF_SYNC_D4 */ | ||
76 | #define R9A06G032_CLK_CRYPTO 81 /* AKA CLK_REF_SYNC_D4 */ | ||
77 | #define R9A06G032_CLK_A7MP 84 /* AKA DIV_CA7 */ | ||
78 | #define R9A06G032_HCLK_CAN0 85 | ||
79 | #define R9A06G032_HCLK_CAN1 86 | ||
80 | #define R9A06G032_HCLK_DELTASIGMA 87 | ||
81 | #define R9A06G032_HCLK_PWMPTO 88 | ||
82 | #define R9A06G032_HCLK_RSV 89 | ||
83 | #define R9A06G032_HCLK_SGPIO0 90 | ||
84 | #define R9A06G032_HCLK_SGPIO1 91 | ||
85 | #define R9A06G032_RTOS_MDC 92 | ||
86 | #define R9A06G032_CLK_CM3 93 | ||
87 | #define R9A06G032_CLK_DDRC 94 | ||
88 | #define R9A06G032_CLK_ECAT25 95 | ||
89 | #define R9A06G032_CLK_HSR50 96 | ||
90 | #define R9A06G032_CLK_HW_RTOS 97 | ||
91 | #define R9A06G032_CLK_SERCOS50 98 | ||
92 | #define R9A06G032_HCLK_ADC 99 | ||
93 | #define R9A06G032_HCLK_CM3 100 | ||
94 | #define R9A06G032_HCLK_CRYPTO_EIP150 101 | ||
95 | #define R9A06G032_HCLK_CRYPTO_EIP93 102 | ||
96 | #define R9A06G032_HCLK_DDRC 103 | ||
97 | #define R9A06G032_HCLK_DMA0 104 | ||
98 | #define R9A06G032_HCLK_DMA1 105 | ||
99 | #define R9A06G032_HCLK_GMAC0 106 | ||
100 | #define R9A06G032_HCLK_GMAC1 107 | ||
101 | #define R9A06G032_HCLK_GPIO0 108 | ||
102 | #define R9A06G032_HCLK_GPIO1 109 | ||
103 | #define R9A06G032_HCLK_GPIO2 110 | ||
104 | #define R9A06G032_HCLK_HSR 111 | ||
105 | #define R9A06G032_HCLK_I2C0 112 | ||
106 | #define R9A06G032_HCLK_I2C1 113 | ||
107 | #define R9A06G032_HCLK_LCD 114 | ||
108 | #define R9A06G032_HCLK_MSEBI_M 115 | ||
109 | #define R9A06G032_HCLK_MSEBI_S 116 | ||
110 | #define R9A06G032_HCLK_NAND 117 | ||
111 | #define R9A06G032_HCLK_PG_I 118 | ||
112 | #define R9A06G032_HCLK_PG19 119 | ||
113 | #define R9A06G032_HCLK_PG20 120 | ||
114 | #define R9A06G032_HCLK_PG3 121 | ||
115 | #define R9A06G032_HCLK_PG4 122 | ||
116 | #define R9A06G032_HCLK_QSPI0 123 | ||
117 | #define R9A06G032_HCLK_QSPI1 124 | ||
118 | #define R9A06G032_HCLK_ROM 125 | ||
119 | #define R9A06G032_HCLK_RTC 126 | ||
120 | #define R9A06G032_HCLK_SDIO0 127 | ||
121 | #define R9A06G032_HCLK_SDIO1 128 | ||
122 | #define R9A06G032_HCLK_SEMAP 129 | ||
123 | #define R9A06G032_HCLK_SPI0 130 | ||
124 | #define R9A06G032_HCLK_SPI1 131 | ||
125 | #define R9A06G032_HCLK_SPI2 132 | ||
126 | #define R9A06G032_HCLK_SPI3 133 | ||
127 | #define R9A06G032_HCLK_SPI4 134 | ||
128 | #define R9A06G032_HCLK_SPI5 135 | ||
129 | #define R9A06G032_HCLK_SWITCH 136 | ||
130 | #define R9A06G032_HCLK_SWITCH_RG 137 | ||
131 | #define R9A06G032_HCLK_UART0 138 | ||
132 | #define R9A06G032_HCLK_UART1 139 | ||
133 | #define R9A06G032_HCLK_UART2 140 | ||
134 | #define R9A06G032_HCLK_UART3 141 | ||
135 | #define R9A06G032_HCLK_UART4 142 | ||
136 | #define R9A06G032_HCLK_UART5 143 | ||
137 | #define R9A06G032_HCLK_UART6 144 | ||
138 | #define R9A06G032_HCLK_UART7 145 | ||
139 | #define R9A06G032_CLK_UART0 146 | ||
140 | #define R9A06G032_CLK_UART1 147 | ||
141 | #define R9A06G032_CLK_UART2 148 | ||
142 | #define R9A06G032_CLK_UART3 149 | ||
143 | #define R9A06G032_CLK_UART4 150 | ||
144 | #define R9A06G032_CLK_UART5 151 | ||
145 | #define R9A06G032_CLK_UART6 152 | ||
146 | #define R9A06G032_CLK_UART7 153 | ||
147 | |||
148 | #endif /* __DT_BINDINGS_R9A06G032_SYSCTRL_H__ */ | ||
diff --git a/include/dt-bindings/clock/sun8i-r40-ccu.h b/include/dt-bindings/clock/sun8i-r40-ccu.h index 4fa5f69fc297..f9e15a235626 100644 --- a/include/dt-bindings/clock/sun8i-r40-ccu.h +++ b/include/dt-bindings/clock/sun8i-r40-ccu.h | |||
@@ -43,6 +43,10 @@ | |||
43 | #ifndef _DT_BINDINGS_CLK_SUN8I_R40_H_ | 43 | #ifndef _DT_BINDINGS_CLK_SUN8I_R40_H_ |
44 | #define _DT_BINDINGS_CLK_SUN8I_R40_H_ | 44 | #define _DT_BINDINGS_CLK_SUN8I_R40_H_ |
45 | 45 | ||
46 | #define CLK_PLL_VIDEO0 7 | ||
47 | |||
48 | #define CLK_PLL_VIDEO1 16 | ||
49 | |||
46 | #define CLK_CPU 24 | 50 | #define CLK_CPU 24 |
47 | 51 | ||
48 | #define CLK_BUS_MIPI_DSI 29 | 52 | #define CLK_BUS_MIPI_DSI 29 |