System timer changes for omaps for v5.8 merge window
This series of changes finally gets the legacy omap dual-mode timer and 32k counter system timer updated to use drivers/clocksource and device tree data. And we can now remove the unused legacy platform data. These changes are based on an immutable clocksource branch set up by Daniel Lezcano. -----BEGIN PGP SIGNATURE----- iQJFBAABCAAvFiEEkgNvrZJU/QSQYIcQG9Q+yVyrpXMFAl7ID2gRHHRvbnlAYXRv bWlkZS5jb20ACgkQG9Q+yVyrpXNgIg//ThhlcPMWT/wDAr2KTZTQ6gMgXyrbGtWT i4y4cGTALFYpHG0Mm9XQnyt8z9s1Ep8ENU8lnF6js/3Izgci3WEvQs92VOYOdzQT 2NZ2nk7s1+kG1j8F3A+rPxYodXA/wR74G+IOFXezsgUwmY8LUaH0PWbQsC8tDYBq 3jRE8v9HlX66yraGlT484xyZp11aYlwkyUA5+Qt/TYutMYNtCJQG4Z7B9dS0dQ+B 6GyWaNg9ksiEy5MmBRRSR3UrFd5rkG6QHrwIZ5t9lFnE+J60B4LFxo98Udr0Upqo TqSke2CpFHtq4xGrq5A+HiVJEs5XTke14GRx8G6agQe5jJns6QPzZvqpzLkAI0A3 vUTcODbwwmewee6GAIGvky0rqT47w5HhYdBI4Fge7yBHW/MZ1HwrnQ8dL99E8dyp ANh1BT/ws+v3VuO/3rSfqlW4v0gjUltHKds33F5uabRSJ8FF2xRl6zPuBQFvXazC z0gadCrlpYMQAmWd9q4znPBnjHGxE0XuPvoDIhN3ALB5T3DEnDb72cuBT1ACPgFC 5lceY08qVhl16hbe1UyRt6rFbs2wpLqpxPZRR4p81MiDvbjHOgnZe0+QWkpmyzL9 bse2rnI+mAZ+gZbFoUD7oyOat5jtH/Y/6VCQao6KPtyL16ft3yk4FrQeUV6enK9C NOQFfSdHpMI= =07SB -----END PGP SIGNATURE----- Merge tag 'omap-for-v5.8/timer-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap into arm/soc System timer changes for omaps for v5.8 merge window This series of changes finally gets the legacy omap dual-mode timer and 32k counter system timer updated to use drivers/clocksource and device tree data. And we can now remove the unused legacy platform data. These changes are based on an immutable clocksource branch set up by Daniel Lezcano. * tag 'omap-for-v5.8/timer-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap: bus: ti-sysc: Timers no longer need legacy quirk handling ARM: OMAP2+: Drop old timer code for dmtimer and 32k counter ARM: dts: Configure system timers for omap2 ARM: dts: Configure system timers for ti81xx ARM: dts: Configure system timers for omap3 ARM: dts: Configure system timers for omap5 and dra7 ARM: dts: Configure system timers for omap4 ARM: dts: Configure system timers for am437x ARM: dts: Configure system timers for am335x ARM: OMAP2+: Add omap_init_time_of() bus: ti-sysc: Ignore timer12 on secure omap3 clk: ti: dm816: enable sysclk6_ck on init clocksource/drivers/timer-ti-dm: Fix warning for set but not used clocksource/drivers/timer-ti-dm: Add clockevent and clocksource support clocksource/drivers/timer-ti-32k: Add support for initializing directly Link: https://lore.kernel.org/r/pull-1590169577-735045@atomide.com Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
		
						commit
						803b504bf5
					
				| @ -330,9 +330,8 @@ | ||||
| 			}; | ||||
| 		}; | ||||
| 
 | ||||
| 		target-module@31000 {			/* 0x44e31000, ap 25 40.0 */ | ||||
| 		timer1_target: target-module@31000 {	/* 0x44e31000, ap 25 40.0 */ | ||||
| 			compatible = "ti,sysc-omap2-timer", "ti,sysc"; | ||||
| 			ti,hwmods = "timer1"; | ||||
| 			reg = <0x31000 0x4>, | ||||
| 			      <0x31010 0x4>, | ||||
| 			      <0x31014 0x4>; | ||||
| @ -1117,9 +1116,8 @@ | ||||
| 			}; | ||||
| 		}; | ||||
| 
 | ||||
