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

Configure Feed

Select the types of activity you want to include in your feed.

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

Pull more clock framework updates from Mike Turquette:
"This contains the second half the of the clk changes for 3.16.

They are simply fixes and code refactoring for the OMAP clock drivers.
The sunxi clock driver changes include splitting out the one
mega-driver into several smaller pieces and adding support for the A31
SoC clocks"

* tag 'clk-for-linus-3.16-part2' of git://git.linaro.org/people/mike.turquette/linux: (25 commits)
clk: sunxi: document PRCM clock compatible strings
clk: sunxi: add PRCM (Power/Reset/Clock Management) clks support
clk: sun6i: Protect SDRAM gating bit
clk: sun6i: Protect CPU clock
clk: sunxi: Rework clock protection code
clk: sunxi: Move the GMAC clock to a file of its own
clk: sunxi: Move the 24M oscillator to a file of its own
clk: sunxi: Remove calls to clk_put
clk: sunxi: document new A31 USB clock compatible
clk: sunxi: Implement A31 USB clock
ARM: dts: OMAP5/DRA7: use omap5-mpu-dpll-clock capable of dealing with higher frequencies
CLK: TI: dpll: support OMAP5 MPU DPLL that need special handling for higher frequencies
ARM: OMAP5+: dpll: support Duty Cycle Correction(DCC)
CLK: TI: clk-54xx: Set the rate for dpll_abe_m2x2_ck
CLK: TI: Driver for DRA7 ATL (Audio Tracking Logic)
dt:/bindings: DRA7 ATL (Audio Tracking Logic) clock bindings
ARM: dts: dra7xx-clocks: Correct name for atl clkin3 clock
CLK: TI: gate: add composite interface clock to OMAP2 only build
ARM: OMAP2: clock: add DT boot support for cpufreq_ck
CLK: TI: OMAP2: add clock init support
...

