aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-firmware.txt14
-rw-r--r--Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-firmware.yaml68
-rw-r--r--Documentation/devicetree/bindings/clock/brcm,bcm2711-dvp.yaml47
-rw-r--r--Documentation/devicetree/bindings/clock/brcm,bcm63xx-clocks.txt2
-rw-r--r--Documentation/devicetree/bindings/clock/clock-bindings.txt2
-rw-r--r--Documentation/devicetree/bindings/clock/idt,versaclock5.txt92
-rw-r--r--Documentation/devicetree/bindings/clock/idt,versaclock5.yaml154
-rw-r--r--Documentation/devicetree/bindings/clock/qcom,a53pll.yaml21
-rw-r--r--Documentation/devicetree/bindings/clock/qcom,gpucc.yaml (renamed from Documentation/devicetree/bindings/clock/qcom,sdm845-gpucc.yaml)18
-rw-r--r--Documentation/devicetree/bindings/clock/qcom,msm8996-apcc.yaml54
-rw-r--r--Documentation/devicetree/bindings/clock/qcom,rpmcc.txt4
-rw-r--r--Documentation/devicetree/bindings/clock/qcom,sc7180-gpucc.yaml74
-rw-r--r--Documentation/devicetree/bindings/clock/qcom,sc7180-lpasscorecc.yaml108
-rw-r--r--Documentation/devicetree/bindings/clock/renesas,cpg-clocks.yaml241
-rw-r--r--Documentation/devicetree/bindings/clock/renesas,cpg-mssr.yaml1
-rw-r--r--Documentation/devicetree/bindings/clock/renesas,r8a73a4-cpg-clocks.txt33
-rw-r--r--Documentation/devicetree/bindings/clock/renesas,r8a7740-cpg-clocks.txt41
-rw-r--r--Documentation/devicetree/bindings/clock/renesas,r8a7778-cpg-clocks.txt47
-rw-r--r--Documentation/devicetree/bindings/clock/renesas,r8a7779-cpg-clocks.txt49
-rw-r--r--Documentation/devicetree/bindings/clock/renesas,rz-cpg-clocks.txt53
-rw-r--r--Documentation/devicetree/bindings/clock/renesas,sh73a0-cpg-clocks.txt35
-rw-r--r--Documentation/devicetree/bindings/clock/rockchip,rk3288-cru.txt8
-rw-r--r--Documentation/devicetree/bindings/clock/silabs,si514.txt2
-rw-r--r--Documentation/devicetree/bindings/clock/silabs,si5351.txt2
-rw-r--r--Documentation/devicetree/bindings/clock/silabs,si570.txt4
-rw-r--r--Documentation/devicetree/bindings/clock/ti,cdce706.txt2
-rw-r--r--Documentation/devicetree/bindings/clock/ti,cdce925.txt8
-rw-r--r--MAINTAINERS4
-rw-r--r--drivers/clk/Kconfig3
-rw-r--r--drivers/clk/actions/owl-s500.c89
-rw-r--r--drivers/clk/bcm/Kconfig11
-rw-r--r--drivers/clk/bcm/Makefile1
-rw-r--r--drivers/clk/bcm/clk-bcm2711-dvp.c124
-rw-r--r--drivers/clk/bcm/clk-bcm2835.c59
-rw-r--r--drivers/clk/bcm/clk-bcm63xx-gate.c553
-rw-r--r--drivers/clk/bcm/clk-iproc-asiu.c4
-rw-r--r--drivers/clk/bcm/clk-raspberrypi.c311
-rw-r--r--drivers/clk/clk-ast2600.c49
-rw-r--r--drivers/clk/clk-cdce706.c2
-rw-r--r--drivers/clk/clk-gpio.c2
-rw-r--r--drivers/clk/clk-si5351.c4
-rw-r--r--drivers/clk/clk-versaclock5.c304
-rw-r--r--drivers/clk/clk.c47
-rw-r--r--drivers/clk/davinci/pll.c2
-rw-r--r--drivers/clk/imx/clk-imx8mp.c1
-rw-r--r--drivers/clk/imx/clk-pllv3.c4
-rw-r--r--drivers/clk/imx/clk-vf610.c1
-rw-r--r--drivers/clk/ingenic/jz4780-cgu.c165
-rw-r--r--drivers/clk/ingenic/x1000-cgu.c97
-rw-r--r--drivers/clk/ingenic/x1830-cgu.c13
-rw-r--r--drivers/clk/keystone/sci-clk.c2
-rw-r--r--drivers/clk/keystone/syscon-clk.c2
-rw-r--r--drivers/clk/meson/g12a.c119
-rw-r--r--drivers/clk/meson/g12a.h7
-rw-r--r--drivers/clk/meson/meson8b.c67
-rw-r--r--drivers/clk/meson/meson8b.h6
-rw-r--r--drivers/clk/mvebu/Kconfig1
-rw-r--r--drivers/clk/qcom/Kconfig53
-rw-r--r--drivers/clk/qcom/Makefile6
-rw-r--r--drivers/clk/qcom/apss-ipq-pll.c95
-rw-r--r--drivers/clk/qcom/apss-ipq6018.c106
-rw-r--r--drivers/clk/qcom/clk-alpha-pll.c70
-rw-r--r--drivers/clk/qcom/clk-alpha-pll.h21
-rw-r--r--drivers/clk/qcom/clk-cpu-8996.c538
-rw-r--r--drivers/clk/qcom/clk-smd-rpm.c297
-rw-r--r--drivers/clk/qcom/gcc-ipq806x.c2
-rw-r--r--drivers/clk/qcom/gcc-ipq8074.c60
-rw-r--r--drivers/clk/qcom/gcc-sc7180.c16
-rw-r--r--drivers/clk/qcom/gcc-sdm660.c4
-rw-r--r--drivers/clk/qcom/gcc-sdm845.c4
-rw-r--r--drivers/clk/qcom/gcc-sm8150.c26
-rw-r--r--drivers/clk/qcom/gdsc.c39
-rw-r--r--drivers/clk/qcom/gdsc.h2
-rw-r--r--drivers/clk/qcom/gpucc-sc7180.c27
-rw-r--r--drivers/clk/qcom/gpucc-sdm845.c27
-rw-r--r--drivers/clk/qcom/gpucc-sm8150.c320
-rw-r--r--drivers/clk/qcom/gpucc-sm8250.c348
-rw-r--r--drivers/clk/qcom/lpasscorecc-sc7180.c476
-rw-r--r--drivers/clk/renesas/Kconfig5
-rw-r--r--drivers/clk/renesas/Makefile1
-rw-r--r--drivers/clk/renesas/r8a774a1-cpg-mssr.c1
-rw-r--r--drivers/clk/renesas/r8a774b1-cpg-mssr.c1
-rw-r--r--drivers/clk/renesas/r8a774c0-cpg-mssr.c1
-rw-r--r--drivers/clk/renesas/r8a774e1-cpg-mssr.c349
-rw-r--r--drivers/clk/renesas/r8a7795-cpg-mssr.c2
-rw-r--r--drivers/clk/renesas/r8a7796-cpg-mssr.c2
-rw-r--r--drivers/clk/renesas/r8a77965-cpg-mssr.c1
-rw-r--r--drivers/clk/renesas/r8a77970-cpg-mssr.c2
-rw-r--r--drivers/clk/renesas/r8a77980-cpg-mssr.c2
-rw-r--r--drivers/clk/renesas/r8a77990-cpg-mssr.c1
-rw-r--r--drivers/clk/renesas/r8a77995-cpg-mssr.c2
-rw-r--r--drivers/clk/renesas/renesas-cpg-mssr.c23
-rw-r--r--drivers/clk/renesas/renesas-cpg-mssr.h1
-rw-r--r--drivers/clk/rockchip/clk-pll.c70
-rw-r--r--drivers/clk/rockchip/clk-rk3188.c1
-rw-r--r--drivers/clk/rockchip/clk-rk3288.c39
-rw-r--r--drivers/clk/rockchip/clk-rk3328.c8
-rw-r--r--drivers/clk/sirf/clk-atlas6.c2
-rw-r--r--drivers/clk/socfpga/clk-agilex.c8
-rw-r--r--drivers/clk/tegra/clk-pll.c20
-rw-r--r--drivers/clk/versatile/icst.c2
-rw-r--r--drivers/clk/versatile/icst.h2
-rw-r--r--drivers/clk/x86/clk-cgu-pll.c2
-rw-r--r--drivers/clk/x86/clk-cgu.c32
-rw-r--r--drivers/firmware/raspberrypi.c14
-rw-r--r--drivers/perf/Kconfig1
-rw-r--r--drivers/perf/qcom_l2_pmu.c90
-rw-r--r--drivers/reset/reset-simple.c23
-rw-r--r--drivers/reset/reset-socfpga.c3
-rw-r--r--drivers/reset/reset-sunxi.c3
-rw-r--r--drivers/reset/reset-uniphier-glue.c3
-rw-r--r--drivers/soc/qcom/Kconfig4
-rw-r--r--drivers/soc/qcom/Makefile1
-rw-r--r--drivers/soc/qcom/kryo-l2-accessors.c57
-rw-r--r--include/dt-bindings/clk/versaclock.h13
-rw-r--r--include/dt-bindings/clock/actions,s500-cmu.h7
-rw-r--r--include/dt-bindings/clock/agilex-clock.h4
-rw-r--r--include/dt-bindings/clock/bcm3368-clock.h24
-rw-r--r--include/dt-bindings/clock/bcm6318-clock.h42
-rw-r--r--include/dt-bindings/clock/bcm63268-clock.h30
-rw-r--r--include/dt-bindings/clock/bcm6328-clock.h19
-rw-r--r--include/dt-bindings/clock/bcm6358-clock.h18
-rw-r--r--include/dt-bindings/clock/bcm6362-clock.h26
-rw-r--r--include/dt-bindings/clock/bcm6368-clock.h24
-rw-r--r--include/dt-bindings/clock/g12a-clkc.h2
-rw-r--r--include/dt-bindings/clock/jz4780-cgu.h144
-rw-r--r--include/dt-bindings/clock/qcom,apss-ipq.h12
-rw-r--r--include/dt-bindings/clock/qcom,gcc-ipq8074.h4
-rw-r--r--include/dt-bindings/clock/qcom,gcc-sc7180.h1
-rw-r--r--include/dt-bindings/clock/qcom,gcc-sdm660.h1
-rw-r--r--include/dt-bindings/clock/qcom,gpucc-sm8150.h33
-rw-r--r--include/dt-bindings/clock/qcom,gpucc-sm8250.h34
-rw-r--r--include/dt-bindings/clock/qcom,lpasscorecc-sc7180.h29
-rw-r--r--include/dt-bindings/clock/qcom,rpmcc.h16
-rw-r--r--include/dt-bindings/clock/r8a774e1-cpg-mssr.h59
-rw-r--r--include/dt-bindings/clock/vf610-clock.h3
-rw-r--r--include/dt-bindings/clock/x1000-cgu.h2
-rw-r--r--include/dt-bindings/clock/x1830-cgu.h2
-rw-r--r--include/dt-bindings/power/r8a774e1-sysc.h36
-rw-r--r--include/dt-bindings/reset/actions,s500-reset.h67
-rw-r--r--include/linux/clk-provider.h2
-rw-r--r--include/linux/reset/reset-simple.h (renamed from drivers/reset/reset-simple.h)7
-rw-r--r--include/soc/qcom/kryo-l2-accessors.h12
143 files changed, 5992 insertions, 1235 deletions
diff --git a/Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-firmware.txt b/Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-firmware.txt
deleted file mode 100644
index 6824b3180ffb..000000000000
--- a/Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-firmware.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-Raspberry Pi VideoCore firmware driver
-
-Required properties:
-
-- compatible: Should be "raspberrypi,bcm2835-firmware"
-- mboxes: Phandle to the firmware device's Mailbox.
- (See: ../mailbox/mailbox.txt for more information)
-
-Example:
-
-firmware {
- compatible = "raspberrypi,bcm2835-firmware";
- mboxes = <&mailbox>;
-};
diff --git a/Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-firmware.yaml b/Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-firmware.yaml
new file mode 100644
index 000000000000..17e4f20c8d39
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-firmware.yaml
@@ -0,0 +1,68 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/arm/bcm/raspberrypi,bcm2835-firmware.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Raspberry Pi VideoCore firmware driver
+
+maintainers:
+ - Eric Anholt <eric@anholt.net>
+ - Stefan Wahren <wahrenst@gmx.net>
+
+select:
+ properties:
+ compatible:
+ contains:
+ const: raspberrypi,bcm2835-firmware
+
+ required:
+ - compatible
+
+properties:
+ compatible:
+ items:
+ - const: raspberrypi,bcm2835-firmware
+ - const: simple-bus
+
+ mboxes:
+ $ref: '/schemas/types.yaml#/definitions/phandle'
+ description: |
+ Phandle to the firmware device's Mailbox.
+ (See: ../mailbox/mailbox.txt for more information)
+
+ clocks:
+ type: object
+
+ properties:
+ compatible:
+ const: raspberrypi,firmware-clocks
+
+ "#clock-cells":
+ const: 1
+ description: >
+ The argument is the ID of the clocks contained by the
+ firmware messages.
+
+ required:
+ - compatible
+ - "#clock-cells"
+
+ additionalProperties: false
+
+required:
+ - compatible
+ - mboxes
+
+examples:
+ - |
+ firmware {
+ compatible = "raspberrypi,bcm2835-firmware", "simple-bus";
+ mboxes = <&mailbox>;
+
+ firmware_clocks: clocks {
+ compatible = "raspberrypi,firmware-clocks";
+ #clock-cells = <1>;
+ };
+ };
+...
diff --git a/Documentation/devicetree/bindings/clock/brcm,bcm2711-dvp.yaml b/Documentation/devicetree/bindings/clock/brcm,bcm2711-dvp.yaml
new file mode 100644
index 000000000000..08543ecbe35b
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/brcm,bcm2711-dvp.yaml
@@ -0,0 +1,47 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/brcm,bcm2711-dvp.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Broadcom BCM2711 HDMI DVP Device Tree Bindings
+
+maintainers:
+ - Maxime Ripard <mripard@kernel.org>
+
+properties:
+ "#clock-cells":
+ const: 1
+
+ "#reset-cells":
+ const: 1
+
+ compatible:
+ const: brcm,brcm2711-dvp
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ maxItems: 1
+
+required:
+ - "#clock-cells"
+ - "#reset-cells"
+ - compatible
+ - reg
+ - clocks
+
+additionalProperties: false
+
+examples:
+ - |
+ dvp: clock@7ef00000 {
+ compatible = "brcm,brcm2711-dvp";
+ reg = <0x7ef00000 0x10>;
+ clocks = <&clk_108MHz>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
+
+...
diff --git a/Documentation/devicetree/bindings/clock/brcm,bcm63xx-clocks.txt b/Documentation/devicetree/bindings/clock/brcm,bcm63xx-clocks.txt
index 3041657e2f96..3e7ca5530775 100644
--- a/Documentation/devicetree/bindings/clock/brcm,bcm63xx-clocks.txt
+++ b/Documentation/devicetree/bindings/clock/brcm,bcm63xx-clocks.txt
@@ -3,6 +3,8 @@ Gated Clock Controller Bindings for MIPS based BCM63XX SoCs
Required properties:
- compatible: must be one of:
"brcm,bcm3368-clocks"
+ "brcm,bcm6318-clocks"
+ "brcm,bcm6318-ubus-clocks"
"brcm,bcm6328-clocks"
"brcm,bcm6358-clocks"
"brcm,bcm6362-clocks"
diff --git a/Documentation/devicetree/bindings/clock/clock-bindings.txt b/Documentation/devicetree/bindings/clock/clock-bindings.txt
index 8a55fdcf96ee..f2ea53832ac6 100644
--- a/Documentation/devicetree/bindings/clock/clock-bindings.txt
+++ b/Documentation/devicetree/bindings/clock/clock-bindings.txt
@@ -9,7 +9,7 @@ specifier is an array of zero, one or more cells identifying the clock
output on a device. The length of a clock specifier is defined by the
value of a #clock-cells property in the clock provider node.
-[1] http://patchwork.ozlabs.org/patch/31551/
+[1] https://patchwork.ozlabs.org/patch/31551/
==Clock providers==
diff --git a/Documentation/devicetree/bindings/clock/idt,versaclock5.txt b/Documentation/devicetree/bindings/clock/idt,versaclock5.txt
deleted file mode 100644
index bcff681a4bd0..000000000000
--- a/Documentation/devicetree/bindings/clock/idt,versaclock5.txt
+++ /dev/null
@@ -1,92 +0,0 @@
-Binding for IDT VersaClock 5,6 programmable i2c clock generators.
-
-The IDT VersaClock 5 and VersaClock 6 are programmable i2c clock
-generators providing from 3 to 12 output clocks.
-
-==I2C device node==
-
-Required properties:
-- compatible: shall be one of
- "idt,5p49v5923"
- "idt,5p49v5925"
- "idt,5p49v5933"
- "idt,5p49v5935"
- "idt,5p49v6901"
- "idt,5p49v6965"
-- reg: i2c device address, shall be 0x68 or 0x6a.
-- #clock-cells: from common clock binding; shall be set to 1.
-- clocks: from common clock binding; list of parent clock handles,
- - 5p49v5923 and
- 5p49v5925 and
- 5p49v6901: (required) either or both of XTAL or CLKIN
- reference clock.
- - 5p49v5933 and
- - 5p49v5935: (optional) property not present (internal
- Xtal used) or CLKIN reference
- clock.
-- clock-names: from common clock binding; clock input names, can be
- - 5p49v5923 and
- 5p49v5925 and
- 5p49v6901: (required) either or both of "xin", "clkin".
- - 5p49v5933 and
- - 5p49v5935: (optional) property not present or "clkin".
-
-==Mapping between clock specifier and physical pins==
-
-When referencing the provided clock in the DT using phandle and
-clock specifier, the following mapping applies:
-
-5P49V5923:
- 0 -- OUT0_SEL_I2CB
- 1 -- OUT1
- 2 -- OUT2
-
-5P49V5933:
- 0 -- OUT0_SEL_I2CB
- 1 -- OUT1
- 2 -- OUT4
-
-5P49V5925 and
-5P49V5935:
- 0 -- OUT0_SEL_I2CB
- 1 -- OUT1
- 2 -- OUT2
- 3 -- OUT3
- 4 -- OUT4
-
-5P49V6901:
- 0 -- OUT0_SEL_I2CB
- 1 -- OUT1
- 2 -- OUT2
- 3 -- OUT3
- 4 -- OUT4
-
-==Example==
-
-/* 25MHz reference crystal */
-ref25: ref25m {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- clock-frequency = <25000000>;
-};
-
-i2c-master-node {
-
- /* IDT 5P49V5923 i2c clock generator */
- vc5: clock-generator@6a {
- compatible = "idt,5p49v5923";
- reg = <0x6a>;
- #clock-cells = <1>;
-
- /* Connect XIN input to 25MHz reference */
- clocks = <&ref25m>;
- clock-names = "xin";
- };
-};
-
-/* Consumer referencing the 5P49V5923 pin OUT1 */
-consumer {
- ...
- clocks = <&vc5 1>;
- ...
-}
diff --git a/Documentation/devicetree/bindings/clock/idt,versaclock5.yaml b/Documentation/devicetree/bindings/clock/idt,versaclock5.yaml
new file mode 100644
index 000000000000..3d4e1685cc55
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/idt,versaclock5.yaml
@@ -0,0 +1,154 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/idt,versaclock5.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Binding for IDT VersaClock 5 and 6 programmable I2C clock generators
+
+description: |
+ The IDT VersaClock 5 and VersaClock 6 are programmable I2C
+ clock generators providing from 3 to 12 output clocks.
+
+ When referencing the provided clock in the DT using phandle and clock
+ specifier, the following mapping applies:
+
+ - 5P49V5923:
+ 0 -- OUT0_SEL_I2CB
+ 1 -- OUT1
+ 2 -- OUT2
+
+ - 5P49V5933:
+ 0 -- OUT0_SEL_I2CB
+ 1 -- OUT1
+ 2 -- OUT4
+
+ - other parts:
+ 0 -- OUT0_SEL_I2CB
+ 1 -- OUT1
+ 2 -- OUT2
+ 3 -- OUT3
+ 4 -- OUT4
+
+maintainers:
+ - Luca Ceresoli <luca@lucaceresoli.net>
+
+properties:
+ compatible:
+ enum:
+ - idt,5p49v5923
+ - idt,5p49v5925
+ - idt,5p49v5933
+ - idt,5p49v5935
+ - idt,5p49v6901
+ - idt,5p49v6965
+
+ reg:
+ description: I2C device address
+ enum: [ 0x68, 0x6a ]
+
+ '#clock-cells':
+ const: 1
+
+patternProperties:
+ "^OUT[1-4]$":
+ type: object
+ description:
+ Description of one of the outputs (OUT1..OUT4). See "Clock1 Output
+ Configuration" in the Versaclock 5/6/6E Family Register Description
+ and Programming Guide.
+ properties:
+ idt,mode:
+ description:
+ The output drive mode. Values defined in dt-bindings/clk/versaclock.h
+ $ref: /schemas/types.yaml#/definitions/uint32
+ minimum: 0
+ maximum: 6
+ idt,voltage-microvolt:
+ description: The output drive voltage.
+ enum: [ 1800000, 2500000, 3300000 ]
+ idt,slew-percent:
+ description: The Slew rate control for CMOS single-ended.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum: [ 80, 85, 90, 100 ]
+
+required:
+ - compatible
+ - reg
+ - '#clock-cells'
+
+allOf:
+ - if:
+ properties:
+ compatible:
+ enum:
+ - idt,5p49v5933
+ - idt,5p49v5935
+ then:
+ # Devices with builtin crystal + optional external input
+ properties:
+ clock-names:
+ const: clkin
+ clocks:
+ maxItems: 1
+ else:
+ # Devices without builtin crystal
+ properties:
+ clock-names:
+ minItems: 1
+ maxItems: 2
+ items:
+ enum: [ xin, clkin ]
+ clocks:
+ minItems: 1
+ maxItems: 2
+ required:
+ - clock-names
+ - clocks
+
+examples:
+ - |
+ #include <dt-bindings/clk/versaclock.h>
+
+ /* 25MHz reference crystal */
+ ref25: ref25m {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <25000000>;
+ };
+
+ i2c@0 {
+ reg = <0x0 0x100>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* IDT 5P49V5923 I2C clock generator */
+ vc5: clock-generator@6a {
+ compatible = "idt,5p49v5923";
+ reg = <0x6a>;
+ #clock-cells = <1>;
+
+ /* Connect XIN input to 25MHz reference */
+ clocks = <&ref25m>;
+ clock-names = "xin";
+
+ OUT1 {
+ idt,drive-mode = <VC5_CMOSD>;
+ idt,voltage-microvolts = <1800000>;
+ idt,slew-percent = <80>;
+ };
+
+ OUT4 {
+ idt,drive-mode = <VC5_LVDS>;
+ };
+ };
+ };
+
+ /* Consumer referencing the 5P49V5923 pin OUT1 */
+ consumer {
+ /* ... */
+ clocks = <&vc5 1>;
+ /* ... */
+ };
+
+...
diff --git a/Documentation/devicetree/bindings/clock/qcom,a53pll.yaml b/Documentation/devicetree/bindings/clock/qcom,a53pll.yaml
index 20d2638b4cd2..db3d0ea6bc7a 100644
--- a/Documentation/devicetree/bindings/clock/qcom,a53pll.yaml
+++ b/Documentation/devicetree/bindings/clock/qcom,a53pll.yaml
@@ -15,7 +15,9 @@ description:
properties:
compatible:
- const: qcom,msm8916-a53pll
+ enum:
+ - qcom,ipq6018-a53pll
+ - qcom,msm8916-a53pll
reg:
maxItems: 1
@@ -23,6 +25,14 @@ properties:
'#clock-cells':
const: 0
+ clocks:
+ items:
+ - description: board XO clock
+
+ clock-names:
+ items:
+ - const: xo
+
required:
- compatible
- reg
@@ -38,3 +48,12 @@ examples:
reg = <0xb016000 0x40>;
#clock-cells = <0>;
};
+ #Example 2 - A53 PLL found on IPQ6018 devices
+ - |
+ a53pll_ipq: clock-controller@b116000 {
+ compatible = "qcom,ipq6018-a53pll";
+ reg = <0x0b116000 0x40>;
+ #clock-cells = <0>;
+ clocks = <&xo>;
+ clock-names = "xo";
+ };
diff --git a/Documentation/devicetree/bindings/clock/qcom,sdm845-gpucc.yaml b/Documentation/devicetree/bindings/clock/qcom,gpucc.yaml
index 8a0c576ba8b3..df943c4c3234 100644
--- a/Documentation/devicetree/bindings/clock/qcom,sdm845-gpucc.yaml
+++ b/Documentation/devicetree/bindings/clock/qcom,gpucc.yaml
@@ -1,23 +1,31 @@
# SPDX-License-Identifier: GPL-2.0-only
%YAML 1.2
---
-$id: http://devicetree.org/schemas/clock/qcom,sdm845-gpucc.yaml#
+$id: http://devicetree.org/schemas/clock/qcom,gpucc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
-title: Qualcomm Graphics Clock & Reset Controller Binding for SDM845
+title: Qualcomm Graphics Clock & Reset Controller Binding
maintainers:
- Taniya Das <tdas@codeaurora.org>
description: |
Qualcomm graphics clock control module which supports the clocks, resets and
- power domains on SDM845.
+ power domains on SDM845/SC7180/SM8150/SM8250.
- See also dt-bindings/clock/qcom,gpucc-sdm845.h.
+ See also:
+ dt-bindings/clock/qcom,gpucc-sdm845.h
+ dt-bindings/clock/qcom,gpucc-sc7180.h
+ dt-bindings/clock/qcom,gpucc-sm8150.h
+ dt-bindings/clock/qcom,gpucc-sm8250.h
properties:
compatible:
- const: qcom,sdm845-gpucc
+ enum:
+ - qcom,sdm845-gpucc
+ - qcom,sc7180-gpucc
+ - qcom,sm8150-gpucc
+ - qcom,sm8250-gpucc
clocks:
items:
diff --git a/Documentation/devicetree/bindings/clock/qcom,msm8996-apcc.yaml b/Documentation/devicetree/bindings/clock/qcom,msm8996-apcc.yaml
new file mode 100644
index 000000000000..a20cb10636dd
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/qcom,msm8996-apcc.yaml
@@ -0,0 +1,54 @@
+# SPDX-License-Identifier: GPL-2.0-only
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/qcom,msm8996-apcc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm clock controller for MSM8996 CPUs
+
+maintainers:
+ - Loic Poulain <loic.poulain@linaro.org>
+
+description: |
+ Qualcomm CPU clock controller for MSM8996 CPUs, clock 0 is for Power cluster
+ and clock 1 is for Perf cluster.
+
+properties:
+ compatible:
+ enum:
+ - qcom,msm8996-apcc
+
+ reg:
+ maxItems: 1
+
+ '#clock-cells':
+ const: 1
+
+ clocks:
+ items:
+ - description: Primary PLL clock for power cluster (little)
+ - description: Primary PLL clock for perf cluster (big)
+ - description: Alternate PLL clock for power cluster (little)
+ - description: Alternate PLL clock for perf cluster (big)
+
+ clock-names:
+ items:
+ - const: pwrcl_pll
+ - const: perfcl_pll
+ - const: pwrcl_alt_pll
+ - const: perfcl_alt_pll
+
+required:
+ - compatible
+ - reg
+ - '#clock-cells'
+
+additionalProperties: false
+
+examples:
+ - |
+ kryocc: clock-controller@6400000 {
+ compatible = "qcom,msm8996-apcc";
+ reg = <0x6400000 0x90000>;
+ #clock-cells = <1>;
+ };
diff --git a/Documentation/devicetree/bindings/clock/qcom,rpmcc.txt b/Documentation/devicetree/bindings/clock/qcom,rpmcc.txt
index 90a1349bc713..b44a0622fb3a 100644
--- a/Documentation/devicetree/bindings/clock/qcom,rpmcc.txt
+++ b/Documentation/devicetree/bindings/clock/qcom,rpmcc.txt
@@ -13,13 +13,17 @@ Required properties :
"qcom,rpmcc-msm8660", "qcom,rpmcc"
"qcom,rpmcc-apq8060", "qcom,rpmcc"
"qcom,rpmcc-msm8916", "qcom,rpmcc"
+ "qcom,rpmcc-msm8936", "qcom,rpmcc"
"qcom,rpmcc-msm8974", "qcom,rpmcc"
"qcom,rpmcc-msm8976", "qcom,rpmcc"
"qcom,rpmcc-apq8064", "qcom,rpmcc"
"qcom,rpmcc-ipq806x", "qcom,rpmcc"
+ "qcom,rpmcc-msm8992",·"qcom,rpmcc"
+ "qcom,rpmcc-msm8994",·"qcom,rpmcc"
"qcom,rpmcc-msm8996", "qcom,rpmcc"
"qcom,rpmcc-msm8998", "qcom,rpmcc"
"qcom,rpmcc-qcs404", "qcom,rpmcc"
+ "qcom,rpmcc-sdm660", "qcom,rpmcc"
- #clock-cells : shall contain 1
diff --git a/Documentation/devicetree/bindings/clock/qcom,sc7180-gpucc.yaml b/Documentation/devicetree/bindings/clock/qcom,sc7180-gpucc.yaml
deleted file mode 100644
index fe08461fce05..000000000000
--- a/Documentation/devicetree/bindings/clock/qcom,sc7180-gpucc.yaml
+++ /dev/null
@@ -1,74 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-%YAML 1.2
----
-$id: http://devicetree.org/schemas/clock/qcom,sc7180-gpucc.yaml#
-$schema: http://devicetree.org/meta-schemas/core.yaml#
-
-title: Qualcomm Graphics Clock & Reset Controller Binding for SC7180
-
-maintainers:
- - Taniya Das <tdas@codeaurora.org>
-
-description: |
- Qualcomm graphics clock control module which supports the clocks, resets and
- power domains on SC7180.
-
- See also dt-bindings/clock/qcom,gpucc-sc7180.h.
-
-properties:
- compatible:
- const: qcom,sc7180-gpucc
-
- clocks:
- items:
- - description: Board XO source
- - description: GPLL0 main branch source
- - description: GPLL0 div branch source
-
- clock-names:
- items:
- - const: bi_tcxo
- - const: gcc_gpu_gpll0_clk_src
- - const: gcc_gpu_gpll0_div_clk_src
-
- '#clock-cells':
- const: 1
-
- '#reset-cells':
- const: 1
-
- '#power-domain-cells':
- const: 1
-
- reg:
- maxItems: 1
-
-required:
- - compatible
- - reg
- - clocks
- - clock-names
- - '#clock-cells'
- - '#reset-cells'
- - '#power-domain-cells'
-
-additionalProperties: false
-
-examples:
- - |
- #include <dt-bindings/clock/qcom,gcc-sc7180.h>
- #include <dt-bindings/clock/qcom,rpmh.h>
- clock-controller@5090000 {
- compatible = "qcom,sc7180-gpucc";
- reg = <0x05090000 0x9000>;
- clocks = <&rpmhcc RPMH_CXO_CLK>,
- <&gcc GCC_GPU_GPLL0_CLK_SRC>,
- <&gcc GCC_GPU_GPLL0_DIV_CLK_SRC>;
- clock-names = "bi_tcxo",
- "gcc_gpu_gpll0_clk_src",
- "gcc_gpu_gpll0_div_clk_src";
- #clock-cells = <1>;
- #reset-cells = <1>;
- #power-domain-cells = <1>;
- };
-...
diff --git a/Documentation/devicetree/bindings/clock/qcom,sc7180-lpasscorecc.yaml b/Documentation/devicetree/bindings/clock/qcom,sc7180-lpasscorecc.yaml
new file mode 100644
index 000000000000..c54172fbf29f
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/qcom,sc7180-lpasscorecc.yaml
@@ -0,0 +1,108 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/qcom,sc7180-lpasscorecc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm LPASS Core Clock Controller Binding for SC7180
+
+maintainers:
+ - Taniya Das <tdas@codeaurora.org>
+
+description: |
+ Qualcomm LPASS core clock control module which supports the clocks and
+ power domains on SC7180.
+
+ See also:
+ - dt-bindings/clock/qcom,lpasscorecc-sc7180.h
+
+properties:
+ compatible:
+ enum:
+ - qcom,sc7180-lpasshm
+ - qcom,sc7180-lpasscorecc
+
+ clocks:
+ items:
+ - description: gcc_lpass_sway clock from GCC
+ - description: Board XO source
+
+ clock-names:
+ items:
+ - const: iface
+ - const: bi_tcxo
+
+ power-domains:
+ maxItems: 1
+
+ '#clock-cells':
+ const: 1
+
+ '#power-domain-cells':
+ const: 1
+
+ reg:
+ minItems: 1
+ items:
+ - description: lpass core cc register
+ - description: lpass audio cc register
+
+ reg-names:
+ items:
+ - const: lpass_core_cc
+ - const: lpass_audio_cc
+
+if:
+ properties:
+ compatible:
+ contains:
+ const: qcom,sc7180-lpasshm
+then:
+ properties:
+ reg:
+ maxItems: 1
+
+else:
+ properties:
+ reg:
+ minItems: 2
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - clock-names
+ - '#clock-cells'
+ - '#power-domain-cells'
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/qcom,rpmh.h>
+ #include <dt-bindings/clock/qcom,gcc-sc7180.h>
+ #include <dt-bindings/clock/qcom,lpasscorecc-sc7180.h>
+ clock-controller@63000000 {
+ compatible = "qcom,sc7180-lpasshm";
+ reg = <0x63000000 0x28>;
+ clocks = <&gcc GCC_LPASS_CFG_NOC_SWAY_CLK>, <&rpmhcc RPMH_CXO_CLK>;
+ clock-names = "iface", "bi_tcxo";
+ #clock-cells = <1>;
+ #power-domain-cells = <1>;
+ };
+
+ - |
+ #include <dt-bindings/clock/qcom,rpmh.h>
+ #include <dt-bindings/clock/qcom,gcc-sc7180.h>
+ #include <dt-bindings/clock/qcom,lpasscorecc-sc7180.h>
+ clock-controller@62d00000 {
+ compatible = "qcom,sc7180-lpasscorecc";
+ reg = <0x62d00000 0x50000>, <0x62780000 0x30000>;
+ reg-names = "lpass_core_cc", "lpass_audio_cc";
+ clocks = <&gcc GCC_LPASS_CFG_NOC_SWAY_CLK>, <&rpmhcc RPMH_CXO_CLK>;
+ clock-names = "iface", "bi_tcxo";
+ power-domains = <&lpass_hm LPASS_CORE_HM_GDSCR>;
+ #clock-cells = <1>;
+ #power-domain-cells = <1>;
+ };
+...
diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-clocks.yaml b/Documentation/devicetree/bindings/clock/renesas,cpg-clocks.yaml
new file mode 100644
index 000000000000..b83f4138f2f8
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/renesas,cpg-clocks.yaml
@@ -0,0 +1,241 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/renesas,cpg-clocks.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Renesas Clock Pulse Generator (CPG)
+
+maintainers:
+ - Geert Uytterhoeven <geert+renesas@glider.be>
+
+description:
+ The Clock Pulse Generator (CPG) generates core clocks for the SoC. It
+ includes PLLs, and fixed and variable ratio dividers.
+
+ The CPG may also provide a Clock Domain for SoC devices, in combination with
+ the CPG Module Stop (MSTP) Clocks.
+
+properties:
+ compatible:
+ oneOf:
+ - const: renesas,r8a73a4-cpg-clocks # R-Mobile APE6
+ - const: renesas,r8a7740-cpg-clocks # R-Mobile A1
+ - const: renesas,r8a7778-cpg-clocks # R-Car M1
+ - const: renesas,r8a7779-cpg-clocks # R-Car H1
+ - items:
+ - enum:
+ - renesas,r7s72100-cpg-clocks # RZ/A1H
+ - const: renesas,rz-cpg-clocks # RZ/A1
+ - const: renesas,sh73a0-cpg-clocks # SH-Mobile AG5
+
+ reg:
+ maxItems: 1
+
+ clocks: true
+
+ '#clock-cells':
+ const: 1
+
+ clock-output-names: true
+
+ renesas,mode:
+ description: Board-specific settings of the MD_CK* bits on R-Mobile A1
+ $ref: /schemas/types.yaml#/definitions/uint32
+ minimum: 0
+ maximum: 7
+
+ '#power-domain-cells':
+ const: 0
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - '#clock-cells'
+ - clock-output-names
+
+allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: renesas,r8a73a4-cpg-clocks
+ then:
+ properties:
+ clocks:
+ items:
+ - description: extal1
+ - description: extal2
+
+ clock-output-names:
+ items:
+ - const: main
+ - const: pll0
+ - const: pll1
+ - const: pll2
+ - const: pll2s
+ - const: pll2h
+ - const: z
+ - const: z2
+ - const: i
+ - const: m3
+ - const: b
+ - const: m1
+ - const: m2
+ - const: zx
+ - const: zs
+ - const: hp
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: renesas,r8a7740-cpg-clocks
+ then:
+ properties:
+ clocks:
+ items:
+ - description: extal1
+ - description: extal2
+ - description: extalr
+
+ clock-output-names:
+ items:
+ - const: system
+ - const: pllc0
+ - const: pllc1
+ - const: pllc2
+ - const: r
+ - const: usb24s
+ - const: i
+ - const: zg
+ - const: b
+ - const: m1
+ - const: hp
+ - const: hpp
+ - const: usbp
+ - const: s
+ - const: zb
+ - const: m3
+ - const: cp
+
+ required:
+ - renesas,mode
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: renesas,r8a7778-cpg-clocks
+ then:
+ properties:
+ clocks:
+ maxItems: 1
+
+ clock-output-names:
+ items:
+ - const: plla
+ - const: pllb
+ - const: b
+ - const: out
+ - const: p
+ - const: s
+ - const: s1
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: renesas,r8a7779-cpg-clocks
+ then:
+ properties:
+ clocks:
+ maxItems: 1
+
+ clock-output-names:
+ items:
+ - const: plla
+ - const: z
+ - const: zs
+ - const: s
+ - const: s1
+ - const: p
+ - const: b
+ - const: out
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: renesas,r7s72100-cpg-clocks
+ then:
+ properties:
+ clocks:
+ items:
+ - description: extal1
+ - description: usb_x1
+
+ clock-output-names:
+ items:
+ - const: pll
+ - const: i
+ - const: g
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: renesas,sh73a0-cpg-clocks
+ then:
+ properties:
+ clocks:
+ items:
+ - description: extal1
+ - description: extal2
+
+ clock-output-names:
+ items:
+ - const: main
+ - const: pll0
+ - const: pll1
+ - const: pll2
+ - const: pll3
+ - const: dsi0phy
+ - const: dsi1phy
+ - const: zg
+ - const: m3
+ - const: b
+ - const: m1
+ - const: m2
+ - const: z
+ - const: zx
+ - const: hp
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - renesas,r8a7778-cpg-clocks
+ - renesas,r8a7779-cpg-clocks
+ - renesas,rz-cpg-clocks
+ then:
+ required:
+ - '#power-domain-cells'
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/r8a7740-clock.h>
+ cpg_clocks: cpg_clocks@e6150000 {
+ compatible = "renesas,r8a7740-cpg-clocks";
+ reg = <0xe6150000 0x10000>;
+ clocks = <&extal1_clk>, <&extal2_clk>, <&extalr_clk>;
+ #clock-cells = <1>;
+ clock-output-names = "system", "pllc0", "pllc1", "pllc2", "r",
+ "usb24s", "i", "zg", "b", "m1", "hp", "hpp",
+ "usbp", "s", "zb", "m3", "cp";
+ renesas,mode = <0x05>;
+ };
diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.yaml b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.yaml
index c745bd60719a..e13aee8ab61a 100644
--- a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.yaml
+++ b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.yaml
@@ -33,6 +33,7 @@ properties:
- renesas,r8a774a1-cpg-mssr # RZ/G2M
- renesas,r8a774b1-cpg-mssr # RZ/G2N
- renesas,r8a774c0-cpg-mssr # RZ/G2E
+ - renesas,r8a774e1-cpg-mssr # RZ/G2H
- renesas,r8a7790-cpg-mssr # R-Car H2
- renesas,r8a7791-cpg-mssr # R-Car M2-W
- renesas,r8a7792-cpg-mssr # R-Car V2H
diff --git a/Documentation/devicetree/bindings/clock/renesas,r8a73a4-cpg-clocks.txt b/Documentation/devicetree/bindings/clock/renesas,r8a73a4-cpg-clocks.txt
deleted file mode 100644
index ece92393e80d..000000000000
--- a/Documentation/devicetree/bindings/clock/renesas,r8a73a4-cpg-clocks.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-* Renesas R8A73A4 Clock Pulse Generator (CPG)
-
-The CPG generates core clocks for the R8A73A4 SoC. It includes five PLLs
-and several fixed ratio dividers.
-
-Required Properties:
-
- - compatible: Must be "renesas,r8a73a4-cpg-clocks"
-
- - reg: Base address and length of the memory resource used by the CPG
-
- - clocks: Reference to the parent clocks ("extal1" and "extal2")
-
- - #clock-cells: Must be 1
-
- - clock-output-names: The names of the clocks. Supported clocks are "main",
- "pll0", "pll1", "pll2", "pll2s", "pll2h", "z", "z2", "i", "m3", "b",
- "m1", "m2", "zx", "zs", and "hp".
-
-
-Example
--------
-
- cpg_clocks: cpg_clocks@e6150000 {
- compatible = "renesas,r8a73a4-cpg-clocks";
- reg = <0 0xe6150000 0 0x10000>;
- clocks = <&extal1_clk>, <&extal2_clk>;
- #clock-cells = <1>;
- clock-output-names = "main", "pll0", "pll1", "pll2",
- "pll2s", "pll2h", "z", "z2",
- "i", "m3", "b", "m1", "m2",
- "zx", "zs", "hp";
- };
diff --git a/Documentation/devicetree/bindings/clock/renesas,r8a7740-cpg-clocks.txt b/Documentation/devicetree/bindings/clock/renesas,r8a7740-cpg-clocks.txt
deleted file mode 100644
index 2c03302f86ed..000000000000
--- a/Documentation/devicetree/bindings/clock/renesas,r8a7740-cpg-clocks.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-These bindings should be considered EXPERIMENTAL for now.
-
-* Renesas R8A7740 Clock Pulse Generator (CPG)
-
-The CPG generates core clocks for the R8A7740 SoC. It includes three PLLs
-and several fixed ratio and variable ratio dividers.
-
-Required Properties:
-
- - compatible: Must be "renesas,r8a7740-cpg-clocks"
-
- - reg: Base address and length of the memory resource used by the CPG
-
- - clocks: Reference to the three parent clocks
- - #clock-cells: Must be 1
- - clock-output-names: The names of the clocks. Supported clocks are
- "system", "pllc0", "pllc1", "pllc2", "r", "usb24s", "i", "zg", "b",
- "m1", "hp", "hpp", "usbp", "s", "zb", "m3", and "cp".
-
- - renesas,mode: board-specific settings of the MD_CK* bits
-
-
-Example
--------
-
-cpg_clocks: cpg_clocks@e6150000 {
- compatible = "renesas,r8a7740-cpg-clocks";
- reg = <0xe6150000 0x10000>;
- clocks = <&extal1_clk>, <&extal2_clk>, <&extalr_clk>;
- #clock-cells = <1>;
- clock-output-names = "system", "pllc0", "pllc1",
- "pllc2", "r",
- "usb24s",
- "i", "zg", "b", "m1", "hp",
- "hpp", "usbp", "s", "zb", "m3",
- "cp";
-};
-
-&cpg_clocks {
- renesas,mode = <0x05>;
-};
diff --git a/Documentation/devicetree/bindings/clock/renesas,r8a7778-cpg-clocks.txt b/Documentation/devicetree/bindings/clock/renesas,r8a7778-cpg-clocks.txt
deleted file mode 100644
index 7cc4c0330b53..000000000000
--- a/Documentation/devicetree/bindings/clock/renesas,r8a7778-cpg-clocks.txt
+++ /dev/null
@@ -1,47 +0,0 @@
-* Renesas R8A7778 Clock Pulse Generator (CPG)
-
-The CPG generates core clocks for the R8A7778. It includes two PLLs and
-several fixed ratio dividers.
-The CPG also provides a Clock Domain for SoC devices, in combination with the
-CPG Module Stop (MSTP) Clocks.
-
-Required Properties:
-
- - compatible: Must be "renesas,r8a7778-cpg-clocks"
- - reg: Base address and length of the memory resource used by the CPG
- - #clock-cells: Must be 1
- - clock-output-names: The names of the clocks. Supported clocks are
- "plla", "pllb", "b", "out", "p", "s", and "s1".
- - #power-domain-cells: Must be 0
-
-SoC devices that are part of the CPG/MSTP Clock Domain and can be power-managed
-through an MSTP clock should refer to the CPG device node in their
-"power-domains" property, as documented by the generic PM domain bindings in
-Documentation/devicetree/bindings/power/power_domain.txt.
-
-
-Examples
---------
-
- - CPG device node:
-
- cpg_clocks: cpg_clocks@ffc80000 {
- compatible = "renesas,r8a7778-cpg-clocks";
- reg = <0xffc80000 0x80>;
- #clock-cells = <1>;
- clocks = <&extal_clk>;
- clock-output-names = "plla", "pllb", "b",
- "out", "p", "s", "s1";
- #power-domain-cells = <0>;
- };
-
-
- - CPG/MSTP Clock Domain member device node:
-
- sdhi0: sd@ffe4c000 {
- compatible = "renesas,sdhi-r8a7778";
- reg = <0xffe4c000 0x100>;
- interrupts = <0 87 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&mstp3_clks R8A7778_CLK_SDHI0>;
- power-domains = <&cpg_clocks>;
- };
diff --git a/Documentation/devicetree/bindings/clock/renesas,r8a7779-cpg-clocks.txt b/Documentation/devicetree/bindings/clock/renesas,r8a7779-cpg-clocks.txt
deleted file mode 100644
index 8c81547c29f5..000000000000
--- a/Documentation/devicetree/bindings/clock/renesas,r8a7779-cpg-clocks.txt
+++ /dev/null
@@ -1,49 +0,0 @@
-* Renesas R8A7779 Clock Pulse Generator (CPG)
-
-The CPG generates core clocks for the R8A7779. It includes one PLL and
-several fixed ratio dividers.
-The CPG also provides a Clock Domain for SoC devices, in combination with the
-CPG Module Stop (MSTP) Clocks.
-
-Required Properties:
-
- - compatible: Must be "renesas,r8a7779-cpg-clocks"
- - reg: Base address and length of the memory resource used by the CPG
-
- - clocks: Reference to the parent clock
- - #clock-cells: Must be 1
- - clock-output-names: The names of the clocks. Supported clocks are "plla",
- "z", "zs", "s", "s1", "p", "b", "out".
- - #power-domain-cells: Must be 0
-
-SoC devices that are part of the CPG/MSTP Clock Domain and can be power-managed
-through an MSTP clock should refer to the CPG device node in their
-"power-domains" property, as documented by the generic PM domain bindings in
-Documentation/devicetree/bindings/power/power_domain.txt.
-
-
-Examples
---------
-
- - CPG device node:
-
- cpg_clocks: cpg_clocks@ffc80000 {
- compatible = "renesas,r8a7779-cpg-clocks";
- reg = <0xffc80000 0x30>;
- clocks = <&extal_clk>;
- #clock-cells = <1>;
- clock-output-names = "plla", "z", "zs", "s", "s1", "p",
- "b", "out";
- #power-domain-cells = <0>;
- };
-
-
- - CPG/MSTP Clock Domain member device node:
-
- sata: sata@fc600000 {
- compatible = "renesas,sata-r8a7779", "renesas,rcar-sata";
- reg = <0xfc600000 0x2000>;
- interrupts = <0 100 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&mstp1_clks R8A7779_CLK_SATA>;
- power-domains = <&cpg_clocks>;
- };
diff --git a/Documentation/devicetree/bindings/clock/renesas,rz-cpg-clocks.txt b/Documentation/devicetree/bindings/clock/renesas,rz-cpg-clocks.txt
deleted file mode 100644
index 8ff3e2774ed8..000000000000
--- a/Documentation/devicetree/bindings/clock/renesas,rz-cpg-clocks.txt
+++ /dev/null
@@ -1,53 +0,0 @@
-* Renesas RZ/A1 Clock Pulse Generator (CPG)
-
-The CPG generates core clocks for the RZ/A1 SoCs. It includes the PLL, variable
-CPU and GPU clocks, and several fixed ratio dividers.
-The CPG also provides a Clock Domain for SoC devices, in combination with the
-CPG Module Stop (MSTP) Clocks.
-
-Required Properties:
-
- - compatible: Must be one of
- - "renesas,r7s72100-cpg-clocks" for the r7s72100 CPG
- and "renesas,rz-cpg-clocks" as a fallback.
- - reg: Base address and length of the memory resource used by the CPG
- - clocks: References to possible parent clocks. Order must match clock modes
- in the datasheet. For the r7s72100, this is extal, usb_x1.
- - #clock-cells: Must be 1
- - clock-output-names: The names of the clocks. Supported clocks are "pll",
- "i", and "g"
- - #power-domain-cells: Must be 0
-
-SoC devices that are part of the CPG/MSTP Clock Domain and can be power-managed
-through an MSTP clock should refer to the CPG device node in their
-"power-domains" property, as documented by the generic PM domain bindings in
-Documentation/devicetree/bindings/power/power_domain.txt.
-
-
-Examples
---------
-
- - CPG device node:
-
- cpg_clocks: cpg_clocks@fcfe0000 {
- #clock-cells = <1>;
- compatible = "renesas,r7s72100-cpg-clocks",
- "renesas,rz-cpg-clocks";
- reg = <0xfcfe0000 0x18>;
- clocks = <&extal_clk>, <&usb_x1_clk>;
- clock-output-names = "pll", "i", "g";
- #power-domain-cells = <0>;
- };
-
-
- - CPG/MSTP Clock Domain member device node:
-
- mtu2: timer@fcff0000 {
- compatible = "renesas,mtu2-r7s72100", "renesas,mtu2";
- reg = <0xfcff0000 0x400>;
- interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "tgi0a";
- clocks = <&mstp3_clks R7S72100_CLK_MTU2>;
- clock-names = "fck";
- power-domains = <&cpg_clocks>;
- };
diff --git a/Documentation/devicetree/bindings/clock/renesas,sh73a0-cpg-clocks.txt b/Documentation/devicetree/bindings/clock/renesas,sh73a0-cpg-clocks.txt
deleted file mode 100644
index a8978ec94831..000000000000
--- a/Documentation/devicetree/bindings/clock/renesas,sh73a0-cpg-clocks.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-These bindings should be considered EXPERIMENTAL for now.
-
-* Renesas SH73A0 Clock Pulse Generator (CPG)
-
-The CPG generates core clocks for the SH73A0 SoC. It includes four PLLs
-and several fixed ratio dividers.
-
-Required Properties:
-
- - compatible: Must be "renesas,sh73a0-cpg-clocks"
-
- - reg: Base address and length of the memory resource used by the CPG
-
- - clocks: Reference to the parent clocks ("extal1" and "extal2")
-
- - #clock-cells: Must be 1
-
- - clock-output-names: The names of the clocks. Supported clocks are "main",
- "pll0", "pll1", "pll2", "pll3", "dsi0phy", "dsi1phy", "zg", "m3", "b",
- "m1", "m2", "z", "zx", and "hp".
-
-
-Example
--------
-
- cpg_clocks: cpg_clocks@e6150000 {
- compatible = "renesas,sh73a0-cpg-clocks";
- reg = <0 0xe6150000 0 0x10000>;
- clocks = <&extal1_clk>, <&extal2_clk>;
- #clock-cells = <1>;
- clock-output-names = "main", "pll0", "pll1", "pll2",
- "pll3", "dsi0phy", "dsi1phy",
- "zg", "m3", "b", "m1", "m2",
- "z", "zx", "hp";
- };
diff --git a/Documentation/devicetree/bindings/clock/rockchip,rk3288-cru.txt b/Documentation/devicetree/bindings/clock/rockchip,rk3288-cru.txt
index 8cb47c39ba53..bf3a9ec19241 100644
--- a/Documentation/devicetree/bindings/clock/rockchip,rk3288-cru.txt
+++ b/Documentation/devicetree/bindings/clock/rockchip,rk3288-cru.txt
@@ -4,9 +4,15 @@ The RK3288 clock controller generates and supplies clock to various
controllers within the SoC and also implements a reset controller for SoC
peripherals.
+A revision of this SoC is available: rk3288w. The clock tree is a bit
+different so another dt-compatible is available. Noticed that it is only
+setting the difference but there is no automatic revision detection. This
+should be performed by bootloaders.
+
Required Properties:
-- compatible: should be "rockchip,rk3288-cru"
+- compatible: should be "rockchip,rk3288-cru" or "rockchip,rk3288w-cru" in
+ case of this revision of Rockchip rk3288.
- reg: physical base address of the controller and length of memory mapped
region.
- #clock-cells: should be 1.
diff --git a/Documentation/devicetree/bindings/clock/silabs,si514.txt b/Documentation/devicetree/bindings/clock/silabs,si514.txt
index ea1a9dbc63b6..a4f28ec86f35 100644
--- a/Documentation/devicetree/bindings/clock/silabs,si514.txt
+++ b/Documentation/devicetree/bindings/clock/silabs,si514.txt
@@ -6,7 +6,7 @@ found in the datasheet[2].
[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
[2] Si514 datasheet
- http://www.silabs.com/Support%20Documents/TechnicalDocs/si514.pdf
+ https://www.silabs.com/Support%20Documents/TechnicalDocs/si514.pdf
Required properties:
- compatible: Shall be "silabs,si514"
diff --git a/Documentation/devicetree/bindings/clock/silabs,si5351.txt b/Documentation/devicetree/bindings/clock/silabs,si5351.txt
index f00191cad8cd..8fe6f80afade 100644
--- a/Documentation/devicetree/bindings/clock/silabs,si5351.txt
+++ b/Documentation/devicetree/bindings/clock/silabs,si5351.txt
@@ -2,7 +2,7 @@ Binding for Silicon Labs Si5351a/b/c programmable i2c clock generator.
Reference
[1] Si5351A/B/C Data Sheet
- http://www.silabs.com/Support%20Documents/TechnicalDocs/Si5351.pdf
+ https://www.silabs.com/Support%20Documents/TechnicalDocs/Si5351.pdf
The Si5351a/b/c are programmable i2c clock generators with up to 8 output
clocks. Si5351a also has a reduced pin-count package (MSOP10) where only
diff --git a/Documentation/devicetree/bindings/clock/silabs,si570.txt b/Documentation/devicetree/bindings/clock/silabs,si570.txt
index c09f21e1d98f..901935e929d2 100644
--- a/Documentation/devicetree/bindings/clock/silabs,si570.txt
+++ b/Documentation/devicetree/bindings/clock/silabs,si570.txt
@@ -7,9 +7,9 @@ found in the data sheets[2][3].
[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
[2] Si570/571 Data Sheet
- http://www.silabs.com/Support%20Documents/TechnicalDocs/si570.pdf
+ https://www.silabs.com/Support%20Documents/TechnicalDocs/si570.pdf
[3] Si598/599 Data Sheet
- http://www.silabs.com/Support%20Documents/TechnicalDocs/si598-99.pdf
+ https://www.silabs.com/Support%20Documents/TechnicalDocs/si598-99.pdf
Required properties:
- compatible: Shall be one of "silabs,si570", "silabs,si571",
diff --git a/Documentation/devicetree/bindings/clock/ti,cdce706.txt b/Documentation/devicetree/bindings/clock/ti,cdce706.txt
index 959d96632f5d..21c3ff764788 100644
--- a/Documentation/devicetree/bindings/clock/ti,cdce706.txt
+++ b/Documentation/devicetree/bindings/clock/ti,cdce706.txt
@@ -1,7 +1,7 @@
Bindings for Texas Instruments CDCE706 programmable 3-PLL clock
synthesizer/multiplier/divider.
-Reference: http://www.ti.com/lit/ds/symlink/cdce706.pdf
+Reference: https://www.ti.com/lit/ds/symlink/cdce706.pdf
I2C device node required properties:
- compatible: shall be "ti,cdce706".
diff --git a/Documentation/devicetree/bindings/clock/ti,cdce925.txt b/Documentation/devicetree/bindings/clock/ti,cdce925.txt
index 26544c85202a..df42ab72718f 100644
--- a/Documentation/devicetree/bindings/clock/ti,cdce925.txt
+++ b/Documentation/devicetree/bindings/clock/ti,cdce925.txt
@@ -4,10 +4,10 @@ Reference
This binding uses the common clock binding[1].
[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
-[2] http://www.ti.com/product/cdce913
-[3] http://www.ti.com/product/cdce925
-[4] http://www.ti.com/product/cdce937
-[5] http://www.ti.com/product/cdce949
+[2] https://www.ti.com/product/cdce913
+[3] https://www.ti.com/product/cdce925
+[4] https://www.ti.com/product/cdce937
+[5] https://www.ti.com/product/cdce949
The driver provides clock sources for each output Y1 through Y5.
diff --git a/MAINTAINERS b/MAINTAINERS
index 68f21d46614c..344564ae0134 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1533,6 +1533,7 @@ F: drivers/mmc/host/owl-mmc.c
F: drivers/pinctrl/actions/*
F: drivers/soc/actions/
F: include/dt-bindings/power/owl-*
+F: include/dt-bindings/reset/actions,*
F: include/linux/soc/actions/
N: owl
@@ -8324,8 +8325,9 @@ W: https://github.com/o2genum/ideapad-slidebar
F: drivers/input/misc/ideapad_slidebar.c
IDT VersaClock 5 CLOCK DRIVER
-M: Marek Vasut <marek.vasut@gmail.com>
+M: Luca Ceresoli <luca@lucaceresoli.net>
S: Maintained
+F: Documentation/devicetree/bindings/clock/idt,versaclock5.yaml
F: drivers/clk/clk-versaclock5.c
IEEE 802.15.4 SUBSYSTEM
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 69934c0c3dd8..4026fac9fac3 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -50,6 +50,7 @@ source "drivers/clk/versatile/Kconfig"
config CLK_HSDK
bool "PLL Driver for HSDK platform"
depends on OF || COMPILE_TEST
+ depends on HAS_IOMEM
help
This driver supports the HSDK core, system, ddr, tunnel and hdmi PLLs
control.
@@ -120,7 +121,6 @@ config COMMON_CLK_SI5351
tristate "Clock driver for SiLabs 5351A/B/C"
depends on I2C
select REGMAP_I2C
- select RATIONAL
help
This driver supports Silicon Labs 5351A/B/C programmable clock
generators.
@@ -162,7 +162,6 @@ config COMMON_CLK_CDCE706
tristate "Clock driver for TI CDCE706 clock synthesizer"
depends on I2C
select REGMAP_I2C
- select RATIONAL
help
This driver supports TI CDCE706 programmable 3-PLL clock synthesizer.
diff --git a/drivers/clk/actions/owl-s500.c b/drivers/clk/actions/owl-s500.c
index e2007ac4d235..61bb224f6330 100644
--- a/drivers/clk/actions/owl-s500.c
+++ b/drivers/clk/actions/owl-s500.c
@@ -23,8 +23,10 @@
#include "owl-gate.h"
#include "owl-mux.h"
#include "owl-pll.h"
+#include "owl-reset.h"
#include <dt-bindings/clock/actions,s500-cmu.h>
+#include <dt-bindings/reset/actions,s500-reset.h>
#define CMU_COREPLL (0x0000)
#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
static OWL_MUX(ahbprediv_clk, "ahbprediv_clk", ahbprediv_clk_mux_p, CMU_BUSCLK1, 8, 3, CLK_SET_RATE_PARENT);
/* gate clocks */
+static OWL_GATE(gpio_clk, "gpio_clk", "apb_clk", CMU_DEVCLKEN0, 18, 0, 0);
+static OWL_GATE(dmac_clk, "dmac_clk", "h_clk", CMU_DEVCLKEN0, 1, 0, 0);
static OWL_GATE(spi0_clk, "spi0_clk", "ahb_clk", CMU_DEVCLKEN1, 10, 0, CLK_IGNORE_UNUSED);
static OWL_GATE(spi1_clk, "spi1_clk", "ahb_clk", CMU_DEVCLKEN1, 11, 0, CLK_IGNORE_UNUSED);
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);
static OWL_GATE(hdmi_clk, "hdmi_clk", "hosc", CMU_DEVCLKEN1, 3, 0, 0);
/* divider clocks */
-static OWL_DIVIDER(h_clk, "h_clk", "ahbprevdiv_clk", CMU_BUSCLK1, 12, 2, NULL, 0, 0);
+static OWL_DIVIDER(h_clk, "h_clk", "ahbprediv_clk", CMU_BUSCLK1, 12, 2, NULL, 0, 0);
+static OWL_DIVIDER(apb_clk, "apb_clk", "ahb_clk", CMU_BUSCLK1, 14, 2, NULL, 0, 0);
static OWL_DIVIDER(rmii_ref_clk, "rmii_ref_clk", "ethernet_pll_clk", CMU_ETHERNETPLL, 1, 1, rmii_ref_div_table, 0, 0);
/* factor clocks */
@@ -428,6 +433,9 @@ static struct owl_clk_common *s500_clks[] = {
&spdif_clk.common,
&nand_clk.common,
&ecc_clk.common,
+ &apb_clk.common,
+ &dmac_clk.common,
+ &gpio_clk.common,
};
static struct clk_hw_onecell_data s500_hw_clks = {
@@ -484,24 +492,103 @@ static struct clk_hw_onecell_data s500_hw_clks = {
[CLK_SPDIF] = &spdif_clk.common.hw,
[CLK_NAND] = &nand_clk.common.hw,
[CLK_ECC] = &ecc_clk.common.hw,
+ [CLK_APB] = &apb_clk.common.hw,
+ [CLK_DMAC] = &dmac_clk.common.hw,
+ [CLK_GPIO] = &gpio_clk.common.hw,
},
.num = CLK_NR_CLKS,
};
+static const struct owl_reset_map s500_resets[] = {
+ [RESET_DMAC] = { CMU_DEVRST0, BIT(0) },
+ [RESET_NORIF] = { CMU_DEVRST0, BIT(1) },
+ [RESET_DDR] = { CMU_DEVRST0, BIT(2) },
+ [RESET_NANDC] = { CMU_DEVRST0, BIT(3) },
+ [RESET_SD0] = { CMU_DEVRST0, BIT(4) },
+ [RESET_SD1] = { CMU_DEVRST0, BIT(5) },
+ [RESET_PCM1] = { CMU_DEVRST0, BIT(6) },
+ [RESET_DE] = { CMU_DEVRST0, BIT(7) },
+ [RESET_LCD] = { CMU_DEVRST0, BIT(8) },
+ [RESET_SD2] = { CMU_DEVRST0, BIT(9) },
+ [RESET_DSI] = { CMU_DEVRST0, BIT(10) },
+ [RESET_CSI] = { CMU_DEVRST0, BIT(11) },
+ [RESET_BISP] = { CMU_DEVRST0, BIT(12) },
+ [RESET_KEY] = { CMU_DEVRST0, BIT(14) },
+ [RESET_GPIO] = { CMU_DEVRST0, BIT(15) },
+ [RESET_AUDIO] = { CMU_DEVRST0, BIT(17) },
+ [RESET_PCM0] = { CMU_DEVRST0, BIT(18) },
+ [RESET_VDE] = { CMU_DEVRST0, BIT(19) },
+ [RESET_VCE] = { CMU_DEVRST0, BIT(20) },
+ [RESET_GPU3D] = { CMU_DEVRST0, BIT(22) },
+ [RESET_NIC301] = { CMU_DEVRST0, BIT(23) },
+ [RESET_LENS] = { CMU_DEVRST0, BIT(26) },
+ [RESET_PERIPHRESET] = { CMU_DEVRST0, BIT(27) },
+ [RESET_USB2_0] = { CMU_DEVRST1, BIT(0) },
+ [RESET_TVOUT] = { CMU_DEVRST1, BIT(1) },
+ [RESET_HDMI] = { CMU_DEVRST1, BIT(2) },
+ [RESET_HDCP2TX] = { CMU_DEVRST1, BIT(3) },
+ [RESET_UART6] = { CMU_DEVRST1, BIT(4) },
+ [RESET_UART0] = { CMU_DEVRST1, BIT(5) },
+ [RESET_UART1] = { CMU_DEVRST1, BIT(6) },
+ [RESET_UART2] = { CMU_DEVRST1, BIT(7) },
+ [RESET_SPI0] = { CMU_DEVRST1, BIT(8) },
+ [RESET_SPI1] = { CMU_DEVRST1, BIT(9) },
+ [RESET_SPI2] = { CMU_DEVRST1, BIT(10) },
+ [RESET_SPI3] = { CMU_DEVRST1, BIT(11) },
+ [RESET_I2C0] = { CMU_DEVRST1, BIT(12) },
+ [RESET_I2C1] = { CMU_DEVRST1, BIT(13) },
+ [RESET_USB3] = { CMU_DEVRST1, BIT(14) },
+ [RESET_UART3] = { CMU_DEVRST1, BIT(15) },
+ [RESET_UART4] = { CMU_DEVRST1, BIT(16) },
+ [RESET_UART5] = { CMU_DEVRST1, BIT(17) },
+ [RESET_I2C2] = { CMU_DEVRST1, BIT(18) },
+ [RESET_I2C3] = { CMU_DEVRST1, BIT(19) },
+ [RESET_ETHERNET] = { CMU_DEVRST1, BIT(20) },
+ [RESET_CHIPID] = { CMU_DEVRST1, BIT(21) },
+ [RESET_USB2_1] = { CMU_DEVRST1, BIT(22) },
+ [RESET_WD0RESET] = { CMU_DEVRST1, BIT(24) },
+ [RESET_WD1RESET] = { CMU_DEVRST1, BIT(25) },
+ [RESET_WD2RESET] = { CMU_DEVRST1, BIT(26) },
+ [RESET_WD3RESET] = { CMU_DEVRST1, BIT(27) },
+ [RESET_DBG0RESET] = { CMU_DEVRST1, BIT(28) },
+ [RESET_DBG1RESET] = { CMU_DEVRST1, BIT(29) },
+ [RESET_DBG2RESET] = { CMU_DEVRST1, BIT(30) },
+ [RESET_DBG3RESET] = { CMU_DEVRST1, BIT(31) },
+};
+
static struct owl_clk_desc s500_clk_desc = {
.clks = s500_clks,
.num_clks = ARRAY_SIZE(s500_clks),
.hw_clks = &s500_hw_clks,
+
+ .resets = s500_resets,
+ .num_resets = ARRAY_SIZE(s500_resets),
};
static int s500_clk_probe(struct platform_device *pdev)
{
struct owl_clk_desc *desc;
+ struct owl_reset *reset;
+ int ret;
desc = &s500_clk_desc;
owl_clk_regmap_init(pdev, desc);
+ reset = devm_kzalloc(&pdev->dev, sizeof(*reset), GFP_KERNEL);
+ if (!reset)
+ return -ENOMEM;
+
+ reset->rcdev.of_node = pdev->dev.of_node;
+ reset->rcdev.ops = &owl_reset_ops;
+ reset->rcdev.nr_resets = desc->num_resets;
+ reset->reset_map = desc->resets;
+ reset->regmap = desc->regmap;
+
+ ret = devm_reset_controller_register(&pdev->dev, &reset->rcdev);
+ if (ret)
+ dev_err(&pdev->dev, "Failed to register reset controller\n");
+
return owl_clk_probe(&pdev->dev, desc->hw_clks);
}
diff --git a/drivers/clk/bcm/Kconfig b/drivers/clk/bcm/Kconfig
index 8c83977a7dc4..784f12c72365 100644
--- a/drivers/clk/bcm/Kconfig
+++ b/drivers/clk/bcm/Kconfig
@@ -1,4 +1,15 @@
# SPDX-License-Identifier: GPL-2.0-only
+
+config CLK_BCM2711_DVP
+ tristate "Broadcom BCM2711 DVP support"
+ depends on ARCH_BCM2835 ||COMPILE_TEST
+ depends on COMMON_CLK
+ default ARCH_BCM2835
+ select RESET_SIMPLE
+ help
+ Enable common clock framework support for the Broadcom BCM2711
+ DVP Controller.
+
config CLK_BCM2835
bool "Broadcom BCM2835 clock support"
depends on ARCH_BCM2835 || ARCH_BRCMSTB || COMPILE_TEST
diff --git a/drivers/clk/bcm/Makefile b/drivers/clk/bcm/Makefile
index 0070ddf6cdd2..edb66b44cb27 100644
--- a/drivers/clk/bcm/Makefile
+++ b/drivers/clk/bcm/Makefile
@@ -6,6 +6,7 @@ obj-$(CONFIG_CLK_BCM_KONA) += clk-kona-setup.o
obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm281xx.o
obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm21664.o
obj-$(CONFIG_COMMON_CLK_IPROC) += clk-iproc-armpll.o clk-iproc-pll.o clk-iproc-asiu.o
+obj-$(CONFIG_CLK_BCM2711_DVP) += clk-bcm2711-dvp.o
obj-$(CONFIG_CLK_BCM2835) += clk-bcm2835.o
obj-$(CONFIG_CLK_BCM2835) += clk-bcm2835-aux.o
obj-$(CONFIG_CLK_RASPBERRYPI) += clk-raspberrypi.o
diff --git a/drivers/clk/bcm/clk-bcm2711-dvp.c b/drivers/clk/bcm/clk-bcm2711-dvp.c
new file mode 100644
index 000000000000..8333e20dc9d2
--- /dev/null
+++ b/drivers/clk/bcm/clk-bcm2711-dvp.c
@@ -0,0 +1,124 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+// Copyright 2020 Cerno
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/reset-controller.h>
+#include <linux/reset/reset-simple.h>
+
+#define DVP_HT_RPI_SW_INIT 0x04
+#define DVP_HT_RPI_MISC_CONFIG 0x08
+
+#define NR_CLOCKS 2
+#define NR_RESETS 6
+
+struct clk_dvp {
+ struct clk_hw_onecell_data *data;
+ struct reset_simple_data reset;
+};
+
+static const struct clk_parent_data clk_dvp_parent = {
+ .index = 0,
+};
+
+static int clk_dvp_probe(struct platform_device *pdev)
+{
+ struct clk_hw_onecell_data *data;
+ struct resource *res;
+ struct clk_dvp *dvp;
+ void __iomem *base;
+ int ret;
+
+ dvp = devm_kzalloc(&pdev->dev, sizeof(*dvp), GFP_KERNEL);
+ if (!dvp)
+ return -ENOMEM;
+ platform_set_drvdata(pdev, dvp);
+
+ dvp->data = devm_kzalloc(&pdev->dev,
+ struct_size(dvp->data, hws, NR_CLOCKS),
+ GFP_KERNEL);
+ if (!dvp->data)
+ return -ENOMEM;
+ data = dvp->data;
+
+ base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+
+ dvp->reset.rcdev.owner = THIS_MODULE;
+ dvp->reset.rcdev.nr_resets = NR_RESETS;
+ dvp->reset.rcdev.ops = &reset_simple_ops;
+ dvp->reset.rcdev.of_node = pdev->dev.of_node;
+ dvp->reset.membase = base + DVP_HT_RPI_SW_INIT;
+ spin_lock_init(&dvp->reset.lock);
+
+ ret = devm_reset_controller_register(&pdev->dev, &dvp->reset.rcdev);
+ if (ret)
+ return ret;
+
+ data->hws[0] = clk_hw_register_gate_parent_data(&pdev->dev,
+ "hdmi0-108MHz",
+ &clk_dvp_parent, 0,
+ base + DVP_HT_RPI_MISC_CONFIG, 3,
+ CLK_GATE_SET_TO_DISABLE,
+ &dvp->reset.lock);
+ if (IS_ERR(data->hws[0]))
+ return PTR_ERR(data->hws[0]);
+
+ data->hws[1] = clk_hw_register_gate_parent_data(&pdev->dev,
+ "hdmi1-108MHz",
+ &clk_dvp_parent, 0,
+ base + DVP_HT_RPI_MISC_CONFIG, 4,
+ CLK_GATE_SET_TO_DISABLE,
+ &dvp->reset.lock);
+ if (IS_ERR(data->hws[1])) {
+ ret = PTR_ERR(data->hws[1]);
+ goto unregister_clk0;
+ }
+
+ data->num = NR_CLOCKS;
+ ret = of_clk_add_hw_provider(pdev->dev.of_node, of_clk_hw_onecell_get,
+ data);
+ if (ret)
+ goto unregister_clk1;
+
+ return 0;
+
+unregister_clk1:
+ clk_hw_unregister_gate(data->hws[1]);
+
+unregister_clk0:
+ clk_hw_unregister_gate(data->hws[0]);
+ return ret;
+};
+
+static int clk_dvp_remove(struct platform_device *pdev)
+{
+ struct clk_dvp *dvp = platform_get_drvdata(pdev);
+ struct clk_hw_onecell_data *data = dvp->data;
+
+ clk_hw_unregister_gate(data->hws[1]);
+ clk_hw_unregister_gate(data->hws[0]);
+
+ return 0;
+}
+
+static const struct of_device_id clk_dvp_dt_ids[] = {
+ { .compatible = "brcm,brcm2711-dvp", },
+ { /* sentinel */ }
+};
+
+static struct platform_driver clk_dvp_driver = {
+ .probe = clk_dvp_probe,
+ .remove = clk_dvp_remove,
+ .driver = {
+ .name = "brcm2711-dvp",
+ .of_match_table = clk_dvp_dt_ids,
+ },
+};
+module_platform_driver(clk_dvp_driver);
+
+MODULE_AUTHOR("Maxime Ripard <maxime@cerno.tech>");
+MODULE_DESCRIPTION("BCM2711 DVP clock driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
index 6bb7efa12037..3439bc65bb4e 100644
--- a/drivers/clk/bcm/clk-bcm2835.c
+++ b/drivers/clk/bcm/clk-bcm2835.c
@@ -314,6 +314,7 @@ struct bcm2835_cprman {
struct device *dev;
void __iomem *regs;
spinlock_t regs_lock; /* spinlock for all clocks */
+ unsigned int soc;
/*
* Real names of cprman clock parents looked up through
@@ -421,6 +422,7 @@ struct bcm2835_pll_data {
u32 reference_enable_mask;
/* Bit in CM_LOCK to indicate when the PLL has locked. */
u32 lock_mask;
+ u32 flags;
const struct bcm2835_pll_ana_bits *ana;
@@ -525,6 +527,20 @@ static int bcm2835_pll_is_on(struct clk_hw *hw)
A2W_PLL_CTRL_PRST_DISABLE;
}
+static u32 bcm2835_pll_get_prediv_mask(struct bcm2835_cprman *cprman,
+ const struct bcm2835_pll_data *data)
+{
+ /*
+ * On BCM2711 there isn't a pre-divisor available in the PLL feedback
+ * loop. Bits 13:14 of ANA1 (PLLA,PLLB,PLLC,PLLD) have been re-purposed
+ * for to for VCO RANGE bits.
+ */
+ if (cprman->soc & SOC_BCM2711)
+ return 0;
+
+ return data->ana->fb_prediv_mask;
+}
+
static void bcm2835_pll_choose_ndiv_and_fdiv(unsigned long rate,
unsigned long parent_rate,
u32 *ndiv, u32 *fdiv)
@@ -582,7 +598,7 @@ static unsigned long bcm2835_pll_get_rate(struct clk_hw *hw,
ndiv = (a2wctrl & A2W_PLL_CTRL_NDIV_MASK) >> A2W_PLL_CTRL_NDIV_SHIFT;
pdiv = (a2wctrl & A2W_PLL_CTRL_PDIV_MASK) >> A2W_PLL_CTRL_PDIV_SHIFT;
using_prediv = cprman_read(cprman, data->ana_reg_base + 4) &
- data->ana->fb_prediv_mask;
+ bcm2835_pll_get_prediv_mask(cprman, data);
if (using_prediv) {
ndiv *= 2;
@@ -665,6 +681,7 @@ static int bcm2835_pll_set_rate(struct clk_hw *hw,
struct bcm2835_pll *pll = container_of(hw, struct bcm2835_pll, hw);
struct bcm2835_cprman *cprman = pll->cprman;
const struct bcm2835_pll_data *data = pll->data;
+ u32 prediv_mask = bcm2835_pll_get_prediv_mask(cprman, data);
bool was_using_prediv, use_fb_prediv, do_ana_setup_first;
u32 ndiv, fdiv, a2w_ctl;
u32 ana[4];
@@ -682,7 +699,7 @@ static int bcm2835_pll_set_rate(struct clk_hw *hw,
for (i = 3; i >= 0; i--)
ana[i] = cprman_read(cprman, data->ana_reg_base + i * 4);
- was_using_prediv = ana[1] & data->ana->fb_prediv_mask;
+ was_using_prediv = ana[1] & prediv_mask;
ana[0] &= ~data->ana->mask0;
ana[0] |= data->ana->set0;
@@ -692,10 +709,10 @@ static int bcm2835_pll_set_rate(struct clk_hw *hw,
ana[3] |= data->ana->set3;
if (was_using_prediv && !use_fb_prediv) {
- ana[1] &= ~data->ana->fb_prediv_mask;
+ ana[1] &= ~prediv_mask;
do_ana_setup_first = true;
} else if (!was_using_prediv && use_fb_prediv) {
- ana[1] |= data->ana->fb_prediv_mask;
+ ana[1] |= prediv_mask;
do_ana_setup_first = false;
} else {
do_ana_setup_first = true;
@@ -1310,7 +1327,7 @@ static struct clk_hw *bcm2835_register_pll(struct bcm2835_cprman *cprman,
init.num_parents = 1;
init.name = pll_data->name;
init.ops = &bcm2835_pll_clk_ops;
- init.flags = CLK_IGNORE_UNUSED;
+ init.flags = pll_data->flags | CLK_IGNORE_UNUSED;
pll = kzalloc(sizeof(*pll), GFP_KERNEL);
if (!pll)
@@ -1684,10 +1701,33 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.fixed_divider = 1,
.flags = CLK_SET_RATE_PARENT),
- /*
- * PLLB is used for the ARM's clock. Controlled by firmware, see
- * clk-raspberrypi.c.
- */
+ /* PLLB is used for the ARM's clock. */
+ [BCM2835_PLLB] = REGISTER_PLL(
+ SOC_ALL,
+ .name = "pllb",
+ .cm_ctrl_reg = CM_PLLB,
+ .a2w_ctrl_reg = A2W_PLLB_CTRL,
+ .frac_reg = A2W_PLLB_FRAC,
+ .ana_reg_base = A2W_PLLB_ANA0,
+ .reference_enable_mask = A2W_XOSC_CTRL_PLLB_ENABLE,
+ .lock_mask = CM_LOCK_FLOCKB,
+
+ .ana = &bcm2835_ana_default,
+
+ .min_rate = 600000000u,
+ .max_rate = 3000000000u,
+ .max_fb_rate = BCM2835_MAX_FB_RATE,
+ .flags = CLK_GET_RATE_NOCACHE),
+ [BCM2835_PLLB_ARM] = REGISTER_PLL_DIV(
+ SOC_ALL,
+ .name = "pllb_arm",
+ .source_pll = "pllb",
+ .cm_reg = CM_PLLB,
+ .a2w_reg = A2W_PLLB_ARM,
+ .load_mask = CM_PLLB_LOADARM,
+ .hold_mask = CM_PLLB_HOLDARM,
+ .fixed_divider = 1,
+ .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE),
/*
* PLLC is the core PLL, used to drive the core VPU clock.
@@ -2238,6 +2278,7 @@ static int bcm2835_clk_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, cprman);
cprman->onecell.num = asize;
+ cprman->soc = pdata->soc;
hws = cprman->onecell.hws;
for (i = 0; i < asize; i++) {
diff --git a/drivers/clk/bcm/clk-bcm63xx-gate.c b/drivers/clk/bcm/clk-bcm63xx-gate.c
index 98e884957db8..89297c57881e 100644
--- a/drivers/clk/bcm/clk-bcm63xx-gate.c
+++ b/drivers/clk/bcm/clk-bcm63xx-gate.c
@@ -6,6 +6,14 @@
#include <linux/of_device.h>
#include <linux/platform_device.h>
+#include <dt-bindings/clock/bcm3368-clock.h>
+#include <dt-bindings/clock/bcm6318-clock.h>
+#include <dt-bindings/clock/bcm6328-clock.h>
+#include <dt-bindings/clock/bcm6358-clock.h>
+#include <dt-bindings/clock/bcm6362-clock.h>
+#include <dt-bindings/clock/bcm6368-clock.h>
+#include <dt-bindings/clock/bcm63268-clock.h>
+
struct clk_bcm63xx_table_entry {
const char * const name;
u8 bit;
@@ -20,126 +28,458 @@ struct clk_bcm63xx_hw {
};
static const struct clk_bcm63xx_table_entry bcm3368_clocks[] = {
- { .name = "mac", .bit = 3, },
- { .name = "tc", .bit = 5, },
- { .name = "us_top", .bit = 6, },
- { .name = "ds_top", .bit = 7, },
- { .name = "acm", .bit = 8, },
- { .name = "spi", .bit = 9, },
- { .name = "usbs", .bit = 10, },
- { .name = "bmu", .bit = 11, },
- { .name = "pcm", .bit = 12, },
- { .name = "ntp", .bit = 13, },
- { .name = "acp_b", .bit = 14, },
- { .name = "acp_a", .bit = 15, },
- { .name = "emusb", .bit = 17, },
- { .name = "enet0", .bit = 18, },
- { .name = "enet1", .bit = 19, },
- { .name = "usbsu", .bit = 20, },
- { .name = "ephy", .bit = 21, },
- { },
+ {
+ .name = "mac",
+ .bit = BCM3368_CLK_MAC,
+ }, {
+ .name = "tc",
+ .bit = BCM3368_CLK_TC,
+ }, {
+ .name = "us_top",
+ .bit = BCM3368_CLK_US_TOP,
+ }, {
+ .name = "ds_top",
+ .bit = BCM3368_CLK_DS_TOP,
+ }, {
+ .name = "acm",
+ .bit = BCM3368_CLK_ACM,
+ }, {
+ .name = "spi",
+ .bit = BCM3368_CLK_SPI,
+ }, {
+ .name = "usbs",
+ .bit = BCM3368_CLK_USBS,
+ }, {
+ .name = "bmu",
+ .bit = BCM3368_CLK_BMU,
+ }, {
+ .name = "pcm",
+ .bit = BCM3368_CLK_PCM,
+ }, {
+ .name = "ntp",
+ .bit = BCM3368_CLK_NTP,
+ }, {
+ .name = "acp_b",
+ .bit = BCM3368_CLK_ACP_B,
+ }, {
+ .name = "acp_a",
+ .bit = BCM3368_CLK_ACP_A,
+ }, {
+ .name = "emusb",
+ .bit = BCM3368_CLK_EMUSB,
+ }, {
+ .name = "enet0",
+ .bit = BCM3368_CLK_ENET0,
+ }, {
+ .name = "enet1",
+ .bit = BCM3368_CLK_ENET1,
+ }, {
+ .name = "usbsu",
+ .bit = BCM3368_CLK_USBSU,
+ }, {
+ .name = "ephy",
+ .bit = BCM3368_CLK_EPHY,
+ }, {
+ /* sentinel */
+ },
+};
+
+static const struct clk_bcm63xx_table_entry bcm6318_clocks[] = {
+ {
+ .name = "adsl_asb",
+ .bit = BCM6318_CLK_ADSL_ASB,
+ }, {
+ .name = "usb_asb",
+ .bit = BCM6318_CLK_USB_ASB,
+ }, {
+ .name = "mips_asb",
+ .bit = BCM6318_CLK_MIPS_ASB,
+ }, {
+ .name = "pcie_asb",
+ .bit = BCM6318_CLK_PCIE_ASB,
+ }, {
+ .name = "phymips_asb",
+ .bit = BCM6318_CLK_PHYMIPS_ASB,
+ }, {
+ .name = "robosw_asb",
+ .bit = BCM6318_CLK_ROBOSW_ASB,
+ }, {
+ .name = "sar_asb",
+ .bit = BCM6318_CLK_SAR_ASB,
+ }, {
+ .name = "sdr_asb",
+ .bit = BCM6318_CLK_SDR_ASB,
+ }, {
+ .name = "swreg_asb",
+ .bit = BCM6318_CLK_SWREG_ASB,
+ }, {
+ .name = "periph_asb",
+ .bit = BCM6318_CLK_PERIPH_ASB,
+ }, {
+ .name = "cpubus160",
+ .bit = BCM6318_CLK_CPUBUS160,
+ }, {
+ .name = "adsl",
+ .bit = BCM6318_CLK_ADSL,
+ }, {
+ .name = "sar125",
+ .bit = BCM6318_CLK_SAR125,
+ }, {
+ .name = "mips",
+ .bit = BCM6318_CLK_MIPS,
+ .flags = CLK_IS_CRITICAL,
+ }, {
+ .name = "pcie",
+ .bit = BCM6318_CLK_PCIE,
+ }, {
+ .name = "robosw250",
+ .bit = BCM6318_CLK_ROBOSW250,
+ }, {
+ .name = "robosw025",
+ .bit = BCM6318_CLK_ROBOSW025,
+ }, {
+ .name = "sdr",
+ .bit = BCM6318_CLK_SDR,
+ .flags = CLK_IS_CRITICAL,
+ }, {
+ .name = "usbd",
+ .bit = BCM6318_CLK_USBD,
+ }, {
+ .name = "hsspi",
+ .bit = BCM6318_CLK_HSSPI,
+ }, {
+ .name = "pcie25",
+ .bit = BCM6318_CLK_PCIE25,
+ }, {
+ .name = "phymips",
+ .bit = BCM6318_CLK_PHYMIPS,
+ }, {
+ .name = "afe",
+ .bit = BCM6318_CLK_AFE,
+ }, {
+ .name = "qproc",
+ .bit = BCM6318_CLK_QPROC,
+ }, {
+ /* sentinel */
+ },
+};
+
+static const struct clk_bcm63xx_table_entry bcm6318_ubus_clocks[] = {
+ {
+ .name = "adsl-ubus",
+ .bit = BCM6318_UCLK_ADSL,
+ }, {
+ .name = "arb-ubus",
+ .bit = BCM6318_UCLK_ARB,
+ .flags = CLK_IS_CRITICAL,
+ }, {
+ .name = "mips-ubus",
+ .bit = BCM6318_UCLK_MIPS,
+ .flags = CLK_IS_CRITICAL,
+ }, {
+ .name = "pcie-ubus",
+ .bit = BCM6318_UCLK_PCIE,
+ }, {
+ .name = "periph-ubus",
+ .bit = BCM6318_UCLK_PERIPH,
+ .flags = CLK_IS_CRITICAL,
+ }, {
+ .name = "phymips-ubus",
+ .bit = BCM6318_UCLK_PHYMIPS,
+ }, {
+ .name = "robosw-ubus",
+ .bit = BCM6318_UCLK_ROBOSW,
+ }, {
+ .name = "sar-ubus",
+ .bit = BCM6318_UCLK_SAR,
+ }, {
+ .name = "sdr-ubus",
+ .bit = BCM6318_UCLK_SDR,
+ }, {
+ .name = "usb-ubus",
+ .bit = BCM6318_UCLK_USB,
+ }, {
+ /* sentinel */
+ },
};
static const struct clk_bcm63xx_table_entry bcm6328_clocks[] = {
- { .name = "phy_mips", .bit = 0, },
- { .name = "adsl_qproc", .bit = 1, },
- { .name = "adsl_afe", .bit = 2, },
- { .name = "adsl", .bit = 3, },
- { .name = "mips", .bit = 4, .flags = CLK_IS_CRITICAL, },
- { .name = "sar", .bit = 5, },
- { .name = "pcm", .bit = 6, },
- { .name = "usbd", .bit = 7, },
- { .name = "usbh", .bit = 8, },
- { .name = "hsspi", .bit = 9, },
- { .name = "pcie", .bit = 10, },
- { .name = "robosw", .bit = 11, },
- { },
+ {
+ .name = "phy_mips",
+ .bit = BCM6328_CLK_PHYMIPS,
+ }, {
+ .name = "adsl_qproc",
+ .bit = BCM6328_CLK_ADSL_QPROC,
+ }, {
+ .name = "adsl_afe",
+ .bit = BCM6328_CLK_ADSL_AFE,
+ }, {
+ .name = "adsl",
+ .bit = BCM6328_CLK_ADSL,
+ }, {
+ .name = "mips",
+ .bit = BCM6328_CLK_MIPS,
+ .flags = CLK_IS_CRITICAL,
+ }, {
+ .name = "sar",
+ .bit = BCM6328_CLK_SAR,
+ }, {
+ .name = "pcm",
+ .bit = BCM6328_CLK_PCM,
+ }, {
+ .name = "usbd",
+ .bit = BCM6328_CLK_USBD,
+ }, {
+ .name = "usbh",
+ .bit = BCM6328_CLK_USBH,
+ }, {
+ .name = "hsspi",
+ .bit = BCM6328_CLK_HSSPI,
+ }, {
+ .name = "pcie",
+ .bit = BCM6328_CLK_PCIE,
+ }, {
+ .name = "robosw",
+ .bit = BCM6328_CLK_ROBOSW,
+ }, {
+ /* sentinel */
+ },
};
static const struct clk_bcm63xx_table_entry bcm6358_clocks[] = {
- { .name = "enet", .bit = 4, },
- { .name = "adslphy", .bit = 5, },
- { .name = "pcm", .bit = 8, },
- { .name = "spi", .bit = 9, },
- { .name = "usbs", .bit = 10, },
- { .name = "sar", .bit = 11, },
- { .name = "emusb", .bit = 17, },
- { .name = "enet0", .bit = 18, },
- { .name = "enet1", .bit = 19, },
- { .name = "usbsu", .bit = 20, },
- { .name = "ephy", .bit = 21, },
- { },
+ {
+ .name = "enet",
+ .bit = BCM6358_CLK_ENET,
+ }, {
+ .name = "adslphy",
+ .bit = BCM6358_CLK_ADSLPHY,
+ }, {
+ .name = "pcm",
+ .bit = BCM6358_CLK_PCM,
+ }, {
+ .name = "spi",
+ .bit = BCM6358_CLK_SPI,
+ }, {
+ .name = "usbs",
+ .bit = BCM6358_CLK_USBS,
+ }, {
+ .name = "sar",
+ .bit = BCM6358_CLK_SAR,
+ }, {
+ .name = "emusb",
+ .bit = BCM6358_CLK_EMUSB,
+ }, {
+ .name = "enet0",
+ .bit = BCM6358_CLK_ENET0,
+ }, {
+ .name = "enet1",
+ .bit = BCM6358_CLK_ENET1,
+ }, {
+ .name = "usbsu",
+ .bit = BCM6358_CLK_USBSU,
+ }, {
+ .name = "ephy",
+ .bit = BCM6358_CLK_EPHY,
+ }, {
+ /* sentinel */
+ },
};
static const struct clk_bcm63xx_table_entry bcm6362_clocks[] = {
- { .name = "adsl_qproc", .bit = 1, },
- { .name = "adsl_afe", .bit = 2, },
- { .name = "adsl", .bit = 3, },
- { .name = "mips", .bit = 4, .flags = CLK_IS_CRITICAL, },
- { .name = "wlan_ocp", .bit = 5, },
- { .name = "swpkt_usb", .bit = 7, },
- { .name = "swpkt_sar", .bit = 8, },
- { .name = "sar", .bit = 9, },
- { .name = "robosw", .bit = 10, },
- { .name = "pcm", .bit = 11, },
- { .name = "usbd", .bit = 12, },
- { .name = "usbh", .bit = 13, },
- { .name = "ipsec", .bit = 14, },
- { .name = "spi", .bit = 15, },
- { .name = "hsspi", .bit = 16, },
- { .name = "pcie", .bit = 17, },
- { .name = "fap", .bit = 18, },
- { .name = "phymips", .bit = 19, },
- { .name = "nand", .bit = 20, },
- { },
+ {
+ .name = "adsl_qproc",
+ .bit = BCM6362_CLK_ADSL_QPROC,
+ }, {
+ .name = "adsl_afe",
+ .bit = BCM6362_CLK_ADSL_AFE,
+ }, {
+ .name = "adsl",
+ .bit = BCM6362_CLK_ADSL,
+ }, {
+ .name = "mips",
+ .bit = BCM6362_CLK_MIPS,
+ .flags = CLK_IS_CRITICAL,
+ }, {
+ .name = "wlan_ocp",
+ .bit = BCM6362_CLK_WLAN_OCP,
+ }, {
+ .name = "swpkt_usb",
+ .bit = BCM6362_CLK_SWPKT_USB,
+ }, {
+ .name = "swpkt_sar",
+ .bit = BCM6362_CLK_SWPKT_SAR,
+ }, {
+ .name = "sar",
+ .bit = BCM6362_CLK_SAR,
+ }, {
+ .name = "robosw",
+ .bit = BCM6362_CLK_ROBOSW,
+ }, {
+ .name = "pcm",
+ .bit = BCM6362_CLK_PCM,
+ }, {
+ .name = "usbd",
+ .bit = BCM6362_CLK_USBD,
+ }, {
+ .name = "usbh",
+ .bit = BCM6362_CLK_USBH,
+ }, {
+ .name = "ipsec",
+ .bit = BCM6362_CLK_IPSEC,
+ }, {
+ .name = "spi",
+ .bit = BCM6362_CLK_SPI,
+ }, {
+ .name = "hsspi",
+ .bit = BCM6362_CLK_HSSPI,
+ }, {
+ .name = "pcie",
+ .bit = BCM6362_CLK_PCIE,
+ }, {
+ .name = "fap",
+ .bit = BCM6362_CLK_FAP,
+ }, {
+ .name = "phymips",
+ .bit = BCM6362_CLK_PHYMIPS,
+ }, {
+ .name = "nand",
+ .bit = BCM6362_CLK_NAND,
+ }, {
+ /* sentinel */
+ },
};
static const struct clk_bcm63xx_table_entry bcm6368_clocks[] = {
- { .name = "vdsl_qproc", .bit = 2, },
- { .name = "vdsl_afe", .bit = 3, },
- { .name = "vdsl_bonding", .bit = 4, },
- { .name = "vdsl", .bit = 5, },
- { .name = "phymips", .bit = 6, },
- { .name = "swpkt_usb", .bit = 7, },
- { .name = "swpkt_sar", .bit = 8, },
- { .name = "spi", .bit = 9, },
- { .name = "usbd", .bit = 10, },
- { .name = "sar", .bit = 11, },
- { .name = "robosw", .bit = 12, },
- { .name = "utopia", .bit = 13, },
- { .name = "pcm", .bit = 14, },
- { .name = "usbh", .bit = 15, },
- { .name = "disable_gless", .bit = 16, },
- { .name = "nand", .bit = 17, },
- { .name = "ipsec", .bit = 18, },
- { },
+ {
+ .name = "vdsl_qproc",
+ .bit = BCM6368_CLK_VDSL_QPROC,
+ }, {
+ .name = "vdsl_afe",
+ .bit = BCM6368_CLK_VDSL_AFE,
+ }, {
+ .name = "vdsl_bonding",
+ .bit = BCM6368_CLK_VDSL_BONDING,
+ }, {
+ .name = "vdsl",
+ .bit = BCM6368_CLK_VDSL,
+ }, {
+ .name = "phymips",
+ .bit = BCM6368_CLK_PHYMIPS,
+ }, {
+ .name = "swpkt_usb",
+ .bit = BCM6368_CLK_SWPKT_USB,
+ }, {
+ .name = "swpkt_sar",
+ .bit = BCM6368_CLK_SWPKT_SAR,
+ }, {
+ .name = "spi",
+ .bit = BCM6368_CLK_SPI,
+ }, {
+ .name = "usbd",
+ .bit = BCM6368_CLK_USBD,
+ }, {
+ .name = "sar",
+ .bit = BCM6368_CLK_SAR,
+ }, {
+ .name = "robosw",
+ .bit = BCM6368_CLK_ROBOSW,
+ }, {
+ .name = "utopia",
+ .bit = BCM6368_CLK_UTOPIA,
+ }, {
+ .name = "pcm",
+ .bit = BCM6368_CLK_PCM,
+ }, {
+ .name = "usbh",
+ .bit = BCM6368_CLK_USBH,
+ }, {
+ .name = "disable_gless",
+ .bit = BCM6368_CLK_DIS_GLESS,
+ }, {
+ .name = "nand",
+ .bit = BCM6368_CLK_NAND,
+ }, {
+ .name = "ipsec",
+ .bit = BCM6368_CLK_IPSEC,
+ }, {
+ /* sentinel */
+ },
};
static const struct clk_bcm63xx_table_entry bcm63268_clocks[] = {
- { .name = "disable_gless", .bit = 0, },
- { .name = "vdsl_qproc", .bit = 1, },
- { .name = "vdsl_afe", .bit = 2, },
- { .name = "vdsl", .bit = 3, },
- { .name = "mips", .bit = 4, .flags = CLK_IS_CRITICAL, },
- { .name = "wlan_ocp", .bit = 5, },
- { .name = "dect", .bit = 6, },
- { .name = "fap0", .bit = 7, },
- { .name = "fap1", .bit = 8, },
- { .name = "sar", .bit = 9, },
- { .name = "robosw", .bit = 10, },
- { .name = "pcm", .bit = 11, },
- { .name = "usbd", .bit = 12, },
- { .name = "usbh", .bit = 13, },
- { .name = "ipsec", .bit = 14, },
- { .name = "spi", .bit = 15, },
- { .name = "hsspi", .bit = 16, },
- { .name = "pcie", .bit = 17, },
- { .name = "phymips", .bit = 18, },
- { .name = "gmac", .bit = 19, },
- { .name = "nand", .bit = 20, },
- { .name = "tbus", .bit = 27, },
- { .name = "robosw250", .bit = 31, },
- { },
+ {
+ .name = "disable_gless",
+ .bit = BCM63268_CLK_DIS_GLESS,
+ }, {
+ .name = "vdsl_qproc",
+ .bit = BCM63268_CLK_VDSL_QPROC,
+ }, {
+ .name = "vdsl_afe",
+ .bit = BCM63268_CLK_VDSL_AFE,
+ }, {
+ .name = "vdsl",
+ .bit = BCM63268_CLK_VDSL,
+ }, {
+ .name = "mips",
+ .bit = BCM63268_CLK_MIPS,
+ .flags = CLK_IS_CRITICAL,
+ }, {
+ .name = "wlan_ocp",
+ .bit = BCM63268_CLK_WLAN_OCP,
+ }, {
+ .name = "dect",
+ .bit = BCM63268_CLK_DECT,
+ }, {
+ .name = "fap0",
+ .bit = BCM63268_CLK_FAP0,
+ }, {
+ .name = "fap1",
+ .bit = BCM63268_CLK_FAP1,
+ }, {
+ .name = "sar",
+ .bit = BCM63268_CLK_SAR,
+ }, {
+ .name = "robosw",
+ .bit = BCM63268_CLK_ROBOSW,
+ }, {
+ .name = "pcm",
+ .bit = BCM63268_CLK_PCM,
+ }, {
+ .name = "usbd",
+ .bit = BCM63268_CLK_USBD,
+ }, {
+ .name = "usbh",
+ .bit = BCM63268_CLK_USBH,
+ }, {
+ .name = "ipsec",
+ .bit = BCM63268_CLK_IPSEC,
+ }, {
+ .name = "spi",
+ .bit = BCM63268_CLK_SPI,
+ }, {
+ .name = "hsspi",
+ .bit = BCM63268_CLK_HSSPI,
+ }, {
+ .name = "pcie",
+ .bit = BCM63268_CLK_PCIE,
+ }, {
+ .name = "phymips",
+ .bit = BCM63268_CLK_PHYMIPS,
+ }, {
+ .name = "gmac",
+ .bit = BCM63268_CLK_GMAC,
+ }, {
+ .name = "nand",
+ .bit = BCM63268_CLK_NAND,
+ }, {
+ .name = "tbus",
+ .bit = BCM63268_CLK_TBUS,
+ }, {
+ .name = "robosw250",
+ .bit = BCM63268_CLK_ROBOSW250,
+ }, {
+ /* sentinel */
+ },
};
static int clk_bcm63xx_probe(struct platform_device *pdev)
@@ -155,6 +495,7 @@ static int clk_bcm63xx_probe(struct platform_device *pdev)
for (entry = table; entry->name; entry++)
maxbit = max_t(u8, maxbit, entry->bit);
+ maxbit++;
hw = devm_kzalloc(&pdev->dev, struct_size(hw, data.hws, maxbit),
GFP_KERNEL);
@@ -217,6 +558,8 @@ static int clk_bcm63xx_remove(struct platform_device *pdev)
static const struct of_device_id clk_bcm63xx_dt_ids[] = {
{ .compatible = "brcm,bcm3368-clocks", .data = &bcm3368_clocks, },
+ { .compatible = "brcm,bcm6318-clocks", .data = &bcm6318_clocks, },
+ { .compatible = "brcm,bcm6318-ubus-clocks", .data = &bcm6318_ubus_clocks, },
{ .compatible = "brcm,bcm6328-clocks", .data = &bcm6328_clocks, },
{ .compatible = "brcm,bcm6358-clocks", .data = &bcm6358_clocks, },
{ .compatible = "brcm,bcm6362-clocks", .data = &bcm6362_clocks, },
diff --git a/drivers/clk/bcm/clk-iproc-asiu.c b/drivers/clk/bcm/clk-iproc-asiu.c
index 6fb8af506777..e062dd4992ea 100644
--- a/drivers/clk/bcm/clk-iproc-asiu.c
+++ b/drivers/clk/bcm/clk-iproc-asiu.c
@@ -119,7 +119,7 @@ static long iproc_asiu_clk_round_rate(struct clk_hw *hw, unsigned long rate,
if (rate == *parent_rate)
return *parent_rate;
- div = DIV_ROUND_UP(*parent_rate, rate);
+ div = DIV_ROUND_CLOSEST(*parent_rate, rate);
if (div < 2)
return *parent_rate;
@@ -145,7 +145,7 @@ static int iproc_asiu_clk_set_rate(struct clk_hw *hw, unsigned long rate,
return 0;
}
- div = DIV_ROUND_UP(parent_rate, rate);
+ div = DIV_ROUND_CLOSEST(parent_rate, rate);
if (div < 2)
return -EINVAL;
diff --git a/drivers/clk/bcm/clk-raspberrypi.c b/drivers/clk/bcm/clk-raspberrypi.c
index 1654fd0eedc9..5cc82954e1ce 100644
--- a/drivers/clk/bcm/clk-raspberrypi.c
+++ b/drivers/clk/bcm/clk-raspberrypi.c
@@ -18,30 +18,56 @@
#include <soc/bcm2835/raspberrypi-firmware.h>
-#define RPI_FIRMWARE_ARM_CLK_ID 0x00000003
+enum rpi_firmware_clk_id {
+ RPI_FIRMWARE_EMMC_CLK_ID = 1,
+ RPI_FIRMWARE_UART_CLK_ID,
+ RPI_FIRMWARE_ARM_CLK_ID,
+ RPI_FIRMWARE_CORE_CLK_ID,
+ RPI_FIRMWARE_V3D_CLK_ID,
+ RPI_FIRMWARE_H264_CLK_ID,
+ RPI_FIRMWARE_ISP_CLK_ID,
+ RPI_FIRMWARE_SDRAM_CLK_ID,
+ RPI_FIRMWARE_PIXEL_CLK_ID,
+ RPI_FIRMWARE_PWM_CLK_ID,
+ RPI_FIRMWARE_HEVC_CLK_ID,
+ RPI_FIRMWARE_EMMC2_CLK_ID,
+ RPI_FIRMWARE_M2MC_CLK_ID,
+ RPI_FIRMWARE_PIXEL_BVB_CLK_ID,
+ RPI_FIRMWARE_NUM_CLK_ID,
+};
+
+static char *rpi_firmware_clk_names[] = {
+ [RPI_FIRMWARE_EMMC_CLK_ID] = "emmc",
+ [RPI_FIRMWARE_UART_CLK_ID] = "uart",
+ [RPI_FIRMWARE_ARM_CLK_ID] = "arm",
+ [RPI_FIRMWARE_CORE_CLK_ID] = "core",
+ [RPI_FIRMWARE_V3D_CLK_ID] = "v3d",
+ [RPI_FIRMWARE_H264_CLK_ID] = "h264",
+ [RPI_FIRMWARE_ISP_CLK_ID] = "isp",
+ [RPI_FIRMWARE_SDRAM_CLK_ID] = "sdram",
+ [RPI_FIRMWARE_PIXEL_CLK_ID] = "pixel",
+ [RPI_FIRMWARE_PWM_CLK_ID] = "pwm",
+ [RPI_FIRMWARE_HEVC_CLK_ID] = "hevc",
+ [RPI_FIRMWARE_EMMC2_CLK_ID] = "emmc2",
+ [RPI_FIRMWARE_M2MC_CLK_ID] = "m2mc",
+ [RPI_FIRMWARE_PIXEL_BVB_CLK_ID] = "pixel-bvb",
+};
#define RPI_FIRMWARE_STATE_ENABLE_BIT BIT(0)
#define RPI_FIRMWARE_STATE_WAIT_BIT BIT(1)
-/*
- * Even though the firmware interface alters 'pllb' the frequencies are
- * provided as per 'pllb_arm'. We need to scale before passing them trough.
- */
-#define RPI_FIRMWARE_PLLB_ARM_DIV_RATE 2
-
-#define A2W_PLL_FRAC_BITS 20
-
struct raspberrypi_clk {
struct device *dev;
struct rpi_firmware *firmware;
struct platform_device *cpufreq;
+};
- unsigned long min_rate;
- unsigned long max_rate;
+struct raspberrypi_clk_data {
+ struct clk_hw hw;
- struct clk_hw pllb;
- struct clk_hw *pllb_arm;
- struct clk_lookup *pllb_arm_lookup;
+ unsigned int id;
+
+ struct raspberrypi_clk *rpi;
};
/*
@@ -64,11 +90,12 @@ struct raspberrypi_firmware_prop {
__le32 disable_turbo;
} __packed;
-static int raspberrypi_clock_property(struct rpi_firmware *firmware, u32 tag,
- u32 clk, u32 *val)
+static int raspberrypi_clock_property(struct rpi_firmware *firmware,
+ const struct raspberrypi_clk_data *data,
+ u32 tag, u32 *val)
{
struct raspberrypi_firmware_prop msg = {
- .id = cpu_to_le32(clk),
+ .id = cpu_to_le32(data->id),
.val = cpu_to_le32(*val),
.disable_turbo = cpu_to_le32(1),
};
@@ -83,16 +110,16 @@ static int raspberrypi_clock_property(struct rpi_firmware *firmware, u32 tag,
return 0;
}
-static int raspberrypi_fw_pll_is_on(struct clk_hw *hw)
+static int raspberrypi_fw_is_prepared(struct clk_hw *hw)
{
- struct raspberrypi_clk *rpi = container_of(hw, struct raspberrypi_clk,
- pllb);
+ struct raspberrypi_clk_data *data =
+ container_of(hw, struct raspberrypi_clk_data, hw);
+ struct raspberrypi_clk *rpi = data->rpi;
u32 val = 0;
int ret;
- ret = raspberrypi_clock_property(rpi->firmware,
- RPI_FIRMWARE_GET_CLOCK_STATE,
- RPI_FIRMWARE_ARM_CLK_ID, &val);
+ ret = raspberrypi_clock_property(rpi->firmware, data,
+ RPI_FIRMWARE_GET_CLOCK_STATE, &val);
if (ret)
return 0;
@@ -100,36 +127,34 @@ static int raspberrypi_fw_pll_is_on(struct clk_hw *hw)
}
-static unsigned long raspberrypi_fw_pll_get_rate(struct clk_hw *hw,
- unsigned long parent_rate)
+static unsigned long raspberrypi_fw_get_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
{
- struct raspberrypi_clk *rpi = container_of(hw, struct raspberrypi_clk,
- pllb);
+ struct raspberrypi_clk_data *data =
+ container_of(hw, struct raspberrypi_clk_data, hw);
+ struct raspberrypi_clk *rpi = data->rpi;
u32 val = 0;
int ret;
- ret = raspberrypi_clock_property(rpi->firmware,
- RPI_FIRMWARE_GET_CLOCK_RATE,
- RPI_FIRMWARE_ARM_CLK_ID,
- &val);
+ ret = raspberrypi_clock_property(rpi->firmware, data,
+ RPI_FIRMWARE_GET_CLOCK_RATE, &val);
if (ret)
return ret;
- return val * RPI_FIRMWARE_PLLB_ARM_DIV_RATE;
+ return val;
}
-static int raspberrypi_fw_pll_set_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long parent_rate)
+static int raspberrypi_fw_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
{
- struct raspberrypi_clk *rpi = container_of(hw, struct raspberrypi_clk,
- pllb);
- u32 new_rate = rate / RPI_FIRMWARE_PLLB_ARM_DIV_RATE;
+ struct raspberrypi_clk_data *data =
+ container_of(hw, struct raspberrypi_clk_data, hw);
+ struct raspberrypi_clk *rpi = data->rpi;
+ u32 _rate = rate;
int ret;
- ret = raspberrypi_clock_property(rpi->firmware,
- RPI_FIRMWARE_SET_CLOCK_RATE,
- RPI_FIRMWARE_ARM_CLK_ID,
- &new_rate);
+ ret = raspberrypi_clock_property(rpi->firmware, data,
+ RPI_FIRMWARE_SET_CLOCK_RATE, &_rate);
if (ret)
dev_err_ratelimited(rpi->dev, "Failed to change %s frequency: %d",
clk_hw_get_name(hw), ret);
@@ -137,111 +162,128 @@ static int raspberrypi_fw_pll_set_rate(struct clk_hw *hw, unsigned long rate,
return ret;
}
-/*
- * Sadly there is no firmware rate rounding interface. We borrowed it from
- * clk-bcm2835.
- */
-static int raspberrypi_pll_determine_rate(struct clk_hw *hw,
- struct clk_rate_request *req)
+static int raspberrypi_fw_dumb_determine_rate(struct clk_hw *hw,
+ struct clk_rate_request *req)
{
- struct raspberrypi_clk *rpi = container_of(hw, struct raspberrypi_clk,
- pllb);
- u64 div, final_rate;
- u32 ndiv, fdiv;
-
- /* We can't use req->rate directly as it would overflow */
- final_rate = clamp(req->rate, rpi->min_rate, rpi->max_rate);
-
- div = (u64)final_rate << A2W_PLL_FRAC_BITS;
- do_div(div, req->best_parent_rate);
-
- ndiv = div >> A2W_PLL_FRAC_BITS;
- fdiv = div & ((1 << A2W_PLL_FRAC_BITS) - 1);
-
- final_rate = ((u64)req->best_parent_rate *
- ((ndiv << A2W_PLL_FRAC_BITS) + fdiv));
-
- req->rate = final_rate >> A2W_PLL_FRAC_BITS;
-
+ /*
+ * The firmware will do the rounding but that isn't part of
+ * the interface with the firmware, so we just do our best
+ * here.
+ */
+ req->rate = clamp(req->rate, req->min_rate, req->max_rate);
return 0;
}
-static const struct clk_ops raspberrypi_firmware_pll_clk_ops = {
- .is_prepared = raspberrypi_fw_pll_is_on,
- .recalc_rate = raspberrypi_fw_pll_get_rate,
- .set_rate = raspberrypi_fw_pll_set_rate,
- .determine_rate = raspberrypi_pll_determine_rate,
+static const struct clk_ops raspberrypi_firmware_clk_ops = {
+ .is_prepared = raspberrypi_fw_is_prepared,
+ .recalc_rate = raspberrypi_fw_get_rate,
+ .determine_rate = raspberrypi_fw_dumb_determine_rate,
+ .set_rate = raspberrypi_fw_set_rate,
};
-static int raspberrypi_register_pllb(struct raspberrypi_clk *rpi)
+static struct clk_hw *raspberrypi_clk_register(struct raspberrypi_clk *rpi,
+ unsigned int parent,
+ unsigned int id)
{
- u32 min_rate = 0, max_rate = 0;
- struct clk_init_data init;
+ struct raspberrypi_clk_data *data;
+ struct clk_init_data init = {};
+ u32 min_rate, max_rate;
int ret;
- memset(&init, 0, sizeof(init));
+ data = devm_kzalloc(rpi->dev, sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return ERR_PTR(-ENOMEM);
+ data->rpi = rpi;
+ data->id = id;
- /* All of the PLLs derive from the external oscillator. */
- init.parent_names = (const char *[]){ "osc" };
- init.num_parents = 1;
- init.name = "pllb";
- init.ops = &raspberrypi_firmware_pll_clk_ops;
- init.flags = CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED;
+ init.name = devm_kasprintf(rpi->dev, GFP_KERNEL,
+ "fw-clk-%s",
+ rpi_firmware_clk_names[id]);
+ init.ops = &raspberrypi_firmware_clk_ops;
+ init.flags = CLK_GET_RATE_NOCACHE;
- /* Get min & max rates set by the firmware */
- ret = raspberrypi_clock_property(rpi->firmware,
+ data->hw.init = &init;
+
+ ret = raspberrypi_clock_property(rpi->firmware, data,
RPI_FIRMWARE_GET_MIN_CLOCK_RATE,
- RPI_FIRMWARE_ARM_CLK_ID,
&min_rate);
if (ret) {
- dev_err(rpi->dev, "Failed to get %s min freq: %d\n",
- init.name, ret);
- return ret;
+ dev_err(rpi->dev, "Failed to get clock %d min freq: %d",
+ id, ret);
+ return ERR_PTR(ret);
}
- ret = raspberrypi_clock_property(rpi->firmware,
+ ret = raspberrypi_clock_property(rpi->firmware, data,
RPI_FIRMWARE_GET_MAX_CLOCK_RATE,
- RPI_FIRMWARE_ARM_CLK_ID,
&max_rate);
if (ret) {
- dev_err(rpi->dev, "Failed to get %s max freq: %d\n",
- init.name, ret);
- return ret;
- }
-
- if (!min_rate || !max_rate) {
- dev_err(rpi->dev, "Unexpected frequency range: min %u, max %u\n",
- min_rate, max_rate);
- return -EINVAL;
+ dev_err(rpi->dev, "Failed to get clock %d max freq: %d\n",
+ id, ret);
+ return ERR_PTR(ret);
}
- dev_info(rpi->dev, "CPU frequency range: min %u, max %u\n",
- min_rate, max_rate);
+ ret = devm_clk_hw_register(rpi->dev, &data->hw);
+ if (ret)
+ return ERR_PTR(ret);
- rpi->min_rate = min_rate * RPI_FIRMWARE_PLLB_ARM_DIV_RATE;
- rpi->max_rate = max_rate * RPI_FIRMWARE_PLLB_ARM_DIV_RATE;
+ clk_hw_set_rate_range(&data->hw, min_rate, max_rate);
- rpi->pllb.init = &init;
+ if (id == RPI_FIRMWARE_ARM_CLK_ID) {
+ ret = devm_clk_hw_register_clkdev(rpi->dev, &data->hw,
+ NULL, "cpu0");
+ if (ret) {
+ dev_err(rpi->dev, "Failed to initialize clkdev\n");
+ return ERR_PTR(ret);
+ }
+ }
- return devm_clk_hw_register(rpi->dev, &rpi->pllb);
+ return &data->hw;
}
-static int raspberrypi_register_pllb_arm(struct raspberrypi_clk *rpi)
+struct rpi_firmware_get_clocks_response {
+ u32 parent;
+ u32 id;
+};
+
+static int raspberrypi_discover_clocks(struct raspberrypi_clk *rpi,
+ struct clk_hw_onecell_data *data)
{
- rpi->pllb_arm = clk_hw_register_fixed_factor(rpi->dev,
- "pllb_arm", "pllb",
- CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
- 1, 2);
- if (IS_ERR(rpi->pllb_arm)) {
- dev_err(rpi->dev, "Failed to initialize pllb_arm\n");
- return PTR_ERR(rpi->pllb_arm);
- }
+ struct rpi_firmware_get_clocks_response *clks;
+ int ret;
- rpi->pllb_arm_lookup = clkdev_hw_create(rpi->pllb_arm, NULL, "cpu0");
- if (!rpi->pllb_arm_lookup) {
- dev_err(rpi->dev, "Failed to initialize pllb_arm_lookup\n");
- clk_hw_unregister_fixed_factor(rpi->pllb_arm);
+ clks = devm_kcalloc(rpi->dev,
+ sizeof(*clks), RPI_FIRMWARE_NUM_CLK_ID,
+ GFP_KERNEL);
+ if (!clks)
return -ENOMEM;
+
+ ret = rpi_firmware_property(rpi->firmware, RPI_FIRMWARE_GET_CLOCKS,
+ clks,
+ sizeof(*clks) * RPI_FIRMWARE_NUM_CLK_ID);
+ if (ret)
+ return ret;
+
+ while (clks->id) {
+ struct clk_hw *hw;
+
+ switch (clks->id) {
+ case RPI_FIRMWARE_ARM_CLK_ID:
+ case RPI_FIRMWARE_CORE_CLK_ID:
+ case RPI_FIRMWARE_M2MC_CLK_ID:
+ case RPI_FIRMWARE_V3D_CLK_ID:
+ hw = raspberrypi_clk_register(rpi, clks->parent,
+ clks->id);
+ if (IS_ERR(hw))
+ return PTR_ERR(hw);
+
+ data->hws[clks->id] = hw;
+ data->num = clks->id + 1;
+ fallthrough;
+
+ default:
+ clks++;
+ break;
+ }
}
return 0;
@@ -249,14 +291,23 @@ static int raspberrypi_register_pllb_arm(struct raspberrypi_clk *rpi)
static int raspberrypi_clk_probe(struct platform_device *pdev)
{
+ struct clk_hw_onecell_data *clk_data;
struct device_node *firmware_node;
struct device *dev = &pdev->dev;
struct rpi_firmware *firmware;
struct raspberrypi_clk *rpi;
int ret;
- firmware_node = of_find_compatible_node(NULL, NULL,
- "raspberrypi,bcm2835-firmware");
+ /*
+ * We can be probed either through the an old-fashioned
+ * platform device registration or through a DT node that is a
+ * child of the firmware node. Handle both cases.
+ */
+ if (dev->of_node)
+ firmware_node = of_get_parent(dev->of_node);
+ else
+ firmware_node = of_find_compatible_node(NULL, NULL,
+ "raspberrypi,bcm2835-firmware");
if (!firmware_node) {
dev_err(dev, "Missing firmware node\n");
return -ENOENT;
@@ -275,13 +326,18 @@ static int raspberrypi_clk_probe(struct platform_device *pdev)
rpi->firmware = firmware;
platform_set_drvdata(pdev, rpi);
- ret = raspberrypi_register_pllb(rpi);
- if (ret) {
- dev_err(dev, "Failed to initialize pllb, %d\n", ret);
+ clk_data = devm_kzalloc(dev, struct_size(clk_data, hws,
+ RPI_FIRMWARE_NUM_CLK_ID),
+ GFP_KERNEL);
+ if (!clk_data)
+ return -ENOMEM;
+
+ ret = raspberrypi_discover_clocks(rpi, clk_data);
+ if (ret)
return ret;
- }
- ret = raspberrypi_register_pllb_arm(rpi);
+ ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
+ clk_data);
if (ret)
return ret;
@@ -300,9 +356,16 @@ static int raspberrypi_clk_remove(struct platform_device *pdev)
return 0;
}
+static const struct of_device_id raspberrypi_clk_match[] = {
+ { .compatible = "raspberrypi,firmware-clocks" },
+ { },
+};
+MODULE_DEVICE_TABLE(of, raspberrypi_clk_match);
+
static struct platform_driver raspberrypi_clk_driver = {
.driver = {
.name = "raspberrypi-clk",
+ .of_match_table = raspberrypi_clk_match,
},
.probe = raspberrypi_clk_probe,
.remove = raspberrypi_clk_remove,
diff --git a/drivers/clk/clk-ast2600.c b/drivers/clk/clk-ast2600.c
index 99afc949925f..177368cac6dd 100644
--- a/drivers/clk/clk-ast2600.c
+++ b/drivers/clk/clk-ast2600.c
@@ -131,6 +131,18 @@ static const struct clk_div_table ast2600_eclk_div_table[] = {
{ 0 }
};
+static const struct clk_div_table ast2600_emmc_extclk_div_table[] = {
+ { 0x0, 2 },
+ { 0x1, 4 },
+ { 0x2, 6 },
+ { 0x3, 8 },
+ { 0x4, 10 },
+ { 0x5, 12 },
+ { 0x6, 14 },
+ { 0x7, 16 },
+ { 0 }
+};
+
static const struct clk_div_table ast2600_mac_div_table[] = {
{ 0x0, 4 },
{ 0x1, 4 },
@@ -390,6 +402,11 @@ static struct clk_hw *aspeed_g6_clk_hw_register_gate(struct device *dev,
return hw;
}
+static const char *const emmc_extclk_parent_names[] = {
+ "emmc_extclk_hpll_in",
+ "mpll",
+};
+
static const char * const vclk_parent_names[] = {
"dpll",
"d1pll",
@@ -459,16 +476,32 @@ static int aspeed_g6_clk_probe(struct platform_device *pdev)
return PTR_ERR(hw);
aspeed_g6_clk_data->hws[ASPEED_CLK_UARTX] = hw;
- /* EMMC ext clock divider */
- hw = clk_hw_register_gate(dev, "emmc_extclk_gate", "hpll", 0,
- scu_g6_base + ASPEED_G6_CLK_SELECTION1, 15, 0,
- &aspeed_g6_clk_lock);
+ /* EMMC ext clock */
+ hw = clk_hw_register_fixed_factor(dev, "emmc_extclk_hpll_in", "hpll",
+ 0, 1, 2);
if (IS_ERR(hw))
return PTR_ERR(hw);
- hw = clk_hw_register_divider_table(dev, "emmc_extclk", "emmc_extclk_gate", 0,
- scu_g6_base + ASPEED_G6_CLK_SELECTION1, 12, 3, 0,
- ast2600_div_table,
- &aspeed_g6_clk_lock);
+
+ hw = clk_hw_register_mux(dev, "emmc_extclk_mux",
+ emmc_extclk_parent_names,
+ ARRAY_SIZE(emmc_extclk_parent_names), 0,
+ scu_g6_base + ASPEED_G6_CLK_SELECTION1, 11, 1,
+ 0, &aspeed_g6_clk_lock);
+ if (IS_ERR(hw))
+ return PTR_ERR(hw);
+
+ hw = clk_hw_register_gate(dev, "emmc_extclk_gate", "emmc_extclk_mux",
+ 0, scu_g6_base + ASPEED_G6_CLK_SELECTION1,
+ 15, 0, &aspeed_g6_clk_lock);
+ if (IS_ERR(hw))
+ return PTR_ERR(hw);
+
+ hw = clk_hw_register_divider_table(dev, "emmc_extclk",
+ "emmc_extclk_gate", 0,
+ scu_g6_base +
+ ASPEED_G6_CLK_SELECTION1, 12,
+ 3, 0, ast2600_emmc_extclk_div_table,
+ &aspeed_g6_clk_lock);
if (IS_ERR(hw))
return PTR_ERR(hw);
aspeed_g6_clk_data->hws[ASPEED_CLK_EMMC] = hw;
diff --git a/drivers/clk/clk-cdce706.c b/drivers/clk/clk-cdce706.c
index 239102e37e2f..c91e9096b070 100644
--- a/drivers/clk/clk-cdce706.c
+++ b/drivers/clk/clk-cdce706.c
@@ -4,7 +4,7 @@
*
* Copyright (c) 2014 Cadence Design Systems Inc.
*
- * Reference: http://www.ti.com/lit/ds/symlink/cdce706.pdf
+ * Reference: https://www.ti.com/lit/ds/symlink/cdce706.pdf
*/
#include <linux/clk.h>
diff --git a/drivers/clk/clk-gpio.c b/drivers/clk/clk-gpio.c
index 70397b4b5ffe..38755a241ab7 100644
--- a/drivers/clk/clk-gpio.c
+++ b/drivers/clk/clk-gpio.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
/*
- * Copyright (C) 2013 - 2014 Texas Instruments Incorporated - http://www.ti.com
+ * Copyright (C) 2013 - 2014 Texas Instruments Incorporated - https://www.ti.com
*
* Authors:
* Jyri Sarha <jsarha@ti.com>
diff --git a/drivers/clk/clk-si5351.c b/drivers/clk/clk-si5351.c
index 71de3618e508..1e1702e609cb 100644
--- a/drivers/clk/clk-si5351.c
+++ b/drivers/clk/clk-si5351.c
@@ -7,9 +7,9 @@
*
* References:
* [1] "Si5351A/B/C Data Sheet"
- * http://www.silabs.com/Support%20Documents/TechnicalDocs/Si5351.pdf
+ * https://www.silabs.com/Support%20Documents/TechnicalDocs/Si5351.pdf
* [2] "Manually Generating an Si5351 Register Map"
- * http://www.silabs.com/Support%20Documents/TechnicalDocs/AN619.pdf
+ * https://www.silabs.com/Support%20Documents/TechnicalDocs/AN619.pdf
*/
#include <linux/module.h>
diff --git a/drivers/clk/clk-versaclock5.c b/drivers/clk/clk-versaclock5.c
index fa96659f8023..c90460e7ef21 100644
--- a/drivers/clk/clk-versaclock5.c
+++ b/drivers/clk/clk-versaclock5.c
@@ -24,6 +24,8 @@
#include <linux/regmap.h>
#include <linux/slab.h>
+#include <dt-bindings/clk/versaclock.h>
+
/* VersaClock5 registers */
#define VC5_OTP_CONTROL 0x00
@@ -89,6 +91,28 @@
/* Clock control register for clock 1,2 */
#define VC5_CLK_OUTPUT_CFG(idx, n) (0x60 + ((idx) * 0x2) + (n))
+#define VC5_CLK_OUTPUT_CFG0_CFG_SHIFT 5
+#define VC5_CLK_OUTPUT_CFG0_CFG_MASK GENMASK(7, VC5_CLK_OUTPUT_CFG0_CFG_SHIFT)
+
+#define VC5_CLK_OUTPUT_CFG0_CFG_LVPECL (VC5_LVPECL)
+#define VC5_CLK_OUTPUT_CFG0_CFG_CMOS (VC5_CMOS)
+#define VC5_CLK_OUTPUT_CFG0_CFG_HCSL33 (VC5_HCSL33)
+#define VC5_CLK_OUTPUT_CFG0_CFG_LVDS (VC5_LVDS)
+#define VC5_CLK_OUTPUT_CFG0_CFG_CMOS2 (VC5_CMOS2)
+#define VC5_CLK_OUTPUT_CFG0_CFG_CMOSD (VC5_CMOSD)
+#define VC5_CLK_OUTPUT_CFG0_CFG_HCSL25 (VC5_HCSL25)
+
+#define VC5_CLK_OUTPUT_CFG0_PWR_SHIFT 3
+#define VC5_CLK_OUTPUT_CFG0_PWR_MASK GENMASK(4, VC5_CLK_OUTPUT_CFG0_PWR_SHIFT)
+#define VC5_CLK_OUTPUT_CFG0_PWR_18 (0<<VC5_CLK_OUTPUT_CFG0_PWR_SHIFT)
+#define VC5_CLK_OUTPUT_CFG0_PWR_25 (2<<VC5_CLK_OUTPUT_CFG0_PWR_SHIFT)
+#define VC5_CLK_OUTPUT_CFG0_PWR_33 (3<<VC5_CLK_OUTPUT_CFG0_PWR_SHIFT)
+#define VC5_CLK_OUTPUT_CFG0_SLEW_SHIFT 0
+#define VC5_CLK_OUTPUT_CFG0_SLEW_MASK GENMASK(1, VC5_CLK_OUTPUT_CFG0_SLEW_SHIFT)
+#define VC5_CLK_OUTPUT_CFG0_SLEW_80 (0<<VC5_CLK_OUTPUT_CFG0_SLEW_SHIFT)
+#define VC5_CLK_OUTPUT_CFG0_SLEW_85 (1<<VC5_CLK_OUTPUT_CFG0_SLEW_SHIFT)
+#define VC5_CLK_OUTPUT_CFG0_SLEW_90 (2<<VC5_CLK_OUTPUT_CFG0_SLEW_SHIFT)
+#define VC5_CLK_OUTPUT_CFG0_SLEW_100 (3<<VC5_CLK_OUTPUT_CFG0_SLEW_SHIFT)
#define VC5_CLK_OUTPUT_CFG1_EN_CLKBUF BIT(0)
#define VC5_CLK_OE_SHDN 0x68
@@ -145,6 +169,14 @@ struct vc5_hw_data {
unsigned int num;
};
+struct vc5_out_data {
+ struct clk_hw hw;
+ struct vc5_driver_data *vc5;
+ unsigned int num;
+ unsigned int clk_output_cfg0;
+ unsigned int clk_output_cfg0_mask;
+};
+
struct vc5_driver_data {
struct i2c_client *client;
struct regmap *regmap;
@@ -158,31 +190,7 @@ struct vc5_driver_data {
struct clk_hw clk_pfd;
struct vc5_hw_data clk_pll;
struct vc5_hw_data clk_fod[VC5_MAX_FOD_NUM];
- struct vc5_hw_data clk_out[VC5_MAX_CLK_OUT_NUM];
-};
-
-static const char * const vc5_mux_names[] = {
- "mux"
-};
-
-static const char * const vc5_dbl_names[] = {
- "dbl"
-};
-
-static const char * const vc5_pfd_names[] = {
- "pfd"
-};
-
-static const char * const vc5_pll_names[] = {
- "pll"
-};
-
-static const char * const vc5_fod_names[] = {
- "fod0", "fod1", "fod2", "fod3",
-};
-
-static const char * const vc5_clk_out_names[] = {
- "out0_sel_i2cb", "out1", "out2", "out3", "out4",
+ struct vc5_out_data clk_out[VC5_MAX_CLK_OUT_NUM];
};
/*
@@ -565,7 +573,7 @@ static const struct clk_ops vc5_fod_ops = {
static int vc5_clk_out_prepare(struct clk_hw *hw)
{
- struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
+ struct vc5_out_data *hwdata = container_of(hw, struct vc5_out_data, hw);
struct vc5_driver_data *vc5 = hwdata->vc5;
const u8 mask = VC5_OUT_DIV_CONTROL_SELB_NORM |
VC5_OUT_DIV_CONTROL_SEL_EXT |
@@ -591,12 +599,23 @@ static int vc5_clk_out_prepare(struct clk_hw *hw)
regmap_update_bits(vc5->regmap, VC5_CLK_OUTPUT_CFG(hwdata->num, 1),
VC5_CLK_OUTPUT_CFG1_EN_CLKBUF,
VC5_CLK_OUTPUT_CFG1_EN_CLKBUF);
+ if (hwdata->clk_output_cfg0_mask) {
+ dev_dbg(&vc5->client->dev, "Update output %d mask 0x%0X val 0x%0X\n",
+ hwdata->num, hwdata->clk_output_cfg0_mask,
+ hwdata->clk_output_cfg0);
+
+ regmap_update_bits(vc5->regmap,
+ VC5_CLK_OUTPUT_CFG(hwdata->num, 0),
+ hwdata->clk_output_cfg0_mask,
+ hwdata->clk_output_cfg0);
+ }
+
return 0;
}
static void vc5_clk_out_unprepare(struct clk_hw *hw)
{
- struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
+ struct vc5_out_data *hwdata = container_of(hw, struct vc5_out_data, hw);
struct vc5_driver_data *vc5 = hwdata->vc5;
/* Disable the clock buffer */
@@ -606,7 +625,7 @@ static void vc5_clk_out_unprepare(struct clk_hw *hw)
static unsigned char vc5_clk_out_get_parent(struct clk_hw *hw)
{
- struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
+ struct vc5_out_data *hwdata = container_of(hw, struct vc5_out_data, hw);
struct vc5_driver_data *vc5 = hwdata->vc5;
const u8 mask = VC5_OUT_DIV_CONTROL_SELB_NORM |
VC5_OUT_DIV_CONTROL_SEL_EXT |
@@ -636,7 +655,7 @@ static unsigned char vc5_clk_out_get_parent(struct clk_hw *hw)
static int vc5_clk_out_set_parent(struct clk_hw *hw, u8 index)
{
- struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
+ struct vc5_out_data *hwdata = container_of(hw, struct vc5_out_data, hw);
struct vc5_driver_data *vc5 = hwdata->vc5;
const u8 mask = VC5_OUT_DIV_CONTROL_RESET |
VC5_OUT_DIV_CONTROL_SELB_NORM |
@@ -690,10 +709,125 @@ static int vc5_map_index_to_output(const enum vc5_model model,
}
}
+static int vc5_update_mode(struct device_node *np_output,
+ struct vc5_out_data *clk_out)
+{
+ u32 value;
+
+ if (!of_property_read_u32(np_output, "idt,mode", &value)) {
+ clk_out->clk_output_cfg0_mask |= VC5_CLK_OUTPUT_CFG0_CFG_MASK;
+ switch (value) {
+ case VC5_CLK_OUTPUT_CFG0_CFG_LVPECL:
+ case VC5_CLK_OUTPUT_CFG0_CFG_CMOS:
+ case VC5_CLK_OUTPUT_CFG0_CFG_HCSL33:
+ case VC5_CLK_OUTPUT_CFG0_CFG_LVDS:
+ case VC5_CLK_OUTPUT_CFG0_CFG_CMOS2:
+ case VC5_CLK_OUTPUT_CFG0_CFG_CMOSD:
+ case VC5_CLK_OUTPUT_CFG0_CFG_HCSL25:
+ clk_out->clk_output_cfg0 |=
+ value << VC5_CLK_OUTPUT_CFG0_CFG_SHIFT;
+ break;
+ default:
+ return -EINVAL;
+ }
+ }
+ return 0;
+}
+
+static int vc5_update_power(struct device_node *np_output,
+ struct vc5_out_data *clk_out)
+{
+ u32 value;
+
+ if (!of_property_read_u32(np_output,
+ "idt,voltage-microvolts", &value)) {
+ clk_out->clk_output_cfg0_mask |= VC5_CLK_OUTPUT_CFG0_PWR_MASK;
+ switch (value) {
+ case 1800000:
+ clk_out->clk_output_cfg0 |= VC5_CLK_OUTPUT_CFG0_PWR_18;
+ break;
+ case 2500000:
+ clk_out->clk_output_cfg0 |= VC5_CLK_OUTPUT_CFG0_PWR_25;
+ break;
+ case 3300000:
+ clk_out->clk_output_cfg0 |= VC5_CLK_OUTPUT_CFG0_PWR_33;
+ break;
+ default:
+ return -EINVAL;
+ }
+ }
+ return 0;
+}
+
+static int vc5_update_slew(struct device_node *np_output,
+ struct vc5_out_data *clk_out)
+{
+ u32 value;
+
+ if (!of_property_read_u32(np_output, "idt,slew-percent", &value)) {
+ clk_out->clk_output_cfg0_mask |= VC5_CLK_OUTPUT_CFG0_SLEW_MASK;
+ switch (value) {
+ case 80:
+ clk_out->clk_output_cfg0 |= VC5_CLK_OUTPUT_CFG0_SLEW_80;
+ break;
+ case 85:
+ clk_out->clk_output_cfg0 |= VC5_CLK_OUTPUT_CFG0_SLEW_85;
+ break;
+ case 90:
+ clk_out->clk_output_cfg0 |= VC5_CLK_OUTPUT_CFG0_SLEW_90;
+ break;
+ case 100:
+ clk_out->clk_output_cfg0 |=
+ VC5_CLK_OUTPUT_CFG0_SLEW_100;
+ break;
+ default:
+ return -EINVAL;
+ }
+ }
+ return 0;
+}
+
+static int vc5_get_output_config(struct i2c_client *client,
+ struct vc5_out_data *clk_out)
+{
+ struct device_node *np_output;
+ char *child_name;
+ int ret = 0;
+
+ child_name = kasprintf(GFP_KERNEL, "OUT%d", clk_out->num + 1);
+ if (!child_name)
+ return -ENOMEM;
+
+ np_output = of_get_child_by_name(client->dev.of_node, child_name);
+ kfree(child_name);
+ if (!np_output)
+ return 0;
+
+ ret = vc5_update_mode(np_output, clk_out);
+ if (ret)
+ goto output_error;
+
+ ret = vc5_update_power(np_output, clk_out);
+ if (ret)
+ goto output_error;
+
+ ret = vc5_update_slew(np_output, clk_out);
+
+output_error:
+ if (ret) {
+ dev_err(&client->dev,
+ "Invalid clock output configuration OUT%d\n",
+ clk_out->num + 1);
+ }
+
+ of_node_put(np_output);
+
+ return ret;
+}
+
static const struct of_device_id clk_vc5_of_match[];
-static int vc5_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
struct vc5_driver_data *vc5;
struct clk_init_data init;
@@ -702,7 +836,7 @@ static int vc5_probe(struct i2c_client *client,
int ret;
vc5 = devm_kzalloc(&client->dev, sizeof(*vc5), GFP_KERNEL);
- if (vc5 == NULL)
+ if (!vc5)
return -ENOMEM;
i2c_set_clientdata(client, vc5);
@@ -742,7 +876,7 @@ static int vc5_probe(struct i2c_client *client,
if (!IS_ERR(vc5->pin_clkin)) {
vc5->clk_mux_ins |= VC5_MUX_IN_CLKIN;
parent_names[init.num_parents++] =
- __clk_get_name(vc5->pin_clkin);
+ __clk_get_name(vc5->pin_clkin);
}
if (!init.num_parents) {
@@ -750,115 +884,116 @@ static int vc5_probe(struct i2c_client *client,
return -EINVAL;
}
- init.name = vc5_mux_names[0];
+ init.name = kasprintf(GFP_KERNEL, "%pOFn.mux", client->dev.of_node);
init.ops = &vc5_mux_ops;
init.flags = 0;
init.parent_names = parent_names;
vc5->clk_mux.init = &init;
ret = devm_clk_hw_register(&client->dev, &vc5->clk_mux);
- if (ret) {
- dev_err(&client->dev, "unable to register %s\n", init.name);
- goto err_clk;
- }
+ if (ret)
+ goto err_clk_register;
+ kfree(init.name); /* clock framework made a copy of the name */
if (vc5->chip_info->flags & VC5_HAS_PFD_FREQ_DBL) {
/* Register frequency doubler */
memset(&init, 0, sizeof(init));
- init.name = vc5_dbl_names[0];
+ init.name = kasprintf(GFP_KERNEL, "%pOFn.dbl",
+ client->dev.of_node);
init.ops = &vc5_dbl_ops;
init.flags = CLK_SET_RATE_PARENT;
- init.parent_names = vc5_mux_names;
+ init.parent_names = parent_names;
+ parent_names[0] = clk_hw_get_name(&vc5->clk_mux);
init.num_parents = 1;
vc5->clk_mul.init = &init;
ret = devm_clk_hw_register(&client->dev, &vc5->clk_mul);
- if (ret) {
- dev_err(&client->dev, "unable to register %s\n",
- init.name);
- goto err_clk;
- }
+ if (ret)
+ goto err_clk_register;
+ kfree(init.name); /* clock framework made a copy of the name */
}
/* Register PFD */
memset(&init, 0, sizeof(init));
- init.name = vc5_pfd_names[0];
+ init.name = kasprintf(GFP_KERNEL, "%pOFn.pfd", client->dev.of_node);
init.ops = &vc5_pfd_ops;
init.flags = CLK_SET_RATE_PARENT;
+ init.parent_names = parent_names;
if (vc5->chip_info->flags & VC5_HAS_PFD_FREQ_DBL)
- init.parent_names = vc5_dbl_names;
+ parent_names[0] = clk_hw_get_name(&vc5->clk_mul);
else
- init.parent_names = vc5_mux_names;
+ parent_names[0] = clk_hw_get_name(&vc5->clk_mux);
init.num_parents = 1;
vc5->clk_pfd.init = &init;
ret = devm_clk_hw_register(&client->dev, &vc5->clk_pfd);
- if (ret) {
- dev_err(&client->dev, "unable to register %s\n", init.name);
- goto err_clk;
- }
+ if (ret)
+ goto err_clk_register;
+ kfree(init.name); /* clock framework made a copy of the name */
/* Register PLL */
memset(&init, 0, sizeof(init));
- init.name = vc5_pll_names[0];
+ init.name = kasprintf(GFP_KERNEL, "%pOFn.pll", client->dev.of_node);
init.ops = &vc5_pll_ops;
init.flags = CLK_SET_RATE_PARENT;
- init.parent_names = vc5_pfd_names;
+ init.parent_names = parent_names;
+ parent_names[0] = clk_hw_get_name(&vc5->clk_pfd);
init.num_parents = 1;
vc5->clk_pll.num = 0;
vc5->clk_pll.vc5 = vc5;
vc5->clk_pll.hw.init = &init;
ret = devm_clk_hw_register(&client->dev, &vc5->clk_pll.hw);
- if (ret) {
- dev_err(&client->dev, "unable to register %s\n", init.name);
- goto err_clk;
- }
+ if (ret)
+ goto err_clk_register;
+ kfree(init.name); /* clock framework made a copy of the name */
/* Register FODs */
for (n = 0; n < vc5->chip_info->clk_fod_cnt; n++) {
idx = vc5_map_index_to_output(vc5->chip_info->model, n);
memset(&init, 0, sizeof(init));
- init.name = vc5_fod_names[idx];
+ init.name = kasprintf(GFP_KERNEL, "%pOFn.fod%d",
+ client->dev.of_node, idx);
init.ops = &vc5_fod_ops;
init.flags = CLK_SET_RATE_PARENT;
- init.parent_names = vc5_pll_names;
+ init.parent_names = parent_names;
+ parent_names[0] = clk_hw_get_name(&vc5->clk_pll.hw);
init.num_parents = 1;
vc5->clk_fod[n].num = idx;
vc5->clk_fod[n].vc5 = vc5;
vc5->clk_fod[n].hw.init = &init;
ret = devm_clk_hw_register(&client->dev, &vc5->clk_fod[n].hw);
- if (ret) {
- dev_err(&client->dev, "unable to register %s\n",
- init.name);
- goto err_clk;
- }
+ if (ret)
+ goto err_clk_register;
+ kfree(init.name); /* clock framework made a copy of the name */
}
/* Register MUX-connected OUT0_I2C_SELB output */
memset(&init, 0, sizeof(init));
- init.name = vc5_clk_out_names[0];
+ init.name = kasprintf(GFP_KERNEL, "%pOFn.out0_sel_i2cb",
+ client->dev.of_node);
init.ops = &vc5_clk_out_ops;
init.flags = CLK_SET_RATE_PARENT;
- init.parent_names = vc5_mux_names;
+ init.parent_names = parent_names;
+ parent_names[0] = clk_hw_get_name(&vc5->clk_mux);
init.num_parents = 1;
vc5->clk_out[0].num = idx;
vc5->clk_out[0].vc5 = vc5;
vc5->clk_out[0].hw.init = &init;
ret = devm_clk_hw_register(&client->dev, &vc5->clk_out[0].hw);
- if (ret) {
- dev_err(&client->dev, "unable to register %s\n",
- init.name);
- goto err_clk;
- }
+ if (ret)
+ goto err_clk_register;
+ kfree(init.name); /* clock framework made a copy of the name */
/* Register FOD-connected OUTx outputs */
for (n = 1; n < vc5->chip_info->clk_out_cnt; n++) {
idx = vc5_map_index_to_output(vc5->chip_info->model, n - 1);
- parent_names[0] = vc5_fod_names[idx];
+ parent_names[0] = clk_hw_get_name(&vc5->clk_fod[idx].hw);
if (n == 1)
- parent_names[1] = vc5_mux_names[0];
+ parent_names[1] = clk_hw_get_name(&vc5->clk_mux);
else
- parent_names[1] = vc5_clk_out_names[n - 1];
+ parent_names[1] =
+ clk_hw_get_name(&vc5->clk_out[n - 1].hw);
memset(&init, 0, sizeof(init));
- init.name = vc5_clk_out_names[idx + 1];
+ init.name = kasprintf(GFP_KERNEL, "%pOFn.out%d",
+ client->dev.of_node, idx + 1);
init.ops = &vc5_clk_out_ops;
init.flags = CLK_SET_RATE_PARENT;
init.parent_names = parent_names;
@@ -866,13 +1001,15 @@ static int vc5_probe(struct i2c_client *client,
vc5->clk_out[n].num = idx;
vc5->clk_out[n].vc5 = vc5;
vc5->clk_out[n].hw.init = &init;
- ret = devm_clk_hw_register(&client->dev,
- &vc5->clk_out[n].hw);
- if (ret) {
- dev_err(&client->dev, "unable to register %s\n",
- init.name);
+ ret = devm_clk_hw_register(&client->dev, &vc5->clk_out[n].hw);
+ if (ret)
+ goto err_clk_register;
+ kfree(init.name); /* clock framework made a copy of the name */
+
+ /* Fetch Clock Output configuration from DT (if specified) */
+ ret = vc5_get_output_config(client, &vc5->clk_out[n]);
+ if (ret)
goto err_clk;
- }
}
ret = of_clk_add_hw_provider(client->dev.of_node, vc5_of_clk_get, vc5);
@@ -883,6 +1020,9 @@ static int vc5_probe(struct i2c_client *client,
return 0;
+err_clk_register:
+ dev_err(&client->dev, "unable to register %s\n", init.name);
+ kfree(init.name); /* clock framework made a copy of the name */
err_clk:
if (vc5->chip_info->flags & VC5_HAS_INTERNAL_XTAL)
clk_unregister_fixed_rate(vc5->pin_xin);
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 3f588ed06ce3..8aed0c3ff122 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -1400,6 +1400,21 @@ int __clk_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
}
EXPORT_SYMBOL_GPL(__clk_determine_rate);
+/**
+ * clk_hw_round_rate() - round the given rate for a hw clk
+ * @hw: the hw clk for which we are rounding a rate
+ * @rate: the rate which is to be rounded
+ *
+ * Takes in a rate as input and rounds it to a rate that the clk can actually
+ * use.
+ *
+ * Context: prepare_lock must be held.
+ * For clk providers to call from within clk_ops such as .round_rate,
+ * .determine_rate.
+ *
+ * Return: returns rounded rate of hw clk if clk supports round_rate operation
+ * else returns the parent rate.
+ */
unsigned long clk_hw_round_rate(struct clk_hw *hw, unsigned long rate)
{
int ret;
@@ -3039,6 +3054,31 @@ static int clk_rate_set(void *data, u64 val)
}
#define clk_rate_mode 0644
+
+static int clk_prepare_enable_set(void *data, u64 val)
+{
+ struct clk_core *core = data;
+ int ret = 0;
+
+ if (val)
+ ret = clk_prepare_enable(core->hw->clk);
+ else
+ clk_disable_unprepare(core->hw->clk);
+
+ return ret;
+}
+
+static int clk_prepare_enable_get(void *data, u64 *val)
+{
+ struct clk_core *core = data;
+
+ *val = core->enable_count && core->prepare_count;
+ return 0;
+}
+
+DEFINE_DEBUGFS_ATTRIBUTE(clk_prepare_enable_fops, clk_prepare_enable_get,
+ clk_prepare_enable_set, "%llu\n");
+
#else
#define clk_rate_set NULL
#define clk_rate_mode 0444
@@ -3216,6 +3256,10 @@ static void clk_debug_create_one(struct clk_core *core, struct dentry *pdentry)
debugfs_create_u32("clk_notifier_count", 0444, root, &core->notifier_count);
debugfs_create_file("clk_duty_cycle", 0444, root, core,
&clk_duty_cycle_fops);
+#ifdef CLOCK_ALLOW_WRITE_DEBUGFS
+ debugfs_create_file("clk_prepare_enable", 0644, root, core,
+ &clk_prepare_enable_fops);
+#endif
if (core->num_parents > 0)
debugfs_create_file("clk_parent", 0444, root, core,
@@ -4120,6 +4164,7 @@ static int devm_clk_hw_match(struct device *dev, void *res, void *data)
/**
* devm_clk_unregister - resource managed clk_unregister()
+ * @dev: device that is unregistering the clock data
* @clk: clock to unregister
*
* Deallocate a clock allocated with devm_clk_register(). Normally
@@ -4309,6 +4354,8 @@ static void clk_core_reparent_orphans(void)
* @node: Pointer to device tree node of clock provider
* @get: Get clock callback. Returns NULL or a struct clk for the
* given clock specifier
+ * @get_hw: Get clk_hw callback. Returns NULL, ERR_PTR or a
+ * struct clk_hw for the given clock specifier
* @data: context pointer to be passed into @get callback
*/
struct of_clk_provider {
diff --git a/drivers/clk/davinci/pll.c b/drivers/clk/davinci/pll.c
index 8a23d5dfd1f8..6c35e4bb7940 100644
--- a/drivers/clk/davinci/pll.c
+++ b/drivers/clk/davinci/pll.c
@@ -651,7 +651,7 @@ static int davinci_pll_sysclk_rate_change(struct notifier_block *nb,
pllcmd = readl(pll->base + PLLCMD);
pllcmd |= PLLCMD_GOSET;
writel(pllcmd, pll->base + PLLCMD);
- /* fallthrough */
+ fallthrough;
case PRE_RATE_CHANGE:
/* Wait until for outstanding changes to take effect */
do {
diff --git a/drivers/clk/imx/clk-imx8mp.c b/drivers/clk/imx/clk-imx8mp.c
index b4d9db9d5bf1..ca747712400f 100644
--- a/drivers/clk/imx/clk-imx8mp.c
+++ b/drivers/clk/imx/clk-imx8mp.c
@@ -680,6 +680,7 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
hws[IMX8MP_CLK_I2C2_ROOT] = imx_clk_hw_gate4("i2c2_root_clk", "i2c2", ccm_base + 0x4180, 0);
hws[IMX8MP_CLK_I2C3_ROOT] = imx_clk_hw_gate4("i2c3_root_clk", "i2c3", ccm_base + 0x4190, 0);
hws[IMX8MP_CLK_I2C4_ROOT] = imx_clk_hw_gate4("i2c4_root_clk", "i2c4", ccm_base + 0x41a0, 0);
+ hws[IMX8MP_CLK_MU_ROOT] = imx_clk_hw_gate4("mu_root_clk", "ipg_root", ccm_base + 0x4210, 0);
hws[IMX8MP_CLK_OCOTP_ROOT] = imx_clk_hw_gate4("ocotp_root_clk", "ipg_root", ccm_base + 0x4220, 0);
hws[IMX8MP_CLK_PCIE_ROOT] = imx_clk_hw_gate4("pcie_root_clk", "pcie_aux", ccm_base + 0x4250, 0);
hws[IMX8MP_CLK_PWM1_ROOT] = imx_clk_hw_gate4("pwm1_root_clk", "pwm1", ccm_base + 0x4280, 0);
diff --git a/drivers/clk/imx/clk-pllv3.c b/drivers/clk/imx/clk-pllv3.c
index a7db93030e02..b20cdea3e9cc 100644
--- a/drivers/clk/imx/clk-pllv3.c
+++ b/drivers/clk/imx/clk-pllv3.c
@@ -433,7 +433,7 @@ struct clk_hw *imx_clk_hw_pllv3(enum imx_pllv3_type type, const char *name,
break;
case IMX_PLLV3_USB_VF610:
pll->div_shift = 1;
- /* fall through */
+ fallthrough;
case IMX_PLLV3_USB:
ops = &clk_pllv3_ops;
pll->powerup_set = true;
@@ -441,7 +441,7 @@ struct clk_hw *imx_clk_hw_pllv3(enum imx_pllv3_type type, const char *name,
case IMX_PLLV3_AV_IMX7:
pll->num_offset = PLL_IMX7_NUM_OFFSET;
pll->denom_offset = PLL_IMX7_DENOM_OFFSET;
- /* fall through */
+ fallthrough;
case IMX_PLLV3_AV:
ops = &clk_pllv3_av_ops;
break;
diff --git a/drivers/clk/imx/clk-vf610.c b/drivers/clk/imx/clk-vf610.c
index cd04e7dc1878..5129ef8e1d6e 100644
--- a/drivers/clk/imx/clk-vf610.c
+++ b/drivers/clk/imx/clk-vf610.c
@@ -438,6 +438,7 @@ static void __init vf610_clocks_init(struct device_node *ccm_node)
clk[VF610_CLK_SNVS] = imx_clk_gate2("snvs-rtc", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(7));
clk[VF610_CLK_DAP] = imx_clk_gate("dap", "platform_bus", CCM_CCSR, 24);
clk[VF610_CLK_OCOTP] = imx_clk_gate("ocotp", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(5));
+ clk[VF610_CLK_CAAM] = imx_clk_gate2("caam", "ipg_bus", CCM_CCGR11, CCM_CCGRx_CGn(0));
imx_check_clocks(clk, ARRAY_SIZE(clk));
diff --git a/drivers/clk/ingenic/jz4780-cgu.c b/drivers/clk/ingenic/jz4780-cgu.c
index 6c5b8029cc8a..0268d23ebe2e 100644
--- a/drivers/clk/ingenic/jz4780-cgu.c
+++ b/drivers/clk/ingenic/jz4780-cgu.c
@@ -4,6 +4,7 @@
*
* Copyright (c) 2013-2015 Imagination Technologies
* Author: Paul Burton <paul.burton@mips.com>
+ * Copyright (c) 2020 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com>
*/
#include <linux/clk-provider.h>
@@ -19,49 +20,50 @@
/* CGU register offsets */
#define CGU_REG_CLOCKCONTROL 0x00
-#define CGU_REG_LCR 0x04
-#define CGU_REG_APLL 0x10
-#define CGU_REG_MPLL 0x14
-#define CGU_REG_EPLL 0x18
-#define CGU_REG_VPLL 0x1c
-#define CGU_REG_CLKGR0 0x20
-#define CGU_REG_OPCR 0x24
-#define CGU_REG_CLKGR1 0x28
-#define CGU_REG_DDRCDR 0x2c
-#define CGU_REG_VPUCDR 0x30
-#define CGU_REG_USBPCR 0x3c
-#define CGU_REG_USBRDT 0x40
-#define CGU_REG_USBVBFIL 0x44
-#define CGU_REG_USBPCR1 0x48
-#define CGU_REG_LP0CDR 0x54
-#define CGU_REG_I2SCDR 0x60
-#define CGU_REG_LP1CDR 0x64
-#define CGU_REG_MSC0CDR 0x68
-#define CGU_REG_UHCCDR 0x6c
-#define CGU_REG_SSICDR 0x74
-#define CGU_REG_CIMCDR 0x7c
-#define CGU_REG_PCMCDR 0x84
-#define CGU_REG_GPUCDR 0x88
-#define CGU_REG_HDMICDR 0x8c
-#define CGU_REG_MSC1CDR 0xa4
-#define CGU_REG_MSC2CDR 0xa8
-#define CGU_REG_BCHCDR 0xac
-#define CGU_REG_CLOCKSTATUS 0xd4
+#define CGU_REG_LCR 0x04
+#define CGU_REG_APLL 0x10
+#define CGU_REG_MPLL 0x14
+#define CGU_REG_EPLL 0x18
+#define CGU_REG_VPLL 0x1c
+#define CGU_REG_CLKGR0 0x20
+#define CGU_REG_OPCR 0x24
+#define CGU_REG_CLKGR1 0x28
+#define CGU_REG_DDRCDR 0x2c
+#define CGU_REG_VPUCDR 0x30
+#define CGU_REG_USBPCR 0x3c
+#define CGU_REG_USBRDT 0x40
+#define CGU_REG_USBVBFIL 0x44
+#define CGU_REG_USBPCR1 0x48
+#define CGU_REG_LP0CDR 0x54
+#define CGU_REG_I2SCDR 0x60
+#define CGU_REG_LP1CDR 0x64
+#define CGU_REG_MSC0CDR 0x68
+#define CGU_REG_UHCCDR 0x6c
+#define CGU_REG_SSICDR 0x74
+#define CGU_REG_CIMCDR 0x7c
+#define CGU_REG_PCMCDR 0x84
+#define CGU_REG_GPUCDR 0x88
+#define CGU_REG_HDMICDR 0x8c
+#define CGU_REG_MSC1CDR 0xa4
+#define CGU_REG_MSC2CDR 0xa8
+#define CGU_REG_BCHCDR 0xac
+#define CGU_REG_CLOCKSTATUS 0xd4
/* bits within the OPCR register */
-#define OPCR_SPENDN0 BIT(7)
-#define OPCR_SPENDN1 BIT(6)
+#define OPCR_SPENDN0 BIT(7)
+#define OPCR_SPENDN1 BIT(6)
/* bits within the USBPCR register */
-#define USBPCR_USB_MODE BIT(31)
+#define USBPCR_USB_MODE BIT(31)
#define USBPCR_IDPULLUP_MASK (0x3 << 28)
-#define USBPCR_COMMONONN BIT(25)
-#define USBPCR_VBUSVLDEXT BIT(24)
+#define USBPCR_COMMONONN BIT(25)
+#define USBPCR_VBUSVLDEXT BIT(24)
#define USBPCR_VBUSVLDEXTSEL BIT(23)
-#define USBPCR_POR BIT(22)
-#define USBPCR_OTG_DISABLE BIT(20)
+#define USBPCR_POR BIT(22)
+#define USBPCR_SIDDQ BIT(21)
+#define USBPCR_OTG_DISABLE BIT(20)
#define USBPCR_COMPDISTUNE_MASK (0x7 << 17)
-#define USBPCR_OTGTUNE_MASK (0x7 << 14)
+#define USBPCR_OTGTUNE_MASK (0x7 << 14)
#define USBPCR_SQRXTUNE_MASK (0x7 << 11)
#define USBPCR_TXFSLSTUNE_MASK (0xf << 7)
#define USBPCR_TXPREEMPHTUNE BIT(6)
@@ -78,13 +80,13 @@
#define USBPCR1_REFCLKDIV_48 (0x2 << USBPCR1_REFCLKDIV_SHIFT)
#define USBPCR1_REFCLKDIV_24 (0x1 << USBPCR1_REFCLKDIV_SHIFT)
#define USBPCR1_REFCLKDIV_12 (0x0 << USBPCR1_REFCLKDIV_SHIFT)
-#define USBPCR1_USB_SEL BIT(28)
-#define USBPCR1_WORD_IF0 BIT(19)
-#define USBPCR1_WORD_IF1 BIT(18)
+#define USBPCR1_USB_SEL BIT(28)
+#define USBPCR1_WORD_IF0 BIT(19)
+#define USBPCR1_WORD_IF1 BIT(18)
/* bits within the USBRDT register */
-#define USBRDT_VBFIL_LD_EN BIT(25)
-#define USBRDT_USBRDT_MASK 0x7fffff
+#define USBRDT_VBFIL_LD_EN BIT(25)
+#define USBRDT_USBRDT_MASK 0x7fffff
/* bits within the USBVBFIL register */
#define USBVBFIL_IDDIGFIL_SHIFT 16
@@ -92,40 +94,14 @@
#define USBVBFIL_USBVBFIL_MASK (0xffff)
/* bits within the LCR register */
-#define LCR_PD_SCPU BIT(31)
-#define LCR_SCPUS BIT(27)
+#define LCR_PD_SCPU BIT(31)
+#define LCR_SCPUS BIT(27)
/* bits within the CLKGR1 register */
-#define CLKGR1_CORE1 BIT(15)
+#define CLKGR1_CORE1 BIT(15)
static struct ingenic_cgu *cgu;
-static u8 jz4780_otg_phy_get_parent(struct clk_hw *hw)
-{
- /* we only use CLKCORE, revisit if that ever changes */
- return 0;
-}
-
-static int jz4780_otg_phy_set_parent(struct clk_hw *hw, u8 idx)
-{
- unsigned long flags;
- u32 usbpcr1;
-
- if (idx > 0)
- return -EINVAL;
-
- spin_lock_irqsave(&cgu->lock, flags);
-
- usbpcr1 = readl(cgu->base + CGU_REG_USBPCR1);
- usbpcr1 &= ~USBPCR1_REFCLKSEL_MASK;
- /* we only use CLKCORE */
- usbpcr1 |= USBPCR1_REFCLKSEL_CORE;
- writel(usbpcr1, cgu->base + CGU_REG_USBPCR1);
-
- spin_unlock_irqrestore(&cgu->lock, flags);
- return 0;
-}
-
static unsigned long jz4780_otg_phy_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
@@ -149,7 +125,6 @@ static unsigned long jz4780_otg_phy_recalc_rate(struct clk_hw *hw,
return 19200000;
}
- BUG();
return parent_rate;
}
@@ -206,13 +181,43 @@ static int jz4780_otg_phy_set_rate(struct clk_hw *hw, unsigned long req_rate,
return 0;
}
-static const struct clk_ops jz4780_otg_phy_ops = {
- .get_parent = jz4780_otg_phy_get_parent,
- .set_parent = jz4780_otg_phy_set_parent,
+static int jz4780_otg_phy_enable(struct clk_hw *hw)
+{
+ void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR;
+ void __iomem *reg_usbpcr = cgu->base + CGU_REG_USBPCR;
+
+ writel(readl(reg_opcr) | OPCR_SPENDN0, reg_opcr);
+ writel(readl(reg_usbpcr) & ~USBPCR_OTG_DISABLE & ~USBPCR_SIDDQ, reg_usbpcr);
+ return 0;
+}
+static void jz4780_otg_phy_disable(struct clk_hw *hw)
+{
+ void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR;
+ void __iomem *reg_usbpcr = cgu->base + CGU_REG_USBPCR;
+
+ writel(readl(reg_opcr) & ~OPCR_SPENDN0, reg_opcr);
+ writel(readl(reg_usbpcr) | USBPCR_OTG_DISABLE | USBPCR_SIDDQ, reg_usbpcr);
+}
+
+static int jz4780_otg_phy_is_enabled(struct clk_hw *hw)
+{
+ void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR;
+ void __iomem *reg_usbpcr = cgu->base + CGU_REG_USBPCR;
+
+ return (readl(reg_opcr) & OPCR_SPENDN0) &&
+ !(readl(reg_usbpcr) & USBPCR_SIDDQ) &&
+ !(readl(reg_usbpcr) & USBPCR_OTG_DISABLE);
+}
+
+static const struct clk_ops jz4780_otg_phy_ops = {
.recalc_rate = jz4780_otg_phy_recalc_rate,
.round_rate = jz4780_otg_phy_round_rate,
.set_rate = jz4780_otg_phy_set_rate,
+
+ .enable = jz4780_otg_phy_enable,
+ .disable = jz4780_otg_phy_disable,
+ .is_enabled = jz4780_otg_phy_is_enabled,
};
static int jz4780_core1_enable(struct clk_hw *hw)
@@ -516,6 +521,18 @@ static const struct ingenic_cgu_clk_info jz4780_cgu_clocks[] = {
.gate = { CGU_REG_CLKGR0, 1 },
},
+ [JZ4780_CLK_EXCLK_DIV512] = {
+ "exclk_div512", CGU_CLK_FIXDIV,
+ .parents = { JZ4780_CLK_EXCLK },
+ .fixdiv = { 512 },
+ },
+
+ [JZ4780_CLK_RTC] = {
+ "rtc_ercs", CGU_CLK_MUX | CGU_CLK_GATE,
+ .parents = { JZ4780_CLK_EXCLK_DIV512, JZ4780_CLK_RTCLK },
+ .mux = { CGU_REG_OPCR, 2, 1},
+ },
+
/* Gate-only clocks */
[JZ4780_CLK_NEMC] = {
diff --git a/drivers/clk/ingenic/x1000-cgu.c b/drivers/clk/ingenic/x1000-cgu.c
index 453f3323cb99..9aa20b52e1c3 100644
--- a/drivers/clk/ingenic/x1000-cgu.c
+++ b/drivers/clk/ingenic/x1000-cgu.c
@@ -48,8 +48,87 @@
#define USBPCR_SIDDQ BIT(21)
#define USBPCR_OTG_DISABLE BIT(20)
+/* bits within the USBPCR1 register */
+#define USBPCR1_REFCLKSEL_SHIFT 26
+#define USBPCR1_REFCLKSEL_MASK (0x3 << USBPCR1_REFCLKSEL_SHIFT)
+#define USBPCR1_REFCLKSEL_CORE (0x2 << USBPCR1_REFCLKSEL_SHIFT)
+#define USBPCR1_REFCLKDIV_SHIFT 24
+#define USBPCR1_REFCLKDIV_MASK (0x3 << USBPCR1_REFCLKDIV_SHIFT)
+#define USBPCR1_REFCLKDIV_48 (0x2 << USBPCR1_REFCLKDIV_SHIFT)
+#define USBPCR1_REFCLKDIV_24 (0x1 << USBPCR1_REFCLKDIV_SHIFT)
+#define USBPCR1_REFCLKDIV_12 (0x0 << USBPCR1_REFCLKDIV_SHIFT)
+
static struct ingenic_cgu *cgu;
+static unsigned long x1000_otg_phy_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ u32 usbpcr1;
+ unsigned refclk_div;
+
+ usbpcr1 = readl(cgu->base + CGU_REG_USBPCR1);
+ refclk_div = usbpcr1 & USBPCR1_REFCLKDIV_MASK;
+
+ switch (refclk_div) {
+ case USBPCR1_REFCLKDIV_12:
+ return 12000000;
+
+ case USBPCR1_REFCLKDIV_24:
+ return 24000000;
+
+ case USBPCR1_REFCLKDIV_48:
+ return 48000000;
+ }
+
+ return parent_rate;
+}
+
+static long x1000_otg_phy_round_rate(struct clk_hw *hw, unsigned long req_rate,
+ unsigned long *parent_rate)
+{
+ if (req_rate < 18000000)
+ return 12000000;
+
+ if (req_rate < 36000000)
+ return 24000000;
+
+ return 48000000;
+}
+
+static int x1000_otg_phy_set_rate(struct clk_hw *hw, unsigned long req_rate,
+ unsigned long parent_rate)
+{
+ unsigned long flags;
+ u32 usbpcr1, div_bits;
+
+ switch (req_rate) {
+ case 12000000:
+ div_bits = USBPCR1_REFCLKDIV_12;
+ break;
+
+ case 24000000:
+ div_bits = USBPCR1_REFCLKDIV_24;
+ break;
+
+ case 48000000:
+ div_bits = USBPCR1_REFCLKDIV_48;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ spin_lock_irqsave(&cgu->lock, flags);
+
+ usbpcr1 = readl(cgu->base + CGU_REG_USBPCR1);
+ usbpcr1 &= ~USBPCR1_REFCLKDIV_MASK;
+ usbpcr1 |= div_bits;
+ writel(usbpcr1, cgu->base + CGU_REG_USBPCR1);
+
+ spin_unlock_irqrestore(&cgu->lock, flags);
+ return 0;
+}
+
static int x1000_usb_phy_enable(struct clk_hw *hw)
{
void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR;
@@ -80,6 +159,10 @@ static int x1000_usb_phy_is_enabled(struct clk_hw *hw)
}
static const struct clk_ops x1000_otg_phy_ops = {
+ .recalc_rate = x1000_otg_phy_recalc_rate,
+ .round_rate = x1000_otg_phy_round_rate,
+ .set_rate = x1000_otg_phy_set_rate,
+
.enable = x1000_usb_phy_enable,
.disable = x1000_usb_phy_disable,
.is_enabled = x1000_usb_phy_is_enabled,
@@ -144,7 +227,6 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
},
},
-
/* Custom (SoC-specific) OTG PHY */
[X1000_CLK_OTGPHY] = {
@@ -278,6 +360,19 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
.mux = { CGU_REG_SSICDR, 30, 1 },
},
+ [X1000_CLK_EXCLK_DIV512] = {
+ "exclk_div512", CGU_CLK_FIXDIV,
+ .parents = { X1000_CLK_EXCLK },
+ .fixdiv = { 512 },
+ },
+
+ [X1000_CLK_RTC] = {
+ "rtc_ercs", CGU_CLK_MUX | CGU_CLK_GATE,
+ .parents = { X1000_CLK_EXCLK_DIV512, X1000_CLK_RTCLK },
+ .mux = { CGU_REG_OPCR, 2, 1},
+ .gate = { CGU_REG_CLKGR, 27 },
+ },
+
/* Gate-only clocks */
[X1000_CLK_EMC] = {
diff --git a/drivers/clk/ingenic/x1830-cgu.c b/drivers/clk/ingenic/x1830-cgu.c
index a1b2ff0ee487..950aee243364 100644
--- a/drivers/clk/ingenic/x1830-cgu.c
+++ b/drivers/clk/ingenic/x1830-cgu.c
@@ -329,6 +329,19 @@ static const struct ingenic_cgu_clk_info x1830_cgu_clocks[] = {
.mux = { CGU_REG_SSICDR, 29, 1 },
},
+ [X1830_CLK_EXCLK_DIV512] = {
+ "exclk_div512", CGU_CLK_FIXDIV,
+ .parents = { X1830_CLK_EXCLK },
+ .fixdiv = { 512 },
+ },
+
+ [X1830_CLK_RTC] = {
+ "rtc_ercs", CGU_CLK_MUX | CGU_CLK_GATE,
+ .parents = { X1830_CLK_EXCLK_DIV512, X1830_CLK_RTCLK },
+ .mux = { CGU_REG_OPCR, 2, 1},
+ .gate = { CGU_REG_CLKGR0, 29 },
+ },
+
/* Gate-only clocks */
[X1830_CLK_EMC] = {
diff --git a/drivers/clk/keystone/sci-clk.c b/drivers/clk/keystone/sci-clk.c
index 7edf8c8432b6..2ad26cb927fd 100644
--- a/drivers/clk/keystone/sci-clk.c
+++ b/drivers/clk/keystone/sci-clk.c
@@ -1,7 +1,7 @@
/*
* SCI Clock driver for keystone based devices
*
- * Copyright (C) 2015-2016 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2015-2016 Texas Instruments Incorporated - https://www.ti.com/
* Tero Kristo <t-kristo@ti.com>
*
* This program is free software; you can redistribute it and/or modify
diff --git a/drivers/clk/keystone/syscon-clk.c b/drivers/clk/keystone/syscon-clk.c
index 8d7dbea3bd30..5b3d36462174 100644
--- a/drivers/clk/keystone/syscon-clk.c
+++ b/drivers/clk/keystone/syscon-clk.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
/*
- * Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2020 Texas Instruments Incorporated - https://www.ti.com/
*/
#include <linux/clk-provider.h>
diff --git a/drivers/clk/meson/g12a.c b/drivers/clk/meson/g12a.c
index 30c15766ebb1..9803d44bb157 100644
--- a/drivers/clk/meson/g12a.c
+++ b/drivers/clk/meson/g12a.c
@@ -3981,6 +3981,113 @@ static struct clk_regmap g12a_spicc1_sclk = {
},
};
+/* Neural Network Accelerator source clock */
+
+static const struct clk_parent_data nna_clk_parent_data[] = {
+ { .fw_name = "xtal", },
+ { .hw = &g12a_gp0_pll.hw, },
+ { .hw = &g12a_hifi_pll.hw, },
+ { .hw = &g12a_fclk_div2p5.hw, },
+ { .hw = &g12a_fclk_div3.hw, },
+ { .hw = &g12a_fclk_div4.hw, },
+ { .hw = &g12a_fclk_div5.hw, },
+ { .hw = &g12a_fclk_div7.hw },
+};
+
+static struct clk_regmap sm1_nna_axi_clk_sel = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = HHI_NNA_CLK_CNTL,
+ .mask = 7,
+ .shift = 9,
+ },
+ .hw.init = &(struct clk_init_data){
+ .name = "nna_axi_clk_sel",
+ .ops = &clk_regmap_mux_ops,
+ .parent_data = nna_clk_parent_data,
+ .num_parents = ARRAY_SIZE(nna_clk_parent_data),
+ },
+};
+
+static struct clk_regmap sm1_nna_axi_clk_div = {
+ .data = &(struct clk_regmap_div_data){
+ .offset = HHI_NNA_CLK_CNTL,
+ .shift = 0,
+ .width = 7,
+ },
+ .hw.init = &(struct clk_init_data){
+ .name = "nna_axi_clk_div",
+ .ops = &clk_regmap_divider_ops,
+ .parent_hws = (const struct clk_hw *[]) {
+ &sm1_nna_axi_clk_sel.hw
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+static struct clk_regmap sm1_nna_axi_clk = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = HHI_NNA_CLK_CNTL,
+ .bit_idx = 8,
+ },
+ .hw.init = &(struct clk_init_data){
+ .name = "nna_axi_clk",
+ .ops = &clk_regmap_gate_ops,
+ .parent_hws = (const struct clk_hw *[]) {
+ &sm1_nna_axi_clk_div.hw
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+static struct clk_regmap sm1_nna_core_clk_sel = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = HHI_NNA_CLK_CNTL,
+ .mask = 7,
+ .shift = 25,
+ },
+ .hw.init = &(struct clk_init_data){
+ .name = "nna_core_clk_sel",
+ .ops = &clk_regmap_mux_ops,
+ .parent_data = nna_clk_parent_data,
+ .num_parents = ARRAY_SIZE(nna_clk_parent_data),
+ },
+};
+
+static struct clk_regmap sm1_nna_core_clk_div = {
+ .data = &(struct clk_regmap_div_data){
+ .offset = HHI_NNA_CLK_CNTL,
+ .shift = 16,
+ .width = 7,
+ },
+ .hw.init = &(struct clk_init_data){
+ .name = "nna_core_clk_div",
+ .ops = &clk_regmap_divider_ops,
+ .parent_hws = (const struct clk_hw *[]) {
+ &sm1_nna_core_clk_sel.hw
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+static struct clk_regmap sm1_nna_core_clk = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = HHI_NNA_CLK_CNTL,
+ .bit_idx = 24,
+ },
+ .hw.init = &(struct clk_init_data){
+ .name = "nna_core_clk",
+ .ops = &clk_regmap_gate_ops,
+ .parent_hws = (const struct clk_hw *[]) {
+ &sm1_nna_core_clk_div.hw
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
#define MESON_GATE(_name, _reg, _bit) \
MESON_PCLK(_name, _reg, _bit, &g12a_clk81.hw)
@@ -4779,6 +4886,12 @@ static struct clk_hw_onecell_data sm1_hw_onecell_data = {
[CLKID_SPICC1_SCLK_SEL] = &g12a_spicc1_sclk_sel.hw,
[CLKID_SPICC1_SCLK_DIV] = &g12a_spicc1_sclk_div.hw,
[CLKID_SPICC1_SCLK] = &g12a_spicc1_sclk.hw,
+ [CLKID_NNA_AXI_CLK_SEL] = &sm1_nna_axi_clk_sel.hw,
+ [CLKID_NNA_AXI_CLK_DIV] = &sm1_nna_axi_clk_div.hw,
+ [CLKID_NNA_AXI_CLK] = &sm1_nna_axi_clk.hw,
+ [CLKID_NNA_CORE_CLK_SEL] = &sm1_nna_core_clk_sel.hw,
+ [CLKID_NNA_CORE_CLK_DIV] = &sm1_nna_core_clk_div.hw,
+ [CLKID_NNA_CORE_CLK] = &sm1_nna_core_clk.hw,
[NR_CLKS] = NULL,
},
.num = NR_CLKS,
@@ -5020,6 +5133,12 @@ static struct clk_regmap *const g12a_clk_regmaps[] = {
&g12a_spicc1_sclk_sel,
&g12a_spicc1_sclk_div,
&g12a_spicc1_sclk,
+ &sm1_nna_axi_clk_sel,
+ &sm1_nna_axi_clk_div,
+ &sm1_nna_axi_clk,
+ &sm1_nna_core_clk_sel,
+ &sm1_nna_core_clk_div,
+ &sm1_nna_core_clk,
};
static const struct reg_sequence g12a_init_regs[] = {
diff --git a/drivers/clk/meson/g12a.h b/drivers/clk/meson/g12a.h
index a8852556836e..69b6a69549c7 100644
--- a/drivers/clk/meson/g12a.h
+++ b/drivers/clk/meson/g12a.h
@@ -70,6 +70,7 @@
#define HHI_MALI_CLK_CNTL 0x1b0
#define HHI_VPU_CLKC_CNTL 0x1b4
#define HHI_VPU_CLK_CNTL 0x1bC
+#define HHI_NNA_CLK_CNTL 0x1C8
#define HHI_HDMI_CLK_CNTL 0x1CC
#define HHI_VDEC_CLK_CNTL 0x1E0
#define HHI_VDEC2_CLK_CNTL 0x1E4
@@ -259,8 +260,12 @@
#define CLKID_SPICC0_SCLK_DIV 257
#define CLKID_SPICC1_SCLK_SEL 259
#define CLKID_SPICC1_SCLK_DIV 260
+#define CLKID_NNA_AXI_CLK_SEL 262
+#define CLKID_NNA_AXI_CLK_DIV 263
+#define CLKID_NNA_CORE_CLK_SEL 265
+#define CLKID_NNA_CORE_CLK_DIV 266
-#define NR_CLKS 262
+#define NR_CLKS 268
/* include the CLKIDs that have been made part of the DT binding */
#include <dt-bindings/clock/g12a-clkc.h>
diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c
index edc09d050ecf..862f0756b50f 100644
--- a/drivers/clk/meson/meson8b.c
+++ b/drivers/clk/meson/meson8b.c
@@ -293,13 +293,6 @@ static struct clk_regmap meson8b_fclk_div2 = {
&meson8b_fclk_div2_div.hw
},
.num_parents = 1,
- /*
- * FIXME: Ethernet with a RGMII PHYs is not working if
- * fclk_div2 is disabled. it is currently unclear why this
- * is. keep it enabled until the Ethernet driver knows how
- * to manage this clock.
- */
- .flags = CLK_IS_CRITICAL,
},
};
@@ -1211,6 +1204,22 @@ static struct clk_regmap meson8b_vclk_in_en = {
},
};
+static struct clk_regmap meson8b_vclk_en = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = HHI_VID_CLK_CNTL,
+ .bit_idx = 19,
+ },
+ .hw.init = &(struct clk_init_data){
+ .name = "vclk_en",
+ .ops = &clk_regmap_gate_ro_ops,
+ .parent_hws = (const struct clk_hw *[]) {
+ &meson8b_vclk_in_en.hw
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
static struct clk_regmap meson8b_vclk_div1_gate = {
.data = &(struct clk_regmap_gate_data){
.offset = HHI_VID_CLK_CNTL,
@@ -1220,7 +1229,7 @@ static struct clk_regmap meson8b_vclk_div1_gate = {
.name = "vclk_div1_en",
.ops = &clk_regmap_gate_ro_ops,
.parent_hws = (const struct clk_hw *[]) {
- &meson8b_vclk_in_en.hw
+ &meson8b_vclk_en.hw
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
@@ -1234,7 +1243,7 @@ static struct clk_fixed_factor meson8b_vclk_div2_div = {
.name = "vclk_div2",
.ops = &clk_fixed_factor_ops,
.parent_hws = (const struct clk_hw *[]) {
- &meson8b_vclk_in_en.hw
+ &meson8b_vclk_en.hw
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
@@ -1264,7 +1273,7 @@ static struct clk_fixed_factor meson8b_vclk_div4_div = {
.name = "vclk_div4",
.ops = &clk_fixed_factor_ops,
.parent_hws = (const struct clk_hw *[]) {
- &meson8b_vclk_in_en.hw
+ &meson8b_vclk_en.hw
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
@@ -1294,7 +1303,7 @@ static struct clk_fixed_factor meson8b_vclk_div6_div = {
.name = "vclk_div6",
.ops = &clk_fixed_factor_ops,
.parent_hws = (const struct clk_hw *[]) {
- &meson8b_vclk_in_en.hw
+ &meson8b_vclk_en.hw
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
@@ -1324,7 +1333,7 @@ static struct clk_fixed_factor meson8b_vclk_div12_div = {
.name = "vclk_div12",
.ops = &clk_fixed_factor_ops,
.parent_hws = (const struct clk_hw *[]) {
- &meson8b_vclk_in_en.hw
+ &meson8b_vclk_en.hw
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
@@ -1378,6 +1387,22 @@ static struct clk_regmap meson8b_vclk2_clk_in_en = {
},
};
+static struct clk_regmap meson8b_vclk2_clk_en = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = HHI_VIID_CLK_DIV,
+ .bit_idx = 19,
+ },
+ .hw.init = &(struct clk_init_data){
+ .name = "vclk2_en",
+ .ops = &clk_regmap_gate_ro_ops,
+ .parent_hws = (const struct clk_hw *[]) {
+ &meson8b_vclk2_clk_in_en.hw
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
static struct clk_regmap meson8b_vclk2_div1_gate = {
.data = &(struct clk_regmap_gate_data){
.offset = HHI_VIID_CLK_DIV,
@@ -1387,7 +1412,7 @@ static struct clk_regmap meson8b_vclk2_div1_gate = {
.name = "vclk2_div1_en",
.ops = &clk_regmap_gate_ro_ops,
.parent_hws = (const struct clk_hw *[]) {
- &meson8b_vclk2_clk_in_en.hw
+ &meson8b_vclk2_clk_en.hw
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
@@ -1401,7 +1426,7 @@ static struct clk_fixed_factor meson8b_vclk2_div2_div = {
.name = "vclk2_div2",
.ops = &clk_fixed_factor_ops,
.parent_hws = (const struct clk_hw *[]) {
- &meson8b_vclk2_clk_in_en.hw
+ &meson8b_vclk2_clk_en.hw
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
@@ -1431,7 +1456,7 @@ static struct clk_fixed_factor meson8b_vclk2_div4_div = {
.name = "vclk2_div4",
.ops = &clk_fixed_factor_ops,
.parent_hws = (const struct clk_hw *[]) {
- &meson8b_vclk2_clk_in_en.hw
+ &meson8b_vclk2_clk_en.hw
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
@@ -1461,7 +1486,7 @@ static struct clk_fixed_factor meson8b_vclk2_div6_div = {
.name = "vclk2_div6",
.ops = &clk_fixed_factor_ops,
.parent_hws = (const struct clk_hw *[]) {
- &meson8b_vclk2_clk_in_en.hw
+ &meson8b_vclk2_clk_en.hw
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
@@ -1491,7 +1516,7 @@ static struct clk_fixed_factor meson8b_vclk2_div12_div = {
.name = "vclk2_div12",
.ops = &clk_fixed_factor_ops,
.parent_hws = (const struct clk_hw *[]) {
- &meson8b_vclk2_clk_in_en.hw
+ &meson8b_vclk2_clk_en.hw
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
@@ -2827,6 +2852,7 @@ static struct clk_hw_onecell_data meson8_hw_onecell_data = {
[CLKID_VID_PLL_FINAL_DIV] = &meson8b_vid_pll_final_div.hw,
[CLKID_VCLK_IN_SEL] = &meson8b_vclk_in_sel.hw,
[CLKID_VCLK_IN_EN] = &meson8b_vclk_in_en.hw,
+ [CLKID_VCLK_EN] = &meson8b_vclk_en.hw,
[CLKID_VCLK_DIV1] = &meson8b_vclk_div1_gate.hw,
[CLKID_VCLK_DIV2_DIV] = &meson8b_vclk_div2_div.hw,
[CLKID_VCLK_DIV2] = &meson8b_vclk_div2_div_gate.hw,
@@ -2838,6 +2864,7 @@ static struct clk_hw_onecell_data meson8_hw_onecell_data = {
[CLKID_VCLK_DIV12] = &meson8b_vclk_div12_div_gate.hw,
[CLKID_VCLK2_IN_SEL] = &meson8b_vclk2_in_sel.hw,
[CLKID_VCLK2_IN_EN] = &meson8b_vclk2_clk_in_en.hw,
+ [CLKID_VCLK2_EN] = &meson8b_vclk2_clk_en.hw,
[CLKID_VCLK2_DIV1] = &meson8b_vclk2_div1_gate.hw,
[CLKID_VCLK2_DIV2_DIV] = &meson8b_vclk2_div2_div.hw,
[CLKID_VCLK2_DIV2] = &meson8b_vclk2_div2_div_gate.hw,
@@ -3032,6 +3059,7 @@ static struct clk_hw_onecell_data meson8b_hw_onecell_data = {
[CLKID_VID_PLL_FINAL_DIV] = &meson8b_vid_pll_final_div.hw,
[CLKID_VCLK_IN_SEL] = &meson8b_vclk_in_sel.hw,
[CLKID_VCLK_IN_EN] = &meson8b_vclk_in_en.hw,
+ [CLKID_VCLK_EN] = &meson8b_vclk_en.hw,
[CLKID_VCLK_DIV1] = &meson8b_vclk_div1_gate.hw,
[CLKID_VCLK_DIV2_DIV] = &meson8b_vclk_div2_div.hw,
[CLKID_VCLK_DIV2] = &meson8b_vclk_div2_div_gate.hw,
@@ -3043,6 +3071,7 @@ static struct clk_hw_onecell_data meson8b_hw_onecell_data = {
[CLKID_VCLK_DIV12] = &meson8b_vclk_div12_div_gate.hw,
[CLKID_VCLK2_IN_SEL] = &meson8b_vclk2_in_sel.hw,
[CLKID_VCLK2_IN_EN] = &meson8b_vclk2_clk_in_en.hw,
+ [CLKID_VCLK2_EN] = &meson8b_vclk2_clk_en.hw,
[CLKID_VCLK2_DIV1] = &meson8b_vclk2_div1_gate.hw,
[CLKID_VCLK2_DIV2_DIV] = &meson8b_vclk2_div2_div.hw,
[CLKID_VCLK2_DIV2] = &meson8b_vclk2_div2_div_gate.hw,
@@ -3248,6 +3277,7 @@ static struct clk_hw_onecell_data meson8m2_hw_onecell_data = {
[CLKID_VID_PLL_FINAL_DIV] = &meson8b_vid_pll_final_div.hw,
[CLKID_VCLK_IN_SEL] = &meson8b_vclk_in_sel.hw,
[CLKID_VCLK_IN_EN] = &meson8b_vclk_in_en.hw,
+ [CLKID_VCLK_EN] = &meson8b_vclk_en.hw,
[CLKID_VCLK_DIV1] = &meson8b_vclk_div1_gate.hw,
[CLKID_VCLK_DIV2_DIV] = &meson8b_vclk_div2_div.hw,
[CLKID_VCLK_DIV2] = &meson8b_vclk_div2_div_gate.hw,
@@ -3259,6 +3289,7 @@ static struct clk_hw_onecell_data meson8m2_hw_onecell_data = {
[CLKID_VCLK_DIV12] = &meson8b_vclk_div12_div_gate.hw,
[CLKID_VCLK2_IN_SEL] = &meson8b_vclk2_in_sel.hw,
[CLKID_VCLK2_IN_EN] = &meson8b_vclk2_clk_in_en.hw,
+ [CLKID_VCLK2_EN] = &meson8b_vclk2_clk_en.hw,
[CLKID_VCLK2_DIV1] = &meson8b_vclk2_div1_gate.hw,
[CLKID_VCLK2_DIV2_DIV] = &meson8b_vclk2_div2_div.hw,
[CLKID_VCLK2_DIV2] = &meson8b_vclk2_div2_div_gate.hw,
@@ -3450,6 +3481,7 @@ static struct clk_regmap *const meson8b_clk_regmaps[] = {
&meson8b_vid_pll_final_div,
&meson8b_vclk_in_sel,
&meson8b_vclk_in_en,
+ &meson8b_vclk_en,
&meson8b_vclk_div1_gate,
&meson8b_vclk_div2_div_gate,
&meson8b_vclk_div4_div_gate,
@@ -3457,6 +3489,7 @@ static struct clk_regmap *const meson8b_clk_regmaps[] = {
&meson8b_vclk_div12_div_gate,
&meson8b_vclk2_in_sel,
&meson8b_vclk2_clk_in_en,
+ &meson8b_vclk2_clk_en,
&meson8b_vclk2_div1_gate,
&meson8b_vclk2_div2_div_gate,
&meson8b_vclk2_div4_div_gate,
diff --git a/drivers/clk/meson/meson8b.h b/drivers/clk/meson/meson8b.h
index cd38ae2a9cb5..b1a5074cf148 100644
--- a/drivers/clk/meson/meson8b.h
+++ b/drivers/clk/meson/meson8b.h
@@ -17,7 +17,7 @@
* blocks below. Those offsets must be multiplied by 4 before adding them to
* the base address to get the right value
*
- * [0] http://dn.odroid.com/S805/Datasheet/S805_Datasheet%20V0.8%2020150126.pdf
+ * [0] https://dn.odroid.com/S805/Datasheet/S805_Datasheet%20V0.8%2020150126.pdf
*/
#define HHI_GP_PLL_CNTL 0x40 /* 0x10 offset in data sheet */
#define HHI_GP_PLL_CNTL2 0x44 /* 0x11 offset in data sheet */
@@ -180,8 +180,10 @@
#define CLKID_CTS_AMCLK_DIV 208
#define CLKID_CTS_MCLK_I958_SEL 210
#define CLKID_CTS_MCLK_I958_DIV 211
+#define CLKID_VCLK_EN 214
+#define CLKID_VCLK2_EN 215
-#define CLK_NR_CLKS 214
+#define CLK_NR_CLKS 216
/*
* include the CLKID and RESETID that have
diff --git a/drivers/clk/mvebu/Kconfig b/drivers/clk/mvebu/Kconfig
index ded07b0bd0d5..557d6213783c 100644
--- a/drivers/clk/mvebu/Kconfig
+++ b/drivers/clk/mvebu/Kconfig
@@ -42,6 +42,7 @@ config ARMADA_AP806_SYSCON
config ARMADA_AP_CPU_CLK
bool
+ select ARMADA_AP_CP_HELPER
config ARMADA_CP110_SYSCON
bool
diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index cde6ca90a06b..058327310c25 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -37,6 +37,15 @@ config QCOM_CLK_APCS_MSM8916
Say Y if you want to support CPU frequency scaling on devices
such as msm8916.
+config QCOM_CLK_APCC_MSM8996
+ tristate "MSM8996 CPU Clock Controller"
+ select QCOM_KRYO_L2_ACCESSORS
+ depends on ARM64
+ help
+ Support for the CPU clock controller on msm8996 devices.
+ Say Y if you want to support CPU clock scaling using CPUfreq
+ drivers for dyanmic power management.
+
config QCOM_CLK_RPM
tristate "RPM based Clock Controller"
depends on MFD_QCOM_RPM
@@ -89,6 +98,25 @@ config APQ_MMCC_8084
Say Y if you want to support multimedia devices such as display,
graphics, video encode/decode, camera, etc.
+config IPQ_APSS_PLL
+ tristate "IPQ APSS PLL"
+ help
+ Support for APSS PLL on ipq devices. The APSS PLL is the main
+ clock that feeds the CPUs on ipq based devices.
+ Say Y if you want to support CPU frequency scaling on ipq based
+ devices.
+
+config IPQ_APSS_6018
+ tristate "IPQ APSS Clock Controller"
+ select IPQ_APSS_PLL
+ depends on QCOM_APCS_IPC || COMPILE_TEST
+ help
+ Support for APSS clock controller on IPQ platforms. The
+ APSS clock controller manages the Mux and enable block that feeds the
+ CPUs.
+ Say Y if you want to support CPU frequency scaling on
+ ipq based devices.
+
config IPQ_GCC_4019
tristate "IPQ4019 Global Clock Controller"
help
@@ -280,6 +308,15 @@ config SC_GCC_7180
Say Y if you want to use peripheral devices such as UART, SPI,
I2C, USB, UFS, SDCC, etc.
+config SC_LPASS_CORECC_7180
+ tristate "SC7180 LPASS Core Clock Controller"
+ select SC_GCC_7180
+ help
+ Support for the LPASS(Low Power Audio Subsystem) core clock controller
+ on SC7180 devices.
+ Say Y if you want to use LPASS clocks and power domains of the LPASS
+ core clock controller.
+
config SC_GPUCC_7180
tristate "SC7180 Graphics Clock Controller"
select SC_GCC_7180
@@ -391,6 +428,22 @@ config SM_GCC_8250
Say Y if you want to use peripheral devices such as UART,
SPI, I2C, USB, SD/UFS, PCIe etc.
+config SM_GPUCC_8150
+ tristate "SM8150 Graphics Clock Controller"
+ select SM_GCC_8150
+ help
+ Support for the graphics clock controller on SM8150 devices.
+ Say Y if you want to support graphics controller devices and
+ functionality such as 3D graphics.
+
+config SM_GPUCC_8250
+ tristate "SM8250 Graphics Clock Controller"
+ select SM_GCC_8250
+ help
+ Support for the graphics clock controller on SM8250 devices.
+ Say Y if you want to support graphics controller devices and
+ functionality such as 3D graphics.
+
config SPMI_PMIC_CLKDIV
tristate "SPMI PMIC clkdiv Support"
depends on SPMI || COMPILE_TEST
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
index 7ec8561a1270..9677e769e7e9 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -19,6 +19,8 @@ clk-qcom-$(CONFIG_QCOM_GDSC) += gdsc.o
# Keep alphabetically sorted by config
obj-$(CONFIG_APQ_GCC_8084) += gcc-apq8084.o
obj-$(CONFIG_APQ_MMCC_8084) += mmcc-apq8084.o
+obj-$(CONFIG_IPQ_APSS_PLL) += apss-ipq-pll.o
+obj-$(CONFIG_IPQ_APSS_6018) += apss-ipq6018.o
obj-$(CONFIG_IPQ_GCC_4019) += gcc-ipq4019.o
obj-$(CONFIG_IPQ_GCC_6018) += gcc-ipq6018.o
obj-$(CONFIG_IPQ_GCC_806X) += gcc-ipq806x.o
@@ -42,6 +44,7 @@ obj-$(CONFIG_MSM_MMCC_8996) += mmcc-msm8996.o
obj-$(CONFIG_MSM_MMCC_8998) += mmcc-msm8998.o
obj-$(CONFIG_QCOM_A53PLL) += a53-pll.o
obj-$(CONFIG_QCOM_CLK_APCS_MSM8916) += apcs-msm8916.o
+obj-$(CONFIG_QCOM_CLK_APCC_MSM8996) += clk-cpu-8996.o
obj-$(CONFIG_QCOM_CLK_RPM) += clk-rpm.o
obj-$(CONFIG_QCOM_CLK_RPMH) += clk-rpmh.o
obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o
@@ -51,6 +54,7 @@ obj-$(CONFIG_QCS_TURING_404) += turingcc-qcs404.o
obj-$(CONFIG_SC_DISPCC_7180) += dispcc-sc7180.o
obj-$(CONFIG_SC_GCC_7180) += gcc-sc7180.o
obj-$(CONFIG_SC_GPUCC_7180) += gpucc-sc7180.o
+obj-$(CONFIG_SC_LPASS_CORECC_7180) += lpasscorecc-sc7180.o
obj-$(CONFIG_SC_MSS_7180) += mss-sc7180.o
obj-$(CONFIG_SC_VIDEOCC_7180) += videocc-sc7180.o
obj-$(CONFIG_SDM_CAMCC_845) += camcc-sdm845.o
@@ -62,6 +66,8 @@ obj-$(CONFIG_SDM_LPASSCC_845) += lpasscc-sdm845.o
obj-$(CONFIG_SDM_VIDEOCC_845) += videocc-sdm845.o
obj-$(CONFIG_SM_GCC_8150) += gcc-sm8150.o
obj-$(CONFIG_SM_GCC_8250) += gcc-sm8250.o
+obj-$(CONFIG_SM_GPUCC_8150) += gpucc-sm8150.o
+obj-$(CONFIG_SM_GPUCC_8250) += gpucc-sm8250.o
obj-$(CONFIG_SPMI_PMIC_CLKDIV) += clk-spmi-pmic-div.o
obj-$(CONFIG_KPSS_XCC) += kpss-xcc.o
obj-$(CONFIG_QCOM_HFPLL) += hfpll.o
diff --git a/drivers/clk/qcom/apss-ipq-pll.c b/drivers/clk/qcom/apss-ipq-pll.c
new file mode 100644
index 000000000000..30be87fb222a
--- /dev/null
+++ b/drivers/clk/qcom/apss-ipq-pll.c
@@ -0,0 +1,95 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2018, The Linux Foundation. All rights reserved.
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include "clk-alpha-pll.h"
+
+static const u8 ipq_pll_offsets[] = {
+ [PLL_OFF_L_VAL] = 0x08,
+ [PLL_OFF_ALPHA_VAL] = 0x10,
+ [PLL_OFF_USER_CTL] = 0x18,
+ [PLL_OFF_CONFIG_CTL] = 0x20,
+ [PLL_OFF_CONFIG_CTL_U] = 0x24,
+ [PLL_OFF_STATUS] = 0x28,
+ [PLL_OFF_TEST_CTL] = 0x30,
+ [PLL_OFF_TEST_CTL_U] = 0x34,
+};
+
+static struct clk_alpha_pll ipq_pll = {
+ .offset = 0x0,
+ .regs = ipq_pll_offsets,
+ .flags = SUPPORTS_DYNAMIC_UPDATE,
+ .clkr = {
+ .enable_reg = 0x0,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "a53pll",
+ .parent_data = &(const struct clk_parent_data) {
+ .fw_name = "xo",
+ },
+ .num_parents = 1,
+ .ops = &clk_alpha_pll_huayra_ops,
+ },
+ },
+};
+
+static const struct alpha_pll_config ipq_pll_config = {
+ .l = 0x37,
+ .config_ctl_val = 0x04141200,
+ .config_ctl_hi_val = 0x0,
+ .early_output_mask = BIT(3),
+ .main_output_mask = BIT(0),
+};
+
+static const struct regmap_config ipq_pll_regmap_config = {
+ .reg_bits = 32,
+ .reg_stride = 4,
+ .val_bits = 32,
+ .max_register = 0x40,
+ .fast_io = true,
+};
+
+static int apss_ipq_pll_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct regmap *regmap;
+ void __iomem *base;
+ int ret;
+
+ base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+
+ regmap = devm_regmap_init_mmio(dev, base, &ipq_pll_regmap_config);
+ if (IS_ERR(regmap))
+ return PTR_ERR(regmap);
+
+ clk_alpha_pll_configure(&ipq_pll, regmap, &ipq_pll_config);
+
+ ret = devm_clk_register_regmap(dev, &ipq_pll.clkr);
+ if (ret)
+ return ret;
+
+ return devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get,
+ &ipq_pll.clkr.hw);
+}
+
+static const struct of_device_id apss_ipq_pll_match_table[] = {
+ { .compatible = "qcom,ipq6018-a53pll" },
+ { }
+};
+
+static struct platform_driver apss_ipq_pll_driver = {
+ .probe = apss_ipq_pll_probe,
+ .driver = {
+ .name = "qcom-ipq-apss-pll",
+ .of_match_table = apss_ipq_pll_match_table,
+ },
+};
+module_platform_driver(apss_ipq_pll_driver);
+
+MODULE_DESCRIPTION("Qualcomm technology Inc APSS ALPHA PLL Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/qcom/apss-ipq6018.c b/drivers/clk/qcom/apss-ipq6018.c
new file mode 100644
index 000000000000..d78ff2f310bf
--- /dev/null
+++ b/drivers/clk/qcom/apss-ipq6018.c
@@ -0,0 +1,106 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/clk-provider.h>
+#include <linux/regmap.h>
+#include <linux/module.h>
+
+#include <dt-bindings/clock/qcom,apss-ipq.h>
+
+#include "common.h"
+#include "clk-regmap.h"
+#include "clk-branch.h"
+#include "clk-alpha-pll.h"
+#include "clk-regmap-mux.h"
+
+enum {
+ P_XO,
+ P_APSS_PLL_EARLY,
+};
+
+static const struct clk_parent_data parents_apcs_alias0_clk_src[] = {
+ { .fw_name = "xo" },
+ { .fw_name = "pll" },
+};
+
+static const struct parent_map parents_apcs_alias0_clk_src_map[] = {
+ { P_XO, 0 },
+ { P_APSS_PLL_EARLY, 5 },
+};
+
+static struct clk_regmap_mux apcs_alias0_clk_src = {
+ .reg = 0x0050,
+ .width = 3,
+ .shift = 7,
+ .parent_map = parents_apcs_alias0_clk_src_map,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "apcs_alias0_clk_src",
+ .parent_data = parents_apcs_alias0_clk_src,
+ .num_parents = 2,
+ .ops = &clk_regmap_mux_closest_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+static struct clk_branch apcs_alias0_core_clk = {
+ .halt_reg = 0x0058,
+ .clkr = {
+ .enable_reg = 0x0058,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "apcs_alias0_core_clk",
+ .parent_hws = (const struct clk_hw *[]){
+ &apcs_alias0_clk_src.clkr.hw },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static const struct regmap_config apss_ipq6018_regmap_config = {
+ .reg_bits = 32,
+ .reg_stride = 4,
+ .val_bits = 32,
+ .max_register = 0x1000,
+ .fast_io = true,
+};
+
+static struct clk_regmap *apss_ipq6018_clks[] = {
+ [APCS_ALIAS0_CLK_SRC] = &apcs_alias0_clk_src.clkr,
+ [APCS_ALIAS0_CORE_CLK] = &apcs_alias0_core_clk.clkr,
+};
+
+static const struct qcom_cc_desc apss_ipq6018_desc = {
+ .config = &apss_ipq6018_regmap_config,
+ .clks = apss_ipq6018_clks,
+ .num_clks = ARRAY_SIZE(apss_ipq6018_clks),
+};
+
+static int apss_ipq6018_probe(struct platform_device *pdev)
+{
+ struct regmap *regmap;
+
+ regmap = dev_get_regmap(pdev->dev.parent, NULL);
+ if (!regmap)
+ return -ENODEV;
+
+ return qcom_cc_really_probe(pdev, &apss_ipq6018_desc, regmap);
+}
+
+static struct platform_driver apss_ipq6018_driver = {
+ .probe = apss_ipq6018_probe,
+ .driver = {
+ .name = "qcom,apss-ipq6018-clk",
+ },
+};
+
+module_platform_driver(apss_ipq6018_driver);
+
+MODULE_DESCRIPTION("QCOM APSS IPQ 6018 CLK Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c
index 9b2dfa08acb2..26139ef005e4 100644
--- a/drivers/clk/qcom/clk-alpha-pll.c
+++ b/drivers/clk/qcom/clk-alpha-pll.c
@@ -56,7 +56,6 @@
#define PLL_STATUS(p) ((p)->offset + (p)->regs[PLL_OFF_STATUS])
#define PLL_OPMODE(p) ((p)->offset + (p)->regs[PLL_OFF_OPMODE])
#define PLL_FRAC(p) ((p)->offset + (p)->regs[PLL_OFF_FRAC])
-#define PLL_CAL_VAL(p) ((p)->offset + (p)->regs[PLL_OFF_CAL_VAL])
const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = {
[CLK_ALPHA_PLL_TYPE_DEFAULT] = {
@@ -112,22 +111,6 @@ const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = {
[PLL_OFF_CONFIG_CTL_U1] = 0x20,
[PLL_OFF_TEST_CTL] = 0x24,
[PLL_OFF_TEST_CTL_U] = 0x28,
- [PLL_OFF_STATUS] = 0x30,
- [PLL_OFF_OPMODE] = 0x38,
- [PLL_OFF_ALPHA_VAL] = 0x40,
- [PLL_OFF_CAL_VAL] = 0x44,
- },
- [CLK_ALPHA_PLL_TYPE_LUCID] = {
- [PLL_OFF_L_VAL] = 0x04,
- [PLL_OFF_CAL_L_VAL] = 0x08,
- [PLL_OFF_USER_CTL] = 0x0c,
- [PLL_OFF_USER_CTL_U] = 0x10,
- [PLL_OFF_USER_CTL_U1] = 0x14,
- [PLL_OFF_CONFIG_CTL] = 0x18,
- [PLL_OFF_CONFIG_CTL_U] = 0x1c,
- [PLL_OFF_CONFIG_CTL_U1] = 0x20,
- [PLL_OFF_TEST_CTL] = 0x24,
- [PLL_OFF_TEST_CTL_U] = 0x28,
[PLL_OFF_TEST_CTL_U1] = 0x2c,
[PLL_OFF_STATUS] = 0x30,
[PLL_OFF_OPMODE] = 0x38,
@@ -156,9 +139,12 @@ EXPORT_SYMBOL_GPL(clk_alpha_pll_regs);
#define PLL_OUT_MASK 0x7
#define PLL_RATE_MARGIN 500
+/* TRION PLL specific settings and offsets */
+#define TRION_PLL_CAL_VAL 0x44
+#define TRION_PCAL_DONE BIT(26)
+
/* LUCID PLL specific settings and offsets */
-#define LUCID_PLL_CAL_VAL 0x44
-#define LUCID_PCAL_DONE BIT(26)
+#define LUCID_PCAL_DONE BIT(27)
#define pll_alpha_width(p) \
((PLL_ALPHA_VAL_U(p) - PLL_ALPHA_VAL(p) == 4) ? \
@@ -912,14 +898,14 @@ const struct clk_ops clk_alpha_pll_hwfsm_ops = {
};
EXPORT_SYMBOL_GPL(clk_alpha_pll_hwfsm_ops);
-const struct clk_ops clk_trion_fixed_pll_ops = {
+const struct clk_ops clk_alpha_pll_fixed_trion_ops = {
.enable = clk_trion_pll_enable,
.disable = clk_trion_pll_disable,
.is_enabled = clk_trion_pll_is_enabled,
.recalc_rate = clk_trion_pll_recalc_rate,
.round_rate = clk_alpha_pll_round_rate,
};
-EXPORT_SYMBOL_GPL(clk_trion_fixed_pll_ops);
+EXPORT_SYMBOL_GPL(clk_alpha_pll_fixed_trion_ops);
static unsigned long
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,
val << PLL_POST_DIV_SHIFT);
}
-const struct clk_ops clk_trion_pll_postdiv_ops = {
+const struct clk_ops clk_alpha_pll_postdiv_trion_ops = {
.recalc_rate = clk_trion_pll_postdiv_recalc_rate,
.round_rate = clk_trion_pll_postdiv_round_rate,
.set_rate = clk_trion_pll_postdiv_set_rate,
};
-EXPORT_SYMBOL_GPL(clk_trion_pll_postdiv_ops);
+EXPORT_SYMBOL_GPL(clk_alpha_pll_postdiv_trion_ops);
static long clk_alpha_pll_postdiv_fabia_round_rate(struct clk_hw *hw,
unsigned long rate, unsigned long *prate)
@@ -1399,13 +1385,13 @@ EXPORT_SYMBOL_GPL(clk_alpha_pll_postdiv_fabia_ops);
* @regmap: register map
* @config: configuration to apply for pll
*/
-void clk_lucid_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
+void clk_trion_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
const struct alpha_pll_config *config)
{
if (config->l)
regmap_write(regmap, PLL_L_VAL(pll), config->l);
- regmap_write(regmap, PLL_CAL_L_VAL(pll), LUCID_PLL_CAL_VAL);
+ regmap_write(regmap, PLL_CAL_L_VAL(pll), TRION_PLL_CAL_VAL);
if (config->alpha)
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,
/* Place the PLL in STANDBY mode */
regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N, PLL_RESET_N);
}
-EXPORT_SYMBOL_GPL(clk_lucid_pll_configure);
+EXPORT_SYMBOL_GPL(clk_trion_pll_configure);
/*
- * The Lucid PLL requires a power-on self-calibration which happens when the
+ * The TRION PLL requires a power-on self-calibration which happens when the
* PLL comes out of reset. Calibrate in case it is not completed.
*/
-static int alpha_pll_lucid_prepare(struct clk_hw *hw)
+static int __alpha_pll_trion_prepare(struct clk_hw *hw, u32 pcal_done)
{
struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
u32 regval;
@@ -1472,7 +1458,7 @@ static int alpha_pll_lucid_prepare(struct clk_hw *hw)
/* Return early if calibration is not needed. */
regmap_read(pll->clkr.regmap, PLL_STATUS(pll), &regval);
- if (regval & LUCID_PCAL_DONE)
+ if (regval & pcal_done)
return 0;
/* On/off to calibrate */
@@ -1483,7 +1469,17 @@ static int alpha_pll_lucid_prepare(struct clk_hw *hw)
return ret;
}
-static int alpha_pll_lucid_set_rate(struct clk_hw *hw, unsigned long rate,
+static int alpha_pll_trion_prepare(struct clk_hw *hw)
+{
+ return __alpha_pll_trion_prepare(hw, TRION_PCAL_DONE);
+}
+
+static int alpha_pll_lucid_prepare(struct clk_hw *hw)
+{
+ return __alpha_pll_trion_prepare(hw, LUCID_PCAL_DONE);
+}
+
+static int alpha_pll_trion_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long prate)
{
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,
return 0;
}
-const struct clk_ops clk_alpha_pll_lucid_ops = {
- .prepare = alpha_pll_lucid_prepare,
+const struct clk_ops clk_alpha_pll_trion_ops = {
+ .prepare = alpha_pll_trion_prepare,
.enable = clk_trion_pll_enable,
.disable = clk_trion_pll_disable,
.is_enabled = clk_trion_pll_is_enabled,
.recalc_rate = clk_trion_pll_recalc_rate,
.round_rate = clk_alpha_pll_round_rate,
- .set_rate = alpha_pll_lucid_set_rate,
+ .set_rate = alpha_pll_trion_set_rate,
};
-EXPORT_SYMBOL_GPL(clk_alpha_pll_lucid_ops);
+EXPORT_SYMBOL_GPL(clk_alpha_pll_trion_ops);
-const struct clk_ops clk_alpha_pll_fixed_lucid_ops = {
+const struct clk_ops clk_alpha_pll_lucid_ops = {
+ .prepare = alpha_pll_lucid_prepare,
.enable = clk_trion_pll_enable,
.disable = clk_trion_pll_disable,
.is_enabled = clk_trion_pll_is_enabled,
.recalc_rate = clk_trion_pll_recalc_rate,
.round_rate = clk_alpha_pll_round_rate,
+ .set_rate = alpha_pll_trion_set_rate,
};
-EXPORT_SYMBOL_GPL(clk_alpha_pll_fixed_lucid_ops);
+EXPORT_SYMBOL_GPL(clk_alpha_pll_lucid_ops);
const struct clk_ops clk_alpha_pll_postdiv_lucid_ops = {
.recalc_rate = clk_alpha_pll_postdiv_fabia_recalc_rate,
diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h
index 704674a153b6..d3201b87c0cd 100644
--- a/drivers/clk/qcom/clk-alpha-pll.h
+++ b/drivers/clk/qcom/clk-alpha-pll.h
@@ -14,7 +14,7 @@ enum {
CLK_ALPHA_PLL_TYPE_BRAMMO,
CLK_ALPHA_PLL_TYPE_FABIA,
CLK_ALPHA_PLL_TYPE_TRION,
- CLK_ALPHA_PLL_TYPE_LUCID,
+ CLK_ALPHA_PLL_TYPE_LUCID = CLK_ALPHA_PLL_TYPE_TRION,
CLK_ALPHA_PLL_TYPE_MAX,
};
@@ -47,6 +47,12 @@ struct pll_vco {
u32 val;
};
+#define VCO(a, b, c) { \
+ .val = a,\
+ .min_freq = b,\
+ .max_freq = c,\
+}
+
/**
* struct clk_alpha_pll - phase locked loop (PLL)
* @offset: base address of registers
@@ -128,18 +134,23 @@ extern const struct clk_ops clk_alpha_pll_fabia_ops;
extern const struct clk_ops clk_alpha_pll_fixed_fabia_ops;
extern const struct clk_ops clk_alpha_pll_postdiv_fabia_ops;
+extern const struct clk_ops clk_alpha_pll_trion_ops;
+extern const struct clk_ops clk_alpha_pll_fixed_trion_ops;
+extern const struct clk_ops clk_alpha_pll_postdiv_trion_ops;
+
extern const struct clk_ops clk_alpha_pll_lucid_ops;
-extern const struct clk_ops clk_alpha_pll_fixed_lucid_ops;
+#define clk_alpha_pll_fixed_lucid_ops clk_alpha_pll_fixed_trion_ops
extern const struct clk_ops clk_alpha_pll_postdiv_lucid_ops;
void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
const struct alpha_pll_config *config);
void clk_fabia_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
const struct alpha_pll_config *config);
-void clk_lucid_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
+void clk_trion_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
const struct alpha_pll_config *config);
+#define clk_lucid_pll_configure(pll, regmap, config) \
+ clk_trion_pll_configure(pll, regmap, config)
+
-extern const struct clk_ops clk_trion_fixed_pll_ops;
-extern const struct clk_ops clk_trion_pll_postdiv_ops;
#endif
diff --git a/drivers/clk/qcom/clk-cpu-8996.c b/drivers/clk/qcom/clk-cpu-8996.c
new file mode 100644
index 000000000000..4a4fde8dd12d
--- /dev/null
+++ b/drivers/clk/qcom/clk-cpu-8996.c
@@ -0,0 +1,538 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ */
+
+/*
+ * Each of the CPU clusters (Power and Perf) on msm8996 are
+ * clocked via 2 PLLs, a primary and alternate. There are also
+ * 2 Mux'es, a primary and secondary all connected together
+ * as shown below
+ *
+ * +-------+
+ * XO | |
+ * +------------------>0 |
+ * | |
+ * PLL/2 | SMUX +----+
+ * +------->1 | |
+ * | | | |
+ * | +-------+ | +-------+
+ * | +---->0 |
+ * | | |
+ * +---------------+ | +----------->1 | CPU clk
+ * |Primary PLL +----+ PLL_EARLY | | +------>
+ * | +------+-----------+ +------>2 PMUX |
+ * +---------------+ | | | |
+ * | +------+ | +-->3 |
+ * +--^+ ACD +-----+ | +-------+
+ * +---------------+ +------+ |
+ * |Alt PLL | |
+ * | +---------------------------+
+ * +---------------+ PLL_EARLY
+ *
+ * The primary PLL is what drives the CPU clk, except for times
+ * when we are reprogramming the PLL itself (for rate changes) when
+ * we temporarily switch to an alternate PLL.
+ *
+ * The primary PLL operates on a single VCO range, between 600MHz
+ * and 3GHz. However the CPUs do support OPPs with frequencies
+ * between 300MHz and 600MHz. In order to support running the CPUs
+ * at those frequencies we end up having to lock the PLL at twice
+ * the rate and drive the CPU clk via the PLL/2 output and SMUX.
+ *
+ * So for frequencies above 600MHz we follow the following path
+ * Primary PLL --> PLL_EARLY --> PMUX(1) --> CPU clk
+ * and for frequencies between 300MHz and 600MHz we follow
+ * Primary PLL --> PLL/2 --> SMUX(1) --> PMUX(0) --> CPU clk
+ *
+ * ACD stands for Adaptive Clock Distribution and is used to
+ * detect voltage droops.
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <soc/qcom/kryo-l2-accessors.h>
+
+#include "clk-alpha-pll.h"
+#include "clk-regmap.h"
+
+enum _pmux_input {
+ DIV_2_INDEX = 0,
+ PLL_INDEX,
+ ACD_INDEX,
+ ALT_INDEX,
+ NUM_OF_PMUX_INPUTS
+};
+
+#define DIV_2_THRESHOLD 600000000
+#define PWRCL_REG_OFFSET 0x0
+#define PERFCL_REG_OFFSET 0x80000
+#define MUX_OFFSET 0x40
+#define ALT_PLL_OFFSET 0x100
+#define SSSCTL_OFFSET 0x160
+
+static const u8 prim_pll_regs[PLL_OFF_MAX_REGS] = {
+ [PLL_OFF_L_VAL] = 0x04,
+ [PLL_OFF_ALPHA_VAL] = 0x08,
+ [PLL_OFF_USER_CTL] = 0x10,
+ [PLL_OFF_CONFIG_CTL] = 0x18,
+ [PLL_OFF_CONFIG_CTL_U] = 0x1c,
+ [PLL_OFF_TEST_CTL] = 0x20,
+ [PLL_OFF_TEST_CTL_U] = 0x24,
+ [PLL_OFF_STATUS] = 0x28,
+};
+
+static const u8 alt_pll_regs[PLL_OFF_MAX_REGS] = {
+ [PLL_OFF_L_VAL] = 0x04,
+ [PLL_OFF_ALPHA_VAL] = 0x08,
+ [PLL_OFF_ALPHA_VAL_U] = 0x0c,
+ [PLL_OFF_USER_CTL] = 0x10,
+ [PLL_OFF_USER_CTL_U] = 0x14,
+ [PLL_OFF_CONFIG_CTL] = 0x18,
+ [PLL_OFF_TEST_CTL] = 0x20,
+ [PLL_OFF_TEST_CTL_U] = 0x24,
+ [PLL_OFF_STATUS] = 0x28,
+};
+
+/* PLLs */
+
+static const struct alpha_pll_config hfpll_config = {
+ .l = 60,
+ .config_ctl_val = 0x200d4aa8,
+ .config_ctl_hi_val = 0x006,
+ .pre_div_mask = BIT(12),
+ .post_div_mask = 0x3 << 8,
+ .post_div_val = 0x1 << 8,
+ .main_output_mask = BIT(0),
+ .early_output_mask = BIT(3),
+};
+
+static struct clk_alpha_pll perfcl_pll = {
+ .offset = PERFCL_REG_OFFSET,
+ .regs = prim_pll_regs,
+ .flags = SUPPORTS_DYNAMIC_UPDATE | SUPPORTS_FSM_MODE,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "perfcl_pll",
+ .parent_names = (const char *[]){ "xo" },
+ .num_parents = 1,
+ .ops = &clk_alpha_pll_huayra_ops,
+ },
+};
+
+static struct clk_alpha_pll pwrcl_pll = {
+ .offset = PWRCL_REG_OFFSET,
+ .regs = prim_pll_regs,
+ .flags = SUPPORTS_DYNAMIC_UPDATE | SUPPORTS_FSM_MODE,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "pwrcl_pll",
+ .parent_names = (const char *[]){ "xo" },
+ .num_parents = 1,
+ .ops = &clk_alpha_pll_huayra_ops,
+ },
+};
+
+static const struct pll_vco alt_pll_vco_modes[] = {
+ VCO(3, 250000000, 500000000),
+ VCO(2, 500000000, 750000000),
+ VCO(1, 750000000, 1000000000),
+ VCO(0, 1000000000, 2150400000),
+};
+
+static const struct alpha_pll_config altpll_config = {
+ .l = 16,
+ .vco_val = 0x3 << 20,
+ .vco_mask = 0x3 << 20,
+ .config_ctl_val = 0x4001051b,
+ .post_div_mask = 0x3 << 8,
+ .post_div_val = 0x1 << 8,
+ .main_output_mask = BIT(0),
+ .early_output_mask = BIT(3),
+};
+
+static struct clk_alpha_pll perfcl_alt_pll = {
+ .offset = PERFCL_REG_OFFSET + ALT_PLL_OFFSET,
+ .regs = alt_pll_regs,
+ .vco_table = alt_pll_vco_modes,
+ .num_vco = ARRAY_SIZE(alt_pll_vco_modes),
+ .flags = SUPPORTS_OFFLINE_REQ | SUPPORTS_FSM_MODE,
+ .clkr.hw.init = &(struct clk_init_data) {
+ .name = "perfcl_alt_pll",
+ .parent_names = (const char *[]){ "xo" },
+ .num_parents = 1,
+ .ops = &clk_alpha_pll_hwfsm_ops,
+ },
+};
+
+static struct clk_alpha_pll pwrcl_alt_pll = {
+ .offset = PWRCL_REG_OFFSET + ALT_PLL_OFFSET,
+ .regs = alt_pll_regs,
+ .vco_table = alt_pll_vco_modes,
+ .num_vco = ARRAY_SIZE(alt_pll_vco_modes),
+ .flags = SUPPORTS_OFFLINE_REQ | SUPPORTS_FSM_MODE,
+ .clkr.hw.init = &(struct clk_init_data) {
+ .name = "pwrcl_alt_pll",
+ .parent_names = (const char *[]){ "xo" },
+ .num_parents = 1,
+ .ops = &clk_alpha_pll_hwfsm_ops,
+ },
+};
+
+struct clk_cpu_8996_mux {
+ u32 reg;
+ u8 shift;
+ u8 width;
+ struct notifier_block nb;
+ struct clk_hw *pll;
+ struct clk_hw *pll_div_2;
+ struct clk_regmap clkr;
+};
+
+static int cpu_clk_notifier_cb(struct notifier_block *nb, unsigned long event,
+ void *data);
+
+#define to_clk_cpu_8996_mux_nb(_nb) \
+ container_of(_nb, struct clk_cpu_8996_mux, nb)
+
+static inline struct clk_cpu_8996_mux *to_clk_cpu_8996_mux_hw(struct clk_hw *hw)
+{
+ return container_of(to_clk_regmap(hw), struct clk_cpu_8996_mux, clkr);
+}
+
+static u8 clk_cpu_8996_mux_get_parent(struct clk_hw *hw)
+{
+ struct clk_regmap *clkr = to_clk_regmap(hw);
+ struct clk_cpu_8996_mux *cpuclk = to_clk_cpu_8996_mux_hw(hw);
+ u32 mask = GENMASK(cpuclk->width - 1, 0);
+ u32 val;
+
+ regmap_read(clkr->regmap, cpuclk->reg, &val);
+ val >>= cpuclk->shift;
+
+ return val & mask;
+}
+
+static int clk_cpu_8996_mux_set_parent(struct clk_hw *hw, u8 index)
+{
+ struct clk_regmap *clkr = to_clk_regmap(hw);
+ struct clk_cpu_8996_mux *cpuclk = to_clk_cpu_8996_mux_hw(hw);
+ u32 mask = GENMASK(cpuclk->width + cpuclk->shift - 1, cpuclk->shift);
+ u32 val;
+
+ val = index;
+ val <<= cpuclk->shift;
+
+ return regmap_update_bits(clkr->regmap, cpuclk->reg, mask, val);
+}
+
+static int clk_cpu_8996_mux_determine_rate(struct clk_hw *hw,
+ struct clk_rate_request *req)
+{
+ struct clk_cpu_8996_mux *cpuclk = to_clk_cpu_8996_mux_hw(hw);
+ struct clk_hw *parent = cpuclk->pll;
+
+ if (cpuclk->pll_div_2 && req->rate < DIV_2_THRESHOLD) {
+ if (req->rate < (DIV_2_THRESHOLD / 2))
+ return -EINVAL;
+
+ parent = cpuclk->pll_div_2;
+ }
+
+ req->best_parent_rate = clk_hw_round_rate(parent, req->rate);
+ req->best_parent_hw = parent;
+
+ return 0;
+}
+
+static const struct clk_ops clk_cpu_8996_mux_ops = {
+ .set_parent = clk_cpu_8996_mux_set_parent,
+ .get_parent = clk_cpu_8996_mux_get_parent,
+ .determine_rate = clk_cpu_8996_mux_determine_rate,
+};
+
+static struct clk_cpu_8996_mux pwrcl_smux = {
+ .reg = PWRCL_REG_OFFSET + MUX_OFFSET,
+ .shift = 2,
+ .width = 2,
+ .clkr.hw.init = &(struct clk_init_data) {
+ .name = "pwrcl_smux",
+ .parent_names = (const char *[]){
+ "xo",
+ "pwrcl_pll_main",
+ },
+ .num_parents = 2,
+ .ops = &clk_cpu_8996_mux_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+static struct clk_cpu_8996_mux perfcl_smux = {
+ .reg = PERFCL_REG_OFFSET + MUX_OFFSET,
+ .shift = 2,
+ .width = 2,
+ .clkr.hw.init = &(struct clk_init_data) {
+ .name = "perfcl_smux",
+ .parent_names = (const char *[]){
+ "xo",
+ "perfcl_pll_main",
+ },
+ .num_parents = 2,
+ .ops = &clk_cpu_8996_mux_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+static struct clk_cpu_8996_mux pwrcl_pmux = {
+ .reg = PWRCL_REG_OFFSET + MUX_OFFSET,
+ .shift = 0,
+ .width = 2,
+ .pll = &pwrcl_pll.clkr.hw,
+ .pll_div_2 = &pwrcl_smux.clkr.hw,
+ .nb.notifier_call = cpu_clk_notifier_cb,
+ .clkr.hw.init = &(struct clk_init_data) {
+ .name = "pwrcl_pmux",
+ .parent_names = (const char *[]){
+ "pwrcl_smux",
+ "pwrcl_pll",
+ "pwrcl_pll_acd",
+ "pwrcl_alt_pll",
+ },
+ .num_parents = 4,
+ .ops = &clk_cpu_8996_mux_ops,
+ /* CPU clock is critical and should never be gated */
+ .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
+ },
+};
+
+static struct clk_cpu_8996_mux perfcl_pmux = {
+ .reg = PERFCL_REG_OFFSET + MUX_OFFSET,
+ .shift = 0,
+ .width = 2,
+ .pll = &perfcl_pll.clkr.hw,
+ .pll_div_2 = &perfcl_smux.clkr.hw,
+ .nb.notifier_call = cpu_clk_notifier_cb,
+ .clkr.hw.init = &(struct clk_init_data) {
+ .name = "perfcl_pmux",
+ .parent_names = (const char *[]){
+ "perfcl_smux",
+ "perfcl_pll",
+ "perfcl_pll_acd",
+ "perfcl_alt_pll",
+ },
+ .num_parents = 4,
+ .ops = &clk_cpu_8996_mux_ops,
+ /* CPU clock is critical and should never be gated */
+ .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
+ },
+};
+
+static const struct regmap_config cpu_msm8996_regmap_config = {
+ .reg_bits = 32,
+ .reg_stride = 4,
+ .val_bits = 32,
+ .max_register = 0x80210,
+ .fast_io = true,
+ .val_format_endian = REGMAP_ENDIAN_LITTLE,
+};
+
+static struct clk_regmap *cpu_msm8996_clks[] = {
+ &perfcl_pll.clkr,
+ &pwrcl_pll.clkr,
+ &perfcl_alt_pll.clkr,
+ &pwrcl_alt_pll.clkr,
+ &perfcl_smux.clkr,
+ &pwrcl_smux.clkr,
+ &perfcl_pmux.clkr,
+ &pwrcl_pmux.clkr,
+};
+
+static int qcom_cpu_clk_msm8996_register_clks(struct device *dev,
+ struct regmap *regmap)
+{
+ int i, ret;
+
+ perfcl_smux.pll = clk_hw_register_fixed_factor(dev, "perfcl_pll_main",
+ "perfcl_pll",
+ CLK_SET_RATE_PARENT,
+ 1, 2);
+ if (IS_ERR(perfcl_smux.pll)) {
+ dev_err(dev, "Failed to initialize perfcl_pll_main\n");
+ return PTR_ERR(perfcl_smux.pll);
+ }
+
+ pwrcl_smux.pll = clk_hw_register_fixed_factor(dev, "pwrcl_pll_main",
+ "pwrcl_pll",
+ CLK_SET_RATE_PARENT,
+ 1, 2);
+ if (IS_ERR(pwrcl_smux.pll)) {
+ dev_err(dev, "Failed to initialize pwrcl_pll_main\n");
+ clk_hw_unregister(perfcl_smux.pll);
+ return PTR_ERR(pwrcl_smux.pll);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(cpu_msm8996_clks); i++) {
+ ret = devm_clk_register_regmap(dev, cpu_msm8996_clks[i]);
+ if (ret) {
+ clk_hw_unregister(perfcl_smux.pll);
+ clk_hw_unregister(pwrcl_smux.pll);
+ return ret;
+ }
+ }
+
+ clk_alpha_pll_configure(&perfcl_pll, regmap, &hfpll_config);
+ clk_alpha_pll_configure(&pwrcl_pll, regmap, &hfpll_config);
+ clk_alpha_pll_configure(&perfcl_alt_pll, regmap, &altpll_config);
+ clk_alpha_pll_configure(&pwrcl_alt_pll, regmap, &altpll_config);
+
+ /* Enable alt PLLs */
+ clk_prepare_enable(pwrcl_alt_pll.clkr.hw.clk);
+ clk_prepare_enable(perfcl_alt_pll.clkr.hw.clk);
+
+ clk_notifier_register(pwrcl_pmux.clkr.hw.clk, &pwrcl_pmux.nb);
+ clk_notifier_register(perfcl_pmux.clkr.hw.clk, &perfcl_pmux.nb);
+
+ return ret;
+}
+
+static int qcom_cpu_clk_msm8996_unregister_clks(void)
+{
+ int ret = 0;
+
+ ret = clk_notifier_unregister(pwrcl_pmux.clkr.hw.clk, &pwrcl_pmux.nb);
+ if (ret)
+ return ret;
+
+ ret = clk_notifier_unregister(perfcl_pmux.clkr.hw.clk, &perfcl_pmux.nb);
+ if (ret)
+ return ret;
+
+ clk_hw_unregister(perfcl_smux.pll);
+ clk_hw_unregister(pwrcl_smux.pll);
+
+ return 0;
+}
+
+#define CPU_AFINITY_MASK 0xFFF
+#define PWRCL_CPU_REG_MASK 0x3
+#define PERFCL_CPU_REG_MASK 0x103
+
+#define L2ACDCR_REG 0x580ULL
+#define L2ACDTD_REG 0x581ULL
+#define L2ACDDVMRC_REG 0x584ULL
+#define L2ACDSSCR_REG 0x589ULL
+
+static DEFINE_SPINLOCK(qcom_clk_acd_lock);
+static void __iomem *base;
+
+static void qcom_cpu_clk_msm8996_acd_init(void __iomem *base)
+{
+ u64 hwid;
+ unsigned long flags;
+
+ spin_lock_irqsave(&qcom_clk_acd_lock, flags);
+
+ hwid = read_cpuid_mpidr() & CPU_AFINITY_MASK;
+
+ kryo_l2_set_indirect_reg(L2ACDTD_REG, 0x00006a11);
+ kryo_l2_set_indirect_reg(L2ACDDVMRC_REG, 0x000e0f0f);
+ kryo_l2_set_indirect_reg(L2ACDSSCR_REG, 0x00000601);
+
+ if (PWRCL_CPU_REG_MASK == (hwid | PWRCL_CPU_REG_MASK)) {
+ writel(0xf, base + PWRCL_REG_OFFSET + SSSCTL_OFFSET);
+ kryo_l2_set_indirect_reg(L2ACDCR_REG, 0x002c5ffd);
+ }
+
+ if (PERFCL_CPU_REG_MASK == (hwid | PERFCL_CPU_REG_MASK)) {
+ kryo_l2_set_indirect_reg(L2ACDCR_REG, 0x002c5ffd);
+ writel(0xf, base + PERFCL_REG_OFFSET + SSSCTL_OFFSET);
+ }
+
+ spin_unlock_irqrestore(&qcom_clk_acd_lock, flags);
+}
+
+static int cpu_clk_notifier_cb(struct notifier_block *nb, unsigned long event,
+ void *data)
+{
+ struct clk_cpu_8996_mux *cpuclk = to_clk_cpu_8996_mux_nb(nb);
+ struct clk_notifier_data *cnd = data;
+ int ret;
+
+ switch (event) {
+ case PRE_RATE_CHANGE:
+ ret = clk_cpu_8996_mux_set_parent(&cpuclk->clkr.hw, ALT_INDEX);
+ qcom_cpu_clk_msm8996_acd_init(base);
+ break;
+ case POST_RATE_CHANGE:
+ if (cnd->new_rate < DIV_2_THRESHOLD)
+ ret = clk_cpu_8996_mux_set_parent(&cpuclk->clkr.hw,
+ DIV_2_INDEX);
+ else
+ ret = clk_cpu_8996_mux_set_parent(&cpuclk->clkr.hw,
+ ACD_INDEX);
+ break;
+ default:
+ ret = 0;
+ break;
+ }
+
+ return notifier_from_errno(ret);
+};
+
+static int qcom_cpu_clk_msm8996_driver_probe(struct platform_device *pdev)
+{
+ struct regmap *regmap;
+ struct clk_hw_onecell_data *data;
+ struct device *dev = &pdev->dev;
+ int ret;
+
+ data = devm_kzalloc(dev, struct_size(data, hws, 2), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+
+ regmap = devm_regmap_init_mmio(dev, base, &cpu_msm8996_regmap_config);
+ if (IS_ERR(regmap))
+ return PTR_ERR(regmap);
+
+ ret = qcom_cpu_clk_msm8996_register_clks(dev, regmap);
+ if (ret)
+ return ret;
+
+ qcom_cpu_clk_msm8996_acd_init(base);
+
+ data->hws[0] = &pwrcl_pmux.clkr.hw;
+ data->hws[1] = &perfcl_pmux.clkr.hw;
+ data->num = 2;
+
+ return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, data);
+}
+
+static int qcom_cpu_clk_msm8996_driver_remove(struct platform_device *pdev)
+{
+ return qcom_cpu_clk_msm8996_unregister_clks();
+}
+
+static const struct of_device_id qcom_cpu_clk_msm8996_match_table[] = {
+ { .compatible = "qcom,msm8996-apcc" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, qcom_cpu_clk_msm8996_match_table);
+
+static struct platform_driver qcom_cpu_clk_msm8996_driver = {
+ .probe = qcom_cpu_clk_msm8996_driver_probe,
+ .remove = qcom_cpu_clk_msm8996_driver_remove,
+ .driver = {
+ .name = "qcom-msm8996-apcc",
+ .of_match_table = qcom_cpu_clk_msm8996_match_table,
+ },
+};
+module_platform_driver(qcom_cpu_clk_msm8996_driver);
+
+MODULE_DESCRIPTION("QCOM MSM8996 CPU Clock Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/qcom/clk-smd-rpm.c b/drivers/clk/qcom/clk-smd-rpm.c
index 52f63ad787ba..0e1dfa89489e 100644
--- a/drivers/clk/qcom/clk-smd-rpm.c
+++ b/drivers/clk/qcom/clk-smd-rpm.c
@@ -452,6 +452,55 @@ static const struct rpm_smd_clk_desc rpm_clk_msm8916 = {
.num_clks = ARRAY_SIZE(msm8916_clks),
};
+/* msm8936 */
+DEFINE_CLK_SMD_RPM(msm8936, pcnoc_clk, pcnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 0);
+DEFINE_CLK_SMD_RPM(msm8936, snoc_clk, snoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 1);
+DEFINE_CLK_SMD_RPM(msm8936, bimc_clk, bimc_a_clk, QCOM_SMD_RPM_MEM_CLK, 0);
+DEFINE_CLK_SMD_RPM(msm8936, sysmmnoc_clk, sysmmnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 2);
+DEFINE_CLK_SMD_RPM_QDSS(msm8936, qdss_clk, qdss_a_clk, QCOM_SMD_RPM_MISC_CLK, 1);
+DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8936, bb_clk1, bb_clk1_a, 1);
+DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8936, bb_clk2, bb_clk2_a, 2);
+DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8936, rf_clk1, rf_clk1_a, 4);
+DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8936, rf_clk2, rf_clk2_a, 5);
+DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8936, bb_clk1_pin, bb_clk1_a_pin, 1);
+DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8936, bb_clk2_pin, bb_clk2_a_pin, 2);
+DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8936, rf_clk1_pin, rf_clk1_a_pin, 4);
+DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8936, rf_clk2_pin, rf_clk2_a_pin, 5);
+
+static struct clk_smd_rpm *msm8936_clks[] = {
+ [RPM_SMD_PCNOC_CLK] = &msm8936_pcnoc_clk,
+ [RPM_SMD_PCNOC_A_CLK] = &msm8936_pcnoc_a_clk,
+ [RPM_SMD_SNOC_CLK] = &msm8936_snoc_clk,
+ [RPM_SMD_SNOC_A_CLK] = &msm8936_snoc_a_clk,
+ [RPM_SMD_BIMC_CLK] = &msm8936_bimc_clk,
+ [RPM_SMD_BIMC_A_CLK] = &msm8936_bimc_a_clk,
+ [RPM_SMD_SYSMMNOC_CLK] = &msm8936_sysmmnoc_clk,
+ [RPM_SMD_SYSMMNOC_A_CLK] = &msm8936_sysmmnoc_a_clk,
+ [RPM_SMD_QDSS_CLK] = &msm8936_qdss_clk,
+ [RPM_SMD_QDSS_A_CLK] = &msm8936_qdss_a_clk,
+ [RPM_SMD_BB_CLK1] = &msm8936_bb_clk1,
+ [RPM_SMD_BB_CLK1_A] = &msm8936_bb_clk1_a,
+ [RPM_SMD_BB_CLK2] = &msm8936_bb_clk2,
+ [RPM_SMD_BB_CLK2_A] = &msm8936_bb_clk2_a,
+ [RPM_SMD_RF_CLK1] = &msm8936_rf_clk1,
+ [RPM_SMD_RF_CLK1_A] = &msm8936_rf_clk1_a,
+ [RPM_SMD_RF_CLK2] = &msm8936_rf_clk2,
+ [RPM_SMD_RF_CLK2_A] = &msm8936_rf_clk2_a,
+ [RPM_SMD_BB_CLK1_PIN] = &msm8936_bb_clk1_pin,
+ [RPM_SMD_BB_CLK1_A_PIN] = &msm8936_bb_clk1_a_pin,
+ [RPM_SMD_BB_CLK2_PIN] = &msm8936_bb_clk2_pin,
+ [RPM_SMD_BB_CLK2_A_PIN] = &msm8936_bb_clk2_a_pin,
+ [RPM_SMD_RF_CLK1_PIN] = &msm8936_rf_clk1_pin,
+ [RPM_SMD_RF_CLK1_A_PIN] = &msm8936_rf_clk1_a_pin,
+ [RPM_SMD_RF_CLK2_PIN] = &msm8936_rf_clk2_pin,
+ [RPM_SMD_RF_CLK2_A_PIN] = &msm8936_rf_clk2_a_pin,
+};
+
+static const struct rpm_smd_clk_desc rpm_clk_msm8936 = {
+ .clks = msm8936_clks,
+ .num_clks = ARRAY_SIZE(msm8936_clks),
+};
+
/* msm8974 */
DEFINE_CLK_SMD_RPM(msm8974, pnoc_clk, pnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 0);
DEFINE_CLK_SMD_RPM(msm8974, snoc_clk, snoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 1);
@@ -574,6 +623,175 @@ static const struct rpm_smd_clk_desc rpm_clk_msm8976 = {
.num_clks = ARRAY_SIZE(msm8976_clks),
};
+/* msm8992 */
+DEFINE_CLK_SMD_RPM(msm8992, pnoc_clk, pnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 0);
+DEFINE_CLK_SMD_RPM(msm8992, ocmemgx_clk, ocmemgx_a_clk, QCOM_SMD_RPM_MEM_CLK, 2);
+DEFINE_CLK_SMD_RPM(msm8992, bimc_clk, bimc_a_clk, QCOM_SMD_RPM_MEM_CLK, 0);
+DEFINE_CLK_SMD_RPM(msm8992, cnoc_clk, cnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 2);
+DEFINE_CLK_SMD_RPM(msm8992, gfx3d_clk_src, gfx3d_a_clk_src, QCOM_SMD_RPM_MEM_CLK, 1);
+DEFINE_CLK_SMD_RPM(msm8992, snoc_clk, snoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 1);
+DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8992, bb_clk1, bb_clk1_a, 1);
+DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8992, bb_clk1_pin, bb_clk1_a_pin, 1);
+DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8992, bb_clk2, bb_clk2_a, 2);
+DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8992, bb_clk2_pin, bb_clk2_a_pin, 2);
+
+DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8992, div_clk1, div_clk1_a, 11);
+DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8992, div_clk2, div_clk2_a, 12);
+DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8992, div_clk3, div_clk3_a, 13);
+DEFINE_CLK_SMD_RPM(msm8992, ipa_clk, ipa_a_clk, QCOM_SMD_RPM_IPA_CLK, 0);
+DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8992, ln_bb_clk, ln_bb_a_clk, 8);
+DEFINE_CLK_SMD_RPM(msm8992, mmssnoc_ahb_clk, mmssnoc_ahb_a_clk,
+ QCOM_SMD_RPM_BUS_CLK, 3);
+DEFINE_CLK_SMD_RPM_QDSS(msm8992, qdss_clk, qdss_a_clk,
+ QCOM_SMD_RPM_MISC_CLK, 1);
+DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8992, rf_clk1, rf_clk1_a, 4);
+DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8992, rf_clk2, rf_clk2_a, 5);
+DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8992, rf_clk1_pin, rf_clk1_a_pin, 4);
+DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8992, rf_clk2_pin, rf_clk2_a_pin, 5);
+
+DEFINE_CLK_SMD_RPM(msm8992, ce1_clk, ce1_a_clk, QCOM_SMD_RPM_CE_CLK, 0);
+DEFINE_CLK_SMD_RPM(msm8992, ce2_clk, ce2_a_clk, QCOM_SMD_RPM_CE_CLK, 1);
+
+static struct clk_smd_rpm *msm8992_clks[] = {
+ [RPM_SMD_PNOC_CLK] = &msm8992_pnoc_clk,
+ [RPM_SMD_PNOC_A_CLK] = &msm8992_pnoc_a_clk,
+ [RPM_SMD_OCMEMGX_CLK] = &msm8992_ocmemgx_clk,
+ [RPM_SMD_OCMEMGX_A_CLK] = &msm8992_ocmemgx_a_clk,
+ [RPM_SMD_BIMC_CLK] = &msm8992_bimc_clk,
+ [RPM_SMD_BIMC_A_CLK] = &msm8992_bimc_a_clk,
+ [RPM_SMD_CNOC_CLK] = &msm8992_cnoc_clk,
+ [RPM_SMD_CNOC_A_CLK] = &msm8992_cnoc_a_clk,
+ [RPM_SMD_GFX3D_CLK_SRC] = &msm8992_gfx3d_clk_src,
+ [RPM_SMD_GFX3D_A_CLK_SRC] = &msm8992_gfx3d_a_clk_src,
+ [RPM_SMD_SNOC_CLK] = &msm8992_snoc_clk,
+ [RPM_SMD_SNOC_A_CLK] = &msm8992_snoc_a_clk,
+ [RPM_SMD_BB_CLK1] = &msm8992_bb_clk1,
+ [RPM_SMD_BB_CLK1_A] = &msm8992_bb_clk1_a,
+ [RPM_SMD_BB_CLK1_PIN] = &msm8992_bb_clk1_pin,
+ [RPM_SMD_BB_CLK1_A_PIN] = &msm8992_bb_clk1_a_pin,
+ [RPM_SMD_BB_CLK2] = &msm8992_bb_clk2,
+ [RPM_SMD_BB_CLK2_A] = &msm8992_bb_clk2_a,
+ [RPM_SMD_BB_CLK2_PIN] = &msm8992_bb_clk2_pin,
+ [RPM_SMD_BB_CLK2_A_PIN] = &msm8992_bb_clk2_a_pin,
+ [RPM_SMD_DIV_CLK1] = &msm8992_div_clk1,
+ [RPM_SMD_DIV_A_CLK1] = &msm8992_div_clk1_a,
+ [RPM_SMD_DIV_CLK2] = &msm8992_div_clk2,
+ [RPM_SMD_DIV_A_CLK2] = &msm8992_div_clk2_a,
+ [RPM_SMD_DIV_CLK3] = &msm8992_div_clk3,
+ [RPM_SMD_DIV_A_CLK3] = &msm8992_div_clk3_a,
+ [RPM_SMD_IPA_CLK] = &msm8992_ipa_clk,
+ [RPM_SMD_IPA_A_CLK] = &msm8992_ipa_a_clk,
+ [RPM_SMD_LN_BB_CLK] = &msm8992_ln_bb_clk,
+ [RPM_SMD_LN_BB_A_CLK] = &msm8992_ln_bb_a_clk,
+ [RPM_SMD_MMSSNOC_AHB_CLK] = &msm8992_mmssnoc_ahb_clk,
+ [RPM_SMD_MMSSNOC_AHB_A_CLK] = &msm8992_mmssnoc_ahb_a_clk,
+ [RPM_SMD_QDSS_CLK] = &msm8992_qdss_clk,
+ [RPM_SMD_QDSS_A_CLK] = &msm8992_qdss_a_clk,
+ [RPM_SMD_RF_CLK1] = &msm8992_rf_clk1,
+ [RPM_SMD_RF_CLK1_A] = &msm8992_rf_clk1_a,
+ [RPM_SMD_RF_CLK2] = &msm8992_rf_clk2,
+ [RPM_SMD_RF_CLK2_A] = &msm8992_rf_clk2_a,
+ [RPM_SMD_RF_CLK1_PIN] = &msm8992_rf_clk1_pin,
+ [RPM_SMD_RF_CLK1_A_PIN] = &msm8992_rf_clk1_a_pin,
+ [RPM_SMD_RF_CLK2_PIN] = &msm8992_rf_clk2_pin,
+ [RPM_SMD_RF_CLK2_A_PIN] = &msm8992_rf_clk2_a_pin,
+ [RPM_SMD_CE1_CLK] = &msm8992_ce1_clk,
+ [RPM_SMD_CE1_A_CLK] = &msm8992_ce1_a_clk,
+ [RPM_SMD_CE2_CLK] = &msm8992_ce2_clk,
+ [RPM_SMD_CE2_A_CLK] = &msm8992_ce2_a_clk,
+};
+
+static const struct rpm_smd_clk_desc rpm_clk_msm8992 = {
+ .clks = msm8992_clks,
+ .num_clks = ARRAY_SIZE(msm8992_clks),
+};
+
+/* msm8994 */
+DEFINE_CLK_SMD_RPM(msm8994, pnoc_clk, pnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 0);
+DEFINE_CLK_SMD_RPM(msm8994, ocmemgx_clk, ocmemgx_a_clk, QCOM_SMD_RPM_MEM_CLK, 2);
+DEFINE_CLK_SMD_RPM(msm8994, bimc_clk, bimc_a_clk, QCOM_SMD_RPM_MEM_CLK, 0);
+DEFINE_CLK_SMD_RPM(msm8994, cnoc_clk, cnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 2);
+DEFINE_CLK_SMD_RPM(msm8994, gfx3d_clk_src, gfx3d_a_clk_src, QCOM_SMD_RPM_MEM_CLK, 1);
+DEFINE_CLK_SMD_RPM(msm8994, snoc_clk, snoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 1);
+DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8994, bb_clk1, bb_clk1_a, 1);
+DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8994, bb_clk1_pin, bb_clk1_a_pin, 1);
+DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8994, bb_clk2, bb_clk2_a, 2);
+DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8994, bb_clk2_pin, bb_clk2_a_pin, 2);
+
+DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8994, div_clk1, div_clk1_a, 11);
+DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8994, div_clk2, div_clk2_a, 12);
+DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8994, div_clk3, div_clk3_a, 13);
+DEFINE_CLK_SMD_RPM(msm8994, ipa_clk, ipa_a_clk, QCOM_SMD_RPM_IPA_CLK, 0);
+DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8994, ln_bb_clk, ln_bb_a_clk, 8);
+DEFINE_CLK_SMD_RPM(msm8994, mmssnoc_ahb_clk, mmssnoc_ahb_a_clk,
+ QCOM_SMD_RPM_BUS_CLK, 3);
+DEFINE_CLK_SMD_RPM_QDSS(msm8994, qdss_clk, qdss_a_clk,
+ QCOM_SMD_RPM_MISC_CLK, 1);
+DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8994, rf_clk1, rf_clk1_a, 4);
+DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8994, rf_clk2, rf_clk2_a, 5);
+DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8994, rf_clk1_pin, rf_clk1_a_pin, 4);
+DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8994, rf_clk2_pin, rf_clk2_a_pin, 5);
+
+DEFINE_CLK_SMD_RPM(msm8994, ce1_clk, ce1_a_clk, QCOM_SMD_RPM_CE_CLK, 0);
+DEFINE_CLK_SMD_RPM(msm8994, ce2_clk, ce2_a_clk, QCOM_SMD_RPM_CE_CLK, 1);
+DEFINE_CLK_SMD_RPM(msm8994, ce3_clk, ce3_a_clk, QCOM_SMD_RPM_CE_CLK, 2);
+
+static struct clk_smd_rpm *msm8994_clks[] = {
+ [RPM_SMD_PNOC_CLK] = &msm8994_pnoc_clk,
+ [RPM_SMD_PNOC_A_CLK] = &msm8994_pnoc_a_clk,
+ [RPM_SMD_OCMEMGX_CLK] = &msm8994_ocmemgx_clk,
+ [RPM_SMD_OCMEMGX_A_CLK] = &msm8994_ocmemgx_a_clk,
+ [RPM_SMD_BIMC_CLK] = &msm8994_bimc_clk,
+ [RPM_SMD_BIMC_A_CLK] = &msm8994_bimc_a_clk,
+ [RPM_SMD_CNOC_CLK] = &msm8994_cnoc_clk,
+ [RPM_SMD_CNOC_A_CLK] = &msm8994_cnoc_a_clk,
+ [RPM_SMD_GFX3D_CLK_SRC] = &msm8994_gfx3d_clk_src,
+ [RPM_SMD_GFX3D_A_CLK_SRC] = &msm8994_gfx3d_a_clk_src,
+ [RPM_SMD_SNOC_CLK] = &msm8994_snoc_clk,
+ [RPM_SMD_SNOC_A_CLK] = &msm8994_snoc_a_clk,
+ [RPM_SMD_BB_CLK1] = &msm8994_bb_clk1,
+ [RPM_SMD_BB_CLK1_A] = &msm8994_bb_clk1_a,
+ [RPM_SMD_BB_CLK1_PIN] = &msm8994_bb_clk1_pin,
+ [RPM_SMD_BB_CLK1_A_PIN] = &msm8994_bb_clk1_a_pin,
+ [RPM_SMD_BB_CLK2] = &msm8994_bb_clk2,
+ [RPM_SMD_BB_CLK2_A] = &msm8994_bb_clk2_a,
+ [RPM_SMD_BB_CLK2_PIN] = &msm8994_bb_clk2_pin,
+ [RPM_SMD_BB_CLK2_A_PIN] = &msm8994_bb_clk2_a_pin,
+ [RPM_SMD_DIV_CLK1] = &msm8994_div_clk1,
+ [RPM_SMD_DIV_A_CLK1] = &msm8994_div_clk1_a,
+ [RPM_SMD_DIV_CLK2] = &msm8994_div_clk2,
+ [RPM_SMD_DIV_A_CLK2] = &msm8994_div_clk2_a,
+ [RPM_SMD_DIV_CLK3] = &msm8994_div_clk3,
+ [RPM_SMD_DIV_A_CLK3] = &msm8994_div_clk3_a,
+ [RPM_SMD_IPA_CLK] = &msm8994_ipa_clk,
+ [RPM_SMD_IPA_A_CLK] = &msm8994_ipa_a_clk,
+ [RPM_SMD_LN_BB_CLK] = &msm8994_ln_bb_clk,
+ [RPM_SMD_LN_BB_A_CLK] = &msm8994_ln_bb_a_clk,
+ [RPM_SMD_MMSSNOC_AHB_CLK] = &msm8994_mmssnoc_ahb_clk,
+ [RPM_SMD_MMSSNOC_AHB_A_CLK] = &msm8994_mmssnoc_ahb_a_clk,
+ [RPM_SMD_QDSS_CLK] = &msm8994_qdss_clk,
+ [RPM_SMD_QDSS_A_CLK] = &msm8994_qdss_a_clk,
+ [RPM_SMD_RF_CLK1] = &msm8994_rf_clk1,
+ [RPM_SMD_RF_CLK1_A] = &msm8994_rf_clk1_a,
+ [RPM_SMD_RF_CLK2] = &msm8994_rf_clk2,
+ [RPM_SMD_RF_CLK2_A] = &msm8994_rf_clk2_a,
+ [RPM_SMD_RF_CLK1_PIN] = &msm8994_rf_clk1_pin,
+ [RPM_SMD_RF_CLK1_A_PIN] = &msm8994_rf_clk1_a_pin,
+ [RPM_SMD_RF_CLK2_PIN] = &msm8994_rf_clk2_pin,
+ [RPM_SMD_RF_CLK2_A_PIN] = &msm8994_rf_clk2_a_pin,
+ [RPM_SMD_CE1_CLK] = &msm8994_ce1_clk,
+ [RPM_SMD_CE1_A_CLK] = &msm8994_ce1_a_clk,
+ [RPM_SMD_CE2_CLK] = &msm8994_ce2_clk,
+ [RPM_SMD_CE2_A_CLK] = &msm8994_ce2_a_clk,
+ [RPM_SMD_CE3_CLK] = &msm8994_ce3_clk,
+ [RPM_SMD_CE3_A_CLK] = &msm8994_ce3_a_clk,
+};
+
+static const struct rpm_smd_clk_desc rpm_clk_msm8994 = {
+ .clks = msm8994_clks,
+ .num_clks = ARRAY_SIZE(msm8994_clks),
+};
+
/* msm8996 */
DEFINE_CLK_SMD_RPM(msm8996, pcnoc_clk, pcnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 0);
DEFINE_CLK_SMD_RPM(msm8996, snoc_clk, snoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 1);
@@ -766,13 +984,92 @@ static const struct rpm_smd_clk_desc rpm_clk_msm8998 = {
.num_clks = ARRAY_SIZE(msm8998_clks),
};
+/* sdm660 */
+DEFINE_CLK_SMD_RPM_BRANCH(sdm660, bi_tcxo, bi_tcxo_a, QCOM_SMD_RPM_MISC_CLK, 0,
+ 19200000);
+DEFINE_CLK_SMD_RPM(sdm660, snoc_clk, snoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 1);
+DEFINE_CLK_SMD_RPM(sdm660, cnoc_clk, cnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 2);
+DEFINE_CLK_SMD_RPM(sdm660, cnoc_periph_clk, cnoc_periph_a_clk,
+ QCOM_SMD_RPM_BUS_CLK, 0);
+DEFINE_CLK_SMD_RPM(sdm660, bimc_clk, bimc_a_clk, QCOM_SMD_RPM_MEM_CLK, 0);
+DEFINE_CLK_SMD_RPM(sdm660, mmssnoc_axi_clk, mmssnoc_axi_a_clk,
+ QCOM_SMD_RPM_MMAXI_CLK, 0);
+DEFINE_CLK_SMD_RPM(sdm660, ipa_clk, ipa_a_clk, QCOM_SMD_RPM_IPA_CLK, 0);
+DEFINE_CLK_SMD_RPM(sdm660, ce1_clk, ce1_a_clk, QCOM_SMD_RPM_CE_CLK, 0);
+DEFINE_CLK_SMD_RPM(sdm660, aggre2_noc_clk, aggre2_noc_a_clk,
+ QCOM_SMD_RPM_AGGR_CLK, 2);
+DEFINE_CLK_SMD_RPM_QDSS(sdm660, qdss_clk, qdss_a_clk,
+ QCOM_SMD_RPM_MISC_CLK, 1);
+DEFINE_CLK_SMD_RPM_XO_BUFFER(sdm660, rf_clk1, rf_clk1_a, 4);
+DEFINE_CLK_SMD_RPM_XO_BUFFER(sdm660, div_clk1, div_clk1_a, 11);
+DEFINE_CLK_SMD_RPM_XO_BUFFER(sdm660, ln_bb_clk1, ln_bb_clk1_a, 1);
+DEFINE_CLK_SMD_RPM_XO_BUFFER(sdm660, ln_bb_clk2, ln_bb_clk2_a, 2);
+DEFINE_CLK_SMD_RPM_XO_BUFFER(sdm660, ln_bb_clk3, ln_bb_clk3_a, 3);
+
+DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(sdm660, rf_clk1_pin, rf_clk1_a_pin, 4);
+DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(sdm660, ln_bb_clk1_pin,
+ ln_bb_clk1_pin_a, 1);
+DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(sdm660, ln_bb_clk2_pin,
+ ln_bb_clk2_pin_a, 2);
+DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(sdm660, ln_bb_clk3_pin,
+ ln_bb_clk3_pin_a, 3);
+static struct clk_smd_rpm *sdm660_clks[] = {
+ [RPM_SMD_XO_CLK_SRC] = &sdm660_bi_tcxo,
+ [RPM_SMD_XO_A_CLK_SRC] = &sdm660_bi_tcxo_a,
+ [RPM_SMD_SNOC_CLK] = &sdm660_snoc_clk,
+ [RPM_SMD_SNOC_A_CLK] = &sdm660_snoc_a_clk,
+ [RPM_SMD_CNOC_CLK] = &sdm660_cnoc_clk,
+ [RPM_SMD_CNOC_A_CLK] = &sdm660_cnoc_a_clk,
+ [RPM_SMD_CNOC_PERIPH_CLK] = &sdm660_cnoc_periph_clk,
+ [RPM_SMD_CNOC_PERIPH_A_CLK] = &sdm660_cnoc_periph_a_clk,
+ [RPM_SMD_BIMC_CLK] = &sdm660_bimc_clk,
+ [RPM_SMD_BIMC_A_CLK] = &sdm660_bimc_a_clk,
+ [RPM_SMD_MMSSNOC_AXI_CLK] = &sdm660_mmssnoc_axi_clk,
+ [RPM_SMD_MMSSNOC_AXI_CLK_A] = &sdm660_mmssnoc_axi_a_clk,
+ [RPM_SMD_IPA_CLK] = &sdm660_ipa_clk,
+ [RPM_SMD_IPA_A_CLK] = &sdm660_ipa_a_clk,
+ [RPM_SMD_CE1_CLK] = &sdm660_ce1_clk,
+ [RPM_SMD_CE1_A_CLK] = &sdm660_ce1_a_clk,
+ [RPM_SMD_AGGR2_NOC_CLK] = &sdm660_aggre2_noc_clk,
+ [RPM_SMD_AGGR2_NOC_A_CLK] = &sdm660_aggre2_noc_a_clk,
+ [RPM_SMD_QDSS_CLK] = &sdm660_qdss_clk,
+ [RPM_SMD_QDSS_A_CLK] = &sdm660_qdss_a_clk,
+ [RPM_SMD_RF_CLK1] = &sdm660_rf_clk1,
+ [RPM_SMD_RF_CLK1_A] = &sdm660_rf_clk1_a,
+ [RPM_SMD_DIV_CLK1] = &sdm660_div_clk1,
+ [RPM_SMD_DIV_A_CLK1] = &sdm660_div_clk1_a,
+ [RPM_SMD_LN_BB_CLK] = &sdm660_ln_bb_clk1,
+ [RPM_SMD_LN_BB_A_CLK] = &sdm660_ln_bb_clk1_a,
+ [RPM_SMD_LN_BB_CLK2] = &sdm660_ln_bb_clk2,
+ [RPM_SMD_LN_BB_CLK2_A] = &sdm660_ln_bb_clk2_a,
+ [RPM_SMD_LN_BB_CLK3] = &sdm660_ln_bb_clk3,
+ [RPM_SMD_LN_BB_CLK3_A] = &sdm660_ln_bb_clk3_a,
+ [RPM_SMD_RF_CLK1_PIN] = &sdm660_rf_clk1_pin,
+ [RPM_SMD_RF_CLK1_A_PIN] = &sdm660_rf_clk1_a_pin,
+ [RPM_SMD_LN_BB_CLK1_PIN] = &sdm660_ln_bb_clk1_pin,
+ [RPM_SMD_LN_BB_CLK1_A_PIN] = &sdm660_ln_bb_clk1_pin_a,
+ [RPM_SMD_LN_BB_CLK2_PIN] = &sdm660_ln_bb_clk2_pin,
+ [RPM_SMD_LN_BB_CLK2_A_PIN] = &sdm660_ln_bb_clk2_pin_a,
+ [RPM_SMD_LN_BB_CLK3_PIN] = &sdm660_ln_bb_clk3_pin,
+ [RPM_SMD_LN_BB_CLK3_A_PIN] = &sdm660_ln_bb_clk3_pin_a,
+};
+
+static const struct rpm_smd_clk_desc rpm_clk_sdm660 = {
+ .clks = sdm660_clks,
+ .num_clks = ARRAY_SIZE(sdm660_clks),
+};
+
static const struct of_device_id rpm_smd_clk_match_table[] = {
{ .compatible = "qcom,rpmcc-msm8916", .data = &rpm_clk_msm8916 },
+ { .compatible = "qcom,rpmcc-msm8936", .data = &rpm_clk_msm8936 },
{ .compatible = "qcom,rpmcc-msm8974", .data = &rpm_clk_msm8974 },
{ .compatible = "qcom,rpmcc-msm8976", .data = &rpm_clk_msm8976 },
+ { .compatible = "qcom,rpmcc-msm8992", .data = &rpm_clk_msm8992 },
+ { .compatible = "qcom,rpmcc-msm8994", .data = &rpm_clk_msm8994 },
{ .compatible = "qcom,rpmcc-msm8996", .data = &rpm_clk_msm8996 },
{ .compatible = "qcom,rpmcc-msm8998", .data = &rpm_clk_msm8998 },
{ .compatible = "qcom,rpmcc-qcs404", .data = &rpm_clk_qcs404 },
+ { .compatible = "qcom,rpmcc-sdm660", .data = &rpm_clk_sdm660 },
{ }
};
MODULE_DEVICE_TABLE(of, rpm_smd_clk_match_table);
diff --git a/drivers/clk/qcom/gcc-ipq806x.c b/drivers/clk/qcom/gcc-ipq806x.c
index a8456e09c44d..d6b7adb4be38 100644
--- a/drivers/clk/qcom/gcc-ipq806x.c
+++ b/drivers/clk/qcom/gcc-ipq806x.c
@@ -3089,7 +3089,7 @@ static int gcc_ipq806x_probe(struct platform_device *pdev)
regmap_write(regmap, 0x3cf8, 8);
regmap_write(regmap, 0x3d18, 8);
- return 0;
+ return of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
}
static struct platform_driver gcc_ipq806x_driver = {
diff --git a/drivers/clk/qcom/gcc-ipq8074.c b/drivers/clk/qcom/gcc-ipq8074.c
index e01f5f591d1e..ef2c9c4cf9ab 100644
--- a/drivers/clk/qcom/gcc-ipq8074.c
+++ b/drivers/clk/qcom/gcc-ipq8074.c
@@ -4316,6 +4316,62 @@ static struct clk_branch gcc_gp3_clk = {
},
};
+static const struct freq_tbl ftbl_pcie_rchng_clk_src[] = {
+ F(19200000, P_XO, 1, 0, 0),
+ F(100000000, P_GPLL0, 8, 0, 0),
+ { }
+};
+
+struct clk_rcg2 pcie0_rchng_clk_src = {
+ .cmd_rcgr = 0x75070,
+ .freq_tbl = ftbl_pcie_rchng_clk_src,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "pcie0_rchng_clk_src",
+ .parent_hws = (const struct clk_hw *[]) {
+ &gpll0.clkr.hw },
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_branch gcc_pcie0_rchng_clk = {
+ .halt_reg = 0x75070,
+ .halt_bit = 31,
+ .clkr = {
+ .enable_reg = 0x75070,
+ .enable_mask = BIT(1),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_pcie0_rchng_clk",
+ .parent_hws = (const struct clk_hw *[]){
+ &pcie0_rchng_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_pcie0_axi_s_bridge_clk = {
+ .halt_reg = 0x75048,
+ .halt_bit = 31,
+ .clkr = {
+ .enable_reg = 0x75048,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_pcie0_axi_s_bridge_clk",
+ .parent_hws = (const struct clk_hw *[]){
+ &pcie0_axi_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
static struct clk_hw *gcc_ipq8074_hws[] = {
&gpll0_out_main_div2.hw,
&gpll6_out_main_div2.hw,
@@ -4551,6 +4607,9 @@ static struct clk_regmap *gcc_ipq8074_clks[] = {
[GCC_GP1_CLK] = &gcc_gp1_clk.clkr,
[GCC_GP2_CLK] = &gcc_gp2_clk.clkr,
[GCC_GP3_CLK] = &gcc_gp3_clk.clkr,
+ [GCC_PCIE0_RCHNG_CLK_SRC] = &pcie0_rchng_clk_src.clkr,
+ [GCC_PCIE0_RCHNG_CLK] = &gcc_pcie0_rchng_clk.clkr,
+ [GCC_PCIE0_AXI_S_BRIDGE_CLK] = &gcc_pcie0_axi_s_bridge_clk.clkr,
};
static const struct qcom_reset_map gcc_ipq8074_resets[] = {
@@ -4678,6 +4737,7 @@ static const struct qcom_reset_map gcc_ipq8074_resets[] = {
[GCC_PCIE0_AXI_SLAVE_ARES] = { 0x75040, 4 },
[GCC_PCIE0_AHB_ARES] = { 0x75040, 5 },
[GCC_PCIE0_AXI_MASTER_STICKY_ARES] = { 0x75040, 6 },
+ [GCC_PCIE0_AXI_SLAVE_STICKY_ARES] = { 0x75040, 7 },
[GCC_PCIE1_PIPE_ARES] = { 0x76040, 0 },
[GCC_PCIE1_SLEEP_ARES] = { 0x76040, 1 },
[GCC_PCIE1_CORE_STICKY_ARES] = { 0x76040, 2 },
diff --git a/drivers/clk/qcom/gcc-sc7180.c b/drivers/clk/qcom/gcc-sc7180.c
index ca4383e3a02a..68d8f7aaf64e 100644
--- a/drivers/clk/qcom/gcc-sc7180.c
+++ b/drivers/clk/qcom/gcc-sc7180.c
@@ -1061,7 +1061,7 @@ static struct clk_branch gcc_disp_gpll0_clk_src = {
.hw = &gpll0.clkr.hw,
},
.num_parents = 1,
- .ops = &clk_branch2_ops,
+ .ops = &clk_branch2_aon_ops,
},
},
};
@@ -2251,6 +2251,19 @@ static struct clk_branch gcc_mss_q6_memnoc_axi_clk = {
},
};
+static struct clk_branch gcc_lpass_cfg_noc_sway_clk = {
+ .halt_reg = 0x47018,
+ .halt_check = BRANCH_HALT_DELAY,
+ .clkr = {
+ .enable_reg = 0x47018,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_lpass_cfg_noc_sway_clk",
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
static struct gdsc ufs_phy_gdsc = {
.gdscr = 0x77004,
.pd = {
@@ -2428,6 +2441,7 @@ static struct clk_regmap *gcc_sc7180_clocks[] = {
[GCC_MSS_Q6_MEMNOC_AXI_CLK] = &gcc_mss_q6_memnoc_axi_clk.clkr,
[GCC_MSS_SNOC_AXI_CLK] = &gcc_mss_snoc_axi_clk.clkr,
[GCC_SEC_CTRL_CLK_SRC] = &gcc_sec_ctrl_clk_src.clkr,
+ [GCC_LPASS_CFG_NOC_SWAY_CLK] = &gcc_lpass_cfg_noc_sway_clk.clkr,
};
static const struct qcom_reset_map gcc_sc7180_resets[] = {
diff --git a/drivers/clk/qcom/gcc-sdm660.c b/drivers/clk/qcom/gcc-sdm660.c
index bf5730832ef3..f0b47b7d50ca 100644
--- a/drivers/clk/qcom/gcc-sdm660.c
+++ b/drivers/clk/qcom/gcc-sdm660.c
@@ -1715,6 +1715,9 @@ static struct clk_branch gcc_mss_cfg_ahb_clk = {
static struct clk_branch gcc_mss_mnoc_bimc_axi_clk = {
.halt_reg = 0x8a004,
+ .halt_check = BRANCH_HALT,
+ .hwcg_reg = 0x8a004,
+ .hwcg_bit = 1,
.clkr = {
.enable_reg = 0x8a004,
.enable_mask = BIT(0),
@@ -2402,6 +2405,7 @@ static const struct qcom_reset_map gcc_sdm660_resets[] = {
[GCC_USB_20_BCR] = { 0x2f000 },
[GCC_USB_30_BCR] = { 0xf000 },
[GCC_USB_PHY_CFG_AHB2PHY_BCR] = { 0x6a000 },
+ [GCC_MSS_RESTART] = { 0x79000 },
};
static const struct regmap_config gcc_sdm660_regmap_config = {
diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c
index f6ce888098be..90f7febaf528 100644
--- a/drivers/clk/qcom/gcc-sdm845.c
+++ b/drivers/clk/qcom/gcc-sdm845.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
/*
- * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018, 2020, The Linux Foundation. All rights reserved.
*/
#include <linux/kernel.h>
@@ -1344,7 +1344,7 @@ static struct clk_branch gcc_disp_gpll0_clk_src = {
"gpll0",
},
.num_parents = 1,
- .ops = &clk_branch2_ops,
+ .ops = &clk_branch2_aon_ops,
},
},
};
diff --git a/drivers/clk/qcom/gcc-sm8150.c b/drivers/clk/qcom/gcc-sm8150.c
index 72524cf11048..8e9b5b3cceaf 100644
--- a/drivers/clk/qcom/gcc-sm8150.c
+++ b/drivers/clk/qcom/gcc-sm8150.c
@@ -34,14 +34,8 @@ enum {
P_SLEEP_CLK,
};
-static const struct pll_vco trion_vco[] = {
- { 249600000, 2000000000, 0 },
-};
-
static struct clk_alpha_pll gpll0 = {
.offset = 0x0,
- .vco_table = trion_vco,
- .num_vco = ARRAY_SIZE(trion_vco),
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TRION],
.clkr = {
.enable_reg = 0x52000,
@@ -53,7 +47,7 @@ static struct clk_alpha_pll gpll0 = {
.name = "bi_tcxo",
},
.num_parents = 1,
- .ops = &clk_trion_fixed_pll_ops,
+ .ops = &clk_alpha_pll_fixed_trion_ops,
},
},
};
@@ -79,14 +73,12 @@ static struct clk_alpha_pll_postdiv gpll0_out_even = {
.hw = &gpll0.clkr.hw,
},
.num_parents = 1,
- .ops = &clk_trion_pll_postdiv_ops,
+ .ops = &clk_alpha_pll_postdiv_trion_ops,
},
};
static struct clk_alpha_pll gpll7 = {
.offset = 0x1a000,
- .vco_table = trion_vco,
- .num_vco = ARRAY_SIZE(trion_vco),
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TRION],
.clkr = {
.enable_reg = 0x52000,
@@ -98,15 +90,13 @@ static struct clk_alpha_pll gpll7 = {
.name = "bi_tcxo",
},
.num_parents = 1,
- .ops = &clk_trion_fixed_pll_ops,
+ .ops = &clk_alpha_pll_fixed_trion_ops,
},
},
};
static struct clk_alpha_pll gpll9 = {
.offset = 0x1c000,
- .vco_table = trion_vco,
- .num_vco = ARRAY_SIZE(trion_vco),
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TRION],
.clkr = {
.enable_reg = 0x52000,
@@ -118,7 +108,7 @@ static struct clk_alpha_pll gpll9 = {
.name = "bi_tcxo",
},
.num_parents = 1,
- .ops = &clk_trion_fixed_pll_ops,
+ .ops = &clk_alpha_pll_fixed_trion_ops,
},
},
};
@@ -1617,6 +1607,7 @@ static struct clk_branch gcc_gpu_cfg_ahb_clk = {
};
static struct clk_branch gcc_gpu_gpll0_clk_src = {
+ .halt_check = BRANCH_HALT_SKIP,
.clkr = {
.enable_reg = 0x52004,
.enable_mask = BIT(15),
@@ -1632,13 +1623,14 @@ static struct clk_branch gcc_gpu_gpll0_clk_src = {
};
static struct clk_branch gcc_gpu_gpll0_div_clk_src = {
+ .halt_check = BRANCH_HALT_SKIP,
.clkr = {
.enable_reg = 0x52004,
.enable_mask = BIT(16),
.hw.init = &(struct clk_init_data){
.name = "gcc_gpu_gpll0_div_clk_src",
.parent_hws = (const struct clk_hw *[]){
- &gcc_gpu_gpll0_clk_src.clkr.hw },
+ &gpll0_out_even.clkr.hw },
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
@@ -1729,6 +1721,7 @@ static struct clk_branch gcc_npu_cfg_ahb_clk = {
};
static struct clk_branch gcc_npu_gpll0_clk_src = {
+ .halt_check = BRANCH_HALT_SKIP,
.clkr = {
.enable_reg = 0x52004,
.enable_mask = BIT(18),
@@ -1744,13 +1737,14 @@ static struct clk_branch gcc_npu_gpll0_clk_src = {
};
static struct clk_branch gcc_npu_gpll0_div_clk_src = {
+ .halt_check = BRANCH_HALT_SKIP,
.clkr = {
.enable_reg = 0x52004,
.enable_mask = BIT(19),
.hw.init = &(struct clk_init_data){
.name = "gcc_npu_gpll0_div_clk_src",
.parent_hws = (const struct clk_hw *[]){
- &gcc_npu_gpll0_clk_src.clkr.hw },
+ &gpll0_out_even.clkr.hw },
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c
index 04944f11659b..bfc4ac02f9ea 100644
--- a/drivers/clk/qcom/gdsc.c
+++ b/drivers/clk/qcom/gdsc.c
@@ -6,6 +6,7 @@
#include <linux/bitops.h>
#include <linux/delay.h>
#include <linux/err.h>
+#include <linux/export.h>
#include <linux/jiffies.h>
#include <linux/kernel.h>
#include <linux/ktime.h>
@@ -29,6 +30,7 @@
/* CFG_GDSCR */
#define GDSC_POWER_UP_COMPLETE BIT(16)
#define GDSC_POWER_DOWN_COMPLETE BIT(15)
+#define GDSC_RETAIN_FF_ENABLE BIT(11)
#define CFG_GDSCR_OFFSET 0x4
/* 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)
regmap_update_bits(sc->regmap, sc->clamp_io_ctrl,
GMEM_RESET_MASK, 0);
}
+
+static void gdsc_retain_ff_on(struct gdsc *sc)
+{
+ u32 mask = GDSC_RETAIN_FF_ENABLE;
+
+ regmap_update_bits(sc->regmap, sc->gdscr, mask, mask);
+}
+
static int gdsc_enable(struct generic_pm_domain *domain)
{
struct gdsc *sc = domain_to_gdsc(domain);
@@ -268,6 +278,9 @@ static int gdsc_enable(struct generic_pm_domain *domain)
udelay(1);
}
+ if (sc->flags & RETAIN_FF_ENABLE)
+ gdsc_retain_ff_on(sc);
+
return 0;
}
@@ -433,3 +446,29 @@ void gdsc_unregister(struct gdsc_desc *desc)
}
of_genpd_del_provider(dev->of_node);
}
+
+/*
+ * On SDM845+ the GPU GX domain is *almost* entirely controlled by the GMU
+ * running in the CX domain so the CPU doesn't need to know anything about the
+ * GX domain EXCEPT....
+ *
+ * Hardware constraints dictate that the GX be powered down before the CX. If
+ * the GMU crashes it could leave the GX on. In order to successfully bring back
+ * the device the CPU needs to disable the GX headswitch. There being no sane
+ * way to reach in and touch that register from deep inside the GPU driver we
+ * need to set up the infrastructure to be able to ensure that the GPU can
+ * ensure that the GX is off during this super special case. We do this by
+ * defining a GX gdsc with a dummy enable function and a "default" disable
+ * function.
+ *
+ * This allows us to attach with genpd_dev_pm_attach_by_name() in the GPU
+ * driver. During power up, nothing will happen from the CPU (and the GMU will
+ * power up normally but during power down this will ensure that the GX domain
+ * is *really* off - this gives us a semi standard way of doing what we need.
+ */
+int gdsc_gx_do_nothing_enable(struct generic_pm_domain *domain)
+{
+ /* Do nothing but give genpd the impression that we were successful */
+ return 0;
+}
+EXPORT_SYMBOL_GPL(gdsc_gx_do_nothing_enable);
diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h
index c36fc26dcdff..bd537438c793 100644
--- a/drivers/clk/qcom/gdsc.h
+++ b/drivers/clk/qcom/gdsc.h
@@ -50,6 +50,7 @@ struct gdsc {
#define AON_RESET BIT(4)
#define POLL_CFG_GDSCR BIT(5)
#define ALWAYS_ON BIT(6)
+#define RETAIN_FF_ENABLE BIT(7)
struct reset_controller_dev *rcdev;
unsigned int *resets;
unsigned int reset_count;
@@ -68,6 +69,7 @@ struct gdsc_desc {
int gdsc_register(struct gdsc_desc *desc, struct reset_controller_dev *,
struct regmap *);
void gdsc_unregister(struct gdsc_desc *desc);
+int gdsc_gx_do_nothing_enable(struct generic_pm_domain *domain);
#else
static inline int gdsc_register(struct gdsc_desc *desc,
struct reset_controller_dev *rcdev,
diff --git a/drivers/clk/qcom/gpucc-sc7180.c b/drivers/clk/qcom/gpucc-sc7180.c
index 7b656b6aeced..88a739b6fec3 100644
--- a/drivers/clk/qcom/gpucc-sc7180.c
+++ b/drivers/clk/qcom/gpucc-sc7180.c
@@ -170,37 +170,12 @@ static struct gdsc cx_gdsc = {
.flags = VOTABLE,
};
-/*
- * On SC7180 the GPU GX domain is *almost* entirely controlled by the GMU
- * running in the CX domain so the CPU doesn't need to know anything about the
- * GX domain EXCEPT....
- *
- * Hardware constraints dictate that the GX be powered down before the CX. If
- * the GMU crashes it could leave the GX on. In order to successfully bring back
- * the device the CPU needs to disable the GX headswitch. There being no sane
- * way to reach in and touch that register from deep inside the GPU driver we
- * need to set up the infrastructure to be able to ensure that the GPU can
- * ensure that the GX is off during this super special case. We do this by
- * defining a GX gdsc with a dummy enable function and a "default" disable
- * function.
- *
- * This allows us to attach with genpd_dev_pm_attach_by_name() in the GPU
- * driver. During power up, nothing will happen from the CPU (and the GMU will
- * power up normally but during power down this will ensure that the GX domain
- * is *really* off - this gives us a semi standard way of doing what we need.
- */
-static int gx_gdsc_enable(struct generic_pm_domain *domain)
-{
- /* Do nothing but give genpd the impression that we were successful */
- return 0;
-}
-
static struct gdsc gx_gdsc = {
.gdscr = 0x100c,
.clamp_io_ctrl = 0x1508,
.pd = {
.name = "gx_gdsc",
- .power_on = gx_gdsc_enable,
+ .power_on = gdsc_gx_do_nothing_enable,
},
.pwrsts = PWRSTS_OFF_ON,
.flags = CLAMP_IO,
diff --git a/drivers/clk/qcom/gpucc-sdm845.c b/drivers/clk/qcom/gpucc-sdm845.c
index e40efba1bf7d..5663698b306b 100644
--- a/drivers/clk/qcom/gpucc-sdm845.c
+++ b/drivers/clk/qcom/gpucc-sdm845.c
@@ -131,37 +131,12 @@ static struct gdsc gpu_cx_gdsc = {
.flags = VOTABLE,
};
-/*
- * On SDM845 the GPU GX domain is *almost* entirely controlled by the GMU
- * running in the CX domain so the CPU doesn't need to know anything about the
- * GX domain EXCEPT....
- *
- * Hardware constraints dictate that the GX be powered down before the CX. If
- * the GMU crashes it could leave the GX on. In order to successfully bring back
- * the device the CPU needs to disable the GX headswitch. There being no sane
- * way to reach in and touch that register from deep inside the GPU driver we
- * need to set up the infrastructure to be able to ensure that the GPU can
- * ensure that the GX is off during this super special case. We do this by
- * defining a GX gdsc with a dummy enable function and a "default" disable
- * function.
- *
- * This allows us to attach with genpd_dev_pm_attach_by_name() in the GPU
- * driver. During power up, nothing will happen from the CPU (and the GMU will
- * power up normally but during power down this will ensure that the GX domain
- * is *really* off - this gives us a semi standard way of doing what we need.
- */
-static int gx_gdsc_enable(struct generic_pm_domain *domain)
-{
- /* Do nothing but give genpd the impression that we were successful */
- return 0;
-}
-
static struct gdsc gpu_gx_gdsc = {
.gdscr = 0x100c,
.clamp_io_ctrl = 0x1508,
.pd = {
.name = "gpu_gx_gdsc",
- .power_on = gx_gdsc_enable,
+ .power_on = gdsc_gx_do_nothing_enable,
},
.pwrsts = PWRSTS_OFF_ON,
.flags = CLAMP_IO | AON_RESET | POLL_CFG_GDSCR,
diff --git a/drivers/clk/qcom/gpucc-sm8150.c b/drivers/clk/qcom/gpucc-sm8150.c
new file mode 100644
index 000000000000..27c40754b2c7
--- /dev/null
+++ b/drivers/clk/qcom/gpucc-sm8150.c
@@ -0,0 +1,320 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/clock/qcom,gpucc-sm8150.h>
+
+#include "common.h"
+#include "clk-alpha-pll.h"
+#include "clk-branch.h"
+#include "clk-pll.h"
+#include "clk-rcg.h"
+#include "clk-regmap.h"
+#include "reset.h"
+#include "gdsc.h"
+
+enum {
+ P_BI_TCXO,
+ P_CORE_BI_PLL_TEST_SE,
+ P_GPLL0_OUT_MAIN,
+ P_GPLL0_OUT_MAIN_DIV,
+ P_GPU_CC_PLL1_OUT_MAIN,
+};
+
+static const struct pll_vco trion_vco[] = {
+ { 249600000, 2000000000, 0 },
+};
+
+static struct alpha_pll_config gpu_cc_pll1_config = {
+ .l = 0x1a,
+ .alpha = 0xaaa,
+ .config_ctl_val = 0x20485699,
+ .config_ctl_hi_val = 0x00002267,
+ .config_ctl_hi1_val = 0x00000024,
+ .test_ctl_val = 0x00000000,
+ .test_ctl_hi_val = 0x00000002,
+ .test_ctl_hi1_val = 0x00000000,
+ .user_ctl_val = 0x00000000,
+ .user_ctl_hi_val = 0x00000805,
+ .user_ctl_hi1_val = 0x000000d0,
+};
+
+static struct clk_alpha_pll gpu_cc_pll1 = {
+ .offset = 0x100,
+ .vco_table = trion_vco,
+ .num_vco = ARRAY_SIZE(trion_vco),
+ .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TRION],
+ .clkr = {
+ .hw.init = &(struct clk_init_data){
+ .name = "gpu_cc_pll1",
+ .parent_data = &(const struct clk_parent_data){
+ .fw_name = "bi_tcxo",
+ },
+ .num_parents = 1,
+ .ops = &clk_alpha_pll_trion_ops,
+ },
+ },
+};
+
+static const struct parent_map gpu_cc_parent_map_0[] = {
+ { P_BI_TCXO, 0 },
+ { P_GPU_CC_PLL1_OUT_MAIN, 3 },
+ { P_GPLL0_OUT_MAIN, 5 },
+ { P_GPLL0_OUT_MAIN_DIV, 6 },
+};
+
+static const struct clk_parent_data gpu_cc_parent_data_0[] = {
+ { .fw_name = "bi_tcxo" },
+ { .hw = &gpu_cc_pll1.clkr.hw },
+ { .fw_name = "gcc_gpu_gpll0_clk_src" },
+ { .fw_name = "gcc_gpu_gpll0_div_clk_src" },
+};
+
+static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = {
+ F(19200000, P_BI_TCXO, 1, 0, 0),
+ F(200000000, P_GPLL0_OUT_MAIN_DIV, 1.5, 0, 0),
+ F(500000000, P_GPU_CC_PLL1_OUT_MAIN, 1, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 gpu_cc_gmu_clk_src = {
+ .cmd_rcgr = 0x1120,
+ .mnd_width = 0,
+ .hid_width = 5,
+ .parent_map = gpu_cc_parent_map_0,
+ .freq_tbl = ftbl_gpu_cc_gmu_clk_src,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "gpu_cc_gmu_clk_src",
+ .parent_data = gpu_cc_parent_data_0,
+ .num_parents = ARRAY_SIZE(gpu_cc_parent_data_0),
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_branch gpu_cc_ahb_clk = {
+ .halt_reg = 0x1078,
+ .halt_check = BRANCH_HALT_DELAY,
+ .clkr = {
+ .enable_reg = 0x1078,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gpu_cc_ahb_clk",
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gpu_cc_crc_ahb_clk = {
+ .halt_reg = 0x107c,
+ .halt_check = BRANCH_HALT,
+ .clkr = {
+ .enable_reg = 0x107c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gpu_cc_crc_ahb_clk",
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gpu_cc_cx_apb_clk = {
+ .halt_reg = 0x1088,
+ .halt_check = BRANCH_HALT,
+ .clkr = {
+ .enable_reg = 0x1088,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gpu_cc_cx_apb_clk",
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gpu_cc_cx_gmu_clk = {
+ .halt_reg = 0x1098,
+ .halt_check = BRANCH_HALT,
+ .clkr = {
+ .enable_reg = 0x1098,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gpu_cc_cx_gmu_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &gpu_cc_gmu_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gpu_cc_cx_snoc_dvm_clk = {
+ .halt_reg = 0x108c,
+ .halt_check = BRANCH_HALT,
+ .clkr = {
+ .enable_reg = 0x108c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gpu_cc_cx_snoc_dvm_clk",
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gpu_cc_cxo_aon_clk = {
+ .halt_reg = 0x1004,
+ .halt_check = BRANCH_HALT,
+ .clkr = {
+ .enable_reg = 0x1004,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gpu_cc_cxo_aon_clk",
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gpu_cc_cxo_clk = {
+ .halt_reg = 0x109c,
+ .halt_check = BRANCH_HALT,
+ .clkr = {
+ .enable_reg = 0x109c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gpu_cc_cxo_clk",
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gpu_cc_gx_gmu_clk = {
+ .halt_reg = 0x1064,
+ .halt_check = BRANCH_HALT,
+ .clkr = {
+ .enable_reg = 0x1064,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gpu_cc_gx_gmu_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &gpu_cc_gmu_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct gdsc gpu_cx_gdsc = {
+ .gdscr = 0x106c,
+ .gds_hw_ctrl = 0x1540,
+ .pd = {
+ .name = "gpu_cx_gdsc",
+ },
+ .pwrsts = PWRSTS_OFF_ON,
+ .flags = VOTABLE,
+};
+
+static struct gdsc gpu_gx_gdsc = {
+ .gdscr = 0x100c,
+ .clamp_io_ctrl = 0x1508,
+ .pd = {
+ .name = "gpu_gx_gdsc",
+ .power_on = gdsc_gx_do_nothing_enable,
+ },
+ .pwrsts = PWRSTS_OFF_ON,
+ .flags = CLAMP_IO | AON_RESET | POLL_CFG_GDSCR,
+};
+
+static struct clk_regmap *gpu_cc_sm8150_clocks[] = {
+ [GPU_CC_AHB_CLK] = &gpu_cc_ahb_clk.clkr,
+ [GPU_CC_CRC_AHB_CLK] = &gpu_cc_crc_ahb_clk.clkr,
+ [GPU_CC_CX_APB_CLK] = &gpu_cc_cx_apb_clk.clkr,
+ [GPU_CC_CX_GMU_CLK] = &gpu_cc_cx_gmu_clk.clkr,
+ [GPU_CC_CX_SNOC_DVM_CLK] = &gpu_cc_cx_snoc_dvm_clk.clkr,
+ [GPU_CC_CXO_AON_CLK] = &gpu_cc_cxo_aon_clk.clkr,
+ [GPU_CC_CXO_CLK] = &gpu_cc_cxo_clk.clkr,
+ [GPU_CC_GMU_CLK_SRC] = &gpu_cc_gmu_clk_src.clkr,
+ [GPU_CC_GX_GMU_CLK] = &gpu_cc_gx_gmu_clk.clkr,
+ [GPU_CC_PLL1] = &gpu_cc_pll1.clkr,
+};
+
+static const struct qcom_reset_map gpu_cc_sm8150_resets[] = {
+ [GPUCC_GPU_CC_CX_BCR] = { 0x1068 },
+ [GPUCC_GPU_CC_GMU_BCR] = { 0x111c },
+ [GPUCC_GPU_CC_GX_BCR] = { 0x1008 },
+ [GPUCC_GPU_CC_SPDM_BCR] = { 0x1110 },
+ [GPUCC_GPU_CC_XO_BCR] = { 0x1000 },
+};
+
+static struct gdsc *gpu_cc_sm8150_gdscs[] = {
+ [GPU_CX_GDSC] = &gpu_cx_gdsc,
+ [GPU_GX_GDSC] = &gpu_gx_gdsc,
+};
+
+static const struct regmap_config gpu_cc_sm8150_regmap_config = {
+ .reg_bits = 32,
+ .reg_stride = 4,
+ .val_bits = 32,
+ .max_register = 0x8008,
+ .fast_io = true,
+};
+
+static const struct qcom_cc_desc gpu_cc_sm8150_desc = {
+ .config = &gpu_cc_sm8150_regmap_config,
+ .clks = gpu_cc_sm8150_clocks,
+ .num_clks = ARRAY_SIZE(gpu_cc_sm8150_clocks),
+ .resets = gpu_cc_sm8150_resets,
+ .num_resets = ARRAY_SIZE(gpu_cc_sm8150_resets),
+ .gdscs = gpu_cc_sm8150_gdscs,
+ .num_gdscs = ARRAY_SIZE(gpu_cc_sm8150_gdscs),
+};
+
+static const struct of_device_id gpu_cc_sm8150_match_table[] = {
+ { .compatible = "qcom,sm8150-gpucc" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, gpu_cc_sm8150_match_table);
+
+static int gpu_cc_sm8150_probe(struct platform_device *pdev)
+{
+ struct regmap *regmap;
+
+ regmap = qcom_cc_map(pdev, &gpu_cc_sm8150_desc);
+ if (IS_ERR(regmap))
+ return PTR_ERR(regmap);
+
+ clk_trion_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config);
+
+ return qcom_cc_really_probe(pdev, &gpu_cc_sm8150_desc, regmap);
+}
+
+static struct platform_driver gpu_cc_sm8150_driver = {
+ .probe = gpu_cc_sm8150_probe,
+ .driver = {
+ .name = "sm8150-gpucc",
+ .of_match_table = gpu_cc_sm8150_match_table,
+ },
+};
+
+static int __init gpu_cc_sm8150_init(void)
+{
+ return platform_driver_register(&gpu_cc_sm8150_driver);
+}
+subsys_initcall(gpu_cc_sm8150_init);
+
+static void __exit gpu_cc_sm8150_exit(void)
+{
+ platform_driver_unregister(&gpu_cc_sm8150_driver);
+}
+module_exit(gpu_cc_sm8150_exit);
+
+MODULE_DESCRIPTION("QTI GPUCC SM8150 Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/qcom/gpucc-sm8250.c b/drivers/clk/qcom/gpucc-sm8250.c
new file mode 100644
index 000000000000..3fa7d1f9ff98
--- /dev/null
+++ b/drivers/clk/qcom/gpucc-sm8250.c
@@ -0,0 +1,348 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/clock/qcom,gpucc-sm8250.h>
+
+#include "common.h"
+#include "clk-alpha-pll.h"
+#include "clk-branch.h"
+#include "clk-pll.h"
+#include "clk-rcg.h"
+#include "clk-regmap.h"
+#include "reset.h"
+#include "gdsc.h"
+
+#define CX_GMU_CBCR_SLEEP_MASK 0xf
+#define CX_GMU_CBCR_SLEEP_SHIFT 4
+#define CX_GMU_CBCR_WAKE_MASK 0xf
+#define CX_GMU_CBCR_WAKE_SHIFT 8
+
+enum {
+ P_BI_TCXO,
+ P_CORE_BI_PLL_TEST_SE,
+ P_GPLL0_OUT_MAIN,
+ P_GPLL0_OUT_MAIN_DIV,
+ P_GPU_CC_PLL0_OUT_MAIN,
+ P_GPU_CC_PLL1_OUT_MAIN,
+};
+
+static struct pll_vco lucid_vco[] = {
+ { 249600000, 2000000000, 0 },
+};
+
+static const struct alpha_pll_config gpu_cc_pll1_config = {
+ .l = 0x1a,
+ .alpha = 0xaaa,
+ .config_ctl_val = 0x20485699,
+ .config_ctl_hi_val = 0x00002261,
+ .config_ctl_hi1_val = 0x029a699c,
+ .user_ctl_val = 0x00000000,
+ .user_ctl_hi_val = 0x00000805,
+ .user_ctl_hi1_val = 0x00000000,
+};
+
+static struct clk_alpha_pll gpu_cc_pll1 = {
+ .offset = 0x100,
+ .vco_table = lucid_vco,
+ .num_vco = ARRAY_SIZE(lucid_vco),
+ .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID],
+ .clkr = {
+ .hw.init = &(struct clk_init_data){
+ .name = "gpu_cc_pll1",
+ .parent_data = &(const struct clk_parent_data){
+ .fw_name = "bi_tcxo",
+ },
+ .num_parents = 1,
+ .ops = &clk_alpha_pll_lucid_ops,
+ },
+ },
+};
+
+static const struct parent_map gpu_cc_parent_map_0[] = {
+ { P_BI_TCXO, 0 },
+ { P_GPU_CC_PLL1_OUT_MAIN, 3 },
+ { P_GPLL0_OUT_MAIN, 5 },
+ { P_GPLL0_OUT_MAIN_DIV, 6 },
+};
+
+static const struct clk_parent_data gpu_cc_parent_data_0[] = {
+ { .fw_name = "bi_tcxo" },
+ { .hw = &gpu_cc_pll1.clkr.hw },
+ { .fw_name = "gcc_gpu_gpll0_clk_src" },
+ { .fw_name = "gcc_gpu_gpll0_div_clk_src" },
+};
+
+static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = {
+ F(19200000, P_BI_TCXO, 1, 0, 0),
+ F(200000000, P_GPLL0_OUT_MAIN_DIV, 1.5, 0, 0),
+ F(500000000, P_GPU_CC_PLL1_OUT_MAIN, 1, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 gpu_cc_gmu_clk_src = {
+ .cmd_rcgr = 0x1120,
+ .mnd_width = 0,
+ .hid_width = 5,
+ .parent_map = gpu_cc_parent_map_0,
+ .freq_tbl = ftbl_gpu_cc_gmu_clk_src,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "gpu_cc_gmu_clk_src",
+ .parent_data = gpu_cc_parent_data_0,
+ .num_parents = ARRAY_SIZE(gpu_cc_parent_data_0),
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_branch gpu_cc_ahb_clk = {
+ .halt_reg = 0x1078,
+ .halt_check = BRANCH_HALT_DELAY,
+ .clkr = {
+ .enable_reg = 0x1078,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gpu_cc_ahb_clk",
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gpu_cc_crc_ahb_clk = {
+ .halt_reg = 0x107c,
+ .halt_check = BRANCH_HALT_VOTED,
+ .clkr = {
+ .enable_reg = 0x107c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gpu_cc_crc_ahb_clk",
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gpu_cc_cx_apb_clk = {
+ .halt_reg = 0x1088,
+ .halt_check = BRANCH_HALT_VOTED,
+ .clkr = {
+ .enable_reg = 0x1088,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gpu_cc_cx_apb_clk",
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gpu_cc_cx_gmu_clk = {
+ .halt_reg = 0x1098,
+ .halt_check = BRANCH_HALT,
+ .clkr = {
+ .enable_reg = 0x1098,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gpu_cc_cx_gmu_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &gpu_cc_gmu_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gpu_cc_cx_snoc_dvm_clk = {
+ .halt_reg = 0x108c,
+ .halt_check = BRANCH_HALT_VOTED,
+ .clkr = {
+ .enable_reg = 0x108c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gpu_cc_cx_snoc_dvm_clk",
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gpu_cc_cxo_aon_clk = {
+ .halt_reg = 0x1004,
+ .halt_check = BRANCH_HALT_VOTED,
+ .clkr = {
+ .enable_reg = 0x1004,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gpu_cc_cxo_aon_clk",
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gpu_cc_cxo_clk = {
+ .halt_reg = 0x109c,
+ .halt_check = BRANCH_HALT,
+ .clkr = {
+ .enable_reg = 0x109c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gpu_cc_cxo_clk",
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gpu_cc_gx_gmu_clk = {
+ .halt_reg = 0x1064,
+ .halt_check = BRANCH_HALT,
+ .clkr = {
+ .enable_reg = 0x1064,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gpu_cc_gx_gmu_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &gpu_cc_gmu_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gpu_cc_hlos1_vote_gpu_smmu_clk = {
+ .halt_reg = 0x5000,
+ .halt_check = BRANCH_VOTED,
+ .clkr = {
+ .enable_reg = 0x5000,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gpu_cc_hlos1_vote_gpu_smmu_clk",
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct gdsc gpu_cx_gdsc = {
+ .gdscr = 0x106c,
+ .gds_hw_ctrl = 0x1540,
+ .pd = {
+ .name = "gpu_cx_gdsc",
+ },
+ .pwrsts = PWRSTS_OFF_ON,
+ .flags = VOTABLE,
+};
+
+static struct gdsc gpu_gx_gdsc = {
+ .gdscr = 0x100c,
+ .clamp_io_ctrl = 0x1508,
+ .pd = {
+ .name = "gpu_gx_gdsc",
+ .power_on = gdsc_gx_do_nothing_enable,
+ },
+ .pwrsts = PWRSTS_OFF_ON,
+ .flags = CLAMP_IO | AON_RESET | POLL_CFG_GDSCR,
+};
+
+static struct clk_regmap *gpu_cc_sm8250_clocks[] = {
+ [GPU_CC_AHB_CLK] = &gpu_cc_ahb_clk.clkr,
+ [GPU_CC_CRC_AHB_CLK] = &gpu_cc_crc_ahb_clk.clkr,
+ [GPU_CC_CX_APB_CLK] = &gpu_cc_cx_apb_clk.clkr,
+ [GPU_CC_CX_GMU_CLK] = &gpu_cc_cx_gmu_clk.clkr,
+ [GPU_CC_CX_SNOC_DVM_CLK] = &gpu_cc_cx_snoc_dvm_clk.clkr,
+ [GPU_CC_CXO_AON_CLK] = &gpu_cc_cxo_aon_clk.clkr,
+ [GPU_CC_CXO_CLK] = &gpu_cc_cxo_clk.clkr,
+ [GPU_CC_GMU_CLK_SRC] = &gpu_cc_gmu_clk_src.clkr,
+ [GPU_CC_GX_GMU_CLK] = &gpu_cc_gx_gmu_clk.clkr,
+ [GPU_CC_PLL1] = &gpu_cc_pll1.clkr,
+ [GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK] = &gpu_cc_hlos1_vote_gpu_smmu_clk.clkr,
+};
+
+static const struct qcom_reset_map gpu_cc_sm8250_resets[] = {
+ [GPUCC_GPU_CC_ACD_BCR] = { 0x1160 },
+ [GPUCC_GPU_CC_CX_BCR] = { 0x1068 },
+ [GPUCC_GPU_CC_GFX3D_AON_BCR] = { 0x10a0 },
+ [GPUCC_GPU_CC_GMU_BCR] = { 0x111c },
+ [GPUCC_GPU_CC_GX_BCR] = { 0x1008 },
+ [GPUCC_GPU_CC_XO_BCR] = { 0x1000 },
+};
+
+static struct gdsc *gpu_cc_sm8250_gdscs[] = {
+ [GPU_CX_GDSC] = &gpu_cx_gdsc,
+ [GPU_GX_GDSC] = &gpu_gx_gdsc,
+};
+
+static const struct regmap_config gpu_cc_sm8250_regmap_config = {
+ .reg_bits = 32,
+ .reg_stride = 4,
+ .val_bits = 32,
+ .max_register = 0x8008,
+ .fast_io = true,
+};
+
+static const struct qcom_cc_desc gpu_cc_sm8250_desc = {
+ .config = &gpu_cc_sm8250_regmap_config,
+ .clks = gpu_cc_sm8250_clocks,
+ .num_clks = ARRAY_SIZE(gpu_cc_sm8250_clocks),
+ .resets = gpu_cc_sm8250_resets,
+ .num_resets = ARRAY_SIZE(gpu_cc_sm8250_resets),
+ .gdscs = gpu_cc_sm8250_gdscs,
+ .num_gdscs = ARRAY_SIZE(gpu_cc_sm8250_gdscs),
+};
+
+static const struct of_device_id gpu_cc_sm8250_match_table[] = {
+ { .compatible = "qcom,sm8250-gpucc" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, gpu_cc_sm8250_match_table);
+
+static int gpu_cc_sm8250_probe(struct platform_device *pdev)
+{
+ struct regmap *regmap;
+ unsigned int value, mask;
+
+ regmap = qcom_cc_map(pdev, &gpu_cc_sm8250_desc);
+ if (IS_ERR(regmap))
+ return PTR_ERR(regmap);
+
+ clk_lucid_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config);
+
+ /*
+ * Configure gpu_cc_cx_gmu_clk with recommended
+ * wakeup/sleep settings
+ */
+ mask = CX_GMU_CBCR_WAKE_MASK << CX_GMU_CBCR_WAKE_SHIFT;
+ mask |= CX_GMU_CBCR_SLEEP_MASK << CX_GMU_CBCR_SLEEP_SHIFT;
+ value = 0xf << CX_GMU_CBCR_WAKE_SHIFT | 0xf << CX_GMU_CBCR_SLEEP_SHIFT;
+ regmap_update_bits(regmap, 0x1098, mask, value);
+
+ return qcom_cc_really_probe(pdev, &gpu_cc_sm8250_desc, regmap);
+}
+
+static struct platform_driver gpu_cc_sm8250_driver = {
+ .probe = gpu_cc_sm8250_probe,
+ .driver = {
+ .name = "sm8250-gpucc",
+ .of_match_table = gpu_cc_sm8250_match_table,
+ },
+};
+
+static int __init gpu_cc_sm8250_init(void)
+{
+ return platform_driver_register(&gpu_cc_sm8250_driver);
+}
+subsys_initcall(gpu_cc_sm8250_init);
+
+static void __exit gpu_cc_sm8250_exit(void)
+{
+ platform_driver_unregister(&gpu_cc_sm8250_driver);
+}
+module_exit(gpu_cc_sm8250_exit);
+
+MODULE_DESCRIPTION("QTI GPU_CC SM8250 Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/qcom/lpasscorecc-sc7180.c b/drivers/clk/qcom/lpasscorecc-sc7180.c
new file mode 100644
index 000000000000..d4c1864e1ee9
--- /dev/null
+++ b/drivers/clk/qcom/lpasscorecc-sc7180.c
@@ -0,0 +1,476 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/pm_clock.h>
+#include <linux/pm_runtime.h>
+#include <linux/of.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/clock/qcom,lpasscorecc-sc7180.h>
+
+#include "clk-alpha-pll.h"
+#include "clk-branch.h"
+#include "clk-rcg.h"
+#include "clk-regmap.h"
+#include "common.h"
+#include "gdsc.h"
+
+enum {
+ P_BI_TCXO,
+ P_LPASS_LPAAUDIO_DIG_PLL_OUT_ODD,
+ P_SLEEP_CLK,
+};
+
+static struct pll_vco fabia_vco[] = {
+ { 249600000, 2000000000, 0 },
+};
+
+static const struct alpha_pll_config lpass_lpaaudio_dig_pll_config = {
+ .l = 0x20,
+ .alpha = 0x0,
+ .config_ctl_val = 0x20485699,
+ .config_ctl_hi_val = 0x00002067,
+ .test_ctl_val = 0x40000000,
+ .test_ctl_hi_val = 0x00000000,
+ .user_ctl_val = 0x00005105,
+ .user_ctl_hi_val = 0x00004805,
+};
+
+static const u8 clk_alpha_pll_regs_offset[][PLL_OFF_MAX_REGS] = {
+ [CLK_ALPHA_PLL_TYPE_FABIA] = {
+ [PLL_OFF_L_VAL] = 0x04,
+ [PLL_OFF_CAL_L_VAL] = 0x8,
+ [PLL_OFF_USER_CTL] = 0x0c,
+ [PLL_OFF_USER_CTL_U] = 0x10,
+ [PLL_OFF_USER_CTL_U1] = 0x14,
+ [PLL_OFF_CONFIG_CTL] = 0x18,
+ [PLL_OFF_CONFIG_CTL_U] = 0x1C,
+ [PLL_OFF_CONFIG_CTL_U1] = 0x20,
+ [PLL_OFF_TEST_CTL] = 0x24,
+ [PLL_OFF_TEST_CTL_U] = 0x28,
+ [PLL_OFF_STATUS] = 0x30,
+ [PLL_OFF_OPMODE] = 0x38,
+ [PLL_OFF_FRAC] = 0x40,
+ },
+};
+
+static struct clk_alpha_pll lpass_lpaaudio_dig_pll = {
+ .offset = 0x1000,
+ .vco_table = fabia_vco,
+ .num_vco = ARRAY_SIZE(fabia_vco),
+ .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_FABIA],
+ .clkr = {
+ .hw.init = &(struct clk_init_data){
+ .name = "lpass_lpaaudio_dig_pll",
+ .parent_data = &(const struct clk_parent_data){
+ .fw_name = "bi_tcxo",
+ },
+ .num_parents = 1,
+ .ops = &clk_alpha_pll_fabia_ops,
+ },
+ },
+};
+
+static const struct clk_div_table
+ post_div_table_lpass_lpaaudio_dig_pll_out_odd[] = {
+ { 0x5, 5 },
+ { }
+};
+
+static struct clk_alpha_pll_postdiv lpass_lpaaudio_dig_pll_out_odd = {
+ .offset = 0x1000,
+ .post_div_shift = 12,
+ .post_div_table = post_div_table_lpass_lpaaudio_dig_pll_out_odd,
+ .num_post_div =
+ ARRAY_SIZE(post_div_table_lpass_lpaaudio_dig_pll_out_odd),
+ .width = 4,
+ .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "lpass_lpaaudio_dig_pll_out_odd",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &lpass_lpaaudio_dig_pll.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_alpha_pll_postdiv_fabia_ops,
+ },
+};
+
+static const struct parent_map lpass_core_cc_parent_map_0[] = {
+ { P_BI_TCXO, 0 },
+ { P_LPASS_LPAAUDIO_DIG_PLL_OUT_ODD, 5 },
+};
+
+static const struct clk_parent_data lpass_core_cc_parent_data_0[] = {
+ { .fw_name = "bi_tcxo" },
+ { .hw = &lpass_lpaaudio_dig_pll_out_odd.clkr.hw },
+};
+
+static const struct parent_map lpass_core_cc_parent_map_2[] = {
+ { P_BI_TCXO, 0 },
+};
+
+static struct clk_rcg2 core_clk_src = {
+ .cmd_rcgr = 0x1d000,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = lpass_core_cc_parent_map_2,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "core_clk_src",
+ .parent_data = &(const struct clk_parent_data){
+ .fw_name = "bi_tcxo",
+ },
+ .num_parents = 1,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_ext_mclk0_clk_src[] = {
+ F(9600000, P_BI_TCXO, 2, 0, 0),
+ F(19200000, P_BI_TCXO, 1, 0, 0),
+ { }
+};
+
+static const struct freq_tbl ftbl_ext_lpaif_clk_src[] = {
+ F(256000, P_LPASS_LPAAUDIO_DIG_PLL_OUT_ODD, 15, 1, 32),
+ F(512000, P_LPASS_LPAAUDIO_DIG_PLL_OUT_ODD, 15, 1, 16),
+ F(768000, P_LPASS_LPAAUDIO_DIG_PLL_OUT_ODD, 10, 1, 16),
+ F(1024000, P_LPASS_LPAAUDIO_DIG_PLL_OUT_ODD, 15, 1, 8),
+ F(1536000, P_LPASS_LPAAUDIO_DIG_PLL_OUT_ODD, 10, 1, 8),
+ F(2048000, P_LPASS_LPAAUDIO_DIG_PLL_OUT_ODD, 15, 1, 4),
+ F(3072000, P_LPASS_LPAAUDIO_DIG_PLL_OUT_ODD, 10, 1, 4),
+ F(4096000, P_LPASS_LPAAUDIO_DIG_PLL_OUT_ODD, 15, 1, 2),
+ F(6144000, P_LPASS_LPAAUDIO_DIG_PLL_OUT_ODD, 10, 1, 2),
+ F(8192000, P_LPASS_LPAAUDIO_DIG_PLL_OUT_ODD, 15, 0, 0),
+ F(9600000, P_BI_TCXO, 2, 0, 0),
+ F(12288000, P_LPASS_LPAAUDIO_DIG_PLL_OUT_ODD, 10, 0, 0),
+ F(19200000, P_BI_TCXO, 1, 0, 0),
+ F(24576000, P_LPASS_LPAAUDIO_DIG_PLL_OUT_ODD, 5, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 ext_mclk0_clk_src = {
+ .cmd_rcgr = 0x20000,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = lpass_core_cc_parent_map_0,
+ .freq_tbl = ftbl_ext_mclk0_clk_src,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "ext_mclk0_clk_src",
+ .parent_data = lpass_core_cc_parent_data_0,
+ .num_parents = 2,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 lpaif_pri_clk_src = {
+ .cmd_rcgr = 0x10000,
+ .mnd_width = 16,
+ .hid_width = 5,
+ .parent_map = lpass_core_cc_parent_map_0,
+ .freq_tbl = ftbl_ext_lpaif_clk_src,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "lpaif_pri_clk_src",
+ .parent_data = lpass_core_cc_parent_data_0,
+ .num_parents = 2,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 lpaif_sec_clk_src = {
+ .cmd_rcgr = 0x11000,
+ .mnd_width = 16,
+ .hid_width = 5,
+ .parent_map = lpass_core_cc_parent_map_0,
+ .freq_tbl = ftbl_ext_lpaif_clk_src,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "lpaif_sec_clk_src",
+ .parent_data = lpass_core_cc_parent_data_0,
+ .num_parents = 2,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_branch lpass_audio_core_ext_mclk0_clk = {
+ .halt_reg = 0x20014,
+ .halt_check = BRANCH_HALT,
+ .hwcg_reg = 0x20014,
+ .hwcg_bit = 1,
+ .clkr = {
+ .enable_reg = 0x20014,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "lpass_audio_core_ext_mclk0_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &ext_mclk0_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch lpass_audio_core_lpaif_pri_ibit_clk = {
+ .halt_reg = 0x10018,
+ .halt_check = BRANCH_HALT,
+ .hwcg_reg = 0x10018,
+ .hwcg_bit = 1,
+ .clkr = {
+ .enable_reg = 0x10018,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "lpass_audio_core_lpaif_pri_ibit_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &lpaif_pri_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch lpass_audio_core_lpaif_sec_ibit_clk = {
+ .halt_reg = 0x11018,
+ .halt_check = BRANCH_HALT,
+ .hwcg_reg = 0x11018,
+ .hwcg_bit = 1,
+ .clkr = {
+ .enable_reg = 0x11018,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "lpass_audio_core_lpaif_sec_ibit_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &lpaif_sec_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch lpass_audio_core_sysnoc_mport_core_clk = {
+ .halt_reg = 0x23000,
+ .halt_check = BRANCH_HALT,
+ .hwcg_reg = 0x23000,
+ .hwcg_bit = 1,
+ .clkr = {
+ .enable_reg = 0x23000,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "lpass_audio_core_sysnoc_mport_core_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &core_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_regmap *lpass_core_cc_sc7180_clocks[] = {
+ [EXT_MCLK0_CLK_SRC] = &ext_mclk0_clk_src.clkr,
+ [LPAIF_PRI_CLK_SRC] = &lpaif_pri_clk_src.clkr,
+ [LPAIF_SEC_CLK_SRC] = &lpaif_sec_clk_src.clkr,
+ [CORE_CLK_SRC] = &core_clk_src.clkr,
+ [LPASS_AUDIO_CORE_EXT_MCLK0_CLK] = &lpass_audio_core_ext_mclk0_clk.clkr,
+ [LPASS_AUDIO_CORE_LPAIF_PRI_IBIT_CLK] =
+ &lpass_audio_core_lpaif_pri_ibit_clk.clkr,
+ [LPASS_AUDIO_CORE_LPAIF_SEC_IBIT_CLK] =
+ &lpass_audio_core_lpaif_sec_ibit_clk.clkr,
+ [LPASS_AUDIO_CORE_SYSNOC_MPORT_CORE_CLK] =
+ &lpass_audio_core_sysnoc_mport_core_clk.clkr,
+ [LPASS_LPAAUDIO_DIG_PLL] = &lpass_lpaaudio_dig_pll.clkr,
+ [LPASS_LPAAUDIO_DIG_PLL_OUT_ODD] = &lpass_lpaaudio_dig_pll_out_odd.clkr,
+};
+
+static struct gdsc lpass_pdc_hm_gdsc = {
+ .gdscr = 0x3090,
+ .pd = {
+ .name = "lpass_pdc_hm_gdsc",
+ },
+ .pwrsts = PWRSTS_OFF_ON,
+ .flags = VOTABLE,
+};
+
+static struct gdsc lpass_audio_hm_gdsc = {
+ .gdscr = 0x9090,
+ .pd = {
+ .name = "lpass_audio_hm_gdsc",
+ },
+ .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc lpass_core_hm_gdsc = {
+ .gdscr = 0x0,
+ .pd = {
+ .name = "lpass_core_hm_gdsc",
+ },
+ .pwrsts = PWRSTS_OFF_ON,
+ .flags = RETAIN_FF_ENABLE,
+};
+
+static struct gdsc *lpass_core_hm_sc7180_gdscs[] = {
+ [LPASS_CORE_HM_GDSCR] = &lpass_core_hm_gdsc,
+};
+
+static struct gdsc *lpass_audio_hm_sc7180_gdscs[] = {
+ [LPASS_PDC_HM_GDSCR] = &lpass_pdc_hm_gdsc,
+ [LPASS_AUDIO_HM_GDSCR] = &lpass_audio_hm_gdsc,
+};
+
+static struct regmap_config lpass_core_cc_sc7180_regmap_config = {
+ .reg_bits = 32,
+ .reg_stride = 4,
+ .val_bits = 32,
+ .fast_io = true,
+};
+
+static const struct qcom_cc_desc lpass_core_hm_sc7180_desc = {
+ .config = &lpass_core_cc_sc7180_regmap_config,
+ .gdscs = lpass_core_hm_sc7180_gdscs,
+ .num_gdscs = ARRAY_SIZE(lpass_core_hm_sc7180_gdscs),
+};
+
+static const struct qcom_cc_desc lpass_core_cc_sc7180_desc = {
+ .config = &lpass_core_cc_sc7180_regmap_config,
+ .clks = lpass_core_cc_sc7180_clocks,
+ .num_clks = ARRAY_SIZE(lpass_core_cc_sc7180_clocks),
+};
+
+static const struct qcom_cc_desc lpass_audio_hm_sc7180_desc = {
+ .config = &lpass_core_cc_sc7180_regmap_config,
+ .gdscs = lpass_audio_hm_sc7180_gdscs,
+ .num_gdscs = ARRAY_SIZE(lpass_audio_hm_sc7180_gdscs),
+};
+
+static int lpass_core_cc_sc7180_probe(struct platform_device *pdev)
+{
+ const struct qcom_cc_desc *desc;
+ struct regmap *regmap;
+ int ret;
+
+ lpass_core_cc_sc7180_regmap_config.name = "lpass_audio_cc";
+ desc = &lpass_audio_hm_sc7180_desc;
+ ret = qcom_cc_probe_by_index(pdev, 1, desc);
+ if (ret)
+ return ret;
+
+ lpass_core_cc_sc7180_regmap_config.name = "lpass_core_cc";
+ regmap = qcom_cc_map(pdev, &lpass_core_cc_sc7180_desc);
+ if (IS_ERR(regmap))
+ return PTR_ERR(regmap);
+
+ /*
+ * Keep the CLK always-ON
+ * LPASS_AUDIO_CORE_SYSNOC_SWAY_CORE_CLK
+ */
+ regmap_update_bits(regmap, 0x24000, BIT(0), BIT(0));
+
+ /* PLL settings */
+ regmap_write(regmap, 0x1008, 0x20);
+ regmap_update_bits(regmap, 0x1014, BIT(0), BIT(0));
+
+ clk_fabia_pll_configure(&lpass_lpaaudio_dig_pll, regmap,
+ &lpass_lpaaudio_dig_pll_config);
+
+ return qcom_cc_really_probe(pdev, &lpass_core_cc_sc7180_desc, regmap);
+}
+
+static int lpass_hm_core_probe(struct platform_device *pdev)
+{
+ const struct qcom_cc_desc *desc;
+
+ lpass_core_cc_sc7180_regmap_config.name = "lpass_hm_core";
+ desc = &lpass_core_hm_sc7180_desc;
+
+ return qcom_cc_probe_by_index(pdev, 0, desc);
+}
+
+static const struct of_device_id lpass_core_cc_sc7180_match_table[] = {
+ {
+ .compatible = "qcom,sc7180-lpasshm",
+ .data = lpass_hm_core_probe,
+ },
+ {
+ .compatible = "qcom,sc7180-lpasscorecc",
+ .data = lpass_core_cc_sc7180_probe,
+ },
+ { }
+};
+MODULE_DEVICE_TABLE(of, lpass_core_cc_sc7180_match_table);
+
+static int lpass_core_sc7180_probe(struct platform_device *pdev)
+{
+ int (*clk_probe)(struct platform_device *p);
+ int ret;
+
+ pm_runtime_enable(&pdev->dev);
+ ret = pm_clk_create(&pdev->dev);
+ if (ret)
+ return ret;
+
+ ret = pm_clk_add(&pdev->dev, "iface");
+ if (ret < 0) {
+ dev_err(&pdev->dev, "failed to acquire iface clock\n");
+ goto disable_pm_runtime;
+ }
+
+ clk_probe = of_device_get_match_data(&pdev->dev);
+ if (!clk_probe)
+ return -EINVAL;
+
+ ret = clk_probe(pdev);
+ if (ret)
+ goto destroy_pm_clk;
+
+ return 0;
+
+destroy_pm_clk:
+ pm_clk_destroy(&pdev->dev);
+
+disable_pm_runtime:
+ pm_runtime_disable(&pdev->dev);
+
+ return ret;
+}
+
+static const struct dev_pm_ops lpass_core_cc_pm_ops = {
+ SET_RUNTIME_PM_OPS(pm_clk_suspend, pm_clk_resume, NULL)
+};
+
+static struct platform_driver lpass_core_cc_sc7180_driver = {
+ .probe = lpass_core_sc7180_probe,
+ .driver = {
+ .name = "lpass_core_cc-sc7180",
+ .of_match_table = lpass_core_cc_sc7180_match_table,
+ .pm = &lpass_core_cc_pm_ops,
+ },
+};
+
+static int __init lpass_core_cc_sc7180_init(void)
+{
+ return platform_driver_register(&lpass_core_cc_sc7180_driver);
+}
+subsys_initcall(lpass_core_cc_sc7180_init);
+
+static void __exit lpass_core_cc_sc7180_exit(void)
+{
+ platform_driver_unregister(&lpass_core_cc_sc7180_driver);
+}
+module_exit(lpass_core_cc_sc7180_exit);
+
+MODULE_DESCRIPTION("QTI LPASS_CORE_CC SC7180 Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig
index 9eb79bf90643..28e8730ce263 100644
--- a/drivers/clk/renesas/Kconfig
+++ b/drivers/clk/renesas/Kconfig
@@ -15,6 +15,7 @@ config CLK_RENESAS
select CLK_R8A774A1 if ARCH_R8A774A1
select CLK_R8A774B1 if ARCH_R8A774B1
select CLK_R8A774C0 if ARCH_R8A774C0
+ select CLK_R8A774E1 if ARCH_R8A774E1
select CLK_R8A7778 if ARCH_R8A7778
select CLK_R8A7779 if ARCH_R8A7779
select CLK_R8A7790 if ARCH_R8A7790
@@ -84,6 +85,10 @@ config CLK_R8A774C0
bool "RZ/G2E clock support" if COMPILE_TEST
select CLK_RCAR_GEN3_CPG
+config CLK_R8A774E1
+ bool "RZ/G2H clock support" if COMPILE_TEST
+ select CLK_RCAR_GEN3_CPG
+
config CLK_R8A7778
bool "R-Car M1A clock support" if COMPILE_TEST
select CLK_RENESAS_CPG_MSTP
diff --git a/drivers/clk/renesas/Makefile b/drivers/clk/renesas/Makefile
index a4066f9b34ef..c7c03ab9a6a3 100644
--- a/drivers/clk/renesas/Makefile
+++ b/drivers/clk/renesas/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_CLK_R8A77470) += r8a77470-cpg-mssr.o
obj-$(CONFIG_CLK_R8A774A1) += r8a774a1-cpg-mssr.o
obj-$(CONFIG_CLK_R8A774B1) += r8a774b1-cpg-mssr.o
obj-$(CONFIG_CLK_R8A774C0) += r8a774c0-cpg-mssr.o
+obj-$(CONFIG_CLK_R8A774E1) += r8a774e1-cpg-mssr.o
obj-$(CONFIG_CLK_R8A7778) += clk-r8a7778.o
obj-$(CONFIG_CLK_R8A7779) += clk-r8a7779.o
obj-$(CONFIG_CLK_R8A7790) += r8a7790-cpg-mssr.o
diff --git a/drivers/clk/renesas/r8a774a1-cpg-mssr.c b/drivers/clk/renesas/r8a774a1-cpg-mssr.c
index e05bfa200480..fd54b9f625da 100644
--- a/drivers/clk/renesas/r8a774a1-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a774a1-cpg-mssr.c
@@ -237,6 +237,7 @@ static const struct mssr_mod_clk r8a774a1_mod_clks[] __initconst = {
};
static const unsigned int r8a774a1_crit_mod_clks[] __initconst = {
+ MOD_CLK_ID(402), /* RWDT */
MOD_CLK_ID(408), /* INTC-AP (GIC) */
};
diff --git a/drivers/clk/renesas/r8a774b1-cpg-mssr.c b/drivers/clk/renesas/r8a774b1-cpg-mssr.c
index c9af70917312..f436691271ec 100644
--- a/drivers/clk/renesas/r8a774b1-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a774b1-cpg-mssr.c
@@ -233,6 +233,7 @@ static const struct mssr_mod_clk r8a774b1_mod_clks[] __initconst = {
};
static const unsigned int r8a774b1_crit_mod_clks[] __initconst = {
+ MOD_CLK_ID(402), /* RWDT */
MOD_CLK_ID(408), /* INTC-AP (GIC) */
};
diff --git a/drivers/clk/renesas/r8a774c0-cpg-mssr.c b/drivers/clk/renesas/r8a774c0-cpg-mssr.c
index f91e7a484753..9fc9fa9e531a 100644
--- a/drivers/clk/renesas/r8a774c0-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a774c0-cpg-mssr.c
@@ -238,6 +238,7 @@ static const struct mssr_mod_clk r8a774c0_mod_clks[] __initconst = {
};
static const unsigned int r8a774c0_crit_mod_clks[] __initconst = {
+ MOD_CLK_ID(402), /* RWDT */
MOD_CLK_ID(408), /* INTC-AP (GIC) */
};
diff --git a/drivers/clk/renesas/r8a774e1-cpg-mssr.c b/drivers/clk/renesas/r8a774e1-cpg-mssr.c
new file mode 100644
index 000000000000..b96c486abb44
--- /dev/null
+++ b/drivers/clk/renesas/r8a774e1-cpg-mssr.c
@@ -0,0 +1,349 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * r8a774e1 Clock Pulse Generator / Module Standby and Software Reset
+ *
+ * Copyright (C) 2020 Renesas Electronics Corp.
+ *
+ * Based on r8a7795-cpg-mssr.c
+ *
+ * Copyright (C) 2015 Glider bvba
+ */
+
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/soc/renesas/rcar-rst.h>
+
+#include <dt-bindings/clock/r8a774e1-cpg-mssr.h>
+
+#include "renesas-cpg-mssr.h"
+#include "rcar-gen3-cpg.h"
+
+enum clk_ids {
+ /* Core Clock Outputs exported to DT */
+ LAST_DT_CORE_CLK = R8A774E1_CLK_CANFD,
+
+ /* External Input Clocks */
+ CLK_EXTAL,
+ CLK_EXTALR,
+
+ /* Internal Core Clocks */
+ CLK_MAIN,
+ CLK_PLL0,
+ CLK_PLL1,
+ CLK_PLL2,
+ CLK_PLL3,
+ CLK_PLL4,
+ CLK_PLL1_DIV2,
+ CLK_PLL1_DIV4,
+ CLK_S0,
+ CLK_S1,
+ CLK_S2,
+ CLK_S3,
+ CLK_SDSRC,
+ CLK_RPCSRC,
+ CLK_RINT,
+
+ /* Module Clocks */
+ MOD_CLK_BASE
+};
+
+static const struct cpg_core_clk r8a774e1_core_clks[] __initconst = {
+ /* External Clock Inputs */
+ DEF_INPUT("extal", CLK_EXTAL),
+ DEF_INPUT("extalr", CLK_EXTALR),
+
+ /* Internal Core Clocks */
+ DEF_BASE(".main", CLK_MAIN, CLK_TYPE_GEN3_MAIN, CLK_EXTAL),
+ DEF_BASE(".pll0", CLK_PLL0, CLK_TYPE_GEN3_PLL0, CLK_MAIN),
+ DEF_BASE(".pll1", CLK_PLL1, CLK_TYPE_GEN3_PLL1, CLK_MAIN),
+ DEF_BASE(".pll2", CLK_PLL2, CLK_TYPE_GEN3_PLL2, CLK_MAIN),
+ DEF_BASE(".pll3", CLK_PLL3, CLK_TYPE_GEN3_PLL3, CLK_MAIN),
+ DEF_BASE(".pll4", CLK_PLL4, CLK_TYPE_GEN3_PLL4, CLK_MAIN),
+
+ DEF_FIXED(".pll1_div2", CLK_PLL1_DIV2, CLK_PLL1, 2, 1),
+ DEF_FIXED(".pll1_div4", CLK_PLL1_DIV4, CLK_PLL1_DIV2, 2, 1),
+ DEF_FIXED(".s0", CLK_S0, CLK_PLL1_DIV2, 2, 1),
+ DEF_FIXED(".s1", CLK_S1, CLK_PLL1_DIV2, 3, 1),
+ DEF_FIXED(".s2", CLK_S2, CLK_PLL1_DIV2, 4, 1),
+ DEF_FIXED(".s3", CLK_S3, CLK_PLL1_DIV2, 6, 1),
+ DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1_DIV2, 2, 1),
+ DEF_BASE(".rpcsrc", CLK_RPCSRC, CLK_TYPE_GEN3_RPCSRC, CLK_PLL1),
+
+ DEF_BASE("rpc", R8A774E1_CLK_RPC, CLK_TYPE_GEN3_RPC,
+ CLK_RPCSRC),
+ DEF_BASE("rpcd2", R8A774E1_CLK_RPCD2, CLK_TYPE_GEN3_RPCD2,
+ R8A774E1_CLK_RPC),
+
+ DEF_GEN3_OSC(".r", CLK_RINT, CLK_EXTAL, 32),
+
+ /* Core Clock Outputs */
+ DEF_GEN3_Z("z", R8A774E1_CLK_Z, CLK_TYPE_GEN3_Z, CLK_PLL0, 2, 8),
+ DEF_GEN3_Z("z2", R8A774E1_CLK_Z2, CLK_TYPE_GEN3_Z, CLK_PLL2, 2, 0),
+ DEF_FIXED("ztr", R8A774E1_CLK_ZTR, CLK_PLL1_DIV2, 6, 1),
+ DEF_FIXED("ztrd2", R8A774E1_CLK_ZTRD2, CLK_PLL1_DIV2, 12, 1),
+ DEF_FIXED("zt", R8A774E1_CLK_ZT, CLK_PLL1_DIV2, 4, 1),
+ DEF_FIXED("zx", R8A774E1_CLK_ZX, CLK_PLL1_DIV2, 2, 1),
+ DEF_FIXED("s0d1", R8A774E1_CLK_S0D1, CLK_S0, 1, 1),
+ DEF_FIXED("s0d2", R8A774E1_CLK_S0D2, CLK_S0, 2, 1),
+ DEF_FIXED("s0d3", R8A774E1_CLK_S0D3, CLK_S0, 3, 1),
+ DEF_FIXED("s0d4", R8A774E1_CLK_S0D4, CLK_S0, 4, 1),
+ DEF_FIXED("s0d6", R8A774E1_CLK_S0D6, CLK_S0, 6, 1),
+ DEF_FIXED("s0d8", R8A774E1_CLK_S0D8, CLK_S0, 8, 1),
+ DEF_FIXED("s0d12", R8A774E1_CLK_S0D12, CLK_S0, 12, 1),
+ DEF_FIXED("s1d2", R8A774E1_CLK_S1D2, CLK_S1, 2, 1),
+ DEF_FIXED("s1d4", R8A774E1_CLK_S1D4, CLK_S1, 4, 1),
+ DEF_FIXED("s2d1", R8A774E1_CLK_S2D1, CLK_S2, 1, 1),
+ DEF_FIXED("s2d2", R8A774E1_CLK_S2D2, CLK_S2, 2, 1),
+ DEF_FIXED("s2d4", R8A774E1_CLK_S2D4, CLK_S2, 4, 1),
+ DEF_FIXED("s3d1", R8A774E1_CLK_S3D1, CLK_S3, 1, 1),
+ DEF_FIXED("s3d2", R8A774E1_CLK_S3D2, CLK_S3, 2, 1),
+ DEF_FIXED("s3d4", R8A774E1_CLK_S3D4, CLK_S3, 4, 1),
+
+ DEF_GEN3_SD("sd0", R8A774E1_CLK_SD0, CLK_SDSRC, 0x074),
+ DEF_GEN3_SD("sd1", R8A774E1_CLK_SD1, CLK_SDSRC, 0x078),
+ DEF_GEN3_SD("sd2", R8A774E1_CLK_SD2, CLK_SDSRC, 0x268),
+ DEF_GEN3_SD("sd3", R8A774E1_CLK_SD3, CLK_SDSRC, 0x26c),
+
+ DEF_FIXED("cl", R8A774E1_CLK_CL, CLK_PLL1_DIV2, 48, 1),
+ DEF_FIXED("cr", R8A774E1_CLK_CR, CLK_PLL1_DIV4, 2, 1),
+ DEF_FIXED("cp", R8A774E1_CLK_CP, CLK_EXTAL, 2, 1),
+ DEF_FIXED("cpex", R8A774E1_CLK_CPEX, CLK_EXTAL, 2, 1),
+
+ DEF_DIV6P1("canfd", R8A774E1_CLK_CANFD, CLK_PLL1_DIV4, 0x244),
+ DEF_DIV6P1("csi0", R8A774E1_CLK_CSI0, CLK_PLL1_DIV4, 0x00c),
+ DEF_DIV6P1("mso", R8A774E1_CLK_MSO, CLK_PLL1_DIV4, 0x014),
+ DEF_DIV6P1("hdmi", R8A774E1_CLK_HDMI, CLK_PLL1_DIV4, 0x250),
+
+ DEF_GEN3_OSC("osc", R8A774E1_CLK_OSC, CLK_EXTAL, 8),
+
+ DEF_BASE("r", R8A774E1_CLK_R, CLK_TYPE_GEN3_R, CLK_RINT),
+};
+
+static const struct mssr_mod_clk r8a774e1_mod_clks[] __initconst = {
+ DEF_MOD("fdp1-1", 118, R8A774E1_CLK_S0D1),
+ DEF_MOD("fdp1-0", 119, R8A774E1_CLK_S0D1),
+ DEF_MOD("tmu4", 121, R8A774E1_CLK_S0D6),
+ DEF_MOD("tmu3", 122, R8A774E1_CLK_S3D2),
+ DEF_MOD("tmu2", 123, R8A774E1_CLK_S3D2),
+ DEF_MOD("tmu1", 124, R8A774E1_CLK_S3D2),
+ DEF_MOD("tmu0", 125, R8A774E1_CLK_CP),
+ DEF_MOD("vcplf", 130, R8A774E1_CLK_S2D1),
+ DEF_MOD("vdpb", 131, R8A774E1_CLK_S2D1),
+ DEF_MOD("scif5", 202, R8A774E1_CLK_S3D4),
+ DEF_MOD("scif4", 203, R8A774E1_CLK_S3D4),
+ DEF_MOD("scif3", 204, R8A774E1_CLK_S3D4),
+ DEF_MOD("scif1", 206, R8A774E1_CLK_S3D4),
+ DEF_MOD("scif0", 207, R8A774E1_CLK_S3D4),
+ DEF_MOD("msiof3", 208, R8A774E1_CLK_MSO),
+ DEF_MOD("msiof2", 209, R8A774E1_CLK_MSO),
+ DEF_MOD("msiof1", 210, R8A774E1_CLK_MSO),
+ DEF_MOD("msiof0", 211, R8A774E1_CLK_MSO),
+ DEF_MOD("sys-dmac2", 217, R8A774E1_CLK_S3D1),
+ DEF_MOD("sys-dmac1", 218, R8A774E1_CLK_S3D1),
+ DEF_MOD("sys-dmac0", 219, R8A774E1_CLK_S0D3),
+ DEF_MOD("cmt3", 300, R8A774E1_CLK_R),
+ DEF_MOD("cmt2", 301, R8A774E1_CLK_R),
+ DEF_MOD("cmt1", 302, R8A774E1_CLK_R),
+ DEF_MOD("cmt0", 303, R8A774E1_CLK_R),
+ DEF_MOD("tpu0", 304, R8A774E1_CLK_S3D4),
+ DEF_MOD("scif2", 310, R8A774E1_CLK_S3D4),
+ DEF_MOD("sdif3", 311, R8A774E1_CLK_SD3),
+ DEF_MOD("sdif2", 312, R8A774E1_CLK_SD2),
+ DEF_MOD("sdif1", 313, R8A774E1_CLK_SD1),
+ DEF_MOD("sdif0", 314, R8A774E1_CLK_SD0),
+ DEF_MOD("pcie1", 318, R8A774E1_CLK_S3D1),
+ DEF_MOD("pcie0", 319, R8A774E1_CLK_S3D1),
+ DEF_MOD("usb3-if0", 328, R8A774E1_CLK_S3D1),
+ DEF_MOD("usb-dmac0", 330, R8A774E1_CLK_S3D1),
+ DEF_MOD("usb-dmac1", 331, R8A774E1_CLK_S3D1),
+ DEF_MOD("rwdt", 402, R8A774E1_CLK_R),
+ DEF_MOD("intc-ex", 407, R8A774E1_CLK_CP),
+ DEF_MOD("intc-ap", 408, R8A774E1_CLK_S0D3),
+ DEF_MOD("audmac1", 501, R8A774E1_CLK_S1D2),
+ DEF_MOD("audmac0", 502, R8A774E1_CLK_S1D2),
+ DEF_MOD("hscif4", 516, R8A774E1_CLK_S3D1),
+ DEF_MOD("hscif3", 517, R8A774E1_CLK_S3D1),
+ DEF_MOD("hscif2", 518, R8A774E1_CLK_S3D1),
+ DEF_MOD("hscif1", 519, R8A774E1_CLK_S3D1),
+ DEF_MOD("hscif0", 520, R8A774E1_CLK_S3D1),
+ DEF_MOD("thermal", 522, R8A774E1_CLK_CP),
+ DEF_MOD("pwm", 523, R8A774E1_CLK_S0D12),
+ DEF_MOD("fcpvd1", 602, R8A774E1_CLK_S0D2),
+ DEF_MOD("fcpvd0", 603, R8A774E1_CLK_S0D2),
+ DEF_MOD("fcpvb1", 606, R8A774E1_CLK_S0D1),
+ DEF_MOD("fcpvb0", 607, R8A774E1_CLK_S0D1),
+ DEF_MOD("fcpvi1", 610, R8A774E1_CLK_S0D1),
+ DEF_MOD("fcpvi0", 611, R8A774E1_CLK_S0D1),
+ DEF_MOD("fcpf1", 614, R8A774E1_CLK_S0D1),
+ DEF_MOD("fcpf0", 615, R8A774E1_CLK_S0D1),
+ DEF_MOD("fcpcs", 619, R8A774E1_CLK_S0D1),
+ DEF_MOD("vspd1", 622, R8A774E1_CLK_S0D2),
+ DEF_MOD("vspd0", 623, R8A774E1_CLK_S0D2),
+ DEF_MOD("vspbc", 624, R8A774E1_CLK_S0D1),
+ DEF_MOD("vspbd", 626, R8A774E1_CLK_S0D1),
+ DEF_MOD("vspi1", 630, R8A774E1_CLK_S0D1),
+ DEF_MOD("vspi0", 631, R8A774E1_CLK_S0D1),
+ DEF_MOD("ehci1", 702, R8A774E1_CLK_S3D2),
+ DEF_MOD("ehci0", 703, R8A774E1_CLK_S3D2),
+ DEF_MOD("hsusb", 704, R8A774E1_CLK_S3D2),
+ DEF_MOD("csi20", 714, R8A774E1_CLK_CSI0),
+ DEF_MOD("csi40", 716, R8A774E1_CLK_CSI0),
+ DEF_MOD("du3", 721, R8A774E1_CLK_S2D1),
+ DEF_MOD("du1", 723, R8A774E1_CLK_S2D1),
+ DEF_MOD("du0", 724, R8A774E1_CLK_S2D1),
+ DEF_MOD("lvds", 727, R8A774E1_CLK_S0D4),
+ DEF_MOD("hdmi0", 729, R8A774E1_CLK_HDMI),
+ DEF_MOD("vin7", 804, R8A774E1_CLK_S0D2),
+ DEF_MOD("vin6", 805, R8A774E1_CLK_S0D2),
+ DEF_MOD("vin5", 806, R8A774E1_CLK_S0D2),
+ DEF_MOD("vin4", 807, R8A774E1_CLK_S0D2),
+ DEF_MOD("vin3", 808, R8A774E1_CLK_S0D2),
+ DEF_MOD("vin2", 809, R8A774E1_CLK_S0D2),
+ DEF_MOD("vin1", 810, R8A774E1_CLK_S0D2),
+ DEF_MOD("vin0", 811, R8A774E1_CLK_S0D2),
+ DEF_MOD("etheravb", 812, R8A774E1_CLK_S0D6),
+ DEF_MOD("sata0", 815, R8A774E1_CLK_S3D2),
+ DEF_MOD("gpio7", 905, R8A774E1_CLK_S3D4),
+ DEF_MOD("gpio6", 906, R8A774E1_CLK_S3D4),
+ DEF_MOD("gpio5", 907, R8A774E1_CLK_S3D4),
+ DEF_MOD("gpio4", 908, R8A774E1_CLK_S3D4),
+ DEF_MOD("gpio3", 909, R8A774E1_CLK_S3D4),
+ DEF_MOD("gpio2", 910, R8A774E1_CLK_S3D4),
+ DEF_MOD("gpio1", 911, R8A774E1_CLK_S3D4),
+ DEF_MOD("gpio0", 912, R8A774E1_CLK_S3D4),
+ DEF_MOD("can-fd", 914, R8A774E1_CLK_S3D2),
+ DEF_MOD("can-if1", 915, R8A774E1_CLK_S3D4),
+ DEF_MOD("can-if0", 916, R8A774E1_CLK_S3D4),
+ DEF_MOD("rpc-if", 917, R8A774E1_CLK_RPCD2),
+ DEF_MOD("i2c6", 918, R8A774E1_CLK_S0D6),
+ DEF_MOD("i2c5", 919, R8A774E1_CLK_S0D6),
+ DEF_MOD("adg", 922, R8A774E1_CLK_S0D1),
+ DEF_MOD("i2c-dvfs", 926, R8A774E1_CLK_CP),
+ DEF_MOD("i2c4", 927, R8A774E1_CLK_S0D6),
+ DEF_MOD("i2c3", 928, R8A774E1_CLK_S0D6),
+ DEF_MOD("i2c2", 929, R8A774E1_CLK_S3D2),
+ DEF_MOD("i2c1", 930, R8A774E1_CLK_S3D2),
+ DEF_MOD("i2c0", 931, R8A774E1_CLK_S3D2),
+ DEF_MOD("ssi-all", 1005, R8A774E1_CLK_S3D4),
+ DEF_MOD("ssi9", 1006, MOD_CLK_ID(1005)),
+ DEF_MOD("ssi8", 1007, MOD_CLK_ID(1005)),
+ DEF_MOD("ssi7", 1008, MOD_CLK_ID(1005)),
+ DEF_MOD("ssi6", 1009, MOD_CLK_ID(1005)),
+ DEF_MOD("ssi5", 1010, MOD_CLK_ID(1005)),
+ DEF_MOD("ssi4", 1011, MOD_CLK_ID(1005)),
+ DEF_MOD("ssi3", 1012, MOD_CLK_ID(1005)),
+ DEF_MOD("ssi2", 1013, MOD_CLK_ID(1005)),
+ DEF_MOD("ssi1", 1014, MOD_CLK_ID(1005)),
+ DEF_MOD("ssi0", 1015, MOD_CLK_ID(1005)),
+ DEF_MOD("scu-all", 1017, R8A774E1_CLK_S3D4),
+ DEF_MOD("scu-dvc1", 1018, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-dvc0", 1019, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-ctu1-mix1", 1020, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-ctu0-mix0", 1021, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-src9", 1022, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-src8", 1023, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-src7", 1024, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-src6", 1025, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-src5", 1026, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-src4", 1027, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-src3", 1028, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-src2", 1029, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-src1", 1030, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-src0", 1031, MOD_CLK_ID(1017)),
+};
+
+static const unsigned int r8a774e1_crit_mod_clks[] __initconst = {
+ MOD_CLK_ID(402), /* RWDT */
+ MOD_CLK_ID(408), /* INTC-AP (GIC) */
+};
+
+/*
+ * CPG Clock Data
+ */
+
+/*
+ * MD EXTAL PLL0 PLL1 PLL2 PLL3 PLL4 OSC
+ * 14 13 19 17 (MHz)
+ *-------------------------------------------------------------------------
+ * 0 0 0 0 16.66 x 1 x180 x192 x144 x192 x144 /16
+ * 0 0 0 1 16.66 x 1 x180 x192 x144 x128 x144 /16
+ * 0 0 1 0 Prohibited setting
+ * 0 0 1 1 16.66 x 1 x180 x192 x144 x192 x144 /16
+ * 0 1 0 0 20 x 1 x150 x160 x120 x160 x120 /19
+ * 0 1 0 1 20 x 1 x150 x160 x120 x106 x120 /19
+ * 0 1 1 0 Prohibited setting
+ * 0 1 1 1 20 x 1 x150 x160 x120 x160 x120 /19
+ * 1 0 0 0 25 x 1 x120 x128 x96 x128 x96 /24
+ * 1 0 0 1 25 x 1 x120 x128 x96 x84 x96 /24
+ * 1 0 1 0 Prohibited setting
+ * 1 0 1 1 25 x 1 x120 x128 x96 x128 x96 /24
+ * 1 1 0 0 33.33 / 2 x180 x192 x144 x192 x144 /32
+ * 1 1 0 1 33.33 / 2 x180 x192 x144 x128 x144 /32
+ * 1 1 1 0 Prohibited setting
+ * 1 1 1 1 33.33 / 2 x180 x192 x144 x192 x144 /32
+ */
+#define CPG_PLL_CONFIG_INDEX(md) ((((md) & BIT(14)) >> 11) | \
+ (((md) & BIT(13)) >> 11) | \
+ (((md) & BIT(19)) >> 18) | \
+ (((md) & BIT(17)) >> 17))
+
+static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[16] __initconst = {
+ /* EXTAL div PLL1 mult/div PLL3 mult/div OSC prediv */
+ { 1, 192, 1, 192, 1, 16, },
+ { 1, 192, 1, 128, 1, 16, },
+ { 0, /* Prohibited setting */ },
+ { 1, 192, 1, 192, 1, 16, },
+ { 1, 160, 1, 160, 1, 19, },
+ { 1, 160, 1, 106, 1, 19, },
+ { 0, /* Prohibited setting */ },
+ { 1, 160, 1, 160, 1, 19, },
+ { 1, 128, 1, 128, 1, 24, },
+ { 1, 128, 1, 84, 1, 24, },
+ { 0, /* Prohibited setting */ },
+ { 1, 128, 1, 128, 1, 24, },
+ { 2, 192, 1, 192, 1, 32, },
+ { 2, 192, 1, 128, 1, 32, },
+ { 0, /* Prohibited setting */ },
+ { 2, 192, 1, 192, 1, 32, },
+};
+
+static int __init r8a774e1_cpg_mssr_init(struct device *dev)
+{
+ const struct rcar_gen3_cpg_pll_config *cpg_pll_config;
+ u32 cpg_mode;
+ int error;
+
+ error = rcar_rst_read_mode_pins(&cpg_mode);
+ if (error)
+ return error;
+
+ cpg_pll_config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)];
+ if (!cpg_pll_config->extal_div) {
+ dev_err(dev, "Prohibited setting (cpg_mode=0x%x)\n", cpg_mode);
+ return -EINVAL;
+ }
+
+ return rcar_gen3_cpg_init(cpg_pll_config, CLK_EXTALR, cpg_mode);
+}
+
+const struct cpg_mssr_info r8a774e1_cpg_mssr_info __initconst = {
+ /* Core Clocks */
+ .core_clks = r8a774e1_core_clks,
+ .num_core_clks = ARRAY_SIZE(r8a774e1_core_clks),
+ .last_dt_core_clk = LAST_DT_CORE_CLK,
+ .num_total_core_clks = MOD_CLK_BASE,
+
+ /* Module Clocks */
+ .mod_clks = r8a774e1_mod_clks,
+ .num_mod_clks = ARRAY_SIZE(r8a774e1_mod_clks),
+ .num_hw_mod_clks = 12 * 32,
+
+ /* Critical Module Clocks */
+ .crit_mod_clks = r8a774e1_crit_mod_clks,
+ .num_crit_mod_clks = ARRAY_SIZE(r8a774e1_crit_mod_clks),
+
+ /* Callbacks */
+ .init = r8a774e1_cpg_mssr_init,
+ .cpg_clk_register = rcar_gen3_cpg_clk_register,
+};
diff --git a/drivers/clk/renesas/r8a7795-cpg-mssr.c b/drivers/clk/renesas/r8a7795-cpg-mssr.c
index ff5b3020cb03..068018ae3c6e 100644
--- a/drivers/clk/renesas/r8a7795-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a7795-cpg-mssr.c
@@ -287,10 +287,10 @@ static struct mssr_mod_clk r8a7795_mod_clks[] __initdata = {
};
static const unsigned int r8a7795_crit_mod_clks[] __initconst = {
+ MOD_CLK_ID(402), /* RWDT */
MOD_CLK_ID(408), /* INTC-AP (GIC) */
};
-
/*
* CPG Clock Data
*/
diff --git a/drivers/clk/renesas/r8a7796-cpg-mssr.c b/drivers/clk/renesas/r8a7796-cpg-mssr.c
index e8d466dbc7f9..2cd6e3876fbd 100644
--- a/drivers/clk/renesas/r8a7796-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a7796-cpg-mssr.c
@@ -262,10 +262,10 @@ static struct mssr_mod_clk r8a7796_mod_clks[] __initdata = {
};
static const unsigned int r8a7796_crit_mod_clks[] __initconst = {
+ MOD_CLK_ID(402), /* RWDT */
MOD_CLK_ID(408), /* INTC-AP (GIC) */
};
-
/*
* CPG Clock Data
*/
diff --git a/drivers/clk/renesas/r8a77965-cpg-mssr.c b/drivers/clk/renesas/r8a77965-cpg-mssr.c
index 7a05a2fc1cc6..2b55a06ac5cf 100644
--- a/drivers/clk/renesas/r8a77965-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a77965-cpg-mssr.c
@@ -263,6 +263,7 @@ static const struct mssr_mod_clk r8a77965_mod_clks[] __initconst = {
};
static const unsigned int r8a77965_crit_mod_clks[] __initconst = {
+ MOD_CLK_ID(402), /* RWDT */
MOD_CLK_ID(408), /* INTC-AP (GIC) */
};
diff --git a/drivers/clk/renesas/r8a77970-cpg-mssr.c b/drivers/clk/renesas/r8a77970-cpg-mssr.c
index cbed3769a100..0f59c84229a8 100644
--- a/drivers/clk/renesas/r8a77970-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a77970-cpg-mssr.c
@@ -165,10 +165,10 @@ static const struct mssr_mod_clk r8a77970_mod_clks[] __initconst = {
};
static const unsigned int r8a77970_crit_mod_clks[] __initconst = {
+ MOD_CLK_ID(402), /* RWDT */
MOD_CLK_ID(408), /* INTC-AP (GIC) */
};
-
/*
* CPG Clock Data
*/
diff --git a/drivers/clk/renesas/r8a77980-cpg-mssr.c b/drivers/clk/renesas/r8a77980-cpg-mssr.c
index 7227f675e61f..9fe372286c1e 100644
--- a/drivers/clk/renesas/r8a77980-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a77980-cpg-mssr.c
@@ -180,10 +180,10 @@ static const struct mssr_mod_clk r8a77980_mod_clks[] __initconst = {
};
static const unsigned int r8a77980_crit_mod_clks[] __initconst = {
+ MOD_CLK_ID(402), /* RWDT */
MOD_CLK_ID(408), /* INTC-AP (GIC) */
};
-
/*
* CPG Clock Data
*/
diff --git a/drivers/clk/renesas/r8a77990-cpg-mssr.c b/drivers/clk/renesas/r8a77990-cpg-mssr.c
index 8eda2e3e2480..2b97ab61d044 100644
--- a/drivers/clk/renesas/r8a77990-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a77990-cpg-mssr.c
@@ -245,6 +245,7 @@ static const struct mssr_mod_clk r8a77990_mod_clks[] __initconst = {
};
static const unsigned int r8a77990_crit_mod_clks[] __initconst = {
+ MOD_CLK_ID(402), /* RWDT */
MOD_CLK_ID(408), /* INTC-AP (GIC) */
};
diff --git a/drivers/clk/renesas/r8a77995-cpg-mssr.c b/drivers/clk/renesas/r8a77995-cpg-mssr.c
index 056ebf3e70e2..5b4691117b47 100644
--- a/drivers/clk/renesas/r8a77995-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a77995-cpg-mssr.c
@@ -183,10 +183,10 @@ static const struct mssr_mod_clk r8a77995_mod_clks[] __initconst = {
};
static const unsigned int r8a77995_crit_mod_clks[] __initconst = {
+ MOD_CLK_ID(402), /* RWDT */
MOD_CLK_ID(408), /* INTC-AP (GIC) */
};
-
/*
* CPG Clock Data
*/
diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c
index dcb6e2706d37..5a306d28738c 100644
--- a/drivers/clk/renesas/renesas-cpg-mssr.c
+++ b/drivers/clk/renesas/renesas-cpg-mssr.c
@@ -416,14 +416,6 @@ static void __init cpg_mssr_register_mod_clk(const struct mssr_mod_clk *mod,
init.name = mod->name;
init.ops = &cpg_mstp_clock_ops;
init.flags = CLK_SET_RATE_PARENT;
- for (i = 0; i < info->num_crit_mod_clks; i++)
- if (id == info->crit_mod_clks[i]) {
- dev_dbg(dev, "MSTP %s setting CLK_IS_CRITICAL\n",
- mod->name);
- init.flags |= CLK_IS_CRITICAL;
- break;
- }
-
parent_name = __clk_get_name(parent);
init.parent_names = &parent_name;
init.num_parents = 1;
@@ -432,6 +424,15 @@ static void __init cpg_mssr_register_mod_clk(const struct mssr_mod_clk *mod,
clock->priv = priv;
clock->hw.init = &init;
+ for (i = 0; i < info->num_crit_mod_clks; i++)
+ if (id == info->crit_mod_clks[i] &&
+ cpg_mstp_clock_is_enabled(&clock->hw)) {
+ dev_dbg(dev, "MSTP %s setting CLK_IS_CRITICAL\n",
+ mod->name);
+ init.flags |= CLK_IS_CRITICAL;
+ break;
+ }
+
clk = clk_register(NULL, &clock->hw);
if (IS_ERR(clk))
goto fail;
@@ -720,6 +721,12 @@ static const struct of_device_id cpg_mssr_match[] = {
.data = &r8a774c0_cpg_mssr_info,
},
#endif
+#ifdef CONFIG_CLK_R8A774E1
+ {
+ .compatible = "renesas,r8a774e1-cpg-mssr",
+ .data = &r8a774e1_cpg_mssr_info,
+ },
+#endif
#ifdef CONFIG_CLK_R8A7790
{
.compatible = "renesas,r8a7790-cpg-mssr",
diff --git a/drivers/clk/renesas/renesas-cpg-mssr.h b/drivers/clk/renesas/renesas-cpg-mssr.h
index 55a18ef0efaf..1cc569484250 100644
--- a/drivers/clk/renesas/renesas-cpg-mssr.h
+++ b/drivers/clk/renesas/renesas-cpg-mssr.h
@@ -162,6 +162,7 @@ extern const struct cpg_mssr_info r8a77470_cpg_mssr_info;
extern const struct cpg_mssr_info r8a774a1_cpg_mssr_info;
extern const struct cpg_mssr_info r8a774b1_cpg_mssr_info;
extern const struct cpg_mssr_info r8a774c0_cpg_mssr_info;
+extern const struct cpg_mssr_info r8a774e1_cpg_mssr_info;
extern const struct cpg_mssr_info r8a7790_cpg_mssr_info;
extern const struct cpg_mssr_info r8a7791_cpg_mssr_info;
extern const struct cpg_mssr_info r8a7792_cpg_mssr_info;
diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c
index 10560d963baf..4c6c9167ef50 100644
--- a/drivers/clk/rockchip/clk-pll.c
+++ b/drivers/clk/rockchip/clk-pll.c
@@ -12,6 +12,7 @@
#include <linux/io.h>
#include <linux/delay.h>
#include <linux/clk-provider.h>
+#include <linux/iopoll.h>
#include <linux/regmap.h>
#include <linux/clk.h>
#include "clk.h"
@@ -86,23 +87,14 @@ static int rockchip_pll_wait_lock(struct rockchip_clk_pll *pll)
{
struct regmap *grf = pll->ctx->grf;
unsigned int val;
- int delay = 24000000, ret;
-
- while (delay > 0) {
- ret = regmap_read(grf, pll->lock_offset, &val);
- if (ret) {
- pr_err("%s: failed to read pll lock status: %d\n",
- __func__, ret);
- return ret;
- }
+ int ret;
- if (val & BIT(pll->lock_shift))
- return 0;
- delay--;
- }
+ ret = regmap_read_poll_timeout(grf, pll->lock_offset, val,
+ val & BIT(pll->lock_shift), 0, 1000);
+ if (ret)
+ pr_err("%s: timeout waiting for pll to lock\n", __func__);
- pr_err("%s: timeout waiting for pll to lock\n", __func__);
- return -ETIMEDOUT;
+ return ret;
}
/**
@@ -118,12 +110,31 @@ static int rockchip_pll_wait_lock(struct rockchip_clk_pll *pll)
#define RK3036_PLLCON1_REFDIV_SHIFT 0
#define RK3036_PLLCON1_POSTDIV2_MASK 0x7
#define RK3036_PLLCON1_POSTDIV2_SHIFT 6
+#define RK3036_PLLCON1_LOCK_STATUS BIT(10)
#define RK3036_PLLCON1_DSMPD_MASK 0x1
#define RK3036_PLLCON1_DSMPD_SHIFT 12
+#define RK3036_PLLCON1_PWRDOWN BIT(13)
#define RK3036_PLLCON2_FRAC_MASK 0xffffff
#define RK3036_PLLCON2_FRAC_SHIFT 0
-#define RK3036_PLLCON1_PWRDOWN (1 << 13)
+static int rockchip_rk3036_pll_wait_lock(struct rockchip_clk_pll *pll)
+{
+ u32 pllcon;
+ int ret;
+
+ /*
+ * Lock time typical 250, max 500 input clock cycles @24MHz
+ * So define a very safe maximum of 1000us, meaning 24000 cycles.
+ */
+ ret = readl_relaxed_poll_timeout(pll->reg_base + RK3036_PLLCON(1),
+ pllcon,
+ pllcon & RK3036_PLLCON1_LOCK_STATUS,
+ 0, 1000);
+ if (ret)
+ pr_err("%s: timeout waiting for pll to lock\n", __func__);
+
+ return ret;
+}
static void rockchip_rk3036_pll_get_params(struct rockchip_clk_pll *pll,
struct rockchip_pll_rate_table *rate)
@@ -221,7 +232,7 @@ static int rockchip_rk3036_pll_set_params(struct rockchip_clk_pll *pll,
writel_relaxed(pllcon, pll->reg_base + RK3036_PLLCON(2));
/* wait for the pll to lock */
- ret = rockchip_pll_wait_lock(pll);
+ ret = rockchip_rk3036_pll_wait_lock(pll);
if (ret) {
pr_warn("%s: pll update unsuccessful, trying to restore old params\n",
__func__);
@@ -260,7 +271,7 @@ static int rockchip_rk3036_pll_enable(struct clk_hw *hw)
writel(HIWORD_UPDATE(0, RK3036_PLLCON1_PWRDOWN, 0),
pll->reg_base + RK3036_PLLCON(1));
- rockchip_pll_wait_lock(pll);
+ rockchip_rk3036_pll_wait_lock(pll);
return 0;
}
@@ -589,19 +600,20 @@ static const struct clk_ops rockchip_rk3066_pll_clk_ops = {
static int rockchip_rk3399_pll_wait_lock(struct rockchip_clk_pll *pll)
{
u32 pllcon;
- int delay = 24000000;
-
- /* poll check the lock status in rk3399 xPLLCON2 */
- while (delay > 0) {
- pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(2));
- if (pllcon & RK3399_PLLCON2_LOCK_STATUS)
- return 0;
+ int ret;
- delay--;
- }
+ /*
+ * Lock time typical 250, max 500 input clock cycles @24MHz
+ * So define a very safe maximum of 1000us, meaning 24000 cycles.
+ */
+ ret = readl_relaxed_poll_timeout(pll->reg_base + RK3399_PLLCON(2),
+ pllcon,
+ pllcon & RK3399_PLLCON2_LOCK_STATUS,
+ 0, 1000);
+ if (ret)
+ pr_err("%s: timeout waiting for pll to lock\n", __func__);
- pr_err("%s: timeout waiting for pll to lock\n", __func__);
- return -ETIMEDOUT;
+ return ret;
}
static void rockchip_rk3399_pll_get_params(struct rockchip_clk_pll *pll,
diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c
index 77aebfb1d6d5..730020fcc7fe 100644
--- a/drivers/clk/rockchip/clk-rk3188.c
+++ b/drivers/clk/rockchip/clk-rk3188.c
@@ -751,6 +751,7 @@ static const char *const rk3188_critical_clocks[] __initconst = {
"pclk_peri",
"hclk_cpubus",
"hclk_vio_bus",
+ "sclk_mac_lbtest",
};
static struct rockchip_clk_provider *__init rk3188_common_clk_init(struct device_node *np)
diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c
index cc2a177bbdbf..93c794695c46 100644
--- a/drivers/clk/rockchip/clk-rk3288.c
+++ b/drivers/clk/rockchip/clk-rk3288.c
@@ -15,6 +15,11 @@
#define RK3288_GRF_SOC_CON(x) (0x244 + x * 4)
#define RK3288_GRF_SOC_STATUS1 0x284
+enum rk3288_variant {
+ RK3288_CRU,
+ RK3288W_CRU,
+};
+
enum rk3288_plls {
apll, dpll, cpll, gpll, npll,
};
@@ -425,8 +430,6 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
COMPOSITE(0, "aclk_vio0", mux_pll_src_cpll_gpll_usb480m_p, CLK_IGNORE_UNUSED,
RK3288_CLKSEL_CON(31), 6, 2, MFLAGS, 0, 5, DFLAGS,
RK3288_CLKGATE_CON(3), 0, GFLAGS),
- DIV(0, "hclk_vio", "aclk_vio0", 0,
- RK3288_CLKSEL_CON(28), 8, 5, DFLAGS),
COMPOSITE(0, "aclk_vio1", mux_pll_src_cpll_gpll_usb480m_p, CLK_IGNORE_UNUSED,
RK3288_CLKSEL_CON(31), 14, 2, MFLAGS, 8, 5, DFLAGS,
RK3288_CLKGATE_CON(3), 2, GFLAGS),
@@ -819,6 +822,16 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
INVERTER(0, "pclk_isp", "pclk_isp_in", RK3288_CLKSEL_CON(29), 3, IFLAGS),
};
+static struct rockchip_clk_branch rk3288w_hclkvio_branch[] __initdata = {
+ DIV(0, "hclk_vio", "aclk_vio1", 0,
+ RK3288_CLKSEL_CON(28), 8, 5, DFLAGS),
+};
+
+static struct rockchip_clk_branch rk3288_hclkvio_branch[] __initdata = {
+ DIV(0, "hclk_vio", "aclk_vio0", 0,
+ RK3288_CLKSEL_CON(28), 8, 5, DFLAGS),
+};
+
static const char *const rk3288_critical_clocks[] __initconst = {
"aclk_cpu",
"aclk_peri",
@@ -914,7 +927,8 @@ static struct syscore_ops rk3288_clk_syscore_ops = {
.resume = rk3288_clk_resume,
};
-static void __init rk3288_clk_init(struct device_node *np)
+static void __init rk3288_common_init(struct device_node *np,
+ enum rk3288_variant soc)
{
struct rockchip_clk_provider *ctx;
@@ -936,6 +950,14 @@ static void __init rk3288_clk_init(struct device_node *np)
RK3288_GRF_SOC_STATUS1);
rockchip_clk_register_branches(ctx, rk3288_clk_branches,
ARRAY_SIZE(rk3288_clk_branches));
+
+ if (soc == RK3288W_CRU)
+ rockchip_clk_register_branches(ctx, rk3288w_hclkvio_branch,
+ ARRAY_SIZE(rk3288w_hclkvio_branch));
+ else
+ rockchip_clk_register_branches(ctx, rk3288_hclkvio_branch,
+ ARRAY_SIZE(rk3288_hclkvio_branch));
+
rockchip_clk_protect_critical(rk3288_critical_clocks,
ARRAY_SIZE(rk3288_critical_clocks));
@@ -954,4 +976,15 @@ static void __init rk3288_clk_init(struct device_node *np)
rockchip_clk_of_add_provider(np, ctx);
}
+
+static void __init rk3288_clk_init(struct device_node *np)
+{
+ rk3288_common_init(np, RK3288_CRU);
+}
CLK_OF_DECLARE(rk3288_cru, "rockchip,rk3288-cru", rk3288_clk_init);
+
+static void __init rk3288w_clk_init(struct device_node *np)
+{
+ rk3288_common_init(np, RK3288W_CRU);
+}
+CLK_OF_DECLARE(rk3288w_cru, "rockchip,rk3288w-cru", rk3288w_clk_init);
diff --git a/drivers/clk/rockchip/clk-rk3328.c b/drivers/clk/rockchip/clk-rk3328.c
index c186a1985bf4..2429b7c2a8b3 100644
--- a/drivers/clk/rockchip/clk-rk3328.c
+++ b/drivers/clk/rockchip/clk-rk3328.c
@@ -808,22 +808,22 @@ static struct rockchip_clk_branch rk3328_clk_branches[] __initdata = {
MMC(SCLK_SDMMC_DRV, "sdmmc_drv", "clk_sdmmc",
RK3328_SDMMC_CON0, 1),
MMC(SCLK_SDMMC_SAMPLE, "sdmmc_sample", "clk_sdmmc",
- RK3328_SDMMC_CON1, 0),
+ RK3328_SDMMC_CON1, 1),
MMC(SCLK_SDIO_DRV, "sdio_drv", "clk_sdio",
RK3328_SDIO_CON0, 1),
MMC(SCLK_SDIO_SAMPLE, "sdio_sample", "clk_sdio",
- RK3328_SDIO_CON1, 0),
+ RK3328_SDIO_CON1, 1),
MMC(SCLK_EMMC_DRV, "emmc_drv", "clk_emmc",
RK3328_EMMC_CON0, 1),
MMC(SCLK_EMMC_SAMPLE, "emmc_sample", "clk_emmc",
- RK3328_EMMC_CON1, 0),
+ RK3328_EMMC_CON1, 1),
MMC(SCLK_SDMMC_EXT_DRV, "sdmmc_ext_drv", "clk_sdmmc_ext",
RK3328_SDMMC_EXT_CON0, 1),
MMC(SCLK_SDMMC_EXT_SAMPLE, "sdmmc_ext_sample", "clk_sdmmc_ext",
- RK3328_SDMMC_EXT_CON1, 0),
+ RK3328_SDMMC_EXT_CON1, 1),
};
static const char *const rk3328_critical_clocks[] __initconst = {
diff --git a/drivers/clk/sirf/clk-atlas6.c b/drivers/clk/sirf/clk-atlas6.c
index c84d5bab7ac2..b95483bb6a5e 100644
--- a/drivers/clk/sirf/clk-atlas6.c
+++ b/drivers/clk/sirf/clk-atlas6.c
@@ -135,7 +135,7 @@ static void __init atlas6_clk_init(struct device_node *np)
for (i = pll1; i < maxclk; i++) {
atlas6_clks[i] = clk_register(NULL, atlas6_clk_hw_array[i]);
- BUG_ON(!atlas6_clks[i]);
+ BUG_ON(IS_ERR(atlas6_clks[i]));
}
clk_register_clkdev(atlas6_clks[cpu], NULL, "cpu");
clk_register_clkdev(atlas6_clks[io], NULL, "io");
diff --git a/drivers/clk/socfpga/clk-agilex.c b/drivers/clk/socfpga/clk-agilex.c
index 699527f7e764..8fb12cbe0208 100644
--- a/drivers/clk/socfpga/clk-agilex.c
+++ b/drivers/clk/socfpga/clk-agilex.c
@@ -252,7 +252,7 @@ static const struct stratix10_gate_clock agilex_gate_clks[] = {
0, 0, 0, 0, 0x30, 0, 0},
{ AGILEX_MPU_PERIPH_CLK, "mpu_periph_clk", "mpu_clk", NULL, 1, 0, 0x24,
0, 0, 0, 0, 0, 0, 4},
- { AGILEX_MPU_L2RAM_CLK, "mpu_l2ram_clk", "mpu_clk", NULL, 1, 0, 0x24,
+ { AGILEX_MPU_CCU_CLK, "mpu_ccu_clk", "mpu_clk", NULL, 1, 0, 0x24,
0, 0, 0, 0, 0, 0, 2},
{ AGILEX_L4_MAIN_CLK, "l4_main_clk", "noc_clk", NULL, 1, 0, 0x24,
1, 0x44, 0, 2, 0, 0, 0},
@@ -294,8 +294,12 @@ static const struct stratix10_gate_clock agilex_gate_clks[] = {
8, 0, 0, 0, 0, 0, 0},
{ AGILEX_SPI_M_CLK, "spi_m_clk", "l4_mp_clk", NULL, 1, 0, 0x7C,
9, 0, 0, 0, 0, 0, 0},
- { AGILEX_NAND_CLK, "nand_clk", "l4_main_clk", NULL, 1, 0, 0x7C,
+ { AGILEX_NAND_X_CLK, "nand_x_clk", "l4_mp_clk", NULL, 1, 0, 0x7C,
10, 0, 0, 0, 0, 0, 0},
+ { AGILEX_NAND_CLK, "nand_clk", "nand_x_clk", NULL, 1, 0, 0x7C,
+ 10, 0, 0, 0, 0, 0, 4},
+ { AGILEX_NAND_ECC_CLK, "nand_ecc_clk", "nand_x_clk", NULL, 1, 0, 0x7C,
+ 10, 0, 0, 0, 0, 0, 4},
};
static int agilex_clk_register_c_perip(const struct stratix10_perip_c_clock *clks,
diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c
index 0b212cf2e794..f180c055d33f 100644
--- a/drivers/clk/tegra/clk-pll.c
+++ b/drivers/clk/tegra/clk-pll.c
@@ -327,16 +327,26 @@ int tegra_pll_wait_for_lock(struct tegra_clk_pll *pll)
return clk_pll_wait_for_lock(pll);
}
+static bool pllm_clk_is_gated_by_pmc(struct tegra_clk_pll *pll)
+{
+ u32 val = readl_relaxed(pll->pmc + PMC_PLLP_WB0_OVERRIDE);
+
+ return (val & PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE) &&
+ !(val & PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE);
+}
+
static int clk_pll_is_enabled(struct clk_hw *hw)
{
struct tegra_clk_pll *pll = to_clk_pll(hw);
u32 val;
- if (pll->params->flags & TEGRA_PLLM) {
- val = readl_relaxed(pll->pmc + PMC_PLLP_WB0_OVERRIDE);
- if (val & PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE)
- return val & PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE ? 1 : 0;
- }
+ /*
+ * Power Management Controller (PMC) can override the PLLM clock
+ * settings, including the enable-state. The PLLM is enabled when
+ * PLLM's CaR state is ON and when PLLM isn't gated by PMC.
+ */
+ if ((pll->params->flags & TEGRA_PLLM) && pllm_clk_is_gated_by_pmc(pll))
+ return 0;
val = pll_readl_base(pll);
diff --git a/drivers/clk/versatile/icst.c b/drivers/clk/versatile/icst.c
index ba4b2d22ec97..307cb3774f87 100644
--- a/drivers/clk/versatile/icst.c
+++ b/drivers/clk/versatile/icst.c
@@ -5,7 +5,7 @@
* Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved.
*
* Support functions for calculating clocks/divisors for the ICST307
- * clock generators. See http://www.idt.com/ for more information
+ * clock generators. See https://www.idt.com/ for more information
* on these devices.
*
* This is an almost identical implementation to the ICST525 clock generator.
diff --git a/drivers/clk/versatile/icst.h b/drivers/clk/versatile/icst.h
index 73a3062b4535..29622768b02a 100644
--- a/drivers/clk/versatile/icst.h
+++ b/drivers/clk/versatile/icst.h
@@ -3,7 +3,7 @@
* Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved.
*
* Support functions for calculating clocks/divisors for the ICST
- * clock generators. See http://www.idt.com/ for more information
+ * clock generators. See https://www.idt.com/ for more information
* on these devices.
*/
#ifndef ICST_H
diff --git a/drivers/clk/x86/clk-cgu-pll.c b/drivers/clk/x86/clk-cgu-pll.c
index c03cc6b85b9f..3179557b5f78 100644
--- a/drivers/clk/x86/clk-cgu-pll.c
+++ b/drivers/clk/x86/clk-cgu-pll.c
@@ -128,7 +128,7 @@ lgm_clk_register_pll(struct lgm_clk_provider *ctx,
pll->hw.init = &init;
hw = &pll->hw;
- ret = clk_hw_register(dev, hw);
+ ret = devm_clk_hw_register(dev, hw);
if (ret)
return ERR_PTR(ret);
diff --git a/drivers/clk/x86/clk-cgu.c b/drivers/clk/x86/clk-cgu.c
index 56af0e04ec1e..33de600e0c38 100644
--- a/drivers/clk/x86/clk-cgu.c
+++ b/drivers/clk/x86/clk-cgu.c
@@ -119,7 +119,7 @@ lgm_clk_register_mux(struct lgm_clk_provider *ctx,
mux->hw.init = &init;
hw = &mux->hw;
- ret = clk_hw_register(dev, hw);
+ ret = devm_clk_hw_register(dev, hw);
if (ret)
return ERR_PTR(ret);
@@ -247,7 +247,7 @@ lgm_clk_register_divider(struct lgm_clk_provider *ctx,
div->hw.init = &init;
hw = &div->hw;
- ret = clk_hw_register(dev, hw);
+ ret = devm_clk_hw_register(dev, hw);
if (ret)
return ERR_PTR(ret);
@@ -361,7 +361,7 @@ lgm_clk_register_gate(struct lgm_clk_provider *ctx,
gate->hw.init = &init;
hw = &gate->hw;
- ret = clk_hw_register(dev, hw);
+ ret = devm_clk_hw_register(dev, hw);
if (ret)
return ERR_PTR(ret);
@@ -420,18 +420,14 @@ lgm_clk_ddiv_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
{
struct lgm_clk_ddiv *ddiv = to_lgm_clk_ddiv(hw);
unsigned int div0, div1, exdiv;
- unsigned long flags;
u64 prate;
- spin_lock_irqsave(&ddiv->lock, flags);
div0 = lgm_get_clk_val(ddiv->membase, ddiv->reg,
ddiv->shift0, ddiv->width0) + 1;
div1 = lgm_get_clk_val(ddiv->membase, ddiv->reg,
ddiv->shift1, ddiv->width1) + 1;
exdiv = lgm_get_clk_val(ddiv->membase, ddiv->reg,
ddiv->shift2, ddiv->width2);
- spin_unlock_irqrestore(&ddiv->lock, flags);
-
prate = (u64)parent_rate;
do_div(prate, div0);
do_div(prate, div1);
@@ -548,24 +544,21 @@ lgm_clk_ddiv_round_rate(struct clk_hw *hw, unsigned long rate,
div = div * 2;
div = DIV_ROUND_CLOSEST_ULL((u64)div, 5);
}
+ spin_unlock_irqrestore(&ddiv->lock, flags);
- if (div <= 0) {
- spin_unlock_irqrestore(&ddiv->lock, flags);
+ if (div <= 0)
return *prate;
- }
- if (lgm_clk_get_ddiv_val(div, &ddiv1, &ddiv2) != 0) {
- if (lgm_clk_get_ddiv_val(div + 1, &ddiv1, &ddiv2) != 0) {
- spin_unlock_irqrestore(&ddiv->lock, flags);
+ if (lgm_clk_get_ddiv_val(div, &ddiv1, &ddiv2) != 0)
+ if (lgm_clk_get_ddiv_val(div + 1, &ddiv1, &ddiv2) != 0)
return -EINVAL;
- }
- }
rate64 = *prate;
do_div(rate64, ddiv1);
do_div(rate64, ddiv2);
/* if predivide bit is enabled, modify rounded rate by factor of 2.5 */
+ spin_lock_irqsave(&ddiv->lock, flags);
if (lgm_get_clk_val(ddiv->membase, ddiv->reg, ddiv->shift2, 1)) {
rate64 = rate64 * 2;
rate64 = DIV_ROUND_CLOSEST_ULL(rate64, 5);
@@ -588,19 +581,18 @@ int lgm_clk_register_ddiv(struct lgm_clk_provider *ctx,
unsigned int nr_clk)
{
struct device *dev = ctx->dev;
- struct clk_init_data init = {};
- struct lgm_clk_ddiv *ddiv;
struct clk_hw *hw;
unsigned int idx;
int ret;
for (idx = 0; idx < nr_clk; idx++, list++) {
- ddiv = NULL;
+ struct clk_init_data init = {};
+ struct lgm_clk_ddiv *ddiv;
+
ddiv = devm_kzalloc(dev, sizeof(*ddiv), GFP_KERNEL);
if (!ddiv)
return -ENOMEM;
- memset(&init, 0, sizeof(init));
init.name = list->name;
init.ops = &lgm_clk_ddiv_ops;
init.flags = list->flags;
@@ -624,7 +616,7 @@ int lgm_clk_register_ddiv(struct lgm_clk_provider *ctx,
ddiv->hw.init = &init;
hw = &ddiv->hw;
- ret = clk_hw_register(dev, hw);
+ ret = devm_clk_hw_register(dev, hw);
if (ret) {
dev_err(dev, "register clk: %s failed!\n", list->name);
return ret;
diff --git a/drivers/firmware/raspberrypi.c b/drivers/firmware/raspberrypi.c
index ef8098856a47..b25901a77c09 100644
--- a/drivers/firmware/raspberrypi.c
+++ b/drivers/firmware/raspberrypi.c
@@ -208,6 +208,20 @@ rpi_register_hwmon_driver(struct device *dev, struct rpi_firmware *fw)
static void rpi_register_clk_driver(struct device *dev)
{
+ struct device_node *firmware;
+
+ /*
+ * Earlier DTs don't have a node for the firmware clocks but
+ * rely on us creating a platform device by hand. If we do
+ * have a node for the firmware clocks, just bail out here.
+ */
+ firmware = of_get_compatible_child(dev->of_node,
+ "raspberrypi,firmware-clocks");
+ if (firmware) {
+ of_node_put(firmware);
+ return;
+ }
+
rpi_clk = platform_device_register_data(dev, "raspberrypi-clk",
-1, NULL, 0);
}
diff --git a/drivers/perf/Kconfig b/drivers/perf/Kconfig
index a9261cf48293..7305d57d1890 100644
--- a/drivers/perf/Kconfig
+++ b/drivers/perf/Kconfig
@@ -82,6 +82,7 @@ config FSL_IMX8_DDR_PMU
config QCOM_L2_PMU
bool "Qualcomm Technologies L2-cache PMU"
depends on ARCH_QCOM && ARM64 && ACPI
+ select QCOM_KRYO_L2_ACCESSORS
help
Provides support for the L2 cache performance monitor unit (PMU)
in Qualcomm Technologies processors.
diff --git a/drivers/perf/qcom_l2_pmu.c b/drivers/perf/qcom_l2_pmu.c
index 21d6991dbe0b..02ca1fadbedd 100644
--- a/drivers/perf/qcom_l2_pmu.c
+++ b/drivers/perf/qcom_l2_pmu.c
@@ -23,6 +23,7 @@
#include <asm/barrier.h>
#include <asm/local64.h>
#include <asm/sysreg.h>
+#include <soc/qcom/kryo-l2-accessors.h>
#define MAX_L2_CTRS 9
@@ -79,8 +80,6 @@
#define L2_COUNTER_RELOAD BIT_ULL(31)
#define L2_CYCLE_COUNTER_RELOAD BIT_ULL(63)
-#define L2CPUSRSELR_EL1 sys_reg(3, 3, 15, 0, 6)
-#define L2CPUSRDR_EL1 sys_reg(3, 3, 15, 0, 7)
#define reg_idx(reg, i) (((i) * IA_L2_REG_OFFSET) + reg##_BASE)
@@ -99,48 +98,7 @@
#define L2_EVENT_STREX 0x421
#define L2_EVENT_CLREX 0x422
-static DEFINE_RAW_SPINLOCK(l2_access_lock);
-/**
- * set_l2_indirect_reg: write value to an L2 register
- * @reg: Address of L2 register.
- * @value: Value to be written to register.
- *
- * Use architecturally required barriers for ordering between system register
- * accesses
- */
-static void set_l2_indirect_reg(u64 reg, u64 val)
-{
- unsigned long flags;
-
- raw_spin_lock_irqsave(&l2_access_lock, flags);
- write_sysreg_s(reg, L2CPUSRSELR_EL1);
- isb();
- write_sysreg_s(val, L2CPUSRDR_EL1);
- isb();
- raw_spin_unlock_irqrestore(&l2_access_lock, flags);
-}
-
-/**
- * get_l2_indirect_reg: read an L2 register value
- * @reg: Address of L2 register.
- *
- * Use architecturally required barriers for ordering between system register
- * accesses
- */
-static u64 get_l2_indirect_reg(u64 reg)
-{
- u64 val;
- unsigned long flags;
-
- raw_spin_lock_irqsave(&l2_access_lock, flags);
- write_sysreg_s(reg, L2CPUSRSELR_EL1);
- isb();
- val = read_sysreg_s(L2CPUSRDR_EL1);
- raw_spin_unlock_irqrestore(&l2_access_lock, flags);
-
- return val;
-}
struct cluster_pmu;
@@ -211,28 +169,28 @@ static inline struct cluster_pmu *get_cluster_pmu(
static void cluster_pmu_reset(void)
{
/* Reset all counters */
- set_l2_indirect_reg(L2PMCR, L2PMCR_RESET_ALL);
- set_l2_indirect_reg(L2PMCNTENCLR, l2_counter_present_mask);
- set_l2_indirect_reg(L2PMINTENCLR, l2_counter_present_mask);
- set_l2_indirect_reg(L2PMOVSCLR, l2_counter_present_mask);
+ kryo_l2_set_indirect_reg(L2PMCR, L2PMCR_RESET_ALL);
+ kryo_l2_set_indirect_reg(L2PMCNTENCLR, l2_counter_present_mask);
+ kryo_l2_set_indirect_reg(L2PMINTENCLR, l2_counter_present_mask);
+ kryo_l2_set_indirect_reg(L2PMOVSCLR, l2_counter_present_mask);
}
static inline void cluster_pmu_enable(void)
{
- set_l2_indirect_reg(L2PMCR, L2PMCR_COUNTERS_ENABLE);
+ kryo_l2_set_indirect_reg(L2PMCR, L2PMCR_COUNTERS_ENABLE);
}
static inline void cluster_pmu_disable(void)
{
- set_l2_indirect_reg(L2PMCR, L2PMCR_COUNTERS_DISABLE);
+ kryo_l2_set_indirect_reg(L2PMCR, L2PMCR_COUNTERS_DISABLE);
}
static inline void cluster_pmu_counter_set_value(u32 idx, u64 value)
{
if (idx == l2_cycle_ctr_idx)
- set_l2_indirect_reg(L2PMCCNTR, value);
+ kryo_l2_set_indirect_reg(L2PMCCNTR, value);
else
- set_l2_indirect_reg(reg_idx(IA_L2PMXEVCNTR, idx), value);
+ kryo_l2_set_indirect_reg(reg_idx(IA_L2PMXEVCNTR, idx), value);
}
static inline u64 cluster_pmu_counter_get_value(u32 idx)
@@ -240,46 +198,46 @@ static inline u64 cluster_pmu_counter_get_value(u32 idx)
u64 value;
if (idx == l2_cycle_ctr_idx)
- value = get_l2_indirect_reg(L2PMCCNTR);
+ value = kryo_l2_get_indirect_reg(L2PMCCNTR);
else
- value = get_l2_indirect_reg(reg_idx(IA_L2PMXEVCNTR, idx));
+ value = kryo_l2_get_indirect_reg(reg_idx(IA_L2PMXEVCNTR, idx));
return value;
}
static inline void cluster_pmu_counter_enable(u32 idx)
{
- set_l2_indirect_reg(L2PMCNTENSET, idx_to_reg_bit(idx));
+ kryo_l2_set_indirect_reg(L2PMCNTENSET, idx_to_reg_bit(idx));
}
static inline void cluster_pmu_counter_disable(u32 idx)
{
- set_l2_indirect_reg(L2PMCNTENCLR, idx_to_reg_bit(idx));
+ kryo_l2_set_indirect_reg(L2PMCNTENCLR, idx_to_reg_bit(idx));
}
static inline void cluster_pmu_counter_enable_interrupt(u32 idx)
{
- set_l2_indirect_reg(L2PMINTENSET, idx_to_reg_bit(idx));
+ kryo_l2_set_indirect_reg(L2PMINTENSET, idx_to_reg_bit(idx));
}
static inline void cluster_pmu_counter_disable_interrupt(u32 idx)
{
- set_l2_indirect_reg(L2PMINTENCLR, idx_to_reg_bit(idx));
+ kryo_l2_set_indirect_reg(L2PMINTENCLR, idx_to_reg_bit(idx));
}
static inline void cluster_pmu_set_evccntcr(u32 val)
{
- set_l2_indirect_reg(L2PMCCNTCR, val);
+ kryo_l2_set_indirect_reg(L2PMCCNTCR, val);
}
static inline void cluster_pmu_set_evcntcr(u32 ctr, u32 val)
{
- set_l2_indirect_reg(reg_idx(IA_L2PMXEVCNTCR, ctr), val);
+ kryo_l2_set_indirect_reg(reg_idx(IA_L2PMXEVCNTCR, ctr), val);
}
static inline void cluster_pmu_set_evtyper(u32 ctr, u32 val)
{
- set_l2_indirect_reg(reg_idx(IA_L2PMXEVTYPER, ctr), val);
+ kryo_l2_set_indirect_reg(reg_idx(IA_L2PMXEVTYPER, ctr), val);
}
static void cluster_pmu_set_resr(struct cluster_pmu *cluster,
@@ -295,11 +253,11 @@ static void cluster_pmu_set_resr(struct cluster_pmu *cluster,
spin_lock_irqsave(&cluster->pmu_lock, flags);
- resr_val = get_l2_indirect_reg(L2PMRESR);
+ resr_val = kryo_l2_get_indirect_reg(L2PMRESR);
resr_val &= ~(L2PMRESR_GROUP_MASK << shift);
resr_val |= field;
resr_val |= L2PMRESR_EN;
- set_l2_indirect_reg(L2PMRESR, resr_val);
+ kryo_l2_set_indirect_reg(L2PMRESR, resr_val);
spin_unlock_irqrestore(&cluster->pmu_lock, flags);
}
@@ -315,14 +273,14 @@ static inline void cluster_pmu_set_evfilter_sys_mode(u32 ctr)
L2PMXEVFILTER_ORGFILTER_IDINDEP |
L2PMXEVFILTER_ORGFILTER_ALL;
- set_l2_indirect_reg(reg_idx(IA_L2PMXEVFILTER, ctr), val);
+ kryo_l2_set_indirect_reg(reg_idx(IA_L2PMXEVFILTER, ctr), val);
}
static inline u32 cluster_pmu_getreset_ovsr(void)
{
- u32 result = get_l2_indirect_reg(L2PMOVSSET);
+ u32 result = kryo_l2_get_indirect_reg(L2PMOVSSET);
- set_l2_indirect_reg(L2PMOVSCLR, result);
+ kryo_l2_set_indirect_reg(L2PMOVSCLR, result);
return result;
}
@@ -767,7 +725,7 @@ static int get_num_counters(void)
{
int val;
- val = get_l2_indirect_reg(L2PMCR);
+ val = kryo_l2_get_indirect_reg(L2PMCR);
/*
* Read number of counters from L2PMCR and add 1
diff --git a/drivers/reset/reset-simple.c b/drivers/reset/reset-simple.c
index 067e7e7b34f1..e066614818a3 100644
--- a/drivers/reset/reset-simple.c
+++ b/drivers/reset/reset-simple.c
@@ -11,6 +11,7 @@
* Maxime Ripard <maxime.ripard@free-electrons.com>
*/
+#include <linux/delay.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/io.h>
@@ -18,10 +19,9 @@
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/reset-controller.h>
+#include <linux/reset/reset-simple.h>
#include <linux/spinlock.h>
-#include "reset-simple.h"
-
static inline struct reset_simple_data *
to_reset_simple_data(struct reset_controller_dev *rcdev)
{
@@ -64,6 +64,24 @@ static int reset_simple_deassert(struct reset_controller_dev *rcdev,
return reset_simple_update(rcdev, id, false);
}
+static int reset_simple_reset(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ struct reset_simple_data *data = to_reset_simple_data(rcdev);
+ int ret;
+
+ if (!data->reset_us)
+ return -ENOTSUPP;
+
+ ret = reset_simple_assert(rcdev, id);
+ if (ret)
+ return ret;
+
+ usleep_range(data->reset_us, data->reset_us * 2);
+
+ return reset_simple_deassert(rcdev, id);
+}
+
static int reset_simple_status(struct reset_controller_dev *rcdev,
unsigned long id)
{
@@ -81,6 +99,7 @@ static int reset_simple_status(struct reset_controller_dev *rcdev,
const struct reset_control_ops reset_simple_ops = {
.assert = reset_simple_assert,
.deassert = reset_simple_deassert,
+ .reset = reset_simple_reset,
.status = reset_simple_status,
};
EXPORT_SYMBOL_GPL(reset_simple_ops);
diff --git a/drivers/reset/reset-socfpga.c b/drivers/reset/reset-socfpga.c
index 96953992c2bb..bdd984296196 100644
--- a/drivers/reset/reset-socfpga.c
+++ b/drivers/reset/reset-socfpga.c
@@ -11,13 +11,12 @@
#include <linux/of_address.h>
#include <linux/platform_device.h>
#include <linux/reset-controller.h>
+#include <linux/reset/reset-simple.h>
#include <linux/reset/socfpga.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/types.h>
-#include "reset-simple.h"
-
#define SOCFPGA_NR_BANKS 8
static int a10_reset_init(struct device_node *np)
diff --git a/drivers/reset/reset-sunxi.c b/drivers/reset/reset-sunxi.c
index e7f169e57bcf..e752594b6971 100644
--- a/drivers/reset/reset-sunxi.c
+++ b/drivers/reset/reset-sunxi.c
@@ -14,13 +14,12 @@
#include <linux/of_address.h>
#include <linux/platform_device.h>
#include <linux/reset-controller.h>
+#include <linux/reset/reset-simple.h>
#include <linux/reset/sunxi.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/types.h>
-#include "reset-simple.h"
-
static int sunxi_reset_init(struct device_node *np)
{
struct reset_simple_data *data;
diff --git a/drivers/reset/reset-uniphier-glue.c b/drivers/reset/reset-uniphier-glue.c
index 2b188b3bb69a..027990b79f61 100644
--- a/drivers/reset/reset-uniphier-glue.c
+++ b/drivers/reset/reset-uniphier-glue.c
@@ -9,8 +9,7 @@
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/reset.h>
-
-#include "reset-simple.h"
+#include <linux/reset/reset-simple.h>
#define MAX_CLKS 2
#define MAX_RSTS 2
diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
index 07bb261a63d2..cdc4f46d64ef 100644
--- a/drivers/soc/qcom/Kconfig
+++ b/drivers/soc/qcom/Kconfig
@@ -53,6 +53,10 @@ config QCOM_LLCC
SDM845. This provides interfaces to clients that use the LLCC.
Say yes here to enable LLCC slice driver.
+config QCOM_KRYO_L2_ACCESSORS
+ bool
+ depends on ARCH_QCOM && ARM64 || COMPILE_TEST
+
config QCOM_MDT_LOADER
tristate
select QCOM_SCM
diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
index 7d7e2ecbdce6..93392d9dc7f7 100644
--- a/drivers/soc/qcom/Makefile
+++ b/drivers/soc/qcom/Makefile
@@ -24,3 +24,4 @@ obj-$(CONFIG_QCOM_APR) += apr.o
obj-$(CONFIG_QCOM_LLCC) += llcc-qcom.o
obj-$(CONFIG_QCOM_RPMHPD) += rpmhpd.o
obj-$(CONFIG_QCOM_RPMPD) += rpmpd.o
+obj-$(CONFIG_QCOM_KRYO_L2_ACCESSORS) += kryo-l2-accessors.o
diff --git a/drivers/soc/qcom/kryo-l2-accessors.c b/drivers/soc/qcom/kryo-l2-accessors.c
new file mode 100644
index 000000000000..c20cb92077c0
--- /dev/null
+++ b/drivers/soc/qcom/kryo-l2-accessors.c
@@ -0,0 +1,57 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/spinlock.h>
+#include <asm/barrier.h>
+#include <asm/sysreg.h>
+#include <soc/qcom/kryo-l2-accessors.h>
+
+#define L2CPUSRSELR_EL1 sys_reg(3, 3, 15, 0, 6)
+#define L2CPUSRDR_EL1 sys_reg(3, 3, 15, 0, 7)
+
+static DEFINE_RAW_SPINLOCK(l2_access_lock);
+
+/**
+ * kryo_l2_set_indirect_reg() - write value to an L2 register
+ * @reg: Address of L2 register.
+ * @value: Value to be written to register.
+ *
+ * Use architecturally required barriers for ordering between system register
+ * accesses, and system registers with respect to device memory
+ */
+void kryo_l2_set_indirect_reg(u64 reg, u64 val)
+{
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&l2_access_lock, flags);
+ write_sysreg_s(reg, L2CPUSRSELR_EL1);
+ isb();
+ write_sysreg_s(val, L2CPUSRDR_EL1);
+ isb();
+ raw_spin_unlock_irqrestore(&l2_access_lock, flags);
+}
+EXPORT_SYMBOL(kryo_l2_set_indirect_reg);
+
+/**
+ * kryo_l2_get_indirect_reg() - read an L2 register value
+ * @reg: Address of L2 register.
+ *
+ * Use architecturally required barriers for ordering between system register
+ * accesses, and system registers with respect to device memory
+ */
+u64 kryo_l2_get_indirect_reg(u64 reg)
+{
+ u64 val;
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&l2_access_lock, flags);
+ write_sysreg_s(reg, L2CPUSRSELR_EL1);
+ isb();
+ val = read_sysreg_s(L2CPUSRDR_EL1);
+ raw_spin_unlock_irqrestore(&l2_access_lock, flags);
+
+ return val;
+}
+EXPORT_SYMBOL(kryo_l2_get_indirect_reg);
diff --git a/include/dt-bindings/clk/versaclock.h b/include/dt-bindings/clk/versaclock.h
new file mode 100644
index 000000000000..c6a6a0946564
--- /dev/null
+++ b/include/dt-bindings/clk/versaclock.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/* This file defines field values used by the versaclock 6 family
+ * for defining output type
+ */
+
+#define VC5_LVPECL 0
+#define VC5_CMOS 1
+#define VC5_HCSL33 2
+#define VC5_LVDS 3
+#define VC5_CMOS2 4
+#define VC5_CMOSD 5
+#define VC5_HCSL25 6
diff --git a/include/dt-bindings/clock/actions,s500-cmu.h b/include/dt-bindings/clock/actions,s500-cmu.h
index 030981cd2d56..a250a52a6192 100644
--- a/include/dt-bindings/clock/actions,s500-cmu.h
+++ b/include/dt-bindings/clock/actions,s500-cmu.h
@@ -72,7 +72,12 @@
#define CLK_NAND 52
#define CLK_ECC 53
#define CLK_RMII_REF 54
+#define CLK_GPIO 55
-#define CLK_NR_CLKS (CLK_RMII_REF + 1)
+/* system clock (part 2) */
+#define CLK_APB 56
+#define CLK_DMAC 57
+
+#define CLK_NR_CLKS (CLK_DMAC + 1)
#endif /* __DT_BINDINGS_CLOCK_S500_CMU_H */
diff --git a/include/dt-bindings/clock/agilex-clock.h b/include/dt-bindings/clock/agilex-clock.h
index f19cf8ccbdd2..06feca07e08e 100644
--- a/include/dt-bindings/clock/agilex-clock.h
+++ b/include/dt-bindings/clock/agilex-clock.h
@@ -65,6 +65,8 @@
#define AGILEX_SDMMC_CLK 50
#define AGILEX_SPI_M_CLK 51
#define AGILEX_USB_CLK 52
-#define AGILEX_NUM_CLKS 53
+#define AGILEX_NAND_X_CLK 53
+#define AGILEX_NAND_ECC_CLK 54
+#define AGILEX_NUM_CLKS 55
#endif /* __AGILEX_CLOCK_H */
diff --git a/include/dt-bindings/clock/bcm3368-clock.h b/include/dt-bindings/clock/bcm3368-clock.h
new file mode 100644
index 000000000000..74a7382f77b8
--- /dev/null
+++ b/include/dt-bindings/clock/bcm3368-clock.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+
+#ifndef __DT_BINDINGS_CLOCK_BCM3368_H
+#define __DT_BINDINGS_CLOCK_BCM3368_H
+
+#define BCM3368_CLK_MAC 3
+#define BCM3368_CLK_TC 5
+#define BCM3368_CLK_US_TOP 6
+#define BCM3368_CLK_DS_TOP 7
+#define BCM3368_CLK_ACM 8
+#define BCM3368_CLK_SPI 9
+#define BCM3368_CLK_USBS 10
+#define BCM3368_CLK_BMU 11
+#define BCM3368_CLK_PCM 12
+#define BCM3368_CLK_NTP 13
+#define BCM3368_CLK_ACP_B 14
+#define BCM3368_CLK_ACP_A 15
+#define BCM3368_CLK_EMUSB 17
+#define BCM3368_CLK_ENET0 18
+#define BCM3368_CLK_ENET1 19
+#define BCM3368_CLK_USBSU 20
+#define BCM3368_CLK_EPHY 21
+
+#endif /* __DT_BINDINGS_CLOCK_BCM3368_H */
diff --git a/include/dt-bindings/clock/bcm6318-clock.h b/include/dt-bindings/clock/bcm6318-clock.h
new file mode 100644
index 000000000000..c4417f8983ab
--- /dev/null
+++ b/include/dt-bindings/clock/bcm6318-clock.h
@@ -0,0 +1,42 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+
+#ifndef __DT_BINDINGS_CLOCK_BCM6318_H
+#define __DT_BINDINGS_CLOCK_BCM6318_H
+
+#define BCM6318_CLK_ADSL_ASB 0
+#define BCM6318_CLK_USB_ASB 1
+#define BCM6318_CLK_MIPS_ASB 2
+#define BCM6318_CLK_PCIE_ASB 3
+#define BCM6318_CLK_PHYMIPS_ASB 4
+#define BCM6318_CLK_ROBOSW_ASB 5
+#define BCM6318_CLK_SAR_ASB 6
+#define BCM6318_CLK_SDR_ASB 7
+#define BCM6318_CLK_SWREG_ASB 8
+#define BCM6318_CLK_PERIPH_ASB 9
+#define BCM6318_CLK_CPUBUS160 10
+#define BCM6318_CLK_ADSL 11
+#define BCM6318_CLK_SAR125 12
+#define BCM6318_CLK_MIPS 13
+#define BCM6318_CLK_PCIE 14
+#define BCM6318_CLK_ROBOSW250 16
+#define BCM6318_CLK_ROBOSW025 17
+#define BCM6318_CLK_SDR 19
+#define BCM6318_CLK_USBD 20
+#define BCM6318_CLK_HSSPI 25
+#define BCM6318_CLK_PCIE25 27
+#define BCM6318_CLK_PHYMIPS 28
+#define BCM6318_CLK_AFE 29
+#define BCM6318_CLK_QPROC 30
+
+#define BCM6318_UCLK_ADSL 0
+#define BCM6318_UCLK_ARB 1
+#define BCM6318_UCLK_MIPS 2
+#define BCM6318_UCLK_PCIE 3
+#define BCM6318_UCLK_PERIPH 4
+#define BCM6318_UCLK_PHYMIPS 5
+#define BCM6318_UCLK_ROBOSW 6
+#define BCM6318_UCLK_SAR 7
+#define BCM6318_UCLK_SDR 8
+#define BCM6318_UCLK_USB 9
+
+#endif /* __DT_BINDINGS_CLOCK_BCM6318_H */
diff --git a/include/dt-bindings/clock/bcm63268-clock.h b/include/dt-bindings/clock/bcm63268-clock.h
new file mode 100644
index 000000000000..da23e691d359
--- /dev/null
+++ b/include/dt-bindings/clock/bcm63268-clock.h
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+
+#ifndef __DT_BINDINGS_CLOCK_BCM63268_H
+#define __DT_BINDINGS_CLOCK_BCM63268_H
+
+#define BCM63268_CLK_DIS_GLESS 0
+#define BCM63268_CLK_VDSL_QPROC 1
+#define BCM63268_CLK_VDSL_AFE 2
+#define BCM63268_CLK_VDSL 3
+#define BCM63268_CLK_MIPS 4
+#define BCM63268_CLK_WLAN_OCP 5
+#define BCM63268_CLK_DECT 6
+#define BCM63268_CLK_FAP0 7
+#define BCM63268_CLK_FAP1 8
+#define BCM63268_CLK_SAR 9
+#define BCM63268_CLK_ROBOSW 10
+#define BCM63268_CLK_PCM 11
+#define BCM63268_CLK_USBD 12
+#define BCM63268_CLK_USBH 13
+#define BCM63268_CLK_IPSEC 14
+#define BCM63268_CLK_SPI 15
+#define BCM63268_CLK_HSSPI 16
+#define BCM63268_CLK_PCIE 17
+#define BCM63268_CLK_PHYMIPS 18
+#define BCM63268_CLK_GMAC 19
+#define BCM63268_CLK_NAND 20
+#define BCM63268_CLK_TBUS 27
+#define BCM63268_CLK_ROBOSW250 31
+
+#endif /* __DT_BINDINGS_CLOCK_BCM63268_H */
diff --git a/include/dt-bindings/clock/bcm6328-clock.h b/include/dt-bindings/clock/bcm6328-clock.h
new file mode 100644
index 000000000000..1f6a3103f3dc
--- /dev/null
+++ b/include/dt-bindings/clock/bcm6328-clock.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+
+#ifndef __DT_BINDINGS_CLOCK_BCM6328_H
+#define __DT_BINDINGS_CLOCK_BCM6328_H
+
+#define BCM6328_CLK_PHYMIPS 0
+#define BCM6328_CLK_ADSL_QPROC 1
+#define BCM6328_CLK_ADSL_AFE 2
+#define BCM6328_CLK_ADSL 3
+#define BCM6328_CLK_MIPS 4
+#define BCM6328_CLK_SAR 5
+#define BCM6328_CLK_PCM 6
+#define BCM6328_CLK_USBD 7
+#define BCM6328_CLK_USBH 8
+#define BCM6328_CLK_HSSPI 9
+#define BCM6328_CLK_PCIE 10
+#define BCM6328_CLK_ROBOSW 11
+
+#endif /* __DT_BINDINGS_CLOCK_BCM6328_H */
diff --git a/include/dt-bindings/clock/bcm6358-clock.h b/include/dt-bindings/clock/bcm6358-clock.h
new file mode 100644
index 000000000000..980c9cac4765
--- /dev/null
+++ b/include/dt-bindings/clock/bcm6358-clock.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+
+#ifndef __DT_BINDINGS_CLOCK_BCM6358_H
+#define __DT_BINDINGS_CLOCK_BCM6358_H
+
+#define BCM6358_CLK_ENET 4
+#define BCM6358_CLK_ADSLPHY 5
+#define BCM6358_CLK_PCM 8
+#define BCM6358_CLK_SPI 9
+#define BCM6358_CLK_USBS 10
+#define BCM6358_CLK_SAR 11
+#define BCM6358_CLK_EMUSB 17
+#define BCM6358_CLK_ENET0 18
+#define BCM6358_CLK_ENET1 19
+#define BCM6358_CLK_USBSU 20
+#define BCM6358_CLK_EPHY 21
+
+#endif /* __DT_BINDINGS_CLOCK_BCM6358_H */
diff --git a/include/dt-bindings/clock/bcm6362-clock.h b/include/dt-bindings/clock/bcm6362-clock.h
new file mode 100644
index 000000000000..17655cd5bf25
--- /dev/null
+++ b/include/dt-bindings/clock/bcm6362-clock.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+
+#ifndef __DT_BINDINGS_CLOCK_BCM6362_H
+#define __DT_BINDINGS_CLOCK_BCM6362_H
+
+#define BCM6362_CLK_ADSL_QPROC 1
+#define BCM6362_CLK_ADSL_AFE 2
+#define BCM6362_CLK_ADSL 3
+#define BCM6362_CLK_MIPS 4
+#define BCM6362_CLK_WLAN_OCP 5
+#define BCM6362_CLK_SWPKT_USB 7
+#define BCM6362_CLK_SWPKT_SAR 8
+#define BCM6362_CLK_SAR 9
+#define BCM6362_CLK_ROBOSW 10
+#define BCM6362_CLK_PCM 11
+#define BCM6362_CLK_USBD 12
+#define BCM6362_CLK_USBH 13
+#define BCM6362_CLK_IPSEC 14
+#define BCM6362_CLK_SPI 15
+#define BCM6362_CLK_HSSPI 16
+#define BCM6362_CLK_PCIE 17
+#define BCM6362_CLK_FAP 18
+#define BCM6362_CLK_PHYMIPS 19
+#define BCM6362_CLK_NAND 20
+
+#endif /* __DT_BINDINGS_CLOCK_BCM6362_H */
diff --git a/include/dt-bindings/clock/bcm6368-clock.h b/include/dt-bindings/clock/bcm6368-clock.h
new file mode 100644
index 000000000000..f161d5333883
--- /dev/null
+++ b/include/dt-bindings/clock/bcm6368-clock.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+
+#ifndef __DT_BINDINGS_CLOCK_BCM6368_H
+#define __DT_BINDINGS_CLOCK_BCM6368_H
+
+#define BCM6368_CLK_VDSL_QPROC 2
+#define BCM6368_CLK_VDSL_AFE 3
+#define BCM6368_CLK_VDSL_BONDING 4
+#define BCM6368_CLK_VDSL 5
+#define BCM6368_CLK_PHYMIPS 6
+#define BCM6368_CLK_SWPKT_USB 7
+#define BCM6368_CLK_SWPKT_SAR 8
+#define BCM6368_CLK_SPI 9
+#define BCM6368_CLK_USBD 10
+#define BCM6368_CLK_SAR 11
+#define BCM6368_CLK_ROBOSW 12
+#define BCM6368_CLK_UTOPIA 13
+#define BCM6368_CLK_PCM 14
+#define BCM6368_CLK_USBH 15
+#define BCM6368_CLK_DIS_GLESS 16
+#define BCM6368_CLK_NAND 17
+#define BCM6368_CLK_IPSEC 18
+
+#endif /* __DT_BINDINGS_CLOCK_BCM6368_H */
diff --git a/include/dt-bindings/clock/g12a-clkc.h b/include/dt-bindings/clock/g12a-clkc.h
index b0d65d73db96..40d49940d8a8 100644
--- a/include/dt-bindings/clock/g12a-clkc.h
+++ b/include/dt-bindings/clock/g12a-clkc.h
@@ -145,5 +145,7 @@
#define CLKID_CPU3_CLK 255
#define CLKID_SPICC0_SCLK 258
#define CLKID_SPICC1_SCLK 261
+#define CLKID_NNA_AXI_CLK 264
+#define CLKID_NNA_CORE_CLK 267
#endif /* __G12A_CLKC_H */
diff --git a/include/dt-bindings/clock/jz4780-cgu.h b/include/dt-bindings/clock/jz4780-cgu.h
index 1859ce53ee38..85cf8eb5081b 100644
--- a/include/dt-bindings/clock/jz4780-cgu.h
+++ b/include/dt-bindings/clock/jz4780-cgu.h
@@ -12,78 +12,80 @@
#ifndef __DT_BINDINGS_CLOCK_JZ4780_CGU_H__
#define __DT_BINDINGS_CLOCK_JZ4780_CGU_H__
-#define JZ4780_CLK_EXCLK 0
-#define JZ4780_CLK_RTCLK 1
-#define JZ4780_CLK_APLL 2
-#define JZ4780_CLK_MPLL 3
-#define JZ4780_CLK_EPLL 4
-#define JZ4780_CLK_VPLL 5
-#define JZ4780_CLK_OTGPHY 6
-#define JZ4780_CLK_SCLKA 7
-#define JZ4780_CLK_CPUMUX 8
-#define JZ4780_CLK_CPU 9
-#define JZ4780_CLK_L2CACHE 10
-#define JZ4780_CLK_AHB0 11
-#define JZ4780_CLK_AHB2PMUX 12
-#define JZ4780_CLK_AHB2 13
-#define JZ4780_CLK_PCLK 14
-#define JZ4780_CLK_DDR 15
-#define JZ4780_CLK_VPU 16
-#define JZ4780_CLK_I2SPLL 17
-#define JZ4780_CLK_I2S 18
+#define JZ4780_CLK_EXCLK 0
+#define JZ4780_CLK_RTCLK 1
+#define JZ4780_CLK_APLL 2
+#define JZ4780_CLK_MPLL 3
+#define JZ4780_CLK_EPLL 4
+#define JZ4780_CLK_VPLL 5
+#define JZ4780_CLK_OTGPHY 6
+#define JZ4780_CLK_SCLKA 7
+#define JZ4780_CLK_CPUMUX 8
+#define JZ4780_CLK_CPU 9
+#define JZ4780_CLK_L2CACHE 10
+#define JZ4780_CLK_AHB0 11
+#define JZ4780_CLK_AHB2PMUX 12
+#define JZ4780_CLK_AHB2 13
+#define JZ4780_CLK_PCLK 14
+#define JZ4780_CLK_DDR 15
+#define JZ4780_CLK_VPU 16
+#define JZ4780_CLK_I2SPLL 17
+#define JZ4780_CLK_I2S 18
#define JZ4780_CLK_LCD0PIXCLK 19
#define JZ4780_CLK_LCD1PIXCLK 20
-#define JZ4780_CLK_MSCMUX 21
-#define JZ4780_CLK_MSC0 22
-#define JZ4780_CLK_MSC1 23
-#define JZ4780_CLK_MSC2 24
-#define JZ4780_CLK_UHC 25
-#define JZ4780_CLK_SSIPLL 26
-#define JZ4780_CLK_SSI 27
-#define JZ4780_CLK_CIMMCLK 28
-#define JZ4780_CLK_PCMPLL 29
-#define JZ4780_CLK_PCM 30
-#define JZ4780_CLK_GPU 31
-#define JZ4780_CLK_HDMI 32
-#define JZ4780_CLK_BCH 33
-#define JZ4780_CLK_NEMC 34
-#define JZ4780_CLK_OTG0 35
-#define JZ4780_CLK_SSI0 36
-#define JZ4780_CLK_SMB0 37
-#define JZ4780_CLK_SMB1 38
-#define JZ4780_CLK_SCC 39
-#define JZ4780_CLK_AIC 40
-#define JZ4780_CLK_TSSI0 41
-#define JZ4780_CLK_OWI 42
-#define JZ4780_CLK_KBC 43
-#define JZ4780_CLK_SADC 44
-#define JZ4780_CLK_UART0 45
-#define JZ4780_CLK_UART1 46
-#define JZ4780_CLK_UART2 47
-#define JZ4780_CLK_UART3 48
-#define JZ4780_CLK_SSI1 49
-#define JZ4780_CLK_SSI2 50
-#define JZ4780_CLK_PDMA 51
-#define JZ4780_CLK_GPS 52
-#define JZ4780_CLK_MAC 53
-#define JZ4780_CLK_SMB2 54
-#define JZ4780_CLK_CIM 55
-#define JZ4780_CLK_LCD 56
-#define JZ4780_CLK_TVE 57
-#define JZ4780_CLK_IPU 58
-#define JZ4780_CLK_DDR0 59
-#define JZ4780_CLK_DDR1 60
-#define JZ4780_CLK_SMB3 61
-#define JZ4780_CLK_TSSI1 62
-#define JZ4780_CLK_COMPRESS 63
-#define JZ4780_CLK_AIC1 64
-#define JZ4780_CLK_GPVLC 65
-#define JZ4780_CLK_OTG1 66
-#define JZ4780_CLK_UART4 67
-#define JZ4780_CLK_AHBMON 68
-#define JZ4780_CLK_SMB4 69
-#define JZ4780_CLK_DES 70
-#define JZ4780_CLK_X2D 71
-#define JZ4780_CLK_CORE1 72
+#define JZ4780_CLK_MSCMUX 21
+#define JZ4780_CLK_MSC0 22
+#define JZ4780_CLK_MSC1 23
+#define JZ4780_CLK_MSC2 24
+#define JZ4780_CLK_UHC 25
+#define JZ4780_CLK_SSIPLL 26
+#define JZ4780_CLK_SSI 27
+#define JZ4780_CLK_CIMMCLK 28
+#define JZ4780_CLK_PCMPLL 29
+#define JZ4780_CLK_PCM 30
+#define JZ4780_CLK_GPU 31
+#define JZ4780_CLK_HDMI 32
+#define JZ4780_CLK_BCH 33
+#define JZ4780_CLK_NEMC 34
+#define JZ4780_CLK_OTG0 35
+#define JZ4780_CLK_SSI0 36
+#define JZ4780_CLK_SMB0 37
+#define JZ4780_CLK_SMB1 38
+#define JZ4780_CLK_SCC 39
+#define JZ4780_CLK_AIC 40
+#define JZ4780_CLK_TSSI0 41
+#define JZ4780_CLK_OWI 42
+#define JZ4780_CLK_KBC 43
+#define JZ4780_CLK_SADC 44
+#define JZ4780_CLK_UART0 45
+#define JZ4780_CLK_UART1 46
+#define JZ4780_CLK_UART2 47
+#define JZ4780_CLK_UART3 48
+#define JZ4780_CLK_SSI1 49
+#define JZ4780_CLK_SSI2 50
+#define JZ4780_CLK_PDMA 51
+#define JZ4780_CLK_GPS 52
+#define JZ4780_CLK_MAC 53
+#define JZ4780_CLK_SMB2 54
+#define JZ4780_CLK_CIM 55
+#define JZ4780_CLK_LCD 56
+#define JZ4780_CLK_TVE 57
+#define JZ4780_CLK_IPU 58
+#define JZ4780_CLK_DDR0 59
+#define JZ4780_CLK_DDR1 60
+#define JZ4780_CLK_SMB3 61
+#define JZ4780_CLK_TSSI1 62
+#define JZ4780_CLK_COMPRESS 63
+#define JZ4780_CLK_AIC1 64
+#define JZ4780_CLK_GPVLC 65
+#define JZ4780_CLK_OTG1 66
+#define JZ4780_CLK_UART4 67
+#define JZ4780_CLK_AHBMON 68
+#define JZ4780_CLK_SMB4 69
+#define JZ4780_CLK_DES 70
+#define JZ4780_CLK_X2D 71
+#define JZ4780_CLK_CORE1 72
+#define JZ4780_CLK_EXCLK_DIV512 73
+#define JZ4780_CLK_RTC 74
#endif /* __DT_BINDINGS_CLOCK_JZ4780_CGU_H__ */
diff --git a/include/dt-bindings/clock/qcom,apss-ipq.h b/include/dt-bindings/clock/qcom,apss-ipq.h
new file mode 100644
index 000000000000..77b6e05492e2
--- /dev/null
+++ b/include/dt-bindings/clock/qcom,apss-ipq.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DT_BINDINGS_CLOCK_QCA_APSS_IPQ6018_H
+#define _DT_BINDINGS_CLOCK_QCA_APSS_IPQ6018_H
+
+#define APCS_ALIAS0_CLK_SRC 0
+#define APCS_ALIAS0_CORE_CLK 1
+
+#endif
diff --git a/include/dt-bindings/clock/qcom,gcc-ipq8074.h b/include/dt-bindings/clock/qcom,gcc-ipq8074.h
index 4de4811a3540..8e2bec1c91bf 100644
--- a/include/dt-bindings/clock/qcom,gcc-ipq8074.h
+++ b/include/dt-bindings/clock/qcom,gcc-ipq8074.h
@@ -230,6 +230,9 @@
#define GCC_GP1_CLK 221
#define GCC_GP2_CLK 222
#define GCC_GP3_CLK 223
+#define GCC_PCIE0_AXI_S_BRIDGE_CLK 224
+#define GCC_PCIE0_RCHNG_CLK_SRC 225
+#define GCC_PCIE0_RCHNG_CLK 226
#define GCC_BLSP1_BCR 0
#define GCC_BLSP1_QUP1_BCR 1
@@ -362,5 +365,6 @@
#define GCC_PCIE1_AXI_SLAVE_ARES 128
#define GCC_PCIE1_AHB_ARES 129
#define GCC_PCIE1_AXI_MASTER_STICKY_ARES 130
+#define GCC_PCIE0_AXI_SLAVE_STICKY_ARES 131
#endif
diff --git a/include/dt-bindings/clock/qcom,gcc-sc7180.h b/include/dt-bindings/clock/qcom,gcc-sc7180.h
index 992b67b7e5e4..bdf43adc7897 100644
--- a/include/dt-bindings/clock/qcom,gcc-sc7180.h
+++ b/include/dt-bindings/clock/qcom,gcc-sc7180.h
@@ -138,6 +138,7 @@
#define GCC_MSS_Q6_MEMNOC_AXI_CLK 128
#define GCC_MSS_SNOC_AXI_CLK 129
#define GCC_SEC_CTRL_CLK_SRC 130
+#define GCC_LPASS_CFG_NOC_SWAY_CLK 131
/* GCC resets */
#define GCC_QUSB2PHY_PRIM_BCR 0
diff --git a/include/dt-bindings/clock/qcom,gcc-sdm660.h b/include/dt-bindings/clock/qcom,gcc-sdm660.h
index 468302282913..df8a6f3d367e 100644
--- a/include/dt-bindings/clock/qcom,gcc-sdm660.h
+++ b/include/dt-bindings/clock/qcom,gcc-sdm660.h
@@ -152,5 +152,6 @@
#define GCC_USB_20_BCR 6
#define GCC_USB_30_BCR 7
#define GCC_USB_PHY_CFG_AHB2PHY_BCR 8
+#define GCC_MSS_RESTART 9
#endif
diff --git a/include/dt-bindings/clock/qcom,gpucc-sm8150.h b/include/dt-bindings/clock/qcom,gpucc-sm8150.h
new file mode 100644
index 000000000000..c5b70aad7770
--- /dev/null
+++ b/include/dt-bindings/clock/qcom,gpucc-sm8150.h
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DT_BINDINGS_CLK_QCOM_GPU_CC_SM8150_H
+#define _DT_BINDINGS_CLK_QCOM_GPU_CC_SM8150_H
+
+/* GPU_CC clock registers */
+#define GPU_CC_AHB_CLK 0
+#define GPU_CC_CRC_AHB_CLK 1
+#define GPU_CC_CX_APB_CLK 2
+#define GPU_CC_CX_GMU_CLK 3
+#define GPU_CC_CX_SNOC_DVM_CLK 4
+#define GPU_CC_CXO_AON_CLK 5
+#define GPU_CC_CXO_CLK 6
+#define GPU_CC_GMU_CLK_SRC 7
+#define GPU_CC_GX_GMU_CLK 8
+#define GPU_CC_PLL1 9
+
+/* GPU_CC Resets */
+#define GPUCC_GPU_CC_CX_BCR 0
+#define GPUCC_GPU_CC_GFX3D_AON_BCR 1
+#define GPUCC_GPU_CC_GMU_BCR 2
+#define GPUCC_GPU_CC_GX_BCR 3
+#define GPUCC_GPU_CC_SPDM_BCR 4
+#define GPUCC_GPU_CC_XO_BCR 5
+
+/* GPU_CC GDSCRs */
+#define GPU_CX_GDSC 0
+#define GPU_GX_GDSC 1
+
+#endif
diff --git a/include/dt-bindings/clock/qcom,gpucc-sm8250.h b/include/dt-bindings/clock/qcom,gpucc-sm8250.h
new file mode 100644
index 000000000000..dc8e387c48ad
--- /dev/null
+++ b/include/dt-bindings/clock/qcom,gpucc-sm8250.h
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DT_BINDINGS_CLK_QCOM_GPU_CC_SM8250_H
+#define _DT_BINDINGS_CLK_QCOM_GPU_CC_SM8250_H
+
+/* GPU_CC clock registers */
+#define GPU_CC_AHB_CLK 0
+#define GPU_CC_CRC_AHB_CLK 1
+#define GPU_CC_CX_APB_CLK 2
+#define GPU_CC_CX_GMU_CLK 3
+#define GPU_CC_CX_SNOC_DVM_CLK 4
+#define GPU_CC_CXO_AON_CLK 5
+#define GPU_CC_CXO_CLK 6
+#define GPU_CC_GMU_CLK_SRC 7
+#define GPU_CC_GX_GMU_CLK 8
+#define GPU_CC_PLL1 9
+#define GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK 10
+
+/* GPU_CC Resets */
+#define GPUCC_GPU_CC_ACD_BCR 0
+#define GPUCC_GPU_CC_CX_BCR 1
+#define GPUCC_GPU_CC_GFX3D_AON_BCR 2
+#define GPUCC_GPU_CC_GMU_BCR 3
+#define GPUCC_GPU_CC_GX_BCR 4
+#define GPUCC_GPU_CC_XO_BCR 5
+
+/* GPU_CC GDSCRs */
+#define GPU_CX_GDSC 0
+#define GPU_GX_GDSC 1
+
+#endif
diff --git a/include/dt-bindings/clock/qcom,lpasscorecc-sc7180.h b/include/dt-bindings/clock/qcom,lpasscorecc-sc7180.h
new file mode 100644
index 000000000000..a55d01db2b20
--- /dev/null
+++ b/include/dt-bindings/clock/qcom,lpasscorecc-sc7180.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DT_BINDINGS_CLK_QCOM_LPASS_CORE_CC_SC7180_H
+#define _DT_BINDINGS_CLK_QCOM_LPASS_CORE_CC_SC7180_H
+
+/* LPASS_CORE_CC clocks */
+#define LPASS_LPAAUDIO_DIG_PLL 0
+#define LPASS_LPAAUDIO_DIG_PLL_OUT_ODD 1
+#define CORE_CLK_SRC 2
+#define EXT_MCLK0_CLK_SRC 3
+#define LPAIF_PRI_CLK_SRC 4
+#define LPAIF_SEC_CLK_SRC 5
+#define LPASS_AUDIO_CORE_CORE_CLK 6
+#define LPASS_AUDIO_CORE_EXT_MCLK0_CLK 7
+#define LPASS_AUDIO_CORE_LPAIF_PRI_IBIT_CLK 8
+#define LPASS_AUDIO_CORE_LPAIF_SEC_IBIT_CLK 9
+#define LPASS_AUDIO_CORE_SYSNOC_MPORT_CORE_CLK 10
+
+/* LPASS Core power domains */
+#define LPASS_CORE_HM_GDSCR 0
+
+/* LPASS Audio power domains */
+#define LPASS_AUDIO_HM_GDSCR 0
+#define LPASS_PDC_HM_GDSCR 1
+
+#endif
diff --git a/include/dt-bindings/clock/qcom,rpmcc.h b/include/dt-bindings/clock/qcom,rpmcc.h
index ae74c43c485d..8aaba7cd9589 100644
--- a/include/dt-bindings/clock/qcom,rpmcc.h
+++ b/include/dt-bindings/clock/qcom,rpmcc.h
@@ -133,5 +133,21 @@
#define RPM_SMD_RF_CLK3_A 87
#define RPM_SMD_RF_CLK3_PIN 88
#define RPM_SMD_RF_CLK3_A_PIN 89
+#define RPM_SMD_MMSSNOC_AXI_CLK 90
+#define RPM_SMD_MMSSNOC_AXI_CLK_A 91
+#define RPM_SMD_CNOC_PERIPH_CLK 92
+#define RPM_SMD_CNOC_PERIPH_A_CLK 93
+#define RPM_SMD_LN_BB_CLK3 94
+#define RPM_SMD_LN_BB_CLK3_A 95
+#define RPM_SMD_LN_BB_CLK1_PIN 96
+#define RPM_SMD_LN_BB_CLK1_A_PIN 97
+#define RPM_SMD_LN_BB_CLK2_PIN 98
+#define RPM_SMD_LN_BB_CLK2_A_PIN 99
+#define RPM_SMD_SYSMMNOC_CLK 100
+#define RPM_SMD_SYSMMNOC_A_CLK 101
+#define RPM_SMD_CE2_CLK 102
+#define RPM_SMD_CE2_A_CLK 103
+#define RPM_SMD_CE3_CLK 104
+#define RPM_SMD_CE3_A_CLK 105
#endif
diff --git a/include/dt-bindings/clock/r8a774e1-cpg-mssr.h b/include/dt-bindings/clock/r8a774e1-cpg-mssr.h
new file mode 100644
index 000000000000..b2fc1d1c3c47
--- /dev/null
+++ b/include/dt-bindings/clock/r8a774e1-cpg-mssr.h
@@ -0,0 +1,59 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (C) 2020 Renesas Electronics Corp.
+ */
+#ifndef __DT_BINDINGS_CLOCK_R8A774E1_CPG_MSSR_H__
+#define __DT_BINDINGS_CLOCK_R8A774E1_CPG_MSSR_H__
+
+#include <dt-bindings/clock/renesas-cpg-mssr.h>
+
+/* R8A774E1 CPG Core Clocks */
+#define R8A774E1_CLK_Z 0
+#define R8A774E1_CLK_Z2 1
+#define R8A774E1_CLK_ZG 2
+#define R8A774E1_CLK_ZTR 3
+#define R8A774E1_CLK_ZTRD2 4
+#define R8A774E1_CLK_ZT 5
+#define R8A774E1_CLK_ZX 6
+#define R8A774E1_CLK_S0D1 7
+#define R8A774E1_CLK_S0D2 8
+#define R8A774E1_CLK_S0D3 9
+#define R8A774E1_CLK_S0D4 10
+#define R8A774E1_CLK_S0D6 11
+#define R8A774E1_CLK_S0D8 12
+#define R8A774E1_CLK_S0D12 13
+#define R8A774E1_CLK_S1D2 14
+#define R8A774E1_CLK_S1D4 15
+#define R8A774E1_CLK_S2D1 16
+#define R8A774E1_CLK_S2D2 17
+#define R8A774E1_CLK_S2D4 18
+#define R8A774E1_CLK_S3D1 19
+#define R8A774E1_CLK_S3D2 20
+#define R8A774E1_CLK_S3D4 21
+#define R8A774E1_CLK_LB 22
+#define R8A774E1_CLK_CL 23
+#define R8A774E1_CLK_ZB3 24
+#define R8A774E1_CLK_ZB3D2 25
+#define R8A774E1_CLK_ZB3D4 26
+#define R8A774E1_CLK_CR 27
+#define R8A774E1_CLK_CRD2 28
+#define R8A774E1_CLK_SD0H 29
+#define R8A774E1_CLK_SD0 30
+#define R8A774E1_CLK_SD1H 31
+#define R8A774E1_CLK_SD1 32
+#define R8A774E1_CLK_SD2H 33
+#define R8A774E1_CLK_SD2 34
+#define R8A774E1_CLK_SD3H 35
+#define R8A774E1_CLK_SD3 36
+#define R8A774E1_CLK_RPC 37
+#define R8A774E1_CLK_RPCD2 38
+#define R8A774E1_CLK_MSO 39
+#define R8A774E1_CLK_HDMI 40
+#define R8A774E1_CLK_CSI0 41
+#define R8A774E1_CLK_CP 42
+#define R8A774E1_CLK_CPEX 43
+#define R8A774E1_CLK_R 44
+#define R8A774E1_CLK_OSC 45
+#define R8A774E1_CLK_CANFD 46
+
+#endif /* __DT_BINDINGS_CLOCK_R8A774E1_CPG_MSSR_H__ */
diff --git a/include/dt-bindings/clock/vf610-clock.h b/include/dt-bindings/clock/vf610-clock.h
index 95394f35a74a..0f2d60e884dc 100644
--- a/include/dt-bindings/clock/vf610-clock.h
+++ b/include/dt-bindings/clock/vf610-clock.h
@@ -195,6 +195,7 @@
#define VF610_CLK_WKPU 186
#define VF610_CLK_TCON0 187
#define VF610_CLK_TCON1 188
-#define VF610_CLK_END 189
+#define VF610_CLK_CAAM 189
+#define VF610_CLK_END 190
#endif /* __DT_BINDINGS_CLOCK_VF610_H */
diff --git a/include/dt-bindings/clock/x1000-cgu.h b/include/dt-bindings/clock/x1000-cgu.h
index 0367c8c02e16..f187e0719fd3 100644
--- a/include/dt-bindings/clock/x1000-cgu.h
+++ b/include/dt-bindings/clock/x1000-cgu.h
@@ -48,5 +48,7 @@
#define X1000_CLK_SSI 33
#define X1000_CLK_OST 34
#define X1000_CLK_PDMA 35
+#define X1000_CLK_EXCLK_DIV512 36
+#define X1000_CLK_RTC 37
#endif /* __DT_BINDINGS_CLOCK_X1000_CGU_H__ */
diff --git a/include/dt-bindings/clock/x1830-cgu.h b/include/dt-bindings/clock/x1830-cgu.h
index 801e1d09c881..88455376a950 100644
--- a/include/dt-bindings/clock/x1830-cgu.h
+++ b/include/dt-bindings/clock/x1830-cgu.h
@@ -51,5 +51,7 @@
#define X1830_CLK_TCU 36
#define X1830_CLK_DTRNG 37
#define X1830_CLK_OST 38
+#define X1830_CLK_EXCLK_DIV512 39
+#define X1830_CLK_RTC 40
#endif /* __DT_BINDINGS_CLOCK_X1830_CGU_H__ */
diff --git a/include/dt-bindings/power/r8a774e1-sysc.h b/include/dt-bindings/power/r8a774e1-sysc.h
new file mode 100644
index 000000000000..7edb8161db36
--- /dev/null
+++ b/include/dt-bindings/power/r8a774e1-sysc.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (C) 2020 Renesas Electronics Corp.
+ */
+#ifndef __DT_BINDINGS_POWER_R8A774E1_SYSC_H__
+#define __DT_BINDINGS_POWER_R8A774E1_SYSC_H__
+
+/*
+ * These power domain indices match the numbers of the interrupt bits
+ * representing the power areas in the various Interrupt Registers
+ * (e.g. SYSCISR, Interrupt Status Register)
+ */
+
+#define R8A774E1_PD_CA57_CPU0 0
+#define R8A774E1_PD_CA57_CPU1 1
+#define R8A774E1_PD_CA57_CPU2 2
+#define R8A774E1_PD_CA57_CPU3 3
+#define R8A774E1_PD_CA53_CPU0 5
+#define R8A774E1_PD_CA53_CPU1 6
+#define R8A774E1_PD_CA53_CPU2 7
+#define R8A774E1_PD_CA53_CPU3 8
+#define R8A774E1_PD_A3VP 9
+#define R8A774E1_PD_CA57_SCU 12
+#define R8A774E1_PD_A3VC 14
+#define R8A774E1_PD_3DG_A 17
+#define R8A774E1_PD_3DG_B 18
+#define R8A774E1_PD_3DG_C 19
+#define R8A774E1_PD_3DG_D 20
+#define R8A774E1_PD_CA53_SCU 21
+#define R8A774E1_PD_3DG_E 22
+#define R8A774E1_PD_A2VC1 26
+
+/* Always-on power area */
+#define R8A774E1_PD_ALWAYS_ON 32
+
+#endif /* __DT_BINDINGS_POWER_R8A774E1_SYSC_H__ */
diff --git a/include/dt-bindings/reset/actions,s500-reset.h b/include/dt-bindings/reset/actions,s500-reset.h
new file mode 100644
index 000000000000..f5d94176d10b
--- /dev/null
+++ b/include/dt-bindings/reset/actions,s500-reset.h
@@ -0,0 +1,67 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Device Tree binding constants for Actions Semi S500 Reset Management Unit
+ *
+ * Copyright (c) 2014 Actions Semi Inc.
+ * Copyright (c) 2020 Cristian Ciocaltea <cristian.ciocaltea@gmail.com>
+ */
+
+#ifndef __DT_BINDINGS_ACTIONS_S500_RESET_H
+#define __DT_BINDINGS_ACTIONS_S500_RESET_H
+
+#define RESET_DMAC 0
+#define RESET_NORIF 1
+#define RESET_DDR 2
+#define RESET_NANDC 3
+#define RESET_SD0 4
+#define RESET_SD1 5
+#define RESET_PCM1 6
+#define RESET_DE 7
+#define RESET_LCD 8
+#define RESET_SD2 9
+#define RESET_DSI 10
+#define RESET_CSI 11
+#define RESET_BISP 12
+#define RESET_KEY 13
+#define RESET_GPIO 14
+#define RESET_AUDIO 15
+#define RESET_PCM0 16
+#define RESET_VDE 17
+#define RESET_VCE 18
+#define RESET_GPU3D 19
+#define RESET_NIC301 20
+#define RESET_LENS 21
+#define RESET_PERIPHRESET 22
+#define RESET_USB2_0 23
+#define RESET_TVOUT 24
+#define RESET_HDMI 25
+#define RESET_HDCP2TX 26
+#define RESET_UART6 27
+#define RESET_UART0 28
+#define RESET_UART1 29
+#define RESET_UART2 30
+#define RESET_SPI0 31
+#define RESET_SPI1 32
+#define RESET_SPI2 33
+#define RESET_SPI3 34
+#define RESET_I2C0 35
+#define RESET_I2C1 36
+#define RESET_USB3 37
+#define RESET_UART3 38
+#define RESET_UART4 39
+#define RESET_UART5 40
+#define RESET_I2C2 41
+#define RESET_I2C3 42
+#define RESET_ETHERNET 43
+#define RESET_CHIPID 44
+#define RESET_USB2_1 45
+#define RESET_WD0RESET 46
+#define RESET_WD1RESET 47
+#define RESET_WD2RESET 48
+#define RESET_WD3RESET 49
+#define RESET_DBG0RESET 50
+#define RESET_DBG1RESET 51
+#define RESET_DBG2RESET 52
+#define RESET_DBG3RESET 53
+
+#endif /* __DT_BINDINGS_ACTIONS_S500_RESET_H */
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index bd1ee9039558..6f815be99b77 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -189,7 +189,7 @@ struct clk_duty {
* and >= numerator) Return 0 on success, otherwise -EERROR.
*
* @init: Perform platform-specific initialization magic.
- * This is not not used by any of the basic clock types.
+ * This is not used by any of the basic clock types.
* This callback exist for HW which needs to perform some
* initialisation magic for CCF to get an accurate view of the
* clock. It may also be used dynamic resource allocation is
diff --git a/drivers/reset/reset-simple.h b/include/linux/reset/reset-simple.h
index 08ccb25a55e6..c3e44f45b0f7 100644
--- a/drivers/reset/reset-simple.h
+++ b/include/linux/reset/reset-simple.h
@@ -27,6 +27,12 @@
* @status_active_low: if true, bits read back as cleared while the reset is
* asserted. Otherwise, bits read back as set while the
* reset is asserted.
+ * @reset_us: Minimum delay in microseconds needed that needs to be
+ * waited for between an assert and a deassert to reset the
+ * device. If multiple consumers with different delay
+ * requirements are connected to this controller, it must
+ * be the largest minimum delay. 0 means that such a delay is
+ * unknown and the reset operation is unsupported.
*/
struct reset_simple_data {
spinlock_t lock;
@@ -34,6 +40,7 @@ struct reset_simple_data {
struct reset_controller_dev rcdev;
bool active_low;
bool status_active_low;
+ unsigned int reset_us;
};
extern const struct reset_control_ops reset_simple_ops;
diff --git a/include/soc/qcom/kryo-l2-accessors.h b/include/soc/qcom/kryo-l2-accessors.h
new file mode 100644
index 000000000000..673c5344afe3
--- /dev/null
+++ b/include/soc/qcom/kryo-l2-accessors.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef __SOC_ARCH_QCOM_KRYO_L2_ACCESSORS_H
+#define __SOC_ARCH_QCOM_KRYO_L2_ACCESSORS_H
+
+void kryo_l2_set_indirect_reg(u64 reg, u64 val);
+u64 kryo_l2_get_indirect_reg(u64 reg);
+
+#endif