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

Merge tag 'clk-for-linus-3.16' of git://git.linaro.org/people/mike.turquette/linux into next

Pull clock framework updates from Mike Turquette:
"The clock framework changes for 3.16 are pretty typical: mostly clock
driver additions and fixes. There are additions to the clock core
code for some of the basic types (e.g. the common divider type has
some fixes and featured added to it).

One minor annoyance is a last-minute dependency that wasn't handled
quite right. Commit ba0fae3b06a6 ("clk: berlin: add core clock driver
for BG2/BG2CD") in this pull request depends on
include/dt-bindings/clock/berlin2.h, which is already in your tree via
the arm-soc pull request. Building for the berlin platform will break
when the clk tree is built on it's own, but merged into your master
branch everything should be fine"

* tag 'clk-for-linus-3.16' of git://git.linaro.org/people/mike.turquette/linux: (75 commits)
mmc: sunxi: Add driver for SD/MMC hosts found on Allwinner sunxi SoCs
clk: export __clk_round_rate for providers
clk: versatile: free icst on error return
clk: qcom: Return error pointers for unimplemented clocks
clk: qcom: Support msm8974pro global clock control hardware
clk: qcom: Properly support display clocks on msm8974
clk: qcom: Support display RCG clocks
clk: qcom: Return highest rate when round_rate() exceeds plan
clk: qcom: Fix mmcc-8974's PLL configurations
clk: qcom: Fix clk_rcg2_is_enabled() check
clk: berlin: add core clock driver for BG2Q
clk: berlin: add core clock driver for BG2/BG2CD
clk: berlin: add driver for BG2x complex divider cells
clk: berlin: add driver for BG2x simple PLLs
clk: berlin: add driver for BG2x audio/video PLL
clk: st: Terminate of match table
clk/exynos4: Fix compilation warning
ARM: shmobile: r8a7779: Add clock index macros for DT sources
clk: divider: Fix overflow in clk_divider_bestdiv
clk: u300: Terminate of match table
...

+7240 -947
+11 -5
Documentation/clk.txt
··· 68 68 int (*is_enabled)(struct clk_hw *hw); 69 69 unsigned long (*recalc_rate)(struct clk_hw *hw, 70 70 unsigned long parent_rate); 71 - long (*round_rate)(struct clk_hw *hw, unsigned long, 72 - unsigned long *); 71 + long (*round_rate)(struct clk_hw *hw, 72 + unsigned long rate, 73 + unsigned long *parent_rate); 73 74 long (*determine_rate)(struct clk_hw *hw, 74 75 unsigned long rate, 75 76 unsigned long *best_parent_rate, 76 77 struct clk **best_parent_clk); 77 78 int (*set_parent)(struct clk_hw *hw, u8 index); 78 79 u8 (*get_parent)(struct clk_hw *hw); 79 - int (*set_rate)(struct clk_hw *hw, unsigned long); 80 + int (*set_rate)(struct clk_hw *hw, 81 + unsigned long rate, 82 + unsigned long parent_rate); 80 83 int (*set_rate_and_parent)(struct clk_hw *hw, 81 84 unsigned long rate, 82 - unsigned long parent_rate, u8 index); 85 + unsigned long parent_rate, 86 + u8 index); 83 87 unsigned long (*recalc_accuracy)(struct clk_hw *hw, 84 - unsigned long parent_accuracy); 88 + unsigned long parent_accuracy); 85 89 void (*init)(struct clk_hw *hw); 90 + int (*debug_init)(struct clk_hw *hw, 91 + struct dentry *dentry); 86 92 }; 87 93 88 94 Part 3 - hardware clk implementations
+81 -35
Documentation/devicetree/bindings/clock/bcm-kona-clock.txt
··· 10 10 11 11 Required properties: 12 12 - compatible 13 - Shall have one of the following values: 14 - - "brcm,bcm11351-root-ccu" 15 - - "brcm,bcm11351-aon-ccu" 16 - - "brcm,bcm11351-hub-ccu" 17 - - "brcm,bcm11351-master-ccu" 18 - - "brcm,bcm11351-slave-ccu" 13 + Shall have a value of the form "brcm,<model>-<which>-ccu", 14 + where <model> is a Broadcom SoC model number and <which> is 15 + the name of a defined CCU. For example: 16 + "brcm,bcm11351-root-ccu" 17 + The compatible strings used for each supported SoC family 18 + are defined below. 19 19 - reg 20 20 Shall define the base and range of the address space 21 21 containing clock control registers ··· 26 26 Shall be an ordered list of strings defining the names of 27 27 the clocks provided by the CCU. 28 28 29 + Device tree example: 29 30 30 - BCM281XX family SoCs use Kona CCUs. The following table defines 31 - the set of CCUs and clock specifiers for BCM281XX clocks. When 32 - a clock consumer references a clocks, its symbolic specifier 33 - (rather than its numeric index value) should be used. These 34 - specifiers are defined in "include/dt-bindings/clock/bcm281xx.h". 31 + slave_ccu: slave_ccu { 32 + compatible = "brcm,bcm11351-slave-ccu"; 33 + reg = <0x3e011000 0x0f00>; 34 + #clock-cells = <1>; 35 + clock-output-names = "uartb", 36 + "uartb2", 37 + "uartb3", 38 + "uartb4"; 39 + }; 40 + 41 + ref_crystal_clk: ref_crystal { 42 + #clock-cells = <0>; 43 + compatible = "fixed-clock"; 44 + clock-frequency = <26000000>; 45 + }; 46 + 47 + uart@3e002000 { 48 + compatible = "brcm,bcm11351-dw-apb-uart", "snps,dw-apb-uart"; 49 + status = "disabled"; 50 + reg = <0x3e002000 0x1000>; 51 + clocks = <&slave_ccu BCM281XX_SLAVE_CCU_UARTB3>; 52 + interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>; 53 + reg-shift = <2>; 54 + reg-io-width = <4>; 55 + }; 56 + 57 + BCM281XX family 58 + --------------- 59 + CCU compatible string values for SoCs in the BCM281XX family are: 60 + "brcm,bcm11351-root-ccu" 61 + "brcm,bcm11351-aon-ccu" 62 + "brcm,bcm11351-hub-ccu" 63 + "brcm,bcm11351-master-ccu" 64 + "brcm,bcm11351-slave-ccu" 65 + 66 + The following table defines the set of CCUs and clock specifiers for 67 + BCM281XX family clocks. When a clock consumer references a clocks, 68 + its symbolic specifier (rather than its numeric index value) should 69 + be used. These specifiers are defined in: 70 + "include/dt-bindings/clock/bcm281xx.h" 35 71 36 72 CCU Clock Type Index Specifier 37 73 --- ----- ---- ----- --------- ··· 100 64 slave pwm peri 9 BCM281XX_SLAVE_CCU_PWM 101 65 102 66 103 - Device tree example: 67 + BCM21664 family 68 + --------------- 69 + CCU compatible string values for SoCs in the BCM21664 family are: 70 + "brcm,bcm21664-root-ccu" 71 + "brcm,bcm21664-aon-ccu" 72 + "brcm,bcm21664-master-ccu" 73 + "brcm,bcm21664-slave-ccu" 104 74 105 - slave_ccu: slave_ccu { 106 - compatible = "brcm,bcm11351-slave-ccu"; 107 - reg = <0x3e011000 0x0f00>; 108 - #clock-cells = <1>; 109 - clock-output-names = "uartb", 110 - "uartb2", 111 - "uartb3", 112 - "uartb4"; 113 - }; 75 + The following table defines the set of CCUs and clock specifiers for 76 + BCM21664 family clocks. When a clock consumer references a clocks, 77 + its symbolic specifier (rather than its numeric index value) should 78 + be used. These specifiers are defined in: 79 + "include/dt-bindings/clock/bcm21664.h" 114 80 115 - ref_crystal_clk: ref_crystal { 116 - #clock-cells = <0>; 117 - compatible = "fixed-clock"; 118 - clock-frequency = <26000000>; 119 - }; 81 + CCU Clock Type Index Specifier 82 + --- ----- ---- ----- --------- 83 + root frac_1m peri 0 BCM21664_ROOT_CCU_FRAC_1M 120 84 121 - uart@3e002000 { 122 - compatible = "brcm,bcm11351-dw-apb-uart", "snps,dw-apb-uart"; 123 - status = "disabled"; 124 - reg = <0x3e002000 0x1000>; 125 - clocks = <&slave_ccu BCM281XX_SLAVE_CCU_UARTB3>; 126 - interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>; 127 - reg-shift = <2>; 128 - reg-io-width = <4>; 129 - }; 85 + aon hub_timer peri 0 BCM21664_AON_CCU_HUB_TIMER 86 + 87 + master sdio1 peri 0 BCM21664_MASTER_CCU_SDIO1 88 + master sdio2 peri 1 BCM21664_MASTER_CCU_SDIO2 89 + master sdio3 peri 2 BCM21664_MASTER_CCU_SDIO3 90 + master sdio4 peri 3 BCM21664_MASTER_CCU_SDIO4 91 + master sdio1_sleep peri 4 BCM21664_MASTER_CCU_SDIO1_SLEEP 92 + master sdio2_sleep peri 5 BCM21664_MASTER_CCU_SDIO2_SLEEP 93 + master sdio3_sleep peri 6 BCM21664_MASTER_CCU_SDIO3_SLEEP 94 + master sdio4_sleep peri 7 BCM21664_MASTER_CCU_SDIO4_SLEEP 95 + 96 + slave uartb peri 0 BCM21664_SLAVE_CCU_UARTB 97 + slave uartb2 peri 1 BCM21664_SLAVE_CCU_UARTB2 98 + slave uartb3 peri 2 BCM21664_SLAVE_CCU_UARTB3 99 + slave uartb4 peri 3 BCM21664_SLAVE_CCU_UARTB4 100 + slave bsc1 peri 4 BCM21664_SLAVE_CCU_BSC1 101 + slave bsc2 peri 5 BCM21664_SLAVE_CCU_BSC2 102 + slave bsc3 peri 6 BCM21664_SLAVE_CCU_BSC3 103 + slave bsc4 peri 7 BCM21664_SLAVE_CCU_BSC4
+4 -5
Documentation/devicetree/bindings/clock/clock-bindings.txt
··· 44 44 clocks by index. The names should reflect the clock output signal 45 45 names for the device. 46 46 47 - clock-indices: If the identifyng number for the clocks in the node 48 - is not linear from zero, then the this mapping allows 49 - the mapping of identifiers into the clock-output-names 50 - array. 47 + clock-indices: If the identifying number for the clocks in the node 48 + is not linear from zero, then this allows the mapping of 49 + identifiers into the clock-output-names array. 51 50 52 51 For example, if we have two clocks <&oscillator 1> and <&oscillator 3>: 53 52 ··· 57 58 clock-output-names = "clka", "clkb"; 58 59 } 59 60 60 - This ensures we do not have any empty nodes in clock-output-names 61 + This ensures we do not have any empty strings in clock-output-names 61 62 62 63 63 64 ==Clock consumers==
-1
Documentation/devicetree/bindings/clock/fixed-clock.txt
··· 12 12 Optional properties: 13 13 - clock-accuracy : accuracy of clock in ppb (parts per billion). 14 14 Should be a single cell. 15 - - gpios : From common gpio binding; gpio connection to clock enable pin. 16 15 - clock-output-names : From common clock binding. 17 16 18 17 Example:
+31
Documentation/devicetree/bindings/clock/hix5hd2-clock.txt
··· 1 + * Hisilicon Hix5hd2 Clock Controller 2 + 3 + The hix5hd2 clock controller generates and supplies clock to various 4 + controllers within the hix5hd2 SoC. 5 + 6 + Required Properties: 7 + 8 + - compatible: should be "hisilicon,hix5hd2-clock" 9 + - reg: Address and length of the register set 10 + - #clock-cells: Should be <1> 11 + 12 + Each clock is assigned an identifier and client nodes use this identifier 13 + to specify the clock which they consume. 14 + 15 + All these identifier could be found in <dt-bindings/clock/hix5hd2-clock.h>. 16 + 17 + Examples: 18 + clock: clock@f8a22000 { 19 + compatible = "hisilicon,hix5hd2-clock"; 20 + reg = <0xf8a22000 0x1000>; 21 + #clock-cells = <1>; 22 + }; 23 + 24 + uart0: uart@f8b00000 { 25 + compatible = "arm,pl011", "arm,primecell"; 26 + reg = <0xf8b00000 0x1000>; 27 + interrupts = <0 49 4>; 28 + clocks = <&clock HIX5HD2_FIXED_83M>; 29 + clock-names = "apb_pclk"; 30 + status = "disabled"; 31 + };
+29
Documentation/devicetree/bindings/clock/lsi,axm5516-clks.txt
··· 1 + AXM5516 clock driver bindings 2 + ----------------------------- 3 + 4 + Required properties : 5 + - compatible : shall contain "lsi,axm5516-clks" 6 + - reg : shall contain base register location and length 7 + - #clock-cells : shall contain 1 8 + 9 + The consumer specifies the desired clock by having the clock ID in its "clocks" 10 + phandle cell. See <dt-bindings/clock/lsi,axxia-clock.h> for the list of 11 + supported clock IDs. 12 + 13 + Example: 14 + 15 + clks: clock-controller@2010020000 { 16 + compatible = "lsi,axm5516-clks"; 17 + #clock-cells = <1>; 18 + reg = <0x20 0x10020000 0 0x20000>; 19 + }; 20 + 21 + serial0: uart@2010080000 { 22 + compatible = "arm,pl011", "arm,primecell"; 23 + reg = <0x20 0x10080000 0 0x1000>; 24 + interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>; 25 + clocks = <&clks AXXIA_CLK_PER>; 26 + clock-names = "apb_pclk"; 27 + }; 28 + }; 29 +
+8
Documentation/devicetree/bindings/clock/mvebu-core-clock.txt
··· 29 29 2 = l2clk (L2 Cache clock derived from CPU0 clock) 30 30 3 = ddrclk (DDR controller clock derived from CPU0 clock) 31 31 32 + The following is a list of provided IDs and clock names on Orion5x: 33 + 0 = tclk (Internal Bus clock) 34 + 1 = cpuclk (CPU0 clock) 35 + 2 = ddrclk (DDR controller clock derived from CPU0 clock) 36 + 32 37 Required properties: 33 38 - compatible : shall be one of the following: 34 39 "marvell,armada-370-core-clock" - For Armada 370 SoC core clocks ··· 43 38 "marvell,dove-core-clock" - for Dove SoC core clocks 44 39 "marvell,kirkwood-core-clock" - for Kirkwood SoC (except mv88f6180) 45 40 "marvell,mv88f6180-core-clock" - for Kirkwood MV88f6180 SoC 41 + "marvell,mv88f5182-core-clock" - for Orion MV88F5182 SoC 42 + "marvell,mv88f5281-core-clock" - for Orion MV88F5281 SoC 43 + "marvell,mv88f6183-core-clock" - for Orion MV88F6183 SoC 46 44 - reg : shall be the register address of the Sample-At-Reset (SAR) register 47 45 - #clock-cells : from common clock binding; shall be set to 1 48 46
+3
Documentation/devicetree/bindings/clock/qcom,gcc.txt
··· 4 4 Required properties : 5 5 - compatible : shall contain only one of the following: 6 6 7 + "qcom,gcc-apq8064" 7 8 "qcom,gcc-msm8660" 8 9 "qcom,gcc-msm8960" 9 10 "qcom,gcc-msm8974" 11 + "qcom,gcc-msm8974pro" 12 + "qcom,gcc-msm8974pro-ac" 10 13 11 14 - reg : shall contain base register location and length 12 15 - #clock-cells : shall contain 1
+1
Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
··· 11 11 12 12 - compatible: Must be one of the following 13 13 - "renesas,r7s72100-mstp-clocks" for R7S72100 (RZ) MSTP gate clocks 14 + - "renesas,r8a7779-mstp-clocks" for R8A7779 (R-Car H1) MSTP gate clocks 14 15 - "renesas,r8a7790-mstp-clocks" for R8A7790 (R-Car H2) MSTP gate clocks 15 16 - "renesas,r8a7791-mstp-clocks" for R8A7791 (R-Car M2) MSTP gate clocks 16 17 - "renesas,cpg-mstp-clock" for generic MSTP gate clocks
+41
Documentation/devicetree/bindings/clock/renesas,r8a7740-cpg-clocks.txt
··· 1 + These bindings should be considered EXPERIMENTAL for now. 2 + 3 + * Renesas R8A7740 Clock Pulse Generator (CPG) 4 + 5 + The CPG generates core clocks for the R8A7740 SoC. It includes three PLLs 6 + and several fixed ratio and variable ratio dividers. 7 + 8 + Required Properties: 9 + 10 + - compatible: Must be "renesas,r8a7740-cpg-clocks" 11 + 12 + - reg: Base address and length of the memory resource used by the CPG 13 + 14 + - clocks: Reference to the three parent clocks 15 + - #clock-cells: Must be 1 16 + - clock-output-names: The names of the clocks. Supported clocks are 17 + "system", "pllc0", "pllc1", "pllc2", "r", "usb24s", "i", "zg", "b", 18 + "m1", "hp", "hpp", "usbp", "s", "zb", "m3", and "cp". 19 + 20 + - renesas,mode: board-specific settings of the MD_CK* bits 21 + 22 + 23 + Example 24 + ------- 25 + 26 + cpg_clocks: cpg_clocks@e6150000 { 27 + compatible = "renesas,r8a7740-cpg-clocks"; 28 + reg = <0xe6150000 0x10000>; 29 + clocks = <&extal1_clk>, <&extal2_clk>, <&extalr_clk>; 30 + #clock-cells = <1>; 31 + clock-output-names = "system", "pllc0", "pllc1", 32 + "pllc2", "r", 33 + "usb24s", 34 + "i", "zg", "b", "m1", "hp", 35 + "hpp", "usbp", "s", "zb", "m3", 36 + "cp"; 37 + }; 38 + 39 + &cpg_clocks { 40 + renesas,mode = <0x05>; 41 + };
+27
Documentation/devicetree/bindings/clock/renesas,r8a7779-cpg-clocks.txt
··· 1 + * Renesas R8A7779 Clock Pulse Generator (CPG) 2 + 3 + The CPG generates core clocks for the R8A7779. It includes one PLL and 4 + several fixed ratio dividers 5 + 6 + Required Properties: 7 + 8 + - compatible: Must be "renesas,r8a7779-cpg-clocks" 9 + - reg: Base address and length of the memory resource used by the CPG 10 + 11 + - clocks: Reference to the parent clock 12 + - #clock-cells: Must be 1 13 + - clock-output-names: The names of the clocks. Supported clocks are "plla", 14 + "z", "zs", "s", "s1", "p", "b", "out". 15 + 16 + 17 + Example 18 + ------- 19 + 20 + cpg_clocks: cpg_clocks@ffc80000 { 21 + compatible = "renesas,r8a7779-cpg-clocks"; 22 + reg = <0 0xffc80000 0 0x30>; 23 + clocks = <&extal_clk>; 24 + #clock-cells = <1>; 25 + clock-output-names = "plla", "z", "zs", "s", "s1", "p", 26 + "b", "out"; 27 + };
+43
Documentation/devicetree/bindings/mmc/sunxi-mmc.txt
··· 1 + * Allwinner sunxi MMC controller 2 + 3 + The highspeed MMC host controller on Allwinner SoCs provides an interface 4 + for MMC, SD and SDIO types of memory cards. 5 + 6 + Supported maximum speeds are the ones of the eMMC standard 4.5 as well 7 + as the speed of SD standard 3.0. 8 + Absolute maximum transfer rate is 200MB/s 9 + 10 + Required properties: 11 + - compatible : "allwinner,sun4i-a10-mmc" or "allwinner,sun5i-a13-mmc" 12 + - reg : mmc controller base registers 13 + - clocks : a list with 2 phandle + clock specifier pairs 14 + - clock-names : must contain "ahb" and "mmc" 15 + - interrupts : mmc controller interrupt 16 + 17 + Optional properties: 18 + - resets : phandle + reset specifier pair 19 + - reset-names : must contain "ahb" 20 + - for cd, bus-width and additional generic mmc parameters 21 + please refer to mmc.txt within this directory 22 + 23 + Examples: 24 + - Within .dtsi: 25 + mmc0: mmc@01c0f000 { 26 + compatible = "allwinner,sun5i-a13-mmc"; 27 + reg = <0x01c0f000 0x1000>; 28 + clocks = <&ahb_gates 8>, <&mmc0_clk>; 29 + clock-names = "ahb", "mod"; 30 + interrupts = <0 32 4>; 31 + status = "disabled"; 32 + }; 33 + 34 + - Within dts: 35 + mmc0: mmc@01c0f000 { 36 + pinctrl-names = "default", "default"; 37 + pinctrl-0 = <&mmc0_pins_a>; 38 + pinctrl-1 = <&mmc0_cd_pin_reference_design>; 39 + bus-width = <4>; 40 + cd-gpios = <&pio 7 1 0>; /* PH1 */ 41 + cd-inverted; 42 + status = "okay"; 43 + };
+5
MAINTAINERS
··· 815 815 F: arch/arm/boot/dts/sama*.dts 816 816 F: arch/arm/boot/dts/sama*.dtsi 817 817 818 + ARM/ATMEL AT91 Clock Support 819 + M: Boris Brezillon <boris.brezillon@free-electrons.com> 820 + S: Maintained 821 + F: drivers/clk/at91 822 + 818 823 ARM/CALXEDA HIGHBANK ARCHITECTURE 819 824 M: Rob Herring <robh@kernel.org> 820 825 L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+130 -84
arch/arm/boot/dts/bcm21664.dtsi
··· 14 14 #include <dt-bindings/interrupt-controller/arm-gic.h> 15 15 #include <dt-bindings/interrupt-controller/irq.h> 16 16 17 + #include "dt-bindings/clock/bcm21664.h" 18 + 17 19 #include "skeleton.dtsi" 18 20 19 21 / { ··· 45 43 compatible = "brcm,bcm21664-dw-apb-uart", "snps,dw-apb-uart"; 46 44 status = "disabled"; 47 45 reg = <0x3e000000 0x118>; 48 - clocks = <&uartb_clk>; 46 + clocks = <&slave_ccu BCM21664_SLAVE_CCU_UARTB>; 49 47 interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>; 50 48 reg-shift = <2>; 51 49 reg-io-width = <4>; ··· 55 53 compatible = "brcm,bcm21664-dw-apb-uart", "snps,dw-apb-uart"; 56 54 status = "disabled"; 57 55 reg = <0x3e001000 0x118>; 58 - clocks = <&uartb2_clk>; 56 + clocks = <&slave_ccu BCM21664_SLAVE_CCU_UARTB2>; 59 57 interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>; 60 58 reg-shift = <2>; 61 59 reg-io-width = <4>; ··· 65 63 compatible = "brcm,bcm21664-dw-apb-uart", "snps,dw-apb-uart"; 66 64 status = "disabled"; 67 65 reg = <0x3e002000 0x118>; 68 - clocks = <&uartb3_clk>; 66 + clocks = <&slave_ccu BCM21664_SLAVE_CCU_UARTB3>; 69 67 interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>; 70 68 reg-shift = <2>; 71 69 reg-io-width = <4>; ··· 87 85 compatible = "brcm,kona-timer"; 88 86 reg = <0x35006000 0x1c>; 89 87 interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; 90 - clocks = <&hub_timer_clk>; 88 + clocks = <&aon_ccu BCM21664_AON_CCU_HUB_TIMER>; 91 89 }; 92 90 93 91 gpio: gpio@35003000 { ··· 108 106 compatible = "brcm,kona-sdhci"; 109 107 reg = <0x3f180000 0x801c>; 110 108 interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>; 111 - clocks = <&sdio1_clk>; 109 + clocks = <&master_ccu BCM21664_MASTER_CCU_SDIO1>; 112 110 status = "disabled"; 113 111 }; 114 112 ··· 116 114 compatible = "brcm,kona-sdhci"; 117 115 reg = <0x3f190000 0x801c>; 118 116 interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>; 119 - clocks = <&sdio2_clk>; 117 + clocks = <&master_ccu BCM21664_MASTER_CCU_SDIO2>; 120 118 status = "disabled"; 121 119 }; 122 120 ··· 124 122 compatible = "brcm,kona-sdhci"; 125 123 reg = <0x3f1a0000 0x801c>; 126 124 interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>; 127 - clocks = <&sdio3_clk>; 125 + clocks = <&master_ccu BCM21664_MASTER_CCU_SDIO3>; 128 126 status = "disabled"; 129 127 }; 130 128 ··· 132 130 compatible = "brcm,kona-sdhci"; 133 131 reg = <0x3f1b0000 0x801c>; 134 132 interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; 135 - clocks = <&sdio4_clk>; 133 + clocks = <&master_ccu BCM21664_MASTER_CCU_SDIO4>; 136 134 status = "disabled"; 137 135 }; 138 136 ··· 142 140 interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>; 143 141 #address-cells = <1>; 144 142 #size-cells = <0>; 145 - clocks = <&bsc1_clk>; 143 + clocks = <&slave_ccu BCM21664_SLAVE_CCU_BSC1>; 146 144 status = "disabled"; 147 145 }; 148 146 ··· 152 150 interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>; 153 151 #address-cells = <1>; 154 152 #size-cells = <0>; 155 - clocks = <&bsc2_clk>; 153 + clocks = <&slave_ccu BCM21664_SLAVE_CCU_BSC2>; 156 154 status = "disabled"; 157 155 }; 158 156 ··· 162 160 interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>; 163 161 #address-cells = <1>; 164 162 #size-cells = <0>; 165 - clocks = <&bsc3_clk>; 163 + clocks = <&slave_ccu BCM21664_SLAVE_CCU_BSC3>; 166 164 status = "disabled"; 167 165 }; 168 166 ··· 172 170 interrupts = <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>; 173 171 #address-cells = <1>; 174 172 #size-cells = <0>; 175 - clocks = <&bsc4_clk>; 173 + clocks = <&slave_ccu BCM21664_SLAVE_CCU_BSC4>; 176 174 status = "disabled"; 177 175 }; 178 176 179 177 clocks { 180 - bsc1_clk: bsc1 { 181 - compatible = "fixed-clock"; 182 - clock-frequency = <13000000>; 183 - #clock-cells = <0>; 184 - }; 178 + #address-cells = <1>; 179 + #size-cells = <1>; 180 + ranges; 185 181 186 - bsc2_clk: bsc2 { 187 - compatible = "fixed-clock"; 188 - clock-frequency = <13000000>; 189 - #clock-cells = <0>; 190 - }; 182 + /* 183 + * Fixed clocks are defined before CCUs whose 184 + * clocks may depend on them. 185 + */ 191 186 192 - bsc3_clk: bsc3 { 193 - compatible = "fixed-clock"; 194 - clock-frequency = <13000000>; 187 + ref_32k_clk: ref_32k { 195 188 #clock-cells = <0>; 196 - }; 197 - 198 - bsc4_clk: bsc4 { 199 - compatible = "fixed-clock"; 200 - clock-frequency = <13000000>; 201 - #clock-cells = <0>; 202 - }; 203 - 204 - pmu_bsc_clk: pmu_bsc { 205 - compatible = "fixed-clock"; 206 - clock-frequency = <13000000>; 207 - #clock-cells = <0>; 208 - }; 209 - 210 - hub_timer_clk: hub_timer { 211 189 compatible = "fixed-clock"; 212 190 clock-frequency = <32768>; 213 - #clock-cells = <0>; 214 191 }; 215 192 216 - pwm_clk: pwm { 193 + bbl_32k_clk: bbl_32k { 194 + #clock-cells = <0>; 195 + compatible = "fixed-clock"; 196 + clock-frequency = <32768>; 197 + }; 198 + 199 + ref_13m_clk: ref_13m { 200 + #clock-cells = <0>; 201 + compatible = "fixed-clock"; 202 + clock-frequency = <13000000>; 203 + }; 204 + 205 + var_13m_clk: var_13m { 206 + #clock-cells = <0>; 207 + compatible = "fixed-clock"; 208 + clock-frequency = <13000000>; 209 + }; 210 + 211 + dft_19_5m_clk: dft_19_5m { 212 + #clock-cells = <0>; 213 + compatible = "fixed-clock"; 214 + clock-frequency = <19500000>; 215 + }; 216 + 217 + ref_crystal_clk: ref_crystal { 218 + #clock-cells = <0>; 217 219 compatible = "fixed-clock"; 218 220 clock-frequency = <26000000>; 219 - #clock-cells = <0>; 220 221 }; 221 222 222 - sdio1_clk: sdio1 { 223 - compatible = "fixed-clock"; 224 - clock-frequency = <48000000>; 223 + ref_52m_clk: ref_52m { 225 224 #clock-cells = <0>; 225 + compatible = "fixed-clock"; 226 + clock-frequency = <52000000>; 226 227 }; 227 228 228 - sdio2_clk: sdio2 { 229 - compatible = "fixed-clock"; 230 - clock-frequency = <48000000>; 229 + var_52m_clk: var_52m { 231 230 #clock-cells = <0>; 232 - }; 233 - 234 - sdio3_clk: sdio3 { 235 231 compatible = "fixed-clock"; 236 - clock-frequency = <48000000>; 237 - #clock-cells = <0>; 238 - }; 239 - 240 - sdio4_clk: sdio4 { 241 - compatible = "fixed-clock"; 242 - clock-frequency = <48000000>; 243 - #clock-cells = <0>; 244 - }; 245 - 246 - tmon_1m_clk: tmon_1m { 247 - compatible = "fixed-clock"; 248 - clock-frequency = <1000000>; 249 - #clock-cells = <0>; 250 - }; 251 - 252 - uartb_clk: uartb { 253 - compatible = "fixed-clock"; 254 - clock-frequency = <13000000>; 255 - #clock-cells = <0>; 256 - }; 257 - 258 - uartb2_clk: uartb2 { 259 - compatible = "fixed-clock"; 260 - clock-frequency = <13000000>; 261 - #clock-cells = <0>; 262 - }; 263 - 264 - uartb3_clk: uartb3 { 265 - compatible = "fixed-clock"; 266 - clock-frequency = <13000000>; 267 - #clock-cells = <0>; 232 + clock-frequency = <52000000>; 268 233 }; 269 234 270 235 usb_otg_ahb_clk: usb_otg_ahb { 236 + #clock-cells = <0>; 271 237 compatible = "fixed-clock"; 272 238 clock-frequency = <52000000>; 239 + }; 240 + 241 + ref_96m_clk: ref_96m { 273 242 #clock-cells = <0>; 243 + compatible = "fixed-clock"; 244 + clock-frequency = <96000000>; 245 + }; 246 + 247 + var_96m_clk: var_96m { 248 + #clock-cells = <0>; 249 + compatible = "fixed-clock"; 250 + clock-frequency = <96000000>; 251 + }; 252 + 253 + ref_104m_clk: ref_104m { 254 + #clock-cells = <0>; 255 + compatible = "fixed-clock"; 256 + clock-frequency = <104000000>; 257 + }; 258 + 259 + var_104m_clk: var_104m { 260 + #clock-cells = <0>; 261 + compatible = "fixed-clock"; 262 + clock-frequency = <104000000>; 263 + }; 264 + 265 + ref_156m_clk: ref_156m { 266 + #clock-cells = <0>; 267 + compatible = "fixed-clock"; 268 + clock-frequency = <156000000>; 269 + }; 270 + 271 + var_156m_clk: var_156m { 272 + #clock-cells = <0>; 273 + compatible = "fixed-clock"; 274 + clock-frequency = <156000000>; 275 + }; 276 + 277 + root_ccu: root_ccu { 278 + compatible = BCM21664_DT_ROOT_CCU_COMPAT; 279 + reg = <0x35001000 0x0f00>; 280 + #clock-cells = <1>; 281 + clock-output-names = "frac_1m"; 282 + }; 283 + 284 + aon_ccu: aon_ccu { 285 + compatible = BCM21664_DT_AON_CCU_COMPAT; 286 + reg = <0x35002000 0x0f00>; 287 + #clock-cells = <1>; 288 + clock-output-names = "hub_timer"; 289 + }; 290 + 291 + master_ccu: master_ccu { 292 + compatible = BCM21664_DT_MASTER_CCU_COMPAT; 293 + reg = <0x3f001000 0x0f00>; 294 + #clock-cells = <1>; 295 + clock-output-names = "sdio1", 296 + "sdio2", 297 + "sdio3", 298 + "sdio4", 299 + "sdio1_sleep", 300 + "sdio2_sleep", 301 + "sdio3_sleep", 302 + "sdio4_sleep"; 303 + }; 304 + 305 + slave_ccu: slave_ccu { 306 + compatible = BCM21664_DT_SLAVE_CCU_COMPAT; 307 + reg = <0x3e011000 0x0f00>; 308 + #clock-cells = <1>; 309 + clock-output-names = "uartb", 310 + "uartb2", 311 + "uartb3", 312 + "bsc1", 313 + "bsc2", 314 + "bsc3", 315 + "bsc4"; 274 316 }; 275 317 }; 276 318
+4 -4
drivers/clk/Kconfig
··· 58 58 clock generators. 59 59 60 60 config COMMON_CLK_S2MPS11 61 - tristate "Clock driver for S2MPS11/S5M8767 MFD" 61 + tristate "Clock driver for S2MPS1X/S5M8767 MFD" 62 62 depends on MFD_SEC_CORE 63 63 ---help--- 64 - This driver supports S2MPS11/S5M8767 crystal oscillator clock. These 65 - multi-function devices have 3 fixed-rate oscillators, clocked at 66 - 32KHz each. 64 + This driver supports S2MPS11/S2MPS14/S5M8767 crystal oscillator 65 + clock. These multi-function devices have two (S2MPS14) or three 66 + (S2MPS11, S5M8767) fixed-rate oscillators, clocked at 32KHz each. 67 67 68 68 config CLK_TWL6040 69 69 tristate "External McPDM functional clock from twl6040"
+3
drivers/clk/Makefile
··· 13 13 # hardware specific clock types 14 14 # please keep this section sorted lexicographically by file/directory path name 15 15 obj-$(CONFIG_COMMON_CLK_AXI_CLKGEN) += clk-axi-clkgen.o 16 + obj-$(CONFIG_ARCH_AXXIA) += clk-axm5516.o 16 17 obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835.o 17 18 obj-$(CONFIG_ARCH_EFM32) += clk-efm32gg.o 18 19 obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o ··· 33 32 obj-$(CONFIG_COMMON_CLK_XGENE) += clk-xgene.o 34 33 obj-$(CONFIG_COMMON_CLK_AT91) += at91/ 35 34 obj-$(CONFIG_ARCH_BCM_MOBILE) += bcm/ 35 + obj-$(CONFIG_ARCH_BERLIN) += berlin/ 36 36 obj-$(CONFIG_ARCH_HI3xxx) += hisilicon/ 37 37 obj-$(CONFIG_ARCH_HIP04) += hisilicon/ 38 + obj-$(CONFIG_ARCH_HIX5HD2) += hisilicon/ 38 39 obj-$(CONFIG_COMMON_CLK_KEYSTONE) += keystone/ 39 40 ifeq ($(CONFIG_COMMON_CLK), y) 40 41 obj-$(CONFIG_ARCH_MMP) += mmp/
+1 -1
drivers/clk/bcm/Kconfig
··· 6 6 help 7 7 Enable common clock framework support for Broadcom SoCs 8 8 using "Kona" style clock control units, including those 9 - in the BCM281xx family. 9 + in the BCM281xx and BCM21664 families.
+1
drivers/clk/bcm/Makefile
··· 1 1 obj-$(CONFIG_CLK_BCM_KONA) += clk-kona.o 2 2 obj-$(CONFIG_CLK_BCM_KONA) += clk-kona-setup.o 3 3 obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm281xx.o 4 + obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm21664.o
+290
drivers/clk/bcm/clk-bcm21664.c
··· 1 + /* 2 + * Copyright (C) 2014 Broadcom Corporation 3 + * Copyright 2014 Linaro Limited 4 + * 5 + * This program is free software; you can redistribute it and/or 6 + * modify it under the terms of the GNU General Public License as 7 + * published by the Free Software Foundation version 2. 8 + * 9 + * This program is distributed "as is" WITHOUT ANY WARRANTY of any 10 + * kind, whether express or implied; without even the implied warranty 11 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 + * GNU General Public License for more details. 13 + */ 14 + 15 + #include "clk-kona.h" 16 + #include "dt-bindings/clock/bcm21664.h" 17 + 18 + #define BCM21664_CCU_COMMON(_name, _capname) \ 19 + KONA_CCU_COMMON(BCM21664, _name, _capname) 20 + 21 + /* Root CCU */ 22 + 23 + static struct peri_clk_data frac_1m_data = { 24 + .gate = HW_SW_GATE(0x214, 16, 0, 1), 25 + .clocks = CLOCKS("ref_crystal"), 26 + }; 27 + 28 + static struct ccu_data root_ccu_data = { 29 + BCM21664_CCU_COMMON(root, ROOT), 30 + /* no policy control */ 31 + .kona_clks = { 32 + [BCM21664_ROOT_CCU_FRAC_1M] = 33 + KONA_CLK(root, frac_1m, peri), 34 + [BCM21664_ROOT_CCU_CLOCK_COUNT] = LAST_KONA_CLK, 35 + }, 36 + }; 37 + 38 + /* AON CCU */ 39 + 40 + static struct peri_clk_data hub_timer_data = { 41 + .gate = HW_SW_GATE(0x0414, 16, 0, 1), 42 + .hyst = HYST(0x0414, 8, 9), 43 + .clocks = CLOCKS("bbl_32k", 44 + "frac_1m", 45 + "dft_19_5m"), 46 + .sel = SELECTOR(0x0a10, 0, 2), 47 + .trig = TRIGGER(0x0a40, 4), 48 + }; 49 + 50 + static struct ccu_data aon_ccu_data = { 51 + BCM21664_CCU_COMMON(aon, AON), 52 + .policy = { 53 + .enable = CCU_LVM_EN(0x0034, 0), 54 + .control = CCU_POLICY_CTL(0x000c, 0, 1, 2), 55 + }, 56 + .kona_clks = { 57 + [BCM21664_AON_CCU_HUB_TIMER] = 58 + KONA_CLK(aon, hub_timer, peri), 59 + [BCM21664_AON_CCU_CLOCK_COUNT] = LAST_KONA_CLK, 60 + }, 61 + }; 62 + 63 + /* Master CCU */ 64 + 65 + static struct peri_clk_data sdio1_data = { 66 + .gate = HW_SW_GATE(0x0358, 18, 2, 3), 67 + .clocks = CLOCKS("ref_crystal", 68 + "var_52m", 69 + "ref_52m", 70 + "var_96m", 71 + "ref_96m"), 72 + .sel = SELECTOR(0x0a28, 0, 3), 73 + .div = DIVIDER(0x0a28, 4, 14), 74 + .trig = TRIGGER(0x0afc, 9), 75 + }; 76 + 77 + static struct peri_clk_data sdio2_data = { 78 + .gate = HW_SW_GATE(0x035c, 18, 2, 3), 79 + .clocks = CLOCKS("ref_crystal", 80 + "var_52m", 81 + "ref_52m", 82 + "var_96m", 83 + "ref_96m"), 84 + .sel = SELECTOR(0x0a2c, 0, 3), 85 + .div = DIVIDER(0x0a2c, 4, 14), 86 + .trig = TRIGGER(0x0afc, 10), 87 + }; 88 + 89 + static struct peri_clk_data sdio3_data = { 90 + .gate = HW_SW_GATE(0x0364, 18, 2, 3), 91 + .clocks = CLOCKS("ref_crystal", 92 + "var_52m", 93 + "ref_52m", 94 + "var_96m", 95 + "ref_96m"), 96 + .sel = SELECTOR(0x0a34, 0, 3), 97 + .div = DIVIDER(0x0a34, 4, 14), 98 + .trig = TRIGGER(0x0afc, 12), 99 + }; 100 + 101 + static struct peri_clk_data sdio4_data = { 102 + .gate = HW_SW_GATE(0x0360, 18, 2, 3), 103 + .clocks = CLOCKS("ref_crystal", 104 + "var_52m", 105 + "ref_52m", 106 + "var_96m", 107 + "ref_96m"), 108 + .sel = SELECTOR(0x0a30, 0, 3), 109 + .div = DIVIDER(0x0a30, 4, 14), 110 + .trig = TRIGGER(0x0afc, 11), 111 + }; 112 + 113 + static struct peri_clk_data sdio1_sleep_data = { 114 + .clocks = CLOCKS("ref_32k"), /* Verify */ 115 + .gate = HW_SW_GATE(0x0358, 18, 2, 3), 116 + }; 117 + 118 + static struct peri_clk_data sdio2_sleep_data = { 119 + .clocks = CLOCKS("ref_32k"), /* Verify */ 120 + .gate = HW_SW_GATE(0x035c, 18, 2, 3), 121 + }; 122 + 123 + static struct peri_clk_data sdio3_sleep_data = { 124 + .clocks = CLOCKS("ref_32k"), /* Verify */ 125 + .gate = HW_SW_GATE(0x0364, 18, 2, 3), 126 + }; 127 + 128 + static struct peri_clk_data sdio4_sleep_data = { 129 + .clocks = CLOCKS("ref_32k"), /* Verify */ 130 + .gate = HW_SW_GATE(0x0360, 18, 2, 3), 131 + }; 132 + 133 + static struct ccu_data master_ccu_data = { 134 + BCM21664_CCU_COMMON(master, MASTER), 135 + .policy = { 136 + .enable = CCU_LVM_EN(0x0034, 0), 137 + .control = CCU_POLICY_CTL(0x000c, 0, 1, 2), 138 + }, 139 + .kona_clks = { 140 + [BCM21664_MASTER_CCU_SDIO1] = 141 + KONA_CLK(master, sdio1, peri), 142 + [BCM21664_MASTER_CCU_SDIO2] = 143 + KONA_CLK(master, sdio2, peri), 144 + [BCM21664_MASTER_CCU_SDIO3] = 145 + KONA_CLK(master, sdio3, peri), 146 + [BCM21664_MASTER_CCU_SDIO4] = 147 + KONA_CLK(master, sdio4, peri), 148 + [BCM21664_MASTER_CCU_SDIO1_SLEEP] = 149 + KONA_CLK(master, sdio1_sleep, peri), 150 + [BCM21664_MASTER_CCU_SDIO2_SLEEP] = 151 + KONA_CLK(master, sdio2_sleep, peri), 152 + [BCM21664_MASTER_CCU_SDIO3_SLEEP] = 153 + KONA_CLK(master, sdio3_sleep, peri), 154 + [BCM21664_MASTER_CCU_SDIO4_SLEEP] = 155 + KONA_CLK(master, sdio4_sleep, peri), 156 + [BCM21664_MASTER_CCU_CLOCK_COUNT] = LAST_KONA_CLK, 157 + }, 158 + }; 159 + 160 + /* Slave CCU */ 161 + 162 + static struct peri_clk_data uartb_data = { 163 + .gate = HW_SW_GATE(0x0400, 18, 2, 3), 164 + .clocks = CLOCKS("ref_crystal", 165 + "var_156m", 166 + "ref_156m"), 167 + .sel = SELECTOR(0x0a10, 0, 2), 168 + .div = FRAC_DIVIDER(0x0a10, 4, 12, 8), 169 + .trig = TRIGGER(0x0afc, 2), 170 + }; 171 + 172 + static struct peri_clk_data uartb2_data = { 173 + .gate = HW_SW_GATE(0x0404, 18, 2, 3), 174 + .clocks = CLOCKS("ref_crystal", 175 + "var_156m", 176 + "ref_156m"), 177 + .sel = SELECTOR(0x0a14, 0, 2), 178 + .div = FRAC_DIVIDER(0x0a14, 4, 12, 8), 179 + .trig = TRIGGER(0x0afc, 3), 180 + }; 181 + 182 + static struct peri_clk_data uartb3_data = { 183 + .gate = HW_SW_GATE(0x0408, 18, 2, 3), 184 + .clocks = CLOCKS("ref_crystal", 185 + "var_156m", 186 + "ref_156m"), 187 + .sel = SELECTOR(0x0a18, 0, 2), 188 + .div = FRAC_DIVIDER(0x0a18, 4, 12, 8), 189 + .trig = TRIGGER(0x0afc, 4), 190 + }; 191 + 192 + static struct peri_clk_data bsc1_data = { 193 + .gate = HW_SW_GATE(0x0458, 18, 2, 3), 194 + .clocks = CLOCKS("ref_crystal", 195 + "var_104m", 196 + "ref_104m", 197 + "var_13m", 198 + "ref_13m"), 199 + .sel = SELECTOR(0x0a64, 0, 3), 200 + .trig = TRIGGER(0x0afc, 23), 201 + }; 202 + 203 + static struct peri_clk_data bsc2_data = { 204 + .gate = HW_SW_GATE(0x045c, 18, 2, 3), 205 + .clocks = CLOCKS("ref_crystal", 206 + "var_104m", 207 + "ref_104m", 208 + "var_13m", 209 + "ref_13m"), 210 + .sel = SELECTOR(0x0a68, 0, 3), 211 + .trig = TRIGGER(0x0afc, 24), 212 + }; 213 + 214 + static struct peri_clk_data bsc3_data = { 215 + .gate = HW_SW_GATE(0x0470, 18, 2, 3), 216 + .clocks = CLOCKS("ref_crystal", 217 + "var_104m", 218 + "ref_104m", 219 + "var_13m", 220 + "ref_13m"), 221 + .sel = SELECTOR(0x0a7c, 0, 3), 222 + .trig = TRIGGER(0x0afc, 18), 223 + }; 224 + 225 + static struct peri_clk_data bsc4_data = { 226 + .gate = HW_SW_GATE(0x0474, 18, 2, 3), 227 + .clocks = CLOCKS("ref_crystal", 228 + "var_104m", 229 + "ref_104m", 230 + "var_13m", 231 + "ref_13m"), 232 + .sel = SELECTOR(0x0a80, 0, 3), 233 + .trig = TRIGGER(0x0afc, 19), 234 + }; 235 + 236 + static struct ccu_data slave_ccu_data = { 237 + BCM21664_CCU_COMMON(slave, SLAVE), 238 + .policy = { 239 + .enable = CCU_LVM_EN(0x0034, 0), 240 + .control = CCU_POLICY_CTL(0x000c, 0, 1, 2), 241 + }, 242 + .kona_clks = { 243 + [BCM21664_SLAVE_CCU_UARTB] = 244 + KONA_CLK(slave, uartb, peri), 245 + [BCM21664_SLAVE_CCU_UARTB2] = 246 + KONA_CLK(slave, uartb2, peri), 247 + [BCM21664_SLAVE_CCU_UARTB3] = 248 + KONA_CLK(slave, uartb3, peri), 249 + [BCM21664_SLAVE_CCU_BSC1] = 250 + KONA_CLK(slave, bsc1, peri), 251 + [BCM21664_SLAVE_CCU_BSC2] = 252 + KONA_CLK(slave, bsc2, peri), 253 + [BCM21664_SLAVE_CCU_BSC3] = 254 + KONA_CLK(slave, bsc3, peri), 255 + [BCM21664_SLAVE_CCU_BSC4] = 256 + KONA_CLK(slave, bsc4, peri), 257 + [BCM21664_SLAVE_CCU_CLOCK_COUNT] = LAST_KONA_CLK, 258 + }, 259 + }; 260 + 261 + /* Device tree match table callback functions */ 262 + 263 + static void __init kona_dt_root_ccu_setup(struct device_node *node) 264 + { 265 + kona_dt_ccu_setup(&root_ccu_data, node); 266 + } 267 + 268 + static void __init kona_dt_aon_ccu_setup(struct device_node *node) 269 + { 270 + kona_dt_ccu_setup(&aon_ccu_data, node); 271 + } 272 + 273 + static void __init kona_dt_master_ccu_setup(struct device_node *node) 274 + { 275 + kona_dt_ccu_setup(&master_ccu_data, node); 276 + } 277 + 278 + static void __init kona_dt_slave_ccu_setup(struct device_node *node) 279 + { 280 + kona_dt_ccu_setup(&slave_ccu_data, node); 281 + } 282 + 283 + CLK_OF_DECLARE(bcm21664_root_ccu, BCM21664_DT_ROOT_CCU_COMPAT, 284 + kona_dt_root_ccu_setup); 285 + CLK_OF_DECLARE(bcm21664_aon_ccu, BCM21664_DT_AON_CCU_COMPAT, 286 + kona_dt_aon_ccu_setup); 287 + CLK_OF_DECLARE(bcm21664_master_ccu, BCM21664_DT_MASTER_CCU_COMPAT, 288 + kona_dt_master_ccu_setup); 289 + CLK_OF_DECLARE(bcm21664_slave_ccu, BCM21664_DT_SLAVE_CCU_COMPAT, 290 + kona_dt_slave_ccu_setup);
+95 -136
drivers/clk/bcm/clk-bcm281xx.c
··· 15 15 #include "clk-kona.h" 16 16 #include "dt-bindings/clock/bcm281xx.h" 17 17 18 - /* bcm11351 CCU device tree "compatible" strings */ 19 - #define BCM11351_DT_ROOT_CCU_COMPAT "brcm,bcm11351-root-ccu" 20 - #define BCM11351_DT_AON_CCU_COMPAT "brcm,bcm11351-aon-ccu" 21 - #define BCM11351_DT_HUB_CCU_COMPAT "brcm,bcm11351-hub-ccu" 22 - #define BCM11351_DT_MASTER_CCU_COMPAT "brcm,bcm11351-master-ccu" 23 - #define BCM11351_DT_SLAVE_CCU_COMPAT "brcm,bcm11351-slave-ccu" 18 + #define BCM281XX_CCU_COMMON(_name, _ucase_name) \ 19 + KONA_CCU_COMMON(BCM281XX, _name, _ucase_name) 24 20 25 - /* Root CCU clocks */ 21 + /* Root CCU */ 26 22 27 23 static struct peri_clk_data frac_1m_data = { 28 24 .gate = HW_SW_GATE(0x214, 16, 0, 1), ··· 27 31 .clocks = CLOCKS("ref_crystal"), 28 32 }; 29 33 30 - /* AON CCU clocks */ 34 + static struct ccu_data root_ccu_data = { 35 + BCM281XX_CCU_COMMON(root, ROOT), 36 + .kona_clks = { 37 + [BCM281XX_ROOT_CCU_FRAC_1M] = 38 + KONA_CLK(root, frac_1m, peri), 39 + [BCM281XX_ROOT_CCU_CLOCK_COUNT] = LAST_KONA_CLK, 40 + }, 41 + }; 42 + 43 + /* AON CCU */ 31 44 32 45 static struct peri_clk_data hub_timer_data = { 33 46 .gate = HW_SW_GATE(0x0414, 16, 0, 1), ··· 65 60 .trig = TRIGGER(0x0a40, 2), 66 61 }; 67 62 68 - /* Hub CCU clocks */ 63 + static struct ccu_data aon_ccu_data = { 64 + BCM281XX_CCU_COMMON(aon, AON), 65 + .kona_clks = { 66 + [BCM281XX_AON_CCU_HUB_TIMER] = 67 + KONA_CLK(aon, hub_timer, peri), 68 + [BCM281XX_AON_CCU_PMU_BSC] = 69 + KONA_CLK(aon, pmu_bsc, peri), 70 + [BCM281XX_AON_CCU_PMU_BSC_VAR] = 71 + KONA_CLK(aon, pmu_bsc_var, peri), 72 + [BCM281XX_AON_CCU_CLOCK_COUNT] = LAST_KONA_CLK, 73 + }, 74 + }; 75 + 76 + /* Hub CCU */ 69 77 70 78 static struct peri_clk_data tmon_1m_data = { 71 79 .gate = HW_SW_GATE(0x04a4, 18, 2, 3), ··· 88 70 .trig = TRIGGER(0x0e84, 1), 89 71 }; 90 72 91 - /* Master CCU clocks */ 73 + static struct ccu_data hub_ccu_data = { 74 + BCM281XX_CCU_COMMON(hub, HUB), 75 + .kona_clks = { 76 + [BCM281XX_HUB_CCU_TMON_1M] = 77 + KONA_CLK(hub, tmon_1m, peri), 78 + [BCM281XX_HUB_CCU_CLOCK_COUNT] = LAST_KONA_CLK, 79 + }, 80 + }; 81 + 82 + /* Master CCU */ 92 83 93 84 static struct peri_clk_data sdio1_data = { 94 85 .gate = HW_SW_GATE(0x0358, 18, 2, 3), ··· 180 153 .trig = TRIGGER(0x0afc, 5), 181 154 }; 182 155 183 - /* Slave CCU clocks */ 156 + static struct ccu_data master_ccu_data = { 157 + BCM281XX_CCU_COMMON(master, MASTER), 158 + .kona_clks = { 159 + [BCM281XX_MASTER_CCU_SDIO1] = 160 + KONA_CLK(master, sdio1, peri), 161 + [BCM281XX_MASTER_CCU_SDIO2] = 162 + KONA_CLK(master, sdio2, peri), 163 + [BCM281XX_MASTER_CCU_SDIO3] = 164 + KONA_CLK(master, sdio3, peri), 165 + [BCM281XX_MASTER_CCU_SDIO4] = 166 + KONA_CLK(master, sdio4, peri), 167 + [BCM281XX_MASTER_CCU_USB_IC] = 168 + KONA_CLK(master, usb_ic, peri), 169 + [BCM281XX_MASTER_CCU_HSIC2_48M] = 170 + KONA_CLK(master, hsic2_48m, peri), 171 + [BCM281XX_MASTER_CCU_HSIC2_12M] = 172 + KONA_CLK(master, hsic2_12m, peri), 173 + [BCM281XX_MASTER_CCU_CLOCK_COUNT] = LAST_KONA_CLK, 174 + }, 175 + }; 176 + 177 + /* Slave CCU */ 184 178 185 179 static struct peri_clk_data uartb_data = { 186 180 .gate = HW_SW_GATE(0x0400, 18, 2, 3), ··· 309 261 .trig = TRIGGER(0x0afc, 15), 310 262 }; 311 263 312 - /* 313 - * CCU setup routines 314 - * 315 - * These are called from kona_dt_ccu_setup() to initialize the array 316 - * of clocks provided by the CCU. Once allocated, the entries in 317 - * the array are initialized by calling kona_clk_setup() with the 318 - * initialization data for each clock. They return 0 if successful 319 - * or an error code otherwise. 320 - */ 321 - static int __init bcm281xx_root_ccu_clks_setup(struct ccu_data *ccu) 322 - { 323 - struct clk **clks; 324 - size_t count = BCM281XX_ROOT_CCU_CLOCK_COUNT; 325 - 326 - clks = kzalloc(count * sizeof(*clks), GFP_KERNEL); 327 - if (!clks) { 328 - pr_err("%s: failed to allocate root clocks\n", __func__); 329 - return -ENOMEM; 330 - } 331 - ccu->data.clks = clks; 332 - ccu->data.clk_num = count; 333 - 334 - PERI_CLK_SETUP(clks, ccu, BCM281XX_ROOT_CCU_FRAC_1M, frac_1m); 335 - 336 - return 0; 337 - } 338 - 339 - static int __init bcm281xx_aon_ccu_clks_setup(struct ccu_data *ccu) 340 - { 341 - struct clk **clks; 342 - size_t count = BCM281XX_AON_CCU_CLOCK_COUNT; 343 - 344 - clks = kzalloc(count * sizeof(*clks), GFP_KERNEL); 345 - if (!clks) { 346 - pr_err("%s: failed to allocate aon clocks\n", __func__); 347 - return -ENOMEM; 348 - } 349 - ccu->data.clks = clks; 350 - ccu->data.clk_num = count; 351 - 352 - PERI_CLK_SETUP(clks, ccu, BCM281XX_AON_CCU_HUB_TIMER, hub_timer); 353 - PERI_CLK_SETUP(clks, ccu, BCM281XX_AON_CCU_PMU_BSC, pmu_bsc); 354 - PERI_CLK_SETUP(clks, ccu, BCM281XX_AON_CCU_PMU_BSC_VAR, pmu_bsc_var); 355 - 356 - return 0; 357 - } 358 - 359 - static int __init bcm281xx_hub_ccu_clks_setup(struct ccu_data *ccu) 360 - { 361 - struct clk **clks; 362 - size_t count = BCM281XX_HUB_CCU_CLOCK_COUNT; 363 - 364 - clks = kzalloc(count * sizeof(*clks), GFP_KERNEL); 365 - if (!clks) { 366 - pr_err("%s: failed to allocate hub clocks\n", __func__); 367 - return -ENOMEM; 368 - } 369 - ccu->data.clks = clks; 370 - ccu->data.clk_num = count; 371 - 372 - PERI_CLK_SETUP(clks, ccu, BCM281XX_HUB_CCU_TMON_1M, tmon_1m); 373 - 374 - return 0; 375 - } 376 - 377 - static int __init bcm281xx_master_ccu_clks_setup(struct ccu_data *ccu) 378 - { 379 - struct clk **clks; 380 - size_t count = BCM281XX_MASTER_CCU_CLOCK_COUNT; 381 - 382 - clks = kzalloc(count * sizeof(*clks), GFP_KERNEL); 383 - if (!clks) { 384 - pr_err("%s: failed to allocate master clocks\n", __func__); 385 - return -ENOMEM; 386 - } 387 - ccu->data.clks = clks; 388 - ccu->data.clk_num = count; 389 - 390 - PERI_CLK_SETUP(clks, ccu, BCM281XX_MASTER_CCU_SDIO1, sdio1); 391 - PERI_CLK_SETUP(clks, ccu, BCM281XX_MASTER_CCU_SDIO2, sdio2); 392 - PERI_CLK_SETUP(clks, ccu, BCM281XX_MASTER_CCU_SDIO3, sdio3); 393 - PERI_CLK_SETUP(clks, ccu, BCM281XX_MASTER_CCU_SDIO4, sdio4); 394 - PERI_CLK_SETUP(clks, ccu, BCM281XX_MASTER_CCU_USB_IC, usb_ic); 395 - PERI_CLK_SETUP(clks, ccu, BCM281XX_MASTER_CCU_HSIC2_48M, hsic2_48m); 396 - PERI_CLK_SETUP(clks, ccu, BCM281XX_MASTER_CCU_HSIC2_12M, hsic2_12m); 397 - 398 - return 0; 399 - } 400 - 401 - static int __init bcm281xx_slave_ccu_clks_setup(struct ccu_data *ccu) 402 - { 403 - struct clk **clks; 404 - size_t count = BCM281XX_SLAVE_CCU_CLOCK_COUNT; 405 - 406 - clks = kzalloc(count * sizeof(*clks), GFP_KERNEL); 407 - if (!clks) { 408 - pr_err("%s: failed to allocate slave clocks\n", __func__); 409 - return -ENOMEM; 410 - } 411 - ccu->data.clks = clks; 412 - ccu->data.clk_num = count; 413 - 414 - PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_UARTB, uartb); 415 - PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_UARTB2, uartb2); 416 - PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_UARTB3, uartb3); 417 - PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_UARTB4, uartb4); 418 - PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_SSP0, ssp0); 419 - PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_SSP2, ssp2); 420 - PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_BSC1, bsc1); 421 - PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_BSC2, bsc2); 422 - PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_BSC3, bsc3); 423 - PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_PWM, pwm); 424 - 425 - return 0; 426 - } 264 + static struct ccu_data slave_ccu_data = { 265 + BCM281XX_CCU_COMMON(slave, SLAVE), 266 + .kona_clks = { 267 + [BCM281XX_SLAVE_CCU_UARTB] = 268 + KONA_CLK(slave, uartb, peri), 269 + [BCM281XX_SLAVE_CCU_UARTB2] = 270 + KONA_CLK(slave, uartb2, peri), 271 + [BCM281XX_SLAVE_CCU_UARTB3] = 272 + KONA_CLK(slave, uartb3, peri), 273 + [BCM281XX_SLAVE_CCU_UARTB4] = 274 + KONA_CLK(slave, uartb4, peri), 275 + [BCM281XX_SLAVE_CCU_SSP0] = 276 + KONA_CLK(slave, ssp0, peri), 277 + [BCM281XX_SLAVE_CCU_SSP2] = 278 + KONA_CLK(slave, ssp2, peri), 279 + [BCM281XX_SLAVE_CCU_BSC1] = 280 + KONA_CLK(slave, bsc1, peri), 281 + [BCM281XX_SLAVE_CCU_BSC2] = 282 + KONA_CLK(slave, bsc2, peri), 283 + [BCM281XX_SLAVE_CCU_BSC3] = 284 + KONA_CLK(slave, bsc3, peri), 285 + [BCM281XX_SLAVE_CCU_PWM] = 286 + KONA_CLK(slave, pwm, peri), 287 + [BCM281XX_SLAVE_CCU_CLOCK_COUNT] = LAST_KONA_CLK, 288 + }, 289 + }; 427 290 428 291 /* Device tree match table callback functions */ 429 292 430 293 static void __init kona_dt_root_ccu_setup(struct device_node *node) 431 294 { 432 - kona_dt_ccu_setup(node, bcm281xx_root_ccu_clks_setup); 295 + kona_dt_ccu_setup(&root_ccu_data, node); 433 296 } 434 297 435 298 static void __init kona_dt_aon_ccu_setup(struct device_node *node) 436 299 { 437 - kona_dt_ccu_setup(node, bcm281xx_aon_ccu_clks_setup); 300 + kona_dt_ccu_setup(&aon_ccu_data, node); 438 301 } 439 302 440 303 static void __init kona_dt_hub_ccu_setup(struct device_node *node) 441 304 { 442 - kona_dt_ccu_setup(node, bcm281xx_hub_ccu_clks_setup); 305 + kona_dt_ccu_setup(&hub_ccu_data, node); 443 306 } 444 307 445 308 static void __init kona_dt_master_ccu_setup(struct device_node *node) 446 309 { 447 - kona_dt_ccu_setup(node, bcm281xx_master_ccu_clks_setup); 310 + kona_dt_ccu_setup(&master_ccu_data, node); 448 311 } 449 312 450 313 static void __init kona_dt_slave_ccu_setup(struct device_node *node) 451 314 { 452 - kona_dt_ccu_setup(node, bcm281xx_slave_ccu_clks_setup); 315 + kona_dt_ccu_setup(&slave_ccu_data, node); 453 316 } 454 317 455 - CLK_OF_DECLARE(bcm11351_root_ccu, BCM11351_DT_ROOT_CCU_COMPAT, 318 + CLK_OF_DECLARE(bcm281xx_root_ccu, BCM281XX_DT_ROOT_CCU_COMPAT, 456 319 kona_dt_root_ccu_setup); 457 - CLK_OF_DECLARE(bcm11351_aon_ccu, BCM11351_DT_AON_CCU_COMPAT, 320 + CLK_OF_DECLARE(bcm281xx_aon_ccu, BCM281XX_DT_AON_CCU_COMPAT, 458 321 kona_dt_aon_ccu_setup); 459 - CLK_OF_DECLARE(bcm11351_hub_ccu, BCM11351_DT_HUB_CCU_COMPAT, 322 + CLK_OF_DECLARE(bcm281xx_hub_ccu, BCM281XX_DT_HUB_CCU_COMPAT, 460 323 kona_dt_hub_ccu_setup); 461 - CLK_OF_DECLARE(bcm11351_master_ccu, BCM11351_DT_MASTER_CCU_COMPAT, 324 + CLK_OF_DECLARE(bcm281xx_master_ccu, BCM281XX_DT_MASTER_CCU_COMPAT, 462 325 kona_dt_master_ccu_setup); 463 - CLK_OF_DECLARE(bcm11351_slave_ccu, BCM11351_DT_SLAVE_CCU_COMPAT, 326 + CLK_OF_DECLARE(bcm281xx_slave_ccu, BCM281XX_DT_SLAVE_CCU_COMPAT, 464 327 kona_dt_slave_ccu_setup);
+168 -61
drivers/clk/bcm/clk-kona-setup.c
··· 25 25 26 26 /* Validity checking */ 27 27 28 + static bool ccu_data_offsets_valid(struct ccu_data *ccu) 29 + { 30 + struct ccu_policy *ccu_policy = &ccu->policy; 31 + u32 limit; 32 + 33 + limit = ccu->range - sizeof(u32); 34 + limit = round_down(limit, sizeof(u32)); 35 + if (ccu_policy_exists(ccu_policy)) { 36 + if (ccu_policy->enable.offset > limit) { 37 + pr_err("%s: bad policy enable offset for %s " 38 + "(%u > %u)\n", __func__, 39 + ccu->name, ccu_policy->enable.offset, limit); 40 + return false; 41 + } 42 + if (ccu_policy->control.offset > limit) { 43 + pr_err("%s: bad policy control offset for %s " 44 + "(%u > %u)\n", __func__, 45 + ccu->name, ccu_policy->control.offset, limit); 46 + return false; 47 + } 48 + } 49 + 50 + return true; 51 + } 52 + 28 53 static bool clk_requires_trigger(struct kona_clk *bcm_clk) 29 54 { 30 55 struct peri_clk_data *peri = bcm_clk->u.peri; ··· 79 54 static bool peri_clk_data_offsets_valid(struct kona_clk *bcm_clk) 80 55 { 81 56 struct peri_clk_data *peri; 57 + struct bcm_clk_policy *policy; 82 58 struct bcm_clk_gate *gate; 59 + struct bcm_clk_hyst *hyst; 83 60 struct bcm_clk_div *div; 84 61 struct bcm_clk_sel *sel; 85 62 struct bcm_clk_trig *trig; ··· 91 64 92 65 BUG_ON(bcm_clk->type != bcm_clk_peri); 93 66 peri = bcm_clk->u.peri; 94 - name = bcm_clk->name; 67 + name = bcm_clk->init_data.name; 95 68 range = bcm_clk->ccu->range; 96 69 97 70 limit = range - sizeof(u32); 98 71 limit = round_down(limit, sizeof(u32)); 99 72 73 + policy = &peri->policy; 74 + if (policy_exists(policy)) { 75 + if (policy->offset > limit) { 76 + pr_err("%s: bad policy offset for %s (%u > %u)\n", 77 + __func__, name, policy->offset, limit); 78 + return false; 79 + } 80 + } 81 + 100 82 gate = &peri->gate; 83 + hyst = &peri->hyst; 101 84 if (gate_exists(gate)) { 102 85 if (gate->offset > limit) { 103 86 pr_err("%s: bad gate offset for %s (%u > %u)\n", 104 87 __func__, name, gate->offset, limit); 105 88 return false; 106 89 } 90 + 91 + if (hyst_exists(hyst)) { 92 + if (hyst->offset > limit) { 93 + pr_err("%s: bad hysteresis offset for %s " 94 + "(%u > %u)\n", __func__, 95 + name, hyst->offset, limit); 96 + return false; 97 + } 98 + } 99 + } else if (hyst_exists(hyst)) { 100 + pr_err("%s: hysteresis but no gate for %s\n", __func__, name); 101 + return false; 107 102 } 108 103 109 104 div = &peri->div; ··· 216 167 return true; 217 168 } 218 169 170 + static bool 171 + ccu_policy_valid(struct ccu_policy *ccu_policy, const char *ccu_name) 172 + { 173 + struct bcm_lvm_en *enable = &ccu_policy->enable; 174 + struct bcm_policy_ctl *control; 175 + 176 + if (!bit_posn_valid(enable->bit, "policy enable", ccu_name)) 177 + return false; 178 + 179 + control = &ccu_policy->control; 180 + if (!bit_posn_valid(control->go_bit, "policy control GO", ccu_name)) 181 + return false; 182 + 183 + if (!bit_posn_valid(control->atl_bit, "policy control ATL", ccu_name)) 184 + return false; 185 + 186 + if (!bit_posn_valid(control->ac_bit, "policy control AC", ccu_name)) 187 + return false; 188 + 189 + return true; 190 + } 191 + 192 + static bool policy_valid(struct bcm_clk_policy *policy, const char *clock_name) 193 + { 194 + if (!bit_posn_valid(policy->bit, "policy", clock_name)) 195 + return false; 196 + 197 + return true; 198 + } 199 + 219 200 /* 220 201 * All gates, if defined, have a status bit, and for hardware-only 221 202 * gates, that's it. Gates that can be software controlled also ··· 271 192 } else { 272 193 BUG_ON(!gate_is_hw_controllable(gate)); 273 194 } 195 + 196 + return true; 197 + } 198 + 199 + static bool hyst_valid(struct bcm_clk_hyst *hyst, const char *clock_name) 200 + { 201 + if (!bit_posn_valid(hyst->en_bit, "hysteresis enable", clock_name)) 202 + return false; 203 + 204 + if (!bit_posn_valid(hyst->val_bit, "hysteresis value", clock_name)) 205 + return false; 274 206 275 207 return true; 276 208 } ··· 402 312 peri_clk_data_valid(struct kona_clk *bcm_clk) 403 313 { 404 314 struct peri_clk_data *peri; 315 + struct bcm_clk_policy *policy; 405 316 struct bcm_clk_gate *gate; 317 + struct bcm_clk_hyst *hyst; 406 318 struct bcm_clk_sel *sel; 407 319 struct bcm_clk_div *div; 408 320 struct bcm_clk_div *pre_div; ··· 422 330 return false; 423 331 424 332 peri = bcm_clk->u.peri; 425 - name = bcm_clk->name; 333 + name = bcm_clk->init_data.name; 334 + 335 + policy = &peri->policy; 336 + if (policy_exists(policy) && !policy_valid(policy, name)) 337 + return false; 338 + 426 339 gate = &peri->gate; 427 340 if (gate_exists(gate) && !gate_valid(gate, "gate", name)) 341 + return false; 342 + 343 + hyst = &peri->hyst; 344 + if (hyst_exists(hyst) && !hyst_valid(hyst, name)) 428 345 return false; 429 346 430 347 sel = &peri->sel; ··· 668 567 struct clk_init_data *init_data) 669 568 { 670 569 clk_sel_teardown(&data->sel, init_data); 671 - init_data->ops = NULL; 672 570 } 673 571 674 572 /* ··· 676 576 * that can be assigned if the clock has one or more parent clocks 677 577 * associated with it. 678 578 */ 679 - static int peri_clk_setup(struct ccu_data *ccu, struct peri_clk_data *data, 680 - struct clk_init_data *init_data) 579 + static int 580 + peri_clk_setup(struct peri_clk_data *data, struct clk_init_data *init_data) 681 581 { 682 - init_data->ops = &kona_peri_clk_ops; 683 582 init_data->flags = CLK_IGNORE_UNUSED; 684 583 685 584 return clk_sel_setup(data->clocks, &data->sel, init_data); ··· 716 617 bcm_clk_teardown(bcm_clk); 717 618 } 718 619 719 - struct clk *kona_clk_setup(struct ccu_data *ccu, const char *name, 720 - enum bcm_clk_type type, void *data) 620 + struct clk *kona_clk_setup(struct kona_clk *bcm_clk) 721 621 { 722 - struct kona_clk *bcm_clk; 723 - struct clk_init_data *init_data; 622 + struct clk_init_data *init_data = &bcm_clk->init_data; 724 623 struct clk *clk = NULL; 725 624 726 - bcm_clk = kzalloc(sizeof(*bcm_clk), GFP_KERNEL); 727 - if (!bcm_clk) { 728 - pr_err("%s: failed to allocate bcm_clk for %s\n", __func__, 729 - name); 730 - return NULL; 731 - } 732 - bcm_clk->ccu = ccu; 733 - bcm_clk->name = name; 734 - 735 - init_data = &bcm_clk->init_data; 736 - init_data->name = name; 737 - switch (type) { 625 + switch (bcm_clk->type) { 738 626 case bcm_clk_peri: 739 - if (peri_clk_setup(ccu, data, init_data)) 740 - goto out_free; 627 + if (peri_clk_setup(bcm_clk->u.data, init_data)) 628 + return NULL; 741 629 break; 742 630 default: 743 - data = NULL; 744 - break; 631 + pr_err("%s: clock type %d invalid for %s\n", __func__, 632 + (int)bcm_clk->type, init_data->name); 633 + return NULL; 745 634 } 746 - bcm_clk->type = type; 747 - bcm_clk->u.data = data; 748 635 749 636 /* Make sure everything makes sense before we set it up */ 750 637 if (!kona_clk_valid(bcm_clk)) { 751 - pr_err("%s: clock data invalid for %s\n", __func__, name); 638 + pr_err("%s: clock data invalid for %s\n", __func__, 639 + init_data->name); 752 640 goto out_teardown; 753 641 } 754 642 ··· 743 657 clk = clk_register(NULL, &bcm_clk->hw); 744 658 if (IS_ERR(clk)) { 745 659 pr_err("%s: error registering clock %s (%ld)\n", __func__, 746 - name, PTR_ERR(clk)); 660 + init_data->name, PTR_ERR(clk)); 747 661 goto out_teardown; 748 662 } 749 663 BUG_ON(!clk); ··· 751 665 return clk; 752 666 out_teardown: 753 667 bcm_clk_teardown(bcm_clk); 754 - out_free: 755 - kfree(bcm_clk); 756 668 757 669 return NULL; 758 670 } ··· 759 675 { 760 676 u32 i; 761 677 762 - for (i = 0; i < ccu->data.clk_num; i++) 763 - kona_clk_teardown(ccu->data.clks[i]); 764 - kfree(ccu->data.clks); 678 + for (i = 0; i < ccu->clk_data.clk_num; i++) 679 + kona_clk_teardown(ccu->clk_data.clks[i]); 680 + kfree(ccu->clk_data.clks); 765 681 } 766 682 767 683 static void kona_ccu_teardown(struct ccu_data *ccu) 768 684 { 769 - if (!ccu) 770 - return; 771 - 685 + kfree(ccu->clk_data.clks); 686 + ccu->clk_data.clks = NULL; 772 687 if (!ccu->base) 773 - goto done; 688 + return; 774 689 775 690 of_clk_del_provider(ccu->node); /* safe if never added */ 776 691 ccu_clks_teardown(ccu); 777 692 list_del(&ccu->links); 778 693 of_node_put(ccu->node); 694 + ccu->node = NULL; 779 695 iounmap(ccu->base); 780 - done: 781 - kfree(ccu->name); 782 - kfree(ccu); 696 + ccu->base = NULL; 697 + } 698 + 699 + static bool ccu_data_valid(struct ccu_data *ccu) 700 + { 701 + struct ccu_policy *ccu_policy; 702 + 703 + if (!ccu_data_offsets_valid(ccu)) 704 + return false; 705 + 706 + ccu_policy = &ccu->policy; 707 + if (ccu_policy_exists(ccu_policy)) 708 + if (!ccu_policy_valid(ccu_policy, ccu->name)) 709 + return false; 710 + 711 + return true; 783 712 } 784 713 785 714 /* 786 715 * Set up a CCU. Call the provided ccu_clks_setup callback to 787 716 * initialize the array of clocks provided by the CCU. 788 717 */ 789 - void __init kona_dt_ccu_setup(struct device_node *node, 790 - int (*ccu_clks_setup)(struct ccu_data *)) 718 + void __init kona_dt_ccu_setup(struct ccu_data *ccu, 719 + struct device_node *node) 791 720 { 792 - struct ccu_data *ccu; 793 721 struct resource res = { 0 }; 794 722 resource_size_t range; 723 + unsigned int i; 795 724 int ret; 796 725 797 - ccu = kzalloc(sizeof(*ccu), GFP_KERNEL); 798 - if (ccu) 799 - ccu->name = kstrdup(node->name, GFP_KERNEL); 800 - if (!ccu || !ccu->name) { 801 - pr_err("%s: unable to allocate CCU struct for %s\n", 802 - __func__, node->name); 803 - kfree(ccu); 726 + if (ccu->clk_data.clk_num) { 727 + size_t size; 804 728 805 - return; 729 + size = ccu->clk_data.clk_num * sizeof(*ccu->clk_data.clks); 730 + ccu->clk_data.clks = kzalloc(size, GFP_KERNEL); 731 + if (!ccu->clk_data.clks) { 732 + pr_err("%s: unable to allocate %u clocks for %s\n", 733 + __func__, ccu->clk_data.clk_num, node->name); 734 + return; 735 + } 806 736 } 807 737 808 738 ret = of_address_to_resource(node, 0, &res); ··· 834 736 } 835 737 836 738 ccu->range = (u32)range; 739 + 740 + if (!ccu_data_valid(ccu)) { 741 + pr_err("%s: ccu data not valid for %s\n", __func__, node->name); 742 + goto out_err; 743 + } 744 + 837 745 ccu->base = ioremap(res.start, ccu->range); 838 746 if (!ccu->base) { 839 747 pr_err("%s: unable to map CCU registers for %s\n", __func__, 840 748 node->name); 841 749 goto out_err; 842 750 } 843 - 844 - spin_lock_init(&ccu->lock); 845 - INIT_LIST_HEAD(&ccu->links); 846 751 ccu->node = of_node_get(node); 847 - 848 752 list_add_tail(&ccu->links, &ccu_list); 849 753 850 - /* Set up clocks array (in ccu->data) */ 851 - if (ccu_clks_setup(ccu)) 852 - goto out_err; 754 + /* 755 + * Set up each defined kona clock and save the result in 756 + * the clock framework clock array (in ccu->data). Then 757 + * register as a provider for these clocks. 758 + */ 759 + for (i = 0; i < ccu->clk_data.clk_num; i++) { 760 + if (!ccu->kona_clks[i].ccu) 761 + continue; 762 + ccu->clk_data.clks[i] = kona_clk_setup(&ccu->kona_clks[i]); 763 + } 853 764 854 - ret = of_clk_add_provider(node, of_clk_src_onecell_get, &ccu->data); 765 + ret = of_clk_add_provider(node, of_clk_src_onecell_get, &ccu->clk_data); 855 766 if (ret) { 856 767 pr_err("%s: error adding ccu %s as provider (%d)\n", __func__, 857 768 node->name, ret);
+256 -10
drivers/clk/bcm/clk-kona.c
··· 16 16 17 17 #include <linux/delay.h> 18 18 19 + /* 20 + * "Policies" affect the frequencies of bus clocks provided by a 21 + * CCU. (I believe these polices are named "Deep Sleep", "Economy", 22 + * "Normal", and "Turbo".) A lower policy number has lower power 23 + * consumption, and policy 2 is the default. 24 + */ 25 + #define CCU_POLICY_COUNT 4 26 + 19 27 #define CCU_ACCESS_PASSWORD 0xA5A500 20 28 #define CLK_GATE_DELAY_LOOP 2000 21 29 ··· 215 207 return true; 216 208 udelay(1); 217 209 } 210 + pr_warn("%s: %s/0x%04x bit %u was never %s\n", __func__, 211 + ccu->name, reg_offset, bit, want ? "set" : "clear"); 212 + 218 213 return false; 214 + } 215 + 216 + /* Policy operations */ 217 + 218 + static bool __ccu_policy_engine_start(struct ccu_data *ccu, bool sync) 219 + { 220 + struct bcm_policy_ctl *control = &ccu->policy.control; 221 + u32 offset; 222 + u32 go_bit; 223 + u32 mask; 224 + bool ret; 225 + 226 + /* If we don't need to control policy for this CCU, we're done. */ 227 + if (!policy_ctl_exists(control)) 228 + return true; 229 + 230 + offset = control->offset; 231 + go_bit = control->go_bit; 232 + 233 + /* Ensure we're not busy before we start */ 234 + ret = __ccu_wait_bit(ccu, offset, go_bit, false); 235 + if (!ret) { 236 + pr_err("%s: ccu %s policy engine wouldn't go idle\n", 237 + __func__, ccu->name); 238 + return false; 239 + } 240 + 241 + /* 242 + * If it's a synchronous request, we'll wait for the voltage 243 + * and frequency of the active load to stabilize before 244 + * returning. To do this we select the active load by 245 + * setting the ATL bit. 246 + * 247 + * An asynchronous request instead ramps the voltage in the 248 + * background, and when that process stabilizes, the target 249 + * load is copied to the active load and the CCU frequency 250 + * is switched. We do this by selecting the target load 251 + * (ATL bit clear) and setting the request auto-copy (AC bit 252 + * set). 253 + * 254 + * Note, we do NOT read-modify-write this register. 255 + */ 256 + mask = (u32)1 << go_bit; 257 + if (sync) 258 + mask |= 1 << control->atl_bit; 259 + else 260 + mask |= 1 << control->ac_bit; 261 + __ccu_write(ccu, offset, mask); 262 + 263 + /* Wait for indication that operation is complete. */ 264 + ret = __ccu_wait_bit(ccu, offset, go_bit, false); 265 + if (!ret) 266 + pr_err("%s: ccu %s policy engine never started\n", 267 + __func__, ccu->name); 268 + 269 + return ret; 270 + } 271 + 272 + static bool __ccu_policy_engine_stop(struct ccu_data *ccu) 273 + { 274 + struct bcm_lvm_en *enable = &ccu->policy.enable; 275 + u32 offset; 276 + u32 enable_bit; 277 + bool ret; 278 + 279 + /* If we don't need to control policy for this CCU, we're done. */ 280 + if (!policy_lvm_en_exists(enable)) 281 + return true; 282 + 283 + /* Ensure we're not busy before we start */ 284 + offset = enable->offset; 285 + enable_bit = enable->bit; 286 + ret = __ccu_wait_bit(ccu, offset, enable_bit, false); 287 + if (!ret) { 288 + pr_err("%s: ccu %s policy engine already stopped\n", 289 + __func__, ccu->name); 290 + return false; 291 + } 292 + 293 + /* Now set the bit to stop the engine (NO read-modify-write) */ 294 + __ccu_write(ccu, offset, (u32)1 << enable_bit); 295 + 296 + /* Wait for indication that it has stopped. */ 297 + ret = __ccu_wait_bit(ccu, offset, enable_bit, false); 298 + if (!ret) 299 + pr_err("%s: ccu %s policy engine never stopped\n", 300 + __func__, ccu->name); 301 + 302 + return ret; 303 + } 304 + 305 + /* 306 + * A CCU has four operating conditions ("policies"), and some clocks 307 + * can be disabled or enabled based on which policy is currently in 308 + * effect. Such clocks have a bit in a "policy mask" register for 309 + * each policy indicating whether the clock is enabled for that 310 + * policy or not. The bit position for a clock is the same for all 311 + * four registers, and the 32-bit registers are at consecutive 312 + * addresses. 313 + */ 314 + static bool policy_init(struct ccu_data *ccu, struct bcm_clk_policy *policy) 315 + { 316 + u32 offset; 317 + u32 mask; 318 + int i; 319 + bool ret; 320 + 321 + if (!policy_exists(policy)) 322 + return true; 323 + 324 + /* 325 + * We need to stop the CCU policy engine to allow update 326 + * of our policy bits. 327 + */ 328 + if (!__ccu_policy_engine_stop(ccu)) { 329 + pr_err("%s: unable to stop CCU %s policy engine\n", 330 + __func__, ccu->name); 331 + return false; 332 + } 333 + 334 + /* 335 + * For now, if a clock defines its policy bit we just mark 336 + * it "enabled" for all four policies. 337 + */ 338 + offset = policy->offset; 339 + mask = (u32)1 << policy->bit; 340 + for (i = 0; i < CCU_POLICY_COUNT; i++) { 341 + u32 reg_val; 342 + 343 + reg_val = __ccu_read(ccu, offset); 344 + reg_val |= mask; 345 + __ccu_write(ccu, offset, reg_val); 346 + offset += sizeof(u32); 347 + } 348 + 349 + /* We're done updating; fire up the policy engine again. */ 350 + ret = __ccu_policy_engine_start(ccu, true); 351 + if (!ret) 352 + pr_err("%s: unable to restart CCU %s policy engine\n", 353 + __func__, ccu->name); 354 + 355 + return ret; 219 356 } 220 357 221 358 /* Gate operations */ ··· 525 372 enable ? "enable" : "disable", name); 526 373 527 374 return -EIO; 375 + } 376 + 377 + /* Hysteresis operations */ 378 + 379 + /* 380 + * If a clock gate requires a turn-off delay it will have 381 + * "hysteresis" register bits defined. The first, if set, enables 382 + * the delay; and if enabled, the second bit determines whether the 383 + * delay is "low" or "high" (1 means high). For now, if it's 384 + * defined for a clock, we set it. 385 + */ 386 + static bool hyst_init(struct ccu_data *ccu, struct bcm_clk_hyst *hyst) 387 + { 388 + u32 offset; 389 + u32 reg_val; 390 + u32 mask; 391 + 392 + if (!hyst_exists(hyst)) 393 + return true; 394 + 395 + offset = hyst->offset; 396 + mask = (u32)1 << hyst->en_bit; 397 + mask |= (u32)1 << hyst->val_bit; 398 + 399 + reg_val = __ccu_read(ccu, offset); 400 + reg_val |= mask; 401 + __ccu_write(ccu, offset, reg_val); 402 + 403 + return true; 528 404 } 529 405 530 406 /* Trigger operations */ ··· 988 806 struct kona_clk *bcm_clk = to_kona_clk(hw); 989 807 struct bcm_clk_gate *gate = &bcm_clk->u.peri->gate; 990 808 991 - return clk_gate(bcm_clk->ccu, bcm_clk->name, gate, true); 809 + return clk_gate(bcm_clk->ccu, bcm_clk->init_data.name, gate, true); 992 810 } 993 811 994 812 static void kona_peri_clk_disable(struct clk_hw *hw) ··· 996 814 struct kona_clk *bcm_clk = to_kona_clk(hw); 997 815 struct bcm_clk_gate *gate = &bcm_clk->u.peri->gate; 998 816 999 - (void)clk_gate(bcm_clk->ccu, bcm_clk->name, gate, false); 817 + (void)clk_gate(bcm_clk->ccu, bcm_clk->init_data.name, gate, false); 1000 818 } 1001 819 1002 820 static int kona_peri_clk_is_enabled(struct clk_hw *hw) ··· 1031 849 rate ? rate : 1, *parent_rate, NULL); 1032 850 } 1033 851 852 + static long kona_peri_clk_determine_rate(struct clk_hw *hw, unsigned long rate, 853 + unsigned long *best_parent_rate, struct clk **best_parent) 854 + { 855 + struct kona_clk *bcm_clk = to_kona_clk(hw); 856 + struct clk *clk = hw->clk; 857 + struct clk *current_parent; 858 + unsigned long parent_rate; 859 + unsigned long best_delta; 860 + unsigned long best_rate; 861 + u32 parent_count; 862 + u32 which; 863 + 864 + /* 865 + * If there is no other parent to choose, use the current one. 866 + * Note: We don't honor (or use) CLK_SET_RATE_NO_REPARENT. 867 + */ 868 + WARN_ON_ONCE(bcm_clk->init_data.flags & CLK_SET_RATE_NO_REPARENT); 869 + parent_count = (u32)bcm_clk->init_data.num_parents; 870 + if (parent_count < 2) 871 + return kona_peri_clk_round_rate(hw, rate, best_parent_rate); 872 + 873 + /* Unless we can do better, stick with current parent */ 874 + current_parent = clk_get_parent(clk); 875 + parent_rate = __clk_get_rate(current_parent); 876 + best_rate = kona_peri_clk_round_rate(hw, rate, &parent_rate); 877 + best_delta = abs(best_rate - rate); 878 + 879 + /* Check whether any other parent clock can produce a better result */ 880 + for (which = 0; which < parent_count; which++) { 881 + struct clk *parent = clk_get_parent_by_index(clk, which); 882 + unsigned long delta; 883 + unsigned long other_rate; 884 + 885 + BUG_ON(!parent); 886 + if (parent == current_parent) 887 + continue; 888 + 889 + /* We don't support CLK_SET_RATE_PARENT */ 890 + parent_rate = __clk_get_rate(parent); 891 + other_rate = kona_peri_clk_round_rate(hw, rate, &parent_rate); 892 + delta = abs(other_rate - rate); 893 + if (delta < best_delta) { 894 + best_delta = delta; 895 + best_rate = other_rate; 896 + *best_parent = parent; 897 + *best_parent_rate = parent_rate; 898 + } 899 + } 900 + 901 + return best_rate; 902 + } 903 + 1034 904 static int kona_peri_clk_set_parent(struct clk_hw *hw, u8 index) 1035 905 { 1036 906 struct kona_clk *bcm_clk = to_kona_clk(hw); ··· 1106 872 1107 873 ret = selector_write(bcm_clk->ccu, &data->gate, sel, trig, index); 1108 874 if (ret == -ENXIO) { 1109 - pr_err("%s: gating failure for %s\n", __func__, bcm_clk->name); 875 + pr_err("%s: gating failure for %s\n", __func__, 876 + bcm_clk->init_data.name); 1110 877 ret = -EIO; /* Don't proliferate weird errors */ 1111 878 } else if (ret == -EIO) { 1112 879 pr_err("%s: %strigger failed for %s\n", __func__, 1113 880 trig == &data->pre_trig ? "pre-" : "", 1114 - bcm_clk->name); 881 + bcm_clk->init_data.name); 1115 882 } 1116 883 1117 884 return ret; ··· 1171 936 ret = divider_write(bcm_clk->ccu, &data->gate, &data->div, 1172 937 &data->trig, scaled_div); 1173 938 if (ret == -ENXIO) { 1174 - pr_err("%s: gating failure for %s\n", __func__, bcm_clk->name); 939 + pr_err("%s: gating failure for %s\n", __func__, 940 + bcm_clk->init_data.name); 1175 941 ret = -EIO; /* Don't proliferate weird errors */ 1176 942 } else if (ret == -EIO) { 1177 - pr_err("%s: trigger failed for %s\n", __func__, bcm_clk->name); 943 + pr_err("%s: trigger failed for %s\n", __func__, 944 + bcm_clk->init_data.name); 1178 945 } 1179 946 1180 947 return ret; ··· 1187 950 .disable = kona_peri_clk_disable, 1188 951 .is_enabled = kona_peri_clk_is_enabled, 1189 952 .recalc_rate = kona_peri_clk_recalc_rate, 1190 - .round_rate = kona_peri_clk_round_rate, 953 + .determine_rate = kona_peri_clk_determine_rate, 1191 954 .set_parent = kona_peri_clk_set_parent, 1192 955 .get_parent = kona_peri_clk_get_parent, 1193 956 .set_rate = kona_peri_clk_set_rate, ··· 1198 961 { 1199 962 struct ccu_data *ccu = bcm_clk->ccu; 1200 963 struct peri_clk_data *peri = bcm_clk->u.peri; 1201 - const char *name = bcm_clk->name; 964 + const char *name = bcm_clk->init_data.name; 1202 965 struct bcm_clk_trig *trig; 1203 966 1204 967 BUG_ON(bcm_clk->type != bcm_clk_peri); 1205 968 969 + if (!policy_init(ccu, &peri->policy)) { 970 + pr_err("%s: error initializing policy for %s\n", 971 + __func__, name); 972 + return false; 973 + } 1206 974 if (!gate_init(ccu, &peri->gate)) { 1207 975 pr_err("%s: error initializing gate for %s\n", __func__, name); 976 + return false; 977 + } 978 + if (!hyst_init(ccu, &peri->hyst)) { 979 + pr_err("%s: error initializing hyst for %s\n", __func__, name); 1208 980 return false; 1209 981 } 1210 982 if (!div_init(ccu, &peri->gate, &peri->div, &peri->trig)) { ··· 1260 1014 { 1261 1015 unsigned long flags; 1262 1016 unsigned int which; 1263 - struct clk **clks = ccu->data.clks; 1017 + struct clk **clks = ccu->clk_data.clks; 1264 1018 bool success = true; 1265 1019 1266 1020 flags = ccu_lock(ccu); 1267 1021 __ccu_write_enable(ccu); 1268 1022 1269 - for (which = 0; which < ccu->data.clk_num; which++) { 1023 + for (which = 0; which < ccu->clk_data.clk_num; which++) { 1270 1024 struct kona_clk *bcm_clk; 1271 1025 1272 1026 if (!clks[which])
+133 -27
drivers/clk/bcm/clk-kona.h
··· 43 43 #define FLAG_FLIP(obj, type, flag) ((obj)->flags ^= FLAG(type, flag)) 44 44 #define FLAG_TEST(obj, type, flag) (!!((obj)->flags & FLAG(type, flag))) 45 45 46 + /* CCU field state tests */ 47 + 48 + #define ccu_policy_exists(ccu_policy) ((ccu_policy)->enable.offset != 0) 49 + 46 50 /* Clock field state tests */ 51 + 52 + #define policy_exists(policy) ((policy)->offset != 0) 47 53 48 54 #define gate_exists(gate) FLAG_TEST(gate, GATE, EXISTS) 49 55 #define gate_is_enabled(gate) FLAG_TEST(gate, GATE, ENABLED) ··· 60 54 61 55 #define gate_flip_enabled(gate) FLAG_FLIP(gate, GATE, ENABLED) 62 56 57 + #define hyst_exists(hyst) ((hyst)->offset != 0) 58 + 63 59 #define divider_exists(div) FLAG_TEST(div, DIV, EXISTS) 64 60 #define divider_is_fixed(div) FLAG_TEST(div, DIV, FIXED) 65 61 #define divider_has_fraction(div) (!divider_is_fixed(div) && \ ··· 69 61 70 62 #define selector_exists(sel) ((sel)->width != 0) 71 63 #define trigger_exists(trig) FLAG_TEST(trig, TRIG, EXISTS) 64 + 65 + #define policy_lvm_en_exists(enable) ((enable)->offset != 0) 66 + #define policy_ctl_exists(control) ((control)->offset != 0) 72 67 73 68 /* Clock type, used to tell common block what it's part of */ 74 69 enum bcm_clk_type { ··· 82 71 }; 83 72 84 73 /* 85 - * Each CCU defines a mapped area of memory containing registers 86 - * used to manage clocks implemented by the CCU. Access to memory 87 - * within the CCU's space is serialized by a spinlock. Before any 88 - * (other) address can be written, a special access "password" value 89 - * must be written to its WR_ACCESS register (located at the base 90 - * address of the range). We keep track of the name of each CCU as 91 - * it is set up, and maintain them in a list. 74 + * CCU policy control for clocks. Clocks can be enabled or disabled 75 + * based on the CCU policy in effect. One bit in each policy mask 76 + * register (one per CCU policy) represents whether the clock is 77 + * enabled when that policy is effect or not. The CCU policy engine 78 + * must be stopped to update these bits, and must be restarted again 79 + * afterward. 92 80 */ 93 - struct ccu_data { 94 - void __iomem *base; /* base of mapped address space */ 95 - spinlock_t lock; /* serialization lock */ 96 - bool write_enabled; /* write access is currently enabled */ 97 - struct list_head links; /* for ccu_list */ 98 - struct device_node *node; 99 - struct clk_onecell_data data; 100 - const char *name; 101 - u32 range; /* byte range of address space */ 81 + struct bcm_clk_policy { 82 + u32 offset; /* first policy mask register offset */ 83 + u32 bit; /* bit used in all mask registers */ 102 84 }; 85 + 86 + /* Policy initialization macro */ 87 + 88 + #define POLICY(_offset, _bit) \ 89 + { \ 90 + .offset = (_offset), \ 91 + .bit = (_bit), \ 92 + } 103 93 104 94 /* 105 95 * Gating control and status is managed by a 32-bit gate register. ··· 205 193 .offset = (_offset), \ 206 194 .status_bit = (_status_bit), \ 207 195 .flags = FLAG(GATE, HW)|FLAG(GATE, EXISTS), \ 196 + } 197 + 198 + /* Gate hysteresis for clocks */ 199 + struct bcm_clk_hyst { 200 + u32 offset; /* hyst register offset (normally CLKGATE) */ 201 + u32 en_bit; /* bit used to enable hysteresis */ 202 + u32 val_bit; /* if enabled: 0 = low delay; 1 = high delay */ 203 + }; 204 + 205 + /* Hysteresis initialization macro */ 206 + 207 + #define HYST(_offset, _en_bit, _val_bit) \ 208 + { \ 209 + .offset = (_offset), \ 210 + .en_bit = (_en_bit), \ 211 + .val_bit = (_val_bit), \ 208 212 } 209 213 210 214 /* ··· 388 360 } 389 361 390 362 struct peri_clk_data { 363 + struct bcm_clk_policy policy; 391 364 struct bcm_clk_gate gate; 365 + struct bcm_clk_hyst hyst; 392 366 struct bcm_clk_trig pre_trig; 393 367 struct bcm_clk_div pre_div; 394 368 struct bcm_clk_trig trig; ··· 403 373 404 374 struct kona_clk { 405 375 struct clk_hw hw; 406 - struct clk_init_data init_data; 407 - const char *name; /* name of this clock */ 376 + struct clk_init_data init_data; /* includes name of this clock */ 408 377 struct ccu_data *ccu; /* ccu this clock is associated with */ 409 378 enum bcm_clk_type type; 410 379 union { ··· 414 385 #define to_kona_clk(_hw) \ 415 386 container_of(_hw, struct kona_clk, hw) 416 387 388 + /* Initialization macro for an entry in a CCU's kona_clks[] array. */ 389 + #define KONA_CLK(_ccu_name, _clk_name, _type) \ 390 + { \ 391 + .init_data = { \ 392 + .name = #_clk_name, \ 393 + .ops = &kona_ ## _type ## _clk_ops, \ 394 + }, \ 395 + .ccu = &_ccu_name ## _ccu_data, \ 396 + .type = bcm_clk_ ## _type, \ 397 + .u.data = &_clk_name ## _data, \ 398 + } 399 + #define LAST_KONA_CLK { .type = bcm_clk_none } 400 + 401 + /* 402 + * CCU policy control. To enable software update of the policy 403 + * tables the CCU policy engine must be stopped by setting the 404 + * software update enable bit (LVM_EN). After an update the engine 405 + * is restarted using the GO bit and either the GO_ATL or GO_AC bit. 406 + */ 407 + struct bcm_lvm_en { 408 + u32 offset; /* LVM_EN register offset */ 409 + u32 bit; /* POLICY_CONFIG_EN bit in register */ 410 + }; 411 + 412 + /* Policy enable initialization macro */ 413 + #define CCU_LVM_EN(_offset, _bit) \ 414 + { \ 415 + .offset = (_offset), \ 416 + .bit = (_bit), \ 417 + } 418 + 419 + struct bcm_policy_ctl { 420 + u32 offset; /* POLICY_CTL register offset */ 421 + u32 go_bit; 422 + u32 atl_bit; /* GO, GO_ATL, and GO_AC bits */ 423 + u32 ac_bit; 424 + }; 425 + 426 + /* Policy control initialization macro */ 427 + #define CCU_POLICY_CTL(_offset, _go_bit, _ac_bit, _atl_bit) \ 428 + { \ 429 + .offset = (_offset), \ 430 + .go_bit = (_go_bit), \ 431 + .ac_bit = (_ac_bit), \ 432 + .atl_bit = (_atl_bit), \ 433 + } 434 + 435 + struct ccu_policy { 436 + struct bcm_lvm_en enable; 437 + struct bcm_policy_ctl control; 438 + }; 439 + 440 + /* 441 + * Each CCU defines a mapped area of memory containing registers 442 + * used to manage clocks implemented by the CCU. Access to memory 443 + * within the CCU's space is serialized by a spinlock. Before any 444 + * (other) address can be written, a special access "password" value 445 + * must be written to its WR_ACCESS register (located at the base 446 + * address of the range). We keep track of the name of each CCU as 447 + * it is set up, and maintain them in a list. 448 + */ 449 + struct ccu_data { 450 + void __iomem *base; /* base of mapped address space */ 451 + spinlock_t lock; /* serialization lock */ 452 + bool write_enabled; /* write access is currently enabled */ 453 + struct ccu_policy policy; 454 + struct list_head links; /* for ccu_list */ 455 + struct device_node *node; 456 + struct clk_onecell_data clk_data; 457 + const char *name; 458 + u32 range; /* byte range of address space */ 459 + struct kona_clk kona_clks[]; /* must be last */ 460 + }; 461 + 462 + /* Initialization for common fields in a Kona ccu_data structure */ 463 + #define KONA_CCU_COMMON(_prefix, _name, _ccuname) \ 464 + .name = #_name "_ccu", \ 465 + .lock = __SPIN_LOCK_UNLOCKED(_name ## _ccu_data.lock), \ 466 + .links = LIST_HEAD_INIT(_name ## _ccu_data.links), \ 467 + .clk_data = { \ 468 + .clk_num = _prefix ## _ ## _ccuname ## _CCU_CLOCK_COUNT, \ 469 + } 470 + 417 471 /* Exported globals */ 418 472 419 473 extern struct clk_ops kona_peri_clk_ops; 420 - 421 - /* Help functions */ 422 - 423 - #define PERI_CLK_SETUP(clks, ccu, id, name) \ 424 - clks[id] = kona_clk_setup(ccu, #name, bcm_clk_peri, &name ## _data) 425 474 426 475 /* Externally visible functions */ 427 476 ··· 508 401 extern u64 scaled_div_build(struct bcm_clk_div *div, u32 div_value, 509 402 u32 billionths); 510 403 511 - extern struct clk *kona_clk_setup(struct ccu_data *ccu, const char *name, 512 - enum bcm_clk_type type, void *data); 513 - extern void __init kona_dt_ccu_setup(struct device_node *node, 514 - int (*ccu_clks_setup)(struct ccu_data *)); 404 + extern struct clk *kona_clk_setup(struct kona_clk *bcm_clk); 405 + extern void __init kona_dt_ccu_setup(struct ccu_data *ccu, 406 + struct device_node *node); 515 407 extern bool __init kona_ccu_init(struct ccu_data *ccu); 516 408 517 409 #endif /* _CLK_KONA_H */
+4
drivers/clk/berlin/Makefile
··· 1 + obj-y += berlin2-avpll.o berlin2-pll.o berlin2-div.o 2 + obj-$(CONFIG_MACH_BERLIN_BG2) += bg2.o 3 + obj-$(CONFIG_MACH_BERLIN_BG2CD) += bg2.o 4 + obj-$(CONFIG_MACH_BERLIN_BG2Q) += bg2q.o
+393
drivers/clk/berlin/berlin2-avpll.c
··· 1 + /* 2 + * Copyright (c) 2014 Marvell Technology Group Ltd. 3 + * 4 + * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> 5 + * Alexandre Belloni <alexandre.belloni@free-electrons.com> 6 + * 7 + * This program is free software; you can redistribute it and/or modify it 8 + * under the terms and conditions of the GNU General Public License, 9 + * version 2, as published by the Free Software Foundation. 10 + * 11 + * This program is distributed in the hope it will be useful, but WITHOUT 12 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 14 + * more details. 15 + * 16 + * You should have received a copy of the GNU General Public License along with 17 + * this program. If not, see <http://www.gnu.org/licenses/>. 18 + */ 19 + #include <linux/clk-provider.h> 20 + #include <linux/io.h> 21 + #include <linux/kernel.h> 22 + #include <linux/of.h> 23 + #include <linux/of_address.h> 24 + #include <linux/slab.h> 25 + 26 + #include "berlin2-avpll.h" 27 + 28 + /* 29 + * Berlin2 SoCs comprise up to two PLLs called AVPLL built upon a 30 + * VCO with 8 channels each, channel 8 is the odd-one-out and does 31 + * not provide mul/div. 32 + * 33 + * Unfortunately, its registers are not named but just numbered. To 34 + * get in at least some kind of structure, we split each AVPLL into 35 + * the VCOs and each channel into separate clock drivers. 36 + * 37 + * Also, here and there the VCO registers are a bit different with 38 + * respect to bit shifts. Make sure to add a comment for those. 39 + */ 40 + #define NUM_CHANNELS 8 41 + 42 + #define AVPLL_CTRL(x) ((x) * 0x4) 43 + 44 + #define VCO_CTRL0 AVPLL_CTRL(0) 45 + /* BG2/BG2CDs VCO_B has an additional shift of 4 for its VCO_CTRL0 reg */ 46 + #define VCO_RESET BIT(0) 47 + #define VCO_POWERUP BIT(1) 48 + #define VCO_INTERPOL_SHIFT 2 49 + #define VCO_INTERPOL_MASK (0xf << VCO_INTERPOL_SHIFT) 50 + #define VCO_REG1V45_SEL_SHIFT 6 51 + #define VCO_REG1V45_SEL(x) ((x) << VCO_REG1V45_SEL_SHIFT) 52 + #define VCO_REG1V45_SEL_1V40 VCO_REG1V45_SEL(0) 53 + #define VCO_REG1V45_SEL_1V45 VCO_REG1V45_SEL(1) 54 + #define VCO_REG1V45_SEL_1V50 VCO_REG1V45_SEL(2) 55 + #define VCO_REG1V45_SEL_1V55 VCO_REG1V45_SEL(3) 56 + #define VCO_REG1V45_SEL_MASK VCO_REG1V45_SEL(3) 57 + #define VCO_REG0V9_SEL_SHIFT 8 58 + #define VCO_REG0V9_SEL_MASK (0xf << VCO_REG0V9_SEL_SHIFT) 59 + #define VCO_VTHCAL_SHIFT 12 60 + #define VCO_VTHCAL(x) ((x) << VCO_VTHCAL_SHIFT) 61 + #define VCO_VTHCAL_0V90 VCO_VTHCAL(0) 62 + #define VCO_VTHCAL_0V95 VCO_VTHCAL(1) 63 + #define VCO_VTHCAL_1V00 VCO_VTHCAL(2) 64 + #define VCO_VTHCAL_1V05 VCO_VTHCAL(3) 65 + #define VCO_VTHCAL_MASK VCO_VTHCAL(3) 66 + #define VCO_KVCOEXT_SHIFT 14 67 + #define VCO_KVCOEXT_MASK (0x3 << VCO_KVCOEXT_SHIFT) 68 + #define VCO_KVCOEXT_ENABLE BIT(17) 69 + #define VCO_V2IEXT_SHIFT 18 70 + #define VCO_V2IEXT_MASK (0xf << VCO_V2IEXT_SHIFT) 71 + #define VCO_V2IEXT_ENABLE BIT(22) 72 + #define VCO_SPEED_SHIFT 23 73 + #define VCO_SPEED(x) ((x) << VCO_SPEED_SHIFT) 74 + #define VCO_SPEED_1G08_1G21 VCO_SPEED(0) 75 + #define VCO_SPEED_1G21_1G40 VCO_SPEED(1) 76 + #define VCO_SPEED_1G40_1G61 VCO_SPEED(2) 77 + #define VCO_SPEED_1G61_1G86 VCO_SPEED(3) 78 + #define VCO_SPEED_1G86_2G00 VCO_SPEED(4) 79 + #define VCO_SPEED_2G00_2G22 VCO_SPEED(5) 80 + #define VCO_SPEED_2G22 VCO_SPEED(6) 81 + #define VCO_SPEED_MASK VCO_SPEED(0x7) 82 + #define VCO_CLKDET_ENABLE BIT(26) 83 + #define VCO_CTRL1 AVPLL_CTRL(1) 84 + #define VCO_REFDIV_SHIFT 0 85 + #define VCO_REFDIV(x) ((x) << VCO_REFDIV_SHIFT) 86 + #define VCO_REFDIV_1 VCO_REFDIV(0) 87 + #define VCO_REFDIV_2 VCO_REFDIV(1) 88 + #define VCO_REFDIV_4 VCO_REFDIV(2) 89 + #define VCO_REFDIV_3 VCO_REFDIV(3) 90 + #define VCO_REFDIV_MASK VCO_REFDIV(0x3f) 91 + #define VCO_FBDIV_SHIFT 6 92 + #define VCO_FBDIV(x) ((x) << VCO_FBDIV_SHIFT) 93 + #define VCO_FBDIV_MASK VCO_FBDIV(0xff) 94 + #define VCO_ICP_SHIFT 14 95 + /* PLL Charge Pump Current = 10uA * (x + 1) */ 96 + #define VCO_ICP(x) ((x) << VCO_ICP_SHIFT) 97 + #define VCO_ICP_MASK VCO_ICP(0xf) 98 + #define VCO_LOAD_CAP BIT(18) 99 + #define VCO_CALIBRATION_START BIT(19) 100 + #define VCO_FREQOFFSETn(x) AVPLL_CTRL(3 + (x)) 101 + #define VCO_FREQOFFSET_MASK 0x7ffff 102 + #define VCO_CTRL10 AVPLL_CTRL(10) 103 + #define VCO_POWERUP_CH1 BIT(20) 104 + #define VCO_CTRL11 AVPLL_CTRL(11) 105 + #define VCO_CTRL12 AVPLL_CTRL(12) 106 + #define VCO_CTRL13 AVPLL_CTRL(13) 107 + #define VCO_CTRL14 AVPLL_CTRL(14) 108 + #define VCO_CTRL15 AVPLL_CTRL(15) 109 + #define VCO_SYNC1n(x) AVPLL_CTRL(15 + (x)) 110 + #define VCO_SYNC1_MASK 0x1ffff 111 + #define VCO_SYNC2n(x) AVPLL_CTRL(23 + (x)) 112 + #define VCO_SYNC2_MASK 0x1ffff 113 + #define VCO_CTRL30 AVPLL_CTRL(30) 114 + #define VCO_DPLL_CH1_ENABLE BIT(17) 115 + 116 + struct berlin2_avpll_vco { 117 + struct clk_hw hw; 118 + void __iomem *base; 119 + u8 flags; 120 + }; 121 + 122 + #define to_avpll_vco(hw) container_of(hw, struct berlin2_avpll_vco, hw) 123 + 124 + static int berlin2_avpll_vco_is_enabled(struct clk_hw *hw) 125 + { 126 + struct berlin2_avpll_vco *vco = to_avpll_vco(hw); 127 + u32 reg; 128 + 129 + reg = readl_relaxed(vco->base + VCO_CTRL0); 130 + if (vco->flags & BERLIN2_AVPLL_BIT_QUIRK) 131 + reg >>= 4; 132 + 133 + return !!(reg & VCO_POWERUP); 134 + } 135 + 136 + static int berlin2_avpll_vco_enable(struct clk_hw *hw) 137 + { 138 + struct berlin2_avpll_vco *vco = to_avpll_vco(hw); 139 + u32 reg; 140 + 141 + reg = readl_relaxed(vco->base + VCO_CTRL0); 142 + if (vco->flags & BERLIN2_AVPLL_BIT_QUIRK) 143 + reg |= VCO_POWERUP << 4; 144 + else 145 + reg |= VCO_POWERUP; 146 + writel_relaxed(reg, vco->base + VCO_CTRL0); 147 + 148 + return 0; 149 + } 150 + 151 + static void berlin2_avpll_vco_disable(struct clk_hw *hw) 152 + { 153 + struct berlin2_avpll_vco *vco = to_avpll_vco(hw); 154 + u32 reg; 155 + 156 + reg = readl_relaxed(vco->base + VCO_CTRL0); 157 + if (vco->flags & BERLIN2_AVPLL_BIT_QUIRK) 158 + reg &= ~(VCO_POWERUP << 4); 159 + else 160 + reg &= ~VCO_POWERUP; 161 + writel_relaxed(reg, vco->base + VCO_CTRL0); 162 + } 163 + 164 + static u8 vco_refdiv[] = { 1, 2, 4, 3 }; 165 + 166 + static unsigned long 167 + berlin2_avpll_vco_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) 168 + { 169 + struct berlin2_avpll_vco *vco = to_avpll_vco(hw); 170 + u32 reg, refdiv, fbdiv; 171 + u64 freq = parent_rate; 172 + 173 + /* AVPLL VCO frequency: Fvco = (Fref / refdiv) * fbdiv */ 174 + reg = readl_relaxed(vco->base + VCO_CTRL1); 175 + refdiv = (reg & VCO_REFDIV_MASK) >> VCO_REFDIV_SHIFT; 176 + refdiv = vco_refdiv[refdiv]; 177 + fbdiv = (reg & VCO_FBDIV_MASK) >> VCO_FBDIV_SHIFT; 178 + freq *= fbdiv; 179 + do_div(freq, refdiv); 180 + 181 + return (unsigned long)freq; 182 + } 183 + 184 + static const struct clk_ops berlin2_avpll_vco_ops = { 185 + .is_enabled = berlin2_avpll_vco_is_enabled, 186 + .enable = berlin2_avpll_vco_enable, 187 + .disable = berlin2_avpll_vco_disable, 188 + .recalc_rate = berlin2_avpll_vco_recalc_rate, 189 + }; 190 + 191 + struct clk * __init berlin2_avpll_vco_register(void __iomem *base, 192 + const char *name, const char *parent_name, 193 + u8 vco_flags, unsigned long flags) 194 + { 195 + struct berlin2_avpll_vco *vco; 196 + struct clk_init_data init; 197 + 198 + vco = kzalloc(sizeof(*vco), GFP_KERNEL); 199 + if (!vco) 200 + return ERR_PTR(-ENOMEM); 201 + 202 + vco->base = base; 203 + vco->flags = vco_flags; 204 + vco->hw.init = &init; 205 + init.name = name; 206 + init.ops = &berlin2_avpll_vco_ops; 207 + init.parent_names = &parent_name; 208 + init.num_parents = 1; 209 + init.flags = flags; 210 + 211 + return clk_register(NULL, &vco->hw); 212 + } 213 + 214 + struct berlin2_avpll_channel { 215 + struct clk_hw hw; 216 + void __iomem *base; 217 + u8 flags; 218 + u8 index; 219 + }; 220 + 221 + #define to_avpll_channel(hw) container_of(hw, struct berlin2_avpll_channel, hw) 222 + 223 + static int berlin2_avpll_channel_is_enabled(struct clk_hw *hw) 224 + { 225 + struct berlin2_avpll_channel *ch = to_avpll_channel(hw); 226 + u32 reg; 227 + 228 + if (ch->index == 7) 229 + return 1; 230 + 231 + reg = readl_relaxed(ch->base + VCO_CTRL10); 232 + reg &= VCO_POWERUP_CH1 << ch->index; 233 + 234 + return !!reg; 235 + } 236 + 237 + static int berlin2_avpll_channel_enable(struct clk_hw *hw) 238 + { 239 + struct berlin2_avpll_channel *ch = to_avpll_channel(hw); 240 + u32 reg; 241 + 242 + reg = readl_relaxed(ch->base + VCO_CTRL10); 243 + reg |= VCO_POWERUP_CH1 << ch->index; 244 + writel_relaxed(reg, ch->base + VCO_CTRL10); 245 + 246 + return 0; 247 + } 248 + 249 + static void berlin2_avpll_channel_disable(struct clk_hw *hw) 250 + { 251 + struct berlin2_avpll_channel *ch = to_avpll_channel(hw); 252 + u32 reg; 253 + 254 + reg = readl_relaxed(ch->base + VCO_CTRL10); 255 + reg &= ~(VCO_POWERUP_CH1 << ch->index); 256 + writel_relaxed(reg, ch->base + VCO_CTRL10); 257 + } 258 + 259 + static const u8 div_hdmi[] = { 1, 2, 4, 6 }; 260 + static const u8 div_av1[] = { 1, 2, 5, 5 }; 261 + 262 + static unsigned long 263 + berlin2_avpll_channel_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) 264 + { 265 + struct berlin2_avpll_channel *ch = to_avpll_channel(hw); 266 + u32 reg, div_av2, div_av3, divider = 1; 267 + u64 freq = parent_rate; 268 + 269 + reg = readl_relaxed(ch->base + VCO_CTRL30); 270 + if ((reg & (VCO_DPLL_CH1_ENABLE << ch->index)) == 0) 271 + goto skip_div; 272 + 273 + /* 274 + * Fch = (Fref * sync2) / 275 + * (sync1 * div_hdmi * div_av1 * div_av2 * div_av3) 276 + */ 277 + 278 + reg = readl_relaxed(ch->base + VCO_SYNC1n(ch->index)); 279 + /* BG2/BG2CDs SYNC1 reg on AVPLL_B channel 1 is shifted by 4 */ 280 + if (ch->flags & BERLIN2_AVPLL_BIT_QUIRK && ch->index == 0) 281 + reg >>= 4; 282 + divider = reg & VCO_SYNC1_MASK; 283 + 284 + reg = readl_relaxed(ch->base + VCO_SYNC2n(ch->index)); 285 + freq *= reg & VCO_SYNC2_MASK; 286 + 287 + /* Channel 8 has no dividers */ 288 + if (ch->index == 7) 289 + goto skip_div; 290 + 291 + /* 292 + * HDMI divider start at VCO_CTRL11, bit 7; MSB is enable, lower 2 bit 293 + * determine divider. 294 + */ 295 + reg = readl_relaxed(ch->base + VCO_CTRL11) >> 7; 296 + reg = (reg >> (ch->index * 3)); 297 + if (reg & BIT(2)) 298 + divider *= div_hdmi[reg & 0x3]; 299 + 300 + /* 301 + * AV1 divider start at VCO_CTRL11, bit 28; MSB is enable, lower 2 bit 302 + * determine divider. 303 + */ 304 + if (ch->index == 0) { 305 + reg = readl_relaxed(ch->base + VCO_CTRL11); 306 + reg >>= 28; 307 + } else { 308 + reg = readl_relaxed(ch->base + VCO_CTRL12); 309 + reg >>= (ch->index-1) * 3; 310 + } 311 + if (reg & BIT(2)) 312 + divider *= div_av1[reg & 0x3]; 313 + 314 + /* 315 + * AV2 divider start at VCO_CTRL12, bit 18; each 7 bits wide, 316 + * zero is not a valid value. 317 + */ 318 + if (ch->index < 2) { 319 + reg = readl_relaxed(ch->base + VCO_CTRL12); 320 + reg >>= 18 + (ch->index * 7); 321 + } else if (ch->index < 7) { 322 + reg = readl_relaxed(ch->base + VCO_CTRL13); 323 + reg >>= (ch->index - 2) * 7; 324 + } else { 325 + reg = readl_relaxed(ch->base + VCO_CTRL14); 326 + } 327 + div_av2 = reg & 0x7f; 328 + if (div_av2) 329 + divider *= div_av2; 330 + 331 + /* 332 + * AV3 divider start at VCO_CTRL14, bit 7; each 4 bits wide. 333 + * AV2/AV3 form a fractional divider, where only specfic values for AV3 334 + * are allowed. AV3 != 0 divides by AV2/2, AV3=0 is bypass. 335 + */ 336 + if (ch->index < 6) { 337 + reg = readl_relaxed(ch->base + VCO_CTRL14); 338 + reg >>= 7 + (ch->index * 4); 339 + } else { 340 + reg = readl_relaxed(ch->base + VCO_CTRL15); 341 + } 342 + div_av3 = reg & 0xf; 343 + if (div_av2 && div_av3) 344 + freq *= 2; 345 + 346 + skip_div: 347 + do_div(freq, divider); 348 + return (unsigned long)freq; 349 + } 350 + 351 + static const struct clk_ops berlin2_avpll_channel_ops = { 352 + .is_enabled = berlin2_avpll_channel_is_enabled, 353 + .enable = berlin2_avpll_channel_enable, 354 + .disable = berlin2_avpll_channel_disable, 355 + .recalc_rate = berlin2_avpll_channel_recalc_rate, 356 + }; 357 + 358 + /* 359 + * Another nice quirk: 360 + * On some production SoCs, AVPLL channels are scrambled with respect 361 + * to the channel numbering in the registers but still referenced by 362 + * their original channel numbers. We deal with it by having a flag 363 + * and a translation table for the index. 364 + */ 365 + static const u8 quirk_index[] __initconst = { 0, 6, 5, 4, 3, 2, 1, 7 }; 366 + 367 + struct clk * __init berlin2_avpll_channel_register(void __iomem *base, 368 + const char *name, u8 index, const char *parent_name, 369 + u8 ch_flags, unsigned long flags) 370 + { 371 + struct berlin2_avpll_channel *ch; 372 + struct clk_init_data init; 373 + 374 + ch = kzalloc(sizeof(*ch), GFP_KERNEL); 375 + if (!ch) 376 + return ERR_PTR(-ENOMEM); 377 + 378 + ch->base = base; 379 + if (ch_flags & BERLIN2_AVPLL_SCRAMBLE_QUIRK) 380 + ch->index = quirk_index[index]; 381 + else 382 + ch->index = index; 383 + 384 + ch->flags = ch_flags; 385 + ch->hw.init = &init; 386 + init.name = name; 387 + init.ops = &berlin2_avpll_channel_ops; 388 + init.parent_names = &parent_name; 389 + init.num_parents = 1; 390 + init.flags = flags; 391 + 392 + return clk_register(NULL, &ch->hw); 393 + }
+36
drivers/clk/berlin/berlin2-avpll.h
··· 1 + /* 2 + * Copyright (c) 2014 Marvell Technology Group Ltd. 3 + * 4 + * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> 5 + * Alexandre Belloni <alexandre.belloni@free-electrons.com> 6 + * 7 + * This program is free software; you can redistribute it and/or modify it 8 + * under the terms and conditions of the GNU General Public License, 9 + * version 2, as published by the Free Software Foundation. 10 + * 11 + * This program is distributed in the hope it will be useful, but WITHOUT 12 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 14 + * more details. 15 + * 16 + * You should have received a copy of the GNU General Public License along with 17 + * this program. If not, see <http://www.gnu.org/licenses/>. 18 + */ 19 + #ifndef __BERLIN2_AVPLL_H 20 + #define __BERLIN2_AVPLL_H 21 + 22 + struct clk; 23 + 24 + #define BERLIN2_AVPLL_BIT_QUIRK BIT(0) 25 + #define BERLIN2_AVPLL_SCRAMBLE_QUIRK BIT(1) 26 + 27 + struct clk * __init 28 + berlin2_avpll_vco_register(void __iomem *base, const char *name, 29 + const char *parent_name, u8 vco_flags, unsigned long flags); 30 + 31 + struct clk * __init 32 + berlin2_avpll_channel_register(void __iomem *base, const char *name, 33 + u8 index, const char *parent_name, u8 ch_flags, 34 + unsigned long flags); 35 + 36 + #endif /* __BERLIN2_AVPLL_H */
+265
drivers/clk/berlin/berlin2-div.c
··· 1 + /* 2 + * Copyright (c) 2014 Marvell Technology Group Ltd. 3 + * 4 + * Alexandre Belloni <alexandre.belloni@free-electrons.com> 5 + * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> 6 + * 7 + * This program is free software; you can redistribute it and/or modify it 8 + * under the terms and conditions of the GNU General Public License, 9 + * version 2, as published by the Free Software Foundation. 10 + * 11 + * This program is distributed in the hope it will be useful, but WITHOUT 12 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 14 + * more details. 15 + * 16 + * You should have received a copy of the GNU General Public License along with 17 + * this program. If not, see <http://www.gnu.org/licenses/>. 18 + */ 19 + #include <linux/bitops.h> 20 + #include <linux/clk-provider.h> 21 + #include <linux/of.h> 22 + #include <linux/of_address.h> 23 + #include <linux/slab.h> 24 + #include <linux/spinlock.h> 25 + 26 + #include "berlin2-div.h" 27 + 28 + /* 29 + * Clock dividers in Berlin2 SoCs comprise a complex cell to select 30 + * input pll and divider. The virtual structure as it is used in Marvell 31 + * BSP code can be seen as: 32 + * 33 + * +---+ 34 + * pll0 --------------->| 0 | +---+ 35 + * +---+ |(B)|--+--------------->| 0 | +---+ 36 + * pll1.0 -->| 0 | +-->| 1 | | +--------+ |(E)|----->| 0 | +---+ 37 + * pll1.1 -->| 1 | | +---+ +-->|(C) 1:M |-->| 1 | |(F)|-->|(G)|-> 38 + * ... -->|(A)|--+ | +--------+ +---+ +-->| 1 | +---+ 39 + * ... -->| | +-->|(D) 1:3 |----------+ +---+ 40 + * pll1.N -->| N | +--------- 41 + * +---+ 42 + * 43 + * (A) input pll clock mux controlled by <PllSelect[1:n]> 44 + * (B) input pll bypass mux controlled by <PllSwitch> 45 + * (C) programmable clock divider controlled by <Select[1:n]> 46 + * (D) constant div-by-3 clock divider 47 + * (E) programmable clock divider bypass controlled by <Switch> 48 + * (F) constant div-by-3 clock mux controlled by <D3Switch> 49 + * (G) clock gate controlled by <Enable> 50 + * 51 + * For whatever reason, above control signals come in two flavors: 52 + * - single register dividers with all bits in one register 53 + * - shared register dividers with bits spread over multiple registers 54 + * (including signals for the same cell spread over consecutive registers) 55 + * 56 + * Also, clock gate and pll mux is not available on every div cell, so 57 + * we have to deal with those, too. We reuse common clock composite driver 58 + * for it. 59 + */ 60 + 61 + #define PLL_SELECT_MASK 0x7 62 + #define DIV_SELECT_MASK 0x7 63 + 64 + struct berlin2_div { 65 + struct clk_hw hw; 66 + void __iomem *base; 67 + struct berlin2_div_map map; 68 + spinlock_t *lock; 69 + }; 70 + 71 + #define to_berlin2_div(hw) container_of(hw, struct berlin2_div, hw) 72 + 73 + static u8 clk_div[] = { 1, 2, 4, 6, 8, 12, 1, 1 }; 74 + 75 + static int berlin2_div_is_enabled(struct clk_hw *hw) 76 + { 77 + struct berlin2_div *div = to_berlin2_div(hw); 78 + struct berlin2_div_map *map = &div->map; 79 + u32 reg; 80 + 81 + if (div->lock) 82 + spin_lock(div->lock); 83 + 84 + reg = readl_relaxed(div->base + map->gate_offs); 85 + reg >>= map->gate_shift; 86 + 87 + if (div->lock) 88 + spin_unlock(div->lock); 89 + 90 + return (reg & 0x1); 91 + } 92 + 93 + static int berlin2_div_enable(struct clk_hw *hw) 94 + { 95 + struct berlin2_div *div = to_berlin2_div(hw); 96 + struct berlin2_div_map *map = &div->map; 97 + u32 reg; 98 + 99 + if (div->lock) 100 + spin_lock(div->lock); 101 + 102 + reg = readl_relaxed(div->base + map->gate_offs); 103 + reg |= BIT(map->gate_shift); 104 + writel_relaxed(reg, div->base + map->gate_offs); 105 + 106 + if (div->lock) 107 + spin_unlock(div->lock); 108 + 109 + return 0; 110 + } 111 + 112 + static void berlin2_div_disable(struct clk_hw *hw) 113 + { 114 + struct berlin2_div *div = to_berlin2_div(hw); 115 + struct berlin2_div_map *map = &div->map; 116 + u32 reg; 117 + 118 + if (div->lock) 119 + spin_lock(div->lock); 120 + 121 + reg = readl_relaxed(div->base + map->gate_offs); 122 + reg &= ~BIT(map->gate_shift); 123 + writel_relaxed(reg, div->base + map->gate_offs); 124 + 125 + if (div->lock) 126 + spin_unlock(div->lock); 127 + } 128 + 129 + static int berlin2_div_set_parent(struct clk_hw *hw, u8 index) 130 + { 131 + struct berlin2_div *div = to_berlin2_div(hw); 132 + struct berlin2_div_map *map = &div->map; 133 + u32 reg; 134 + 135 + if (div->lock) 136 + spin_lock(div->lock); 137 + 138 + /* index == 0 is PLL_SWITCH */ 139 + reg = readl_relaxed(div->base + map->pll_switch_offs); 140 + if (index == 0) 141 + reg &= ~BIT(map->pll_switch_shift); 142 + else 143 + reg |= BIT(map->pll_switch_shift); 144 + writel_relaxed(reg, div->base + map->pll_switch_offs); 145 + 146 + /* index > 0 is PLL_SELECT */ 147 + if (index > 0) { 148 + reg = readl_relaxed(div->base + map->pll_select_offs); 149 + reg &= ~(PLL_SELECT_MASK << map->pll_select_shift); 150 + reg |= (index - 1) << map->pll_select_shift; 151 + writel_relaxed(reg, div->base + map->pll_select_offs); 152 + } 153 + 154 + if (div->lock) 155 + spin_unlock(div->lock); 156 + 157 + return 0; 158 + } 159 + 160 + static u8 berlin2_div_get_parent(struct clk_hw *hw) 161 + { 162 + struct berlin2_div *div = to_berlin2_div(hw); 163 + struct berlin2_div_map *map = &div->map; 164 + u32 reg; 165 + u8 index = 0; 166 + 167 + if (div->lock) 168 + spin_lock(div->lock); 169 + 170 + /* PLL_SWITCH == 0 is index 0 */ 171 + reg = readl_relaxed(div->base + map->pll_switch_offs); 172 + reg &= BIT(map->pll_switch_shift); 173 + if (reg) { 174 + reg = readl_relaxed(div->base + map->pll_select_offs); 175 + reg >>= map->pll_select_shift; 176 + reg &= PLL_SELECT_MASK; 177 + index = 1 + reg; 178 + } 179 + 180 + if (div->lock) 181 + spin_unlock(div->lock); 182 + 183 + return index; 184 + } 185 + 186 + static unsigned long berlin2_div_recalc_rate(struct clk_hw *hw, 187 + unsigned long parent_rate) 188 + { 189 + struct berlin2_div *div = to_berlin2_div(hw); 190 + struct berlin2_div_map *map = &div->map; 191 + u32 divsw, div3sw, divider = 1; 192 + 193 + if (div->lock) 194 + spin_lock(div->lock); 195 + 196 + divsw = readl_relaxed(div->base + map->div_switch_offs) & 197 + (1 << map->div_switch_shift); 198 + div3sw = readl_relaxed(div->base + map->div3_switch_offs) & 199 + (1 << map->div3_switch_shift); 200 + 201 + /* constant divide-by-3 (dominant) */ 202 + if (div3sw != 0) { 203 + divider = 3; 204 + /* divider can be bypassed with DIV_SWITCH == 0 */ 205 + } else if (divsw == 0) { 206 + divider = 1; 207 + /* clock divider determined by DIV_SELECT */ 208 + } else { 209 + u32 reg; 210 + reg = readl_relaxed(div->base + map->div_select_offs); 211 + reg >>= map->div_select_shift; 212 + reg &= DIV_SELECT_MASK; 213 + divider = clk_div[reg]; 214 + } 215 + 216 + if (div->lock) 217 + spin_unlock(div->lock); 218 + 219 + return parent_rate / divider; 220 + } 221 + 222 + static const struct clk_ops berlin2_div_rate_ops = { 223 + .recalc_rate = berlin2_div_recalc_rate, 224 + }; 225 + 226 + static const struct clk_ops berlin2_div_gate_ops = { 227 + .is_enabled = berlin2_div_is_enabled, 228 + .enable = berlin2_div_enable, 229 + .disable = berlin2_div_disable, 230 + }; 231 + 232 + static const struct clk_ops berlin2_div_mux_ops = { 233 + .set_parent = berlin2_div_set_parent, 234 + .get_parent = berlin2_div_get_parent, 235 + }; 236 + 237 + struct clk * __init 238 + berlin2_div_register(const struct berlin2_div_map *map, 239 + void __iomem *base, const char *name, u8 div_flags, 240 + const char **parent_names, int num_parents, 241 + unsigned long flags, spinlock_t *lock) 242 + { 243 + const struct clk_ops *mux_ops = &berlin2_div_mux_ops; 244 + const struct clk_ops *rate_ops = &berlin2_div_rate_ops; 245 + const struct clk_ops *gate_ops = &berlin2_div_gate_ops; 246 + struct berlin2_div *div; 247 + 248 + div = kzalloc(sizeof(*div), GFP_KERNEL); 249 + if (!div) 250 + return ERR_PTR(-ENOMEM); 251 + 252 + /* copy div_map to allow __initconst */ 253 + memcpy(&div->map, map, sizeof(*map)); 254 + div->base = base; 255 + div->lock = lock; 256 + 257 + if ((div_flags & BERLIN2_DIV_HAS_GATE) == 0) 258 + gate_ops = NULL; 259 + if ((div_flags & BERLIN2_DIV_HAS_MUX) == 0) 260 + mux_ops = NULL; 261 + 262 + return clk_register_composite(NULL, name, parent_names, num_parents, 263 + &div->hw, mux_ops, &div->hw, rate_ops, 264 + &div->hw, gate_ops, flags); 265 + }
+89
drivers/clk/berlin/berlin2-div.h
··· 1 + /* 2 + * Copyright (c) 2014 Marvell Technology Group Ltd. 3 + * 4 + * Alexandre Belloni <alexandre.belloni@free-electrons.com> 5 + * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> 6 + * 7 + * This program is free software; you can redistribute it and/or modify it 8 + * under the terms and conditions of the GNU General Public License, 9 + * version 2, as published by the Free Software Foundation. 10 + * 11 + * This program is distributed in the hope it will be useful, but WITHOUT 12 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 14 + * more details. 15 + * 16 + * You should have received a copy of the GNU General Public License along with 17 + * this program. If not, see <http://www.gnu.org/licenses/>. 18 + */ 19 + #ifndef __BERLIN2_DIV_H 20 + #define __BERLIN2_DIV_H 21 + 22 + struct clk; 23 + 24 + #define BERLIN2_DIV_HAS_GATE BIT(0) 25 + #define BERLIN2_DIV_HAS_MUX BIT(1) 26 + 27 + #define BERLIN2_PLL_SELECT(_off, _sh) \ 28 + .pll_select_offs = _off, \ 29 + .pll_select_shift = _sh 30 + 31 + #define BERLIN2_PLL_SWITCH(_off, _sh) \ 32 + .pll_switch_offs = _off, \ 33 + .pll_switch_shift = _sh 34 + 35 + #define BERLIN2_DIV_SELECT(_off, _sh) \ 36 + .div_select_offs = _off, \ 37 + .div_select_shift = _sh 38 + 39 + #define BERLIN2_DIV_SWITCH(_off, _sh) \ 40 + .div_switch_offs = _off, \ 41 + .div_switch_shift = _sh 42 + 43 + #define BERLIN2_DIV_D3SWITCH(_off, _sh) \ 44 + .div3_switch_offs = _off, \ 45 + .div3_switch_shift = _sh 46 + 47 + #define BERLIN2_DIV_GATE(_off, _sh) \ 48 + .gate_offs = _off, \ 49 + .gate_shift = _sh 50 + 51 + #define BERLIN2_SINGLE_DIV(_off) \ 52 + BERLIN2_DIV_GATE(_off, 0), \ 53 + BERLIN2_PLL_SELECT(_off, 1), \ 54 + BERLIN2_PLL_SWITCH(_off, 4), \ 55 + BERLIN2_DIV_SWITCH(_off, 5), \ 56 + BERLIN2_DIV_D3SWITCH(_off, 6), \ 57 + BERLIN2_DIV_SELECT(_off, 7) 58 + 59 + struct berlin2_div_map { 60 + u16 pll_select_offs; 61 + u16 pll_switch_offs; 62 + u16 div_select_offs; 63 + u16 div_switch_offs; 64 + u16 div3_switch_offs; 65 + u16 gate_offs; 66 + u8 pll_select_shift; 67 + u8 pll_switch_shift; 68 + u8 div_select_shift; 69 + u8 div_switch_shift; 70 + u8 div3_switch_shift; 71 + u8 gate_shift; 72 + }; 73 + 74 + struct berlin2_div_data { 75 + const char *name; 76 + const u8 *parent_ids; 77 + int num_parents; 78 + unsigned long flags; 79 + struct berlin2_div_map map; 80 + u8 div_flags; 81 + }; 82 + 83 + struct clk * __init 84 + berlin2_div_register(const struct berlin2_div_map *map, 85 + void __iomem *base, const char *name, u8 div_flags, 86 + const char **parent_names, int num_parents, 87 + unsigned long flags, spinlock_t *lock); 88 + 89 + #endif /* __BERLIN2_DIV_H */
+117
drivers/clk/berlin/berlin2-pll.c
··· 1 + /* 2 + * Copyright (c) 2014 Marvell Technology Group Ltd. 3 + * 4 + * Alexandre Belloni <alexandre.belloni@free-electrons.com> 5 + * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> 6 + * 7 + * This program is free software; you can redistribute it and/or modify it 8 + * under the terms and conditions of the GNU General Public License, 9 + * version 2, as published by the Free Software Foundation. 10 + * 11 + * This program is distributed in the hope it will be useful, but WITHOUT 12 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 14 + * more details. 15 + * 16 + * You should have received a copy of the GNU General Public License along with 17 + * this program. If not, see <http://www.gnu.org/licenses/>. 18 + */ 19 + #include <linux/clk-provider.h> 20 + #include <linux/io.h> 21 + #include <linux/kernel.h> 22 + #include <linux/of.h> 23 + #include <linux/of_address.h> 24 + #include <linux/slab.h> 25 + #include <asm/div64.h> 26 + 27 + #include "berlin2-div.h" 28 + 29 + struct berlin2_pll_map { 30 + const u8 vcodiv[16]; 31 + u8 mult; 32 + u8 fbdiv_shift; 33 + u8 rfdiv_shift; 34 + u8 divsel_shift; 35 + }; 36 + 37 + struct berlin2_pll { 38 + struct clk_hw hw; 39 + void __iomem *base; 40 + struct berlin2_pll_map map; 41 + }; 42 + 43 + #define to_berlin2_pll(hw) container_of(hw, struct berlin2_pll, hw) 44 + 45 + #define SPLL_CTRL0 0x00 46 + #define SPLL_CTRL1 0x04 47 + #define SPLL_CTRL2 0x08 48 + #define SPLL_CTRL3 0x0c 49 + #define SPLL_CTRL4 0x10 50 + 51 + #define FBDIV_MASK 0x1ff 52 + #define RFDIV_MASK 0x1f 53 + #define DIVSEL_MASK 0xf 54 + 55 + /* 56 + * The output frequency formula for the pll is: 57 + * clkout = fbdiv / refdiv * parent / vcodiv 58 + */ 59 + static unsigned long 60 + berlin2_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) 61 + { 62 + struct berlin2_pll *pll = to_berlin2_pll(hw); 63 + struct berlin2_pll_map *map = &pll->map; 64 + u32 val, fbdiv, rfdiv, vcodivsel, vcodiv; 65 + u64 rate = parent_rate; 66 + 67 + val = readl_relaxed(pll->base + SPLL_CTRL0); 68 + fbdiv = (val >> map->fbdiv_shift) & FBDIV_MASK; 69 + rfdiv = (val >> map->rfdiv_shift) & RFDIV_MASK; 70 + if (rfdiv == 0) { 71 + pr_warn("%s has zero rfdiv\n", __clk_get_name(hw->clk)); 72 + rfdiv = 1; 73 + } 74 + 75 + val = readl_relaxed(pll->base + SPLL_CTRL1); 76 + vcodivsel = (val >> map->divsel_shift) & DIVSEL_MASK; 77 + vcodiv = map->vcodiv[vcodivsel]; 78 + if (vcodiv == 0) { 79 + pr_warn("%s has zero vcodiv (index %d)\n", 80 + __clk_get_name(hw->clk), vcodivsel); 81 + vcodiv = 1; 82 + } 83 + 84 + rate *= fbdiv * map->mult; 85 + do_div(rate, rfdiv * vcodiv); 86 + 87 + return (unsigned long)rate; 88 + } 89 + 90 + static const struct clk_ops berlin2_pll_ops = { 91 + .recalc_rate = berlin2_pll_recalc_rate, 92 + }; 93 + 94 + struct clk * __init 95 + berlin2_pll_register(const struct berlin2_pll_map *map, 96 + void __iomem *base, const char *name, 97 + const char *parent_name, unsigned long flags) 98 + { 99 + struct clk_init_data init; 100 + struct berlin2_pll *pll; 101 + 102 + pll = kzalloc(sizeof(*pll), GFP_KERNEL); 103 + if (!pll) 104 + return ERR_PTR(-ENOMEM); 105 + 106 + /* copy pll_map to allow __initconst */ 107 + memcpy(&pll->map, map, sizeof(*map)); 108 + pll->base = base; 109 + pll->hw.init = &init; 110 + init.name = name; 111 + init.ops = &berlin2_pll_ops; 112 + init.parent_names = &parent_name; 113 + init.num_parents = 1; 114 + init.flags = flags; 115 + 116 + return clk_register(NULL, &pll->hw); 117 + }
+37
drivers/clk/berlin/berlin2-pll.h
··· 1 + /* 2 + * Copyright (c) 2014 Marvell Technology Group Ltd. 3 + * 4 + * Alexandre Belloni <alexandre.belloni@free-electrons.com> 5 + * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> 6 + * 7 + * This program is free software; you can redistribute it and/or modify it 8 + * under the terms and conditions of the GNU General Public License, 9 + * version 2, as published by the Free Software Foundation. 10 + * 11 + * This program is distributed in the hope it will be useful, but WITHOUT 12 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 14 + * more details. 15 + * 16 + * You should have received a copy of the GNU General Public License along with 17 + * this program. If not, see <http://www.gnu.org/licenses/>. 18 + */ 19 + #ifndef __BERLIN2_PLL_H 20 + #define __BERLIN2_PLL_H 21 + 22 + struct clk; 23 + 24 + struct berlin2_pll_map { 25 + const u8 vcodiv[16]; 26 + u8 mult; 27 + u8 fbdiv_shift; 28 + u8 rfdiv_shift; 29 + u8 divsel_shift; 30 + }; 31 + 32 + struct clk * __init 33 + berlin2_pll_register(const struct berlin2_pll_map *map, 34 + void __iomem *base, const char *name, 35 + const char *parent_name, unsigned long flags); 36 + 37 + #endif /* __BERLIN2_PLL_H */
+691
drivers/clk/berlin/bg2.c
··· 1 + /* 2 + * Copyright (c) 2014 Marvell Technology Group Ltd. 3 + * 4 + * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> 5 + * Alexandre Belloni <alexandre.belloni@free-electrons.com> 6 + * 7 + * This program is free software; you can redistribute it and/or modify it 8 + * under the terms and conditions of the GNU General Public License, 9 + * version 2, as published by the Free Software Foundation. 10 + * 11 + * This program is distributed in the hope it will be useful, but WITHOUT 12 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 14 + * more details. 15 + * 16 + * You should have received a copy of the GNU General Public License along with 17 + * this program. If not, see <http://www.gnu.org/licenses/>. 18 + */ 19 + 20 + #include <linux/clk.h> 21 + #include <linux/clk-provider.h> 22 + #include <linux/kernel.h> 23 + #include <linux/of.h> 24 + #include <linux/of_address.h> 25 + #include <linux/slab.h> 26 + 27 + #include <dt-bindings/clock/berlin2.h> 28 + 29 + #include "berlin2-avpll.h" 30 + #include "berlin2-div.h" 31 + #include "berlin2-pll.h" 32 + #include "common.h" 33 + 34 + #define REG_PINMUX0 0x0000 35 + #define REG_PINMUX1 0x0004 36 + #define REG_SYSPLLCTL0 0x0014 37 + #define REG_SYSPLLCTL4 0x0024 38 + #define REG_MEMPLLCTL0 0x0028 39 + #define REG_MEMPLLCTL4 0x0038 40 + #define REG_CPUPLLCTL0 0x003c 41 + #define REG_CPUPLLCTL4 0x004c 42 + #define REG_AVPLLCTL0 0x0050 43 + #define REG_AVPLLCTL31 0x00cc 44 + #define REG_AVPLLCTL62 0x0148 45 + #define REG_PLLSTATUS 0x014c 46 + #define REG_CLKENABLE 0x0150 47 + #define REG_CLKSELECT0 0x0154 48 + #define REG_CLKSELECT1 0x0158 49 + #define REG_CLKSELECT2 0x015c 50 + #define REG_CLKSELECT3 0x0160 51 + #define REG_CLKSWITCH0 0x0164 52 + #define REG_CLKSWITCH1 0x0168 53 + #define REG_RESET_TRIGGER 0x0178 54 + #define REG_RESET_STATUS0 0x017c 55 + #define REG_RESET_STATUS1 0x0180 56 + #define REG_SW_GENERIC0 0x0184 57 + #define REG_SW_GENERIC3 0x0190 58 + #define REG_PRODUCTID 0x01cc 59 + #define REG_PRODUCTID_EXT 0x01d0 60 + #define REG_GFX3DCORE_CLKCTL 0x022c 61 + #define REG_GFX3DSYS_CLKCTL 0x0230 62 + #define REG_ARC_CLKCTL 0x0234 63 + #define REG_VIP_CLKCTL 0x0238 64 + #define REG_SDIO0XIN_CLKCTL 0x023c 65 + #define REG_SDIO1XIN_CLKCTL 0x0240 66 + #define REG_GFX3DEXTRA_CLKCTL 0x0244 67 + #define REG_GFX3D_RESET 0x0248 68 + #define REG_GC360_CLKCTL 0x024c 69 + #define REG_SDIO_DLLMST_CLKCTL 0x0250 70 + 71 + /* 72 + * BG2/BG2CD SoCs have the following audio/video I/O units: 73 + * 74 + * audiohd: HDMI TX audio 75 + * audio0: 7.1ch TX 76 + * audio1: 2ch TX 77 + * audio2: 2ch RX 78 + * audio3: SPDIF TX 79 + * video0: HDMI video 80 + * video1: Secondary video 81 + * video2: SD auxiliary video 82 + * 83 + * There are no external audio clocks (ACLKI0, ACLKI1) and 84 + * only one external video clock (VCLKI0). 85 + * 86 + * Currently missing bits and pieces: 87 + * - audio_fast_pll is unknown 88 + * - audiohd_pll is unknown 89 + * - video0_pll is unknown 90 + * - audio[023], audiohd parent pll is assumed to be audio_fast_pll 91 + * 92 + */ 93 + 94 + #define MAX_CLKS 41 95 + static struct clk *clks[MAX_CLKS]; 96 + static struct clk_onecell_data clk_data; 97 + static DEFINE_SPINLOCK(lock); 98 + static void __iomem *gbase; 99 + 100 + enum { 101 + REFCLK, VIDEO_EXT0, 102 + SYSPLL, MEMPLL, CPUPLL, 103 + AVPLL_A1, AVPLL_A2, AVPLL_A3, AVPLL_A4, 104 + AVPLL_A5, AVPLL_A6, AVPLL_A7, AVPLL_A8, 105 + AVPLL_B1, AVPLL_B2, AVPLL_B3, AVPLL_B4, 106 + AVPLL_B5, AVPLL_B6, AVPLL_B7, AVPLL_B8, 107 + AUDIO1_PLL, AUDIO_FAST_PLL, 108 + VIDEO0_PLL, VIDEO0_IN, 109 + VIDEO1_PLL, VIDEO1_IN, 110 + VIDEO2_PLL, VIDEO2_IN, 111 + }; 112 + 113 + static const char *clk_names[] = { 114 + [REFCLK] = "refclk", 115 + [VIDEO_EXT0] = "video_ext0", 116 + [SYSPLL] = "syspll", 117 + [MEMPLL] = "mempll", 118 + [CPUPLL] = "cpupll", 119 + [AVPLL_A1] = "avpll_a1", 120 + [AVPLL_A2] = "avpll_a2", 121 + [AVPLL_A3] = "avpll_a3", 122 + [AVPLL_A4] = "avpll_a4", 123 + [AVPLL_A5] = "avpll_a5", 124 + [AVPLL_A6] = "avpll_a6", 125 + [AVPLL_A7] = "avpll_a7", 126 + [AVPLL_A8] = "avpll_a8", 127 + [AVPLL_B1] = "avpll_b1", 128 + [AVPLL_B2] = "avpll_b2", 129 + [AVPLL_B3] = "avpll_b3", 130 + [AVPLL_B4] = "avpll_b4", 131 + [AVPLL_B5] = "avpll_b5", 132 + [AVPLL_B6] = "avpll_b6", 133 + [AVPLL_B7] = "avpll_b7", 134 + [AVPLL_B8] = "avpll_b8", 135 + [AUDIO1_PLL] = "audio1_pll", 136 + [AUDIO_FAST_PLL] = "audio_fast_pll", 137 + [VIDEO0_PLL] = "video0_pll", 138 + [VIDEO0_IN] = "video0_in", 139 + [VIDEO1_PLL] = "video1_pll", 140 + [VIDEO1_IN] = "video1_in", 141 + [VIDEO2_PLL] = "video2_pll", 142 + [VIDEO2_IN] = "video2_in", 143 + }; 144 + 145 + static const struct berlin2_pll_map bg2_pll_map __initconst = { 146 + .vcodiv = {10, 15, 20, 25, 30, 40, 50, 60, 80}, 147 + .mult = 10, 148 + .fbdiv_shift = 6, 149 + .rfdiv_shift = 1, 150 + .divsel_shift = 7, 151 + }; 152 + 153 + static const u8 default_parent_ids[] = { 154 + SYSPLL, AVPLL_B4, AVPLL_A5, AVPLL_B6, AVPLL_B7, SYSPLL 155 + }; 156 + 157 + static const struct berlin2_div_data bg2_divs[] __initconst = { 158 + { 159 + .name = "sys", 160 + .parent_ids = (const u8 []){ 161 + SYSPLL, AVPLL_B4, AVPLL_B5, AVPLL_B6, AVPLL_B7, SYSPLL 162 + }, 163 + .num_parents = 6, 164 + .map = { 165 + BERLIN2_DIV_GATE(REG_CLKENABLE, 0), 166 + BERLIN2_PLL_SELECT(REG_CLKSELECT0, 0), 167 + BERLIN2_DIV_SELECT(REG_CLKSELECT0, 3), 168 + BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 3), 169 + BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 4), 170 + BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 5), 171 + }, 172 + .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX, 173 + .flags = CLK_IGNORE_UNUSED, 174 + }, 175 + { 176 + .name = "cpu", 177 + .parent_ids = (const u8 []){ 178 + CPUPLL, MEMPLL, MEMPLL, MEMPLL, MEMPLL 179 + }, 180 + .num_parents = 5, 181 + .map = { 182 + BERLIN2_PLL_SELECT(REG_CLKSELECT0, 6), 183 + BERLIN2_DIV_SELECT(REG_CLKSELECT0, 9), 184 + BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 6), 185 + BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 7), 186 + BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 8), 187 + }, 188 + .div_flags = BERLIN2_DIV_HAS_MUX, 189 + .flags = 0, 190 + }, 191 + { 192 + .name = "drmfigo", 193 + .parent_ids = default_parent_ids, 194 + .num_parents = ARRAY_SIZE(default_parent_ids), 195 + .map = { 196 + BERLIN2_DIV_GATE(REG_CLKENABLE, 16), 197 + BERLIN2_PLL_SELECT(REG_CLKSELECT0, 17), 198 + BERLIN2_DIV_SELECT(REG_CLKSELECT0, 20), 199 + BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 12), 200 + BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 13), 201 + BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 14), 202 + }, 203 + .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX, 204 + .flags = 0, 205 + }, 206 + { 207 + .name = "cfg", 208 + .parent_ids = default_parent_ids, 209 + .num_parents = ARRAY_SIZE(default_parent_ids), 210 + .map = { 211 + BERLIN2_DIV_GATE(REG_CLKENABLE, 1), 212 + BERLIN2_PLL_SELECT(REG_CLKSELECT0, 23), 213 + BERLIN2_DIV_SELECT(REG_CLKSELECT0, 26), 214 + BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 15), 215 + BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 16), 216 + BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 17), 217 + }, 218 + .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX, 219 + .flags = 0, 220 + }, 221 + { 222 + .name = "gfx", 223 + .parent_ids = default_parent_ids, 224 + .num_parents = ARRAY_SIZE(default_parent_ids), 225 + .map = { 226 + BERLIN2_DIV_GATE(REG_CLKENABLE, 4), 227 + BERLIN2_PLL_SELECT(REG_CLKSELECT0, 29), 228 + BERLIN2_DIV_SELECT(REG_CLKSELECT1, 0), 229 + BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 18), 230 + BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 19), 231 + BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 20), 232 + }, 233 + .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX, 234 + .flags = 0, 235 + }, 236 + { 237 + .name = "zsp", 238 + .parent_ids = default_parent_ids, 239 + .num_parents = ARRAY_SIZE(default_parent_ids), 240 + .map = { 241 + BERLIN2_DIV_GATE(REG_CLKENABLE, 5), 242 + BERLIN2_PLL_SELECT(REG_CLKSELECT1, 3), 243 + BERLIN2_DIV_SELECT(REG_CLKSELECT1, 6), 244 + BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 21), 245 + BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 22), 246 + BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 23), 247 + }, 248 + .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX, 249 + .flags = 0, 250 + }, 251 + { 252 + .name = "perif", 253 + .parent_ids = default_parent_ids, 254 + .num_parents = ARRAY_SIZE(default_parent_ids), 255 + .map = { 256 + BERLIN2_DIV_GATE(REG_CLKENABLE, 6), 257 + BERLIN2_PLL_SELECT(REG_CLKSELECT1, 9), 258 + BERLIN2_DIV_SELECT(REG_CLKSELECT1, 12), 259 + BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 24), 260 + BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 25), 261 + BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 26), 262 + }, 263 + .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX, 264 + .flags = CLK_IGNORE_UNUSED, 265 + }, 266 + { 267 + .name = "pcube", 268 + .parent_ids = default_parent_ids, 269 + .num_parents = ARRAY_SIZE(default_parent_ids), 270 + .map = { 271 + BERLIN2_DIV_GATE(REG_CLKENABLE, 2), 272 + BERLIN2_PLL_SELECT(REG_CLKSELECT1, 15), 273 + BERLIN2_DIV_SELECT(REG_CLKSELECT1, 18), 274 + BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 27), 275 + BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 28), 276 + BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 29), 277 + }, 278 + .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX, 279 + .flags = 0, 280 + }, 281 + { 282 + .name = "vscope", 283 + .parent_ids = default_parent_ids, 284 + .num_parents = ARRAY_SIZE(default_parent_ids), 285 + .map = { 286 + BERLIN2_DIV_GATE(REG_CLKENABLE, 3), 287 + BERLIN2_PLL_SELECT(REG_CLKSELECT1, 21), 288 + BERLIN2_DIV_SELECT(REG_CLKSELECT1, 24), 289 + BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 30), 290 + BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 31), 291 + BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH1, 0), 292 + }, 293 + .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX, 294 + .flags = 0, 295 + }, 296 + { 297 + .name = "nfc_ecc", 298 + .parent_ids = default_parent_ids, 299 + .num_parents = ARRAY_SIZE(default_parent_ids), 300 + .map = { 301 + BERLIN2_DIV_GATE(REG_CLKENABLE, 18), 302 + BERLIN2_PLL_SELECT(REG_CLKSELECT1, 27), 303 + BERLIN2_DIV_SELECT(REG_CLKSELECT2, 0), 304 + BERLIN2_PLL_SWITCH(REG_CLKSWITCH1, 1), 305 + BERLIN2_DIV_SWITCH(REG_CLKSWITCH1, 2), 306 + BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH1, 3), 307 + }, 308 + .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX, 309 + .flags = 0, 310 + }, 311 + { 312 + .name = "vpp", 313 + .parent_ids = default_parent_ids, 314 + .num_parents = ARRAY_SIZE(default_parent_ids), 315 + .map = { 316 + BERLIN2_DIV_GATE(REG_CLKENABLE, 21), 317 + BERLIN2_PLL_SELECT(REG_CLKSELECT2, 3), 318 + BERLIN2_DIV_SELECT(REG_CLKSELECT2, 6), 319 + BERLIN2_PLL_SWITCH(REG_CLKSWITCH1, 4), 320 + BERLIN2_DIV_SWITCH(REG_CLKSWITCH1, 5), 321 + BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH1, 6), 322 + }, 323 + .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX, 324 + .flags = 0, 325 + }, 326 + { 327 + .name = "app", 328 + .parent_ids = default_parent_ids, 329 + .num_parents = ARRAY_SIZE(default_parent_ids), 330 + .map = { 331 + BERLIN2_DIV_GATE(REG_CLKENABLE, 20), 332 + BERLIN2_PLL_SELECT(REG_CLKSELECT2, 9), 333 + BERLIN2_DIV_SELECT(REG_CLKSELECT2, 12), 334 + BERLIN2_PLL_SWITCH(REG_CLKSWITCH1, 7), 335 + BERLIN2_DIV_SWITCH(REG_CLKSWITCH1, 8), 336 + BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH1, 9), 337 + }, 338 + .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX, 339 + .flags = 0, 340 + }, 341 + { 342 + .name = "audio0", 343 + .parent_ids = (const u8 []){ AUDIO_FAST_PLL }, 344 + .num_parents = 1, 345 + .map = { 346 + BERLIN2_DIV_GATE(REG_CLKENABLE, 22), 347 + BERLIN2_DIV_SELECT(REG_CLKSELECT2, 17), 348 + BERLIN2_DIV_SWITCH(REG_CLKSWITCH1, 10), 349 + BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH1, 11), 350 + }, 351 + .div_flags = BERLIN2_DIV_HAS_GATE, 352 + .flags = 0, 353 + }, 354 + { 355 + .name = "audio2", 356 + .parent_ids = (const u8 []){ AUDIO_FAST_PLL }, 357 + .num_parents = 1, 358 + .map = { 359 + BERLIN2_DIV_GATE(REG_CLKENABLE, 24), 360 + BERLIN2_DIV_SELECT(REG_CLKSELECT2, 20), 361 + BERLIN2_DIV_SWITCH(REG_CLKSWITCH1, 14), 362 + BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH1, 15), 363 + }, 364 + .div_flags = BERLIN2_DIV_HAS_GATE, 365 + .flags = 0, 366 + }, 367 + { 368 + .name = "audio3", 369 + .parent_ids = (const u8 []){ AUDIO_FAST_PLL }, 370 + .num_parents = 1, 371 + .map = { 372 + BERLIN2_DIV_GATE(REG_CLKENABLE, 25), 373 + BERLIN2_DIV_SELECT(REG_CLKSELECT2, 23), 374 + BERLIN2_DIV_SWITCH(REG_CLKSWITCH1, 16), 375 + BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH1, 17), 376 + }, 377 + .div_flags = BERLIN2_DIV_HAS_GATE, 378 + .flags = 0, 379 + }, 380 + { 381 + .name = "audio1", 382 + .parent_ids = (const u8 []){ AUDIO1_PLL }, 383 + .num_parents = 1, 384 + .map = { 385 + BERLIN2_DIV_GATE(REG_CLKENABLE, 23), 386 + BERLIN2_DIV_SELECT(REG_CLKSELECT3, 0), 387 + BERLIN2_DIV_SWITCH(REG_CLKSWITCH1, 12), 388 + BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH1, 13), 389 + }, 390 + .div_flags = BERLIN2_DIV_HAS_GATE, 391 + .flags = 0, 392 + }, 393 + { 394 + .name = "gfx3d_core", 395 + .parent_ids = default_parent_ids, 396 + .num_parents = ARRAY_SIZE(default_parent_ids), 397 + .map = { 398 + BERLIN2_SINGLE_DIV(REG_GFX3DCORE_CLKCTL), 399 + }, 400 + .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX, 401 + .flags = 0, 402 + }, 403 + { 404 + .name = "gfx3d_sys", 405 + .parent_ids = default_parent_ids, 406 + .num_parents = ARRAY_SIZE(default_parent_ids), 407 + .map = { 408 + BERLIN2_SINGLE_DIV(REG_GFX3DSYS_CLKCTL), 409 + }, 410 + .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX, 411 + .flags = 0, 412 + }, 413 + { 414 + .name = "arc", 415 + .parent_ids = default_parent_ids, 416 + .num_parents = ARRAY_SIZE(default_parent_ids), 417 + .map = { 418 + BERLIN2_SINGLE_DIV(REG_ARC_CLKCTL), 419 + }, 420 + .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX, 421 + .flags = 0, 422 + }, 423 + { 424 + .name = "vip", 425 + .parent_ids = default_parent_ids, 426 + .num_parents = ARRAY_SIZE(default_parent_ids), 427 + .map = { 428 + BERLIN2_SINGLE_DIV(REG_VIP_CLKCTL), 429 + }, 430 + .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX, 431 + .flags = 0, 432 + }, 433 + { 434 + .name = "sdio0xin", 435 + .parent_ids = default_parent_ids, 436 + .num_parents = ARRAY_SIZE(default_parent_ids), 437 + .map = { 438 + BERLIN2_SINGLE_DIV(REG_SDIO0XIN_CLKCTL), 439 + }, 440 + .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX, 441 + .flags = 0, 442 + }, 443 + { 444 + .name = "sdio1xin", 445 + .parent_ids = default_parent_ids, 446 + .num_parents = ARRAY_SIZE(default_parent_ids), 447 + .map = { 448 + BERLIN2_SINGLE_DIV(REG_SDIO1XIN_CLKCTL), 449 + }, 450 + .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX, 451 + .flags = 0, 452 + }, 453 + { 454 + .name = "gfx3d_extra", 455 + .parent_ids = default_parent_ids, 456 + .num_parents = ARRAY_SIZE(default_parent_ids), 457 + .map = { 458 + BERLIN2_SINGLE_DIV(REG_GFX3DEXTRA_CLKCTL), 459 + }, 460 + .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX, 461 + .flags = 0, 462 + }, 463 + { 464 + .name = "gc360", 465 + .parent_ids = default_parent_ids, 466 + .num_parents = ARRAY_SIZE(default_parent_ids), 467 + .map = { 468 + BERLIN2_SINGLE_DIV(REG_GC360_CLKCTL), 469 + }, 470 + .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX, 471 + .flags = 0, 472 + }, 473 + { 474 + .name = "sdio_dllmst", 475 + .parent_ids = default_parent_ids, 476 + .num_parents = ARRAY_SIZE(default_parent_ids), 477 + .map = { 478 + BERLIN2_SINGLE_DIV(REG_SDIO_DLLMST_CLKCTL), 479 + }, 480 + .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX, 481 + .flags = 0, 482 + }, 483 + }; 484 + 485 + static const struct berlin2_gate_data bg2_gates[] __initconst = { 486 + { "geth0", "perif", 7 }, 487 + { "geth1", "perif", 8 }, 488 + { "sata", "perif", 9 }, 489 + { "ahbapb", "perif", 10, CLK_IGNORE_UNUSED }, 490 + { "usb0", "perif", 11 }, 491 + { "usb1", "perif", 12 }, 492 + { "pbridge", "perif", 13, CLK_IGNORE_UNUSED }, 493 + { "sdio0", "perif", 14, CLK_IGNORE_UNUSED }, 494 + { "sdio1", "perif", 15, CLK_IGNORE_UNUSED }, 495 + { "nfc", "perif", 17 }, 496 + { "smemc", "perif", 19 }, 497 + { "audiohd", "audiohd_pll", 26 }, 498 + { "video0", "video0_in", 27 }, 499 + { "video1", "video1_in", 28 }, 500 + { "video2", "video2_in", 29 }, 501 + }; 502 + 503 + static void __init berlin2_clock_setup(struct device_node *np) 504 + { 505 + const char *parent_names[9]; 506 + struct clk *clk; 507 + u8 avpll_flags = 0; 508 + int n; 509 + 510 + gbase = of_iomap(np, 0); 511 + if (!gbase) 512 + return; 513 + 514 + /* overwrite default clock names with DT provided ones */ 515 + clk = of_clk_get_by_name(np, clk_names[REFCLK]); 516 + if (!IS_ERR(clk)) { 517 + clk_names[REFCLK] = __clk_get_name(clk); 518 + clk_put(clk); 519 + } 520 + 521 + clk = of_clk_get_by_name(np, clk_names[VIDEO_EXT0]); 522 + if (!IS_ERR(clk)) { 523 + clk_names[VIDEO_EXT0] = __clk_get_name(clk); 524 + clk_put(clk); 525 + } 526 + 527 + /* simple register PLLs */ 528 + clk = berlin2_pll_register(&bg2_pll_map, gbase + REG_SYSPLLCTL0, 529 + clk_names[SYSPLL], clk_names[REFCLK], 0); 530 + if (IS_ERR(clk)) 531 + goto bg2_fail; 532 + 533 + clk = berlin2_pll_register(&bg2_pll_map, gbase + REG_MEMPLLCTL0, 534 + clk_names[MEMPLL], clk_names[REFCLK], 0); 535 + if (IS_ERR(clk)) 536 + goto bg2_fail; 537 + 538 + clk = berlin2_pll_register(&bg2_pll_map, gbase + REG_CPUPLLCTL0, 539 + clk_names[CPUPLL], clk_names[REFCLK], 0); 540 + if (IS_ERR(clk)) 541 + goto bg2_fail; 542 + 543 + if (of_device_is_compatible(np, "marvell,berlin2-global-register")) 544 + avpll_flags |= BERLIN2_AVPLL_SCRAMBLE_QUIRK; 545 + 546 + /* audio/video VCOs */ 547 + clk = berlin2_avpll_vco_register(gbase + REG_AVPLLCTL0, "avpll_vcoA", 548 + clk_names[REFCLK], avpll_flags, 0); 549 + if (IS_ERR(clk)) 550 + goto bg2_fail; 551 + 552 + for (n = 0; n < 8; n++) { 553 + clk = berlin2_avpll_channel_register(gbase + REG_AVPLLCTL0, 554 + clk_names[AVPLL_A1 + n], n, "avpll_vcoA", 555 + avpll_flags, 0); 556 + if (IS_ERR(clk)) 557 + goto bg2_fail; 558 + } 559 + 560 + clk = berlin2_avpll_vco_register(gbase + REG_AVPLLCTL31, "avpll_vcoB", 561 + clk_names[REFCLK], BERLIN2_AVPLL_BIT_QUIRK | 562 + avpll_flags, 0); 563 + if (IS_ERR(clk)) 564 + goto bg2_fail; 565 + 566 + for (n = 0; n < 8; n++) { 567 + clk = berlin2_avpll_channel_register(gbase + REG_AVPLLCTL31, 568 + clk_names[AVPLL_B1 + n], n, "avpll_vcoB", 569 + BERLIN2_AVPLL_BIT_QUIRK | avpll_flags, 0); 570 + if (IS_ERR(clk)) 571 + goto bg2_fail; 572 + } 573 + 574 + /* reference clock bypass switches */ 575 + parent_names[0] = clk_names[SYSPLL]; 576 + parent_names[1] = clk_names[REFCLK]; 577 + clk = clk_register_mux(NULL, "syspll_byp", parent_names, 2, 578 + 0, gbase + REG_CLKSWITCH0, 0, 1, 0, &lock); 579 + if (IS_ERR(clk)) 580 + goto bg2_fail; 581 + clk_names[SYSPLL] = __clk_get_name(clk); 582 + 583 + parent_names[0] = clk_names[MEMPLL]; 584 + parent_names[1] = clk_names[REFCLK]; 585 + clk = clk_register_mux(NULL, "mempll_byp", parent_names, 2, 586 + 0, gbase + REG_CLKSWITCH0, 1, 1, 0, &lock); 587 + if (IS_ERR(clk)) 588 + goto bg2_fail; 589 + clk_names[MEMPLL] = __clk_get_name(clk); 590 + 591 + parent_names[0] = clk_names[CPUPLL]; 592 + parent_names[1] = clk_names[REFCLK]; 593 + clk = clk_register_mux(NULL, "cpupll_byp", parent_names, 2, 594 + 0, gbase + REG_CLKSWITCH0, 2, 1, 0, &lock); 595 + if (IS_ERR(clk)) 596 + goto bg2_fail; 597 + clk_names[CPUPLL] = __clk_get_name(clk); 598 + 599 + /* clock muxes */ 600 + parent_names[0] = clk_names[AVPLL_B3]; 601 + parent_names[1] = clk_names[AVPLL_A3]; 602 + clk = clk_register_mux(NULL, clk_names[AUDIO1_PLL], parent_names, 2, 603 + 0, gbase + REG_CLKSELECT2, 29, 1, 0, &lock); 604 + if (IS_ERR(clk)) 605 + goto bg2_fail; 606 + 607 + parent_names[0] = clk_names[VIDEO0_PLL]; 608 + parent_names[1] = clk_names[VIDEO_EXT0]; 609 + clk = clk_register_mux(NULL, clk_names[VIDEO0_IN], parent_names, 2, 610 + 0, gbase + REG_CLKSELECT3, 4, 1, 0, &lock); 611 + if (IS_ERR(clk)) 612 + goto bg2_fail; 613 + 614 + parent_names[0] = clk_names[VIDEO1_PLL]; 615 + parent_names[1] = clk_names[VIDEO_EXT0]; 616 + clk = clk_register_mux(NULL, clk_names[VIDEO1_IN], parent_names, 2, 617 + 0, gbase + REG_CLKSELECT3, 6, 1, 0, &lock); 618 + if (IS_ERR(clk)) 619 + goto bg2_fail; 620 + 621 + parent_names[0] = clk_names[AVPLL_A2]; 622 + parent_names[1] = clk_names[AVPLL_B2]; 623 + clk = clk_register_mux(NULL, clk_names[VIDEO1_PLL], parent_names, 2, 624 + 0, gbase + REG_CLKSELECT3, 7, 1, 0, &lock); 625 + if (IS_ERR(clk)) 626 + goto bg2_fail; 627 + 628 + parent_names[0] = clk_names[VIDEO2_PLL]; 629 + parent_names[1] = clk_names[VIDEO_EXT0]; 630 + clk = clk_register_mux(NULL, clk_names[VIDEO2_IN], parent_names, 2, 631 + 0, gbase + REG_CLKSELECT3, 9, 1, 0, &lock); 632 + if (IS_ERR(clk)) 633 + goto bg2_fail; 634 + 635 + parent_names[0] = clk_names[AVPLL_B1]; 636 + parent_names[1] = clk_names[AVPLL_A5]; 637 + clk = clk_register_mux(NULL, clk_names[VIDEO2_PLL], parent_names, 2, 638 + 0, gbase + REG_CLKSELECT3, 10, 1, 0, &lock); 639 + if (IS_ERR(clk)) 640 + goto bg2_fail; 641 + 642 + /* clock divider cells */ 643 + for (n = 0; n < ARRAY_SIZE(bg2_divs); n++) { 644 + const struct berlin2_div_data *dd = &bg2_divs[n]; 645 + int k; 646 + 647 + for (k = 0; k < dd->num_parents; k++) 648 + parent_names[k] = clk_names[dd->parent_ids[k]]; 649 + 650 + clks[CLKID_SYS + n] = berlin2_div_register(&dd->map, gbase, 651 + dd->name, dd->div_flags, parent_names, 652 + dd->num_parents, dd->flags, &lock); 653 + } 654 + 655 + /* clock gate cells */ 656 + for (n = 0; n < ARRAY_SIZE(bg2_gates); n++) { 657 + const struct berlin2_gate_data *gd = &bg2_gates[n]; 658 + 659 + clks[CLKID_GETH0 + n] = clk_register_gate(NULL, gd->name, 660 + gd->parent_name, gd->flags, gbase + REG_CLKENABLE, 661 + gd->bit_idx, 0, &lock); 662 + } 663 + 664 + /* twdclk is derived from cpu/3 */ 665 + clks[CLKID_TWD] = 666 + clk_register_fixed_factor(NULL, "twd", "cpu", 0, 1, 3); 667 + 668 + /* check for errors on leaf clocks */ 669 + for (n = 0; n < MAX_CLKS; n++) { 670 + if (!IS_ERR(clks[n])) 671 + continue; 672 + 673 + pr_err("%s: Unable to register leaf clock %d\n", 674 + np->full_name, n); 675 + goto bg2_fail; 676 + } 677 + 678 + /* register clk-provider */ 679 + clk_data.clks = clks; 680 + clk_data.clk_num = MAX_CLKS; 681 + of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); 682 + 683 + return; 684 + 685 + bg2_fail: 686 + iounmap(gbase); 687 + } 688 + CLK_OF_DECLARE(berlin2_clock, "marvell,berlin2-chip-ctrl", 689 + berlin2_clock_setup); 690 + CLK_OF_DECLARE(berlin2cd_clock, "marvell,berlin2cd-chip-ctrl", 691 + berlin2_clock_setup);
+389
drivers/clk/berlin/bg2q.c
··· 1 + /* 2 + * Copyright (c) 2014 Marvell Technology Group Ltd. 3 + * 4 + * Alexandre Belloni <alexandre.belloni@free-electrons.com> 5 + * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> 6 + * 7 + * This program is free software; you can redistribute it and/or modify it 8 + * under the terms and conditions of the GNU General Public License, 9 + * version 2, as published by the Free Software Foundation. 10 + * 11 + * This program is distributed in the hope it will be useful, but WITHOUT 12 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 14 + * more details. 15 + * 16 + * You should have received a copy of the GNU General Public License along with 17 + * this program. If not, see <http://www.gnu.org/licenses/>. 18 + */ 19 + 20 + #include <linux/clk.h> 21 + #include <linux/clk-provider.h> 22 + #include <linux/kernel.h> 23 + #include <linux/of.h> 24 + #include <linux/of_address.h> 25 + #include <linux/slab.h> 26 + 27 + #include <dt-bindings/clock/berlin2q.h> 28 + 29 + #include "berlin2-div.h" 30 + #include "berlin2-pll.h" 31 + #include "common.h" 32 + 33 + #define REG_PINMUX0 0x0018 34 + #define REG_PINMUX5 0x002c 35 + #define REG_SYSPLLCTL0 0x0030 36 + #define REG_SYSPLLCTL4 0x0040 37 + #define REG_CLKENABLE 0x00e8 38 + #define REG_CLKSELECT0 0x00ec 39 + #define REG_CLKSELECT1 0x00f0 40 + #define REG_CLKSELECT2 0x00f4 41 + #define REG_CLKSWITCH0 0x00f8 42 + #define REG_CLKSWITCH1 0x00fc 43 + #define REG_SW_GENERIC0 0x0110 44 + #define REG_SW_GENERIC3 0x011c 45 + #define REG_SDIO0XIN_CLKCTL 0x0158 46 + #define REG_SDIO1XIN_CLKCTL 0x015c 47 + 48 + #define MAX_CLKS 27 49 + static struct clk *clks[MAX_CLKS]; 50 + static struct clk_onecell_data clk_data; 51 + static DEFINE_SPINLOCK(lock); 52 + static void __iomem *gbase; 53 + static void __iomem *cpupll_base; 54 + 55 + enum { 56 + REFCLK, 57 + SYSPLL, CPUPLL, 58 + AVPLL_B1, AVPLL_B2, AVPLL_B3, AVPLL_B4, 59 + AVPLL_B5, AVPLL_B6, AVPLL_B7, AVPLL_B8, 60 + }; 61 + 62 + static const char *clk_names[] = { 63 + [REFCLK] = "refclk", 64 + [SYSPLL] = "syspll", 65 + [CPUPLL] = "cpupll", 66 + [AVPLL_B1] = "avpll_b1", 67 + [AVPLL_B2] = "avpll_b2", 68 + [AVPLL_B3] = "avpll_b3", 69 + [AVPLL_B4] = "avpll_b4", 70 + [AVPLL_B5] = "avpll_b5", 71 + [AVPLL_B6] = "avpll_b6", 72 + [AVPLL_B7] = "avpll_b7", 73 + [AVPLL_B8] = "avpll_b8", 74 + }; 75 + 76 + static const struct berlin2_pll_map bg2q_pll_map __initconst = { 77 + .vcodiv = {1, 0, 2, 0, 3, 4, 0, 6, 8}, 78 + .mult = 1, 79 + .fbdiv_shift = 7, 80 + .rfdiv_shift = 2, 81 + .divsel_shift = 9, 82 + }; 83 + 84 + static const u8 default_parent_ids[] = { 85 + SYSPLL, AVPLL_B4, AVPLL_B5, AVPLL_B6, AVPLL_B7, SYSPLL 86 + }; 87 + 88 + static const struct berlin2_div_data bg2q_divs[] __initconst = { 89 + { 90 + .name = "sys", 91 + .parent_ids = default_parent_ids, 92 + .num_parents = ARRAY_SIZE(default_parent_ids), 93 + .map = { 94 + BERLIN2_DIV_GATE(REG_CLKENABLE, 0), 95 + BERLIN2_PLL_SELECT(REG_CLKSELECT0, 0), 96 + BERLIN2_DIV_SELECT(REG_CLKSELECT0, 3), 97 + BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 3), 98 + BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 4), 99 + BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 5), 100 + }, 101 + .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX, 102 + .flags = CLK_IGNORE_UNUSED, 103 + }, 104 + { 105 + .name = "drmfigo", 106 + .parent_ids = default_parent_ids, 107 + .num_parents = ARRAY_SIZE(default_parent_ids), 108 + .map = { 109 + BERLIN2_DIV_GATE(REG_CLKENABLE, 17), 110 + BERLIN2_PLL_SELECT(REG_CLKSELECT0, 6), 111 + BERLIN2_DIV_SELECT(REG_CLKSELECT0, 9), 112 + BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 6), 113 + BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 7), 114 + BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 8), 115 + }, 116 + .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX, 117 + .flags = 0, 118 + }, 119 + { 120 + .name = "cfg", 121 + .parent_ids = default_parent_ids, 122 + .num_parents = ARRAY_SIZE(default_parent_ids), 123 + .map = { 124 + BERLIN2_DIV_GATE(REG_CLKENABLE, 1), 125 + BERLIN2_PLL_SELECT(REG_CLKSELECT0, 12), 126 + BERLIN2_DIV_SELECT(REG_CLKSELECT0, 15), 127 + BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 9), 128 + BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 10), 129 + BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 11), 130 + }, 131 + .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX, 132 + .flags = 0, 133 + }, 134 + { 135 + .name = "gfx2d", 136 + .parent_ids = default_parent_ids, 137 + .num_parents = ARRAY_SIZE(default_parent_ids), 138 + .map = { 139 + BERLIN2_DIV_GATE(REG_CLKENABLE, 4), 140 + BERLIN2_PLL_SELECT(REG_CLKSELECT0, 18), 141 + BERLIN2_DIV_SELECT(REG_CLKSELECT0, 21), 142 + BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 12), 143 + BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 13), 144 + BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 14), 145 + }, 146 + .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX, 147 + .flags = 0, 148 + }, 149 + { 150 + .name = "zsp", 151 + .parent_ids = default_parent_ids, 152 + .num_parents = ARRAY_SIZE(default_parent_ids), 153 + .map = { 154 + BERLIN2_DIV_GATE(REG_CLKENABLE, 6), 155 + BERLIN2_PLL_SELECT(REG_CLKSELECT0, 24), 156 + BERLIN2_DIV_SELECT(REG_CLKSELECT0, 27), 157 + BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 15), 158 + BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 16), 159 + BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 17), 160 + }, 161 + .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX, 162 + .flags = 0, 163 + }, 164 + { 165 + .name = "perif", 166 + .parent_ids = default_parent_ids, 167 + .num_parents = ARRAY_SIZE(default_parent_ids), 168 + .map = { 169 + BERLIN2_DIV_GATE(REG_CLKENABLE, 7), 170 + BERLIN2_PLL_SELECT(REG_CLKSELECT1, 0), 171 + BERLIN2_DIV_SELECT(REG_CLKSELECT1, 3), 172 + BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 18), 173 + BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 19), 174 + BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 20), 175 + }, 176 + .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX, 177 + .flags = CLK_IGNORE_UNUSED, 178 + }, 179 + { 180 + .name = "pcube", 181 + .parent_ids = default_parent_ids, 182 + .num_parents = ARRAY_SIZE(default_parent_ids), 183 + .map = { 184 + BERLIN2_DIV_GATE(REG_CLKENABLE, 2), 185 + BERLIN2_PLL_SELECT(REG_CLKSELECT1, 6), 186 + BERLIN2_DIV_SELECT(REG_CLKSELECT1, 9), 187 + BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 21), 188 + BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 22), 189 + BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 23), 190 + }, 191 + .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX, 192 + .flags = 0, 193 + }, 194 + { 195 + .name = "vscope", 196 + .parent_ids = default_parent_ids, 197 + .num_parents = ARRAY_SIZE(default_parent_ids), 198 + .map = { 199 + BERLIN2_DIV_GATE(REG_CLKENABLE, 3), 200 + BERLIN2_PLL_SELECT(REG_CLKSELECT1, 12), 201 + BERLIN2_DIV_SELECT(REG_CLKSELECT1, 15), 202 + BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 24), 203 + BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 25), 204 + BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 26), 205 + }, 206 + .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX, 207 + .flags = 0, 208 + }, 209 + { 210 + .name = "nfc_ecc", 211 + .parent_ids = default_parent_ids, 212 + .num_parents = ARRAY_SIZE(default_parent_ids), 213 + .map = { 214 + BERLIN2_DIV_GATE(REG_CLKENABLE, 19), 215 + BERLIN2_PLL_SELECT(REG_CLKSELECT1, 18), 216 + BERLIN2_DIV_SELECT(REG_CLKSELECT1, 21), 217 + BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 27), 218 + BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 28), 219 + BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 29), 220 + }, 221 + .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX, 222 + .flags = 0, 223 + }, 224 + { 225 + .name = "vpp", 226 + .parent_ids = default_parent_ids, 227 + .num_parents = ARRAY_SIZE(default_parent_ids), 228 + .map = { 229 + BERLIN2_DIV_GATE(REG_CLKENABLE, 21), 230 + BERLIN2_PLL_SELECT(REG_CLKSELECT1, 24), 231 + BERLIN2_DIV_SELECT(REG_CLKSELECT1, 27), 232 + BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 30), 233 + BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 31), 234 + BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH1, 0), 235 + }, 236 + .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX, 237 + .flags = 0, 238 + }, 239 + { 240 + .name = "app", 241 + .parent_ids = default_parent_ids, 242 + .num_parents = ARRAY_SIZE(default_parent_ids), 243 + .map = { 244 + BERLIN2_DIV_GATE(REG_CLKENABLE, 20), 245 + BERLIN2_PLL_SELECT(REG_CLKSELECT2, 0), 246 + BERLIN2_DIV_SELECT(REG_CLKSELECT2, 3), 247 + BERLIN2_PLL_SWITCH(REG_CLKSWITCH1, 1), 248 + BERLIN2_DIV_SWITCH(REG_CLKSWITCH1, 2), 249 + BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH1, 3), 250 + }, 251 + .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX, 252 + .flags = 0, 253 + }, 254 + { 255 + .name = "sdio0xin", 256 + .parent_ids = default_parent_ids, 257 + .num_parents = ARRAY_SIZE(default_parent_ids), 258 + .map = { 259 + BERLIN2_SINGLE_DIV(REG_SDIO0XIN_CLKCTL), 260 + }, 261 + .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX, 262 + .flags = 0, 263 + }, 264 + { 265 + .name = "sdio1xin", 266 + .parent_ids = default_parent_ids, 267 + .num_parents = ARRAY_SIZE(default_parent_ids), 268 + .map = { 269 + BERLIN2_SINGLE_DIV(REG_SDIO1XIN_CLKCTL), 270 + }, 271 + .div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX, 272 + .flags = 0, 273 + }, 274 + }; 275 + 276 + static const struct berlin2_gate_data bg2q_gates[] __initconst = { 277 + { "gfx2daxi", "perif", 5 }, 278 + { "geth0", "perif", 8 }, 279 + { "sata", "perif", 9 }, 280 + { "ahbapb", "perif", 10, CLK_IGNORE_UNUSED }, 281 + { "usb0", "perif", 11 }, 282 + { "usb1", "perif", 12 }, 283 + { "usb2", "perif", 13 }, 284 + { "usb3", "perif", 14 }, 285 + { "pbridge", "perif", 15, CLK_IGNORE_UNUSED }, 286 + { "sdio", "perif", 16, CLK_IGNORE_UNUSED }, 287 + { "nfc", "perif", 18 }, 288 + { "smemc", "perif", 19 }, 289 + { "pcie", "perif", 22 }, 290 + }; 291 + 292 + static void __init berlin2q_clock_setup(struct device_node *np) 293 + { 294 + const char *parent_names[9]; 295 + struct clk *clk; 296 + int n; 297 + 298 + gbase = of_iomap(np, 0); 299 + if (!gbase) { 300 + pr_err("%s: Unable to map global base\n", np->full_name); 301 + return; 302 + } 303 + 304 + /* BG2Q CPU PLL is not part of global registers */ 305 + cpupll_base = of_iomap(np, 1); 306 + if (!cpupll_base) { 307 + pr_err("%s: Unable to map cpupll base\n", np->full_name); 308 + iounmap(gbase); 309 + return; 310 + } 311 + 312 + /* overwrite default clock names with DT provided ones */ 313 + clk = of_clk_get_by_name(np, clk_names[REFCLK]); 314 + if (!IS_ERR(clk)) { 315 + clk_names[REFCLK] = __clk_get_name(clk); 316 + clk_put(clk); 317 + } 318 + 319 + /* simple register PLLs */ 320 + clk = berlin2_pll_register(&bg2q_pll_map, gbase + REG_SYSPLLCTL0, 321 + clk_names[SYSPLL], clk_names[REFCLK], 0); 322 + if (IS_ERR(clk)) 323 + goto bg2q_fail; 324 + 325 + clk = berlin2_pll_register(&bg2q_pll_map, cpupll_base, 326 + clk_names[CPUPLL], clk_names[REFCLK], 0); 327 + if (IS_ERR(clk)) 328 + goto bg2q_fail; 329 + 330 + /* TODO: add BG2Q AVPLL */ 331 + 332 + /* 333 + * TODO: add reference clock bypass switches: 334 + * memPLLSWBypass, cpuPLLSWBypass, and sysPLLSWBypass 335 + */ 336 + 337 + /* clock divider cells */ 338 + for (n = 0; n < ARRAY_SIZE(bg2q_divs); n++) { 339 + const struct berlin2_div_data *dd = &bg2q_divs[n]; 340 + int k; 341 + 342 + for (k = 0; k < dd->num_parents; k++) 343 + parent_names[k] = clk_names[dd->parent_ids[k]]; 344 + 345 + clks[CLKID_SYS + n] = berlin2_div_register(&dd->map, gbase, 346 + dd->name, dd->div_flags, parent_names, 347 + dd->num_parents, dd->flags, &lock); 348 + } 349 + 350 + /* clock gate cells */ 351 + for (n = 0; n < ARRAY_SIZE(bg2q_gates); n++) { 352 + const struct berlin2_gate_data *gd = &bg2q_gates[n]; 353 + 354 + clks[CLKID_GFX2DAXI + n] = clk_register_gate(NULL, gd->name, 355 + gd->parent_name, gd->flags, gbase + REG_CLKENABLE, 356 + gd->bit_idx, 0, &lock); 357 + } 358 + 359 + /* 360 + * twdclk is derived from cpu/3 361 + * TODO: use cpupll until cpuclk is not available 362 + */ 363 + clks[CLKID_TWD] = 364 + clk_register_fixed_factor(NULL, "twd", clk_names[CPUPLL], 365 + 0, 1, 3); 366 + 367 + /* check for errors on leaf clocks */ 368 + for (n = 0; n < MAX_CLKS; n++) { 369 + if (!IS_ERR(clks[n])) 370 + continue; 371 + 372 + pr_err("%s: Unable to register leaf clock %d\n", 373 + np->full_name, n); 374 + goto bg2q_fail; 375 + } 376 + 377 + /* register clk-provider */ 378 + clk_data.clks = clks; 379 + clk_data.clk_num = MAX_CLKS; 380 + of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); 381 + 382 + return; 383 + 384 + bg2q_fail: 385 + iounmap(cpupll_base); 386 + iounmap(gbase); 387 + } 388 + CLK_OF_DECLARE(berlin2q_clock, "marvell,berlin2q-chip-ctrl", 389 + berlin2q_clock_setup);
+29
drivers/clk/berlin/common.h
··· 1 + /* 2 + * Copyright (c) 2014 Marvell Technology Group Ltd. 3 + * 4 + * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> 5 + * Alexandre Belloni <alexandre.belloni@free-electrons.com> 6 + * 7 + * This program is free software; you can redistribute it and/or modify it 8 + * under the terms and conditions of the GNU General Public License, 9 + * version 2, as published by the Free Software Foundation. 10 + * 11 + * This program is distributed in the hope it will be useful, but WITHOUT 12 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 14 + * more details. 15 + * 16 + * You should have received a copy of the GNU General Public License along with 17 + * this program. If not, see <http://www.gnu.org/licenses/>. 18 + */ 19 + #ifndef __BERLIN2_COMMON_H 20 + #define __BERLIN2_COMMON_H 21 + 22 + struct berlin2_gate_data { 23 + const char *name; 24 + const char *parent_name; 25 + u8 bit_idx; 26 + unsigned long flags; 27 + }; 28 + 29 + #endif /* BERLIN2_COMMON_H */
+615
drivers/clk/clk-axm5516.c
··· 1 + /* 2 + * drivers/clk/clk-axm5516.c 3 + * 4 + * Provides clock implementations for three different types of clock devices on 5 + * the Axxia device: PLL clock, a clock divider and a clock mux. 6 + * 7 + * Copyright (C) 2014 LSI Corporation 8 + * 9 + * This program is free software; you can redistribute it and/or modify it 10 + * under the terms of the GNU General Public License version 2 as published by 11 + * the Free Software Foundation. 12 + */ 13 + #include <linux/module.h> 14 + #include <linux/kernel.h> 15 + #include <linux/slab.h> 16 + #include <linux/platform_device.h> 17 + #include <linux/of.h> 18 + #include <linux/of_address.h> 19 + #include <linux/clk-provider.h> 20 + #include <linux/regmap.h> 21 + #include <dt-bindings/clock/lsi,axm5516-clks.h> 22 + 23 + 24 + /** 25 + * struct axxia_clk - Common struct to all Axxia clocks. 26 + * @hw: clk_hw for the common clk framework 27 + * @regmap: Regmap for the clock control registers 28 + */ 29 + struct axxia_clk { 30 + struct clk_hw hw; 31 + struct regmap *regmap; 32 + }; 33 + #define to_axxia_clk(_hw) container_of(_hw, struct axxia_clk, hw) 34 + 35 + /** 36 + * struct axxia_pllclk - Axxia PLL generated clock. 37 + * @aclk: Common struct 38 + * @reg: Offset into regmap for PLL control register 39 + */ 40 + struct axxia_pllclk { 41 + struct axxia_clk aclk; 42 + u32 reg; 43 + }; 44 + #define to_axxia_pllclk(_aclk) container_of(_aclk, struct axxia_pllclk, aclk) 45 + 46 + /** 47 + * axxia_pllclk_recalc - Calculate the PLL generated clock rate given the 48 + * parent clock rate. 49 + */ 50 + static unsigned long 51 + axxia_pllclk_recalc(struct clk_hw *hw, unsigned long parent_rate) 52 + { 53 + struct axxia_clk *aclk = to_axxia_clk(hw); 54 + struct axxia_pllclk *pll = to_axxia_pllclk(aclk); 55 + unsigned long rate, fbdiv, refdiv, postdiv; 56 + u32 control; 57 + 58 + regmap_read(aclk->regmap, pll->reg, &control); 59 + postdiv = ((control >> 0) & 0xf) + 1; 60 + fbdiv = ((control >> 4) & 0xfff) + 3; 61 + refdiv = ((control >> 16) & 0x1f) + 1; 62 + rate = (parent_rate / (refdiv * postdiv)) * fbdiv; 63 + 64 + return rate; 65 + } 66 + 67 + static const struct clk_ops axxia_pllclk_ops = { 68 + .recalc_rate = axxia_pllclk_recalc, 69 + }; 70 + 71 + /** 72 + * struct axxia_divclk - Axxia clock divider 73 + * @aclk: Common struct 74 + * @reg: Offset into regmap for PLL control register 75 + * @shift: Bit position for divider value 76 + * @width: Number of bits in divider value 77 + */ 78 + struct axxia_divclk { 79 + struct axxia_clk aclk; 80 + u32 reg; 81 + u32 shift; 82 + u32 width; 83 + }; 84 + #define to_axxia_divclk(_aclk) container_of(_aclk, struct axxia_divclk, aclk) 85 + 86 + /** 87 + * axxia_divclk_recalc_rate - Calculate clock divider output rage 88 + */ 89 + static unsigned long 90 + axxia_divclk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) 91 + { 92 + struct axxia_clk *aclk = to_axxia_clk(hw); 93 + struct axxia_divclk *divclk = to_axxia_divclk(aclk); 94 + u32 ctrl, div; 95 + 96 + regmap_read(aclk->regmap, divclk->reg, &ctrl); 97 + div = 1 + ((ctrl >> divclk->shift) & ((1 << divclk->width)-1)); 98 + 99 + return parent_rate / div; 100 + } 101 + 102 + static const struct clk_ops axxia_divclk_ops = { 103 + .recalc_rate = axxia_divclk_recalc_rate, 104 + }; 105 + 106 + /** 107 + * struct axxia_clkmux - Axxia clock mux 108 + * @aclk: Common struct 109 + * @reg: Offset into regmap for PLL control register 110 + * @shift: Bit position for selection value 111 + * @width: Number of bits in selection value 112 + */ 113 + struct axxia_clkmux { 114 + struct axxia_clk aclk; 115 + u32 reg; 116 + u32 shift; 117 + u32 width; 118 + }; 119 + #define to_axxia_clkmux(_aclk) container_of(_aclk, struct axxia_clkmux, aclk) 120 + 121 + /** 122 + * axxia_clkmux_get_parent - Return the index of selected parent clock 123 + */ 124 + static u8 axxia_clkmux_get_parent(struct clk_hw *hw) 125 + { 126 + struct axxia_clk *aclk = to_axxia_clk(hw); 127 + struct axxia_clkmux *mux = to_axxia_clkmux(aclk); 128 + u32 ctrl, parent; 129 + 130 + regmap_read(aclk->regmap, mux->reg, &ctrl); 131 + parent = (ctrl >> mux->shift) & ((1 << mux->width) - 1); 132 + 133 + return (u8) parent; 134 + } 135 + 136 + static const struct clk_ops axxia_clkmux_ops = { 137 + .get_parent = axxia_clkmux_get_parent, 138 + }; 139 + 140 + 141 + /* 142 + * PLLs 143 + */ 144 + 145 + static struct axxia_pllclk clk_fab_pll = { 146 + .aclk.hw.init = &(struct clk_init_data){ 147 + .name = "clk_fab_pll", 148 + .parent_names = (const char *[]){ 149 + "clk_ref0" 150 + }, 151 + .num_parents = 1, 152 + .ops = &axxia_pllclk_ops, 153 + }, 154 + .reg = 0x01800, 155 + }; 156 + 157 + static struct axxia_pllclk clk_cpu_pll = { 158 + .aclk.hw.init = &(struct clk_init_data){ 159 + .name = "clk_cpu_pll", 160 + .parent_names = (const char *[]){ 161 + "clk_ref0" 162 + }, 163 + .num_parents = 1, 164 + .ops = &axxia_pllclk_ops, 165 + }, 166 + .reg = 0x02000, 167 + }; 168 + 169 + static struct axxia_pllclk clk_sys_pll = { 170 + .aclk.hw.init = &(struct clk_init_data){ 171 + .name = "clk_sys_pll", 172 + .parent_names = (const char *[]){ 173 + "clk_ref0" 174 + }, 175 + .num_parents = 1, 176 + .ops = &axxia_pllclk_ops, 177 + }, 178 + .reg = 0x02800, 179 + }; 180 + 181 + static struct axxia_pllclk clk_sm0_pll = { 182 + .aclk.hw.init = &(struct clk_init_data){ 183 + .name = "clk_sm0_pll", 184 + .parent_names = (const char *[]){ 185 + "clk_ref2" 186 + }, 187 + .num_parents = 1, 188 + .ops = &axxia_pllclk_ops, 189 + }, 190 + .reg = 0x03000, 191 + }; 192 + 193 + static struct axxia_pllclk clk_sm1_pll = { 194 + .aclk.hw.init = &(struct clk_init_data){ 195 + .name = "clk_sm1_pll", 196 + .parent_names = (const char *[]){ 197 + "clk_ref1" 198 + }, 199 + .num_parents = 1, 200 + .ops = &axxia_pllclk_ops, 201 + }, 202 + .reg = 0x03800, 203 + }; 204 + 205 + /* 206 + * Clock dividers 207 + */ 208 + 209 + static struct axxia_divclk clk_cpu0_div = { 210 + .aclk.hw.init = &(struct clk_init_data){ 211 + .name = "clk_cpu0_div", 212 + .parent_names = (const char *[]){ 213 + "clk_cpu_pll" 214 + }, 215 + .num_parents = 1, 216 + .ops = &axxia_divclk_ops, 217 + }, 218 + .reg = 0x10008, 219 + .shift = 0, 220 + .width = 4, 221 + }; 222 + 223 + static struct axxia_divclk clk_cpu1_div = { 224 + .aclk.hw.init = &(struct clk_init_data){ 225 + .name = "clk_cpu1_div", 226 + .parent_names = (const char *[]){ 227 + "clk_cpu_pll" 228 + }, 229 + .num_parents = 1, 230 + .ops = &axxia_divclk_ops, 231 + }, 232 + .reg = 0x10008, 233 + .shift = 4, 234 + .width = 4, 235 + }; 236 + 237 + static struct axxia_divclk clk_cpu2_div = { 238 + .aclk.hw.init = &(struct clk_init_data){ 239 + .name = "clk_cpu2_div", 240 + .parent_names = (const char *[]){ 241 + "clk_cpu_pll" 242 + }, 243 + .num_parents = 1, 244 + .ops = &axxia_divclk_ops, 245 + }, 246 + .reg = 0x10008, 247 + .shift = 8, 248 + .width = 4, 249 + }; 250 + 251 + static struct axxia_divclk clk_cpu3_div = { 252 + .aclk.hw.init = &(struct clk_init_data){ 253 + .name = "clk_cpu3_div", 254 + .parent_names = (const char *[]){ 255 + "clk_cpu_pll" 256 + }, 257 + .num_parents = 1, 258 + .ops = &axxia_divclk_ops, 259 + }, 260 + .reg = 0x10008, 261 + .shift = 12, 262 + .width = 4, 263 + }; 264 + 265 + static struct axxia_divclk clk_nrcp_div = { 266 + .aclk.hw.init = &(struct clk_init_data){ 267 + .name = "clk_nrcp_div", 268 + .parent_names = (const char *[]){ 269 + "clk_sys_pll" 270 + }, 271 + .num_parents = 1, 272 + .ops = &axxia_divclk_ops, 273 + }, 274 + .reg = 0x1000c, 275 + .shift = 0, 276 + .width = 4, 277 + }; 278 + 279 + static struct axxia_divclk clk_sys_div = { 280 + .aclk.hw.init = &(struct clk_init_data){ 281 + .name = "clk_sys_div", 282 + .parent_names = (const char *[]){ 283 + "clk_sys_pll" 284 + }, 285 + .num_parents = 1, 286 + .ops = &axxia_divclk_ops, 287 + }, 288 + .reg = 0x1000c, 289 + .shift = 4, 290 + .width = 4, 291 + }; 292 + 293 + static struct axxia_divclk clk_fab_div = { 294 + .aclk.hw.init = &(struct clk_init_data){ 295 + .name = "clk_fab_div", 296 + .parent_names = (const char *[]){ 297 + "clk_fab_pll" 298 + }, 299 + .num_parents = 1, 300 + .ops = &axxia_divclk_ops, 301 + }, 302 + .reg = 0x1000c, 303 + .shift = 8, 304 + .width = 4, 305 + }; 306 + 307 + static struct axxia_divclk clk_per_div = { 308 + .aclk.hw.init = &(struct clk_init_data){ 309 + .name = "clk_per_div", 310 + .parent_names = (const char *[]){ 311 + "clk_sm1_pll" 312 + }, 313 + .num_parents = 1, 314 + .flags = CLK_IS_BASIC, 315 + .ops = &axxia_divclk_ops, 316 + }, 317 + .reg = 0x1000c, 318 + .shift = 12, 319 + .width = 4, 320 + }; 321 + 322 + static struct axxia_divclk clk_mmc_div = { 323 + .aclk.hw.init = &(struct clk_init_data){ 324 + .name = "clk_mmc_div", 325 + .parent_names = (const char *[]){ 326 + "clk_sm1_pll" 327 + }, 328 + .num_parents = 1, 329 + .flags = CLK_IS_BASIC, 330 + .ops = &axxia_divclk_ops, 331 + }, 332 + .reg = 0x1000c, 333 + .shift = 16, 334 + .width = 4, 335 + }; 336 + 337 + /* 338 + * Clock MUXes 339 + */ 340 + 341 + static struct axxia_clkmux clk_cpu0_mux = { 342 + .aclk.hw.init = &(struct clk_init_data){ 343 + .name = "clk_cpu0", 344 + .parent_names = (const char *[]){ 345 + "clk_ref0", 346 + "clk_cpu_pll", 347 + "clk_cpu0_div", 348 + "clk_cpu0_div" 349 + }, 350 + .num_parents = 4, 351 + .ops = &axxia_clkmux_ops, 352 + }, 353 + .reg = 0x10000, 354 + .shift = 0, 355 + .width = 2, 356 + }; 357 + 358 + static struct axxia_clkmux clk_cpu1_mux = { 359 + .aclk.hw.init = &(struct clk_init_data){ 360 + .name = "clk_cpu1", 361 + .parent_names = (const char *[]){ 362 + "clk_ref0", 363 + "clk_cpu_pll", 364 + "clk_cpu1_div", 365 + "clk_cpu1_div" 366 + }, 367 + .num_parents = 4, 368 + .ops = &axxia_clkmux_ops, 369 + }, 370 + .reg = 0x10000, 371 + .shift = 2, 372 + .width = 2, 373 + }; 374 + 375 + static struct axxia_clkmux clk_cpu2_mux = { 376 + .aclk.hw.init = &(struct clk_init_data){ 377 + .name = "clk_cpu2", 378 + .parent_names = (const char *[]){ 379 + "clk_ref0", 380 + "clk_cpu_pll", 381 + "clk_cpu2_div", 382 + "clk_cpu2_div" 383 + }, 384 + .num_parents = 4, 385 + .ops = &axxia_clkmux_ops, 386 + }, 387 + .reg = 0x10000, 388 + .shift = 4, 389 + .width = 2, 390 + }; 391 + 392 + static struct axxia_clkmux clk_cpu3_mux = { 393 + .aclk.hw.init = &(struct clk_init_data){ 394 + .name = "clk_cpu3", 395 + .parent_names = (const char *[]){ 396 + "clk_ref0", 397 + "clk_cpu_pll", 398 + "clk_cpu3_div", 399 + "clk_cpu3_div" 400 + }, 401 + .num_parents = 4, 402 + .ops = &axxia_clkmux_ops, 403 + }, 404 + .reg = 0x10000, 405 + .shift = 6, 406 + .width = 2, 407 + }; 408 + 409 + static struct axxia_clkmux clk_nrcp_mux = { 410 + .aclk.hw.init = &(struct clk_init_data){ 411 + .name = "clk_nrcp", 412 + .parent_names = (const char *[]){ 413 + "clk_ref0", 414 + "clk_sys_pll", 415 + "clk_nrcp_div", 416 + "clk_nrcp_div" 417 + }, 418 + .num_parents = 4, 419 + .ops = &axxia_clkmux_ops, 420 + }, 421 + .reg = 0x10004, 422 + .shift = 0, 423 + .width = 2, 424 + }; 425 + 426 + static struct axxia_clkmux clk_sys_mux = { 427 + .aclk.hw.init = &(struct clk_init_data){ 428 + .name = "clk_sys", 429 + .parent_names = (const char *[]){ 430 + "clk_ref0", 431 + "clk_sys_pll", 432 + "clk_sys_div", 433 + "clk_sys_div" 434 + }, 435 + .num_parents = 4, 436 + .ops = &axxia_clkmux_ops, 437 + }, 438 + .reg = 0x10004, 439 + .shift = 2, 440 + .width = 2, 441 + }; 442 + 443 + static struct axxia_clkmux clk_fab_mux = { 444 + .aclk.hw.init = &(struct clk_init_data){ 445 + .name = "clk_fab", 446 + .parent_names = (const char *[]){ 447 + "clk_ref0", 448 + "clk_fab_pll", 449 + "clk_fab_div", 450 + "clk_fab_div" 451 + }, 452 + .num_parents = 4, 453 + .ops = &axxia_clkmux_ops, 454 + }, 455 + .reg = 0x10004, 456 + .shift = 4, 457 + .width = 2, 458 + }; 459 + 460 + static struct axxia_clkmux clk_per_mux = { 461 + .aclk.hw.init = &(struct clk_init_data){ 462 + .name = "clk_per", 463 + .parent_names = (const char *[]){ 464 + "clk_ref1", 465 + "clk_per_div" 466 + }, 467 + .num_parents = 2, 468 + .ops = &axxia_clkmux_ops, 469 + }, 470 + .reg = 0x10004, 471 + .shift = 6, 472 + .width = 1, 473 + }; 474 + 475 + static struct axxia_clkmux clk_mmc_mux = { 476 + .aclk.hw.init = &(struct clk_init_data){ 477 + .name = "clk_mmc", 478 + .parent_names = (const char *[]){ 479 + "clk_ref1", 480 + "clk_mmc_div" 481 + }, 482 + .num_parents = 2, 483 + .ops = &axxia_clkmux_ops, 484 + }, 485 + .reg = 0x10004, 486 + .shift = 9, 487 + .width = 1, 488 + }; 489 + 490 + /* Table of all supported clocks indexed by the clock identifiers from the 491 + * device tree binding 492 + */ 493 + static struct axxia_clk *axmclk_clocks[] = { 494 + [AXXIA_CLK_FAB_PLL] = &clk_fab_pll.aclk, 495 + [AXXIA_CLK_CPU_PLL] = &clk_cpu_pll.aclk, 496 + [AXXIA_CLK_SYS_PLL] = &clk_sys_pll.aclk, 497 + [AXXIA_CLK_SM0_PLL] = &clk_sm0_pll.aclk, 498 + [AXXIA_CLK_SM1_PLL] = &clk_sm1_pll.aclk, 499 + [AXXIA_CLK_FAB_DIV] = &clk_fab_div.aclk, 500 + [AXXIA_CLK_SYS_DIV] = &clk_sys_div.aclk, 501 + [AXXIA_CLK_NRCP_DIV] = &clk_nrcp_div.aclk, 502 + [AXXIA_CLK_CPU0_DIV] = &clk_cpu0_div.aclk, 503 + [AXXIA_CLK_CPU1_DIV] = &clk_cpu1_div.aclk, 504 + [AXXIA_CLK_CPU2_DIV] = &clk_cpu2_div.aclk, 505 + [AXXIA_CLK_CPU3_DIV] = &clk_cpu3_div.aclk, 506 + [AXXIA_CLK_PER_DIV] = &clk_per_div.aclk, 507 + [AXXIA_CLK_MMC_DIV] = &clk_mmc_div.aclk, 508 + [AXXIA_CLK_FAB] = &clk_fab_mux.aclk, 509 + [AXXIA_CLK_SYS] = &clk_sys_mux.aclk, 510 + [AXXIA_CLK_NRCP] = &clk_nrcp_mux.aclk, 511 + [AXXIA_CLK_CPU0] = &clk_cpu0_mux.aclk, 512 + [AXXIA_CLK_CPU1] = &clk_cpu1_mux.aclk, 513 + [AXXIA_CLK_CPU2] = &clk_cpu2_mux.aclk, 514 + [AXXIA_CLK_CPU3] = &clk_cpu3_mux.aclk, 515 + [AXXIA_CLK_PER] = &clk_per_mux.aclk, 516 + [AXXIA_CLK_MMC] = &clk_mmc_mux.aclk, 517 + }; 518 + 519 + static const struct regmap_config axmclk_regmap_config = { 520 + .reg_bits = 32, 521 + .reg_stride = 4, 522 + .val_bits = 32, 523 + .max_register = 0x1fffc, 524 + .fast_io = true, 525 + }; 526 + 527 + static const struct of_device_id axmclk_match_table[] = { 528 + { .compatible = "lsi,axm5516-clks" }, 529 + { } 530 + }; 531 + MODULE_DEVICE_TABLE(of, axmclk_match_table); 532 + 533 + struct axmclk_priv { 534 + struct clk_onecell_data onecell; 535 + struct clk *clks[]; 536 + }; 537 + 538 + static int axmclk_probe(struct platform_device *pdev) 539 + { 540 + void __iomem *base; 541 + struct resource *res; 542 + int i, ret; 543 + struct device *dev = &pdev->dev; 544 + struct clk *clk; 545 + struct regmap *regmap; 546 + size_t num_clks; 547 + struct axmclk_priv *priv; 548 + 549 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 550 + base = devm_ioremap_resource(dev, res); 551 + if (IS_ERR(base)) 552 + return PTR_ERR(base); 553 + 554 + regmap = devm_regmap_init_mmio(dev, base, &axmclk_regmap_config); 555 + if (IS_ERR(regmap)) 556 + return PTR_ERR(regmap); 557 + 558 + num_clks = ARRAY_SIZE(axmclk_clocks); 559 + pr_info("axmclk: supporting %u clocks\n", num_clks); 560 + priv = devm_kzalloc(dev, sizeof(*priv) + sizeof(*priv->clks) * num_clks, 561 + GFP_KERNEL); 562 + if (!priv) 563 + return -ENOMEM; 564 + 565 + priv->onecell.clks = priv->clks; 566 + priv->onecell.clk_num = num_clks; 567 + 568 + /* Update each entry with the allocated regmap and register the clock 569 + * with the common clock framework 570 + */ 571 + for (i = 0; i < num_clks; i++) { 572 + axmclk_clocks[i]->regmap = regmap; 573 + clk = devm_clk_register(dev, &axmclk_clocks[i]->hw); 574 + if (IS_ERR(clk)) 575 + return PTR_ERR(clk); 576 + priv->clks[i] = clk; 577 + } 578 + 579 + ret = of_clk_add_provider(dev->of_node, 580 + of_clk_src_onecell_get, &priv->onecell); 581 + 582 + return ret; 583 + } 584 + 585 + static int axmclk_remove(struct platform_device *pdev) 586 + { 587 + of_clk_del_provider(pdev->dev.of_node); 588 + return 0; 589 + } 590 + 591 + static struct platform_driver axmclk_driver = { 592 + .probe = axmclk_probe, 593 + .remove = axmclk_remove, 594 + .driver = { 595 + .name = "clk-axm5516", 596 + .owner = THIS_MODULE, 597 + .of_match_table = axmclk_match_table, 598 + }, 599 + }; 600 + 601 + static int __init axmclk_init(void) 602 + { 603 + return platform_driver_register(&axmclk_driver); 604 + } 605 + core_initcall(axmclk_init); 606 + 607 + static void __exit axmclk_exit(void) 608 + { 609 + platform_driver_unregister(&axmclk_driver); 610 + } 611 + module_exit(axmclk_exit); 612 + 613 + MODULE_DESCRIPTION("AXM5516 clock driver"); 614 + MODULE_LICENSE("GPL v2"); 615 + MODULE_ALIAS("platform:clk-axm5516");
+89 -4
drivers/clk/clk-divider.c
··· 43 43 return maxdiv; 44 44 } 45 45 46 + static unsigned int _get_table_mindiv(const struct clk_div_table *table) 47 + { 48 + unsigned int mindiv = UINT_MAX; 49 + const struct clk_div_table *clkt; 50 + 51 + for (clkt = table; clkt->div; clkt++) 52 + if (clkt->div < mindiv) 53 + mindiv = clkt->div; 54 + return mindiv; 55 + } 56 + 46 57 static unsigned int _get_maxdiv(struct clk_divider *divider) 47 58 { 48 59 if (divider->flags & CLK_DIVIDER_ONE_BASED) ··· 173 162 return up; 174 163 } 175 164 165 + static int _round_down_table(const struct clk_div_table *table, int div) 166 + { 167 + const struct clk_div_table *clkt; 168 + int down = _get_table_mindiv(table); 169 + 170 + for (clkt = table; clkt->div; clkt++) { 171 + if (clkt->div == div) 172 + return clkt->div; 173 + else if (clkt->div > div) 174 + continue; 175 + 176 + if ((div - clkt->div) < (div - down)) 177 + down = clkt->div; 178 + } 179 + 180 + return down; 181 + } 182 + 176 183 static int _div_round_up(struct clk_divider *divider, 177 184 unsigned long parent_rate, unsigned long rate) 178 185 { ··· 200 171 div = __roundup_pow_of_two(div); 201 172 if (divider->table) 202 173 div = _round_up_table(divider->table, div); 174 + 175 + return div; 176 + } 177 + 178 + static int _div_round_closest(struct clk_divider *divider, 179 + unsigned long parent_rate, unsigned long rate) 180 + { 181 + int up, down, div; 182 + 183 + up = down = div = DIV_ROUND_CLOSEST(parent_rate, rate); 184 + 185 + if (divider->flags & CLK_DIVIDER_POWER_OF_TWO) { 186 + up = __roundup_pow_of_two(div); 187 + down = __rounddown_pow_of_two(div); 188 + } else if (divider->table) { 189 + up = _round_up_table(divider->table, div); 190 + down = _round_down_table(divider->table, div); 191 + } 192 + 193 + return (up - div) <= (div - down) ? up : down; 194 + } 195 + 196 + static int _div_round(struct clk_divider *divider, unsigned long parent_rate, 197 + unsigned long rate) 198 + { 199 + if (divider->flags & CLK_DIVIDER_ROUND_CLOSEST) 200 + return _div_round_closest(divider, parent_rate, rate); 201 + 202 + return _div_round_up(divider, parent_rate, rate); 203 + } 204 + 205 + static bool _is_best_div(struct clk_divider *divider, 206 + unsigned long rate, unsigned long now, unsigned long best) 207 + { 208 + if (divider->flags & CLK_DIVIDER_ROUND_CLOSEST) 209 + return abs(rate - now) < abs(rate - best); 210 + 211 + return now <= rate && now > best; 212 + } 213 + 214 + static int _next_div(struct clk_divider *divider, int div) 215 + { 216 + div++; 217 + 218 + if (divider->flags & CLK_DIVIDER_POWER_OF_TWO) 219 + return __roundup_pow_of_two(div); 220 + if (divider->table) 221 + return _round_up_table(divider->table, div); 203 222 204 223 return div; 205 224 } ··· 267 190 268 191 if (!(__clk_get_flags(hw->clk) & CLK_SET_RATE_PARENT)) { 269 192 parent_rate = *best_parent_rate; 270 - bestdiv = _div_round_up(divider, parent_rate, rate); 193 + bestdiv = _div_round(divider, parent_rate, rate); 271 194 bestdiv = bestdiv == 0 ? 1 : bestdiv; 272 195 bestdiv = bestdiv > maxdiv ? maxdiv : bestdiv; 273 196 return bestdiv; ··· 279 202 */ 280 203 maxdiv = min(ULONG_MAX / rate, maxdiv); 281 204 282 - for (i = 1; i <= maxdiv; i++) { 205 + for (i = 1; i <= maxdiv; i = _next_div(divider, i)) { 283 206 if (!_is_valid_div(divider, i)) 284 207 continue; 285 208 if (rate * i == parent_rate_saved) { ··· 294 217 parent_rate = __clk_round_rate(__clk_get_parent(hw->clk), 295 218 MULT_ROUND_UP(rate, i)); 296 219 now = DIV_ROUND_UP(parent_rate, i); 297 - if (now <= rate && now > best) { 220 + if (_is_best_div(divider, rate, now, best)) { 298 221 bestdiv = i; 299 222 best = now; 300 223 *best_parent_rate = parent_rate; ··· 361 284 }; 362 285 EXPORT_SYMBOL_GPL(clk_divider_ops); 363 286 287 + const struct clk_ops clk_divider_ro_ops = { 288 + .recalc_rate = clk_divider_recalc_rate, 289 + }; 290 + EXPORT_SYMBOL_GPL(clk_divider_ro_ops); 291 + 364 292 static struct clk *_register_divider(struct device *dev, const char *name, 365 293 const char *parent_name, unsigned long flags, 366 294 void __iomem *reg, u8 shift, u8 width, ··· 391 309 } 392 310 393 311 init.name = name; 394 - init.ops = &clk_divider_ops; 312 + if (clk_divider_flags & CLK_DIVIDER_READ_ONLY) 313 + init.ops = &clk_divider_ro_ops; 314 + else 315 + init.ops = &clk_divider_ops; 395 316 init.flags = flags | CLK_IS_BASIC; 396 317 init.parent_names = (parent_name ? &parent_name: NULL); 397 318 init.num_parents = (parent_name ? 1 : 0);
+62 -26
drivers/clk/clk-s2mps11.c
··· 1 1 /* 2 2 * clk-s2mps11.c - Clock driver for S2MPS11. 3 3 * 4 - * Copyright (C) 2013 Samsung Electornics 4 + * Copyright (C) 2013,2014 Samsung Electornics 5 5 * 6 6 * This program is free software; you can redistribute it and/or modify it 7 7 * under the terms of the GNU General Public License as published by the ··· 13 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 14 * GNU General Public License for more details. 15 15 * 16 - * You should have received a copy of the GNU General Public License 17 - * along with this program; if not, write to the Free Software 18 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 - * 20 16 */ 21 17 22 18 #include <linux/module.h> ··· 23 27 #include <linux/clk-provider.h> 24 28 #include <linux/platform_device.h> 25 29 #include <linux/mfd/samsung/s2mps11.h> 30 + #include <linux/mfd/samsung/s2mps14.h> 26 31 #include <linux/mfd/samsung/s5m8767.h> 27 32 #include <linux/mfd/samsung/core.h> 28 33 ··· 41 44 42 45 struct s2mps11_clk { 43 46 struct sec_pmic_dev *iodev; 47 + struct device_node *clk_np; 44 48 struct clk_hw hw; 45 49 struct clk *clk; 46 50 struct clk_lookup *lookup; ··· 123 125 }, 124 126 }; 125 127 126 - static struct device_node *s2mps11_clk_parse_dt(struct platform_device *pdev) 128 + static struct clk_init_data s2mps14_clks_init[S2MPS11_CLKS_NUM] = { 129 + [S2MPS11_CLK_AP] = { 130 + .name = "s2mps14_ap", 131 + .ops = &s2mps11_clk_ops, 132 + .flags = CLK_IS_ROOT, 133 + }, 134 + [S2MPS11_CLK_BT] = { 135 + .name = "s2mps14_bt", 136 + .ops = &s2mps11_clk_ops, 137 + .flags = CLK_IS_ROOT, 138 + }, 139 + }; 140 + 141 + static struct device_node *s2mps11_clk_parse_dt(struct platform_device *pdev, 142 + struct clk_init_data *clks_init) 127 143 { 128 144 struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent); 129 145 struct device_node *clk_np; ··· 152 140 return ERR_PTR(-EINVAL); 153 141 } 154 142 155 - clk_table = devm_kzalloc(&pdev->dev, sizeof(struct clk *) * 156 - S2MPS11_CLKS_NUM, GFP_KERNEL); 157 - if (!clk_table) 158 - return ERR_PTR(-ENOMEM); 159 - 160 - for (i = 0; i < S2MPS11_CLKS_NUM; i++) 143 + for (i = 0; i < S2MPS11_CLKS_NUM; i++) { 144 + if (!clks_init[i].name) 145 + continue; /* Skip clocks not present in some devices */ 161 146 of_property_read_string_index(clk_np, "clock-output-names", i, 162 - &s2mps11_clks_init[i].name); 147 + &clks_init[i].name); 148 + } 163 149 164 150 return clk_np; 165 151 } ··· 166 156 { 167 157 struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent); 168 158 struct s2mps11_clk *s2mps11_clks, *s2mps11_clk; 169 - struct device_node *clk_np = NULL; 170 159 unsigned int s2mps11_reg; 160 + struct clk_init_data *clks_init; 171 161 int i, ret = 0; 172 162 u32 val; 173 163 ··· 178 168 179 169 s2mps11_clk = s2mps11_clks; 180 170 181 - clk_np = s2mps11_clk_parse_dt(pdev); 182 - if (IS_ERR(clk_np)) 183 - return PTR_ERR(clk_np); 171 + clk_table = devm_kzalloc(&pdev->dev, sizeof(struct clk *) * 172 + S2MPS11_CLKS_NUM, GFP_KERNEL); 173 + if (!clk_table) 174 + return -ENOMEM; 184 175 185 176 switch(platform_get_device_id(pdev)->driver_data) { 186 177 case S2MPS11X: 187 178 s2mps11_reg = S2MPS11_REG_RTC_CTRL; 179 + clks_init = s2mps11_clks_init; 180 + break; 181 + case S2MPS14X: 182 + s2mps11_reg = S2MPS14_REG_RTCCTRL; 183 + clks_init = s2mps14_clks_init; 188 184 break; 189 185 case S5M8767X: 190 186 s2mps11_reg = S5M8767_REG_CTRL1; 187 + clks_init = s2mps11_clks_init; 191 188 break; 192 189 default: 193 190 dev_err(&pdev->dev, "Invalid device type\n"); 194 191 return -EINVAL; 195 192 }; 196 193 194 + /* Store clocks of_node in first element of s2mps11_clks array */ 195 + s2mps11_clks->clk_np = s2mps11_clk_parse_dt(pdev, clks_init); 196 + if (IS_ERR(s2mps11_clks->clk_np)) 197 + return PTR_ERR(s2mps11_clks->clk_np); 198 + 197 199 for (i = 0; i < S2MPS11_CLKS_NUM; i++, s2mps11_clk++) { 200 + if (!clks_init[i].name) 201 + continue; /* Skip clocks not present in some devices */ 198 202 s2mps11_clk->iodev = iodev; 199 - s2mps11_clk->hw.init = &s2mps11_clks_init[i]; 203 + s2mps11_clk->hw.init = &clks_init[i]; 200 204 s2mps11_clk->mask = 1 << i; 201 205 s2mps11_clk->reg = s2mps11_reg; 202 206 ··· 243 219 clkdev_add(s2mps11_clk->lookup); 244 220 } 245 221 246 - if (clk_table) { 247 - for (i = 0; i < S2MPS11_CLKS_NUM; i++) 248 - clk_table[i] = s2mps11_clks[i].clk; 249 - 250 - clk_data.clks = clk_table; 251 - clk_data.clk_num = S2MPS11_CLKS_NUM; 252 - of_clk_add_provider(clk_np, of_clk_src_onecell_get, &clk_data); 222 + for (i = 0; i < S2MPS11_CLKS_NUM; i++) { 223 + /* Skip clocks not present on S2MPS14 */ 224 + if (!clks_init[i].name) 225 + continue; 226 + clk_table[i] = s2mps11_clks[i].clk; 253 227 } 228 + 229 + clk_data.clks = clk_table; 230 + clk_data.clk_num = S2MPS11_CLKS_NUM; 231 + of_clk_add_provider(s2mps11_clks->clk_np, of_clk_src_onecell_get, 232 + &clk_data); 254 233 255 234 platform_set_drvdata(pdev, s2mps11_clks); 256 235 ··· 277 250 struct s2mps11_clk *s2mps11_clks = platform_get_drvdata(pdev); 278 251 int i; 279 252 280 - for (i = 0; i < S2MPS11_CLKS_NUM; i++) 253 + of_clk_del_provider(s2mps11_clks[0].clk_np); 254 + /* Drop the reference obtained in s2mps11_clk_parse_dt */ 255 + of_node_put(s2mps11_clks[0].clk_np); 256 + 257 + for (i = 0; i < S2MPS11_CLKS_NUM; i++) { 258 + /* Skip clocks not present on S2MPS14 */ 259 + if (!s2mps11_clks[i].lookup) 260 + continue; 281 261 clkdev_drop(s2mps11_clks[i].lookup); 262 + } 282 263 283 264 return 0; 284 265 } 285 266 286 267 static const struct platform_device_id s2mps11_clk_id[] = { 287 268 { "s2mps11-clk", S2MPS11X}, 269 + { "s2mps14-clk", S2MPS14X}, 288 270 { "s5m8767-clk", S5M8767X}, 289 271 { }, 290 272 };
+1 -1
drivers/clk/clk-si570.c
··· 526 526 module_i2c_driver(si570_driver); 527 527 528 528 MODULE_AUTHOR("Guenter Roeck <guenter.roeck@ericsson.com>"); 529 - MODULE_AUTHOR("Soeren Brinkmann <soren.brinkmann@xilinx.com"); 529 + MODULE_AUTHOR("Soeren Brinkmann <soren.brinkmann@xilinx.com>"); 530 530 MODULE_DESCRIPTION("Si570 driver"); 531 531 MODULE_LICENSE("GPL");
+1
drivers/clk/clk-u300.c
··· 1168 1168 .compatible = "stericsson,u300-syscon-mclk", 1169 1169 .data = of_u300_syscon_mclk_init, 1170 1170 }, 1171 + {} 1171 1172 }; 1172 1173 1173 1174
+21 -26
drivers/clk/clk.c
··· 106 106 if (!c) 107 107 return; 108 108 109 - seq_printf(s, "%*s%-*s %-11d %-12d %-10lu %-11lu", 109 + seq_printf(s, "%*s%-*s %11d %12d %11lu %10lu\n", 110 110 level * 3 + 1, "", 111 111 30 - level * 3, c->name, 112 112 c->enable_count, c->prepare_count, clk_get_rate(c), 113 113 clk_get_accuracy(c)); 114 - seq_printf(s, "\n"); 115 114 } 116 115 117 116 static void clk_summary_show_subtree(struct seq_file *s, struct clk *c, ··· 131 132 { 132 133 struct clk *c; 133 134 134 - seq_printf(s, " clock enable_cnt prepare_cnt rate accuracy\n"); 135 - seq_printf(s, "---------------------------------------------------------------------------------\n"); 135 + seq_puts(s, " clock enable_cnt prepare_cnt rate accuracy\n"); 136 + seq_puts(s, "--------------------------------------------------------------------------------\n"); 136 137 137 138 clk_prepare_lock(); 138 139 ··· 821 822 */ 822 823 void clk_unprepare(struct clk *clk) 823 824 { 825 + if (IS_ERR_OR_NULL(clk)) 826 + return; 827 + 824 828 clk_prepare_lock(); 825 829 __clk_unprepare(clk); 826 830 clk_prepare_unlock(); ··· 885 883 if (!clk) 886 884 return; 887 885 888 - if (WARN_ON(IS_ERR(clk))) 889 - return; 890 - 891 886 if (WARN_ON(clk->enable_count == 0)) 892 887 return; 893 888 ··· 912 913 void clk_disable(struct clk *clk) 913 914 { 914 915 unsigned long flags; 916 + 917 + if (IS_ERR_OR_NULL(clk)) 918 + return; 915 919 916 920 flags = clk_enable_lock(); 917 921 __clk_disable(clk); ··· 1006 1004 else 1007 1005 return clk->rate; 1008 1006 } 1007 + EXPORT_SYMBOL_GPL(__clk_round_rate); 1009 1008 1010 1009 /** 1011 1010 * clk_round_rate - round the given rate for a clk ··· 1118 1115 } 1119 1116 EXPORT_SYMBOL_GPL(clk_get_accuracy); 1120 1117 1118 + static unsigned long clk_recalc(struct clk *clk, unsigned long parent_rate) 1119 + { 1120 + if (clk->ops->recalc_rate) 1121 + return clk->ops->recalc_rate(clk->hw, parent_rate); 1122 + return parent_rate; 1123 + } 1124 + 1121 1125 /** 1122 1126 * __clk_recalc_rates 1123 1127 * @clk: first clk in the subtree ··· 1150 1140 if (clk->parent) 1151 1141 parent_rate = clk->parent->rate; 1152 1142 1153 - if (clk->ops->recalc_rate) 1154 - clk->rate = clk->ops->recalc_rate(clk->hw, parent_rate); 1155 - else 1156 - clk->rate = parent_rate; 1143 + clk->rate = clk_recalc(clk, parent_rate); 1157 1144 1158 1145 /* 1159 1146 * ignore NOTIFY_STOP and NOTIFY_BAD return values for POST_RATE_CHANGE ··· 1341 1334 unsigned long new_rate; 1342 1335 int ret = NOTIFY_DONE; 1343 1336 1344 - if (clk->ops->recalc_rate) 1345 - new_rate = clk->ops->recalc_rate(clk->hw, parent_rate); 1346 - else 1347 - new_rate = parent_rate; 1337 + new_rate = clk_recalc(clk, parent_rate); 1348 1338 1349 1339 /* abort rate change if a driver returns NOTIFY_BAD or NOTIFY_STOP */ 1350 1340 if (clk->notifier_count) ··· 1377 1373 new_parent->new_child = clk; 1378 1374 1379 1375 hlist_for_each_entry(child, &clk->children, child_node) { 1380 - if (child->ops->recalc_rate) 1381 - child->new_rate = child->ops->recalc_rate(child->hw, new_rate); 1382 - else 1383 - child->new_rate = new_rate; 1376 + child->new_rate = clk_recalc(child, new_rate); 1384 1377 clk_calc_subtree(child, child->new_rate, NULL, 0); 1385 1378 } 1386 1379 } ··· 1525 1524 if (!skip_set_rate && clk->ops->set_rate) 1526 1525 clk->ops->set_rate(clk->hw, clk->new_rate, best_parent_rate); 1527 1526 1528 - if (clk->ops->recalc_rate) 1529 - clk->rate = clk->ops->recalc_rate(clk->hw, best_parent_rate); 1530 - else 1531 - clk->rate = best_parent_rate; 1527 + clk->rate = clk_recalc(clk, best_parent_rate); 1532 1528 1533 1529 if (clk->notifier_count && old_rate != clk->rate) 1534 1530 __clk_notify(clk, POST_RATE_CHANGE, old_rate, clk->rate); ··· 1713 1715 1714 1716 if (!clk) 1715 1717 return 0; 1716 - 1717 - if (!clk->ops) 1718 - return -EINVAL; 1719 1718 1720 1719 /* verify ops for for multi-parent clks */ 1721 1720 if ((clk->num_parents > 1) && (!clk->ops->set_parent))
+1
drivers/clk/clk.h
··· 10 10 */ 11 11 12 12 #if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK) 13 + struct clk *of_clk_get_by_clkspec(struct of_phandle_args *clkspec); 13 14 struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec); 14 15 void of_clk_lock(void); 15 16 void of_clk_unlock(void);
+27 -7
drivers/clk/clkdev.c
··· 27 27 static DEFINE_MUTEX(clocks_mutex); 28 28 29 29 #if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK) 30 + 31 + /** 32 + * of_clk_get_by_clkspec() - Lookup a clock form a clock provider 33 + * @clkspec: pointer to a clock specifier data structure 34 + * 35 + * This function looks up a struct clk from the registered list of clock 36 + * providers, an input is a clock specifier data structure as returned 37 + * from the of_parse_phandle_with_args() function call. 38 + */ 39 + struct clk *of_clk_get_by_clkspec(struct of_phandle_args *clkspec) 40 + { 41 + struct clk *clk; 42 + 43 + if (!clkspec) 44 + return ERR_PTR(-EINVAL); 45 + 46 + of_clk_lock(); 47 + clk = __of_clk_get_from_provider(clkspec); 48 + 49 + if (!IS_ERR(clk) && !__clk_get(clk)) 50 + clk = ERR_PTR(-ENOENT); 51 + 52 + of_clk_unlock(); 53 + return clk; 54 + } 55 + 30 56 struct clk *of_clk_get(struct device_node *np, int index) 31 57 { 32 58 struct of_phandle_args clkspec; ··· 67 41 if (rc) 68 42 return ERR_PTR(rc); 69 43 70 - of_clk_lock(); 71 - clk = __of_clk_get_from_provider(&clkspec); 72 - 73 - if (!IS_ERR(clk) && !__clk_get(clk)) 74 - clk = ERR_PTR(-ENOENT); 75 - 76 - of_clk_unlock(); 44 + clk = of_clk_get_by_clkspec(&clkspec); 77 45 of_node_put(clkspec.np); 78 46 return clk; 79 47 }
+1
drivers/clk/hisilicon/Makefile
··· 6 6 7 7 obj-$(CONFIG_ARCH_HI3xxx) += clk-hi3620.o 8 8 obj-$(CONFIG_ARCH_HIP04) += clk-hip04.o 9 + obj-$(CONFIG_ARCH_HIX5HD2) += clk-hix5hd2.o
+101
drivers/clk/hisilicon/clk-hix5hd2.c
··· 1 + /* 2 + * Copyright (c) 2014 Linaro Ltd. 3 + * Copyright (c) 2014 Hisilicon Limited. 4 + * 5 + * This program is free software; you can redistribute it and/or modify it 6 + * under the terms and conditions of the GNU General Public License, 7 + * version 2, as published by the Free Software Foundation. 8 + */ 9 + 10 + #include <linux/of_address.h> 11 + #include <dt-bindings/clock/hix5hd2-clock.h> 12 + #include "clk.h" 13 + 14 + static struct hisi_fixed_rate_clock hix5hd2_fixed_rate_clks[] __initdata = { 15 + { HIX5HD2_FIXED_1200M, "1200m", NULL, CLK_IS_ROOT, 1200000000, }, 16 + { HIX5HD2_FIXED_400M, "400m", NULL, CLK_IS_ROOT, 400000000, }, 17 + { HIX5HD2_FIXED_48M, "48m", NULL, CLK_IS_ROOT, 48000000, }, 18 + { HIX5HD2_FIXED_24M, "24m", NULL, CLK_IS_ROOT, 24000000, }, 19 + { HIX5HD2_FIXED_600M, "600m", NULL, CLK_IS_ROOT, 600000000, }, 20 + { HIX5HD2_FIXED_300M, "300m", NULL, CLK_IS_ROOT, 300000000, }, 21 + { HIX5HD2_FIXED_75M, "75m", NULL, CLK_IS_ROOT, 75000000, }, 22 + { HIX5HD2_FIXED_200M, "200m", NULL, CLK_IS_ROOT, 200000000, }, 23 + { HIX5HD2_FIXED_100M, "100m", NULL, CLK_IS_ROOT, 100000000, }, 24 + { HIX5HD2_FIXED_40M, "40m", NULL, CLK_IS_ROOT, 40000000, }, 25 + { HIX5HD2_FIXED_150M, "150m", NULL, CLK_IS_ROOT, 150000000, }, 26 + { HIX5HD2_FIXED_1728M, "1728m", NULL, CLK_IS_ROOT, 1728000000, }, 27 + { HIX5HD2_FIXED_28P8M, "28p8m", NULL, CLK_IS_ROOT, 28000000, }, 28 + { HIX5HD2_FIXED_432M, "432m", NULL, CLK_IS_ROOT, 432000000, }, 29 + { HIX5HD2_FIXED_345P6M, "345p6m", NULL, CLK_IS_ROOT, 345000000, }, 30 + { HIX5HD2_FIXED_288M, "288m", NULL, CLK_IS_ROOT, 288000000, }, 31 + { HIX5HD2_FIXED_60M, "60m", NULL, CLK_IS_ROOT, 60000000, }, 32 + { HIX5HD2_FIXED_750M, "750m", NULL, CLK_IS_ROOT, 750000000, }, 33 + { HIX5HD2_FIXED_500M, "500m", NULL, CLK_IS_ROOT, 500000000, }, 34 + { HIX5HD2_FIXED_54M, "54m", NULL, CLK_IS_ROOT, 54000000, }, 35 + { HIX5HD2_FIXED_27M, "27m", NULL, CLK_IS_ROOT, 27000000, }, 36 + { HIX5HD2_FIXED_1500M, "1500m", NULL, CLK_IS_ROOT, 1500000000, }, 37 + { HIX5HD2_FIXED_375M, "375m", NULL, CLK_IS_ROOT, 375000000, }, 38 + { HIX5HD2_FIXED_187M, "187m", NULL, CLK_IS_ROOT, 187000000, }, 39 + { HIX5HD2_FIXED_250M, "250m", NULL, CLK_IS_ROOT, 250000000, }, 40 + { HIX5HD2_FIXED_125M, "125m", NULL, CLK_IS_ROOT, 125000000, }, 41 + { HIX5HD2_FIXED_2P02M, "2m", NULL, CLK_IS_ROOT, 2000000, }, 42 + { HIX5HD2_FIXED_50M, "50m", NULL, CLK_IS_ROOT, 50000000, }, 43 + { HIX5HD2_FIXED_25M, "25m", NULL, CLK_IS_ROOT, 25000000, }, 44 + { HIX5HD2_FIXED_83M, "83m", NULL, CLK_IS_ROOT, 83333333, }, 45 + }; 46 + 47 + static const char *sfc_mux_p[] __initconst = { 48 + "24m", "150m", "200m", "100m", "75m", }; 49 + static u32 sfc_mux_table[] = {0, 4, 5, 6, 7}; 50 + 51 + static const char *sdio1_mux_p[] __initconst = { 52 + "75m", "100m", "50m", "15m", }; 53 + static u32 sdio1_mux_table[] = {0, 1, 2, 3}; 54 + 55 + static const char *fephy_mux_p[] __initconst = { "25m", "125m"}; 56 + static u32 fephy_mux_table[] = {0, 1}; 57 + 58 + 59 + static struct hisi_mux_clock hix5hd2_mux_clks[] __initdata = { 60 + { HIX5HD2_SFC_MUX, "sfc_mux", sfc_mux_p, ARRAY_SIZE(sfc_mux_p), 61 + CLK_SET_RATE_PARENT, 0x5c, 8, 3, 0, sfc_mux_table, }, 62 + { HIX5HD2_MMC_MUX, "mmc_mux", sdio1_mux_p, ARRAY_SIZE(sdio1_mux_p), 63 + CLK_SET_RATE_PARENT, 0xa0, 8, 2, 0, sdio1_mux_table, }, 64 + { HIX5HD2_FEPHY_MUX, "fephy_mux", 65 + fephy_mux_p, ARRAY_SIZE(fephy_mux_p), 66 + CLK_SET_RATE_PARENT, 0x120, 8, 2, 0, fephy_mux_table, }, 67 + }; 68 + 69 + static struct hisi_gate_clock hix5hd2_gate_clks[] __initdata = { 70 + /*sfc*/ 71 + { HIX5HD2_SFC_CLK, "clk_sfc", "sfc_mux", 72 + CLK_SET_RATE_PARENT, 0x5c, 0, 0, }, 73 + { HIX5HD2_SFC_RST, "rst_sfc", "clk_sfc", 74 + CLK_SET_RATE_PARENT, 0x5c, 4, CLK_GATE_SET_TO_DISABLE, }, 75 + /*sdio1*/ 76 + { HIX5HD2_MMC_BIU_CLK, "clk_mmc_biu", "200m", 77 + CLK_SET_RATE_PARENT, 0xa0, 0, 0, }, 78 + { HIX5HD2_MMC_CIU_CLK, "clk_mmc_ciu", "mmc_mux", 79 + CLK_SET_RATE_PARENT, 0xa0, 1, 0, }, 80 + { HIX5HD2_MMC_CIU_RST, "rst_mmc_ciu", "clk_mmc_ciu", 81 + CLK_SET_RATE_PARENT, 0xa0, 4, CLK_GATE_SET_TO_DISABLE, }, 82 + }; 83 + 84 + static void __init hix5hd2_clk_init(struct device_node *np) 85 + { 86 + struct hisi_clock_data *clk_data; 87 + 88 + clk_data = hisi_clk_init(np, HIX5HD2_NR_CLKS); 89 + if (!clk_data) 90 + return; 91 + 92 + hisi_clk_register_fixed_rate(hix5hd2_fixed_rate_clks, 93 + ARRAY_SIZE(hix5hd2_fixed_rate_clks), 94 + clk_data); 95 + hisi_clk_register_mux(hix5hd2_mux_clks, ARRAY_SIZE(hix5hd2_mux_clks), 96 + clk_data); 97 + hisi_clk_register_gate(hix5hd2_gate_clks, 98 + ARRAY_SIZE(hix5hd2_gate_clks), clk_data); 99 + } 100 + 101 + CLK_OF_DECLARE(hix5hd2_clk, "hisilicon,hix5hd2-clock", hix5hd2_clk_init);
+36 -5
drivers/clk/hisilicon/clk.c
··· 127 127 int i; 128 128 129 129 for (i = 0; i < nums; i++) { 130 - clk = clk_register_mux(NULL, clks[i].name, clks[i].parent_names, 131 - clks[i].num_parents, clks[i].flags, 132 - base + clks[i].offset, clks[i].shift, 133 - clks[i].width, clks[i].mux_flags, 134 - &hisi_clk_lock); 130 + u32 mask = BIT(clks[i].width) - 1; 131 + 132 + clk = clk_register_mux_table(NULL, clks[i].name, 133 + clks[i].parent_names, 134 + clks[i].num_parents, clks[i].flags, 135 + base + clks[i].offset, clks[i].shift, 136 + mask, clks[i].mux_flags, 137 + clks[i].table, &hisi_clk_lock); 135 138 if (IS_ERR(clk)) { 136 139 pr_err("%s: failed to register clock %s\n", 137 140 __func__, clks[i].name); ··· 164 161 clks[i].div_flags, 165 162 clks[i].table, 166 163 &hisi_clk_lock); 164 + if (IS_ERR(clk)) { 165 + pr_err("%s: failed to register clock %s\n", 166 + __func__, clks[i].name); 167 + continue; 168 + } 169 + 170 + if (clks[i].alias) 171 + clk_register_clkdev(clk, clks[i].alias, NULL); 172 + 173 + data->clk_data.clks[clks[i].id] = clk; 174 + } 175 + } 176 + 177 + void __init hisi_clk_register_gate(struct hisi_gate_clock *clks, 178 + int nums, struct hisi_clock_data *data) 179 + { 180 + struct clk *clk; 181 + void __iomem *base = data->base; 182 + int i; 183 + 184 + for (i = 0; i < nums; i++) { 185 + clk = clk_register_gate(NULL, clks[i].name, 186 + clks[i].parent_name, 187 + clks[i].flags, 188 + base + clks[i].offset, 189 + clks[i].bit_idx, 190 + clks[i].gate_flags, 191 + &hisi_clk_lock); 167 192 if (IS_ERR(clk)) { 168 193 pr_err("%s: failed to register clock %s\n", 169 194 __func__, clks[i].name);
+3
drivers/clk/hisilicon/clk.h
··· 62 62 u8 shift; 63 63 u8 width; 64 64 u8 mux_flags; 65 + u32 *table; 65 66 const char *alias; 66 67 }; 67 68 ··· 104 103 struct hisi_clock_data *); 105 104 void __init hisi_clk_register_divider(struct hisi_divider_clock *, 106 105 int, struct hisi_clock_data *); 106 + void __init hisi_clk_register_gate(struct hisi_gate_clock *, 107 + int, struct hisi_clock_data *); 107 108 void __init hisi_clk_register_gate_sep(struct hisi_gate_clock *, 108 109 int, struct hisi_clock_data *); 109 110 #endif /* __HISI_CLK_H */
+4
drivers/clk/mvebu/Kconfig
··· 34 34 config KIRKWOOD_CLK 35 35 bool 36 36 select MVEBU_CLK_COMMON 37 + 38 + config ORION_CLK 39 + bool 40 + select MVEBU_CLK_COMMON
+1
drivers/clk/mvebu/Makefile
··· 8 8 obj-$(CONFIG_ARMADA_XP_CLK) += armada-xp.o 9 9 obj-$(CONFIG_DOVE_CLK) += dove.o 10 10 obj-$(CONFIG_KIRKWOOD_CLK) += kirkwood.o 11 + obj-$(CONFIG_ORION_CLK) += orion.o
+210
drivers/clk/mvebu/orion.c
··· 1 + /* 2 + * Marvell Orion SoC clocks 3 + * 4 + * Copyright (C) 2014 Thomas Petazzoni 5 + * 6 + * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> 7 + * 8 + * This file is licensed under the terms of the GNU General Public 9 + * License version 2. This program is licensed "as is" without any 10 + * warranty of any kind, whether express or implied. 11 + */ 12 + 13 + #include <linux/kernel.h> 14 + #include <linux/clk-provider.h> 15 + #include <linux/io.h> 16 + #include <linux/of.h> 17 + #include "common.h" 18 + 19 + static const struct coreclk_ratio orion_coreclk_ratios[] __initconst = { 20 + { .id = 0, .name = "ddrclk", } 21 + }; 22 + 23 + /* 24 + * Orion 5182 25 + */ 26 + 27 + #define SAR_MV88F5182_TCLK_FREQ 8 28 + #define SAR_MV88F5182_TCLK_FREQ_MASK 0x3 29 + 30 + static u32 __init mv88f5182_get_tclk_freq(void __iomem *sar) 31 + { 32 + u32 opt = (readl(sar) >> SAR_MV88F5182_TCLK_FREQ) & 33 + SAR_MV88F5182_TCLK_FREQ_MASK; 34 + if (opt == 1) 35 + return 150000000; 36 + else if (opt == 2) 37 + return 166666667; 38 + else 39 + return 0; 40 + } 41 + 42 + #define SAR_MV88F5182_CPU_FREQ 4 43 + #define SAR_MV88F5182_CPU_FREQ_MASK 0xf 44 + 45 + static u32 __init mv88f5182_get_cpu_freq(void __iomem *sar) 46 + { 47 + u32 opt = (readl(sar) >> SAR_MV88F5182_CPU_FREQ) & 48 + SAR_MV88F5182_CPU_FREQ_MASK; 49 + if (opt == 0) 50 + return 333333333; 51 + else if (opt == 1 || opt == 2) 52 + return 400000000; 53 + else if (opt == 3) 54 + return 500000000; 55 + else 56 + return 0; 57 + } 58 + 59 + static void __init mv88f5182_get_clk_ratio(void __iomem *sar, int id, 60 + int *mult, int *div) 61 + { 62 + u32 opt = (readl(sar) >> SAR_MV88F5182_CPU_FREQ) & 63 + SAR_MV88F5182_CPU_FREQ_MASK; 64 + if (opt == 0 || opt == 1) { 65 + *mult = 1; 66 + *div = 2; 67 + } else if (opt == 2 || opt == 3) { 68 + *mult = 1; 69 + *div = 3; 70 + } else { 71 + *mult = 0; 72 + *div = 1; 73 + } 74 + } 75 + 76 + static const struct coreclk_soc_desc mv88f5182_coreclks = { 77 + .get_tclk_freq = mv88f5182_get_tclk_freq, 78 + .get_cpu_freq = mv88f5182_get_cpu_freq, 79 + .get_clk_ratio = mv88f5182_get_clk_ratio, 80 + .ratios = orion_coreclk_ratios, 81 + .num_ratios = ARRAY_SIZE(orion_coreclk_ratios), 82 + }; 83 + 84 + static void __init mv88f5182_clk_init(struct device_node *np) 85 + { 86 + return mvebu_coreclk_setup(np, &mv88f5182_coreclks); 87 + } 88 + 89 + CLK_OF_DECLARE(mv88f5182_clk, "marvell,mv88f5182-core-clock", mv88f5182_clk_init); 90 + 91 + /* 92 + * Orion 5281 93 + */ 94 + 95 + static u32 __init mv88f5281_get_tclk_freq(void __iomem *sar) 96 + { 97 + /* On 5281, tclk is always 166 Mhz */ 98 + return 166666667; 99 + } 100 + 101 + #define SAR_MV88F5281_CPU_FREQ 4 102 + #define SAR_MV88F5281_CPU_FREQ_MASK 0xf 103 + 104 + static u32 __init mv88f5281_get_cpu_freq(void __iomem *sar) 105 + { 106 + u32 opt = (readl(sar) >> SAR_MV88F5281_CPU_FREQ) & 107 + SAR_MV88F5281_CPU_FREQ_MASK; 108 + if (opt == 1 || opt == 2) 109 + return 400000000; 110 + else if (opt == 3) 111 + return 500000000; 112 + else 113 + return 0; 114 + } 115 + 116 + static void __init mv88f5281_get_clk_ratio(void __iomem *sar, int id, 117 + int *mult, int *div) 118 + { 119 + u32 opt = (readl(sar) >> SAR_MV88F5281_CPU_FREQ) & 120 + SAR_MV88F5281_CPU_FREQ_MASK; 121 + if (opt == 1) { 122 + *mult = 1; 123 + *div = 2; 124 + } else if (opt == 2 || opt == 3) { 125 + *mult = 1; 126 + *div = 3; 127 + } else { 128 + *mult = 0; 129 + *div = 1; 130 + } 131 + } 132 + 133 + static const struct coreclk_soc_desc mv88f5281_coreclks = { 134 + .get_tclk_freq = mv88f5281_get_tclk_freq, 135 + .get_cpu_freq = mv88f5281_get_cpu_freq, 136 + .get_clk_ratio = mv88f5281_get_clk_ratio, 137 + .ratios = orion_coreclk_ratios, 138 + .num_ratios = ARRAY_SIZE(orion_coreclk_ratios), 139 + }; 140 + 141 + static void __init mv88f5281_clk_init(struct device_node *np) 142 + { 143 + return mvebu_coreclk_setup(np, &mv88f5281_coreclks); 144 + } 145 + 146 + CLK_OF_DECLARE(mv88f5281_clk, "marvell,mv88f5281-core-clock", mv88f5281_clk_init); 147 + 148 + /* 149 + * Orion 6183 150 + */ 151 + 152 + #define SAR_MV88F6183_TCLK_FREQ 9 153 + #define SAR_MV88F6183_TCLK_FREQ_MASK 0x1 154 + 155 + static u32 __init mv88f6183_get_tclk_freq(void __iomem *sar) 156 + { 157 + u32 opt = (readl(sar) >> SAR_MV88F6183_TCLK_FREQ) & 158 + SAR_MV88F6183_TCLK_FREQ_MASK; 159 + if (opt == 0) 160 + return 133333333; 161 + else if (opt == 1) 162 + return 166666667; 163 + else 164 + return 0; 165 + } 166 + 167 + #define SAR_MV88F6183_CPU_FREQ 1 168 + #define SAR_MV88F6183_CPU_FREQ_MASK 0x3f 169 + 170 + static u32 __init mv88f6183_get_cpu_freq(void __iomem *sar) 171 + { 172 + u32 opt = (readl(sar) >> SAR_MV88F6183_CPU_FREQ) & 173 + SAR_MV88F6183_CPU_FREQ_MASK; 174 + if (opt == 9) 175 + return 333333333; 176 + else if (opt == 17) 177 + return 400000000; 178 + else 179 + return 0; 180 + } 181 + 182 + static void __init mv88f6183_get_clk_ratio(void __iomem *sar, int id, 183 + int *mult, int *div) 184 + { 185 + u32 opt = (readl(sar) >> SAR_MV88F6183_CPU_FREQ) & 186 + SAR_MV88F6183_CPU_FREQ_MASK; 187 + if (opt == 9 || opt == 17) { 188 + *mult = 1; 189 + *div = 2; 190 + } else { 191 + *mult = 0; 192 + *div = 1; 193 + } 194 + } 195 + 196 + static const struct coreclk_soc_desc mv88f6183_coreclks = { 197 + .get_tclk_freq = mv88f6183_get_tclk_freq, 198 + .get_cpu_freq = mv88f6183_get_cpu_freq, 199 + .get_clk_ratio = mv88f6183_get_clk_ratio, 200 + .ratios = orion_coreclk_ratios, 201 + .num_ratios = ARRAY_SIZE(orion_coreclk_ratios), 202 + }; 203 + 204 + 205 + static void __init mv88f6183_clk_init(struct device_node *np) 206 + { 207 + return mvebu_coreclk_setup(np, &mv88f6183_coreclks); 208 + } 209 + 210 + CLK_OF_DECLARE(mv88f6183_clk, "marvell,mv88f6183-core-clock", mv88f6183_clk_init);
+2 -2
drivers/clk/qcom/Kconfig
··· 13 13 i2c, USB, SD/eMMC, etc. 14 14 15 15 config MSM_GCC_8960 16 - tristate "MSM8960 Global Clock Controller" 16 + tristate "APQ8064/MSM8960 Global Clock Controller" 17 17 depends on COMMON_CLK_QCOM 18 18 help 19 - Support for the global clock controller on msm8960 devices. 19 + Support for the global clock controller on apq8064/msm8960 devices. 20 20 Say Y if you want to use peripheral devices such as UART, SPI, 21 21 i2c, USB, SD/eMMC, SATA, PCIe, etc. 22 22
+1
drivers/clk/qcom/Makefile
··· 1 1 obj-$(CONFIG_COMMON_CLK_QCOM) += clk-qcom.o 2 2 3 + clk-qcom-y += common.o 3 4 clk-qcom-y += clk-regmap.o 4 5 clk-qcom-y += clk-pll.o 5 6 clk-qcom-y += clk-rcg.o
+3
drivers/clk/qcom/clk-rcg.h
··· 155 155 #define to_clk_rcg2(_hw) container_of(to_clk_regmap(_hw), struct clk_rcg2, clkr) 156 156 157 157 extern const struct clk_ops clk_rcg2_ops; 158 + extern const struct clk_ops clk_edp_pixel_ops; 159 + extern const struct clk_ops clk_byte_ops; 160 + extern const struct clk_ops clk_pixel_ops; 158 161 159 162 #endif
+287 -17
drivers/clk/qcom/clk-rcg2.c
··· 19 19 #include <linux/clk-provider.h> 20 20 #include <linux/delay.h> 21 21 #include <linux/regmap.h> 22 + #include <linux/math64.h> 22 23 23 24 #include <asm/div64.h> 24 25 ··· 56 55 if (ret) 57 56 return ret; 58 57 59 - return (cmd & CMD_ROOT_OFF) != 0; 58 + return (cmd & CMD_ROOT_OFF) == 0; 60 59 } 61 60 62 61 static u8 clk_rcg2_get_parent(struct clk_hw *hw) ··· 182 181 if (rate <= f->freq) 183 182 return f; 184 183 185 - return NULL; 184 + /* Default to our fastest rate */ 185 + return f - 1; 186 186 } 187 187 188 188 static long _freq_tbl_determine_rate(struct clk_hw *hw, ··· 226 224 return _freq_tbl_determine_rate(hw, rcg->freq_tbl, rate, p_rate, p); 227 225 } 228 226 229 - static int __clk_rcg2_set_rate(struct clk_hw *hw, unsigned long rate) 227 + static int clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f) 230 228 { 231 - struct clk_rcg2 *rcg = to_clk_rcg2(hw); 232 - const struct freq_tbl *f; 233 229 u32 cfg, mask; 234 230 int ret; 235 231 236 - f = find_freq(rcg->freq_tbl, rate); 237 - if (!f) 238 - return -EINVAL; 239 - 240 232 if (rcg->mnd_width && f->n) { 241 233 mask = BIT(rcg->mnd_width) - 1; 242 - ret = regmap_update_bits(rcg->clkr.regmap, rcg->cmd_rcgr + M_REG, 243 - mask, f->m); 234 + ret = regmap_update_bits(rcg->clkr.regmap, 235 + rcg->cmd_rcgr + M_REG, mask, f->m); 244 236 if (ret) 245 237 return ret; 246 238 247 - ret = regmap_update_bits(rcg->clkr.regmap, rcg->cmd_rcgr + N_REG, 248 - mask, ~(f->n - f->m)); 239 + ret = regmap_update_bits(rcg->clkr.regmap, 240 + rcg->cmd_rcgr + N_REG, mask, ~(f->n - f->m)); 249 241 if (ret) 250 242 return ret; 251 243 252 - ret = regmap_update_bits(rcg->clkr.regmap, rcg->cmd_rcgr + D_REG, 253 - mask, ~f->n); 244 + ret = regmap_update_bits(rcg->clkr.regmap, 245 + rcg->cmd_rcgr + D_REG, mask, ~f->n); 254 246 if (ret) 255 247 return ret; 256 248 } ··· 255 259 cfg |= rcg->parent_map[f->src] << CFG_SRC_SEL_SHIFT; 256 260 if (rcg->mnd_width && f->n) 257 261 cfg |= CFG_MODE_DUAL_EDGE; 258 - ret = regmap_update_bits(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, mask, 259 - cfg); 262 + ret = regmap_update_bits(rcg->clkr.regmap, 263 + rcg->cmd_rcgr + CFG_REG, mask, cfg); 260 264 if (ret) 261 265 return ret; 262 266 263 267 return update_config(rcg); 268 + } 269 + 270 + static int __clk_rcg2_set_rate(struct clk_hw *hw, unsigned long rate) 271 + { 272 + struct clk_rcg2 *rcg = to_clk_rcg2(hw); 273 + const struct freq_tbl *f; 274 + 275 + f = find_freq(rcg->freq_tbl, rate); 276 + if (!f) 277 + return -EINVAL; 278 + 279 + return clk_rcg2_configure(rcg, f); 264 280 } 265 281 266 282 static int clk_rcg2_set_rate(struct clk_hw *hw, unsigned long rate, ··· 297 289 .set_rate_and_parent = clk_rcg2_set_rate_and_parent, 298 290 }; 299 291 EXPORT_SYMBOL_GPL(clk_rcg2_ops); 292 + 293 + struct frac_entry { 294 + int num; 295 + int den; 296 + }; 297 + 298 + static const struct frac_entry frac_table_675m[] = { /* link rate of 270M */ 299 + { 52, 295 }, /* 119 M */ 300 + { 11, 57 }, /* 130.25 M */ 301 + { 63, 307 }, /* 138.50 M */ 302 + { 11, 50 }, /* 148.50 M */ 303 + { 47, 206 }, /* 154 M */ 304 + { 31, 100 }, /* 205.25 M */ 305 + { 107, 269 }, /* 268.50 M */ 306 + { }, 307 + }; 308 + 309 + static struct frac_entry frac_table_810m[] = { /* Link rate of 162M */ 310 + { 31, 211 }, /* 119 M */ 311 + { 32, 199 }, /* 130.25 M */ 312 + { 63, 307 }, /* 138.50 M */ 313 + { 11, 60 }, /* 148.50 M */ 314 + { 50, 263 }, /* 154 M */ 315 + { 31, 120 }, /* 205.25 M */ 316 + { 119, 359 }, /* 268.50 M */ 317 + { }, 318 + }; 319 + 320 + static int clk_edp_pixel_set_rate(struct clk_hw *hw, unsigned long rate, 321 + unsigned long parent_rate) 322 + { 323 + struct clk_rcg2 *rcg = to_clk_rcg2(hw); 324 + struct freq_tbl f = *rcg->freq_tbl; 325 + const struct frac_entry *frac; 326 + int delta = 100000; 327 + s64 src_rate = parent_rate; 328 + s64 request; 329 + u32 mask = BIT(rcg->hid_width) - 1; 330 + u32 hid_div; 331 + 332 + if (src_rate == 810000000) 333 + frac = frac_table_810m; 334 + else 335 + frac = frac_table_675m; 336 + 337 + for (; frac->num; frac++) { 338 + request = rate; 339 + request *= frac->den; 340 + request = div_s64(request, frac->num); 341 + if ((src_rate < (request - delta)) || 342 + (src_rate > (request + delta))) 343 + continue; 344 + 345 + regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, 346 + &hid_div); 347 + f.pre_div = hid_div; 348 + f.pre_div >>= CFG_SRC_DIV_SHIFT; 349 + f.pre_div &= mask; 350 + f.m = frac->num; 351 + f.n = frac->den; 352 + 353 + return clk_rcg2_configure(rcg, &f); 354 + } 355 + 356 + return -EINVAL; 357 + } 358 + 359 + static int clk_edp_pixel_set_rate_and_parent(struct clk_hw *hw, 360 + unsigned long rate, unsigned long parent_rate, u8 index) 361 + { 362 + /* Parent index is set statically in frequency table */ 363 + return clk_edp_pixel_set_rate(hw, rate, parent_rate); 364 + } 365 + 366 + static long clk_edp_pixel_determine_rate(struct clk_hw *hw, unsigned long rate, 367 + unsigned long *p_rate, struct clk **p) 368 + { 369 + struct clk_rcg2 *rcg = to_clk_rcg2(hw); 370 + const struct freq_tbl *f = rcg->freq_tbl; 371 + const struct frac_entry *frac; 372 + int delta = 100000; 373 + s64 src_rate = *p_rate; 374 + s64 request; 375 + u32 mask = BIT(rcg->hid_width) - 1; 376 + u32 hid_div; 377 + 378 + /* Force the correct parent */ 379 + *p = clk_get_parent_by_index(hw->clk, f->src); 380 + 381 + if (src_rate == 810000000) 382 + frac = frac_table_810m; 383 + else 384 + frac = frac_table_675m; 385 + 386 + for (; frac->num; frac++) { 387 + request = rate; 388 + request *= frac->den; 389 + request = div_s64(request, frac->num); 390 + if ((src_rate < (request - delta)) || 391 + (src_rate > (request + delta))) 392 + continue; 393 + 394 + regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, 395 + &hid_div); 396 + hid_div >>= CFG_SRC_DIV_SHIFT; 397 + hid_div &= mask; 398 + 399 + return calc_rate(src_rate, frac->num, frac->den, !!frac->den, 400 + hid_div); 401 + } 402 + 403 + return -EINVAL; 404 + } 405 + 406 + const struct clk_ops clk_edp_pixel_ops = { 407 + .is_enabled = clk_rcg2_is_enabled, 408 + .get_parent = clk_rcg2_get_parent, 409 + .set_parent = clk_rcg2_set_parent, 410 + .recalc_rate = clk_rcg2_recalc_rate, 411 + .set_rate = clk_edp_pixel_set_rate, 412 + .set_rate_and_parent = clk_edp_pixel_set_rate_and_parent, 413 + .determine_rate = clk_edp_pixel_determine_rate, 414 + }; 415 + EXPORT_SYMBOL_GPL(clk_edp_pixel_ops); 416 + 417 + static long clk_byte_determine_rate(struct clk_hw *hw, unsigned long rate, 418 + unsigned long *p_rate, struct clk **p) 419 + { 420 + struct clk_rcg2 *rcg = to_clk_rcg2(hw); 421 + const struct freq_tbl *f = rcg->freq_tbl; 422 + unsigned long parent_rate, div; 423 + u32 mask = BIT(rcg->hid_width) - 1; 424 + 425 + if (rate == 0) 426 + return -EINVAL; 427 + 428 + *p = clk_get_parent_by_index(hw->clk, f->src); 429 + *p_rate = parent_rate = __clk_round_rate(*p, rate); 430 + 431 + div = DIV_ROUND_UP((2 * parent_rate), rate) - 1; 432 + div = min_t(u32, div, mask); 433 + 434 + return calc_rate(parent_rate, 0, 0, 0, div); 435 + } 436 + 437 + static int clk_byte_set_rate(struct clk_hw *hw, unsigned long rate, 438 + unsigned long parent_rate) 439 + { 440 + struct clk_rcg2 *rcg = to_clk_rcg2(hw); 441 + struct freq_tbl f = *rcg->freq_tbl; 442 + unsigned long div; 443 + u32 mask = BIT(rcg->hid_width) - 1; 444 + 445 + div = DIV_ROUND_UP((2 * parent_rate), rate) - 1; 446 + div = min_t(u32, div, mask); 447 + 448 + f.pre_div = div; 449 + 450 + return clk_rcg2_configure(rcg, &f); 451 + } 452 + 453 + static int clk_byte_set_rate_and_parent(struct clk_hw *hw, 454 + unsigned long rate, unsigned long parent_rate, u8 index) 455 + { 456 + /* Parent index is set statically in frequency table */ 457 + return clk_byte_set_rate(hw, rate, parent_rate); 458 + } 459 + 460 + const struct clk_ops clk_byte_ops = { 461 + .is_enabled = clk_rcg2_is_enabled, 462 + .get_parent = clk_rcg2_get_parent, 463 + .set_parent = clk_rcg2_set_parent, 464 + .recalc_rate = clk_rcg2_recalc_rate, 465 + .set_rate = clk_byte_set_rate, 466 + .set_rate_and_parent = clk_byte_set_rate_and_parent, 467 + .determine_rate = clk_byte_determine_rate, 468 + }; 469 + EXPORT_SYMBOL_GPL(clk_byte_ops); 470 + 471 + static const struct frac_entry frac_table_pixel[] = { 472 + { 3, 8 }, 473 + { 2, 9 }, 474 + { 4, 9 }, 475 + { 1, 1 }, 476 + { } 477 + }; 478 + 479 + static long clk_pixel_determine_rate(struct clk_hw *hw, unsigned long rate, 480 + unsigned long *p_rate, struct clk **p) 481 + { 482 + struct clk_rcg2 *rcg = to_clk_rcg2(hw); 483 + unsigned long request, src_rate; 484 + int delta = 100000; 485 + const struct freq_tbl *f = rcg->freq_tbl; 486 + const struct frac_entry *frac = frac_table_pixel; 487 + struct clk *parent = *p = clk_get_parent_by_index(hw->clk, f->src); 488 + 489 + for (; frac->num; frac++) { 490 + request = (rate * frac->den) / frac->num; 491 + 492 + src_rate = __clk_round_rate(parent, request); 493 + if ((src_rate < (request - delta)) || 494 + (src_rate > (request + delta))) 495 + continue; 496 + 497 + *p_rate = src_rate; 498 + return (src_rate * frac->num) / frac->den; 499 + } 500 + 501 + return -EINVAL; 502 + } 503 + 504 + static int clk_pixel_set_rate(struct clk_hw *hw, unsigned long rate, 505 + unsigned long parent_rate) 506 + { 507 + struct clk_rcg2 *rcg = to_clk_rcg2(hw); 508 + struct freq_tbl f = *rcg->freq_tbl; 509 + const struct frac_entry *frac = frac_table_pixel; 510 + unsigned long request, src_rate; 511 + int delta = 100000; 512 + u32 mask = BIT(rcg->hid_width) - 1; 513 + u32 hid_div; 514 + struct clk *parent = clk_get_parent_by_index(hw->clk, f.src); 515 + 516 + for (; frac->num; frac++) { 517 + request = (rate * frac->den) / frac->num; 518 + 519 + src_rate = __clk_round_rate(parent, request); 520 + if ((src_rate < (request - delta)) || 521 + (src_rate > (request + delta))) 522 + continue; 523 + 524 + regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, 525 + &hid_div); 526 + f.pre_div = hid_div; 527 + f.pre_div >>= CFG_SRC_DIV_SHIFT; 528 + f.pre_div &= mask; 529 + f.m = frac->num; 530 + f.n = frac->den; 531 + 532 + return clk_rcg2_configure(rcg, &f); 533 + } 534 + return -EINVAL; 535 + } 536 + 537 + static int clk_pixel_set_rate_and_parent(struct clk_hw *hw, unsigned long rate, 538 + unsigned long parent_rate, u8 index) 539 + { 540 + /* Parent index is set statically in frequency table */ 541 + return clk_pixel_set_rate(hw, rate, parent_rate); 542 + } 543 + 544 + const struct clk_ops clk_pixel_ops = { 545 + .is_enabled = clk_rcg2_is_enabled, 546 + .get_parent = clk_rcg2_get_parent, 547 + .set_parent = clk_rcg2_set_parent, 548 + .recalc_rate = clk_rcg2_recalc_rate, 549 + .set_rate = clk_pixel_set_rate, 550 + .set_rate_and_parent = clk_pixel_set_rate_and_parent, 551 + .determine_rate = clk_pixel_determine_rate, 552 + }; 553 + EXPORT_SYMBOL_GPL(clk_pixel_ops);
+101
drivers/clk/qcom/common.c
··· 1 + /* 2 + * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. 3 + * 4 + * This software is licensed under the terms of the GNU General Public 5 + * License version 2, as published by the Free Software Foundation, and 6 + * may be copied, distributed, and modified under those terms. 7 + * 8 + * This program is distributed in the hope that it will be useful, 9 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 + * GNU General Public License for more details. 12 + */ 13 + 14 + #include <linux/export.h> 15 + #include <linux/regmap.h> 16 + #include <linux/platform_device.h> 17 + #include <linux/clk-provider.h> 18 + #include <linux/reset-controller.h> 19 + 20 + #include "common.h" 21 + #include "clk-regmap.h" 22 + #include "reset.h" 23 + 24 + struct qcom_cc { 25 + struct qcom_reset_controller reset; 26 + struct clk_onecell_data data; 27 + struct clk *clks[]; 28 + }; 29 + 30 + int qcom_cc_probe(struct platform_device *pdev, const struct qcom_cc_desc *desc) 31 + { 32 + void __iomem *base; 33 + struct resource *res; 34 + int i, ret; 35 + struct device *dev = &pdev->dev; 36 + struct clk *clk; 37 + struct clk_onecell_data *data; 38 + struct clk **clks; 39 + struct regmap *regmap; 40 + struct qcom_reset_controller *reset; 41 + struct qcom_cc *cc; 42 + size_t num_clks = desc->num_clks; 43 + struct clk_regmap **rclks = desc->clks; 44 + 45 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 46 + base = devm_ioremap_resource(dev, res); 47 + if (IS_ERR(base)) 48 + return PTR_ERR(base); 49 + 50 + regmap = devm_regmap_init_mmio(dev, base, desc->config); 51 + if (IS_ERR(regmap)) 52 + return PTR_ERR(regmap); 53 + 54 + cc = devm_kzalloc(dev, sizeof(*cc) + sizeof(*clks) * num_clks, 55 + GFP_KERNEL); 56 + if (!cc) 57 + return -ENOMEM; 58 + 59 + clks = cc->clks; 60 + data = &cc->data; 61 + data->clks = clks; 62 + data->clk_num = num_clks; 63 + 64 + for (i = 0; i < num_clks; i++) { 65 + if (!rclks[i]) { 66 + clks[i] = ERR_PTR(-ENOENT); 67 + continue; 68 + } 69 + clk = devm_clk_register_regmap(dev, rclks[i]); 70 + if (IS_ERR(clk)) 71 + return PTR_ERR(clk); 72 + clks[i] = clk; 73 + } 74 + 75 + ret = of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, data); 76 + if (ret) 77 + return ret; 78 + 79 + reset = &cc->reset; 80 + reset->rcdev.of_node = dev->of_node; 81 + reset->rcdev.ops = &qcom_reset_ops; 82 + reset->rcdev.owner = dev->driver->owner; 83 + reset->rcdev.nr_resets = desc->num_resets; 84 + reset->regmap = regmap; 85 + reset->reset_map = desc->resets; 86 + platform_set_drvdata(pdev, &reset->rcdev); 87 + 88 + ret = reset_controller_register(&reset->rcdev); 89 + if (ret) 90 + of_clk_del_provider(dev->of_node); 91 + 92 + return ret; 93 + } 94 + EXPORT_SYMBOL_GPL(qcom_cc_probe); 95 + 96 + void qcom_cc_remove(struct platform_device *pdev) 97 + { 98 + of_clk_del_provider(pdev->dev.of_node); 99 + reset_controller_unregister(platform_get_drvdata(pdev)); 100 + } 101 + EXPORT_SYMBOL_GPL(qcom_cc_remove);
+34
drivers/clk/qcom/common.h
··· 1 + /* 2 + * Copyright (c) 2014, The Linux Foundation. All rights reserved. 3 + * 4 + * This software is licensed under the terms of the GNU General Public 5 + * License version 2, as published by the Free Software Foundation, and 6 + * may be copied, distributed, and modified under those terms. 7 + * 8 + * This program is distributed in the hope that it will be useful, 9 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 + * GNU General Public License for more details. 12 + */ 13 + #ifndef __QCOM_CLK_COMMON_H__ 14 + #define __QCOM_CLK_COMMON_H__ 15 + 16 + struct platform_device; 17 + struct regmap_config; 18 + struct clk_regmap; 19 + struct qcom_reset_map; 20 + 21 + struct qcom_cc_desc { 22 + const struct regmap_config *config; 23 + struct clk_regmap **clks; 24 + size_t num_clks; 25 + const struct qcom_reset_map *resets; 26 + size_t num_resets; 27 + }; 28 + 29 + extern int qcom_cc_probe(struct platform_device *pdev, 30 + const struct qcom_cc_desc *desc); 31 + 32 + extern void qcom_cc_remove(struct platform_device *pdev); 33 + 34 + #endif
+12 -65
drivers/clk/qcom/gcc-msm8660.c
··· 25 25 #include <dt-bindings/clock/qcom,gcc-msm8660.h> 26 26 #include <dt-bindings/reset/qcom,gcc-msm8660.h> 27 27 28 + #include "common.h" 28 29 #include "clk-regmap.h" 29 30 #include "clk-pll.h" 30 31 #include "clk-rcg.h" ··· 2702 2701 .fast_io = true, 2703 2702 }; 2704 2703 2704 + static const struct qcom_cc_desc gcc_msm8660_desc = { 2705 + .config = &gcc_msm8660_regmap_config, 2706 + .clks = gcc_msm8660_clks, 2707 + .num_clks = ARRAY_SIZE(gcc_msm8660_clks), 2708 + .resets = gcc_msm8660_resets, 2709 + .num_resets = ARRAY_SIZE(gcc_msm8660_resets), 2710 + }; 2711 + 2705 2712 static const struct of_device_id gcc_msm8660_match_table[] = { 2706 2713 { .compatible = "qcom,gcc-msm8660" }, 2707 2714 { } 2708 2715 }; 2709 2716 MODULE_DEVICE_TABLE(of, gcc_msm8660_match_table); 2710 2717 2711 - struct qcom_cc { 2712 - struct qcom_reset_controller reset; 2713 - struct clk_onecell_data data; 2714 - struct clk *clks[]; 2715 - }; 2716 - 2717 2718 static int gcc_msm8660_probe(struct platform_device *pdev) 2718 2719 { 2719 - void __iomem *base; 2720 - struct resource *res; 2721 - int i, ret; 2722 - struct device *dev = &pdev->dev; 2723 2720 struct clk *clk; 2724 - struct clk_onecell_data *data; 2725 - struct clk **clks; 2726 - struct regmap *regmap; 2727 - size_t num_clks; 2728 - struct qcom_reset_controller *reset; 2729 - struct qcom_cc *cc; 2730 - 2731 - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 2732 - base = devm_ioremap_resource(dev, res); 2733 - if (IS_ERR(base)) 2734 - return PTR_ERR(base); 2735 - 2736 - regmap = devm_regmap_init_mmio(dev, base, &gcc_msm8660_regmap_config); 2737 - if (IS_ERR(regmap)) 2738 - return PTR_ERR(regmap); 2739 - 2740 - num_clks = ARRAY_SIZE(gcc_msm8660_clks); 2741 - cc = devm_kzalloc(dev, sizeof(*cc) + sizeof(*clks) * num_clks, 2742 - GFP_KERNEL); 2743 - if (!cc) 2744 - return -ENOMEM; 2745 - 2746 - clks = cc->clks; 2747 - data = &cc->data; 2748 - data->clks = clks; 2749 - data->clk_num = num_clks; 2721 + struct device *dev = &pdev->dev; 2750 2722 2751 2723 /* Temporary until RPM clocks supported */ 2752 2724 clk = clk_register_fixed_rate(dev, "cxo", NULL, CLK_IS_ROOT, 19200000); ··· 2730 2756 if (IS_ERR(clk)) 2731 2757 return PTR_ERR(clk); 2732 2758 2733 - for (i = 0; i < num_clks; i++) { 2734 - if (!gcc_msm8660_clks[i]) 2735 - continue; 2736 - clk = devm_clk_register_regmap(dev, gcc_msm8660_clks[i]); 2737 - if (IS_ERR(clk)) 2738 - return PTR_ERR(clk); 2739 - clks[i] = clk; 2740 - } 2741 - 2742 - ret = of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, data); 2743 - if (ret) 2744 - return ret; 2745 - 2746 - reset = &cc->reset; 2747 - reset->rcdev.of_node = dev->of_node; 2748 - reset->rcdev.ops = &qcom_reset_ops, 2749 - reset->rcdev.owner = THIS_MODULE, 2750 - reset->rcdev.nr_resets = ARRAY_SIZE(gcc_msm8660_resets), 2751 - reset->regmap = regmap; 2752 - reset->reset_map = gcc_msm8660_resets, 2753 - platform_set_drvdata(pdev, &reset->rcdev); 2754 - 2755 - ret = reset_controller_register(&reset->rcdev); 2756 - if (ret) 2757 - of_clk_del_provider(dev->of_node); 2758 - 2759 - return ret; 2759 + return qcom_cc_probe(pdev, &gcc_msm8660_desc); 2760 2760 } 2761 2761 2762 2762 static int gcc_msm8660_remove(struct platform_device *pdev) 2763 2763 { 2764 - of_clk_del_provider(pdev->dev.of_node); 2765 - reset_controller_unregister(platform_get_drvdata(pdev)); 2764 + qcom_cc_remove(pdev); 2766 2765 return 0; 2767 2766 } 2768 2767
+39 -68
drivers/clk/qcom/gcc-msm8960.c
··· 1 1 /* 2 - * Copyright (c) 2013, The Linux Foundation. All rights reserved. 2 + * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. 3 3 * 4 4 * This software is licensed under the terms of the GNU General Public 5 5 * License version 2, as published by the Free Software Foundation, and ··· 25 25 #include <dt-bindings/clock/qcom,gcc-msm8960.h> 26 26 #include <dt-bindings/reset/qcom,gcc-msm8960.h> 27 27 28 + #include "common.h" 28 29 #include "clk-regmap.h" 29 30 #include "clk-pll.h" 30 31 #include "clk-rcg.h" ··· 2810 2809 [PPSS_PROC_RESET] = { 0x2594, 1 }, 2811 2810 [PPSS_RESET] = { 0x2594}, 2812 2811 [DMA_BAM_RESET] = { 0x25c0, 7 }, 2813 - [SIC_TIC_RESET] = { 0x2600, 7 }, 2812 + [SPS_TIC_H_RESET] = { 0x2600, 7 }, 2814 2813 [SLIMBUS_H_RESET] = { 0x2620, 7 }, 2815 2814 [SFAB_CFPB_M_RESET] = { 0x2680, 7 }, 2816 2815 [SFAB_CFPB_S_RESET] = { 0x26c0, 7 }, ··· 2823 2822 [SFAB_SFPB_M_RESET] = { 0x2780, 7 }, 2824 2823 [SFAB_SFPB_S_RESET] = { 0x27a0, 7 }, 2825 2824 [RPM_PROC_RESET] = { 0x27c0, 7 }, 2826 - [PMIC_SSBI2_RESET] = { 0x270c, 12 }, 2825 + [PMIC_SSBI2_RESET] = { 0x280c, 12 }, 2827 2826 [SDC1_RESET] = { 0x2830 }, 2828 2827 [SDC2_RESET] = { 0x2850 }, 2829 2828 [SDC3_RESET] = { 0x2870 }, ··· 2868 2867 [RIVA_RESET] = { 0x35e0 }, 2869 2868 }; 2870 2869 2870 + static struct clk_regmap *gcc_apq8064_clks[] = { 2871 + [PLL8] = &pll8.clkr, 2872 + [PLL8_VOTE] = &pll8_vote, 2873 + [GSBI7_UART_SRC] = &gsbi7_uart_src.clkr, 2874 + [GSBI7_UART_CLK] = &gsbi7_uart_clk.clkr, 2875 + [GSBI7_QUP_SRC] = &gsbi7_qup_src.clkr, 2876 + [GSBI7_QUP_CLK] = &gsbi7_qup_clk.clkr, 2877 + [GSBI7_H_CLK] = &gsbi7_h_clk.clkr, 2878 + }; 2879 + 2871 2880 static const struct regmap_config gcc_msm8960_regmap_config = { 2872 2881 .reg_bits = 32, 2873 2882 .reg_stride = 4, ··· 2886 2875 .fast_io = true, 2887 2876 }; 2888 2877 2878 + static const struct qcom_cc_desc gcc_msm8960_desc = { 2879 + .config = &gcc_msm8960_regmap_config, 2880 + .clks = gcc_msm8960_clks, 2881 + .num_clks = ARRAY_SIZE(gcc_msm8960_clks), 2882 + .resets = gcc_msm8960_resets, 2883 + .num_resets = ARRAY_SIZE(gcc_msm8960_resets), 2884 + }; 2885 + 2886 + static const struct qcom_cc_desc gcc_apq8064_desc = { 2887 + .config = &gcc_msm8960_regmap_config, 2888 + .clks = gcc_apq8064_clks, 2889 + .num_clks = ARRAY_SIZE(gcc_apq8064_clks), 2890 + .resets = gcc_msm8960_resets, 2891 + .num_resets = ARRAY_SIZE(gcc_msm8960_resets), 2892 + }; 2893 + 2889 2894 static const struct of_device_id gcc_msm8960_match_table[] = { 2890 - { .compatible = "qcom,gcc-msm8960" }, 2895 + { .compatible = "qcom,gcc-msm8960", .data = &gcc_msm8960_desc }, 2896 + { .compatible = "qcom,gcc-apq8064", .data = &gcc_apq8064_desc }, 2891 2897 { } 2892 2898 }; 2893 2899 MODULE_DEVICE_TABLE(of, gcc_msm8960_match_table); 2894 2900 2895 - struct qcom_cc { 2896 - struct qcom_reset_controller reset; 2897 - struct clk_onecell_data data; 2898 - struct clk *clks[]; 2899 - }; 2900 - 2901 2901 static int gcc_msm8960_probe(struct platform_device *pdev) 2902 2902 { 2903 - void __iomem *base; 2904 - struct resource *res; 2905 - int i, ret; 2906 - struct device *dev = &pdev->dev; 2907 2903 struct clk *clk; 2908 - struct clk_onecell_data *data; 2909 - struct clk **clks; 2910 - struct regmap *regmap; 2911 - size_t num_clks; 2912 - struct qcom_reset_controller *reset; 2913 - struct qcom_cc *cc; 2904 + struct device *dev = &pdev->dev; 2905 + const struct of_device_id *match; 2914 2906 2915 - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 2916 - base = devm_ioremap_resource(dev, res); 2917 - if (IS_ERR(base)) 2918 - return PTR_ERR(base); 2919 - 2920 - regmap = devm_regmap_init_mmio(dev, base, &gcc_msm8960_regmap_config); 2921 - if (IS_ERR(regmap)) 2922 - return PTR_ERR(regmap); 2923 - 2924 - num_clks = ARRAY_SIZE(gcc_msm8960_clks); 2925 - cc = devm_kzalloc(dev, sizeof(*cc) + sizeof(*clks) * num_clks, 2926 - GFP_KERNEL); 2927 - if (!cc) 2928 - return -ENOMEM; 2929 - 2930 - clks = cc->clks; 2931 - data = &cc->data; 2932 - data->clks = clks; 2933 - data->clk_num = num_clks; 2907 + match = of_match_device(gcc_msm8960_match_table, &pdev->dev); 2908 + if (!match) 2909 + return -EINVAL; 2934 2910 2935 2911 /* Temporary until RPM clocks supported */ 2936 2912 clk = clk_register_fixed_rate(dev, "cxo", NULL, CLK_IS_ROOT, 19200000); ··· 2928 2930 if (IS_ERR(clk)) 2929 2931 return PTR_ERR(clk); 2930 2932 2931 - for (i = 0; i < num_clks; i++) { 2932 - if (!gcc_msm8960_clks[i]) 2933 - continue; 2934 - clk = devm_clk_register_regmap(dev, gcc_msm8960_clks[i]); 2935 - if (IS_ERR(clk)) 2936 - return PTR_ERR(clk); 2937 - clks[i] = clk; 2938 - } 2939 - 2940 - ret = of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, data); 2941 - if (ret) 2942 - return ret; 2943 - 2944 - reset = &cc->reset; 2945 - reset->rcdev.of_node = dev->of_node; 2946 - reset->rcdev.ops = &qcom_reset_ops, 2947 - reset->rcdev.owner = THIS_MODULE, 2948 - reset->rcdev.nr_resets = ARRAY_SIZE(gcc_msm8960_resets), 2949 - reset->regmap = regmap; 2950 - reset->reset_map = gcc_msm8960_resets, 2951 - platform_set_drvdata(pdev, &reset->rcdev); 2952 - 2953 - ret = reset_controller_register(&reset->rcdev); 2954 - if (ret) 2955 - of_clk_del_provider(dev->of_node); 2956 - 2957 - return ret; 2933 + return qcom_cc_probe(pdev, match->data); 2958 2934 } 2959 2935 2960 2936 static int gcc_msm8960_remove(struct platform_device *pdev) 2961 2937 { 2962 - of_clk_del_provider(pdev->dev.of_node); 2963 - reset_controller_unregister(platform_get_drvdata(pdev)); 2938 + qcom_cc_remove(pdev); 2964 2939 return 0; 2965 2940 } 2966 2941
+134 -69
drivers/clk/qcom/gcc-msm8974.c
··· 25 25 #include <dt-bindings/clock/qcom,gcc-msm8974.h> 26 26 #include <dt-bindings/reset/qcom,gcc-msm8974.h> 27 27 28 + #include "common.h" 28 29 #include "clk-regmap.h" 29 30 #include "clk-pll.h" 30 31 #include "clk-rcg.h" ··· 35 34 #define P_XO 0 36 35 #define P_GPLL0 1 37 36 #define P_GPLL1 1 37 + #define P_GPLL4 2 38 38 39 39 static const u8 gcc_xo_gpll0_map[] = { 40 40 [P_XO] = 0, ··· 45 43 static const char *gcc_xo_gpll0[] = { 46 44 "xo", 47 45 "gpll0_vote", 46 + }; 47 + 48 + static const u8 gcc_xo_gpll0_gpll4_map[] = { 49 + [P_XO] = 0, 50 + [P_GPLL0] = 1, 51 + [P_GPLL4] = 5, 52 + }; 53 + 54 + static const char *gcc_xo_gpll0_gpll4[] = { 55 + "xo", 56 + "gpll0_vote", 57 + "gpll4_vote", 48 58 }; 49 59 50 60 #define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } ··· 146 132 .hw.init = &(struct clk_init_data){ 147 133 .name = "gpll1_vote", 148 134 .parent_names = (const char *[]){ "gpll1" }, 135 + .num_parents = 1, 136 + .ops = &clk_pll_vote_ops, 137 + }, 138 + }; 139 + 140 + static struct clk_pll gpll4 = { 141 + .l_reg = 0x1dc4, 142 + .m_reg = 0x1dc8, 143 + .n_reg = 0x1dcc, 144 + .config_reg = 0x1dd4, 145 + .mode_reg = 0x1dc0, 146 + .status_reg = 0x1ddc, 147 + .status_bit = 17, 148 + .clkr.hw.init = &(struct clk_init_data){ 149 + .name = "gpll4", 150 + .parent_names = (const char *[]){ "xo" }, 151 + .num_parents = 1, 152 + .ops = &clk_pll_ops, 153 + }, 154 + }; 155 + 156 + static struct clk_regmap gpll4_vote = { 157 + .enable_reg = 0x1480, 158 + .enable_mask = BIT(4), 159 + .hw.init = &(struct clk_init_data){ 160 + .name = "gpll4_vote", 161 + .parent_names = (const char *[]){ "gpll4" }, 149 162 .num_parents = 1, 150 163 .ops = &clk_pll_vote_ops, 151 164 }, ··· 852 811 { } 853 812 }; 854 813 814 + static const struct freq_tbl ftbl_gcc_sdcc1_apps_clk_pro[] = { 815 + F(144000, P_XO, 16, 3, 25), 816 + F(400000, P_XO, 12, 1, 4), 817 + F(20000000, P_GPLL0, 15, 1, 2), 818 + F(25000000, P_GPLL0, 12, 1, 2), 819 + F(50000000, P_GPLL0, 12, 0, 0), 820 + F(100000000, P_GPLL0, 6, 0, 0), 821 + F(192000000, P_GPLL4, 4, 0, 0), 822 + F(200000000, P_GPLL0, 3, 0, 0), 823 + F(384000000, P_GPLL4, 2, 0, 0), 824 + { } 825 + }; 826 + 827 + static struct clk_init_data sdcc1_apps_clk_src_init = { 828 + .name = "sdcc1_apps_clk_src", 829 + .parent_names = gcc_xo_gpll0, 830 + .num_parents = 2, 831 + .ops = &clk_rcg2_ops, 832 + }; 833 + 855 834 static struct clk_rcg2 sdcc1_apps_clk_src = { 856 835 .cmd_rcgr = 0x04d0, 857 836 .mnd_width = 8, 858 837 .hid_width = 5, 859 838 .parent_map = gcc_xo_gpll0_map, 860 839 .freq_tbl = ftbl_gcc_sdcc1_4_apps_clk, 861 - .clkr.hw.init = &(struct clk_init_data){ 862 - .name = "sdcc1_apps_clk_src", 863 - .parent_names = gcc_xo_gpll0, 864 - .num_parents = 2, 865 - .ops = &clk_rcg2_ops, 866 - }, 840 + .clkr.hw.init = &sdcc1_apps_clk_src_init, 867 841 }; 868 842 869 843 static struct clk_rcg2 sdcc2_apps_clk_src = { ··· 1396 1340 }; 1397 1341 1398 1342 static struct clk_branch gcc_blsp2_ahb_clk = { 1399 - .halt_reg = 0x05c4, 1343 + .halt_reg = 0x0944, 1400 1344 .halt_check = BRANCH_HALT_VOTED, 1401 1345 .clkr = { 1402 1346 .enable_reg = 0x1484, ··· 2050 1994 }, 2051 1995 }; 2052 1996 1997 + static struct clk_branch gcc_sdcc1_cdccal_ff_clk = { 1998 + .halt_reg = 0x04e8, 1999 + .clkr = { 2000 + .enable_reg = 0x04e8, 2001 + .enable_mask = BIT(0), 2002 + .hw.init = &(struct clk_init_data){ 2003 + .name = "gcc_sdcc1_cdccal_ff_clk", 2004 + .parent_names = (const char *[]){ 2005 + "xo" 2006 + }, 2007 + .num_parents = 1, 2008 + .ops = &clk_branch2_ops, 2009 + }, 2010 + }, 2011 + }; 2012 + 2013 + static struct clk_branch gcc_sdcc1_cdccal_sleep_clk = { 2014 + .halt_reg = 0x04e4, 2015 + .clkr = { 2016 + .enable_reg = 0x04e4, 2017 + .enable_mask = BIT(0), 2018 + .hw.init = &(struct clk_init_data){ 2019 + .name = "gcc_sdcc1_cdccal_sleep_clk", 2020 + .parent_names = (const char *[]){ 2021 + "sleep_clk_src" 2022 + }, 2023 + .num_parents = 1, 2024 + .ops = &clk_branch2_ops, 2025 + }, 2026 + }, 2027 + }; 2028 + 2053 2029 static struct clk_branch gcc_sdcc2_ahb_clk = { 2054 2030 .halt_reg = 0x0508, 2055 2031 .clkr = { ··· 2571 2483 [GCC_USB_HSIC_IO_CAL_SLEEP_CLK] = &gcc_usb_hsic_io_cal_sleep_clk.clkr, 2572 2484 [GCC_USB_HSIC_SYSTEM_CLK] = &gcc_usb_hsic_system_clk.clkr, 2573 2485 [GCC_MMSS_GPLL0_CLK_SRC] = &gcc_mmss_gpll0_clk_src, 2486 + [GPLL4] = NULL, 2487 + [GPLL4_VOTE] = NULL, 2488 + [GCC_SDCC1_CDCCAL_SLEEP_CLK] = NULL, 2489 + [GCC_SDCC1_CDCCAL_FF_CLK] = NULL, 2574 2490 }; 2575 2491 2576 2492 static const struct qcom_reset_map gcc_msm8974_resets[] = { ··· 2666 2574 .fast_io = true, 2667 2575 }; 2668 2576 2577 + static const struct qcom_cc_desc gcc_msm8974_desc = { 2578 + .config = &gcc_msm8974_regmap_config, 2579 + .clks = gcc_msm8974_clocks, 2580 + .num_clks = ARRAY_SIZE(gcc_msm8974_clocks), 2581 + .resets = gcc_msm8974_resets, 2582 + .num_resets = ARRAY_SIZE(gcc_msm8974_resets), 2583 + }; 2584 + 2669 2585 static const struct of_device_id gcc_msm8974_match_table[] = { 2670 2586 { .compatible = "qcom,gcc-msm8974" }, 2587 + { .compatible = "qcom,gcc-msm8974pro" , .data = (void *)1UL }, 2588 + { .compatible = "qcom,gcc-msm8974pro-ac", .data = (void *)1UL }, 2671 2589 { } 2672 2590 }; 2673 2591 MODULE_DEVICE_TABLE(of, gcc_msm8974_match_table); 2674 2592 2675 - struct qcom_cc { 2676 - struct qcom_reset_controller reset; 2677 - struct clk_onecell_data data; 2678 - struct clk *clks[]; 2679 - }; 2593 + static void msm8974_pro_clock_override(void) 2594 + { 2595 + sdcc1_apps_clk_src_init.parent_names = gcc_xo_gpll0_gpll4; 2596 + sdcc1_apps_clk_src_init.num_parents = 3; 2597 + sdcc1_apps_clk_src.freq_tbl = ftbl_gcc_sdcc1_apps_clk_pro; 2598 + sdcc1_apps_clk_src.parent_map = gcc_xo_gpll0_gpll4_map; 2599 + 2600 + gcc_msm8974_clocks[GPLL4] = &gpll4.clkr; 2601 + gcc_msm8974_clocks[GPLL4_VOTE] = &gpll4_vote; 2602 + gcc_msm8974_clocks[GCC_SDCC1_CDCCAL_SLEEP_CLK] = 2603 + &gcc_sdcc1_cdccal_sleep_clk.clkr; 2604 + gcc_msm8974_clocks[GCC_SDCC1_CDCCAL_FF_CLK] = 2605 + &gcc_sdcc1_cdccal_ff_clk.clkr; 2606 + } 2680 2607 2681 2608 static int gcc_msm8974_probe(struct platform_device *pdev) 2682 2609 { 2683 - void __iomem *base; 2684 - struct resource *res; 2685 - int i, ret; 2686 - struct device *dev = &pdev->dev; 2687 2610 struct clk *clk; 2688 - struct clk_onecell_data *data; 2689 - struct clk **clks; 2690 - struct regmap *regmap; 2691 - size_t num_clks; 2692 - struct qcom_reset_controller *reset; 2693 - struct qcom_cc *cc; 2611 + struct device *dev = &pdev->dev; 2612 + bool pro; 2613 + const struct of_device_id *id; 2694 2614 2695 - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 2696 - base = devm_ioremap_resource(dev, res); 2697 - if (IS_ERR(base)) 2698 - return PTR_ERR(base); 2615 + id = of_match_device(gcc_msm8974_match_table, dev); 2616 + if (!id) 2617 + return -ENODEV; 2618 + pro = !!(id->data); 2699 2619 2700 - regmap = devm_regmap_init_mmio(dev, base, &gcc_msm8974_regmap_config); 2701 - if (IS_ERR(regmap)) 2702 - return PTR_ERR(regmap); 2703 - 2704 - num_clks = ARRAY_SIZE(gcc_msm8974_clocks); 2705 - cc = devm_kzalloc(dev, sizeof(*cc) + sizeof(*clks) * num_clks, 2706 - GFP_KERNEL); 2707 - if (!cc) 2708 - return -ENOMEM; 2709 - 2710 - clks = cc->clks; 2711 - data = &cc->data; 2712 - data->clks = clks; 2713 - data->clk_num = num_clks; 2620 + if (pro) 2621 + msm8974_pro_clock_override(); 2714 2622 2715 2623 /* Temporary until RPM clocks supported */ 2716 2624 clk = clk_register_fixed_rate(dev, "xo", NULL, CLK_IS_ROOT, 19200000); ··· 2723 2631 if (IS_ERR(clk)) 2724 2632 return PTR_ERR(clk); 2725 2633 2726 - for (i = 0; i < num_clks; i++) { 2727 - if (!gcc_msm8974_clocks[i]) 2728 - continue; 2729 - clk = devm_clk_register_regmap(dev, gcc_msm8974_clocks[i]); 2730 - if (IS_ERR(clk)) 2731 - return PTR_ERR(clk); 2732 - clks[i] = clk; 2733 - } 2734 - 2735 - ret = of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, data); 2736 - if (ret) 2737 - return ret; 2738 - 2739 - reset = &cc->reset; 2740 - reset->rcdev.of_node = dev->of_node; 2741 - reset->rcdev.ops = &qcom_reset_ops, 2742 - reset->rcdev.owner = THIS_MODULE, 2743 - reset->rcdev.nr_resets = ARRAY_SIZE(gcc_msm8974_resets), 2744 - reset->regmap = regmap; 2745 - reset->reset_map = gcc_msm8974_resets, 2746 - platform_set_drvdata(pdev, &reset->rcdev); 2747 - 2748 - ret = reset_controller_register(&reset->rcdev); 2749 - if (ret) 2750 - of_clk_del_provider(dev->of_node); 2751 - 2752 - return ret; 2634 + return qcom_cc_probe(pdev, &gcc_msm8974_desc); 2753 2635 } 2754 2636 2755 2637 static int gcc_msm8974_remove(struct platform_device *pdev) 2756 2638 { 2757 - of_clk_del_provider(pdev->dev.of_node); 2758 - reset_controller_unregister(platform_get_drvdata(pdev)); 2639 + qcom_cc_remove(pdev); 2759 2640 return 0; 2760 2641 } 2761 2642
+11 -67
drivers/clk/qcom/mmcc-msm8960.c
··· 26 26 #include <dt-bindings/clock/qcom,mmcc-msm8960.h> 27 27 #include <dt-bindings/reset/qcom,mmcc-msm8960.h> 28 28 29 + #include "common.h" 29 30 #include "clk-regmap.h" 30 31 #include "clk-pll.h" 31 32 #include "clk-rcg.h" ··· 2223 2222 .fast_io = true, 2224 2223 }; 2225 2224 2225 + static const struct qcom_cc_desc mmcc_msm8960_desc = { 2226 + .config = &mmcc_msm8960_regmap_config, 2227 + .clks = mmcc_msm8960_clks, 2228 + .num_clks = ARRAY_SIZE(mmcc_msm8960_clks), 2229 + .resets = mmcc_msm8960_resets, 2230 + .num_resets = ARRAY_SIZE(mmcc_msm8960_resets), 2231 + }; 2232 + 2226 2233 static const struct of_device_id mmcc_msm8960_match_table[] = { 2227 2234 { .compatible = "qcom,mmcc-msm8960" }, 2228 2235 { } 2229 2236 }; 2230 2237 MODULE_DEVICE_TABLE(of, mmcc_msm8960_match_table); 2231 2238 2232 - struct qcom_cc { 2233 - struct qcom_reset_controller reset; 2234 - struct clk_onecell_data data; 2235 - struct clk *clks[]; 2236 - }; 2237 - 2238 2239 static int mmcc_msm8960_probe(struct platform_device *pdev) 2239 2240 { 2240 - void __iomem *base; 2241 - struct resource *res; 2242 - int i, ret; 2243 - struct device *dev = &pdev->dev; 2244 - struct clk *clk; 2245 - struct clk_onecell_data *data; 2246 - struct clk **clks; 2247 - struct regmap *regmap; 2248 - size_t num_clks; 2249 - struct qcom_reset_controller *reset; 2250 - struct qcom_cc *cc; 2251 - 2252 - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 2253 - base = devm_ioremap_resource(dev, res); 2254 - if (IS_ERR(base)) 2255 - return PTR_ERR(base); 2256 - 2257 - regmap = devm_regmap_init_mmio(dev, base, &mmcc_msm8960_regmap_config); 2258 - if (IS_ERR(regmap)) 2259 - return PTR_ERR(regmap); 2260 - 2261 - num_clks = ARRAY_SIZE(mmcc_msm8960_clks); 2262 - cc = devm_kzalloc(dev, sizeof(*cc) + sizeof(*clks) * num_clks, 2263 - GFP_KERNEL); 2264 - if (!cc) 2265 - return -ENOMEM; 2266 - 2267 - clks = cc->clks; 2268 - data = &cc->data; 2269 - data->clks = clks; 2270 - data->clk_num = num_clks; 2271 - 2272 - for (i = 0; i < num_clks; i++) { 2273 - if (!mmcc_msm8960_clks[i]) 2274 - continue; 2275 - clk = devm_clk_register_regmap(dev, mmcc_msm8960_clks[i]); 2276 - if (IS_ERR(clk)) 2277 - return PTR_ERR(clk); 2278 - clks[i] = clk; 2279 - } 2280 - 2281 - ret = of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, data); 2282 - if (ret) 2283 - return ret; 2284 - 2285 - reset = &cc->reset; 2286 - reset->rcdev.of_node = dev->of_node; 2287 - reset->rcdev.ops = &qcom_reset_ops, 2288 - reset->rcdev.owner = THIS_MODULE, 2289 - reset->rcdev.nr_resets = ARRAY_SIZE(mmcc_msm8960_resets), 2290 - reset->regmap = regmap; 2291 - reset->reset_map = mmcc_msm8960_resets, 2292 - platform_set_drvdata(pdev, &reset->rcdev); 2293 - 2294 - ret = reset_controller_register(&reset->rcdev); 2295 - if (ret) 2296 - of_clk_del_provider(dev->of_node); 2297 - 2298 - return ret; 2241 + return qcom_cc_probe(pdev, &mmcc_msm8960_desc); 2299 2242 } 2300 2243 2301 2244 static int mmcc_msm8960_remove(struct platform_device *pdev) 2302 2245 { 2303 - of_clk_del_provider(pdev->dev.of_node); 2304 - reset_controller_unregister(platform_get_drvdata(pdev)); 2246 + qcom_cc_remove(pdev); 2305 2247 return 0; 2306 2248 } 2307 2249
+78 -120
drivers/clk/qcom/mmcc-msm8974.c
··· 25 25 #include <dt-bindings/clock/qcom,mmcc-msm8974.h> 26 26 #include <dt-bindings/reset/qcom,mmcc-msm8974.h> 27 27 28 + #include "common.h" 28 29 #include "clk-regmap.h" 29 30 #include "clk-pll.h" 30 31 #include "clk-rcg.h" ··· 41 40 #define P_EDPVCO 3 42 41 #define P_GPLL1 4 43 42 #define P_DSI0PLL 4 43 + #define P_DSI0PLL_BYTE 4 44 44 #define P_MMPLL2 4 45 45 #define P_MMPLL3 4 46 46 #define P_DSI1PLL 5 47 + #define P_DSI1PLL_BYTE 5 47 48 48 49 static const u8 mmcc_xo_mmpll0_mmpll1_gpll0_map[] = { 49 50 [P_XO] = 0, ··· 163 160 "dsi1pll", 164 161 }; 165 162 163 + static const u8 mmcc_xo_dsibyte_hdmi_edp_gpll0_map[] = { 164 + [P_XO] = 0, 165 + [P_EDPLINK] = 4, 166 + [P_HDMIPLL] = 3, 167 + [P_GPLL0] = 5, 168 + [P_DSI0PLL_BYTE] = 1, 169 + [P_DSI1PLL_BYTE] = 2, 170 + }; 171 + 172 + static const char *mmcc_xo_dsibyte_hdmi_edp_gpll0[] = { 173 + "xo", 174 + "edp_link_clk", 175 + "hdmipll", 176 + "gpll0_vote", 177 + "dsi0pllbyte", 178 + "dsi1pllbyte", 179 + }; 180 + 166 181 #define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } 167 182 168 183 static struct clk_pll mmpll0 = { ··· 190 169 .config_reg = 0x0014, 191 170 .mode_reg = 0x0000, 192 171 .status_reg = 0x001c, 172 + .status_bit = 17, 193 173 .clkr.hw.init = &(struct clk_init_data){ 194 174 .name = "mmpll0", 195 175 .parent_names = (const char *[]){ "xo" }, ··· 214 192 .l_reg = 0x0044, 215 193 .m_reg = 0x0048, 216 194 .n_reg = 0x004c, 217 - .config_reg = 0x0054, 195 + .config_reg = 0x0050, 218 196 .mode_reg = 0x0040, 219 197 .status_reg = 0x005c, 198 + .status_bit = 17, 220 199 .clkr.hw.init = &(struct clk_init_data){ 221 200 .name = "mmpll1", 222 201 .parent_names = (const char *[]){ "xo" }, ··· 241 218 .l_reg = 0x4104, 242 219 .m_reg = 0x4108, 243 220 .n_reg = 0x410c, 244 - .config_reg = 0x4114, 221 + .config_reg = 0x4110, 245 222 .mode_reg = 0x4100, 246 223 .status_reg = 0x411c, 247 224 .clkr.hw.init = &(struct clk_init_data){ ··· 256 233 .l_reg = 0x0084, 257 234 .m_reg = 0x0088, 258 235 .n_reg = 0x008c, 259 - .config_reg = 0x0094, 236 + .config_reg = 0x0090, 260 237 .mode_reg = 0x0080, 261 238 .status_reg = 0x009c, 239 + .status_bit = 17, 262 240 .clkr.hw.init = &(struct clk_init_data){ 263 241 .name = "mmpll3", 264 242 .parent_names = (const char *[]){ "xo" }, ··· 520 496 }, 521 497 }; 522 498 523 - static struct freq_tbl ftbl_mdss_pclk0_clk[] = { 524 - F(125000000, P_DSI0PLL, 2, 0, 0), 525 - F(250000000, P_DSI0PLL, 1, 0, 0), 526 - { } 527 - }; 528 - 529 - static struct freq_tbl ftbl_mdss_pclk1_clk[] = { 530 - F(125000000, P_DSI1PLL, 2, 0, 0), 531 - F(250000000, P_DSI1PLL, 1, 0, 0), 499 + static struct freq_tbl pixel_freq_tbl[] = { 500 + { .src = P_DSI0PLL }, 532 501 { } 533 502 }; 534 503 ··· 530 513 .mnd_width = 8, 531 514 .hid_width = 5, 532 515 .parent_map = mmcc_xo_dsi_hdmi_edp_gpll0_map, 533 - .freq_tbl = ftbl_mdss_pclk0_clk, 516 + .freq_tbl = pixel_freq_tbl, 534 517 .clkr.hw.init = &(struct clk_init_data){ 535 518 .name = "pclk0_clk_src", 536 519 .parent_names = mmcc_xo_dsi_hdmi_edp_gpll0, 537 520 .num_parents = 6, 538 - .ops = &clk_rcg2_ops, 521 + .ops = &clk_pixel_ops, 522 + .flags = CLK_SET_RATE_PARENT, 539 523 }, 540 524 }; 541 525 ··· 545 527 .mnd_width = 8, 546 528 .hid_width = 5, 547 529 .parent_map = mmcc_xo_dsi_hdmi_edp_gpll0_map, 548 - .freq_tbl = ftbl_mdss_pclk1_clk, 530 + .freq_tbl = pixel_freq_tbl, 549 531 .clkr.hw.init = &(struct clk_init_data){ 550 532 .name = "pclk1_clk_src", 551 533 .parent_names = mmcc_xo_dsi_hdmi_edp_gpll0, 552 534 .num_parents = 6, 553 - .ops = &clk_rcg2_ops, 535 + .ops = &clk_pixel_ops, 536 + .flags = CLK_SET_RATE_PARENT, 554 537 }, 555 538 }; 556 539 ··· 769 750 }, 770 751 }; 771 752 772 - static struct freq_tbl ftbl_mdss_byte0_clk[] = { 773 - F(93750000, P_DSI0PLL, 8, 0, 0), 774 - F(187500000, P_DSI0PLL, 4, 0, 0), 775 - { } 776 - }; 777 - 778 - static struct freq_tbl ftbl_mdss_byte1_clk[] = { 779 - F(93750000, P_DSI1PLL, 8, 0, 0), 780 - F(187500000, P_DSI1PLL, 4, 0, 0), 753 + static struct freq_tbl byte_freq_tbl[] = { 754 + { .src = P_DSI0PLL_BYTE }, 781 755 { } 782 756 }; 783 757 784 758 static struct clk_rcg2 byte0_clk_src = { 785 759 .cmd_rcgr = 0x2120, 786 760 .hid_width = 5, 787 - .parent_map = mmcc_xo_dsi_hdmi_edp_gpll0_map, 788 - .freq_tbl = ftbl_mdss_byte0_clk, 761 + .parent_map = mmcc_xo_dsibyte_hdmi_edp_gpll0_map, 762 + .freq_tbl = byte_freq_tbl, 789 763 .clkr.hw.init = &(struct clk_init_data){ 790 764 .name = "byte0_clk_src", 791 - .parent_names = mmcc_xo_dsi_hdmi_edp_gpll0, 765 + .parent_names = mmcc_xo_dsibyte_hdmi_edp_gpll0, 792 766 .num_parents = 6, 793 - .ops = &clk_rcg2_ops, 767 + .ops = &clk_byte_ops, 768 + .flags = CLK_SET_RATE_PARENT, 794 769 }, 795 770 }; 796 771 797 772 static struct clk_rcg2 byte1_clk_src = { 798 773 .cmd_rcgr = 0x2140, 799 774 .hid_width = 5, 800 - .parent_map = mmcc_xo_dsi_hdmi_edp_gpll0_map, 801 - .freq_tbl = ftbl_mdss_byte1_clk, 775 + .parent_map = mmcc_xo_dsibyte_hdmi_edp_gpll0_map, 776 + .freq_tbl = byte_freq_tbl, 802 777 .clkr.hw.init = &(struct clk_init_data){ 803 778 .name = "byte1_clk_src", 804 - .parent_names = mmcc_xo_dsi_hdmi_edp_gpll0, 779 + .parent_names = mmcc_xo_dsibyte_hdmi_edp_gpll0, 805 780 .num_parents = 6, 806 - .ops = &clk_rcg2_ops, 781 + .ops = &clk_byte_ops, 782 + .flags = CLK_SET_RATE_PARENT, 807 783 }, 808 784 }; 809 785 ··· 836 822 .parent_names = mmcc_xo_dsi_hdmi_edp_gpll0, 837 823 .num_parents = 6, 838 824 .ops = &clk_rcg2_ops, 825 + .flags = CLK_SET_RATE_PARENT, 839 826 }, 840 827 }; 841 828 842 - static struct freq_tbl ftbl_mdss_edppixel_clk[] = { 843 - F(175000000, P_EDPVCO, 2, 0, 0), 844 - F(350000000, P_EDPVCO, 11, 0, 0), 829 + static struct freq_tbl edp_pixel_freq_tbl[] = { 830 + { .src = P_EDPVCO }, 845 831 { } 846 832 }; 847 833 ··· 850 836 .mnd_width = 8, 851 837 .hid_width = 5, 852 838 .parent_map = mmcc_xo_dsi_hdmi_edp_map, 853 - .freq_tbl = ftbl_mdss_edppixel_clk, 839 + .freq_tbl = edp_pixel_freq_tbl, 854 840 .clkr.hw.init = &(struct clk_init_data){ 855 841 .name = "edppixel_clk_src", 856 842 .parent_names = mmcc_xo_dsi_hdmi_edp, 857 843 .num_parents = 6, 858 - .ops = &clk_rcg2_ops, 844 + .ops = &clk_edp_pixel_ops, 859 845 }, 860 846 }; 861 847 ··· 867 853 static struct clk_rcg2 esc0_clk_src = { 868 854 .cmd_rcgr = 0x2160, 869 855 .hid_width = 5, 870 - .parent_map = mmcc_xo_dsi_hdmi_edp_gpll0_map, 856 + .parent_map = mmcc_xo_dsibyte_hdmi_edp_gpll0_map, 871 857 .freq_tbl = ftbl_mdss_esc0_1_clk, 872 858 .clkr.hw.init = &(struct clk_init_data){ 873 859 .name = "esc0_clk_src", 874 - .parent_names = mmcc_xo_dsi_hdmi_edp_gpll0, 860 + .parent_names = mmcc_xo_dsibyte_hdmi_edp_gpll0, 875 861 .num_parents = 6, 876 862 .ops = &clk_rcg2_ops, 877 863 }, ··· 880 866 static struct clk_rcg2 esc1_clk_src = { 881 867 .cmd_rcgr = 0x2180, 882 868 .hid_width = 5, 883 - .parent_map = mmcc_xo_dsi_hdmi_edp_gpll0_map, 869 + .parent_map = mmcc_xo_dsibyte_hdmi_edp_gpll0_map, 884 870 .freq_tbl = ftbl_mdss_esc0_1_clk, 885 871 .clkr.hw.init = &(struct clk_init_data){ 886 872 .name = "esc1_clk_src", 887 - .parent_names = mmcc_xo_dsi_hdmi_edp_gpll0, 873 + .parent_names = mmcc_xo_dsibyte_hdmi_edp_gpll0, 888 874 .num_parents = 6, 889 875 .ops = &clk_rcg2_ops, 890 876 }, 891 877 }; 892 878 893 - static struct freq_tbl ftbl_mdss_extpclk_clk[] = { 894 - F(25200000, P_HDMIPLL, 1, 0, 0), 895 - F(27000000, P_HDMIPLL, 1, 0, 0), 896 - F(27030000, P_HDMIPLL, 1, 0, 0), 897 - F(65000000, P_HDMIPLL, 1, 0, 0), 898 - F(74250000, P_HDMIPLL, 1, 0, 0), 899 - F(108000000, P_HDMIPLL, 1, 0, 0), 900 - F(148500000, P_HDMIPLL, 1, 0, 0), 901 - F(268500000, P_HDMIPLL, 1, 0, 0), 902 - F(297000000, P_HDMIPLL, 1, 0, 0), 879 + static struct freq_tbl extpclk_freq_tbl[] = { 880 + { .src = P_HDMIPLL }, 903 881 { } 904 882 }; 905 883 ··· 899 893 .cmd_rcgr = 0x2060, 900 894 .hid_width = 5, 901 895 .parent_map = mmcc_xo_dsi_hdmi_edp_gpll0_map, 902 - .freq_tbl = ftbl_mdss_extpclk_clk, 896 + .freq_tbl = extpclk_freq_tbl, 903 897 .clkr.hw.init = &(struct clk_init_data){ 904 898 .name = "extpclk_clk_src", 905 899 .parent_names = mmcc_xo_dsi_hdmi_edp_gpll0, 906 900 .num_parents = 6, 907 - .ops = &clk_rcg2_ops, 901 + .ops = &clk_byte_ops, 902 + .flags = CLK_SET_RATE_PARENT, 908 903 }, 909 904 }; 910 905 ··· 2325 2318 .vco_val = 0x0, 2326 2319 .vco_mask = 0x3 << 20, 2327 2320 .pre_div_val = 0x0, 2328 - .pre_div_mask = 0x3 << 12, 2321 + .pre_div_mask = 0x7 << 12, 2329 2322 .post_div_val = 0x0, 2330 2323 .post_div_mask = 0x3 << 8, 2331 2324 .mn_ena_mask = BIT(24), ··· 2339 2332 .vco_val = 0x0, 2340 2333 .vco_mask = 0x3 << 20, 2341 2334 .pre_div_val = 0x0, 2342 - .pre_div_mask = 0x3 << 12, 2335 + .pre_div_mask = 0x7 << 12, 2343 2336 .post_div_val = 0x0, 2344 2337 .post_div_mask = 0x3 << 8, 2345 2338 .mn_ena_mask = BIT(24), ··· 2531 2524 .fast_io = true, 2532 2525 }; 2533 2526 2527 + static const struct qcom_cc_desc mmcc_msm8974_desc = { 2528 + .config = &mmcc_msm8974_regmap_config, 2529 + .clks = mmcc_msm8974_clocks, 2530 + .num_clks = ARRAY_SIZE(mmcc_msm8974_clocks), 2531 + .resets = mmcc_msm8974_resets, 2532 + .num_resets = ARRAY_SIZE(mmcc_msm8974_resets), 2533 + }; 2534 + 2534 2535 static const struct of_device_id mmcc_msm8974_match_table[] = { 2535 2536 { .compatible = "qcom,mmcc-msm8974" }, 2536 2537 { } 2537 2538 }; 2538 2539 MODULE_DEVICE_TABLE(of, mmcc_msm8974_match_table); 2539 2540 2540 - struct qcom_cc { 2541 - struct qcom_reset_controller reset; 2542 - struct clk_onecell_data data; 2543 - struct clk *clks[]; 2544 - }; 2545 - 2546 2541 static int mmcc_msm8974_probe(struct platform_device *pdev) 2547 2542 { 2548 - void __iomem *base; 2549 - struct resource *res; 2550 - int i, ret; 2551 - struct device *dev = &pdev->dev; 2552 - struct clk *clk; 2553 - struct clk_onecell_data *data; 2554 - struct clk **clks; 2543 + int ret; 2555 2544 struct regmap *regmap; 2556 - size_t num_clks; 2557 - struct qcom_reset_controller *reset; 2558 - struct qcom_cc *cc; 2559 2545 2560 - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 2561 - base = devm_ioremap_resource(dev, res); 2562 - if (IS_ERR(base)) 2563 - return PTR_ERR(base); 2564 - 2565 - regmap = devm_regmap_init_mmio(dev, base, &mmcc_msm8974_regmap_config); 2566 - if (IS_ERR(regmap)) 2567 - return PTR_ERR(regmap); 2568 - 2569 - num_clks = ARRAY_SIZE(mmcc_msm8974_clocks); 2570 - cc = devm_kzalloc(dev, sizeof(*cc) + sizeof(*clks) * num_clks, 2571 - GFP_KERNEL); 2572 - if (!cc) 2573 - return -ENOMEM; 2574 - 2575 - clks = cc->clks; 2576 - data = &cc->data; 2577 - data->clks = clks; 2578 - data->clk_num = num_clks; 2579 - 2580 - clk_pll_configure_sr_hpm_lp(&mmpll1, regmap, &mmpll1_config, true); 2581 - clk_pll_configure_sr_hpm_lp(&mmpll3, regmap, &mmpll3_config, false); 2582 - 2583 - for (i = 0; i < num_clks; i++) { 2584 - if (!mmcc_msm8974_clocks[i]) 2585 - continue; 2586 - clk = devm_clk_register_regmap(dev, mmcc_msm8974_clocks[i]); 2587 - if (IS_ERR(clk)) 2588 - return PTR_ERR(clk); 2589 - clks[i] = clk; 2590 - } 2591 - 2592 - ret = of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, data); 2546 + ret = qcom_cc_probe(pdev, &mmcc_msm8974_desc); 2593 2547 if (ret) 2594 2548 return ret; 2595 2549 2596 - reset = &cc->reset; 2597 - reset->rcdev.of_node = dev->of_node; 2598 - reset->rcdev.ops = &qcom_reset_ops, 2599 - reset->rcdev.owner = THIS_MODULE, 2600 - reset->rcdev.nr_resets = ARRAY_SIZE(mmcc_msm8974_resets), 2601 - reset->regmap = regmap; 2602 - reset->reset_map = mmcc_msm8974_resets, 2603 - platform_set_drvdata(pdev, &reset->rcdev); 2550 + regmap = dev_get_regmap(&pdev->dev, NULL); 2551 + clk_pll_configure_sr_hpm_lp(&mmpll1, regmap, &mmpll1_config, true); 2552 + clk_pll_configure_sr_hpm_lp(&mmpll3, regmap, &mmpll3_config, false); 2604 2553 2605 - ret = reset_controller_register(&reset->rcdev); 2606 - if (ret) 2607 - of_clk_del_provider(dev->of_node); 2608 - 2609 - return ret; 2554 + return 0; 2610 2555 } 2611 2556 2612 2557 static int mmcc_msm8974_remove(struct platform_device *pdev) 2613 2558 { 2614 - of_clk_del_provider(pdev->dev.of_node); 2615 - reset_controller_unregister(platform_get_drvdata(pdev)); 2559 + qcom_cc_remove(pdev); 2616 2560 return 0; 2617 2561 } 2618 2562
+2 -2
drivers/clk/samsung/clk-exynos4.c
··· 324 324 .resume = exynos4_clk_resume, 325 325 }; 326 326 327 - static void exynos4_clk_sleep_init(void) 327 + static void __init exynos4_clk_sleep_init(void) 328 328 { 329 329 exynos4_save_common = samsung_clk_alloc_reg_dump(exynos4_clk_regs, 330 330 ARRAY_SIZE(exynos4_clk_regs)); ··· 359 359 __func__); 360 360 } 361 361 #else 362 - static void exynos4_clk_sleep_init(void) {} 362 + static void __init exynos4_clk_sleep_init(void) {} 363 363 #endif 364 364 365 365 /* list of all parent clock list */
+2
drivers/clk/shmobile/Makefile
··· 1 1 obj-$(CONFIG_ARCH_EMEV2) += clk-emev2.o 2 2 obj-$(CONFIG_ARCH_R7S72100) += clk-rz.o 3 + obj-$(CONFIG_ARCH_R8A7740) += clk-r8a7740.o 4 + obj-$(CONFIG_ARCH_R8A7779) += clk-r8a7779.o 3 5 obj-$(CONFIG_ARCH_R8A7790) += clk-rcar-gen2.o 4 6 obj-$(CONFIG_ARCH_R8A7791) += clk-rcar-gen2.o 5 7 obj-$(CONFIG_ARCH_SHMOBILE_MULTI) += clk-div6.o
+1 -1
drivers/clk/shmobile/clk-mstp.c
··· 112 112 else 113 113 value = clk_readl(group->smstpcr); 114 114 115 - return !!(value & BIT(clock->bit_index)); 115 + return !(value & BIT(clock->bit_index)); 116 116 } 117 117 118 118 static const struct clk_ops cpg_mstp_clock_ops = {
+199
drivers/clk/shmobile/clk-r8a7740.c
··· 1 + /* 2 + * r8a7740 Core CPG Clocks 3 + * 4 + * Copyright (C) 2014 Ulrich Hecht 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License as published by 8 + * the Free Software Foundation; version 2 of the License. 9 + */ 10 + 11 + #include <linux/clk-provider.h> 12 + #include <linux/clkdev.h> 13 + #include <linux/clk/shmobile.h> 14 + #include <linux/init.h> 15 + #include <linux/kernel.h> 16 + #include <linux/of.h> 17 + #include <linux/of_address.h> 18 + #include <linux/spinlock.h> 19 + 20 + struct r8a7740_cpg { 21 + struct clk_onecell_data data; 22 + spinlock_t lock; 23 + void __iomem *reg; 24 + }; 25 + 26 + #define CPG_FRQCRA 0x00 27 + #define CPG_FRQCRB 0x04 28 + #define CPG_PLLC2CR 0x2c 29 + #define CPG_USBCKCR 0x8c 30 + #define CPG_FRQCRC 0xe0 31 + 32 + #define CLK_ENABLE_ON_INIT BIT(0) 33 + 34 + struct div4_clk { 35 + const char *name; 36 + unsigned int reg; 37 + unsigned int shift; 38 + int flags; 39 + }; 40 + 41 + static struct div4_clk div4_clks[] = { 42 + { "i", CPG_FRQCRA, 20, CLK_ENABLE_ON_INIT }, 43 + { "zg", CPG_FRQCRA, 16, CLK_ENABLE_ON_INIT }, 44 + { "b", CPG_FRQCRA, 8, CLK_ENABLE_ON_INIT }, 45 + { "m1", CPG_FRQCRA, 4, CLK_ENABLE_ON_INIT }, 46 + { "hp", CPG_FRQCRB, 4, 0 }, 47 + { "hpp", CPG_FRQCRC, 20, 0 }, 48 + { "usbp", CPG_FRQCRC, 16, 0 }, 49 + { "s", CPG_FRQCRC, 12, 0 }, 50 + { "zb", CPG_FRQCRC, 8, 0 }, 51 + { "m3", CPG_FRQCRC, 4, 0 }, 52 + { "cp", CPG_FRQCRC, 0, 0 }, 53 + { NULL, 0, 0, 0 }, 54 + }; 55 + 56 + static const struct clk_div_table div4_div_table[] = { 57 + { 0, 2 }, { 1, 3 }, { 2, 4 }, { 3, 6 }, { 4, 8 }, { 5, 12 }, 58 + { 6, 16 }, { 7, 18 }, { 8, 24 }, { 9, 32 }, { 10, 36 }, { 11, 48 }, 59 + { 13, 72 }, { 14, 96 }, { 0, 0 } 60 + }; 61 + 62 + static u32 cpg_mode __initdata; 63 + 64 + static struct clk * __init 65 + r8a7740_cpg_register_clock(struct device_node *np, struct r8a7740_cpg *cpg, 66 + const char *name) 67 + { 68 + const struct clk_div_table *table = NULL; 69 + const char *parent_name; 70 + unsigned int shift, reg; 71 + unsigned int mult = 1; 72 + unsigned int div = 1; 73 + 74 + if (!strcmp(name, "r")) { 75 + switch (cpg_mode & (BIT(2) | BIT(1))) { 76 + case BIT(1) | BIT(2): 77 + /* extal1 */ 78 + parent_name = of_clk_get_parent_name(np, 0); 79 + div = 2048; 80 + break; 81 + case BIT(2): 82 + /* extal1 */ 83 + parent_name = of_clk_get_parent_name(np, 0); 84 + div = 1024; 85 + break; 86 + default: 87 + /* extalr */ 88 + parent_name = of_clk_get_parent_name(np, 2); 89 + break; 90 + } 91 + } else if (!strcmp(name, "system")) { 92 + parent_name = of_clk_get_parent_name(np, 0); 93 + if (cpg_mode & BIT(1)) 94 + div = 2; 95 + } else if (!strcmp(name, "pllc0")) { 96 + /* PLLC0/1 are configurable multiplier clocks. Register them as 97 + * fixed factor clocks for now as there's no generic multiplier 98 + * clock implementation and we currently have no need to change 99 + * the multiplier value. 100 + */ 101 + u32 value = clk_readl(cpg->reg + CPG_FRQCRC); 102 + parent_name = "system"; 103 + mult = ((value >> 24) & 0x7f) + 1; 104 + } else if (!strcmp(name, "pllc1")) { 105 + u32 value = clk_readl(cpg->reg + CPG_FRQCRA); 106 + parent_name = "system"; 107 + mult = ((value >> 24) & 0x7f) + 1; 108 + div = 2; 109 + } else if (!strcmp(name, "pllc2")) { 110 + u32 value = clk_readl(cpg->reg + CPG_PLLC2CR); 111 + parent_name = "system"; 112 + mult = ((value >> 24) & 0x3f) + 1; 113 + } else if (!strcmp(name, "usb24s")) { 114 + u32 value = clk_readl(cpg->reg + CPG_USBCKCR); 115 + if (value & BIT(7)) 116 + /* extal2 */ 117 + parent_name = of_clk_get_parent_name(np, 1); 118 + else 119 + parent_name = "system"; 120 + if (!(value & BIT(6))) 121 + div = 2; 122 + } else { 123 + struct div4_clk *c; 124 + for (c = div4_clks; c->name; c++) { 125 + if (!strcmp(name, c->name)) { 126 + parent_name = "pllc1"; 127 + table = div4_div_table; 128 + reg = c->reg; 129 + shift = c->shift; 130 + break; 131 + } 132 + } 133 + if (!c->name) 134 + return ERR_PTR(-EINVAL); 135 + } 136 + 137 + if (!table) { 138 + return clk_register_fixed_factor(NULL, name, parent_name, 0, 139 + mult, div); 140 + } else { 141 + return clk_register_divider_table(NULL, name, parent_name, 0, 142 + cpg->reg + reg, shift, 4, 0, 143 + table, &cpg->lock); 144 + } 145 + } 146 + 147 + static void __init r8a7740_cpg_clocks_init(struct device_node *np) 148 + { 149 + struct r8a7740_cpg *cpg; 150 + struct clk **clks; 151 + unsigned int i; 152 + int num_clks; 153 + 154 + if (of_property_read_u32(np, "renesas,mode", &cpg_mode)) 155 + pr_warn("%s: missing renesas,mode property\n", __func__); 156 + 157 + num_clks = of_property_count_strings(np, "clock-output-names"); 158 + if (num_clks < 0) { 159 + pr_err("%s: failed to count clocks\n", __func__); 160 + return; 161 + } 162 + 163 + cpg = kzalloc(sizeof(*cpg), GFP_KERNEL); 164 + clks = kzalloc(num_clks * sizeof(*clks), GFP_KERNEL); 165 + if (cpg == NULL || clks == NULL) { 166 + /* We're leaking memory on purpose, there's no point in cleaning 167 + * up as the system won't boot anyway. 168 + */ 169 + return; 170 + } 171 + 172 + spin_lock_init(&cpg->lock); 173 + 174 + cpg->data.clks = clks; 175 + cpg->data.clk_num = num_clks; 176 + 177 + cpg->reg = of_iomap(np, 0); 178 + if (WARN_ON(cpg->reg == NULL)) 179 + return; 180 + 181 + for (i = 0; i < num_clks; ++i) { 182 + const char *name; 183 + struct clk *clk; 184 + 185 + of_property_read_string_index(np, "clock-output-names", i, 186 + &name); 187 + 188 + clk = r8a7740_cpg_register_clock(np, cpg, name); 189 + if (IS_ERR(clk)) 190 + pr_err("%s: failed to register %s %s clock (%ld)\n", 191 + __func__, np->name, name, PTR_ERR(clk)); 192 + else 193 + cpg->data.clks[i] = clk; 194 + } 195 + 196 + of_clk_add_provider(np, of_clk_src_onecell_get, &cpg->data); 197 + } 198 + CLK_OF_DECLARE(r8a7740_cpg_clks, "renesas,r8a7740-cpg-clocks", 199 + r8a7740_cpg_clocks_init);
+180
drivers/clk/shmobile/clk-r8a7779.c
··· 1 + /* 2 + * r8a7779 Core CPG Clocks 3 + * 4 + * Copyright (C) 2013, 2014 Horms Solutions Ltd. 5 + * 6 + * Contact: Simon Horman <horms@verge.net.au> 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License as published by 10 + * the Free Software Foundation; version 2 of the License. 11 + */ 12 + 13 + #include <linux/clk-provider.h> 14 + #include <linux/clkdev.h> 15 + #include <linux/clk/shmobile.h> 16 + #include <linux/init.h> 17 + #include <linux/kernel.h> 18 + #include <linux/of.h> 19 + #include <linux/of_address.h> 20 + #include <linux/spinlock.h> 21 + 22 + #include <dt-bindings/clock/r8a7779-clock.h> 23 + 24 + #define CPG_NUM_CLOCKS (R8A7779_CLK_OUT + 1) 25 + 26 + struct r8a7779_cpg { 27 + struct clk_onecell_data data; 28 + spinlock_t lock; 29 + void __iomem *reg; 30 + }; 31 + 32 + /* ----------------------------------------------------------------------------- 33 + * CPG Clock Data 34 + */ 35 + 36 + /* 37 + * MD1 = 1 MD1 = 0 38 + * (PLLA = 1500) (PLLA = 1600) 39 + * (MHz) (MHz) 40 + *------------------------------------------------+-------------------- 41 + * clkz 1000 (2/3) 800 (1/2) 42 + * clkzs 250 (1/6) 200 (1/8) 43 + * clki 750 (1/2) 800 (1/2) 44 + * clks 250 (1/6) 200 (1/8) 45 + * clks1 125 (1/12) 100 (1/16) 46 + * clks3 187.5 (1/8) 200 (1/8) 47 + * clks4 93.7 (1/16) 100 (1/16) 48 + * clkp 62.5 (1/24) 50 (1/32) 49 + * clkg 62.5 (1/24) 66.6 (1/24) 50 + * clkb, CLKOUT 51 + * (MD2 = 0) 62.5 (1/24) 66.6 (1/24) 52 + * (MD2 = 1) 41.6 (1/36) 50 (1/32) 53 + */ 54 + 55 + #define CPG_CLK_CONFIG_INDEX(md) (((md) & (BIT(2)|BIT(1))) >> 1) 56 + 57 + struct cpg_clk_config { 58 + unsigned int z_mult; 59 + unsigned int z_div; 60 + unsigned int zs_and_s_div; 61 + unsigned int s1_div; 62 + unsigned int p_div; 63 + unsigned int b_and_out_div; 64 + }; 65 + 66 + static const struct cpg_clk_config cpg_clk_configs[4] __initconst = { 67 + { 1, 2, 8, 16, 32, 24 }, 68 + { 2, 3, 6, 12, 24, 24 }, 69 + { 1, 2, 8, 16, 32, 32 }, 70 + { 2, 3, 6, 12, 24, 36 }, 71 + }; 72 + 73 + /* 74 + * MD PLLA Ratio 75 + * 12 11 76 + *------------------------ 77 + * 0 0 x42 78 + * 0 1 x48 79 + * 1 0 x56 80 + * 1 1 x64 81 + */ 82 + 83 + #define CPG_PLLA_MULT_INDEX(md) (((md) & (BIT(12)|BIT(11))) >> 11) 84 + 85 + static const unsigned int cpg_plla_mult[4] __initconst = { 42, 48, 56, 64 }; 86 + 87 + /* ----------------------------------------------------------------------------- 88 + * Initialization 89 + */ 90 + 91 + static u32 cpg_mode __initdata; 92 + 93 + static struct clk * __init 94 + r8a7779_cpg_register_clock(struct device_node *np, struct r8a7779_cpg *cpg, 95 + const struct cpg_clk_config *config, 96 + unsigned int plla_mult, const char *name) 97 + { 98 + const char *parent_name = "plla"; 99 + unsigned int mult = 1; 100 + unsigned int div = 1; 101 + 102 + if (!strcmp(name, "plla")) { 103 + parent_name = of_clk_get_parent_name(np, 0); 104 + mult = plla_mult; 105 + } else if (!strcmp(name, "z")) { 106 + div = config->z_div; 107 + mult = config->z_mult; 108 + } else if (!strcmp(name, "zs") || !strcmp(name, "s")) { 109 + div = config->zs_and_s_div; 110 + } else if (!strcmp(name, "s1")) { 111 + div = config->s1_div; 112 + } else if (!strcmp(name, "p")) { 113 + div = config->p_div; 114 + } else if (!strcmp(name, "b") || !strcmp(name, "out")) { 115 + div = config->b_and_out_div; 116 + } else { 117 + return ERR_PTR(-EINVAL); 118 + } 119 + 120 + return clk_register_fixed_factor(NULL, name, parent_name, 0, mult, div); 121 + } 122 + 123 + static void __init r8a7779_cpg_clocks_init(struct device_node *np) 124 + { 125 + const struct cpg_clk_config *config; 126 + struct r8a7779_cpg *cpg; 127 + struct clk **clks; 128 + unsigned int i, plla_mult; 129 + int num_clks; 130 + 131 + num_clks = of_property_count_strings(np, "clock-output-names"); 132 + if (num_clks < 0) { 133 + pr_err("%s: failed to count clocks\n", __func__); 134 + return; 135 + } 136 + 137 + cpg = kzalloc(sizeof(*cpg), GFP_KERNEL); 138 + clks = kzalloc(CPG_NUM_CLOCKS * sizeof(*clks), GFP_KERNEL); 139 + if (cpg == NULL || clks == NULL) { 140 + /* We're leaking memory on purpose, there's no point in cleaning 141 + * up as the system won't boot anyway. 142 + */ 143 + return; 144 + } 145 + 146 + spin_lock_init(&cpg->lock); 147 + 148 + cpg->data.clks = clks; 149 + cpg->data.clk_num = num_clks; 150 + 151 + config = &cpg_clk_configs[CPG_CLK_CONFIG_INDEX(cpg_mode)]; 152 + plla_mult = cpg_plla_mult[CPG_PLLA_MULT_INDEX(cpg_mode)]; 153 + 154 + for (i = 0; i < num_clks; ++i) { 155 + const char *name; 156 + struct clk *clk; 157 + 158 + of_property_read_string_index(np, "clock-output-names", i, 159 + &name); 160 + 161 + clk = r8a7779_cpg_register_clock(np, cpg, config, 162 + plla_mult, name); 163 + if (IS_ERR(clk)) 164 + pr_err("%s: failed to register %s %s clock (%ld)\n", 165 + __func__, np->name, name, PTR_ERR(clk)); 166 + else 167 + cpg->data.clks[i] = clk; 168 + } 169 + 170 + of_clk_add_provider(np, of_clk_src_onecell_get, &cpg->data); 171 + } 172 + CLK_OF_DECLARE(r8a7779_cpg_clks, "renesas,r8a7779-cpg-clocks", 173 + r8a7779_cpg_clocks_init); 174 + 175 + void __init r8a7779_clocks_init(u32 mode) 176 + { 177 + cpg_mode = mode; 178 + 179 + of_clk_init(NULL); 180 + }
-1
drivers/clk/socfpga/clk-gate.c
··· 32 32 #define SOCFPGA_MMC_CLK "sdmmc_clk" 33 33 #define SOCFPGA_GPIO_DB_CLK_OFFSET 0xA8 34 34 35 - #define div_mask(width) ((1 << (width)) - 1) 36 35 #define streq(a, b) (strcmp((a), (b)) == 0) 37 36 38 37 #define to_socfpga_gate_clk(p) container_of(p, struct socfpga_gate_clk, hw.hw)
+19 -3
drivers/clk/socfpga/clk-periph.c
··· 29 29 unsigned long parent_rate) 30 30 { 31 31 struct socfpga_periph_clk *socfpgaclk = to_socfpga_periph_clk(hwclk); 32 - u32 div; 32 + u32 div, val; 33 33 34 - if (socfpgaclk->fixed_div) 34 + if (socfpgaclk->fixed_div) { 35 35 div = socfpgaclk->fixed_div; 36 - else 36 + } else { 37 + if (socfpgaclk->div_reg) { 38 + val = readl(socfpgaclk->div_reg) >> socfpgaclk->shift; 39 + val &= div_mask(socfpgaclk->width); 40 + parent_rate /= (val + 1); 41 + } 37 42 div = ((readl(socfpgaclk->hw.reg) & 0x1ff) + 1); 43 + } 38 44 39 45 return parent_rate / div; 40 46 } ··· 60 54 struct clk_init_data init; 61 55 int rc; 62 56 u32 fixed_div; 57 + u32 div_reg[3]; 63 58 64 59 of_property_read_u32(node, "reg", &reg); 65 60 ··· 69 62 return; 70 63 71 64 periph_clk->hw.reg = clk_mgr_base_addr + reg; 65 + 66 + rc = of_property_read_u32_array(node, "div-reg", div_reg, 3); 67 + if (!rc) { 68 + periph_clk->div_reg = clk_mgr_base_addr + div_reg[0]; 69 + periph_clk->shift = div_reg[1]; 70 + periph_clk->width = div_reg[2]; 71 + } else { 72 + periph_clk->div_reg = 0; 73 + } 72 74 73 75 rc = of_property_read_u32(node, "fixed-divider", &fixed_div); 74 76 if (rc)
+4
drivers/clk/socfpga/clk.h
··· 27 27 #define CLKMGR_PERPLL_SRC 0xAC 28 28 29 29 #define SOCFPGA_MAX_PARENTS 3 30 + #define div_mask(width) ((1 << (width)) - 1) 30 31 31 32 extern void __iomem *clk_mgr_base_addr; 32 33 ··· 53 52 struct clk_gate hw; 54 53 char *parent_name; 55 54 u32 fixed_div; 55 + void __iomem *div_reg; 56 + u32 width; /* only valid if div_reg != 0 */ 57 + u32 shift; /* only valid if div_reg != 0 */ 56 58 }; 57 59 58 60 #endif /* SOCFPGA_CLK_H */
+1
drivers/clk/st/clkgen-pll.c
··· 655 655 .compatible = "st,stih416-gpu-pll-c32", 656 656 .data = &st_pll1200c32_gpu_416, 657 657 }, 658 + {} 658 659 }; 659 660 660 661 static void __init clkgengpu_c32_pll_setup(struct device_node *np)
+36
drivers/clk/sunxi/clk-factors.c
··· 77 77 return rate; 78 78 } 79 79 80 + static long clk_factors_determine_rate(struct clk_hw *hw, unsigned long rate, 81 + unsigned long *best_parent_rate, 82 + struct clk **best_parent_p) 83 + { 84 + struct clk *clk = hw->clk, *parent, *best_parent = NULL; 85 + int i, num_parents; 86 + unsigned long parent_rate, best = 0, child_rate, best_child_rate = 0; 87 + 88 + /* find the parent that can help provide the fastest rate <= rate */ 89 + num_parents = __clk_get_num_parents(clk); 90 + for (i = 0; i < num_parents; i++) { 91 + parent = clk_get_parent_by_index(clk, i); 92 + if (!parent) 93 + continue; 94 + if (__clk_get_flags(clk) & CLK_SET_RATE_PARENT) 95 + parent_rate = __clk_round_rate(parent, rate); 96 + else 97 + parent_rate = __clk_get_rate(parent); 98 + 99 + child_rate = clk_factors_round_rate(hw, rate, &parent_rate); 100 + 101 + if (child_rate <= rate && child_rate > best_child_rate) { 102 + best_parent = parent; 103 + best = parent_rate; 104 + best_child_rate = child_rate; 105 + } 106 + } 107 + 108 + if (best_parent) 109 + *best_parent_p = best_parent; 110 + *best_parent_rate = best; 111 + 112 + return best_child_rate; 113 + } 114 + 80 115 static int clk_factors_set_rate(struct clk_hw *hw, unsigned long rate, 81 116 unsigned long parent_rate) 82 117 { ··· 148 113 } 149 114 150 115 const struct clk_ops clk_factors_ops = { 116 + .determine_rate = clk_factors_determine_rate, 151 117 .recalc_rate = clk_factors_recalc_rate, 152 118 .round_rate = clk_factors_round_rate, 153 119 .set_rate = clk_factors_set_rate,
+37
drivers/clk/sunxi/clk-sunxi.c
··· 507 507 508 508 509 509 /** 510 + * clk_sunxi_mmc_phase_control() - configures MMC clock phase control 511 + */ 512 + 513 + void clk_sunxi_mmc_phase_control(struct clk *clk, u8 sample, u8 output) 514 + { 515 + #define to_clk_composite(_hw) container_of(_hw, struct clk_composite, hw) 516 + #define to_clk_factors(_hw) container_of(_hw, struct clk_factors, hw) 517 + 518 + struct clk_hw *hw = __clk_get_hw(clk); 519 + struct clk_composite *composite = to_clk_composite(hw); 520 + struct clk_hw *rate_hw = composite->rate_hw; 521 + struct clk_factors *factors = to_clk_factors(rate_hw); 522 + unsigned long flags = 0; 523 + u32 reg; 524 + 525 + if (factors->lock) 526 + spin_lock_irqsave(factors->lock, flags); 527 + 528 + reg = readl(factors->reg); 529 + 530 + /* set sample clock phase control */ 531 + reg &= ~(0x7 << 20); 532 + reg |= ((sample & 0x7) << 20); 533 + 534 + /* set output clock phase control */ 535 + reg &= ~(0x7 << 8); 536 + reg |= ((output & 0x7) << 8); 537 + 538 + writel(reg, factors->reg); 539 + 540 + if (factors->lock) 541 + spin_unlock_irqrestore(factors->lock, flags); 542 + } 543 + EXPORT_SYMBOL(clk_sunxi_mmc_phase_control); 544 + 545 + 546 + /** 510 547 * sunxi_factors_clk_setup() - Setup function for factor clocks 511 548 */ 512 549
+1
drivers/clk/tegra/clk-id.h
··· 233 233 tegra_clk_xusb_hs_src, 234 234 tegra_clk_xusb_ss, 235 235 tegra_clk_xusb_ss_src, 236 + tegra_clk_xusb_ss_div2, 236 237 tegra_clk_max, 237 238 }; 238 239
+32 -1
drivers/clk/tegra/clk-pll.c
··· 96 96 (PLLE_SS_MAX_VAL | PLLE_SS_INC_VAL | PLLE_SS_INCINTRV_VAL) 97 97 98 98 #define PLLE_AUX_PLLP_SEL BIT(2) 99 + #define PLLE_AUX_USE_LOCKDET BIT(3) 99 100 #define PLLE_AUX_ENABLE_SWCTL BIT(4) 101 + #define PLLE_AUX_SS_SWCTL BIT(6) 100 102 #define PLLE_AUX_SEQ_ENABLE BIT(24) 103 + #define PLLE_AUX_SEQ_START_STATE BIT(25) 101 104 #define PLLE_AUX_PLLRE_SEL BIT(28) 105 + 106 + #define XUSBIO_PLL_CFG0 0x51c 107 + #define XUSBIO_PLL_CFG0_PADPLL_RESET_SWCTL BIT(0) 108 + #define XUSBIO_PLL_CFG0_CLK_ENABLE_SWCTL BIT(2) 109 + #define XUSBIO_PLL_CFG0_PADPLL_USE_LOCKDET BIT(6) 110 + #define XUSBIO_PLL_CFG0_SEQ_ENABLE BIT(24) 111 + #define XUSBIO_PLL_CFG0_SEQ_START_STATE BIT(25) 102 112 103 113 #define PLLE_MISC_PLLE_PTS BIT(8) 104 114 #define PLLE_MISC_IDDQ_SW_VALUE BIT(13) ··· 1338 1328 pll_writel(val, PLLE_SS_CTRL, pll); 1339 1329 udelay(1); 1340 1330 1341 - /* TODO: enable hw control of xusb brick pll */ 1331 + /* Enable hw control of xusb brick pll */ 1332 + val = pll_readl_misc(pll); 1333 + val &= ~PLLE_MISC_IDDQ_SW_CTRL; 1334 + pll_writel_misc(val, pll); 1335 + 1336 + val = pll_readl(pll->params->aux_reg, pll); 1337 + val |= (PLLE_AUX_USE_LOCKDET | PLLE_AUX_SEQ_START_STATE); 1338 + val &= ~(PLLE_AUX_ENABLE_SWCTL | PLLE_AUX_SS_SWCTL); 1339 + pll_writel(val, pll->params->aux_reg, pll); 1340 + udelay(1); 1341 + val |= PLLE_AUX_SEQ_ENABLE; 1342 + pll_writel(val, pll->params->aux_reg, pll); 1343 + 1344 + val = pll_readl(XUSBIO_PLL_CFG0, pll); 1345 + val |= (XUSBIO_PLL_CFG0_PADPLL_USE_LOCKDET | 1346 + XUSBIO_PLL_CFG0_SEQ_START_STATE); 1347 + val &= ~(XUSBIO_PLL_CFG0_CLK_ENABLE_SWCTL | 1348 + XUSBIO_PLL_CFG0_PADPLL_RESET_SWCTL); 1349 + pll_writel(val, XUSBIO_PLL_CFG0, pll); 1350 + udelay(1); 1351 + val |= XUSBIO_PLL_CFG0_SEQ_ENABLE; 1352 + pll_writel(val, XUSBIO_PLL_CFG0, pll); 1342 1353 1343 1354 out: 1344 1355 if (pll->lock)
+9 -1
drivers/clk/tegra/clk-tegra-periph.c
··· 329 329 static const char *mux_clkm_48M_pllp_480M[] = { 330 330 "clk_m", "pll_u_48M", "pll_p", "pll_u_480M" 331 331 }; 332 - #define mux_clkm_48M_pllp_480M_idx NULL 332 + static u32 mux_clkm_48M_pllp_480M_idx[] = { 333 + [0] = 0, [1] = 2, [2] = 4, [3] = 6, 334 + }; 333 335 334 336 static const char *mux_clkm_pllre_clk32_480M_pllc_ref[] = { 335 337 "clk_m", "pll_re_out", "clk_32k", "pll_u_480M", "pll_c", "pll_ref" ··· 339 337 static u32 mux_clkm_pllre_clk32_480M_pllc_ref_idx[] = { 340 338 [0] = 0, [1] = 1, [2] = 3, [3] = 3, [4] = 4, [5] = 7, 341 339 }; 340 + 341 + static const char *mux_ss_60M[] = { 342 + "xusb_ss_div2", "pll_u_60M" 343 + }; 344 + #define mux_ss_60M_idx NULL 342 345 343 346 static const char *mux_d_audio_clk[] = { 344 347 "pll_a_out0", "pll_p", "clk_m", "spdif_in_sync", "i2s0_sync", ··· 506 499 XUSB("xusb_falcon_src", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_FALCON_SRC, 143, TEGRA_PERIPH_NO_RESET, tegra_clk_xusb_falcon_src), 507 500 XUSB("xusb_fs_src", mux_clkm_48M_pllp_480M, CLK_SOURCE_XUSB_FS_SRC, 143, TEGRA_PERIPH_NO_RESET, tegra_clk_xusb_fs_src), 508 501 XUSB("xusb_ss_src", mux_clkm_pllre_clk32_480M_pllc_ref, CLK_SOURCE_XUSB_SS_SRC, 143, TEGRA_PERIPH_NO_RESET, tegra_clk_xusb_ss_src), 502 + NODIV("xusb_hs_src", mux_ss_60M, CLK_SOURCE_XUSB_SS_SRC, 25, MASK(1), 143, TEGRA_PERIPH_NO_RESET, tegra_clk_xusb_hs_src, NULL), 509 503 XUSB("xusb_dev_src", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_DEV_SRC, 95, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, tegra_clk_xusb_dev_src), 510 504 }; 511 505
+11 -11
drivers/clk/tegra/clk-tegra114.c
··· 142 142 #define UTMIPLL_HW_PWRDN_CFG0_IDDQ_SWCTL BIT(0) 143 143 144 144 #define CLK_SOURCE_CSITE 0x1d4 145 - #define CLK_SOURCE_XUSB_SS_SRC 0x610 146 145 #define CLK_SOURCE_EMC 0x19c 147 146 148 147 /* PLLM override registers */ ··· 833 834 [tegra_clk_xusb_falcon_src] = { .dt_id = TEGRA114_CLK_XUSB_FALCON_SRC, .present = true }, 834 835 [tegra_clk_xusb_fs_src] = { .dt_id = TEGRA114_CLK_XUSB_FS_SRC, .present = true }, 835 836 [tegra_clk_xusb_ss_src] = { .dt_id = TEGRA114_CLK_XUSB_SS_SRC, .present = true }, 837 + [tegra_clk_xusb_ss_div2] = { .dt_id = TEGRA114_CLK_XUSB_SS_DIV2, .present = true}, 836 838 [tegra_clk_xusb_dev_src] = { .dt_id = TEGRA114_CLK_XUSB_DEV_SRC, .present = true }, 837 839 [tegra_clk_xusb_dev] = { .dt_id = TEGRA114_CLK_XUSB_DEV, .present = true }, 838 840 [tegra_clk_xusb_hs_src] = { .dt_id = TEGRA114_CLK_XUSB_HS_SRC, .present = true }, ··· 1182 1182 void __iomem *pmc_base) 1183 1183 { 1184 1184 struct clk *clk; 1185 - u32 val; 1186 1185 1187 - /* xusb_hs_src */ 1188 - val = readl(clk_base + CLK_SOURCE_XUSB_SS_SRC); 1189 - val |= BIT(25); /* always select PLLU_60M */ 1190 - writel(val, clk_base + CLK_SOURCE_XUSB_SS_SRC); 1191 - 1192 - clk = clk_register_fixed_factor(NULL, "xusb_hs_src", "pll_u_60M", 0, 1193 - 1, 1); 1194 - clks[TEGRA114_CLK_XUSB_HS_SRC] = clk; 1186 + /* xusb_ss_div2 */ 1187 + clk = clk_register_fixed_factor(NULL, "xusb_ss_div2", "xusb_ss_src", 0, 1188 + 1, 2); 1189 + clks[TEGRA114_CLK_XUSB_SS_DIV2] = clk; 1195 1190 1196 1191 /* dsia mux */ 1197 1192 clk = clk_register_mux(NULL, "dsia_mux", mux_plld_out0_plld2_out0, ··· 1296 1301 {TEGRA114_CLK_GR3D, TEGRA114_CLK_PLL_C2, 300000000, 0}, 1297 1302 {TEGRA114_CLK_DSIALP, TEGRA114_CLK_PLL_P, 68000000, 0}, 1298 1303 {TEGRA114_CLK_DSIBLP, TEGRA114_CLK_PLL_P, 68000000, 0}, 1299 - 1304 + {TEGRA114_CLK_PLL_RE_VCO, TEGRA114_CLK_CLK_MAX, 612000000, 0}, 1305 + {TEGRA114_CLK_XUSB_SS_SRC, TEGRA114_CLK_PLL_RE_OUT, 122400000, 0}, 1306 + {TEGRA114_CLK_XUSB_FS_SRC, TEGRA114_CLK_PLL_U_48M, 48000000, 0}, 1307 + {TEGRA114_CLK_XUSB_HS_SRC, TEGRA114_CLK_XUSB_SS_DIV2, 61200000, 0}, 1308 + {TEGRA114_CLK_XUSB_FALCON_SRC, TEGRA114_CLK_PLL_P, 204000000, 0}, 1309 + {TEGRA114_CLK_XUSB_HOST_SRC, TEGRA114_CLK_PLL_P, 102000000, 0}, 1300 1310 /* This MUST be the last entry. */ 1301 1311 {TEGRA114_CLK_CLK_MAX, TEGRA114_CLK_CLK_MAX, 0, 0}, 1302 1312 };
+11 -10
drivers/clk/tegra/clk-tegra124.c
··· 30 30 31 31 #define CLK_SOURCE_CSITE 0x1d4 32 32 #define CLK_SOURCE_EMC 0x19c 33 - #define CLK_SOURCE_XUSB_SS_SRC 0x610 34 33 35 34 #define PLLC_BASE 0x80 36 35 #define PLLC_OUT 0x84 ··· 924 925 [tegra_clk_xusb_falcon_src] = { .dt_id = TEGRA124_CLK_XUSB_FALCON_SRC, .present = true }, 925 926 [tegra_clk_xusb_fs_src] = { .dt_id = TEGRA124_CLK_XUSB_FS_SRC, .present = true }, 926 927 [tegra_clk_xusb_ss_src] = { .dt_id = TEGRA124_CLK_XUSB_SS_SRC, .present = true }, 928 + [tegra_clk_xusb_ss_div2] = { .dt_id = TEGRA124_CLK_XUSB_SS_DIV2, .present = true }, 927 929 [tegra_clk_xusb_dev_src] = { .dt_id = TEGRA124_CLK_XUSB_DEV_SRC, .present = true }, 928 930 [tegra_clk_xusb_dev] = { .dt_id = TEGRA124_CLK_XUSB_DEV, .present = true }, 929 931 [tegra_clk_xusb_hs_src] = { .dt_id = TEGRA124_CLK_XUSB_HS_SRC, .present = true }, ··· 1105 1105 void __iomem *pmc_base) 1106 1106 { 1107 1107 struct clk *clk; 1108 - u32 val; 1109 1108 1110 - /* xusb_hs_src */ 1111 - val = readl(clk_base + CLK_SOURCE_XUSB_SS_SRC); 1112 - val |= BIT(25); /* always select PLLU_60M */ 1113 - writel(val, clk_base + CLK_SOURCE_XUSB_SS_SRC); 1114 - 1115 - clk = clk_register_fixed_factor(NULL, "xusb_hs_src", "pll_u_60M", 0, 1116 - 1, 1); 1117 - clks[TEGRA124_CLK_XUSB_HS_SRC] = clk; 1109 + /* xusb_ss_div2 */ 1110 + clk = clk_register_fixed_factor(NULL, "xusb_ss_div2", "xusb_ss_src", 0, 1111 + 1, 2); 1112 + clks[TEGRA124_CLK_XUSB_SS_DIV2] = clk; 1118 1113 1119 1114 /* dsia mux */ 1120 1115 clk = clk_register_mux(NULL, "dsia_mux", mux_plld_out0_plld2_out0, ··· 1363 1368 {TEGRA124_CLK_SBC4, TEGRA124_CLK_PLL_P, 12000000, 1}, 1364 1369 {TEGRA124_CLK_TSEC, TEGRA124_CLK_PLL_C3, 0, 0}, 1365 1370 {TEGRA124_CLK_MSENC, TEGRA124_CLK_PLL_C3, 0, 0}, 1371 + {TEGRA124_CLK_PLL_RE_VCO, TEGRA124_CLK_CLK_MAX, 672000000, 0}, 1372 + {TEGRA124_CLK_XUSB_SS_SRC, TEGRA124_CLK_PLL_U_480M, 120000000, 0}, 1373 + {TEGRA124_CLK_XUSB_FS_SRC, TEGRA124_CLK_PLL_U_48M, 48000000, 0}, 1374 + {TEGRA124_CLK_XUSB_HS_SRC, TEGRA124_CLK_PLL_U_60M, 60000000, 0}, 1375 + {TEGRA124_CLK_XUSB_FALCON_SRC, TEGRA124_CLK_PLL_RE_OUT, 224000000, 0}, 1376 + {TEGRA124_CLK_XUSB_HOST_SRC, TEGRA124_CLK_PLL_RE_OUT, 112000000, 0}, 1366 1377 /* This MUST be the last entry. */ 1367 1378 {TEGRA124_CLK_CLK_MAX, TEGRA124_CLK_CLK_MAX, 0, 0}, 1368 1379 };
+2
drivers/clk/versatile/clk-icst.c
··· 140 140 141 141 pclone = kmemdup(desc->params, sizeof(*pclone), GFP_KERNEL); 142 142 if (!pclone) { 143 + kfree(icst); 143 144 pr_err("could not clone ICST params\n"); 144 145 return ERR_PTR(-ENOMEM); 145 146 } ··· 161 160 162 161 return clk; 163 162 } 163 + EXPORT_SYMBOL_GPL(icst_clk_register);
+31 -7
drivers/clk/versatile/clk-impd1.c
··· 20 20 #define IMPD1_LOCK 0x08 21 21 22 22 struct impd1_clk { 23 + char *pclkname; 24 + struct clk *pclk; 23 25 char *vco1name; 24 26 struct clk *vco1clk; 25 27 char *vco2name; ··· 33 31 struct clk *spiclk; 34 32 char *scname; 35 33 struct clk *scclk; 36 - struct clk_lookup *clks[6]; 34 + struct clk_lookup *clks[15]; 37 35 }; 38 36 39 37 /* One entry for each connected IM-PD1 LM */ ··· 88 86 { 89 87 struct impd1_clk *imc; 90 88 struct clk *clk; 89 + struct clk *pclk; 91 90 int i; 92 91 93 92 if (id > 3) { ··· 97 94 } 98 95 imc = &impd1_clks[id]; 99 96 97 + /* Register the fixed rate PCLK */ 98 + imc->pclkname = kasprintf(GFP_KERNEL, "lm%x-pclk", id); 99 + pclk = clk_register_fixed_rate(NULL, imc->pclkname, NULL, 100 + CLK_IS_ROOT, 0); 101 + imc->pclk = pclk; 102 + 100 103 imc->vco1name = kasprintf(GFP_KERNEL, "lm%x-vco1", id); 101 104 clk = icst_clk_register(NULL, &impd1_icst1_desc, imc->vco1name, NULL, 102 105 base); 103 106 imc->vco1clk = clk; 104 - imc->clks[0] = clkdev_alloc(clk, NULL, "lm%x:01000", id); 107 + imc->clks[0] = clkdev_alloc(pclk, "apb_pclk", "lm%x:01000", id); 108 + imc->clks[1] = clkdev_alloc(clk, NULL, "lm%x:01000", id); 105 109 106 110 /* VCO2 is also called "CLK2" */ 107 111 imc->vco2name = kasprintf(GFP_KERNEL, "lm%x-vco2", id); ··· 117 107 imc->vco2clk = clk; 118 108 119 109 /* MMCI uses CLK2 right off */ 120 - imc->clks[1] = clkdev_alloc(clk, NULL, "lm%x:00700", id); 110 + imc->clks[2] = clkdev_alloc(pclk, "apb_pclk", "lm%x:00700", id); 111 + imc->clks[3] = clkdev_alloc(clk, NULL, "lm%x:00700", id); 121 112 122 113 /* UART reference clock divides CLK2 by a fixed factor 4 */ 123 114 imc->uartname = kasprintf(GFP_KERNEL, "lm%x-uartclk", id); 124 115 clk = clk_register_fixed_factor(NULL, imc->uartname, imc->vco2name, 125 116 CLK_IGNORE_UNUSED, 1, 4); 126 117 imc->uartclk = clk; 127 - imc->clks[2] = clkdev_alloc(clk, NULL, "lm%x:00100", id); 128 - imc->clks[3] = clkdev_alloc(clk, NULL, "lm%x:00200", id); 118 + imc->clks[4] = clkdev_alloc(pclk, "apb_pclk", "lm%x:00100", id); 119 + imc->clks[5] = clkdev_alloc(clk, NULL, "lm%x:00100", id); 120 + imc->clks[6] = clkdev_alloc(pclk, "apb_pclk", "lm%x:00200", id); 121 + imc->clks[7] = clkdev_alloc(clk, NULL, "lm%x:00200", id); 129 122 130 123 /* SPI PL022 clock divides CLK2 by a fixed factor 64 */ 131 124 imc->spiname = kasprintf(GFP_KERNEL, "lm%x-spiclk", id); 132 125 clk = clk_register_fixed_factor(NULL, imc->spiname, imc->vco2name, 133 126 CLK_IGNORE_UNUSED, 1, 64); 134 - imc->clks[4] = clkdev_alloc(clk, NULL, "lm%x:00300", id); 127 + imc->clks[8] = clkdev_alloc(pclk, "apb_pclk", "lm%x:00300", id); 128 + imc->clks[9] = clkdev_alloc(clk, NULL, "lm%x:00300", id); 129 + 130 + /* The GPIO blocks and AACI have only PCLK */ 131 + imc->clks[10] = clkdev_alloc(pclk, "apb_pclk", "lm%x:00400", id); 132 + imc->clks[11] = clkdev_alloc(pclk, "apb_pclk", "lm%x:00500", id); 133 + imc->clks[12] = clkdev_alloc(pclk, "apb_pclk", "lm%x:00800", id); 135 134 136 135 /* Smart Card clock divides CLK2 by a fixed factor 4 */ 137 136 imc->scname = kasprintf(GFP_KERNEL, "lm%x-scclk", id); 138 137 clk = clk_register_fixed_factor(NULL, imc->scname, imc->vco2name, 139 138 CLK_IGNORE_UNUSED, 1, 4); 140 139 imc->scclk = clk; 141 - imc->clks[5] = clkdev_alloc(clk, NULL, "lm%x:00600", id); 140 + imc->clks[13] = clkdev_alloc(pclk, "apb_pclk", "lm%x:00600", id); 141 + imc->clks[14] = clkdev_alloc(clk, NULL, "lm%x:00600", id); 142 142 143 143 for (i = 0; i < ARRAY_SIZE(imc->clks); i++) 144 144 clkdev_add(imc->clks[i]); 145 145 } 146 + EXPORT_SYMBOL_GPL(integrator_impd1_clk_init); 146 147 147 148 void integrator_impd1_clk_exit(unsigned int id) 148 149 { ··· 170 149 clk_unregister(imc->uartclk); 171 150 clk_unregister(imc->vco2clk); 172 151 clk_unregister(imc->vco1clk); 152 + clk_unregister(imc->pclk); 173 153 kfree(imc->scname); 174 154 kfree(imc->spiname); 175 155 kfree(imc->uartname); 176 156 kfree(imc->vco2name); 177 157 kfree(imc->vco1name); 158 + kfree(imc->pclkname); 178 159 } 160 + EXPORT_SYMBOL_GPL(integrator_impd1_clk_exit);
+12
drivers/clk/zynq/clkc.c
··· 53 53 54 54 #define NUM_MIO_PINS 54 55 55 56 + #define DBG_CLK_CTRL_CLKACT_TRC BIT(0) 57 + #define DBG_CLK_CTRL_CPU_1XCLKACT BIT(1) 58 + 56 59 enum zynq_clk { 57 60 armpll, ddrpll, iopll, 58 61 cpu_6or4x, cpu_3or2x, cpu_2x, cpu_1x, ··· 501 498 clks[dbg_apb] = clk_register_gate(NULL, clk_output_name[dbg_apb], 502 499 clk_output_name[cpu_1x], 0, SLCR_DBG_CLK_CTRL, 1, 0, 503 500 &dbgclk_lock); 501 + 502 + /* leave debug clocks in the state the bootloader set them up to */ 503 + tmp = clk_readl(SLCR_DBG_CLK_CTRL); 504 + if (tmp & DBG_CLK_CTRL_CLKACT_TRC) 505 + if (clk_prepare_enable(clks[dbg_trc])) 506 + pr_warn("%s: trace clk enable failed\n", __func__); 507 + if (tmp & DBG_CLK_CTRL_CPU_1XCLKACT) 508 + if (clk_prepare_enable(clks[dbg_apb])) 509 + pr_warn("%s: debug APB clk enable failed\n", __func__); 504 510 505 511 /* One gated clock for all APER clocks. */ 506 512 clks[dma] = clk_register_gate(NULL, clk_output_name[dma],
+7
drivers/mmc/host/Kconfig
··· 701 701 help 702 702 Say Y here to include driver code to support SD/MMC card interface 703 703 of Realtek RTS5129/39 series card reader 704 + 705 + config MMC_SUNXI 706 + tristate "Allwinner sunxi SD/MMC Host Controller support" 707 + depends on ARCH_SUNXI 708 + help 709 + This selects support for the SD/MMC Host Controller on 710 + Allwinner sunxi SoCs.
+1
drivers/mmc/host/Makefile
··· 50 50 obj-$(CONFIG_MMC_VUB300) += vub300.o 51 51 obj-$(CONFIG_MMC_USHC) += ushc.o 52 52 obj-$(CONFIG_MMC_WMT) += wmt-sdmmc.o 53 + obj-$(CONFIG_MMC_SUNXI) += sunxi-mmc.o 53 54 54 55 obj-$(CONFIG_MMC_REALTEK_PCI) += rtsx_pci_sdmmc.o 55 56 obj-$(CONFIG_MMC_REALTEK_USB) += rtsx_usb_sdmmc.o
+1049
drivers/mmc/host/sunxi-mmc.c
··· 1 + /* 2 + * Driver for sunxi SD/MMC host controllers 3 + * (C) Copyright 2007-2011 Reuuimlla Technology Co., Ltd. 4 + * (C) Copyright 2007-2011 Aaron Maoye <leafy.myeh@reuuimllatech.com> 5 + * (C) Copyright 2013-2014 O2S GmbH <www.o2s.ch> 6 + * (C) Copyright 2013-2014 David Lanzend�rfer <david.lanzendoerfer@o2s.ch> 7 + * (C) Copyright 2013-2014 Hans de Goede <hdegoede@redhat.com> 8 + * 9 + * This program is free software; you can redistribute it and/or 10 + * modify it under the terms of the GNU General Public License as 11 + * published by the Free Software Foundation; either version 2 of 12 + * the License, or (at your option) any later version. 13 + */ 14 + 15 + #include <linux/kernel.h> 16 + #include <linux/module.h> 17 + #include <linux/io.h> 18 + #include <linux/device.h> 19 + #include <linux/interrupt.h> 20 + #include <linux/delay.h> 21 + #include <linux/err.h> 22 + 23 + #include <linux/clk.h> 24 + #include <linux/clk-private.h> 25 + #include <linux/clk/sunxi.h> 26 + 27 + #include <linux/gpio.h> 28 + #include <linux/platform_device.h> 29 + #include <linux/spinlock.h> 30 + #include <linux/scatterlist.h> 31 + #include <linux/dma-mapping.h> 32 + #include <linux/slab.h> 33 + #include <linux/reset.h> 34 + 35 + #include <linux/of_address.h> 36 + #include <linux/of_gpio.h> 37 + #include <linux/of_platform.h> 38 + 39 + #include <linux/mmc/host.h> 40 + #include <linux/mmc/sd.h> 41 + #include <linux/mmc/sdio.h> 42 + #include <linux/mmc/mmc.h> 43 + #include <linux/mmc/core.h> 44 + #include <linux/mmc/card.h> 45 + #include <linux/mmc/slot-gpio.h> 46 + 47 + /* register offset definitions */ 48 + #define SDXC_REG_GCTRL (0x00) /* SMC Global Control Register */ 49 + #define SDXC_REG_CLKCR (0x04) /* SMC Clock Control Register */ 50 + #define SDXC_REG_TMOUT (0x08) /* SMC Time Out Register */ 51 + #define SDXC_REG_WIDTH (0x0C) /* SMC Bus Width Register */ 52 + #define SDXC_REG_BLKSZ (0x10) /* SMC Block Size Register */ 53 + #define SDXC_REG_BCNTR (0x14) /* SMC Byte Count Register */ 54 + #define SDXC_REG_CMDR (0x18) /* SMC Command Register */ 55 + #define SDXC_REG_CARG (0x1C) /* SMC Argument Register */ 56 + #define SDXC_REG_RESP0 (0x20) /* SMC Response Register 0 */ 57 + #define SDXC_REG_RESP1 (0x24) /* SMC Response Register 1 */ 58 + #define SDXC_REG_RESP2 (0x28) /* SMC Response Register 2 */ 59 + #define SDXC_REG_RESP3 (0x2C) /* SMC Response Register 3 */ 60 + #define SDXC_REG_IMASK (0x30) /* SMC Interrupt Mask Register */ 61 + #define SDXC_REG_MISTA (0x34) /* SMC Masked Interrupt Status Register */ 62 + #define SDXC_REG_RINTR (0x38) /* SMC Raw Interrupt Status Register */ 63 + #define SDXC_REG_STAS (0x3C) /* SMC Status Register */ 64 + #define SDXC_REG_FTRGL (0x40) /* SMC FIFO Threshold Watermark Registe */ 65 + #define SDXC_REG_FUNS (0x44) /* SMC Function Select Register */ 66 + #define SDXC_REG_CBCR (0x48) /* SMC CIU Byte Count Register */ 67 + #define SDXC_REG_BBCR (0x4C) /* SMC BIU Byte Count Register */ 68 + #define SDXC_REG_DBGC (0x50) /* SMC Debug Enable Register */ 69 + #define SDXC_REG_HWRST (0x78) /* SMC Card Hardware Reset for Register */ 70 + #define SDXC_REG_DMAC (0x80) /* SMC IDMAC Control Register */ 71 + #define SDXC_REG_DLBA (0x84) /* SMC IDMAC Descriptor List Base Addre */ 72 + #define SDXC_REG_IDST (0x88) /* SMC IDMAC Status Register */ 73 + #define SDXC_REG_IDIE (0x8C) /* SMC IDMAC Interrupt Enable Register */ 74 + #define SDXC_REG_CHDA (0x90) 75 + #define SDXC_REG_CBDA (0x94) 76 + 77 + #define mmc_readl(host, reg) \ 78 + readl((host)->reg_base + SDXC_##reg) 79 + #define mmc_writel(host, reg, value) \ 80 + writel((value), (host)->reg_base + SDXC_##reg) 81 + 82 + /* global control register bits */ 83 + #define SDXC_SOFT_RESET BIT(0) 84 + #define SDXC_FIFO_RESET BIT(1) 85 + #define SDXC_DMA_RESET BIT(2) 86 + #define SDXC_INTERRUPT_ENABLE_BIT BIT(4) 87 + #define SDXC_DMA_ENABLE_BIT BIT(5) 88 + #define SDXC_DEBOUNCE_ENABLE_BIT BIT(8) 89 + #define SDXC_POSEDGE_LATCH_DATA BIT(9) 90 + #define SDXC_DDR_MODE BIT(10) 91 + #define SDXC_MEMORY_ACCESS_DONE BIT(29) 92 + #define SDXC_ACCESS_DONE_DIRECT BIT(30) 93 + #define SDXC_ACCESS_BY_AHB BIT(31) 94 + #define SDXC_ACCESS_BY_DMA (0 << 31) 95 + #define SDXC_HARDWARE_RESET \ 96 + (SDXC_SOFT_RESET | SDXC_FIFO_RESET | SDXC_DMA_RESET) 97 + 98 + /* clock control bits */ 99 + #define SDXC_CARD_CLOCK_ON BIT(16) 100 + #define SDXC_LOW_POWER_ON BIT(17) 101 + 102 + /* bus width */ 103 + #define SDXC_WIDTH1 0 104 + #define SDXC_WIDTH4 1 105 + #define SDXC_WIDTH8 2 106 + 107 + /* smc command bits */ 108 + #define SDXC_RESP_EXPIRE BIT(6) 109 + #define SDXC_LONG_RESPONSE BIT(7) 110 + #define SDXC_CHECK_RESPONSE_CRC BIT(8) 111 + #define SDXC_DATA_EXPIRE BIT(9) 112 + #define SDXC_WRITE BIT(10) 113 + #define SDXC_SEQUENCE_MODE BIT(11) 114 + #define SDXC_SEND_AUTO_STOP BIT(12) 115 + #define SDXC_WAIT_PRE_OVER BIT(13) 116 + #define SDXC_STOP_ABORT_CMD BIT(14) 117 + #define SDXC_SEND_INIT_SEQUENCE BIT(15) 118 + #define SDXC_UPCLK_ONLY BIT(21) 119 + #define SDXC_READ_CEATA_DEV BIT(22) 120 + #define SDXC_CCS_EXPIRE BIT(23) 121 + #define SDXC_ENABLE_BIT_BOOT BIT(24) 122 + #define SDXC_ALT_BOOT_OPTIONS BIT(25) 123 + #define SDXC_BOOT_ACK_EXPIRE BIT(26) 124 + #define SDXC_BOOT_ABORT BIT(27) 125 + #define SDXC_VOLTAGE_SWITCH BIT(28) 126 + #define SDXC_USE_HOLD_REGISTER BIT(29) 127 + #define SDXC_START BIT(31) 128 + 129 + /* interrupt bits */ 130 + #define SDXC_RESP_ERROR BIT(1) 131 + #define SDXC_COMMAND_DONE BIT(2) 132 + #define SDXC_DATA_OVER BIT(3) 133 + #define SDXC_TX_DATA_REQUEST BIT(4) 134 + #define SDXC_RX_DATA_REQUEST BIT(5) 135 + #define SDXC_RESP_CRC_ERROR BIT(6) 136 + #define SDXC_DATA_CRC_ERROR BIT(7) 137 + #define SDXC_RESP_TIMEOUT BIT(8) 138 + #define SDXC_DATA_TIMEOUT BIT(9) 139 + #define SDXC_VOLTAGE_CHANGE_DONE BIT(10) 140 + #define SDXC_FIFO_RUN_ERROR BIT(11) 141 + #define SDXC_HARD_WARE_LOCKED BIT(12) 142 + #define SDXC_START_BIT_ERROR BIT(13) 143 + #define SDXC_AUTO_COMMAND_DONE BIT(14) 144 + #define SDXC_END_BIT_ERROR BIT(15) 145 + #define SDXC_SDIO_INTERRUPT BIT(16) 146 + #define SDXC_CARD_INSERT BIT(30) 147 + #define SDXC_CARD_REMOVE BIT(31) 148 + #define SDXC_INTERRUPT_ERROR_BIT \ 149 + (SDXC_RESP_ERROR | SDXC_RESP_CRC_ERROR | SDXC_DATA_CRC_ERROR | \ 150 + SDXC_RESP_TIMEOUT | SDXC_DATA_TIMEOUT | SDXC_FIFO_RUN_ERROR | \ 151 + SDXC_HARD_WARE_LOCKED | SDXC_START_BIT_ERROR | SDXC_END_BIT_ERROR) 152 + #define SDXC_INTERRUPT_DONE_BIT \ 153 + (SDXC_AUTO_COMMAND_DONE | SDXC_DATA_OVER | \ 154 + SDXC_COMMAND_DONE | SDXC_VOLTAGE_CHANGE_DONE) 155 + 156 + /* status */ 157 + #define SDXC_RXWL_FLAG BIT(0) 158 + #define SDXC_TXWL_FLAG BIT(1) 159 + #define SDXC_FIFO_EMPTY BIT(2) 160 + #define SDXC_FIFO_FULL BIT(3) 161 + #define SDXC_CARD_PRESENT BIT(8) 162 + #define SDXC_CARD_DATA_BUSY BIT(9) 163 + #define SDXC_DATA_FSM_BUSY BIT(10) 164 + #define SDXC_DMA_REQUEST BIT(31) 165 + #define SDXC_FIFO_SIZE 16 166 + 167 + /* Function select */ 168 + #define SDXC_CEATA_ON (0xceaa << 16) 169 + #define SDXC_SEND_IRQ_RESPONSE BIT(0) 170 + #define SDXC_SDIO_READ_WAIT BIT(1) 171 + #define SDXC_ABORT_READ_DATA BIT(2) 172 + #define SDXC_SEND_CCSD BIT(8) 173 + #define SDXC_SEND_AUTO_STOPCCSD BIT(9) 174 + #define SDXC_CEATA_DEV_IRQ_ENABLE BIT(10) 175 + 176 + /* IDMA controller bus mod bit field */ 177 + #define SDXC_IDMAC_SOFT_RESET BIT(0) 178 + #define SDXC_IDMAC_FIX_BURST BIT(1) 179 + #define SDXC_IDMAC_IDMA_ON BIT(7) 180 + #define SDXC_IDMAC_REFETCH_DES BIT(31) 181 + 182 + /* IDMA status bit field */ 183 + #define SDXC_IDMAC_TRANSMIT_INTERRUPT BIT(0) 184 + #define SDXC_IDMAC_RECEIVE_INTERRUPT BIT(1) 185 + #define SDXC_IDMAC_FATAL_BUS_ERROR BIT(2) 186 + #define SDXC_IDMAC_DESTINATION_INVALID BIT(4) 187 + #define SDXC_IDMAC_CARD_ERROR_SUM BIT(5) 188 + #define SDXC_IDMAC_NORMAL_INTERRUPT_SUM BIT(8) 189 + #define SDXC_IDMAC_ABNORMAL_INTERRUPT_SUM BIT(9) 190 + #define SDXC_IDMAC_HOST_ABORT_INTERRUPT BIT(10) 191 + #define SDXC_IDMAC_IDLE (0 << 13) 192 + #define SDXC_IDMAC_SUSPEND (1 << 13) 193 + #define SDXC_IDMAC_DESC_READ (2 << 13) 194 + #define SDXC_IDMAC_DESC_CHECK (3 << 13) 195 + #define SDXC_IDMAC_READ_REQUEST_WAIT (4 << 13) 196 + #define SDXC_IDMAC_WRITE_REQUEST_WAIT (5 << 13) 197 + #define SDXC_IDMAC_READ (6 << 13) 198 + #define SDXC_IDMAC_WRITE (7 << 13) 199 + #define SDXC_IDMAC_DESC_CLOSE (8 << 13) 200 + 201 + /* 202 + * If the idma-des-size-bits of property is ie 13, bufsize bits are: 203 + * Bits 0-12: buf1 size 204 + * Bits 13-25: buf2 size 205 + * Bits 26-31: not used 206 + * Since we only ever set buf1 size, we can simply store it directly. 207 + */ 208 + #define SDXC_IDMAC_DES0_DIC BIT(1) /* disable interrupt on completion */ 209 + #define SDXC_IDMAC_DES0_LD BIT(2) /* last descriptor */ 210 + #define SDXC_IDMAC_DES0_FD BIT(3) /* first descriptor */ 211 + #define SDXC_IDMAC_DES0_CH BIT(4) /* chain mode */ 212 + #define SDXC_IDMAC_DES0_ER BIT(5) /* end of ring */ 213 + #define SDXC_IDMAC_DES0_CES BIT(30) /* card error summary */ 214 + #define SDXC_IDMAC_DES0_OWN BIT(31) /* 1-idma owns it, 0-host owns it */ 215 + 216 + struct sunxi_idma_des { 217 + u32 config; 218 + u32 buf_size; 219 + u32 buf_addr_ptr1; 220 + u32 buf_addr_ptr2; 221 + }; 222 + 223 + struct sunxi_mmc_host { 224 + struct mmc_host *mmc; 225 + struct reset_control *reset; 226 + 227 + /* IO mapping base */ 228 + void __iomem *reg_base; 229 + 230 + /* clock management */ 231 + struct clk *clk_ahb; 232 + struct clk *clk_mmc; 233 + 234 + /* irq */ 235 + spinlock_t lock; 236 + int irq; 237 + u32 int_sum; 238 + u32 sdio_imask; 239 + 240 + /* dma */ 241 + u32 idma_des_size_bits; 242 + dma_addr_t sg_dma; 243 + void *sg_cpu; 244 + bool wait_dma; 245 + 246 + struct mmc_request *mrq; 247 + struct mmc_request *manual_stop_mrq; 248 + int ferror; 249 + }; 250 + 251 + static int sunxi_mmc_reset_host(struct sunxi_mmc_host *host) 252 + { 253 + unsigned long expire = jiffies + msecs_to_jiffies(250); 254 + u32 rval; 255 + 256 + mmc_writel(host, REG_CMDR, SDXC_HARDWARE_RESET); 257 + do { 258 + rval = mmc_readl(host, REG_GCTRL); 259 + } while (time_before(jiffies, expire) && (rval & SDXC_HARDWARE_RESET)); 260 + 261 + if (rval & SDXC_HARDWARE_RESET) { 262 + dev_err(mmc_dev(host->mmc), "fatal err reset timeout\n"); 263 + return -EIO; 264 + } 265 + 266 + return 0; 267 + } 268 + 269 + static int sunxi_mmc_init_host(struct mmc_host *mmc) 270 + { 271 + u32 rval; 272 + struct sunxi_mmc_host *host = mmc_priv(mmc); 273 + 274 + if (sunxi_mmc_reset_host(host)) 275 + return -EIO; 276 + 277 + mmc_writel(host, REG_FTRGL, 0x20070008); 278 + mmc_writel(host, REG_TMOUT, 0xffffffff); 279 + mmc_writel(host, REG_IMASK, host->sdio_imask); 280 + mmc_writel(host, REG_RINTR, 0xffffffff); 281 + mmc_writel(host, REG_DBGC, 0xdeb); 282 + mmc_writel(host, REG_FUNS, SDXC_CEATA_ON); 283 + mmc_writel(host, REG_DLBA, host->sg_dma); 284 + 285 + rval = mmc_readl(host, REG_GCTRL); 286 + rval |= SDXC_INTERRUPT_ENABLE_BIT; 287 + rval &= ~SDXC_ACCESS_DONE_DIRECT; 288 + mmc_writel(host, REG_GCTRL, rval); 289 + 290 + return 0; 291 + } 292 + 293 + static void sunxi_mmc_init_idma_des(struct sunxi_mmc_host *host, 294 + struct mmc_data *data) 295 + { 296 + struct sunxi_idma_des *pdes = (struct sunxi_idma_des *)host->sg_cpu; 297 + struct sunxi_idma_des *pdes_pa = (struct sunxi_idma_des *)host->sg_dma; 298 + int i, max_len = (1 << host->idma_des_size_bits); 299 + 300 + for (i = 0; i < data->sg_len; i++) { 301 + pdes[i].config = SDXC_IDMAC_DES0_CH | SDXC_IDMAC_DES0_OWN | 302 + SDXC_IDMAC_DES0_DIC; 303 + 304 + if (data->sg[i].length == max_len) 305 + pdes[i].buf_size = 0; /* 0 == max_len */ 306 + else 307 + pdes[i].buf_size = data->sg[i].length; 308 + 309 + pdes[i].buf_addr_ptr1 = sg_dma_address(&data->sg[i]); 310 + pdes[i].buf_addr_ptr2 = (u32)&pdes_pa[i + 1]; 311 + } 312 + 313 + pdes[0].config |= SDXC_IDMAC_DES0_FD; 314 + pdes[i - 1].config = SDXC_IDMAC_DES0_OWN | SDXC_IDMAC_DES0_LD; 315 + 316 + /* 317 + * Avoid the io-store starting the idmac hitting io-mem before the 318 + * descriptors hit the main-mem. 319 + */ 320 + wmb(); 321 + } 322 + 323 + static enum dma_data_direction sunxi_mmc_get_dma_dir(struct mmc_data *data) 324 + { 325 + if (data->flags & MMC_DATA_WRITE) 326 + return DMA_TO_DEVICE; 327 + else 328 + return DMA_FROM_DEVICE; 329 + } 330 + 331 + static int sunxi_mmc_map_dma(struct sunxi_mmc_host *host, 332 + struct mmc_data *data) 333 + { 334 + u32 i, dma_len; 335 + struct scatterlist *sg; 336 + 337 + dma_len = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len, 338 + sunxi_mmc_get_dma_dir(data)); 339 + if (dma_len == 0) { 340 + dev_err(mmc_dev(host->mmc), "dma_map_sg failed\n"); 341 + return -ENOMEM; 342 + } 343 + 344 + for_each_sg(data->sg, sg, data->sg_len, i) { 345 + if (sg->offset & 3 || sg->length & 3) { 346 + dev_err(mmc_dev(host->mmc), 347 + "unaligned scatterlist: os %x length %d\n", 348 + sg->offset, sg->length); 349 + return -EINVAL; 350 + } 351 + } 352 + 353 + return 0; 354 + } 355 + 356 + static void sunxi_mmc_start_dma(struct sunxi_mmc_host *host, 357 + struct mmc_data *data) 358 + { 359 + u32 rval; 360 + 361 + sunxi_mmc_init_idma_des(host, data); 362 + 363 + rval = mmc_readl(host, REG_GCTRL); 364 + rval |= SDXC_DMA_ENABLE_BIT; 365 + mmc_writel(host, REG_GCTRL, rval); 366 + rval |= SDXC_DMA_RESET; 367 + mmc_writel(host, REG_GCTRL, rval); 368 + 369 + mmc_writel(host, REG_DMAC, SDXC_IDMAC_SOFT_RESET); 370 + 371 + if (!(data->flags & MMC_DATA_WRITE)) 372 + mmc_writel(host, REG_IDIE, SDXC_IDMAC_RECEIVE_INTERRUPT); 373 + 374 + mmc_writel(host, REG_DMAC, 375 + SDXC_IDMAC_FIX_BURST | SDXC_IDMAC_IDMA_ON); 376 + } 377 + 378 + static void sunxi_mmc_send_manual_stop(struct sunxi_mmc_host *host, 379 + struct mmc_request *req) 380 + { 381 + u32 arg, cmd_val, ri; 382 + unsigned long expire = jiffies + msecs_to_jiffies(1000); 383 + 384 + cmd_val = SDXC_START | SDXC_RESP_EXPIRE | 385 + SDXC_STOP_ABORT_CMD | SDXC_CHECK_RESPONSE_CRC; 386 + 387 + if (req->cmd->opcode == SD_IO_RW_EXTENDED) { 388 + cmd_val |= SD_IO_RW_DIRECT; 389 + arg = (1 << 31) | (0 << 28) | (SDIO_CCCR_ABORT << 9) | 390 + ((req->cmd->arg >> 28) & 0x7); 391 + } else { 392 + cmd_val |= MMC_STOP_TRANSMISSION; 393 + arg = 0; 394 + } 395 + 396 + mmc_writel(host, REG_CARG, arg); 397 + mmc_writel(host, REG_CMDR, cmd_val); 398 + 399 + do { 400 + ri = mmc_readl(host, REG_RINTR); 401 + } while (!(ri & (SDXC_COMMAND_DONE | SDXC_INTERRUPT_ERROR_BIT)) && 402 + time_before(jiffies, expire)); 403 + 404 + if (!(ri & SDXC_COMMAND_DONE) || (ri & SDXC_INTERRUPT_ERROR_BIT)) { 405 + dev_err(mmc_dev(host->mmc), "send stop command failed\n"); 406 + if (req->stop) 407 + req->stop->resp[0] = -ETIMEDOUT; 408 + } else { 409 + if (req->stop) 410 + req->stop->resp[0] = mmc_readl(host, REG_RESP0); 411 + } 412 + 413 + mmc_writel(host, REG_RINTR, 0xffff); 414 + } 415 + 416 + static void sunxi_mmc_dump_errinfo(struct sunxi_mmc_host *host) 417 + { 418 + struct mmc_command *cmd = host->mrq->cmd; 419 + struct mmc_data *data = host->mrq->data; 420 + 421 + /* For some cmds timeout is normal with sd/mmc cards */ 422 + if ((host->int_sum & SDXC_INTERRUPT_ERROR_BIT) == 423 + SDXC_RESP_TIMEOUT && (cmd->opcode == SD_IO_SEND_OP_COND || 424 + cmd->opcode == SD_IO_RW_DIRECT)) 425 + return; 426 + 427 + dev_err(mmc_dev(host->mmc), 428 + "smc %d err, cmd %d,%s%s%s%s%s%s%s%s%s%s !!\n", 429 + host->mmc->index, cmd->opcode, 430 + data ? (data->flags & MMC_DATA_WRITE ? " WR" : " RD") : "", 431 + host->int_sum & SDXC_RESP_ERROR ? " RE" : "", 432 + host->int_sum & SDXC_RESP_CRC_ERROR ? " RCE" : "", 433 + host->int_sum & SDXC_DATA_CRC_ERROR ? " DCE" : "", 434 + host->int_sum & SDXC_RESP_TIMEOUT ? " RTO" : "", 435 + host->int_sum & SDXC_DATA_TIMEOUT ? " DTO" : "", 436 + host->int_sum & SDXC_FIFO_RUN_ERROR ? " FE" : "", 437 + host->int_sum & SDXC_HARD_WARE_LOCKED ? " HL" : "", 438 + host->int_sum & SDXC_START_BIT_ERROR ? " SBE" : "", 439 + host->int_sum & SDXC_END_BIT_ERROR ? " EBE" : "" 440 + ); 441 + } 442 + 443 + /* Called in interrupt context! */ 444 + static irqreturn_t sunxi_mmc_finalize_request(struct sunxi_mmc_host *host) 445 + { 446 + struct mmc_request *mrq = host->mrq; 447 + struct mmc_data *data = mrq->data; 448 + u32 rval; 449 + 450 + mmc_writel(host, REG_IMASK, host->sdio_imask); 451 + mmc_writel(host, REG_IDIE, 0); 452 + 453 + if (host->int_sum & SDXC_INTERRUPT_ERROR_BIT) { 454 + sunxi_mmc_dump_errinfo(host); 455 + mrq->cmd->error = -ETIMEDOUT; 456 + 457 + if (data) { 458 + data->error = -ETIMEDOUT; 459 + host->manual_stop_mrq = mrq; 460 + } 461 + 462 + if (mrq->stop) 463 + mrq->stop->error = -ETIMEDOUT; 464 + } else { 465 + if (mrq->cmd->flags & MMC_RSP_136) { 466 + mrq->cmd->resp[0] = mmc_readl(host, REG_RESP3); 467 + mrq->cmd->resp[1] = mmc_readl(host, REG_RESP2); 468 + mrq->cmd->resp[2] = mmc_readl(host, REG_RESP1); 469 + mrq->cmd->resp[3] = mmc_readl(host, REG_RESP0); 470 + } else { 471 + mrq->cmd->resp[0] = mmc_readl(host, REG_RESP0); 472 + } 473 + 474 + if (data) 475 + data->bytes_xfered = data->blocks * data->blksz; 476 + } 477 + 478 + if (data) { 479 + mmc_writel(host, REG_IDST, 0x337); 480 + mmc_writel(host, REG_DMAC, 0); 481 + rval = mmc_readl(host, REG_GCTRL); 482 + rval |= SDXC_DMA_RESET; 483 + mmc_writel(host, REG_GCTRL, rval); 484 + rval &= ~SDXC_DMA_ENABLE_BIT; 485 + mmc_writel(host, REG_GCTRL, rval); 486 + rval |= SDXC_FIFO_RESET; 487 + mmc_writel(host, REG_GCTRL, rval); 488 + dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, 489 + sunxi_mmc_get_dma_dir(data)); 490 + } 491 + 492 + mmc_writel(host, REG_RINTR, 0xffff); 493 + 494 + host->mrq = NULL; 495 + host->int_sum = 0; 496 + host->wait_dma = false; 497 + 498 + return host->manual_stop_mrq ? IRQ_WAKE_THREAD : IRQ_HANDLED; 499 + } 500 + 501 + static irqreturn_t sunxi_mmc_irq(int irq, void *dev_id) 502 + { 503 + struct sunxi_mmc_host *host = dev_id; 504 + struct mmc_request *mrq; 505 + u32 msk_int, idma_int; 506 + bool finalize = false; 507 + bool sdio_int = false; 508 + irqreturn_t ret = IRQ_HANDLED; 509 + 510 + spin_lock(&host->lock); 511 + 512 + idma_int = mmc_readl(host, REG_IDST); 513 + msk_int = mmc_readl(host, REG_MISTA); 514 + 515 + dev_dbg(mmc_dev(host->mmc), "irq: rq %p mi %08x idi %08x\n", 516 + host->mrq, msk_int, idma_int); 517 + 518 + mrq = host->mrq; 519 + if (mrq) { 520 + if (idma_int & SDXC_IDMAC_RECEIVE_INTERRUPT) 521 + host->wait_dma = false; 522 + 523 + host->int_sum |= msk_int; 524 + 525 + /* Wait for COMMAND_DONE on RESPONSE_TIMEOUT before finalize */ 526 + if ((host->int_sum & SDXC_RESP_TIMEOUT) && 527 + !(host->int_sum & SDXC_COMMAND_DONE)) 528 + mmc_writel(host, REG_IMASK, 529 + host->sdio_imask | SDXC_COMMAND_DONE); 530 + /* Don't wait for dma on error */ 531 + else if (host->int_sum & SDXC_INTERRUPT_ERROR_BIT) 532 + finalize = true; 533 + else if ((host->int_sum & SDXC_INTERRUPT_DONE_BIT) && 534 + !host->wait_dma) 535 + finalize = true; 536 + } 537 + 538 + if (msk_int & SDXC_SDIO_INTERRUPT) 539 + sdio_int = true; 540 + 541 + mmc_writel(host, REG_RINTR, msk_int); 542 + mmc_writel(host, REG_IDST, idma_int); 543 + 544 + if (finalize) 545 + ret = sunxi_mmc_finalize_request(host); 546 + 547 + spin_unlock(&host->lock); 548 + 549 + if (finalize && ret == IRQ_HANDLED) 550 + mmc_request_done(host->mmc, mrq); 551 + 552 + if (sdio_int) 553 + mmc_signal_sdio_irq(host->mmc); 554 + 555 + return ret; 556 + } 557 + 558 + static irqreturn_t sunxi_mmc_handle_manual_stop(int irq, void *dev_id) 559 + { 560 + struct sunxi_mmc_host *host = dev_id; 561 + struct mmc_request *mrq; 562 + unsigned long iflags; 563 + 564 + spin_lock_irqsave(&host->lock, iflags); 565 + mrq = host->manual_stop_mrq; 566 + spin_unlock_irqrestore(&host->lock, iflags); 567 + 568 + if (!mrq) { 569 + dev_err(mmc_dev(host->mmc), "no request for manual stop\n"); 570 + return IRQ_HANDLED; 571 + } 572 + 573 + dev_err(mmc_dev(host->mmc), "data error, sending stop command\n"); 574 + sunxi_mmc_send_manual_stop(host, mrq); 575 + 576 + spin_lock_irqsave(&host->lock, iflags); 577 + host->manual_stop_mrq = NULL; 578 + spin_unlock_irqrestore(&host->lock, iflags); 579 + 580 + mmc_request_done(host->mmc, mrq); 581 + 582 + return IRQ_HANDLED; 583 + } 584 + 585 + static int sunxi_mmc_oclk_onoff(struct sunxi_mmc_host *host, u32 oclk_en) 586 + { 587 + unsigned long expire = jiffies + msecs_to_jiffies(250); 588 + u32 rval; 589 + 590 + rval = mmc_readl(host, REG_CLKCR); 591 + rval &= ~(SDXC_CARD_CLOCK_ON | SDXC_LOW_POWER_ON); 592 + 593 + if (oclk_en) 594 + rval |= SDXC_CARD_CLOCK_ON; 595 + 596 + mmc_writel(host, REG_CLKCR, rval); 597 + 598 + rval = SDXC_START | SDXC_UPCLK_ONLY | SDXC_WAIT_PRE_OVER; 599 + mmc_writel(host, REG_CMDR, rval); 600 + 601 + do { 602 + rval = mmc_readl(host, REG_CMDR); 603 + } while (time_before(jiffies, expire) && (rval & SDXC_START)); 604 + 605 + /* clear irq status bits set by the command */ 606 + mmc_writel(host, REG_RINTR, 607 + mmc_readl(host, REG_RINTR) & ~SDXC_SDIO_INTERRUPT); 608 + 609 + if (rval & SDXC_START) { 610 + dev_err(mmc_dev(host->mmc), "fatal err update clk timeout\n"); 611 + return -EIO; 612 + } 613 + 614 + return 0; 615 + } 616 + 617 + static int sunxi_mmc_clk_set_rate(struct sunxi_mmc_host *host, 618 + struct mmc_ios *ios) 619 + { 620 + u32 rate, oclk_dly, rval, sclk_dly, src_clk; 621 + int ret; 622 + 623 + rate = clk_round_rate(host->clk_mmc, ios->clock); 624 + dev_dbg(mmc_dev(host->mmc), "setting clk to %d, rounded %d\n", 625 + ios->clock, rate); 626 + 627 + /* setting clock rate */ 628 + ret = clk_set_rate(host->clk_mmc, rate); 629 + if (ret) { 630 + dev_err(mmc_dev(host->mmc), "error setting clk to %d: %d\n", 631 + rate, ret); 632 + return ret; 633 + } 634 + 635 + ret = sunxi_mmc_oclk_onoff(host, 0); 636 + if (ret) 637 + return ret; 638 + 639 + /* clear internal divider */ 640 + rval = mmc_readl(host, REG_CLKCR); 641 + rval &= ~0xff; 642 + mmc_writel(host, REG_CLKCR, rval); 643 + 644 + /* determine delays */ 645 + if (rate <= 400000) { 646 + oclk_dly = 0; 647 + sclk_dly = 7; 648 + } else if (rate <= 25000000) { 649 + oclk_dly = 0; 650 + sclk_dly = 5; 651 + } else if (rate <= 50000000) { 652 + if (ios->timing == MMC_TIMING_UHS_DDR50) { 653 + oclk_dly = 2; 654 + sclk_dly = 4; 655 + } else { 656 + oclk_dly = 3; 657 + sclk_dly = 5; 658 + } 659 + } else { 660 + /* rate > 50000000 */ 661 + oclk_dly = 2; 662 + sclk_dly = 4; 663 + } 664 + 665 + src_clk = clk_get_rate(clk_get_parent(host->clk_mmc)); 666 + if (src_clk >= 300000000 && src_clk <= 400000000) { 667 + if (oclk_dly) 668 + oclk_dly--; 669 + if (sclk_dly) 670 + sclk_dly--; 671 + } 672 + 673 + clk_sunxi_mmc_phase_control(host->clk_mmc, sclk_dly, oclk_dly); 674 + 675 + return sunxi_mmc_oclk_onoff(host, 1); 676 + } 677 + 678 + static void sunxi_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) 679 + { 680 + struct sunxi_mmc_host *host = mmc_priv(mmc); 681 + u32 rval; 682 + 683 + /* Set the power state */ 684 + switch (ios->power_mode) { 685 + case MMC_POWER_ON: 686 + break; 687 + 688 + case MMC_POWER_UP: 689 + mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, ios->vdd); 690 + 691 + host->ferror = sunxi_mmc_init_host(mmc); 692 + if (host->ferror) 693 + return; 694 + 695 + dev_dbg(mmc_dev(mmc), "power on!\n"); 696 + break; 697 + 698 + case MMC_POWER_OFF: 699 + dev_dbg(mmc_dev(mmc), "power off!\n"); 700 + sunxi_mmc_reset_host(host); 701 + mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0); 702 + break; 703 + } 704 + 705 + /* set bus width */ 706 + switch (ios->bus_width) { 707 + case MMC_BUS_WIDTH_1: 708 + mmc_writel(host, REG_WIDTH, SDXC_WIDTH1); 709 + break; 710 + case MMC_BUS_WIDTH_4: 711 + mmc_writel(host, REG_WIDTH, SDXC_WIDTH4); 712 + break; 713 + case MMC_BUS_WIDTH_8: 714 + mmc_writel(host, REG_WIDTH, SDXC_WIDTH8); 715 + break; 716 + } 717 + 718 + /* set ddr mode */ 719 + rval = mmc_readl(host, REG_GCTRL); 720 + if (ios->timing == MMC_TIMING_UHS_DDR50) 721 + rval |= SDXC_DDR_MODE; 722 + else 723 + rval &= ~SDXC_DDR_MODE; 724 + mmc_writel(host, REG_GCTRL, rval); 725 + 726 + /* set up clock */ 727 + if (ios->clock && ios->power_mode) { 728 + host->ferror = sunxi_mmc_clk_set_rate(host, ios); 729 + /* Android code had a usleep_range(50000, 55000); here */ 730 + } 731 + } 732 + 733 + static void sunxi_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable) 734 + { 735 + struct sunxi_mmc_host *host = mmc_priv(mmc); 736 + unsigned long flags; 737 + u32 imask; 738 + 739 + spin_lock_irqsave(&host->lock, flags); 740 + 741 + imask = mmc_readl(host, REG_IMASK); 742 + if (enable) { 743 + host->sdio_imask = SDXC_SDIO_INTERRUPT; 744 + imask |= SDXC_SDIO_INTERRUPT; 745 + } else { 746 + host->sdio_imask = 0; 747 + imask &= ~SDXC_SDIO_INTERRUPT; 748 + } 749 + mmc_writel(host, REG_IMASK, imask); 750 + spin_unlock_irqrestore(&host->lock, flags); 751 + } 752 + 753 + static void sunxi_mmc_hw_reset(struct mmc_host *mmc) 754 + { 755 + struct sunxi_mmc_host *host = mmc_priv(mmc); 756 + mmc_writel(host, REG_HWRST, 0); 757 + udelay(10); 758 + mmc_writel(host, REG_HWRST, 1); 759 + udelay(300); 760 + } 761 + 762 + static void sunxi_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq) 763 + { 764 + struct sunxi_mmc_host *host = mmc_priv(mmc); 765 + struct mmc_command *cmd = mrq->cmd; 766 + struct mmc_data *data = mrq->data; 767 + unsigned long iflags; 768 + u32 imask = SDXC_INTERRUPT_ERROR_BIT; 769 + u32 cmd_val = SDXC_START | (cmd->opcode & 0x3f); 770 + int ret; 771 + 772 + /* Check for set_ios errors (should never happen) */ 773 + if (host->ferror) { 774 + mrq->cmd->error = host->ferror; 775 + mmc_request_done(mmc, mrq); 776 + return; 777 + } 778 + 779 + if (data) { 780 + ret = sunxi_mmc_map_dma(host, data); 781 + if (ret < 0) { 782 + dev_err(mmc_dev(mmc), "map DMA failed\n"); 783 + cmd->error = ret; 784 + data->error = ret; 785 + mmc_request_done(mmc, mrq); 786 + return; 787 + } 788 + } 789 + 790 + if (cmd->opcode == MMC_GO_IDLE_STATE) { 791 + cmd_val |= SDXC_SEND_INIT_SEQUENCE; 792 + imask |= SDXC_COMMAND_DONE; 793 + } 794 + 795 + if (cmd->flags & MMC_RSP_PRESENT) { 796 + cmd_val |= SDXC_RESP_EXPIRE; 797 + if (cmd->flags & MMC_RSP_136) 798 + cmd_val |= SDXC_LONG_RESPONSE; 799 + if (cmd->flags & MMC_RSP_CRC) 800 + cmd_val |= SDXC_CHECK_RESPONSE_CRC; 801 + 802 + if ((cmd->flags & MMC_CMD_MASK) == MMC_CMD_ADTC) { 803 + cmd_val |= SDXC_DATA_EXPIRE | SDXC_WAIT_PRE_OVER; 804 + if (cmd->data->flags & MMC_DATA_STREAM) { 805 + imask |= SDXC_AUTO_COMMAND_DONE; 806 + cmd_val |= SDXC_SEQUENCE_MODE | 807 + SDXC_SEND_AUTO_STOP; 808 + } 809 + 810 + if (cmd->data->stop) { 811 + imask |= SDXC_AUTO_COMMAND_DONE; 812 + cmd_val |= SDXC_SEND_AUTO_STOP; 813 + } else { 814 + imask |= SDXC_DATA_OVER; 815 + } 816 + 817 + if (cmd->data->flags & MMC_DATA_WRITE) 818 + cmd_val |= SDXC_WRITE; 819 + else 820 + host->wait_dma = true; 821 + } else { 822 + imask |= SDXC_COMMAND_DONE; 823 + } 824 + } else { 825 + imask |= SDXC_COMMAND_DONE; 826 + } 827 + 828 + dev_dbg(mmc_dev(mmc), "cmd %d(%08x) arg %x ie 0x%08x len %d\n", 829 + cmd_val & 0x3f, cmd_val, cmd->arg, imask, 830 + mrq->data ? mrq->data->blksz * mrq->data->blocks : 0); 831 + 832 + spin_lock_irqsave(&host->lock, iflags); 833 + 834 + if (host->mrq || host->manual_stop_mrq) { 835 + spin_unlock_irqrestore(&host->lock, iflags); 836 + 837 + if (data) 838 + dma_unmap_sg(mmc_dev(mmc), data->sg, data->sg_len, 839 + sunxi_mmc_get_dma_dir(data)); 840 + 841 + dev_err(mmc_dev(mmc), "request already pending\n"); 842 + mrq->cmd->error = -EBUSY; 843 + mmc_request_done(mmc, mrq); 844 + return; 845 + } 846 + 847 + if (data) { 848 + mmc_writel(host, REG_BLKSZ, data->blksz); 849 + mmc_writel(host, REG_BCNTR, data->blksz * data->blocks); 850 + sunxi_mmc_start_dma(host, data); 851 + } 852 + 853 + host->mrq = mrq; 854 + mmc_writel(host, REG_IMASK, host->sdio_imask | imask); 855 + mmc_writel(host, REG_CARG, cmd->arg); 856 + mmc_writel(host, REG_CMDR, cmd_val); 857 + 858 + spin_unlock_irqrestore(&host->lock, iflags); 859 + } 860 + 861 + static const struct of_device_id sunxi_mmc_of_match[] = { 862 + { .compatible = "allwinner,sun4i-a10-mmc", }, 863 + { .compatible = "allwinner,sun5i-a13-mmc", }, 864 + { /* sentinel */ } 865 + }; 866 + MODULE_DEVICE_TABLE(of, sunxi_mmc_of_match); 867 + 868 + static struct mmc_host_ops sunxi_mmc_ops = { 869 + .request = sunxi_mmc_request, 870 + .set_ios = sunxi_mmc_set_ios, 871 + .get_ro = mmc_gpio_get_ro, 872 + .get_cd = mmc_gpio_get_cd, 873 + .enable_sdio_irq = sunxi_mmc_enable_sdio_irq, 874 + .hw_reset = sunxi_mmc_hw_reset, 875 + }; 876 + 877 + static int sunxi_mmc_resource_request(struct sunxi_mmc_host *host, 878 + struct platform_device *pdev) 879 + { 880 + struct device_node *np = pdev->dev.of_node; 881 + int ret; 882 + 883 + if (of_device_is_compatible(np, "allwinner,sun4i-a10-mmc")) 884 + host->idma_des_size_bits = 13; 885 + else 886 + host->idma_des_size_bits = 16; 887 + 888 + ret = mmc_regulator_get_supply(host->mmc); 889 + if (ret) { 890 + if (ret != -EPROBE_DEFER) 891 + dev_err(&pdev->dev, "Could not get vmmc supply\n"); 892 + return ret; 893 + } 894 + 895 + host->reg_base = devm_ioremap_resource(&pdev->dev, 896 + platform_get_resource(pdev, IORESOURCE_MEM, 0)); 897 + if (IS_ERR(host->reg_base)) 898 + return PTR_ERR(host->reg_base); 899 + 900 + host->clk_ahb = devm_clk_get(&pdev->dev, "ahb"); 901 + if (IS_ERR(host->clk_ahb)) { 902 + dev_err(&pdev->dev, "Could not get ahb clock\n"); 903 + return PTR_ERR(host->clk_ahb); 904 + } 905 + 906 + host->clk_mmc = devm_clk_get(&pdev->dev, "mmc"); 907 + if (IS_ERR(host->clk_mmc)) { 908 + dev_err(&pdev->dev, "Could not get mmc clock\n"); 909 + return PTR_ERR(host->clk_mmc); 910 + } 911 + 912 + host->reset = devm_reset_control_get(&pdev->dev, "ahb"); 913 + 914 + ret = clk_prepare_enable(host->clk_ahb); 915 + if (ret) { 916 + dev_err(&pdev->dev, "Enable ahb clk err %d\n", ret); 917 + return ret; 918 + } 919 + 920 + ret = clk_prepare_enable(host->clk_mmc); 921 + if (ret) { 922 + dev_err(&pdev->dev, "Enable mmc clk err %d\n", ret); 923 + goto error_disable_clk_ahb; 924 + } 925 + 926 + if (!IS_ERR(host->reset)) { 927 + ret = reset_control_deassert(host->reset); 928 + if (ret) { 929 + dev_err(&pdev->dev, "reset err %d\n", ret); 930 + goto error_disable_clk_mmc; 931 + } 932 + } 933 + 934 + /* 935 + * Sometimes the controller asserts the irq on boot for some reason, 936 + * make sure the controller is in a sane state before enabling irqs. 937 + */ 938 + ret = sunxi_mmc_reset_host(host); 939 + if (ret) 940 + goto error_assert_reset; 941 + 942 + host->irq = platform_get_irq(pdev, 0); 943 + return devm_request_threaded_irq(&pdev->dev, host->irq, sunxi_mmc_irq, 944 + sunxi_mmc_handle_manual_stop, 0, "sunxi-mmc", host); 945 + 946 + error_assert_reset: 947 + if (!IS_ERR(host->reset)) 948 + reset_control_assert(host->reset); 949 + error_disable_clk_mmc: 950 + clk_disable_unprepare(host->clk_mmc); 951 + error_disable_clk_ahb: 952 + clk_disable_unprepare(host->clk_ahb); 953 + return ret; 954 + } 955 + 956 + static int sunxi_mmc_probe(struct platform_device *pdev) 957 + { 958 + struct sunxi_mmc_host *host; 959 + struct mmc_host *mmc; 960 + int ret; 961 + 962 + mmc = mmc_alloc_host(sizeof(struct sunxi_mmc_host), &pdev->dev); 963 + if (!mmc) { 964 + dev_err(&pdev->dev, "mmc alloc host failed\n"); 965 + return -ENOMEM; 966 + } 967 + 968 + host = mmc_priv(mmc); 969 + host->mmc = mmc; 970 + spin_lock_init(&host->lock); 971 + 972 + ret = sunxi_mmc_resource_request(host, pdev); 973 + if (ret) 974 + goto error_free_host; 975 + 976 + host->sg_cpu = dma_alloc_coherent(&pdev->dev, PAGE_SIZE, 977 + &host->sg_dma, GFP_KERNEL); 978 + if (!host->sg_cpu) { 979 + dev_err(&pdev->dev, "Failed to allocate DMA descriptor mem\n"); 980 + ret = -ENOMEM; 981 + goto error_free_host; 982 + } 983 + 984 + mmc->ops = &sunxi_mmc_ops; 985 + mmc->max_blk_count = 8192; 986 + mmc->max_blk_size = 4096; 987 + mmc->max_segs = PAGE_SIZE / sizeof(struct sunxi_idma_des); 988 + mmc->max_seg_size = (1 << host->idma_des_size_bits); 989 + mmc->max_req_size = mmc->max_seg_size * mmc->max_segs; 990 + /* 400kHz ~ 50MHz */ 991 + mmc->f_min = 400000; 992 + mmc->f_max = 50000000; 993 + mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED; 994 + 995 + ret = mmc_of_parse(mmc); 996 + if (ret) 997 + goto error_free_dma; 998 + 999 + ret = mmc_add_host(mmc); 1000 + if (ret) 1001 + goto error_free_dma; 1002 + 1003 + dev_info(&pdev->dev, "base:0x%p irq:%u\n", host->reg_base, host->irq); 1004 + platform_set_drvdata(pdev, mmc); 1005 + return 0; 1006 + 1007 + error_free_dma: 1008 + dma_free_coherent(&pdev->dev, PAGE_SIZE, host->sg_cpu, host->sg_dma); 1009 + error_free_host: 1010 + mmc_free_host(mmc); 1011 + return ret; 1012 + } 1013 + 1014 + static int sunxi_mmc_remove(struct platform_device *pdev) 1015 + { 1016 + struct mmc_host *mmc = platform_get_drvdata(pdev); 1017 + struct sunxi_mmc_host *host = mmc_priv(mmc); 1018 + 1019 + mmc_remove_host(mmc); 1020 + disable_irq(host->irq); 1021 + sunxi_mmc_reset_host(host); 1022 + 1023 + if (!IS_ERR(host->reset)) 1024 + reset_control_assert(host->reset); 1025 + 1026 + clk_disable_unprepare(host->clk_mmc); 1027 + clk_disable_unprepare(host->clk_ahb); 1028 + 1029 + dma_free_coherent(&pdev->dev, PAGE_SIZE, host->sg_cpu, host->sg_dma); 1030 + mmc_free_host(mmc); 1031 + 1032 + return 0; 1033 + } 1034 + 1035 + static struct platform_driver sunxi_mmc_driver = { 1036 + .driver = { 1037 + .name = "sunxi-mmc", 1038 + .owner = THIS_MODULE, 1039 + .of_match_table = of_match_ptr(sunxi_mmc_of_match), 1040 + }, 1041 + .probe = sunxi_mmc_probe, 1042 + .remove = sunxi_mmc_remove, 1043 + }; 1044 + module_platform_driver(sunxi_mmc_driver); 1045 + 1046 + MODULE_DESCRIPTION("Allwinner's SD/MMC Card Controller Driver"); 1047 + MODULE_LICENSE("GPL v2"); 1048 + MODULE_AUTHOR("David Lanzend�rfer <david.lanzendoerfer@o2s.ch>"); 1049 + MODULE_ALIAS("platform:sunxi-mmc");
+62
include/dt-bindings/clock/bcm21664.h
··· 1 + /* 2 + * Copyright (C) 2013 Broadcom Corporation 3 + * Copyright 2013 Linaro Limited 4 + * 5 + * This program is free software; you can redistribute it and/or 6 + * modify it under the terms of the GNU General Public License as 7 + * published by the Free Software Foundation version 2. 8 + * 9 + * This program is distributed "as is" WITHOUT ANY WARRANTY of any 10 + * kind, whether express or implied; without even the implied warranty 11 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 + * GNU General Public License for more details. 13 + */ 14 + 15 + #ifndef _CLOCK_BCM21664_H 16 + #define _CLOCK_BCM21664_H 17 + 18 + /* 19 + * This file defines the values used to specify clocks provided by 20 + * the clock control units (CCUs) on Broadcom BCM21664 family SoCs. 21 + */ 22 + 23 + /* bcm21664 CCU device tree "compatible" strings */ 24 + #define BCM21664_DT_ROOT_CCU_COMPAT "brcm,bcm21664-root-ccu" 25 + #define BCM21664_DT_AON_CCU_COMPAT "brcm,bcm21664-aon-ccu" 26 + #define BCM21664_DT_MASTER_CCU_COMPAT "brcm,bcm21664-master-ccu" 27 + #define BCM21664_DT_SLAVE_CCU_COMPAT "brcm,bcm21664-slave-ccu" 28 + 29 + /* root CCU clock ids */ 30 + 31 + #define BCM21664_ROOT_CCU_FRAC_1M 0 32 + #define BCM21664_ROOT_CCU_CLOCK_COUNT 1 33 + 34 + /* aon CCU clock ids */ 35 + 36 + #define BCM21664_AON_CCU_HUB_TIMER 0 37 + #define BCM21664_AON_CCU_CLOCK_COUNT 1 38 + 39 + /* master CCU clock ids */ 40 + 41 + #define BCM21664_MASTER_CCU_SDIO1 0 42 + #define BCM21664_MASTER_CCU_SDIO2 1 43 + #define BCM21664_MASTER_CCU_SDIO3 2 44 + #define BCM21664_MASTER_CCU_SDIO4 3 45 + #define BCM21664_MASTER_CCU_SDIO1_SLEEP 4 46 + #define BCM21664_MASTER_CCU_SDIO2_SLEEP 5 47 + #define BCM21664_MASTER_CCU_SDIO3_SLEEP 6 48 + #define BCM21664_MASTER_CCU_SDIO4_SLEEP 7 49 + #define BCM21664_MASTER_CCU_CLOCK_COUNT 8 50 + 51 + /* slave CCU clock ids */ 52 + 53 + #define BCM21664_SLAVE_CCU_UARTB 0 54 + #define BCM21664_SLAVE_CCU_UARTB2 1 55 + #define BCM21664_SLAVE_CCU_UARTB3 2 56 + #define BCM21664_SLAVE_CCU_BSC1 3 57 + #define BCM21664_SLAVE_CCU_BSC2 4 58 + #define BCM21664_SLAVE_CCU_BSC3 5 59 + #define BCM21664_SLAVE_CCU_BSC4 6 60 + #define BCM21664_SLAVE_CCU_CLOCK_COUNT 7 61 + 62 + #endif /* _CLOCK_BCM21664_H */
+12
include/dt-bindings/clock/bcm281xx.h
··· 20 20 * the clock control units (CCUs) on Broadcom BCM281XX family SoCs. 21 21 */ 22 22 23 + /* 24 + * These are the bcm281xx CCU device tree "compatible" strings. 25 + * We're stuck with using "bcm11351" in the string because wild 26 + * cards aren't allowed, and that name was the first one defined 27 + * in this family of devices. 28 + */ 29 + #define BCM281XX_DT_ROOT_CCU_COMPAT "brcm,bcm11351-root-ccu" 30 + #define BCM281XX_DT_AON_CCU_COMPAT "brcm,bcm11351-aon-ccu" 31 + #define BCM281XX_DT_HUB_CCU_COMPAT "brcm,bcm11351-hub-ccu" 32 + #define BCM281XX_DT_MASTER_CCU_COMPAT "brcm,bcm11351-master-ccu" 33 + #define BCM281XX_DT_SLAVE_CCU_COMPAT "brcm,bcm11351-slave-ccu" 34 + 23 35 /* root CCU clock ids */ 24 36 25 37 #define BCM281XX_ROOT_CCU_FRAC_1M 0
+58
include/dt-bindings/clock/hix5hd2-clock.h
··· 1 + /* 2 + * Copyright (c) 2014 Linaro Ltd. 3 + * Copyright (c) 2014 Hisilicon Limited. 4 + * 5 + * This program is free software; you can redistribute it and/or modify it 6 + * under the terms and conditions of the GNU General Public License, 7 + * version 2, as published by the Free Software Foundation. 8 + */ 9 + 10 + #ifndef __DTS_HIX5HD2_CLOCK_H 11 + #define __DTS_HIX5HD2_CLOCK_H 12 + 13 + /* fixed rate */ 14 + #define HIX5HD2_FIXED_1200M 1 15 + #define HIX5HD2_FIXED_400M 2 16 + #define HIX5HD2_FIXED_48M 3 17 + #define HIX5HD2_FIXED_24M 4 18 + #define HIX5HD2_FIXED_600M 5 19 + #define HIX5HD2_FIXED_300M 6 20 + #define HIX5HD2_FIXED_75M 7 21 + #define HIX5HD2_FIXED_200M 8 22 + #define HIX5HD2_FIXED_100M 9 23 + #define HIX5HD2_FIXED_40M 10 24 + #define HIX5HD2_FIXED_150M 11 25 + #define HIX5HD2_FIXED_1728M 12 26 + #define HIX5HD2_FIXED_28P8M 13 27 + #define HIX5HD2_FIXED_432M 14 28 + #define HIX5HD2_FIXED_345P6M 15 29 + #define HIX5HD2_FIXED_288M 16 30 + #define HIX5HD2_FIXED_60M 17 31 + #define HIX5HD2_FIXED_750M 18 32 + #define HIX5HD2_FIXED_500M 19 33 + #define HIX5HD2_FIXED_54M 20 34 + #define HIX5HD2_FIXED_27M 21 35 + #define HIX5HD2_FIXED_1500M 22 36 + #define HIX5HD2_FIXED_375M 23 37 + #define HIX5HD2_FIXED_187M 24 38 + #define HIX5HD2_FIXED_250M 25 39 + #define HIX5HD2_FIXED_125M 26 40 + #define HIX5HD2_FIXED_2P02M 27 41 + #define HIX5HD2_FIXED_50M 28 42 + #define HIX5HD2_FIXED_25M 29 43 + #define HIX5HD2_FIXED_83M 30 44 + 45 + /* mux clocks */ 46 + #define HIX5HD2_SFC_MUX 64 47 + #define HIX5HD2_MMC_MUX 65 48 + #define HIX5HD2_FEPHY_MUX 66 49 + 50 + /* gate clocks */ 51 + #define HIX5HD2_SFC_RST 128 52 + #define HIX5HD2_SFC_CLK 129 53 + #define HIX5HD2_MMC_CIU_CLK 130 54 + #define HIX5HD2_MMC_BIU_CLK 131 55 + #define HIX5HD2_MMC_CIU_RST 132 56 + 57 + #define HIX5HD2_NR_CLKS 256 58 + #endif /* __DTS_HIX5HD2_CLOCK_H */
+3 -4
include/dt-bindings/clock/qcom,gcc-msm8960.h
··· 51 51 #define QDSS_TSCTR_CLK 34 52 52 #define SFAB_ADM0_M0_A_CLK 35 53 53 #define SFAB_ADM0_M1_A_CLK 36 54 - #define SFAB_ADM0_M2_A_CLK 37 54 + #define SFAB_ADM0_M2_H_CLK 37 55 55 #define ADM0_CLK 38 56 56 #define ADM0_PBUS_CLK 39 57 57 #define MSS_XPU_CLK 40 ··· 99 99 #define CFPB2_H_CLK 82 100 100 #define SFAB_CFPB_M_H_CLK 83 101 101 #define CFPB_MASTER_H_CLK 84 102 - #define SFAB_CFPB_S_HCLK 85 102 + #define SFAB_CFPB_S_H_CLK 85 103 103 #define CFPB_SPLITTER_H_CLK 86 104 104 #define TSIF_H_CLK 87 105 105 #define TSIF_INACTIVITY_TIMERS_CLK 88 ··· 110 110 #define CE1_SLEEP_CLK 93 111 111 #define CE2_H_CLK 94 112 112 #define CE2_CORE_CLK 95 113 - #define CE2_SLEEP_CLK 96 114 113 #define SFPB_H_CLK_SRC 97 115 114 #define SFPB_H_CLK 98 116 115 #define SFAB_SFPB_M_H_CLK 99 ··· 251 252 #define MSS_S_H_CLK 235 252 253 #define MSS_CXO_SRC_CLK 236 253 254 #define SATA_H_CLK 237 254 - #define SATA_SRC_CLK 238 255 + #define SATA_CLK_SRC 238 255 256 #define SATA_RXOOB_CLK 239 256 257 #define SATA_PMALIVE_CLK 240 257 258 #define SATA_PHY_REF_CLK 241
+4
include/dt-bindings/clock/qcom,gcc-msm8974.h
··· 316 316 #define GCC_CE2_CLK_SLEEP_ENA 299 317 317 #define GCC_CE2_AXI_CLK_SLEEP_ENA 300 318 318 #define GCC_CE2_AHB_CLK_SLEEP_ENA 301 319 + #define GPLL4 302 320 + #define GPLL4_VOTE 303 321 + #define GCC_SDCC1_CDCCAL_SLEEP_CLK 304 322 + #define GCC_SDCC1_CDCCAL_FF_CLK 305 319 323 320 324 #endif
+64
include/dt-bindings/clock/r8a7779-clock.h
··· 1 + /* 2 + * Copyright (C) 2013 Horms Solutions Ltd. 3 + * 4 + * Contact: Simon Horman <horms@verge.net.au> 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License as published by 8 + * the Free Software Foundation; either version 2 of the License, or 9 + * (at your option) any later version. 10 + */ 11 + 12 + #ifndef __DT_BINDINGS_CLOCK_R8A7779_H__ 13 + #define __DT_BINDINGS_CLOCK_R8A7779_H__ 14 + 15 + /* CPG */ 16 + #define R8A7779_CLK_PLLA 0 17 + #define R8A7779_CLK_Z 1 18 + #define R8A7779_CLK_ZS 2 19 + #define R8A7779_CLK_S 3 20 + #define R8A7779_CLK_S1 4 21 + #define R8A7779_CLK_P 5 22 + #define R8A7779_CLK_B 6 23 + #define R8A7779_CLK_OUT 7 24 + 25 + /* MSTP 0 */ 26 + #define R8A7779_CLK_HSPI 7 27 + #define R8A7779_CLK_TMU2 14 28 + #define R8A7779_CLK_TMU1 15 29 + #define R8A7779_CLK_TMU0 16 30 + #define R8A7779_CLK_HSCIF1 18 31 + #define R8A7779_CLK_HSCIF0 19 32 + #define R8A7779_CLK_SCIF5 21 33 + #define R8A7779_CLK_SCIF4 22 34 + #define R8A7779_CLK_SCIF3 23 35 + #define R8A7779_CLK_SCIF2 24 36 + #define R8A7779_CLK_SCIF1 25 37 + #define R8A7779_CLK_SCIF0 26 38 + #define R8A7779_CLK_I2C3 27 39 + #define R8A7779_CLK_I2C2 28 40 + #define R8A7779_CLK_I2C1 29 41 + #define R8A7779_CLK_I2C0 30 42 + 43 + /* MSTP 1 */ 44 + #define R8A7779_CLK_USB01 0 45 + #define R8A7779_CLK_USB2 1 46 + #define R8A7779_CLK_DU 3 47 + #define R8A7779_CLK_VIN2 8 48 + #define R8A7779_CLK_VIN1 9 49 + #define R8A7779_CLK_VIN0 10 50 + #define R8A7779_CLK_ETHER 14 51 + #define R8A7779_CLK_SATA 15 52 + #define R8A7779_CLK_PCIE 16 53 + #define R8A7779_CLK_VIN3 20 54 + 55 + /* MSTP 3 */ 56 + #define R8A7779_CLK_SDHI3 20 57 + #define R8A7779_CLK_SDHI2 21 58 + #define R8A7779_CLK_SDHI1 22 59 + #define R8A7779_CLK_SDHI0 23 60 + #define R8A7779_CLK_MMC1 30 61 + #define R8A7779_CLK_MMC0 31 62 + 63 + 64 + #endif /* __DT_BINDINGS_CLOCK_R8A7779_H__ */
+2 -1
include/dt-bindings/clock/tegra114-car.h
··· 337 337 #define TEGRA114_CLK_CLK_OUT_3_MUX 308 338 338 #define TEGRA114_CLK_DSIA_MUX 309 339 339 #define TEGRA114_CLK_DSIB_MUX 310 340 - #define TEGRA114_CLK_CLK_MAX 311 340 + #define TEGRA114_CLK_XUSB_SS_DIV2 311 341 + #define TEGRA114_CLK_CLK_MAX 312 341 342 342 343 #endif /* _DT_BINDINGS_CLOCK_TEGRA114_CAR_H */
+2 -1
include/dt-bindings/clock/tegra124-car.h
··· 336 336 #define TEGRA124_CLK_DSIA_MUX 309 337 337 #define TEGRA124_CLK_DSIB_MUX 310 338 338 #define TEGRA124_CLK_SOR0_LVDS 311 339 - #define TEGRA124_CLK_CLK_MAX 312 339 + #define TEGRA124_CLK_XUSB_SS_DIV2 312 340 + #define TEGRA124_CLK_CLK_MAX 313 340 341 341 342 #endif /* _DT_BINDINGS_CLOCK_TEGRA124_CAR_H */
+1 -1
include/dt-bindings/reset/qcom,gcc-msm8960.h
··· 58 58 #define PPSS_PROC_RESET 41 59 59 #define PPSS_RESET 42 60 60 #define DMA_BAM_RESET 43 61 - #define SIC_TIC_RESET 44 61 + #define SPS_TIC_H_RESET 44 62 62 #define SLIMBUS_H_RESET 45 63 63 #define SFAB_CFPB_M_RESET 46 64 64 #define SFAB_CFPB_S_RESET 47
+70 -57
include/linux/clk-provider.h
··· 40 40 * through the clk_* api. 41 41 * 42 42 * @prepare: Prepare the clock for enabling. This must not return until 43 - * the clock is fully prepared, and it's safe to call clk_enable. 44 - * This callback is intended to allow clock implementations to 45 - * do any initialisation that may sleep. Called with 46 - * prepare_lock held. 43 + * the clock is fully prepared, and it's safe to call clk_enable. 44 + * This callback is intended to allow clock implementations to 45 + * do any initialisation that may sleep. Called with 46 + * prepare_lock held. 47 47 * 48 48 * @unprepare: Release the clock from its prepared state. This will typically 49 - * undo any work done in the @prepare callback. Called with 50 - * prepare_lock held. 49 + * undo any work done in the @prepare callback. Called with 50 + * prepare_lock held. 51 51 * 52 52 * @is_prepared: Queries the hardware to determine if the clock is prepared. 53 53 * This function is allowed to sleep. Optional, if this op is not ··· 58 58 * Called with prepare mutex held. This function may sleep. 59 59 * 60 60 * @enable: Enable the clock atomically. This must not return until the 61 - * clock is generating a valid clock signal, usable by consumer 62 - * devices. Called with enable_lock held. This function must not 63 - * sleep. 61 + * clock is generating a valid clock signal, usable by consumer 62 + * devices. Called with enable_lock held. This function must not 63 + * sleep. 64 64 * 65 65 * @disable: Disable the clock atomically. Called with enable_lock held. 66 - * This function must not sleep. 66 + * This function must not sleep. 67 67 * 68 68 * @is_enabled: Queries the hardware to determine if the clock is enabled. 69 - * This function must not sleep. Optional, if this op is not 70 - * set then the enable count will be used. 69 + * This function must not sleep. Optional, if this op is not 70 + * set then the enable count will be used. 71 71 * 72 72 * @disable_unused: Disable the clock atomically. Only called from 73 73 * clk_disable_unused for gate clocks with special needs. ··· 75 75 * sleep. 76 76 * 77 77 * @recalc_rate Recalculate the rate of this clock, by querying hardware. The 78 - * parent rate is an input parameter. It is up to the caller to 79 - * ensure that the prepare_mutex is held across this call. 80 - * Returns the calculated rate. Optional, but recommended - if 81 - * this op is not set then clock rate will be initialized to 0. 78 + * parent rate is an input parameter. It is up to the caller to 79 + * ensure that the prepare_mutex is held across this call. 80 + * Returns the calculated rate. Optional, but recommended - if 81 + * this op is not set then clock rate will be initialized to 0. 82 82 * 83 83 * @round_rate: Given a target rate as input, returns the closest rate actually 84 - * supported by the clock. 84 + * supported by the clock. The parent rate is an input/output 85 + * parameter. 85 86 * 86 87 * @determine_rate: Given a target rate as input, returns the closest rate 87 88 * actually supported by the clock, and optionally the parent clock 88 89 * that should be used to provide the clock rate. 89 90 * 90 - * @get_parent: Queries the hardware to determine the parent of a clock. The 91 - * return value is a u8 which specifies the index corresponding to 92 - * the parent clock. This index can be applied to either the 93 - * .parent_names or .parents arrays. In short, this function 94 - * translates the parent value read from hardware into an array 95 - * index. Currently only called when the clock is initialized by 96 - * __clk_init. This callback is mandatory for clocks with 97 - * multiple parents. It is optional (and unnecessary) for clocks 98 - * with 0 or 1 parents. 99 - * 100 91 * @set_parent: Change the input source of this clock; for clocks with multiple 101 - * possible parents specify a new parent by passing in the index 102 - * as a u8 corresponding to the parent in either the .parent_names 103 - * or .parents arrays. This function in affect translates an 104 - * array index into the value programmed into the hardware. 105 - * Returns 0 on success, -EERROR otherwise. 92 + * possible parents specify a new parent by passing in the index 93 + * as a u8 corresponding to the parent in either the .parent_names 94 + * or .parents arrays. This function in affect translates an 95 + * array index into the value programmed into the hardware. 96 + * Returns 0 on success, -EERROR otherwise. 97 + * 98 + * @get_parent: Queries the hardware to determine the parent of a clock. The 99 + * return value is a u8 which specifies the index corresponding to 100 + * the parent clock. This index can be applied to either the 101 + * .parent_names or .parents arrays. In short, this function 102 + * translates the parent value read from hardware into an array 103 + * index. Currently only called when the clock is initialized by 104 + * __clk_init. This callback is mandatory for clocks with 105 + * multiple parents. It is optional (and unnecessary) for clocks 106 + * with 0 or 1 parents. 106 107 * 107 108 * @set_rate: Change the rate of this clock. The requested rate is specified 108 109 * by the second argument, which should typically be the return 109 110 * of .round_rate call. The third argument gives the parent rate 110 111 * which is likely helpful for most .set_rate implementation. 111 112 * Returns 0 on success, -EERROR otherwise. 112 - * 113 - * @recalc_accuracy: Recalculate the accuracy of this clock. The clock accuracy 114 - * is expressed in ppb (parts per billion). The parent accuracy is 115 - * an input parameter. 116 - * Returns the calculated accuracy. Optional - if this op is not 117 - * set then clock accuracy will be initialized to parent accuracy 118 - * or 0 (perfect clock) if clock has no parent. 119 113 * 120 114 * @set_rate_and_parent: Change the rate and the parent of this clock. The 121 115 * requested rate is specified by the second argument, which ··· 121 127 * for clocks that can tolerate switching the rate and the parent 122 128 * separately via calls to .set_parent and .set_rate. 123 129 * Returns 0 on success, -EERROR otherwise. 130 + * 131 + * @recalc_accuracy: Recalculate the accuracy of this clock. The clock accuracy 132 + * is expressed in ppb (parts per billion). The parent accuracy is 133 + * an input parameter. 134 + * Returns the calculated accuracy. Optional - if this op is not 135 + * set then clock accuracy will be initialized to parent accuracy 136 + * or 0 (perfect clock) if clock has no parent. 137 + * 138 + * @init: Perform platform-specific initialization magic. 139 + * This is not not used by any of the basic clock types. 140 + * Please consider other ways of solving initialization problems 141 + * before using this callback, as its use is discouraged. 124 142 * 125 143 * @debug_init: Set up type-specific debugfs entries for this clock. This 126 144 * is called once, after the debugfs directory entry for this ··· 163 157 void (*disable_unused)(struct clk_hw *hw); 164 158 unsigned long (*recalc_rate)(struct clk_hw *hw, 165 159 unsigned long parent_rate); 166 - long (*round_rate)(struct clk_hw *hw, unsigned long, 167 - unsigned long *); 160 + long (*round_rate)(struct clk_hw *hw, unsigned long rate, 161 + unsigned long *parent_rate); 168 162 long (*determine_rate)(struct clk_hw *hw, unsigned long rate, 169 163 unsigned long *best_parent_rate, 170 164 struct clk **best_parent_clk); 171 165 int (*set_parent)(struct clk_hw *hw, u8 index); 172 166 u8 (*get_parent)(struct clk_hw *hw); 173 - int (*set_rate)(struct clk_hw *hw, unsigned long, 174 - unsigned long); 167 + int (*set_rate)(struct clk_hw *hw, unsigned long rate, 168 + unsigned long parent_rate); 175 169 int (*set_rate_and_parent)(struct clk_hw *hw, 176 170 unsigned long rate, 177 171 unsigned long parent_rate, u8 index); ··· 260 254 * 261 255 * Flags: 262 256 * CLK_GATE_SET_TO_DISABLE - by default this clock sets the bit at bit_idx to 263 - * enable the clock. Setting this flag does the opposite: setting the bit 264 - * disable the clock and clearing it enables the clock 257 + * enable the clock. Setting this flag does the opposite: setting the bit 258 + * disable the clock and clearing it enables the clock 265 259 * CLK_GATE_HIWORD_MASK - The gate settings are only in lower 16-bit 266 - * of this register, and mask of gate bits are in higher 16-bit of this 267 - * register. While setting the gate bits, higher 16-bit should also be 268 - * updated to indicate changing gate bits. 260 + * of this register, and mask of gate bits are in higher 16-bit of this 261 + * register. While setting the gate bits, higher 16-bit should also be 262 + * updated to indicate changing gate bits. 269 263 */ 270 264 struct clk_gate { 271 265 struct clk_hw hw; ··· 304 298 * 305 299 * Flags: 306 300 * CLK_DIVIDER_ONE_BASED - by default the divisor is the value read from the 307 - * register plus one. If CLK_DIVIDER_ONE_BASED is set then the divider is 308 - * the raw value read from the register, with the value of zero considered 301 + * register plus one. If CLK_DIVIDER_ONE_BASED is set then the divider is 302 + * the raw value read from the register, with the value of zero considered 309 303 * invalid, unless CLK_DIVIDER_ALLOW_ZERO is set. 310 304 * CLK_DIVIDER_POWER_OF_TWO - clock divisor is 2 raised to the value read from 311 - * the hardware register 305 + * the hardware register 312 306 * CLK_DIVIDER_ALLOW_ZERO - Allow zero divisors. For dividers which have 313 307 * CLK_DIVIDER_ONE_BASED set, it is possible to end up with a zero divisor. 314 308 * Some hardware implementations gracefully handle this case and allow a 315 309 * zero divisor by not modifying their input clock 316 310 * (divide by one / bypass). 317 311 * CLK_DIVIDER_HIWORD_MASK - The divider settings are only in lower 16-bit 318 - * of this register, and mask of divider bits are in higher 16-bit of this 319 - * register. While setting the divider bits, higher 16-bit should also be 320 - * updated to indicate changing divider bits. 312 + * of this register, and mask of divider bits are in higher 16-bit of this 313 + * register. While setting the divider bits, higher 16-bit should also be 314 + * updated to indicate changing divider bits. 315 + * CLK_DIVIDER_ROUND_CLOSEST - Makes the best calculated divider to be rounded 316 + * to the closest integer instead of the up one. 317 + * CLK_DIVIDER_READ_ONLY - The divider settings are preconfigured and should 318 + * not be changed by the clock framework. 321 319 */ 322 320 struct clk_divider { 323 321 struct clk_hw hw; ··· 337 327 #define CLK_DIVIDER_POWER_OF_TWO BIT(1) 338 328 #define CLK_DIVIDER_ALLOW_ZERO BIT(2) 339 329 #define CLK_DIVIDER_HIWORD_MASK BIT(3) 330 + #define CLK_DIVIDER_ROUND_CLOSEST BIT(4) 331 + #define CLK_DIVIDER_READ_ONLY BIT(5) 340 332 341 333 extern const struct clk_ops clk_divider_ops; 334 + extern const struct clk_ops clk_divider_ro_ops; 342 335 struct clk *clk_register_divider(struct device *dev, const char *name, 343 336 const char *parent_name, unsigned long flags, 344 337 void __iomem *reg, u8 shift, u8 width, ··· 369 356 * CLK_MUX_INDEX_ONE - register index starts at 1, not 0 370 357 * CLK_MUX_INDEX_BIT - register index is a single bit (power of two) 371 358 * CLK_MUX_HIWORD_MASK - The mux settings are only in lower 16-bit of this 372 - * register, and mask of mux bits are in higher 16-bit of this register. 373 - * While setting the mux bits, higher 16-bit should also be updated to 374 - * indicate changing mux bits. 359 + * register, and mask of mux bits are in higher 16-bit of this register. 360 + * While setting the mux bits, higher 16-bit should also be updated to 361 + * indicate changing mux bits. 375 362 */ 376 363 struct clk_mux { 377 364 struct clk_hw hw;
+3
include/linux/clk/shmobile.h
··· 1 1 /* 2 2 * Copyright 2013 Ideas On Board SPRL 3 + * Copyright 2013, 2014 Horms Solutions Ltd. 3 4 * 4 5 * Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com> 6 + * Contact: Simon Horman <horms@verge.net.au> 5 7 * 6 8 * This program is free software; you can redistribute it and/or modify 7 9 * it under the terms of the GNU General Public License as published by ··· 16 14 17 15 #include <linux/types.h> 18 16 17 + void r8a7779_clocks_init(u32 mode); 19 18 void rcar_gen2_clocks_init(u32 mode); 20 19 21 20 #endif
+22
include/linux/clk/sunxi.h
··· 1 + /* 2 + * Copyright 2013 - Hans de Goede <hdegoede@redhat.com> 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License as published by 6 + * the Free Software Foundation; either version 2 of the License, or 7 + * (at your option) any later version. 8 + * 9 + * This program is distributed in the hope that it will be useful, 10 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 + * GNU General Public License for more details. 13 + */ 14 + 15 + #ifndef __LINUX_CLK_SUNXI_H_ 16 + #define __LINUX_CLK_SUNXI_H_ 17 + 18 + #include <linux/clk.h> 19 + 20 + void clk_sunxi_mmc_phase_control(struct clk *clk, u8 sample, u8 output); 21 + 22 + #endif