mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 04:02:20 +00:00
It looks like a smaller batch of clk updates this time around. In the core
framework we just have some minor tweaks and a debugfs feature, so not much to see there. The driver updates are fairly well split between AT91 and Qualcomm clk support. Adding those two drivers together equals about 50% of the diffstat. Otherwise, the big amount of work this time was on supporting Broadcom's Raspberry Pi firmware clks. See below for some more highlights. Core: - Document clk_hw_round_rate() so it gets some more use - Remove unused __clk_get_flags() - Add a prepare/enable debugfs feature similar to rate setting New Drivers: - Add support for SAMA7G5 SoC clks - Enable CPU clks on Qualcomm IPQ6018 SoCs - Enable CPU clks on Qualcomm MSM8996 SoCs - GPU clk support for Qualcomm SM8150 and SM8250 SoCs - Audio clks on Qualcomm SC7180 SoCs - Microchip Sparx5 DPLL clk - Add support for the new Renesas RZ/G2H (R8A774E1) SoC Updates: - Make defines for bcm63xx-gate clks to use in DT - Support BCM2711 SoC firmware clks - Add HDMI clks for BCM2711 SoCs - Add RTC related clks on Ingenic SoCs - Support USB PHY clks on Ingenic SoCs - Support gate clks on BCM6318 SoCs - RMU and DMAC/GPIO clock support for Actions Semi S500 SoCs - Use poll_timeout functions in Rockchip clk driver - Support Rockchip rk3288w SoC variant - Mark mac_lbtest critical on Rockchip rk3188 - Add CAAM clock support for i.MX vf610 driver - Add MU root clock support for i.MX imx8mp driver - Amlogic g12: add neural network accelerator clock sources - Amlogic meson8: remove critical flag for main PLL divider - Amlogic meson8: add video decoder clock gates - Convert one more Renesas DT binding to json-schema - Enhance critical clock handling on Renesas platforms to only consider clocks that were enabled at boot time -----BEGIN PGP SIGNATURE----- iQJFBAABCAAvFiEE9L57QeeUxqYDyoaDrQKIl8bklSUFAl8tspERHHNib3lkQGtl cm5lbC5vcmcACgkQrQKIl8bklSX0og//TXp134IBXVZ2Z5Wca4J41itv7tPGJFsX EslQ/eMm6xhGEqqrA6BVsQ228JF9rUmg1fbvdl82UPK7Zyp9P2fo6CMC65ngDTky B1rLZOaKitER9JdL9DmmnIR772pI//rAMdIeVC/Jn5RR7OpP4lgY6+qvK0pJjVFl 8aK3uHY+UWVFtqZxuJEAAyZBq1+bREqmVwNC1my6kmMIf0j0KwcGhrZgASWWtjQK 4TRmroehLC4FBqnJ78Y3E6UAOBlz6C7XnP38qJge2672Ef7QhXZU7AGrGiTtxc4h 5fB6MNMF+5QGel54qR1eH+JxaEoKsAjLaX1VBr7hAHrGIQ26dBFHFPsPvWDA+VVR 4bwXJKz2objAWyqlMVM/cVV3q6uDixuScdrw2aAiojmV7ZvdZXflacdmZuS5v7e4 sh86llN+lF0YrViYz33z+up0risCAi089xVo7Z99VgyLe2DR8TE+4/d6DQTFRNxl m66m6mlB9pPPgIV028SAf/zmzyoVWEarwdEAQPjJC6KVRbnR9mFlhSiTQMmCsSvU zHRxVcInc+8qIJY6VJ552UFu/JAan/AFl5knb+kW21a7hM8p81H9HuSnS4aHDDq4 yETPU3XSMYz8ARHX4lKo1UIB6+k9iF2CWdCP+gXHNP+QYSAsRBIJsonjul9lLUCi 8i6mUGkS0OU= =QLRg -----END PGP SIGNATURE----- Merge tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux Pull clk updates from Stephen Boyd: "It looks like a smaller batch of clk updates this time around. In the core framework we just have some minor tweaks and a debugfs feature, so not much to see there. The driver updates are fairly well split between AT91 and Qualcomm clk support. Adding those two drivers together equals about 50% of the diffstat. Otherwise, the big amount of work this time was on supporting Broadcom's Raspberry Pi firmware clks. Highlights: Core: - Document clk_hw_round_rate() so it gets some more use - Remove unused __clk_get_flags() - Add a prepare/enable debugfs feature similar to rate setting New Drivers: - Add support for SAMA7G5 SoC clks - Enable CPU clks on Qualcomm IPQ6018 SoCs - Enable CPU clks on Qualcomm MSM8996 SoCs - GPU clk support for Qualcomm SM8150 and SM8250 SoCs - Audio clks on Qualcomm SC7180 SoCs - Microchip Sparx5 DPLL clk - Add support for the new Renesas RZ/G2H (R8A774E1) SoC Updates: - Make defines for bcm63xx-gate clks to use in DT - Support BCM2711 SoC firmware clks - Add HDMI clks for BCM2711 SoCs - Add RTC related clks on Ingenic SoCs - Support USB PHY clks on Ingenic SoCs - Support gate clks on BCM6318 SoCs - RMU and DMAC/GPIO clock support for Actions Semi S500 SoCs - Use poll_timeout functions in Rockchip clk driver - Support Rockchip rk3288w SoC variant - Mark mac_lbtest critical on Rockchip rk3188 - Add CAAM clock support for i.MX vf610 driver - Add MU root clock support for i.MX imx8mp driver - Amlogic g12: add neural network accelerator clock sources - Amlogic meson8: remove critical flag for main PLL divider - Amlogic meson8: add video decoder clock gates - Convert one more Renesas DT binding to json-schema - Enhance critical clock handling on Renesas platforms to only consider clocks that were enabled at boot time" * tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux: (79 commits) clk: qcom: gcc: Make disp gpll0 branch aon for sc7180/sdm845 ipq806x: gcc: add support for child probe clk: qcom: msm8996: Make symbol 'cpu_msm8996_clks' static clk: qcom: ipq8074: Add correct index for PCIe clocks clk: <linux/clk-provider.h>: drop a duplicated word clk: renesas: cpg-mssr: Add r8a774e1 support dt-bindings: clock: renesas,cpg-mssr: Document r8a774e1 clk: Drop duplicate selection in Kconfig clk: qcom: smd: Add support for MSM8992/4 rpm clocks clk: qcom: ipq8074: Add missing clocks for pcie dt-bindings: clock: qcom: ipq8074: Add missing bindings for PCIe Replace HTTP links with HTTPS ones: Common CLK framework clk: qcom: Add CPU clock driver for msm8996 dt-bindings: clk: qcom: Add bindings for CPU clock for msm8996 soc: qcom: Separate kryo l2 accessors from PMU driver clk: meson: meson8b: add the vclk2_en gate clock clk: meson: meson8b: add the vclk_en gate clock clk: qcom: Fix return value check in apss_ipq6018_probe() clk: bcm: dvp: Add missing module informations clk: meson: meson8b: Drop CLK_IS_CRITICAL from fclk_div2 ...
This commit is contained in:
commit
30185b69a2
@ -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>;
|
||||
};
|
@ -0,0 +1,59 @@
|
||||
# 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>
|
||||
|
||||
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>;
|
||||
};
|
||||
};
|
||||
...
|
@ -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>;
|
||||
};
|
||||
|
||||
...
|
@ -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"
|
||||
|
@ -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==
|
||||
|
||||
|
@ -31,6 +31,29 @@ Required properties:
|
||||
- 5p49v5933 and
|
||||
- 5p49v5935: (optional) property not present or "clkin".
|
||||
|
||||
For all output ports, a corresponding, optional child node named OUT1,
|
||||
OUT2, etc. can represent a each output, and the node can be used to
|
||||
specify the following:
|
||||
|
||||
- itd,mode: can be one of the following:
|
||||
- VC5_LVPECL
|
||||
- VC5_CMOS
|
||||
- VC5_HCSL33
|
||||
- VC5_LVDS
|
||||
- VC5_CMOS2
|
||||
- VC5_CMOSD
|
||||
- VC5_HCSL25
|
||||
|
||||
- idt,voltage-microvolts: can be one of the following
|
||||
- 1800000
|
||||
- 2500000
|
||||
- 3300000
|
||||
- idt,slew-percent: Percent of normal, can be one of
|
||||
- 80
|
||||
- 85
|
||||
- 90
|
||||
- 100
|
||||
|
||||
==Mapping between clock specifier and physical pins==
|
||||
|
||||
When referencing the provided clock in the DT using phandle and
|
||||
@ -81,6 +104,16 @@ i2c-master-node {
|
||||
/* Connect XIN input to 25MHz reference */
|
||||
clocks = <&ref25m>;
|
||||
clock-names = "xin";
|
||||
|
||||
OUT1 {
|
||||
itd,mode = <VC5_CMOS>;
|
||||
idt,voltage-microvolts = <1800000>;
|
||||
idt,slew-percent = <80>;
|
||||
};
|
||||
OUT2 {
|
||||
...
|
||||
};
|
||||
...
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -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";
|
||||
};
|
||||
|
@ -0,0 +1,56 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/clock/qcom,kryocc.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:
|
||||
# Example for msm8996
|
||||
- |
|
||||
kryocc: clock-controller@6400000 {
|
||||
compatible = "qcom,msm8996-apcc";
|
||||
reg = <0x6400000 0x90000>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
...
|
@ -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
|
||||
|
||||
|
241
Documentation/devicetree/bindings/clock/renesas,cpg-clocks.yaml
Normal file
241
Documentation/devicetree/bindings/clock/renesas,cpg-clocks.yaml
Normal file
@ -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>;
|
||||
};
|
@ -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
|
||||
|
@ -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";
|
||||
};
|
@ -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>;
|
||||
};
|
@ -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>;
|
||||
};
|
@ -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>;
|
||||
};
|
@ -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>;
|
||||
};
|
@ -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";
|
||||
};
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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",
|
||||
|
@ -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".
|
||||
|
@ -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.
|
||||
|
||||
|
@ -121,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.
|
||||
@ -163,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.
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
124
drivers/clk/bcm/clk-bcm2711-dvp.c
Normal file
124
drivers/clk/bcm/clk-bcm2711-dvp.c
Normal file
@ -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");
|
@ -421,6 +421,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;
|
||||
|
||||
@ -1310,7 +1311,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 +1685,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.
|
||||
|
@ -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, },
|
||||
|
@ -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;
|
||||
dev_err(rpi->dev, "Failed to get clock %d max freq: %d\n",
|
||||
id, ret);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
if (!min_rate || !max_rate) {
|
||||
dev_err(rpi->dev, "Unexpected frequency range: min %u, max %u\n",
|
||||
min_rate, max_rate);
|
||||
return -EINVAL;
|
||||
ret = devm_clk_hw_register(rpi->dev, &data->hw);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
clk_hw_set_rate_range(&data->hw, min_rate, max_rate);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
dev_info(rpi->dev, "CPU frequency range: min %u, max %u\n",
|
||||
min_rate, max_rate);
|
||||
|
||||
rpi->min_rate = min_rate * RPI_FIRMWARE_PLLB_ARM_DIV_RATE;
|
||||
rpi->max_rate = max_rate * RPI_FIRMWARE_PLLB_ARM_DIV_RATE;
|
||||
|
||||
rpi->pllb.init = &init;
|
||||
|
||||
return devm_clk_hw_register(rpi->dev, &rpi->pllb);
|
||||
return &data->hw;
|
||||
}
|
||||
|
||||
static int raspberrypi_register_pllb_arm(struct raspberrypi_clk *rpi)
|
||||
{
|
||||
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 {
|
||||
u32 parent;
|
||||
u32 id;
|
||||
};
|
||||
|
||||
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);
|
||||
static int raspberrypi_discover_clocks(struct raspberrypi_clk *rpi,
|
||||
struct clk_hw_onecell_data *data)
|
||||
{
|
||||
struct rpi_firmware_get_clocks_response *clks;
|
||||
int ret;
|
||||
|
||||
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);
|
||||
return 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_register_pllb_arm(rpi);
|
||||
ret = raspberrypi_discover_clocks(rpi, clk_data);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
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,
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
@ -143,6 +167,8 @@ struct vc5_hw_data {
|
||||
u32 div_int;
|
||||
u32 div_frc;
|
||||
unsigned int num;
|
||||
unsigned int clk_output_cfg0;
|
||||
unsigned int clk_output_cfg0_mask;
|
||||
};
|
||||
|
||||
struct vc5_driver_data {
|
||||
@ -161,30 +187,6 @@ struct vc5_driver_data {
|
||||
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",
|
||||
};
|
||||
|
||||
/*
|
||||
* VersaClock5 i2c regmap
|
||||
*/
|
||||
@ -591,6 +593,17 @@ 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;
|
||||
}
|
||||
|
||||
@ -690,10 +703,123 @@ static int vc5_map_index_to_output(const enum vc5_model model,
|
||||
}
|
||||
}
|
||||
|
||||
static int vc5_update_mode(struct device_node *np_output,
|
||||
struct vc5_hw_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_hw_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_hw_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_hw_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);
|
||||
np_output = of_get_child_by_name(client->dev.of_node, child_name);
|
||||
kfree(child_name);
|
||||
if (!np_output)
|
||||
goto output_done;
|
||||
|
||||
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);
|
||||
|
||||
output_done:
|
||||
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;
|
||||
@ -742,7 +868,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,12 +876,13 @@ 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);
|
||||
kfree(init.name); /* clock framework made a copy of the name */
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "unable to register %s\n", init.name);
|
||||
goto err_clk;
|
||||
@ -764,13 +891,16 @@ static int vc5_probe(struct i2c_client *client,
|
||||
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);
|
||||
kfree(init.name); /* clock framework made a copy of the name */
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "unable to register %s\n",
|
||||
init.name);
|
||||
@ -780,16 +910,18 @@ static int vc5_probe(struct i2c_client *client,
|
||||
|
||||
/* 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);
|
||||
kfree(init.name); /* clock framework made a copy of the name */
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "unable to register %s\n", init.name);
|
||||
goto err_clk;
|
||||
@ -797,15 +929,17 @@ static int vc5_probe(struct i2c_client *client,
|
||||
|
||||
/* 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);
|
||||
kfree(init.name); /* clock framework made a copy of the name */
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "unable to register %s\n", init.name);
|
||||
goto err_clk;
|
||||
@ -815,15 +949,18 @@ static int vc5_probe(struct i2c_client *client,
|
||||
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);
|
||||
kfree(init.name); /* clock framework made a copy of the name */
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "unable to register %s\n",
|
||||
init.name);
|
||||
@ -833,32 +970,36 @@ static int vc5_probe(struct i2c_client *client,
|
||||
|
||||
/* 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);
|
||||
kfree(init.name); /* clock framework made a copy of the name */
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "unable to register %s\n",
|
||||
init.name);
|
||||
dev_err(&client->dev, "unable to register %s\n", init.name);
|
||||
goto err_clk;
|
||||
}
|
||||
|
||||
/* 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 +1007,18 @@ 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);
|
||||
ret = devm_clk_hw_register(&client->dev, &vc5->clk_out[n].hw);
|
||||
kfree(init.name); /* clock framework made a copy of the name */
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "unable to register %s\n",
|
||||
init.name);
|
||||
goto err_clk;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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[] = {
|
||||
|
@ -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>
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
95
drivers/clk/qcom/apss-ipq-pll.c
Normal file
95
drivers/clk/qcom/apss-ipq-pll.c
Normal file
@ -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");
|
106
drivers/clk/qcom/apss-ipq6018.c
Normal file
106
drivers/clk/qcom/apss-ipq6018.c
Normal file
@ -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");
|
@ -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
|
||||
|
538
drivers/clk/qcom/clk-cpu-8996.c
Normal file
538
drivers/clk/qcom/clk-cpu-8996.c
Normal file
@ -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");
|
@ -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);
|
||||
|
@ -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 = {
|
||||
|
@ -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 },
|
||||
|
@ -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,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -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,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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) */
|
||||
};
|
||||
|
||||
|
@ -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) */
|
||||
};
|
||||
|
||||
|
@ -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) */
|
||||
};
|
||||
|
||||
|
349
drivers/clk/renesas/r8a774e1-cpg-mssr.c
Normal file
349
drivers/clk/renesas/r8a774e1-cpg-mssr.c
Normal file
@ -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,
|
||||
};
|
@ -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
|
||||
*/
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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) */
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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) */
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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",
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -211,6 +211,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);
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
57
drivers/soc/qcom/kryo-l2-accessors.c
Normal file
57
drivers/soc/qcom/kryo-l2-accessors.c
Normal file
@ -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);
|
13
include/dt-bindings/clk/versaclock.h
Normal file
13
include/dt-bindings/clk/versaclock.h
Normal file
@ -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
|
@ -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 */
|
||||
|
24
include/dt-bindings/clock/bcm3368-clock.h
Normal file
24
include/dt-bindings/clock/bcm3368-clock.h
Normal file
@ -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 */
|
42
include/dt-bindings/clock/bcm6318-clock.h
Normal file
42
include/dt-bindings/clock/bcm6318-clock.h
Normal file
@ -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 */
|
30
include/dt-bindings/clock/bcm63268-clock.h
Normal file
30
include/dt-bindings/clock/bcm63268-clock.h
Normal file
@ -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 */
|
19
include/dt-bindings/clock/bcm6328-clock.h
Normal file
19
include/dt-bindings/clock/bcm6328-clock.h
Normal file
@ -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 */
|
18
include/dt-bindings/clock/bcm6358-clock.h
Normal file
18
include/dt-bindings/clock/bcm6358-clock.h
Normal file
@ -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 */
|
26
include/dt-bindings/clock/bcm6362-clock.h
Normal file
26
include/dt-bindings/clock/bcm6362-clock.h
Normal file
@ -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 */
|
24
include/dt-bindings/clock/bcm6368-clock.h
Normal file
24
include/dt-bindings/clock/bcm6368-clock.h
Normal file
@ -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 */
|
@ -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 */
|
||||
|
12
include/dt-bindings/clock/qcom,apss-ipq.h
Normal file
12
include/dt-bindings/clock/qcom,apss-ipq.h
Normal file
@ -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
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
12
include/soc/qcom/kryo-l2-accessors.h
Normal file
12
include/soc/qcom/kryo-l2-accessors.h
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user