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.18' of git://git.linaro.org/people/mike.turquette/linux

Pull clock tree updates from Mike Turquette:
"The clk tree changes for 3.18 are dominated by clock drivers. Mostly
fixes and enhancements to existing drivers as well as new drivers.
This tag contains a bit more arch code than I usually take due to some
OMAP2+ changes. Additionally it contains the restart notifier
handlers which are merged as a dependency into several trees.

The PXA changes are the only messy part. Due to having a stable tree
I had to revert one patch and follow up with one more fix near the tip
of this tag. Some dead code is introduced but it will soon become
live code after 3.18-rc1 is released as the rest of the PXA family is
converted over to the common clock framework.

Another trend in this tag is that multiple vendors have started to
push the complexity of changing their CPU frequency into the clock
driver, whereas this used to be done in CPUfreq drivers.

Changes to the clk core include a generic gpio-clock type and a
clk_set_phase() function added to the top-level clk.h api. Due to
some confusion on the fbdev mailing list the kernel boot parameters
documentation was updated to further explain the clk_ignore_unused
parameter, which is often required by users of the simplefb driver.

Finally some fixes to the locking around the clock debugfs stuff was
done to prevent deadlocks when interacting with other subsystems."

* tag 'clk-for-linus-3.18' of git://git.linaro.org/people/mike.turquette/linux: (99 commits)
clk: pxa clocks build system fix
Revert "arm: pxa: Transition pxa27x to clk framework"
clk: samsung: register restart handlers for s3c2412 and s3c2443
clk: rockchip: add restart handler
clk: rockchip: rk3288: i2s_frac adds flag to set parent's rate
doc/kernel-parameters.txt: clarify clk_ignore_unused
arm: pxa: Transition pxa27x to clk framework
dts: add devicetree bindings for pxa27x clocks
clk: add pxa27x clock drivers
arm: pxa: add clock pll selection bits
clk: dts: document pxa clock binding
clk: add pxa clocks infrastructure
clk: gpio-gate: Ensure gpiod_ APIs are prototyped
clk: ti: dra7-atl-clock: Mark the device as pm_runtime_irq_safe
clk: ti: LLVMLinux: Move __init outside of type definition
clk: ti: consider the fact that of_clk_get() might return an error
clk: ti: dra7-atl-clock: fix a memory leak
clk: ti: change clock init to use generic of_clk_init
clk: hix5hd2: add I2C clocks
clk: hix5hd2: add watchdog0 clocks
...