+1836 -265
+4
Documentation/devicetree/bindings/clock/sunxi.txt
··· 20 20 "allwinner,sun5i-a13-ahb-gates-clk" - for the AHB gates on A13 21 21 "allwinner,sun5i-a10s-ahb-gates-clk" - for the AHB gates on A10s 22 22 "allwinner,sun7i-a20-ahb-gates-clk" - for the AHB gates on A20 23 + "allwinner,sun6i-a31-ar100-clk" - for the AR100 on A31 23 24 "allwinner,sun6i-a31-ahb1-mux-clk" - for the AHB1 multiplexer on A31 24 25 "allwinner,sun6i-a31-ahb1-gates-clk" - for the AHB1 gates on A31 25 26 "allwinner,sun4i-a10-apb0-clk" - for the APB0 clock 27 + "allwinner,sun6i-a31-apb0-clk" - for the APB0 clock on A31 26 28 "allwinner,sun4i-a10-apb0-gates-clk" - for the APB0 gates on A10 27 29 "allwinner,sun5i-a13-apb0-gates-clk" - for the APB0 gates on A13 28 30 "allwinner,sun5i-a10s-apb0-gates-clk" - for the APB0 gates on A10s 31 + "allwinner,sun6i-a31-apb0-gates-clk" - for the APB0 gates on A31 29 32 "allwinner,sun7i-a20-apb0-gates-clk" - for the APB0 gates on A20 30 33 "allwinner,sun4i-a10-apb1-clk" - for the APB1 clock 31 34 "allwinner,sun4i-a10-apb1-mux-clk" - for the APB1 clock muxing ··· 44 41 "allwinner,sun7i-a20-gmac-clk" - for the GMAC clock module on A20/A31 45 42 "allwinner,sun4i-a10-usb-clk" - for usb gates + resets on A10 / A20 46 43 "allwinner,sun5i-a13-usb-clk" - for usb gates + resets on A13 44 + "allwinner,sun6i-a31-usb-clk" - for usb gates + resets on A31 47 45 48 46 Required properties for all clocks: 49 47 - reg : shall be the control register address for the clock.
+19 -5
Documentation/devicetree/bindings/clock/ti/apll.txt
··· 14 14 [2] Documentation/devicetree/bindings/clock/ti/dpll.txt 15 15 16 16 Required properties: 17 - - compatible : shall be "ti,dra7-apll-clock" 17 + - compatible : shall be "ti,dra7-apll-clock" or "ti,omap2-apll-clock" 18 18 - #clock-cells : from common clock binding; shall be set to 0. 19 19 - clocks : link phandles of parent clocks (clk-ref and clk-bypass) 20 20 - reg : address and length of the register set for controlling the APLL. 21 21 It contains the information of registers in the following order: 22 - "control" - contains the control register base address 23 - "idlest" - contains the idlest register base address 22 + "control" - contains the control register offset 23 + "idlest" - contains the idlest register offset 24 + "autoidle" - contains the autoidle register offset (OMAP2 only) 25 + - ti,clock-frequency : static clock frequency for the clock (OMAP2 only) 26 + - ti,idlest-shift : bit-shift for the idlest field (OMAP2 only) 27 + - ti,bit-shift : bit-shift for enable and autoidle fields (OMAP2 only) 24 28 25 29 Examples: 26 - apll_pcie_ck: apll_pcie_ck@4a008200 { 30 + apll_pcie_ck: apll_pcie_ck { 27 31 #clock-cells = <0>; 28 32 clocks = <&apll_pcie_in_clk_mux>, <&dpll_pcie_ref_ck>; 29 - reg = <0x4a00821c 0x4>, <0x4a008220 0x4>; 33 + reg = <0x021c>, <0x0220>; 30 34 compatible = "ti,dra7-apll-clock"; 35 + }; 36 + 37 + apll96_ck: apll96_ck { 38 + #clock-cells = <0>; 39 + compatible = "ti,omap2-apll-clock"; 40 + clocks = <&sys_ck>; 41 + ti,bit-shift = <2>; 42 + ti,idlest-shift = <8>; 43 + ti,clock-frequency = <96000000>; 44 + reg = <0x0500>, <0x0530>, <0x0520>; 31 45 };
+10
Documentation/devicetree/bindings/clock/ti/dpll.txt
··· 24 24 "ti,omap4-dpll-core-clock", 25 25 "ti,omap4-dpll-m4xen-clock", 26 26 "ti,omap4-dpll-j-type-clock", 27 + "ti,omap5-mpu-dpll-clock", 27 28 "ti,am3-dpll-no-gate-clock", 28 29 "ti,am3-dpll-j-type-clock", 29 30 "ti,am3-dpll-no-gate-j-type-clock", 30 31 "ti,am3-dpll-clock", 31 32 "ti,am3-dpll-core-clock", 32 33 "ti,am3-dpll-x2-clock", 34 + "ti,omap2-dpll-core-clock", 33 35 34 36 - #clock-cells : from common clock binding; shall be set to 0. 35 37 - clocks : link phandles of parent clocks, first entry lists reference clock ··· 43 41 "mult-div1" - contains the multiplier / divider register base address 44 42 "autoidle" - contains the autoidle register base address (optional) 45 43 ti,am3-* dpll types do not have autoidle register 44 + ti,omap2-* dpll type does not support idlest / autoidle registers 46 45 47 46 Optional properties: 48 47 - DPLL mode setting - defining any one or more of the following overrides ··· 75 72 compatible = "ti,am3-dpll-core-clock"; 76 73 clocks = <&sys_clkin_ck>, <&sys_clkin_ck>; 77 74 reg = <0x90>, <0x5c>, <0x68>; 75 + }; 76 + 77 + dpll_ck: dpll_ck { 78 + #clock-cells = <0>; 79 + compatible = "ti,omap2-dpll-core-clock"; 80 + clocks = <&sys_ck>, <&sys_ck>; 81 + reg = <0x0500>, <0x0540>; 78 82 };
+96
Documentation/devicetree/bindings/clock/ti/dra7-atl.txt
··· 1 + Device Tree Clock bindings for ATL (Audio Tracking Logic) of DRA7 SoC. 2 + 3 + The ATL IP is used to generate clock to be used to synchronize baseband and 4 + audio codec. A single ATL IP provides four ATL clock instances sharing the same 5 + functional clock but can be configured to provide different clocks. 6 + ATL can maintain a clock averages to some desired frequency based on the bws/aws 7 + signals - can compensate the drift between the two ws signal. 8 + 9 + In order to provide the support for ATL and it's output clocks (which can be used 10 + internally within the SoC or external components) two sets of bindings is needed: 11 + 12 + Clock tree binding: 13 + This binding uses the common clock binding[1]. 14 + To be able to integrate the ATL clocks with DT clock tree. 15 + Provides ccf level representation of the ATL clocks to be used by drivers. 16 + Since the clock instances are part of a single IP this binding is used as a node 17 + for the DT clock tree, the IP driver is needed to handle the actual configuration 18 + of the IP. 19 + 20 + [1] Documentation/devicetree/bindings/clock/clock-bindings.txt 21 + 22 + Required properties: 23 + - compatible : shall be "ti,dra7-atl-clock" 24 + - #clock-cells : from common clock binding; shall be set to 0. 25 + - clocks : link phandles to functional clock of ATL 26 + 27 + Binding for the IP driver: 28 + This binding is used to configure the IP driver which is going to handle the 29 + configuration of the IP for the ATL clock instances. 30 + 31 + Required properties: 32 + - compatible : shall be "ti,dra7-atl" 33 + - reg : base address for the ATL IP 34 + - ti,provided-clocks : List of phandles to the clocks associated with the ATL 35 + - clocks : link phandles to functional clock of ATL 36 + - clock-names : Shall be set to "fck" 37 + - ti,hwmods : Shall be set to "atl" 38 + 39 + Optional properties: 40 + Configuration of ATL instances: 41 + - atl{0/1/2/3} { 42 + - bws : Baseband word select signal selection 43 + - aws : Audio word select signal selection 44 + }; 45 + 46 + For valid word select signals, see the dt-bindings/clk/ti-dra7-atl.h include 47 + file. 48 + 49 + Examples: 50 + /* clock bindings for atl provided clocks */ 51 + atl_clkin0_ck: atl_clkin0_ck { 52 + #clock-cells = <0>; 53 + compatible = "ti,dra7-atl-clock"; 54 + clocks = <&atl_gfclk_mux>; 55 + }; 56 + 57 + atl_clkin1_ck: atl_clkin1_ck { 58 + #clock-cells = <0>; 59 + compatible = "ti,dra7-atl-clock"; 60 + clocks = <&atl_gfclk_mux>; 61 + }; 62 + 63 + atl_clkin2_ck: atl_clkin2_ck { 64 + #clock-cells = <0>; 65 + compatible = "ti,dra7-atl-clock"; 66 + clocks = <&atl_gfclk_mux>; 67 + }; 68 + 69 + atl_clkin3_ck: atl_clkin3_ck { 70 + #clock-cells = <0>; 71 + compatible = "ti,dra7-atl-clock"; 72 + clocks = <&atl_gfclk_mux>; 73 + }; 74 + 75 + /* binding for the IP */ 76 + atl: atl@4843c000 { 77 + compatible = "ti,dra7-atl"; 78 + reg = <0x4843c000 0x3ff>; 79 + ti,hwmods = "atl"; 80 + ti,provided-clocks = <&atl_clkin0_ck>, <&atl_clkin1_ck>, 81 + <&atl_clkin2_ck>, <&atl_clkin3_ck>; 82 + clocks = <&atl_gfclk_mux>; 83 + clock-names = "fck"; 84 + status = "disabled"; 85 + }; 86 + 87 + #include <dt-bindings/clk/ti-dra7-atl.h> 88 + 89 + &atl { 90 + status = "okay"; 91 + 92 + atl2 { 93 + bws = <DRA7_ATL_WS_MCASP2_FSX>; 94 + aws = <DRA7_ATL_WS_MCASP3_FSX>; 95 + }; 96 + };
+25 -4
Documentation/devicetree/bindings/clock/ti/gate.txt
··· 25 25 to map clockdomains properly 26 26 "ti,hsdiv-gate-clock" - gate clock with OMAP36xx specific hardware handling, 27 27 required for a hardware errata 28 + "ti,composite-gate-clock" - composite gate clock, to be part of composite 29 + clock 30 + "ti,composite-no-wait-gate-clock" - composite gate clock that does not wait 31 + for clock to be active before returning 32 + from clk_enable() 28 33 - #clock-cells : from common clock binding; shall be set to 0 29 34 - clocks : link to phandle of parent clock 30 35 - reg : offset for register controlling adjustable gate, not needed for ··· 46 41 #clock-cells = <0>; 47 42 compatible = "ti,gate-clock"; 48 43 clocks = <&core_96m_fck>; 49 - reg = <0x48004a00 0x4>; 44 + reg = <0x0a00>; 50 45 ti,bit-shift = <25>; 51 46 }; 52 47 ··· 62 57 #clock-cells = <0>; 63 58 compatible = "ti,dss-gate-clock"; 64 59 clocks = <&dpll4_m4x2_ck>; 65 - reg = <0x48004e00 0x4>; 60 + reg = <0x0e00>; 66 61 ti,bit-shift = <0>; 67 62 }; 68 63 ··· 70 65 #clock-cells = <0>; 71 66 compatible = "ti,am35xx-gate-clock"; 72 67 clocks = <&ipss_ick>; 73 - reg = <0x4800259c 0x4>; 68 + reg = <0x059c>; 74 69 ti,bit-shift = <1>; 75 70 }; 76 71 ··· 85 80 compatible = "ti,hsdiv-gate-clock"; 86 81 clocks = <&dpll4_m2x2_mul_ck>; 87 82 ti,bit-shift = <0x1b>; 88 - reg = <0x48004d00 0x4>; 83 + reg = <0x0d00>; 89 84 ti,set-bit-to-disable; 85 + }; 86 + 87 + vlynq_gate_fck: vlynq_gate_fck { 88 + #clock-cells = <0>; 89 + compatible = "ti,composite-gate-clock"; 90 + clocks = <&core_ck>; 91 + ti,bit-shift = <3>; 92 + reg = <0x0200>; 93 + }; 94 + 95 + sys_clkout2_src_gate: sys_clkout2_src_gate { 96 + #clock-cells = <0>; 97 + compatible = "ti,composite-no-wait-gate-clock"; 98 + clocks = <&core_ck>; 99 + ti,bit-shift = <15>; 100 + reg = <0x0070>; 90 101 };
+2
Documentation/devicetree/bindings/clock/ti/interface.txt
··· 21 21 "ti,omap3-dss-interface-clock" - interface clock with DSS specific HW handling 22 22 "ti,omap3-ssi-interface-clock" - interface clock with SSI specific HW handling 23 23 "ti,am35xx-interface-clock" - interface clock with AM35xx specific HW handling 24 + "ti,omap2430-interface-clock" - interface clock with OMAP2430 specific HW 25 + handling 24 26 - #clock-cells : from common clock binding; shall be set to 0 25 27 - clocks : link to phandle of parent clock 26 28 - reg : base address for the control register
+12 -12
arch/arm/boot/dts/dra7xx-clocks.dtsi
··· 26 26 clock-frequency = <0>; 27 27 }; 28 28 29 - atlclkin3_ck: atlclkin3_ck { 29 + atl_clkin3_ck: atl_clkin3_ck { 30 30 #clock-cells = <0>; 31 31 compatible = "fixed-clock"; 32 32 clock-frequency = <0>; ··· 277 277 278 278 dpll_mpu_ck: dpll_mpu_ck { 279 279 #clock-cells = <0>; 280 - compatible = "ti,omap4-dpll-clock"; 280 + compatible = "ti,omap5-mpu-dpll-clock"; 281 281 clocks = <&sys_clkin1>, <&mpu_dpll_hs_clk_div>; 282 282 reg = <0x0160>, <0x0164>, <0x016c>, <0x0168>; 283 283 }; ··· 730 730 mcasp1_ahclkr_mux: mcasp1_ahclkr_mux { 731 731 #clock-cells = <0>; 732 732 compatible = "ti,mux-clock"; 733 - clocks = <&abe_24m_fclk>, <&abe_sys_clk_div>, <&func_24m_clk>, <&atlclkin3_ck>, <&atl_clkin2_ck>, <&atl_clkin1_ck>, <&atl_clkin0_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&mlb_clk>, <&mlbp_clk>; 733 + clocks = <&abe_24m_fclk>, <&abe_sys_clk_div>, <&func_24m_clk>, <&atl_clkin3_ck>, <&atl_clkin2_ck>, <&atl_clkin1_ck>, <&atl_clkin0_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&mlb_clk>, <&mlbp_clk>; 734 734 ti,bit-shift = <28>; 735 735 reg = <0x0550>; 736 736 }; ··· 738 738 mcasp1_ahclkx_mux: mcasp1_ahclkx_mux { 739 739 #clock-cells = <0>; 740 740 compatible = "ti,mux-clock"; 741 - clocks = <&abe_24m_fclk>, <&abe_sys_clk_div>, <&func_24m_clk>, <&atlclkin3_ck>, <&atl_clkin2_ck>, <&atl_clkin1_ck>, <&atl_clkin0_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&mlb_clk>, <&mlbp_clk>; 741 + clocks = <&abe_24m_fclk>, <&abe_sys_clk_div>, <&func_24m_clk>, <&atl_clkin3_ck>, <&atl_clkin2_ck>, <&atl_clkin1_ck>, <&atl_clkin0_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&mlb_clk>, <&mlbp_clk>; 742 742 ti,bit-shift = <24>; 743 743 reg = <0x0550>; 744 744 }; ··· 1639 1639 mcasp2_ahclkr_mux: mcasp2_ahclkr_mux { 1640 1640 #clock-cells = <0>; 1641 1641 compatible = "ti,mux-clock"; 1642 - clocks = <&abe_24m_fclk>, <&abe_sys_clk_div>, <&func_24m_clk>, <&atlclkin3_ck>, <&atl_clkin2_ck>, <&atl_clkin1_ck>, <&atl_clkin0_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&mlb_clk>, <&mlbp_clk>; 1642 + clocks = <&abe_24m_fclk>, <&abe_sys_clk_div>, <&func_24m_clk>, <&atl_clkin3_ck>, <&atl_clkin2_ck>, <&atl_clkin1_ck>, <&atl_clkin0_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&mlb_clk>, <&mlbp_clk>; 1643 1643 ti,bit-shift = <28>; 1644 1644 reg = <0x1860>; 1645 1645 }; ··· 1647 1647 mcasp2_ahclkx_mux: mcasp2_ahclkx_mux { 1648 1648 #clock-cells = <0>; 1649 1649 compatible = "ti,mux-clock"; 1650 - clocks = <&abe_24m_fclk>, <&abe_sys_clk_div>, <&func_24m_clk>, <&atlclkin3_ck>, <&atl_clkin2_ck>, <&atl_clkin1_ck>, <&atl_clkin0_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&mlb_clk>, <&mlbp_clk>; 1650 + clocks = <&abe_24m_fclk>, <&abe_sys_clk_div>, <&func_24m_clk>, <&atl_clkin3_ck>, <&atl_clkin2_ck>, <&atl_clkin1_ck>, <&atl_clkin0_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&mlb_clk>, <&mlbp_clk>; 1651 1651 ti,bit-shift = <24>; 1652 1652 reg = <0x1860>; 1653 1653 }; ··· 1663 1663 mcasp3_ahclkx_mux: mcasp3_ahclkx_mux { 1664 1664 #clock-cells = <0>; 1665 1665 compatible = "ti,mux-clock"; 1666 - clocks = <&abe_24m_fclk>, <&abe_sys_clk_div>, <&func_24m_clk>, <&atlclkin3_ck>, <&atl_clkin2_ck>, <&atl_clkin1_ck>, <&atl_clkin0_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&mlb_clk>, <&mlbp_clk>; 1666 + clocks = <&abe_24m_fclk>, <&abe_sys_clk_div>, <&func_24m_clk>, <&atl_clkin3_ck>, <&atl_clkin2_ck>, <&atl_clkin1_ck>, <&atl_clkin0_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&mlb_clk>, <&mlbp_clk>; 1667 1667 ti,bit-shift = <24>; 1668 1668 reg = <0x1868>; 1669 1669 }; ··· 1679 1679 mcasp4_ahclkx_mux: mcasp4_ahclkx_mux { 1680 1680 #clock-cells = <0>; 1681 1681 compatible = "ti,mux-clock"; 1682 - clocks = <&abe_24m_fclk>, <&abe_sys_clk_div>, <&func_24m_clk>, <&atlclkin3_ck>, <&atl_clkin2_ck>, <&atl_clkin1_ck>, <&atl_clkin0_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&mlb_clk>, <&mlbp_clk>; 1682 + clocks = <&abe_24m_fclk>, <&abe_sys_clk_div>, <&func_24m_clk>, <&atl_clkin3_ck>, <&atl_clkin2_ck>, <&atl_clkin1_ck>, <&atl_clkin0_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&mlb_clk>, <&mlbp_clk>; 1683 1683 ti,bit-shift = <24>; 1684 1684 reg = <0x1898>; 1685 1685 }; ··· 1695 1695 mcasp5_ahclkx_mux: mcasp5_ahclkx_mux { 1696 1696 #clock-cells = <0>; 1697 1697 compatible = "ti,mux-clock"; 1698 - clocks = <&abe_24m_fclk>, <&abe_sys_clk_div>, <&func_24m_clk>, <&atlclkin3_ck>, <&atl_clkin2_ck>, <&atl_clkin1_ck>, <&atl_clkin0_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&mlb_clk>, <&mlbp_clk>; 1698 + clocks = <&abe_24m_fclk>, <&abe_sys_clk_div>, <&func_24m_clk>, <&atl_clkin3_ck>, <&atl_clkin2_ck>, <&atl_clkin1_ck>, <&atl_clkin0_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&mlb_clk>, <&mlbp_clk>; 1699 1699 ti,bit-shift = <24>; 1700 1700 reg = <0x1878>; 1701 1701 }; ··· 1711 1711 mcasp6_ahclkx_mux: mcasp6_ahclkx_mux { 1712 1712 #clock-cells = <0>; 1713 1713 compatible = "ti,mux-clock"; 1714 - clocks = <&abe_24m_fclk>, <&abe_sys_clk_div>, <&func_24m_clk>, <&atlclkin3_ck>, <&atl_clkin2_ck>, <&atl_clkin1_ck>, <&atl_clkin0_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&mlb_clk>, <&mlbp_clk>; 1714 + clocks = <&abe_24m_fclk>, <&abe_sys_clk_div>, <&func_24m_clk>, <&atl_clkin3_ck>, <&atl_clkin2_ck>, <&atl_clkin1_ck>, <&atl_clkin0_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&mlb_clk>, <&mlbp_clk>; 1715 1715 ti,bit-shift = <24>; 1716 1716 reg = <0x1904>; 1717 1717 }; ··· 1727 1727 mcasp7_ahclkx_mux: mcasp7_ahclkx_mux { 1728 1728 #clock-cells = <0>; 1729 1729 compatible = "ti,mux-clock"; 1730 - clocks = <&abe_24m_fclk>, <&abe_sys_clk_div>, <&func_24m_clk>, <&atlclkin3_ck>, <&atl_clkin2_ck>, <&atl_clkin1_ck>, <&atl_clkin0_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&mlb_clk>, <&mlbp_clk>; 1730 + clocks = <&abe_24m_fclk>, <&abe_sys_clk_div>, <&func_24m_clk>, <&atl_clkin3_ck>, <&atl_clkin2_ck>, <&atl_clkin1_ck>, <&atl_clkin0_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&mlb_clk>, <&mlbp_clk>; 1731 1731 ti,bit-shift = <24>; 1732 1732 reg = <0x1908>; 1733 1733 }; ··· 1743 1743 mcasp8_ahclk_mux: mcasp8_ahclk_mux { 1744 1744 #clock-cells = <0>; 1745 1745 compatible = "ti,mux-clock"; 1746 - clocks = <&abe_24m_fclk>, <&abe_sys_clk_div>, <&func_24m_clk>, <&atlclkin3_ck>, <&atl_clkin2_ck>, <&atl_clkin1_ck>, <&atl_clkin0_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&mlb_clk>, <&mlbp_clk>; 1746 + clocks = <&abe_24m_fclk>, <&abe_sys_clk_div>, <&func_24m_clk>, <&atl_clkin3_ck>, <&atl_clkin2_ck>, <&atl_clkin1_ck>, <&atl_clkin0_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&mlb_clk>, <&mlbp_clk>; 1747 1747 ti,bit-shift = <22>; 1748 1748 reg = <0x1890>; 1749 1749 };
+1 -1
arch/arm/boot/dts/omap54xx-clocks.dtsi
··· 335 335 336 336 dpll_mpu_ck: dpll_mpu_ck { 337 337 #clock-cells = <0>; 338 - compatible = "ti,omap4-dpll-clock"; 338 + compatible = "ti,omap5-mpu-dpll-clock"; 339 339 clocks = <&sys_clkin>, <&mpu_dpll_hs_clk_div>; 340 340 reg = <0x0160>, <0x0164>, <0x016c>, <0x0168>; 341 341 };
+53
arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c
··· 208 208 clk_put(c); 209 209 } 210 210 } 211 + 212 + #ifdef CONFIG_OF 213 + #include <linux/clk-provider.h> 214 + #include <linux/clkdev.h> 215 + 216 + static const struct clk_ops virt_prcm_set_ops = { 217 + .recalc_rate = &omap2_table_mpu_recalc, 218 + .set_rate = &omap2_select_table_rate, 219 + .round_rate = &omap2_round_to_table_rate, 220 + }; 221 + 222 + /** 223 + * omap2xxx_clkt_vps_init - initialize virt_prcm_set clock 224 + * 225 + * Does a manual init for the virtual prcm DVFS clock for OMAP2. This 226 + * function is called only from omap2 DT clock init, as the virtual 227 + * node is not modelled in the DT clock data. 228 + */ 229 + void omap2xxx_clkt_vps_init(void) 230 + { 231 + struct clk_init_data init = { NULL }; 232 + struct clk_hw_omap *hw = NULL; 233 + struct clk *clk; 234 + const char *parent_name = "mpu_ck"; 235 + struct clk_lookup *lookup = NULL; 236 + 237 + omap2xxx_clkt_vps_late_init(); 238 + omap2xxx_clkt_vps_check_bootloader_rates(); 239 + 240 + hw = kzalloc(sizeof(*hw), GFP_KERNEL); 241 + lookup = kzalloc(sizeof(*lookup), GFP_KERNEL); 242 + if (!hw || !lookup) 243 + goto cleanup; 244 + init.name = "virt_prcm_set"; 245 + init.ops = &virt_prcm_set_ops; 246 + init.parent_names = &parent_name; 247 + init.num_parents = 1; 248 + 249 + hw->hw.init = &init; 250 + 251 + clk = clk_register(NULL, &hw->hw); 252 + 253 + lookup->dev_id = NULL; 254 + lookup->con_id = "cpufreq_ck"; 255 + lookup->clk = clk; 256 + 257 + clkdev_add(lookup); 258 + return; 259 + cleanup: 260 + kfree(hw); 261 + kfree(lookup); 262 + } 263 + #endif
-13
arch/arm/mach-omap2/clock.h
··· 178 178 const struct clksel_rate *rates; 179 179 }; 180 180 181 - struct clk_hw_omap_ops { 182 - void (*find_idlest)(struct clk_hw_omap *oclk, 183 - void __iomem **idlest_reg, 184 - u8 *idlest_bit, u8 *idlest_val); 185 - void (*find_companion)(struct clk_hw_omap *oclk, 186 - void __iomem **other_reg, 187 - u8 *other_bit); 188 - void (*allow_idle)(struct clk_hw_omap *oclk); 189 - void (*deny_idle)(struct clk_hw_omap *oclk); 190 - }; 191 - 192 181 unsigned long omap_fixed_divisor_recalc(struct clk_hw *hw, 193 182 unsigned long parent_rate); 194 183 ··· 268 279 extern const struct clk_hw_omap_ops clkhwops_am35xx_ipss_module_wait; 269 280 extern const struct clk_hw_omap_ops clkhwops_apll54; 270 281 extern const struct clk_hw_omap_ops clkhwops_apll96; 271 - extern const struct clk_hw_omap_ops clkhwops_omap2xxx_dpll; 272 - extern const struct clk_hw_omap_ops clkhwops_omap2430_i2chs_wait; 273 282 274 283 /* clksel_rate blocks shared between OMAP44xx and AM33xx */ 275 284 extern const struct clksel_rate div_1_0_rates[];
-4
arch/arm/mach-omap2/clock2xxx.h
··· 21 21 unsigned long parent_rate); 22 22 unsigned long omap2_osc_clk_recalc(struct clk_hw *clk, 23 23 unsigned long parent_rate); 24 - unsigned long omap2_dpllcore_recalc(struct clk_hw *hw, 25 - unsigned long parent_rate); 26 - int omap2_reprogram_dpllcore(struct clk_hw *clk, unsigned long rate, 27 - unsigned long parent_rate); 28 24 void omap2xxx_clkt_dpllcore_init(struct clk_hw *hw); 29 25 unsigned long omap2_clk_apll54_recalc(struct clk_hw *hw, 30 26 unsigned long parent_rate);
+9
arch/arm/mach-omap2/dpll3xxx.c
··· 319 319 320 320 /* Set DPLL multiplier, divider */ 321 321 v = omap2_clk_readl(clk, dd->mult_div1_reg); 322 + 323 + /* Handle Duty Cycle Correction */ 324 + if (dd->dcc_mask) { 325 + if (dd->last_rounded_rate >= dd->dcc_rate) 326 + v |= dd->dcc_mask; /* Enable DCC */ 327 + else 328 + v &= ~dd->dcc_mask; /* Disable DCC */ 329 + } 330 + 322 331 v &= ~(dd->mult_mask | dd->div1_mask); 323 332 v |= dd->last_rounded_m << __ffs(dd->mult_mask); 324 333 v |= (dd->last_rounded_n - 1) << __ffs(dd->div1_mask);
+4
drivers/clk/sunxi/Makefile
··· 3 3 # 4 4 5 5 obj-y += clk-sunxi.o clk-factors.o 6 + obj-y += clk-a10-hosc.o 7 + obj-y += clk-a20-gmac.o 8 + 9 + obj-$(CONFIG_MFD_SUN6I_PRCM) += clk-sun6i-ar100.o clk-sun6i-apb0.o clk-sun6i-apb0-gates.o
+73
drivers/clk/sunxi/clk-a10-hosc.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.h> 20 + #include <linux/of_address.h> 21 + 22 + #define SUNXI_OSC24M_GATE 0 23 + 24 + static DEFINE_SPINLOCK(hosc_lock); 25 + 26 + static void __init sun4i_osc_clk_setup(struct device_node *node) 27 + { 28 + struct clk *clk; 29 + struct clk_fixed_rate *fixed; 30 + struct clk_gate *gate; 31 + const char *clk_name = node->name; 32 + u32 rate; 33 + 34 + if (of_property_read_u32(node, "clock-frequency", &rate)) 35 + return; 36 + 37 + /* allocate fixed-rate and gate clock structs */ 38 + fixed = kzalloc(sizeof(struct clk_fixed_rate), GFP_KERNEL); 39 + if (!fixed) 40 + return; 41 + gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL); 42 + if (!gate) 43 + goto err_free_fixed; 44 + 45 + of_property_read_string(node, "clock-output-names", &clk_name); 46 + 47 + /* set up gate and fixed rate properties */ 48 + gate->reg = of_iomap(node, 0); 49 + gate->bit_idx = SUNXI_OSC24M_GATE; 50 + gate->lock = &hosc_lock; 51 + fixed->fixed_rate = rate; 52 + 53 + clk = clk_register_composite(NULL, clk_name, 54 + NULL, 0, 55 + NULL, NULL, 56 + &fixed->hw, &clk_fixed_rate_ops, 57 + &gate->hw, &clk_gate_ops, 58 + CLK_IS_ROOT); 59 + 60 + if (IS_ERR(clk)) 61 + goto err_free_gate; 62 + 63 + of_clk_add_provider(node, of_clk_src_simple_get, clk); 64 + clk_register_clkdev(clk, clk_name, NULL); 65 + 66 + return; 67 + 68 + err_free_gate: 69 + kfree(gate); 70 + err_free_fixed: 71 + kfree(fixed); 72 + } 73 + CLK_OF_DECLARE(sun4i_osc, "allwinner,sun4i-a10-osc-clk", sun4i_osc_clk_setup);
+119
drivers/clk/sunxi/clk-a20-gmac.c
··· 1 + /* 2 + * Copyright 2013 Emilio López 3 + * Emilio López <emilio@elopez.com.ar> 4 + * 5 + * Copyright 2013 Chen-Yu Tsai 6 + * Chen-Yu Tsai <wens@csie.org> 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; either version 2 of the License, or 11 + * (at your option) any later version. 12 + * 13 + * This program is distributed in the hope that it will be useful, 14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 + * GNU General Public License for more details. 17 + */ 18 + 19 + #include <linux/clk-provider.h> 20 + #include <linux/clkdev.h> 21 + #include <linux/of.h> 22 + #include <linux/of_address.h> 23 + #include <linux/slab.h> 24 + 25 + static DEFINE_SPINLOCK(gmac_lock); 26 + 27 + /** 28 + * sun7i_a20_gmac_clk_setup - Setup function for A20/A31 GMAC clock module 29 + * 30 + * This clock looks something like this 31 + * ________________________ 32 + * MII TX clock from PHY >-----|___________ _________|----> to GMAC core 33 + * GMAC Int. RGMII TX clk >----|___________\__/__gate---|----> to PHY 34 + * Ext. 125MHz RGMII TX clk >--|__divider__/ | 35 + * |________________________| 36 + * 37 + * The external 125 MHz reference is optional, i.e. GMAC can use its 38 + * internal TX clock just fine. The A31 GMAC clock module does not have 39 + * the divider controls for the external reference. 40 + * 41 + * To keep it simple, let the GMAC use either the MII TX clock for MII mode, 42 + * and its internal TX clock for GMII and RGMII modes. The GMAC driver should 43 + * select the appropriate source and gate/ungate the output to the PHY. 44 + * 45 + * Only the GMAC should use this clock. Altering the clock so that it doesn't 46 + * match the GMAC's operation parameters will result in the GMAC not being 47 + * able to send traffic out. The GMAC driver should set the clock rate and 48 + * enable/disable this clock to configure the required state. The clock 49 + * driver then responds by auto-reparenting the clock. 50 + */ 51 + 52 + #define SUN7I_A20_GMAC_GPIT 2 53 + #define SUN7I_A20_GMAC_MASK 0x3 54 + #define SUN7I_A20_GMAC_PARENTS 2 55 + 56 + static void __init sun7i_a20_gmac_clk_setup(struct device_node *node) 57 + { 58 + struct clk *clk; 59 + struct clk_mux *mux; 60 + struct clk_gate *gate; 61 + const char *clk_name = node->name; 62 + const char *parents[SUN7I_A20_GMAC_PARENTS]; 63 + void *reg; 64 + 65 + if (of_property_read_string(node, "clock-output-names", &clk_name)) 66 + return; 67 + 68 + /* allocate mux and gate clock structs */ 69 + mux = kzalloc(sizeof(struct clk_mux), GFP_KERNEL); 70 + if (!mux) 71 + return; 72 + 73 + gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL); 74 + if (!gate) 75 + goto free_mux; 76 + 77 + /* gmac clock requires exactly 2 parents */ 78 + parents[0] = of_clk_get_parent_name(node, 0); 79 + parents[1] = of_clk_get_parent_name(node, 1); 80 + if (!parents[0] || !parents[1]) 81 + goto free_gate; 82 + 83 + reg = of_iomap(node, 0); 84 + if (!reg) 85 + goto free_gate; 86 + 87 + /* set up gate and fixed rate properties */ 88 + gate->reg = reg; 89 + gate->bit_idx = SUN7I_A20_GMAC_GPIT; 90 + gate->lock = &gmac_lock; 91 + mux->reg = reg; 92 + mux->mask = SUN7I_A20_GMAC_MASK; 93 + mux->flags = CLK_MUX_INDEX_BIT; 94 + mux->lock = &gmac_lock; 95 + 96 + clk = clk_register_composite(NULL, clk_name, 97 + parents, SUN7I_A20_GMAC_PARENTS, 98 + &mux->hw, &clk_mux_ops, 99 + NULL, NULL, 100 + &gate->hw, &clk_gate_ops, 101 + 0); 102 + 103 + if (IS_ERR(clk)) 104 + goto iounmap_reg; 105 + 106 + of_clk_add_provider(node, of_clk_src_simple_get, clk); 107 + clk_register_clkdev(clk, clk_name, NULL); 108 + 109 + return; 110 + 111 + iounmap_reg: 112 + iounmap(reg); 113 + free_gate: 114 + kfree(gate); 115 + free_mux: 116 + kfree(mux); 117 + } 118 + CLK_OF_DECLARE(sun7i_a20_gmac, "allwinner,sun7i-a20-gmac-clk", 119 + sun7i_a20_gmac_clk_setup);
+99
drivers/clk/sunxi/clk-sun6i-apb0-gates.c
··· 1 + /* 2 + * Copyright (C) 2014 Free Electrons 3 + * 4 + * License Terms: GNU General Public License v2 5 + * Author: Boris BREZILLON <boris.brezillon@free-electrons.com> 6 + * 7 + * Allwinner A31 APB0 clock gates driver 8 + * 9 + */ 10 + 11 + #include <linux/clk-provider.h> 12 + #include <linux/module.h> 13 + #include <linux/of.h> 14 + #include <linux/platform_device.h> 15 + 16 + #define SUN6I_APB0_GATES_MAX_SIZE 32 17 + 18 + static int sun6i_a31_apb0_gates_clk_probe(struct platform_device *pdev) 19 + { 20 + struct device_node *np = pdev->dev.of_node; 21 + struct clk_onecell_data *clk_data; 22 + const char *clk_parent; 23 + const char *clk_name; 24 + struct resource *r; 25 + void __iomem *reg; 26 + int gate_id; 27 + int ngates; 28 + int i; 29 + 30 + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 31 + reg = devm_ioremap_resource(&pdev->dev, r); 32 + if (!reg) 33 + return PTR_ERR(reg); 34 + 35 + clk_parent = of_clk_get_parent_name(np, 0); 36 + if (!clk_parent) 37 + return -EINVAL; 38 + 39 + ngates = of_property_count_strings(np, "clock-output-names"); 40 + if (ngates < 0) 41 + return ngates; 42 + 43 + if (!ngates || ngates > SUN6I_APB0_GATES_MAX_SIZE) 44 + return -EINVAL; 45 + 46 + clk_data = devm_kzalloc(&pdev->dev, sizeof(struct clk_onecell_data), 47 + GFP_KERNEL); 48 + if (!clk_data) 49 + return -ENOMEM; 50 + 51 + clk_data->clks = devm_kzalloc(&pdev->dev, 52 + SUN6I_APB0_GATES_MAX_SIZE * 53 + sizeof(struct clk *), 54 + GFP_KERNEL); 55 + if (!clk_data->clks) 56 + return -ENOMEM; 57 + 58 + for (i = 0; i < ngates; i++) { 59 + of_property_read_string_index(np, "clock-output-names", 60 + i, &clk_name); 61 + 62 + gate_id = i; 63 + of_property_read_u32_index(np, "clock-indices", i, &gate_id); 64 + 65 + WARN_ON(gate_id >= SUN6I_APB0_GATES_MAX_SIZE); 66 + if (gate_id >= SUN6I_APB0_GATES_MAX_SIZE) 67 + continue; 68 + 69 + clk_data->clks[gate_id] = clk_register_gate(&pdev->dev, 70 + clk_name, 71 + clk_parent, 0, 72 + reg, gate_id, 73 + 0, NULL); 74 + WARN_ON(IS_ERR(clk_data->clks[gate_id])); 75 + } 76 + 77 + clk_data->clk_num = ngates; 78 + 79 + return of_clk_add_provider(np, of_clk_src_onecell_get, clk_data); 80 + } 81 + 82 + const struct of_device_id sun6i_a31_apb0_gates_clk_dt_ids[] = { 83 + { .compatible = "allwinner,sun6i-a31-apb0-gates-clk" }, 84 + { /* sentinel */ } 85 + }; 86 + 87 + static struct platform_driver sun6i_a31_apb0_gates_clk_driver = { 88 + .driver = { 89 + .name = "sun6i-a31-apb0-gates-clk", 90 + .owner = THIS_MODULE, 91 + .of_match_table = sun6i_a31_apb0_gates_clk_dt_ids, 92 + }, 93 + .probe = sun6i_a31_apb0_gates_clk_probe, 94 + }; 95 + module_platform_driver(sun6i_a31_apb0_gates_clk_driver); 96 + 97 + MODULE_AUTHOR("Boris BREZILLON <boris.brezillon@free-electrons.com>"); 98 + MODULE_DESCRIPTION("Allwinner A31 APB0 gate clocks driver"); 99 + MODULE_LICENSE("GPL v2");
+77
drivers/clk/sunxi/clk-sun6i-apb0.c
··· 1 + /* 2 + * Copyright (C) 2014 Free Electrons 3 + * 4 + * License Terms: GNU General Public License v2 5 + * Author: Boris BREZILLON <boris.brezillon@free-electrons.com> 6 + * 7 + * Allwinner A31 APB0 clock driver 8 + * 9 + */ 10 + 11 + #include <linux/clk-provider.h> 12 + #include <linux/module.h> 13 + #include <linux/of.h> 14 + #include <linux/platform_device.h> 15 + 16 + /* 17 + * The APB0 clk has a configurable divisor. 18 + * 19 + * We must use a clk_div_table and not a regular power of 2 20 + * divisor here, because the first 2 values divide the clock 21 + * by 2. 22 + */ 23 + static const struct clk_div_table sun6i_a31_apb0_divs[] = { 24 + { .val = 0, .div = 2, }, 25 + { .val = 1, .div = 2, }, 26 + { .val = 2, .div = 4, }, 27 + { .val = 3, .div = 8, }, 28 + { /* sentinel */ }, 29 + }; 30 + 31 + static int sun6i_a31_apb0_clk_probe(struct platform_device *pdev) 32 + { 33 + struct device_node *np = pdev->dev.of_node; 34 + const char *clk_name = np->name; 35 + const char *clk_parent; 36 + struct resource *r; 37 + void __iomem *reg; 38 + struct clk *clk; 39 + 40 + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 41 + reg = devm_ioremap_resource(&pdev->dev, r); 42 + if (IS_ERR(reg)) 43 + return PTR_ERR(reg); 44 + 45 + clk_parent = of_clk_get_parent_name(np, 0); 46 + if (!clk_parent) 47 + return -EINVAL; 48 + 49 + of_property_read_string(np, "clock-output-names", &clk_name); 50 + 51 + clk = clk_register_divider_table(&pdev->dev, clk_name, clk_parent, 52 + 0, reg, 0, 2, 0, sun6i_a31_apb0_divs, 53 + NULL); 54 + if (IS_ERR(clk)) 55 + return PTR_ERR(clk); 56 + 57 + return of_clk_add_provider(np, of_clk_src_simple_get, clk); 58 + } 59 + 60 + const struct of_device_id sun6i_a31_apb0_clk_dt_ids[] = { 61 + { .compatible = "allwinner,sun6i-a31-apb0-clk" }, 62 + { /* sentinel */ } 63 + }; 64 + 65 + static struct platform_driver sun6i_a31_apb0_clk_driver = { 66 + .driver = { 67 + .name = "sun6i-a31-apb0-clk", 68 + .owner = THIS_MODULE, 69 + .of_match_table = sun6i_a31_apb0_clk_dt_ids, 70 + }, 71 + .probe = sun6i_a31_apb0_clk_probe, 72 + }; 73 + module_platform_driver(sun6i_a31_apb0_clk_driver); 74 + 75 + MODULE_AUTHOR("Boris BREZILLON <boris.brezillon@free-electrons.com>"); 76 + MODULE_DESCRIPTION("Allwinner A31 APB0 clock Driver"); 77 + MODULE_LICENSE("GPL v2");
+233
drivers/clk/sunxi/clk-sun6i-ar100.c
··· 1 + /* 2 + * Copyright (C) 2014 Free Electrons 3 + * 4 + * License Terms: GNU General Public License v2 5 + * Author: Boris BREZILLON <boris.brezillon@free-electrons.com> 6 + * 7 + * Allwinner A31 AR100 clock driver 8 + * 9 + */ 10 + 11 + #include <linux/clk-provider.h> 12 + #include <linux/module.h> 13 + #include <linux/of.h> 14 + #include <linux/platform_device.h> 15 + 16 + #define SUN6I_AR100_MAX_PARENTS 4 17 + #define SUN6I_AR100_SHIFT_MASK 0x3 18 + #define SUN6I_AR100_SHIFT_MAX SUN6I_AR100_SHIFT_MASK 19 + #define SUN6I_AR100_SHIFT_SHIFT 4 20 + #define SUN6I_AR100_DIV_MASK 0x1f 21 + #define SUN6I_AR100_DIV_MAX (SUN6I_AR100_DIV_MASK + 1) 22 + #define SUN6I_AR100_DIV_SHIFT 8 23 + #define SUN6I_AR100_MUX_MASK 0x3 24 + #define SUN6I_AR100_MUX_SHIFT 16 25 + 26 + struct ar100_clk { 27 + struct clk_hw hw; 28 + void __iomem *reg; 29 + }; 30 + 31 + static inline struct ar100_clk *to_ar100_clk(struct clk_hw *hw) 32 + { 33 + return container_of(hw, struct ar100_clk, hw); 34 + } 35 + 36 + static unsigned long ar100_recalc_rate(struct clk_hw *hw, 37 + unsigned long parent_rate) 38 + { 39 + struct ar100_clk *clk = to_ar100_clk(hw); 40 + u32 val = readl(clk->reg); 41 + int shift = (val >> SUN6I_AR100_SHIFT_SHIFT) & SUN6I_AR100_SHIFT_MASK; 42 + int div = (val >> SUN6I_AR100_DIV_SHIFT) & SUN6I_AR100_DIV_MASK; 43 + 44 + return (parent_rate >> shift) / (div + 1); 45 + } 46 + 47 + static long ar100_determine_rate(struct clk_hw *hw, unsigned long rate, 48 + unsigned long *best_parent_rate, 49 + struct clk **best_parent_clk) 50 + { 51 + int nparents = __clk_get_num_parents(hw->clk); 52 + long best_rate = -EINVAL; 53 + int i; 54 + 55 + *best_parent_clk = NULL; 56 + 57 + for (i = 0; i < nparents; i++) { 58 + unsigned long parent_rate; 59 + unsigned long tmp_rate; 60 + struct clk *parent; 61 + unsigned long div; 62 + int shift; 63 + 64 + parent = clk_get_parent_by_index(hw->clk, i); 65 + parent_rate = __clk_get_rate(parent); 66 + div = DIV_ROUND_UP(parent_rate, rate); 67 + 68 + /* 69 + * The AR100 clk contains 2 divisors: 70 + * - one power of 2 divisor 71 + * - one regular divisor 72 + * 73 + * First check if we can safely shift (or divide by a power 74 + * of 2) without losing precision on the requested rate. 75 + */ 76 + shift = ffs(div) - 1; 77 + if (shift > SUN6I_AR100_SHIFT_MAX) 78 + shift = SUN6I_AR100_SHIFT_MAX; 79 + 80 + div >>= shift; 81 + 82 + /* 83 + * Then if the divisor is still bigger than what the HW 84 + * actually supports, use a bigger shift (or power of 2 85 + * divider) value and accept to lose some precision. 86 + */ 87 + while (div > SUN6I_AR100_DIV_MAX) { 88 + shift++; 89 + div >>= 1; 90 + if (shift > SUN6I_AR100_SHIFT_MAX) 91 + break; 92 + } 93 + 94 + /* 95 + * If the shift value (or power of 2 divider) is bigger 96 + * than what the HW actually support, skip this parent. 97 + */ 98 + if (shift > SUN6I_AR100_SHIFT_MAX) 99 + continue; 100 + 101 + tmp_rate = (parent_rate >> shift) / div; 102 + if (!*best_parent_clk || tmp_rate > best_rate) { 103 + *best_parent_clk = parent; 104 + *best_parent_rate = parent_rate; 105 + best_rate = tmp_rate; 106 + } 107 + } 108 + 109 + return best_rate; 110 + } 111 + 112 + static int ar100_set_parent(struct clk_hw *hw, u8 index) 113 + { 114 + struct ar100_clk *clk = to_ar100_clk(hw); 115 + u32 val = readl(clk->reg); 116 + 117 + if (index >= SUN6I_AR100_MAX_PARENTS) 118 + return -EINVAL; 119 + 120 + val &= ~(SUN6I_AR100_MUX_MASK << SUN6I_AR100_MUX_SHIFT); 121 + val |= (index << SUN6I_AR100_MUX_SHIFT); 122 + writel(val, clk->reg); 123 + 124 + return 0; 125 + } 126 + 127 + static u8 ar100_get_parent(struct clk_hw *hw) 128 + { 129 + struct ar100_clk *clk = to_ar100_clk(hw); 130 + return (readl(clk->reg) >> SUN6I_AR100_MUX_SHIFT) & 131 + SUN6I_AR100_MUX_MASK; 132 + } 133 + 134 + static int ar100_set_rate(struct clk_hw *hw, unsigned long rate, 135 + unsigned long parent_rate) 136 + { 137 + unsigned long div = parent_rate / rate; 138 + struct ar100_clk *clk = to_ar100_clk(hw); 139 + u32 val = readl(clk->reg); 140 + int shift; 141 + 142 + if (parent_rate % rate) 143 + return -EINVAL; 144 + 145 + shift = ffs(div) - 1; 146 + if (shift > SUN6I_AR100_SHIFT_MAX) 147 + shift = SUN6I_AR100_SHIFT_MAX; 148 + 149 + div >>= shift; 150 + 151 + if (div > SUN6I_AR100_DIV_MAX) 152 + return -EINVAL; 153 + 154 + val &= ~((SUN6I_AR100_SHIFT_MASK << SUN6I_AR100_SHIFT_SHIFT) | 155 + (SUN6I_AR100_DIV_MASK << SUN6I_AR100_DIV_SHIFT)); 156 + val |= (shift << SUN6I_AR100_SHIFT_SHIFT) | 157 + (div << SUN6I_AR100_DIV_SHIFT); 158 + writel(val, clk->reg); 159 + 160 + return 0; 161 + } 162 + 163 + struct clk_ops ar100_ops = { 164 + .recalc_rate = ar100_recalc_rate, 165 + .determine_rate = ar100_determine_rate, 166 + .set_parent = ar100_set_parent, 167 + .get_parent = ar100_get_parent, 168 + .set_rate = ar100_set_rate, 169 + }; 170 + 171 + static int sun6i_a31_ar100_clk_probe(struct platform_device *pdev) 172 + { 173 + const char *parents[SUN6I_AR100_MAX_PARENTS]; 174 + struct device_node *np = pdev->dev.of_node; 175 + const char *clk_name = np->name; 176 + struct clk_init_data init; 177 + struct ar100_clk *ar100; 178 + struct resource *r; 179 + struct clk *clk; 180 + int nparents; 181 + int i; 182 + 183 + ar100 = devm_kzalloc(&pdev->dev, sizeof(*ar100), GFP_KERNEL); 184 + if (!ar100) 185 + return -ENOMEM; 186 + 187 + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 188 + ar100->reg = devm_ioremap_resource(&pdev->dev, r); 189 + if (IS_ERR(ar100->reg)) 190 + return PTR_ERR(ar100->reg); 191 + 192 + nparents = of_clk_get_parent_count(np); 193 + if (nparents > SUN6I_AR100_MAX_PARENTS) 194 + nparents = SUN6I_AR100_MAX_PARENTS; 195 + 196 + for (i = 0; i < nparents; i++) 197 + parents[i] = of_clk_get_parent_name(np, i); 198 + 199 + of_property_read_string(np, "clock-output-names", &clk_name); 200 + 201 + init.name = clk_name; 202 + init.ops = &ar100_ops; 203 + init.parent_names = parents; 204 + init.num_parents = nparents; 205 + init.flags = 0; 206 + 207 + ar100->hw.init = &init; 208 + 209 + clk = clk_register(&pdev->dev, &ar100->hw); 210 + if (IS_ERR(clk)) 211 + return PTR_ERR(clk); 212 + 213 + return of_clk_add_provider(np, of_clk_src_simple_get, clk); 214 + } 215 + 216 + const struct of_device_id sun6i_a31_ar100_clk_dt_ids[] = { 217 + { .compatible = "allwinner,sun6i-a31-ar100-clk" }, 218 + { /* sentinel */ } 219 + }; 220 + 221 + static struct platform_driver sun6i_a31_ar100_clk_driver = { 222 + .driver = { 223 + .name = "sun6i-a31-ar100-clk", 224 + .owner = THIS_MODULE, 225 + .of_match_table = sun6i_a31_ar100_clk_dt_ids, 226 + }, 227 + .probe = sun6i_a31_ar100_clk_probe, 228 + }; 229 + module_platform_driver(sun6i_a31_ar100_clk_driver); 230 + 231 + MODULE_AUTHOR("Boris BREZILLON <boris.brezillon@free-electrons.com>"); 232 + MODULE_DESCRIPTION("Allwinner A31 AR100 clock Driver"); 233 + MODULE_LICENSE("GPL v2");
+52 -187
drivers/clk/sunxi/clk-sunxi.c
··· 28 28 #define SUNXI_MAX_PARENTS 5 29 29 30 30 /** 31 - * sun4i_osc_clk_setup() - Setup function for gatable oscillator 32 - */ 33 - 34 - #define SUNXI_OSC24M_GATE 0 35 - 36 - static void __init sun4i_osc_clk_setup(struct device_node *node) 37 - { 38 - struct clk *clk; 39 - struct clk_fixed_rate *fixed; 40 - struct clk_gate *gate; 41 - const char *clk_name = node->name; 42 - u32 rate; 43 - 44 - if (of_property_read_u32(node, "clock-frequency", &rate)) 45 - return; 46 - 47 - /* allocate fixed-rate and gate clock structs */ 48 - fixed = kzalloc(sizeof(struct clk_fixed_rate), GFP_KERNEL); 49 - if (!fixed) 50 - return; 51 - gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL); 52 - if (!gate) 53 - goto err_free_fixed; 54 - 55 - of_property_read_string(node, "clock-output-names", &clk_name); 56 - 57 - /* set up gate and fixed rate properties */ 58 - gate->reg = of_iomap(node, 0); 59 - gate->bit_idx = SUNXI_OSC24M_GATE; 60 - gate->lock = &clk_lock; 61 - fixed->fixed_rate = rate; 62 - 63 - clk = clk_register_composite(NULL, clk_name, 64 - NULL, 0, 65 - NULL, NULL, 66 - &fixed->hw, &clk_fixed_rate_ops, 67 - &gate->hw, &clk_gate_ops, 68 - CLK_IS_ROOT); 69 - 70 - if (IS_ERR(clk)) 71 - goto err_free_gate; 72 - 73 - of_clk_add_provider(node, of_clk_src_simple_get, clk); 74 - clk_register_clkdev(clk, clk_name, NULL); 75 - 76 - return; 77 - 78 - err_free_gate: 79 - kfree(gate); 80 - err_free_fixed: 81 - kfree(fixed); 82 - } 83 - CLK_OF_DECLARE(sun4i_osc, "allwinner,sun4i-a10-osc-clk", sun4i_osc_clk_setup); 84 - 85 - 86 - 87 - /** 88 31 * sun4i_get_pll1_factors() - calculates n, k, m, p factors for PLL1 89 32 * PLL1 rate is calculated as follows 90 33 * rate = (parent_rate * n * (k + 1) >> p) / (m + 1); ··· 350 407 *m = calcm - 1; 351 408 *p = calcp; 352 409 } 353 - 354 - 355 - 356 - /** 357 - * sun7i_a20_gmac_clk_setup - Setup function for A20/A31 GMAC clock module 358 - * 359 - * This clock looks something like this 360 - * ________________________ 361 - * MII TX clock from PHY >-----|___________ _________|----> to GMAC core 362 - * GMAC Int. RGMII TX clk >----|___________\__/__gate---|----> to PHY 363 - * Ext. 125MHz RGMII TX clk >--|__divider__/ | 364 - * |________________________| 365 - * 366 - * The external 125 MHz reference is optional, i.e. GMAC can use its 367 - * internal TX clock just fine. The A31 GMAC clock module does not have 368 - * the divider controls for the external reference. 369 - * 370 - * To keep it simple, let the GMAC use either the MII TX clock for MII mode, 371 - * and its internal TX clock for GMII and RGMII modes. The GMAC driver should 372 - * select the appropriate source and gate/ungate the output to the PHY. 373 - * 374 - * Only the GMAC should use this clock. Altering the clock so that it doesn't 375 - * match the GMAC's operation parameters will result in the GMAC not being 376 - * able to send traffic out. The GMAC driver should set the clock rate and 377 - * enable/disable this clock to configure the required state. The clock 378 - * driver then responds by auto-reparenting the clock. 379 - */ 380 - 381 - #define SUN7I_A20_GMAC_GPIT 2 382 - #define SUN7I_A20_GMAC_MASK 0x3 383 - #define SUN7I_A20_GMAC_PARENTS 2 384 - 385 - static void __init sun7i_a20_gmac_clk_setup(struct device_node *node) 386 - { 387 - struct clk *clk; 388 - struct clk_mux *mux; 389 - struct clk_gate *gate; 390 - const char *clk_name = node->name; 391 - const char *parents[SUN7I_A20_GMAC_PARENTS]; 392 - void *reg; 393 - 394 - if (of_property_read_string(node, "clock-output-names", &clk_name)) 395 - return; 396 - 397 - /* allocate mux and gate clock structs */ 398 - mux = kzalloc(sizeof(struct clk_mux), GFP_KERNEL); 399 - if (!mux) 400 - return; 401 - 402 - gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL); 403 - if (!gate) 404 - goto free_mux; 405 - 406 - /* gmac clock requires exactly 2 parents */ 407 - parents[0] = of_clk_get_parent_name(node, 0); 408 - parents[1] = of_clk_get_parent_name(node, 1); 409 - if (!parents[0] || !parents[1]) 410 - goto free_gate; 411 - 412 - reg = of_iomap(node, 0); 413 - if (!reg) 414 - goto free_gate; 415 - 416 - /* set up gate and fixed rate properties */ 417 - gate->reg = reg; 418 - gate->bit_idx = SUN7I_A20_GMAC_GPIT; 419 - gate->lock = &clk_lock; 420 - mux->reg = reg; 421 - mux->mask = SUN7I_A20_GMAC_MASK; 422 - mux->flags = CLK_MUX_INDEX_BIT; 423 - mux->lock = &clk_lock; 424 - 425 - clk = clk_register_composite(NULL, clk_name, 426 - parents, SUN7I_A20_GMAC_PARENTS, 427 - &mux->hw, &clk_mux_ops, 428 - NULL, NULL, 429 - &gate->hw, &clk_gate_ops, 430 - 0); 431 - 432 - if (IS_ERR(clk)) 433 - goto iounmap_reg; 434 - 435 - of_clk_add_provider(node, of_clk_src_simple_get, clk); 436 - clk_register_clkdev(clk, clk_name, NULL); 437 - 438 - return; 439 - 440 - iounmap_reg: 441 - iounmap(reg); 442 - free_gate: 443 - kfree(gate); 444 - free_mux: 445 - kfree(mux); 446 - } 447 - CLK_OF_DECLARE(sun7i_a20_gmac, "allwinner,sun7i-a20-gmac-clk", 448 - sun7i_a20_gmac_clk_setup); 449 - 450 - 451 410 452 411 /** 453 412 * clk_sunxi_mmc_phase_control() - configures MMC clock phase control ··· 854 1009 .reset_mask = 0x03, 855 1010 }; 856 1011 1012 + static const struct gates_data sun6i_a31_usb_gates_data __initconst = { 1013 + .mask = { BIT(18) | BIT(17) | BIT(16) | BIT(10) | BIT(9) | BIT(8) }, 1014 + .reset_mask = BIT(2) | BIT(1) | BIT(0), 1015 + }; 1016 + 857 1017 static void __init sunxi_gates_clk_setup(struct device_node *node, 858 1018 struct gates_data *data) 859 1019 { ··· 1154 1304 {.compatible = "allwinner,sun6i-a31-apb2-gates-clk", .data = &sun6i_a31_apb2_gates_data,}, 1155 1305 {.compatible = "allwinner,sun4i-a10-usb-clk", .data = &sun4i_a10_usb_gates_data,}, 1156 1306 {.compatible = "allwinner,sun5i-a13-usb-clk", .data = &sun5i_a13_usb_gates_data,}, 1307 + {.compatible = "allwinner,sun6i-a31-usb-clk", .data = &sun6i_a31_usb_gates_data,}, 1157 1308 {} 1158 1309 }; 1159 1310 ··· 1172 1321 } 1173 1322 } 1174 1323 1175 - /** 1176 - * System clock protection 1177 - * 1178 - * By enabling these critical clocks, we prevent their accidental gating 1179 - * by the framework 1180 - */ 1181 - static void __init sunxi_clock_protect(void) 1324 + static void __init sunxi_init_clocks(const char *clocks[], int nclocks) 1182 1325 { 1183 - struct clk *clk; 1326 + unsigned int i; 1184 1327 1185 - /* memory bus clock - sun5i+ */ 1186 - clk = clk_get(NULL, "mbus"); 1187 - if (!IS_ERR(clk)) { 1188 - clk_prepare_enable(clk); 1189 - clk_put(clk); 1190 - } 1191 - 1192 - /* DDR clock - sun4i+ */ 1193 - clk = clk_get(NULL, "pll5_ddr"); 1194 - if (!IS_ERR(clk)) { 1195 - clk_prepare_enable(clk); 1196 - clk_put(clk); 1197 - } 1198 - } 1199 - 1200 - static void __init sunxi_init_clocks(struct device_node *np) 1201 - { 1202 1328 /* Register factor clocks */ 1203 1329 of_sunxi_table_clock_setup(clk_factors_match, sunxi_factors_clk_setup); 1204 1330 ··· 1191 1363 /* Register gate clocks */ 1192 1364 of_sunxi_table_clock_setup(clk_gates_match, sunxi_gates_clk_setup); 1193 1365 1194 - /* Enable core system clocks */ 1195 - sunxi_clock_protect(); 1366 + /* Protect the clocks that needs to stay on */ 1367 + for (i = 0; i < nclocks; i++) { 1368 + struct clk *clk = clk_get(NULL, clocks[i]); 1369 + 1370 + if (!IS_ERR(clk)) 1371 + clk_prepare_enable(clk); 1372 + } 1196 1373 } 1197 - CLK_OF_DECLARE(sun4i_a10_clk_init, "allwinner,sun4i-a10", sunxi_init_clocks); 1198 - CLK_OF_DECLARE(sun5i_a10s_clk_init, "allwinner,sun5i-a10s", sunxi_init_clocks); 1199 - CLK_OF_DECLARE(sun5i_a13_clk_init, "allwinner,sun5i-a13", sunxi_init_clocks); 1200 - CLK_OF_DECLARE(sun6i_a31_clk_init, "allwinner,sun6i-a31", sunxi_init_clocks); 1201 - CLK_OF_DECLARE(sun7i_a20_clk_init, "allwinner,sun7i-a20", sunxi_init_clocks); 1374 + 1375 + static const char *sun4i_a10_critical_clocks[] __initdata = { 1376 + "pll5_ddr", 1377 + }; 1378 + 1379 + static void __init sun4i_a10_init_clocks(struct device_node *node) 1380 + { 1381 + sunxi_init_clocks(sun4i_a10_critical_clocks, 1382 + ARRAY_SIZE(sun4i_a10_critical_clocks)); 1383 + } 1384 + CLK_OF_DECLARE(sun4i_a10_clk_init, "allwinner,sun4i-a10", sun4i_a10_init_clocks); 1385 + 1386 + static const char *sun5i_critical_clocks[] __initdata = { 1387 + "mbus", 1388 + "pll5_ddr", 1389 + }; 1390 + 1391 + static void __init sun5i_init_clocks(struct device_node *node) 1392 + { 1393 + sunxi_init_clocks(sun5i_critical_clocks, 1394 + ARRAY_SIZE(sun5i_critical_clocks)); 1395 + } 1396 + CLK_OF_DECLARE(sun5i_a10s_clk_init, "allwinner,sun5i-a10s", sun5i_init_clocks); 1397 + CLK_OF_DECLARE(sun5i_a13_clk_init, "allwinner,sun5i-a13", sun5i_init_clocks); 1398 + CLK_OF_DECLARE(sun7i_a20_clk_init, "allwinner,sun7i-a20", sun5i_init_clocks); 1399 + 1400 + static const char *sun6i_critical_clocks[] __initdata = { 1401 + "cpu", 1402 + "ahb1_sdram", 1403 + }; 1404 + 1405 + static void __init sun6i_init_clocks(struct device_node *node) 1406 + { 1407 + sunxi_init_clocks(sun6i_critical_clocks, 1408 + ARRAY_SIZE(sun6i_critical_clocks)); 1409 + } 1410 + CLK_OF_DECLARE(sun6i_a31_clk_init, "allwinner,sun6i-a31", sun6i_init_clocks);
+3 -1
drivers/clk/ti/Makefile
··· 3 3 clk-common = dpll.o composite.o divider.o gate.o \ 4 4 fixed-factor.o mux.o apll.o 5 5 obj-$(CONFIG_SOC_AM33XX) += $(clk-common) clk-33xx.o 6 + obj-$(CONFIG_ARCH_OMAP2) += $(clk-common) interface.o clk-2xxx.o 6 7 obj-$(CONFIG_ARCH_OMAP3) += $(clk-common) interface.o clk-3xxx.o 7 8 obj-$(CONFIG_ARCH_OMAP4) += $(clk-common) clk-44xx.o 8 9 obj-$(CONFIG_SOC_OMAP5) += $(clk-common) clk-54xx.o 9 - obj-$(CONFIG_SOC_DRA7XX) += $(clk-common) clk-7xx.o 10 + obj-$(CONFIG_SOC_DRA7XX) += $(clk-common) clk-7xx.o \ 11 + clk-dra7-atl.o 10 12 obj-$(CONFIG_SOC_AM43XX) += $(clk-common) clk-43xx.o 11 13 endif
+181
drivers/clk/ti/apll.c
··· 221 221 kfree(init); 222 222 } 223 223 CLK_OF_DECLARE(dra7_apll_clock, "ti,dra7-apll-clock", of_dra7_apll_setup); 224 + 225 + #define OMAP2_EN_APLL_LOCKED 0x3 226 + #define OMAP2_EN_APLL_STOPPED 0x0 227 + 228 + static int omap2_apll_is_enabled(struct clk_hw *hw) 229 + { 230 + struct clk_hw_omap *clk = to_clk_hw_omap(hw); 231 + struct dpll_data *ad = clk->dpll_data; 232 + u32 v; 233 + 234 + v = ti_clk_ll_ops->clk_readl(ad->control_reg); 235 + v &= ad->enable_mask; 236 + 237 + v >>= __ffs(ad->enable_mask); 238 + 239 + return v == OMAP2_EN_APLL_LOCKED ? 1 : 0; 240 + } 241 + 242 + static unsigned long omap2_apll_recalc(struct clk_hw *hw, 243 + unsigned long parent_rate) 244 + { 245 + struct clk_hw_omap *clk = to_clk_hw_omap(hw); 246 + 247 + if (omap2_apll_is_enabled(hw)) 248 + return clk->fixed_rate; 249 + 250 + return 0; 251 + } 252 + 253 + static int omap2_apll_enable(struct clk_hw *hw) 254 + { 255 + struct clk_hw_omap *clk = to_clk_hw_omap(hw); 256 + struct dpll_data *ad = clk->dpll_data; 257 + u32 v; 258 + int i = 0; 259 + 260 + v = ti_clk_ll_ops->clk_readl(ad->control_reg); 261 + v &= ~ad->enable_mask; 262 + v |= OMAP2_EN_APLL_LOCKED << __ffs(ad->enable_mask); 263 + ti_clk_ll_ops->clk_writel(v, ad->control_reg); 264 + 265 + while (1) { 266 + v = ti_clk_ll_ops->clk_readl(ad->idlest_reg); 267 + if (v & ad->idlest_mask) 268 + break; 269 + if (i > MAX_APLL_WAIT_TRIES) 270 + break; 271 + i++; 272 + udelay(1); 273 + } 274 + 275 + if (i == MAX_APLL_WAIT_TRIES) { 276 + pr_warn("%s failed to transition to locked\n", 277 + __clk_get_name(clk->hw.clk)); 278 + return -EBUSY; 279 + } 280 + 281 + return 0; 282 + } 283 + 284 + static void omap2_apll_disable(struct clk_hw *hw) 285 + { 286 + struct clk_hw_omap *clk = to_clk_hw_omap(hw); 287 + struct dpll_data *ad = clk->dpll_data; 288 + u32 v; 289 + 290 + v = ti_clk_ll_ops->clk_readl(ad->control_reg); 291 + v &= ~ad->enable_mask; 292 + v |= OMAP2_EN_APLL_STOPPED << __ffs(ad->enable_mask); 293 + ti_clk_ll_ops->clk_writel(v, ad->control_reg); 294 + } 295 + 296 + static struct clk_ops omap2_apll_ops = { 297 + .enable = &omap2_apll_enable, 298 + .disable = &omap2_apll_disable, 299 + .is_enabled = &omap2_apll_is_enabled, 300 + .recalc_rate = &omap2_apll_recalc, 301 + }; 302 + 303 + static void omap2_apll_set_autoidle(struct clk_hw_omap *clk, u32 val) 304 + { 305 + struct dpll_data *ad = clk->dpll_data; 306 + u32 v; 307 + 308 + v = ti_clk_ll_ops->clk_readl(ad->autoidle_reg); 309 + v &= ~ad->autoidle_mask; 310 + v |= val << __ffs(ad->autoidle_mask); 311 + ti_clk_ll_ops->clk_writel(v, ad->control_reg); 312 + } 313 + 314 + #define OMAP2_APLL_AUTOIDLE_LOW_POWER_STOP 0x3 315 + #define OMAP2_APLL_AUTOIDLE_DISABLE 0x0 316 + 317 + static void omap2_apll_allow_idle(struct clk_hw_omap *clk) 318 + { 319 + omap2_apll_set_autoidle(clk, OMAP2_APLL_AUTOIDLE_LOW_POWER_STOP); 320 + } 321 + 322 + static void omap2_apll_deny_idle(struct clk_hw_omap *clk) 323 + { 324 + omap2_apll_set_autoidle(clk, OMAP2_APLL_AUTOIDLE_DISABLE); 325 + } 326 + 327 + static struct clk_hw_omap_ops omap2_apll_hwops = { 328 + .allow_idle = &omap2_apll_allow_idle, 329 + .deny_idle = &omap2_apll_deny_idle, 330 + }; 331 + 332 + static void __init of_omap2_apll_setup(struct device_node *node) 333 + { 334 + struct dpll_data *ad = NULL; 335 + struct clk_hw_omap *clk_hw = NULL; 336 + struct clk_init_data *init = NULL; 337 + struct clk *clk; 338 + const char *parent_name; 339 + u32 val; 340 + 341 + ad = kzalloc(sizeof(*clk_hw), GFP_KERNEL); 342 + clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL); 343 + init = kzalloc(sizeof(*init), GFP_KERNEL); 344 + 345 + if (!ad || !clk_hw || !init) 346 + goto cleanup; 347 + 348 + clk_hw->dpll_data = ad; 349 + clk_hw->hw.init = init; 350 + init->ops = &omap2_apll_ops; 351 + init->name = node->name; 352 + clk_hw->ops = &omap2_apll_hwops; 353 + 354 + init->num_parents = of_clk_get_parent_count(node); 355 + if (init->num_parents != 1) { 356 + pr_err("%s must have one parent\n", node->name); 357 + goto cleanup; 358 + } 359 + 360 + parent_name = of_clk_get_parent_name(node, 0); 361 + init->parent_names = &parent_name; 362 + 363 + if (of_property_read_u32(node, "ti,clock-frequency", &val)) { 364 + pr_err("%s missing clock-frequency\n", node->name); 365 + goto cleanup; 366 + } 367 + clk_hw->fixed_rate = val; 368 + 369 + if (of_property_read_u32(node, "ti,bit-shift", &val)) { 370 + pr_err("%s missing bit-shift\n", node->name); 371 + goto cleanup; 372 + } 373 + 374 + clk_hw->enable_bit = val; 375 + ad->enable_mask = 0x3 << val; 376 + ad->autoidle_mask = 0x3 << val; 377 + 378 + if (of_property_read_u32(node, "ti,idlest-shift", &val)) { 379 + pr_err("%s missing idlest-shift\n", node->name); 380 + goto cleanup; 381 + } 382 + 383 + ad->idlest_mask = 1 << val; 384 + 385 + ad->control_reg = ti_clk_get_reg_addr(node, 0); 386 + ad->autoidle_reg = ti_clk_get_reg_addr(node, 1); 387 + ad->idlest_reg = ti_clk_get_reg_addr(node, 2); 388 + 389 + if (!ad->control_reg || !ad->autoidle_reg || !ad->idlest_reg) 390 + goto cleanup; 391 + 392 + clk = clk_register(NULL, &clk_hw->hw); 393 + if (!IS_ERR(clk)) { 394 + of_clk_add_provider(node, of_clk_src_simple_get, clk); 395 + kfree(init); 396 + return; 397 + } 398 + cleanup: 399 + kfree(ad); 400 + kfree(clk_hw); 401 + kfree(init); 402 + } 403 + CLK_OF_DECLARE(omap2_apll_clock, "ti,omap2-apll-clock", 404 + of_omap2_apll_setup);
+256
drivers/clk/ti/clk-2xxx.c
··· 1 + /* 2 + * OMAP2 Clock init 3 + * 4 + * Copyright (C) 2013 Texas Instruments, Inc 5 + * Tero Kristo (t-kristo@ti.com) 6 + * 7 + * This program is free software; you can redistribute it and/or 8 + * modify it under the terms of the GNU General Public License as 9 + * published by the Free Software Foundation version 2. 10 + * 11 + * This program is distributed "as is" WITHOUT ANY WARRANTY of any 12 + * kind, whether express or implied; without even the implied warranty 13 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + */ 16 + 17 + #include <linux/kernel.h> 18 + #include <linux/list.h> 19 + #include <linux/clk-provider.h> 20 + #include <linux/clk/ti.h> 21 + 22 + static struct ti_dt_clk omap2xxx_clks[] = { 23 + DT_CLK(NULL, "func_32k_ck", "func_32k_ck"), 24 + DT_CLK(NULL, "secure_32k_ck", "secure_32k_ck"), 25 + DT_CLK(NULL, "virt_12m_ck", "virt_12m_ck"), 26 + DT_CLK(NULL, "virt_13m_ck", "virt_13m_ck"), 27 + DT_CLK(NULL, "virt_19200000_ck", "virt_19200000_ck"), 28 + DT_CLK(NULL, "virt_26m_ck", "virt_26m_ck"), 29 + DT_CLK(NULL, "aplls_clkin_ck", "aplls_clkin_ck"), 30 + DT_CLK(NULL, "aplls_clkin_x2_ck", "aplls_clkin_x2_ck"), 31 + DT_CLK(NULL, "osc_ck", "osc_ck"), 32 + DT_CLK(NULL, "sys_ck", "sys_ck"), 33 + DT_CLK(NULL, "alt_ck", "alt_ck"), 34 + DT_CLK(NULL, "mcbsp_clks", "mcbsp_clks"), 35 + DT_CLK(NULL, "dpll_ck", "dpll_ck"), 36 + DT_CLK(NULL, "apll96_ck", "apll96_ck"), 37 + DT_CLK(NULL, "apll54_ck", "apll54_ck"), 38 + DT_CLK(NULL, "func_54m_ck", "func_54m_ck"), 39 + DT_CLK(NULL, "core_ck", "core_ck"), 40 + DT_CLK(NULL, "func_96m_ck", "func_96m_ck"), 41 + DT_CLK(NULL, "func_48m_ck", "func_48m_ck"), 42 + DT_CLK(NULL, "func_12m_ck", "func_12m_ck"), 43 + DT_CLK(NULL, "sys_clkout_src", "sys_clkout_src"), 44 + DT_CLK(NULL, "sys_clkout", "sys_clkout"), 45 + DT_CLK(NULL, "emul_ck", "emul_ck"), 46 + DT_CLK(NULL, "mpu_ck", "mpu_ck"), 47 + DT_CLK(NULL, "dsp_fck", "dsp_fck"), 48 + DT_CLK(NULL, "gfx_3d_fck", "gfx_3d_fck"), 49 + DT_CLK(NULL, "gfx_2d_fck", "gfx_2d_fck"), 50 + DT_CLK(NULL, "gfx_ick", "gfx_ick"), 51 + DT_CLK("omapdss_dss", "ick", "dss_ick"), 52 + DT_CLK(NULL, "dss_ick", "dss_ick"), 53 + DT_CLK(NULL, "dss1_fck", "dss1_fck"), 54 + DT_CLK(NULL, "dss2_fck", "dss2_fck"), 55 + DT_CLK(NULL, "dss_54m_fck", "dss_54m_fck"), 56 + DT_CLK(NULL, "core_l3_ck", "core_l3_ck"), 57 + DT_CLK(NULL, "ssi_fck", "ssi_ssr_sst_fck"), 58 + DT_CLK(NULL, "usb_l4_ick", "usb_l4_ick"), 59 + DT_CLK(NULL, "l4_ck", "l4_ck"), 60 + DT_CLK(NULL, "ssi_l4_ick", "ssi_l4_ick"), 61 + DT_CLK(NULL, "gpt1_ick", "gpt1_ick"), 62 + DT_CLK(NULL, "gpt1_fck", "gpt1_fck"), 63 + DT_CLK(NULL, "gpt2_ick", "gpt2_ick"), 64 + DT_CLK(NULL, "gpt2_fck", "gpt2_fck"), 65 + DT_CLK(NULL, "gpt3_ick", "gpt3_ick"), 66 + DT_CLK(NULL, "gpt3_fck", "gpt3_fck"), 67 + DT_CLK(NULL, "gpt4_ick", "gpt4_ick"), 68 + DT_CLK(NULL, "gpt4_fck", "gpt4_fck"), 69 + DT_CLK(NULL, "gpt5_ick", "gpt5_ick"), 70 + DT_CLK(NULL, "gpt5_fck", "gpt5_fck"), 71 + DT_CLK(NULL, "gpt6_ick", "gpt6_ick"), 72 + DT_CLK(NULL, "gpt6_fck", "gpt6_fck"), 73 + DT_CLK(NULL, "gpt7_ick", "gpt7_ick"), 74 + DT_CLK(NULL, "gpt7_fck", "gpt7_fck"), 75 + DT_CLK(NULL, "gpt8_ick", "gpt8_ick"), 76 + DT_CLK(NULL, "gpt8_fck", "gpt8_fck"), 77 + DT_CLK(NULL, "gpt9_ick", "gpt9_ick"), 78 + DT_CLK(NULL, "gpt9_fck", "gpt9_fck"), 79 + DT_CLK(NULL, "gpt10_ick", "gpt10_ick"), 80 + DT_CLK(NULL, "gpt10_fck", "gpt10_fck"), 81 + DT_CLK(NULL, "gpt11_ick", "gpt11_ick"), 82 + DT_CLK(NULL, "gpt11_fck", "gpt11_fck"), 83 + DT_CLK(NULL, "gpt12_ick", "gpt12_ick"), 84 + DT_CLK(NULL, "gpt12_fck", "gpt12_fck"), 85 + DT_CLK("omap-mcbsp.1", "ick", "mcbsp1_ick"), 86 + DT_CLK(NULL, "mcbsp1_ick", "mcbsp1_ick"), 87 + DT_CLK(NULL, "mcbsp1_fck", "mcbsp1_fck"), 88 + DT_CLK("omap-mcbsp.2", "ick", "mcbsp2_ick"), 89 + DT_CLK(NULL, "mcbsp2_ick", "mcbsp2_ick"), 90 + DT_CLK(NULL, "mcbsp2_fck", "mcbsp2_fck"), 91 + DT_CLK("omap2_mcspi.1", "ick", "mcspi1_ick"), 92 + DT_CLK(NULL, "mcspi1_ick", "mcspi1_ick"), 93 + DT_CLK(NULL, "mcspi1_fck", "mcspi1_fck"), 94 + DT_CLK("omap2_mcspi.2", "ick", "mcspi2_ick"), 95 + DT_CLK(NULL, "mcspi2_ick", "mcspi2_ick"), 96 + DT_CLK(NULL, "mcspi2_fck", "mcspi2_fck"), 97 + DT_CLK(NULL, "uart1_ick", "uart1_ick"), 98 + DT_CLK(NULL, "uart1_fck", "uart1_fck"), 99 + DT_CLK(NULL, "uart2_ick", "uart2_ick"), 100 + DT_CLK(NULL, "uart2_fck", "uart2_fck"), 101 + DT_CLK(NULL, "uart3_ick", "uart3_ick"), 102 + DT_CLK(NULL, "uart3_fck", "uart3_fck"), 103 + DT_CLK(NULL, "gpios_ick", "gpios_ick"), 104 + DT_CLK(NULL, "gpios_fck", "gpios_fck"), 105 + DT_CLK("omap_wdt", "ick", "mpu_wdt_ick"), 106 + DT_CLK(NULL, "mpu_wdt_ick", "mpu_wdt_ick"), 107 + DT_CLK(NULL, "mpu_wdt_fck", "mpu_wdt_fck"), 108 + DT_CLK(NULL, "sync_32k_ick", "sync_32k_ick"), 109 + DT_CLK(NULL, "wdt1_ick", "wdt1_ick"), 110 + DT_CLK(NULL, "omapctrl_ick", "omapctrl_ick"), 111 + DT_CLK("omap24xxcam", "fck", "cam_fck"), 112 + DT_CLK(NULL, "cam_fck", "cam_fck"), 113 + DT_CLK("omap24xxcam", "ick", "cam_ick"), 114 + DT_CLK(NULL, "cam_ick", "cam_ick"), 115 + DT_CLK(NULL, "mailboxes_ick", "mailboxes_ick"), 116 + DT_CLK(NULL, "wdt4_ick", "wdt4_ick"), 117 + DT_CLK(NULL, "wdt4_fck", "wdt4_fck"), 118 + DT_CLK(NULL, "mspro_ick", "mspro_ick"), 119 + DT_CLK(NULL, "mspro_fck", "mspro_fck"), 120 + DT_CLK(NULL, "fac_ick", "fac_ick"), 121 + DT_CLK(NULL, "fac_fck", "fac_fck"), 122 + DT_CLK("omap_hdq.0", "ick", "hdq_ick"), 123 + DT_CLK(NULL, "hdq_ick", "hdq_ick"), 124 + DT_CLK("omap_hdq.0", "fck", "hdq_fck"), 125 + DT_CLK(NULL, "hdq_fck", "hdq_fck"), 126 + DT_CLK("omap_i2c.1", "ick", "i2c1_ick"), 127 + DT_CLK(NULL, "i2c1_ick", "i2c1_ick"), 128 + DT_CLK("omap_i2c.2", "ick", "i2c2_ick"), 129 + DT_CLK(NULL, "i2c2_ick", "i2c2_ick"), 130 + DT_CLK(NULL, "gpmc_fck", "gpmc_fck"), 131 + DT_CLK(NULL, "sdma_fck", "sdma_fck"), 132 + DT_CLK(NULL, "sdma_ick", "sdma_ick"), 133 + DT_CLK(NULL, "sdrc_ick", "sdrc_ick"), 134 + DT_CLK(NULL, "des_ick", "des_ick"), 135 + DT_CLK("omap-sham", "ick", "sha_ick"), 136 + DT_CLK(NULL, "sha_ick", "sha_ick"), 137 + DT_CLK("omap_rng", "ick", "rng_ick"), 138 + DT_CLK(NULL, "rng_ick", "rng_ick"), 139 + DT_CLK("omap-aes", "ick", "aes_ick"), 140 + DT_CLK(NULL, "aes_ick", "aes_ick"), 141 + DT_CLK(NULL, "pka_ick", "pka_ick"), 142 + DT_CLK(NULL, "usb_fck", "usb_fck"), 143 + DT_CLK(NULL, "timer_32k_ck", "func_32k_ck"), 144 + DT_CLK(NULL, "timer_sys_ck", "sys_ck"), 145 + DT_CLK(NULL, "timer_ext_ck", "alt_ck"), 146 + { .node_name = NULL }, 147 + }; 148 + 149 + static struct ti_dt_clk omap2420_clks[] = { 150 + DT_CLK(NULL, "sys_clkout2_src", "sys_clkout2_src"), 151 + DT_CLK(NULL, "sys_clkout2", "sys_clkout2"), 152 + DT_CLK(NULL, "dsp_ick", "dsp_ick"), 153 + DT_CLK(NULL, "iva1_ifck", "iva1_ifck"), 154 + DT_CLK(NULL, "iva1_mpu_int_ifck", "iva1_mpu_int_ifck"), 155 + DT_CLK(NULL, "wdt3_ick", "wdt3_ick"), 156 + DT_CLK(NULL, "wdt3_fck", "wdt3_fck"), 157 + DT_CLK("mmci-omap.0", "ick", "mmc_ick"), 158 + DT_CLK(NULL, "mmc_ick", "mmc_ick"), 159 + DT_CLK("mmci-omap.0", "fck", "mmc_fck"), 160 + DT_CLK(NULL, "mmc_fck", "mmc_fck"), 161 + DT_CLK(NULL, "eac_ick", "eac_ick"), 162 + DT_CLK(NULL, "eac_fck", "eac_fck"), 163 + DT_CLK(NULL, "i2c1_fck", "i2c1_fck"), 164 + DT_CLK(NULL, "i2c2_fck", "i2c2_fck"), 165 + DT_CLK(NULL, "vlynq_ick", "vlynq_ick"), 166 + DT_CLK(NULL, "vlynq_fck", "vlynq_fck"), 167 + DT_CLK("musb-hdrc", "fck", "osc_ck"), 168 + { .node_name = NULL }, 169 + }; 170 + 171 + static struct ti_dt_clk omap2430_clks[] = { 172 + DT_CLK("twl", "fck", "osc_ck"), 173 + DT_CLK(NULL, "iva2_1_ick", "iva2_1_ick"), 174 + DT_CLK(NULL, "mdm_ick", "mdm_ick"), 175 + DT_CLK(NULL, "mdm_osc_ck", "mdm_osc_ck"), 176 + DT_CLK("omap-mcbsp.3", "ick", "mcbsp3_ick"), 177 + DT_CLK(NULL, "mcbsp3_ick", "mcbsp3_ick"), 178 + DT_CLK(NULL, "mcbsp3_fck", "mcbsp3_fck"), 179 + DT_CLK("omap-mcbsp.4", "ick", "mcbsp4_ick"), 180 + DT_CLK(NULL, "mcbsp4_ick", "mcbsp4_ick"), 181 + DT_CLK(NULL, "mcbsp4_fck", "mcbsp4_fck"), 182 + DT_CLK("omap-mcbsp.5", "ick", "mcbsp5_ick"), 183 + DT_CLK(NULL, "mcbsp5_ick", "mcbsp5_ick"), 184 + DT_CLK(NULL, "mcbsp5_fck", "mcbsp5_fck"), 185 + DT_CLK("omap2_mcspi.3", "ick", "mcspi3_ick"), 186 + DT_CLK(NULL, "mcspi3_ick", "mcspi3_ick"), 187 + DT_CLK(NULL, "mcspi3_fck", "mcspi3_fck"), 188 + DT_CLK(NULL, "icr_ick", "icr_ick"), 189 + DT_CLK(NULL, "i2chs1_fck", "i2chs1_fck"), 190 + DT_CLK(NULL, "i2chs2_fck", "i2chs2_fck"), 191 + DT_CLK("musb-omap2430", "ick", "usbhs_ick"), 192 + DT_CLK(NULL, "usbhs_ick", "usbhs_ick"), 193 + DT_CLK("omap_hsmmc.0", "ick", "mmchs1_ick"), 194 + DT_CLK(NULL, "mmchs1_ick", "mmchs1_ick"), 195 + DT_CLK(NULL, "mmchs1_fck", "mmchs1_fck"), 196 + DT_CLK("omap_hsmmc.1", "ick", "mmchs2_ick"), 197 + DT_CLK(NULL, "mmchs2_ick", "mmchs2_ick"), 198 + DT_CLK(NULL, "mmchs2_fck", "mmchs2_fck"), 199 + DT_CLK(NULL, "gpio5_ick", "gpio5_ick"), 200 + DT_CLK(NULL, "gpio5_fck", "gpio5_fck"), 201 + DT_CLK(NULL, "mdm_intc_ick", "mdm_intc_ick"), 202 + DT_CLK("omap_hsmmc.0", "mmchsdb_fck", "mmchsdb1_fck"), 203 + DT_CLK(NULL, "mmchsdb1_fck", "mmchsdb1_fck"), 204 + DT_CLK("omap_hsmmc.1", "mmchsdb_fck", "mmchsdb2_fck"), 205 + DT_CLK(NULL, "mmchsdb2_fck", "mmchsdb2_fck"), 206 + { .node_name = NULL }, 207 + }; 208 + 209 + static const char *enable_init_clks[] = { 210 + "apll96_ck", 211 + "apll54_ck", 212 + "sync_32k_ick", 213 + "omapctrl_ick", 214 + "gpmc_fck", 215 + "sdrc_ick", 216 + }; 217 + 218 + enum { 219 + OMAP2_SOC_OMAP2420, 220 + OMAP2_SOC_OMAP2430, 221 + }; 222 + 223 + static int __init omap2xxx_dt_clk_init(int soc_type) 224 + { 225 + ti_dt_clocks_register(omap2xxx_clks); 226 + 227 + if (soc_type == OMAP2_SOC_OMAP2420) 228 + ti_dt_clocks_register(omap2420_clks); 229 + else 230 + ti_dt_clocks_register(omap2430_clks); 231 + 232 + omap2xxx_clkt_vps_init(); 233 + 234 + omap2_clk_disable_autoidle_all(); 235 + 236 + omap2_clk_enable_init_clocks(enable_init_clks, 237 + ARRAY_SIZE(enable_init_clks)); 238 + 239 + pr_info("Clocking rate (Crystal/DPLL/MPU): %ld.%01ld/%ld/%ld MHz\n", 240 + (clk_get_rate(clk_get_sys(NULL, "sys_ck")) / 1000000), 241 + (clk_get_rate(clk_get_sys(NULL, "sys_ck")) / 100000) % 10, 242 + (clk_get_rate(clk_get_sys(NULL, "dpll_ck")) / 1000000), 243 + (clk_get_rate(clk_get_sys(NULL, "mpu_ck")) / 1000000)); 244 + 245 + return 0; 246 + } 247 + 248 + int __init omap2420_dt_clk_init(void) 249 + { 250 + return omap2xxx_dt_clk_init(OMAP2_SOC_OMAP2420); 251 + } 252 + 253 + int __init omap2430_dt_clk_init(void) 254 + { 255 + return omap2xxx_dt_clk_init(OMAP2_SOC_OMAP2430); 256 + }
+6
drivers/clk/ti/clk-54xx.c
··· 240 240 if (rc) 241 241 pr_err("%s: failed to configure ABE DPLL!\n", __func__); 242 242 243 + abe_dpll = clk_get_sys(NULL, "dpll_abe_m2x2_ck"); 244 + if (!rc) 245 + rc = clk_set_rate(abe_dpll, OMAP5_DPLL_ABE_DEFFREQ * 2); 246 + if (rc) 247 + pr_err("%s: failed to configure ABE m2x2 DPLL!\n", __func__); 248 + 243 249 usb_dpll = clk_get_sys(NULL, "dpll_usb_ck"); 244 250 rc = clk_set_rate(usb_dpll, OMAP5_DPLL_USB_DEFFREQ); 245 251 if (rc)
+1 -1
drivers/clk/ti/clk-7xx.c
··· 24 24 DT_CLK(NULL, "atl_clkin0_ck", "atl_clkin0_ck"), 25 25 DT_CLK(NULL, "atl_clkin1_ck", "atl_clkin1_ck"), 26 26 DT_CLK(NULL, "atl_clkin2_ck", "atl_clkin2_ck"), 27 - DT_CLK(NULL, "atlclkin3_ck", "atlclkin3_ck"), 27 + DT_CLK(NULL, "atl_clkin3_ck", "atl_clkin3_ck"), 28 28 DT_CLK(NULL, "hdmi_clkin_ck", "hdmi_clkin_ck"), 29 29 DT_CLK(NULL, "mlb_clkin_ck", "mlb_clkin_ck"), 30 30 DT_CLK(NULL, "mlbp_clkin_ck", "mlbp_clkin_ck"),
+312
drivers/clk/ti/clk-dra7-atl.c
··· 1 + /* 2 + * DRA7 ATL (Audio Tracking Logic) clock driver 3 + * 4 + * Copyright (C) 2013 Texas Instruments, Inc. 5 + * 6 + * Peter Ujfalusi <peter.ujfalusi@ti.com> 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 version 2 as 10 + * published by the Free Software Foundation. 11 + * 12 + * This program is distributed "as is" WITHOUT ANY WARRANTY of any 13 + * kind, whether express or implied; without even the implied warranty 14 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 + * GNU General Public License for more details. 16 + */ 17 + 18 + #include <linux/module.h> 19 + #include <linux/clk-provider.h> 20 + #include <linux/slab.h> 21 + #include <linux/io.h> 22 + #include <linux/of.h> 23 + #include <linux/of_address.h> 24 + #include <linux/platform_device.h> 25 + #include <linux/pm_runtime.h> 26 + 27 + #define DRA7_ATL_INSTANCES 4 28 + 29 + #define DRA7_ATL_PPMR_REG(id) (0x200 + (id * 0x80)) 30 + #define DRA7_ATL_BBSR_REG(id) (0x204 + (id * 0x80)) 31 + #define DRA7_ATL_ATLCR_REG(id) (0x208 + (id * 0x80)) 32 + #define DRA7_ATL_SWEN_REG(id) (0x210 + (id * 0x80)) 33 + #define DRA7_ATL_BWSMUX_REG(id) (0x214 + (id * 0x80)) 34 + #define DRA7_ATL_AWSMUX_REG(id) (0x218 + (id * 0x80)) 35 + #define DRA7_ATL_PCLKMUX_REG(id) (0x21c + (id * 0x80)) 36 + 37 + #define DRA7_ATL_SWEN BIT(0) 38 + #define DRA7_ATL_DIVIDER_MASK (0x1f) 39 + #define DRA7_ATL_PCLKMUX BIT(0) 40 + struct dra7_atl_clock_info; 41 + 42 + struct dra7_atl_desc { 43 + struct clk *clk; 44 + struct clk_hw hw; 45 + struct dra7_atl_clock_info *cinfo; 46 + int id; 47 + 48 + bool probed; /* the driver for the IP has been loaded */ 49 + bool valid; /* configured */ 50 + bool enabled; 51 + u32 bws; /* Baseband Word Select Mux */ 52 + u32 aws; /* Audio Word Select Mux */ 53 + u32 divider; /* Cached divider value */ 54 + }; 55 + 56 + struct dra7_atl_clock_info { 57 + struct device *dev; 58 + void __iomem *iobase; 59 + 60 + struct dra7_atl_desc *cdesc; 61 + }; 62 + 63 + #define to_atl_desc(_hw) container_of(_hw, struct dra7_atl_desc, hw) 64 + 65 + static inline void atl_write(struct dra7_atl_clock_info *cinfo, u32 reg, 66 + u32 val) 67 + { 68 + __raw_writel(val, cinfo->iobase + reg); 69 + } 70 + 71 + static inline int atl_read(struct dra7_atl_clock_info *cinfo, u32 reg) 72 + { 73 + return __raw_readl(cinfo->iobase + reg); 74 + } 75 + 76 + static int atl_clk_enable(struct clk_hw *hw) 77 + { 78 + struct dra7_atl_desc *cdesc = to_atl_desc(hw); 79 + 80 + if (!cdesc->probed) 81 + goto out; 82 + 83 + if (unlikely(!cdesc->valid)) 84 + dev_warn(cdesc->cinfo->dev, "atl%d has not been configured\n", 85 + cdesc->id); 86 + pm_runtime_get_sync(cdesc->cinfo->dev); 87 + 88 + atl_write(cdesc->cinfo, DRA7_ATL_ATLCR_REG(cdesc->id), 89 + cdesc->divider - 1); 90 + atl_write(cdesc->cinfo, DRA7_ATL_SWEN_REG(cdesc->id), DRA7_ATL_SWEN); 91 + 92 + out: 93 + cdesc->enabled = true; 94 + 95 + return 0; 96 + } 97 + 98 + static void atl_clk_disable(struct clk_hw *hw) 99 + { 100 + struct dra7_atl_desc *cdesc = to_atl_desc(hw); 101 + 102 + if (!cdesc->probed) 103 + goto out; 104 + 105 + atl_write(cdesc->cinfo, DRA7_ATL_SWEN_REG(cdesc->id), 0); 106 + pm_runtime_put_sync(cdesc->cinfo->dev); 107 + 108 + out: 109 + cdesc->enabled = false; 110 + } 111 + 112 + static int atl_clk_is_enabled(struct clk_hw *hw) 113 + { 114 + struct dra7_atl_desc *cdesc = to_atl_desc(hw); 115 + 116 + return cdesc->enabled; 117 + } 118 + 119 + static unsigned long atl_clk_recalc_rate(struct clk_hw *hw, 120 + unsigned long parent_rate) 121 + { 122 + struct dra7_atl_desc *cdesc = to_atl_desc(hw); 123 + 124 + return parent_rate / cdesc->divider; 125 + } 126 + 127 + static long atl_clk_round_rate(struct clk_hw *hw, unsigned long rate, 128 + unsigned long *parent_rate) 129 + { 130 + unsigned divider; 131 + 132 + divider = (*parent_rate + rate / 2) / rate; 133 + if (divider > DRA7_ATL_DIVIDER_MASK + 1) 134 + divider = DRA7_ATL_DIVIDER_MASK + 1; 135 + 136 + return *parent_rate / divider; 137 + } 138 + 139 + static int atl_clk_set_rate(struct clk_hw *hw, unsigned long rate, 140 + unsigned long parent_rate) 141 + { 142 + struct dra7_atl_desc *cdesc = to_atl_desc(hw); 143 + u32 divider; 144 + 145 + divider = ((parent_rate + rate / 2) / rate) - 1; 146 + if (divider > DRA7_ATL_DIVIDER_MASK) 147 + divider = DRA7_ATL_DIVIDER_MASK; 148 + 149 + cdesc->divider = divider + 1; 150 + 151 + return 0; 152 + } 153 + 154 + const struct clk_ops atl_clk_ops = { 155 + .enable = atl_clk_enable, 156 + .disable = atl_clk_disable, 157 + .is_enabled = atl_clk_is_enabled, 158 + .recalc_rate = atl_clk_recalc_rate, 159 + .round_rate = atl_clk_round_rate, 160 + .set_rate = atl_clk_set_rate, 161 + }; 162 + 163 + static void __init of_dra7_atl_clock_setup(struct device_node *node) 164 + { 165 + struct dra7_atl_desc *clk_hw = NULL; 166 + struct clk_init_data init = { 0 }; 167 + const char **parent_names = NULL; 168 + struct clk *clk; 169 + 170 + clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL); 171 + if (!clk_hw) { 172 + pr_err("%s: could not allocate dra7_atl_desc\n", __func__); 173 + return; 174 + } 175 + 176 + clk_hw->hw.init = &init; 177 + clk_hw->divider = 1; 178 + init.name = node->name; 179 + init.ops = &atl_clk_ops; 180 + init.flags = CLK_IGNORE_UNUSED; 181 + init.num_parents = of_clk_get_parent_count(node); 182 + 183 + if (init.num_parents != 1) { 184 + pr_err("%s: atl clock %s must have 1 parent\n", __func__, 185 + node->name); 186 + goto cleanup; 187 + } 188 + 189 + parent_names = kzalloc(sizeof(char *), GFP_KERNEL); 190 + 191 + if (!parent_names) 192 + goto cleanup; 193 + 194 + parent_names[0] = of_clk_get_parent_name(node, 0); 195 + 196 + init.parent_names = parent_names; 197 + 198 + clk = clk_register(NULL, &clk_hw->hw); 199 + 200 + if (!IS_ERR(clk)) { 201 + of_clk_add_provider(node, of_clk_src_simple_get, clk); 202 + return; 203 + } 204 + cleanup: 205 + kfree(parent_names); 206 + kfree(clk_hw); 207 + } 208 + CLK_OF_DECLARE(dra7_atl_clock, "ti,dra7-atl-clock", of_dra7_atl_clock_setup); 209 + 210 + static int of_dra7_atl_clk_probe(struct platform_device *pdev) 211 + { 212 + struct device_node *node = pdev->dev.of_node; 213 + struct dra7_atl_clock_info *cinfo; 214 + int i; 215 + int ret = 0; 216 + 217 + if (!node) 218 + return -ENODEV; 219 + 220 + cinfo = devm_kzalloc(&pdev->dev, sizeof(*cinfo), GFP_KERNEL); 221 + if (!cinfo) 222 + return -ENOMEM; 223 + 224 + cinfo->iobase = of_iomap(node, 0); 225 + cinfo->dev = &pdev->dev; 226 + pm_runtime_enable(cinfo->dev); 227 + 228 + pm_runtime_get_sync(cinfo->dev); 229 + atl_write(cinfo, DRA7_ATL_PCLKMUX_REG(0), DRA7_ATL_PCLKMUX); 230 + 231 + for (i = 0; i < DRA7_ATL_INSTANCES; i++) { 232 + struct device_node *cfg_node; 233 + char prop[5]; 234 + struct dra7_atl_desc *cdesc; 235 + struct of_phandle_args clkspec; 236 + struct clk *clk; 237 + int rc; 238 + 239 + rc = of_parse_phandle_with_args(node, "ti,provided-clocks", 240 + NULL, i, &clkspec); 241 + 242 + if (rc) { 243 + pr_err("%s: failed to lookup atl clock %d\n", __func__, 244 + i); 245 + return -EINVAL; 246 + } 247 + 248 + clk = of_clk_get_from_provider(&clkspec); 249 + 250 + cdesc = to_atl_desc(__clk_get_hw(clk)); 251 + cdesc->cinfo = cinfo; 252 + cdesc->id = i; 253 + 254 + /* Get configuration for the ATL instances */ 255 + snprintf(prop, sizeof(prop), "atl%u", i); 256 + cfg_node = of_find_node_by_name(node, prop); 257 + if (cfg_node) { 258 + ret = of_property_read_u32(cfg_node, "bws", 259 + &cdesc->bws); 260 + ret |= of_property_read_u32(cfg_node, "aws", 261 + &cdesc->aws); 262 + if (!ret) { 263 + cdesc->valid = true; 264 + atl_write(cinfo, DRA7_ATL_BWSMUX_REG(i), 265 + cdesc->bws); 266 + atl_write(cinfo, DRA7_ATL_AWSMUX_REG(i), 267 + cdesc->aws); 268 + } 269 + } 270 + 271 + cdesc->probed = true; 272 + /* 273 + * Enable the clock if it has been asked prior to loading the 274 + * hw driver 275 + */ 276 + if (cdesc->enabled) 277 + atl_clk_enable(__clk_get_hw(clk)); 278 + } 279 + pm_runtime_put_sync(cinfo->dev); 280 + 281 + return ret; 282 + } 283 + 284 + static int of_dra7_atl_clk_remove(struct platform_device *pdev) 285 + { 286 + pm_runtime_disable(&pdev->dev); 287 + 288 + return 0; 289 + } 290 + 291 + static struct of_device_id of_dra7_atl_clk_match_tbl[] = { 292 + { .compatible = "ti,dra7-atl", }, 293 + {}, 294 + }; 295 + MODULE_DEVICE_TABLE(of, of_dra7_atl_clk_match_tbl); 296 + 297 + static struct platform_driver dra7_atl_clk_driver = { 298 + .driver = { 299 + .name = "dra7-atl", 300 + .owner = THIS_MODULE, 301 + .of_match_table = of_dra7_atl_clk_match_tbl, 302 + }, 303 + .probe = of_dra7_atl_clk_probe, 304 + .remove = of_dra7_atl_clk_remove, 305 + }; 306 + 307 + module_platform_driver(dra7_atl_clk_driver); 308 + 309 + MODULE_DESCRIPTION("Clock driver for DRA7 Audio Tracking Logic"); 310 + MODULE_ALIAS("platform:dra7-atl-clock"); 311 + MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>"); 312 + MODULE_LICENSE("GPL v2");
+103 -35
drivers/clk/ti/dpll.c
··· 25 25 #undef pr_fmt 26 26 #define pr_fmt(fmt) "%s: " fmt, __func__ 27 27 28 - #define DPLL_HAS_AUTOIDLE 0x1 29 - 30 28 #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \ 31 29 defined(CONFIG_SOC_DRA7XX) 32 30 static const struct clk_ops dpll_m4xen_ck_ops = { ··· 35 37 .set_rate = &omap3_noncore_dpll_set_rate, 36 38 .get_parent = &omap2_init_dpll_parent, 37 39 }; 40 + #else 41 + static const struct clk_ops dpll_m4xen_ck_ops = {}; 38 42 #endif 39 43 44 + #if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) || \ 45 + defined(CONFIG_SOC_OMAP5) || defined(CONFIG_SOC_DRA7XX) || \ 46 + defined(CONFIG_SOC_AM33XX) || defined(CONFIG_SOC_AM43XX) 40 47 static const struct clk_ops dpll_core_ck_ops = { 41 48 .recalc_rate = &omap3_dpll_recalc, 42 49 .get_parent = &omap2_init_dpll_parent, 43 50 }; 44 - 45 - #ifdef CONFIG_ARCH_OMAP3 46 - static const struct clk_ops omap3_dpll_core_ck_ops = { 47 - .get_parent = &omap2_init_dpll_parent, 48 - .recalc_rate = &omap3_dpll_recalc, 49 - .round_rate = &omap2_dpll_round_rate, 50 - }; 51 - #endif 52 51 53 52 static const struct clk_ops dpll_ck_ops = { 54 53 .enable = &omap3_noncore_dpll_enable, ··· 62 67 .round_rate = &omap2_dpll_round_rate, 63 68 .set_rate = &omap3_noncore_dpll_set_rate, 64 69 }; 70 + #else 71 + static const struct clk_ops dpll_core_ck_ops = {}; 72 + static const struct clk_ops dpll_ck_ops = {}; 73 + static const struct clk_ops dpll_no_gate_ck_ops = {}; 74 + const struct clk_hw_omap_ops clkhwops_omap3_dpll = {}; 75 + #endif 76 + 77 + #ifdef CONFIG_ARCH_OMAP2 78 + static const struct clk_ops omap2_dpll_core_ck_ops = { 79 + .get_parent = &omap2_init_dpll_parent, 80 + .recalc_rate = &omap2_dpllcore_recalc, 81 + .round_rate = &omap2_dpll_round_rate, 82 + .set_rate = &omap2_reprogram_dpllcore, 83 + }; 84 + #else 85 + static const struct clk_ops omap2_dpll_core_ck_ops = {}; 86 + #endif 87 + 88 + #ifdef CONFIG_ARCH_OMAP3 89 + static const struct clk_ops omap3_dpll_core_ck_ops = { 90 + .get_parent = &omap2_init_dpll_parent, 91 + .recalc_rate = &omap3_dpll_recalc, 92 + .round_rate = &omap2_dpll_round_rate, 93 + }; 94 + #else 95 + static const struct clk_ops omap3_dpll_core_ck_ops = {}; 96 + #endif 65 97 66 98 #ifdef CONFIG_ARCH_OMAP3 67 99 static const struct clk_ops omap3_dpll_ck_ops = { ··· 215 193 * @node: device node containing the DPLL info 216 194 * @ops: ops for the DPLL 217 195 * @ddt: DPLL data template to use 218 - * @init_flags: flags for controlling init types 219 196 * 220 197 * Initializes a DPLL clock from device tree data. 221 198 */ 222 199 static void __init of_ti_dpll_setup(struct device_node *node, 223 200 const struct clk_ops *ops, 224 - const struct dpll_data *ddt, 225 - u8 init_flags) 201 + const struct dpll_data *ddt) 226 202 { 227 203 struct clk_hw_omap *clk_hw = NULL; 228 204 struct clk_init_data *init = NULL; ··· 261 241 init->parent_names = parent_names; 262 242 263 243 dd->control_reg = ti_clk_get_reg_addr(node, 0); 264 - dd->idlest_reg = ti_clk_get_reg_addr(node, 1); 265 - dd->mult_div1_reg = ti_clk_get_reg_addr(node, 2); 266 244 267 - if (!dd->control_reg || !dd->idlest_reg || !dd->mult_div1_reg) 245 + /* 246 + * Special case for OMAP2 DPLL, register order is different due to 247 + * missing idlest_reg, also clkhwops is different. Detected from 248 + * missing idlest_mask. 249 + */ 250 + if (!dd->idlest_mask) { 251 + dd->mult_div1_reg = ti_clk_get_reg_addr(node, 1); 252 + #ifdef CONFIG_ARCH_OMAP2 253 + clk_hw->ops = &clkhwops_omap2xxx_dpll; 254 + omap2xxx_clkt_dpllcore_init(&clk_hw->hw); 255 + #endif 256 + } else { 257 + dd->idlest_reg = ti_clk_get_reg_addr(node, 1); 258 + if (!dd->idlest_reg) 259 + goto cleanup; 260 + 261 + dd->mult_div1_reg = ti_clk_get_reg_addr(node, 2); 262 + } 263 + 264 + if (!dd->control_reg || !dd->mult_div1_reg) 268 265 goto cleanup; 269 266 270 - if (init_flags & DPLL_HAS_AUTOIDLE) { 267 + if (dd->autoidle_mask) { 271 268 dd->autoidle_reg = ti_clk_get_reg_addr(node, 3); 272 269 if (!dd->autoidle_reg) 273 270 goto cleanup; ··· 347 310 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), 348 311 }; 349 312 350 - of_ti_dpll_setup(node, &omap3_dpll_ck_ops, &dd, DPLL_HAS_AUTOIDLE); 313 + of_ti_dpll_setup(node, &omap3_dpll_ck_ops, &dd); 351 314 } 352 315 CLK_OF_DECLARE(ti_omap3_dpll_clock, "ti,omap3-dpll-clock", 353 316 of_ti_omap3_dpll_setup); ··· 366 329 .freqsel_mask = 0xf0, 367 330 }; 368 331 369 - of_ti_dpll_setup(node, &omap3_dpll_core_ck_ops, &dd, DPLL_HAS_AUTOIDLE); 332 + of_ti_dpll_setup(node, &omap3_dpll_core_ck_ops, &dd); 370 333 } 371 334 CLK_OF_DECLARE(ti_omap3_core_dpll_clock, "ti,omap3-dpll-core-clock", 372 335 of_ti_omap3_core_dpll_setup); ··· 386 349 .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED), 387 350 }; 388 351 389 - of_ti_dpll_setup(node, &omap3_dpll_per_ck_ops, &dd, DPLL_HAS_AUTOIDLE); 352 + of_ti_dpll_setup(node, &omap3_dpll_per_ck_ops, &dd); 390 353 } 391 354 CLK_OF_DECLARE(ti_omap3_per_dpll_clock, "ti,omap3-dpll-per-clock", 392 355 of_ti_omap3_per_dpll_setup); ··· 408 371 .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED), 409 372 }; 410 373 411 - of_ti_dpll_setup(node, &omap3_dpll_per_ck_ops, &dd, DPLL_HAS_AUTOIDLE); 374 + of_ti_dpll_setup(node, &omap3_dpll_per_ck_ops, &dd); 412 375 } 413 376 CLK_OF_DECLARE(ti_omap3_per_jtype_dpll_clock, "ti,omap3-dpll-per-j-type-clock", 414 377 of_ti_omap3_per_jtype_dpll_setup); ··· 428 391 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), 429 392 }; 430 393 431 - of_ti_dpll_setup(node, &dpll_ck_ops, &dd, DPLL_HAS_AUTOIDLE); 394 + of_ti_dpll_setup(node, &dpll_ck_ops, &dd); 432 395 } 433 396 CLK_OF_DECLARE(ti_omap4_dpll_clock, "ti,omap4-dpll-clock", 434 397 of_ti_omap4_dpll_setup); 398 + 399 + static void __init of_ti_omap5_mpu_dpll_setup(struct device_node *node) 400 + { 401 + const struct dpll_data dd = { 402 + .idlest_mask = 0x1, 403 + .enable_mask = 0x7, 404 + .autoidle_mask = 0x7, 405 + .mult_mask = 0x7ff << 8, 406 + .div1_mask = 0x7f, 407 + .max_multiplier = 2047, 408 + .max_divider = 128, 409 + .dcc_mask = BIT(22), 410 + .dcc_rate = 1400000000, /* DCC beyond 1.4GHz */ 411 + .min_divider = 1, 412 + .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), 413 + }; 414 + 415 + of_ti_dpll_setup(node, &dpll_ck_ops, &dd); 416 + } 417 + CLK_OF_DECLARE(of_ti_omap5_mpu_dpll_clock, "ti,omap5-mpu-dpll-clock", 418 + of_ti_omap5_mpu_dpll_setup); 435 419 436 420 static void __init of_ti_omap4_core_dpll_setup(struct device_node *node) 437 421 { ··· 468 410 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), 469 411 }; 470 412 471 - of_ti_dpll_setup(node, &dpll_core_ck_ops, &dd, DPLL_HAS_AUTOIDLE); 413 + of_ti_dpll_setup(node, &dpll_core_ck_ops, &dd); 472 414 } 473 415 CLK_OF_DECLARE(ti_omap4_core_dpll_clock, "ti,omap4-dpll-core-clock", 474 416 of_ti_omap4_core_dpll_setup); ··· 491 433 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), 492 434 }; 493 435 494 - of_ti_dpll_setup(node, &dpll_m4xen_ck_ops, &dd, DPLL_HAS_AUTOIDLE); 436 + of_ti_dpll_setup(node, &dpll_m4xen_ck_ops, &dd); 495 437 } 496 438 CLK_OF_DECLARE(ti_omap4_m4xen_dpll_clock, "ti,omap4-dpll-m4xen-clock", 497 439 of_ti_omap4_m4xen_dpll_setup); ··· 512 454 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), 513 455 }; 514 456 515 - of_ti_dpll_setup(node, &dpll_m4xen_ck_ops, &dd, DPLL_HAS_AUTOIDLE); 457 + of_ti_dpll_setup(node, &dpll_m4xen_ck_ops, &dd); 516 458 } 517 459 CLK_OF_DECLARE(ti_omap4_jtype_dpll_clock, "ti,omap4-dpll-j-type-clock", 518 460 of_ti_omap4_jtype_dpll_setup); ··· 523 465 const struct dpll_data dd = { 524 466 .idlest_mask = 0x1, 525 467 .enable_mask = 0x7, 526 - .autoidle_mask = 0x7, 527 468 .mult_mask = 0x7ff << 8, 528 469 .div1_mask = 0x7f, 529 470 .max_multiplier = 2047, ··· 531 474 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), 532 475 }; 533 476 534 - of_ti_dpll_setup(node, &dpll_no_gate_ck_ops, &dd, 0); 477 + of_ti_dpll_setup(node, &dpll_no_gate_ck_ops, &dd); 535 478 } 536 479 CLK_OF_DECLARE(ti_am3_no_gate_dpll_clock, "ti,am3-dpll-no-gate-clock", 537 480 of_ti_am3_no_gate_dpll_setup); ··· 541 484 const struct dpll_data dd = { 542 485 .idlest_mask = 0x1, 543 486 .enable_mask = 0x7, 544 - .autoidle_mask = 0x7, 545 487 .mult_mask = 0x7ff << 8, 546 488 .div1_mask = 0x7f, 547 489 .max_multiplier = 4095, ··· 550 494 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), 551 495 }; 552 496 553 - of_ti_dpll_setup(node, &dpll_ck_ops, &dd, 0); 497 + of_ti_dpll_setup(node, &dpll_ck_ops, &dd); 554 498 } 555 499 CLK_OF_DECLARE(ti_am3_jtype_dpll_clock, "ti,am3-dpll-j-type-clock", 556 500 of_ti_am3_jtype_dpll_setup); ··· 560 504 const struct dpll_data dd = { 561 505 .idlest_mask = 0x1, 562 506 .enable_mask = 0x7, 563 - .autoidle_mask = 0x7, 564 507 .mult_mask = 0x7ff << 8, 565 508 .div1_mask = 0x7f, 566 509 .max_multiplier = 2047, ··· 569 514 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), 570 515 }; 571 516 572 - of_ti_dpll_setup(node, &dpll_no_gate_ck_ops, &dd, 0); 517 + of_ti_dpll_setup(node, &dpll_no_gate_ck_ops, &dd); 573 518 } 574 519 CLK_OF_DECLARE(ti_am3_no_gate_jtype_dpll_clock, 575 520 "ti,am3-dpll-no-gate-j-type-clock", ··· 580 525 const struct dpll_data dd = { 581 526 .idlest_mask = 0x1, 582 527 .enable_mask = 0x7, 583 - .autoidle_mask = 0x7, 584 528 .mult_mask = 0x7ff << 8, 585 529 .div1_mask = 0x7f, 586 530 .max_multiplier = 2047, ··· 588 534 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), 589 535 }; 590 536 591 - of_ti_dpll_setup(node, &dpll_ck_ops, &dd, 0); 537 + of_ti_dpll_setup(node, &dpll_ck_ops, &dd); 592 538 } 593 539 CLK_OF_DECLARE(ti_am3_dpll_clock, "ti,am3-dpll-clock", of_ti_am3_dpll_setup); 594 540 ··· 597 543 const struct dpll_data dd = { 598 544 .idlest_mask = 0x1, 599 545 .enable_mask = 0x7, 600 - .autoidle_mask = 0x7, 601 546 .mult_mask = 0x7ff << 8, 602 547 .div1_mask = 0x7f, 603 548 .max_multiplier = 2047, ··· 605 552 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), 606 553 }; 607 554 608 - of_ti_dpll_setup(node, &dpll_core_ck_ops, &dd, 0); 555 + of_ti_dpll_setup(node, &dpll_core_ck_ops, &dd); 609 556 } 610 557 CLK_OF_DECLARE(ti_am3_core_dpll_clock, "ti,am3-dpll-core-clock", 611 558 of_ti_am3_core_dpll_setup); 559 + 560 + static void __init of_ti_omap2_core_dpll_setup(struct device_node *node) 561 + { 562 + const struct dpll_data dd = { 563 + .enable_mask = 0x3, 564 + .mult_mask = 0x3ff << 12, 565 + .div1_mask = 0xf << 8, 566 + .max_divider = 16, 567 + .min_divider = 1, 568 + }; 569 + 570 + of_ti_dpll_setup(node, &omap2_dpll_core_ck_ops, &dd); 571 + } 572 + CLK_OF_DECLARE(ti_omap2_core_dpll_clock, "ti,omap2-dpll-core-clock", 573 + of_ti_omap2_core_dpll_setup);
+1 -1
drivers/clk/ti/gate.c
··· 185 185 CLK_OF_DECLARE(ti_composite_no_wait_gate_clk, "ti,composite-no-wait-gate-clock", 186 186 of_ti_composite_no_wait_gate_clk_setup); 187 187 188 - #ifdef CONFIG_ARCH_OMAP3 188 + #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) 189 189 static void __init of_ti_composite_interface_clk_setup(struct device_node *node) 190 190 { 191 191 _of_ti_composite_gate_clk_setup(node, &clkhwops_iclk_wait);
+11
drivers/clk/ti/interface.c
··· 94 94 CLK_OF_DECLARE(ti_no_wait_interface_clk, "ti,omap3-no-wait-interface-clock", 95 95 of_ti_no_wait_interface_clk_setup); 96 96 97 + #ifdef CONFIG_ARCH_OMAP3 97 98 static void __init of_ti_hsotgusb_interface_clk_setup(struct device_node *node) 98 99 { 99 100 _of_ti_interface_clk_setup(node, ··· 124 123 } 125 124 CLK_OF_DECLARE(ti_am35xx_interface_clk, "ti,am35xx-interface-clock", 126 125 of_ti_am35xx_interface_clk_setup); 126 + #endif 127 + 128 + #ifdef CONFIG_SOC_OMAP2430 129 + static void __init of_ti_omap2430_interface_clk_setup(struct device_node *node) 130 + { 131 + _of_ti_interface_clk_setup(node, &clkhwops_omap2430_i2chs_wait); 132 + } 133 + CLK_OF_DECLARE(ti_omap2430_interface_clk, "ti,omap2430-interface-clock", 134 + of_ti_omap2430_interface_clk_setup); 135 + #endif
+40
include/dt-bindings/clk/ti-dra7-atl.h
··· 1 + /* 2 + * This header provides constants for DRA7 ATL (Audio Tracking Logic) 3 + * 4 + * The constants defined in this header are used in dts files 5 + * 6 + * Copyright (C) 2013 Texas Instruments, Inc. 7 + * 8 + * Peter Ujfalusi <peter.ujfalusi@ti.com> 9 + * 10 + * This program is free software; you can redistribute it and/or modify 11 + * it under the terms of the GNU General Public License version 2 as 12 + * published by the Free Software Foundation. 13 + * 14 + * This program is distributed "as is" WITHOUT ANY WARRANTY of any 15 + * kind, whether express or implied; without even the implied warranty 16 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 + * GNU General Public License for more details. 18 + */ 19 + 20 + #ifndef _DT_BINDINGS_CLK_DRA7_ATL_H 21 + #define _DT_BINDINGS_CLK_DRA7_ATL_H 22 + 23 + #define DRA7_ATL_WS_MCASP1_FSR 0 24 + #define DRA7_ATL_WS_MCASP1_FSX 1 25 + #define DRA7_ATL_WS_MCASP2_FSR 2 26 + #define DRA7_ATL_WS_MCASP2_FSX 3 27 + #define DRA7_ATL_WS_MCASP3_FSX 4 28 + #define DRA7_ATL_WS_MCASP4_FSX 5 29 + #define DRA7_ATL_WS_MCASP5_FSX 6 30 + #define DRA7_ATL_WS_MCASP6_FSX 7 31 + #define DRA7_ATL_WS_MCASP7_FSX 8 32 + #define DRA7_ATL_WS_MCASP8_FSX 9 33 + #define DRA7_ATL_WS_MCASP8_AHCLKX 10 34 + #define DRA7_ATL_WS_XREF_CLK3 11 35 + #define DRA7_ATL_WS_XREF_CLK0 12 36 + #define DRA7_ATL_WS_XREF_CLK1 13 37 + #define DRA7_ATL_WS_XREF_CLK2 14 38 + #define DRA7_ATL_WS_OSC1_X1 15 39 + 40 + #endif
+34 -1
include/linux/clk/ti.h
··· 41 41 * @idlest_reg: register containing the DPLL idle status bitfield 42 42 * @autoidle_mask: mask of the DPLL autoidle mode bitfield in @autoidle_reg 43 43 * @freqsel_mask: mask of the DPLL jitter correction bitfield in @control_reg 44 + * @dcc_mask: mask of the DPLL DCC correction bitfield @mult_div1_reg 45 + * @dcc_rate: rate atleast which DCC @dcc_mask must be set 44 46 * @idlest_mask: mask of the DPLL idle status bitfield in @idlest_reg 45 47 * @lpmode_mask: mask of the DPLL low-power mode bitfield in @control_reg 46 48 * @m4xen_mask: mask of the DPLL M4X multiplier bitfield in @control_reg ··· 88 86 u32 idlest_mask; 89 87 u32 dco_mask; 90 88 u32 sddiv_mask; 89 + u32 dcc_mask; 90 + unsigned long dcc_rate; 91 91 u32 lpmode_mask; 92 92 u32 m4xen_mask; 93 93 u8 auto_recal_bit; ··· 98 94 u8 flags; 99 95 }; 100 96 101 - struct clk_hw_omap_ops; 97 + struct clk_hw_omap; 98 + 99 + /** 100 + * struct clk_hw_omap_ops - OMAP clk ops 101 + * @find_idlest: find idlest register information for a clock 102 + * @find_companion: find companion clock register information for a clock, 103 + * basically converts CM_ICLKEN* <-> CM_FCLKEN* 104 + * @allow_idle: enables autoidle hardware functionality for a clock 105 + * @deny_idle: prevent autoidle hardware functionality for a clock 106 + */ 107 + struct clk_hw_omap_ops { 108 + void (*find_idlest)(struct clk_hw_omap *oclk, 109 + void __iomem **idlest_reg, 110 + u8 *idlest_bit, u8 *idlest_val); 111 + void (*find_companion)(struct clk_hw_omap *oclk, 112 + void __iomem **other_reg, 113 + u8 *other_bit); 114 + void (*allow_idle)(struct clk_hw_omap *oclk); 115 + void (*deny_idle)(struct clk_hw_omap *oclk); 116 + }; 102 117 103 118 /** 104 119 * struct clk_hw_omap - OMAP struct clk ··· 282 259 void omap2_dflt_clk_disable(struct clk_hw *hw); 283 260 int omap2_dflt_clk_is_enabled(struct clk_hw *hw); 284 261 void omap3_clk_lock_dpll5(void); 262 + unsigned long omap2_dpllcore_recalc(struct clk_hw *hw, 263 + unsigned long parent_rate); 264 + int omap2_reprogram_dpllcore(struct clk_hw *clk, unsigned long rate, 265 + unsigned long parent_rate); 266 + void omap2xxx_clkt_dpllcore_init(struct clk_hw *hw); 267 + void omap2xxx_clkt_vps_init(void); 285 268 286 269 void __iomem *ti_clk_get_reg_addr(struct device_node *node, int index); 287 270 void ti_dt_clocks_register(struct ti_dt_clk *oclks); ··· 307 278 int dra7xx_dt_clk_init(void); 308 279 int am33xx_dt_clk_init(void); 309 280 int am43xx_dt_clk_init(void); 281 + int omap2420_dt_clk_init(void); 282 + int omap2430_dt_clk_init(void); 310 283 311 284 #ifdef CONFIG_OF 312 285 void of_ti_clk_allow_autoidle_all(void); ··· 318 287 static inline void of_ti_clk_deny_autoidle_all(void) { } 319 288 #endif 320 289 290 + extern const struct clk_hw_omap_ops clkhwops_omap2xxx_dpll; 291 + extern const struct clk_hw_omap_ops clkhwops_omap2430_i2chs_wait; 321 292 extern const struct clk_hw_omap_ops clkhwops_omap3_dpll; 322 293 extern const struct clk_hw_omap_ops clkhwops_omap4_dpllmx; 323 294 extern const struct clk_hw_omap_ops clkhwops_wait;