diff options
22 files changed, 1175 insertions, 78 deletions
| diff --git a/Documentation/devicetree/bindings/clock/ti/apll.txt b/Documentation/devicetree/bindings/clock/ti/apll.txt index 7faf5a68b3be..ade4dd4c30f0 100644 --- a/Documentation/devicetree/bindings/clock/ti/apll.txt +++ b/Documentation/devicetree/bindings/clock/ti/apll.txt @@ -14,18 +14,32 @@ a subtype of a DPLL [2], although a simplified one at that.  [2] Documentation/devicetree/bindings/clock/ti/dpll.txt  Required properties: -- compatible : shall be "ti,dra7-apll-clock" +- compatible : shall be "ti,dra7-apll-clock" or "ti,omap2-apll-clock"  - #clock-cells : from common clock binding; shall be set to 0.  - clocks : link phandles of parent clocks (clk-ref and clk-bypass)  - reg : address and length of the register set for controlling the APLL.    It contains the information of registers in the following order: -	"control" - contains the control register base address -	"idlest" - contains the idlest register base address +	"control" - contains the control register offset +	"idlest" - contains the idlest register offset +	"autoidle" - contains the autoidle register offset (OMAP2 only) +- ti,clock-frequency : static clock frequency for the clock (OMAP2 only) +- ti,idlest-shift : bit-shift for the idlest field (OMAP2 only) +- ti,bit-shift : bit-shift for enable and autoidle fields (OMAP2 only)  Examples: -	apll_pcie_ck: apll_pcie_ck@4a008200 { +	apll_pcie_ck: apll_pcie_ck {  		#clock-cells = <0>;  		clocks = <&apll_pcie_in_clk_mux>, <&dpll_pcie_ref_ck>; -		reg = <0x4a00821c 0x4>, <0x4a008220 0x4>; +		reg = <0x021c>, <0x0220>;  		compatible = "ti,dra7-apll-clock";  	}; + +	apll96_ck: apll96_ck { +		#clock-cells = <0>; +		compatible = "ti,omap2-apll-clock"; +		clocks = <&sys_ck>; +		ti,bit-shift = <2>; +		ti,idlest-shift = <8>; +		ti,clock-frequency = <96000000>; +		reg = <0x0500>, <0x0530>, <0x0520>; +	}; diff --git a/Documentation/devicetree/bindings/clock/ti/dpll.txt b/Documentation/devicetree/bindings/clock/ti/dpll.txt index 30bfdb7c9f18..df57009ff8e7 100644 --- a/Documentation/devicetree/bindings/clock/ti/dpll.txt +++ b/Documentation/devicetree/bindings/clock/ti/dpll.txt @@ -24,12 +24,14 @@ Required properties:  		"ti,omap4-dpll-core-clock",  		"ti,omap4-dpll-m4xen-clock",  		"ti,omap4-dpll-j-type-clock", +		"ti,omap5-mpu-dpll-clock",  		"ti,am3-dpll-no-gate-clock",  		"ti,am3-dpll-j-type-clock",  		"ti,am3-dpll-no-gate-j-type-clock",  		"ti,am3-dpll-clock",  		"ti,am3-dpll-core-clock",  		"ti,am3-dpll-x2-clock", +		"ti,omap2-dpll-core-clock",  - #clock-cells : from common clock binding; shall be set to 0.  - clocks : link phandles of parent clocks, first entry lists reference clock @@ -41,6 +43,7 @@ Required properties:  	"mult-div1" - contains the multiplier / divider register base address  	"autoidle" - contains the autoidle register base address (optional)    ti,am3-* dpll types do not have autoidle register +  ti,omap2-* dpll type does not support idlest / autoidle registers  Optional properties:  - DPLL mode setting - defining any one or more of the following overrides @@ -73,3 +76,10 @@ Examples:  		clocks = <&sys_clkin_ck>, <&sys_clkin_ck>;  		reg = <0x90>, <0x5c>, <0x68>;  	}; + +	dpll_ck: dpll_ck { +		#clock-cells = <0>; +		compatible = "ti,omap2-dpll-core-clock"; +		clocks = <&sys_ck>, <&sys_ck>; +		reg = <0x0500>, <0x0540>; +	}; diff --git a/Documentation/devicetree/bindings/clock/ti/dra7-atl.txt b/Documentation/devicetree/bindings/clock/ti/dra7-atl.txt new file mode 100644 index 000000000000..585e8c191f50 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/ti/dra7-atl.txt @@ -0,0 +1,96 @@ +Device Tree Clock bindings for ATL (Audio Tracking Logic) of DRA7 SoC. + +The ATL IP is used to generate clock to be used to synchronize baseband and +audio codec. A single ATL IP provides four ATL clock instances sharing the same +functional clock but can be configured to provide different clocks. +ATL can maintain a clock averages to some desired frequency based on the bws/aws +signals - can compensate the drift between the two ws signal. + +In order to provide the support for ATL and it's output clocks (which can be used +internally within the SoC or external components) two sets of bindings is needed: + +Clock tree binding: +This binding uses the common clock binding[1]. +To be able to integrate the ATL clocks with DT clock tree. +Provides ccf level representation of the ATL clocks to be used by drivers. +Since the clock instances are part of a single IP this binding is used as a node +for the DT clock tree, the IP driver is needed to handle the actual configuration +of the IP. + +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt + +Required properties: +- compatible : shall be "ti,dra7-atl-clock" +- #clock-cells : from common clock binding; shall be set to 0. +- clocks : link phandles to functional clock of ATL + +Binding for the IP driver: +This binding is used to configure the IP driver which is going to handle the +configuration of the IP for the ATL clock instances. + +Required properties: +- compatible : shall be "ti,dra7-atl" +- reg : base address for the ATL IP +- ti,provided-clocks : List of phandles to the clocks associated with the ATL +- clocks : link phandles to functional clock of ATL +- clock-names : Shall be set to "fck" +- ti,hwmods : Shall be set to "atl" + +Optional properties: +Configuration of ATL instances: +- atl{0/1/2/3} { +	- bws : Baseband word select signal selection +	- aws : Audio word select signal selection +}; + +For valid word select signals, see the dt-bindings/clk/ti-dra7-atl.h include +file. + +Examples: +/* clock bindings for atl provided clocks */ +atl_clkin0_ck: atl_clkin0_ck { +	#clock-cells = <0>; +	compatible = "ti,dra7-atl-clock"; +	clocks = <&atl_gfclk_mux>; +}; + +atl_clkin1_ck: atl_clkin1_ck { +	#clock-cells = <0>; +	compatible = "ti,dra7-atl-clock"; +	clocks = <&atl_gfclk_mux>; +}; + +atl_clkin2_ck: atl_clkin2_ck { +	#clock-cells = <0>; +	compatible = "ti,dra7-atl-clock"; +	clocks = <&atl_gfclk_mux>; +}; + +atl_clkin3_ck: atl_clkin3_ck { +	#clock-cells = <0>; +	compatible = "ti,dra7-atl-clock"; +	clocks = <&atl_gfclk_mux>; +}; + +/* binding for the IP */ +atl: atl@4843c000 { +	compatible = "ti,dra7-atl"; +	reg = <0x4843c000 0x3ff>; +	ti,hwmods = "atl"; +	ti,provided-clocks = <&atl_clkin0_ck>, <&atl_clkin1_ck>, +				<&atl_clkin2_ck>, <&atl_clkin3_ck>; +	clocks = <&atl_gfclk_mux>; +	clock-names = "fck"; +	status = "disabled"; +}; + +#include <dt-bindings/clk/ti-dra7-atl.h> + +&atl { +	status = "okay"; + +	atl2 { +		bws = <DRA7_ATL_WS_MCASP2_FSX>; +		aws = <DRA7_ATL_WS_MCASP3_FSX>; +	}; +}; diff --git a/Documentation/devicetree/bindings/clock/ti/gate.txt b/Documentation/devicetree/bindings/clock/ti/gate.txt index 125281aaa4ca..03f8fdee62a7 100644 --- a/Documentation/devicetree/bindings/clock/ti/gate.txt +++ b/Documentation/devicetree/bindings/clock/ti/gate.txt @@ -25,6 +25,11 @@ Required properties:  			  to map clockdomains properly    "ti,hsdiv-gate-clock" - gate clock with OMAP36xx specific hardware handling,  			  required for a hardware errata +  "ti,composite-gate-clock" - composite gate clock, to be part of composite +			      clock +  "ti,composite-no-wait-gate-clock" - composite gate clock that does not wait +				      for clock to be active before returning +				      from clk_enable()  - #clock-cells : from common clock binding; shall be set to 0  - clocks : link to phandle of parent clock  - reg : offset for register controlling adjustable gate, not needed for @@ -41,7 +46,7 @@ Examples:  		#clock-cells = <0>;  		compatible = "ti,gate-clock";  		clocks = <&core_96m_fck>; -		reg = <0x48004a00 0x4>; +		reg = <0x0a00>;  		ti,bit-shift = <25>;  	}; @@ -57,7 +62,7 @@ Examples:  		#clock-cells = <0>;  		compatible = "ti,dss-gate-clock";  		clocks = <&dpll4_m4x2_ck>; -		reg = <0x48004e00 0x4>; +		reg = <0x0e00>;  		ti,bit-shift = <0>;  	}; @@ -65,7 +70,7 @@ Examples:  		#clock-cells = <0>;  		compatible = "ti,am35xx-gate-clock";  		clocks = <&ipss_ick>; -		reg = <0x4800259c 0x4>; +		reg = <0x059c>;  		ti,bit-shift = <1>;  	}; @@ -80,6 +85,22 @@ Examples:  		compatible = "ti,hsdiv-gate-clock";  		clocks = <&dpll4_m2x2_mul_ck>;  		ti,bit-shift = <0x1b>; -		reg = <0x48004d00 0x4>; +		reg = <0x0d00>;  		ti,set-bit-to-disable;  	}; + +	vlynq_gate_fck: vlynq_gate_fck { +		#clock-cells = <0>; +		compatible = "ti,composite-gate-clock"; +		clocks = <&core_ck>; +		ti,bit-shift = <3>; +		reg = <0x0200>; +	}; + +	sys_clkout2_src_gate: sys_clkout2_src_gate { +		#clock-cells = <0>; +		compatible = "ti,composite-no-wait-gate-clock"; +		clocks = <&core_ck>; +		ti,bit-shift = <15>; +		reg = <0x0070>; +	}; diff --git a/Documentation/devicetree/bindings/clock/ti/interface.txt b/Documentation/devicetree/bindings/clock/ti/interface.txt index 064e8caccac3..3111a409fea6 100644 --- a/Documentation/devicetree/bindings/clock/ti/interface.txt +++ b/Documentation/devicetree/bindings/clock/ti/interface.txt @@ -21,6 +21,8 @@ Required properties:    "ti,omap3-dss-interface-clock" - interface clock with DSS specific HW handling    "ti,omap3-ssi-interface-clock" - interface clock with SSI specific HW handling    "ti,am35xx-interface-clock" - interface clock with AM35xx specific HW handling +  "ti,omap2430-interface-clock" - interface clock with OMAP2430 specific HW +				  handling  - #clock-cells : from common clock binding; shall be set to 0  - clocks : link to phandle of parent clock  - reg : base address for the control register diff --git a/arch/arm/boot/dts/dra7xx-clocks.dtsi b/arch/arm/boot/dts/dra7xx-clocks.dtsi index c7676871d9c0..b03cfe49d22b 100644 --- a/arch/arm/boot/dts/dra7xx-clocks.dtsi +++ b/arch/arm/boot/dts/dra7xx-clocks.dtsi @@ -26,7 +26,7 @@  		clock-frequency = <0>;  	}; -	atlclkin3_ck: atlclkin3_ck { +	atl_clkin3_ck: atl_clkin3_ck {  		#clock-cells = <0>;  		compatible = "fixed-clock";  		clock-frequency = <0>; @@ -277,7 +277,7 @@  	dpll_mpu_ck: dpll_mpu_ck {  		#clock-cells = <0>; -		compatible = "ti,omap4-dpll-clock"; +		compatible = "ti,omap5-mpu-dpll-clock";  		clocks = <&sys_clkin1>, <&mpu_dpll_hs_clk_div>;  		reg = <0x0160>, <0x0164>, <0x016c>, <0x0168>;  	}; @@ -730,7 +730,7 @@  	mcasp1_ahclkr_mux: mcasp1_ahclkr_mux {  		#clock-cells = <0>;  		compatible = "ti,mux-clock"; -		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>; +		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>;  		ti,bit-shift = <28>;  		reg = <0x0550>;  	}; @@ -738,7 +738,7 @@  	mcasp1_ahclkx_mux: mcasp1_ahclkx_mux {  		#clock-cells = <0>;  		compatible = "ti,mux-clock"; -		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>; +		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>;  		ti,bit-shift = <24>;  		reg = <0x0550>;  	}; @@ -1639,7 +1639,7 @@  	mcasp2_ahclkr_mux: mcasp2_ahclkr_mux {  		#clock-cells = <0>;  		compatible = "ti,mux-clock"; -		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>; +		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>;  		ti,bit-shift = <28>;  		reg = <0x1860>;  	}; @@ -1647,7 +1647,7 @@  	mcasp2_ahclkx_mux: mcasp2_ahclkx_mux {  		#clock-cells = <0>;  		compatible = "ti,mux-clock"; -		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>; +		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>;  		ti,bit-shift = <24>;  		reg = <0x1860>;  	}; @@ -1663,7 +1663,7 @@  	mcasp3_ahclkx_mux: mcasp3_ahclkx_mux {  		#clock-cells = <0>;  		compatible = "ti,mux-clock"; -		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>; +		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>;  		ti,bit-shift = <24>;  		reg = <0x1868>;  	}; @@ -1679,7 +1679,7 @@  	mcasp4_ahclkx_mux: mcasp4_ahclkx_mux {  		#clock-cells = <0>;  		compatible = "ti,mux-clock"; -		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>; +		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>;  		ti,bit-shift = <24>;  		reg = <0x1898>;  	}; @@ -1695,7 +1695,7 @@  	mcasp5_ahclkx_mux: mcasp5_ahclkx_mux {  		#clock-cells = <0>;  		compatible = "ti,mux-clock"; -		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>; +		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>;  		ti,bit-shift = <24>;  		reg = <0x1878>;  	}; @@ -1711,7 +1711,7 @@  	mcasp6_ahclkx_mux: mcasp6_ahclkx_mux {  		#clock-cells = <0>;  		compatible = "ti,mux-clock"; -		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>; +		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>;  		ti,bit-shift = <24>;  		reg = <0x1904>;  	}; @@ -1727,7 +1727,7 @@  	mcasp7_ahclkx_mux: mcasp7_ahclkx_mux {  		#clock-cells = <0>;  		compatible = "ti,mux-clock"; -		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>; +		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>;  		ti,bit-shift = <24>;  		reg = <0x1908>;  	}; @@ -1743,7 +1743,7 @@  	mcasp8_ahclk_mux: mcasp8_ahclk_mux {  		#clock-cells = <0>;  		compatible = "ti,mux-clock"; -		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>; +		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>;  		ti,bit-shift = <22>;  		reg = <0x1890>;  	}; diff --git a/arch/arm/boot/dts/omap54xx-clocks.dtsi b/arch/arm/boot/dts/omap54xx-clocks.dtsi index aeb142ce8e9d..e67a23b5d788 100644 --- a/arch/arm/boot/dts/omap54xx-clocks.dtsi +++ b/arch/arm/boot/dts/omap54xx-clocks.dtsi @@ -335,7 +335,7 @@  	dpll_mpu_ck: dpll_mpu_ck {  		#clock-cells = <0>; -		compatible = "ti,omap4-dpll-clock"; +		compatible = "ti,omap5-mpu-dpll-clock";  		clocks = <&sys_clkin>, <&mpu_dpll_hs_clk_div>;  		reg = <0x0160>, <0x0164>, <0x016c>, <0x0168>;  	}; diff --git a/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c b/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c index b935ed2922d8..85e0b0c06718 100644 --- a/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c +++ b/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c @@ -208,3 +208,56 @@ void omap2xxx_clkt_vps_late_init(void)  		clk_put(c);  	}  } + +#ifdef CONFIG_OF +#include <linux/clk-provider.h> +#include <linux/clkdev.h> + +static const struct clk_ops virt_prcm_set_ops = { +	.recalc_rate	= &omap2_table_mpu_recalc, +	.set_rate	= &omap2_select_table_rate, +	.round_rate	= &omap2_round_to_table_rate, +}; + +/** + * omap2xxx_clkt_vps_init - initialize virt_prcm_set clock + * + * Does a manual init for the virtual prcm DVFS clock for OMAP2. This + * function is called only from omap2 DT clock init, as the virtual + * node is not modelled in the DT clock data. + */ +void omap2xxx_clkt_vps_init(void) +{ +	struct clk_init_data init = { NULL }; +	struct clk_hw_omap *hw = NULL; +	struct clk *clk; +	const char *parent_name = "mpu_ck"; +	struct clk_lookup *lookup = NULL; + +	omap2xxx_clkt_vps_late_init(); +	omap2xxx_clkt_vps_check_bootloader_rates(); + +	hw = kzalloc(sizeof(*hw), GFP_KERNEL); +	lookup = kzalloc(sizeof(*lookup), GFP_KERNEL); +	if (!hw || !lookup) +		goto cleanup; +	init.name = "virt_prcm_set"; +	init.ops = &virt_prcm_set_ops; +	init.parent_names = &parent_name; +	init.num_parents = 1; + +	hw->hw.init = &init; + +	clk = clk_register(NULL, &hw->hw); + +	lookup->dev_id = NULL; +	lookup->con_id = "cpufreq_ck"; +	lookup->clk = clk; + +	clkdev_add(lookup); +	return; +cleanup: +	kfree(hw); +	kfree(lookup); +} +#endif diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h index bda767a9dea8..12f54d428d7c 100644 --- a/arch/arm/mach-omap2/clock.h +++ b/arch/arm/mach-omap2/clock.h @@ -178,17 +178,6 @@ struct clksel {  	const struct clksel_rate *rates;  }; -struct clk_hw_omap_ops { -	void			(*find_idlest)(struct clk_hw_omap *oclk, -					void __iomem **idlest_reg, -					u8 *idlest_bit, u8 *idlest_val); -	void			(*find_companion)(struct clk_hw_omap *oclk, -					void __iomem **other_reg, -					u8 *other_bit); -	void			(*allow_idle)(struct clk_hw_omap *oclk); -	void			(*deny_idle)(struct clk_hw_omap *oclk); -}; -  unsigned long omap_fixed_divisor_recalc(struct clk_hw *hw,  					unsigned long parent_rate); @@ -279,8 +268,6 @@ extern const struct clk_hw_omap_ops clkhwops_omap3430es2_hsotgusb_wait;  extern const struct clk_hw_omap_ops clkhwops_am35xx_ipss_module_wait;  extern const struct clk_hw_omap_ops clkhwops_apll54;  extern const struct clk_hw_omap_ops clkhwops_apll96; -extern const struct clk_hw_omap_ops clkhwops_omap2xxx_dpll; -extern const struct clk_hw_omap_ops clkhwops_omap2430_i2chs_wait;  /* clksel_rate blocks shared between OMAP44xx and AM33xx */  extern const struct clksel_rate div_1_0_rates[]; diff --git a/arch/arm/mach-omap2/clock2xxx.h b/arch/arm/mach-omap2/clock2xxx.h index 539dc08afbba..45f41a411603 100644 --- a/arch/arm/mach-omap2/clock2xxx.h +++ b/arch/arm/mach-omap2/clock2xxx.h @@ -21,10 +21,6 @@ unsigned long omap2xxx_sys_clk_recalc(struct clk_hw *clk,  				      unsigned long parent_rate);  unsigned long omap2_osc_clk_recalc(struct clk_hw *clk,  				   unsigned long parent_rate); -unsigned long omap2_dpllcore_recalc(struct clk_hw *hw, -				    unsigned long parent_rate); -int omap2_reprogram_dpllcore(struct clk_hw *clk, unsigned long rate, -			     unsigned long parent_rate);  void omap2xxx_clkt_dpllcore_init(struct clk_hw *hw);  unsigned long omap2_clk_apll54_recalc(struct clk_hw *hw,  				      unsigned long parent_rate); diff --git a/arch/arm/mach-omap2/dpll3xxx.c b/arch/arm/mach-omap2/dpll3xxx.c index fcd8036af910..6d7ba37e2257 100644 --- a/arch/arm/mach-omap2/dpll3xxx.c +++ b/arch/arm/mach-omap2/dpll3xxx.c @@ -319,6 +319,15 @@ static int omap3_noncore_dpll_program(struct clk_hw_omap *clk, u16 freqsel)  	/* Set DPLL multiplier, divider */  	v = omap2_clk_readl(clk, dd->mult_div1_reg); + +	/* Handle Duty Cycle Correction */ +	if (dd->dcc_mask) { +		if (dd->last_rounded_rate >= dd->dcc_rate) +			v |= dd->dcc_mask; /* Enable DCC */ +		else +			v &= ~dd->dcc_mask; /* Disable DCC */ +	} +  	v &= ~(dd->mult_mask | dd->div1_mask);  	v |= dd->last_rounded_m << __ffs(dd->mult_mask);  	v |= (dd->last_rounded_n - 1) << __ffs(dd->div1_mask); diff --git a/drivers/clk/ti/Makefile b/drivers/clk/ti/Makefile index 4319d4031aa3..ed4d0aaf8916 100644 --- a/drivers/clk/ti/Makefile +++ b/drivers/clk/ti/Makefile @@ -3,9 +3,11 @@ obj-y					+= clk.o autoidle.o clockdomain.o  clk-common				= dpll.o composite.o divider.o gate.o \  					  fixed-factor.o mux.o apll.o  obj-$(CONFIG_SOC_AM33XX)		+= $(clk-common) clk-33xx.o +obj-$(CONFIG_ARCH_OMAP2)		+= $(clk-common) interface.o clk-2xxx.o  obj-$(CONFIG_ARCH_OMAP3)		+= $(clk-common) interface.o clk-3xxx.o  obj-$(CONFIG_ARCH_OMAP4)		+= $(clk-common) clk-44xx.o  obj-$(CONFIG_SOC_OMAP5)			+= $(clk-common) clk-54xx.o -obj-$(CONFIG_SOC_DRA7XX)		+= $(clk-common) clk-7xx.o +obj-$(CONFIG_SOC_DRA7XX)		+= $(clk-common) clk-7xx.o \ +					   clk-dra7-atl.o  obj-$(CONFIG_SOC_AM43XX)		+= $(clk-common) clk-43xx.o  endif diff --git a/drivers/clk/ti/apll.c b/drivers/clk/ti/apll.c index b986f61f5a77..5428c9c547cd 100644 --- a/drivers/clk/ti/apll.c +++ b/drivers/clk/ti/apll.c @@ -221,3 +221,184 @@ cleanup:  	kfree(init);  }  CLK_OF_DECLARE(dra7_apll_clock, "ti,dra7-apll-clock", of_dra7_apll_setup); + +#define OMAP2_EN_APLL_LOCKED	0x3 +#define OMAP2_EN_APLL_STOPPED	0x0 + +static int omap2_apll_is_enabled(struct clk_hw *hw) +{ +	struct clk_hw_omap *clk = to_clk_hw_omap(hw); +	struct dpll_data *ad = clk->dpll_data; +	u32 v; + +	v = ti_clk_ll_ops->clk_readl(ad->control_reg); +	v &= ad->enable_mask; + +	v >>= __ffs(ad->enable_mask); + +	return v == OMAP2_EN_APLL_LOCKED ? 1 : 0; +} + +static unsigned long omap2_apll_recalc(struct clk_hw *hw, +				       unsigned long parent_rate) +{ +	struct clk_hw_omap *clk = to_clk_hw_omap(hw); + +	if (omap2_apll_is_enabled(hw)) +		return clk->fixed_rate; + +	return 0; +} + +static int omap2_apll_enable(struct clk_hw *hw) +{ +	struct clk_hw_omap *clk = to_clk_hw_omap(hw); +	struct dpll_data *ad = clk->dpll_data; +	u32 v; +	int i = 0; + +	v = ti_clk_ll_ops->clk_readl(ad->control_reg); +	v &= ~ad->enable_mask; +	v |= OMAP2_EN_APLL_LOCKED << __ffs(ad->enable_mask); +	ti_clk_ll_ops->clk_writel(v, ad->control_reg); + +	while (1) { +		v = ti_clk_ll_ops->clk_readl(ad->idlest_reg); +		if (v & ad->idlest_mask) +			break; +		if (i > MAX_APLL_WAIT_TRIES) +			break; +		i++; +		udelay(1); +	} + +	if (i == MAX_APLL_WAIT_TRIES) { +		pr_warn("%s failed to transition to locked\n", +			__clk_get_name(clk->hw.clk)); +		return -EBUSY; +	} + +	return 0; +} + +static void omap2_apll_disable(struct clk_hw *hw) +{ +	struct clk_hw_omap *clk = to_clk_hw_omap(hw); +	struct dpll_data *ad = clk->dpll_data; +	u32 v; + +	v = ti_clk_ll_ops->clk_readl(ad->control_reg); +	v &= ~ad->enable_mask; +	v |= OMAP2_EN_APLL_STOPPED << __ffs(ad->enable_mask); +	ti_clk_ll_ops->clk_writel(v, ad->control_reg); +} + +static struct clk_ops omap2_apll_ops = { +	.enable		= &omap2_apll_enable, +	.disable	= &omap2_apll_disable, +	.is_enabled	= &omap2_apll_is_enabled, +	.recalc_rate	= &omap2_apll_recalc, +}; + +static void omap2_apll_set_autoidle(struct clk_hw_omap *clk, u32 val) +{ +	struct dpll_data *ad = clk->dpll_data; +	u32 v; + +	v = ti_clk_ll_ops->clk_readl(ad->autoidle_reg); +	v &= ~ad->autoidle_mask; +	v |= val << __ffs(ad->autoidle_mask); +	ti_clk_ll_ops->clk_writel(v, ad->control_reg); +} + +#define OMAP2_APLL_AUTOIDLE_LOW_POWER_STOP	0x3 +#define OMAP2_APLL_AUTOIDLE_DISABLE		0x0 + +static void omap2_apll_allow_idle(struct clk_hw_omap *clk) +{ +	omap2_apll_set_autoidle(clk, OMAP2_APLL_AUTOIDLE_LOW_POWER_STOP); +} + +static void omap2_apll_deny_idle(struct clk_hw_omap *clk) +{ +	omap2_apll_set_autoidle(clk, OMAP2_APLL_AUTOIDLE_DISABLE); +} + +static struct clk_hw_omap_ops omap2_apll_hwops = { +	.allow_idle	= &omap2_apll_allow_idle, +	.deny_idle	= &omap2_apll_deny_idle, +}; + +static void __init of_omap2_apll_setup(struct device_node *node) +{ +	struct dpll_data *ad = NULL; +	struct clk_hw_omap *clk_hw = NULL; +	struct clk_init_data *init = NULL; +	struct clk *clk; +	const char *parent_name; +	u32 val; + +	ad = kzalloc(sizeof(*clk_hw), GFP_KERNEL); +	clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL); +	init = kzalloc(sizeof(*init), GFP_KERNEL); + +	if (!ad || !clk_hw || !init) +		goto cleanup; + +	clk_hw->dpll_data = ad; +	clk_hw->hw.init = init; +	init->ops = &omap2_apll_ops; +	init->name = node->name; +	clk_hw->ops = &omap2_apll_hwops; + +	init->num_parents = of_clk_get_parent_count(node); +	if (init->num_parents != 1) { +		pr_err("%s must have one parent\n", node->name); +		goto cleanup; +	} + +	parent_name = of_clk_get_parent_name(node, 0); +	init->parent_names = &parent_name; + +	if (of_property_read_u32(node, "ti,clock-frequency", &val)) { +		pr_err("%s missing clock-frequency\n", node->name); +		goto cleanup; +	} +	clk_hw->fixed_rate = val; + +	if (of_property_read_u32(node, "ti,bit-shift", &val)) { +		pr_err("%s missing bit-shift\n", node->name); +		goto cleanup; +	} + +	clk_hw->enable_bit = val; +	ad->enable_mask = 0x3 << val; +	ad->autoidle_mask = 0x3 << val; + +	if (of_property_read_u32(node, "ti,idlest-shift", &val)) { +		pr_err("%s missing idlest-shift\n", node->name); +		goto cleanup; +	} + +	ad->idlest_mask = 1 << val; + +	ad->control_reg = ti_clk_get_reg_addr(node, 0); +	ad->autoidle_reg = ti_clk_get_reg_addr(node, 1); +	ad->idlest_reg = ti_clk_get_reg_addr(node, 2); + +	if (!ad->control_reg || !ad->autoidle_reg || !ad->idlest_reg) +		goto cleanup; + +	clk = clk_register(NULL, &clk_hw->hw); +	if (!IS_ERR(clk)) { +		of_clk_add_provider(node, of_clk_src_simple_get, clk); +		kfree(init); +		return; +	} +cleanup: +	kfree(ad); +	kfree(clk_hw); +	kfree(init); +} +CLK_OF_DECLARE(omap2_apll_clock, "ti,omap2-apll-clock", +	       of_omap2_apll_setup); diff --git a/drivers/clk/ti/clk-2xxx.c b/drivers/clk/ti/clk-2xxx.c new file mode 100644 index 000000000000..c808ab3d2bb2 --- /dev/null +++ b/drivers/clk/ti/clk-2xxx.c @@ -0,0 +1,256 @@ +/* + * OMAP2 Clock init + * + * Copyright (C) 2013 Texas Instruments, Inc + *     Tero Kristo (t-kristo@ti.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/kernel.h> +#include <linux/list.h> +#include <linux/clk-provider.h> +#include <linux/clk/ti.h> + +static struct ti_dt_clk omap2xxx_clks[] = { +	DT_CLK(NULL, "func_32k_ck", "func_32k_ck"), +	DT_CLK(NULL, "secure_32k_ck", "secure_32k_ck"), +	DT_CLK(NULL, "virt_12m_ck", "virt_12m_ck"), +	DT_CLK(NULL, "virt_13m_ck", "virt_13m_ck"), +	DT_CLK(NULL, "virt_19200000_ck", "virt_19200000_ck"), +	DT_CLK(NULL, "virt_26m_ck", "virt_26m_ck"), +	DT_CLK(NULL, "aplls_clkin_ck", "aplls_clkin_ck"), +	DT_CLK(NULL, "aplls_clkin_x2_ck", "aplls_clkin_x2_ck"), +	DT_CLK(NULL, "osc_ck", "osc_ck"), +	DT_CLK(NULL, "sys_ck", "sys_ck"), +	DT_CLK(NULL, "alt_ck", "alt_ck"), +	DT_CLK(NULL, "mcbsp_clks", "mcbsp_clks"), +	DT_CLK(NULL, "dpll_ck", "dpll_ck"), +	DT_CLK(NULL, "apll96_ck", "apll96_ck"), +	DT_CLK(NULL, "apll54_ck", "apll54_ck"), +	DT_CLK(NULL, "func_54m_ck", "func_54m_ck"), +	DT_CLK(NULL, "core_ck", "core_ck"), +	DT_CLK(NULL, "func_96m_ck", "func_96m_ck"), +	DT_CLK(NULL, "func_48m_ck", "func_48m_ck"), +	DT_CLK(NULL, "func_12m_ck", "func_12m_ck"), +	DT_CLK(NULL, "sys_clkout_src", "sys_clkout_src"), +	DT_CLK(NULL, "sys_clkout", "sys_clkout"), +	DT_CLK(NULL, "emul_ck", "emul_ck"), +	DT_CLK(NULL, "mpu_ck", "mpu_ck"), +	DT_CLK(NULL, "dsp_fck", "dsp_fck"), +	DT_CLK(NULL, "gfx_3d_fck", "gfx_3d_fck"), +	DT_CLK(NULL, "gfx_2d_fck", "gfx_2d_fck"), +	DT_CLK(NULL, "gfx_ick", "gfx_ick"), +	DT_CLK("omapdss_dss", "ick", "dss_ick"), +	DT_CLK(NULL, "dss_ick", "dss_ick"), +	DT_CLK(NULL, "dss1_fck", "dss1_fck"), +	DT_CLK(NULL, "dss2_fck", "dss2_fck"), +	DT_CLK(NULL, "dss_54m_fck", "dss_54m_fck"), +	DT_CLK(NULL, "core_l3_ck", "core_l3_ck"), +	DT_CLK(NULL, "ssi_fck", "ssi_ssr_sst_fck"), +	DT_CLK(NULL, "usb_l4_ick", "usb_l4_ick"), +	DT_CLK(NULL, "l4_ck", "l4_ck"), +	DT_CLK(NULL, "ssi_l4_ick", "ssi_l4_ick"), +	DT_CLK(NULL, "gpt1_ick", "gpt1_ick"), +	DT_CLK(NULL, "gpt1_fck", "gpt1_fck"), +	DT_CLK(NULL, "gpt2_ick", "gpt2_ick"), +	DT_CLK(NULL, "gpt2_fck", "gpt2_fck"), +	DT_CLK(NULL, "gpt3_ick", "gpt3_ick"), +	DT_CLK(NULL, "gpt3_fck", "gpt3_fck"), +	DT_CLK(NULL, "gpt4_ick", "gpt4_ick"), +	DT_CLK(NULL, "gpt4_fck", "gpt4_fck"), +	DT_CLK(NULL, "gpt5_ick", "gpt5_ick"), +	DT_CLK(NULL, "gpt5_fck", "gpt5_fck"), +	DT_CLK(NULL, "gpt6_ick", "gpt6_ick"), +	DT_CLK(NULL, "gpt6_fck", "gpt6_fck"), +	DT_CLK(NULL, "gpt7_ick", "gpt7_ick"), +	DT_CLK(NULL, "gpt7_fck", "gpt7_fck"), +	DT_CLK(NULL, "gpt8_ick", "gpt8_ick"), +	DT_CLK(NULL, "gpt8_fck", "gpt8_fck"), +	DT_CLK(NULL, "gpt9_ick", "gpt9_ick"), +	DT_CLK(NULL, "gpt9_fck", "gpt9_fck"), +	DT_CLK(NULL, "gpt10_ick", "gpt10_ick"), +	DT_CLK(NULL, "gpt10_fck", "gpt10_fck"), +	DT_CLK(NULL, "gpt11_ick", "gpt11_ick"), +	DT_CLK(NULL, "gpt11_fck", "gpt11_fck"), +	DT_CLK(NULL, "gpt12_ick", "gpt12_ick"), +	DT_CLK(NULL, "gpt12_fck", "gpt12_fck"), +	DT_CLK("omap-mcbsp.1", "ick", "mcbsp1_ick"), +	DT_CLK(NULL, "mcbsp1_ick", "mcbsp1_ick"), +	DT_CLK(NULL, "mcbsp1_fck", "mcbsp1_fck"), +	DT_CLK("omap-mcbsp.2", "ick", "mcbsp2_ick"), +	DT_CLK(NULL, "mcbsp2_ick", "mcbsp2_ick"), +	DT_CLK(NULL, "mcbsp2_fck", "mcbsp2_fck"), +	DT_CLK("omap2_mcspi.1", "ick", "mcspi1_ick"), +	DT_CLK(NULL, "mcspi1_ick", "mcspi1_ick"), +	DT_CLK(NULL, "mcspi1_fck", "mcspi1_fck"), +	DT_CLK("omap2_mcspi.2", "ick", "mcspi2_ick"), +	DT_CLK(NULL, "mcspi2_ick", "mcspi2_ick"), +	DT_CLK(NULL, "mcspi2_fck", "mcspi2_fck"), +	DT_CLK(NULL, "uart1_ick", "uart1_ick"), +	DT_CLK(NULL, "uart1_fck", "uart1_fck"), +	DT_CLK(NULL, "uart2_ick", "uart2_ick"), +	DT_CLK(NULL, "uart2_fck", "uart2_fck"), +	DT_CLK(NULL, "uart3_ick", "uart3_ick"), +	DT_CLK(NULL, "uart3_fck", "uart3_fck"), +	DT_CLK(NULL, "gpios_ick", "gpios_ick"), +	DT_CLK(NULL, "gpios_fck", "gpios_fck"), +	DT_CLK("omap_wdt", "ick", "mpu_wdt_ick"), +	DT_CLK(NULL, "mpu_wdt_ick", "mpu_wdt_ick"), +	DT_CLK(NULL, "mpu_wdt_fck", "mpu_wdt_fck"), +	DT_CLK(NULL, "sync_32k_ick", "sync_32k_ick"), +	DT_CLK(NULL, "wdt1_ick", "wdt1_ick"), +	DT_CLK(NULL, "omapctrl_ick", "omapctrl_ick"), +	DT_CLK("omap24xxcam", "fck", "cam_fck"), +	DT_CLK(NULL, "cam_fck", "cam_fck"), +	DT_CLK("omap24xxcam", "ick", "cam_ick"), +	DT_CLK(NULL, "cam_ick", "cam_ick"), +	DT_CLK(NULL, "mailboxes_ick", "mailboxes_ick"), +	DT_CLK(NULL, "wdt4_ick", "wdt4_ick"), +	DT_CLK(NULL, "wdt4_fck", "wdt4_fck"), +	DT_CLK(NULL, "mspro_ick", "mspro_ick"), +	DT_CLK(NULL, "mspro_fck", "mspro_fck"), +	DT_CLK(NULL, "fac_ick", "fac_ick"), +	DT_CLK(NULL, "fac_fck", "fac_fck"), +	DT_CLK("omap_hdq.0", "ick", "hdq_ick"), +	DT_CLK(NULL, "hdq_ick", "hdq_ick"), +	DT_CLK("omap_hdq.0", "fck", "hdq_fck"), +	DT_CLK(NULL, "hdq_fck", "hdq_fck"), +	DT_CLK("omap_i2c.1", "ick", "i2c1_ick"), +	DT_CLK(NULL, "i2c1_ick", "i2c1_ick"), +	DT_CLK("omap_i2c.2", "ick", "i2c2_ick"), +	DT_CLK(NULL, "i2c2_ick", "i2c2_ick"), +	DT_CLK(NULL, "gpmc_fck", "gpmc_fck"), +	DT_CLK(NULL, "sdma_fck", "sdma_fck"), +	DT_CLK(NULL, "sdma_ick", "sdma_ick"), +	DT_CLK(NULL, "sdrc_ick", "sdrc_ick"), +	DT_CLK(NULL, "des_ick", "des_ick"), +	DT_CLK("omap-sham", "ick", "sha_ick"), +	DT_CLK(NULL, "sha_ick", "sha_ick"), +	DT_CLK("omap_rng", "ick", "rng_ick"), +	DT_CLK(NULL, "rng_ick", "rng_ick"), +	DT_CLK("omap-aes", "ick", "aes_ick"), +	DT_CLK(NULL, "aes_ick", "aes_ick"), +	DT_CLK(NULL, "pka_ick", "pka_ick"), +	DT_CLK(NULL, "usb_fck", "usb_fck"), +	DT_CLK(NULL, "timer_32k_ck", "func_32k_ck"), +	DT_CLK(NULL, "timer_sys_ck", "sys_ck"), +	DT_CLK(NULL, "timer_ext_ck", "alt_ck"), +	{ .node_name = NULL }, +}; + +static struct ti_dt_clk omap2420_clks[] = { +	DT_CLK(NULL, "sys_clkout2_src", "sys_clkout2_src"), +	DT_CLK(NULL, "sys_clkout2", "sys_clkout2"), +	DT_CLK(NULL, "dsp_ick", "dsp_ick"), +	DT_CLK(NULL, "iva1_ifck", "iva1_ifck"), +	DT_CLK(NULL, "iva1_mpu_int_ifck", "iva1_mpu_int_ifck"), +	DT_CLK(NULL, "wdt3_ick", "wdt3_ick"), +	DT_CLK(NULL, "wdt3_fck", "wdt3_fck"), +	DT_CLK("mmci-omap.0", "ick", "mmc_ick"), +	DT_CLK(NULL, "mmc_ick", "mmc_ick"), +	DT_CLK("mmci-omap.0", "fck", "mmc_fck"), +	DT_CLK(NULL, "mmc_fck", "mmc_fck"), +	DT_CLK(NULL, "eac_ick", "eac_ick"), +	DT_CLK(NULL, "eac_fck", "eac_fck"), +	DT_CLK(NULL, "i2c1_fck", "i2c1_fck"), +	DT_CLK(NULL, "i2c2_fck", "i2c2_fck"), +	DT_CLK(NULL, "vlynq_ick", "vlynq_ick"), +	DT_CLK(NULL, "vlynq_fck", "vlynq_fck"), +	DT_CLK("musb-hdrc", "fck", "osc_ck"), +	{ .node_name = NULL }, +}; + +static struct ti_dt_clk omap2430_clks[] = { +	DT_CLK("twl", "fck", "osc_ck"), +	DT_CLK(NULL, "iva2_1_ick", "iva2_1_ick"), +	DT_CLK(NULL, "mdm_ick", "mdm_ick"), +	DT_CLK(NULL, "mdm_osc_ck", "mdm_osc_ck"), +	DT_CLK("omap-mcbsp.3", "ick", "mcbsp3_ick"), +	DT_CLK(NULL, "mcbsp3_ick", "mcbsp3_ick"), +	DT_CLK(NULL, "mcbsp3_fck", "mcbsp3_fck"), +	DT_CLK("omap-mcbsp.4", "ick", "mcbsp4_ick"), +	DT_CLK(NULL, "mcbsp4_ick", "mcbsp4_ick"), +	DT_CLK(NULL, "mcbsp4_fck", "mcbsp4_fck"), +	DT_CLK("omap-mcbsp.5", "ick", "mcbsp5_ick"), +	DT_CLK(NULL, "mcbsp5_ick", "mcbsp5_ick"), +	DT_CLK(NULL, "mcbsp5_fck", "mcbsp5_fck"), +	DT_CLK("omap2_mcspi.3", "ick", "mcspi3_ick"), +	DT_CLK(NULL, "mcspi3_ick", "mcspi3_ick"), +	DT_CLK(NULL, "mcspi3_fck", "mcspi3_fck"), +	DT_CLK(NULL, "icr_ick", "icr_ick"), +	DT_CLK(NULL, "i2chs1_fck", "i2chs1_fck"), +	DT_CLK(NULL, "i2chs2_fck", "i2chs2_fck"), +	DT_CLK("musb-omap2430", "ick", "usbhs_ick"), +	DT_CLK(NULL, "usbhs_ick", "usbhs_ick"), +	DT_CLK("omap_hsmmc.0", "ick", "mmchs1_ick"), +	DT_CLK(NULL, "mmchs1_ick", "mmchs1_ick"), +	DT_CLK(NULL, "mmchs1_fck", "mmchs1_fck"), +	DT_CLK("omap_hsmmc.1", "ick", "mmchs2_ick"), +	DT_CLK(NULL, "mmchs2_ick", "mmchs2_ick"), +	DT_CLK(NULL, "mmchs2_fck", "mmchs2_fck"), +	DT_CLK(NULL, "gpio5_ick", "gpio5_ick"), +	DT_CLK(NULL, "gpio5_fck", "gpio5_fck"), +	DT_CLK(NULL, "mdm_intc_ick", "mdm_intc_ick"), +	DT_CLK("omap_hsmmc.0", "mmchsdb_fck", "mmchsdb1_fck"), +	DT_CLK(NULL, "mmchsdb1_fck", "mmchsdb1_fck"), +	DT_CLK("omap_hsmmc.1", "mmchsdb_fck", "mmchsdb2_fck"), +	DT_CLK(NULL, "mmchsdb2_fck", "mmchsdb2_fck"), +	{ .node_name = NULL }, +}; + +static const char *enable_init_clks[] = { +	"apll96_ck", +	"apll54_ck", +	"sync_32k_ick", +	"omapctrl_ick", +	"gpmc_fck", +	"sdrc_ick", +}; + +enum { +	OMAP2_SOC_OMAP2420, +	OMAP2_SOC_OMAP2430, +}; + +static int __init omap2xxx_dt_clk_init(int soc_type) +{ +	ti_dt_clocks_register(omap2xxx_clks); + +	if (soc_type == OMAP2_SOC_OMAP2420) +		ti_dt_clocks_register(omap2420_clks); +	else +		ti_dt_clocks_register(omap2430_clks); + +	omap2xxx_clkt_vps_init(); + +	omap2_clk_disable_autoidle_all(); + +	omap2_clk_enable_init_clocks(enable_init_clks, +				     ARRAY_SIZE(enable_init_clks)); + +	pr_info("Clocking rate (Crystal/DPLL/MPU): %ld.%01ld/%ld/%ld MHz\n", +		(clk_get_rate(clk_get_sys(NULL, "sys_ck")) / 1000000), +		(clk_get_rate(clk_get_sys(NULL, "sys_ck")) / 100000) % 10, +		(clk_get_rate(clk_get_sys(NULL, "dpll_ck")) / 1000000), +		(clk_get_rate(clk_get_sys(NULL, "mpu_ck")) / 1000000)); + +	return 0; +} + +int __init omap2420_dt_clk_init(void) +{ +	return omap2xxx_dt_clk_init(OMAP2_SOC_OMAP2420); +} + +int __init omap2430_dt_clk_init(void) +{ +	return omap2xxx_dt_clk_init(OMAP2_SOC_OMAP2430); +} diff --git a/drivers/clk/ti/clk-54xx.c b/drivers/clk/ti/clk-54xx.c index 08f3d1b915b3..5e183993e3ec 100644 --- a/drivers/clk/ti/clk-54xx.c +++ b/drivers/clk/ti/clk-54xx.c @@ -240,6 +240,12 @@ int __init omap5xxx_dt_clk_init(void)  	if (rc)  		pr_err("%s: failed to configure ABE DPLL!\n", __func__); +	abe_dpll = clk_get_sys(NULL, "dpll_abe_m2x2_ck"); +	if (!rc) +		rc = clk_set_rate(abe_dpll, OMAP5_DPLL_ABE_DEFFREQ * 2); +	if (rc) +		pr_err("%s: failed to configure ABE m2x2 DPLL!\n", __func__); +  	usb_dpll = clk_get_sys(NULL, "dpll_usb_ck");  	rc = clk_set_rate(usb_dpll, OMAP5_DPLL_USB_DEFFREQ);  	if (rc) diff --git a/drivers/clk/ti/clk-7xx.c b/drivers/clk/ti/clk-7xx.c index f7e40734c819..e1581335937d 100644 --- a/drivers/clk/ti/clk-7xx.c +++ b/drivers/clk/ti/clk-7xx.c @@ -24,7 +24,7 @@ static struct ti_dt_clk dra7xx_clks[] = {  	DT_CLK(NULL, "atl_clkin0_ck", "atl_clkin0_ck"),  	DT_CLK(NULL, "atl_clkin1_ck", "atl_clkin1_ck"),  	DT_CLK(NULL, "atl_clkin2_ck", "atl_clkin2_ck"), -	DT_CLK(NULL, "atlclkin3_ck", "atlclkin3_ck"), +	DT_CLK(NULL, "atl_clkin3_ck", "atl_clkin3_ck"),  	DT_CLK(NULL, "hdmi_clkin_ck", "hdmi_clkin_ck"),  	DT_CLK(NULL, "mlb_clkin_ck", "mlb_clkin_ck"),  	DT_CLK(NULL, "mlbp_clkin_ck", "mlbp_clkin_ck"), diff --git a/drivers/clk/ti/clk-dra7-atl.c b/drivers/clk/ti/clk-dra7-atl.c new file mode 100644 index 000000000000..4a65b410e4d5 --- /dev/null +++ b/drivers/clk/ti/clk-dra7-atl.c @@ -0,0 +1,312 @@ +/* + * DRA7 ATL (Audio Tracking Logic) clock driver + * + * Copyright (C) 2013 Texas Instruments, Inc. + * + * Peter Ujfalusi <peter.ujfalusi@ti.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + */ + +#include <linux/module.h> +#include <linux/clk-provider.h> +#include <linux/slab.h> +#include <linux/io.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/platform_device.h> +#include <linux/pm_runtime.h> + +#define DRA7_ATL_INSTANCES	4 + +#define DRA7_ATL_PPMR_REG(id)		(0x200 + (id * 0x80)) +#define DRA7_ATL_BBSR_REG(id)		(0x204 + (id * 0x80)) +#define DRA7_ATL_ATLCR_REG(id)		(0x208 + (id * 0x80)) +#define DRA7_ATL_SWEN_REG(id)		(0x210 + (id * 0x80)) +#define DRA7_ATL_BWSMUX_REG(id)		(0x214 + (id * 0x80)) +#define DRA7_ATL_AWSMUX_REG(id)		(0x218 + (id * 0x80)) +#define DRA7_ATL_PCLKMUX_REG(id)	(0x21c + (id * 0x80)) + +#define DRA7_ATL_SWEN			BIT(0) +#define DRA7_ATL_DIVIDER_MASK		(0x1f) +#define DRA7_ATL_PCLKMUX		BIT(0) +struct dra7_atl_clock_info; + +struct dra7_atl_desc { +	struct clk *clk; +	struct clk_hw hw; +	struct dra7_atl_clock_info *cinfo; +	int id; + +	bool probed;		/* the driver for the IP has been loaded */ +	bool valid;		/* configured */ +	bool enabled; +	u32 bws;		/* Baseband Word Select Mux */ +	u32 aws;		/* Audio Word Select Mux */ +	u32 divider;		/* Cached divider value */ +}; + +struct dra7_atl_clock_info { +	struct device *dev; +	void __iomem *iobase; + +	struct dra7_atl_desc *cdesc; +}; + +#define to_atl_desc(_hw)	container_of(_hw, struct dra7_atl_desc, hw) + +static inline void atl_write(struct dra7_atl_clock_info *cinfo, u32 reg, +			     u32 val) +{ +	__raw_writel(val, cinfo->iobase + reg); +} + +static inline int atl_read(struct dra7_atl_clock_info *cinfo, u32 reg) +{ +	return __raw_readl(cinfo->iobase + reg); +} + +static int atl_clk_enable(struct clk_hw *hw) +{ +	struct dra7_atl_desc *cdesc = to_atl_desc(hw); + +	if (!cdesc->probed) +		goto out; + +	if (unlikely(!cdesc->valid)) +		dev_warn(cdesc->cinfo->dev, "atl%d has not been configured\n", +			 cdesc->id); +	pm_runtime_get_sync(cdesc->cinfo->dev); + +	atl_write(cdesc->cinfo, DRA7_ATL_ATLCR_REG(cdesc->id), +		  cdesc->divider - 1); +	atl_write(cdesc->cinfo, DRA7_ATL_SWEN_REG(cdesc->id), DRA7_ATL_SWEN); + +out: +	cdesc->enabled = true; + +	return 0; +} + +static void atl_clk_disable(struct clk_hw *hw) +{ +	struct dra7_atl_desc *cdesc = to_atl_desc(hw); + +	if (!cdesc->probed) +		goto out; + +	atl_write(cdesc->cinfo, DRA7_ATL_SWEN_REG(cdesc->id), 0); +	pm_runtime_put_sync(cdesc->cinfo->dev); + +out: +	cdesc->enabled = false; +} + +static int atl_clk_is_enabled(struct clk_hw *hw) +{ +	struct dra7_atl_desc *cdesc = to_atl_desc(hw); + +	return cdesc->enabled; +} + +static unsigned long atl_clk_recalc_rate(struct clk_hw *hw, +					 unsigned long parent_rate) +{ +	struct dra7_atl_desc *cdesc = to_atl_desc(hw); + +	return parent_rate / cdesc->divider; +} + +static long atl_clk_round_rate(struct clk_hw *hw, unsigned long rate, +			       unsigned long *parent_rate) +{ +	unsigned divider; + +	divider = (*parent_rate + rate / 2) / rate; +	if (divider > DRA7_ATL_DIVIDER_MASK + 1) +		divider = DRA7_ATL_DIVIDER_MASK + 1; + +	return *parent_rate / divider; +} + +static int atl_clk_set_rate(struct clk_hw *hw, unsigned long rate, +			    unsigned long parent_rate) +{ +	struct dra7_atl_desc *cdesc = to_atl_desc(hw); +	u32 divider; + +	divider = ((parent_rate + rate / 2) / rate) - 1; +	if (divider > DRA7_ATL_DIVIDER_MASK) +		divider = DRA7_ATL_DIVIDER_MASK; + +	cdesc->divider = divider + 1; + +	return 0; +} + +const struct clk_ops atl_clk_ops = { +	.enable		= atl_clk_enable, +	.disable	= atl_clk_disable, +	.is_enabled	= atl_clk_is_enabled, +	.recalc_rate	= atl_clk_recalc_rate, +	.round_rate	= atl_clk_round_rate, +	.set_rate	= atl_clk_set_rate, +}; + +static void __init of_dra7_atl_clock_setup(struct device_node *node) +{ +	struct dra7_atl_desc *clk_hw = NULL; +	struct clk_init_data init = { 0 }; +	const char **parent_names = NULL; +	struct clk *clk; + +	clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL); +	if (!clk_hw) { +		pr_err("%s: could not allocate dra7_atl_desc\n", __func__); +		return; +	} + +	clk_hw->hw.init = &init; +	clk_hw->divider = 1; +	init.name = node->name; +	init.ops = &atl_clk_ops; +	init.flags = CLK_IGNORE_UNUSED; +	init.num_parents = of_clk_get_parent_count(node); + +	if (init.num_parents != 1) { +		pr_err("%s: atl clock %s must have 1 parent\n", __func__, +		       node->name); +		goto cleanup; +	} + +	parent_names = kzalloc(sizeof(char *), GFP_KERNEL); + +	if (!parent_names) +		goto cleanup; + +	parent_names[0] = of_clk_get_parent_name(node, 0); + +	init.parent_names = parent_names; + +	clk = clk_register(NULL, &clk_hw->hw); + +	if (!IS_ERR(clk)) { +		of_clk_add_provider(node, of_clk_src_simple_get, clk); +		return; +	} +cleanup: +	kfree(parent_names); +	kfree(clk_hw); +} +CLK_OF_DECLARE(dra7_atl_clock, "ti,dra7-atl-clock", of_dra7_atl_clock_setup); + +static int of_dra7_atl_clk_probe(struct platform_device *pdev) +{ +	struct device_node *node = pdev->dev.of_node; +	struct dra7_atl_clock_info *cinfo; +	int i; +	int ret = 0; + +	if (!node) +		return -ENODEV; + +	cinfo = devm_kzalloc(&pdev->dev, sizeof(*cinfo), GFP_KERNEL); +	if (!cinfo) +		return -ENOMEM; + +	cinfo->iobase = of_iomap(node, 0); +	cinfo->dev = &pdev->dev; +	pm_runtime_enable(cinfo->dev); + +	pm_runtime_get_sync(cinfo->dev); +	atl_write(cinfo, DRA7_ATL_PCLKMUX_REG(0), DRA7_ATL_PCLKMUX); + +	for (i = 0; i < DRA7_ATL_INSTANCES; i++) { +		struct device_node *cfg_node; +		char prop[5]; +		struct dra7_atl_desc *cdesc; +		struct of_phandle_args clkspec; +		struct clk *clk; +		int rc; + +		rc = of_parse_phandle_with_args(node, "ti,provided-clocks", +						NULL, i, &clkspec); + +		if (rc) { +			pr_err("%s: failed to lookup atl clock %d\n", __func__, +			       i); +			return -EINVAL; +		} + +		clk = of_clk_get_from_provider(&clkspec); + +		cdesc = to_atl_desc(__clk_get_hw(clk)); +		cdesc->cinfo = cinfo; +		cdesc->id = i; + +		/* Get configuration for the ATL instances */ +		snprintf(prop, sizeof(prop), "atl%u", i); +		cfg_node = of_find_node_by_name(node, prop); +		if (cfg_node) { +			ret = of_property_read_u32(cfg_node, "bws", +						   &cdesc->bws); +			ret |= of_property_read_u32(cfg_node, "aws", +						    &cdesc->aws); +			if (!ret) { +				cdesc->valid = true; +				atl_write(cinfo, DRA7_ATL_BWSMUX_REG(i), +					  cdesc->bws); +				atl_write(cinfo, DRA7_ATL_AWSMUX_REG(i), +					  cdesc->aws); +			} +		} + +		cdesc->probed = true; +		/* +		 * Enable the clock if it has been asked prior to loading the +		 * hw driver +		 */ +		if (cdesc->enabled) +			atl_clk_enable(__clk_get_hw(clk)); +	} +	pm_runtime_put_sync(cinfo->dev); + +	return ret; +} + +static int of_dra7_atl_clk_remove(struct platform_device *pdev) +{ +	pm_runtime_disable(&pdev->dev); + +	return 0; +} + +static struct of_device_id of_dra7_atl_clk_match_tbl[] = { +	{ .compatible = "ti,dra7-atl", }, +	{}, +}; +MODULE_DEVICE_TABLE(of, of_dra7_atl_clk_match_tbl); + +static struct platform_driver dra7_atl_clk_driver = { +	.driver = { +		.name = "dra7-atl", +		.owner = THIS_MODULE, +		.of_match_table = of_dra7_atl_clk_match_tbl, +	}, +	.probe = of_dra7_atl_clk_probe, +	.remove = of_dra7_atl_clk_remove, +}; + +module_platform_driver(dra7_atl_clk_driver); + +MODULE_DESCRIPTION("Clock driver for DRA7 Audio Tracking Logic"); +MODULE_ALIAS("platform:dra7-atl-clock"); +MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/ti/dpll.c b/drivers/clk/ti/dpll.c index 7e498a44f97d..abd956d5f838 100644 --- a/drivers/clk/ti/dpll.c +++ b/drivers/clk/ti/dpll.c @@ -25,8 +25,6 @@  #undef pr_fmt  #define pr_fmt(fmt) "%s: " fmt, __func__ -#define DPLL_HAS_AUTOIDLE	0x1 -  #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \  	defined(CONFIG_SOC_DRA7XX)  static const struct clk_ops dpll_m4xen_ck_ops = { @@ -37,21 +35,18 @@ static const struct clk_ops dpll_m4xen_ck_ops = {  	.set_rate	= &omap3_noncore_dpll_set_rate,  	.get_parent	= &omap2_init_dpll_parent,  }; +#else +static const struct clk_ops dpll_m4xen_ck_ops = {};  #endif +#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) || \ +	defined(CONFIG_SOC_OMAP5) || defined(CONFIG_SOC_DRA7XX) || \ +	defined(CONFIG_SOC_AM33XX) || defined(CONFIG_SOC_AM43XX)  static const struct clk_ops dpll_core_ck_ops = {  	.recalc_rate	= &omap3_dpll_recalc,  	.get_parent	= &omap2_init_dpll_parent,  }; -#ifdef CONFIG_ARCH_OMAP3 -static const struct clk_ops omap3_dpll_core_ck_ops = { -	.get_parent	= &omap2_init_dpll_parent, -	.recalc_rate	= &omap3_dpll_recalc, -	.round_rate	= &omap2_dpll_round_rate, -}; -#endif -  static const struct clk_ops dpll_ck_ops = {  	.enable		= &omap3_noncore_dpll_enable,  	.disable	= &omap3_noncore_dpll_disable, @@ -67,6 +62,33 @@ static const struct clk_ops dpll_no_gate_ck_ops = {  	.round_rate	= &omap2_dpll_round_rate,  	.set_rate	= &omap3_noncore_dpll_set_rate,  }; +#else +static const struct clk_ops dpll_core_ck_ops = {}; +static const struct clk_ops dpll_ck_ops = {}; +static const struct clk_ops dpll_no_gate_ck_ops = {}; +const struct clk_hw_omap_ops clkhwops_omap3_dpll = {}; +#endif + +#ifdef CONFIG_ARCH_OMAP2 +static const struct clk_ops omap2_dpll_core_ck_ops = { +	.get_parent	= &omap2_init_dpll_parent, +	.recalc_rate	= &omap2_dpllcore_recalc, +	.round_rate	= &omap2_dpll_round_rate, +	.set_rate	= &omap2_reprogram_dpllcore, +}; +#else +static const struct clk_ops omap2_dpll_core_ck_ops = {}; +#endif + +#ifdef CONFIG_ARCH_OMAP3 +static const struct clk_ops omap3_dpll_core_ck_ops = { +	.get_parent	= &omap2_init_dpll_parent, +	.recalc_rate	= &omap3_dpll_recalc, +	.round_rate	= &omap2_dpll_round_rate, +}; +#else +static const struct clk_ops omap3_dpll_core_ck_ops = {}; +#endif  #ifdef CONFIG_ARCH_OMAP3  static const struct clk_ops omap3_dpll_ck_ops = { @@ -193,14 +215,12 @@ static void ti_clk_register_dpll_x2(struct device_node *node,   * @node: device node containing the DPLL info   * @ops: ops for the DPLL   * @ddt: DPLL data template to use - * @init_flags: flags for controlling init types   *   * Initializes a DPLL clock from device tree data.   */  static void __init of_ti_dpll_setup(struct device_node *node,  				    const struct clk_ops *ops, -				    const struct dpll_data *ddt, -				    u8 init_flags) +				    const struct dpll_data *ddt)  {  	struct clk_hw_omap *clk_hw = NULL;  	struct clk_init_data *init = NULL; @@ -241,13 +261,30 @@ static void __init of_ti_dpll_setup(struct device_node *node,  	init->parent_names = parent_names;  	dd->control_reg = ti_clk_get_reg_addr(node, 0); -	dd->idlest_reg = ti_clk_get_reg_addr(node, 1); -	dd->mult_div1_reg = ti_clk_get_reg_addr(node, 2); -	if (!dd->control_reg || !dd->idlest_reg || !dd->mult_div1_reg) +	/* +	 * Special case for OMAP2 DPLL, register order is different due to +	 * missing idlest_reg, also clkhwops is different. Detected from +	 * missing idlest_mask. +	 */ +	if (!dd->idlest_mask) { +		dd->mult_div1_reg = ti_clk_get_reg_addr(node, 1); +#ifdef CONFIG_ARCH_OMAP2 +		clk_hw->ops = &clkhwops_omap2xxx_dpll; +		omap2xxx_clkt_dpllcore_init(&clk_hw->hw); +#endif +	} else { +		dd->idlest_reg = ti_clk_get_reg_addr(node, 1); +		if (!dd->idlest_reg) +			goto cleanup; + +		dd->mult_div1_reg = ti_clk_get_reg_addr(node, 2); +	} + +	if (!dd->control_reg || !dd->mult_div1_reg)  		goto cleanup; -	if (init_flags & DPLL_HAS_AUTOIDLE) { +	if (dd->autoidle_mask) {  		dd->autoidle_reg = ti_clk_get_reg_addr(node, 3);  		if (!dd->autoidle_reg)  			goto cleanup; @@ -310,7 +347,7 @@ static void __init of_ti_omap3_dpll_setup(struct device_node *node)  		.modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),  	}; -	of_ti_dpll_setup(node, &omap3_dpll_ck_ops, &dd, DPLL_HAS_AUTOIDLE); +	of_ti_dpll_setup(node, &omap3_dpll_ck_ops, &dd);  }  CLK_OF_DECLARE(ti_omap3_dpll_clock, "ti,omap3-dpll-clock",  	       of_ti_omap3_dpll_setup); @@ -329,7 +366,7 @@ static void __init of_ti_omap3_core_dpll_setup(struct device_node *node)  		.freqsel_mask = 0xf0,  	}; -	of_ti_dpll_setup(node, &omap3_dpll_core_ck_ops, &dd, DPLL_HAS_AUTOIDLE); +	of_ti_dpll_setup(node, &omap3_dpll_core_ck_ops, &dd);  }  CLK_OF_DECLARE(ti_omap3_core_dpll_clock, "ti,omap3-dpll-core-clock",  	       of_ti_omap3_core_dpll_setup); @@ -349,7 +386,7 @@ static void __init of_ti_omap3_per_dpll_setup(struct device_node *node)  		.modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED),  	}; -	of_ti_dpll_setup(node, &omap3_dpll_per_ck_ops, &dd, DPLL_HAS_AUTOIDLE); +	of_ti_dpll_setup(node, &omap3_dpll_per_ck_ops, &dd);  }  CLK_OF_DECLARE(ti_omap3_per_dpll_clock, "ti,omap3-dpll-per-clock",  	       of_ti_omap3_per_dpll_setup); @@ -371,7 +408,7 @@ static void __init of_ti_omap3_per_jtype_dpll_setup(struct device_node *node)  		.modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED),  	}; -	of_ti_dpll_setup(node, &omap3_dpll_per_ck_ops, &dd, DPLL_HAS_AUTOIDLE); +	of_ti_dpll_setup(node, &omap3_dpll_per_ck_ops, &dd);  }  CLK_OF_DECLARE(ti_omap3_per_jtype_dpll_clock, "ti,omap3-dpll-per-j-type-clock",  	       of_ti_omap3_per_jtype_dpll_setup); @@ -391,11 +428,32 @@ static void __init of_ti_omap4_dpll_setup(struct device_node *node)  		.modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),  	}; -	of_ti_dpll_setup(node, &dpll_ck_ops, &dd, DPLL_HAS_AUTOIDLE); +	of_ti_dpll_setup(node, &dpll_ck_ops, &dd);  }  CLK_OF_DECLARE(ti_omap4_dpll_clock, "ti,omap4-dpll-clock",  	       of_ti_omap4_dpll_setup); +static void __init of_ti_omap5_mpu_dpll_setup(struct device_node *node) +{ +	const struct dpll_data dd = { +		.idlest_mask = 0x1, +		.enable_mask = 0x7, +		.autoidle_mask = 0x7, +		.mult_mask = 0x7ff << 8, +		.div1_mask = 0x7f, +		.max_multiplier = 2047, +		.max_divider = 128, +		.dcc_mask = BIT(22), +		.dcc_rate = 1400000000, /* DCC beyond 1.4GHz */ +		.min_divider = 1, +		.modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), +	}; + +	of_ti_dpll_setup(node, &dpll_ck_ops, &dd); +} +CLK_OF_DECLARE(of_ti_omap5_mpu_dpll_clock, "ti,omap5-mpu-dpll-clock", +	       of_ti_omap5_mpu_dpll_setup); +  static void __init of_ti_omap4_core_dpll_setup(struct device_node *node)  {  	const struct dpll_data dd = { @@ -410,7 +468,7 @@ static void __init of_ti_omap4_core_dpll_setup(struct device_node *node)  		.modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),  	}; -	of_ti_dpll_setup(node, &dpll_core_ck_ops, &dd, DPLL_HAS_AUTOIDLE); +	of_ti_dpll_setup(node, &dpll_core_ck_ops, &dd);  }  CLK_OF_DECLARE(ti_omap4_core_dpll_clock, "ti,omap4-dpll-core-clock",  	       of_ti_omap4_core_dpll_setup); @@ -433,7 +491,7 @@ static void __init of_ti_omap4_m4xen_dpll_setup(struct device_node *node)  		.modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),  	}; -	of_ti_dpll_setup(node, &dpll_m4xen_ck_ops, &dd, DPLL_HAS_AUTOIDLE); +	of_ti_dpll_setup(node, &dpll_m4xen_ck_ops, &dd);  }  CLK_OF_DECLARE(ti_omap4_m4xen_dpll_clock, "ti,omap4-dpll-m4xen-clock",  	       of_ti_omap4_m4xen_dpll_setup); @@ -454,7 +512,7 @@ static void __init of_ti_omap4_jtype_dpll_setup(struct device_node *node)  		.modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),  	}; -	of_ti_dpll_setup(node, &dpll_m4xen_ck_ops, &dd, DPLL_HAS_AUTOIDLE); +	of_ti_dpll_setup(node, &dpll_m4xen_ck_ops, &dd);  }  CLK_OF_DECLARE(ti_omap4_jtype_dpll_clock, "ti,omap4-dpll-j-type-clock",  	       of_ti_omap4_jtype_dpll_setup); @@ -465,7 +523,6 @@ static void __init of_ti_am3_no_gate_dpll_setup(struct device_node *node)  	const struct dpll_data dd = {  		.idlest_mask = 0x1,  		.enable_mask = 0x7, -		.autoidle_mask = 0x7,  		.mult_mask = 0x7ff << 8,  		.div1_mask = 0x7f,  		.max_multiplier = 2047, @@ -474,7 +531,7 @@ static void __init of_ti_am3_no_gate_dpll_setup(struct device_node *node)  		.modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),  	}; -	of_ti_dpll_setup(node, &dpll_no_gate_ck_ops, &dd, 0); +	of_ti_dpll_setup(node, &dpll_no_gate_ck_ops, &dd);  }  CLK_OF_DECLARE(ti_am3_no_gate_dpll_clock, "ti,am3-dpll-no-gate-clock",  	       of_ti_am3_no_gate_dpll_setup); @@ -484,7 +541,6 @@ static void __init of_ti_am3_jtype_dpll_setup(struct device_node *node)  	const struct dpll_data dd = {  		.idlest_mask = 0x1,  		.enable_mask = 0x7, -		.autoidle_mask = 0x7,  		.mult_mask = 0x7ff << 8,  		.div1_mask = 0x7f,  		.max_multiplier = 4095, @@ -494,7 +550,7 @@ static void __init of_ti_am3_jtype_dpll_setup(struct device_node *node)  		.modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),  	}; -	of_ti_dpll_setup(node, &dpll_ck_ops, &dd, 0); +	of_ti_dpll_setup(node, &dpll_ck_ops, &dd);  }  CLK_OF_DECLARE(ti_am3_jtype_dpll_clock, "ti,am3-dpll-j-type-clock",  	       of_ti_am3_jtype_dpll_setup); @@ -504,7 +560,6 @@ static void __init of_ti_am3_no_gate_jtype_dpll_setup(struct device_node *node)  	const struct dpll_data dd = {  		.idlest_mask = 0x1,  		.enable_mask = 0x7, -		.autoidle_mask = 0x7,  		.mult_mask = 0x7ff << 8,  		.div1_mask = 0x7f,  		.max_multiplier = 2047, @@ -514,7 +569,7 @@ static void __init of_ti_am3_no_gate_jtype_dpll_setup(struct device_node *node)  		.modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),  	}; -	of_ti_dpll_setup(node, &dpll_no_gate_ck_ops, &dd, 0); +	of_ti_dpll_setup(node, &dpll_no_gate_ck_ops, &dd);  }  CLK_OF_DECLARE(ti_am3_no_gate_jtype_dpll_clock,  	       "ti,am3-dpll-no-gate-j-type-clock", @@ -525,7 +580,6 @@ static void __init of_ti_am3_dpll_setup(struct device_node *node)  	const struct dpll_data dd = {  		.idlest_mask = 0x1,  		.enable_mask = 0x7, -		.autoidle_mask = 0x7,  		.mult_mask = 0x7ff << 8,  		.div1_mask = 0x7f,  		.max_multiplier = 2047, @@ -534,7 +588,7 @@ static void __init of_ti_am3_dpll_setup(struct device_node *node)  		.modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),  	}; -	of_ti_dpll_setup(node, &dpll_ck_ops, &dd, 0); +	of_ti_dpll_setup(node, &dpll_ck_ops, &dd);  }  CLK_OF_DECLARE(ti_am3_dpll_clock, "ti,am3-dpll-clock", of_ti_am3_dpll_setup); @@ -543,7 +597,6 @@ static void __init of_ti_am3_core_dpll_setup(struct device_node *node)  	const struct dpll_data dd = {  		.idlest_mask = 0x1,  		.enable_mask = 0x7, -		.autoidle_mask = 0x7,  		.mult_mask = 0x7ff << 8,  		.div1_mask = 0x7f,  		.max_multiplier = 2047, @@ -552,7 +605,22 @@ static void __init of_ti_am3_core_dpll_setup(struct device_node *node)  		.modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),  	}; -	of_ti_dpll_setup(node, &dpll_core_ck_ops, &dd, 0); +	of_ti_dpll_setup(node, &dpll_core_ck_ops, &dd);  }  CLK_OF_DECLARE(ti_am3_core_dpll_clock, "ti,am3-dpll-core-clock",  	       of_ti_am3_core_dpll_setup); + +static void __init of_ti_omap2_core_dpll_setup(struct device_node *node) +{ +	const struct dpll_data dd = { +		.enable_mask = 0x3, +		.mult_mask = 0x3ff << 12, +		.div1_mask = 0xf << 8, +		.max_divider = 16, +		.min_divider = 1, +	}; + +	of_ti_dpll_setup(node, &omap2_dpll_core_ck_ops, &dd); +} +CLK_OF_DECLARE(ti_omap2_core_dpll_clock, "ti,omap2-dpll-core-clock", +	       of_ti_omap2_core_dpll_setup); diff --git a/drivers/clk/ti/gate.c b/drivers/clk/ti/gate.c index 58734817d502..b326d2797feb 100644 --- a/drivers/clk/ti/gate.c +++ b/drivers/clk/ti/gate.c @@ -185,7 +185,7 @@ of_ti_composite_no_wait_gate_clk_setup(struct device_node *node)  CLK_OF_DECLARE(ti_composite_no_wait_gate_clk, "ti,composite-no-wait-gate-clock",  	       of_ti_composite_no_wait_gate_clk_setup); -#ifdef CONFIG_ARCH_OMAP3 +#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)  static void __init of_ti_composite_interface_clk_setup(struct device_node *node)  {  	_of_ti_composite_gate_clk_setup(node, &clkhwops_iclk_wait); diff --git a/drivers/clk/ti/interface.c b/drivers/clk/ti/interface.c index 320a2b168bb2..9c3e8c4aaa40 100644 --- a/drivers/clk/ti/interface.c +++ b/drivers/clk/ti/interface.c @@ -94,6 +94,7 @@ static void __init of_ti_no_wait_interface_clk_setup(struct device_node *node)  CLK_OF_DECLARE(ti_no_wait_interface_clk, "ti,omap3-no-wait-interface-clock",  	       of_ti_no_wait_interface_clk_setup); +#ifdef CONFIG_ARCH_OMAP3  static void __init of_ti_hsotgusb_interface_clk_setup(struct device_node *node)  {  	_of_ti_interface_clk_setup(node, @@ -123,3 +124,13 @@ static void __init of_ti_am35xx_interface_clk_setup(struct device_node *node)  }  CLK_OF_DECLARE(ti_am35xx_interface_clk, "ti,am35xx-interface-clock",  	       of_ti_am35xx_interface_clk_setup); +#endif + +#ifdef CONFIG_SOC_OMAP2430 +static void __init of_ti_omap2430_interface_clk_setup(struct device_node *node) +{ +	_of_ti_interface_clk_setup(node, &clkhwops_omap2430_i2chs_wait); +} +CLK_OF_DECLARE(ti_omap2430_interface_clk, "ti,omap2430-interface-clock", +	       of_ti_omap2430_interface_clk_setup); +#endif diff --git a/include/dt-bindings/clk/ti-dra7-atl.h b/include/dt-bindings/clk/ti-dra7-atl.h new file mode 100644 index 000000000000..42dd4164f6f4 --- /dev/null +++ b/include/dt-bindings/clk/ti-dra7-atl.h @@ -0,0 +1,40 @@ +/* + * This header provides constants for DRA7 ATL (Audio Tracking Logic) + * + * The constants defined in this header are used in dts files + * + * Copyright (C) 2013 Texas Instruments, Inc. + * + * Peter Ujfalusi <peter.ujfalusi@ti.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + */ + +#ifndef _DT_BINDINGS_CLK_DRA7_ATL_H +#define _DT_BINDINGS_CLK_DRA7_ATL_H + +#define DRA7_ATL_WS_MCASP1_FSR		0 +#define DRA7_ATL_WS_MCASP1_FSX		1 +#define DRA7_ATL_WS_MCASP2_FSR		2 +#define DRA7_ATL_WS_MCASP2_FSX		3 +#define DRA7_ATL_WS_MCASP3_FSX		4 +#define DRA7_ATL_WS_MCASP4_FSX		5 +#define DRA7_ATL_WS_MCASP5_FSX		6 +#define DRA7_ATL_WS_MCASP6_FSX		7 +#define DRA7_ATL_WS_MCASP7_FSX		8 +#define DRA7_ATL_WS_MCASP8_FSX		9 +#define DRA7_ATL_WS_MCASP8_AHCLKX	10 +#define DRA7_ATL_WS_XREF_CLK3		11 +#define DRA7_ATL_WS_XREF_CLK0		12 +#define DRA7_ATL_WS_XREF_CLK1		13 +#define DRA7_ATL_WS_XREF_CLK2		14 +#define DRA7_ATL_WS_OSC1_X1		15 + +#endif diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h index 4a21a872dbbd..e8d8a35034a5 100644 --- a/include/linux/clk/ti.h +++ b/include/linux/clk/ti.h @@ -41,6 +41,8 @@   * @idlest_reg: register containing the DPLL idle status bitfield   * @autoidle_mask: mask of the DPLL autoidle mode bitfield in @autoidle_reg   * @freqsel_mask: mask of the DPLL jitter correction bitfield in @control_reg + * @dcc_mask: mask of the DPLL DCC correction bitfield @mult_div1_reg + * @dcc_rate: rate atleast which DCC @dcc_mask must be set   * @idlest_mask: mask of the DPLL idle status bitfield in @idlest_reg   * @lpmode_mask: mask of the DPLL low-power mode bitfield in @control_reg   * @m4xen_mask: mask of the DPLL M4X multiplier bitfield in @control_reg @@ -86,6 +88,8 @@ struct dpll_data {  	u32			idlest_mask;  	u32			dco_mask;  	u32			sddiv_mask; +	u32			dcc_mask; +	unsigned long		dcc_rate;  	u32			lpmode_mask;  	u32			m4xen_mask;  	u8			auto_recal_bit; @@ -94,7 +98,26 @@ struct dpll_data {  	u8			flags;  }; -struct clk_hw_omap_ops; +struct clk_hw_omap; + +/** + * struct clk_hw_omap_ops - OMAP clk ops + * @find_idlest: find idlest register information for a clock + * @find_companion: find companion clock register information for a clock, + *		    basically converts CM_ICLKEN* <-> CM_FCLKEN* + * @allow_idle: enables autoidle hardware functionality for a clock + * @deny_idle: prevent autoidle hardware functionality for a clock + */ +struct clk_hw_omap_ops { +	void	(*find_idlest)(struct clk_hw_omap *oclk, +			       void __iomem **idlest_reg, +			       u8 *idlest_bit, u8 *idlest_val); +	void	(*find_companion)(struct clk_hw_omap *oclk, +				  void __iomem **other_reg, +				  u8 *other_bit); +	void	(*allow_idle)(struct clk_hw_omap *oclk); +	void	(*deny_idle)(struct clk_hw_omap *oclk); +};  /**   * struct clk_hw_omap - OMAP struct clk @@ -259,6 +282,12 @@ int omap2_dflt_clk_enable(struct clk_hw *hw);  void omap2_dflt_clk_disable(struct clk_hw *hw);  int omap2_dflt_clk_is_enabled(struct clk_hw *hw);  void omap3_clk_lock_dpll5(void); +unsigned long omap2_dpllcore_recalc(struct clk_hw *hw, +				    unsigned long parent_rate); +int omap2_reprogram_dpllcore(struct clk_hw *clk, unsigned long rate, +			     unsigned long parent_rate); +void omap2xxx_clkt_dpllcore_init(struct clk_hw *hw); +void omap2xxx_clkt_vps_init(void);  void __iomem *ti_clk_get_reg_addr(struct device_node *node, int index);  void ti_dt_clocks_register(struct ti_dt_clk *oclks); @@ -278,6 +307,8 @@ int omap5xxx_dt_clk_init(void);  int dra7xx_dt_clk_init(void);  int am33xx_dt_clk_init(void);  int am43xx_dt_clk_init(void); +int omap2420_dt_clk_init(void); +int omap2430_dt_clk_init(void);  #ifdef CONFIG_OF  void of_ti_clk_allow_autoidle_all(void); @@ -287,6 +318,8 @@ static inline void of_ti_clk_allow_autoidle_all(void) { }  static inline void of_ti_clk_deny_autoidle_all(void) { }  #endif +extern const struct clk_hw_omap_ops clkhwops_omap2xxx_dpll; +extern const struct clk_hw_omap_ops clkhwops_omap2430_i2chs_wait;  extern const struct clk_hw_omap_ops clkhwops_omap3_dpll;  extern const struct clk_hw_omap_ops clkhwops_omap4_dpllmx;  extern const struct clk_hw_omap_ops clkhwops_wait; | 
