History

Merge tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux

Pull more clk updates from Stephen Boyd: "Here's some more updates that missed the last pull request because I happened to tag the tree at an earlier point in the history of clk-next. I must have fat fingered it and checked out an older version of clk-next on this second computer I'm using. This time it actually includes more code for Qualcomm SoCs, the AT91 major updates, and some Rockchip SoC clk driver updates as well. I've corrected this flow so this shouldn't happen again" * tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux: (83 commits) clk: bcm2835: Do not use prediv with bcm2711's PLLs clk: drop unused function __clk_get_flags clk: hsdk: Fix bad dependency on IOMEM dt-bindings: clock: Fix YAML schemas for LPASS clocks on SC7180 clk: mmp: avoid missing prototype warning clk: sparx5: Add Sparx5 SoC DPLL clock driver dt-bindings: clock: sparx5: Add bindings include file clk: qoriq: add LS1021A core pll mux options clk: clk-atlas6: fix return value check in atlas6_clk_init() clk: tegra: pll: Improve PLLM enable-state detection clk: X1000: Add support for calculat REFCLK of USB PHY. clk: JZ4780: Reformat the code to align it. clk: JZ4780: Add functions for enable and disable USB PHY. clk: Ingenic: Add RTC related clocks for Ingenic SoCs. dt-bindings: clock: Add tabs to align code. dt-bindings: clock: Add RTC related clocks for Ingenic SoCs. clk: davinci: Use fallthrough pseudo-keyword clk: imx: Use fallthrough pseudo-keyword clk: qcom: gcc-sdm660: Fix up gcc_mss_mnoc_bimc_axi_clk clk: qcom: gcc-sdm660: Add missing modem reset ...

Linus Torvalds committed 6 years ago

Commit 05a5b5d2 parents 4586039 dd9c69782 files · +4778 −871Browse files

Unified · Split

82 files
  1. Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-firmware.yaml +9 −0
  2. Documentation/devicetree/bindings/clock/idt,versaclock5.txt +0 −125
  3. Documentation/devicetree/bindings/clock/idt,versaclock5.yaml +154 −0
  4. Documentation/devicetree/bindings/clock/qcom,gpucc.yaml +13 −5
  5. Documentation/devicetree/bindings/clock/qcom,msm8996-apcc.yaml +2 −4
  6. Documentation/devicetree/bindings/clock/qcom,sc7180-gpucc.yaml +0 −74
  7. Documentation/devicetree/bindings/clock/qcom,sc7180-lpasscorecc.yaml +108 −0
  8. Documentation/devicetree/bindings/clock/rockchip,rk3288-cru.txt +7 −1
  9. MAINTAINERS +3 −1
  10. drivers/clk/Kconfig +1 −1
  11. drivers/clk/Makefile +1 −0
  12. drivers/clk/actions/owl-s500.c +88 −1
  13. drivers/clk/at91/Makefile +1 −0
  14. drivers/clk/at91/at91rm9200.c +2 −1
  15. drivers/clk/at91/at91sam9260.c +2 −1
  16. drivers/clk/at91/at91sam9g45.c +3 −2
  17. drivers/clk/at91/at91sam9n12.c +4 −3
  18. drivers/clk/at91/at91sam9rl.c +2 −1
  19. drivers/clk/at91/at91sam9x5.c +4 −3
  20. drivers/clk/at91/clk-generated.c +27 −17
  21. drivers/clk/at91/clk-main.c +3 −3
  22. drivers/clk/at91/clk-master.c +305 −5
  23. drivers/clk/at91/clk-peripheral.c +105 −6
  24. drivers/clk/at91/clk-programmable.c +10 −1
  25. drivers/clk/at91/clk-sam9x60-pll.c +381 −166
  26. drivers/clk/at91/clk-system.c +2 −2
  27. drivers/clk/at91/clk-utmi.c +98 −5
  28. drivers/clk/at91/dt-compat.c +15 −10
  29. drivers/clk/at91/pmc.h +35 −8
  30. drivers/clk/at91/sam9x60.c +49 −17
  31. drivers/clk/at91/sama5d2.c +21 −20
  32. drivers/clk/at91/sama5d3.c +5 −3
  33. drivers/clk/at91/sama5d4.c +4 −3
  34. drivers/clk/at91/sama7g5.c +1059 −0
  35. drivers/clk/at91/sckc.c +3 −2
  36. drivers/clk/bcm/clk-bcm2835.c +21 −4
  37. drivers/clk/bcm/clk-iproc-asiu.c +2 −2
  38. drivers/clk/clk-qoriq.c +9 −1
  39. drivers/clk/clk-sparx5.c +295 −0
  40. drivers/clk/clk-versaclock5.c +38 −44
  41. drivers/clk/clk.c +32 −6
  42. drivers/clk/davinci/pll.c +1 −1
  43. drivers/clk/imx/clk-pllv3.c +2 −2
  44. drivers/clk/ingenic/jz4780-cgu.c +91 −74
  45. drivers/clk/ingenic/x1000-cgu.c +96 −1
  46. drivers/clk/ingenic/x1830-cgu.c +13 −0
  47. drivers/clk/mmp/clk-pxa168.c +1 −0
  48. drivers/clk/mmp/clk-pxa910.c +1 −0
  49. drivers/clk/qcom/Kconfig +25 −0
  50. drivers/clk/qcom/Makefile +3 −0
  51. drivers/clk/qcom/clk-alpha-pll.c +34 −36
  52. drivers/clk/qcom/clk-alpha-pll.h +10 −5
  53. drivers/clk/qcom/gcc-sc7180.c +14 −0
  54. drivers/clk/qcom/gcc-sdm660.c +4 −0
  55. drivers/clk/qcom/gcc-sm8150.c +10 −16
  56. drivers/clk/qcom/gdsc.c +39 −0
  57. drivers/clk/qcom/gdsc.h +2 −0
  58. drivers/clk/qcom/gpucc-sc7180.c +1 −26
  59. drivers/clk/qcom/gpucc-sdm845.c +1 −26
  60. drivers/clk/qcom/gpucc-sm8150.c +320 −0
  61. drivers/clk/qcom/gpucc-sm8250.c +348 −0
  62. drivers/clk/qcom/lpasscorecc-sc7180.c +476 −0
  63. drivers/clk/rockchip/clk-pll.c +41 −29
  64. drivers/clk/rockchip/clk-rk3188.c +1 −0
  65. drivers/clk/rockchip/clk-rk3288.c +36 −3
  66. drivers/clk/rockchip/clk-rk3328.c +4 −4
  67. drivers/clk/sirf/clk-atlas6.c +1 −1
  68. drivers/clk/tegra/clk-pll.c +15 −5
  69. drivers/clk/x86/clk-cgu-pll.c +1 −1
  70. drivers/clk/x86/clk-cgu.c +12 −20
  71. include/dt-bindings/clock/actions,s500-cmu.h +6 −1
  72. include/dt-bindings/clock/jz4780-cgu.h +73 −71
  73. include/dt-bindings/clock/qcom,gcc-sc7180.h +1 −0
  74. include/dt-bindings/clock/qcom,gcc-sdm660.h +1 −0
  75. include/dt-bindings/clock/qcom,gpucc-sm8150.h +33 −0
  76. include/dt-bindings/clock/qcom,gpucc-sm8250.h +34 −0
  77. include/dt-bindings/clock/qcom,lpasscorecc-sc7180.h +29 −0
  78. include/dt-bindings/clock/x1000-cgu.h +2 −0
  79. include/dt-bindings/clock/x1830-cgu.h +2 −0
  80. include/dt-bindings/reset/actions,s500-reset.h +67 −0
  81. include/linux/clk-provider.h +0 −1
  82. include/linux/clk/at91_pmc.h +4 −0
Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-firmware.yaml+9−0
@@ -10,6 +10,15 @@ maintainers: · 9 unmodified lines
1010 - Eric Anholt <eric@anholt.net>
1111 - Stefan Wahren <wahrenst@gmx.net>
1212
13+select:
14+ properties:
15+ compatible:
16+ contains:
17+ const: raspberrypi,bcm2835-firmware
18+
19+ required:
20+ - compatible
21+
1322 properties:
1423 compatible:
1524 items:
Documentation/devicetree/bindings/clock/idt,versaclock5.txt+0−125
@@ -1,125 +0,0 @@
1−Binding for IDT VersaClock 5,6 programmable i2c clock generators.
2−
3−The IDT VersaClock 5 and VersaClock 6 are programmable i2c clock
4−generators providing from 3 to 12 output clocks.
5−
6−==I2C device node==
7−
8−Required properties:
9−- compatible: shall be one of
10− "idt,5p49v5923"
11− "idt,5p49v5925"
12− "idt,5p49v5933"
13− "idt,5p49v5935"
14− "idt,5p49v6901"
15− "idt,5p49v6965"
16−- reg: i2c device address, shall be 0x68 or 0x6a.
17−- #clock-cells: from common clock binding; shall be set to 1.
18−- clocks: from common clock binding; list of parent clock handles,
19− - 5p49v5923 and
20− 5p49v5925 and
21− 5p49v6901: (required) either or both of XTAL or CLKIN
22− reference clock.
23− - 5p49v5933 and
24− - 5p49v5935: (optional) property not present (internal
25− Xtal used) or CLKIN reference
26− clock.
27−- clock-names: from common clock binding; clock input names, can be
28− - 5p49v5923 and
29− 5p49v5925 and
30− 5p49v6901: (required) either or both of "xin", "clkin".
31− - 5p49v5933 and
32− - 5p49v5935: (optional) property not present or "clkin".
33−
34−For all output ports, a corresponding, optional child node named OUT1,
35−OUT2, etc. can represent a each output, and the node can be used to
36−specify the following:
37−
38−- itd,mode: can be one of the following:
39− - VC5_LVPECL
40− - VC5_CMOS
41− - VC5_HCSL33
42− - VC5_LVDS
43− - VC5_CMOS2
44− - VC5_CMOSD
45− - VC5_HCSL25
46−
47−- idt,voltage-microvolts: can be one of the following
48− - 1800000
49− - 2500000
50− - 3300000
51−- idt,slew-percent: Percent of normal, can be one of
52− - 80
53− - 85
54− - 90
55− - 100
56−
57−==Mapping between clock specifier and physical pins==
58−
59−When referencing the provided clock in the DT using phandle and
60−clock specifier, the following mapping applies:
61−
62−5P49V5923:
63− 0 -- OUT0_SEL_I2CB
64− 1 -- OUT1
65− 2 -- OUT2
66−
67−5P49V5933:
68− 0 -- OUT0_SEL_I2CB
69− 1 -- OUT1
70− 2 -- OUT4
71−
72−5P49V5925 and
73−5P49V5935:
74− 0 -- OUT0_SEL_I2CB
75− 1 -- OUT1
76− 2 -- OUT2
77− 3 -- OUT3
78− 4 -- OUT4
79−
80−5P49V6901:
81− 0 -- OUT0_SEL_I2CB
82− 1 -- OUT1
83− 2 -- OUT2
84− 3 -- OUT3
85− 4 -- OUT4
86−
87−==Example==
88−
89−/* 25MHz reference crystal */
90−ref25: ref25m {
91− compatible = "fixed-clock";
92− #clock-cells = <0>;
93− clock-frequency = <25000000>;
94−};
95−
96−i2c-master-node {
97−
98− /* IDT 5P49V5923 i2c clock generator */
99− vc5: clock-generator@6a {
100− compatible = "idt,5p49v5923";
101− reg = <0x6a>;
102− #clock-cells = <1>;
103−
104− /* Connect XIN input to 25MHz reference */
105− clocks = <&ref25m>;
106− clock-names = "xin";
107−
108− OUT1 {
109− itd,mode = <VC5_CMOS>;
110− idt,voltage-microvolts = <1800000>;
111− idt,slew-percent = <80>;
112− };
113− OUT2 {
114− ...
115− };
116− ...
117− };
118−};
119−
120−/* Consumer referencing the 5P49V5923 pin OUT1 */
121−consumer {
122− ...
123− clocks = <&vc5 1>;
124− ...
125−}
Documentation/devicetree/bindings/clock/idt,versaclock5.yaml+154−0
@@ -0,0 +1,154 @@
1+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/clock/idt,versaclock5.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: Binding for IDT VersaClock 5 and 6 programmable I2C clock generators
8+
9+description: |
10+ The IDT VersaClock 5 and VersaClock 6 are programmable I2C
11+ clock generators providing from 3 to 12 output clocks.
12+
13+ When referencing the provided clock in the DT using phandle and clock
14+ specifier, the following mapping applies:
15+
16+ - 5P49V5923:
17+ 0 -- OUT0_SEL_I2CB
18+ 1 -- OUT1
19+ 2 -- OUT2
20+
21+ - 5P49V5933:
22+ 0 -- OUT0_SEL_I2CB
23+ 1 -- OUT1
24+ 2 -- OUT4
25+
26+ - other parts:
27+ 0 -- OUT0_SEL_I2CB
28+ 1 -- OUT1
29+ 2 -- OUT2
30+ 3 -- OUT3
31+ 4 -- OUT4
32+
33+maintainers:
34+ - Luca Ceresoli <luca@lucaceresoli.net>
35+
36+properties:
37+ compatible:
38+ enum:
39+ - idt,5p49v5923
40+ - idt,5p49v5925
41+ - idt,5p49v5933
42+ - idt,5p49v5935
43+ - idt,5p49v6901
44+ - idt,5p49v6965
45+
46+ reg:
47+ description: I2C device address
48+ enum: [ 0x68, 0x6a ]
49+
50+ '#clock-cells':
51+ const: 1
52+
53+patternProperties:
54+ "^OUT[1-4]$":
55+ type: object
56+ description:
57+ Description of one of the outputs (OUT1..OUT4). See "Clock1 Output
58+ Configuration" in the Versaclock 5/6/6E Family Register Description
59+ and Programming Guide.
60+ properties:
61+ idt,mode:
62+ description:
63+ The output drive mode. Values defined in dt-bindings/clk/versaclock.h
64+ $ref: /schemas/types.yaml#/definitions/uint32
65+ minimum: 0
66+ maximum: 6
67+ idt,voltage-microvolt:
68+ description: The output drive voltage.
69+ enum: [ 1800000, 2500000, 3300000 ]
70+ idt,slew-percent:
71+ description: The Slew rate control for CMOS single-ended.
72+ $ref: /schemas/types.yaml#/definitions/uint32
73+ enum: [ 80, 85, 90, 100 ]
74+
75+required:
76+ - compatible
77+ - reg
78+ - '#clock-cells'
79+
80+allOf:
81+ - if:
82+ properties:
83+ compatible:
84+ enum:
85+ - idt,5p49v5933
86+ - idt,5p49v5935
87+ then:
88+ # Devices with builtin crystal + optional external input
89+ properties:
90+ clock-names:
91+ const: clkin
92+ clocks:
93+ maxItems: 1
94+ else:
95+ # Devices without builtin crystal
96+ properties:
97+ clock-names:
98+ minItems: 1
99+ maxItems: 2
100+ items:
101+ enum: [ xin, clkin ]
102+ clocks:
103+ minItems: 1
104+ maxItems: 2
105+ required:
106+ - clock-names
107+ - clocks
108+
109+examples:
110+ - |
111+ #include <dt-bindings/clk/versaclock.h>
112+
113+ /* 25MHz reference crystal */
114+ ref25: ref25m {
115+ compatible = "fixed-clock";
116+ #clock-cells = <0>;
117+ clock-frequency = <25000000>;
118+ };
119+
120+ i2c@0 {
121+ reg = <0x0 0x100>;
122+ #address-cells = <1>;
123+ #size-cells = <0>;
124+
125+ /* IDT 5P49V5923 I2C clock generator */
126+ vc5: clock-generator@6a {
127+ compatible = "idt,5p49v5923";
128+ reg = <0x6a>;
129+ #clock-cells = <1>;
130+
131+ /* Connect XIN input to 25MHz reference */
132+ clocks = <&ref25m>;
133+ clock-names = "xin";
134+
135+ OUT1 {
136+ idt,drive-mode = <VC5_CMOSD>;
137+ idt,voltage-microvolts = <1800000>;
138+ idt,slew-percent = <80>;
139+ };
140+
141+ OUT4 {
142+ idt,drive-mode = <VC5_LVDS>;
143+ };
144+ };
145+ };
146+
147+ /* Consumer referencing the 5P49V5923 pin OUT1 */
148+ consumer {
149+ /* ... */
150+ clocks = <&vc5 1>;
151+ /* ... */
152+ };
153+
154+...
Documentation/devicetree/bindings/clock/qcom,gpucc.yamlrenamed from Documentation/devicetree/bindings/clock/qcom,sdm845-gpucc.yaml+13−5
@@ -1,23 +1,31 @@
11 # SPDX-License-Identifier: GPL-2.0-only
22 %YAML 1.2
33 ---
4−$id: http://devicetree.org/schemas/clock/qcom,sdm845-gpucc.yaml#
4+$id: http://devicetree.org/schemas/clock/qcom,gpucc.yaml#
55 $schema: http://devicetree.org/meta-schemas/core.yaml#
66
7−title: Qualcomm Graphics Clock & Reset Controller Binding for SDM845
7+title: Qualcomm Graphics Clock & Reset Controller Binding
88
99 maintainers:
1010 - Taniya Das <tdas@codeaurora.org>
1111
1212 description: |
1313 Qualcomm graphics clock control module which supports the clocks, resets and
14− power domains on SDM845.
14+ power domains on SDM845/SC7180/SM8150/SM8250.
1515
16− See also dt-bindings/clock/qcom,gpucc-sdm845.h.
16+ See also:
17+ dt-bindings/clock/qcom,gpucc-sdm845.h
18+ dt-bindings/clock/qcom,gpucc-sc7180.h
19+ dt-bindings/clock/qcom,gpucc-sm8150.h
20+ dt-bindings/clock/qcom,gpucc-sm8250.h
1721
1822 properties:
1923 compatible:
20− const: qcom,sdm845-gpucc
24+ enum:
25+ - qcom,sdm845-gpucc
26+ - qcom,sc7180-gpucc
27+ - qcom,sm8150-gpucc
28+ - qcom,sm8250-gpucc
2129
2230 clocks:
2331 items:
Documentation/devicetree/bindings/clock/qcom,msm8996-apcc.yaml+2−4
@@ -1,7 +1,7 @@
11 # SPDX-License-Identifier: GPL-2.0-only
22 %YAML 1.2
33 ---
4−$id: http://devicetree.org/schemas/clock/qcom,kryocc.yaml#
4+$id: http://devicetree.org/schemas/clock/qcom,msm8996-apcc.yaml#
55 $schema: http://devicetree.org/meta-schemas/core.yaml#
66
77 title: Qualcomm clock controller for MSM8996 CPUs
@@ -46,11 +46,9 @@ required: · 38 unmodified lines
4646 additionalProperties: false
4747
4848 examples:
49− # Example for msm8996
5049 - |
5150 kryocc: clock-controller@6400000 {
5251 compatible = "qcom,msm8996-apcc";
5352 reg = <0x6400000 0x90000>;
5453 #clock-cells = <1>;
55− };
56−...
54+ };
Documentation/devicetree/bindings/clock/qcom,sc7180-gpucc.yaml+0−74
@@ -1,74 +0,0 @@
1−# SPDX-License-Identifier: GPL-2.0-only
2−%YAML 1.2
3−---
4−$id: http://devicetree.org/schemas/clock/qcom,sc7180-gpucc.yaml#
5−$schema: http://devicetree.org/meta-schemas/core.yaml#
6−
7−title: Qualcomm Graphics Clock & Reset Controller Binding for SC7180
8−
9−maintainers:
10− - Taniya Das <tdas@codeaurora.org>
11−
12−description: |
13− Qualcomm graphics clock control module which supports the clocks, resets and
14− power domains on SC7180.
15−
16− See also dt-bindings/clock/qcom,gpucc-sc7180.h.
17−
18−properties:
19− compatible:
20− const: qcom,sc7180-gpucc
21−
22− clocks:
23− items:
24− - description: Board XO source
25− - description: GPLL0 main branch source
26− - description: GPLL0 div branch source
27−
28− clock-names:
29− items:
30− - const: bi_tcxo
31− - const: gcc_gpu_gpll0_clk_src
32− - const: gcc_gpu_gpll0_div_clk_src
33−
34− '#clock-cells':
35− const: 1
36−
37− '#reset-cells':
38− const: 1
39−
40− '#power-domain-cells':
41− const: 1
42−
43− reg:
44− maxItems: 1
45−
46−required:
47− - compatible
48− - reg
49− - clocks
50− - clock-names
51− - '#clock-cells'
52− - '#reset-cells'
53− - '#power-domain-cells'
54−
55−additionalProperties: false
56−
57−examples:
58− - |
59− #include <dt-bindings/clock/qcom,gcc-sc7180.h>
60− #include <dt-bindings/clock/qcom,rpmh.h>
61− clock-controller@5090000 {
62− compatible = "qcom,sc7180-gpucc";
63− reg = <0x05090000 0x9000>;
64− clocks = <&rpmhcc RPMH_CXO_CLK>,
65− <&gcc GCC_GPU_GPLL0_CLK_SRC>,
66− <&gcc GCC_GPU_GPLL0_DIV_CLK_SRC>;
67− clock-names = "bi_tcxo",
68− "gcc_gpu_gpll0_clk_src",
69− "gcc_gpu_gpll0_div_clk_src";
70− #clock-cells = <1>;
71− #reset-cells = <1>;
72− #power-domain-cells = <1>;
73− };
74−...
Documentation/devicetree/bindings/clock/qcom,sc7180-lpasscorecc.yaml+108−0
@@ -0,0 +1,108 @@
1+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/clock/qcom,sc7180-lpasscorecc.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: Qualcomm LPASS Core Clock Controller Binding for SC7180
8+
9+maintainers:
10+ - Taniya Das <tdas@codeaurora.org>
11+
12+description: |
13+ Qualcomm LPASS core clock control module which supports the clocks and
14+ power domains on SC7180.
15+
16+ See also:
17+ - dt-bindings/clock/qcom,lpasscorecc-sc7180.h
18+
19+properties:
20+ compatible:
21+ enum:
22+ - qcom,sc7180-lpasshm
23+ - qcom,sc7180-lpasscorecc
24+
25+ clocks:
26+ items:
27+ - description: gcc_lpass_sway clock from GCC
28+ - description: Board XO source
29+
30+ clock-names:
31+ items:
32+ - const: iface
33+ - const: bi_tcxo
34+
35+ power-domains:
36+ maxItems: 1
37+
38+ '#clock-cells':
39+ const: 1
40+
41+ '#power-domain-cells':
42+ const: 1
43+
44+ reg:
45+ minItems: 1
46+ items:
47+ - description: lpass core cc register
48+ - description: lpass audio cc register
49+
50+ reg-names:
51+ items:
52+ - const: lpass_core_cc
53+ - const: lpass_audio_cc
54+
55+if:
56+ properties:
57+ compatible:
58+ contains:
59+ const: qcom,sc7180-lpasshm
60+then:
61+ properties:
62+ reg:
63+ maxItems: 1
64+
65+else:
66+ properties:
67+ reg:
68+ minItems: 2
69+
70+required:
71+ - compatible
72+ - reg
73+ - clocks
74+ - clock-names
75+ - '#clock-cells'
76+ - '#power-domain-cells'
77+
78+additionalProperties: false
79+
80+examples:
81+ - |
82+ #include <dt-bindings/clock/qcom,rpmh.h>
83+ #include <dt-bindings/clock/qcom,gcc-sc7180.h>
84+ #include <dt-bindings/clock/qcom,lpasscorecc-sc7180.h>
85+ clock-controller@63000000 {
86+ compatible = "qcom,sc7180-lpasshm";
87+ reg = <0x63000000 0x28>;
88+ clocks = <&gcc GCC_LPASS_CFG_NOC_SWAY_CLK>, <&rpmhcc RPMH_CXO_CLK>;
89+ clock-names = "iface", "bi_tcxo";
90+ #clock-cells = <1>;
91+ #power-domain-cells = <1>;
92+ };
93+
94+ - |
95+ #include <dt-bindings/clock/qcom,rpmh.h>
96+ #include <dt-bindings/clock/qcom,gcc-sc7180.h>
97+ #include <dt-bindings/clock/qcom,lpasscorecc-sc7180.h>
98+ clock-controller@62d00000 {
99+ compatible = "qcom,sc7180-lpasscorecc";
100+ reg = <0x62d00000 0x50000>, <0x62780000 0x30000>;
101+ reg-names = "lpass_core_cc", "lpass_audio_cc";
102+ clocks = <&gcc GCC_LPASS_CFG_NOC_SWAY_CLK>, <&rpmhcc RPMH_CXO_CLK>;
103+ clock-names = "iface", "bi_tcxo";
104+ power-domains = <&lpass_hm LPASS_CORE_HM_GDSCR>;
105+ #clock-cells = <1>;
106+ #power-domain-cells = <1>;
107+ };
108+...
Documentation/devicetree/bindings/clock/rockchip,rk3288-cru.txt+7−1
@@ -4,9 +4,15 @@ The RK3288 clock controller generates and supplies clock to various · 3 unmodified lines
44 controllers within the SoC and also implements a reset controller for SoC
55 peripherals.
66
7+A revision of this SoC is available: rk3288w. The clock tree is a bit
8+different so another dt-compatible is available. Noticed that it is only
9+setting the difference but there is no automatic revision detection. This
10+should be performed by bootloaders.
11+
712 Required Properties:
813
9−- compatible: should be "rockchip,rk3288-cru"
14+- compatible: should be "rockchip,rk3288-cru" or "rockchip,rk3288w-cru" in
15+ case of this revision of Rockchip rk3288.
1016 - reg: physical base address of the controller and length of memory mapped
1117 region.
1218 - #clock-cells: should be 1.
MAINTAINERS+3−1
@@ -1540,6 +1540,7 @@ F: drivers/mmc/host/owl-mmc.c · 1539 unmodified lines
15401540 F: drivers/pinctrl/actions/*
15411541 F: drivers/soc/actions/
15421542 F: include/dt-bindings/power/owl-*
1543+F: include/dt-bindings/reset/actions,*
15431544 F: include/linux/soc/actions/
15441545 N: owl
15451546
@@ -8409,8 +8410,9 @@ W: https://github.com/o2genum/ideapad-slidebar · 6863 unmodified lines
84098410 F: drivers/input/misc/ideapad_slidebar.c
84108411
84118412 IDT VersaClock 5 CLOCK DRIVER
8412−M: Marek Vasut <marek.vasut@gmail.com>
8413+M: Luca Ceresoli <luca@lucaceresoli.net>
84138414 S: Maintained
8415+F: Documentation/devicetree/bindings/clock/idt,versaclock5.yaml
84148416 F: drivers/clk/clk-versaclock5.c
84158417
84168418 IEEE 802.15.4 SUBSYSTEM
drivers/clk/Kconfig+1−1
@@ -50,7 +50,7 @@ source "drivers/clk/versatile/Kconfig" · 49 unmodified lines
5050 config CLK_HSDK
5151 bool "PLL Driver for HSDK platform"
5252 depends on OF || COMPILE_TEST
53− depends on IOMEM
53+ depends on HAS_IOMEM
5454 help
5555 This driver supports the HSDK core, system, ddr, tunnel and hdmi PLLs
5656 control.
drivers/clk/Makefile+1−0
@@ -28,6 +28,7 @@ obj-$(CONFIG_COMMON_CLK_CDCE925) += clk-cdce925.o · 27 unmodified lines
2828 obj-$(CONFIG_ARCH_CLPS711X) += clk-clps711x.o
2929 obj-$(CONFIG_COMMON_CLK_CS2000_CP) += clk-cs2000-cp.o
3030 obj-$(CONFIG_ARCH_EFM32) += clk-efm32gg.o
31+obj-$(CONFIG_ARCH_SPARX5) += clk-sparx5.o
3132 obj-$(CONFIG_COMMON_CLK_FIXED_MMIO) += clk-fixed-mmio.o
3233 obj-$(CONFIG_COMMON_CLK_FSL_SAI) += clk-fsl-sai.o
3334 obj-$(CONFIG_COMMON_CLK_GEMINI) += clk-gemini.o
drivers/clk/actions/owl-s500.c+88−1
@@ -23,8 +23,10 @@ · 22 unmodified lines
2323 #include "owl-gate.h"
2424 #include "owl-mux.h"
2525 #include "owl-pll.h"
26+#include "owl-reset.h"
2627
2728 #include <dt-bindings/clock/actions,s500-cmu.h>
29+#include <dt-bindings/reset/actions,s500-reset.h>
2830
2931 #define CMU_COREPLL (0x0000)
3032 #define CMU_DEVPLL (0x0004)
@@ -175,6 +177,8 @@ static OWL_MUX(dev_clk, "dev_clk", dev_clk_mux_p, CMU_DEVPLL, 12, 1, CLK_SET_RAT · 144 unmodified lines
175177 static OWL_MUX(ahbprediv_clk, "ahbprediv_clk", ahbprediv_clk_mux_p, CMU_BUSCLK1, 8, 3, CLK_SET_RATE_PARENT);
176178
177179 /* gate clocks */
180+static OWL_GATE(gpio_clk, "gpio_clk", "apb_clk", CMU_DEVCLKEN0, 18, 0, 0);
181+static OWL_GATE(dmac_clk, "dmac_clk", "h_clk", CMU_DEVCLKEN0, 1, 0, 0);
178182 static OWL_GATE(spi0_clk, "spi0_clk", "ahb_clk", CMU_DEVCLKEN1, 10, 0, CLK_IGNORE_UNUSED);
179183 static OWL_GATE(spi1_clk, "spi1_clk", "ahb_clk", CMU_DEVCLKEN1, 11, 0, CLK_IGNORE_UNUSED);
180184 static OWL_GATE(spi2_clk, "spi2_clk", "ahb_clk", CMU_DEVCLKEN1, 12, 0, CLK_IGNORE_UNUSED);
@@ -183,7 +187,8 @@ static OWL_GATE(timer_clk, "timer_clk", "hosc", CMU_DEVCLKEN1, 27, 0, 0); · 2 unmodified lines
183187 static OWL_GATE(hdmi_clk, "hdmi_clk", "hosc", CMU_DEVCLKEN1, 3, 0, 0);
184188
185189 /* divider clocks */
186−static OWL_DIVIDER(h_clk, "h_clk", "ahbprevdiv_clk", CMU_BUSCLK1, 12, 2, NULL, 0, 0);
190+static OWL_DIVIDER(h_clk, "h_clk", "ahbprediv_clk", CMU_BUSCLK1, 12, 2, NULL, 0, 0);
191+static OWL_DIVIDER(apb_clk, "apb_clk", "ahb_clk", CMU_BUSCLK1, 14, 2, NULL, 0, 0);
187192 static OWL_DIVIDER(rmii_ref_clk, "rmii_ref_clk", "ethernet_pll_clk", CMU_ETHERNETPLL, 1, 1, rmii_ref_div_table, 0, 0);
188193
189194 /* factor clocks */
@@ -428,6 +433,9 @@ static struct owl_clk_common *s500_clks[] = { · 238 unmodified lines
428433 &spdif_clk.common,
429434 &nand_clk.common,
430435 &ecc_clk.common,
436+ &apb_clk.common,
437+ &dmac_clk.common,
438+ &gpio_clk.common,
431439 };
432440
433441 static struct clk_hw_onecell_data s500_hw_clks = {
@@ -484,24 +492,103 @@ static struct clk_hw_onecell_data s500_hw_clks = { · 50 unmodified lines
484492 [CLK_SPDIF] = &spdif_clk.common.hw,
485493 [CLK_NAND] = &nand_clk.common.hw,
486494 [CLK_ECC] = &ecc_clk.common.hw,
495+ [CLK_APB] = &apb_clk.common.hw,
496+ [CLK_DMAC] = &dmac_clk.common.hw,
497+ [CLK_GPIO] = &gpio_clk.common.hw,
487498 },
488499 .num = CLK_NR_CLKS,
489500 };
490501
502+static const struct owl_reset_map s500_resets[] = {
503+ [RESET_DMAC] = { CMU_DEVRST0, BIT(0) },
504+ [RESET_NORIF] = { CMU_DEVRST0, BIT(1) },
505+ [RESET_DDR] = { CMU_DEVRST0, BIT(2) },
506+ [RESET_NANDC] = { CMU_DEVRST0, BIT(3) },
507+ [RESET_SD0] = { CMU_DEVRST0, BIT(4) },
508+ [RESET_SD1] = { CMU_DEVRST0, BIT(5) },
509+ [RESET_PCM1] = { CMU_DEVRST0, BIT(6) },
510+ [RESET_DE] = { CMU_DEVRST0, BIT(7) },
511+ [RESET_LCD] = { CMU_DEVRST0, BIT(8) },
512+ [RESET_SD2] = { CMU_DEVRST0, BIT(9) },
513+ [RESET_DSI] = { CMU_DEVRST0, BIT(10) },
514+ [RESET_CSI] = { CMU_DEVRST0, BIT(11) },
515+ [RESET_BISP] = { CMU_DEVRST0, BIT(12) },
516+ [RESET_KEY] = { CMU_DEVRST0, BIT(14) },
517+ [RESET_GPIO] = { CMU_DEVRST0, BIT(15) },
518+ [RESET_AUDIO] = { CMU_DEVRST0, BIT(17) },
519+ [RESET_PCM0] = { CMU_DEVRST0, BIT(18) },
520+ [RESET_VDE] = { CMU_DEVRST0, BIT(19) },
521+ [RESET_VCE] = { CMU_DEVRST0, BIT(20) },
522+ [RESET_GPU3D] = { CMU_DEVRST0, BIT(22) },
523+ [RESET_NIC301] = { CMU_DEVRST0, BIT(23) },
524+ [RESET_LENS] = { CMU_DEVRST0, BIT(26) },
525+ [RESET_PERIPHRESET] = { CMU_DEVRST0, BIT(27) },
526+ [RESET_USB2_0] = { CMU_DEVRST1, BIT(0) },
527+ [RESET_TVOUT] = { CMU_DEVRST1, BIT(1) },
528+ [RESET_HDMI] = { CMU_DEVRST1, BIT(2) },
529+ [RESET_HDCP2TX] = { CMU_DEVRST1, BIT(3) },
530+ [RESET_UART6] = { CMU_DEVRST1, BIT(4) },
531+ [RESET_UART0] = { CMU_DEVRST1, BIT(5) },
532+ [RESET_UART1] = { CMU_DEVRST1, BIT(6) },
533+ [RESET_UART2] = { CMU_DEVRST1, BIT(7) },
534+ [RESET_SPI0] = { CMU_DEVRST1, BIT(8) },
535+ [RESET_SPI1] = { CMU_DEVRST1, BIT(9) },
536+ [RESET_SPI2] = { CMU_DEVRST1, BIT(10) },
537+ [RESET_SPI3] = { CMU_DEVRST1, BIT(11) },
538+ [RESET_I2C0] = { CMU_DEVRST1, BIT(12) },
539+ [RESET_I2C1] = { CMU_DEVRST1, BIT(13) },
540+ [RESET_USB3] = { CMU_DEVRST1, BIT(14) },
541+ [RESET_UART3] = { CMU_DEVRST1, BIT(15) },
542+ [RESET_UART4] = { CMU_DEVRST1, BIT(16) },
543+ [RESET_UART5] = { CMU_DEVRST1, BIT(17) },
544+ [RESET_I2C2] = { CMU_DEVRST1, BIT(18) },
545+ [RESET_I2C3] = { CMU_DEVRST1, BIT(19) },
546+ [RESET_ETHERNET] = { CMU_DEVRST1, BIT(20) },
547+ [RESET_CHIPID] = { CMU_DEVRST1, BIT(21) },
548+ [RESET_USB2_1] = { CMU_DEVRST1, BIT(22) },
549+ [RESET_WD0RESET] = { CMU_DEVRST1, BIT(24) },
550+ [RESET_WD1RESET] = { CMU_DEVRST1, BIT(25) },
551+ [RESET_WD2RESET] = { CMU_DEVRST1, BIT(26) },
552+ [RESET_WD3RESET] = { CMU_DEVRST1, BIT(27) },
553+ [RESET_DBG0RESET] = { CMU_DEVRST1, BIT(28) },
554+ [RESET_DBG1RESET] = { CMU_DEVRST1, BIT(29) },
555+ [RESET_DBG2RESET] = { CMU_DEVRST1, BIT(30) },
556+ [RESET_DBG3RESET] = { CMU_DEVRST1, BIT(31) },
557+};
558+
491559 static struct owl_clk_desc s500_clk_desc = {
492560 .clks = s500_clks,
493561 .num_clks = ARRAY_SIZE(s500_clks),
494562
495563 .hw_clks = &s500_hw_clks,
564+
565+ .resets = s500_resets,
566+ .num_resets = ARRAY_SIZE(s500_resets),
496567 };
497568
498569 static int s500_clk_probe(struct platform_device *pdev)
499570 {
500571 struct owl_clk_desc *desc;
572+ struct owl_reset *reset;
573+ int ret;
501574
502575 desc = &s500_clk_desc;
503576 owl_clk_regmap_init(pdev, desc);
504577
578+ reset = devm_kzalloc(&pdev->dev, sizeof(*reset), GFP_KERNEL);
579+ if (!reset)
580+ return -ENOMEM;
581+
582+ reset->rcdev.of_node = pdev->dev.of_node;
583+ reset->rcdev.ops = &owl_reset_ops;
584+ reset->rcdev.nr_resets = desc->num_resets;
585+ reset->reset_map = desc->resets;
586+ reset->regmap = desc->regmap;
587+
588+ ret = devm_reset_controller_register(&pdev->dev, &reset->rcdev);
589+ if (ret)
590+ dev_err(&pdev->dev, "Failed to register reset controller\n");
591+
505592 return owl_clk_probe(&pdev->dev, desc->hw_clks);
506593 }
507594
drivers/clk/at91/Makefile+1−0
@@ -23,3 +23,4 @@ obj-$(CONFIG_SOC_SAM9X60) += sam9x60.o · 22 unmodified lines
2323 obj-$(CONFIG_SOC_SAMA5D3) += sama5d3.o
2424 obj-$(CONFIG_SOC_SAMA5D4) += sama5d4.o
2525 obj-$(CONFIG_SOC_SAMA5D2) += sama5d2.o
26+obj-$(CONFIG_SOC_SAMA7G5) += sama7g5.o
drivers/clk/at91/at91rm9200.c+2−1
@@ -160,7 +160,8 @@ static void __init at91rm9200_pmc_setup(struct device_node *np) · 159 unmodified lines
160160
161161 hw = at91_clk_register_programmable(regmap, name,
162162 parent_names, 4, i,
163− &at91rm9200_programmable_layout);
163+ &at91rm9200_programmable_layout,
164+ NULL);
164165 if (IS_ERR(hw))
165166 goto err_free;
166167
drivers/clk/at91/at91sam9260.c+2−1
@@ -436,7 +436,8 @@ static void __init at91sam926x_pmc_setup(struct device_node *np, · 435 unmodified lines
436436
437437 hw = at91_clk_register_programmable(regmap, name,
438438 parent_names, 4, i,
439− &at91rm9200_programmable_layout);
439+ &at91rm9200_programmable_layout,
440+ NULL);
440441 if (IS_ERR(hw))
441442 goto err_free;
442443
drivers/clk/at91/at91sam9g45.c+3−2
@@ -111,7 +111,7 @@ static void __init at91sam9g45_pmc_setup(struct device_node *np) · 110 unmodified lines
111111 return;
112112 mainxtal_name = of_clk_get_parent_name(np, i);
113113
114− regmap = syscon_node_to_regmap(np);
114+ regmap = device_node_to_regmap(np);
115115 if (IS_ERR(regmap))
116116 return;
117117
@@ -181,7 +181,8 @@ static void __init at91sam9g45_pmc_setup(struct device_node *np) · 63 unmodified lines
181181
182182 hw = at91_clk_register_programmable(regmap, name,
183183 parent_names, 5, i,
184− &at91sam9g45_programmable_layout);
184+ &at91sam9g45_programmable_layout,
185+ NULL);
185186 if (IS_ERR(hw))
186187 goto err_free;
187188
drivers/clk/at91/at91sam9n12.c+4−3
@@ -124,7 +124,7 @@ static void __init at91sam9n12_pmc_setup(struct device_node *np) · 123 unmodified lines
124124 return;
125125 mainxtal_name = of_clk_get_parent_name(np, i);
126126
127− regmap = syscon_node_to_regmap(np);
127+ regmap = device_node_to_regmap(np);
128128 if (IS_ERR(regmap))
129129 return;
130130
@@ -199,7 +199,8 @@ static void __init at91sam9n12_pmc_setup(struct device_node *np) · 68 unmodified lines
199199
200200 hw = at91_clk_register_programmable(regmap, name,
201201 parent_names, 5, i,
202− &at91sam9x5_programmable_layout);
202+ &at91sam9x5_programmable_layout,
203+ NULL);
203204 if (IS_ERR(hw))
204205 goto err_free;
205206
@@ -222,7 +223,7 @@ static void __init at91sam9n12_pmc_setup(struct device_node *np) · 16 unmodified lines
222223 at91sam9n12_periphck[i].n,
223224 "masterck",
224225 at91sam9n12_periphck[i].id,
225− &range);
226+ &range, INT_MIN);
226227 if (IS_ERR(hw))
227228 goto err_free;
228229
drivers/clk/at91/at91sam9rl.c+2−1
@@ -137,7 +137,8 @@ static void __init at91sam9rl_pmc_setup(struct device_node *np) · 136 unmodified lines
137137
138138 hw = at91_clk_register_programmable(regmap, name,
139139 parent_names, 5, i,
140− &at91rm9200_programmable_layout);
140+ &at91rm9200_programmable_layout,
141+ NULL);
141142 if (IS_ERR(hw))
142143 goto err_free;
143144
drivers/clk/at91/at91sam9x5.c+4−3
@@ -226,7 +226,8 @@ static void __init at91sam9x5_pmc_setup(struct device_node *np, · 225 unmodified lines
226226
227227 hw = at91_clk_register_programmable(regmap, name,
228228 parent_names, 5, i,
229− &at91sam9x5_programmable_layout);
229+ &at91sam9x5_programmable_layout,
230+ NULL);
230231 if (IS_ERR(hw))
231232 goto err_free;
232233
@@ -257,7 +258,7 @@ static void __init at91sam9x5_pmc_setup(struct device_node *np, · 24 unmodified lines
257258 at91sam9x5_periphck[i].n,
258259 "masterck",
259260 at91sam9x5_periphck[i].id,
260− &range);
261+ &range, INT_MIN);
261262 if (IS_ERR(hw))
262263 goto err_free;
263264
@@ -270,7 +271,7 @@ static void __init at91sam9x5_pmc_setup(struct device_node *np, · 6 unmodified lines
270271 extra_pcks[i].n,
271272 "masterck",
272273 extra_pcks[i].id,
273− &range);
274+ &range, INT_MIN);
274275 if (IS_ERR(hw))
275276 goto err_free;
276277
drivers/clk/at91/clk-generated.c+27−17
@@ -18,18 +18,17 @@ · 17 unmodified lines
1818
1919 #define GENERATED_MAX_DIV 255
2020
21−#define GCK_INDEX_DT_AUDIO_PLL 5
22−
2321 struct clk_generated {
2422 struct clk_hw hw;
2523 struct regmap *regmap;
2624 struct clk_range range;
2725 spinlock_t *lock;
26+ u32 *mux_table;
2827 u32 id;
2928 u32 gckdiv;
3029 const struct clk_pcr_layout *layout;
3130 u8 parent_id;
32− bool audio_pll_allowed;
31+ int chg_pid;
3332 };
3433
3534 #define to_clk_generated(hw) \
@@ -83,7 +82,7 @@ static int clk_generated_is_enabled(struct clk_hw *hw) · 47 unmodified lines
8382 regmap_read(gck->regmap, gck->layout->offset, &status);
8483 spin_unlock_irqrestore(gck->lock, flags);
8584
86− return status & AT91_PMC_PCR_GCKEN ? 1 : 0;
85+ return !!(status & AT91_PMC_PCR_GCKEN);
8786 }
8887
8988 static unsigned long
@@ -109,7 +108,7 @@ static void clk_generated_best_diff(struct clk_rate_request *req, · 19 unmodified lines
109108 tmp_rate = parent_rate / div;
110109 tmp_diff = abs(req->rate - tmp_rate);
111110
112− if (*best_diff < 0 || *best_diff > tmp_diff) {
111+ if (*best_diff < 0 || *best_diff >= tmp_diff) {
113112 *best_rate = tmp_rate;
114113 *best_diff = tmp_diff;
115114 req->best_parent_rate = parent_rate;
@@ -129,7 +128,10 @@ static int clk_generated_determine_rate(struct clk_hw *hw, · 13 unmodified lines
129128 int i;
130129 u32 div;
131130
132− for (i = 0; i < clk_hw_get_num_parents(hw) - 1; i++) {
131+ for (i = 0; i < clk_hw_get_num_parents(hw); i++) {
132+ if (gck->chg_pid == i)
133+ continue;
134+
133135 parent = clk_hw_get_parent_by_index(hw, i);
134136 if (!parent)
135137 continue;
@@ -161,16 +163,17 @@ static int clk_generated_determine_rate(struct clk_hw *hw, · 25 unmodified lines
161163 * that the only clks able to modify gck rate are those of audio IPs.
162164 */
163165
164− if (!gck->audio_pll_allowed)
166+ if (gck->chg_pid < 0)
165167 goto end;
166168
167− parent = clk_hw_get_parent_by_index(hw, GCK_INDEX_DT_AUDIO_PLL);
169+ parent = clk_hw_get_parent_by_index(hw, gck->chg_pid);
168170 if (!parent)
169171 goto end;
170172
171173 for (div = 1; div < GENERATED_MAX_DIV + 2; div++) {
172174 req_parent.rate = req->rate * div;
173− __clk_determine_rate(parent, &req_parent);
175+ if (__clk_determine_rate(parent, &req_parent))
176+ continue;
174177 clk_generated_best_diff(req, parent, req_parent.rate, div,
175178 &best_diff, &best_rate);
176179
@@ -184,8 +187,8 @@ end: · 7 unmodified lines
184187 __clk_get_name((req->best_parent_hw)->clk),
185188 req->best_parent_rate);
186189
187− if (best_rate < 0)
188− return best_rate;
190+ if (best_rate < 0 || (gck->range.max && best_rate > gck->range.max))
191+ return -EINVAL;
189192
190193 req->rate = best_rate;
191194 return 0;
@@ -199,7 +202,11 @@ static int clk_generated_set_parent(struct clk_hw *hw, u8 index) · 7 unmodified lines
199202 if (index >= clk_hw_get_num_parents(hw))
200203 return -EINVAL;
201204
202− gck->parent_id = index;
205+ if (gck->mux_table)
206+ gck->parent_id = clk_mux_index_to_val(gck->mux_table, 0, index);
207+ else
208+ gck->parent_id = index;
209+
203210 return 0;
204211 }
205212
@@ -271,8 +278,9 @@ struct clk_hw * __init · 65 unmodified lines
271278 at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock,
272279 const struct clk_pcr_layout *layout,
273280 const char *name, const char **parent_names,
274− u8 num_parents, u8 id, bool pll_audio,
275− const struct clk_range *range)
281+ u32 *mux_table, u8 num_parents, u8 id,
282+ const struct clk_range *range,
283+ int chg_pid)
276284 {
277285 struct clk_generated *gck;
278286 struct clk_init_data init;
@@ -287,16 +295,18 @@ at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock, · 8 unmodified lines
287295 init.ops = &generated_ops;
288296 init.parent_names = parent_names;
289297 init.num_parents = num_parents;
290− init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
291− CLK_SET_RATE_PARENT;
298+ init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE;
299+ if (chg_pid >= 0)
300+ init.flags |= CLK_SET_RATE_PARENT;
292301
293302 gck->id = id;
294303 gck->hw.init = &init;
295304 gck->regmap = regmap;
296305 gck->lock = lock;
297306 gck->range = *range;
298− gck->audio_pll_allowed = pll_audio;
307+ gck->chg_pid = chg_pid;
299308 gck->layout = layout;
309+ gck->mux_table = mux_table;
300310
301311 clk_generated_startup(gck);
302312 hw = &gck->hw;
drivers/clk/at91/clk-main.c+3−3
@@ -175,7 +175,7 @@ static bool clk_main_rc_osc_ready(struct regmap *regmap) · 174 unmodified lines
175175
176176 regmap_read(regmap, AT91_PMC_SR, &status);
177177
178− return status & AT91_PMC_MOSCRCS;
178+ return !!(status & AT91_PMC_MOSCRCS);
179179 }
180180
181181 static int clk_main_rc_osc_prepare(struct clk_hw *hw)
@@ -336,7 +336,7 @@ static int clk_rm9200_main_is_prepared(struct clk_hw *hw) · 154 unmodified lines
336336
337337 regmap_read(clkmain->regmap, AT91_CKGR_MCFR, &status);
338338
339− return status & AT91_PMC_MAINRDY ? 1 : 0;
339+ return !!(status & AT91_PMC_MAINRDY);
340340 }
341341
342342 static unsigned long clk_rm9200_main_recalc_rate(struct clk_hw *hw,
@@ -398,7 +398,7 @@ static inline bool clk_sam9x5_main_ready(struct regmap *regmap) · 55 unmodified lines
398398
399399 regmap_read(regmap, AT91_PMC_SR, &status);
400400
401− return status & AT91_PMC_MOSCSELS ? 1 : 0;
401+ return !!(status & AT91_PMC_MOSCSELS);
402402 }
403403
404404 static int clk_sam9x5_main_prepare(struct clk_hw *hw)
drivers/clk/at91/clk-master.c+305−5
@@ -17,30 +17,49 @@ · 16 unmodified lines
1717 #define MASTER_DIV_SHIFT 8
1818 #define MASTER_DIV_MASK 0x3
1919
20+#define PMC_MCR 0x30
21+#define PMC_MCR_ID_MSK GENMASK(3, 0)
22+#define PMC_MCR_CMD BIT(7)
23+#define PMC_MCR_DIV GENMASK(10, 8)
24+#define PMC_MCR_CSS GENMASK(20, 16)
25+#define PMC_MCR_CSS_SHIFT (16)
26+#define PMC_MCR_EN BIT(28)
27+
28+#define PMC_MCR_ID(x) ((x) & PMC_MCR_ID_MSK)
29+
30+#define MASTER_MAX_ID 4
31+
2032 #define to_clk_master(hw) container_of(hw, struct clk_master, hw)
2133
2234 struct clk_master {
2335 struct clk_hw hw;
2436 struct regmap *regmap;
37+ spinlock_t *lock;
2538 const struct clk_master_layout *layout;
2639 const struct clk_master_characteristics *characteristics;
40+ u32 *mux_table;
2741 u32 mckr;
42+ int chg_pid;
43+ u8 id;
44+ u8 parent;
45+ u8 div;
2846 };
2947
30−static inline bool clk_master_ready(struct regmap *regmap)
48+static inline bool clk_master_ready(struct clk_master *master)
3149 {
50+ unsigned int bit = master->id ? AT91_PMC_MCKXRDY : AT91_PMC_MCKRDY;
3251 unsigned int status;
3352
34− regmap_read(regmap, AT91_PMC_SR, &status);
53+ regmap_read(master->regmap, AT91_PMC_SR, &status);
3554
36− return status & AT91_PMC_MCKRDY ? 1 : 0;
55+ return !!(status & bit);
3756 }
3857
3958 static int clk_master_prepare(struct clk_hw *hw)
4059 {
4160 struct clk_master *master = to_clk_master(hw);
4261
43− while (!clk_master_ready(master->regmap))
62+ while (!clk_master_ready(master))
4463 cpu_relax();
4564
4665 return 0;
@@ -50,7 +69,7 @@ static int clk_master_is_prepared(struct clk_hw *hw) · 3 unmodified lines
5069 {
5170 struct clk_master *master = to_clk_master(hw);
5271
53− return clk_master_ready(master->regmap);
72+ return clk_master_ready(master);
5473 }
5574
5675 static unsigned long clk_master_recalc_rate(struct clk_hw *hw,
@@ -143,6 +162,287 @@ at91_clk_register_master(struct regmap *regmap, · 86 unmodified lines
143162 return hw;
144163 }
145164
165+static unsigned long
166+clk_sama7g5_master_recalc_rate(struct clk_hw *hw,
167+ unsigned long parent_rate)
168+{
169+ struct clk_master *master = to_clk_master(hw);
170+
171+ return DIV_ROUND_CLOSEST_ULL(parent_rate, (1 << master->div));
172+}
173+
174+static void clk_sama7g5_master_best_diff(struct clk_rate_request *req,
175+ struct clk_hw *parent,
176+ unsigned long parent_rate,
177+ long *best_rate,
178+ long *best_diff,
179+ u32 div)
180+{
181+ unsigned long tmp_rate, tmp_diff;
182+
183+ if (div == MASTER_PRES_MAX)
184+ tmp_rate = parent_rate / 3;
185+ else
186+ tmp_rate = parent_rate >> div;
187+
188+ tmp_diff = abs(req->rate - tmp_rate);
189+
190+ if (*best_diff < 0 || *best_diff >= tmp_diff) {
191+ *best_rate = tmp_rate;
192+ *best_diff = tmp_diff;
193+ req->best_parent_rate = parent_rate;
194+ req->best_parent_hw = parent;
195+ }
196+}
197+
198+static int clk_sama7g5_master_determine_rate(struct clk_hw *hw,
199+ struct clk_rate_request *req)
200+{
201+ struct clk_master *master = to_clk_master(hw);
202+ struct clk_rate_request req_parent = *req;
203+ struct clk_hw *parent;
204+ long best_rate = LONG_MIN, best_diff = LONG_MIN;
205+ unsigned long parent_rate;
206+ unsigned int div, i;
207+
208+ /* First: check the dividers of MCR. */
209+ for (i = 0; i < clk_hw_get_num_parents(hw); i++) {
210+ parent = clk_hw_get_parent_by_index(hw, i);
211+ if (!parent)
212+ continue;
213+
214+ parent_rate = clk_hw_get_rate(parent);
215+ if (!parent_rate)
216+ continue;
217+
218+ for (div = 0; div < MASTER_PRES_MAX + 1; div++) {
219+ clk_sama7g5_master_best_diff(req, parent, parent_rate,
220+ &best_rate, &best_diff,
221+ div);
222+ if (!best_diff)
223+ break;
224+ }
225+
226+ if (!best_diff)
227+ break;
228+ }
229+
230+ /* Second: try to request rate form changeable parent. */
231+ if (master->chg_pid < 0)
232+ goto end;
233+
234+ parent = clk_hw_get_parent_by_index(hw, master->chg_pid);
235+ if (!parent)
236+ goto end;
237+
238+ for (div = 0; div < MASTER_PRES_MAX + 1; div++) {
239+ if (div == MASTER_PRES_MAX)
240+ req_parent.rate = req->rate * 3;
241+ else
242+ req_parent.rate = req->rate << div;
243+
244+ if (__clk_determine_rate(parent, &req_parent))
245+ continue;
246+
247+ clk_sama7g5_master_best_diff(req, parent, req_parent.rate,
248+ &best_rate, &best_diff, div);
249+
250+ if (!best_diff)
251+ break;
252+ }
253+
254+end:
255+ pr_debug("MCK: %s, best_rate = %ld, parent clk: %s @ %ld\n",
256+ __func__, best_rate,
257+ __clk_get_name((req->best_parent_hw)->clk),
258+ req->best_parent_rate);
259+
260+ if (best_rate < 0)
261+ return -EINVAL;
262+
263+ req->rate = best_rate;
264+
265+ return 0;
266+}
267+
268+static u8 clk_sama7g5_master_get_parent(struct clk_hw *hw)
269+{
270+ struct clk_master *master = to_clk_master(hw);
271+ unsigned long flags;
272+ u8 index;
273+
274+ spin_lock_irqsave(master->lock, flags);
275+ index = clk_mux_val_to_index(&master->hw, master->mux_table, 0,
276+ master->parent);
277+ spin_unlock_irqrestore(master->lock, flags);
278+
279+ return index;
280+}
281+
282+static int clk_sama7g5_master_set_parent(struct clk_hw *hw, u8 index)
283+{
284+ struct clk_master *master = to_clk_master(hw);
285+ unsigned long flags;
286+
287+ if (index >= clk_hw_get_num_parents(hw))
288+ return -EINVAL;
289+
290+ spin_lock_irqsave(master->lock, flags);
291+ master->parent = clk_mux_index_to_val(master->mux_table, 0, index);
292+ spin_unlock_irqrestore(master->lock, flags);
293+
294+ return 0;
295+}
296+
297+static int clk_sama7g5_master_enable(struct clk_hw *hw)
298+{
299+ struct clk_master *master = to_clk_master(hw);
300+ unsigned long flags;
301+ unsigned int val, cparent;
302+
303+ spin_lock_irqsave(master->lock, flags);
304+
305+ regmap_write(master->regmap, PMC_MCR, PMC_MCR_ID(master->id));
306+ regmap_read(master->regmap, PMC_MCR, &val);
307+ regmap_update_bits(master->regmap, PMC_MCR,
308+ PMC_MCR_EN | PMC_MCR_CSS | PMC_MCR_DIV |
309+ PMC_MCR_CMD | PMC_MCR_ID_MSK,
310+ PMC_MCR_EN | (master->parent << PMC_MCR_CSS_SHIFT) |
311+ (master->div << MASTER_DIV_SHIFT) |
312+ PMC_MCR_CMD | PMC_MCR_ID(master->id));
313+
314+ cparent = (val & PMC_MCR_CSS) >> PMC_MCR_CSS_SHIFT;
315+
316+ /* Wait here only if parent is being changed. */
317+ while ((cparent != master->parent) && !clk_master_ready(master))
318+ cpu_relax();
319+
320+ spin_unlock_irqrestore(master->lock, flags);
321+
322+ return 0;
323+}
324+
325+static void clk_sama7g5_master_disable(struct clk_hw *hw)
326+{
327+ struct clk_master *master = to_clk_master(hw);
328+ unsigned long flags;
329+
330+ spin_lock_irqsave(master->lock, flags);
331+
332+ regmap_write(master->regmap, PMC_MCR, master->id);
333+ regmap_update_bits(master->regmap, PMC_MCR,
334+ PMC_MCR_EN | PMC_MCR_CMD | PMC_MCR_ID_MSK,
335+ PMC_MCR_CMD | PMC_MCR_ID(master->id));
336+
337+ spin_unlock_irqrestore(master->lock, flags);
338+}
339+
340+static int clk_sama7g5_master_is_enabled(struct clk_hw *hw)
341+{
342+ struct clk_master *master = to_clk_master(hw);
343+ unsigned long flags;
344+ unsigned int val;
345+
346+ spin_lock_irqsave(master->lock, flags);
347+
348+ regmap_write(master->regmap, PMC_MCR, master->id);
349+ regmap_read(master->regmap, PMC_MCR, &val);
350+
351+ spin_unlock_irqrestore(master->lock, flags);
352+
353+ return !!(val & PMC_MCR_EN);
354+}
355+
356+static int clk_sama7g5_master_set_rate(struct clk_hw *hw, unsigned long rate,
357+ unsigned long parent_rate)
358+{
359+ struct clk_master *master = to_clk_master(hw);
360+ unsigned long div, flags;
361+
362+ div = DIV_ROUND_CLOSEST(parent_rate, rate);
363+ if ((div > (1 << (MASTER_PRES_MAX - 1))) || (div & (div - 1)))
364+ return -EINVAL;
365+
366+ if (div == 3)
367+ div = MASTER_PRES_MAX;
368+ else
369+ div = ffs(div) - 1;
370+
371+ spin_lock_irqsave(master->lock, flags);
372+ master->div = div;
373+ spin_unlock_irqrestore(master->lock, flags);
374+
375+ return 0;
376+}
377+
378+static const struct clk_ops sama7g5_master_ops = {
379+ .enable = clk_sama7g5_master_enable,
380+ .disable = clk_sama7g5_master_disable,
381+ .is_enabled = clk_sama7g5_master_is_enabled,
382+ .recalc_rate = clk_sama7g5_master_recalc_rate,
383+ .determine_rate = clk_sama7g5_master_determine_rate,
384+ .set_rate = clk_sama7g5_master_set_rate,
385+ .get_parent = clk_sama7g5_master_get_parent,
386+ .set_parent = clk_sama7g5_master_set_parent,
387+};
388+
389+struct clk_hw * __init
390+at91_clk_sama7g5_register_master(struct regmap *regmap,
391+ const char *name, int num_parents,
392+ const char **parent_names,
393+ u32 *mux_table,
394+ spinlock_t *lock, u8 id,
395+ bool critical, int chg_pid)
396+{
397+ struct clk_master *master;
398+ struct clk_hw *hw;
399+ struct clk_init_data init;
400+ unsigned long flags;
401+ unsigned int val;
402+ int ret;
403+
404+ if (!name || !num_parents || !parent_names || !mux_table ||
405+ !lock || id > MASTER_MAX_ID)
406+ return ERR_PTR(-EINVAL);
407+
408+ master = kzalloc(sizeof(*master), GFP_KERNEL);
409+ if (!master)
410+ return ERR_PTR(-ENOMEM);
411+
412+ init.name = name;
413+ init.ops = &sama7g5_master_ops;
414+ init.parent_names = parent_names;
415+ init.num_parents = num_parents;
416+ init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE;
417+ if (chg_pid >= 0)
418+ init.flags |= CLK_SET_RATE_PARENT;
419+ if (critical)
420+ init.flags |= CLK_IS_CRITICAL;
421+
422+ master->hw.init = &init;
423+ master->regmap = regmap;
424+ master->id = id;
425+ master->chg_pid = chg_pid;
426+ master->lock = lock;
427+ master->mux_table = mux_table;
428+
429+ spin_lock_irqsave(master->lock, flags);
430+ regmap_write(master->regmap, PMC_MCR, master->id);
431+ regmap_read(master->regmap, PMC_MCR, &val);
432+ master->parent = (val & PMC_MCR_CSS) >> PMC_MCR_CSS_SHIFT;
433+ master->div = (val & PMC_MCR_DIV) >> MASTER_DIV_SHIFT;
434+ spin_unlock_irqrestore(master->lock, flags);
435+
436+ hw = &master->hw;
437+ ret = clk_hw_register(NULL, &master->hw);
438+ if (ret) {
439+ kfree(master);
440+ hw = ERR_PTR(ret);
441+ }
442+
443+ return hw;
444+}
445+
146446 const struct clk_master_layout at91rm9200_master_layout = {
147447 .mask = 0x31F,
148448 .pres_shift = 2,
drivers/clk/at91/clk-peripheral.c+105−6
@@ -38,6 +38,7 @@ struct clk_sam9x5_peripheral { · 37 unmodified lines
3838 u32 div;
3939 const struct clk_pcr_layout *layout;
4040 bool auto_div;
41+ int chg_pid;
4142 };
4243
4344 #define to_clk_sam9x5_peripheral(hw) \
@@ -208,7 +209,7 @@ static int clk_sam9x5_peripheral_is_enabled(struct clk_hw *hw) · 164 unmodified lines
208209 regmap_read(periph->regmap, periph->layout->offset, &status);
209210 spin_unlock_irqrestore(periph->lock, flags);
210211
211− return status & AT91_PMC_PCR_EN ? 1 : 0;
212+ return !!(status & AT91_PMC_PCR_EN);
212213 }
213214
214215 static unsigned long
@@ -238,6 +239,87 @@ clk_sam9x5_peripheral_recalc_rate(struct clk_hw *hw, · 23 unmodified lines
238239 return parent_rate >> periph->div;
239240 }
240241
242+static void clk_sam9x5_peripheral_best_diff(struct clk_rate_request *req,
243+ struct clk_hw *parent,
244+ unsigned long parent_rate,
245+ u32 shift, long *best_diff,
246+ long *best_rate)
247+{
248+ unsigned long tmp_rate = parent_rate >> shift;
249+ unsigned long tmp_diff = abs(req->rate - tmp_rate);
250+
251+ if (*best_diff < 0 || *best_diff >= tmp_diff) {
252+ *best_rate = tmp_rate;
253+ *best_diff = tmp_diff;
254+ req->best_parent_rate = parent_rate;
255+ req->best_parent_hw = parent;
256+ }
257+}
258+
259+static int clk_sam9x5_peripheral_determine_rate(struct clk_hw *hw,
260+ struct clk_rate_request *req)
261+{
262+ struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw);
263+ struct clk_hw *parent = clk_hw_get_parent(hw);
264+ struct clk_rate_request req_parent = *req;
265+ unsigned long parent_rate = clk_hw_get_rate(parent);
266+ unsigned long tmp_rate;
267+ long best_rate = LONG_MIN;
268+ long best_diff = LONG_MIN;
269+ u32 shift;
270+
271+ if (periph->id < PERIPHERAL_ID_MIN || !periph->range.max)
272+ return parent_rate;
273+
274+ /* Fist step: check the available dividers. */
275+ for (shift = 0; shift <= PERIPHERAL_MAX_SHIFT; shift++) {
276+ tmp_rate = parent_rate >> shift;
277+
278+ if (periph->range.max && tmp_rate > periph->range.max)
279+ continue;
280+
281+ clk_sam9x5_peripheral_best_diff(req, parent, parent_rate,
282+ shift, &best_diff, &best_rate);
283+
284+ if (!best_diff || best_rate <= req->rate)
285+ break;
286+ }
287+
288+ if (periph->chg_pid < 0)
289+ goto end;
290+
291+ /* Step two: try to request rate from parent. */
292+ parent = clk_hw_get_parent_by_index(hw, periph->chg_pid);
293+ if (!parent)
294+ goto end;
295+
296+ for (shift = 0; shift <= PERIPHERAL_MAX_SHIFT; shift++) {
297+ req_parent.rate = req->rate << shift;
298+
299+ if (__clk_determine_rate(parent, &req_parent))
300+ continue;
301+
302+ clk_sam9x5_peripheral_best_diff(req, parent, req_parent.rate,
303+ shift, &best_diff, &best_rate);
304+
305+ if (!best_diff)
306+ break;
307+ }
308+end:
309+ if (best_rate < 0 ||
310+ (periph->range.max && best_rate > periph->range.max))
311+ return -EINVAL;
312+
313+ pr_debug("PCK: %s, best_rate = %ld, parent clk: %s @ %ld\n",
314+ __func__, best_rate,
315+ __clk_get_name((req->best_parent_hw)->clk),
316+ req->best_parent_rate);
317+
318+ req->rate = best_rate;
319+
320+ return 0;
321+}
322+
241323 static long clk_sam9x5_peripheral_round_rate(struct clk_hw *hw,
242324 unsigned long rate,
243325 unsigned long *parent_rate)
@@ -320,11 +402,21 @@ static const struct clk_ops sam9x5_peripheral_ops = { · 76 unmodified lines
320402 .set_rate = clk_sam9x5_peripheral_set_rate,
321403 };
322404
405+static const struct clk_ops sam9x5_peripheral_chg_ops = {
406+ .enable = clk_sam9x5_peripheral_enable,
407+ .disable = clk_sam9x5_peripheral_disable,
408+ .is_enabled = clk_sam9x5_peripheral_is_enabled,
409+ .recalc_rate = clk_sam9x5_peripheral_recalc_rate,
410+ .determine_rate = clk_sam9x5_peripheral_determine_rate,
411+ .set_rate = clk_sam9x5_peripheral_set_rate,
412+};
413+
323414 struct clk_hw * __init
324415 at91_clk_register_sam9x5_peripheral(struct regmap *regmap, spinlock_t *lock,
325416 const struct clk_pcr_layout *layout,
326417 const char *name, const char *parent_name,
327− u32 id, const struct clk_range *range)
418+ u32 id, const struct clk_range *range,
419+ int chg_pid)
328420 {
329421 struct clk_sam9x5_peripheral *periph;
330422 struct clk_init_data init;
@@ -339,10 +431,16 @@ at91_clk_register_sam9x5_peripheral(struct regmap *regmap, spinlock_t *lock, · 8 unmodified lines
339431 return ERR_PTR(-ENOMEM);
340432
341433 init.name = name;
342− init.ops = &sam9x5_peripheral_ops;
343− init.parent_names = (parent_name ? &parent_name : NULL);
344− init.num_parents = (parent_name ? 1 : 0);
345− init.flags = 0;
434+ init.parent_names = &parent_name;
435+ init.num_parents = 1;
436+ if (chg_pid < 0) {
437+ init.flags = 0;
438+ init.ops = &sam9x5_peripheral_ops;
439+ } else {
440+ init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
441+ CLK_SET_RATE_PARENT;
442+ init.ops = &sam9x5_peripheral_chg_ops;
443+ }
346444
347445 periph->id = id;
348446 periph->hw.init = &init;
@@ -353,6 +451,7 @@ at91_clk_register_sam9x5_peripheral(struct regmap *regmap, spinlock_t *lock, · 4 unmodified lines
353451 periph->auto_div = true;
354452 periph->layout = layout;
355453 periph->range = *range;
454+ periph->chg_pid = chg_pid;
356455
357456 hw = &periph->hw;
358457 ret = clk_hw_register(NULL, &periph->hw);
drivers/clk/at91/clk-programmable.c+10−1
@@ -21,6 +21,7 @@ · 20 unmodified lines
2121 struct clk_programmable {
2222 struct clk_hw hw;
2323 struct regmap *regmap;
24+ u32 *mux_table;
2425 u8 id;
2526 const struct clk_programmable_layout *layout;
2627 };
@@ -108,6 +109,9 @@ static int clk_programmable_set_parent(struct clk_hw *hw, u8 index) · 81 unmodified lines
108109 if (layout->have_slck_mck)
109110 mask |= AT91_PMC_CSSMCK_MCK;
110111
112+ if (prog->mux_table)
113+ pckr = clk_mux_index_to_val(prog->mux_table, 0, index);
114+
111115 if (index > layout->css_mask) {
112116 if (index > PROG_MAX_RM9200_CSS && !layout->have_slck_mck)
113117 return -EINVAL;
@@ -134,6 +138,9 @@ static u8 clk_programmable_get_parent(struct clk_hw *hw) · 20 unmodified lines
134138 if (layout->have_slck_mck && (pckr & AT91_PMC_CSSMCK_MCK) && !ret)
135139 ret = PROG_MAX_RM9200_CSS + 1;
136140
141+ if (prog->mux_table)
142+ ret = clk_mux_val_to_index(&prog->hw, prog->mux_table, 0, ret);
143+
137144 return ret;
138145 }
139146
@@ -182,7 +189,8 @@ struct clk_hw * __init · 42 unmodified lines
182189 at91_clk_register_programmable(struct regmap *regmap,
183190 const char *name, const char **parent_names,
184191 u8 num_parents, u8 id,
185− const struct clk_programmable_layout *layout)
192+ const struct clk_programmable_layout *layout,
193+ u32 *mux_table)
186194 {
187195 struct clk_programmable *prog;
188196 struct clk_hw *hw;
@@ -206,6 +214,7 @@ at91_clk_register_programmable(struct regmap *regmap, · 17 unmodified lines
206214 prog->layout = layout;
207215 prog->hw.init = &init;
208216 prog->regmap = regmap;
217+ prog->mux_table = mux_table;
209218
210219 hw = &prog->hw;
211220 ret = clk_hw_register(NULL, &prog->hw);
drivers/clk/at91/clk-sam9x60-pll.c+381−166
@@ -15,26 +15,41 @@ · 14 unmodified lines
1515 #include "pmc.h"
1616
1717 #define PMC_PLL_CTRL0_DIV_MSK GENMASK(7, 0)
18−#define PMC_PLL_CTRL1_MUL_MSK GENMASK(30, 24)
18+#define PMC_PLL_CTRL1_MUL_MSK GENMASK(31, 24)
19+#define PMC_PLL_CTRL1_FRACR_MSK GENMASK(21, 0)
1920
2021 #define PLL_DIV_MAX (FIELD_GET(PMC_PLL_CTRL0_DIV_MSK, UINT_MAX) + 1)
2122 #define UPLL_DIV 2
2223 #define PLL_MUL_MAX (FIELD_GET(PMC_PLL_CTRL1_MUL_MSK, UINT_MAX) + 1)
2324
24−#define PLL_MAX_ID 1
25+#define FCORE_MIN (600000000)
26+#define FCORE_MAX (1200000000)
2527
26−struct sam9x60_pll {
27− struct clk_hw hw;
28+#define PLL_MAX_ID 7
29+
30+struct sam9x60_pll_core {
2831 struct regmap *regmap;
2932 spinlock_t *lock;
3033 const struct clk_pll_characteristics *characteristics;
31− u32 frac;
34+ const struct clk_pll_layout *layout;
35+ struct clk_hw hw;
3236 u8 id;
33− u8 div;
37+};
38+
39+struct sam9x60_frac {
40+ struct sam9x60_pll_core core;
41+ u32 frac;
3442 u16 mul;
3543 };
3644
37−#define to_sam9x60_pll(hw) container_of(hw, struct sam9x60_pll, hw)
45+struct sam9x60_div {
46+ struct sam9x60_pll_core core;
47+ u8 div;
48+};
49+
50+#define to_sam9x60_pll_core(hw) container_of(hw, struct sam9x60_pll_core, hw)
51+#define to_sam9x60_frac(core) container_of(core, struct sam9x60_frac, core)
52+#define to_sam9x60_div(core) container_of(core, struct sam9x60_div, core)
3853
3954 static inline bool sam9x60_pll_ready(struct regmap *regmap, int id)
4055 {
@@ -45,41 +60,53 @@ static inline bool sam9x60_pll_ready(struct regmap *regmap, int id) · 4 unmodified lines
4560 return !!(status & BIT(id));
4661 }
4762
48−static int sam9x60_pll_prepare(struct clk_hw *hw)
63+static bool sam9x60_frac_pll_ready(struct regmap *regmap, u8 id)
4964 {
50− struct sam9x60_pll *pll = to_sam9x60_pll(hw);
51− struct regmap *regmap = pll->regmap;
52− unsigned long flags;
53− u8 div;
54− u16 mul;
55− u32 val;
65+ return sam9x60_pll_ready(regmap, id);
66+}
5667
57− spin_lock_irqsave(pll->lock, flags);
58− regmap_write(regmap, AT91_PMC_PLL_UPDT, pll->id);
68+static unsigned long sam9x60_frac_pll_recalc_rate(struct clk_hw *hw,
69+ unsigned long parent_rate)
70+{
71+ struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw);
72+ struct sam9x60_frac *frac = to_sam9x60_frac(core);
5973
60− regmap_read(regmap, AT91_PMC_PLL_CTRL0, &val);
61− div = FIELD_GET(PMC_PLL_CTRL0_DIV_MSK, val);
74+ return (parent_rate * (frac->mul + 1) +
75+ ((u64)parent_rate * frac->frac >> 22));
76+}
6277
78+static int sam9x60_frac_pll_prepare(struct clk_hw *hw)
79+{
80+ struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw);
81+ struct sam9x60_frac *frac = to_sam9x60_frac(core);
82+ struct regmap *regmap = core->regmap;
83+ unsigned int val, cfrac, cmul;
84+ unsigned long flags;
85+
86+ spin_lock_irqsave(core->lock, flags);
87+
88+ regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
89+ AT91_PMC_PLL_UPDT_ID_MSK, core->id);
6390 regmap_read(regmap, AT91_PMC_PLL_CTRL1, &val);
64− mul = FIELD_GET(PMC_PLL_CTRL1_MUL_MSK, val);
91+ cmul = (val & core->layout->mul_mask) >> core->layout->mul_shift;
92+ cfrac = (val & core->layout->frac_mask) >> core->layout->frac_shift;
6593
66− if (sam9x60_pll_ready(regmap, pll->id) &&
67− (div == pll->div && mul == pll->mul)) {
68− spin_unlock_irqrestore(pll->lock, flags);
69− return 0;
70− }
94+ if (sam9x60_frac_pll_ready(regmap, core->id) &&
95+ (cmul == frac->mul && cfrac == frac->frac))
96+ goto unlock;
7197
72− /* Recommended value for AT91_PMC_PLL_ACR */
73− if (pll->characteristics->upll)
98+ /* Recommended value for PMC_PLL_ACR */
99+ if (core->characteristics->upll)
74100 val = AT91_PMC_PLL_ACR_DEFAULT_UPLL;
75101 else
76102 val = AT91_PMC_PLL_ACR_DEFAULT_PLLA;
77103 regmap_write(regmap, AT91_PMC_PLL_ACR, val);
78104
79105 regmap_write(regmap, AT91_PMC_PLL_CTRL1,
80− FIELD_PREP(PMC_PLL_CTRL1_MUL_MSK, pll->mul));
106+ (frac->mul << core->layout->mul_shift) |
107+ (frac->frac << core->layout->frac_shift));
81108
82− if (pll->characteristics->upll) {
109+ if (core->characteristics->upll) {
83110 /* Enable the UTMI internal bandgap */
84111 val |= AT91_PMC_PLL_ACR_UTMIBG;
85112 regmap_write(regmap, AT91_PMC_PLL_ACR, val);
@@ -94,221 +121,409 @@ static int sam9x60_pll_prepare(struct clk_hw *hw) · 8 unmodified lines
94121 }
95122
96123 regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
97− AT91_PMC_PLL_UPDT_UPDATE, AT91_PMC_PLL_UPDT_UPDATE);
124+ AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK,
125+ AT91_PMC_PLL_UPDT_UPDATE | core->id);
98126
99− regmap_write(regmap, AT91_PMC_PLL_CTRL0,
100− AT91_PMC_PLL_CTRL0_ENLOCK | AT91_PMC_PLL_CTRL0_ENPLL |
101− AT91_PMC_PLL_CTRL0_ENPLLCK | pll->div);
127+ regmap_update_bits(regmap, AT91_PMC_PLL_CTRL0,
128+ AT91_PMC_PLL_CTRL0_ENLOCK | AT91_PMC_PLL_CTRL0_ENPLL,
129+ AT91_PMC_PLL_CTRL0_ENLOCK | AT91_PMC_PLL_CTRL0_ENPLL);
102130
103131 regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
104− AT91_PMC_PLL_UPDT_UPDATE, AT91_PMC_PLL_UPDT_UPDATE);
132+ AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK,
133+ AT91_PMC_PLL_UPDT_UPDATE | core->id);
105134
106− while (!sam9x60_pll_ready(regmap, pll->id))
135+ while (!sam9x60_pll_ready(regmap, core->id))
107136 cpu_relax();
108137
109− spin_unlock_irqrestore(pll->lock, flags);
138+unlock:
139+ spin_unlock_irqrestore(core->lock, flags);
110140
111141 return 0;
112142 }
113143
114−static int sam9x60_pll_is_prepared(struct clk_hw *hw)
144+static void sam9x60_frac_pll_unprepare(struct clk_hw *hw)
115145 {
116− struct sam9x60_pll *pll = to_sam9x60_pll(hw);
146+ struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw);
147+ struct regmap *regmap = core->regmap;
148+ unsigned long flags;
149+
150+ spin_lock_irqsave(core->lock, flags);
117151
118− return sam9x60_pll_ready(pll->regmap, pll->id);
152+ regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
153+ AT91_PMC_PLL_UPDT_ID_MSK, core->id);
154+
155+ regmap_update_bits(regmap, AT91_PMC_PLL_CTRL0, AT91_PMC_PLL_CTRL0_ENPLL, 0);
156+
157+ if (core->characteristics->upll)
158+ regmap_update_bits(regmap, AT91_PMC_PLL_ACR,
159+ AT91_PMC_PLL_ACR_UTMIBG | AT91_PMC_PLL_ACR_UTMIVR, 0);
160+
161+ regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
162+ AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK,
163+ AT91_PMC_PLL_UPDT_UPDATE | core->id);
164+
165+ spin_unlock_irqrestore(core->lock, flags);
119166 }
120167
121−static void sam9x60_pll_unprepare(struct clk_hw *hw)
168+static int sam9x60_frac_pll_is_prepared(struct clk_hw *hw)
122169 {
123− struct sam9x60_pll *pll = to_sam9x60_pll(hw);
124− unsigned long flags;
170+ struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw);
125171
126− spin_lock_irqsave(pll->lock, flags);
172+ return sam9x60_pll_ready(core->regmap, core->id);
173+}
127174
128− regmap_write(pll->regmap, AT91_PMC_PLL_UPDT, pll->id);
175+static long sam9x60_frac_pll_compute_mul_frac(struct sam9x60_pll_core *core,
176+ unsigned long rate,
177+ unsigned long parent_rate,
178+ bool update)
179+{
180+ struct sam9x60_frac *frac = to_sam9x60_frac(core);
181+ unsigned long tmprate, remainder;
182+ unsigned long nmul = 0;
183+ unsigned long nfrac = 0;
129184
130− regmap_update_bits(pll->regmap, AT91_PMC_PLL_CTRL0,
131− AT91_PMC_PLL_CTRL0_ENPLLCK, 0);
185+ if (rate < FCORE_MIN || rate > FCORE_MAX)
186+ return -ERANGE;
132187
133− regmap_update_bits(pll->regmap, AT91_PMC_PLL_UPDT,
134− AT91_PMC_PLL_UPDT_UPDATE, AT91_PMC_PLL_UPDT_UPDATE);
188+ /*
189+ * Calculate the multiplier associated with the current
190+ * divider that provide the closest rate to the requested one.
191+ */
192+ nmul = mult_frac(rate, 1, parent_rate);
193+ tmprate = mult_frac(parent_rate, nmul, 1);
194+ remainder = rate - tmprate;
135195
136− regmap_update_bits(pll->regmap, AT91_PMC_PLL_CTRL0,
137− AT91_PMC_PLL_CTRL0_ENPLL, 0);
196+ if (remainder) {
197+ nfrac = DIV_ROUND_CLOSEST_ULL((u64)remainder * (1 << 22),
198+ parent_rate);
138199
139− if (pll->characteristics->upll)
140− regmap_update_bits(pll->regmap, AT91_PMC_PLL_ACR,
141− AT91_PMC_PLL_ACR_UTMIBG |
142− AT91_PMC_PLL_ACR_UTMIVR, 0);
200+ tmprate += DIV_ROUND_CLOSEST_ULL((u64)nfrac * parent_rate,
201+ (1 << 22));
202+ }
143203
144− regmap_update_bits(pll->regmap, AT91_PMC_PLL_UPDT,
145− AT91_PMC_PLL_UPDT_UPDATE, AT91_PMC_PLL_UPDT_UPDATE);
204+ /* Check if resulted rate is a valid. */
205+ if (tmprate < FCORE_MIN || tmprate > FCORE_MAX)
206+ return -ERANGE;
146207
147− spin_unlock_irqrestore(pll->lock, flags);
208+ if (update) {
209+ frac->mul = nmul - 1;
210+ frac->frac = nfrac;
211+ }
212+
213+ return tmprate;
148214 }
149215
150−static unsigned long sam9x60_pll_recalc_rate(struct clk_hw *hw,
151− unsigned long parent_rate)
216+static long sam9x60_frac_pll_round_rate(struct clk_hw *hw, unsigned long rate,
217+ unsigned long *parent_rate)
152218 {
153− struct sam9x60_pll *pll = to_sam9x60_pll(hw);
219+ struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw);
154220
155− return (parent_rate * (pll->mul + 1)) / (pll->div + 1);
221+ return sam9x60_frac_pll_compute_mul_frac(core, rate, *parent_rate, false);
156222 }
157223
158−static long sam9x60_pll_get_best_div_mul(struct sam9x60_pll *pll,
159− unsigned long rate,
160− unsigned long parent_rate,
161− bool update)
224+static int sam9x60_frac_pll_set_rate(struct clk_hw *hw, unsigned long rate,
225+ unsigned long parent_rate)
162226 {
163− const struct clk_pll_characteristics *characteristics =
164− pll->characteristics;
165− unsigned long bestremainder = ULONG_MAX;
166− unsigned long maxdiv, mindiv, tmpdiv;
167− long bestrate = -ERANGE;
168− unsigned long bestdiv = 0;
169− unsigned long bestmul = 0;
170− unsigned long bestfrac = 0;
227+ struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw);
171228
172− if (rate < characteristics->output[0].min ||
173− rate > characteristics->output[0].max)
174− return -ERANGE;
229+ return sam9x60_frac_pll_compute_mul_frac(core, rate, parent_rate, true);
230+}
175231
176− if (!pll->characteristics->upll) {
177− mindiv = parent_rate / rate;
178− if (mindiv < 2)
179− mindiv = 2;
232+static const struct clk_ops sam9x60_frac_pll_ops = {
233+ .prepare = sam9x60_frac_pll_prepare,
234+ .unprepare = sam9x60_frac_pll_unprepare,
235+ .is_prepared = sam9x60_frac_pll_is_prepared,
236+ .recalc_rate = sam9x60_frac_pll_recalc_rate,
237+ .round_rate = sam9x60_frac_pll_round_rate,
238+ .set_rate = sam9x60_frac_pll_set_rate,
239+};
180240
181− maxdiv = DIV_ROUND_UP(parent_rate * PLL_MUL_MAX, rate);
182− if (maxdiv > PLL_DIV_MAX)
183− maxdiv = PLL_DIV_MAX;
184− } else {
185− mindiv = maxdiv = UPLL_DIV;
186− }
241+static int sam9x60_div_pll_prepare(struct clk_hw *hw)
242+{
243+ struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw);
244+ struct sam9x60_div *div = to_sam9x60_div(core);
245+ struct regmap *regmap = core->regmap;
246+ unsigned long flags;
247+ unsigned int val, cdiv;
187248
188− for (tmpdiv = mindiv; tmpdiv <= maxdiv; tmpdiv++) {
189− unsigned long remainder;
190− unsigned long tmprate;
191− unsigned long tmpmul;
192− unsigned long tmpfrac = 0;
249+ spin_lock_irqsave(core->lock, flags);
250+ regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
251+ AT91_PMC_PLL_UPDT_ID_MSK, core->id);
252+ regmap_read(regmap, AT91_PMC_PLL_CTRL0, &val);
253+ cdiv = (val & core->layout->div_mask) >> core->layout->div_shift;
193254
194− /*
195− * Calculate the multiplier associated with the current
196− * divider that provide the closest rate to the requested one.
197− */
198− tmpmul = mult_frac(rate, tmpdiv, parent_rate);
199− tmprate = mult_frac(parent_rate, tmpmul, tmpdiv);
200− remainder = rate - tmprate;
255+ /* Stop if enabled an nothing changed. */
256+ if (!!(val & core->layout->endiv_mask) && cdiv == div->div)
257+ goto unlock;
201258
202− if (remainder) {
203− tmpfrac = DIV_ROUND_CLOSEST_ULL((u64)remainder * tmpdiv * (1 << 22),
204− parent_rate);
259+ regmap_update_bits(regmap, AT91_PMC_PLL_CTRL0,
260+ core->layout->div_mask | core->layout->endiv_mask,
261+ (div->div << core->layout->div_shift) |
262+ (1 << core->layout->endiv_shift));
205263
206− tmprate += DIV_ROUND_CLOSEST_ULL((u64)tmpfrac * parent_rate,
207− tmpdiv * (1 << 22));
264+ regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
265+ AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK,
266+ AT91_PMC_PLL_UPDT_UPDATE | core->id);
208267
209− if (tmprate > rate)
210− remainder = tmprate - rate;
211− else
212− remainder = rate - tmprate;
213− }
268+ while (!sam9x60_pll_ready(regmap, core->id))
269+ cpu_relax();
214270
215− /*
216− * Compare the remainder with the best remainder found until
217− * now and elect a new best multiplier/divider pair if the
218− * current remainder is smaller than the best one.
219− */
220− if (remainder < bestremainder) {
221− bestremainder = remainder;
222− bestdiv = tmpdiv;
223− bestmul = tmpmul;
224− bestrate = tmprate;
225− bestfrac = tmpfrac;
271+unlock:
272+ spin_unlock_irqrestore(core->lock, flags);
273+
274+ return 0;
275+}
276+
277+static void sam9x60_div_pll_unprepare(struct clk_hw *hw)
278+{
279+ struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw);
280+ struct regmap *regmap = core->regmap;
281+ unsigned long flags;
282+
283+ spin_lock_irqsave(core->lock, flags);
284+
285+ regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
286+ AT91_PMC_PLL_UPDT_ID_MSK, core->id);
287+
288+ regmap_update_bits(regmap, AT91_PMC_PLL_CTRL0,
289+ core->layout->endiv_mask, 0);
290+
291+ regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
292+ AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK,
293+ AT91_PMC_PLL_UPDT_UPDATE | core->id);
294+
295+ spin_unlock_irqrestore(core->lock, flags);
296+}
297+
298+static int sam9x60_div_pll_is_prepared(struct clk_hw *hw)
299+{
300+ struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw);
301+ struct regmap *regmap = core->regmap;
302+ unsigned long flags;
303+ unsigned int val;
304+
305+ spin_lock_irqsave(core->lock, flags);
306+
307+ regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
308+ AT91_PMC_PLL_UPDT_ID_MSK, core->id);
309+ regmap_read(regmap, AT91_PMC_PLL_CTRL0, &val);
310+
311+ spin_unlock_irqrestore(core->lock, flags);
312+
313+ return !!(val & core->layout->endiv_mask);
314+}
315+
316+static unsigned long sam9x60_div_pll_recalc_rate(struct clk_hw *hw,
317+ unsigned long parent_rate)
318+{
319+ struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw);
320+ struct sam9x60_div *div = to_sam9x60_div(core);
321+
322+ return DIV_ROUND_CLOSEST_ULL(parent_rate, (div->div + 1));
323+}
324+
325+static long sam9x60_div_pll_compute_div(struct sam9x60_pll_core *core,
326+ unsigned long *parent_rate,
327+ unsigned long rate)
328+{
329+ const struct clk_pll_characteristics *characteristics =
330+ core->characteristics;
331+ struct clk_hw *parent = clk_hw_get_parent(&core->hw);
332+ unsigned long tmp_rate, tmp_parent_rate, tmp_diff;
333+ long best_diff = -1, best_rate = -EINVAL;
334+ u32 divid, best_div;
335+
336+ if (!rate)
337+ return 0;
338+
339+ if (rate < characteristics->output[0].min ||
340+ rate > characteristics->output[0].max)
341+ return -ERANGE;
342+
343+ for (divid = 1; divid < core->layout->div_mask; divid++) {
344+ tmp_parent_rate = clk_hw_round_rate(parent, rate * divid);
345+ if (!tmp_parent_rate)
346+ continue;
347+
348+ tmp_rate = DIV_ROUND_CLOSEST_ULL(tmp_parent_rate, divid);
349+ tmp_diff = abs(rate - tmp_rate);
350+
351+ if (best_diff < 0 || best_diff > tmp_diff) {
352+ *parent_rate = tmp_parent_rate;
353+ best_rate = tmp_rate;
354+ best_diff = tmp_diff;
355+ best_div = divid;
226356 }
227357
228− /* We've found a perfect match! */
229− if (!remainder)
358+ if (!best_diff)
230359 break;
231360 }
232361
233− /* Check if bestrate is a valid output rate */
234− if (bestrate < characteristics->output[0].min &&
235− bestrate > characteristics->output[0].max)
362+ if (best_rate < characteristics->output[0].min ||
363+ best_rate > characteristics->output[0].max)
236364 return -ERANGE;
237365
238− if (update) {
239− pll->div = bestdiv - 1;
240− pll->mul = bestmul - 1;
241− pll->frac = bestfrac;
242− }
243−
244− return bestrate;
366+ return best_rate;
245367 }
246368
247−static long sam9x60_pll_round_rate(struct clk_hw *hw, unsigned long rate,
248− unsigned long *parent_rate)
369+static long sam9x60_div_pll_round_rate(struct clk_hw *hw, unsigned long rate,
370+ unsigned long *parent_rate)
249371 {
250− struct sam9x60_pll *pll = to_sam9x60_pll(hw);
372+ struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw);
251373
252− return sam9x60_pll_get_best_div_mul(pll, rate, *parent_rate, false);
374+ return sam9x60_div_pll_compute_div(core, parent_rate, rate);
253375 }
254376
255−static int sam9x60_pll_set_rate(struct clk_hw *hw, unsigned long rate,
256− unsigned long parent_rate)
377+static int sam9x60_div_pll_set_rate(struct clk_hw *hw, unsigned long rate,
378+ unsigned long parent_rate)
257379 {
258− struct sam9x60_pll *pll = to_sam9x60_pll(hw);
380+ struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw);
381+ struct sam9x60_div *div = to_sam9x60_div(core);
382+
383+ div->div = DIV_ROUND_CLOSEST(parent_rate, rate) - 1;
259384
260− return sam9x60_pll_get_best_div_mul(pll, rate, parent_rate, true);
385+ return 0;
261386 }
262387
263−static const struct clk_ops pll_ops = {
264− .prepare = sam9x60_pll_prepare,
265− .unprepare = sam9x60_pll_unprepare,
266− .is_prepared = sam9x60_pll_is_prepared,
267− .recalc_rate = sam9x60_pll_recalc_rate,
268− .round_rate = sam9x60_pll_round_rate,
269− .set_rate = sam9x60_pll_set_rate,
388+static const struct clk_ops sam9x60_div_pll_ops = {
389+ .prepare = sam9x60_div_pll_prepare,
390+ .unprepare = sam9x60_div_pll_unprepare,
391+ .is_prepared = sam9x60_div_pll_is_prepared,
392+ .recalc_rate = sam9x60_div_pll_recalc_rate,
393+ .round_rate = sam9x60_div_pll_round_rate,
394+ .set_rate = sam9x60_div_pll_set_rate,
270395 };
271396
272397 struct clk_hw * __init
273−sam9x60_clk_register_pll(struct regmap *regmap, spinlock_t *lock,
274− const char *name, const char *parent_name, u8 id,
275− const struct clk_pll_characteristics *characteristics)
398+sam9x60_clk_register_frac_pll(struct regmap *regmap, spinlock_t *lock,
399+ const char *name, const char *parent_name,
400+ struct clk_hw *parent_hw, u8 id,
401+ const struct clk_pll_characteristics *characteristics,
402+ const struct clk_pll_layout *layout, bool critical)
276403 {
277− struct sam9x60_pll *pll;
404+ struct sam9x60_frac *frac;
278405 struct clk_hw *hw;
279406 struct clk_init_data init;
280− unsigned int pllr;
407+ unsigned long parent_rate, flags;
408+ unsigned int val;
281409 int ret;
282410
283− if (id > PLL_MAX_ID)
411+ if (id > PLL_MAX_ID || !lock || !parent_hw)
284412 return ERR_PTR(-EINVAL);
285413
286− pll = kzalloc(sizeof(*pll), GFP_KERNEL);
287− if (!pll)
414+ frac = kzalloc(sizeof(*frac), GFP_KERNEL);
415+ if (!frac)
288416 return ERR_PTR(-ENOMEM);
289417
290418 init.name = name;
291− init.ops = &pll_ops;
292419 init.parent_names = &parent_name;
293420 init.num_parents = 1;
421+ init.ops = &sam9x60_frac_pll_ops;
294422 init.flags = CLK_SET_RATE_GATE;
423+ if (critical)
424+ init.flags |= CLK_IS_CRITICAL;
425+
426+ frac->core.id = id;
427+ frac->core.hw.init = &init;
428+ frac->core.characteristics = characteristics;
429+ frac->core.layout = layout;
430+ frac->core.regmap = regmap;
431+ frac->core.lock = lock;
432+
433+ spin_lock_irqsave(frac->core.lock, flags);
434+ if (sam9x60_pll_ready(regmap, id)) {
435+ regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
436+ AT91_PMC_PLL_UPDT_ID_MSK, id);
437+ regmap_read(regmap, AT91_PMC_PLL_CTRL1, &val);
438+ frac->mul = FIELD_GET(PMC_PLL_CTRL1_MUL_MSK, val);
439+ frac->frac = FIELD_GET(PMC_PLL_CTRL1_FRACR_MSK, val);
440+ } else {
441+ /*
442+ * This means the PLL is not setup by bootloaders. In this
443+ * case we need to set the minimum rate for it. Otherwise
444+ * a clock child of this PLL may be enabled before setting
445+ * its rate leading to enabling this PLL with unsupported
446+ * rate. This will lead to PLL not being locked at all.
447+ */
448+ parent_rate = clk_hw_get_rate(parent_hw);
449+ if (!parent_rate) {
450+ hw = ERR_PTR(-EINVAL);
451+ goto free;
452+ }
453+
454+ ret = sam9x60_frac_pll_compute_mul_frac(&frac->core, FCORE_MIN,
455+ parent_rate, true);
456+ if (ret <= 0) {
457+ hw = ERR_PTR(ret);
458+ goto free;
459+ }
460+ }
461+ spin_unlock_irqrestore(frac->core.lock, flags);
462+
463+ hw = &frac->core.hw;
464+ ret = clk_hw_register(NULL, hw);
465+ if (ret) {
466+ kfree(frac);
467+ hw = ERR_PTR(ret);
468+ }
295469
296− pll->id = id;
297− pll->hw.init = &init;
298− pll->characteristics = characteristics;
299− pll->regmap = regmap;
300− pll->lock = lock;
470+ return hw;
471+
472+free:
473+ spin_unlock_irqrestore(frac->core.lock, flags);
474+ kfree(frac);
475+ return hw;
476+}
477+
478+struct clk_hw * __init
479+sam9x60_clk_register_div_pll(struct regmap *regmap, spinlock_t *lock,
480+ const char *name, const char *parent_name, u8 id,
481+ const struct clk_pll_characteristics *characteristics,
482+ const struct clk_pll_layout *layout, bool critical)
483+{
484+ struct sam9x60_div *div;
485+ struct clk_hw *hw;
486+ struct clk_init_data init;
487+ unsigned long flags;
488+ unsigned int val;
489+ int ret;
490+
491+ if (id > PLL_MAX_ID || !lock)
492+ return ERR_PTR(-EINVAL);
493+
494+ div = kzalloc(sizeof(*div), GFP_KERNEL);
495+ if (!div)
496+ return ERR_PTR(-ENOMEM);
497+
498+ init.name = name;
499+ init.parent_names = &parent_name;
500+ init.num_parents = 1;
501+ init.ops = &sam9x60_div_pll_ops;
502+ init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
503+ CLK_SET_RATE_PARENT;
504+ if (critical)
505+ init.flags |= CLK_IS_CRITICAL;
506+
507+ div->core.id = id;
508+ div->core.hw.init = &init;
509+ div->core.characteristics = characteristics;
510+ div->core.layout = layout;
511+ div->core.regmap = regmap;
512+ div->core.lock = lock;
513+
514+ spin_lock_irqsave(div->core.lock, flags);
515+
516+ regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
517+ AT91_PMC_PLL_UPDT_ID_MSK, id);
518+ regmap_read(regmap, AT91_PMC_PLL_CTRL0, &val);
519+ div->div = FIELD_GET(PMC_PLL_CTRL0_DIV_MSK, val);
301520
302− regmap_write(regmap, AT91_PMC_PLL_UPDT, id);
303− regmap_read(regmap, AT91_PMC_PLL_CTRL0, &pllr);
304− pll->div = FIELD_GET(PMC_PLL_CTRL0_DIV_MSK, pllr);
305− regmap_read(regmap, AT91_PMC_PLL_CTRL1, &pllr);
306− pll->mul = FIELD_GET(PMC_PLL_CTRL1_MUL_MSK, pllr);
521+ spin_unlock_irqrestore(div->core.lock, flags);
307522
308− hw = &pll->hw;
523+ hw = &div->core.hw;
309524 ret = clk_hw_register(NULL, hw);
310525 if (ret) {
311− kfree(pll);
526+ kfree(div);
312527 hw = ERR_PTR(ret);
313528 }
314529
drivers/clk/at91/clk-system.c+2−2
@@ -34,7 +34,7 @@ static inline bool clk_system_ready(struct regmap *regmap, int id) · 33 unmodified lines
3434
3535 regmap_read(regmap, AT91_PMC_SR, &status);
3636
37− return status & (1 << id) ? 1 : 0;
37+ return !!(status & (1 << id));
3838 }
3939
4040 static int clk_system_prepare(struct clk_hw *hw)
@@ -74,7 +74,7 @@ static int clk_system_is_prepared(struct clk_hw *hw) · 33 unmodified lines
7474
7575 regmap_read(sys->regmap, AT91_PMC_SR, &status);
7676
77− return status & (1 << sys->id) ? 1 : 0;
77+ return !!(status & (1 << sys->id));
7878 }
7979
8080 static const struct clk_ops system_ops = {
drivers/clk/at91/clk-utmi.c+98−5
@@ -120,9 +120,11 @@ static const struct clk_ops utmi_ops = { · 119 unmodified lines
120120 .recalc_rate = clk_utmi_recalc_rate,
121121 };
122122
123−struct clk_hw * __init
124−at91_clk_register_utmi(struct regmap *regmap_pmc, struct regmap *regmap_sfr,
125− const char *name, const char *parent_name)
123+static struct clk_hw * __init
124+at91_clk_register_utmi_internal(struct regmap *regmap_pmc,
125+ struct regmap *regmap_sfr,
126+ const char *name, const char *parent_name,
127+ const struct clk_ops *ops, unsigned long flags)
126128 {
127129 struct clk_utmi *utmi;
128130 struct clk_hw *hw;
@@ -134,10 +136,10 @@ at91_clk_register_utmi(struct regmap *regmap_pmc, struct regmap *regmap_sfr, · 5 unmodified lines
134136 return ERR_PTR(-ENOMEM);
135137
136138 init.name = name;
137− init.ops = &utmi_ops;
139+ init.ops = ops;
138140 init.parent_names = parent_name ? &parent_name : NULL;
139141 init.num_parents = parent_name ? 1 : 0;
140− init.flags = CLK_SET_RATE_GATE;
142+ init.flags = flags;
141143
142144 utmi->hw.init = &init;
143145 utmi->regmap_pmc = regmap_pmc;
@@ -152,3 +154,94 @@ at91_clk_register_utmi(struct regmap *regmap_pmc, struct regmap *regmap_sfr, · 8 unmodified lines
152154
153155 return hw;
154156 }
157+
158+struct clk_hw * __init
159+at91_clk_register_utmi(struct regmap *regmap_pmc, struct regmap *regmap_sfr,
160+ const char *name, const char *parent_name)
161+{
162+ return at91_clk_register_utmi_internal(regmap_pmc, regmap_sfr, name,
163+ parent_name, &utmi_ops, CLK_SET_RATE_GATE);
164+}
165+
166+static int clk_utmi_sama7g5_prepare(struct clk_hw *hw)
167+{
168+ struct clk_utmi *utmi = to_clk_utmi(hw);
169+ struct clk_hw *hw_parent;
170+ unsigned long parent_rate;
171+ unsigned int val;
172+
173+ hw_parent = clk_hw_get_parent(hw);
174+ parent_rate = clk_hw_get_rate(hw_parent);
175+
176+ switch (parent_rate) {
177+ case 16000000:
178+ val = 0;
179+ break;
180+ case 20000000:
181+ val = 2;
182+ break;
183+ case 24000000:
184+ val = 3;
185+ break;
186+ case 32000000:
187+ val = 5;
188+ break;
189+ default:
190+ pr_err("UTMICK: unsupported main_xtal rate\n");
191+ return -EINVAL;
192+ }
193+
194+ regmap_write(utmi->regmap_pmc, AT91_PMC_XTALF, val);
195+
196+ return 0;
197+
198+}
199+
200+static int clk_utmi_sama7g5_is_prepared(struct clk_hw *hw)
201+{
202+ struct clk_utmi *utmi = to_clk_utmi(hw);
203+ struct clk_hw *hw_parent;
204+ unsigned long parent_rate;
205+ unsigned int val;
206+
207+ hw_parent = clk_hw_get_parent(hw);
208+ parent_rate = clk_hw_get_rate(hw_parent);
209+
210+ regmap_read(utmi->regmap_pmc, AT91_PMC_XTALF, &val);
211+ switch (val & 0x7) {
212+ case 0:
213+ if (parent_rate == 16000000)
214+ return 1;
215+ break;
216+ case 2:
217+ if (parent_rate == 20000000)
218+ return 1;
219+ break;
220+ case 3:
221+ if (parent_rate == 24000000)
222+ return 1;
223+ break;
224+ case 5:
225+ if (parent_rate == 32000000)
226+ return 1;
227+ break;
228+ default:
229+ break;
230+ }
231+
232+ return 0;
233+}
234+
235+static const struct clk_ops sama7g5_utmi_ops = {
236+ .prepare = clk_utmi_sama7g5_prepare,
237+ .is_prepared = clk_utmi_sama7g5_is_prepared,
238+ .recalc_rate = clk_utmi_recalc_rate,
239+};
240+
241+struct clk_hw * __init
242+at91_clk_sama7g5_register_utmi(struct regmap *regmap_pmc, const char *name,
243+ const char *parent_name)
244+{
245+ return at91_clk_register_utmi_internal(regmap_pmc, NULL, name,
246+ parent_name, &sama7g5_utmi_ops, 0);
247+}
drivers/clk/at91/dt-compat.c+15−10
@@ -22,6 +22,8 @@ · 21 unmodified lines
2222
2323 #define SYSTEM_MAX_ID 31
2424
25+#define GCK_INDEX_DT_AUDIO_PLL 5
26+
2527 #ifdef CONFIG_HAVE_AT91_AUDIO_PLL
2628 static void __init of_sama5d2_clk_audio_pll_frac_setup(struct device_node *np)
2729 {
@@ -135,7 +137,7 @@ static void __init of_sama5d2_clk_generated_setup(struct device_node *np) · 107 unmodified lines
135137 return;
136138
137139 for_each_child_of_node(np, gcknp) {
138− bool pll_audio = false;
140+ int chg_pid = INT_MIN;
139141
140142 if (of_property_read_u32(gcknp, "reg", &id))
141143 continue;
@@ -152,12 +154,13 @@ static void __init of_sama5d2_clk_generated_setup(struct device_node *np) · 10 unmodified lines
152154 if (of_device_is_compatible(np, "atmel,sama5d2-clk-generated") &&
153155 (id == GCK_ID_I2S0 || id == GCK_ID_I2S1 ||
154156 id == GCK_ID_CLASSD))
155− pll_audio = true;
157+ chg_pid = GCK_INDEX_DT_AUDIO_PLL;
156158
157159 hw = at91_clk_register_generated(regmap, &pmc_pcr_lock,
158160 &dt_pcr_layout, name,
159− parent_names, num_parents,
160− id, pll_audio, &range);
161+ parent_names, NULL,
162+ num_parents, id, &range,
163+ chg_pid);
161164 if (IS_ERR(hw))
162165 continue;
163166
@@ -460,7 +463,8 @@ of_at91_clk_periph_setup(struct device_node *np, u8 type) · 296 unmodified lines
460463 &dt_pcr_layout,
461464 name,
462465 parent_name,
463− id, &range);
466+ id, &range,
467+ INT_MIN);
464468 }
465469
466470 if (IS_ERR(hw))
@@ -673,7 +677,8 @@ CLK_OF_DECLARE(at91sam9x5_clk_plldiv, "atmel,at91sam9x5-clk-plldiv", · 206 unmodified lines
673677
674678 static void __init
675679 of_at91_clk_prog_setup(struct device_node *np,
676− const struct clk_programmable_layout *layout)
680+ const struct clk_programmable_layout *layout,
681+ u32 *mux_table)
677682 {
678683 int num;
679684 u32 id;
@@ -707,7 +712,7 @@ of_at91_clk_prog_setup(struct device_node *np, · 27 unmodified lines
707712
708713 hw = at91_clk_register_programmable(regmap, name,
709714 parent_names, num_parents,
710− id, layout);
715+ id, layout, mux_table);
711716 if (IS_ERR(hw))
712717 continue;
713718
@@ -717,21 +722,21 @@ of_at91_clk_prog_setup(struct device_node *np, · 3 unmodified lines
717722
718723 static void __init of_at91rm9200_clk_prog_setup(struct device_node *np)
719724 {
720− of_at91_clk_prog_setup(np, &at91rm9200_programmable_layout);
725+ of_at91_clk_prog_setup(np, &at91rm9200_programmable_layout, NULL);
721726 }
722727 CLK_OF_DECLARE(at91rm9200_clk_prog, "atmel,at91rm9200-clk-programmable",
723728 of_at91rm9200_clk_prog_setup);
724729
725730 static void __init of_at91sam9g45_clk_prog_setup(struct device_node *np)
726731 {
727− of_at91_clk_prog_setup(np, &at91sam9g45_programmable_layout);
732+ of_at91_clk_prog_setup(np, &at91sam9g45_programmable_layout, NULL);
728733 }
729734 CLK_OF_DECLARE(at91sam9g45_clk_prog, "atmel,at91sam9g45-clk-programmable",
730735 of_at91sam9g45_clk_prog_setup);
731736
732737 static void __init of_at91sam9x5_clk_prog_setup(struct device_node *np)
733738 {
734− of_at91_clk_prog_setup(np, &at91sam9x5_programmable_layout);
739+ of_at91_clk_prog_setup(np, &at91sam9x5_programmable_layout, NULL);
735740 }
736741 CLK_OF_DECLARE(at91sam9x5_clk_prog, "atmel,at91sam9x5-clk-programmable",
737742 of_at91sam9x5_clk_prog_setup);
drivers/clk/at91/pmc.h+35−8
@@ -54,8 +54,14 @@ struct clk_master_characteristics { · 53 unmodified lines
5454
5555 struct clk_pll_layout {
5656 u32 pllr_mask;
57− u16 mul_mask;
57+ u32 mul_mask;
58+ u32 frac_mask;
59+ u32 div_mask;
60+ u32 endiv_mask;
5861 u8 mul_shift;
62+ u8 frac_shift;
63+ u8 div_shift;
64+ u8 endiv_shift;
5965 };
6066
6167 extern const struct clk_pll_layout at91rm9200_pll_layout;
@@ -122,8 +128,8 @@ struct clk_hw * __init · 60 unmodified lines
122128 at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock,
123129 const struct clk_pcr_layout *layout,
124130 const char *name, const char **parent_names,
125− u8 num_parents, u8 id, bool pll_audio,
126− const struct clk_range *range);
131+ u32 *mux_table, u8 num_parents, u8 id,
132+ const struct clk_range *range, int chg_pid);
127133
128134 struct clk_hw * __init
129135 at91_clk_register_h32mx(struct regmap *regmap, const char *name,
@@ -154,6 +160,13 @@ at91_clk_register_master(struct regmap *regmap, const char *name, · 24 unmodified lines
154160 const struct clk_master_layout *layout,
155161 const struct clk_master_characteristics *characteristics);
156162
163+struct clk_hw * __init
164+at91_clk_sama7g5_register_master(struct regmap *regmap,
165+ const char *name, int num_parents,
166+ const char **parent_names, u32 *mux_table,
167+ spinlock_t *lock, u8 id, bool critical,
168+ int chg_pid);
169+
157170 struct clk_hw * __init
158171 at91_clk_register_peripheral(struct regmap *regmap, const char *name,
159172 const char *parent_name, u32 id);
@@ -161,7 +174,8 @@ struct clk_hw * __init · 1 unmodified line
161174 at91_clk_register_sam9x5_peripheral(struct regmap *regmap, spinlock_t *lock,
162175 const struct clk_pcr_layout *layout,
163176 const char *name, const char *parent_name,
164− u32 id, const struct clk_range *range);
177+ u32 id, const struct clk_range *range,
178+ int chg_pid);
165179
166180 struct clk_hw * __init
167181 at91_clk_register_pll(struct regmap *regmap, const char *name,
@@ -173,14 +187,23 @@ at91_clk_register_plldiv(struct regmap *regmap, const char *name, · 5 unmodified lines
173187 const char *parent_name);
174188
175189 struct clk_hw * __init
176−sam9x60_clk_register_pll(struct regmap *regmap, spinlock_t *lock,
177− const char *name, const char *parent_name, u8 id,
178− const struct clk_pll_characteristics *characteristics);
190+sam9x60_clk_register_div_pll(struct regmap *regmap, spinlock_t *lock,
191+ const char *name, const char *parent_name, u8 id,
192+ const struct clk_pll_characteristics *characteristics,
193+ const struct clk_pll_layout *layout, bool critical);
194+
195+struct clk_hw * __init
196+sam9x60_clk_register_frac_pll(struct regmap *regmap, spinlock_t *lock,
197+ const char *name, const char *parent_name,
198+ struct clk_hw *parent_hw, u8 id,
199+ const struct clk_pll_characteristics *characteristics,
200+ const struct clk_pll_layout *layout, bool critical);
179201
180202 struct clk_hw * __init
181203 at91_clk_register_programmable(struct regmap *regmap, const char *name,
182204 const char **parent_names, u8 num_parents, u8 id,
183− const struct clk_programmable_layout *layout);
205+ const struct clk_programmable_layout *layout,
206+ u32 *mux_table);
184207
185208 struct clk_hw * __init
186209 at91_clk_register_sam9260_slow(struct regmap *regmap,
@@ -213,6 +236,10 @@ struct clk_hw * __init · 26 unmodified lines
213236 at91_clk_register_utmi(struct regmap *regmap_pmc, struct regmap *regmap_sfr,
214237 const char *name, const char *parent_name);
215238
239+struct clk_hw * __init
240+at91_clk_sama7g5_register_utmi(struct regmap *regmap, const char *name,
241+ const char *parent_name);
242+
216243 #ifdef CONFIG_PM
217244 void pmc_register_id(u8 id);
218245 void pmc_register_pck(u8 pck);
drivers/clk/at91/sam9x60.c+49−17
@@ -22,7 +22,7 @@ static const struct clk_master_layout sam9x60_master_layout = { · 21 unmodified lines
2222 };
2323
2424 static const struct clk_range plla_outputs[] = {
25− { .min = 300000000, .max = 600000000 },
25+ { .min = 2343750, .max = 1200000000 },
2626 };
2727
2828 static const struct clk_pll_characteristics plla_characteristics = {
@@ -42,6 +42,20 @@ static const struct clk_pll_characteristics upll_characteristics = { · 13 unmodified lines
4242 .upll = true,
4343 };
4444
45+static const struct clk_pll_layout pll_frac_layout = {
46+ .mul_mask = GENMASK(31, 24),
47+ .frac_mask = GENMASK(21, 0),
48+ .mul_shift = 24,
49+ .frac_shift = 0,
50+};
51+
52+static const struct clk_pll_layout pll_div_layout = {
53+ .div_mask = GENMASK(7, 0),
54+ .endiv_mask = BIT(29),
55+ .div_shift = 0,
56+ .endiv_shift = 29,
57+};
58+
4559 static const struct clk_programmable_layout sam9x60_programmable_layout = {
4660 .pres_mask = 0xff,
4761 .pres_shift = 8,
@@ -156,6 +170,7 @@ static void __init sam9x60_pmc_setup(struct device_node *np) · 108 unmodified lines
156170 const char *td_slck_name, *md_slck_name, *mainxtal_name;
157171 struct pmc_data *sam9x60_pmc;
158172 const char *parent_names[6];
173+ struct clk_hw *main_osc_hw;
159174 struct regmap *regmap;
160175 struct clk_hw *hw;
161176 int i;
@@ -178,7 +193,7 @@ static void __init sam9x60_pmc_setup(struct device_node *np) · 16 unmodified lines
178193 return;
179194 mainxtal_name = of_clk_get_parent_name(np, i);
180195
181− regmap = syscon_node_to_regmap(np);
196+ regmap = device_node_to_regmap(np);
182197 if (IS_ERR(regmap))
183198 return;
184199
@@ -189,7 +204,7 @@ static void __init sam9x60_pmc_setup(struct device_node *np) · 4 unmodified lines
189204 if (!sam9x60_pmc)
190205 return;
191206
192− hw = at91_clk_register_main_rc_osc(regmap, "main_rc_osc", 24000000,
207+ hw = at91_clk_register_main_rc_osc(regmap, "main_rc_osc", 12000000,
193208 50000000);
194209 if (IS_ERR(hw))
195210 goto err_free;
@@ -200,6 +215,7 @@ static void __init sam9x60_pmc_setup(struct device_node *np) · 4 unmodified lines
200215 bypass);
201216 if (IS_ERR(hw))
202217 goto err_free;
218+ main_osc_hw = hw;
203219
204220 parent_names[0] = "main_rc_osc";
205221 parent_names[1] = "main_osc";
@@ -209,15 +225,31 @@ static void __init sam9x60_pmc_setup(struct device_node *np) · 3 unmodified lines
209225
210226 sam9x60_pmc->chws[PMC_MAIN] = hw;
211227
212− hw = sam9x60_clk_register_pll(regmap, &pmc_pll_lock, "pllack",
213− "mainck", 0, &plla_characteristics);
228+ hw = sam9x60_clk_register_frac_pll(regmap, &pmc_pll_lock, "pllack_fracck",
229+ "mainck", sam9x60_pmc->chws[PMC_MAIN],
230+ 0, &plla_characteristics,
231+ &pll_frac_layout, true);
232+ if (IS_ERR(hw))
233+ goto err_free;
234+
235+ hw = sam9x60_clk_register_div_pll(regmap, &pmc_pll_lock, "pllack_divck",
236+ "pllack_fracck", 0, &plla_characteristics,
237+ &pll_div_layout, true);
214238 if (IS_ERR(hw))
215239 goto err_free;
216240
217241 sam9x60_pmc->chws[PMC_PLLACK] = hw;
218242
219− hw = sam9x60_clk_register_pll(regmap, &pmc_pll_lock, "upllck",
220− "main_osc", 1, &upll_characteristics);
243+ hw = sam9x60_clk_register_frac_pll(regmap, &pmc_pll_lock, "upllck_fracck",
244+ "main_osc", main_osc_hw, 1,
245+ &upll_characteristics,
246+ &pll_frac_layout, false);
247+ if (IS_ERR(hw))
248+ goto err_free;
249+
250+ hw = sam9x60_clk_register_div_pll(regmap, &pmc_pll_lock, "upllck_divck",
251+ "upllck_fracck", 1, &upll_characteristics,
252+ &pll_div_layout, false);
221253 if (IS_ERR(hw))
222254 goto err_free;
223255
@@ -225,7 +257,7 @@ static void __init sam9x60_pmc_setup(struct device_node *np) · 1 unmodified line
225257
226258 parent_names[0] = md_slck_name;
227259 parent_names[1] = "mainck";
228− parent_names[2] = "pllack";
260+ parent_names[2] = "pllack_divck";
229261 hw = at91_clk_register_master(regmap, "masterck", 3, parent_names,
230262 &sam9x60_master_layout,
231263 &mck_characteristics);
@@ -234,8 +266,8 @@ static void __init sam9x60_pmc_setup(struct device_node *np) · 2 unmodified lines
234266
235267 sam9x60_pmc->chws[PMC_MCK] = hw;
236268
237− parent_names[0] = "pllack";
238− parent_names[1] = "upllck";
269+ parent_names[0] = "pllack_divck";
270+ parent_names[1] = "upllck_divck";
239271 parent_names[2] = "main_osc";
240272 hw = sam9x60_clk_register_usb(regmap, "usbck", parent_names, 3);
241273 if (IS_ERR(hw))
@@ -245,8 +277,8 @@ static void __init sam9x60_pmc_setup(struct device_node *np) · 3 unmodified lines
245277 parent_names[1] = td_slck_name;
246278 parent_names[2] = "mainck";
247279 parent_names[3] = "masterck";
248− parent_names[4] = "pllack";
249− parent_names[5] = "upllck";
280+ parent_names[4] = "pllack_divck";
281+ parent_names[5] = "upllck_divck";
250282 for (i = 0; i < 8; i++) {
251283 char name[6];
252284
@@ -254,7 +286,8 @@ static void __init sam9x60_pmc_setup(struct device_node *np) · 1 unmodified line
254286
255287 hw = at91_clk_register_programmable(regmap, name,
256288 parent_names, 6, i,
257− &sam9x60_programmable_layout);
289+ &sam9x60_programmable_layout,
290+ NULL);
258291 if (IS_ERR(hw))
259292 goto err_free;
260293
@@ -277,7 +310,7 @@ static void __init sam9x60_pmc_setup(struct device_node *np) · 16 unmodified lines
277310 sam9x60_periphck[i].n,
278311 "masterck",
279312 sam9x60_periphck[i].id,
280− &range);
313+ &range, INT_MIN);
281314 if (IS_ERR(hw))
282315 goto err_free;
283316
@@ -288,10 +321,9 @@ static void __init sam9x60_pmc_setup(struct device_node *np) · 4 unmodified lines
288321 hw = at91_clk_register_generated(regmap, &pmc_pcr_lock,
289322 &sam9x60_pcr_layout,
290323 sam9x60_gck[i].n,
291− parent_names, 6,
324+ parent_names, NULL, 6,
292325 sam9x60_gck[i].id,
293− false,
294− &sam9x60_gck[i].r);
326+ &sam9x60_gck[i].r, INT_MIN);
295327 if (IS_ERR(hw))
296328 goto err_free;
297329
drivers/clk/at91/sama5d2.c+21−20
@@ -116,21 +116,20 @@ static const struct { · 115 unmodified lines
116116 char *n;
117117 u8 id;
118118 struct clk_range r;
119− bool pll;
119+ int chg_pid;
120120 } sama5d2_gck[] = {
121− { .n = "sdmmc0_gclk", .id = 31, },
122− { .n = "sdmmc1_gclk", .id = 32, },
123− { .n = "tcb0_gclk", .id = 35, .r = { .min = 0, .max = 83000000 }, },
124− { .n = "tcb1_gclk", .id = 36, .r = { .min = 0, .max = 83000000 }, },
125− { .n = "pwm_gclk", .id = 38, .r = { .min = 0, .max = 83000000 }, },
126− { .n = "isc_gclk", .id = 46, },
127− { .n = "pdmic_gclk", .id = 48, },
128− { .n = "i2s0_gclk", .id = 54, .pll = true },
129− { .n = "i2s1_gclk", .id = 55, .pll = true },
130− { .n = "can0_gclk", .id = 56, .r = { .min = 0, .max = 80000000 }, },
131− { .n = "can1_gclk", .id = 57, .r = { .min = 0, .max = 80000000 }, },
132− { .n = "classd_gclk", .id = 59, .r = { .min = 0, .max = 100000000 },
133− .pll = true },
121+ { .n = "sdmmc0_gclk", .id = 31, .chg_pid = INT_MIN, },
122+ { .n = "sdmmc1_gclk", .id = 32, .chg_pid = INT_MIN, },
123+ { .n = "tcb0_gclk", .id = 35, .chg_pid = INT_MIN, .r = { .min = 0, .max = 83000000 }, },
124+ { .n = "tcb1_gclk", .id = 36, .chg_pid = INT_MIN, .r = { .min = 0, .max = 83000000 }, },
125+ { .n = "pwm_gclk", .id = 38, .chg_pid = INT_MIN, .r = { .min = 0, .max = 83000000 }, },
126+ { .n = "isc_gclk", .id = 46, .chg_pid = INT_MIN, },
127+ { .n = "pdmic_gclk", .id = 48, .chg_pid = INT_MIN, },
128+ { .n = "i2s0_gclk", .id = 54, .chg_pid = 5, },
129+ { .n = "i2s1_gclk", .id = 55, .chg_pid = 5, },
130+ { .n = "can0_gclk", .id = 56, .chg_pid = INT_MIN, .r = { .min = 0, .max = 80000000 }, },
131+ { .n = "can1_gclk", .id = 57, .chg_pid = INT_MIN, .r = { .min = 0, .max = 80000000 }, },
132+ { .n = "classd_gclk", .id = 59, .chg_pid = 5, .r = { .min = 0, .max = 100000000 }, },
134133 };
135134
136135 static const struct clk_programmable_layout sama5d2_programmable_layout = {
@@ -269,7 +268,8 @@ static void __init sama5d2_pmc_setup(struct device_node *np) · 132 unmodified lines
269268
270269 hw = at91_clk_register_programmable(regmap, name,
271270 parent_names, 6, i,
272− &sama5d2_programmable_layout);
271+ &sama5d2_programmable_layout,
272+ NULL);
273273 if (IS_ERR(hw))
274274 goto err_free;
275275
@@ -292,7 +292,7 @@ static void __init sama5d2_pmc_setup(struct device_node *np) · 16 unmodified lines
292292 sama5d2_periphck[i].n,
293293 "masterck",
294294 sama5d2_periphck[i].id,
295− &range);
295+ &range, INT_MIN);
296296 if (IS_ERR(hw))
297297 goto err_free;
298298
@@ -305,7 +305,8 @@ static void __init sama5d2_pmc_setup(struct device_node *np) · 6 unmodified lines
305305 sama5d2_periph32ck[i].n,
306306 "h32mxck",
307307 sama5d2_periph32ck[i].id,
308− &sama5d2_periph32ck[i].r);
308+ &sama5d2_periph32ck[i].r,
309+ INT_MIN);
309310 if (IS_ERR(hw))
310311 goto err_free;
311312
@@ -322,10 +323,10 @@ static void __init sama5d2_pmc_setup(struct device_node *np) · 10 unmodified lines
322323 hw = at91_clk_register_generated(regmap, &pmc_pcr_lock,
323324 &sama5d2_pcr_layout,
324325 sama5d2_gck[i].n,
325− parent_names, 6,
326+ parent_names, NULL, 6,
326327 sama5d2_gck[i].id,
327− sama5d2_gck[i].pll,
328− &sama5d2_gck[i].r);
328+ &sama5d2_gck[i].r,
329+ sama5d2_gck[i].chg_pid);
329330 if (IS_ERR(hw))
330331 goto err_free;
331332
drivers/clk/at91/sama5d3.c+5−3
@@ -121,7 +121,7 @@ static void __init sama5d3_pmc_setup(struct device_node *np) · 120 unmodified lines
121121 return;
122122 mainxtal_name = of_clk_get_parent_name(np, i);
123123
124− regmap = syscon_node_to_regmap(np);
124+ regmap = device_node_to_regmap(np);
125125 if (IS_ERR(regmap))
126126 return;
127127
@@ -200,7 +200,8 @@ static void __init sama5d3_pmc_setup(struct device_node *np) · 72 unmodified lines
200200
201201 hw = at91_clk_register_programmable(regmap, name,
202202 parent_names, 5, i,
203− &at91sam9x5_programmable_layout);
203+ &at91sam9x5_programmable_layout,
204+ NULL);
204205 if (IS_ERR(hw))
205206 goto err_free;
206207
@@ -223,7 +224,8 @@ static void __init sama5d3_pmc_setup(struct device_node *np) · 16 unmodified lines
223224 sama5d3_periphck[i].n,
224225 "masterck",
225226 sama5d3_periphck[i].id,
226− &sama5d3_periphck[i].r);
227+ &sama5d3_periphck[i].r,
228+ INT_MIN);
227229 if (IS_ERR(hw))
228230 goto err_free;
229231
drivers/clk/at91/sama5d4.c+4−3
@@ -223,7 +223,8 @@ static void __init sama5d4_pmc_setup(struct device_node *np) · 222 unmodified lines
223223
224224 hw = at91_clk_register_programmable(regmap, name,
225225 parent_names, 5, i,
226− &at91sam9x5_programmable_layout);
226+ &at91sam9x5_programmable_layout,
227+ NULL);
227228 if (IS_ERR(hw))
228229 goto err_free;
229230
@@ -246,7 +247,7 @@ static void __init sama5d4_pmc_setup(struct device_node *np) · 16 unmodified lines
246247 sama5d4_periphck[i].n,
247248 "masterck",
248249 sama5d4_periphck[i].id,
249− &range);
250+ &range, INT_MIN);
250251 if (IS_ERR(hw))
251252 goto err_free;
252253
@@ -259,7 +260,7 @@ static void __init sama5d4_pmc_setup(struct device_node *np) · 6 unmodified lines
259260 sama5d4_periph32ck[i].n,
260261 "h32mxck",
261262 sama5d4_periph32ck[i].id,
262− &range);
263+ &range, INT_MIN);
263264 if (IS_ERR(hw))
264265 goto err_free;
265266
drivers/clk/at91/sama7g5.c+1059−0
@@ -0,0 +1,1059 @@
1+// SPDX-License-Identifier: GPL-2.0
2+/*
3+ * SAMA7G5 PMC code.
4+ *
5+ * Copyright (C) 2020 Microchip Technology Inc. and its subsidiaries
6+ *
7+ * Author: Claudiu Beznea <claudiu.beznea@microchip.com>
8+ *
9+ */
10+#include <linux/clk.h>
11+#include <linux/clk-provider.h>
12+#include <linux/mfd/syscon.h>
13+#include <linux/slab.h>
14+
15+#include <dt-bindings/clock/at91.h>
16+
17+#include "pmc.h"
18+
19+#define SAMA7G5_INIT_TABLE(_table, _count) \
20+ do { \
21+ u8 _i; \
22+ for (_i = 0; _i < (_count); _i++) \
23+ (_table)[_i] = _i; \
24+ } while (0)
25+
26+#define SAMA7G5_FILL_TABLE(_to, _from, _count) \
27+ do { \
28+ u8 _i; \
29+ for (_i = 0; _i < (_count); _i++) { \
30+ (_to)[_i] = (_from)[_i]; \
31+ } \
32+ } while (0)
33+
34+static DEFINE_SPINLOCK(pmc_pll_lock);
35+static DEFINE_SPINLOCK(pmc_mckX_lock);
36+
37+/**
38+ * PLL clocks identifiers
39+ * @PLL_ID_CPU: CPU PLL identifier
40+ * @PLL_ID_SYS: System PLL identifier
41+ * @PLL_ID_DDR: DDR PLL identifier
42+ * @PLL_ID_IMG: Image subsystem PLL identifier
43+ * @PLL_ID_BAUD: Baud PLL identifier
44+ * @PLL_ID_AUDIO: Audio PLL identifier
45+ * @PLL_ID_ETH: Ethernet PLL identifier
46+ */
47+enum pll_ids {
48+ PLL_ID_CPU,
49+ PLL_ID_SYS,
50+ PLL_ID_DDR,
51+ PLL_ID_IMG,
52+ PLL_ID_BAUD,
53+ PLL_ID_AUDIO,
54+ PLL_ID_ETH,
55+ PLL_ID_MAX,
56+};
57+
58+/**
59+ * PLL type identifiers
60+ * @PLL_TYPE_FRAC: fractional PLL identifier
61+ * @PLL_TYPE_DIV: divider PLL identifier
62+ */
63+enum pll_type {
64+ PLL_TYPE_FRAC,
65+ PLL_TYPE_DIV,
66+};
67+
68+/* Layout for fractional PLLs. */
69+static const struct clk_pll_layout pll_layout_frac = {
70+ .mul_mask = GENMASK(31, 24),
71+ .frac_mask = GENMASK(21, 0),
72+ .mul_shift = 24,
73+ .frac_shift = 0,
74+};
75+
76+/* Layout for DIVPMC dividers. */
77+static const struct clk_pll_layout pll_layout_divpmc = {
78+ .div_mask = GENMASK(7, 0),
79+ .endiv_mask = BIT(29),
80+ .div_shift = 0,
81+ .endiv_shift = 29,
82+};
83+
84+/* Layout for DIVIO dividers. */
85+static const struct clk_pll_layout pll_layout_divio = {
86+ .div_mask = GENMASK(19, 12),
87+ .endiv_mask = BIT(30),
88+ .div_shift = 12,
89+ .endiv_shift = 30,
90+};
91+
92+/**
93+ * PLL clocks description
94+ * @n: clock name
95+ * @p: clock parent
96+ * @l: clock layout
97+ * @t: clock type
98+ * @f: true if clock is critical and cannot be disabled
99+ * @eid: export index in sama7g5->chws[] array
100+ */
101+static const struct {
102+ const char *n;
103+ const char *p;
104+ const struct clk_pll_layout *l;
105+ u8 t;
106+ u8 c;
107+ u8 eid;
108+} sama7g5_plls[][PLL_ID_MAX] = {
109+ [PLL_ID_CPU] = {
110+ { .n = "cpupll_fracck",
111+ .p = "mainck",
112+ .l = &pll_layout_frac,
113+ .t = PLL_TYPE_FRAC,
114+ .c = 1, },
115+
116+ { .n = "cpupll_divpmcck",
117+ .p = "cpupll_fracck",
118+ .l = &pll_layout_divpmc,
119+ .t = PLL_TYPE_DIV,
120+ .c = 1, },
121+ },
122+
123+ [PLL_ID_SYS] = {
124+ { .n = "syspll_fracck",
125+ .p = "mainck",
126+ .l = &pll_layout_frac,
127+ .t = PLL_TYPE_FRAC,
128+ .c = 1, },
129+
130+ { .n = "syspll_divpmcck",
131+ .p = "syspll_fracck",
132+ .l = &pll_layout_divpmc,
133+ .t = PLL_TYPE_DIV,
134+ .c = 1, },
135+ },
136+
137+ [PLL_ID_DDR] = {
138+ { .n = "ddrpll_fracck",
139+ .p = "mainck",
140+ .l = &pll_layout_frac,
141+ .t = PLL_TYPE_FRAC,
142+ .c = 1, },
143+
144+ { .n = "ddrpll_divpmcck",
145+ .p = "ddrpll_fracck",
146+ .l = &pll_layout_divpmc,
147+ .t = PLL_TYPE_DIV,
148+ .c = 1, },
149+ },
150+
151+ [PLL_ID_IMG] = {
152+ { .n = "imgpll_fracck",
153+ .p = "mainck",
154+ .l = &pll_layout_frac,
155+ .t = PLL_TYPE_FRAC, },
156+
157+ { .n = "imgpll_divpmcck",
158+ .p = "imgpll_fracck",
159+ .l = &pll_layout_divpmc,
160+ .t = PLL_TYPE_DIV, },
161+ },
162+
163+ [PLL_ID_BAUD] = {
164+ { .n = "baudpll_fracck",
165+ .p = "mainck",
166+ .l = &pll_layout_frac,
167+ .t = PLL_TYPE_FRAC, },
168+
169+ { .n = "baudpll_divpmcck",
170+ .p = "baudpll_fracck",
171+ .l = &pll_layout_divpmc,
172+ .t = PLL_TYPE_DIV, },
173+ },
174+
175+ [PLL_ID_AUDIO] = {
176+ { .n = "audiopll_fracck",
177+ .p = "main_xtal",
178+ .l = &pll_layout_frac,
179+ .t = PLL_TYPE_FRAC, },
180+
181+ { .n = "audiopll_divpmcck",
182+ .p = "audiopll_fracck",
183+ .l = &pll_layout_divpmc,
184+ .t = PLL_TYPE_DIV,
185+ .eid = PMC_I2S0_MUX, },
186+
187+ { .n = "audiopll_diviock",
188+ .p = "audiopll_fracck",
189+ .l = &pll_layout_divio,
190+ .t = PLL_TYPE_DIV,
191+ .eid = PMC_I2S1_MUX, },
192+ },
193+
194+ [PLL_ID_ETH] = {
195+ { .n = "ethpll_fracck",
196+ .p = "main_xtal",
197+ .l = &pll_layout_frac,
198+ .t = PLL_TYPE_FRAC, },
199+
200+ { .n = "ethpll_divpmcck",
201+ .p = "ethpll_fracck",
202+ .l = &pll_layout_divpmc,
203+ .t = PLL_TYPE_DIV, },
204+ },
205+};
206+
207+/**
208+ * Master clock (MCK[1..4]) description
209+ * @n: clock name
210+ * @ep: extra parents names array
211+ * @ep_chg_chg_id: index in parents array that specifies the changeable
212+ * parent
213+ * @ep_count: extra parents count
214+ * @ep_mux_table: mux table for extra parents
215+ * @id: clock id
216+ * @c: true if clock is critical and cannot be disabled
217+ */
218+static const struct {
219+ const char *n;
220+ const char *ep[4];
221+ int ep_chg_id;
222+ u8 ep_count;
223+ u8 ep_mux_table[4];
224+ u8 id;
225+ u8 c;
226+} sama7g5_mckx[] = {
227+ { .n = "mck1",
228+ .id = 1,
229+ .ep = { "syspll_divpmcck", },
230+ .ep_mux_table = { 5, },
231+ .ep_count = 1,
232+ .ep_chg_id = INT_MIN,
233+ .c = 1, },
234+
235+ { .n = "mck2",
236+ .id = 2,
237+ .ep = { "ddrpll_divpmcck", },
238+ .ep_mux_table = { 6, },
239+ .ep_count = 1,
240+ .ep_chg_id = INT_MIN,
241+ .c = 1, },
242+
243+ { .n = "mck3",
244+ .id = 3,
245+ .ep = { "syspll_divpmcck", "ddrpll_divpmcck", "imgpll_divpmcck", },
246+ .ep_mux_table = { 5, 6, 7, },
247+ .ep_count = 3,
248+ .ep_chg_id = 6, },
249+
250+ { .n = "mck4",
251+ .id = 4,
252+ .ep = { "syspll_divpmcck", },
253+ .ep_mux_table = { 5, },
254+ .ep_count = 1,
255+ .ep_chg_id = INT_MIN,
256+ .c = 1, },
257+};
258+
259+/**
260+ * System clock description
261+ * @n: clock name
262+ * @p: clock parent name
263+ * @id: clock id
264+ */
265+static const struct {
266+ const char *n;
267+ const char *p;
268+ u8 id;
269+} sama7g5_systemck[] = {
270+ { .n = "pck0", .p = "prog0", .id = 8, },
271+ { .n = "pck1", .p = "prog1", .id = 9, },
272+ { .n = "pck2", .p = "prog2", .id = 10, },
273+ { .n = "pck3", .p = "prog3", .id = 11, },
274+ { .n = "pck4", .p = "prog4", .id = 12, },
275+ { .n = "pck5", .p = "prog5", .id = 13, },
276+ { .n = "pck6", .p = "prog6", .id = 14, },
277+ { .n = "pck7", .p = "prog7", .id = 15, },
278+};
279+
280+/* Mux table for programmable clocks. */
281+static u32 sama7g5_prog_mux_table[] = { 0, 1, 2, 3, 5, 6, 7, 8, 9, 10, };
282+
283+/**
284+ * Peripheral clock description
285+ * @n: clock name
286+ * @p: clock parent name
287+ * @r: clock range values
288+ * @id: clock id
289+ * @chgp: index in parent array of the changeable parent
290+ */
291+static const struct {
292+ const char *n;
293+ const char *p;
294+ struct clk_range r;
295+ u8 chgp;
296+ u8 id;
297+} sama7g5_periphck[] = {
298+ { .n = "pioA_clk", .p = "mck0", .id = 11, },
299+ { .n = "sfr_clk", .p = "mck1", .id = 19, },
300+ { .n = "hsmc_clk", .p = "mck1", .id = 21, },
301+ { .n = "xdmac0_clk", .p = "mck1", .id = 22, },
302+ { .n = "xdmac1_clk", .p = "mck1", .id = 23, },
303+ { .n = "xdmac2_clk", .p = "mck1", .id = 24, },
304+ { .n = "acc_clk", .p = "mck1", .id = 25, },
305+ { .n = "aes_clk", .p = "mck1", .id = 27, },
306+ { .n = "tzaesbasc_clk", .p = "mck1", .id = 28, },
307+ { .n = "asrc_clk", .p = "mck1", .id = 30, .r = { .max = 200000000, }, },
308+ { .n = "cpkcc_clk", .p = "mck0", .id = 32, },
309+ { .n = "csi_clk", .p = "mck3", .id = 33, .r = { .max = 266000000, }, .chgp = 1, },
310+ { .n = "csi2dc_clk", .p = "mck3", .id = 34, .r = { .max = 266000000, }, .chgp = 1, },
311+ { .n = "eic_clk", .p = "mck1", .id = 37, },
312+ { .n = "flex0_clk", .p = "mck1", .id = 38, },
313+ { .n = "flex1_clk", .p = "mck1", .id = 39, },
314+ { .n = "flex2_clk", .p = "mck1", .id = 40, },
315+ { .n = "flex3_clk", .p = "mck1", .id = 41, },
316+ { .n = "flex4_clk", .p = "mck1", .id = 42, },
317+ { .n = "flex5_clk", .p = "mck1", .id = 43, },
318+ { .n = "flex6_clk", .p = "mck1", .id = 44, },
319+ { .n = "flex7_clk", .p = "mck1", .id = 45, },
320+ { .n = "flex8_clk", .p = "mck1", .id = 46, },
321+ { .n = "flex9_clk", .p = "mck1", .id = 47, },
322+ { .n = "flex10_clk", .p = "mck1", .id = 48, },
323+ { .n = "flex11_clk", .p = "mck1", .id = 49, },
324+ { .n = "gmac0_clk", .p = "mck1", .id = 51, },
325+ { .n = "gmac1_clk", .p = "mck1", .id = 52, },
326+ { .n = "icm_clk", .p = "mck1", .id = 55, },
327+ { .n = "isc_clk", .p = "mck3", .id = 56, .r = { .max = 266000000, }, .chgp = 1, },
328+ { .n = "i2smcc0_clk", .p = "mck1", .id = 57, .r = { .max = 200000000, }, },
329+ { .n = "i2smcc1_clk", .p = "mck1", .id = 58, .r = { .max = 200000000, }, },
330+ { .n = "matrix_clk", .p = "mck1", .id = 60, },
331+ { .n = "mcan0_clk", .p = "mck1", .id = 61, .r = { .max = 200000000, }, },
332+ { .n = "mcan1_clk", .p = "mck1", .id = 62, .r = { .max = 200000000, }, },
333+ { .n = "mcan2_clk", .p = "mck1", .id = 63, .r = { .max = 200000000, }, },
334+ { .n = "mcan3_clk", .p = "mck1", .id = 64, .r = { .max = 200000000, }, },
335+ { .n = "mcan4_clk", .p = "mck1", .id = 65, .r = { .max = 200000000, }, },
336+ { .n = "mcan5_clk", .p = "mck1", .id = 66, .r = { .max = 200000000, }, },
337+ { .n = "pdmc0_clk", .p = "mck1", .id = 68, .r = { .max = 200000000, }, },
338+ { .n = "pdmc1_clk", .p = "mck1", .id = 69, .r = { .max = 200000000, }, },
339+ { .n = "pit64b0_clk", .p = "mck1", .id = 70, },
340+ { .n = "pit64b1_clk", .p = "mck1", .id = 71, },
341+ { .n = "pit64b2_clk", .p = "mck1", .id = 72, },
342+ { .n = "pit64b3_clk", .p = "mck1", .id = 73, },
343+ { .n = "pit64b4_clk", .p = "mck1", .id = 74, },
344+ { .n = "pit64b5_clk", .p = "mck1", .id = 75, },
345+ { .n = "pwm_clk", .p = "mck1", .id = 77, },
346+ { .n = "qspi0_clk", .p = "mck1", .id = 78, },
347+ { .n = "qspi1_clk", .p = "mck1", .id = 79, },
348+ { .n = "sdmmc0_clk", .p = "mck1", .id = 80, },
349+ { .n = "sdmmc1_clk", .p = "mck1", .id = 81, },
350+ { .n = "sdmmc2_clk", .p = "mck1", .id = 82, },
351+ { .n = "sha_clk", .p = "mck1", .id = 83, },
352+ { .n = "spdifrx_clk", .p = "mck1", .id = 84, .r = { .max = 200000000, }, },
353+ { .n = "spdiftx_clk", .p = "mck1", .id = 85, .r = { .max = 200000000, }, },
354+ { .n = "ssc0_clk", .p = "mck1", .id = 86, .r = { .max = 200000000, }, },
355+ { .n = "ssc1_clk", .p = "mck1", .id = 87, .r = { .max = 200000000, }, },
356+ { .n = "tcb0_ch0_clk", .p = "mck1", .id = 88, .r = { .max = 200000000, }, },
357+ { .n = "tcb0_ch1_clk", .p = "mck1", .id = 89, .r = { .max = 200000000, }, },
358+ { .n = "tcb0_ch2_clk", .p = "mck1", .id = 90, .r = { .max = 200000000, }, },
359+ { .n = "tcb1_ch0_clk", .p = "mck1", .id = 91, .r = { .max = 200000000, }, },
360+ { .n = "tcb1_ch1_clk", .p = "mck1", .id = 92, .r = { .max = 200000000, }, },
361+ { .n = "tcb1_ch2_clk", .p = "mck1", .id = 93, .r = { .max = 200000000, }, },
362+ { .n = "tcpca_clk", .p = "mck1", .id = 94, },
363+ { .n = "tcpcb_clk", .p = "mck1", .id = 95, },
364+ { .n = "tdes_clk", .p = "mck1", .id = 96, },
365+ { .n = "trng_clk", .p = "mck1", .id = 97, },
366+ { .n = "udphsa_clk", .p = "mck1", .id = 104, },
367+ { .n = "udphsb_clk", .p = "mck1", .id = 105, },
368+ { .n = "uhphs_clk", .p = "mck1", .id = 106, },
369+};
370+
371+/**
372+ * Generic clock description
373+ * @n: clock name
374+ * @pp: PLL parents
375+ * @pp_mux_table: PLL parents mux table
376+ * @r: clock output range
377+ * @pp_chg_id: id in parrent array of changeable PLL parent
378+ * @pp_count: PLL parents count
379+ * @id: clock id
380+ */
381+static const struct {
382+ const char *n;
383+ const char *pp[8];
384+ const char pp_mux_table[8];
385+ struct clk_range r;
386+ int pp_chg_id;
387+ u8 pp_count;
388+ u8 id;
389+} sama7g5_gck[] = {
390+ { .n = "adc_gclk",
391+ .id = 26,
392+ .r = { .max = 100000000, },
393+ .pp = { "syspll_divpmcck", "imgpll_divpmcck", "audiopll_divpmcck", },
394+ .pp_mux_table = { 5, 7, 9, },
395+ .pp_count = 3,
396+ .pp_chg_id = INT_MIN, },
397+
398+ { .n = "asrc_gclk",
399+ .id = 30,
400+ .r = { .max = 200000000 },
401+ .pp = { "audiopll_divpmcck", },
402+ .pp_mux_table = { 9, },
403+ .pp_count = 1,
404+ .pp_chg_id = 4, },
405+
406+ { .n = "csi_gclk",
407+ .id = 33,
408+ .r = { .max = 27000000 },
409+ .pp = { "ddrpll_divpmcck", "imgpll_divpmcck", },
410+ .pp_mux_table = { 6, 7, },
411+ .pp_count = 2,
412+ .pp_chg_id = INT_MIN, },
413+
414+ { .n = "flex0_gclk",
415+ .id = 38,
416+ .r = { .max = 200000000 },
417+ .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
418+ .pp_mux_table = { 5, 8, },
419+ .pp_count = 2,
420+ .pp_chg_id = INT_MIN, },
421+
422+ { .n = "flex1_gclk",
423+ .id = 39,
424+ .r = { .max = 200000000 },
425+ .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
426+ .pp_mux_table = { 5, 8, },
427+ .pp_count = 2,
428+ .pp_chg_id = INT_MIN, },
429+
430+ { .n = "flex2_gclk",
431+ .id = 40,
432+ .r = { .max = 200000000 },
433+ .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
434+ .pp_mux_table = { 5, 8, },
435+ .pp_count = 2,
436+ .pp_chg_id = INT_MIN, },
437+
438+ { .n = "flex3_gclk",
439+ .id = 41,
440+ .r = { .max = 200000000 },
441+ .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
442+ .pp_mux_table = { 5, 8, },
443+ .pp_count = 2,
444+ .pp_chg_id = INT_MIN, },
445+
446+ { .n = "flex4_gclk",
447+ .id = 42,
448+ .r = { .max = 200000000 },
449+ .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
450+ .pp_mux_table = { 5, 8, },
451+ .pp_count = 2,
452+ .pp_chg_id = INT_MIN, },
453+
454+ { .n = "flex5_gclk",
455+ .id = 43,
456+ .r = { .max = 200000000 },
457+ .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
458+ .pp_mux_table = { 5, 8, },
459+ .pp_count = 2,
460+ .pp_chg_id = INT_MIN, },
461+
462+ { .n = "flex6_gclk",
463+ .id = 44,
464+ .r = { .max = 200000000 },
465+ .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
466+ .pp_mux_table = { 5, 8, },
467+ .pp_count = 2,
468+ .pp_chg_id = INT_MIN, },
469+
470+ { .n = "flex7_gclk",
471+ .id = 45,
472+ .r = { .max = 200000000 },
473+ .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
474+ .pp_mux_table = { 5, 8, },
475+ .pp_count = 2,
476+ .pp_chg_id = INT_MIN, },
477+
478+ { .n = "flex8_gclk",
479+ .id = 46,
480+ .r = { .max = 200000000 },
481+ .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
482+ .pp_mux_table = { 5, 8, },
483+ .pp_count = 2,
484+ .pp_chg_id = INT_MIN, },
485+
486+ { .n = "flex9_gclk",
487+ .id = 47,
488+ .r = { .max = 200000000 },
489+ .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
490+ .pp_mux_table = { 5, 8, },
491+ .pp_count = 2,
492+ .pp_chg_id = INT_MIN, },
493+
494+ { .n = "flex10_gclk",
495+ .id = 48,
496+ .r = { .max = 200000000 },
497+ .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
498+ .pp_mux_table = { 5, 8, },
499+ .pp_count = 2,
500+ .pp_chg_id = INT_MIN, },
501+
502+ { .n = "flex11_gclk",
503+ .id = 49,
504+ .r = { .max = 200000000 },
505+ .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
506+ .pp_mux_table = { 5, 8, },
507+ .pp_count = 2,
508+ .pp_chg_id = INT_MIN, },
509+
510+ { .n = "gmac0_gclk",
511+ .id = 51,
512+ .r = { .max = 125000000 },
513+ .pp = { "ethpll_divpmcck", },
514+ .pp_mux_table = { 10, },
515+ .pp_count = 1,
516+ .pp_chg_id = 4, },
517+
518+ { .n = "gmac1_gclk",
519+ .id = 52,
520+ .r = { .max = 50000000 },
521+ .pp = { "ethpll_divpmcck", },
522+ .pp_mux_table = { 10, },
523+ .pp_count = 1,
524+ .pp_chg_id = INT_MIN, },
525+
526+ { .n = "gmac0_tsu_gclk",
527+ .id = 53,
528+ .r = { .max = 300000000 },
529+ .pp = { "audiopll_divpmcck", "ethpll_divpmcck", },
530+ .pp_mux_table = { 9, 10, },
531+ .pp_count = 2,
532+ .pp_chg_id = INT_MIN, },
533+
534+ { .n = "gmac1_tsu_gclk",
535+ .id = 54,
536+ .r = { .max = 300000000 },
537+ .pp = { "audiopll_divpmcck", "ethpll_divpmcck", },
538+ .pp_mux_table = { 9, 10, },
539+ .pp_count = 2,
540+ .pp_chg_id = INT_MIN, },
541+
542+ { .n = "i2smcc0_gclk",
543+ .id = 57,
544+ .r = { .max = 100000000 },
545+ .pp = { "syspll_divpmcck", "audiopll_divpmcck", },
546+ .pp_mux_table = { 5, 9, },
547+ .pp_count = 2,
548+ .pp_chg_id = 5, },
549+
550+ { .n = "i2smcc1_gclk",
551+ .id = 58,
552+ .r = { .max = 100000000 },
553+ .pp = { "syspll_divpmcck", "audiopll_divpmcck", },
554+ .pp_mux_table = { 5, 9, },
555+ .pp_count = 2,
556+ .pp_chg_id = 5, },
557+
558+ { .n = "mcan0_gclk",
559+ .id = 61,
560+ .r = { .max = 200000000 },
561+ .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
562+ .pp_mux_table = { 5, 8, },
563+ .pp_count = 2,
564+ .pp_chg_id = INT_MIN, },
565+
566+ { .n = "mcan1_gclk",
567+ .id = 62,
568+ .r = { .max = 200000000 },
569+ .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
570+ .pp_mux_table = { 5, 8, },
571+ .pp_count = 2,
572+ .pp_chg_id = INT_MIN, },
573+
574+ { .n = "mcan2_gclk",
575+ .id = 63,
576+ .r = { .max = 200000000 },
577+ .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
578+ .pp_mux_table = { 5, 8, },
579+ .pp_count = 2,
580+ .pp_chg_id = INT_MIN, },
581+
582+ { .n = "mcan3_gclk",
583+ .id = 64,
584+ .r = { .max = 200000000 },
585+ .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
586+ .pp_mux_table = { 5, 8, },
587+ .pp_count = 2,
588+ .pp_chg_id = INT_MIN, },
589+
590+ { .n = "mcan4_gclk",
591+ .id = 65,
592+ .r = { .max = 200000000 },
593+ .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
594+ .pp_mux_table = { 5, 8, },
595+ .pp_count = 2,
596+ .pp_chg_id = INT_MIN, },
597+
598+ { .n = "mcan5_gclk",
599+ .id = 66,
600+ .r = { .max = 200000000 },
601+ .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
602+ .pp_mux_table = { 5, 8, },
603+ .pp_count = 2,
604+ .pp_chg_id = INT_MIN, },
605+
606+ { .n = "pdmc0_gclk",
607+ .id = 68,
608+ .r = { .max = 50000000 },
609+ .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
610+ .pp_mux_table = { 5, 8, },
611+ .pp_count = 2,
612+ .pp_chg_id = INT_MIN, },
613+
614+ { .n = "pdmc1_gclk",
615+ .id = 69,
616+ .r = { .max = 50000000, },
617+ .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
618+ .pp_mux_table = { 5, 8, },
619+ .pp_count = 2,
620+ .pp_chg_id = INT_MIN, },
621+
622+ { .n = "pit64b0_gclk",
623+ .id = 70,
624+ .r = { .max = 200000000 },
625+ .pp = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck",
626+ "audiopll_divpmcck", "ethpll_divpmcck", },
627+ .pp_mux_table = { 5, 7, 8, 9, 10, },
628+ .pp_count = 5,
629+ .pp_chg_id = INT_MIN, },
630+
631+ { .n = "pit64b1_gclk",
632+ .id = 71,
633+ .r = { .max = 200000000 },
634+ .pp = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck",
635+ "audiopll_divpmcck", "ethpll_divpmcck", },
636+ .pp_mux_table = { 5, 7, 8, 9, 10, },
637+ .pp_count = 5,
638+ .pp_chg_id = INT_MIN, },
639+
640+ { .n = "pit64b2_gclk",
641+ .id = 72,
642+ .r = { .max = 200000000 },
643+ .pp = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck",
644+ "audiopll_divpmcck", "ethpll_divpmcck", },
645+ .pp_mux_table = { 5, 7, 8, 9, 10, },
646+ .pp_count = 5,
647+ .pp_chg_id = INT_MIN, },
648+
649+ { .n = "pit64b3_gclk",
650+ .id = 73,
651+ .r = { .max = 200000000 },
652+ .pp = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck",
653+ "audiopll_divpmcck", "ethpll_divpmcck", },
654+ .pp_mux_table = { 5, 7, 8, 9, 10, },
655+ .pp_count = 5,
656+ .pp_chg_id = INT_MIN, },
657+
658+ { .n = "pit64b4_gclk",
659+ .id = 74,
660+ .r = { .max = 200000000 },
661+ .pp = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck",
662+ "audiopll_divpmcck", "ethpll_divpmcck", },
663+ .pp_mux_table = { 5, 7, 8, 9, 10, },
664+ .pp_count = 5,
665+ .pp_chg_id = INT_MIN, },
666+
667+ { .n = "pit64b5_gclk",
668+ .id = 75,
669+ .r = { .max = 200000000 },
670+ .pp = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck",
671+ "audiopll_divpmcck", "ethpll_divpmcck", },
672+ .pp_mux_table = { 5, 7, 8, 9, 10, },
673+ .pp_count = 5,
674+ .pp_chg_id = INT_MIN, },
675+
676+ { .n = "qspi0_gclk",
677+ .id = 78,
678+ .r = { .max = 200000000 },
679+ .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
680+ .pp_mux_table = { 5, 8, },
681+ .pp_count = 2,
682+ .pp_chg_id = INT_MIN, },
683+
684+ { .n = "qspi1_gclk",
685+ .id = 79,
686+ .r = { .max = 200000000 },
687+ .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
688+ .pp_mux_table = { 5, 8, },
689+ .pp_count = 2,
690+ .pp_chg_id = INT_MIN, },
691+
692+ { .n = "sdmmc0_gclk",
693+ .id = 80,
694+ .r = { .max = 208000000 },
695+ .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
696+ .pp_mux_table = { 5, 8, },
697+ .pp_count = 2,
698+ .pp_chg_id = 5, },
699+
700+ { .n = "sdmmc1_gclk",
701+ .id = 81,
702+ .r = { .max = 208000000 },
703+ .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
704+ .pp_mux_table = { 5, 8, },
705+ .pp_count = 2,
706+ .pp_chg_id = 5, },
707+
708+ { .n = "sdmmc2_gclk",
709+ .id = 82,
710+ .r = { .max = 208000000 },
711+ .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
712+ .pp_mux_table = { 5, 8, },
713+ .pp_count = 2,
714+ .pp_chg_id = 5, },
715+
716+ { .n = "spdifrx_gclk",
717+ .id = 84,
718+ .r = { .max = 150000000 },
719+ .pp = { "syspll_divpmcck", "audiopll_divpmcck", },
720+ .pp_mux_table = { 5, 9, },
721+ .pp_count = 2,
722+ .pp_chg_id = 5, },
723+
724+ { .n = "spdiftx_gclk",
725+ .id = 85,
726+ .r = { .max = 25000000 },
727+ .pp = { "syspll_divpmcck", "audiopll_divpmcck", },
728+ .pp_mux_table = { 5, 9, },
729+ .pp_count = 2,
730+ .pp_chg_id = 5, },
731+
732+ { .n = "tcb0_ch0_gclk",
733+ .id = 88,
734+ .r = { .max = 200000000 },
735+ .pp = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck",
736+ "audiopll_divpmcck", "ethpll_divpmcck", },
737+ .pp_mux_table = { 5, 7, 8, 9, 10, },
738+ .pp_count = 5,
739+ .pp_chg_id = INT_MIN, },
740+
741+ { .n = "tcb1_ch0_gclk",
742+ .id = 91,
743+ .r = { .max = 200000000 },
744+ .pp = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck",
745+ "audiopll_divpmcck", "ethpll_divpmcck", },
746+ .pp_mux_table = { 5, 7, 8, 9, 10, },
747+ .pp_count = 5,
748+ .pp_chg_id = INT_MIN, },
749+
750+ { .n = "tcpca_gclk",
751+ .id = 94,
752+ .r = { .max = 32768, },
753+ .pp_chg_id = INT_MIN, },
754+
755+ { .n = "tcpcb_gclk",
756+ .id = 95,
757+ .r = { .max = 32768, },
758+ .pp_chg_id = INT_MIN, },
759+};
760+
761+/* PLL output range. */
762+static const struct clk_range pll_outputs[] = {
763+ { .min = 2343750, .max = 1200000000 },
764+};
765+
766+/* PLL characteristics. */
767+static const struct clk_pll_characteristics pll_characteristics = {
768+ .input = { .min = 12000000, .max = 50000000 },
769+ .num_output = ARRAY_SIZE(pll_outputs),
770+ .output = pll_outputs,
771+};
772+
773+/* MCK0 characteristics. */
774+static const struct clk_master_characteristics mck0_characteristics = {
775+ .output = { .min = 140000000, .max = 200000000 },
776+ .divisors = { 1, 2, 4, 3 },
777+ .have_div3_pres = 1,
778+};
779+
780+/* MCK0 layout. */
781+static const struct clk_master_layout mck0_layout = {
782+ .mask = 0x373,
783+ .pres_shift = 4,
784+ .offset = 0x28,
785+};
786+
787+/* Programmable clock layout. */
788+static const struct clk_programmable_layout programmable_layout = {
789+ .pres_mask = 0xff,
790+ .pres_shift = 8,
791+ .css_mask = 0x1f,
792+ .have_slck_mck = 0,
793+ .is_pres_direct = 1,
794+};
795+
796+/* Peripheral clock layout. */
797+static const struct clk_pcr_layout sama7g5_pcr_layout = {
798+ .offset = 0x88,
799+ .cmd = BIT(31),
800+ .gckcss_mask = GENMASK(12, 8),
801+ .pid_mask = GENMASK(6, 0),
802+};
803+
804+static void __init sama7g5_pmc_setup(struct device_node *np)
805+{
806+ const char *td_slck_name, *md_slck_name, *mainxtal_name;
807+ struct pmc_data *sama7g5_pmc;
808+ const char *parent_names[10];
809+ void **alloc_mem = NULL;
810+ int alloc_mem_size = 0;
811+ struct regmap *regmap;
812+ struct clk_hw *hw;
813+ bool bypass;
814+ int i, j;
815+
816+ i = of_property_match_string(np, "clock-names", "td_slck");
817+ if (i < 0)
818+ return;
819+
820+ td_slck_name = of_clk_get_parent_name(np, i);
821+
822+ i = of_property_match_string(np, "clock-names", "md_slck");
823+ if (i < 0)
824+ return;
825+
826+ md_slck_name = of_clk_get_parent_name(np, i);
827+
828+ i = of_property_match_string(np, "clock-names", "main_xtal");
829+ if (i < 0)
830+ return;
831+
832+ mainxtal_name = of_clk_get_parent_name(np, i);
833+
834+ regmap = device_node_to_regmap(np);
835+ if (IS_ERR(regmap))
836+ return;
837+
838+ sama7g5_pmc = pmc_data_allocate(PMC_I2S1_MUX + 1,
839+ nck(sama7g5_systemck),
840+ nck(sama7g5_periphck),
841+ nck(sama7g5_gck));
842+ if (!sama7g5_pmc)
843+ return;
844+
845+ alloc_mem = kmalloc(sizeof(void *) *
846+ (ARRAY_SIZE(sama7g5_mckx) + ARRAY_SIZE(sama7g5_gck)),
847+ GFP_KERNEL);
848+ if (!alloc_mem)
849+ goto err_free;
850+
851+ hw = at91_clk_register_main_rc_osc(regmap, "main_rc_osc", 12000000,
852+ 50000000);
853+ if (IS_ERR(hw))
854+ goto err_free;
855+
856+ bypass = of_property_read_bool(np, "atmel,osc-bypass");
857+
858+ hw = at91_clk_register_main_osc(regmap, "main_osc", mainxtal_name,
859+ bypass);
860+ if (IS_ERR(hw))
861+ goto err_free;
862+
863+ parent_names[0] = "main_rc_osc";
864+ parent_names[1] = "main_osc";
865+ hw = at91_clk_register_sam9x5_main(regmap, "mainck", parent_names, 2);
866+ if (IS_ERR(hw))
867+ goto err_free;
868+
869+ sama7g5_pmc->chws[PMC_MAIN] = hw;
870+
871+ for (i = 0; i < PLL_ID_MAX; i++) {
872+ for (j = 0; j < 3; j++) {
873+ struct clk_hw *parent_hw;
874+
875+ if (!sama7g5_plls[i][j].n)
876+ continue;
877+
878+ switch (sama7g5_plls[i][j].t) {
879+ case PLL_TYPE_FRAC:
880+ if (!strcmp(sama7g5_plls[i][j].p, "mainck"))
881+ parent_hw = sama7g5_pmc->chws[PMC_MAIN];
882+ else
883+ parent_hw = __clk_get_hw(of_clk_get_by_name(np,
884+ sama7g5_plls[i][j].p));
885+
886+ hw = sam9x60_clk_register_frac_pll(regmap,
887+ &pmc_pll_lock, sama7g5_plls[i][j].n,
888+ sama7g5_plls[i][j].p, parent_hw, i,
889+ &pll_characteristics,
890+ sama7g5_plls[i][j].l,
891+ sama7g5_plls[i][j].c);
892+ break;
893+
894+ case PLL_TYPE_DIV:
895+ hw = sam9x60_clk_register_div_pll(regmap,
896+ &pmc_pll_lock, sama7g5_plls[i][j].n,
897+ sama7g5_plls[i][j].p, i,
898+ &pll_characteristics,
899+ sama7g5_plls[i][j].l,
900+ sama7g5_plls[i][j].c);
901+ break;
902+
903+ default:
904+ continue;
905+ }
906+
907+ if (IS_ERR(hw))
908+ goto err_free;
909+
910+ if (sama7g5_plls[i][j].eid)
911+ sama7g5_pmc->chws[sama7g5_plls[i][j].eid] = hw;
912+ }
913+ }
914+
915+ parent_names[0] = md_slck_name;
916+ parent_names[1] = "mainck";
917+ parent_names[2] = "cpupll_divpmcck";
918+ parent_names[3] = "syspll_divpmcck";
919+ hw = at91_clk_register_master(regmap, "mck0", 4, parent_names,
920+ &mck0_layout, &mck0_characteristics);
921+ if (IS_ERR(hw))
922+ goto err_free;
923+
924+ sama7g5_pmc->chws[PMC_MCK] = hw;
925+
926+ parent_names[0] = md_slck_name;
927+ parent_names[1] = td_slck_name;
928+ parent_names[2] = "mainck";
929+ parent_names[3] = "mck0";
930+ for (i = 0; i < ARRAY_SIZE(sama7g5_mckx); i++) {
931+ u8 num_parents = 4 + sama7g5_mckx[i].ep_count;
932+ u32 *mux_table;
933+
934+ mux_table = kmalloc_array(num_parents, sizeof(*mux_table),
935+ GFP_KERNEL);
936+ if (!mux_table)
937+ goto err_free;
938+
939+ SAMA7G5_INIT_TABLE(mux_table, 4);
940+ SAMA7G5_FILL_TABLE(&mux_table[4], sama7g5_mckx[i].ep_mux_table,
941+ sama7g5_mckx[i].ep_count);
942+ SAMA7G5_FILL_TABLE(&parent_names[4], sama7g5_mckx[i].ep,
943+ sama7g5_mckx[i].ep_count);
944+
945+ hw = at91_clk_sama7g5_register_master(regmap, sama7g5_mckx[i].n,
946+ num_parents, parent_names, mux_table,
947+ &pmc_mckX_lock, sama7g5_mckx[i].id,
948+ sama7g5_mckx[i].c,
949+ sama7g5_mckx[i].ep_chg_id);
950+ if (IS_ERR(hw))
951+ goto err_free;
952+
953+ alloc_mem[alloc_mem_size++] = mux_table;
954+ }
955+
956+ hw = at91_clk_sama7g5_register_utmi(regmap, "utmick", "main_xtal");
957+ if (IS_ERR(hw))
958+ goto err_free;
959+
960+ sama7g5_pmc->chws[PMC_UTMI] = hw;
961+
962+ parent_names[0] = md_slck_name;
963+ parent_names[1] = td_slck_name;
964+ parent_names[2] = "mainck";
965+ parent_names[3] = "mck0";
966+ parent_names[4] = "syspll_divpmcck";
967+ parent_names[5] = "ddrpll_divpmcck";
968+ parent_names[6] = "imgpll_divpmcck";
969+ parent_names[7] = "baudpll_divpmcck";
970+ parent_names[8] = "audiopll_divpmcck";
971+ parent_names[9] = "ethpll_divpmcck";
972+ for (i = 0; i < 8; i++) {
973+ char name[6];
974+
975+ snprintf(name, sizeof(name), "prog%d", i);
976+
977+ hw = at91_clk_register_programmable(regmap, name, parent_names,
978+ 10, i,
979+ &programmable_layout,
980+ sama7g5_prog_mux_table);
981+ if (IS_ERR(hw))
982+ goto err_free;
983+ }
984+
985+ for (i = 0; i < ARRAY_SIZE(sama7g5_systemck); i++) {
986+ hw = at91_clk_register_system(regmap, sama7g5_systemck[i].n,
987+ sama7g5_systemck[i].p,
988+ sama7g5_systemck[i].id);
989+ if (IS_ERR(hw))
990+ goto err_free;
991+
992+ sama7g5_pmc->shws[sama7g5_systemck[i].id] = hw;
993+ }
994+
995+ for (i = 0; i < ARRAY_SIZE(sama7g5_periphck); i++) {
996+ hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock,
997+ &sama7g5_pcr_layout,
998+ sama7g5_periphck[i].n,
999+ sama7g5_periphck[i].p,
1000+ sama7g5_periphck[i].id,
1001+ &sama7g5_periphck[i].r,
1002+ sama7g5_periphck[i].chgp ? 0 :
1003+ INT_MIN);
1004+ if (IS_ERR(hw))
1005+ goto err_free;
1006+
1007+ sama7g5_pmc->phws[sama7g5_periphck[i].id] = hw;
1008+ }
1009+
1010+ parent_names[0] = md_slck_name;
1011+ parent_names[1] = td_slck_name;
1012+ parent_names[2] = "mainck";
1013+ parent_names[3] = "mck0";
1014+ for (i = 0; i < ARRAY_SIZE(sama7g5_gck); i++) {
1015+ u8 num_parents = 4 + sama7g5_gck[i].pp_count;
1016+ u32 *mux_table;
1017+
1018+ mux_table = kmalloc_array(num_parents, sizeof(*mux_table),
1019+ GFP_KERNEL);
1020+ if (!mux_table)
1021+ goto err_free;
1022+
1023+ SAMA7G5_INIT_TABLE(mux_table, 4);
1024+ SAMA7G5_FILL_TABLE(&mux_table[4], sama7g5_gck[i].pp_mux_table,
1025+ sama7g5_gck[i].pp_count);
1026+ SAMA7G5_FILL_TABLE(&parent_names[4], sama7g5_gck[i].pp,
1027+ sama7g5_gck[i].pp_count);
1028+
1029+ hw = at91_clk_register_generated(regmap, &pmc_pcr_lock,
1030+ &sama7g5_pcr_layout,
1031+ sama7g5_gck[i].n,
1032+ parent_names, mux_table,
1033+ num_parents,
1034+ sama7g5_gck[i].id,
1035+ &sama7g5_gck[i].r,
1036+ sama7g5_gck[i].pp_chg_id);
1037+ if (IS_ERR(hw))
1038+ goto err_free;
1039+
1040+ sama7g5_pmc->ghws[sama7g5_gck[i].id] = hw;
1041+ alloc_mem[alloc_mem_size++] = mux_table;
1042+ }
1043+
1044+ of_clk_add_hw_provider(np, of_clk_hw_pmc_get, sama7g5_pmc);
1045+
1046+ return;
1047+
1048+err_free:
1049+ if (alloc_mem) {
1050+ for (i = 0; i < alloc_mem_size; i++)
1051+ kfree(alloc_mem[i]);
1052+ kfree(alloc_mem);
1053+ }
1054+
1055+ pmc_data_free(sama7g5_pmc);
1056+}
1057+
1058+/* Some clks are used for a clocksource */
1059+CLK_OF_DECLARE(sama7g5_pmc, "microchip,sama7g5-pmc", sama7g5_pmc_setup);
drivers/clk/at91/sckc.c+3−2
@@ -471,8 +471,9 @@ static void __init of_sam9x60_sckc_setup(struct device_node *np) · 470 unmodified lines
471471 if (!regbase)
472472 return;
473473
474− slow_rc = clk_hw_register_fixed_rate(NULL, parent_names[0], NULL, 0,
475− 32768);
474+ slow_rc = clk_hw_register_fixed_rate_with_accuracy(NULL, parent_names[0],
475+ NULL, 0, 32768,
476+ 93750000);
476477 if (IS_ERR(slow_rc))
477478 return;
478479
drivers/clk/bcm/clk-bcm2835.c+21−4
@@ -314,6 +314,7 @@ struct bcm2835_cprman { · 313 unmodified lines
314314 struct device *dev;
315315 void __iomem *regs;
316316 spinlock_t regs_lock; /* spinlock for all clocks */
317+ unsigned int soc;
317318
318319 /*
319320 * Real names of cprman clock parents looked up through
@@ -526,6 +527,20 @@ static int bcm2835_pll_is_on(struct clk_hw *hw) · 206 unmodified lines
526527 A2W_PLL_CTRL_PRST_DISABLE;
527528 }
528529
530+static u32 bcm2835_pll_get_prediv_mask(struct bcm2835_cprman *cprman,
531+ const struct bcm2835_pll_data *data)
532+{
533+ /*
534+ * On BCM2711 there isn't a pre-divisor available in the PLL feedback
535+ * loop. Bits 13:14 of ANA1 (PLLA,PLLB,PLLC,PLLD) have been re-purposed
536+ * for to for VCO RANGE bits.
537+ */
538+ if (cprman->soc & SOC_BCM2711)
539+ return 0;
540+
541+ return data->ana->fb_prediv_mask;
542+}
543+
529544 static void bcm2835_pll_choose_ndiv_and_fdiv(unsigned long rate,
530545 unsigned long parent_rate,
531546 u32 *ndiv, u32 *fdiv)
@@ -583,7 +598,7 @@ static unsigned long bcm2835_pll_get_rate(struct clk_hw *hw, · 51 unmodified lines
583598 ndiv = (a2wctrl & A2W_PLL_CTRL_NDIV_MASK) >> A2W_PLL_CTRL_NDIV_SHIFT;
584599 pdiv = (a2wctrl & A2W_PLL_CTRL_PDIV_MASK) >> A2W_PLL_CTRL_PDIV_SHIFT;
585600 using_prediv = cprman_read(cprman, data->ana_reg_base + 4) &
586− data->ana->fb_prediv_mask;
601+ bcm2835_pll_get_prediv_mask(cprman, data);
587602
588603 if (using_prediv) {
589604 ndiv *= 2;
@@ -666,6 +681,7 @@ static int bcm2835_pll_set_rate(struct clk_hw *hw, · 76 unmodified lines
666681 struct bcm2835_pll *pll = container_of(hw, struct bcm2835_pll, hw);
667682 struct bcm2835_cprman *cprman = pll->cprman;
668683 const struct bcm2835_pll_data *data = pll->data;
684+ u32 prediv_mask = bcm2835_pll_get_prediv_mask(cprman, data);
669685 bool was_using_prediv, use_fb_prediv, do_ana_setup_first;
670686 u32 ndiv, fdiv, a2w_ctl;
671687 u32 ana[4];
@@ -683,7 +699,7 @@ static int bcm2835_pll_set_rate(struct clk_hw *hw, · 11 unmodified lines
683699 for (i = 3; i >= 0; i--)
684700 ana[i] = cprman_read(cprman, data->ana_reg_base + i * 4);
685701
686− was_using_prediv = ana[1] & data->ana->fb_prediv_mask;
702+ was_using_prediv = ana[1] & prediv_mask;
687703
688704 ana[0] &= ~data->ana->mask0;
689705 ana[0] |= data->ana->set0;
@@ -693,10 +709,10 @@ static int bcm2835_pll_set_rate(struct clk_hw *hw, · 3 unmodified lines
693709 ana[3] |= data->ana->set3;
694710
695711 if (was_using_prediv && !use_fb_prediv) {
696− ana[1] &= ~data->ana->fb_prediv_mask;
712+ ana[1] &= ~prediv_mask;
697713 do_ana_setup_first = true;
698714 } else if (!was_using_prediv && use_fb_prediv) {
699− ana[1] |= data->ana->fb_prediv_mask;
715+ ana[1] |= prediv_mask;
700716 do_ana_setup_first = false;
701717 } else {
702718 do_ana_setup_first = true;
@@ -2262,6 +2278,7 @@ static int bcm2835_clk_probe(struct platform_device *pdev) · 1559 unmodified lines
22622278 platform_set_drvdata(pdev, cprman);
22632279
22642280 cprman->onecell.num = asize;
2281+ cprman->soc = pdata->soc;
22652282 hws = cprman->onecell.hws;
22662283
22672284 for (i = 0; i < asize; i++) {
drivers/clk/bcm/clk-iproc-asiu.c+2−2
@@ -119,7 +119,7 @@ static long iproc_asiu_clk_round_rate(struct clk_hw *hw, unsigned long rate, · 118 unmodified lines
119119 if (rate == *parent_rate)
120120 return *parent_rate;
121121
122− div = DIV_ROUND_UP(*parent_rate, rate);
122+ div = DIV_ROUND_CLOSEST(*parent_rate, rate);
123123 if (div < 2)
124124 return *parent_rate;
125125
@@ -145,7 +145,7 @@ static int iproc_asiu_clk_set_rate(struct clk_hw *hw, unsigned long rate, · 19 unmodified lines
145145 return 0;
146146 }
147147
148− div = DIV_ROUND_UP(parent_rate, rate);
148+ div = DIV_ROUND_CLOSEST(parent_rate, rate);
149149 if (div < 2)
150150 return -EINVAL;
151151
drivers/clk/clk-qoriq.c+9−1
@@ -244,6 +244,14 @@ static const struct clockgen_muxinfo clockgen2_cmux_cgb = { · 243 unmodified lines
244244 },
245245 };
246246
247+static const struct clockgen_muxinfo ls1021a_cmux = {
248+ {
249+ { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 },
250+ { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
251+ { CLKSEL_VALID, CGA_PLL1, PLL_DIV4 },
252+ }
253+};
254+
247255 static const struct clockgen_muxinfo ls1028a_hwa1 = {
248256 {
249257 { CLKSEL_VALID, PLATFORM_PLL, PLL_DIV1 },
@@ -577,7 +585,7 @@ static const struct clockgen_chipinfo chipinfo[] = { · 327 unmodified lines
577585 {
578586 .compat = "fsl,ls1021a-clockgen",
579587 .cmux_groups = {
580− &t1023_cmux
588+ &ls1021a_cmux
581589 },
582590 .cmux_to_group = {
583591 0, -1
drivers/clk/clk-sparx5.c+295−0
@@ -0,0 +1,295 @@
1+// SPDX-License-Identifier: GPL-2.0-or-later
2+/*
3+ * Microchip Sparx5 SoC Clock driver.
4+ *
5+ * Copyright (c) 2019 Microchip Inc.
6+ *
7+ * Author: Lars Povlsen <lars.povlsen@microchip.com>
8+ */
9+
10+#include <linux/io.h>
11+#include <linux/module.h>
12+#include <linux/clk-provider.h>
13+#include <linux/bitfield.h>
14+#include <linux/of.h>
15+#include <linux/slab.h>
16+#include <linux/platform_device.h>
17+#include <dt-bindings/clock/microchip,sparx5.h>
18+
19+#define PLL_DIV GENMASK(7, 0)
20+#define PLL_PRE_DIV GENMASK(10, 8)
21+#define PLL_ROT_DIR BIT(11)
22+#define PLL_ROT_SEL GENMASK(13, 12)
23+#define PLL_ROT_ENA BIT(14)
24+#define PLL_CLK_ENA BIT(15)
25+
26+#define MAX_SEL 4
27+#define MAX_PRE BIT(3)
28+
29+static const u8 sel_rates[MAX_SEL] = { 0, 2*8, 2*4, 2*2 };
30+
31+static const char *clk_names[N_CLOCKS] = {
32+ "core", "ddr", "cpu2", "arm2",
33+ "aux1", "aux2", "aux3", "aux4",
34+ "synce",
35+};
36+
37+struct s5_hw_clk {
38+ struct clk_hw hw;
39+ void __iomem *reg;
40+};
41+
42+struct s5_clk_data {
43+ void __iomem *base;
44+ struct s5_hw_clk s5_hw[N_CLOCKS];
45+};
46+
47+struct s5_pll_conf {
48+ unsigned long freq;
49+ u8 div;
50+ bool rot_ena;
51+ u8 rot_sel;
52+ u8 rot_dir;
53+ u8 pre_div;
54+};
55+
56+#define to_s5_pll(hw) container_of(hw, struct s5_hw_clk, hw)
57+
58+static unsigned long s5_calc_freq(unsigned long parent_rate,
59+ const struct s5_pll_conf *conf)
60+{
61+ unsigned long rate = parent_rate / conf->div;
62+
63+ if (conf->rot_ena) {
64+ int sign = conf->rot_dir ? -1 : 1;
65+ int divt = sel_rates[conf->rot_sel] * (1 + conf->pre_div);
66+ int divb = divt + sign;
67+
68+ rate = mult_frac(rate, divt, divb);
69+ rate = roundup(rate, 1000);
70+ }
71+
72+ return rate;
73+}
74+
75+static void s5_search_fractional(unsigned long rate,
76+ unsigned long parent_rate,
77+ int div,
78+ struct s5_pll_conf *conf)
79+{
80+ struct s5_pll_conf best;
81+ ulong cur_offset, best_offset = rate;
82+ int d, i, j;
83+
84+ memset(conf, 0, sizeof(*conf));
85+ conf->div = div;
86+ conf->rot_ena = 1; /* Fractional rate */
87+
88+ for (d = 0; best_offset > 0 && d <= 1 ; d++) {
89+ conf->rot_dir = !!d;
90+ for (i = 0; best_offset > 0 && i < MAX_PRE; i++) {
91+ conf->pre_div = i;
92+ for (j = 1; best_offset > 0 && j < MAX_SEL; j++) {
93+ conf->rot_sel = j;
94+ conf->freq = s5_calc_freq(parent_rate, conf);
95+ cur_offset = abs(rate - conf->freq);
96+ if (cur_offset < best_offset) {
97+ best_offset = cur_offset;
98+ best = *conf;
99+ }
100+ }
101+ }
102+ }
103+
104+ /* Best match */
105+ *conf = best;
106+}
107+
108+static unsigned long s5_calc_params(unsigned long rate,
109+ unsigned long parent_rate,
110+ struct s5_pll_conf *conf)
111+{
112+ if (parent_rate % rate) {
113+ struct s5_pll_conf alt1, alt2;
114+ int div;
115+
116+ div = DIV_ROUND_CLOSEST_ULL(parent_rate, rate);
117+ s5_search_fractional(rate, parent_rate, div, &alt1);
118+
119+ /* Straight match? */
120+ if (alt1.freq == rate) {
121+ *conf = alt1;
122+ } else {
123+ /* Try without rounding divider */
124+ div = parent_rate / rate;
125+ if (div != alt1.div) {
126+ s5_search_fractional(rate, parent_rate, div,
127+ &alt2);
128+ /* Select the better match */
129+ if (abs(rate - alt1.freq) <
130+ abs(rate - alt2.freq))
131+ *conf = alt1;
132+ else
133+ *conf = alt2;
134+ }
135+ }
136+ } else {
137+ /* Straight fit */
138+ memset(conf, 0, sizeof(*conf));
139+ conf->div = parent_rate / rate;
140+ }
141+
142+ return conf->freq;
143+}
144+
145+static int s5_pll_enable(struct clk_hw *hw)
146+{
147+ struct s5_hw_clk *pll = to_s5_pll(hw);
148+ u32 val = readl(pll->reg);
149+
150+ val |= PLL_CLK_ENA;
151+ writel(val, pll->reg);
152+
153+ return 0;
154+}
155+
156+static void s5_pll_disable(struct clk_hw *hw)
157+{
158+ struct s5_hw_clk *pll = to_s5_pll(hw);
159+ u32 val = readl(pll->reg);
160+
161+ val &= ~PLL_CLK_ENA;
162+ writel(val, pll->reg);
163+}
164+
165+static int s5_pll_set_rate(struct clk_hw *hw,
166+ unsigned long rate,
167+ unsigned long parent_rate)
168+{
169+ struct s5_hw_clk *pll = to_s5_pll(hw);
170+ struct s5_pll_conf conf;
171+ unsigned long eff_rate;
172+ u32 val;
173+
174+ eff_rate = s5_calc_params(rate, parent_rate, &conf);
175+ if (eff_rate != rate)
176+ return -EOPNOTSUPP;
177+
178+ val = readl(pll->reg) & PLL_CLK_ENA;
179+ val |= FIELD_PREP(PLL_DIV, conf.div);
180+ if (conf.rot_ena) {
181+ val |= PLL_ROT_ENA;
182+ val |= FIELD_PREP(PLL_ROT_SEL, conf.rot_sel);
183+ val |= FIELD_PREP(PLL_PRE_DIV, conf.pre_div);
184+ if (conf.rot_dir)
185+ val |= PLL_ROT_DIR;
186+ }
187+ writel(val, pll->reg);
188+
189+ return 0;
190+}
191+
192+static unsigned long s5_pll_recalc_rate(struct clk_hw *hw,
193+ unsigned long parent_rate)
194+{
195+ struct s5_hw_clk *pll = to_s5_pll(hw);
196+ struct s5_pll_conf conf;
197+ u32 val;
198+
199+ val = readl(pll->reg);
200+
201+ if (val & PLL_CLK_ENA) {
202+ conf.div = FIELD_GET(PLL_DIV, val);
203+ conf.pre_div = FIELD_GET(PLL_PRE_DIV, val);
204+ conf.rot_ena = FIELD_GET(PLL_ROT_ENA, val);
205+ conf.rot_dir = FIELD_GET(PLL_ROT_DIR, val);
206+ conf.rot_sel = FIELD_GET(PLL_ROT_SEL, val);
207+
208+ conf.freq = s5_calc_freq(parent_rate, &conf);
209+ } else {
210+ conf.freq = 0;
211+ }
212+
213+ return conf.freq;
214+}
215+
216+static long s5_pll_round_rate(struct clk_hw *hw, unsigned long rate,
217+ unsigned long *parent_rate)
218+{
219+ struct s5_pll_conf conf;
220+
221+ return s5_calc_params(rate, *parent_rate, &conf);
222+}
223+
224+static const struct clk_ops s5_pll_ops = {
225+ .enable = s5_pll_enable,
226+ .disable = s5_pll_disable,
227+ .set_rate = s5_pll_set_rate,
228+ .round_rate = s5_pll_round_rate,
229+ .recalc_rate = s5_pll_recalc_rate,
230+};
231+
232+static struct clk_hw *s5_clk_hw_get(struct of_phandle_args *clkspec, void *data)
233+{
234+ struct s5_clk_data *s5_clk = data;
235+ unsigned int idx = clkspec->args[0];
236+
237+ if (idx >= N_CLOCKS) {
238+ pr_err("%s: invalid index %u\n", __func__, idx);
239+ return ERR_PTR(-EINVAL);
240+ }
241+
242+ return &s5_clk->s5_hw[idx].hw;
243+}
244+
245+static int s5_clk_probe(struct platform_device *pdev)
246+{
247+ struct device *dev = &pdev->dev;
248+ int i, ret;
249+ struct s5_clk_data *s5_clk;
250+ struct clk_parent_data pdata = { .index = 0 };
251+ struct clk_init_data init = {
252+ .ops = &s5_pll_ops,
253+ .num_parents = 1,
254+ .parent_data = &pdata,
255+ };
256+
257+ s5_clk = devm_kzalloc(dev, sizeof(*s5_clk), GFP_KERNEL);
258+ if (!s5_clk)
259+ return -ENOMEM;
260+
261+ s5_clk->base = devm_platform_ioremap_resource(pdev, 0);
262+ if (IS_ERR(s5_clk->base))
263+ return PTR_ERR(s5_clk->base);
264+
265+ for (i = 0; i < N_CLOCKS; i++) {
266+ struct s5_hw_clk *s5_hw = &s5_clk->s5_hw[i];
267+
268+ init.name = clk_names[i];
269+ s5_hw->reg = s5_clk->base + (i * 4);
270+ s5_hw->hw.init = &init;
271+ ret = devm_clk_hw_register(dev, &s5_hw->hw);
272+ if (ret) {
273+ dev_err(dev, "failed to register %s clock\n",
274+ init.name);
275+ return ret;
276+ }
277+ }
278+
279+ return devm_of_clk_add_hw_provider(dev, s5_clk_hw_get, s5_clk);
280+}
281+
282+static const struct of_device_id s5_clk_dt_ids[] = {
283+ { .compatible = "microchip,sparx5-dpll", },
284+ { }
285+};
286+MODULE_DEVICE_TABLE(of, s5_clk_dt_ids);
287+
288+static struct platform_driver s5_clk_driver = {
289+ .probe = s5_clk_probe,
290+ .driver = {
291+ .name = "sparx5-clk",
292+ .of_match_table = s5_clk_dt_ids,
293+ },
294+};
295+builtin_platform_driver(s5_clk_driver);
drivers/clk/clk-versaclock5.c+38−44
@@ -167,6 +167,12 @@ struct vc5_hw_data { · 166 unmodified lines
167167 u32 div_int;
168168 u32 div_frc;
169169 unsigned int num;
170+};
171+
172+struct vc5_out_data {
173+ struct clk_hw hw;
174+ struct vc5_driver_data *vc5;
175+ unsigned int num;
170176 unsigned int clk_output_cfg0;
171177 unsigned int clk_output_cfg0_mask;
172178 };
@@ -184,7 +190,7 @@ struct vc5_driver_data { · 11 unmodified lines
184190 struct clk_hw clk_pfd;
185191 struct vc5_hw_data clk_pll;
186192 struct vc5_hw_data clk_fod[VC5_MAX_FOD_NUM];
187− struct vc5_hw_data clk_out[VC5_MAX_CLK_OUT_NUM];
193+ struct vc5_out_data clk_out[VC5_MAX_CLK_OUT_NUM];
188194 };
189195
190196 /*
@@ -567,7 +573,7 @@ static const struct clk_ops vc5_fod_ops = { · 376 unmodified lines
567573
568574 static int vc5_clk_out_prepare(struct clk_hw *hw)
569575 {
570− struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
576+ struct vc5_out_data *hwdata = container_of(hw, struct vc5_out_data, hw);
571577 struct vc5_driver_data *vc5 = hwdata->vc5;
572578 const u8 mask = VC5_OUT_DIV_CONTROL_SELB_NORM |
573579 VC5_OUT_DIV_CONTROL_SEL_EXT |
@@ -609,7 +615,7 @@ static int vc5_clk_out_prepare(struct clk_hw *hw) · 35 unmodified lines
609615
610616 static void vc5_clk_out_unprepare(struct clk_hw *hw)
611617 {
612− struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
618+ struct vc5_out_data *hwdata = container_of(hw, struct vc5_out_data, hw);
613619 struct vc5_driver_data *vc5 = hwdata->vc5;
614620
615621 /* Disable the clock buffer */
@@ -619,7 +625,7 @@ static void vc5_clk_out_unprepare(struct clk_hw *hw) · 3 unmodified lines
619625
620626 static unsigned char vc5_clk_out_get_parent(struct clk_hw *hw)
621627 {
622− struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
628+ struct vc5_out_data *hwdata = container_of(hw, struct vc5_out_data, hw);
623629 struct vc5_driver_data *vc5 = hwdata->vc5;
624630 const u8 mask = VC5_OUT_DIV_CONTROL_SELB_NORM |
625631 VC5_OUT_DIV_CONTROL_SEL_EXT |
@@ -649,7 +655,7 @@ static unsigned char vc5_clk_out_get_parent(struct clk_hw *hw) · 23 unmodified lines
649655
650656 static int vc5_clk_out_set_parent(struct clk_hw *hw, u8 index)
651657 {
652− struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
658+ struct vc5_out_data *hwdata = container_of(hw, struct vc5_out_data, hw);
653659 struct vc5_driver_data *vc5 = hwdata->vc5;
654660 const u8 mask = VC5_OUT_DIV_CONTROL_RESET |
655661 VC5_OUT_DIV_CONTROL_SELB_NORM |
@@ -704,7 +710,7 @@ static int vc5_map_index_to_output(const enum vc5_model model, · 48 unmodified lines
704710 }
705711
706712 static int vc5_update_mode(struct device_node *np_output,
707− struct vc5_hw_data *clk_out)
713+ struct vc5_out_data *clk_out)
708714 {
709715 u32 value;
710716
@@ -729,7 +735,7 @@ static int vc5_update_mode(struct device_node *np_output, · 18 unmodified lines
729735 }
730736
731737 static int vc5_update_power(struct device_node *np_output,
732− struct vc5_hw_data *clk_out)
738+ struct vc5_out_data *clk_out)
733739 {
734740 u32 value;
735741
@@ -754,7 +760,7 @@ static int vc5_update_power(struct device_node *np_output, · 18 unmodified lines
754760 }
755761
756762 static int vc5_update_slew(struct device_node *np_output,
757− struct vc5_hw_data *clk_out)
763+ struct vc5_out_data *clk_out)
758764 {
759765 u32 value;
760766
@@ -782,17 +788,20 @@ static int vc5_update_slew(struct device_node *np_output, · 21 unmodified lines
782788 }
783789
784790 static int vc5_get_output_config(struct i2c_client *client,
785− struct vc5_hw_data *clk_out)
791+ struct vc5_out_data *clk_out)
786792 {
787793 struct device_node *np_output;
788794 char *child_name;
789795 int ret = 0;
790796
791797 child_name = kasprintf(GFP_KERNEL, "OUT%d", clk_out->num + 1);
798+ if (!child_name)
799+ return -ENOMEM;
800+
792801 np_output = of_get_child_by_name(client->dev.of_node, child_name);
793802 kfree(child_name);
794803 if (!np_output)
795− goto output_done;
804+ return 0;
796805
797806 ret = vc5_update_mode(np_output, clk_out);
798807 if (ret)
@@ -813,7 +822,6 @@ output_error: · 14 unmodified lines
813822
814823 of_node_put(np_output);
815824
816−output_done:
817825 return ret;
818826 }
819827
@@ -828,7 +836,7 @@ static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id) · 8 unmodified lines
828836 int ret;
829837
830838 vc5 = devm_kzalloc(&client->dev, sizeof(*vc5), GFP_KERNEL);
831− if (vc5 == NULL)
839+ if (!vc5)
832840 return -ENOMEM;
833841
834842 i2c_set_clientdata(client, vc5);
@@ -882,11 +890,9 @@ static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id) · 47 unmodified lines
882890 init.parent_names = parent_names;
883891 vc5->clk_mux.init = &init;
884892 ret = devm_clk_hw_register(&client->dev, &vc5->clk_mux);
893+ if (ret)
894+ goto err_clk_register;
885895 kfree(init.name); /* clock framework made a copy of the name */
886− if (ret) {
887− dev_err(&client->dev, "unable to register %s\n", init.name);
888− goto err_clk;
889− }
890896
891897 if (vc5->chip_info->flags & VC5_HAS_PFD_FREQ_DBL) {
892898 /* Register frequency doubler */
@@ -900,12 +906,9 @@ static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id) · 7 unmodified lines
900906 init.num_parents = 1;
901907 vc5->clk_mul.init = &init;
902908 ret = devm_clk_hw_register(&client->dev, &vc5->clk_mul);
909+ if (ret)
910+ goto err_clk_register;
903911 kfree(init.name); /* clock framework made a copy of the name */
904− if (ret) {
905− dev_err(&client->dev, "unable to register %s\n",
906− init.name);
907− goto err_clk;
908− }
909912 }
910913
911914 /* Register PFD */
@@ -921,11 +924,9 @@ static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id) · 9 unmodified lines
921924 init.num_parents = 1;
922925 vc5->clk_pfd.init = &init;
923926 ret = devm_clk_hw_register(&client->dev, &vc5->clk_pfd);
927+ if (ret)
928+ goto err_clk_register;
924929 kfree(init.name); /* clock framework made a copy of the name */
925− if (ret) {
926− dev_err(&client->dev, "unable to register %s\n", init.name);
927− goto err_clk;
928− }
929930
930931 /* Register PLL */
931932 memset(&init, 0, sizeof(init));
@@ -939,11 +940,9 @@ static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id) · 7 unmodified lines
939940 vc5->clk_pll.vc5 = vc5;
940941 vc5->clk_pll.hw.init = &init;
941942 ret = devm_clk_hw_register(&client->dev, &vc5->clk_pll.hw);
943+ if (ret)
944+ goto err_clk_register;
942945 kfree(init.name); /* clock framework made a copy of the name */
943− if (ret) {
944− dev_err(&client->dev, "unable to register %s\n", init.name);
945− goto err_clk;
946− }
947946
948947 /* Register FODs */
949948 for (n = 0; n < vc5->chip_info->clk_fod_cnt; n++) {
@@ -960,12 +959,9 @@ static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id) · 10 unmodified lines
960959 vc5->clk_fod[n].vc5 = vc5;
961960 vc5->clk_fod[n].hw.init = &init;
962961 ret = devm_clk_hw_register(&client->dev, &vc5->clk_fod[n].hw);
962+ if (ret)
963+ goto err_clk_register;
963964 kfree(init.name); /* clock framework made a copy of the name */
964− if (ret) {
965− dev_err(&client->dev, "unable to register %s\n",
966− init.name);
967− goto err_clk;
968− }
969965 }
970966
971967 /* Register MUX-connected OUT0_I2C_SELB output */
@@ -981,11 +977,9 @@ static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id) · 9 unmodified lines
981977 vc5->clk_out[0].vc5 = vc5;
982978 vc5->clk_out[0].hw.init = &init;
983979 ret = devm_clk_hw_register(&client->dev, &vc5->clk_out[0].hw);
984− kfree(init.name); /* clock framework made a copy of the name */
985− if (ret) {
986− dev_err(&client->dev, "unable to register %s\n", init.name);
987− goto err_clk;
988− }
980+ if (ret)
981+ goto err_clk_register;
982+ kfree(init.name); /* clock framework made a copy of the name */
989983
990984 /* Register FOD-connected OUTx outputs */
991985 for (n = 1; n < vc5->chip_info->clk_out_cnt; n++) {
@@ -1008,12 +1002,9 @@ static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id) · 16 unmodified lines
10081002 vc5->clk_out[n].vc5 = vc5;
10091003 vc5->clk_out[n].hw.init = &init;
10101004 ret = devm_clk_hw_register(&client->dev, &vc5->clk_out[n].hw);
1005+ if (ret)
1006+ goto err_clk_register;
10111007 kfree(init.name); /* clock framework made a copy of the name */
1012− if (ret) {
1013− dev_err(&client->dev, "unable to register %s\n",
1014− init.name);
1015− goto err_clk;
1016− }
10171008
10181009 /* Fetch Clock Output configuration from DT (if specified) */
10191010 ret = vc5_get_output_config(client, &vc5->clk_out[n]);
@@ -1029,6 +1020,9 @@ static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id) · 9 unmodified lines
10291020
10301021 return 0;
10311022
1023+err_clk_register:
1024+ dev_err(&client->dev, "unable to register %s\n", init.name);
1025+ kfree(init.name); /* clock framework made a copy of the name */
10321026 err_clk:
10331027 if (vc5->chip_info->flags & VC5_HAS_INTERNAL_XTAL)
10341028 clk_unregister_fixed_rate(vc5->pin_xin);
drivers/clk/clk.c+32−6
@@ -500,12 +500,6 @@ static unsigned long clk_core_get_accuracy_no_lock(struct clk_core *core) · 499 unmodified lines
500500 return core->accuracy;
501501 }
502502
503−unsigned long __clk_get_flags(struct clk *clk)
504−{
505− return !clk ? 0 : clk->core->flags;
506−}
507−EXPORT_SYMBOL_GPL(__clk_get_flags);
508−
509503 unsigned long clk_hw_get_flags(const struct clk_hw *hw)
510504 {
511505 return hw->core->flags;
@@ -3054,6 +3048,31 @@ static int clk_rate_set(void *data, u64 val) · 2542 unmodified lines
30543048 }
30553049
30563050 #define clk_rate_mode 0644
3051+
3052+static int clk_prepare_enable_set(void *data, u64 val)
3053+{
3054+ struct clk_core *core = data;
3055+ int ret = 0;
3056+
3057+ if (val)
3058+ ret = clk_prepare_enable(core->hw->clk);
3059+ else
3060+ clk_disable_unprepare(core->hw->clk);
3061+
3062+ return ret;
3063+}
3064+
3065+static int clk_prepare_enable_get(void *data, u64 *val)
3066+{
3067+ struct clk_core *core = data;
3068+
3069+ *val = core->enable_count && core->prepare_count;
3070+ return 0;
3071+}
3072+
3073+DEFINE_DEBUGFS_ATTRIBUTE(clk_prepare_enable_fops, clk_prepare_enable_get,
3074+ clk_prepare_enable_set, "%llu\n");
3075+
30573076 #else
30583077 #define clk_rate_set NULL
30593078 #define clk_rate_mode 0444
@@ -3231,6 +3250,10 @@ static void clk_debug_create_one(struct clk_core *core, struct dentry *pdentry) · 171 unmodified lines
32313250 debugfs_create_u32("clk_notifier_count", 0444, root, &core->notifier_count);
32323251 debugfs_create_file("clk_duty_cycle", 0444, root, core,
32333252 &clk_duty_cycle_fops);
3253+#ifdef CLOCK_ALLOW_WRITE_DEBUGFS
3254+ debugfs_create_file("clk_prepare_enable", 0644, root, core,
3255+ &clk_prepare_enable_fops);
3256+#endif
32343257
32353258 if (core->num_parents > 0)
32363259 debugfs_create_file("clk_parent", 0444, root, core,
@@ -4135,6 +4158,7 @@ static int devm_clk_hw_match(struct device *dev, void *res, void *data) · 898 unmodified lines
41354158
41364159 /**
41374160 * devm_clk_unregister - resource managed clk_unregister()
4161+ * @dev: device that is unregistering the clock data
41384162 * @clk: clock to unregister
41394163 *
41404164 * Deallocate a clock allocated with devm_clk_register(). Normally
@@ -4324,6 +4348,8 @@ static void clk_core_reparent_orphans(void) · 183 unmodified lines
43244348 * @node: Pointer to device tree node of clock provider
43254349 * @get: Get clock callback. Returns NULL or a struct clk for the
43264350 * given clock specifier
4351+ * @get_hw: Get clk_hw callback. Returns NULL, ERR_PTR or a
4352+ * struct clk_hw for the given clock specifier
43274353 * @data: context pointer to be passed into @get callback
43284354 */
43294355 struct of_clk_provider {
drivers/clk/davinci/pll.c+1−1
@@ -651,7 +651,7 @@ static int davinci_pll_sysclk_rate_change(struct notifier_block *nb, · 650 unmodified lines
651651 pllcmd = readl(pll->base + PLLCMD);
652652 pllcmd |= PLLCMD_GOSET;
653653 writel(pllcmd, pll->base + PLLCMD);
654− /* fallthrough */
654+ fallthrough;
655655 case PRE_RATE_CHANGE:
656656 /* Wait until for outstanding changes to take effect */
657657 do {
drivers/clk/imx/clk-pllv3.c+2−2
@@ -433,7 +433,7 @@ struct clk_hw *imx_clk_hw_pllv3(enum imx_pllv3_type type, const char *name, · 432 unmodified lines
433433 break;
434434 case IMX_PLLV3_USB_VF610:
435435 pll->div_shift = 1;
436− /* fall through */
436+ fallthrough;
437437 case IMX_PLLV3_USB:
438438 ops = &clk_pllv3_ops;
439439 pll->powerup_set = true;
@@ -441,7 +441,7 @@ struct clk_hw *imx_clk_hw_pllv3(enum imx_pllv3_type type, const char *name, · 1 unmodified line
441441 case IMX_PLLV3_AV_IMX7:
442442 pll->num_offset = PLL_IMX7_NUM_OFFSET;
443443 pll->denom_offset = PLL_IMX7_DENOM_OFFSET;
444− /* fall through */
444+ fallthrough;
445445 case IMX_PLLV3_AV:
446446 ops = &clk_pllv3_av_ops;
447447 break;
drivers/clk/ingenic/jz4780-cgu.c+91−74
@@ -4,6 +4,7 @@ · 3 unmodified lines
44 *
55 * Copyright (c) 2013-2015 Imagination Technologies
66 * Author: Paul Burton <paul.burton@mips.com>
7+ * Copyright (c) 2020 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com>
78 */
89
910 #include <linux/clk-provider.h>
@@ -19,49 +20,50 @@ · 9 unmodified lines
1920
2021 /* CGU register offsets */
2122 #define CGU_REG_CLOCKCONTROL 0x00
22−#define CGU_REG_LCR 0x04
23−#define CGU_REG_APLL 0x10
24−#define CGU_REG_MPLL 0x14
25−#define CGU_REG_EPLL 0x18
26−#define CGU_REG_VPLL 0x1c
27−#define CGU_REG_CLKGR0 0x20
28−#define CGU_REG_OPCR 0x24
29−#define CGU_REG_CLKGR1 0x28
30−#define CGU_REG_DDRCDR 0x2c
31−#define CGU_REG_VPUCDR 0x30
32−#define CGU_REG_USBPCR 0x3c
33−#define CGU_REG_USBRDT 0x40
34−#define CGU_REG_USBVBFIL 0x44
35−#define CGU_REG_USBPCR1 0x48
36−#define CGU_REG_LP0CDR 0x54
37−#define CGU_REG_I2SCDR 0x60
38−#define CGU_REG_LP1CDR 0x64
39−#define CGU_REG_MSC0CDR 0x68
40−#define CGU_REG_UHCCDR 0x6c
41−#define CGU_REG_SSICDR 0x74
42−#define CGU_REG_CIMCDR 0x7c
43−#define CGU_REG_PCMCDR 0x84
44−#define CGU_REG_GPUCDR 0x88
45−#define CGU_REG_HDMICDR 0x8c
46−#define CGU_REG_MSC1CDR 0xa4
47−#define CGU_REG_MSC2CDR 0xa8
48−#define CGU_REG_BCHCDR 0xac
49−#define CGU_REG_CLOCKSTATUS 0xd4
23+#define CGU_REG_LCR 0x04
24+#define CGU_REG_APLL 0x10
25+#define CGU_REG_MPLL 0x14
26+#define CGU_REG_EPLL 0x18
27+#define CGU_REG_VPLL 0x1c
28+#define CGU_REG_CLKGR0 0x20
29+#define CGU_REG_OPCR 0x24
30+#define CGU_REG_CLKGR1 0x28
31+#define CGU_REG_DDRCDR 0x2c
32+#define CGU_REG_VPUCDR 0x30
33+#define CGU_REG_USBPCR 0x3c
34+#define CGU_REG_USBRDT 0x40
35+#define CGU_REG_USBVBFIL 0x44
36+#define CGU_REG_USBPCR1 0x48
37+#define CGU_REG_LP0CDR 0x54
38+#define CGU_REG_I2SCDR 0x60
39+#define CGU_REG_LP1CDR 0x64
40+#define CGU_REG_MSC0CDR 0x68
41+#define CGU_REG_UHCCDR 0x6c
42+#define CGU_REG_SSICDR 0x74
43+#define CGU_REG_CIMCDR 0x7c
44+#define CGU_REG_PCMCDR 0x84
45+#define CGU_REG_GPUCDR 0x88
46+#define CGU_REG_HDMICDR 0x8c
47+#define CGU_REG_MSC1CDR 0xa4
48+#define CGU_REG_MSC2CDR 0xa8
49+#define CGU_REG_BCHCDR 0xac
50+#define CGU_REG_CLOCKSTATUS 0xd4
5051
5152 /* bits within the OPCR register */
52−#define OPCR_SPENDN0 BIT(7)
53−#define OPCR_SPENDN1 BIT(6)
53+#define OPCR_SPENDN0 BIT(7)
54+#define OPCR_SPENDN1 BIT(6)
5455
5556 /* bits within the USBPCR register */
56−#define USBPCR_USB_MODE BIT(31)
57+#define USBPCR_USB_MODE BIT(31)
5758 #define USBPCR_IDPULLUP_MASK (0x3 << 28)
58−#define USBPCR_COMMONONN BIT(25)
59−#define USBPCR_VBUSVLDEXT BIT(24)
59+#define USBPCR_COMMONONN BIT(25)
60+#define USBPCR_VBUSVLDEXT BIT(24)
6061 #define USBPCR_VBUSVLDEXTSEL BIT(23)
61−#define USBPCR_POR BIT(22)
62−#define USBPCR_OTG_DISABLE BIT(20)
62+#define USBPCR_POR BIT(22)
63+#define USBPCR_SIDDQ BIT(21)
64+#define USBPCR_OTG_DISABLE BIT(20)
6365 #define USBPCR_COMPDISTUNE_MASK (0x7 << 17)
64−#define USBPCR_OTGTUNE_MASK (0x7 << 14)
66+#define USBPCR_OTGTUNE_MASK (0x7 << 14)
6567 #define USBPCR_SQRXTUNE_MASK (0x7 << 11)
6668 #define USBPCR_TXFSLSTUNE_MASK (0xf << 7)
6769 #define USBPCR_TXPREEMPHTUNE BIT(6)
@@ -78,13 +80,13 @@ · 10 unmodified lines
7880 #define USBPCR1_REFCLKDIV_48 (0x2 << USBPCR1_REFCLKDIV_SHIFT)
7981 #define USBPCR1_REFCLKDIV_24 (0x1 << USBPCR1_REFCLKDIV_SHIFT)
8082 #define USBPCR1_REFCLKDIV_12 (0x0 << USBPCR1_REFCLKDIV_SHIFT)
81−#define USBPCR1_USB_SEL BIT(28)
82−#define USBPCR1_WORD_IF0 BIT(19)
83−#define USBPCR1_WORD_IF1 BIT(18)
83+#define USBPCR1_USB_SEL BIT(28)
84+#define USBPCR1_WORD_IF0 BIT(19)
85+#define USBPCR1_WORD_IF1 BIT(18)
8486
8587 /* bits within the USBRDT register */
86−#define USBRDT_VBFIL_LD_EN BIT(25)
87−#define USBRDT_USBRDT_MASK 0x7fffff
88+#define USBRDT_VBFIL_LD_EN BIT(25)
89+#define USBRDT_USBRDT_MASK 0x7fffff
8890
8991 /* bits within the USBVBFIL register */
9092 #define USBVBFIL_IDDIGFIL_SHIFT 16
@@ -92,40 +94,14 @@ · 1 unmodified line
9294 #define USBVBFIL_USBVBFIL_MASK (0xffff)
9395
9496 /* bits within the LCR register */
95−#define LCR_PD_SCPU BIT(31)
96−#define LCR_SCPUS BIT(27)
97+#define LCR_PD_SCPU BIT(31)
98+#define LCR_SCPUS BIT(27)
9799
98100 /* bits within the CLKGR1 register */
99−#define CLKGR1_CORE1 BIT(15)
101+#define CLKGR1_CORE1 BIT(15)
100102
101103 static struct ingenic_cgu *cgu;
102104
103−static u8 jz4780_otg_phy_get_parent(struct clk_hw *hw)
104−{
105− /* we only use CLKCORE, revisit if that ever changes */
106− return 0;
107−}
108−
109−static int jz4780_otg_phy_set_parent(struct clk_hw *hw, u8 idx)
110−{
111− unsigned long flags;
112− u32 usbpcr1;
113−
114− if (idx > 0)
115− return -EINVAL;
116−
117− spin_lock_irqsave(&cgu->lock, flags);
118−
119− usbpcr1 = readl(cgu->base + CGU_REG_USBPCR1);
120− usbpcr1 &= ~USBPCR1_REFCLKSEL_MASK;
121− /* we only use CLKCORE */
122− usbpcr1 |= USBPCR1_REFCLKSEL_CORE;
123− writel(usbpcr1, cgu->base + CGU_REG_USBPCR1);
124−
125− spin_unlock_irqrestore(&cgu->lock, flags);
126− return 0;
127−}
128−
129105 static unsigned long jz4780_otg_phy_recalc_rate(struct clk_hw *hw,
130106 unsigned long parent_rate)
131107 {
@@ -149,7 +125,6 @@ static unsigned long jz4780_otg_phy_recalc_rate(struct clk_hw *hw, · 17 unmodified lines
149125 return 19200000;
150126 }
151127
152− BUG();
153128 return parent_rate;
154129 }
155130
@@ -206,13 +181,43 @@ static int jz4780_otg_phy_set_rate(struct clk_hw *hw, unsigned long req_rate, · 50 unmodified lines
206181 return 0;
207182 }
208183
209−static const struct clk_ops jz4780_otg_phy_ops = {
210− .get_parent = jz4780_otg_phy_get_parent,
211− .set_parent = jz4780_otg_phy_set_parent,
184+static int jz4780_otg_phy_enable(struct clk_hw *hw)
185+{
186+ void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR;
187+ void __iomem *reg_usbpcr = cgu->base + CGU_REG_USBPCR;
188+
189+ writel(readl(reg_opcr) | OPCR_SPENDN0, reg_opcr);
190+ writel(readl(reg_usbpcr) & ~USBPCR_OTG_DISABLE & ~USBPCR_SIDDQ, reg_usbpcr);
191+ return 0;
192+}
212193
194+static void jz4780_otg_phy_disable(struct clk_hw *hw)
195+{
196+ void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR;
197+ void __iomem *reg_usbpcr = cgu->base + CGU_REG_USBPCR;
198+
199+ writel(readl(reg_opcr) & ~OPCR_SPENDN0, reg_opcr);
200+ writel(readl(reg_usbpcr) | USBPCR_OTG_DISABLE | USBPCR_SIDDQ, reg_usbpcr);
201+}
202+
203+static int jz4780_otg_phy_is_enabled(struct clk_hw *hw)
204+{
205+ void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR;
206+ void __iomem *reg_usbpcr = cgu->base + CGU_REG_USBPCR;
207+
208+ return (readl(reg_opcr) & OPCR_SPENDN0) &&
209+ !(readl(reg_usbpcr) & USBPCR_SIDDQ) &&
210+ !(readl(reg_usbpcr) & USBPCR_OTG_DISABLE);
211+}
212+
213+static const struct clk_ops jz4780_otg_phy_ops = {
213214 .recalc_rate = jz4780_otg_phy_recalc_rate,
214215 .round_rate = jz4780_otg_phy_round_rate,
215216 .set_rate = jz4780_otg_phy_set_rate,
217+
218+ .enable = jz4780_otg_phy_enable,
219+ .disable = jz4780_otg_phy_disable,
220+ .is_enabled = jz4780_otg_phy_is_enabled,
216221 };
217222
218223 static int jz4780_core1_enable(struct clk_hw *hw)
@@ -516,6 +521,18 @@ static const struct ingenic_cgu_clk_info jz4780_cgu_clocks[] = { · 297 unmodified lines
516521 .gate = { CGU_REG_CLKGR0, 1 },
517522 },
518523
524+ [JZ4780_CLK_EXCLK_DIV512] = {
525+ "exclk_div512", CGU_CLK_FIXDIV,
526+ .parents = { JZ4780_CLK_EXCLK },
527+ .fixdiv = { 512 },
528+ },
529+
530+ [JZ4780_CLK_RTC] = {
531+ "rtc_ercs", CGU_CLK_MUX | CGU_CLK_GATE,
532+ .parents = { JZ4780_CLK_EXCLK_DIV512, JZ4780_CLK_RTCLK },
533+ .mux = { CGU_REG_OPCR, 2, 1},
534+ },
535+
519536 /* Gate-only clocks */
520537
521538 [JZ4780_CLK_NEMC] = {
drivers/clk/ingenic/x1000-cgu.c+96−1
@@ -48,8 +48,87 @@ · 47 unmodified lines
4848 #define USBPCR_SIDDQ BIT(21)
4949 #define USBPCR_OTG_DISABLE BIT(20)
5050
51+/* bits within the USBPCR1 register */
52+#define USBPCR1_REFCLKSEL_SHIFT 26
53+#define USBPCR1_REFCLKSEL_MASK (0x3 << USBPCR1_REFCLKSEL_SHIFT)
54+#define USBPCR1_REFCLKSEL_CORE (0x2 << USBPCR1_REFCLKSEL_SHIFT)
55+#define USBPCR1_REFCLKDIV_SHIFT 24
56+#define USBPCR1_REFCLKDIV_MASK (0x3 << USBPCR1_REFCLKDIV_SHIFT)
57+#define USBPCR1_REFCLKDIV_48 (0x2 << USBPCR1_REFCLKDIV_SHIFT)
58+#define USBPCR1_REFCLKDIV_24 (0x1 << USBPCR1_REFCLKDIV_SHIFT)
59+#define USBPCR1_REFCLKDIV_12 (0x0 << USBPCR1_REFCLKDIV_SHIFT)
60+
5161 static struct ingenic_cgu *cgu;
5262
63+static unsigned long x1000_otg_phy_recalc_rate(struct clk_hw *hw,
64+ unsigned long parent_rate)
65+{
66+ u32 usbpcr1;
67+ unsigned refclk_div;
68+
69+ usbpcr1 = readl(cgu->base + CGU_REG_USBPCR1);
70+ refclk_div = usbpcr1 & USBPCR1_REFCLKDIV_MASK;
71+
72+ switch (refclk_div) {
73+ case USBPCR1_REFCLKDIV_12:
74+ return 12000000;
75+
76+ case USBPCR1_REFCLKDIV_24:
77+ return 24000000;
78+
79+ case USBPCR1_REFCLKDIV_48:
80+ return 48000000;
81+ }
82+
83+ return parent_rate;
84+}
85+
86+static long x1000_otg_phy_round_rate(struct clk_hw *hw, unsigned long req_rate,
87+ unsigned long *parent_rate)
88+{
89+ if (req_rate < 18000000)
90+ return 12000000;
91+
92+ if (req_rate < 36000000)
93+ return 24000000;
94+
95+ return 48000000;
96+}
97+
98+static int x1000_otg_phy_set_rate(struct clk_hw *hw, unsigned long req_rate,
99+ unsigned long parent_rate)
100+{
101+ unsigned long flags;
102+ u32 usbpcr1, div_bits;
103+
104+ switch (req_rate) {
105+ case 12000000:
106+ div_bits = USBPCR1_REFCLKDIV_12;
107+ break;
108+
109+ case 24000000:
110+ div_bits = USBPCR1_REFCLKDIV_24;
111+ break;
112+
113+ case 48000000:
114+ div_bits = USBPCR1_REFCLKDIV_48;
115+ break;
116+
117+ default:
118+ return -EINVAL;
119+ }
120+
121+ spin_lock_irqsave(&cgu->lock, flags);
122+
123+ usbpcr1 = readl(cgu->base + CGU_REG_USBPCR1);
124+ usbpcr1 &= ~USBPCR1_REFCLKDIV_MASK;
125+ usbpcr1 |= div_bits;
126+ writel(usbpcr1, cgu->base + CGU_REG_USBPCR1);
127+
128+ spin_unlock_irqrestore(&cgu->lock, flags);
129+ return 0;
130+}
131+
53132 static int x1000_usb_phy_enable(struct clk_hw *hw)
54133 {
55134 void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR;
@@ -80,6 +159,10 @@ static int x1000_usb_phy_is_enabled(struct clk_hw *hw) · 24 unmodified lines
80159 }
81160
82161 static const struct clk_ops x1000_otg_phy_ops = {
162+ .recalc_rate = x1000_otg_phy_recalc_rate,
163+ .round_rate = x1000_otg_phy_round_rate,
164+ .set_rate = x1000_otg_phy_set_rate,
165+
83166 .enable = x1000_usb_phy_enable,
84167 .disable = x1000_usb_phy_disable,
85168 .is_enabled = x1000_usb_phy_is_enabled,
@@ -144,7 +227,6 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = { · 58 unmodified lines
144227 },
145228 },
146229
147−
148230 /* Custom (SoC-specific) OTG PHY */
149231
150232 [X1000_CLK_OTGPHY] = {
@@ -278,6 +360,19 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = { · 127 unmodified lines
278360 .mux = { CGU_REG_SSICDR, 30, 1 },
279361 },
280362
363+ [X1000_CLK_EXCLK_DIV512] = {
364+ "exclk_div512", CGU_CLK_FIXDIV,
365+ .parents = { X1000_CLK_EXCLK },
366+ .fixdiv = { 512 },
367+ },
368+
369+ [X1000_CLK_RTC] = {
370+ "rtc_ercs", CGU_CLK_MUX | CGU_CLK_GATE,
371+ .parents = { X1000_CLK_EXCLK_DIV512, X1000_CLK_RTCLK },
372+ .mux = { CGU_REG_OPCR, 2, 1},
373+ .gate = { CGU_REG_CLKGR, 27 },
374+ },
375+
281376 /* Gate-only clocks */
282377
283378 [X1000_CLK_EMC] = {
drivers/clk/ingenic/x1830-cgu.c+13−0
@@ -329,6 +329,19 @@ static const struct ingenic_cgu_clk_info x1830_cgu_clocks[] = { · 328 unmodified lines
329329 .mux = { CGU_REG_SSICDR, 29, 1 },
330330 },
331331
332+ [X1830_CLK_EXCLK_DIV512] = {
333+ "exclk_div512", CGU_CLK_FIXDIV,
334+ .parents = { X1830_CLK_EXCLK },
335+ .fixdiv = { 512 },
336+ },
337+
338+ [X1830_CLK_RTC] = {
339+ "rtc_ercs", CGU_CLK_MUX | CGU_CLK_GATE,
340+ .parents = { X1830_CLK_EXCLK_DIV512, X1830_CLK_RTCLK },
341+ .mux = { CGU_REG_OPCR, 2, 1},
342+ .gate = { CGU_REG_CLKGR0, 29 },
343+ },
344+
332345 /* Gate-only clocks */
333346
334347 [X1830_CLK_EMC] = {
drivers/clk/mmp/clk-pxa168.c+1−0
@@ -10,6 +10,7 @@ · 9 unmodified lines
1010 */
1111
1212 #include <linux/clk.h>
13+#include <linux/clk/mmp.h>
1314 #include <linux/module.h>
1415 #include <linux/kernel.h>
1516 #include <linux/spinlock.h>
drivers/clk/mmp/clk-pxa910.c+1−0
@@ -10,6 +10,7 @@ · 9 unmodified lines
1010 */
1111
1212 #include <linux/clk.h>
13+#include <linux/clk/mmp.h>
1314 #include <linux/module.h>
1415 #include <linux/kernel.h>
1516 #include <linux/spinlock.h>
drivers/clk/qcom/Kconfig+25−0
@@ -308,6 +308,15 @@ config SC_GCC_7180 · 307 unmodified lines
308308 Say Y if you want to use peripheral devices such as UART, SPI,
309309 I2C, USB, UFS, SDCC, etc.
310310
311+config SC_LPASS_CORECC_7180
312+ tristate "SC7180 LPASS Core Clock Controller"
313+ select SC_GCC_7180
314+ help
315+ Support for the LPASS(Low Power Audio Subsystem) core clock controller
316+ on SC7180 devices.
317+ Say Y if you want to use LPASS clocks and power domains of the LPASS
318+ core clock controller.
319+
311320 config SC_GPUCC_7180
312321 tristate "SC7180 Graphics Clock Controller"
313322 select SC_GCC_7180
@@ -419,6 +428,22 @@ config SM_GCC_8250 · 105 unmodified lines
419428 Say Y if you want to use peripheral devices such as UART,
420429 SPI, I2C, USB, SD/UFS, PCIe etc.
421430
431+config SM_GPUCC_8150
432+ tristate "SM8150 Graphics Clock Controller"
433+ select SM_GCC_8150
434+ help
435+ Support for the graphics clock controller on SM8150 devices.
436+ Say Y if you want to support graphics controller devices and
437+ functionality such as 3D graphics.
438+
439+config SM_GPUCC_8250
440+ tristate "SM8250 Graphics Clock Controller"
441+ select SM_GCC_8250
442+ help
443+ Support for the graphics clock controller on SM8250 devices.
444+ Say Y if you want to support graphics controller devices and
445+ functionality such as 3D graphics.
446+
422447 config SPMI_PMIC_CLKDIV
423448 tristate "SPMI PMIC clkdiv Support"
424449 depends on SPMI || COMPILE_TEST
drivers/clk/qcom/Makefile+3−0
@@ -54,6 +54,7 @@ obj-$(CONFIG_QCS_TURING_404) += turingcc-qcs404.o · 53 unmodified lines
5454 obj-$(CONFIG_SC_DISPCC_7180) += dispcc-sc7180.o
5555 obj-$(CONFIG_SC_GCC_7180) += gcc-sc7180.o
5656 obj-$(CONFIG_SC_GPUCC_7180) += gpucc-sc7180.o
57+obj-$(CONFIG_SC_LPASS_CORECC_7180) += lpasscorecc-sc7180.o
5758 obj-$(CONFIG_SC_MSS_7180) += mss-sc7180.o
5859 obj-$(CONFIG_SC_VIDEOCC_7180) += videocc-sc7180.o
5960 obj-$(CONFIG_SDM_CAMCC_845) += camcc-sdm845.o
@@ -65,6 +66,8 @@ obj-$(CONFIG_SDM_LPASSCC_845) += lpasscc-sdm845.o · 5 unmodified lines
6566 obj-$(CONFIG_SDM_VIDEOCC_845) += videocc-sdm845.o
6667 obj-$(CONFIG_SM_GCC_8150) += gcc-sm8150.o
6768 obj-$(CONFIG_SM_GCC_8250) += gcc-sm8250.o
69+obj-$(CONFIG_SM_GPUCC_8150) += gpucc-sm8150.o
70+obj-$(CONFIG_SM_GPUCC_8250) += gpucc-sm8250.o
6871 obj-$(CONFIG_SPMI_PMIC_CLKDIV) += clk-spmi-pmic-div.o
6972 obj-$(CONFIG_KPSS_XCC) += kpss-xcc.o
7073 obj-$(CONFIG_QCOM_HFPLL) += hfpll.o
drivers/clk/qcom/clk-alpha-pll.c+34−36
@@ -56,7 +56,6 @@ · 55 unmodified lines
5656 #define PLL_STATUS(p) ((p)->offset + (p)->regs[PLL_OFF_STATUS])
5757 #define PLL_OPMODE(p) ((p)->offset + (p)->regs[PLL_OFF_OPMODE])
5858 #define PLL_FRAC(p) ((p)->offset + (p)->regs[PLL_OFF_FRAC])
59−#define PLL_CAL_VAL(p) ((p)->offset + (p)->regs[PLL_OFF_CAL_VAL])
6059
6160 const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = {
6261 [CLK_ALPHA_PLL_TYPE_DEFAULT] = {
@@ -102,22 +101,6 @@ const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = { · 39 unmodified lines
102101 [PLL_OFF_FRAC] = 0x38,
103102 },
104103 [CLK_ALPHA_PLL_TYPE_TRION] = {
105− [PLL_OFF_L_VAL] = 0x04,
106− [PLL_OFF_CAL_L_VAL] = 0x08,
107− [PLL_OFF_USER_CTL] = 0x0c,
108− [PLL_OFF_USER_CTL_U] = 0x10,
109− [PLL_OFF_USER_CTL_U1] = 0x14,
110− [PLL_OFF_CONFIG_CTL] = 0x18,
111− [PLL_OFF_CONFIG_CTL_U] = 0x1c,
112− [PLL_OFF_CONFIG_CTL_U1] = 0x20,
113− [PLL_OFF_TEST_CTL] = 0x24,
114− [PLL_OFF_TEST_CTL_U] = 0x28,
115− [PLL_OFF_STATUS] = 0x30,
116− [PLL_OFF_OPMODE] = 0x38,
117− [PLL_OFF_ALPHA_VAL] = 0x40,
118− [PLL_OFF_CAL_VAL] = 0x44,
119− },
120− [CLK_ALPHA_PLL_TYPE_LUCID] = {
121104 [PLL_OFF_L_VAL] = 0x04,
122105 [PLL_OFF_CAL_L_VAL] = 0x08,
123106 [PLL_OFF_USER_CTL] = 0x0c,
@@ -156,9 +139,12 @@ EXPORT_SYMBOL_GPL(clk_alpha_pll_regs); · 32 unmodified lines
156139 #define PLL_OUT_MASK 0x7
157140 #define PLL_RATE_MARGIN 500
158141
142+/* TRION PLL specific settings and offsets */
143+#define TRION_PLL_CAL_VAL 0x44
144+#define TRION_PCAL_DONE BIT(26)
145+
159146 /* LUCID PLL specific settings and offsets */
160−#define LUCID_PLL_CAL_VAL 0x44
161−#define LUCID_PCAL_DONE BIT(26)
147+#define LUCID_PCAL_DONE BIT(27)
162148
163149 #define pll_alpha_width(p) \
164150 ((PLL_ALPHA_VAL_U(p) - PLL_ALPHA_VAL(p) == 4) ? \
@@ -912,14 +898,14 @@ const struct clk_ops clk_alpha_pll_hwfsm_ops = { · 747 unmodified lines
912898 };
913899 EXPORT_SYMBOL_GPL(clk_alpha_pll_hwfsm_ops);
914900
915−const struct clk_ops clk_trion_fixed_pll_ops = {
901+const struct clk_ops clk_alpha_pll_fixed_trion_ops = {
916902 .enable = clk_trion_pll_enable,
917903 .disable = clk_trion_pll_disable,
918904 .is_enabled = clk_trion_pll_is_enabled,
919905 .recalc_rate = clk_trion_pll_recalc_rate,
920906 .round_rate = clk_alpha_pll_round_rate,
921907 };
922−EXPORT_SYMBOL_GPL(clk_trion_fixed_pll_ops);
908+EXPORT_SYMBOL_GPL(clk_alpha_pll_fixed_trion_ops);
923909
924910 static unsigned long
925911 clk_alpha_pll_postdiv_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
@@ -1339,12 +1325,12 @@ clk_trion_pll_postdiv_set_rate(struct clk_hw *hw, unsigned long rate, · 413 unmodified lines
13391325 val << PLL_POST_DIV_SHIFT);
13401326 }
13411327
1342−const struct clk_ops clk_trion_pll_postdiv_ops = {
1328+const struct clk_ops clk_alpha_pll_postdiv_trion_ops = {
13431329 .recalc_rate = clk_trion_pll_postdiv_recalc_rate,
13441330 .round_rate = clk_trion_pll_postdiv_round_rate,
13451331 .set_rate = clk_trion_pll_postdiv_set_rate,
13461332 };
1347−EXPORT_SYMBOL_GPL(clk_trion_pll_postdiv_ops);
1333+EXPORT_SYMBOL_GPL(clk_alpha_pll_postdiv_trion_ops);
13481334
13491335 static long clk_alpha_pll_postdiv_fabia_round_rate(struct clk_hw *hw,
13501336 unsigned long rate, unsigned long *prate)
@@ -1399,13 +1385,13 @@ EXPORT_SYMBOL_GPL(clk_alpha_pll_postdiv_fabia_ops); · 48 unmodified lines
13991385 * @regmap: register map
14001386 * @config: configuration to apply for pll
14011387 */
1402−void clk_lucid_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
1388+void clk_trion_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
14031389 const struct alpha_pll_config *config)
14041390 {
14051391 if (config->l)
14061392 regmap_write(regmap, PLL_L_VAL(pll), config->l);
14071393
1408− regmap_write(regmap, PLL_CAL_L_VAL(pll), LUCID_PLL_CAL_VAL);
1394+ regmap_write(regmap, PLL_CAL_L_VAL(pll), TRION_PLL_CAL_VAL);
14091395
14101396 if (config->alpha)
14111397 regmap_write(regmap, PLL_ALPHA_VAL(pll), config->alpha);
@@ -1458,13 +1444,13 @@ void clk_lucid_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, · 46 unmodified lines
14581444 /* Place the PLL in STANDBY mode */
14591445 regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N, PLL_RESET_N);
14601446 }
1461−EXPORT_SYMBOL_GPL(clk_lucid_pll_configure);
1447+EXPORT_SYMBOL_GPL(clk_trion_pll_configure);
14621448
14631449 /*
1464− * The Lucid PLL requires a power-on self-calibration which happens when the
1450+ * The TRION PLL requires a power-on self-calibration which happens when the
14651451 * PLL comes out of reset. Calibrate in case it is not completed.
14661452 */
1467−static int alpha_pll_lucid_prepare(struct clk_hw *hw)
1453+static int __alpha_pll_trion_prepare(struct clk_hw *hw, u32 pcal_done)
14681454 {
14691455 struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
14701456 u32 regval;
@@ -1472,7 +1458,7 @@ static int alpha_pll_lucid_prepare(struct clk_hw *hw) · 1 unmodified line
14721458
14731459 /* Return early if calibration is not needed. */
14741460 regmap_read(pll->clkr.regmap, PLL_STATUS(pll), &regval);
1475− if (regval & LUCID_PCAL_DONE)
1461+ if (regval & pcal_done)
14761462 return 0;
14771463
14781464 /* On/off to calibrate */
@@ -1483,7 +1469,17 @@ static int alpha_pll_lucid_prepare(struct clk_hw *hw) · 4 unmodified lines
14831469 return ret;
14841470 }
14851471
1486−static int alpha_pll_lucid_set_rate(struct clk_hw *hw, unsigned long rate,
1472+static int alpha_pll_trion_prepare(struct clk_hw *hw)
1473+{
1474+ return __alpha_pll_trion_prepare(hw, TRION_PCAL_DONE);
1475+}
1476+
1477+static int alpha_pll_lucid_prepare(struct clk_hw *hw)
1478+{
1479+ return __alpha_pll_trion_prepare(hw, LUCID_PCAL_DONE);
1480+}
1481+
1482+static int alpha_pll_trion_set_rate(struct clk_hw *hw, unsigned long rate,
14871483 unsigned long prate)
14881484 {
14891485 struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
@@ -1537,25 +1533,27 @@ static int alpha_pll_lucid_set_rate(struct clk_hw *hw, unsigned long rate, · 47 unmodified lines
15371533 return 0;
15381534 }
15391535
1540−const struct clk_ops clk_alpha_pll_lucid_ops = {
1541− .prepare = alpha_pll_lucid_prepare,
1536+const struct clk_ops clk_alpha_pll_trion_ops = {
1537+ .prepare = alpha_pll_trion_prepare,
15421538 .enable = clk_trion_pll_enable,
15431539 .disable = clk_trion_pll_disable,
15441540 .is_enabled = clk_trion_pll_is_enabled,
15451541 .recalc_rate = clk_trion_pll_recalc_rate,
15461542 .round_rate = clk_alpha_pll_round_rate,
1547− .set_rate = alpha_pll_lucid_set_rate,
1543+ .set_rate = alpha_pll_trion_set_rate,
15481544 };
1549−EXPORT_SYMBOL_GPL(clk_alpha_pll_lucid_ops);
1545+EXPORT_SYMBOL_GPL(clk_alpha_pll_trion_ops);
15501546
1551−const struct clk_ops clk_alpha_pll_fixed_lucid_ops = {
1547+const struct clk_ops clk_alpha_pll_lucid_ops = {
1548+ .prepare = alpha_pll_lucid_prepare,
15521549 .enable = clk_trion_pll_enable,
15531550 .disable = clk_trion_pll_disable,
15541551 .is_enabled = clk_trion_pll_is_enabled,
15551552 .recalc_rate = clk_trion_pll_recalc_rate,
15561553 .round_rate = clk_alpha_pll_round_rate,
1554+ .set_rate = alpha_pll_trion_set_rate,
15571555 };
1558−EXPORT_SYMBOL_GPL(clk_alpha_pll_fixed_lucid_ops);
1556+EXPORT_SYMBOL_GPL(clk_alpha_pll_lucid_ops);
15591557
15601558 const struct clk_ops clk_alpha_pll_postdiv_lucid_ops = {
15611559 .recalc_rate = clk_alpha_pll_postdiv_fabia_recalc_rate,
drivers/clk/qcom/clk-alpha-pll.h+10−5
@@ -14,7 +14,7 @@ enum { · 13 unmodified lines
1414 CLK_ALPHA_PLL_TYPE_BRAMMO,
1515 CLK_ALPHA_PLL_TYPE_FABIA,
1616 CLK_ALPHA_PLL_TYPE_TRION,
17− CLK_ALPHA_PLL_TYPE_LUCID,
17+ CLK_ALPHA_PLL_TYPE_LUCID = CLK_ALPHA_PLL_TYPE_TRION,
1818 CLK_ALPHA_PLL_TYPE_MAX,
1919 };
2020
@@ -134,18 +134,23 @@ extern const struct clk_ops clk_alpha_pll_fabia_ops; · 113 unmodified lines
134134 extern const struct clk_ops clk_alpha_pll_fixed_fabia_ops;
135135 extern const struct clk_ops clk_alpha_pll_postdiv_fabia_ops;
136136
137+extern const struct clk_ops clk_alpha_pll_trion_ops;
138+extern const struct clk_ops clk_alpha_pll_fixed_trion_ops;
139+extern const struct clk_ops clk_alpha_pll_postdiv_trion_ops;
140+
137141 extern const struct clk_ops clk_alpha_pll_lucid_ops;
138−extern const struct clk_ops clk_alpha_pll_fixed_lucid_ops;
142+#define clk_alpha_pll_fixed_lucid_ops clk_alpha_pll_fixed_trion_ops
139143 extern const struct clk_ops clk_alpha_pll_postdiv_lucid_ops;
140144
141145 void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
142146 const struct alpha_pll_config *config);
143147 void clk_fabia_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
144148 const struct alpha_pll_config *config);
145−void clk_lucid_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
149+void clk_trion_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
146150 const struct alpha_pll_config *config);
151+#define clk_lucid_pll_configure(pll, regmap, config) \
152+ clk_trion_pll_configure(pll, regmap, config)
153+
147154
148−extern const struct clk_ops clk_trion_fixed_pll_ops;
149−extern const struct clk_ops clk_trion_pll_postdiv_ops;
150155
151156 #endif
drivers/clk/qcom/gcc-sc7180.c+14−0
@@ -2251,6 +2251,19 @@ static struct clk_branch gcc_mss_q6_memnoc_axi_clk = { · 2250 unmodified lines
22512251 },
22522252 };
22532253
2254+static struct clk_branch gcc_lpass_cfg_noc_sway_clk = {
2255+ .halt_reg = 0x47018,
2256+ .halt_check = BRANCH_HALT_DELAY,
2257+ .clkr = {
2258+ .enable_reg = 0x47018,
2259+ .enable_mask = BIT(0),
2260+ .hw.init = &(struct clk_init_data){
2261+ .name = "gcc_lpass_cfg_noc_sway_clk",
2262+ .ops = &clk_branch2_ops,
2263+ },
2264+ },
2265+};
2266+
22542267 static struct gdsc ufs_phy_gdsc = {
22552268 .gdscr = 0x77004,
22562269 .pd = {
@@ -2428,6 +2441,7 @@ static struct clk_regmap *gcc_sc7180_clocks[] = { · 171 unmodified lines
24282441 [GCC_MSS_Q6_MEMNOC_AXI_CLK] = &gcc_mss_q6_memnoc_axi_clk.clkr,
24292442 [GCC_MSS_SNOC_AXI_CLK] = &gcc_mss_snoc_axi_clk.clkr,
24302443 [GCC_SEC_CTRL_CLK_SRC] = &gcc_sec_ctrl_clk_src.clkr,
2444+ [GCC_LPASS_CFG_NOC_SWAY_CLK] = &gcc_lpass_cfg_noc_sway_clk.clkr,
24312445 };
24322446
24332447 static const struct qcom_reset_map gcc_sc7180_resets[] = {
drivers/clk/qcom/gcc-sdm660.c+4−0
@@ -1715,6 +1715,9 @@ static struct clk_branch gcc_mss_cfg_ahb_clk = { · 1714 unmodified lines
17151715
17161716 static struct clk_branch gcc_mss_mnoc_bimc_axi_clk = {
17171717 .halt_reg = 0x8a004,
1718+ .halt_check = BRANCH_HALT,
1719+ .hwcg_reg = 0x8a004,
1720+ .hwcg_bit = 1,
17181721 .clkr = {
17191722 .enable_reg = 0x8a004,
17201723 .enable_mask = BIT(0),
@@ -2402,6 +2405,7 @@ static const struct qcom_reset_map gcc_sdm660_resets[] = { · 681 unmodified lines
24022405 [GCC_USB_20_BCR] = { 0x2f000 },
24032406 [GCC_USB_30_BCR] = { 0xf000 },
24042407 [GCC_USB_PHY_CFG_AHB2PHY_BCR] = { 0x6a000 },
2408+ [GCC_MSS_RESTART] = { 0x79000 },
24052409 };
24062410
24072411 static const struct regmap_config gcc_sdm660_regmap_config = {
drivers/clk/qcom/gcc-sm8150.c+10−16
@@ -34,14 +34,8 @@ enum { · 33 unmodified lines
3434 P_SLEEP_CLK,
3535 };
3636
37−static const struct pll_vco trion_vco[] = {
38− { 249600000, 2000000000, 0 },
39−};
40−
4137 static struct clk_alpha_pll gpll0 = {
4238 .offset = 0x0,
43− .vco_table = trion_vco,
44− .num_vco = ARRAY_SIZE(trion_vco),
4539 .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TRION],
4640 .clkr = {
4741 .enable_reg = 0x52000,
@@ -53,7 +47,7 @@ static struct clk_alpha_pll gpll0 = { · 5 unmodified lines
5347 .name = "bi_tcxo",
5448 },
5549 .num_parents = 1,
56− .ops = &clk_trion_fixed_pll_ops,
50+ .ops = &clk_alpha_pll_fixed_trion_ops,
5751 },
5852 },
5953 };
@@ -79,14 +73,12 @@ static struct clk_alpha_pll_postdiv gpll0_out_even = { · 19 unmodified lines
7973 .hw = &gpll0.clkr.hw,
8074 },
8175 .num_parents = 1,
82− .ops = &clk_trion_pll_postdiv_ops,
76+ .ops = &clk_alpha_pll_postdiv_trion_ops,
8377 },
8478 };
8579
8680 static struct clk_alpha_pll gpll7 = {
8781 .offset = 0x1a000,
88− .vco_table = trion_vco,
89− .num_vco = ARRAY_SIZE(trion_vco),
9082 .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TRION],
9183 .clkr = {
9284 .enable_reg = 0x52000,
@@ -98,15 +90,13 @@ static struct clk_alpha_pll gpll7 = { · 5 unmodified lines
9890 .name = "bi_tcxo",
9991 },
10092 .num_parents = 1,
101− .ops = &clk_trion_fixed_pll_ops,
93+ .ops = &clk_alpha_pll_fixed_trion_ops,
10294 },
10395 },
10496 };
10597
10698 static struct clk_alpha_pll gpll9 = {
10799 .offset = 0x1c000,
108− .vco_table = trion_vco,
109− .num_vco = ARRAY_SIZE(trion_vco),
110100 .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TRION],
111101 .clkr = {
112102 .enable_reg = 0x52000,
@@ -118,7 +108,7 @@ static struct clk_alpha_pll gpll9 = { · 5 unmodified lines
118108 .name = "bi_tcxo",
119109 },
120110 .num_parents = 1,
121− .ops = &clk_trion_fixed_pll_ops,
111+ .ops = &clk_alpha_pll_fixed_trion_ops,
122112 },
123113 },
124114 };
@@ -1617,6 +1607,7 @@ static struct clk_branch gcc_gpu_cfg_ahb_clk = { · 1492 unmodified lines
16171607 };
16181608
16191609 static struct clk_branch gcc_gpu_gpll0_clk_src = {
1610+ .halt_check = BRANCH_HALT_SKIP,
16201611 .clkr = {
16211612 .enable_reg = 0x52004,
16221613 .enable_mask = BIT(15),
@@ -1632,13 +1623,14 @@ static struct clk_branch gcc_gpu_gpll0_clk_src = { · 9 unmodified lines
16321623 };
16331624
16341625 static struct clk_branch gcc_gpu_gpll0_div_clk_src = {
1626+ .halt_check = BRANCH_HALT_SKIP,
16351627 .clkr = {
16361628 .enable_reg = 0x52004,
16371629 .enable_mask = BIT(16),
16381630 .hw.init = &(struct clk_init_data){
16391631 .name = "gcc_gpu_gpll0_div_clk_src",
16401632 .parent_hws = (const struct clk_hw *[]){
1641− &gcc_gpu_gpll0_clk_src.clkr.hw },
1633+ &gpll0_out_even.clkr.hw },
16421634 .num_parents = 1,
16431635 .flags = CLK_SET_RATE_PARENT,
16441636 .ops = &clk_branch2_ops,
@@ -1729,6 +1721,7 @@ static struct clk_branch gcc_npu_cfg_ahb_clk = { · 84 unmodified lines
17291721 };
17301722
17311723 static struct clk_branch gcc_npu_gpll0_clk_src = {
1724+ .halt_check = BRANCH_HALT_SKIP,
17321725 .clkr = {
17331726 .enable_reg = 0x52004,
17341727 .enable_mask = BIT(18),
@@ -1744,13 +1737,14 @@ static struct clk_branch gcc_npu_gpll0_clk_src = { · 9 unmodified lines
17441737 };
17451738
17461739 static struct clk_branch gcc_npu_gpll0_div_clk_src = {
1740+ .halt_check = BRANCH_HALT_SKIP,
17471741 .clkr = {
17481742 .enable_reg = 0x52004,
17491743 .enable_mask = BIT(19),
17501744 .hw.init = &(struct clk_init_data){
17511745 .name = "gcc_npu_gpll0_div_clk_src",
17521746 .parent_hws = (const struct clk_hw *[]){
1753− &gcc_npu_gpll0_clk_src.clkr.hw },
1747+ &gpll0_out_even.clkr.hw },
17541748 .num_parents = 1,
17551749 .flags = CLK_SET_RATE_PARENT,
17561750 .ops = &clk_branch2_ops,
drivers/clk/qcom/gdsc.c+39−0
@@ -6,6 +6,7 @@ · 5 unmodified lines
66 #include <linux/bitops.h>
77 #include <linux/delay.h>
88 #include <linux/err.h>
9+#include <linux/export.h>
910 #include <linux/jiffies.h>
1011 #include <linux/kernel.h>
1112 #include <linux/ktime.h>
@@ -29,6 +30,7 @@ · 17 unmodified lines
2930 /* CFG_GDSCR */
3031 #define GDSC_POWER_UP_COMPLETE BIT(16)
3132 #define GDSC_POWER_DOWN_COMPLETE BIT(15)
33+#define GDSC_RETAIN_FF_ENABLE BIT(11)
3234 #define CFG_GDSCR_OFFSET 0x4
3335
3436 /* Wait 2^n CXO cycles between all states. Here, n=2 (4 cycles). */
@@ -216,6 +218,14 @@ static inline void gdsc_assert_reset_aon(struct gdsc *sc) · 181 unmodified lines
216218 regmap_update_bits(sc->regmap, sc->clamp_io_ctrl,
217219 GMEM_RESET_MASK, 0);
218220 }
221+
222+static void gdsc_retain_ff_on(struct gdsc *sc)
223+{
224+ u32 mask = GDSC_RETAIN_FF_ENABLE;
225+
226+ regmap_update_bits(sc->regmap, sc->gdscr, mask, mask);
227+}
228+
219229 static int gdsc_enable(struct generic_pm_domain *domain)
220230 {
221231 struct gdsc *sc = domain_to_gdsc(domain);
@@ -268,6 +278,9 @@ static int gdsc_enable(struct generic_pm_domain *domain) · 46 unmodified lines
268278 udelay(1);
269279 }
270280
281+ if (sc->flags & RETAIN_FF_ENABLE)
282+ gdsc_retain_ff_on(sc);
283+
271284 return 0;
272285 }
273286
@@ -433,3 +446,29 @@ void gdsc_unregister(struct gdsc_desc *desc) · 159 unmodified lines
433446 }
434447 of_genpd_del_provider(dev->of_node);
435448 }
449+
450+/*
451+ * On SDM845+ the GPU GX domain is *almost* entirely controlled by the GMU
452+ * running in the CX domain so the CPU doesn't need to know anything about the
453+ * GX domain EXCEPT....
454+ *
455+ * Hardware constraints dictate that the GX be powered down before the CX. If
456+ * the GMU crashes it could leave the GX on. In order to successfully bring back
457+ * the device the CPU needs to disable the GX headswitch. There being no sane
458+ * way to reach in and touch that register from deep inside the GPU driver we
459+ * need to set up the infrastructure to be able to ensure that the GPU can
460+ * ensure that the GX is off during this super special case. We do this by
461+ * defining a GX gdsc with a dummy enable function and a "default" disable
462+ * function.
463+ *
464+ * This allows us to attach with genpd_dev_pm_attach_by_name() in the GPU
465+ * driver. During power up, nothing will happen from the CPU (and the GMU will
466+ * power up normally but during power down this will ensure that the GX domain
467+ * is *really* off - this gives us a semi standard way of doing what we need.
468+ */
469+int gdsc_gx_do_nothing_enable(struct generic_pm_domain *domain)
470+{
471+ /* Do nothing but give genpd the impression that we were successful */
472+ return 0;
473+}
474+EXPORT_SYMBOL_GPL(gdsc_gx_do_nothing_enable);
drivers/clk/qcom/gdsc.h+2−0
@@ -50,6 +50,7 @@ struct gdsc { · 49 unmodified lines
5050 #define AON_RESET BIT(4)
5151 #define POLL_CFG_GDSCR BIT(5)
5252 #define ALWAYS_ON BIT(6)
53+#define RETAIN_FF_ENABLE BIT(7)
5354 struct reset_controller_dev *rcdev;
5455 unsigned int *resets;
5556 unsigned int reset_count;
@@ -68,6 +69,7 @@ struct gdsc_desc { · 12 unmodified lines
6869 int gdsc_register(struct gdsc_desc *desc, struct reset_controller_dev *,
6970 struct regmap *);
7071 void gdsc_unregister(struct gdsc_desc *desc);
72+int gdsc_gx_do_nothing_enable(struct generic_pm_domain *domain);
7173 #else
7274 static inline int gdsc_register(struct gdsc_desc *desc,
7375 struct reset_controller_dev *rcdev,
drivers/clk/qcom/gpucc-sc7180.c+1−26
@@ -170,37 +170,12 @@ static struct gdsc cx_gdsc = { · 169 unmodified lines
170170 .flags = VOTABLE,
171171 };
172172
173−/*
174− * On SC7180 the GPU GX domain is *almost* entirely controlled by the GMU
175− * running in the CX domain so the CPU doesn't need to know anything about the
176− * GX domain EXCEPT....
177− *
178− * Hardware constraints dictate that the GX be powered down before the CX. If
179− * the GMU crashes it could leave the GX on. In order to successfully bring back
180− * the device the CPU needs to disable the GX headswitch. There being no sane
181− * way to reach in and touch that register from deep inside the GPU driver we
182− * need to set up the infrastructure to be able to ensure that the GPU can
183− * ensure that the GX is off during this super special case. We do this by
184− * defining a GX gdsc with a dummy enable function and a "default" disable
185− * function.
186− *
187− * This allows us to attach with genpd_dev_pm_attach_by_name() in the GPU
188− * driver. During power up, nothing will happen from the CPU (and the GMU will
189− * power up normally but during power down this will ensure that the GX domain
190− * is *really* off - this gives us a semi standard way of doing what we need.
191− */
192−static int gx_gdsc_enable(struct generic_pm_domain *domain)
193−{
194− /* Do nothing but give genpd the impression that we were successful */
195− return 0;
196−}
197−
198173 static struct gdsc gx_gdsc = {
199174 .gdscr = 0x100c,
200175 .clamp_io_ctrl = 0x1508,
201176 .pd = {
202177 .name = "gx_gdsc",
203− .power_on = gx_gdsc_enable,
178+ .power_on = gdsc_gx_do_nothing_enable,
204179 },
205180 .pwrsts = PWRSTS_OFF_ON,
206181 .flags = CLAMP_IO,
drivers/clk/qcom/gpucc-sdm845.c+1−26
@@ -131,37 +131,12 @@ static struct gdsc gpu_cx_gdsc = { · 130 unmodified lines
131131 .flags = VOTABLE,
132132 };
133133
134−/*
135− * On SDM845 the GPU GX domain is *almost* entirely controlled by the GMU
136− * running in the CX domain so the CPU doesn't need to know anything about the
137− * GX domain EXCEPT....
138− *
139− * Hardware constraints dictate that the GX be powered down before the CX. If
140− * the GMU crashes it could leave the GX on. In order to successfully bring back
141− * the device the CPU needs to disable the GX headswitch. There being no sane
142− * way to reach in and touch that register from deep inside the GPU driver we
143− * need to set up the infrastructure to be able to ensure that the GPU can
144− * ensure that the GX is off during this super special case. We do this by
145− * defining a GX gdsc with a dummy enable function and a "default" disable
146− * function.
147− *
148− * This allows us to attach with genpd_dev_pm_attach_by_name() in the GPU
149− * driver. During power up, nothing will happen from the CPU (and the GMU will
150− * power up normally but during power down this will ensure that the GX domain
151− * is *really* off - this gives us a semi standard way of doing what we need.
152− */
153−static int gx_gdsc_enable(struct generic_pm_domain *domain)
154−{
155− /* Do nothing but give genpd the impression that we were successful */
156− return 0;
157−}
158−
159134 static struct gdsc gpu_gx_gdsc = {
160135 .gdscr = 0x100c,
161136 .clamp_io_ctrl = 0x1508,
162137 .pd = {
163138 .name = "gpu_gx_gdsc",
164− .power_on = gx_gdsc_enable,
139+ .power_on = gdsc_gx_do_nothing_enable,
165140 },
166141 .pwrsts = PWRSTS_OFF_ON,
167142 .flags = CLAMP_IO | AON_RESET | POLL_CFG_GDSCR,
drivers/clk/qcom/gpucc-sm8150.c+320−0
@@ -0,0 +1,320 @@
1+// SPDX-License-Identifier: GPL-2.0
2+/*
3+ * Copyright (c) 2017-2020, 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+
11+#include <dt-bindings/clock/qcom,gpucc-sm8150.h>
12+
13+#include "common.h"
14+#include "clk-alpha-pll.h"
15+#include "clk-branch.h"
16+#include "clk-pll.h"
17+#include "clk-rcg.h"
18+#include "clk-regmap.h"
19+#include "reset.h"
20+#include "gdsc.h"
21+
22+enum {
23+ P_BI_TCXO,
24+ P_CORE_BI_PLL_TEST_SE,
25+ P_GPLL0_OUT_MAIN,
26+ P_GPLL0_OUT_MAIN_DIV,
27+ P_GPU_CC_PLL1_OUT_MAIN,
28+};
29+
30+static const struct pll_vco trion_vco[] = {
31+ { 249600000, 2000000000, 0 },
32+};
33+
34+static struct alpha_pll_config gpu_cc_pll1_config = {
35+ .l = 0x1a,
36+ .alpha = 0xaaa,
37+ .config_ctl_val = 0x20485699,
38+ .config_ctl_hi_val = 0x00002267,
39+ .config_ctl_hi1_val = 0x00000024,
40+ .test_ctl_val = 0x00000000,
41+ .test_ctl_hi_val = 0x00000002,
42+ .test_ctl_hi1_val = 0x00000000,
43+ .user_ctl_val = 0x00000000,
44+ .user_ctl_hi_val = 0x00000805,
45+ .user_ctl_hi1_val = 0x000000d0,
46+};
47+
48+static struct clk_alpha_pll gpu_cc_pll1 = {
49+ .offset = 0x100,
50+ .vco_table = trion_vco,
51+ .num_vco = ARRAY_SIZE(trion_vco),
52+ .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TRION],
53+ .clkr = {
54+ .hw.init = &(struct clk_init_data){
55+ .name = "gpu_cc_pll1",
56+ .parent_data = &(const struct clk_parent_data){
57+ .fw_name = "bi_tcxo",
58+ },
59+ .num_parents = 1,
60+ .ops = &clk_alpha_pll_trion_ops,
61+ },
62+ },
63+};
64+
65+static const struct parent_map gpu_cc_parent_map_0[] = {
66+ { P_BI_TCXO, 0 },
67+ { P_GPU_CC_PLL1_OUT_MAIN, 3 },
68+ { P_GPLL0_OUT_MAIN, 5 },
69+ { P_GPLL0_OUT_MAIN_DIV, 6 },
70+};
71+
72+static const struct clk_parent_data gpu_cc_parent_data_0[] = {
73+ { .fw_name = "bi_tcxo" },
74+ { .hw = &gpu_cc_pll1.clkr.hw },
75+ { .fw_name = "gcc_gpu_gpll0_clk_src" },
76+ { .fw_name = "gcc_gpu_gpll0_div_clk_src" },
77+};
78+
79+static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = {
80+ F(19200000, P_BI_TCXO, 1, 0, 0),
81+ F(200000000, P_GPLL0_OUT_MAIN_DIV, 1.5, 0, 0),
82+ F(500000000, P_GPU_CC_PLL1_OUT_MAIN, 1, 0, 0),
83+ { }
84+};
85+
86+static struct clk_rcg2 gpu_cc_gmu_clk_src = {
87+ .cmd_rcgr = 0x1120,
88+ .mnd_width = 0,
89+ .hid_width = 5,
90+ .parent_map = gpu_cc_parent_map_0,
91+ .freq_tbl = ftbl_gpu_cc_gmu_clk_src,
92+ .clkr.hw.init = &(struct clk_init_data){
93+ .name = "gpu_cc_gmu_clk_src",
94+ .parent_data = gpu_cc_parent_data_0,
95+ .num_parents = ARRAY_SIZE(gpu_cc_parent_data_0),
96+ .flags = CLK_SET_RATE_PARENT,
97+ .ops = &clk_rcg2_ops,
98+ },
99+};
100+
101+static struct clk_branch gpu_cc_ahb_clk = {
102+ .halt_reg = 0x1078,
103+ .halt_check = BRANCH_HALT_DELAY,
104+ .clkr = {
105+ .enable_reg = 0x1078,
106+ .enable_mask = BIT(0),
107+ .hw.init = &(struct clk_init_data){
108+ .name = "gpu_cc_ahb_clk",
109+ .ops = &clk_branch2_ops,
110+ },
111+ },
112+};
113+
114+static struct clk_branch gpu_cc_crc_ahb_clk = {
115+ .halt_reg = 0x107c,
116+ .halt_check = BRANCH_HALT,
117+ .clkr = {
118+ .enable_reg = 0x107c,
119+ .enable_mask = BIT(0),
120+ .hw.init = &(struct clk_init_data){
121+ .name = "gpu_cc_crc_ahb_clk",
122+ .ops = &clk_branch2_ops,
123+ },
124+ },
125+};
126+
127+static struct clk_branch gpu_cc_cx_apb_clk = {
128+ .halt_reg = 0x1088,
129+ .halt_check = BRANCH_HALT,
130+ .clkr = {
131+ .enable_reg = 0x1088,
132+ .enable_mask = BIT(0),
133+ .hw.init = &(struct clk_init_data){
134+ .name = "gpu_cc_cx_apb_clk",
135+ .ops = &clk_branch2_ops,
136+ },
137+ },
138+};
139+
140+static struct clk_branch gpu_cc_cx_gmu_clk = {
141+ .halt_reg = 0x1098,
142+ .halt_check = BRANCH_HALT,
143+ .clkr = {
144+ .enable_reg = 0x1098,
145+ .enable_mask = BIT(0),
146+ .hw.init = &(struct clk_init_data){
147+ .name = "gpu_cc_cx_gmu_clk",
148+ .parent_data = &(const struct clk_parent_data){
149+ .hw = &gpu_cc_gmu_clk_src.clkr.hw,
150+ },
151+ .num_parents = 1,
152+ .flags = CLK_SET_RATE_PARENT,
153+ .ops = &clk_branch2_ops,
154+ },
155+ },
156+};
157+
158+static struct clk_branch gpu_cc_cx_snoc_dvm_clk = {
159+ .halt_reg = 0x108c,
160+ .halt_check = BRANCH_HALT,
161+ .clkr = {
162+ .enable_reg = 0x108c,
163+ .enable_mask = BIT(0),
164+ .hw.init = &(struct clk_init_data){
165+ .name = "gpu_cc_cx_snoc_dvm_clk",
166+ .ops = &clk_branch2_ops,
167+ },
168+ },
169+};
170+
171+static struct clk_branch gpu_cc_cxo_aon_clk = {
172+ .halt_reg = 0x1004,
173+ .halt_check = BRANCH_HALT,
174+ .clkr = {
175+ .enable_reg = 0x1004,
176+ .enable_mask = BIT(0),
177+ .hw.init = &(struct clk_init_data){
178+ .name = "gpu_cc_cxo_aon_clk",
179+ .ops = &clk_branch2_ops,
180+ },
181+ },
182+};
183+
184+static struct clk_branch gpu_cc_cxo_clk = {
185+ .halt_reg = 0x109c,
186+ .halt_check = BRANCH_HALT,
187+ .clkr = {
188+ .enable_reg = 0x109c,
189+ .enable_mask = BIT(0),
190+ .hw.init = &(struct clk_init_data){
191+ .name = "gpu_cc_cxo_clk",
192+ .ops = &clk_branch2_ops,
193+ },
194+ },
195+};
196+
197+static struct clk_branch gpu_cc_gx_gmu_clk = {
198+ .halt_reg = 0x1064,
199+ .halt_check = BRANCH_HALT,
200+ .clkr = {
201+ .enable_reg = 0x1064,
202+ .enable_mask = BIT(0),
203+ .hw.init = &(struct clk_init_data){
204+ .name = "gpu_cc_gx_gmu_clk",
205+ .parent_data = &(const struct clk_parent_data){
206+ .hw = &gpu_cc_gmu_clk_src.clkr.hw,
207+ },
208+ .num_parents = 1,
209+ .flags = CLK_SET_RATE_PARENT,
210+ .ops = &clk_branch2_ops,
211+ },
212+ },
213+};
214+
215+static struct gdsc gpu_cx_gdsc = {
216+ .gdscr = 0x106c,
217+ .gds_hw_ctrl = 0x1540,
218+ .pd = {
219+ .name = "gpu_cx_gdsc",
220+ },
221+ .pwrsts = PWRSTS_OFF_ON,
222+ .flags = VOTABLE,
223+};
224+
225+static struct gdsc gpu_gx_gdsc = {
226+ .gdscr = 0x100c,
227+ .clamp_io_ctrl = 0x1508,
228+ .pd = {
229+ .name = "gpu_gx_gdsc",
230+ .power_on = gdsc_gx_do_nothing_enable,
231+ },
232+ .pwrsts = PWRSTS_OFF_ON,
233+ .flags = CLAMP_IO | AON_RESET | POLL_CFG_GDSCR,
234+};
235+
236+static struct clk_regmap *gpu_cc_sm8150_clocks[] = {
237+ [GPU_CC_AHB_CLK] = &gpu_cc_ahb_clk.clkr,
238+ [GPU_CC_CRC_AHB_CLK] = &gpu_cc_crc_ahb_clk.clkr,
239+ [GPU_CC_CX_APB_CLK] = &gpu_cc_cx_apb_clk.clkr,
240+ [GPU_CC_CX_GMU_CLK] = &gpu_cc_cx_gmu_clk.clkr,
241+ [GPU_CC_CX_SNOC_DVM_CLK] = &gpu_cc_cx_snoc_dvm_clk.clkr,
242+ [GPU_CC_CXO_AON_CLK] = &gpu_cc_cxo_aon_clk.clkr,
243+ [GPU_CC_CXO_CLK] = &gpu_cc_cxo_clk.clkr,
244+ [GPU_CC_GMU_CLK_SRC] = &gpu_cc_gmu_clk_src.clkr,
245+ [GPU_CC_GX_GMU_CLK] = &gpu_cc_gx_gmu_clk.clkr,
246+ [GPU_CC_PLL1] = &gpu_cc_pll1.clkr,
247+};
248+
249+static const struct qcom_reset_map gpu_cc_sm8150_resets[] = {
250+ [GPUCC_GPU_CC_CX_BCR] = { 0x1068 },
251+ [GPUCC_GPU_CC_GMU_BCR] = { 0x111c },
252+ [GPUCC_GPU_CC_GX_BCR] = { 0x1008 },
253+ [GPUCC_GPU_CC_SPDM_BCR] = { 0x1110 },
254+ [GPUCC_GPU_CC_XO_BCR] = { 0x1000 },
255+};
256+
257+static struct gdsc *gpu_cc_sm8150_gdscs[] = {
258+ [GPU_CX_GDSC] = &gpu_cx_gdsc,
259+ [GPU_GX_GDSC] = &gpu_gx_gdsc,
260+};
261+
262+static const struct regmap_config gpu_cc_sm8150_regmap_config = {
263+ .reg_bits = 32,
264+ .reg_stride = 4,
265+ .val_bits = 32,
266+ .max_register = 0x8008,
267+ .fast_io = true,
268+};
269+
270+static const struct qcom_cc_desc gpu_cc_sm8150_desc = {
271+ .config = &gpu_cc_sm8150_regmap_config,
272+ .clks = gpu_cc_sm8150_clocks,
273+ .num_clks = ARRAY_SIZE(gpu_cc_sm8150_clocks),
274+ .resets = gpu_cc_sm8150_resets,
275+ .num_resets = ARRAY_SIZE(gpu_cc_sm8150_resets),
276+ .gdscs = gpu_cc_sm8150_gdscs,
277+ .num_gdscs = ARRAY_SIZE(gpu_cc_sm8150_gdscs),
278+};
279+
280+static const struct of_device_id gpu_cc_sm8150_match_table[] = {
281+ { .compatible = "qcom,sm8150-gpucc" },
282+ { }
283+};
284+MODULE_DEVICE_TABLE(of, gpu_cc_sm8150_match_table);
285+
286+static int gpu_cc_sm8150_probe(struct platform_device *pdev)
287+{
288+ struct regmap *regmap;
289+
290+ regmap = qcom_cc_map(pdev, &gpu_cc_sm8150_desc);
291+ if (IS_ERR(regmap))
292+ return PTR_ERR(regmap);
293+
294+ clk_trion_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config);
295+
296+ return qcom_cc_really_probe(pdev, &gpu_cc_sm8150_desc, regmap);
297+}
298+
299+static struct platform_driver gpu_cc_sm8150_driver = {
300+ .probe = gpu_cc_sm8150_probe,
301+ .driver = {
302+ .name = "sm8150-gpucc",
303+ .of_match_table = gpu_cc_sm8150_match_table,
304+ },
305+};
306+
307+static int __init gpu_cc_sm8150_init(void)
308+{
309+ return platform_driver_register(&gpu_cc_sm8150_driver);
310+}
311+subsys_initcall(gpu_cc_sm8150_init);
312+
313+static void __exit gpu_cc_sm8150_exit(void)
314+{
315+ platform_driver_unregister(&gpu_cc_sm8150_driver);
316+}
317+module_exit(gpu_cc_sm8150_exit);
318+
319+MODULE_DESCRIPTION("QTI GPUCC SM8150 Driver");
320+MODULE_LICENSE("GPL v2");
drivers/clk/qcom/gpucc-sm8250.c+348−0
@@ -0,0 +1,348 @@
1+// SPDX-License-Identifier: GPL-2.0
2+/*
3+ * Copyright (c) 2018-2020, 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+
11+#include <dt-bindings/clock/qcom,gpucc-sm8250.h>
12+
13+#include "common.h"
14+#include "clk-alpha-pll.h"
15+#include "clk-branch.h"
16+#include "clk-pll.h"
17+#include "clk-rcg.h"
18+#include "clk-regmap.h"
19+#include "reset.h"
20+#include "gdsc.h"
21+
22+#define CX_GMU_CBCR_SLEEP_MASK 0xf
23+#define CX_GMU_CBCR_SLEEP_SHIFT 4
24+#define CX_GMU_CBCR_WAKE_MASK 0xf
25+#define CX_GMU_CBCR_WAKE_SHIFT 8
26+
27+enum {
28+ P_BI_TCXO,
29+ P_CORE_BI_PLL_TEST_SE,
30+ P_GPLL0_OUT_MAIN,
31+ P_GPLL0_OUT_MAIN_DIV,
32+ P_GPU_CC_PLL0_OUT_MAIN,
33+ P_GPU_CC_PLL1_OUT_MAIN,
34+};
35+
36+static struct pll_vco lucid_vco[] = {
37+ { 249600000, 2000000000, 0 },
38+};
39+
40+static const struct alpha_pll_config gpu_cc_pll1_config = {
41+ .l = 0x1a,
42+ .alpha = 0xaaa,
43+ .config_ctl_val = 0x20485699,
44+ .config_ctl_hi_val = 0x00002261,
45+ .config_ctl_hi1_val = 0x029a699c,
46+ .user_ctl_val = 0x00000000,
47+ .user_ctl_hi_val = 0x00000805,
48+ .user_ctl_hi1_val = 0x00000000,
49+};
50+
51+static struct clk_alpha_pll gpu_cc_pll1 = {
52+ .offset = 0x100,
53+ .vco_table = lucid_vco,
54+ .num_vco = ARRAY_SIZE(lucid_vco),
55+ .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID],
56+ .clkr = {
57+ .hw.init = &(struct clk_init_data){
58+ .name = "gpu_cc_pll1",
59+ .parent_data = &(const struct clk_parent_data){
60+ .fw_name = "bi_tcxo",
61+ },
62+ .num_parents = 1,
63+ .ops = &clk_alpha_pll_lucid_ops,
64+ },
65+ },
66+};
67+
68+static const struct parent_map gpu_cc_parent_map_0[] = {
69+ { P_BI_TCXO, 0 },
70+ { P_GPU_CC_PLL1_OUT_MAIN, 3 },
71+ { P_GPLL0_OUT_MAIN, 5 },
72+ { P_GPLL0_OUT_MAIN_DIV, 6 },
73+};
74+
75+static const struct clk_parent_data gpu_cc_parent_data_0[] = {
76+ { .fw_name = "bi_tcxo" },
77+ { .hw = &gpu_cc_pll1.clkr.hw },
78+ { .fw_name = "gcc_gpu_gpll0_clk_src" },
79+ { .fw_name = "gcc_gpu_gpll0_div_clk_src" },
80+};
81+
82+static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = {
83+ F(19200000, P_BI_TCXO, 1, 0, 0),
84+ F(200000000, P_GPLL0_OUT_MAIN_DIV, 1.5, 0, 0),
85+ F(500000000, P_GPU_CC_PLL1_OUT_MAIN, 1, 0, 0),
86+ { }
87+};
88+
89+static struct clk_rcg2 gpu_cc_gmu_clk_src = {
90+ .cmd_rcgr = 0x1120,
91+ .mnd_width = 0,
92+ .hid_width = 5,
93+ .parent_map = gpu_cc_parent_map_0,
94+ .freq_tbl = ftbl_gpu_cc_gmu_clk_src,
95+ .clkr.hw.init = &(struct clk_init_data){
96+ .name = "gpu_cc_gmu_clk_src",
97+ .parent_data = gpu_cc_parent_data_0,
98+ .num_parents = ARRAY_SIZE(gpu_cc_parent_data_0),
99+ .flags = CLK_SET_RATE_PARENT,
100+ .ops = &clk_rcg2_ops,
101+ },
102+};
103+
104+static struct clk_branch gpu_cc_ahb_clk = {
105+ .halt_reg = 0x1078,
106+ .halt_check = BRANCH_HALT_DELAY,
107+ .clkr = {
108+ .enable_reg = 0x1078,
109+ .enable_mask = BIT(0),
110+ .hw.init = &(struct clk_init_data){
111+ .name = "gpu_cc_ahb_clk",
112+ .ops = &clk_branch2_ops,
113+ },
114+ },
115+};
116+
117+static struct clk_branch gpu_cc_crc_ahb_clk = {
118+ .halt_reg = 0x107c,
119+ .halt_check = BRANCH_HALT_VOTED,
120+ .clkr = {
121+ .enable_reg = 0x107c,
122+ .enable_mask = BIT(0),
123+ .hw.init = &(struct clk_init_data){
124+ .name = "gpu_cc_crc_ahb_clk",
125+ .ops = &clk_branch2_ops,
126+ },
127+ },
128+};
129+
130+static struct clk_branch gpu_cc_cx_apb_clk = {
131+ .halt_reg = 0x1088,
132+ .halt_check = BRANCH_HALT_VOTED,
133+ .clkr = {
134+ .enable_reg = 0x1088,
135+ .enable_mask = BIT(0),
136+ .hw.init = &(struct clk_init_data){
137+ .name = "gpu_cc_cx_apb_clk",
138+ .ops = &clk_branch2_ops,
139+ },
140+ },
141+};
142+
143+static struct clk_branch gpu_cc_cx_gmu_clk = {
144+ .halt_reg = 0x1098,
145+ .halt_check = BRANCH_HALT,
146+ .clkr = {
147+ .enable_reg = 0x1098,
148+ .enable_mask = BIT(0),
149+ .hw.init = &(struct clk_init_data){
150+ .name = "gpu_cc_cx_gmu_clk",
151+ .parent_data = &(const struct clk_parent_data){
152+ .hw = &gpu_cc_gmu_clk_src.clkr.hw,
153+ },
154+ .num_parents = 1,
155+ .flags = CLK_SET_RATE_PARENT,
156+ .ops = &clk_branch2_ops,
157+ },
158+ },
159+};
160+
161+static struct clk_branch gpu_cc_cx_snoc_dvm_clk = {
162+ .halt_reg = 0x108c,
163+ .halt_check = BRANCH_HALT_VOTED,
164+ .clkr = {
165+ .enable_reg = 0x108c,
166+ .enable_mask = BIT(0),
167+ .hw.init = &(struct clk_init_data){
168+ .name = "gpu_cc_cx_snoc_dvm_clk",
169+ .ops = &clk_branch2_ops,
170+ },
171+ },
172+};
173+
174+static struct clk_branch gpu_cc_cxo_aon_clk = {
175+ .halt_reg = 0x1004,
176+ .halt_check = BRANCH_HALT_VOTED,
177+ .clkr = {
178+ .enable_reg = 0x1004,
179+ .enable_mask = BIT(0),
180+ .hw.init = &(struct clk_init_data){
181+ .name = "gpu_cc_cxo_aon_clk",
182+ .ops = &clk_branch2_ops,
183+ },
184+ },
185+};
186+
187+static struct clk_branch gpu_cc_cxo_clk = {
188+ .halt_reg = 0x109c,
189+ .halt_check = BRANCH_HALT,
190+ .clkr = {
191+ .enable_reg = 0x109c,
192+ .enable_mask = BIT(0),
193+ .hw.init = &(struct clk_init_data){
194+ .name = "gpu_cc_cxo_clk",
195+ .ops = &clk_branch2_ops,
196+ },
197+ },
198+};
199+
200+static struct clk_branch gpu_cc_gx_gmu_clk = {
201+ .halt_reg = 0x1064,
202+ .halt_check = BRANCH_HALT,
203+ .clkr = {
204+ .enable_reg = 0x1064,
205+ .enable_mask = BIT(0),
206+ .hw.init = &(struct clk_init_data){
207+ .name = "gpu_cc_gx_gmu_clk",
208+ .parent_data = &(const struct clk_parent_data){
209+ .hw = &gpu_cc_gmu_clk_src.clkr.hw,
210+ },
211+ .num_parents = 1,
212+ .flags = CLK_SET_RATE_PARENT,
213+ .ops = &clk_branch2_ops,
214+ },
215+ },
216+};
217+
218+static struct clk_branch gpu_cc_hlos1_vote_gpu_smmu_clk = {
219+ .halt_reg = 0x5000,
220+ .halt_check = BRANCH_VOTED,
221+ .clkr = {
222+ .enable_reg = 0x5000,
223+ .enable_mask = BIT(0),
224+ .hw.init = &(struct clk_init_data){
225+ .name = "gpu_cc_hlos1_vote_gpu_smmu_clk",
226+ .ops = &clk_branch2_ops,
227+ },
228+ },
229+};
230+
231+static struct gdsc gpu_cx_gdsc = {
232+ .gdscr = 0x106c,
233+ .gds_hw_ctrl = 0x1540,
234+ .pd = {
235+ .name = "gpu_cx_gdsc",
236+ },
237+ .pwrsts = PWRSTS_OFF_ON,
238+ .flags = VOTABLE,
239+};
240+
241+static struct gdsc gpu_gx_gdsc = {
242+ .gdscr = 0x100c,
243+ .clamp_io_ctrl = 0x1508,
244+ .pd = {
245+ .name = "gpu_gx_gdsc",
246+ .power_on = gdsc_gx_do_nothing_enable,
247+ },
248+ .pwrsts = PWRSTS_OFF_ON,
249+ .flags = CLAMP_IO | AON_RESET | POLL_CFG_GDSCR,
250+};
251+
252+static struct clk_regmap *gpu_cc_sm8250_clocks[] = {
253+ [GPU_CC_AHB_CLK] = &gpu_cc_ahb_clk.clkr,
254+ [GPU_CC_CRC_AHB_CLK] = &gpu_cc_crc_ahb_clk.clkr,
255+ [GPU_CC_CX_APB_CLK] = &gpu_cc_cx_apb_clk.clkr,
256+ [GPU_CC_CX_GMU_CLK] = &gpu_cc_cx_gmu_clk.clkr,
257+ [GPU_CC_CX_SNOC_DVM_CLK] = &gpu_cc_cx_snoc_dvm_clk.clkr,
258+ [GPU_CC_CXO_AON_CLK] = &gpu_cc_cxo_aon_clk.clkr,
259+ [GPU_CC_CXO_CLK] = &gpu_cc_cxo_clk.clkr,
260+ [GPU_CC_GMU_CLK_SRC] = &gpu_cc_gmu_clk_src.clkr,
261+ [GPU_CC_GX_GMU_CLK] = &gpu_cc_gx_gmu_clk.clkr,
262+ [GPU_CC_PLL1] = &gpu_cc_pll1.clkr,
263+ [GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK] = &gpu_cc_hlos1_vote_gpu_smmu_clk.clkr,
264+};
265+
266+static const struct qcom_reset_map gpu_cc_sm8250_resets[] = {
267+ [GPUCC_GPU_CC_ACD_BCR] = { 0x1160 },
268+ [GPUCC_GPU_CC_CX_BCR] = { 0x1068 },
269+ [GPUCC_GPU_CC_GFX3D_AON_BCR] = { 0x10a0 },
270+ [GPUCC_GPU_CC_GMU_BCR] = { 0x111c },
271+ [GPUCC_GPU_CC_GX_BCR] = { 0x1008 },
272+ [GPUCC_GPU_CC_XO_BCR] = { 0x1000 },
273+};
274+
275+static struct gdsc *gpu_cc_sm8250_gdscs[] = {
276+ [GPU_CX_GDSC] = &gpu_cx_gdsc,
277+ [GPU_GX_GDSC] = &gpu_gx_gdsc,
278+};
279+
280+static const struct regmap_config gpu_cc_sm8250_regmap_config = {
281+ .reg_bits = 32,
282+ .reg_stride = 4,
283+ .val_bits = 32,
284+ .max_register = 0x8008,
285+ .fast_io = true,
286+};
287+
288+static const struct qcom_cc_desc gpu_cc_sm8250_desc = {
289+ .config = &gpu_cc_sm8250_regmap_config,
290+ .clks = gpu_cc_sm8250_clocks,
291+ .num_clks = ARRAY_SIZE(gpu_cc_sm8250_clocks),
292+ .resets = gpu_cc_sm8250_resets,
293+ .num_resets = ARRAY_SIZE(gpu_cc_sm8250_resets),
294+ .gdscs = gpu_cc_sm8250_gdscs,
295+ .num_gdscs = ARRAY_SIZE(gpu_cc_sm8250_gdscs),
296+};
297+
298+static const struct of_device_id gpu_cc_sm8250_match_table[] = {
299+ { .compatible = "qcom,sm8250-gpucc" },
300+ { }
301+};
302+MODULE_DEVICE_TABLE(of, gpu_cc_sm8250_match_table);
303+
304+static int gpu_cc_sm8250_probe(struct platform_device *pdev)
305+{
306+ struct regmap *regmap;
307+ unsigned int value, mask;
308+
309+ regmap = qcom_cc_map(pdev, &gpu_cc_sm8250_desc);
310+ if (IS_ERR(regmap))
311+ return PTR_ERR(regmap);
312+
313+ clk_lucid_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config);
314+
315+ /*
316+ * Configure gpu_cc_cx_gmu_clk with recommended
317+ * wakeup/sleep settings
318+ */
319+ mask = CX_GMU_CBCR_WAKE_MASK << CX_GMU_CBCR_WAKE_SHIFT;
320+ mask |= CX_GMU_CBCR_SLEEP_MASK << CX_GMU_CBCR_SLEEP_SHIFT;
321+ value = 0xf << CX_GMU_CBCR_WAKE_SHIFT | 0xf << CX_GMU_CBCR_SLEEP_SHIFT;
322+ regmap_update_bits(regmap, 0x1098, mask, value);
323+
324+ return qcom_cc_really_probe(pdev, &gpu_cc_sm8250_desc, regmap);
325+}
326+
327+static struct platform_driver gpu_cc_sm8250_driver = {
328+ .probe = gpu_cc_sm8250_probe,
329+ .driver = {
330+ .name = "sm8250-gpucc",
331+ .of_match_table = gpu_cc_sm8250_match_table,
332+ },
333+};
334+
335+static int __init gpu_cc_sm8250_init(void)
336+{
337+ return platform_driver_register(&gpu_cc_sm8250_driver);
338+}
339+subsys_initcall(gpu_cc_sm8250_init);
340+
341+static void __exit gpu_cc_sm8250_exit(void)
342+{
343+ platform_driver_unregister(&gpu_cc_sm8250_driver);
344+}
345+module_exit(gpu_cc_sm8250_exit);
346+
347+MODULE_DESCRIPTION("QTI GPU_CC SM8250 Driver");
348+MODULE_LICENSE("GPL v2");
drivers/clk/qcom/lpasscorecc-sc7180.c+476−0
@@ -0,0 +1,476 @@
1+// SPDX-License-Identifier: GPL-2.0-only
2+/*
3+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
4+ */
5+
6+#include <linux/clk-provider.h>
7+#include <linux/err.h>
8+#include <linux/module.h>
9+#include <linux/of_device.h>
10+#include <linux/pm_clock.h>
11+#include <linux/pm_runtime.h>
12+#include <linux/of.h>
13+#include <linux/regmap.h>
14+
15+#include <dt-bindings/clock/qcom,lpasscorecc-sc7180.h>
16+
17+#include "clk-alpha-pll.h"
18+#include "clk-branch.h"
19+#include "clk-rcg.h"
20+#include "clk-regmap.h"
21+#include "common.h"
22+#include "gdsc.h"
23+
24+enum {
25+ P_BI_TCXO,
26+ P_LPASS_LPAAUDIO_DIG_PLL_OUT_ODD,
27+ P_SLEEP_CLK,
28+};
29+
30+static struct pll_vco fabia_vco[] = {
31+ { 249600000, 2000000000, 0 },
32+};
33+
34+static const struct alpha_pll_config lpass_lpaaudio_dig_pll_config = {
35+ .l = 0x20,
36+ .alpha = 0x0,
37+ .config_ctl_val = 0x20485699,
38+ .config_ctl_hi_val = 0x00002067,
39+ .test_ctl_val = 0x40000000,
40+ .test_ctl_hi_val = 0x00000000,
41+ .user_ctl_val = 0x00005105,
42+ .user_ctl_hi_val = 0x00004805,
43+};
44+
45+static const u8 clk_alpha_pll_regs_offset[][PLL_OFF_MAX_REGS] = {
46+ [CLK_ALPHA_PLL_TYPE_FABIA] = {
47+ [PLL_OFF_L_VAL] = 0x04,
48+ [PLL_OFF_CAL_L_VAL] = 0x8,
49+ [PLL_OFF_USER_CTL] = 0x0c,
50+ [PLL_OFF_USER_CTL_U] = 0x10,
51+ [PLL_OFF_USER_CTL_U1] = 0x14,
52+ [PLL_OFF_CONFIG_CTL] = 0x18,
53+ [PLL_OFF_CONFIG_CTL_U] = 0x1C,
54+ [PLL_OFF_CONFIG_CTL_U1] = 0x20,
55+ [PLL_OFF_TEST_CTL] = 0x24,
56+ [PLL_OFF_TEST_CTL_U] = 0x28,
57+ [PLL_OFF_STATUS] = 0x30,
58+ [PLL_OFF_OPMODE] = 0x38,
59+ [PLL_OFF_FRAC] = 0x40,
60+ },
61+};
62+
63+static struct clk_alpha_pll lpass_lpaaudio_dig_pll = {
64+ .offset = 0x1000,
65+ .vco_table = fabia_vco,
66+ .num_vco = ARRAY_SIZE(fabia_vco),
67+ .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_FABIA],
68+ .clkr = {
69+ .hw.init = &(struct clk_init_data){
70+ .name = "lpass_lpaaudio_dig_pll",
71+ .parent_data = &(const struct clk_parent_data){
72+ .fw_name = "bi_tcxo",
73+ },
74+ .num_parents = 1,
75+ .ops = &clk_alpha_pll_fabia_ops,
76+ },
77+ },
78+};
79+
80+static const struct clk_div_table
81+ post_div_table_lpass_lpaaudio_dig_pll_out_odd[] = {
82+ { 0x5, 5 },
83+ { }
84+};
85+
86+static struct clk_alpha_pll_postdiv lpass_lpaaudio_dig_pll_out_odd = {
87+ .offset = 0x1000,
88+ .post_div_shift = 12,
89+ .post_div_table = post_div_table_lpass_lpaaudio_dig_pll_out_odd,
90+ .num_post_div =
91+ ARRAY_SIZE(post_div_table_lpass_lpaaudio_dig_pll_out_odd),
92+ .width = 4,
93+ .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
94+ .clkr.hw.init = &(struct clk_init_data){
95+ .name = "lpass_lpaaudio_dig_pll_out_odd",
96+ .parent_data = &(const struct clk_parent_data){
97+ .hw = &lpass_lpaaudio_dig_pll.clkr.hw,
98+ },
99+ .num_parents = 1,
100+ .flags = CLK_SET_RATE_PARENT,
101+ .ops = &clk_alpha_pll_postdiv_fabia_ops,
102+ },
103+};
104+
105+static const struct parent_map lpass_core_cc_parent_map_0[] = {
106+ { P_BI_TCXO, 0 },
107+ { P_LPASS_LPAAUDIO_DIG_PLL_OUT_ODD, 5 },
108+};
109+
110+static const struct clk_parent_data lpass_core_cc_parent_data_0[] = {
111+ { .fw_name = "bi_tcxo" },
112+ { .hw = &lpass_lpaaudio_dig_pll_out_odd.clkr.hw },
113+};
114+
115+static const struct parent_map lpass_core_cc_parent_map_2[] = {
116+ { P_BI_TCXO, 0 },
117+};
118+
119+static struct clk_rcg2 core_clk_src = {
120+ .cmd_rcgr = 0x1d000,
121+ .mnd_width = 8,
122+ .hid_width = 5,
123+ .parent_map = lpass_core_cc_parent_map_2,
124+ .clkr.hw.init = &(struct clk_init_data){
125+ .name = "core_clk_src",
126+ .parent_data = &(const struct clk_parent_data){
127+ .fw_name = "bi_tcxo",
128+ },
129+ .num_parents = 1,
130+ .ops = &clk_rcg2_ops,
131+ },
132+};
133+
134+static const struct freq_tbl ftbl_ext_mclk0_clk_src[] = {
135+ F(9600000, P_BI_TCXO, 2, 0, 0),
136+ F(19200000, P_BI_TCXO, 1, 0, 0),
137+ { }
138+};
139+
140+static const struct freq_tbl ftbl_ext_lpaif_clk_src[] = {
141+ F(256000, P_LPASS_LPAAUDIO_DIG_PLL_OUT_ODD, 15, 1, 32),
142+ F(512000, P_LPASS_LPAAUDIO_DIG_PLL_OUT_ODD, 15, 1, 16),
143+ F(768000, P_LPASS_LPAAUDIO_DIG_PLL_OUT_ODD, 10, 1, 16),
144+ F(1024000, P_LPASS_LPAAUDIO_DIG_PLL_OUT_ODD, 15, 1, 8),
145+ F(1536000, P_LPASS_LPAAUDIO_DIG_PLL_OUT_ODD, 10, 1, 8),
146+ F(2048000, P_LPASS_LPAAUDIO_DIG_PLL_OUT_ODD, 15, 1, 4),
147+ F(3072000, P_LPASS_LPAAUDIO_DIG_PLL_OUT_ODD, 10, 1, 4),
148+ F(4096000, P_LPASS_LPAAUDIO_DIG_PLL_OUT_ODD, 15, 1, 2),
149+ F(6144000, P_LPASS_LPAAUDIO_DIG_PLL_OUT_ODD, 10, 1, 2),
150+ F(8192000, P_LPASS_LPAAUDIO_DIG_PLL_OUT_ODD, 15, 0, 0),
151+ F(9600000, P_BI_TCXO, 2, 0, 0),
152+ F(12288000, P_LPASS_LPAAUDIO_DIG_PLL_OUT_ODD, 10, 0, 0),
153+ F(19200000, P_BI_TCXO, 1, 0, 0),
154+ F(24576000, P_LPASS_LPAAUDIO_DIG_PLL_OUT_ODD, 5, 0, 0),
155+ { }
156+};
157+
158+static struct clk_rcg2 ext_mclk0_clk_src = {
159+ .cmd_rcgr = 0x20000,
160+ .mnd_width = 8,
161+ .hid_width = 5,
162+ .parent_map = lpass_core_cc_parent_map_0,
163+ .freq_tbl = ftbl_ext_mclk0_clk_src,
164+ .clkr.hw.init = &(struct clk_init_data){
165+ .name = "ext_mclk0_clk_src",
166+ .parent_data = lpass_core_cc_parent_data_0,
167+ .num_parents = 2,
168+ .flags = CLK_SET_RATE_PARENT,
169+ .ops = &clk_rcg2_ops,
170+ },
171+};
172+
173+static struct clk_rcg2 lpaif_pri_clk_src = {
174+ .cmd_rcgr = 0x10000,
175+ .mnd_width = 16,
176+ .hid_width = 5,
177+ .parent_map = lpass_core_cc_parent_map_0,
178+ .freq_tbl = ftbl_ext_lpaif_clk_src,
179+ .clkr.hw.init = &(struct clk_init_data){
180+ .name = "lpaif_pri_clk_src",
181+ .parent_data = lpass_core_cc_parent_data_0,
182+ .num_parents = 2,
183+ .flags = CLK_SET_RATE_PARENT,
184+ .ops = &clk_rcg2_ops,
185+ },
186+};
187+
188+static struct clk_rcg2 lpaif_sec_clk_src = {
189+ .cmd_rcgr = 0x11000,
190+ .mnd_width = 16,
191+ .hid_width = 5,
192+ .parent_map = lpass_core_cc_parent_map_0,
193+ .freq_tbl = ftbl_ext_lpaif_clk_src,
194+ .clkr.hw.init = &(struct clk_init_data){
195+ .name = "lpaif_sec_clk_src",
196+ .parent_data = lpass_core_cc_parent_data_0,
197+ .num_parents = 2,
198+ .flags = CLK_SET_RATE_PARENT,
199+ .ops = &clk_rcg2_ops,
200+ },
201+};
202+
203+static struct clk_branch lpass_audio_core_ext_mclk0_clk = {
204+ .halt_reg = 0x20014,
205+ .halt_check = BRANCH_HALT,
206+ .hwcg_reg = 0x20014,
207+ .hwcg_bit = 1,
208+ .clkr = {
209+ .enable_reg = 0x20014,
210+ .enable_mask = BIT(0),
211+ .hw.init = &(struct clk_init_data){
212+ .name = "lpass_audio_core_ext_mclk0_clk",
213+ .parent_data = &(const struct clk_parent_data){
214+ .hw = &ext_mclk0_clk_src.clkr.hw,
215+ },
216+ .num_parents = 1,
217+ .flags = CLK_SET_RATE_PARENT,
218+ .ops = &clk_branch2_ops,
219+ },
220+ },
221+};
222+
223+static struct clk_branch lpass_audio_core_lpaif_pri_ibit_clk = {
224+ .halt_reg = 0x10018,
225+ .halt_check = BRANCH_HALT,
226+ .hwcg_reg = 0x10018,
227+ .hwcg_bit = 1,
228+ .clkr = {
229+ .enable_reg = 0x10018,
230+ .enable_mask = BIT(0),
231+ .hw.init = &(struct clk_init_data){
232+ .name = "lpass_audio_core_lpaif_pri_ibit_clk",
233+ .parent_data = &(const struct clk_parent_data){
234+ .hw = &lpaif_pri_clk_src.clkr.hw,
235+ },
236+ .num_parents = 1,
237+ .flags = CLK_SET_RATE_PARENT,
238+ .ops = &clk_branch2_ops,
239+ },
240+ },
241+};
242+
243+static struct clk_branch lpass_audio_core_lpaif_sec_ibit_clk = {
244+ .halt_reg = 0x11018,
245+ .halt_check = BRANCH_HALT,
246+ .hwcg_reg = 0x11018,
247+ .hwcg_bit = 1,
248+ .clkr = {
249+ .enable_reg = 0x11018,
250+ .enable_mask = BIT(0),
251+ .hw.init = &(struct clk_init_data){
252+ .name = "lpass_audio_core_lpaif_sec_ibit_clk",
253+ .parent_data = &(const struct clk_parent_data){
254+ .hw = &lpaif_sec_clk_src.clkr.hw,
255+ },
256+ .num_parents = 1,
257+ .flags = CLK_SET_RATE_PARENT,
258+ .ops = &clk_branch2_ops,
259+ },
260+ },
261+};
262+
263+static struct clk_branch lpass_audio_core_sysnoc_mport_core_clk = {
264+ .halt_reg = 0x23000,
265+ .halt_check = BRANCH_HALT,
266+ .hwcg_reg = 0x23000,
267+ .hwcg_bit = 1,
268+ .clkr = {
269+ .enable_reg = 0x23000,
270+ .enable_mask = BIT(0),
271+ .hw.init = &(struct clk_init_data){
272+ .name = "lpass_audio_core_sysnoc_mport_core_clk",
273+ .parent_data = &(const struct clk_parent_data){
274+ .hw = &core_clk_src.clkr.hw,
275+ },
276+ .num_parents = 1,
277+ .flags = CLK_SET_RATE_PARENT,
278+ .ops = &clk_branch2_ops,
279+ },
280+ },
281+};
282+
283+static struct clk_regmap *lpass_core_cc_sc7180_clocks[] = {
284+ [EXT_MCLK0_CLK_SRC] = &ext_mclk0_clk_src.clkr,
285+ [LPAIF_PRI_CLK_SRC] = &lpaif_pri_clk_src.clkr,
286+ [LPAIF_SEC_CLK_SRC] = &lpaif_sec_clk_src.clkr,
287+ [CORE_CLK_SRC] = &core_clk_src.clkr,
288+ [LPASS_AUDIO_CORE_EXT_MCLK0_CLK] = &lpass_audio_core_ext_mclk0_clk.clkr,
289+ [LPASS_AUDIO_CORE_LPAIF_PRI_IBIT_CLK] =
290+ &lpass_audio_core_lpaif_pri_ibit_clk.clkr,
291+ [LPASS_AUDIO_CORE_LPAIF_SEC_IBIT_CLK] =
292+ &lpass_audio_core_lpaif_sec_ibit_clk.clkr,
293+ [LPASS_AUDIO_CORE_SYSNOC_MPORT_CORE_CLK] =
294+ &lpass_audio_core_sysnoc_mport_core_clk.clkr,
295+ [LPASS_LPAAUDIO_DIG_PLL] = &lpass_lpaaudio_dig_pll.clkr,
296+ [LPASS_LPAAUDIO_DIG_PLL_OUT_ODD] = &lpass_lpaaudio_dig_pll_out_odd.clkr,
297+};
298+
299+static struct gdsc lpass_pdc_hm_gdsc = {
300+ .gdscr = 0x3090,
301+ .pd = {
302+ .name = "lpass_pdc_hm_gdsc",
303+ },
304+ .pwrsts = PWRSTS_OFF_ON,
305+ .flags = VOTABLE,
306+};
307+
308+static struct gdsc lpass_audio_hm_gdsc = {
309+ .gdscr = 0x9090,
310+ .pd = {
311+ .name = "lpass_audio_hm_gdsc",
312+ },
313+ .pwrsts = PWRSTS_OFF_ON,
314+};
315+
316+static struct gdsc lpass_core_hm_gdsc = {
317+ .gdscr = 0x0,
318+ .pd = {
319+ .name = "lpass_core_hm_gdsc",
320+ },
321+ .pwrsts = PWRSTS_OFF_ON,
322+ .flags = RETAIN_FF_ENABLE,
323+};
324+
325+static struct gdsc *lpass_core_hm_sc7180_gdscs[] = {
326+ [LPASS_CORE_HM_GDSCR] = &lpass_core_hm_gdsc,
327+};
328+
329+static struct gdsc *lpass_audio_hm_sc7180_gdscs[] = {
330+ [LPASS_PDC_HM_GDSCR] = &lpass_pdc_hm_gdsc,
331+ [LPASS_AUDIO_HM_GDSCR] = &lpass_audio_hm_gdsc,
332+};
333+
334+static struct regmap_config lpass_core_cc_sc7180_regmap_config = {
335+ .reg_bits = 32,
336+ .reg_stride = 4,
337+ .val_bits = 32,
338+ .fast_io = true,
339+};
340+
341+static const struct qcom_cc_desc lpass_core_hm_sc7180_desc = {
342+ .config = &lpass_core_cc_sc7180_regmap_config,
343+ .gdscs = lpass_core_hm_sc7180_gdscs,
344+ .num_gdscs = ARRAY_SIZE(lpass_core_hm_sc7180_gdscs),
345+};
346+
347+static const struct qcom_cc_desc lpass_core_cc_sc7180_desc = {
348+ .config = &lpass_core_cc_sc7180_regmap_config,
349+ .clks = lpass_core_cc_sc7180_clocks,
350+ .num_clks = ARRAY_SIZE(lpass_core_cc_sc7180_clocks),
351+};
352+
353+static const struct qcom_cc_desc lpass_audio_hm_sc7180_desc = {
354+ .config = &lpass_core_cc_sc7180_regmap_config,
355+ .gdscs = lpass_audio_hm_sc7180_gdscs,
356+ .num_gdscs = ARRAY_SIZE(lpass_audio_hm_sc7180_gdscs),
357+};
358+
359+static int lpass_core_cc_sc7180_probe(struct platform_device *pdev)
360+{
361+ const struct qcom_cc_desc *desc;
362+ struct regmap *regmap;
363+ int ret;
364+
365+ lpass_core_cc_sc7180_regmap_config.name = "lpass_audio_cc";
366+ desc = &lpass_audio_hm_sc7180_desc;
367+ ret = qcom_cc_probe_by_index(pdev, 1, desc);
368+ if (ret)
369+ return ret;
370+
371+ lpass_core_cc_sc7180_regmap_config.name = "lpass_core_cc";
372+ regmap = qcom_cc_map(pdev, &lpass_core_cc_sc7180_desc);
373+ if (IS_ERR(regmap))
374+ return PTR_ERR(regmap);
375+
376+ /*
377+ * Keep the CLK always-ON
378+ * LPASS_AUDIO_CORE_SYSNOC_SWAY_CORE_CLK
379+ */
380+ regmap_update_bits(regmap, 0x24000, BIT(0), BIT(0));
381+
382+ /* PLL settings */
383+ regmap_write(regmap, 0x1008, 0x20);
384+ regmap_update_bits(regmap, 0x1014, BIT(0), BIT(0));
385+
386+ clk_fabia_pll_configure(&lpass_lpaaudio_dig_pll, regmap,
387+ &lpass_lpaaudio_dig_pll_config);
388+
389+ return qcom_cc_really_probe(pdev, &lpass_core_cc_sc7180_desc, regmap);
390+}
391+
392+static int lpass_hm_core_probe(struct platform_device *pdev)
393+{
394+ const struct qcom_cc_desc *desc;
395+
396+ lpass_core_cc_sc7180_regmap_config.name = "lpass_hm_core";
397+ desc = &lpass_core_hm_sc7180_desc;
398+
399+ return qcom_cc_probe_by_index(pdev, 0, desc);
400+}
401+
402+static const struct of_device_id lpass_core_cc_sc7180_match_table[] = {
403+ {
404+ .compatible = "qcom,sc7180-lpasshm",
405+ .data = lpass_hm_core_probe,
406+ },
407+ {
408+ .compatible = "qcom,sc7180-lpasscorecc",
409+ .data = lpass_core_cc_sc7180_probe,
410+ },
411+ { }
412+};
413+MODULE_DEVICE_TABLE(of, lpass_core_cc_sc7180_match_table);
414+
415+static int lpass_core_sc7180_probe(struct platform_device *pdev)
416+{
417+ int (*clk_probe)(struct platform_device *p);
418+ int ret;
419+
420+ pm_runtime_enable(&pdev->dev);
421+ ret = pm_clk_create(&pdev->dev);
422+ if (ret)
423+ return ret;
424+
425+ ret = pm_clk_add(&pdev->dev, "iface");
426+ if (ret < 0) {
427+ dev_err(&pdev->dev, "failed to acquire iface clock\n");
428+ goto disable_pm_runtime;
429+ }
430+
431+ clk_probe = of_device_get_match_data(&pdev->dev);
432+ if (!clk_probe)
433+ return -EINVAL;
434+
435+ ret = clk_probe(pdev);
436+ if (ret)
437+ goto destroy_pm_clk;
438+
439+ return 0;
440+
441+destroy_pm_clk:
442+ pm_clk_destroy(&pdev->dev);
443+
444+disable_pm_runtime:
445+ pm_runtime_disable(&pdev->dev);
446+
447+ return ret;
448+}
449+
450+static const struct dev_pm_ops lpass_core_cc_pm_ops = {
451+ SET_RUNTIME_PM_OPS(pm_clk_suspend, pm_clk_resume, NULL)
452+};
453+
454+static struct platform_driver lpass_core_cc_sc7180_driver = {
455+ .probe = lpass_core_sc7180_probe,
456+ .driver = {
457+ .name = "lpass_core_cc-sc7180",
458+ .of_match_table = lpass_core_cc_sc7180_match_table,
459+ .pm = &lpass_core_cc_pm_ops,
460+ },
461+};
462+
463+static int __init lpass_core_cc_sc7180_init(void)
464+{
465+ return platform_driver_register(&lpass_core_cc_sc7180_driver);
466+}
467+subsys_initcall(lpass_core_cc_sc7180_init);
468+
469+static void __exit lpass_core_cc_sc7180_exit(void)
470+{
471+ platform_driver_unregister(&lpass_core_cc_sc7180_driver);
472+}
473+module_exit(lpass_core_cc_sc7180_exit);
474+
475+MODULE_DESCRIPTION("QTI LPASS_CORE_CC SC7180 Driver");
476+MODULE_LICENSE("GPL v2");
drivers/clk/rockchip/clk-pll.c+41−29
@@ -12,6 +12,7 @@ · 11 unmodified lines
1212 #include <linux/io.h>
1313 #include <linux/delay.h>
1414 #include <linux/clk-provider.h>
15+#include <linux/iopoll.h>
1516 #include <linux/regmap.h>
1617 #include <linux/clk.h>
1718 #include "clk.h"
@@ -86,23 +87,14 @@ static int rockchip_pll_wait_lock(struct rockchip_clk_pll *pll) · 68 unmodified lines
8687 {
8788 struct regmap *grf = pll->ctx->grf;
8889 unsigned int val;
89− int delay = 24000000, ret;
90−
91− while (delay > 0) {
92− ret = regmap_read(grf, pll->lock_offset, &val);
93− if (ret) {
94− pr_err("%s: failed to read pll lock status: %d\n",
95− __func__, ret);
96− return ret;
97− }
90+ int ret;
9891
99− if (val & BIT(pll->lock_shift))
100− return 0;
101− delay--;
102− }
92+ ret = regmap_read_poll_timeout(grf, pll->lock_offset, val,
93+ val & BIT(pll->lock_shift), 0, 1000);
94+ if (ret)
95+ pr_err("%s: timeout waiting for pll to lock\n", __func__);
10396
104− pr_err("%s: timeout waiting for pll to lock\n", __func__);
105− return -ETIMEDOUT;
97+ return ret;
10698 }
10799
108100 /**
@@ -118,12 +110,31 @@ static int rockchip_pll_wait_lock(struct rockchip_clk_pll *pll) · 9 unmodified lines
118110 #define RK3036_PLLCON1_REFDIV_SHIFT 0
119111 #define RK3036_PLLCON1_POSTDIV2_MASK 0x7
120112 #define RK3036_PLLCON1_POSTDIV2_SHIFT 6
113+#define RK3036_PLLCON1_LOCK_STATUS BIT(10)
121114 #define RK3036_PLLCON1_DSMPD_MASK 0x1
122115 #define RK3036_PLLCON1_DSMPD_SHIFT 12
116+#define RK3036_PLLCON1_PWRDOWN BIT(13)
123117 #define RK3036_PLLCON2_FRAC_MASK 0xffffff
124118 #define RK3036_PLLCON2_FRAC_SHIFT 0
125119
126−#define RK3036_PLLCON1_PWRDOWN (1 << 13)
120+static int rockchip_rk3036_pll_wait_lock(struct rockchip_clk_pll *pll)
121+{
122+ u32 pllcon;
123+ int ret;
124+
125+ /*
126+ * Lock time typical 250, max 500 input clock cycles @24MHz
127+ * So define a very safe maximum of 1000us, meaning 24000 cycles.
128+ */
129+ ret = readl_relaxed_poll_timeout(pll->reg_base + RK3036_PLLCON(1),
130+ pllcon,
131+ pllcon & RK3036_PLLCON1_LOCK_STATUS,
132+ 0, 1000);
133+ if (ret)
134+ pr_err("%s: timeout waiting for pll to lock\n", __func__);
135+
136+ return ret;
137+}
127138
128139 static void rockchip_rk3036_pll_get_params(struct rockchip_clk_pll *pll,
129140 struct rockchip_pll_rate_table *rate)
@@ -221,7 +232,7 @@ static int rockchip_rk3036_pll_set_params(struct rockchip_clk_pll *pll, · 91 unmodified lines
221232 writel_relaxed(pllcon, pll->reg_base + RK3036_PLLCON(2));
222233
223234 /* wait for the pll to lock */
224− ret = rockchip_pll_wait_lock(pll);
235+ ret = rockchip_rk3036_pll_wait_lock(pll);
225236 if (ret) {
226237 pr_warn("%s: pll update unsuccessful, trying to restore old params\n",
227238 __func__);
@@ -260,7 +271,7 @@ static int rockchip_rk3036_pll_enable(struct clk_hw *hw) · 32 unmodified lines
260271
261272 writel(HIWORD_UPDATE(0, RK3036_PLLCON1_PWRDOWN, 0),
262273 pll->reg_base + RK3036_PLLCON(1));
263− rockchip_pll_wait_lock(pll);
274+ rockchip_rk3036_pll_wait_lock(pll);
264275
265276 return 0;
266277 }
@@ -589,19 +600,20 @@ static const struct clk_ops rockchip_rk3066_pll_clk_ops = { · 322 unmodified lines
589600 static int rockchip_rk3399_pll_wait_lock(struct rockchip_clk_pll *pll)
590601 {
591602 u32 pllcon;
592− int delay = 24000000;
593−
594− /* poll check the lock status in rk3399 xPLLCON2 */
595− while (delay > 0) {
596− pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(2));
597− if (pllcon & RK3399_PLLCON2_LOCK_STATUS)
598− return 0;
603+ int ret;
599604
600− delay--;
601− }
605+ /*
606+ * Lock time typical 250, max 500 input clock cycles @24MHz
607+ * So define a very safe maximum of 1000us, meaning 24000 cycles.
608+ */
609+ ret = readl_relaxed_poll_timeout(pll->reg_base + RK3399_PLLCON(2),
610+ pllcon,
611+ pllcon & RK3399_PLLCON2_LOCK_STATUS,
612+ 0, 1000);
613+ if (ret)
614+ pr_err("%s: timeout waiting for pll to lock\n", __func__);
602615
603− pr_err("%s: timeout waiting for pll to lock\n", __func__);
604− return -ETIMEDOUT;
616+ return ret;
605617 }
606618
607619 static void rockchip_rk3399_pll_get_params(struct rockchip_clk_pll *pll,
drivers/clk/rockchip/clk-rk3188.c+1−0
@@ -751,6 +751,7 @@ static const char *const rk3188_critical_clocks[] __initconst = { · 750 unmodified lines
751751 "pclk_peri",
752752 "hclk_cpubus",
753753 "hclk_vio_bus",
754+ "sclk_mac_lbtest",
754755 };
755756
756757 static struct rockchip_clk_provider *__init rk3188_common_clk_init(struct device_node *np)
drivers/clk/rockchip/clk-rk3288.c+36−3
@@ -15,6 +15,11 @@ · 14 unmodified lines
1515 #define RK3288_GRF_SOC_CON(x) (0x244 + x * 4)
1616 #define RK3288_GRF_SOC_STATUS1 0x284
1717
18+enum rk3288_variant {
19+ RK3288_CRU,
20+ RK3288W_CRU,
21+};
22+
1823 enum rk3288_plls {
1924 apll, dpll, cpll, gpll, npll,
2025 };
@@ -425,8 +430,6 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { · 404 unmodified lines
425430 COMPOSITE(0, "aclk_vio0", mux_pll_src_cpll_gpll_usb480m_p, CLK_IGNORE_UNUSED,
426431 RK3288_CLKSEL_CON(31), 6, 2, MFLAGS, 0, 5, DFLAGS,
427432 RK3288_CLKGATE_CON(3), 0, GFLAGS),
428− DIV(0, "hclk_vio", "aclk_vio0", 0,
429− RK3288_CLKSEL_CON(28), 8, 5, DFLAGS),
430433 COMPOSITE(0, "aclk_vio1", mux_pll_src_cpll_gpll_usb480m_p, CLK_IGNORE_UNUSED,
431434 RK3288_CLKSEL_CON(31), 14, 2, MFLAGS, 8, 5, DFLAGS,
432435 RK3288_CLKGATE_CON(3), 2, GFLAGS),
@@ -819,6 +822,16 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { · 386 unmodified lines
819822 INVERTER(0, "pclk_isp", "pclk_isp_in", RK3288_CLKSEL_CON(29), 3, IFLAGS),
820823 };
821824
825+static struct rockchip_clk_branch rk3288w_hclkvio_branch[] __initdata = {
826+ DIV(0, "hclk_vio", "aclk_vio1", 0,
827+ RK3288_CLKSEL_CON(28), 8, 5, DFLAGS),
828+};
829+
830+static struct rockchip_clk_branch rk3288_hclkvio_branch[] __initdata = {
831+ DIV(0, "hclk_vio", "aclk_vio0", 0,
832+ RK3288_CLKSEL_CON(28), 8, 5, DFLAGS),
833+};
834+
822835 static const char *const rk3288_critical_clocks[] __initconst = {
823836 "aclk_cpu",
824837 "aclk_peri",
@@ -914,7 +927,8 @@ static struct syscore_ops rk3288_clk_syscore_ops = { · 89 unmodified lines
914927 .resume = rk3288_clk_resume,
915928 };
916929
917−static void __init rk3288_clk_init(struct device_node *np)
930+static void __init rk3288_common_init(struct device_node *np,
931+ enum rk3288_variant soc)
918932 {
919933 struct rockchip_clk_provider *ctx;
920934
@@ -936,6 +950,14 @@ static void __init rk3288_clk_init(struct device_node *np) · 15 unmodified lines
936950 RK3288_GRF_SOC_STATUS1);
937951 rockchip_clk_register_branches(ctx, rk3288_clk_branches,
938952 ARRAY_SIZE(rk3288_clk_branches));
953+
954+ if (soc == RK3288W_CRU)
955+ rockchip_clk_register_branches(ctx, rk3288w_hclkvio_branch,
956+ ARRAY_SIZE(rk3288w_hclkvio_branch));
957+ else
958+ rockchip_clk_register_branches(ctx, rk3288_hclkvio_branch,
959+ ARRAY_SIZE(rk3288_hclkvio_branch));
960+
939961 rockchip_clk_protect_critical(rk3288_critical_clocks,
940962 ARRAY_SIZE(rk3288_critical_clocks));
941963
@@ -954,4 +976,15 @@ static void __init rk3288_clk_init(struct device_node *np) · 12 unmodified lines
954976
955977 rockchip_clk_of_add_provider(np, ctx);
956978 }
979+
980+static void __init rk3288_clk_init(struct device_node *np)
981+{
982+ rk3288_common_init(np, RK3288_CRU);
983+}
957984 CLK_OF_DECLARE(rk3288_cru, "rockchip,rk3288-cru", rk3288_clk_init);
985+
986+static void __init rk3288w_clk_init(struct device_node *np)
987+{
988+ rk3288_common_init(np, RK3288W_CRU);
989+}
990+CLK_OF_DECLARE(rk3288w_cru, "rockchip,rk3288w-cru", rk3288w_clk_init);
drivers/clk/rockchip/clk-rk3328.c+4−4
@@ -808,22 +808,22 @@ static struct rockchip_clk_branch rk3328_clk_branches[] __initdata = { · 807 unmodified lines
808808 MMC(SCLK_SDMMC_DRV, "sdmmc_drv", "clk_sdmmc",
809809 RK3328_SDMMC_CON0, 1),
810810 MMC(SCLK_SDMMC_SAMPLE, "sdmmc_sample", "clk_sdmmc",
811− RK3328_SDMMC_CON1, 0),
811+ RK3328_SDMMC_CON1, 1),
812812
813813 MMC(SCLK_SDIO_DRV, "sdio_drv", "clk_sdio",
814814 RK3328_SDIO_CON0, 1),
815815 MMC(SCLK_SDIO_SAMPLE, "sdio_sample", "clk_sdio",
816− RK3328_SDIO_CON1, 0),
816+ RK3328_SDIO_CON1, 1),
817817
818818 MMC(SCLK_EMMC_DRV, "emmc_drv", "clk_emmc",
819819 RK3328_EMMC_CON0, 1),
820820 MMC(SCLK_EMMC_SAMPLE, "emmc_sample", "clk_emmc",
821− RK3328_EMMC_CON1, 0),
821+ RK3328_EMMC_CON1, 1),
822822
823823 MMC(SCLK_SDMMC_EXT_DRV, "sdmmc_ext_drv", "clk_sdmmc_ext",
824824 RK3328_SDMMC_EXT_CON0, 1),
825825 MMC(SCLK_SDMMC_EXT_SAMPLE, "sdmmc_ext_sample", "clk_sdmmc_ext",
826− RK3328_SDMMC_EXT_CON1, 0),
826+ RK3328_SDMMC_EXT_CON1, 1),
827827 };
828828
829829 static const char *const rk3328_critical_clocks[] __initconst = {
drivers/clk/sirf/clk-atlas6.c+1−1
@@ -135,7 +135,7 @@ static void __init atlas6_clk_init(struct device_node *np) · 134 unmodified lines
135135
136136 for (i = pll1; i < maxclk; i++) {
137137 atlas6_clks[i] = clk_register(NULL, atlas6_clk_hw_array[i]);
138− BUG_ON(!atlas6_clks[i]);
138+ BUG_ON(IS_ERR(atlas6_clks[i]));
139139 }
140140 clk_register_clkdev(atlas6_clks[cpu], NULL, "cpu");
141141 clk_register_clkdev(atlas6_clks[io], NULL, "io");
drivers/clk/tegra/clk-pll.c+15−5
@@ -327,16 +327,26 @@ int tegra_pll_wait_for_lock(struct tegra_clk_pll *pll) · 326 unmodified lines
327327 return clk_pll_wait_for_lock(pll);
328328 }
329329
330+static bool pllm_clk_is_gated_by_pmc(struct tegra_clk_pll *pll)
331+{
332+ u32 val = readl_relaxed(pll->pmc + PMC_PLLP_WB0_OVERRIDE);
333+
334+ return (val & PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE) &&
335+ !(val & PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE);
336+}
337+
330338 static int clk_pll_is_enabled(struct clk_hw *hw)
331339 {
332340 struct tegra_clk_pll *pll = to_clk_pll(hw);
333341 u32 val;
334342
335− if (pll->params->flags & TEGRA_PLLM) {
336− val = readl_relaxed(pll->pmc + PMC_PLLP_WB0_OVERRIDE);
337− if (val & PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE)
338− return val & PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE ? 1 : 0;
339− }
343+ /*
344+ * Power Management Controller (PMC) can override the PLLM clock
345+ * settings, including the enable-state. The PLLM is enabled when
346+ * PLLM's CaR state is ON and when PLLM isn't gated by PMC.
347+ */
348+ if ((pll->params->flags & TEGRA_PLLM) && pllm_clk_is_gated_by_pmc(pll))
349+ return 0;
340350
341351 val = pll_readl_base(pll);
342352
drivers/clk/x86/clk-cgu-pll.c+1−1
@@ -128,7 +128,7 @@ lgm_clk_register_pll(struct lgm_clk_provider *ctx, · 127 unmodified lines
128128 pll->hw.init = &init;
129129
130130 hw = &pll->hw;
131− ret = clk_hw_register(dev, hw);
131+ ret = devm_clk_hw_register(dev, hw);
132132 if (ret)
133133 return ERR_PTR(ret);
134134
drivers/clk/x86/clk-cgu.c+12−20
@@ -119,7 +119,7 @@ lgm_clk_register_mux(struct lgm_clk_provider *ctx, · 118 unmodified lines
119119 mux->hw.init = &init;
120120
121121 hw = &mux->hw;
122− ret = clk_hw_register(dev, hw);
122+ ret = devm_clk_hw_register(dev, hw);
123123 if (ret)
124124 return ERR_PTR(ret);
125125
@@ -247,7 +247,7 @@ lgm_clk_register_divider(struct lgm_clk_provider *ctx, · 121 unmodified lines
247247 div->hw.init = &init;
248248
249249 hw = &div->hw;
250− ret = clk_hw_register(dev, hw);
250+ ret = devm_clk_hw_register(dev, hw);
251251 if (ret)
252252 return ERR_PTR(ret);
253253
@@ -361,7 +361,7 @@ lgm_clk_register_gate(struct lgm_clk_provider *ctx, · 107 unmodified lines
361361 gate->hw.init = &init;
362362
363363 hw = &gate->hw;
364− ret = clk_hw_register(dev, hw);
364+ ret = devm_clk_hw_register(dev, hw);
365365 if (ret)
366366 return ERR_PTR(ret);
367367
@@ -420,18 +420,14 @@ lgm_clk_ddiv_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) · 52 unmodified lines
420420 {
421421 struct lgm_clk_ddiv *ddiv = to_lgm_clk_ddiv(hw);
422422 unsigned int div0, div1, exdiv;
423− unsigned long flags;
424423 u64 prate;
425424
426− spin_lock_irqsave(&ddiv->lock, flags);
427425 div0 = lgm_get_clk_val(ddiv->membase, ddiv->reg,
428426 ddiv->shift0, ddiv->width0) + 1;
429427 div1 = lgm_get_clk_val(ddiv->membase, ddiv->reg,
430428 ddiv->shift1, ddiv->width1) + 1;
431429 exdiv = lgm_get_clk_val(ddiv->membase, ddiv->reg,
432430 ddiv->shift2, ddiv->width2);
433− spin_unlock_irqrestore(&ddiv->lock, flags);
434−
435431 prate = (u64)parent_rate;
436432 do_div(prate, div0);
437433 do_div(prate, div1);
@@ -548,24 +544,21 @@ lgm_clk_ddiv_round_rate(struct clk_hw *hw, unsigned long rate, · 110 unmodified lines
548544 div = div * 2;
549545 div = DIV_ROUND_CLOSEST_ULL((u64)div, 5);
550546 }
547+ spin_unlock_irqrestore(&ddiv->lock, flags);
551548
552− if (div <= 0) {
553− spin_unlock_irqrestore(&ddiv->lock, flags);
549+ if (div <= 0)
554550 return *prate;
555− }
556551
557− if (lgm_clk_get_ddiv_val(div, &ddiv1, &ddiv2) != 0) {
558− if (lgm_clk_get_ddiv_val(div + 1, &ddiv1, &ddiv2) != 0) {
559− spin_unlock_irqrestore(&ddiv->lock, flags);
552+ if (lgm_clk_get_ddiv_val(div, &ddiv1, &ddiv2) != 0)
553+ if (lgm_clk_get_ddiv_val(div + 1, &ddiv1, &ddiv2) != 0)
560554 return -EINVAL;
561− }
562− }
563555
564556 rate64 = *prate;
565557 do_div(rate64, ddiv1);
566558 do_div(rate64, ddiv2);
567559
568560 /* if predivide bit is enabled, modify rounded rate by factor of 2.5 */
561+ spin_lock_irqsave(&ddiv->lock, flags);
569562 if (lgm_get_clk_val(ddiv->membase, ddiv->reg, ddiv->shift2, 1)) {
570563 rate64 = rate64 * 2;
571564 rate64 = DIV_ROUND_CLOSEST_ULL(rate64, 5);
@@ -588,19 +581,18 @@ int lgm_clk_register_ddiv(struct lgm_clk_provider *ctx, · 16 unmodified lines
588581 unsigned int nr_clk)
589582 {
590583 struct device *dev = ctx->dev;
591− struct clk_init_data init = {};
592− struct lgm_clk_ddiv *ddiv;
593584 struct clk_hw *hw;
594585 unsigned int idx;
595586 int ret;
596587
597588 for (idx = 0; idx < nr_clk; idx++, list++) {
598− ddiv = NULL;
589+ struct clk_init_data init = {};
590+ struct lgm_clk_ddiv *ddiv;
591+
599592 ddiv = devm_kzalloc(dev, sizeof(*ddiv), GFP_KERNEL);
600593 if (!ddiv)
601594 return -ENOMEM;
602595
603− memset(&init, 0, sizeof(init));
604596 init.name = list->name;
605597 init.ops = &lgm_clk_ddiv_ops;
606598 init.flags = list->flags;
@@ -624,7 +616,7 @@ int lgm_clk_register_ddiv(struct lgm_clk_provider *ctx, · 17 unmodified lines
624616 ddiv->hw.init = &init;
625617
626618 hw = &ddiv->hw;
627− ret = clk_hw_register(dev, hw);
619+ ret = devm_clk_hw_register(dev, hw);
628620 if (ret) {
629621 dev_err(dev, "register clk: %s failed!\n", list->name);
630622 return ret;
include/dt-bindings/clock/actions,s500-cmu.h+6−1
@@ -72,7 +72,12 @@ · 71 unmodified lines
7272 #define CLK_NAND 52
7373 #define CLK_ECC 53
7474 #define CLK_RMII_REF 54
75+#define CLK_GPIO 55
7576
76−#define CLK_NR_CLKS (CLK_RMII_REF + 1)
77+/* system clock (part 2) */
78+#define CLK_APB 56
79+#define CLK_DMAC 57
80+
81+#define CLK_NR_CLKS (CLK_DMAC + 1)
7782
7883 #endif /* __DT_BINDINGS_CLOCK_S500_CMU_H */
include/dt-bindings/clock/jz4780-cgu.h+73−71
@@ -12,78 +12,80 @@ · 11 unmodified lines
1212 #ifndef __DT_BINDINGS_CLOCK_JZ4780_CGU_H__
1313 #define __DT_BINDINGS_CLOCK_JZ4780_CGU_H__
1414
15−#define JZ4780_CLK_EXCLK 0
16−#define JZ4780_CLK_RTCLK 1
17−#define JZ4780_CLK_APLL 2
18−#define JZ4780_CLK_MPLL 3
19−#define JZ4780_CLK_EPLL 4
20−#define JZ4780_CLK_VPLL 5
21−#define JZ4780_CLK_OTGPHY 6
22−#define JZ4780_CLK_SCLKA 7
23−#define JZ4780_CLK_CPUMUX 8
24−#define JZ4780_CLK_CPU 9
25−#define JZ4780_CLK_L2CACHE 10
26−#define JZ4780_CLK_AHB0 11
27−#define JZ4780_CLK_AHB2PMUX 12
28−#define JZ4780_CLK_AHB2 13
29−#define JZ4780_CLK_PCLK 14
30−#define JZ4780_CLK_DDR 15
31−#define JZ4780_CLK_VPU 16
32−#define JZ4780_CLK_I2SPLL 17
33−#define JZ4780_CLK_I2S 18
15+#define JZ4780_CLK_EXCLK 0
16+#define JZ4780_CLK_RTCLK 1
17+#define JZ4780_CLK_APLL 2
18+#define JZ4780_CLK_MPLL 3
19+#define JZ4780_CLK_EPLL 4
20+#define JZ4780_CLK_VPLL 5
21+#define JZ4780_CLK_OTGPHY 6
22+#define JZ4780_CLK_SCLKA 7
23+#define JZ4780_CLK_CPUMUX 8
24+#define JZ4780_CLK_CPU 9
25+#define JZ4780_CLK_L2CACHE 10
26+#define JZ4780_CLK_AHB0 11
27+#define JZ4780_CLK_AHB2PMUX 12
28+#define JZ4780_CLK_AHB2 13
29+#define JZ4780_CLK_PCLK 14
30+#define JZ4780_CLK_DDR 15
31+#define JZ4780_CLK_VPU 16
32+#define JZ4780_CLK_I2SPLL 17
33+#define JZ4780_CLK_I2S 18
3434 #define JZ4780_CLK_LCD0PIXCLK 19
3535 #define JZ4780_CLK_LCD1PIXCLK 20
36−#define JZ4780_CLK_MSCMUX 21
37−#define JZ4780_CLK_MSC0 22
38−#define JZ4780_CLK_MSC1 23
39−#define JZ4780_CLK_MSC2 24
40−#define JZ4780_CLK_UHC 25
41−#define JZ4780_CLK_SSIPLL 26
42−#define JZ4780_CLK_SSI 27
43−#define JZ4780_CLK_CIMMCLK 28
44−#define JZ4780_CLK_PCMPLL 29
45−#define JZ4780_CLK_PCM 30
46−#define JZ4780_CLK_GPU 31
47−#define JZ4780_CLK_HDMI 32
48−#define JZ4780_CLK_BCH 33
49−#define JZ4780_CLK_NEMC 34
50−#define JZ4780_CLK_OTG0 35
51−#define JZ4780_CLK_SSI0 36
52−#define JZ4780_CLK_SMB0 37
53−#define JZ4780_CLK_SMB1 38
54−#define JZ4780_CLK_SCC 39
55−#define JZ4780_CLK_AIC 40
56−#define JZ4780_CLK_TSSI0 41
57−#define JZ4780_CLK_OWI 42
58−#define JZ4780_CLK_KBC 43
59−#define JZ4780_CLK_SADC 44
60−#define JZ4780_CLK_UART0 45
61−#define JZ4780_CLK_UART1 46
62−#define JZ4780_CLK_UART2 47
63−#define JZ4780_CLK_UART3 48
64−#define JZ4780_CLK_SSI1 49
65−#define JZ4780_CLK_SSI2 50
66−#define JZ4780_CLK_PDMA 51
67−#define JZ4780_CLK_GPS 52
68−#define JZ4780_CLK_MAC 53
69−#define JZ4780_CLK_SMB2 54
70−#define JZ4780_CLK_CIM 55
71−#define JZ4780_CLK_LCD 56
72−#define JZ4780_CLK_TVE 57
73−#define JZ4780_CLK_IPU 58
74−#define JZ4780_CLK_DDR0 59
75−#define JZ4780_CLK_DDR1 60
76−#define JZ4780_CLK_SMB3 61
77−#define JZ4780_CLK_TSSI1 62
78−#define JZ4780_CLK_COMPRESS 63
79−#define JZ4780_CLK_AIC1 64
80−#define JZ4780_CLK_GPVLC 65
81−#define JZ4780_CLK_OTG1 66
82−#define JZ4780_CLK_UART4 67
83−#define JZ4780_CLK_AHBMON 68
84−#define JZ4780_CLK_SMB4 69
85−#define JZ4780_CLK_DES 70
86−#define JZ4780_CLK_X2D 71
87−#define JZ4780_CLK_CORE1 72
36+#define JZ4780_CLK_MSCMUX 21
37+#define JZ4780_CLK_MSC0 22
38+#define JZ4780_CLK_MSC1 23
39+#define JZ4780_CLK_MSC2 24
40+#define JZ4780_CLK_UHC 25
41+#define JZ4780_CLK_SSIPLL 26
42+#define JZ4780_CLK_SSI 27
43+#define JZ4780_CLK_CIMMCLK 28
44+#define JZ4780_CLK_PCMPLL 29
45+#define JZ4780_CLK_PCM 30
46+#define JZ4780_CLK_GPU 31
47+#define JZ4780_CLK_HDMI 32
48+#define JZ4780_CLK_BCH 33
49+#define JZ4780_CLK_NEMC 34
50+#define JZ4780_CLK_OTG0 35
51+#define JZ4780_CLK_SSI0 36
52+#define JZ4780_CLK_SMB0 37
53+#define JZ4780_CLK_SMB1 38
54+#define JZ4780_CLK_SCC 39
55+#define JZ4780_CLK_AIC 40
56+#define JZ4780_CLK_TSSI0 41
57+#define JZ4780_CLK_OWI 42
58+#define JZ4780_CLK_KBC 43
59+#define JZ4780_CLK_SADC 44
60+#define JZ4780_CLK_UART0 45
61+#define JZ4780_CLK_UART1 46
62+#define JZ4780_CLK_UART2 47
63+#define JZ4780_CLK_UART3 48
64+#define JZ4780_CLK_SSI1 49
65+#define JZ4780_CLK_SSI2 50
66+#define JZ4780_CLK_PDMA 51
67+#define JZ4780_CLK_GPS 52
68+#define JZ4780_CLK_MAC 53
69+#define JZ4780_CLK_SMB2 54
70+#define JZ4780_CLK_CIM 55
71+#define JZ4780_CLK_LCD 56
72+#define JZ4780_CLK_TVE 57
73+#define JZ4780_CLK_IPU 58
74+#define JZ4780_CLK_DDR0 59
75+#define JZ4780_CLK_DDR1 60
76+#define JZ4780_CLK_SMB3 61
77+#define JZ4780_CLK_TSSI1 62
78+#define JZ4780_CLK_COMPRESS 63
79+#define JZ4780_CLK_AIC1 64
80+#define JZ4780_CLK_GPVLC 65
81+#define JZ4780_CLK_OTG1 66
82+#define JZ4780_CLK_UART4 67
83+#define JZ4780_CLK_AHBMON 68
84+#define JZ4780_CLK_SMB4 69
85+#define JZ4780_CLK_DES 70
86+#define JZ4780_CLK_X2D 71
87+#define JZ4780_CLK_CORE1 72
88+#define JZ4780_CLK_EXCLK_DIV512 73
89+#define JZ4780_CLK_RTC 74
8890
8991 #endif /* __DT_BINDINGS_CLOCK_JZ4780_CGU_H__ */
include/dt-bindings/clock/qcom,gcc-sc7180.h+1−0
@@ -138,6 +138,7 @@ · 137 unmodified lines
138138 #define GCC_MSS_Q6_MEMNOC_AXI_CLK 128
139139 #define GCC_MSS_SNOC_AXI_CLK 129
140140 #define GCC_SEC_CTRL_CLK_SRC 130
141+#define GCC_LPASS_CFG_NOC_SWAY_CLK 131
141142
142143 /* GCC resets */
143144 #define GCC_QUSB2PHY_PRIM_BCR 0
include/dt-bindings/clock/qcom,gcc-sdm660.h+1−0
@@ -152,5 +152,6 @@ · 151 unmodified lines
152152 #define GCC_USB_20_BCR 6
153153 #define GCC_USB_30_BCR 7
154154 #define GCC_USB_PHY_CFG_AHB2PHY_BCR 8
155+#define GCC_MSS_RESTART 9
155156
156157 #endif
include/dt-bindings/clock/qcom,gpucc-sm8150.h+33−0
@@ -0,0 +1,33 @@
1+/* SPDX-License-Identifier: GPL-2.0 */
2+/*
3+ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
4+ */
5+
6+#ifndef _DT_BINDINGS_CLK_QCOM_GPU_CC_SM8150_H
7+#define _DT_BINDINGS_CLK_QCOM_GPU_CC_SM8150_H
8+
9+/* GPU_CC clock registers */
10+#define GPU_CC_AHB_CLK 0
11+#define GPU_CC_CRC_AHB_CLK 1
12+#define GPU_CC_CX_APB_CLK 2
13+#define GPU_CC_CX_GMU_CLK 3
14+#define GPU_CC_CX_SNOC_DVM_CLK 4
15+#define GPU_CC_CXO_AON_CLK 5
16+#define GPU_CC_CXO_CLK 6
17+#define GPU_CC_GMU_CLK_SRC 7
18+#define GPU_CC_GX_GMU_CLK 8
19+#define GPU_CC_PLL1 9
20+
21+/* GPU_CC Resets */
22+#define GPUCC_GPU_CC_CX_BCR 0
23+#define GPUCC_GPU_CC_GFX3D_AON_BCR 1
24+#define GPUCC_GPU_CC_GMU_BCR 2
25+#define GPUCC_GPU_CC_GX_BCR 3
26+#define GPUCC_GPU_CC_SPDM_BCR 4
27+#define GPUCC_GPU_CC_XO_BCR 5
28+
29+/* GPU_CC GDSCRs */
30+#define GPU_CX_GDSC 0
31+#define GPU_GX_GDSC 1
32+
33+#endif
include/dt-bindings/clock/qcom,gpucc-sm8250.h+34−0
@@ -0,0 +1,34 @@
1+/* SPDX-License-Identifier: GPL-2.0 */
2+/*
3+ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
4+ */
5+
6+#ifndef _DT_BINDINGS_CLK_QCOM_GPU_CC_SM8250_H
7+#define _DT_BINDINGS_CLK_QCOM_GPU_CC_SM8250_H
8+
9+/* GPU_CC clock registers */
10+#define GPU_CC_AHB_CLK 0
11+#define GPU_CC_CRC_AHB_CLK 1
12+#define GPU_CC_CX_APB_CLK 2
13+#define GPU_CC_CX_GMU_CLK 3
14+#define GPU_CC_CX_SNOC_DVM_CLK 4
15+#define GPU_CC_CXO_AON_CLK 5
16+#define GPU_CC_CXO_CLK 6
17+#define GPU_CC_GMU_CLK_SRC 7
18+#define GPU_CC_GX_GMU_CLK 8
19+#define GPU_CC_PLL1 9
20+#define GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK 10
21+
22+/* GPU_CC Resets */
23+#define GPUCC_GPU_CC_ACD_BCR 0
24+#define GPUCC_GPU_CC_CX_BCR 1
25+#define GPUCC_GPU_CC_GFX3D_AON_BCR 2
26+#define GPUCC_GPU_CC_GMU_BCR 3
27+#define GPUCC_GPU_CC_GX_BCR 4
28+#define GPUCC_GPU_CC_XO_BCR 5
29+
30+/* GPU_CC GDSCRs */
31+#define GPU_CX_GDSC 0
32+#define GPU_GX_GDSC 1
33+
34+#endif
include/dt-bindings/clock/qcom,lpasscorecc-sc7180.h+29−0
@@ -0,0 +1,29 @@
1+/* SPDX-License-Identifier: GPL-2.0-only */
2+/*
3+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
4+ */
5+
6+#ifndef _DT_BINDINGS_CLK_QCOM_LPASS_CORE_CC_SC7180_H
7+#define _DT_BINDINGS_CLK_QCOM_LPASS_CORE_CC_SC7180_H
8+
9+/* LPASS_CORE_CC clocks */
10+#define LPASS_LPAAUDIO_DIG_PLL 0
11+#define LPASS_LPAAUDIO_DIG_PLL_OUT_ODD 1
12+#define CORE_CLK_SRC 2
13+#define EXT_MCLK0_CLK_SRC 3
14+#define LPAIF_PRI_CLK_SRC 4
15+#define LPAIF_SEC_CLK_SRC 5
16+#define LPASS_AUDIO_CORE_CORE_CLK 6
17+#define LPASS_AUDIO_CORE_EXT_MCLK0_CLK 7
18+#define LPASS_AUDIO_CORE_LPAIF_PRI_IBIT_CLK 8
19+#define LPASS_AUDIO_CORE_LPAIF_SEC_IBIT_CLK 9
20+#define LPASS_AUDIO_CORE_SYSNOC_MPORT_CORE_CLK 10
21+
22+/* LPASS Core power domains */
23+#define LPASS_CORE_HM_GDSCR 0
24+
25+/* LPASS Audio power domains */
26+#define LPASS_AUDIO_HM_GDSCR 0
27+#define LPASS_PDC_HM_GDSCR 1
28+
29+#endif
include/dt-bindings/clock/x1000-cgu.h+2−0
@@ -48,5 +48,7 @@ · 47 unmodified lines
4848 #define X1000_CLK_SSI 33
4949 #define X1000_CLK_OST 34
5050 #define X1000_CLK_PDMA 35
51+#define X1000_CLK_EXCLK_DIV512 36
52+#define X1000_CLK_RTC 37
5153
5254 #endif /* __DT_BINDINGS_CLOCK_X1000_CGU_H__ */
include/dt-bindings/clock/x1830-cgu.h+2−0
@@ -51,5 +51,7 @@ · 50 unmodified lines
5151 #define X1830_CLK_TCU 36
5252 #define X1830_CLK_DTRNG 37
5353 #define X1830_CLK_OST 38
54+#define X1830_CLK_EXCLK_DIV512 39
55+#define X1830_CLK_RTC 40
5456
5557 #endif /* __DT_BINDINGS_CLOCK_X1830_CGU_H__ */
include/dt-bindings/reset/actions,s500-reset.h+67−0
@@ -0,0 +1,67 @@
1+/* SPDX-License-Identifier: GPL-2.0+ */
2+/*
3+ * Device Tree binding constants for Actions Semi S500 Reset Management Unit
4+ *
5+ * Copyright (c) 2014 Actions Semi Inc.
6+ * Copyright (c) 2020 Cristian Ciocaltea <cristian.ciocaltea@gmail.com>
7+ */
8+
9+#ifndef __DT_BINDINGS_ACTIONS_S500_RESET_H
10+#define __DT_BINDINGS_ACTIONS_S500_RESET_H
11+
12+#define RESET_DMAC 0
13+#define RESET_NORIF 1
14+#define RESET_DDR 2
15+#define RESET_NANDC 3
16+#define RESET_SD0 4
17+#define RESET_SD1 5
18+#define RESET_PCM1 6
19+#define RESET_DE 7
20+#define RESET_LCD 8
21+#define RESET_SD2 9
22+#define RESET_DSI 10
23+#define RESET_CSI 11
24+#define RESET_BISP 12
25+#define RESET_KEY 13
26+#define RESET_GPIO 14
27+#define RESET_AUDIO 15
28+#define RESET_PCM0 16
29+#define RESET_VDE 17
30+#define RESET_VCE 18
31+#define RESET_GPU3D 19
32+#define RESET_NIC301 20
33+#define RESET_LENS 21
34+#define RESET_PERIPHRESET 22
35+#define RESET_USB2_0 23
36+#define RESET_TVOUT 24
37+#define RESET_HDMI 25
38+#define RESET_HDCP2TX 26
39+#define RESET_UART6 27
40+#define RESET_UART0 28
41+#define RESET_UART1 29
42+#define RESET_UART2 30
43+#define RESET_SPI0 31
44+#define RESET_SPI1 32
45+#define RESET_SPI2 33
46+#define RESET_SPI3 34
47+#define RESET_I2C0 35
48+#define RESET_I2C1 36
49+#define RESET_USB3 37
50+#define RESET_UART3 38
51+#define RESET_UART4 39
52+#define RESET_UART5 40
53+#define RESET_I2C2 41
54+#define RESET_I2C3 42
55+#define RESET_ETHERNET 43
56+#define RESET_CHIPID 44
57+#define RESET_USB2_1 45
58+#define RESET_WD0RESET 46
59+#define RESET_WD1RESET 47
60+#define RESET_WD2RESET 48
61+#define RESET_WD3RESET 49
62+#define RESET_DBG0RESET 50
63+#define RESET_DBG1RESET 51
64+#define RESET_DBG2RESET 52
65+#define RESET_DBG3RESET 53
66+
67+#endif /* __DT_BINDINGS_ACTIONS_S500_RESET_H */
include/linux/clk-provider.h+0−1
@@ -1096,7 +1096,6 @@ int clk_hw_get_parent_index(struct clk_hw *hw); · 1095 unmodified lines
10961096 int clk_hw_set_parent(struct clk_hw *hw, struct clk_hw *new_parent);
10971097 unsigned int __clk_get_enable_count(struct clk *clk);
10981098 unsigned long clk_hw_get_rate(const struct clk_hw *hw);
1099−unsigned long __clk_get_flags(struct clk *clk);
11001099 unsigned long clk_hw_get_flags(const struct clk_hw *hw);
11011100 #define clk_hw_can_set_rate_parent(hw) \
11021101 (clk_hw_get_flags((hw)) & CLK_SET_RATE_PARENT)
include/linux/clk/at91_pmc.h+4−0
@@ -59,6 +59,7 @@ · 58 unmodified lines
5959 #define AT91_PMC_PLL_UPDT 0x1C /* PMC PLL update register [for SAM9X60] */
6060 #define AT91_PMC_PLL_UPDT_UPDATE (1 << 8) /* Update PLL settings */
6161 #define AT91_PMC_PLL_UPDT_ID (1 << 0) /* PLL ID */
62+#define AT91_PMC_PLL_UPDT_ID_MSK (0xf) /* PLL ID mask */
6263 #define AT91_PMC_PLL_UPDT_STUPTIM (0xff << 16) /* Startup time */
6364
6465 #define AT91_CKGR_MOR 0x20 /* Main Oscillator Register [not on SAM9RL] */
@@ -136,6 +137,8 @@ · 71 unmodified lines
136137 #define AT91_PMC_PLLADIV2_ON (1 << 12)
137138 #define AT91_PMC_H32MXDIV BIT(24)
138139
140+#define AT91_PMC_XTALF 0x34 /* Main XTAL Frequency Register [SAMA7G5 only] */
141+
139142 #define AT91_PMC_USB 0x38 /* USB Clock Register [some SAM9 only] */
140143 #define AT91_PMC_USBS (0x1 << 0) /* USB OHCI Input clock selection */
141144 #define AT91_PMC_USBS_PLLA (0 << 0)
@@ -174,6 +177,7 @@ · 32 unmodified lines
174177 #define AT91_PMC_MOSCRCS (1 << 17) /* Main On-Chip RC [some SAM9] */
175178 #define AT91_PMC_CFDEV (1 << 18) /* Clock Failure Detector Event [some SAM9] */
176179 #define AT91_PMC_GCKRDY (1 << 24) /* Generated Clocks */
180+#define AT91_PMC_MCKXRDY (1 << 26) /* Master Clock x [x=1..4] Ready Status */
177181 #define AT91_PMC_IMR 0x6c /* Interrupt Mask Register */
178182
179183 #define AT91_PMC_FSMR 0x70 /* Fast Startup Mode Register */