Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

Pull more clk updates from Stephen Boyd:
"Here's some more updates that missed the last pull request because I
happened to tag the tree at an earlier point in the history of
clk-next. I must have fat fingered it and checked out an older version
of clk-next on this second computer I'm using.

This time it actually includes more code for Qualcomm SoCs, the AT91
major updates, and some Rockchip SoC clk driver updates as well. I've
corrected this flow so this shouldn't happen again"

* tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux: (83 commits)
clk: bcm2835: Do not use prediv with bcm2711's PLLs
clk: drop unused function __clk_get_flags
clk: hsdk: Fix bad dependency on IOMEM
dt-bindings: clock: Fix YAML schemas for LPASS clocks on SC7180
clk: mmp: avoid missing prototype warning
clk: sparx5: Add Sparx5 SoC DPLL clock driver
dt-bindings: clock: sparx5: Add bindings include file
clk: qoriq: add LS1021A core pll mux options
clk: clk-atlas6: fix return value check in atlas6_clk_init()
clk: tegra: pll: Improve PLLM enable-state detection
clk: X1000: Add support for calculat REFCLK of USB PHY.
clk: JZ4780: Reformat the code to align it.
clk: JZ4780: Add functions for enable and disable USB PHY.
clk: Ingenic: Add RTC related clocks for Ingenic SoCs.
dt-bindings: clock: Add tabs to align code.
dt-bindings: clock: Add RTC related clocks for Ingenic SoCs.
clk: davinci: Use fallthrough pseudo-keyword
clk: imx: Use fallthrough pseudo-keyword
clk: qcom: gcc-sdm660: Fix up gcc_mss_mnoc_bimc_axi_clk
clk: qcom: gcc-sdm660: Add missing modem reset
...

+4788 -881
+9
Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-firmware.yaml
··· 10 10 - Eric Anholt <eric@anholt.net> 11 11 - Stefan Wahren <wahrenst@gmx.net> 12 12 13 + select: 14 + properties: 15 + compatible: 16 + contains: 17 + const: raspberrypi,bcm2835-firmware 18 + 19 + required: 20 + - compatible 21 + 13 22 properties: 14 23 compatible: 15 24 items:
-125
Documentation/devicetree/bindings/clock/idt,versaclock5.txt
··· 1 - Binding for IDT VersaClock 5,6 programmable i2c clock generators. 2 - 3 - The IDT VersaClock 5 and VersaClock 6 are programmable i2c clock 4 - generators providing from 3 to 12 output clocks. 5 - 6 - ==I2C device node== 7 - 8 - Required properties: 9 - - compatible: shall be one of 10 - "idt,5p49v5923" 11 - "idt,5p49v5925" 12 - "idt,5p49v5933" 13 - "idt,5p49v5935" 14 - "idt,5p49v6901" 15 - "idt,5p49v6965" 16 - - reg: i2c device address, shall be 0x68 or 0x6a. 17 - - #clock-cells: from common clock binding; shall be set to 1. 18 - - clocks: from common clock binding; list of parent clock handles, 19 - - 5p49v5923 and 20 - 5p49v5925 and 21 - 5p49v6901: (required) either or both of XTAL or CLKIN 22 - reference clock. 23 - - 5p49v5933 and 24 - - 5p49v5935: (optional) property not present (internal 25 - Xtal used) or CLKIN reference 26 - clock. 27 - - clock-names: from common clock binding; clock input names, can be 28 - - 5p49v5923 and 29 - 5p49v5925 and 30 - 5p49v6901: (required) either or both of "xin", "clkin". 31 - - 5p49v5933 and 32 - - 5p49v5935: (optional) property not present or "clkin". 33 - 34 - For all output ports, a corresponding, optional child node named OUT1, 35 - OUT2, etc. can represent a each output, and the node can be used to 36 - specify the following: 37 - 38 - - itd,mode: can be one of the following: 39 - - VC5_LVPECL 40 - - VC5_CMOS 41 - - VC5_HCSL33 42 - - VC5_LVDS 43 - - VC5_CMOS2 44 - - VC5_CMOSD 45 - - VC5_HCSL25 46 - 47 - - idt,voltage-microvolts: can be one of the following 48 - - 1800000 49 - - 2500000 50 - - 3300000 51 - - idt,slew-percent: Percent of normal, can be one of 52 - - 80 53 - - 85 54 - - 90 55 - - 100 56 - 57 - ==Mapping between clock specifier and physical pins== 58 - 59 - When referencing the provided clock in the DT using phandle and 60 - clock specifier, the following mapping applies: 61 - 62 - 5P49V5923: 63 - 0 -- OUT0_SEL_I2CB 64 - 1 -- OUT1 65 - 2 -- OUT2 66 - 67 - 5P49V5933: 68 - 0 -- OUT0_SEL_I2CB 69 - 1 -- OUT1 70 - 2 -- OUT4 71 - 72 - 5P49V5925 and 73 - 5P49V5935: 74 - 0 -- OUT0_SEL_I2CB 75 - 1 -- OUT1 76 - 2 -- OUT2 77 - 3 -- OUT3 78 - 4 -- OUT4 79 - 80 - 5P49V6901: 81 - 0 -- OUT0_SEL_I2CB 82 - 1 -- OUT1 83 - 2 -- OUT2 84 - 3 -- OUT3 85 - 4 -- OUT4 86 - 87 - ==Example== 88 - 89 - /* 25MHz reference crystal */ 90 - ref25: ref25m { 91 - compatible = "fixed-clock"; 92 - #clock-cells = <0>; 93 - clock-frequency = <25000000>; 94 - }; 95 - 96 - i2c-master-node { 97 - 98 - /* IDT 5P49V5923 i2c clock generator */ 99 - vc5: clock-generator@6a { 100 - compatible = "idt,5p49v5923"; 101 - reg = <0x6a>; 102 - #clock-cells = <1>; 103 - 104 - /* Connect XIN input to 25MHz reference */ 105 - clocks = <&ref25m>; 106 - clock-names = "xin"; 107 - 108 - OUT1 { 109 - itd,mode = <VC5_CMOS>; 110 - idt,voltage-microvolts = <1800000>; 111 - idt,slew-percent = <80>; 112 - }; 113 - OUT2 { 114 - ... 115 - }; 116 - ... 117 - }; 118 - }; 119 - 120 - /* Consumer referencing the 5P49V5923 pin OUT1 */ 121 - consumer { 122 - ... 123 - clocks = <&vc5 1>; 124 - ... 125 - }
+154
Documentation/devicetree/bindings/clock/idt,versaclock5.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/clock/idt,versaclock5.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Binding for IDT VersaClock 5 and 6 programmable I2C clock generators 8 + 9 + description: | 10 + The IDT VersaClock 5 and VersaClock 6 are programmable I2C 11 + clock generators providing from 3 to 12 output clocks. 12 + 13 + When referencing the provided clock in the DT using phandle and clock 14 + specifier, the following mapping applies: 15 + 16 + - 5P49V5923: 17 + 0 -- OUT0_SEL_I2CB 18 + 1 -- OUT1 19 + 2 -- OUT2 20 + 21 + - 5P49V5933: 22 + 0 -- OUT0_SEL_I2CB 23 + 1 -- OUT1 24 + 2 -- OUT4 25 + 26 + - other parts: 27 + 0 -- OUT0_SEL_I2CB 28 + 1 -- OUT1 29 + 2 -- OUT2 30 + 3 -- OUT3 31 + 4 -- OUT4 32 + 33 + maintainers: 34 + - Luca Ceresoli <luca@lucaceresoli.net> 35 + 36 + properties: 37 + compatible: 38 + enum: 39 + - idt,5p49v5923 40 + - idt,5p49v5925 41 + - idt,5p49v5933 42 + - idt,5p49v5935 43 + - idt,5p49v6901 44 + - idt,5p49v6965 45 + 46 + reg: 47 + description: I2C device address 48 + enum: [ 0x68, 0x6a ] 49 + 50 + '#clock-cells': 51 + const: 1 52 + 53 + patternProperties: 54 + "^OUT[1-4]$": 55 + type: object 56 + description: 57 + Description of one of the outputs (OUT1..OUT4). See "Clock1 Output 58 + Configuration" in the Versaclock 5/6/6E Family Register Description 59 + and Programming Guide. 60 + properties: 61 + idt,mode: 62 + description: 63 + The output drive mode. Values defined in dt-bindings/clk/versaclock.h 64 + $ref: /schemas/types.yaml#/definitions/uint32 65 + minimum: 0 66 + maximum: 6 67 + idt,voltage-microvolt: 68 + description: The output drive voltage. 69 + enum: [ 1800000, 2500000, 3300000 ] 70 + idt,slew-percent: 71 + description: The Slew rate control for CMOS single-ended. 72 + $ref: /schemas/types.yaml#/definitions/uint32 73 + enum: [ 80, 85, 90, 100 ] 74 + 75 + required: 76 + - compatible 77 + - reg 78 + - '#clock-cells' 79 + 80 + allOf: 81 + - if: 82 + properties: 83 + compatible: 84 + enum: 85 + - idt,5p49v5933 86 + - idt,5p49v5935 87 + then: 88 + # Devices with builtin crystal + optional external input 89 + properties: 90 + clock-names: 91 + const: clkin 92 + clocks: 93 + maxItems: 1 94 + else: 95 + # Devices without builtin crystal 96 + properties: 97 + clock-names: 98 + minItems: 1 99 + maxItems: 2 100 + items: 101 + enum: [ xin, clkin ] 102 + clocks: 103 + minItems: 1 104 + maxItems: 2 105 + required: 106 + - clock-names 107 + - clocks 108 + 109 + examples: 110 + - | 111 + #include <dt-bindings/clk/versaclock.h> 112 + 113 + /* 25MHz reference crystal */ 114 + ref25: ref25m { 115 + compatible = "fixed-clock"; 116 + #clock-cells = <0>; 117 + clock-frequency = <25000000>; 118 + }; 119 + 120 + i2c@0 { 121 + reg = <0x0 0x100>; 122 + #address-cells = <1>; 123 + #size-cells = <0>; 124 + 125 + /* IDT 5P49V5923 I2C clock generator */ 126 + vc5: clock-generator@6a { 127 + compatible = "idt,5p49v5923"; 128 + reg = <0x6a>; 129 + #clock-cells = <1>; 130 + 131 + /* Connect XIN input to 25MHz reference */ 132 + clocks = <&ref25m>; 133 + clock-names = "xin"; 134 + 135 + OUT1 { 136 + idt,drive-mode = <VC5_CMOSD>; 137 + idt,voltage-microvolts = <1800000>; 138 + idt,slew-percent = <80>; 139 + }; 140 + 141 + OUT4 { 142 + idt,drive-mode = <VC5_LVDS>; 143 + }; 144 + }; 145 + }; 146 + 147 + /* Consumer referencing the 5P49V5923 pin OUT1 */ 148 + consumer { 149 + /* ... */ 150 + clocks = <&vc5 1>; 151 + /* ... */ 152 + }; 153 + 154 + ...
+2 -4
Documentation/devicetree/bindings/clock/qcom,msm8996-apcc.yaml
··· 1 1 # SPDX-License-Identifier: GPL-2.0-only 2 2 %YAML 1.2 3 3 --- 4 - $id: http://devicetree.org/schemas/clock/qcom,kryocc.yaml# 4 + $id: http://devicetree.org/schemas/clock/qcom,msm8996-apcc.yaml# 5 5 $schema: http://devicetree.org/meta-schemas/core.yaml# 6 6 7 7 title: Qualcomm clock controller for MSM8996 CPUs ··· 46 46 additionalProperties: false 47 47 48 48 examples: 49 - # Example for msm8996 50 49 - | 51 50 kryocc: clock-controller@6400000 { 52 51 compatible = "qcom,msm8996-apcc"; 53 52 reg = <0x6400000 0x90000>; 54 53 #clock-cells = <1>; 55 - }; 56 - ... 54 + };
-74
Documentation/devicetree/bindings/clock/qcom,sc7180-gpucc.yaml
··· 1 - # SPDX-License-Identifier: GPL-2.0-only 2 - %YAML 1.2 3 - --- 4 - $id: http://devicetree.org/schemas/clock/qcom,sc7180-gpucc.yaml# 5 - $schema: http://devicetree.org/meta-schemas/core.yaml# 6 - 7 - title: Qualcomm Graphics Clock & Reset Controller Binding for SC7180 8 - 9 - maintainers: 10 - - Taniya Das <tdas@codeaurora.org> 11 - 12 - description: | 13 - Qualcomm graphics clock control module which supports the clocks, resets and 14 - power domains on SC7180. 15 - 16 - See also dt-bindings/clock/qcom,gpucc-sc7180.h. 17 - 18 - properties: 19 - compatible: 20 - const: qcom,sc7180-gpucc 21 - 22 - clocks: 23 - items: 24 - - description: Board XO source 25 - - description: GPLL0 main branch source 26 - - description: GPLL0 div branch source 27 - 28 - clock-names: 29 - items: 30 - - const: bi_tcxo 31 - - const: gcc_gpu_gpll0_clk_src 32 - - const: gcc_gpu_gpll0_div_clk_src 33 - 34 - '#clock-cells': 35 - const: 1 36 - 37 - '#reset-cells': 38 - const: 1 39 - 40 - '#power-domain-cells': 41 - const: 1 42 - 43 - reg: 44 - maxItems: 1 45 - 46 - required: 47 - - compatible 48 - - reg 49 - - clocks 50 - - clock-names 51 - - '#clock-cells' 52 - - '#reset-cells' 53 - - '#power-domain-cells' 54 - 55 - additionalProperties: false 56 - 57 - examples: 58 - - | 59 - #include <dt-bindings/clock/qcom,gcc-sc7180.h> 60 - #include <dt-bindings/clock/qcom,rpmh.h> 61 - clock-controller@5090000 { 62 - compatible = "qcom,sc7180-gpucc"; 63 - reg = <0x05090000 0x9000>; 64 - clocks = <&rpmhcc RPMH_CXO_CLK>, 65 - <&gcc GCC_GPU_GPLL0_CLK_SRC>, 66 - <&gcc GCC_GPU_GPLL0_DIV_CLK_SRC>; 67 - clock-names = "bi_tcxo", 68 - "gcc_gpu_gpll0_clk_src", 69 - "gcc_gpu_gpll0_div_clk_src"; 70 - #clock-cells = <1>; 71 - #reset-cells = <1>; 72 - #power-domain-cells = <1>; 73 - }; 74 - ...
+108
Documentation/devicetree/bindings/clock/qcom,sc7180-lpasscorecc.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/clock/qcom,sc7180-lpasscorecc.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Qualcomm LPASS Core Clock Controller Binding for SC7180 8 + 9 + maintainers: 10 + - Taniya Das <tdas@codeaurora.org> 11 + 12 + description: | 13 + Qualcomm LPASS core clock control module which supports the clocks and 14 + power domains on SC7180. 15 + 16 + See also: 17 + - dt-bindings/clock/qcom,lpasscorecc-sc7180.h 18 + 19 + properties: 20 + compatible: 21 + enum: 22 + - qcom,sc7180-lpasshm 23 + - qcom,sc7180-lpasscorecc 24 + 25 + clocks: 26 + items: 27 + - description: gcc_lpass_sway clock from GCC 28 + - description: Board XO source 29 + 30 + clock-names: 31 + items: 32 + - const: iface 33 + - const: bi_tcxo 34 + 35 + power-domains: 36 + maxItems: 1 37 + 38 + '#clock-cells': 39 + const: 1 40 + 41 + '#power-domain-cells': 42 + const: 1 43 + 44 + reg: 45 + minItems: 1 46 + items: 47 + - description: lpass core cc register 48 + - description: lpass audio cc register 49 + 50 + reg-names: 51 + items: 52 + - const: lpass_core_cc 53 + - const: lpass_audio_cc 54 + 55 + if: 56 + properties: 57 + compatible: 58 + contains: 59 + const: qcom,sc7180-lpasshm 60 + then: 61 + properties: 62 + reg: 63 + maxItems: 1 64 + 65 + else: 66 + properties: 67 + reg: 68 + minItems: 2 69 + 70 + required: 71 + - compatible 72 + - reg 73 + - clocks 74 + - clock-names 75 + - '#clock-cells' 76 + - '#power-domain-cells' 77 + 78 + additionalProperties: false 79 + 80 + examples: 81 + - | 82 + #include <dt-bindings/clock/qcom,rpmh.h> 83 + #include <dt-bindings/clock/qcom,gcc-sc7180.h> 84 + #include <dt-bindings/clock/qcom,lpasscorecc-sc7180.h> 85 + clock-controller@63000000 { 86 + compatible = "qcom,sc7180-lpasshm"; 87 + reg = <0x63000000 0x28>; 88 + clocks = <&gcc GCC_LPASS_CFG_NOC_SWAY_CLK>, <&rpmhcc RPMH_CXO_CLK>; 89 + clock-names = "iface", "bi_tcxo"; 90 + #clock-cells = <1>; 91 + #power-domain-cells = <1>; 92 + }; 93 + 94 + - | 95 + #include <dt-bindings/clock/qcom,rpmh.h> 96 + #include <dt-bindings/clock/qcom,gcc-sc7180.h> 97 + #include <dt-bindings/clock/qcom,lpasscorecc-sc7180.h> 98 + clock-controller@62d00000 { 99 + compatible = "qcom,sc7180-lpasscorecc"; 100 + reg = <0x62d00000 0x50000>, <0x62780000 0x30000>; 101 + reg-names = "lpass_core_cc", "lpass_audio_cc"; 102 + clocks = <&gcc GCC_LPASS_CFG_NOC_SWAY_CLK>, <&rpmhcc RPMH_CXO_CLK>; 103 + clock-names = "iface", "bi_tcxo"; 104 + power-domains = <&lpass_hm LPASS_CORE_HM_GDSCR>; 105 + #clock-cells = <1>; 106 + #power-domain-cells = <1>; 107 + }; 108 + ...
+13 -5
Documentation/devicetree/bindings/clock/qcom,sdm845-gpucc.yaml Documentation/devicetree/bindings/clock/qcom,gpucc.yaml
··· 1 1 # SPDX-License-Identifier: GPL-2.0-only 2 2 %YAML 1.2 3 3 --- 4 - $id: http://devicetree.org/schemas/clock/qcom,sdm845-gpucc.yaml# 4 + $id: http://devicetree.org/schemas/clock/qcom,gpucc.yaml# 5 5 $schema: http://devicetree.org/meta-schemas/core.yaml# 6 6 7 - title: Qualcomm Graphics Clock & Reset Controller Binding for SDM845 7 + title: Qualcomm Graphics Clock & Reset Controller Binding 8 8 9 9 maintainers: 10 10 - Taniya Das <tdas@codeaurora.org> 11 11 12 12 description: | 13 13 Qualcomm graphics clock control module which supports the clocks, resets and 14 - power domains on SDM845. 14 + power domains on SDM845/SC7180/SM8150/SM8250. 15 15 16 - See also dt-bindings/clock/qcom,gpucc-sdm845.h. 16 + See also: 17 + dt-bindings/clock/qcom,gpucc-sdm845.h 18 + dt-bindings/clock/qcom,gpucc-sc7180.h 19 + dt-bindings/clock/qcom,gpucc-sm8150.h 20 + dt-bindings/clock/qcom,gpucc-sm8250.h 17 21 18 22 properties: 19 23 compatible: 20 - const: qcom,sdm845-gpucc 24 + enum: 25 + - qcom,sdm845-gpucc 26 + - qcom,sc7180-gpucc 27 + - qcom,sm8150-gpucc 28 + - qcom,sm8250-gpucc 21 29 22 30 clocks: 23 31 items:
+7 -1
Documentation/devicetree/bindings/clock/rockchip,rk3288-cru.txt
··· 4 4 controllers within the SoC and also implements a reset controller for SoC 5 5 peripherals. 6 6 7 + A revision of this SoC is available: rk3288w. The clock tree is a bit 8 + different so another dt-compatible is available. Noticed that it is only 9 + setting the difference but there is no automatic revision detection. This 10 + should be performed by bootloaders. 11 + 7 12 Required Properties: 8 13 9 - - compatible: should be "rockchip,rk3288-cru" 14 + - compatible: should be "rockchip,rk3288-cru" or "rockchip,rk3288w-cru" in 15 + case of this revision of Rockchip rk3288. 10 16 - reg: physical base address of the controller and length of memory mapped 11 17 region. 12 18 - #clock-cells: should be 1.
+3 -1
MAINTAINERS
··· 1540 1540 F: drivers/pinctrl/actions/* 1541 1541 F: drivers/soc/actions/ 1542 1542 F: include/dt-bindings/power/owl-* 1543 + F: include/dt-bindings/reset/actions,* 1543 1544 F: include/linux/soc/actions/ 1544 1545 N: owl 1545 1546 ··· 8410 8409 F: drivers/input/misc/ideapad_slidebar.c 8411 8410 8412 8411 IDT VersaClock 5 CLOCK DRIVER 8413 - M: Marek Vasut <marek.vasut@gmail.com> 8412 + M: Luca Ceresoli <luca@lucaceresoli.net> 8414 8413 S: Maintained 8414 + F: Documentation/devicetree/bindings/clock/idt,versaclock5.yaml 8415 8415 F: drivers/clk/clk-versaclock5.c 8416 8416 8417 8417 IEEE 802.15.4 SUBSYSTEM
+1 -1
drivers/clk/Kconfig
··· 50 50 config CLK_HSDK 51 51 bool "PLL Driver for HSDK platform" 52 52 depends on OF || COMPILE_TEST 53 - depends on IOMEM 53 + depends on HAS_IOMEM 54 54 help 55 55 This driver supports the HSDK core, system, ddr, tunnel and hdmi PLLs 56 56 control.
+1
drivers/clk/Makefile
··· 28 28 obj-$(CONFIG_ARCH_CLPS711X) += clk-clps711x.o 29 29 obj-$(CONFIG_COMMON_CLK_CS2000_CP) += clk-cs2000-cp.o 30 30 obj-$(CONFIG_ARCH_EFM32) += clk-efm32gg.o 31 + obj-$(CONFIG_ARCH_SPARX5) += clk-sparx5.o 31 32 obj-$(CONFIG_COMMON_CLK_FIXED_MMIO) += clk-fixed-mmio.o 32 33 obj-$(CONFIG_COMMON_CLK_FSL_SAI) += clk-fsl-sai.o 33 34 obj-$(CONFIG_COMMON_CLK_GEMINI) += clk-gemini.o
+88 -1
drivers/clk/actions/owl-s500.c
··· 23 23 #include "owl-gate.h" 24 24 #include "owl-mux.h" 25 25 #include "owl-pll.h" 26 + #include "owl-reset.h" 26 27 27 28 #include <dt-bindings/clock/actions,s500-cmu.h> 29 + #include <dt-bindings/reset/actions,s500-reset.h> 28 30 29 31 #define CMU_COREPLL (0x0000) 30 32 #define CMU_DEVPLL (0x0004) ··· 177 175 static OWL_MUX(ahbprediv_clk, "ahbprediv_clk", ahbprediv_clk_mux_p, CMU_BUSCLK1, 8, 3, CLK_SET_RATE_PARENT); 178 176 179 177 /* gate clocks */ 178 + static OWL_GATE(gpio_clk, "gpio_clk", "apb_clk", CMU_DEVCLKEN0, 18, 0, 0); 179 + static OWL_GATE(dmac_clk, "dmac_clk", "h_clk", CMU_DEVCLKEN0, 1, 0, 0); 180 180 static OWL_GATE(spi0_clk, "spi0_clk", "ahb_clk", CMU_DEVCLKEN1, 10, 0, CLK_IGNORE_UNUSED); 181 181 static OWL_GATE(spi1_clk, "spi1_clk", "ahb_clk", CMU_DEVCLKEN1, 11, 0, CLK_IGNORE_UNUSED); 182 182 static OWL_GATE(spi2_clk, "spi2_clk", "ahb_clk", CMU_DEVCLKEN1, 12, 0, CLK_IGNORE_UNUSED); ··· 187 183 static OWL_GATE(hdmi_clk, "hdmi_clk", "hosc", CMU_DEVCLKEN1, 3, 0, 0); 188 184 189 185 /* divider clocks */ 190 - static OWL_DIVIDER(h_clk, "h_clk", "ahbprevdiv_clk", CMU_BUSCLK1, 12, 2, NULL, 0, 0); 186 + static OWL_DIVIDER(h_clk, "h_clk", "ahbprediv_clk", CMU_BUSCLK1, 12, 2, NULL, 0, 0); 187 + static OWL_DIVIDER(apb_clk, "apb_clk", "ahb_clk", CMU_BUSCLK1, 14, 2, NULL, 0, 0); 191 188 static OWL_DIVIDER(rmii_ref_clk, "rmii_ref_clk", "ethernet_pll_clk", CMU_ETHERNETPLL, 1, 1, rmii_ref_div_table, 0, 0); 192 189 193 190 /* factor clocks */ ··· 433 428 &spdif_clk.common, 434 429 &nand_clk.common, 435 430 &ecc_clk.common, 431 + &apb_clk.common, 432 + &dmac_clk.common, 433 + &gpio_clk.common, 436 434 }; 437 435 438 436 static struct clk_hw_onecell_data s500_hw_clks = { ··· 492 484 [CLK_SPDIF] = &spdif_clk.common.hw, 493 485 [CLK_NAND] = &nand_clk.common.hw, 494 486 [CLK_ECC] = &ecc_clk.common.hw, 487 + [CLK_APB] = &apb_clk.common.hw, 488 + [CLK_DMAC] = &dmac_clk.common.hw, 489 + [CLK_GPIO] = &gpio_clk.common.hw, 495 490 }, 496 491 .num = CLK_NR_CLKS, 492 + }; 493 + 494 + static const struct owl_reset_map s500_resets[] = { 495 + [RESET_DMAC] = { CMU_DEVRST0, BIT(0) }, 496 + [RESET_NORIF] = { CMU_DEVRST0, BIT(1) }, 497 + [RESET_DDR] = { CMU_DEVRST0, BIT(2) }, 498 + [RESET_NANDC] = { CMU_DEVRST0, BIT(3) }, 499 + [RESET_SD0] = { CMU_DEVRST0, BIT(4) }, 500 + [RESET_SD1] = { CMU_DEVRST0, BIT(5) }, 501 + [RESET_PCM1] = { CMU_DEVRST0, BIT(6) }, 502 + [RESET_DE] = { CMU_DEVRST0, BIT(7) }, 503 + [RESET_LCD] = { CMU_DEVRST0, BIT(8) }, 504 + [RESET_SD2] = { CMU_DEVRST0, BIT(9) }, 505 + [RESET_DSI] = { CMU_DEVRST0, BIT(10) }, 506 + [RESET_CSI] = { CMU_DEVRST0, BIT(11) }, 507 + [RESET_BISP] = { CMU_DEVRST0, BIT(12) }, 508 + [RESET_KEY] = { CMU_DEVRST0, BIT(14) }, 509 + [RESET_GPIO] = { CMU_DEVRST0, BIT(15) }, 510 + [RESET_AUDIO] = { CMU_DEVRST0, BIT(17) }, 511 + [RESET_PCM0] = { CMU_DEVRST0, BIT(18) }, 512 + [RESET_VDE] = { CMU_DEVRST0, BIT(19) }, 513 + [RESET_VCE] = { CMU_DEVRST0, BIT(20) }, 514 + [RESET_GPU3D] = { CMU_DEVRST0, BIT(22) }, 515 + [RESET_NIC301] = { CMU_DEVRST0, BIT(23) }, 516 + [RESET_LENS] = { CMU_DEVRST0, BIT(26) }, 517 + [RESET_PERIPHRESET] = { CMU_DEVRST0, BIT(27) }, 518 + [RESET_USB2_0] = { CMU_DEVRST1, BIT(0) }, 519 + [RESET_TVOUT] = { CMU_DEVRST1, BIT(1) }, 520 + [RESET_HDMI] = { CMU_DEVRST1, BIT(2) }, 521 + [RESET_HDCP2TX] = { CMU_DEVRST1, BIT(3) }, 522 + [RESET_UART6] = { CMU_DEVRST1, BIT(4) }, 523 + [RESET_UART0] = { CMU_DEVRST1, BIT(5) }, 524 + [RESET_UART1] = { CMU_DEVRST1, BIT(6) }, 525 + [RESET_UART2] = { CMU_DEVRST1, BIT(7) }, 526 + [RESET_SPI0] = { CMU_DEVRST1, BIT(8) }, 527 + [RESET_SPI1] = { CMU_DEVRST1, BIT(9) }, 528 + [RESET_SPI2] = { CMU_DEVRST1, BIT(10) }, 529 + [RESET_SPI3] = { CMU_DEVRST1, BIT(11) }, 530 + [RESET_I2C0] = { CMU_DEVRST1, BIT(12) }, 531 + [RESET_I2C1] = { CMU_DEVRST1, BIT(13) }, 532 + [RESET_USB3] = { CMU_DEVRST1, BIT(14) }, 533 + [RESET_UART3] = { CMU_DEVRST1, BIT(15) }, 534 + [RESET_UART4] = { CMU_DEVRST1, BIT(16) }, 535 + [RESET_UART5] = { CMU_DEVRST1, BIT(17) }, 536 + [RESET_I2C2] = { CMU_DEVRST1, BIT(18) }, 537 + [RESET_I2C3] = { CMU_DEVRST1, BIT(19) }, 538 + [RESET_ETHERNET] = { CMU_DEVRST1, BIT(20) }, 539 + [RESET_CHIPID] = { CMU_DEVRST1, BIT(21) }, 540 + [RESET_USB2_1] = { CMU_DEVRST1, BIT(22) }, 541 + [RESET_WD0RESET] = { CMU_DEVRST1, BIT(24) }, 542 + [RESET_WD1RESET] = { CMU_DEVRST1, BIT(25) }, 543 + [RESET_WD2RESET] = { CMU_DEVRST1, BIT(26) }, 544 + [RESET_WD3RESET] = { CMU_DEVRST1, BIT(27) }, 545 + [RESET_DBG0RESET] = { CMU_DEVRST1, BIT(28) }, 546 + [RESET_DBG1RESET] = { CMU_DEVRST1, BIT(29) }, 547 + [RESET_DBG2RESET] = { CMU_DEVRST1, BIT(30) }, 548 + [RESET_DBG3RESET] = { CMU_DEVRST1, BIT(31) }, 497 549 }; 498 550 499 551 static struct owl_clk_desc s500_clk_desc = { ··· 561 493 .num_clks = ARRAY_SIZE(s500_clks), 562 494 563 495 .hw_clks = &s500_hw_clks, 496 + 497 + .resets = s500_resets, 498 + .num_resets = ARRAY_SIZE(s500_resets), 564 499 }; 565 500 566 501 static int s500_clk_probe(struct platform_device *pdev) 567 502 { 568 503 struct owl_clk_desc *desc; 504 + struct owl_reset *reset; 505 + int ret; 569 506 570 507 desc = &s500_clk_desc; 571 508 owl_clk_regmap_init(pdev, desc); 509 + 510 + reset = devm_kzalloc(&pdev->dev, sizeof(*reset), GFP_KERNEL); 511 + if (!reset) 512 + return -ENOMEM; 513 + 514 + reset->rcdev.of_node = pdev->dev.of_node; 515 + reset->rcdev.ops = &owl_reset_ops; 516 + reset->rcdev.nr_resets = desc->num_resets; 517 + reset->reset_map = desc->resets; 518 + reset->regmap = desc->regmap; 519 + 520 + ret = devm_reset_controller_register(&pdev->dev, &reset->rcdev); 521 + if (ret) 522 + dev_err(&pdev->dev, "Failed to register reset controller\n"); 572 523 573 524 return owl_clk_probe(&pdev->dev, desc->hw_clks); 574 525 }
+1
drivers/clk/at91/Makefile
··· 23 23 obj-$(CONFIG_SOC_SAMA5D3) += sama5d3.o 24 24 obj-$(CONFIG_SOC_SAMA5D4) += sama5d4.o 25 25 obj-$(CONFIG_SOC_SAMA5D2) += sama5d2.o 26 + obj-$(CONFIG_SOC_SAMA7G5) += sama7g5.o
+2 -1
drivers/clk/at91/at91rm9200.c
··· 160 160 161 161 hw = at91_clk_register_programmable(regmap, name, 162 162 parent_names, 4, i, 163 - &at91rm9200_programmable_layout); 163 + &at91rm9200_programmable_layout, 164 + NULL); 164 165 if (IS_ERR(hw)) 165 166 goto err_free; 166 167
+2 -1
drivers/clk/at91/at91sam9260.c
··· 436 436 437 437 hw = at91_clk_register_programmable(regmap, name, 438 438 parent_names, 4, i, 439 - &at91rm9200_programmable_layout); 439 + &at91rm9200_programmable_layout, 440 + NULL); 440 441 if (IS_ERR(hw)) 441 442 goto err_free; 442 443
+3 -2
drivers/clk/at91/at91sam9g45.c
··· 111 111 return; 112 112 mainxtal_name = of_clk_get_parent_name(np, i); 113 113 114 - regmap = syscon_node_to_regmap(np); 114 + regmap = device_node_to_regmap(np); 115 115 if (IS_ERR(regmap)) 116 116 return; 117 117 ··· 181 181 182 182 hw = at91_clk_register_programmable(regmap, name, 183 183 parent_names, 5, i, 184 - &at91sam9g45_programmable_layout); 184 + &at91sam9g45_programmable_layout, 185 + NULL); 185 186 if (IS_ERR(hw)) 186 187 goto err_free; 187 188
+4 -3
drivers/clk/at91/at91sam9n12.c
··· 124 124 return; 125 125 mainxtal_name = of_clk_get_parent_name(np, i); 126 126 127 - regmap = syscon_node_to_regmap(np); 127 + regmap = device_node_to_regmap(np); 128 128 if (IS_ERR(regmap)) 129 129 return; 130 130 ··· 199 199 200 200 hw = at91_clk_register_programmable(regmap, name, 201 201 parent_names, 5, i, 202 - &at91sam9x5_programmable_layout); 202 + &at91sam9x5_programmable_layout, 203 + NULL); 203 204 if (IS_ERR(hw)) 204 205 goto err_free; 205 206 ··· 223 222 at91sam9n12_periphck[i].n, 224 223 "masterck", 225 224 at91sam9n12_periphck[i].id, 226 - &range); 225 + &range, INT_MIN); 227 226 if (IS_ERR(hw)) 228 227 goto err_free; 229 228
+2 -1
drivers/clk/at91/at91sam9rl.c
··· 137 137 138 138 hw = at91_clk_register_programmable(regmap, name, 139 139 parent_names, 5, i, 140 - &at91rm9200_programmable_layout); 140 + &at91rm9200_programmable_layout, 141 + NULL); 141 142 if (IS_ERR(hw)) 142 143 goto err_free; 143 144
+4 -3
drivers/clk/at91/at91sam9x5.c
··· 226 226 227 227 hw = at91_clk_register_programmable(regmap, name, 228 228 parent_names, 5, i, 229 - &at91sam9x5_programmable_layout); 229 + &at91sam9x5_programmable_layout, 230 + NULL); 230 231 if (IS_ERR(hw)) 231 232 goto err_free; 232 233 ··· 258 257 at91sam9x5_periphck[i].n, 259 258 "masterck", 260 259 at91sam9x5_periphck[i].id, 261 - &range); 260 + &range, INT_MIN); 262 261 if (IS_ERR(hw)) 263 262 goto err_free; 264 263 ··· 271 270 extra_pcks[i].n, 272 271 "masterck", 273 272 extra_pcks[i].id, 274 - &range); 273 + &range, INT_MIN); 275 274 if (IS_ERR(hw)) 276 275 goto err_free; 277 276
+27 -17
drivers/clk/at91/clk-generated.c
··· 18 18 19 19 #define GENERATED_MAX_DIV 255 20 20 21 - #define GCK_INDEX_DT_AUDIO_PLL 5 22 - 23 21 struct clk_generated { 24 22 struct clk_hw hw; 25 23 struct regmap *regmap; 26 24 struct clk_range range; 27 25 spinlock_t *lock; 26 + u32 *mux_table; 28 27 u32 id; 29 28 u32 gckdiv; 30 29 const struct clk_pcr_layout *layout; 31 30 u8 parent_id; 32 - bool audio_pll_allowed; 31 + int chg_pid; 33 32 }; 34 33 35 34 #define to_clk_generated(hw) \ ··· 82 83 regmap_read(gck->regmap, gck->layout->offset, &status); 83 84 spin_unlock_irqrestore(gck->lock, flags); 84 85 85 - return status & AT91_PMC_PCR_GCKEN ? 1 : 0; 86 + return !!(status & AT91_PMC_PCR_GCKEN); 86 87 } 87 88 88 89 static unsigned long ··· 108 109 tmp_rate = parent_rate / div; 109 110 tmp_diff = abs(req->rate - tmp_rate); 110 111 111 - if (*best_diff < 0 || *best_diff > tmp_diff) { 112 + if (*best_diff < 0 || *best_diff >= tmp_diff) { 112 113 *best_rate = tmp_rate; 113 114 *best_diff = tmp_diff; 114 115 req->best_parent_rate = parent_rate; ··· 128 129 int i; 129 130 u32 div; 130 131 131 - for (i = 0; i < clk_hw_get_num_parents(hw) - 1; i++) { 132 + for (i = 0; i < clk_hw_get_num_parents(hw); i++) { 133 + if (gck->chg_pid == i) 134 + continue; 135 + 132 136 parent = clk_hw_get_parent_by_index(hw, i); 133 137 if (!parent) 134 138 continue; ··· 163 161 * that the only clks able to modify gck rate are those of audio IPs. 164 162 */ 165 163 166 - if (!gck->audio_pll_allowed) 164 + if (gck->chg_pid < 0) 167 165 goto end; 168 166 169 - parent = clk_hw_get_parent_by_index(hw, GCK_INDEX_DT_AUDIO_PLL); 167 + parent = clk_hw_get_parent_by_index(hw, gck->chg_pid); 170 168 if (!parent) 171 169 goto end; 172 170 173 171 for (div = 1; div < GENERATED_MAX_DIV + 2; div++) { 174 172 req_parent.rate = req->rate * div; 175 - __clk_determine_rate(parent, &req_parent); 173 + if (__clk_determine_rate(parent, &req_parent)) 174 + continue; 176 175 clk_generated_best_diff(req, parent, req_parent.rate, div, 177 176 &best_diff, &best_rate); 178 177 ··· 187 184 __clk_get_name((req->best_parent_hw)->clk), 188 185 req->best_parent_rate); 189 186 190 - if (best_rate < 0) 191 - return best_rate; 187 + if (best_rate < 0 || (gck->range.max && best_rate > gck->range.max)) 188 + return -EINVAL; 192 189 193 190 req->rate = best_rate; 194 191 return 0; ··· 202 199 if (index >= clk_hw_get_num_parents(hw)) 203 200 return -EINVAL; 204 201 205 - gck->parent_id = index; 202 + if (gck->mux_table) 203 + gck->parent_id = clk_mux_index_to_val(gck->mux_table, 0, index); 204 + else 205 + gck->parent_id = index; 206 + 206 207 return 0; 207 208 } 208 209 ··· 278 271 at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock, 279 272 const struct clk_pcr_layout *layout, 280 273 const char *name, const char **parent_names, 281 - u8 num_parents, u8 id, bool pll_audio, 282 - const struct clk_range *range) 274 + u32 *mux_table, u8 num_parents, u8 id, 275 + const struct clk_range *range, 276 + int chg_pid) 283 277 { 284 278 struct clk_generated *gck; 285 279 struct clk_init_data init; ··· 295 287 init.ops = &generated_ops; 296 288 init.parent_names = parent_names; 297 289 init.num_parents = num_parents; 298 - init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | 299 - CLK_SET_RATE_PARENT; 290 + init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE; 291 + if (chg_pid >= 0) 292 + init.flags |= CLK_SET_RATE_PARENT; 300 293 301 294 gck->id = id; 302 295 gck->hw.init = &init; 303 296 gck->regmap = regmap; 304 297 gck->lock = lock; 305 298 gck->range = *range; 306 - gck->audio_pll_allowed = pll_audio; 299 + gck->chg_pid = chg_pid; 307 300 gck->layout = layout; 301 + gck->mux_table = mux_table; 308 302 309 303 clk_generated_startup(gck); 310 304 hw = &gck->hw;
+3 -3
drivers/clk/at91/clk-main.c
··· 175 175 176 176 regmap_read(regmap, AT91_PMC_SR, &status); 177 177 178 - return status & AT91_PMC_MOSCRCS; 178 + return !!(status & AT91_PMC_MOSCRCS); 179 179 } 180 180 181 181 static int clk_main_rc_osc_prepare(struct clk_hw *hw) ··· 336 336 337 337 regmap_read(clkmain->regmap, AT91_CKGR_MCFR, &status); 338 338 339 - return status & AT91_PMC_MAINRDY ? 1 : 0; 339 + return !!(status & AT91_PMC_MAINRDY); 340 340 } 341 341 342 342 static unsigned long clk_rm9200_main_recalc_rate(struct clk_hw *hw, ··· 398 398 399 399 regmap_read(regmap, AT91_PMC_SR, &status); 400 400 401 - return status & AT91_PMC_MOSCSELS ? 1 : 0; 401 + return !!(status & AT91_PMC_MOSCSELS); 402 402 } 403 403 404 404 static int clk_sam9x5_main_prepare(struct clk_hw *hw)
+305 -5
drivers/clk/at91/clk-master.c
··· 17 17 #define MASTER_DIV_SHIFT 8 18 18 #define MASTER_DIV_MASK 0x3 19 19 20 + #define PMC_MCR 0x30 21 + #define PMC_MCR_ID_MSK GENMASK(3, 0) 22 + #define PMC_MCR_CMD BIT(7) 23 + #define PMC_MCR_DIV GENMASK(10, 8) 24 + #define PMC_MCR_CSS GENMASK(20, 16) 25 + #define PMC_MCR_CSS_SHIFT (16) 26 + #define PMC_MCR_EN BIT(28) 27 + 28 + #define PMC_MCR_ID(x) ((x) & PMC_MCR_ID_MSK) 29 + 30 + #define MASTER_MAX_ID 4 31 + 20 32 #define to_clk_master(hw) container_of(hw, struct clk_master, hw) 21 33 22 34 struct clk_master { 23 35 struct clk_hw hw; 24 36 struct regmap *regmap; 37 + spinlock_t *lock; 25 38 const struct clk_master_layout *layout; 26 39 const struct clk_master_characteristics *characteristics; 40 + u32 *mux_table; 27 41 u32 mckr; 42 + int chg_pid; 43 + u8 id; 44 + u8 parent; 45 + u8 div; 28 46 }; 29 47 30 - static inline bool clk_master_ready(struct regmap *regmap) 48 + static inline bool clk_master_ready(struct clk_master *master) 31 49 { 50 + unsigned int bit = master->id ? AT91_PMC_MCKXRDY : AT91_PMC_MCKRDY; 32 51 unsigned int status; 33 52 34 - regmap_read(regmap, AT91_PMC_SR, &status); 53 + regmap_read(master->regmap, AT91_PMC_SR, &status); 35 54 36 - return status & AT91_PMC_MCKRDY ? 1 : 0; 55 + return !!(status & bit); 37 56 } 38 57 39 58 static int clk_master_prepare(struct clk_hw *hw) 40 59 { 41 60 struct clk_master *master = to_clk_master(hw); 42 61 43 - while (!clk_master_ready(master->regmap)) 62 + while (!clk_master_ready(master)) 44 63 cpu_relax(); 45 64 46 65 return 0; ··· 69 50 { 70 51 struct clk_master *master = to_clk_master(hw); 71 52 72 - return clk_master_ready(master->regmap); 53 + return clk_master_ready(master); 73 54 } 74 55 75 56 static unsigned long clk_master_recalc_rate(struct clk_hw *hw, ··· 151 132 master->layout = layout; 152 133 master->characteristics = characteristics; 153 134 master->regmap = regmap; 135 + 136 + hw = &master->hw; 137 + ret = clk_hw_register(NULL, &master->hw); 138 + if (ret) { 139 + kfree(master); 140 + hw = ERR_PTR(ret); 141 + } 142 + 143 + return hw; 144 + } 145 + 146 + static unsigned long 147 + clk_sama7g5_master_recalc_rate(struct clk_hw *hw, 148 + unsigned long parent_rate) 149 + { 150 + struct clk_master *master = to_clk_master(hw); 151 + 152 + return DIV_ROUND_CLOSEST_ULL(parent_rate, (1 << master->div)); 153 + } 154 + 155 + static void clk_sama7g5_master_best_diff(struct clk_rate_request *req, 156 + struct clk_hw *parent, 157 + unsigned long parent_rate, 158 + long *best_rate, 159 + long *best_diff, 160 + u32 div) 161 + { 162 + unsigned long tmp_rate, tmp_diff; 163 + 164 + if (div == MASTER_PRES_MAX) 165 + tmp_rate = parent_rate / 3; 166 + else 167 + tmp_rate = parent_rate >> div; 168 + 169 + tmp_diff = abs(req->rate - tmp_rate); 170 + 171 + if (*best_diff < 0 || *best_diff >= tmp_diff) { 172 + *best_rate = tmp_rate; 173 + *best_diff = tmp_diff; 174 + req->best_parent_rate = parent_rate; 175 + req->best_parent_hw = parent; 176 + } 177 + } 178 + 179 + static int clk_sama7g5_master_determine_rate(struct clk_hw *hw, 180 + struct clk_rate_request *req) 181 + { 182 + struct clk_master *master = to_clk_master(hw); 183 + struct clk_rate_request req_parent = *req; 184 + struct clk_hw *parent; 185 + long best_rate = LONG_MIN, best_diff = LONG_MIN; 186 + unsigned long parent_rate; 187 + unsigned int div, i; 188 + 189 + /* First: check the dividers of MCR. */ 190 + for (i = 0; i < clk_hw_get_num_parents(hw); i++) { 191 + parent = clk_hw_get_parent_by_index(hw, i); 192 + if (!parent) 193 + continue; 194 + 195 + parent_rate = clk_hw_get_rate(parent); 196 + if (!parent_rate) 197 + continue; 198 + 199 + for (div = 0; div < MASTER_PRES_MAX + 1; div++) { 200 + clk_sama7g5_master_best_diff(req, parent, parent_rate, 201 + &best_rate, &best_diff, 202 + div); 203 + if (!best_diff) 204 + break; 205 + } 206 + 207 + if (!best_diff) 208 + break; 209 + } 210 + 211 + /* Second: try to request rate form changeable parent. */ 212 + if (master->chg_pid < 0) 213 + goto end; 214 + 215 + parent = clk_hw_get_parent_by_index(hw, master->chg_pid); 216 + if (!parent) 217 + goto end; 218 + 219 + for (div = 0; div < MASTER_PRES_MAX + 1; div++) { 220 + if (div == MASTER_PRES_MAX) 221 + req_parent.rate = req->rate * 3; 222 + else 223 + req_parent.rate = req->rate << div; 224 + 225 + if (__clk_determine_rate(parent, &req_parent)) 226 + continue; 227 + 228 + clk_sama7g5_master_best_diff(req, parent, req_parent.rate, 229 + &best_rate, &best_diff, div); 230 + 231 + if (!best_diff) 232 + break; 233 + } 234 + 235 + end: 236 + pr_debug("MCK: %s, best_rate = %ld, parent clk: %s @ %ld\n", 237 + __func__, best_rate, 238 + __clk_get_name((req->best_parent_hw)->clk), 239 + req->best_parent_rate); 240 + 241 + if (best_rate < 0) 242 + return -EINVAL; 243 + 244 + req->rate = best_rate; 245 + 246 + return 0; 247 + } 248 + 249 + static u8 clk_sama7g5_master_get_parent(struct clk_hw *hw) 250 + { 251 + struct clk_master *master = to_clk_master(hw); 252 + unsigned long flags; 253 + u8 index; 254 + 255 + spin_lock_irqsave(master->lock, flags); 256 + index = clk_mux_val_to_index(&master->hw, master->mux_table, 0, 257 + master->parent); 258 + spin_unlock_irqrestore(master->lock, flags); 259 + 260 + return index; 261 + } 262 + 263 + static int clk_sama7g5_master_set_parent(struct clk_hw *hw, u8 index) 264 + { 265 + struct clk_master *master = to_clk_master(hw); 266 + unsigned long flags; 267 + 268 + if (index >= clk_hw_get_num_parents(hw)) 269 + return -EINVAL; 270 + 271 + spin_lock_irqsave(master->lock, flags); 272 + master->parent = clk_mux_index_to_val(master->mux_table, 0, index); 273 + spin_unlock_irqrestore(master->lock, flags); 274 + 275 + return 0; 276 + } 277 + 278 + static int clk_sama7g5_master_enable(struct clk_hw *hw) 279 + { 280 + struct clk_master *master = to_clk_master(hw); 281 + unsigned long flags; 282 + unsigned int val, cparent; 283 + 284 + spin_lock_irqsave(master->lock, flags); 285 + 286 + regmap_write(master->regmap, PMC_MCR, PMC_MCR_ID(master->id)); 287 + regmap_read(master->regmap, PMC_MCR, &val); 288 + regmap_update_bits(master->regmap, PMC_MCR, 289 + PMC_MCR_EN | PMC_MCR_CSS | PMC_MCR_DIV | 290 + PMC_MCR_CMD | PMC_MCR_ID_MSK, 291 + PMC_MCR_EN | (master->parent << PMC_MCR_CSS_SHIFT) | 292 + (master->div << MASTER_DIV_SHIFT) | 293 + PMC_MCR_CMD | PMC_MCR_ID(master->id)); 294 + 295 + cparent = (val & PMC_MCR_CSS) >> PMC_MCR_CSS_SHIFT; 296 + 297 + /* Wait here only if parent is being changed. */ 298 + while ((cparent != master->parent) && !clk_master_ready(master)) 299 + cpu_relax(); 300 + 301 + spin_unlock_irqrestore(master->lock, flags); 302 + 303 + return 0; 304 + } 305 + 306 + static void clk_sama7g5_master_disable(struct clk_hw *hw) 307 + { 308 + struct clk_master *master = to_clk_master(hw); 309 + unsigned long flags; 310 + 311 + spin_lock_irqsave(master->lock, flags); 312 + 313 + regmap_write(master->regmap, PMC_MCR, master->id); 314 + regmap_update_bits(master->regmap, PMC_MCR, 315 + PMC_MCR_EN | PMC_MCR_CMD | PMC_MCR_ID_MSK, 316 + PMC_MCR_CMD | PMC_MCR_ID(master->id)); 317 + 318 + spin_unlock_irqrestore(master->lock, flags); 319 + } 320 + 321 + static int clk_sama7g5_master_is_enabled(struct clk_hw *hw) 322 + { 323 + struct clk_master *master = to_clk_master(hw); 324 + unsigned long flags; 325 + unsigned int val; 326 + 327 + spin_lock_irqsave(master->lock, flags); 328 + 329 + regmap_write(master->regmap, PMC_MCR, master->id); 330 + regmap_read(master->regmap, PMC_MCR, &val); 331 + 332 + spin_unlock_irqrestore(master->lock, flags); 333 + 334 + return !!(val & PMC_MCR_EN); 335 + } 336 + 337 + static int clk_sama7g5_master_set_rate(struct clk_hw *hw, unsigned long rate, 338 + unsigned long parent_rate) 339 + { 340 + struct clk_master *master = to_clk_master(hw); 341 + unsigned long div, flags; 342 + 343 + div = DIV_ROUND_CLOSEST(parent_rate, rate); 344 + if ((div > (1 << (MASTER_PRES_MAX - 1))) || (div & (div - 1))) 345 + return -EINVAL; 346 + 347 + if (div == 3) 348 + div = MASTER_PRES_MAX; 349 + else 350 + div = ffs(div) - 1; 351 + 352 + spin_lock_irqsave(master->lock, flags); 353 + master->div = div; 354 + spin_unlock_irqrestore(master->lock, flags); 355 + 356 + return 0; 357 + } 358 + 359 + static const struct clk_ops sama7g5_master_ops = { 360 + .enable = clk_sama7g5_master_enable, 361 + .disable = clk_sama7g5_master_disable, 362 + .is_enabled = clk_sama7g5_master_is_enabled, 363 + .recalc_rate = clk_sama7g5_master_recalc_rate, 364 + .determine_rate = clk_sama7g5_master_determine_rate, 365 + .set_rate = clk_sama7g5_master_set_rate, 366 + .get_parent = clk_sama7g5_master_get_parent, 367 + .set_parent = clk_sama7g5_master_set_parent, 368 + }; 369 + 370 + struct clk_hw * __init 371 + at91_clk_sama7g5_register_master(struct regmap *regmap, 372 + const char *name, int num_parents, 373 + const char **parent_names, 374 + u32 *mux_table, 375 + spinlock_t *lock, u8 id, 376 + bool critical, int chg_pid) 377 + { 378 + struct clk_master *master; 379 + struct clk_hw *hw; 380 + struct clk_init_data init; 381 + unsigned long flags; 382 + unsigned int val; 383 + int ret; 384 + 385 + if (!name || !num_parents || !parent_names || !mux_table || 386 + !lock || id > MASTER_MAX_ID) 387 + return ERR_PTR(-EINVAL); 388 + 389 + master = kzalloc(sizeof(*master), GFP_KERNEL); 390 + if (!master) 391 + return ERR_PTR(-ENOMEM); 392 + 393 + init.name = name; 394 + init.ops = &sama7g5_master_ops; 395 + init.parent_names = parent_names; 396 + init.num_parents = num_parents; 397 + init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE; 398 + if (chg_pid >= 0) 399 + init.flags |= CLK_SET_RATE_PARENT; 400 + if (critical) 401 + init.flags |= CLK_IS_CRITICAL; 402 + 403 + master->hw.init = &init; 404 + master->regmap = regmap; 405 + master->id = id; 406 + master->chg_pid = chg_pid; 407 + master->lock = lock; 408 + master->mux_table = mux_table; 409 + 410 + spin_lock_irqsave(master->lock, flags); 411 + regmap_write(master->regmap, PMC_MCR, master->id); 412 + regmap_read(master->regmap, PMC_MCR, &val); 413 + master->parent = (val & PMC_MCR_CSS) >> PMC_MCR_CSS_SHIFT; 414 + master->div = (val & PMC_MCR_DIV) >> MASTER_DIV_SHIFT; 415 + spin_unlock_irqrestore(master->lock, flags); 154 416 155 417 hw = &master->hw; 156 418 ret = clk_hw_register(NULL, &master->hw);
+105 -6
drivers/clk/at91/clk-peripheral.c
··· 38 38 u32 div; 39 39 const struct clk_pcr_layout *layout; 40 40 bool auto_div; 41 + int chg_pid; 41 42 }; 42 43 43 44 #define to_clk_sam9x5_peripheral(hw) \ ··· 209 208 regmap_read(periph->regmap, periph->layout->offset, &status); 210 209 spin_unlock_irqrestore(periph->lock, flags); 211 210 212 - return status & AT91_PMC_PCR_EN ? 1 : 0; 211 + return !!(status & AT91_PMC_PCR_EN); 213 212 } 214 213 215 214 static unsigned long ··· 237 236 } 238 237 239 238 return parent_rate >> periph->div; 239 + } 240 + 241 + static void clk_sam9x5_peripheral_best_diff(struct clk_rate_request *req, 242 + struct clk_hw *parent, 243 + unsigned long parent_rate, 244 + u32 shift, long *best_diff, 245 + long *best_rate) 246 + { 247 + unsigned long tmp_rate = parent_rate >> shift; 248 + unsigned long tmp_diff = abs(req->rate - tmp_rate); 249 + 250 + if (*best_diff < 0 || *best_diff >= tmp_diff) { 251 + *best_rate = tmp_rate; 252 + *best_diff = tmp_diff; 253 + req->best_parent_rate = parent_rate; 254 + req->best_parent_hw = parent; 255 + } 256 + } 257 + 258 + static int clk_sam9x5_peripheral_determine_rate(struct clk_hw *hw, 259 + struct clk_rate_request *req) 260 + { 261 + struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw); 262 + struct clk_hw *parent = clk_hw_get_parent(hw); 263 + struct clk_rate_request req_parent = *req; 264 + unsigned long parent_rate = clk_hw_get_rate(parent); 265 + unsigned long tmp_rate; 266 + long best_rate = LONG_MIN; 267 + long best_diff = LONG_MIN; 268 + u32 shift; 269 + 270 + if (periph->id < PERIPHERAL_ID_MIN || !periph->range.max) 271 + return parent_rate; 272 + 273 + /* Fist step: check the available dividers. */ 274 + for (shift = 0; shift <= PERIPHERAL_MAX_SHIFT; shift++) { 275 + tmp_rate = parent_rate >> shift; 276 + 277 + if (periph->range.max && tmp_rate > periph->range.max) 278 + continue; 279 + 280 + clk_sam9x5_peripheral_best_diff(req, parent, parent_rate, 281 + shift, &best_diff, &best_rate); 282 + 283 + if (!best_diff || best_rate <= req->rate) 284 + break; 285 + } 286 + 287 + if (periph->chg_pid < 0) 288 + goto end; 289 + 290 + /* Step two: try to request rate from parent. */ 291 + parent = clk_hw_get_parent_by_index(hw, periph->chg_pid); 292 + if (!parent) 293 + goto end; 294 + 295 + for (shift = 0; shift <= PERIPHERAL_MAX_SHIFT; shift++) { 296 + req_parent.rate = req->rate << shift; 297 + 298 + if (__clk_determine_rate(parent, &req_parent)) 299 + continue; 300 + 301 + clk_sam9x5_peripheral_best_diff(req, parent, req_parent.rate, 302 + shift, &best_diff, &best_rate); 303 + 304 + if (!best_diff) 305 + break; 306 + } 307 + end: 308 + if (best_rate < 0 || 309 + (periph->range.max && best_rate > periph->range.max)) 310 + return -EINVAL; 311 + 312 + pr_debug("PCK: %s, best_rate = %ld, parent clk: %s @ %ld\n", 313 + __func__, best_rate, 314 + __clk_get_name((req->best_parent_hw)->clk), 315 + req->best_parent_rate); 316 + 317 + req->rate = best_rate; 318 + 319 + return 0; 240 320 } 241 321 242 322 static long clk_sam9x5_peripheral_round_rate(struct clk_hw *hw, ··· 402 320 .set_rate = clk_sam9x5_peripheral_set_rate, 403 321 }; 404 322 323 + static const struct clk_ops sam9x5_peripheral_chg_ops = { 324 + .enable = clk_sam9x5_peripheral_enable, 325 + .disable = clk_sam9x5_peripheral_disable, 326 + .is_enabled = clk_sam9x5_peripheral_is_enabled, 327 + .recalc_rate = clk_sam9x5_peripheral_recalc_rate, 328 + .determine_rate = clk_sam9x5_peripheral_determine_rate, 329 + .set_rate = clk_sam9x5_peripheral_set_rate, 330 + }; 331 + 405 332 struct clk_hw * __init 406 333 at91_clk_register_sam9x5_peripheral(struct regmap *regmap, spinlock_t *lock, 407 334 const struct clk_pcr_layout *layout, 408 335 const char *name, const char *parent_name, 409 - u32 id, const struct clk_range *range) 336 + u32 id, const struct clk_range *range, 337 + int chg_pid) 410 338 { 411 339 struct clk_sam9x5_peripheral *periph; 412 340 struct clk_init_data init; ··· 431 339 return ERR_PTR(-ENOMEM); 432 340 433 341 init.name = name; 434 - init.ops = &sam9x5_peripheral_ops; 435 - init.parent_names = (parent_name ? &parent_name : NULL); 436 - init.num_parents = (parent_name ? 1 : 0); 437 - init.flags = 0; 342 + init.parent_names = &parent_name; 343 + init.num_parents = 1; 344 + if (chg_pid < 0) { 345 + init.flags = 0; 346 + init.ops = &sam9x5_peripheral_ops; 347 + } else { 348 + init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | 349 + CLK_SET_RATE_PARENT; 350 + init.ops = &sam9x5_peripheral_chg_ops; 351 + } 438 352 439 353 periph->id = id; 440 354 periph->hw.init = &init; ··· 451 353 periph->auto_div = true; 452 354 periph->layout = layout; 453 355 periph->range = *range; 356 + periph->chg_pid = chg_pid; 454 357 455 358 hw = &periph->hw; 456 359 ret = clk_hw_register(NULL, &periph->hw);
+10 -1
drivers/clk/at91/clk-programmable.c
··· 21 21 struct clk_programmable { 22 22 struct clk_hw hw; 23 23 struct regmap *regmap; 24 + u32 *mux_table; 24 25 u8 id; 25 26 const struct clk_programmable_layout *layout; 26 27 }; ··· 109 108 if (layout->have_slck_mck) 110 109 mask |= AT91_PMC_CSSMCK_MCK; 111 110 111 + if (prog->mux_table) 112 + pckr = clk_mux_index_to_val(prog->mux_table, 0, index); 113 + 112 114 if (index > layout->css_mask) { 113 115 if (index > PROG_MAX_RM9200_CSS && !layout->have_slck_mck) 114 116 return -EINVAL; ··· 137 133 138 134 if (layout->have_slck_mck && (pckr & AT91_PMC_CSSMCK_MCK) && !ret) 139 135 ret = PROG_MAX_RM9200_CSS + 1; 136 + 137 + if (prog->mux_table) 138 + ret = clk_mux_val_to_index(&prog->hw, prog->mux_table, 0, ret); 140 139 141 140 return ret; 142 141 } ··· 189 182 at91_clk_register_programmable(struct regmap *regmap, 190 183 const char *name, const char **parent_names, 191 184 u8 num_parents, u8 id, 192 - const struct clk_programmable_layout *layout) 185 + const struct clk_programmable_layout *layout, 186 + u32 *mux_table) 193 187 { 194 188 struct clk_programmable *prog; 195 189 struct clk_hw *hw; ··· 214 206 prog->layout = layout; 215 207 prog->hw.init = &init; 216 208 prog->regmap = regmap; 209 + prog->mux_table = mux_table; 217 210 218 211 hw = &prog->hw; 219 212 ret = clk_hw_register(NULL, &prog->hw);
+387 -172
drivers/clk/at91/clk-sam9x60-pll.c
··· 15 15 #include "pmc.h" 16 16 17 17 #define PMC_PLL_CTRL0_DIV_MSK GENMASK(7, 0) 18 - #define PMC_PLL_CTRL1_MUL_MSK GENMASK(30, 24) 18 + #define PMC_PLL_CTRL1_MUL_MSK GENMASK(31, 24) 19 + #define PMC_PLL_CTRL1_FRACR_MSK GENMASK(21, 0) 19 20 20 21 #define PLL_DIV_MAX (FIELD_GET(PMC_PLL_CTRL0_DIV_MSK, UINT_MAX) + 1) 21 22 #define UPLL_DIV 2 22 23 #define PLL_MUL_MAX (FIELD_GET(PMC_PLL_CTRL1_MUL_MSK, UINT_MAX) + 1) 23 24 24 - #define PLL_MAX_ID 1 25 + #define FCORE_MIN (600000000) 26 + #define FCORE_MAX (1200000000) 25 27 26 - struct sam9x60_pll { 27 - struct clk_hw hw; 28 + #define PLL_MAX_ID 7 29 + 30 + struct sam9x60_pll_core { 28 31 struct regmap *regmap; 29 32 spinlock_t *lock; 30 33 const struct clk_pll_characteristics *characteristics; 31 - u32 frac; 34 + const struct clk_pll_layout *layout; 35 + struct clk_hw hw; 32 36 u8 id; 33 - u8 div; 37 + }; 38 + 39 + struct sam9x60_frac { 40 + struct sam9x60_pll_core core; 41 + u32 frac; 34 42 u16 mul; 35 43 }; 36 44 37 - #define to_sam9x60_pll(hw) container_of(hw, struct sam9x60_pll, hw) 45 + struct sam9x60_div { 46 + struct sam9x60_pll_core core; 47 + u8 div; 48 + }; 49 + 50 + #define to_sam9x60_pll_core(hw) container_of(hw, struct sam9x60_pll_core, hw) 51 + #define to_sam9x60_frac(core) container_of(core, struct sam9x60_frac, core) 52 + #define to_sam9x60_div(core) container_of(core, struct sam9x60_div, core) 38 53 39 54 static inline bool sam9x60_pll_ready(struct regmap *regmap, int id) 40 55 { ··· 60 45 return !!(status & BIT(id)); 61 46 } 62 47 63 - static int sam9x60_pll_prepare(struct clk_hw *hw) 48 + static bool sam9x60_frac_pll_ready(struct regmap *regmap, u8 id) 64 49 { 65 - struct sam9x60_pll *pll = to_sam9x60_pll(hw); 66 - struct regmap *regmap = pll->regmap; 50 + return sam9x60_pll_ready(regmap, id); 51 + } 52 + 53 + static unsigned long sam9x60_frac_pll_recalc_rate(struct clk_hw *hw, 54 + unsigned long parent_rate) 55 + { 56 + struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw); 57 + struct sam9x60_frac *frac = to_sam9x60_frac(core); 58 + 59 + return (parent_rate * (frac->mul + 1) + 60 + ((u64)parent_rate * frac->frac >> 22)); 61 + } 62 + 63 + static int sam9x60_frac_pll_prepare(struct clk_hw *hw) 64 + { 65 + struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw); 66 + struct sam9x60_frac *frac = to_sam9x60_frac(core); 67 + struct regmap *regmap = core->regmap; 68 + unsigned int val, cfrac, cmul; 67 69 unsigned long flags; 68 - u8 div; 69 - u16 mul; 70 - u32 val; 71 70 72 - spin_lock_irqsave(pll->lock, flags); 73 - regmap_write(regmap, AT91_PMC_PLL_UPDT, pll->id); 71 + spin_lock_irqsave(core->lock, flags); 74 72 75 - regmap_read(regmap, AT91_PMC_PLL_CTRL0, &val); 76 - div = FIELD_GET(PMC_PLL_CTRL0_DIV_MSK, val); 77 - 73 + regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, 74 + AT91_PMC_PLL_UPDT_ID_MSK, core->id); 78 75 regmap_read(regmap, AT91_PMC_PLL_CTRL1, &val); 79 - mul = FIELD_GET(PMC_PLL_CTRL1_MUL_MSK, val); 76 + cmul = (val & core->layout->mul_mask) >> core->layout->mul_shift; 77 + cfrac = (val & core->layout->frac_mask) >> core->layout->frac_shift; 80 78 81 - if (sam9x60_pll_ready(regmap, pll->id) && 82 - (div == pll->div && mul == pll->mul)) { 83 - spin_unlock_irqrestore(pll->lock, flags); 84 - return 0; 85 - } 79 + if (sam9x60_frac_pll_ready(regmap, core->id) && 80 + (cmul == frac->mul && cfrac == frac->frac)) 81 + goto unlock; 86 82 87 - /* Recommended value for AT91_PMC_PLL_ACR */ 88 - if (pll->characteristics->upll) 83 + /* Recommended value for PMC_PLL_ACR */ 84 + if (core->characteristics->upll) 89 85 val = AT91_PMC_PLL_ACR_DEFAULT_UPLL; 90 86 else 91 87 val = AT91_PMC_PLL_ACR_DEFAULT_PLLA; 92 88 regmap_write(regmap, AT91_PMC_PLL_ACR, val); 93 89 94 90 regmap_write(regmap, AT91_PMC_PLL_CTRL1, 95 - FIELD_PREP(PMC_PLL_CTRL1_MUL_MSK, pll->mul)); 91 + (frac->mul << core->layout->mul_shift) | 92 + (frac->frac << core->layout->frac_shift)); 96 93 97 - if (pll->characteristics->upll) { 94 + if (core->characteristics->upll) { 98 95 /* Enable the UTMI internal bandgap */ 99 96 val |= AT91_PMC_PLL_ACR_UTMIBG; 100 97 regmap_write(regmap, AT91_PMC_PLL_ACR, val); ··· 121 94 } 122 95 123 96 regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, 124 - AT91_PMC_PLL_UPDT_UPDATE, AT91_PMC_PLL_UPDT_UPDATE); 97 + AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK, 98 + AT91_PMC_PLL_UPDT_UPDATE | core->id); 125 99 126 - regmap_write(regmap, AT91_PMC_PLL_CTRL0, 127 - AT91_PMC_PLL_CTRL0_ENLOCK | AT91_PMC_PLL_CTRL0_ENPLL | 128 - AT91_PMC_PLL_CTRL0_ENPLLCK | pll->div); 100 + regmap_update_bits(regmap, AT91_PMC_PLL_CTRL0, 101 + AT91_PMC_PLL_CTRL0_ENLOCK | AT91_PMC_PLL_CTRL0_ENPLL, 102 + AT91_PMC_PLL_CTRL0_ENLOCK | AT91_PMC_PLL_CTRL0_ENPLL); 129 103 130 104 regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, 131 - AT91_PMC_PLL_UPDT_UPDATE, AT91_PMC_PLL_UPDT_UPDATE); 105 + AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK, 106 + AT91_PMC_PLL_UPDT_UPDATE | core->id); 132 107 133 - while (!sam9x60_pll_ready(regmap, pll->id)) 108 + while (!sam9x60_pll_ready(regmap, core->id)) 134 109 cpu_relax(); 135 110 136 - spin_unlock_irqrestore(pll->lock, flags); 111 + unlock: 112 + spin_unlock_irqrestore(core->lock, flags); 137 113 138 114 return 0; 139 115 } 140 116 141 - static int sam9x60_pll_is_prepared(struct clk_hw *hw) 117 + static void sam9x60_frac_pll_unprepare(struct clk_hw *hw) 142 118 { 143 - struct sam9x60_pll *pll = to_sam9x60_pll(hw); 144 - 145 - return sam9x60_pll_ready(pll->regmap, pll->id); 146 - } 147 - 148 - static void sam9x60_pll_unprepare(struct clk_hw *hw) 149 - { 150 - struct sam9x60_pll *pll = to_sam9x60_pll(hw); 119 + struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw); 120 + struct regmap *regmap = core->regmap; 151 121 unsigned long flags; 152 122 153 - spin_lock_irqsave(pll->lock, flags); 123 + spin_lock_irqsave(core->lock, flags); 154 124 155 - regmap_write(pll->regmap, AT91_PMC_PLL_UPDT, pll->id); 125 + regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, 126 + AT91_PMC_PLL_UPDT_ID_MSK, core->id); 156 127 157 - regmap_update_bits(pll->regmap, AT91_PMC_PLL_CTRL0, 158 - AT91_PMC_PLL_CTRL0_ENPLLCK, 0); 128 + regmap_update_bits(regmap, AT91_PMC_PLL_CTRL0, AT91_PMC_PLL_CTRL0_ENPLL, 0); 159 129 160 - regmap_update_bits(pll->regmap, AT91_PMC_PLL_UPDT, 161 - AT91_PMC_PLL_UPDT_UPDATE, AT91_PMC_PLL_UPDT_UPDATE); 130 + if (core->characteristics->upll) 131 + regmap_update_bits(regmap, AT91_PMC_PLL_ACR, 132 + AT91_PMC_PLL_ACR_UTMIBG | AT91_PMC_PLL_ACR_UTMIVR, 0); 162 133 163 - regmap_update_bits(pll->regmap, AT91_PMC_PLL_CTRL0, 164 - AT91_PMC_PLL_CTRL0_ENPLL, 0); 134 + regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, 135 + AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK, 136 + AT91_PMC_PLL_UPDT_UPDATE | core->id); 165 137 166 - if (pll->characteristics->upll) 167 - regmap_update_bits(pll->regmap, AT91_PMC_PLL_ACR, 168 - AT91_PMC_PLL_ACR_UTMIBG | 169 - AT91_PMC_PLL_ACR_UTMIVR, 0); 170 - 171 - regmap_update_bits(pll->regmap, AT91_PMC_PLL_UPDT, 172 - AT91_PMC_PLL_UPDT_UPDATE, AT91_PMC_PLL_UPDT_UPDATE); 173 - 174 - spin_unlock_irqrestore(pll->lock, flags); 138 + spin_unlock_irqrestore(core->lock, flags); 175 139 } 176 140 177 - static unsigned long sam9x60_pll_recalc_rate(struct clk_hw *hw, 178 - unsigned long parent_rate) 141 + static int sam9x60_frac_pll_is_prepared(struct clk_hw *hw) 179 142 { 180 - struct sam9x60_pll *pll = to_sam9x60_pll(hw); 143 + struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw); 181 144 182 - return (parent_rate * (pll->mul + 1)) / (pll->div + 1); 145 + return sam9x60_pll_ready(core->regmap, core->id); 183 146 } 184 147 185 - static long sam9x60_pll_get_best_div_mul(struct sam9x60_pll *pll, 186 - unsigned long rate, 187 - unsigned long parent_rate, 188 - bool update) 148 + static long sam9x60_frac_pll_compute_mul_frac(struct sam9x60_pll_core *core, 149 + unsigned long rate, 150 + unsigned long parent_rate, 151 + bool update) 152 + { 153 + struct sam9x60_frac *frac = to_sam9x60_frac(core); 154 + unsigned long tmprate, remainder; 155 + unsigned long nmul = 0; 156 + unsigned long nfrac = 0; 157 + 158 + if (rate < FCORE_MIN || rate > FCORE_MAX) 159 + return -ERANGE; 160 + 161 + /* 162 + * Calculate the multiplier associated with the current 163 + * divider that provide the closest rate to the requested one. 164 + */ 165 + nmul = mult_frac(rate, 1, parent_rate); 166 + tmprate = mult_frac(parent_rate, nmul, 1); 167 + remainder = rate - tmprate; 168 + 169 + if (remainder) { 170 + nfrac = DIV_ROUND_CLOSEST_ULL((u64)remainder * (1 << 22), 171 + parent_rate); 172 + 173 + tmprate += DIV_ROUND_CLOSEST_ULL((u64)nfrac * parent_rate, 174 + (1 << 22)); 175 + } 176 + 177 + /* Check if resulted rate is a valid. */ 178 + if (tmprate < FCORE_MIN || tmprate > FCORE_MAX) 179 + return -ERANGE; 180 + 181 + if (update) { 182 + frac->mul = nmul - 1; 183 + frac->frac = nfrac; 184 + } 185 + 186 + return tmprate; 187 + } 188 + 189 + static long sam9x60_frac_pll_round_rate(struct clk_hw *hw, unsigned long rate, 190 + unsigned long *parent_rate) 191 + { 192 + struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw); 193 + 194 + return sam9x60_frac_pll_compute_mul_frac(core, rate, *parent_rate, false); 195 + } 196 + 197 + static int sam9x60_frac_pll_set_rate(struct clk_hw *hw, unsigned long rate, 198 + unsigned long parent_rate) 199 + { 200 + struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw); 201 + 202 + return sam9x60_frac_pll_compute_mul_frac(core, rate, parent_rate, true); 203 + } 204 + 205 + static const struct clk_ops sam9x60_frac_pll_ops = { 206 + .prepare = sam9x60_frac_pll_prepare, 207 + .unprepare = sam9x60_frac_pll_unprepare, 208 + .is_prepared = sam9x60_frac_pll_is_prepared, 209 + .recalc_rate = sam9x60_frac_pll_recalc_rate, 210 + .round_rate = sam9x60_frac_pll_round_rate, 211 + .set_rate = sam9x60_frac_pll_set_rate, 212 + }; 213 + 214 + static int sam9x60_div_pll_prepare(struct clk_hw *hw) 215 + { 216 + struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw); 217 + struct sam9x60_div *div = to_sam9x60_div(core); 218 + struct regmap *regmap = core->regmap; 219 + unsigned long flags; 220 + unsigned int val, cdiv; 221 + 222 + spin_lock_irqsave(core->lock, flags); 223 + regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, 224 + AT91_PMC_PLL_UPDT_ID_MSK, core->id); 225 + regmap_read(regmap, AT91_PMC_PLL_CTRL0, &val); 226 + cdiv = (val & core->layout->div_mask) >> core->layout->div_shift; 227 + 228 + /* Stop if enabled an nothing changed. */ 229 + if (!!(val & core->layout->endiv_mask) && cdiv == div->div) 230 + goto unlock; 231 + 232 + regmap_update_bits(regmap, AT91_PMC_PLL_CTRL0, 233 + core->layout->div_mask | core->layout->endiv_mask, 234 + (div->div << core->layout->div_shift) | 235 + (1 << core->layout->endiv_shift)); 236 + 237 + regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, 238 + AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK, 239 + AT91_PMC_PLL_UPDT_UPDATE | core->id); 240 + 241 + while (!sam9x60_pll_ready(regmap, core->id)) 242 + cpu_relax(); 243 + 244 + unlock: 245 + spin_unlock_irqrestore(core->lock, flags); 246 + 247 + return 0; 248 + } 249 + 250 + static void sam9x60_div_pll_unprepare(struct clk_hw *hw) 251 + { 252 + struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw); 253 + struct regmap *regmap = core->regmap; 254 + unsigned long flags; 255 + 256 + spin_lock_irqsave(core->lock, flags); 257 + 258 + regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, 259 + AT91_PMC_PLL_UPDT_ID_MSK, core->id); 260 + 261 + regmap_update_bits(regmap, AT91_PMC_PLL_CTRL0, 262 + core->layout->endiv_mask, 0); 263 + 264 + regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, 265 + AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK, 266 + AT91_PMC_PLL_UPDT_UPDATE | core->id); 267 + 268 + spin_unlock_irqrestore(core->lock, flags); 269 + } 270 + 271 + static int sam9x60_div_pll_is_prepared(struct clk_hw *hw) 272 + { 273 + struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw); 274 + struct regmap *regmap = core->regmap; 275 + unsigned long flags; 276 + unsigned int val; 277 + 278 + spin_lock_irqsave(core->lock, flags); 279 + 280 + regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, 281 + AT91_PMC_PLL_UPDT_ID_MSK, core->id); 282 + regmap_read(regmap, AT91_PMC_PLL_CTRL0, &val); 283 + 284 + spin_unlock_irqrestore(core->lock, flags); 285 + 286 + return !!(val & core->layout->endiv_mask); 287 + } 288 + 289 + static unsigned long sam9x60_div_pll_recalc_rate(struct clk_hw *hw, 290 + unsigned long parent_rate) 291 + { 292 + struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw); 293 + struct sam9x60_div *div = to_sam9x60_div(core); 294 + 295 + return DIV_ROUND_CLOSEST_ULL(parent_rate, (div->div + 1)); 296 + } 297 + 298 + static long sam9x60_div_pll_compute_div(struct sam9x60_pll_core *core, 299 + unsigned long *parent_rate, 300 + unsigned long rate) 189 301 { 190 302 const struct clk_pll_characteristics *characteristics = 191 - pll->characteristics; 192 - unsigned long bestremainder = ULONG_MAX; 193 - unsigned long maxdiv, mindiv, tmpdiv; 194 - long bestrate = -ERANGE; 195 - unsigned long bestdiv = 0; 196 - unsigned long bestmul = 0; 197 - unsigned long bestfrac = 0; 303 + core->characteristics; 304 + struct clk_hw *parent = clk_hw_get_parent(&core->hw); 305 + unsigned long tmp_rate, tmp_parent_rate, tmp_diff; 306 + long best_diff = -1, best_rate = -EINVAL; 307 + u32 divid, best_div; 308 + 309 + if (!rate) 310 + return 0; 198 311 199 312 if (rate < characteristics->output[0].min || 200 313 rate > characteristics->output[0].max) 201 314 return -ERANGE; 202 315 203 - if (!pll->characteristics->upll) { 204 - mindiv = parent_rate / rate; 205 - if (mindiv < 2) 206 - mindiv = 2; 316 + for (divid = 1; divid < core->layout->div_mask; divid++) { 317 + tmp_parent_rate = clk_hw_round_rate(parent, rate * divid); 318 + if (!tmp_parent_rate) 319 + continue; 207 320 208 - maxdiv = DIV_ROUND_UP(parent_rate * PLL_MUL_MAX, rate); 209 - if (maxdiv > PLL_DIV_MAX) 210 - maxdiv = PLL_DIV_MAX; 211 - } else { 212 - mindiv = maxdiv = UPLL_DIV; 213 - } 321 + tmp_rate = DIV_ROUND_CLOSEST_ULL(tmp_parent_rate, divid); 322 + tmp_diff = abs(rate - tmp_rate); 214 323 215 - for (tmpdiv = mindiv; tmpdiv <= maxdiv; tmpdiv++) { 216 - unsigned long remainder; 217 - unsigned long tmprate; 218 - unsigned long tmpmul; 219 - unsigned long tmpfrac = 0; 220 - 221 - /* 222 - * Calculate the multiplier associated with the current 223 - * divider that provide the closest rate to the requested one. 224 - */ 225 - tmpmul = mult_frac(rate, tmpdiv, parent_rate); 226 - tmprate = mult_frac(parent_rate, tmpmul, tmpdiv); 227 - remainder = rate - tmprate; 228 - 229 - if (remainder) { 230 - tmpfrac = DIV_ROUND_CLOSEST_ULL((u64)remainder * tmpdiv * (1 << 22), 231 - parent_rate); 232 - 233 - tmprate += DIV_ROUND_CLOSEST_ULL((u64)tmpfrac * parent_rate, 234 - tmpdiv * (1 << 22)); 235 - 236 - if (tmprate > rate) 237 - remainder = tmprate - rate; 238 - else 239 - remainder = rate - tmprate; 324 + if (best_diff < 0 || best_diff > tmp_diff) { 325 + *parent_rate = tmp_parent_rate; 326 + best_rate = tmp_rate; 327 + best_diff = tmp_diff; 328 + best_div = divid; 240 329 } 241 330 242 - /* 243 - * Compare the remainder with the best remainder found until 244 - * now and elect a new best multiplier/divider pair if the 245 - * current remainder is smaller than the best one. 246 - */ 247 - if (remainder < bestremainder) { 248 - bestremainder = remainder; 249 - bestdiv = tmpdiv; 250 - bestmul = tmpmul; 251 - bestrate = tmprate; 252 - bestfrac = tmpfrac; 253 - } 254 - 255 - /* We've found a perfect match! */ 256 - if (!remainder) 331 + if (!best_diff) 257 332 break; 258 333 } 259 334 260 - /* Check if bestrate is a valid output rate */ 261 - if (bestrate < characteristics->output[0].min && 262 - bestrate > characteristics->output[0].max) 335 + if (best_rate < characteristics->output[0].min || 336 + best_rate > characteristics->output[0].max) 263 337 return -ERANGE; 264 338 265 - if (update) { 266 - pll->div = bestdiv - 1; 267 - pll->mul = bestmul - 1; 268 - pll->frac = bestfrac; 269 - } 270 - 271 - return bestrate; 339 + return best_rate; 272 340 } 273 341 274 - static long sam9x60_pll_round_rate(struct clk_hw *hw, unsigned long rate, 275 - unsigned long *parent_rate) 342 + static long sam9x60_div_pll_round_rate(struct clk_hw *hw, unsigned long rate, 343 + unsigned long *parent_rate) 276 344 { 277 - struct sam9x60_pll *pll = to_sam9x60_pll(hw); 345 + struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw); 278 346 279 - return sam9x60_pll_get_best_div_mul(pll, rate, *parent_rate, false); 347 + return sam9x60_div_pll_compute_div(core, parent_rate, rate); 280 348 } 281 349 282 - static int sam9x60_pll_set_rate(struct clk_hw *hw, unsigned long rate, 283 - unsigned long parent_rate) 350 + static int sam9x60_div_pll_set_rate(struct clk_hw *hw, unsigned long rate, 351 + unsigned long parent_rate) 284 352 { 285 - struct sam9x60_pll *pll = to_sam9x60_pll(hw); 353 + struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw); 354 + struct sam9x60_div *div = to_sam9x60_div(core); 286 355 287 - return sam9x60_pll_get_best_div_mul(pll, rate, parent_rate, true); 356 + div->div = DIV_ROUND_CLOSEST(parent_rate, rate) - 1; 357 + 358 + return 0; 288 359 } 289 360 290 - static const struct clk_ops pll_ops = { 291 - .prepare = sam9x60_pll_prepare, 292 - .unprepare = sam9x60_pll_unprepare, 293 - .is_prepared = sam9x60_pll_is_prepared, 294 - .recalc_rate = sam9x60_pll_recalc_rate, 295 - .round_rate = sam9x60_pll_round_rate, 296 - .set_rate = sam9x60_pll_set_rate, 361 + static const struct clk_ops sam9x60_div_pll_ops = { 362 + .prepare = sam9x60_div_pll_prepare, 363 + .unprepare = sam9x60_div_pll_unprepare, 364 + .is_prepared = sam9x60_div_pll_is_prepared, 365 + .recalc_rate = sam9x60_div_pll_recalc_rate, 366 + .round_rate = sam9x60_div_pll_round_rate, 367 + .set_rate = sam9x60_div_pll_set_rate, 297 368 }; 298 369 299 370 struct clk_hw * __init 300 - sam9x60_clk_register_pll(struct regmap *regmap, spinlock_t *lock, 301 - const char *name, const char *parent_name, u8 id, 302 - const struct clk_pll_characteristics *characteristics) 371 + sam9x60_clk_register_frac_pll(struct regmap *regmap, spinlock_t *lock, 372 + const char *name, const char *parent_name, 373 + struct clk_hw *parent_hw, u8 id, 374 + const struct clk_pll_characteristics *characteristics, 375 + const struct clk_pll_layout *layout, bool critical) 303 376 { 304 - struct sam9x60_pll *pll; 377 + struct sam9x60_frac *frac; 305 378 struct clk_hw *hw; 306 379 struct clk_init_data init; 307 - unsigned int pllr; 380 + unsigned long parent_rate, flags; 381 + unsigned int val; 308 382 int ret; 309 383 310 - if (id > PLL_MAX_ID) 384 + if (id > PLL_MAX_ID || !lock || !parent_hw) 311 385 return ERR_PTR(-EINVAL); 312 386 313 - pll = kzalloc(sizeof(*pll), GFP_KERNEL); 314 - if (!pll) 387 + frac = kzalloc(sizeof(*frac), GFP_KERNEL); 388 + if (!frac) 315 389 return ERR_PTR(-ENOMEM); 316 390 317 391 init.name = name; 318 - init.ops = &pll_ops; 319 392 init.parent_names = &parent_name; 320 393 init.num_parents = 1; 394 + init.ops = &sam9x60_frac_pll_ops; 321 395 init.flags = CLK_SET_RATE_GATE; 396 + if (critical) 397 + init.flags |= CLK_IS_CRITICAL; 322 398 323 - pll->id = id; 324 - pll->hw.init = &init; 325 - pll->characteristics = characteristics; 326 - pll->regmap = regmap; 327 - pll->lock = lock; 399 + frac->core.id = id; 400 + frac->core.hw.init = &init; 401 + frac->core.characteristics = characteristics; 402 + frac->core.layout = layout; 403 + frac->core.regmap = regmap; 404 + frac->core.lock = lock; 328 405 329 - regmap_write(regmap, AT91_PMC_PLL_UPDT, id); 330 - regmap_read(regmap, AT91_PMC_PLL_CTRL0, &pllr); 331 - pll->div = FIELD_GET(PMC_PLL_CTRL0_DIV_MSK, pllr); 332 - regmap_read(regmap, AT91_PMC_PLL_CTRL1, &pllr); 333 - pll->mul = FIELD_GET(PMC_PLL_CTRL1_MUL_MSK, pllr); 406 + spin_lock_irqsave(frac->core.lock, flags); 407 + if (sam9x60_pll_ready(regmap, id)) { 408 + regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, 409 + AT91_PMC_PLL_UPDT_ID_MSK, id); 410 + regmap_read(regmap, AT91_PMC_PLL_CTRL1, &val); 411 + frac->mul = FIELD_GET(PMC_PLL_CTRL1_MUL_MSK, val); 412 + frac->frac = FIELD_GET(PMC_PLL_CTRL1_FRACR_MSK, val); 413 + } else { 414 + /* 415 + * This means the PLL is not setup by bootloaders. In this 416 + * case we need to set the minimum rate for it. Otherwise 417 + * a clock child of this PLL may be enabled before setting 418 + * its rate leading to enabling this PLL with unsupported 419 + * rate. This will lead to PLL not being locked at all. 420 + */ 421 + parent_rate = clk_hw_get_rate(parent_hw); 422 + if (!parent_rate) { 423 + hw = ERR_PTR(-EINVAL); 424 + goto free; 425 + } 334 426 335 - hw = &pll->hw; 427 + ret = sam9x60_frac_pll_compute_mul_frac(&frac->core, FCORE_MIN, 428 + parent_rate, true); 429 + if (ret <= 0) { 430 + hw = ERR_PTR(ret); 431 + goto free; 432 + } 433 + } 434 + spin_unlock_irqrestore(frac->core.lock, flags); 435 + 436 + hw = &frac->core.hw; 336 437 ret = clk_hw_register(NULL, hw); 337 438 if (ret) { 338 - kfree(pll); 439 + kfree(frac); 440 + hw = ERR_PTR(ret); 441 + } 442 + 443 + return hw; 444 + 445 + free: 446 + spin_unlock_irqrestore(frac->core.lock, flags); 447 + kfree(frac); 448 + return hw; 449 + } 450 + 451 + struct clk_hw * __init 452 + sam9x60_clk_register_div_pll(struct regmap *regmap, spinlock_t *lock, 453 + const char *name, const char *parent_name, u8 id, 454 + const struct clk_pll_characteristics *characteristics, 455 + const struct clk_pll_layout *layout, bool critical) 456 + { 457 + struct sam9x60_div *div; 458 + struct clk_hw *hw; 459 + struct clk_init_data init; 460 + unsigned long flags; 461 + unsigned int val; 462 + int ret; 463 + 464 + if (id > PLL_MAX_ID || !lock) 465 + return ERR_PTR(-EINVAL); 466 + 467 + div = kzalloc(sizeof(*div), GFP_KERNEL); 468 + if (!div) 469 + return ERR_PTR(-ENOMEM); 470 + 471 + init.name = name; 472 + init.parent_names = &parent_name; 473 + init.num_parents = 1; 474 + init.ops = &sam9x60_div_pll_ops; 475 + init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | 476 + CLK_SET_RATE_PARENT; 477 + if (critical) 478 + init.flags |= CLK_IS_CRITICAL; 479 + 480 + div->core.id = id; 481 + div->core.hw.init = &init; 482 + div->core.characteristics = characteristics; 483 + div->core.layout = layout; 484 + div->core.regmap = regmap; 485 + div->core.lock = lock; 486 + 487 + spin_lock_irqsave(div->core.lock, flags); 488 + 489 + regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, 490 + AT91_PMC_PLL_UPDT_ID_MSK, id); 491 + regmap_read(regmap, AT91_PMC_PLL_CTRL0, &val); 492 + div->div = FIELD_GET(PMC_PLL_CTRL0_DIV_MSK, val); 493 + 494 + spin_unlock_irqrestore(div->core.lock, flags); 495 + 496 + hw = &div->core.hw; 497 + ret = clk_hw_register(NULL, hw); 498 + if (ret) { 499 + kfree(div); 339 500 hw = ERR_PTR(ret); 340 501 } 341 502
+2 -2
drivers/clk/at91/clk-system.c
··· 34 34 35 35 regmap_read(regmap, AT91_PMC_SR, &status); 36 36 37 - return status & (1 << id) ? 1 : 0; 37 + return !!(status & (1 << id)); 38 38 } 39 39 40 40 static int clk_system_prepare(struct clk_hw *hw) ··· 74 74 75 75 regmap_read(sys->regmap, AT91_PMC_SR, &status); 76 76 77 - return status & (1 << sys->id) ? 1 : 0; 77 + return !!(status & (1 << sys->id)); 78 78 } 79 79 80 80 static const struct clk_ops system_ops = {
+98 -5
drivers/clk/at91/clk-utmi.c
··· 120 120 .recalc_rate = clk_utmi_recalc_rate, 121 121 }; 122 122 123 - struct clk_hw * __init 124 - at91_clk_register_utmi(struct regmap *regmap_pmc, struct regmap *regmap_sfr, 125 - const char *name, const char *parent_name) 123 + static struct clk_hw * __init 124 + at91_clk_register_utmi_internal(struct regmap *regmap_pmc, 125 + struct regmap *regmap_sfr, 126 + const char *name, const char *parent_name, 127 + const struct clk_ops *ops, unsigned long flags) 126 128 { 127 129 struct clk_utmi *utmi; 128 130 struct clk_hw *hw; ··· 136 134 return ERR_PTR(-ENOMEM); 137 135 138 136 init.name = name; 139 - init.ops = &utmi_ops; 137 + init.ops = ops; 140 138 init.parent_names = parent_name ? &parent_name : NULL; 141 139 init.num_parents = parent_name ? 1 : 0; 142 - init.flags = CLK_SET_RATE_GATE; 140 + init.flags = flags; 143 141 144 142 utmi->hw.init = &init; 145 143 utmi->regmap_pmc = regmap_pmc; ··· 153 151 } 154 152 155 153 return hw; 154 + } 155 + 156 + struct clk_hw * __init 157 + at91_clk_register_utmi(struct regmap *regmap_pmc, struct regmap *regmap_sfr, 158 + const char *name, const char *parent_name) 159 + { 160 + return at91_clk_register_utmi_internal(regmap_pmc, regmap_sfr, name, 161 + parent_name, &utmi_ops, CLK_SET_RATE_GATE); 162 + } 163 + 164 + static int clk_utmi_sama7g5_prepare(struct clk_hw *hw) 165 + { 166 + struct clk_utmi *utmi = to_clk_utmi(hw); 167 + struct clk_hw *hw_parent; 168 + unsigned long parent_rate; 169 + unsigned int val; 170 + 171 + hw_parent = clk_hw_get_parent(hw); 172 + parent_rate = clk_hw_get_rate(hw_parent); 173 + 174 + switch (parent_rate) { 175 + case 16000000: 176 + val = 0; 177 + break; 178 + case 20000000: 179 + val = 2; 180 + break; 181 + case 24000000: 182 + val = 3; 183 + break; 184 + case 32000000: 185 + val = 5; 186 + break; 187 + default: 188 + pr_err("UTMICK: unsupported main_xtal rate\n"); 189 + return -EINVAL; 190 + } 191 + 192 + regmap_write(utmi->regmap_pmc, AT91_PMC_XTALF, val); 193 + 194 + return 0; 195 + 196 + } 197 + 198 + static int clk_utmi_sama7g5_is_prepared(struct clk_hw *hw) 199 + { 200 + struct clk_utmi *utmi = to_clk_utmi(hw); 201 + struct clk_hw *hw_parent; 202 + unsigned long parent_rate; 203 + unsigned int val; 204 + 205 + hw_parent = clk_hw_get_parent(hw); 206 + parent_rate = clk_hw_get_rate(hw_parent); 207 + 208 + regmap_read(utmi->regmap_pmc, AT91_PMC_XTALF, &val); 209 + switch (val & 0x7) { 210 + case 0: 211 + if (parent_rate == 16000000) 212 + return 1; 213 + break; 214 + case 2: 215 + if (parent_rate == 20000000) 216 + return 1; 217 + break; 218 + case 3: 219 + if (parent_rate == 24000000) 220 + return 1; 221 + break; 222 + case 5: 223 + if (parent_rate == 32000000) 224 + return 1; 225 + break; 226 + default: 227 + break; 228 + } 229 + 230 + return 0; 231 + } 232 + 233 + static const struct clk_ops sama7g5_utmi_ops = { 234 + .prepare = clk_utmi_sama7g5_prepare, 235 + .is_prepared = clk_utmi_sama7g5_is_prepared, 236 + .recalc_rate = clk_utmi_recalc_rate, 237 + }; 238 + 239 + struct clk_hw * __init 240 + at91_clk_sama7g5_register_utmi(struct regmap *regmap_pmc, const char *name, 241 + const char *parent_name) 242 + { 243 + return at91_clk_register_utmi_internal(regmap_pmc, NULL, name, 244 + parent_name, &sama7g5_utmi_ops, 0); 156 245 }
+15 -10
drivers/clk/at91/dt-compat.c
··· 22 22 23 23 #define SYSTEM_MAX_ID 31 24 24 25 + #define GCK_INDEX_DT_AUDIO_PLL 5 26 + 25 27 #ifdef CONFIG_HAVE_AT91_AUDIO_PLL 26 28 static void __init of_sama5d2_clk_audio_pll_frac_setup(struct device_node *np) 27 29 { ··· 137 135 return; 138 136 139 137 for_each_child_of_node(np, gcknp) { 140 - bool pll_audio = false; 138 + int chg_pid = INT_MIN; 141 139 142 140 if (of_property_read_u32(gcknp, "reg", &id)) 143 141 continue; ··· 154 152 if (of_device_is_compatible(np, "atmel,sama5d2-clk-generated") && 155 153 (id == GCK_ID_I2S0 || id == GCK_ID_I2S1 || 156 154 id == GCK_ID_CLASSD)) 157 - pll_audio = true; 155 + chg_pid = GCK_INDEX_DT_AUDIO_PLL; 158 156 159 157 hw = at91_clk_register_generated(regmap, &pmc_pcr_lock, 160 158 &dt_pcr_layout, name, 161 - parent_names, num_parents, 162 - id, pll_audio, &range); 159 + parent_names, NULL, 160 + num_parents, id, &range, 161 + chg_pid); 163 162 if (IS_ERR(hw)) 164 163 continue; 165 164 ··· 463 460 &dt_pcr_layout, 464 461 name, 465 462 parent_name, 466 - id, &range); 463 + id, &range, 464 + INT_MIN); 467 465 } 468 466 469 467 if (IS_ERR(hw)) ··· 677 673 678 674 static void __init 679 675 of_at91_clk_prog_setup(struct device_node *np, 680 - const struct clk_programmable_layout *layout) 676 + const struct clk_programmable_layout *layout, 677 + u32 *mux_table) 681 678 { 682 679 int num; 683 680 u32 id; ··· 712 707 713 708 hw = at91_clk_register_programmable(regmap, name, 714 709 parent_names, num_parents, 715 - id, layout); 710 + id, layout, mux_table); 716 711 if (IS_ERR(hw)) 717 712 continue; 718 713 ··· 722 717 723 718 static void __init of_at91rm9200_clk_prog_setup(struct device_node *np) 724 719 { 725 - of_at91_clk_prog_setup(np, &at91rm9200_programmable_layout); 720 + of_at91_clk_prog_setup(np, &at91rm9200_programmable_layout, NULL); 726 721 } 727 722 CLK_OF_DECLARE(at91rm9200_clk_prog, "atmel,at91rm9200-clk-programmable", 728 723 of_at91rm9200_clk_prog_setup); 729 724 730 725 static void __init of_at91sam9g45_clk_prog_setup(struct device_node *np) 731 726 { 732 - of_at91_clk_prog_setup(np, &at91sam9g45_programmable_layout); 727 + of_at91_clk_prog_setup(np, &at91sam9g45_programmable_layout, NULL); 733 728 } 734 729 CLK_OF_DECLARE(at91sam9g45_clk_prog, "atmel,at91sam9g45-clk-programmable", 735 730 of_at91sam9g45_clk_prog_setup); 736 731 737 732 static void __init of_at91sam9x5_clk_prog_setup(struct device_node *np) 738 733 { 739 - of_at91_clk_prog_setup(np, &at91sam9x5_programmable_layout); 734 + of_at91_clk_prog_setup(np, &at91sam9x5_programmable_layout, NULL); 740 735 } 741 736 CLK_OF_DECLARE(at91sam9x5_clk_prog, "atmel,at91sam9x5-clk-programmable", 742 737 of_at91sam9x5_clk_prog_setup);
+35 -8
drivers/clk/at91/pmc.h
··· 54 54 55 55 struct clk_pll_layout { 56 56 u32 pllr_mask; 57 - u16 mul_mask; 57 + u32 mul_mask; 58 + u32 frac_mask; 59 + u32 div_mask; 60 + u32 endiv_mask; 58 61 u8 mul_shift; 62 + u8 frac_shift; 63 + u8 div_shift; 64 + u8 endiv_shift; 59 65 }; 60 66 61 67 extern const struct clk_pll_layout at91rm9200_pll_layout; ··· 128 122 at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock, 129 123 const struct clk_pcr_layout *layout, 130 124 const char *name, const char **parent_names, 131 - u8 num_parents, u8 id, bool pll_audio, 132 - const struct clk_range *range); 125 + u32 *mux_table, u8 num_parents, u8 id, 126 + const struct clk_range *range, int chg_pid); 133 127 134 128 struct clk_hw * __init 135 129 at91_clk_register_h32mx(struct regmap *regmap, const char *name, ··· 161 155 const struct clk_master_characteristics *characteristics); 162 156 163 157 struct clk_hw * __init 158 + at91_clk_sama7g5_register_master(struct regmap *regmap, 159 + const char *name, int num_parents, 160 + const char **parent_names, u32 *mux_table, 161 + spinlock_t *lock, u8 id, bool critical, 162 + int chg_pid); 163 + 164 + struct clk_hw * __init 164 165 at91_clk_register_peripheral(struct regmap *regmap, const char *name, 165 166 const char *parent_name, u32 id); 166 167 struct clk_hw * __init 167 168 at91_clk_register_sam9x5_peripheral(struct regmap *regmap, spinlock_t *lock, 168 169 const struct clk_pcr_layout *layout, 169 170 const char *name, const char *parent_name, 170 - u32 id, const struct clk_range *range); 171 + u32 id, const struct clk_range *range, 172 + int chg_pid); 171 173 172 174 struct clk_hw * __init 173 175 at91_clk_register_pll(struct regmap *regmap, const char *name, ··· 187 173 const char *parent_name); 188 174 189 175 struct clk_hw * __init 190 - sam9x60_clk_register_pll(struct regmap *regmap, spinlock_t *lock, 191 - const char *name, const char *parent_name, u8 id, 192 - const struct clk_pll_characteristics *characteristics); 176 + sam9x60_clk_register_div_pll(struct regmap *regmap, spinlock_t *lock, 177 + const char *name, const char *parent_name, u8 id, 178 + const struct clk_pll_characteristics *characteristics, 179 + const struct clk_pll_layout *layout, bool critical); 180 + 181 + struct clk_hw * __init 182 + sam9x60_clk_register_frac_pll(struct regmap *regmap, spinlock_t *lock, 183 + const char *name, const char *parent_name, 184 + struct clk_hw *parent_hw, u8 id, 185 + const struct clk_pll_characteristics *characteristics, 186 + const struct clk_pll_layout *layout, bool critical); 193 187 194 188 struct clk_hw * __init 195 189 at91_clk_register_programmable(struct regmap *regmap, const char *name, 196 190 const char **parent_names, u8 num_parents, u8 id, 197 - const struct clk_programmable_layout *layout); 191 + const struct clk_programmable_layout *layout, 192 + u32 *mux_table); 198 193 199 194 struct clk_hw * __init 200 195 at91_clk_register_sam9260_slow(struct regmap *regmap, ··· 235 212 struct clk_hw * __init 236 213 at91_clk_register_utmi(struct regmap *regmap_pmc, struct regmap *regmap_sfr, 237 214 const char *name, const char *parent_name); 215 + 216 + struct clk_hw * __init 217 + at91_clk_sama7g5_register_utmi(struct regmap *regmap, const char *name, 218 + const char *parent_name); 238 219 239 220 #ifdef CONFIG_PM 240 221 void pmc_register_id(u8 id);
+49 -17
drivers/clk/at91/sam9x60.c
··· 22 22 }; 23 23 24 24 static const struct clk_range plla_outputs[] = { 25 - { .min = 300000000, .max = 600000000 }, 25 + { .min = 2343750, .max = 1200000000 }, 26 26 }; 27 27 28 28 static const struct clk_pll_characteristics plla_characteristics = { ··· 40 40 .num_output = ARRAY_SIZE(upll_outputs), 41 41 .output = upll_outputs, 42 42 .upll = true, 43 + }; 44 + 45 + static const struct clk_pll_layout pll_frac_layout = { 46 + .mul_mask = GENMASK(31, 24), 47 + .frac_mask = GENMASK(21, 0), 48 + .mul_shift = 24, 49 + .frac_shift = 0, 50 + }; 51 + 52 + static const struct clk_pll_layout pll_div_layout = { 53 + .div_mask = GENMASK(7, 0), 54 + .endiv_mask = BIT(29), 55 + .div_shift = 0, 56 + .endiv_shift = 29, 43 57 }; 44 58 45 59 static const struct clk_programmable_layout sam9x60_programmable_layout = { ··· 170 156 const char *td_slck_name, *md_slck_name, *mainxtal_name; 171 157 struct pmc_data *sam9x60_pmc; 172 158 const char *parent_names[6]; 159 + struct clk_hw *main_osc_hw; 173 160 struct regmap *regmap; 174 161 struct clk_hw *hw; 175 162 int i; ··· 193 178 return; 194 179 mainxtal_name = of_clk_get_parent_name(np, i); 195 180 196 - regmap = syscon_node_to_regmap(np); 181 + regmap = device_node_to_regmap(np); 197 182 if (IS_ERR(regmap)) 198 183 return; 199 184 ··· 204 189 if (!sam9x60_pmc) 205 190 return; 206 191 207 - hw = at91_clk_register_main_rc_osc(regmap, "main_rc_osc", 24000000, 192 + hw = at91_clk_register_main_rc_osc(regmap, "main_rc_osc", 12000000, 208 193 50000000); 209 194 if (IS_ERR(hw)) 210 195 goto err_free; ··· 215 200 bypass); 216 201 if (IS_ERR(hw)) 217 202 goto err_free; 203 + main_osc_hw = hw; 218 204 219 205 parent_names[0] = "main_rc_osc"; 220 206 parent_names[1] = "main_osc"; ··· 225 209 226 210 sam9x60_pmc->chws[PMC_MAIN] = hw; 227 211 228 - hw = sam9x60_clk_register_pll(regmap, &pmc_pll_lock, "pllack", 229 - "mainck", 0, &plla_characteristics); 212 + hw = sam9x60_clk_register_frac_pll(regmap, &pmc_pll_lock, "pllack_fracck", 213 + "mainck", sam9x60_pmc->chws[PMC_MAIN], 214 + 0, &plla_characteristics, 215 + &pll_frac_layout, true); 216 + if (IS_ERR(hw)) 217 + goto err_free; 218 + 219 + hw = sam9x60_clk_register_div_pll(regmap, &pmc_pll_lock, "pllack_divck", 220 + "pllack_fracck", 0, &plla_characteristics, 221 + &pll_div_layout, true); 230 222 if (IS_ERR(hw)) 231 223 goto err_free; 232 224 233 225 sam9x60_pmc->chws[PMC_PLLACK] = hw; 234 226 235 - hw = sam9x60_clk_register_pll(regmap, &pmc_pll_lock, "upllck", 236 - "main_osc", 1, &upll_characteristics); 227 + hw = sam9x60_clk_register_frac_pll(regmap, &pmc_pll_lock, "upllck_fracck", 228 + "main_osc", main_osc_hw, 1, 229 + &upll_characteristics, 230 + &pll_frac_layout, false); 231 + if (IS_ERR(hw)) 232 + goto err_free; 233 + 234 + hw = sam9x60_clk_register_div_pll(regmap, &pmc_pll_lock, "upllck_divck", 235 + "upllck_fracck", 1, &upll_characteristics, 236 + &pll_div_layout, false); 237 237 if (IS_ERR(hw)) 238 238 goto err_free; 239 239 ··· 257 225 258 226 parent_names[0] = md_slck_name; 259 227 parent_names[1] = "mainck"; 260 - parent_names[2] = "pllack"; 228 + parent_names[2] = "pllack_divck"; 261 229 hw = at91_clk_register_master(regmap, "masterck", 3, parent_names, 262 230 &sam9x60_master_layout, 263 231 &mck_characteristics); ··· 266 234 267 235 sam9x60_pmc->chws[PMC_MCK] = hw; 268 236 269 - parent_names[0] = "pllack"; 270 - parent_names[1] = "upllck"; 237 + parent_names[0] = "pllack_divck"; 238 + parent_names[1] = "upllck_divck"; 271 239 parent_names[2] = "main_osc"; 272 240 hw = sam9x60_clk_register_usb(regmap, "usbck", parent_names, 3); 273 241 if (IS_ERR(hw)) ··· 277 245 parent_names[1] = td_slck_name; 278 246 parent_names[2] = "mainck"; 279 247 parent_names[3] = "masterck"; 280 - parent_names[4] = "pllack"; 281 - parent_names[5] = "upllck"; 248 + parent_names[4] = "pllack_divck"; 249 + parent_names[5] = "upllck_divck"; 282 250 for (i = 0; i < 8; i++) { 283 251 char name[6]; 284 252 ··· 286 254 287 255 hw = at91_clk_register_programmable(regmap, name, 288 256 parent_names, 6, i, 289 - &sam9x60_programmable_layout); 257 + &sam9x60_programmable_layout, 258 + NULL); 290 259 if (IS_ERR(hw)) 291 260 goto err_free; 292 261 ··· 310 277 sam9x60_periphck[i].n, 311 278 "masterck", 312 279 sam9x60_periphck[i].id, 313 - &range); 280 + &range, INT_MIN); 314 281 if (IS_ERR(hw)) 315 282 goto err_free; 316 283 ··· 321 288 hw = at91_clk_register_generated(regmap, &pmc_pcr_lock, 322 289 &sam9x60_pcr_layout, 323 290 sam9x60_gck[i].n, 324 - parent_names, 6, 291 + parent_names, NULL, 6, 325 292 sam9x60_gck[i].id, 326 - false, 327 - &sam9x60_gck[i].r); 293 + &sam9x60_gck[i].r, INT_MIN); 328 294 if (IS_ERR(hw)) 329 295 goto err_free; 330 296
+21 -20
drivers/clk/at91/sama5d2.c
··· 116 116 char *n; 117 117 u8 id; 118 118 struct clk_range r; 119 - bool pll; 119 + int chg_pid; 120 120 } sama5d2_gck[] = { 121 - { .n = "sdmmc0_gclk", .id = 31, }, 122 - { .n = "sdmmc1_gclk", .id = 32, }, 123 - { .n = "tcb0_gclk", .id = 35, .r = { .min = 0, .max = 83000000 }, }, 124 - { .n = "tcb1_gclk", .id = 36, .r = { .min = 0, .max = 83000000 }, }, 125 - { .n = "pwm_gclk", .id = 38, .r = { .min = 0, .max = 83000000 }, }, 126 - { .n = "isc_gclk", .id = 46, }, 127 - { .n = "pdmic_gclk", .id = 48, }, 128 - { .n = "i2s0_gclk", .id = 54, .pll = true }, 129 - { .n = "i2s1_gclk", .id = 55, .pll = true }, 130 - { .n = "can0_gclk", .id = 56, .r = { .min = 0, .max = 80000000 }, }, 131 - { .n = "can1_gclk", .id = 57, .r = { .min = 0, .max = 80000000 }, }, 132 - { .n = "classd_gclk", .id = 59, .r = { .min = 0, .max = 100000000 }, 133 - .pll = true }, 121 + { .n = "sdmmc0_gclk", .id = 31, .chg_pid = INT_MIN, }, 122 + { .n = "sdmmc1_gclk", .id = 32, .chg_pid = INT_MIN, }, 123 + { .n = "tcb0_gclk", .id = 35, .chg_pid = INT_MIN, .r = { .min = 0, .max = 83000000 }, }, 124 + { .n = "tcb1_gclk", .id = 36, .chg_pid = INT_MIN, .r = { .min = 0, .max = 83000000 }, }, 125 + { .n = "pwm_gclk", .id = 38, .chg_pid = INT_MIN, .r = { .min = 0, .max = 83000000 }, }, 126 + { .n = "isc_gclk", .id = 46, .chg_pid = INT_MIN, }, 127 + { .n = "pdmic_gclk", .id = 48, .chg_pid = INT_MIN, }, 128 + { .n = "i2s0_gclk", .id = 54, .chg_pid = 5, }, 129 + { .n = "i2s1_gclk", .id = 55, .chg_pid = 5, }, 130 + { .n = "can0_gclk", .id = 56, .chg_pid = INT_MIN, .r = { .min = 0, .max = 80000000 }, }, 131 + { .n = "can1_gclk", .id = 57, .chg_pid = INT_MIN, .r = { .min = 0, .max = 80000000 }, }, 132 + { .n = "classd_gclk", .id = 59, .chg_pid = 5, .r = { .min = 0, .max = 100000000 }, }, 134 133 }; 135 134 136 135 static const struct clk_programmable_layout sama5d2_programmable_layout = { ··· 268 269 269 270 hw = at91_clk_register_programmable(regmap, name, 270 271 parent_names, 6, i, 271 - &sama5d2_programmable_layout); 272 + &sama5d2_programmable_layout, 273 + NULL); 272 274 if (IS_ERR(hw)) 273 275 goto err_free; 274 276 ··· 292 292 sama5d2_periphck[i].n, 293 293 "masterck", 294 294 sama5d2_periphck[i].id, 295 - &range); 295 + &range, INT_MIN); 296 296 if (IS_ERR(hw)) 297 297 goto err_free; 298 298 ··· 305 305 sama5d2_periph32ck[i].n, 306 306 "h32mxck", 307 307 sama5d2_periph32ck[i].id, 308 - &sama5d2_periph32ck[i].r); 308 + &sama5d2_periph32ck[i].r, 309 + INT_MIN); 309 310 if (IS_ERR(hw)) 310 311 goto err_free; 311 312 ··· 323 322 hw = at91_clk_register_generated(regmap, &pmc_pcr_lock, 324 323 &sama5d2_pcr_layout, 325 324 sama5d2_gck[i].n, 326 - parent_names, 6, 325 + parent_names, NULL, 6, 327 326 sama5d2_gck[i].id, 328 - sama5d2_gck[i].pll, 329 - &sama5d2_gck[i].r); 327 + &sama5d2_gck[i].r, 328 + sama5d2_gck[i].chg_pid); 330 329 if (IS_ERR(hw)) 331 330 goto err_free; 332 331
+5 -3
drivers/clk/at91/sama5d3.c
··· 121 121 return; 122 122 mainxtal_name = of_clk_get_parent_name(np, i); 123 123 124 - regmap = syscon_node_to_regmap(np); 124 + regmap = device_node_to_regmap(np); 125 125 if (IS_ERR(regmap)) 126 126 return; 127 127 ··· 200 200 201 201 hw = at91_clk_register_programmable(regmap, name, 202 202 parent_names, 5, i, 203 - &at91sam9x5_programmable_layout); 203 + &at91sam9x5_programmable_layout, 204 + NULL); 204 205 if (IS_ERR(hw)) 205 206 goto err_free; 206 207 ··· 224 223 sama5d3_periphck[i].n, 225 224 "masterck", 226 225 sama5d3_periphck[i].id, 227 - &sama5d3_periphck[i].r); 226 + &sama5d3_periphck[i].r, 227 + INT_MIN); 228 228 if (IS_ERR(hw)) 229 229 goto err_free; 230 230
+4 -3
drivers/clk/at91/sama5d4.c
··· 223 223 224 224 hw = at91_clk_register_programmable(regmap, name, 225 225 parent_names, 5, i, 226 - &at91sam9x5_programmable_layout); 226 + &at91sam9x5_programmable_layout, 227 + NULL); 227 228 if (IS_ERR(hw)) 228 229 goto err_free; 229 230 ··· 247 246 sama5d4_periphck[i].n, 248 247 "masterck", 249 248 sama5d4_periphck[i].id, 250 - &range); 249 + &range, INT_MIN); 251 250 if (IS_ERR(hw)) 252 251 goto err_free; 253 252 ··· 260 259 sama5d4_periph32ck[i].n, 261 260 "h32mxck", 262 261 sama5d4_periph32ck[i].id, 263 - &range); 262 + &range, INT_MIN); 264 263 if (IS_ERR(hw)) 265 264 goto err_free; 266 265
+1059
drivers/clk/at91/sama7g5.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * SAMA7G5 PMC code. 4 + * 5 + * Copyright (C) 2020 Microchip Technology Inc. and its subsidiaries 6 + * 7 + * Author: Claudiu Beznea <claudiu.beznea@microchip.com> 8 + * 9 + */ 10 + #include <linux/clk.h> 11 + #include <linux/clk-provider.h> 12 + #include <linux/mfd/syscon.h> 13 + #include <linux/slab.h> 14 + 15 + #include <dt-bindings/clock/at91.h> 16 + 17 + #include "pmc.h" 18 + 19 + #define SAMA7G5_INIT_TABLE(_table, _count) \ 20 + do { \ 21 + u8 _i; \ 22 + for (_i = 0; _i < (_count); _i++) \ 23 + (_table)[_i] = _i; \ 24 + } while (0) 25 + 26 + #define SAMA7G5_FILL_TABLE(_to, _from, _count) \ 27 + do { \ 28 + u8 _i; \ 29 + for (_i = 0; _i < (_count); _i++) { \ 30 + (_to)[_i] = (_from)[_i]; \ 31 + } \ 32 + } while (0) 33 + 34 + static DEFINE_SPINLOCK(pmc_pll_lock); 35 + static DEFINE_SPINLOCK(pmc_mckX_lock); 36 + 37 + /** 38 + * PLL clocks identifiers 39 + * @PLL_ID_CPU: CPU PLL identifier 40 + * @PLL_ID_SYS: System PLL identifier 41 + * @PLL_ID_DDR: DDR PLL identifier 42 + * @PLL_ID_IMG: Image subsystem PLL identifier 43 + * @PLL_ID_BAUD: Baud PLL identifier 44 + * @PLL_ID_AUDIO: Audio PLL identifier 45 + * @PLL_ID_ETH: Ethernet PLL identifier 46 + */ 47 + enum pll_ids { 48 + PLL_ID_CPU, 49 + PLL_ID_SYS, 50 + PLL_ID_DDR, 51 + PLL_ID_IMG, 52 + PLL_ID_BAUD, 53 + PLL_ID_AUDIO, 54 + PLL_ID_ETH, 55 + PLL_ID_MAX, 56 + }; 57 + 58 + /** 59 + * PLL type identifiers 60 + * @PLL_TYPE_FRAC: fractional PLL identifier 61 + * @PLL_TYPE_DIV: divider PLL identifier 62 + */ 63 + enum pll_type { 64 + PLL_TYPE_FRAC, 65 + PLL_TYPE_DIV, 66 + }; 67 + 68 + /* Layout for fractional PLLs. */ 69 + static const struct clk_pll_layout pll_layout_frac = { 70 + .mul_mask = GENMASK(31, 24), 71 + .frac_mask = GENMASK(21, 0), 72 + .mul_shift = 24, 73 + .frac_shift = 0, 74 + }; 75 + 76 + /* Layout for DIVPMC dividers. */ 77 + static const struct clk_pll_layout pll_layout_divpmc = { 78 + .div_mask = GENMASK(7, 0), 79 + .endiv_mask = BIT(29), 80 + .div_shift = 0, 81 + .endiv_shift = 29, 82 + }; 83 + 84 + /* Layout for DIVIO dividers. */ 85 + static const struct clk_pll_layout pll_layout_divio = { 86 + .div_mask = GENMASK(19, 12), 87 + .endiv_mask = BIT(30), 88 + .div_shift = 12, 89 + .endiv_shift = 30, 90 + }; 91 + 92 + /** 93 + * PLL clocks description 94 + * @n: clock name 95 + * @p: clock parent 96 + * @l: clock layout 97 + * @t: clock type 98 + * @f: true if clock is critical and cannot be disabled 99 + * @eid: export index in sama7g5->chws[] array 100 + */ 101 + static const struct { 102 + const char *n; 103 + const char *p; 104 + const struct clk_pll_layout *l; 105 + u8 t; 106 + u8 c; 107 + u8 eid; 108 + } sama7g5_plls[][PLL_ID_MAX] = { 109 + [PLL_ID_CPU] = { 110 + { .n = "cpupll_fracck", 111 + .p = "mainck", 112 + .l = &pll_layout_frac, 113 + .t = PLL_TYPE_FRAC, 114 + .c = 1, }, 115 + 116 + { .n = "cpupll_divpmcck", 117 + .p = "cpupll_fracck", 118 + .l = &pll_layout_divpmc, 119 + .t = PLL_TYPE_DIV, 120 + .c = 1, }, 121 + }, 122 + 123 + [PLL_ID_SYS] = { 124 + { .n = "syspll_fracck", 125 + .p = "mainck", 126 + .l = &pll_layout_frac, 127 + .t = PLL_TYPE_FRAC, 128 + .c = 1, }, 129 + 130 + { .n = "syspll_divpmcck", 131 + .p = "syspll_fracck", 132 + .l = &pll_layout_divpmc, 133 + .t = PLL_TYPE_DIV, 134 + .c = 1, }, 135 + }, 136 + 137 + [PLL_ID_DDR] = { 138 + { .n = "ddrpll_fracck", 139 + .p = "mainck", 140 + .l = &pll_layout_frac, 141 + .t = PLL_TYPE_FRAC, 142 + .c = 1, }, 143 + 144 + { .n = "ddrpll_divpmcck", 145 + .p = "ddrpll_fracck", 146 + .l = &pll_layout_divpmc, 147 + .t = PLL_TYPE_DIV, 148 + .c = 1, }, 149 + }, 150 + 151 + [PLL_ID_IMG] = { 152 + { .n = "imgpll_fracck", 153 + .p = "mainck", 154 + .l = &pll_layout_frac, 155 + .t = PLL_TYPE_FRAC, }, 156 + 157 + { .n = "imgpll_divpmcck", 158 + .p = "imgpll_fracck", 159 + .l = &pll_layout_divpmc, 160 + .t = PLL_TYPE_DIV, }, 161 + }, 162 + 163 + [PLL_ID_BAUD] = { 164 + { .n = "baudpll_fracck", 165 + .p = "mainck", 166 + .l = &pll_layout_frac, 167 + .t = PLL_TYPE_FRAC, }, 168 + 169 + { .n = "baudpll_divpmcck", 170 + .p = "baudpll_fracck", 171 + .l = &pll_layout_divpmc, 172 + .t = PLL_TYPE_DIV, }, 173 + }, 174 + 175 + [PLL_ID_AUDIO] = { 176 + { .n = "audiopll_fracck", 177 + .p = "main_xtal", 178 + .l = &pll_layout_frac, 179 + .t = PLL_TYPE_FRAC, }, 180 + 181 + { .n = "audiopll_divpmcck", 182 + .p = "audiopll_fracck", 183 + .l = &pll_layout_divpmc, 184 + .t = PLL_TYPE_DIV, 185 + .eid = PMC_I2S0_MUX, }, 186 + 187 + { .n = "audiopll_diviock", 188 + .p = "audiopll_fracck", 189 + .l = &pll_layout_divio, 190 + .t = PLL_TYPE_DIV, 191 + .eid = PMC_I2S1_MUX, }, 192 + }, 193 + 194 + [PLL_ID_ETH] = { 195 + { .n = "ethpll_fracck", 196 + .p = "main_xtal", 197 + .l = &pll_layout_frac, 198 + .t = PLL_TYPE_FRAC, }, 199 + 200 + { .n = "ethpll_divpmcck", 201 + .p = "ethpll_fracck", 202 + .l = &pll_layout_divpmc, 203 + .t = PLL_TYPE_DIV, }, 204 + }, 205 + }; 206 + 207 + /** 208 + * Master clock (MCK[1..4]) description 209 + * @n: clock name 210 + * @ep: extra parents names array 211 + * @ep_chg_chg_id: index in parents array that specifies the changeable 212 + * parent 213 + * @ep_count: extra parents count 214 + * @ep_mux_table: mux table for extra parents 215 + * @id: clock id 216 + * @c: true if clock is critical and cannot be disabled 217 + */ 218 + static const struct { 219 + const char *n; 220 + const char *ep[4]; 221 + int ep_chg_id; 222 + u8 ep_count; 223 + u8 ep_mux_table[4]; 224 + u8 id; 225 + u8 c; 226 + } sama7g5_mckx[] = { 227 + { .n = "mck1", 228 + .id = 1, 229 + .ep = { "syspll_divpmcck", }, 230 + .ep_mux_table = { 5, }, 231 + .ep_count = 1, 232 + .ep_chg_id = INT_MIN, 233 + .c = 1, }, 234 + 235 + { .n = "mck2", 236 + .id = 2, 237 + .ep = { "ddrpll_divpmcck", }, 238 + .ep_mux_table = { 6, }, 239 + .ep_count = 1, 240 + .ep_chg_id = INT_MIN, 241 + .c = 1, }, 242 + 243 + { .n = "mck3", 244 + .id = 3, 245 + .ep = { "syspll_divpmcck", "ddrpll_divpmcck", "imgpll_divpmcck", }, 246 + .ep_mux_table = { 5, 6, 7, }, 247 + .ep_count = 3, 248 + .ep_chg_id = 6, }, 249 + 250 + { .n = "mck4", 251 + .id = 4, 252 + .ep = { "syspll_divpmcck", }, 253 + .ep_mux_table = { 5, }, 254 + .ep_count = 1, 255 + .ep_chg_id = INT_MIN, 256 + .c = 1, }, 257 + }; 258 + 259 + /** 260 + * System clock description 261 + * @n: clock name 262 + * @p: clock parent name 263 + * @id: clock id 264 + */ 265 + static const struct { 266 + const char *n; 267 + const char *p; 268 + u8 id; 269 + } sama7g5_systemck[] = { 270 + { .n = "pck0", .p = "prog0", .id = 8, }, 271 + { .n = "pck1", .p = "prog1", .id = 9, }, 272 + { .n = "pck2", .p = "prog2", .id = 10, }, 273 + { .n = "pck3", .p = "prog3", .id = 11, }, 274 + { .n = "pck4", .p = "prog4", .id = 12, }, 275 + { .n = "pck5", .p = "prog5", .id = 13, }, 276 + { .n = "pck6", .p = "prog6", .id = 14, }, 277 + { .n = "pck7", .p = "prog7", .id = 15, }, 278 + }; 279 + 280 + /* Mux table for programmable clocks. */ 281 + static u32 sama7g5_prog_mux_table[] = { 0, 1, 2, 3, 5, 6, 7, 8, 9, 10, }; 282 + 283 + /** 284 + * Peripheral clock description 285 + * @n: clock name 286 + * @p: clock parent name 287 + * @r: clock range values 288 + * @id: clock id 289 + * @chgp: index in parent array of the changeable parent 290 + */ 291 + static const struct { 292 + const char *n; 293 + const char *p; 294 + struct clk_range r; 295 + u8 chgp; 296 + u8 id; 297 + } sama7g5_periphck[] = { 298 + { .n = "pioA_clk", .p = "mck0", .id = 11, }, 299 + { .n = "sfr_clk", .p = "mck1", .id = 19, }, 300 + { .n = "hsmc_clk", .p = "mck1", .id = 21, }, 301 + { .n = "xdmac0_clk", .p = "mck1", .id = 22, }, 302 + { .n = "xdmac1_clk", .p = "mck1", .id = 23, }, 303 + { .n = "xdmac2_clk", .p = "mck1", .id = 24, }, 304 + { .n = "acc_clk", .p = "mck1", .id = 25, }, 305 + { .n = "aes_clk", .p = "mck1", .id = 27, }, 306 + { .n = "tzaesbasc_clk", .p = "mck1", .id = 28, }, 307 + { .n = "asrc_clk", .p = "mck1", .id = 30, .r = { .max = 200000000, }, }, 308 + { .n = "cpkcc_clk", .p = "mck0", .id = 32, }, 309 + { .n = "csi_clk", .p = "mck3", .id = 33, .r = { .max = 266000000, }, .chgp = 1, }, 310 + { .n = "csi2dc_clk", .p = "mck3", .id = 34, .r = { .max = 266000000, }, .chgp = 1, }, 311 + { .n = "eic_clk", .p = "mck1", .id = 37, }, 312 + { .n = "flex0_clk", .p = "mck1", .id = 38, }, 313 + { .n = "flex1_clk", .p = "mck1", .id = 39, }, 314 + { .n = "flex2_clk", .p = "mck1", .id = 40, }, 315 + { .n = "flex3_clk", .p = "mck1", .id = 41, }, 316 + { .n = "flex4_clk", .p = "mck1", .id = 42, }, 317 + { .n = "flex5_clk", .p = "mck1", .id = 43, }, 318 + { .n = "flex6_clk", .p = "mck1", .id = 44, }, 319 + { .n = "flex7_clk", .p = "mck1", .id = 45, }, 320 + { .n = "flex8_clk", .p = "mck1", .id = 46, }, 321 + { .n = "flex9_clk", .p = "mck1", .id = 47, }, 322 + { .n = "flex10_clk", .p = "mck1", .id = 48, }, 323 + { .n = "flex11_clk", .p = "mck1", .id = 49, }, 324 + { .n = "gmac0_clk", .p = "mck1", .id = 51, }, 325 + { .n = "gmac1_clk", .p = "mck1", .id = 52, }, 326 + { .n = "icm_clk", .p = "mck1", .id = 55, }, 327 + { .n = "isc_clk", .p = "mck3", .id = 56, .r = { .max = 266000000, }, .chgp = 1, }, 328 + { .n = "i2smcc0_clk", .p = "mck1", .id = 57, .r = { .max = 200000000, }, }, 329 + { .n = "i2smcc1_clk", .p = "mck1", .id = 58, .r = { .max = 200000000, }, }, 330 + { .n = "matrix_clk", .p = "mck1", .id = 60, }, 331 + { .n = "mcan0_clk", .p = "mck1", .id = 61, .r = { .max = 200000000, }, }, 332 + { .n = "mcan1_clk", .p = "mck1", .id = 62, .r = { .max = 200000000, }, }, 333 + { .n = "mcan2_clk", .p = "mck1", .id = 63, .r = { .max = 200000000, }, }, 334 + { .n = "mcan3_clk", .p = "mck1", .id = 64, .r = { .max = 200000000, }, }, 335 + { .n = "mcan4_clk", .p = "mck1", .id = 65, .r = { .max = 200000000, }, }, 336 + { .n = "mcan5_clk", .p = "mck1", .id = 66, .r = { .max = 200000000, }, }, 337 + { .n = "pdmc0_clk", .p = "mck1", .id = 68, .r = { .max = 200000000, }, }, 338 + { .n = "pdmc1_clk", .p = "mck1", .id = 69, .r = { .max = 200000000, }, }, 339 + { .n = "pit64b0_clk", .p = "mck1", .id = 70, }, 340 + { .n = "pit64b1_clk", .p = "mck1", .id = 71, }, 341 + { .n = "pit64b2_clk", .p = "mck1", .id = 72, }, 342 + { .n = "pit64b3_clk", .p = "mck1", .id = 73, }, 343 + { .n = "pit64b4_clk", .p = "mck1", .id = 74, }, 344 + { .n = "pit64b5_clk", .p = "mck1", .id = 75, }, 345 + { .n = "pwm_clk", .p = "mck1", .id = 77, }, 346 + { .n = "qspi0_clk", .p = "mck1", .id = 78, }, 347 + { .n = "qspi1_clk", .p = "mck1", .id = 79, }, 348 + { .n = "sdmmc0_clk", .p = "mck1", .id = 80, }, 349 + { .n = "sdmmc1_clk", .p = "mck1", .id = 81, }, 350 + { .n = "sdmmc2_clk", .p = "mck1", .id = 82, }, 351 + { .n = "sha_clk", .p = "mck1", .id = 83, }, 352 + { .n = "spdifrx_clk", .p = "mck1", .id = 84, .r = { .max = 200000000, }, }, 353 + { .n = "spdiftx_clk", .p = "mck1", .id = 85, .r = { .max = 200000000, }, }, 354 + { .n = "ssc0_clk", .p = "mck1", .id = 86, .r = { .max = 200000000, }, }, 355 + { .n = "ssc1_clk", .p = "mck1", .id = 87, .r = { .max = 200000000, }, }, 356 + { .n = "tcb0_ch0_clk", .p = "mck1", .id = 88, .r = { .max = 200000000, }, }, 357 + { .n = "tcb0_ch1_clk", .p = "mck1", .id = 89, .r = { .max = 200000000, }, }, 358 + { .n = "tcb0_ch2_clk", .p = "mck1", .id = 90, .r = { .max = 200000000, }, }, 359 + { .n = "tcb1_ch0_clk", .p = "mck1", .id = 91, .r = { .max = 200000000, }, }, 360 + { .n = "tcb1_ch1_clk", .p = "mck1", .id = 92, .r = { .max = 200000000, }, }, 361 + { .n = "tcb1_ch2_clk", .p = "mck1", .id = 93, .r = { .max = 200000000, }, }, 362 + { .n = "tcpca_clk", .p = "mck1", .id = 94, }, 363 + { .n = "tcpcb_clk", .p = "mck1", .id = 95, }, 364 + { .n = "tdes_clk", .p = "mck1", .id = 96, }, 365 + { .n = "trng_clk", .p = "mck1", .id = 97, }, 366 + { .n = "udphsa_clk", .p = "mck1", .id = 104, }, 367 + { .n = "udphsb_clk", .p = "mck1", .id = 105, }, 368 + { .n = "uhphs_clk", .p = "mck1", .id = 106, }, 369 + }; 370 + 371 + /** 372 + * Generic clock description 373 + * @n: clock name 374 + * @pp: PLL parents 375 + * @pp_mux_table: PLL parents mux table 376 + * @r: clock output range 377 + * @pp_chg_id: id in parrent array of changeable PLL parent 378 + * @pp_count: PLL parents count 379 + * @id: clock id 380 + */ 381 + static const struct { 382 + const char *n; 383 + const char *pp[8]; 384 + const char pp_mux_table[8]; 385 + struct clk_range r; 386 + int pp_chg_id; 387 + u8 pp_count; 388 + u8 id; 389 + } sama7g5_gck[] = { 390 + { .n = "adc_gclk", 391 + .id = 26, 392 + .r = { .max = 100000000, }, 393 + .pp = { "syspll_divpmcck", "imgpll_divpmcck", "audiopll_divpmcck", }, 394 + .pp_mux_table = { 5, 7, 9, }, 395 + .pp_count = 3, 396 + .pp_chg_id = INT_MIN, }, 397 + 398 + { .n = "asrc_gclk", 399 + .id = 30, 400 + .r = { .max = 200000000 }, 401 + .pp = { "audiopll_divpmcck", }, 402 + .pp_mux_table = { 9, }, 403 + .pp_count = 1, 404 + .pp_chg_id = 4, }, 405 + 406 + { .n = "csi_gclk", 407 + .id = 33, 408 + .r = { .max = 27000000 }, 409 + .pp = { "ddrpll_divpmcck", "imgpll_divpmcck", }, 410 + .pp_mux_table = { 6, 7, }, 411 + .pp_count = 2, 412 + .pp_chg_id = INT_MIN, }, 413 + 414 + { .n = "flex0_gclk", 415 + .id = 38, 416 + .r = { .max = 200000000 }, 417 + .pp = { "syspll_divpmcck", "baudpll_divpmcck", }, 418 + .pp_mux_table = { 5, 8, }, 419 + .pp_count = 2, 420 + .pp_chg_id = INT_MIN, }, 421 + 422 + { .n = "flex1_gclk", 423 + .id = 39, 424 + .r = { .max = 200000000 }, 425 + .pp = { "syspll_divpmcck", "baudpll_divpmcck", }, 426 + .pp_mux_table = { 5, 8, }, 427 + .pp_count = 2, 428 + .pp_chg_id = INT_MIN, }, 429 + 430 + { .n = "flex2_gclk", 431 + .id = 40, 432 + .r = { .max = 200000000 }, 433 + .pp = { "syspll_divpmcck", "baudpll_divpmcck", }, 434 + .pp_mux_table = { 5, 8, }, 435 + .pp_count = 2, 436 + .pp_chg_id = INT_MIN, }, 437 + 438 + { .n = "flex3_gclk", 439 + .id = 41, 440 + .r = { .max = 200000000 }, 441 + .pp = { "syspll_divpmcck", "baudpll_divpmcck", }, 442 + .pp_mux_table = { 5, 8, }, 443 + .pp_count = 2, 444 + .pp_chg_id = INT_MIN, }, 445 + 446 + { .n = "flex4_gclk", 447 + .id = 42, 448 + .r = { .max = 200000000 }, 449 + .pp = { "syspll_divpmcck", "baudpll_divpmcck", }, 450 + .pp_mux_table = { 5, 8, }, 451 + .pp_count = 2, 452 + .pp_chg_id = INT_MIN, }, 453 + 454 + { .n = "flex5_gclk", 455 + .id = 43, 456 + .r = { .max = 200000000 }, 457 + .pp = { "syspll_divpmcck", "baudpll_divpmcck", }, 458 + .pp_mux_table = { 5, 8, }, 459 + .pp_count = 2, 460 + .pp_chg_id = INT_MIN, }, 461 + 462 + { .n = "flex6_gclk", 463 + .id = 44, 464 + .r = { .max = 200000000 }, 465 + .pp = { "syspll_divpmcck", "baudpll_divpmcck", }, 466 + .pp_mux_table = { 5, 8, }, 467 + .pp_count = 2, 468 + .pp_chg_id = INT_MIN, }, 469 + 470 + { .n = "flex7_gclk", 471 + .id = 45, 472 + .r = { .max = 200000000 }, 473 + .pp = { "syspll_divpmcck", "baudpll_divpmcck", }, 474 + .pp_mux_table = { 5, 8, }, 475 + .pp_count = 2, 476 + .pp_chg_id = INT_MIN, }, 477 + 478 + { .n = "flex8_gclk", 479 + .id = 46, 480 + .r = { .max = 200000000 }, 481 + .pp = { "syspll_divpmcck", "baudpll_divpmcck", }, 482 + .pp_mux_table = { 5, 8, }, 483 + .pp_count = 2, 484 + .pp_chg_id = INT_MIN, }, 485 + 486 + { .n = "flex9_gclk", 487 + .id = 47, 488 + .r = { .max = 200000000 }, 489 + .pp = { "syspll_divpmcck", "baudpll_divpmcck", }, 490 + .pp_mux_table = { 5, 8, }, 491 + .pp_count = 2, 492 + .pp_chg_id = INT_MIN, }, 493 + 494 + { .n = "flex10_gclk", 495 + .id = 48, 496 + .r = { .max = 200000000 }, 497 + .pp = { "syspll_divpmcck", "baudpll_divpmcck", }, 498 + .pp_mux_table = { 5, 8, }, 499 + .pp_count = 2, 500 + .pp_chg_id = INT_MIN, }, 501 + 502 + { .n = "flex11_gclk", 503 + .id = 49, 504 + .r = { .max = 200000000 }, 505 + .pp = { "syspll_divpmcck", "baudpll_divpmcck", }, 506 + .pp_mux_table = { 5, 8, }, 507 + .pp_count = 2, 508 + .pp_chg_id = INT_MIN, }, 509 + 510 + { .n = "gmac0_gclk", 511 + .id = 51, 512 + .r = { .max = 125000000 }, 513 + .pp = { "ethpll_divpmcck", }, 514 + .pp_mux_table = { 10, }, 515 + .pp_count = 1, 516 + .pp_chg_id = 4, }, 517 + 518 + { .n = "gmac1_gclk", 519 + .id = 52, 520 + .r = { .max = 50000000 }, 521 + .pp = { "ethpll_divpmcck", }, 522 + .pp_mux_table = { 10, }, 523 + .pp_count = 1, 524 + .pp_chg_id = INT_MIN, }, 525 + 526 + { .n = "gmac0_tsu_gclk", 527 + .id = 53, 528 + .r = { .max = 300000000 }, 529 + .pp = { "audiopll_divpmcck", "ethpll_divpmcck", }, 530 + .pp_mux_table = { 9, 10, }, 531 + .pp_count = 2, 532 + .pp_chg_id = INT_MIN, }, 533 + 534 + { .n = "gmac1_tsu_gclk", 535 + .id = 54, 536 + .r = { .max = 300000000 }, 537 + .pp = { "audiopll_divpmcck", "ethpll_divpmcck", }, 538 + .pp_mux_table = { 9, 10, }, 539 + .pp_count = 2, 540 + .pp_chg_id = INT_MIN, }, 541 + 542 + { .n = "i2smcc0_gclk", 543 + .id = 57, 544 + .r = { .max = 100000000 }, 545 + .pp = { "syspll_divpmcck", "audiopll_divpmcck", }, 546 + .pp_mux_table = { 5, 9, }, 547 + .pp_count = 2, 548 + .pp_chg_id = 5, }, 549 + 550 + { .n = "i2smcc1_gclk", 551 + .id = 58, 552 + .r = { .max = 100000000 }, 553 + .pp = { "syspll_divpmcck", "audiopll_divpmcck", }, 554 + .pp_mux_table = { 5, 9, }, 555 + .pp_count = 2, 556 + .pp_chg_id = 5, }, 557 + 558 + { .n = "mcan0_gclk", 559 + .id = 61, 560 + .r = { .max = 200000000 }, 561 + .pp = { "syspll_divpmcck", "baudpll_divpmcck", }, 562 + .pp_mux_table = { 5, 8, }, 563 + .pp_count = 2, 564 + .pp_chg_id = INT_MIN, }, 565 + 566 + { .n = "mcan1_gclk", 567 + .id = 62, 568 + .r = { .max = 200000000 }, 569 + .pp = { "syspll_divpmcck", "baudpll_divpmcck", }, 570 + .pp_mux_table = { 5, 8, }, 571 + .pp_count = 2, 572 + .pp_chg_id = INT_MIN, }, 573 + 574 + { .n = "mcan2_gclk", 575 + .id = 63, 576 + .r = { .max = 200000000 }, 577 + .pp = { "syspll_divpmcck", "baudpll_divpmcck", }, 578 + .pp_mux_table = { 5, 8, }, 579 + .pp_count = 2, 580 + .pp_chg_id = INT_MIN, }, 581 + 582 + { .n = "mcan3_gclk", 583 + .id = 64, 584 + .r = { .max = 200000000 }, 585 + .pp = { "syspll_divpmcck", "baudpll_divpmcck", }, 586 + .pp_mux_table = { 5, 8, }, 587 + .pp_count = 2, 588 + .pp_chg_id = INT_MIN, }, 589 + 590 + { .n = "mcan4_gclk", 591 + .id = 65, 592 + .r = { .max = 200000000 }, 593 + .pp = { "syspll_divpmcck", "baudpll_divpmcck", }, 594 + .pp_mux_table = { 5, 8, }, 595 + .pp_count = 2, 596 + .pp_chg_id = INT_MIN, }, 597 + 598 + { .n = "mcan5_gclk", 599 + .id = 66, 600 + .r = { .max = 200000000 }, 601 + .pp = { "syspll_divpmcck", "baudpll_divpmcck", }, 602 + .pp_mux_table = { 5, 8, }, 603 + .pp_count = 2, 604 + .pp_chg_id = INT_MIN, }, 605 + 606 + { .n = "pdmc0_gclk", 607 + .id = 68, 608 + .r = { .max = 50000000 }, 609 + .pp = { "syspll_divpmcck", "baudpll_divpmcck", }, 610 + .pp_mux_table = { 5, 8, }, 611 + .pp_count = 2, 612 + .pp_chg_id = INT_MIN, }, 613 + 614 + { .n = "pdmc1_gclk", 615 + .id = 69, 616 + .r = { .max = 50000000, }, 617 + .pp = { "syspll_divpmcck", "baudpll_divpmcck", }, 618 + .pp_mux_table = { 5, 8, }, 619 + .pp_count = 2, 620 + .pp_chg_id = INT_MIN, }, 621 + 622 + { .n = "pit64b0_gclk", 623 + .id = 70, 624 + .r = { .max = 200000000 }, 625 + .pp = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck", 626 + "audiopll_divpmcck", "ethpll_divpmcck", }, 627 + .pp_mux_table = { 5, 7, 8, 9, 10, }, 628 + .pp_count = 5, 629 + .pp_chg_id = INT_MIN, }, 630 + 631 + { .n = "pit64b1_gclk", 632 + .id = 71, 633 + .r = { .max = 200000000 }, 634 + .pp = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck", 635 + "audiopll_divpmcck", "ethpll_divpmcck", }, 636 + .pp_mux_table = { 5, 7, 8, 9, 10, }, 637 + .pp_count = 5, 638 + .pp_chg_id = INT_MIN, }, 639 + 640 + { .n = "pit64b2_gclk", 641 + .id = 72, 642 + .r = { .max = 200000000 }, 643 + .pp = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck", 644 + "audiopll_divpmcck", "ethpll_divpmcck", }, 645 + .pp_mux_table = { 5, 7, 8, 9, 10, }, 646 + .pp_count = 5, 647 + .pp_chg_id = INT_MIN, }, 648 + 649 + { .n = "pit64b3_gclk", 650 + .id = 73, 651 + .r = { .max = 200000000 }, 652 + .pp = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck", 653 + "audiopll_divpmcck", "ethpll_divpmcck", }, 654 + .pp_mux_table = { 5, 7, 8, 9, 10, }, 655 + .pp_count = 5, 656 + .pp_chg_id = INT_MIN, }, 657 + 658 + { .n = "pit64b4_gclk", 659 + .id = 74, 660 + .r = { .max = 200000000 }, 661 + .pp = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck", 662 + "audiopll_divpmcck", "ethpll_divpmcck", }, 663 + .pp_mux_table = { 5, 7, 8, 9, 10, }, 664 + .pp_count = 5, 665 + .pp_chg_id = INT_MIN, }, 666 + 667 + { .n = "pit64b5_gclk", 668 + .id = 75, 669 + .r = { .max = 200000000 }, 670 + .pp = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck", 671 + "audiopll_divpmcck", "ethpll_divpmcck", }, 672 + .pp_mux_table = { 5, 7, 8, 9, 10, }, 673 + .pp_count = 5, 674 + .pp_chg_id = INT_MIN, }, 675 + 676 + { .n = "qspi0_gclk", 677 + .id = 78, 678 + .r = { .max = 200000000 }, 679 + .pp = { "syspll_divpmcck", "baudpll_divpmcck", }, 680 + .pp_mux_table = { 5, 8, }, 681 + .pp_count = 2, 682 + .pp_chg_id = INT_MIN, }, 683 + 684 + { .n = "qspi1_gclk", 685 + .id = 79, 686 + .r = { .max = 200000000 }, 687 + .pp = { "syspll_divpmcck", "baudpll_divpmcck", }, 688 + .pp_mux_table = { 5, 8, }, 689 + .pp_count = 2, 690 + .pp_chg_id = INT_MIN, }, 691 + 692 + { .n = "sdmmc0_gclk", 693 + .id = 80, 694 + .r = { .max = 208000000 }, 695 + .pp = { "syspll_divpmcck", "baudpll_divpmcck", }, 696 + .pp_mux_table = { 5, 8, }, 697 + .pp_count = 2, 698 + .pp_chg_id = 5, }, 699 + 700 + { .n = "sdmmc1_gclk", 701 + .id = 81, 702 + .r = { .max = 208000000 }, 703 + .pp = { "syspll_divpmcck", "baudpll_divpmcck", }, 704 + .pp_mux_table = { 5, 8, }, 705 + .pp_count = 2, 706 + .pp_chg_id = 5, }, 707 + 708 + { .n = "sdmmc2_gclk", 709 + .id = 82, 710 + .r = { .max = 208000000 }, 711 + .pp = { "syspll_divpmcck", "baudpll_divpmcck", }, 712 + .pp_mux_table = { 5, 8, }, 713 + .pp_count = 2, 714 + .pp_chg_id = 5, }, 715 + 716 + { .n = "spdifrx_gclk", 717 + .id = 84, 718 + .r = { .max = 150000000 }, 719 + .pp = { "syspll_divpmcck", "audiopll_divpmcck", }, 720 + .pp_mux_table = { 5, 9, }, 721 + .pp_count = 2, 722 + .pp_chg_id = 5, }, 723 + 724 + { .n = "spdiftx_gclk", 725 + .id = 85, 726 + .r = { .max = 25000000 }, 727 + .pp = { "syspll_divpmcck", "audiopll_divpmcck", }, 728 + .pp_mux_table = { 5, 9, }, 729 + .pp_count = 2, 730 + .pp_chg_id = 5, }, 731 + 732 + { .n = "tcb0_ch0_gclk", 733 + .id = 88, 734 + .r = { .max = 200000000 }, 735 + .pp = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck", 736 + "audiopll_divpmcck", "ethpll_divpmcck", }, 737 + .pp_mux_table = { 5, 7, 8, 9, 10, }, 738 + .pp_count = 5, 739 + .pp_chg_id = INT_MIN, }, 740 + 741 + { .n = "tcb1_ch0_gclk", 742 + .id = 91, 743 + .r = { .max = 200000000 }, 744 + .pp = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck", 745 + "audiopll_divpmcck", "ethpll_divpmcck", }, 746 + .pp_mux_table = { 5, 7, 8, 9, 10, }, 747 + .pp_count = 5, 748 + .pp_chg_id = INT_MIN, }, 749 + 750 + { .n = "tcpca_gclk", 751 + .id = 94, 752 + .r = { .max = 32768, }, 753 + .pp_chg_id = INT_MIN, }, 754 + 755 + { .n = "tcpcb_gclk", 756 + .id = 95, 757 + .r = { .max = 32768, }, 758 + .pp_chg_id = INT_MIN, }, 759 + }; 760 + 761 + /* PLL output range. */ 762 + static const struct clk_range pll_outputs[] = { 763 + { .min = 2343750, .max = 1200000000 }, 764 + }; 765 + 766 + /* PLL characteristics. */ 767 + static const struct clk_pll_characteristics pll_characteristics = { 768 + .input = { .min = 12000000, .max = 50000000 }, 769 + .num_output = ARRAY_SIZE(pll_outputs), 770 + .output = pll_outputs, 771 + }; 772 + 773 + /* MCK0 characteristics. */ 774 + static const struct clk_master_characteristics mck0_characteristics = { 775 + .output = { .min = 140000000, .max = 200000000 }, 776 + .divisors = { 1, 2, 4, 3 }, 777 + .have_div3_pres = 1, 778 + }; 779 + 780 + /* MCK0 layout. */ 781 + static const struct clk_master_layout mck0_layout = { 782 + .mask = 0x373, 783 + .pres_shift = 4, 784 + .offset = 0x28, 785 + }; 786 + 787 + /* Programmable clock layout. */ 788 + static const struct clk_programmable_layout programmable_layout = { 789 + .pres_mask = 0xff, 790 + .pres_shift = 8, 791 + .css_mask = 0x1f, 792 + .have_slck_mck = 0, 793 + .is_pres_direct = 1, 794 + }; 795 + 796 + /* Peripheral clock layout. */ 797 + static const struct clk_pcr_layout sama7g5_pcr_layout = { 798 + .offset = 0x88, 799 + .cmd = BIT(31), 800 + .gckcss_mask = GENMASK(12, 8), 801 + .pid_mask = GENMASK(6, 0), 802 + }; 803 + 804 + static void __init sama7g5_pmc_setup(struct device_node *np) 805 + { 806 + const char *td_slck_name, *md_slck_name, *mainxtal_name; 807 + struct pmc_data *sama7g5_pmc; 808 + const char *parent_names[10]; 809 + void **alloc_mem = NULL; 810 + int alloc_mem_size = 0; 811 + struct regmap *regmap; 812 + struct clk_hw *hw; 813 + bool bypass; 814 + int i, j; 815 + 816 + i = of_property_match_string(np, "clock-names", "td_slck"); 817 + if (i < 0) 818 + return; 819 + 820 + td_slck_name = of_clk_get_parent_name(np, i); 821 + 822 + i = of_property_match_string(np, "clock-names", "md_slck"); 823 + if (i < 0) 824 + return; 825 + 826 + md_slck_name = of_clk_get_parent_name(np, i); 827 + 828 + i = of_property_match_string(np, "clock-names", "main_xtal"); 829 + if (i < 0) 830 + return; 831 + 832 + mainxtal_name = of_clk_get_parent_name(np, i); 833 + 834 + regmap = device_node_to_regmap(np); 835 + if (IS_ERR(regmap)) 836 + return; 837 + 838 + sama7g5_pmc = pmc_data_allocate(PMC_I2S1_MUX + 1, 839 + nck(sama7g5_systemck), 840 + nck(sama7g5_periphck), 841 + nck(sama7g5_gck)); 842 + if (!sama7g5_pmc) 843 + return; 844 + 845 + alloc_mem = kmalloc(sizeof(void *) * 846 + (ARRAY_SIZE(sama7g5_mckx) + ARRAY_SIZE(sama7g5_gck)), 847 + GFP_KERNEL); 848 + if (!alloc_mem) 849 + goto err_free; 850 + 851 + hw = at91_clk_register_main_rc_osc(regmap, "main_rc_osc", 12000000, 852 + 50000000); 853 + if (IS_ERR(hw)) 854 + goto err_free; 855 + 856 + bypass = of_property_read_bool(np, "atmel,osc-bypass"); 857 + 858 + hw = at91_clk_register_main_osc(regmap, "main_osc", mainxtal_name, 859 + bypass); 860 + if (IS_ERR(hw)) 861 + goto err_free; 862 + 863 + parent_names[0] = "main_rc_osc"; 864 + parent_names[1] = "main_osc"; 865 + hw = at91_clk_register_sam9x5_main(regmap, "mainck", parent_names, 2); 866 + if (IS_ERR(hw)) 867 + goto err_free; 868 + 869 + sama7g5_pmc->chws[PMC_MAIN] = hw; 870 + 871 + for (i = 0; i < PLL_ID_MAX; i++) { 872 + for (j = 0; j < 3; j++) { 873 + struct clk_hw *parent_hw; 874 + 875 + if (!sama7g5_plls[i][j].n) 876 + continue; 877 + 878 + switch (sama7g5_plls[i][j].t) { 879 + case PLL_TYPE_FRAC: 880 + if (!strcmp(sama7g5_plls[i][j].p, "mainck")) 881 + parent_hw = sama7g5_pmc->chws[PMC_MAIN]; 882 + else 883 + parent_hw = __clk_get_hw(of_clk_get_by_name(np, 884 + sama7g5_plls[i][j].p)); 885 + 886 + hw = sam9x60_clk_register_frac_pll(regmap, 887 + &pmc_pll_lock, sama7g5_plls[i][j].n, 888 + sama7g5_plls[i][j].p, parent_hw, i, 889 + &pll_characteristics, 890 + sama7g5_plls[i][j].l, 891 + sama7g5_plls[i][j].c); 892 + break; 893 + 894 + case PLL_TYPE_DIV: 895 + hw = sam9x60_clk_register_div_pll(regmap, 896 + &pmc_pll_lock, sama7g5_plls[i][j].n, 897 + sama7g5_plls[i][j].p, i, 898 + &pll_characteristics, 899 + sama7g5_plls[i][j].l, 900 + sama7g5_plls[i][j].c); 901 + break; 902 + 903 + default: 904 + continue; 905 + } 906 + 907 + if (IS_ERR(hw)) 908 + goto err_free; 909 + 910 + if (sama7g5_plls[i][j].eid) 911 + sama7g5_pmc->chws[sama7g5_plls[i][j].eid] = hw; 912 + } 913 + } 914 + 915 + parent_names[0] = md_slck_name; 916 + parent_names[1] = "mainck"; 917 + parent_names[2] = "cpupll_divpmcck"; 918 + parent_names[3] = "syspll_divpmcck"; 919 + hw = at91_clk_register_master(regmap, "mck0", 4, parent_names, 920 + &mck0_layout, &mck0_characteristics); 921 + if (IS_ERR(hw)) 922 + goto err_free; 923 + 924 + sama7g5_pmc->chws[PMC_MCK] = hw; 925 + 926 + parent_names[0] = md_slck_name; 927 + parent_names[1] = td_slck_name; 928 + parent_names[2] = "mainck"; 929 + parent_names[3] = "mck0"; 930 + for (i = 0; i < ARRAY_SIZE(sama7g5_mckx); i++) { 931 + u8 num_parents = 4 + sama7g5_mckx[i].ep_count; 932 + u32 *mux_table; 933 + 934 + mux_table = kmalloc_array(num_parents, sizeof(*mux_table), 935 + GFP_KERNEL); 936 + if (!mux_table) 937 + goto err_free; 938 + 939 + SAMA7G5_INIT_TABLE(mux_table, 4); 940 + SAMA7G5_FILL_TABLE(&mux_table[4], sama7g5_mckx[i].ep_mux_table, 941 + sama7g5_mckx[i].ep_count); 942 + SAMA7G5_FILL_TABLE(&parent_names[4], sama7g5_mckx[i].ep, 943 + sama7g5_mckx[i].ep_count); 944 + 945 + hw = at91_clk_sama7g5_register_master(regmap, sama7g5_mckx[i].n, 946 + num_parents, parent_names, mux_table, 947 + &pmc_mckX_lock, sama7g5_mckx[i].id, 948 + sama7g5_mckx[i].c, 949 + sama7g5_mckx[i].ep_chg_id); 950 + if (IS_ERR(hw)) 951 + goto err_free; 952 + 953 + alloc_mem[alloc_mem_size++] = mux_table; 954 + } 955 + 956 + hw = at91_clk_sama7g5_register_utmi(regmap, "utmick", "main_xtal"); 957 + if (IS_ERR(hw)) 958 + goto err_free; 959 + 960 + sama7g5_pmc->chws[PMC_UTMI] = hw; 961 + 962 + parent_names[0] = md_slck_name; 963 + parent_names[1] = td_slck_name; 964 + parent_names[2] = "mainck"; 965 + parent_names[3] = "mck0"; 966 + parent_names[4] = "syspll_divpmcck"; 967 + parent_names[5] = "ddrpll_divpmcck"; 968 + parent_names[6] = "imgpll_divpmcck"; 969 + parent_names[7] = "baudpll_divpmcck"; 970 + parent_names[8] = "audiopll_divpmcck"; 971 + parent_names[9] = "ethpll_divpmcck"; 972 + for (i = 0; i < 8; i++) { 973 + char name[6]; 974 + 975 + snprintf(name, sizeof(name), "prog%d", i); 976 + 977 + hw = at91_clk_register_programmable(regmap, name, parent_names, 978 + 10, i, 979 + &programmable_layout, 980 + sama7g5_prog_mux_table); 981 + if (IS_ERR(hw)) 982 + goto err_free; 983 + } 984 + 985 + for (i = 0; i < ARRAY_SIZE(sama7g5_systemck); i++) { 986 + hw = at91_clk_register_system(regmap, sama7g5_systemck[i].n, 987 + sama7g5_systemck[i].p, 988 + sama7g5_systemck[i].id); 989 + if (IS_ERR(hw)) 990 + goto err_free; 991 + 992 + sama7g5_pmc->shws[sama7g5_systemck[i].id] = hw; 993 + } 994 + 995 + for (i = 0; i < ARRAY_SIZE(sama7g5_periphck); i++) { 996 + hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock, 997 + &sama7g5_pcr_layout, 998 + sama7g5_periphck[i].n, 999 + sama7g5_periphck[i].p, 1000 + sama7g5_periphck[i].id, 1001 + &sama7g5_periphck[i].r, 1002 + sama7g5_periphck[i].chgp ? 0 : 1003 + INT_MIN); 1004 + if (IS_ERR(hw)) 1005 + goto err_free; 1006 + 1007 + sama7g5_pmc->phws[sama7g5_periphck[i].id] = hw; 1008 + } 1009 + 1010 + parent_names[0] = md_slck_name; 1011 + parent_names[1] = td_slck_name; 1012 + parent_names[2] = "mainck"; 1013 + parent_names[3] = "mck0"; 1014 + for (i = 0; i < ARRAY_SIZE(sama7g5_gck); i++) { 1015 + u8 num_parents = 4 + sama7g5_gck[i].pp_count; 1016 + u32 *mux_table; 1017 + 1018 + mux_table = kmalloc_array(num_parents, sizeof(*mux_table), 1019 + GFP_KERNEL); 1020 + if (!mux_table) 1021 + goto err_free; 1022 + 1023 + SAMA7G5_INIT_TABLE(mux_table, 4); 1024 + SAMA7G5_FILL_TABLE(&mux_table[4], sama7g5_gck[i].pp_mux_table, 1025 + sama7g5_gck[i].pp_count); 1026 + SAMA7G5_FILL_TABLE(&parent_names[4], sama7g5_gck[i].pp, 1027 + sama7g5_gck[i].pp_count); 1028 + 1029 + hw = at91_clk_register_generated(regmap, &pmc_pcr_lock, 1030 + &sama7g5_pcr_layout, 1031 + sama7g5_gck[i].n, 1032 + parent_names, mux_table, 1033 + num_parents, 1034 + sama7g5_gck[i].id, 1035 + &sama7g5_gck[i].r, 1036 + sama7g5_gck[i].pp_chg_id); 1037 + if (IS_ERR(hw)) 1038 + goto err_free; 1039 + 1040 + sama7g5_pmc->ghws[sama7g5_gck[i].id] = hw; 1041 + alloc_mem[alloc_mem_size++] = mux_table; 1042 + } 1043 + 1044 + of_clk_add_hw_provider(np, of_clk_hw_pmc_get, sama7g5_pmc); 1045 + 1046 + return; 1047 + 1048 + err_free: 1049 + if (alloc_mem) { 1050 + for (i = 0; i < alloc_mem_size; i++) 1051 + kfree(alloc_mem[i]); 1052 + kfree(alloc_mem); 1053 + } 1054 + 1055 + pmc_data_free(sama7g5_pmc); 1056 + } 1057 + 1058 + /* Some clks are used for a clocksource */ 1059 + CLK_OF_DECLARE(sama7g5_pmc, "microchip,sama7g5-pmc", sama7g5_pmc_setup);
+3 -2
drivers/clk/at91/sckc.c
··· 471 471 if (!regbase) 472 472 return; 473 473 474 - slow_rc = clk_hw_register_fixed_rate(NULL, parent_names[0], NULL, 0, 475 - 32768); 474 + slow_rc = clk_hw_register_fixed_rate_with_accuracy(NULL, parent_names[0], 475 + NULL, 0, 32768, 476 + 93750000); 476 477 if (IS_ERR(slow_rc)) 477 478 return; 478 479
+21 -4
drivers/clk/bcm/clk-bcm2835.c
··· 314 314 struct device *dev; 315 315 void __iomem *regs; 316 316 spinlock_t regs_lock; /* spinlock for all clocks */ 317 + unsigned int soc; 317 318 318 319 /* 319 320 * Real names of cprman clock parents looked up through ··· 527 526 A2W_PLL_CTRL_PRST_DISABLE; 528 527 } 529 528 529 + static u32 bcm2835_pll_get_prediv_mask(struct bcm2835_cprman *cprman, 530 + const struct bcm2835_pll_data *data) 531 + { 532 + /* 533 + * On BCM2711 there isn't a pre-divisor available in the PLL feedback 534 + * loop. Bits 13:14 of ANA1 (PLLA,PLLB,PLLC,PLLD) have been re-purposed 535 + * for to for VCO RANGE bits. 536 + */ 537 + if (cprman->soc & SOC_BCM2711) 538 + return 0; 539 + 540 + return data->ana->fb_prediv_mask; 541 + } 542 + 530 543 static void bcm2835_pll_choose_ndiv_and_fdiv(unsigned long rate, 531 544 unsigned long parent_rate, 532 545 u32 *ndiv, u32 *fdiv) ··· 598 583 ndiv = (a2wctrl & A2W_PLL_CTRL_NDIV_MASK) >> A2W_PLL_CTRL_NDIV_SHIFT; 599 584 pdiv = (a2wctrl & A2W_PLL_CTRL_PDIV_MASK) >> A2W_PLL_CTRL_PDIV_SHIFT; 600 585 using_prediv = cprman_read(cprman, data->ana_reg_base + 4) & 601 - data->ana->fb_prediv_mask; 586 + bcm2835_pll_get_prediv_mask(cprman, data); 602 587 603 588 if (using_prediv) { 604 589 ndiv *= 2; ··· 681 666 struct bcm2835_pll *pll = container_of(hw, struct bcm2835_pll, hw); 682 667 struct bcm2835_cprman *cprman = pll->cprman; 683 668 const struct bcm2835_pll_data *data = pll->data; 669 + u32 prediv_mask = bcm2835_pll_get_prediv_mask(cprman, data); 684 670 bool was_using_prediv, use_fb_prediv, do_ana_setup_first; 685 671 u32 ndiv, fdiv, a2w_ctl; 686 672 u32 ana[4]; ··· 699 683 for (i = 3; i >= 0; i--) 700 684 ana[i] = cprman_read(cprman, data->ana_reg_base + i * 4); 701 685 702 - was_using_prediv = ana[1] & data->ana->fb_prediv_mask; 686 + was_using_prediv = ana[1] & prediv_mask; 703 687 704 688 ana[0] &= ~data->ana->mask0; 705 689 ana[0] |= data->ana->set0; ··· 709 693 ana[3] |= data->ana->set3; 710 694 711 695 if (was_using_prediv && !use_fb_prediv) { 712 - ana[1] &= ~data->ana->fb_prediv_mask; 696 + ana[1] &= ~prediv_mask; 713 697 do_ana_setup_first = true; 714 698 } else if (!was_using_prediv && use_fb_prediv) { 715 - ana[1] |= data->ana->fb_prediv_mask; 699 + ana[1] |= prediv_mask; 716 700 do_ana_setup_first = false; 717 701 } else { 718 702 do_ana_setup_first = true; ··· 2278 2262 platform_set_drvdata(pdev, cprman); 2279 2263 2280 2264 cprman->onecell.num = asize; 2265 + cprman->soc = pdata->soc; 2281 2266 hws = cprman->onecell.hws; 2282 2267 2283 2268 for (i = 0; i < asize; i++) {
+2 -2
drivers/clk/bcm/clk-iproc-asiu.c
··· 119 119 if (rate == *parent_rate) 120 120 return *parent_rate; 121 121 122 - div = DIV_ROUND_UP(*parent_rate, rate); 122 + div = DIV_ROUND_CLOSEST(*parent_rate, rate); 123 123 if (div < 2) 124 124 return *parent_rate; 125 125 ··· 145 145 return 0; 146 146 } 147 147 148 - div = DIV_ROUND_UP(parent_rate, rate); 148 + div = DIV_ROUND_CLOSEST(parent_rate, rate); 149 149 if (div < 2) 150 150 return -EINVAL; 151 151
+9 -1
drivers/clk/clk-qoriq.c
··· 244 244 }, 245 245 }; 246 246 247 + static const struct clockgen_muxinfo ls1021a_cmux = { 248 + { 249 + { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 }, 250 + { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 }, 251 + { CLKSEL_VALID, CGA_PLL1, PLL_DIV4 }, 252 + } 253 + }; 254 + 247 255 static const struct clockgen_muxinfo ls1028a_hwa1 = { 248 256 { 249 257 { CLKSEL_VALID, PLATFORM_PLL, PLL_DIV1 }, ··· 585 577 { 586 578 .compat = "fsl,ls1021a-clockgen", 587 579 .cmux_groups = { 588 - &t1023_cmux 580 + &ls1021a_cmux 589 581 }, 590 582 .cmux_to_group = { 591 583 0, -1
+295
drivers/clk/clk-sparx5.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 3 + * Microchip Sparx5 SoC Clock driver. 4 + * 5 + * Copyright (c) 2019 Microchip Inc. 6 + * 7 + * Author: Lars Povlsen <lars.povlsen@microchip.com> 8 + */ 9 + 10 + #include <linux/io.h> 11 + #include <linux/module.h> 12 + #include <linux/clk-provider.h> 13 + #include <linux/bitfield.h> 14 + #include <linux/of.h> 15 + #include <linux/slab.h> 16 + #include <linux/platform_device.h> 17 + #include <dt-bindings/clock/microchip,sparx5.h> 18 + 19 + #define PLL_DIV GENMASK(7, 0) 20 + #define PLL_PRE_DIV GENMASK(10, 8) 21 + #define PLL_ROT_DIR BIT(11) 22 + #define PLL_ROT_SEL GENMASK(13, 12) 23 + #define PLL_ROT_ENA BIT(14) 24 + #define PLL_CLK_ENA BIT(15) 25 + 26 + #define MAX_SEL 4 27 + #define MAX_PRE BIT(3) 28 + 29 + static const u8 sel_rates[MAX_SEL] = { 0, 2*8, 2*4, 2*2 }; 30 + 31 + static const char *clk_names[N_CLOCKS] = { 32 + "core", "ddr", "cpu2", "arm2", 33 + "aux1", "aux2", "aux3", "aux4", 34 + "synce", 35 + }; 36 + 37 + struct s5_hw_clk { 38 + struct clk_hw hw; 39 + void __iomem *reg; 40 + }; 41 + 42 + struct s5_clk_data { 43 + void __iomem *base; 44 + struct s5_hw_clk s5_hw[N_CLOCKS]; 45 + }; 46 + 47 + struct s5_pll_conf { 48 + unsigned long freq; 49 + u8 div; 50 + bool rot_ena; 51 + u8 rot_sel; 52 + u8 rot_dir; 53 + u8 pre_div; 54 + }; 55 + 56 + #define to_s5_pll(hw) container_of(hw, struct s5_hw_clk, hw) 57 + 58 + static unsigned long s5_calc_freq(unsigned long parent_rate, 59 + const struct s5_pll_conf *conf) 60 + { 61 + unsigned long rate = parent_rate / conf->div; 62 + 63 + if (conf->rot_ena) { 64 + int sign = conf->rot_dir ? -1 : 1; 65 + int divt = sel_rates[conf->rot_sel] * (1 + conf->pre_div); 66 + int divb = divt + sign; 67 + 68 + rate = mult_frac(rate, divt, divb); 69 + rate = roundup(rate, 1000); 70 + } 71 + 72 + return rate; 73 + } 74 + 75 + static void s5_search_fractional(unsigned long rate, 76 + unsigned long parent_rate, 77 + int div, 78 + struct s5_pll_conf *conf) 79 + { 80 + struct s5_pll_conf best; 81 + ulong cur_offset, best_offset = rate; 82 + int d, i, j; 83 + 84 + memset(conf, 0, sizeof(*conf)); 85 + conf->div = div; 86 + conf->rot_ena = 1; /* Fractional rate */ 87 + 88 + for (d = 0; best_offset > 0 && d <= 1 ; d++) { 89 + conf->rot_dir = !!d; 90 + for (i = 0; best_offset > 0 && i < MAX_PRE; i++) { 91 + conf->pre_div = i; 92 + for (j = 1; best_offset > 0 && j < MAX_SEL; j++) { 93 + conf->rot_sel = j; 94 + conf->freq = s5_calc_freq(parent_rate, conf); 95 + cur_offset = abs(rate - conf->freq); 96 + if (cur_offset < best_offset) { 97 + best_offset = cur_offset; 98 + best = *conf; 99 + } 100 + } 101 + } 102 + } 103 + 104 + /* Best match */ 105 + *conf = best; 106 + } 107 + 108 + static unsigned long s5_calc_params(unsigned long rate, 109 + unsigned long parent_rate, 110 + struct s5_pll_conf *conf) 111 + { 112 + if (parent_rate % rate) { 113 + struct s5_pll_conf alt1, alt2; 114 + int div; 115 + 116 + div = DIV_ROUND_CLOSEST_ULL(parent_rate, rate); 117 + s5_search_fractional(rate, parent_rate, div, &alt1); 118 + 119 + /* Straight match? */ 120 + if (alt1.freq == rate) { 121 + *conf = alt1; 122 + } else { 123 + /* Try without rounding divider */ 124 + div = parent_rate / rate; 125 + if (div != alt1.div) { 126 + s5_search_fractional(rate, parent_rate, div, 127 + &alt2); 128 + /* Select the better match */ 129 + if (abs(rate - alt1.freq) < 130 + abs(rate - alt2.freq)) 131 + *conf = alt1; 132 + else 133 + *conf = alt2; 134 + } 135 + } 136 + } else { 137 + /* Straight fit */ 138 + memset(conf, 0, sizeof(*conf)); 139 + conf->div = parent_rate / rate; 140 + } 141 + 142 + return conf->freq; 143 + } 144 + 145 + static int s5_pll_enable(struct clk_hw *hw) 146 + { 147 + struct s5_hw_clk *pll = to_s5_pll(hw); 148 + u32 val = readl(pll->reg); 149 + 150 + val |= PLL_CLK_ENA; 151 + writel(val, pll->reg); 152 + 153 + return 0; 154 + } 155 + 156 + static void s5_pll_disable(struct clk_hw *hw) 157 + { 158 + struct s5_hw_clk *pll = to_s5_pll(hw); 159 + u32 val = readl(pll->reg); 160 + 161 + val &= ~PLL_CLK_ENA; 162 + writel(val, pll->reg); 163 + } 164 + 165 + static int s5_pll_set_rate(struct clk_hw *hw, 166 + unsigned long rate, 167 + unsigned long parent_rate) 168 + { 169 + struct s5_hw_clk *pll = to_s5_pll(hw); 170 + struct s5_pll_conf conf; 171 + unsigned long eff_rate; 172 + u32 val; 173 + 174 + eff_rate = s5_calc_params(rate, parent_rate, &conf); 175 + if (eff_rate != rate) 176 + return -EOPNOTSUPP; 177 + 178 + val = readl(pll->reg) & PLL_CLK_ENA; 179 + val |= FIELD_PREP(PLL_DIV, conf.div); 180 + if (conf.rot_ena) { 181 + val |= PLL_ROT_ENA; 182 + val |= FIELD_PREP(PLL_ROT_SEL, conf.rot_sel); 183 + val |= FIELD_PREP(PLL_PRE_DIV, conf.pre_div); 184 + if (conf.rot_dir) 185 + val |= PLL_ROT_DIR; 186 + } 187 + writel(val, pll->reg); 188 + 189 + return 0; 190 + } 191 + 192 + static unsigned long s5_pll_recalc_rate(struct clk_hw *hw, 193 + unsigned long parent_rate) 194 + { 195 + struct s5_hw_clk *pll = to_s5_pll(hw); 196 + struct s5_pll_conf conf; 197 + u32 val; 198 + 199 + val = readl(pll->reg); 200 + 201 + if (val & PLL_CLK_ENA) { 202 + conf.div = FIELD_GET(PLL_DIV, val); 203 + conf.pre_div = FIELD_GET(PLL_PRE_DIV, val); 204 + conf.rot_ena = FIELD_GET(PLL_ROT_ENA, val); 205 + conf.rot_dir = FIELD_GET(PLL_ROT_DIR, val); 206 + conf.rot_sel = FIELD_GET(PLL_ROT_SEL, val); 207 + 208 + conf.freq = s5_calc_freq(parent_rate, &conf); 209 + } else { 210 + conf.freq = 0; 211 + } 212 + 213 + return conf.freq; 214 + } 215 + 216 + static long s5_pll_round_rate(struct clk_hw *hw, unsigned long rate, 217 + unsigned long *parent_rate) 218 + { 219 + struct s5_pll_conf conf; 220 + 221 + return s5_calc_params(rate, *parent_rate, &conf); 222 + } 223 + 224 + static const struct clk_ops s5_pll_ops = { 225 + .enable = s5_pll_enable, 226 + .disable = s5_pll_disable, 227 + .set_rate = s5_pll_set_rate, 228 + .round_rate = s5_pll_round_rate, 229 + .recalc_rate = s5_pll_recalc_rate, 230 + }; 231 + 232 + static struct clk_hw *s5_clk_hw_get(struct of_phandle_args *clkspec, void *data) 233 + { 234 + struct s5_clk_data *s5_clk = data; 235 + unsigned int idx = clkspec->args[0]; 236 + 237 + if (idx >= N_CLOCKS) { 238 + pr_err("%s: invalid index %u\n", __func__, idx); 239 + return ERR_PTR(-EINVAL); 240 + } 241 + 242 + return &s5_clk->s5_hw[idx].hw; 243 + } 244 + 245 + static int s5_clk_probe(struct platform_device *pdev) 246 + { 247 + struct device *dev = &pdev->dev; 248 + int i, ret; 249 + struct s5_clk_data *s5_clk; 250 + struct clk_parent_data pdata = { .index = 0 }; 251 + struct clk_init_data init = { 252 + .ops = &s5_pll_ops, 253 + .num_parents = 1, 254 + .parent_data = &pdata, 255 + }; 256 + 257 + s5_clk = devm_kzalloc(dev, sizeof(*s5_clk), GFP_KERNEL); 258 + if (!s5_clk) 259 + return -ENOMEM; 260 + 261 + s5_clk->base = devm_platform_ioremap_resource(pdev, 0); 262 + if (IS_ERR(s5_clk->base)) 263 + return PTR_ERR(s5_clk->base); 264 + 265 + for (i = 0; i < N_CLOCKS; i++) { 266 + struct s5_hw_clk *s5_hw = &s5_clk->s5_hw[i]; 267 + 268 + init.name = clk_names[i]; 269 + s5_hw->reg = s5_clk->base + (i * 4); 270 + s5_hw->hw.init = &init; 271 + ret = devm_clk_hw_register(dev, &s5_hw->hw); 272 + if (ret) { 273 + dev_err(dev, "failed to register %s clock\n", 274 + init.name); 275 + return ret; 276 + } 277 + } 278 + 279 + return devm_of_clk_add_hw_provider(dev, s5_clk_hw_get, s5_clk); 280 + } 281 + 282 + static const struct of_device_id s5_clk_dt_ids[] = { 283 + { .compatible = "microchip,sparx5-dpll", }, 284 + { } 285 + }; 286 + MODULE_DEVICE_TABLE(of, s5_clk_dt_ids); 287 + 288 + static struct platform_driver s5_clk_driver = { 289 + .probe = s5_clk_probe, 290 + .driver = { 291 + .name = "sparx5-clk", 292 + .of_match_table = s5_clk_dt_ids, 293 + }, 294 + }; 295 + builtin_platform_driver(s5_clk_driver);
+38 -44
drivers/clk/clk-versaclock5.c
··· 167 167 u32 div_int; 168 168 u32 div_frc; 169 169 unsigned int num; 170 + }; 171 + 172 + struct vc5_out_data { 173 + struct clk_hw hw; 174 + struct vc5_driver_data *vc5; 175 + unsigned int num; 170 176 unsigned int clk_output_cfg0; 171 177 unsigned int clk_output_cfg0_mask; 172 178 }; ··· 190 184 struct clk_hw clk_pfd; 191 185 struct vc5_hw_data clk_pll; 192 186 struct vc5_hw_data clk_fod[VC5_MAX_FOD_NUM]; 193 - struct vc5_hw_data clk_out[VC5_MAX_CLK_OUT_NUM]; 187 + struct vc5_out_data clk_out[VC5_MAX_CLK_OUT_NUM]; 194 188 }; 195 189 196 190 /* ··· 573 567 574 568 static int vc5_clk_out_prepare(struct clk_hw *hw) 575 569 { 576 - struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw); 570 + struct vc5_out_data *hwdata = container_of(hw, struct vc5_out_data, hw); 577 571 struct vc5_driver_data *vc5 = hwdata->vc5; 578 572 const u8 mask = VC5_OUT_DIV_CONTROL_SELB_NORM | 579 573 VC5_OUT_DIV_CONTROL_SEL_EXT | ··· 615 609 616 610 static void vc5_clk_out_unprepare(struct clk_hw *hw) 617 611 { 618 - struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw); 612 + struct vc5_out_data *hwdata = container_of(hw, struct vc5_out_data, hw); 619 613 struct vc5_driver_data *vc5 = hwdata->vc5; 620 614 621 615 /* Disable the clock buffer */ ··· 625 619 626 620 static unsigned char vc5_clk_out_get_parent(struct clk_hw *hw) 627 621 { 628 - struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw); 622 + struct vc5_out_data *hwdata = container_of(hw, struct vc5_out_data, hw); 629 623 struct vc5_driver_data *vc5 = hwdata->vc5; 630 624 const u8 mask = VC5_OUT_DIV_CONTROL_SELB_NORM | 631 625 VC5_OUT_DIV_CONTROL_SEL_EXT | ··· 655 649 656 650 static int vc5_clk_out_set_parent(struct clk_hw *hw, u8 index) 657 651 { 658 - struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw); 652 + struct vc5_out_data *hwdata = container_of(hw, struct vc5_out_data, hw); 659 653 struct vc5_driver_data *vc5 = hwdata->vc5; 660 654 const u8 mask = VC5_OUT_DIV_CONTROL_RESET | 661 655 VC5_OUT_DIV_CONTROL_SELB_NORM | ··· 710 704 } 711 705 712 706 static int vc5_update_mode(struct device_node *np_output, 713 - struct vc5_hw_data *clk_out) 707 + struct vc5_out_data *clk_out) 714 708 { 715 709 u32 value; 716 710 ··· 735 729 } 736 730 737 731 static int vc5_update_power(struct device_node *np_output, 738 - struct vc5_hw_data *clk_out) 732 + struct vc5_out_data *clk_out) 739 733 { 740 734 u32 value; 741 735 ··· 760 754 } 761 755 762 756 static int vc5_update_slew(struct device_node *np_output, 763 - struct vc5_hw_data *clk_out) 757 + struct vc5_out_data *clk_out) 764 758 { 765 759 u32 value; 766 760 ··· 788 782 } 789 783 790 784 static int vc5_get_output_config(struct i2c_client *client, 791 - struct vc5_hw_data *clk_out) 785 + struct vc5_out_data *clk_out) 792 786 { 793 787 struct device_node *np_output; 794 788 char *child_name; 795 789 int ret = 0; 796 790 797 791 child_name = kasprintf(GFP_KERNEL, "OUT%d", clk_out->num + 1); 792 + if (!child_name) 793 + return -ENOMEM; 794 + 798 795 np_output = of_get_child_by_name(client->dev.of_node, child_name); 799 796 kfree(child_name); 800 797 if (!np_output) 801 - goto output_done; 798 + return 0; 802 799 803 800 ret = vc5_update_mode(np_output, clk_out); 804 801 if (ret) ··· 822 813 823 814 of_node_put(np_output); 824 815 825 - output_done: 826 816 return ret; 827 817 } 828 818 ··· 836 828 int ret; 837 829 838 830 vc5 = devm_kzalloc(&client->dev, sizeof(*vc5), GFP_KERNEL); 839 - if (vc5 == NULL) 831 + if (!vc5) 840 832 return -ENOMEM; 841 833 842 834 i2c_set_clientdata(client, vc5); ··· 890 882 init.parent_names = parent_names; 891 883 vc5->clk_mux.init = &init; 892 884 ret = devm_clk_hw_register(&client->dev, &vc5->clk_mux); 885 + if (ret) 886 + goto err_clk_register; 893 887 kfree(init.name); /* clock framework made a copy of the name */ 894 - if (ret) { 895 - dev_err(&client->dev, "unable to register %s\n", init.name); 896 - goto err_clk; 897 - } 898 888 899 889 if (vc5->chip_info->flags & VC5_HAS_PFD_FREQ_DBL) { 900 890 /* Register frequency doubler */ ··· 906 900 init.num_parents = 1; 907 901 vc5->clk_mul.init = &init; 908 902 ret = devm_clk_hw_register(&client->dev, &vc5->clk_mul); 903 + if (ret) 904 + goto err_clk_register; 909 905 kfree(init.name); /* clock framework made a copy of the name */ 910 - if (ret) { 911 - dev_err(&client->dev, "unable to register %s\n", 912 - init.name); 913 - goto err_clk; 914 - } 915 906 } 916 907 917 908 /* Register PFD */ ··· 924 921 init.num_parents = 1; 925 922 vc5->clk_pfd.init = &init; 926 923 ret = devm_clk_hw_register(&client->dev, &vc5->clk_pfd); 924 + if (ret) 925 + goto err_clk_register; 927 926 kfree(init.name); /* clock framework made a copy of the name */ 928 - if (ret) { 929 - dev_err(&client->dev, "unable to register %s\n", init.name); 930 - goto err_clk; 931 - } 932 927 933 928 /* Register PLL */ 934 929 memset(&init, 0, sizeof(init)); ··· 940 939 vc5->clk_pll.vc5 = vc5; 941 940 vc5->clk_pll.hw.init = &init; 942 941 ret = devm_clk_hw_register(&client->dev, &vc5->clk_pll.hw); 942 + if (ret) 943 + goto err_clk_register; 943 944 kfree(init.name); /* clock framework made a copy of the name */ 944 - if (ret) { 945 - dev_err(&client->dev, "unable to register %s\n", init.name); 946 - goto err_clk; 947 - } 948 945 949 946 /* Register FODs */ 950 947 for (n = 0; n < vc5->chip_info->clk_fod_cnt; n++) { ··· 959 960 vc5->clk_fod[n].vc5 = vc5; 960 961 vc5->clk_fod[n].hw.init = &init; 961 962 ret = devm_clk_hw_register(&client->dev, &vc5->clk_fod[n].hw); 963 + if (ret) 964 + goto err_clk_register; 962 965 kfree(init.name); /* clock framework made a copy of the name */ 963 - if (ret) { 964 - dev_err(&client->dev, "unable to register %s\n", 965 - init.name); 966 - goto err_clk; 967 - } 968 966 } 969 967 970 968 /* Register MUX-connected OUT0_I2C_SELB output */ ··· 977 981 vc5->clk_out[0].vc5 = vc5; 978 982 vc5->clk_out[0].hw.init = &init; 979 983 ret = devm_clk_hw_register(&client->dev, &vc5->clk_out[0].hw); 980 - kfree(init.name); /* clock framework made a copy of the name */ 981 - if (ret) { 982 - dev_err(&client->dev, "unable to register %s\n", init.name); 983 - goto err_clk; 984 - } 984 + if (ret) 985 + goto err_clk_register; 986 + kfree(init.name); /* clock framework made a copy of the name */ 985 987 986 988 /* Register FOD-connected OUTx outputs */ 987 989 for (n = 1; n < vc5->chip_info->clk_out_cnt; n++) { ··· 1002 1008 vc5->clk_out[n].vc5 = vc5; 1003 1009 vc5->clk_out[n].hw.init = &init; 1004 1010 ret = devm_clk_hw_register(&client->dev, &vc5->clk_out[n].hw); 1011 + if (ret) 1012 + goto err_clk_register; 1005 1013 kfree(init.name); /* clock framework made a copy of the name */ 1006 - if (ret) { 1007 - dev_err(&client->dev, "unable to register %s\n", 1008 - init.name); 1009 - goto err_clk; 1010 - } 1011 1014 1012 1015 /* Fetch Clock Output configuration from DT (if specified) */ 1013 1016 ret = vc5_get_output_config(client, &vc5->clk_out[n]); ··· 1020 1029 1021 1030 return 0; 1022 1031 1032 + err_clk_register: 1033 + dev_err(&client->dev, "unable to register %s\n", init.name); 1034 + kfree(init.name); /* clock framework made a copy of the name */ 1023 1035 err_clk: 1024 1036 if (vc5->chip_info->flags & VC5_HAS_INTERNAL_XTAL) 1025 1037 clk_unregister_fixed_rate(vc5->pin_xin);
+32 -6
drivers/clk/clk.c
··· 500 500 return core->accuracy; 501 501 } 502 502 503 - unsigned long __clk_get_flags(struct clk *clk) 504 - { 505 - return !clk ? 0 : clk->core->flags; 506 - } 507 - EXPORT_SYMBOL_GPL(__clk_get_flags); 508 - 509 503 unsigned long clk_hw_get_flags(const struct clk_hw *hw) 510 504 { 511 505 return hw->core->flags; ··· 3048 3054 } 3049 3055 3050 3056 #define clk_rate_mode 0644 3057 + 3058 + static int clk_prepare_enable_set(void *data, u64 val) 3059 + { 3060 + struct clk_core *core = data; 3061 + int ret = 0; 3062 + 3063 + if (val) 3064 + ret = clk_prepare_enable(core->hw->clk); 3065 + else 3066 + clk_disable_unprepare(core->hw->clk); 3067 + 3068 + return ret; 3069 + } 3070 + 3071 + static int clk_prepare_enable_get(void *data, u64 *val) 3072 + { 3073 + struct clk_core *core = data; 3074 + 3075 + *val = core->enable_count && core->prepare_count; 3076 + return 0; 3077 + } 3078 + 3079 + DEFINE_DEBUGFS_ATTRIBUTE(clk_prepare_enable_fops, clk_prepare_enable_get, 3080 + clk_prepare_enable_set, "%llu\n"); 3081 + 3051 3082 #else 3052 3083 #define clk_rate_set NULL 3053 3084 #define clk_rate_mode 0444 ··· 3250 3231 debugfs_create_u32("clk_notifier_count", 0444, root, &core->notifier_count); 3251 3232 debugfs_create_file("clk_duty_cycle", 0444, root, core, 3252 3233 &clk_duty_cycle_fops); 3234 + #ifdef CLOCK_ALLOW_WRITE_DEBUGFS 3235 + debugfs_create_file("clk_prepare_enable", 0644, root, core, 3236 + &clk_prepare_enable_fops); 3237 + #endif 3253 3238 3254 3239 if (core->num_parents > 0) 3255 3240 debugfs_create_file("clk_parent", 0444, root, core, ··· 4158 4135 4159 4136 /** 4160 4137 * devm_clk_unregister - resource managed clk_unregister() 4138 + * @dev: device that is unregistering the clock data 4161 4139 * @clk: clock to unregister 4162 4140 * 4163 4141 * Deallocate a clock allocated with devm_clk_register(). Normally ··· 4348 4324 * @node: Pointer to device tree node of clock provider 4349 4325 * @get: Get clock callback. Returns NULL or a struct clk for the 4350 4326 * given clock specifier 4327 + * @get_hw: Get clk_hw callback. Returns NULL, ERR_PTR or a 4328 + * struct clk_hw for the given clock specifier 4351 4329 * @data: context pointer to be passed into @get callback 4352 4330 */ 4353 4331 struct of_clk_provider {
+1 -1
drivers/clk/davinci/pll.c
··· 651 651 pllcmd = readl(pll->base + PLLCMD); 652 652 pllcmd |= PLLCMD_GOSET; 653 653 writel(pllcmd, pll->base + PLLCMD); 654 - /* fallthrough */ 654 + fallthrough; 655 655 case PRE_RATE_CHANGE: 656 656 /* Wait until for outstanding changes to take effect */ 657 657 do {
+2 -2
drivers/clk/imx/clk-pllv3.c
··· 433 433 break; 434 434 case IMX_PLLV3_USB_VF610: 435 435 pll->div_shift = 1; 436 - /* fall through */ 436 + fallthrough; 437 437 case IMX_PLLV3_USB: 438 438 ops = &clk_pllv3_ops; 439 439 pll->powerup_set = true; ··· 441 441 case IMX_PLLV3_AV_IMX7: 442 442 pll->num_offset = PLL_IMX7_NUM_OFFSET; 443 443 pll->denom_offset = PLL_IMX7_DENOM_OFFSET; 444 - /* fall through */ 444 + fallthrough; 445 445 case IMX_PLLV3_AV: 446 446 ops = &clk_pllv3_av_ops; 447 447 break;
+91 -74
drivers/clk/ingenic/jz4780-cgu.c
··· 4 4 * 5 5 * Copyright (c) 2013-2015 Imagination Technologies 6 6 * Author: Paul Burton <paul.burton@mips.com> 7 + * Copyright (c) 2020 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com> 7 8 */ 8 9 9 10 #include <linux/clk-provider.h> ··· 20 19 21 20 /* CGU register offsets */ 22 21 #define CGU_REG_CLOCKCONTROL 0x00 23 - #define CGU_REG_LCR 0x04 24 - #define CGU_REG_APLL 0x10 25 - #define CGU_REG_MPLL 0x14 26 - #define CGU_REG_EPLL 0x18 27 - #define CGU_REG_VPLL 0x1c 28 - #define CGU_REG_CLKGR0 0x20 29 - #define CGU_REG_OPCR 0x24 30 - #define CGU_REG_CLKGR1 0x28 31 - #define CGU_REG_DDRCDR 0x2c 32 - #define CGU_REG_VPUCDR 0x30 33 - #define CGU_REG_USBPCR 0x3c 34 - #define CGU_REG_USBRDT 0x40 35 - #define CGU_REG_USBVBFIL 0x44 36 - #define CGU_REG_USBPCR1 0x48 37 - #define CGU_REG_LP0CDR 0x54 38 - #define CGU_REG_I2SCDR 0x60 39 - #define CGU_REG_LP1CDR 0x64 40 - #define CGU_REG_MSC0CDR 0x68 41 - #define CGU_REG_UHCCDR 0x6c 42 - #define CGU_REG_SSICDR 0x74 43 - #define CGU_REG_CIMCDR 0x7c 44 - #define CGU_REG_PCMCDR 0x84 45 - #define CGU_REG_GPUCDR 0x88 46 - #define CGU_REG_HDMICDR 0x8c 47 - #define CGU_REG_MSC1CDR 0xa4 48 - #define CGU_REG_MSC2CDR 0xa8 49 - #define CGU_REG_BCHCDR 0xac 50 - #define CGU_REG_CLOCKSTATUS 0xd4 22 + #define CGU_REG_LCR 0x04 23 + #define CGU_REG_APLL 0x10 24 + #define CGU_REG_MPLL 0x14 25 + #define CGU_REG_EPLL 0x18 26 + #define CGU_REG_VPLL 0x1c 27 + #define CGU_REG_CLKGR0 0x20 28 + #define CGU_REG_OPCR 0x24 29 + #define CGU_REG_CLKGR1 0x28 30 + #define CGU_REG_DDRCDR 0x2c 31 + #define CGU_REG_VPUCDR 0x30 32 + #define CGU_REG_USBPCR 0x3c 33 + #define CGU_REG_USBRDT 0x40 34 + #define CGU_REG_USBVBFIL 0x44 35 + #define CGU_REG_USBPCR1 0x48 36 + #define CGU_REG_LP0CDR 0x54 37 + #define CGU_REG_I2SCDR 0x60 38 + #define CGU_REG_LP1CDR 0x64 39 + #define CGU_REG_MSC0CDR 0x68 40 + #define CGU_REG_UHCCDR 0x6c 41 + #define CGU_REG_SSICDR 0x74 42 + #define CGU_REG_CIMCDR 0x7c 43 + #define CGU_REG_PCMCDR 0x84 44 + #define CGU_REG_GPUCDR 0x88 45 + #define CGU_REG_HDMICDR 0x8c 46 + #define CGU_REG_MSC1CDR 0xa4 47 + #define CGU_REG_MSC2CDR 0xa8 48 + #define CGU_REG_BCHCDR 0xac 49 + #define CGU_REG_CLOCKSTATUS 0xd4 51 50 52 51 /* bits within the OPCR register */ 53 - #define OPCR_SPENDN0 BIT(7) 54 - #define OPCR_SPENDN1 BIT(6) 52 + #define OPCR_SPENDN0 BIT(7) 53 + #define OPCR_SPENDN1 BIT(6) 55 54 56 55 /* bits within the USBPCR register */ 57 - #define USBPCR_USB_MODE BIT(31) 56 + #define USBPCR_USB_MODE BIT(31) 58 57 #define USBPCR_IDPULLUP_MASK (0x3 << 28) 59 - #define USBPCR_COMMONONN BIT(25) 60 - #define USBPCR_VBUSVLDEXT BIT(24) 58 + #define USBPCR_COMMONONN BIT(25) 59 + #define USBPCR_VBUSVLDEXT BIT(24) 61 60 #define USBPCR_VBUSVLDEXTSEL BIT(23) 62 - #define USBPCR_POR BIT(22) 63 - #define USBPCR_OTG_DISABLE BIT(20) 61 + #define USBPCR_POR BIT(22) 62 + #define USBPCR_SIDDQ BIT(21) 63 + #define USBPCR_OTG_DISABLE BIT(20) 64 64 #define USBPCR_COMPDISTUNE_MASK (0x7 << 17) 65 - #define USBPCR_OTGTUNE_MASK (0x7 << 14) 65 + #define USBPCR_OTGTUNE_MASK (0x7 << 14) 66 66 #define USBPCR_SQRXTUNE_MASK (0x7 << 11) 67 67 #define USBPCR_TXFSLSTUNE_MASK (0xf << 7) 68 68 #define USBPCR_TXPREEMPHTUNE BIT(6) ··· 80 78 #define USBPCR1_REFCLKDIV_48 (0x2 << USBPCR1_REFCLKDIV_SHIFT) 81 79 #define USBPCR1_REFCLKDIV_24 (0x1 << USBPCR1_REFCLKDIV_SHIFT) 82 80 #define USBPCR1_REFCLKDIV_12 (0x0 << USBPCR1_REFCLKDIV_SHIFT) 83 - #define USBPCR1_USB_SEL BIT(28) 84 - #define USBPCR1_WORD_IF0 BIT(19) 85 - #define USBPCR1_WORD_IF1 BIT(18) 81 + #define USBPCR1_USB_SEL BIT(28) 82 + #define USBPCR1_WORD_IF0 BIT(19) 83 + #define USBPCR1_WORD_IF1 BIT(18) 86 84 87 85 /* bits within the USBRDT register */ 88 - #define USBRDT_VBFIL_LD_EN BIT(25) 89 - #define USBRDT_USBRDT_MASK 0x7fffff 86 + #define USBRDT_VBFIL_LD_EN BIT(25) 87 + #define USBRDT_USBRDT_MASK 0x7fffff 90 88 91 89 /* bits within the USBVBFIL register */ 92 90 #define USBVBFIL_IDDIGFIL_SHIFT 16 ··· 94 92 #define USBVBFIL_USBVBFIL_MASK (0xffff) 95 93 96 94 /* bits within the LCR register */ 97 - #define LCR_PD_SCPU BIT(31) 98 - #define LCR_SCPUS BIT(27) 95 + #define LCR_PD_SCPU BIT(31) 96 + #define LCR_SCPUS BIT(27) 99 97 100 98 /* bits within the CLKGR1 register */ 101 - #define CLKGR1_CORE1 BIT(15) 99 + #define CLKGR1_CORE1 BIT(15) 102 100 103 101 static struct ingenic_cgu *cgu; 104 - 105 - static u8 jz4780_otg_phy_get_parent(struct clk_hw *hw) 106 - { 107 - /* we only use CLKCORE, revisit if that ever changes */ 108 - return 0; 109 - } 110 - 111 - static int jz4780_otg_phy_set_parent(struct clk_hw *hw, u8 idx) 112 - { 113 - unsigned long flags; 114 - u32 usbpcr1; 115 - 116 - if (idx > 0) 117 - return -EINVAL; 118 - 119 - spin_lock_irqsave(&cgu->lock, flags); 120 - 121 - usbpcr1 = readl(cgu->base + CGU_REG_USBPCR1); 122 - usbpcr1 &= ~USBPCR1_REFCLKSEL_MASK; 123 - /* we only use CLKCORE */ 124 - usbpcr1 |= USBPCR1_REFCLKSEL_CORE; 125 - writel(usbpcr1, cgu->base + CGU_REG_USBPCR1); 126 - 127 - spin_unlock_irqrestore(&cgu->lock, flags); 128 - return 0; 129 - } 130 102 131 103 static unsigned long jz4780_otg_phy_recalc_rate(struct clk_hw *hw, 132 104 unsigned long parent_rate) ··· 125 149 return 19200000; 126 150 } 127 151 128 - BUG(); 129 152 return parent_rate; 130 153 } 131 154 ··· 181 206 return 0; 182 207 } 183 208 184 - static const struct clk_ops jz4780_otg_phy_ops = { 185 - .get_parent = jz4780_otg_phy_get_parent, 186 - .set_parent = jz4780_otg_phy_set_parent, 209 + static int jz4780_otg_phy_enable(struct clk_hw *hw) 210 + { 211 + void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR; 212 + void __iomem *reg_usbpcr = cgu->base + CGU_REG_USBPCR; 187 213 214 + writel(readl(reg_opcr) | OPCR_SPENDN0, reg_opcr); 215 + writel(readl(reg_usbpcr) & ~USBPCR_OTG_DISABLE & ~USBPCR_SIDDQ, reg_usbpcr); 216 + return 0; 217 + } 218 + 219 + static void jz4780_otg_phy_disable(struct clk_hw *hw) 220 + { 221 + void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR; 222 + void __iomem *reg_usbpcr = cgu->base + CGU_REG_USBPCR; 223 + 224 + writel(readl(reg_opcr) & ~OPCR_SPENDN0, reg_opcr); 225 + writel(readl(reg_usbpcr) | USBPCR_OTG_DISABLE | USBPCR_SIDDQ, reg_usbpcr); 226 + } 227 + 228 + static int jz4780_otg_phy_is_enabled(struct clk_hw *hw) 229 + { 230 + void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR; 231 + void __iomem *reg_usbpcr = cgu->base + CGU_REG_USBPCR; 232 + 233 + return (readl(reg_opcr) & OPCR_SPENDN0) && 234 + !(readl(reg_usbpcr) & USBPCR_SIDDQ) && 235 + !(readl(reg_usbpcr) & USBPCR_OTG_DISABLE); 236 + } 237 + 238 + static const struct clk_ops jz4780_otg_phy_ops = { 188 239 .recalc_rate = jz4780_otg_phy_recalc_rate, 189 240 .round_rate = jz4780_otg_phy_round_rate, 190 241 .set_rate = jz4780_otg_phy_set_rate, 242 + 243 + .enable = jz4780_otg_phy_enable, 244 + .disable = jz4780_otg_phy_disable, 245 + .is_enabled = jz4780_otg_phy_is_enabled, 191 246 }; 192 247 193 248 static int jz4780_core1_enable(struct clk_hw *hw) ··· 519 514 .mux = { CGU_REG_BCHCDR, 30, 2 }, 520 515 .div = { CGU_REG_BCHCDR, 0, 1, 4, 29, 28, 27 }, 521 516 .gate = { CGU_REG_CLKGR0, 1 }, 517 + }, 518 + 519 + [JZ4780_CLK_EXCLK_DIV512] = { 520 + "exclk_div512", CGU_CLK_FIXDIV, 521 + .parents = { JZ4780_CLK_EXCLK }, 522 + .fixdiv = { 512 }, 523 + }, 524 + 525 + [JZ4780_CLK_RTC] = { 526 + "rtc_ercs", CGU_CLK_MUX | CGU_CLK_GATE, 527 + .parents = { JZ4780_CLK_EXCLK_DIV512, JZ4780_CLK_RTCLK }, 528 + .mux = { CGU_REG_OPCR, 2, 1}, 522 529 }, 523 530 524 531 /* Gate-only clocks */
+96 -1
drivers/clk/ingenic/x1000-cgu.c
··· 48 48 #define USBPCR_SIDDQ BIT(21) 49 49 #define USBPCR_OTG_DISABLE BIT(20) 50 50 51 + /* bits within the USBPCR1 register */ 52 + #define USBPCR1_REFCLKSEL_SHIFT 26 53 + #define USBPCR1_REFCLKSEL_MASK (0x3 << USBPCR1_REFCLKSEL_SHIFT) 54 + #define USBPCR1_REFCLKSEL_CORE (0x2 << USBPCR1_REFCLKSEL_SHIFT) 55 + #define USBPCR1_REFCLKDIV_SHIFT 24 56 + #define USBPCR1_REFCLKDIV_MASK (0x3 << USBPCR1_REFCLKDIV_SHIFT) 57 + #define USBPCR1_REFCLKDIV_48 (0x2 << USBPCR1_REFCLKDIV_SHIFT) 58 + #define USBPCR1_REFCLKDIV_24 (0x1 << USBPCR1_REFCLKDIV_SHIFT) 59 + #define USBPCR1_REFCLKDIV_12 (0x0 << USBPCR1_REFCLKDIV_SHIFT) 60 + 51 61 static struct ingenic_cgu *cgu; 62 + 63 + static unsigned long x1000_otg_phy_recalc_rate(struct clk_hw *hw, 64 + unsigned long parent_rate) 65 + { 66 + u32 usbpcr1; 67 + unsigned refclk_div; 68 + 69 + usbpcr1 = readl(cgu->base + CGU_REG_USBPCR1); 70 + refclk_div = usbpcr1 & USBPCR1_REFCLKDIV_MASK; 71 + 72 + switch (refclk_div) { 73 + case USBPCR1_REFCLKDIV_12: 74 + return 12000000; 75 + 76 + case USBPCR1_REFCLKDIV_24: 77 + return 24000000; 78 + 79 + case USBPCR1_REFCLKDIV_48: 80 + return 48000000; 81 + } 82 + 83 + return parent_rate; 84 + } 85 + 86 + static long x1000_otg_phy_round_rate(struct clk_hw *hw, unsigned long req_rate, 87 + unsigned long *parent_rate) 88 + { 89 + if (req_rate < 18000000) 90 + return 12000000; 91 + 92 + if (req_rate < 36000000) 93 + return 24000000; 94 + 95 + return 48000000; 96 + } 97 + 98 + static int x1000_otg_phy_set_rate(struct clk_hw *hw, unsigned long req_rate, 99 + unsigned long parent_rate) 100 + { 101 + unsigned long flags; 102 + u32 usbpcr1, div_bits; 103 + 104 + switch (req_rate) { 105 + case 12000000: 106 + div_bits = USBPCR1_REFCLKDIV_12; 107 + break; 108 + 109 + case 24000000: 110 + div_bits = USBPCR1_REFCLKDIV_24; 111 + break; 112 + 113 + case 48000000: 114 + div_bits = USBPCR1_REFCLKDIV_48; 115 + break; 116 + 117 + default: 118 + return -EINVAL; 119 + } 120 + 121 + spin_lock_irqsave(&cgu->lock, flags); 122 + 123 + usbpcr1 = readl(cgu->base + CGU_REG_USBPCR1); 124 + usbpcr1 &= ~USBPCR1_REFCLKDIV_MASK; 125 + usbpcr1 |= div_bits; 126 + writel(usbpcr1, cgu->base + CGU_REG_USBPCR1); 127 + 128 + spin_unlock_irqrestore(&cgu->lock, flags); 129 + return 0; 130 + } 52 131 53 132 static int x1000_usb_phy_enable(struct clk_hw *hw) 54 133 { ··· 159 80 } 160 81 161 82 static const struct clk_ops x1000_otg_phy_ops = { 83 + .recalc_rate = x1000_otg_phy_recalc_rate, 84 + .round_rate = x1000_otg_phy_round_rate, 85 + .set_rate = x1000_otg_phy_set_rate, 86 + 162 87 .enable = x1000_usb_phy_enable, 163 88 .disable = x1000_usb_phy_disable, 164 89 .is_enabled = x1000_usb_phy_is_enabled, ··· 226 143 .stable_bit = 0, 227 144 }, 228 145 }, 229 - 230 146 231 147 /* Custom (SoC-specific) OTG PHY */ 232 148 ··· 358 276 "ssi_mux", CGU_CLK_MUX, 359 277 .parents = { X1000_CLK_EXCLK, X1000_CLK_SSIPLL_DIV2, -1, -1 }, 360 278 .mux = { CGU_REG_SSICDR, 30, 1 }, 279 + }, 280 + 281 + [X1000_CLK_EXCLK_DIV512] = { 282 + "exclk_div512", CGU_CLK_FIXDIV, 283 + .parents = { X1000_CLK_EXCLK }, 284 + .fixdiv = { 512 }, 285 + }, 286 + 287 + [X1000_CLK_RTC] = { 288 + "rtc_ercs", CGU_CLK_MUX | CGU_CLK_GATE, 289 + .parents = { X1000_CLK_EXCLK_DIV512, X1000_CLK_RTCLK }, 290 + .mux = { CGU_REG_OPCR, 2, 1}, 291 + .gate = { CGU_REG_CLKGR, 27 }, 361 292 }, 362 293 363 294 /* Gate-only clocks */
+13
drivers/clk/ingenic/x1830-cgu.c
··· 329 329 .mux = { CGU_REG_SSICDR, 29, 1 }, 330 330 }, 331 331 332 + [X1830_CLK_EXCLK_DIV512] = { 333 + "exclk_div512", CGU_CLK_FIXDIV, 334 + .parents = { X1830_CLK_EXCLK }, 335 + .fixdiv = { 512 }, 336 + }, 337 + 338 + [X1830_CLK_RTC] = { 339 + "rtc_ercs", CGU_CLK_MUX | CGU_CLK_GATE, 340 + .parents = { X1830_CLK_EXCLK_DIV512, X1830_CLK_RTCLK }, 341 + .mux = { CGU_REG_OPCR, 2, 1}, 342 + .gate = { CGU_REG_CLKGR0, 29 }, 343 + }, 344 + 332 345 /* Gate-only clocks */ 333 346 334 347 [X1830_CLK_EMC] = {
+1
drivers/clk/mmp/clk-pxa168.c
··· 10 10 */ 11 11 12 12 #include <linux/clk.h> 13 + #include <linux/clk/mmp.h> 13 14 #include <linux/module.h> 14 15 #include <linux/kernel.h> 15 16 #include <linux/spinlock.h>
+1
drivers/clk/mmp/clk-pxa910.c
··· 10 10 */ 11 11 12 12 #include <linux/clk.h> 13 + #include <linux/clk/mmp.h> 13 14 #include <linux/module.h> 14 15 #include <linux/kernel.h> 15 16 #include <linux/spinlock.h>
+25
drivers/clk/qcom/Kconfig
··· 308 308 Say Y if you want to use peripheral devices such as UART, SPI, 309 309 I2C, USB, UFS, SDCC, etc. 310 310 311 + config SC_LPASS_CORECC_7180 312 + tristate "SC7180 LPASS Core Clock Controller" 313 + select SC_GCC_7180 314 + help 315 + Support for the LPASS(Low Power Audio Subsystem) core clock controller 316 + on SC7180 devices. 317 + Say Y if you want to use LPASS clocks and power domains of the LPASS 318 + core clock controller. 319 + 311 320 config SC_GPUCC_7180 312 321 tristate "SC7180 Graphics Clock Controller" 313 322 select SC_GCC_7180 ··· 427 418 Support for the global clock controller on SM8250 devices. 428 419 Say Y if you want to use peripheral devices such as UART, 429 420 SPI, I2C, USB, SD/UFS, PCIe etc. 421 + 422 + config SM_GPUCC_8150 423 + tristate "SM8150 Graphics Clock Controller" 424 + select SM_GCC_8150 425 + help 426 + Support for the graphics clock controller on SM8150 devices. 427 + Say Y if you want to support graphics controller devices and 428 + functionality such as 3D graphics. 429 + 430 + config SM_GPUCC_8250 431 + tristate "SM8250 Graphics Clock Controller" 432 + select SM_GCC_8250 433 + help 434 + Support for the graphics clock controller on SM8250 devices. 435 + Say Y if you want to support graphics controller devices and 436 + functionality such as 3D graphics. 430 437 431 438 config SPMI_PMIC_CLKDIV 432 439 tristate "SPMI PMIC clkdiv Support"
+3
drivers/clk/qcom/Makefile
··· 54 54 obj-$(CONFIG_SC_DISPCC_7180) += dispcc-sc7180.o 55 55 obj-$(CONFIG_SC_GCC_7180) += gcc-sc7180.o 56 56 obj-$(CONFIG_SC_GPUCC_7180) += gpucc-sc7180.o 57 + obj-$(CONFIG_SC_LPASS_CORECC_7180) += lpasscorecc-sc7180.o 57 58 obj-$(CONFIG_SC_MSS_7180) += mss-sc7180.o 58 59 obj-$(CONFIG_SC_VIDEOCC_7180) += videocc-sc7180.o 59 60 obj-$(CONFIG_SDM_CAMCC_845) += camcc-sdm845.o ··· 66 65 obj-$(CONFIG_SDM_VIDEOCC_845) += videocc-sdm845.o 67 66 obj-$(CONFIG_SM_GCC_8150) += gcc-sm8150.o 68 67 obj-$(CONFIG_SM_GCC_8250) += gcc-sm8250.o 68 + obj-$(CONFIG_SM_GPUCC_8150) += gpucc-sm8150.o 69 + obj-$(CONFIG_SM_GPUCC_8250) += gpucc-sm8250.o 69 70 obj-$(CONFIG_SPMI_PMIC_CLKDIV) += clk-spmi-pmic-div.o 70 71 obj-$(CONFIG_KPSS_XCC) += kpss-xcc.o 71 72 obj-$(CONFIG_QCOM_HFPLL) += hfpll.o
+38 -40
drivers/clk/qcom/clk-alpha-pll.c
··· 56 56 #define PLL_STATUS(p) ((p)->offset + (p)->regs[PLL_OFF_STATUS]) 57 57 #define PLL_OPMODE(p) ((p)->offset + (p)->regs[PLL_OFF_OPMODE]) 58 58 #define PLL_FRAC(p) ((p)->offset + (p)->regs[PLL_OFF_FRAC]) 59 - #define PLL_CAL_VAL(p) ((p)->offset + (p)->regs[PLL_OFF_CAL_VAL]) 60 59 61 60 const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = { 62 61 [CLK_ALPHA_PLL_TYPE_DEFAULT] = { ··· 111 112 [PLL_OFF_CONFIG_CTL_U1] = 0x20, 112 113 [PLL_OFF_TEST_CTL] = 0x24, 113 114 [PLL_OFF_TEST_CTL_U] = 0x28, 114 - [PLL_OFF_STATUS] = 0x30, 115 - [PLL_OFF_OPMODE] = 0x38, 116 - [PLL_OFF_ALPHA_VAL] = 0x40, 117 - [PLL_OFF_CAL_VAL] = 0x44, 118 - }, 119 - [CLK_ALPHA_PLL_TYPE_LUCID] = { 120 - [PLL_OFF_L_VAL] = 0x04, 121 - [PLL_OFF_CAL_L_VAL] = 0x08, 122 - [PLL_OFF_USER_CTL] = 0x0c, 123 - [PLL_OFF_USER_CTL_U] = 0x10, 124 - [PLL_OFF_USER_CTL_U1] = 0x14, 125 - [PLL_OFF_CONFIG_CTL] = 0x18, 126 - [PLL_OFF_CONFIG_CTL_U] = 0x1c, 127 - [PLL_OFF_CONFIG_CTL_U1] = 0x20, 128 - [PLL_OFF_TEST_CTL] = 0x24, 129 - [PLL_OFF_TEST_CTL_U] = 0x28, 130 115 [PLL_OFF_TEST_CTL_U1] = 0x2c, 131 116 [PLL_OFF_STATUS] = 0x30, 132 117 [PLL_OFF_OPMODE] = 0x38, ··· 139 156 #define PLL_OUT_MASK 0x7 140 157 #define PLL_RATE_MARGIN 500 141 158 159 + /* TRION PLL specific settings and offsets */ 160 + #define TRION_PLL_CAL_VAL 0x44 161 + #define TRION_PCAL_DONE BIT(26) 162 + 142 163 /* LUCID PLL specific settings and offsets */ 143 - #define LUCID_PLL_CAL_VAL 0x44 144 - #define LUCID_PCAL_DONE BIT(26) 164 + #define LUCID_PCAL_DONE BIT(27) 145 165 146 166 #define pll_alpha_width(p) \ 147 167 ((PLL_ALPHA_VAL_U(p) - PLL_ALPHA_VAL(p) == 4) ? \ ··· 898 912 }; 899 913 EXPORT_SYMBOL_GPL(clk_alpha_pll_hwfsm_ops); 900 914 901 - const struct clk_ops clk_trion_fixed_pll_ops = { 915 + const struct clk_ops clk_alpha_pll_fixed_trion_ops = { 902 916 .enable = clk_trion_pll_enable, 903 917 .disable = clk_trion_pll_disable, 904 918 .is_enabled = clk_trion_pll_is_enabled, 905 919 .recalc_rate = clk_trion_pll_recalc_rate, 906 920 .round_rate = clk_alpha_pll_round_rate, 907 921 }; 908 - EXPORT_SYMBOL_GPL(clk_trion_fixed_pll_ops); 922 + EXPORT_SYMBOL_GPL(clk_alpha_pll_fixed_trion_ops); 909 923 910 924 static unsigned long 911 925 clk_alpha_pll_postdiv_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) ··· 1325 1339 val << PLL_POST_DIV_SHIFT); 1326 1340 } 1327 1341 1328 - const struct clk_ops clk_trion_pll_postdiv_ops = { 1342 + const struct clk_ops clk_alpha_pll_postdiv_trion_ops = { 1329 1343 .recalc_rate = clk_trion_pll_postdiv_recalc_rate, 1330 1344 .round_rate = clk_trion_pll_postdiv_round_rate, 1331 1345 .set_rate = clk_trion_pll_postdiv_set_rate, 1332 1346 }; 1333 - EXPORT_SYMBOL_GPL(clk_trion_pll_postdiv_ops); 1347 + EXPORT_SYMBOL_GPL(clk_alpha_pll_postdiv_trion_ops); 1334 1348 1335 1349 static long clk_alpha_pll_postdiv_fabia_round_rate(struct clk_hw *hw, 1336 1350 unsigned long rate, unsigned long *prate) ··· 1385 1399 * @regmap: register map 1386 1400 * @config: configuration to apply for pll 1387 1401 */ 1388 - void clk_lucid_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, 1402 + void clk_trion_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, 1389 1403 const struct alpha_pll_config *config) 1390 1404 { 1391 1405 if (config->l) 1392 1406 regmap_write(regmap, PLL_L_VAL(pll), config->l); 1393 1407 1394 - regmap_write(regmap, PLL_CAL_L_VAL(pll), LUCID_PLL_CAL_VAL); 1408 + regmap_write(regmap, PLL_CAL_L_VAL(pll), TRION_PLL_CAL_VAL); 1395 1409 1396 1410 if (config->alpha) 1397 1411 regmap_write(regmap, PLL_ALPHA_VAL(pll), config->alpha); ··· 1444 1458 /* Place the PLL in STANDBY mode */ 1445 1459 regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N, PLL_RESET_N); 1446 1460 } 1447 - EXPORT_SYMBOL_GPL(clk_lucid_pll_configure); 1461 + EXPORT_SYMBOL_GPL(clk_trion_pll_configure); 1448 1462 1449 1463 /* 1450 - * The Lucid PLL requires a power-on self-calibration which happens when the 1464 + * The TRION PLL requires a power-on self-calibration which happens when the 1451 1465 * PLL comes out of reset. Calibrate in case it is not completed. 1452 1466 */ 1453 - static int alpha_pll_lucid_prepare(struct clk_hw *hw) 1467 + static int __alpha_pll_trion_prepare(struct clk_hw *hw, u32 pcal_done) 1454 1468 { 1455 1469 struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); 1456 1470 u32 regval; ··· 1458 1472 1459 1473 /* Return early if calibration is not needed. */ 1460 1474 regmap_read(pll->clkr.regmap, PLL_STATUS(pll), &regval); 1461 - if (regval & LUCID_PCAL_DONE) 1475 + if (regval & pcal_done) 1462 1476 return 0; 1463 1477 1464 1478 /* On/off to calibrate */ ··· 1469 1483 return ret; 1470 1484 } 1471 1485 1472 - static int alpha_pll_lucid_set_rate(struct clk_hw *hw, unsigned long rate, 1486 + static int alpha_pll_trion_prepare(struct clk_hw *hw) 1487 + { 1488 + return __alpha_pll_trion_prepare(hw, TRION_PCAL_DONE); 1489 + } 1490 + 1491 + static int alpha_pll_lucid_prepare(struct clk_hw *hw) 1492 + { 1493 + return __alpha_pll_trion_prepare(hw, LUCID_PCAL_DONE); 1494 + } 1495 + 1496 + static int alpha_pll_trion_set_rate(struct clk_hw *hw, unsigned long rate, 1473 1497 unsigned long prate) 1474 1498 { 1475 1499 struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); ··· 1533 1537 return 0; 1534 1538 } 1535 1539 1540 + const struct clk_ops clk_alpha_pll_trion_ops = { 1541 + .prepare = alpha_pll_trion_prepare, 1542 + .enable = clk_trion_pll_enable, 1543 + .disable = clk_trion_pll_disable, 1544 + .is_enabled = clk_trion_pll_is_enabled, 1545 + .recalc_rate = clk_trion_pll_recalc_rate, 1546 + .round_rate = clk_alpha_pll_round_rate, 1547 + .set_rate = alpha_pll_trion_set_rate, 1548 + }; 1549 + EXPORT_SYMBOL_GPL(clk_alpha_pll_trion_ops); 1550 + 1536 1551 const struct clk_ops clk_alpha_pll_lucid_ops = { 1537 1552 .prepare = alpha_pll_lucid_prepare, 1538 1553 .enable = clk_trion_pll_enable, ··· 1551 1544 .is_enabled = clk_trion_pll_is_enabled, 1552 1545 .recalc_rate = clk_trion_pll_recalc_rate, 1553 1546 .round_rate = clk_alpha_pll_round_rate, 1554 - .set_rate = alpha_pll_lucid_set_rate, 1547 + .set_rate = alpha_pll_trion_set_rate, 1555 1548 }; 1556 1549 EXPORT_SYMBOL_GPL(clk_alpha_pll_lucid_ops); 1557 - 1558 - const struct clk_ops clk_alpha_pll_fixed_lucid_ops = { 1559 - .enable = clk_trion_pll_enable, 1560 - .disable = clk_trion_pll_disable, 1561 - .is_enabled = clk_trion_pll_is_enabled, 1562 - .recalc_rate = clk_trion_pll_recalc_rate, 1563 - .round_rate = clk_alpha_pll_round_rate, 1564 - }; 1565 - EXPORT_SYMBOL_GPL(clk_alpha_pll_fixed_lucid_ops); 1566 1550 1567 1551 const struct clk_ops clk_alpha_pll_postdiv_lucid_ops = { 1568 1552 .recalc_rate = clk_alpha_pll_postdiv_fabia_recalc_rate,
+10 -5
drivers/clk/qcom/clk-alpha-pll.h
··· 14 14 CLK_ALPHA_PLL_TYPE_BRAMMO, 15 15 CLK_ALPHA_PLL_TYPE_FABIA, 16 16 CLK_ALPHA_PLL_TYPE_TRION, 17 - CLK_ALPHA_PLL_TYPE_LUCID, 17 + CLK_ALPHA_PLL_TYPE_LUCID = CLK_ALPHA_PLL_TYPE_TRION, 18 18 CLK_ALPHA_PLL_TYPE_MAX, 19 19 }; 20 20 ··· 134 134 extern const struct clk_ops clk_alpha_pll_fixed_fabia_ops; 135 135 extern const struct clk_ops clk_alpha_pll_postdiv_fabia_ops; 136 136 137 + extern const struct clk_ops clk_alpha_pll_trion_ops; 138 + extern const struct clk_ops clk_alpha_pll_fixed_trion_ops; 139 + extern const struct clk_ops clk_alpha_pll_postdiv_trion_ops; 140 + 137 141 extern const struct clk_ops clk_alpha_pll_lucid_ops; 138 - extern const struct clk_ops clk_alpha_pll_fixed_lucid_ops; 142 + #define clk_alpha_pll_fixed_lucid_ops clk_alpha_pll_fixed_trion_ops 139 143 extern const struct clk_ops clk_alpha_pll_postdiv_lucid_ops; 140 144 141 145 void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, 142 146 const struct alpha_pll_config *config); 143 147 void clk_fabia_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, 144 148 const struct alpha_pll_config *config); 145 - void clk_lucid_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, 149 + void clk_trion_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, 146 150 const struct alpha_pll_config *config); 151 + #define clk_lucid_pll_configure(pll, regmap, config) \ 152 + clk_trion_pll_configure(pll, regmap, config) 147 153 148 - extern const struct clk_ops clk_trion_fixed_pll_ops; 149 - extern const struct clk_ops clk_trion_pll_postdiv_ops; 154 + 150 155 151 156 #endif
+14
drivers/clk/qcom/gcc-sc7180.c
··· 2251 2251 }, 2252 2252 }; 2253 2253 2254 + static struct clk_branch gcc_lpass_cfg_noc_sway_clk = { 2255 + .halt_reg = 0x47018, 2256 + .halt_check = BRANCH_HALT_DELAY, 2257 + .clkr = { 2258 + .enable_reg = 0x47018, 2259 + .enable_mask = BIT(0), 2260 + .hw.init = &(struct clk_init_data){ 2261 + .name = "gcc_lpass_cfg_noc_sway_clk", 2262 + .ops = &clk_branch2_ops, 2263 + }, 2264 + }, 2265 + }; 2266 + 2254 2267 static struct gdsc ufs_phy_gdsc = { 2255 2268 .gdscr = 0x77004, 2256 2269 .pd = { ··· 2441 2428 [GCC_MSS_Q6_MEMNOC_AXI_CLK] = &gcc_mss_q6_memnoc_axi_clk.clkr, 2442 2429 [GCC_MSS_SNOC_AXI_CLK] = &gcc_mss_snoc_axi_clk.clkr, 2443 2430 [GCC_SEC_CTRL_CLK_SRC] = &gcc_sec_ctrl_clk_src.clkr, 2431 + [GCC_LPASS_CFG_NOC_SWAY_CLK] = &gcc_lpass_cfg_noc_sway_clk.clkr, 2444 2432 }; 2445 2433 2446 2434 static const struct qcom_reset_map gcc_sc7180_resets[] = {
+4
drivers/clk/qcom/gcc-sdm660.c
··· 1715 1715 1716 1716 static struct clk_branch gcc_mss_mnoc_bimc_axi_clk = { 1717 1717 .halt_reg = 0x8a004, 1718 + .halt_check = BRANCH_HALT, 1719 + .hwcg_reg = 0x8a004, 1720 + .hwcg_bit = 1, 1718 1721 .clkr = { 1719 1722 .enable_reg = 0x8a004, 1720 1723 .enable_mask = BIT(0), ··· 2405 2402 [GCC_USB_20_BCR] = { 0x2f000 }, 2406 2403 [GCC_USB_30_BCR] = { 0xf000 }, 2407 2404 [GCC_USB_PHY_CFG_AHB2PHY_BCR] = { 0x6a000 }, 2405 + [GCC_MSS_RESTART] = { 0x79000 }, 2408 2406 }; 2409 2407 2410 2408 static const struct regmap_config gcc_sdm660_regmap_config = {
+10 -16
drivers/clk/qcom/gcc-sm8150.c
··· 34 34 P_SLEEP_CLK, 35 35 }; 36 36 37 - static const struct pll_vco trion_vco[] = { 38 - { 249600000, 2000000000, 0 }, 39 - }; 40 - 41 37 static struct clk_alpha_pll gpll0 = { 42 38 .offset = 0x0, 43 - .vco_table = trion_vco, 44 - .num_vco = ARRAY_SIZE(trion_vco), 45 39 .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TRION], 46 40 .clkr = { 47 41 .enable_reg = 0x52000, ··· 47 53 .name = "bi_tcxo", 48 54 }, 49 55 .num_parents = 1, 50 - .ops = &clk_trion_fixed_pll_ops, 56 + .ops = &clk_alpha_pll_fixed_trion_ops, 51 57 }, 52 58 }, 53 59 }; ··· 73 79 .hw = &gpll0.clkr.hw, 74 80 }, 75 81 .num_parents = 1, 76 - .ops = &clk_trion_pll_postdiv_ops, 82 + .ops = &clk_alpha_pll_postdiv_trion_ops, 77 83 }, 78 84 }; 79 85 80 86 static struct clk_alpha_pll gpll7 = { 81 87 .offset = 0x1a000, 82 - .vco_table = trion_vco, 83 - .num_vco = ARRAY_SIZE(trion_vco), 84 88 .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TRION], 85 89 .clkr = { 86 90 .enable_reg = 0x52000, ··· 90 98 .name = "bi_tcxo", 91 99 }, 92 100 .num_parents = 1, 93 - .ops = &clk_trion_fixed_pll_ops, 101 + .ops = &clk_alpha_pll_fixed_trion_ops, 94 102 }, 95 103 }, 96 104 }; 97 105 98 106 static struct clk_alpha_pll gpll9 = { 99 107 .offset = 0x1c000, 100 - .vco_table = trion_vco, 101 - .num_vco = ARRAY_SIZE(trion_vco), 102 108 .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TRION], 103 109 .clkr = { 104 110 .enable_reg = 0x52000, ··· 108 118 .name = "bi_tcxo", 109 119 }, 110 120 .num_parents = 1, 111 - .ops = &clk_trion_fixed_pll_ops, 121 + .ops = &clk_alpha_pll_fixed_trion_ops, 112 122 }, 113 123 }, 114 124 }; ··· 1607 1617 }; 1608 1618 1609 1619 static struct clk_branch gcc_gpu_gpll0_clk_src = { 1620 + .halt_check = BRANCH_HALT_SKIP, 1610 1621 .clkr = { 1611 1622 .enable_reg = 0x52004, 1612 1623 .enable_mask = BIT(15), ··· 1623 1632 }; 1624 1633 1625 1634 static struct clk_branch gcc_gpu_gpll0_div_clk_src = { 1635 + .halt_check = BRANCH_HALT_SKIP, 1626 1636 .clkr = { 1627 1637 .enable_reg = 0x52004, 1628 1638 .enable_mask = BIT(16), 1629 1639 .hw.init = &(struct clk_init_data){ 1630 1640 .name = "gcc_gpu_gpll0_div_clk_src", 1631 1641 .parent_hws = (const struct clk_hw *[]){ 1632 - &gcc_gpu_gpll0_clk_src.clkr.hw }, 1642 + &gpll0_out_even.clkr.hw }, 1633 1643 .num_parents = 1, 1634 1644 .flags = CLK_SET_RATE_PARENT, 1635 1645 .ops = &clk_branch2_ops, ··· 1721 1729 }; 1722 1730 1723 1731 static struct clk_branch gcc_npu_gpll0_clk_src = { 1732 + .halt_check = BRANCH_HALT_SKIP, 1724 1733 .clkr = { 1725 1734 .enable_reg = 0x52004, 1726 1735 .enable_mask = BIT(18), ··· 1737 1744 }; 1738 1745 1739 1746 static struct clk_branch gcc_npu_gpll0_div_clk_src = { 1747 + .halt_check = BRANCH_HALT_SKIP, 1740 1748 .clkr = { 1741 1749 .enable_reg = 0x52004, 1742 1750 .enable_mask = BIT(19), 1743 1751 .hw.init = &(struct clk_init_data){ 1744 1752 .name = "gcc_npu_gpll0_div_clk_src", 1745 1753 .parent_hws = (const struct clk_hw *[]){ 1746 - &gcc_npu_gpll0_clk_src.clkr.hw }, 1754 + &gpll0_out_even.clkr.hw }, 1747 1755 .num_parents = 1, 1748 1756 .flags = CLK_SET_RATE_PARENT, 1749 1757 .ops = &clk_branch2_ops,
+39
drivers/clk/qcom/gdsc.c
··· 6 6 #include <linux/bitops.h> 7 7 #include <linux/delay.h> 8 8 #include <linux/err.h> 9 + #include <linux/export.h> 9 10 #include <linux/jiffies.h> 10 11 #include <linux/kernel.h> 11 12 #include <linux/ktime.h> ··· 30 29 /* CFG_GDSCR */ 31 30 #define GDSC_POWER_UP_COMPLETE BIT(16) 32 31 #define GDSC_POWER_DOWN_COMPLETE BIT(15) 32 + #define GDSC_RETAIN_FF_ENABLE BIT(11) 33 33 #define CFG_GDSCR_OFFSET 0x4 34 34 35 35 /* Wait 2^n CXO cycles between all states. Here, n=2 (4 cycles). */ ··· 218 216 regmap_update_bits(sc->regmap, sc->clamp_io_ctrl, 219 217 GMEM_RESET_MASK, 0); 220 218 } 219 + 220 + static void gdsc_retain_ff_on(struct gdsc *sc) 221 + { 222 + u32 mask = GDSC_RETAIN_FF_ENABLE; 223 + 224 + regmap_update_bits(sc->regmap, sc->gdscr, mask, mask); 225 + } 226 + 221 227 static int gdsc_enable(struct generic_pm_domain *domain) 222 228 { 223 229 struct gdsc *sc = domain_to_gdsc(domain); ··· 277 267 */ 278 268 udelay(1); 279 269 } 270 + 271 + if (sc->flags & RETAIN_FF_ENABLE) 272 + gdsc_retain_ff_on(sc); 280 273 281 274 return 0; 282 275 } ··· 446 433 } 447 434 of_genpd_del_provider(dev->of_node); 448 435 } 436 + 437 + /* 438 + * On SDM845+ the GPU GX domain is *almost* entirely controlled by the GMU 439 + * running in the CX domain so the CPU doesn't need to know anything about the 440 + * GX domain EXCEPT.... 441 + * 442 + * Hardware constraints dictate that the GX be powered down before the CX. If 443 + * the GMU crashes it could leave the GX on. In order to successfully bring back 444 + * the device the CPU needs to disable the GX headswitch. There being no sane 445 + * way to reach in and touch that register from deep inside the GPU driver we 446 + * need to set up the infrastructure to be able to ensure that the GPU can 447 + * ensure that the GX is off during this super special case. We do this by 448 + * defining a GX gdsc with a dummy enable function and a "default" disable 449 + * function. 450 + * 451 + * This allows us to attach with genpd_dev_pm_attach_by_name() in the GPU 452 + * driver. During power up, nothing will happen from the CPU (and the GMU will 453 + * power up normally but during power down this will ensure that the GX domain 454 + * is *really* off - this gives us a semi standard way of doing what we need. 455 + */ 456 + int gdsc_gx_do_nothing_enable(struct generic_pm_domain *domain) 457 + { 458 + /* Do nothing but give genpd the impression that we were successful */ 459 + return 0; 460 + } 461 + EXPORT_SYMBOL_GPL(gdsc_gx_do_nothing_enable);
+2
drivers/clk/qcom/gdsc.h
··· 50 50 #define AON_RESET BIT(4) 51 51 #define POLL_CFG_GDSCR BIT(5) 52 52 #define ALWAYS_ON BIT(6) 53 + #define RETAIN_FF_ENABLE BIT(7) 53 54 struct reset_controller_dev *rcdev; 54 55 unsigned int *resets; 55 56 unsigned int reset_count; ··· 69 68 int gdsc_register(struct gdsc_desc *desc, struct reset_controller_dev *, 70 69 struct regmap *); 71 70 void gdsc_unregister(struct gdsc_desc *desc); 71 + int gdsc_gx_do_nothing_enable(struct generic_pm_domain *domain); 72 72 #else 73 73 static inline int gdsc_register(struct gdsc_desc *desc, 74 74 struct reset_controller_dev *rcdev,
+1 -26
drivers/clk/qcom/gpucc-sc7180.c
··· 170 170 .flags = VOTABLE, 171 171 }; 172 172 173 - /* 174 - * On SC7180 the GPU GX domain is *almost* entirely controlled by the GMU 175 - * running in the CX domain so the CPU doesn't need to know anything about the 176 - * GX domain EXCEPT.... 177 - * 178 - * Hardware constraints dictate that the GX be powered down before the CX. If 179 - * the GMU crashes it could leave the GX on. In order to successfully bring back 180 - * the device the CPU needs to disable the GX headswitch. There being no sane 181 - * way to reach in and touch that register from deep inside the GPU driver we 182 - * need to set up the infrastructure to be able to ensure that the GPU can 183 - * ensure that the GX is off during this super special case. We do this by 184 - * defining a GX gdsc with a dummy enable function and a "default" disable 185 - * function. 186 - * 187 - * This allows us to attach with genpd_dev_pm_attach_by_name() in the GPU 188 - * driver. During power up, nothing will happen from the CPU (and the GMU will 189 - * power up normally but during power down this will ensure that the GX domain 190 - * is *really* off - this gives us a semi standard way of doing what we need. 191 - */ 192 - static int gx_gdsc_enable(struct generic_pm_domain *domain) 193 - { 194 - /* Do nothing but give genpd the impression that we were successful */ 195 - return 0; 196 - } 197 - 198 173 static struct gdsc gx_gdsc = { 199 174 .gdscr = 0x100c, 200 175 .clamp_io_ctrl = 0x1508, 201 176 .pd = { 202 177 .name = "gx_gdsc", 203 - .power_on = gx_gdsc_enable, 178 + .power_on = gdsc_gx_do_nothing_enable, 204 179 }, 205 180 .pwrsts = PWRSTS_OFF_ON, 206 181 .flags = CLAMP_IO,
+1 -26
drivers/clk/qcom/gpucc-sdm845.c
··· 131 131 .flags = VOTABLE, 132 132 }; 133 133 134 - /* 135 - * On SDM845 the GPU GX domain is *almost* entirely controlled by the GMU 136 - * running in the CX domain so the CPU doesn't need to know anything about the 137 - * GX domain EXCEPT.... 138 - * 139 - * Hardware constraints dictate that the GX be powered down before the CX. If 140 - * the GMU crashes it could leave the GX on. In order to successfully bring back 141 - * the device the CPU needs to disable the GX headswitch. There being no sane 142 - * way to reach in and touch that register from deep inside the GPU driver we 143 - * need to set up the infrastructure to be able to ensure that the GPU can 144 - * ensure that the GX is off during this super special case. We do this by 145 - * defining a GX gdsc with a dummy enable function and a "default" disable 146 - * function. 147 - * 148 - * This allows us to attach with genpd_dev_pm_attach_by_name() in the GPU 149 - * driver. During power up, nothing will happen from the CPU (and the GMU will 150 - * power up normally but during power down this will ensure that the GX domain 151 - * is *really* off - this gives us a semi standard way of doing what we need. 152 - */ 153 - static int gx_gdsc_enable(struct generic_pm_domain *domain) 154 - { 155 - /* Do nothing but give genpd the impression that we were successful */ 156 - return 0; 157 - } 158 - 159 134 static struct gdsc gpu_gx_gdsc = { 160 135 .gdscr = 0x100c, 161 136 .clamp_io_ctrl = 0x1508, 162 137 .pd = { 163 138 .name = "gpu_gx_gdsc", 164 - .power_on = gx_gdsc_enable, 139 + .power_on = gdsc_gx_do_nothing_enable, 165 140 }, 166 141 .pwrsts = PWRSTS_OFF_ON, 167 142 .flags = CLAMP_IO | AON_RESET | POLL_CFG_GDSCR,
+320
drivers/clk/qcom/gpucc-sm8150.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. 4 + */ 5 + 6 + #include <linux/clk-provider.h> 7 + #include <linux/module.h> 8 + #include <linux/platform_device.h> 9 + #include <linux/regmap.h> 10 + 11 + #include <dt-bindings/clock/qcom,gpucc-sm8150.h> 12 + 13 + #include "common.h" 14 + #include "clk-alpha-pll.h" 15 + #include "clk-branch.h" 16 + #include "clk-pll.h" 17 + #include "clk-rcg.h" 18 + #include "clk-regmap.h" 19 + #include "reset.h" 20 + #include "gdsc.h" 21 + 22 + enum { 23 + P_BI_TCXO, 24 + P_CORE_BI_PLL_TEST_SE, 25 + P_GPLL0_OUT_MAIN, 26 + P_GPLL0_OUT_MAIN_DIV, 27 + P_GPU_CC_PLL1_OUT_MAIN, 28 + }; 29 + 30 + static const struct pll_vco trion_vco[] = { 31 + { 249600000, 2000000000, 0 }, 32 + }; 33 + 34 + static struct alpha_pll_config gpu_cc_pll1_config = { 35 + .l = 0x1a, 36 + .alpha = 0xaaa, 37 + .config_ctl_val = 0x20485699, 38 + .config_ctl_hi_val = 0x00002267, 39 + .config_ctl_hi1_val = 0x00000024, 40 + .test_ctl_val = 0x00000000, 41 + .test_ctl_hi_val = 0x00000002, 42 + .test_ctl_hi1_val = 0x00000000, 43 + .user_ctl_val = 0x00000000, 44 + .user_ctl_hi_val = 0x00000805, 45 + .user_ctl_hi1_val = 0x000000d0, 46 + }; 47 + 48 + static struct clk_alpha_pll gpu_cc_pll1 = { 49 + .offset = 0x100, 50 + .vco_table = trion_vco, 51 + .num_vco = ARRAY_SIZE(trion_vco), 52 + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TRION], 53 + .clkr = { 54 + .hw.init = &(struct clk_init_data){ 55 + .name = "gpu_cc_pll1", 56 + .parent_data = &(const struct clk_parent_data){ 57 + .fw_name = "bi_tcxo", 58 + }, 59 + .num_parents = 1, 60 + .ops = &clk_alpha_pll_trion_ops, 61 + }, 62 + }, 63 + }; 64 + 65 + static const struct parent_map gpu_cc_parent_map_0[] = { 66 + { P_BI_TCXO, 0 }, 67 + { P_GPU_CC_PLL1_OUT_MAIN, 3 }, 68 + { P_GPLL0_OUT_MAIN, 5 }, 69 + { P_GPLL0_OUT_MAIN_DIV, 6 }, 70 + }; 71 + 72 + static const struct clk_parent_data gpu_cc_parent_data_0[] = { 73 + { .fw_name = "bi_tcxo" }, 74 + { .hw = &gpu_cc_pll1.clkr.hw }, 75 + { .fw_name = "gcc_gpu_gpll0_clk_src" }, 76 + { .fw_name = "gcc_gpu_gpll0_div_clk_src" }, 77 + }; 78 + 79 + static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = { 80 + F(19200000, P_BI_TCXO, 1, 0, 0), 81 + F(200000000, P_GPLL0_OUT_MAIN_DIV, 1.5, 0, 0), 82 + F(500000000, P_GPU_CC_PLL1_OUT_MAIN, 1, 0, 0), 83 + { } 84 + }; 85 + 86 + static struct clk_rcg2 gpu_cc_gmu_clk_src = { 87 + .cmd_rcgr = 0x1120, 88 + .mnd_width = 0, 89 + .hid_width = 5, 90 + .parent_map = gpu_cc_parent_map_0, 91 + .freq_tbl = ftbl_gpu_cc_gmu_clk_src, 92 + .clkr.hw.init = &(struct clk_init_data){ 93 + .name = "gpu_cc_gmu_clk_src", 94 + .parent_data = gpu_cc_parent_data_0, 95 + .num_parents = ARRAY_SIZE(gpu_cc_parent_data_0), 96 + .flags = CLK_SET_RATE_PARENT, 97 + .ops = &clk_rcg2_ops, 98 + }, 99 + }; 100 + 101 + static struct clk_branch gpu_cc_ahb_clk = { 102 + .halt_reg = 0x1078, 103 + .halt_check = BRANCH_HALT_DELAY, 104 + .clkr = { 105 + .enable_reg = 0x1078, 106 + .enable_mask = BIT(0), 107 + .hw.init = &(struct clk_init_data){ 108 + .name = "gpu_cc_ahb_clk", 109 + .ops = &clk_branch2_ops, 110 + }, 111 + }, 112 + }; 113 + 114 + static struct clk_branch gpu_cc_crc_ahb_clk = { 115 + .halt_reg = 0x107c, 116 + .halt_check = BRANCH_HALT, 117 + .clkr = { 118 + .enable_reg = 0x107c, 119 + .enable_mask = BIT(0), 120 + .hw.init = &(struct clk_init_data){ 121 + .name = "gpu_cc_crc_ahb_clk", 122 + .ops = &clk_branch2_ops, 123 + }, 124 + }, 125 + }; 126 + 127 + static struct clk_branch gpu_cc_cx_apb_clk = { 128 + .halt_reg = 0x1088, 129 + .halt_check = BRANCH_HALT, 130 + .clkr = { 131 + .enable_reg = 0x1088, 132 + .enable_mask = BIT(0), 133 + .hw.init = &(struct clk_init_data){ 134 + .name = "gpu_cc_cx_apb_clk", 135 + .ops = &clk_branch2_ops, 136 + }, 137 + }, 138 + }; 139 + 140 + static struct clk_branch gpu_cc_cx_gmu_clk = { 141 + .halt_reg = 0x1098, 142 + .halt_check = BRANCH_HALT, 143 + .clkr = { 144 + .enable_reg = 0x1098, 145 + .enable_mask = BIT(0), 146 + .hw.init = &(struct clk_init_data){ 147 + .name = "gpu_cc_cx_gmu_clk", 148 + .parent_data = &(const struct clk_parent_data){ 149 + .hw = &gpu_cc_gmu_clk_src.clkr.hw, 150 + }, 151 + .num_parents = 1, 152 + .flags = CLK_SET_RATE_PARENT, 153 + .ops = &clk_branch2_ops, 154 + }, 155 + }, 156 + }; 157 + 158 + static struct clk_branch gpu_cc_cx_snoc_dvm_clk = { 159 + .halt_reg = 0x108c, 160 + .halt_check = BRANCH_HALT, 161 + .clkr = { 162 + .enable_reg = 0x108c, 163 + .enable_mask = BIT(0), 164 + .hw.init = &(struct clk_init_data){ 165 + .name = "gpu_cc_cx_snoc_dvm_clk", 166 + .ops = &clk_branch2_ops, 167 + }, 168 + }, 169 + }; 170 + 171 + static struct clk_branch gpu_cc_cxo_aon_clk = { 172 + .halt_reg = 0x1004, 173 + .halt_check = BRANCH_HALT, 174 + .clkr = { 175 + .enable_reg = 0x1004, 176 + .enable_mask = BIT(0), 177 + .hw.init = &(struct clk_init_data){ 178 + .name = "gpu_cc_cxo_aon_clk", 179 + .ops = &clk_branch2_ops, 180 + }, 181 + }, 182 + }; 183 + 184 + static struct clk_branch gpu_cc_cxo_clk = { 185 + .halt_reg = 0x109c, 186 + .halt_check = BRANCH_HALT, 187 + .clkr = { 188 + .enable_reg = 0x109c, 189 + .enable_mask = BIT(0), 190 + .hw.init = &(struct clk_init_data){ 191 + .name = "gpu_cc_cxo_clk", 192 + .ops = &clk_branch2_ops, 193 + }, 194 + }, 195 + }; 196 + 197 + static struct clk_branch gpu_cc_gx_gmu_clk = { 198 + .halt_reg = 0x1064, 199 + .halt_check = BRANCH_HALT, 200 + .clkr = { 201 + .enable_reg = 0x1064, 202 + .enable_mask = BIT(0), 203 + .hw.init = &(struct clk_init_data){ 204 + .name = "gpu_cc_gx_gmu_clk", 205 + .parent_data = &(const struct clk_parent_data){ 206 + .hw = &gpu_cc_gmu_clk_src.clkr.hw, 207 + }, 208 + .num_parents = 1, 209 + .flags = CLK_SET_RATE_PARENT, 210 + .ops = &clk_branch2_ops, 211 + }, 212 + }, 213 + }; 214 + 215 + static struct gdsc gpu_cx_gdsc = { 216 + .gdscr = 0x106c, 217 + .gds_hw_ctrl = 0x1540, 218 + .pd = { 219 + .name = "gpu_cx_gdsc", 220 + }, 221 + .pwrsts = PWRSTS_OFF_ON, 222 + .flags = VOTABLE, 223 + }; 224 + 225 + static struct gdsc gpu_gx_gdsc = { 226 + .gdscr = 0x100c, 227 + .clamp_io_ctrl = 0x1508, 228 + .pd = { 229 + .name = "gpu_gx_gdsc", 230 + .power_on = gdsc_gx_do_nothing_enable, 231 + }, 232 + .pwrsts = PWRSTS_OFF_ON, 233 + .flags = CLAMP_IO | AON_RESET | POLL_CFG_GDSCR, 234 + }; 235 + 236 + static struct clk_regmap *gpu_cc_sm8150_clocks[] = { 237 + [GPU_CC_AHB_CLK] = &gpu_cc_ahb_clk.clkr, 238 + [GPU_CC_CRC_AHB_CLK] = &gpu_cc_crc_ahb_clk.clkr, 239 + [GPU_CC_CX_APB_CLK] = &gpu_cc_cx_apb_clk.clkr, 240 + [GPU_CC_CX_GMU_CLK] = &gpu_cc_cx_gmu_clk.clkr, 241 + [GPU_CC_CX_SNOC_DVM_CLK] = &gpu_cc_cx_snoc_dvm_clk.clkr, 242 + [GPU_CC_CXO_AON_CLK] = &gpu_cc_cxo_aon_clk.clkr, 243 + [GPU_CC_CXO_CLK] = &gpu_cc_cxo_clk.clkr, 244 + [GPU_CC_GMU_CLK_SRC] = &gpu_cc_gmu_clk_src.clkr, 245 + [GPU_CC_GX_GMU_CLK] = &gpu_cc_gx_gmu_clk.clkr, 246 + [GPU_CC_PLL1] = &gpu_cc_pll1.clkr, 247 + }; 248 + 249 + static const struct qcom_reset_map gpu_cc_sm8150_resets[] = { 250 + [GPUCC_GPU_CC_CX_BCR] = { 0x1068 }, 251 + [GPUCC_GPU_CC_GMU_BCR] = { 0x111c }, 252 + [GPUCC_GPU_CC_GX_BCR] = { 0x1008 }, 253 + [GPUCC_GPU_CC_SPDM_BCR] = { 0x1110 }, 254 + [GPUCC_GPU_CC_XO_BCR] = { 0x1000 }, 255 + }; 256 + 257 + static struct gdsc *gpu_cc_sm8150_gdscs[] = { 258 + [GPU_CX_GDSC] = &gpu_cx_gdsc, 259 + [GPU_GX_GDSC] = &gpu_gx_gdsc, 260 + }; 261 + 262 + static const struct regmap_config gpu_cc_sm8150_regmap_config = { 263 + .reg_bits = 32, 264 + .reg_stride = 4, 265 + .val_bits = 32, 266 + .max_register = 0x8008, 267 + .fast_io = true, 268 + }; 269 + 270 + static const struct qcom_cc_desc gpu_cc_sm8150_desc = { 271 + .config = &gpu_cc_sm8150_regmap_config, 272 + .clks = gpu_cc_sm8150_clocks, 273 + .num_clks = ARRAY_SIZE(gpu_cc_sm8150_clocks), 274 + .resets = gpu_cc_sm8150_resets, 275 + .num_resets = ARRAY_SIZE(gpu_cc_sm8150_resets), 276 + .gdscs = gpu_cc_sm8150_gdscs, 277 + .num_gdscs = ARRAY_SIZE(gpu_cc_sm8150_gdscs), 278 + }; 279 + 280 + static const struct of_device_id gpu_cc_sm8150_match_table[] = { 281 + { .compatible = "qcom,sm8150-gpucc" }, 282 + { } 283 + }; 284 + MODULE_DEVICE_TABLE(of, gpu_cc_sm8150_match_table); 285 + 286 + static int gpu_cc_sm8150_probe(struct platform_device *pdev) 287 + { 288 + struct regmap *regmap; 289 + 290 + regmap = qcom_cc_map(pdev, &gpu_cc_sm8150_desc); 291 + if (IS_ERR(regmap)) 292 + return PTR_ERR(regmap); 293 + 294 + clk_trion_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config); 295 + 296 + return qcom_cc_really_probe(pdev, &gpu_cc_sm8150_desc, regmap); 297 + } 298 + 299 + static struct platform_driver gpu_cc_sm8150_driver = { 300 + .probe = gpu_cc_sm8150_probe, 301 + .driver = { 302 + .name = "sm8150-gpucc", 303 + .of_match_table = gpu_cc_sm8150_match_table, 304 + }, 305 + }; 306 + 307 + static int __init gpu_cc_sm8150_init(void) 308 + { 309 + return platform_driver_register(&gpu_cc_sm8150_driver); 310 + } 311 + subsys_initcall(gpu_cc_sm8150_init); 312 + 313 + static void __exit gpu_cc_sm8150_exit(void) 314 + { 315 + platform_driver_unregister(&gpu_cc_sm8150_driver); 316 + } 317 + module_exit(gpu_cc_sm8150_exit); 318 + 319 + MODULE_DESCRIPTION("QTI GPUCC SM8150 Driver"); 320 + MODULE_LICENSE("GPL v2");
+348
drivers/clk/qcom/gpucc-sm8250.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. 4 + */ 5 + 6 + #include <linux/clk-provider.h> 7 + #include <linux/module.h> 8 + #include <linux/platform_device.h> 9 + #include <linux/regmap.h> 10 + 11 + #include <dt-bindings/clock/qcom,gpucc-sm8250.h> 12 + 13 + #include "common.h" 14 + #include "clk-alpha-pll.h" 15 + #include "clk-branch.h" 16 + #include "clk-pll.h" 17 + #include "clk-rcg.h" 18 + #include "clk-regmap.h" 19 + #include "reset.h" 20 + #include "gdsc.h" 21 + 22 + #define CX_GMU_CBCR_SLEEP_MASK 0xf 23 + #define CX_GMU_CBCR_SLEEP_SHIFT 4 24 + #define CX_GMU_CBCR_WAKE_MASK 0xf 25 + #define CX_GMU_CBCR_WAKE_SHIFT 8 26 + 27 + enum { 28 + P_BI_TCXO, 29 + P_CORE_BI_PLL_TEST_SE, 30 + P_GPLL0_OUT_MAIN, 31 + P_GPLL0_OUT_MAIN_DIV, 32 + P_GPU_CC_PLL0_OUT_MAIN, 33 + P_GPU_CC_PLL1_OUT_MAIN, 34 + }; 35 + 36 + static struct pll_vco lucid_vco[] = { 37 + { 249600000, 2000000000, 0 }, 38 + }; 39 + 40 + static const struct alpha_pll_config gpu_cc_pll1_config = { 41 + .l = 0x1a, 42 + .alpha = 0xaaa, 43 + .config_ctl_val = 0x20485699, 44 + .config_ctl_hi_val = 0x00002261, 45 + .config_ctl_hi1_val = 0x029a699c, 46 + .user_ctl_val = 0x00000000, 47 + .user_ctl_hi_val = 0x00000805, 48 + .user_ctl_hi1_val = 0x00000000, 49 + }; 50 + 51 + static struct clk_alpha_pll gpu_cc_pll1 = { 52 + .offset = 0x100, 53 + .vco_table = lucid_vco, 54 + .num_vco = ARRAY_SIZE(lucid_vco), 55 + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID], 56 + .clkr = { 57 + .hw.init = &(struct clk_init_data){ 58 + .name = "gpu_cc_pll1", 59 + .parent_data = &(const struct clk_parent_data){ 60 + .fw_name = "bi_tcxo", 61 + }, 62 + .num_parents = 1, 63 + .ops = &clk_alpha_pll_lucid_ops, 64 + }, 65 + }, 66 + }; 67 + 68 + static const struct parent_map gpu_cc_parent_map_0[] = { 69 + { P_BI_TCXO, 0 }, 70 + { P_GPU_CC_PLL1_OUT_MAIN, 3 }, 71 + { P_GPLL0_OUT_MAIN, 5 }, 72 + { P_GPLL0_OUT_MAIN_DIV, 6 }, 73 + }; 74 + 75 + static const struct clk_parent_data gpu_cc_parent_data_0[] = { 76 + { .fw_name = "bi_tcxo" }, 77 + { .hw = &gpu_cc_pll1.clkr.hw }, 78 + { .fw_name = "gcc_gpu_gpll0_clk_src" }, 79 + { .fw_name = "gcc_gpu_gpll0_div_clk_src" }, 80 + }; 81 + 82 + static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = { 83 + F(19200000, P_BI_TCXO, 1, 0, 0), 84 + F(200000000, P_GPLL0_OUT_MAIN_DIV, 1.5, 0, 0), 85 + F(500000000, P_GPU_CC_PLL1_OUT_MAIN, 1, 0, 0), 86 + { } 87 + }; 88 + 89 + static struct clk_rcg2 gpu_cc_gmu_clk_src = { 90 + .cmd_rcgr = 0x1120, 91 + .mnd_width = 0, 92 + .hid_width = 5, 93 + .parent_map = gpu_cc_parent_map_0, 94 + .freq_tbl = ftbl_gpu_cc_gmu_clk_src, 95 + .clkr.hw.init = &(struct clk_init_data){ 96 + .name = "gpu_cc_gmu_clk_src", 97 + .parent_data = gpu_cc_parent_data_0, 98 + .num_parents = ARRAY_SIZE(gpu_cc_parent_data_0), 99 + .flags = CLK_SET_RATE_PARENT, 100 + .ops = &clk_rcg2_ops, 101 + }, 102 + }; 103 + 104 + static struct clk_branch gpu_cc_ahb_clk = { 105 + .halt_reg = 0x1078, 106 + .halt_check = BRANCH_HALT_DELAY, 107 + .clkr = { 108 + .enable_reg = 0x1078, 109 + .enable_mask = BIT(0), 110 + .hw.init = &(struct clk_init_data){ 111 + .name = "gpu_cc_ahb_clk", 112 + .ops = &clk_branch2_ops, 113 + }, 114 + }, 115 + }; 116 + 117 + static struct clk_branch gpu_cc_crc_ahb_clk = { 118 + .halt_reg = 0x107c, 119 + .halt_check = BRANCH_HALT_VOTED, 120 + .clkr = { 121 + .enable_reg = 0x107c, 122 + .enable_mask = BIT(0), 123 + .hw.init = &(struct clk_init_data){ 124 + .name = "gpu_cc_crc_ahb_clk", 125 + .ops = &clk_branch2_ops, 126 + }, 127 + }, 128 + }; 129 + 130 + static struct clk_branch gpu_cc_cx_apb_clk = { 131 + .halt_reg = 0x1088, 132 + .halt_check = BRANCH_HALT_VOTED, 133 + .clkr = { 134 + .enable_reg = 0x1088, 135 + .enable_mask = BIT(0), 136 + .hw.init = &(struct clk_init_data){ 137 + .name = "gpu_cc_cx_apb_clk", 138 + .ops = &clk_branch2_ops, 139 + }, 140 + }, 141 + }; 142 + 143 + static struct clk_branch gpu_cc_cx_gmu_clk = { 144 + .halt_reg = 0x1098, 145 + .halt_check = BRANCH_HALT, 146 + .clkr = { 147 + .enable_reg = 0x1098, 148 + .enable_mask = BIT(0), 149 + .hw.init = &(struct clk_init_data){ 150 + .name = "gpu_cc_cx_gmu_clk", 151 + .parent_data = &(const struct clk_parent_data){ 152 + .hw = &gpu_cc_gmu_clk_src.clkr.hw, 153 + }, 154 + .num_parents = 1, 155 + .flags = CLK_SET_RATE_PARENT, 156 + .ops = &clk_branch2_ops, 157 + }, 158 + }, 159 + }; 160 + 161 + static struct clk_branch gpu_cc_cx_snoc_dvm_clk = { 162 + .halt_reg = 0x108c, 163 + .halt_check = BRANCH_HALT_VOTED, 164 + .clkr = { 165 + .enable_reg = 0x108c, 166 + .enable_mask = BIT(0), 167 + .hw.init = &(struct clk_init_data){ 168 + .name = "gpu_cc_cx_snoc_dvm_clk", 169 + .ops = &clk_branch2_ops, 170 + }, 171 + }, 172 + }; 173 + 174 + static struct clk_branch gpu_cc_cxo_aon_clk = { 175 + .halt_reg = 0x1004, 176 + .halt_check = BRANCH_HALT_VOTED, 177 + .clkr = { 178 + .enable_reg = 0x1004, 179 + .enable_mask = BIT(0), 180 + .hw.init = &(struct clk_init_data){ 181 + .name = "gpu_cc_cxo_aon_clk", 182 + .ops = &clk_branch2_ops, 183 + }, 184 + }, 185 + }; 186 + 187 + static struct clk_branch gpu_cc_cxo_clk = { 188 + .halt_reg = 0x109c, 189 + .halt_check = BRANCH_HALT, 190 + .clkr = { 191 + .enable_reg = 0x109c, 192 + .enable_mask = BIT(0), 193 + .hw.init = &(struct clk_init_data){ 194 + .name = "gpu_cc_cxo_clk", 195 + .ops = &clk_branch2_ops, 196 + }, 197 + }, 198 + }; 199 + 200 + static struct clk_branch gpu_cc_gx_gmu_clk = { 201 + .halt_reg = 0x1064, 202 + .halt_check = BRANCH_HALT, 203 + .clkr = { 204 + .enable_reg = 0x1064, 205 + .enable_mask = BIT(0), 206 + .hw.init = &(struct clk_init_data){ 207 + .name = "gpu_cc_gx_gmu_clk", 208 + .parent_data = &(const struct clk_parent_data){ 209 + .hw = &gpu_cc_gmu_clk_src.clkr.hw, 210 + }, 211 + .num_parents = 1, 212 + .flags = CLK_SET_RATE_PARENT, 213 + .ops = &clk_branch2_ops, 214 + }, 215 + }, 216 + }; 217 + 218 + static struct clk_branch gpu_cc_hlos1_vote_gpu_smmu_clk = { 219 + .halt_reg = 0x5000, 220 + .halt_check = BRANCH_VOTED, 221 + .clkr = { 222 + .enable_reg = 0x5000, 223 + .enable_mask = BIT(0), 224 + .hw.init = &(struct clk_init_data){ 225 + .name = "gpu_cc_hlos1_vote_gpu_smmu_clk", 226 + .ops = &clk_branch2_ops, 227 + }, 228 + }, 229 + }; 230 + 231 + static struct gdsc gpu_cx_gdsc = { 232 + .gdscr = 0x106c, 233 + .gds_hw_ctrl = 0x1540, 234 + .pd = { 235 + .name = "gpu_cx_gdsc", 236 + }, 237 + .pwrsts = PWRSTS_OFF_ON, 238 + .flags = VOTABLE, 239 + }; 240 + 241 + static struct gdsc gpu_gx_gdsc = { 242 + .gdscr = 0x100c, 243 + .clamp_io_ctrl = 0x1508, 244 + .pd = { 245 + .name = "gpu_gx_gdsc", 246 + .power_on = gdsc_gx_do_nothing_enable, 247 + }, 248 + .pwrsts = PWRSTS_OFF_ON, 249 + .flags = CLAMP_IO | AON_RESET | POLL_CFG_GDSCR, 250 + }; 251 + 252 + static struct clk_regmap *gpu_cc_sm8250_clocks[] = { 253 + [GPU_CC_AHB_CLK] = &gpu_cc_ahb_clk.clkr, 254 + [GPU_CC_CRC_AHB_CLK] = &gpu_cc_crc_ahb_clk.clkr, 255 + [GPU_CC_CX_APB_CLK] = &gpu_cc_cx_apb_clk.clkr, 256 + [GPU_CC_CX_GMU_CLK] = &gpu_cc_cx_gmu_clk.clkr, 257 + [GPU_CC_CX_SNOC_DVM_CLK] = &gpu_cc_cx_snoc_dvm_clk.clkr, 258 + [GPU_CC_CXO_AON_CLK] = &gpu_cc_cxo_aon_clk.clkr, 259 + [GPU_CC_CXO_CLK] = &gpu_cc_cxo_clk.clkr, 260 + [GPU_CC_GMU_CLK_SRC] = &gpu_cc_gmu_clk_src.clkr, 261 + [GPU_CC_GX_GMU_CLK] = &gpu_cc_gx_gmu_clk.clkr, 262 + [GPU_CC_PLL1] = &gpu_cc_pll1.clkr, 263 + [GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK] = &gpu_cc_hlos1_vote_gpu_smmu_clk.clkr, 264 + }; 265 + 266 + static const struct qcom_reset_map gpu_cc_sm8250_resets[] = { 267 + [GPUCC_GPU_CC_ACD_BCR] = { 0x1160 }, 268 + [GPUCC_GPU_CC_CX_BCR] = { 0x1068 }, 269 + [GPUCC_GPU_CC_GFX3D_AON_BCR] = { 0x10a0 }, 270 + [GPUCC_GPU_CC_GMU_BCR] = { 0x111c }, 271 + [GPUCC_GPU_CC_GX_BCR] = { 0x1008 }, 272 + [GPUCC_GPU_CC_XO_BCR] = { 0x1000 }, 273 + }; 274 + 275 + static struct gdsc *gpu_cc_sm8250_gdscs[] = { 276 + [GPU_CX_GDSC] = &gpu_cx_gdsc, 277 + [GPU_GX_GDSC] = &gpu_gx_gdsc, 278 + }; 279 + 280 + static const struct regmap_config gpu_cc_sm8250_regmap_config = { 281 + .reg_bits = 32, 282 + .reg_stride = 4, 283 + .val_bits = 32, 284 + .max_register = 0x8008, 285 + .fast_io = true, 286 + }; 287 + 288 + static const struct qcom_cc_desc gpu_cc_sm8250_desc = { 289 + .config = &gpu_cc_sm8250_regmap_config, 290 + .clks = gpu_cc_sm8250_clocks, 291 + .num_clks = ARRAY_SIZE(gpu_cc_sm8250_clocks), 292 + .resets = gpu_cc_sm8250_resets, 293 + .num_resets = ARRAY_SIZE(gpu_cc_sm8250_resets), 294 + .gdscs = gpu_cc_sm8250_gdscs, 295 + .num_gdscs = ARRAY_SIZE(gpu_cc_sm8250_gdscs), 296 + }; 297 + 298 + static const struct of_device_id gpu_cc_sm8250_match_table[] = { 299 + { .compatible = "qcom,sm8250-gpucc" }, 300 + { } 301 + }; 302 + MODULE_DEVICE_TABLE(of, gpu_cc_sm8250_match_table); 303 + 304 + static int gpu_cc_sm8250_probe(struct platform_device *pdev) 305 + { 306 + struct regmap *regmap; 307 + unsigned int value, mask; 308 + 309 + regmap = qcom_cc_map(pdev, &gpu_cc_sm8250_desc); 310 + if (IS_ERR(regmap)) 311 + return PTR_ERR(regmap); 312 + 313 + clk_lucid_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config); 314 + 315 + /* 316 + * Configure gpu_cc_cx_gmu_clk with recommended 317 + * wakeup/sleep settings 318 + */ 319 + mask = CX_GMU_CBCR_WAKE_MASK << CX_GMU_CBCR_WAKE_SHIFT; 320 + mask |= CX_GMU_CBCR_SLEEP_MASK << CX_GMU_CBCR_SLEEP_SHIFT; 321 + value = 0xf << CX_GMU_CBCR_WAKE_SHIFT | 0xf << CX_GMU_CBCR_SLEEP_SHIFT; 322 + regmap_update_bits(regmap, 0x1098, mask, value); 323 + 324 + return qcom_cc_really_probe(pdev, &gpu_cc_sm8250_desc, regmap); 325 + } 326 + 327 + static struct platform_driver gpu_cc_sm8250_driver = { 328 + .probe = gpu_cc_sm8250_probe, 329 + .driver = { 330 + .name = "sm8250-gpucc", 331 + .of_match_table = gpu_cc_sm8250_match_table, 332 + }, 333 + }; 334 + 335 + static int __init gpu_cc_sm8250_init(void) 336 + { 337 + return platform_driver_register(&gpu_cc_sm8250_driver); 338 + } 339 + subsys_initcall(gpu_cc_sm8250_init); 340 + 341 + static void __exit gpu_cc_sm8250_exit(void) 342 + { 343 + platform_driver_unregister(&gpu_cc_sm8250_driver); 344 + } 345 + module_exit(gpu_cc_sm8250_exit); 346 + 347 + MODULE_DESCRIPTION("QTI GPU_CC SM8250 Driver"); 348 + MODULE_LICENSE("GPL v2");
+476
drivers/clk/qcom/lpasscorecc-sc7180.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright (c) 2020, The Linux Foundation. All rights reserved. 4 + */ 5 + 6 + #include <linux/clk-provider.h> 7 + #include <linux/err.h> 8 + #include <linux/module.h> 9 + #include <linux/of_device.h> 10 + #include <linux/pm_clock.h> 11 + #include <linux/pm_runtime.h> 12 + #include <linux/of.h> 13 + #include <linux/regmap.h> 14 + 15 + #include <dt-bindings/clock/qcom,lpasscorecc-sc7180.h> 16 + 17 + #include "clk-alpha-pll.h" 18 + #include "clk-branch.h" 19 + #include "clk-rcg.h" 20 + #include "clk-regmap.h" 21 + #include "common.h" 22 + #include "gdsc.h" 23 + 24 + enum { 25 + P_BI_TCXO, 26 + P_LPASS_LPAAUDIO_DIG_PLL_OUT_ODD, 27 + P_SLEEP_CLK, 28 + }; 29 + 30 + static struct pll_vco fabia_vco[] = { 31 + { 249600000, 2000000000, 0 }, 32 + }; 33 + 34 + static const struct alpha_pll_config lpass_lpaaudio_dig_pll_config = { 35 + .l = 0x20, 36 + .alpha = 0x0, 37 + .config_ctl_val = 0x20485699, 38 + .config_ctl_hi_val = 0x00002067, 39 + .test_ctl_val = 0x40000000, 40 + .test_ctl_hi_val = 0x00000000, 41 + .user_ctl_val = 0x00005105, 42 + .user_ctl_hi_val = 0x00004805, 43 + }; 44 + 45 + static const u8 clk_alpha_pll_regs_offset[][PLL_OFF_MAX_REGS] = { 46 + [CLK_ALPHA_PLL_TYPE_FABIA] = { 47 + [PLL_OFF_L_VAL] = 0x04, 48 + [PLL_OFF_CAL_L_VAL] = 0x8, 49 + [PLL_OFF_USER_CTL] = 0x0c, 50 + [PLL_OFF_USER_CTL_U] = 0x10, 51 + [PLL_OFF_USER_CTL_U1] = 0x14, 52 + [PLL_OFF_CONFIG_CTL] = 0x18, 53 + [PLL_OFF_CONFIG_CTL_U] = 0x1C, 54 + [PLL_OFF_CONFIG_CTL_U1] = 0x20, 55 + [PLL_OFF_TEST_CTL] = 0x24, 56 + [PLL_OFF_TEST_CTL_U] = 0x28, 57 + [PLL_OFF_STATUS] = 0x30, 58 + [PLL_OFF_OPMODE] = 0x38, 59 + [PLL_OFF_FRAC] = 0x40, 60 + }, 61 + }; 62 + 63 + static struct clk_alpha_pll lpass_lpaaudio_dig_pll = { 64 + .offset = 0x1000, 65 + .vco_table = fabia_vco, 66 + .num_vco = ARRAY_SIZE(fabia_vco), 67 + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_FABIA], 68 + .clkr = { 69 + .hw.init = &(struct clk_init_data){ 70 + .name = "lpass_lpaaudio_dig_pll", 71 + .parent_data = &(const struct clk_parent_data){ 72 + .fw_name = "bi_tcxo", 73 + }, 74 + .num_parents = 1, 75 + .ops = &clk_alpha_pll_fabia_ops, 76 + }, 77 + }, 78 + }; 79 + 80 + static const struct clk_div_table 81 + post_div_table_lpass_lpaaudio_dig_pll_out_odd[] = { 82 + { 0x5, 5 }, 83 + { } 84 + }; 85 + 86 + static struct clk_alpha_pll_postdiv lpass_lpaaudio_dig_pll_out_odd = { 87 + .offset = 0x1000, 88 + .post_div_shift = 12, 89 + .post_div_table = post_div_table_lpass_lpaaudio_dig_pll_out_odd, 90 + .num_post_div = 91 + ARRAY_SIZE(post_div_table_lpass_lpaaudio_dig_pll_out_odd), 92 + .width = 4, 93 + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], 94 + .clkr.hw.init = &(struct clk_init_data){ 95 + .name = "lpass_lpaaudio_dig_pll_out_odd", 96 + .parent_data = &(const struct clk_parent_data){ 97 + .hw = &lpass_lpaaudio_dig_pll.clkr.hw, 98 + }, 99 + .num_parents = 1, 100 + .flags = CLK_SET_RATE_PARENT, 101 + .ops = &clk_alpha_pll_postdiv_fabia_ops, 102 + }, 103 + }; 104 + 105 + static const struct parent_map lpass_core_cc_parent_map_0[] = { 106 + { P_BI_TCXO, 0 }, 107 + { P_LPASS_LPAAUDIO_DIG_PLL_OUT_ODD, 5 }, 108 + }; 109 + 110 + static const struct clk_parent_data lpass_core_cc_parent_data_0[] = { 111 + { .fw_name = "bi_tcxo" }, 112 + { .hw = &lpass_lpaaudio_dig_pll_out_odd.clkr.hw }, 113 + }; 114 + 115 + static const struct parent_map lpass_core_cc_parent_map_2[] = { 116 + { P_BI_TCXO, 0 }, 117 + }; 118 + 119 + static struct clk_rcg2 core_clk_src = { 120 + .cmd_rcgr = 0x1d000, 121 + .mnd_width = 8, 122 + .hid_width = 5, 123 + .parent_map = lpass_core_cc_parent_map_2, 124 + .clkr.hw.init = &(struct clk_init_data){ 125 + .name = "core_clk_src", 126 + .parent_data = &(const struct clk_parent_data){ 127 + .fw_name = "bi_tcxo", 128 + }, 129 + .num_parents = 1, 130 + .ops = &clk_rcg2_ops, 131 + }, 132 + }; 133 + 134 + static const struct freq_tbl ftbl_ext_mclk0_clk_src[] = { 135 + F(9600000, P_BI_TCXO, 2, 0, 0), 136 + F(19200000, P_BI_TCXO, 1, 0, 0), 137 + { } 138 + }; 139 + 140 + static const struct freq_tbl ftbl_ext_lpaif_clk_src[] = { 141 + F(256000, P_LPASS_LPAAUDIO_DIG_PLL_OUT_ODD, 15, 1, 32), 142 + F(512000, P_LPASS_LPAAUDIO_DIG_PLL_OUT_ODD, 15, 1, 16), 143 + F(768000, P_LPASS_LPAAUDIO_DIG_PLL_OUT_ODD, 10, 1, 16), 144 + F(1024000, P_LPASS_LPAAUDIO_DIG_PLL_OUT_ODD, 15, 1, 8), 145 + F(1536000, P_LPASS_LPAAUDIO_DIG_PLL_OUT_ODD, 10, 1, 8), 146 + F(2048000, P_LPASS_LPAAUDIO_DIG_PLL_OUT_ODD, 15, 1, 4), 147 + F(3072000, P_LPASS_LPAAUDIO_DIG_PLL_OUT_ODD, 10, 1, 4), 148 + F(4096000, P_LPASS_LPAAUDIO_DIG_PLL_OUT_ODD, 15, 1, 2), 149 + F(6144000, P_LPASS_LPAAUDIO_DIG_PLL_OUT_ODD, 10, 1, 2), 150 + F(8192000, P_LPASS_LPAAUDIO_DIG_PLL_OUT_ODD, 15, 0, 0), 151 + F(9600000, P_BI_TCXO, 2, 0, 0), 152 + F(12288000, P_LPASS_LPAAUDIO_DIG_PLL_OUT_ODD, 10, 0, 0), 153 + F(19200000, P_BI_TCXO, 1, 0, 0), 154 + F(24576000, P_LPASS_LPAAUDIO_DIG_PLL_OUT_ODD, 5, 0, 0), 155 + { } 156 + }; 157 + 158 + static struct clk_rcg2 ext_mclk0_clk_src = { 159 + .cmd_rcgr = 0x20000, 160 + .mnd_width = 8, 161 + .hid_width = 5, 162 + .parent_map = lpass_core_cc_parent_map_0, 163 + .freq_tbl = ftbl_ext_mclk0_clk_src, 164 + .clkr.hw.init = &(struct clk_init_data){ 165 + .name = "ext_mclk0_clk_src", 166 + .parent_data = lpass_core_cc_parent_data_0, 167 + .num_parents = 2, 168 + .flags = CLK_SET_RATE_PARENT, 169 + .ops = &clk_rcg2_ops, 170 + }, 171 + }; 172 + 173 + static struct clk_rcg2 lpaif_pri_clk_src = { 174 + .cmd_rcgr = 0x10000, 175 + .mnd_width = 16, 176 + .hid_width = 5, 177 + .parent_map = lpass_core_cc_parent_map_0, 178 + .freq_tbl = ftbl_ext_lpaif_clk_src, 179 + .clkr.hw.init = &(struct clk_init_data){ 180 + .name = "lpaif_pri_clk_src", 181 + .parent_data = lpass_core_cc_parent_data_0, 182 + .num_parents = 2, 183 + .flags = CLK_SET_RATE_PARENT, 184 + .ops = &clk_rcg2_ops, 185 + }, 186 + }; 187 + 188 + static struct clk_rcg2 lpaif_sec_clk_src = { 189 + .cmd_rcgr = 0x11000, 190 + .mnd_width = 16, 191 + .hid_width = 5, 192 + .parent_map = lpass_core_cc_parent_map_0, 193 + .freq_tbl = ftbl_ext_lpaif_clk_src, 194 + .clkr.hw.init = &(struct clk_init_data){ 195 + .name = "lpaif_sec_clk_src", 196 + .parent_data = lpass_core_cc_parent_data_0, 197 + .num_parents = 2, 198 + .flags = CLK_SET_RATE_PARENT, 199 + .ops = &clk_rcg2_ops, 200 + }, 201 + }; 202 + 203 + static struct clk_branch lpass_audio_core_ext_mclk0_clk = { 204 + .halt_reg = 0x20014, 205 + .halt_check = BRANCH_HALT, 206 + .hwcg_reg = 0x20014, 207 + .hwcg_bit = 1, 208 + .clkr = { 209 + .enable_reg = 0x20014, 210 + .enable_mask = BIT(0), 211 + .hw.init = &(struct clk_init_data){ 212 + .name = "lpass_audio_core_ext_mclk0_clk", 213 + .parent_data = &(const struct clk_parent_data){ 214 + .hw = &ext_mclk0_clk_src.clkr.hw, 215 + }, 216 + .num_parents = 1, 217 + .flags = CLK_SET_RATE_PARENT, 218 + .ops = &clk_branch2_ops, 219 + }, 220 + }, 221 + }; 222 + 223 + static struct clk_branch lpass_audio_core_lpaif_pri_ibit_clk = { 224 + .halt_reg = 0x10018, 225 + .halt_check = BRANCH_HALT, 226 + .hwcg_reg = 0x10018, 227 + .hwcg_bit = 1, 228 + .clkr = { 229 + .enable_reg = 0x10018, 230 + .enable_mask = BIT(0), 231 + .hw.init = &(struct clk_init_data){ 232 + .name = "lpass_audio_core_lpaif_pri_ibit_clk", 233 + .parent_data = &(const struct clk_parent_data){ 234 + .hw = &lpaif_pri_clk_src.clkr.hw, 235 + }, 236 + .num_parents = 1, 237 + .flags = CLK_SET_RATE_PARENT, 238 + .ops = &clk_branch2_ops, 239 + }, 240 + }, 241 + }; 242 + 243 + static struct clk_branch lpass_audio_core_lpaif_sec_ibit_clk = { 244 + .halt_reg = 0x11018, 245 + .halt_check = BRANCH_HALT, 246 + .hwcg_reg = 0x11018, 247 + .hwcg_bit = 1, 248 + .clkr = { 249 + .enable_reg = 0x11018, 250 + .enable_mask = BIT(0), 251 + .hw.init = &(struct clk_init_data){ 252 + .name = "lpass_audio_core_lpaif_sec_ibit_clk", 253 + .parent_data = &(const struct clk_parent_data){ 254 + .hw = &lpaif_sec_clk_src.clkr.hw, 255 + }, 256 + .num_parents = 1, 257 + .flags = CLK_SET_RATE_PARENT, 258 + .ops = &clk_branch2_ops, 259 + }, 260 + }, 261 + }; 262 + 263 + static struct clk_branch lpass_audio_core_sysnoc_mport_core_clk = { 264 + .halt_reg = 0x23000, 265 + .halt_check = BRANCH_HALT, 266 + .hwcg_reg = 0x23000, 267 + .hwcg_bit = 1, 268 + .clkr = { 269 + .enable_reg = 0x23000, 270 + .enable_mask = BIT(0), 271 + .hw.init = &(struct clk_init_data){ 272 + .name = "lpass_audio_core_sysnoc_mport_core_clk", 273 + .parent_data = &(const struct clk_parent_data){ 274 + .hw = &core_clk_src.clkr.hw, 275 + }, 276 + .num_parents = 1, 277 + .flags = CLK_SET_RATE_PARENT, 278 + .ops = &clk_branch2_ops, 279 + }, 280 + }, 281 + }; 282 + 283 + static struct clk_regmap *lpass_core_cc_sc7180_clocks[] = { 284 + [EXT_MCLK0_CLK_SRC] = &ext_mclk0_clk_src.clkr, 285 + [LPAIF_PRI_CLK_SRC] = &lpaif_pri_clk_src.clkr, 286 + [LPAIF_SEC_CLK_SRC] = &lpaif_sec_clk_src.clkr, 287 + [CORE_CLK_SRC] = &core_clk_src.clkr, 288 + [LPASS_AUDIO_CORE_EXT_MCLK0_CLK] = &lpass_audio_core_ext_mclk0_clk.clkr, 289 + [LPASS_AUDIO_CORE_LPAIF_PRI_IBIT_CLK] = 290 + &lpass_audio_core_lpaif_pri_ibit_clk.clkr, 291 + [LPASS_AUDIO_CORE_LPAIF_SEC_IBIT_CLK] = 292 + &lpass_audio_core_lpaif_sec_ibit_clk.clkr, 293 + [LPASS_AUDIO_CORE_SYSNOC_MPORT_CORE_CLK] = 294 + &lpass_audio_core_sysnoc_mport_core_clk.clkr, 295 + [LPASS_LPAAUDIO_DIG_PLL] = &lpass_lpaaudio_dig_pll.clkr, 296 + [LPASS_LPAAUDIO_DIG_PLL_OUT_ODD] = &lpass_lpaaudio_dig_pll_out_odd.clkr, 297 + }; 298 + 299 + static struct gdsc lpass_pdc_hm_gdsc = { 300 + .gdscr = 0x3090, 301 + .pd = { 302 + .name = "lpass_pdc_hm_gdsc", 303 + }, 304 + .pwrsts = PWRSTS_OFF_ON, 305 + .flags = VOTABLE, 306 + }; 307 + 308 + static struct gdsc lpass_audio_hm_gdsc = { 309 + .gdscr = 0x9090, 310 + .pd = { 311 + .name = "lpass_audio_hm_gdsc", 312 + }, 313 + .pwrsts = PWRSTS_OFF_ON, 314 + }; 315 + 316 + static struct gdsc lpass_core_hm_gdsc = { 317 + .gdscr = 0x0, 318 + .pd = { 319 + .name = "lpass_core_hm_gdsc", 320 + }, 321 + .pwrsts = PWRSTS_OFF_ON, 322 + .flags = RETAIN_FF_ENABLE, 323 + }; 324 + 325 + static struct gdsc *lpass_core_hm_sc7180_gdscs[] = { 326 + [LPASS_CORE_HM_GDSCR] = &lpass_core_hm_gdsc, 327 + }; 328 + 329 + static struct gdsc *lpass_audio_hm_sc7180_gdscs[] = { 330 + [LPASS_PDC_HM_GDSCR] = &lpass_pdc_hm_gdsc, 331 + [LPASS_AUDIO_HM_GDSCR] = &lpass_audio_hm_gdsc, 332 + }; 333 + 334 + static struct regmap_config lpass_core_cc_sc7180_regmap_config = { 335 + .reg_bits = 32, 336 + .reg_stride = 4, 337 + .val_bits = 32, 338 + .fast_io = true, 339 + }; 340 + 341 + static const struct qcom_cc_desc lpass_core_hm_sc7180_desc = { 342 + .config = &lpass_core_cc_sc7180_regmap_config, 343 + .gdscs = lpass_core_hm_sc7180_gdscs, 344 + .num_gdscs = ARRAY_SIZE(lpass_core_hm_sc7180_gdscs), 345 + }; 346 + 347 + static const struct qcom_cc_desc lpass_core_cc_sc7180_desc = { 348 + .config = &lpass_core_cc_sc7180_regmap_config, 349 + .clks = lpass_core_cc_sc7180_clocks, 350 + .num_clks = ARRAY_SIZE(lpass_core_cc_sc7180_clocks), 351 + }; 352 + 353 + static const struct qcom_cc_desc lpass_audio_hm_sc7180_desc = { 354 + .config = &lpass_core_cc_sc7180_regmap_config, 355 + .gdscs = lpass_audio_hm_sc7180_gdscs, 356 + .num_gdscs = ARRAY_SIZE(lpass_audio_hm_sc7180_gdscs), 357 + }; 358 + 359 + static int lpass_core_cc_sc7180_probe(struct platform_device *pdev) 360 + { 361 + const struct qcom_cc_desc *desc; 362 + struct regmap *regmap; 363 + int ret; 364 + 365 + lpass_core_cc_sc7180_regmap_config.name = "lpass_audio_cc"; 366 + desc = &lpass_audio_hm_sc7180_desc; 367 + ret = qcom_cc_probe_by_index(pdev, 1, desc); 368 + if (ret) 369 + return ret; 370 + 371 + lpass_core_cc_sc7180_regmap_config.name = "lpass_core_cc"; 372 + regmap = qcom_cc_map(pdev, &lpass_core_cc_sc7180_desc); 373 + if (IS_ERR(regmap)) 374 + return PTR_ERR(regmap); 375 + 376 + /* 377 + * Keep the CLK always-ON 378 + * LPASS_AUDIO_CORE_SYSNOC_SWAY_CORE_CLK 379 + */ 380 + regmap_update_bits(regmap, 0x24000, BIT(0), BIT(0)); 381 + 382 + /* PLL settings */ 383 + regmap_write(regmap, 0x1008, 0x20); 384 + regmap_update_bits(regmap, 0x1014, BIT(0), BIT(0)); 385 + 386 + clk_fabia_pll_configure(&lpass_lpaaudio_dig_pll, regmap, 387 + &lpass_lpaaudio_dig_pll_config); 388 + 389 + return qcom_cc_really_probe(pdev, &lpass_core_cc_sc7180_desc, regmap); 390 + } 391 + 392 + static int lpass_hm_core_probe(struct platform_device *pdev) 393 + { 394 + const struct qcom_cc_desc *desc; 395 + 396 + lpass_core_cc_sc7180_regmap_config.name = "lpass_hm_core"; 397 + desc = &lpass_core_hm_sc7180_desc; 398 + 399 + return qcom_cc_probe_by_index(pdev, 0, desc); 400 + } 401 + 402 + static const struct of_device_id lpass_core_cc_sc7180_match_table[] = { 403 + { 404 + .compatible = "qcom,sc7180-lpasshm", 405 + .data = lpass_hm_core_probe, 406 + }, 407 + { 408 + .compatible = "qcom,sc7180-lpasscorecc", 409 + .data = lpass_core_cc_sc7180_probe, 410 + }, 411 + { } 412 + }; 413 + MODULE_DEVICE_TABLE(of, lpass_core_cc_sc7180_match_table); 414 + 415 + static int lpass_core_sc7180_probe(struct platform_device *pdev) 416 + { 417 + int (*clk_probe)(struct platform_device *p); 418 + int ret; 419 + 420 + pm_runtime_enable(&pdev->dev); 421 + ret = pm_clk_create(&pdev->dev); 422 + if (ret) 423 + return ret; 424 + 425 + ret = pm_clk_add(&pdev->dev, "iface"); 426 + if (ret < 0) { 427 + dev_err(&pdev->dev, "failed to acquire iface clock\n"); 428 + goto disable_pm_runtime; 429 + } 430 + 431 + clk_probe = of_device_get_match_data(&pdev->dev); 432 + if (!clk_probe) 433 + return -EINVAL; 434 + 435 + ret = clk_probe(pdev); 436 + if (ret) 437 + goto destroy_pm_clk; 438 + 439 + return 0; 440 + 441 + destroy_pm_clk: 442 + pm_clk_destroy(&pdev->dev); 443 + 444 + disable_pm_runtime: 445 + pm_runtime_disable(&pdev->dev); 446 + 447 + return ret; 448 + } 449 + 450 + static const struct dev_pm_ops lpass_core_cc_pm_ops = { 451 + SET_RUNTIME_PM_OPS(pm_clk_suspend, pm_clk_resume, NULL) 452 + }; 453 + 454 + static struct platform_driver lpass_core_cc_sc7180_driver = { 455 + .probe = lpass_core_sc7180_probe, 456 + .driver = { 457 + .name = "lpass_core_cc-sc7180", 458 + .of_match_table = lpass_core_cc_sc7180_match_table, 459 + .pm = &lpass_core_cc_pm_ops, 460 + }, 461 + }; 462 + 463 + static int __init lpass_core_cc_sc7180_init(void) 464 + { 465 + return platform_driver_register(&lpass_core_cc_sc7180_driver); 466 + } 467 + subsys_initcall(lpass_core_cc_sc7180_init); 468 + 469 + static void __exit lpass_core_cc_sc7180_exit(void) 470 + { 471 + platform_driver_unregister(&lpass_core_cc_sc7180_driver); 472 + } 473 + module_exit(lpass_core_cc_sc7180_exit); 474 + 475 + MODULE_DESCRIPTION("QTI LPASS_CORE_CC SC7180 Driver"); 476 + MODULE_LICENSE("GPL v2");
+41 -29
drivers/clk/rockchip/clk-pll.c
··· 12 12 #include <linux/io.h> 13 13 #include <linux/delay.h> 14 14 #include <linux/clk-provider.h> 15 + #include <linux/iopoll.h> 15 16 #include <linux/regmap.h> 16 17 #include <linux/clk.h> 17 18 #include "clk.h" ··· 87 86 { 88 87 struct regmap *grf = pll->ctx->grf; 89 88 unsigned int val; 90 - int delay = 24000000, ret; 89 + int ret; 91 90 92 - while (delay > 0) { 93 - ret = regmap_read(grf, pll->lock_offset, &val); 94 - if (ret) { 95 - pr_err("%s: failed to read pll lock status: %d\n", 96 - __func__, ret); 97 - return ret; 98 - } 91 + ret = regmap_read_poll_timeout(grf, pll->lock_offset, val, 92 + val & BIT(pll->lock_shift), 0, 1000); 93 + if (ret) 94 + pr_err("%s: timeout waiting for pll to lock\n", __func__); 99 95 100 - if (val & BIT(pll->lock_shift)) 101 - return 0; 102 - delay--; 103 - } 104 - 105 - pr_err("%s: timeout waiting for pll to lock\n", __func__); 106 - return -ETIMEDOUT; 96 + return ret; 107 97 } 108 98 109 99 /** ··· 110 118 #define RK3036_PLLCON1_REFDIV_SHIFT 0 111 119 #define RK3036_PLLCON1_POSTDIV2_MASK 0x7 112 120 #define RK3036_PLLCON1_POSTDIV2_SHIFT 6 121 + #define RK3036_PLLCON1_LOCK_STATUS BIT(10) 113 122 #define RK3036_PLLCON1_DSMPD_MASK 0x1 114 123 #define RK3036_PLLCON1_DSMPD_SHIFT 12 124 + #define RK3036_PLLCON1_PWRDOWN BIT(13) 115 125 #define RK3036_PLLCON2_FRAC_MASK 0xffffff 116 126 #define RK3036_PLLCON2_FRAC_SHIFT 0 117 127 118 - #define RK3036_PLLCON1_PWRDOWN (1 << 13) 128 + static int rockchip_rk3036_pll_wait_lock(struct rockchip_clk_pll *pll) 129 + { 130 + u32 pllcon; 131 + int ret; 132 + 133 + /* 134 + * Lock time typical 250, max 500 input clock cycles @24MHz 135 + * So define a very safe maximum of 1000us, meaning 24000 cycles. 136 + */ 137 + ret = readl_relaxed_poll_timeout(pll->reg_base + RK3036_PLLCON(1), 138 + pllcon, 139 + pllcon & RK3036_PLLCON1_LOCK_STATUS, 140 + 0, 1000); 141 + if (ret) 142 + pr_err("%s: timeout waiting for pll to lock\n", __func__); 143 + 144 + return ret; 145 + } 119 146 120 147 static void rockchip_rk3036_pll_get_params(struct rockchip_clk_pll *pll, 121 148 struct rockchip_pll_rate_table *rate) ··· 232 221 writel_relaxed(pllcon, pll->reg_base + RK3036_PLLCON(2)); 233 222 234 223 /* wait for the pll to lock */ 235 - ret = rockchip_pll_wait_lock(pll); 224 + ret = rockchip_rk3036_pll_wait_lock(pll); 236 225 if (ret) { 237 226 pr_warn("%s: pll update unsuccessful, trying to restore old params\n", 238 227 __func__); ··· 271 260 272 261 writel(HIWORD_UPDATE(0, RK3036_PLLCON1_PWRDOWN, 0), 273 262 pll->reg_base + RK3036_PLLCON(1)); 274 - rockchip_pll_wait_lock(pll); 263 + rockchip_rk3036_pll_wait_lock(pll); 275 264 276 265 return 0; 277 266 } ··· 600 589 static int rockchip_rk3399_pll_wait_lock(struct rockchip_clk_pll *pll) 601 590 { 602 591 u32 pllcon; 603 - int delay = 24000000; 592 + int ret; 604 593 605 - /* poll check the lock status in rk3399 xPLLCON2 */ 606 - while (delay > 0) { 607 - pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(2)); 608 - if (pllcon & RK3399_PLLCON2_LOCK_STATUS) 609 - return 0; 594 + /* 595 + * Lock time typical 250, max 500 input clock cycles @24MHz 596 + * So define a very safe maximum of 1000us, meaning 24000 cycles. 597 + */ 598 + ret = readl_relaxed_poll_timeout(pll->reg_base + RK3399_PLLCON(2), 599 + pllcon, 600 + pllcon & RK3399_PLLCON2_LOCK_STATUS, 601 + 0, 1000); 602 + if (ret) 603 + pr_err("%s: timeout waiting for pll to lock\n", __func__); 610 604 611 - delay--; 612 - } 613 - 614 - pr_err("%s: timeout waiting for pll to lock\n", __func__); 615 - return -ETIMEDOUT; 605 + return ret; 616 606 } 617 607 618 608 static void rockchip_rk3399_pll_get_params(struct rockchip_clk_pll *pll,
+1
drivers/clk/rockchip/clk-rk3188.c
··· 751 751 "pclk_peri", 752 752 "hclk_cpubus", 753 753 "hclk_vio_bus", 754 + "sclk_mac_lbtest", 754 755 }; 755 756 756 757 static struct rockchip_clk_provider *__init rk3188_common_clk_init(struct device_node *np)
+36 -3
drivers/clk/rockchip/clk-rk3288.c
··· 15 15 #define RK3288_GRF_SOC_CON(x) (0x244 + x * 4) 16 16 #define RK3288_GRF_SOC_STATUS1 0x284 17 17 18 + enum rk3288_variant { 19 + RK3288_CRU, 20 + RK3288W_CRU, 21 + }; 22 + 18 23 enum rk3288_plls { 19 24 apll, dpll, cpll, gpll, npll, 20 25 }; ··· 430 425 COMPOSITE(0, "aclk_vio0", mux_pll_src_cpll_gpll_usb480m_p, CLK_IGNORE_UNUSED, 431 426 RK3288_CLKSEL_CON(31), 6, 2, MFLAGS, 0, 5, DFLAGS, 432 427 RK3288_CLKGATE_CON(3), 0, GFLAGS), 433 - DIV(0, "hclk_vio", "aclk_vio0", 0, 434 - RK3288_CLKSEL_CON(28), 8, 5, DFLAGS), 435 428 COMPOSITE(0, "aclk_vio1", mux_pll_src_cpll_gpll_usb480m_p, CLK_IGNORE_UNUSED, 436 429 RK3288_CLKSEL_CON(31), 14, 2, MFLAGS, 8, 5, DFLAGS, 437 430 RK3288_CLKGATE_CON(3), 2, GFLAGS), ··· 822 819 INVERTER(0, "pclk_isp", "pclk_isp_in", RK3288_CLKSEL_CON(29), 3, IFLAGS), 823 820 }; 824 821 822 + static struct rockchip_clk_branch rk3288w_hclkvio_branch[] __initdata = { 823 + DIV(0, "hclk_vio", "aclk_vio1", 0, 824 + RK3288_CLKSEL_CON(28), 8, 5, DFLAGS), 825 + }; 826 + 827 + static struct rockchip_clk_branch rk3288_hclkvio_branch[] __initdata = { 828 + DIV(0, "hclk_vio", "aclk_vio0", 0, 829 + RK3288_CLKSEL_CON(28), 8, 5, DFLAGS), 830 + }; 831 + 825 832 static const char *const rk3288_critical_clocks[] __initconst = { 826 833 "aclk_cpu", 827 834 "aclk_peri", ··· 927 914 .resume = rk3288_clk_resume, 928 915 }; 929 916 930 - static void __init rk3288_clk_init(struct device_node *np) 917 + static void __init rk3288_common_init(struct device_node *np, 918 + enum rk3288_variant soc) 931 919 { 932 920 struct rockchip_clk_provider *ctx; 933 921 ··· 950 936 RK3288_GRF_SOC_STATUS1); 951 937 rockchip_clk_register_branches(ctx, rk3288_clk_branches, 952 938 ARRAY_SIZE(rk3288_clk_branches)); 939 + 940 + if (soc == RK3288W_CRU) 941 + rockchip_clk_register_branches(ctx, rk3288w_hclkvio_branch, 942 + ARRAY_SIZE(rk3288w_hclkvio_branch)); 943 + else 944 + rockchip_clk_register_branches(ctx, rk3288_hclkvio_branch, 945 + ARRAY_SIZE(rk3288_hclkvio_branch)); 946 + 953 947 rockchip_clk_protect_critical(rk3288_critical_clocks, 954 948 ARRAY_SIZE(rk3288_critical_clocks)); 955 949 ··· 976 954 977 955 rockchip_clk_of_add_provider(np, ctx); 978 956 } 957 + 958 + static void __init rk3288_clk_init(struct device_node *np) 959 + { 960 + rk3288_common_init(np, RK3288_CRU); 961 + } 979 962 CLK_OF_DECLARE(rk3288_cru, "rockchip,rk3288-cru", rk3288_clk_init); 963 + 964 + static void __init rk3288w_clk_init(struct device_node *np) 965 + { 966 + rk3288_common_init(np, RK3288W_CRU); 967 + } 968 + CLK_OF_DECLARE(rk3288w_cru, "rockchip,rk3288w-cru", rk3288w_clk_init);
+4 -4
drivers/clk/rockchip/clk-rk3328.c
··· 808 808 MMC(SCLK_SDMMC_DRV, "sdmmc_drv", "clk_sdmmc", 809 809 RK3328_SDMMC_CON0, 1), 810 810 MMC(SCLK_SDMMC_SAMPLE, "sdmmc_sample", "clk_sdmmc", 811 - RK3328_SDMMC_CON1, 0), 811 + RK3328_SDMMC_CON1, 1), 812 812 813 813 MMC(SCLK_SDIO_DRV, "sdio_drv", "clk_sdio", 814 814 RK3328_SDIO_CON0, 1), 815 815 MMC(SCLK_SDIO_SAMPLE, "sdio_sample", "clk_sdio", 816 - RK3328_SDIO_CON1, 0), 816 + RK3328_SDIO_CON1, 1), 817 817 818 818 MMC(SCLK_EMMC_DRV, "emmc_drv", "clk_emmc", 819 819 RK3328_EMMC_CON0, 1), 820 820 MMC(SCLK_EMMC_SAMPLE, "emmc_sample", "clk_emmc", 821 - RK3328_EMMC_CON1, 0), 821 + RK3328_EMMC_CON1, 1), 822 822 823 823 MMC(SCLK_SDMMC_EXT_DRV, "sdmmc_ext_drv", "clk_sdmmc_ext", 824 824 RK3328_SDMMC_EXT_CON0, 1), 825 825 MMC(SCLK_SDMMC_EXT_SAMPLE, "sdmmc_ext_sample", "clk_sdmmc_ext", 826 - RK3328_SDMMC_EXT_CON1, 0), 826 + RK3328_SDMMC_EXT_CON1, 1), 827 827 }; 828 828 829 829 static const char *const rk3328_critical_clocks[] __initconst = {
+1 -1
drivers/clk/sirf/clk-atlas6.c
··· 135 135 136 136 for (i = pll1; i < maxclk; i++) { 137 137 atlas6_clks[i] = clk_register(NULL, atlas6_clk_hw_array[i]); 138 - BUG_ON(!atlas6_clks[i]); 138 + BUG_ON(IS_ERR(atlas6_clks[i])); 139 139 } 140 140 clk_register_clkdev(atlas6_clks[cpu], NULL, "cpu"); 141 141 clk_register_clkdev(atlas6_clks[io], NULL, "io");
+15 -5
drivers/clk/tegra/clk-pll.c
··· 327 327 return clk_pll_wait_for_lock(pll); 328 328 } 329 329 330 + static bool pllm_clk_is_gated_by_pmc(struct tegra_clk_pll *pll) 331 + { 332 + u32 val = readl_relaxed(pll->pmc + PMC_PLLP_WB0_OVERRIDE); 333 + 334 + return (val & PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE) && 335 + !(val & PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE); 336 + } 337 + 330 338 static int clk_pll_is_enabled(struct clk_hw *hw) 331 339 { 332 340 struct tegra_clk_pll *pll = to_clk_pll(hw); 333 341 u32 val; 334 342 335 - if (pll->params->flags & TEGRA_PLLM) { 336 - val = readl_relaxed(pll->pmc + PMC_PLLP_WB0_OVERRIDE); 337 - if (val & PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE) 338 - return val & PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE ? 1 : 0; 339 - } 343 + /* 344 + * Power Management Controller (PMC) can override the PLLM clock 345 + * settings, including the enable-state. The PLLM is enabled when 346 + * PLLM's CaR state is ON and when PLLM isn't gated by PMC. 347 + */ 348 + if ((pll->params->flags & TEGRA_PLLM) && pllm_clk_is_gated_by_pmc(pll)) 349 + return 0; 340 350 341 351 val = pll_readl_base(pll); 342 352
+1 -1
drivers/clk/x86/clk-cgu-pll.c
··· 128 128 pll->hw.init = &init; 129 129 130 130 hw = &pll->hw; 131 - ret = clk_hw_register(dev, hw); 131 + ret = devm_clk_hw_register(dev, hw); 132 132 if (ret) 133 133 return ERR_PTR(ret); 134 134
+12 -20
drivers/clk/x86/clk-cgu.c
··· 119 119 mux->hw.init = &init; 120 120 121 121 hw = &mux->hw; 122 - ret = clk_hw_register(dev, hw); 122 + ret = devm_clk_hw_register(dev, hw); 123 123 if (ret) 124 124 return ERR_PTR(ret); 125 125 ··· 247 247 div->hw.init = &init; 248 248 249 249 hw = &div->hw; 250 - ret = clk_hw_register(dev, hw); 250 + ret = devm_clk_hw_register(dev, hw); 251 251 if (ret) 252 252 return ERR_PTR(ret); 253 253 ··· 361 361 gate->hw.init = &init; 362 362 363 363 hw = &gate->hw; 364 - ret = clk_hw_register(dev, hw); 364 + ret = devm_clk_hw_register(dev, hw); 365 365 if (ret) 366 366 return ERR_PTR(ret); 367 367 ··· 420 420 { 421 421 struct lgm_clk_ddiv *ddiv = to_lgm_clk_ddiv(hw); 422 422 unsigned int div0, div1, exdiv; 423 - unsigned long flags; 424 423 u64 prate; 425 424 426 - spin_lock_irqsave(&ddiv->lock, flags); 427 425 div0 = lgm_get_clk_val(ddiv->membase, ddiv->reg, 428 426 ddiv->shift0, ddiv->width0) + 1; 429 427 div1 = lgm_get_clk_val(ddiv->membase, ddiv->reg, 430 428 ddiv->shift1, ddiv->width1) + 1; 431 429 exdiv = lgm_get_clk_val(ddiv->membase, ddiv->reg, 432 430 ddiv->shift2, ddiv->width2); 433 - spin_unlock_irqrestore(&ddiv->lock, flags); 434 - 435 431 prate = (u64)parent_rate; 436 432 do_div(prate, div0); 437 433 do_div(prate, div1); ··· 544 548 div = div * 2; 545 549 div = DIV_ROUND_CLOSEST_ULL((u64)div, 5); 546 550 } 551 + spin_unlock_irqrestore(&ddiv->lock, flags); 547 552 548 - if (div <= 0) { 549 - spin_unlock_irqrestore(&ddiv->lock, flags); 553 + if (div <= 0) 550 554 return *prate; 551 - } 552 555 553 - if (lgm_clk_get_ddiv_val(div, &ddiv1, &ddiv2) != 0) { 554 - if (lgm_clk_get_ddiv_val(div + 1, &ddiv1, &ddiv2) != 0) { 555 - spin_unlock_irqrestore(&ddiv->lock, flags); 556 + if (lgm_clk_get_ddiv_val(div, &ddiv1, &ddiv2) != 0) 557 + if (lgm_clk_get_ddiv_val(div + 1, &ddiv1, &ddiv2) != 0) 556 558 return -EINVAL; 557 - } 558 - } 559 559 560 560 rate64 = *prate; 561 561 do_div(rate64, ddiv1); 562 562 do_div(rate64, ddiv2); 563 563 564 564 /* if predivide bit is enabled, modify rounded rate by factor of 2.5 */ 565 + spin_lock_irqsave(&ddiv->lock, flags); 565 566 if (lgm_get_clk_val(ddiv->membase, ddiv->reg, ddiv->shift2, 1)) { 566 567 rate64 = rate64 * 2; 567 568 rate64 = DIV_ROUND_CLOSEST_ULL(rate64, 5); ··· 581 588 unsigned int nr_clk) 582 589 { 583 590 struct device *dev = ctx->dev; 584 - struct clk_init_data init = {}; 585 - struct lgm_clk_ddiv *ddiv; 586 591 struct clk_hw *hw; 587 592 unsigned int idx; 588 593 int ret; 589 594 590 595 for (idx = 0; idx < nr_clk; idx++, list++) { 591 - ddiv = NULL; 596 + struct clk_init_data init = {}; 597 + struct lgm_clk_ddiv *ddiv; 598 + 592 599 ddiv = devm_kzalloc(dev, sizeof(*ddiv), GFP_KERNEL); 593 600 if (!ddiv) 594 601 return -ENOMEM; 595 602 596 - memset(&init, 0, sizeof(init)); 597 603 init.name = list->name; 598 604 init.ops = &lgm_clk_ddiv_ops; 599 605 init.flags = list->flags; ··· 616 624 ddiv->hw.init = &init; 617 625 618 626 hw = &ddiv->hw; 619 - ret = clk_hw_register(dev, hw); 627 + ret = devm_clk_hw_register(dev, hw); 620 628 if (ret) { 621 629 dev_err(dev, "register clk: %s failed!\n", list->name); 622 630 return ret;
+6 -1
include/dt-bindings/clock/actions,s500-cmu.h
··· 72 72 #define CLK_NAND 52 73 73 #define CLK_ECC 53 74 74 #define CLK_RMII_REF 54 75 + #define CLK_GPIO 55 75 76 76 - #define CLK_NR_CLKS (CLK_RMII_REF + 1) 77 + /* system clock (part 2) */ 78 + #define CLK_APB 56 79 + #define CLK_DMAC 57 80 + 81 + #define CLK_NR_CLKS (CLK_DMAC + 1) 77 82 78 83 #endif /* __DT_BINDINGS_CLOCK_S500_CMU_H */
+73 -71
include/dt-bindings/clock/jz4780-cgu.h
··· 12 12 #ifndef __DT_BINDINGS_CLOCK_JZ4780_CGU_H__ 13 13 #define __DT_BINDINGS_CLOCK_JZ4780_CGU_H__ 14 14 15 - #define JZ4780_CLK_EXCLK 0 16 - #define JZ4780_CLK_RTCLK 1 17 - #define JZ4780_CLK_APLL 2 18 - #define JZ4780_CLK_MPLL 3 19 - #define JZ4780_CLK_EPLL 4 20 - #define JZ4780_CLK_VPLL 5 21 - #define JZ4780_CLK_OTGPHY 6 22 - #define JZ4780_CLK_SCLKA 7 23 - #define JZ4780_CLK_CPUMUX 8 24 - #define JZ4780_CLK_CPU 9 25 - #define JZ4780_CLK_L2CACHE 10 26 - #define JZ4780_CLK_AHB0 11 27 - #define JZ4780_CLK_AHB2PMUX 12 28 - #define JZ4780_CLK_AHB2 13 29 - #define JZ4780_CLK_PCLK 14 30 - #define JZ4780_CLK_DDR 15 31 - #define JZ4780_CLK_VPU 16 32 - #define JZ4780_CLK_I2SPLL 17 33 - #define JZ4780_CLK_I2S 18 15 + #define JZ4780_CLK_EXCLK 0 16 + #define JZ4780_CLK_RTCLK 1 17 + #define JZ4780_CLK_APLL 2 18 + #define JZ4780_CLK_MPLL 3 19 + #define JZ4780_CLK_EPLL 4 20 + #define JZ4780_CLK_VPLL 5 21 + #define JZ4780_CLK_OTGPHY 6 22 + #define JZ4780_CLK_SCLKA 7 23 + #define JZ4780_CLK_CPUMUX 8 24 + #define JZ4780_CLK_CPU 9 25 + #define JZ4780_CLK_L2CACHE 10 26 + #define JZ4780_CLK_AHB0 11 27 + #define JZ4780_CLK_AHB2PMUX 12 28 + #define JZ4780_CLK_AHB2 13 29 + #define JZ4780_CLK_PCLK 14 30 + #define JZ4780_CLK_DDR 15 31 + #define JZ4780_CLK_VPU 16 32 + #define JZ4780_CLK_I2SPLL 17 33 + #define JZ4780_CLK_I2S 18 34 34 #define JZ4780_CLK_LCD0PIXCLK 19 35 35 #define JZ4780_CLK_LCD1PIXCLK 20 36 - #define JZ4780_CLK_MSCMUX 21 37 - #define JZ4780_CLK_MSC0 22 38 - #define JZ4780_CLK_MSC1 23 39 - #define JZ4780_CLK_MSC2 24 40 - #define JZ4780_CLK_UHC 25 41 - #define JZ4780_CLK_SSIPLL 26 42 - #define JZ4780_CLK_SSI 27 43 - #define JZ4780_CLK_CIMMCLK 28 44 - #define JZ4780_CLK_PCMPLL 29 45 - #define JZ4780_CLK_PCM 30 46 - #define JZ4780_CLK_GPU 31 47 - #define JZ4780_CLK_HDMI 32 48 - #define JZ4780_CLK_BCH 33 49 - #define JZ4780_CLK_NEMC 34 50 - #define JZ4780_CLK_OTG0 35 51 - #define JZ4780_CLK_SSI0 36 52 - #define JZ4780_CLK_SMB0 37 53 - #define JZ4780_CLK_SMB1 38 54 - #define JZ4780_CLK_SCC 39 55 - #define JZ4780_CLK_AIC 40 56 - #define JZ4780_CLK_TSSI0 41 57 - #define JZ4780_CLK_OWI 42 58 - #define JZ4780_CLK_KBC 43 59 - #define JZ4780_CLK_SADC 44 60 - #define JZ4780_CLK_UART0 45 61 - #define JZ4780_CLK_UART1 46 62 - #define JZ4780_CLK_UART2 47 63 - #define JZ4780_CLK_UART3 48 64 - #define JZ4780_CLK_SSI1 49 65 - #define JZ4780_CLK_SSI2 50 66 - #define JZ4780_CLK_PDMA 51 67 - #define JZ4780_CLK_GPS 52 68 - #define JZ4780_CLK_MAC 53 69 - #define JZ4780_CLK_SMB2 54 70 - #define JZ4780_CLK_CIM 55 71 - #define JZ4780_CLK_LCD 56 72 - #define JZ4780_CLK_TVE 57 73 - #define JZ4780_CLK_IPU 58 74 - #define JZ4780_CLK_DDR0 59 75 - #define JZ4780_CLK_DDR1 60 76 - #define JZ4780_CLK_SMB3 61 77 - #define JZ4780_CLK_TSSI1 62 78 - #define JZ4780_CLK_COMPRESS 63 79 - #define JZ4780_CLK_AIC1 64 80 - #define JZ4780_CLK_GPVLC 65 81 - #define JZ4780_CLK_OTG1 66 82 - #define JZ4780_CLK_UART4 67 83 - #define JZ4780_CLK_AHBMON 68 84 - #define JZ4780_CLK_SMB4 69 85 - #define JZ4780_CLK_DES 70 86 - #define JZ4780_CLK_X2D 71 87 - #define JZ4780_CLK_CORE1 72 36 + #define JZ4780_CLK_MSCMUX 21 37 + #define JZ4780_CLK_MSC0 22 38 + #define JZ4780_CLK_MSC1 23 39 + #define JZ4780_CLK_MSC2 24 40 + #define JZ4780_CLK_UHC 25 41 + #define JZ4780_CLK_SSIPLL 26 42 + #define JZ4780_CLK_SSI 27 43 + #define JZ4780_CLK_CIMMCLK 28 44 + #define JZ4780_CLK_PCMPLL 29 45 + #define JZ4780_CLK_PCM 30 46 + #define JZ4780_CLK_GPU 31 47 + #define JZ4780_CLK_HDMI 32 48 + #define JZ4780_CLK_BCH 33 49 + #define JZ4780_CLK_NEMC 34 50 + #define JZ4780_CLK_OTG0 35 51 + #define JZ4780_CLK_SSI0 36 52 + #define JZ4780_CLK_SMB0 37 53 + #define JZ4780_CLK_SMB1 38 54 + #define JZ4780_CLK_SCC 39 55 + #define JZ4780_CLK_AIC 40 56 + #define JZ4780_CLK_TSSI0 41 57 + #define JZ4780_CLK_OWI 42 58 + #define JZ4780_CLK_KBC 43 59 + #define JZ4780_CLK_SADC 44 60 + #define JZ4780_CLK_UART0 45 61 + #define JZ4780_CLK_UART1 46 62 + #define JZ4780_CLK_UART2 47 63 + #define JZ4780_CLK_UART3 48 64 + #define JZ4780_CLK_SSI1 49 65 + #define JZ4780_CLK_SSI2 50 66 + #define JZ4780_CLK_PDMA 51 67 + #define JZ4780_CLK_GPS 52 68 + #define JZ4780_CLK_MAC 53 69 + #define JZ4780_CLK_SMB2 54 70 + #define JZ4780_CLK_CIM 55 71 + #define JZ4780_CLK_LCD 56 72 + #define JZ4780_CLK_TVE 57 73 + #define JZ4780_CLK_IPU 58 74 + #define JZ4780_CLK_DDR0 59 75 + #define JZ4780_CLK_DDR1 60 76 + #define JZ4780_CLK_SMB3 61 77 + #define JZ4780_CLK_TSSI1 62 78 + #define JZ4780_CLK_COMPRESS 63 79 + #define JZ4780_CLK_AIC1 64 80 + #define JZ4780_CLK_GPVLC 65 81 + #define JZ4780_CLK_OTG1 66 82 + #define JZ4780_CLK_UART4 67 83 + #define JZ4780_CLK_AHBMON 68 84 + #define JZ4780_CLK_SMB4 69 85 + #define JZ4780_CLK_DES 70 86 + #define JZ4780_CLK_X2D 71 87 + #define JZ4780_CLK_CORE1 72 88 + #define JZ4780_CLK_EXCLK_DIV512 73 89 + #define JZ4780_CLK_RTC 74 88 90 89 91 #endif /* __DT_BINDINGS_CLOCK_JZ4780_CGU_H__ */
+1
include/dt-bindings/clock/qcom,gcc-sc7180.h
··· 138 138 #define GCC_MSS_Q6_MEMNOC_AXI_CLK 128 139 139 #define GCC_MSS_SNOC_AXI_CLK 129 140 140 #define GCC_SEC_CTRL_CLK_SRC 130 141 + #define GCC_LPASS_CFG_NOC_SWAY_CLK 131 141 142 142 143 /* GCC resets */ 143 144 #define GCC_QUSB2PHY_PRIM_BCR 0
+1
include/dt-bindings/clock/qcom,gcc-sdm660.h
··· 152 152 #define GCC_USB_20_BCR 6 153 153 #define GCC_USB_30_BCR 7 154 154 #define GCC_USB_PHY_CFG_AHB2PHY_BCR 8 155 + #define GCC_MSS_RESTART 9 155 156 156 157 #endif
+33
include/dt-bindings/clock/qcom,gpucc-sm8150.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. 4 + */ 5 + 6 + #ifndef _DT_BINDINGS_CLK_QCOM_GPU_CC_SM8150_H 7 + #define _DT_BINDINGS_CLK_QCOM_GPU_CC_SM8150_H 8 + 9 + /* GPU_CC clock registers */ 10 + #define GPU_CC_AHB_CLK 0 11 + #define GPU_CC_CRC_AHB_CLK 1 12 + #define GPU_CC_CX_APB_CLK 2 13 + #define GPU_CC_CX_GMU_CLK 3 14 + #define GPU_CC_CX_SNOC_DVM_CLK 4 15 + #define GPU_CC_CXO_AON_CLK 5 16 + #define GPU_CC_CXO_CLK 6 17 + #define GPU_CC_GMU_CLK_SRC 7 18 + #define GPU_CC_GX_GMU_CLK 8 19 + #define GPU_CC_PLL1 9 20 + 21 + /* GPU_CC Resets */ 22 + #define GPUCC_GPU_CC_CX_BCR 0 23 + #define GPUCC_GPU_CC_GFX3D_AON_BCR 1 24 + #define GPUCC_GPU_CC_GMU_BCR 2 25 + #define GPUCC_GPU_CC_GX_BCR 3 26 + #define GPUCC_GPU_CC_SPDM_BCR 4 27 + #define GPUCC_GPU_CC_XO_BCR 5 28 + 29 + /* GPU_CC GDSCRs */ 30 + #define GPU_CX_GDSC 0 31 + #define GPU_GX_GDSC 1 32 + 33 + #endif
+34
include/dt-bindings/clock/qcom,gpucc-sm8250.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. 4 + */ 5 + 6 + #ifndef _DT_BINDINGS_CLK_QCOM_GPU_CC_SM8250_H 7 + #define _DT_BINDINGS_CLK_QCOM_GPU_CC_SM8250_H 8 + 9 + /* GPU_CC clock registers */ 10 + #define GPU_CC_AHB_CLK 0 11 + #define GPU_CC_CRC_AHB_CLK 1 12 + #define GPU_CC_CX_APB_CLK 2 13 + #define GPU_CC_CX_GMU_CLK 3 14 + #define GPU_CC_CX_SNOC_DVM_CLK 4 15 + #define GPU_CC_CXO_AON_CLK 5 16 + #define GPU_CC_CXO_CLK 6 17 + #define GPU_CC_GMU_CLK_SRC 7 18 + #define GPU_CC_GX_GMU_CLK 8 19 + #define GPU_CC_PLL1 9 20 + #define GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK 10 21 + 22 + /* GPU_CC Resets */ 23 + #define GPUCC_GPU_CC_ACD_BCR 0 24 + #define GPUCC_GPU_CC_CX_BCR 1 25 + #define GPUCC_GPU_CC_GFX3D_AON_BCR 2 26 + #define GPUCC_GPU_CC_GMU_BCR 3 27 + #define GPUCC_GPU_CC_GX_BCR 4 28 + #define GPUCC_GPU_CC_XO_BCR 5 29 + 30 + /* GPU_CC GDSCRs */ 31 + #define GPU_CX_GDSC 0 32 + #define GPU_GX_GDSC 1 33 + 34 + #endif
+29
include/dt-bindings/clock/qcom,lpasscorecc-sc7180.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /* 3 + * Copyright (c) 2020, The Linux Foundation. All rights reserved. 4 + */ 5 + 6 + #ifndef _DT_BINDINGS_CLK_QCOM_LPASS_CORE_CC_SC7180_H 7 + #define _DT_BINDINGS_CLK_QCOM_LPASS_CORE_CC_SC7180_H 8 + 9 + /* LPASS_CORE_CC clocks */ 10 + #define LPASS_LPAAUDIO_DIG_PLL 0 11 + #define LPASS_LPAAUDIO_DIG_PLL_OUT_ODD 1 12 + #define CORE_CLK_SRC 2 13 + #define EXT_MCLK0_CLK_SRC 3 14 + #define LPAIF_PRI_CLK_SRC 4 15 + #define LPAIF_SEC_CLK_SRC 5 16 + #define LPASS_AUDIO_CORE_CORE_CLK 6 17 + #define LPASS_AUDIO_CORE_EXT_MCLK0_CLK 7 18 + #define LPASS_AUDIO_CORE_LPAIF_PRI_IBIT_CLK 8 19 + #define LPASS_AUDIO_CORE_LPAIF_SEC_IBIT_CLK 9 20 + #define LPASS_AUDIO_CORE_SYSNOC_MPORT_CORE_CLK 10 21 + 22 + /* LPASS Core power domains */ 23 + #define LPASS_CORE_HM_GDSCR 0 24 + 25 + /* LPASS Audio power domains */ 26 + #define LPASS_AUDIO_HM_GDSCR 0 27 + #define LPASS_PDC_HM_GDSCR 1 28 + 29 + #endif
+2
include/dt-bindings/clock/x1000-cgu.h
··· 48 48 #define X1000_CLK_SSI 33 49 49 #define X1000_CLK_OST 34 50 50 #define X1000_CLK_PDMA 35 51 + #define X1000_CLK_EXCLK_DIV512 36 52 + #define X1000_CLK_RTC 37 51 53 52 54 #endif /* __DT_BINDINGS_CLOCK_X1000_CGU_H__ */
+2
include/dt-bindings/clock/x1830-cgu.h
··· 51 51 #define X1830_CLK_TCU 36 52 52 #define X1830_CLK_DTRNG 37 53 53 #define X1830_CLK_OST 38 54 + #define X1830_CLK_EXCLK_DIV512 39 55 + #define X1830_CLK_RTC 40 54 56 55 57 #endif /* __DT_BINDINGS_CLOCK_X1830_CGU_H__ */
+67
include/dt-bindings/reset/actions,s500-reset.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 + /* 3 + * Device Tree binding constants for Actions Semi S500 Reset Management Unit 4 + * 5 + * Copyright (c) 2014 Actions Semi Inc. 6 + * Copyright (c) 2020 Cristian Ciocaltea <cristian.ciocaltea@gmail.com> 7 + */ 8 + 9 + #ifndef __DT_BINDINGS_ACTIONS_S500_RESET_H 10 + #define __DT_BINDINGS_ACTIONS_S500_RESET_H 11 + 12 + #define RESET_DMAC 0 13 + #define RESET_NORIF 1 14 + #define RESET_DDR 2 15 + #define RESET_NANDC 3 16 + #define RESET_SD0 4 17 + #define RESET_SD1 5 18 + #define RESET_PCM1 6 19 + #define RESET_DE 7 20 + #define RESET_LCD 8 21 + #define RESET_SD2 9 22 + #define RESET_DSI 10 23 + #define RESET_CSI 11 24 + #define RESET_BISP 12 25 + #define RESET_KEY 13 26 + #define RESET_GPIO 14 27 + #define RESET_AUDIO 15 28 + #define RESET_PCM0 16 29 + #define RESET_VDE 17 30 + #define RESET_VCE 18 31 + #define RESET_GPU3D 19 32 + #define RESET_NIC301 20 33 + #define RESET_LENS 21 34 + #define RESET_PERIPHRESET 22 35 + #define RESET_USB2_0 23 36 + #define RESET_TVOUT 24 37 + #define RESET_HDMI 25 38 + #define RESET_HDCP2TX 26 39 + #define RESET_UART6 27 40 + #define RESET_UART0 28 41 + #define RESET_UART1 29 42 + #define RESET_UART2 30 43 + #define RESET_SPI0 31 44 + #define RESET_SPI1 32 45 + #define RESET_SPI2 33 46 + #define RESET_SPI3 34 47 + #define RESET_I2C0 35 48 + #define RESET_I2C1 36 49 + #define RESET_USB3 37 50 + #define RESET_UART3 38 51 + #define RESET_UART4 39 52 + #define RESET_UART5 40 53 + #define RESET_I2C2 41 54 + #define RESET_I2C3 42 55 + #define RESET_ETHERNET 43 56 + #define RESET_CHIPID 44 57 + #define RESET_USB2_1 45 58 + #define RESET_WD0RESET 46 59 + #define RESET_WD1RESET 47 60 + #define RESET_WD2RESET 48 61 + #define RESET_WD3RESET 49 62 + #define RESET_DBG0RESET 50 63 + #define RESET_DBG1RESET 51 64 + #define RESET_DBG2RESET 52 65 + #define RESET_DBG3RESET 53 66 + 67 + #endif /* __DT_BINDINGS_ACTIONS_S500_RESET_H */
-1
include/linux/clk-provider.h
··· 1096 1096 int clk_hw_set_parent(struct clk_hw *hw, struct clk_hw *new_parent); 1097 1097 unsigned int __clk_get_enable_count(struct clk *clk); 1098 1098 unsigned long clk_hw_get_rate(const struct clk_hw *hw); 1099 - unsigned long __clk_get_flags(struct clk *clk); 1100 1099 unsigned long clk_hw_get_flags(const struct clk_hw *hw); 1101 1100 #define clk_hw_can_set_rate_parent(hw) \ 1102 1101 (clk_hw_get_flags((hw)) & CLK_SET_RATE_PARENT)
+4
include/linux/clk/at91_pmc.h
··· 59 59 #define AT91_PMC_PLL_UPDT 0x1C /* PMC PLL update register [for SAM9X60] */ 60 60 #define AT91_PMC_PLL_UPDT_UPDATE (1 << 8) /* Update PLL settings */ 61 61 #define AT91_PMC_PLL_UPDT_ID (1 << 0) /* PLL ID */ 62 + #define AT91_PMC_PLL_UPDT_ID_MSK (0xf) /* PLL ID mask */ 62 63 #define AT91_PMC_PLL_UPDT_STUPTIM (0xff << 16) /* Startup time */ 63 64 64 65 #define AT91_CKGR_MOR 0x20 /* Main Oscillator Register [not on SAM9RL] */ ··· 137 136 #define AT91_PMC_PLLADIV2_ON (1 << 12) 138 137 #define AT91_PMC_H32MXDIV BIT(24) 139 138 139 + #define AT91_PMC_XTALF 0x34 /* Main XTAL Frequency Register [SAMA7G5 only] */ 140 + 140 141 #define AT91_PMC_USB 0x38 /* USB Clock Register [some SAM9 only] */ 141 142 #define AT91_PMC_USBS (0x1 << 0) /* USB OHCI Input clock selection */ 142 143 #define AT91_PMC_USBS_PLLA (0 << 0) ··· 177 174 #define AT91_PMC_MOSCRCS (1 << 17) /* Main On-Chip RC [some SAM9] */ 178 175 #define AT91_PMC_CFDEV (1 << 18) /* Clock Failure Detector Event [some SAM9] */ 179 176 #define AT91_PMC_GCKRDY (1 << 24) /* Generated Clocks */ 177 + #define AT91_PMC_MCKXRDY (1 << 26) /* Master Clock x [x=1..4] Ready Status */ 180 178 #define AT91_PMC_IMR 0x6c /* Interrupt Mask Register */ 181 179 182 180 #define AT91_PMC_FSMR 0x70 /* Fast Startup Mode Register */