| 		target-module@40000 {			/* 0x48040000, ap 22 1e.0 */ | ||||
| 		timer2_target: target-module@40000 {	/* 0x48040000, ap 22 1e.0 */ | ||||
| 			compatible = "ti,sysc-omap4-timer", "ti,sysc"; | ||||
| 			ti,hwmods = "timer2"; | ||||
| 			reg = <0x40000 0x4>, | ||||
| 			      <0x40010 0x4>, | ||||
| 			      <0x40014 0x4>; | ||||
|  | ||||
| @ -619,3 +619,23 @@ | ||||
| 		#reset-cells = <1>; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| /* Preferred always-on timer for clocksource */ | ||||
| &timer1_target { | ||||
| 	ti,no-reset-on-init; | ||||
| 	ti,no-idle; | ||||
| 	timer@0 { | ||||
| 		assigned-clocks = <&timer1_fck>; | ||||
| 		assigned-clock-parents = <&sys_clkin_ck>; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| /* Preferred timer for clockevent */ | ||||
| &timer2_target { | ||||
| 	ti,no-reset-on-init; | ||||
| 	ti,no-idle; | ||||
| 	timer@0 { | ||||
| 		assigned-clocks = <&timer2_fck>; | ||||
| 		assigned-clock-parents = <&sys_clkin_ck>; | ||||
| 	}; | ||||
| }; | ||||
|  | ||||
| @ -169,5 +169,25 @@ | ||||
| 	status = "disabled"; | ||||
| }; | ||||
| 
 | ||||
| /include/ "am35xx-clocks.dtsi" | ||||
| /include/ "omap36xx-am35xx-omap3430es2plus-clocks.dtsi" | ||||
| #include "am35xx-clocks.dtsi" | ||||
| #include "omap36xx-am35xx-omap3430es2plus-clocks.dtsi" | ||||
| 
 | ||||
| /* Preferred always-on timer for clocksource */ | ||||
| &timer1_target { | ||||
| 	ti,no-reset-on-init; | ||||
| 	ti,no-idle; | ||||
| 	timer@0 { | ||||
| 		assigned-clocks = <&gpt1_fck>; | ||||
| 		assigned-clock-parents = <&sys_ck>; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| /* Preferred timer for clockevent */ | ||||
| &timer2_target { | ||||
| 	ti,no-reset-on-init; | ||||
| 	ti,no-idle; | ||||
| 	timer@0 { | ||||
| 		assigned-clocks = <&gpt2_fck>; | ||||
| 		assigned-clock-parents = <&sys_ck>; | ||||
| 	}; | ||||
| }; | ||||
|  | ||||
| @ -553,3 +553,23 @@ | ||||
| 		#reset-cells = <1>; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| /* Preferred always-on timer for clocksource */ | ||||
| &timer1_target { | ||||
| 	ti,no-reset-on-init; | ||||
| 	ti,no-idle; | ||||
| 	timer@0 { | ||||
| 		assigned-clocks = <&timer1_fck>; | ||||
| 		assigned-clock-parents = <&sys_clkin_ck>; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| /* Preferred timer for clockevent */ | ||||
| &timer2_target { | ||||
| 	ti,no-reset-on-init; | ||||
| 	ti,no-idle; | ||||
| 	timer@0 { | ||||
| 		assigned-clocks = <&timer2_fck>; | ||||
| 		assigned-clock-parents = <&sys_clkin_ck>; | ||||
| 	}; | ||||
| }; | ||||
|  | ||||
| @ -328,9 +328,8 @@ | ||||
| 			}; | ||||
| 		}; | ||||
| 
 | ||||
| 		target-module@31000 {			/* 0x44e31000, ap 24 40.0 */ | ||||
| 		timer1_target: target-module@31000 {	/* 0x44e31000, ap 24 40.0 */ | ||||
| 			compatible = "ti,sysc-omap2-timer", "ti,sysc"; | ||||
| 			ti,hwmods = "timer1"; | ||||
| 			reg = <0x31000 0x4>, | ||||
| 			      <0x31010 0x4>, | ||||
| 			      <0x31014 0x4>; | ||||
| @ -450,7 +449,6 @@ | ||||
| 
 | ||||
| 		target-module@86000 {			/* 0x44e86000, ap 40 70.0 */ | ||||
| 			compatible = "ti,sysc-omap2", "ti,sysc"; | ||||
| 			ti,hwmods = "counter_32k"; | ||||
| 			reg = <0x86000 0x4>, | ||||
| 			      <0x86004 0x4>; | ||||
| 			reg-names = "rev", "sysc"; | ||||
| @ -868,9 +866,8 @@ | ||||
| 			}; | ||||
| 		}; | ||||
| 
 | ||||
| 		target-module@40000 {			/* 0x48040000, ap 18 1e.0 */ | ||||
| 		timer2_target: target-module@40000 {	/* 0x48040000, ap 18 1e.0 */ | ||||
| 			compatible = "ti,sysc-omap4-timer", "ti,sysc"; | ||||
| 			ti,hwmods = "timer2"; | ||||
| 			reg = <0x40000 0x4>, | ||||
| 			      <0x40010 0x4>, | ||||
| 			      <0x40014 0x4>; | ||||
|  | ||||
| @ -308,14 +308,30 @@ | ||||
| 				ti,hwmods = "mcspi4"; | ||||
| 			}; | ||||
| 
 | ||||
| 			timer1: timer@2e000 { | ||||
| 				compatible = "ti,dm814-timer"; | ||||
| 				reg = <0x2e000 0x2000>; | ||||
| 				interrupts = <67>; | ||||
| 				ti,hwmods = "timer1"; | ||||
| 				ti,timer-alwon; | ||||
| 			timer1_target: target-module@2e000 { | ||||
| 				compatible = "ti,sysc-omap4-timer", "ti,sysc"; | ||||
| 				reg = <0x2e000 0x4>, | ||||
| 				      <0x2e010 0x4>; | ||||
| 				reg-names = "rev", "sysc"; | ||||
| 				ti,sysc-mask = <SYSC_OMAP4_SOFTRESET>; | ||||
| 				ti,sysc-sidle = <SYSC_IDLE_FORCE>, | ||||
| 						<SYSC_IDLE_NO>, | ||||
| 						<SYSC_IDLE_SMART>, | ||||
| 						<SYSC_IDLE_SMART_WKUP>; | ||||
| 				clocks = <&timer1_fck>; | ||||
| 				clock-names = "fck"; | ||||
| 				#address-cells = <1>; | ||||
| 				#size-cells = <1>; | ||||
| 				ranges = <0x0 0x2e000 0x1000>; | ||||
| 
 | ||||
| 				timer1: timer@0 { | ||||
| 					compatible = "ti,am335x-timer-1ms"; | ||||
| 					reg = <0x0 0x400>; | ||||
| 					interrupts = <67>; | ||||
| 					ti,timer-alwon; | ||||
| 					clocks = <&timer1_fck>; | ||||
| 					clock-names = "fck"; | ||||
| 				}; | ||||
| 			}; | ||||
| 
 | ||||
| 			uart1: uart@20000 { | ||||
| @ -348,13 +364,29 @@ | ||||
| 				dma-names = "tx", "rx"; | ||||
| 			}; | ||||
| 
 | ||||
| 			timer2: timer@40000 { | ||||
| 				compatible = "ti,dm814-timer"; | ||||
| 				reg = <0x40000 0x2000>; | ||||
| 				interrupts = <68>; | ||||
| 				ti,hwmods = "timer2"; | ||||
| 			timer2_target: target-module@40000 { | ||||
| 				compatible = "ti,sysc-omap4-timer", "ti,sysc"; | ||||
| 				reg = <0x40000 0x4>, | ||||
| 				      <0x40010 0x4>; | ||||
| 				reg-names = "rev", "sysc"; | ||||
| 				ti,sysc-mask = <SYSC_OMAP4_SOFTRESET>; | ||||
| 				ti,sysc-sidle = <SYSC_IDLE_FORCE>, | ||||
| 						<SYSC_IDLE_NO>, | ||||
| 						<SYSC_IDLE_SMART>, | ||||
| 						<SYSC_IDLE_SMART_WKUP>; | ||||
| 				clocks = <&timer2_fck>; | ||||
| 				clock-names = "fck"; | ||||
| 				#address-cells = <1>; | ||||
| 				#size-cells = <1>; | ||||
| 				ranges = <0x0 0x40000 0x1000>; | ||||
| 
 | ||||
| 				timer2: timer@0 { | ||||
| 					compatible = "ti,dm814-timer"; | ||||
| 					reg = <0 0x1000>; | ||||
| 					interrupts = <68>; | ||||
| 					clocks = <&timer2_fck>; | ||||
| 					clock-names = "fck"; | ||||
| 				}; | ||||
| 			}; | ||||
| 
 | ||||
| 			timer3: timer@42000 { | ||||
| @ -735,3 +767,23 @@ | ||||
| }; | ||||
| 
 | ||||
| #include "dm814x-clocks.dtsi" | ||||
| 
 | ||||
| /* Preferred always-on timer for clocksource */ | ||||
| &timer1_target { | ||||
| 	ti,no-reset-on-init; | ||||
| 	ti,no-idle; | ||||
| 	timer@0 { | ||||
| 		assigned-clocks = <&timer1_fck>; | ||||
| 		assigned-clock-parents = <&devosc_ck>; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| /* Preferred timer for clockevent */ | ||||
| &timer2_target { | ||||
| 	ti,no-reset-on-init; | ||||
| 	ti,no-idle; | ||||
| 	timer@0 { | ||||
| 		assigned-clocks = <&timer2_fck>; | ||||
| 		assigned-clock-parents = <&devosc_ck>; | ||||
| 	}; | ||||
| }; | ||||
|  | ||||
| @ -440,23 +440,55 @@ | ||||
| 			dma-names = "tx", "rx"; | ||||
| 		}; | ||||
| 
 | ||||
| 		timer1: timer@4802e000 { | ||||
| 			compatible = "ti,dm816-timer"; | ||||
| 			reg = <0x4802e000 0x2000>; | ||||
| 			interrupts = <67>; | ||||
| 			ti,hwmods = "timer1"; | ||||
| 			ti,timer-alwon; | ||||
| 			clocks = <&timer1_fck>; | ||||
| 		timer1_target: target-module@4802e000 { | ||||
| 			compatible = "ti,sysc-omap4-timer", "ti,sysc"; | ||||
| 			reg = <0x4802e000 0x4>, | ||||
| 			      <0x4802e010 0x4>; | ||||
| 			reg-names = "rev", "sysc"; | ||||
| 			ti,sysc-mask = <SYSC_OMAP4_SOFTRESET>; | ||||
| 			ti,sysc-sidle = <SYSC_IDLE_FORCE>, | ||||
| 					<SYSC_IDLE_NO>, | ||||
| 					<SYSC_IDLE_SMART>, | ||||
| 					<SYSC_IDLE_SMART_WKUP>; | ||||
| 			clocks = <&alwon_clkctrl DM816_TIMER1_CLKCTRL 0>; | ||||
| 			clock-names = "fck"; | ||||
| 			#address-cells = <1>; | ||||
| 			#size-cells = <1>; | ||||
| 			ranges = <0x0 0x4802e000 0x1000>; | ||||
| 
 | ||||
| 			timer1: timer@0 { | ||||
| 				compatible = "ti,dm816-timer"; | ||||
| 				reg = <0 0x1000>; | ||||
| 				interrupts = <67>; | ||||
| 				ti,timer-alwon; | ||||
| 				clocks = <&alwon_clkctrl DM816_TIMER1_CLKCTRL 0>; | ||||
| 				clock-names = "fck"; | ||||
| 			}; | ||||
| 		}; | ||||
| 
 | ||||
| 		timer2: timer@48040000 { | ||||
| 			compatible = "ti,dm816-timer"; | ||||
| 			reg = <0x48040000 0x2000>; | ||||
| 			interrupts = <68>; | ||||
| 			ti,hwmods = "timer2"; | ||||
| 			clocks = <&timer2_fck>; | ||||
| 		timer2_target: target-module@48040000 { | ||||
| 			compatible = "ti,sysc-omap4-timer", "ti,sysc"; | ||||
| 			reg = <0x48040000 0x4>, | ||||
| 			      <0x48040010 0x4>; | ||||
| 			reg-names = "rev", "sysc"; | ||||
| 			ti,sysc-mask = <SYSC_OMAP4_SOFTRESET>; | ||||
| 			ti,sysc-sidle = <SYSC_IDLE_FORCE>, | ||||
| 					<SYSC_IDLE_NO>, | ||||
| 					<SYSC_IDLE_SMART>, | ||||
| 					<SYSC_IDLE_SMART_WKUP>; | ||||
| 			clocks = <&alwon_clkctrl DM816_TIMER2_CLKCTRL 0>; | ||||
| 			clock-names = "fck"; | ||||
| 			#address-cells = <1>; | ||||
| 			#size-cells = <1>; | ||||
| 			ranges = <0x0 0x48040000 0x1000>; | ||||
| 
 | ||||
| 			timer2: timer@0 { | ||||
| 				compatible = "ti,dm816-timer"; | ||||
| 				reg = <0 0x1000>; | ||||
| 				interrupts = <68>; | ||||
| 				clocks = <&alwon_clkctrl DM816_TIMER2_CLKCTRL 0>; | ||||
| 				clock-names = "fck"; | ||||
| 			}; | ||||
| 		}; | ||||
| 
 | ||||
| 		timer3: timer@48042000 { | ||||
| @ -642,3 +674,23 @@ | ||||
| }; | ||||
| 
 | ||||
| #include "dm816x-clocks.dtsi" | ||||
| 
 | ||||
| /* Preferred always-on timer for clocksource */ | ||||
| &timer1_target { | ||||
| 	ti,no-reset-on-init; | ||||
| 	ti,no-idle; | ||||
| 	timer@0 { | ||||
| 		assigned-clocks = <&timer1_fck>; | ||||
| 		assigned-clock-parents = <&sys_clkin_ck>; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| /* Preferred timer for clockevent */ | ||||
| &timer2_target { | ||||
| 	ti,no-reset-on-init; | ||||
| 	ti,no-idle; | ||||
| 	timer@0 { | ||||
| 		assigned-clocks = <&timer2_fck>; | ||||
| 		assigned-clock-parents = <&sys_clkin_ck>; | ||||
| 	}; | ||||
| }; | ||||
|  | ||||
| @ -1143,7 +1143,6 @@ | ||||
| 
 | ||||
| 		target-module@32000 {			/* 0x48032000, ap 5 3e.0 */ | ||||
| 			compatible = "ti,sysc-omap4-timer", "ti,sysc"; | ||||
| 			ti,hwmods = "timer2"; | ||||
| 			reg = <0x32000 0x4>, | ||||
| 			      <0x32010 0x4>; | ||||
| 			reg-names = "rev", "sysc"; | ||||
| @ -1171,7 +1170,6 @@ | ||||
| 
 | ||||
| 		target-module@34000 {			/* 0x48034000, ap 7 46.0 */ | ||||
| 			compatible = "ti,sysc-omap4-timer", "ti,sysc"; | ||||
| 			ti,hwmods = "timer3"; | ||||
| 			reg = <0x34000 0x4>, | ||||
| 			      <0x34010 0x4>; | ||||
| 			reg-names = "rev", "sysc"; | ||||
| @ -1199,7 +1197,6 @@ | ||||
| 
 | ||||
| 		target-module@36000 {			/* 0x48036000, ap 9 4e.0 */ | ||||
| 			compatible = "ti,sysc-omap4-timer", "ti,sysc"; | ||||
| 			ti,hwmods = "timer4"; | ||||
| 			reg = <0x36000 0x4>, | ||||
| 			      <0x36010 0x4>; | ||||
| 			reg-names = "rev", "sysc"; | ||||
| @ -4295,7 +4292,6 @@ | ||||
| 
 | ||||
| 		target-module@4000 {			/* 0x4ae04000, ap 15 40.0 */ | ||||
| 			compatible = "ti,sysc-omap2", "ti,sysc"; | ||||
| 			ti,hwmods = "counter_32k"; | ||||
| 			reg = <0x4000 0x4>, | ||||
| 			      <0x4010 0x4>; | ||||
| 			reg-names = "rev", "sysc"; | ||||
| @ -4430,9 +4426,8 @@ | ||||
| 			}; | ||||
| 		}; | ||||
| 
 | ||||
| 		target-module@8000 {			/* 0x4ae18000, ap 9 30.0 */ | ||||
| 		timer1_target: target-module@8000 {	/* 0x4ae18000, ap 9 30.0 */ | ||||
| 			compatible = "ti,sysc-omap4-timer", "ti,sysc"; | ||||
| 			ti,hwmods = "timer1"; | ||||
| 			reg = <0x8000 0x4>, | ||||
| 			      <0x8010 0x4>; | ||||
| 			reg-names = "rev", "sysc"; | ||||
|  | ||||
| @ -1044,3 +1044,13 @@ | ||||
| 		reg = <0x1c00 0x60>; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| /* Preferred always-on timer for clockevent */ | ||||
| &timer1_target { | ||||
| 	ti,no-reset-on-init; | ||||
| 	ti,no-idle; | ||||
| 	timer@0 { | ||||
| 		assigned-clocks = <&wkupaon_clkctrl DRA7_TIMER1_CLKCTRL 24>; | ||||
| 		assigned-clock-parents = <&sys_32k_ck>; | ||||
| 	}; | ||||
| }; | ||||
|  | ||||
| @ -201,11 +201,32 @@ | ||||
| 			clock-frequency = <48000000>; | ||||
| 		}; | ||||
| 
 | ||||
| 		timer2: timer@4802a000 { | ||||
| 			compatible = "ti,omap2420-timer"; | ||||
| 			reg = <0x4802a000 0x400>; | ||||
| 			interrupts = <38>; | ||||
| 			ti,hwmods = "timer2"; | ||||
| 		timer2_target: target-module@4802a000 { | ||||
| 			compatible = "ti,sysc-omap2-timer", "ti,sysc"; | ||||
| 			reg = <0x4802a000 0x4>, | ||||
| 			      <0x4802a010 0x4>, | ||||
| 			      <0x4802a014 0x4>; | ||||
| 			reg-names = "rev", "sysc", "syss"; | ||||
| 			ti,sysc-mask = <(SYSC_OMAP2_CLOCKACTIVITY | | ||||
| 					 SYSC_OMAP2_EMUFREE | | ||||
| 					 SYSC_OMAP2_ENAWAKEUP | | ||||
| 					 SYSC_OMAP2_SOFTRESET | | ||||
| 					 SYSC_OMAP2_AUTOIDLE)>; | ||||
| 			ti,sysc-sidle = <SYSC_IDLE_FORCE>, | ||||
| 					<SYSC_IDLE_NO>, | ||||
| 					<SYSC_IDLE_SMART>; | ||||
| 			ti,syss-mask = <1>; | ||||
| 			clocks = <&gpt2_fck>, <&gpt2_ick>; | ||||
| 			clock-names = "fck", "ick"; | ||||
| 			#address-cells = <1>; | ||||
| 			#size-cells = <1>; | ||||
| 			ranges = <0x0 0x4802a000 0x1000>; | ||||
| 
 | ||||
| 			timer2: timer@0 { | ||||
| 				compatible = "ti,omap2420-timer"; | ||||
| 				reg = <0 0x400>; | ||||
| 				interrupts = <38>; | ||||
| 			}; | ||||
| 		}; | ||||
| 
 | ||||
| 		timer3: timer@48078000 { | ||||
|  | ||||
| @ -68,10 +68,23 @@ | ||||
| 				}; | ||||
| 			}; | ||||
| 
 | ||||
| 			counter32k: counter@4000 { | ||||
| 				compatible = "ti,omap-counter32k"; | ||||
| 				reg = <0x4000 0x20>; | ||||
| 				ti,hwmods = "counter_32k"; | ||||
| 			target-module@4000 { | ||||
| 				compatible = "ti,sysc-omap2", "ti,sysc"; | ||||
| 				reg = <0x4000 0x4>, | ||||
| 				      <0x4004 0x4>; | ||||
| 				reg-names = "rev", "sysc"; | ||||
| 				ti,sysc-sidle = <SYSC_IDLE_FORCE>, | ||||
| 						<SYSC_IDLE_NO>; | ||||
| 				clocks = <&func_32k_ck>; | ||||
| 				clock-names = "fck"; | ||||
| 				#address-cells = <1>; | ||||
| 				#size-cells = <1>; | ||||
| 				ranges = <0x0 0x4000 0x1000>; | ||||
| 
 | ||||
| 				counter32k: counter@0 { | ||||
| 					compatible = "ti,omap-counter32k"; | ||||
| 					reg = <0 0x20>; | ||||
| 				}; | ||||
| 			}; | ||||
| 		}; | ||||
| 
 | ||||
| @ -194,12 +207,33 @@ | ||||
| 			}; | ||||
| 		}; | ||||
| 
 | ||||
| 		timer1: timer@48028000 { | ||||
| 			compatible = "ti,omap2420-timer"; | ||||
| 			reg = <0x48028000 0x400>; | ||||
| 			interrupts = <37>; | ||||
| 			ti,hwmods = "timer1"; | ||||
| 			ti,timer-alwon; | ||||
| 		timer1_target: target-module@48028000 { | ||||
| 			compatible = "ti,sysc-omap2-timer", "ti,sysc"; | ||||
| 			reg = <0x48028000 0x4>, | ||||
| 			      <0x48028010 0x4>, | ||||
| 			      <0x48028014 0x4>; | ||||
| 			reg-names = "rev", "sysc", "syss"; | ||||
| 			ti,sysc-mask = <(SYSC_OMAP2_CLOCKACTIVITY | | ||||
| 					 SYSC_OMAP2_EMUFREE | | ||||
| 					 SYSC_OMAP2_ENAWAKEUP | | ||||
| 					 SYSC_OMAP2_SOFTRESET | | ||||
| 					 SYSC_OMAP2_AUTOIDLE)>; | ||||
| 			ti,sysc-sidle = <SYSC_IDLE_FORCE>, | ||||
| 					<SYSC_IDLE_NO>, | ||||
| 					<SYSC_IDLE_SMART>; | ||||
| 			ti,syss-mask = <1>; | ||||
| 			clocks = <&gpt1_fck>, <&gpt1_ick>; | ||||
| 			clock-names = "fck", "ick"; | ||||
| 			#address-cells = <1>; | ||||
| 			#size-cells = <1>; | ||||
| 			ranges = <0x0 0x48028000 0x1000>; | ||||
| 
 | ||||
| 			timer1: timer@0 { | ||||
| 				compatible = "ti,omap2420-timer"; | ||||
| 				reg = <0 0x400>; | ||||
| 				interrupts = <37>; | ||||
| 				ti,timer-alwon; | ||||
| 			}; | ||||
| 		}; | ||||
| 
 | ||||
| 		wd_timer2: wdt@48022000 { | ||||
| @ -218,5 +252,15 @@ | ||||
| 	compatible = "ti,omap2420-i2c"; | ||||
| }; | ||||
| 
 | ||||
| /include/ "omap24xx-clocks.dtsi" | ||||
| /include/ "omap2420-clocks.dtsi" | ||||
| #include "omap24xx-clocks.dtsi" | ||||
| #include "omap2420-clocks.dtsi" | ||||
| 
 | ||||
| /* Preferred always-on timer for clockevent */ | ||||
| &timer1_target { | ||||
| 	ti,no-reset-on-init; | ||||
| 	ti,no-idle; | ||||
| 	timer@0 { | ||||
| 		assigned-clocks = <&gpt1_fck>; | ||||
| 		assigned-clock-parents = <&func_32k_ck>; | ||||
| 	}; | ||||
| }; | ||||
|  | ||||
| @ -81,10 +81,23 @@ | ||||
| 				}; | ||||
| 			}; | ||||
| 
 | ||||
| 			counter32k: counter@20000 { | ||||
| 				compatible = "ti,omap-counter32k"; | ||||
| 				reg = <0x20000 0x20>; | ||||
| 				ti,hwmods = "counter_32k"; | ||||
| 			target-module@20000 { | ||||
| 				compatible = "ti,sysc-omap2", "ti,sysc"; | ||||
| 				reg = <0x20000 0x4>, | ||||
| 				      <0x20004 0x4>; | ||||
| 				reg-names = "rev", "sysc"; | ||||
| 				ti,sysc-sidle = <SYSC_IDLE_FORCE>, | ||||
| 						<SYSC_IDLE_NO>; | ||||
| 				clocks = <&func_32k_ck>; | ||||
| 				clock-names = "fck"; | ||||
| 				#address-cells = <1>; | ||||
| 				#size-cells = <1>; | ||||
| 				ranges = <0x0 0x20000 0x1000>; | ||||
| 
 | ||||
| 				counter32k: counter@0 { | ||||
| 					compatible = "ti,omap-counter32k"; | ||||
| 					reg = <0 0x20>; | ||||
| 				}; | ||||
| 			}; | ||||
| 		}; | ||||
| 
 | ||||
| @ -277,12 +290,33 @@ | ||||
| 			}; | ||||
| 		}; | ||||
| 
 | ||||
| 		timer1: timer@49018000 { | ||||
| 			compatible = "ti,omap2420-timer"; | ||||
| 			reg = <0x49018000 0x400>; | ||||
| 			interrupts = <37>; | ||||
| 			ti,hwmods = "timer1"; | ||||
| 			ti,timer-alwon; | ||||
| 		timer1_target: target-module@49018000 { | ||||
| 			compatible = "ti,sysc-omap2-timer", "ti,sysc"; | ||||
| 			reg = <0x49018000 0x4>, | ||||
| 			      <0x49018010 0x4>, | ||||
| 			      <0x49018014 0x4>; | ||||
| 			reg-names = "rev", "sysc", "syss"; | ||||
| 			ti,sysc-mask = <(SYSC_OMAP2_CLOCKACTIVITY | | ||||
| 					 SYSC_OMAP2_EMUFREE | | ||||
| 					 SYSC_OMAP2_ENAWAKEUP | | ||||
| 					 SYSC_OMAP2_SOFTRESET | | ||||
| 					 SYSC_OMAP2_AUTOIDLE)>; | ||||
| 			ti,sysc-sidle = <SYSC_IDLE_FORCE>, | ||||
| 					<SYSC_IDLE_NO>, | ||||
| 					<SYSC_IDLE_SMART>; | ||||
| 			ti,syss-mask = <1>; | ||||
| 			clocks = <&gpt1_fck>, <&gpt1_ick>; | ||||
| 			clock-names = "fck", "ick"; | ||||
| 			#address-cells = <1>; | ||||
| 			#size-cells = <1>; | ||||
| 			ranges = <0x0 0x49018000 0x1000>; | ||||
| 
 | ||||
| 			timer1: timer@0 { | ||||
| 				compatible = "ti,omap2420-timer"; | ||||
| 				reg = <0 0x400>; | ||||
| 				interrupts = <37>; | ||||
| 				ti,timer-alwon; | ||||
| 			}; | ||||
| 		}; | ||||
| 
 | ||||
| 		mcspi3: spi@480b8000 { | ||||
| @ -321,5 +355,15 @@ | ||||
| 	compatible = "ti,omap2430-i2c"; | ||||
| }; | ||||
| 
 | ||||
| /include/ "omap24xx-clocks.dtsi" | ||||
| /include/ "omap2430-clocks.dtsi" | ||||
| #include "omap24xx-clocks.dtsi" | ||||
| #include "omap2430-clocks.dtsi" | ||||
| 
 | ||||
| /* Preferred always-on timer for clockevent */ | ||||
| &timer1_target { | ||||
| 	ti,no-reset-on-init; | ||||
| 	ti,no-idle; | ||||
| 	timer@0 { | ||||
| 		assigned-clocks = <&gpt1_fck>; | ||||
| 		assigned-clock-parents = <&func_32k_ck>; | ||||
| 	}; | ||||
| }; | ||||
|  | ||||
| @ -304,6 +304,39 @@ | ||||
| 	phys = <0 &hsusb2_phy>; | ||||
| }; | ||||
| 
 | ||||
| /* Unusable as clocksource because of unreliable oscillator */ | ||||
| &counter32k { | ||||
| 	status = "disabled"; | ||||
| }; | ||||
| 
 | ||||
| /* Unusable as clockevent because if unreliable oscillator, allow to idle */ | ||||
| &timer1_target { | ||||
| 	/delete-property/ti,no-reset-on-init; | ||||
| 	/delete-property/ti,no-idle; | ||||
| 	timer@0 { | ||||
| 		/delete-property/ti,timer-alwon; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| /* Preferred always-on timer for clocksource */ | ||||
| &timer12_target { | ||||
| 	ti,no-reset-on-init; | ||||
| 	ti,no-idle; | ||||
| 	timer@0 { | ||||
| 		/* Always clocked by secure_32k_fck */ | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| /* Preferred timer for clockevent */ | ||||
| &timer2_target { | ||||
| 	ti,no-reset-on-init; | ||||
| 	ti,no-idle; | ||||
| 	timer@0 { | ||||
| 		assigned-clocks = <&gpt2_fck>; | ||||
| 		assigned-clock-parents = <&sys_ck>; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| &twl_gpio { | ||||
| 	ti,use-leds; | ||||
| 	/* pullups: BIT(1) */ | ||||
|  | ||||
| @ -14,3 +14,36 @@ | ||||
| 		display2 = &tv0; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| /* Unusable as clocksource because of unreliable oscillator */ | ||||
| &counter32k { | ||||
| 	status = "disabled"; | ||||
| }; | ||||
| 
 | ||||
| /* Unusable as clockevent because if unreliable oscillator, allow to idle */ | ||||
| &timer1_target { | ||||
| 	/delete-property/ti,no-reset-on-init; | ||||
| 	/delete-property/ti,no-idle; | ||||
| 	timer@0 { | ||||
| 		/delete-property/ti,timer-alwon; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| /* Preferred always-on timer for clocksource */ | ||||
| &timer12_target { | ||||
| 	ti,no-reset-on-init; | ||||
| 	ti,no-idle; | ||||
| 	timer@0 { | ||||
| 		/* Always clocked by secure_32k_fck */ | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| /* Preferred timer for clockevent */ | ||||
| &timer2_target { | ||||
| 	ti,no-reset-on-init; | ||||
| 	ti,no-idle; | ||||
| 	timer@0 { | ||||
| 		assigned-clocks = <&gpt2_fck>; | ||||
| 		assigned-clock-parents = <&sys_ck>; | ||||
| 	}; | ||||
| }; | ||||
|  | ||||
| @ -193,10 +193,23 @@ | ||||
| 			}; | ||||
| 		}; | ||||
| 
 | ||||
| 		counter32k: counter@48320000 { | ||||
| 			compatible = "ti,omap-counter32k"; | ||||
| 			reg = <0x48320000 0x20>; | ||||
| 			ti,hwmods = "counter_32k"; | ||||
| 		target-module@48320000 { | ||||
| 			compatible = "ti,sysc-omap2", "ti,sysc"; | ||||
| 			reg = <0x48320000 0x4>, | ||||
| 			      <0x48320004 0x4>; | ||||
| 			reg-names = "rev", "sysc"; | ||||
| 			ti,sysc-sidle = <SYSC_IDLE_FORCE>, | ||||
| 					<SYSC_IDLE_NO>; | ||||
| 			clocks = <&wkup_32k_fck>, <&omap_32ksync_ick>; | ||||
| 			clock-names = "fck", "ick"; | ||||
| 			#address-cells = <1>; | ||||
| 			#size-cells = <1>; | ||||
| 			ranges = <0x0 0x48320000 0x1000>; | ||||
| 
 | ||||
| 			counter32k: counter@0 { | ||||
| 				compatible = "ti,omap-counter32k"; | ||||
| 				reg = <0x0 0x20>; | ||||
| 			}; | ||||
| 		}; | ||||
| 
 | ||||
| 		intc: interrupt-controller@48200000 { | ||||
| @ -637,19 +650,63 @@ | ||||
| 			dma-names = "rx"; | ||||
| 		}; | ||||
| 
 | ||||
| 		timer1: timer@48318000 { | ||||
| 			compatible = "ti,omap3430-timer"; | ||||
| 			reg = <0x48318000 0x400>; | ||||
| 			interrupts = <37>; | ||||
| 			ti,hwmods = "timer1"; | ||||
| 			ti,timer-alwon; | ||||
| 		timer1_target: target-module@48318000 { | ||||
| 			compatible = "ti,sysc-omap2-timer", "ti,sysc"; | ||||
| 			reg = <0x48318000 0x4>, | ||||
| 			      <0x48318010 0x4>, | ||||
| 			      <0x48318014 0x4>; | ||||
| 			reg-names = "rev", "sysc", "syss"; | ||||
| 			ti,sysc-mask = <(SYSC_OMAP2_CLOCKACTIVITY | | ||||
| 					 SYSC_OMAP2_EMUFREE | | ||||
| 					 SYSC_OMAP2_ENAWAKEUP | | ||||
| 					 SYSC_OMAP2_SOFTRESET | | ||||
| 					 SYSC_OMAP2_AUTOIDLE)>; | ||||
| 			ti,sysc-sidle = <SYSC_IDLE_FORCE>, | ||||
| 					<SYSC_IDLE_NO>, | ||||
| 					<SYSC_IDLE_SMART>; | ||||
| 			ti,syss-mask = <1>; | ||||
| 			clocks = <&gpt1_fck>, <&gpt1_ick>; | ||||
| 			clock-names = "fck", "ick"; | ||||
| 			#address-cells = <1>; | ||||
| 			#size-cells = <1>; | ||||
| 			ranges = <0x0 0x48318000 0x1000>; | ||||
| 
 | ||||
| 			timer1: timer@0 { | ||||
| 				compatible = "ti,omap3430-timer"; | ||||
| 				reg = <0x0 0x80>; | ||||
| 				clocks = <&gpt1_fck>; | ||||
| 				clock-names = "fck"; | ||||
| 				interrupts = <37>; | ||||
| 				ti,timer-alwon; | ||||
| 			}; | ||||
| 		}; | ||||
| 
 | ||||
| 		timer2: timer@49032000 { | ||||
| 			compatible = "ti,omap3430-timer"; | ||||
| 			reg = <0x49032000 0x400>; | ||||
| 			interrupts = <38>; | ||||
| 			ti,hwmods = "timer2"; | ||||
| 		timer2_target: target-module@49032000 { | ||||
| 			compatible = "ti,sysc-omap2-timer", "ti,sysc"; | ||||
| 			reg = <0x49032000 0x4>, | ||||
| 			      <0x49032010 0x4>, | ||||
| 			      <0x49032014 0x4>; | ||||
| 			reg-names = "rev", "sysc", "syss"; | ||||
| 			ti,sysc-mask = <(SYSC_OMAP2_CLOCKACTIVITY | | ||||
| 					 SYSC_OMAP2_EMUFREE | | ||||
| 					 SYSC_OMAP2_ENAWAKEUP | | ||||
| 					 SYSC_OMAP2_SOFTRESET | | ||||
| 					 SYSC_OMAP2_AUTOIDLE)>; | ||||
| 			ti,sysc-sidle = <SYSC_IDLE_FORCE>, | ||||
| 					<SYSC_IDLE_NO>, | ||||
| 					<SYSC_IDLE_SMART>; | ||||
| 			ti,syss-mask = <1>; | ||||
| 			clocks = <&gpt2_fck>, <&gpt2_ick>; | ||||
| 			clock-names = "fck", "ick"; | ||||
| 			#address-cells = <1>; | ||||
| 			#size-cells = <1>; | ||||
| 			ranges = <0x0 0x49032000 0x1000>; | ||||
| 
 | ||||
| 			timer2: timer@0 { | ||||
| 				compatible = "ti,omap3430-timer"; | ||||
| 				reg = <0 0x400>; | ||||
| 				interrupts = <38>; | ||||
| 			}; | ||||
| 		}; | ||||
| 
 | ||||
| 		timer3: timer@49034000 { | ||||
| @ -723,13 +780,34 @@ | ||||
| 			ti,timer-pwm; | ||||
| 		}; | ||||
| 
 | ||||
| 		timer12: timer@48304000 { | ||||
| 			compatible = "ti,omap3430-timer"; | ||||
| 			reg = <0x48304000 0x400>; | ||||
| 			interrupts = <95>; | ||||
| 			ti,hwmods = "timer12"; | ||||
| 			ti,timer-alwon; | ||||
| 			ti,timer-secure; | ||||
| 		timer12_target: target-module@48304000 { | ||||
| 			compatible = "ti,sysc-omap2-timer", "ti,sysc"; | ||||
| 			reg = <0x48304000 0x4>, | ||||
| 			      <0x48304010 0x4>, | ||||
| 			      <0x48304014 0x4>; | ||||
| 			reg-names = "rev", "sysc", "syss"; | ||||
| 			ti,sysc-mask = <(SYSC_OMAP2_CLOCKACTIVITY | | ||||
| 					 SYSC_OMAP2_EMUFREE | | ||||
| 					 SYSC_OMAP2_ENAWAKEUP | | ||||
| 					 SYSC_OMAP2_SOFTRESET | | ||||
| 					 SYSC_OMAP2_AUTOIDLE)>; | ||||
| 			ti,sysc-sidle = <SYSC_IDLE_FORCE>, | ||||
| 					<SYSC_IDLE_NO>, | ||||
| 					<SYSC_IDLE_SMART>; | ||||
| 			ti,syss-mask = <1>; | ||||
| 			clocks = <&gpt12_fck>, <&gpt12_ick>; | ||||
| 			clock-names = "fck", "ick"; | ||||
| 			#address-cells = <1>; | ||||
| 			#size-cells = <1>; | ||||
| 			ranges = <0x0 0x48304000 0x1000>; | ||||
| 
 | ||||
| 			timer12: timer@0 { | ||||
| 				compatible = "ti,omap3430-timer"; | ||||
| 				reg = <0 0x400>; | ||||
| 				interrupts = <95>; | ||||
| 				ti,timer-alwon; | ||||
| 				ti,timer-secure; | ||||
| 			}; | ||||
| 		}; | ||||
| 
 | ||||
| 		usbhstll: usbhstll@48062000 { | ||||
| @ -886,4 +964,14 @@ | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| /include/ "omap3xxx-clocks.dtsi" | ||||
| #include "omap3xxx-clocks.dtsi" | ||||
| 
 | ||||
| /* Preferred always-on timer for clockevent. Some boards must use dmtimer12 */ | ||||
| &timer1_target { | ||||
| 	ti,no-reset-on-init; | ||||
| 	ti,no-idle; | ||||
| 	timer@0 { | ||||
| 		assigned-clocks = <&gpt1_fck>; | ||||
| 		assigned-clock-parents = <&omap_32k_fck>; | ||||
| 	}; | ||||
| }; | ||||
|  | ||||
| @ -974,7 +974,6 @@ | ||||
| 
 | ||||
| 		target-module@4000 {			/* 0x4a304000, ap 17 24.0 */ | ||||
| 			compatible = "ti,sysc-omap2", "ti,sysc"; | ||||
| 			ti,hwmods = "counter_32k"; | ||||
| 			reg = <0x4000 0x4>, | ||||
| 			      <0x4004 0x4>; | ||||
| 			reg-names = "rev", "sysc"; | ||||
| @ -1139,9 +1138,8 @@ | ||||
| 			}; | ||||
| 		}; | ||||
| 
 | ||||
| 		target-module@8000 {			/* 0x4a318000, ap 9 1c.0 */ | ||||
| 		timer1_target: target-module@8000 {	/* 0x4a318000, ap 9 1c.0 */ | ||||
| 			compatible = "ti,sysc-omap2-timer", "ti,sysc"; | ||||
| 			ti,hwmods = "timer1"; | ||||
| 			reg = <0x8000 0x4>, | ||||
| 			      <0x8010 0x4>, | ||||
| 			      <0x8014 0x4>; | ||||
|  | ||||
| @ -655,3 +655,13 @@ | ||||
| 		#reset-cells = <1>; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| /* Preferred always-on timer for clockevent */ | ||||
| &timer1_target { | ||||
| 	ti,no-reset-on-init; | ||||
| 	ti,no-idle; | ||||
| 	timer@0 { | ||||
| 		assigned-clocks = <&l4_wkup_clkctrl OMAP4_TIMER1_CLKCTRL 24>; | ||||
| 		assigned-clock-parents = <&sys_clkin_ck>; | ||||
| 	}; | ||||
| }; | ||||
|  | ||||
| @ -2150,7 +2150,6 @@ | ||||
| 
 | ||||
| 		target-module@4000 {			/* 0x4ae04000, ap 17 20.0 */ | ||||
| 			compatible = "ti,sysc-omap2", "ti,sysc"; | ||||
| 			ti,hwmods = "counter_32k"; | ||||
| 			reg = <0x4000 0x4>, | ||||
| 			      <0x4010 0x4>; | ||||
| 			reg-names = "rev", "sysc"; | ||||
| @ -2336,9 +2335,8 @@ | ||||
| 			}; | ||||
| 		}; | ||||
| 
 | ||||
| 		target-module@8000 {			/* 0x4ae18000, ap 9 18.0 */ | ||||
| 		timer1_target: target-module@8000 {	/* 0x4ae18000, ap 9 18.0 */ | ||||
| 			compatible = "ti,sysc-omap4-timer", "ti,sysc"; | ||||
| 			ti,hwmods = "timer1"; | ||||
| 			reg = <0x8000 0x4>, | ||||
| 			      <0x8010 0x4>; | ||||
| 			reg-names = "rev", "sysc"; | ||||
|  | ||||
| @ -581,3 +581,13 @@ | ||||
| 		#reset-cells = <1>; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| /* Preferred always-on timer for clockevent */ | ||||
| &timer1_target { | ||||
| 	ti,no-reset-on-init; | ||||
| 	ti,no-idle; | ||||
| 	timer@0 { | ||||
| 		assigned-clocks = <&wkupaon_clkctrl OMAP5_TIMER1_CLKCTRL 24>; | ||||
| 		assigned-clock-parents = <&sys_32k_ck>; | ||||
| 	}; | ||||
| }; | ||||
|  | ||||
| @ -7,7 +7,7 @@ ccflags-y := -I$(srctree)/$(src)/include \ | ||||
| 	-I$(srctree)/arch/arm/plat-omap/include | ||||
| 
 | ||||
| # Common support
 | ||||
| obj-y := id.o io.o control.o devices.o fb.o timer.o pm.o \
 | ||||
| obj-y := id.o io.o control.o devices.o fb.o pm.o \
 | ||||
| 	 common.o dma.o wd_timer.o display.o i2c.o hdq1w.o omap_hwmod.o \
 | ||||
| 	 omap_device.o omap-headsmp.o sram.o | ||||
| 
 | ||||
| @ -16,6 +16,8 @@ hwmod-common				= omap_hwmod.o omap_hwmod_reset.o \ | ||||
| clock-common				= clock.o | ||||
| secure-common				= omap-smc.o omap-secure.o | ||||
| 
 | ||||
| obj-$(CONFIG_SOC_HAS_REALTIME_COUNTER)	+= timer.o | ||||
| 
 | ||||
| obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(hwmod-common) | ||||
| obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(hwmod-common) $(secure-common) | ||||
| obj-$(CONFIG_ARCH_OMAP4) += $(hwmod-common) $(secure-common) | ||||
|  | ||||
| @ -12,6 +12,7 @@ | ||||
| #include <linux/of_irq.h> | ||||
| #include <linux/of_platform.h> | ||||
| #include <linux/irqdomain.h> | ||||
| #include <linux/clocksource.h> | ||||
| 
 | ||||
| #include <asm/setup.h> | ||||
| #include <asm/mach/arch.h> | ||||
| @ -31,6 +32,13 @@ static void __init __maybe_unused omap_generic_init(void) | ||||
| 	omap_soc_device_init(); | ||||
| } | ||||
| 
 | ||||
| /* Clocks are needed early, see drivers/clocksource for the rest */ | ||||
| void __init __maybe_unused omap_init_time_of(void) | ||||
| { | ||||
| 	omap_clk_init(); | ||||
| 	timer_probe(); | ||||
| } | ||||
| 
 | ||||
| #ifdef CONFIG_SOC_OMAP2420 | ||||
| static const char *const omap242x_boards_compat[] __initconst = { | ||||
| 	"ti,omap2420", | ||||
| @ -42,7 +50,7 @@ DT_MACHINE_START(OMAP242X_DT, "Generic OMAP2420 (Flattened Device Tree)") | ||||
| 	.map_io		= omap242x_map_io, | ||||
| 	.init_early	= omap2420_init_early, | ||||
| 	.init_machine	= omap_generic_init, | ||||
| 	.init_time	= omap_init_time, | ||||
| 	.init_time	= omap_init_time_of, | ||||
| 	.dt_compat	= omap242x_boards_compat, | ||||
| 	.restart	= omap2xxx_restart, | ||||
| MACHINE_END | ||||
| @ -59,7 +67,7 @@ DT_MACHINE_START(OMAP243X_DT, "Generic OMAP2430 (Flattened Device Tree)") | ||||
| 	.map_io		= omap243x_map_io, | ||||
| 	.init_early	= omap2430_init_early, | ||||
| 	.init_machine	= omap_generic_init, | ||||
| 	.init_time	= omap_init_time, | ||||
| 	.init_time	= omap_init_time_of, | ||||
| 	.dt_compat	= omap243x_boards_compat, | ||||
| 	.restart	= omap2xxx_restart, | ||||
| MACHINE_END | ||||
| @ -106,7 +114,7 @@ DT_MACHINE_START(OMAP3_N900_DT, "Nokia RX-51 board") | ||||
| 	.init_early	= omap3430_init_early, | ||||
| 	.init_machine	= omap_generic_init, | ||||
| 	.init_late	= omap3_init_late, | ||||
| 	.init_time	= omap_init_time, | ||||
| 	.init_time	= omap_init_time_of, | ||||
| 	.dt_compat	= n900_boards_compat, | ||||
| 	.restart	= omap3xxx_restart, | ||||
| MACHINE_END | ||||
| @ -124,7 +132,7 @@ DT_MACHINE_START(OMAP3_DT, "Generic OMAP3 (Flattened Device Tree)") | ||||
| 	.init_early	= omap3430_init_early, | ||||
| 	.init_machine	= omap_generic_init, | ||||
| 	.init_late	= omap3_init_late, | ||||
| 	.init_time	= omap_init_time, | ||||
| 	.init_time	= omap_init_time_of, | ||||
| 	.dt_compat	= omap3_boards_compat, | ||||
| 	.restart	= omap3xxx_restart, | ||||
| MACHINE_END | ||||
| @ -141,7 +149,7 @@ DT_MACHINE_START(OMAP36XX_DT, "Generic OMAP36xx (Flattened Device Tree)") | ||||
| 	.init_early	= omap3630_init_early, | ||||
| 	.init_machine	= omap_generic_init, | ||||
| 	.init_late	= omap3_init_late, | ||||
| 	.init_time	= omap_init_time, | ||||
| 	.init_time	= omap_init_time_of, | ||||
| 	.dt_compat	= omap36xx_boards_compat, | ||||
| 	.restart	= omap3xxx_restart, | ||||
| MACHINE_END | ||||
| @ -158,7 +166,7 @@ DT_MACHINE_START(OMAP3_GP_DT, "Generic OMAP3-GP (Flattened Device Tree)") | ||||
| 	.init_early	= omap3430_init_early, | ||||
| 	.init_machine	= omap_generic_init, | ||||
| 	.init_late	= omap3_init_late, | ||||
| 	.init_time	= omap3_secure_sync32k_timer_init, | ||||
| 	.init_time	= omap_init_time_of, | ||||
| 	.dt_compat	= omap3_gp_boards_compat, | ||||
| 	.restart	= omap3xxx_restart, | ||||
| MACHINE_END | ||||
| @ -174,7 +182,7 @@ DT_MACHINE_START(AM3517_DT, "Generic AM3517 (Flattened Device Tree)") | ||||
| 	.init_early	= am35xx_init_early, | ||||
| 	.init_machine	= omap_generic_init, | ||||
| 	.init_late	= omap3_init_late, | ||||
| 	.init_time	= omap3_gptimer_timer_init, | ||||
| 	.init_time	= omap_init_time_of, | ||||
| 	.dt_compat	= am3517_boards_compat, | ||||
| 	.restart	= omap3xxx_restart, | ||||
| MACHINE_END | ||||
| @ -193,7 +201,7 @@ DT_MACHINE_START(TI814X_DT, "Generic ti814x (Flattened Device Tree)") | ||||
| 	.init_early	= ti814x_init_early, | ||||
| 	.init_machine	= omap_generic_init, | ||||
| 	.init_late	= ti81xx_init_late, | ||||
| 	.init_time	= omap3_gptimer_timer_init, | ||||
| 	.init_time	= omap_init_time_of, | ||||
| 	.dt_compat	= ti814x_boards_compat, | ||||
| 	.restart	= ti81xx_restart, | ||||
| MACHINE_END | ||||
| @ -210,7 +218,7 @@ DT_MACHINE_START(TI816X_DT, "Generic ti816x (Flattened Device Tree)") | ||||
| 	.init_early	= ti816x_init_early, | ||||
| 	.init_machine	= omap_generic_init, | ||||
| 	.init_late	= ti81xx_init_late, | ||||
| 	.init_time	= omap3_gptimer_timer_init, | ||||
| 	.init_time	= omap_init_time_of, | ||||
| 	.dt_compat	= ti816x_boards_compat, | ||||
| 	.restart	= ti81xx_restart, | ||||
| MACHINE_END | ||||
| @ -228,7 +236,7 @@ DT_MACHINE_START(AM33XX_DT, "Generic AM33XX (Flattened Device Tree)") | ||||
| 	.init_early	= am33xx_init_early, | ||||
| 	.init_machine	= omap_generic_init, | ||||
| 	.init_late	= am33xx_init_late, | ||||
| 	.init_time	= omap3_gptimer_timer_init, | ||||
| 	.init_time	= omap_init_time_of, | ||||
| 	.dt_compat	= am33xx_boards_compat, | ||||
| 	.restart	= am33xx_restart, | ||||
| MACHINE_END | ||||
| @ -253,7 +261,7 @@ DT_MACHINE_START(OMAP4_DT, "Generic OMAP4 (Flattened Device Tree)") | ||||
| 	.init_irq	= omap_gic_of_init, | ||||
| 	.init_machine	= omap_generic_init, | ||||
| 	.init_late	= omap4430_init_late, | ||||
| 	.init_time	= omap4_local_timer_init, | ||||
| 	.init_time	= omap_init_time_of, | ||||
| 	.dt_compat	= omap4_boards_compat, | ||||
| 	.restart	= omap44xx_restart, | ||||
| MACHINE_END | ||||
| @ -300,7 +308,7 @@ DT_MACHINE_START(AM43_DT, "Generic AM43 (Flattened Device Tree)") | ||||
| 	.init_late	= am43xx_init_late, | ||||
| 	.init_irq	= omap_gic_of_init, | ||||
| 	.init_machine	= omap_generic_init, | ||||
| 	.init_time	= omap3_gptimer_timer_init, | ||||
| 	.init_time	= omap_init_time_of, | ||||
| 	.dt_compat	= am43_boards_compat, | ||||
| 	.restart	= omap44xx_restart, | ||||
| MACHINE_END | ||||
|  | ||||
| @ -111,7 +111,14 @@ static inline int omap_l2_cache_init(void) | ||||
| #define OMAP_L2C_AUX_CTRL	0 | ||||
| #define omap4_l2c310_write_sec	NULL | ||||
| #endif | ||||
| 
 | ||||
| #ifdef CONFIG_SOC_HAS_REALTIME_COUNTER | ||||
| extern void omap5_realtime_timer_init(void); | ||||
| #else | ||||
| static inline void omap5_realtime_timer_init(void) | ||||
| { | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| void omap2420_init_early(void); | ||||
| void omap2430_init_early(void); | ||||
|  | ||||
| @ -264,14 +264,6 @@ static struct omap_hwmod_ocp_if omap2420_l3__dsp = { | ||||
| 	.user		= OCP_USER_MPU | OCP_USER_SDMA, | ||||
| }; | ||||
| 
 | ||||
| /* l4_wkup -> timer1 */ | ||||
| static struct omap_hwmod_ocp_if omap2420_l4_wkup__timer1 = { | ||||
| 	.master		= &omap2xxx_l4_wkup_hwmod, | ||||
| 	.slave		= &omap2xxx_timer1_hwmod, | ||||
| 	.clk		= "gpt1_ick", | ||||
| 	.user		= OCP_USER_MPU | OCP_USER_SDMA, | ||||
| }; | ||||
| 
 | ||||
| /* l4_wkup -> wd_timer2 */ | ||||
| static struct omap_hwmod_ocp_if omap2420_l4_wkup__wd_timer2 = { | ||||
| 	.master		= &omap2xxx_l4_wkup_hwmod, | ||||
| @ -352,15 +344,6 @@ static struct omap_hwmod_ocp_if omap2420_l4_core__hdq1w = { | ||||
| 	.flags		= OMAP_FIREWALL_L4 | OCPIF_SWSUP_IDLE, | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| /* l4_wkup -> 32ksync_counter */ | ||||
| static struct omap_hwmod_ocp_if omap2420_l4_wkup__counter_32k = { | ||||
| 	.master		= &omap2xxx_l4_wkup_hwmod, | ||||
| 	.slave		= &omap2xxx_counter_32k_hwmod, | ||||
| 	.clk		= "sync_32k_ick", | ||||
| 	.user		= OCP_USER_MPU | OCP_USER_SDMA, | ||||
| }; | ||||
| 
 | ||||
| static struct omap_hwmod_ocp_if omap2420_l3__gpmc = { | ||||
| 	.master		= &omap2xxx_l3_main_hwmod, | ||||
| 	.slave		= &omap2xxx_gpmc_hwmod, | ||||
| @ -382,8 +365,6 @@ static struct omap_hwmod_ocp_if *omap2420_hwmod_ocp_ifs[] __initdata = { | ||||
| 	&omap2420_l4_core__i2c2, | ||||
| 	&omap2420_l3__iva, | ||||
| 	&omap2420_l3__dsp, | ||||
| 	&omap2420_l4_wkup__timer1, | ||||
| 	&omap2xxx_l4_core__timer2, | ||||
| 	&omap2xxx_l4_core__timer3, | ||||
| 	&omap2xxx_l4_core__timer4, | ||||
| 	&omap2xxx_l4_core__timer5, | ||||
| @ -411,7 +392,6 @@ static struct omap_hwmod_ocp_if *omap2420_hwmod_ocp_ifs[] __initdata = { | ||||
| 	&omap2xxx_l4_core__sham, | ||||
| 	&omap2xxx_l4_core__aes, | ||||
| 	&omap2420_l4_core__hdq1w, | ||||
| 	&omap2420_l4_wkup__counter_32k, | ||||
| 	&omap2420_l3__gpmc, | ||||
| 	NULL, | ||||
| }; | ||||
|  | ||||
| @ -436,14 +436,6 @@ static struct omap_hwmod_ocp_if omap2430_l3__iva = { | ||||
| 	.user		= OCP_USER_MPU | OCP_USER_SDMA, | ||||
| }; | ||||
| 
 | ||||
| /* l4_wkup -> timer1 */ | ||||
| static struct omap_hwmod_ocp_if omap2430_l4_wkup__timer1 = { | ||||
| 	.master		= &omap2xxx_l4_wkup_hwmod, | ||||
| 	.slave		= &omap2xxx_timer1_hwmod, | ||||
| 	.clk		= "gpt1_ick", | ||||
| 	.user		= OCP_USER_MPU | OCP_USER_SDMA, | ||||
| }; | ||||
| 
 | ||||
| /* l4_wkup -> wd_timer2 */ | ||||
| static struct omap_hwmod_ocp_if omap2430_l4_wkup__wd_timer2 = { | ||||
| 	.master		= &omap2xxx_l4_wkup_hwmod, | ||||
| @ -548,14 +540,6 @@ static struct omap_hwmod_ocp_if omap2430_l4_core__hdq1w = { | ||||
| 	.flags		= OMAP_FIREWALL_L4 | OCPIF_SWSUP_IDLE, | ||||
| }; | ||||
| 
 | ||||
| /* l4_wkup -> 32ksync_counter */ | ||||
| static struct omap_hwmod_ocp_if omap2430_l4_wkup__counter_32k = { | ||||
| 	.master		= &omap2xxx_l4_wkup_hwmod, | ||||
| 	.slave		= &omap2xxx_counter_32k_hwmod, | ||||
| 	.clk		= "sync_32k_ick", | ||||
| 	.user		= OCP_USER_MPU | OCP_USER_SDMA, | ||||
| }; | ||||
| 
 | ||||
| static struct omap_hwmod_ocp_if omap2430_l3__gpmc = { | ||||
| 	.master		= &omap2xxx_l3_main_hwmod, | ||||
| 	.slave		= &omap2xxx_gpmc_hwmod, | ||||
| @ -581,8 +565,6 @@ static struct omap_hwmod_ocp_if *omap2430_hwmod_ocp_ifs[] __initdata = { | ||||
| 	&omap2xxx_l4_core__mcspi2, | ||||
| 	&omap2430_l4_core__mcspi3, | ||||
| 	&omap2430_l3__iva, | ||||
| 	&omap2430_l4_wkup__timer1, | ||||
| 	&omap2xxx_l4_core__timer2, | ||||
| 	&omap2xxx_l4_core__timer3, | ||||
| 	&omap2xxx_l4_core__timer4, | ||||
| 	&omap2xxx_l4_core__timer5, | ||||
| @ -613,7 +595,6 @@ static struct omap_hwmod_ocp_if *omap2430_hwmod_ocp_ifs[] __initdata = { | ||||
| 	&omap2xxx_l4_core__rng, | ||||
| 	&omap2xxx_l4_core__sham, | ||||
| 	&omap2xxx_l4_core__aes, | ||||
| 	&omap2430_l4_wkup__counter_32k, | ||||
| 	&omap2430_l3__gpmc, | ||||
| 	NULL, | ||||
| }; | ||||
|  | ||||
| @ -95,14 +95,6 @@ struct omap_hwmod_ocp_if omap2xxx_l4_core__mcspi2 = { | ||||
| 	.user		= OCP_USER_MPU | OCP_USER_SDMA, | ||||
| }; | ||||
| 
 | ||||
| /* l4_core -> timer2 */ | ||||
| struct omap_hwmod_ocp_if omap2xxx_l4_core__timer2 = { | ||||
| 	.master		= &omap2xxx_l4_core_hwmod, | ||||
| 	.slave		= &omap2xxx_timer2_hwmod, | ||||
| 	.clk		= "gpt2_ick", | ||||
| 	.user		= OCP_USER_MPU | OCP_USER_SDMA, | ||||
| }; | ||||
| 
 | ||||
| /* l4_core -> timer3 */ | ||||
| struct omap_hwmod_ocp_if omap2xxx_l4_core__timer3 = { | ||||
| 	.master		= &omap2xxx_l4_core_hwmod, | ||||
|  | ||||
| @ -195,36 +195,6 @@ struct omap_hwmod omap2xxx_iva_hwmod = { | ||||
| 	.class		= &iva_hwmod_class, | ||||
| }; | ||||
| 
 | ||||
| /* timer1 */ | ||||
| struct omap_hwmod omap2xxx_timer1_hwmod = { | ||||
| 	.name		= "timer1", | ||||
| 	.main_clk	= "gpt1_fck", | ||||
| 	.prcm		= { | ||||
| 		.omap2 = { | ||||
| 			.module_offs = WKUP_MOD, | ||||
| 			.idlest_reg_id = 1, | ||||
| 			.idlest_idle_bit = OMAP24XX_ST_GPT1_SHIFT, | ||||
| 		}, | ||||
| 	}, | ||||
| 	.class		= &omap2xxx_timer_hwmod_class, | ||||
| 	.flags          = HWMOD_SET_DEFAULT_CLOCKACT, | ||||
| }; | ||||
| 
 | ||||
| /* timer2 */ | ||||
| struct omap_hwmod omap2xxx_timer2_hwmod = { | ||||
| 	.name		= "timer2", | ||||
| 	.main_clk	= "gpt2_fck", | ||||
| 	.prcm		= { | ||||
| 		.omap2 = { | ||||
| 			.module_offs = CORE_MOD, | ||||
| 			.idlest_reg_id = 1, | ||||
| 			.idlest_idle_bit = OMAP24XX_ST_GPT2_SHIFT, | ||||
| 		}, | ||||
| 	}, | ||||
| 	.class		= &omap2xxx_timer_hwmod_class, | ||||
| 	.flags          = HWMOD_SET_DEFAULT_CLOCKACT, | ||||
| }; | ||||
| 
 | ||||
| /* timer3 */ | ||||
| struct omap_hwmod omap2xxx_timer3_hwmod = { | ||||
| 	.name		= "timer3", | ||||
| @ -595,23 +565,6 @@ struct omap_hwmod omap2xxx_mcspi2_hwmod = { | ||||
| 	.class		= &omap2xxx_mcspi_class, | ||||
| }; | ||||
| 
 | ||||
| static struct omap_hwmod_class omap2xxx_counter_hwmod_class = { | ||||
| 	.name	= "counter", | ||||
| }; | ||||
| 
 | ||||
| struct omap_hwmod omap2xxx_counter_32k_hwmod = { | ||||
| 	.name		= "counter_32k", | ||||
| 	.main_clk	= "func_32k_ck", | ||||
| 	.prcm		= { | ||||
| 		.omap2	= { | ||||
| 			.module_offs = WKUP_MOD, | ||||
| 			.idlest_reg_id = 1, | ||||
| 			.idlest_idle_bit = OMAP24XX_ST_32KSYNC_SHIFT, | ||||
| 		}, | ||||
| 	}, | ||||
| 	.class		= &omap2xxx_counter_hwmod_class, | ||||
| }; | ||||
| 
 | ||||
| /* gpmc */ | ||||
| struct omap_hwmod omap2xxx_gpmc_hwmod = { | ||||
| 	.name		= "gpmc", | ||||
|  | ||||
| @ -44,8 +44,6 @@ extern struct omap_hwmod am33xx_smartreflex0_hwmod; | ||||
| extern struct omap_hwmod am33xx_smartreflex1_hwmod; | ||||
| extern struct omap_hwmod am33xx_gpmc_hwmod; | ||||
| extern struct omap_hwmod am33xx_rtc_hwmod; | ||||
| extern struct omap_hwmod am33xx_timer1_hwmod; | ||||
| extern struct omap_hwmod am33xx_timer2_hwmod; | ||||
| 
 | ||||
| extern struct omap_hwmod_class am33xx_emif_hwmod_class; | ||||
| extern struct omap_hwmod_class am33xx_l4_hwmod_class; | ||||
|  | ||||
| @ -106,14 +106,6 @@ struct omap_hwmod_ocp_if am33xx_l3_s__gpmc = { | ||||
| 	.user		= OCP_USER_MPU, | ||||
| }; | ||||
| 
 | ||||
| /* l4 per -> timer2 */ | ||||
| struct omap_hwmod_ocp_if am33xx_l4_ls__timer2 = { | ||||
| 	.master		= &am33xx_l4_ls_hwmod, | ||||
| 	.slave		= &am33xx_timer2_hwmod, | ||||
| 	.clk		= "l4ls_gclk", | ||||
| 	.user		= OCP_USER_MPU, | ||||
| }; | ||||
| 
 | ||||
| /* l3 main -> ocmc */ | ||||
| struct omap_hwmod_ocp_if am33xx_l3_main__ocmc = { | ||||
| 	.master		= &am33xx_l3_main_hwmod, | ||||
|  | ||||
| @ -307,72 +307,12 @@ struct omap_hwmod am33xx_rtc_hwmod = { | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| /* 'timer 2-7' class */ | ||||
| static struct omap_hwmod_class_sysconfig am33xx_timer_sysc = { | ||||
| 	.rev_offs	= 0x0000, | ||||
| 	.sysc_offs	= 0x0010, | ||||
| 	.syss_offs	= 0x0014, | ||||
| 	.sysc_flags	= SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | | ||||
| 			  SYSC_HAS_RESET_STATUS, | ||||
| 	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | | ||||
| 			  SIDLE_SMART_WKUP), | ||||
| 	.sysc_fields	= &omap_hwmod_sysc_type2, | ||||
| }; | ||||
| 
 | ||||
| struct omap_hwmod_class am33xx_timer_hwmod_class = { | ||||
| 	.name		= "timer", | ||||
| 	.sysc		= &am33xx_timer_sysc, | ||||
| }; | ||||
| 
 | ||||
| /* timer1 1ms */ | ||||
| static struct omap_hwmod_class_sysconfig am33xx_timer1ms_sysc = { | ||||
| 	.rev_offs	= 0x0000, | ||||
| 	.sysc_offs	= 0x0010, | ||||
| 	.syss_offs	= 0x0014, | ||||
| 	.sysc_flags	= (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE | | ||||
| 			SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE | | ||||
| 			SYSS_HAS_RESET_STATUS), | ||||
| 	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), | ||||
| 	.sysc_fields	= &omap_hwmod_sysc_type1, | ||||
| }; | ||||
| 
 | ||||
| static struct omap_hwmod_class am33xx_timer1ms_hwmod_class = { | ||||
| 	.name		= "timer", | ||||
| 	.sysc		= &am33xx_timer1ms_sysc, | ||||
| }; | ||||
| 
 | ||||
| struct omap_hwmod am33xx_timer1_hwmod = { | ||||
| 	.name		= "timer1", | ||||
| 	.class		= &am33xx_timer1ms_hwmod_class, | ||||
| 	.clkdm_name	= "l4_wkup_clkdm", | ||||
| 	.main_clk	= "timer1_fck", | ||||
| 	.prcm		= { | ||||
| 		.omap4	= { | ||||
| 			.modulemode	= MODULEMODE_SWCTRL, | ||||
| 		}, | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| struct omap_hwmod am33xx_timer2_hwmod = { | ||||
| 	.name		= "timer2", | ||||
| 	.class		= &am33xx_timer_hwmod_class, | ||||
| 	.clkdm_name	= "l4ls_clkdm", | ||||
| 	.main_clk	= "timer2_fck", | ||||
| 	.prcm		= { | ||||
| 		.omap4	= { | ||||
| 			.modulemode	= MODULEMODE_SWCTRL, | ||||
| 		}, | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| static void omap_hwmod_am33xx_clkctrl(void) | ||||
| { | ||||
| 	CLKCTRL(am33xx_timer2_hwmod, AM33XX_CM_PER_TIMER2_CLKCTRL_OFFSET); | ||||
| 	CLKCTRL(am33xx_smartreflex0_hwmod, | ||||
| 		AM33XX_CM_WKUP_SMARTREFLEX0_CLKCTRL_OFFSET); | ||||
| 	CLKCTRL(am33xx_smartreflex1_hwmod, | ||||
| 		AM33XX_CM_WKUP_SMARTREFLEX1_CLKCTRL_OFFSET); | ||||
| 	CLKCTRL(am33xx_timer1_hwmod, AM33XX_CM_WKUP_TIMER1_CLKCTRL_OFFSET); | ||||
| 	CLKCTRL(am33xx_rtc_hwmod, AM33XX_CM_RTC_RTC_CLKCTRL_OFFSET); | ||||
| 	PRCM_FLAGS(am33xx_rtc_hwmod, HWMOD_OMAP4_ZERO_CLKCTRL_OFFSET); | ||||
| 	CLKCTRL(am33xx_gpmc_hwmod, AM33XX_CM_PER_GPMC_CLKCTRL_OFFSET); | ||||
| @ -399,12 +339,10 @@ void omap_hwmod_am33xx_reg(void) | ||||
| 
 | ||||
| static void omap_hwmod_am43xx_clkctrl(void) | ||||
| { | ||||
| 	CLKCTRL(am33xx_timer2_hwmod, AM43XX_CM_PER_TIMER2_CLKCTRL_OFFSET); | ||||
| 	CLKCTRL(am33xx_smartreflex0_hwmod, | ||||
| 		AM43XX_CM_WKUP_SMARTREFLEX0_CLKCTRL_OFFSET); | ||||
| 	CLKCTRL(am33xx_smartreflex1_hwmod, | ||||
| 		AM43XX_CM_WKUP_SMARTREFLEX1_CLKCTRL_OFFSET); | ||||
| 	CLKCTRL(am33xx_timer1_hwmod, AM43XX_CM_WKUP_TIMER1_CLKCTRL_OFFSET); | ||||
| 	CLKCTRL(am33xx_rtc_hwmod, AM43XX_CM_RTC_RTC_CLKCTRL_OFFSET); | ||||
| 	CLKCTRL(am33xx_gpmc_hwmod, AM43XX_CM_PER_GPMC_CLKCTRL_OFFSET); | ||||
| 	CLKCTRL(am33xx_l4_ls_hwmod, AM43XX_CM_PER_L4LS_CLKCTRL_OFFSET); | ||||
|  | ||||
| @ -265,14 +265,6 @@ static struct omap_hwmod_ocp_if am33xx_l4_wkup__control = { | ||||
| 	.user		= OCP_USER_MPU, | ||||
| }; | ||||
| 
 | ||||
| /* l4 wkup -> timer1 */ | ||||
| static struct omap_hwmod_ocp_if am33xx_l4_wkup__timer1 = { | ||||
| 	.master		= &am33xx_l4_wkup_hwmod, | ||||
| 	.slave		= &am33xx_timer1_hwmod, | ||||
| 	.clk		= "dpll_core_m4_div2_ck", | ||||
| 	.user		= OCP_USER_MPU, | ||||
| }; | ||||
| 
 | ||||
| static struct omap_hwmod_ocp_if *am33xx_hwmod_ocp_ifs[] __initdata = { | ||||
| 	&am33xx_l3_main__emif, | ||||
| 	&am33xx_mpu__l3_main, | ||||
| @ -291,9 +283,7 @@ static struct omap_hwmod_ocp_if *am33xx_hwmod_ocp_ifs[] __initdata = { | ||||
| 	&am33xx_l4_wkup__control, | ||||
| 	&am33xx_l4_wkup__smartreflex0, | ||||
| 	&am33xx_l4_wkup__smartreflex1, | ||||
| 	&am33xx_l4_wkup__timer1, | ||||
| 	&am33xx_l4_wkup__rtc, | ||||
| 	&am33xx_l4_ls__timer2, | ||||
| 	&am33xx_l3_s__gpmc, | ||||
| 	&am33xx_l3_main__ocmc, | ||||
| 	NULL, | ||||
|  | ||||
| @ -147,36 +147,6 @@ static struct omap_hwmod_class omap3xxx_timer_hwmod_class = { | ||||
| 	.sysc = &omap3xxx_timer_sysc, | ||||
| }; | ||||
| 
 | ||||
| /* timer1 */ | ||||
| static struct omap_hwmod omap3xxx_timer1_hwmod = { | ||||
| 	.name		= "timer1", | ||||
| 	.main_clk	= "gpt1_fck", | ||||
| 	.prcm		= { | ||||
| 		.omap2 = { | ||||
| 			.module_offs = WKUP_MOD, | ||||
| 			.idlest_reg_id = 1, | ||||
| 			.idlest_idle_bit = OMAP3430_ST_GPT1_SHIFT, | ||||
| 		}, | ||||
| 	}, | ||||
| 	.class		= &omap3xxx_timer_hwmod_class, | ||||
| 	.flags		= HWMOD_SET_DEFAULT_CLOCKACT, | ||||
| }; | ||||
| 
 | ||||
| /* timer2 */ | ||||
| static struct omap_hwmod omap3xxx_timer2_hwmod = { | ||||
| 	.name		= "timer2", | ||||
| 	.main_clk	= "gpt2_fck", | ||||
| 	.prcm		= { | ||||
| 		.omap2 = { | ||||
| 			.module_offs = OMAP3430_PER_MOD, | ||||
| 			.idlest_reg_id = 1, | ||||
| 			.idlest_idle_bit = OMAP3430_ST_GPT2_SHIFT, | ||||
| 		}, | ||||
| 	}, | ||||
| 	.class		= &omap3xxx_timer_hwmod_class, | ||||
| 	.flags		= HWMOD_SET_DEFAULT_CLOCKACT, | ||||
| }; | ||||
| 
 | ||||
| /* timer3 */ | ||||
| static struct omap_hwmod omap3xxx_timer3_hwmod = { | ||||
| 	.name		= "timer3", | ||||
| @ -312,21 +282,6 @@ static struct omap_hwmod omap3xxx_timer11_hwmod = { | ||||
| 	.flags		= HWMOD_SET_DEFAULT_CLOCKACT, | ||||
| }; | ||||
| 
 | ||||
| /* timer12 */ | ||||
| static struct omap_hwmod omap3xxx_timer12_hwmod = { | ||||
| 	.name		= "timer12", | ||||
| 	.main_clk	= "gpt12_fck", | ||||
| 	.prcm		= { | ||||
| 		.omap2 = { | ||||
| 			.module_offs = WKUP_MOD, | ||||
| 			.idlest_reg_id = 1, | ||||
| 			.idlest_idle_bit = OMAP3430_ST_GPT12_SHIFT, | ||||
| 		}, | ||||
| 	}, | ||||
| 	.class		= &omap3xxx_timer_hwmod_class, | ||||
| 	.flags		= HWMOD_SET_DEFAULT_CLOCKACT, | ||||
| }; | ||||
| 
 | ||||
| /*
 | ||||
|  * 'wd_timer' class | ||||
|  * 32-bit watchdog upward counter that generates a pulse on the reset pin on | ||||
| @ -1524,38 +1479,6 @@ static struct omap_hwmod omap3xxx_sad2d_hwmod = { | ||||
| 	.class		= &omap3xxx_sad2d_class, | ||||
| }; | ||||
| 
 | ||||
| /*
 | ||||
|  * '32K sync counter' class | ||||
|  * 32-bit ordinary counter, clocked by the falling edge of the 32 khz clock | ||||
|  */ | ||||
| static struct omap_hwmod_class_sysconfig omap3xxx_counter_sysc = { | ||||
| 	.rev_offs	= 0x0000, | ||||
| 	.sysc_offs	= 0x0004, | ||||
| 	.sysc_flags	= SYSC_HAS_SIDLEMODE, | ||||
| 	.idlemodes	= (SIDLE_FORCE | SIDLE_NO), | ||||
| 	.sysc_fields	= &omap_hwmod_sysc_type1, | ||||
| }; | ||||
| 
 | ||||
| static struct omap_hwmod_class omap3xxx_counter_hwmod_class = { | ||||
| 	.name	= "counter", | ||||
| 	.sysc	= &omap3xxx_counter_sysc, | ||||
| }; | ||||
| 
 | ||||
| static struct omap_hwmod omap3xxx_counter_32k_hwmod = { | ||||
| 	.name		= "counter_32k", | ||||
| 	.class		= &omap3xxx_counter_hwmod_class, | ||||
| 	.clkdm_name	= "wkup_clkdm", | ||||
| 	.flags		= HWMOD_SWSUP_SIDLE, | ||||
| 	.main_clk	= "wkup_32k_fck", | ||||
| 	.prcm		= { | ||||
| 		.omap2	= { | ||||
| 			.module_offs = WKUP_MOD, | ||||
| 			.idlest_reg_id = 1, | ||||
| 			.idlest_idle_bit = OMAP3430_ST_32KSYNC_SHIFT, | ||||
| 		}, | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| /*
 | ||||
|  * 'gpmc' class | ||||
|  * general purpose memory controller | ||||
| @ -1868,25 +1791,6 @@ static struct omap_hwmod_ocp_if omap3xxx_l3__iva = { | ||||
| 	.user		= OCP_USER_MPU | OCP_USER_SDMA, | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| /* l4_wkup -> timer1 */ | ||||
| static struct omap_hwmod_ocp_if omap3xxx_l4_wkup__timer1 = { | ||||
| 	.master		= &omap3xxx_l4_wkup_hwmod, | ||||
| 	.slave		= &omap3xxx_timer1_hwmod, | ||||
| 	.clk		= "gpt1_ick", | ||||
| 	.user		= OCP_USER_MPU | OCP_USER_SDMA, | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| /* l4_per -> timer2 */ | ||||
| static struct omap_hwmod_ocp_if omap3xxx_l4_per__timer2 = { | ||||
| 	.master		= &omap3xxx_l4_per_hwmod, | ||||
| 	.slave		= &omap3xxx_timer2_hwmod, | ||||
| 	.clk		= "gpt2_ick", | ||||
| 	.user		= OCP_USER_MPU | OCP_USER_SDMA, | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| /* l4_per -> timer3 */ | ||||
| static struct omap_hwmod_ocp_if omap3xxx_l4_per__timer3 = { | ||||
| 	.master		= &omap3xxx_l4_per_hwmod, | ||||
| @ -1965,15 +1869,6 @@ static struct omap_hwmod_ocp_if omap3xxx_l4_core__timer11 = { | ||||
| 	.user		= OCP_USER_MPU | OCP_USER_SDMA, | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| /* l4_core -> timer12 */ | ||||
| static struct omap_hwmod_ocp_if omap3xxx_l4_sec__timer12 = { | ||||
| 	.master		= &omap3xxx_l4_sec_hwmod, | ||||
| 	.slave		= &omap3xxx_timer12_hwmod, | ||||
| 	.clk		= "gpt12_ick", | ||||
| 	.user		= OCP_USER_MPU | OCP_USER_SDMA, | ||||
| }; | ||||
| 
 | ||||
| /* l4_wkup -> wd_timer2 */ | ||||
| 
 | ||||
| static struct omap_hwmod_ocp_if omap3xxx_l4_wkup__wd_timer2 = { | ||||
| @ -2325,16 +2220,6 @@ static struct omap_hwmod_ocp_if omap3xxx_l4_core__hdq1w = { | ||||
| 	.flags		= OMAP_FIREWALL_L4 | OCPIF_SWSUP_IDLE, | ||||
| }; | ||||
| 
 | ||||
| /* l4_wkup -> 32ksync_counter */ | ||||
| 
 | ||||
| 
 | ||||
| static struct omap_hwmod_ocp_if omap3xxx_l4_wkup__counter_32k = { | ||||
| 	.master		= &omap3xxx_l4_wkup_hwmod, | ||||
| 	.slave		= &omap3xxx_counter_32k_hwmod, | ||||
| 	.clk		= "omap_32ksync_ick", | ||||
| 	.user		= OCP_USER_MPU | OCP_USER_SDMA, | ||||
| }; | ||||
| 
 | ||||
| /* am35xx has Davinci MDIO & EMAC */ | ||||
| static struct omap_hwmod_class am35xx_mdio_class = { | ||||
| 	.name = "davinci_mdio", | ||||
| @ -2551,8 +2436,6 @@ static struct omap_hwmod_ocp_if *omap3xxx_hwmod_ocp_ifs[] __initdata = { | ||||
| 	&omap3_l4_core__i2c2, | ||||
| 	&omap3_l4_core__i2c3, | ||||
| 	&omap3xxx_l4_wkup__l4_sec, | ||||
| 	&omap3xxx_l4_wkup__timer1, | ||||
| 	&omap3xxx_l4_per__timer2, | ||||
| 	&omap3xxx_l4_per__timer3, | ||||
| 	&omap3xxx_l4_per__timer4, | ||||
| 	&omap3xxx_l4_per__timer5, | ||||
| @ -2580,27 +2463,10 @@ static struct omap_hwmod_ocp_if *omap3xxx_hwmod_ocp_ifs[] __initdata = { | ||||
| 	&omap34xx_l4_core__mcspi2, | ||||
| 	&omap34xx_l4_core__mcspi3, | ||||
| 	&omap34xx_l4_core__mcspi4, | ||||
| 	&omap3xxx_l4_wkup__counter_32k, | ||||
| 	&omap3xxx_l3_main__gpmc, | ||||
| 	NULL, | ||||
| }; | ||||
| 
 | ||||
| /* GP-only hwmod links */ | ||||
| static struct omap_hwmod_ocp_if *omap34xx_gp_hwmod_ocp_ifs[] __initdata = { | ||||
| 	&omap3xxx_l4_sec__timer12, | ||||
| 	NULL, | ||||
| }; | ||||
| 
 | ||||
| static struct omap_hwmod_ocp_if *omap36xx_gp_hwmod_ocp_ifs[] __initdata = { | ||||
| 	&omap3xxx_l4_sec__timer12, | ||||
| 	NULL, | ||||
| }; | ||||
| 
 | ||||
| static struct omap_hwmod_ocp_if *am35xx_gp_hwmod_ocp_ifs[] __initdata = { | ||||
| 	&omap3xxx_l4_sec__timer12, | ||||
| 	NULL, | ||||
| }; | ||||
| 
 | ||||
| /* crypto hwmod links */ | ||||
| static struct omap_hwmod_ocp_if *omap34xx_sham_hwmod_ocp_ifs[] __initdata = { | ||||
| 	&omap3xxx_l4_core__sham, | ||||
| @ -2774,7 +2640,7 @@ static bool __init omap3xxx_hwmod_is_hs_ip_block_usable(struct device_node *bus, | ||||
| int __init omap3xxx_hwmod_init(void) | ||||
| { | ||||
| 	int r; | ||||
| 	struct omap_hwmod_ocp_if **h = NULL, **h_gp = NULL, **h_sham = NULL; | ||||
| 	struct omap_hwmod_ocp_if **h = NULL, **h_sham = NULL; | ||||
| 	struct omap_hwmod_ocp_if **h_aes = NULL; | ||||
| 	struct device_node *bus; | ||||
| 	unsigned int rev; | ||||
| @ -2797,18 +2663,15 @@ int __init omap3xxx_hwmod_init(void) | ||||
| 	    rev == OMAP3430_REV_ES2_1 || rev == OMAP3430_REV_ES3_0 || | ||||
| 	    rev == OMAP3430_REV_ES3_1 || rev == OMAP3430_REV_ES3_1_2) { | ||||
| 		h = omap34xx_hwmod_ocp_ifs; | ||||
| 		h_gp = omap34xx_gp_hwmod_ocp_ifs; | ||||
| 		h_sham = omap34xx_sham_hwmod_ocp_ifs; | ||||
| 		h_aes = omap34xx_aes_hwmod_ocp_ifs; | ||||
| 	} else if (rev == AM35XX_REV_ES1_0 || rev == AM35XX_REV_ES1_1) { | ||||
| 		h = am35xx_hwmod_ocp_ifs; | ||||
| 		h_gp = am35xx_gp_hwmod_ocp_ifs; | ||||
| 		h_sham = am35xx_sham_hwmod_ocp_ifs; | ||||
| 		h_aes = am35xx_aes_hwmod_ocp_ifs; | ||||
| 	} else if (rev == OMAP3630_REV_ES1_0 || rev == OMAP3630_REV_ES1_1 || | ||||
| 		   rev == OMAP3630_REV_ES1_2) { | ||||
| 		h = omap36xx_hwmod_ocp_ifs; | ||||
| 		h_gp = omap36xx_gp_hwmod_ocp_ifs; | ||||
| 		h_sham = omap36xx_sham_hwmod_ocp_ifs; | ||||
| 		h_aes = omap36xx_aes_hwmod_ocp_ifs; | ||||
| 	} else { | ||||
| @ -2820,13 +2683,6 @@ int __init omap3xxx_hwmod_init(void) | ||||
| 	if (r < 0) | ||||
| 		return r; | ||||
| 
 | ||||
| 	/* Register GP-only hwmod links. */ | ||||
| 	if (h_gp && omap_type() == OMAP2_DEVICE_TYPE_GP) { | ||||
| 		r = omap_hwmod_register_links(h_gp); | ||||
| 		if (r < 0) | ||||
| 			return r; | ||||
| 	} | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Register crypto hwmod links only if they are not disabled in DT. | ||||
| 	 * If DT information is missing, enable them only for GP devices. | ||||
|  | ||||
| @ -85,34 +85,6 @@ static struct omap_hwmod am43xx_control_hwmod = { | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| static struct omap_hwmod_class_sysconfig am43xx_synctimer_sysc = { | ||||
| 	.rev_offs	= 0x0, | ||||
| 	.sysc_offs	= 0x4, | ||||
| 	.sysc_flags	= SYSC_HAS_SIDLEMODE, | ||||
| 	.idlemodes	= (SIDLE_FORCE | SIDLE_NO), | ||||
| 	.sysc_fields	= &omap_hwmod_sysc_type1, | ||||
| }; | ||||
| 
 | ||||
| static struct omap_hwmod_class am43xx_synctimer_hwmod_class = { | ||||
| 	.name	= "synctimer", | ||||
| 	.sysc	= &am43xx_synctimer_sysc, | ||||
| }; | ||||
| 
 | ||||
| static struct omap_hwmod am43xx_synctimer_hwmod = { | ||||
| 	.name		= "counter_32k", | ||||
| 	.class		= &am43xx_synctimer_hwmod_class, | ||||
| 	.clkdm_name	= "l4_wkup_aon_clkdm", | ||||
| 	.flags		= HWMOD_SWSUP_SIDLE, | ||||
| 	.main_clk	= "synctimer_32kclk", | ||||
| 	.prcm = { | ||||
| 		.omap4 = { | ||||
| 			.clkctrl_offs = AM43XX_CM_WKUP_SYNCTIMER_CLKCTRL_OFFSET, | ||||
| 			.modulemode   = MODULEMODE_SWCTRL, | ||||
| 		}, | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| static struct omap_hwmod_class_sysconfig am43xx_usb_otg_ss_sysc = { | ||||
| 	.rev_offs	= 0x0000, | ||||
| 	.sysc_offs	= 0x0010, | ||||
| @ -206,20 +178,6 @@ static struct omap_hwmod_ocp_if am43xx_l4_wkup__control = { | ||||
| 	.user		= OCP_USER_MPU, | ||||
| }; | ||||
| 
 | ||||
| static struct omap_hwmod_ocp_if am43xx_l4_wkup__timer1 = { | ||||
| 	.master		= &am33xx_l4_wkup_hwmod, | ||||
| 	.slave		= &am33xx_timer1_hwmod, | ||||
| 	.clk		= "sys_clkin_ck", | ||||
| 	.user		= OCP_USER_MPU, | ||||
| }; | ||||
| 
 | ||||
| static struct omap_hwmod_ocp_if am33xx_l4_wkup__synctimer = { | ||||
| 	.master		= &am33xx_l4_wkup_hwmod, | ||||
| 	.slave		= &am43xx_synctimer_hwmod, | ||||
| 	.clk		= "sys_clkin_ck", | ||||
| 	.user		= OCP_USER_MPU, | ||||
| }; | ||||
| 
 | ||||
| static struct omap_hwmod_ocp_if am43xx_l3_s__usbotgss0 = { | ||||
| 	.master         = &am33xx_l3_s_hwmod, | ||||
| 	.slave          = &am43xx_usb_otg_ss0_hwmod, | ||||
| @ -235,7 +193,6 @@ static struct omap_hwmod_ocp_if am43xx_l3_s__usbotgss1 = { | ||||
| }; | ||||
| 
 | ||||
| static struct omap_hwmod_ocp_if *am43xx_hwmod_ocp_ifs[] __initdata = { | ||||
| 	&am33xx_l4_wkup__synctimer, | ||||
| 	&am33xx_mpu__l3_main, | ||||
| 	&am33xx_mpu__prcm, | ||||
| 	&am33xx_l3_s__l4_ls, | ||||
| @ -252,8 +209,6 @@ static struct omap_hwmod_ocp_if *am43xx_hwmod_ocp_ifs[] __initdata = { | ||||
| 	&am43xx_l4_wkup__control, | ||||
| 	&am43xx_l4_wkup__smartreflex0, | ||||
| 	&am43xx_l4_wkup__smartreflex1, | ||||
| 	&am43xx_l4_wkup__timer1, | ||||
| 	&am33xx_l4_ls__timer2, | ||||
| 	&am33xx_l3_s__gpmc, | ||||
| 	&am33xx_l3_main__ocmc, | ||||
| 	&am43xx_l3_s__usbotgss0, | ||||
|  | ||||
| @ -231,39 +231,6 @@ static struct omap_hwmod omap44xx_ocp_wp_noc_hwmod = { | ||||
|  * usim | ||||
|  */ | ||||
| 
 | ||||
| /*
 | ||||
|  * 'counter' class | ||||
|  * 32-bit ordinary counter, clocked by the falling edge of the 32 khz clock | ||||
|  */ | ||||
| 
 | ||||
| static struct omap_hwmod_class_sysconfig omap44xx_counter_sysc = { | ||||
| 	.rev_offs	= 0x0000, | ||||
| 	.sysc_offs	= 0x0004, | ||||
| 	.sysc_flags	= SYSC_HAS_SIDLEMODE, | ||||
| 	.idlemodes	= (SIDLE_FORCE | SIDLE_NO), | ||||
| 	.sysc_fields	= &omap_hwmod_sysc_type1, | ||||
| }; | ||||
| 
 | ||||
| static struct omap_hwmod_class omap44xx_counter_hwmod_class = { | ||||
| 	.name	= "counter", | ||||
| 	.sysc	= &omap44xx_counter_sysc, | ||||
| }; | ||||
| 
 | ||||
| /* counter_32k */ | ||||
| static struct omap_hwmod omap44xx_counter_32k_hwmod = { | ||||
| 	.name		= "counter_32k", | ||||
| 	.class		= &omap44xx_counter_hwmod_class, | ||||
| 	.clkdm_name	= "l4_wkup_clkdm", | ||||
| 	.flags		= HWMOD_SWSUP_SIDLE, | ||||
| 	.main_clk	= "sys_32k_ck", | ||||
| 	.prcm = { | ||||
| 		.omap4 = { | ||||
| 			.clkctrl_offs = OMAP4_CM_WKUP_SYNCTIMER_CLKCTRL_OFFSET, | ||||
| 			.context_offs = OMAP4_RM_WKUP_SYNCTIMER_CONTEXT_OFFSET, | ||||
| 		}, | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| /*
 | ||||
|  * 'ctrl_module' class | ||||
|  * attila core control module + core pad control module + wkup pad control | ||||
| @ -672,45 +639,6 @@ static struct omap_hwmod omap44xx_sl2if_hwmod = { | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| /*
 | ||||
|  * 'timer' class | ||||
|  * general purpose timer module with accurate 1ms tick | ||||
|  * This class contains several variants: ['timer_1ms', 'timer'] | ||||
|  */ | ||||
| 
 | ||||
| static struct omap_hwmod_class_sysconfig omap44xx_timer_1ms_sysc = { | ||||
| 	.rev_offs	= 0x0000, | ||||
| 	.sysc_offs	= 0x0010, | ||||
| 	.syss_offs	= 0x0014, | ||||
| 	.sysc_flags	= (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY | | ||||
| 			   SYSC_HAS_EMUFREE | SYSC_HAS_ENAWAKEUP | | ||||
| 			   SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | | ||||
| 			   SYSS_HAS_RESET_STATUS), | ||||
| 	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), | ||||
| 	.sysc_fields	= &omap_hwmod_sysc_type1, | ||||
| }; | ||||
| 
 | ||||
| static struct omap_hwmod_class omap44xx_timer_1ms_hwmod_class = { | ||||
| 	.name	= "timer", | ||||
| 	.sysc	= &omap44xx_timer_1ms_sysc, | ||||
| }; | ||||
| 
 | ||||
| /* timer1 */ | ||||
| static struct omap_hwmod omap44xx_timer1_hwmod = { | ||||
| 	.name		= "timer1", | ||||
| 	.class		= &omap44xx_timer_1ms_hwmod_class, | ||||
| 	.clkdm_name	= "l4_wkup_clkdm", | ||||
| 	.flags		= HWMOD_SET_DEFAULT_CLOCKACT, | ||||
| 	.main_clk	= "dmt1_clk_mux", | ||||
| 	.prcm = { | ||||
| 		.omap4 = { | ||||
| 			.clkctrl_offs = OMAP4_CM_WKUP_TIMER1_CLKCTRL_OFFSET, | ||||
| 			.context_offs = OMAP4_RM_WKUP_TIMER1_CONTEXT_OFFSET, | ||||
| 			.modulemode   = MODULEMODE_SWCTRL, | ||||
| 		}, | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| /*
 | ||||
|  * 'usb_host_fs' class | ||||
|  * full-speed usb host controller | ||||
| @ -1063,14 +991,6 @@ static struct omap_hwmod_ocp_if omap44xx_l4_cfg__ocp_wp_noc = { | ||||
| 	.user		= OCP_USER_MPU | OCP_USER_SDMA, | ||||
| }; | ||||
| 
 | ||||
| /* l4_wkup -> counter_32k */ | ||||
| static struct omap_hwmod_ocp_if omap44xx_l4_wkup__counter_32k = { | ||||
| 	.master		= &omap44xx_l4_wkup_hwmod, | ||||
| 	.slave		= &omap44xx_counter_32k_hwmod, | ||||
| 	.clk		= "l4_wkup_clk_mux_ck", | ||||
| 	.user		= OCP_USER_MPU | OCP_USER_SDMA, | ||||
| }; | ||||
| 
 | ||||
| /* l4_cfg -> ctrl_module_core */ | ||||
| static struct omap_hwmod_ocp_if omap44xx_l4_cfg__ctrl_module_core = { | ||||
| 	.master		= &omap44xx_l4_cfg_hwmod, | ||||
| @ -1199,14 +1119,6 @@ static struct omap_hwmod_ocp_if __maybe_unused omap44xx_l3_main_2__sl2if = { | ||||
| 	.user		= OCP_USER_MPU | OCP_USER_SDMA, | ||||
| }; | ||||
| 
 | ||||
| /* l4_wkup -> timer1 */ | ||||
| static struct omap_hwmod_ocp_if omap44xx_l4_wkup__timer1 = { | ||||
| 	.master		= &omap44xx_l4_wkup_hwmod, | ||||
| 	.slave		= &omap44xx_timer1_hwmod, | ||||
| 	.clk		= "l4_wkup_clk_mux_ck", | ||||
| 	.user		= OCP_USER_MPU | OCP_USER_SDMA, | ||||
| }; | ||||
| 
 | ||||
| /* l4_cfg -> usb_host_fs */ | ||||
| static struct omap_hwmod_ocp_if __maybe_unused omap44xx_l4_cfg__usb_host_fs = { | ||||
| 	.master		= &omap44xx_l4_cfg_hwmod, | ||||
| @ -1273,7 +1185,6 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = { | ||||
| 	&omap44xx_l4_cfg__l4_wkup, | ||||
| 	&omap44xx_mpu__mpu_private, | ||||
| 	&omap44xx_l4_cfg__ocp_wp_noc, | ||||
| 	&omap44xx_l4_wkup__counter_32k, | ||||
| 	&omap44xx_l4_cfg__ctrl_module_core, | ||||
| 	&omap44xx_l4_cfg__ctrl_module_pad_core, | ||||
| 	&omap44xx_l4_wkup__ctrl_module_wkup, | ||||
| @ -1290,7 +1201,6 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = { | ||||
| 	&omap44xx_l4_wkup__prm, | ||||
| 	&omap44xx_l4_wkup__scrm, | ||||
| 	/* &omap44xx_l3_main_2__sl2if, */ | ||||
| 	&omap44xx_l4_wkup__timer1, | ||||
| 	/* &omap44xx_l4_cfg__usb_host_fs, */ | ||||
| 	&omap44xx_l4_cfg__usb_host_hs, | ||||
| 	&omap44xx_l4_cfg__usb_tll_hs, | ||||
|  | ||||
| @ -193,39 +193,6 @@ static struct omap_hwmod omap54xx_mpu_private_hwmod = { | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| /*
 | ||||
|  * 'counter' class | ||||
|  * 32-bit ordinary counter, clocked by the falling edge of the 32 khz clock | ||||
|  */ | ||||
| 
 | ||||
| static struct omap_hwmod_class_sysconfig omap54xx_counter_sysc = { | ||||
| 	.rev_offs	= 0x0000, | ||||
| 	.sysc_offs	= 0x0010, | ||||
| 	.sysc_flags	= SYSC_HAS_SIDLEMODE, | ||||
| 	.idlemodes	= (SIDLE_FORCE | SIDLE_NO), | ||||
| 	.sysc_fields	= &omap_hwmod_sysc_type1, | ||||
| }; | ||||
| 
 | ||||
| static struct omap_hwmod_class omap54xx_counter_hwmod_class = { | ||||
| 	.name	= "counter", | ||||
| 	.sysc	= &omap54xx_counter_sysc, | ||||
| }; | ||||
| 
 | ||||
| /* counter_32k */ | ||||
| static struct omap_hwmod omap54xx_counter_32k_hwmod = { | ||||
| 	.name		= "counter_32k", | ||||
| 	.class		= &omap54xx_counter_hwmod_class, | ||||
| 	.clkdm_name	= "wkupaon_clkdm", | ||||
| 	.flags		= HWMOD_SWSUP_SIDLE, | ||||
| 	.main_clk	= "wkupaon_iclk_mux", | ||||
| 	.prcm = { | ||||
| 		.omap4 = { | ||||
| 			.clkctrl_offs = OMAP54XX_CM_WKUPAON_COUNTER_32K_CLKCTRL_OFFSET, | ||||
| 			.context_offs = OMAP54XX_RM_WKUPAON_COUNTER_32K_CONTEXT_OFFSET, | ||||
| 		}, | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| /*
 | ||||
|  * 'emif' class | ||||
|  * external memory interface no1 (wrapper) | ||||
| @ -299,44 +266,6 @@ static struct omap_hwmod omap54xx_mpu_hwmod = { | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| /*
 | ||||
|  * 'timer' class | ||||
|  * general purpose timer module with accurate 1ms tick | ||||
|  * This class contains several variants: ['timer_1ms', 'timer'] | ||||
|  */ | ||||
| 
 | ||||
| static struct omap_hwmod_class_sysconfig omap54xx_timer_1ms_sysc = { | ||||
| 	.rev_offs	= 0x0000, | ||||
| 	.sysc_offs	= 0x0010, | ||||
| 	.sysc_flags	= (SYSC_HAS_EMUFREE | SYSC_HAS_RESET_STATUS | | ||||
| 			   SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET), | ||||
| 	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | | ||||
| 			   SIDLE_SMART_WKUP), | ||||
| 	.sysc_fields	= &omap_hwmod_sysc_type2, | ||||
| }; | ||||
| 
 | ||||
| static struct omap_hwmod_class omap54xx_timer_1ms_hwmod_class = { | ||||
| 	.name	= "timer", | ||||
| 	.sysc	= &omap54xx_timer_1ms_sysc, | ||||
| }; | ||||
| 
 | ||||
| /* timer1 */ | ||||
| static struct omap_hwmod omap54xx_timer1_hwmod = { | ||||
| 	.name		= "timer1", | ||||
| 	.class		= &omap54xx_timer_1ms_hwmod_class, | ||||
| 	.clkdm_name	= "wkupaon_clkdm", | ||||
| 	.main_clk	= "timer1_gfclk_mux", | ||||
| 	.flags		= HWMOD_SET_DEFAULT_CLOCKACT, | ||||
| 	.prcm = { | ||||
| 		.omap4 = { | ||||
| 			.clkctrl_offs = OMAP54XX_CM_WKUPAON_TIMER1_CLKCTRL_OFFSET, | ||||
| 			.context_offs = OMAP54XX_RM_WKUPAON_TIMER1_CONTEXT_OFFSET, | ||||
| 			.modulemode   = MODULEMODE_SWCTRL, | ||||
| 		}, | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| /*
 | ||||
|  * 'usb_host_hs' class | ||||
|  * high-speed multi-port usb host controller | ||||
| @ -666,14 +595,6 @@ static struct omap_hwmod_ocp_if omap54xx_mpu__mpu_private = { | ||||
| 	.user		= OCP_USER_MPU | OCP_USER_SDMA, | ||||
| }; | ||||
| 
 | ||||
| /* l4_wkup -> counter_32k */ | ||||
| static struct omap_hwmod_ocp_if omap54xx_l4_wkup__counter_32k = { | ||||
| 	.master		= &omap54xx_l4_wkup_hwmod, | ||||
| 	.slave		= &omap54xx_counter_32k_hwmod, | ||||
| 	.clk		= "wkupaon_iclk_mux", | ||||
| 	.user		= OCP_USER_MPU | OCP_USER_SDMA, | ||||
| }; | ||||
| 
 | ||||
| /* mpu -> emif1 */ | ||||
| static struct omap_hwmod_ocp_if omap54xx_mpu__emif1 = { | ||||
| 	.master		= &omap54xx_mpu_hwmod, | ||||
| @ -698,14 +619,6 @@ static struct omap_hwmod_ocp_if omap54xx_l4_cfg__mpu = { | ||||
| 	.user		= OCP_USER_MPU | OCP_USER_SDMA, | ||||
| }; | ||||
| 
 | ||||
| /* l4_wkup -> timer1 */ | ||||
| static struct omap_hwmod_ocp_if omap54xx_l4_wkup__timer1 = { | ||||
| 	.master		= &omap54xx_l4_wkup_hwmod, | ||||
| 	.slave		= &omap54xx_timer1_hwmod, | ||||
| 	.clk		= "wkupaon_iclk_mux", | ||||
| 	.user		= OCP_USER_MPU | OCP_USER_SDMA, | ||||
| }; | ||||
| 
 | ||||
| /* l4_cfg -> usb_host_hs */ | ||||
| static struct omap_hwmod_ocp_if omap54xx_l4_cfg__usb_host_hs = { | ||||
| 	.master		= &omap54xx_l4_cfg_hwmod, | ||||
| @ -747,11 +660,9 @@ static struct omap_hwmod_ocp_if *omap54xx_hwmod_ocp_ifs[] __initdata = { | ||||
| 	&omap54xx_l3_main_2__l4_per, | ||||
| 	&omap54xx_l3_main_1__l4_wkup, | ||||
| 	&omap54xx_mpu__mpu_private, | ||||
| 	&omap54xx_l4_wkup__counter_32k, | ||||
| 	&omap54xx_mpu__emif1, | ||||
| 	&omap54xx_mpu__emif2, | ||||
| 	&omap54xx_l4_cfg__mpu, | ||||
| 	&omap54xx_l4_wkup__timer1, | ||||
| 	&omap54xx_l4_cfg__usb_host_hs, | ||||
| 	&omap54xx_l4_cfg__usb_tll_hs, | ||||
| 	&omap54xx_l4_cfg__usb_otg_ss, | ||||
|  | ||||
| @ -221,40 +221,6 @@ static struct omap_hwmod dra7xx_bb2d_hwmod = { | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| /*
 | ||||
|  * 'counter' class | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| static struct omap_hwmod_class_sysconfig dra7xx_counter_sysc = { | ||||
| 	.rev_offs	= 0x0000, | ||||
| 	.sysc_offs	= 0x0010, | ||||
| 	.sysc_flags	= SYSC_HAS_SIDLEMODE, | ||||
| 	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | | ||||
| 			   SIDLE_SMART_WKUP), | ||||
| 	.sysc_fields	= &omap_hwmod_sysc_type1, | ||||
| }; | ||||
| 
 | ||||
| static struct omap_hwmod_class dra7xx_counter_hwmod_class = { | ||||
| 	.name	= "counter", | ||||
| 	.sysc	= &dra7xx_counter_sysc, | ||||
| }; | ||||
| 
 | ||||
| /* counter_32k */ | ||||
| static struct omap_hwmod dra7xx_counter_32k_hwmod = { | ||||
| 	.name		= "counter_32k", | ||||
| 	.class		= &dra7xx_counter_hwmod_class, | ||||
| 	.clkdm_name	= "wkupaon_clkdm", | ||||
| 	.flags		= HWMOD_SWSUP_SIDLE, | ||||
| 	.main_clk	= "wkupaon_iclk_mux", | ||||
| 	.prcm = { | ||||
| 		.omap4 = { | ||||
| 			.clkctrl_offs = DRA7XX_CM_WKUPAON_COUNTER_32K_CLKCTRL_OFFSET, | ||||
| 			.context_offs = DRA7XX_RM_WKUPAON_COUNTER_32K_CONTEXT_OFFSET, | ||||
| 		}, | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| /*
 | ||||
|  * 'ctrl_module' class | ||||
|  * | ||||
| @ -525,103 +491,6 @@ static struct omap_hwmod dra7xx_sata_hwmod = { | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| /*
 | ||||
|  * 'timer' class | ||||
|  * | ||||
|  * This class contains several variants: ['timer_1ms', 'timer_secure', | ||||
|  * 'timer'] | ||||
|  */ | ||||
| 
 | ||||
| static struct omap_hwmod_class_sysconfig dra7xx_timer_1ms_sysc = { | ||||
| 	.rev_offs	= 0x0000, | ||||
| 	.sysc_offs	= 0x0010, | ||||
| 	.sysc_flags	= (SYSC_HAS_EMUFREE | SYSC_HAS_RESET_STATUS | | ||||
| 			   SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET), | ||||
| 	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | | ||||
| 			   SIDLE_SMART_WKUP), | ||||
| 	.sysc_fields	= &omap_hwmod_sysc_type2, | ||||
| }; | ||||
| 
 | ||||
| static struct omap_hwmod_class dra7xx_timer_1ms_hwmod_class = { | ||||
| 	.name	= "timer", | ||||
| 	.sysc	= &dra7xx_timer_1ms_sysc, | ||||
| }; | ||||
| 
 | ||||
| static struct omap_hwmod_class_sysconfig dra7xx_timer_sysc = { | ||||
| 	.rev_offs	= 0x0000, | ||||
| 	.sysc_offs	= 0x0010, | ||||
| 	.sysc_flags	= (SYSC_HAS_EMUFREE | SYSC_HAS_RESET_STATUS | | ||||
| 			   SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET), | ||||
| 	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | | ||||
| 			   SIDLE_SMART_WKUP), | ||||
| 	.sysc_fields	= &omap_hwmod_sysc_type2, | ||||
| }; | ||||
| 
 | ||||
| static struct omap_hwmod_class dra7xx_timer_hwmod_class = { | ||||
| 	.name	= "timer", | ||||
| 	.sysc	= &dra7xx_timer_sysc, | ||||
| }; | ||||
| 
 | ||||
| /* timer1 */ | ||||
| static struct omap_hwmod dra7xx_timer1_hwmod = { | ||||
| 	.name		= "timer1", | ||||
| 	.class		= &dra7xx_timer_1ms_hwmod_class, | ||||
| 	.clkdm_name	= "wkupaon_clkdm", | ||||
| 	.main_clk	= "timer1_gfclk_mux", | ||||
| 	.prcm = { | ||||
| 		.omap4 = { | ||||
| 			.clkctrl_offs = DRA7XX_CM_WKUPAON_TIMER1_CLKCTRL_OFFSET, | ||||
| 			.context_offs = DRA7XX_RM_WKUPAON_TIMER1_CONTEXT_OFFSET, | ||||
| 			.modulemode   = MODULEMODE_SWCTRL, | ||||
| 		}, | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| /* timer2 */ | ||||
| static struct omap_hwmod dra7xx_timer2_hwmod = { | ||||
| 	.name		= "timer2", | ||||
| 	.class		= &dra7xx_timer_1ms_hwmod_class, | ||||
| 	.clkdm_name	= "l4per_clkdm", | ||||
| 	.main_clk	= "timer2_gfclk_mux", | ||||
| 	.prcm = { | ||||
| 		.omap4 = { | ||||
| 			.clkctrl_offs = DRA7XX_CM_L4PER_TIMER2_CLKCTRL_OFFSET, | ||||
| 			.context_offs = DRA7XX_RM_L4PER_TIMER2_CONTEXT_OFFSET, | ||||
| 			.modulemode   = MODULEMODE_SWCTRL, | ||||
| 		}, | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| /* timer3 */ | ||||
| static struct omap_hwmod dra7xx_timer3_hwmod = { | ||||
| 	.name		= "timer3", | ||||
| 	.class		= &dra7xx_timer_hwmod_class, | ||||
| 	.clkdm_name	= "l4per_clkdm", | ||||
| 	.main_clk	= "timer3_gfclk_mux", | ||||
| 	.prcm = { | ||||
| 		.omap4 = { | ||||
| 			.clkctrl_offs = DRA7XX_CM_L4PER_TIMER3_CLKCTRL_OFFSET, | ||||
| 			.context_offs = DRA7XX_RM_L4PER_TIMER3_CONTEXT_OFFSET, | ||||
| 			.modulemode   = MODULEMODE_SWCTRL, | ||||
| 		}, | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| /* timer4 */ | ||||
| static struct omap_hwmod dra7xx_timer4_hwmod = { | ||||
| 	.name		= "timer4", | ||||
| 	.class		= &dra7xx_timer_hwmod_class, | ||||
| 	.clkdm_name	= "l4per_clkdm", | ||||
| 	.main_clk	= "timer4_gfclk_mux", | ||||
| 	.prcm = { | ||||
| 		.omap4 = { | ||||
| 			.clkctrl_offs = DRA7XX_CM_L4PER_TIMER4_CLKCTRL_OFFSET, | ||||
| 			.context_offs = DRA7XX_RM_L4PER_TIMER4_CONTEXT_OFFSET, | ||||
| 			.modulemode   = MODULEMODE_SWCTRL, | ||||
| 		}, | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| /*
 | ||||
|  * 'usb_otg_ss' class | ||||
|  * | ||||
| @ -864,14 +733,6 @@ static struct omap_hwmod_ocp_if dra7xx_l3_main_1__bb2d = { | ||||
| 	.user		= OCP_USER_MPU | OCP_USER_SDMA, | ||||
| }; | ||||
| 
 | ||||
| /* l4_wkup -> counter_32k */ | ||||
| static struct omap_hwmod_ocp_if dra7xx_l4_wkup__counter_32k = { | ||||
| 	.master		= &dra7xx_l4_wkup_hwmod, | ||||
| 	.slave		= &dra7xx_counter_32k_hwmod, | ||||
| 	.clk		= "wkupaon_iclk_mux", | ||||
| 	.user		= OCP_USER_MPU | OCP_USER_SDMA, | ||||
| }; | ||||
| 
 | ||||
| /* l4_wkup -> ctrl_module_wkup */ | ||||
| static struct omap_hwmod_ocp_if dra7xx_l4_wkup__ctrl_module_wkup = { | ||||
| 	.master		= &dra7xx_l4_wkup_hwmod, | ||||
| @ -952,38 +813,6 @@ static struct omap_hwmod_ocp_if dra7xx_l4_cfg__sata = { | ||||
| 	.user		= OCP_USER_MPU | OCP_USER_SDMA, | ||||
| }; | ||||
| 
 | ||||
| /* l4_wkup -> timer1 */ | ||||
| static struct omap_hwmod_ocp_if dra7xx_l4_wkup__timer1 = { | ||||
| 	.master		= &dra7xx_l4_wkup_hwmod, | ||||
| 	.slave		= &dra7xx_timer1_hwmod, | ||||
| 	.clk		= "wkupaon_iclk_mux", | ||||
| 	.user		= OCP_USER_MPU | OCP_USER_SDMA, | ||||
| }; | ||||
| 
 | ||||
| /* l4_per1 -> timer2 */ | ||||
| static struct omap_hwmod_ocp_if dra7xx_l4_per1__timer2 = { | ||||
| 	.master		= &dra7xx_l4_per1_hwmod, | ||||
| 	.slave		= &dra7xx_timer2_hwmod, | ||||
| 	.clk		= "l3_iclk_div", | ||||
| 	.user		= OCP_USER_MPU | OCP_USER_SDMA, | ||||
| }; | ||||
| 
 | ||||
| /* l4_per1 -> timer3 */ | ||||
| static struct omap_hwmod_ocp_if dra7xx_l4_per1__timer3 = { | ||||
| 	.master		= &dra7xx_l4_per1_hwmod, | ||||
| 	.slave		= &dra7xx_timer3_hwmod, | ||||
| 	.clk		= "l3_iclk_div", | ||||
| 	.user		= OCP_USER_MPU | OCP_USER_SDMA, | ||||
| }; | ||||
| 
 | ||||
| /* l4_per1 -> timer4 */ | ||||
| static struct omap_hwmod_ocp_if dra7xx_l4_per1__timer4 = { | ||||
| 	.master		= &dra7xx_l4_per1_hwmod, | ||||
| 	.slave		= &dra7xx_timer4_hwmod, | ||||
| 	.clk		= "l3_iclk_div", | ||||
| 	.user		= OCP_USER_MPU | OCP_USER_SDMA, | ||||
| }; | ||||
| 
 | ||||
| /* l4_per3 -> usb_otg_ss1 */ | ||||
| static struct omap_hwmod_ocp_if dra7xx_l4_per3__usb_otg_ss1 = { | ||||
| 	.master		= &dra7xx_l4_per3_hwmod, | ||||
| @ -1062,7 +891,6 @@ static struct omap_hwmod_ocp_if *dra7xx_hwmod_ocp_ifs[] __initdata = { | ||||
| 	&dra7xx_l3_main_1__l4_wkup, | ||||
| 	&dra7xx_l4_per2__atl, | ||||
| 	&dra7xx_l3_main_1__bb2d, | ||||
| 	&dra7xx_l4_wkup__counter_32k, | ||||
| 	&dra7xx_l4_wkup__ctrl_module_wkup, | ||||
| 	&dra7xx_l3_main_1__gpmc, | ||||
| 	&dra7xx_l4_cfg__mpu, | ||||
| @ -1072,10 +900,6 @@ static struct omap_hwmod_ocp_if *dra7xx_hwmod_ocp_ifs[] __initdata = { | ||||
| 	&dra7xx_l4_cfg__pciess2, | ||||
| 	&dra7xx_l3_main_1__qspi, | ||||
| 	&dra7xx_l4_cfg__sata, | ||||
| 	&dra7xx_l4_wkup__timer1, | ||||
| 	&dra7xx_l4_per1__timer2, | ||||
| 	&dra7xx_l4_per1__timer3, | ||||
| 	&dra7xx_l4_per1__timer4, | ||||
| 	&dra7xx_l4_per3__usb_otg_ss1, | ||||
| 	&dra7xx_l4_per3__usb_otg_ss2, | ||||
| 	&dra7xx_l4_per3__usb_otg_ss3, | ||||
|  | ||||
| @ -690,76 +690,6 @@ static struct omap_hwmod_class dm816x_timer_hwmod_class = { | ||||
| 	.sysc = &dm816x_timer_sysc, | ||||
| }; | ||||
| 
 | ||||
| static struct omap_hwmod dm814x_timer1_hwmod = { | ||||
| 	.name		= "timer1", | ||||
| 	.clkdm_name	= "alwon_l3s_clkdm", | ||||
| 	.main_clk	= "timer1_fck", | ||||
| 	.class		= &dm816x_timer_hwmod_class, | ||||
| 	.flags		= HWMOD_NO_IDLEST, | ||||
| }; | ||||
| 
 | ||||
| static struct omap_hwmod_ocp_if dm814x_l4_ls__timer1 = { | ||||
| 	.master		= &dm81xx_l4_ls_hwmod, | ||||
| 	.slave		= &dm814x_timer1_hwmod, | ||||
| 	.clk		= "sysclk6_ck", | ||||
| 	.user		= OCP_USER_MPU, | ||||
| }; | ||||
| 
 | ||||
| static struct omap_hwmod dm816x_timer1_hwmod = { | ||||
| 	.name		= "timer1", | ||||
| 	.clkdm_name	= "alwon_l3s_clkdm", | ||||
| 	.main_clk	= "timer1_fck", | ||||
| 	.prcm		= { | ||||
| 		.omap4 = { | ||||
| 			.clkctrl_offs = DM816X_CM_ALWON_TIMER_1_CLKCTRL, | ||||
| 			.modulemode = MODULEMODE_SWCTRL, | ||||
| 		}, | ||||
| 	}, | ||||
| 	.class		= &dm816x_timer_hwmod_class, | ||||
| }; | ||||
| 
 | ||||
| static struct omap_hwmod_ocp_if dm816x_l4_ls__timer1 = { | ||||
| 	.master		= &dm81xx_l4_ls_hwmod, | ||||
| 	.slave		= &dm816x_timer1_hwmod, | ||||
| 	.clk		= "sysclk6_ck", | ||||
| 	.user		= OCP_USER_MPU, | ||||
| }; | ||||
| 
 | ||||
| static struct omap_hwmod dm814x_timer2_hwmod = { | ||||
| 	.name		= "timer2", | ||||
| 	.clkdm_name	= "alwon_l3s_clkdm", | ||||
| 	.main_clk	= "timer2_fck", | ||||
| 	.class		= &dm816x_timer_hwmod_class, | ||||
| 	.flags		= HWMOD_NO_IDLEST, | ||||
| }; | ||||
| 
 | ||||
| static struct omap_hwmod_ocp_if dm814x_l4_ls__timer2 = { | ||||
| 	.master		= &dm81xx_l4_ls_hwmod, | ||||
| 	.slave		= &dm814x_timer2_hwmod, | ||||
| 	.clk		= "sysclk6_ck", | ||||
| 	.user		= OCP_USER_MPU, | ||||
| }; | ||||
| 
 | ||||
| static struct omap_hwmod dm816x_timer2_hwmod = { | ||||
| 	.name		= "timer2", | ||||
| 	.clkdm_name	= "alwon_l3s_clkdm", | ||||
| 	.main_clk	= "timer2_fck", | ||||
| 	.prcm		= { | ||||
| 		.omap4 = { | ||||
| 			.clkctrl_offs = DM816X_CM_ALWON_TIMER_2_CLKCTRL, | ||||
| 			.modulemode = MODULEMODE_SWCTRL, | ||||
| 		}, | ||||
| 	}, | ||||
| 	.class		= &dm816x_timer_hwmod_class, | ||||
| }; | ||||
| 
 | ||||
| static struct omap_hwmod_ocp_if dm816x_l4_ls__timer2 = { | ||||
| 	.master		= &dm81xx_l4_ls_hwmod, | ||||
| 	.slave		= &dm816x_timer2_hwmod, | ||||
| 	.clk		= "sysclk6_ck", | ||||
| 	.user		= OCP_USER_MPU, | ||||
| }; | ||||
| 
 | ||||
| static struct omap_hwmod dm816x_timer3_hwmod = { | ||||
| 	.name		= "timer3", | ||||
| 	.clkdm_name	= "alwon_l3s_clkdm", | ||||
| @ -1288,8 +1218,6 @@ static struct omap_hwmod_ocp_if *dm814x_hwmod_ocp_ifs[] __initdata = { | ||||
| 	&dm814x_l4_ls__mmc1, | ||||
| 	&dm814x_l4_ls__mmc2, | ||||
| 	&ti81xx_l4_ls__rtc, | ||||
| 	&dm814x_l4_ls__timer1, | ||||
| 	&dm814x_l4_ls__timer2, | ||||
| 	&dm81xx_alwon_l3_slow__gpmc, | ||||
| 	&dm814x_default_l3_slow__usbss, | ||||
| 	&dm814x_alwon_l3_med__mmc3, | ||||
| @ -1318,8 +1246,6 @@ static struct omap_hwmod_ocp_if *dm816x_hwmod_ocp_ifs[] __initdata = { | ||||
| 	&dm81xx_l4_ls__elm, | ||||
| 	&ti81xx_l4_ls__rtc, | ||||
| 	&dm816x_l4_ls__mmc1, | ||||
| 	&dm816x_l4_ls__timer1, | ||||
| 	&dm816x_l4_ls__timer2, | ||||
| 	&dm816x_l4_ls__timer3, | ||||
| 	&dm816x_l4_ls__timer4, | ||||
| 	&dm816x_l4_ls__timer5, | ||||
|  | ||||
| @ -21,8 +21,6 @@ extern struct omap_hwmod omap2xxx_l4_core_hwmod; | ||||
| extern struct omap_hwmod omap2xxx_l4_wkup_hwmod; | ||||
| extern struct omap_hwmod omap2xxx_mpu_hwmod; | ||||
| extern struct omap_hwmod omap2xxx_iva_hwmod; | ||||
| extern struct omap_hwmod omap2xxx_timer1_hwmod; | ||||
| extern struct omap_hwmod omap2xxx_timer2_hwmod; | ||||
| extern struct omap_hwmod omap2xxx_timer3_hwmod; | ||||
| extern struct omap_hwmod omap2xxx_timer4_hwmod; | ||||
| extern struct omap_hwmod omap2xxx_timer5_hwmod; | ||||
| @ -47,7 +45,6 @@ extern struct omap_hwmod omap2xxx_gpio3_hwmod; | ||||
| extern struct omap_hwmod omap2xxx_gpio4_hwmod; | ||||
| extern struct omap_hwmod omap2xxx_mcspi1_hwmod; | ||||
| extern struct omap_hwmod omap2xxx_mcspi2_hwmod; | ||||
| extern struct omap_hwmod omap2xxx_counter_32k_hwmod; | ||||
| extern struct omap_hwmod omap2xxx_gpmc_hwmod; | ||||
| extern struct omap_hwmod omap2xxx_rng_hwmod; | ||||
| extern struct omap_hwmod omap2xxx_sham_hwmod; | ||||
|  | ||||
| @ -26,34 +26,12 @@ | ||||
|  * License. See the file "COPYING" in the main directory of this archive | ||||
|  * for more details. | ||||
|  */ | ||||
| #include <linux/init.h> | ||||
| #include <linux/time.h> | ||||
| #include <linux/interrupt.h> | ||||
| #include <linux/err.h> | ||||
| #include <linux/clk.h> | ||||
| #include <linux/delay.h> | ||||
| #include <linux/irq.h> | ||||
| #include <linux/clocksource.h> | ||||
| #include <linux/clockchips.h> | ||||
| #include <linux/slab.h> | ||||
| #include <linux/of.h> | ||||
| #include <linux/of_address.h> | ||||
| #include <linux/of_irq.h> | ||||
| #include <linux/platform_device.h> | ||||
| #include <linux/platform_data/dmtimer-omap.h> | ||||
| #include <linux/sched_clock.h> | ||||
| 
 | ||||
| #include <asm/mach/time.h> | ||||
| 
 | ||||
| #include "omap_hwmod.h" | ||||
| #include "omap_device.h" | ||||
| #include <plat/counter-32k.h> | ||||
| #include <clocksource/timer-ti-dm.h> | ||||
| 
 | ||||
| #include "soc.h" | ||||
| #include "common.h" | ||||
| #include "control.h" | ||||
| #include "powerdomain.h" | ||||
| #include "omap-secure.h" | ||||
| 
 | ||||
| #define REALTIME_COUNTER_BASE				0x48243200 | ||||
| @ -61,294 +39,12 @@ | ||||
| #define INCREMENTER_DENUMERATOR_RELOAD_OFFSET		0x14 | ||||
| #define NUMERATOR_DENUMERATOR_MASK			0xfffff000 | ||||
| 
 | ||||
| /* Clockevent code */ | ||||
| 
 | ||||
| static struct omap_dm_timer clkev; | ||||
| static struct clock_event_device clockevent_gpt; | ||||
| 
 | ||||
| /* Clockevent hwmod for am335x and am437x suspend */ | ||||
| static struct omap_hwmod *clockevent_gpt_hwmod; | ||||
| 
 | ||||
| /* Clockesource hwmod for am437x suspend */ | ||||
| static struct omap_hwmod *clocksource_gpt_hwmod; | ||||
| 
 | ||||
| #ifdef CONFIG_SOC_HAS_REALTIME_COUNTER | ||||
| static unsigned long arch_timer_freq; | ||||
| 
 | ||||
| void set_cntfreq(void) | ||||
| { | ||||
| 	omap_smc1(OMAP5_DRA7_MON_SET_CNTFRQ_INDEX, arch_timer_freq); | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id) | ||||
| { | ||||
| 	struct clock_event_device *evt = &clockevent_gpt; | ||||
| 
 | ||||
| 	__omap_dm_timer_write_status(&clkev, OMAP_TIMER_INT_OVERFLOW); | ||||
| 
 | ||||
| 	evt->event_handler(evt); | ||||
| 	return IRQ_HANDLED; | ||||
| } | ||||
| 
 | ||||
| static int omap2_gp_timer_set_next_event(unsigned long cycles, | ||||
| 					 struct clock_event_device *evt) | ||||
| { | ||||
| 	__omap_dm_timer_load_start(&clkev, OMAP_TIMER_CTRL_ST, | ||||
| 				   0xffffffff - cycles, OMAP_TIMER_POSTED); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int omap2_gp_timer_shutdown(struct clock_event_device *evt) | ||||
| { | ||||
| 	__omap_dm_timer_stop(&clkev, OMAP_TIMER_POSTED, clkev.rate); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int omap2_gp_timer_set_periodic(struct clock_event_device *evt) | ||||
| { | ||||
| 	u32 period; | ||||
| 
 | ||||
| 	__omap_dm_timer_stop(&clkev, OMAP_TIMER_POSTED, clkev.rate); | ||||
| 
 | ||||
| 	period = clkev.rate / HZ; | ||||
| 	period -= 1; | ||||
| 	/* Looks like we need to first set the load value separately */ | ||||
| 	__omap_dm_timer_write(&clkev, OMAP_TIMER_LOAD_REG, 0xffffffff - period, | ||||
| 			      OMAP_TIMER_POSTED); | ||||
| 	__omap_dm_timer_load_start(&clkev, | ||||
| 				   OMAP_TIMER_CTRL_AR | OMAP_TIMER_CTRL_ST, | ||||
| 				   0xffffffff - period, OMAP_TIMER_POSTED); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static void omap_clkevt_idle(struct clock_event_device *unused) | ||||
| { | ||||
| 	if (!clockevent_gpt_hwmod) | ||||
| 		return; | ||||
| 
 | ||||
| 	omap_hwmod_idle(clockevent_gpt_hwmod); | ||||
| } | ||||
| 
 | ||||
| static void omap_clkevt_unidle(struct clock_event_device *unused) | ||||
| { | ||||
| 	if (!clockevent_gpt_hwmod) | ||||
| 		return; | ||||
| 
 | ||||
| 	omap_hwmod_enable(clockevent_gpt_hwmod); | ||||
| 	__omap_dm_timer_int_enable(&clkev, OMAP_TIMER_INT_OVERFLOW); | ||||
| } | ||||
| 
 | ||||
| static struct clock_event_device clockevent_gpt = { | ||||
| 	.features		= CLOCK_EVT_FEAT_PERIODIC | | ||||
| 				  CLOCK_EVT_FEAT_ONESHOT, | ||||
| 	.rating			= 300, | ||||
| 	.set_next_event		= omap2_gp_timer_set_next_event, | ||||
| 	.set_state_shutdown	= omap2_gp_timer_shutdown, | ||||
| 	.set_state_periodic	= omap2_gp_timer_set_periodic, | ||||
| 	.set_state_oneshot	= omap2_gp_timer_shutdown, | ||||
| 	.tick_resume		= omap2_gp_timer_shutdown, | ||||
| }; | ||||
| 
 | ||||
| static const struct of_device_id omap_timer_match[] __initconst = { | ||||
| 	{ .compatible = "ti,omap2420-timer", }, | ||||
| 	{ .compatible = "ti,omap3430-timer", }, | ||||
| 	{ .compatible = "ti,omap4430-timer", }, | ||||
| 	{ .compatible = "ti,omap5430-timer", }, | ||||
| 	{ .compatible = "ti,dm814-timer", }, | ||||
| 	{ .compatible = "ti,dm816-timer", }, | ||||
| 	{ .compatible = "ti,am335x-timer", }, | ||||
| 	{ .compatible = "ti,am335x-timer-1ms", }, | ||||
| 	{ } | ||||
| }; | ||||
| 
 | ||||
| static int omap_timer_add_disabled_property(struct device_node *np) | ||||
| { | ||||
| 	struct property *prop; | ||||
| 
 | ||||
| 	prop = kzalloc(sizeof(*prop), GFP_KERNEL); | ||||
| 	if (!prop) | ||||
| 		return -ENOMEM; | ||||
| 
 | ||||
| 	prop->name = "status"; | ||||
| 	prop->value = "disabled"; | ||||
| 	prop->length = strlen(prop->value); | ||||
| 
 | ||||
| 	return of_add_property(np, prop); | ||||
| } | ||||
| 
 | ||||
| static int omap_timer_update_dt(struct device_node *np) | ||||
| { | ||||
| 	int error = 0; | ||||
| 
 | ||||
| 	if (!of_device_is_compatible(np, "ti,omap-counter32k")) { | ||||
| 		error = omap_timer_add_disabled_property(np); | ||||
| 		if (error) | ||||
| 			return error; | ||||
| 	} | ||||
| 
 | ||||
| 	/* No parent interconnect target module configured? */ | ||||
| 	if (of_get_property(np, "ti,hwmods", NULL)) | ||||
| 		return error; | ||||
| 
 | ||||
| 	/* Tag parent interconnect target module disabled */ | ||||
| 	error = omap_timer_add_disabled_property(np->parent); | ||||
| 	if (error) | ||||
| 		return error; | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * omap_get_timer_dt - get a timer using device-tree | ||||
|  * @match	- device-tree match structure for matching a device type | ||||
|  * @property	- optional timer property to match | ||||
|  * | ||||
|  * Helper function to get a timer during early boot using device-tree for use | ||||
|  * as kernel system timer. Optionally, the property argument can be used to | ||||
|  * select a timer with a specific property. Once a timer is found then mark | ||||
|  * the timer node in device-tree as disabled, to prevent the kernel from | ||||
|  * registering this timer as a platform device and so no one else can use it. | ||||
|  */ | ||||
| static struct device_node * __init omap_get_timer_dt(const struct of_device_id *match, | ||||
| 						     const char *property) | ||||
| { | ||||
| 	struct device_node *np; | ||||
| 	int error; | ||||
| 
 | ||||
| 	for_each_matching_node(np, match) { | ||||
| 		if (!of_device_is_available(np)) | ||||
| 			continue; | ||||
| 
 | ||||
| 		if (property && !of_get_property(np, property, NULL)) | ||||
| 			continue; | ||||
| 
 | ||||
| 		if (!property && (of_get_property(np, "ti,timer-alwon", NULL) || | ||||
| 				  of_get_property(np, "ti,timer-dsp", NULL) || | ||||
| 				  of_get_property(np, "ti,timer-pwm", NULL) || | ||||
| 				  of_get_property(np, "ti,timer-secure", NULL))) | ||||
| 			continue; | ||||
| 
 | ||||
| 		error = omap_timer_update_dt(np); | ||||
| 		WARN(error, "%s: Could not update dt: %i\n", __func__, error); | ||||
| 
 | ||||
| 		return np; | ||||
| 	} | ||||
| 
 | ||||
| 	return NULL; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * omap_dmtimer_init - initialisation function when device tree is used | ||||
|  * | ||||
|  * For secure OMAP3/DRA7xx devices, timers with device type "timer-secure" | ||||
|  * cannot be used by the kernel as they are reserved. Therefore, to prevent the | ||||
|  * kernel registering these devices remove them dynamically from the device | ||||
|  * tree on boot. | ||||
|  */ | ||||
| static void __init omap_dmtimer_init(void) | ||||
| { | ||||
| 	struct device_node *np; | ||||
| 
 | ||||
| 	if (!cpu_is_omap34xx() && !soc_is_dra7xx()) | ||||
| 		return; | ||||
| 
 | ||||
| 	/* If we are a secure device, remove any secure timer nodes */ | ||||
| 	if ((omap_type() != OMAP2_DEVICE_TYPE_GP)) { | ||||
| 		np = omap_get_timer_dt(omap_timer_match, "ti,timer-secure"); | ||||
| 		of_node_put(np); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * omap_dm_timer_get_errata - get errata flags for a timer | ||||
|  * | ||||
|  * Get the timer errata flags that are specific to the OMAP device being used. | ||||
|  */ | ||||
| static u32 __init omap_dm_timer_get_errata(void) | ||||
| { | ||||
| 	if (cpu_is_omap24xx()) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	return OMAP_TIMER_ERRATA_I103_I767; | ||||
| } | ||||
| 
 | ||||
| static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, | ||||
| 					 const char *fck_source, | ||||
| 					 const char *property, | ||||
| 					 const char **timer_name, | ||||
| 					 int posted) | ||||
| { | ||||
| 	const char *oh_name = NULL; | ||||
| 	struct device_node *np; | ||||
| 	struct omap_hwmod *oh; | ||||
| 	struct clk *src; | ||||
| 	int r = 0; | ||||
| 
 | ||||
| 	np = omap_get_timer_dt(omap_timer_match, property); | ||||
| 	if (!np) | ||||
| 		return -ENODEV; | ||||
| 
 | ||||
| 	of_property_read_string_index(np, "ti,hwmods", 0, &oh_name); | ||||
| 	if (!oh_name) { | ||||
| 		of_property_read_string_index(np->parent, "ti,hwmods", 0, | ||||
| 					      &oh_name); | ||||
| 		if (!oh_name) | ||||
| 			return -ENODEV; | ||||
| 	} | ||||
| 
 | ||||
| 	timer->irq = irq_of_parse_and_map(np, 0); | ||||
| 	if (!timer->irq) | ||||
| 		return -ENXIO; | ||||
| 
 | ||||
| 	timer->io_base = of_iomap(np, 0); | ||||
| 
 | ||||
| 	timer->fclk = of_clk_get_by_name(np, "fck"); | ||||
| 
 | ||||
| 	of_node_put(np); | ||||
| 
 | ||||
| 	oh = omap_hwmod_lookup(oh_name); | ||||
| 	if (!oh) | ||||
| 		return -ENODEV; | ||||
| 
 | ||||
| 	*timer_name = oh->name; | ||||
| 
 | ||||
| 	if (!timer->io_base) | ||||
| 		return -ENXIO; | ||||
| 
 | ||||
| 	omap_hwmod_setup_one(oh_name); | ||||
| 
 | ||||
| 	/* After the dmtimer is using hwmod these clocks won't be needed */ | ||||
| 	if (IS_ERR_OR_NULL(timer->fclk)) | ||||
| 		timer->fclk = clk_get(NULL, omap_hwmod_get_main_clk(oh)); | ||||
| 	if (IS_ERR(timer->fclk)) | ||||
| 		return PTR_ERR(timer->fclk); | ||||
| 
 | ||||
| 	src = clk_get(NULL, fck_source); | ||||
| 	if (IS_ERR(src)) | ||||
| 		return PTR_ERR(src); | ||||
| 
 | ||||
| 	WARN(clk_set_parent(timer->fclk, src) < 0, | ||||
| 	     "Cannot set timer parent clock, no PLL clock driver?"); | ||||
| 
 | ||||
| 	clk_put(src); | ||||
| 
 | ||||
| 	omap_hwmod_enable(oh); | ||||
| 	__omap_dm_timer_init_regs(timer); | ||||
| 
 | ||||
| 	if (posted) | ||||
| 		__omap_dm_timer_enable_posted(timer); | ||||
| 
 | ||||
| 	/* Check that the intended posted configuration matches the actual */ | ||||
| 	if (posted != timer->posted) | ||||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	timer->rate = clk_get_rate(timer->fclk); | ||||
| 	timer->reserved = 1; | ||||
| 
 | ||||
| 	return r; | ||||
| } | ||||
| 
 | ||||
| #if !defined(CONFIG_SMP) && defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) | ||||
| void tick_broadcast(const struct cpumask *mask) | ||||
| @ -356,241 +52,6 @@ void tick_broadcast(const struct cpumask *mask) | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| static void __init omap2_gp_clockevent_init(int gptimer_id, | ||||
| 						const char *fck_source, | ||||
| 						const char *property) | ||||
| { | ||||
| 	int res; | ||||
| 
 | ||||
| 	clkev.id = gptimer_id; | ||||
| 	clkev.errata = omap_dm_timer_get_errata(); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * For clock-event timers we never read the timer counter and | ||||
| 	 * so we are not impacted by errata i103 and i767. Therefore, | ||||
| 	 * we can safely ignore this errata for clock-event timers. | ||||
| 	 */ | ||||
| 	__omap_dm_timer_override_errata(&clkev, OMAP_TIMER_ERRATA_I103_I767); | ||||
| 
 | ||||
| 	res = omap_dm_timer_init_one(&clkev, fck_source, property, | ||||
| 				     &clockevent_gpt.name, OMAP_TIMER_POSTED); | ||||
| 	BUG_ON(res); | ||||
| 
 | ||||
| 	if (request_irq(clkev.irq, omap2_gp_timer_interrupt, | ||||
| 			IRQF_TIMER | IRQF_IRQPOLL, "gp_timer", &clkev)) | ||||
| 		pr_err("Failed to request irq %d (gp_timer)\n", clkev.irq); | ||||
| 
 | ||||
| 	__omap_dm_timer_int_enable(&clkev, OMAP_TIMER_INT_OVERFLOW); | ||||
| 
 | ||||
| 	clockevent_gpt.cpumask = cpu_possible_mask; | ||||
| 	clockevent_gpt.irq = omap_dm_timer_get_irq(&clkev); | ||||
| 	clockevents_config_and_register(&clockevent_gpt, clkev.rate, | ||||
| 					3, /* Timer internal resynch latency */ | ||||
| 					0xffffffff); | ||||
| 
 | ||||
| 	if (soc_is_am33xx() || soc_is_am43xx()) { | ||||
| 		clockevent_gpt.suspend = omap_clkevt_idle; | ||||
| 		clockevent_gpt.resume = omap_clkevt_unidle; | ||||
| 
 | ||||
| 		clockevent_gpt_hwmod = | ||||
| 			omap_hwmod_lookup(clockevent_gpt.name); | ||||
| 	} | ||||
| 
 | ||||
| 	pr_info("OMAP clockevent source: %s at %lu Hz\n", clockevent_gpt.name, | ||||
| 		clkev.rate); | ||||
| } | ||||
| 
 | ||||
| /* Clocksource code */ | ||||
| static struct omap_dm_timer clksrc; | ||||
| static bool use_gptimer_clksrc __initdata; | ||||
| 
 | ||||
| /*
 | ||||
|  * clocksource | ||||
|  */ | ||||
| static u64 clocksource_read_cycles(struct clocksource *cs) | ||||
| { | ||||
| 	return (u64)__omap_dm_timer_read_counter(&clksrc, | ||||
| 						     OMAP_TIMER_NONPOSTED); | ||||
| } | ||||
| 
 | ||||
| static struct clocksource clocksource_gpt = { | ||||
| 	.rating		= 300, | ||||
| 	.read		= clocksource_read_cycles, | ||||
| 	.mask		= CLOCKSOURCE_MASK(32), | ||||
| 	.flags		= CLOCK_SOURCE_IS_CONTINUOUS, | ||||
| }; | ||||
| 
 | ||||
| static u64 notrace dmtimer_read_sched_clock(void) | ||||
| { | ||||
| 	if (clksrc.reserved) | ||||
| 		return __omap_dm_timer_read_counter(&clksrc, | ||||
| 						    OMAP_TIMER_NONPOSTED); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static const struct of_device_id omap_counter_match[] __initconst = { | ||||
| 	{ .compatible = "ti,omap-counter32k", }, | ||||
| 	{ } | ||||
| }; | ||||
| 
 | ||||
| /* Setup free-running counter for clocksource */ | ||||
| static int __init __maybe_unused omap2_sync32k_clocksource_init(void) | ||||
| { | ||||
| 	int ret; | ||||
| 	struct device_node *np = NULL; | ||||
| 	struct omap_hwmod *oh; | ||||
| 	const char *oh_name = "counter_32k"; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * See if the 32kHz counter is supported. | ||||
| 	 */ | ||||
| 	np = omap_get_timer_dt(omap_counter_match, NULL); | ||||
| 	if (!np) | ||||
| 		return -ENODEV; | ||||
| 
 | ||||
| 	of_property_read_string_index(np->parent, "ti,hwmods", 0, &oh_name); | ||||
| 	if (!oh_name) { | ||||
| 		of_property_read_string_index(np, "ti,hwmods", 0, &oh_name); | ||||
| 		if (!oh_name) | ||||
| 			return -ENODEV; | ||||
| 	} | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * First check hwmod data is available for sync32k counter | ||||
| 	 */ | ||||
| 	oh = omap_hwmod_lookup(oh_name); | ||||
| 	if (!oh || oh->slaves_cnt == 0) | ||||
| 		return -ENODEV; | ||||
| 
 | ||||
| 	omap_hwmod_setup_one(oh_name); | ||||
| 
 | ||||
| 	ret = omap_hwmod_enable(oh); | ||||
| 	if (ret) { | ||||
| 		pr_warn("%s: failed to enable counter_32k module (%d)\n", | ||||
| 							__func__, ret); | ||||
| 		return ret; | ||||
| 	} | ||||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| static unsigned int omap2_gptimer_clksrc_load; | ||||
| 
 | ||||
| static void omap2_gptimer_clksrc_suspend(struct clocksource *unused) | ||||
| { | ||||
| 	omap2_gptimer_clksrc_load = | ||||
| 		__omap_dm_timer_read_counter(&clksrc, OMAP_TIMER_NONPOSTED); | ||||
| 
 | ||||
| 	omap_hwmod_idle(clocksource_gpt_hwmod); | ||||
| } | ||||
| 
 | ||||
| static void omap2_gptimer_clksrc_resume(struct clocksource *unused) | ||||
| { | ||||
| 	omap_hwmod_enable(clocksource_gpt_hwmod); | ||||
| 
 | ||||
| 	__omap_dm_timer_load_start(&clksrc, | ||||
| 				   OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR, | ||||
| 				   omap2_gptimer_clksrc_load, | ||||
| 				   OMAP_TIMER_NONPOSTED); | ||||
| } | ||||
| 
 | ||||
| static void __init omap2_gptimer_clocksource_init(int gptimer_id, | ||||
| 						  const char *fck_source, | ||||
| 						  const char *property) | ||||
| { | ||||
| 	int res; | ||||
| 
 | ||||
| 	clksrc.id = gptimer_id; | ||||
| 	clksrc.errata = omap_dm_timer_get_errata(); | ||||
| 
 | ||||
| 	res = omap_dm_timer_init_one(&clksrc, fck_source, property, | ||||
| 				     &clocksource_gpt.name, | ||||
| 				     OMAP_TIMER_NONPOSTED); | ||||
| 
 | ||||
| 	if (soc_is_am43xx()) { | ||||
| 		clocksource_gpt.suspend = omap2_gptimer_clksrc_suspend; | ||||
| 		clocksource_gpt.resume = omap2_gptimer_clksrc_resume; | ||||
| 
 | ||||
| 		clocksource_gpt_hwmod = | ||||
| 			omap_hwmod_lookup(clocksource_gpt.name); | ||||
| 	} | ||||
| 
 | ||||
| 	BUG_ON(res); | ||||
| 
 | ||||
| 	__omap_dm_timer_load_start(&clksrc, | ||||
| 				   OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR, 0, | ||||
| 				   OMAP_TIMER_NONPOSTED); | ||||
| 	sched_clock_register(dmtimer_read_sched_clock, 32, clksrc.rate); | ||||
| 
 | ||||
| 	if (clocksource_register_hz(&clocksource_gpt, clksrc.rate)) | ||||
| 		pr_err("Could not register clocksource %s\n", | ||||
| 			clocksource_gpt.name); | ||||
| 	else | ||||
| 		pr_info("OMAP clocksource: %s at %lu Hz\n", | ||||
| 			clocksource_gpt.name, clksrc.rate); | ||||
| } | ||||
| 
 | ||||
| static void __init __omap_sync32k_timer_init(int clkev_nr, const char *clkev_src, | ||||
| 		const char *clkev_prop, int clksrc_nr, const char *clksrc_src, | ||||
| 		const char *clksrc_prop, bool gptimer) | ||||
| { | ||||
| 	omap_clk_init(); | ||||
| 	omap_dmtimer_init(); | ||||
| 	omap2_gp_clockevent_init(clkev_nr, clkev_src, clkev_prop); | ||||
| 
 | ||||
| 	/* Enable the use of clocksource="gp_timer" kernel parameter */ | ||||
| 	if (clksrc_nr && (use_gptimer_clksrc || gptimer)) | ||||
| 		omap2_gptimer_clocksource_init(clksrc_nr, clksrc_src, | ||||
| 						clksrc_prop); | ||||
| 	else | ||||
| 		omap2_sync32k_clocksource_init(); | ||||
| } | ||||
| 
 | ||||
| void __init omap_init_time(void) | ||||
| { | ||||
| 	__omap_sync32k_timer_init(1, "timer_32k_ck", "ti,timer-alwon", | ||||
| 			2, "timer_sys_ck", NULL, false); | ||||
| 
 | ||||
| 	timer_probe(); | ||||
| } | ||||
| 
 | ||||
| #if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_SOC_AM43XX) | ||||
| void __init omap3_secure_sync32k_timer_init(void) | ||||
| { | ||||
| 	__omap_sync32k_timer_init(12, "secure_32k_fck", "ti,timer-secure", | ||||
| 			2, "timer_sys_ck", NULL, false); | ||||
| 
 | ||||
| 	timer_probe(); | ||||
| } | ||||
| #endif /* CONFIG_ARCH_OMAP3 */ | ||||
| 
 | ||||
| #if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_SOC_AM33XX) || \ | ||||
| 	defined(CONFIG_SOC_AM43XX) | ||||
| void __init omap3_gptimer_timer_init(void) | ||||
| { | ||||
| 	__omap_sync32k_timer_init(2, "timer_sys_ck", NULL, | ||||
| 			1, "timer_sys_ck", "ti,timer-alwon", true); | ||||
| 	if (of_have_populated_dt()) | ||||
| 		timer_probe(); | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) ||		\ | ||||
| 	defined(CONFIG_SOC_DRA7XX) | ||||
| static void __init omap4_sync32k_timer_init(void) | ||||
| { | ||||
| 	__omap_sync32k_timer_init(1, "timer_32k_ck", "ti,timer-alwon", | ||||
| 				  0, NULL, NULL, false); | ||||
| } | ||||
| 
 | ||||
| void __init omap4_local_timer_init(void) | ||||
| { | ||||
| 	omap4_sync32k_timer_init(); | ||||
| 	timer_probe(); | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| #if defined(CONFIG_SOC_OMAP5) || defined(CONFIG_SOC_DRA7XX) | ||||
| 
 | ||||
| /*
 | ||||
| @ -604,7 +65,6 @@ void __init omap4_local_timer_init(void) | ||||
|  */ | ||||
| static void __init realtime_counter_init(void) | ||||
| { | ||||
| #ifdef CONFIG_SOC_HAS_REALTIME_COUNTER | ||||
| 	void __iomem *base; | ||||
| 	static struct clk *sys_clk; | ||||
| 	unsigned long rate; | ||||
| @ -703,39 +163,13 @@ sysclk1_based: | ||||
| 	set_cntfreq(); | ||||
| 
 | ||||
| 	iounmap(base); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| void __init omap5_realtime_timer_init(void) | ||||
| { | ||||
| 	omap4_sync32k_timer_init(); | ||||
| 	omap_clk_init(); | ||||
| 	realtime_counter_init(); | ||||
| 
 | ||||
| 	timer_probe(); | ||||
| } | ||||
| #endif /* CONFIG_SOC_OMAP5 || CONFIG_SOC_DRA7XX */ | ||||
| 
 | ||||
| /**
 | ||||
|  * omap2_override_clocksource - clocksource override with user configuration | ||||
|  * | ||||
|  * Allows user to override default clocksource, using kernel parameter | ||||
|  *   clocksource="gp_timer"	(For all OMAP2PLUS architectures) | ||||
|  * | ||||
|  * Note that, here we are using same standard kernel parameter "clocksource=", | ||||
|  * and not introducing any OMAP specific interface. | ||||
|  */ | ||||
| static int __init omap2_override_clocksource(char *str) | ||||
| { | ||||
| 	if (!str) | ||||
| 		return 0; | ||||
| 	/*
 | ||||
| 	 * For OMAP architecture, we only have two options | ||||
| 	 *    - sync_32k (default) | ||||
| 	 *    - gp_timer (sys_clk based) | ||||
| 	 */ | ||||
| 	if (!strcmp(str, "gp_timer")) | ||||
| 		use_gptimer_clksrc = true; | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| early_param("clocksource", omap2_override_clocksource); | ||||
|  | ||||
| @ -1275,13 +1275,6 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = { | ||||
| 		   SYSC_QUIRK_LEGACY_IDLE), | ||||
| 	SYSC_QUIRK("smartreflex", 0, -ENODEV, 0x38, -ENODEV, 0x00000000, 0xffffffff, | ||||
| 		   SYSC_QUIRK_LEGACY_IDLE), | ||||
| 	SYSC_QUIRK("timer", 0, 0, 0x10, 0x14, 0x00000015, 0xffffffff, | ||||
| 		   0), | ||||
| 	/* Some timers on omap4 and later */ | ||||
| 	SYSC_QUIRK("timer", 0, 0, 0x10, -ENODEV, 0x50002100, 0xffffffff, | ||||
| 		   0), | ||||
| 	SYSC_QUIRK("timer", 0, 0, 0x10, -ENODEV, 0x4fff1301, 0xffff00ff, | ||||
| 		   0), | ||||
| 	SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x00000046, 0xffffffff, | ||||
| 		   SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_LEGACY_IDLE), | ||||
| 	SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x00000052, 0xffffffff, | ||||
| @ -1404,6 +1397,13 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = { | ||||
| 	SYSC_QUIRK("slimbus", 0, 0, 0x10, -ENODEV, 0x40002903, 0xffffffff, 0), | ||||
| 	SYSC_QUIRK("spinlock", 0, 0, 0x10, -ENODEV, 0x50020000, 0xffffffff, 0), | ||||
| 	SYSC_QUIRK("rng", 0, 0x1fe0, 0x1fe4, -ENODEV, 0x00000020, 0xffffffff, 0), | ||||
| 	SYSC_QUIRK("timer", 0, 0, 0x10, 0x14, 0x00000013, 0xffffffff, 0), | ||||
| 	SYSC_QUIRK("timer", 0, 0, 0x10, 0x14, 0x00000015, 0xffffffff, 0), | ||||
| 	/* Some timers on omap4 and later */ | ||||
| 	SYSC_QUIRK("timer", 0, 0, 0x10, -ENODEV, 0x50002100, 0xffffffff, 0), | ||||
| 	SYSC_QUIRK("timer", 0, 0, 0x10, -ENODEV, 0x4fff1301, 0xffff00ff, 0), | ||||
| 	SYSC_QUIRK("timer32k", 0, 0, 0x4, -ENODEV, 0x00000040, 0xffffffff, 0), | ||||
| 	SYSC_QUIRK("timer32k", 0, 0, 0x4, -ENODEV, 0x00000011, 0xffffffff, 0), | ||||
| 	SYSC_QUIRK("timer32k", 0, 0, 0x4, -ENODEV, 0x00000060, 0xffffffff, 0), | ||||
| 	SYSC_QUIRK("tpcc", 0, 0, -ENODEV, -ENODEV, 0x40014c00, 0xffffffff, 0), | ||||
| 	SYSC_QUIRK("usbhstll", 0, 0, 0x10, 0x14, 0x00000004, 0xffffffff, 0), | ||||
| @ -2744,6 +2744,17 @@ static int sysc_init_soc(struct sysc *ddata) | ||||
| 	if (match && match->data) | ||||
| 		sysc_soc->soc = (int)match->data; | ||||
| 
 | ||||
| 	/* Ignore devices that are not available on HS and EMU SoCs */ | ||||
| 	if (!sysc_soc->general_purpose) { | ||||
| 		switch (sysc_soc->soc) { | ||||
| 		case SOC_3430 ... SOC_3630: | ||||
| 			sysc_add_disabled(0x48304000);	/* timer12 */ | ||||
| 			break; | ||||
| 		default: | ||||
| 			break; | ||||
| 		}; | ||||
| 	} | ||||
| 
 | ||||
| 	match = soc_device_match(sysc_soc_feat_match); | ||||
| 	if (!match) | ||||
| 		return 0; | ||||
|  | ||||
| @ -73,6 +73,7 @@ static const char *enable_init_clks[] = { | ||||
| 	"ddr_pll_clk1", | ||||
| 	"ddr_pll_clk2", | ||||
| 	"ddr_pll_clk3", | ||||
| 	"sysclk6_ck", | ||||
| }; | ||||
| 
 | ||||
| int __init dm816x_dt_clk_init(void) | ||||
|  | ||||
| @ -18,6 +18,7 @@ obj-$(CONFIG_CLKSRC_MMIO)	+= mmio.o | ||||
| obj-$(CONFIG_DAVINCI_TIMER)	+= timer-davinci.o | ||||
| obj-$(CONFIG_DIGICOLOR_TIMER)	+= timer-digicolor.o | ||||
| obj-$(CONFIG_OMAP_DM_TIMER)	+= timer-ti-dm.o | ||||
| obj-$(CONFIG_OMAP_DM_TIMER)	+= timer-ti-dm-systimer.o | ||||
| obj-$(CONFIG_DW_APB_TIMER)	+= dw_apb_timer.o | ||||
| obj-$(CONFIG_DW_APB_TIMER_OF)	+= dw_apb_timer_of.o | ||||
| obj-$(CONFIG_FTTMR010_TIMER)	+= timer-fttmr010.o | ||||
|  | ||||
| @ -24,6 +24,7 @@ | ||||
|  * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com
 | ||||
|  */ | ||||
| 
 | ||||
| #include <linux/clk.h> | ||||
| #include <linux/init.h> | ||||
| #include <linux/time.h> | ||||
| #include <linux/sched_clock.h> | ||||
| @ -76,6 +77,49 @@ static u64 notrace omap_32k_read_sched_clock(void) | ||||
| 	return ti_32k_read_cycles(&ti_32k_timer.cs); | ||||
| } | ||||
| 
 | ||||
| static void __init ti_32k_timer_enable_clock(struct device_node *np, | ||||
| 					     const char *name) | ||||
| { | ||||
| 	struct clk *clock; | ||||
| 	int error; | ||||
| 
 | ||||
| 	clock = of_clk_get_by_name(np->parent, name); | ||||
| 	if (IS_ERR(clock)) { | ||||
| 		/* Only some SoCs have a separate interface clock */ | ||||
| 		if (PTR_ERR(clock) == -EINVAL && !strncmp("ick", name, 3)) | ||||
| 			return; | ||||
| 
 | ||||
| 		pr_warn("%s: could not get clock %s %li\n", | ||||
| 			__func__, name, PTR_ERR(clock)); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	error = clk_prepare_enable(clock); | ||||
| 	if (error) { | ||||
| 		pr_warn("%s: could not enable %s: %i\n", | ||||
| 			__func__, name, error); | ||||
| 		return; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static void __init ti_32k_timer_module_init(struct device_node *np, | ||||
| 					    void __iomem *base) | ||||
| { | ||||
| 	void __iomem *sysc = base + 4; | ||||
| 
 | ||||
| 	if (!of_device_is_compatible(np->parent, "ti,sysc")) | ||||
| 		return; | ||||
| 
 | ||||
| 	ti_32k_timer_enable_clock(np, "fck"); | ||||
| 	ti_32k_timer_enable_clock(np, "ick"); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Force idle module as wkup domain is active with MPU. | ||||
| 	 * No need to tag the module disabled for ti-sysc probe. | ||||
| 	 */ | ||||
| 	writel_relaxed(0, sysc); | ||||
| } | ||||
| 
 | ||||
| static int __init ti_32k_timer_init(struct device_node *np) | ||||
| { | ||||
| 	int ret; | ||||
| @ -90,6 +134,7 @@ static int __init ti_32k_timer_init(struct device_node *np) | ||||
| 		ti_32k_timer.cs.flags |= CLOCK_SOURCE_SUSPEND_NONSTOP; | ||||
| 
 | ||||
| 	ti_32k_timer.counter = ti_32k_timer.base; | ||||
| 	ti_32k_timer_module_init(np, ti_32k_timer.base); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * 32k sync Counter IP register offsets vary between the highlander | ||||
| @ -104,6 +149,8 @@ static int __init ti_32k_timer_init(struct device_node *np) | ||||
| 	else | ||||
| 		ti_32k_timer.counter += OMAP2_32KSYNCNT_CR_OFF_LOW; | ||||
| 
 | ||||
| 	pr_info("OMAP clocksource: 32k_counter at 32768 Hz\n"); | ||||
| 
 | ||||
| 	ret = clocksource_register_hz(&ti_32k_timer.cs, 32768); | ||||
| 	if (ret) { | ||||
| 		pr_err("32k_counter: can't register clocksource\n"); | ||||
| @ -111,7 +158,6 @@ static int __init ti_32k_timer_init(struct device_node *np) | ||||
| 	} | ||||
| 
 | ||||
| 	sched_clock_register(omap_32k_read_sched_clock, 32, 32768); | ||||
| 	pr_info("OMAP clocksource: 32k_counter at 32768 Hz\n"); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
							
								
								
									
										727
									
								
								drivers/clocksource/timer-ti-dm-systimer.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										727
									
								
								drivers/clocksource/timer-ti-dm-systimer.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,727 @@ | ||||
| // SPDX-License-Identifier: GPL-2.0+
 | ||||
| #include <linux/clk.h> | ||||
| #include <linux/clocksource.h> | ||||
| #include <linux/clockchips.h> | ||||
| #include <linux/interrupt.h> | ||||
| #include <linux/io.h> | ||||
| #include <linux/iopoll.h> | ||||
| #include <linux/err.h> | ||||
| #include <linux/of.h> | ||||
| #include <linux/of_address.h> | ||||
| #include <linux/of_irq.h> | ||||
| #include <linux/sched_clock.h> | ||||
| 
 | ||||
| #include <linux/clk/clk-conf.h> | ||||
| 
 | ||||
| #include <clocksource/timer-ti-dm.h> | ||||
| #include <dt-bindings/bus/ti-sysc.h> | ||||
| 
 | ||||
| /* For type1, set SYSC_OMAP2_CLOCKACTIVITY for fck off on idle, l4 clock on */ | ||||
| #define DMTIMER_TYPE1_ENABLE	((1 << 9) | (SYSC_IDLE_SMART << 3) | \ | ||||
| 				 SYSC_OMAP2_ENAWAKEUP | SYSC_OMAP2_AUTOIDLE) | ||||
| 
 | ||||
| #define DMTIMER_TYPE2_ENABLE	(SYSC_IDLE_SMART_WKUP << 2) | ||||
| #define DMTIMER_RESET_WAIT	100000 | ||||
| 
 | ||||
| #define DMTIMER_INST_DONT_CARE	~0U | ||||
| 
 | ||||
| static int counter_32k; | ||||
| static u32 clocksource; | ||||
| static u32 clockevent; | ||||
| 
 | ||||
| /*
 | ||||
|  * Subset of the timer registers we use. Note that the register offsets | ||||
|  * depend on the timer revision detected. | ||||
|  */ | ||||
| struct dmtimer_systimer { | ||||
| 	void __iomem *base; | ||||
| 	u8 sysc; | ||||
| 	u8 irq_stat; | ||||
| 	u8 irq_ena; | ||||
| 	u8 pend; | ||||
| 	u8 load; | ||||
| 	u8 counter; | ||||
| 	u8 ctrl; | ||||
| 	u8 wakeup; | ||||
| 	u8 ifctrl; | ||||
| 	unsigned long rate; | ||||
| }; | ||||
| 
 | ||||
| struct dmtimer_clockevent { | ||||
| 	struct clock_event_device dev; | ||||
| 	struct dmtimer_systimer t; | ||||
| 	u32 period; | ||||
| }; | ||||
| 
 | ||||
| struct dmtimer_clocksource { | ||||
| 	struct clocksource dev; | ||||
| 	struct dmtimer_systimer t; | ||||
| 	unsigned int loadval; | ||||
| }; | ||||
| 
 | ||||
| /* Assumes v1 ip if bits [31:16] are zero */ | ||||
| static bool dmtimer_systimer_revision1(struct dmtimer_systimer *t) | ||||
| { | ||||
| 	u32 tidr = readl_relaxed(t->base); | ||||
| 
 | ||||
| 	return !(tidr >> 16); | ||||
| } | ||||
| 
 | ||||
| static int __init dmtimer_systimer_type1_reset(struct dmtimer_systimer *t) | ||||
| { | ||||
| 	void __iomem *syss = t->base + OMAP_TIMER_V1_SYS_STAT_OFFSET; | ||||
| 	int ret; | ||||
| 	u32 l; | ||||
| 
 | ||||
| 	writel_relaxed(BIT(1) | BIT(2), t->base + t->ifctrl); | ||||
| 	ret = readl_poll_timeout_atomic(syss, l, l & BIT(0), 100, | ||||
| 					DMTIMER_RESET_WAIT); | ||||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| /* Note we must use io_base instead of func_base for type2 OCP regs */ | ||||
| static int __init dmtimer_systimer_type2_reset(struct dmtimer_systimer *t) | ||||
| { | ||||
| 	void __iomem *sysc = t->base + t->sysc; | ||||
| 	u32 l; | ||||
| 
 | ||||
| 	l = readl_relaxed(sysc); | ||||
| 	l |= BIT(0); | ||||
| 	writel_relaxed(l, sysc); | ||||
| 
 | ||||
| 	return readl_poll_timeout_atomic(sysc, l, !(l & BIT(0)), 100, | ||||
| 					 DMTIMER_RESET_WAIT); | ||||
| } | ||||
| 
 | ||||
| static int __init dmtimer_systimer_reset(struct dmtimer_systimer *t) | ||||
| { | ||||
| 	int ret; | ||||
| 
 | ||||
| 	if (dmtimer_systimer_revision1(t)) | ||||
| 		ret = dmtimer_systimer_type1_reset(t); | ||||
| 	else | ||||
| 		ret = dmtimer_systimer_type2_reset(t); | ||||
| 	if (ret < 0) { | ||||
| 		pr_err("%s failed with %i\n", __func__, ret); | ||||
| 
 | ||||
| 		return ret; | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static const struct of_device_id counter_match_table[] = { | ||||
| 	{ .compatible = "ti,omap-counter32k" }, | ||||
| 	{ /* Sentinel */ }, | ||||
| }; | ||||
| 
 | ||||
| /*
 | ||||
|  * Check if the SoC als has a usable working 32 KiHz counter. The 32 KiHz | ||||
|  * counter is handled by timer-ti-32k, but we need to detect it as it | ||||
|  * affects the preferred dmtimer system timer configuration. There is | ||||
|  * typically no use for a dmtimer clocksource if the 32 KiHz counter is | ||||
|  * present, except on am437x as described below. | ||||
|  */ | ||||
| static void __init dmtimer_systimer_check_counter32k(void) | ||||
| { | ||||
| 	struct device_node *np; | ||||
| 
 | ||||
| 	if (counter_32k) | ||||
| 		return; | ||||
| 
 | ||||
| 	np = of_find_matching_node(NULL, counter_match_table); | ||||
| 	if (!np) { | ||||
| 		counter_32k = -ENODEV; | ||||
| 
 | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	if (of_device_is_available(np)) | ||||
| 		counter_32k = 1; | ||||
| 	else | ||||
| 		counter_32k = -ENODEV; | ||||
| 
 | ||||
| 	of_node_put(np); | ||||
| } | ||||
| 
 | ||||
| static const struct of_device_id dmtimer_match_table[] = { | ||||
| 	{ .compatible = "ti,omap2420-timer", }, | ||||
| 	{ .compatible = "ti,omap3430-timer", }, | ||||
| 	{ .compatible = "ti,omap4430-timer", }, | ||||
| 	{ .compatible = "ti,omap5430-timer", }, | ||||
| 	{ .compatible = "ti,am335x-timer", }, | ||||
| 	{ .compatible = "ti,am335x-timer-1ms", }, | ||||
| 	{ .compatible = "ti,dm814-timer", }, | ||||
| 	{ .compatible = "ti,dm816-timer", }, | ||||
| 	{ /* Sentinel */ }, | ||||
| }; | ||||
| 
 | ||||
| /*
 | ||||
|  * Checks that system timers are configured to not reset and idle during | ||||
|  * the generic timer-ti-dm device driver probe. And that the system timer | ||||
|  * source clocks are properly configured. Also, let's not hog any DSP and | ||||
|  * PWM capable timers unnecessarily as system timers. | ||||
|  */ | ||||
| static bool __init dmtimer_is_preferred(struct device_node *np) | ||||
| { | ||||
| 	if (!of_device_is_available(np)) | ||||
| 		return false; | ||||
| 
 | ||||
| 	if (!of_property_read_bool(np->parent, | ||||
| 				   "ti,no-reset-on-init")) | ||||
| 		return false; | ||||
| 
 | ||||
| 	if (!of_property_read_bool(np->parent, "ti,no-idle")) | ||||
| 		return false; | ||||
| 
 | ||||
| 	/* Secure gptimer12 is always clocked with a fixed source */ | ||||
| 	if (!of_property_read_bool(np, "ti,timer-secure")) { | ||||
| 		if (!of_property_read_bool(np, "assigned-clocks")) | ||||
| 			return false; | ||||
| 
 | ||||
| 		if (!of_property_read_bool(np, "assigned-clock-parents")) | ||||
| 			return false; | ||||
| 	} | ||||
| 
 | ||||
| 	if (of_property_read_bool(np, "ti,timer-dsp")) | ||||
| 		return false; | ||||
| 
 | ||||
| 	if (of_property_read_bool(np, "ti,timer-pwm")) | ||||
| 		return false; | ||||
| 
 | ||||
| 	return true; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Finds the first available usable always-on timer, and assigns it to either | ||||
|  * clockevent or clocksource depending if the counter_32k is available on the | ||||
|  * SoC or not. | ||||
|  * | ||||
|  * Some omap3 boards with unreliable oscillator must not use the counter_32k | ||||
|  * or dmtimer1 with 32 KiHz source. Additionally, the boards with unreliable | ||||
|  * oscillator should really set counter_32k as disabled, and delete dmtimer1 | ||||
|  * ti,always-on property, but let's not count on it. For these quirky cases, | ||||
|  * we prefer using the always-on secure dmtimer12 with the internal 32 KiHz | ||||
|  * clock as the clocksource, and any available dmtimer as clockevent. | ||||
|  * | ||||
|  * For am437x, we are using am335x style dmtimer clocksource. It is unclear | ||||
|  * if this quirk handling is really needed, but let's change it separately | ||||
|  * based on testing as it might cause side effects. | ||||
|  */ | ||||
| static void __init dmtimer_systimer_assign_alwon(void) | ||||
| { | ||||
| 	struct device_node *np; | ||||
| 	u32 pa = 0; | ||||
| 	bool quirk_unreliable_oscillator = false; | ||||
| 
 | ||||
| 	/* Quirk unreliable 32 KiHz oscillator with incomplete dts */ | ||||
| 	if (of_machine_is_compatible("ti,omap3-beagle") || | ||||
| 	    of_machine_is_compatible("timll,omap3-devkit8000")) { | ||||
| 		quirk_unreliable_oscillator = true; | ||||
| 		counter_32k = -ENODEV; | ||||
| 	} | ||||
| 
 | ||||
| 	/* Quirk am437x using am335x style dmtimer clocksource */ | ||||
| 	if (of_machine_is_compatible("ti,am43")) | ||||
| 		counter_32k = -ENODEV; | ||||
| 
 | ||||
| 	for_each_matching_node(np, dmtimer_match_table) { | ||||
| 		if (!dmtimer_is_preferred(np)) | ||||
| 			continue; | ||||
| 
 | ||||
| 		if (of_property_read_bool(np, "ti,timer-alwon")) { | ||||
| 			const __be32 *addr; | ||||
| 
 | ||||
| 			addr = of_get_address(np, 0, NULL, NULL); | ||||
| 			pa = of_translate_address(np, addr); | ||||
| 			if (pa) { | ||||
| 				/* Quirky omap3 boards must use dmtimer12 */ | ||||
| 				if (quirk_unreliable_oscillator && | ||||
| 				    pa == 0x48318000) | ||||
| 					continue; | ||||
| 
 | ||||
| 				of_node_put(np); | ||||
| 				break; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	/* Usually no need for dmtimer clocksource if we have counter32 */ | ||||
| 	if (counter_32k >= 0) { | ||||
| 		clockevent = pa; | ||||
| 		clocksource = 0; | ||||
| 	} else { | ||||
| 		clocksource = pa; | ||||
| 		clockevent = DMTIMER_INST_DONT_CARE; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| /* Finds the first usable dmtimer, used for the don't care case */ | ||||
| static u32 __init dmtimer_systimer_find_first_available(void) | ||||
| { | ||||
| 	struct device_node *np; | ||||
| 	const __be32 *addr; | ||||
| 	u32 pa = 0; | ||||
| 
 | ||||
| 	for_each_matching_node(np, dmtimer_match_table) { | ||||
| 		if (!dmtimer_is_preferred(np)) | ||||
| 			continue; | ||||
| 
 | ||||
| 		addr = of_get_address(np, 0, NULL, NULL); | ||||
| 		pa = of_translate_address(np, addr); | ||||
| 		if (pa) { | ||||
| 			if (pa == clocksource || pa == clockevent) { | ||||
| 				pa = 0; | ||||
| 				continue; | ||||
| 			} | ||||
| 
 | ||||
| 			of_node_put(np); | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return pa; | ||||
| } | ||||
| 
 | ||||
| /* Selects the best clocksource and clockevent to use */ | ||||
| static void __init dmtimer_systimer_select_best(void) | ||||
| { | ||||
| 	dmtimer_systimer_check_counter32k(); | ||||
| 	dmtimer_systimer_assign_alwon(); | ||||
| 
 | ||||
| 	if (clockevent == DMTIMER_INST_DONT_CARE) | ||||
| 		clockevent = dmtimer_systimer_find_first_available(); | ||||
| 
 | ||||
| 	pr_debug("%s: counter_32k: %i clocksource: %08x clockevent: %08x\n", | ||||
| 		 __func__, counter_32k, clocksource, clockevent); | ||||
| } | ||||
| 
 | ||||
| /* Interface clocks are only available on some SoCs variants */ | ||||
| static int __init dmtimer_systimer_init_clock(struct device_node *np, | ||||
| 					      const char *name, | ||||
| 					      unsigned long *rate) | ||||
| { | ||||
| 	struct clk *clock; | ||||
| 	unsigned long r; | ||||
| 	int error; | ||||
| 
 | ||||
| 	clock = of_clk_get_by_name(np, name); | ||||
| 	if ((PTR_ERR(clock) == -EINVAL) && !strncmp(name, "ick", 3)) | ||||
| 		return 0; | ||||
| 	else if (IS_ERR(clock)) | ||||
| 		return PTR_ERR(clock); | ||||
| 
 | ||||
| 	error = clk_prepare_enable(clock); | ||||
| 	if (error) | ||||
| 		return error; | ||||
| 
 | ||||
| 	r = clk_get_rate(clock); | ||||
| 	if (!r) | ||||
| 		return -ENODEV; | ||||
| 
 | ||||
| 	*rate = r; | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static void dmtimer_systimer_enable(struct dmtimer_systimer *t) | ||||
| { | ||||
| 	u32 val; | ||||
| 
 | ||||
| 	if (dmtimer_systimer_revision1(t)) | ||||
| 		val = DMTIMER_TYPE1_ENABLE; | ||||
| 	else | ||||
| 		val = DMTIMER_TYPE2_ENABLE; | ||||
| 
 | ||||
| 	writel_relaxed(val, t->base + t->sysc); | ||||
| } | ||||
| 
 | ||||
| static void dmtimer_systimer_disable(struct dmtimer_systimer *t) | ||||
| { | ||||
| 	writel_relaxed(0, t->base + t->sysc); | ||||
| } | ||||
| 
 | ||||
| static int __init dmtimer_systimer_setup(struct device_node *np, | ||||
| 					 struct dmtimer_systimer *t) | ||||
| { | ||||
| 	unsigned long rate; | ||||
| 	u8 regbase; | ||||
| 	int error; | ||||
| 
 | ||||
| 	if (!of_device_is_compatible(np->parent, "ti,sysc")) | ||||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	t->base = of_iomap(np, 0); | ||||
| 	if (!t->base) | ||||
| 		return -ENXIO; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Enable optional assigned-clock-parents configured at the timer | ||||
| 	 * node level. For regular device drivers, this is done automatically | ||||
| 	 * by bus related code such as platform_drv_probe(). | ||||
| 	 */ | ||||
| 	error = of_clk_set_defaults(np, false); | ||||
| 	if (error < 0) | ||||
| 		pr_err("%s: clock source init failed: %i\n", __func__, error); | ||||
| 
 | ||||
| 	/* For ti-sysc, we have timer clocks at the parent module level */ | ||||
| 	error = dmtimer_systimer_init_clock(np->parent, "fck", &rate); | ||||
| 	if (error) | ||||
| 		goto err_unmap; | ||||
| 
 | ||||
| 	t->rate = rate; | ||||
| 
 | ||||
| 	error = dmtimer_systimer_init_clock(np->parent, "ick", &rate); | ||||
| 	if (error) | ||||
| 		goto err_unmap; | ||||
| 
 | ||||
| 	if (dmtimer_systimer_revision1(t)) { | ||||
| 		t->irq_stat = OMAP_TIMER_V1_STAT_OFFSET; | ||||
| 		t->irq_ena = OMAP_TIMER_V1_INT_EN_OFFSET; | ||||
| 		t->pend = _OMAP_TIMER_WRITE_PEND_OFFSET; | ||||
| 		regbase = 0; | ||||
| 	} else { | ||||
| 		t->irq_stat = OMAP_TIMER_V2_IRQSTATUS; | ||||
| 		t->irq_ena = OMAP_TIMER_V2_IRQENABLE_SET; | ||||
| 		regbase = OMAP_TIMER_V2_FUNC_OFFSET; | ||||
| 		t->pend = regbase + _OMAP_TIMER_WRITE_PEND_OFFSET; | ||||
| 	} | ||||
| 
 | ||||
| 	t->sysc = OMAP_TIMER_OCP_CFG_OFFSET; | ||||
| 	t->load = regbase + _OMAP_TIMER_LOAD_OFFSET; | ||||
| 	t->counter = regbase + _OMAP_TIMER_COUNTER_OFFSET; | ||||
| 	t->ctrl = regbase + _OMAP_TIMER_CTRL_OFFSET; | ||||
| 	t->wakeup = regbase + _OMAP_TIMER_WAKEUP_EN_OFFSET; | ||||
| 	t->ifctrl = regbase + _OMAP_TIMER_IF_CTRL_OFFSET; | ||||
| 
 | ||||
| 	dmtimer_systimer_enable(t); | ||||
| 	dmtimer_systimer_reset(t); | ||||
| 	pr_debug("dmtimer rev %08x sysc %08x\n", readl_relaxed(t->base), | ||||
| 		 readl_relaxed(t->base + t->sysc)); | ||||
| 
 | ||||
| 	return 0; | ||||
| 
 | ||||
| err_unmap: | ||||
| 	iounmap(t->base); | ||||
| 
 | ||||
| 	return error; | ||||
| } | ||||
| 
 | ||||
| /* Clockevent */ | ||||
| static struct dmtimer_clockevent * | ||||
| to_dmtimer_clockevent(struct clock_event_device *clockevent) | ||||
| { | ||||
| 	return container_of(clockevent, struct dmtimer_clockevent, dev); | ||||
| } | ||||
| 
 | ||||
| static irqreturn_t dmtimer_clockevent_interrupt(int irq, void *data) | ||||
| { | ||||
| 	struct dmtimer_clockevent *clkevt = data; | ||||
| 	struct dmtimer_systimer *t = &clkevt->t; | ||||
| 
 | ||||
| 	writel_relaxed(OMAP_TIMER_INT_OVERFLOW, t->base + t->irq_stat); | ||||
| 	clkevt->dev.event_handler(&clkevt->dev); | ||||
| 
 | ||||
| 	return IRQ_HANDLED; | ||||
| } | ||||
| 
 | ||||
| static int dmtimer_set_next_event(unsigned long cycles, | ||||
| 				  struct clock_event_device *evt) | ||||
| { | ||||
| 	struct dmtimer_clockevent *clkevt = to_dmtimer_clockevent(evt); | ||||
| 	struct dmtimer_systimer *t = &clkevt->t; | ||||
| 	void __iomem *pend = t->base + t->pend; | ||||
| 
 | ||||
| 	writel_relaxed(0xffffffff - cycles, t->base + t->counter); | ||||
| 	while (readl_relaxed(pend) & WP_TCRR) | ||||
| 		cpu_relax(); | ||||
| 
 | ||||
| 	writel_relaxed(OMAP_TIMER_CTRL_ST, t->base + t->ctrl); | ||||
| 	while (readl_relaxed(pend) & WP_TCLR) | ||||
| 		cpu_relax(); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int dmtimer_clockevent_shutdown(struct clock_event_device *evt) | ||||
| { | ||||
| 	struct dmtimer_clockevent *clkevt = to_dmtimer_clockevent(evt); | ||||
| 	struct dmtimer_systimer *t = &clkevt->t; | ||||
| 	void __iomem *ctrl = t->base + t->ctrl; | ||||
| 	u32 l; | ||||
| 
 | ||||
| 	l = readl_relaxed(ctrl); | ||||
| 	if (l & OMAP_TIMER_CTRL_ST) { | ||||
| 		l &= ~BIT(0); | ||||
| 		writel_relaxed(l, ctrl); | ||||
| 		/* Flush posted write */ | ||||
| 		l = readl_relaxed(ctrl); | ||||
| 		/*  Wait for functional clock period x 3.5 */ | ||||
| 		udelay(3500000 / t->rate + 1); | ||||
| 	} | ||||
| 	writel_relaxed(OMAP_TIMER_INT_OVERFLOW, t->base + t->irq_stat); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int dmtimer_set_periodic(struct clock_event_device *evt) | ||||
| { | ||||
| 	struct dmtimer_clockevent *clkevt = to_dmtimer_clockevent(evt); | ||||
| 	struct dmtimer_systimer *t = &clkevt->t; | ||||
| 	void __iomem *pend = t->base + t->pend; | ||||
| 
 | ||||
| 	dmtimer_clockevent_shutdown(evt); | ||||
| 
 | ||||
| 	/* Looks like we need to first set the load value separately */ | ||||
| 	writel_relaxed(clkevt->period, t->base + t->load); | ||||
| 	while (readl_relaxed(pend) & WP_TLDR) | ||||
| 		cpu_relax(); | ||||
| 
 | ||||
| 	writel_relaxed(clkevt->period, t->base + t->counter); | ||||
| 	while (readl_relaxed(pend) & WP_TCRR) | ||||
| 		cpu_relax(); | ||||
| 
 | ||||
| 	writel_relaxed(OMAP_TIMER_CTRL_AR | OMAP_TIMER_CTRL_ST, | ||||
| 		       t->base + t->ctrl); | ||||
| 	while (readl_relaxed(pend) & WP_TCLR) | ||||
| 		cpu_relax(); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static void omap_clockevent_idle(struct clock_event_device *evt) | ||||
| { | ||||
| 	struct dmtimer_clockevent *clkevt = to_dmtimer_clockevent(evt); | ||||
| 	struct dmtimer_systimer *t = &clkevt->t; | ||||
| 
 | ||||
| 	dmtimer_systimer_disable(t); | ||||
| } | ||||
| 
 | ||||
| static void omap_clockevent_unidle(struct clock_event_device *evt) | ||||
| { | ||||
| 	struct dmtimer_clockevent *clkevt = to_dmtimer_clockevent(evt); | ||||
| 	struct dmtimer_systimer *t = &clkevt->t; | ||||
| 
 | ||||
| 	dmtimer_systimer_enable(t); | ||||
| 	writel_relaxed(OMAP_TIMER_INT_OVERFLOW, t->base + t->irq_ena); | ||||
| 	writel_relaxed(OMAP_TIMER_INT_OVERFLOW, t->base + t->wakeup); | ||||
| } | ||||
| 
 | ||||
| static int __init dmtimer_clockevent_init(struct device_node *np) | ||||
| { | ||||
| 	struct dmtimer_clockevent *clkevt; | ||||
| 	struct clock_event_device *dev; | ||||
| 	struct dmtimer_systimer *t; | ||||
| 	int error; | ||||
| 
 | ||||
| 	clkevt = kzalloc(sizeof(*clkevt), GFP_KERNEL); | ||||
| 	if (!clkevt) | ||||
| 		return -ENOMEM; | ||||
| 
 | ||||
| 	t = &clkevt->t; | ||||
| 	dev = &clkevt->dev; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * We mostly use cpuidle_coupled with ARM local timers for runtime, | ||||
| 	 * so there's probably no use for CLOCK_EVT_FEAT_DYNIRQ here. | ||||
| 	 */ | ||||
| 	dev->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; | ||||
| 	dev->rating = 300; | ||||
| 	dev->set_next_event = dmtimer_set_next_event; | ||||
| 	dev->set_state_shutdown = dmtimer_clockevent_shutdown; | ||||
| 	dev->set_state_periodic = dmtimer_set_periodic; | ||||
| 	dev->set_state_oneshot = dmtimer_clockevent_shutdown; | ||||
| 	dev->tick_resume = dmtimer_clockevent_shutdown; | ||||
| 	dev->cpumask = cpu_possible_mask; | ||||
| 
 | ||||
| 	dev->irq = irq_of_parse_and_map(np, 0); | ||||
| 	if (!dev->irq) { | ||||
| 		error = -ENXIO; | ||||
| 		goto err_out_free; | ||||
| 	} | ||||
| 
 | ||||
| 	error = dmtimer_systimer_setup(np, &clkevt->t); | ||||
| 	if (error) | ||||
| 		goto err_out_free; | ||||
| 
 | ||||
| 	clkevt->period = 0xffffffff - DIV_ROUND_CLOSEST(t->rate, HZ); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * For clock-event timers we never read the timer counter and | ||||
| 	 * so we are not impacted by errata i103 and i767. Therefore, | ||||
| 	 * we can safely ignore this errata for clock-event timers. | ||||
| 	 */ | ||||
| 	writel_relaxed(OMAP_TIMER_CTRL_POSTED, t->base + t->ifctrl); | ||||
| 
 | ||||
| 	error = request_irq(dev->irq, dmtimer_clockevent_interrupt, | ||||
| 			    IRQF_TIMER, "clockevent", clkevt); | ||||
| 	if (error) | ||||
| 		goto err_out_unmap; | ||||
| 
 | ||||
| 	writel_relaxed(OMAP_TIMER_INT_OVERFLOW, t->base + t->irq_ena); | ||||
| 	writel_relaxed(OMAP_TIMER_INT_OVERFLOW, t->base + t->wakeup); | ||||
| 
 | ||||
| 	pr_info("TI gptimer clockevent: %s%lu Hz at %pOF\n", | ||||
| 		of_find_property(np, "ti,timer-alwon", NULL) ? | ||||
| 		"always-on " : "", t->rate, np->parent); | ||||
| 
 | ||||
| 	clockevents_config_and_register(dev, t->rate, | ||||
| 					3, /* Timer internal resynch latency */ | ||||
| 					0xffffffff); | ||||
| 
 | ||||
| 	if (of_device_is_compatible(np, "ti,am33xx") || | ||||
| 	    of_device_is_compatible(np, "ti,am43")) { | ||||
| 		dev->suspend = omap_clockevent_idle; | ||||
| 		dev->resume = omap_clockevent_unidle; | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| 
 | ||||
| err_out_unmap: | ||||
| 	iounmap(t->base); | ||||
| 
 | ||||
| err_out_free: | ||||
| 	kfree(clkevt); | ||||
| 
 | ||||
| 	return error; | ||||
| } | ||||
| 
 | ||||
| /* Clocksource */ | ||||
| static struct dmtimer_clocksource * | ||||
| to_dmtimer_clocksource(struct clocksource *cs) | ||||
| { | ||||
| 	return container_of(cs, struct dmtimer_clocksource, dev); | ||||
| } | ||||
| 
 | ||||
| static u64 dmtimer_clocksource_read_cycles(struct clocksource *cs) | ||||
| { | ||||
| 	struct dmtimer_clocksource *clksrc = to_dmtimer_clocksource(cs); | ||||
| 	struct dmtimer_systimer *t = &clksrc->t; | ||||
| 
 | ||||
| 	return (u64)readl_relaxed(t->base + t->counter); | ||||
| } | ||||
| 
 | ||||
| static void __iomem *dmtimer_sched_clock_counter; | ||||
| 
 | ||||
| static u64 notrace dmtimer_read_sched_clock(void) | ||||
| { | ||||
| 	return readl_relaxed(dmtimer_sched_clock_counter); | ||||
| } | ||||
| 
 | ||||
| static void dmtimer_clocksource_suspend(struct clocksource *cs) | ||||
| { | ||||
| 	struct dmtimer_clocksource *clksrc = to_dmtimer_clocksource(cs); | ||||
| 	struct dmtimer_systimer *t = &clksrc->t; | ||||
| 
 | ||||
| 	clksrc->loadval = readl_relaxed(t->base + t->counter); | ||||
| 	dmtimer_systimer_disable(t); | ||||
| } | ||||
| 
 | ||||
| static void dmtimer_clocksource_resume(struct clocksource *cs) | ||||
| { | ||||
| 	struct dmtimer_clocksource *clksrc = to_dmtimer_clocksource(cs); | ||||
| 	struct dmtimer_systimer *t = &clksrc->t; | ||||
| 
 | ||||
| 	dmtimer_systimer_enable(t); | ||||
| 	writel_relaxed(clksrc->loadval, t->base + t->counter); | ||||
| 	writel_relaxed(OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR, | ||||
| 		       t->base + t->ctrl); | ||||
| } | ||||
| 
 | ||||
| static int __init dmtimer_clocksource_init(struct device_node *np) | ||||
| { | ||||
| 	struct dmtimer_clocksource *clksrc; | ||||
| 	struct dmtimer_systimer *t; | ||||
| 	struct clocksource *dev; | ||||
| 	int error; | ||||
| 
 | ||||
| 	clksrc = kzalloc(sizeof(*clksrc), GFP_KERNEL); | ||||
| 	if (!clksrc) | ||||
| 		return -ENOMEM; | ||||
| 
 | ||||
| 	dev = &clksrc->dev; | ||||
| 	t = &clksrc->t; | ||||
| 
 | ||||
| 	error = dmtimer_systimer_setup(np, t); | ||||
| 	if (error) | ||||
| 		goto err_out_free; | ||||
| 
 | ||||
| 	dev->name = "dmtimer"; | ||||
| 	dev->rating = 300; | ||||
| 	dev->read = dmtimer_clocksource_read_cycles; | ||||
| 	dev->mask = CLOCKSOURCE_MASK(32); | ||||
| 	dev->flags = CLOCK_SOURCE_IS_CONTINUOUS; | ||||
| 
 | ||||
| 	if (of_device_is_compatible(np, "ti,am33xx") || | ||||
| 	    of_device_is_compatible(np, "ti,am43")) { | ||||
| 		dev->suspend = dmtimer_clocksource_suspend; | ||||
| 		dev->resume = dmtimer_clocksource_resume; | ||||
| 	} | ||||
| 
 | ||||
| 	writel_relaxed(0, t->base + t->counter); | ||||
| 	writel_relaxed(OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR, | ||||
| 		       t->base + t->ctrl); | ||||
| 
 | ||||
| 	pr_info("TI gptimer clocksource: %s%pOF\n", | ||||
| 		of_find_property(np, "ti,timer-alwon", NULL) ? | ||||
| 		"always-on " : "", np->parent); | ||||
| 
 | ||||
| 	if (!dmtimer_sched_clock_counter) { | ||||
| 		dmtimer_sched_clock_counter = t->base + t->counter; | ||||
| 		sched_clock_register(dmtimer_read_sched_clock, 32, t->rate); | ||||
| 	} | ||||
| 
 | ||||
| 	if (clocksource_register_hz(dev, t->rate)) | ||||
| 		pr_err("Could not register clocksource %pOF\n", np); | ||||
| 
 | ||||
| 	return 0; | ||||
| 
 | ||||
| err_out_free: | ||||
| 	kfree(clksrc); | ||||
| 
 | ||||
| 	return -ENODEV; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * To detect between a clocksource and clockevent, we assume the device tree | ||||
|  * has no interrupts configured for a clocksource timer. | ||||
|  */ | ||||
| static int __init dmtimer_systimer_init(struct device_node *np) | ||||
| { | ||||
| 	const __be32 *addr; | ||||
| 	u32 pa; | ||||
| 
 | ||||
| 	/* One time init for the preferred timer configuration */ | ||||
| 	if (!clocksource && !clockevent) | ||||
| 		dmtimer_systimer_select_best(); | ||||
| 
 | ||||
| 	if (!clocksource && !clockevent) { | ||||
| 		pr_err("%s: unable to detectt system timers, update dtb?\n", | ||||
| 		       __func__); | ||||
| 
 | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
| 
 | ||||
| 	addr = of_get_address(np, 0, NULL, NULL); | ||||
| 	pa = of_translate_address(np, addr); | ||||
| 	if (!pa) | ||||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	if (counter_32k <= 0 && clocksource == pa) | ||||
| 		return dmtimer_clocksource_init(np); | ||||
| 
 | ||||
| 	if (clockevent == pa) | ||||
| 		return dmtimer_clockevent_init(np); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| TIMER_OF_DECLARE(systimer_omap2, "ti,omap2420-timer", dmtimer_systimer_init); | ||||
| TIMER_OF_DECLARE(systimer_omap3, "ti,omap3430-timer", dmtimer_systimer_init); | ||||
| TIMER_OF_DECLARE(systimer_omap4, "ti,omap4430-timer", dmtimer_systimer_init); | ||||
| TIMER_OF_DECLARE(systimer_omap5, "ti,omap5430-timer", dmtimer_systimer_init); | ||||
| TIMER_OF_DECLARE(systimer_am33x, "ti,am335x-timer", dmtimer_systimer_init); | ||||
| TIMER_OF_DECLARE(systimer_am3ms, "ti,am335x-timer-1ms", dmtimer_systimer_init); | ||||
| TIMER_OF_DECLARE(systimer_dm814, "ti,dm814-timer", dmtimer_systimer_init); | ||||
| TIMER_OF_DECLARE(systimer_dm816, "ti,dm816-timer", dmtimer_systimer_init); | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user