+4138 -802
+9 -1
Documentation/devicetree/bindings/clock/exynos3250-clock.txt
··· 7 7 8 8 - compatible: should be one of the following. 9 9 - "samsung,exynos3250-cmu" - controller compatible with Exynos3250 SoC. 10 + - "samsung,exynos3250-cmu-dmc" - controller compatible with 11 + Exynos3250 SoC for Dynamic Memory Controller domain. 10 12 11 13 - reg: physical base address of the controller and length of memory mapped 12 14 region. ··· 22 20 dt-bindings/clock/exynos3250.h header and can be used in device 23 21 tree sources. 24 22 25 - Example 1: An example of a clock controller node is listed below. 23 + Example 1: Examples of clock controller nodes are listed below. 26 24 27 25 cmu: clock-controller@10030000 { 28 26 compatible = "samsung,exynos3250-cmu"; 29 27 reg = <0x10030000 0x20000>; 28 + #clock-cells = <1>; 29 + }; 30 + 31 + cmu_dmc: clock-controller@105C0000 { 32 + compatible = "samsung,exynos3250-cmu-dmc"; 33 + reg = <0x105C0000 0x2000>; 30 34 #clock-cells = <1>; 31 35 }; 32 36
+21
Documentation/devicetree/bindings/clock/gpio-gate-clock.txt
··· 1 + Binding for simple gpio gated clock. 2 + 3 + This binding uses the common clock binding[1]. 4 + 5 + [1] Documentation/devicetree/bindings/clock/clock-bindings.txt 6 + 7 + Required properties: 8 + - compatible : shall be "gpio-gate-clock". 9 + - #clock-cells : from common clock binding; shall be set to 0. 10 + - enable-gpios : GPIO reference for enabling and disabling the clock. 11 + 12 + Optional properties: 13 + - clocks: Maximum of one parent clock is supported. 14 + 15 + Example: 16 + clock { 17 + compatible = "gpio-gate-clock"; 18 + clocks = <&parentclk>; 19 + #clock-cells = <0>; 20 + enable-gpios = <&gpio 1 GPIO_ACTIVE_HIGH>; 21 + };
+12 -4
Documentation/devicetree/bindings/clock/maxim,max77686.txt
··· 9 9 Following properties should be presend in main device node of the MFD chip. 10 10 11 11 Required properties: 12 - - #clock-cells: simple one-cell clock specifier format is used, where the 13 - only cell is used as an index of the clock inside the provider. Following 14 - indices are allowed: 12 + 13 + - #clock-cells: from common clock binding; shall be set to 1. 14 + 15 + Optional properties: 16 + - clock-output-names: From common clock binding. 17 + 18 + Each clock is assigned an identifier and client nodes can use this identifier 19 + to specify the clock which they consume. Following indices are allowed: 15 20 - 0: 32khz_ap clock, 16 21 - 1: 32khz_cp clock, 17 22 - 2: 32khz_pmic clock. 23 + 24 + Clocks are defined as preprocessor macros in dt-bindings/clock/maxim,max77686.h 25 + header and can be used in device tree sources. 18 26 19 27 Example: Node of the MFD chip 20 28 ··· 42 34 compatible = "bar,foo"; 43 35 /* ... */ 44 36 clock-names = "my-clock"; 45 - clocks = <&max77686 2>; 37 + clocks = <&max77686 MAX77686_CLK_PMIC>; 46 38 };
+44
Documentation/devicetree/bindings/clock/maxim,max77802.txt
··· 1 + Binding for Maxim MAX77802 32k clock generator block 2 + 3 + This is a part of device tree bindings of MAX77802 multi-function device. 4 + More information can be found in bindings/mfd/max77802.txt file. 5 + 6 + The MAX77802 contains two 32.768khz clock outputs that can be controlled 7 + (gated/ungated) over I2C. 8 + 9 + Following properties should be present in main device node of the MFD chip. 10 + 11 + Required properties: 12 + - #clock-cells: From common clock binding; shall be set to 1. 13 + 14 + Optional properties: 15 + - clock-output-names: From common clock binding. 16 + 17 + Each clock is assigned an identifier and client nodes can use this identifier 18 + to specify the clock which they consume. Following indices are allowed: 19 + - 0: 32khz_ap clock, 20 + - 1: 32khz_cp clock. 21 + 22 + Clocks are defined as preprocessor macros in dt-bindings/clock/maxim,max77802.h 23 + header and can be used in device tree sources. 24 + 25 + Example: Node of the MFD chip 26 + 27 + max77802: max77802@09 { 28 + compatible = "maxim,max77802"; 29 + interrupt-parent = <&wakeup_eint>; 30 + interrupts = <26 0>; 31 + reg = <0x09>; 32 + #clock-cells = <1>; 33 + 34 + /* ... */ 35 + }; 36 + 37 + Example: Clock consumer node 38 + 39 + foo@0 { 40 + compatible = "bar,foo"; 41 + /* ... */ 42 + clock-names = "my-clock"; 43 + clocks = <&max77802 MAX77802_CLK_32K_AP>; 44 + };
+16
Documentation/devicetree/bindings/clock/pxa-clock.txt
··· 1 + * Clock bindings for Marvell PXA chips 2 + 3 + Required properties: 4 + - compatible: Should be "marvell,pxa-clocks" 5 + - #clock-cells: Should be <1> 6 + 7 + The clock consumer should specify the desired clock by having the clock 8 + ID in its "clocks" phandle cell (see include/.../pxa-clock.h). 9 + 10 + Examples: 11 + 12 + pxa2xx_clks: pxa2xx_clks@41300004 { 13 + compatible = "marvell,pxa-clocks"; 14 + #clock-cells = <1>; 15 + status = "okay"; 16 + };
+1
Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
··· 15 15 - "renesas,r8a7779-mstp-clocks" for R8A7779 (R-Car H1) MSTP gate clocks 16 16 - "renesas,r8a7790-mstp-clocks" for R8A7790 (R-Car H2) MSTP gate clocks 17 17 - "renesas,r8a7791-mstp-clocks" for R8A7791 (R-Car M2) MSTP gate clocks 18 + - "renesas,r8a7794-mstp-clocks" for R8A7794 (R-Car E2) MSTP gate clocks 18 19 - "renesas,sh73a0-mstp-clocks" for SH73A0 (SH-MobileAG5) MSTP gate clocks 19 20 - "renesas,cpg-mstp-clock" for generic MSTP gate clocks 20 21 - reg: Base address and length of the I/O mapped registers used by the MSTP
+1
Documentation/devicetree/bindings/clock/renesas,rcar-gen2-cpg-clocks.txt
··· 8 8 - compatible: Must be one of 9 9 - "renesas,r8a7790-cpg-clocks" for the r8a7790 CPG 10 10 - "renesas,r8a7791-cpg-clocks" for the r8a7791 CPG 11 + - "renesas,r8a7794-cpg-clocks" for the r8a7794 CPG 11 12 - "renesas,rcar-gen2-cpg-clocks" for the generic R-Car Gen2 CPG 12 13 13 14 - reg: Base address and length of the memory resource used by the CPG
+4
Documentation/devicetree/bindings/clock/sunxi.txt
··· 46 46 "allwinner,sun6i-a31-apb2-div-clk" - for the APB2 gates on A31 47 47 "allwinner,sun6i-a31-apb2-gates-clk" - for the APB2 gates on A31 48 48 "allwinner,sun8i-a23-apb2-gates-clk" - for the APB2 gates on A23 49 + "allwinner,sun5i-a13-mbus-clk" - for the MBUS clock on A13 50 + "allwinner,sun4i-a10-mmc-output-clk" - for the MMC output clock on A10 51 + "allwinner,sun4i-a10-mmc-sample-clk" - for the MMC sample clock on A10 49 52 "allwinner,sun4i-a10-mod0-clk" - for the module 0 family of clocks 53 + "allwinner,sun8i-a23-mbus-clk" - for the MBUS clock on A23 50 54 "allwinner,sun7i-a20-out-clk" - for the external output clocks 51 55 "allwinner,sun7i-a20-gmac-clk" - for the GMAC clock module on A20/A31 52 56 "allwinner,sun4i-a10-usb-clk" - for usb gates + resets on A10 / A20
+9 -5
Documentation/kernel-parameters.txt
··· 605 605 See Documentation/s390/CommonIO for details. 606 606 clk_ignore_unused 607 607 [CLK] 608 - Keep all clocks already enabled by bootloader on, 609 - even if no driver has claimed them. This is useful 610 - for debug and development, but should not be 611 - needed on a platform with proper driver support. 612 - For more information, see Documentation/clk.txt. 608 + Prevents the clock framework from automatically gating 609 + clocks that have not been explicitly enabled by a Linux 610 + device driver but are enabled in hardware at reset or 611 + by the bootloader/firmware. Note that this does not 612 + force such clocks to be always-on nor does it reserve 613 + those clocks in any way. This parameter is useful for 614 + debug and development, but should not be needed on a 615 + platform with proper driver support. For more 616 + information, see Documentation/clk.txt. 613 617 614 618 clock= [BUGS=X86-32, HW] gettimeofday clocksource override. 615 619 [Deprecated]
+6
arch/arm/boot/dts/exynos3250.dtsi
··· 169 169 #clock-cells = <1>; 170 170 }; 171 171 172 + cmu_dmc: clock-controller@105C0000 { 173 + compatible = "samsung,exynos3250-cmu-dmc"; 174 + reg = <0x105C0000 0x2000>; 175 + #clock-cells = <1>; 176 + }; 177 + 172 178 rtc: rtc@10070000 { 173 179 compatible = "samsung,exynos3250-rtc"; 174 180 reg = <0x10070000 0x100>;
+19 -1
arch/arm/boot/dts/pxa27x.dtsi
··· 1 1 /* The pxa3xx skeleton simply augments the 2xx version */ 2 - /include/ "pxa2xx.dtsi" 2 + #include "pxa2xx.dtsi" 3 + #include "dt-bindings/clock/pxa2xx-clock.h" 3 4 4 5 / { 5 6 model = "Marvell PXA27x familiy SoC"; ··· 36 35 #pwm-cells = <1>; 37 36 }; 38 37 }; 38 + 39 + clocks { 40 + /* 41 + * The muxing of external clocks/internal dividers for osc* clock 42 + * sources has been hidden under the carpet by now. 43 + */ 44 + #address-cells = <1>; 45 + #size-cells = <1>; 46 + ranges; 47 + 48 + pxa2xx_clks: pxa2xx_clks@41300004 { 49 + compatible = "marvell,pxa-clocks"; 50 + #clock-cells = <1>; 51 + status = "okay"; 52 + }; 53 + }; 54 + 39 55 };
+1 -1
arch/arm/boot/dts/sun5i-a10s.dtsi
··· 287 287 288 288 mbus_clk: clk@01c2015c { 289 289 #clock-cells = <0>; 290 - compatible = "allwinner,sun4i-a10-mod0-clk"; 290 + compatible = "allwinner,sun5i-a13-mbus-clk"; 291 291 reg = <0x01c2015c 0x4>; 292 292 clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; 293 293 clock-output-names = "mbus";
+1 -1
arch/arm/boot/dts/sun5i-a13.dtsi
··· 285 285 286 286 mbus_clk: clk@01c2015c { 287 287 #clock-cells = <0>; 288 - compatible = "allwinner,sun4i-a10-mod0-clk"; 288 + compatible = "allwinner,sun5i-a13-mbus-clk"; 289 289 reg = <0x01c2015c 0x4>; 290 290 clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; 291 291 clock-output-names = "mbus";
+1 -1
arch/arm/boot/dts/sun7i-a20.dtsi
··· 382 382 383 383 mbus_clk: clk@01c2015c { 384 384 #clock-cells = <0>; 385 - compatible = "allwinner,sun4i-a10-mod0-clk"; 385 + compatible = "allwinner,sun5i-a13-mbus-clk"; 386 386 reg = <0x01c2015c 0x4>; 387 387 clocks = <&osc24M>, <&pll6 2>, <&pll5 1>; 388 388 clock-output-names = "mbus";
+10 -2
arch/arm/mach-omap2/io.c
··· 723 723 ti_clk_init_features(); 724 724 725 725 ret = of_prcm_init(); 726 - if (!ret) 727 - ret = omap_clk_soc_init(); 726 + if (ret) 727 + return ret; 728 + 729 + of_clk_init(NULL); 730 + 731 + ti_dt_clk_init_retry_clks(); 732 + 733 + ti_dt_clockdomains_setup(); 734 + 735 + ret = omap_clk_soc_init(); 728 736 729 737 return ret; 730 738 }
-2
arch/arm/mach-omap2/prm_common.c
··· 525 525 memmap_index++; 526 526 } 527 527 528 - ti_dt_clockdomains_setup(); 529 - 530 528 return 0; 531 529 } 532 530
+10
arch/arm/mach-pxa/include/mach/pxa2xx-regs.h
··· 143 143 #define CCCR_M_MASK 0x0060 /* Memory Frequency to Run Mode Frequency Multiplier */ 144 144 #define CCCR_L_MASK 0x001f /* Crystal Frequency to Memory Frequency Multiplier */ 145 145 146 + #define CCCR_CPDIS_BIT (31) 147 + #define CCCR_PPDIS_BIT (30) 148 + #define CCCR_LCD_26_BIT (27) 149 + #define CCCR_A_BIT (25) 150 + 151 + #define CCSR_N2_MASK CCCR_N_MASK 152 + #define CCSR_M_MASK CCCR_M_MASK 153 + #define CCSR_L_MASK CCCR_L_MASK 154 + #define CCSR_N2_SHIFT 7 155 + 146 156 #define CKEN_AC97CONF (31) /* AC97 Controller Configuration */ 147 157 #define CKEN_CAMERA (24) /* Camera Interface Clock Enable */ 148 158 #define CKEN_SSP1 (23) /* SSP1 Unit Clock Enable */
+16
drivers/clk/Kconfig
··· 32 32 33 33 source "drivers/clk/versatile/Kconfig" 34 34 35 + config COMMON_CLK_MAX_GEN 36 + bool 37 + 35 38 config COMMON_CLK_MAX77686 36 39 tristate "Clock driver for Maxim 77686 MFD" 37 40 depends on MFD_MAX77686 41 + select COMMON_CLK_MAX_GEN 38 42 ---help--- 39 43 This driver supports Maxim 77686 crystal oscillator clock. 44 + 45 + config COMMON_CLK_MAX77802 46 + tristate "Clock driver for Maxim 77802 PMIC" 47 + depends on MFD_MAX77686 48 + select COMMON_CLK_MAX_GEN 49 + ---help--- 50 + This driver supports Maxim 77802 crystal oscillator clock. 40 51 41 52 config COMMON_CLK_RK808 42 53 tristate "Clock driver for RK808" ··· 128 117 ---help--- 129 118 This driver supports TI Palmas devices 32KHz output KG and KG_AUDIO 130 119 using common clock framework. 120 + 121 + config COMMON_CLK_PXA 122 + def_bool COMMON_CLK && ARCH_PXA 123 + ---help--- 124 + Sypport for the Marvell PXA SoC. 131 125 132 126 source "drivers/clk/qcom/Kconfig" 133 127
+4
drivers/clk/Makefile
··· 9 9 obj-$(CONFIG_COMMON_CLK) += clk-mux.o 10 10 obj-$(CONFIG_COMMON_CLK) += clk-composite.o 11 11 obj-$(CONFIG_COMMON_CLK) += clk-fractional-divider.o 12 + obj-$(CONFIG_COMMON_CLK) += clk-gpio-gate.o 12 13 ifeq ($(CONFIG_OF), y) 13 14 obj-$(CONFIG_COMMON_CLK) += clk-conf.o 14 15 endif ··· 23 22 obj-$(CONFIG_ARCH_EFM32) += clk-efm32gg.o 24 23 obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o 25 24 obj-$(CONFIG_MACH_LOONGSON1) += clk-ls1x.o 25 + obj-$(CONFIG_COMMON_CLK_MAX_GEN) += clk-max-gen.o 26 26 obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o 27 + obj-$(CONFIG_COMMON_CLK_MAX77802) += clk-max77802.o 27 28 obj-$(CONFIG_ARCH_MOXART) += clk-moxart.o 28 29 obj-$(CONFIG_ARCH_NOMADIK) += clk-nomadik.o 29 30 obj-$(CONFIG_ARCH_NSPIRE) += clk-nspire.o ··· 52 49 endif 53 50 obj-$(CONFIG_PLAT_ORION) += mvebu/ 54 51 obj-$(CONFIG_ARCH_MXS) += mxs/ 52 + obj-$(CONFIG_COMMON_CLK_PXA) += pxa/ 55 53 obj-$(CONFIG_COMMON_CLK_QCOM) += qcom/ 56 54 obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/ 57 55 obj-$(CONFIG_COMMON_CLK_SAMSUNG) += samsung/
+83 -81
drivers/clk/at91/clk-pll.c
··· 15 15 #include <linux/of_address.h> 16 16 #include <linux/of_irq.h> 17 17 #include <linux/io.h> 18 + #include <linux/kernel.h> 18 19 #include <linux/wait.h> 19 20 #include <linux/sched.h> 20 21 #include <linux/interrupt.h> ··· 30 29 #define PLL_DIV(reg) ((reg) & PLL_DIV_MASK) 31 30 #define PLL_MUL(reg, layout) (((reg) >> (layout)->mul_shift) & \ 32 31 (layout)->mul_mask) 32 + #define PLL_MUL_MIN 2 33 + #define PLL_MUL_MASK(layout) ((layout)->mul_mask) 34 + #define PLL_MUL_MAX(layout) (PLL_MUL_MASK(layout) + 1) 33 35 #define PLL_ICPR_SHIFT(id) ((id) * 16) 34 36 #define PLL_ICPR_MASK(id) (0xffff << PLL_ICPR_SHIFT(id)) 35 - #define PLL_MAX_COUNT 0x3ff 37 + #define PLL_MAX_COUNT 0x3f 36 38 #define PLL_COUNT_SHIFT 8 37 39 #define PLL_OUT_SHIFT 14 38 40 #define PLL_MAX_ID 1 ··· 151 147 unsigned long parent_rate) 152 148 { 153 149 struct clk_pll *pll = to_clk_pll(hw); 154 - const struct clk_pll_layout *layout = pll->layout; 155 - struct at91_pmc *pmc = pll->pmc; 156 - int offset = PLL_REG(pll->id); 157 - u32 tmp = pmc_read(pmc, offset) & layout->pllr_mask; 158 - u8 div = PLL_DIV(tmp); 159 - u16 mul = PLL_MUL(tmp, layout); 160 - if (!div || !mul) 150 + 151 + if (!pll->div || !pll->mul) 161 152 return 0; 162 153 163 - return (parent_rate * (mul + 1)) / div; 154 + return (parent_rate / pll->div) * (pll->mul + 1); 164 155 } 165 156 166 157 static long clk_pll_get_best_div_mul(struct clk_pll *pll, unsigned long rate, 167 158 unsigned long parent_rate, 168 159 u32 *div, u32 *mul, 169 160 u32 *index) { 170 - unsigned long maxrate; 171 - unsigned long minrate; 172 - unsigned long divrate; 173 - unsigned long bestdiv = 1; 174 - unsigned long bestmul; 175 - unsigned long tmpdiv; 176 - unsigned long roundup; 177 - unsigned long rounddown; 178 - unsigned long remainder; 179 - unsigned long bestremainder; 180 - unsigned long maxmul; 181 - unsigned long maxdiv; 182 - unsigned long mindiv; 183 - int i = 0; 184 161 const struct clk_pll_layout *layout = pll->layout; 185 162 const struct clk_pll_characteristics *characteristics = 186 163 pll->characteristics; 164 + unsigned long bestremainder = ULONG_MAX; 165 + unsigned long maxdiv, mindiv, tmpdiv; 166 + long bestrate = -ERANGE; 167 + unsigned long bestdiv; 168 + unsigned long bestmul; 169 + int i = 0; 187 170 188 - /* Minimum divider = 1 */ 189 - /* Maximum multiplier = max_mul */ 190 - maxmul = layout->mul_mask + 1; 191 - maxrate = (parent_rate * maxmul) / 1; 192 - 193 - /* Maximum divider = max_div */ 194 - /* Minimum multiplier = 2 */ 195 - maxdiv = PLL_DIV_MAX; 196 - minrate = (parent_rate * 2) / maxdiv; 197 - 171 + /* Check if parent_rate is a valid input rate */ 198 172 if (parent_rate < characteristics->input.min || 199 - parent_rate < characteristics->input.max) 173 + parent_rate > characteristics->input.max) 200 174 return -ERANGE; 201 175 202 - if (parent_rate < minrate || parent_rate > maxrate) 203 - return -ERANGE; 176 + /* 177 + * Calculate minimum divider based on the minimum multiplier, the 178 + * parent_rate and the requested rate. 179 + * Should always be 2 according to the input and output characteristics 180 + * of the PLL blocks. 181 + */ 182 + mindiv = (parent_rate * PLL_MUL_MIN) / rate; 183 + if (!mindiv) 184 + mindiv = 1; 204 185 186 + /* 187 + * Calculate the maximum divider which is limited by PLL register 188 + * layout (limited by the MUL or DIV field size). 189 + */ 190 + maxdiv = DIV_ROUND_UP(parent_rate * PLL_MUL_MAX(layout), rate); 191 + if (maxdiv > PLL_DIV_MAX) 192 + maxdiv = PLL_DIV_MAX; 193 + 194 + /* 195 + * Iterate over the acceptable divider values to find the best 196 + * divider/multiplier pair (the one that generates the closest 197 + * rate to the requested one). 198 + */ 199 + for (tmpdiv = mindiv; tmpdiv <= maxdiv; tmpdiv++) { 200 + unsigned long remainder; 201 + unsigned long tmprate; 202 + unsigned long tmpmul; 203 + 204 + /* 205 + * Calculate the multiplier associated with the current 206 + * divider that provide the closest rate to the requested one. 207 + */ 208 + tmpmul = DIV_ROUND_CLOSEST(rate, parent_rate / tmpdiv); 209 + tmprate = (parent_rate / tmpdiv) * tmpmul; 210 + if (tmprate > rate) 211 + remainder = tmprate - rate; 212 + else 213 + remainder = rate - tmprate; 214 + 215 + /* 216 + * Compare the remainder with the best remainder found until 217 + * now and elect a new best multiplier/divider pair if the 218 + * current remainder is smaller than the best one. 219 + */ 220 + if (remainder < bestremainder) { 221 + bestremainder = remainder; 222 + bestdiv = tmpdiv; 223 + bestmul = tmpmul; 224 + bestrate = tmprate; 225 + } 226 + 227 + /* 228 + * We've found a perfect match! 229 + * Stop searching now and use this multiplier/divider pair. 230 + */ 231 + if (!remainder) 232 + break; 233 + } 234 + 235 + /* We haven't found any multiplier/divider pair => return -ERANGE */ 236 + if (bestrate < 0) 237 + return bestrate; 238 + 239 + /* Check if bestrate is a valid output rate */ 205 240 for (i = 0; i < characteristics->num_output; i++) { 206 - if (parent_rate >= characteristics->output[i].min && 207 - parent_rate <= characteristics->output[i].max) 241 + if (bestrate >= characteristics->output[i].min && 242 + bestrate <= characteristics->output[i].max) 208 243 break; 209 244 } 210 245 211 246 if (i >= characteristics->num_output) 212 247 return -ERANGE; 213 248 214 - bestmul = rate / parent_rate; 215 - rounddown = parent_rate % rate; 216 - roundup = rate - rounddown; 217 - bestremainder = roundup < rounddown ? roundup : rounddown; 218 - 219 - if (!bestremainder) { 220 - if (div) 221 - *div = bestdiv; 222 - if (mul) 223 - *mul = bestmul; 224 - if (index) 225 - *index = i; 226 - return rate; 227 - } 228 - 229 - maxdiv = 255 / (bestmul + 1); 230 - if (parent_rate / maxdiv < characteristics->input.min) 231 - maxdiv = parent_rate / characteristics->input.min; 232 - mindiv = parent_rate / characteristics->input.max; 233 - if (parent_rate % characteristics->input.max) 234 - mindiv++; 235 - 236 - for (tmpdiv = mindiv; tmpdiv < maxdiv; tmpdiv++) { 237 - divrate = parent_rate / tmpdiv; 238 - 239 - rounddown = rate % divrate; 240 - roundup = divrate - rounddown; 241 - remainder = roundup < rounddown ? roundup : rounddown; 242 - 243 - if (remainder < bestremainder) { 244 - bestremainder = remainder; 245 - bestmul = rate / divrate; 246 - bestdiv = tmpdiv; 247 - } 248 - 249 - if (!remainder) 250 - break; 251 - } 252 - 253 - rate = (parent_rate / bestdiv) * bestmul; 254 - 255 249 if (div) 256 250 *div = bestdiv; 257 251 if (mul) 258 - *mul = bestmul; 252 + *mul = bestmul - 1; 259 253 if (index) 260 254 *index = i; 261 255 262 - return rate; 256 + return bestrate; 263 257 } 264 258 265 259 static long clk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
+15 -5
drivers/clk/at91/clk-usb.c
··· 238 238 unsigned long *parent_rate) 239 239 { 240 240 struct at91rm9200_clk_usb *usb = to_at91rm9200_clk_usb(hw); 241 + struct clk *parent = __clk_get_parent(hw->clk); 241 242 unsigned long bestrate = 0; 242 243 int bestdiff = -1; 243 244 unsigned long tmprate; 244 245 int tmpdiff; 245 246 int i = 0; 246 247 247 - for (i = 0; i < 4; i++) { 248 + for (i = 0; i < RM9200_USB_DIV_TAB_SIZE; i++) { 249 + unsigned long tmp_parent_rate; 250 + 248 251 if (!usb->divisors[i]) 249 252 continue; 250 - tmprate = *parent_rate / usb->divisors[i]; 253 + 254 + tmp_parent_rate = rate * usb->divisors[i]; 255 + tmp_parent_rate = __clk_round_rate(parent, tmp_parent_rate); 256 + tmprate = tmp_parent_rate / usb->divisors[i]; 251 257 if (tmprate < rate) 252 258 tmpdiff = rate - tmprate; 253 259 else ··· 262 256 if (bestdiff < 0 || bestdiff > tmpdiff) { 263 257 bestrate = tmprate; 264 258 bestdiff = tmpdiff; 259 + *parent_rate = tmp_parent_rate; 265 260 } 266 261 267 262 if (!bestdiff) ··· 279 272 int i; 280 273 struct at91rm9200_clk_usb *usb = to_at91rm9200_clk_usb(hw); 281 274 struct at91_pmc *pmc = usb->pmc; 282 - unsigned long div = parent_rate / rate; 275 + unsigned long div; 283 276 284 - if (parent_rate % rate) 277 + if (!rate || parent_rate % rate) 285 278 return -EINVAL; 279 + 280 + div = parent_rate / rate; 281 + 286 282 for (i = 0; i < RM9200_USB_DIV_TAB_SIZE; i++) { 287 283 if (usb->divisors[i] == div) { 288 284 tmp = pmc_read(pmc, AT91_CKGR_PLLBR) & ··· 321 311 init.ops = &at91rm9200_usb_ops; 322 312 init.parent_names = &parent_name; 323 313 init.num_parents = 1; 324 - init.flags = 0; 314 + init.flags = CLK_SET_RATE_PARENT; 325 315 326 316 usb->hw.init = &init; 327 317 usb->pmc = pmc;
-1
drivers/clk/clk-axi-clkgen.c
··· 544 544 static struct platform_driver axi_clkgen_driver = { 545 545 .driver = { 546 546 .name = "adi-axi-clkgen", 547 - .owner = THIS_MODULE, 548 547 .of_match_table = axi_clkgen_ids, 549 548 }, 550 549 .probe = axi_clkgen_probe,
+1 -1
drivers/clk/clk-fractional-divider.c
··· 36 36 m = (val & fd->mmask) >> fd->mshift; 37 37 n = (val & fd->nmask) >> fd->nshift; 38 38 39 - ret = parent_rate * m; 39 + ret = (u64)parent_rate * m; 40 40 do_div(ret, n); 41 41 42 42 return ret;
+1 -1
drivers/clk/clk-gate.c
··· 45 45 { 46 46 struct clk_gate *gate = to_clk_gate(hw); 47 47 int set = gate->flags & CLK_GATE_SET_TO_DISABLE ? 1 : 0; 48 - unsigned long flags = 0; 48 + unsigned long uninitialized_var(flags); 49 49 u32 reg; 50 50 51 51 set ^= enable;
+205
drivers/clk/clk-gpio-gate.c
··· 1 + /* 2 + * Copyright (C) 2013 - 2014 Texas Instruments Incorporated - http://www.ti.com 3 + * Author: Jyri Sarha <jsarha@ti.com> 4 + * 5 + * This program is free software; you can redistribute it and/or modify 6 + * it under the terms of the GNU General Public License version 2 as 7 + * published by the Free Software Foundation. 8 + * 9 + * Gpio gated clock implementation 10 + */ 11 + 12 + #include <linux/clk-provider.h> 13 + #include <linux/module.h> 14 + #include <linux/slab.h> 15 + #include <linux/gpio.h> 16 + #include <linux/gpio/consumer.h> 17 + #include <linux/of_gpio.h> 18 + #include <linux/err.h> 19 + #include <linux/device.h> 20 + 21 + /** 22 + * DOC: basic gpio gated clock which can be enabled and disabled 23 + * with gpio output 24 + * Traits of this clock: 25 + * prepare - clk_(un)prepare only ensures parent is (un)prepared 26 + * enable - clk_enable and clk_disable are functional & control gpio 27 + * rate - inherits rate from parent. No clk_set_rate support 28 + * parent - fixed parent. No clk_set_parent support 29 + */ 30 + 31 + #define to_clk_gpio(_hw) container_of(_hw, struct clk_gpio, hw) 32 + 33 + static int clk_gpio_gate_enable(struct clk_hw *hw) 34 + { 35 + struct clk_gpio *clk = to_clk_gpio(hw); 36 + 37 + gpiod_set_value(clk->gpiod, 1); 38 + 39 + return 0; 40 + } 41 + 42 + static void clk_gpio_gate_disable(struct clk_hw *hw) 43 + { 44 + struct clk_gpio *clk = to_clk_gpio(hw); 45 + 46 + gpiod_set_value(clk->gpiod, 0); 47 + } 48 + 49 + static int clk_gpio_gate_is_enabled(struct clk_hw *hw) 50 + { 51 + struct clk_gpio *clk = to_clk_gpio(hw); 52 + 53 + return gpiod_get_value(clk->gpiod); 54 + } 55 + 56 + const struct clk_ops clk_gpio_gate_ops = { 57 + .enable = clk_gpio_gate_enable, 58 + .disable = clk_gpio_gate_disable, 59 + .is_enabled = clk_gpio_gate_is_enabled, 60 + }; 61 + EXPORT_SYMBOL_GPL(clk_gpio_gate_ops); 62 + 63 + /** 64 + * clk_register_gpio - register a gpip clock with the clock framework 65 + * @dev: device that is registering this clock 66 + * @name: name of this clock 67 + * @parent_name: name of this clock's parent 68 + * @gpiod: gpio descriptor to gate this clock 69 + */ 70 + struct clk *clk_register_gpio_gate(struct device *dev, const char *name, 71 + const char *parent_name, struct gpio_desc *gpiod, 72 + unsigned long flags) 73 + { 74 + struct clk_gpio *clk_gpio = NULL; 75 + struct clk *clk = ERR_PTR(-EINVAL); 76 + struct clk_init_data init = { NULL }; 77 + unsigned long gpio_flags; 78 + int err; 79 + 80 + if (gpiod_is_active_low(gpiod)) 81 + gpio_flags = GPIOF_OUT_INIT_HIGH; 82 + else 83 + gpio_flags = GPIOF_OUT_INIT_LOW; 84 + 85 + if (dev) 86 + err = devm_gpio_request_one(dev, desc_to_gpio(gpiod), 87 + gpio_flags, name); 88 + else 89 + err = gpio_request_one(desc_to_gpio(gpiod), gpio_flags, name); 90 + 91 + if (err) { 92 + pr_err("%s: %s: Error requesting clock control gpio %u\n", 93 + __func__, name, desc_to_gpio(gpiod)); 94 + return ERR_PTR(err); 95 + } 96 + 97 + if (dev) 98 + clk_gpio = devm_kzalloc(dev, sizeof(struct clk_gpio), 99 + GFP_KERNEL); 100 + else 101 + clk_gpio = kzalloc(sizeof(struct clk_gpio), GFP_KERNEL); 102 + 103 + if (!clk_gpio) { 104 + clk = ERR_PTR(-ENOMEM); 105 + goto clk_register_gpio_gate_err; 106 + } 107 + 108 + init.name = name; 109 + init.ops = &clk_gpio_gate_ops; 110 + init.flags = flags | CLK_IS_BASIC; 111 + init.parent_names = (parent_name ? &parent_name : NULL); 112 + init.num_parents = (parent_name ? 1 : 0); 113 + 114 + clk_gpio->gpiod = gpiod; 115 + clk_gpio->hw.init = &init; 116 + 117 + clk = clk_register(dev, &clk_gpio->hw); 118 + 119 + if (!IS_ERR(clk)) 120 + return clk; 121 + 122 + if (!dev) 123 + kfree(clk_gpio); 124 + 125 + clk_register_gpio_gate_err: 126 + gpiod_put(gpiod); 127 + 128 + return clk; 129 + } 130 + EXPORT_SYMBOL_GPL(clk_register_gpio_gate); 131 + 132 + #ifdef CONFIG_OF 133 + /** 134 + * The clk_register_gpio_gate has to be delayed, because the EPROBE_DEFER 135 + * can not be handled properly at of_clk_init() call time. 136 + */ 137 + 138 + struct clk_gpio_gate_delayed_register_data { 139 + struct device_node *node; 140 + struct mutex lock; 141 + struct clk *clk; 142 + }; 143 + 144 + static struct clk *of_clk_gpio_gate_delayed_register_get( 145 + struct of_phandle_args *clkspec, 146 + void *_data) 147 + { 148 + struct clk_gpio_gate_delayed_register_data *data = _data; 149 + struct clk *clk; 150 + const char *clk_name = data->node->name; 151 + const char *parent_name; 152 + struct gpio_desc *gpiod; 153 + int gpio; 154 + 155 + mutex_lock(&data->lock); 156 + 157 + if (data->clk) { 158 + mutex_unlock(&data->lock); 159 + return data->clk; 160 + } 161 + 162 + gpio = of_get_named_gpio_flags(data->node, "enable-gpios", 0, NULL); 163 + if (gpio < 0) { 164 + mutex_unlock(&data->lock); 165 + if (gpio != -EPROBE_DEFER) 166 + pr_err("%s: %s: Can't get 'enable-gpios' DT property\n", 167 + __func__, clk_name); 168 + return ERR_PTR(gpio); 169 + } 170 + gpiod = gpio_to_desc(gpio); 171 + 172 + parent_name = of_clk_get_parent_name(data->node, 0); 173 + 174 + clk = clk_register_gpio_gate(NULL, clk_name, parent_name, gpiod, 0); 175 + if (IS_ERR(clk)) { 176 + mutex_unlock(&data->lock); 177 + return clk; 178 + } 179 + 180 + data->clk = clk; 181 + mutex_unlock(&data->lock); 182 + 183 + return clk; 184 + } 185 + 186 + /** 187 + * of_gpio_gate_clk_setup() - Setup function for gpio controlled clock 188 + */ 189 + void __init of_gpio_gate_clk_setup(struct device_node *node) 190 + { 191 + struct clk_gpio_gate_delayed_register_data *data; 192 + 193 + data = kzalloc(sizeof(struct clk_gpio_gate_delayed_register_data), 194 + GFP_KERNEL); 195 + if (!data) 196 + return; 197 + 198 + data->node = node; 199 + mutex_init(&data->lock); 200 + 201 + of_clk_add_provider(node, of_clk_gpio_gate_delayed_register_get, data); 202 + } 203 + EXPORT_SYMBOL_GPL(of_gpio_gate_clk_setup); 204 + CLK_OF_DECLARE(gpio_gate_clk, "gpio-gate-clock", of_gpio_gate_clk_setup); 205 + #endif
+192
drivers/clk/clk-max-gen.c
··· 1 + /* 2 + * clk-max-gen.c - Generic clock driver for Maxim PMICs clocks 3 + * 4 + * Copyright (C) 2014 Google, Inc 5 + * 6 + * Copyright (C) 2012 Samsung Electornics 7 + * Jonghwa Lee <jonghwa3.lee@samsung.com> 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 as published by the 11 + * Free Software Foundation; either version 2 of the License, or (at your 12 + * option) any later version. 13 + * 14 + * This program is distributed in the hope that it will be useful, 15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 + * GNU General Public License for more details. 18 + * 19 + * This driver is based on clk-max77686.c 20 + * 21 + */ 22 + 23 + #include <linux/kernel.h> 24 + #include <linux/slab.h> 25 + #include <linux/err.h> 26 + #include <linux/regmap.h> 27 + #include <linux/platform_device.h> 28 + #include <linux/clk-provider.h> 29 + #include <linux/mutex.h> 30 + #include <linux/clkdev.h> 31 + #include <linux/of.h> 32 + #include <linux/export.h> 33 + 34 + struct max_gen_clk { 35 + struct regmap *regmap; 36 + u32 mask; 37 + u32 reg; 38 + struct clk_hw hw; 39 + }; 40 + 41 + static struct max_gen_clk *to_max_gen_clk(struct clk_hw *hw) 42 + { 43 + return container_of(hw, struct max_gen_clk, hw); 44 + } 45 + 46 + static int max_gen_clk_prepare(struct clk_hw *hw) 47 + { 48 + struct max_gen_clk *max_gen = to_max_gen_clk(hw); 49 + 50 + return regmap_update_bits(max_gen->regmap, max_gen->reg, 51 + max_gen->mask, max_gen->mask); 52 + } 53 + 54 + static void max_gen_clk_unprepare(struct clk_hw *hw) 55 + { 56 + struct max_gen_clk *max_gen = to_max_gen_clk(hw); 57 + 58 + regmap_update_bits(max_gen->regmap, max_gen->reg, 59 + max_gen->mask, ~max_gen->mask); 60 + } 61 + 62 + static int max_gen_clk_is_prepared(struct clk_hw *hw) 63 + { 64 + struct max_gen_clk *max_gen = to_max_gen_clk(hw); 65 + int ret; 66 + u32 val; 67 + 68 + ret = regmap_read(max_gen->regmap, max_gen->reg, &val); 69 + 70 + if (ret < 0) 71 + return -EINVAL; 72 + 73 + return val & max_gen->mask; 74 + } 75 + 76 + static unsigned long max_gen_recalc_rate(struct clk_hw *hw, 77 + unsigned long parent_rate) 78 + { 79 + return 32768; 80 + } 81 + 82 + struct clk_ops max_gen_clk_ops = { 83 + .prepare = max_gen_clk_prepare, 84 + .unprepare = max_gen_clk_unprepare, 85 + .is_prepared = max_gen_clk_is_prepared, 86 + .recalc_rate = max_gen_recalc_rate, 87 + }; 88 + EXPORT_SYMBOL_GPL(max_gen_clk_ops); 89 + 90 + static struct clk *max_gen_clk_register(struct device *dev, 91 + struct max_gen_clk *max_gen) 92 + { 93 + struct clk *clk; 94 + struct clk_hw *hw = &max_gen->hw; 95 + int ret; 96 + 97 + clk = devm_clk_register(dev, hw); 98 + if (IS_ERR(clk)) 99 + return clk; 100 + 101 + ret = clk_register_clkdev(clk, hw->init->name, NULL); 102 + 103 + if (ret) 104 + return ERR_PTR(ret); 105 + 106 + return clk; 107 + } 108 + 109 + int max_gen_clk_probe(struct platform_device *pdev, struct regmap *regmap, 110 + u32 reg, struct clk_init_data *clks_init, int num_init) 111 + { 112 + int i, ret; 113 + struct max_gen_clk *max_gen_clks; 114 + struct clk **clocks; 115 + struct device *dev = pdev->dev.parent; 116 + const char *clk_name; 117 + struct clk_init_data *init; 118 + 119 + clocks = devm_kzalloc(dev, sizeof(struct clk *) * num_init, GFP_KERNEL); 120 + if (!clocks) 121 + return -ENOMEM; 122 + 123 + max_gen_clks = devm_kzalloc(dev, sizeof(struct max_gen_clk) 124 + * num_init, GFP_KERNEL); 125 + if (!max_gen_clks) 126 + return -ENOMEM; 127 + 128 + for (i = 0; i < num_init; i++) { 129 + max_gen_clks[i].regmap = regmap; 130 + max_gen_clks[i].mask = 1 << i; 131 + max_gen_clks[i].reg = reg; 132 + 133 + init = devm_kzalloc(dev, sizeof(*init), GFP_KERNEL); 134 + if (!init) 135 + return -ENOMEM; 136 + 137 + if (dev->of_node && 138 + !of_property_read_string_index(dev->of_node, 139 + "clock-output-names", 140 + i, &clk_name)) 141 + init->name = clk_name; 142 + else 143 + init->name = clks_init[i].name; 144 + 145 + init->ops = clks_init[i].ops; 146 + init->flags = clks_init[i].flags; 147 + 148 + max_gen_clks[i].hw.init = init; 149 + 150 + clocks[i] = max_gen_clk_register(dev, &max_gen_clks[i]); 151 + if (IS_ERR(clocks[i])) { 152 + ret = PTR_ERR(clocks[i]); 153 + dev_err(dev, "failed to register %s\n", 154 + max_gen_clks[i].hw.init->name); 155 + return ret; 156 + } 157 + } 158 + 159 + platform_set_drvdata(pdev, clocks); 160 + 161 + if (dev->of_node) { 162 + struct clk_onecell_data *of_data; 163 + 164 + of_data = devm_kzalloc(dev, sizeof(*of_data), GFP_KERNEL); 165 + if (!of_data) 166 + return -ENOMEM; 167 + 168 + of_data->clks = clocks; 169 + of_data->clk_num = num_init; 170 + ret = of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, 171 + of_data); 172 + 173 + if (ret) { 174 + dev_err(dev, "failed to register OF clock provider\n"); 175 + return ret; 176 + } 177 + } 178 + 179 + return 0; 180 + } 181 + EXPORT_SYMBOL_GPL(max_gen_clk_probe); 182 + 183 + int max_gen_clk_remove(struct platform_device *pdev, int num_init) 184 + { 185 + struct device *dev = pdev->dev.parent; 186 + 187 + if (dev->of_node) 188 + of_clk_del_provider(dev->of_node); 189 + 190 + return 0; 191 + } 192 + EXPORT_SYMBOL_GPL(max_gen_clk_remove);
+32
drivers/clk/clk-max-gen.h
··· 1 + /* 2 + * clk-max-gen.h - Generic clock driver for Maxim PMICs clocks 3 + * 4 + * Copyright (C) 2014 Google, Inc 5 + * 6 + * This program is free software; you can redistribute it and/or modify it 7 + * under the terms of the GNU General Public License as published by the 8 + * Free Software Foundation; either version 2 of the License, or (at your 9 + * option) any later version. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + * 16 + */ 17 + 18 + #ifndef __CLK_MAX_GEN_H__ 19 + #define __CLK_MAX_GEN_H__ 20 + 21 + #include <linux/types.h> 22 + #include <linux/device.h> 23 + #include <linux/clkdev.h> 24 + #include <linux/regmap.h> 25 + #include <linux/platform_device.h> 26 + 27 + int max_gen_clk_probe(struct platform_device *pdev, struct regmap *regmap, 28 + u32 reg, struct clk_init_data *clks_init, int num_init); 29 + int max_gen_clk_remove(struct platform_device *pdev, int num_init); 30 + extern struct clk_ops max_gen_clk_ops; 31 + 32 + #endif /* __CLK_MAX_GEN_H__ */
+9 -175
drivers/clk/clk-max77686.c
··· 30 30 #include <linux/mutex.h> 31 31 #include <linux/clkdev.h> 32 32 33 - enum { 34 - MAX77686_CLK_AP = 0, 35 - MAX77686_CLK_CP, 36 - MAX77686_CLK_PMIC, 37 - MAX77686_CLKS_NUM, 38 - }; 39 - 40 - struct max77686_clk { 41 - struct max77686_dev *iodev; 42 - u32 mask; 43 - struct clk_hw hw; 44 - struct clk_lookup *lookup; 45 - }; 46 - 47 - static struct max77686_clk *to_max77686_clk(struct clk_hw *hw) 48 - { 49 - return container_of(hw, struct max77686_clk, hw); 50 - } 51 - 52 - static int max77686_clk_prepare(struct clk_hw *hw) 53 - { 54 - struct max77686_clk *max77686 = to_max77686_clk(hw); 55 - 56 - return regmap_update_bits(max77686->iodev->regmap, 57 - MAX77686_REG_32KHZ, max77686->mask, 58 - max77686->mask); 59 - } 60 - 61 - static void max77686_clk_unprepare(struct clk_hw *hw) 62 - { 63 - struct max77686_clk *max77686 = to_max77686_clk(hw); 64 - 65 - regmap_update_bits(max77686->iodev->regmap, 66 - MAX77686_REG_32KHZ, max77686->mask, ~max77686->mask); 67 - } 68 - 69 - static int max77686_clk_is_prepared(struct clk_hw *hw) 70 - { 71 - struct max77686_clk *max77686 = to_max77686_clk(hw); 72 - int ret; 73 - u32 val; 74 - 75 - ret = regmap_read(max77686->iodev->regmap, 76 - MAX77686_REG_32KHZ, &val); 77 - 78 - if (ret < 0) 79 - return -EINVAL; 80 - 81 - return val & max77686->mask; 82 - } 83 - 84 - static unsigned long max77686_recalc_rate(struct clk_hw *hw, 85 - unsigned long parent_rate) 86 - { 87 - return 32768; 88 - } 89 - 90 - static struct clk_ops max77686_clk_ops = { 91 - .prepare = max77686_clk_prepare, 92 - .unprepare = max77686_clk_unprepare, 93 - .is_prepared = max77686_clk_is_prepared, 94 - .recalc_rate = max77686_recalc_rate, 95 - }; 33 + #include <dt-bindings/clock/maxim,max77686.h> 34 + #include "clk-max-gen.h" 96 35 97 36 static struct clk_init_data max77686_clks_init[MAX77686_CLKS_NUM] = { 98 37 [MAX77686_CLK_AP] = { 99 38 .name = "32khz_ap", 100 - .ops = &max77686_clk_ops, 39 + .ops = &max_gen_clk_ops, 101 40 .flags = CLK_IS_ROOT, 102 41 }, 103 42 [MAX77686_CLK_CP] = { 104 43 .name = "32khz_cp", 105 - .ops = &max77686_clk_ops, 44 + .ops = &max_gen_clk_ops, 106 45 .flags = CLK_IS_ROOT, 107 46 }, 108 47 [MAX77686_CLK_PMIC] = { 109 48 .name = "32khz_pmic", 110 - .ops = &max77686_clk_ops, 49 + .ops = &max_gen_clk_ops, 111 50 .flags = CLK_IS_ROOT, 112 51 }, 113 52 }; 114 53 115 - static struct clk *max77686_clk_register(struct device *dev, 116 - struct max77686_clk *max77686) 117 - { 118 - struct clk *clk; 119 - struct clk_hw *hw = &max77686->hw; 120 - 121 - clk = clk_register(dev, hw); 122 - if (IS_ERR(clk)) 123 - return clk; 124 - 125 - max77686->lookup = kzalloc(sizeof(struct clk_lookup), GFP_KERNEL); 126 - if (!max77686->lookup) 127 - return ERR_PTR(-ENOMEM); 128 - 129 - max77686->lookup->con_id = hw->init->name; 130 - max77686->lookup->clk = clk; 131 - 132 - clkdev_add(max77686->lookup); 133 - 134 - return clk; 135 - } 136 - 137 54 static int max77686_clk_probe(struct platform_device *pdev) 138 55 { 139 56 struct max77686_dev *iodev = dev_get_drvdata(pdev->dev.parent); 140 - struct max77686_clk *max77686_clks[MAX77686_CLKS_NUM]; 141 - struct clk **clocks; 142 - int i, ret; 143 57 144 - clocks = devm_kzalloc(&pdev->dev, sizeof(struct clk *) 145 - * MAX77686_CLKS_NUM, GFP_KERNEL); 146 - if (!clocks) 147 - return -ENOMEM; 148 - 149 - for (i = 0; i < MAX77686_CLKS_NUM; i++) { 150 - max77686_clks[i] = devm_kzalloc(&pdev->dev, 151 - sizeof(struct max77686_clk), GFP_KERNEL); 152 - if (!max77686_clks[i]) 153 - return -ENOMEM; 154 - } 155 - 156 - for (i = 0; i < MAX77686_CLKS_NUM; i++) { 157 - max77686_clks[i]->iodev = iodev; 158 - max77686_clks[i]->mask = 1 << i; 159 - max77686_clks[i]->hw.init = &max77686_clks_init[i]; 160 - 161 - clocks[i] = max77686_clk_register(&pdev->dev, max77686_clks[i]); 162 - if (IS_ERR(clocks[i])) { 163 - ret = PTR_ERR(clocks[i]); 164 - dev_err(&pdev->dev, "failed to register %s\n", 165 - max77686_clks[i]->hw.init->name); 166 - goto err_clocks; 167 - } 168 - } 169 - 170 - platform_set_drvdata(pdev, clocks); 171 - 172 - if (iodev->dev->of_node) { 173 - struct clk_onecell_data *of_data; 174 - 175 - of_data = devm_kzalloc(&pdev->dev, 176 - sizeof(*of_data), GFP_KERNEL); 177 - if (!of_data) { 178 - ret = -ENOMEM; 179 - goto err_clocks; 180 - } 181 - 182 - of_data->clks = clocks; 183 - of_data->clk_num = MAX77686_CLKS_NUM; 184 - ret = of_clk_add_provider(iodev->dev->of_node, 185 - of_clk_src_onecell_get, of_data); 186 - if (ret) { 187 - dev_err(&pdev->dev, "failed to register OF clock provider\n"); 188 - goto err_clocks; 189 - } 190 - } 191 - 192 - return 0; 193 - 194 - err_clocks: 195 - for (--i; i >= 0; --i) { 196 - clkdev_drop(max77686_clks[i]->lookup); 197 - clk_unregister(max77686_clks[i]->hw.clk); 198 - } 199 - 200 - return ret; 58 + return max_gen_clk_probe(pdev, iodev->regmap, MAX77686_REG_32KHZ, 59 + max77686_clks_init, MAX77686_CLKS_NUM); 201 60 } 202 61 203 62 static int max77686_clk_remove(struct platform_device *pdev) 204 63 { 205 - struct max77686_dev *iodev = dev_get_drvdata(pdev->dev.parent); 206 - struct clk **clocks = platform_get_drvdata(pdev); 207 - int i; 208 - 209 - if (iodev->dev->of_node) 210 - of_clk_del_provider(iodev->dev->of_node); 211 - 212 - for (i = 0; i < MAX77686_CLKS_NUM; i++) { 213 - struct clk_hw *hw = __clk_get_hw(clocks[i]); 214 - struct max77686_clk *max77686 = to_max77686_clk(hw); 215 - 216 - clkdev_drop(max77686->lookup); 217 - clk_unregister(clocks[i]); 218 - } 219 - return 0; 64 + return max_gen_clk_remove(pdev, MAX77686_CLKS_NUM); 220 65 } 221 66 222 67 static const struct platform_device_id max77686_clk_id[] = { ··· 73 228 static struct platform_driver max77686_clk_driver = { 74 229 .driver = { 75 230 .name = "max77686-clk", 76 - .owner = THIS_MODULE, 77 231 }, 78 232 .probe = max77686_clk_probe, 79 233 .remove = max77686_clk_remove, 80 234 .id_table = max77686_clk_id, 81 235 }; 82 236 83 - static int __init max77686_clk_init(void) 84 - { 85 - return platform_driver_register(&max77686_clk_driver); 86 - } 87 - subsys_initcall(max77686_clk_init); 88 - 89 - static void __init max77686_clk_cleanup(void) 90 - { 91 - platform_driver_unregister(&max77686_clk_driver); 92 - } 93 - module_exit(max77686_clk_cleanup); 237 + module_platform_driver(max77686_clk_driver); 94 238 95 239 MODULE_DESCRIPTION("MAXIM 77686 Clock Driver"); 96 240 MODULE_AUTHOR("Jonghwa Lee <jonghwa3.lee@samsung.com>");
+97
drivers/clk/clk-max77802.c
··· 1 + /* 2 + * clk-max77802.c - Clock driver for Maxim 77802 3 + * 4 + * Copyright (C) 2014 Google, Inc 5 + * 6 + * Copyright (C) 2012 Samsung Electornics 7 + * Jonghwa Lee <jonghwa3.lee@samsung.com> 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 as published by the 11 + * Free Software Foundation; either version 2 of the License, or (at your 12 + * option) any later version. 13 + * 14 + * This program is distributed in the hope that it will be useful, 15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 + * GNU General Public License for more details. 18 + * 19 + * This driver is based on clk-max77686.c 20 + */ 21 + 22 + #include <linux/kernel.h> 23 + #include <linux/slab.h> 24 + #include <linux/err.h> 25 + #include <linux/platform_device.h> 26 + #include <linux/mfd/max77686-private.h> 27 + #include <linux/clk-provider.h> 28 + #include <linux/mutex.h> 29 + #include <linux/clkdev.h> 30 + 31 + #include <dt-bindings/clock/maxim,max77802.h> 32 + #include "clk-max-gen.h" 33 + 34 + #define MAX77802_CLOCK_OPMODE_MASK 0x1 35 + #define MAX77802_CLOCK_LOW_JITTER_SHIFT 0x3 36 + 37 + static struct clk_init_data max77802_clks_init[MAX77802_CLKS_NUM] = { 38 + [MAX77802_CLK_32K_AP] = { 39 + .name = "32khz_ap", 40 + .ops = &max_gen_clk_ops, 41 + .flags = CLK_IS_ROOT, 42 + }, 43 + [MAX77802_CLK_32K_CP] = { 44 + .name = "32khz_cp", 45 + .ops = &max_gen_clk_ops, 46 + .flags = CLK_IS_ROOT, 47 + }, 48 + }; 49 + 50 + static int max77802_clk_probe(struct platform_device *pdev) 51 + { 52 + struct max77686_dev *iodev = dev_get_drvdata(pdev->dev.parent); 53 + int ret; 54 + 55 + ret = max_gen_clk_probe(pdev, iodev->regmap, MAX77802_REG_32KHZ, 56 + max77802_clks_init, MAX77802_CLKS_NUM); 57 + 58 + if (ret) { 59 + dev_err(&pdev->dev, "generic probe failed %d\n", ret); 60 + return ret; 61 + } 62 + 63 + /* Enable low-jitter mode on the 32khz clocks. */ 64 + ret = regmap_update_bits(iodev->regmap, MAX77802_REG_32KHZ, 65 + 1 << MAX77802_CLOCK_LOW_JITTER_SHIFT, 66 + 1 << MAX77802_CLOCK_LOW_JITTER_SHIFT); 67 + if (ret < 0) 68 + dev_err(&pdev->dev, "failed to enable low-jitter mode\n"); 69 + 70 + return ret; 71 + } 72 + 73 + static int max77802_clk_remove(struct platform_device *pdev) 74 + { 75 + return max_gen_clk_remove(pdev, MAX77802_CLKS_NUM); 76 + } 77 + 78 + static const struct platform_device_id max77802_clk_id[] = { 79 + { "max77802-clk", 0}, 80 + { }, 81 + }; 82 + MODULE_DEVICE_TABLE(platform, max77802_clk_id); 83 + 84 + static struct platform_driver max77802_clk_driver = { 85 + .driver = { 86 + .name = "max77802-clk", 87 + }, 88 + .probe = max77802_clk_probe, 89 + .remove = max77802_clk_remove, 90 + .id_table = max77802_clk_id, 91 + }; 92 + 93 + module_platform_driver(max77802_clk_driver); 94 + 95 + MODULE_DESCRIPTION("MAXIM 77802 Clock Driver"); 96 + MODULE_AUTHOR("Javier Martinez Canillas <javier.martinez@collabora.co.uk>"); 97 + MODULE_LICENSE("GPL");
-1
drivers/clk/clk-palmas.c
··· 292 292 static struct platform_driver palmas_clks_driver = { 293 293 .driver = { 294 294 .name = "palmas-clk", 295 - .owner = THIS_MODULE, 296 295 .of_match_table = palmas_clks_of_match, 297 296 }, 298 297 .probe = palmas_clks_probe,
-1
drivers/clk/clk-twl6040.c
··· 112 112 static struct platform_driver twl6040_clk_driver = { 113 113 .driver = { 114 114 .name = "twl6040-clk", 115 - .owner = THIS_MODULE, 116 115 }, 117 116 .probe = twl6040_clk_probe, 118 117 .remove = twl6040_clk_remove,
-1
drivers/clk/clk-wm831x.c
··· 395 395 .probe = wm831x_clk_probe, 396 396 .driver = { 397 397 .name = "wm831x-clk", 398 - .owner = THIS_MODULE, 399 398 }, 400 399 }; 401 400
+118 -50
drivers/clk/clk.c
··· 100 100 101 101 static struct dentry *rootdir; 102 102 static int inited = 0; 103 + static DEFINE_MUTEX(clk_debug_lock); 104 + static HLIST_HEAD(clk_debug_list); 103 105 104 106 static struct hlist_head *all_lists[] = { 105 107 &clk_root_list, ··· 119 117 if (!c) 120 118 return; 121 119 122 - seq_printf(s, "%*s%-*s %11d %12d %11lu %10lu\n", 120 + seq_printf(s, "%*s%-*s %11d %12d %11lu %10lu %-3d\n", 123 121 level * 3 + 1, "", 124 122 30 - level * 3, c->name, 125 123 c->enable_count, c->prepare_count, clk_get_rate(c), 126 - clk_get_accuracy(c)); 124 + clk_get_accuracy(c), clk_get_phase(c)); 127 125 } 128 126 129 127 static void clk_summary_show_subtree(struct seq_file *s, struct clk *c, ··· 145 143 struct clk *c; 146 144 struct hlist_head **lists = (struct hlist_head **)s->private; 147 145 148 - seq_puts(s, " clock enable_cnt prepare_cnt rate accuracy\n"); 149 - seq_puts(s, "--------------------------------------------------------------------------------\n"); 146 + seq_puts(s, " clock enable_cnt prepare_cnt rate accuracy phase\n"); 147 + seq_puts(s, "----------------------------------------------------------------------------------------\n"); 150 148 151 149 clk_prepare_lock(); 152 150 ··· 182 180 seq_printf(s, "\"prepare_count\": %d,", c->prepare_count); 183 181 seq_printf(s, "\"rate\": %lu", clk_get_rate(c)); 184 182 seq_printf(s, "\"accuracy\": %lu", clk_get_accuracy(c)); 183 + seq_printf(s, "\"phase\": %d", clk_get_phase(c)); 185 184 } 186 185 187 186 static void clk_dump_subtree(struct seq_file *s, struct clk *c, int level) ··· 267 264 if (!d) 268 265 goto err_out; 269 266 267 + d = debugfs_create_u32("clk_phase", S_IRUGO, clk->dentry, 268 + (u32 *)&clk->phase); 269 + if (!d) 270 + goto err_out; 271 + 270 272 d = debugfs_create_x32("clk_flags", S_IRUGO, clk->dentry, 271 273 (u32 *)&clk->flags); 272 274 if (!d) ··· 308 300 return ret; 309 301 } 310 302 311 - /* caller must hold prepare_lock */ 312 - static int clk_debug_create_subtree(struct clk *clk, struct dentry *pdentry) 313 - { 314 - struct clk *child; 315 - int ret = -EINVAL;; 316 - 317 - if (!clk || !pdentry) 318 - goto out; 319 - 320 - ret = clk_debug_create_one(clk, pdentry); 321 - 322 - if (ret) 323 - goto out; 324 - 325 - hlist_for_each_entry(child, &clk->children, child_node) 326 - clk_debug_create_subtree(child, pdentry); 327 - 328 - ret = 0; 329 - out: 330 - return ret; 331 - } 332 - 333 303 /** 334 304 * clk_debug_register - add a clk node to the debugfs clk tree 335 305 * @clk: the clk being added to the debugfs clk tree ··· 315 329 * Dynamically adds a clk to the debugfs clk tree if debugfs has been 316 330 * initialized. Otherwise it bails out early since the debugfs clk tree 317 331 * will be created lazily by clk_debug_init as part of a late_initcall. 318 - * 319 - * Caller must hold prepare_lock. Only clk_init calls this function (so 320 - * far) so this is taken care. 321 332 */ 322 333 static int clk_debug_register(struct clk *clk) 323 334 { 324 335 int ret = 0; 325 336 337 + mutex_lock(&clk_debug_lock); 338 + hlist_add_head(&clk->debug_node, &clk_debug_list); 339 + 326 340 if (!inited) 327 - goto out; 341 + goto unlock; 328 342 329 - ret = clk_debug_create_subtree(clk, rootdir); 343 + ret = clk_debug_create_one(clk, rootdir); 344 + unlock: 345 + mutex_unlock(&clk_debug_lock); 330 346 331 - out: 332 347 return ret; 333 348 } 334 349 ··· 340 353 * Dynamically removes a clk and all it's children clk nodes from the 341 354 * debugfs clk tree if clk->dentry points to debugfs created by 342 355 * clk_debug_register in __clk_init. 343 - * 344 - * Caller must hold prepare_lock. 345 356 */ 346 357 static void clk_debug_unregister(struct clk *clk) 347 358 { 359 + mutex_lock(&clk_debug_lock); 360 + if (!clk->dentry) 361 + goto out; 362 + 363 + hlist_del_init(&clk->debug_node); 348 364 debugfs_remove_recursive(clk->dentry); 365 + clk->dentry = NULL; 366 + out: 367 + mutex_unlock(&clk_debug_lock); 349 368 } 350 369 351 370 struct dentry *clk_debugfs_add_file(struct clk *clk, char *name, umode_t mode, ··· 408 415 if (!d) 409 416 return -ENOMEM; 410 417 411 - clk_prepare_lock(); 412 - 413 - hlist_for_each_entry(clk, &clk_root_list, child_node) 414 - clk_debug_create_subtree(clk, rootdir); 415 - 416 - hlist_for_each_entry(clk, &clk_orphan_list, child_node) 417 - clk_debug_create_subtree(clk, rootdir); 418 + mutex_lock(&clk_debug_lock); 419 + hlist_for_each_entry(clk, &clk_debug_list, debug_node) 420 + clk_debug_create_one(clk, rootdir); 418 421 419 422 inited = 1; 420 - 421 - clk_prepare_unlock(); 423 + mutex_unlock(&clk_debug_lock); 422 424 423 425 return 0; 424 426 } ··· 1732 1744 EXPORT_SYMBOL_GPL(clk_set_parent); 1733 1745 1734 1746 /** 1747 + * clk_set_phase - adjust the phase shift of a clock signal 1748 + * @clk: clock signal source 1749 + * @degrees: number of degrees the signal is shifted 1750 + * 1751 + * Shifts the phase of a clock signal by the specified 1752 + * degrees. Returns 0 on success, -EERROR otherwise. 1753 + * 1754 + * This function makes no distinction about the input or reference 1755 + * signal that we adjust the clock signal phase against. For example 1756 + * phase locked-loop clock signal generators we may shift phase with 1757 + * respect to feedback clock signal input, but for other cases the 1758 + * clock phase may be shifted with respect to some other, unspecified 1759 + * signal. 1760 + * 1761 + * Additionally the concept of phase shift does not propagate through 1762 + * the clock tree hierarchy, which sets it apart from clock rates and 1763 + * clock accuracy. A parent clock phase attribute does not have an 1764 + * impact on the phase attribute of a child clock. 1765 + */ 1766 + int clk_set_phase(struct clk *clk, int degrees) 1767 + { 1768 + int ret = 0; 1769 + 1770 + if (!clk) 1771 + goto out; 1772 + 1773 + /* sanity check degrees */ 1774 + degrees %= 360; 1775 + if (degrees < 0) 1776 + degrees += 360; 1777 + 1778 + clk_prepare_lock(); 1779 + 1780 + if (!clk->ops->set_phase) 1781 + goto out_unlock; 1782 + 1783 + ret = clk->ops->set_phase(clk->hw, degrees); 1784 + 1785 + if (!ret) 1786 + clk->phase = degrees; 1787 + 1788 + out_unlock: 1789 + clk_prepare_unlock(); 1790 + 1791 + out: 1792 + return ret; 1793 + } 1794 + 1795 + /** 1796 + * clk_get_phase - return the phase shift of a clock signal 1797 + * @clk: clock signal source 1798 + * 1799 + * Returns the phase shift of a clock node in degrees, otherwise returns 1800 + * -EERROR. 1801 + */ 1802 + int clk_get_phase(struct clk *clk) 1803 + { 1804 + int ret = 0; 1805 + 1806 + if (!clk) 1807 + goto out; 1808 + 1809 + clk_prepare_lock(); 1810 + ret = clk->phase; 1811 + clk_prepare_unlock(); 1812 + 1813 + out: 1814 + return ret; 1815 + } 1816 + 1817 + /** 1735 1818 * __clk_init - initialize the data structures in a struct clk 1736 1819 * @dev: device initializing this clk, placeholder for now 1737 1820 * @clk: clk being initialized ··· 1919 1860 clk->accuracy = clk->parent->accuracy; 1920 1861 else 1921 1862 clk->accuracy = 0; 1863 + 1864 + /* 1865 + * Set clk's phase. 1866 + * Since a phase is by definition relative to its parent, just 1867 + * query the current clock phase, or just assume it's in phase. 1868 + */ 1869 + if (clk->ops->get_phase) 1870 + clk->phase = clk->ops->get_phase(clk->hw); 1871 + else 1872 + clk->phase = 0; 1922 1873 1923 1874 /* 1924 1875 * Set clk's rate. The preferred method is to use .recalc_rate. For ··· 2161 2092 { 2162 2093 unsigned long flags; 2163 2094 2164 - if (!clk || WARN_ON_ONCE(IS_ERR(clk))) 2165 - return; 2095 + if (!clk || WARN_ON_ONCE(IS_ERR(clk))) 2096 + return; 2097 + 2098 + clk_debug_unregister(clk); 2166 2099 2167 2100 clk_prepare_lock(); 2168 2101 2169 2102 if (clk->ops == &clk_nodrv_ops) { 2170 2103 pr_err("%s: unregistered clock: %s\n", __func__, clk->name); 2171 - goto out; 2104 + return; 2172 2105 } 2173 2106 /* 2174 2107 * Assign empty clock ops for consumers that might still hold ··· 2189 2118 clk_set_parent(child, NULL); 2190 2119 } 2191 2120 2192 - clk_debug_unregister(clk); 2193 - 2194 2121 hlist_del_init(&clk->child_node); 2195 2122 2196 2123 if (clk->prepare_count) 2197 2124 pr_warn("%s: unregistering prepared clock: %s\n", 2198 2125 __func__, clk->name); 2199 - 2200 2126 kref_put(&clk->ref, __clk_release); 2201 - out: 2127 + 2202 2128 clk_prepare_unlock(); 2203 2129 } 2204 2130 EXPORT_SYMBOL_GPL(clk_unregister);
+226 -6
drivers/clk/hisilicon/clk-hix5hd2.c
··· 9 9 10 10 #include <linux/of_address.h> 11 11 #include <dt-bindings/clock/hix5hd2-clock.h> 12 + #include <linux/slab.h> 13 + #include <linux/delay.h> 12 14 #include "clk.h" 13 15 14 16 static struct hisi_fixed_rate_clock hix5hd2_fixed_rate_clks[] __initdata = { ··· 50 48 "24m", "150m", "200m", "100m", "75m", }; 51 49 static u32 sfc_mux_table[] = {0, 4, 5, 6, 7}; 52 50 53 - static const char *sdio1_mux_p[] __initconst = { 51 + static const char *sdio_mux_p[] __initconst = { 54 52 "75m", "100m", "50m", "15m", }; 55 - static u32 sdio1_mux_table[] = {0, 1, 2, 3}; 53 + static u32 sdio_mux_table[] = {0, 1, 2, 3}; 56 54 57 55 static const char *fephy_mux_p[] __initconst = { "25m", "125m"}; 58 56 static u32 fephy_mux_table[] = {0, 1}; ··· 61 59 static struct hisi_mux_clock hix5hd2_mux_clks[] __initdata = { 62 60 { HIX5HD2_SFC_MUX, "sfc_mux", sfc_mux_p, ARRAY_SIZE(sfc_mux_p), 63 61 CLK_SET_RATE_PARENT, 0x5c, 8, 3, 0, sfc_mux_table, }, 64 - { HIX5HD2_MMC_MUX, "mmc_mux", sdio1_mux_p, ARRAY_SIZE(sdio1_mux_p), 65 - CLK_SET_RATE_PARENT, 0xa0, 8, 2, 0, sdio1_mux_table, }, 62 + { HIX5HD2_MMC_MUX, "mmc_mux", sdio_mux_p, ARRAY_SIZE(sdio_mux_p), 63 + CLK_SET_RATE_PARENT, 0xa0, 8, 2, 0, sdio_mux_table, }, 64 + { HIX5HD2_SD_MUX, "sd_mux", sdio_mux_p, ARRAY_SIZE(sdio_mux_p), 65 + CLK_SET_RATE_PARENT, 0x9c, 8, 2, 0, sdio_mux_table, }, 66 66 { HIX5HD2_FEPHY_MUX, "fephy_mux", 67 67 fephy_mux_p, ARRAY_SIZE(fephy_mux_p), 68 68 CLK_SET_RATE_PARENT, 0x120, 8, 2, 0, fephy_mux_table, }, 69 69 }; 70 70 71 71 static struct hisi_gate_clock hix5hd2_gate_clks[] __initdata = { 72 - /*sfc*/ 72 + /* sfc */ 73 73 { HIX5HD2_SFC_CLK, "clk_sfc", "sfc_mux", 74 74 CLK_SET_RATE_PARENT, 0x5c, 0, 0, }, 75 75 { HIX5HD2_SFC_RST, "rst_sfc", "clk_sfc", 76 76 CLK_SET_RATE_PARENT, 0x5c, 4, CLK_GATE_SET_TO_DISABLE, }, 77 - /*sdio1*/ 77 + /* sdio0 */ 78 + { HIX5HD2_SD_BIU_CLK, "clk_sd_biu", "200m", 79 + CLK_SET_RATE_PARENT, 0x9c, 0, 0, }, 80 + { HIX5HD2_SD_CIU_CLK, "clk_sd_ciu", "sd_mux", 81 + CLK_SET_RATE_PARENT, 0x9c, 1, 0, }, 82 + { HIX5HD2_SD_CIU_RST, "rst_sd_ciu", "clk_sd_ciu", 83 + CLK_SET_RATE_PARENT, 0x9c, 4, CLK_GATE_SET_TO_DISABLE, }, 84 + /* sdio1 */ 78 85 { HIX5HD2_MMC_BIU_CLK, "clk_mmc_biu", "200m", 79 86 CLK_SET_RATE_PARENT, 0xa0, 0, 0, }, 80 87 { HIX5HD2_MMC_CIU_CLK, "clk_mmc_ciu", "mmc_mux", 81 88 CLK_SET_RATE_PARENT, 0xa0, 1, 0, }, 82 89 { HIX5HD2_MMC_CIU_RST, "rst_mmc_ciu", "clk_mmc_ciu", 83 90 CLK_SET_RATE_PARENT, 0xa0, 4, CLK_GATE_SET_TO_DISABLE, }, 91 + /* gsf */ 92 + { HIX5HD2_FWD_BUS_CLK, "clk_fwd_bus", NULL, 0, 0xcc, 0, 0, }, 93 + { HIX5HD2_FWD_SYS_CLK, "clk_fwd_sys", "clk_fwd_bus", 0, 0xcc, 5, 0, }, 94 + { HIX5HD2_MAC0_PHY_CLK, "clk_fephy", "clk_fwd_sys", 95 + CLK_SET_RATE_PARENT, 0x120, 0, 0, }, 96 + /* wdg0 */ 97 + { HIX5HD2_WDG0_CLK, "clk_wdg0", "24m", 98 + CLK_SET_RATE_PARENT, 0x178, 0, 0, }, 99 + { HIX5HD2_WDG0_RST, "rst_wdg0", "clk_wdg0", 100 + CLK_SET_RATE_PARENT, 0x178, 4, CLK_GATE_SET_TO_DISABLE, }, 101 + /* I2C */ 102 + {HIX5HD2_I2C0_CLK, "clk_i2c0", "100m", 103 + CLK_SET_RATE_PARENT, 0x06c, 4, 0, }, 104 + {HIX5HD2_I2C0_RST, "rst_i2c0", "clk_i2c0", 105 + CLK_SET_RATE_PARENT, 0x06c, 5, CLK_GATE_SET_TO_DISABLE, }, 106 + {HIX5HD2_I2C1_CLK, "clk_i2c1", "100m", 107 + CLK_SET_RATE_PARENT, 0x06c, 8, 0, }, 108 + {HIX5HD2_I2C1_RST, "rst_i2c1", "clk_i2c1", 109 + CLK_SET_RATE_PARENT, 0x06c, 9, CLK_GATE_SET_TO_DISABLE, }, 110 + {HIX5HD2_I2C2_CLK, "clk_i2c2", "100m", 111 + CLK_SET_RATE_PARENT, 0x06c, 12, 0, }, 112 + {HIX5HD2_I2C2_RST, "rst_i2c2", "clk_i2c2", 113 + CLK_SET_RATE_PARENT, 0x06c, 13, CLK_GATE_SET_TO_DISABLE, }, 114 + {HIX5HD2_I2C3_CLK, "clk_i2c3", "100m", 115 + CLK_SET_RATE_PARENT, 0x06c, 16, 0, }, 116 + {HIX5HD2_I2C3_RST, "rst_i2c3", "clk_i2c3", 117 + CLK_SET_RATE_PARENT, 0x06c, 17, CLK_GATE_SET_TO_DISABLE, }, 118 + {HIX5HD2_I2C4_CLK, "clk_i2c4", "100m", 119 + CLK_SET_RATE_PARENT, 0x06c, 20, 0, }, 120 + {HIX5HD2_I2C4_RST, "rst_i2c4", "clk_i2c4", 121 + CLK_SET_RATE_PARENT, 0x06c, 21, CLK_GATE_SET_TO_DISABLE, }, 122 + {HIX5HD2_I2C5_CLK, "clk_i2c5", "100m", 123 + CLK_SET_RATE_PARENT, 0x06c, 0, 0, }, 124 + {HIX5HD2_I2C5_RST, "rst_i2c5", "clk_i2c5", 125 + CLK_SET_RATE_PARENT, 0x06c, 1, CLK_GATE_SET_TO_DISABLE, }, 84 126 }; 127 + 128 + enum hix5hd2_clk_type { 129 + TYPE_COMPLEX, 130 + TYPE_ETHER, 131 + }; 132 + 133 + struct hix5hd2_complex_clock { 134 + const char *name; 135 + const char *parent_name; 136 + u32 id; 137 + u32 ctrl_reg; 138 + u32 ctrl_clk_mask; 139 + u32 ctrl_rst_mask; 140 + u32 phy_reg; 141 + u32 phy_clk_mask; 142 + u32 phy_rst_mask; 143 + enum hix5hd2_clk_type type; 144 + }; 145 + 146 + struct hix5hd2_clk_complex { 147 + struct clk_hw hw; 148 + u32 id; 149 + void __iomem *ctrl_reg; 150 + u32 ctrl_clk_mask; 151 + u32 ctrl_rst_mask; 152 + void __iomem *phy_reg; 153 + u32 phy_clk_mask; 154 + u32 phy_rst_mask; 155 + }; 156 + 157 + static struct hix5hd2_complex_clock hix5hd2_complex_clks[] __initdata = { 158 + {"clk_mac0", "clk_fephy", HIX5HD2_MAC0_CLK, 159 + 0xcc, 0xa, 0x500, 0x120, 0, 0x10, TYPE_ETHER}, 160 + {"clk_mac1", "clk_fwd_sys", HIX5HD2_MAC1_CLK, 161 + 0xcc, 0x14, 0xa00, 0x168, 0x2, 0, TYPE_ETHER}, 162 + {"clk_sata", NULL, HIX5HD2_SATA_CLK, 163 + 0xa8, 0x1f, 0x300, 0xac, 0x1, 0x0, TYPE_COMPLEX}, 164 + {"clk_usb", NULL, HIX5HD2_USB_CLK, 165 + 0xb8, 0xff, 0x3f000, 0xbc, 0x7, 0x3f00, TYPE_COMPLEX}, 166 + }; 167 + 168 + #define to_complex_clk(_hw) container_of(_hw, struct hix5hd2_clk_complex, hw) 169 + 170 + static int clk_ether_prepare(struct clk_hw *hw) 171 + { 172 + struct hix5hd2_clk_complex *clk = to_complex_clk(hw); 173 + u32 val; 174 + 175 + val = readl_relaxed(clk->ctrl_reg); 176 + val |= clk->ctrl_clk_mask | clk->ctrl_rst_mask; 177 + writel_relaxed(val, clk->ctrl_reg); 178 + val &= ~(clk->ctrl_rst_mask); 179 + writel_relaxed(val, clk->ctrl_reg); 180 + 181 + val = readl_relaxed(clk->phy_reg); 182 + val |= clk->phy_clk_mask; 183 + val &= ~(clk->phy_rst_mask); 184 + writel_relaxed(val, clk->phy_reg); 185 + mdelay(10); 186 + 187 + val &= ~(clk->phy_clk_mask); 188 + val |= clk->phy_rst_mask; 189 + writel_relaxed(val, clk->phy_reg); 190 + mdelay(10); 191 + 192 + val |= clk->phy_clk_mask; 193 + val &= ~(clk->phy_rst_mask); 194 + writel_relaxed(val, clk->phy_reg); 195 + mdelay(30); 196 + return 0; 197 + } 198 + 199 + static void clk_ether_unprepare(struct clk_hw *hw) 200 + { 201 + struct hix5hd2_clk_complex *clk = to_complex_clk(hw); 202 + u32 val; 203 + 204 + val = readl_relaxed(clk->ctrl_reg); 205 + val &= ~(clk->ctrl_clk_mask); 206 + writel_relaxed(val, clk->ctrl_reg); 207 + } 208 + 209 + static struct clk_ops clk_ether_ops = { 210 + .prepare = clk_ether_prepare, 211 + .unprepare = clk_ether_unprepare, 212 + }; 213 + 214 + static int clk_complex_enable(struct clk_hw *hw) 215 + { 216 + struct hix5hd2_clk_complex *clk = to_complex_clk(hw); 217 + u32 val; 218 + 219 + val = readl_relaxed(clk->ctrl_reg); 220 + val |= clk->ctrl_clk_mask; 221 + val &= ~(clk->ctrl_rst_mask); 222 + writel_relaxed(val, clk->ctrl_reg); 223 + 224 + val = readl_relaxed(clk->phy_reg); 225 + val |= clk->phy_clk_mask; 226 + val &= ~(clk->phy_rst_mask); 227 + writel_relaxed(val, clk->phy_reg); 228 + 229 + return 0; 230 + } 231 + 232 + static void clk_complex_disable(struct clk_hw *hw) 233 + { 234 + struct hix5hd2_clk_complex *clk = to_complex_clk(hw); 235 + u32 val; 236 + 237 + val = readl_relaxed(clk->ctrl_reg); 238 + val |= clk->ctrl_rst_mask; 239 + val &= ~(clk->ctrl_clk_mask); 240 + writel_relaxed(val, clk->ctrl_reg); 241 + 242 + val = readl_relaxed(clk->phy_reg); 243 + val |= clk->phy_rst_mask; 244 + val &= ~(clk->phy_clk_mask); 245 + writel_relaxed(val, clk->phy_reg); 246 + } 247 + 248 + static struct clk_ops clk_complex_ops = { 249 + .enable = clk_complex_enable, 250 + .disable = clk_complex_disable, 251 + }; 252 + 253 + void __init hix5hd2_clk_register_complex(struct hix5hd2_complex_clock *clks, 254 + int nums, struct hisi_clock_data *data) 255 + { 256 + void __iomem *base = data->base; 257 + int i; 258 + 259 + for (i = 0; i < nums; i++) { 260 + struct hix5hd2_clk_complex *p_clk; 261 + struct clk *clk; 262 + struct clk_init_data init; 263 + 264 + p_clk = kzalloc(sizeof(*p_clk), GFP_KERNEL); 265 + if (!p_clk) 266 + return; 267 + 268 + init.name = clks[i].name; 269 + if (clks[i].type == TYPE_ETHER) 270 + init.ops = &clk_ether_ops; 271 + else 272 + init.ops = &clk_complex_ops; 273 + 274 + init.flags = CLK_IS_BASIC; 275 + init.parent_names = 276 + (clks[i].parent_name ? &clks[i].parent_name : NULL); 277 + init.num_parents = (clks[i].parent_name ? 1 : 0); 278 + 279 + p_clk->ctrl_reg = base + clks[i].ctrl_reg; 280 + p_clk->ctrl_clk_mask = clks[i].ctrl_clk_mask; 281 + p_clk->ctrl_rst_mask = clks[i].ctrl_rst_mask; 282 + p_clk->phy_reg = base + clks[i].phy_reg; 283 + p_clk->phy_clk_mask = clks[i].phy_clk_mask; 284 + p_clk->phy_rst_mask = clks[i].phy_rst_mask; 285 + p_clk->hw.init = &init; 286 + 287 + clk = clk_register(NULL, &p_clk->hw); 288 + if (IS_ERR(clk)) { 289 + kfree(p_clk); 290 + pr_err("%s: failed to register clock %s\n", 291 + __func__, clks[i].name); 292 + continue; 293 + } 294 + 295 + data->clk_data.clks[clks[i].id] = clk; 296 + } 297 + } 85 298 86 299 static void __init hix5hd2_clk_init(struct device_node *np) 87 300 { ··· 313 96 clk_data); 314 97 hisi_clk_register_gate(hix5hd2_gate_clks, 315 98 ARRAY_SIZE(hix5hd2_gate_clks), clk_data); 99 + hix5hd2_clk_register_complex(hix5hd2_complex_clks, 100 + ARRAY_SIZE(hix5hd2_complex_clks), 101 + clk_data); 316 102 } 317 103 318 104 CLK_OF_DECLARE(hix5hd2_clk, "hisilicon,hix5hd2-clock", hix5hd2_clk_init);
+8
drivers/clk/mvebu/armada-370.c
··· 23 23 */ 24 24 25 25 #define SARL 0 /* Low part [0:31] */ 26 + #define SARL_A370_SSCG_ENABLE BIT(10) 26 27 #define SARL_A370_PCLK_FREQ_OPT 11 27 28 #define SARL_A370_PCLK_FREQ_OPT_MASK 0xF 28 29 #define SARL_A370_FAB_FREQ_OPT 15 ··· 134 133 } 135 134 } 136 135 136 + static bool a370_is_sscg_enabled(void __iomem *sar) 137 + { 138 + return !(readl(sar) & SARL_A370_SSCG_ENABLE); 139 + } 140 + 137 141 static const struct coreclk_soc_desc a370_coreclks = { 138 142 .get_tclk_freq = a370_get_tclk_freq, 139 143 .get_cpu_freq = a370_get_cpu_freq, 140 144 .get_clk_ratio = a370_get_clk_ratio, 145 + .is_sscg_enabled = a370_is_sscg_enabled, 146 + .fix_sscg_deviation = kirkwood_fix_sscg_deviation, 141 147 .ratios = a370_coreclk_ratios, 142 148 .num_ratios = ARRAY_SIZE(a370_coreclk_ratios), 143 149 };
+2 -2
drivers/clk/mvebu/armada-375.c
··· 27 27 * all modified at the same time, and not separately as for the Armada 28 28 * 370 or the Armada XP SoCs. 29 29 * 30 - * SAR0[21:17] : CPU frequency DDR frequency L2 frequency 30 + * SAR1[21:17] : CPU frequency DDR frequency L2 frequency 31 31 * 6 = 400 MHz 400 MHz 200 MHz 32 32 * 15 = 600 MHz 600 MHz 300 MHz 33 33 * 21 = 800 MHz 534 MHz 400 MHz 34 34 * 25 = 1000 MHz 500 MHz 500 MHz 35 35 * others reserved. 36 36 * 37 - * SAR0[22] : TCLK frequency 37 + * SAR1[22] : TCLK frequency 38 38 * 0 = 166 MHz 39 39 * 1 = 200 MHz 40 40 */
+88 -3
drivers/clk/mvebu/common.c
··· 26 26 * Core Clocks 27 27 */ 28 28 29 + #define SSCG_CONF_MODE(reg) (((reg) >> 16) & 0x3) 30 + #define SSCG_SPREAD_DOWN 0x0 31 + #define SSCG_SPREAD_UP 0x1 32 + #define SSCG_SPREAD_CENTRAL 0x2 33 + #define SSCG_CONF_LOW(reg) (((reg) >> 8) & 0xFF) 34 + #define SSCG_CONF_HIGH(reg) ((reg) & 0xFF) 35 + 29 36 static struct clk_onecell_data clk_data; 37 + 38 + /* 39 + * This function can be used by the Kirkwood, the Armada 370, the 40 + * Armada XP and the Armada 375 SoC. The name of the function was 41 + * chosen following the dt convention: using the first known SoC 42 + * compatible with it. 43 + */ 44 + u32 kirkwood_fix_sscg_deviation(u32 system_clk) 45 + { 46 + struct device_node *sscg_np = NULL; 47 + void __iomem *sscg_map; 48 + u32 sscg_reg; 49 + s32 low_bound, high_bound; 50 + u64 freq_swing_half; 51 + 52 + sscg_np = of_find_node_by_name(NULL, "sscg"); 53 + if (sscg_np == NULL) { 54 + pr_err("cannot get SSCG register node\n"); 55 + return system_clk; 56 + } 57 + 58 + sscg_map = of_iomap(sscg_np, 0); 59 + if (sscg_map == NULL) { 60 + pr_err("cannot map SSCG register\n"); 61 + goto out; 62 + } 63 + 64 + sscg_reg = readl(sscg_map); 65 + high_bound = SSCG_CONF_HIGH(sscg_reg); 66 + low_bound = SSCG_CONF_LOW(sscg_reg); 67 + 68 + if ((high_bound - low_bound) <= 0) 69 + goto out; 70 + /* 71 + * From Marvell engineer we got the following formula (when 72 + * this code was written, the datasheet was erroneous) 73 + * Spread percentage = 1/96 * (H - L) / H 74 + * H = SSCG_High_Boundary 75 + * L = SSCG_Low_Boundary 76 + * 77 + * As the deviation is half of spread then it lead to the 78 + * following formula in the code. 79 + * 80 + * To avoid an overflow and not lose any significant digit in 81 + * the same time we have to use a 64 bit integer. 82 + */ 83 + 84 + freq_swing_half = (((u64)high_bound - (u64)low_bound) 85 + * (u64)system_clk); 86 + do_div(freq_swing_half, (2 * 96 * high_bound)); 87 + 88 + switch (SSCG_CONF_MODE(sscg_reg)) { 89 + case SSCG_SPREAD_DOWN: 90 + system_clk -= freq_swing_half; 91 + break; 92 + case SSCG_SPREAD_UP: 93 + system_clk += freq_swing_half; 94 + break; 95 + case SSCG_SPREAD_CENTRAL: 96 + default: 97 + break; 98 + } 99 + 100 + iounmap(sscg_map); 101 + 102 + out: 103 + of_node_put(sscg_np); 104 + 105 + return system_clk; 106 + } 30 107 31 108 void __init mvebu_coreclk_setup(struct device_node *np, 32 109 const struct coreclk_soc_desc *desc) ··· 139 62 of_property_read_string_index(np, "clock-output-names", 1, 140 63 &cpuclk_name); 141 64 rate = desc->get_cpu_freq(base); 65 + 66 + if (desc->is_sscg_enabled && desc->fix_sscg_deviation 67 + && desc->is_sscg_enabled(base)) 68 + rate = desc->fix_sscg_deviation(rate); 69 + 142 70 clk_data.clks[1] = clk_register_fixed_rate(NULL, cpuclk_name, NULL, 143 71 CLK_IS_ROOT, rate); 144 72 WARN_ON(IS_ERR(clk_data.clks[1])); ··· 171 89 * Clock Gating Control 172 90 */ 173 91 92 + DEFINE_SPINLOCK(ctrl_gating_lock); 93 + 174 94 struct clk_gating_ctrl { 175 - spinlock_t lock; 95 + spinlock_t *lock; 176 96 struct clk **gates; 177 97 int num_gates; 178 98 }; ··· 222 138 if (WARN_ON(!ctrl)) 223 139 goto ctrl_out; 224 140 225 - spin_lock_init(&ctrl->lock); 141 + /* lock must already be initialized */ 142 + ctrl->lock = &ctrl_gating_lock; 226 143 227 144 /* Count, allocate, and register clock gates */ 228 145 for (n = 0; desc[n].name;) ··· 240 155 (desc[n].parent) ? desc[n].parent : default_parent; 241 156 ctrl->gates[n] = clk_register_gate(NULL, desc[n].name, parent, 242 157 desc[n].flags, base, desc[n].bit_idx, 243 - 0, &ctrl->lock); 158 + 0, ctrl->lock); 244 159 WARN_ON(IS_ERR(ctrl->gates[n])); 245 160 } 246 161
+9
drivers/clk/mvebu/common.h
··· 17 17 18 18 #include <linux/kernel.h> 19 19 20 + extern spinlock_t ctrl_gating_lock; 21 + 20 22 struct device_node; 21 23 22 24 struct coreclk_ratio { ··· 30 28 u32 (*get_tclk_freq)(void __iomem *sar); 31 29 u32 (*get_cpu_freq)(void __iomem *sar); 32 30 void (*get_clk_ratio)(void __iomem *sar, int id, int *mult, int *div); 31 + bool (*is_sscg_enabled)(void __iomem *sar); 32 + u32 (*fix_sscg_deviation)(u32 system_clk); 33 33 const struct coreclk_ratio *ratios; 34 34 int num_ratios; 35 35 }; ··· 49 45 void __init mvebu_clk_gating_setup(struct device_node *np, 50 46 const struct clk_gating_soc_desc *desc); 51 47 48 + /* 49 + * This function is shared among the Kirkwood, Armada 370, Armada XP 50 + * and Armada 375 SoC 51 + */ 52 + u32 kirkwood_fix_sscg_deviation(u32 system_clk); 52 53 #endif
+100 -2
drivers/clk/mvebu/kirkwood.c
··· 13 13 */ 14 14 15 15 #include <linux/kernel.h> 16 + #include <linux/slab.h> 16 17 #include <linux/clk-provider.h> 17 18 #include <linux/io.h> 18 19 #include <linux/of.h> 20 + #include <linux/of_address.h> 19 21 #include "common.h" 20 22 21 23 /* ··· 216 214 { "runit", NULL, 7, 0 }, 217 215 { "xor0", NULL, 8, 0 }, 218 216 { "audio", NULL, 9, 0 }, 219 - { "powersave", "cpuclk", 11, 0 }, 220 217 { "sata0", NULL, 14, 0 }, 221 218 { "sata1", NULL, 15, 0 }, 222 219 { "xor1", NULL, 16, 0 }, ··· 225 224 { "tdm", NULL, 20, 0 }, 226 225 { } 227 226 }; 227 + 228 + 229 + /* 230 + * Clock Muxing Control 231 + */ 232 + 233 + struct clk_muxing_soc_desc { 234 + const char *name; 235 + const char **parents; 236 + int num_parents; 237 + int shift; 238 + int width; 239 + unsigned long flags; 240 + }; 241 + 242 + struct clk_muxing_ctrl { 243 + spinlock_t *lock; 244 + struct clk **muxes; 245 + int num_muxes; 246 + }; 247 + 248 + static const char *powersave_parents[] = { 249 + "cpuclk", 250 + "ddrclk", 251 + }; 252 + 253 + static const struct clk_muxing_soc_desc kirkwood_mux_desc[] __initconst = { 254 + { "powersave", powersave_parents, ARRAY_SIZE(powersave_parents), 255 + 11, 1, 0 }, 256 + }; 257 + 258 + #define to_clk_mux(_hw) container_of(_hw, struct clk_mux, hw) 259 + 260 + static struct clk *clk_muxing_get_src( 261 + struct of_phandle_args *clkspec, void *data) 262 + { 263 + struct clk_muxing_ctrl *ctrl = (struct clk_muxing_ctrl *)data; 264 + int n; 265 + 266 + if (clkspec->args_count < 1) 267 + return ERR_PTR(-EINVAL); 268 + 269 + for (n = 0; n < ctrl->num_muxes; n++) { 270 + struct clk_mux *mux = 271 + to_clk_mux(__clk_get_hw(ctrl->muxes[n])); 272 + if (clkspec->args[0] == mux->shift) 273 + return ctrl->muxes[n]; 274 + } 275 + return ERR_PTR(-ENODEV); 276 + } 277 + 278 + static void __init kirkwood_clk_muxing_setup(struct device_node *np, 279 + const struct clk_muxing_soc_desc *desc) 280 + { 281 + struct clk_muxing_ctrl *ctrl; 282 + void __iomem *base; 283 + int n; 284 + 285 + base = of_iomap(np, 0); 286 + if (WARN_ON(!base)) 287 + return; 288 + 289 + ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL); 290 + if (WARN_ON(!ctrl)) 291 + goto ctrl_out; 292 + 293 + /* lock must already be initialized */ 294 + ctrl->lock = &ctrl_gating_lock; 295 + 296 + /* Count, allocate, and register clock muxes */ 297 + for (n = 0; desc[n].name;) 298 + n++; 299 + 300 + ctrl->num_muxes = n; 301 + ctrl->muxes = kcalloc(ctrl->num_muxes, sizeof(struct clk *), 302 + GFP_KERNEL); 303 + if (WARN_ON(!ctrl->muxes)) 304 + goto muxes_out; 305 + 306 + for (n = 0; n < ctrl->num_muxes; n++) { 307 + ctrl->muxes[n] = clk_register_mux(NULL, desc[n].name, 308 + desc[n].parents, desc[n].num_parents, 309 + desc[n].flags, base, desc[n].shift, 310 + desc[n].width, desc[n].flags, ctrl->lock); 311 + WARN_ON(IS_ERR(ctrl->muxes[n])); 312 + } 313 + 314 + of_clk_add_provider(np, clk_muxing_get_src, ctrl); 315 + 316 + return; 317 + muxes_out: 318 + kfree(ctrl); 319 + ctrl_out: 320 + iounmap(base); 321 + } 228 322 229 323 static void __init kirkwood_clk_init(struct device_node *np) 230 324 { ··· 332 236 else 333 237 mvebu_coreclk_setup(np, &kirkwood_coreclks); 334 238 335 - if (cgnp) 239 + if (cgnp) { 336 240 mvebu_clk_gating_setup(cgnp, kirkwood_gating_desc); 241 + kirkwood_clk_muxing_setup(cgnp, kirkwood_mux_desc); 242 + } 337 243 } 338 244 CLK_OF_DECLARE(kirkwood_clk, "marvell,kirkwood-core-clock", 339 245 kirkwood_clk_init);
+2
drivers/clk/pxa/Makefile
··· 1 + obj-y += clk-pxa.o 2 + obj-$(CONFIG_PXA27x) += clk-pxa27x.o
+97
drivers/clk/pxa/clk-pxa.c
··· 1 + /* 2 + * Marvell PXA family clocks 3 + * 4 + * Copyright (C) 2014 Robert Jarzmik 5 + * 6 + * Common clock code for PXA clocks ("CKEN" type clocks + DT) 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.h> 14 + #include <linux/clk-provider.h> 15 + #include <linux/clkdev.h> 16 + #include <linux/of.h> 17 + 18 + #include <dt-bindings/clock/pxa-clock.h> 19 + #include "clk-pxa.h" 20 + 21 + DEFINE_SPINLOCK(lock); 22 + 23 + static struct clk *pxa_clocks[CLK_MAX]; 24 + static struct clk_onecell_data onecell_data = { 25 + .clks = pxa_clocks, 26 + .clk_num = CLK_MAX, 27 + }; 28 + 29 + #define to_pxa_clk(_hw) container_of(_hw, struct pxa_clk_cken, hw) 30 + 31 + static unsigned long cken_recalc_rate(struct clk_hw *hw, 32 + unsigned long parent_rate) 33 + { 34 + struct pxa_clk_cken *pclk = to_pxa_clk(hw); 35 + struct clk_fixed_factor *fix; 36 + 37 + if (!pclk->is_in_low_power || pclk->is_in_low_power()) 38 + fix = &pclk->lp; 39 + else 40 + fix = &pclk->hp; 41 + fix->hw.clk = hw->clk; 42 + return clk_fixed_factor_ops.recalc_rate(&fix->hw, parent_rate); 43 + } 44 + 45 + static struct clk_ops cken_rate_ops = { 46 + .recalc_rate = cken_recalc_rate, 47 + }; 48 + 49 + static u8 cken_get_parent(struct clk_hw *hw) 50 + { 51 + struct pxa_clk_cken *pclk = to_pxa_clk(hw); 52 + 53 + if (!pclk->is_in_low_power) 54 + return 0; 55 + return pclk->is_in_low_power() ? 0 : 1; 56 + } 57 + 58 + static struct clk_ops cken_mux_ops = { 59 + .get_parent = cken_get_parent, 60 + .set_parent = dummy_clk_set_parent, 61 + }; 62 + 63 + void __init clkdev_pxa_register(int ckid, const char *con_id, 64 + const char *dev_id, struct clk *clk) 65 + { 66 + if (!IS_ERR(clk) && (ckid != CLK_NONE)) 67 + pxa_clocks[ckid] = clk; 68 + if (!IS_ERR(clk)) 69 + clk_register_clkdev(clk, con_id, dev_id); 70 + } 71 + 72 + int __init clk_pxa_cken_init(struct pxa_clk_cken *clks, int nb_clks) 73 + { 74 + int i; 75 + struct pxa_clk_cken *pclk; 76 + struct clk *clk; 77 + 78 + for (i = 0; i < nb_clks; i++) { 79 + pclk = clks + i; 80 + pclk->gate.lock = &lock; 81 + clk = clk_register_composite(NULL, pclk->name, 82 + pclk->parent_names, 2, 83 + &pclk->hw, &cken_mux_ops, 84 + &pclk->hw, &cken_rate_ops, 85 + &pclk->gate.hw, &clk_gate_ops, 86 + pclk->flags); 87 + clkdev_pxa_register(pclk->ckid, pclk->con_id, pclk->dev_id, 88 + clk); 89 + } 90 + return 0; 91 + } 92 + 93 + static void __init pxa_dt_clocks_init(struct device_node *np) 94 + { 95 + of_clk_add_provider(np, of_clk_src_onecell_get, &onecell_data); 96 + } 97 + CLK_OF_DECLARE(pxa_clks, "marvell,pxa-clocks", pxa_dt_clocks_init);
+107
drivers/clk/pxa/clk-pxa.h
··· 1 + /* 2 + * Marvell PXA family clocks 3 + * 4 + * Copyright (C) 2014 Robert Jarzmik 5 + * 6 + * Common clock code for PXA clocks ("CKEN" type clocks + DT) 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 + #ifndef _CLK_PXA_ 14 + #define _CLK_PXA_ 15 + 16 + #define PARENTS(name) \ 17 + static const char *name ## _parents[] __initconst 18 + #define MUX_RO_RATE_RO_OPS(name, clk_name) \ 19 + static struct clk_hw name ## _mux_hw; \ 20 + static struct clk_hw name ## _rate_hw; \ 21 + static struct clk_ops name ## _mux_ops = { \ 22 + .get_parent = name ## _get_parent, \ 23 + .set_parent = dummy_clk_set_parent, \ 24 + }; \ 25 + static struct clk_ops name ## _rate_ops = { \ 26 + .recalc_rate = name ## _get_rate, \ 27 + }; \ 28 + static struct clk *clk_register_ ## name(void) \ 29 + { \ 30 + return clk_register_composite(NULL, clk_name, \ 31 + name ## _parents, \ 32 + ARRAY_SIZE(name ## _parents), \ 33 + &name ## _mux_hw, &name ## _mux_ops, \ 34 + &name ## _rate_hw, &name ## _rate_ops, \ 35 + NULL, NULL, CLK_GET_RATE_NOCACHE); \ 36 + } 37 + 38 + #define RATE_RO_OPS(name, clk_name) \ 39 + static struct clk_hw name ## _rate_hw; \ 40 + static struct clk_ops name ## _rate_ops = { \ 41 + .recalc_rate = name ## _get_rate, \ 42 + }; \ 43 + static struct clk *clk_register_ ## name(void) \ 44 + { \ 45 + return clk_register_composite(NULL, clk_name, \ 46 + name ## _parents, \ 47 + ARRAY_SIZE(name ## _parents), \ 48 + NULL, NULL, \ 49 + &name ## _rate_hw, &name ## _rate_ops, \ 50 + NULL, NULL, CLK_GET_RATE_NOCACHE); \ 51 + } 52 + 53 + /* 54 + * CKEN clock type 55 + * This clock takes it source from 2 possible parents : 56 + * - a low power parent 57 + * - a normal parent 58 + * 59 + * +------------+ +-----------+ 60 + * | Low Power | --- | x mult_lp | 61 + * | Clock | | / div_lp |\ 62 + * +------------+ +-----------+ \+-----+ +-----------+ 63 + * | Mux |---| CKEN gate | 64 + * +------------+ +-----------+ /+-----+ +-----------+ 65 + * | High Power | | x mult_hp |/ 66 + * | Clock | --- | / div_hp | 67 + * +------------+ +-----------+ 68 + */ 69 + struct pxa_clk_cken { 70 + struct clk_hw hw; 71 + int ckid; 72 + const char *name; 73 + const char *dev_id; 74 + const char *con_id; 75 + const char **parent_names; 76 + struct clk_fixed_factor lp; 77 + struct clk_fixed_factor hp; 78 + struct clk_gate gate; 79 + bool (*is_in_low_power)(void); 80 + const unsigned long flags; 81 + }; 82 + 83 + #define PXA_CKEN(_dev_id, _con_id, _name, parents, _mult_lp, _div_lp, \ 84 + _mult_hp, _div_hp, is_lp, _cken_reg, _cken_bit, flag) \ 85 + { .ckid = CLK_ ## _name, .name = #_name, \ 86 + .dev_id = _dev_id, .con_id = _con_id, .parent_names = parents,\ 87 + .lp = { .mult = _mult_lp, .div = _div_lp }, \ 88 + .hp = { .mult = _mult_hp, .div = _div_hp }, \ 89 + .is_in_low_power = is_lp, \ 90 + .gate = { .reg = (void __iomem *)_cken_reg, .bit_idx = _cken_bit }, \ 91 + .flags = flag, \ 92 + } 93 + #define PXA_CKEN_1RATE(dev_id, con_id, name, parents, cken_reg, \ 94 + cken_bit, flag) \ 95 + PXA_CKEN(dev_id, con_id, name, parents, 1, 1, 1, 1, \ 96 + NULL, cken_reg, cken_bit, flag) 97 + 98 + static int dummy_clk_set_parent(struct clk_hw *hw, u8 index) 99 + { 100 + return 0; 101 + } 102 + 103 + extern void clkdev_pxa_register(int ckid, const char *con_id, 104 + const char *dev_id, struct clk *clk); 105 + extern int clk_pxa_cken_init(struct pxa_clk_cken *clks, int nb_clks); 106 + 107 + #endif
+370
drivers/clk/pxa/clk-pxa27x.c
··· 1 + /* 2 + * Marvell PXA27x family clocks 3 + * 4 + * Copyright (C) 2014 Robert Jarzmik 5 + * 6 + * Heavily inspired from former arch/arm/mach-pxa/clock.c. 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 <mach/pxa2xx-regs.h> 15 + #include <linux/io.h> 16 + #include <linux/clk.h> 17 + #include <linux/clkdev.h> 18 + #include <linux/of.h> 19 + 20 + #include <dt-bindings/clock/pxa-clock.h> 21 + #include "clk-pxa.h" 22 + 23 + #define KHz 1000 24 + #define MHz (1000 * 1000) 25 + 26 + enum { 27 + PXA_CORE_13Mhz = 0, 28 + PXA_CORE_RUN, 29 + PXA_CORE_TURBO, 30 + }; 31 + 32 + enum { 33 + PXA_BUS_13Mhz = 0, 34 + PXA_BUS_RUN, 35 + }; 36 + 37 + enum { 38 + PXA_LCD_13Mhz = 0, 39 + PXA_LCD_RUN, 40 + }; 41 + 42 + enum { 43 + PXA_MEM_13Mhz = 0, 44 + PXA_MEM_SYSTEM_BUS, 45 + PXA_MEM_RUN, 46 + }; 47 + 48 + static const char * const get_freq_khz[] = { 49 + "core", "run", "cpll", "memory", 50 + "system_bus" 51 + }; 52 + 53 + /* 54 + * Get the clock frequency as reflected by CCSR and the turbo flag. 55 + * We assume these values have been applied via a fcs. 56 + * If info is not 0 we also display the current settings. 57 + */ 58 + unsigned int pxa27x_get_clk_frequency_khz(int info) 59 + { 60 + struct clk *clk; 61 + unsigned long clks[5]; 62 + int i; 63 + 64 + for (i = 0; i < 5; i++) { 65 + clk = clk_get(NULL, get_freq_khz[i]); 66 + if (IS_ERR(clk)) { 67 + clks[i] = 0; 68 + } else { 69 + clks[i] = clk_get_rate(clk); 70 + clk_put(clk); 71 + } 72 + } 73 + if (info) { 74 + pr_info("Run Mode clock: %ld.%02ldMHz\n", 75 + clks[1] / 1000000, (clks[1] % 1000000) / 10000); 76 + pr_info("Turbo Mode clock: %ld.%02ldMHz\n", 77 + clks[2] / 1000000, (clks[2] % 1000000) / 10000); 78 + pr_info("Memory clock: %ld.%02ldMHz\n", 79 + clks[3] / 1000000, (clks[3] % 1000000) / 10000); 80 + pr_info("System bus clock: %ld.%02ldMHz\n", 81 + clks[4] / 1000000, (clks[4] % 1000000) / 10000); 82 + } 83 + return (unsigned int)clks[0]; 84 + } 85 + 86 + bool pxa27x_is_ppll_disabled(void) 87 + { 88 + unsigned long ccsr = CCSR; 89 + 90 + return ccsr & (1 << CCCR_PPDIS_BIT); 91 + } 92 + 93 + #define PXA27X_CKEN(dev_id, con_id, parents, mult_hp, div_hp, \ 94 + bit, is_lp, flags) \ 95 + PXA_CKEN(dev_id, con_id, bit, parents, 1, 1, mult_hp, div_hp, \ 96 + is_lp, &CKEN, CKEN_ ## bit, flags) 97 + #define PXA27X_PBUS_CKEN(dev_id, con_id, bit, mult_hp, div_hp, delay) \ 98 + PXA27X_CKEN(dev_id, con_id, pxa27x_pbus_parents, mult_hp, \ 99 + div_hp, bit, pxa27x_is_ppll_disabled, 0) 100 + 101 + PARENTS(pxa27x_pbus) = { "osc_13mhz", "ppll_312mhz" }; 102 + PARENTS(pxa27x_sbus) = { "system_bus", "system_bus" }; 103 + PARENTS(pxa27x_32Mhz_bus) = { "osc_32_768khz", "osc_32_768khz" }; 104 + PARENTS(pxa27x_lcd_bus) = { "lcd_base", "lcd_base" }; 105 + PARENTS(pxa27x_membus) = { "lcd_base", "lcd_base" }; 106 + 107 + #define PXA27X_CKEN_1RATE(dev_id, con_id, bit, parents, delay) \ 108 + PXA_CKEN_1RATE(dev_id, con_id, bit, parents, \ 109 + &CKEN, CKEN_ ## bit, 0) 110 + #define PXA27X_CKEN_1RATE_AO(dev_id, con_id, bit, parents, delay) \ 111 + PXA_CKEN_1RATE(dev_id, con_id, bit, parents, \ 112 + &CKEN, CKEN_ ## bit, CLK_IGNORE_UNUSED) 113 + 114 + static struct pxa_clk_cken pxa27x_clocks[] = { 115 + PXA27X_PBUS_CKEN("pxa2xx-uart.0", NULL, FFUART, 2, 42, 1), 116 + PXA27X_PBUS_CKEN("pxa2xx-uart.1", NULL, BTUART, 2, 42, 1), 117 + PXA27X_PBUS_CKEN("pxa2xx-uart.2", NULL, STUART, 2, 42, 1), 118 + PXA27X_PBUS_CKEN("pxa2xx-i2s", NULL, I2S, 2, 51, 0), 119 + PXA27X_PBUS_CKEN("pxa2xx-i2c.0", NULL, I2C, 2, 19, 0), 120 + PXA27X_PBUS_CKEN("pxa27x-udc", NULL, USB, 2, 13, 5), 121 + PXA27X_PBUS_CKEN("pxa2xx-mci.0", NULL, MMC, 2, 32, 0), 122 + PXA27X_PBUS_CKEN("pxa2xx-ir", "FICPCLK", FICP, 2, 13, 0), 123 + PXA27X_PBUS_CKEN("pxa27x-ohci", NULL, USBHOST, 2, 13, 0), 124 + PXA27X_PBUS_CKEN("pxa2xx-i2c.1", NULL, PWRI2C, 1, 24, 0), 125 + PXA27X_PBUS_CKEN("pxa27x-ssp.0", NULL, SSP1, 1, 24, 0), 126 + PXA27X_PBUS_CKEN("pxa27x-ssp.1", NULL, SSP2, 1, 24, 0), 127 + PXA27X_PBUS_CKEN("pxa27x-ssp.2", NULL, SSP3, 1, 24, 0), 128 + PXA27X_PBUS_CKEN("pxa27x-pwm.0", NULL, PWM0, 1, 24, 0), 129 + PXA27X_PBUS_CKEN("pxa27x-pwm.1", NULL, PWM1, 1, 24, 0), 130 + PXA27X_PBUS_CKEN(NULL, "MSLCLK", MSL, 2, 13, 0), 131 + PXA27X_PBUS_CKEN(NULL, "USIMCLK", USIM, 2, 13, 0), 132 + PXA27X_PBUS_CKEN(NULL, "MSTKCLK", MEMSTK, 2, 32, 0), 133 + PXA27X_PBUS_CKEN(NULL, "AC97CLK", AC97, 1, 1, 0), 134 + PXA27X_PBUS_CKEN(NULL, "AC97CONFCLK", AC97CONF, 1, 1, 0), 135 + PXA27X_PBUS_CKEN(NULL, "OSTIMER0", OSTIMER, 1, 96, 0), 136 + 137 + PXA27X_CKEN_1RATE("pxa27x-keypad", NULL, KEYPAD, 138 + pxa27x_32Mhz_bus_parents, 0), 139 + PXA27X_CKEN_1RATE(NULL, "IMCLK", IM, pxa27x_sbus_parents, 0), 140 + PXA27X_CKEN_1RATE("pxa2xx-fb", NULL, LCD, pxa27x_lcd_bus_parents, 0), 141 + PXA27X_CKEN_1RATE("pxa27x-camera.0", NULL, CAMERA, 142 + pxa27x_lcd_bus_parents, 0), 143 + PXA27X_CKEN_1RATE_AO("pxa2xx-pcmcia", NULL, MEMC, 144 + pxa27x_membus_parents, 0), 145 + 146 + }; 147 + 148 + static unsigned long clk_pxa27x_cpll_get_rate(struct clk_hw *hw, 149 + unsigned long parent_rate) 150 + { 151 + unsigned long clkcfg; 152 + unsigned int t, ht; 153 + unsigned int l, L, n2, N; 154 + unsigned long ccsr = CCSR; 155 + 156 + asm("mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg)); 157 + t = clkcfg & (1 << 0); 158 + ht = clkcfg & (1 << 2); 159 + 160 + l = ccsr & CCSR_L_MASK; 161 + n2 = (ccsr & CCSR_N2_MASK) >> CCSR_N2_SHIFT; 162 + L = l * parent_rate; 163 + N = (L * n2) / 2; 164 + 165 + return t ? N : L; 166 + } 167 + PARENTS(clk_pxa27x_cpll) = { "osc_13mhz" }; 168 + RATE_RO_OPS(clk_pxa27x_cpll, "cpll"); 169 + 170 + static unsigned long clk_pxa27x_lcd_base_get_rate(struct clk_hw *hw, 171 + unsigned long parent_rate) 172 + { 173 + unsigned int l, osc_forced; 174 + unsigned long ccsr = CCSR; 175 + unsigned long cccr = CCCR; 176 + 177 + l = ccsr & CCSR_L_MASK; 178 + osc_forced = ccsr & (1 << CCCR_CPDIS_BIT); 179 + if (osc_forced) { 180 + if (cccr & (1 << CCCR_LCD_26_BIT)) 181 + return parent_rate * 2; 182 + else 183 + return parent_rate; 184 + } 185 + 186 + if (l <= 7) 187 + return parent_rate; 188 + if (l <= 16) 189 + return parent_rate / 2; 190 + return parent_rate / 4; 191 + } 192 + 193 + static u8 clk_pxa27x_lcd_base_get_parent(struct clk_hw *hw) 194 + { 195 + unsigned int osc_forced; 196 + unsigned long ccsr = CCSR; 197 + 198 + osc_forced = ccsr & (1 << CCCR_CPDIS_BIT); 199 + if (osc_forced) 200 + return PXA_LCD_13Mhz; 201 + else 202 + return PXA_LCD_RUN; 203 + } 204 + 205 + PARENTS(clk_pxa27x_lcd_base) = { "osc_13mhz", "run" }; 206 + MUX_RO_RATE_RO_OPS(clk_pxa27x_lcd_base, "lcd_base"); 207 + 208 + static void __init pxa27x_register_plls(void) 209 + { 210 + clk_register_fixed_rate(NULL, "osc_13mhz", NULL, 211 + CLK_GET_RATE_NOCACHE | CLK_IS_ROOT, 212 + 13 * MHz); 213 + clk_register_fixed_rate(NULL, "osc_32_768khz", NULL, 214 + CLK_GET_RATE_NOCACHE | CLK_IS_ROOT, 215 + 32768 * KHz); 216 + clk_register_fixed_rate(NULL, "clk_dummy", NULL, CLK_IS_ROOT, 0); 217 + clk_register_fixed_factor(NULL, "ppll_312mhz", "osc_13mhz", 0, 24, 1); 218 + } 219 + 220 + static unsigned long clk_pxa27x_core_get_rate(struct clk_hw *hw, 221 + unsigned long parent_rate) 222 + { 223 + unsigned long clkcfg; 224 + unsigned int t, ht, b, osc_forced; 225 + unsigned long ccsr = CCSR; 226 + 227 + osc_forced = ccsr & (1 << CCCR_CPDIS_BIT); 228 + asm("mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg)); 229 + t = clkcfg & (1 << 0); 230 + ht = clkcfg & (1 << 2); 231 + b = clkcfg & (1 << 3); 232 + 233 + if (osc_forced) 234 + return parent_rate; 235 + if (ht) 236 + return parent_rate / 2; 237 + else 238 + return parent_rate; 239 + } 240 + 241 + static u8 clk_pxa27x_core_get_parent(struct clk_hw *hw) 242 + { 243 + unsigned long clkcfg; 244 + unsigned int t, ht, b, osc_forced; 245 + unsigned long ccsr = CCSR; 246 + 247 + osc_forced = ccsr & (1 << CCCR_CPDIS_BIT); 248 + if (osc_forced) 249 + return PXA_CORE_13Mhz; 250 + 251 + asm("mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg)); 252 + t = clkcfg & (1 << 0); 253 + ht = clkcfg & (1 << 2); 254 + b = clkcfg & (1 << 3); 255 + 256 + if (ht || t) 257 + return PXA_CORE_TURBO; 258 + return PXA_CORE_RUN; 259 + } 260 + PARENTS(clk_pxa27x_core) = { "osc_13mhz", "run", "cpll" }; 261 + MUX_RO_RATE_RO_OPS(clk_pxa27x_core, "core"); 262 + 263 + static unsigned long clk_pxa27x_run_get_rate(struct clk_hw *hw, 264 + unsigned long parent_rate) 265 + { 266 + unsigned long ccsr = CCSR; 267 + unsigned int n2 = (ccsr & CCSR_N2_MASK) >> CCSR_N2_SHIFT; 268 + 269 + return (parent_rate / n2) * 2; 270 + } 271 + PARENTS(clk_pxa27x_run) = { "cpll" }; 272 + RATE_RO_OPS(clk_pxa27x_run, "run"); 273 + 274 + static void __init pxa27x_register_core(void) 275 + { 276 + clk_register_clk_pxa27x_cpll(); 277 + clk_register_clk_pxa27x_run(); 278 + 279 + clkdev_pxa_register(CLK_CORE, "core", NULL, 280 + clk_register_clk_pxa27x_core()); 281 + } 282 + 283 + static unsigned long clk_pxa27x_system_bus_get_rate(struct clk_hw *hw, 284 + unsigned long parent_rate) 285 + { 286 + unsigned long clkcfg; 287 + unsigned int b, osc_forced; 288 + unsigned long ccsr = CCSR; 289 + 290 + osc_forced = ccsr & (1 << CCCR_CPDIS_BIT); 291 + asm("mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg)); 292 + b = clkcfg & (1 << 3); 293 + 294 + if (osc_forced) 295 + return parent_rate; 296 + if (b) 297 + return parent_rate / 2; 298 + else 299 + return parent_rate; 300 + } 301 + 302 + static u8 clk_pxa27x_system_bus_get_parent(struct clk_hw *hw) 303 + { 304 + unsigned int osc_forced; 305 + unsigned long ccsr = CCSR; 306 + 307 + osc_forced = ccsr & (1 << CCCR_CPDIS_BIT); 308 + if (osc_forced) 309 + return PXA_BUS_13Mhz; 310 + else 311 + return PXA_BUS_RUN; 312 + } 313 + 314 + PARENTS(clk_pxa27x_system_bus) = { "osc_13mhz", "run" }; 315 + MUX_RO_RATE_RO_OPS(clk_pxa27x_system_bus, "system_bus"); 316 + 317 + static unsigned long clk_pxa27x_memory_get_rate(struct clk_hw *hw, 318 + unsigned long parent_rate) 319 + { 320 + unsigned int a, l, osc_forced; 321 + unsigned long cccr = CCCR; 322 + unsigned long ccsr = CCSR; 323 + 324 + osc_forced = ccsr & (1 << CCCR_CPDIS_BIT); 325 + a = cccr & CCCR_A_BIT; 326 + l = ccsr & CCSR_L_MASK; 327 + 328 + if (osc_forced || a) 329 + return parent_rate; 330 + if (l <= 10) 331 + return parent_rate; 332 + if (l <= 20) 333 + return parent_rate / 2; 334 + return parent_rate / 4; 335 + } 336 + 337 + static u8 clk_pxa27x_memory_get_parent(struct clk_hw *hw) 338 + { 339 + unsigned int osc_forced, a; 340 + unsigned long cccr = CCCR; 341 + unsigned long ccsr = CCSR; 342 + 343 + osc_forced = ccsr & (1 << CCCR_CPDIS_BIT); 344 + a = cccr & CCCR_A_BIT; 345 + if (osc_forced) 346 + return PXA_MEM_13Mhz; 347 + if (a) 348 + return PXA_MEM_SYSTEM_BUS; 349 + else 350 + return PXA_MEM_RUN; 351 + } 352 + 353 + PARENTS(clk_pxa27x_memory) = { "osc_13mhz", "system_bus", "run" }; 354 + MUX_RO_RATE_RO_OPS(clk_pxa27x_memory, "memory"); 355 + 356 + static void __init pxa27x_base_clocks_init(void) 357 + { 358 + pxa27x_register_plls(); 359 + pxa27x_register_core(); 360 + clk_register_clk_pxa27x_system_bus(); 361 + clk_register_clk_pxa27x_memory(); 362 + clk_register_clk_pxa27x_lcd_base(); 363 + } 364 + 365 + static int __init pxa27x_clocks_init(void) 366 + { 367 + pxa27x_base_clocks_init(); 368 + return clk_pxa_cken_init(pxa27x_clocks, ARRAY_SIZE(pxa27x_clocks)); 369 + } 370 + postcore_initcall(pxa27x_clocks_init);
+67 -1
drivers/clk/qcom/clk-pll.c
··· 97 97 clk_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) 98 98 { 99 99 struct clk_pll *pll = to_clk_pll(hw); 100 - u32 l, m, n; 100 + u32 l, m, n, config; 101 101 unsigned long rate; 102 102 u64 tmp; 103 103 ··· 116 116 do_div(tmp, n); 117 117 rate += tmp; 118 118 } 119 + if (pll->post_div_width) { 120 + regmap_read(pll->clkr.regmap, pll->config_reg, &config); 121 + config >>= pll->post_div_shift; 122 + config &= BIT(pll->post_div_width) - 1; 123 + rate /= config + 1; 124 + } 125 + 119 126 return rate; 127 + } 128 + 129 + static const 130 + struct pll_freq_tbl *find_freq(const struct pll_freq_tbl *f, unsigned long rate) 131 + { 132 + if (!f) 133 + return NULL; 134 + 135 + for (; f->freq; f++) 136 + if (rate <= f->freq) 137 + return f; 138 + 139 + return NULL; 140 + } 141 + 142 + static long 143 + clk_pll_determine_rate(struct clk_hw *hw, unsigned long rate, 144 + unsigned long *p_rate, struct clk **p) 145 + { 146 + struct clk_pll *pll = to_clk_pll(hw); 147 + const struct pll_freq_tbl *f; 148 + 149 + f = find_freq(pll->freq_tbl, rate); 150 + if (!f) 151 + return clk_pll_recalc_rate(hw, *p_rate); 152 + 153 + return f->freq; 154 + } 155 + 156 + static int 157 + clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long p_rate) 158 + { 159 + struct clk_pll *pll = to_clk_pll(hw); 160 + const struct pll_freq_tbl *f; 161 + bool enabled; 162 + u32 mode; 163 + u32 enable_mask = PLL_OUTCTRL | PLL_BYPASSNL | PLL_RESET_N; 164 + 165 + f = find_freq(pll->freq_tbl, rate); 166 + if (!f) 167 + return -EINVAL; 168 + 169 + regmap_read(pll->clkr.regmap, pll->mode_reg, &mode); 170 + enabled = (mode & enable_mask) == enable_mask; 171 + 172 + if (enabled) 173 + clk_pll_disable(hw); 174 + 175 + regmap_update_bits(pll->clkr.regmap, pll->l_reg, 0x3ff, f->l); 176 + regmap_update_bits(pll->clkr.regmap, pll->m_reg, 0x7ffff, f->m); 177 + regmap_update_bits(pll->clkr.regmap, pll->n_reg, 0x7ffff, f->n); 178 + regmap_write(pll->clkr.regmap, pll->config_reg, f->ibits); 179 + 180 + if (enabled) 181 + clk_pll_enable(hw); 182 + 183 + return 0; 120 184 } 121 185 122 186 const struct clk_ops clk_pll_ops = { 123 187 .enable = clk_pll_enable, 124 188 .disable = clk_pll_disable, 125 189 .recalc_rate = clk_pll_recalc_rate, 190 + .determine_rate = clk_pll_determine_rate, 191 + .set_rate = clk_pll_set_rate, 126 192 }; 127 193 EXPORT_SYMBOL_GPL(clk_pll_ops); 128 194
+20
drivers/clk/qcom/clk-pll.h
··· 18 18 #include "clk-regmap.h" 19 19 20 20 /** 21 + * struct pll_freq_tbl - PLL frequency table 22 + * @l: L value 23 + * @m: M value 24 + * @n: N value 25 + * @ibits: internal values 26 + */ 27 + struct pll_freq_tbl { 28 + unsigned long freq; 29 + u16 l; 30 + u16 m; 31 + u16 n; 32 + u32 ibits; 33 + }; 34 + 35 + /** 21 36 * struct clk_pll - phase locked loop (PLL) 22 37 * @l_reg: L register 23 38 * @m_reg: M register ··· 41 26 * @mode_reg: mode register 42 27 * @status_reg: status register 43 28 * @status_bit: ANDed with @status_reg to determine if PLL is enabled 29 + * @freq_tbl: PLL frequency table 44 30 * @hw: handle between common and hardware-specific interfaces 45 31 */ 46 32 struct clk_pll { ··· 52 36 u32 mode_reg; 53 37 u32 status_reg; 54 38 u8 status_bit; 39 + u8 post_div_width; 40 + u8 post_div_shift; 41 + 42 + const struct pll_freq_tbl *freq_tbl; 55 43 56 44 struct clk_regmap clkr; 57 45 };
+54 -61
drivers/clk/qcom/clk-rcg.c
··· 21 21 #include <asm/div64.h> 22 22 23 23 #include "clk-rcg.h" 24 + #include "common.h" 24 25 25 26 static u32 ns_to_src(struct src_sel *s, u32 ns) 26 27 { ··· 68 67 { 69 68 struct clk_dyn_rcg *rcg = to_clk_dyn_rcg(hw); 70 69 int num_parents = __clk_get_num_parents(hw->clk); 71 - u32 ns, ctl; 70 + u32 ns, reg; 72 71 int bank; 73 72 int i; 74 73 struct src_sel *s; 75 74 76 - regmap_read(rcg->clkr.regmap, rcg->clkr.enable_reg, &ctl); 77 - bank = reg_to_bank(rcg, ctl); 75 + regmap_read(rcg->clkr.regmap, rcg->bank_reg, &reg); 76 + bank = reg_to_bank(rcg, reg); 78 77 s = &rcg->s[bank]; 79 78 80 - regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns); 79 + regmap_read(rcg->clkr.regmap, rcg->ns_reg[bank], &ns); 81 80 ns = ns_to_src(s, ns); 82 81 83 82 for (i = 0; i < num_parents; i++) ··· 193 192 194 193 static void configure_bank(struct clk_dyn_rcg *rcg, const struct freq_tbl *f) 195 194 { 196 - u32 ns, md, ctl, *regp; 195 + u32 ns, md, reg; 197 196 int bank, new_bank; 198 197 struct mn *mn; 199 198 struct pre_div *p; 200 199 struct src_sel *s; 201 200 bool enabled; 202 - u32 md_reg; 203 - u32 bank_reg; 201 + u32 md_reg, ns_reg; 204 202 bool banked_mn = !!rcg->mn[1].width; 203 + bool banked_p = !!rcg->p[1].pre_div_width; 205 204 struct clk_hw *hw = &rcg->clkr.hw; 206 205 207 206 enabled = __clk_is_enabled(hw->clk); 208 207 209 - regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns); 210 - regmap_read(rcg->clkr.regmap, rcg->clkr.enable_reg, &ctl); 211 - 212 - if (banked_mn) { 213 - regp = &ctl; 214 - bank_reg = rcg->clkr.enable_reg; 215 - } else { 216 - regp = &ns; 217 - bank_reg = rcg->ns_reg; 218 - } 219 - 220 - bank = reg_to_bank(rcg, *regp); 208 + regmap_read(rcg->clkr.regmap, rcg->bank_reg, &reg); 209 + bank = reg_to_bank(rcg, reg); 221 210 new_bank = enabled ? !bank : bank; 211 + 212 + ns_reg = rcg->ns_reg[new_bank]; 213 + regmap_read(rcg->clkr.regmap, ns_reg, &ns); 222 214 223 215 if (banked_mn) { 224 216 mn = &rcg->mn[new_bank]; 225 217 md_reg = rcg->md_reg[new_bank]; 226 218 227 219 ns |= BIT(mn->mnctr_reset_bit); 228 - regmap_write(rcg->clkr.regmap, rcg->ns_reg, ns); 220 + regmap_write(rcg->clkr.regmap, ns_reg, ns); 229 221 230 222 regmap_read(rcg->clkr.regmap, md_reg, &md); 231 223 md = mn_to_md(mn, f->m, f->n, md); 232 224 regmap_write(rcg->clkr.regmap, md_reg, md); 233 225 234 226 ns = mn_to_ns(mn, f->m, f->n, ns); 235 - regmap_write(rcg->clkr.regmap, rcg->ns_reg, ns); 227 + regmap_write(rcg->clkr.regmap, ns_reg, ns); 236 228 237 - ctl = mn_to_reg(mn, f->m, f->n, ctl); 238 - regmap_write(rcg->clkr.regmap, rcg->clkr.enable_reg, ctl); 229 + /* Two NS registers means mode control is in NS register */ 230 + if (rcg->ns_reg[0] != rcg->ns_reg[1]) { 231 + ns = mn_to_reg(mn, f->m, f->n, ns); 232 + regmap_write(rcg->clkr.regmap, ns_reg, ns); 233 + } else { 234 + reg = mn_to_reg(mn, f->m, f->n, reg); 235 + regmap_write(rcg->clkr.regmap, rcg->bank_reg, reg); 236 + } 239 237 240 238 ns &= ~BIT(mn->mnctr_reset_bit); 241 - regmap_write(rcg->clkr.regmap, rcg->ns_reg, ns); 242 - } else { 239 + regmap_write(rcg->clkr.regmap, ns_reg, ns); 240 + } 241 + 242 + if (banked_p) { 243 243 p = &rcg->p[new_bank]; 244 244 ns = pre_div_to_ns(p, f->pre_div - 1, ns); 245 245 } 246 246 247 247 s = &rcg->s[new_bank]; 248 248 ns = src_to_ns(s, s->parent_map[f->src], ns); 249 - regmap_write(rcg->clkr.regmap, rcg->ns_reg, ns); 249 + regmap_write(rcg->clkr.regmap, ns_reg, ns); 250 250 251 251 if (enabled) { 252 - *regp ^= BIT(rcg->mux_sel_bit); 253 - regmap_write(rcg->clkr.regmap, bank_reg, *regp); 252 + regmap_read(rcg->clkr.regmap, rcg->bank_reg, &reg); 253 + reg ^= BIT(rcg->mux_sel_bit); 254 + regmap_write(rcg->clkr.regmap, rcg->bank_reg, reg); 254 255 } 255 256 } 256 257 257 258 static int clk_dyn_rcg_set_parent(struct clk_hw *hw, u8 index) 258 259 { 259 260 struct clk_dyn_rcg *rcg = to_clk_dyn_rcg(hw); 260 - u32 ns, ctl, md, reg; 261 + u32 ns, md, reg; 261 262 int bank; 262 263 struct freq_tbl f = { 0 }; 263 264 bool banked_mn = !!rcg->mn[1].width; 265 + bool banked_p = !!rcg->p[1].pre_div_width; 264 266 265 - regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns); 266 - regmap_read(rcg->clkr.regmap, rcg->clkr.enable_reg, &ctl); 267 - reg = banked_mn ? ctl : ns; 268 - 267 + regmap_read(rcg->clkr.regmap, rcg->bank_reg, &reg); 269 268 bank = reg_to_bank(rcg, reg); 269 + 270 + regmap_read(rcg->clkr.regmap, rcg->ns_reg[bank], &ns); 270 271 271 272 if (banked_mn) { 272 273 regmap_read(rcg->clkr.regmap, rcg->md_reg[bank], &md); 273 274 f.m = md_to_m(&rcg->mn[bank], md); 274 275 f.n = ns_m_to_n(&rcg->mn[bank], ns, f.m); 275 - } else { 276 - f.pre_div = ns_to_pre_div(&rcg->p[bank], ns) + 1; 277 276 } 278 - f.src = index; 279 277 278 + if (banked_p) 279 + f.pre_div = ns_to_pre_div(&rcg->p[bank], ns) + 1; 280 + 281 + f.src = index; 280 282 configure_bank(rcg, &f); 281 283 282 284 return 0; ··· 340 336 u32 m, n, pre_div, ns, md, mode, reg; 341 337 int bank; 342 338 struct mn *mn; 339 + bool banked_p = !!rcg->p[1].pre_div_width; 343 340 bool banked_mn = !!rcg->mn[1].width; 344 341 345 - regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns); 346 - 347 - if (banked_mn) 348 - regmap_read(rcg->clkr.regmap, rcg->clkr.enable_reg, &reg); 349 - else 350 - reg = ns; 351 - 342 + regmap_read(rcg->clkr.regmap, rcg->bank_reg, &reg); 352 343 bank = reg_to_bank(rcg, reg); 344 + 345 + regmap_read(rcg->clkr.regmap, rcg->ns_reg[bank], &ns); 346 + m = n = pre_div = mode = 0; 353 347 354 348 if (banked_mn) { 355 349 mn = &rcg->mn[bank]; 356 350 regmap_read(rcg->clkr.regmap, rcg->md_reg[bank], &md); 357 351 m = md_to_m(mn, md); 358 352 n = ns_m_to_n(mn, ns, m); 353 + /* Two NS registers means mode control is in NS register */ 354 + if (rcg->ns_reg[0] != rcg->ns_reg[1]) 355 + reg = ns; 359 356 mode = reg_to_mnctr_mode(mn, reg); 360 - return calc_rate(parent_rate, m, n, mode, 0); 361 - } else { 362 - pre_div = ns_to_pre_div(&rcg->p[bank], ns); 363 - return calc_rate(parent_rate, 0, 0, 0, pre_div); 364 357 } 365 - } 366 358 367 - static const 368 - struct freq_tbl *find_freq(const struct freq_tbl *f, unsigned long rate) 369 - { 370 - if (!f) 371 - return NULL; 359 + if (banked_p) 360 + pre_div = ns_to_pre_div(&rcg->p[bank], ns); 372 361 373 - for (; f->freq; f++) 374 - if (rate <= f->freq) 375 - return f; 376 - 377 - return NULL; 362 + return calc_rate(parent_rate, m, n, mode, pre_div); 378 363 } 379 364 380 365 static long _freq_tbl_determine_rate(struct clk_hw *hw, ··· 372 379 { 373 380 unsigned long clk_flags; 374 381 375 - f = find_freq(f, rate); 382 + f = qcom_find_freq(f, rate); 376 383 if (!f) 377 384 return -EINVAL; 378 385 ··· 470 477 struct clk_rcg *rcg = to_clk_rcg(hw); 471 478 const struct freq_tbl *f; 472 479 473 - f = find_freq(rcg->freq_tbl, rate); 480 + f = qcom_find_freq(rcg->freq_tbl, rate); 474 481 if (!f) 475 482 return -EINVAL; 476 483 ··· 490 497 struct clk_dyn_rcg *rcg = to_clk_dyn_rcg(hw); 491 498 const struct freq_tbl *f; 492 499 493 - f = find_freq(rcg->freq_tbl, rate); 500 + f = qcom_find_freq(rcg->freq_tbl, rate); 494 501 if (!f) 495 502 return -EINVAL; 496 503
+4 -2
drivers/clk/qcom/clk-rcg.h
··· 103 103 * struct clk_dyn_rcg - root clock generator with glitch free mux 104 104 * 105 105 * @mux_sel_bit: bit to switch glitch free mux 106 - * @ns_reg: NS register 106 + * @ns_reg: NS0 and NS1 register 107 107 * @md_reg: MD0 and MD1 register 108 + * @bank_reg: register to XOR @mux_sel_bit into to switch glitch free mux 108 109 * @mn: mn counter (banked) 109 110 * @s: source selector (banked) 110 111 * @freq_tbl: frequency table ··· 114 113 * 115 114 */ 116 115 struct clk_dyn_rcg { 117 - u32 ns_reg; 116 + u32 ns_reg[2]; 118 117 u32 md_reg[2]; 118 + u32 bank_reg; 119 119 120 120 u8 mux_sel_bit; 121 121
+3 -16
drivers/clk/qcom/clk-rcg2.c
··· 24 24 #include <asm/div64.h> 25 25 26 26 #include "clk-rcg.h" 27 + #include "common.h" 27 28 28 29 #define CMD_REG 0x0 29 30 #define CMD_UPDATE BIT(0) ··· 173 172 return calc_rate(parent_rate, m, n, mode, hid_div); 174 173 } 175 174 176 - static const 177 - struct freq_tbl *find_freq(const struct freq_tbl *f, unsigned long rate) 178 - { 179 - if (!f) 180 - return NULL; 181 - 182 - for (; f->freq; f++) 183 - if (rate <= f->freq) 184 - return f; 185 - 186 - /* Default to our fastest rate */ 187 - return f - 1; 188 - } 189 - 190 175 static long _freq_tbl_determine_rate(struct clk_hw *hw, 191 176 const struct freq_tbl *f, unsigned long rate, 192 177 unsigned long *p_rate, struct clk **p) 193 178 { 194 179 unsigned long clk_flags; 195 180 196 - f = find_freq(f, rate); 181 + f = qcom_find_freq(f, rate); 197 182 if (!f) 198 183 return -EINVAL; 199 184 ··· 255 268 struct clk_rcg2 *rcg = to_clk_rcg2(hw); 256 269 const struct freq_tbl *f; 257 270 258 - f = find_freq(rcg->freq_tbl, rate); 271 + f = qcom_find_freq(rcg->freq_tbl, rate); 259 272 if (!f) 260 273 return -EINVAL; 261 274
+16
drivers/clk/qcom/common.c
··· 18 18 #include <linux/reset-controller.h> 19 19 20 20 #include "common.h" 21 + #include "clk-rcg.h" 21 22 #include "clk-regmap.h" 22 23 #include "reset.h" 23 24 ··· 27 26 struct clk_onecell_data data; 28 27 struct clk *clks[]; 29 28 }; 29 + 30 + const 31 + struct freq_tbl *qcom_find_freq(const struct freq_tbl *f, unsigned long rate) 32 + { 33 + if (!f) 34 + return NULL; 35 + 36 + for (; f->freq; f++) 37 + if (rate <= f->freq) 38 + return f; 39 + 40 + /* Default to our fastest rate */ 41 + return f - 1; 42 + } 43 + EXPORT_SYMBOL_GPL(qcom_find_freq); 30 44 31 45 struct regmap * 32 46 qcom_cc_map(struct platform_device *pdev, const struct qcom_cc_desc *desc)
+4
drivers/clk/qcom/common.h
··· 18 18 struct clk_regmap; 19 19 struct qcom_reset_map; 20 20 struct regmap; 21 + struct freq_tbl; 21 22 22 23 struct qcom_cc_desc { 23 24 const struct regmap_config *config; ··· 27 26 const struct qcom_reset_map *resets; 28 27 size_t num_resets; 29 28 }; 29 + 30 + extern const struct freq_tbl *qcom_find_freq(const struct freq_tbl *f, 31 + unsigned long rate); 30 32 31 33 extern struct regmap *qcom_cc_map(struct platform_device *pdev, 32 34 const struct qcom_cc_desc *desc);
+30 -1
drivers/clk/qcom/gcc-ipq806x.c
··· 32 32 #include "clk-branch.h" 33 33 #include "reset.h" 34 34 35 + static struct clk_pll pll0 = { 36 + .l_reg = 0x30c4, 37 + .m_reg = 0x30c8, 38 + .n_reg = 0x30cc, 39 + .config_reg = 0x30d4, 40 + .mode_reg = 0x30c0, 41 + .status_reg = 0x30d8, 42 + .status_bit = 16, 43 + .clkr.hw.init = &(struct clk_init_data){ 44 + .name = "pll0", 45 + .parent_names = (const char *[]){ "pxo" }, 46 + .num_parents = 1, 47 + .ops = &clk_pll_ops, 48 + }, 49 + }; 50 + 51 + static struct clk_regmap pll0_vote = { 52 + .enable_reg = 0x34c0, 53 + .enable_mask = BIT(0), 54 + .hw.init = &(struct clk_init_data){ 55 + .name = "pll0_vote", 56 + .parent_names = (const char *[]){ "pll0" }, 57 + .num_parents = 1, 58 + .ops = &clk_pll_vote_ops, 59 + }, 60 + }; 61 + 35 62 static struct clk_pll pll3 = { 36 63 .l_reg = 0x3164, 37 64 .m_reg = 0x3168, ··· 181 154 static const char *gcc_pxo_pll8_pll0_map[] = { 182 155 "pxo", 183 156 "pll8_vote", 184 - "pll0", 157 + "pll0_vote", 185 158 }; 186 159 187 160 static struct freq_tbl clk_tbl_gsbi_uart[] = { ··· 2160 2133 }; 2161 2134 2162 2135 static struct clk_regmap *gcc_ipq806x_clks[] = { 2136 + [PLL0] = &pll0.clkr, 2137 + [PLL0_VOTE] = &pll0_vote, 2163 2138 [PLL3] = &pll3.clkr, 2164 2139 [PLL8] = &pll8.clkr, 2165 2140 [PLL8_VOTE] = &pll8_vote,
-1
drivers/clk/qcom/mmcc-apq8084.c
··· 3341 3341 .remove = mmcc_apq8084_remove, 3342 3342 .driver = { 3343 3343 .name = "mmcc-apq8084", 3344 - .owner = THIS_MODULE, 3345 3344 .of_match_table = mmcc_apq8084_match_table, 3346 3345 }, 3347 3346 };
+21 -8
drivers/clk/qcom/mmcc-msm8960.c
··· 773 773 }; 774 774 775 775 static struct clk_dyn_rcg gfx2d0_src = { 776 - .ns_reg = 0x0070, 776 + .ns_reg[0] = 0x0070, 777 + .ns_reg[1] = 0x0070, 777 778 .md_reg[0] = 0x0064, 778 779 .md_reg[1] = 0x0068, 780 + .bank_reg = 0x0060, 779 781 .mn[0] = { 780 782 .mnctr_en_bit = 8, 781 783 .mnctr_reset_bit = 25, ··· 833 831 }; 834 832 835 833 static struct clk_dyn_rcg gfx2d1_src = { 836 - .ns_reg = 0x007c, 834 + .ns_reg[0] = 0x007c, 835 + .ns_reg[1] = 0x007c, 837 836 .md_reg[0] = 0x0078, 838 837 .md_reg[1] = 0x006c, 838 + .bank_reg = 0x0074, 839 839 .mn[0] = { 840 840 .mnctr_en_bit = 8, 841 841 .mnctr_reset_bit = 25, ··· 934 930 }; 935 931 936 932 static struct clk_dyn_rcg gfx3d_src = { 937 - .ns_reg = 0x008c, 933 + .ns_reg[0] = 0x008c, 934 + .ns_reg[1] = 0x008c, 938 935 .md_reg[0] = 0x0084, 939 936 .md_reg[1] = 0x0088, 937 + .bank_reg = 0x0080, 940 938 .mn[0] = { 941 939 .mnctr_en_bit = 8, 942 940 .mnctr_reset_bit = 25, ··· 1012 1006 }; 1013 1007 1014 1008 static struct clk_dyn_rcg vcap_src = { 1015 - .ns_reg = 0x021c, 1009 + .ns_reg[0] = 0x021c, 1010 + .ns_reg[1] = 0x021c, 1016 1011 .md_reg[0] = 0x01ec, 1017 1012 .md_reg[1] = 0x0218, 1013 + .bank_reg = 0x0178, 1018 1014 .mn[0] = { 1019 1015 .mnctr_en_bit = 8, 1020 1016 .mnctr_reset_bit = 23, ··· 1219 1211 }; 1220 1212 1221 1213 static struct clk_dyn_rcg mdp_src = { 1222 - .ns_reg = 0x00d0, 1214 + .ns_reg[0] = 0x00d0, 1215 + .ns_reg[1] = 0x00d0, 1223 1216 .md_reg[0] = 0x00c4, 1224 1217 .md_reg[1] = 0x00c8, 1218 + .bank_reg = 0x00c0, 1225 1219 .mn[0] = { 1226 1220 .mnctr_en_bit = 8, 1227 1221 .mnctr_reset_bit = 31, ··· 1328 1318 }; 1329 1319 1330 1320 static struct clk_dyn_rcg rot_src = { 1331 - .ns_reg = 0x00e8, 1321 + .ns_reg[0] = 0x00e8, 1322 + .ns_reg[1] = 0x00e8, 1323 + .bank_reg = 0x00e8, 1332 1324 .p[0] = { 1333 1325 .pre_div_shift = 22, 1334 1326 .pre_div_width = 4, ··· 1554 1542 }; 1555 1543 1556 1544 static struct clk_dyn_rcg vcodec_src = { 1557 - .ns_reg = 0x0100, 1545 + .ns_reg[0] = 0x0100, 1546 + .ns_reg[1] = 0x0100, 1558 1547 .md_reg[0] = 0x00fc, 1559 1548 .md_reg[1] = 0x0128, 1549 + .bank_reg = 0x00f8, 1560 1550 .mn[0] = { 1561 1551 .mnctr_en_bit = 5, 1562 1552 .mnctr_reset_bit = 31, ··· 2693 2679 .remove = mmcc_msm8960_remove, 2694 2680 .driver = { 2695 2681 .name = "mmcc-msm8960", 2696 - .owner = THIS_MODULE, 2697 2682 .of_match_table = mmcc_msm8960_match_table, 2698 2683 }, 2699 2684 };
-1
drivers/clk/qcom/mmcc-msm8974.c
··· 2570 2570 .remove = mmcc_msm8974_remove, 2571 2571 .driver = { 2572 2572 .name = "mmcc-msm8974", 2573 - .owner = THIS_MODULE, 2574 2573 .of_match_table = mmcc_msm8974_match_table, 2575 2574 }, 2576 2575 };
+1
drivers/clk/rockchip/Makefile
··· 5 5 obj-y += clk-rockchip.o 6 6 obj-y += clk.o 7 7 obj-y += clk-pll.o 8 + obj-y += clk-cpu.o 8 9 obj-$(CONFIG_RESET_CONTROLLER) += softrst.o 9 10 10 11 obj-y += clk-rk3188.o
+329
drivers/clk/rockchip/clk-cpu.c
··· 1 + /* 2 + * Copyright (c) 2014 MundoReader S.L. 3 + * Author: Heiko Stuebner <heiko@sntech.de> 4 + * 5 + * based on clk/samsung/clk-cpu.c 6 + * Copyright (c) 2014 Samsung Electronics Co., Ltd. 7 + * Author: Thomas Abraham <thomas.ab@samsung.com> 8 + * 9 + * This program is free software; you can redistribute it and/or modify 10 + * it under the terms of the GNU General Public License version 2 as 11 + * published by the Free Software Foundation. 12 + * 13 + * A CPU clock is defined as a clock supplied to a CPU or a group of CPUs. 14 + * The CPU clock is typically derived from a hierarchy of clock 15 + * blocks which includes mux and divider blocks. There are a number of other 16 + * auxiliary clocks supplied to the CPU domain such as the debug blocks and AXI 17 + * clock for CPU domain. The rates of these auxiliary clocks are related to the 18 + * CPU clock rate and this relation is usually specified in the hardware manual 19 + * of the SoC or supplied after the SoC characterization. 20 + * 21 + * The below implementation of the CPU clock allows the rate changes of the CPU 22 + * clock and the corresponding rate changes of the auxillary clocks of the CPU 23 + * domain. The platform clock driver provides a clock register configuration 24 + * for each configurable rate which is then used to program the clock hardware 25 + * registers to acheive a fast co-oridinated rate change for all the CPU domain 26 + * clocks. 27 + * 28 + * On a rate change request for the CPU clock, the rate change is propagated 29 + * upto the PLL supplying the clock to the CPU domain clock blocks. While the 30 + * CPU domain PLL is reconfigured, the CPU domain clocks are driven using an 31 + * alternate clock source. If required, the alternate clock source is divided 32 + * down in order to keep the output clock rate within the previous OPP limits. 33 + */ 34 + 35 + #include <linux/of.h> 36 + #include <linux/slab.h> 37 + #include <linux/io.h> 38 + #include <linux/clk-provider.h> 39 + #include "clk.h" 40 + 41 + /** 42 + * struct rockchip_cpuclk: information about clock supplied to a CPU core. 43 + * @hw: handle between ccf and cpu clock. 44 + * @alt_parent: alternate parent clock to use when switching the speed 45 + * of the primary parent clock. 46 + * @reg_base: base register for cpu-clock values. 47 + * @clk_nb: clock notifier registered for changes in clock speed of the 48 + * primary parent clock. 49 + * @rate_count: number of rates in the rate_table 50 + * @rate_table: pll-rates and their associated dividers 51 + * @reg_data: cpu-specific register settings 52 + * @lock: clock lock 53 + */ 54 + struct rockchip_cpuclk { 55 + struct clk_hw hw; 56 + 57 + struct clk_mux cpu_mux; 58 + const struct clk_ops *cpu_mux_ops; 59 + 60 + struct clk *alt_parent; 61 + void __iomem *reg_base; 62 + struct notifier_block clk_nb; 63 + unsigned int rate_count; 64 + struct rockchip_cpuclk_rate_table *rate_table; 65 + const struct rockchip_cpuclk_reg_data *reg_data; 66 + spinlock_t *lock; 67 + }; 68 + 69 + #define to_rockchip_cpuclk_hw(hw) container_of(hw, struct rockchip_cpuclk, hw) 70 + #define to_rockchip_cpuclk_nb(nb) \ 71 + container_of(nb, struct rockchip_cpuclk, clk_nb) 72 + 73 + static const struct rockchip_cpuclk_rate_table *rockchip_get_cpuclk_settings( 74 + struct rockchip_cpuclk *cpuclk, unsigned long rate) 75 + { 76 + const struct rockchip_cpuclk_rate_table *rate_table = 77 + cpuclk->rate_table; 78 + int i; 79 + 80 + for (i = 0; i < cpuclk->rate_count; i++) { 81 + if (rate == rate_table[i].prate) 82 + return &rate_table[i]; 83 + } 84 + 85 + return NULL; 86 + } 87 + 88 + static unsigned long rockchip_cpuclk_recalc_rate(struct clk_hw *hw, 89 + unsigned long parent_rate) 90 + { 91 + struct rockchip_cpuclk *cpuclk = to_rockchip_cpuclk_hw(hw); 92 + const struct rockchip_cpuclk_reg_data *reg_data = cpuclk->reg_data; 93 + u32 clksel0 = readl_relaxed(cpuclk->reg_base + reg_data->core_reg); 94 + 95 + clksel0 >>= reg_data->div_core_shift; 96 + clksel0 &= reg_data->div_core_mask; 97 + return parent_rate / (clksel0 + 1); 98 + } 99 + 100 + static const struct clk_ops rockchip_cpuclk_ops = { 101 + .recalc_rate = rockchip_cpuclk_recalc_rate, 102 + }; 103 + 104 + static void rockchip_cpuclk_set_dividers(struct rockchip_cpuclk *cpuclk, 105 + const struct rockchip_cpuclk_rate_table *rate) 106 + { 107 + int i; 108 + 109 + /* alternate parent is active now. set the dividers */ 110 + for (i = 0; i < ARRAY_SIZE(rate->divs); i++) { 111 + const struct rockchip_cpuclk_clksel *clksel = &rate->divs[i]; 112 + 113 + if (!clksel->reg) 114 + continue; 115 + 116 + pr_debug("%s: setting reg 0x%x to 0x%x\n", 117 + __func__, clksel->reg, clksel->val); 118 + writel(clksel->val , cpuclk->reg_base + clksel->reg); 119 + } 120 + } 121 + 122 + static int rockchip_cpuclk_pre_rate_change(struct rockchip_cpuclk *cpuclk, 123 + struct clk_notifier_data *ndata) 124 + { 125 + const struct rockchip_cpuclk_reg_data *reg_data = cpuclk->reg_data; 126 + unsigned long alt_prate, alt_div; 127 + 128 + alt_prate = clk_get_rate(cpuclk->alt_parent); 129 + 130 + spin_lock(cpuclk->lock); 131 + 132 + /* 133 + * If the old parent clock speed is less than the clock speed 134 + * of the alternate parent, then it should be ensured that at no point 135 + * the armclk speed is more than the old_rate until the dividers are 136 + * set. 137 + */ 138 + if (alt_prate > ndata->old_rate) { 139 + /* calculate dividers */ 140 + alt_div = DIV_ROUND_UP(alt_prate, ndata->old_rate) - 1; 141 + if (alt_div > reg_data->div_core_mask) { 142 + pr_warn("%s: limiting alt-divider %lu to %d\n", 143 + __func__, alt_div, reg_data->div_core_mask); 144 + alt_div = reg_data->div_core_mask; 145 + } 146 + 147 + /* 148 + * Change parents and add dividers in a single transaction. 149 + * 150 + * NOTE: we do this in a single transaction so we're never 151 + * dividing the primary parent by the extra dividers that were 152 + * needed for the alt. 153 + */ 154 + pr_debug("%s: setting div %lu as alt-rate %lu > old-rate %lu\n", 155 + __func__, alt_div, alt_prate, ndata->old_rate); 156 + 157 + writel(HIWORD_UPDATE(alt_div, reg_data->div_core_mask, 158 + reg_data->div_core_shift) | 159 + HIWORD_UPDATE(1, 1, reg_data->mux_core_shift), 160 + cpuclk->reg_base + reg_data->core_reg); 161 + } else { 162 + /* select alternate parent */ 163 + writel(HIWORD_UPDATE(1, 1, reg_data->mux_core_shift), 164 + cpuclk->reg_base + reg_data->core_reg); 165 + } 166 + 167 + spin_unlock(cpuclk->lock); 168 + return 0; 169 + } 170 + 171 + static int rockchip_cpuclk_post_rate_change(struct rockchip_cpuclk *cpuclk, 172 + struct clk_notifier_data *ndata) 173 + { 174 + const struct rockchip_cpuclk_reg_data *reg_data = cpuclk->reg_data; 175 + const struct rockchip_cpuclk_rate_table *rate; 176 + 177 + rate = rockchip_get_cpuclk_settings(cpuclk, ndata->new_rate); 178 + if (!rate) { 179 + pr_err("%s: Invalid rate : %lu for cpuclk\n", 180 + __func__, ndata->new_rate); 181 + return -EINVAL; 182 + } 183 + 184 + spin_lock(cpuclk->lock); 185 + 186 + if (ndata->old_rate < ndata->new_rate) 187 + rockchip_cpuclk_set_dividers(cpuclk, rate); 188 + 189 + /* 190 + * post-rate change event, re-mux to primary parent and remove dividers. 191 + * 192 + * NOTE: we do this in a single transaction so we're never dividing the 193 + * primary parent by the extra dividers that were needed for the alt. 194 + */ 195 + 196 + writel(HIWORD_UPDATE(0, reg_data->div_core_mask, 197 + reg_data->div_core_shift) | 198 + HIWORD_UPDATE(0, 1, reg_data->mux_core_shift), 199 + cpuclk->reg_base + reg_data->core_reg); 200 + 201 + if (ndata->old_rate > ndata->new_rate) 202 + rockchip_cpuclk_set_dividers(cpuclk, rate); 203 + 204 + spin_unlock(cpuclk->lock); 205 + return 0; 206 + } 207 + 208 + /* 209 + * This clock notifier is called when the frequency of the parent clock 210 + * of cpuclk is to be changed. This notifier handles the setting up all 211 + * the divider clocks, remux to temporary parent and handling the safe 212 + * frequency levels when using temporary parent. 213 + */ 214 + static int rockchip_cpuclk_notifier_cb(struct notifier_block *nb, 215 + unsigned long event, void *data) 216 + { 217 + struct clk_notifier_data *ndata = data; 218 + struct rockchip_cpuclk *cpuclk = to_rockchip_cpuclk_nb(nb); 219 + int ret = 0; 220 + 221 + pr_debug("%s: event %lu, old_rate %lu, new_rate: %lu\n", 222 + __func__, event, ndata->old_rate, ndata->new_rate); 223 + if (event == PRE_RATE_CHANGE) 224 + ret = rockchip_cpuclk_pre_rate_change(cpuclk, ndata); 225 + else if (event == POST_RATE_CHANGE) 226 + ret = rockchip_cpuclk_post_rate_change(cpuclk, ndata); 227 + 228 + return notifier_from_errno(ret); 229 + } 230 + 231 + struct clk *rockchip_clk_register_cpuclk(const char *name, 232 + const char **parent_names, u8 num_parents, 233 + const struct rockchip_cpuclk_reg_data *reg_data, 234 + const struct rockchip_cpuclk_rate_table *rates, 235 + int nrates, void __iomem *reg_base, spinlock_t *lock) 236 + { 237 + struct rockchip_cpuclk *cpuclk; 238 + struct clk_init_data init; 239 + struct clk *clk, *cclk; 240 + int ret; 241 + 242 + if (num_parents != 2) { 243 + pr_err("%s: needs two parent clocks\n", __func__); 244 + return ERR_PTR(-EINVAL); 245 + } 246 + 247 + cpuclk = kzalloc(sizeof(*cpuclk), GFP_KERNEL); 248 + if (!cpuclk) 249 + return ERR_PTR(-ENOMEM); 250 + 251 + init.name = name; 252 + init.parent_names = &parent_names[0]; 253 + init.num_parents = 1; 254 + init.ops = &rockchip_cpuclk_ops; 255 + 256 + /* only allow rate changes when we have a rate table */ 257 + init.flags = (nrates > 0) ? CLK_SET_RATE_PARENT : 0; 258 + 259 + /* disallow automatic parent changes by ccf */ 260 + init.flags |= CLK_SET_RATE_NO_REPARENT; 261 + 262 + init.flags |= CLK_GET_RATE_NOCACHE; 263 + 264 + cpuclk->reg_base = reg_base; 265 + cpuclk->lock = lock; 266 + cpuclk->reg_data = reg_data; 267 + cpuclk->clk_nb.notifier_call = rockchip_cpuclk_notifier_cb; 268 + cpuclk->hw.init = &init; 269 + 270 + cpuclk->alt_parent = __clk_lookup(parent_names[1]); 271 + if (!cpuclk->alt_parent) { 272 + pr_err("%s: could not lookup alternate parent\n", 273 + __func__); 274 + ret = -EINVAL; 275 + goto free_cpuclk; 276 + } 277 + 278 + ret = clk_prepare_enable(cpuclk->alt_parent); 279 + if (ret) { 280 + pr_err("%s: could not enable alternate parent\n", 281 + __func__); 282 + goto free_cpuclk; 283 + } 284 + 285 + clk = __clk_lookup(parent_names[0]); 286 + if (!clk) { 287 + pr_err("%s: could not lookup parent clock %s\n", 288 + __func__, parent_names[0]); 289 + ret = -EINVAL; 290 + goto free_cpuclk; 291 + } 292 + 293 + ret = clk_notifier_register(clk, &cpuclk->clk_nb); 294 + if (ret) { 295 + pr_err("%s: failed to register clock notifier for %s\n", 296 + __func__, name); 297 + goto free_cpuclk; 298 + } 299 + 300 + if (nrates > 0) { 301 + cpuclk->rate_count = nrates; 302 + cpuclk->rate_table = kmemdup(rates, 303 + sizeof(*rates) * nrates, 304 + GFP_KERNEL); 305 + if (!cpuclk->rate_table) { 306 + pr_err("%s: could not allocate memory for cpuclk rates\n", 307 + __func__); 308 + ret = -ENOMEM; 309 + goto unregister_notifier; 310 + } 311 + } 312 + 313 + cclk = clk_register(NULL, &cpuclk->hw); 314 + if (IS_ERR(clk)) { 315 + pr_err("%s: could not register cpuclk %s\n", __func__, name); 316 + ret = PTR_ERR(clk); 317 + goto free_rate_table; 318 + } 319 + 320 + return cclk; 321 + 322 + free_rate_table: 323 + kfree(cpuclk->rate_table); 324 + unregister_notifier: 325 + clk_notifier_unregister(clk, &cpuclk->clk_nb); 326 + free_cpuclk: 327 + kfree(cpuclk); 328 + return ERR_PTR(ret); 329 + }
+13 -50
drivers/clk/rockchip/clk-pll.c
··· 34 34 const struct clk_ops *pll_mux_ops; 35 35 36 36 struct notifier_block clk_nb; 37 - bool rate_change_remuxed; 38 37 39 38 void __iomem *reg_base; 40 39 int lock_offset; ··· 108 109 } 109 110 110 111 /** 111 - * Set pll mux when changing the pll rate. 112 - * This makes sure to move the pll mux away from the actual pll before 113 - * changing its rate and back to the original parent after the change. 114 - */ 115 - static int rockchip_pll_notifier_cb(struct notifier_block *nb, 116 - unsigned long event, void *data) 117 - { 118 - struct rockchip_clk_pll *pll = to_rockchip_clk_pll_nb(nb); 119 - struct clk_mux *pll_mux = &pll->pll_mux; 120 - const struct clk_ops *pll_mux_ops = pll->pll_mux_ops; 121 - int cur_parent; 122 - 123 - switch (event) { 124 - case PRE_RATE_CHANGE: 125 - cur_parent = pll_mux_ops->get_parent(&pll_mux->hw); 126 - if (cur_parent == PLL_MODE_NORM) { 127 - pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW); 128 - pll->rate_change_remuxed = 1; 129 - } 130 - break; 131 - case POST_RATE_CHANGE: 132 - if (pll->rate_change_remuxed) { 133 - pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_NORM); 134 - pll->rate_change_remuxed = 0; 135 - } 136 - break; 137 - } 138 - 139 - return NOTIFY_OK; 140 - } 141 - 142 - /** 143 112 * PLL used in RK3066, RK3188 and RK3288 144 113 */ 145 114 ··· 161 194 const struct rockchip_pll_rate_table *rate; 162 195 unsigned long old_rate = rockchip_rk3066_pll_recalc_rate(hw, prate); 163 196 struct regmap *grf = rockchip_clk_get_grf(); 197 + struct clk_mux *pll_mux = &pll->pll_mux; 198 + const struct clk_ops *pll_mux_ops = pll->pll_mux_ops; 199 + int rate_change_remuxed = 0; 200 + int cur_parent; 164 201 int ret; 165 202 166 203 if (IS_ERR(grf)) { ··· 186 215 187 216 pr_debug("%s: rate settings for %lu (nr, no, nf): (%d, %d, %d)\n", 188 217 __func__, rate->rate, rate->nr, rate->no, rate->nf); 218 + 219 + cur_parent = pll_mux_ops->get_parent(&pll_mux->hw); 220 + if (cur_parent == PLL_MODE_NORM) { 221 + pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW); 222 + rate_change_remuxed = 1; 223 + } 189 224 190 225 /* enter reset mode */ 191 226 writel(HIWORD_UPDATE(RK3066_PLLCON3_RESET, RK3066_PLLCON3_RESET, 0), ··· 223 246 __func__, old_rate); 224 247 rockchip_rk3066_pll_set_rate(hw, old_rate, prate); 225 248 } 249 + 250 + if (rate_change_remuxed) 251 + pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_NORM); 226 252 227 253 return ret; 228 254 } ··· 290 310 struct clk_mux *pll_mux; 291 311 struct clk *pll_clk, *mux_clk; 292 312 char pll_name[20]; 293 - int ret; 294 313 295 314 if (num_parents != 2) { 296 315 pr_err("%s: needs two parent clocks\n", __func__); ··· 346 367 pll->lock_offset = grf_lock_offset; 347 368 pll->lock_shift = lock_shift; 348 369 pll->lock = lock; 349 - pll->clk_nb.notifier_call = rockchip_pll_notifier_cb; 350 370 351 371 pll_clk = clk_register(NULL, &pll->hw); 352 372 if (IS_ERR(pll_clk)) { ··· 353 375 __func__, name, PTR_ERR(pll_clk)); 354 376 mux_clk = pll_clk; 355 377 goto err_pll; 356 - } 357 - 358 - ret = clk_notifier_register(pll_clk, &pll->clk_nb); 359 - if (ret) { 360 - pr_err("%s: failed to register clock notifier for %s : %d\n", 361 - __func__, name, ret); 362 - mux_clk = ERR_PTR(ret); 363 - goto err_pll_notifier; 364 378 } 365 379 366 380 /* create the mux on top of the real pll */ ··· 387 417 return mux_clk; 388 418 389 419 err_mux: 390 - ret = clk_notifier_unregister(pll_clk, &pll->clk_nb); 391 - if (ret) { 392 - pr_err("%s: could not unregister clock notifier in error path : %d\n", 393 - __func__, ret); 394 - return mux_clk; 395 - } 396 - err_pll_notifier: 397 420 clk_unregister(pll_clk); 398 421 err_pll: 399 422 kfree(pll);
+156 -15
drivers/clk/rockchip/clk-rk3188.c
··· 19 19 #include <dt-bindings/clock/rk3188-cru-common.h> 20 20 #include "clk.h" 21 21 22 + #define RK3066_GRF_SOC_STATUS 0x15c 22 23 #define RK3188_GRF_SOC_STATUS 0xac 23 24 24 25 enum rk3188_plls { ··· 101 100 { /* sentinel */ }, 102 101 }; 103 102 103 + #define RK3066_DIV_CORE_PERIPH_MASK 0x3 104 + #define RK3066_DIV_CORE_PERIPH_SHIFT 6 105 + #define RK3066_DIV_ACLK_CORE_MASK 0x7 106 + #define RK3066_DIV_ACLK_CORE_SHIFT 0 107 + #define RK3066_DIV_ACLK_HCLK_MASK 0x3 108 + #define RK3066_DIV_ACLK_HCLK_SHIFT 8 109 + #define RK3066_DIV_ACLK_PCLK_MASK 0x3 110 + #define RK3066_DIV_ACLK_PCLK_SHIFT 12 111 + #define RK3066_DIV_AHB2APB_MASK 0x3 112 + #define RK3066_DIV_AHB2APB_SHIFT 14 113 + 114 + #define RK3066_CLKSEL0(_core_peri) \ 115 + { \ 116 + .reg = RK2928_CLKSEL_CON(0), \ 117 + .val = HIWORD_UPDATE(_core_peri, RK3066_DIV_CORE_PERIPH_MASK, \ 118 + RK3066_DIV_CORE_PERIPH_SHIFT) \ 119 + } 120 + #define RK3066_CLKSEL1(_aclk_core, _aclk_hclk, _aclk_pclk, _ahb2apb) \ 121 + { \ 122 + .reg = RK2928_CLKSEL_CON(1), \ 123 + .val = HIWORD_UPDATE(_aclk_core, RK3066_DIV_ACLK_CORE_MASK, \ 124 + RK3066_DIV_ACLK_CORE_SHIFT) | \ 125 + HIWORD_UPDATE(_aclk_hclk, RK3066_DIV_ACLK_HCLK_MASK, \ 126 + RK3066_DIV_ACLK_HCLK_SHIFT) | \ 127 + HIWORD_UPDATE(_aclk_pclk, RK3066_DIV_ACLK_PCLK_MASK, \ 128 + RK3066_DIV_ACLK_PCLK_SHIFT) | \ 129 + HIWORD_UPDATE(_ahb2apb, RK3066_DIV_AHB2APB_MASK, \ 130 + RK3066_DIV_AHB2APB_SHIFT), \ 131 + } 132 + 133 + #define RK3066_CPUCLK_RATE(_prate, _core_peri, _acore, _ahclk, _apclk, _h2p) \ 134 + { \ 135 + .prate = _prate, \ 136 + .divs = { \ 137 + RK3066_CLKSEL0(_core_peri), \ 138 + RK3066_CLKSEL1(_acore, _ahclk, _apclk, _h2p), \ 139 + }, \ 140 + } 141 + 142 + static struct rockchip_cpuclk_rate_table rk3066_cpuclk_rates[] __initdata = { 143 + RK3066_CPUCLK_RATE(1416000000, 2, 3, 1, 2, 1), 144 + RK3066_CPUCLK_RATE(1200000000, 2, 3, 1, 2, 1), 145 + RK3066_CPUCLK_RATE(1008000000, 2, 2, 1, 2, 1), 146 + RK3066_CPUCLK_RATE( 816000000, 2, 2, 1, 2, 1), 147 + RK3066_CPUCLK_RATE( 600000000, 1, 2, 1, 2, 1), 148 + RK3066_CPUCLK_RATE( 504000000, 1, 1, 1, 2, 1), 149 + RK3066_CPUCLK_RATE( 312000000, 0, 1, 1, 1, 0), 150 + }; 151 + 152 + static const struct rockchip_cpuclk_reg_data rk3066_cpuclk_data = { 153 + .core_reg = RK2928_CLKSEL_CON(0), 154 + .div_core_shift = 0, 155 + .div_core_mask = 0x1f, 156 + .mux_core_shift = 8, 157 + }; 158 + 159 + #define RK3188_DIV_ACLK_CORE_MASK 0x7 160 + #define RK3188_DIV_ACLK_CORE_SHIFT 3 161 + 162 + #define RK3188_CLKSEL1(_aclk_core) \ 163 + { \ 164 + .reg = RK2928_CLKSEL_CON(1), \ 165 + .val = HIWORD_UPDATE(_aclk_core, RK3188_DIV_ACLK_CORE_MASK,\ 166 + RK3188_DIV_ACLK_CORE_SHIFT) \ 167 + } 168 + #define RK3188_CPUCLK_RATE(_prate, _core_peri, _aclk_core) \ 169 + { \ 170 + .prate = _prate, \ 171 + .divs = { \ 172 + RK3066_CLKSEL0(_core_peri), \ 173 + RK3188_CLKSEL1(_aclk_core), \ 174 + }, \ 175 + } 176 + 177 + static struct rockchip_cpuclk_rate_table rk3188_cpuclk_rates[] __initdata = { 178 + RK3188_CPUCLK_RATE(1608000000, 2, 3), 179 + RK3188_CPUCLK_RATE(1416000000, 2, 3), 180 + RK3188_CPUCLK_RATE(1200000000, 2, 3), 181 + RK3188_CPUCLK_RATE(1008000000, 2, 3), 182 + RK3188_CPUCLK_RATE( 816000000, 2, 3), 183 + RK3188_CPUCLK_RATE( 600000000, 1, 3), 184 + RK3188_CPUCLK_RATE( 504000000, 1, 3), 185 + RK3188_CPUCLK_RATE( 312000000, 0, 1), 186 + }; 187 + 188 + static const struct rockchip_cpuclk_reg_data rk3188_cpuclk_data = { 189 + .core_reg = RK2928_CLKSEL_CON(0), 190 + .div_core_shift = 9, 191 + .div_core_mask = 0x1f, 192 + .mux_core_shift = 8, 193 + }; 194 + 104 195 PNAME(mux_pll_p) = { "xin24m", "xin32k" }; 105 196 PNAME(mux_armclk_p) = { "apll", "gpll_armclk" }; 106 197 PNAME(mux_ddrphy_p) = { "dpll", "gpll_ddr" }; ··· 266 173 GATE(0, "aclk_cpu", "aclk_cpu_pre", 0, 267 174 RK2928_CLKGATE_CON(0), 3, GFLAGS), 268 175 269 - DIV(0, "pclk_cpu_pre", "aclk_cpu_pre", 0, 270 - RK2928_CLKSEL_CON(1), 12, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO), 271 176 GATE(0, "atclk_cpu", "pclk_cpu_pre", 0, 272 177 RK2928_CLKGATE_CON(0), 6, GFLAGS), 273 178 GATE(0, "pclk_cpu", "pclk_cpu_pre", 0, 274 179 RK2928_CLKGATE_CON(0), 5, GFLAGS), 275 - DIV(0, "hclk_cpu_pre", "aclk_cpu_pre", 0, 276 - RK2928_CLKSEL_CON(1), 8, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO), 277 - COMPOSITE_NOMUX(0, "hclk_ahb2apb", "hclk_cpu_pre", 0, 278 - RK2928_CLKSEL_CON(1), 14, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO, 279 - RK2928_CLKGATE_CON(4), 9, GFLAGS), 280 180 GATE(0, "hclk_cpu", "hclk_cpu_pre", 0, 281 181 RK2928_CLKGATE_CON(0), 4, GFLAGS), 282 182 ··· 498 412 }; 499 413 500 414 static struct rockchip_clk_branch rk3066a_clk_branches[] __initdata = { 501 - COMPOSITE_NOGATE(0, "armclk", mux_armclk_p, 0, 502 - RK2928_CLKSEL_CON(0), 8, 1, MFLAGS, 0, 5, DFLAGS), 503 415 DIVTBL(0, "aclk_cpu_pre", "armclk", 0, 504 - RK2928_CLKSEL_CON(1), 0, 3, DFLAGS, div_aclk_cpu_t), 416 + RK2928_CLKSEL_CON(1), 0, 3, DFLAGS | CLK_DIVIDER_READ_ONLY, div_aclk_cpu_t), 417 + DIV(0, "pclk_cpu_pre", "aclk_cpu_pre", 0, 418 + RK2928_CLKSEL_CON(1), 12, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO 419 + | CLK_DIVIDER_READ_ONLY), 420 + DIV(0, "hclk_cpu_pre", "aclk_cpu_pre", 0, 421 + RK2928_CLKSEL_CON(1), 8, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO 422 + | CLK_DIVIDER_READ_ONLY), 423 + COMPOSITE_NOMUX(0, "hclk_ahb2apb", "hclk_cpu_pre", 0, 424 + RK2928_CLKSEL_CON(1), 14, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO 425 + | CLK_DIVIDER_READ_ONLY, 426 + RK2928_CLKGATE_CON(4), 9, GFLAGS), 505 427 506 428 GATE(CORE_L2C, "core_l2c", "aclk_cpu", 0, 507 429 RK2928_CLKGATE_CON(9), 4, GFLAGS), ··· 618 524 "gpll", "cpll" }; 619 525 620 526 static struct rockchip_clk_branch rk3188_clk_branches[] __initdata = { 621 - COMPOSITE_NOGATE(0, "armclk", mux_armclk_p, 0, 622 - RK2928_CLKSEL_CON(0), 8, 1, MFLAGS, 9, 5, DFLAGS), 623 527 COMPOSITE_NOMUX_DIVTBL(0, "aclk_core", "armclk", 0, 624 528 RK2928_CLKSEL_CON(1), 3, 3, DFLAGS | CLK_DIVIDER_READ_ONLY, 625 529 div_rk3188_aclk_core_t, RK2928_CLKGATE_CON(0), 7, GFLAGS), ··· 625 533 /* do not source aclk_cpu_pre from the apll, to keep complexity down */ 626 534 COMPOSITE_NOGATE(0, "aclk_cpu_pre", mux_aclk_cpu_p, CLK_SET_RATE_NO_REPARENT, 627 535 RK2928_CLKSEL_CON(0), 5, 1, MFLAGS, 0, 5, DFLAGS), 536 + DIV(0, "pclk_cpu_pre", "aclk_cpu_pre", 0, 537 + RK2928_CLKSEL_CON(1), 12, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO), 538 + DIV(0, "hclk_cpu_pre", "aclk_cpu_pre", 0, 539 + RK2928_CLKSEL_CON(1), 8, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO), 540 + COMPOSITE_NOMUX(0, "hclk_ahb2apb", "hclk_cpu_pre", 0, 541 + RK2928_CLKSEL_CON(1), 14, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO, 542 + RK2928_CLKGATE_CON(4), 9, GFLAGS), 628 543 629 544 GATE(CORE_L2C, "core_l2c", "armclk", 0, 630 545 RK2928_CLKGATE_CON(9), 4, GFLAGS), ··· 698 599 GATE(ACLK_GPS, "aclk_gps", "aclk_peri", 0, RK2928_CLKGATE_CON(8), 13, GFLAGS), 699 600 }; 700 601 602 + static const char *rk3188_critical_clocks[] __initconst = { 603 + "aclk_cpu", 604 + "aclk_peri", 605 + "hclk_peri", 606 + }; 607 + 701 608 static void __init rk3188_common_clk_init(struct device_node *np) 702 609 { 703 610 void __iomem *reg_base; ··· 728 623 pr_warn("%s: could not register clock usb480m: %ld\n", 729 624 __func__, PTR_ERR(clk)); 730 625 731 - rockchip_clk_register_plls(rk3188_pll_clks, 732 - ARRAY_SIZE(rk3188_pll_clks), 733 - RK3188_GRF_SOC_STATUS); 734 626 rockchip_clk_register_branches(common_clk_branches, 735 627 ARRAY_SIZE(common_clk_branches)); 628 + rockchip_clk_protect_critical(rk3188_critical_clocks, 629 + ARRAY_SIZE(rk3188_critical_clocks)); 736 630 737 631 rockchip_register_softrst(np, 9, reg_base + RK2928_SOFTRST_CON(0), 738 632 ROCKCHIP_SOFTRST_HIWORD_MASK); 633 + 634 + rockchip_register_restart_notifier(RK2928_GLB_SRST_FST); 739 635 } 740 636 741 637 static void __init rk3066a_clk_init(struct device_node *np) 742 638 { 743 639 rk3188_common_clk_init(np); 640 + rockchip_clk_register_plls(rk3188_pll_clks, 641 + ARRAY_SIZE(rk3188_pll_clks), 642 + RK3066_GRF_SOC_STATUS); 744 643 rockchip_clk_register_branches(rk3066a_clk_branches, 745 644 ARRAY_SIZE(rk3066a_clk_branches)); 645 + rockchip_clk_register_armclk(ARMCLK, "armclk", 646 + mux_armclk_p, ARRAY_SIZE(mux_armclk_p), 647 + &rk3066_cpuclk_data, rk3066_cpuclk_rates, 648 + ARRAY_SIZE(rk3066_cpuclk_rates)); 746 649 } 747 650 CLK_OF_DECLARE(rk3066a_cru, "rockchip,rk3066a-cru", rk3066a_clk_init); 748 651 749 652 static void __init rk3188a_clk_init(struct device_node *np) 750 653 { 654 + struct clk *clk1, *clk2; 655 + unsigned long rate; 656 + int ret; 657 + 751 658 rk3188_common_clk_init(np); 659 + rockchip_clk_register_plls(rk3188_pll_clks, 660 + ARRAY_SIZE(rk3188_pll_clks), 661 + RK3188_GRF_SOC_STATUS); 752 662 rockchip_clk_register_branches(rk3188_clk_branches, 753 663 ARRAY_SIZE(rk3188_clk_branches)); 664 + rockchip_clk_register_armclk(ARMCLK, "armclk", 665 + mux_armclk_p, ARRAY_SIZE(mux_armclk_p), 666 + &rk3188_cpuclk_data, rk3188_cpuclk_rates, 667 + ARRAY_SIZE(rk3188_cpuclk_rates)); 668 + 669 + /* reparent aclk_cpu_pre from apll */ 670 + clk1 = __clk_lookup("aclk_cpu_pre"); 671 + clk2 = __clk_lookup("gpll"); 672 + if (clk1 && clk2) { 673 + rate = clk_get_rate(clk1); 674 + 675 + ret = clk_set_parent(clk1, clk2); 676 + if (ret < 0) 677 + pr_warn("%s: could not reparent aclk_cpu_pre to gpll\n", 678 + __func__); 679 + 680 + clk_set_rate(clk1, rate); 681 + } else { 682 + pr_warn("%s: missing clocks to reparent aclk_cpu_pre to gpll\n", 683 + __func__); 684 + } 754 685 } 755 686 CLK_OF_DECLARE(rk3188a_cru, "rockchip,rk3188a-cru", rk3188a_clk_init); 756 687
+150 -53
drivers/clk/rockchip/clk-rk3288.c
··· 20 20 #include "clk.h" 21 21 22 22 #define RK3288_GRF_SOC_CON(x) (0x244 + x * 4) 23 - #define RK3288_GRF_SOC_STATUS 0x280 23 + #define RK3288_GRF_SOC_STATUS1 0x284 24 24 25 25 enum rk3288_plls { 26 26 apll, dpll, cpll, gpll, npll, ··· 101 101 { /* sentinel */ }, 102 102 }; 103 103 104 + #define RK3288_DIV_ACLK_CORE_M0_MASK 0xf 105 + #define RK3288_DIV_ACLK_CORE_M0_SHIFT 0 106 + #define RK3288_DIV_ACLK_CORE_MP_MASK 0xf 107 + #define RK3288_DIV_ACLK_CORE_MP_SHIFT 4 108 + #define RK3288_DIV_L2RAM_MASK 0x7 109 + #define RK3288_DIV_L2RAM_SHIFT 0 110 + #define RK3288_DIV_ATCLK_MASK 0x1f 111 + #define RK3288_DIV_ATCLK_SHIFT 4 112 + #define RK3288_DIV_PCLK_DBGPRE_MASK 0x1f 113 + #define RK3288_DIV_PCLK_DBGPRE_SHIFT 9 114 + 115 + #define RK3288_CLKSEL0(_core_m0, _core_mp) \ 116 + { \ 117 + .reg = RK3288_CLKSEL_CON(0), \ 118 + .val = HIWORD_UPDATE(_core_m0, RK3288_DIV_ACLK_CORE_M0_MASK, \ 119 + RK3288_DIV_ACLK_CORE_M0_SHIFT) | \ 120 + HIWORD_UPDATE(_core_mp, RK3288_DIV_ACLK_CORE_MP_MASK, \ 121 + RK3288_DIV_ACLK_CORE_MP_SHIFT), \ 122 + } 123 + #define RK3288_CLKSEL37(_l2ram, _atclk, _pclk_dbg_pre) \ 124 + { \ 125 + .reg = RK3288_CLKSEL_CON(37), \ 126 + .val = HIWORD_UPDATE(_l2ram, RK3288_DIV_L2RAM_MASK, \ 127 + RK3288_DIV_L2RAM_SHIFT) | \ 128 + HIWORD_UPDATE(_atclk, RK3288_DIV_ATCLK_MASK, \ 129 + RK3288_DIV_ATCLK_SHIFT) | \ 130 + HIWORD_UPDATE(_pclk_dbg_pre, \ 131 + RK3288_DIV_PCLK_DBGPRE_MASK, \ 132 + RK3288_DIV_PCLK_DBGPRE_SHIFT), \ 133 + } 134 + 135 + #define RK3288_CPUCLK_RATE(_prate, _core_m0, _core_mp, _l2ram, _atclk, _pdbg) \ 136 + { \ 137 + .prate = _prate, \ 138 + .divs = { \ 139 + RK3288_CLKSEL0(_core_m0, _core_mp), \ 140 + RK3288_CLKSEL37(_l2ram, _atclk, _pdbg), \ 141 + }, \ 142 + } 143 + 144 + static struct rockchip_cpuclk_rate_table rk3288_cpuclk_rates[] __initdata = { 145 + RK3288_CPUCLK_RATE(1800000000, 2, 4, 2, 4, 4), 146 + RK3288_CPUCLK_RATE(1704000000, 2, 4, 2, 4, 4), 147 + RK3288_CPUCLK_RATE(1608000000, 2, 4, 2, 4, 4), 148 + RK3288_CPUCLK_RATE(1512000000, 2, 4, 2, 4, 4), 149 + RK3288_CPUCLK_RATE(1416000000, 2, 4, 2, 4, 4), 150 + RK3288_CPUCLK_RATE(1200000000, 2, 4, 2, 4, 4), 151 + RK3288_CPUCLK_RATE(1008000000, 2, 4, 2, 4, 4), 152 + RK3288_CPUCLK_RATE( 816000000, 2, 4, 2, 4, 4), 153 + RK3288_CPUCLK_RATE( 696000000, 2, 4, 2, 4, 4), 154 + RK3288_CPUCLK_RATE( 600000000, 2, 4, 2, 4, 4), 155 + RK3288_CPUCLK_RATE( 408000000, 2, 4, 2, 4, 4), 156 + RK3288_CPUCLK_RATE( 312000000, 2, 4, 2, 4, 4), 157 + RK3288_CPUCLK_RATE( 216000000, 2, 4, 2, 4, 4), 158 + RK3288_CPUCLK_RATE( 126000000, 2, 4, 2, 4, 4), 159 + }; 160 + 161 + static const struct rockchip_cpuclk_reg_data rk3288_cpuclk_data = { 162 + .core_reg = RK3288_CLKSEL_CON(0), 163 + .div_core_shift = 8, 164 + .div_core_mask = 0x1f, 165 + .mux_core_shift = 15, 166 + }; 167 + 104 168 PNAME(mux_pll_p) = { "xin24m", "xin32k" }; 105 169 PNAME(mux_armclk_p) = { "apll_core", "gpll_core" }; 106 170 PNAME(mux_ddrphy_p) = { "dpll_ddr", "gpll_ddr" }; ··· 207 143 [gpll] = PLL(pll_rk3066, PLL_GPLL, "gpll", mux_pll_p, 0, RK3288_PLL_CON(12), 208 144 RK3288_MODE_CON, 12, 8, rk3288_pll_rates), 209 145 [npll] = PLL(pll_rk3066, PLL_NPLL, "npll", mux_pll_p, 0, RK3288_PLL_CON(16), 210 - RK3288_MODE_CON, 14, 9, NULL), 146 + RK3288_MODE_CON, 14, 9, rk3288_pll_rates), 211 147 }; 212 148 213 149 static struct clk_div_table div_hclk_cpu_t[] = { ··· 230 166 RK3288_CLKGATE_CON(0), 1, GFLAGS), 231 167 GATE(0, "gpll_core", "gpll", 0, 232 168 RK3288_CLKGATE_CON(0), 2, GFLAGS), 233 - COMPOSITE_NOGATE(0, "armclk", mux_armclk_p, 0, 234 - RK3288_CLKSEL_CON(0), 15, 1, MFLAGS, 8, 5, DFLAGS), 235 169 236 170 COMPOSITE_NOMUX(0, "armcore0", "armclk", 0, 237 - RK3288_CLKSEL_CON(36), 0, 3, DFLAGS, 171 + RK3288_CLKSEL_CON(36), 0, 3, DFLAGS | CLK_DIVIDER_READ_ONLY, 238 172 RK3288_CLKGATE_CON(12), 0, GFLAGS), 239 173 COMPOSITE_NOMUX(0, "armcore1", "armclk", 0, 240 - RK3288_CLKSEL_CON(36), 4, 3, DFLAGS, 174 + RK3288_CLKSEL_CON(36), 4, 3, DFLAGS | CLK_DIVIDER_READ_ONLY, 241 175 RK3288_CLKGATE_CON(12), 1, GFLAGS), 242 176 COMPOSITE_NOMUX(0, "armcore2", "armclk", 0, 243 - RK3288_CLKSEL_CON(36), 8, 3, DFLAGS, 177 + RK3288_CLKSEL_CON(36), 8, 3, DFLAGS | CLK_DIVIDER_READ_ONLY, 244 178 RK3288_CLKGATE_CON(12), 2, GFLAGS), 245 179 COMPOSITE_NOMUX(0, "armcore3", "armclk", 0, 246 - RK3288_CLKSEL_CON(36), 12, 3, DFLAGS, 180 + RK3288_CLKSEL_CON(36), 12, 3, DFLAGS | CLK_DIVIDER_READ_ONLY, 247 181 RK3288_CLKGATE_CON(12), 3, GFLAGS), 248 182 COMPOSITE_NOMUX(0, "l2ram", "armclk", 0, 249 - RK3288_CLKSEL_CON(37), 0, 3, DFLAGS, 183 + RK3288_CLKSEL_CON(37), 0, 3, DFLAGS | CLK_DIVIDER_READ_ONLY, 250 184 RK3288_CLKGATE_CON(12), 4, GFLAGS), 251 185 COMPOSITE_NOMUX(0, "aclk_core_m0", "armclk", 0, 252 - RK3288_CLKSEL_CON(0), 0, 4, DFLAGS, 186 + RK3288_CLKSEL_CON(0), 0, 4, DFLAGS | CLK_DIVIDER_READ_ONLY, 253 187 RK3288_CLKGATE_CON(12), 5, GFLAGS), 254 188 COMPOSITE_NOMUX(0, "aclk_core_mp", "armclk", 0, 255 - RK3288_CLKSEL_CON(0), 4, 4, DFLAGS, 189 + RK3288_CLKSEL_CON(0), 4, 4, DFLAGS | CLK_DIVIDER_READ_ONLY, 256 190 RK3288_CLKGATE_CON(12), 6, GFLAGS), 257 191 COMPOSITE_NOMUX(0, "atclk", "armclk", 0, 258 - RK3288_CLKSEL_CON(37), 4, 5, DFLAGS, 192 + RK3288_CLKSEL_CON(37), 4, 5, DFLAGS | CLK_DIVIDER_READ_ONLY, 259 193 RK3288_CLKGATE_CON(12), 7, GFLAGS), 260 194 COMPOSITE_NOMUX(0, "pclk_dbg_pre", "armclk", 0, 261 - RK3288_CLKSEL_CON(37), 9, 5, DFLAGS, 195 + RK3288_CLKSEL_CON(37), 9, 5, DFLAGS | CLK_DIVIDER_READ_ONLY, 262 196 RK3288_CLKGATE_CON(12), 8, GFLAGS), 263 197 GATE(0, "pclk_dbg", "pclk_dbg_pre", 0, 264 198 RK3288_CLKGATE_CON(12), 9, GFLAGS), ··· 281 219 RK3288_CLKSEL_CON(1), 15, 1, MFLAGS, 3, 5, DFLAGS), 282 220 DIV(0, "aclk_cpu_pre", "aclk_cpu_src", 0, 283 221 RK3288_CLKSEL_CON(1), 0, 3, DFLAGS), 284 - GATE(0, "aclk_cpu", "aclk_cpu_pre", 0, 222 + GATE(ACLK_CPU, "aclk_cpu", "aclk_cpu_pre", 0, 285 223 RK3288_CLKGATE_CON(0), 3, GFLAGS), 286 - COMPOSITE_NOMUX(0, "pclk_cpu", "aclk_cpu_pre", 0, 224 + COMPOSITE_NOMUX(PCLK_CPU, "pclk_cpu", "aclk_cpu_pre", 0, 287 225 RK3288_CLKSEL_CON(1), 12, 3, DFLAGS, 288 226 RK3288_CLKGATE_CON(0), 5, GFLAGS), 289 - COMPOSITE_NOMUX_DIVTBL(0, "hclk_cpu", "aclk_cpu_pre", 0, 227 + COMPOSITE_NOMUX_DIVTBL(HCLK_CPU, "hclk_cpu", "aclk_cpu_pre", 0, 290 228 RK3288_CLKSEL_CON(1), 8, 2, DFLAGS, div_hclk_cpu_t, 291 229 RK3288_CLKGATE_CON(0), 4, GFLAGS), 292 230 GATE(0, "c2c_host", "aclk_cpu_src", 0, ··· 300 238 COMPOSITE(0, "i2s_src", mux_pll_src_cpll_gpll_p, 0, 301 239 RK3288_CLKSEL_CON(4), 15, 1, MFLAGS, 0, 7, DFLAGS, 302 240 RK3288_CLKGATE_CON(4), 1, GFLAGS), 303 - COMPOSITE_FRAC(0, "i2s_frac", "i2s_src", 0, 241 + COMPOSITE_FRAC(0, "i2s_frac", "i2s_src", CLK_SET_RATE_PARENT, 304 242 RK3288_CLKSEL_CON(8), 0, 305 243 RK3288_CLKGATE_CON(4), 2, GFLAGS), 306 - MUX(0, "i2s_pre", mux_i2s_pre_p, 0, 244 + MUX(0, "i2s_pre", mux_i2s_pre_p, CLK_SET_RATE_PARENT, 307 245 RK3288_CLKSEL_CON(4), 8, 2, MFLAGS), 308 - COMPOSITE_NODIV(0, "i2s0_clkout", mux_i2s_clkout_p, 0, 246 + COMPOSITE_NODIV(0, "i2s0_clkout", mux_i2s_clkout_p, CLK_SET_RATE_PARENT, 309 247 RK3288_CLKSEL_CON(4), 12, 1, MFLAGS, 310 248 RK3288_CLKGATE_CON(4), 0, GFLAGS), 311 - GATE(SCLK_I2S0, "sclk_i2s0", "i2s_pre", 0, 249 + GATE(SCLK_I2S0, "sclk_i2s0", "i2s_pre", CLK_SET_RATE_PARENT, 312 250 RK3288_CLKGATE_CON(4), 3, GFLAGS), 313 251 314 252 MUX(0, "spdif_src", mux_pll_src_cpll_gpll_p, 0, ··· 358 296 COMPOSITE(0, "aclk_vdpu", mux_pll_src_cpll_gpll_usb480m_p, 0, 359 297 RK3288_CLKSEL_CON(32), 14, 2, MFLAGS, 8, 5, DFLAGS, 360 298 RK3288_CLKGATE_CON(3), 11, GFLAGS), 299 + /* 300 + * We use aclk_vdpu by default GRF_SOC_CON0[7] setting in system, 301 + * so we ignore the mux and make clocks nodes as following, 302 + */ 303 + GATE(ACLK_VCODEC, "aclk_vcodec", "aclk_vdpu", 0, 304 + RK3288_CLKGATE_CON(9), 0, GFLAGS), 305 + /* 306 + * We introduce a virtul node of hclk_vodec_pre_v to split one clock 307 + * struct with a gate and a fix divider into two node in software. 308 + */ 309 + GATE(0, "hclk_vcodec_pre_v", "aclk_vdpu", 0, 310 + RK3288_CLKGATE_CON(3), 10, GFLAGS), 311 + GATE(HCLK_VCODEC, "hclk_vcodec", "hclk_vcodec_pre", 0, 312 + RK3288_CLKGATE_CON(9), 1, GFLAGS), 361 313 362 314 COMPOSITE(0, "aclk_vio0", mux_pll_src_cpll_gpll_usb480m_p, 0, 363 315 RK3288_CLKSEL_CON(31), 6, 2, MFLAGS, 0, 5, DFLAGS, ··· 385 309 COMPOSITE(0, "aclk_rga_pre", mux_pll_src_cpll_gpll_usb480m_p, 0, 386 310 RK3288_CLKSEL_CON(30), 6, 2, MFLAGS, 0, 5, DFLAGS, 387 311 RK3288_CLKGATE_CON(3), 5, GFLAGS), 388 - COMPOSITE(0, "sclk_rga", mux_pll_src_cpll_gpll_usb480m_p, 0, 312 + COMPOSITE(SCLK_RGA, "sclk_rga", mux_pll_src_cpll_gpll_usb480m_p, 0, 389 313 RK3288_CLKSEL_CON(30), 14, 2, MFLAGS, 8, 5, DFLAGS, 390 314 RK3288_CLKGATE_CON(3), 4, GFLAGS), 391 315 ··· 396 320 RK3288_CLKSEL_CON(29), 6, 2, MFLAGS, 8, 8, DFLAGS, 397 321 RK3288_CLKGATE_CON(3), 3, GFLAGS), 398 322 399 - COMPOSITE_NODIV(0, "sclk_edp_24m", mux_edp_24m_p, 0, 323 + COMPOSITE_NODIV(SCLK_EDP_24M, "sclk_edp_24m", mux_edp_24m_p, 0, 400 324 RK3288_CLKSEL_CON(28), 15, 1, MFLAGS, 401 325 RK3288_CLKGATE_CON(3), 12, GFLAGS), 402 - COMPOSITE(0, "sclk_edp", mux_pll_src_cpll_gpll_npll_p, 0, 326 + COMPOSITE(SCLK_EDP, "sclk_edp", mux_pll_src_cpll_gpll_npll_p, 0, 403 327 RK3288_CLKSEL_CON(28), 6, 2, MFLAGS, 0, 6, DFLAGS, 404 328 RK3288_CLKGATE_CON(3), 13, GFLAGS), 405 329 406 - COMPOSITE(0, "sclk_isp", mux_pll_src_cpll_gpll_npll_p, 0, 330 + COMPOSITE(SCLK_ISP, "sclk_isp", mux_pll_src_cpll_gpll_npll_p, 0, 407 331 RK3288_CLKSEL_CON(6), 6, 2, MFLAGS, 0, 6, DFLAGS, 408 332 RK3288_CLKGATE_CON(3), 14, GFLAGS), 409 - COMPOSITE(0, "sclk_isp_jpe", mux_pll_src_cpll_gpll_npll_p, 0, 333 + COMPOSITE(SCLK_ISP_JPE, "sclk_isp_jpe", mux_pll_src_cpll_gpll_npll_p, 0, 410 334 RK3288_CLKSEL_CON(6), 14, 2, MFLAGS, 8, 6, DFLAGS, 411 335 RK3288_CLKGATE_CON(3), 15, GFLAGS), 412 336 413 - GATE(0, "sclk_hdmi_hdcp", "xin24m", 0, 337 + GATE(SCLK_HDMI_HDCP, "sclk_hdmi_hdcp", "xin24m", 0, 414 338 RK3288_CLKGATE_CON(5), 12, GFLAGS), 415 - GATE(0, "sclk_hdmi_cec", "xin32k", 0, 339 + GATE(SCLK_HDMI_CEC, "sclk_hdmi_cec", "xin32k", 0, 416 340 RK3288_CLKGATE_CON(5), 11, GFLAGS), 417 341 418 - COMPOSITE(0, "aclk_hevc", mux_pll_src_cpll_gpll_npll_p, 0, 342 + COMPOSITE(ACLK_HEVC, "aclk_hevc", mux_pll_src_cpll_gpll_npll_p, 0, 419 343 RK3288_CLKSEL_CON(39), 14, 2, MFLAGS, 8, 5, DFLAGS, 420 344 RK3288_CLKGATE_CON(13), 13, GFLAGS), 421 - DIV(0, "hclk_hevc", "aclk_hevc", 0, 345 + DIV(HCLK_HEVC, "hclk_hevc", "aclk_hevc", 0, 422 346 RK3288_CLKSEL_CON(40), 12, 2, DFLAGS), 423 347 424 - COMPOSITE(0, "sclk_hevc_cabac", mux_pll_src_cpll_gpll_npll_p, 0, 348 + COMPOSITE(SCLK_HEVC_CABAC, "sclk_hevc_cabac", mux_pll_src_cpll_gpll_npll_p, 0, 425 349 RK3288_CLKSEL_CON(42), 6, 2, MFLAGS, 0, 5, DFLAGS, 426 350 RK3288_CLKGATE_CON(13), 14, GFLAGS), 427 - COMPOSITE(0, "sclk_hevc_core", mux_pll_src_cpll_gpll_npll_p, 0, 351 + COMPOSITE(SCLK_HEVC_CORE, "sclk_hevc_core", mux_pll_src_cpll_gpll_npll_p, 0, 428 352 RK3288_CLKSEL_CON(42), 14, 2, MFLAGS, 8, 5, DFLAGS, 429 353 RK3288_CLKGATE_CON(13), 15, GFLAGS), 430 354 ··· 447 371 COMPOSITE(0, "aclk_peri_src", mux_pll_src_cpll_gpll_p, 0, 448 372 RK3288_CLKSEL_CON(10), 15, 1, MFLAGS, 0, 5, DFLAGS, 449 373 RK3288_CLKGATE_CON(2), 0, GFLAGS), 450 - COMPOSITE_NOMUX(0, "pclk_peri", "aclk_peri_src", 0, 374 + COMPOSITE_NOMUX(PCLK_PERI, "pclk_peri", "aclk_peri_src", 0, 451 375 RK3288_CLKSEL_CON(10), 12, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO, 452 376 RK3288_CLKGATE_CON(2), 3, GFLAGS), 453 - COMPOSITE_NOMUX(0, "hclk_peri", "aclk_peri_src", 0, 377 + COMPOSITE_NOMUX(HCLK_PERI, "hclk_peri", "aclk_peri_src", 0, 454 378 RK3288_CLKSEL_CON(10), 8, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO, 455 379 RK3288_CLKGATE_CON(2), 2, GFLAGS), 456 - GATE(0, "aclk_peri", "aclk_peri_src", 0, 380 + GATE(ACLK_PERI, "aclk_peri", "aclk_peri_src", 0, 457 381 RK3288_CLKGATE_CON(2), 1, GFLAGS), 458 382 459 383 /* ··· 719 643 GATE(HCLK_RGA, "hclk_rga", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 1, GFLAGS), 720 644 GATE(HCLK_VOP0, "hclk_vop0", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 6, GFLAGS), 721 645 GATE(HCLK_VOP1, "hclk_vop1", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 8, GFLAGS), 722 - GATE(0, "hclk_vio_ahb_arbi", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 9, GFLAGS), 723 - GATE(0, "hclk_vio_niu", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 10, GFLAGS), 724 - GATE(0, "hclk_vip", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 15, GFLAGS), 646 + GATE(HCLK_VIO_AHB_ARBI, "hclk_vio_ahb_arbi", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 9, GFLAGS), 647 + GATE(HCLK_VIO_NIU, "hclk_vio_niu", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 10, GFLAGS), 648 + GATE(HCLK_VIP, "hclk_vip", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 15, GFLAGS), 725 649 GATE(HCLK_IEP, "hclk_iep", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 3, GFLAGS), 726 650 GATE(HCLK_ISP, "hclk_isp", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 1, GFLAGS), 727 - GATE(0, "hclk_vio2_h2p", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 10, GFLAGS), 728 - GATE(0, "pclk_mipi_dsi0", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 4, GFLAGS), 729 - GATE(0, "pclk_mipi_dsi1", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 5, GFLAGS), 730 - GATE(0, "pclk_mipi_csi", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 6, GFLAGS), 731 - GATE(0, "pclk_lvds_phy", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 7, GFLAGS), 732 - GATE(0, "pclk_edp_ctrl", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 8, GFLAGS), 733 - GATE(0, "pclk_hdmi_ctrl", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 9, GFLAGS), 734 - GATE(0, "pclk_vio2_h2p", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 11, GFLAGS), 651 + GATE(HCLK_VIO2_H2P, "hclk_vio2_h2p", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 10, GFLAGS), 652 + GATE(PCLK_MIPI_DSI0, "pclk_mipi_dsi0", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 4, GFLAGS), 653 + GATE(PCLK_MIPI_DSI1, "pclk_mipi_dsi1", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 5, GFLAGS), 654 + GATE(PCLK_MIPI_CSI, "pclk_mipi_csi", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 6, GFLAGS), 655 + GATE(PCLK_LVDS_PHY, "pclk_lvds_phy", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 7, GFLAGS), 656 + GATE(PCLK_EDP_CTRL, "pclk_edp_ctrl", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 8, GFLAGS), 657 + GATE(PCLK_HDMI_CTRL, "pclk_hdmi_ctrl", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 9, GFLAGS), 658 + GATE(PCLK_VIO2_H2P, "pclk_vio2_h2p", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 11, GFLAGS), 735 659 736 660 /* aclk_vio0 gates */ 737 661 GATE(ACLK_VOP0, "aclk_vop0", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 5, GFLAGS), 738 - GATE(0, "aclk_iep", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 2, GFLAGS), 739 - GATE(0, "aclk_vio0_niu", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 11, GFLAGS), 740 - GATE(0, "aclk_vip", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 14, GFLAGS), 662 + GATE(ACLK_IEP, "aclk_iep", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 2, GFLAGS), 663 + GATE(ACLK_VIO0_NIU, "aclk_vio0_niu", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 11, GFLAGS), 664 + GATE(ACLK_VIP, "aclk_vip", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 14, GFLAGS), 741 665 742 666 /* aclk_vio1 gates */ 743 667 GATE(ACLK_VOP1, "aclk_vop1", "aclk_vio1", 0, RK3288_CLKGATE_CON(15), 7, GFLAGS), 744 - GATE(0, "aclk_isp", "aclk_vio1", 0, RK3288_CLKGATE_CON(16), 2, GFLAGS), 745 - GATE(0, "aclk_vio1_niu", "aclk_vio1", 0, RK3288_CLKGATE_CON(15), 12, GFLAGS), 668 + GATE(ACLK_ISP, "aclk_isp", "aclk_vio1", 0, RK3288_CLKGATE_CON(16), 2, GFLAGS), 669 + GATE(ACLK_VIO1_NIU, "aclk_vio1_niu", "aclk_vio1", 0, RK3288_CLKGATE_CON(15), 12, GFLAGS), 746 670 747 671 /* aclk_rga_pre gates */ 748 672 GATE(ACLK_RGA, "aclk_rga", "aclk_rga_pre", 0, RK3288_CLKGATE_CON(15), 0, GFLAGS), 749 - GATE(0, "aclk_rga_niu", "aclk_rga_pre", 0, RK3288_CLKGATE_CON(15), 13, GFLAGS), 673 + GATE(ACLK_RGA_NIU, "aclk_rga_niu", "aclk_rga_pre", 0, RK3288_CLKGATE_CON(15), 13, GFLAGS), 750 674 751 675 /* 752 676 * Other ungrouped clocks. ··· 754 678 755 679 GATE(0, "pclk_vip_in", "ext_vip", 0, RK3288_CLKGATE_CON(16), 0, GFLAGS), 756 680 GATE(0, "pclk_isp_in", "ext_isp", 0, RK3288_CLKGATE_CON(16), 3, GFLAGS), 681 + }; 682 + 683 + static const char *rk3288_critical_clocks[] __initconst = { 684 + "aclk_cpu", 685 + "aclk_peri", 686 + "hclk_peri", 757 687 }; 758 688 759 689 static void __init rk3288_clk_init(struct device_node *np) ··· 787 705 pr_warn("%s: could not register clock usb480m: %ld\n", 788 706 __func__, PTR_ERR(clk)); 789 707 708 + clk = clk_register_fixed_factor(NULL, "hclk_vcodec_pre", 709 + "hclk_vcodec_pre_v", 0, 1, 4); 710 + if (IS_ERR(clk)) 711 + pr_warn("%s: could not register clock hclk_vcodec_pre: %ld\n", 712 + __func__, PTR_ERR(clk)); 713 + 790 714 rockchip_clk_register_plls(rk3288_pll_clks, 791 715 ARRAY_SIZE(rk3288_pll_clks), 792 - RK3288_GRF_SOC_STATUS); 716 + RK3288_GRF_SOC_STATUS1); 793 717 rockchip_clk_register_branches(rk3288_clk_branches, 794 718 ARRAY_SIZE(rk3288_clk_branches)); 719 + rockchip_clk_protect_critical(rk3288_critical_clocks, 720 + ARRAY_SIZE(rk3288_critical_clocks)); 795 721 796 - rockchip_register_softrst(np, 9, reg_base + RK3288_SOFTRST_CON(0), 722 + rockchip_clk_register_armclk(ARMCLK, "armclk", 723 + mux_armclk_p, ARRAY_SIZE(mux_armclk_p), 724 + &rk3288_cpuclk_data, rk3288_cpuclk_rates, 725 + ARRAY_SIZE(rk3288_cpuclk_rates)); 726 + 727 + rockchip_register_softrst(np, 12, reg_base + RK3288_SOFTRST_CON(0), 797 728 ROCKCHIP_SOFTRST_HIWORD_MASK); 729 + 730 + rockchip_register_restart_notifier(RK3288_GLB_SRST_FST); 798 731 } 799 732 CLK_OF_DECLARE(rk3288_cru, "rockchip,rk3288-cru", rk3288_clk_init);
+116 -3
drivers/clk/rockchip/clk.c
··· 25 25 #include <linux/clk-provider.h> 26 26 #include <linux/mfd/syscon.h> 27 27 #include <linux/regmap.h> 28 + #include <linux/reboot.h> 28 29 #include "clk.h" 29 30 30 31 /** ··· 38 37 * 39 38 * sometimes without one of those components. 40 39 */ 41 - struct clk *rockchip_clk_register_branch(const char *name, 40 + static struct clk *rockchip_clk_register_branch(const char *name, 42 41 const char **parent_names, u8 num_parents, void __iomem *base, 43 42 int muxdiv_offset, u8 mux_shift, u8 mux_width, u8 mux_flags, 44 43 u8 div_shift, u8 div_width, u8 div_flags, ··· 98 97 clk = clk_register_composite(NULL, name, parent_names, num_parents, 99 98 mux ? &mux->hw : NULL, mux_ops, 100 99 div ? &div->hw : NULL, div_ops, 100 + gate ? &gate->hw : NULL, gate_ops, 101 + flags); 102 + 103 + return clk; 104 + } 105 + 106 + static struct clk *rockchip_clk_register_frac_branch(const char *name, 107 + const char **parent_names, u8 num_parents, void __iomem *base, 108 + int muxdiv_offset, u8 div_flags, 109 + int gate_offset, u8 gate_shift, u8 gate_flags, 110 + unsigned long flags, spinlock_t *lock) 111 + { 112 + struct clk *clk; 113 + struct clk_gate *gate = NULL; 114 + struct clk_fractional_divider *div = NULL; 115 + const struct clk_ops *div_ops = NULL, *gate_ops = NULL; 116 + 117 + if (gate_offset >= 0) { 118 + gate = kzalloc(sizeof(*gate), GFP_KERNEL); 119 + if (!gate) 120 + return ERR_PTR(-ENOMEM); 121 + 122 + gate->flags = gate_flags; 123 + gate->reg = base + gate_offset; 124 + gate->bit_idx = gate_shift; 125 + gate->lock = lock; 126 + gate_ops = &clk_gate_ops; 127 + } 128 + 129 + if (muxdiv_offset < 0) 130 + return ERR_PTR(-EINVAL); 131 + 132 + div = kzalloc(sizeof(*div), GFP_KERNEL); 133 + if (!div) 134 + return ERR_PTR(-ENOMEM); 135 + 136 + div->flags = div_flags; 137 + div->reg = base + muxdiv_offset; 138 + div->mshift = 16; 139 + div->mmask = 0xffff0000; 140 + div->nshift = 0; 141 + div->nmask = 0xffff; 142 + div->lock = lock; 143 + div_ops = &clk_fractional_divider_ops; 144 + 145 + clk = clk_register_composite(NULL, name, parent_names, num_parents, 146 + NULL, NULL, 147 + &div->hw, div_ops, 101 148 gate ? &gate->hw : NULL, gate_ops, 102 149 flags); 103 150 ··· 246 197 list->div_flags, &clk_lock); 247 198 break; 248 199 case branch_fraction_divider: 249 - /* unimplemented */ 250 - continue; 200 + /* keep all gates untouched for now */ 201 + flags |= CLK_IGNORE_UNUSED; 202 + 203 + clk = rockchip_clk_register_frac_branch(list->name, 204 + list->parent_names, list->num_parents, 205 + reg_base, list->muxdiv_offset, list->div_flags, 206 + list->gate_offset, list->gate_shift, 207 + list->gate_flags, flags, &clk_lock); 251 208 break; 252 209 case branch_gate: 253 210 flags |= CLK_SET_RATE_PARENT; ··· 296 241 297 242 rockchip_clk_add_lookup(clk, list->id); 298 243 } 244 + } 245 + 246 + void __init rockchip_clk_register_armclk(unsigned int lookup_id, 247 + const char *name, const char **parent_names, 248 + u8 num_parents, 249 + const struct rockchip_cpuclk_reg_data *reg_data, 250 + const struct rockchip_cpuclk_rate_table *rates, 251 + int nrates) 252 + { 253 + struct clk *clk; 254 + 255 + clk = rockchip_clk_register_cpuclk(name, parent_names, num_parents, 256 + reg_data, rates, nrates, reg_base, 257 + &clk_lock); 258 + if (IS_ERR(clk)) { 259 + pr_err("%s: failed to register clock %s: %ld\n", 260 + __func__, name, PTR_ERR(clk)); 261 + return; 262 + } 263 + 264 + rockchip_clk_add_lookup(clk, lookup_id); 265 + } 266 + 267 + void __init rockchip_clk_protect_critical(const char *clocks[], int nclocks) 268 + { 269 + int i; 270 + 271 + /* Protect the clocks that needs to stay on */ 272 + for (i = 0; i < nclocks; i++) { 273 + struct clk *clk = __clk_lookup(clocks[i]); 274 + 275 + if (clk) 276 + clk_prepare_enable(clk); 277 + } 278 + } 279 + 280 + static unsigned int reg_restart; 281 + static int rockchip_restart_notify(struct notifier_block *this, 282 + unsigned long mode, void *cmd) 283 + { 284 + writel(0xfdb9, reg_base + reg_restart); 285 + return NOTIFY_DONE; 286 + } 287 + 288 + static struct notifier_block rockchip_restart_handler = { 289 + .notifier_call = rockchip_restart_notify, 290 + .priority = 128, 291 + }; 292 + 293 + void __init rockchip_register_restart_notifier(unsigned int reg) 294 + { 295 + int ret; 296 + 297 + reg_restart = reg; 298 + ret = register_restart_handler(&rockchip_restart_handler); 299 + if (ret) 300 + pr_err("%s: cannot register restart handler, %d\n", 301 + __func__, ret); 299 302 }
+39
drivers/clk/rockchip/clk.h
··· 120 120 struct rockchip_pll_rate_table *rate_table, 121 121 spinlock_t *lock); 122 122 123 + struct rockchip_cpuclk_clksel { 124 + int reg; 125 + u32 val; 126 + }; 127 + 128 + #define ROCKCHIP_CPUCLK_NUM_DIVIDERS 2 129 + struct rockchip_cpuclk_rate_table { 130 + unsigned long prate; 131 + struct rockchip_cpuclk_clksel divs[ROCKCHIP_CPUCLK_NUM_DIVIDERS]; 132 + }; 133 + 134 + /** 135 + * struct rockchip_cpuclk_reg_data: describes register offsets and masks of the cpuclock 136 + * @core_reg: register offset of the core settings register 137 + * @div_core_shift: core divider offset used to divide the pll value 138 + * @div_core_mask: core divider mask 139 + * @mux_core_shift: offset of the core multiplexer 140 + */ 141 + struct rockchip_cpuclk_reg_data { 142 + int core_reg; 143 + u8 div_core_shift; 144 + u32 div_core_mask; 145 + int mux_core_reg; 146 + u8 mux_core_shift; 147 + }; 148 + 149 + struct clk *rockchip_clk_register_cpuclk(const char *name, 150 + const char **parent_names, u8 num_parents, 151 + const struct rockchip_cpuclk_reg_data *reg_data, 152 + const struct rockchip_cpuclk_rate_table *rates, 153 + int nrates, void __iomem *reg_base, spinlock_t *lock); 154 + 123 155 #define PNAME(x) static const char *x[] __initconst 124 156 125 157 enum rockchip_clk_branch_type { ··· 361 329 unsigned int nr_clk); 362 330 void rockchip_clk_register_plls(struct rockchip_pll_clock *pll_list, 363 331 unsigned int nr_pll, int grf_lock_offset); 332 + void rockchip_clk_register_armclk(unsigned int lookup_id, const char *name, 333 + const char **parent_names, u8 num_parents, 334 + const struct rockchip_cpuclk_reg_data *reg_data, 335 + const struct rockchip_cpuclk_rate_table *rates, 336 + int nrates); 337 + void rockchip_clk_protect_critical(const char *clocks[], int nclocks); 338 + void rockchip_register_restart_notifier(unsigned int reg); 364 339 365 340 #define ROCKCHIP_SOFTRST_HIWORD_MASK BIT(0) 366 341
+199 -3
drivers/clk/samsung/clk-exynos3250.c
··· 110 110 nr_plls 111 111 }; 112 112 113 + /* list of PLLs in DMC block to be registered */ 114 + enum exynos3250_dmc_plls { 115 + bpll, epll, 116 + nr_dmc_plls 117 + }; 118 + 113 119 static void __iomem *reg_base; 120 + static void __iomem *dmc_reg_base; 114 121 115 122 /* 116 123 * Support for CMU save/restore across system suspends ··· 273 266 "none", "none", "none", 274 267 "none", "div_mpll_pre", 275 268 "mout_epll_user", "mout_vpll", 269 + "none", "none", "none", 276 270 "div_cam_blk_320", }; 277 271 PNAME(group_sclk_fimd0_p) = { "xxti", "xusbxti", 278 272 "m_bitclkhsdiv4_2l", "none", ··· 361 353 362 354 /* SRC_FSYS */ 363 355 MUX(CLK_MOUT_TSADC, "mout_tsadc", group_sclk_p, SRC_FSYS, 28, 4), 364 - MUX(CLK_MOUT_MMC1, "mout_mmc1", group_sclk_p, SRC_FSYS, 4, 3), 365 - MUX(CLK_MOUT_MMC0, "mout_mmc0", group_sclk_p, SRC_FSYS, 0, 3), 356 + MUX(CLK_MOUT_MMC1, "mout_mmc1", group_sclk_p, SRC_FSYS, 4, 4), 357 + MUX(CLK_MOUT_MMC0, "mout_mmc0", group_sclk_p, SRC_FSYS, 0, 4), 366 358 367 359 /* SRC_PERIL0 */ 368 360 MUX(CLK_MOUT_UART1, "mout_uart1", group_sclk_p, SRC_PERIL0, 4, 4), ··· 431 423 DIV(CLK_DIV_SPI1_ISP, "div_spi1_isp", "mout_spi1_isp", DIV_ISP, 16, 4), 432 424 DIV_F(CLK_DIV_SPI0_ISP_PRE, "div_spi0_isp_pre", "div_spi0_isp", 433 425 DIV_ISP, 8, 8, CLK_SET_RATE_PARENT, 0), 434 - DIV(CLK_DIV_SPI0_ISP, "div_spi0_isp", "mout_spi0_isp", DIV_ISP, 0, 4), 426 + DIV(CLK_DIV_SPI0_ISP, "div_spi0_isp", "mout_spi0_isp", DIV_ISP, 4, 4), 435 427 436 428 /* DIV_FSYS0 */ 437 429 DIV_F(CLK_DIV_TSADC_PRE, "div_tsadc_pre", "div_tsadc", DIV_FSYS0, 8, 8, ··· 732 724 { /* sentinel */ } 733 725 }; 734 726 727 + /* EPLL */ 728 + static struct samsung_pll_rate_table exynos3250_epll_rates[] = { 729 + PLL_36XX_RATE(800000000, 200, 3, 1, 0), 730 + PLL_36XX_RATE(288000000, 96, 2, 2, 0), 731 + PLL_36XX_RATE(192000000, 128, 2, 3, 0), 732 + PLL_36XX_RATE(144000000, 96, 2, 3, 0), 733 + PLL_36XX_RATE( 96000000, 128, 2, 4, 0), 734 + PLL_36XX_RATE( 84000000, 112, 2, 4, 0), 735 + PLL_36XX_RATE( 80000004, 106, 2, 4, 43691), 736 + PLL_36XX_RATE( 73728000, 98, 2, 4, 19923), 737 + PLL_36XX_RATE( 67737598, 270, 3, 5, 62285), 738 + PLL_36XX_RATE( 65535999, 174, 2, 5, 49982), 739 + PLL_36XX_RATE( 50000000, 200, 3, 5, 0), 740 + PLL_36XX_RATE( 49152002, 131, 2, 5, 4719), 741 + PLL_36XX_RATE( 48000000, 128, 2, 5, 0), 742 + PLL_36XX_RATE( 45158401, 180, 3, 5, 41524), 743 + { /* sentinel */ } 744 + }; 745 + 735 746 /* VPLL */ 736 747 static struct samsung_pll_rate_table exynos3250_vpll_rates[] = { 737 748 PLL_36XX_RATE(600000000, 100, 2, 1, 0), ··· 848 821 samsung_clk_of_add_provider(np, ctx); 849 822 } 850 823 CLK_OF_DECLARE(exynos3250_cmu, "samsung,exynos3250-cmu", exynos3250_cmu_init); 824 + 825 + /* 826 + * CMU DMC 827 + */ 828 + 829 + #define BPLL_LOCK 0x0118 830 + #define BPLL_CON0 0x0218 831 + #define BPLL_CON1 0x021c 832 + #define BPLL_CON2 0x0220 833 + #define SRC_DMC 0x0300 834 + #define DIV_DMC1 0x0504 835 + #define GATE_BUS_DMC0 0x0700 836 + #define GATE_BUS_DMC1 0x0704 837 + #define GATE_BUS_DMC2 0x0708 838 + #define GATE_BUS_DMC3 0x070c 839 + #define GATE_SCLK_DMC 0x0800 840 + #define GATE_IP_DMC0 0x0900 841 + #define GATE_IP_DMC1 0x0904 842 + #define EPLL_LOCK 0x1110 843 + #define EPLL_CON0 0x1114 844 + #define EPLL_CON1 0x1118 845 + #define EPLL_CON2 0x111c 846 + #define SRC_EPLL 0x1120 847 + 848 + /* 849 + * Support for CMU save/restore across system suspends 850 + */ 851 + #ifdef CONFIG_PM_SLEEP 852 + static struct samsung_clk_reg_dump *exynos3250_dmc_clk_regs; 853 + 854 + static unsigned long exynos3250_cmu_dmc_clk_regs[] __initdata = { 855 + BPLL_LOCK, 856 + BPLL_CON0, 857 + BPLL_CON1, 858 + BPLL_CON2, 859 + SRC_DMC, 860 + DIV_DMC1, 861 + GATE_BUS_DMC0, 862 + GATE_BUS_DMC1, 863 + GATE_BUS_DMC2, 864 + GATE_BUS_DMC3, 865 + GATE_SCLK_DMC, 866 + GATE_IP_DMC0, 867 + GATE_IP_DMC1, 868 + EPLL_LOCK, 869 + EPLL_CON0, 870 + EPLL_CON1, 871 + EPLL_CON2, 872 + SRC_EPLL, 873 + }; 874 + 875 + static int exynos3250_dmc_clk_suspend(void) 876 + { 877 + samsung_clk_save(dmc_reg_base, exynos3250_dmc_clk_regs, 878 + ARRAY_SIZE(exynos3250_cmu_dmc_clk_regs)); 879 + return 0; 880 + } 881 + 882 + static void exynos3250_dmc_clk_resume(void) 883 + { 884 + samsung_clk_restore(dmc_reg_base, exynos3250_dmc_clk_regs, 885 + ARRAY_SIZE(exynos3250_cmu_dmc_clk_regs)); 886 + } 887 + 888 + static struct syscore_ops exynos3250_dmc_clk_syscore_ops = { 889 + .suspend = exynos3250_dmc_clk_suspend, 890 + .resume = exynos3250_dmc_clk_resume, 891 + }; 892 + 893 + static void exynos3250_dmc_clk_sleep_init(void) 894 + { 895 + exynos3250_dmc_clk_regs = 896 + samsung_clk_alloc_reg_dump(exynos3250_cmu_dmc_clk_regs, 897 + ARRAY_SIZE(exynos3250_cmu_dmc_clk_regs)); 898 + if (!exynos3250_dmc_clk_regs) { 899 + pr_warn("%s: Failed to allocate sleep save data\n", __func__); 900 + goto err; 901 + } 902 + 903 + register_syscore_ops(&exynos3250_dmc_clk_syscore_ops); 904 + return; 905 + err: 906 + kfree(exynos3250_dmc_clk_regs); 907 + } 908 + #else 909 + static inline void exynos3250_dmc_clk_sleep_init(void) { } 910 + #endif 911 + 912 + PNAME(mout_epll_p) = { "fin_pll", "fout_epll", }; 913 + PNAME(mout_bpll_p) = { "fin_pll", "fout_bpll", }; 914 + PNAME(mout_mpll_mif_p) = { "fin_pll", "sclk_mpll_mif", }; 915 + PNAME(mout_dphy_p) = { "mout_mpll_mif", "mout_bpll", }; 916 + 917 + static struct samsung_mux_clock dmc_mux_clks[] __initdata = { 918 + /* 919 + * NOTE: Following table is sorted by register address in ascending 920 + * order and then bitfield shift in descending order, as it is done 921 + * in the User's Manual. When adding new entries, please make sure 922 + * that the order is preserved, to avoid merge conflicts and make 923 + * further work with defined data easier. 924 + */ 925 + 926 + /* SRC_DMC */ 927 + MUX(CLK_MOUT_MPLL_MIF, "mout_mpll_mif", mout_mpll_mif_p, SRC_DMC, 12, 1), 928 + MUX(CLK_MOUT_BPLL, "mout_bpll", mout_bpll_p, SRC_DMC, 10, 1), 929 + MUX(CLK_MOUT_DPHY, "mout_dphy", mout_dphy_p, SRC_DMC, 8, 1), 930 + MUX(CLK_MOUT_DMC_BUS, "mout_dmc_bus", mout_dphy_p, SRC_DMC, 4, 1), 931 + 932 + /* SRC_EPLL */ 933 + MUX(CLK_MOUT_EPLL, "mout_epll", mout_epll_p, SRC_EPLL, 4, 1), 934 + }; 935 + 936 + static struct samsung_div_clock dmc_div_clks[] __initdata = { 937 + /* 938 + * NOTE: Following table is sorted by register address in ascending 939 + * order and then bitfield shift in descending order, as it is done 940 + * in the User's Manual. When adding new entries, please make sure 941 + * that the order is preserved, to avoid merge conflicts and make 942 + * further work with defined data easier. 943 + */ 944 + 945 + /* DIV_DMC1 */ 946 + DIV(CLK_DIV_DMC, "div_dmc", "div_dmc_pre", DIV_DMC1, 27, 3), 947 + DIV(CLK_DIV_DPHY, "div_dphy", "mout_dphy", DIV_DMC1, 23, 3), 948 + DIV(CLK_DIV_DMC_PRE, "div_dmc_pre", "mout_dmc_bus", DIV_DMC1, 19, 2), 949 + DIV(CLK_DIV_DMCP, "div_dmcp", "div_dmcd", DIV_DMC1, 15, 3), 950 + DIV(CLK_DIV_DMCD, "div_dmcd", "div_dmc", DIV_DMC1, 11, 3), 951 + }; 952 + 953 + static struct samsung_pll_clock exynos3250_dmc_plls[nr_dmc_plls] __initdata = { 954 + [bpll] = PLL(pll_35xx, CLK_FOUT_BPLL, "fout_bpll", "fin_pll", 955 + BPLL_LOCK, BPLL_CON0, NULL), 956 + [epll] = PLL(pll_36xx, CLK_FOUT_EPLL, "fout_epll", "fin_pll", 957 + EPLL_LOCK, EPLL_CON0, NULL), 958 + }; 959 + 960 + static void __init exynos3250_cmu_dmc_init(struct device_node *np) 961 + { 962 + struct samsung_clk_provider *ctx; 963 + 964 + dmc_reg_base = of_iomap(np, 0); 965 + if (!dmc_reg_base) 966 + panic("%s: failed to map registers\n", __func__); 967 + 968 + ctx = samsung_clk_init(np, dmc_reg_base, NR_CLKS_DMC); 969 + if (!ctx) 970 + panic("%s: unable to allocate context.\n", __func__); 971 + 972 + exynos3250_dmc_plls[bpll].rate_table = exynos3250_pll_rates; 973 + exynos3250_dmc_plls[epll].rate_table = exynos3250_epll_rates; 974 + 975 + pr_err("CLK registering epll bpll: %d, %d, %d, %d\n", 976 + exynos3250_dmc_plls[bpll].rate_table[0].rate, 977 + exynos3250_dmc_plls[bpll].rate_table[0].mdiv, 978 + exynos3250_dmc_plls[bpll].rate_table[0].pdiv, 979 + exynos3250_dmc_plls[bpll].rate_table[0].sdiv 980 + ); 981 + samsung_clk_register_pll(ctx, exynos3250_dmc_plls, 982 + ARRAY_SIZE(exynos3250_dmc_plls), dmc_reg_base); 983 + 984 + samsung_clk_register_mux(ctx, dmc_mux_clks, ARRAY_SIZE(dmc_mux_clks)); 985 + samsung_clk_register_div(ctx, dmc_div_clks, ARRAY_SIZE(dmc_div_clks)); 986 + 987 + exynos3250_dmc_clk_sleep_init(); 988 + 989 + samsung_clk_of_add_provider(np, ctx); 990 + } 991 + CLK_OF_DECLARE(exynos3250_cmu_dmc, "samsung,exynos3250-cmu-dmc", 992 + exynos3250_cmu_dmc_init);
+8 -10
drivers/clk/samsung/clk-exynos4.c
··· 517 517 FFACTOR(0, "sclk_apll_div_2", "sclk_apll", 1, 2, 0), 518 518 FFACTOR(0, "fout_mpll_div_2", "fout_mpll", 1, 2, 0), 519 519 FFACTOR(0, "fout_apll_div_2", "fout_apll", 1, 2, 0), 520 - FFACTOR(0, "arm_clk_div_2", "arm_clk", 1, 2, 0), 520 + FFACTOR(0, "arm_clk_div_2", "div_core2", 1, 2, 0), 521 521 }; 522 522 523 523 static struct samsung_fixed_factor_clock exynos4210_fixed_factor_clks[] __initdata = { ··· 535 535 static struct samsung_mux_clock exynos4_mux_clks[] __initdata = { 536 536 MUX_FA(CLK_MOUT_APLL, "mout_apll", mout_apll_p, SRC_CPU, 0, 1, 537 537 CLK_SET_RATE_PARENT, 0, "mout_apll"), 538 - MUX(0, "mout_hdmi", mout_hdmi_p, SRC_TV, 0, 1), 538 + MUX(CLK_MOUT_HDMI, "mout_hdmi", mout_hdmi_p, SRC_TV, 0, 1), 539 539 MUX(0, "mout_mfc1", sclk_evpll_p, SRC_MFC, 4, 1), 540 540 MUX(0, "mout_mfc", mout_mfc_p, SRC_MFC, 8, 1), 541 541 MUX_F(CLK_MOUT_G3D1, "mout_g3d1", sclk_evpll_p, SRC_G3D, 4, 1, ··· 569 569 MUX(0, "mout_aclk100", sclk_ampll_p4210, SRC_TOP0, 16, 1), 570 570 MUX(0, "mout_aclk160", sclk_ampll_p4210, SRC_TOP0, 20, 1), 571 571 MUX(0, "mout_aclk133", sclk_ampll_p4210, SRC_TOP0, 24, 1), 572 - MUX(0, "mout_mixer", mout_mixer_p4210, SRC_TV, 4, 1), 572 + MUX(CLK_MOUT_MIXER, "mout_mixer", mout_mixer_p4210, SRC_TV, 4, 1), 573 573 MUX(0, "mout_dac", mout_dac_p4210, SRC_TV, 8, 1), 574 574 MUX(0, "mout_g2d0", sclk_ampll_p4210, E4210_SRC_IMAGE, 0, 1), 575 575 MUX(0, "mout_g2d1", sclk_evpll_p, E4210_SRC_IMAGE, 4, 1), ··· 719 719 DIV(0, "div_periph", "div_core2", DIV_CPU0, 12, 3), 720 720 DIV(0, "div_atb", "mout_core", DIV_CPU0, 16, 3), 721 721 DIV(0, "div_pclk_dbg", "div_atb", DIV_CPU0, 20, 3), 722 - DIV(0, "div_core2", "div_core", DIV_CPU0, 28, 3), 722 + DIV(CLK_ARM_CLK, "div_core2", "div_core", DIV_CPU0, 28, 3), 723 723 DIV(0, "div_copy", "mout_hpm", DIV_CPU1, 0, 3), 724 724 DIV(0, "div_hpm", "div_copy", DIV_CPU1, 4, 3), 725 725 DIV(0, "div_clkout_cpu", "mout_clkout_cpu", CLKOUT_CMU_CPU, 8, 6), ··· 733 733 DIV(0, "div_csis0", "mout_csis0", DIV_CAM, 24, 4), 734 734 DIV(0, "div_csis1", "mout_csis1", DIV_CAM, 28, 4), 735 735 DIV(CLK_SCLK_MFC, "sclk_mfc", "mout_mfc", DIV_MFC, 0, 4), 736 - DIV_F(0, "div_g3d", "mout_g3d", DIV_G3D, 0, 4, 737 - CLK_SET_RATE_PARENT, 0), 736 + DIV(CLK_SCLK_G3D, "sclk_g3d", "mout_g3d", DIV_G3D, 0, 4), 738 737 DIV(0, "div_fimd0", "mout_fimd0", DIV_LCD0, 0, 4), 739 738 DIV(0, "div_mipi0", "mout_mipi0", DIV_LCD0, 16, 4), 740 739 DIV(0, "div_audio0", "mout_audio0", DIV_MAUDIO, 0, 4), ··· 768 769 DIV(0, "div_spi_pre2", "div_spi2", DIV_PERIL2, 8, 8), 769 770 DIV(0, "div_audio1", "mout_audio1", DIV_PERIL4, 0, 4), 770 771 DIV(0, "div_audio2", "mout_audio2", DIV_PERIL4, 16, 4), 771 - DIV(CLK_ARM_CLK, "arm_clk", "div_core2", DIV_CPU0, 28, 3), 772 772 DIV(CLK_SCLK_APLL, "sclk_apll", "mout_apll", DIV_CPU0, 24, 3), 773 773 DIV_F(0, "div_mipi_pre0", "div_mipi0", DIV_LCD0, 20, 4, 774 774 CLK_SET_RATE_PARENT, 0), ··· 855 857 0), 856 858 GATE(CLK_TSI, "tsi", "aclk133", GATE_IP_FSYS, 4, 0, 0), 857 859 GATE(CLK_SROMC, "sromc", "aclk133", GATE_IP_FSYS, 11, 0, 0), 858 - GATE(CLK_SCLK_G3D, "sclk_g3d", "div_g3d", GATE_IP_G3D, 0, 859 - CLK_SET_RATE_PARENT, 0), 860 + GATE(CLK_G3D, "g3d", "aclk200", GATE_IP_G3D, 0, 0, 0), 860 861 GATE(CLK_PPMUG3D, "ppmug3d", "aclk200", GATE_IP_G3D, 1, 0, 0), 861 862 GATE(CLK_USB_DEVICE, "usb_device", "aclk133", GATE_IP_FSYS, 13, 0, 0), 862 863 GATE(CLK_ONENAND, "onenand", "aclk133", GATE_IP_FSYS, 15, 0, 0), ··· 1180 1183 GATE(CLK_SPI1_ISP, "spi1_isp", "aclk200", E4X12_GATE_ISP1, 13, 1181 1184 CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), 1182 1185 GATE(CLK_G2D, "g2d", "aclk200", GATE_IP_DMC, 23, 0, 0), 1186 + GATE(CLK_SMMU_G2D, "smmu_g2d", "aclk200", GATE_IP_DMC, 24, 0, 0), 1183 1187 GATE(CLK_TMU_APBIF, "tmu_apbif", "aclk100", E4X12_GATE_IP_PERIR, 17, 0, 1184 1188 0), 1185 1189 }; ··· 1484 1486 exynos4_soc == EXYNOS4210 ? "Exynos4210" : "Exynos4x12", 1485 1487 _get_rate("sclk_apll"), _get_rate("sclk_mpll"), 1486 1488 _get_rate("sclk_epll"), _get_rate("sclk_vpll"), 1487 - _get_rate("arm_clk")); 1489 + _get_rate("div_core2")); 1488 1490 } 1489 1491 1490 1492
+1 -1
drivers/clk/samsung/clk-exynos5260.c
··· 1581 1581 FRATE(PHYCLK_HDMI_LINK_O_TMDS_CLKHI, "phyclk_hdmi_link_o_tmds_clkhi", 1582 1582 NULL, CLK_IS_ROOT, 125000000), 1583 1583 FRATE(PHYCLK_MIPI_DPHY_4L_M_TXBYTECLKHS, 1584 - "phyclk_mipi_dphy_4l_m_txbyteclkhs" , NULL, 1584 + "phyclk_mipi_dphy_4l_m_txbyte_clkhs" , NULL, 1585 1585 CLK_IS_ROOT, 187500000), 1586 1586 FRATE(PHYCLK_DPTX_PHY_O_REF_CLK_24M, "phyclk_dptx_phy_o_ref_clk_24m", 1587 1587 NULL, CLK_IS_ROOT, 24000000),
-1
drivers/clk/samsung/clk-s3c2410-dclk.c
··· 426 426 static struct platform_driver s3c24xx_dclk_driver = { 427 427 .driver = { 428 428 .name = "s3c24xx-dclk", 429 - .owner = THIS_MODULE, 430 429 .pm = &s3c24xx_dclk_pm_ops, 431 430 }, 432 431 .probe = s3c24xx_dclk_probe,
+29
drivers/clk/samsung/clk-s3c2412.c
··· 14 14 #include <linux/of.h> 15 15 #include <linux/of_address.h> 16 16 #include <linux/syscore_ops.h> 17 + #include <linux/reboot.h> 17 18 18 19 #include <dt-bindings/clock/s3c2412.h> 19 20 ··· 27 26 #define CLKCON 0x0c 28 27 #define CLKDIVN 0x14 29 28 #define CLKSRC 0x1c 29 + #define SWRST 0x30 30 30 31 31 /* list of PLLs to be registered */ 32 32 enum s3c2412_plls { ··· 206 204 ALIAS(MSYSCLK, NULL, "fclk"), 207 205 }; 208 206 207 + static int s3c2412_restart(struct notifier_block *this, 208 + unsigned long mode, void *cmd) 209 + { 210 + /* errata "Watch-dog/Software Reset Problem" specifies that 211 + * this reset must be done with the SYSCLK sourced from 212 + * EXTCLK instead of FOUT to avoid a glitch in the reset 213 + * mechanism. 214 + * 215 + * See the watchdog section of the S3C2412 manual for more 216 + * information on this fix. 217 + */ 218 + 219 + __raw_writel(0x00, reg_base + CLKSRC); 220 + __raw_writel(0x533C2412, reg_base + SWRST); 221 + return NOTIFY_DONE; 222 + } 223 + 224 + static struct notifier_block s3c2412_restart_handler = { 225 + .notifier_call = s3c2412_restart, 226 + .priority = 129, 227 + }; 228 + 209 229 /* 210 230 * fixed rate clocks generated outside the soc 211 231 * Only necessary until the devicetree-move is complete ··· 257 233 unsigned long ext_f, void __iomem *base) 258 234 { 259 235 struct samsung_clk_provider *ctx; 236 + int ret; 260 237 reg_base = base; 261 238 262 239 if (np) { ··· 292 267 s3c2412_clk_sleep_init(); 293 268 294 269 samsung_clk_of_add_provider(np, ctx); 270 + 271 + ret = register_restart_handler(&s3c2412_restart_handler); 272 + if (ret) 273 + pr_warn("cannot register restart handler, %d\n", ret); 295 274 } 296 275 297 276 static void __init s3c2412_clk_init(struct device_node *np)
+19
drivers/clk/samsung/clk-s3c2443.c
··· 14 14 #include <linux/of.h> 15 15 #include <linux/of_address.h> 16 16 #include <linux/syscore_ops.h> 17 + #include <linux/reboot.h> 17 18 18 19 #include <dt-bindings/clock/s3c2443.h> 19 20 ··· 34 33 #define HCLKCON 0x30 35 34 #define PCLKCON 0x34 36 35 #define SCLKCON 0x38 36 + #define SWRST 0x44 37 37 38 38 /* the soc types */ 39 39 enum supported_socs { ··· 356 354 ALIAS(PCLK_I2C1, "s3c2410-i2c.1", "i2c"), 357 355 }; 358 356 357 + static int s3c2443_restart(struct notifier_block *this, 358 + unsigned long mode, void *cmd) 359 + { 360 + __raw_writel(0x533c2443, reg_base + SWRST); 361 + return NOTIFY_DONE; 362 + } 363 + 364 + static struct notifier_block s3c2443_restart_handler = { 365 + .notifier_call = s3c2443_restart, 366 + .priority = 129, 367 + }; 368 + 359 369 /* 360 370 * fixed rate clocks generated outside the soc 361 371 * Only necessary until the devicetree-move is complete ··· 392 378 void __iomem *base) 393 379 { 394 380 struct samsung_clk_provider *ctx; 381 + int ret; 395 382 reg_base = base; 396 383 397 384 if (np) { ··· 462 447 s3c2443_clk_sleep_init(); 463 448 464 449 samsung_clk_of_add_provider(np, ctx); 450 + 451 + ret = register_restart_handler(&s3c2443_restart_handler); 452 + if (ret) 453 + pr_warn("cannot register restart handler, %d\n", ret); 465 454 } 466 455 467 456 static void __init s3c2416_clk_init(struct device_node *np)
+1
drivers/clk/shmobile/clk-rcar-gen2.c
··· 202 202 }; 203 203 204 204 static const struct clk_div_table cpg_sd01_div_table[] = { 205 + { 4, 8 }, 205 206 { 5, 12 }, { 6, 16 }, { 7, 18 }, { 8, 24 }, 206 207 { 10, 36 }, { 11, 48 }, { 12, 10 }, { 0, 0 }, 207 208 };
+2
drivers/clk/sunxi/Makefile
··· 5 5 obj-y += clk-sunxi.o clk-factors.o 6 6 obj-y += clk-a10-hosc.o 7 7 obj-y += clk-a20-gmac.o 8 + obj-y += clk-mod0.o 9 + obj-y += clk-sun8i-mbus.o 8 10 9 11 obj-$(CONFIG_MFD_SUN6I_PRCM) += \ 10 12 clk-sun6i-ar100.o clk-sun6i-apb0.o clk-sun6i-apb0-gates.o \
+97 -8
drivers/clk/sunxi/clk-factors.c
··· 9 9 */ 10 10 11 11 #include <linux/clk-provider.h> 12 - #include <linux/module.h> 13 - #include <linux/slab.h> 14 - #include <linux/io.h> 15 - #include <linux/err.h> 16 - #include <linux/string.h> 17 - 18 12 #include <linux/delay.h> 13 + #include <linux/err.h> 14 + #include <linux/io.h> 15 + #include <linux/module.h> 16 + #include <linux/of_address.h> 17 + #include <linux/slab.h> 18 + #include <linux/string.h> 19 19 20 20 #include "clk-factors.h" 21 21 22 22 /* 23 - * DOC: basic adjustable factor-based clock that cannot gate 23 + * DOC: basic adjustable factor-based clock 24 24 * 25 25 * Traits of this clock: 26 26 * prepare - clk_prepare only ensures that parents are prepared ··· 31 31 */ 32 32 33 33 #define to_clk_factors(_hw) container_of(_hw, struct clk_factors, hw) 34 + 35 + #define FACTORS_MAX_PARENTS 5 34 36 35 37 #define SETMASK(len, pos) (((1U << (len)) - 1) << (pos)) 36 38 #define CLRMASK(len, pos) (~(SETMASK(len, pos))) ··· 149 147 return 0; 150 148 } 151 149 152 - const struct clk_ops clk_factors_ops = { 150 + static const struct clk_ops clk_factors_ops = { 153 151 .determine_rate = clk_factors_determine_rate, 154 152 .recalc_rate = clk_factors_recalc_rate, 155 153 .round_rate = clk_factors_round_rate, 156 154 .set_rate = clk_factors_set_rate, 157 155 }; 156 + 157 + struct clk * __init sunxi_factors_register(struct device_node *node, 158 + const struct factors_data *data, 159 + spinlock_t *lock) 160 + { 161 + struct clk *clk; 162 + struct clk_factors *factors; 163 + struct clk_gate *gate = NULL; 164 + struct clk_mux *mux = NULL; 165 + struct clk_hw *gate_hw = NULL; 166 + struct clk_hw *mux_hw = NULL; 167 + const char *clk_name = node->name; 168 + const char *parents[FACTORS_MAX_PARENTS]; 169 + void __iomem *reg; 170 + int i = 0; 171 + 172 + reg = of_iomap(node, 0); 173 + 174 + /* if we have a mux, we will have >1 parents */ 175 + while (i < FACTORS_MAX_PARENTS && 176 + (parents[i] = of_clk_get_parent_name(node, i)) != NULL) 177 + i++; 178 + 179 + /* 180 + * some factor clocks, such as pll5 and pll6, may have multiple 181 + * outputs, and have their name designated in factors_data 182 + */ 183 + if (data->name) 184 + clk_name = data->name; 185 + else 186 + of_property_read_string(node, "clock-output-names", &clk_name); 187 + 188 + factors = kzalloc(sizeof(struct clk_factors), GFP_KERNEL); 189 + if (!factors) 190 + return NULL; 191 + 192 + /* set up factors properties */ 193 + factors->reg = reg; 194 + factors->config = data->table; 195 + factors->get_factors = data->getter; 196 + factors->lock = lock; 197 + 198 + /* Add a gate if this factor clock can be gated */ 199 + if (data->enable) { 200 + gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL); 201 + if (!gate) { 202 + kfree(factors); 203 + return NULL; 204 + } 205 + 206 + /* set up gate properties */ 207 + gate->reg = reg; 208 + gate->bit_idx = data->enable; 209 + gate->lock = factors->lock; 210 + gate_hw = &gate->hw; 211 + } 212 + 213 + /* Add a mux if this factor clock can be muxed */ 214 + if (data->mux) { 215 + mux = kzalloc(sizeof(struct clk_mux), GFP_KERNEL); 216 + if (!mux) { 217 + kfree(factors); 218 + kfree(gate); 219 + return NULL; 220 + } 221 + 222 + /* set up gate properties */ 223 + mux->reg = reg; 224 + mux->shift = data->mux; 225 + mux->mask = SUNXI_FACTORS_MUX_MASK; 226 + mux->lock = factors->lock; 227 + mux_hw = &mux->hw; 228 + } 229 + 230 + clk = clk_register_composite(NULL, clk_name, 231 + parents, i, 232 + mux_hw, &clk_mux_ops, 233 + &factors->hw, &clk_factors_ops, 234 + gate_hw, &clk_gate_ops, 0); 235 + 236 + if (!IS_ERR(clk)) { 237 + of_clk_add_provider(node, of_clk_src_simple_get, clk); 238 + clk_register_clkdev(clk, clk_name, NULL); 239 + } 240 + 241 + return clk; 242 + }
+15 -1
drivers/clk/sunxi/clk-factors.h
··· 3 3 4 4 #include <linux/clk-provider.h> 5 5 #include <linux/clkdev.h> 6 + #include <linux/spinlock.h> 6 7 7 8 #define SUNXI_FACTORS_NOT_APPLICABLE (0) 9 + 10 + #define SUNXI_FACTORS_MUX_MASK 0x3 8 11 9 12 struct clk_factors_config { 10 13 u8 nshift; ··· 21 18 u8 n_start; 22 19 }; 23 20 21 + struct factors_data { 22 + int enable; 23 + int mux; 24 + struct clk_factors_config *table; 25 + void (*getter) (u32 *rate, u32 parent_rate, u8 *n, u8 *k, u8 *m, u8 *p); 26 + const char *name; 27 + }; 28 + 24 29 struct clk_factors { 25 30 struct clk_hw hw; 26 31 void __iomem *reg; ··· 37 26 spinlock_t *lock; 38 27 }; 39 28 40 - extern const struct clk_ops clk_factors_ops; 29 + struct clk * __init sunxi_factors_register(struct device_node *node, 30 + const struct factors_data *data, 31 + spinlock_t *lock); 32 + 41 33 #endif
+283
drivers/clk/sunxi/clk-mod0.c
··· 1 + /* 2 + * Copyright 2013 Emilio López 3 + * 4 + * Emilio López <emilio@elopez.com.ar> 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 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + */ 16 + 17 + #include <linux/clk-provider.h> 18 + #include <linux/clkdev.h> 19 + #include <linux/of_address.h> 20 + 21 + #include "clk-factors.h" 22 + 23 + /** 24 + * sun4i_get_mod0_factors() - calculates m, n factors for MOD0-style clocks 25 + * MOD0 rate is calculated as follows 26 + * rate = (parent_rate >> p) / (m + 1); 27 + */ 28 + 29 + static void sun4i_a10_get_mod0_factors(u32 *freq, u32 parent_rate, 30 + u8 *n, u8 *k, u8 *m, u8 *p) 31 + { 32 + u8 div, calcm, calcp; 33 + 34 + /* These clocks can only divide, so we will never be able to achieve 35 + * frequencies higher than the parent frequency */ 36 + if (*freq > parent_rate) 37 + *freq = parent_rate; 38 + 39 + div = DIV_ROUND_UP(parent_rate, *freq); 40 + 41 + if (div < 16) 42 + calcp = 0; 43 + else if (div / 2 < 16) 44 + calcp = 1; 45 + else if (div / 4 < 16) 46 + calcp = 2; 47 + else 48 + calcp = 3; 49 + 50 + calcm = DIV_ROUND_UP(div, 1 << calcp); 51 + 52 + *freq = (parent_rate >> calcp) / calcm; 53 + 54 + /* we were called to round the frequency, we can now return */ 55 + if (n == NULL) 56 + return; 57 + 58 + *m = calcm - 1; 59 + *p = calcp; 60 + } 61 + 62 + /* user manual says "n" but it's really "p" */ 63 + static struct clk_factors_config sun4i_a10_mod0_config = { 64 + .mshift = 0, 65 + .mwidth = 4, 66 + .pshift = 16, 67 + .pwidth = 2, 68 + }; 69 + 70 + static const struct factors_data sun4i_a10_mod0_data __initconst = { 71 + .enable = 31, 72 + .mux = 24, 73 + .table = &sun4i_a10_mod0_config, 74 + .getter = sun4i_a10_get_mod0_factors, 75 + }; 76 + 77 + static DEFINE_SPINLOCK(sun4i_a10_mod0_lock); 78 + 79 + static void __init sun4i_a10_mod0_setup(struct device_node *node) 80 + { 81 + sunxi_factors_register(node, &sun4i_a10_mod0_data, &sun4i_a10_mod0_lock); 82 + } 83 + CLK_OF_DECLARE(sun4i_a10_mod0, "allwinner,sun4i-a10-mod0-clk", sun4i_a10_mod0_setup); 84 + 85 + static DEFINE_SPINLOCK(sun5i_a13_mbus_lock); 86 + 87 + static void __init sun5i_a13_mbus_setup(struct device_node *node) 88 + { 89 + struct clk *mbus = sunxi_factors_register(node, &sun4i_a10_mod0_data, &sun5i_a13_mbus_lock); 90 + 91 + /* The MBUS clocks needs to be always enabled */ 92 + __clk_get(mbus); 93 + clk_prepare_enable(mbus); 94 + } 95 + CLK_OF_DECLARE(sun5i_a13_mbus, "allwinner,sun5i-a13-mbus-clk", sun5i_a13_mbus_setup); 96 + 97 + struct mmc_phase_data { 98 + u8 offset; 99 + }; 100 + 101 + struct mmc_phase { 102 + struct clk_hw hw; 103 + void __iomem *reg; 104 + struct mmc_phase_data *data; 105 + spinlock_t *lock; 106 + }; 107 + 108 + #define to_mmc_phase(_hw) container_of(_hw, struct mmc_phase, hw) 109 + 110 + static int mmc_get_phase(struct clk_hw *hw) 111 + { 112 + struct clk *mmc, *mmc_parent, *clk = hw->clk; 113 + struct mmc_phase *phase = to_mmc_phase(hw); 114 + unsigned int mmc_rate, mmc_parent_rate; 115 + u16 step, mmc_div; 116 + u32 value; 117 + u8 delay; 118 + 119 + value = readl(phase->reg); 120 + delay = (value >> phase->data->offset) & 0x3; 121 + 122 + if (!delay) 123 + return 180; 124 + 125 + /* Get the main MMC clock */ 126 + mmc = clk_get_parent(clk); 127 + if (!mmc) 128 + return -EINVAL; 129 + 130 + /* And its rate */ 131 + mmc_rate = clk_get_rate(mmc); 132 + if (!mmc_rate) 133 + return -EINVAL; 134 + 135 + /* Now, get the MMC parent (most likely some PLL) */ 136 + mmc_parent = clk_get_parent(mmc); 137 + if (!mmc_parent) 138 + return -EINVAL; 139 + 140 + /* And its rate */ 141 + mmc_parent_rate = clk_get_rate(mmc_parent); 142 + if (!mmc_parent_rate) 143 + return -EINVAL; 144 + 145 + /* Get MMC clock divider */ 146 + mmc_div = mmc_parent_rate / mmc_rate; 147 + 148 + step = DIV_ROUND_CLOSEST(360, mmc_div); 149 + return delay * step; 150 + } 151 + 152 + static int mmc_set_phase(struct clk_hw *hw, int degrees) 153 + { 154 + struct clk *mmc, *mmc_parent, *clk = hw->clk; 155 + struct mmc_phase *phase = to_mmc_phase(hw); 156 + unsigned int mmc_rate, mmc_parent_rate; 157 + unsigned long flags; 158 + u32 value; 159 + u8 delay; 160 + 161 + /* Get the main MMC clock */ 162 + mmc = clk_get_parent(clk); 163 + if (!mmc) 164 + return -EINVAL; 165 + 166 + /* And its rate */ 167 + mmc_rate = clk_get_rate(mmc); 168 + if (!mmc_rate) 169 + return -EINVAL; 170 + 171 + /* Now, get the MMC parent (most likely some PLL) */ 172 + mmc_parent = clk_get_parent(mmc); 173 + if (!mmc_parent) 174 + return -EINVAL; 175 + 176 + /* And its rate */ 177 + mmc_parent_rate = clk_get_rate(mmc_parent); 178 + if (!mmc_parent_rate) 179 + return -EINVAL; 180 + 181 + if (degrees != 180) { 182 + u16 step, mmc_div; 183 + 184 + /* Get MMC clock divider */ 185 + mmc_div = mmc_parent_rate / mmc_rate; 186 + 187 + /* 188 + * We can only outphase the clocks by multiple of the 189 + * PLL's period. 190 + * 191 + * Since the MMC clock in only a divider, and the 192 + * formula to get the outphasing in degrees is deg = 193 + * 360 * delta / period 194 + * 195 + * If we simplify this formula, we can see that the 196 + * only thing that we're concerned about is the number 197 + * of period we want to outphase our clock from, and 198 + * the divider set by the MMC clock. 199 + */ 200 + step = DIV_ROUND_CLOSEST(360, mmc_div); 201 + delay = DIV_ROUND_CLOSEST(degrees, step); 202 + } else { 203 + delay = 0; 204 + } 205 + 206 + spin_lock_irqsave(phase->lock, flags); 207 + value = readl(phase->reg); 208 + value &= ~GENMASK(phase->data->offset + 3, phase->data->offset); 209 + value |= delay << phase->data->offset; 210 + writel(value, phase->reg); 211 + spin_unlock_irqrestore(phase->lock, flags); 212 + 213 + return 0; 214 + } 215 + 216 + static const struct clk_ops mmc_clk_ops = { 217 + .get_phase = mmc_get_phase, 218 + .set_phase = mmc_set_phase, 219 + }; 220 + 221 + static void __init sun4i_a10_mmc_phase_setup(struct device_node *node, 222 + struct mmc_phase_data *data) 223 + { 224 + const char *parent_names[1] = { of_clk_get_parent_name(node, 0) }; 225 + struct clk_init_data init = { 226 + .num_parents = 1, 227 + .parent_names = parent_names, 228 + .ops = &mmc_clk_ops, 229 + }; 230 + 231 + struct mmc_phase *phase; 232 + struct clk *clk; 233 + 234 + phase = kmalloc(sizeof(*phase), GFP_KERNEL); 235 + if (!phase) 236 + return; 237 + 238 + phase->hw.init = &init; 239 + 240 + phase->reg = of_iomap(node, 0); 241 + if (!phase->reg) 242 + goto err_free; 243 + 244 + phase->data = data; 245 + phase->lock = &sun4i_a10_mod0_lock; 246 + 247 + if (of_property_read_string(node, "clock-output-names", &init.name)) 248 + init.name = node->name; 249 + 250 + clk = clk_register(NULL, &phase->hw); 251 + if (IS_ERR(clk)) 252 + goto err_unmap; 253 + 254 + of_clk_add_provider(node, of_clk_src_simple_get, clk); 255 + 256 + return; 257 + 258 + err_unmap: 259 + iounmap(phase->reg); 260 + err_free: 261 + kfree(phase); 262 + } 263 + 264 + 265 + static struct mmc_phase_data mmc_output_clk = { 266 + .offset = 8, 267 + }; 268 + 269 + static struct mmc_phase_data mmc_sample_clk = { 270 + .offset = 20, 271 + }; 272 + 273 + static void __init sun4i_a10_mmc_output_setup(struct device_node *node) 274 + { 275 + sun4i_a10_mmc_phase_setup(node, &mmc_output_clk); 276 + } 277 + CLK_OF_DECLARE(sun4i_a10_mmc_output, "allwinner,sun4i-a10-mmc-output-clk", sun4i_a10_mmc_output_setup); 278 + 279 + static void __init sun4i_a10_mmc_sample_setup(struct device_node *node) 280 + { 281 + sun4i_a10_mmc_phase_setup(node, &mmc_sample_clk); 282 + } 283 + CLK_OF_DECLARE(sun4i_a10_mmc_sample, "allwinner,sun4i-a10-mmc-sample-clk", sun4i_a10_mmc_sample_setup);
-1
drivers/clk/sunxi/clk-sun6i-apb0-gates.c
··· 99 99 static struct platform_driver sun6i_a31_apb0_gates_clk_driver = { 100 100 .driver = { 101 101 .name = "sun6i-a31-apb0-gates-clk", 102 - .owner = THIS_MODULE, 103 102 .of_match_table = sun6i_a31_apb0_gates_clk_dt_ids, 104 103 }, 105 104 .probe = sun6i_a31_apb0_gates_clk_probe,
-1
drivers/clk/sunxi/clk-sun6i-apb0.c
··· 65 65 static struct platform_driver sun6i_a31_apb0_clk_driver = { 66 66 .driver = { 67 67 .name = "sun6i-a31-apb0-clk", 68 - .owner = THIS_MODULE, 69 68 .of_match_table = sun6i_a31_apb0_clk_dt_ids, 70 69 }, 71 70 .probe = sun6i_a31_apb0_clk_probe,
-1
drivers/clk/sunxi/clk-sun6i-ar100.c
··· 221 221 static struct platform_driver sun6i_a31_ar100_clk_driver = { 222 222 .driver = { 223 223 .name = "sun6i-a31-ar100-clk", 224 - .owner = THIS_MODULE, 225 224 .of_match_table = sun6i_a31_ar100_clk_dt_ids, 226 225 }, 227 226 .probe = sun6i_a31_ar100_clk_probe,
-1
drivers/clk/sunxi/clk-sun8i-apb0.c
··· 56 56 static struct platform_driver sun8i_a23_apb0_clk_driver = { 57 57 .driver = { 58 58 .name = "sun8i-a23-apb0-clk", 59 - .owner = THIS_MODULE, 60 59 .of_match_table = sun8i_a23_apb0_clk_dt_ids, 61 60 }, 62 61 .probe = sun8i_a23_apb0_clk_probe,
+78
drivers/clk/sunxi/clk-sun8i-mbus.c
··· 1 + /* 2 + * Copyright 2014 Chen-Yu Tsai 3 + * 4 + * Chen-Yu Tsai <wens@csie.org> 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 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + */ 16 + 17 + #include <linux/clk-provider.h> 18 + #include <linux/clkdev.h> 19 + #include <linux/of_address.h> 20 + 21 + #include "clk-factors.h" 22 + 23 + /** 24 + * sun8i_a23_get_mbus_factors() - calculates m factor for MBUS clocks 25 + * MBUS rate is calculated as follows 26 + * rate = parent_rate / (m + 1); 27 + */ 28 + 29 + static void sun8i_a23_get_mbus_factors(u32 *freq, u32 parent_rate, 30 + u8 *n, u8 *k, u8 *m, u8 *p) 31 + { 32 + u8 div; 33 + 34 + /* 35 + * These clocks can only divide, so we will never be able to 36 + * achieve frequencies higher than the parent frequency 37 + */ 38 + if (*freq > parent_rate) 39 + *freq = parent_rate; 40 + 41 + div = DIV_ROUND_UP(parent_rate, *freq); 42 + 43 + if (div > 8) 44 + div = 8; 45 + 46 + *freq = parent_rate / div; 47 + 48 + /* we were called to round the frequency, we can now return */ 49 + if (m == NULL) 50 + return; 51 + 52 + *m = div - 1; 53 + } 54 + 55 + static struct clk_factors_config sun8i_a23_mbus_config = { 56 + .mshift = 0, 57 + .mwidth = 3, 58 + }; 59 + 60 + static const struct factors_data sun8i_a23_mbus_data __initconst = { 61 + .enable = 31, 62 + .mux = 24, 63 + .table = &sun8i_a23_mbus_config, 64 + .getter = sun8i_a23_get_mbus_factors, 65 + }; 66 + 67 + static DEFINE_SPINLOCK(sun8i_a23_mbus_lock); 68 + 69 + static void __init sun8i_a23_mbus_setup(struct device_node *node) 70 + { 71 + struct clk *mbus = sunxi_factors_register(node, &sun8i_a23_mbus_data, 72 + &sun8i_a23_mbus_lock); 73 + 74 + /* The MBUS clocks needs to be always enabled */ 75 + __clk_get(mbus); 76 + clk_prepare_enable(mbus); 77 + } 78 + CLK_OF_DECLARE(sun8i_a23_mbus, "allwinner,sun8i-a23-mbus-clk", sun8i_a23_mbus_setup);
+12 -149
drivers/clk/sunxi/clk-sunxi.c
··· 19 19 #include <linux/of.h> 20 20 #include <linux/of_address.h> 21 21 #include <linux/reset-controller.h> 22 + #include <linux/spinlock.h> 22 23 23 24 #include "clk-factors.h" 24 25 ··· 320 319 321 320 322 321 323 - /** 324 - * sun4i_get_mod0_factors() - calculates m, n factors for MOD0-style clocks 325 - * MOD0 rate is calculated as follows 326 - * rate = (parent_rate >> p) / (m + 1); 327 - */ 328 - 329 - static void sun4i_get_mod0_factors(u32 *freq, u32 parent_rate, 330 - u8 *n, u8 *k, u8 *m, u8 *p) 331 - { 332 - u8 div, calcm, calcp; 333 - 334 - /* These clocks can only divide, so we will never be able to achieve 335 - * frequencies higher than the parent frequency */ 336 - if (*freq > parent_rate) 337 - *freq = parent_rate; 338 - 339 - div = DIV_ROUND_UP(parent_rate, *freq); 340 - 341 - if (div < 16) 342 - calcp = 0; 343 - else if (div / 2 < 16) 344 - calcp = 1; 345 - else if (div / 4 < 16) 346 - calcp = 2; 347 - else 348 - calcp = 3; 349 - 350 - calcm = DIV_ROUND_UP(div, 1 << calcp); 351 - 352 - *freq = (parent_rate >> calcp) / calcm; 353 - 354 - /* we were called to round the frequency, we can now return */ 355 - if (n == NULL) 356 - return; 357 - 358 - *m = calcm - 1; 359 - *p = calcp; 360 - } 361 - 362 - 363 322 364 323 /** 365 324 * sun7i_a20_get_out_factors() - calculates m, p factors for CLK_OUT_A/B ··· 401 440 * sunxi_factors_clk_setup() - Setup function for factor clocks 402 441 */ 403 442 404 - #define SUNXI_FACTORS_MUX_MASK 0x3 405 - 406 - struct factors_data { 407 - int enable; 408 - int mux; 409 - struct clk_factors_config *table; 410 - void (*getter) (u32 *rate, u32 parent_rate, u8 *n, u8 *k, u8 *m, u8 *p); 411 - const char *name; 412 - }; 413 - 414 443 static struct clk_factors_config sun4i_pll1_config = { 415 444 .nshift = 8, 416 445 .nwidth = 5, ··· 450 499 static struct clk_factors_config sun4i_apb1_config = { 451 500 .mshift = 0, 452 501 .mwidth = 5, 453 - .pshift = 16, 454 - .pwidth = 2, 455 - }; 456 - 457 - /* user manual says "n" but it's really "p" */ 458 - static struct clk_factors_config sun4i_mod0_config = { 459 - .mshift = 0, 460 - .mwidth = 4, 461 502 .pshift = 16, 462 503 .pwidth = 2, 463 504 }; ··· 511 568 .getter = sun4i_get_apb1_factors, 512 569 }; 513 570 514 - static const struct factors_data sun4i_mod0_data __initconst = { 515 - .enable = 31, 516 - .mux = 24, 517 - .table = &sun4i_mod0_config, 518 - .getter = sun4i_get_mod0_factors, 519 - }; 520 - 521 571 static const struct factors_data sun7i_a20_out_data __initconst = { 522 572 .enable = 31, 523 573 .mux = 24, ··· 519 583 }; 520 584 521 585 static struct clk * __init sunxi_factors_clk_setup(struct device_node *node, 522 - const struct factors_data *data) 586 + const struct factors_data *data) 523 587 { 524 - struct clk *clk; 525 - struct clk_factors *factors; 526 - struct clk_gate *gate = NULL; 527 - struct clk_mux *mux = NULL; 528 - struct clk_hw *gate_hw = NULL; 529 - struct clk_hw *mux_hw = NULL; 530 - const char *clk_name = node->name; 531 - const char *parents[SUNXI_MAX_PARENTS]; 532 - void __iomem *reg; 533 - int i = 0; 534 - 535 - reg = of_iomap(node, 0); 536 - 537 - /* if we have a mux, we will have >1 parents */ 538 - while (i < SUNXI_MAX_PARENTS && 539 - (parents[i] = of_clk_get_parent_name(node, i)) != NULL) 540 - i++; 541 - 542 - /* 543 - * some factor clocks, such as pll5 and pll6, may have multiple 544 - * outputs, and have their name designated in factors_data 545 - */ 546 - if (data->name) 547 - clk_name = data->name; 548 - else 549 - of_property_read_string(node, "clock-output-names", &clk_name); 550 - 551 - factors = kzalloc(sizeof(struct clk_factors), GFP_KERNEL); 552 - if (!factors) 553 - return NULL; 554 - 555 - /* Add a gate if this factor clock can be gated */ 556 - if (data->enable) { 557 - gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL); 558 - if (!gate) { 559 - kfree(factors); 560 - return NULL; 561 - } 562 - 563 - /* set up gate properties */ 564 - gate->reg = reg; 565 - gate->bit_idx = data->enable; 566 - gate->lock = &clk_lock; 567 - gate_hw = &gate->hw; 568 - } 569 - 570 - /* Add a mux if this factor clock can be muxed */ 571 - if (data->mux) { 572 - mux = kzalloc(sizeof(struct clk_mux), GFP_KERNEL); 573 - if (!mux) { 574 - kfree(factors); 575 - kfree(gate); 576 - return NULL; 577 - } 578 - 579 - /* set up gate properties */ 580 - mux->reg = reg; 581 - mux->shift = data->mux; 582 - mux->mask = SUNXI_FACTORS_MUX_MASK; 583 - mux->lock = &clk_lock; 584 - mux_hw = &mux->hw; 585 - } 586 - 587 - /* set up factors properties */ 588 - factors->reg = reg; 589 - factors->config = data->table; 590 - factors->get_factors = data->getter; 591 - factors->lock = &clk_lock; 592 - 593 - clk = clk_register_composite(NULL, clk_name, 594 - parents, i, 595 - mux_hw, &clk_mux_ops, 596 - &factors->hw, &clk_factors_ops, 597 - gate_hw, &clk_gate_ops, 0); 598 - 599 - if (!IS_ERR(clk)) { 600 - of_clk_add_provider(node, of_clk_src_simple_get, clk); 601 - clk_register_clkdev(clk, clk_name, NULL); 602 - } 603 - 604 - return clk; 588 + return sunxi_factors_register(node, data, &clk_lock); 605 589 } 606 590 607 591 ··· 618 762 .width = 2, 619 763 }; 620 764 765 + static const struct clk_div_table sun4i_apb0_table[] __initconst = { 766 + { .val = 0, .div = 2 }, 767 + { .val = 1, .div = 2 }, 768 + { .val = 2, .div = 4 }, 769 + { .val = 3, .div = 8 }, 770 + { } /* sentinel */ 771 + }; 772 + 621 773 static const struct div_data sun4i_apb0_data __initconst = { 622 774 .shift = 8, 623 775 .pow = 1, 624 776 .width = 2, 777 + .table = sun4i_apb0_table, 625 778 }; 626 779 627 780 static const struct div_data sun6i_a31_apb2_div_data __initconst = { ··· 1064 1199 {.compatible = "allwinner,sun7i-a20-pll4-clk", .data = &sun7i_a20_pll4_data,}, 1065 1200 {.compatible = "allwinner,sun6i-a31-pll6-clk", .data = &sun6i_a31_pll6_data,}, 1066 1201 {.compatible = "allwinner,sun4i-a10-apb1-clk", .data = &sun4i_apb1_data,}, 1067 - {.compatible = "allwinner,sun4i-a10-mod0-clk", .data = &sun4i_mod0_data,}, 1068 1202 {.compatible = "allwinner,sun7i-a20-out-clk", .data = &sun7i_a20_out_data,}, 1069 1203 {} 1070 1204 }; ··· 1175 1311 CLK_OF_DECLARE(sun4i_a10_clk_init, "allwinner,sun4i-a10", sun4i_a10_init_clocks); 1176 1312 1177 1313 static const char *sun5i_critical_clocks[] __initdata = { 1178 - "mbus", 1179 1314 "pll5_ddr", 1180 1315 "ahb_sdram", 1181 1316 };
+8
drivers/clk/tegra/clk-tegra124.c
··· 1166 1166 clk_register_clkdev(clk, "pll_c_out1", NULL); 1167 1167 clks[TEGRA124_CLK_PLL_C_OUT1] = clk; 1168 1168 1169 + /* PLLC_UD */ 1170 + clk = clk_register_fixed_factor(NULL, "pll_c_ud", "pll_c", 1171 + CLK_SET_RATE_PARENT, 1, 1); 1172 + clk_register_clkdev(clk, "pll_c_ud", NULL); 1173 + clks[TEGRA124_CLK_PLL_C_UD] = clk; 1174 + 1169 1175 /* PLLC2 */ 1170 1176 clk = tegra_clk_register_pllc("pll_c2", "pll_ref", clk_base, pmc, 0, 1171 1177 &pll_c2_params, NULL); ··· 1204 1198 /* PLLM_UD */ 1205 1199 clk = clk_register_fixed_factor(NULL, "pll_m_ud", "pll_m", 1206 1200 CLK_SET_RATE_PARENT, 1, 1); 1201 + clk_register_clkdev(clk, "pll_m_ud", NULL); 1202 + clks[TEGRA124_CLK_PLL_M_UD] = clk; 1207 1203 1208 1204 /* PLLU */ 1209 1205 val = readl(clk_base + pll_u_params.base_reg);
+7 -2
drivers/clk/tegra/clk.c
··· 207 207 208 208 for (; tbl->clk_id < clk_max; tbl++) { 209 209 clk = clks[tbl->clk_id]; 210 - if (IS_ERR_OR_NULL(clk)) 211 - return; 210 + if (IS_ERR_OR_NULL(clk)) { 211 + pr_err("%s: invalid entry %ld in clks array for id %d\n", 212 + __func__, PTR_ERR(clk), tbl->clk_id); 213 + WARN_ON(1); 214 + 215 + continue; 216 + } 212 217 213 218 if (tbl->parent_id < clk_max) { 214 219 struct clk *parent = clks[tbl->parent_id];
+2 -1
drivers/clk/ti/clk-dra7-atl.c
··· 203 203 204 204 if (!IS_ERR(clk)) { 205 205 of_clk_add_provider(node, of_clk_src_simple_get, clk); 206 + kfree(parent_names); 206 207 return; 207 208 } 208 209 cleanup: ··· 229 228 cinfo->iobase = of_iomap(node, 0); 230 229 cinfo->dev = &pdev->dev; 231 230 pm_runtime_enable(cinfo->dev); 231 + pm_runtime_irq_safe(cinfo->dev); 232 232 233 233 pm_runtime_get_sync(cinfo->dev); 234 234 atl_write(cinfo, DRA7_ATL_PCLKMUX_REG(0), DRA7_ATL_PCLKMUX); ··· 303 301 static struct platform_driver dra7_atl_clk_driver = { 304 302 .driver = { 305 303 .name = "dra7-atl", 306 - .owner = THIS_MODULE, 307 304 .of_match_table = of_dra7_atl_clk_match_tbl, 308 305 }, 309 306 .probe = of_dra7_atl_clk_probe,
+43 -25
drivers/clk/ti/clk.c
··· 25 25 #undef pr_fmt 26 26 #define pr_fmt(fmt) "%s: " fmt, __func__ 27 27 28 - static int ti_dt_clk_memmap_index; 29 28 struct ti_clk_ll_ops *ti_clk_ll_ops; 29 + static struct device_node *clocks_node_ptr[CLK_MAX_MEMMAPS]; 30 30 31 31 /** 32 32 * ti_dt_clocks_register - register DT alias clocks during boot ··· 108 108 struct clk_omap_reg *reg; 109 109 u32 val; 110 110 u32 tmp; 111 + int i; 111 112 112 113 reg = (struct clk_omap_reg *)&tmp; 113 - reg->index = ti_dt_clk_memmap_index; 114 + 115 + for (i = 0; i < CLK_MAX_MEMMAPS; i++) { 116 + if (clocks_node_ptr[i] == node->parent) 117 + break; 118 + } 119 + 120 + if (i == CLK_MAX_MEMMAPS) { 121 + pr_err("clk-provider not found for %s!\n", node->name); 122 + return NULL; 123 + } 124 + 125 + reg->index = i; 114 126 115 127 if (of_property_read_u32_index(node, "reg", index, &val)) { 116 128 pr_err("%s must have reg[%d]!\n", node->name, index); ··· 139 127 * @parent: master node 140 128 * @index: internal index for clk_reg_ops 141 129 * 142 - * Initializes a master clock IP block and its child clock nodes. 143 - * Regmap is provided for accessing the register space for the 144 - * IP block and all the clocks under it. 130 + * Initializes a master clock IP block. This basically sets up the 131 + * mapping from clocks node to the memory map index. All the clocks 132 + * are then initialized through the common of_clk_init call, and the 133 + * clocks will access their memory maps based on the node layout. 145 134 */ 146 135 void ti_dt_clk_init_provider(struct device_node *parent, int index) 147 136 { 148 - const struct of_device_id *match; 149 - struct device_node *np; 150 137 struct device_node *clocks; 151 - of_clk_init_cb_t clk_init_cb; 152 - struct clk_init_item *retry; 153 - struct clk_init_item *tmp; 154 - 155 - ti_dt_clk_memmap_index = index; 156 138 157 139 /* get clocks for this parent */ 158 140 clocks = of_get_child_by_name(parent, "clocks"); ··· 155 149 return; 156 150 } 157 151 158 - for_each_child_of_node(clocks, np) { 159 - match = of_match_node(&__clk_of_table, np); 160 - if (!match) 161 - continue; 162 - clk_init_cb = (of_clk_init_cb_t)match->data; 163 - pr_debug("%s: initializing: %s\n", __func__, np->name); 164 - clk_init_cb(np); 165 - } 152 + /* add clocks node info */ 153 + clocks_node_ptr[index] = clocks; 154 + } 166 155 167 - list_for_each_entry_safe(retry, tmp, &retry_list, link) { 168 - pr_debug("retry-init: %s\n", retry->node->name); 169 - retry->func(retry->hw, retry->node); 170 - list_del(&retry->link); 171 - kfree(retry); 156 + /** 157 + * ti_dt_clk_init_retry_clks - init clocks from the retry list 158 + * 159 + * Initializes any clocks that have failed to initialize before, 160 + * reasons being missing parent node(s) during earlier init. This 161 + * typically happens only for DPLLs which need to have both of their 162 + * parent clocks ready during init. 163 + */ 164 + void ti_dt_clk_init_retry_clks(void) 165 + { 166 + struct clk_init_item *retry; 167 + struct clk_init_item *tmp; 168 + int retries = 5; 169 + 170 + while (!list_empty(&retry_list) && retries) { 171 + list_for_each_entry_safe(retry, tmp, &retry_list, link) { 172 + pr_debug("retry-init: %s\n", retry->node->name); 173 + retry->func(retry->hw, retry->node); 174 + list_del(&retry->link); 175 + kfree(retry); 176 + } 177 + retries--; 172 178 } 173 179 }
+5
drivers/clk/ti/clockdomain.c
··· 36 36 37 37 for (i = 0; i < num_clks; i++) { 38 38 clk = of_clk_get(node, i); 39 + if (IS_ERR(clk)) { 40 + pr_err("%s: Failed get %s' clock nr %d (%ld)\n", 41 + __func__, node->full_name, i, PTR_ERR(clk)); 42 + continue; 43 + } 39 44 if (__clk_get_flags(clk) & CLK_IS_BASIC) { 40 45 pr_warn("can't setup clkdm for basic clk %s\n", 41 46 __clk_get_name(clk));
+2 -2
drivers/clk/ti/divider.c
··· 300 300 return clk; 301 301 } 302 302 303 - static struct clk_div_table 304 - __init *ti_clk_get_div_table(struct device_node *node) 303 + static struct clk_div_table * 304 + __init ti_clk_get_div_table(struct device_node *node) 305 305 { 306 306 struct clk_div_table *table; 307 307 const __be32 *divspec;
+14 -16
drivers/clk/zynq/clkc.c
··· 85 85 static DEFINE_SPINLOCK(dbgclk_lock); 86 86 static DEFINE_SPINLOCK(aperclk_lock); 87 87 88 - static const char dummy_nm[] __initconst = "dummy_name"; 89 - 90 - static const char *armpll_parents[] __initdata = {"armpll_int", "ps_clk"}; 91 - static const char *ddrpll_parents[] __initdata = {"ddrpll_int", "ps_clk"}; 92 - static const char *iopll_parents[] __initdata = {"iopll_int", "ps_clk"}; 93 - static const char *gem0_mux_parents[] __initdata = {"gem0_div1", dummy_nm}; 94 - static const char *gem1_mux_parents[] __initdata = {"gem1_div1", dummy_nm}; 95 - static const char *can0_mio_mux2_parents[] __initdata = {"can0_gate", 88 + static const char *armpll_parents[] __initconst = {"armpll_int", "ps_clk"}; 89 + static const char *ddrpll_parents[] __initconst = {"ddrpll_int", "ps_clk"}; 90 + static const char *iopll_parents[] __initconst = {"iopll_int", "ps_clk"}; 91 + static const char *gem0_mux_parents[] __initconst = {"gem0_div1", "dummy_name"}; 92 + static const char *gem1_mux_parents[] __initconst = {"gem1_div1", "dummy_name"}; 93 + static const char *can0_mio_mux2_parents[] __initconst = {"can0_gate", 96 94 "can0_mio_mux"}; 97 - static const char *can1_mio_mux2_parents[] __initdata = {"can1_gate", 95 + static const char *can1_mio_mux2_parents[] __initconst = {"can1_gate", 98 96 "can1_mio_mux"}; 99 - static const char *dbg_emio_mux_parents[] __initdata = {"dbg_div", 100 - dummy_nm}; 97 + static const char *dbg_emio_mux_parents[] __initconst = {"dbg_div", 98 + "dummy_name"}; 101 99 102 - static const char *dbgtrc_emio_input_names[] __initdata = {"trace_emio_clk"}; 103 - static const char *gem0_emio_input_names[] __initdata = {"gem0_emio_clk"}; 104 - static const char *gem1_emio_input_names[] __initdata = {"gem1_emio_clk"}; 105 - static const char *swdt_ext_clk_input_names[] __initdata = {"swdt_ext_clk"}; 100 + static const char *dbgtrc_emio_input_names[] __initconst = {"trace_emio_clk"}; 101 + static const char *gem0_emio_input_names[] __initconst = {"gem0_emio_clk"}; 102 + static const char *gem1_emio_input_names[] __initconst = {"gem1_emio_clk"}; 103 + static const char *swdt_ext_clk_input_names[] __initconst = {"swdt_ext_clk"}; 106 104 107 105 static void __init zynq_clk_register_fclk(enum zynq_clk fclk, 108 106 const char *clk_name, void __iomem *fclk_ctrl_reg, ··· 228 230 const char *periph_parents[4]; 229 231 const char *swdt_ext_clk_mux_parents[2]; 230 232 const char *can_mio_mux_parents[NUM_MIO_PINS]; 233 + const char *dummy_nm = "dummy_name"; 231 234 232 235 pr_info("Zynq clock init\n"); 233 236 ··· 618 619 np_err: 619 620 of_node_put(np); 620 621 BUG(); 621 - return; 622 622 }
+1 -3
drivers/clk/zynq/pll.c
··· 211 211 }; 212 212 213 213 pll = kmalloc(sizeof(*pll), GFP_KERNEL); 214 - if (!pll) { 215 - pr_err("%s: Could not allocate Zynq PLL clk.\n", __func__); 214 + if (!pll) 216 215 return ERR_PTR(-ENOMEM); 217 - } 218 216 219 217 /* Populate the struct */ 220 218 pll->hw.init = &initd;
+5 -9
drivers/cpufreq/kirkwood-cpufreq.c
··· 12 12 #include <linux/kernel.h> 13 13 #include <linux/module.h> 14 14 #include <linux/clk.h> 15 - #include <linux/clk-provider.h> 16 15 #include <linux/cpufreq.h> 17 16 #include <linux/of_device.h> 18 17 #include <linux/platform_device.h> ··· 38 39 * - cpu clk 39 40 * - ddr clk 40 41 * 41 - * The frequencies are set at runtime before registering this * 42 - * table. 42 + * The frequencies are set at runtime before registering this table. 43 43 */ 44 44 static struct cpufreq_frequency_table kirkwood_freq_table[] = { 45 45 {0, STATE_CPU_FREQ, 0}, /* CPU uses cpuclk */ ··· 48 50 49 51 static unsigned int kirkwood_cpufreq_get_cpu_frequency(unsigned int cpu) 50 52 { 51 - if (__clk_is_enabled(priv.powersave_clk)) 52 - return kirkwood_freq_table[1].frequency; 53 - return kirkwood_freq_table[0].frequency; 53 + return clk_get_rate(priv.powersave_clk) / 1000; 54 54 } 55 55 56 56 static int kirkwood_cpufreq_target(struct cpufreq_policy *policy, ··· 66 70 67 71 switch (state) { 68 72 case STATE_CPU_FREQ: 69 - clk_disable(priv.powersave_clk); 73 + clk_set_parent(priv.powersave_clk, priv.cpu_clk); 70 74 break; 71 75 case STATE_DDR_FREQ: 72 - clk_enable(priv.powersave_clk); 76 + clk_set_parent(priv.powersave_clk, priv.ddr_clk); 73 77 break; 74 78 } 75 79 ··· 146 150 err = PTR_ERR(priv.powersave_clk); 147 151 goto out_ddr; 148 152 } 149 - clk_prepare(priv.powersave_clk); 153 + clk_prepare_enable(priv.powersave_clk); 150 154 151 155 of_node_put(np); 152 156 np = NULL;
+2
include/asm-generic/clkdev.h
··· 15 15 16 16 #include <linux/slab.h> 17 17 18 + #ifndef CONFIG_COMMON_CLK 18 19 struct clk; 19 20 20 21 static inline int __clk_get(struct clk *clk) { return 1; } 21 22 static inline void __clk_put(struct clk *clk) { } 23 + #endif 22 24 23 25 static inline struct clk_lookup_alloc *__clkdev_alloc(size_t size) 24 26 {
+27
include/dt-bindings/clock/exynos3250.h
··· 255 255 */ 256 256 #define CLK_NR_CLKS 248 257 257 258 + /* 259 + * CMU DMC 260 + */ 261 + 262 + #define CLK_FOUT_BPLL 1 263 + #define CLK_FOUT_EPLL 2 264 + 265 + /* Muxes */ 266 + #define CLK_MOUT_MPLL_MIF 8 267 + #define CLK_MOUT_BPLL 9 268 + #define CLK_MOUT_DPHY 10 269 + #define CLK_MOUT_DMC_BUS 11 270 + #define CLK_MOUT_EPLL 12 271 + 272 + /* Dividers */ 273 + #define CLK_DIV_DMC 16 274 + #define CLK_DIV_DPHY 17 275 + #define CLK_DIV_DMC_PRE 18 276 + #define CLK_DIV_DMCP 19 277 + #define CLK_DIV_DMCD 20 278 + 279 + /* 280 + * Total number of clocks of main CMU. 281 + * NOTE: Must be equal to last clock ID increased by one. 282 + */ 283 + #define NR_CLKS_DMC 21 284 + 258 285 #endif /* _DT_BINDINGS_CLOCK_SAMSUNG_EXYNOS3250_CLOCK_H */
+7 -5
include/dt-bindings/clock/exynos4.h
··· 115 115 #define CLK_SMMU_MFCR 275 116 116 #define CLK_G3D 276 117 117 #define CLK_G2D 277 118 - #define CLK_ROTATOR 278 /* Exynos4210 only */ 119 - #define CLK_MDMA 279 /* Exynos4210 only */ 120 - #define CLK_SMMU_G2D 280 /* Exynos4210 only */ 121 - #define CLK_SMMU_ROTATOR 281 /* Exynos4210 only */ 122 - #define CLK_SMMU_MDMA 282 /* Exynos4210 only */ 118 + #define CLK_ROTATOR 278 119 + #define CLK_MDMA 279 120 + #define CLK_SMMU_G2D 280 121 + #define CLK_SMMU_ROTATOR 281 122 + #define CLK_SMMU_MDMA 282 123 123 #define CLK_FIMD0 283 124 124 #define CLK_MIE0 284 125 125 #define CLK_MDNIE0 285 /* Exynos4412 only */ ··· 234 234 #define CLK_MOUT_G3D1 393 235 235 #define CLK_MOUT_G3D 394 236 236 #define CLK_ACLK400_MCUISP 395 /* Exynos4x12 only */ 237 + #define CLK_MOUT_HDMI 396 238 + #define CLK_MOUT_MIXER 397 237 239 238 240 /* gate clocks - ppmu */ 239 241 #define CLK_PPMULEFT 400
+27
include/dt-bindings/clock/hix5hd2-clock.h
··· 46 46 #define HIX5HD2_SFC_MUX 64 47 47 #define HIX5HD2_MMC_MUX 65 48 48 #define HIX5HD2_FEPHY_MUX 66 49 + #define HIX5HD2_SD_MUX 67 49 50 50 51 /* gate clocks */ 51 52 #define HIX5HD2_SFC_RST 128 ··· 54 53 #define HIX5HD2_MMC_CIU_CLK 130 55 54 #define HIX5HD2_MMC_BIU_CLK 131 56 55 #define HIX5HD2_MMC_CIU_RST 132 56 + #define HIX5HD2_FWD_BUS_CLK 133 57 + #define HIX5HD2_FWD_SYS_CLK 134 58 + #define HIX5HD2_MAC0_PHY_CLK 135 59 + #define HIX5HD2_SD_CIU_CLK 136 60 + #define HIX5HD2_SD_BIU_CLK 137 61 + #define HIX5HD2_SD_CIU_RST 138 62 + #define HIX5HD2_WDG0_CLK 139 63 + #define HIX5HD2_WDG0_RST 140 64 + #define HIX5HD2_I2C0_CLK 141 65 + #define HIX5HD2_I2C0_RST 142 66 + #define HIX5HD2_I2C1_CLK 143 67 + #define HIX5HD2_I2C1_RST 144 68 + #define HIX5HD2_I2C2_CLK 145 69 + #define HIX5HD2_I2C2_RST 146 70 + #define HIX5HD2_I2C3_CLK 147 71 + #define HIX5HD2_I2C3_RST 148 72 + #define HIX5HD2_I2C4_CLK 149 73 + #define HIX5HD2_I2C4_RST 150 74 + #define HIX5HD2_I2C5_CLK 151 75 + #define HIX5HD2_I2C5_RST 152 76 + 77 + /* complex */ 78 + #define HIX5HD2_MAC0_CLK 192 79 + #define HIX5HD2_MAC1_CLK 193 80 + #define HIX5HD2_SATA_CLK 194 81 + #define HIX5HD2_USB_CLK 195 57 82 58 83 #define HIX5HD2_NR_CLKS 256 59 84 #endif /* __DTS_HIX5HD2_CLOCK_H */
+23
include/dt-bindings/clock/maxim,max77686.h
··· 1 + /* 2 + * Copyright (C) 2014 Google, Inc 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 version 2 as 6 + * published by the Free Software Foundation. 7 + * 8 + * Device Tree binding constants clocks for the Maxim 77686 PMIC. 9 + */ 10 + 11 + #ifndef _DT_BINDINGS_CLOCK_MAXIM_MAX77686_CLOCK_H 12 + #define _DT_BINDINGS_CLOCK_MAXIM_MAX77686_CLOCK_H 13 + 14 + /* Fixed rate clocks. */ 15 + 16 + #define MAX77686_CLK_AP 0 17 + #define MAX77686_CLK_CP 1 18 + #define MAX77686_CLK_PMIC 2 19 + 20 + /* Total number of clocks. */ 21 + #define MAX77686_CLKS_NUM (MAX77686_CLK_PMIC + 1) 22 + 23 + #endif /* _DT_BINDINGS_CLOCK_MAXIM_MAX77686_CLOCK_H */
+22
include/dt-bindings/clock/maxim,max77802.h
··· 1 + /* 2 + * Copyright (C) 2014 Google, Inc 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 version 2 as 6 + * published by the Free Software Foundation. 7 + * 8 + * Device Tree binding constants clocks for the Maxim 77802 PMIC. 9 + */ 10 + 11 + #ifndef _DT_BINDINGS_CLOCK_MAXIM_MAX77802_CLOCK_H 12 + #define _DT_BINDINGS_CLOCK_MAXIM_MAX77802_CLOCK_H 13 + 14 + /* Fixed rate clocks. */ 15 + 16 + #define MAX77802_CLK_32K_AP 0 17 + #define MAX77802_CLK_32K_CP 1 18 + 19 + /* Total number of clocks. */ 20 + #define MAX77802_CLKS_NUM (MAX77802_CLK_32K_CP + 1) 21 + 22 + #endif /* _DT_BINDINGS_CLOCK_MAXIM_MAX77802_CLOCK_H */
+77
include/dt-bindings/clock/pxa-clock.h
··· 1 + /* 2 + * Inspired by original work from pxa2xx-regs.h by Nicolas Pitre 3 + * Copyright (C) 2014 Robert Jarzmik 4 + * 5 + * This program is free software; you can redistribute it and/or modify 6 + * it under the terms of the GNU General Public License as published by 7 + * the Free Software Foundation; either version 2 of the License, or 8 + * (at your option) any later version. 9 + */ 10 + 11 + #ifndef __DT_BINDINGS_CLOCK_PXA2XX_H__ 12 + #define __DT_BINDINGS_CLOCK_PXA2XX_H__ 13 + 14 + #define CLK_NONE 0 15 + #define CLK_1WIRE 1 16 + #define CLK_AC97 2 17 + #define CLK_AC97CONF 3 18 + #define CLK_ASSP 4 19 + #define CLK_BOOT 5 20 + #define CLK_BTUART 6 21 + #define CLK_CAMERA 7 22 + #define CLK_CIR 8 23 + #define CLK_CORE 9 24 + #define CLK_DMC 10 25 + #define CLK_FFUART 11 26 + #define CLK_FICP 12 27 + #define CLK_GPIO 13 28 + #define CLK_HSIO2 14 29 + #define CLK_HWUART 15 30 + #define CLK_I2C 16 31 + #define CLK_I2S 17 32 + #define CLK_IM 18 33 + #define CLK_INC 19 34 + #define CLK_ISC 20 35 + #define CLK_KEYPAD 21 36 + #define CLK_LCD 22 37 + #define CLK_MEMC 23 38 + #define CLK_MEMSTK 24 39 + #define CLK_MINI_IM 25 40 + #define CLK_MINI_LCD 26 41 + #define CLK_MMC 27 42 + #define CLK_MMC1 28 43 + #define CLK_MMC2 29 44 + #define CLK_MMC3 30 45 + #define CLK_MSL 31 46 + #define CLK_MSL0 32 47 + #define CLK_MVED 33 48 + #define CLK_NAND 34 49 + #define CLK_NSSP 35 50 + #define CLK_OSTIMER 36 51 + #define CLK_PWM0 37 52 + #define CLK_PWM1 38 53 + #define CLK_PWM2 39 54 + #define CLK_PWM3 40 55 + #define CLK_PWRI2C 41 56 + #define CLK_PXA300_GCU 42 57 + #define CLK_PXA320_GCU 43 58 + #define CLK_SMC 44 59 + #define CLK_SSP 45 60 + #define CLK_SSP1 46 61 + #define CLK_SSP2 47 62 + #define CLK_SSP3 48 63 + #define CLK_SSP4 49 64 + #define CLK_STUART 50 65 + #define CLK_TOUCH 51 66 + #define CLK_TPM 52 67 + #define CLK_UDC 53 68 + #define CLK_USB 54 69 + #define CLK_USB2 55 70 + #define CLK_USBH 56 71 + #define CLK_USBHOST 57 72 + #define CLK_USIM 58 73 + #define CLK_USIM1 59 74 + #define CLK_USMI0 60 75 + #define CLK_MAX 61 76 + 77 + #endif
+1
include/dt-bindings/clock/rk3188-cru-common.h
··· 20 20 #define PLL_GPLL 4 21 21 #define CORE_PERI 5 22 22 #define CORE_L2C 6 23 + #define ARMCLK 7 23 24 24 25 /* sclk gates (special clocks) */ 25 26 #define SCLK_UART0 64
+81 -1
include/dt-bindings/clock/rk3288-cru.h
··· 19 19 #define PLL_CPLL 3 20 20 #define PLL_GPLL 4 21 21 #define PLL_NPLL 5 22 + #define ARMCLK 6 22 23 23 24 /* sclk gates (special clocks) */ 24 25 #define SCLK_GPU 64 ··· 62 61 #define SCLK_LCDC_PWM1 101 63 62 #define SCLK_MAC_RX 102 64 63 #define SCLK_MAC_TX 103 64 + #define SCLK_EDP_24M 104 65 + #define SCLK_EDP 105 66 + #define SCLK_RGA 106 67 + #define SCLK_ISP 107 68 + #define SCLK_ISP_JPE 108 69 + #define SCLK_HDMI_HDCP 109 70 + #define SCLK_HDMI_CEC 110 71 + #define SCLK_HEVC_CABAC 111 72 + #define SCLK_HEVC_CORE 112 65 73 66 74 #define DCLK_VOP0 190 67 75 #define DCLK_VOP1 191 ··· 85 75 #define ACLK_VOP1 198 86 76 #define ACLK_CRYPTO 199 87 77 #define ACLK_RGA 200 78 + #define ACLK_RGA_NIU 201 79 + #define ACLK_IEP 202 80 + #define ACLK_VIO0_NIU 203 81 + #define ACLK_VIP 204 82 + #define ACLK_ISP 205 83 + #define ACLK_VIO1_NIU 206 84 + #define ACLK_HEVC 207 85 + #define ACLK_VCODEC 208 86 + #define ACLK_CPU 209 87 + #define ACLK_PERI 210 88 88 89 89 /* pclk gates */ 90 90 #define PCLK_GPIO0 320 ··· 132 112 #define PCLK_PS2C 352 133 113 #define PCLK_TIMER 353 134 114 #define PCLK_TZPC 354 115 + #define PCLK_EDP_CTRL 355 116 + #define PCLK_MIPI_DSI0 356 117 + #define PCLK_MIPI_DSI1 357 118 + #define PCLK_MIPI_CSI 358 119 + #define PCLK_LVDS_PHY 359 120 + #define PCLK_HDMI_CTRL 360 121 + #define PCLK_VIO2_H2P 361 122 + #define PCLK_CPU 362 123 + #define PCLK_PERI 363 135 124 136 125 /* hclk gates */ 137 126 #define HCLK_GPS 448 ··· 166 137 #define HCLK_IEP 468 167 138 #define HCLK_ISP 469 168 139 #define HCLK_RGA 470 140 + #define HCLK_VIO_AHB_ARBI 471 141 + #define HCLK_VIO_NIU 472 142 + #define HCLK_VIP 473 143 + #define HCLK_VIO2_H2P 474 144 + #define HCLK_HEVC 475 145 + #define HCLK_VCODEC 476 146 + #define HCLK_CPU 477 147 + #define HCLK_PERI 478 169 148 170 - #define CLK_NR_CLKS (HCLK_RGA + 1) 149 + #define CLK_NR_CLKS (HCLK_PERI + 1) 171 150 172 151 /* soft-reset indices */ 173 152 #define SRST_CORE0 0 ··· 313 276 #define SRST_USBHOST1_CON 140 314 277 #define SRST_USB_ADP 141 315 278 #define SRST_ACC_EFUSE 142 279 + 280 + #define SRST_CORESIGHT 144 281 + #define SRST_PD_CORE_AHB_NOC 145 282 + #define SRST_PD_CORE_APB_NOC 146 283 + #define SRST_PD_CORE_MP_AXI 147 284 + #define SRST_GIC 148 285 + #define SRST_LCDC_PWM0 149 286 + #define SRST_LCDC_PWM1 150 287 + #define SRST_VIO0_H2P_BRG 151 288 + #define SRST_VIO1_H2P_BRG 152 289 + #define SRST_RGA_H2P_BRG 153 290 + #define SRST_HEVC 154 291 + #define SRST_TSADC 159 292 + 293 + #define SRST_DDRPHY0 160 294 + #define SRST_DDRPHY0_APB 161 295 + #define SRST_DDRCTRL0 162 296 + #define SRST_DDRCTRL0_APB 163 297 + #define SRST_DDRPHY0_CTRL 164 298 + #define SRST_DDRPHY1 165 299 + #define SRST_DDRPHY1_APB 166 300 + #define SRST_DDRCTRL1 167 301 + #define SRST_DDRCTRL1_APB 168 302 + #define SRST_DDRPHY1_CTRL 169 303 + #define SRST_DDRMSCH0 170 304 + #define SRST_DDRMSCH1 171 305 + #define SRST_CRYPTO 174 306 + #define SRST_C2C_HOST 175 307 + 308 + #define SRST_LCDC1_AXI 176 309 + #define SRST_LCDC1_AHB 177 310 + #define SRST_LCDC1_DCLK 178 311 + #define SRST_UART0 179 312 + #define SRST_UART1 180 313 + #define SRST_UART2 181 314 + #define SRST_UART3 182 315 + #define SRST_UART4 183 316 + #define SRST_SIMC 186 317 + #define SRST_PS2C 187 318 + #define SRST_TSP 188 319 + #define SRST_TSP_CLKIN0 189 320 + #define SRST_TSP_CLKIN1 190 321 + #define SRST_TSP_27M 191
+5 -1
include/dt-bindings/clock/tegra124-car.h
··· 337 337 #define TEGRA124_CLK_DSIB_MUX 310 338 338 #define TEGRA124_CLK_SOR0_LVDS 311 339 339 #define TEGRA124_CLK_XUSB_SS_DIV2 312 340 - #define TEGRA124_CLK_CLK_MAX 313 340 + 341 + #define TEGRA124_CLK_PLL_M_UD 313 342 + #define TEGRA124_CLK_PLL_C_UD 314 343 + 344 + #define TEGRA124_CLK_CLK_MAX 315 341 345 342 346 #endif /* _DT_BINDINGS_CLOCK_TEGRA124_CAR_H */
+2
include/linux/clk-private.h
··· 46 46 unsigned int enable_count; 47 47 unsigned int prepare_count; 48 48 unsigned long accuracy; 49 + int phase; 49 50 struct hlist_head children; 50 51 struct hlist_node child_node; 52 + struct hlist_node debug_node; 51 53 unsigned int notifier_count; 52 54 #ifdef CONFIG_DEBUG_FS 53 55 struct dentry *dentry;
+33
include/linux/clk-provider.h
··· 13 13 14 14 #include <linux/clk.h> 15 15 #include <linux/io.h> 16 + #include <linux/of.h> 16 17 17 18 #ifdef CONFIG_COMMON_CLK 18 19 ··· 130 129 * set then clock accuracy will be initialized to parent accuracy 131 130 * or 0 (perfect clock) if clock has no parent. 132 131 * 132 + * @get_phase: Queries the hardware to get the current phase of a clock. 133 + * Returned values are 0-359 degrees on success, negative 134 + * error codes on failure. 135 + * 136 + * @set_phase: Shift the phase this clock signal in degrees specified 137 + * by the second argument. Valid values for degrees are 138 + * 0-359. Return 0 on success, otherwise -EERROR. 139 + * 133 140 * @init: Perform platform-specific initialization magic. 134 141 * This is not not used by any of the basic clock types. 135 142 * Please consider other ways of solving initialization problems ··· 186 177 unsigned long parent_rate, u8 index); 187 178 unsigned long (*recalc_accuracy)(struct clk_hw *hw, 188 179 unsigned long parent_accuracy); 180 + int (*get_phase)(struct clk_hw *hw); 181 + int (*set_phase)(struct clk_hw *hw, int degrees); 189 182 void (*init)(struct clk_hw *hw); 190 183 int (*debug_init)(struct clk_hw *hw, struct dentry *dentry); 191 184 }; ··· 498 487 struct clk_hw *rate_hw, const struct clk_ops *rate_ops, 499 488 struct clk_hw *gate_hw, const struct clk_ops *gate_ops, 500 489 unsigned long flags); 490 + 491 + /*** 492 + * struct clk_gpio_gate - gpio gated clock 493 + * 494 + * @hw: handle between common and hardware-specific interfaces 495 + * @gpiod: gpio descriptor 496 + * 497 + * Clock with a gpio control for enabling and disabling the parent clock. 498 + * Implements .enable, .disable and .is_enabled 499 + */ 500 + 501 + struct clk_gpio { 502 + struct clk_hw hw; 503 + struct gpio_desc *gpiod; 504 + }; 505 + 506 + extern const struct clk_ops clk_gpio_gate_ops; 507 + struct clk *clk_register_gpio_gate(struct device *dev, const char *name, 508 + const char *parent_name, struct gpio_desc *gpio, 509 + unsigned long flags); 510 + 511 + void of_gpio_clk_gate_setup(struct device_node *node); 501 512 502 513 /** 503 514 * clk_register - allocate a new clock, register it and return an opaque cookie
+29
include/linux/clk.h
··· 106 106 */ 107 107 long clk_get_accuracy(struct clk *clk); 108 108 109 + /** 110 + * clk_set_phase - adjust the phase shift of a clock signal 111 + * @clk: clock signal source 112 + * @degrees: number of degrees the signal is shifted 113 + * 114 + * Shifts the phase of a clock signal by the specified degrees. Returns 0 on 115 + * success, -EERROR otherwise. 116 + */ 117 + int clk_set_phase(struct clk *clk, int degrees); 118 + 119 + /** 120 + * clk_get_phase - return the phase shift of a clock signal 121 + * @clk: clock signal source 122 + * 123 + * Returns the phase shift of a clock node in degrees, otherwise returns 124 + * -EERROR. 125 + */ 126 + int clk_get_phase(struct clk *clk); 127 + 109 128 #else 110 129 111 130 static inline long clk_get_accuracy(struct clk *clk) 131 + { 132 + return -ENOTSUPP; 133 + } 134 + 135 + static inline long clk_set_phase(struct clk *clk, int phase) 136 + { 137 + return -ENOTSUPP; 138 + } 139 + 140 + static inline long clk_get_phase(struct clk *clk) 112 141 { 113 142 return -ENOTSUPP; 114 143 }
+1
include/linux/clk/ti.h
··· 292 292 void __iomem *ti_clk_get_reg_addr(struct device_node *node, int index); 293 293 void ti_dt_clocks_register(struct ti_dt_clk *oclks); 294 294 void ti_dt_clk_init_provider(struct device_node *np, int index); 295 + void ti_dt_clk_init_retry_clks(void); 295 296 void ti_dt_clockdomains_setup(void); 296 297 int ti_clk_retry_init(struct device_node *node, struct clk_hw *hw, 297 298 ti_of_clk_init_cb_t func);